/* ============================================================
   pages.css — 页面级组件样式（前台各页 + 后台）
   ============================================================ */

/* ---------------- Hero（首页首屏） ---------------- */
/* 导航右侧的「后台」入口：平时半透明，悬停或吸顶后显现 */
.nav-admin {
  opacity: 0.42;
  transition: opacity var(--t-base) var(--ease-out), transform var(--t-base) var(--ease-out);
}
.nav:hover .nav-admin,
.nav-admin:focus-visible {
  opacity: 1;
}
@media (max-width: 1024px) {
  .nav-admin {
    display: none;
  }
}
.hero {
  position: relative;
  min-height: 100vh;
  display: flex;
  align-items: center;
  padding: calc(var(--nav-h) + 56px) 0 72px;
  color: #fff;
  background: radial-gradient(1100px 620px at 12% 18%, #1b2028 0%, #0b0d10 62%, #07080a 100%);
  overflow: hidden;
  isolation: isolate;
}
.hero-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
}
.hero-glow {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: radial-gradient(520px 320px at 78% 26%, rgba(194, 145, 58, 0.3), transparent 70%),
    radial-gradient(480px 300px at 22% 84%, rgba(31, 157, 157, 0.22), transparent 72%);
  pointer-events: none;
}
.hero-inner {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: 54px;
  align-items: center;
}
.hero-copy {
  min-width: 0;
}
.hero-title {
  margin: 20px 0 22px;
  font-size: clamp(32px, 4.6vw, 62px);
  line-height: 1.16;
}
.hero-typed-wrap {
  min-height: 1.2em;
  display: inline-block;
}
.hero-lead {
  max-width: 54ch;
  font-size: clamp(14.5px, 1.15vw, 16.5px);
  line-height: 1.9;
}
.hero-actions {
  margin-top: 32px;
  gap: 14px;
  flex-wrap: wrap;
}
.hero-meta {
  display: flex;
  gap: 42px;
  margin-top: 52px;
  padding-top: 26px;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  flex-wrap: wrap;
}
.hero-meta b {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(24px, 2.4vw, 34px);
  color: var(--gold-400);
  line-height: 1.1;
}
.hero-meta span {
  font-size: 12px;
  letter-spacing: 0.12em;
  color: rgba(255, 255, 255, 0.5);
}
.hero-art {
  position: relative;
  padding: 30px 10px;
  min-width: 0;
  max-width: 100%;
}
.hero-card {
  position: relative;
  border-radius: 24px;
  overflow: hidden;
  box-shadow: 0 40px 90px rgba(0, 0, 0, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.12);
  background: #14171c;
  max-width: 100%;
}
.hero-card img {
  border-radius: 20px;
}
.hero-card-tag {
  position: absolute;
  left: 18px;
  bottom: 18px;
  padding: 12px 18px;
  border-radius: 14px;
  background: rgba(11, 13, 16, 0.7);
  backdrop-filter: blur(12px);
  border: 1px solid rgba(255, 255, 255, 0.14);
}
.hero-card-tag b {
  display: block;
  font-size: 15px;
  color: #fff;
}
.hero-card-tag span {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.6);
}
.hero-chip {
  position: absolute;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  border-radius: var(--r-pill);
  font-size: 13px;
  font-weight: 600;
  background: rgba(255, 255, 255, 0.94);
  color: var(--ink-800);
  box-shadow: var(--sh-3);
}
.hero-chip i {
  display: grid;
  place-items: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--gold-500);
  color: #241a04;
  font-size: 11px;
  font-style: normal;
}
.hero-chip-1 {
  top: 6%;
  left: -12px;
}
.hero-chip-2 {
  bottom: 12%;
  right: -6px;
}
@media (max-width: 1024px) {
  .hero-inner {
    grid-template-columns: minmax(0, 1fr);
    gap: 30px;
  }
  .hero {
    min-height: auto;
    padding-top: calc(var(--nav-h) + 40px);
  }
  .hero-art {
    order: -1;
    max-width: 460px;
    width: 100%;
    padding: 26px 0 8px;
  }
  .hero-chip-1 {
    left: 4px;
  }
  .hero-chip-2 {
    right: 4px;
  }
}
@media (max-width: 600px) {
  /*
    窄屏下胶囊标签改为静态排布，避免溢出屏幕。
    ------------------------------------------------------------
    注意这里必须让父容器 .hero-art 变成 flex ——
    只把胶囊改成 position:static 是不够的：
    胶囊是 inline-flex，两个标签之间的换行符会被当成一个空格（约 4px），
    两个胶囊宽度加起来刚好超过手机可用宽度，第二个就会被挤到下一行并左移，
    看起来就是「排列错乱」（而 hero-card-tag 仍是绝对定位，更显乱）。
    用 flex column + gap 后间距由 gap 控制，不再受 HTML 换行符影响。
  */
  .hero-art {
    display: flex;
    flex-direction: column;
    gap: 10px;
  }
  .hero-chip {
    position: static;
    display: inline-flex;
    margin: 0;               /* 间距交给父级 gap，避免和空格叠加 */
    align-self: flex-start;  /* 胶囊按内容宽度，不拉满整行 */
    max-width: 100%;         /* 极窄屏（320px）下不溢出 */
    font-size: 12px;
    padding: 8px 12px;
    gap: 7px;
  }
  /* 窄屏下卡片与胶囊之间留一点距离，视觉上不和图片贴住 */
  .hero-card {
    margin-bottom: 2px;
  }
  .hero-card-tag {
    left: 12px;
    bottom: 12px;
    padding: 10px 14px;
  }
  .hero-actions {
    gap: 10px;
  }
  .hero-actions .btn {
    flex: 1 1 140px;
    min-width: 0;
    padding: 0 12px;
    height: 50px;
    font-size: 14.5px;
  }
  .hero-meta {
    gap: 24px;
  }
}

/* ---------------- 首页：分类磁贴 ---------------- */
.cat-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.cat-tile {
  position: relative;
  display: block;
  padding: 34px 28px 30px;
  background: var(--surface);
  transition: background var(--t-base) var(--ease-out), transform var(--t-base) var(--ease-out);
}
.cat-tile::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 2px;
  background: linear-gradient(90deg, var(--gold-400), var(--gold-600));
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--t-slow) var(--ease-out);
}
.cat-tile:hover {
  background: linear-gradient(180deg, #fff, var(--gold-100));
}
.cat-tile:hover::after {
  transform: scaleX(1);
}
.cat-tile h3 {
  margin: 10px 0 8px;
  font-size: 18px;
}
.cat-idx {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--gold-600);
  letter-spacing: 0.1em;
}
.cat-count {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-top: 16px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-soft);
}
.cat-count i {
  font-style: normal;
  transition: transform var(--t-base) var(--ease-out);
}
.cat-tile:hover .cat-count i {
  transform: translateX(5px);
}
@media (max-width: 1024px) {
  .cat-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 600px) {
  .cat-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ---------------- 首页：优势 / 流程 ---------------- */
.adv-card {
  padding: 30px 26px;
}
.adv-icon {
  width: 50px;
  height: 50px;
  display: grid;
  place-items: center;
  border-radius: 15px;
  background: linear-gradient(140deg, var(--gold-100), #fff);
  border: 1px solid var(--line);
  color: var(--gold-600);
  margin-bottom: 18px;
  transition: transform var(--t-base) var(--ease-spring);
}
.adv-icon svg {
  width: 24px;
  height: 24px;
}
.adv-card:hover .adv-icon {
  transform: rotate(-6deg) scale(1.06);
}
.adv-card h3 {
  margin-bottom: 8px;
  font-size: 17px;
}

.proc-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0;
  border-top: 1px solid var(--line);
  border-left: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.proc-item {
  position: relative;
  padding: 30px 26px 34px;
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  background: var(--surface);
  transition: background var(--t-base) var(--ease-out);
}
.proc-item:hover {
  background: var(--paper-2);
}
.proc-step {
  font-family: var(--font-mono);
  font-size: 26px;
  font-weight: 700;
  color: var(--ink-200);
  transition: color var(--t-base) var(--ease-out);
}
.proc-item:hover .proc-step {
  color: var(--gold-500);
}
.proc-item h4 {
  margin: 12px 0 8px;
  font-size: 16.5px;
}
.proc-line {
  position: absolute;
  right: -6px;
  top: 50%;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--surface);
  border: 2px solid var(--line-strong);
  transform: translateY(-50%);
  transition: all var(--t-base) var(--ease-out);
}
.proc-item:hover .proc-line {
  background: var(--gold-500);
  border-color: var(--gold-500);
  box-shadow: 0 0 0 5px rgba(194, 145, 58, 0.18);
}
@media (max-width: 1024px) {
  .proc-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 600px) {
  .proc-grid {
    grid-template-columns: minmax(0, 1fr);
  }
  .proc-line {
    display: none;
  }
}

.stats-row {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 26px;
  text-align: center;
}
@media (max-width: 768px) {
  .stats-row {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* ---------------- 案例 / 资讯卡片 ---------------- */
.case-card {
  display: block;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--surface);
  transition: transform var(--t-base) var(--ease-out), box-shadow var(--t-base) var(--ease-out), border-color var(--t-base);
}
.case-card:hover {
  transform: translateY(-7px);
  box-shadow: var(--sh-3);
  border-color: var(--line-strong);
}
.case-media {
  position: relative;
  aspect-ratio: 16 / 11;
  overflow: hidden;
}
.case-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 1s var(--ease-out);
}
.case-card:hover .case-media img {
  transform: scale(1.07);
}
.case-year,
.case-cat {
  position: absolute;
  top: 14px;
  padding: 5px 12px;
  border-radius: var(--r-pill);
  font-size: 11.5px;
  font-weight: 600;
  background: rgba(11, 13, 16, 0.7);
  color: #fff;
  backdrop-filter: blur(8px);
}
.case-year {
  right: 14px;
}
.case-cat {
  left: 14px;
  background: rgba(255, 255, 255, 0.9);
  color: var(--ink-700);
}
.case-card.is-tall {
  display: flex;
  flex-direction: column;
  height: 100%;
}
.case-card.is-tall .case-body {
  display: flex;
  flex-direction: column;
  flex: 1;
}
.case-card.is-tall .case-metrics {
  margin-top: auto;
}
.case-body {
  padding: 22px 24px 26px;
}
.case-body h3 {
  margin: 8px 0 10px;
  font-size: 18px;
}
.case-metrics {
  display: flex;
  gap: 22px;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px dashed var(--line);
  flex-wrap: wrap;
}
.case-metrics span {
  font-size: 11.5px;
  color: var(--text-mute);
  letter-spacing: 0.06em;
}
.case-metrics b {
  display: block;
  font-family: var(--font-display);
  font-size: 19px;
  color: var(--gold-600);
}

.art-card {
  display: block;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--surface);
  padding-bottom: 20px;
  transition: transform var(--t-base) var(--ease-out), box-shadow var(--t-base) var(--ease-out), border-color var(--t-base);
}
.art-card:hover {
  transform: translateY(-6px);
  box-shadow: var(--sh-2);
  border-color: var(--line-strong);
}
.art-media {
  position: relative;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  margin-bottom: 18px;
}
.art-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 1s var(--ease-out);
}
.art-card:hover .art-media img {
  transform: scale(1.06);
}
.art-cat {
  position: absolute;
  left: 14px;
  bottom: 14px;
  padding: 5px 12px;
  border-radius: var(--r-pill);
  font-size: 11.5px;
  font-weight: 600;
  background: rgba(255, 255, 255, 0.92);
  color: var(--gold-600);
}
.art-cat.is-inline {
  position: static;
  display: inline-block;
  background: var(--gold-100);
}
.art-card h3,
.art-card h4 {
  padding: 0 22px;
  font-size: 16.5px;
  margin-bottom: 8px;
  transition: color var(--t-fast);
}
.art-card:hover h3 {
  color: var(--gold-600);
}
.art-card p,
.art-card .mute-2,
.art-card > span {
  padding: 0 22px;
}
.art-card.is-row {
  display: grid;
  grid-template-columns: 320px 1fr;
  gap: 0;
  padding-bottom: 0;
  align-items: stretch;
}
.art-card.is-row .art-media {
  aspect-ratio: auto;
  margin: 0;
  height: 100%;
}
.art-card.is-row .art-text {
  padding: 24px 26px;
}
.art-card.is-row h3 {
  padding: 0;
  margin: 12px 0 10px;
  font-size: 19px;
}
.art-card.is-row p,
.art-card.is-row .mute-2 {
  padding: 0;
}
@media (max-width: 768px) {
  .art-card.is-row {
    grid-template-columns: minmax(0, 1fr);
  }
  .art-card.is-row .art-media {
    aspect-ratio: 16 / 10;
  }
}
.art-card.is-mini {
  padding-bottom: 16px;
}
.art-card.is-mini img {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  margin-bottom: 14px;
}
.art-card.is-mini h4 {
  font-size: 14.5px;
  line-height: 1.6;
}

/* ---------------- 客户评价 / FAQ ---------------- */
.quote-card {
  position: relative;
  padding: 32px 28px;
  overflow: hidden;
}
.quote-mark {
  position: absolute;
  right: 22px;
  top: 18px;
  width: 54px;
  height: 54px;
  color: var(--gold-300);
  opacity: 0.55;
}
.quote-card blockquote {
  margin: 0 0 22px;
  font-size: 14.8px;
  line-height: 1.95;
  color: var(--text);
}
.quote-card figcaption {
  display: flex;
  align-items: center;
  gap: 12px;
  padding-top: 18px;
  border-top: 1px dashed var(--line);
}
.avatar {
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: linear-gradient(140deg, var(--gold-400), var(--gold-600));
  color: #241a04;
  font-weight: 700;
  flex: none;
}
.quote-card figcaption b {
  display: block;
  font-size: 14px;
}
.quote-card figcaption em {
  font-style: normal;
  font-size: 12px;
  color: var(--text-mute);
}

.faq {
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
  overflow: hidden;
  transition: border-color var(--t-fast), box-shadow var(--t-base);
}
.faq + .faq {
  margin-top: 12px;
}
.faq[open] {
  border-color: var(--line-strong);
  box-shadow: var(--sh-1);
}
.faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 19px 22px;
  cursor: pointer;
  font-weight: 620;
  font-size: 15px;
  list-style: none;
}
.faq summary::-webkit-details-marker {
  display: none;
}
.faq-icon {
  position: relative;
  width: 18px;
  height: 18px;
  flex: none;
}
.faq-icon::before,
.faq-icon::after {
  content: "";
  position: absolute;
  background: var(--gold-600);
  border-radius: 2px;
  transition: transform var(--t-base) var(--ease-out);
}
.faq-icon::before {
  left: 0;
  top: 8px;
  width: 18px;
  height: 1.8px;
}
.faq-icon::after {
  left: 8px;
  top: 0;
  width: 1.8px;
  height: 18px;
}
.faq[open] .faq-icon::after {
  transform: scaleY(0);
}
.faq-body {
  padding: 0 22px 22px;
  color: var(--text-soft);
  font-size: 14px;
  line-height: 1.9;
  animation: faqIn 420ms var(--ease-out);
}
@keyframes faqIn {
  from {
    opacity: 0;
    transform: translateY(-6px);
  }
}

/* ---------------- CTA 区块 ---------------- */
.cta-band {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-xl);
  padding: clamp(38px, 5vw, 66px);
  color: #fff;
  background: linear-gradient(120deg, #14171c, #23282f 55%, #14171c);
}
.cta-band::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(420px 240px at 8% 10%, rgba(194, 145, 58, 0.34), transparent 70%),
    radial-gradient(420px 240px at 92% 90%, rgba(31, 157, 157, 0.26), transparent 70%);
}
.cta-band > * {
  position: relative;
}
.cta-band h2 {
  margin-bottom: 12px;
}

/* 关于页图片 */
.about-img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border: 1px solid var(--line);
  box-shadow: var(--sh-2);
}

/* ---------------- 自绘日期选择器 ---------------- */
.datepicker {
  position: relative;
}
.dp-panel {
  padding: 14px;
}
.dp-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}
.dp-title {
  font-size: 14px;
  font-weight: 650;
}
.dp-nav {
  width: 30px;
  height: 30px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--surface);
  color: var(--text-soft);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  transition: all var(--t-fast) var(--ease-out);
}
.dp-nav:hover {
  border-color: var(--gold-500);
  color: var(--gold-600);
  background: var(--gold-100);
}
.dp-week {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
  margin-bottom: 6px;
}
.dp-week span {
  text-align: center;
  font-size: 11px;
  color: var(--text-mute);
  padding: 4px 0;
}
.dp-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
}
.dp-day {
  height: 34px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: var(--text);
  font-size: 13px;
  cursor: pointer;
  transition: background var(--t-fast), color var(--t-fast), transform var(--t-fast) var(--ease-out);
}
button.dp-day:hover {
  background: var(--gold-100);
  color: var(--gold-600);
  transform: translateY(-1px);
}
.dp-day.is-out {
  color: var(--text-mute);
  opacity: 0.4;
  cursor: default;
}
.dp-day.is-today {
  box-shadow: inset 0 0 0 1px var(--gold-400);
}
.dp-day.is-active {
  background: linear-gradient(135deg, var(--gold-400), var(--gold-600));
  color: #241a04;
  font-weight: 700;
  box-shadow: 0 4px 12px rgba(194, 145, 58, 0.32);
}
.dp-day.is-off {
  opacity: 0.3;
  cursor: not-allowed;
}
.dp-foot {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
}

/* ---------------- 上传压缩进度 / 体积信息 ---------------- */
.dropzone-status {
  width: 100%;
  margin-top: 4px;
}
.dropzone-status:empty {
  display: none;
}
.dropzone-status-in {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  font-size: 12.5px;
  color: var(--text-soft);
  margin-bottom: 6px;
}
.dropzone-status-in .ds-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dropzone-status-in .ds-pct {
  font-family: var(--font-mono);
  font-weight: 700;
  color: var(--gold-600);
  flex: none;
}
.ds-bar {
  height: 5px;
  border-radius: 99px;
  background: var(--ink-100);
  overflow: hidden;
}
.ds-bar > i {
  display: block;
  height: 100%;
  border-radius: 99px;
  background: linear-gradient(90deg, var(--gold-400), var(--gold-600));
  transition: width 300ms var(--ease-out);
}
.dropzone.is-busy {
  pointer-events: none;
  opacity: 0.85;
}
/* 已压缩标记 */
.file-saved {
  flex: none;
  padding: 2px 8px;
  border-radius: var(--r-pill);
  background: #e8f6ee;
  color: var(--green-500);
  font-size: 11.5px;
  font-weight: 650;
}
/* 后台配图控件里的体积信息 */
.pick-size {
  margin-top: 8px;
  font-size: 12.2px;
  line-height: 1.7;
}
.pick-size:empty {
  display: none;
}

/* ---------------- 通用提示卡 ---------------- */
.alert-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 26px;
  flex-wrap: wrap;
  padding: clamp(24px, 3vw, 34px);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: linear-gradient(120deg, var(--paper-2), #fff 60%, var(--gold-100));
}

/* ---------------- 产品列表页 ---------------- */
.page-head {
  position: relative;
  padding: calc(var(--nav-h) + 58px) 0 clamp(38px, 5vw, 64px);
  background: linear-gradient(180deg, var(--paper-2), var(--paper));
  border-bottom: 1px solid var(--line);
  overflow: hidden;
}
.page-head .grid-lines {
  opacity: 0.5;
}
.page-head h1 {
  font-size: clamp(28px, 3.4vw, 44px);
  margin: 12px 0 14px;
}
.breadcrumb {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 12.5px;
  color: var(--text-mute);
}
.breadcrumb a:hover {
  color: var(--gold-600);
}
.breadcrumb i {
  font-style: normal;
  opacity: 0.5;
}

.toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
  margin-bottom: 26px;
}
.filter-chips {
  display: flex;
  gap: 9px;
  flex-wrap: wrap;
}
.filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 40px;
  padding: 0 16px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--text-soft);
  font-size: 13.5px;
  font-weight: 550;
  cursor: pointer;
  transition: all var(--t-fast) var(--ease-out);
}
.filter-chip em {
  font-style: normal;
  font-size: 11.5px;
  padding: 1px 7px;
  border-radius: var(--r-pill);
  background: var(--ink-100);
  color: var(--text-mute);
}
.filter-chip:hover {
  color: var(--text);
  border-color: var(--ink-300);
  transform: translateY(-2px);
}
.filter-chip.is-active {
  background: var(--ink-800);
  border-color: var(--ink-800);
  color: #fff;
}
.filter-chip.is-active em {
  background: rgba(255, 255, 255, 0.2);
  color: #fff;
}
.search-box {
  position: relative;
  min-width: 260px;
  flex: 1;
  max-width: 340px;
}
.search-box svg {
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  width: 17px;
  height: 17px;
  color: var(--text-mute);
}
.search-box .input {
  padding-left: 42px;
}

.pager {
  display: flex;
  justify-content: center;
  gap: 8px;
  margin-top: 46px;
  flex-wrap: wrap;
}
.page-btn {
  min-width: 42px;
  height: 42px;
  padding: 0 14px;
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  background: var(--surface);
  color: var(--text-soft);
  font-size: 13.5px;
  font-weight: 550;
  cursor: pointer;
  transition: all var(--t-fast) var(--ease-out);
}
.page-btn:hover:not(:disabled) {
  color: var(--text);
  border-color: var(--ink-300);
  transform: translateY(-2px);
}
.page-btn.is-active {
  background: linear-gradient(135deg, var(--gold-400), var(--gold-600));
  border-color: var(--gold-600);
  color: #241a04;
  font-weight: 700;
}
.page-btn:disabled {
  opacity: 0.42;
  cursor: not-allowed;
}

/* ---------------- 产品详情 ---------------- */
.detail-grid {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: clamp(28px, 4vw, 56px);
  align-items: start;
}
.detail-media {
  min-width: 0;
}
.detail-info {
  min-width: 0;
}
@media (max-width: 1024px) {
  .detail-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}
.detail-main {
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--surface);
  cursor: zoom-in;
}
.detail-main img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  transition: opacity 220ms var(--ease-out);
}
.detail-thumbs {
  display: flex;
  gap: 12px;
  margin-top: 14px;
}
.thumb {
  width: 88px;
  height: 68px;
  padding: 0;
  border: 1.5px solid var(--line);
  border-radius: 12px;
  overflow: hidden;
  background: none;
  cursor: pointer;
  transition: all var(--t-fast) var(--ease-out);
  opacity: 0.66;
}
.thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.thumb:hover {
  opacity: 1;
  transform: translateY(-2px);
}
.thumb.is-active {
  border-color: var(--gold-500);
  opacity: 1;
  box-shadow: 0 0 0 3px rgba(194, 145, 58, 0.16);
}
.detail-zoom-tip {
  margin-top: 12px;
}
.detail-price {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px;
  padding: 20px 22px;
  border-radius: var(--r-md);
  background: var(--paper-2);
  border: 1px solid var(--line);
  margin-bottom: 20px;
}
.detail-trust {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin-top: 20px;
  font-size: 13px;
  color: var(--text-soft);
}
.detail-trust i {
  color: var(--green-500);
  font-style: normal;
  margin-right: 6px;
  font-weight: 700;
}
.detail-specs {
  margin-top: clamp(36px, 5vw, 62px);
  padding: clamp(26px, 3vw, 40px);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
}
.spec-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}
.spec-table tr + tr {
  border-top: 1px solid var(--line);
}
.spec-table th {
  width: 190px;
  text-align: left;
  padding: 15px 0;
  color: var(--text-mute);
  font-weight: 550;
  vertical-align: top;
}
.spec-table td {
  padding: 15px 0;
  color: var(--text);
}
@media (max-width: 600px) {
  .spec-table th {
    width: 110px;
  }
  .detail-price {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ---------------- 文章详情 ---------------- */
.article-head {
  max-width: 760px;
  margin: 0 auto;
  text-align: center;
}
.article-meta {
  font-size: 13px;
  color: var(--text-mute);
}
.article-hero {
  margin: 30px 0 40px;
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--sh-2);
}
.article-hero img {
  width: 100%;
  aspect-ratio: 2 / 1;
  object-fit: cover;
}
.article-body {
  max-width: 760px;
  margin: 0 auto;
  font-size: 15.6px;
  line-height: 2.05;
  color: var(--ink-600);
}
.article-body h3 {
  margin: 34px 0 12px;
  font-size: 19px;
  color: var(--ink-800);
}
.article-body p {
  margin: 0 0 18px;
}
.article-body b {
  color: var(--ink-800);
}
.article-cta {
  max-width: 760px;
  margin: 48px auto 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
  background: var(--paper-2);
}

/* ---------------- 关于我们 ---------------- */
.timeline {
  position: relative;
  padding-left: 34px;
}
.timeline::before {
  content: "";
  position: absolute;
  left: 7px;
  top: 8px;
  bottom: 8px;
  width: 1px;
  background: linear-gradient(180deg, var(--gold-400), var(--line));
}
.tl-item {
  position: relative;
  padding-bottom: 32px;
}
.tl-dot {
  position: absolute;
  left: -34px;
  top: 5px;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: var(--surface);
  border: 2px solid var(--gold-500);
  transition: all var(--t-base) var(--ease-out);
}
.tl-item:hover .tl-dot {
  background: var(--gold-500);
  box-shadow: 0 0 0 6px rgba(194, 145, 58, 0.16);
}
.tl-year {
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 700;
  color: var(--gold-600);
  letter-spacing: 0.08em;
}
.tl-item h4 {
  margin: 6px 0 6px;
  font-size: 16.5px;
}
.equip-list {
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--surface);
}
.equip-row {
  display: grid;
  grid-template-columns: 88px 1fr 1.2fr;
  gap: 18px;
  align-items: center;
  padding: 18px 22px;
  transition: background var(--t-fast);
}
.equip-row + .equip-row {
  border-top: 1px solid var(--line);
}
.equip-row:hover {
  background: var(--paper-2);
}
.equip-row b {
  font-size: 14.5px;
}
@media (max-width: 768px) {
  .equip-row {
    grid-template-columns: minmax(0, 1fr);
    gap: 8px;
  }
}

/* ---------------- 联系 / 询价表单 ---------------- */
.contact-grid {
  display: grid;
  grid-template-columns: 1fr 1.15fr;
  gap: clamp(28px, 4vw, 56px);
  align-items: start;
}
@media (max-width: 1024px) {
  .contact-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}
.contact-item {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 18px 0;
  border-bottom: 1px dashed var(--line);
}
.contact-ico {
  width: 42px;
  height: 42px;
  flex: none;
  display: grid;
  place-items: center;
  border-radius: 13px;
  background: var(--paper-2);
  border: 1px solid var(--line);
  font-size: 17px;
}
.contact-item b {
  display: block;
  font-size: 15px;
  margin-top: 2px;
}

.form-card {
  padding: clamp(24px, 3vw, 38px);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--sh-1);
}

/* 表单分组小标题：统一间距，避免行内 style 造成的节奏不一致 */
.form-step {
  font-size: 16px;
  margin: 30px 0 16px;
}
.form-card .form-step:first-of-type {
  margin-top: 0;
}

/* ---------------- 对称两栏布局（联系页等） ----------------
   两列严格等宽，下方通栏内容与两列整体同宽，
   避免「左边窄一点、右边宽一点」造成的视觉不对齐。 */
.stack-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 26px;
  align-items: start;
  margin-bottom: 26px;
}
.stack-col {
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-width: 0;
}
.block-title {
  font-size: 22px;
  margin: 0 0 10px;
}
.form-card-wide {
  width: 100%;
}
@media (max-width: 768px) {
  .stack-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 18px;
    margin-bottom: 18px;
  }
}

/* 配图预设：实物图预设另起一行，横向滚动，避免把抽屉撑高 */
.preset-scroll {
  display: flex;
  gap: 6px;
  margin-top: 6px;
  padding-bottom: 2px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: thin;
}
.preset-scroll::-webkit-scrollbar {
  height: 6px;
}
.preset-scroll::-webkit-scrollbar-thumb {
  background: #d5dbe2;
  border-radius: 99px;
}
.preset-scroll .mini-btn {
  flex: none;
}

/* 配图预览：完整显示不裁切，可点开看大图 */
.picker-field {
  min-width: 0;
}
.picker-thumb {
  position: relative;
  width: 148px;
  flex: none;
  padding: 0;
  border: 1px solid #e4e8ec;
  border-radius: 12px;
  background: #f7f8fa;
  overflow: hidden;
  cursor: zoom-in;
  display: block;
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
.picker-thumb:hover {
  border-color: var(--gold-500);
  box-shadow: 0 6px 18px rgba(16, 18, 22, 0.1);
}
.picker-thumb img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  /* contain：完整显示，不裁切，所见即所传 */
  object-fit: contain;
  background: #fff;
}
.picker-zoom {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 4px 6px;
  font-size: 11px;
  color: #fff;
  background: linear-gradient(transparent, rgba(16, 18, 22, 0.72));
  opacity: 0;
  transition: opacity var(--t-fast);
  text-align: center;
}
.picker-thumb:hover .picker-zoom,
.picker-thumb:focus-visible .picker-zoom {
  opacity: 1;
}
/* 触摸设备没有 hover，常驻显示提示 */
@media (hover: none) {
  .picker-zoom {
    opacity: 1;
  }
}

/* 抽屉里的表单：统一两列栅格（formGrid: true），字段不再忽宽忽窄 */
.drawer-body.has-form-grid > form {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px 16px;
  align-items: start;
}
.drawer-body.has-form-grid > form > .field + .field {
  margin-top: 0;
}
.drawer-body.has-form-grid > form > .span-2 {
  grid-column: 1 / -1;
}
.drawer-body.has-form-grid > form > .row-between {
  grid-column: 1 / -1;
}
@media (max-width: 600px) {
  .drawer-body.has-form-grid > form {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ---------------- 统一表单栅格 ----------------
   两列严格等宽（1fr 1fr）、行内控件顶部对齐、行高一致。
   不再依赖 .grid + .field 的隐式间距，避免任何宽度 / 缩放下的错位。 */
.form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px 18px;
  align-items: start;
}
.form-grid > .field,
.form-grid > .field + .field {
  margin-top: 0; /* 间距交给栅格 gap，清掉 .field + .field 的 margin */
  min-width: 0;
}
.form-grid > .span-2 {
  grid-column: 1 / -1;
}
/*
  栅格里的字段（.grid g-2 / g-3 …）：清掉「相邻字段上间距」。
  ------------------------------------------------------------
  用户反馈（截图）：后台「编辑案例」里，第二列「年份」比第一列「客户名称」低一截，
  输入框底边还压住了下面「关联分类」的标签。

  根因：style.css 有一条全局规则
      .field + .field { margin-top: 18px }
  栅格里的第二个字段也是「相邻的 .field」，于是被额外往下推了 18px ——
  标签和第一列对不齐，而且它的输入框底边正好顶到栅格外那个字段的标签上。

  .form-grid 早就处理过这件事（上面那条 margin-top: 0），
  但后台抽屉用的是 .grid g-2，没有这层重置，所以只有抽屉里错位。
  这里把同一套规则补到 .grid 上，任何列数都适用。
*/
.grid > .field,
.form-grid > .field + .field {
  margin-top: 0;
  min-width: 0;
}
/*
  栅格**后面**紧跟的字段需要有上间距。
  为什么：.field + .field 只在「上一个兄弟也是 .field」时生效，
  而上一个兄弟是栅格时它不生效 —— 结果栅格下面的字段完全没有间距，
  紧贴着栅格底边，看着像被压住了。
*/
.grid + .field,
.form-grid + .field {
  margin-top: 18px;
}
.form-grid > .field {
  display: flex;
  flex-direction: column;
}
/* 标签文字高度统一，带 * 与不带 * 也不会让控件上下错位 */
.form-grid .field-label {
  min-height: 20px;
}
.form-grid .input,
.form-grid .select-trigger {
  flex: none;
}
.form-grid .textarea {
  flex: 1 1 auto;
}
@media (max-width: 768px) {
  .form-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 14px;
  }
}

/* 表单底部按钮行 */
.form-actions {
  margin-top: 22px;
  gap: 14px;
  flex-wrap: wrap;
}
.form-actions .btn-primary {
  flex: 1 1 200px;
  min-width: 0;
}
.form-note {
  margin: 16px 0 0;
}

.craft-checks {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(122px, 1fr));
  gap: 10px;
}
.craft-check {
  padding: 11px 13px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  align-items: center;
  gap: 9px;
  transition: all var(--t-fast) var(--ease-out);
  background: var(--surface);
}
.craft-check:hover {
  border-color: var(--line-strong);
  background: var(--paper-2);
}
.craft-check:has(input:checked) {
  border-color: var(--gold-500);
  background: var(--gold-100);
  color: var(--gold-600);
  font-weight: 600;
}
.craft-check .check-box {
  width: 17px;
  height: 17px;
  margin: 0;
}
.craft-check .check-box::after {
  left: 5px;
  top: 1.5px;
  width: 4px;
  height: 8px;
}

.progress-wrap {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 22px;
  padding-bottom: 20px;
  border-bottom: 1px dashed var(--line);
}
.progress-bar {
  flex: 1;
  height: 6px;
  border-radius: 99px;
  background: var(--ink-100);
  overflow: hidden;
}
.progress-bar > i {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 99px;
  background: linear-gradient(90deg, var(--gold-400), var(--gold-600));
  transition: width 520ms var(--ease-out);
}
.progress-text {
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 700;
  color: var(--gold-600);
  min-width: 40px;
  text-align: right;
}

.file-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 12px;
}
.file-chip {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 9px 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--paper-2);
  font-size: 13px;
  animation: faqIn 320ms var(--ease-out);
}
.file-ico {
  width: 30px;
  height: 30px;
  flex: none;
  display: grid;
  place-items: center;
  border-radius: 8px;
  overflow: hidden;
  background: var(--ink-100);
}
.file-ico img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.file-name {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.file-x {
  border: 0;
  background: transparent;
  color: var(--text-mute);
  cursor: pointer;
  padding: 4px 6px;
  border-radius: 6px;
  transition: all var(--t-fast);
}
.file-x:hover {
  background: #fdeceb;
  color: var(--rose-500);
}

/* ---------------- 进度查询 ---------------- */
.track-card {
  padding: clamp(24px, 3vw, 38px);
}
.track-meta {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px;
  margin: 22px 0 26px;
  padding: 20px 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.track-meta b {
  display: block;
  font-size: 14.5px;
  margin-top: 2px;
}
@media (max-width: 768px) {
  .track-meta {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
.track-steps {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.track-step {
  display: flex;
  gap: 16px;
  padding: 14px 0;
  position: relative;
  opacity: 0.5;
}
.track-step:not(:last-child)::after {
  content: "";
  position: absolute;
  left: 15px;
  top: 42px;
  bottom: -4px;
  width: 1px;
  background: var(--line);
}
.track-step.is-done,
.track-step.is-now {
  opacity: 1;
}
.ts-dot {
  width: 31px;
  height: 31px;
  flex: none;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  font-size: 12.5px;
  font-weight: 700;
  color: var(--text-mute);
  transition: all var(--t-base) var(--ease-spring);
}
.track-step.is-done .ts-dot {
  background: var(--green-500);
  border-color: var(--green-500);
  color: #fff;
}
.track-step.is-now .ts-dot {
  background: linear-gradient(135deg, var(--gold-400), var(--gold-600));
  border-color: var(--gold-600);
  color: #241a04;
  box-shadow: 0 0 0 6px rgba(194, 145, 58, 0.16);
  animation: pulse 2s var(--ease-in-out) infinite;
}
@keyframes pulse {
  50% {
    box-shadow: 0 0 0 11px rgba(194, 145, 58, 0.08);
  }
}
.track-step b {
  font-size: 15px;
}
.track-tip {
  margin-top: 22px;
  padding: 14px 18px;
  border-radius: var(--r-md);
  background: var(--gold-100);
  font-size: 13.5px;
  color: var(--gold-600);
}

/* ============================================================
   后台管理 admin
   ============================================================ */
.admin-body {
  background: #f4f6f8;
  color: var(--ink-800);
  overflow-x: hidden;
}
/*
  后台骨架：侧栏固定 + 右侧内容独立滚动。
  这里刻意不用 position: sticky —— html/body 上的 overflow-x: hidden
  会把滚动容器从视口变成 body，导致 sticky 在部分浏览器/缩放下失效
  （症状：往下滚时侧栏跟着滚走，深色背景提前结束）。
  改成「外壳固定 100vh，主区自己滚」，无论视口怎么缩放侧栏都不会动。
*/
.admin-shell {
  display: grid;
  grid-template-columns: 246px minmax(0, 1fr);
  height: 100vh;
  overflow: hidden;
}
.admin-main {
  min-width: 0;
  height: 100%;
  overflow-y: auto;
  overscroll-behavior-y: contain;
  display: flex;
  flex-direction: column;
}
.admin-side {
  /* 兜底：即使外壳高度被浏览器改掉，也尽量吸住 */
  position: sticky;
  top: 0;
  height: 100%;
  max-height: 100vh;
  display: flex;
  flex-direction: column;
  padding: 20px 16px;
  background: linear-gradient(180deg, #16191f, #0e1013);
  color: #e7e9ec;
  overflow: auto;
}
.admin-brand {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 6px 8px 22px;
  color: #fff;
  font-weight: 700;
  letter-spacing: 0.03em;
}
.admin-brand small {
  display: block;
  font-size: 10px;
  letter-spacing: 0.2em;
  color: rgba(255, 255, 255, 0.42);
  font-weight: 500;
}
.admin-nav {
  display: flex;
  flex-direction: column;
  gap: 3px;
  flex: 1;
}
.admin-nav-group {
  padding: 18px 12px 8px;
  font-size: 10.5px;
  letter-spacing: 0.18em;
  color: rgba(255, 255, 255, 0.32);
  text-transform: uppercase;
}
.admin-link {
  position: relative;
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 11px 13px;
  border-radius: 11px;
  color: rgba(255, 255, 255, 0.68);
  font-size: 13.8px;
  font-weight: 500;
  transition: all var(--t-fast) var(--ease-out);
  cursor: pointer;
}
.admin-link svg {
  width: 17px;
  height: 17px;
  flex: none;
  opacity: 0.8;
}
.admin-link:hover {
  background: rgba(255, 255, 255, 0.07);
  color: #fff;
  transform: translateX(2px);
}
.admin-link.is-active {
  background: linear-gradient(100deg, rgba(194, 145, 58, 0.22), rgba(194, 145, 58, 0.06));
  color: #fff;
  font-weight: 620;
}
.admin-link.is-active::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 3px;
  height: 20px;
  border-radius: 3px;
  background: var(--gold-400);
  transform: translateY(-50%);
}
.admin-link .tag {
  margin-left: auto;
  min-width: 20px;
  height: 18px;
  padding: 0 6px;
  display: grid;
  place-items: center;
  border-radius: 99px;
  background: var(--rose-500);
  color: #fff;
  font-size: 10.5px;
  font-weight: 700;
}
/* 显示开关：已关闭数量 */
.admin-link .badge-dot {
  margin-left: auto;
  min-width: 20px;
  height: 18px;
  padding: 0 6px;
  display: grid;
  place-items: center;
  border-radius: 99px;
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
  font-size: 10.5px;
  font-weight: 700;
}
.admin-side-foot {
  padding: 14px 10px 4px;
  border-top: 1px solid rgba(255, 255, 255, 0.09);
  font-size: 11.5px;
  color: rgba(255, 255, 255, 0.4);
}
.admin-content {
  padding: clamp(18px, 2.4vw, 30px);
  display: flex;
  flex-direction: column;
  gap: 22px;
  min-width: 0;
}
/* 面板内的表格横向滚动，不要撑破整个页面（否则固定侧栏会与内容重叠） */
.admin-content .panel,
.admin-content .table-wrap {
  min-width: 0;
  max-width: 100%;
}
.admin-content .table-wrap {
  overflow-x: auto;
  overscroll-behavior-x: contain;
}
/* 后台表格横向滚动条做细一点，避免压住最后一行 */
.admin-content .table-wrap::-webkit-scrollbar {
  height: 9px;
}
.admin-content .table-wrap::-webkit-scrollbar-thumb {
  background: #c9cfd6;
  border: 2px solid #fff;
  border-radius: 99px;
}
.admin-content .table-wrap::-webkit-scrollbar-track {
  background: #f7f8fa;
}
.admin-top {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 14px clamp(18px, 2.4vw, 32px);
  background: rgba(255, 255, 255, 0.86);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid #e4e8ec;
}
.admin-top h1 {
  font-family: var(--font-sans);
  font-size: 18px;
  font-weight: 680;
  letter-spacing: 0;
}
.admin-top .crumb {
  font-size: 12px;
  color: var(--text-mute);
  margin-top: 2px;
}
.admin-content {
  padding: clamp(18px, 2.4vw, 30px);
  display: flex;
  flex-direction: column;
  gap: 22px;
}
.admin-user {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 12px 6px 6px;
  border: 1px solid #e4e8ec;
  border-radius: var(--r-pill);
  background: #fff;
  cursor: pointer;
  transition: all var(--t-fast);
}
.admin-user:hover {
  border-color: var(--line-strong);
  box-shadow: var(--sh-1);
}
.admin-user .avatar {
  width: 32px;
  height: 32px;
  font-size: 13px;
  line-height: 1;
  overflow: hidden;
  border-radius: 50%;
}
.admin-user b {
  font-size: 13.5px;
}
.admin-user span {
  font-size: 11px;
  color: var(--text-mute);
  display: block;
}

.metric-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
}
@media (max-width: 1200px) {
  .metric-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
.metric {
  position: relative;
  padding: 20px 22px;
  border: 1px solid #e4e8ec;
  border-radius: var(--r-md);
  background: #fff;
  overflow: hidden;
  transition: all var(--t-base) var(--ease-out);
}
.metric:hover {
  transform: translateY(-3px);
  box-shadow: var(--sh-2);
  border-color: var(--line-strong);
}
.metric-label {
  font-size: 12.5px;
  color: var(--text-mute);
  display: flex;
  align-items: center;
  gap: 7px;
}
.metric-num {
  font-family: var(--font-display);
  font-size: 30px;
  font-weight: 650;
  line-height: 1.2;
  margin: 8px 0 4px;
}
.metric-foot {
  font-size: 12px;
  color: var(--text-soft);
  display: flex;
  align-items: center;
  gap: 6px;
}
.metric-foot .up {
  color: var(--green-500);
  font-weight: 650;
}
.metric-foot .down {
  color: var(--rose-500);
  font-weight: 650;
}
.metric-spark {
  position: absolute;
  right: 14px;
  top: 16px;
  width: 62px;
  height: 34px;
  opacity: 0.55;
}

.panel {
  border: 1px solid #e4e8ec;
  border-radius: var(--r-md);
  background: #fff;
  overflow: hidden;
}
.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 16px 20px;
  border-bottom: 1px solid #eceff2;
  flex-wrap: wrap;
}
.panel-head h3 {
  font-size: 15px;
  font-family: var(--font-sans);
}
.panel-head .sub {
  font-size: 12px;
  color: var(--text-mute);
  margin-top: 2px;
}
.panel-body {
  padding: 20px;
}
.panel-body.flush {
  padding: 0;
}

.table-wrap {
  overflow-x: auto;
}
table.data {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.6px;
  min-width: 660px;
  table-layout: fixed;
}

/* ---------- 列对齐契约 ----------
   表头与单元格统一使用 .al-left / .al-center / .al-right，
   由 admin.js 的 table() 同时写到 th 与 td 上，保证两边永远一致。 */
table.data .al-left {
  text-align: left;
}
table.data .al-center {
  text-align: center;
}
table.data .al-right {
  text-align: right;
}
/* 居中/右对齐的单元格里，块级内容要跟着走，否则会看起来没对齐 */
table.data .al-center > *,
table.data .al-right > * {
  text-align: inherit;
}

table.data th {
  padding: 12px 16px;
  font-size: 12px;
  font-weight: 650;
  letter-spacing: 0.04em;
  color: var(--text-mute);
  background: #fafbfc;
  border-bottom: 1px solid #eceff2;
  white-space: nowrap;
  text-align: left;
  vertical-align: middle;
}
table.data td {
  padding: 13px 16px;
  border-bottom: 1px solid #f1f3f5;
  vertical-align: middle;
  line-height: 1.55;
  overflow-wrap: break-word;
}
/* 首列与末列内边距对齐面板边缘 */
table.data th:first-child,
table.data td:first-child {
  padding-left: 20px;
}
table.data th:last-child,
table.data td:last-child {
  padding-right: 20px;
}

table.data tbody tr {
  transition: background var(--t-fast);
}
table.data tbody tr:hover {
  background: #fafbfc;
}
table.data tbody tr.is-checked {
  background: #fdf8ee;
}

/* 复选框列：表头与内容都严格居中 */
table.data th.al-center .check,
table.data td.al-center .check {
  display: inline-flex;
  vertical-align: middle;
}

/* 主标题列 */
table.data .cell-title {
  display: flex;
  align-items: center;
  gap: 11px;
  text-align: left;
  min-width: 0;
}
table.data .cell-title > div {
  min-width: 0;
}
table.data .cell-title .t-strong,
table.data .cell-title .t-sub {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
table.data .cell-thumb {
  width: 44px;
  height: 34px;
  border-radius: 8px;
  object-fit: cover;
  border: 1px solid #eceff2;
  flex: none;
  background: #f4f5f7;
}
table.data .t-strong {
  font-weight: 620;
  color: var(--ink-800);
}
table.data .t-sub {
  font-size: 11.8px;
  color: var(--text-mute);
}
/* 时间 / 手机号 / 编号等等宽信息 */
table.data .num,
table.data .mono {
  font-family: var(--font-mono);
  font-size: 12.6px;
  letter-spacing: -0.01em;
  white-space: nowrap;
}
/* 长文本单元格：单行省略，避免行高不一致造成的错位 */
table.data .cell-clip {
  max-width: 420px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/*
  注意：flex 容器里的子元素不受父级 text-align 影响，
  所以所有「内容块」统一用 inline-flex + 水平居中，
  这样列的居中/右对齐才和表头严格一致。
*/
table.data .cell-badges {
  display: inline-flex;
  /* 徽标不换行：一行高一行低看着就是没对齐（状态列已留够宽度） */
  flex-wrap: nowrap;
  gap: 6px;
  align-items: center;
  justify-content: center;
  vertical-align: middle;
  text-align: center;
  white-space: nowrap;
}
table.data .al-left .cell-badges {
  justify-content: flex-start;
  text-align: left;
}
table.data .al-right .cell-badges {
  justify-content: flex-end;
  text-align: right;
}
table.data .cell-tags {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/*
  「前台显示」列的开关。
  开关原本是「轨道 + 显示/隐藏文字」并排，只让整体居中的话，
  视觉主体（轨道）会被右侧文字挤偏，和居中的表头看起来就是错位的。
  这里把这一列的开关改成上下两行：轨道在上、文字在下，
  轨道因此天然居中，不需要任何像素级位移 hack，任何视口宽度都成立。
*/
table.data td.al-center .switch,
table.data th.al-center .switch {
  justify-content: center;
}
table.data td.al-center .switch-sm {
  flex-direction: column;
  gap: 4px;
  align-items: center;
}
table.data td.al-center .switch-sm .switch-track {
  flex: none;
}
table.data td.al-center .switch-sm .switch-text {
  width: auto;
  min-width: 0;
  font-size: 11px;
  line-height: 1;
  text-align: center;
}
table.data td.al-right .switch {
  justify-content: flex-end;
}
/* 操作列：按钮组右对齐，与表头一致 */
table.data .ops {
  display: flex;
  gap: 6px;
  justify-content: flex-end;
  flex-wrap: nowrap;
}
table.data .al-center .ops {
  justify-content: center;
}
table.data .al-left .ops {
  justify-content: flex-start;
}
/* 表格内的小号开关（列表页「前台显示」列） */
.switch-sm {
  gap: 8px;
  font-size: 12.5px;
  display: inline-flex;
  width: 100%;
  justify-content: center;
}
.switch-sm .switch-track {
  width: 38px;
  height: 22px;
}
.switch-sm .switch-track::after {
  width: 16px;
  height: 16px;
}
.switch-sm input:checked + .switch-track::after {
  transform: translateX(16px);
}
.switch-sm input:disabled + .switch-track {
  opacity: 0.45;
  cursor: not-allowed;
}
.switch-sm .switch-text {
  min-width: 28px;
  text-align: left;
  white-space: nowrap;
}

/* 显示开关面板 */
.switch-cell {
  min-width: 0;
}
.switch-cell .t-strong {
  font-size: 14px;
}
.switch-cell .t-sub {
  margin-top: 2px;
}
.key-code {
  display: inline-block;
  padding: 3px 9px;
  border-radius: 7px;
  background: #f1f3f5;
  border: 1px solid #e4e8ec;
  color: var(--ink-600);
  font-family: var(--font-mono);
  font-size: 11.5px;
  white-space: nowrap;
}
.preset-btn {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  padding: 13px 17px;
  border: 1px solid #e4e8ec;
  border-radius: var(--r-md);
  background: #fff;
  cursor: pointer;
  text-align: left;
  transition: all var(--t-fast) var(--ease-out);
}
.preset-btn b {
  font-size: 13.6px;
  color: var(--ink-800);
}
.preset-btn span {
  font-size: 11.6px;
  color: var(--text-mute);
}
.preset-btn:hover {
  border-color: var(--gold-500);
  background: var(--gold-100);
  transform: translateY(-2px);
  box-shadow: var(--sh-1);
}
.preset-btn:hover b {
  color: var(--gold-600);
}

/* 被前台显示开关关闭时，区块直接从 DOM 移除；
   这里额外保证空区块不会留下多余间距 */
[data-section]:empty {
  display: none;
}

.mini-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 30px;
  padding: 0 11px;
  border: 1px solid #e4e8ec;
  border-radius: 9px;
  background: #fff;
  color: var(--ink-600);
  font-size: 12.5px;
  font-weight: 550;
  cursor: pointer;
  transition: all var(--t-fast) var(--ease-out);
  white-space: nowrap;
}
.mini-btn:hover {
  border-color: var(--gold-500);
  color: var(--gold-600);
  background: var(--gold-100);
  transform: translateY(-1px);
}
.mini-btn.danger:hover {
  border-color: #f3c9c6;
  color: var(--rose-500);
  background: #fdf3f2;
}

.admin-toolbar {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.admin-toolbar .input,
.admin-toolbar .select {
  min-height: 40px;
  height: 40px;
}
.admin-toolbar .search-box .input {
  height: 40px;
  min-height: 40px;
}
.seg {
  display: inline-flex;
  padding: 3px;
  border: 1px solid #e4e8ec;
  border-radius: var(--r-pill);
  background: #fff;
}
.seg button {
  border: 0;
  background: transparent;
  padding: 7px 15px;
  border-radius: var(--r-pill);
  font-size: 13px;
  font-weight: 550;
  color: var(--text-soft);
  cursor: pointer;
  transition: all var(--t-fast) var(--ease-out);
}
.seg button.is-active {
  background: var(--ink-800);
  color: #fff;
}

/* 迷你柱状图 / 折线图 */
.chart {
  display: flex;
  align-items: flex-end;
  gap: 10px;
  height: 168px;
  padding-top: 10px;
}
.chart-col {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  gap: 8px;
  height: 100%;
}
.chart-bar {
  width: 100%;
  max-width: 34px;
  border-radius: 7px 7px 3px 3px;
  background: linear-gradient(180deg, var(--gold-400), var(--gold-600));
  height: 0;
  transition: height 900ms var(--ease-out);
  position: relative;
}
.chart-bar:hover::after {
  content: attr(data-v);
  position: absolute;
  top: -26px;
  left: 50%;
  transform: translateX(-50%);
  padding: 3px 8px;
  border-radius: 6px;
  background: var(--ink-800);
  color: #fff;
  font-size: 11px;
  white-space: nowrap;
}
.chart-label {
  font-size: 11px;
  color: var(--text-mute);
}
.spark-line {
  width: 100%;
  height: 60px;
}

.donut-wrap {
  display: flex;
  align-items: center;
  gap: 26px;
  flex-wrap: wrap;
}
.donut-legend {
  display: flex;
  flex-direction: column;
  gap: 11px;
  font-size: 13px;
}
.donut-legend span {
  display: flex;
  align-items: center;
  gap: 9px;
}
.donut-legend i {
  width: 10px;
  height: 10px;
  border-radius: 3px;
  flex: none;
}

/* 登录页 */
.login-page {
  min-height: 100vh;
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  background: #f4f6f8;
}
@media (max-width: 1024px) {
  .login-page {
    grid-template-columns: minmax(0, 1fr);
  }
  .login-aside {
    display: none;
  }
}
.login-aside {
  position: relative;
  overflow: hidden;
  padding: 52px;
  color: #fff;
  background: radial-gradient(720px 460px at 20% 20%, #23282f, #0b0d10 70%);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
.login-aside::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(400px 260px at 82% 78%, rgba(194, 145, 58, 0.32), transparent 70%);
}
.login-aside > * {
  position: relative;
  z-index: 1;
}
.login-form-wrap {
  display: grid;
  place-items: center;
  padding: 40px 24px;
}
.login-card {
  width: min(100%, 400px);
}
.login-card h1 {
  font-family: var(--font-sans);
  font-size: 25px;
  margin-bottom: 8px;
}
.demo-tip {
  margin-top: 22px;
  padding: 14px 16px;
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-md);
  background: #fff;
  font-size: 12.8px;
  color: var(--text-soft);
  line-height: 1.9;
}
.demo-tip b {
  color: var(--gold-600);
  font-family: var(--font-mono);
}
.pwd-wrap {
  position: relative;
}
.pwd-toggle {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  border: 0;
  background: transparent;
  color: var(--text-mute);
  cursor: pointer;
  padding: 8px 10px;
  border-radius: 8px;
  font-size: 12.5px;
}
.pwd-toggle:hover {
  background: var(--ink-100);
  color: var(--text);
}

/* 设置页小卡 */
.setting-row {
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: 20px;
  padding: 18px 0;
  align-items: start;
}
.setting-row + .setting-row {
  border-top: 1px solid #f1f3f5;
}
.setting-row > label {
  font-size: 13.5px;
  font-weight: 600;
  padding-top: 13px;
  color: var(--ink-700);
  /* 标签右侧放「前台显示」开关（系统设置里逐项控制） */
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.setting-label-text {
  min-width: 0;
}
.setting-switch {
  flex: none;
}
.setting-row .hint {
  font-size: 12px;
  color: var(--text-mute);
  margin-top: 6px;
}
@media (max-width: 768px) {
  .setting-row {
    grid-template-columns: minmax(0, 1fr);
    gap: 8px;
  }
  .setting-row > label {
    padding-top: 0;
    /* 小屏上开关挪到标签下方，避免和文字挤在一起 */
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
  }
}

/* ============================================================
   手机端：把数据表格变成「卡片」列表
   ------------------------------------------------------------
   8 列挤在 375px 里会把中文逐字换行，完全没法看。
   手机端改为每行一张卡片：
     · 第一列（产品 / 案例 / 资讯…）当卡片标题，带缩略图
     · 「操作」列固定在卡片底部，按钮占满整行，方便点按
     · 其余列两列排布，字段名由 td 的 data-label 提供
   表格结构完全不动，只在 CSS 层切换，桌面端不受影响。
   ============================================================ */
@media (max-width: 768px) {
  .admin-content .table-wrap {
    overflow-x: visible;
    padding: 0 14px 14px;
  }
  table.data[data-cards] {
    display: block;
    min-width: 0;
    width: 100%;
  }
  table.data[data-cards] > thead {
    /* 表头在卡片模式下没有意义，隐藏（字段名走 data-label） */
    display: none;
  }
  table.data[data-cards] > tbody {
    display: block;
  }
  table.data[data-cards] > tbody > tr {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px 12px;
    align-items: start;
    margin: 12px 0 0;
    padding: 14px;
    border: 1px solid #e8ecf0;
    border-radius: 14px;
    background: #fff;
    box-shadow: 0 1px 2px rgba(16, 18, 22, 0.03);
  }
  table.data[data-cards] > tbody > tr:hover {
    background: #fff;
  }
  table.data[data-cards] > tbody > tr.is-checked {
    border-color: var(--gold-400);
    box-shadow: 0 0 0 3px rgba(194, 145, 58, 0.12);
  }
  /* 所有单元格统一成「标签 + 值」的小块 */
  table.data[data-cards] > tbody > tr > td {
    display: block;
    grid-column: span 1;
    width: auto !important;
    padding: 0;
    border: 0;
    text-align: left !important;
    min-width: 0;
    font-size: 13px;
    line-height: 1.6;
    overflow-wrap: anywhere;
  }
  /* 字段名 */
  table.data[data-cards] > tbody > tr > td[data-label]::before {
    content: attr(data-label);
    display: block;
    font-size: 11px;
    letter-spacing: 0.04em;
    color: var(--text-mute);
    margin-bottom: 3px;
  }
  /*
    ============================================================
    手机端卡片的排布：完全由 data-card 属性决定
    ------------------------------------------------------------
    列定义里显式声明每一格在卡片里怎么放（admin.js 的 COLUMNS[].card），
    渲染成 data-card="title|full|half|hide|ops"。
    为什么不用 CSS 的 :has / :first-child 去猜：
      原来写 `td[data-label]:has(+ td)` 想选「标题那格」，
      结果它匹配「后面还有任何单元格的所有 td」= 除最后一格之外全部，
      徽标、开关、按钮全被拉成单独一行，卡片被拉得极长（用户截图反馈过）。
      而且同一个列名（比如「分类」）在不同面板要不同处理，
      靠列名做选择器必然打架。显式声明最稳，也方便测试核对。
    ============================================================ */
  /* 标题：整行，不显示字段名 */
  table.data[data-cards] > tbody > tr > td[data-card="title"] {
    grid-column: 1 / -1;
    border-bottom: 1px solid #f1f3f5;
    padding-bottom: 11px;
  }
  table.data[data-cards] > tbody > tr > td[data-card="title"]::before {
    display: none;
  }
  /* 整行字段（长文本：描述、内容、关键词、联系方式…） */
  table.data[data-cards] > tbody > tr > td[data-card="full"] {
    grid-column: 1 / -1;
  }
  /* 手机上不显示的次要字段 */
  table.data[data-cards] > tbody > tr > td[data-card="hide"] {
    display: none;
  }
  /*
    复选框列：绝对定位到卡片右上角。
    ⚠️ 只认 data-check-col 这个显式标记，不要用「没有 data-label」来选 ——
    那样任何忘记写 data-label 的单元格都会被绝对定位、几格叠在一起
    （显示开关面板和操作日志真的这样叠过，用户截图看到一团乱）。
  */
  table.data[data-cards] > tbody > tr > td[data-check-col] {
    position: absolute;
    top: 14px;
    right: 14px;
    grid-column: auto !important;
    padding: 0 !important;
    border: 0 !important;
    width: auto !important;
  }
  /*
    兜底：万一还有没写 data-label 也没有 data-check-col 的单元格，
    让它整行显示 —— 宁可多占一行，也绝不重叠。
  */
  table.data[data-cards] > tbody > tr > td:not([data-label]):not([data-check-col]) {
    grid-column: 1 / -1;
  }
  /*
    产品的「工艺标签」：标题里已经带了分类，这里合成
    「工艺标签 / 分类名」一行，用 flex 让字段名和内容并排。
  */
  table.data[data-cards] > tbody > tr > td[data-label="工艺标签"] {
    display: flex;
    align-items: baseline;
    gap: 8px;
    min-width: 0;
  }
  table.data[data-cards] > tbody > tr > td[data-label="工艺标签"]::before {
    content: attr(data-label) " / " attr(data-cat);
    margin-bottom: 0;
    flex: none;
  }
  table.data[data-cards] .cell-title {
    align-items: center;
    gap: 11px;
  }
  table.data[data-cards] .cell-thumb {
    width: 52px;
    height: 40px;
    border-radius: 8px;
  }
  table.data[data-cards] .cell-title .t-strong {
    font-size: 14.5px;
    line-height: 1.4;
  }
  table.data[data-cards] .cell-title .t-sub {
    font-size: 12px;
    margin-top: 2px;
  }
  table.data[data-cards] .cell-tags {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  table.data[data-cards] .cell-title {
    align-items: center;
    gap: 11px;
  }
  table.data[data-cards] .cell-thumb {
    width: 52px;
    height: 40px;
    border-radius: 8px;
  }
  table.data[data-cards] .cell-title .t-strong {
    font-size: 14.5px;
    line-height: 1.4;
  }
  table.data[data-cards] .cell-title .t-sub {
    font-size: 12px;
    margin-top: 2px;
  }
  /* 卡片本身作为定位上下文，复选框才能贴到右上角 */
  table.data[data-cards] > tbody > tr {
    position: relative;
  }
  /* 长文本（工艺标签、地址等）允许换行，不要省略号截断 */
  table.data[data-cards] .cell-tags,
  table.data[data-cards] .cell-clip {
    display: block;
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
  }
  /* 徽标、开关、按钮组一律靠左，省空间 */
  table.data[data-cards] .cell-badges,
  table.data[data-cards] .al-right .cell-badges {
    justify-content: flex-start;
    text-align: left;
  }
  table.data[data-cards] .switch {
    justify-content: flex-start;
  }
  /* 开关改成「轨道 + 文字」横排（卡片里高度更省） */
  table.data[data-cards] td.al-center .switch-sm {
    flex-direction: row;
    align-items: center;
    gap: 8px;
  }
  /* 操作列：固定在卡片底部，所有按钮平分一行，方便点按 */
  table.data[data-cards] > tbody > tr > td[data-label="操作"] {
    grid-column: 1 / -1;
    margin-top: 2px;
    padding-top: 11px;
    border-top: 1px solid #f1f3f5;
  }
  table.data[data-cards] > tbody > tr > td[data-label="操作"]::before {
    display: none;
  }
  /*
    按钮一行排开，平分宽度。
    原来是 repeat(2, 1fr)：3 个按钮（预览/编辑/删除）时第 3 个被挤到下一行，
    看起来就是「按钮各占一行」，非常占地方（用户截图反馈过）。
    改成 flex 不换行 + 等分，2 个或 3 个都在同一行。
  */
  table.data[data-cards] .ops {
    display: flex;
    flex-wrap: nowrap;
    gap: 8px;
  }
  table.data[data-cards] .ops > * {
    flex: 1 1 0;
    min-width: 0;
  }
  table.data[data-cards] .ops .mini-btn {
    /* .mini-btn 有固定 height:30px，必须显式覆盖，
       否则卡片里按钮会被撑高、把单元格顶出卡片右边缘 */
    height: auto;
    width: auto;
    min-width: 0;
    min-height: 42px;
    padding-left: 6px;
    padding-right: 6px;
    justify-content: center;
    font-size: 13px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  /* 空态单元格（无数据 / 无结果）不要卡片边框 */
  table.data[data-cards] > tbody > tr:has(> td[colspan]) {
    display: block;
    border: 0;
    box-shadow: none;
    padding: 0;
  }
  table.data[data-cards] > tbody > tr > td[colspan] {
    grid-column: 1 / -1;
  }
  /*
    极窄机型（≤340px）才把卡片内字段改成单列。
    原来写的是 ≤400px —— 那是主流手机宽度，结果 390/414 的机器上
    每个字段都独占一行，卡片被拉得极长（用户截图反馈过）。
    字段都是短值（价格、数量、状态），两列在 320px 也放得下。
  */
  @media (max-width: 340px) {
    table.data[data-cards] > tbody > tr {
      grid-template-columns: minmax(0, 1fr);
    }
  }

  /* 卡片模式下的面板头部与工具条：尽量一行放得下，放不下就换行 */
  .admin-content .panel-head {
    padding: 14px 16px;
    gap: 10px;
  }
  .admin-content .panel-head h3 {
    font-size: 15px;
  }
  .admin-content .panel-body.flush {
    padding: 0;
  }
  .admin-content .admin-toolbar {
    gap: 8px;
  }
  /* 搜索框独占一行，分类筛选条另起一行 */
  .admin-content .admin-toolbar .search-box {
    flex: 1 1 100%;
    min-width: 0 !important;
  }
  .admin-content .admin-toolbar .search-box .input {
    width: 100%;
  }
  .admin-content .admin-toolbar .seg {
    max-width: 100%;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .admin-content .admin-toolbar .seg::-webkit-scrollbar {
    display: none;
  }
  /* 后台工具条按钮：46px，与前台 .btn 的手机端最小尺寸保持一致 */
  .admin-content .admin-toolbar .btn,
  .admin-content .panel-head .btn {
    min-height: 46px;
  }
  .admin-content .pager {
    padding: 10px 14px;
  }
  .admin-content .pager button {
    min-width: 40px;
    min-height: 40px;
  }
}

/* 后台响应式：侧栏收起 */
.admin-burger {
  display: none;
  width: 40px;
  height: 40px;
  border: 1px solid #e4e8ec;
  border-radius: 11px;
  background: #fff;
  cursor: pointer;
  place-items: center;
}
@media (max-width: 1024px) {
  .admin-shell {
    grid-template-columns: minmax(0, 1fr);
  }
  .admin-side {
    position: fixed;
    z-index: 200;
    width: 250px;
    transform: translateX(-104%);
    transition: transform 420ms var(--ease-out);
  }
  .admin-side.is-open {
    transform: none;
    box-shadow: 0 0 60px rgba(0, 0, 0, 0.4);
  }
  .admin-burger {
    display: grid;
  }
  .metric-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 600px) {
  .metric-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* 迷你列表 */
.list-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 13px 20px;
  transition: background var(--t-fast);
}
.list-row + .list-row {
  border-top: 1px solid #f1f3f5;
}
.list-row:hover {
  background: #fafbfc;
}
.list-row .dot-ico {
  width: 34px;
  height: 34px;
  flex: none;
  display: grid;
  place-items: center;
  border-radius: 10px;
  background: var(--gold-100);
  color: var(--gold-600);
  font-size: 14px;
  font-weight: 700;
}
.list-row .grow {
  flex: 1;
  min-width: 0;
}
.list-row .grow b {
  display: block;
  font-size: 13.8px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.list-row .grow span {
  font-size: 12px;
  color: var(--text-mute);
}

/* ============================================================
   后台文字换行修正
   ------------------------------------------------------------
   侧栏只有 246px（减去内边距剩 220px），而品牌名 + "ADMIN CONSOLE"
   加起来的宽度会超，导致「上海骋瑞实业有限公司」被折成两行、
   把导航整体挤下去。这里统一处理：
     · 品牌名与副标题都不换行，过长用省略号
     · 导航项文字不换行，过长省略（避免「AI 智能客服」折行）
     · 设置行标签不换行
   ============================================================ */
.admin-brand {
  min-width: 0;
}
.admin-brand .admin-brand-text {
  min-width: 0;
  flex: 1;
}
.admin-brand .admin-brand-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}
.admin-brand small {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  /* ADMIN CONSOLE 字距过大在 220px 内放不下，这里收紧一点 */
  letter-spacing: 0.16em;
}
/* 导航项：图标固定，文字不换行（避免「AI 智能客服」折行） */
.admin-link {
  min-width: 0;
  white-space: nowrap;
}
.admin-link > *:not(svg) {
  min-width: 0;
}
.admin-link .tag,
.admin-link .badge-dot {
  flex: none;
}
/* 设置行标签不换行（窄屏时下面的媒体查询会改成单列，不受影响） */
.setting-row > label {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* 后台页头标题与面包屑也不换行 */
.admin-top h1,
.admin-top .crumb {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ============================================================
   头像：确保文字「居中、且只有一个字」
   ------------------------------------------------------------
   曾经把「超级管理员」四个字塞进 34px 的圆里，折成三行、溢出容器。
   代码层已改为只取首字（admin.js 的 avatar()），这里做样式兜底。

   注意：不要用 ::first-letter + font-size:0 那套写法 ——
   ::first-letter 对 inline-grid / inline-flex 不生效（规范如此），
   结果就是「文字直接消失、圆圈里一片空白」。
   这里改用最稳的做法：单行、超出裁掉、强制水平垂直居中。
   ============================================================ */
.avatar,
.aic-avatar--text,
.aic-mini--text {
  display: inline-grid;
  place-items: center;
  overflow: hidden;
  white-space: nowrap;
  line-height: 1;
  text-align: center;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0;
  padding: 0;
}
/* 后台顶栏用户头像（42px）里的字稍大 */
.admin-user .avatar {
  font-size: 17px;
}
/* 列表/设置行里的 34px 头像：固定尺寸，不参与压缩 */
.cell-title .avatar {
  font-size: 15px;
  width: 34px;
  height: 34px;
  flex: none;
}
/* 头像里放图片时（后台可上传）铺满且不变形 */
.avatar > img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  border-radius: inherit;
}
/* 有图片时去掉金色底，避免图片透明部分透出黄色 */
.avatar.has-img {
  background: #fff;
  box-shadow: inset 0 0 0 1px #e4e8ec;
}
