
:root{
  --primary:#1746A2;
  --primary-bright:#409EFF;
  --accent:#EA5B0B;
  --accent-soft:#FCEFE6;
  --blue-soft:#EBF3FF;
  --white:#FFFFFF;
  --bg:#F7F9FC;
  --surface:#FFFFFF;
  --surface-alt:#F5F7FA;
  --border:#E4E7ED;
  --border-light:#EBEEF5;
  --field-border:#C3CDDC;
  --ink:#303133;
  --ink-2:#606266;
  --ink-3:#909399;
  --ink-4:#C0C4CC;
  --radius:14px;
  --radius-sm:10px;
  --radius-lg:20px;
  
  --color-primary:#1746A2;
  --color-primary-bright:#409EFF;
  --color-text-2:#606266;
  --color-text-3:#909399;
  --color-border:#E4E7ED;
  --shadow:0 10px 40px rgba(23,70,162,.10);
  --shadow-sm:0 2px 12px rgba(23,70,162,.06);
  --font:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,'PingFang SC','Microsoft YaHei',sans-serif;
}
*{box-sizing:border-box;}
html{scroll-behavior:smooth;}
body{margin:0;background:var(--bg);color:var(--ink);font-family:var(--font);font-size:18px;line-height:1.8;-webkit-font-smoothing:antialiased;letter-spacing:.005em;}
img{max-width:100%;height:auto;display:block;}
a{color:var(--primary);text-decoration:none;transition:color .18s;}
a:hover{color:var(--primary-bright);}
h1,h2,h3,h4{line-height:1.18;letter-spacing:-.018em;font-weight:700;color:var(--ink);margin:0 0 .45em;}
h1{font-size:68px;font-weight:900;line-height:1.04;letter-spacing:-.02em;} h2{font-size:64px;font-weight:900;line-height:1.08;letter-spacing:-.02em;} h3{font-size:30px;font-weight:800;line-height:1.22;}
p{margin:0 0 1.1em;}
::selection{background:rgba(64,158,255,.18);}
.lead{font-size:21px;color:var(--ink-2);max-width:60ch;line-height:1.75;}
.lead-lg{font-size:21px;}
/* GEO TL;DR — self-contained answer for AI extraction. Keep markup identical
   everywhere (Tldr.astro) so every page renders the same citable block. */
.tldr{margin-top:18px;padding:16px 18px;background:var(--blue-soft);border-left:4px solid var(--primary);border-radius:0 12px 12px 0;font-size:15.5px;line-height:1.7;color:var(--ink);max-width:78ch;}
.tldr strong{color:var(--primary);}
/* On a dark hero the light block read as an opaque panel on the glass card, and
   .hero strong{color:#fff !important} made the "In short:" label white-on-white.
   Fixed by re-styling for dark contexts — but NOT with a white tint: these hero
   backgrounds are photos that contain very light regions (measured: hero-oem.jpg
   left area RGB 180,184,198; hero-eco.jpg mid 210,224,236), and the ::after
   overlays fall to .10 alpha on the right. A white-tinted panel therefore made
   the backdrop LIGHTER while the text stayed light, measuring 3.6-4.4:1 —
   below WCAG AA. A dark tint keeps a guaranteed floor: rgba(8,20,36,.45) over the
   worst measured composite gives 8.33:1. Do not swap this back to white. */
.hero .tldr,
.hero-card .tldr{
  margin:18px 0 24px;
  background:rgba(8,20,36,.45);
  border-left:4px solid var(--accent);
  border-radius:0 12px 12px 0;
  color:#e9f1fb;
  -webkit-backdrop-filter:blur(10px);
  backdrop-filter:blur(10px);
}
.hero .tldr strong,
.hero-card .tldr strong{color:#fff;}
/* Visible freshness stamp — pairs with the WebPage dateModified in the JSON-LD.
   Kept low-contrast and small: it is a trust signal, not a design element. */
.last-updated{margin:36px auto 0;padding-top:16px;border-top:1px solid var(--border-light);font-size:13.5px;color:var(--ink-3);display:flex;align-items:center;gap:7px;flex-wrap:wrap;}
.last-updated time{font-weight:600;color:var(--ink-2);}

/* HERO — full-image background + floating white card */
.hero{position:relative;min-height:52vh;display:flex;align-items:center;justify-content:center;padding:64px 20px;overflow:hidden;color:#fff;background:#17253d;}
.hero::before{content:"";position:absolute;inset:0;z-index:0;background:url(/images/hero-factory.webp) center/cover no-repeat;}
.hero::after{content:"";position:absolute;inset:0;z-index:1;background:linear-gradient(90deg,rgba(8,20,36,.85) 0%,rgba(8,20,36,.52) 52%,rgba(8,20,36,.22) 100%);}
/* .hero-home background (2026-09-24): the JPEG was the homepage LCP element and it was
   only discovered after style.css had been parsed (Lighthouse mobile: 2.4 s of the
   LCP came from "resource load delay"). Converted to WebP with the same 1920 px
   source — 63.8 KB -> 39.1 KB — and preloaded from <head> (see Layout.astro), so the
   fetch starts with the document instead of after the stylesheet. WebP-only matches
   the convention already used by .hero::before (hero-factory.webp). */
.hero-home::before{content:"";position:absolute;inset:0;z-index:0;background:url(/images/hero-main-clean.webp) center/cover no-repeat;}
.hero-oem::after{content:"";position:absolute;inset:0;z-index:1;background:linear-gradient(90deg,rgba(8,20,36,.78) 0%,rgba(8,20,36,.42) 55%,rgba(8,20,36,.10) 100%);}
.hero-home{min-height:76vh;padding:44px 20px;}
.hero-content{position:relative;z-index:2;width:100%;max-width:1180px;margin:0 auto;padding:0 24px;display:flex;align-items:center;justify-content:center;}
.hero .container{position:relative;z-index:3;text-align:left;max-width:1180px;}
.hero .container .eyebrow{justify-content:flex-start;text-align:left;margin-left:0;}
.hero h1{max-width:22ch;font-size:clamp(36px,4.3vw,56px);margin-bottom:16px;}
.hero .lead{color:#e2ecf7;font-size:20px;max-width:54ch;line-height:1.6;}
.hero-card{background:rgba(23,70,162,.16);-webkit-backdrop-filter:blur(32px);backdrop-filter:blur(32px);border:none;border-radius:48px;padding:48px 52px;box-shadow:0 44px 120px rgba(10,24,43,.16);max-width:560px;margin:0 auto;color:#fff;}
.hero-card .eyebrow{color:#a6c9ec;border:none;text-align:left;justify-content:flex-start;}
.hero-card .eyebrow::before{background:var(--accent);}
.hero-card h1{color:#fff;font-size:clamp(40px,4.4vw,56px);line-height:1.08;max-width:22ch;font-weight:900;letter-spacing:-.02em;}
.hero-card .lead{color:#dde9f6;font-size:18px;max-width:46ch;line-height:1.6;}
.hero-card .btn-primary{background:linear-gradient(135deg,#fb923c,#ea5b0b);color:#fff;border-color:#f97316;box-shadow:0 0 0 2px rgba(255,255,255,.22),0 12px 30px rgba(0,0,0,.34);font-weight:800;font-size:17px;padding:16px 34px;}
.hero-card .btn-primary:hover{background:linear-gradient(180deg,#6CB8FF,#409EFF);transform:translateY(-2px);box-shadow:0 0 0 2px #fff,0 16px 36px rgba(64,158,255,.42);}
.hero .btn-outline{background:rgba(255,255,255,.10);color:#fff;border:2px solid rgba(255,255,255,.72);font-weight:700;}
.hero .btn-outline:hover{border-color:#fff;background:rgba(255,255,255,.14);}
.hero-card .trustbar{border-top:1px solid rgba(255,255,255,.2);padding-top:20px;margin-top:8px;display:grid;grid-template-columns:repeat(2,1fr);gap:18px 16px;}
.hero-card .trustbar .t{border-left:3px solid #6ba3d6;padding-left:12px;}
.hero-card .trustbar .t b{color:#fff;font-size:24px;display:block;}
.hero-card .trustbar .t span{color:#bcd6ee;font-size:12.5px;}
@media(max-width:900px){.hero{min-height:auto;padding:64px 16px;}.hero-card{padding:30px 26px;}.hero-card .trustbar{grid-template-columns:1fr 1fr;}}
/* Long unbreakable words also blow out the hero: a flex item cannot shrink below
   its min-content width, so a single compound word sets the card's floor.
   Measured 2026-09-24 on the German tree at 320px: "Batteriehersteller" at the
   clamped 40px H1 size is ~330px wide, which pushed .hero-card to 331px with
   left:-5 — wider than the viewport, and .hero{overflow:hidden} silently clipped
   it. hyphens:auto uses the <html lang> dictionary (Layout.astro sets it), so
   German compounds break on their real syllable boundaries; overflow-wrap is the
   fallback where Chrome has no dictionary. Both are no-ops when words fit. */
.hero h1,.hero-card h1{hyphens:auto;overflow-wrap:break-word;}

/* container */
.container{width:100%;max-width:1180px;margin:0 auto;padding:0 32px;}
.container-narrow{max-width:860px;}
.container-wide{max-width:1320px;}

/* button — refined */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:9px;font-size:16px;font-weight:600;padding:14px 30px;border-radius:10px;border:1px solid transparent;cursor:pointer;transition:all .2s ease;line-height:1;}
.btn-primary{background:var(--primary);color:#fff;border-color:var(--primary);box-shadow:0 6px 18px rgba(23,70,162,.22);}
.btn-primary:hover{background:var(--primary-bright);border-color:var(--primary-bright);transform:translateY(-2px);box-shadow:0 10px 26px rgba(64,158,255,.3);}
.btn-outline{background:#fff;color:var(--primary);border-color:#cdddf5;}
.btn-outline:hover{border-color:var(--primary);background:var(--blue-soft);transform:translateY(-2px);}
.btn-light{background:var(--blue-soft);color:var(--primary);border-color:var(--blue-soft);}
.btn-light:hover{background:#dcedff;}
.btn-accent{background:var(--accent);color:#fff;border-color:var(--accent);}
.btn-accent:hover{background:#d54f02;transform:translateY(-2px);}
.btn-sm{padding:10px 20px;font-size:14px;}
.btn-lg{padding:17px 40px;font-size:17px;}
.btn-block{width:100%;justify-content:center;}

/* eyebrow */
.eyebrow{text-transform:uppercase;letter-spacing:.14em;font-size:13px;font-weight:800;color:#ea5b0b;margin-bottom:14px;display:flex;align-items:center;gap:10px;justify-content:center;}
.eyebrow::before{content:"";width:24px;height:3px;border-radius:3px;background:var(--accent);}
.eyebrow.left{justify-content:flex-start;}
.eyebrow .dot{width:7px;height:7px;border-radius:50%;background:var(--accent);}

/* section */
section{padding:76px 0;}
.section-alt{background:var(--surface-alt);}
.section h2{margin-bottom:16px;color:#1c2b4a;}
.headline-group{max-width:780px;margin-bottom:36px;}
.hl-center{margin-left:auto;margin-right:auto;text-align:center;}
.hl-center .lead{margin-left:auto;margin-right:auto;}
@media(max-width:768px){.headline-group{margin-bottom:32px;}}

/* big number */
.stats-band{background:#fff;border-bottom:1px solid var(--border-light);}
.stats-band .inner{display:grid;grid-template-columns:repeat(4,1fr);}
.stats-band .item{padding:46px 24px;border-right:1px solid var(--border-light);}
.stats-band .item:last-child{border-right:none;}
.stats-band .num{font-size:48px;font-weight:700;letter-spacing:-.02em;color:var(--primary);line-height:1;}
.stats-band .lab{font-size:14px;color:var(--ink-3);margin-top:10px;text-transform:uppercase;letter-spacing:.07em;}

/* card — refined light grey */
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:22px;}
.card,.c{background:#fff;border-radius:var(--radius);padding:28px;border:1px solid var(--border-light);transition:all .26s ease;box-shadow:var(--shadow-sm);}
.card:hover,.c:hover{transform:translateY(-5px);box-shadow:var(--shadow);border-color:transparent;}
.card h3,.c h3{font-size:26px;}
.card p,.c p{color:var(--ink-2);font-size:15.5px;line-height:1.65;}
.card img{cursor:;}
.card img{width:100%;height:190px;object-fit:contain;border-radius:var(--radius-sm);background:var(--surface-alt);margin-bottom:16px;}
/* Guide thumbnails on /blog/. Needs (0,2,1) to beat the .card img rule above.
   cover, not contain: the source shots run from 0.31 to 3.12 in aspect, so a
   fixed 16/9 tile centre-cropped is what makes the grid even. */
.card img.card-thumb{height:auto;aspect-ratio:16/9;object-fit:cover;object-position:center;display:block;transition:transform .4s ease;}
.card a:has(> .card-thumb){display:block;overflow:hidden;border-radius:var(--radius-sm);margin-bottom:16px;}
.card a:has(> .card-thumb) img{margin-bottom:0;}
.card:hover img.card-thumb{transform:scale(1.04);}
.card .more,.c .more{color:var(--primary);font-weight:600;font-size:15px;}
.prod-card{background:#fff;border-radius:var(--radius);padding:22px;border:1px solid var(--border-light);transition:all .26s ease;box-shadow:var(--shadow-sm);}
.prod-card:hover{transform:translateY(-5px);box-shadow:var(--shadow);border-color:transparent;}
.prod-card img{width:100%;height:180px;object-fit:contain;border-radius:var(--radius-sm);background:var(--surface-alt);margin-bottom:14px;}
.prod-card h3{font-size:24px;}
.prod-card .sub{font-size:12.5px;color:var(--ink-3);margin-bottom:6px;text-transform:uppercase;letter-spacing:.05em;}
.prod-card p{color:var(--ink-2);font-size:15px;}
.prod-card .more{color:var(--primary);font-weight:600;font-size:14px;}

/* step flow (premium step cards) */
.steps-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:18px;}
.step{background:#fff;border-radius:var(--radius);padding:30px;border:1px solid var(--border-light);box-shadow:var(--shadow-sm);position:relative;transition:all .26s;}
.step:hover{box-shadow:var(--shadow);transform:translateY(-4px);}
.step .sn{font-size:44px;font-weight:800;color:var(--blue-soft);line-height:1;margin-bottom:14px;letter-spacing:-.03em;}
.step h4{font-size:19px;color:var(--ink);margin:0 0 6px;}
.step p{font-size:16px;color:var(--ink-2);}

/* icon feature */
.feat-icon{width:52px;height:52px;border-radius:14px;background:var(--blue-soft);color:var(--primary);display:flex;align-items:center;justify-content:center;font-size:22px;margin-bottom:16px;}
.feature{background:#fff;border-radius:var(--radius);padding:32px;border:1px solid var(--border-light);box-shadow:var(--shadow-sm);transition:all .26s;}
.feature:hover{box-shadow:var(--shadow);transform:translateY(-4px);border-color:transparent;}
.feature h3{font-size:26px;}
.feature p{color:var(--ink-2);font-size:15.5px;}

/* table */
table{width:100%;border-collapse:collapse;margin:0;font-size:15px;}
th,td{padding:16px 18px;text-align:left;border-bottom:1px solid var(--border-light);font-size:16px;}
th{font-weight:600;color:var(--ink);background:var(--surface-alt);}
td{color:var(--ink-2);}
tbody tr:hover{background:var(--surface-alt);}

/* FAQ */
details{border:1px solid var(--border-light);border-radius:var(--radius-sm);margin-bottom:12px;background:#fff;overflow:hidden;box-shadow:var(--shadow-sm);}
details summary{cursor:pointer;padding:20px 24px;font-weight:600;font-size:16.5px;list-style:none;display:flex;justify-content:space-between;align-items:center;gap:16px;color:var(--ink);}
details summary::-webkit-details-marker{display:none;}
details summary::after{content:"+";font-size:24px;color:var(--primary-bright);font-weight:400;}
details[open] summary::after{content:"−";}
details .a{padding:0 24px 22px;color:var(--ink-2);font-size:15px;}

/* nav — premium */
.nav{position:sticky;top:0;z-index:100;background:rgba(255,255,255,.82);backdrop-filter:saturate(180%) blur(18px);border-bottom:1px solid var(--border-light);}
.nav-inner{max-width:1180px;margin:0 auto;padding:0 32px;height:72px;display:flex;align-items:center;gap:30px;}
/* flex:0 0 auto + nowrap: the brand must never be squeezed. It used to shrink
   (flex-shrink:1) because the desktop nav needs ~1147px inside a 1116px content
   box, and the <b> text then overflowed its own box by up to 36px and landed on
   top of the first nav item — visibly clipping the "U" of TIANQIU. The nav is
   now tightened (see .nav-links a) and collapses at 1200px (see the media query
   further down) so this never has to give. */
.nav-logo{font-size:20px;font-weight:800;color:#1c2b4a;letter-spacing:-.02em;display:flex;align-items:center;gap:9px;flex:0 0 auto;white-space:nowrap;}
/* 站点 logo（/logo-tianqiu.png，192x162 透明底）。
   高度写死、宽度 auto —— 保持原始宽高比，绝不让外框被压扁；
   flex:0 0 auto 防止在窄屏被 flex 压缩变形。 */
.logo-img{height:28px;width:auto;display:block;flex:0 0 auto;}
.nav-logo .bmark{width:30px;height:30px;border-radius:9px;background:linear-gradient(135deg,var(--primary),var(--primary-bright));display:flex;align-items:center;justify-content:center;color:#fff;font-size:15px;}
.nav-labels,.nav-links{margin-left:auto;display:flex;gap:0;}
.nav-labels a,.nav-links a{padding:9px 12px;border-radius:10px;color:var(--ink);font-size:16px;font-weight:600;letter-spacing:-.005em;transition:color .2s,background .2s;}
.nav-labels a:hover,.nav-links a:hover{color:var(--primary);background:var(--blue-soft);text-decoration:none;}
.nav-labels a.active,.nav-links a.active{color:var(--primary);font-weight:700;background:var(--blue-soft);}
.nav-cta{margin-left:10px;}
.nav-burger{display:none;margin-left:10px;background:none;border:1px solid var(--border);border-radius:9px;padding:8px 12px;font-size:22px;cursor:pointer;color:var(--ink);}
/* search: icon-only button, same hover treatment as the nav links */
.nav-search{margin-left:8px;display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:10px;color:var(--ink);font-size:16px;flex:0 0 auto;transition:color .2s,background .2s;}
.nav-search:hover{color:var(--primary);background:var(--blue-soft);text-decoration:none;}
.nav-search:focus-visible{outline:2px solid var(--primary-bright);outline-offset:2px;}
@media(max-width:600px){.nav-search{width:36px;height:36px;margin-left:0;}}
/* Language switcher. ⚠️ The premise of the old comment here ("it is the only way
   to reach the other language tree, so it has to survive next to the burger at
   360px") went stale when the mobile menu gained its own full-label switcher
   (.lang-strip-mobile, see Layout.astro) — there are now two switchers, and the
   one in the bar is the redundant one.
   Why it had to go: the bar row is a nowrap flex of non-shrinking items, so
   every pixel the switcher takes comes out of the burger's room. The strip
   renders at 137px (four short labels), which pinned .nav-burger to a fixed
   left:396/right:442 at EVERY phone width — past the right edge below 442px, so
   the menu button was unreachable on 360–430px phones (measured 2026-09-24;
   360px overflowed by 82px). It is hidden at ≤600px next to .lang-strip below;
   the menu's own switcher keeps every language reachable. */
/* .nav-lang lived here: a compact language button that never got markup (the
   switcher shipped as the four-chip .lang-strip instead, and has been the
   .lang-switch dropdown since 2026-09-28). Removed rather than kept as dead
   CSS — but the two lessons stay: (1) the bar row is a nowrap flex of
   non-shrinking items, so every pixel the language slot takes comes out of the
   burger's room — the chips pinned .nav-burger at left:396/right:442 at every
   phone width and made the menu button unreachable below 442px (measured
   2026-09-24, 360px overflowed by 82px); (2) see the `.nav-inner >` note at the
   ≤600px rule below before writing any .lang-* rule scoped by media query. */
/* Chinese typography: Inter has no CJK glyphs, so the stack falls through to the
   system Chinese face. Line-height is nudged up — CJK needs more leading than
   Latin at the same size. */
:lang(zh) body{font-family:Inter,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","Source Han Sans SC","Noto Sans CJK SC",system-ui,sans-serif;}
:lang(zh) h1,:lang(zh) h2,:lang(zh) h3,:lang(zh) h4{letter-spacing:0;line-height:1.35;}
:lang(zh) .prose p,:lang(zh) .prose li{line-height:1.9;}
/* Mobile header. The desktop nav needs ~1000px to fit (links alone are 596px,
   plus logo, search and the CTA), so it must collapse before the desktop nav runs
   out of room. Measured 2026-09-18: the nav needs ~1093px and .nav-inner caps its
   content box at 1116px (max-width 1180 minus 2x32 padding), so the desktop layout
   only genuinely fits from ~1180px up. The old 1024px breakpoint let it render for
   another ~150px of viewport where it did not fit, and flex resolved that by
   shrinking .nav-logo until the "TIANQIU" text overlapped the "Home" item.
   1200px leaves margin on both sides of the measured threshold. (.mobile-bottom-nav
   is referenced in the line above but no rule ever displays it — it is dead CSS.)
   This block has to stay AFTER the desktop nav rules above: an identical rule
   near the top of the file was dead, because `.nav-labels,.nav-links` sets
   display:flex further down at equal specificity, so the later declaration won.
   The result was a burger that never appeared and every page scrolling
   sideways on a phone. Do not move this back up the file. */
@media(max-width:1200px){
  .nav-labels,.nav-cta,.nav-links{display:none;}
  .nav-burger{display:block;}
  .nav-inner{gap:16px;}
}
.mobile-menu{display:none;position:fixed;top:68px;left:0;right:0;z-index:99;background:#fff;border-bottom:1px solid var(--border-light);overflow-y:auto;max-height:calc(100vh - 68px);padding:10px 20px 30px;}
.mobile-menu.open{display:block;}
.mobile-menu a{display:block;padding:15px 4px;border-bottom:1px solid var(--border-light);color:var(--ink);font-size:17px;}
.mobile-menu a:last-child{border-bottom:none;}


.footer{background:#17253d;color:#b9c8dc;padding:80px 0 38px;}
.footer-grid{display:grid;grid-template-columns:1.6fr 1fr 1fr 1.2fr;gap:36px;margin-bottom:46px;}
.footer h4{font-size:13px;color:#7f92ab;text-transform:uppercase;letter-spacing:.1em;margin-bottom:18px;font-weight:700;}
.footer a{color:#b9c8dc;font-size:15px;display:block;margin-bottom:11px;}
.footer a:hover{color:#fff;}
.footer-bottom{border-top:1px solid rgba(255,255,255,.12);padding-top:24px;font-size:13px;color:#7f92ab;display:flex;justify-content:space-between;gap:12px;flex-wrap:wrap;}
/* Footer copy carries the longest words on the site (German compounds, legal page
   names). Measured 2026-09-24 at 320px: "Verkaufsbedingungen" is ~145px at the
   15px link size inside a 122px column, so the word spilled to 337px — 17px of
   page overflow on the German tree (en/es/zh stayed at 0; their longest links are
   short enough). hyphens:auto breaks German at real syllable boundaries using the
   <html lang> dictionary, overflow-wrap is the fallback for languages Chrome has
   no dictionary for or for URLs; both are no-ops when the word already fits. */
.footer a,.footer p,.footer-bottom{hyphens:auto;overflow-wrap:break-word;}
.footer strong{color:#fff;}

/* breadcrumb */
.breadcrumb{font-size:14px;color:var(--ink-3);padding:18px 0;}
.breadcrumb a{color:var(--ink-3);}
.breadcrumb a:hover{color:var(--primary);}


.panel,.cta-panel{background:#fff;border:1px solid var(--border-light);border-radius:var(--radius-lg);padding:36px;box-shadow:var(--shadow-sm);}
.panel-note{background:var(--blue-soft);border-left:4px solid var(--primary-bright);border-radius:0 var(--radius-sm) var(--radius-sm) 0;padding:18px 22px;font-size:15px;color:var(--ink-2);}
.badge{display:inline-flex;align-items:center;gap:6px;padding:8px 16px;background:var(--blue-soft);border:1px solid transparent;border-radius:999px;font-size:14px;font-weight:500;color:var(--primary);}
.badge i{color:var(--primary-bright);}
.badge:hover{background:#dcedff;color:var(--primary);}
ul.clean{list-style:none;padding:0;}
ul.clean li{padding-left:28px;position:relative;margin-bottom:10px;}
ul.clean li::before{content:"✓";position:absolute;left:0;color:var(--primary-bright);font-weight:700;}

/* layout */
.cols2{display:grid;grid-template-columns:1fr 1fr;gap:36px;}
.cols3{display:grid;grid-template-columns:repeat(3,1fr);gap:22px;}
.cols4{display:grid;grid-template-columns:repeat(4,1fr);gap:22px;}
.product-layout{display:grid;grid-template-columns:1.08fr 1fr;gap:46px;align-items:center;}
.product-layout .img-wrap{background:var(--surface-alt);border:1px solid var(--border-light);border-radius:var(--radius-lg);padding:18px;box-shadow:var(--shadow-sm);}
.product-layout img{width:100%;object-fit:contain;max-height:400px;}

/* form — fields must read clearly as fields: the quote / inquiry forms sit
   directly on --bg with white inputs, so a 1px #E4E7ED border was nearly
   invisible. Stronger border + faint inset shadow + a real focus ring. */
.form-row{margin-bottom:20px;}
label{display:block;font-weight:600;font-size:14px;margin-bottom:7px;color:var(--ink);}
input,select,textarea{width:100%;padding:13px 16px;border:1px solid var(--field-border);border-radius:var(--radius-sm);font-size:16px;font-family:var(--font);color:var(--ink);background:#fff;box-shadow:inset 0 1px 2px rgba(16,32,64,.05);transition:border-color .15s, box-shadow .15s;}
input::placeholder,textarea::placeholder{color:#9AA6B6;opacity:1;}
input:hover,select:hover,textarea:hover{border-color:#9FB0C8;}
input:focus,select:focus,textarea:focus{outline:none;border-color:var(--primary-bright);box-shadow:0 0 0 3px rgba(64,158,255,.20), inset 0 1px 2px rgba(16,32,64,.04);}
input:user-invalid,select:user-invalid,textarea:user-invalid{border-color:#E5484D;box-shadow:0 0 0 3px rgba(229,72,77,.13);}
/* checkboxes / radios must not inherit the width:100% field rule */
input[type=checkbox],input[type=radio]{width:18px;height:18px;flex:0 0 auto;margin:0;padding:0;box-shadow:none;accent-color:var(--primary);cursor:pointer;}
input[type=checkbox]:focus-visible,input[type=radio]:focus-visible{outline:2px solid var(--primary-bright);outline-offset:2px;}
textarea{min-height:104px;line-height:1.6;resize:vertical;}
/* caret so a select reads as a dropdown in every browser */
select{appearance:none;-webkit-appearance:none;-moz-appearance:none;padding-right:44px;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='13' height='9' viewBox='0 0 13 9'%3E%3Cpath d='M1 1l5.5 5.5L12 1' fill='none' stroke='%231746A2' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 15px center;background-size:13px 9px;}
input[type=file]{padding:11px 14px;cursor:pointer;}
input[type=file]::file-selector-button{margin-right:12px;padding:8px 14px;border:1px solid var(--primary);border-radius:8px;background:var(--blue-soft);color:var(--primary);font:inherit;font-size:14px;font-weight:600;cursor:pointer;}
input[type=file]::file-selector-button:hover{background:#dcedff;}
label .req{color:#E5484D;font-weight:800;margin-left:2px;}
/* keep the inquiry forms short: required fields first, everything else folded
   behind a disclosure so an 11-field form reads as a 3-field one. Controls
   inside a closed <details> are still submitted (only disabled controls are
   excluded), so no detail is lost when it stays shut. */
.form-req-note{font-size:13.5px;line-height:1.6;color:var(--ink-3);margin:0 0 18px;}
.form-req-note strong{color:var(--ink);}
.form-more{margin:2px 0 20px;border:1px solid var(--border-light);border-radius:var(--radius-sm);background:var(--surface-alt);}
.form-more>summary{cursor:pointer;padding:13px 16px;font-size:14.5px;font-weight:700;color:var(--primary);list-style:none;display:flex;align-items:center;gap:8px;}
.form-more>summary::-webkit-details-marker{display:none;}
.form-more>summary::after{content:"\25BE";margin-left:auto;font-size:13px;line-height:1;color:var(--ink-3);}
.form-more[open]>summary::after{content:"\25B4";}
.form-more>summary:hover{color:var(--primary-bright);}
.form-more>summary .opt{font-weight:600;color:var(--ink-3);font-size:13px;}
.form-more .form-more-body{padding:16px 16px 2px;border-top:1px solid var(--border-light);background:#fff;border-radius:0 0 8px 8px;}
.form-more .form-more-body>:last-child{margin-bottom:16px;}
/* standalone quote / inquiry forms become a real form panel */
#quoteForm,#packForm,#contactForm{background:#fff;border:1px solid var(--border);border-radius:var(--radius-lg);padding:32px;box-shadow:var(--shadow-sm);}
@media(max-width:640px){#quoteForm,#packForm,#contactForm{padding:22px 18px;}}
/* site search field carries inline styles, so it needs !important */
#q{border-color:var(--field-border)!important;box-shadow:inset 0 1px 2px rgba(16,32,64,.05),var(--shadow-sm)!important;}
#q:focus{border-color:var(--primary-bright)!important;box-shadow:0 0 0 3px rgba(64,158,255,.20)!important;}
/* arriving from a product page: /contact-us/#product-photo-cr2032 etc. No
   element carried those ids, so nothing scrolled or highlighted the form and the
   visitor had no sign of which model they had asked about. */
.form-context{display:flex;gap:10px;align-items:flex-start;margin-bottom:20px;padding:14px 16px;border:1px solid #bfe0cd;background:#eefaf2;border-radius:12px;font-size:14.5px;line-height:1.55;color:var(--ink);}
.form-context[hidden]{display:none;}
.form-context i{color:#1e9e57;margin-top:3px;flex:0 0 auto;}
.form-context strong{color:#157a42;}
.form-focus{animation:formFocus 2.4s ease-out 1;box-shadow:0 0 0 3px rgba(64,158,255,.35),var(--shadow-sm)!important;}
#contactForm{scroll-margin-top:96px;}
@keyframes formFocus{0%{box-shadow:0 0 0 6px rgba(64,158,255,.45),var(--shadow-sm);}100%{box-shadow:0 0 0 3px rgba(64,158,255,.35),var(--shadow-sm);}}
@media(prefers-reduced-motion:reduce){.form-focus{animation:none;}}

/* contact */
.contact-item{display:flex;gap:14px;align-items:flex-start;margin-bottom:18px;}
.contact-item .ci{width:46px;height:46px;border-radius:12px;background:var(--blue-soft);color:var(--primary);display:flex;align-items:center;justify-content:center;font-size:19px;flex-shrink:0;}
.contact-item .l{font-size:13px;color:var(--ink-3);}
.contact-item .v{font-size:16px;font-weight:600;color:var(--ink);}

/* floating */
.wa-fab{position:fixed;right:22px;bottom:22px;z-index:88;width:56px;height:56px;border-radius:50%;background:#25D366;display:flex;align-items:center;justify-content:center;box-shadow:0 10px 26px rgba(37,211,102,.35);clip-path:circle(50% at 50% 50%);transition:opacity .18s ease,transform .18s ease;}
.wa-fab svg{width:30px;height:30px;fill:#fff;}
.wa-fab:hover{transform:scale(1.08);}
/* While the visitor scrolls, the phone FAB must not sit on the content column.
   Measured on live pages at 390×844 it covered up to 2,496 px² of a product-card
   link (CR2032 / AG13 / LR1130 cards, R6P "View specs →", a video thumb), so a
   tap meant for the card opened WhatsApp instead. The shell adds .is-hidden
   while scrolling down and removes it once scrolling stops (or on scroll-up),
   so the CTA is still one tap away whenever the page is at rest. The clip-path
   on the base rule keeps the transparent corners of the square box out of
   hit-testing — without it those corners swallow taps too. */
.wa-fab.is-hidden{opacity:0;transform:translateY(14px) scale(.9);pointer-events:none;}
@media (prefers-reduced-motion:reduce){.wa-fab{transition:none;}}
.back-top{position:fixed;right:22px;bottom:92px;z-index:88;width:44px;height:44px;border-radius:50%;background:#fff;border:1px solid var(--border);color:var(--ink-2);display:none;align-items:center;justify-content:center;font-size:18px;cursor:pointer;box-shadow:var(--shadow-sm);}
.back-top:hover{color:var(--primary);}
/* Phones: stack the two floating buttons instead of overlapping them. The
   WhatsApp FAB sat at bottom:88 and back-to-top at 92 with near-identical right
   offsets, so back-to-top's box landed entirely inside the FAB's — one circle
   drawn on top of the other. The bottom nav occupies 0-64px, so the FAB sits
   just above it and back-to-top clears the FAB by 12px. Desktop is unaffected:
   there the FAB is at 22 and back-to-top at 92, already apart.
   This block MUST stay after the .back-top base rule above — same specificity,
   so an earlier block would be overridden by it (the exact bug that left the
   mobile nav uncollapsed further up this file).
   (.floating-quote has a colliding mobile position too but is dead CSS —
   nothing references it; don't reuse that position.) */
@media (max-width:1024px){
  .wa-fab{bottom:78px;right:16px;width:52px;height:52px;}
  .back-top{bottom:142px;right:20px;}
}

/* motion — scroll fade-in */
.reveal{opacity:0;transform:translateY(26px);transition:opacity .7s ease,transform .7s cubic-bezier(.2,.7,.3,1);}
.reveal.in{opacity:1;transform:none;}

/* mobile bottom nav */
.mobile-bottom-nav{display:none;position:fixed;left:0;right:0;bottom:0;z-index:95;background:rgba(255,255,255,.96);backdrop-filter:blur(12px);border-top:1px solid var(--border-light);padding:6px 4px calc(6px + env(safe-area-inset-bottom));}
.mobile-bottom-nav a{flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;padding:6px 0;font-size:11px;color:var(--ink-3);}
.mobile-bottom-nav a i{font-size:18px;}
.mobile-bottom-nav a.active{color:var(--primary);font-weight:600;}

/* responsive */
@media(max-width:1024px){
  h1{font-size:40px;} h2{font-size:30px;}
  .product-layout{grid-template-columns:1fr;gap:30px;}
  .cols3,.cols4,.steps-grid{grid-template-columns:1fr 1fr;}
  .stats-band .inner{grid-template-columns:repeat(2,1fr);}
  .stats-band .item{border-bottom:1px solid var(--border-light);}
  .stats-band .item:nth-child(2n){border-right:none;}
  /* minmax(0,1fr), not bare 1fr: a bare fr is minmax(auto,1fr), whose auto
     minimum is min-content — so one long unbreakable word inflates the whole
     track past the container and the page scrolls sideways. Measured on the
     German tree at 320px: tracks resolved to 136px/159px inside a 280px box
     (331px of grid), 31px of page overflow, while en/es/zh were fine at 122px
     each. German compounds are the trigger; do not revert to 1fr. */
  .footer-grid{grid-template-columns:minmax(0,1fr) minmax(0,1fr);}
  .mobile-bottom-nav{display:flex;}
  body{padding-bottom:64px;}
}
@media(max-width:768px){
  body{font-size:16px;}
  h1{font-size:44px;font-weight:900;} h2{font-size:42px;font-weight:900;} .lead{font-size:20px;}
  .hero{padding:84px 0 64px;}
  .container{padding:0 20px;}
  .section{padding:64px 0;}
  .grid{grid-template-columns:1fr;}
  .cols2,.cols3,.cols4,.steps-grid{grid-template-columns:1fr;}
  .stats-band .inner{grid-template-columns:1fr;}
  .stats-band .item{border-right:none;border-bottom:1px solid var(--border-light);padding:28px 20px;}
  .card img,.prod-card img{height:180px;}
}








.section-deep{background:linear-gradient(135deg,#0c2f4d 0%,#1746a2 100%);color:#fff;padding:70px 0;position:relative;overflow:hidden;}
.section-deep::before{content:"";position:absolute;inset:0;background:radial-gradient(640px 340px at 82% 8%,rgba(64,158,255,.22),transparent 60%);}
.section-deep>*{position:relative;z-index:1;}
.section-deep h2,.section-deep h3{color:#fff;}
.section-deep .lead{color:#cfe0f5;}
.section-deep .eyebrow{color:#8fc0e8;}
.section-deep .eyebrow::before{background:#6fb0e0;}
.section-deep .headline-group h2::after{background:linear-gradient(90deg,#8fc0e8,#5f9df7);}
.section-deep .card,.section-deep .c{background:rgba(255,255,255,.07);border-color:rgba(255,255,255,.14);backdrop-filter:blur(8px);}
.section-deep .card:hover,.section-deep .c:hover{border-color:rgba(255,255,255,.28);}
.section-deep .card h3,.section-deep .c h3{color:#fff;}
.section-deep .card p,.section-deep .c p{color:#cfe0f5;}
.section-deep .card .feat-icon,.section-deep .c .feat-icon{background:rgba(255,255,255,.16);color:#fff;}
.section-deep .card::before,.section-deep .c::before{background:linear-gradient(90deg,#8fc0e8,#409eff);}

/* ===== content card area (avoid wall of text)===== */
.content-block{background:#fff;border:1px solid var(--border-light);border-radius:20px;padding:26px 28px;box-shadow:var(--shadow-sm);}
.content-block h2,.content-block h3{margin-top:0;}
.content-block .lead{margin-bottom:0;}
.section .container>.content-block{background:#fff;}
.section-alt .container>.content-block{background:#fff;}
/* section background layering */
.section-alt{background:#F2F5FA;}
.sec-title{display:flex;align-items:center;gap:12px;margin-bottom:16px;}
.sec-title .ic{width:46px;height:46px;flex-shrink:0;border-radius:13px;background:var(--blue-soft);color:var(--primary);display:flex;align-items:center;justify-content:center;font-size:20px;}
.sec-title h2{font-size:34px;margin:0;font-weight:900;min-width:0;overflow-wrap:break-word;}
/* 多语种长词保护：行内大号统计标签（font-size:32px + 800）在窄列里允许断行，
   否则 ru「Многоразово」/ fr「Réutiliser」这类长词会把页面撑出横向滚动条。 */
[style*="font-size:32px"][style*="font-weight:800"]{min-width:0;overflow-wrap:break-word;}

/* ===== safety notice box===== */
.safety-warn{background:#fff6f6;border:1px solid #f2c7c7;border-left:5px solid #d64545;border-radius:14px;padding:22px 24px;}
.safety-warn .sw-label{color:#c0392b;font-weight:800;font-size:18px;display:flex;align-items:center;gap:8px;}
.safety-warn ul{color:var(--ink-2);font-size:15px;line-height:1.9;padding-left:20px;margin:12px 0 0;}
.safety-warn summary,.safety-summary{color:#c0392b;font-weight:700;}

/* ===== site-wide subtle pattern decoration (less monotone)===== */
body{background-image:radial-gradient(rgba(23,70,162,.06) 1px,transparent 1px);background-size:26px 26px;}
.hero{position:relative;overflow:hidden;}
.hero::after{background:linear-gradient(90deg,rgba(8,20,36,.9) 0%,rgba(8,20,36,.64) 52%,rgba(8,20,36,.42) 100%);}
.section .headline-group::before{content:"";display:block;width:40px;height:4px;margin-bottom:18px;border-radius:4px;background:linear-gradient(90deg,var(--primary-bright),var(--accent));}
.content-block{position:relative;overflow:hidden;}
.content-block::before{content:"";position:absolute;top:-60px;right:-60px;width:200px;height:200px;border-radius:50%;
  background:radial-gradient(circle,rgba(64,158,255,.10),transparent 70%);}

/* symbols in text-dense areas */
.a li,.safety-warn li,.content-block li{list-style:none;position:relative;padding-left:26px;margin-bottom:8px;}
.a li::before,.safety-warn li::before,.content-block li::before{content:"✔";position:absolute;left:0;top:0;color:var(--primary);font-weight:800;}
.feat-icon{background:var(--blue-soft);}

/* ===== hero background variants (different image per page)===== */
.hero-ind::before{content:"";position:absolute;inset:0;z-index:0;background:url(/images/hero-industrial.webp) center/cover no-repeat;}
.hero-oem::before{content:"";position:absolute;inset:0;z-index:0;background:url(/images/hero-oem.webp) center/cover no-repeat;}
.hero-lithium::before{content:"";position:absolute;inset:0;z-index:0;background:url(/images/hero-eco.webp) center/cover no-repeat;} .hero-park::before{content:"";position:absolute;inset:0;z-index:0;background:url(/images/hero-park.webp) center/cover no-repeat;}
.hero-eco::before{content:"";position:absolute;inset:0;z-index:0;background:url(/images/hero-eco.webp) center/cover no-repeat;}

/* nav dropdown (Applications) */
.nav-drop{position:relative;}
.nav-drop .nav-drop-title{padding:9px 15px;border-radius:10px;color:var(--ink);font-size:16px;font-weight:500;display:flex;align-items:center;cursor:pointer;transition:color .2s,background .2s;}
.nav-drop:hover .nav-drop-title{color:var(--primary);background:var(--blue-soft);}
.nav-drop .nav-drop-title.active{color:var(--primary);font-weight:700;background:var(--blue-soft);}
.nav-links a.active{color:var(--primary);font-weight:700;background:var(--blue-soft);}
.nav-dropdown{position:absolute;top:100%;left:0;background:#fff;border:1px solid var(--border-light);border-radius:14px;box-shadow:0 12px 30px rgba(20,40,70,.12);min-width:230px;padding:8px;display:none;flex-direction:column;z-index:200;}
.nav-drop:hover .nav-dropdown{display:flex;}
.nav-dropdown a{padding:11px 14px;border-radius:9px;color:var(--ink);font-size:15px;text-decoration:none;display:block;}
.nav-dropdown a:hover{color:var(--primary);background:var(--blue-soft);}

.hero h1{text-shadow:0 2px 18px rgba(0,0,0,.6),0 1px 3px rgba(0,0,0,.5);}
.hero .lead{text-shadow:0 1px 12px rgba(0,0,0,.55);}
/* ===== premium motion ===== */
@keyframes kenburns{from{transform:scale(1);}to{transform:scale(1.12);}}
.hero::before{animation:kenburns 24s ease-in-out infinite alternate;}
@keyframes fadeUp{from{opacity:0;transform:translateY(26px);}to{opacity:1;transform:none;}}
.hero .hero-content{animation:fadeUp .95s cubic-bezier(.2,.7,.3,1) both;}
.hero .hero-card{animation:fadeUp .95s .1s cubic-bezier(.2,.7,.3,1) both;}
/* reveal scroll fade-in rhythm */
.reveal{opacity:0;transform:translateY(34px);transition:opacity .8s ease,transform .8s cubic-bezier(.2,.7,.3,1);}
.reveal.in{opacity:1;transform:none;}
/* card hover lift */
/* card hover enhancement */
.card,.feature,.step{position:relative;overflow:hidden;transition:transform .32s ease,box-shadow .32s ease,border-color .32s ease;}
.card:hover,.feature:hover,.step:hover{transform:translateY(-6px);box-shadow:0 20px 46px rgba(10,24,43,.14);border-color:rgba(23,70,162,.22);}
.card h3,.feature h3,.step h4{transition:color .25s ease;}
.card:hover h3,.feature:hover h3,.step:hover h4{color:var(--primary);}
.feat-icon{transition:transform .35s cubic-bezier(.2,.7,.3,1),background .3s;}
.card:hover .feat-icon,.feature:hover .feat-icon{transform:scale(1.12) rotate(-4deg);background:var(--blue-soft);}
.card::before,.feature::before{content:"";position:absolute;top:0;left:0;right:0;height:3px;background:linear-gradient(90deg,var(--primary),#409eff);opacity:0;transition:opacity .3s;z-index:2;}
.card:hover::before,.feature:hover::before{opacity:1;}
.hero-watch::before{content:"";position:absolute;inset:0;z-index:0;background:url(/images/hero-watch.webp) center/cover no-repeat;}
.hero-keyfob::before{content:"";position:absolute;inset:0;z-index:0;background:url(/images/hero-keyfob.webp) center/cover no-repeat;}
.hero-cmos::before{content:"";position:absolute;inset:0;z-index:0;background:url(/images/hero-cmos.webp) center/cover no-repeat;}
.hero-wholesale::before{content:"";position:absolute;inset:0;z-index:0;background:url(/images/hero-wholesale.webp) center/cover no-repeat;}
.hero-cert::before{content:"";position:absolute;inset:0;z-index:0;background:url(/images/hero-cert.webp) center/cover no-repeat;}
.hero-pack::before{content:"";position:absolute;inset:0;z-index:0;background:url(/images/hero-main.webp) center/cover no-repeat;}

/* applications hero: stronger overlay (brighter images need clearer white text) */
.hero-watch::after,.hero-keyfob::after,.hero-cmos::after{content:"";position:absolute;inset:0;z-index:1;background:linear-gradient(90deg,rgba(8,20,36,.86) 0%,rgba(8,20,36,.58) 52%,rgba(8,20,36,.28) 100%);}

/* ===== hero 背景图 · 手机窄版（卡 G · 2026-09-27 首页/型号页 LCP 专项）=========
   背景是 center/cover，hero 在手机上是 390x641 左右的竖长条，而原图是横图：
   hero-main-clean.webp 1920x701（40.1 KB）、hero-keyfob.jpg 1440x960（101.2 KB，
   还是 JPEG）、hero-watch.webp 931x620（94.5 KB）。cover 只放大了竖边，真正可见的
   只有中间一条，但浏览器要下整张。这里在 900 px 断点换成窄版（宽度见
   scripts/make-hero-variants.mjs），桌面版字节不变。未命中的 media 查询不会产生
   请求，所以手机只下窄版、桌面只下原尺寸；与 <head> 里带 media 的 preload 一一对应。
   顺序上 .hero::before 必须排在各变体之前，否则会把 keyfob/watch 的底图压掉。 */
@media(max-width:900px){
  .hero::before{background-image:url(/images/hero-factory-m1000.webp);}
  .hero-home::before{background-image:url(/images/hero-main-clean-m900.webp);}
  .hero-keyfob::before{background-image:url(/images/hero-keyfob-m1000.webp);}
  .hero-watch::before{background-image:url(/images/hero-watch-m620.webp);}
  .hero-cmos::before{background-image:url(/images/hero-cmos-m700.webp);}
  .hero-wholesale::before{background-image:url(/images/hero-wholesale-m560.webp);}
  .hero-cert::before{background-image:url(/images/hero-cert-m1000.webp);}
  .hero-park::before{background-image:url(/images/hero-park-m700.webp);}
  .hero-oem::before{background-image:url(/images/hero-oem-m1000.webp);}
  .hero-lithium::before,.hero-eco::before{background-image:url(/images/hero-eco-m900.webp);}
  .hero-ind::before{background-image:url(/images/hero-industrial-m1000.webp);}
  .hero-pack::before{background-image:url(/images/hero-main-m900.webp);}
}

/* ===== hero text forced white (readable over images)===== */
.hero h1,.hero h2,.hero .lead,.hero p,.hero b,.hero strong,.hero .t b,.hero .t span,.hero .num b,.hero .num span{color:#fff !important;}
.hero .lead{color:#eef4fb !important;}

/* ===== bullet icons in body copy===== */
.content-block ul li,.content ul li,article ul li,main ul li{list-style:none;position:relative;padding-left:26px;margin-bottom:9px;color:var(--ink);}
.content-block ul li::before,.content ul li::before,article ul li::before,main ul li::before{content:"✓";position:absolute;left:0;top:1px;color:#ea5b0b;font-weight:800;}
/* key numbers/labels as small icon cards */
.content-block .lead{max-width:70ch;}

/* ===== product image carousel ===== */
.carousel{position:relative;overflow:hidden;border-radius:18px;border:1px solid var(--border-light);background:var(--soft);width:100%;}
.car-slides{display:flex;transition:transform .5s ease;}
.car-slides img{width:100%;flex:0 0 100%;object-fit:contain;max-height:450px;background:var(--soft);display:block;}
.car-arrow{position:absolute;top:50%;transform:translateY(-50%);width:42px;height:42px;border-radius:50%;background:rgba(255,255,255,.92);border:1px solid var(--border-light);color:var(--ink);cursor:pointer;font-size:20px;display:flex;align-items:center;justify-content:center;z-index:2;box-shadow:var(--shadow-sm);}
.car-arrow.prev{left:12px}.car-arrow.next{right:12px}
.car-dots{position:absolute;bottom:10px;left:0;right:0;display:flex;justify-content:center;gap:8px;z-index:2;}
.car-dots span{width:9px;height:9px;border-radius:50%;background:rgba(255,255,255,.6);cursor:pointer;border:1px solid rgba(0,0,0,.15);}
.car-dots span.on{background:var(--primary);}

/* ===== detail/body table styling (clean, readable, key values highlighted)===== */
.section table,article table,main table{width:100%;border-collapse:collapse;border-radius:12px;overflow:hidden;box-shadow:0 1px 3px rgba(15,23,42,.06);}
.section thead th,article thead th{background:#eef4fb;color:var(--primary);font-weight:700;text-align:left;padding:13px 16px;font-size:14px;letter-spacing:.02em;white-space:nowrap;border-bottom:2px solid #d9e6f7;}
.section td,article td{padding:12px 16px;border-bottom:1px solid var(--border-light);font-size:14.5px;color:var(--ink);vertical-align:middle;}
.section tbody tr:nth-child(even),article tbody tr:nth-child(even){background:var(--soft);}
.section tbody tr:hover,article tbody tr:hover{background:#eef4fb;}
.section td strong,article td strong{color:var(--primary);font-weight:700;}
.section td:first-child,article td:first-child{font-weight:600;color:var(--ink);}

/* floating inquiry button */
.floating-quote{position:fixed;bottom:24px;right:20px;z-index:900;width:54px;height:54px;border-radius:50%;background:linear-gradient(135deg,#fb923c,#ea5b0b);color:#fff;font-size:22px;display:flex;align-items:center;justify-content:center;box-shadow:0 8px 24px rgba(234,91,11,.35);text-decoration:none;transition:transform .2s;}
.floating-quote:hover{transform:scale(1.07);}
@media(max-width:600px){.floating-quote{right:14px;bottom:78px;width:50px;height:50px;font-size:20px;}}

/* ===== left-side “On this page” TOC (global, same layout as battery-type/cr2032)===== */
.detail-layout{display:grid;grid-template-columns:200px minmax(0,1fr);gap:26px;max-width:1320px;margin:0 auto;padding:44px 24px 0;align-items:start;}
/* 裸 .trustbar（不带 .hero-card 前缀）此前没有任何规则 → 数值与标签以内联排版粘连
   （"CR2032Обычный элемент"）。补一条与 hero 同形的栅格规则，值上标签下。 */
.trustbar{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:16px 20px;}
.trustbar .t{border-left:3px solid var(--primary);padding-left:12px;min-width:0;overflow-wrap:break-word;}
.trustbar .t b{display:block;font-size:24px;line-height:1.2;}
.trustbar .t span{font-size:12.5px;color:var(--ink-3);}
/* 俄语页头：俄语导航项与 CTA 文案更长（О компании / Запросить цену），16px 字号下会被挤成两行，
   俄语树单独略缩字号与内边距，保持单行且不让页头横向溢出。
   2026-10-15：.nav-drop-title 也要一起缩 —— 这一条原先只匹配 a，三个下拉标题（Продукция /
   Применения / Загрузки）仍按 16px + 9px 15px 渲染；把「资源」改成下拉、多出一个标题后，
   俄语页头从「刚好不溢出」变成横向溢出 18px（实测 1280px）。 */
html[lang="ru"] .nav-links a,html[lang="ru"] .nav-labels a,html[lang="ru"] .nav-drop .nav-drop-title{font-size:14px;padding:8px 9px;white-space:nowrap;}
html[lang="ru"] a.nav-cta,html[lang="ru"] .nav-cta a{white-space:nowrap;font-size:13px;padding-left:11px;padding-right:11px;}
html[lang="ru"] .nav-inner{gap:18px;}
.page-toc{position:sticky;top:96px;background:#fff;border:1px solid var(--border-light);border-radius:14px;padding:16px;box-shadow:0 10px 30px rgba(0,0,0,.06);max-height:70vh;overflow:auto;}
.page-toc .lbl{font-size:11px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-2);margin-bottom:8px;}
.page-toc a{display:block;padding:8px 12px;font-size:13px;color:var(--ink-2);border-radius:8px;margin-bottom:2px;line-height:1.45;border-bottom:none;transition:background .15s,color .15s;}
.page-toc a:hover{background:var(--soft);color:var(--ink);}
.page-toc a.active{background:linear-gradient(90deg,#eef4fb,#fff);color:var(--primary);font-weight:700;border-left:3px solid var(--accent);}
@media(max-width:1239px){.detail-layout{grid-template-columns:1fr;padding:28px 16px 0;}.page-toc{position:sticky;top:60px;z-index:20;display:flex;flex-wrap:wrap;gap:8px;width:100%;padding:8px 10px;}.page-toc .lbl{display:none;}.page-toc a{border:none;padding:6px 10px;background:var(--soft);border-radius:20px;font-size:12px;}}
html{scroll-behavior:smooth}


/* ===== model page gallery: main image + thumbnails (all photos visible, click to swap) ===== */
.pgallery{display:flex;flex-direction:column;gap:12px;width:100%;}
.pg-main{position:relative;background:var(--soft);border-radius:14px;display:flex;align-items:center;justify-content:center;min-height:340px;padding:10px;}
.pg-main img{max-width:100%;max-height:450px;object-fit:contain;display:block;}
.pg-thumbs{display:flex;gap:10px;flex-wrap:wrap;justify-content:center;}
.pg-thumb{width:78px;height:78px;padding:4px;background:#fff;border:1px solid var(--border-light);border-radius:10px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:border-color .2s, box-shadow .2s;}
.pg-thumb img{max-width:100%;max-height:100%;object-fit:contain;display:block;}
.pg-thumb:hover{border-color:var(--primary);}
.pg-thumb.on{border-color:var(--primary);box-shadow:0 0 0 2px rgba(23,70,162,.18);}
/* left/right carousel controls on the main image */
.pg-nav{position:absolute;top:50%;transform:translateY(-50%);width:42px;height:42px;border-radius:50%;border:1px solid var(--border-light);background:rgba(255,255,255,.94);color:var(--primary);cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:16px;line-height:1;box-shadow:var(--shadow-sm);z-index:2;transition:background .2s, border-color .2s, transform .2s;padding:0;}
.pg-nav:hover{background:#fff;border-color:var(--primary);}
.pg-nav:focus-visible{outline:2px solid var(--primary);outline-offset:2px;}
.pg-nav[disabled]{opacity:.4;cursor:default;}
.pg-prev{left:10px;}
.pg-next{right:10px;}
.pg-count{position:absolute;right:12px;bottom:10px;background:rgba(11,31,69,.72);color:#fff;font-size:12px;font-variant-numeric:tabular-nums;padding:3px 9px;border-radius:999px;letter-spacing:.02em;z-index:2;pointer-events:none;}
@media(max-width:640px){.pg-main{min-height:240px;}.pg-main img{max-height:300px;}.pg-thumb{width:62px;height:62px;}.pg-nav{width:38px;height:38px;font-size:14px;}.pg-prev{left:4px;}.pg-next{right:4px;}.pg-count{right:8px;bottom:8px;font-size:11px;}}

/* ===== Videos page: hero (solid brand gradient, no photo) ===== */
.hero-videos::before{content:"";position:absolute;inset:0;z-index:0;background:linear-gradient(135deg,#0b1f45 0%,#1746a2 55%,#1f5fd0 100%);}
.hero-videos .hero-content{padding:78px 0 66px;}

/* ===== Videos page: grid + cards + self-hosted player ===== */
.video-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:22px;margin-top:22px;}
.vcard{margin:0;background:#fff;border:1px solid var(--border-light);border-radius:16px;overflow:hidden;box-shadow:var(--shadow-sm);transition:transform .25s ease,box-shadow .25s ease,border-color .25s ease;}
.vcard:hover{transform:translateY(-3px);box-shadow:0 16px 40px rgba(11,26,46,.12);border-color:var(--primary);}
.vthumb{position:relative;display:block;width:100%;border:0;padding:0;cursor:pointer;background:var(--soft);aspect-ratio:16/9;}
.vthumb-portrait{aspect-ratio:3/4;}
.vthumb img{width:100%;height:100%;object-fit:contain;display:block;}
.vplay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;}
.vplay::after{content:"";width:58px;height:58px;border-radius:50%;background:rgba(23,70,162,.92);box-shadow:0 8px 24px rgba(11,26,46,.35);}
.vplay::before{content:"";position:absolute;margin-left:4px;border-style:solid;border-width:11px 0 11px 18px;border-color:transparent transparent transparent #fff;z-index:2;}
.vthumb:hover .vplay::after{background:#ea5b0b;}
.vdur{position:absolute;right:10px;bottom:10px;background:rgba(8,20,36,.78);color:#fff;font-size:12px;font-weight:700;padding:3px 8px;border-radius:6px;letter-spacing:.02em;}
.vcard figcaption{padding:14px 16px 16px;}
.vcard figcaption b{display:block;color:var(--ink);font-size:16px;margin-bottom:5px;}
.vcard figcaption span{display:block;color:var(--ink-2);font-size:14px;line-height:1.6;}

/* ===== self-hosted video lightbox ===== */
.vbox{position:fixed;inset:0;z-index:2100;background:rgba(6,14,28,.94);display:flex;align-items:center;justify-content:center;padding:24px;}
.vbox[hidden]{display:none;}
.vbox-inner{width:min(1100px,100%);}
.vbox video{width:100%;max-height:76vh;background:#000;border-radius:14px;display:block;box-shadow:0 30px 90px rgba(0,0,0,.6);}
.vbox-title{color:#fff;font-size:16px;font-weight:700;margin-top:14px;text-align:center;}
.vbox-close{position:absolute;top:18px;right:24px;width:46px;height:46px;border-radius:50%;border:0;background:rgba(255,255,255,.16);color:#fff;font-size:26px;line-height:1;cursor:pointer;}
.vbox-close:hover{background:rgba(255,255,255,.28);}
@media(max-width:640px){.video-grid{grid-template-columns:1fr;gap:16px;}.vbox-inner video{max-height:60vh;}}

/* ===== Inline video block (video embedded inside a content section) ===== */
.vblock{display:grid;grid-template-columns:minmax(240px,380px) 1fr;gap:30px;align-items:center;margin-top:26px;background:#fff;border:1px solid var(--border-light);border-radius:18px;padding:22px;box-shadow:var(--shadow-sm);}
.vblock-grid{grid-template-columns:1fr;}
.vblock-grid .vblock-media{display:grid;grid-template-columns:repeat(auto-fit,minmax(270px,1fr));gap:18px;width:100%;align-items:start;}
.vblock-media{display:flex;gap:16px;flex-wrap:wrap;justify-content:center;}
.vblock-media .vcard{border:0;box-shadow:none;margin:0;}
.vblock-media .vthumb{box-shadow:0 10px 30px rgba(11,26,46,.14);}
.vblock-list{margin:0;padding-left:18px;color:var(--ink-2);font-size:15px;line-height:1.75;}
.vblock-list li{margin-bottom:4px;}
@media(max-width:900px){.vblock{grid-template-columns:1fr;gap:20px;}}

/* ===== Process steps (OEM page): 3x2 icon cards, readable, not a wall of text ===== */
.steps-grid{grid-template-columns:repeat(3,1fr);gap:20px;}
.pstep{padding:24px 24px 22px;display:flex;flex-direction:column;}
.pstep-top{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px;}
.pstep-num{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;border-radius:10px;background:var(--primary);color:#fff;font-weight:800;font-size:15px;box-shadow:0 6px 16px rgba(23,70,162,.22);}
.pstep-ic{display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;border-radius:12px;background:var(--blue-soft);color:var(--primary);font-size:19px;}
.pstep h4{font-size:17.5px;margin:0 0 8px;}
.pstep p{font-size:14.5px;line-height:1.6;color:var(--ink-2);margin:0 0 14px;}
.pstep-chip{align-self:flex-start;margin-top:auto;background:#fff5ec;color:#b34700;border:1px solid #ffe0c7;font-size:12.5px;font-weight:700;padding:5px 11px;border-radius:999px;letter-spacing:.01em;}
.pstep:hover .pstep-ic{background:#e3efff;}
@media(max-width:1023px){.steps-grid{grid-template-columns:1fr 1fr;}}
@media(max-width:700px){.steps-grid{grid-template-columns:1fr;}}

/* Process step cards v2: photo on top, badge overlay, icon inline with title */
.pstep{padding:0 0 22px;overflow:hidden;}
.pstep-media{position:relative;margin:0;background:var(--soft);}
.pstep-img{width:100%;height:152px;object-fit:cover;display:block;}
.pstep-img.is-product{object-fit:contain;padding:14px;background:#fff;}
.pstep-num{position:absolute;top:12px;left:12px;box-shadow:0 6px 18px rgba(8,20,36,.28);}
.pstep-body{padding:16px 22px 0;}
.pstep-body h4{display:flex;align-items:center;gap:9px;font-size:17px;margin:0 0 8px;}
.pstep-body h4 i{color:var(--primary-bright);font-size:15px;}
@media(max-width:1023px){.pstep-img{height:170px;}}

/* ===== Article typography for Markdown/MDX content (.prose) ===== */
.prose{font-size:17px;line-height:1.85;color:var(--ink-2);}
.prose > *:first-child{margin-top:0;}
.prose h2{font-size:27px;font-weight:900;color:#1c2b4a;margin:40px 0 14px;line-height:1.25;}
.prose h3{font-size:20px;font-weight:800;color:var(--ink);margin:28px 0 10px;}
.prose h2:first-child,.prose h3:first-child{margin-top:0;}
.prose p{margin:0 0 18px;}
.prose strong{color:var(--ink);font-weight:700;}
/* :not(.btn) matters — without it this rule (specificity 0,1,1) outranks
   .btn-primary{color:#fff} (0,1,0), so any button placed inside .prose got its
   text recoloured to the same navy as its own background and rendered blank
   (plus an underline it should never have had). Same guard already used by the
   .cta-inline rule below. */
.prose a:not(.btn){color:var(--primary);font-weight:600;text-decoration:underline;text-underline-offset:3px;}
.prose a:not(.btn):hover{color:var(--primary-bright);}
.prose ul,.prose ol{margin:0 0 20px;padding-left:24px;}
.prose ul li{list-style:disc !important;padding-left:0 !important;margin-bottom:8px;}
.prose ul li::before{content:none !important;}
.prose ol li{list-style:decimal !important;padding-left:0 !important;margin-bottom:8px;}
.prose li::marker{color:var(--primary);}
.prose blockquote{margin:24px 0;padding:16px 22px;background:var(--blue-soft);border-left:4px solid var(--primary-bright);border-radius:0 12px 12px 0;color:var(--ink-2);}
.prose blockquote p:last-child{margin-bottom:0;}
.prose img{border-radius:12px;margin:22px 0;border:1px solid var(--border-light);}
.prose hr{border:0;border-top:1px solid var(--border-light);margin:34px 0;}
.prose code{background:var(--soft);padding:2px 6px;border-radius:5px;font-size:15px;}
.prose table{margin:22px 0;}
/* Spec tables are wider than a phone — the CR2032 comparison measures ~620px in
   six columns of part numbers — and with no scroll box they pushed the whole
   page sideways. display:block on the table makes it its own scroll container
   while the rows stay a real table inside it. */
@media(max-width:768px){
  .prose table,.container table{display:block;overflow-x:auto;-webkit-overflow-scrolling:touch;max-width:100%;}
}
/* Grid/flex children default to min-width:auto, so a column is floored by its
   content's min-content width: the model-page gallery and the OEM page's
   detail column were both pinned ~410-520px on a 390px phone, scrolling the
   whole page sideways. min-width:0 lets them shrink to the screen. */
@media(max-width:1024px){
  .product-layout > *,.detail-layout > *{min-width:0;}
}
/* Contact page: the form/sidebar split is set inline as 1.4fr/1fr, so it takes
   !important to override at phone widths (an inline declaration outranks any
   selector). Without this the page measured 609px on a 390px screen. */
@media(max-width:900px){
  .contact-grid{grid-template-columns:1fr !important;gap:28px !important;}
  .contact-grid > *{min-width:0;}
}

/* ---- Blog article typography -------------------------------------------
   The post column ran 756px wide at 17px — roughly 88 characters per line,
   well past the 60-75 that reads comfortably. Capping the measure and opening
   up the heading rhythm is the biggest readability win on these guides.
   Scoped to .prose-article so product and legal pages keep their layout. */
/* 640px, not 72ch: ch resolves against the glyph "0" (~0.6em) and came out at
   771.6px, wider than the 756px column, so it constrained nothing. 640px lands
   near 72 real characters per line at 17.5px. */
.prose-article{max-width:640px;margin:0 auto;}
.prose-article p{font-size:17.5px;line-height:1.8;}
.prose-article > p:first-of-type{font-size:19px;line-height:1.72;color:var(--ink-2);}
.prose-article h2{margin-top:54px;}
.prose-article h2:first-child{margin-top:0;}
.prose-article h3{margin-top:34px;}
.prose-article ul,.prose-article ol{margin-bottom:24px;}
.prose-article table{font-size:15px;}
.prose .panel-note{margin:24px 0;font-size:15.5px;}

/* live spec table inside articles (SpecTable.astro) */
.spec-table{margin:26px 0;background:#fff;border:1px solid var(--border-light);border-radius:14px;padding:6px 10px 10px;box-shadow:var(--shadow-sm);}
.spec-table table{margin:0;}
.spec-table td strong{color:var(--primary);}
.spec-note{margin:8px 2px 4px;font-size:13.5px;color:var(--ink-3);}

/* inline CTA box inside articles */
.cta-inline{display:flex;align-items:center;gap:18px;flex-wrap:wrap;justify-content:space-between;margin:30px 0 6px;padding:20px 24px;border-radius:16px;background:linear-gradient(135deg,#12233c,#1b3a6b);color:#fff;}
.cta-inline strong{font-size:17px;display:block;}
.cta-inline span{color:#cfe0f5;font-size:14.5px;}
.cta-inline > div,.cta-inline > span{max-width:52ch;}
.cta-inline .btn{background:#fff;color:var(--primary);border-color:#fff;}
.cta-inline .btn:hover{background:var(--blue-soft);color:var(--primary);}
@media(max-width:640px){.prose{font-size:16.5px;}.prose h2{font-size:23px;}}

/* figure inside articles (e.g. the watch replacement diagram) */
.article-figure{margin:26px 0;background:#fff;border:1px solid var(--border-light);border-radius:16px;padding:16px;box-shadow:var(--shadow-sm);}
.article-figure svg{width:100%;height:auto;display:block;}

/* ---- Blog media & layout blocks -----------------------------------------
   These guides carry real first-party photos: the factory floor, the
   certificates and the actual cells we produce. Captions say what is shown,
   so an image never implies more than it is. Different blocks let each guide
   lead with the device that suits its content instead of one uniform layout. */
.prose figure{margin:26px 0;}
/* Single figures show the whole frame — several of our product shots are tall
   strips (model-cr2032.jpg is 187x595), so contain + a height cap guarantees a
   product is never cropped out of view. The soft backing keeps odd ratios tidy. */
.prose figure img{margin:0 auto;display:block;width:auto;max-width:100%;max-height:460px;object-fit:contain;background:var(--soft);border-radius:10px;}
.prose figcaption{margin-top:10px;font-size:13.5px;line-height:1.65;color:var(--ink-3);text-align:left;}
.prose figcaption strong{color:var(--ink-2);font-weight:600;}

/* 2- and 3-up rows — uniform square tiles so a row of mixed source shapes still
   reads as one grid. Wins over .prose figure img on specificity (0,2,1 > 0,1,2). */
.prose .img-row{display:grid;gap:14px;margin:26px 0;}
.prose .img-row.cols-2{grid-template-columns:repeat(2,1fr);}
.prose .img-row.cols-3{grid-template-columns:repeat(3,1fr);}
.prose .img-row figure{margin:0;background:#fff;border:1px solid var(--border-light);border-radius:14px;padding:10px;}
.prose .img-row figcaption{margin-top:8px;font-size:12.5px;}
.prose .img-row img{width:100%;height:auto;aspect-ratio:1/1;object-fit:cover;object-position:center;border-radius:8px;background:var(--soft);}
@media(max-width:640px){.prose .img-row.cols-3{grid-template-columns:repeat(2,1fr);}}

/* Inline video — portrait source (544x720) so pair it with its caption rather
   than letting a full-width block run ~960px tall down the article. */
.prose .video-figure{margin:28px 0;display:flex;gap:22px;align-items:center;flex-wrap:wrap;background:#fff;border:1px solid var(--border-light);border-radius:16px;padding:16px;box-shadow:var(--shadow-sm);}
.prose .video-figure video{flex:0 0 300px;width:300px;max-width:100%;height:auto;display:block;border-radius:10px;background:#0b1f45;}
.prose .video-figure figcaption{flex:1 1 240px;margin:0;font-size:13.5px;line-height:1.7;color:var(--ink-3);}
@media(max-width:640px){.prose .video-figure video{flex:0 0 100%;width:100%;}}

/* Key takeaway — deliberately unlike blockquote (which is a quotation) */
.prose .key-takeaway{margin:26px 0;padding:18px 22px;background:#f2f7ff;border:1px solid #cfe0f5;border-left:4px solid var(--accent);border-radius:0 14px 14px 0;}
.prose .key-takeaway .kt-label{display:block;font-size:11.5px;letter-spacing:.14em;text-transform:uppercase;font-weight:800;color:var(--accent);margin-bottom:9px;}
.prose .key-takeaway ul{margin:0;padding-left:20px;}
.prose .key-takeaway li{margin-bottom:7px;color:var(--ink-2);}
.prose .key-takeaway li:last-child{margin-bottom:0;}

/* Stat strip — figures already stated in the text, pulled out for scanning */
.prose .stat-strip{display:grid;grid-template-columns:repeat(auto-fit,minmax(132px,1fr));gap:14px;margin:26px 0;padding:18px;background:#fff;border:1px solid var(--border-light);border-radius:14px;box-shadow:var(--shadow-sm);}
.prose .stat-strip div{border-left:3px solid var(--primary);padding-left:12px;}
.prose .stat-strip b{display:block;font-size:21px;font-weight:800;color:var(--primary);line-height:1.2;}
.prose .stat-strip span{font-size:12.5px;color:var(--ink-3);line-height:1.4;}

/* Recommended-reading link card (GuideLink.astro) */
.guidelink{display:flex;gap:16px;align-items:center;margin:34px auto 0;padding:18px 22px;max-width:820px;background:#fff;border:1px solid var(--border-light);border-left:4px solid var(--primary-bright);border-radius:14px;box-shadow:var(--shadow-sm);transition:box-shadow .25s ease,transform .25s ease;}
.guidelink:hover{box-shadow:0 10px 30px rgba(23,70,162,.14);transform:translateY(-2px);}
.gl-ic{flex:0 0 44px;width:44px;height:44px;border-radius:12px;background:var(--blue-soft);color:var(--primary);display:flex;align-items:center;justify-content:center;font-size:18px;}
.gl-body{flex:1;min-width:0;}
.gl-eyebrow{font-size:11.5px;letter-spacing:.12em;text-transform:uppercase;font-weight:800;color:var(--orange,#ea5b0b);margin-bottom:4px;}
.gl-title{display:block;font-size:17px;font-weight:800;color:var(--ink);text-decoration:none;line-height:1.35;}
.gl-title:hover{color:var(--primary);}
.gl-desc{font-size:13.5px;color:var(--ink-2);margin-top:5px;line-height:1.5;}
.gl-arrow{flex:0 0 auto;font-size:20px;font-weight:800;color:var(--primary-bright);text-decoration:none;padding-left:6px;}
@media(max-width:640px){.guidelink{gap:12px;padding:15px 16px;}.gl-ic{flex:0 0 36px;width:36px;height:36px;font-size:15px;}.gl-title{font-size:15.5px;}.gl-desc{display:none;}}

/* contrast fix (2026-09-11): text inside the dark inline CTA must stay light —
   .prose strong / .prose a would otherwise paint it dark on dark */
.cta-inline strong,.prose .cta-inline strong{color:#fff !important;font-size:17px;display:block;}
.cta-inline a:not(.btn),.prose .cta-inline a:not(.btn){color:#fff !important;text-decoration:underline;text-underline-offset:3px;}
.cta-inline a:not(.btn):hover,.prose .cta-inline a:not(.btn):hover{color:#cfe0f5 !important;}
.cta-inline h2,.cta-inline h3,.cta-inline h4{color:#fff !important;}

/* Screen-reader-only text (2026-09-17): the header search icon and the WhatsApp
   floating button are icon-only <a> tags, so they shipped with zero anchor text.
   Screaming Frog flagged every one of the 192 pages for it. The span below gives
   crawlers and screen readers real link text without touching the visual design. */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;}

/* Only clickable cards advertise a click (2026-09-23).
   A .card/.feature/.step lifts and its heading turns blue on hover — the strongest
   "I am clickable" signal on the site. Cards that are NOT links were lifting right
   next to real link cards (the "On request" model tiles on /models/ and
   /zh/aaa-battery/ sit in the same grid as the linked ones), so a tap did nothing.
   Clarity showed dead clicks on exactly those pages (/zh/aaa-battery/ 2 clicks =
   100% of sessions, /models/ 1) and the page's own source comment records the same
   bug being fixed once before for the homepage industry cards, which became links.
   A card keeps the hover response only if it is a link itself (a.card) or contains
   one (.card:has(a)). No .card on the site is nested inside an <a>, so that case
   needs no rule. Only the movement/shadow/heading-colour are reset here — border
   colour is left alone because .section-deep .c has a different resting border. */
.card:not(a):not(:has(a)):hover,.c:not(a):not(:has(a)):hover,
.feature:not(a):not(:has(a)):hover,.step:not(a):not(:has(a)):hover,
.prod-card:not(a):not(:has(a)):hover{transform:none;box-shadow:var(--shadow-sm);}
.card:not(a):not(:has(a)):hover h3,.card:not(a):not(:has(a)):hover h4,
.feature:not(a):not(:has(a)):hover h3,.step:not(a):not(:has(a)):hover h4{color:inherit;}
.card:not(a):not(:has(a)):hover img.card-thumb{transform:none;}
.card:not(a):not(:has(a)):hover .feat-icon,.feature:not(a):not(:has(a)):hover .feat-icon{transform:none;}


/* Language switcher: one chip per published language (en/zh/de/es). Previously a
   single toggle between two languages; with four trees the strip lists them all
   and marks the one you are on. Kept compact so it fits the desktop nav. */
.lang-strip{display:inline-flex;align-items:center;gap:2px;margin-left:8px;height:40px;padding:0 4px;border:1px solid var(--border);border-radius:10px;flex:0 0 auto;}
.lang-strip a{display:inline-flex;align-items:center;justify-content:center;height:30px;min-width:32px;padding:0 8px;border-radius:7px;color:var(--ink);font-size:13px;font-weight:700;line-height:1;transition:color .2s,background .2s;}
.lang-strip a:hover{color:var(--primary);background:var(--blue-soft);text-decoration:none;}
.lang-strip a[aria-current="true"]{background:var(--primary);color:#fff;}
.lang-strip-mobile{margin-left:0;height:auto;border:0;padding:0;flex-wrap:wrap;gap:6px;}
.lang-strip-mobile a{height:34px;padding:0 10px;border:1px solid var(--border);border-radius:8px;font-weight:700;color:var(--primary);}
.lang-strip-mobile a[aria-current="true"]{color:#fff;}
/* ===== language switcher — one dropdown instead of four chips (2026-09-28) ====
   Owner request: "把语种切换的合并，换成下拉切换的方式". The bar's four chips
   (137px: four non-shrinking items in a nowrap row) become a single button that
   opens a four-row panel, so the language slot costs ~62px instead of ~137px —
   ~75px handed back to every language, which is what lets the phone button added
   the same day pay for itself (de/es went from −96/−109 to about −21/−34).
   The mobile menu keeps its own .lang-strip-mobile chips (this dropdown is hidden
   ≤600px): inside a vertical menu a four-item list beats a nested dropdown, and
   its 34px rows are the touch target. Hover/focus opens it on desktop; the click
   toggle (.open, set by the inline script) covers tablets and touch, where hover
   does not exist. */
.lang-switch{position:relative;display:flex;flex:0 0 auto;}
.lang-switch-btn{display:inline-flex;align-items:center;gap:5px;height:40px;padding:0 9px;border:1px solid var(--border);border-radius:10px;background:none;color:var(--ink);font:inherit;font-size:13px;font-weight:700;line-height:1;cursor:pointer;transition:color .2s,background .2s,border-color .2s;}
.lang-switch-btn:hover{color:var(--primary);background:var(--blue-soft);border-color:transparent;}
.lang-switch-btn:focus-visible{outline:2px solid var(--primary-bright);outline-offset:2px;}
.lang-switch-btn > i{font-size:12px;color:var(--primary);}
.lang-switch-btn .ls-caret{font-size:10px;color:var(--ink-3);transition:transform .2s;}
.lang-switch.open .lang-switch-btn .ls-caret{transform:rotate(180deg);}
.lang-switch-panel{display:none;position:absolute;top:100%;right:0;z-index:200;min-width:188px;padding:6px;background:#fff;border:1px solid var(--border-light);border-radius:14px;box-shadow:0 12px 30px rgba(20,40,70,.12);}
.lang-switch-panel a{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:9px 10px;border-radius:9px;color:var(--ink);font-size:14.5px;font-weight:600;white-space:nowrap;}
.lang-switch-panel a:hover{color:var(--primary);background:var(--blue-soft);text-decoration:none;}
.lang-switch-panel .ls-short{font-size:11.5px;font-weight:700;letter-spacing:.04em;color:var(--ink-3);}
.lang-switch-panel a[aria-current="true"]{color:var(--primary);background:var(--blue-soft);}
.lang-switch-panel a[aria-current="true"] > i{font-size:12px;}
.lang-switch.open .lang-switch-panel{display:flex;flex-direction:column;}
@media(min-width:1201px){
  .lang-switch:hover .lang-switch-panel,.lang-switch:focus-within .lang-switch-panel{display:flex;flex-direction:column;}
}
/* ≤600px: the bar's switcher is the dropdown, so hide that instead of the old
   chip strip (the menu's own .lang-strip-mobile keeps every language reachable).
   Keep the `.nav-inner >` scope: .lang-strip is still shared with
   .lang-strip-mobile in the menu, and media queries add no specificity — a bare
   `.lang-strip a{height:26px}` rule written when the strip only existed in the
   bar once won on document order and shrank the MENU's chips to 26px, below
   their designed 34px touch height. */
@media(max-width:600px){.nav-inner > .lang-switch{display:none;}}
/* 1201-1439px: compressed desktop nav. The bar needs logo 130 + nav-links +
   search 40 + language slot + CTA + four gaps, and the longest language sets
   the threshold. Measured 2026-09-24: with the standard 30px gap, DE/ES need
   ~1380px of viewport and EN ~1314px, so the entire 1201-1380 band scrolled
   sideways on laptops — DE 67px, ES 68px, EN 2px at 1280px. Verified against
   production: byte-identical overflow before and after the mobile burger fix, so
   it predates it. Root cause is the same class of miss as the burger bug: the
   desktop threshold was measured 2026-09-18 as "fits from ~1180px", then de/es
   were added 2026-09-23 and widened the bar past it without a re-measure.
   Compressing the band, rather than raising the burger breakpoint to 1380, keeps
   the full nav on 1280/1366 laptops: gap 30->16, link padding 12->9 and tighter
   spacing recover enough that all four trees measure 0px overflow from
   1201px up (de/es/zh/en, 1201-1520px swept).
   History of the language slot: ~159px of chips until 2026-09-24, then a 137px
   chip strip, and 62px since 2026-09-28 (.lang-switch dropdown). The 75px that
   freed is what de/es spend on the phone button and on closing their own gap —
   they are still the reason this band exists.
   MUST stay at the end of the file: .nav-links a is set earlier, media queries
   add no specificity, so document order decides. If a language is ever added,
   re-measure this band and the >=1440px slack. */
@media(min-width:1201px) and (max-width:1439px){
  .nav-inner{gap:16px;}
  .nav-links a{padding-left:9px;padding-right:9px;}
  /* the language chips that used to be tightened here are gone: the slot is the
     .lang-switch dropdown now, fixed at ~62px in every band. */
}

/* ===== nav contact — phone button + contact panel (2026-09-28) ==============
   Owner request: "顶部导航也加个联系方式" — a contact channel in the top bar.

   Budget first, because this bar has no spare pixels. Measured 2026-09-28
   (nav budget harness, single-line widths, content box 1116px):
     en +20px · zh +64px · de −102px · es −115px   (negative = over budget)
   and the >=1440px band, with its roomy 30px gap, was over in EVERY language
   (en −88, de −210, es −223) — which is why the quote button has been wrapping
   to two lines above 1440px and de/es have been wrapping "Über uns" inside the
   compressed band. So the new button is paid for out of the bar's airiness, not
   out of its items — no nav link, chip or language toggle was removed:
     · one desktop spacing for the whole >=1201px range (gap 14, link padding 7,
       chips 26px/4px, search 36px, cta margin 6px). This also removes the
       pre-existing >=1440px overflow, so the quote button stops wrapping.
     · the phone button itself is 40x40 (36 on phones) and costs exactly one
       border+gap, i.e. ~56px.
   Re-measured after: en/zh fit with slack, de/es end up no worse than before
   (they were already over budget) — numbers in
   conversation-logs/2026-09-28-首页门店实拍提前.md and the nav budget report.
   Hover/focus panel carries the three channels; on touch the number is one tap
   away in the mobile menu (.mobile-menu-contact), where it is visible as text. */
.nav-phone{position:relative;display:flex;flex:0 0 auto;}
.nav-phone-btn{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;border:1px solid var(--border);border-radius:10px;color:var(--ink);font-size:16px;flex:0 0 auto;transition:color .2s,background .2s,border-color .2s;}
.nav-phone-btn:hover{color:var(--primary);background:var(--blue-soft);border-color:transparent;text-decoration:none;}
.nav-phone-btn:focus-visible{outline:2px solid var(--primary-bright);outline-offset:2px;}
.nav-phone-panel{display:none;position:absolute;top:100%;right:0;z-index:200;min-width:252px;padding:8px;background:#fff;border:1px solid var(--border-light);border-radius:14px;box-shadow:0 12px 30px rgba(20,40,70,.12);}
.nav-phone-panel .npp-title{padding:6px 10px 4px;font-size:11.5px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3);}
.nav-phone-panel a{display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:9px;color:var(--ink);font-size:14.5px;font-weight:600;white-space:nowrap;}
.nav-phone-panel a:hover{color:var(--primary);background:var(--blue-soft);text-decoration:none;}
.nav-phone-panel i,.nav-phone-panel svg{width:17px;height:17px;flex:0 0 auto;font-size:16px;color:var(--primary);fill:currentColor;}
/* touch/short viewports: no hover, and the number lives in the menu — see below */
@media(min-width:1201px){
  .nav-phone:hover .nav-phone-panel,.nav-phone:focus-within .nav-phone-panel{display:flex;flex-direction:column;}
}
.mobile-menu .mobile-menu-contact{display:flex;flex-direction:column;gap:8px;padding:4px 0 14px;border-bottom:1px solid var(--border-light);}
.mobile-menu .mobile-menu-contact a{display:flex;align-items:center;gap:10px;padding:11px 12px;border:1px solid var(--border);border-radius:10px;color:var(--primary);font-size:15px;font-weight:700;}
.mobile-menu .mobile-menu-contact a:hover{background:var(--blue-soft);text-decoration:none;}
.mobile-menu .mobile-menu-contact i,.mobile-menu .mobile-menu-contact svg{width:17px;height:17px;flex:0 0 auto;font-size:16px;}
.mobile-menu .mobile-menu-contact svg{fill:currentColor;}
.mobile-menu .mobile-menu-contact span{overflow-wrap:anywhere;}
/* one spacing for the whole desktop range (see the budget comment above).
   Document order decides: this block must stay after the two band rules. */
@media(min-width:1201px){
  .nav-inner{gap:14px;}
  .nav-links a{padding-left:7px;padding-right:7px;}
  .nav-search{width:36px;height:36px;}
  .nav-cta{margin-left:6px;}
}
@media(max-width:600px){
  .nav-inner{gap:10px;}
  .nav-phone-btn{width:36px;height:36px;}
}
/* the quote button has been wrapping to two lines since long before this change
   (measured 2026-09-28: 2 lines at every width in en/de/es, 1 line in zh — the
   .btn line-height is 1, so 14px text in a 20px-padded box wraps as soon as the
   flex row squeezes it). en/zh have the room to keep it on one line, de/es do
   not: forcing nowrap there pushed the bar 54-58px past its container and gave
   the page a horizontal scrollbar at 1201px, so it is scoped, not global. */
:lang(en) .nav-cta,:lang(zh) .nav-cta{white-space:nowrap;}
/* 1201-1439px: give back the last ~20px the button costs in this band, so de/es
   keep the room they had before it (they carry the two longest nav sets).
   Must stay after the >=1201px block above — same specificity, order decides. */
@media(min-width:1201px) and (max-width:1439px){
  .nav-inner{gap:12px;}
  .nav-search{width:34px;height:34px;}
}
/* 360px budget with the phone in the bar: logo 129 + search 36 + phone 36 +
   burger 46 + 3x10px gaps = 277 of the 281px content box — 4px of slack, so
   below 360px the button steps aside and the menu keeps the number. */
@media(max-width:359px){
  .nav-phone{display:none;}
}
