// mobile.jsx — Native mobile layouts for each route
// Renders a single-column, gesture-friendly version of each page

// ── Shared mobile chrome ───────────────────────────────────
const MAppBar = ({ title, subtitle, onMenu, right }) => (
  <div style={{
    height: 52, flex: "0 0 52px", display: "flex", alignItems: "center",
    padding: "0 8px 0 4px", gap: 8, position: "relative", zIndex: 5,
    background: "var(--bg-1)", borderBottom: "1px solid var(--border-1)",
  }}>
    <button onClick={onMenu} aria-label="菜单" style={{
      width: 40, height: 40, display: "grid", placeItems: "center",
      background: "transparent", border: "none", color: "var(--fg-1)", borderRadius: 8, cursor: "pointer",
    }}>
      <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></svg>
    </button>
    <div style={{ flex: 1, minWidth: 0 }}>
      <div style={{ fontWeight: 600, fontSize: 15, color: "var(--fg-0)", lineHeight: 1.2 }}>{title}</div>
      {subtitle && <div style={{ fontSize: 11, color: "var(--fg-3)", lineHeight: 1.2 }}>{subtitle}</div>}
    </div>
    {right}
  </div>
);

const MIconBtn = ({ icon, badge, onClick }) => (
  <button onClick={onClick} style={{
    width: 40, height: 40, display: "grid", placeItems: "center",
    background: "transparent", border: "none", color: "var(--fg-1)", borderRadius: 8, cursor: "pointer", position: "relative",
  }}>
    <Icon name={icon} size={17}/>
    {badge && <span style={{ position: "absolute", top: 8, right: 8, minWidth: 14, height: 14, padding: "0 4px", background: "var(--danger)", color: "#fff", fontSize: 9, fontWeight: 600, borderRadius: 7, display: "grid", placeItems: "center", lineHeight: 1 }}>{badge}</span>}
  </button>
);

const MTabBar = ({ active, onChange }) => {
  const tabs = [
    { id: "overview", icon: "map",   label: "总览" },
    { id: "history",  icon: "history", label: "查询" },
    { id: "playback", icon: "route", label: "回放" },
    { id: "inbox",    icon: "bell",  label: "通知" },
    { id: "esg",      icon: "chart", label: "ESG" },
  ];
  return (
    <div style={{
      flex: "0 0 56px", height: 56, display: "grid", gridTemplateColumns: `repeat(${tabs.length}, 1fr)`,
      background: "var(--bg-1)", borderTop: "1px solid var(--border-1)",
      paddingBottom: "env(safe-area-inset-bottom)",
    }}>
      {tabs.map(t => (
        <button key={t.id} onClick={() => onChange(t.id)} style={{
          background: "transparent", border: "none", display: "flex", flexDirection: "column",
          alignItems: "center", justifyContent: "center", gap: 2, cursor: "pointer",
          color: active === t.id ? "var(--accent)" : "var(--fg-3)",
        }}>
          <Icon name={t.icon} size={18}/>
          <span style={{ fontSize: 10, fontWeight: active === t.id ? 600 : 400 }}>{t.label}</span>
        </button>
      ))}
    </div>
  );
};

// ── Mobile shell wrapper ───────────────────────────────────
const MobileShell = ({ title, subtitle, right, children, hideTabBar }) => {
  const ctx = window.useRoute();
  return (
    <div style={{
      width: "100%", height: "100%", display: "flex", flexDirection: "column",
      background: "var(--bg-0)", color: "var(--fg-1)", overflow: "hidden",
      fontFamily: "var(--font-sans)",
    }}>
      <MAppBar title={title} subtitle={subtitle} onMenu={ctx.openDrawer} right={right}/>
      <div style={{ flex: 1, minHeight: 0, position: "relative", overflow: "hidden" }}>
        {children}
      </div>
      {!hideTabBar && <MTabBar active={ctx.route} onChange={ctx.navigate}/>}
    </div>
  );
};

// ── 1. Mobile Overview: hero map + bottom sheet vehicle list ──
const MobileOverview = () => {
  const [selected, setSelected] = React.useState("浙F08638F");
  const [sheetOpen, setSheetOpen] = React.useState(false);
  const [filter, setFilter] = React.useState("all");
  const v = (window.VEHICLES || []).find(x => x.id === selected) || {};
  const vehicles = window.VEHICLES || [];
  const counts = { all: vehicles.length, ok: vehicles.filter(x=>x.status==="ok").length, warn: vehicles.filter(x=>x.status==="warn").length, danger: vehicles.filter(x=>x.status==="danger").length };
  const filtered = filter === "all" ? vehicles : vehicles.filter(x => x.status === filter);

  return (
    <MobileShell
      title="实时监控"
      subtitle="487/512 在线 · 312 行驶中"
      right={<><MIconBtn icon="search"/><MIconBtn icon="bell" badge="3" onClick={() => window.useRoute().navigate("inbox")}/></>}
    >
      {/* Map fills, sheet floats */}
      <div style={{ position: "absolute", inset: 0 }}>
        <FleetMap selected={selected} onSelect={setSelected}/>
      </div>

      {/* KPI strip floating on map */}
      <div style={{ position: "absolute", top: 12, left: 12, right: 12, display: "flex", gap: 8, overflowX: "auto", scrollbarWidth: "none" }}>
        {[
          { l: "在线率", v: "95.1%", c: "var(--ok)" },
          { l: "告警", v: "8", c: "var(--danger)" },
          { l: "今日里程", v: "24.7K km", c: "var(--fg-1)" },
          { l: "平均能耗", v: "1.16", c: "var(--info)" },
        ].map((k, i) => (
          <div key={i} style={{
            flex: "0 0 auto", padding: "8px 12px", background: "var(--bg-1)",
            border: "1px solid var(--border-1)", borderRadius: 10, boxShadow: "var(--shadow-1)",
          }}>
            <div style={{ fontSize: 10, color: "var(--fg-3)" }}>{k.l}</div>
            <div className="mono tnum" style={{ fontSize: 15, fontWeight: 600, color: k.c }}>{k.v}</div>
          </div>
        ))}
      </div>

      {/* Floating action: locate */}
      <button style={{
        position: "absolute", right: 14, bottom: sheetOpen ? "70%" : 130,
        width: 44, height: 44, borderRadius: 22, border: "1px solid var(--border-1)",
        background: "var(--bg-1)", color: "var(--accent)", display: "grid", placeItems: "center",
        boxShadow: "var(--shadow-2)", cursor: "pointer", transition: "bottom 280ms cubic-bezier(.3,0,.2,1)",
      }}>
        <Icon name="pin" size={18}/>
      </button>

      {/* Bottom sheet */}
      <div style={{
        position: "absolute", left: 0, right: 0, bottom: 0,
        height: sheetOpen ? "70%" : 120, background: "var(--bg-1)",
        borderTop: "1px solid var(--border-1)", borderRadius: "16px 16px 0 0",
        boxShadow: "0 -8px 24px -8px rgba(0,0,0,0.16)",
        transition: "height 320ms cubic-bezier(.3,0,.2,1)",
        display: "flex", flexDirection: "column", overflow: "hidden",
      }}>
        {/* Drag handle + selected vehicle quick card */}
        <div onClick={() => setSheetOpen(s => !s)} style={{ padding: "8px 16px 6px", cursor: "pointer" }}>
          <div style={{ width: 36, height: 4, background: "var(--border-2)", borderRadius: 2, margin: "0 auto 8px" }}/>
          <div className="between">
            <div className="mid gap-2">
              <span className={"dot " + v.status}/>
              <span className="mono strong" style={{ fontSize: 14 }}>{v.id}</span>
              <SourceBadge src={v.src}/>
              <span className="muted" style={{ fontSize: 11 }}>{v.deptName}</span>
            </div>
            <span className="mono" style={{ fontSize: 13, color: v.soc < 20 ? "var(--danger)" : "var(--fg-1)" }}>{v.soc}%</span>
          </div>
        </div>

        {!sheetOpen ? (
          // Mini quick stats when collapsed
          <div style={{ padding: "0 16px 12px", display: "flex", gap: 16, fontSize: 11 }}>
            <div className="col"><span className="muted">速度</span><span className="mono strong">{v.speed} km/h</span></div>
            <div className="col"><span className="muted">续航</span><span className="mono strong">{Math.round((v.soc||0)*6.2)} km</span></div>
            <div className="col"><span className="muted">温度</span><span className="mono strong">{v.status==="danger"?"102":"68"}°C</span></div>
            <button onClick={() => window.useRoute().navigate("detail")} className="btn primary sm" style={{ marginLeft: "auto", alignSelf: "center" }}>详情</button>
          </div>
        ) : (
          // Full list when expanded
          <>
            <div style={{ padding: "0 16px 8px", display: "flex", gap: 6, overflowX: "auto", scrollbarWidth: "none" }}>
              {[
                {id:"all", label:`全部 ${counts.all}`, c:""},
                {id:"ok", label:`行驶 ${counts.ok}`, c:"ok"},
                {id:"warn", label:`异常 ${counts.warn}`, c:"warn"},
                {id:"danger", label:`故障 ${counts.danger}`, c:"danger"},
              ].map(t => (
                <button key={t.id} onClick={() => setFilter(t.id)} className={"chip " + (filter===t.id ? "accent" : t.c)} style={{ flex: "0 0 auto", cursor: "pointer", padding: "6px 12px", fontSize: 12 }}>
                  {t.label}
                </button>
              ))}
            </div>
            <div style={{ flex: 1, overflowY: "auto" }}>
              {filtered.map(x => (
                <div key={x.id} onClick={() => { setSelected(x.id); }} style={{
                  padding: "12px 16px", borderBottom: "1px solid var(--border-1)",
                  display: "flex", alignItems: "center", gap: 12,
                  background: x.id === selected ? "var(--accent-soft)" : "transparent", cursor: "pointer",
                }}>
                  <span className={"dot " + x.status}/>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div className="mid gap-2">
                      <span className="mono strong" style={{ fontSize: 13 }}>{x.id}</span>
                      <SourceBadge src={x.src}/>
                    </div>
                    <div className="muted" style={{ fontSize: 11, marginTop: 2 }}>{x.deptName} · {x.speed} km/h</div>
                  </div>
                  <div style={{ textAlign: "right" }}>
                    <div className="mono" style={{ fontSize: 13, color: x.soc < 20 ? "var(--danger)" : "var(--fg-1)" }}>{x.soc}%</div>
                    <div style={{ width: 50, height: 3, background: "var(--bg-3)", borderRadius: 2, marginTop: 4 }}>
                      <div style={{ width: x.soc + "%", height: "100%", background: x.soc<20?"var(--danger)":x.soc<40?"var(--warn)":"var(--accent)", borderRadius: 2 }}/>
                    </div>
                  </div>
                </div>
              ))}
            </div>
          </>
        )}
      </div>
    </MobileShell>
  );
};

// ── 2. Mobile Detail ────────────────────────────────────────
const MobileDetail = () => {
  const vehicles = window.VEHICLES || [];
  const v = vehicles.find(x => x.id === "浙F03980F") || vehicles[0] || {};
  return (
    <MobileShell title={v.plate || v.id} subtitle={`${v.deptName || ''} · ${v.customer || ''}`} right={<MIconBtn icon="pin"/>}>
      <div style={{ height: "100%", overflowY: "auto", padding: 12, paddingBottom: 24 }}>
        {/* Hero status card */}
        <div className="panel" style={{ padding: 16, marginBottom: 12 }}>
          <div className="between" style={{ marginBottom: 12 }}>
            <div className="mid gap-2">
              <span className={"chip " + (v.asset === "abnormal" ? "danger" : v.asset === "leasing" ? "info" : "ok")}>
                <span className={"dot " + (v.asset === "abnormal" ? "danger" : v.asset === "leasing" ? "info" : "ok") + " pulse"}/>
                {v.asset === "leasing" ? "租赁" : v.asset === "abnormal" ? "异常" : "在库 · 运营中"}
              </span>
              <span className="chip" style={{fontSize:10, background: v.own === "self" ? "rgba(31,139,76,.10)" : "rgba(122,140,46,.12)", color: v.own === "self" ? "var(--accent)" : "#7A8C2E"}}>{v.own === "self" ? "自有" : "外租"}</span>
            </div>
            <SourceBadge src={v.src}/>
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
            <MStat label="车速" value={v.speed} unit="km/h" big/>
            <MStat label="续航" value={v.range} unit="km" big/>
            <MStat label="电池SOC" value={v.soc} unit="%" color={v.soc < 20 ? "var(--danger)" : "var(--ok)"}/>
            <MStat label="氢气压力" value={v.h2} unit="MPa" color="var(--info)"/>
            <MStat label="电机温度" value={v.motorTemp} unit="°C"/>
            <MStat label="累计里程" value={(v.totalKm/1000).toFixed(1)} unit="k km"/>
          </div>
        </div>

        <MSection title="业务关系">
          <div className="panel" style={{padding: 14}}>
            <div className="col gap-2" style={{fontSize:12}}>
              <div className="between"><span className="muted">业务部门</span>
                <span className="mid gap-1"><span style={{width:7,height:7,background:v.deptColor,borderRadius:1,display:"inline-block"}}/><span className="strong">{v.deptName}</span></span>
              </div>
              <div className="between"><span className="muted">业务负责人</span><span className="strong">{v.deptLead}</span></div>
              <div className="between"><span className="muted">客户</span><span style={{textAlign:"right", maxWidth:160}}>{v.customer}</span></div>
              <div className="between"><span className="muted">所属公司</span><span style={{fontSize:11,textAlign:"right"}}>{v.ownCompany}</span></div>
              {v.contractNo && <div className="between"><span className="muted">合同</span><span className="mono" style={{fontSize:11}}>{v.contractNo}</span></div>}
            </div>
          </div>
        </MSection>

        <MSection title="氢电系统">
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10 }}>
            <MMini label="燃料电池" value="42.5 kW" sub="输出功率"/>
            <MMini label="动力电池" value={v.soc + "%"} sub="SOC"/>
            <MMini label="H₂消耗" value="0.84 kg" sub="本次行程"/>
            <MMini label="电机扭矩" value="180 N·m" sub="实时"/>
          </div>
        </MSection>

        <MSection title="胎压与温度">
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }}>
            {[
              { l: "左前", p: "0.24", t: "32" },
              { l: "右前", p: "0.24", t: "33" },
              { l: "左后", p: "0.23", t: "31" },
              { l: "右后", p: v.asset === "abnormal" ? "0.16" : "0.24", t: "38", warn: v.asset === "abnormal" },
            ].map((tire, i) => (
              <div key={i} className="panel" style={{ padding: 12, border: tire.warn ? "1px solid var(--danger)" : "1px solid var(--border-1)" }}>
                <div className="between"><span className="muted" style={{ fontSize: 11 }}>{tire.l}</span>{tire.warn && <span className="chip danger" style={{ fontSize: 9 }}>低压</span>}</div>
                <div className="mono strong" style={{ fontSize: 18, color: tire.warn ? "var(--danger)" : "var(--fg-0)" }}>{tire.p}<span style={{ fontSize: 10, fontWeight: 400, color: "var(--fg-3)" }}> MPa</span></div>
                <div className="mono muted" style={{ fontSize: 11 }}>{tire.t}°C</div>
              </div>
            ))}
          </div>
        </MSection>

        <MSection title="保养预警">
          <div className="panel" style={{padding: 14}}>
            <div className="between" style={{marginBottom:8}}>
              <span className="muted" style={{fontSize:12}}>距下次保养</span>
              <span className="mono strong" style={{fontSize:16, color: v.kmToMaint < 1000 ? "var(--warn)" : "var(--accent)"}}>{v.kmToMaint.toLocaleString()} km</span>
            </div>
            <div className="bar" style={{height:5}}>
              <i style={{width: ((10000 - v.kmToMaint)/10000*100) + "%", background: v.kmToMaint < 1000 ? "var(--warn)" : "var(--accent)"}}/>
            </div>
            <div className="muted" style={{fontSize:11, marginTop:8}}>上次保养 {v.lastMaintDays} 天前 · {v.lastMaintKm.toLocaleString()} km</div>
          </div>
        </MSection>

        <MSection title="数据通道">
          <div className="col gap-2" style={{ fontSize: 12 }}>
            {[
              { l: "TBOX (3296/2016)", st: "ok", info: "5s 上报 · 信号 -68dBm" },
              { l: "JT808 部标", st: "ok", info: "实时 · 北京·朝阳" },
              { l: "JT1078 视频", st: "ok", info: "4 路 · 720P" },
            ].map((c, i) => (
              <div key={i} className="between" style={{ padding: "10px 12px", background: "var(--bg-2)", borderRadius: 8, border: "1px solid var(--border-1)" }}>
                <div>
                  <div className="strong" style={{ fontSize: 13 }}>{c.l}</div>
                  <div className="muted" style={{ fontSize: 11, marginTop: 2 }}>{c.info}</div>
                </div>
                <span className="dot ok"/>
              </div>
            ))}
          </div>
        </MSection>

        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8, marginTop: 16 }}>
          <button onClick={() => window.useRoute().navigate("playback")} className="btn primary" style={{ height: 44 }}><Icon name="route" size={14}/> 轨迹回放</button>
          <button onClick={() => window.useRoute().navigate("history")} className="btn" style={{ height: 44 }}><Icon name="history" size={14}/> 历史数据</button>
        </div>
      </div>
    </MobileShell>
  );
};

const MStat = ({ label, value, unit, color, big }) => (
  <div>
    <div className="muted" style={{ fontSize: 11 }}>{label}</div>
    <div className="mono strong tnum" style={{ fontSize: big ? 26 : 18, color: color || "var(--fg-0)", lineHeight: 1.1, marginTop: 2 }}>
      {value}<span style={{ fontSize: big ? 12 : 10, fontWeight: 400, color: "var(--fg-3)", marginLeft: 4 }}>{unit}</span>
    </div>
  </div>
);

const MMini = ({ label, value, sub }) => (
  <div style={{ padding: 10, background: "var(--bg-2)", borderRadius: 8, border: "1px solid var(--border-1)" }}>
    <div className="muted" style={{ fontSize: 10 }}>{label}</div>
    <div className="mono strong" style={{ fontSize: 15, marginTop: 2 }}>{value}</div>
    {sub && <div className="muted" style={{ fontSize: 10, marginTop: 1 }}>{sub}</div>}
  </div>
);

const MSection = ({ title, children, action }) => (
  <div style={{ marginBottom: 16 }}>
    <div className="between" style={{ marginBottom: 8, padding: "0 4px" }}>
      <span className="eyebrow" style={{ fontSize: 11 }}>{title}</span>
      {action}
    </div>
    {children}
  </div>
);

// ── 3. Mobile History ───────────────────────────────────────
const MobileHistory = () => {
  const [showFilter, setShowFilter] = React.useState(false);
  const trips = [
    { d: "04-28", t: "14:02–14:44", v: "浙F07179F", k: "32.4 km", h: "0.84 kg", st: "ok" },
    { d: "04-28", t: "10:11–11:03", v: "浙F07179F", k: "48.2 km", h: "1.21 kg", st: "ok" },
    { d: "04-28", t: "08:30–09:18", v: "浙F08638F", k: "29.8 km", h: "0.76 kg", st: "warn" },
    { d: "04-27", t: "17:42–18:25", v: "浙F07179F", k: "36.1 km", h: "0.92 kg", st: "ok" },
    { d: "04-27", t: "14:08–15:01", v: "浙F02002F", k: "44.5 km", h: "1.13 kg", st: "danger" },
    { d: "04-27", t: "09:22–10:14", v: "浙F07179F", k: "39.7 km", h: "1.01 kg", st: "ok" },
  ];
  return (
    <MobileShell title="历史查询" subtitle="近 7 日 · 187 条记录" right={<MIconBtn icon="filter" onClick={()=>setShowFilter(s=>!s)}/>}>
      <div style={{ height: "100%", display: "flex", flexDirection: "column" }}>
        {/* Search */}
        <div style={{ padding: "12px 12px 0" }}>
          <div className="search" style={{ height: 40 }}>
            <Icon name="search" size={14}/>
            <input placeholder="车牌 / VIN / 部门 / 客户" style={{ fontSize: 14 }}/>
          </div>
        </div>

        {/* Filter chips - horizontal scroll */}
        <div style={{ padding: "10px 12px", display: "flex", gap: 6, overflowX: "auto", scrollbarWidth: "none", flexShrink: 0 }}>
          <span className="chip accent" style={{ flex: "0 0 auto", padding: "6px 12px", fontSize: 12 }}>近 7 日</span>
          <span className="chip" style={{ flex: "0 0 auto", padding: "6px 12px", fontSize: 12 }}>编组A</span>
          <span className="chip" style={{ flex: "0 0 auto", padding: "6px 12px", fontSize: 12 }}>全部车型</span>
          <span className="chip" style={{ flex: "0 0 auto", padding: "6px 12px", fontSize: 12 }}>有告警</span>
        </div>

        {/* KPI summary */}
        <div style={{ padding: "0 12px 12px", display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 8, flexShrink: 0 }}>
          {[
            { l: "总里程", v: "1,847", u: "km", c: "var(--fg-0)" },
            { l: "氢耗", v: "47.2", u: "kg", c: "var(--info)" },
            { l: "减碳", v: "118", u: "kg", c: "var(--ok)" },
          ].map((k, i) => (
            <div key={i} style={{ padding: 10, background: "var(--bg-1)", border: "1px solid var(--border-1)", borderRadius: 8 }}>
              <div className="muted" style={{ fontSize: 10 }}>{k.l}</div>
              <div className="mono strong tnum" style={{ fontSize: 16, color: k.c }}>{k.v}<span style={{ fontSize: 10, fontWeight: 400, color: "var(--fg-3)" }}> {k.u}</span></div>
            </div>
          ))}
        </div>

        {/* Trip list */}
        <div style={{ flex: 1, overflowY: "auto", padding: "0 12px 16px" }}>
          {trips.map((t, i) => {
            const cls = t.st === "danger" ? "danger" : t.st === "warn" ? "warn" : "ok";
            return (
              <div key={i} className="panel" style={{ padding: 12, marginBottom: 8 }}>
                <div className="between" style={{ marginBottom: 6 }}>
                  <div className="mid gap-2">
                    <span className="mono strong" style={{ fontSize: 13 }}>{t.v}</span>
                    <span className={"chip " + cls} style={{ fontSize: 9 }}>{t.st === "danger" ? "故障" : t.st === "warn" ? "告警" : "正常"}</span>
                  </div>
                  <span className="muted mono" style={{ fontSize: 11 }}>{t.d} {t.t}</span>
                </div>
                <div style={{ display: "flex", gap: 14, fontSize: 12 }}>
                  <div><span className="muted">里程 </span><span className="mono strong">{t.k}</span></div>
                  <div><span className="muted">氢耗 </span><span className="mono strong">{t.h}</span></div>
                  <button onClick={() => window.useRoute().navigate("playback")} className="btn sm ghost" style={{ marginLeft: "auto", padding: "4px 10px", fontSize: 11 }}>回放</button>
                </div>
              </div>
            );
          })}
        </div>
      </div>
    </MobileShell>
  );
};

// ── 4. Mobile Playback ──────────────────────────────────────
const MobilePlayback = () => {
  const [t, setT] = React.useState(38);
  const [playing, setPlaying] = React.useState(true);
  const [speed, setSpeed] = React.useState(2);

  React.useEffect(() => {
    if (!playing) return;
    const id = setInterval(() => setT(v => (v + speed * 0.6) % 100), 200);
    return () => clearInterval(id);
  }, [playing, speed]);

  return (
    <MobileShell title="轨迹回放" subtitle="浙F07179F · 04-28 14:02 → 14:44">
      <div style={{ position: "absolute", inset: 0, display: "flex", flexDirection: "column" }}>
        {/* Map area */}
        <div style={{ flex: 1, minHeight: 0, position: "relative" }}>
          <FleetMap selected="浙F07179F" playbackPoint={{ x: 280 + t * 4, y: 260 + Math.sin(t/15) * 80 }}/>
          {/* Floating speed badge */}
          <div style={{ position: "absolute", top: 12, left: 12, padding: "8px 12px", background: "var(--bg-1)", border: "1px solid var(--border-1)", borderRadius: 10, boxShadow: "var(--shadow-1)" }}>
            <div className="muted" style={{ fontSize: 10 }}>当前速度</div>
            <div className="mono strong tnum" style={{ fontSize: 16 }}>{Math.round(40 + Math.sin(t/8)*20)} <span style={{ fontSize: 10, fontWeight: 400, color: "var(--fg-3)" }}>km/h</span></div>
          </div>
          <div style={{ position: "absolute", top: 12, right: 12, padding: "8px 12px", background: "var(--bg-1)", border: "1px solid var(--border-1)", borderRadius: 10, boxShadow: "var(--shadow-1)" }}>
            <div className="muted" style={{ fontSize: 10 }}>SOC</div>
            <div className="mono strong tnum" style={{ fontSize: 16, color: "var(--ok)" }}>{Math.round(78 - t * 0.15)}%</div>
          </div>
        </div>

        {/* Bottom playback panel */}
        <div style={{
          flex: "0 0 auto", background: "var(--bg-1)", borderTop: "1px solid var(--border-1)",
          padding: "12px 14px 16px", boxShadow: "0 -4px 16px -4px rgba(0,0,0,0.08)",
        }}>
          {/* Time + scrub */}
          <div className="between" style={{ marginBottom: 8 }}>
            <span className="mono strong" style={{ fontSize: 14 }}>14:{String(Math.floor(t * 0.42 + 2)).padStart(2,"0")}:{String(Math.floor(t*36)%60).padStart(2,"0")}</span>
            <span className="mono muted" style={{ fontSize: 11 }}>已 {Math.round(t*0.42)} 分 / 共 42 分</span>
          </div>
          <input type="range" min="0" max="100" value={t} onChange={e => setT(+e.target.value)} style={{
            width: "100%", height: 4, accentColor: "var(--accent)", marginBottom: 12,
          }}/>

          {/* Controls row */}
          <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
            <button onClick={() => setT(0)} style={ctrlBtn}><Icon name="route" size={14}/></button>
            <button onClick={() => setT(v => Math.max(0, v - 10))} style={ctrlBtn}>« 10s</button>
            <button onClick={() => setPlaying(p => !p)} style={{ ...ctrlBtn, width: 56, height: 44, background: "var(--accent)", color: "#fff", borderColor: "var(--accent)" }}>{playing ? "⏸" : "▶"}</button>
            <button onClick={() => setT(v => Math.min(100, v + 10))} style={ctrlBtn}>10s »</button>
            <select value={speed} onChange={e => setSpeed(+e.target.value)} style={{ ...ctrlBtn, padding: "0 10px" }}>
              {[0.5, 1, 2, 4, 8, 16].map(s => <option key={s} value={s}>{s}×</option>)}
            </select>
          </div>

          {/* Mini chart timeline events */}
          <div style={{ marginTop: 12, position: "relative", height: 24, background: "var(--bg-2)", borderRadius: 4 }}>
            {[12, 38, 65, 88].map((p, i) => (
              <div key={i} style={{ position: "absolute", left: p+"%", top: 0, bottom: 0, width: 2, background: i===2?"var(--danger)":"var(--warn)" }}/>
            ))}
            <div style={{ position: "absolute", left: t+"%", top: -4, bottom: -4, width: 2, background: "var(--accent)", boxShadow: "0 0 8px var(--accent)" }}/>
          </div>
          <div className="between" style={{ marginTop: 4, fontSize: 10 }}>
            <span className="muted">事件</span>
            <span className="mono muted">急刹×1 · 超速×2 · 故障×1</span>
          </div>
        </div>
      </div>
    </MobileShell>
  );
};

const ctrlBtn = {
  flex: 1, height: 40, display: "grid", placeItems: "center",
  background: "var(--bg-2)", border: "1px solid var(--border-1)",
  color: "var(--fg-1)", borderRadius: 8, fontSize: 12, fontFamily: "var(--font-mono)", cursor: "pointer",
};

// ── 5. Mobile Alarm Rules (list-based) ──────────────────────
const MobileAlarm = () => {
  const rules = [
    { n: "电池SOC严重不足", st: "on", trig: 12, cond: "SOC < 15% 持续 30s", p: "P0" },
    { n: "右后胎压低", st: "on", trig: 8, cond: "压力 < 0.20 MPa", p: "P0" },
    { n: "超速预警", st: "on", trig: 47, cond: "速度 > 限速 + 5 km/h", p: "P1" },
    { n: "H₂压力异常下降", st: "on", trig: 5, cond: "5min 内下降 > 1.0 MPa", p: "P0" },
    { n: "电堆过温保护", st: "on", trig: 3, cond: "温度 > 90°C", p: "P0" },
    { n: "急加速密集", st: "on", trig: 31, cond: "5min 内 ≥ 3 次", p: "P2" },
    { n: "疲劳驾驶", st: "off", trig: 0, cond: "连续驾驶 > 4h", p: "P1" },
  ];
  return (
    <MobileShell title="事件规则" subtitle={`${rules.filter(r=>r.st==="on").length} / ${rules.length} 启用`} right={<MIconBtn icon="plus"/>}>
      <div style={{ height: "100%", overflowY: "auto", padding: 12 }}>
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 8, marginBottom: 12 }}>
          {[
            { l: "P0 紧急", v: 4, c: "var(--danger)" },
            { l: "P1 警告", v: 2, c: "var(--warn)" },
            { l: "P2 提示", v: 1, c: "var(--info)" },
          ].map((k, i) => (
            <div key={i} style={{ padding: 10, background: "var(--bg-1)", border: "1px solid var(--border-1)", borderRadius: 8 }}>
              <div className="muted" style={{ fontSize: 10 }}>{k.l}</div>
              <div className="mono strong" style={{ fontSize: 18, color: k.c }}>{k.v}</div>
            </div>
          ))}
        </div>

        {rules.map((r, i) => (
          <div key={i} className="panel" style={{ padding: 14, marginBottom: 8 }}>
            <div className="between" style={{ marginBottom: 6 }}>
              <div className="mid gap-2">
                <span className={"chip " + (r.p==="P0"?"danger":r.p==="P1"?"warn":"info")} style={{ fontSize: 9 }}>{r.p}</span>
                <span className="strong" style={{ fontSize: 14 }}>{r.n}</span>
              </div>
              <MSwitch on={r.st==="on"}/>
            </div>
            <div className="muted mono" style={{ fontSize: 11, marginBottom: 6 }}>{r.cond}</div>
            <div className="between" style={{ fontSize: 11 }}>
              <span className="muted">7日触发 <span className="mono strong" style={{ color: "var(--fg-1)" }}>{r.trig}</span> 次</span>
              <span className="muted">短信 · App推送 · 邮件</span>
            </div>
          </div>
        ))}
      </div>
    </MobileShell>
  );
};

const MSwitch = ({ on }) => (
  <div style={{
    width: 36, height: 20, borderRadius: 10, padding: 2,
    background: on ? "var(--accent)" : "var(--bg-3)", transition: "background 200ms",
  }}>
    <div style={{
      width: 16, height: 16, borderRadius: 8, background: "#fff",
      transform: on ? "translateX(16px)" : "translateX(0)",
      transition: "transform 200ms cubic-bezier(.3,0,.2,1)",
      boxShadow: "0 1px 2px rgba(0,0,0,0.2)",
    }}/>
  </div>
);

// ── 6. Mobile Inbox ─────────────────────────────────────────
const MobileInbox = () => {
  const [filter, setFilter] = React.useState("all");
  const alerts = [
    {p:"P0", n:"电池SOC严重不足", v:"浙F08638F", t:"刚刚", det:"SOC 9% < 阈值 15% · 持续 4分20秒", st:"new"},
    {p:"P0", n:"右后胎压低", v:"浙F08638F", t:"3分钟前", det:"0.16 MPa · 阈值 0.20 MPa", st:"new"},
    {p:"P1", n:"超速预警", v:"浙F02002F", t:"12分钟前", det:"实测 89 km/h · 限速 80 km/h · 持续 12s", st:"new"},
    {p:"P1", n:"H₂压力异常下降", v:"浙F07179F", t:"32分钟前", det:"5分钟内下降 1.2 MPa", st:"ack"},
    {p:"P0", n:"电堆过温保护", v:"浙F00598F", t:"1小时前", det:"电堆温度 95°C · 阈值 90°C", st:"resolved"},
    {p:"P2", n:"急加速密集", v:"浙F02608F", t:"2小时前", det:"5分钟内 3 次急加速", st:"resolved"},
    {p:"P1", n:"偏离规划路线", v:"浙F00278F", t:"3小时前", det:"偏离 1.2 km · 持续 6 分钟", st:"resolved"},
  ];
  const filtered = filter === "all" ? alerts : filter === "new" ? alerts.filter(a=>a.st==="new") : alerts.filter(a=>a.p===filter);
  return (
    <MobileShell title="通知中心" subtitle="3 未处理 · 24 今日">
      <div style={{ height: "100%", display: "flex", flexDirection: "column" }}>
        <div style={{ padding: "10px 12px 8px", display: "flex", gap: 6, overflowX: "auto", scrollbarWidth: "none", flexShrink: 0, borderBottom: "1px solid var(--border-1)" }}>
          {[
            {id:"all", l:"全部 24"},
            {id:"new", l:"未处理 3"},
            {id:"P0", l:"P0 · 2"},
            {id:"P1", l:"P1 · 8"},
            {id:"P2", l:"P2 · 14"},
          ].map(t => (
            <button key={t.id} onClick={()=>setFilter(t.id)} className={"chip " + (filter===t.id?"accent":"")} style={{ flex: "0 0 auto", padding: "6px 12px", fontSize: 12, cursor: "pointer" }}>{t.l}</button>
          ))}
        </div>
        <div style={{ flex: 1, overflowY: "auto" }}>
          {filtered.map((a, i) => {
            const c = a.p === "P0" ? "var(--danger)" : a.p === "P1" ? "var(--warn)" : "var(--info)";
            return (
              <div key={i} style={{
                display: "flex", gap: 12, padding: "14px 14px",
                borderBottom: "1px solid var(--border-1)",
                background: a.st === "new" ? "var(--accent-soft)" : "transparent",
              }}>
                <div style={{ flexShrink: 0 }}>
                  <div style={{ width: 36, height: 36, borderRadius: 18, background: a.st === "new" ? c : "var(--bg-3)", opacity: a.st==="resolved"?0.4:1, display: "grid", placeItems: "center", color: "#fff", boxShadow: a.st === "new" ? `0 0 12px ${c}` : "none" }}>
                    <Icon name="bell" size={14}/>
                  </div>
                </div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div className="between">
                    <div className="mid gap-2">
                      <span className={"chip " + (a.p==="P0"?"danger":a.p==="P1"?"warn":"info")} style={{ fontSize: 9, padding: "2px 6px" }}>{a.p}</span>
                      <span className="strong" style={{ fontSize: 13 }}>{a.n}</span>
                    </div>
                    <span className="mono muted" style={{ fontSize: 11 }}>{a.t}</span>
                  </div>
                  <div className="mono muted" style={{ fontSize: 11, marginTop: 2 }}>{a.v}</div>
                  <div className="muted" style={{ fontSize: 12, marginTop: 4 }}>{a.det}</div>
                  {a.st === "new" && (
                    <div style={{ display: "flex", gap: 6, marginTop: 10 }}>
                      <button onClick={()=>window.useRoute().navigate("playback")} className="btn sm primary" style={{ fontSize: 11 }}><Icon name="route" size={11}/> 轨迹</button>
                      <button className="btn sm" style={{ fontSize: 11 }}>确认</button>
                      <button className="btn sm ghost" style={{ fontSize: 11 }}>忽略</button>
                    </div>
                  )}
                </div>
              </div>
            );
          })}
        </div>
      </div>
    </MobileShell>
  );
};

// ── 7. Mobile ESG ────────────────────────────────────────────
const MobileESG = () => {
  return (
    <MobileShell title="ESG · 碳减排" subtitle="羚牛 ESG Link">
      <div style={{ height: "100%", overflowY: "auto", padding: 12 }}>
        {/* Hero stat */}
        <div className="panel" style={{ padding: 16, marginBottom: 12, background: "linear-gradient(135deg, #007143, #00A35F)", color: "#fff", border: "none" }}>
          <div style={{ fontSize: 11, opacity: 0.85 }}>本年度累计减碳</div>
          <div className="mono tnum" style={{ fontSize: 36, fontWeight: 700, lineHeight: 1.1, margin: "4px 0" }}>1,847.2<span style={{ fontSize: 14, fontWeight: 400, opacity: 0.85, marginLeft: 6 }}>tCO₂e</span></div>
          <div style={{ fontSize: 11, opacity: 0.85 }}>较去年同期 ▲ 32.4%</div>
        </div>

        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8, marginBottom: 12 }}>
          {[
            { l: "氢能消耗", v: "47.2", u: "万 m³", c: "var(--info)" },
            { l: "里程", v: "1.84", u: "万 km", c: "var(--fg-0)" },
            { l: "碳交易收益", v: "18.78", u: "万元", c: "var(--accent)" },
            { l: "覆盖城市", v: "23", u: "个", c: "var(--fg-0)" },
          ].map((k, i) => (
            <div key={i} className="panel" style={{ padding: 12 }}>
              <div className="muted" style={{ fontSize: 10 }}>{k.l}</div>
              <div className="mono strong tnum" style={{ fontSize: 18, color: k.c, marginTop: 2 }}>{k.v}<span style={{ fontSize: 10, fontWeight: 400, color: "var(--fg-3)", marginLeft: 4 }}>{k.u}</span></div>
            </div>
          ))}
        </div>

        <MSection title="月度减碳趋势">
          <div className="panel" style={{ padding: 14 }}>
            <svg viewBox="0 0 320 120" width="100%" height="100" style={{ overflow: "visible" }}>
              {[180,220,255,235,290,270,310,345,320,355,380,420].map((v, i, arr) => {
                const x = 12 + i * 26;
                const h = (v / 420) * 90;
                return (
                  <g key={i}>
                    <rect x={x-9} y={108-h} width="18" height={h} fill="var(--accent)" rx="2" opacity={i===11?1:0.65}/>
                    {i%3===0 && <text x={x} y="118" fontSize="9" fill="var(--fg-3)" textAnchor="middle">{i+1}月</text>}
                  </g>
                );
              })}
            </svg>
          </div>
        </MSection>

        <MSection title="车辆减碳排行 Top 5">
          <div className="col gap-1">
            {[
              { p:"浙F·8A03F", v: 24.38 },
              { p:"浙F·2C57G", v: 22.15 },
              { p:"浙F·9D14B", v: 19.84 },
              { p:"浙F·6E72H", v: 17.21 },
              { p:"浙F·1B49K", v: 15.67 },
            ].map((r, i) => (
              <div key={i} className="between" style={{ padding: "10px 12px", background: "var(--bg-1)", border: "1px solid var(--border-1)", borderRadius: 8 }}>
                <span className="mid gap-2">
                  <span className="mono" style={{ fontSize: 11, color: "var(--fg-3)", width: 16 }}>#{i+1}</span>
                  <span className="mono strong" style={{ fontSize: 13 }}>{r.p}</span>
                </span>
                <span className="mono strong" style={{ fontSize: 13, color: "var(--accent)" }}>{r.v} <span style={{ fontSize: 10, fontWeight: 400, color: "var(--fg-3)" }}>kg</span></span>
              </div>
            ))}
          </div>
        </MSection>
      </div>
    </MobileShell>
  );
};

// ── Mobile route map ────────────────────────────────────────
const MOBILE_PAGES = {
  overview: MobileOverview,
  detail: MobileDetail,
  history: MobileHistory,
  playback: MobilePlayback,
  alarm: MobileAlarm,
  inbox: MobileInbox,
  esg: MobileESG,
};

const MobileRouter = ({ route }) => {
  const Cmp = MOBILE_PAGES[route];
  if (!Cmp) {
    return (
      <MobileShell title="设计画板" subtitle="该页面仅桌面端可用">
        <div style={{ padding: 24, textAlign: "center", color: "var(--fg-2)" }}>
          <Icon name="settings" size={32}/>
          <div style={{ marginTop: 12, fontSize: 14 }}>设计画板模式</div>
          <div style={{ fontSize: 12, color: "var(--fg-3)", marginTop: 4 }}>请在桌面端访问以查看完整设计稿</div>
          <button onClick={() => window.useRoute().navigate("overview")} className="btn primary" style={{ marginTop: 16, height: 40, padding: "0 20px" }}>返回主页</button>
        </div>
      </MobileShell>
    );
  }
  return <Cmp/>;
};

window.MobileRouter = MobileRouter;
window.MobileShell = MobileShell;
