/* ============================================================
   Component Layer — 组件层
   ------------------------------------------------------------
   设计约束（方案 A 契约）：
   1. 前缀 .c- ，与外壳 .sh- 、门户 .pt- 分层，互不覆盖。
   2. 颜色/间距/圆角/字号一律取 tools.css 令牌，不新增颜色变量。
   3. 每个交互组件必须实现 :hover / :focus-visible / :active / :disabled。
   4. 正文对比度 WCAG AA >= 4.5:1；大字号(>=24px 或 >=18.66px粗) >= 3:1。
      禁止用 --color-text-muted(#94a3b8) 作为正文色（白底仅 2.6:1）。
   5. 深色模式统一走 html[data-theme="dark"] ，复用同一批令牌。
   6. 不覆盖 .btn / .card / .form-input 等既有类，只提供新的 .c- 类。
   ============================================================ */

/* ============================================================
   1. Layout helpers
   ============================================================ */
.c-stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-4, 16px);
}
.c-row {
  display: flex;
  align-items: center;
  gap: var(--space-3, 12px);
  flex-wrap: wrap;
}
.c-row--between {
  justify-content: space-between;
}
.c-spacer { flex: 1 1 auto; }
.c-muted {
  color: var(--color-text-secondary);
  font-size: var(--text-sm);
}

/* ============================================================
   2. Card — 统一容器（替代 box / panel / card 三种叫法）
   ============================================================ */
.c-card {
  background: var(--color-bg-surface);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-lg);
  padding: var(--space-5, 20px);
}
.c-card + .c-card { margin-top: var(--space-4, 16px); }

.c-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3, 12px);
  margin-bottom: var(--space-4, 16px);
  flex-wrap: wrap;
}
.c-card__title {
  margin: 0;
  font-size: var(--text-base);
  font-weight: 600;
  color: var(--color-text-primary);
}
.c-card__desc {
  margin: 4px 0 0;
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}

/* ============================================================
   3. Upload dropzone — 四态状态机
      idle / dragover / ready / disabled
   ============================================================ */
.c-upload {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 132px;
  padding: var(--space-6, 24px) var(--space-5, 20px);
  border: 2px dashed var(--color-border-strong);
  border-radius: var(--radius-lg);
  background: var(--color-bg-subtle);
  text-align: center;
  cursor: pointer;
  transition: border-color 160ms ease, background-color 160ms ease;
}
/* 关键：子元素不接管指针事件，避免拖入子节点时 dragleave 抖动 */
.c-upload > * {
  pointer-events: none;
}
.c-upload:hover {
  border-color: var(--color-primary);
  background: var(--color-primary-subtle);
}
.c-upload:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}
.c-upload.is-dragover {
  border-color: var(--color-primary);
  border-style: solid;
  background: var(--color-primary-subtle);
}
.c-upload.is-disabled,
.c-upload[aria-disabled="true"] {
  opacity: .55;
  cursor: not-allowed;
  border-color: var(--color-border-subtle);
  background: var(--color-bg-canvas);
}
.c-upload.is-disabled:hover {
  border-color: var(--color-border-subtle);
  background: var(--color-bg-canvas);
}

.c-upload__icon {
  width: 32px;
  height: 32px;
  color: var(--color-text-secondary);
}
.c-upload__icon svg { width: 100%; height: 100%; }

.c-upload__title {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-text-primary);
}
.c-upload__title em {
  font-style: normal;
  color: var(--color-primary);
}
.c-upload__hint {
  font-size: var(--text-xs);
  color: var(--color-text-secondary);   /* 不用 muted：白底对比度不足 */
}

/* ready 态：已选文件 */
.c-upload.is-ready {
  border-style: solid;
  border-color: var(--color-border-subtle);
  background: var(--color-bg-surface);
  align-items: stretch;
  text-align: left;
  min-height: 0;
  padding: var(--space-3, 12px) var(--space-4, 16px);
}
.c-file {
  display: flex;
  align-items: center;
  gap: var(--space-3, 12px);
  min-width: 0;
}
.c-file__icon {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-sm);
  background: var(--color-primary-subtle);
  color: var(--color-primary);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-xs);
  font-weight: 700;
}
.c-file__body {
  min-width: 0;
  flex: 1 1 auto;
}
.c-file__name {
  display: block;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.c-file__meta {
  display: block;
  font-size: var(--text-xs);
  color: var(--color-text-secondary);
  margin-top: 2px;
}
.c-file__remove {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-sm);
  background: var(--color-bg-surface);
  color: var(--color-text-secondary);
  cursor: pointer;
  font-size: 16px;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: color 150ms ease, border-color 150ms ease, background-color 150ms ease;
}
.c-file__remove:hover {
  color: var(--color-error, #dc2626);
  border-color: var(--color-border-strong);
  background: var(--color-bg-subtle);
}
.c-file__remove:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 1px;
}

/* ============================================================
   4. Progress — 确定 / 不确定 / 步骤
   ============================================================ */
.c-progress {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.c-progress__track {
  position: relative;
  height: 6px;
  border-radius: var(--radius-full);
  background: var(--color-bg-active, #cbd5e1);
  overflow: hidden;
}
.c-progress__bar {
  height: 100%;
  width: 0%;
  border-radius: inherit;
  background: var(--color-primary);
  transition: width 240ms ease;
}
/* 不确定进度：无百分比时使用 */
.c-progress.is-indeterminate .c-progress__bar {
  width: 35%;
  animation: c-progress-slide 1.1s ease-in-out infinite;
}
@keyframes c-progress-slide {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(340%); }
}
/* 用户偏好减少动效时降级为静态条 */
@media (prefers-reduced-motion: reduce) {
  .c-progress.is-indeterminate .c-progress__bar {
    animation: none;
    width: 100%;
    opacity: .5;
  }
}

.c-progress__meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2, 8px);
  font-size: var(--text-xs);
  color: var(--color-text-secondary);
}
.c-progress__pct {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--color-text-primary);
}

/* 步骤条 */
.c-steps {
  display: flex;
  align-items: center;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}
.c-step {
  flex: 1 1 0;
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  font-size: var(--text-xs);
  color: var(--color-text-secondary);
}
.c-step + .c-step::before {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  min-width: 8px;
  background: var(--color-border-strong);
  margin-right: 6px;
}
.c-step__dot {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 1.5px solid var(--color-border-strong);
  background: var(--color-bg-surface);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  font-weight: 700;
  color: var(--color-text-secondary);
}
.c-step__label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.c-step.is-active {
  color: var(--color-text-primary);
  font-weight: 600;
}
.c-step.is-active .c-step__dot {
  border-color: var(--color-primary);
  background: var(--color-primary);
  color: var(--color-text-inverse, #fff);
}
.c-step.is-done .c-step__dot {
  border-color: var(--color-primary);
  background: var(--color-primary-subtle);
  color: var(--color-primary);
}
.c-step.is-done { color: var(--color-text-secondary); }

/* ============================================================
   5. Result card
   ============================================================ */
.c-result {
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-lg);
  padding: var(--space-4, 16px);
  background: var(--color-bg-surface);
}
.c-result__head {
  display: flex;
  align-items: center;
  gap: var(--space-2, 8px);
  margin-bottom: var(--space-3, 12px);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-text-primary);
}
.c-result__badge {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--color-success, #16a34a);
  color: #fff;
  font-size: 11px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.c-result__body {
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}

/* ============================================================
   6. Empty state
   ============================================================ */
.c-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: var(--space-8, 32px) var(--space-4, 16px);
  text-align: center;
}
.c-empty__icon {
  width: 36px;
  height: 36px;
  color: var(--color-text-secondary);
  opacity: .8;
}
.c-empty__title {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-text-primary);
}
.c-empty__text {
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  max-width: 36ch;
  line-height: 1.6;
}

/* ============================================================
   7. Error box
   ============================================================ */
.c-error {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3, 12px);
  padding: var(--space-4, 16px);
  border: 1px solid var(--color-error-border, #fecaca);
  border-radius: var(--radius-lg);
  background: var(--color-error-bg, #fef2f2);
}
.c-error__icon {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--color-error, #dc2626);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.c-error__body { min-width: 0; flex: 1 1 auto; }
.c-error__title {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-error-text, #991b1b);
  margin: 0 0 2px;
}
.c-error__text {
  font-size: var(--text-sm);
  color: var(--color-error-text, #991b1b);
  margin: 0;
  line-height: 1.55;
  word-break: break-word;
}

/* ============================================================
   8. Badge / tag
   ============================================================ */
.c-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: var(--radius-full);
  font-size: var(--text-xs);
  font-weight: 600;
  background: var(--color-bg-subtle);
  color: var(--color-text-secondary);
  border: 1px solid var(--color-border-subtle);
  white-space: nowrap;
}
.c-badge--primary {
  background: var(--color-primary-subtle);
  color: var(--color-primary-hover, #1d4ed8);
  border-color: var(--color-border-subtle);
}
.c-badge--success {
  background: var(--color-success-subtle, #f0fdf4);
  color: var(--color-success-text, #15803d);
}

/* ============================================================
   9. Spinner（骨架/加载）
   ============================================================ */
.c-spinner {
  display: inline-block;
  width: 16px;
  height: 16px;
  border: 2px solid var(--color-border-strong);
  border-top-color: var(--color-primary);
  border-radius: 50%;
  animation: c-spin .8s linear infinite;
  vertical-align: -3px;
}
@keyframes c-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .c-spinner { animation-duration: 2.4s; }
}

.c-skeleton {
  background: linear-gradient(90deg,
    var(--color-bg-subtle) 25%,
    var(--color-bg-hover) 37%,
    var(--color-bg-subtle) 63%);
  background-size: 400% 100%;
  border-radius: var(--radius-sm);
  animation: c-shimmer 1.4s ease infinite;
}
@keyframes c-shimmer {
  0% { background-position: 100% 50%; }
  100% { background-position: 0 50%; }
}
@media (prefers-reduced-motion: reduce) {
  .c-skeleton { animation: none; }
}

/* ============================================================
   10. Dark mode
   ============================================================ */
html[data-theme="dark"] .c-card,
html[data-theme="dark"] .c-result,
html[data-theme="dark"] .c-upload.is-ready {
  background: var(--color-bg-surface);
  border-color: var(--color-border-subtle);
}
html[data-theme="dark"] .c-upload {
  background: var(--color-bg-subtle);
  border-color: var(--color-border-strong);
}
html[data-theme="dark"] .c-upload:hover,
html[data-theme="dark"] .c-upload.is-dragover {
  background: var(--color-primary-subtle);
  border-color: var(--color-primary);
}
html[data-theme="dark"] .c-progress__track {
  background: var(--color-bg-hover);
}
html[data-theme="dark"] .c-badge {
  background: var(--color-bg-subtle);
  color: var(--color-text-secondary);
}
html[data-theme="dark"] .c-error {
  background: rgba(220, 38, 38, .12);
  border-color: rgba(220, 38, 38, .34);
}
html[data-theme="dark"] .c-error__title,
html[data-theme="dark"] .c-error__text {
  color: #fca5a5;
}

/* ============================================================
   11. Mobile
   ============================================================ */
@media (max-width: 719px) {
  .c-card { padding: var(--space-4, 16px); border-radius: var(--radius-md); }
  .c-upload { min-height: 116px; padding: var(--space-5, 20px) var(--space-4, 16px); }
  .c-file__remove { width: 40px; height: 40px; }   /* 触控目标 */
  .c-step__label { display: none; }                 /* 窄屏只留圆点 */
  .c-step.is-active .c-step__label { display: inline; }
  .c-empty { padding: var(--space-6, 24px) var(--space-3, 12px); }
}
