/* 2026-08-18 实测修正：1f23133 原版和 prism-sfr.html 的全局重置都是 border-box(两边
   一致，不是要抵消谁）,这批图当年就是在 border-box 下调出来的。显式写死在这里，不依赖
   目标页将来不改——防止哪天目标页把全局重置换掉，这批图无声跟着走样。 */
#market, #market * { box-sizing: border-box; }

/* 2026-08-18 实测修正：line-height 两边都是 1.6(prism-sfr.html body 和 1f23133 body 一致）,
   不需要抵消，写回 1.6 只是不依赖继承。font-weight 才是真的要抵消的：原版 400,
   prism-sfr.html body 是 300,不写回这批图的粗细会变细。background 不写——1f23133 原版这一段
   background 是透明的，坐在 --canvas(#f4f7f5)上；之前这里写的 var(--surface) 是错的，
   把底色从浅灰绿改成了纯白（2026-08-18 对比原版浏览器实测发现）。 */
#market { line-height: var(--lh-reset); font-weight: 400; }

#market{margin-bottom:40px}
#market .g-head{margin-bottom:16px}
#market .g-styles{display:flex;gap:8px;margin-bottom:16px}
#market .g-pill{font-family:var(--font-mono);font-size:var(--fs-caption);letter-spacing:var(--track-label);text-transform:uppercase;
             padding:8px 16px;border-radius:var(--radius-pill);border:1px solid var(--border);background:var(--surface);
             color:var(--muted-strong);cursor:pointer;transition:border-color var(--dur-fast),color var(--dur-fast),background var(--dur-fast)}
#market .g-pill:hover{border-color:var(--accent-line);color:var(--ink)}
#market .g-pill.on{background:var(--ink-card);border-color:var(--ink-card);color:var(--on-ink)}
#market .g-claim{font-family:var(--font-display);font-weight:400;font-size:var(--fs-h1);color:var(--ink);
             line-height:1.25 /* line-height: matches r-h2's 1.25; this element is on --fs-h1 not --fs-h2 so the class isn't adopted */;margin-bottom:8px;max-width:var(--w-narrow)}
        /* Task 13(design-language-unification): was .g-sub — brief's collapse table grouped it
           with the a-caption ("what is this?") names, but its actual content ("Circle position =
           ... size = ... colour = ...") answers a-legend's question ("what do the colours and
           sizes mean?"), not a-caption's — measured off the live text, not assumed from the name.
           Corrected here; noted in task-13-report.md. #plHowBody's only direct-child div.a-legend
           is this one (the real legend rows below live inside .pl-item), so this scope is safe. */
#market #plHowBody>div.a-legend{max-width:var(--w-narrow)}
        /* Task 13: was .g-legend + .tl-legend — identical container rules (display/flex-wrap/gap/
           margin-top), both collapsed into one. Both containers' rows live inside a .pl-item, so
           that ancestor plus the div/span element split (below) keeps this from also matching
           #plHowBody's bare .g-sub div above or .bf-legend's differently-laid-out container. */
#market .pl-item div.a-legend{display:flex;flex-wrap:wrap;gap:8px 16px;margin-top:8px}
        /* Task 13: was .g-size-note — font-size/color/line-height dropped, they already matched
           .a-scope (styles/roles.css) exactly; margin/max-width are the real remainder. ID-scoped
           (not class-scoped) so this doesn't also reach #market's other .a-scope uses in the same
           panel (g-scope-note, the big provenance paragraph, #bfCoverage). */
#market #sizeNote{margin-top:8px;max-width:var(--w-read)}
        /* 面板可用性反馈①(2026-08-09, Eddie): "没有一个市场从 09 年高点回归吗？ 为什么最高的比例
           也没有超过 0%" —— 这是表达问题， 不是数据问题： 回撤这个指标的定义是"距自己历史高点还差
           多少", 数学上最高就是 0, 0% 的含义是"正在创新高"。读者不该需要读小字才理解这件事， 所以
           这句解释不能用 .g-size-note/.strip-note 那种 11-11.5px 的静音灰footnote 排版（那正是
           Eddie 说的"小字")—— 用 --ink(不是 --muted-strong)、更大的字号、带色块的 callout, 让它
           在页面视觉层级上更接近"正文"而不是"脚注"。左边框的绿色（#2E7D5B)
           2026-08-10-panel-charts-redesign Task 3(独立复审 Minor m1 修复轮）: 这个色值原来的注释说
           它"取自 js/resi-market.js BANDS 数组里最接近历史高点那一档的圆圈颜色"——这条理由已经失效，
           BANDS 数组已经换成发散色阶（见 js/resi-market.js 文件头 §pct), 里面已经没有"最接近历史
           高点那一档"这个概念了（C_UP 现在的含义是"已经涨过崩盘前高点", 与这个 callout 描述的
           "0% = 历史高点"是另一件事）。色值本身仍然合适， 现在是一个独立选定的正向绿， 不再"取自
           BANDS"。
           m-2(2026-08-10 最终整支复审）: 上面原来还说"与 js/resi-market.js:477 附近同一色值（dd 带
           "top 0%" 标注）一样"——那个"dd 带 top 0% 标注"是四层带取代的旧单条回撤带上的一处标注，
           已经随那次重写整个消失， js/resi-market.js 现在对应位置是四层带的左上角三行（读 q75/q50/
           q25, 与"0% = 历史高点"这句话完全无关）, 不存在任何"同一色值"的姐妹引用了 —— 已删除这条
           失效的交叉引用， 不再指向一个不存在的东西。 */
        /* Task 13(design-language-unification): was .g-peak-note, now .a-scope — but the callout
           look above (--ink not --muted-strong, bigger font, coloured block) is Eddie's explicit,
           documented call one paragraph up ("这句解释不能用。..footnote 排版。..用 --ink、更大
           的字号、带色块的 callout"), not drift, so every property here is kept exactly as it
           was rather than dropped to the role's default look. ID-scoped so it doesn't leak this
           deviation onto #market's other .a-scope uses. */
#market #peakNote{font-size:var(--fs-small);color:var(--ink);line-height: var(--lh-panel);margin-top:12px;max-width:var(--w-read);
             padding:8px 12px;background:rgba(46,125,91,0.08) /* Task 16: kept literal on purpose — (46,125,91) is not any token (nearest is --accent (47,132,103), off by 1/7/12); it's the same historical green as this rule's own border-left:#2E7D5B two properties over, at 8% */;border-left:3px solid #2E7D5B;border-radius:0 var(--radius-sm) var(--radius-sm) 0}
#market #peakNote strong{font-weight:var(--fw-medium)}
#market .g-controls{margin-top:12px;display:flex;gap:8px;flex-wrap:wrap;align-items:center}
        /* Task 13: was .g-legend-item — font-size/color dropped, .a-legend (styles/roles.css)
           already supplies the same values; layout is the real remainder. Element-qualified
           (span, not div) and .pl-item-scoped so this doesn't also match the container-level
           div.a-legend rule above or .bf-legend's item-less container below. */
#market .pl-item span.a-legend{display:inline-flex;align-items:center;gap:8px}
#market .g-swatch{display:inline-block;width:9px;height:9px;border-radius:50%;flex:none}
        /* m-7(2026-08-10 最终整支复审）: 原来这里用 var(--accent-strong)(#2b7a5f, 一个青绿） —— 这个
           色值不在 js/resi-market.js 的 BANDS 数组里， 地图上永远不会有一个圆被画成这个颜色， 留着一个
           没有任何圆会画出来的样例就是撒谎。同一份文件紧接着下面 .g-swatch-faded 被删除时用的正是
           这条理由（"留着一个没有任何圆会画出来的样例就是撒谎")——这里逐字适用， 只是没人当时顺手把
           这一处也改掉。换成 C_ZERO(js/resi-market.js 里"恰好回到崩盘前高点"那一档的颜色， #d9d8d3),
           这是 BANDS 数组里真实存在、地图上真的会画出来的一个颜色。 */
#market .g-swatch-solid{background:#d9d8d3}
        /* .g-swatch-faded(2026-08-10-panel-charts-redesign Task 3, coordinator 裁定）已删除：
           "褪色 = 借用了更早季度"那个视觉状态随 resolveFrame 一起从颜色通道退役了， 圆现在只有
           实心/空心两种， 留着一个没有任何圆会画出来的样例就是撒谎。 */
#market .g-swatch-hollow{background:none;border:1px dashed #7C8794}
        /* Task 8: 时间轴柱子的三段图例 —— 方块（不是圆）, 和 js/resi-market.js 里锁死的三个色盲可
           分辨色一一对应（#2a78d6/#eda100/#c2521c), 不经 CSS 变量（数据色， 不随主题换）。
           Task 13(design-language-unification): 当时给了它一个独立的 .tl-legend 容器 class 名，
           理由是"测试需要一个无歧义的字符串起点截出这一块， 不能跟地图圆图例共用 class"——那个理由
           现在已经不成立了： 当时援引的 test/prism-hub-legend-panel.test.mjs 已在 43cc022 被删除，
           而它在被删之前那些断言就已经改用 id="tlLegend" 定位（2026-08-20 Task 22 补注： 原文没写
           它已被删除， 读起来像还有一条测试靠这个 class 名在守什么， 其实没有）,
           不再依赖 class 字符串本身唯一， 所以容器现在与地图圆图例共用同一个 .a-legend 收敛结果，
           上面 `#market .pl-item div.a-legend` 那条规则（container display/flex-wrap/gap/margin-top)
           已经覆盖它， 这里不再需要一条重复规则。 */
#market .g-swatch-mkt{background:#2a78d6;border-radius:var(--radius-sm)}
#market .g-swatch-pre{background:#eda100;border-radius:var(--radius-sm)}
#market .g-swatch-reo{background:#c2521c;border-radius:var(--radius-sm)}
#market #resiMap{background:var(--canvas);border:1px solid var(--border);box-shadow:var(--shadow-sm)}

        /* Task 12(2026-08-08, 收敛面板注解）: 悬浮图例/怎么读控件， 收进图右上角一个悬浮控件里的
           两个折叠块。两个折叠块共用 .pl-summary/.pl-body/.pl-chevron —— "统一格式"这条硬要求靠
           共用同一套类保证， 不是靠肉眼比对两份各写各的 CSS。
           Task 14(design-language-unification, 2026-08-20): 上面这段曾经描述的浮层布局（叠在地图
           右上角， .g-map-wrap 给 position:relative 的定位祖先， z-index 950 保证浮在 Leaflet 图层
           之上）已经整段撤回 —— 实测浮层内容 470px 只能在 360px 的高度上限里显示、必须内部滚动，
           且遮住地图 22.4%(见 task-14-report.md)。dataviz 指南明确把"图表容器内嵌套纵向滚动"
           列为反模式。改成复用本文件本来就有的、给手机断点写的"图下静态块"形态（见下方
           .panel-legend-ctrl 规则）——那正是"图例移到图下"这件事本该长的样子， 不是新发明一套布局。
           .g-map-wrap 的 position:relative 保留（不做定位祖先也无害）, 不再有任何后代依赖它定位。 */
#market .g-map-wrap{position:relative}
        /* Task 14: 桌面端曾经是 position:absolute 的浮层（见上方注释）, 现在直接采用原本只在
           max-width:640px 断点下才用的"图下静态块"这套值 —— 两种视口不再需要两套规则， 下面
           640px 断点里原来复位 position:static 的那条覆盖规则也随之整段删除（不会有任何一个视口
           还会用到 position:absolute, 复位规则变成死代码）。max-height/overflow 也一并去掉：
           不再是叠在地图上的浮层， 就不再需要一个滚动裁切来防止它盖住下面的图三/图三区域。 */
#market .panel-legend-ctrl{position:static;width:auto;max-width:none;max-height:none;
             overflow-y:visible;overflow-x:visible;margin-top:12px;
             background:var(--surface);backdrop-filter:none;-webkit-backdrop-filter:none;
             border:1px solid var(--border);border-radius:var(--radius);
             box-shadow:var(--shadow-sm);font-size:var(--fs-caption);color:var(--muted-strong)}
        /* Task 13(design-language-unification): was .pl-block, renamed .pl-panel — NOT collapsed
           into .a-disclosure despite the brief's collapse table grouping it there. Checked by
           content, not by name: .pl-block carries no text of its own (all copy lives in nested
           .pl-summary/.pl-item-label/.pl-item-note, none of which are in the 16-name list) — it's
           a pure structural wrapper for one collapsible section of the floating legend/how-to-read
           control, styled entirely by .panel-legend-ctrl (font-size/color) and its own children.
           Giving it .a-disclosure would import that role's own look (18/22px padding, --surface
           background, 2px accent border-left, fs-small/1.7/body text) on top of the floating
           widget's existing chrome — a real visual regression, not a rename. Renamed to .pl-panel
           (matching the widget's existing .pl-* prefix) instead of reusing a-disclosure as an
           alias-with-every-property-cancelled, which would satisfy the letter of "no aliases" but
           not the spirit. Noted in task-13-report.md as a correction to the brief's table. */
#market .pl-panel+.pl-panel{border-top:1px solid var(--border)}
#market .pl-summary{all:unset;box-sizing:border-box;display:flex;align-items:center;justify-content:space-between;
             gap:8px;width:100%;padding:8px 12px;cursor:pointer;font-family:var(--font-mono);font-size:var(--fs-caption);
             letter-spacing:var(--track-label);text-transform:uppercase;color:var(--ink)}
#market .pl-summary:hover{color:var(--accent-strong)}
#market .pl-summary:focus-visible{outline:2px solid var(--accent-strong);outline-offset:-2px}
#market .pl-chevron{transition:transform var(--dur-fast);font-size:var(--fs-caption);flex:none}
#market .pl-summary[aria-expanded="true"] .pl-chevron{transform:rotate(180deg)}
#market .pl-body{padding:0 12px 12px;line-height: var(--lh-caption)}
#market .pl-body[hidden]{display:none}
#market .pl-body>*:first-child{margin-top:0}
#market .pl-item{margin-top:8px}
#market .pl-item-label{font-size:var(--fs-caption);font-weight:var(--fw-medium);color:var(--ink);margin-bottom:4px}
#market .pl-item-note{font-size:var(--fs-caption);color:var(--muted-strong);line-height:1.45 /* line-height: tighter than a-caption/r-caption's 1.5, kept literal rather than silently rounded */}
#market .pl-ramp{width:100%;height:9px;border-radius:var(--radius-sm);border:1px solid var(--border)}
#market .pl-ramp-labels{display:flex;justify-content:space-between;font-size:var(--fs-caption);color:var(--muted-strong);margin-top:4px}
#market .pl-size-demo{display:flex;align-items:center;gap:8px}
#market .pl-size-circle{display:inline-block;border-radius:50%;background:var(--accent-strong);flex:none}
#market .pl-size-sm{width:6px;height:6px}
#market .pl-size-lg{width:16px;height:16px}
#market .pl-howto p{margin-top:8px}
        /* Task 14: 原来这里有一条 @media(max-width:640px) 覆盖规则， 把 .panel-legend-ctrl 从
           position:absolute 的浮层复位成 position:static 的图下静态块 —— 现在桌面端本身就已经是
           同一套 position:static 值（见上面 .panel-legend-ctrl 规则本身）, 两个视口不再有任何差别，
           这条覆盖规则整段变成死代码， 删除而不是留着一份不会再生效的重复声明。 */

        /* ── Task 6(交接项 #2/#3/#4/#5): .strip / .strip-h / .strip-note / .tl-note 全仓零 CSS,
           #globeStrips / #globeTimeline 是裸 div — 补齐。参照物是同页面的迁移图时间轴： 它靠的是
           .tl-bars{height:56px}(prism-hub.html 上方） + 内部 canvas 的 width:100%, 不是媒体查询给
           出确定高度。两条带（renderStrips)自己的 <svg> 已经带 style="width:100%;height:${H}px"
           内联像素高度（js/resi-market.js C-2 修过）, 所以 .strip/#globeStrips 这里只需要排版（标题/
           说明文字的字号颜色、条与条之间的间距）, 不需要再给高度。
           2026-08-10-panel-charts-redesign Task 5(困境带并入量价图， 图三重写）: 原来这里还有一段
           #globeTimeline 专属的 !important 高度覆盖（renderTimeline 的 <svg style="height:100%">
           在裸 div 父元素上解析不出确定高度， 退化成约 19px 的那个 bug, 曾靠 "#globeTimeline 的
           直接子 svg { height: 34px !important }" 这条选择器根治）——图三整体重写成上下两层之后，
           两层各自的 <svg> 已经改用与 renderStrips 同一种写法（style="width:100%;height:${H}px;display:block", 内联
           像素高度， 不是百分比）, #globeTimeline 因此不再需要、也不再有这条 !important 覆盖去够
           它——两层各自的高度完全由 js/resi-market.js 的 HP/HV 常量决定（见该文件 renderTimeline
           上方注释）, 与 .strip/#globeStrips 现在是同一套模式， 这里不再需要额外写一份。 */
#market .strip{margin-bottom:16px}
#market .strip:last-of-type{margin-bottom:8px}
        /* text-align —— Task 7(2026-08-10)曾把这里定成 center, 理由是当时的 spec §4.2/Eddie 原话
           要求"每个图都需要有一个同样格式的居中标题"。
           Task 14(design-language-unification, E5): 这条决定被推翻 —— 图标题现在统一左对齐
           (roles.css 的 figure.a-figure > figcaption 规则）。本文件三处静态标题（地图/价格走势带/
           买家来源）已经改走 figcaption > .a-figure-title 那条角色路径， 不再用 .strip-h; 这个类
           现在只剩 js/resi-market.js 内部自己拼的两处标题还在用（renderStrips 的轴说明行、
           renderTimeline 的图三标题） —— 那份文件被逐字节冻结， 改不了它输出的 class 名， 但这里是
           styles/resi-market.css, 不受冻结约束， 改 CSS 规则本身就能让它们跟着变左对齐， 不需要动
           被冻结的那个文件一个字。 */
#market .strip-h{font-family:var(--font-mono);font-size:var(--fs-caption);letter-spacing:.6px /* tracking: chart title, tighter than r-label's default 1px */;color:var(--muted-strong);margin-bottom:4px;text-align:left}
        /* .strip-coverage(2026-08-10-panel-charts-redesign Task 5 清理）: 已从选择器列表移除 ——
           这是原困境带（distress strip)覆盖度说明（"本季回撤/困境中位数各用了几个城市")用的
           class, 困境带本身已在 Task 4 整个移除、困境占比现在并进图三的左上角三行数字里， 没有
           任何元素还会渲染出 class="strip-coverage" 的节点， 留着这条规则是一份没人会用的死 CSS。 */
#market .strip-note{font-size:var(--fs-caption);color:var(--muted-strong);line-height: var(--lh-caption);margin-top:4px}
        /* .strip-peaknote(2026-08-10-panel-charts-redesign Task 6, 收尾清理）已删除： 曾经是"这一季
           距历史高点很近的市场有多少个"这句动态说明用的样式（js/resi-market.js renderStrips 里
           nearPeakCount() 每帧现算）。Task 4 独立复审裁定（spec §2.4 末尾明写）把 nearPeakCount()
           连同 PEAK_THRESHOLD_PP 常量整个删除之后， 这条 CSS 规则就已经没有任何元素会用它， 当时
           留给"最终整支复审"处理 —— 本任务就是那次最终清理， 规则本身（含 640px 断点下的字号覆盖）
           与钉住它的那条测试（原 test/prism-hub-static.test.mjs "Minor" 用例）一并删除。 */
        /* .strip-city-window(2026-08-10-panel-charts-redesign Task 3, 独立复审 C1 修复轮）已删除：
           cityWindowNote()(选中城市之后， 地图圆颜色 vs 这条带的城市叠加线并排显示的那一句）整个从
           js/resi-market.js 移除了 —— 它对读者谎报"地图圆颜色现在读的是这个数"(颜色通道早已换成 pct,
           那句话已被证伪）, 且没有站得住的改写方式， 见 js/resi-market.js renderStrips 上方的删除说明。
           这里不再留一条没有任何元素会用到的 CSS 规则。 */
#market #resiStrips{margin-top:16px}
        /* 2026-08-21 strip-corner-occlusion: 这里原来有一条 `#market .strip-corner{background:
           color-mix(in srgb, var(--surface) 88%, transparent); padding; border-radius}` ——
           Task 14(design-language-unification)加的衬板。给一块叠在数据上的注解加不透明底色，
           等于把"一层注解"变成"一块盖住数据的实心板"：实测 390px 视口下它横穿时间轴 93.9%，
           四层带里的三层被整块盖住（桌面 1440 下宽度占 24.6%、高度占 33.3%， 恰好那一段没有带子
           经过， 所以肉眼看不出来 —— 缺陷只在窄窗口显形）。
           规则整条删除， 因为那三行**已经不在绘图区里**了：js/resi-market.js 现在把它们输出成
           .strip-plot 之外的一行普通文字（class="strip-summary a-caption"）, 照 /prism/mf 的
           figcaption > .a-caption 同一个形态。⛔ 不是"删掉衬板让它透明"—— 无衬板压在深色带
           #c2c1bb 上时 #5b5a54 只有 3.83:1, 低于 AA 4.5:1; 修法是搬出来， 不是变透明。
           字号/行高/颜色全部由 .a-caption 角色给， 这里不再需要任何规则（边距见下面
           .strip-summary 那条）。
           .tl-corner(图三左上角三行）当时就判定不需要衬板 —— 它压在的是价格折线图层， 底下没有
           填充色块， 那条判断至今成立， 本次不动它。 */
#market .strip-summary{margin-bottom:8px}
#market #resiTimeline{margin-top:16px}
        /* .tl-plot(2026-08-10-panel-charts-redesign Task 5): 图三上下两层（价格/成交量）的包裹
           容器， position:relative 承重 —— .tl-corner(左上角三行）与 .tl-playhead(跨两层的共用
           播放头）都是叠在它上面的 position:absolute 元素， 与 renderStrips 的 .strip-plot 同一个
           模式（见该规则上方注释）。两层各自的 <svg> 用内联像素高度 + display:block(与 .strip-plot
           内部的 svg 同一种写法）, 不需要这里再给 !important 高度覆盖 —— 旧的
           "#globeTimeline 的直接子 svg { height: 34px !important }" 那条（给百分比高度 svg 用的）
           已随之删除， 不是遗漏。 */
#market .tl-plot{margin-top:4px}
#market .tl-current{font-family:var(--font-mono);font-size:var(--fs-caption);color:var(--ink);margin-top:8px}
#market .tl-note{font-size:var(--fs-caption);color:var(--muted-strong);line-height: var(--lh-caption);margin-top:4px}
@media(max-width: 640px){#market .g-claim{font-size:var(--fs-h2)}
             #market .strip-h{font-size:var(--fs-caption)}#market .strip-note,#market .tl-note{font-size:var(--fs-caption)}
             #market #peakNote{font-size:var(--fs-small)}
             /* I3(2026-08-10 复审）: 手机断点下图三两层的高度收缩规则 —— 旧版（单层， 百分比高度）
                在这个断点下靠 "#globeTimeline 的直接子 svg { height: 28px !important }" 收缩；
                图三重写成两层之后这条被删掉时没有补等价物（复审点名的真实缺口）。两个 <svg> 现在
                用内联像素高度（js/resi-market.js 的 HV=34/HP=54 常量）, 收缩必须用 !important
                覆盖 + data-layer 属性选择器分别指定（不能像旧版那样一个裸的直接子选择器就够，
                因为现在同一个容器里有两个 svg、高度还不一样）。28/44 与旧版 34→28 同一个收缩比例
                (34→28 ≈ 82%, 54×0.82≈44)。 */
             #market .tl-plot svg[data-layer="volume"]{height:28px!important}
             #market .tl-plot svg[data-layer="price"]{height:44px!important}}
#market .city-card{position:relative;margin-top:16px;padding:16px 20px 16px;max-width:380px; /* not-a-column: 点城市后弹出的紧凑卡片， 不是内容栏 */
             background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);
             box-shadow:var(--shadow-sm)}
#market .cc-close{position:absolute;top:8px;right:10px;background:none;border:none;font-size:var(--fs-h2);
             line-height: var(--lh-flush);color:var(--muted-strong);cursor:pointer;padding:4px 8px;border-radius:var(--radius-sm)}
#market .cc-close:hover{color:var(--ink);background:var(--canvas)}
#market .cc-name{font-family:var(--font-display);font-weight:400;font-size:var(--fs-h2);color:var(--ink);
             margin-bottom:12px;padding-right:24px}
#market .cc-row{display:flex;justify-content:space-between;align-items:baseline;gap:16px;
             font-size:var(--fs-small);color:var(--muted-strong);padding:8px 0;border-top:1px solid var(--border)}
#market .cc-row:first-of-type{border-top:none}
#market .cc-row b{font-family:var(--font-mono);font-weight:500;color:var(--ink);text-align:right;white-space:nowrap}
#market .cc-cta{display:block;margin-top:12px;padding-top:12px;border-top:1px solid var(--border);
             font-size:var(--fs-small);font-weight:var(--fw-medium);color:var(--accent-strong);text-decoration:none}
#market .cc-cta:hover{color:var(--ink)}

/* .btn-reset(1f23133:prism-hub.html:326-330) lifted out of the migration-map block deliberately:
   #gReplay/#gPause depend on it and this page has no .btn-reset of its own. */
#market .btn-reset{font-family:var(--font-body);font-size:var(--fs-small);cursor:pointer;background:none;
             border:1px solid var(--border);color:var(--body);padding:8px 12px;border-radius:var(--radius-sm);
             transition:border-color var(--dur-fast),color var(--dur-fast)}
#market .btn-reset:hover{border-color:var(--accent-line);color:var(--ink)}
#market .btn-reset:disabled{opacity:.45;cursor:default}

/* Task 8(2026-08-17-resi-station1-market): buyer-origin arcs, fourth block in #market. Map /
   tooltip / bar / legend / timeline rules lifted from buyer-flow.html(1f23133)第 24-94 行内联
   <style>(selectors renamed to this block's own bf-* classes / #bfXxx ids, #market 前缀按本文件
   既有规则加上） —— 页面级 chrome(kicker/h1/lede/wrap/disclosure/status/err)不在这份抽取范围内，
   那些是独立页面 buyer-flow.html 自己的排版脚手架、不是这块弧线图的画法本身， 这里复用本页已有的
   .strip-h / .btn-reset(上面已经为 #gReplay/#gPause 搬过一份， 这里的 #bfReset
   直接复用同一个类， 不再搬第二份）。#bfCoverage/#bfStatus 原来复用的是 .footnote —— Task 13
   (design-language-unification) 把它按内容拆开了（#bfCoverage 讲样本覆盖率 → .a-scope,
   #bfStatus 是加载失败态 → .a-flag), 见 prism-sfr.html 对应两处的行内注释。
   D8(Eddie 2026-08-17, 已获批）唯一的视觉改动： 原 .legend 里 Financed↔Cash 的色带（.ramp)整个
   删除， 图例（下面 .bf-legend)只留线宽刻度（.thin/.thick)—— 与 js/resi-buyer-flow.js 文件头/
   task-8-report.md 的六处改动对照表一致。 */
#market #bfMap{height:var(--h-map);width:100%;background:var(--canvas)}
#market .bf-panel{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);
             box-shadow:var(--shadow-sm);overflow:hidden;margin-top:12px}
#market .bf-panel .leaflet-tile-pane{filter:saturate(0.72) contrast(0.98)}
#market .flow-label{font-family:var(--font-mono);font-size:var(--fs-caption);color:var(--ink);
             background:color-mix(in srgb, var(--surface) 82%, transparent);padding:4px 4px;border-radius:var(--radius-sm);
             border:1px solid var(--border);white-space:nowrap;box-shadow:var(--shadow-sm)}
/* origin labels: lighter than destination labels so the eye reads dests as the subject */
#market .origin-label{font-family:var(--font-body);font-size:var(--fs-caption);color:var(--muted-strong);
             background:none;border:none;box-shadow:none;white-space:nowrap}
#market .leaflet-tooltip.origin-label::before{display:none}
#market .leaflet-tooltip.flow-label::before{display:none}
#market .leaflet-tooltip.fl-tip{font-family:var(--font-body);font-size:var(--fs-small);color:var(--body);
             background:var(--surface);border:1px solid var(--border);box-shadow:var(--shadow);
             border-radius:var(--radius-sm);padding:8px 12px}
#market .leaflet-tooltip.fl-tip b{color:var(--ink)}
#market .bf-bar{display:flex;align-items:center;gap:16px;flex-wrap:wrap;
             padding:12px 16px;border-top:1px solid var(--border);background:var(--surface)}
#market .bf-win{font-family:var(--font-mono);font-size:var(--fs-small);color:var(--ink);font-weight:500}
/* Task 13(design-language-unification): .bf-sub deleted outright — was font-size:fs-small/
   color:muted-strong only, and its new class, .a-caption, already supplies both (styles/roles.css)
   with no other property to keep. */
#market .bf-bar .spacer{flex:1 1 auto}
/* legend: line-width scale only — the Financed↔Cash colour ramp is D8's one approved deletion.
   Task 13: was .bf-legend — font-size/color dropped, .a-legend (styles/roles.css) already
   supplies both; layout is the real remainder. Scoped to .bf-bar (this container's only ancestor
   distinct from .pl-item, which the other div.a-legend rule above is scoped to) so the two
   different container layouts (flex-wrap here vs align-items:center there) don't collide on the
   same bare `div.a-legend` selector. */
#market .bf-bar div.a-legend{display:flex;align-items:center;gap:12px}
#market .bf-bar div.a-legend .thin,#market .bf-bar div.a-legend .thick{display:inline-block;background:var(--muted-strong);border-radius:var(--radius-sm)}
#market .bf-bar div.a-legend .thin{width:16px;height:2px}
#market .bf-bar div.a-legend .thick{width:16px;height:6px}
#market .bf-tl{padding:16px 16px 16px;border-top:1px solid var(--border);background:var(--surface);user-select:none}
#market .bf-tl-head{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:8px}
#market .bf-tl-head .t{font-family:var(--font-mono);font-size:var(--fs-caption);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--muted-strong)}
#market .bf-tl-head .hint{font-size:var(--fs-caption);color:var(--muted-strong)}
#market .bf-tl-bars{position:relative;height:68px}
#market #bfTlCanvas{position:absolute;inset:0;width:100%;height:100%}
#market .bf-tl-axis{display:flex;justify-content:space-between;margin-top:8px;font-family:var(--font-mono);
             font-size:var(--fs-caption);color:var(--muted-strong)}
