/* wf1 Web Console — 页面/功能专属样式(控制台 / 落地页 / 目标横幅 / 定制封面 / 积木 tab)。
   设计 token(:root)在 tokens.css(由 pf_color.h + token_map.json 生成);通用原语
   (reset / #app / .btn / .field / .modal / .empty / .badge)在 base.css。
   <link> 顺序:tokens.css → base.css → style.css。 */

/* 顶栏 */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-6);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--border);
}
.topbar h1 {
  margin: 0;
  font-size: var(--font-xl);
  font-weight: 600;
}
.topbar .sub {
  color: var(--text-dim);
  font-size: var(--font-sm);
}

/* =====================================================================
   host 控制台页(app.js + settings.js DashboardTab)—— IoT dashboard 风格
   顶部条 + 主导航 + Hero 总览卡 + 控制卡网格。双主题。
   注:per-app 定制页仍用 .topbar(上方),本段只服务 host 控制台页。
   ===================================================================== */

/* ---- 全屏外壳:左 icon rail + 主区(fixed 突破 #app 居中限制) ---- */
.app-shell { position: fixed; inset: 0; display: grid; grid-template-columns: 216px 1fr; }
.rail {
  background: var(--rail); border-right: 1px solid var(--border);
  display: flex; flex-direction: column; padding: 12px 10px; gap: 2px; overflow: auto;
}
.rail__brand { display: flex; align-items: center; gap: 9px; padding: 6px 8px 12px; }
.rail__mark {
  width: 40px; height: 40px; border-radius: 10px; flex: none;
  /* rimu 官方 logo(rimu.me favicon 512x512),内联 data URI 保持零 CDN。白底 tile 衬托青色字形。 */
  background: #fff url("data:image/png;base64,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") center/78% no-repeat;
}
.rail__name { font-size: 15px; font-weight: 650; letter-spacing: -.01em; }
.rail__nav { display: flex; flex-direction: column; gap: 2px; }
.rail__btn {
  display: flex; align-items: center; gap: 11px; width: 100%; text-align: left;
  padding: 9px 10px; border: 0; background: none; border-radius: 8px; color: var(--text-dim);
  cursor: pointer; font: inherit; font-size: 13.5px;
}
.rail__btn svg { width: 18px; height: 18px; flex: none; }
.rail__btn:hover { background: var(--bg-card); color: var(--text); }
.rail__btn.is-active { background: color-mix(in srgb, var(--primary) 16%, transparent); color: var(--text); }
.rail__btn.is-active svg { color: var(--primary); }

/* 系统面板:导航栏底部,竖排紧凑设备信息 + 维护操作 */
.railsys { margin-top: auto; padding-top: 12px; border-top: 1px solid var(--border); }
.railsys__hd { display: flex; align-items: center; gap: 7px; padding: 4px 8px 8px; font-size: 11px; font-weight: 600; color: var(--text-dim); text-transform: uppercase; letter-spacing: .05em; }
.railsys__hd svg { width: 15px; height: 15px; }
.railsys__info { display: flex; flex-direction: column; gap: 7px; padding: 2px 8px 10px; }
.railsys__row { display: flex; flex-direction: column; gap: 1px; }
.railsys__row .k { font-size: 11px; color: var(--text-dim); }
.railsys__row .v { font-size: 12px; font-variant-numeric: tabular-nums; word-break: break-all; }
.railsys__acts { display: flex; flex-wrap: wrap; gap: 6px; padding: 0 8px; }
.railsys__acts .dbtn { font: inherit; font-size: 12px; padding: 5px 10px; border-radius: 7px; border: 1px solid var(--border); background: var(--bg-elev); color: var(--text); cursor: pointer; }
.railsys__acts .dbtn:disabled { opacity: .5; cursor: not-allowed; }
.railsys__acts .dbtn--primary:not(:disabled) { background: var(--primary); border-color: var(--primary); color: #fff; }
.railsys__acts .dbtn--danger { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 45%, var(--border)); }

.main { min-width: 0; display: flex; flex-direction: column; overflow: hidden; }

/* ---- 顶栏:品牌 + 连接名 + 连接条 + 主题(设备详情在 Hero 卡,这里不重复) ---- */
.console-top { display: flex; align-items: center; gap: var(--space-3); padding: 11px 22px; border-bottom: 1px solid var(--border); flex: none; flex-wrap: wrap; }
.console-top .brand { font-size: 19px; font-weight: 650; letter-spacing: -.01em; }
.console-top__conn { font-size: var(--font-sm); color: var(--text-dim); display: inline-flex; align-items: center; gap: var(--space-2); }
.console-top .spacer { flex: 1; }
.chan-pill {
  font-size: var(--font-sm); color: var(--text-dim);
  border: 1px solid var(--border); border-radius: 999px; padding: 1px 8px;
}

/* 内容区:普通滚动块(Hero + 控制卡网格从上往下排) */
.console-content { flex: 1; min-height: 0; overflow: auto; padding: var(--space-6) var(--space-4); }

/* 卡片基类:Hero / 控制卡共用。背景 + 描边 + 阴影(主题适配:深色偏重浮起,Apple 浅色极轻)。 */
.card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: 0 1px 0 rgba(0, 0, 0, .2), 0 10px 26px -18px rgba(0, 0, 0, .6);
  transition: background .2s, border-color .2s, box-shadow .2s;
}
:root[data-theme="light"] .card { box-shadow: 0 1px 2px rgba(0, 0, 0, .04), 0 8px 22px -16px rgba(0, 0, 0, .12); }

/* 主题切换按钮(顶栏) */
.theme-toggle {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--bg-elev); border: 1px solid var(--border); color: var(--text);
  border-radius: var(--radius); padding: 7px 12px;
  font: inherit; font-size: var(--font-sm); cursor: pointer;
  transition: background .15s, border-color .15s;
}
.theme-toggle:hover { border-color: var(--primary-dim); }
.theme-toggle svg { width: 15px; height: 15px; }

/* 主题切换时页面底色/文字平滑过渡 */
body { transition: background .2s, color .2s; }

/* ---- Hero 设备总览卡 ---- */
.hero {
  display: grid; grid-template-columns: auto 1fr; gap: var(--space-6);
  padding: var(--space-4) var(--space-6); align-items: center; margin-bottom: var(--space-6);
}
.hero__ring { position: relative; width: 128px; height: 128px; flex: none; }
.hero__lbl { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.hero__lbl b { font-size: 29px; font-weight: 680; letter-spacing: -.02em; }
.hero__lbl b small { font-size: 15px; }
.hero__lbl span { font-size: 11px; color: var(--text-dim); margin-top: 2px; }
.hero__info { min-width: 0; }
.hero__id { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-1); flex-wrap: wrap; }
.hero__dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.hero__nm { font-size: 22px; font-weight: 650; letter-spacing: -.01em; }
.hero__role { font-size: 11px; color: var(--text-dim); border: 1px solid var(--border); border-radius: 999px; padding: 2px 9px; }
.hero__sub { color: var(--text-dim); font-size: var(--font-sm); margin-bottom: var(--space-4); }
.hero__stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-3); }
.hero__stats .stat .k { font-size: 11px; color: var(--text-dim); margin-bottom: 3px; }
.hero__stats .stat .v { font-size: var(--font-lg); font-weight: 600; }

/* ---- 控制卡网格 ---- */
.dash-sectitle {
  font-size: var(--font-sm); font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-dim); margin: 0 var(--space-1) var(--space-3);
}
/* 行优先规整网格(对齐设计稿):卡片按行铺,同一行拉到等高(默认 stretch),底边对齐成干净横带。 */
.dash-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: var(--space-4); }
.cc__hd { display: flex; align-items: center; gap: 9px; padding: var(--space-4) var(--space-4) var(--space-1); }
.cc__ic { width: 16px; height: 16px; color: var(--text-dim); flex: none; }
.cc__t { font-size: var(--font-sm); font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--text-dim); }
.cc__bd { padding: 0 var(--space-4) var(--space-2); }

/* ---- range 滑块(Field slider):标签在上 + 整行滑块 + 填充 ---- */
.slider-field { padding: var(--space-3) 0; }
.slider-field__top { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: var(--space-2); }
.slider-field__top > span:first-child { font-size: var(--font-md); }
.slider-field__val { font-size: var(--font-lg); font-weight: 600; }
input[type=range] {
  -webkit-appearance: none; appearance: none; width: 100%; height: 6px; border-radius: 999px; outline: 0; cursor: pointer;
  background: linear-gradient(90deg, var(--primary) var(--p, 0%), var(--bg-elev) var(--p, 0%));
}
input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 18px; height: 18px; border-radius: 50%; background: #fff; border: 3px solid var(--primary); cursor: pointer; box-shadow: 0 1px 4px rgba(0,0,0,.5); }
input[type=range]::-moz-range-thumb { width: 15px; height: 15px; border-radius: 50%; background: #fff; border: 3px solid var(--primary); cursor: pointer; }

/* 状态行(StatusStrip):保留供 per-app 页复用 */
.status-strip {
  display: flex; gap: var(--space-4); align-items: center; flex-wrap: wrap;
  font-size: var(--font-sm); color: var(--text-dim);
  padding: var(--space-3) 0; border-top: 1px solid var(--border);
}
.status-strip code { font-family: monospace; }

@media (max-width: 560px) {
  .hero { grid-template-columns: 1fr; justify-items: start; }
  .hero__stats { grid-template-columns: repeat(2, 1fr); }
}

/* 设备列表 */
.device-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: var(--space-4);
}

/* 设备卡片 */
.device-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
}
.device-card .head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-3);
}
.device-card .head .name {
  font-weight: 600;
  font-size: var(--font-lg);
}
.device-card .head .badge {
  font-size: var(--font-sm);
  padding: 2px 8px;
  border-radius: 10px;
  background: color-mix(in srgb, var(--ok) 15%, transparent);
  color: var(--ok);
}
.device-card .head .badge.offline {
  background: color-mix(in srgb, var(--danger) 15%, transparent);
  color: var(--danger);
}
.device-card .meta {
  color: var(--text-dim);
  font-size: var(--font-sm);
  margin-bottom: var(--space-3);
}
.device-card .mods {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* ---- 落地页(landing.js):固件清单 ---- */
.landing__head { margin-bottom: var(--space-6); }
.landing__head h1 { margin: 0 0 var(--space-2); font-size: var(--font-xl); font-weight: 600; }
.landing__head .sub { color: var(--text-dim); font-size: var(--font-sm); max-width: 640px; }
.landing__section { margin-bottom: var(--space-6); }
.landing__section h2 {
  font-size: var(--font-md); font-weight: 600; color: var(--text-dim);
  text-transform: uppercase; letter-spacing: .04em; margin: 0 0 var(--space-3);
}
.landing__foot { margin-top: var(--space-8); padding-top: var(--space-4); border-top: 1px solid var(--border); }
.landing__foot a { color: var(--primary); text-decoration: none; }
.landing__foot a:hover { text-decoration: underline; }
.landing .err { color: var(--danger); }

.app-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: var(--space-3);
}
.app-card {
  display: block;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  text-decoration: none;
  color: var(--text);
  transition: border-color .15s, transform .1s;
}
.app-card:hover { border-color: var(--primary-dim); transform: translateY(-1px); }
.app-card--placeholder { opacity: .55; }
.app-card__display { font-size: var(--font-lg); font-weight: 600; margin-bottom: var(--space-1); }
.app-card__id { font-size: var(--font-sm); color: var(--text-dim); margin-bottom: var(--space-2); }
.app-card__meta { display: flex; gap: var(--space-2); align-items: center; flex-wrap: wrap; }
.app-card__hex { font-size: var(--font-sm); color: var(--text-dim); font-family: monospace; }
.badge--custom { background: color-mix(in srgb, var(--primary) 15%, transparent); color: var(--primary); }
.badge--ph { background: color-mix(in srgb, var(--text-dim) 15%, transparent); color: var(--text-dim); }

/* ---- 目标固件横幅(app.js TargetBanner) ---- */
.target-banner {
  display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-left: 3px solid var(--primary);
  border-radius: var(--radius);
  padding: var(--space-2) var(--space-3);
  margin-bottom: var(--space-4);
  font-size: var(--font-sm);
}
.target-banner--warn { border-left-color: var(--warn); }
.target-banner code { color: var(--text-dim); }
.target-banner__home { margin-left: auto; color: var(--primary); text-decoration: none; }
.target-banner__home:hover { text-decoration: underline; }
.target-banner__warn { flex-basis: 100%; color: var(--warn); }

/* ---- 定制封面页(apps/<id>/index.html) ---- */
.app-cover {
  max-width: 560px; margin: var(--space-8) auto; padding: var(--space-6);
  background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius-lg);
}
.app-cover__home { color: var(--primary); text-decoration: none; font-size: var(--font-sm); }
.app-cover h1 { margin: var(--space-4) 0 var(--space-2); }
.app-cover__id { color: var(--text-dim); font-size: var(--font-sm); margin: 0 0 var(--space-4); }
.app-cover__desc { color: var(--text-dim); margin-bottom: var(--space-6); }
.app-cover__go {
  display: inline-block; padding: var(--space-2) var(--space-4);
  background: var(--primary); color: var(--bg); border-radius: var(--radius);
  text-decoration: none; font-weight: 600;
}
.app-cover__go:hover { background: var(--primary-dim); }

/* ---- 积木 tab（app.js BlocklyTab，复用 studio 逻辑） ---- */
.blockly-tab__toolbar {
  display: flex; gap: var(--space-2); align-items: center; flex-wrap: wrap;
  margin-bottom: var(--space-3);
}
.blockly-tab__status { font-size: var(--font-sm); color: var(--text-dim); margin-left: auto; }
.blockly-tab__body {
  display: flex; gap: var(--space-3);
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  overflow: hidden; min-height: 0;
}
.blockly-tab__canvas { flex: 1; min-width: 0; height: 60vh; }
.blockly-tab__side {
  width: 320px; border-left: 1px solid var(--border);
  display: flex; flex-direction: column; min-height: 0;
}
.blockly-tab__side h3 {
  font-size: var(--font-sm); color: var(--text-dim); margin: 0;
  padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--border);
  text-transform: uppercase; letter-spacing: .05em; font-weight: 600;
}
.blockly-tab__preview {
  flex: 1; overflow: auto; margin: 0; padding: var(--space-2) var(--space-3);
  font-family: monospace; font-size: var(--font-sm); color: #9ccc65;
  background: #071216; white-space: pre;
}
.blockly-tab__log {
  height: 34%; overflow: auto; margin: 0; padding: var(--space-2) var(--space-3);
  font-family: monospace; font-size: var(--font-sm); color: var(--text-dim);
  background: #000; border-top: 1px solid var(--border); white-space: pre-wrap;
}

/* ── pill 开关 ──
   设置行的 toggle。开态用 --primary(源自 pf_color.h INFO,设备↔web 单一色源),
   替代原生 checkbox。纯 CSS,不改 onChange 逻辑。 */
input.sw {
  appearance: none; -webkit-appearance: none;
  position: relative; flex: none;
  width: 40px; height: 24px; margin: 0;
  border-radius: 999px;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  cursor: pointer;
  transition: background .18s ease, border-color .18s ease;
}
input.sw::after {
  content: ""; position: absolute; top: 2px; left: 2px;
  width: 18px; height: 18px; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, .4);
  transition: transform .18s ease;
}
input.sw:checked {
  background: var(--primary); border-color: var(--primary);
}
input.sw:checked::after { transform: translateX(16px); }
input.sw:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

/* WiFi/蓝牙 扫描结果列表:限高 + 内部滚动,避免真机扫到十几个网络时把卡片撑得过高、行间失衡。 */
.scan-list { max-height: 220px; overflow-y: auto; }

/* landing 页头品牌:rimu logo + 标题横排对齐。 */
.landing__brand { display: flex; align-items: center; gap: 12px; }
.landing__brand h1 { margin: 0; }
