/* ============================================================================
   Product pages, group archives and the catalogue index.

   One stylesheet for four visually different themes. Everything below paints with the
   --p-* tokens declared at the top, and that block is the only per-site part: the deploy
   script rewrites it to point at whatever the theme already calls its palette and type.
   Without that split there would be four copies of this file drifting apart.

   No literal colour appears past the bridge. A hard-coded #fff would look right on the
   three light themes and paint a white hole in dampfwerks/vapehub.
   ============================================================================ */

/* Vape Hubs — dark, neon accent, Manrope */
:root{
  --p-bg:var(--bg); --p-surface:var(--surface); --p-soft:var(--surface-2);
  --p-ink:var(--text); --p-dim:var(--dim); --p-line:var(--line);
  --p-accent:var(--neon); --p-on-accent:#05130E;
  --p-font:var(--font); --p-display:var(--font);
  --p-mono:ui-monospace,SFMono-Regular,Menlo,monospace;
  --p-r:var(--r); --p-max:1180px;
}

.pd-wrap{max-width:var(--p-max);margin:0 auto;padding:0 22px}

/* ---------- breadcrumb ---------------------------------------------------- */
/* min-height is load-bearing: with the webfont still swapping in, the crumb went from two
   lines to one on a 390px screen and pushed the whole hero down 24px (measured CLS 0.30 on
   the first site). Reserving the space costs nothing and the shift disappears. */
.pd-crumb{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:18px 0 26px;
  min-height:2.6em;font:500 11px/1.35 var(--p-mono);letter-spacing:.06em;
  text-transform:uppercase;color:var(--p-dim)}
.pd-crumb a{color:var(--p-dim);text-decoration:none}
.pd-crumb a:hover{color:var(--p-accent)}
.pd-crumb-here{color:var(--p-ink)}

/* ---------- hero ---------------------------------------------------------- */
.pd-hero{display:grid;grid-template-columns:minmax(0,0.82fr) minmax(0,1.18fr);
  gap:44px;align-items:start;padding-bottom:44px}
.pd-media{position:relative;border:1px solid var(--p-line);border-radius:var(--p-r);
  padding:16px;aspect-ratio:4/5;display:flex;align-items:center;justify-content:center;
  background:var(--p-soft)}
.pd-media.is-dark{background:#0b0c0e;border-color:#20222a}
/* <picture> only exists so the browser can pick WebP; it must not create a box.
   Without this the img stops being the flex child and max-height:100% loses its reference,
   so the photo renders at natural size and bursts the slot. */
.pd-media picture{display:contents}
.pd-media img{max-width:100%;max-height:100%;width:auto;height:auto;object-fit:contain}
.pd-media-badge{position:absolute;top:14px;left:14px}

.pd-eye{margin:0 0 12px;font:600 10.5px/1.3 var(--p-mono);letter-spacing:.16em;
  text-transform:uppercase;color:var(--p-accent)}
.pd-top h1{margin:0 0 14px;font-family:var(--p-display);font-size:clamp(26px,3.4vw,40px);
  line-height:1.1;letter-spacing:-.025em;font-weight:700;color:var(--p-ink)}
.pd-tag{margin:0 0 24px;font-size:15px;line-height:1.65;color:var(--p-dim);max-width:60ch}

.pd-actions{display:flex;flex-wrap:wrap;gap:10px;margin:0 0 28px}
.pd-cta{display:inline-flex;align-items:center;justify-content:center;padding:13px 22px;
  border-radius:var(--p-r);background:var(--p-accent);color:var(--p-on-accent);
  font:700 12px/1.3 var(--p-font);letter-spacing:.06em;text-transform:uppercase;
  text-decoration:none;border:1px solid var(--p-accent);transition:.15s;cursor:pointer}
.pd-cta:hover{filter:brightness(1.08)}
.pd-cta.ghost{background:transparent;color:var(--p-ink);border-color:var(--p-line)}
.pd-cta.ghost:hover{border-color:var(--p-ink);filter:none}

/* ---------- spec table ---------------------------------------------------- */
.pd-spec{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0;
  margin:0;border-top:1px solid var(--p-line)}
.pd-spec>div{display:grid;grid-template-columns:minmax(96px,.62fr) minmax(0,1fr);gap:12px;
  padding:11px 0;border-bottom:1px solid var(--p-line)}
.pd-spec>div:nth-child(odd){padding-right:20px}
.pd-spec dt{margin:0;font:600 10px/1.45 var(--p-mono);letter-spacing:.1em;
  text-transform:uppercase;color:var(--p-dim)}
.pd-spec dd{margin:0;font:500 13.5px/1.45 var(--p-font);color:var(--p-ink);word-break:break-word}

/* ---------- body ---------------------------------------------------------- */
.pd-body{display:grid;grid-template-columns:minmax(0,1.62fr) minmax(0,.78fr);
  gap:52px;align-items:start;padding:8px 0 54px;border-top:1px solid var(--p-line);
  padding-top:44px}
.pd-main p{margin:0 0 18px;font-size:15px;line-height:1.78;color:var(--p-dim)}
.pd-main h2{margin:34px 0 14px;font-family:var(--p-display);font-size:19px;line-height:1.3;
  letter-spacing:-.01em;color:var(--p-ink)}
.pd-main p:first-child{font-size:15.5px;color:var(--p-ink)}

.pd-apps{margin:0;padding:0;list-style:none;display:grid;gap:9px}
.pd-apps li{position:relative;padding:0 0 0 22px;font-size:14px;line-height:1.6;color:var(--p-dim)}
.pd-apps li::before{content:"";position:absolute;left:2px;top:.62em;width:7px;height:7px;
  border-radius:50%;background:var(--p-accent)}

.pd-faq{margin:0;border-top:1px solid var(--p-line)}
.pd-faq details{border-bottom:1px solid var(--p-line)}
.pd-faq summary{padding:14px 30px 14px 0;position:relative;cursor:pointer;
  font:600 14px/1.5 var(--p-font);color:var(--p-ink);list-style:none}
.pd-faq summary::-webkit-details-marker{display:none}
.pd-faq summary::after{content:"+";position:absolute;right:4px;top:12px;
  font:400 17px/1 var(--p-mono);color:var(--p-accent)}
.pd-faq details[open] summary::after{content:"−"}
.pd-faq p{margin:0 0 16px;padding-right:30px;font-size:14px;line-height:1.7;color:var(--p-dim)}

/* ---------- side box ------------------------------------------------------ */
.pd-side{position:sticky;top:92px}
.pd-box{border:1px solid var(--p-line);border-radius:var(--p-r);padding:22px;
  background:var(--p-surface)}
.pd-box h3{margin:0 0 10px;font:600 10.5px/1.3 var(--p-mono);letter-spacing:.14em;
  text-transform:uppercase;color:var(--p-dim)}
.pd-box p{margin:0 0 18px;font-size:13.5px;line-height:1.65;color:var(--p-dim)}
.pd-box .pd-cta{width:100%}
.pd-facts{list-style:none;margin:18px 0 0;padding:18px 0 0;border-top:1px solid var(--p-line);
  display:grid;gap:12px}
.pd-facts li{display:flex;flex-direction:column;gap:2px}
.pd-facts b{font:700 15px/1.2 var(--p-font);color:var(--p-ink)}
.pd-facts span{font:500 11px/1.4 var(--p-mono);letter-spacing:.04em;color:var(--p-dim)}

/* ---------- related strip ------------------------------------------------- */
.pd-rel{padding:44px 0 60px;border-top:1px solid var(--p-line)}
.pd-rel-head{display:flex;align-items:baseline;justify-content:space-between;gap:16px;
  margin-bottom:22px}
.pd-rel-head h2{margin:0;font-family:var(--p-display);font-size:20px;letter-spacing:-.01em;
  color:var(--p-ink)}
.pd-rel-all{font:600 10.5px/1.3 var(--p-mono);letter-spacing:.1em;text-transform:uppercase;
  color:var(--p-accent);text-decoration:none;white-space:nowrap}
.pd-rel-all:hover{text-decoration:underline}

/* ---------- card grid ----------------------------------------------------- */
/* minmax(0,1fr) not 1fr: a bare 1fr is minmax(auto,1fr), whose lower bound is the content's
   min-content width, so one long spec value stops the column from shrinking and the grid
   overflows the viewport instead of wrapping. */
.pd-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:18px}
.pd-card{display:flex;flex-direction:column;border:1px solid var(--p-line);
  border-radius:var(--p-r);background:var(--p-surface);overflow:hidden;transition:.18s}
.pd-card:hover{border-color:var(--p-accent);transform:translateY(-2px)}
.pd-card-visual{display:block;padding:14px;aspect-ratio:1/1;background:var(--p-soft);
  display:flex;align-items:center;justify-content:center;border-bottom:1px solid var(--p-line)}
.pd-card-visual picture{display:contents}
.pd-card-visual img{max-width:100%;max-height:100%;width:auto;height:auto;object-fit:contain}
.pd-card-body{display:flex;flex-direction:column;gap:7px;padding:14px 15px 15px;flex:1}
.pd-card-code{margin:0;font:600 9.5px/1.3 var(--p-mono);letter-spacing:.12em;
  text-transform:uppercase;color:var(--p-dim)}
.pd-card-name{margin:0;font-size:14.5px;line-height:1.35;font-weight:700;letter-spacing:-.01em}
.pd-card-name a{color:var(--p-ink);text-decoration:none}
.pd-card-name a:hover{color:var(--p-accent)}
.pd-card-specs{margin:3px 0 0;display:grid;gap:5px}
.pd-card-specs>div{display:flex;justify-content:space-between;gap:10px;font-size:11.5px;
  line-height:1.4;border-top:1px dashed var(--p-line);padding-top:5px}
.pd-card-specs dt{margin:0;color:var(--p-dim);font-family:var(--p-mono);font-size:9.5px;
  letter-spacing:.06em;text-transform:uppercase;padding-top:1px}
.pd-card-specs dd{margin:0;color:var(--p-ink);font-weight:600;text-align:right;word-break:break-word}
.pd-card-foot{display:flex;align-items:center;justify-content:space-between;gap:10px;
  margin-top:auto;padding-top:12px}
.pd-moq{font:600 10px/1.3 var(--p-mono);letter-spacing:.08em;text-transform:uppercase;
  color:var(--p-dim)}
.pd-add{padding:9px 12px;border-radius:calc(var(--p-r) * .8);border:1px solid var(--p-accent);
  background:transparent;color:var(--p-accent);cursor:pointer;
  font:700 10px/1.2 var(--p-font);letter-spacing:.08em;text-transform:uppercase;transition:.15s}
.pd-add:hover{background:var(--p-accent);color:var(--p-on-accent)}

.pd-badge{display:inline-block;font:600 9px/1.3 var(--p-mono);letter-spacing:.1em;
  text-transform:uppercase;padding:3px 7px;border-radius:3px;
  background:var(--p-accent);color:var(--p-on-accent)}
.pd-badge.best{background:transparent;color:var(--p-accent);border:1px solid var(--p-accent)}

/* ---------- group / catalogue heads --------------------------------------- */
.pd-ghead{padding:6px 0 30px}
.pd-ghead h1{margin:0 0 14px;font-family:var(--p-display);font-size:clamp(24px,3.2vw,36px);
  line-height:1.12;letter-spacing:-.025em;font-weight:700;color:var(--p-ink)}
.pd-lead{margin:0 0 14px;font-size:15px;line-height:1.7;color:var(--p-dim);max-width:72ch}
.pd-meta{margin:0;font:500 10.5px/1.5 var(--p-mono);letter-spacing:.06em;
  text-transform:uppercase;color:var(--p-dim)}
.pd-block{padding:34px 0}
.pd-block-head{display:flex;align-items:baseline;justify-content:space-between;gap:16px;
  margin-bottom:18px;padding-bottom:12px;border-bottom:1px solid var(--p-line)}
.pd-block-head h2{margin:0;font-family:var(--p-display);font-size:19px;letter-spacing:-.01em;
  color:var(--p-ink)}
.pd-notes{padding:34px 0 54px;border-top:1px solid var(--p-line);margin-top:34px}
.pd-notes h2{margin:0 0 12px;font-family:var(--p-display);font-size:18px;color:var(--p-ink)}
.pd-notes p{margin:0 0 12px;font-size:14px;line-height:1.7;color:var(--p-dim);max-width:78ch}
.pd-more{font:500 11px/1.6 var(--p-mono);letter-spacing:.04em;text-transform:uppercase}
.pd-more a{color:var(--p-accent);text-decoration:none}
.pd-more a:hover{text-decoration:underline}

/* ---------- responsive ---------------------------------------------------- */
@media (max-width:1080px){
  .pd-grid{grid-template-columns:repeat(3,minmax(0,1fr))}
  .pd-body{grid-template-columns:minmax(0,1fr);gap:34px}
  .pd-side{position:static}
}
@media (max-width:820px){
  .pd-hero{grid-template-columns:minmax(0,1fr);gap:28px}
  .pd-media{aspect-ratio:4/5;max-width:420px;margin:0 auto;width:100%}
  .pd-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .pd-spec{grid-template-columns:minmax(0,1fr)}
  .pd-spec>div:nth-child(odd){padding-right:0}
}
@media (max-width:560px){
  .pd-wrap{padding:0 16px}
  /* 手机上省掉面包屑的中层：留着就要多占一行，正是当初 CLS 抖动的来源 */
  .pd-crumb .crumb-mid{display:none}
  .pd-crumb{min-height:2.6em;align-items:center}
  .pd-media{aspect-ratio:1/1;padding:12px}
  .pd-actions{display:grid;grid-template-columns:1fr}
  .pd-actions .pd-cta{width:100%}
  .pd-card-specs>div{font-size:11px}
  .pd-rel-head{flex-direction:column;gap:8px}
}
