/* ============================================================
   CARTO — App Atlas. Design system derived from Revyl Atlas.
   ============================================================ */
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&family=Space+Grotesk:wght@400;500;600;700&display=swap');

:root {
  /* surfaces */
  --bg:        #0a0a0b;
  --bg-2:      #0c0c0e;
  --canvas:    #08080a;
  --panel:     #0e0e12;
  --panel-2:   #131318;
  --raised:    #17171d;
  --hover:     #1c1c23;

  /* lines */
  --line:      rgba(255,255,255,.07);
  --line-2:    rgba(255,255,255,.12);
  --line-3:    rgba(255,255,255,.20);

  /* text */
  --t-hi:      #ededf0;
  --t:         #c3c3c9;
  --t-dim:     #84848d;
  --t-faint:   #56565e;

  /* accent — violet */
  --acc:       #8b7cf6;
  --acc-hi:    #a99bff;
  --acc-dim:   #6d5dd3;
  --acc-deep:  #4b3fa0;
  --acc-glow:  rgba(139,124,246,.35);
  --acc-soft:  rgba(139,124,246,.12);

  /* node accents */
  --n-green:   #5bd06a;
  --n-blue:    #2eb6f0;
  --n-pink:    #ff5b96;
  --n-amber:   #f5b945;
  --n-teal:    #34d3c0;
  --n-violet:  #9b7cf6;
  --n-red:     #f0625b;

  --ok:        #5bd06a;

  --mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, "PingFang SC", monospace;
  --sans: "Space Grotesk", -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", sans-serif;

  --r-sm: 4px;
  --r:    7px;
  --r-lg: 12px;
}

:root[data-theme="light"] {
  --bg:        #f5f5f8;
  --bg-2:      #ffffff;
  --canvas:    #ececf1;
  --panel:     #ffffff;
  --panel-2:   #f4f4f8;
  --raised:    #e9e9ef;
  --hover:     #e2e2ea;
  --line:      rgba(20,18,40,.09);
  --line-2:    rgba(20,18,40,.16);
  --line-3:    rgba(20,18,40,.28);
  --t-hi:      #16161c;
  --t:         #3a3a44;
  --t-dim:     #6c6c78;
  --t-faint:   #9a9aa6;
  --acc-soft:  rgba(109,93,211,.12);
}

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body {
  background: var(--bg);
  color: var(--t);
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow: hidden;
}
#root { height: 100vh; }

::selection { background: var(--acc-glow); color: #fff; }

/* ---- typography helpers ---- */
.mono { font-family: var(--mono); }
.eyebrow {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--t-dim);
  font-weight: 500;
  white-space: nowrap;
}
.num { font-family: var(--mono); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ---- category pill ---- */
.pill {
  display: inline-flex;
  align-items: center;
  height: 18px;
  padding: 0 7px;
  border-radius: var(--r-sm);
  background: var(--raised);
  border: 1px solid var(--line);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .12em;
  font-weight: 600;
  color: var(--t-dim);
  text-transform: uppercase;
  white-space: nowrap;
}

/* ---- buttons ---- */
.btn {
  display: inline-flex; align-items: center; gap: 8px; white-space: nowrap;
  height: 38px; padding: 0 18px;
  border-radius: var(--r);
  border: 1px solid var(--line-2);
  background: var(--raised);
  color: var(--t-hi);
  font-family: var(--mono);
  font-size: 12px; letter-spacing: .04em; font-weight: 500;
  cursor: pointer;
  transition: background .15s, border-color .15s, transform .05s;
  user-select: none;
}
.btn:hover { background: var(--hover); border-color: var(--line-3); }
.btn:active { transform: translateY(1px); }
.btn-primary {
  background: linear-gradient(180deg, #9684ff, var(--acc-dim));
  border-color: transparent;
  color: #fff;
  box-shadow: 0 0 0 1px var(--acc-deep), 0 8px 24px -8px var(--acc-glow);
}
.btn-primary:hover { background: linear-gradient(180deg, #a596ff, #7666e0); }
.btn-ghost { background: transparent; border-color: var(--line); }
.btn-ghost:hover { background: var(--panel-2); }
.btn:disabled { opacity: .4; cursor: not-allowed; }

/* ---- segmented progress (journey cards) ---- */
.seg { display: flex; gap: 3px; }
.seg i {
  height: 4px; flex: 1; border-radius: 2px;
  background: var(--raised);
}
.seg i.on { background: var(--acc); }

/* ---- scrollbars ---- */
*::-webkit-scrollbar { width: 9px; height: 9px; }
*::-webkit-scrollbar-thumb { background: #26262e; border-radius: 6px; border: 2px solid transparent; background-clip: padding-box; }
*::-webkit-scrollbar-thumb:hover { background: #34343e; background-clip: padding-box; }
*::-webkit-scrollbar-track { background: transparent; }

/* ---- top bar ---- */
.topbar {
  height: 52px; flex: 0 0 52px;
  display: flex; align-items: center;
  padding: 0 18px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-2);
  position: relative; z-index: 30;
}
.crumb { display: flex; align-items: center; gap: 9px; font-family: var(--mono); font-size: 12px; }
.crumb .sep { color: var(--t-faint); }
.crumb .brand { color: var(--t-hi); font-weight: 600; letter-spacing: .12em; }
.crumb .acc { color: var(--acc-hi); font-weight: 600; letter-spacing: .1em; }
.crumb .app { color: var(--t-hi); font-weight: 600; font-family: var(--sans); letter-spacing: .01em; }

.tabs { display: flex; gap: 2px; background: var(--panel); border: 1px solid var(--line); border-radius: var(--r); padding: 3px; }
.tab {
  height: 28px; padding: 0 16px; display: flex; align-items: center; white-space: nowrap;
  font-family: var(--mono); font-size: 11px; letter-spacing: .14em; font-weight: 500;
  color: var(--t-dim); border-radius: var(--r-sm); cursor: pointer; text-transform: uppercase;
  transition: color .15s, background .15s;
}
.tab:hover { color: var(--t); }
.tab.on { background: var(--acc-soft); color: var(--acc-hi); box-shadow: inset 0 0 0 1px rgba(139,124,246,.25); }

.stat { display: flex; align-items: baseline; gap: 7px; }
.stat .k { font-family: var(--mono); font-size: 10px; letter-spacing: .16em; color: var(--t-dim); text-transform: uppercase; white-space: nowrap; }
.stat .v { font-family: var(--mono); font-size: 15px; color: var(--t-hi); font-weight: 600; white-space: nowrap; }

.icon-btn {
  width: 30px; height: 30px; display: grid; place-items: center;
  border-radius: var(--r-sm); color: var(--t-dim); cursor: pointer;
  border: 1px solid transparent;
}
.icon-btn:hover { background: var(--panel-2); color: var(--t); border-color: var(--line); }

/* ---- generic card ---- */
.card { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-lg); }

/* fades / utility */
/* fades / utility — entrance anims animate transform only (never hold opacity:0),
   so content stays visible even if the animation timeline is frozen (capture/print). */
.fade-in { animation: fadeIn .45s ease both; }
@keyframes fadeIn { from { transform: translateY(7px); } to { transform: none; } }
.pop-in { animation: popIn .35s cubic-bezier(.2,1.2,.3,1) both; }
@keyframes popIn { from { transform: scale(.82); } to { transform: scale(1); } }

@keyframes blink { 0%,49% { opacity: 1; } 50%,100% { opacity: 0; } }
.caret { display: inline-block; width: 7px; height: 14px; background: var(--acc); margin-left: 2px; vertical-align: -2px; animation: blink 1s steps(1) infinite; }

@keyframes spin { to { transform: rotate(360deg); } }
.spin { animation: spin 1s linear infinite; }

@keyframes dash { to { stroke-dashoffset: 0; } }
@keyframes scanY { 0% { top: -6%; } 100% { top: 104%; } }
@keyframes pulseGlow { 0%,100% { box-shadow: 0 0 0 0 var(--acc-glow); } 50% { box-shadow: 0 0 0 6px transparent; } }

/* 选中节点的高亮呼吸光晕 —— 比静态描边更抢眼，一眼定位 */
@keyframes nodeGlow {
  0%,100% { box-shadow: 0 0 0 1.5px var(--acc), 0 0 18px 2px rgba(139,124,246,.45), 0 10px 30px -8px rgba(0,0,0,.7); }
  50%     { box-shadow: 0 0 0 2px var(--acc-hi), 0 0 36px 8px rgba(139,124,246,.8),  0 10px 30px -8px rgba(0,0,0,.7); }
}
.phone-active { animation: nodeGlow 1.8s ease-in-out infinite; }

/* skeleton shimmer (AI 分析中占位) */
.shimmer { position: relative; overflow: hidden; }
.shimmer::after { content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.06), transparent);
  transform: translateX(-100%); animation: shimmer 1.4s infinite; }
@keyframes shimmer { to { transform: translateX(100%); } }
