/* =========================================================================
   Run4Joy 跑步实时追踪系统 · 共享样式
   两个页面对应两个入口：index.html（普通用户） / admin.html（管理员）
   ========================================================================= */
:root{
  --bg:#f4f6fa; --surface:#ffffff; --surface-2:#f8fafc; --line:#e3e8ef; --line-2:#eef2f7;
  --text:#0f172a; --text-2:#475569; --text-3:#94a3b8;
  --brand:#2563eb; --brand-2:#1d4ed8; --brand-soft:#eff4ff;
  --green:#16a34a; --green-soft:#e8f7ee;
  --amber:#d97706; --amber-soft:#fdf3e3;
  --red:#dc2626; --red-soft:#fdecec;
  --slate:#64748b; --slate-soft:#f1f5f9;
  --garmin:#1f6feb; --coros:#ff6a00; --self:#10b981;
  --r:12px; --r-sm:8px;
  --shadow:0 1px 2px rgba(15,23,42,.06), 0 8px 24px -12px rgba(15,23,42,.18);
  --shadow-lg:0 24px 60px -20px rgba(15,23,42,.35);
  --topbar-h:56px;
}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
[hidden]{display:none!important}
html,body{margin:0;height:100%}
body{
  font-family:-apple-system,BlinkMacSystemFont,"PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;
  background:var(--bg);color:var(--text);font-size:14px;line-height:1.5;overflow:hidden;
}
button{font-family:inherit;font-size:inherit;cursor:pointer;border:none;background:none;color:inherit}
input,select,textarea{font-family:inherit;font-size:inherit;color:inherit}
::-webkit-scrollbar{width:8px;height:8px}
::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:8px}
::-webkit-scrollbar-thumb:hover{background:#94a3b8}

/* ---------- 应用骨架 ---------- */
#app{display:flex;flex-direction:column;height:100%}
.topbar{
  height:var(--topbar-h);flex:none;display:flex;align-items:center;gap:12px;
  padding:0 16px;background:#0f172a;color:#e2e8f0;position:relative;z-index:40;
}
.brand{display:flex;align-items:center;gap:9px;font-weight:700;letter-spacing:.2px;white-space:nowrap}
.brand .logo{
  width:26px;height:26px;border-radius:8px;flex:none;
  background:linear-gradient(135deg,#3b82f6,#22d3ee);
  display:flex;align-items:center;justify-content:center;font-size:14px;
}
.brand .nm{font-size:15px}
.brand .vm{font-size:11px;font-weight:500;color:#94a3b8;margin-left:2px}
.tb-tag{
  font-size:11.5px;padding:3px 9px;border-radius:999px;white-space:nowrap;
  background:rgba(255,255,255,.10);color:#cbd5e1;
}
.tb-tag.admin{background:rgba(217,119,6,.22);color:#fcd34d}
.tb-tag.viewer{background:rgba(37,99,235,.24);color:#93c5fd}
.api-tag{display:inline-flex;align-items:center;padding:3px 9px;border-radius:999px;font-size:11px;font-weight:500;margin-left:6px;line-height:1.4;white-space:nowrap;cursor:default}
.api-tag.on{background:#dcfce7;color:#15803d;border:1px solid #86efac}
.api-tag.off{background:#fef3c7;color:#a16207;border:1px solid #fcd34d}
.tb-spacer{flex:1}
.tb-stat{
  font-size:12px;color:#cbd5e1;display:flex;align-items:center;gap:7px;
  padding:5px 11px;border-radius:999px;background:rgba(255,255,255,.07);white-space:nowrap;
}
.tb-stat b{color:#fff;font-variant-numeric:tabular-nums}
.dot{width:7px;height:7px;border-radius:50%;background:#22c55e;flex:none}
.dot.warn{background:#f59e0b} .dot.err{background:#ef4444}
.dot.pulse{animation:pl 1.8s ease-out infinite}
@keyframes pl{0%{box-shadow:0 0 0 0 rgba(34,197,94,.6)}70%{box-shadow:0 0 0 7px rgba(34,197,94,0)}100%{box-shadow:0 0 0 0 rgba(34,197,94,0)}}
.main{flex:1;display:flex;min-height:0;position:relative}

/* ---------- 地图容器 ----------
   isolation 让地图 SDK 内部的图层自成层叠上下文，避免它盖住悬浮控件与弹窗 */
.map-wrap{flex:1;position:relative;min-width:0;background:#e8eef5;isolation:isolate;z-index:1}
#map{position:absolute;inset:0}
.map-fallback{position:absolute;inset:0;display:none;z-index:1100;background:#eef3f8}
.map-fallback.on{display:block}
.map-tools{position:absolute;top:12px;left:12px;right:12px;z-index:1200;display:flex;flex-wrap:wrap;gap:8px;align-items:flex-start}
.map-legend{
  position:absolute;left:12px;bottom:12px;z-index:1200;background:rgba(255,255,255,.94);backdrop-filter:blur(6px);
  border-radius:var(--r);box-shadow:var(--shadow);padding:9px 12px;display:flex;gap:14px;font-size:11.5px;color:var(--text-2);flex-wrap:wrap
}
.lg{display:flex;align-items:center;gap:5px}
.lg i{width:9px;height:9px;border-radius:50%;display:inline-block}
/* v3.4.3:实时轨迹(实线) / 赛事轨迹(虚线) 的图例样式 —— 与实际线型一一对应 */
.lg i.lg-bar{width:18px;height:4px;border-radius:2px}
.lg i.lg-dash{
  width:18px;height:4px;border-radius:0;
  background-image:repeating-linear-gradient(90deg,currentColor 0 5px,rgba(0,0,0,0) 5px 9px)
}
.map-source{
  position:absolute;right:12px;bottom:12px;z-index:1200;font-size:11px;color:var(--text-3);
  background:rgba(255,255,255,.9);padding:4px 9px;border-radius:999px
}
.map-empty{
  /* 引导卡靠下摆放，给地图中心留出空间——未选赛事时会在地图中心标注「默认视野」，
     两者叠在一起会互相遮挡。底部留白避开图例与回放条。 */
  position:absolute;inset:0;z-index:1150;display:flex;align-items:flex-end;justify-content:center;
  pointer-events:none;padding:24px 24px 78px;
}
/* v3.4.3e:首屏功能引导（4 张可点击小卡片，替代原来的单张大卡） */
.map-empty .guide{
  pointer-events:auto;width:min(560px,100%);background:rgba(255,255,255,.97);
  backdrop-filter:blur(10px);border:1px solid var(--line);border-radius:16px;
  box-shadow:var(--shadow-lg);padding:15px 17px
}
.guide-h{display:flex;align-items:baseline;gap:10px;margin-bottom:11px}
.guide-h b{font-size:13.5px;letter-spacing:.2px}
.guide-h span{font-size:11.5px;color:var(--text-3)}
.guide-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
.guide-card{
  display:flex;align-items:flex-start;gap:9px;text-align:left;padding:9px 10px;
  border:1px solid var(--line);border-radius:11px;background:#fff;cursor:pointer;
  transition:transform .15s,border-color .15s,background .15s;
  font:inherit;color:inherit
}
.guide-card:hover{border-color:#bfdbfe;background:#f8fbff;transform:translateY(-1px)}
.guide-card:active{transform:none;background:#eff6ff}
.gc-ico{
  width:27px;height:27px;flex:none;display:grid;place-items:center;font-size:14px;
  border-radius:8px;background:#eff6ff;line-height:1
}
.gc-tx{display:flex;flex-direction:column;gap:2px;min-width:0}
.gc-tx b{font-size:12.5px;font-weight:600;color:var(--text)}
.gc-tx i{font-style:normal;font-size:11px;color:var(--text-3);line-height:1.35}
/* 引导卡点击后的"指向"动画：让用户的目光跟到对应的工具条按钮 */
@keyframes guidePulse{
  0%{box-shadow:0 0 0 0 rgba(31,111,235,.55)}
  70%{box-shadow:0 0 0 8px rgba(31,111,235,0)}
  100%{box-shadow:0 0 0 0 rgba(31,111,235,0)}
}
.hint-pulse{animation:guidePulse 1.1s ease-out 2}

.replay-bar{
  position:absolute;left:12px;right:12px;bottom:12px;z-index:1250;background:rgba(255,255,255,.97);
  border-radius:var(--r);box-shadow:var(--shadow-lg);padding:12px 16px;display:none;gap:14px;align-items:center
}
.replay-bar.on{display:flex}
.replay-bar input[type=range]{flex:1;accent-color:var(--brand)}
.rb-time{font-variant-numeric:tabular-nums;font-weight:600;font-size:13px;min-width:86px}
.rb-name{font-size:12.5px;color:var(--text-2);white-space:nowrap;max-width:230px;overflow:hidden;text-overflow:ellipsis}

/* 地图上的悬浮下拉（选赛事） */
.tool-card{
  background:rgba(255,255,255,.96);backdrop-filter:blur(6px);border-radius:var(--r);
  box-shadow:var(--shadow);padding:8px 10px;display:flex;align-items:center;gap:9px;max-width:min(560px,100%)
}
.tool-card .lb{font-size:11.5px;color:var(--text-3);white-space:nowrap}
.tool-btn{
  height:38px;padding:0 13px;border-radius:var(--r);background:rgba(255,255,255,.96);box-shadow:var(--shadow);
  font-size:12.5px;color:var(--text-2);display:flex;align-items:center;gap:6px;transition:.15s;white-space:nowrap
}
.tool-btn:hover{background:#fff;color:var(--text)}
.tool-btn.on{background:var(--brand);color:#fff}
.tool-btn[disabled]{opacity:.5;cursor:not-allowed}

/* ---------- 右侧面板 ---------- */
.panel{
  width:404px;flex:none;background:var(--surface);border-left:1px solid var(--line);
  display:flex;flex-direction:column;min-height:0;position:relative;z-index:30
}
.p-grab{display:none}
.p-scroll{flex:1;overflow:auto;padding:14px 16px 18px;min-height:0}
.p-foot{
  flex:none;display:flex;gap:9px;padding:11px 16px;border-top:1px solid var(--line);background:var(--surface)
}
.p-title{display:flex;align-items:center;justify-content:space-between;margin:0 0 10px}
.p-title h3{margin:0;font-size:13px}
.p-title .sub{font-size:11.5px;color:var(--text-3);font-weight:400;margin-left:5px}
.brand-hint{font-size:11.5px;color:var(--text-3)}

/* ---------- 通用控件 ---------- */
.btn{
  height:38px;padding:0 16px;border-radius:var(--r);font-size:13px;font-weight:600;
  display:inline-flex;align-items:center;justify-content:center;gap:6px;transition:.15s;background:var(--slate-soft);color:var(--text-2)
}
.btn:hover{background:#e8edf4}
.btn.pri{background:var(--brand);color:#fff}
.btn.pri:hover{background:var(--brand-2)}
.btn.gh{background:var(--surface);border:1px solid var(--line);color:var(--text-2)}
.btn.gh:hover{background:var(--surface-2)}
.btn.dg{background:var(--red);color:#fff}
.btn:disabled{opacity:.5;cursor:not-allowed}
.btn-sm{
  height:30px;padding:0 11px;border-radius:var(--r-sm);font-size:12px;font-weight:600;
  display:inline-flex;align-items:center;gap:5px;background:var(--brand);color:#fff;white-space:nowrap;transition:.15s
}
.btn-sm:hover{filter:brightness(1.06)}
.btn-sm.gh{background:var(--surface);border:1px solid var(--line);color:var(--text-2)}
.btn-sm.gh:hover{background:var(--surface-2)}
.btn-sm.dg{background:var(--red)}
.icon-btn{
  width:30px;height:30px;border-radius:8px;color:var(--text-3);flex:none;
  display:flex;align-items:center;justify-content:center;font-size:15px;transition:.15s
}
.icon-btn:hover{background:var(--slate-soft);color:var(--text)}
.inp,.sel{
  width:100%;height:38px;padding:0 11px;border-radius:var(--r-sm);border:1px solid var(--line);
  background:var(--surface);font-size:13px;outline:none;transition:.15s
}
.inp:focus,.sel:focus{border-color:#93c5fd;box-shadow:0 0 0 3px rgba(37,99,235,.12)}
textarea.inp{height:auto;min-height:120px;padding:9px 11px;resize:vertical;line-height:1.6;font-family:ui-monospace,Menlo,Consolas,monospace;font-size:12px}
.search{
  width:100%;height:36px;padding:0 11px;border-radius:var(--r-sm);border:1px solid var(--line);
  background:var(--surface);font-size:12.5px;outline:none;margin-bottom:10px
}
.search:focus{border-color:#93c5fd;box-shadow:0 0 0 3px rgba(37,99,235,.12)}
.field{margin-bottom:14px}
.field>label{display:block;font-size:12px;color:var(--text-2);margin-bottom:6px;font-weight:500}
.field .hint{font-size:11.5px;color:var(--text-3);margin-top:6px;line-height:1.6}
.filters{display:flex;gap:8px;margin-bottom:10px;flex-wrap:wrap}
.filters .sel{height:34px;font-size:12.5px}
.filters .btn-sm.gh.on{background:var(--brand);border-color:var(--brand);color:#fff}
.share-link{display:flex;gap:7px}
.share-link input{
  flex:1;height:34px;padding:0 10px;border-radius:var(--r-sm);border:1px solid var(--line);
  background:var(--surface-2);font-size:12px;color:var(--text-2);outline:none
}
.tag{
  font-size:11px;padding:2px 7px;border-radius:6px;background:var(--slate-soft);color:var(--slate);
  white-space:nowrap;font-weight:600;display:inline-block
}
.tag.ok{background:var(--green-soft);color:#15803d}
.tag.off{background:var(--slate-soft);color:var(--slate)}
.tag.warn{background:var(--amber-soft);color:#b45309}
.tag.err{background:var(--red-soft);color:#b91c1c}
.empty{
  padding:26px 14px;text-align:center;font-size:12.5px;color:var(--text-3);
  border:1px dashed var(--line);border-radius:var(--r);background:var(--surface-2)
}
.adm-note{
  font-size:11.5px;line-height:1.7;color:var(--text-2);background:var(--brand-soft);
  border:1px solid #dbeafe;border-radius:var(--r-sm);padding:9px 11px;margin-bottom:12px
}
.adm-note b{color:var(--brand-2)}

/* ---------- 赛事选择（普通用户） ---------- */
.event-select{position:relative;min-width:230px;flex:1;max-width:380px}
.event-select .sel{
  height:38px;background:rgba(255,255,255,.96);box-shadow:var(--shadow);border:none;
  font-size:12.5px;font-weight:600;padding-right:30px;cursor:pointer;
  /* 只保留自定义的 .arrow,去掉原生箭头(否则叠成两个 ⌄) */
  -webkit-appearance:none;appearance:none
}
.event-select .arrow{position:absolute;right:11px;top:50%;transform:translateY(-50%);pointer-events:none;color:var(--text-3);font-size:11px}

/* ---------- 跑者卡片 ---------- */
.r-card{
  display:flex;align-items:flex-start;gap:11px;padding:11px;border:1px solid var(--line);
  border-radius:var(--r);background:var(--surface);margin-bottom:9px;cursor:pointer;transition:.15s;position:relative
}
.r-card:hover{border-color:#c7dbff;box-shadow:var(--shadow)}
.r-card.on{border-color:var(--brand);background:var(--brand-soft)}
.r-card.muted{opacity:.62}
.r-ava{
  width:38px;height:38px;border-radius:50%;flex:none;color:#fff;font-weight:700;font-size:14px;
  display:flex;align-items:center;justify-content:center;position:relative
}
.r-ava .br{
  position:absolute;right:-3px;bottom:-3px;width:17px;height:17px;border-radius:50%;
  font-size:9.5px;font-style:normal;font-weight:700;color:#fff;display:flex;align-items:center;justify-content:center;
  border:2px solid var(--surface)
}
.br-garmin{background:var(--garmin)} .br-coros{background:var(--coros)} .br-self{background:var(--self)}
.r-body{flex:1;min-width:0}
.r-l1{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.r-name{font-weight:700;font-size:13.5px}
.r-team{font-size:10.5px;padding:2px 6px;border-radius:5px;font-weight:600}
.r-l2{display:flex;gap:12px;margin-top:5px;font-size:11.5px;color:var(--text-2);font-variant-numeric:tabular-nums;flex-wrap:wrap}
.r-l2 .k{color:var(--text-3)}
.r-upd{margin-left:auto;color:var(--text-3)}
.r-detail{display:none;margin:-6px 0 10px;padding:11px 12px;border:1px solid var(--line);border-radius:var(--r);background:var(--surface-2)}
.r-detail.on{display:block}
.r-grid{display:grid;grid-template-columns:1fr 1fr;gap:9px 14px}
.r-grid>div{display:flex;flex-direction:column;gap:2px;min-width:0}
.r-grid span{font-size:11px;color:var(--text-3)}
.r-grid b{font-size:12.5px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.seg-list{margin-top:10px;border-top:1px dashed var(--line);padding-top:8px}
.seg-list .sh{font-size:11px;color:var(--text-3);margin-bottom:4px}
.seg-row{display:flex;justify-content:space-between;padding:3px 0;font-size:11.5px;border-bottom:1px dashed var(--line-2);font-variant-numeric:tabular-nums}

/* ---------- 事件卡 ---------- */
.event-card{
  background:linear-gradient(135deg,#0f172a,#1e293b);color:#e2e8f0;border-radius:14px;
  padding:14px 16px;margin-bottom:14px
}
.event-card .ec-h{display:flex;align-items:center;gap:8px;margin-bottom:9px}
.event-card .ec-n{font-size:15px;font-weight:700;color:#fff;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.event-card .ec-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px 14px}
.event-card .ec-grid>div{display:flex;flex-direction:column;gap:2px}
.event-card .ec-grid span{font-size:10.5px;color:#94a3b8}
.event-card .ec-grid b{font-size:13px;font-weight:600;font-variant-numeric:tabular-nums}
.progress-line{height:5px;border-radius:999px;background:rgba(255,255,255,.14);overflow:hidden;margin-top:11px}
.progress-line i{display:block;height:100%;background:linear-gradient(90deg,#3b82f6,#22d3ee);width:0;transition:width .6s}
.live-pill{
  font-size:10.5px;font-weight:700;padding:2px 8px;border-radius:999px;
  background:rgba(34,197,94,.2);color:#4ade80;display:inline-flex;align-items:center;gap:5px
}
/* v3.5.0:按公里连续绘制的海拔趋势图 */
.ele-card{
  background:var(--surface);border:1px solid var(--line);border-radius:12px;
  padding:10px 11px 7px;margin-bottom:14px
}
.ele-head{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;margin-bottom:2px}
.ele-head b{font-size:12.5px;color:var(--text)}
.ele-head span{font-size:10.5px;color:var(--text-3);font-variant-numeric:tabular-nums}
.ele-svg{display:block;width:100%;height:auto;overflow:visible}
.ele-legend{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:1px}
.ele-legend>span{display:inline-flex;align-items:center;font-size:10px;color:var(--text-2)}
.ele-legend i{display:inline-block;width:11px;height:3px;border-radius:2px;margin-right:4px}

/* ---------- 管理端 ---------- */
.adm-tabs{
  flex:none;display:flex;gap:4px;padding:10px 14px 0;border-bottom:1px solid var(--line);
  background:var(--surface);overflow-x:auto
}
.adm-tabs button{
  padding:9px 13px;font-size:12.5px;color:var(--text-2);border-radius:8px 8px 0 0;
  border-bottom:2px solid transparent;white-space:nowrap;transition:.15s;font-weight:500
}
.adm-tabs button:hover{background:var(--surface-2)}
.adm-tabs button.on{color:var(--brand);border-bottom-color:var(--brand);font-weight:700;background:var(--brand-soft)}
.adm-tabs .cnt{
  display:inline-block;min-width:17px;padding:0 5px;margin-left:5px;border-radius:999px;
  background:var(--slate-soft);color:var(--slate);font-size:10.5px;font-weight:700
}
.adm-tabs button.on .cnt{background:#dbeafe;color:var(--brand-2)}
.adm-body{padding:16px}
.adm-head{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:12px}
.adm-head h3{margin:0;font-size:15px}
.rt-card{
  display:flex;align-items:flex-start;gap:11px;padding:12px;border:1px solid var(--line);
  border-radius:var(--r);background:var(--surface);margin-bottom:9px;position:relative;transition:.15s
}
.rt-card:hover{border-color:#c7dbff;box-shadow:var(--shadow)}
.rt-c{width:4px;align-self:stretch;border-radius:999px;flex:none}
.rt-main{flex:1;min-width:0}
.rt-n{font-size:13.5px;font-weight:700;display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.rt-m{display:flex;gap:14px;margin-top:6px;font-size:11.5px;color:var(--text-2);flex-wrap:wrap;font-variant-numeric:tabular-nums}
.rt-m .k{color:var(--text-3);font-style:normal;margin-right:3px}
.rt-ref{font-size:11px;color:var(--text-3);margin-top:6px}
.menu{
  position:absolute;right:8px;top:40px;z-index:60;background:#fff;border:1px solid var(--line);
  border-radius:10px;box-shadow:var(--shadow-lg);padding:5px;min-width:186px;display:none
}
.menu.on{display:block}
.menu button{
  display:flex;align-items:center;gap:8px;width:100%;padding:8px 10px;border-radius:7px;
  font-size:12.5px;color:var(--text-2);text-align:left;transition:.12s
}
.menu button:hover{background:var(--surface-2);color:var(--text)}
.menu button.dg{color:var(--red)}
.menu button.dg:hover{background:var(--red-soft)}
.menu hr{border:none;border-top:1px solid var(--line-2);margin:4px 2px}
.rec-card{
  display:flex;align-items:flex-start;gap:11px;padding:11px;border:1px solid var(--line);
  border-radius:var(--r);background:var(--surface);margin-bottom:8px;position:relative
}
.rec-dot{
  width:34px;height:34px;border-radius:50%;flex:none;color:#fff;font-weight:700;font-size:13px;
  display:flex;align-items:center;justify-content:center
}
.rec-main{flex:1;min-width:0}
.rec-l1{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.rec-n{font-weight:700;font-size:13px}
.rec-m{display:flex;gap:12px;margin-top:5px;font-size:11.5px;color:var(--text-2);flex-wrap:wrap;font-variant-numeric:tabular-nums}
.src-card{border:1px solid var(--line);border-radius:var(--r);background:var(--surface);padding:13px;margin-bottom:10px}
.src-h{display:flex;align-items:center;gap:9px;margin-bottom:11px}
.src-logo{
  width:32px;height:32px;border-radius:9px;color:#fff;font-weight:700;font-size:13px;flex:none;
  display:flex;align-items:center;justify-content:center
}
.src-n{font-weight:700;font-size:13.5px;flex:1;min-width:0}
.src-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:9px}
.src-grid>div{display:flex;flex-direction:column;gap:2px}
.src-grid span{font-size:10.5px;color:var(--text-3)}
.src-grid b{font-size:12.5px;font-weight:600;font-variant-numeric:tabular-nums}
.expire{
  display:flex;align-items:center;gap:8px;margin-top:11px;font-size:11.5px;color:#b45309;
  background:var(--amber-soft);border-radius:var(--r-sm);padding:8px 11px
}
.alert-row{
  display:flex;align-items:center;gap:10px;padding:10px 11px;border:1px solid #fed7aa;
  background:#fffbeb;border-radius:var(--r);margin-bottom:8px
}
.a-t{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.a-t b{font-size:12.5px}
.a-t span{font-size:11.5px;color:var(--text-2)}
.drop{
  border:1.5px dashed #c7d2fe;border-radius:var(--r);background:var(--brand-soft);
  padding:20px 16px;text-align:center;transition:.15s;cursor:pointer
}
.drop:hover,.drop.over{border-color:var(--brand);background:#e6efff}
.drop .ico{font-size:26px;line-height:1}
.drop .t{font-size:13px;font-weight:700;margin:8px 0 4px}
.drop .s{font-size:11.5px;color:var(--text-2);line-height:1.7}
.file-pill{
  display:flex;align-items:center;gap:9px;margin-top:11px;padding:9px 11px;border:1px solid #bbf7d0;
  background:var(--green-soft);border-radius:var(--r-sm);font-size:12px;color:#15803d
}
.file-pill b{font-weight:700}
.file-pill .x{margin-left:auto;color:#15803d;opacity:.7}
.st-row{display:flex;gap:8px;align-items:center;margin-bottom:7px}
.st-row .inp{height:34px;font-size:12.5px}
.st-row .inp.nm{flex:2} .st-row .inp.km{flex:1;max-width:110px}
/* 站点类型图标(GPX 派生 / admin 编辑) */
.st-type{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:6px;font-size:13px;flex:none}
.st-type-label{font-size:11.5px;color:#64748b;flex:none;min-width:30px}
.st-type-start{background:#fee2e2;color:#b91c1c}
.st-type-finish{background:#dbeafe;color:#1d4ed8}
.st-type-cp{background:#fef3c7;color:#a16207}
.st-type-aid{background:#dcfce7;color:#15803d}
.st-type-waypoint{background:#ede9fe;color:#6d28d9}
.st-type-other{background:#f1f5f9;color:#475569}
.parse-box{margin-top:12px}
.parse-ok{
  font-size:12px;line-height:1.75;color:#15803d;background:var(--green-soft);
  border:1px solid #bbf7d0;border-radius:var(--r-sm);padding:10px 12px
}
.parse-warn{
  font-size:12px;line-height:1.75;color:#b45309;background:var(--amber-soft);
  border:1px solid #fde68a;border-radius:var(--r-sm);padding:10px 12px
}
.parse-err{
  font-size:12px;line-height:1.75;color:#b91c1c;background:var(--red-soft);
  border:1px solid #fecaca;border-radius:var(--r-sm);padding:10px 12px
}
.kv{display:grid;grid-template-columns:1fr 1fr;gap:9px 14px;margin-top:11px}
.kv>div{display:flex;flex-direction:column;gap:2px}
.kv span{font-size:11px;color:var(--text-3)}
.kv b{font-size:12.5px;font-variant-numeric:tabular-nums}
.kv.kv3{grid-template-columns:1fr 1fr 1fr}
.rec-tbl{width:100%;border-collapse:collapse;margin-top:9px}
.rec-tbl th,.rec-tbl td{padding:9px 8px;border-bottom:1px solid var(--line);vertical-align:middle;text-align:left;font-size:12.5px}
.rec-tbl thead th{font-size:11.5px;color:var(--text-3);font-weight:600}

/* ---------- 失效分享链接拦截层（index.html FR-USR-S04） ---------- */
.link-expired{
  position:fixed;inset:0;z-index:4500;background:rgba(15,23,42,.62);display:flex;
  align-items:center;justify-content:center;padding:20px;backdrop-filter:blur(3px)
}
.link-expired[hidden]{display:none}
.le-card{
  background:#fff;border-radius:14px;box-shadow:0 20px 60px rgba(15,23,42,.35);
  max-width:480px;width:100%;padding:28px 28px 22px;text-align:center
}
.le-ico{font-size:42px;line-height:1;margin-bottom:8px}
.le-card h2{margin:0 0 10px;font-size:18px;color:#0f172a}
.le-reason{font-size:13.5px;color:#b91c1c;background:var(--red-soft);
  border:1px solid #fecaca;border-radius:9px;padding:9px 12px;margin-bottom:10px}
.le-time{font-size:12px;color:var(--text-3);margin-bottom:12px;font-variant-numeric:tabular-nums}
.le-hint{font-size:12.5px;color:var(--text-2);line-height:1.7;margin-bottom:18px}
.le-actions{display:flex;gap:10px;justify-content:center;align-items:center;margin-bottom:14px}
.le-actions .btn.pri{font-size:13px;padding:8px 14px}
.le-actions .btn-sm.gh{font-size:12.5px}
.le-doc{font-size:11px;color:var(--text-3);line-height:1.6;border-top:1px solid var(--line);padding-top:10px}
.le-doc code{background:var(--slate-soft);padding:1px 5px;border-radius:4px;font-size:10.5px}
body.gate-on #app{filter:grayscale(.4) blur(1px);pointer-events:none;user-select:none}
.step-list{counter-reset:s;margin:0;padding:0;list-style:none}
.step-list li{counter-increment:s;position:relative;padding:0 0 11px 26px;font-size:12px;line-height:1.7;color:var(--text-2)}
.step-list li:before{
  content:counter(s);position:absolute;left:0;top:0;width:18px;height:18px;border-radius:50%;
  background:var(--brand);color:#fff;font-size:10.5px;font-weight:700;display:flex;align-items:center;justify-content:center
}

/* ---------- 弹窗 / 提示 ---------- */
.mask{
  position:fixed;inset:0;background:rgba(15,23,42,.45);z-index:4000;display:none;
  align-items:center;justify-content:center;padding:20px;backdrop-filter:blur(2px)
}
.mask.on{display:flex}
.dlg{
  background:var(--surface);border-radius:16px;box-shadow:var(--shadow-lg);width:100%;max-width:480px;
  max-height:calc(100vh - 40px);display:flex;flex-direction:column;animation:dlgIn .18s ease-out
}
.dlg.wide{max-width:760px}
@keyframes dlgIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
.dlg-h{display:flex;align-items:center;gap:10px;padding:15px 18px;border-bottom:1px solid var(--line)}
.dlg-h h4{margin:0;font-size:14.5px;flex:1;min-width:0}
.dlg-h .x{width:28px;height:28px;border-radius:8px;font-size:18px;line-height:1;color:var(--text-3);display:flex;align-items:center;justify-content:center}
.dlg-h .x:hover{background:var(--slate-soft);color:var(--text)}
.dlg-b{padding:16px 18px;overflow:auto;min-height:0}
.dlg-f{display:flex;justify-content:flex-end;gap:9px;padding:13px 18px;border-top:1px solid var(--line);flex-wrap:wrap}
.qr{display:block;margin:14px auto 0;width:150px;height:150px;border:1px solid var(--line);border-radius:10px}
.qr-cap{text-align:center;font-size:11.5px;color:var(--text-3);margin-top:8px}
.status-pill{
  font-size:10.5px;font-weight:700;padding:2px 7px;border-radius:999px;white-space:nowrap
}
.status-pill.active{background:var(--green-soft);color:#15803d}
.status-pill.delayed{background:var(--amber-soft);color:#b45309}
.status-pill.pending{background:var(--slate-soft);color:var(--slate)}
.status-pill.ended{background:#e2e8f0;color:#475569}
.status-pill.err{background:var(--red-soft);color:#b91c1c}

/* ---------- 管理台登录闸门（独立账号） ---------- */
.login-gate{
  position:fixed;inset:0;z-index:6000;display:flex;align-items:center;justify-content:center;padding:20px;
  background:linear-gradient(135deg,#0b1220 0%,#16294a 52%,#0b1220 100%)
}
.login-card{
  width:100%;max-width:372px;background:var(--surface);border-radius:16px;padding:26px 24px 22px;
  box-shadow:0 30px 70px -24px rgba(0,0,0,.65)
}
.login-card .lg-logo{
  width:52px;height:52px;border-radius:14px;background:var(--brand);margin:0 auto 14px;
  display:flex;align-items:center;justify-content:center;font-size:26px
}
.login-card h2{margin:0;font-size:16px;text-align:center;letter-spacing:.2px}
.login-card .lg-sub{margin:6px 0 18px;font-size:12px;color:var(--text-3);text-align:center}
.login-card .btn.pri{width:100%;margin-top:4px}
.lg-hint{margin-top:13px;font-size:11.5px;color:var(--text-3);line-height:1.65;text-align:center}
.lg-err{
  margin-top:12px;padding:8px 11px;border-radius:8px;font-size:12px;
  background:var(--red-soft);border:1px solid #fecaca;color:#b91c1c
}
.lg-row{margin-top:10px;text-align:center;font-size:12px}
.lg-row a{color:var(--brand-2);text-decoration:none}
.lg-row a:hover{text-decoration:underline}
.lg-mail{margin-top:9px;font-size:11.5px;color:var(--text-3);text-align:center;line-height:1.6}
.lg-mail b{color:var(--text-2);font-weight:600;letter-spacing:.1px}

/* ---------- 赛事下的组别 / 多轨迹 ---------- */
.grp-row{
  border:1px solid var(--line);border-radius:var(--r);padding:12px;margin-bottom:11px;background:var(--surface-2)
}
.grp-h{display:flex;align-items:center;gap:8px;margin-bottom:9px}
.grp-h .inp{flex:1;min-width:0}
.grp-tracks{margin-top:9px;display:flex;flex-direction:column;gap:8px}
.trk-block{border:1px solid var(--line-2);border-radius:var(--r-sm);background:var(--surface);padding:9px 10px}
.trk-st-rows{margin-top:7px}
.grp-row .drop{padding:14px 12px}
.grp-row .drop .ico{font-size:20px}

/* 赛事卡上的组别小标签 */
.gchips{display:flex;flex-wrap:wrap;gap:6px;margin-top:7px}
.gchip{
  display:inline-flex;align-items:center;gap:5px;font-size:11px;padding:2px 7px;border-radius:999px;
  background:var(--slate-soft);color:var(--text-2);white-space:nowrap
}
.gchip i{width:8px;height:8px;border-radius:2px;flex:none}
.gchip em{font-style:normal;color:var(--text-3)}

/* ---------- 移动端 ----------
   v3.4.3b:手机端从「面板固定占 54% 高度」改成「可拖拽的底部抽屉 + 地图优先」:
     · 三档高度 peek(约 200px) / half(52vh) / full(84vh),抓手上滑/下滑吸附切换;
     · peek 态只留一行赛事摘要 + 跑者卡,地图能拿到 ~65% 的竖向空间;
     · 抽屉高度变化时 index.html 会调 R4JMap.resize() 让腾讯地图重算画布尺寸。 */
.p-grab{
  display:none;height:26px;flex:none;align-items:center;justify-content:center;
  cursor:grab;background:var(--surface);position:relative;touch-action:none;
  border-radius:16px 16px 0 0;
}
.p-grab i{width:38px;height:4px;border-radius:999px;background:#cbd5e1;transition:background .15s}
.p-grab:active i,.panel.dragging .p-grab i{background:#94a3b8}
.p-grab .pg-tip{
  position:absolute;right:14px;top:50%;transform:translateY(-50%);
  font-size:10.5px;color:#94a3b8;letter-spacing:.2px
}
/* 抽屉收起态的一行赛事摘要(展开后由 #evCard 的完整赛事卡接管) */
.p-sheet-mini{
  display:none;flex:none;padding:2px 14px 6px;font-size:11.5px;color:#64748b;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;background:var(--surface)
}
.p-sheet-mini b{color:var(--text);font-weight:700}

@media (max-width:880px){
  :root{--topbar-h:50px}
  /* 竖排:地图先吃满剩余空间,抽屉固定高度钉在底部 */
  .main{flex-direction:column}
  .map-wrap{flex:1 1 auto;min-height:0}
  .panel{
    position:relative;left:auto;right:auto;bottom:auto;top:auto;
    width:auto;flex:none;height:clamp(206px,29vh,272px);
    height:clamp(206px,29dvh,272px);   /* dvh:iPhone 地址栏展开/收起时不留黑边 */
    border-left:none;border-top:1px solid var(--line);
    border-radius:16px 16px 0 0;
    box-shadow:0 -12px 40px -20px rgba(15,23,42,.4);
    transition:height .24s cubic-bezier(.32,.72,0,1);
    z-index:35;overflow:hidden;
  }
  .panel.dragging{transition:none}
  .panel[data-sheet="half"]{height:52vh;height:52dvh}
  .panel[data-sheet="full"]{height:84vh;height:84dvh}
  .panel.full{height:84vh;height:84dvh}   /* 兼容展厅模式等旧路径 */

  .p-grab{display:flex}
  .p-sheet-mini{display:block}
  /* 抽屉拉满时地图只剩一条缝,工具条/图例摆上去只会互相压叠 → 收起 */
  body[data-sheet="full"] .map-tools,
  body[data-sheet="full"] .map-legend{display:none}
  .panel[data-sheet="half"] .p-sheet-mini,
  .panel[data-sheet="full"] .p-sheet-mini{display:none}
  .p-scroll{padding:8px 12px 12px}
  .p-foot{padding:8px 12px;gap:8px}
  .p-foot .btn{height:34px;flex:1;font-size:12.5px;padding:0 8px}
  /* 跑者卡第二行:赛事名 + LiveTrack 长 URL 在手机上必须单行省略,
     否则 URL 折成两行会把卡片撑高一倍 */
  .lr-l2{min-width:0}
  .lr-l2>span,.lr-l2>a{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .lr-l2>a{flex:1}

  /* 顶栏:只保留必要信息,少占一行高度 */
  .topbar{padding:0 10px;gap:8px}
  .brand .nm{font-size:13px}
  .brand .vm,.tb-tag{display:none}
  .tb-stat{font-size:11px;padding:4px 8px;gap:5px}
  /* 手机状态栏本来就有时间,页面里的时钟纯占位;连接态文字限宽避免把顶栏撑破 */
  #clock{display:none}
  .tb-stat #connText{
    display:inline-block;max-width:74px;overflow:hidden;
    text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom
  }
  /* 地图工具条:单行横向滚动,不再换行把小地图挤扁。
     v3.4.3d 关键:两个下拉必须**可收缩**。原来 .event-select 的 max-width:56vw 是"每个"
     下拉的上限,选了赛事出现「组别」后 56vw+56vw 直接超宽 → 后面的
     「我的位置/全览/回放」被挤出可视区(看起来就是按钮消失了)。
     现在:下拉卡片 flex:1 1 0 + min-width:0 让它俩平分剩余宽度,
     三个图标按钮 flex:none 永远留在右端。 */
  .map-tools{
    left:8px;right:8px;top:8px;gap:6px;flex-wrap:nowrap;
    overflow-x:auto;scrollbar-width:none
  }
  .map-tools::-webkit-scrollbar{display:none}
  .tool-card{padding:5px 8px;flex:0 1 auto;min-width:0;max-width:none}
  /* 组别下拉固定窄宽(只放「全部组别」/组别名),剩余宽度全部让给赛事名。
     不能用 width:auto —— 原生 select 按**最长 option** 取宽,组名一长就把赛事名挤没。 */
  #grpCard{flex:none;width:106px}
  #grpCard .event-select{flex:none;width:100%}
  #grpCard .sel{width:100%;max-width:100%;padding-right:20px}
  .tool-card .lb{display:none}
  .tool-card .event-select{flex:1;width:100%;min-width:0;max-width:none}
  .event-select .sel{height:34px;font-size:12px;width:100%;max-width:100%}
  .tool-btn{height:34px;padding:0 9px;font-size:11.5px;flex:none}
  .tool-btn span{display:none}        /* 只留图标,横向空间留给赛事下拉 */
  /* 图例:手机上不允许换行(换行会叠成 2~3 行盖住轨迹),单行横向滑动;
     「信号弱 / 站点」这两项在手机上略去,把宽度让给组别图例 */
  .map-legend{
    gap:10px;font-size:10px;padding:5px 9px;left:8px;bottom:8px;
    max-width:calc(100% - 16px);flex-wrap:nowrap;overflow-x:auto;
    white-space:nowrap;scrollbar-width:none
  }
  .map-legend::-webkit-scrollbar{display:none}
  .map-legend .lg-opt{display:none}
  .map-source{display:none}
  /* 首屏引导卡:手机地图本来就矮,压成 2×2 小卡 + 单行说明 */
  .map-empty{padding:10px 10px 60px}
  .map-empty .guide{padding:11px 12px;border-radius:13px}
  .guide-h{margin-bottom:8px}
  .guide-h b{font-size:12.5px}
  .guide-h span{display:none}
  .guide-grid{gap:6px}
  .guide-card{padding:7px 8px;gap:7px;border-radius:9px}
  .gc-ico{width:23px;height:23px;font-size:12px;border-radius:6px}
  .gc-tx b{font-size:11.5px}
  .gc-tx i{
    font-size:10px;line-height:1.3;
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap
  }

  /* 赛事卡:7 项指标改成 4 列 × 2 行(390px 宽下「2026-10-18」也放得下),
     高度从 ~272px 压到 ~150px —— 展开抽屉后也能一眼看到跑者列表 */
  .event-card{padding:12px 14px;margin-bottom:10px;border-radius:12px}
  .event-card .ec-h{margin-bottom:7px}
  .event-card .ec-n{font-size:14px}
  .event-card .ec-grid{grid-template-columns:repeat(4,minmax(0,1fr));gap:7px 8px}
  .event-card .ec-grid span{font-size:9.5px}
  .event-card .ec-grid b{font-size:12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .event-card .progress-line{margin-top:9px}

  /* 抽屉收起态:赛事卡收起(信息由 .p-sheet-mini 一行承载),筛选条也收起 */
  .panel[data-sheet="peek"] #evCard{display:none}
  /* v3.5.1:海拔趋势图同样只在展开(half)/全屏(full)显示 —— 收起态高度只有 ~210px,
     要塞下赛事摘要+跑者列表,再放一张图会把实时列表挤没 */
  .panel[data-sheet="peek"] #eleCard{display:none}
  .panel[data-sheet="peek"] #rFilters{display:none}
  .panel[data-sheet="peek"] .p-scroll{padding:0 10px 10px}
  .panel[data-sheet="peek"] .p-title{margin:2px 0 6px}
  .panel[data-sheet="peek"] .lr-item{padding:7px 9px}
  .panel[data-sheet="peek"] .lr-l2{display:none}     /* 赛事名/长 URL 在收起态不展示 */
  .panel[data-sheet="peek"] .lr-l3{margin-top:3px;padding-top:3px;gap:2px 8px}
  .panel[data-sheet="peek"] .lr-empty{padding:10px 8px;font-size:11.5px}
}

/* v3.1 · 跟踪记录横条(公开只读面板) */
.track-strip{background:#fff;border-bottom:1px solid var(--line);padding:8px 16px;display:flex;flex-direction:column;gap:6px;animation:slide-down .22s ease}
.track-strip[hidden]{display:none}
@keyframes slide-down{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:translateY(0)}}
.ts-head{display:flex;align-items:baseline;gap:10px;font-size:13px}
.ts-title{font-weight:600;color:#0f172a}
.ts-title #tsScope{color:#475569;font-weight:500}
.ts-sub{color:#64748b;font-size:11.5px;margin-left:auto}
.ts-body{display:flex;gap:8px;overflow-x:auto;padding-bottom:2px}
.ts-card{display:flex;flex-direction:column;gap:3px;padding:7px 12px;border:1px solid var(--line);border-radius:8px;min-width:180px;max-width:280px;flex:none;background:#f8fafc;transition:background .15s}
.ts-card:hover{background:#eff6ff;border-color:#93c5fd}
.ts-card .ts-name{font-weight:600;color:#0f172a;font-size:13px;display:flex;align-items:center;gap:5px}
.ts-card .ts-meta{font-size:11.5px;color:#64748b;display:flex;gap:8px}
.ts-card .ts-meta .ev{background:#dbeafe;color:#1d4ed8;padding:1px 6px;border-radius:4px;font-size:10.5px}
.ts-card a{color:#2563eb;text-decoration:none;word-break:break-all;font-size:11.5px}
.ts-card a:hover{text-decoration:underline}
.ts-empty{padding:14px;color:#94a3b8;font-size:12.5px;text-align:center}
.ts-brand-garmin{color:#1f6feb}
.ts-brand-coros{color:#ff6a00}
.ts-brand-manual{color:#64748b}

/* ==== v3.1.2 实时位置列表(右侧栏) ==== */
.live-runner-list{display:flex;flex-direction:column;gap:6px;padding:4px 0 8px}
.lr-item{display:flex;align-items:center;gap:9px;padding:8px 10px;border-radius:8px;background:#fff;border:1px solid #e2e8f0;cursor:pointer;transition:.12s}
.lr-item:hover{border-color:#94a3b8;background:#f8fafc}
.lr-item.is-focus{border-color:#2563eb;background:#eff6ff;box-shadow:0 0 0 1px #2563eb}
.lr-item.is-dim{opacity:.35}
.lr-avatar{width:30px;height:30px;border-radius:50%;display:flex;align-items:center;justify-content:center;color:#fff;font-weight:700;font-size:13px;flex:none;border:2px solid #fff;box-shadow:0 1px 3px rgba(0,0,0,.18)}
.lr-main{flex:1;min-width:0}
.lr-l1{display:flex;align-items:center;gap:6px;font-size:13px}
.lr-n{font-weight:600;color:#0f172a;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lr-tag{font-size:10px;padding:1px 5px;border-radius:4px;font-weight:600;flex:none}
.lr-tag-garmin{background:#dbeafe;color:#1f6feb}
.lr-tag-coros{background:#ffedd5;color:#ea580c}
.lr-tag-manual{background:#e2e8f0;color:#475569}
.lr-tag-live{background:#dcfce7;color:#16a34a}
.lr-tag-wait{background:#f1f5f9;color:#64748b}
.lr-tag-stale{background:#fef3c7;color:#b45309;animation:pulse-stale 2s infinite}
@keyframes pulse-stale{0%,100%{opacity:1}50%{opacity:.65}}
.lr-l2{font-size:11px;color:#64748b;margin-top:2px;display:flex;gap:8px;align-items:center}
.lr-l2 a{color:#2563eb;text-decoration:none;word-break:break-all}
.lr-l2 a:hover{text-decoration:underline}
.lr-pos{font-size:10.5px;color:#94a3b8}
/* v3.4.3:跑者卡实时数据行 —— 距离 / 配速 / 心率 / 最后更新 */
.lr-l3{display:flex;flex-wrap:wrap;align-items:center;gap:3px 10px;margin-top:5px;padding-top:5px;border-top:1px dashed #e2e8f0;font-size:11px;color:#334155}
.lr-l3 .lr-m{display:inline-flex;align-items:baseline;gap:3px;white-space:nowrap}
.lr-l3 .lr-m b{font-weight:600;font-size:10px;color:#94a3b8}
.lr-l3 .lr-ago{margin-left:auto;color:#64748b}
.lr-l3 .lr-ago.is-stale{color:#b45309}
.lr-empty{padding:14px;color:#94a3b8;font-size:12.5px;text-align:center;background:#f8fafc;border-radius:6px;border:1px dashed #cbd5e1}
.p-title .btn-sm{margin-left:6px;vertical-align:middle}

/* v3.4.3g：admin 页面过期提示条（后台已部署新版，但当前标签页仍是旧版） */
.ver-bar{
  position:fixed;left:0;right:0;top:0;z-index:9999;display:flex;align-items:center;gap:10px;
  justify-content:center;flex-wrap:wrap;
  padding:9px 14px;background:#b45309;color:#fff;font-size:12.5px;line-height:1.4;
  box-shadow:0 2px 10px rgba(0,0,0,.18)
}
.ver-bar[hidden]{display:none}
.ver-bar button{
  flex:none;padding:5px 12px;border:none;border-radius:6px;cursor:pointer;
  background:#fff;color:#b45309;font-size:12px;font-weight:700
}
.ver-bar button:hover{background:#fef3c7}
