/* ============================================================
   HoldSay — production UI stylesheet (Braun system)
   Extracted verbatim from the design handoff (HoldSay_Design/styles.css)
   so the shipping app is pixel-identical to the gold-standard screenshots,
   plus Braun-token sections for surfaces the design canvas didn't draw
   (Settings, Pro, Templates, empty states). Everything reads from the same
   token set; never hardcode a surface color inside a component.
   ============================================================ */

:root{
  --font: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text", "Segoe UI", system-ui, sans-serif;
  --mono: "Roboto Mono", "SF Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;
}

*{ box-sizing:border-box; }
html,body{ margin:0; height:100%; }
/* #root must carry the full height too, otherwise the percentage-height chain
   breaks here: .ba (height:100%) would collapse to content height, the flex
   columns grow past the viewport, and the inner overflow:auto panes never
   become scroll containers (they just get clipped by .ba's overflow:hidden). */
#root{ height:100%; }
body{ font-family:var(--font); -webkit-font-smoothing:antialiased; user-select:none; cursor:default; }

/* fine grain noise overlay (skeuomorphic widget only) */
.bw-grain::after{
  content:""; position:absolute; inset:0; border-radius:inherit; pointer-events:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity:.04; mix-blend-mode:multiply;
}

/* ============================================================
   FLOATING WIDGET — "Braun" desktop panel (skeuomorphic)
   ============================================================ */
.bw{
  position:relative; width:372px; height:244px; display:flex;
  border-radius:6px 34px 34px 6px;
  background:linear-gradient(180deg,#efece6 0%,#e4e0d7 100%);
  color:#2c2c2e; font-family:var(--font);
  box-shadow:
    0 1px 0 rgba(255,255,255,.95) inset,
    0 -1px 2px rgba(0,0,0,.05) inset,
    0 0 0 1px rgba(0,0,0,.11),
    0 18px 42px -14px rgba(40,40,45,.42);
}

.bw-rail{
  flex:0 0 118px; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:16px;
  padding:18px 0;
  border-right:1px solid rgba(0,0,0,.10);
  box-shadow:1px 0 0 rgba(255,255,255,.75);
}
.bw-keywrap{ position:relative; display:flex; flex-direction:column; align-items:center; gap:7px; }
.bw-legend{ font-family:var(--mono); font-size:9px; font-weight:700; letter-spacing:.17em; color:#908d85; }

.bw-rec{
  position:relative; width:60px; height:60px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  background:radial-gradient(circle at 50% 36%, #fcfbf8, #e7e3db 70%, #d6d2c8);
  box-shadow:
    0 1px 0 rgba(255,255,255,.95) inset,
    0 -2px 4px rgba(0,0,0,.10) inset,
    0 0 0 1px rgba(0,0,0,.13),
    0 3px 6px rgba(0,0,0,.16);
  cursor:pointer;
}
.bw-rec::after{
  content:""; width:15px; height:15px; border-radius:50%;
  background:radial-gradient(circle at 38% 32%, #ff6e51, #e8402a 58%, #c5301c);
  box-shadow:0 0 0 1px rgba(150,30,15,.28), 0 1px 1px rgba(0,0,0,.22);
}
/* perforated microphone ring around the record key */
.bw-mic{
  position:absolute; top:-7px; left:50%; transform:translateX(-50%);
  width:74px; height:74px; pointer-events:none;
  background-image:radial-gradient(circle, rgba(0,0,0,.20) .8px, transparent 1.3px);
  background-size:6px 6px;
  -webkit-mask:radial-gradient(circle, transparent 33px, #000 34px, #000 36px, transparent 37px);
          mask:radial-gradient(circle, transparent 33px, #000 34px, #000 36px, transparent 37px);
}
.bw-rec.is-live{
  background:radial-gradient(circle at 50% 36%, #ff8068, #e8402a 56%, #c5301c);
  box-shadow:
    0 1px 0 rgba(255,255,255,.4) inset,
    0 0 0 1px rgba(150,30,15,.4),
    0 0 16px rgba(232,64,42,.38),
    0 3px 7px rgba(0,0,0,.2);
}
.bw-rec.is-live::after{ width:16px; height:16px;
  background:#fff; box-shadow:0 0 8px rgba(255,255,255,.75); }

/*
.bw-file{
  width:50px; height:46px; border-radius:12px; color:#5c5a54;
  display:flex; align-items:center; justify-content:center;
  background:linear-gradient(180deg,#f3f0ea,#e0dcd2);
  box-shadow:
    0 1px 0 rgba(255,255,255,.95) inset,
    0 -2px 4px rgba(0,0,0,.07) inset,
    0 0 0 1px rgba(0,0,0,.11),
    0 2px 5px rgba(0,0,0,.13);
  cursor:pointer;
}
.bw-file svg{ width:22px; height:22px; }
.bw-file.is-dim{ opacity:.34; pointer-events:none; }
*/
.bw-file-slot{ width:50px; height:63px; }

.bw-body{ flex:1; min-width:0; padding:15px 24px; display:flex; flex-direction:column; justify-content:center; }
.bw-slogan{ display:flex; align-items:center; gap:9px; margin-bottom:12px; }
.bw-logo{ position:relative; width:16px; height:16px; border-radius:5px; background:#2a2a2e; box-shadow:0 1px 2px rgba(0,0,0,.22); flex:0 0 auto; }
.bw-logo::after{ content:""; position:absolute; left:50%; top:50%; transform:translate(-50%,-50%); width:5px; height:5px; border-radius:50%; background:#e8402a; }
.bw-slogan-txt{ font-size:14px; font-weight:600; color:#3a3a3c; letter-spacing:.005em; }
.bw-slogan-txt b{ font-weight:700; color:#1d1d1f; }

.bw-list{ display:flex; flex-direction:column; gap:4px; }
.bw-item{ display:flex; align-items:center; gap:12px; padding:7px 0; border-top:1px solid rgba(0,0,0,.07); cursor:pointer; }
.bw-item:first-child{ border-top:none; }
.bw-disc{
  position:relative; flex:0 0 auto; width:28px; height:28px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  background:radial-gradient(circle at 50% 36%, #fcfbf8, #e4e0d7 76%);
  box-shadow:0 0 0 1px rgba(0,0,0,.12), 0 1px 2px rgba(0,0,0,.12);
}
.bw-disc svg{ width:9px; height:9px; color:#3a3a3c; margin-left:1px; }
.bw-disc.is-playing{
  background:radial-gradient(circle at 50% 36%, #ff8068, #d8402a 70%);
  box-shadow:0 0 0 1px rgba(150,30,15,.26), 0 1px 4px rgba(216,64,42,.22);
}
.bw-disc.is-playing svg{ width:11px; height:11px; color:#fff; margin-left:0; }
.bw-dur{ font-family:var(--mono); font-size:13px; font-weight:600; color:#6a6862; font-variant-numeric:tabular-nums; flex:0 0 auto; }
.bw-prev{ font-size:13.5px; color:#88867f; overflow:hidden; white-space:nowrap; text-overflow:ellipsis; flex:1; min-width:0; }
.bw-empty{ font-size:13px; color:#a3a199; font-style:italic; padding:4px 0; }

/* recording layout */
.bw-recmode{ flex:1; min-width:0; padding:20px 26px; display:flex; flex-direction:column; justify-content:center; }
.bw-reclabel{ display:flex; align-items:center; gap:7px; font-family:var(--mono); font-size:10px; font-weight:700; letter-spacing:.18em; color:#d23a22; }
.bw-reclabel .dot{ width:7px; height:7px; border-radius:50%; background:#e8402a; box-shadow:0 0 6px rgba(232,64,42,.5); animation:bwpulse 1.1s ease-in-out infinite; }
@keyframes bwpulse{ 0%,100%{ opacity:1; } 50%{ opacity:.3; } }
.bw-timer{ font-size:76px; font-weight:700; letter-spacing:.01em; font-variant-numeric:tabular-nums; color:#26262a; line-height:.95; margin:auto 0; }
.bw-recprev{ display:flex; align-items:center; gap:10px; padding:9px 12px; border-radius:10px;
  background:rgba(0,0,0,.045); box-shadow:0 0 0 1px rgba(0,0,0,.06) inset; cursor:pointer; }
.bw-recprev .bw-dur{ font-size:12px; }
.bw-recprev .bw-prev{ font-size:12.5px; }

/* ---- matte graphite colorway ---- */
.bw.is-dark{
  background:linear-gradient(180deg,#3a3a40,#2a2a2f); color:#e8e8ea;
  box-shadow:
    0 1px 0 rgba(255,255,255,.10) inset,
    0 -1px 3px rgba(0,0,0,.4) inset,
    0 0 0 1px rgba(0,0,0,.5),
    0 18px 42px -14px rgba(0,0,0,.55);
}
.bw.is-dark .bw-rail{ border-right-color:rgba(0,0,0,.4); box-shadow:1px 0 0 rgba(255,255,255,.05); }
.bw.is-dark .bw-legend{ color:#8b8b93; }
.bw.is-dark .bw-rec{
  background:radial-gradient(circle at 50% 36%,#4c4c54,#2c2c31 72%);
  box-shadow:0 1px 0 rgba(255,255,255,.12) inset,0 -2px 4px rgba(0,0,0,.5) inset,0 0 0 1px rgba(0,0,0,.5),0 3px 6px rgba(0,0,0,.4);
}
.bw.is-dark .bw-mic{ background-image:radial-gradient(circle, rgba(255,255,255,.13) .8px, transparent 1.3px); }
.bw.is-dark .bw-rec.is-live{
  background:radial-gradient(circle at 50% 36%, #ff8068, #e8402a 56%, #c5301c);
  box-shadow:0 1px 0 rgba(255,255,255,.4) inset,0 0 0 1px rgba(150,30,15,.4),0 0 16px rgba(232,64,42,.45),0 3px 7px rgba(0,0,0,.4);
}
/*
.bw.is-dark .bw-file{
  background:linear-gradient(180deg,#404047,#2a2a30); color:#bdbdc4;
  box-shadow:0 1px 0 rgba(255,255,255,.10) inset,0 -2px 4px rgba(0,0,0,.5) inset,0 0 0 1px rgba(0,0,0,.5),0 2px 5px rgba(0,0,0,.4);
}
*/
.bw.is-dark .bw-logo{ background:#e8e6e0; }
.bw.is-dark .bw-slogan-txt{ color:#d7d7dd; }
.bw.is-dark .bw-slogan-txt b{ color:#fff; }
.bw.is-dark .bw-item{ border-top-color:rgba(255,255,255,.07); }
.bw.is-dark .bw-disc{
  background:radial-gradient(circle at 50% 36%,#44444c,#26262b 76%);
  box-shadow:0 0 0 1px rgba(0,0,0,.5),0 1px 2px rgba(0,0,0,.4);
}
.bw.is-dark .bw-disc svg{ color:#cfcfd6; }
.bw.is-dark .bw-disc.is-playing{
  background:radial-gradient(circle at 50% 36%, #ff8068, #d8402a 70%);
  box-shadow:0 0 0 1px rgba(150,30,15,.40), 0 0 10px rgba(216,64,42,.18);
}
.bw.is-dark .bw-disc.is-playing svg{ color:#fff; }
.bw.is-dark .bw-dur{ color:#b6b6bd; }
.bw.is-dark .bw-prev{ color:#86868d; }
.bw.is-dark .bw-empty{ color:#76767d; }
.bw.is-dark .bw-timer{ color:#f0f0f2; text-shadow:0 1px 1px rgba(0,0,0,.4); }
.bw.is-dark .bw-recprev{ background:rgba(255,255,255,.06); box-shadow:0 0 0 1px rgba(255,255,255,.07) inset; }
.bw.is-dark .bw-grain::after{ mix-blend-mode:overlay; opacity:.05; }

/* ============================================================
   BRAUN APP / FILES — matte off-white & matte graphite (flat)
   ============================================================ */
.ba{
  /* Surfaces tuned to the Braun card's clean near-whites (alloy #fdfcf9 / matte
     #f1f0ec) — brighter + far less beige than before, so the UI reads crisp and
     white instead of grimy. Subtle warm tint (R−B ≈ 4-6) kept to match the card.
     panel = the white content (card alloy), field = the sunken search/inputs
     (card matte), bg/side ramp gently between them. */
  --bg:#f7f7f6; --panel:#ffffff; --side:#f2f2f1;
  --ink:#28282a; --ink2:#6f6e68; --ink3:#9c9a92;
  --hair:rgba(0,0,0,.09); --hairsoft:rgba(0,0,0,.05);
  /* 2026-07-16 作者两轮钦定:灰格子先统一,后因无框化按钮太浅看不清 → 统一加重一档
     (所有灰控件走同一个 --field,一处改全站一致;统计卡仍用更浅的 --bg,大面积没问题) */
  --rbtn:13px; --rbtn-in:10px;   /* 按钮类控件圆角:外层/分段器内片(作者:胶囊太圆不像按钮,收稍方) */
  --field:#f3f3f2; --chip:#f3f3f2;   /* 两轮夹逼定稿:f7 太浅看不清、ef 太深,取中 */ --red:#d8402a; --redsoft:rgba(216,64,42,.10);
  --frost:rgba(247,247,246,.66);  /* 行内按钮磨砂遮罩底色(半透明 → 配 backdrop blur) */
  width:100%; height:100%; display:flex; flex-direction:column; overflow:hidden;
  background:var(--bg); color:var(--ink); font-family:var(--font);
  font-variant-numeric:tabular-nums;
}
.ba.is-dark{
  --bg:#202023; --panel:#27272b; --side:#222226;
  --ink:#eaeaec; --ink2:#aeaeb4; --ink3:#7e7e84;
  --hair:rgba(255,255,255,.085); --hairsoft:rgba(255,255,255,.045);
  --field:#1b1b1f; --chip:#34343a; --redsoft:rgba(216,64,42,.16);
  --frost:rgba(32,32,35,.62);  /* 深色磨砂遮罩底色 */
}

.ba-titlebar{ height:38px; flex:0 0 38px; display:flex; align-items:center; gap:8px; padding:0 14px;
  background:var(--side); border-bottom:1px solid var(--hair); -webkit-app-region:drag; }
.ba-light{ width:12px; height:12px; border-radius:50%; box-shadow:0 0 0 .5px rgba(0,0,0,.12) inset; }
.ba-light.r{ background:#ff5f57; }
.ba-light.y{ background:#febc2e; }
.ba-light.g{ background:#28c840; }
/* In the native macOS window the real traffic-light buttons are shown in the
   transparent titlebar; hide the faux web dots but keep the titlebar height so
   the layout (and the native buttons' position over it) stays identical. */
.is-native .ba-light{ visibility:hidden; }

/* Unified title bar: the separate 38px titlebar strip is gone — this is now the
   top row. Left padding (84px) clears the real macOS traffic-light cluster, which
   Swift repositions to vertically center in this row (see positionTrafficLights). */
.ba-topbar{ height:56px; flex:0 0 56px; display:flex; align-items:center; gap:14px; padding:0 26px 0 107px;
  background:var(--panel); border-bottom:1px solid var(--hair); }
.ba-iconbtn{ width:32px; height:32px; border-radius:8px; display:flex; align-items:center; justify-content:center; color:var(--ink2); background:transparent; cursor:pointer; }
.ba-iconbtn:hover{ background:var(--field); }
.ba-iconbtn.is-on{ background:var(--field); color:var(--ink); }
.ba-iconbtn svg{ width:18px; height:18px; }
/* settings 页底 Debug 分区标签:红色区分,提示这是开发者区(Debug Mode 开才出现) */
.ba-sectlabel-debug{ color:var(--red); }
/* DEBUG 徽标(搜索栏左侧):亮 = Debug Mode 开,点击即关。红底白字 + 呼吸,确保一眼看到。 */
.ba-debugbadge{ margin-left:auto; flex:0 0 auto; height:26px; padding:0 12px; border:0; border-radius:7px; cursor:pointer;
  background:var(--red); color:#fff; font-family:var(--mono); font-size:10.5px; font-weight:700; letter-spacing:.14em;
  animation:hsDbgPulse 2.4s ease-in-out infinite; }
.ba-debugbadge:hover{ filter:brightness(1.08); }
@keyframes hsDbgPulse{ 0%,100%{ box-shadow:0 0 0 0 var(--redsoft);} 50%{ box-shadow:0 0 0 5px var(--redsoft);} }
.ba-debugbadge + .ba-search{ margin-left:14px; }   /* 徽标接管了 auto 推挤,搜索框回到固定间距 */
/* 健康徽标(权限/模型出硬错时常驻):与 DEBUG 同族红pill,点击直开 Health Check 面板 */
.ba-healthbadge{ margin-left:auto; flex:0 0 auto; height:26px; padding:0 12px; border:0; border-radius:7px; cursor:pointer;
  background:var(--red); color:#fff; font-family:var(--mono); font-size:10.5px; font-weight:700; letter-spacing:.06em;
  animation:hsDbgPulse 2.4s ease-in-out infinite; }
.ba-healthbadge:hover{ filter:brightness(1.08); }
.ba-healthbadge + .ba-debugbadge{ margin-left:14px; }   /* 两徽标同现:健康徽标先接管 auto */
.ba-healthbadge + .ba-search{ margin-left:14px; }
.ba-search{ flex:0 1 190px; margin-left:auto; max-width:230px; height:34px; display:flex; align-items:center; gap:9px; padding:0 15px; border-radius:var(--rbtn);
  color:var(--ink3); font-size:13.5px; background:var(--field); }
/* 有查询词时:主题红粗外框(对齐系统 Notes 的粗色环,owner 2026-07-30)——
   is-active 由 syncSearchClear 随 query 有无切换,零新机制 */
.ba-search.is-active{ box-shadow:0 0 0 3px rgba(216,64,42,.52); }   /* 稍透明,别太实(owner) */
.ba-search svg{ flex:0 0 auto; }
.ba-search input{ border:0; outline:0; background:transparent; font-family:var(--font); font-size:13.5px; color:var(--ink); width:100%; }
.ba-search input::placeholder{ color:var(--ink3); }
/* Clear-search (×) — shown only while a query is active, so the filter is
   obvious and one click resets it. */
.ba-search-clear{ flex:0 0 auto; display:flex; align-items:center; justify-content:center; width:18px; height:18px;
  border:0; padding:0; border-radius:50%; background:transparent; color:var(--ink3); cursor:pointer; }
.ba-search-clear:hover{ color:var(--ink); background:var(--hairsoft); }
.ba-search-clear svg{ width:13px; height:13px; }
/* 品牌靠左(topbar 第一个,无 margin-left:auto);新 logo 用真图标(自带红点,不要 CSS 假点)。 */
.ba-brand{ display:flex; align-items:center; gap:9px; font-weight:600; font-size:15px; letter-spacing:-.01em; }
.ba-logo{ width:28px; height:28px; border-radius:7px; display:block; object-fit:contain; }
.ba-logo::after{ content:none; }

.ba-cols{ flex:1; display:flex; min-height:0; }
.ba-nav{ flex:0 0 404px; display:flex; flex-direction:column; padding:14px 12px; background:var(--side); border-right:1px solid var(--hair); }
/* 两列布局左列:导航(上) + 列表(中,填充) + Pro(底),合并原中间列。宽度 = 旧侧栏 2 倍。 */
/* min-width:0 + overflow-x:hidden:锁死 404px,防止某个子元素(如超长 File 文件名标题)
   的 min-content 撑宽整列(flex 项默认最小宽=min-content,漏设 min-width:0 会被撑大且不回缩)。 */
.ba-side{ flex:0 0 404px; min-width:0; max-width:404px; overflow-x:hidden; display:flex; flex-direction:column; min-height:0; background:var(--side); border-right:1px solid var(--hair); }
.ba-side-nav{ flex:0 0 auto; padding:14px 12px 4px; }
.ba-side-foot{ flex:0 0 auto; padding:4px 12px 12px; }
.ba-side > .ba-listcol{ flex:1 1 0; min-width:0; min-height:0; max-width:none; border-right:0; background:transparent; }
/* 列表内容左右多留白(作者:文字太贴左)。行底色仍满宽,只缩进内容。 */
/* 左缘:卡片左边框(20)再右移 ~7px → 27,看起来落在「按钮内容区」而不是死贴边框(作者要的)。
   右缘:对齐卡片右边框 x=383 → padding-right = 404-383 = 21(不动)。
   listhead 上下留白也收紧(10/8),配合卡片变矮,缩小顶部「大头」、让列表更靠上。 */
.ba-side .ba-listhead{ padding:10px 21px 8px 27px; }
.ba-side .ba-noterow{ padding-left:27px; padding-right:21px; }
/* History = Finder 风小灰标题(小号灰字,不抢眼;原 18px 黑太大)。 */
.ba-side .ba-listhead h2{ font-size:13px; font-weight:600; color:var(--ink3); letter-spacing:.02em; }
.ba-side .ba-listhead .lh-row{ align-items:center; }
/* 顶部 Files:做成清晰、够大的真按钮(原 navitem 太平,不像按钮)。 */
/* Dictation / Files 顶部按钮:竖排有间距(不再粘一起),清晰的抬起式按钮(hover 上浮、当前项红框)。 */
/* Three nav pills (Dictation / Files / AI Cowork) compressed so the trio occupies
   ~the same height the old two did — keeps the top tight, more room for History. */
.ba-side-nav{ display:flex; flex-direction:column; gap:6px; padding:10px 20px 3px; }
.ba-side-nav .ba-navitem{ height:40px; border:1px solid var(--hair); background:var(--panel); border-radius:11px; font-weight:600; padding:0 16px; box-shadow:0 1px 2px rgba(0,0,0,.06); transition:transform .12s ease, box-shadow .12s ease, border-color .12s ease; }
.ba-side-nav .ba-navitem:hover{ border-color:var(--ink3); box-shadow:0 4px 10px rgba(0,0,0,.10); transform:translateY(-1px); }
.ba-side-nav .ba-navitem:active{ transform:translateY(0); box-shadow:0 1px 2px rgba(0,0,0,.06); }
.ba-side-nav .ba-navitem.is-active{ border-color:var(--red); box-shadow:0 0 0 1px var(--red) inset, 0 1px 2px rgba(0,0,0,.06); }
.ba-side-nav .ba-navitem.is-active::before{ display:none; }
/* AI Cowork — empty placeholder (content TBD). */
.ba-aicowork-pane{ flex:1; display:flex; align-items:center; justify-content:center; background:var(--bg); }
.ba-aicowork-empty{ display:flex; flex-direction:column; align-items:center; gap:10px; text-align:center; }
.ba-aicowork-icon{ width:54px; height:54px; border-radius:50%; display:flex; align-items:center; justify-content:center; color:var(--red); background:var(--redsoft); }
.ba-aicowork-icon svg{ width:26px; height:26px; }
.ba-aicowork-title{ font-size:19px; font-weight:650; letter-spacing:-.02em; color:var(--ink); }
.ba-aicowork-sub{ font-size:13px; color:var(--ink3); }

/* ---------- AI Cowork page ---------- */
.ba-cw{ max-width:760px; }
.ba-cw .lead{ margin-bottom:6px; }
.ba-cw-honest{ font-size:12.5px; line-height:1.5; color:var(--ink2); background:var(--field); border:1px solid var(--hair); border-radius:9px; padding:9px 12px; margin:0 0 4px; }
.ba-cw-honest b{ color:var(--ink); font-weight:600; }
.ba-cw-statusrow{ display:flex; align-items:center; justify-content:space-between; gap:12px; margin:2px 0 8px; flex-wrap:wrap; }
.ba-cw-pill{ font-size:12px; font-weight:600; color:var(--ink3); background:var(--field); border:1px solid var(--hair); border-radius:7px; padding:5px 11px; }
.ba-cw-pill.is-on{ color:#1f8a4c; background:rgba(31,138,76,.10); border-color:rgba(31,138,76,.25); }
.ba-cw-pill.is-warn{ color:var(--red); background:var(--redsoft); border-color:rgba(216,64,42,.25); }
.ba-cw-portwrap{ font-size:12px; color:var(--ink2); display:flex; align-items:center; gap:7px; }
.ba-cw-port{ width:74px; font-family:var(--mono); font-size:12.5px; padding:5px 8px; border:1px solid var(--hair); border-radius:7px; background:var(--panel); color:var(--ink); }
.ba-cw-tokctl{ display:flex; align-items:center; gap:6px; flex-wrap:wrap; justify-content:flex-end; }
.ba-cw-token{ font-family:var(--mono); font-size:12.5px; color:var(--ink); background:var(--field); border:1px solid var(--hair); border-radius:7px; padding:5px 10px; letter-spacing:.02em; }
.ba-cw-mini{ font-size:12px; font-weight:600; color:var(--ink); background:var(--panel); border:1px solid var(--hair); border-radius:7px; padding:5px 11px; cursor:pointer; transition:background .12s; }
.ba-cw-mini:hover{ background:var(--field); }
.ba-cw-mini:disabled{ opacity:.4; cursor:default; }
.ba-cw-mini.is-danger{ color:var(--red); border-color:rgba(216,64,42,.3); }
.ba-cw-mini.is-danger:hover{ background:var(--redsoft); }
.ba-cw-seg{ display:flex; gap:6px; flex-wrap:wrap; margin:2px 0 10px; }
.ba-cw-seg button{ font-size:12.5px; font-weight:600; color:var(--ink2); background:var(--field); border:1px solid var(--hair); border-radius:8px; padding:7px 13px; cursor:pointer; transition:all .12s; }
.ba-cw-seg button:hover{ color:var(--ink); }
.ba-cw-seg button.is-on{ color:#fff; background:var(--red); border-color:var(--red); }
.ba-cw-hint{ font-size:12.5px; color:var(--ink2); line-height:1.6; margin-bottom:8px; display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.ba-cw-hint.ba-cw-after{ margin-top:8px; color:var(--ink3); }
.ba-cw-path{ font-family:var(--mono); font-size:11.5px; color:var(--ink); background:var(--field); border:1px solid var(--hair); border-radius:6px; padding:3px 7px; }
.ba-cw-codewrap{ position:relative; }
/* Compact by design: the user doesn't read it — they hit Copy. ~1/3 height, scrolls. */
.ba-cw-code{ font-family:var(--mono); font-size:11.5px; line-height:1.55; color:var(--ink); background:var(--field); border:1px solid var(--hair); border-radius:10px; padding:10px 14px; margin:0; white-space:pre; overflow:auto; max-height:68px; }
.ba-cw-copy{ position:absolute; top:10px; right:10px; display:flex; align-items:center; gap:5px; font-size:12px; font-weight:600; color:var(--ink); background:var(--panel); border:1px solid var(--hair); border-radius:7px; padding:5px 10px; cursor:pointer; box-shadow:0 1px 3px rgba(0,0,0,.08); }
.ba-cw-copy:hover{ background:var(--field); }
.ba-cw-copy.is-copied{ color:#1f8a4c; border-color:rgba(31,138,76,.3); }
.ba-cw-copy svg{ width:14px; height:14px; }
.ba-cw-testrow{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin-bottom:4px; }
.ba-cw-test{ font-size:12.5px; color:var(--ink3); }
.ba-cw-test.is-ok{ color:#1f8a4c; font-weight:600; }
.ba-cw-test.is-bad{ color:var(--red); font-weight:600; }
.ba-cw-permrow{ display:flex; align-items:flex-start; gap:11px; padding:10px 0; border-top:1px solid var(--hairsoft); }
.ba-cw-permrow .sname{ font-size:13.5px; font-weight:550; color:var(--ink); }
.ba-cw-permrow .sdesc{ font-size:12px; color:var(--ink3); margin-top:2px; }
.ba-cw-check{ flex:0 0 auto; margin-top:1px; padding:0; background:none; border:none; cursor:pointer; }
.ba-cw-box{ width:20px; height:20px; display:flex; align-items:center; justify-content:center; border:1.5px solid var(--hair); border-radius:6px; color:#fff; background:var(--panel); transition:all .12s; }
.ba-cw-check.is-on .ba-cw-box{ background:var(--red); border-color:var(--red); }
.ba-cw-check .ba-cw-box svg{ width:13px; height:13px; }
.ba-cw-watch{ font-size:12.5px; line-height:1.6; color:var(--ink2); background:var(--field); border:1px solid var(--hair); border-radius:9px; padding:10px 13px; margin:14px 0 0; }
.ba-cw-watch b{ color:var(--ink); }
.ba-cw-foot{ font-size:11.5px; line-height:1.6; color:var(--ink3); margin:12px 0 6px; }
/* Claude Desktop one-click row */
.ba-cw-claude{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin-top:16px; padding-top:12px; border-top:1px solid var(--hairsoft); font-size:12.5px; color:var(--ink2); }
.ba-cw-claude-q b{ color:var(--ink); }
.ba-cw-link{ color:var(--red); cursor:pointer; text-decoration:underline; }
/* AI Cowork — two scenarios (local app vs browser) */
.ba-cw-modeseg{ margin:8px 0 16px; }
.ba-cw-modeseg button{ font-size:13px; padding:8px 18px; }
.ba-cw-sub{ font-size:13.5px; color:var(--ink2); line-height:1.6; margin:0 0 12px; }
.ba-cw-sub b{ color:var(--ink); }
.ba-cw-steps{ margin:6px 0 14px; padding-left:20px; }
.ba-cw-steps li{ font-size:13.5px; color:var(--ink); line-height:1.75; margin:4px 0; }
.ba-cw-steps b{ color:var(--ink); }
.ba-cw-steps svg{ width:14px; height:14px; vertical-align:-2px; color:var(--red); }
/* "Use with any AI" skills gallery — preview chips of the skills you can copy from a row */
.ba-cw-skills{ display:flex; flex-wrap:wrap; gap:7px; margin:2px 0 16px; }
.ba-cw-skill{ display:inline-flex; align-items:center; gap:6px; font-size:12.5px; font-weight:600; color:var(--ink2);
  background:var(--field); border:1px solid var(--hair); border-radius:999px; padding:5px 12px 5px 9px; }
.ba-cw-skill svg{ width:14px; height:14px; color:var(--red); flex:0 0 auto; }
/* simplified one-paste layout */
.ba-cw-statusdot{ font-size:12px; font-weight:600; color:var(--ink3); margin:2px 0 10px; }
.ba-cw-statusdot.is-on{ color:#1f8a4c; }
.ba-cw-statusdot.is-warn{ color:var(--red); }
.ba-cw-copybig{ top:12px; right:12px; padding:7px 14px; font-size:12.5px; }
.ba-cw-tip{ font-size:12.5px; color:var(--ink2); margin:9px 2px 4px; line-height:1.55; }
.ba-cw-disc{ border-top:1px solid var(--hairsoft); margin-top:14px; }
.ba-cw-disc-h{ width:100%; text-align:left; background:none; border:none; cursor:pointer; padding:12px 2px 6px; font-size:13px; font-weight:600; color:var(--ink2); }
.ba-cw-disc-h:hover{ color:var(--ink); }
.ba-cw-disc-b{ padding:4px 2px 10px; }
.ba-cw-managerow{ display:flex; align-items:center; justify-content:space-between; gap:12px; padding:10px 0; border-top:1px solid var(--hairsoft); font-size:13px; color:var(--ink); }
.ba-cw-mgr-sub{ font-size:11.5px; color:var(--ink3); font-weight:400; }
/* 来源筛选下拉:清晰可读,带下拉箭头。 */
.lh-filter{ display:flex; align-items:center; }
.ba-select{ -webkit-appearance:none; appearance:none; font-family:var(--font); font-size:12.5px; font-weight:500; color:var(--ink); background-color:var(--field); border:1px solid transparent; border-radius:var(--rbtn); padding:5px 28px 5px 13px; cursor:pointer;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236f6e68' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>"); background-repeat:no-repeat; background-position:right 9px center; }
.ba-select:hover{ filter:brightness(.965); }
/* 来源下拉夺回「弹出按钮」观感:后面那条通用 .ba-select(设置/详情用)会用 background
   shorthand 洗掉箭头 + border:0,把它压平。这条更高特异性,重新给回 箭头+边框+抬升阴影+
   加粗+按下反馈,让它一眼是可点的下拉。只作用于来源下拉,不动其它 .ba-select。 */
.lh-filter .ba-select{
  font-size:13px; font-weight:600; color:var(--ink); min-width:0;
  border:1px solid var(--hair); border-radius:8px; padding:6px 28px 6px 12px;
  background-color:var(--panel);
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236f6e68' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>");
  background-repeat:no-repeat; background-position:right 10px center;
  box-shadow:0 1px 2px rgba(0,0,0,.08); }
.lh-filter .ba-select:hover{ border-color:var(--ink3); box-shadow:0 1px 3px rgba(0,0,0,.13); }
.lh-filter .ba-select:active{ box-shadow:0 1px 1px rgba(0,0,0,.10) inset; }
/* Pro → Unlock Pro:更醒目,标签 + 价格更大,皇冠更大。 */
.ba-pro{ gap:12px; position:relative; overflow:hidden; }
/* 已购左下角:复用 .ba-pro 按钮壳,只换内容(表盘 + 连击 + 省时 tag)。 */
.ba-pro .pro-dial{ display:flex; flex:0 0 auto; }

/* ============================================================
   连击表盘(Braun 仪表语言):细环 + 中心数字,红弧 = 向里程碑进度,
   入场弧线从零画出。sm 版给左下角瓦片。
   ============================================================ */
.hs-dial{ transform:rotate(-90deg); overflow:visible; flex:0 0 auto; }
.hs-dial circle{ fill:none; stroke-width:5; }
.hs-dial.sm circle{ stroke-width:3; }
.hs-dial .dl-track{ stroke:var(--hair); }
.hs-dial .dl-arc{ stroke:var(--red); stroke-linecap:round; }
/* 画弧入场只在 .anim(真切入视图)时播:侧栏/后台推送重渲不重播 */
.anim .hs-dial .dl-arc{ animation:hsDialIn .9s cubic-bezier(.3,.9,.35,1) both; }
@keyframes hsDialIn{ from{ stroke-dashoffset:var(--dl-c); } }
@media (prefers-reduced-motion: reduce){ .hs-dial .dl-arc{ animation:none !important; } }

/* 已购会员之家:内容列与设置页同宽,節奏统一 */
/* 会员页整页统一读秒 mono 字族(owner 2026-07-16:不要 mono/sans 混排);
   中文等 CJK 字形 SF Mono 没有 → 自动回退系统中文字体,不受影响。 */
.ba-member-wrap{ max-width:720px; font-family:var(--mono); }
.ba-member-wrap .ba-btn, .ba-member-wrap .ie-cta{ font-family:var(--mono); }

/* 会员统计(2026-07-15 owner 重定稿):顶部「说了多少字」大数字 + 里程碑进度(整幅),
   下面复用付费前 paywall 的独立卡片布局 —— 热力图占左半,统计数字各自独立卡片占右半。
   不再是一张大仪表盘,也不给省时单独一个大 hero(owner 打回)。 */
/* heading 区(owner 2026-07-16 重定稿):删「YOUR STATS」冗余标签;Next stop 行
   升到 heading 量级;heading 与下方模块拉开大留白。 */
.mp-hero{ padding:2px 2px clamp(20px, 3.6vh, 44px); }   /* 标题块→统计区间距随视口收缩(owner 2026-07-20:矮窗一页放不下) */
.mp-hero.is-mile{ animation:hsMileGlow 1.15s ease-in-out 3; border-radius:14px; }
/* 数字一律用读秒计时器同款等宽字(--mono,同 .bw3-timer/.ba-reclive-time)——
   owner 2026-07-16:统计页数字要和 App 读秒数字一个字体。 */
.hw-num{ font-family:var(--mono); font-size:46px; font-weight:700; line-height:1; letter-spacing:.01em; font-variant-numeric:tabular-nums; }
.hw-num.pop{ animation:hsNumPop .45s cubic-bezier(.2,1.4,.4,1) both; }
@keyframes hsNumPop{ from{ transform:scale(.8); opacity:.4; } to{ transform:scale(1); opacity:1; } }
/* 大数字 + 标签同一基线并排(owner 2026-07-15:小字贴在数字后面,不再另起一行) */
.hw-top{ display:flex; align-items:baseline; gap:11px; flex-wrap:wrap; }
.hw-lab{ font-family:var(--mono); font-size:13.5px; font-weight:700; letter-spacing:.2em; text-transform:uppercase; color:var(--ink2); }
.hw-line{ display:flex; align-items:center; gap:10px; font-size:15px; font-weight:700; color:var(--ink2); margin-top:14px; }
.hw-line b{ font-family:var(--mono); color:var(--ink); font-weight:700; }
.hw-line .up{ color:var(--red); font-weight:700; }
.hw-line .up b{ color:inherit; }   /* +N today / 里程碑数字:等宽但保持红色 */

.hc-today{ box-shadow:0 0 0 2px var(--red) !important; }
.ba-stats-heat .ba-heat-scroll{ overflow:visible; }   /* 今天格描边在格外 2px,别被裁 */
.anim .hcol{ animation:hsColIn .3s ease both; }
@keyframes hsColIn{ from{ opacity:0; transform:translateY(3px); } to{ opacity:1; transform:none; } }

/* 里程碑穿越日:瓦片 + 仪表卡三连脉冲(当天常在,次日自然回常态) */
.ba-pro.is-mile{ animation:hsMileGlow 1.15s ease-in-out 3; }
@keyframes hsMileGlow{ 0%,100%{ box-shadow:0 0 0 0 rgba(216,64,42,0); }
  50%{ box-shadow:0 0 0 2px var(--red), 0 0 26px var(--redsoft); } }
@media (prefers-reduced-motion: reduce){ .ba-pro.is-mile, .mp-hero.is-mile{ animation:none !important; } }

/* 邀请卡(Wise 思路:一个大数字 + 一个动作;不解释结算机制) */
.ba-invite{ display:flex; flex-wrap:wrap; align-items:center; gap:22px; margin-top:30px; padding:24px 28px; border-radius:18px;
  border:1px solid var(--hair); background:var(--panel); box-shadow:0 1px 3px rgba(0,0,0,.05); }
.ba-invite .iv-left{ flex:1 1 300px; min-width:0; }
.iv-kick{ display:flex; align-items:center; gap:6px; font-family:var(--mono); font-size:10.5px; font-weight:700;
  letter-spacing:.13em; text-transform:uppercase; color:var(--ink3); }
.iv-kick .ic{ display:flex; } .iv-kick .ic svg{ width:13px; height:13px; }
.iv-title{ font-size:21px; font-weight:750; letter-spacing:-.01em; margin-top:9px; }
.iv-title b{ color:var(--red); }
.iv-sub{ font-size:13px; color:var(--ink2); margin-top:6px; max-width:44ch; line-height:1.55; }
.iv-cta{ display:flex; align-items:center; gap:16px; margin-top:15px; }
.iv-cta .ba-btn{ height:36px; padding:0 18px; font-size:13.5px; }
.iv-cta .rlink{ font-size:12.5px; color:var(--ink2); cursor:pointer; }
.iv-cta .rlink:hover{ color:var(--ink); }
.iv-foot{ font-size:11.5px; color:var(--ink3); margin-top:10px; }
.iv-badge{ margin-left:auto; flex:0 0 auto; width:104px; height:104px; border-radius:50%;
  background:radial-gradient(circle at 32% 28%, rgba(255,255,255,.55), rgba(255,255,255,0) 58%), var(--redsoft);
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  color:var(--red); font-weight:800; font-size:27px; letter-spacing:-.01em; }
.ba.is-dark .iv-badge{ background:radial-gradient(circle at 32% 28%, rgba(255,255,255,.08), rgba(255,255,255,0) 58%), var(--redsoft); }
.iv-badge span{ font-size:10.5px; font-weight:650; letter-spacing:.05em; opacity:.8; margin-top:2px; }
/* 左栏常驻 Invite 入口:gift 图标 + 25% 徽标(红,拉眼球);点进滚到 Referrals 卡时闪一下 */
.ba-nav-invite .ba-nav-pct{ margin-left:auto; font-family:var(--mono); font-size:11px; font-weight:700; color:var(--red); letter-spacing:.02em; }
.ba-side-nav .ba-nav-invite .ba-nav-pct, .ba-nav .ba-nav-invite .ba-nav-pct{ margin-left:auto; }
.ba-invite.is-flash{ animation:hsInviteFlash 1.1s ease; }
@keyframes hsInviteFlash{ 0%,100%{ box-shadow:0 1px 3px rgba(0,0,0,.05); } 30%{ box-shadow:0 0 0 2px var(--red), 0 0 22px var(--redsoft); } }
@media (prefers-reduced-motion: reduce){ .ba-invite.is-flash{ animation:none; } }
/* 已注册战绩态:两个真金白银大数(已赚 / 待打款) */
.ba-invite.is-earning .iv-earn{ display:flex; gap:34px; margin:12px 0 4px; }
.iv-earn .ev{ display:flex; flex-direction:column; }
.iv-earn .ev .n{ font-size:28px; font-weight:800; letter-spacing:-.02em; color:var(--ink); font-variant-numeric:tabular-nums; }
.iv-earn .ev .l{ font-family:var(--mono); font-size:9px; font-weight:700; letter-spacing:.1em; text-transform:uppercase; color:var(--ink3); margin-top:4px; }

/* license 一行(最次要,收尾) */
.ba-pro .crown svg{ width:23px; height:23px; }
.ba-pro-label{ font-size:16.5px; font-weight:700; }
.ba-pro-label .wl{ font-family:var(--mono); font-style:normal; font-size:9.5px; font-weight:700; letter-spacing:.16em; text-transform:uppercase; color:var(--ink2); margin-left:7px; }   /* words spoken 后缀=统计页 hw-lab 风格(作者 2026-07-16) */
.ba-pro-labels{ display:flex; flex-direction:column; align-items:flex-start; gap:1px; min-width:0; }
.ba-pro-sub{ font-size:10.5px; font-weight:500; line-height:1.2; color:rgba(255,255,255,.72); white-space:nowrap; }
.ba-pro .tag{ margin-left:auto; font-family:var(--mono); font-size:15.5px; font-weight:700; color:var(--red); }
/* 未解锁:红底白字反色,超醒目;解锁后(无 is-locked)回到常态浅底。 */
.ba-pro.is-locked{ background:var(--red); box-shadow:none; color:#fff;
  transition:transform .16s ease, box-shadow .22s ease; }
.ba-pro.is-locked > *{ position:relative; z-index:1; }   /* 文字/图标在跟随光标的高光之上,保持清晰 */
.ba-pro.is-locked .ba-pro-label,
.ba-pro.is-locked .crown,
.ba-pro.is-locked .crown svg,
.ba-pro.is-locked .tag{ color:#fff; }
/* 跟随光标的柔光高光:JS 把光标位置写进 --mx/--my,径向光斑随之移动;仅悬停可见,不悬停 opacity:0 完全静止。 */
.ba-pro.is-locked::after{ content:""; position:absolute; inset:0; z-index:0; border-radius:inherit; pointer-events:none;
  background:radial-gradient(220px circle at var(--mx,50%) var(--my,50%), rgba(255,255,255,.26), rgba(255,255,255,0) 55%);
  opacity:0; transition:opacity .25s ease; }
.ba-pro.is-locked:hover::after{ opacity:1; }
.ba-pro.is-locked:hover{ transform:translateY(-1px); box-shadow:0 9px 24px rgba(216,64,42,.42), 0 3px 8px rgba(0,0,0,.14); }
.ba-pro.is-locked:active{ transform:translateY(0); box-shadow:0 4px 12px rgba(216,64,42,.34); }
.ba-pro.is-locked.is-active{ box-shadow:0 0 0 2px rgba(255,255,255,.55) inset; }
.ba-navsec{ font-family:var(--mono); font-size:10.5px; font-weight:700; letter-spacing:.14em; text-transform:uppercase; color:var(--ink3); padding:6px 11px 8px; }
.ba-navitem{ position:relative; display:flex; align-items:center; gap:10px; height:36px; padding:0 11px; border-radius:8px; font-size:14px; font-weight:500; color:var(--ink); cursor:pointer; }
.ba-navitem:hover{ background:var(--panel); }
.ba-navitem svg{ width:17px; height:17px; color:var(--ink2); flex:0 0 auto; }
.ba-navitem .count{ margin-left:auto; font-family:var(--mono); font-size:11.5px; color:var(--ink3); }
/* Files「处理中」的跳动计数:红色 + 前置小圆点(running 时脉冲),一眼看出还有几个在转写。 */
.ba-navitem .count.is-active-files{ display:inline-flex; align-items:center; gap:5px; color:var(--red); font-variant-numeric:tabular-nums; }
.ba-navitem .count.is-active-files .live{ width:7px; height:7px; border-radius:50%; background:var(--red); flex:0 0 auto; }
.ba-navitem .count.is-active-files.is-live .live{ animation:bwpulse 1.1s ease-in-out infinite; }
.ba-navitem.is-active{ font-weight:600; background:var(--panel); box-shadow:0 0 0 1px var(--hair) inset; }
.ba-navitem.is-active::before{ content:""; position:absolute; left:-12px; top:8px; bottom:8px; width:2px; background:var(--red); }
.ba-spacer{ flex:1; }
.ba-pro{ display:flex; align-items:center; gap:10px; height:59px; padding:0 18px; border-radius:24px; font-weight:600; font-size:14px; color:var(--ink);
  background:var(--panel); box-shadow:0 0 0 1px var(--hair) inset; cursor:pointer; }
.ba-pro.is-active{ box-shadow:0 0 0 1.5px var(--red) inset; }   /* 1px 细描边在白底上光学发橙,加粗到与品牌红等重 */
.ba-pro .crown{ color:var(--red); display:flex; }
.ba-pro .crown svg{ width:18px; height:18px; }
.ba-pro .tag{ margin-left:auto; font-family:var(--mono); font-size:12px; font-weight:700; color:var(--red); }

/* List vs reader share the post-sidebar width responsively. Explicit min-width
   (not the flex default `auto`) stops the list from ballooning to its content;
   the grow ratio (list 1 : reader 1.25) keeps the list substantial while the
   reader stays the slightly-larger reading surface. Both scale with the window. */
.ba-listcol{ flex:1 1 0; min-width:340px; max-width:600px; display:flex; flex-direction:column; background:var(--bg); border-right:1px solid var(--hair); }
.ba-listhead{ display:flex; flex-direction:column; gap:9px; padding:16px 16px 9px; border-bottom:1px solid var(--hair); }
.ba-listhead .lh-row{ display:flex; align-items:baseline; justify-content:space-between; }
.ba-listhead h2{ margin:0; font-size:18px; font-weight:600; letter-spacing:-.02em; }
.ba-listhead .lh-right{ display:flex; align-items:center; gap:8px; }
.ba-listhead .sub{ font-family:var(--mono); font-size:11.5px; color:var(--ink3); }
.lh-fav{ display:flex; align-items:center; justify-content:center; width:26px; height:26px; border-radius:7px; color:var(--ink3); background:transparent; cursor:pointer; }
.lh-fav:hover{ background:var(--field); color:var(--ink2); }
.lh-fav svg{ width:18px; height:18px; }
.lh-fav.is-on{ color:#e0a13a; background:var(--redsoft); }
/* Keep-history retention bar */
.ba-keephist{ display:flex; align-items:center; gap:8px; padding:8px 10px; border-radius:9px; background:var(--field); }
.ba-keephist .kh-ico{ display:flex; color:var(--ink2); }
.ba-keephist .kh-ico svg{ width:16px; height:16px; }
.ba-keephist .kh-label{ font-size:12.5px; font-weight:500; color:var(--ink); flex:1; }
.kh-select{ font-family:var(--mono); font-size:11.5px; color:var(--ink); background:var(--field); border:1px solid transparent; border-radius:var(--rbtn); padding:4px 10px; cursor:pointer; -webkit-appearance:none; appearance:none; background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='%239c9a92' stroke-width='3'><path d='M6 9l6 6 6-6'/></svg>"); background-repeat:no-repeat; background-position:right 7px center; padding-right:22px; }
/* 来源筛选栏(All / Dictation / Record)— 复用 .ba-vartabs 分段 pill;段选靠左、
   收藏★靠右。内嵌在 .ba-listhead(已带 16px 侧距)里,故自身不再加侧距,段选与标题左对齐。 */
.ba-srcbar{ display:flex; align-items:center; justify-content:space-between; gap:8px; padding:0; }
.ba-srcbar .ba-vartabs{ margin:0; flex-wrap:wrap;
  /* 这组坐在灰页面背景上(≠详情页的白卡),--field 与页面灰只差 4 阶,组轮廓消失 →
     轨道单独加深一档,白色选中片才有「从一组里选中」的语义(作者 2026-07-16) */
  background:#eaeae9; }
.ba.is-dark .ba-srcbar .ba-vartabs{ background:var(--chip); }
.ba-srcbar .ba-seg-btn{ padding:4px 11px; font-size:12px; }
.ba-srcbar .ba-seg-btn .c{ font-family:var(--mono); font-size:10px; color:var(--ink3); margin-left:5px; }
.ba-srcbar .ba-seg-btn.is-on .c{ color:var(--ink2); }
.ba-scroll{ flex:1; overflow-y:auto; overflow-x:hidden; }
/* 虚拟滚动的上下占位条:撑出窗口外行的真实高度,使滚动条比例/位置与全量一致。 */
.ba-vpad{ flex:0 0 auto; width:100%; pointer-events:none; }
.ba-scroll::-webkit-scrollbar{ width:9px; }
.ba-scroll::-webkit-scrollbar-thumb{ background:var(--hair); border-radius:5px; border:2px solid transparent; background-clip:padding-box; }
.ba-noterow{ position:relative; display:flex; align-items:center; gap:12px; padding:16px 16px; border-bottom:1px solid var(--hairsoft); cursor:pointer; -webkit-user-select:none; user-select:none; }
.ba-noterow:hover{ background:var(--panel); }
.ba-noterow.is-active{ background:var(--panel); }
.ba-noterow.is-active::before{ content:""; position:absolute; left:0; top:0; bottom:0; width:6px; background:var(--red); }
/* 收藏常驻金星:绝对定位在「红条(0-6)↔播放键(27)」之间的左侧留白(中点 ~16)里,竖直居中。
   不进 flex 流 → 不影响行内任何间距/排版/行高(作者钦定:放前面这个位置长住,作收藏的视觉区分)。 */
.ba-noterow .ba-favlead{ position:absolute; left:9px; top:50%; transform:translateY(-50%); display:inline-flex; align-items:center; color:#e0a13a; pointer-events:none; z-index:2; }
.ba-noterow .ba-favlead svg{ width:14px; height:14px; }
.ba-noterow .meta{ flex:1; min-width:0; display:flex; flex-direction:column; justify-content:center; }
/* 列表只显示标题,严格单行(超出省略号)。标题长度由数据层 Note.deriveTitle 控制(填满整行)。 */
.ba-noterow .title{ font-size:14px; font-weight:600; margin-bottom:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; line-height:1.4; }
/* 进行中的录音行:标题「录音中…/录音:名字」用主题红 + 加粗到 700(红字在浅灰底上比黑字显淡,
   600 看着不够粗 → 700 才明显加粗,作者 2026-07-25),与红点圆盘 + 下方 .ba-recstate 状态标签同色,
   一眼看出这条正在录。改名输入框 .ba-row-rename 自带 --ink 颜色,不受影响。 */
.ba-noterow-rec .title{ color:var(--red); font-weight:700; }
/* 已重命名的录音行:「录音:」前缀保持主题红(在录信号),用户起的名字用正文墨色(不跟着变红,
   作者 2026-07-25)。--ink 随明暗主题走(浅色=近黑、深色=近白)。 */
.ba-noterow-rec .title .ba-recname{ color:var(--ink); }
/* 转写中的行:标题槽直接显示「⟳ 转写中…」(墨色 + 转圈,含已重命名的录音),不再回落成未翻译的
   英文 "Recording"(作者 2026-07-25:文字用黑白墨色 --ink,不用灰色)。短文案无需省略号 → inline-flex。 */
.ba-noterow .title.is-tx{ display:inline-flex; align-items:center; gap:6px; color:var(--ink); font-weight:600; }
/* 时长读秒与标题同排(借悬浮卡 bw3-dur 风格):等宽加粗小字在前、标题在后吃掉剩余宽度并省略号。
   meta 仍是 column+居中、这一排为单行 → 播放键对齐到该行视觉中心。 */
.ba-noterow .ba-titlerow{ display:flex; align-items:baseline; gap:7px; min-width:0; }
/* 标题右侧预留 ~2 个中文字宽(2em@14px),让省略号比填满整行再早两个字出现。 */
.ba-noterow .ba-titlerow .title{ flex:1 1 auto; min-width:0; margin-right:2em; }
/* 行内改名输入框:借用行标题的字号字重,填满标题槽,轻描边聚焦主题红。
   录音行的 .title 是 block、普通行的 .title 在 .ba-titlerow 里是 flex item —— 两处都用它。 */
.ba-row-rename{ display:block; width:100%; box-sizing:border-box; margin:0;
  font-family:var(--font); font-size:14px; font-weight:600; line-height:1.4; letter-spacing:inherit;
  color:var(--ink); background:var(--field); border:0; box-shadow:0 0 0 1px var(--hair) inset;
  border-radius:7px; padding:2px 7px; outline:none; }
.ba-row-rename:focus{ box-shadow:0 0 0 2px var(--red) inset; }
.ba.is-dark .ba-row-rename{ background:var(--panel); }
.ba-noterow .ba-rowdur{ position:relative; flex:0 0 auto; font-family:var(--mono); font-size:12px; font-weight:700; line-height:1.4; color:var(--ink2); white-space:nowrap; pointer-events:none; font-variant-numeric:tabular-nums; }
/* "NEW" — a tiny red italic flag floating just ABOVE the duration on a freshly
   transcribed file; absolutely positioned so it never shifts the time itself. */
.ba-newbadge{ position:absolute; left:0; bottom:calc(100% - 1px); font-family:var(--font); font-size:7.5px; font-style:italic; font-weight:800; letter-spacing:.08em; color:var(--red); line-height:1; pointer-events:none; }
/* 应用内听写指示器(pill):摁住 ⌥ 听写到 HoldSay 自己的字段时,贴在焦点输入框旁显示(瞬时、网页定位)。
   原生 AX overlay 在这种情况被抑制(见 setStatusIcon),所以只有这一个指示器,且就在用户打字的地方。 */
/* 尺寸对齐原生 overlay(140×36pt / 字 13 / 点 10),避免应用内 pill 看起来又窄又扁。 */
#ba-dictpill{ position:fixed; z-index:9999; display:none; align-items:center; gap:10px;
  height:36px; padding:0 18px 0 14px; border-radius:18px; background:var(--panel); color:var(--ink);
  font-size:13px; font-weight:500; line-height:1; white-space:nowrap;
  border:1px solid var(--hair); box-shadow:0 6px 20px rgba(0,0,0,.18); pointer-events:none; }
#ba-dictpill.show{ display:flex; }
#ba-dictpill .ba-dictpill-dot{ width:10px; height:10px; border-radius:50%; background:var(--ink3); flex:0 0 auto; }
#ba-dictpill.is-rec .ba-dictpill-dot{ background:var(--red); animation:hsDictPulse .8s ease-in-out infinite; }
@keyframes hsDictPulse{ 0%,100%{ opacity:1; } 50%{ opacity:.3; } }

/* 点击复制 → 整行短暂变成「✓ Copied」框,给出明确反馈。 */
.ba-copied{ position:absolute; inset:0; z-index:6; display:flex; align-items:center; justify-content:center; gap:8px;
  background:var(--panel); color:var(--red); font-size:13.5px; font-weight:600; white-space:nowrap;
  pointer-events:none; animation:hsCopiedIn .2s ease-out; }   /* 主题红字 + 复制图标,字号字重对齐 Copy 按钮 */
.ba-copied .ico{ display:inline-flex; align-items:center; color:var(--red); }
.ba-copied .ico svg{ width:17px; height:17px; }
.ba-copied.is-out{ animation:hsCopiedOut .22s ease-in forwards; }
@keyframes hsCopiedIn{ from{ opacity:0; transform:scale(.97); } to{ opacity:1; transform:scale(1); } }
@keyframes hsCopiedOut{ from{ opacity:1; } to{ opacity:0; } }
/* 收藏/取消收藏 → 星标弹一下(只在刚切换那次,见 noteRow 的 _popFavId)。 */
.ba-rowacts .ra-star.is-pop{ animation:hsStarPop .26s ease-out; }
@keyframes hsStarPop{ 0%{ transform:scale(1); } 40%{ transform:scale(1.28); } 100%{ transform:scale(1); } }
/* 内容预览段 — 标题下显示 2 行正文摘要(作者:只留标题信息量太少,分不清每条) */
.ba-noterow .snip{ display:none; font-size:12.5px; color:var(--ink2); line-height:1.45; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
/* 列表行底部「时长 · 时间」详情行 — 作者要更简约的列表,隐藏(详情面板仍显示时间) */
.ba-noterow .row2{ display:none; gap:8px; align-items:center; margin-top:6px; font-family:var(--mono); font-size:11px; color:var(--ink3); }
/* 「从 iPhone 同步」徽标:标记来自 iPhone「同步到 Mac」的笔记(独立 CloudKit 库落地)。 */
.ba-syncbadge{ display:inline-flex; align-items:center; padding:1px 7px; border-radius:6px; font-family:var(--sans,inherit); font-size:10px; font-weight:600; letter-spacing:.02em; color:var(--red); background:color-mix(in srgb, var(--red) 12%, transparent); border:1px solid color-mix(in srgb, var(--red) 28%, transparent); white-space:nowrap; }
/* 转写队列状态徽标:某条录音「排队转写中」/「转写中 i/N」时,在历史列表里替代(仍空的)摘要显示。温馨橘,不用红。 */
.ba-txchip{ display:inline-flex; align-items:center; padding:1px 8px; border-radius:7px; font-family:var(--sans,inherit); font-size:11.5px; font-weight:600; letter-spacing:.01em; color:#c9781a; background:rgba(217,133,31,.13); border:1px solid rgba(217,133,31,.34); white-space:nowrap; }
/* In-progress recording: list row state + the static red dot in the disc. */
.ba-recstate{ font-weight:600; color:var(--red); font-variant-numeric:tabular-nums; }
.ba-recstate.is-paused{ color:var(--ink3); }
.ba-disc-rec{ display:flex; align-items:center; justify-content:center; }
.ba-recdot{ width:9px; height:9px; border-radius:50%; background:var(--red); box-shadow:0 0 7px rgba(232,64,42,.55); animation:ba-recpulse 1.6s ease-in-out infinite; }
@keyframes ba-recpulse{ 0%,100%{ opacity:1 } 50%{ opacity:.35 } }
/* In-progress recording: the detail panel (no tabs/edit/export until stop). */
.ba-reclive{ display:flex; flex-direction:column; align-items:center; justify-content:center; gap:16px; padding:56px 40px; text-align:center; }
.ba-reclive-state{ display:flex; align-items:center; gap:9px; font-family:var(--mono); font-size:13px; font-weight:700; letter-spacing:.14em; text-transform:uppercase; color:var(--red); }
.ba-reclive-state.is-paused{ color:var(--ink3); }
.ba-reclive-state .ba-recdot{ width:10px; height:10px; }
.ba-reclive-time{ font-family:var(--mono); font-size:64px; font-weight:700; font-variant-numeric:tabular-nums; color:var(--ink); line-height:1; }
.ba-reclive-state.is-paused ~ .ba-reclive-time{ color:var(--ink3); }
.ba-reclive .ba-recpause{ margin-top:4px; height:40px; padding:0 22px; }
.ba-recpause-ico{ font-size:12px; letter-spacing:0; margin-right:3px; }
/* Recording controls: Stop (red, left) + Pause (right) — same pairing as the
   floating card (red REC = stop, tap timer = pause), kept consistent here. */
.ba-reclive-btns{ display:flex; align-items:center; justify-content:center; gap:14px; margin-top:16px; }
/* Stop + Pause are ONE identical box. .ba-btn base is 42px while .ba-recpause was
   overridden to 40px → 2px mismatch. Hard-pin BOTH to 40px (height + min/max +
   line-height) so no variant, icon, or line-box quirk in any engine can grow one
   taller than the other. Only color + label differ. */
.ba-reclive-btns .ba-btn{ height:40px; min-height:40px; max-height:40px; box-sizing:border-box; line-height:1; padding:0 22px; margin-top:0; }
.ba-recstop{ background:var(--red); color:#fff; box-shadow:none; }
.ba-recstop:hover{ filter:brightness(.94); }
/* Pause (ghost) ships a 1px inset hairline that reads as an extra outer ring →
   makes it look bigger than the borderless solid Stop. Drop the ring here so both
   buttons have the same clean filled edge + visually-matched size. */
.ba-reclive-btns .ba-btn.ghost{ box-shadow:none; }
/* Icons are CSS shapes (not text glyphs, which render unpredictably tall): a
   square (Stop), two bars (Pause), a triangle (Continue) — ALL exactly 11px tall
   so the two buttons carry visually-matched icons. */
.ba-reclive-btns .ba-rec-ico{ display:inline-flex; align-items:center; justify-content:center; margin:0; }
.ba-ico-stop{ width:11px; height:11px; border-radius:2px; background:currentColor; }
.ba-ico-pause{ gap:3px; }
.ba-ico-pause i{ width:3px; height:11px; border-radius:1px; background:currentColor; }
.ba-reclive-btns .ba-ico-play{ display:inline-block; width:0; height:0; border-style:solid; border-width:6px 0 6px 11px; border-color:transparent transparent transparent currentColor; }
/* Transcribing live face — mirrors the floating card's Transcribing state
   (rotating spinner + chunk count, or three pulsing dots while preparing) so the
   in-app pane shows the SAME middle state between Recording and the finished doc. */
.ba-reclive-state.ba-txstate{ color:var(--ink3); }
.ba-txspin{ display:inline-block; box-sizing:border-box; width:11px; height:11px;
  border:1.5px solid var(--ink3); border-top-color:var(--ink); border-radius:50%;
  animation:baspin .7s linear infinite; }
.ba-reclive-time.ba-txfig{ font-size:52px; color:var(--ink3); }
.ba-txdots{ display:inline-flex; align-items:center; gap:12px; }
.ba-txdots i{ display:block; width:13px; height:13px; border-radius:50%; background:var(--ink3);
  animation:bwpulse 1.1s ease-in-out infinite; }
.ba-txdots i:nth-child(2){ animation-delay:.18s; }
.ba-txdots i:nth-child(3){ animation-delay:.36s; }
/* LiveScribe partial transcript — the already-committed text shown UNDER the
   recording / transcribing controls ("Transcribed so far"). Reads like a calm
   draft of the finished doc: left-aligned body text, a quiet uppercase label,
   a hairline separating it from the live panel above. pre-wrap keeps the
   server's paragraph breaks without any markup. */
.ba-recpartial{ margin:8px 40px 40px; padding-top:22px; border-top:1px solid var(--hair); text-align:left; }
.ba-recpartial-label{ font-family:var(--mono); font-size:11px; font-weight:700; letter-spacing:.14em;
  text-transform:uppercase; color:var(--ink3); margin-bottom:12px; }
.ba-recpartial-text{ white-space:pre-wrap; font-size:14.5px; line-height:1.75; color:var(--ink2); }
/* Native push-button chrome (gradient fill, drop shadow, rounded bezel) reappears
   on recent macOS even after a background is set — recent WebKit no longer drops
   the native appearance automatically, which made these buttons look like raised
   "gift" keycaps. Reset every button to a flat box so only our own styling shows;
   the per-button rules below add their own background/color where wanted. */
button{ -webkit-appearance:none; appearance:none; background:none; border:0;
  padding:0; margin:0; font:inherit; color:inherit; cursor:pointer; }

/* Per-row action cluster (copy / star / more), revealed on hover; a starred
   note keeps its star visible always. Absolutely placed with a fade strip so it
   sits cleanly over the right end of the title. */
/* 占满整行高度(top:0/bottom:0),这样磨砂遮罩能完整盖住标题——避免只盖按钮那一条、
   标题底部露出一截。按钮仍竖直居中。 */
.ba-rowacts{ position:absolute; top:0; bottom:0; right:0; display:flex; align-items:center; gap:1px; padding-left:26px; padding-right:8px; }
/* 磨砂玻璃遮罩:backdrop 模糊把后面的清晰文字打糊(看不清=遮挡完全),半透明 --frost 让它
   仍稍微透出后面;左侧用 mask 渐隐,让遮罩自然融入文字而不是一条硬边。 */
.ba-noterow:hover .ba-rowacts, .ba-noterow.is-active .ba-rowacts{
  background:var(--frost);
  -webkit-backdrop-filter:blur(8px); backdrop-filter:blur(8px);
  -webkit-mask-image:linear-gradient(to right, transparent, #000 26px); mask-image:linear-gradient(to right, transparent, #000 26px); }
.ba-rowacts .ra{ width:28px; height:28px; border-radius:8px; display:flex; align-items:center; justify-content:center; color:var(--ink3); cursor:pointer; opacity:0; transition:opacity .12s; }
.ba-rowacts .ra svg{ width:18px; height:18px; }   /* 图标 18 不变;按钮 30→28 收紧三按钮间距(留白 -15%) */
.ba-rowacts .ra:hover{ background:var(--hair); color:var(--ink); }
.ba-noterow:hover .ba-rowacts .ra, .ba-noterow.is-active .ba-rowacts .ra{ opacity:1; }
/* 收藏星不常驻列表(会压住标题文字);收藏态只让 hover 操作区里的 ☆ 变金色(便于取消)。 */
.ba-rowacts .ra-star.is-on{ color:#e0a13a; }
.ba-rowacts .ra-star.is-on:hover{ color:#c8881f; }

/* Floating "…" row menu — appended to <body>, so it uses explicit colors
   instead of the .ba-scoped variables. */
.ba-menu{ position:fixed; z-index:1000; min-width:186px; padding:6px;
  background:#fdfcf9; border:1px solid rgba(0,0,0,.10); border-radius:12px;
  box-shadow:0 14px 38px rgba(0,0,0,.17), 0 2px 8px rgba(0,0,0,.08); }
.ba-menu.is-dark{ background:#2a2a2e; border-color:rgba(255,255,255,.09);
  box-shadow:0 14px 40px rgba(0,0,0,.5); }
.bm-item{ display:flex; align-items:center; gap:11px; width:100%; padding:9px 11px;
  border-radius:8px; font:500 13.5px var(--font); color:#28282a; background:transparent;
  text-align:left; cursor:pointer; }
.bm-item svg{ width:17px; height:17px; color:#6f6e68; flex:0 0 auto; }
.bm-item:hover{ background:#f1f0eb; }
.bm-item.danger{ color:#c5301c; }
.bm-item.danger svg{ color:#c5301c; }
.bm-sep{ height:1px; background:rgba(0,0,0,.09); margin:5px 6px; }
.ba-menu.is-dark .bm-item{ color:#e9e8e3; }
.ba-menu.is-dark .bm-item svg{ color:#a0a09a; }
.ba-menu.is-dark .bm-item:hover{ background:rgba(255,255,255,.07); }
.ba-menu.is-dark .bm-item.danger{ color:#ff6a55; }
.ba-menu.is-dark .bm-item.danger svg{ color:#ff6a55; }
.ba-menu.is-dark .bm-sep{ background:rgba(255,255,255,.09); }
/* AI Cowork row skill picker — wider, scrolls if the skill list is long, with a header. */
.ba-menu-skills{ min-width:236px; max-height:340px; overflow-y:auto; }
.bm-head{ padding:7px 11px 8px; font:600 11.5px var(--font); color:#8a8980; letter-spacing:.02em; }
.bm-item .sparkle, .ba-menu-skills .bm-item svg{ color:#c5301c; }
.ba-menu.is-dark .bm-head{ color:#a0a09a; }
.ba-menu.is-dark.ba-menu-skills .bm-item svg{ color:#ff6a55; }

/* 播放钮:借悬浮卡 bw3-disc 的暖色机加工金属(径向高光 + 多层内/外阴影),与卡片质感统一。 */
.ba-disc{ position:relative; flex:0 0 auto; width:28px; height:28px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  background:radial-gradient(circle at 50% 36%, #fcfbf8, #e7e3db 70%, #d6d2c8);
  box-shadow:0 1px 0 rgba(255,255,255,.9) inset, 0 -1px 2px rgba(0,0,0,.08) inset, 0 0 0 1px rgba(0,0,0,.13), 0 1px 2px rgba(0,0,0,.16);
  cursor:pointer; }
.ba-disc svg{ width:11px; height:11px; color:#3a3a3c; margin-left:1px; }
.ba-disc.is-playing{ background:radial-gradient(circle at 50% 34%, #ff6e51, #e8402a 70%); box-shadow:0 0 0 1px rgba(150,30,15,.3), 0 1px 2px rgba(0,0,0,.25); }
.ba-disc.is-playing svg{ width:12px; height:12px; color:#fff; margin-left:0; }

/* ---------- 播放行(P1,2026-08-01):点了左列播放才出现,标题下一条波形 scrubber ----------
   视觉与试听波形(sp-wave)同族:灰底条 + 红色进度层同布局 clip-path 揭示;
   播放键沿用列表 is-playing 红盘,倍速钮 panel 底 mono 数字。 */
#hs-player-slot:empty{ display:none; }
/* 播放行 sticky 钉顶(owner 2026-08-02):往上滚不消失,挂在文档区顶部 ——
   用户永远知道播到哪。间距从 pill 的 margin 挪成 slot 的 padding(margin 会
   塌穿透明的 slot,钉住时下方文字从缝里露出来);钉住态由 .ba-doc 滚动侦测
   打 is-stuck,亮一条 hairline 分隔线(1px 实线,非投影)。 */
/* top:-32px 对冲 .ba-doc 的 padding-top(sticky 以滚动容器 padding 盒定位,
   top:0 会钉在内边距之下,上方 32px 缝里文字照样滚过 —— 真机取证)。
   横向同理(owner 2026-08-05 报「左右边缘卡掉」):slot 原本只有正文列那么宽,
   而正文里有两处【横向出血】比正文列更宽 —— 正在播放的段 .spk-playing 左右各
   出血 12px、时间码 .spk-tc 也是 margin:0 -12px —— 往上滚时这两侧的出血就从
   钉住的播放条两边露出来。修:slot 负边距吃满 .ba-doc 的 40px 横向内距、等量
   内距把 pill 推回原位 → 底色铺满整个滚动宽度,再宽的出血也遮得住,而 pill
   的位置与尺寸一像素没动。
   ⚠ 上下左右都与 .ba-doc 的 padding 耦合,改那边必改这里。 */
#hs-player-slot{ position:sticky; top:-32px; z-index:25; background:var(--panel);
  margin:0 -40px; padding:12px 40px 14px; }
#hs-player-slot.is-stuck{ box-shadow:0 1px 0 var(--hair); }
.ba-playstack{ display:flex; flex-direction:column; gap:8px; margin:0; }
.pr-sources{ display:flex; align-items:center; gap:4px; width:max-content; padding:3px;
  border-radius:9px; background:var(--panel); }
.pr-source{ border:0; border-radius:7px; padding:5px 9px; background:transparent;
  color:var(--ink2); font:600 11px/1.2 var(--font); cursor:pointer; }
.pr-source:hover{ color:var(--ink); }
.pr-source.is-on{ background:var(--surface); color:var(--ink); box-shadow:0 1px 4px rgba(0,0,0,.09); }
.ba-playrow{ display:flex; align-items:center; gap:12px; margin:0;
  padding:8px 12px; border-radius:14px; background:var(--field); }
.ba-playrow .pr-btn{ flex:0 0 auto; width:28px; height:28px; border-radius:50%;
  display:flex; align-items:center; justify-content:center; cursor:pointer;
  background:radial-gradient(circle at 50% 34%, #ff6e51, #e8402a 70%);
  box-shadow:0 0 0 1px rgba(150,30,15,.3), 0 1px 2px rgba(0,0,0,.25); }
.ba-playrow .pr-btn svg{ width:12px; height:12px; color:#fff; }
.ba-playrow .pr-btn[data-paused="true"] svg{ margin-left:2px; }
.ba-playrow .pr-wave{ position:relative; flex:1; height:34px; cursor:pointer; overflow:hidden; }
/* 竖条固定宽 2.5px(owner:必须有肉眼可见的宽度,发丝级太丑)、space-between 分缝;
   条数由 hsWaveFit 按轨道宽抽样,双层(底/红填充)同布局逐条对齐。 */
.ba-playrow .pr-base, .ba-playrow .pr-fillwrap{ position:absolute; inset:0;
  display:flex; align-items:center; justify-content:space-between; }
.ba-playrow .pr-wave i{ flex:0 0 3px; width:3px; border-radius:2px; background:var(--ink3);
  opacity:.5; display:block; }
.ba-playrow .pr-fillwrap i{ background:var(--red); opacity:1; }
.ba-playrow .pr-track{ flex:1; height:4px; border-radius:4px; background:var(--ink3); opacity:.35; }
.ba-playrow .pr-fillwrap .pr-track{ background:var(--red); opacity:1; }
.ba-playrow .pr-time{ flex:0 0 auto; display:flex; gap:4px; align-items:baseline;
  font-family:"SF Mono",ui-monospace,Menlo,monospace; font-size:12px; font-weight:600;
  color:var(--ink3); }
.ba-playrow .pr-time .pr-cur{ color:var(--ink); }
.ba-playrow .pr-speed{ flex:0 0 auto; border:0; background:var(--panel); border-radius:999px;
  padding:5px 12px; font-family:"SF Mono",ui-monospace,Menlo,monospace; font-size:12px;
  font-weight:700; color:var(--ink); cursor:pointer; min-width:52px; text-align:center; }
.ba-playrow .pr-speed:hover{ color:var(--red); }
.ba-playrow .pr-close{ flex:0 0 auto; width:22px; height:22px; border-radius:7px;
  display:flex; align-items:center; justify-content:center; font-size:15px;
  color:var(--ink3); user-select:none; -webkit-user-select:none; }
.ba-playrow .pr-close:hover{ background:var(--panel); color:var(--ink); }
.ba .ba-playrow .pr-close{ cursor:pointer !important; }
.ba .ba-playrow .pr-btn, .ba .ba-playrow .pr-wave, .ba .ba-playrow .pr-speed{ cursor:pointer !important; }

/* ---- 段级同步(P2,2026-08-02):播放中当前发言整块高亮 ----
   owner 视觉拍板:无竖线、浅色整块、同一发言(具名行+续行)绝不断开。
   连块手法:续行负上边距吃掉行距 + 等量内距补回 → 文本纹丝不动,底色连成一片;
   圆角只留组首(上圆角)与组尾(下圆角)。只 toggle class,绝不动文本节点。 */
.spk-row{ position:relative; }
.spk-row.spk-playing{ background:rgba(216,64,42,.06); border-radius:14px;
  /* 横向出血:负边距+等量内距 → 文字位置纹丝不动,底色向两侧延展出呼吸感 */
  margin-left:-12px; padding-left:12px; margin-right:-12px; padding-right:12px; }
.ba.is-dark .spk-row.spk-playing{ background:rgba(216,64,42,.11); }
.spk-row.spk-playing + .spk-row.spk-playing{ margin-top:-14px; padding-top:14px;
  border-top-left-radius:0; border-top-right-radius:0; }
.spk-row.spk-playing:has(+ .spk-row.spk-playing){
  border-bottom-left-radius:0; border-bottom-right-radius:0; }
/* 时间码在头像正下方(owner 拍板:不占水平空间),常显、点击跳播。
   avcol 定宽=头像宽,chip 负外边距对称出血 → 不同行文本列零错位;
   与头像留 8px 呼吸,高度做足(11px 字 + 上下 3.5px 内距),大方不局促。 */
.spk-avcol{ display:flex; flex-direction:column; align-items:center; gap:12px;
  flex:0 0 auto; width:30px; }
.spk-tc{ font-family:"SF Mono",ui-monospace,Menlo,monospace; font-size:11px; font-weight:700;
  line-height:1.4; color:var(--ink3); background:var(--field); border-radius:8px;
  padding:3.5px 6px; margin:0 -12px; white-space:nowrap;
  transition:color .12s, background .12s; user-select:none; -webkit-user-select:none; }
.spk-tc:hover{ color:#fff; background:var(--red); }
.ba .spk-tc{ cursor:pointer !important; }
/* 原文视图的稀疏时间码行(段落间独立小行,Podcasts 转写同款;根级 CE:false 序列化跳过) */
.raw-tcrow{ margin:14px 0 6px; line-height:1; }
.raw-tcrow .spk-tc{ margin:0; }
/* 深色主题:同款做成阳极氧化石墨(与 bw3 深色盘一致),避免亮金属在暗底刺眼。 */
.ba.is-dark .ba-disc{ background:radial-gradient(circle at 50% 34%,#54565d,#26282c 78%);
  box-shadow:0 0 0 1px rgba(0,0,0,.55),0 1px 2px rgba(0,0,0,.45),0 1px 0 rgba(255,255,255,.08) inset; }
.ba.is-dark .ba-disc svg{ color:#cfcfd6; }
.ba.is-dark .ba-disc.is-playing svg{ color:#fff; }

.ba-content{ flex:1.25 1 0; display:flex; flex-direction:column; min-width:0; background:var(--panel); }
.ba-doc{ flex:1; overflow-y:auto; padding:32px 40px 10px; }
/* The note title tracks the window's own screen-adaptive size: 24px at the full
   1180pt-wide window (27"), eased down to ~19px on a 13" laptop's ~944pt window,
   so the big headline doesn't dominate the smaller window. (2.034vw = 24px at a
   1180px viewport; clamp floors it at 19px and caps it at 24px.) */
.ba-doc h1{ margin:0 0 10px; font-size:clamp(19px, 2.034vw, 24px); font-weight:600; letter-spacing:-.02em; }
.ba-docmeta{ display:flex; gap:8px; align-items:center; font-family:var(--mono); font-size:12px; color:var(--ink3); margin-bottom:26px; flex-wrap:wrap; }
.ba-docmeta .sep{ color:var(--ink3); opacity:.5; }
.ba-docmeta .chip{ display:flex; align-items:center; gap:6px; }
.ba-docmeta .chip svg{ width:13px; height:13px; }
.ba-docmeta .match{ color:var(--red); }
.ba-para{ font-size:15px; line-height:1.78; color:var(--ink); margin:0 0 16px; max-width:62ch; }
.ba-para .spk{ font-weight:600; }
/* 全文搜索命中高亮:与 ⌘F 页面内查找同一款黄(owner 2026-07-30 统一;原红系+红下划线) */
.ba-hl{ background:rgba(255,213,79,.45); border-radius:2px; padding:0 1px; }

/* ---- Speakers (diarize) view: colored circular avatar + text, like a
   chat / meeting record. Avatar color is stable per speaker (set inline from
   the JS palette). Consecutive rows from the same speaker drop the avatar and
   align under a same-width spacer (.spk-av-ph). ---- */
.spk-row{ display:flex; gap:12px; align-items:flex-start; margin:0 0 14px; max-width:64ch; }
.spk-row.spk-cont{ margin-top:-8px; }   /* tuck follow-on lines closer to the turn */
.spk-av{ flex:0 0 auto; width:30px; height:30px; border-radius:50%; margin-top:3px;
  display:flex; align-items:center; justify-content:center; overflow:hidden;
  box-shadow:0 0 0 1px rgba(0,0,0,.06) inset, 0 1px 2px rgba(0,0,0,.14); }
.spk-av svg{ width:19px; height:19px; display:block; }
.spk-av-ph{ background:transparent !important; box-shadow:none !important; }   /* alignment spacer only */
.spk-col{ flex:1; min-width:0; }
.spk-name{ font-weight:700; font-size:.92em; line-height:1.5; margin:4px 0 2px; }
.spk-body{ flex:1; min-width:0; }
.ba-para.spk-text{ margin:0 0 6px; }
.ba-para.spk-text:last-child{ margin-bottom:0; }
.ba.is-dark .spk-av{ box-shadow:0 0 0 1px rgba(255,255,255,.12) inset, 0 1px 2px rgba(0,0,0,.4); }
/* 说话人档案:头像照片盖满圆盘(onerror 隐藏 → 露出底下剪影);可点区域给手型 +
   轻微悬停反馈(纯透明度,无渐变/无投影 —— App 审美红线)。 */
.spk-av{ position:relative; }
.spk-av img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block; }
/* 全局光标政策(.ba *=default!important / 编辑面=text!important)会把可点的头像/
   名字压成箭头或 I-beam —— 定点压回小手(owner 2026-07-31:用户得一眼知道能点)。
   编辑面内的同款豁免在光标政策区(搜 spk-clickable)还有一组更高特异度的。 */
.ba .spk-clickable, .ba .spk-av.spk-clickable *{ cursor:pointer !important; }
.spk-av.spk-clickable:hover{ filter:brightness(1.08); }
.spk-name.spk-clickable:hover{ text-decoration:underline; text-underline-offset:3px; }
/* 改名进行中:无边框无底色,只留细下划线示意可输入(IME 光标自然出现)。
   width:fit-content 收缩到文字宽度 —— 下划线只垫在名字底下,不拉通整列(owner
   2026-07-31)。⚠ 不许用 display:inline-block:名字被 Backspace 清空时,空的
   inline-block 会被 contenteditable 编辑逻辑连节点一起删掉(真机取证);保持
   block+fit-content,空节点存活、min-width 兜底可点。 */
.spk-name.spk-name-editing{ outline:none; text-decoration:none; width:fit-content;
  border-bottom:1.5px solid currentColor; min-width:4ch; max-width:100%; }
.ba .spk-name.spk-name-editing{ cursor:text !important; }

/* ⑦ 说话人视图首次引导:一行淡字 + ×,认过人/关过就永久退场(宁缺毋滥,不做卡片) */
.ba-spkhint{ display:flex; align-items:center; gap:10px; font-size:12.5px;
  color:var(--ink3); margin:0 0 16px; max-width:64ch; }
.ba-spkhint .hint-x{ cursor:pointer; flex:0 0 auto; width:20px; height:20px; border-radius:6px;
  display:flex; align-items:center; justify-content:center; font-size:14px; color:var(--ink3); }
.ba-spkhint .hint-x:hover{ background:var(--field); color:var(--ink); }

/* ---- Settings ▸ People(认识的人):头像+名字+笔记数,悬停出 ×,行内两步确认。
   纯色圆角、无渐变无投影(App 审美红线);删除确认用文字+两枚小按钮,不弹窗。 ---- */
.ba-spkprow{ display:flex; align-items:center; gap:12px; }
.ba-spkprow .sp-av{ width:34px; height:34px; }
.ba-spkprow .sp-av svg{ width:21px; height:21px; }
.ba-spkprow .sp-name{ font-weight:600; font-size:14px; color:var(--ink); min-width:4ch; }
.ba-spkprow .sp-tail{ margin-left:auto; display:flex; align-items:center; gap:10px; }
/* 试听:播放键 + 真实长波形,吃掉行中段的空(owner 2026-07-31)。纯色,无渐变无投影;
   播放中红色进度层按片段时长线性扫过(clip 宽度动画,不动 DOM)。 */
.ba-spkprow .sp-sample{ flex:1; min-width:120px; max-width:420px; display:flex; align-items:center;
  gap:10px; height:34px; padding:0 12px; margin:0 6px; border-radius:12px; }
.ba-spkprow .sp-sample:hover{ background:var(--field); }
.ba-spkprow .sp-play{ flex:0 0 auto; width:16px; height:16px; display:flex; align-items:center;
  justify-content:center; color:var(--ink2); }
.ba-spkprow .sp-play svg{ width:15px; height:15px; }
.ba-spkprow .sp-sample.is-playing .sp-play{ color:var(--red); }
.ba-spkprow .sp-wave{ position:relative; flex:1; display:flex; align-items:center;
  justify-content:space-between; height:24px; overflow:hidden; }
.ba-spkprow .sp-wave>i{ flex:0 0 3px; width:3px; border-radius:2px; background:var(--ink3);
  opacity:.55; display:block; }
/* 红色进度层与灰底层【完全同布局】,clip-path 从左往右揭示 —— 条条对齐,零重排 */
.ba-spkprow .sp-wave-on{ position:absolute; inset:0; display:flex; align-items:center;
  justify-content:space-between; animation:spSweep linear forwards; }
.ba-spkprow .sp-wave-on i{ flex:0 0 3px; width:3px; border-radius:2px; background:var(--red); display:block; opacity:1; }
@keyframes spSweep{ from{ clip-path:inset(0 100% 0 0); } to{ clip-path:inset(0 0 0 0); } }
.ba .ba-spkprow .sp-sample, .ba .ba-spkprow .sp-sample *{ cursor:pointer !important; }
/* 「{n} 条笔记」可点跳筛选:悬停下划线示意(与名字行同款轻反馈) */
.ba .ba-spkprow .sp-count.spk-clickable{ cursor:pointer !important; }
.ba-spkprow .sp-count.spk-clickable:hover{ color:var(--ink); text-decoration:underline; text-underline-offset:3px; }

/* 人物筛选胶囊(历史列表顶部):整条可点=清除。纯色圆角,与列表行同语言。 */
.ba-personbar{ display:flex; align-items:center; gap:9px; margin:2px 14px 8px;
  padding:6px 12px 6px 8px; border-radius:12px; background:var(--field); width:fit-content; max-width:calc(100% - 28px); }
.ba-personbar .pf-av{ flex:0 0 auto; width:24px; height:24px; margin:0; }
.ba-personbar .pf-av svg{ width:15px; height:15px; }
.ba-personbar .pf-name{ font-weight:600; font-size:13px; color:var(--ink); white-space:nowrap;
  overflow:hidden; text-overflow:ellipsis; }
.ba-personbar .pf-count{ font-size:12px; color:var(--ink3); white-space:nowrap; }
.ba-personbar .pf-x{ flex:0 0 auto; width:18px; height:18px; border-radius:6px; display:flex;
  align-items:center; justify-content:center; font-size:14px; color:var(--ink3); }
.ba-personbar:hover .pf-x{ background:rgba(0,0,0,.07); color:var(--ink); }
.ba .ba-personbar, .ba .ba-personbar *{ cursor:pointer !important; }
/* 声纹 debug 面板(Debug Mode 专用):等宽小字数据面孔,纯色圆角无投影 */
.ba-spkdbg-bar{ margin:6px 0 2px; }
.ba-spkdbg-btn{ font-size:11px; padding:3px 10px; }
.ba .ba-spkdbg-btn{ cursor:pointer !important; }
.ba-spkdbg{ margin:4px 0 10px; padding:10px 12px; border-radius:10px; background:var(--field);
  font:11px/1.7 ui-monospace, SFMono-Regular, Menlo, monospace; color:var(--ink2);
  user-select:text; -webkit-user-select:text; }
.ba-spkdbg .sd-head{ font-weight:700; color:var(--ink); }
.ba-spkdbg .sd-cluster{ margin:6px 0; }
.ba-spkdbg .sd-hit{ color:var(--ink); }
.ba-spkdbg .sd-src{ text-decoration:underline; text-underline-offset:2px; }
.ba-spkdbg .sd-src:hover{ color:var(--ink); }
.ba .ba-spkdbg .sd-src{ cursor:pointer !important; }
.ba-spkdbg .sd-enroll{ font-size:10.5px; padding:1px 8px; margin-left:8px; vertical-align:1px; }
.ba .ba-spkdbg .sd-enroll{ cursor:pointer !important; }
.ba-spkprow .sp-count{ font-size:12.5px; color:var(--ink3); }
.ba-spkprow .sp-x{ width:24px; height:24px; border-radius:7px; display:flex; align-items:center;
  justify-content:center; font-size:16px; color:var(--ink3); cursor:pointer; opacity:0; transition:opacity .12s; }
.ba-spkprow:hover .sp-x{ opacity:1; }
.ba-spkprow .sp-x:hover{ background:var(--field); color:var(--ink); }
.ba-spkprow .sp-confirm{ font-size:12.5px; color:var(--ink2); }
.ba-spkprow .sp-del-yes{ background:var(--red); color:#fff; }
.ba .ba-spkprow .sp-x, .ba .ba-spkprow .sp-av, .ba .ba-spkprow .sp-av *,
.ba .ba-spkprow .sp-name{ cursor:pointer !important; }
.ba .ba-spkprow .sp-name.spk-name-editing{ cursor:text !important; }

/* Export action bar — copy / save-as-file / system share for the current view.
   Replaces the deprecated Paste-to-AI hero. Sits under the transcript body. */
.ba-actionbar{ padding:14px 40px 20px; border-top:1px solid var(--hair); display:flex; align-items:center; gap:10px; }
.ba-actionbar .ba-btn{ height:38px; padding:0 16px; font-size:13.5px; }
.ba-btn .ico{ display:flex; width:17px; height:17px; }
.ba-btn .ico svg{ width:17px; height:17px; }

/* Inline transcript editor (Raw / Speakers / Markdown). The textarea fills the
   reading column; the bar below carries Save / Cancel + a per-mode hint. */
.ba-editor{ width:100%; max-width:none; min-height:46vh; box-sizing:border-box; resize:vertical;
  font-family:var(--font); font-size:15px; line-height:1.78; color:var(--ink);
  background:var(--field); border:0; box-shadow:0 0 0 1px var(--hair) inset; border-radius:10px;
  padding:16px 18px; outline:none; }
.ba-editor:focus{ box-shadow:0 0 0 2px var(--red) inset; }
.ba.is-dark .ba-editor{ background:var(--panel); }
/* Title input in edit mode — the h1's type, the editor's field chrome. */
.ba-title-edit{ display:block; width:100%; box-sizing:border-box; margin:0 0 10px;
  font-family:var(--font); font-size:clamp(19px, 2.034vw, 24px); font-weight:600; letter-spacing:-.02em;
  color:var(--ink); background:var(--field); border:0; box-shadow:0 0 0 1px var(--hair) inset;
  border-radius:10px; padding:6px 12px; outline:none; }
.ba-title-edit:focus{ box-shadow:0 0 0 2px var(--red) inset; }
.ba.is-dark .ba-title-edit{ background:var(--panel); }
.ba-editbar{ display:flex; align-items:center; gap:12px; margin:14px 0 4px; }

/* Right cluster of the variant tab bar: Edit button + debug. */
.ba-tabactions{ display:inline-flex; align-items:center; gap:8px; flex:0 0 auto; }
.ba-edit-btn{ display:inline-flex; align-items:center; gap:6px; height:30px; padding:0 14px; border:0; border-radius:var(--rbtn);
  background:var(--field); color:var(--ink2); font-family:var(--font);
  font-size:12.5px; font-weight:600; cursor:pointer; }
.ba-edit-btn:hover{ color:var(--ink); }
.ba-edit-btn svg{ width:14px; height:14px; }

/* files */
.ba-droparea{ flex:1; display:flex; background:var(--bg); }
.ba-drop{ flex:1; margin:20px; border-radius:12px; border:1.5px dashed var(--red); background:var(--redsoft);
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:18px; transition:box-shadow .12s, background .12s; }
.ba-drop.is-hot{ background:rgba(216,64,42,.18); box-shadow:0 0 0 4px var(--redsoft) inset; }
.ba-dropcircle{ width:84px; height:84px; border-radius:50%; display:flex; align-items:center; justify-content:center; color:var(--red);
  background:var(--chip); box-shadow:0 0 0 1px var(--hair) inset; }
.ba-dropcircle svg{ width:40px; height:40px; }
.ba-droptitle{ font-size:20px; font-weight:600; letter-spacing:-.02em; text-align:center; }
.ba-dropsub{ font-size:14px; color:var(--ink2); margin-top:8px; text-align:center; }
.ba-droprow{ display:flex; gap:8px; margin-top:6px; flex-wrap:wrap; justify-content:center; }
.ba-pill{ font-family:var(--mono); font-size:11px; font-weight:500; color:var(--ink2); padding:5px 12px; border-radius:7px;
  background:var(--panel); box-shadow:0 0 0 1px var(--hair) inset; }

.ba-tasks{ flex:1; display:flex; flex-direction:column; background:var(--panel); min-width:0; }
.ba-taskhead{ padding:22px 28px 18px; border-bottom:1px solid var(--hair); }
.ba-taskhead h2{ margin:0 0 6px; font-family:var(--mono); font-size:15px; font-weight:700; letter-spacing:.05em; text-transform:uppercase; display:flex; align-items:center; gap:10px; }
.ba-taskhead .live{ width:8px; height:8px; border-radius:50%; background:var(--red); }
.ba-taskhead.is-live .live{ animation:bwpulse 1.1s ease-in-out infinite; }
.ba-taskhead .sub{ font-family:var(--mono); font-size:12px; color:var(--ink3); }
.ba-taskstats{ display:flex; gap:36px; margin-top:18px; }
.ba-stat .n{ font-family:var(--mono); font-size:22px; font-weight:700; letter-spacing:0; }
.ba-stat .l{ font-family:var(--mono); font-size:10px; color:var(--ink3); text-transform:uppercase; letter-spacing:.1em; margin-top:4px; }
.ba-tasklist{ flex:1; overflow-y:auto; padding:6px 0; }
.ba-task{ display:flex; align-items:center; gap:14px; padding:11px 28px; border-bottom:1px solid var(--hairsoft); }
.ba-ft{ width:32px; height:32px; border-radius:7px; flex:0 0 auto; display:flex; align-items:center; justify-content:center; font-family:var(--mono); font-size:9px; font-weight:600; color:#fff; }
.ba-ft.vid{ background:#e7eaf0; color:#69748c; }
.ba-ft.aud{ background:#e7ece9; color:#5f8270; }
.ba.is-dark .ba-ft.vid{ background:#33363d; color:#aeb6c6; }
.ba.is-dark .ba-ft.aud{ background:#2f3a35; color:#9cc1ad; }
.ba-task .info{ flex:1; min-width:0; }
.ba-task .fn{ font-size:13.5px; font-weight:500; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.ba-task .fmeta{ font-family:var(--mono); font-size:11px; color:var(--ink3); margin-top:2px; }
.ba-bar{ flex:0 0 150px; height:4px; border-radius:2px; overflow:hidden; background:var(--field); }
.ba-bar > i{ display:block; height:100%; border-radius:2px; background:var(--red); transition:width .3s ease; }
.ba.is-dark .ba-bar > i{ background:var(--ink2); }
.ba-status{ flex:0 0 76px; text-align:right; font-family:var(--mono); font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.05em; }
.ba-status.doing{ color:var(--red); }
.ba-status.done{ color:var(--ink2); }
.ba-status.queued{ color:var(--ink3); }
.ba-status.failed{ color:var(--red); cursor:pointer; text-decoration:underline; }
/* ---- Files 页重做:顶部大拖拽区(动画邀请,占上半)+ 下方队列 ---- */
.ba-files-pane{ flex:1; display:flex; flex-direction:column; min-width:0; background:var(--bg); }
.ba-files-top{ flex:1 1 0; min-height:210px; display:flex; padding:40px 48px 44px; }
/* 外框:大圆角(38px)+ 粗虚线(4px)+ 稀疏 dash —— border-style:dashed 控不了 dash 间距,
   用内联 SVG 背景画(owner 2026-07-15:大大大圆角、粗一点、dash 别太密)。 */
.ba-fdrop{ flex:1; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:30px; text-align:center;
  border-radius:52px; background-color:var(--panel); background-image:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='100%'%20height='100%'%3E%3Crect%20x='0'%20y='0'%20width='100%'%20height='100%'%20rx='52'%20ry='52'%20fill='none'%20stroke='rgba%280%2C0%2C0%2C0.09%29'%20stroke-width='8'%20stroke-dasharray='7%2011'/%3E%3C/svg%3E"); transition:box-shadow .18s, background .18s, transform .18s; }
.ba.is-dark .ba-fdrop:not(.is-hot):not(.is-scanning){ background-image:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='100%'%20height='100%'%3E%3Crect%20x='0'%20y='0'%20width='100%'%20height='100%'%20rx='52'%20ry='52'%20fill='none'%20stroke='rgba%28255%2C255%2C255%2C0.085%29'%20stroke-width='8'%20stroke-dasharray='7%2011'/%3E%3C/svg%3E"); }
/* Dragging a media/folder over the zone: solid accent ring + a gentle "pop" so
   the user clearly sees it'll catch the drop. */
.ba-fdrop.is-hot{ background-image:none; box-shadow:0 0 0 2.5px var(--red) inset; background-color:var(--redsoft); transform:scale(1.012); }
.ba-fdrop-icon{ width:88px; height:88px; border-radius:50%; display:flex; align-items:center; justify-content:center; color:var(--red); background:var(--redsoft); animation:hsDropBob 2.2s ease-in-out infinite; }
.ba-fdrop-icon svg{ width:40px; height:40px; }
@keyframes hsDropBob{ 0%,100%{ transform:translateY(0);} 50%{ transform:translateY(-6px);} }
/* Walking a dropped folder for media — spinner while the scan runs. */
.ba-fdrop.is-scanning{ background-image:none; box-shadow:0 0 0 2.5px var(--red) inset; background-color:var(--redsoft); }
.ba-fdrop-spin{ width:36px; height:36px; border-radius:50%; box-sizing:border-box; border:3px solid var(--redsoft); border-top-color:var(--red); animation:baspin .7s linear infinite; }
.ba-fdrop-title{ font-size:26px; font-weight:650; letter-spacing:-.02em; color:var(--ink);
  max-width:22em; padding:0 48px; text-wrap:balance; }   /* 左右留白+均衡断行:防「一行到边、二行两个字」(owner 2026-07-20,全语言通用) */
.ba-fdrop-sub{ font-size:13px; color:var(--ink2); max-width:430px; line-height:1.5; }
.ba-fdrop-pills{ display:flex; gap:9px; flex-wrap:wrap; justify-content:center; margin-top:4px; }
/* 格式图块(owner 2026-07-15:图标要大、单独在上一行,文字在下) */
.ba-fdrop-pills{ gap:14px; }
.ba-fdrop-pills .ba-pill{ display:inline-flex; flex-direction:column; align-items:center; gap:10px; padding:18px 24px; border-radius:20px; font-size:12px; }
.ba-pill-ic{ display:inline-flex; color:var(--ink3); }
.ba-pill-ic svg{ width:34px; height:34px; }
/* Stable queue slot: takes the bottom half (like the old queue did) so the drop
   zone keeps its height, and the list scrolls INTERNALLY — so rebuilding the slot
   never changes its outer height → no whole-pane reflow/flash. Empty → 0 height
   so the drop zone gets the full pane when there's no queue. */
.ba-files-queue-slot{ flex:1 1 0; min-height:0; display:flex; flex-direction:column; }
.ba-files-queue-slot:empty{ flex:0 0 0; }
.ba-queue{ flex:1 1 0; min-height:0; display:flex; flex-direction:column; border-top:1px solid var(--hair); background:var(--panel); }
.ba-queue-head{ display:flex; align-items:center; gap:12px; padding:13px 28px; border-bottom:1px solid var(--hairsoft); }
.ba-queue-head .qh-title{ font-family:var(--mono); font-size:12.5px; font-weight:700; letter-spacing:.05em; text-transform:uppercase; color:var(--ink); display:flex; align-items:center; gap:8px; }
.ba-queue-head .live{ width:8px; height:8px; border-radius:50%; background:var(--ink3); }
.ba-queue-head.is-live .live{ background:var(--red); animation:bwpulse 1.1s ease-in-out infinite; }
.ba-queue-head .qh-sub{ font-family:var(--mono); font-size:11.5px; color:var(--ink3); }
.ba-queue-list{ flex:1; overflow-y:auto; padding:4px 0; }
/* Redesigned queue: one "Resume all" in the header; each row is either a live
   progress bar (running) or a single Resume pill + a big ✕ — no empty-bar
   "skewer", no Retry/Queued labels. */
.ba-resume-all{ margin-left:auto; display:inline-flex; align-items:center; gap:6px; height:30px; padding:0 14px; border:0; border-radius:8px; background:var(--red); color:#fff; font-family:var(--font); font-size:12.5px; font-weight:600; cursor:pointer; }
.ba-resume-all:hover{ filter:brightness(.95); }
/* Pause all — shown while transcribing; neutral (ghost) so it reads as "stop for
   now", distinct from the red Resume all. */
.ba-pause-all{ margin-left:auto; display:inline-flex; align-items:center; gap:6px; height:30px; padding:0 14px; border:0; border-radius:8px; background:var(--field); color:var(--ink); box-shadow:0 0 0 1px var(--hair) inset; font-family:var(--font); font-size:12.5px; font-weight:600; cursor:pointer; }
.ba-pause-all:hover{ background:var(--red); color:#fff; box-shadow:none; }
.ba-resume-all .ico, .ba-task-resume .ico, .ba-pause-all .ico{ display:inline-flex; width:12px; height:12px; }
.ba-resume-all .ico svg, .ba-task-resume .ico svg, .ba-pause-all .ico svg{ width:12px; height:12px; }
.ba-task-resume{ flex:0 0 auto; display:inline-flex; align-items:center; gap:6px; height:30px; padding:0 14px; border:0; border-radius:8px; background:var(--field); color:var(--ink); box-shadow:0 0 0 1px var(--hair) inset; font-family:var(--font); font-size:12.5px; font-weight:600; cursor:pointer; }
.ba-task-resume:hover{ background:var(--red); color:#fff; box-shadow:none; }
.ba-task-pct{ flex:0 0 auto; min-width:56px; text-align:right; font-family:var(--mono); font-size:13px; font-weight:700; font-variant-numeric:tabular-nums; color:var(--red); }
/* Queued = in line, will auto-start when a worker frees. Greyed, NOT a button —
   so the user knows it's waiting (clicking Resume on it would do nothing). */
.ba-task-queued{ flex:0 0 auto; display:inline-flex; align-items:center; height:30px; padding:0 12px; font-family:var(--font); font-size:12.5px; font-weight:600; color:var(--ink3); opacity:.65; }
.ba-task-x{ flex:0 0 auto; width:30px; height:30px; display:inline-flex; align-items:center; justify-content:center; border:0; border-radius:8px; background:transparent; color:var(--ink3); font-size:18px; line-height:1; cursor:pointer; }
.ba-task-x:hover{ background:rgba(232,64,42,.12); color:var(--red); }

/* ---- Dictation 教学页(Dictation 导航 → 右栏):大文本框 + 摁住 Option 教学动画 ---- */
.ba-dictate-pane{ background:var(--bg); }
/* 纵向布局(作者 2026-07-17 A+C 整理):教学模块 + 词典是【一组内容流】,整组垂直居中
   (auto margin 居中而非 justify-content:center —— 矮窗口溢出时后者会裁掉顶部,auto
   margin 溢出自动归零、可滚动)。底 padding 大于顶 = 整组略偏上。词典不再贴底:固定
   margin-top 跟随教学模块(150px = 绝对定位键盘引导 ~112px + 呼吸),中段真空消失。 */
.ba-dictate-scroll{ display:flex; flex-direction:column; align-items:center; padding:40px 40px 88px; }
/* 顶距只随窗高、不随词典条数(owner 2026-07-20:词多把教学模块顶上去很怪异);
   词典块 margin-bottom 也不再 auto,超出往下滚。 */
.ba-dictate-wrap{ margin-top:clamp(16px, 8vh, 88px); }
/* 词典块(作者 2026-07-17 定稿):标题/副标题与教学模块同轴【居中】;气泡【左对齐】
   (居中排两行长短不一更乱,作者否)。横线已否,留间距不留线。 */
/* 引导已上移进副标题位,输入框下方不再有 overlay → 间距从 150px 收到 96px */
.ba-dictate-dict{ margin-bottom:0; width:100%; max-width:660px; text-align:center;
  margin-top:96px; padding-top:0; }
/* 副行说明已删(2026-07-17):dname 直接接气泡,间距归 dname 的 margin-bottom。
   字体与键盘引导文字 .ba-dstep-t 同款(作者钦定:14px/600/ink2)。 */
.ba-dictate-dict .dname{ font-size:14px; font-weight:600; color:var(--ink2); margin:0 0 16px; }
/* 气泡随标题同轴居中(作者 2026-07-17 终稿;Settings 页仍左排不受影响) */
.ba-dictate-dict .ba-dictwrap{ justify-content:center; }
.ba-dictate-wrap{ width:100%; max-width:660px; text-align:center; position:relative; }
.ba-dictate-wrap .ba-dictate-title{ margin:0 0 16px; font-size:26px; font-weight:650; letter-spacing:-.02em; color:var(--ink); }
/* (.ba-dictate-sub 文字副标题已删 —— 键盘引导 .ba-dictate-guide 接管副标题位,2026-07-17) */
.ba-dictate-box{ position:relative; }
.ba-dictate-input{ width:100%; min-height:112px; resize:none; box-sizing:border-box; border-radius:26px; border:1px solid var(--hair); background:var(--field); padding:20px 22px; font-family:var(--font); font-size:15px; line-height:1.65; color:var(--ink); box-shadow:0 1px 3px rgba(0,0,0,.05); transition:border-color .2s, box-shadow .2s; }
.ba-dictate-input::placeholder{ color:var(--ink3); }
.ba-dictate-input:focus{ outline:none; border-color:var(--red); box-shadow:0 0 0 3px var(--redsoft); }
/* 未聚焦:输入框脉冲邀请点击(对应第①步)。 */
.ba-dictate-wrap:not(:focus-within) .ba-dictate-input{ animation:hsInvite 2s ease-in-out infinite; }
@keyframes hsInvite{ 0%,100%{ box-shadow:0 1px 3px rgba(0,0,0,.05), 0 0 0 0 var(--redsoft);} 50%{ box-shadow:0 1px 3px rgba(0,0,0,.05), 0 0 0 6px var(--redsoft);} }
/* 键盘引导(owner 2026-07-17 合二为一):文字副标题已删,引导以副标题规格常驻标题
   下方 —— 无框无底,只有「按住右 + 键帽切片 + 说话」一行,不与输入框争主角。
   聚焦前静止;聚焦后 ⌥ 键帽才呼吸浮动(该按了);真按下时键帽下压(JS .is-optdown)。 */
.ba-dictate-guide{ display:flex; align-items:center; justify-content:center; gap:10px; margin:18px auto 26px; }
.ba-dstep-t{ font-size:14px; font-weight:600; color:var(--ink2); }
/* Option 键帽:第②步激活时轻晃引导按下;真按下 Option(JS 加 .is-optdown)时压下去,松手弹回。 */
.ba-optkey{ display:inline-flex; flex-direction:column; align-items:center; gap:0; min-width:48px; padding:5px 10px 4px; border-radius:8px; background:var(--panel); border:1px solid var(--hair); color:var(--ink);
  box-shadow:0 2px 0 var(--hair), 0 3px 5px rgba(0,0,0,.10); transition:transform .07s ease, box-shadow .07s ease, background .1s, border-color .1s; }
.ba-optkey .kc-glyph{ font-size:15px; line-height:1.1; }
.ba-optkey .kc-name{ font-family:var(--mono); font-size:8.5px; letter-spacing:.03em; color:var(--ink3); }
.ba-dictate-wrap:focus-within .ba-dictate-guide .ba-optkey{ animation:hsOptBob 1.4s ease-in-out infinite, hsOptGlow 2.2s ease-in-out infinite; }
@keyframes hsOptBob{ 0%,100%{ transform:translateY(0);} 50%{ transform:translateY(-2px);} }
/* 真按下:整键变红、字反白(作者 2026-07-17:原灰底红圈不明显),压下 2px。 */
.ba-dictate-wrap.is-optdown .ba-optkey{ transform:translateY(2px) !important; animation:none !important; background:var(--red); border-color:var(--red); color:#fff; box-shadow:0 1px 2px rgba(0,0,0,.12); }
.ba-dictate-wrap.is-optdown .ba-optkey .kc-name{ color:rgba(255,255,255,.85); }

/* 第②步键盘右下角切片(.ba-minikb):让"右 Option"一眼定位到键盘右下角。
   空格条左缘渐隐 = 键盘还在往左延续;方向键倒 T 簇 = 右下角地标;⌥ 呼吸红光 = 主角。 */
.ba-minikb{ display:inline-flex; align-items:flex-end; gap:4px; margin:0 -2px;
  padding:10px 10px 6px;   /* 内留画布:⌥ 上浮 + 红圈呼吸光都画在 mask 框内,不再被裁 */
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 48px); mask-image:linear-gradient(90deg,transparent 0,#000 48px); }
.mk-k{ box-sizing:border-box; display:inline-flex; align-items:center; justify-content:center;
  height:38px; border-radius:7px; background:var(--panel); border:1px solid var(--hair);
  box-shadow:0 1.5px 0 var(--hair); color:var(--ink3); }
.mk-space{ width:58px; }
.mk-mod{ width:38px; font-size:16px; color:var(--ink2); }
.mk-ak{ width:27px; height:18px; border-radius:5px; font-size:8px; align-self:flex-end; }
.mk-updown{ display:inline-flex; flex-direction:column; gap:2px; }
.mk-hk{ width:27px; height:18px; border-radius:5px; font-size:8px; }
.ba-minikb .ba-optkey{ min-width:0; width:58px; height:46px; padding:0; flex-direction:column; justify-content:center; gap:2px;
  border-color:var(--red); box-shadow:0 0 0 1px var(--red), 0 2px 0 rgba(0,0,0,.06), 0 0 10px var(--redsoft); animation:hsOptGlow 2.2s ease-in-out infinite; }
.ba-minikb .ba-optkey .kc-glyph{ font-size:18px; }
.ba-minikb .ba-optkey .kc-name{ font-size:8px; letter-spacing:.08em; color:var(--ink2); }   /* 全小写(作者 2026-07-17):不再 uppercase,跟 HTML 的 toLowerCase 走 */
@keyframes hsOptGlow{ 0%,100%{ box-shadow:0 0 0 1px var(--red), 0 2px 0 rgba(0,0,0,.06), 0 0 6px var(--redsoft);}
  50%{ box-shadow:0 0 0 1.5px var(--red), 0 2px 0 rgba(0,0,0,.06), 0 0 18px var(--redsoft);} }

/* ============================================================
   AI Cowork home (left nav) — one calm screen: 4 animated core
   skills as the hero, 5 secondary chips, a quiet agent disclosure.
   ============================================================ */
.ba-cowork-pane{ background:var(--bg); }
/* Center the whole view (both axes) like the Files pane; `safe center` keeps tall
   content scrolling from the top instead of clipping above the scroll area. */
.ba-cowork-scroll{ display:flex; flex-direction:column; align-items:center; justify-content:safe center; padding:40px 40px 56px; }
.ba-cowork-wrap{ width:100%; max-width:720px; }
.ba-cowork-title{ margin:0 0 12px; font-size:26px; font-weight:650; letter-spacing:-.02em; color:var(--ink); text-align:center; }
.ba-cowork-sub{ margin:0 auto 28px; max-width:540px; font-size:13.5px; line-height:1.65; color:var(--ink2); text-align:center; }
.ba-cowork-sub b{ color:var(--ink); font-weight:600; }
.ba-cowork-howto{ margin:18px 2px 2px; font-size:12.5px; color:var(--ink3); line-height:1.5; text-align:center; }
.ba-cowork-howto b{ color:var(--ink2); font-weight:600; }

/* 2×2 grid of skill cards — calm horizontal rows: icon · name+one-liner · cue */
.ba-skillgrid{ display:grid; grid-template-columns:1fr 1fr; gap:14px; }
@media (max-width:620px){ .ba-skillgrid{ grid-template-columns:1fr; } }
.ba-skillcard{ position:relative; display:flex; align-items:center; gap:14px; text-align:left;
  background:var(--field); border:1px solid var(--hair); border-radius:14px; padding:16px 16px; cursor:pointer;
  transition:border-color .15s, box-shadow .15s, transform .12s; }
.ba-skillcard:hover{ border-color:var(--ink3); box-shadow:0 6px 20px rgba(0,0,0,.06); }
.ba-skillcard:active{ transform:scale(.99); }
.ba-skillicon{ flex:0 0 auto; width:42px; height:42px; border-radius:11px; display:flex; align-items:center; justify-content:center;
  background:var(--redsoft); color:var(--red); transition:transform .15s; }
.ba-skillicon svg{ width:22px; height:22px; }
.ba-skillcard:hover .ba-skillicon{ transform:scale(1.06); }
.ba-skilltext{ flex:1; min-width:0; display:flex; flex-direction:column; gap:2px; }
.ba-skillname{ font-size:15px; font-weight:650; color:var(--ink); letter-spacing:-.01em; }
.ba-skillone{ font-size:12px; color:var(--ink3); line-height:1.4; }
.ba-skillcue{ flex:0 0 auto; font-size:11.5px; font-weight:600; color:var(--ink3); opacity:0; transform:translateX(-3px);
  transition:opacity .15s, transform .15s; white-space:nowrap; }
.ba-skillcard:hover .ba-skillcue{ opacity:1; transform:none; }
.ba-skill-copied{ position:absolute; top:10px; right:12px; z-index:3; font-size:11px; font-weight:700; color:#fff; background:var(--red);
  border-radius:999px; padding:3px 9px; opacity:0; transform:translateY(-4px); transition:opacity .15s, transform .15s; pointer-events:none; }
.ba-skillcard.is-copied .ba-skill-copied{ opacity:1; transform:none; }
.ba-skillcard.is-copied .ba-skillcue{ opacity:0; }

/* recording picker — click a skill → choose which recording to run it on */
.ba-pickwrap{ position:fixed; inset:0; z-index:1100; display:flex; align-items:flex-start; justify-content:center;
  padding-top:8vh; background:rgba(0,0,0,.45); -webkit-backdrop-filter:blur(3px); backdrop-filter:blur(3px); animation:hsFadeIO .14s ease; }
.ba-pickcard{ width:min(520px,92vw); max-height:78vh; display:flex; flex-direction:column; background:#ffffff; background:var(--panel);
  border:1px solid var(--hair); border-radius:16px; box-shadow:0 24px 70px rgba(0,0,0,.4); overflow:hidden; }
.ba.is-dark .ba-pickcard{ background:#27272b; }
.ba-pick-head{ display:flex; align-items:center; justify-content:space-between; padding:16px 18px 10px; }
.ba-pick-title{ display:flex; align-items:center; gap:8px; font-size:15px; font-weight:600; color:var(--ink); }
.ba-pick-title svg{ width:18px; height:18px; color:var(--red); flex:0 0 auto; }
.ba-pick-title b{ font-weight:700; }
.ba-pick-x{ background:none; border:none; cursor:pointer; font-size:20px; line-height:1; color:var(--ink3); padding:0 6px; border-radius:6px; }
.ba-pick-x:hover{ background:var(--field); color:var(--ink); }
.ba-pick-sub{ padding:2px 18px 6px; font-size:11px; font-weight:600; letter-spacing:.03em; text-transform:uppercase; color:var(--ink3); }
.ba-pick-langs{ display:flex; flex-wrap:wrap; gap:6px; padding:0 18px 12px; }
.ba-pick-lang{ font-size:11.5px; font-weight:600; color:var(--ink2); background:var(--field); border:1px solid var(--hair); border-radius:999px; padding:4px 11px; cursor:pointer; transition:all .12s; }
.ba-pick-lang:hover{ color:var(--ink); border-color:var(--ink3); }
.ba-pick-lang.is-on{ color:#fff; background:var(--red); border-color:var(--red); }
.ba-pick-search{ display:flex; align-items:center; gap:8px; margin:0 18px 8px; padding:9px 12px; background:var(--field); border:1px solid var(--hair); border-radius:10px; }
.ba-pick-search svg{ width:15px; height:15px; color:var(--ink3); flex:0 0 auto; }
.ba-pick-search input{ flex:1; min-width:0; border:none; background:none; outline:none; font-family:var(--font); font-size:13.5px; color:var(--ink); }
.ba-pick-search input::placeholder{ color:var(--ink3); }
.ba-pick-list{ flex:1; overflow-y:auto; padding:2px 10px 12px; }
.ba-pick-row{ display:flex; flex-direction:column; gap:2px; width:100%; text-align:left; background:none; border:none; border-radius:9px; padding:9px 11px; cursor:pointer; }
.ba-pick-row:hover{ background:var(--field); }
.ba-pick-row-t{ font-size:13.5px; font-weight:600; color:var(--ink); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:100%; }
.ba-pick-row-m{ font-size:11.5px; color:var(--ink3); }
.ba-pick-empty{ padding:34px 18px; text-align:center; font-size:13px; color:var(--ink3); line-height:1.5; }

/* "More skills" divider + secondary chips */
.ba-cowork-rule{ display:flex; align-items:center; gap:12px; margin:30px 0 14px; }
.ba-cowork-rule::before, .ba-cowork-rule::after{ content:''; flex:1; height:1px; background:var(--hairsoft); }
.ba-cowork-rule span{ font-size:11px; font-weight:600; letter-spacing:.05em; text-transform:uppercase; color:var(--ink3); }
.ba-morechips{ display:flex; flex-wrap:wrap; gap:8px; justify-content:center; }
.ba-morechip{ font-size:12.5px; font-weight:600; color:var(--ink2); background:var(--field); border:1px solid var(--hair); border-radius:999px; padding:6px 13px; cursor:pointer; transition:all .12s; }
.ba-morechip:hover{ color:var(--ink); border-color:var(--ink3); }
.ba-morechip.is-copied{ color:#fff; background:var(--red); border-color:var(--red); }

/* agent batch path — prominent heading + one short line + a ONE-LINER you copy */
.ba-cowork-agent{ margin-top:34px; border-top:1px solid var(--hairsoft); padding-top:18px; }
.ba-cw-agent-head{ margin:0 0 4px; font-size:15px; font-weight:650; letter-spacing:-.01em; color:var(--ink); }
.ba-cw-agent-line{ margin:0 0 11px; font-size:12.5px; line-height:1.55; color:var(--ink2); }
.ba-cw-agent-line b{ color:var(--ink); font-weight:600; }
.ba-cw-oneliner{ display:flex; align-items:center; gap:10px; }
.ba-cw-oneliner-txt{ flex:1; min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  font-family:var(--mono); font-size:11.5px; color:var(--ink2); background:var(--field); border:1px solid var(--hair);
  border-radius:9px; padding:9px 12px; }
.ba-cw-oneliner .ba-cw-copy{ position:static; flex:0 0 auto; }

/* copy toast (skill copied from menu or card) */
.ba-cwtoast{ position:fixed; left:50%; bottom:30px; transform:translate(-50%,14px); z-index:1200; display:flex; align-items:center; gap:8px;
  background:#28282a; color:#fff; font-size:12.5px; font-weight:600; padding:9px 15px; border-radius:999px; box-shadow:0 10px 30px rgba(0,0,0,.28);
  opacity:0; pointer-events:none; transition:opacity .2s, transform .2s; }
.ba-cwtoast .ico{ display:inline-flex; }
.ba-cwtoast .ico svg{ width:15px; height:15px; }
.ba-cwtoast.is-in{ opacity:1; transform:translate(-50%,0); }
.ba-cwtoast.is-out{ opacity:0; transform:translate(-50%,14px); }

/* skill picker menu: name-over-one-liner + "More" subhead */
.ba-menu-skills .bm-skill{ align-items:flex-start; }
.ba-menu-skills .bm-skill svg{ margin-top:1px; }
.bm-txt{ display:flex; flex-direction:column; gap:1px; min-width:0; }
.bm-nm{ font-size:13px; font-weight:600; color:inherit; line-height:1.2; }
.bm-one{ font-style:normal; font-size:11px; color:#8a8980; line-height:1.25; }
.bm-subhead{ padding:9px 11px 3px; font:700 10px var(--font); letter-spacing:.06em; text-transform:uppercase; color:#a8a79f; }
.ba-menu.is-dark .bm-one{ color:#9a9a93; }
.ba-menu.is-dark .bm-subhead{ color:#88877f; }

/* ============================================================
   NEW Braun-token surfaces: empty states, single-pane views,
   Templates, Settings, Pro. Same flat discipline, same tokens.
   ============================================================ */
.ba-pane{ flex:1; min-width:0; display:flex; flex-direction:column; background:var(--panel); overflow:hidden; }
.ba-pane-scroll{ flex:1; overflow-y:auto; padding:32px 40px 40px; }
.ba-pane-scroll{ scrollbar-width:none; }   /* 右栏各页(统计/音声入力/文件…)统一隐藏灰色滚动条(owner 2026-07-20:很丑) */
.ba-pane-scroll::-webkit-scrollbar{ display:none; }
.ba-pane h1{ margin:0 0 4px; font-size:24px; font-weight:600; letter-spacing:-.02em; }
.ba-pane .lead{ font-size:13.5px; color:var(--ink2); margin:0 0 26px; max-width:60ch; line-height:1.5; }

.ba-empty{ flex:1; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:14px; color:var(--ink3); text-align:center; padding:40px; }
.ba-empty .big{ font-size:17px; font-weight:600; color:var(--ink2); }
.ba-empty .small{ font-size:13px; max-width:40ch; line-height:1.5; }
.ba-empty .kbd{ font-family:var(--mono); font-size:12px; background:var(--field); box-shadow:0 0 0 1px var(--hair) inset; padding:2px 8px; border-radius:6px; color:var(--ink); }

/* section card grid (templates, pro) */
.ba-grid{ display:grid; grid-template-columns:repeat(auto-fill, minmax(220px,1fr)); gap:14px; }
.ba-card{ background:var(--bg); border-radius:10px; box-shadow:0 0 0 1px var(--hair) inset; padding:16px 18px; cursor:pointer; display:flex; flex-direction:column; gap:8px; }
.ba-card:hover{ box-shadow:0 0 0 1px var(--ink3) inset; }
.ba-card.is-on{ box-shadow:0 0 0 1px var(--red) inset; }
.ba-card .ct{ font-size:14.5px; font-weight:600; display:flex; align-items:center; gap:8px; }
.ba-card .ct .ti{ width:16px; height:16px; color:var(--ink2); display:flex; }
.ba-card .cd{ font-size:12.5px; color:var(--ink2); line-height:1.5; }
.ba-card .cmeta{ font-family:var(--mono); font-size:10.5px; color:var(--ink3); text-transform:uppercase; letter-spacing:.08em; }

.ba-sectlabel{ font-family:var(--mono); font-size:11px; font-weight:700; letter-spacing:.14em; text-transform:uppercase; color:var(--ink2); margin:34px 0 10px; }
/* 大模块之间画一条分隔线(owner 2026-07-15:子项行不再各自画线,只在区块标题上边);
   只作用于设置页,不影响 Pro 页「Your stats」等其它 sectlabel。首个区块贴 h1,不画。 */
.ba-settings-wrap .ba-sectlabel{ border-top:1px solid var(--hairsoft); padding-top:26px; color:var(--red); }
.ba-settings-wrap h1 + .ba-sectlabel{ border-top:none; padding-top:0; }
/* 设置页内容列压到 640px:标题↔控件视线距离减半,和 macOS 系统设置列宽同级(去 overload)。 */
.ba-settings-wrap{ max-width:640px; }
.ba-sectlabel:first-child{ margin-top:0; }

/* settings rows */
/* 子项之间不再画 divider(owner 2026-07-15:行行有线太乱);大区块的分隔由
   .ba-sectlabel 的上边线承担(首个区块贴着 h1,不画)。 */
.ba-setrow{ display:flex; align-items:center; gap:16px; padding:12px 0; }
.ba-setrow .sinfo{ flex:1; min-width:0; }
.ba-setrow .sname{ font-size:14px; font-weight:600; }
.ba-setrow .sdesc{ font-size:12.5px; color:var(--ink2); margin-top:3px; line-height:1.45; }
.ba-setrow .sctl{ flex:0 0 auto; }
/* 词典行:气泡区会长高,导入按钮钉在行首标题线上,不随行高垂直居中 */
.ba-dictrow{ align-items:flex-start; }
.ba-dictrow .sctl{ padding-top:2px; }

/* toggle switch */
.ba-toggle{ width:42px; height:25px; border-radius:13px; background:var(--field); box-shadow:0 0 0 1px var(--hair) inset; position:relative; cursor:pointer; transition:background .15s; }
.ba-toggle.is-on{ background:var(--red); box-shadow:none; }
.ba-toggle::after{ content:""; position:absolute; top:3px; left:3px; width:19px; height:19px; border-radius:50%; background:#fff; box-shadow:0 1px 3px rgba(0,0,0,.25); transition:left .15s; }
.ba-toggle.is-on::after{ left:20px; }

/* segmented control */
.ba-seg{ display:inline-flex; background:var(--field); border-radius:var(--rbtn); padding:3px; }
.ba-seg button{ border:0; background:transparent; font-family:var(--font); font-size:12.5px; font-weight:500; color:var(--ink2); padding:5px 15px; border-radius:var(--rbtn-in); cursor:pointer; }
.ba-seg button.is-on{ background:var(--panel); color:var(--ink); font-weight:600; }

/* select */
.ba-select{ font-family:var(--font); font-size:13px; color:var(--ink); background-color:var(--field); border:0; border-radius:var(--rbtn); padding:7px 30px 7px 14px; cursor:pointer; min-width:180px;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236f6e68' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>"); background-repeat:no-repeat; background-position:right 11px center; }

/* pro hero */
.ba-prohero{ background:var(--bg); border-radius:12px; box-shadow:0 0 0 1px var(--hair) inset; padding:26px 28px; display:flex; align-items:center; gap:24px; margin-bottom:24px; }
.ba-prohero .pleft{ flex:1; }
.ba-prohero .ptitle{ font-size:20px; font-weight:600; display:flex; align-items:center; gap:10px; }
.ba-prohero .ptitle .crown{ color:var(--red); display:flex; }
.ba-prohero .pdesc{ font-size:13.5px; color:var(--ink2); line-height:1.55; margin-top:8px; max-width:48ch; }
.ba-prohero .pprice{ text-align:right; }
.ba-prohero .pprice .amt{ font-family:var(--mono); font-size:32px; font-weight:700; color:var(--red); }
.ba-prohero .pprice .once{ font-family:var(--mono); font-size:11px; color:var(--ink3); text-transform:uppercase; letter-spacing:.1em; margin-top:2px; }
.ba-prohero .pprice .was{ font-family:var(--mono); font-size:12px; color:var(--ink3); text-decoration:line-through; margin-top:8px; }
/* Early Bird 早鸟(与官网 site-v4 一致):折扣率不划线;早鸟印章 brand 红 */
.ba-prohero .pprice .hs-off{ display:inline-block; text-decoration:none; color:var(--red); font-weight:700; margin-left:3px; }
.ba-prohero .pprice .hs-ebstamp{ display:inline-block; font-family:var(--mono); font-size:9.5px; font-weight:700; letter-spacing:.12em; text-transform:uppercase; color:var(--red); background:var(--redsoft); border:1px solid rgba(216,64,42,.32); border-radius:5px; padding:2px 6px; transform:rotate(-4deg); margin-bottom:7px; }
.ba-btn{ display:inline-flex; align-items:center; gap:8px; height:42px; padding:0 22px; border-radius:var(--rbtn); border:0; font-family:var(--font); font-size:14px; font-weight:600; cursor:pointer; }
/* 设置行里的按钮(Health Check Open… / Check for Updates… / Library folder Choose…/Open)
   压到与 .ba-select / .ba-seg 同一控件尺寸级(~28px),不再用 42px 大按钮突兀撑行。 */
.ba-setrow .ba-btn{ height:30px; padding:0 14px; border-radius:var(--rbtn); font-size:12.5px; font-weight:500; }

/* Settings ▸ Dictionary 词典气泡:标题/说明下方另起一行,从左排、满行自动折行(owner 定稿);
   常驻加号收尾。选中气泡右上角浮出 ×(溢出圆角外,wrap 顶部留内边距防裁切)。 */
.ba-dictwrap{ display:flex; flex-wrap:wrap; gap:9px; justify-content:flex-start; align-items:center;
  margin-top:12px; padding-top:4px; }
.ba-dictchip{ position:relative; font-size:12.5px; font-weight:500; color:var(--ink); background:var(--field);
  border-radius:999px; padding:5px 13px; cursor:default;
  user-select:none; -webkit-user-select:none; }
.ba-dictchip.is-sel{ box-shadow:0 0 0 1.5px var(--red) inset; }
.ba-dictx{ position:absolute; top:-7px; right:-7px; width:17px; height:17px; border-radius:50%;
  background:var(--ink); color:var(--panel); font-size:12px; line-height:16px; text-align:center;
  cursor:pointer; box-shadow:0 1px 3px rgba(0,0,0,.25); }
.ba-dictadd{ width:27px; height:27px; border-radius:50%; border:1px dashed var(--ink3, var(--ink2));
  background:none; color:var(--ink2); font-size:15px; line-height:1; cursor:pointer; padding:0; }
.ba-dictadd:hover{ color:var(--ink); border-color:var(--ink); }
.ba-dictinput{ width:178px; height:27px; border-radius:999px; border:1px solid transparent;   /* 132→178:放得下「添加人名等专有名词」等长 placeholder */
  background:var(--panel); color:var(--ink); font-size:12.5px; padding:0 12px; outline:none; }
.ba-dictinput:focus{ border-color:var(--red); }

/* 词典弹窗(加入词典?/替换):X → Y 双输入 + 可选「同时加入词典」勾选 */
.ba-dictpair{ display:flex; align-items:center; gap:10px; padding:18px 22px 4px; }
.ba-dictinput.wide{ flex:1; min-width:0; height:34px; font-size:14px; border-radius:9px; text-align:center; }
.ba-dictarrow{ color:var(--ink2); font-weight:600; flex:0 0 auto; }
.ba-dictalso{ display:flex; align-items:center; gap:7px; padding:10px 22px 0; font-size:12.5px; color:var(--ink2); cursor:pointer; user-select:none; -webkit-user-select:none; }
.ba-dictalso input{ accent-color:var(--red); }

.ba-btn.primary{ background:var(--red); color:#fff; }
.ba-btn.ghost{ background:var(--field); color:var(--ink); }
.ba-btn.primary:active,.ba-btn.ghost:active{ filter:brightness(.95); }

/* 会员之家 · Invite 引导卡:品牌红小卡(hero 同款红,横排:图标+文案 左 / 白 CTA 右)。
   过去是 var(--bg) 灰盒 → 与上方精致成就区脱节;现为有质感的邀请入口。 */
.hs-inv-entry{ position:relative; overflow:hidden; cursor:pointer;   /* 整卡可点 → Invite(作者 2026-07-16) */
  transition:background-color .16s ease;
  display:flex; align-items:center; gap:16px; margin:clamp(28px, 6.5vh, 72px) 0 24px;   /* 与上方统计区拉开:大窗保持 72px(owner 2026-07-16 拍板),矮窗随视口收缩防止整卡被挤出视口(owner 2026-07-20) */
  border-radius:28px; padding:18px 20px; color:var(--ink);
  background:var(--bg); }   /* 降噪(owner 2026-07-16:广告不该比用户成就醒目):统计卡同款灰底,红只做点缀 */
/* 续期提醒条(2026-08-09):仅到期前 30 天显示。简洁一行:说明 + 续期按钮,整条可点;灰底红字。 */
.hs-renew-bar{ display:flex; align-items:center; gap:14px; cursor:pointer;
  margin:clamp(20px,4vh,32px) 0 4px; padding:14px 18px; border-radius:20px; color:var(--ink);
  background:var(--bg); border:1px solid rgba(216,64,42,.25); transition:background-color .16s ease; }
.hs-renew-bar:hover{ background:rgba(216,64,42,.07); }
.hs-renew-bar .hs-renew-txt{ flex:1; font-weight:600; }
.hs-renew-bar .hs-renew-btn{ flex:0 0 auto; font-weight:700; color:var(--red); white-space:nowrap; }
/* 图标/CTA 裸放:淡红底被否(同事 2026-07-16「slop」),灰卡上只留红符号+红字;
   2026-07-16 owner 再定稿:大符号 + 大标题「Share HoldSay」+ 第二行说明 */
.hs-inv-entry .ie-ic{ flex:0 0 56px; width:56px; height:56px; display:flex; align-items:center; justify-content:center;
  color:var(--red); }
.hs-inv-entry .ie-ic svg{ width:40px; height:40px; }
.hs-inv-entry .ie-tx{ min-width:0; flex:1; }
.hs-inv-entry .ie-t{ font-size:21px; font-weight:700; letter-spacing:-.015em; color:var(--ink); }
.hs-inv-entry .ie-sub{ font-size:13.5px; font-weight:700; color:var(--ink2); margin-top:5px; }
.hs-inv-entry .ie-cta{ flex:0 0 auto; display:inline-flex; align-items:center; height:40px; padding:0 20px; font-size:13.5px; font-weight:700;
  color:var(--red); }
/* 整卡可点:hover 卡面微深 */
.hs-inv-entry:hover{ background:var(--field); }
/* 邀请页返回按钮(作者 2026-07-16) */
.hs-inv-back{ display:inline-flex; align-items:center; gap:5px; margin:2px 0 4px; padding:6px 12px 6px 8px;
  border:0; border-radius:9px; background:transparent; color:var(--ink2); font:inherit; font-size:13.5px; font-weight:700; cursor:pointer; }
.hs-inv-back svg{ width:17px; height:17px; }
.hs-inv-back:hover{ background:var(--field); color:var(--ink); }

/* achievements */

.ba-achieve{ display:grid; grid-template-columns:repeat(auto-fill, minmax(150px,1fr)); gap:14px; }
.ba-ach{ background:var(--bg); border-radius:10px; box-shadow:0 0 0 1px var(--hair) inset; padding:18px; }
.ba-ach .an{ font-family:var(--mono); font-size:26px; font-weight:700; color:var(--ink); }
.ba-ach .al{ font-family:var(--mono); font-size:10px; color:var(--ink3); text-transform:uppercase; letter-spacing:.1em; margin-top:6px; }

/* Achievements:左半年听写热力图卡 + 右 2×2 dictation 指标卡(参考 Wispr 样式)*/
/* Equal-height cards: both stretch to the row's tallest, and BOTH fill it — the grid
   rows grow (grid-auto-rows:1fr, cards already center their content) and the heatmap
   is vertically centered (.ba-heat-scroll flex:1 + centered) with its legend pinned to
   the bottom. So neither side shows dead space regardless of which is naturally taller. */
/* 热力图卡与指标卡强制左右排列。付费前后共用 memberStatsHTML,因此这里必须保持
   nowrap:空间不足时由两列的 flex-shrink + min-width:0 收窄,热力图格子随之等比缩小,
   不能再回退成未付费页上下、已付费页左右的两套观感。 */
.ba-stats{ display:flex; gap:14px; align-items:stretch; flex-wrap:nowrap; }
/* 统计模块卡:去灰描边、大圆角(owner 2026-07-16:外框土、圆角要大幅加大) */
.ba-statcard{ background:var(--bg); border-radius:24px; padding:18px; }
/* 热力图裸放:去灰底卡(owner 2026-07-16「背景土」),格子自身的浅灰填充即是形 */
.ba-stats-heat{ flex:1 1 300px; min-width:0; display:flex; flex-direction:column; background:transparent; padding:0; }
/* basis 360 配合左列 300 定出宽窗比例;窄窗由两列共同 shrink,不换行。
   minmax(0,1fr) + min-width:0 = 数值卡永不撑破容器(166.2K 这类宽值曾把面板顶出横向滚动)。 */
.ba-stats-grid{ flex:1.18 1 360px; min-width:0; display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); grid-auto-rows:1fr; gap:14px; }
.ba-stat{ min-width:0; }
.ba-stat{ background:var(--bg); border-radius:24px;
  /* 图标尺寸/间距随卡宽收缩(owner 2026-07-20:小屏上写死的 padding 把文字推出卡外) */
  --st-ic:clamp(20px, 15cqw, 30px); --st-gap:clamp(6px, 5cqw, 10px);
  padding:16px clamp(10px, 9cqw, 18px); display:flex; flex-direction:column; gap:9px; justify-content:center; }
.ba-stat-top{ display:flex; align-items:center; gap:var(--st-gap); }
/* 图标裸放(去圆角矩形底色)且加大(owner 2026-07-16) */
.ba-stat-ic{ width:var(--st-ic); height:var(--st-ic); flex:0 0 var(--st-ic);
  color:var(--ink2); display:flex; align-items:center; justify-content:center; }
.ba-stat-ic svg{ width:77%; height:77%; }
/* 数字字号随卡片宽度自适应(container query;owner 2026-07-20:换显示器/窄窗
   固定 24px 会溢出边框 —— Roboto Mono 落地后「13 hr 15 min」在窄卡爆版)。
   大卡维持原 24px/13.5px 上限,窄卡线性收缩,永不出框。 */
.ba-stat{ container-type:inline-size; }
.ba-stat-val{ font-family:var(--font); font-size:clamp(10px,6.8cqw,13.5px); font-weight:700; color:var(--ink2); white-space:nowrap; min-width:0; }   /* 单位小字加粗;灰统一 ink2;卡片文字保持 sans,数字才 mono(owner 2026-07-16 撤回) */
.ba-stat-val b{ font-family:var(--mono); font-size:clamp(15px,12cqw,24px); font-weight:700; color:var(--ink); font-variant-numeric:tabular-nums; }
.ba-stat-lab{ font-family:var(--font); font-size:13.5px; font-weight:700; color:var(--ink2); margin-left:calc(var(--st-ic) + var(--st-gap)); }   /* icon 占位+gap:与数字左对齐(随卡宽自适应);文字保持 sans(owner 2026-07-16 撤回) */
.ba-heat-title{ font-size:13.5px; font-weight:700; color:var(--ink2); margin-bottom:12px; }

/* 听写热力图格子(2026-07-15 owner:收到 2 个月/9 列)。列定宽 ≤36px 并居中,
   9 列不再拉满整宽把整图撑高;窄容器时能缩(flex:0 1)。格子 aspect-ratio:1 保持正方。 */
.ba-heat-scroll{ overflow:hidden; flex:1; display:flex; flex-direction:column; justify-content:center; }
.ba-heat-months{ display:flex; gap:4px; margin-bottom:5px; justify-content:center; }
.ba-heat-months .hmon{ flex:0 1 30px; min-width:0; font-size:13.5px; font-weight:700; line-height:1; color:var(--ink2); white-space:nowrap; overflow:visible; }
/* 色阶 = 品牌正红 #d8402a 的透明度阶梯 —— 同一色相只变浓度,禁手调降饱和的"水洗红"。 */
.ba-heat-body{ display:flex; gap:4px; justify-content:center; }
.hcol{ display:flex; flex-direction:column; gap:4px; flex:0 1 30px; min-width:0; }
.hc{ width:100%; aspect-ratio:1; border-radius:28%; }   /* 大圆角随格径缩放,和 App 圆角语言一致(作者钦定) */
.hc-empty{ background:transparent; }
.hc-l0{ background:var(--field); }   /* 零活动格 = 浅灰填充,不再描边(owner 2026-07-16) */
.hc-l1{ background:rgba(216,64,42,.32); }
.hc-l2{ background:rgba(216,64,42,.56); }
.hc-l3{ background:rgba(216,64,42,.78); }
.hc-l4{ background:#d8402a; }
.ba.is-dark .hc-l0{ background:var(--chip); }
.ba.is-dark .hc-l1{ background:rgba(216,64,42,.38); }
.ba.is-dark .hc-l2{ background:rgba(216,64,42,.6); }
.ba.is-dark .hc-l3{ background:rgba(216,64,42,.8); }
.ba.is-dark .hc-l4{ background:#d8402a; }
.ba-heat-foot{ display:flex; justify-content:space-between; align-items:center; gap:14px; flex-wrap:wrap; margin-top:10px; }
/* 图例/日均:提到与统计卡副标题同级(13.5px+加粗)——页面里不再有又细又小的字(owner 2026-07-16) */
.ba-heat-legend{ display:flex; align-items:center; gap:4px; font-size:13.5px; font-weight:700; color:var(--ink2); }
.ba-heat-legend span:first-child{ margin-right:5px; }  /* Less 与色块拉开(作者 2026-07-16) */
.ba-heat-legend span:last-child{ margin-left:5px; }    /* More 与色块拉开(作者 2026-07-16) */
.ba-heat-legend i{ width:12px; height:12px; border-radius:3px; display:inline-block; }
.ba-heat-avg{ font-size:13.5px; font-weight:700; color:var(--ink2); white-space:nowrap; }
.ba-heat-sub{ font-size:13.5px; font-weight:700; color:var(--ink2); }

/* App 最窄允许到 820px(右面板扣掉 404px 侧栏后很窄)。仍保持「热力图左、统计右」,
   只把右侧卡片收成单列并缩紧图例;否则 2 列卡片会窄到文字产生横向溢出。 */
@media (max-width:900px){
  .ba-stats-grid{ grid-template-columns:minmax(0,1fr); }
  .ba-stat{ padding:12px 14px; gap:6px; }
  .ba-heat-months .hmon{ font-size:11px; }
  .ba-heat-foot{ gap:8px; }
  .ba-heat-legend{ gap:2px; font-size:11px; }
  .ba-heat-legend span:first-child{ margin-right:2px; }
  .ba-heat-legend span:last-child{ margin-left:2px; }
  .ba-heat-legend i{ width:8px; height:8px; border-radius:2px; }
  .ba-heat-avg{ font-size:11px; white-space:normal; line-height:1.25; }
}

/* entrance fade for view switches */
.ba-fade{ animation:bafade .26s ease both; }
@keyframes bafade{ from{ opacity:0; transform:translateY(4px); } to{ opacity:1; transform:none; } }
/* 纯透明度淡入,零位移 —— 用于编辑↔查看过渡(作者不喜欢任何上下移动)。 */
.ba-fadeio{ animation:hsFadeIO .22s ease both; }
@keyframes hsFadeIO{ from{ opacity:0; } to{ opacity:1; } }

/* ============================================================
   FLOATING WIDGET v2 — Braun · compact · ALLOY GRILLE (bw3-*)
   Ported from HoldSay-AlloyTight design (clean · tight). Light
   (brushed alloy) + dark (anodised graphite). Self-contained.
   ============================================================ */
.bw3{
  position:relative; width:316px; height:207px; display:flex;
  border-radius:5px 36px 36px 5px;
  /* 右侧两角用 Apple 连续圆角(squircle / superellipse),更大更平滑;左侧小角保持普通圆角 */
  /* corner-shape squircle 移除:Chromium(Electron Chromium139+)渲染偏方、Safari 不支持忽略 → 跨端不一致;统一走 border-radius 圆角 */
  background:linear-gradient(180deg,#efece6 0%,#e4e0d7 100%);
  color:#2c2c2e; font-family:var(--font);
  box-shadow:
    0 1px 0 rgba(255,255,255,.95) inset,
    0 -1px 2px rgba(0,0,0,.05) inset,
    0 0 0 1px rgba(0,0,0,.13),
    /* 外投影:分层柔和、在 #wrap 留白内自然淡到 0(避免被窗口 overflow:hidden 硬裁出截断线) */
    0 2px 5px -1px rgba(40,40,45,.16),
    0 10px 20px -8px rgba(40,40,45,.34);
}
.bw3-grain::after{
  content:""; position:absolute; inset:0; border-radius:inherit; pointer-events:none; z-index:3;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity:.035; mix-blend-mode:multiply;
}

/* matte ABS rail — single record key (kept matte, contrasts the alloy) */
.bw3-rail{
  position:relative; z-index:2;
  flex:0 0 100px; display:flex; flex-direction:column; align-items:center; justify-content:center;
  padding:15px 0;
  border-right:1px solid rgba(0,0,0,.16);
  box-shadow:1px 0 0 rgba(255,255,255,.7);
}
.bw3-keywrap{ position:relative; display:flex; flex-direction:column; align-items:center; }
/* "REC" is absolutely positioned below the knob so it doesn't shift the knob:
   the keywrap's only in-flow child is the knob, so centering the keywrap in the
   rail centers the knob — i.e. the red dot sits on the rail's vertical midline. */
.bw3-legend{ position:absolute; top:100%; left:50%; transform:translateX(-50%); margin-top:11px; white-space:nowrap; font-family:var(--mono); font-size:8px; font-weight:700; letter-spacing:.17em; color:#908d85; }

.bw3-rec{
  cursor:pointer;
  position:relative; width:51px; height:51px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  background:radial-gradient(circle at 50% 36%, #fcfbf8, #e7e3db 70%, #d6d2c8);
  box-shadow:
    0 1px 0 rgba(255,255,255,.95) inset,
    0 -2px 3px rgba(0,0,0,.10) inset,
    0 0 0 1px rgba(0,0,0,.13),
    0 3px 5px rgba(0,0,0,.16);
}
.bw3-rec::after{
  content:""; width:13px; height:13px; border-radius:50%;
  background:radial-gradient(circle at 38% 32%, #ff6e51, #e8402a 58%, #c5301c);
  box-shadow:0 0 0 1px rgba(150,30,15,.28), 0 1px 1px rgba(0,0,0,.22);
}
/* REC 旋钮外圈的 Braun 刻度点环:等角度均匀分布的同样大小圆点(SVG 精确摆位,
   见 widget.html 的 micRing());不再用方格平铺底纹裁切,避免散乱/半点/大小不一。 */
.bw3-mic{
  position:absolute; top:-8px; left:50%; transform:translateX(-50%);
  width:67px; height:67px; pointer-events:none; overflow:visible;
}
.bw3-mic circle{ fill:rgba(0,0,0,.26); }
/* 内录指示:录音面 ● Recording 标签右侧的小耳机 emoji — 仅在录系统声音时出现
   (widget.html bodyRecording() 在 st.sysAudio 时渲染)。状态信息归状态行,
   rail(控制区)保持克制。 */
.bw3-srclabel{ margin-left:7px; font-size:12px; line-height:1; vertical-align:-1px; }
.bw3-rec.is-live{
  background:radial-gradient(circle at 50% 36%, #ff8068, #e8402a 56%, #c5301c);
  box-shadow:
    0 1px 0 rgba(255,255,255,.4) inset,
    0 0 0 1px rgba(150,30,15,.4),
    0 0 14px rgba(232,64,42,.4),
    0 3px 6px rgba(0,0,0,.2);
}
.bw3-rec.is-live::after{ width:14px; height:14px; background:#fff; box-shadow:0 0 7px rgba(255,255,255,.75); }
/* Transcribing → no new recording can start: dim the whole key (knob + ring +
   legend) and make it pointer-transparent so it reads as disabled and clicks
   fall through to dragging. The engine guards the action too. */
.bw3-keywrap.is-busy{ opacity:.4; pointer-events:none; }

/* ---- the machined aluminium faceplate (right of the seam) ---- */
.bw3-face{
  position:relative; z-index:1; flex:1; min-width:0;
  border-radius:0 36px 36px 0;
  /* corner-shape squircle 移除:Chromium(Electron Chromium139+)渲染偏方、Safari 不支持忽略 → 跨端不一致;统一走 border-radius 圆角 */
  /* layered: diagonal anodised sheen · fine horizontal ridges · base metal */
  background:
    linear-gradient(108deg, rgba(255,255,255,.42) 0%, rgba(255,255,255,0) 26%, rgba(255,255,255,.22) 50%, rgba(255,255,255,0) 74%, rgba(255,255,255,.32) 100%),
    repeating-linear-gradient(180deg,
      rgba(255,255,255,.40) 0px,
      rgba(255,255,255,0) 5px,
      rgba(70,64,52,.075) 10px,
      rgba(255,255,255,0) 15px,
      rgba(255,255,255,.40) 20px),
    linear-gradient(180deg, #efeeea 0%, #dbd9d3 46%, #d2d0ca 60%, #e7e5e0 100%);
  box-shadow:
    inset 1px 0 0 rgba(255,255,255,.6),
    inset 2px 0 4px rgba(0,0,0,.10),
    inset 0 1px 0 rgba(255,255,255,.55),
    inset 0 -1px 2px rgba(0,0,0,.10);
}
/* soft top-corner glint so the ripples read as anodised metal */
.bw3-face::before{
  content:""; position:absolute; inset:0; border-radius:inherit; pointer-events:none;
  background:radial-gradient(120% 80% at 78% -10%, rgba(255,255,255,.5), rgba(255,255,255,0) 55%);
}

/* idle body content sits on the alloy */
.bw3-body{ position:relative; z-index:1; padding:13px 20px; height:100%; box-sizing:border-box; display:flex; flex-direction:column; justify-content:center; }
.bw3-slogan{ display:flex; align-items:center; margin-bottom:10px; overflow:hidden; }
.bw3-slogan-txt{ font-size:12px; font-weight:600; color:#33363b; letter-spacing:.005em; text-shadow:0 1px 0 rgba(255,255,255,.5); white-space:nowrap; }
.bw3-slogan-txt b{ font-weight:700; color:#16181b; }

.bw3-list{ display:flex; flex-direction:column; gap:7px; }
.bw3-item{ display:flex; align-items:center; gap:10px; }
.bw3-disc{
  position:relative; flex:0 0 auto; width:26px; height:26px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  /* 与左侧 REC 旋钮同款暖色机加工金属(原来的冷灰蓝 #c9ccd2 与卡片暖调不搭) */
  background:radial-gradient(circle at 50% 36%, #fcfbf8, #e7e3db 70%, #d6d2c8);
  box-shadow:
    0 1px 0 rgba(255,255,255,.9) inset,
    0 -1px 2px rgba(0,0,0,.08) inset,
    0 0 0 1px rgba(0,0,0,.13),
    0 1px 2px rgba(0,0,0,.16);
}
.bw3-disc svg{ width:12px; height:12px; color:#3a3a3c; margin-left:1px; }
.bw3-dur{ font-family:var(--mono); font-size:12px; font-weight:600; color:#52555b; font-variant-numeric:tabular-nums; flex:0 0 auto; text-shadow:0 1px 0 rgba(255,255,255,.4); }
.bw3-prev{ font-size:13px; color:#6c6f75; overflow:hidden; white-space:nowrap; text-overflow:ellipsis; flex:1; min-width:0; text-shadow:0 1px 0 rgba(255,255,255,.35); }

/* recording layout on alloy */
.bw3-recmode{ position:relative; z-index:1; padding:17px 22px; height:100%; box-sizing:border-box; display:flex; flex-direction:column; justify-content:center; }
/* 录音中/转写中/暂停 状态标签:字体·字号·字重·letter-spacing 对齐待机 slogan
   (.bw3-slogan-txt = sans var(--font) / 12px / 600 / .005em,作者 2026-07-25 钦定),
   字号从 9px 放大到 12px。位置见下方 .is-tight 规则:仍保持卡片顶部原位 top:16px
   (作者 2026-07-25:曾试过对齐 slogan 的 30px,看着偏低,已还原)。颜色保留
   (录音红 / 转写黑 = 状态信号,不属于「字体字号」)。 */
.bw3-reclabel{ display:flex; align-items:center; gap:6px; font-size:12px; font-weight:600; letter-spacing:.005em; color:#c0341e; }
.bw3-reclabel .dot{ width:7px; height:7px; border-radius:50%; background:#e8402a; box-shadow:0 0 6px rgba(232,64,42,.5); }
.bw3-timer{ font-family:var(--mono); font-size:64px; font-weight:700; letter-spacing:.01em; font-variant-numeric:tabular-nums; color:#26282c; line-height:.95; margin:auto 0; text-shadow:0 1px 0 rgba(255,255,255,.5); }
/* Tap-to-pause hit box — ONLY the digits, so dragging the card elsewhere never
   pauses. cursor:pointer is a fallback when the panel is key; the hand cursor in
   the (usual) background case is driven natively over this exact rect. */
.bw3-time-hit{ display:inline-block; cursor:pointer; }
/* paused freezes + greys the timer and stops the red dot. */
.bw3-recmode.is-paused .bw3-timer{ color:#9a9892; text-shadow:none; transition:color .15s ease; }
.bw3-recmode.is-paused .bw3-reclabel{ color:#9a9892; }
.bw3-pauseglyph{ font-size:9px; letter-spacing:0; margin-right:1px; }
.bw3.is-dark .bw3-recmode.is-paused .bw3-timer,
.bw3.is-dark .bw3-recmode.is-paused .bw3-reclabel{ color:#8b8d92; }
.bw3-recprev{ display:flex; align-items:center; gap:9px; padding:8px 11px; border-radius:9px;
  background:transparent; box-shadow:none; }
.bw3-recprev .bw3-dur{ font-size:10px; }
/* 转写收尾中的行:时长右侧小转圈 —— 空白会读作「转写失败」(owner 2026-07-20)。
   busy 由 native 快照点亮(Mac liveTxStatus / Windows files.liveTx),完成即换回预览文字。 */
.bw3-rowspin{ display:inline-block; width:10px; height:10px; border-radius:50%;
  border:1.6px solid rgba(128,124,116,.30); border-top-color:#6a6862;
  animation:bwRowSpin .8s linear infinite; vertical-align:-1px; }
.bw3.is-dark .bw3-rowspin{ border-color:rgba(255,255,255,.18); border-top-color:#b2b3ba; }
@keyframes bwRowSpin{ to{ transform:rotate(360deg); } }
.bw3-recprev .bw3-prev{ font-size:11px; }

/* ---- transcription progress (on-card, replaces the old top-right popup) ---- */
/* Reuses the recording face verbatim (.bw3-recmode + .bw3-reclabel + .bw3-timer)
   so the label slot and the big figure share Recording's exact position, font
   and size. Only the differences live here: the label is black (not red) and
   the live dot becomes a small spinner. */
.bw3-txlabel{ color:#26282c; }
.bw3-txspin{ display:inline-block; box-sizing:border-box; width:7px; height:7px;
  border:1.5px solid rgba(38,40,44,.25); border-top-color:#26282c; border-radius:50%;
  animation:baspin .7s linear infinite; }
/* The figure is centred HORIZONTALLY in the right panel (not left-aligned like
   the timer) and keeps the timer's -11px vertical lift so it clears the recent
   preview pill below it — identical font/size/height to Recording's timer (both
   52px in the tight skin), just centred. */
.bw3.is-tight .bw3-timer.bw3-txfig{ justify-content:center; padding-left:0; padding-right:0; }
/* "Preparing" state, before the chunk count is known: three clean round dots
   (a gentle staggered pulse), not the cramped ellipsis glyph. Unlike the count,
   the lone trio is centred horizontally in the face. */
.bw3.is-tight .bw3-timer.bw3-txfig-prep{ justify-content:center; padding-left:0; padding-right:0; }
.bw3-txdots{ display:inline-flex; align-items:center; gap:9px; }
.bw3-txdots i{ display:block; width:11px; height:11px; border-radius:50%; background:#26282c;
  animation:bwpulse 1.1s ease-in-out infinite; }
.bw3-txdots i:nth-child(2){ animation-delay:.18s; }
.bw3-txdots i:nth-child(3){ animation-delay:.36s; }

/* ---- drag-to-transcribe hint (covers the right-half faceplate while a media
   file hovers over the card) ---- */
/* The rail is 100px wide, so the faceplate begins at x=100; the overlay covers
   exactly the alloy face and mirrors its right-corner squircle. Visual only —
   pointer-events:none so it never intercepts the native file drop. */
.bw3-drop{
  position:absolute; z-index:4; top:0; bottom:0; left:100px; right:0;
  pointer-events:none; box-sizing:border-box; padding:12px 13px;
  /* lives permanently in the scaffold now → hidden until a media file hovers */
  display:none; align-items:center; justify-content:center;
  border-radius:0 36px 36px 0;
  /* corner-shape squircle 移除:Chromium(Electron Chromium139+)渲染偏方、Safari 不支持忽略 → 跨端不一致;统一走 border-radius 圆角 */
  background:rgba(244,242,237,.95);
  -webkit-backdrop-filter:blur(3px); backdrop-filter:blur(3px);
  box-shadow:inset 2px 0 4px rgba(0,0,0,.08);
  animation:bwdropin .14s ease-out;
}
.bw3.is-dropping .bw3-drop{ display:flex; }
.bw3.is-min .bw3-drop{ display:none; }   /* drop-to-transcribe is a big-card affordance */
.bw3-drop-inner{
  width:100%; height:100%; box-sizing:border-box;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:8px;
  border:1.5px dashed rgba(192,52,30,.55); border-radius:14px;
}
.bw3-drop-ico{ width:26px; height:26px; color:#c0341e; }
.bw3-drop-txt{ font-size:12px; font-weight:700; letter-spacing:.01em; color:#26282c;
  text-shadow:0 1px 0 rgba(255,255,255,.5); }
@keyframes bwdropin{ from{ opacity:0; transform:scale(.97); } to{ opacity:1; transform:scale(1); } }

/* ---- matte graphite + anodised graphite alloy ---- */
.bw3.is-dark{
  background:linear-gradient(180deg,#3a3a40,#2a2a2f); color:#e8e8ea;
  box-shadow:
    0 1px 0 rgba(255,255,255,.10) inset,
    0 -1px 3px rgba(0,0,0,.4) inset,
    0 0 0 1px rgba(0,0,0,.55),
    /* 外投影:分层柔和、在留白内自然淡到 0,避免硬裁 */
    0 2px 5px -1px rgba(0,0,0,.32),
    0 10px 20px -8px rgba(0,0,0,.5);
}
.bw3.is-dark .bw3-rail{ border-right-color:rgba(0,0,0,.5); box-shadow:1px 0 0 rgba(255,255,255,.05); }
.bw3.is-dark .bw3-legend{ color:#8b8b93; }
.bw3.is-dark .bw3-drop{ background:rgba(32,32,36,.93); box-shadow:inset 2px 0 4px rgba(0,0,0,.4); }
.bw3.is-dark .bw3-drop-inner{ border-color:rgba(255,120,100,.5); }
.bw3.is-dark .bw3-drop-ico{ color:#ff7a64; }
.bw3.is-dark .bw3-drop-txt{ color:#f0f0f2; text-shadow:0 1px 1px rgba(0,0,0,.4); }
.bw3.is-dark .bw3-rec{
  background:radial-gradient(circle at 50% 36%,#4c4c54,#2c2c31 72%);
  box-shadow:0 1px 0 rgba(255,255,255,.12) inset,0 -2px 4px rgba(0,0,0,.5) inset,0 0 0 1px rgba(0,0,0,.5),0 3px 6px rgba(0,0,0,.4);
}
.bw3.is-dark .bw3-mic circle{ fill:rgba(255,255,255,.18); }
.bw3.is-dark .bw3-rec.is-live{
  background:radial-gradient(circle at 50% 36%, #ff8068, #e8402a 56%, #c5301c);
  box-shadow:0 1px 0 rgba(255,255,255,.4) inset,0 0 0 1px rgba(150,30,15,.4),0 0 16px rgba(232,64,42,.45),0 3px 7px rgba(0,0,0,.4);
}
.bw3.is-dark .bw3-face{
  background:
    linear-gradient(108deg, rgba(255,255,255,.15) 0%, rgba(255,255,255,0) 26%, rgba(255,255,255,.08) 50%, rgba(255,255,255,0) 74%, rgba(255,255,255,.12) 100%),
    repeating-linear-gradient(180deg,
      rgba(255,255,255,.11) 0px,
      rgba(255,255,255,0) 5px,
      rgba(0,0,0,.30) 10px,
      rgba(255,255,255,0) 15px,
      rgba(255,255,255,.11) 20px),
    linear-gradient(180deg, #43423e 0%, #312f2c 46%, #2b2a27 60%, #3a3935 100%);
  box-shadow:
    inset 1px 0 0 rgba(255,255,255,.10),
    inset 2px 0 4px rgba(0,0,0,.4),
    inset 0 1px 0 rgba(255,255,255,.10),
    inset 0 -1px 2px rgba(0,0,0,.4);
}
.bw3.is-dark .bw3-face::before{ background:radial-gradient(120% 80% at 78% -10%, rgba(255,255,255,.18), rgba(255,255,255,0) 55%); }
.bw3.is-dark .bw3-slogan-txt{ color:#dcdde1; text-shadow:0 1px 1px rgba(0,0,0,.5); }
.bw3.is-dark .bw3-slogan-txt b{ color:#fff; }
.bw3.is-dark .bw3-disc{
  background:radial-gradient(circle at 50% 34%,#54565d,#26282c 78%);
  box-shadow:0 0 0 1px rgba(0,0,0,.55),0 1px 2px rgba(0,0,0,.45),0 1px 0 rgba(255,255,255,.08) inset;
}
.bw3.is-dark .bw3-disc svg{ color:#cfcfd6; }
.bw3.is-dark .bw3-dur{ color:#b2b3ba; text-shadow:0 1px 1px rgba(0,0,0,.5); }
.bw3.is-dark .bw3-prev{ color:#9a9ca2; text-shadow:0 1px 1px rgba(0,0,0,.45); }
.bw3.is-dark .bw3-timer{ color:#f0f1f3; text-shadow:0 1px 2px rgba(0,0,0,.55); }
.bw3.is-dark .bw3-reclabel{ color:#ff6a4f; }
.bw3.is-dark .bw3-recprev{ background:transparent; box-shadow:none; }
.bw3.is-dark .bw3-txlabel{ color:#f0f1f3; }
.bw3.is-dark .bw3-txspin{ border-color:rgba(240,241,243,.25); border-top-color:#f0f1f3; }
.bw3.is-dark .bw3-txdots i{ background:#f0f1f3; }
.bw3.is-dark .bw3-grain::after{ mix-blend-mode:overlay; opacity:.05; }

/* clean + tight + rec-header modifiers */
/* ============================================================
   BRAUN — COMPACT · ALLOY  ·  "clean dark" modifier (bw3.is-clean)
   ADD-ON ONLY. Targets .bw3.is-clean.is-dark — existing .bw3
   designs never carry .is-clean, so nothing else changes.
   Fixes the dark faceplate: neutral graphite (no green/olive
   cast), no diagonal sheen + no radial hot-spot (kills the
   over-reflection), gentler flutes (less dirty / muddy).
   ============================================================ */
.bw3.is-clean.is-dark .bw3-face{
  background:
    /* 单侧金属格栅:淡白棱脊高光(顶边硬切)→ 硬边跳到纯黑阴影 → 阴影只向下衰减。周期 30px → 约 6 条格栅。 */
    repeating-linear-gradient(180deg,
      rgba(255,255,255,.10) 0px,       /* 淡白棱脊高光 */
      rgba(255,255,255,.10) 2px,       /* 很细的高光带 */
      rgba(0,0,0,.34) 2px,             /* 硬边:高光直接跳变到纯黑阴影 */
      rgba(0,0,0,0) 12px,              /* 阴影只往下衰减回透明 */
      rgba(0,0,0,0) 30px),             /* 平的金属本色 */
    /* clean neutral graphite — no warm/olive tint */
    linear-gradient(180deg, #3a3a3c 0%, #2f2f31 50%, #363638 100%);
  box-shadow:
    inset 1px 0 0 rgba(255,255,255,.06),
    inset 2px 0 4px rgba(0,0,0,.32),
    inset 0 1px 0 rgba(255,255,255,.06),
    inset 0 -1px 2px rgba(0,0,0,.28);
}
/* remove the bright reflection hot-spot entirely */
.bw3.is-clean.is-dark .bw3-face::before{ background:none; }

/* tone the surface noise down so it doesn't read as grime */
.bw3.is-clean.is-dark .bw3-grain::after{ opacity:.03; }

/* keep text crisp on the cleaner neutral metal */
.bw3.is-clean.is-dark .bw3-slogan-txt{ color:#e3e4e7; text-shadow:0 1px 1px rgba(0,0,0,.45); }
.bw3.is-clean.is-dark .bw3-dur{ color:#bdbec3; }
.bw3.is-clean.is-dark .bw3-prev{ color:#9b9ca1; }
.bw3.is-clean.is-dark .bw3-timer{ color:#f1f1f3; text-shadow:0 1px 2px rgba(0,0,0,.5); }

/* ---- "clean light" — same gentle, low-reflection treatment ---- */
/* 左区(REC 哑光槽,显示的是容器底色)调浅一些 */
.bw3.is-clean:not(.is-dark){
  background:linear-gradient(180deg,#faf9f7 0%,#f1f0ec 100%);
}
.bw3.is-clean:not(.is-dark) .bw3-face{
  background:
    /* 单侧金属格栅:细高光棱脊(顶边硬切、上方无模糊)→ 硬边跳到偏暖深色阴影 → 阴影只向下衰减回金属本色。周期 30px → 约 6 条格栅。 */
    repeating-linear-gradient(180deg,
      rgba(255,255,255,.55) 0px,       /* 棱脊高光(被光打到的亮线) */
      rgba(255,255,255,.55) 2px,       /* 很细的高光带 */
      rgba(45,42,36,.085) 2px,         /* 硬边:高光直接跳变到阴影(更浅,不那么生硬) */
      rgba(45,42,36,0) 20px,           /* 阴影范围更广,向下更柔和地衰减回金属本色 */
      rgba(45,42,36,0) 30px),          /* 剩下是平的金属本色,保住线间距 */
    linear-gradient(180deg, #fdfcf9 0%, #fbfaf6 100%);   /* 底色:近白 + 一丁点米色,纯白太生硬 */
  box-shadow:
    inset 1px 0 0 rgba(255,255,255,.55),
    inset 2px 0 4px rgba(0,0,0,.08),
    inset 0 1px 0 rgba(255,255,255,.5),
    inset 0 -1px 2px rgba(0,0,0,.07);
}
.bw3.is-clean:not(.is-dark) .bw3-face::before{ background:none; }
.bw3.is-clean:not(.is-dark) .bw3-grain::after{ opacity:.03; }

/* "rec header" variant — red Recording label pinned top-left,
   the two notes truly centred in the full faceplate height */
.bw3-body-rec{ justify-content:center; }
.bw3-body-rec .bw3-reclabel{ position:absolute; top:14px; left:20px; }
/* same mono/letter-spaced label style, but the real copy in black */
.bw3-headlabel{ color:#1d1d1f; }
.bw3.is-dark .bw3-headlabel{ color:#f0f0f2; }

/* "tight" — same 1.52:1 ratio & same inner element sizes, but less
   top/bottom + right padding so the whole card is smaller */
.bw3.is-tight{ width:296px; height:194px; }
.bw3.is-tight .bw3-rail{ padding:10px 0; }
/* 文字块锁到格栅网格:顶端对齐到一条棱(padding-top 取周期 30 的整数倍),
   配合每行高 30,使每行文字中心都落在相邻两棱的中点(波谷 45/105/135)。
   两条记录行距=0 → 占相邻两条波谷带;slogan 与记录之间留一条空格栅带。 */
.bw3.is-tight .bw3-body{ padding:30px 13px 0 20px; justify-content:flex-start; }
.bw3.is-tight .bw3-slogan{ height:30px; margin-bottom:30px; }   /* 行高=1 周期、与记录隔 1 空带 → 中心落波谷 */
.bw3.is-tight .bw3-list{ gap:7px; margin-top:-1px; }            /* 第一条回落贴近波谷、第二条再下移:中心 104/141 */
.bw3.is-tight .bw3-item{ height:30px; }                          /* 每条记录高=1 周期,内容垂直居中→落波谷 */
/* recording in the tight size — label pinned top, timer vertically
   centred on the REC-key line, note chip floated up + narrower */
.bw3.is-tight .bw3-recmode{ padding:0; }
/* 位置还原到原始的 top:16px(作者 2026-07-25:对齐 slogan 的 30px 看着偏低)——只保留放大后的
   字号/字体(见上方 .bw3-reclabel:12px sans 600),位置回到卡片顶部原位。 */
.bw3.is-tight .bw3-reclabel{ position:absolute; top:16px; left:20px; }
.bw3.is-tight .bw3-timer{ font-size:52px; margin:0; height:100%; display:flex; align-items:center; justify-content:flex-start; padding-left:20px; transform:translateY(-2px); }
.bw3.is-tight .bw3-recprev{ position:absolute; left:20px; right:auto; bottom:20px; width:auto; padding-left:0; }
.bw3.is-tight .bw3-recprev .bw3-prev{ max-width:52px; }

/* playing / empty states + live pulse (production additions) */
.bw3-disc.is-playing{ background:radial-gradient(circle at 50% 34%, #ff6e51, #e8402a 70%); box-shadow:0 0 0 1px rgba(150,30,15,.3), 0 1px 2px rgba(0,0,0,.25); }
.bw3-disc.is-playing svg{ color:#fff; margin-left:0; }
.bw3.is-dark .bw3-disc.is-playing svg{ color:#fff; }
.bw3-empty{ font-size:11.5px; color:#8a8d93; font-style:italic; }
.bw3.is-dark .bw3-empty{ color:#83858c; }
.bw3-reclabel .dot{ animation:bwpulse 1.1s ease-in-out infinite; }
.bw3-item{ cursor:pointer; }

/* ============================================================
   MINIMIZED — the iOS desktop-widget card, laid HORIZONTAL.
   This is the EXACT geometry of HoldSayHomeWidget's systemSmall card
   (ios-app/HoldSayWidget + HoldSayShared/BraunUI.swift), which is the
   Mac card rotated 90°. The only difference is orientation: the widget
   is portrait, this floating bar is landscape — everything else (aspect,
   rail share, knob size, dot-ring, corner, 4 ridges) matches it 1:1.

   iOS spec → CSS:
     • aspect  width = height × 1.526   → 132×86
     • rail    = long-edge × 0.338      → 45  (matte REC slot)
     • knob    = min(H×0.46, railW×0.64)→ 29  (≈0.33·H; SMALL, like iOS)
     • dot-ring= knob × 1.31 (kept, like iOS RecKnob — never hidden)
     • corner  = short-edge × 0.30      → 26  (big round end), rail end 5
     • ridges  = period short-edge/4    → 4 horizontal flutes
   The faceplate line is the latest clip: duration (mono) then a short
   preview, e.g. `00:05  会议`, centered. Use case: Dictation.

   PERFORMANCE: the morph animates ONLY width/height/border-radius (cheap
   layout/paint on a ~12-node tree) + opacity (GPU). Nothing heavy is ever
   transitioned. The persistent .bw3 element (never re-created on content
   updates, see widget.html ensureScaffold) is what lets it run.
   ============================================================ */
:root{ --bw3-ease:cubic-bezier(.32,.72,0,1); --bw3-morph:.36s; }
.bw3{ transition:width var(--bw3-morph) var(--bw3-ease),
                  height var(--bw3-morph) var(--bw3-ease),
                  border-radius var(--bw3-morph) var(--bw3-ease); }
.bw3-rail{ transition:flex-basis var(--bw3-morph) var(--bw3-ease),
                       padding var(--bw3-morph) var(--bw3-ease); }
.bw3-rec{ transition:width var(--bw3-morph) var(--bw3-ease),
                     height var(--bw3-morph) var(--bw3-ease); }
.bw3-mic{ transition:width var(--bw3-morph) var(--bw3-ease),
                     height var(--bw3-morph) var(--bw3-ease),
                     top var(--bw3-morph) var(--bw3-ease), opacity .18s ease; }
.bw3-legend{ transition:opacity .18s ease; }
.bw3-face{ transition:border-radius var(--bw3-morph) var(--bw3-ease); }

/* the two faceplate bodies overlap so they can cross-dissolve */
/* 面孔文字与尺寸 morph 的配合(作者两轮验收调校):
   出场面孔快速淡出(.12s,字先消失再变形);进场面孔【立即】淡入 —— slogan 单行钉死+容器
   裁切后文字不再随宽度逐帧重排(旧发卡根因),而是被变宽的卡片右缘「扫过揭示」,既不卡
   也没有"等一下才出字"的死等(上一版 delay .30s 的问题)。 */
.bw3-bigbody{ position:relative; z-index:1; height:100%; transition:opacity .16s ease .04s; }
.bw3-mini{ position:absolute; inset:0; z-index:2; display:flex;
  align-items:center; justify-content:flex-start;
  box-sizing:border-box; padding:0 13px; opacity:0; pointer-events:none;
  transition:opacity .12s ease; }
.bw3.is-min .bw3-bigbody{ opacity:0; pointer-events:none; transition:opacity .12s ease; }
.bw3.is-min .bw3-mini{ opacity:1; transition:opacity .2s ease .06s; }
/* MINIMIZED ONLY: time STACKED over preview, left-aligned — the preview gets the
   full faceplate width so it can show a few more characters than a single row. */
.bw3-mini-line{ display:flex; flex-direction:column; align-items:flex-start; gap:3px;
  min-width:0; width:100%; pointer-events:none; cursor:default; }
.bw3.is-min .bw3-mini-line{ pointer-events:auto; cursor:pointer; }
.bw3-mini .bw3-dur{ font-size:12px; flex:0 0 auto; }
.bw3-mini .bw3-prev{ font-size:11px; max-width:100%; min-width:0;
  overflow:hidden; white-space:nowrap; text-overflow:ellipsis; }
.bw3-mini .bw3-prev b{ font-weight:700; color:#16181b; }
.bw3.is-dark .bw3-mini .bw3-prev b{ color:#fff; }
/* MINIMIZED active state: big centred figure — the recording timer or the X/Y
   transcribe count (font-size set inline, shrinks for longer strings). No label. */
.bw3-mini-fig{ width:100%; text-align:center; font-family:var(--mono); font-weight:700;
  letter-spacing:.01em; font-variant-numeric:tabular-nums; color:#26282c; line-height:1;
  text-shadow:0 1px 0 rgba(255,255,255,.5); }
.bw3.is-dark .bw3-mini-fig{ color:#f0f1f3; text-shadow:0 1px 2px rgba(0,0,0,.55); }
.bw3-mini-prep{ display:flex; align-items:center; justify-content:center; }
.bw3-mini-prep .bw3-txdots i{ width:6px; height:6px; }

/* ---- the compact geometry — iOS systemSmall card, rotated to landscape ---- */
.bw3.is-tight.is-min{ width:132px; height:86px; border-radius:5px 26px 26px 5px; }
.bw3.is-tight.is-min .bw3-rail{ flex:0 0 45px; padding:0; }   /* 45/132 = 0.34 */
.bw3.is-min .bw3-rec{ width:29px; height:29px; }              /* min(86·.46,45·.64) */
/* the red dot must scale WITH the knob (it's a fixed 13px on the 51px big knob =
   0.255); without this it stays 13px on the 29px knob = a giant "cracked" dot.
   13·29/51 = 7.4, the iOS knob dot ratio. Thin the ring/shadow to match. */
.bw3.is-min .bw3-rec::after{ width:7.4px; height:7.4px;
  box-shadow:0 0 0 .5px rgba(150,30,15,.28), 0 .5px 1px rgba(0,0,0,.22); }
.bw3.is-min .bw3-rec.is-live::after{ width:8px; height:8px; }
.bw3.is-min .bw3-mic{ width:38px; height:38px; top:-4.5px; opacity:1; }  /* ring = knob·1.31, kept */
.bw3.is-min .bw3-legend{ opacity:0; }                          /* compact → no REC legend (iOS) */
.bw3.is-min .bw3-face{ border-radius:0 26px 26px 0; }

/* ---- 4 horizontal ridges: identical metal, period = short-edge/4 = 21.5px,
   so the highlight lines land at y = 0 / 21.5 / 43 / 64.5 across the 86px face
   (iOS compact uses period = width/4; the big card is period 30 over 194 → 7) ---- */
.bw3.is-min.is-clean:not(.is-dark) .bw3-face{
  background:
    repeating-linear-gradient(180deg,
      rgba(255,255,255,.55) 0px,
      rgba(255,255,255,.55) 1.5px,
      rgba(45,42,36,.085) 1.5px,
      rgba(45,42,36,0) 14px,
      rgba(45,42,36,0) 21.5px),
    linear-gradient(180deg, #fdfcf9 0%, #fbfaf6 100%);
}
.bw3.is-min.is-clean.is-dark .bw3-face{
  background:
    repeating-linear-gradient(180deg,
      rgba(255,255,255,.10) 0px,
      rgba(255,255,255,.10) 1.5px,
      rgba(0,0,0,.34) 1.5px,
      rgba(0,0,0,0) 13px,
      rgba(0,0,0,0) 21.5px),
    linear-gradient(180deg, #3a3a3c 0%, #2f2f31 50%, #363638 100%);
}

/* honour the user's reduce-motion setting — no morph, just a snap */
@media (prefers-reduced-motion: reduce){
  .bw3,.bw3-rail,.bw3-rec,.bw3-face,.bw3-mic,.bw3-legend,.bw3-bigbody,.bw3-mini{ transition:none; }
}

/* ============================================================
   Variant tabs (Raw / Speakers / Paragraphs / Markdown)
   Mirrors the segmented control (.ba-seg) but lives at the top
   of .ba-doc; sits above the rendered transcript body.
   ============================================================ */
.ba-vartabs{ display:inline-flex; gap:0; background:var(--field); border-radius:var(--rbtn); padding:3px; margin:0 0 20px; }
.ba-vartabs .ba-seg-btn{ display:inline-flex; align-items:center; gap:6px; border:0; background:transparent; font-family:var(--font); font-size:12.5px; font-weight:500; color:var(--ink2); padding:5px 15px; border-radius:var(--rbtn-in); cursor:pointer; }
.ba-vartabs .ba-seg-btn:hover{ color:var(--ink); }
.ba-vartabs .ba-seg-btn.is-on{ background:var(--panel); color:var(--ink); font-weight:600; }
/* No recording on this note → these views can't re-recognize, so they're dead.
   Dim them, kill hover, and block the pointer. */
.ba-vartabs .ba-seg-btn.disabled{ opacity:.38; cursor:not-allowed; pointer-events:none; }
.ba-vartabs .ba-seg-btn.disabled:hover{ color:var(--ink2); }

/* status badges on a variant tab */
.ba-vardot{ display:inline-flex; align-items:center; justify-content:center; width:12px; height:12px; }
.ba-vardot.spin{ border:1.6px solid var(--hair); border-top-color:var(--red); border-radius:50%; animation:baspin .7s linear infinite; }
.ba-vardot.fail{ color:var(--red); }
.ba-vardot.fail svg{ width:12px; height:12px; }
@keyframes baspin{ to{ transform:rotate(360deg); } }
/* "暂未内置" corner tag — marks a permanently-disabled variant (e.g. 分人) */
.ba-vartag{ display:inline-flex; align-items:center; font-family:var(--mono); font-size:9.5px; font-weight:700; letter-spacing:.04em; line-height:1; color:var(--ink3); background:var(--chip); border:1px solid var(--hair); border-radius:5px; padding:2px 5px; }

/* tab bar = variant tabs on the left, debug control pinned to the right */
.ba-tabbar{ display:flex; align-items:center; justify-content:space-between; gap:12px; margin:0 0 20px; }
.ba-tabbar .ba-vartabs{ margin:0; }

/* debug control (ASR model switcher) */
.ba-debug-wrap{ position:relative; flex:0 0 auto; }
.ba-debug-btn{ display:inline-flex; align-items:center; gap:6px; height:30px; padding:0 11px; border:0; border-radius:8px;
  font-family:var(--mono); font-size:11px; font-weight:600; letter-spacing:.04em; color:var(--ink3);
  background:var(--field); box-shadow:0 0 0 1px var(--hair) inset; cursor:pointer; }
.ba-debug-btn:hover{ color:var(--ink2); }
.ba-debug-btn svg{ width:14px; height:14px; }
.ba-debug-btn.is-on{ color:var(--ink); box-shadow:0 0 0 1px var(--ink3) inset; }
.ba-debug-pop{ position:absolute; top:36px; right:0; z-index:50; width:268px; padding:16px;
  background:var(--bg); border-radius:12px; box-shadow:0 0 0 1px var(--hair) inset, 0 14px 38px rgba(0,0,0,.17), 0 2px 8px rgba(0,0,0,.08); }
.ba.is-dark .ba-debug-pop{ box-shadow:0 0 0 1px var(--hair) inset, 0 14px 40px rgba(0,0,0,.5); }
.ba-debug-pop .dbg-title{ display:flex; align-items:center; gap:7px; font-size:13px; font-weight:600; color:var(--ink); }
.ba-debug-pop .dbg-title svg{ width:15px; height:15px; color:var(--ink2); }
/* Per-mode cheat-sheet: what model + which steps each view runs. */
.ba-debug-pop .dbg-modes{ display:flex; flex-direction:column; gap:9px; margin:11px 0 14px; padding:11px 12px; border-radius:9px; background:var(--field); box-shadow:0 0 0 1px var(--hair) inset; }
.ba-debug-pop .dbg-mode{ display:flex; flex-direction:column; gap:2px; }
.ba-debug-pop .dbg-mode .m{ font-size:11.5px; font-weight:700; color:var(--ink); }
.ba-debug-pop .dbg-mode .d{ font-size:11px; color:var(--ink2); line-height:1.45; }
.ba-debug-pop .dbg-sublabel{ font-family:var(--mono); font-size:10px; font-weight:700; letter-spacing:.12em; text-transform:uppercase; color:var(--ink3); margin:0 0 7px; }
.ba-debug-pop .dbg-note{ font-size:11px; color:var(--ink2); line-height:1.5; margin:8px 0 0; }
/* 重新生成入口(放 debug 弹层,长转写不必滚到底部找)*/
.ba-debug-pop .dbg-regen{ width:100%; justify-content:center; margin-top:14px; }
.ba-debug-pop .dbg-seg{ display:flex; }
/* small inline toggle inside the debug overlay (long-turn re-segmentation) */
.ba-debug-pop .dbg-toggle{ margin:0; }
/* closing hint reminding the user changes need 「重新生成」 to take effect */
.ba-debug-pop .dbg-hint{ font-size:11px; font-weight:600; color:var(--red); line-height:1.45; margin:14px 0 0; padding-top:11px; border-top:1px solid var(--hair); }

/* "重新生成" footer under a rendered result — the single re-run entry point */
.ba-regenbar{ display:flex; align-items:center; gap:14px; margin:22px 0 8px; padding-top:18px; border-top:1px solid var(--hair); max-width:62ch; }
.ba-regen-btn{ height:38px; padding:0 18px; }
.ba-regen-btn .ico{ display:flex; width:16px; height:16px; }
.ba-regen-btn .ico svg{ width:16px; height:16px; }

/* running progress UI: 3-step stepper + determinate bar + cancel */
.ba-runwrap{ display:flex; flex-direction:column; gap:18px; max-width:62ch; padding:8px 0 4px; }
.ba-stepper{ display:flex; align-items:center; gap:0; }
.ba-step{ display:flex; align-items:center; gap:9px; }
.ba-step .dot{ width:24px; height:24px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  font-family:var(--mono); font-size:12px; font-weight:700; box-shadow:0 0 0 1px var(--hair) inset; background:var(--field); color:var(--ink3); }
.ba-step .lbl{ font-size:13px; font-weight:500; color:var(--ink3); }
.ba-step-line{ flex:1; min-width:22px; height:2px; margin:0 12px; border-radius:1px; background:var(--hair); }
.ba-step.done .dot{ background:var(--red); color:#fff; box-shadow:none; }
.ba-step.done .lbl{ color:var(--ink2); }
.ba-step.active .dot{ background:var(--panel); color:var(--red); box-shadow:0 0 0 1.6px var(--red) inset; }
.ba-step.active .lbl{ color:var(--ink); font-weight:600; }
.ba-step.todo .dot{ background:var(--field); color:var(--ink3); }
.ba-prog{ height:6px; border-radius:3px; overflow:hidden; background:var(--field); box-shadow:0 0 0 1px var(--hair) inset; }
.ba-progfill{ position:relative; display:block; height:100%; border-radius:3px; background:var(--red);
  overflow:hidden; transition:width .25s linear; }
.ba.is-dark .ba-progfill{ background:var(--ink2); }
/* Indeterminate "still working" shimmer riding the filled portion — keeps the bar
   alive even in the gap between chunk ticks. Phase re-synced each render. */
.ba-progshine{ position:absolute; inset:0; pointer-events:none;
  background:linear-gradient(100deg, transparent 18%, rgba(255,255,255,.5) 50%, transparent 82%);
  transform:translateX(-100%); animation:ba-progshine 1.15s linear infinite; }
@keyframes ba-progshine{ to{ transform:translateX(100%); } }
.ba-runrow{ display:flex; align-items:center; justify-content:space-between; gap:14px; }
.ba-runlabel{ font-size:13.5px; font-weight:500; color:var(--ink2); }
.ba-runright{ display:flex; align-items:center; gap:10px; }
.ba-eta{ font-size:12.5px; color:var(--ink3); white-space:nowrap; }
.ba-cancel{ border:0; background:var(--field); box-shadow:0 0 0 1px var(--hair) inset; color:var(--ink2);
  font-family:var(--font); font-size:12.5px; font-weight:500; padding:7px 16px; border-radius:8px; cursor:pointer; }
.ba-cancel:hover{ color:var(--ink); box-shadow:0 0 0 1px var(--ink3) inset; }

/* retry button inside the failed empty-state */
.ba-retry-btn{ margin-top:4px; }
.ba-retry-btn .ico{ display:flex; width:18px; height:18px; }
.ba-retry-btn .ico svg{ width:18px; height:18px; }

/* markdown view — rendered into real typography (was raw <pre>) */
.ba-md{ font-size:15px; line-height:1.7; color:var(--ink); margin:0 0 16px; max-width:62ch; }
.ba-md .ba-mdh{ font-weight:600; letter-spacing:-.01em; color:var(--ink); margin:24px 0 10px; line-height:1.3; }
.ba-md .ba-mdh:first-child{ margin-top:0; }
.ba-md .ba-mdh1{ font-size:22px; }
.ba-md .ba-mdh2{ font-size:18px; }
.ba-md .ba-mdh3{ font-size:15.5px; }
.ba-md .ba-mdh4,.ba-md .ba-mdh5,.ba-md .ba-mdh6{ font-size:14px; color:var(--ink2); }
.ba-md .ba-mdp{ margin:0 0 14px; }
.ba-md .ba-mdp strong,.ba-md .ba-mdli strong{ font-weight:700; }
.ba-md .ba-mdul,.ba-md .ba-mdol{ margin:0 0 14px; padding-left:22px; }
.ba-md .ba-mdli{ margin:0 0 6px; line-height:1.65; }
.ba-md .ba-mdul{ list-style:disc; }
.ba-md .ba-mdol{ list-style:decimal; }
/* GFM tables (e.g. Outline 行动项: 任务/负责人/截止时间/备注). Horizontal scroll on
   overflow so a wide table never blows out the panel width. */
.ba-md .ba-mdtwrap{ margin:0 0 16px; overflow-x:auto; -webkit-overflow-scrolling:touch; }
.ba-md .ba-mdtable{ border-collapse:collapse; width:100%; font-size:13.5px; line-height:1.55; }
.ba-md .ba-mdth,.ba-md .ba-mdtd{ border:1px solid var(--hair); padding:7px 11px; text-align:left; vertical-align:top; }
.ba-md .ba-mdth{ background:var(--chip); font-weight:600; color:var(--ink); white-space:nowrap; }
.ba-md .ba-mdtd{ color:var(--ink); }
.ba-md .ba-mdtable tbody tr:nth-child(even) td{ background:var(--hairsoft); }

/* ============================================================
   Live "整理预览" — the Outline forming under the progress bar.
   The pipeline streams accumulating polished markdown; we render
   it in a recessed panel so the wait shows real, growing content
   instead of a blank canvas. Before the first chunk lands we show
   the note's own raw transcript as a faded skeleton ("通读全文").
   ============================================================ */
.ba-preview{ position:relative; margin:20px 0 4px; max-width:62ch; border:1px solid var(--hair); border-radius:13px;
  background:var(--panel); box-shadow:0 1px 3px rgba(0,0,0,.04); overflow:hidden; }
.ba.is-dark .ba-preview{ box-shadow:0 1px 3px rgba(0,0,0,.22); }
/* Glass "refresh" sweep — a soft, wide band of light gliding diagonally across the
   whole panel, like a reflection moving over a pane of glass. The one constant cue
   that this is live and provisional, not a finished result. Compositor-only
   (transform), pointer-transparent, sits above the content for the glare; render()
   re-syncs its phase so the per-tick rebuild doesn't restart the glide. */
.ba-preview-sweep{ position:absolute; inset:0; z-index:3; pointer-events:none; border-radius:inherit;
  /* TWO chunky specular bands (each a bright PLATEAU, not a thin line) raking over one
     very wide, thick soft halo — like light sweeping across a glass pane. Band 1 is the
     wider, brighter streak; band 2 is a touch narrower; the halo is a broad glow behind
     both. Visible but text stays legible; phase synced to HS_SWEEP_MS. */
  background:
    linear-gradient(100deg, transparent 18%, rgba(255,255,255,.50) 28%, rgba(255,255,255,.50) 40%, transparent 50%),
    linear-gradient(100deg, transparent 56%, rgba(255,255,255,.40) 63%, rgba(255,255,255,.40) 69%, transparent 76%),
    linear-gradient(100deg, transparent  1%, rgba(255,255,255,.22) 28%, rgba(255,255,255,.24) 50%, rgba(255,255,255,.22) 72%, transparent 99%);
  transform:translateX(-125%); animation:ba-sweep 3.4s ease-in-out infinite; will-change:transform; }
@keyframes ba-sweep{ 0%{ transform:translateX(-125%); } 100%{ transform:translateX(125%); } }
.ba.is-dark .ba-preview-sweep{ background:
    linear-gradient(100deg, transparent 18%, rgba(255,255,255,.27) 28%, rgba(255,255,255,.27) 40%, transparent 50%),
    linear-gradient(100deg, transparent 56%, rgba(255,255,255,.22) 63%, rgba(255,255,255,.22) 69%, transparent 76%),
    linear-gradient(100deg, transparent  1%, rgba(255,255,255,.12) 28%, rgba(255,255,255,.13) 50%, rgba(255,255,255,.12) 72%, transparent 99%); }
@media (prefers-reduced-motion: reduce){ .ba-preview-sweep,.ba-progshine{ animation:none; } }
.ba-preview-head{ display:flex; align-items:center; gap:8px; padding:11px 16px;
  font-size:11.5px; font-weight:600; letter-spacing:.02em; color:var(--ink3);
  border-bottom:1px solid var(--hairsoft); background:linear-gradient(var(--hairsoft), transparent); }
.ba-preview-pip{ position:relative; width:7px; height:7px; border-radius:50%; background:var(--red); flex:none;
  animation:ba-pip 1.5s ease-in-out infinite; }
/* The expanding ring is a fixed-spread box-shadow on ::after that we only scale +
   fade — transform/opacity are compositor-only, so no per-frame repaint of spread. */
.ba-preview-pip::after{ content:''; position:absolute; inset:0; border-radius:50%;
  box-shadow:0 0 0 2px var(--red); animation:ba-pip-ring 1.5s ease-out infinite; }
@keyframes ba-pip{ 0%,100%{ opacity:1; } 60%{ opacity:.55; } }
@keyframes ba-pip-ring{ 0%{ transform:scale(1); opacity:.55; } 70%,100%{ transform:scale(2.6); opacity:0; } }
.ba-preview-body{ padding:8px 16px 14px; }
.ba-preview-body.ba-md{ max-width:none; margin:0; }   /* fill the panel (.ba-md otherwise caps at 62ch) */
/* Live polished preview: crisp, real content. The header + tail carry the
   "this is provisional" message, so the text itself stays fully legible. */
.ba-preview.is-live .ba-preview-body .ba-mdh:first-child{ margin-top:2px; }
.ba-preview-tail{ display:flex; align-items:center; gap:9px; padding:11px 16px 13px;
  font-size:12.5px; color:var(--ink3); border-top:1px solid var(--hairsoft); }
.ba-preview-wave{ display:inline-flex; align-items:flex-end; gap:3px; height:12px; }
/* Fixed height, animated via scaleY only (compositor) — no per-frame layout reflow. */
.ba-preview-wave i{ width:3px; height:12px; transform-origin:bottom; transform:scaleY(.42);
  border-radius:1.5px; background:var(--red); opacity:.8; animation:ba-wave 1s ease-in-out infinite; }
.ba-preview-wave i:nth-child(2){ animation-delay:.16s; }
.ba-preview-wave i:nth-child(3){ animation-delay:.32s; }
@keyframes ba-wave{ 0%,100%{ transform:scaleY(.42); opacity:.5; } 50%{ transform:scaleY(1); opacity:1; } }
/* Skeleton: the raw transcript while the model warms up. Recessed + masked at the
   bottom so it reads as "reading through it", never a hard cut or a fake outline. */
.ba-preview.is-skeleton .ba-preview-body{ position:relative; max-height:300px; overflow:hidden;
  -webkit-mask-image:linear-gradient(to bottom,#000 58%,transparent);
          mask-image:linear-gradient(to bottom,#000 58%,transparent); }
/* The user's own transcript while the model warms up — keep it legible (--ink2,
   ~4:1 light / ~7:1 dark); the bottom mask alone carries the "unfinished" cue. */
.ba-preview.is-skeleton .ba-preview-body .ba-mdp{ color:var(--ink2); margin:0 0 10px; }

/* ============================================================
   Multi-select (History): header entry, row checkboxes, batch
   bar, merge sheet, confirm dialog. Default browse view is
   untouched — everything below only appears in select mode /
   while a modal is open.
   ============================================================ */
/* Header "Select" / "Done" text button + count */
.lh-textbtn{ border:0; background:transparent; cursor:pointer; font-family:var(--font); font-size:12.5px; font-weight:600;
  color:var(--ink2); padding:4px 8px; border-radius:7px; }
.lh-textbtn:hover{ background:var(--field); color:var(--ink); }
.lh-selcount{ font-family:var(--mono); font-size:11.5px; color:var(--ink3); }

/* Row checkbox (replaces the play disc in select mode) */
.ba-check{ flex:0 0 auto; width:22px; height:22px; margin:3px 0; border-radius:7px; display:flex; align-items:center; justify-content:center;
  background:var(--field); box-shadow:0 0 0 1px var(--hair) inset; color:transparent; transition:background .12s, box-shadow .12s; }
.ba-check svg{ width:14px; height:14px; color:#fff; }
.ba-check.is-checked{ background:var(--red); box-shadow:0 0 0 1px var(--red) inset; }
.ba-noterow.is-selrow{ cursor:pointer; }
.ba-noterow.is-selrow.is-checked{ background:var(--redsoft); }
.ba-noterow.is-selrow.is-checked::before{ content:""; position:absolute; left:0; top:0; bottom:0; width:2px; background:var(--red); }

/* In-flow batch action bar at the bottom of the list column (.ba-scroll shrinks
   to make room — never overlaps rows). Select mode only. */
.ba-batchbar{ flex:0 0 auto; display:flex; align-items:center; gap:10px; padding:10px 14px;
  border-top:1px solid var(--hair); background:var(--panel); }
.ba-batchbar.is-empty{ justify-content:center; }
.ba-batchbar .bb-hint{ font-size:12px; color:var(--ink3); }
.ba-batchbar .bb-count{ font-family:var(--mono); font-size:12px; color:var(--ink2); white-space:nowrap; }
.ba-batchbar .bb-actions{ margin-left:auto; display:flex; gap:8px; }
.ba-batchbar .bb-btn{ height:34px; padding:0 14px; font-size:13px; }
.ba-batchbar .bb-btn .ico{ display:flex; width:16px; height:16px; }
.ba-batchbar .bb-btn .ico svg{ width:16px; height:16px; }
.ba-batchbar .bb-btn.is-disabled{ opacity:.4; cursor:default; }
.ba-batchbar .bb-danger{ color:var(--red); }
.ba-batchbar .bb-danger:hover{ background:var(--redsoft); }

/* Modal backdrop + sheet (merge / confirm) */
.ba-backdrop{ position:fixed; inset:0; z-index:1200; display:flex; align-items:center; justify-content:center;
  background:rgba(0,0,0,.34); animation:ba-fade .12s ease; }
@keyframes ba-fade{ from{ opacity:0 } to{ opacity:1 } }
.ba-sheet{ width:440px; max-width:calc(100vw - 48px); max-height:calc(100vh - 96px); display:flex; flex-direction:column;
  background:var(--bg); border-radius:14px; box-shadow:0 18px 60px rgba(0,0,0,.32), 0 0 0 1px var(--hair);
  padding:20px; animation:ba-pop .14s ease; }
.ba-sheet.ba-sheet-sm{ width:380px; }
@keyframes ba-pop{ from{ transform:scale(.97); opacity:.4 } to{ transform:scale(1); opacity:1 } }
/* 弹窗开着期间的后台重渲:is-settled(见 modalAnimClass)= 不重放进场动画 */
.ba-backdrop.is-settled{ animation:none; }
.ba-backdrop.is-settled .ba-sheet{ animation:none; }
.ba-sheet-head h3{ margin:0; font-size:16px; font-weight:600; letter-spacing:-.01em; color:var(--ink); }
.ba-sheet-sub{ margin-top:4px; font-size:12.5px; color:var(--ink3); line-height:1.45; }
.ba-sheet-actions{ display:flex; justify-content:flex-end; gap:10px; margin-top:18px; }
.ba-sheet-actions .ba-btn{ height:38px; padding:0 18px; font-size:13.5px; }
.ba-btn.danger{ background:var(--red); color:#fff; }
.ba-btn.danger:active{ filter:brightness(.95); }

/* Merge sheet — reorderable parts list */
.ms-list{ margin-top:14px; overflow-y:auto; display:flex; flex-direction:column; gap:4px; }
.ms-item{ display:flex; align-items:center; gap:10px; padding:9px 10px; border-radius:9px; background:var(--field);
  box-shadow:0 0 0 1px var(--hair) inset; cursor:grab; user-select:none; }
.ms-item.is-dragging{ opacity:.5; }
.ms-item.is-over{ box-shadow:0 0 0 2px var(--red) inset; }
.ms-grip{ display:flex; color:var(--ink3); flex:0 0 auto; }
.ms-grip svg{ width:16px; height:16px; }
.ms-num{ font-family:var(--mono); font-size:11px; color:var(--ink3); width:14px; text-align:center; flex:0 0 auto; }
.ms-title{ flex:1; min-width:0; font-size:13.5px; font-weight:500; color:var(--ink); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.ms-dur{ font-family:var(--mono); font-size:11.5px; color:var(--ink3); flex:0 0 auto; }
.ms-foot{ display:flex; align-items:center; justify-content:space-between; gap:12px; margin-top:14px; flex-wrap:wrap; }
.ms-summary{ font-family:var(--mono); font-size:11.5px; color:var(--ink3); }
.ms-check{ display:inline-flex; align-items:center; gap:8px; font-size:12.5px; color:var(--ink2); cursor:pointer; user-select:none; }
.ms-check .ms-box{ width:18px; height:18px; border-radius:6px; display:flex; align-items:center; justify-content:center;
  background:var(--field); box-shadow:0 0 0 1px var(--hair) inset; color:transparent; }
.ms-check .ms-box svg{ width:12px; height:12px; color:#fff; }
.ms-check.is-on .ms-box{ background:var(--red); box-shadow:0 0 0 1px var(--red) inset; }

/* ---- Pro paywall · 3 档付费墙(Braun,沿用变量,自动适配深色) ---- */
.ba-prohero.hs-pay{ align-items:flex-start; }
.hs-seatlab{ font-family:var(--mono); font-size:11px; color:var(--ink3); text-transform:uppercase; letter-spacing:.1em; margin:18px 0 8px; }
.hs-seats{ display:grid; grid-template-columns:repeat(3,1fr); gap:8px; max-width:320px; }
.hs-seat{ background:var(--field); border:0; border-radius:10px; padding:9px 6px 7px; cursor:pointer; text-align:center; font-family:var(--font); color:var(--ink); box-shadow:0 0 0 1px var(--hair) inset; transition:box-shadow .15s, background .15s; }
.hs-seat b{ display:block; font-size:18px; font-weight:700; line-height:1.1; }
.hs-seat span{ display:block; font-size:11px; color:var(--ink3); margin-top:1px; }
.hs-seat.is-on{ background:var(--bg); box-shadow:0 0 0 1.5px var(--red) inset; }
.hs-feats{ list-style:none; margin:16px 0 0; padding:0; }
.hs-feats li{ font-size:13px; color:var(--ink2); line-height:1.5; padding:3px 0 3px 20px; position:relative; }
.hs-feats li::before{ content:''; position:absolute; left:2px; top:9px; width:7px; height:7px; border-radius:50%; background:var(--red); opacity:.85; }
.hs-buyrow{ margin-top:18px; }
.hs-buyrow .ba-btn.primary{ height:44px; padding:0 26px; }
.hs-redeem{ margin-top:18px; padding-top:18px; border-top:1px solid var(--hair); max-width:440px; }
.hs-redeem-lab{ font-size:12.5px; font-weight:600; color:var(--ink2); margin-bottom:9px; }
.hs-redeem-row{ display:flex; gap:8px; }
.hs-redeem-input{ flex:1; height:38px; padding:0 12px; border:0; border-radius:8px; box-shadow:0 0 0 1px var(--hair) inset; background:var(--field); color:var(--ink); font-family:var(--mono); font-size:12px; outline:none; }
.hs-redeem-input:focus{ box-shadow:0 0 0 1.5px var(--red) inset; }
.hs-redeem-row .ba-btn{ height:38px; flex:0 0 auto; }
.hs-redeem-row .ba-btn[disabled]{ opacity:.55; cursor:default; }
.hs-redeem-status{ font-size:12px; margin-top:9px; min-height:15px; line-height:1.4; }
.hs-redeem-status.is-err{ color:var(--red); }
.hs-redeem-status.is-busy{ color:var(--ink3); }
.hs-redeem-status.is-ok{ color:#1c8c4a; }

/* ---- 上限已满:设备解绑列表 ---- */
/* (设备解绑列表 .hs-dev* 样式已删 —— 自助解绑 2026-07-17 反倒卖下线) */
/* 深色模式:选中档位要比 hero 背景更亮(浅色已是变亮,深色需修方向) */
.ba.is-dark .hs-seat.is-on{ background:#2d2d31; }

/* Debug · Outline 性能对比视图(仅 Debug Mode 显示;4B vs Apple FM 并排) */
.ba-metrics{ margin:22px 0 6px; padding:14px 16px; border-radius:12px; background:var(--field); box-shadow:0 0 0 1px var(--hair) inset; }
.ba-metrics .mt-h{ font-size:11px; font-weight:700; letter-spacing:.08em; color:var(--ink3); text-transform:uppercase; margin-bottom:10px; }
.ba-metrics table{ width:100%; border-collapse:collapse; font-family:var(--mono); font-size:12.5px; }
.ba-metrics th, .ba-metrics td{ padding:6px 10px; text-align:right; color:var(--ink2); border-top:1px solid var(--hair); }
.ba-metrics thead th{ border-top:0; color:var(--ink); font-weight:700; }
.ba-metrics thead th .sub{ font-size:10px; font-weight:400; color:var(--ink3); letter-spacing:.04em; }
.ba-metrics th.rk{ text-align:left; color:var(--ink3); font-weight:400; }
.ba-metrics .on{ color:var(--ink); background:var(--chip); }
.ba-metrics .mt-note{ margin-top:10px; font-family:var(--font); font-size:11.5px; line-height:1.5; color:var(--ink3); }

/* ---- 原生 app 观感:全局默认箭头光标(去掉网页式小手);只有文本输入框保留 I 形光标。 ----
   用 !important + 足够特异度盖过全文 40+ 处 cursor:pointer。 */
.ba *, .bw *, .bw3 *{ cursor:default !important; }
.ba input, .ba textarea, .bw input, .bw textarea, .bw3 input, .bw3 textarea{ cursor:text !important; }

/* ============================================================
   Invite — 自建 referral 整页(五段式)。设计语言 = 现有基线
   (中性白/大圆角/无 emoji 自绘图形);hero 用品牌深色卡一套。
   ============================================================ */
.hs-inv{ max-width:860px; }

/* 页顶条(S4 温和 banner / S9 风控灰条 / 72h 黄条 / Alipay 蓝条) */
.hs-inv-bar{ display:flex; align-items:center; gap:10px; font-size:13px; line-height:1.5; color:var(--ink);
  background:var(--field); border-radius:10px; box-shadow:0 0 0 1px var(--hair) inset; padding:10px 14px; margin-bottom:14px; }
.hs-inv-bar .x{ margin-left:auto; color:var(--ink3); cursor:pointer; font-size:12px; padding:2px 6px; border-radius:6px; }
.hs-inv-bar .x:hover{ color:var(--ink); background:var(--hairsoft); }
.hs-inv-bar.is-gray{ color:var(--ink2); }
.hs-inv-bar.is-soft{ background:var(--redsoft); box-shadow:0 0 0 1px rgba(216,64,42,.18) inset; }
.hs-inv-bar.is-warn{ background:rgba(222,168,32,.12); box-shadow:0 0 0 1px rgba(222,168,32,.32) inset; }
.hs-inv-bar.is-blue{ background:rgba(46,116,222,.10); box-shadow:0 0 0 1px rgba(46,116,222,.28) inset; }

/* ① Hero 分享卡:满宽圆角,纯品牌红平面卡(渐变+投影被否,owner 2026-07-16「土」),
   白色大标题 + 白色主 CTA,同 App 纯色语言。 */
.hs-inv-hero{ position:relative; overflow:hidden;
  border-radius:32px; padding:34px 36px 32px; margin-bottom:22px; color:#fff;
  background:var(--red); }
.hs-inv-hero .h1{ font-size:28px; font-weight:750; letter-spacing:-.022em; line-height:1.12; color:#fff; }
.hs-inv-hero .sub{ font-size:15px; font-weight:650; line-height:1.62; color:rgba(255,255,255,.88); margin-top:11px; max-width:48ch; }
.hs-inv-hero .lab{ font-family:var(--mono); font-size:13.5px; font-weight:700; letter-spacing:.16em; text-transform:uppercase;
  color:rgba(255,255,255,.68); margin:26px 0 9px; }
.hs-inv-hero .linkrow{ display:flex; align-items:center; gap:10px; }
.hs-inv-hero .link{ flex:1; min-width:0; height:44px; padding:0 15px; border:0; border-radius:11px; outline:0;
  font-family:var(--mono); font-size:13.5px; font-weight:700; letter-spacing:.01em; color:#fff;
  background:rgba(0,0,0,.18);
  text-overflow:ellipsis; white-space:nowrap; overflow:hidden; -webkit-user-select:text; user-select:text; }
/* Copy = 半透明描边幽灵按钮;Share = 纯白药丸(红字)= 主 CTA,Wise 式白钮 */
.hs-inv-hero .ba-btn{ height:44px; }
.hs-inv-hero .ba-btn.ghost{ background:rgba(255,255,255,.16); color:#fff; box-shadow:none; }
.hs-inv-hero .ba-btn.ghost:hover{ background:rgba(255,255,255,.22); }
.hs-inv-hero .ba-btn.ghost.is-copied{ color:#dff5e1; }
.hs-inv-hero .ba-btn.primary{ background:#fff; color:var(--red); box-shadow:none; }
.hs-inv-hero .ba-btn.primary:hover{ background:#fff8f5; }
.hs-inv-hero .ba-btn[disabled]{ opacity:.5; }

/* S11:缓存态小字 */
.hs-inv-stale{ font-size:13.5px; font-weight:700; color:var(--ink2); text-align:right; margin:-6px 0 6px; }
.hs-inv-stale a{ color:var(--ink2); text-decoration:underline; text-underline-offset:2px; cursor:pointer; }

/* ② 战绩四格(与成就仪表盘统计卡同级:大留白 + 大数字 + 克制标签) */
.hs-inv-tiles{ display:grid; grid-template-columns:repeat(4,1fr); gap:14px; margin-bottom:6px; }
/* 2026-07-16 两格版(人 + 钱,去传销后台味):冻结/可提现拆解挪进提现卡 */
.hs-inv-tiles.two{ grid-template-columns:repeat(2,1fr); }
.hs-inv-bd{ font-variant-numeric:tabular-nums; }
.hs-inv-tile{ background:var(--bg); border-radius:24px; padding:18px 20px 17px; }   /* stats 页准则(2026-07-16):纯色灰底、无描边、大圆角 */
.hs-inv-tile .tl{ font-family:var(--mono); font-size:13.5px; font-weight:700; letter-spacing:.15em; text-transform:uppercase; color:var(--ink2); }
.hs-inv-tile .tv{ font-family:var(--mono); font-size:27px; font-weight:750; letter-spacing:-.015em; font-variant-numeric:tabular-nums; color:var(--ink); margin-top:11px; line-height:1; }
.hs-inv-tile .ts{ font-size:13.5px; font-weight:700; color:var(--ink2); margin-top:8px; }
.hs-inv-hint{ font-size:13.5px; font-weight:700; color:var(--ink2); margin:10px 2px 0; }

/* ③ 奖励三卡:大留白 + 醒目价格 + 底部整宽 CTA 对齐(三卡等高等宽底钮) */
.hs-inv-cards{ display:grid; grid-template-columns:repeat(3,1fr); gap:14px; margin:20px 0 6px; align-items:stretch; }
.hs-inv-card{ display:flex; flex-direction:column; background:var(--bg); border-radius:24px;
  padding:20px 20px 18px; min-height:176px; }
.hs-inv-card.is-dim{ opacity:.6; }   /* 余额不足:置灰但可见 — 让用户看到目标 */
.hs-inv-card .head{ display:flex; align-items:baseline; justify-content:space-between; gap:10px; }
.hs-inv-card .t{ font-size:15px; font-weight:700; letter-spacing:-.01em; color:var(--ink); }
.hs-inv-card .p{ font-family:var(--mono); font-size:15px; font-weight:750; font-variant-numeric:tabular-nums; letter-spacing:-.01em; color:var(--ink); flex:0 0 auto; }
.hs-inv-card .d{ font-size:13.5px; font-weight:700; line-height:1.55; color:var(--ink2); margin-top:8px; }
.hs-inv-card .body{ margin-top:auto; padding-top:16px; }
.hs-inv-card .body .ba-btn{ height:38px; padding:0 16px; font-size:13px; width:100%; justify-content:center; }
.hs-inv-card .note{ font-size:13.5px; font-weight:700; line-height:1.55; color:var(--ink); margin-bottom:10px; }
.hs-inv-card .note.is-warn{ color:#a5701c; }
.hs-inv-card .sub{ font-size:13.5px; font-weight:700; line-height:1.5; color:var(--ink2); margin-top:9px; }
.hs-inv-card .ba-btn.is-ready{ color:#2e7d3a; box-shadow:0 0 0 1px rgba(46,125,58,.32) inset; background:rgba(46,125,58,.09); }
.hs-inv-pill{ display:block; text-align:center; font-size:13.5px; font-weight:700; line-height:1.5; color:var(--red);
  background:var(--redsoft); border-radius:11px; padding:11px 14px; }   /* S5:品牌色胶囊,不像故障 */
.hs-inv-prog{ margin-bottom:8px; }
.hs-inv-prog .bar{ height:7px; border-radius:4px; background:var(--field); overflow:hidden; }
.hs-inv-prog .bar i{ display:block; height:100%; border-radius:4px; background:var(--red); }
.hs-inv-prog .nums{ font-family:var(--mono); font-size:13.5px; font-weight:700; font-variant-numeric:tabular-nums; color:var(--ink2); margin-top:7px; }

/* ④ 引荐流水表 + 空状态 */
.hs-inv-sect{ font-family:var(--mono); font-size:13.5px; font-weight:700; letter-spacing:.16em; text-transform:uppercase; color:var(--ink2); margin:34px 0 12px; }
.hs-inv-table{ background:var(--bg); border-radius:24px; overflow:hidden; }
.hs-inv-table .row{ display:grid; grid-template-columns:76px 1.4fr .8fr .8fr 1.4fr; gap:10px; align-items:center;
  padding:13px 18px; border-top:1px solid var(--hairsoft); font-size:13.5px; font-weight:700; color:var(--ink); }
.hs-inv-table .row:first-child{ border-top:0; }
.hs-inv-table .row.is-head{ font-family:var(--mono); font-size:12px; font-weight:700; letter-spacing:.1em; text-transform:uppercase; color:var(--ink2); background:var(--field); padding-top:11px; padding-bottom:11px; }
.hs-inv-table .c-date{ color:var(--ink2); font-variant-numeric:tabular-nums; }
.hs-inv-table .c-friend{ color:var(--ink); font-weight:550; }
.hs-inv-table .c-paid{ color:var(--ink2); }
.hs-inv-table .c-paid,.hs-inv-table .c-earned{ font-family:var(--mono); font-variant-numeric:tabular-nums; }
.hs-inv-table .c-earned{ color:var(--ink); font-weight:650; }
.hs-inv-table .row.is-head .c-paid,.hs-inv-table .row.is-head .c-earned{ font-weight:700; color:var(--ink2); }
.hs-inv-table .c-status{ text-align:right; }
.hs-inv-chip{ display:inline-block; font-size:11px; font-weight:600; border-radius:999px; padding:3.5px 11px; white-space:nowrap; }
.hs-inv-chip.is-hold{ color:var(--ink2); background:var(--field); box-shadow:0 0 0 1px var(--hair) inset; }
.hs-inv-chip.is-ok{ color:#2e7d3a; background:rgba(46,125,58,.10); box-shadow:0 0 0 1px rgba(46,125,58,.22) inset; }
.hs-inv-chip.is-rev{ color:#b3564a; background:rgba(216,64,42,.08); box-shadow:0 0 0 1px rgba(216,64,42,.18) inset; }
.hs-inv-chip.is-warn{ color:#a5701c; background:rgba(222,168,32,.12); box-shadow:0 0 0 1px rgba(222,168,32,.3) inset; }
.hs-inv-more{ display:flex; justify-content:center; margin-top:12px; }
.hs-inv-emptyw{ display:flex; flex-direction:column; align-items:center; text-align:center; gap:6px;
  background:var(--bg); border-radius:24px; padding:44px 20px; }
.hs-inv-emptyw .art{ width:120px; height:78px; color:var(--ink2); margin-bottom:6px; }
.hs-inv-emptyw .big{ font-size:15px; font-weight:700; color:var(--ink); }
.hs-inv-emptyw .sub{ font-size:13.5px; font-weight:700; color:var(--ink2); max-width:40ch; line-height:1.55; }

/* ⑤ Important information */
.hs-inv-info{ background:var(--bg); border-radius:24px; padding:20px 22px; margin-bottom:26px; }
.hs-inv-info .li{ display:flex; align-items:flex-start; gap:11px; font-size:13.5px; font-weight:700; line-height:1.6; color:var(--ink2); padding:5.5px 0; }
.hs-inv-info .ck{ flex:0 0 16px; width:16px; height:16px; color:var(--red); margin-top:2px; }   /* 装饰性 ✓ 用品牌红,页面只留 灰/红 两色 */
.hs-inv-info .ck svg{ width:16px; height:16px; }
.hs-inv-info .zh{ font-size:13.5px; font-weight:700; line-height:1.7; color:var(--ink2); margin-top:10px; }   /* S15:仅此段的中文小字 */
.hs-inv-info .terms{ margin-top:12px; }
.hs-inv-info .terms a{ font-size:13.5px; font-weight:700; color:var(--ink2); text-decoration:underline; text-underline-offset:2px; cursor:pointer; }

/* 整页居中态(S10 锁定 / S14 过期 / S11 无缓存 / loading) */
.hs-inv-center{ display:flex; flex-direction:column; align-items:center; justify-content:center; gap:10px;
  min-height:60vh; text-align:center; }
.hs-inv-center-big{ font-size:17px; font-weight:700; color:var(--ink); }
.hs-inv-center-sub{ font-size:13.5px; font-weight:700; color:var(--ink2); }

/* 分享弹窗(四行)+ QR */
.hs-inv-sheet{ width:480px; }
.hs-inv-shrow{ display:flex; align-items:center; gap:14px; padding:12px 10px; border-radius:12px; cursor:pointer; margin-top:4px; }
.hs-inv-shrow:hover{ background:var(--field); }
.hs-inv-shrow .ic{ flex:0 0 34px; width:34px; height:34px; display:flex; align-items:center; justify-content:center;
  border-radius:10px; background:var(--field); box-shadow:0 0 0 1px var(--hair) inset; color:var(--ink2); }
.hs-inv-shrow .ic svg{ width:18px; height:18px; }
.hs-inv-shrow .tx{ display:flex; flex-direction:column; gap:2px; }
.hs-inv-shrow .tx b{ font-size:13.5px; font-weight:600; color:var(--ink); }
.hs-inv-shrow .tx span{ font-size:11.5px; color:var(--ink3); }
.hs-inv-qrbox{ display:flex; flex-direction:column; align-items:center; gap:10px; padding:14px 0 6px; }
.hs-inv-qrbox img{ width:180px; height:180px; border-radius:12px; box-shadow:0 0 0 1px var(--hair); background:#fff; }
.hs-inv-qrbox .ba-btn{ height:32px; padding:0 14px; font-size:12.5px; }

/* 收款设置 sheet */
.hs-inv-seg{ margin:14px 0 4px; }
.hs-inv-payout-body{ padding-top:8px; overflow-y:auto; min-height:0; }
/* 矮窗口保底:sheet 是 flex 列 + max-height 裁切,body 必须可滚,否则表单长了 Save 按钮
   会被挤出可点区(2026-07-07 手续费披露行加高表单后 playwright 740px 视口真踩到)。 */
.hs-inv-field{ margin-top:12px; }
.hs-inv-field label{ display:block; font-size:12px; font-weight:600; color:var(--ink2); margin-bottom:6px; }
.hs-inv-field input, .hs-inv-field select{ width:100%; height:38px; padding:0 12px; border:0; border-radius:9px; outline:0;
  font-family:var(--font); font-size:13.5px; color:var(--ink); background:var(--field); box-shadow:0 0 0 1px var(--hair) inset;
  -webkit-user-select:text; user-select:text; }
.hs-inv-field input:focus{ box-shadow:0 0 0 1.5px var(--ink3) inset; }
.hs-inv-field .err{ min-height:14px; font-size:11.5px; color:var(--red); margin-top:4px; }
.hs-inv-codes{ font-size:13px; line-height:1.6; color:var(--ink2); background:var(--field); border-radius:10px;
  box-shadow:0 0 0 1px var(--hair) inset; padding:12px 14px; margin-top:12px; }

/* 禁用态(S11 缓存 / S9 风控):所有 Invite 操作按钮统一变淡 + 不可点 */
.hs-inv .ba-btn[disabled], .hs-inv-sheet .ba-btn[disabled]{ opacity:.55; pointer-events:none; }
.hs-inv .ba-btn.is-ready[disabled]{ opacity:1; }   /* Ready ✓ 是状态徽章不是禁用按钮 */

/* S1:试用用户 Pro 页底部种子钩子(灰字,不可点) */
/* (.hs-inv-seed 种子文案已删 —— 未解锁不再显示邀请钩子,owner 2026-07-17) */

/* ============ Pro 付费墙票券(官网 Get License 同款,2026-07-13) ============
   素材复用 ob/(票底/双卡/邮戳/Road Rage);cqw 基于 .hs-ticketwrap 容器宽,
   1310 设计稿 → 1cqw = 宽/100(N 设计 px ≈ N/13.1 cqw)。票面是奶油实底图,
   内部一律用固定墨色,不跟深浅主题翻转。 */
/* 数字/标签等宽体:设计首选 Roboto Mono(onboarding 栈里一直写着它但从未捆绑 ——
   Mac 静默回退 SF Mono、Windows 回退 Consolas,两端数字观感分家)。捆绑 variable
   woff2(32KB,latin 覆盖全部字重),两端从此同一张脸;系统装了本尊则用本尊。 */
@font-face{ font-family:'Roboto Mono'; src:local('Roboto Mono'),url('fonts/hs-mono.woff2') format('woff2'); font-weight:100 900; font-display:swap; }
@font-face{ font-family:'Road Rage'; src:url('ob/fonts/roadrage.woff2') format('woff2'); font-display:swap; }
/* CJK 光学等高+等重(礼品页同招):Road Rage 无 CJK,回退系统体同字号视觉大 ~30%
   且常规体在浓黑手写体旁发虚 → size-adjust 74% + 直接映射真半粗。 */
@font-face{ font-family:'HS CJK'; src:local('PingFang SC Semibold'),local('PingFangSC-Semibold'),local('Microsoft YaHei Bold'),local('Microsoft YaHei'); size-adjust:74%; unicode-range:U+2E80-303F,U+3400-4DBF,U+4E00-9FFF,U+F900-FAFF,U+FE30-FE4F,U+FF00-FFEF; }
@font-face{ font-family:'HS CJK'; src:local('Hiragino Sans W6'),local('HiraginoSans-W6'),local('Yu Gothic Bold'),local('Meiryo'); size-adjust:74%; unicode-range:U+3040-30FF,U+31F0-31FF; }
@font-face{ font-family:'HS CJK'; src:local('Apple SD Gothic Neo Bold'),local('AppleSDGothicNeo-Bold'),local('Malgun Gothic Bold'),local('Malgun Gothic'); size-adjust:74%; unicode-range:U+AC00-D7AF,U+1100-11FF,U+3130-318F; }
.hs-ticketwrap{ container-type:inline-size; margin-bottom:8px; }
.hs-tk-head{ font-family:'Road Rage','HS CJK',Impact,sans-serif; font-weight:400; color:var(--ink);
  font-size:max(30px,4.9cqw); line-height:1; letter-spacing:.01em; margin:2px 0 14px 2px; }
.hs-ticket{ position:relative; width:100%; aspect-ratio:1310/516;
  background:url('ob/ticket.png') center/100% 100% no-repeat;
  display:grid; grid-template-columns:1fr 1fr; }
.hs-ticket img{ height:auto; }
.hs-tk-art{ position:relative; }
.hs-tk-art img{ position:absolute; }
.hs-tk-art .tk-light{ left:5.8cqw; top:6.6cqw; width:22.9cqw; transform:rotate(-8deg); }
.hs-tk-art .tk-dark{ left:20cqw; top:15.7cqw; width:22.9cqw; transform:rotate(10deg); z-index:1; }
.hs-tk-art .tk-url{ position:absolute; left:4.3cqw; bottom:3.1cqw; font-family:var(--mono); font-size:max(9px,1.3cqw); color:#8E8B84; }
.hs-tk-stamp{ position:absolute; z-index:2; pointer-events:none; right:4.9cqw; top:-5.5cqw; width:max(84px,12.2cqw); opacity:.4; transform:rotate(-18deg); }
.hs-tk-buy{ display:flex; flex-direction:column; justify-content:center; text-align:left;
  padding:2.9cqw 4.7cqw 2.6cqw 8.4cqw; color:#000; }
.tk-brand{ display:flex; align-items:center; gap:.8cqw; color:#8E8B84; }
.tk-brand img{ width:max(18px,2.3cqw); border-radius:22%; filter:grayscale(1); opacity:.55; }
.tk-brand span{ font-weight:700; font-size:max(12px,1.55cqw); }
.tk-title{ font-family:'Road Rage','HS CJK',Impact,sans-serif; font-weight:400; color:#000;
  font-size:max(26px,4.4cqw); line-height:1; margin-top:1.5cqw; letter-spacing:.01em; }
.tk-price{ margin-top:2.2cqw; line-height:.85; text-align:center; }
.tk-price .amt{ font-family:'Road Rage','HS CJK',Impact,sans-serif; color:#000; font-size:max(34px,5.5cqw); }
.tk-price .was{ font-family:'Road Rage','HS CJK',Impact,sans-serif; color:#B8B7B4; font-size:max(16px,2.9cqw); margin-left:.9cqw; white-space:nowrap; }
.tk-price .was s{ text-decoration-thickness:max(2px,.22cqw); }
.tk-price .hs-off{ font-style:normal; font-size:.62em; text-decoration:none; display:inline-block; margin-left:.25em; }
/* 席位:官网 .seat 同款(白底描边圆角,选中加粗描黑)。覆盖 app 旧样式,色值固定不随主题。 */
.hs-ticket .hs-seats{ display:flex; gap:1.5cqw; max-width:none; margin-top:2.4cqw; }
.hs-ticket .hs-seat{ flex:1; background:#fff; border-radius:max(10px,1.8cqw); padding:1.1cqw .5cqw .9cqw;
  box-shadow:0 0 0 max(2px,.23cqw) #DCDBCF inset, 0 2px 8px -4px rgba(30,25,15,.12); color:#8E8B84; }
.hs-ticket .hs-seat b{ font-size:max(15px,2cqw); color:inherit; }
.hs-ticket .hs-seat span{ font-family:var(--mono); font-size:max(9px,1.2cqw); color:inherit; margin-top:.2cqw; }
.hs-ticket .hs-seat.is-on{ background:#fff; box-shadow:0 0 0 max(3px,.34cqw) #000 inset, 0 2px 8px -4px rgba(30,25,15,.12); color:#000; }
/* CTA:官网 tb-btn 同款黑胶囊 */
.hs-ticket .hs-buyrow{ margin-top:2.4cqw; }
.hs-ticket .tk-cta{ width:100%; height:max(40px,5.5cqw); border-radius:max(12px,1.8cqw);
  background:#000; color:#fff; font-weight:700; font-size:max(13px,1.8cqw); justify-content:center; }
.hs-ticket .tk-cta:hover{ background:#1c1917; transform:translateY(-1px); box-shadow:0 6px 16px -6px rgba(0,0,0,.5); }
.hs-ticket .hs-payfine{ font-family:var(--mono); margin-top:1cqw; font-size:max(9px,1.05cqw); line-height:1.5; color:#8E8B84; }
/* 票下:一句简介 + 三个卖点 + 激活码(样式沿用既有 .hs-feats/.hs-redeem) */
.hs-belowtk{ margin:18px 2px 24px; }
.hs-belowtk .pdesc{ font-size:13.5px; color:var(--ink2); line-height:1.55; max-width:60ch; }
.hs-belowtk .hs-feats{ margin-top:10px; }
.hs-belowtk .hs-redeem{ max-width:520px; border-top:0; padding-top:0; }
/* 深色主题:票面是固定奶油实底,内部一律不跟主题翻转 —— 压过 .ba.is-dark 的
   席位覆盖(否则选中席位在票面上变成深色块,2026-07-13 实测)。 */
.ba.is-dark .hs-ticket .hs-seat{ background:#fff; color:#8E8B84; }
.ba.is-dark .hs-ticket .hs-seat.is-on{ background:#fff; color:#000; box-shadow:0 0 0 max(3px,.34cqw) #000 inset, 0 2px 8px -4px rgba(30,25,15,.12); }

/* 深色模式微调 */
.ba.is-dark .hs-inv-chip.is-ok{ color:#7ecf8a; }
.ba.is-dark .hs-inv-card .note.is-warn{ color:#d9a94e; }
.ba.is-dark .hs-inv-info .ck{ color:#7ecf8a; }
/* 邀请页首屏骨架:无数据时(首次/刚启动)立即显示页面壳 + 灰条占位,数据回来再填,不显示 Loading 空屏 */
@keyframes hsSkShimmer{ 0%{ background-position:-160px 0; } 100%{ background-position:160px 0; } }
.hs-sk{ display:inline-block; border-radius:6px; background:rgba(120,110,100,.16);
  background-image:linear-gradient(90deg, rgba(120,110,100,.10) 0%, rgba(120,110,100,.22) 50%, rgba(120,110,100,.10) 100%);
  background-size:220px 100%; background-repeat:no-repeat; animation:hsSkShimmer 1.15s ease-in-out infinite; }
.hs-sk-num{ width:64px; height:26px; vertical-align:middle; }
.hs-inv-hero .link.is-sk{ color:transparent; }
.hs-inv-hero .link.is-sk::placeholder{ color:rgba(255,240,234,.5); }

/* ---- 照片入稿(会议照片按时间插进文稿;方案:桌面《HoldSay-照片入稿方案》) ---- */
.ba-content{ position:relative; }
.ba-attrow{ display:grid; grid-template-columns:1fr 1fr; gap:10px; margin:12px 0 18px; align-items:start; }
.ba-attrow.solo{ grid-template-columns:minmax(0,1fr); }
/* 排版态:图片本体即内容 —— 无卡片底、无常驻文字;时间码/移除按钮悬停浮现 */
.ba-att{ margin:0; position:relative; min-width:0; cursor:zoom-in; }
.ba-att-img{ display:block; width:100%; height:240px; min-height:96px; object-fit:cover;
  border-radius:12px; border:1px solid var(--hair); background:var(--field);
  box-shadow:0 1px 4px rgba(0,0,0,.06); }
.ba-attrow.solo .ba-att-img{ width:auto; max-width:100%; height:auto; max-height:440px; object-fit:contain; }
.ba-att:hover .ba-att-img{ box-shadow:0 4px 16px rgba(0,0,0,.14); }
.ba-att.is-dragging{ opacity:.35; }
.ba-att-hover{ position:absolute; left:8px; right:8px; top:8px; display:flex; align-items:center;
  justify-content:space-between; gap:8px; opacity:0; transition:opacity .15s; pointer-events:none; }
.ba-att:hover .ba-att-hover{ opacity:1; pointer-events:auto; }
@media (prefers-reduced-motion:reduce){ .ba-att-hover{ transition:none; } }
.ba-att-tc{ font-family:ui-monospace,'SF Mono',Menlo,monospace; font-size:11px; font-weight:700;
  color:#fff; background:rgba(22,20,17,.62); padding:3px 8px; border-radius:7px;
  -webkit-backdrop-filter:blur(4px); backdrop-filter:blur(4px); }
.ba-att-x{ flex:none; width:24px; height:24px; border-radius:50%; border:0; cursor:pointer;
  font-size:15px; line-height:1; color:#fff; background:rgba(22,20,17,.62);
  -webkit-backdrop-filter:blur(4px); backdrop-filter:blur(4px); font-family:inherit; }
.ba-att-x:hover{ background:var(--red); }
/* 原始路径断开但缓存/Library 仍可显示:保留图片,只给一个克制的状态角标。 */
.ba-att-sourcewarn{ position:absolute; left:8px; bottom:8px; z-index:2; width:22px; height:22px;
  display:flex; align-items:center; justify-content:center; border-radius:7px; color:#fff;
  background:rgba(22,20,17,.62); font-size:12px; line-height:1;
  -webkit-backdrop-filter:blur(4px); backdrop-filter:blur(4px); }
.ba-att-fallback{ display:none; }
/* 只有 thumb scheme 确认缓存、原图、Library 镜像都读不到才进入真正断链态。 */
.ba-att.ba-att-broken{ display:flex; align-items:center; gap:10px; padding:8px 10px;
  border:1px dashed var(--hair); border-radius:12px; cursor:default; }
.ba-att-broken .ba-att-img,.ba-att-broken .ba-att-hover,.ba-att-broken .ba-att-sourcewarn{ display:none; }
.ba-att-broken .ba-att-fallback{ display:flex; align-items:center; gap:10px; min-width:0; flex:1; }
.ba-att-missico{ width:40px; height:40px; border-radius:9px; background:var(--field);
  display:flex; align-items:center; justify-content:center; color:var(--ink3); flex:none; }
.ba-att-missico svg{ width:20px; height:20px; }
.ba-att-broken .ba-att-meta{ min-width:0; flex:1; display:flex; flex-direction:column; }
.ba-att-btc{ font-family:ui-monospace,'SF Mono',Menlo,monospace; font-size:12px; font-weight:700; color:var(--ink); }
.ba-att-broken .ba-att-name{ font-size:11.5px; color:var(--ink3); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.ba-att-broken .ba-att-x{ color:var(--ink3); background:transparent; }
.ba-att-broken .ba-att-x:hover{ background:var(--chip); color:var(--ink); }
/* 拖动换位的落点:平时不可见;chip 拖起时显形,悬停加深。 */
.ba-attgap{ height:6px; margin:-3px 0; border-radius:3px; }
body.is-att-drag .ba-attgap{ height:14px; margin:2px 0; background:var(--redsoft);
  outline:1px dashed var(--red); outline-offset:-1px; }
body.is-att-drag .ba-attgap.hot{ background:var(--red); opacity:.55; }
/* 拖拽悬停覆盖层(native 推 photoDrag 时) */
.ba-photoveil{ position:absolute; inset:10px; border:2px dashed var(--red); border-radius:14px;
  background:var(--redsoft); display:flex; align-items:center; justify-content:center;
  z-index:30; pointer-events:none; }
.ba-photoveil .in{ text-align:center; background:var(--panel); border:1px solid var(--hair);
  border-radius:12px; padding:14px 22px; box-shadow:0 6px 24px rgba(0,0,0,.12); }
.ba-photoveil b{ display:block; font-size:15px; color:var(--red); }
.ba-photoveil span{ font-size:12.5px; color:var(--ink2); }

/* 庆祝彩纸画布(hsCelebrate):全屏覆盖但绝不挡操作,粒子落尽由 JS 自移除 */
.hs-confetti{ position:fixed; inset:0; z-index:9999; pointer-events:none; }

/* 2026-07-09:兑换区改两卡(提现 + 送码);送码价带划线挂牌价 */
.hs-inv-cards.two{grid-template-columns:repeat(2,minmax(0,1fr))}
.hs-inv-cards.one{grid-template-columns:1fr}
.hs-inv-card .p s{color:#b9b6ae;font-weight:400;font-size:.82em;margin-left:5px;text-decoration-thickness:1.2px}

/* ============================================================
   直接编辑 + ⌘F 查找/替换条(2026-07-28 Notes 化)
   ============================================================ */
/* 标题:阅读态即可编辑;空标题占位灰字;聚焦无系统描边(光标本身就是状态) */
.hs-title-live{ outline:none; cursor:text; white-space:pre-wrap; }
.hs-title-live:empty::before{ content:attr(data-ph); color:var(--ink3); }
.hs-title-live:focus{ outline:none; }
/* 正文编辑面:与只读 .ba-para 同一套排版;不加边框不加底色 —— 它就是"纸"本身 */
.ba-livedit{ outline:none; cursor:text; caret-color:var(--red); min-height:160px; }
.ba-livedit:focus{ outline:none; }
.ba-livedit .ba-para{ white-space:pre-wrap; }
.ba-livedit .ba-attrow, .ba-livedit .ba-attgap{ cursor:default; }
.ba-livehost{ min-height:160px; }
/* 查找/替换条:吸顶于笔记滚动容器,磨砂底,两行(Notes 同款布局) */
/* 浮卡形态:吸顶但不贴边不压标题(负边距贴边版在真机把标题盖了半截,owner 打回) */
.ba-findbar{ position:sticky; top:0; z-index:8; display:flex; flex-direction:column; gap:8px;
  margin:0 0 20px; padding:10px 12px;
  background:var(--panel); border:1px solid var(--hair); border-radius:14px;
  box-shadow:0 10px 28px -14px rgba(0,0,0,.28); }
.ba-findbar .fb-row{ display:flex; align-items:center; gap:8px; }
.ba-findbar .fb-field{ flex:1; display:flex; align-items:center; gap:7px; height:32px; padding:0 10px;
  background:var(--field); border:1px solid var(--hair); border-radius:9px; min-width:0; }
.ba-findbar .fb-field:focus-within{ border-color:var(--red); box-shadow:0 0 0 3px var(--redsoft); }
.ba-findbar .fb-field svg{ width:14px; height:14px; color:var(--ink3); flex:none; }
.ba-findbar .fb-field input{ flex:1; min-width:0; border:none; outline:none; background:transparent;
  font:inherit; font-size:13px; color:var(--ink); }
.ba-findbar .fb-count{ font-family:var(--mono); font-size:11px; color:var(--ink3); flex:none; }
.ba-findbar .fb-count.is-zero{ color:var(--red); }
.ba-findbar .fb-navs{ display:flex; gap:0; flex:none; }
.ba-findbar .fb-btn{ height:32px; min-width:32px; padding:0 12px; border:1px solid var(--hair);
  border-radius:9px; background:var(--panel); color:var(--ink); font:inherit; font-size:13px;
  font-weight:600; cursor:pointer; }
.ba-findbar .fb-btn:hover{ background:var(--chip); }
.ba-findbar .fb-btn:disabled{ opacity:.4; cursor:default; }
.ba-findbar .fb-navs .fb-btn{ padding:0; width:32px; font-size:16px; line-height:1; }
.ba-findbar .fb-navs .fb-btn:first-child{ border-radius:9px 0 0 9px; border-right:none; }
.ba-findbar .fb-navs .fb-btn:last-child{ border-radius:0 9px 9px 0; }
.ba-findbar .fb-repchk, .ba-findbar .fb-dict{ display:flex; align-items:center; gap:6px; flex:none;
  font-size:13px; color:var(--ink2); cursor:pointer; user-select:none; -webkit-user-select:none; }
.ba-findbar .fb-repchk input, .ba-findbar .fb-dict input{ accent-color:var(--red); }
/* 全局光标政策(.ba *=default!important,input=text!important)会把勾选框弄成 I-beam;
   查找条两个勾选框(含 input 本体)定点压回小手(owner 2026-07-28) */
.ba .ba-findbar .fb-repchk, .ba .ba-findbar .fb-dict,
.ba .ba-findbar .fb-repchk *, .ba .ba-findbar .fb-dict *{ cursor:pointer !important; }
/* 同一政策也盖掉了直改正文/标题 —— 可编辑的纸面必须是 I-beam(备忘录同款,owner 2026-07-28);
   照片孤岛(不可编辑)保持箭头 */
.ba .hs-title-live, .ba .ba-livedit, .ba .ba-livedit *{ cursor:text !important; }
.ba .ba-livedit .ba-attrow, .ba .ba-livedit .ba-attrow *, .ba .ba-livedit .ba-attgap{ cursor:default !important; }
/* 说话人档案孤岛(可点):同一政策也会把头像/名字压成 I-beam —— 定点压回小手,
   用户一看就知道能点(owner 2026-07-31);改名进行中名字行回到 I-beam(可输入) */
.ba .ba-livedit .spk-av.spk-clickable, .ba .ba-livedit .spk-av.spk-clickable *,
.ba .ba-livedit .spk-name.spk-clickable{ cursor:pointer !important; }
/* 时间码跳播 chip 同为可点孤岛:编辑面政策(.ba-livedit *)在后面盖过通用豁免,
   这里用更高特异度定点压回小手(2026-08-02 owner 真机:I-beam 误导) */
.ba .ba-livedit .spk-tc, .ba .ba-livedit .spk-avcol{ cursor:pointer !important; }
.ba .ba-livedit .spk-name.spk-name-editing{ cursor:text !important; }
.ba-findbar .fb-dict{ font-size:12px; color:var(--ink3); }
.ba-findbar .fb-result{ font-size:12px; color:var(--ink2); display:flex; align-items:center; gap:8px; }
.ba-findbar .fb-undo{ border:none; background:none; color:var(--red); font:inherit; font-size:12px;
  font-weight:600; cursor:pointer; padding:0; text-decoration:underline; }
/* Done = 主色红(owner 2026-07-28:更醒目) */
.ba-findbar .fb-btn.fb-done{ background:var(--red); border-color:var(--red); color:#fff; }
.ba-findbar .fb-btn.fb-done:hover{ filter:brightness(.94); background:var(--red); }
/* 查找框清空 ⓧ(Notes 同款,count 右侧;无输入时隐藏) */
.ba-findbar .fb-clear{ flex:none; width:18px; height:18px; padding:0; border:none; background:none;
  color:var(--ink3); display:flex; align-items:center; justify-content:center; }
.ba-findbar .fb-clear svg{ width:15px; height:15px; display:block; }
.ba-findbar .fb-clear:hover{ color:var(--ink2); }
/* 命中高亮(CSS Custom Highlight API):全部=淡黄,当前=实黄加深字 —— 两主题通用 */
::highlight(hs-find){ background-color:rgba(255,213,79,.45); }
::highlight(hs-find-cur){ background-color:#ffc72e; color:#1a1a1a; }
::highlight(hs-q){ background-color:rgba(255,213,79,.45); }   /* 直编面全文搜索:同一款黄 */
