/* ==========================================================================

   charts.css · trackandreact.com

   信息可视化系统 — 雷达图/时间线/进度条/对比条/数据卡/热力图

   生成者：Crystal Yifei Liu · 2026-09-25

   依赖：tokens.css

   核心原则：图表是表达，不是装饰；每个图表必须有明确信息

   ========================================================================== */



/* ==========================================================================

   一、图表通用容器

   ========================================================================== */



.chart-wrapper {

  margin: var(--rhythm-loose) 0;

  padding: var(--space-5);

  background-color: var(--color-surface);

  border: 1px solid var(--color-border);

  border-radius: var(--radius-lg);

  container-type: inline-size;

  container-name: chart;

}



.chart-wrapper h3 {

  font-size: var(--chart-title-size);

  margin-top: 0;

  margin-bottom: var(--space-4);

  color: var(--color-text-primary);

  font-weight: var(--font-semibold);

}



.chart-wrapper h3::before {

  content: '📊 ';

  margin-right: var(--space-2);

  opacity: 0.7;

}



.chart-caption {

  margin-top: var(--space-3);

  font-size: var(--text-xs);

  color: var(--color-text-tertiary);

  text-align: center;

  font-style: italic;

  line-height: var(--leading-snug);

}



.chart-data-table {

  margin-top: var(--space-3);

  font-size: var(--text-sm);

}



.chart-data-table summary {

  cursor: pointer;

  color: var(--color-primary-600);

  font-weight: var(--font-medium);

  padding: var(--space-2) 0;

  min-height: 44px;

  display: flex;

  align-items: center;

  gap: var(--space-2);

}



.chart-data-table summary::before {

  content: '📋 ';

}



.chart-data-table[open] summary {

  margin-bottom: var(--space-3);

}



.chart-data-table table {

  width: 100%;

  border-collapse: collapse;

  font-size: var(--text-xs);

}



.chart-data-table th,

.chart-data-table td {

  padding: var(--space-2);

  text-align: left;

  border-bottom: 1px solid var(--color-border);

}



.chart-data-table th {

  font-weight: var(--font-semibold);

  color: var(--color-text-primary);

  background-color: var(--color-neutral-50);

}



/* ==========================================================================

   二、雷达图（Radar Chart）

   ========================================================================== */



.chart-radar {

  display: flex;

  justify-content: center;

  align-items: center;

  padding: var(--chart-padding) 0;

}



.chart-radar svg {

  width: 100%;

  max-width: 400px;

  height: auto;

  aspect-ratio: 1 / 1;

}



.chart-radar .radar-grid {

  fill: none;

  stroke: var(--color-neutral-200);

  stroke-width: 1;

}



.chart-radar .radar-grid-outer {

  stroke: var(--color-neutral-300);

  stroke-width: 1.5;

}



.chart-radar .radar-axis {

  stroke: var(--color-neutral-300);

  stroke-width: 1;

}



.chart-radar .radar-axis-label {

  font-size: var(--text-xs);

  fill: var(--color-text-secondary);

  font-weight: var(--font-medium);

  font-family: var(--font-body);

}



.chart-radar .radar-series {

  fill-opacity: 0.2;

  stroke-width: 2;

  stroke-linejoin: round;

}



.chart-radar .radar-series-1 {

  fill: var(--color-primary-500);

  stroke: var(--color-primary-500);

}



.chart-radar .radar-series-2 {

  fill: var(--color-accent-500);

  stroke: var(--color-accent-500);

}



.chart-radar .radar-series-3 {

  fill: var(--color-warning);

  stroke: var(--color-warning);

}



.chart-radar .radar-point {

  fill: var(--color-surface);

  stroke-width: 2;

}



.chart-radar .radar-legend {

  display: flex;

  gap: var(--space-4);

  justify-content: center;

  flex-wrap: wrap;

  margin-top: var(--space-4);

  font-size: var(--text-sm);

}



.chart-radar .radar-legend-item {

  display: inline-flex;

  align-items: center;

  gap: var(--space-2);

}



.chart-radar .radar-legend-dot {

  width: 12px;

  height: 12px;

  border-radius: var(--radius-sm);

}



.chart-radar .radar-legend-dot-1 { background-color: var(--color-primary-500); }

.chart-radar .radar-legend-dot-2 { background-color: var(--color-accent-500); }

.chart-radar .radar-legend-dot-3 { background-color: var(--color-warning); }



@container chart (max-width: 480px) {

  .chart-radar svg {

    max-width: 300px;

  }

  .chart-radar .radar-axis-label {

    font-size: 10px;

  }

}



/* ==========================================================================

   三、时间线（Timeline）

   ========================================================================== */



.chart-timeline {

  position: relative;

  padding: var(--space-5) 0;

}



.chart-timeline-horizontal {

  display: flex;

  gap: 0;

  overflow-x: auto;

  padding: var(--space-5) 0 var(--space-4);

  -webkit-overflow-scrolling: touch;

  scrollbar-width: thin;

}



.chart-timeline-horizontal::-webkit-scrollbar {

  height: 6px;

}



.chart-timeline-horizontal::-webkit-scrollbar-thumb {

  background-color: var(--color-neutral-300);

  border-radius: var(--radius-full);

}



.timeline-item {

  position: relative;

  padding-left: var(--space-8);

  padding-bottom: var(--rhythm-normal);

  border-left: 2px dashed var(--color-border-strong);

}



.timeline-item:last-child {

  border-left-color: transparent;

  padding-bottom: 0;

}



.timeline-item::before {

  content: '';

  position: absolute;

  left: -8px;

  top: 0;

  width: 14px;

  height: 14px;

  border-radius: var(--radius-full);

  background-color: var(--color-surface);

  border: 3px solid var(--color-primary-500);

  z-index: 1;

}



.timeline-item-current::before {

  background-color: var(--color-primary-500);

  box-shadow: 0 0 0 4px var(--color-primary-alpha-20);

  animation: timelinePulse 2s var(--ease-in-out) infinite;

}



@keyframes timelinePulse {

  0%, 100% { box-shadow: 0 0 0 4px var(--color-primary-alpha-20); }

  50% { box-shadow: 0 0 0 8px var(--color-primary-alpha-10); }

}



.timeline-time {

  font-size: var(--text-xs);

  color: var(--color-text-tertiary);

  font-weight: var(--font-semibold);

  text-transform: uppercase;

  letter-spacing: var(--tracking-wide);

  margin-bottom: var(--space-1);

}



.timeline-title {

  font-size: var(--text-base);

  font-weight: var(--font-semibold);

  color: var(--color-text-primary);

  margin-bottom: var(--space-1);

}



.timeline-desc {

  font-size: var(--text-sm);

  color: var(--color-text-secondary);

  line-height: var(--leading-snug);

}



@container chart (max-width: 640px) {

  .chart-timeline-horizontal {

    flex-direction: column;

  }



  .timeline-item {

    padding-left: var(--space-6);

    border-left: 2px dashed var(--color-border-strong);

    border-bottom: none;

    padding-bottom: var(--rhythm-normal);

  }

}



/* ==========================================================================

   四、进度条（Progress Bar）

   ========================================================================== */



.chart-progress {

  margin: var(--rhythm-normal) 0;

}



.progress-row {

  display: flex;

  align-items: center;

  gap: var(--space-3);

  margin-bottom: var(--space-3);

}



.progress-label {

  flex-shrink: 0;

  width: 120px;

  font-size: var(--text-sm);

  color: var(--color-text-secondary);

  font-weight: var(--font-medium);

}



.progress-track {

  flex: 1;

  height: 10px;

  background-color: var(--color-neutral-200);

  border-radius: var(--radius-full);

  overflow: hidden;

}



.progress-fill {

  height: 100%;

  background-color: var(--color-primary-500);

  border-radius: var(--radius-full);

  transition: width var(--duration-slower) var(--ease-out);

}



.progress-fill-accent { background-color: var(--color-accent-500); }

.progress-fill-success { background-color: var(--color-success); }

.progress-fill-warning { background-color: var(--color-warning); }

.progress-fill-error { background-color: var(--color-error); }



.progress-value {

  flex-shrink: 0;

  min-width: 48px;

  text-align: right;

  font-size: var(--text-sm);

  font-weight: var(--font-semibold);

  color: var(--color-text-primary);

}



@container chart (max-width: 480px) {

  .progress-label {

    width: 80px;

    font-size: var(--text-xs);

  }

}



/* ==========================================================================

   五、对比条（Comparison Bar）

   ========================================================================== */



.chart-comparison {

  margin: var(--rhythm-normal) 0;

}



.comparison-row {

  display: flex;

  align-items: center;

  gap: var(--space-3);

  margin-bottom: var(--space-4);

}



.comparison-label {

  flex-shrink: 0;

  width: 140px;

  font-size: var(--text-sm);

  color: var(--color-text-primary);

  font-weight: var(--font-medium);

  overflow: hidden;

  text-overflow: ellipsis;

  white-space: nowrap;

}



.comparison-track {

  flex: 1;

  height: 24px;

  background-color: var(--color-neutral-100);

  border-radius: var(--radius-md);

  overflow: hidden;

  position: relative;

}



.comparison-fill {

  height: 100%;

  background-color: var(--color-primary-500);

  border-radius: var(--radius-md);

  transition: width var(--duration-slower) var(--ease-out);

  display: flex;

  align-items: center;

  padding-left: var(--space-2);

}



.comparison-fill-accent { background-color: var(--color-accent-500); }

.comparison-fill-success { background-color: var(--color-success); }

.comparison-fill-warning { background-color: var(--color-warning); }



.comparison-fill-text {

  color: hsl(0, 0%, 100%);

  font-size: var(--text-xs);

  font-weight: var(--font-bold);

  white-space: nowrap;

}



.comparison-value {

  flex-shrink: 0;

  min-width: 60px;

  text-align: right;

  font-size: var(--text-sm);

  font-weight: var(--font-bold);

  color: var(--color-text-primary);

}



.comparison-winner {

  position: relative;

}



.comparison-winner::after {

  content: '🏆';

  position: absolute;

  right: -20px;

  top: 50%;

  transform: translateY(-50%);

  font-size: var(--text-base);

}



@container chart (max-width: 480px) {

  .comparison-label {

    width: 90px;

    font-size: var(--text-xs);

  }



  .comparison-value {

    min-width: 50px;

    font-size: var(--text-xs);

  }



  .comparison-winner::after {

    display: none;

  }

}



/* ==========================================================================

   六、数据卡（Data Card）

   ========================================================================== */



.chart-data-cards {

  display: grid;

  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));

  gap: var(--space-4);

  margin: var(--rhythm-normal) 0;

}



.chart-data-card {

  padding: var(--space-5);

  background: linear-gradient(135deg,

    var(--color-primary-alpha-10),

    var(--color-accent-alpha-10));

  border: 1px solid var(--color-border);

  border-radius: var(--radius-lg);

  text-align: center;

  transition: all var(--duration-normal) var(--ease-out);

}



.chart-data-card:hover {

  transform: translateY(-3px);

  box-shadow: var(--shadow-md);

}



.data-value {

  font-size: var(--text-4xl);

  font-weight: var(--font-bold);

  color: var(--color-primary-600);

  line-height: var(--leading-tight);

  margin-bottom: var(--space-2);

  font-family: var(--font-display);

  letter-spacing: var(--tracking-tight);

}



.data-unit {

  font-size: var(--text-base);

  font-weight: var(--font-medium);

  color: var(--color-text-tertiary);

  margin-left: var(--space-1);

}



.data-description {

  font-size: var(--text-sm);

  color: var(--color-text-secondary);

  line-height: var(--leading-snug);

}



@container chart (max-width: 480px) {

  .chart-data-cards {

    grid-template-columns: 1fr;

  }



  .data-value {

    font-size: var(--text-3xl);

  }

}



/* ==========================================================================

   七、热力图（Heatmap）

   ========================================================================== */



.chart-heatmap {

  margin: var(--rhythm-normal) 0;

  overflow-x: auto;

  -webkit-overflow-scrolling: touch;

}



.heatmap-grid {

  display: grid;

  grid-template-columns: 120px repeat(auto-fit, minmax(60px, 1fr));

  gap: 4px;

  min-width: 400px;

}



.heatmap-corner {

  font-size: var(--text-xs);

  color: var(--color-text-tertiary);

}



.heatmap-header {

  font-size: var(--text-xs);

  font-weight: var(--font-semibold);

  color: var(--color-text-primary);

  text-align: center;

  padding: var(--space-2);

  text-transform: uppercase;

  letter-spacing: var(--tracking-wide);

}



.heatmap-row-label {

  font-size: var(--text-sm);

  font-weight: var(--font-medium);

  color: var(--color-text-primary);

  display: flex;

  align-items: center;

  padding-right: var(--space-2);

}



.heatmap-cell {

  aspect-ratio: 1 / 1;

  border-radius: var(--radius-sm);

  display: flex;

  align-items: center;

  justify-content: center;

  font-size: var(--text-xs);

  font-weight: var(--font-semibold);

  color: var(--color-text-primary);

  transition: transform var(--duration-fast) var(--ease-out);

}



.heatmap-cell:hover {

  transform: scale(1.1);

  z-index: 1;

  box-shadow: var(--shadow-md);

}



/* 五级热力强度 */

.heatmap-1 { background-color: hsl(220, 65%, 95%); }

.heatmap-2 { background-color: hsl(220, 65%, 88%); }

.heatmap-3 { background-color: hsl(220, 65%, 78%); }

.heatmap-4 { background-color: hsl(220, 65%, 62%); color: hsl(0, 0%, 100%); }

.heatmap-5 { background-color: hsl(220, 65%, 45%); color: hsl(0, 0%, 100%); }



.heatmap-legend {

  display: flex;

  align-items: center;

  justify-content: center;

  gap: var(--space-2);

  margin-top: var(--space-4);

  font-size: var(--text-xs);

  color: var(--color-text-tertiary);

}



.heatmap-legend-item {

  width: 20px;

  height: 20px;

  border-radius: var(--radius-sm);

}



@container chart (max-width: 640px) {

  .heatmap-grid {

    grid-template-columns: 90px repeat(auto-fit, minmax(45px, 1fr));

  }



  .heatmap-cell {

    font-size: 10px;

  }

}



/* ==========================================================================

   八、成本对比表（带视觉高亮）

   ========================================================================== */



.cost-comparison {

  margin: var(--rhythm-loose) 0;

  border: 2px solid var(--color-accent-200);

  border-radius: var(--radius-lg);

  overflow: hidden;

}



.cost-comparison-header {

  padding: var(--space-4) var(--space-5);

  background: linear-gradient(135deg,

    var(--color-accent-alpha-20),

    var(--color-primary-alpha-10));

  border-bottom: 1px solid var(--color-border);

}



.cost-comparison-header h3 {

  margin: 0;

  font-size: var(--text-lg);

  color: var(--color-accent-700);

}



.cost-comparison-header h3::before {

  content: '💰 ';

}



.cost-comparison-body {

  padding: var(--space-5);

}



.cost-row {

  display: flex;

  justify-content: space-between;

  align-items: center;

  padding: var(--space-3) 0;

  border-bottom: 1px solid var(--color-border);

  font-size: var(--text-base);

}



.cost-row:last-child {

  border-bottom: none;

  padding-top: var(--space-4);

  font-weight: var(--font-bold);

  font-size: var(--text-lg);

  color: var(--color-accent-700);

}



.cost-row-label {

  color: var(--color-text-secondary);

}



.cost-row-value {

  font-weight: var(--font-semibold);

  color: var(--color-text-primary);

}



.cost-row-savings {

  color: var(--color-accent-600);

}



.cost-row-savings::before {

  content: '↓ ';

}



/* ==========================================================================

   九、评分分布图（柱状）

   ========================================================================== */



.chart-score-distribution {

  display: flex;

  align-items: flex-end;

  justify-content: space-around;

  gap: var(--space-2);

  height: 200px;

  padding: var(--space-4) 0;

  border-bottom: 2px solid var(--color-border-strong);

  margin-bottom: var(--space-3);

}



.score-bar {

  flex: 1;

  max-width: 60px;

  background-color: var(--color-primary-500);

  border-radius: var(--radius-sm) var(--radius-sm) 0 0;

  display: flex;

  flex-direction: column;

  justify-content: flex-end;

  align-items: center;

  padding-bottom: var(--space-2);

  position: relative;

  transition: all var(--duration-normal) var(--ease-out);

}



.score-bar:hover {

  background-color: var(--color-primary-600);

  transform: scaleY(1.05);

  transform-origin: bottom;

}



.score-bar-value {

  font-size: var(--text-sm);

  font-weight: var(--font-bold);

  color: hsl(0, 0%, 100%);

  margin-bottom: var(--space-1);

}



.score-bar-label {

  position: absolute;

  bottom: -28px;

  left: 50%;

  transform: translateX(-50%);

  font-size: var(--text-xs);

  color: var(--color-text-secondary);

  white-space: nowrap;

}



/* ==========================================================================

   十、移动端图表适配

   ========================================================================== */



@media (max-width: 768px) {

  .chart-wrapper {

    padding: var(--space-4);

    margin: var(--rhythm-normal) 0;

  }



  .chart-timeline-horizontal {

    flex-direction: column;

  }



  .comparison-label {

    width: 80px;

    font-size: var(--text-xs);

  }



  .comparison-value {

    min-width: 44px;

    font-size: var(--text-xs);

  }



  .chart-score-distribution {

    height: 160px;

  }

}



/* ==========================================================================

   十一、图表可访问性

   ========================================================================== */



/* 图表必须有alt文本（通过aria-label） */

.chart-wrapper[role="img"] {

  position: relative;

}



/* 图表必须有数据表格替代 */

.chart-wrapper .chart-data-table {

  margin-top: var(--space-3);

}



.chart-data-table summary {

  list-style: none;

}



.chart-data-table summary::-webkit-details-marker {

  display: none;

}



/* ==========================================================================

   十二、减少动效偏好

   ========================================================================== */



@media (prefers-reduced-motion: reduce) {

  .timeline-item-current::before {

    animation: none;

  }



  .progress-fill,

  .comparison-fill {

    transition: none;

  }

}



/* ==========================================================================

   十三、打印样式

   ========================================================================== */



@media print {

  .chart-wrapper {

    break-inside: avoid;

    border: 1px solid #ccc;

    box-shadow: none;

  }



  .chart-data-table[open] {

    display: block;

  }



  .chart-data-table summary {

    display: none;

  }



  .chart-data-table table {

    display: table;

  }

}



/* ==========================================================================

   charts.css 结束

   ========================================================================== */