/* ==========================================================================
   Linnuo Optical Communications — Design System
   ==========================================================================
   Visual direction: engineering-credible, not marketing-loud.
   The audience is network engineers and procurement engineers. They trust
   spec tables, clear numbers and restraint far more than gradients and glow.
   Palette is deliberately cool/technical; the single accent is reserved for
   primary actions so every CTA is unambiguous.
   ========================================================================== */

:root {
  /* --- Surfaces: light theme, because datasheet-legibility wins here --- */
  --bg:            #ffffff;
  --bg-subtle:     #f6f8fa;
  --bg-sunken:     #eef1f4;
  --surface:       #ffffff;
  --surface-alt:   #f9fafb;

  /* --- Ink --- */
  --ink:           #0d1520;
  --ink-strong:    #060b12;
  --ink-muted:     #556070;
  --ink-faint:     #8590a0;
  --ink-invert:    #ffffff;

  /* --- Lines --- */
  --line:          #dfe4ea;
  --line-strong:   #c3cbd6;
  --line-faint:    #eaeef2;

  /* --- Accent: single action colour, used sparingly --- */
  --accent:        #0f5fd4;
  --accent-hover:  #0b4cae;
  --accent-soft:   #e8f0fd;
  --accent-line:   #b9d2f7;

  /* --- Signal colours (only for status, never decoration) --- */
  --ok:            #0f7b4f;
  --ok-soft:       #e6f5ee;
  --warn:          #a8620a;
  --warn-soft:     #fdf3e3;
  --danger:        #b42318;

  /* --- Typography --- */
  --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI",
          "Helvetica Neue", Arial, "Noto Sans", sans-serif;
  --mono: "SFMono-Regular", "JetBrains Mono", Menlo, Consolas,
          "Liberation Mono", monospace;

  /* --- Spacing scale (4px base) --- */
  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
  --s5: 24px; --s6: 32px; --s7: 48px; --s8: 64px; --s9: 96px;

  /* --- Radii: tight. Rounded corners read as consumer software. --- */
  --r1: 3px; --r2: 5px; --r3: 8px;

  /* --- Elevation: barely there --- */
  --sh1: 0 1px 2px rgba(13,21,32,.06);
  --sh2: 0 2px 8px rgba(13,21,32,.07);
  --sh3: 0 8px 24px rgba(13,21,32,.09);

  --maxw: 1200px;
  --maxw-narrow: 860px;

  /* ==========================================================================
     图片显示大小与位置 —— 想调产品图，只改下面这几个数字就够了
     --------------------------------------------------------------------------
     宽度（填百分比或像素都行）
        100%      撑满所在的栏
         80%      缩到八成的宽度
        420px     固定 420 像素宽，大屏也不会再变大
     横向位置（三选一）
        center    居中（默认）
        left      靠左
        right     靠右
     上边留白：图片上方空多少（想让图和上面的标题贴近就调小）
     改完存盘 → 重建网站 → 刷新页面就能看到。
     百分比会自动适配中英文两版以及手机 / 电脑，不需要分别设置。
     ========================================================================== */
  --photo-card-w: 40%;              /* 分类页卡片 小图宽度 */
  --photo-card-align: center;       /* 分类页卡片 小图位置：center / left / right */
  --photo-radius: var(--r3);        /* 图片圆角 */
}
/* --------------------------------------------------------------------------
   Reset
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img, svg { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; color: inherit; }
h1, h2, h3, h4, h5 { margin: 0; line-height: 1.22; letter-spacing: -.015em; font-weight: 650; }
p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
table { border-collapse: collapse; width: 100%; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--r1); }

/* --------------------------------------------------------------------------
   Layout
   -------------------------------------------------------------------------- */
.wrap { width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 0 var(--s5); }
.wrap-narrow { max-width: var(--maxw-narrow); }
.section { padding: var(--s8) 0; }
.section-sm { padding: var(--s7) 0; }
.section-alt { background: var(--bg-subtle); border-top: 1px solid var(--line-faint); border-bottom: 1px solid var(--line-faint); }
.grid { display: grid; gap: var(--s5); }
.g2 { grid-template-columns: repeat(2, 1fr); }
.g3 { grid-template-columns: repeat(3, 1fr); }
.g4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 960px) { .g3, .g4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px) { .g2, .g3, .g4 { grid-template-columns: 1fr; } }

/* --------------------------------------------------------------------------
   Typography helpers
   -------------------------------------------------------------------------- */
.eyebrow {
  font-size: 12px; font-weight: 640; letter-spacing: .09em;
  text-transform: uppercase; color: var(--accent);
}
.h1 { font-size: clamp(30px, 4.4vw, 52px); font-weight: 680; letter-spacing: -.025em; }
.h2 { font-size: clamp(24px, 2.9vw, 34px); }
.h3 { font-size: clamp(18px, 1.9vw, 22px); }
.lead { font-size: clamp(16px, 1.5vw, 18.5px); color: var(--ink-muted); line-height: 1.62; }
.muted { color: var(--ink-muted); }
.faint { color: var(--ink-faint); }
.mono { font-family: var(--mono); font-size: .92em; }
.section-head { max-width: 760px; margin-bottom: var(--s6); }
.section-head .h2 { margin-bottom: var(--s3); }
.nowrap { white-space: nowrap; }

/* --------------------------------------------------------------------------
   Home hero: full-bleed banner, copy sitting on the image (left side)

   Source photo is 6.1:1 and already composed for this: the left ~38% is a
   clean, very dark (mean luminance ~48, peak 73) uncluttered surface with no
   bright pixel anywhere in it, and the switch with the green MPO connector
   and a fan of fibre patch cords sits centre-right. Because the left is
   already dark, the scrim only has to shape the transition rather than
   rescue contrast -- a heavy overlay would flatten the equipment we want
   people to look at.
   -------------------------------------------------------------------------- */
.hero-banner {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background: #2a3038;              /* matches the photo's dark tone */
  border-bottom: 1px solid var(--line);
}

.hero-banner-img {
  display: block;
  width: 100%;
  /* cap the height so very wide screens don't get a letterbox strip */
  height: clamp(280px, 34vw, 500px);
  object-fit: cover;
  /* A 6.1:1 photo in a ~2.94:1 box, so cover keeps the full height and crops
     the sides -- only ~48% of the photo's width survives at 1440px. Measured
     luminance across the original: flat dark surface out to ~38%, a blurred
     rack post near 40%, the lit switch core at 48-68%, rack shadow beyond 75%.
     A 50% anchor puts the brass latch at ~40% of the viewport (just clear of
     the copy block, which ends near 36%) and lands the switch core at
     46-87%, so the unit reads big and the patch cords sweep into the middle.
     Pushing left (30-40%) shoved the switch against the right edge and cut
     it off; pushing right (60%+) dragged the bright latch over the headline --
     measured text-zone peak luminance jumps from 56 at 50% to 143 at 60%. */
  object-position: 50% 50%;
}

/* Left-to-right scrim. The photo's left edge is already dark, so this is
   deliberately gentle: it deepens the corner the headline sits on and fades
   out before reaching the equipment. */
.hero-banner-scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(
    100deg,
    rgba(10, 22, 38, .62) 0%,
    rgba(10, 22, 38, .40) 26%,
    rgba(10, 22, 38, .14) 46%,
    rgba(10, 22, 38, 0) 60%
  );
}

.hero-banner-wrap {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  align-items: center;
}

.hero-banner-copy {
  max-width: 640px;
  color: #fff;
}

.hero-banner-copy .eyebrow {
  color: rgba(255, 255, 255, .88);
}

.hero-banner-copy .h1 {
  color: #fff;
  max-width: 15ch;
  text-shadow: 0 1px 18px rgba(4, 12, 24, .45);
}

.hero-banner-copy .lead {
  color: rgba(255, 255, 255, .93);
  max-width: 44ch;
  text-shadow: 0 1px 14px rgba(4, 12, 24, .42);
}

/* On the photo the outline button needs a light treatment, not the theme's
   dark-ink one. */
.hero-banner-copy .btn-outline {
  background: rgba(255, 255, 255, .10);
  border-color: rgba(255, 255, 255, .62);
  color: #fff;
  backdrop-filter: blur(3px);
}
.hero-banner-copy .btn-outline:hover {
  background: rgba(255, 255, 255, .20);
  border-color: #fff;
}

/* ---- narrow screens: stack the copy under a shorter banner ---- */
@media (max-width: 860px) {
  /* A 6:1 photo in a tall narrow box crops hard -- only ~32% of the width
     survives at 390px. The vertical scrim below darkens the bottom band, so
     the copy stays readable at any anchor (measured: 0 pixels above 150 in
     the text zone from 40% to 70%), which leaves the anchor free to be
     chosen purely for composition. 50% frames the latch, the green MPO
     connector and the fan of patch cords together. */
  .hero-banner-img { height: clamp(200px, 42vw, 320px); object-position: 50% 50%; }
  .hero-banner-scrim {
    background: linear-gradient(
      180deg,
      rgba(10, 22, 38, .30) 0%,
      rgba(10, 22, 38, .64) 70%,
      rgba(10, 22, 38, .78) 100%
    );
  }
  .hero-banner-wrap { align-items: flex-end; padding-bottom: var(--s5); }
  .hero-banner-copy { max-width: none; }
  .hero-banner-copy .h1 { max-width: none; }
  .hero-banner-copy .lead { max-width: none; }
}

/* Respect users who ask for more contrast over the photo */
@media (prefers-contrast: more) {
  .hero-banner-scrim {
    background: linear-gradient(
      100deg,
      rgba(6, 16, 30, .86) 0%,
      rgba(6, 16, 30, .64) 34%,
      rgba(6, 16, 30, .28) 58%,
      rgba(6, 16, 30, .04) 74%
    );
  }
}

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  padding: 11px 20px; border-radius: var(--r2);
  font-size: 15px; font-weight: 600; line-height: 1;
  border: 1px solid transparent; cursor: pointer;
  transition: background .14s ease, border-color .14s ease, color .14s ease;
  white-space: nowrap;
}
.btn-primary { background: var(--accent); color: var(--ink-invert); }
.btn-primary:hover { background: var(--accent-hover); }
.btn-outline { background: var(--surface); border-color: var(--line-strong); color: var(--ink); }
.btn-outline:hover { border-color: var(--ink-muted); background: var(--surface-alt); }
.btn-ghost { background: transparent; color: var(--accent); padding-left: 0; padding-right: 0; }
.btn-ghost:hover { text-decoration: underline; }
.btn-sm { padding: 7px 13px; font-size: 13.5px; }
.btn-lg { padding: 14px 26px; font-size: 16px; }
.btn-block { width: 100%; }
.btn-wa { background: #1faa53; color: #fff; }
.btn-wa:hover { background: #188c44; }

/* --------------------------------------------------------------------------
   Cards & panels
   -------------------------------------------------------------------------- */
.card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r3); padding: var(--s5);
}
.card-hover { transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease; }
.card-hover:hover { border-color: var(--accent-line); box-shadow: var(--sh2); transform: translateY(-1px); }
.panel { background: var(--surface-alt); border: 1px solid var(--line); border-radius: var(--r3); padding: var(--s5); }
.panel-accent { background: var(--accent-soft); border: 1px solid var(--accent-line); border-radius: var(--r3); padding: var(--s5); }

/* ---- quote rail on a product page ------------------------------------------
   Follows the page as it scrolls and stays on the vertical centre line of the
   viewport. It cannot just be `position: sticky; top: 50vh` — sticky only ever
   offsets an element DOWNWARD, so at the very top of the page the panel would
   jump 200-odd px below where it belongs. Putting the box on the centre line
   and pulling it back up by half its own height keeps it centred while it
   travels and leaves it in place at the top. The height differs between
   English and Chinese copy, which is why this is a transform rather than a
   hard-coded calc().
   On narrow screens the whole grid collapses to one column, so there is
   nothing to sit beside — the rail goes back to being an ordinary block. */
/* ---- product detail page --------------------------------------------------
   Classic two-column PDP: the left column carries the photo + specs and is
   tall; the right column carries SKU/title/badges + the quote box and is
   STICKY, so the buy box follows the reader while the specs scroll. The old
   floating rail (sticky + translateY(-50%)) needed an empty column to travel
   in — that was the void this layout replaces. */
.pd-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s6);
  /* Mobile: title → photo → buy box → specs → quality */
  grid-template-areas: 'info' 'photo' 'aside' 'specs' 'quality';
}
.pd-info { grid-area: info; min-width: 0; }
.pd-photo { grid-area: photo; }
.pd-aside { grid-area: aside; min-width: 0; }
.pd-specs { grid-area: specs; min-width: 0; }
.pd-quality { grid-area: quality; min-width: 0; }
@media (min-width: 901px) {
  .pd-grid {
    grid-template-columns: minmax(0, 1.15fr) minmax(320px, 0.85fr);
    gap: var(--s7);
    align-items: start;
    /* Desktop: title spans full width; the buy box occupies the right column
       from the photo row down and is sticky, so it follows the reader while
       the specs and quality sections scroll past. */
    grid-template-areas:
      'info info'
      'photo aside'
      'specs aside'
      'quality aside';
  }
  .pd-aside { position: sticky; top: 90px; }
}

.pd-photo {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--photo-radius);
  padding: 14px;
  line-height: 0;
}
.pd-photo img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: calc(var(--photo-radius) - 3px);
}

/* ---- product photos (only products listed in data/product-images.json) ----
   Both are studio shots on a white ground, so they need a hairline to hold
   their edges against the white page — a heavier frame would read as a
   screenshot rather than a product photo. */
.card-shot {
  /* full-bleed across the card's top edge: the negative margins undo .card's
     own padding, so the shot sits flush instead of looking inset */
  margin: calc(var(--s5) * -1) calc(var(--s5) * -1) var(--s5);
  border-bottom: 1px solid var(--line-faint);
  border-radius: var(--photo-radius) var(--photo-radius) 0 0;
  overflow: hidden;
  background: #fff;
  /* text-align + inline-block is what lets one variable position the shot
     (left/center/right); line-height 0 kills the inline descender gap */
  text-align: var(--photo-card-align);
  line-height: 0;
}
.card-shot img {
  display: inline-block;
  width: var(--photo-card-w);
  height: auto;
  vertical-align: top;
}

/* hero stats under the lead — dark-ground styling, hairline between the two */
.hero-stats { display: flex; gap: var(--s6); margin-top: var(--s4); }
.hero-stats .v { font-size: 21px; font-weight: 680; color: #fff; letter-spacing: -.01em; }
.hero-stats .l { font-size: 13px; color: rgba(255, 255, 255, .72); margin-top: 3px; }
.hero-stats > div + div { border-left: 1px solid rgba(255, 255, 255, .30); padding-left: var(--s6); }
@media (max-width: 860px) {
  .hero-stats { gap: var(--s5); margin-top: var(--s3); }
  .hero-stats .v { font-size: 18px; }
  .hero-stats > div + div { padding-left: var(--s5); }
}

/* ---- home-page trust bar + hot-products carousel ----
   The trust bar is a slim strip now (14px padding instead of section-sm).
   The carousel is a scroll-snap flex track: 5 cards per view on desktop,
   arrows half-outside the wrap, dots = number of scroll positions. */
.trustbar { padding: 14px 0; }

/* The flagship feature sits directly on the grey band — no card box. The
   spec strip reads as five white cells with neutral hairlines. */
.flag-specs { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--r2); overflow: hidden; }
.flag-specs > div { background: var(--surface); padding: 12px 14px; }

.hot-rule { width: 44px; height: 3px; background: var(--accent); margin: 12px auto; border-radius: 2px; }
.hot-sub { font-size: 13.5px; letter-spacing: .02em; }
/* The wrap carries side padding sized to the round arrows, so the buttons sit
   beside the track — never on top of the cards — at every viewport width. */
.hot-wrap { position: relative; margin-top: var(--s6); padding: 0 56px; }
.hot-track {
  position: relative;
  display: flex; gap: var(--s4);
  overflow-x: auto; scroll-snap-type: x mandatory; scroll-behavior: smooth;
  scrollbar-width: none; -ms-overflow-style: none;
  padding-bottom: 4px;
}
.hot-track::-webkit-scrollbar { display: none; }
.hot-card {
  flex: 0 0 calc((100% - 4 * var(--s4)) / 5);
  scroll-snap-align: start;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r3);
  overflow: hidden;
  transition: box-shadow .15s ease, transform .15s ease;
}
.hot-card:hover { box-shadow: 0 10px 24px rgba(13, 21, 32, .12); transform: translateY(-3px); }
.hot-img { aspect-ratio: 1 / 1; background: #fff; line-height: 0; }
.hot-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.hot-body { padding: 12px 14px 14px; border-top: 1px solid var(--line-faint); }
.hot-title {
  font-size: 14px; font-weight: 620; line-height: 1.45;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; min-height: 2.9em;
}
.hot-meta { font-size: 12.5px; color: var(--accent); margin-top: 8px; }
.hot-nav {
  position: absolute; top: 30%; z-index: 2;
  width: 38px; height: 38px; border-radius: 50%;
  border: 1px solid var(--line-strong);
  background: var(--surface); color: var(--accent);
  font-size: 22px; line-height: 1; cursor: pointer;
  box-shadow: var(--sh1);
  display: flex; align-items: center; justify-content: center;
}
.hot-nav:hover { background: var(--accent); color: #fff; border-color: var(--accent); }
.hot-nav.prev { left: 0; }
.hot-nav.next { right: 0; }
.hot-dots { display: flex; gap: 8px; justify-content: center; margin-top: var(--s5); }
.hot-dots button { width: 8px; height: 8px; border-radius: 50%; border: 0; padding: 0; cursor: pointer; background: var(--line-strong); }
.hot-dots button.on { background: var(--accent); }
@media (max-width: 1100px) {
  .hot-card { flex-basis: calc((100% - 3 * var(--s4)) / 4); }
}
@media (max-width: 860px) {
  .hot-wrap { padding: 0 46px; }
  .hot-card { flex-basis: calc((100% - 2 * var(--s4)) / 3); }
  .hot-nav { background: rgba(255, 255, 255, .92); }
}
@media (max-width: 620px) {
  .hot-card { flex-basis: calc((100% - var(--s4)) / 2); }
}
@media (max-width: 430px) {
  .hot-card { flex-basis: 78%; }
}

/* products filter card: a full-bleed white band (as wide as the hero band
   above); the inner .wrap keeps the fields at content width and position. */
.fpanel {
  background: var(--surface-alt);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.fpanel-in { position: relative; padding: var(--s6) 0 24px; }
.fpanel .input, .fpanel .select { padding: 13px 14px; }
.fpanel-reset { margin-top: var(--s3); }

/* products catalogue hero band — light datacenter photo with a white scrim:
   the dark title stays readable on the left, the corridor shows through on
   the right. */
.pl-hero { position: relative; overflow: hidden; border-bottom: 1px solid var(--line-faint); }
.pl-hero-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.pl-hero-scrim {
  position: absolute; inset: 0;
  background: linear-gradient(90deg, rgba(255,255,255,.94) 0%, rgba(255,255,255,.82) 52%, rgba(255,255,255,.42) 100%);
}
.pl-hero-in {
  position: relative;
  min-height: clamp(320px, 28vw, 400px);
  display: flex; flex-direction: column; justify-content: center;
  padding: var(--s6) 0;
}
@media (max-width: 860px) {
  .pl-hero-in { padding: var(--s6) 0; }
  .pl-hero-scrim { background: rgba(255, 255, 255, .88); }
}

/* ---- about page ----
   Three pillars under a shared accent rule + mono index number; the stats
   band is a centred strip with hairline dividers (echoes the home flagship
   spec strip). */
.about-pillar { border-top: 3px solid var(--accent); padding-top: var(--s5); }
.stats-row { display: grid; grid-template-columns: repeat(3, 1fr); text-align: center; }
.stats-row > div { padding: 4px var(--s4); }
.stats-row > div + div { border-left: 1px solid var(--accent-line); }
.stats-row .v { font-size: clamp(26px, 3vw, 40px); font-weight: 680; letter-spacing: -.02em; }
.stats-row .l { font-size: 14px; color: var(--ink-muted); margin-top: 6px; }
@media (max-width: 760px) {
  .stats-row { grid-template-columns: 1fr; gap: var(--s4); }
  .stats-row > div + div { border-left: 0; border-top: 1px solid var(--accent-line); padding-top: var(--s4); }
}

/* ---- home-page category card photo ----
   Full-bleed across the card's top edge (negative margins undo .card's own
   padding). aspect-ratio + object-fit keep every card's image the same height
   even when the AI placeholders are replaced by photos of other sizes. */
.cat-shot {
  margin: calc(var(--s5) * -1) calc(var(--s5) * -1) var(--s4);
  border-bottom: 1px solid var(--line-faint);
  border-radius: var(--photo-radius) var(--photo-radius) 0 0;
  overflow: hidden;
  background: #fff;
  line-height: 0;
}
.cat-shot img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
}

/* ---- home-page flagship panel photo ----
   The photo is a white-ground studio shot, so it sits on a white mat with a
   hairline — a plain <img> on the pale-blue panel would show a hard white
   rectangle with no edge. */
.flag-top {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--s5); margin-bottom: var(--s5);
}
.flag-copy { flex: 1 1 320px; min-width: 260px; }
/* Transparent-ground module shot: no white mat, the module floats on the
   grey band (the user asked for no white box). */
.flag-shot {
  flex: 1 1 300px; max-width: 380px; margin: 0;
  line-height: 0;
}
.flag-shot img { display: block; width: 100%; height: auto; }

/* Spec strip under the copy: five metrics side by side. Cells are white with
   neutral hairlines so the strip blends with the grey band (the blue panel
   box around the flagship was removed at the user's request). */
.flag-specs dt { font-size: 12px; color: var(--ink-muted); margin: 0 0 4px; letter-spacing: .02em; }
.flag-specs dd { margin: 0; font-size: 14px; font-weight: 640; color: var(--ink); word-break: break-word; }
/* Wide screens: keep spec values like "640 km @400G / 2000 km @200G" on one
   line AND give each column a width that matches its content — 传输距离 gets
   the biggest share, 封装形式 the smallest (its value is short), so nothing
   is clipped by the panel's overflow:hidden. Narrow screens drop back to the
   auto-fit grid and let long values wrap. */
@media (min-width: 901px) {
  .flag-specs { grid-template-columns: 0.8fr 1.2fr 1.55fr 1.25fr 0.7fr; }
  .flag-specs dd { white-space: nowrap; }
}

/* --------------------------------------------------------------------------
   Badges / chips / pills
   -------------------------------------------------------------------------- */
.badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; border-radius: 100px;
  font-size: 12px; font-weight: 620; line-height: 1.5;
}
.badge-neutral  { background: var(--bg-sunken); color: var(--ink-muted); }
.badge-accent   { background: var(--accent-soft); color: var(--accent); }
.badge-ok       { background: var(--ok-soft); color: var(--ok); }
.badge-warn     { background: var(--warn-soft); color: var(--warn); }
.badge-outline  { border: 1px solid var(--line-strong); color: var(--ink-muted); background: transparent; }

.chips { display: flex; flex-wrap: wrap; gap: var(--s2); }
.chip {
  display: inline-flex; align-items: center;
  padding: 5px 11px; border: 1px solid var(--line); border-radius: 100px;
  background: var(--surface); font-size: 13px; font-weight: 560;
  color: var(--ink-muted); cursor: pointer; user-select: none;
  transition: all .13s ease;
}
.chip:hover { border-color: var(--line-strong); color: var(--ink); }
.chip[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: #fff; }

/* --------------------------------------------------------------------------
   Spec tables — the backbone of this site
   -------------------------------------------------------------------------- */
.spec-table { font-size: 14.5px; }
.spec-table th {
  text-align: left; font-weight: 620; font-size: 12px;
  letter-spacing: .05em; text-transform: uppercase; color: var(--ink-muted);
  padding: 10px var(--s3); border-bottom: 1px solid var(--line-strong);
  white-space: nowrap;
}
.spec-table td {
  padding: 11px var(--s3); border-bottom: 1px solid var(--line-faint);
  vertical-align: top;
}
.spec-table tbody tr:hover { background: var(--accent-soft); }
.spec-table .sku { font-family: var(--mono); font-size: 13px; font-weight: 600; color: var(--ink); white-space: nowrap; }

/* ---- 列宽：型号 / 速率 / 传输距离 / 产品描述 / 操作 ----
   描述列不设宽度，自动吃掉剩余空间，这样各列间距才均匀。
   ⚠️ 增删表格列时必须同步改这几条 nth-child（现在目录表和分类页
   的 tier-2 表都是这 5 列，共用这一组规则）。 */
.spec-table th:nth-child(1), .spec-table td:nth-child(1) { width: 150px; }
.spec-table th:nth-child(2), .spec-table td:nth-child(2) { width: 150px; }
.spec-table th:nth-child(3), .spec-table td:nth-child(3) { width: 190px; }
.spec-table th:nth-child(5), .spec-table td:nth-child(5) { width: 108px; }

.kv { display: grid; grid-template-columns: 168px 1fr; gap: 1px; font-size: 14.5px; }
.kv dt {
  padding: 10px 0; color: var(--ink-muted); font-weight: 560;
  border-bottom: 1px solid var(--line-faint);
}
.kv dd {
  margin: 0; padding: 10px 0; border-bottom: 1px solid var(--line-faint);
}
@media (max-width: 560px) {
  .kv { grid-template-columns: 1fr; }
  .kv dt { padding-bottom: 0; border-bottom: 0; }
  .kv dd { padding-top: 2px; }
}

/* --------------------------------------------------------------------------
   Forms
   -------------------------------------------------------------------------- */
.field { margin-bottom: var(--s4); }
.field label {
  display: block; margin-bottom: 6px;
  font-size: 13.5px; font-weight: 600; color: var(--ink);
}
.field .hint { font-size: 12.5px; color: var(--ink-faint); margin-top: 5px; }
.input, .select, .textarea {
  width: 100%; padding: 10px 12px;
  border: 1px solid var(--line-strong); border-radius: var(--r2);
  background: var(--surface); font-size: 15px;
  transition: border-color .13s ease, box-shadow .13s ease;
}
.input:focus, .select:focus, .textarea:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.textarea { min-height: 108px; resize: vertical; }
.input[readonly] { background: var(--bg-subtle); color: var(--ink-muted); }
.req { color: var(--danger); }

/* --------------------------------------------------------------------------
   Header / nav
   -------------------------------------------------------------------------- */
.hdr {
  position: sticky; top: 0; z-index: 60;
  background: rgba(255,255,255,.92);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--line);
}
.hdr-in { display: flex; align-items: center; gap: var(--s6); height: 66px; }
.brand { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
/* The mark used to be a blue rounded square with "LN" set in it. It is now the
   real brand logo (assets/img/brand-mark.png) — a flat orange/blue "N" on a
   TRANSPARENT ground, so no background, no border-radius and no type styles:
   any of those would fight the artwork. The logo's own negative space is the
   white that forms the N, which is why it must sit on a light surface. It is
   still legible on the dark footer (measured 3.7:1 for the blue, and the
   orange is far higher), so no separate dark-mode asset is needed. */
.brand-mark {
  width: 32px; height: 32px;
  object-fit: contain;
  flex-shrink: 0;
  display: block;
}
.brand-txt { display: flex; flex-direction: column; line-height: 1.18; }
.brand-name { font-size: 15px; font-weight: 680; letter-spacing: -.01em; }
.brand-sub { font-size: 10.5px; color: var(--ink-faint); letter-spacing: .04em; text-transform: uppercase; }

.nav { display: flex; align-items: center; gap: var(--s1); margin-left: auto; }
/* :not(.btn) — the CTA button in the nav is a .btn-primary, and this rule's
   specificity (0,1,1) beats .btn-primary's (0,1,0). Without the exclusion the
   muted link colour leaked onto the button and its label vanished against the
   blue fill. */
.nav a:not(.btn) {
  padding: 8px 12px; border-radius: var(--r2);
  font-size: 14.5px; font-weight: 560; color: var(--ink-muted);
  transition: color .13s ease, background .13s ease;
}
.nav a:not(.btn):hover { color: var(--ink); background: var(--bg-subtle); }
.nav a:not(.btn)[aria-current="page"] { color: var(--accent); font-weight: 620; }
.nav .btn { margin-left: var(--s3); }

/* Language switch */
.lang { display: flex; align-items: center; gap: 2px; padding: 2px; background: var(--bg-sunken); border-radius: var(--r2); }
.lang a { padding: 4px 9px; border-radius: var(--r1); font-size: 12.5px; font-weight: 620; color: var(--ink-muted); }
.lang a[aria-current="true"] { background: var(--surface); color: var(--ink); box-shadow: var(--sh1); }

.burger { display: none; margin-left: auto; background: none; border: 0; cursor: pointer; padding: 8px; }
.burger span { display: block; width: 20px; height: 2px; background: var(--ink); margin: 4px 0; border-radius: 2px; }

@media (max-width: 1040px) {
  .nav {
    display: none; position: absolute; top: 66px; left: 0; right: 0;
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--surface); border-bottom: 1px solid var(--line);
    padding: var(--s3) var(--s5) var(--s5); box-shadow: var(--sh3);
  }
  .nav.open { display: flex; }
  .nav a { padding: 11px 0; border-bottom: 1px solid var(--line-faint); }
  .nav .btn { margin: var(--s4) 0 0; }
  .burger { display: block; }
  .hdr-in { gap: var(--s3); }
}

/* --------------------------------------------------------------------------
   Breadcrumb
   -------------------------------------------------------------------------- */
.crumb { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-size: 13px; color: var(--ink-faint); }
.crumb a:hover { color: var(--accent); }
.crumb .sep { color: var(--line-strong); }

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */
.ftr { background: var(--ink-strong); color: #c8d1dd; padding: var(--s8) 0 var(--s5); margin-top: var(--s9); }
.ftr a { color: #c8d1dd; font-size: 14px; }
.ftr a:hover { color: #fff; }
.ftr h4 { color: #fff; font-size: 13px; letter-spacing: .07em; text-transform: uppercase; margin-bottom: var(--s3); }
.ftr-links li { margin-bottom: 9px; }
.ftr-grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1.3fr; gap: var(--s6); }
@media (max-width: 900px) { .ftr-grid { grid-template-columns: 1fr 1fr; gap: var(--s5); } }
@media (max-width: 560px) { .ftr-grid { grid-template-columns: 1fr; } }
.ftr-bot {
  margin-top: var(--s7); padding-top: var(--s5);
  border-top: 1px solid rgba(255,255,255,.13);
  display: flex; flex-wrap: wrap; gap: var(--s3) var(--s5);
  justify-content: space-between; font-size: 13px; color: #8e9aab;
}
.ftr .brand-name { color: #fff; }

/* --------------------------------------------------------------------------
   Utilities
   -------------------------------------------------------------------------- */
.mt0{margin-top:0}.mt1{margin-top:var(--s1)}.mt2{margin-top:var(--s2)}.mt3{margin-top:var(--s3)}
.mt4{margin-top:var(--s4)}.mt5{margin-top:var(--s5)}.mt6{margin-top:var(--s6)}.mt7{margin-top:var(--s7)}
.mb0{margin-bottom:0}.mb1{margin-bottom:var(--s1)}.mb2{margin-bottom:var(--s2)}.mb3{margin-bottom:var(--s3)}
.mb4{margin-bottom:var(--s4)}.mb5{margin-bottom:var(--s5)}.mb6{margin-bottom:var(--s6)}.mb7{margin-bottom:var(--s7)}
.flex{display:flex}.ac{align-items:center}.jb{justify-content:space-between}.fw{flex-wrap:wrap}
.g2s{gap:var(--s2)}.g3s{gap:var(--s3)}.g4s{gap:var(--s4)}.g5s{gap:var(--s5)}.g6s{gap:var(--s6)}
.tc{text-align:center}.tr{text-align:right}
.hide{display:none !important}
.sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}

/* ------------------------------------------------------------------
   生产能力页（Capabilities）—— 数据条 / 流程编号 / 图墙
   ------------------------------------------------------------------ */
.svc-stats {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--s4);
}
.svc-stat {
  background: var(--card, #fff); border: 1px solid var(--line, #e6e9ee);
  border-radius: 10px; padding: 22px 20px;
}
.svc-stat .v {
  font-size: clamp(26px, 3vw, 34px); font-weight: 640; color: var(--accent);
  letter-spacing: -0.02em;
}
.svc-stat .l { margin-top: 6px; font-size: 14px; color: var(--ink-muted); }
.svc-step .num {
  font-size: 13px; font-weight: 640; color: var(--accent);
  margin-bottom: 10px; letter-spacing: 0.08em;
}
.svc-shot { margin: 0; }
.svc-shot img {
  width: 100%; height: auto; border-radius: var(--photo-radius, 8px);
  border: 1px solid var(--line, #e6e9ee); display: block;
}
@media (max-width: 860px) {
  .svc-stats { grid-template-columns: repeat(2, 1fr); }
}

/* ------------------------------------------------------------------
   生产能力页：内容较短，去掉页脚上方过大的留白
   （.ftr 全局带 96px 上间距，此处单独收紧）
   ------------------------------------------------------------------ */
body.page-service .ftr { margin-top: 0; }
