/* expansion-map.css — 扩张计划地图(#network)的唯一一份画法
 *
 * 谁在用:首页 site/index.html 的门店节、门店页 site/locations/index.html 的页头。
 * 为什么抽出来:两边原本各存一份几乎一样的 .xp-* 规则,各改各的,半个月下来漂成了两个样
 * (首页停在「地图当小角标」时期的排版:字 36 号、OPEN TODAY/PLANNED 全藏;门店页早就是
 * 21 号 + 小标露出来)。Jack 2026-09-17 看了两边原话「it is still different, in design and
 * text and so on, ensure to use code directly」——所以这里只留一份,两边共用,想改一起改。
 *
 * 动画时序和公式的正本在 Video Picker 仓 app/reports/effect-library/effects/us-expansion-map.html,
 * 由 js/locations-expansion.js 实现;这个文件只管长什么样,不管怎么动。
 *
 * 页面各自留在自己 <style> 里的,只有「地图摆在哪、多宽」这类版面问题,别再往这边塞。
 */

svg.xp-map { display: block; width: 100%; height: auto; overflow: visible; }

/* 地图上面那条:左边一句话、右边图例 */
.xp-map-top { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 6px 18px; margin-bottom: 10px; font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--soft); }
.xp-map-legend { display: flex; gap: 18px; }
.xp-map-legend i { display: inline-flex; align-items: center; gap: 8px; font-style: normal; }
.xp-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; }
.xp-dot.open { background: var(--ignite); }
.xp-dot.plan { border: 1.3px solid var(--soft); }

/* 陆地。stroke 对齐效果库正本 --hair(细发丝线);曾经错接成 --rule-2(双倍亮),州界线比正本抢眼 */
.xp-state { fill: var(--carbon); stroke: var(--rule); stroke-width: 0.8; stroke-linejoin: round; }

/* 计划中 vs 已经开的店:计划 = 空心细线 + 灰 + 虚线连线;已开 = 实心琥珀 + 光晕 + 绿点。锁 TC-XP20。
   「计划=灰」是 Jack 09-16 从 A/B/C 三版里挑定的,效果库正本那边是统一金黄,这条不跟着正本改回去 */
.xp-arc { fill: none; stroke: var(--soft); stroke-width: 1.4; stroke-linecap: butt; opacity: 0.75; }
/* stroke-dasharray 是照效果库正本抄的字节对齐:两边 JS 都会在 render() 里把它改写成整条路径
   长度(画完变实线),这个值从来没真生效过,不是漏做的视觉效果 */
.xp-spine { fill: none; stroke: var(--yf-accent-border); stroke-width: 1.6; stroke-linecap: round; stroke-dasharray: 2 5; }
.xp-sonar { fill: none; stroke: var(--soft); stroke-width: 1.2; opacity: 0; }
.xp-ring { fill: none; stroke: var(--ignite); stroke-width: 2; }
.xp-ring-plan { stroke: var(--soft); stroke-width: 1.3; }
.xp-node { fill: none; stroke: var(--soft); stroke-width: 1.3; }
.xp-core { fill: var(--ignite); }
.xp-halo { fill: var(--ignite); opacity: 0.16; transform-box: fill-box; transform-origin: center; }
.xp-live { fill: var(--signal); }

/* 字压在地图上,描一圈底色边才读得清 */
#xp-map text { paint-order: stroke; stroke: var(--black); stroke-width: 5px; stroke-linejoin: round; }
/* 字号写成两个旋钮:地图是按 1048 宽的坐标画的,屏上多大取决于这张图被摆多宽。
   两页在电脑上宽度接近,所以默认值一样;窄屏/矮窗口下两页的地图宽度差得多,
   由各自页面只调这两个旋钮(别再整段复制画法过去)。屏上不得小于 10px —— 锁 FS-8。 */
.xp-lbl { font-family: var(--mono); font-weight: 600; font-size: var(--xp-lbl-size, 21px); letter-spacing: 0.1em; fill: var(--white); }
.xp-lbl-hub { fill: var(--ignite-text); }
.xp-coord { display: none; } /* Jack 09-15「hide numbers, make it vague」:经纬度不露 */
.xp-tag-open { font-family: var(--mono); font-weight: 600; font-size: var(--xp-tag-size, 14px); letter-spacing: 0.18em; fill: var(--signal); }
.xp-tag-plan { font-family: var(--mono); font-weight: 600; font-size: var(--xp-tag-size, 14px); letter-spacing: 0.18em; fill: var(--soft); }
/* 脚本里 CHAMPAIGN 的位置是按 16 号字定的,21 号字会顶到自己的圆点上,往下让一点(锁 FS-5) */
.xp-hub[data-city="Champaign"] .xp-lbl-hub { transform: translateY(4px); }

/* 播完之后的「还活着」的呼吸:光晕轻微涨落 + 已开门店的绿点闪。
   效果库正本是每帧用正弦算的,这里改成播完(.xp-done)才起的 CSS 动画——网页版只播一遍不循环,
   呼吸当静置状态的提示更合适,不是漏抄 */
#network.xp-done .xp-halo { animation: xp-breathe 3s ease-in-out infinite; }
#network.xp-done .xp-live { animation: xp-live-pulse 1.8s ease-in-out infinite; }
@keyframes xp-breathe { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.08); } }
@keyframes xp-live-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }

/* 窄屏:地图缩到三分之一,小标放大到看得清就跟城市名一样大了,两个小标一起藏,
   靠形状(实心琥珀 + 光晕 vs 空心细灰圈)和下面的图例区分(锁 FS-8) */
@media (max-width: 760px) {
  :root { --xp-lbl-size: 34px; }
  .xp-coord, .xp-tag-open, .xp-tag-plan { display: none; }
  .xp-hub[data-city="Champaign"] .xp-lbl-hub { transform: translateY(16px); }
}

@media (prefers-reduced-motion: reduce) {
  #network.xp-done .xp-halo, #network.xp-done .xp-live { animation: none; }
}
