@charset "utf-8";
/* ==========================================================================
   W.S. Security — Design System  "Version A · 極簡溫暖米白企業資安風"
   Minimal · Enterprise · Editorial · Premium · Warm · Technical · Calm
   Principle: the logo is ornate, therefore the UI stays quiet.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. TOKENS
   Accessibility rules derived from measured WCAG ratios (see comments):
     graphite on ivory  14.74:1  AAA  -> body text
     bronze  on ivory    2.94:1  FAIL -> DECORATION ONLY, never text
     gold    on ivory    1.95:1  FAIL -> DECORATION ONLY, never text
     warmgray on ivory   3.40:1  fail body -> large text only
     gray-ink on ivory   5.08:1  AA   -> muted body text  (derived tone)
     charcoal on bronze  5.76:1  AA   -> button label on bronze fill
     white   on bronze   3.26:1  FAIL -> never use white text on bronze
     gold    on charcoal 8.67:1  AAA  -> accent text on dark sections
   -------------------------------------------------------------------------- */
:root {
  /* Brand palette (fixed) */
  --ws-ivory:      #F7F3EA;
  --ws-soft:       #FCFBF8;
  --ws-graphite:   #20201E;
  --ws-charcoal:   #121210;
  --ws-bronze:     #B98445;
  --ws-gold:       #D1AA72;
  --ws-warm-gray:  #87837D;

  /* Derived tones (accessibility + surface work only — same warm family) */
  --ws-gray-ink:   #6B6760;   /* AA muted text on ivory/soft */
  --ws-bronze-ink: #8A5F2B;   /* AA bronze for SMALL text on light: 5.41 on soft,
                                 4.83 on ivory. --ws-bronze itself is 3.15 and
                                 must not carry small labels. */
  --ws-line:       #E3DCCD;   /* hairline rules on ivory */
  --ws-line-dark:  #2E2E2A;   /* hairline rules on charcoal */
  --ws-bronze-dim: rgba(185, 132, 69, 0.16);
  --ws-bronze-vei: rgba(185, 132, 69, 0.30);

  /* Semantic */
  --bg:            var(--ws-ivory);
  --bg-raised:     var(--ws-soft);
  --bg-invert:     var(--ws-charcoal);
  --text:          var(--ws-graphite);
  --text-strong:   var(--ws-charcoal);
  --text-muted:    var(--ws-gray-ink);
  --accent:        var(--ws-bronze);
  --accent-soft:   var(--ws-gold);
  --rule:          var(--ws-line);

  /* Type */
  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans TC",
               "PingFang TC", "Hiragino Sans CJK TC", "Microsoft JhengHei",
               "Source Han Sans TC", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-serif: "Noto Serif TC", "Source Han Serif TC", "Songti TC", "Georgia",
                "Times New Roman", "PMingLiU", serif;
  --font-mono: ui-monospace, "SFMono-Regular", "JetBrains Mono", Menlo,
               Consolas, "Noto Sans Mono CJK TC", monospace;

  /* Spacing scale (4px base) */
  --s1: .25rem;  --s2: .5rem;   --s3: .75rem;  --s4: 1rem;
  --s5: 1.5rem;  --s6: 2rem;    --s7: 3rem;    --s8: 4rem;
  --s9: 6rem;    --s10: 8rem;

  --measure: 68ch;
  --container: 1180px;
  /* The header row carries the whole navigation, and the four languages size
     it very differently: Traditional Chinese needs 523px of it, Malay 907px.
     Giving the header its own wider maximum keeps a single shared header for
     all four languages rather than tuning type or dropping items for the
     widest one. Page content keeps --container. */
  --container-header: 1280px;
  --radius: 2px;              /* editorial: almost square, never pill-like */
  --dur: 220ms;
  --ease: cubic-bezier(.4, 0, .2, 1);
}

/* --------------------------------------------------------------------------
   2. RESET / BASE
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 1.0625rem;
  line-height: 1.75;
  letter-spacing: .012em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}
img, svg, picture { max-width: 100%; height: auto; display: block; }
h1, h2, h3, h4 {
  color: var(--text-strong);
  font-weight: 600;
  line-height: 1.28;
  letter-spacing: -.005em;
  margin: 0 0 var(--s4);
  text-wrap: balance;
}
h1 { font-size: clamp(2rem, 1.35rem + 2.6vw, 3.15rem); line-height: 1.18; }
h2 { font-size: clamp(1.5rem, 1.2rem + 1.3vw, 2.1rem); }
h3 { font-size: clamp(1.125rem, 1.05rem + .35vw, 1.3rem); }
h4 { font-size: 1.0625rem; }
p  { margin: 0 0 var(--s4); max-width: var(--measure); }
ul, ol { margin: 0 0 var(--s4); padding-left: 1.25em; max-width: var(--measure); }
li { margin-bottom: var(--s2); }
strong { font-weight: 600; color: var(--text-strong); }
hr { border: 0; border-top: 1px solid var(--rule); margin: var(--s7) 0; }

a { color: var(--text-strong); text-decoration-thickness: 1px; text-underline-offset: .22em; }
a:hover { text-decoration-color: var(--accent); }

:focus-visible {
  outline: 2px solid var(--ws-graphite);
  outline-offset: 3px;
  border-radius: 1px;
}

.skip-link {
  position: absolute; left: var(--s4); top: -100px; z-index: 200;
  background: var(--ws-charcoal); color: var(--ws-ivory);
  padding: var(--s3) var(--s5); border-radius: var(--radius);
  font-size: .9375rem; font-weight: 600; text-decoration: none;
  transition: top var(--dur) var(--ease);
}
.skip-link:focus { top: var(--s4); }

.visually-hidden {
  position: absolute !important; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* --------------------------------------------------------------------------
   3. LAYOUT PRIMITIVES
   -------------------------------------------------------------------------- */
.container { width: 100%; max-width: var(--container); margin-inline: auto; padding-inline: var(--s5); }
.section { padding-block: clamp(var(--s8), 7vw, var(--s10)); }
.section--tight { padding-block: clamp(var(--s7), 5vw, var(--s8)); }
.section--rule { border-top: 1px solid var(--rule); }
.section--raised { background: var(--bg-raised); }

/* Dark editorial band */
.section--invert {
  background: var(--bg-invert);
  color: #DFDAD0;
  /* Re-point the muted token for dark ground. --ws-gray-ink (#6B6760) is tuned
     for ivory and measures only 3.13:1 on the dark panel -- it FAILS WCAG AA
     for body text. Overriding the custom property here cascades the correct
     tone to every descendant (.pillar p, .cred-list li, .steps p,
     .contact-list dt ...) instead of patching each one. #B8B3A9 measures
     8.98:1 on --ws-charcoal and 8.43:1 on the raised dark panel. */
  --text-muted: #B8B3A9;
}
.section--invert h1, .section--invert h2,
.section--invert h3, .section--invert h4 { color: var(--ws-ivory); }
.section--invert .eyebrow { color: var(--ws-gold); }
.section--invert .lede { color: #C9C4BA; }
.section--invert a { color: var(--ws-gold); }
.section--invert hr,
.section--invert .section--rule { border-color: var(--ws-line-dark); }

.stack > * + * { margin-top: var(--s4); }
.grid { display: grid; gap: var(--s6); }
@media (min-width: 720px)  { .grid--2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 940px)  { .grid--3 { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 940px)  { .grid--split { grid-template-columns: 1fr 1fr; gap: var(--s8); align-items: center; } }
@media (min-width: 940px)  { .grid--aside { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: var(--s8); } }

/* --------------------------------------------------------------------------
   4. EDITORIAL TYPE COMPONENTS
   -------------------------------------------------------------------------- */
.eyebrow {
  display: block;
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: var(--s4);
}
.eyebrow::before {
  content: ""; display: inline-block;
  width: 1.75rem; height: 1px; margin-right: .75rem;
  vertical-align: .32em; background: var(--accent);
}
.lede {
  font-size: clamp(1.0625rem, 1rem + .35vw, 1.25rem);
  line-height: 1.7;
  color: var(--text-muted);
  max-width: 60ch;
}
.section-title { max-width: 34ch; }
.display-rule { width: 3.5rem; height: 2px; background: var(--accent); border: 0; margin: var(--s5) 0; }

/* --------------------------------------------------------------------------
   5. BUTTONS  (charcoal label on bronze fill = 5.76:1 AA)
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; gap: .6em;
  padding: .78em 1.5em;
  font-family: inherit; font-size: .9688rem; font-weight: 600;
  line-height: 1.2; letter-spacing: .02em;
  border: 1px solid transparent; border-radius: var(--radius);
  text-decoration: none; cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
              border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.btn .icon { width: 1em; height: 1em; flex: none; }

.btn--primary { background: var(--ws-bronze); color: var(--ws-charcoal); border-color: var(--ws-bronze); }
.btn--primary:hover { background: var(--ws-gold); border-color: var(--ws-gold); color: var(--ws-charcoal); }

.btn--ghost { background: transparent; color: var(--text-strong); border-color: var(--ws-line); }
.btn--ghost:hover { border-color: var(--accent); background: var(--ws-bronze-dim); }

/* CASCADE FIX: `.section--invert a` (0,1,1) outranks `.btn--primary` (0,1,0)
   and was repainting the primary button's label gold on a gold fill — 1.50:1,
   effectively invisible. Restate the label colour at equal-or-higher weight.
   Charcoal on bronze measures 5.76:1. */
.section--invert .btn--primary { color: var(--ws-charcoal); }
.section--invert .btn--primary:hover { color: var(--ws-charcoal); }
.section--invert .btn--ghost { color: var(--ws-ivory); border-color: var(--ws-line-dark); }
.section--invert .btn--ghost:hover { border-color: var(--ws-gold); background: rgba(209,170,114,.10); }

/* Inline arrow link */
.arrow-link {
  display: inline-flex; align-items: center; gap: .5em;
  font-weight: 600; font-size: .9688rem; letter-spacing: .02em;
  color: var(--text-strong); text-decoration: none;
  padding-bottom: 2px; border-bottom: 1px solid var(--accent);
  transition: gap var(--dur) var(--ease);
}
.arrow-link:hover { gap: .85em; }
.arrow-link .icon { width: .9em; height: .9em; flex: none; }
.section--invert .arrow-link { color: var(--ws-ivory); border-bottom-color: var(--ws-gold); }

/* --------------------------------------------------------------------------
   6. HEADER / NAV
   -------------------------------------------------------------------------- */
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: rgba(247, 243, 234, .92);
  border-bottom: 1px solid var(--rule);
  backdrop-filter: saturate(1.4) blur(8px);
}
/* Header-only container width. Scoped to .site-header so ordinary sections
   and the footer keep the 1180px measure. */
.site-header .container { max-width: var(--container-header); }

.site-header__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s4); min-height: 76px;
}
.brand { display: inline-flex; align-items: center; text-decoration: none; color: inherit; }
/* Official full company logo. The emblem-only mark stands in on narrow
   screens, where the full lockup would crowd the nav toggle. Exactly one is
   in the DOM-visible state at a time; the link carries the accessible name so
   both images can be decorative. */
.brand__logo   { display: none; height: 40px; width: auto; max-width: 46vw; object-fit: contain; flex: none; }
.brand__emblem { display: block; width: 50px; height: auto; flex: none; }
@media (min-width: 560px) {
  .brand__logo   { display: block; }
  .brand__emblem { display: none; }
}
/* Desktop keeps the logo at the smaller of the two sizes at every width. The
   full lockup is 930x118, so 32px tall is ~252px wide and leaves the nav row
   enough space for the longest of the four languages without wrapping. The
   step up to 40px that used to apply above 1200px cost 63px of that budget. */
@media (min-width: 1080px) { .brand__logo { height: 32px; } }

/* Below --container-header the header row is bounded by the viewport, not by
   the container, and the full lockup plus the whole navigation no longer both
   fit. Worst case is Malay on the consulting page, where the current-page item
   is bold: 915px of navigation against a viewport minus 316px, so the lockup
   needs 1231px before it fits — and Japanese needs 1094px. The emblem, the
   same mark the header already falls back to on phones, is 50px instead of
   252px and brings the requirement down to 1029px, below the nav breakpoint.
   The switch is tied to the header container width rather than to a number
   chosen to just clear one language. A width rule, not a language rule. */
@media (min-width: 1080px) and (max-width: 1279px) {
  .brand__logo   { display: none; }
  .brand__emblem { display: block; }
}

.nav-toggle {
  display: inline-flex; align-items: center; gap: .5em;
  background: transparent; border: 1px solid var(--rule); border-radius: var(--radius);
  padding: .5em .85em; font: inherit; font-size: .875rem; font-weight: 600;
  color: var(--text-strong); cursor: pointer;
}
.nav-toggle:hover { border-color: var(--accent); }
.nav-toggle .icon { width: 1.05em; height: 1.05em; }
.nav-toggle__close { display: none; }
.nav-toggle[aria-expanded="true"] .nav-toggle__open { display: none; }
.nav-toggle[aria-expanded="true"] .nav-toggle__close { display: block; }

.site-nav__list { list-style: none; margin: 0; padding: 0; max-width: none; }
.site-nav__link {
  display: block; text-decoration: none; color: var(--text);
  font-size: .9688rem; font-weight: 500; letter-spacing: .02em;
  padding: var(--s3) 0; border-bottom: 1px solid var(--rule);
}
.site-nav__link:hover { color: var(--text-strong); }
.site-nav__link[aria-current="page"] { color: var(--text-strong); font-weight: 700; }

/* Mobile drawer */
@media (max-width: 1079px) {
  .site-nav {
    display: none;
    position: absolute; left: 0; right: 0; top: 100%;
    background: var(--ws-soft);
    border-bottom: 1px solid var(--rule);
    padding: var(--s4) var(--s5) var(--s6);
    box-shadow: 0 18px 40px -24px rgba(18,18,16,.35);
  }
  .site-nav.is-open { display: block; }
  .site-nav__list > li:last-child .site-nav__link { border-bottom: 0; }
  .site-nav__cta { margin-top: var(--s5); }
  .site-nav__cta .btn { width: 100%; justify-content: center; }
}
@media (min-width: 1080px) {
  .nav-toggle { display: none; }
  .site-nav { display: block !important; }
  /* 20px rather than 24px between navigation items. The row is nowrap, so
     when it runs out of room the flex items are squeezed instead of wrapping
     and the contact button's label breaks onto a second line. Malay needs by
     far the most room of the four languages, so the row is tuned as tightly as
     it can be without crowding: 16px between items, 16px between brand and
     nav, and no extra margin before the contact button. */
  .site-nav__list { display: flex; align-items: center; gap: 1rem; }
  .site-nav__link { padding: .35rem 0; border-bottom: 2px solid transparent; white-space: nowrap; }
  .site-nav__link:hover { border-bottom-color: var(--accent); }
  .site-nav__link[aria-current="page"] { border-bottom-color: var(--accent); }
  .site-nav__cta { margin-left: 0; }
  .site-nav__cta .btn { padding: .6em 1.15em; }
}

/* --------------------------------------------------------------------------
   6b. PRODUCT DROPDOWN
   One trigger serves both modes: a hover/focus dropdown at desktop widths and
   an accordion inside the drawer below the nav breakpoint.
   -------------------------------------------------------------------------- */
.site-nav__item--has-sub { position: relative; }

/* The trigger is a <button> but must read as a nav link. */
.site-nav__sub-toggle {
  appearance: none; -webkit-appearance: none;
  background: none; border: 0; font: inherit; cursor: pointer;
  display: inline-flex; align-items: center; gap: .45em;
  color: var(--text);
  font-size: .9688rem; font-weight: 500; letter-spacing: .02em;
  text-align: left;
}
.site-nav__sub-toggle:hover { color: var(--text-strong); }
.site-nav__sub-toggle.is-current-section { color: var(--text-strong); font-weight: 700; }

.sub-icon { display: inline-flex; flex: none; }
/* SPECIFICITY: the hide rule below is (0,1,1) because of the element selector.
   Every rule that reveals one of these icons must therefore also be at least
   (0,1,1) — a bare `.sub-icon__caret` at (0,1,0) loses and the icon stays
   invisible. Each show rule is scoped through .sub-icon for that reason. */
.sub-icon svg { width: .72em; height: .72em; display: none; }
.sub-icon .sub-icon__caret { transition: transform var(--dur) var(--ease); }
.site-nav__sub-toggle[aria-expanded="true"] .sub-icon__caret { transform: rotate(180deg); }

.subnav__list { list-style: none; margin: 0; padding: 0; max-width: none; }
.subnav__list li { margin: 0; }

.subnav__item {
  display: block; text-decoration: none; border-radius: var(--radius);
  color: var(--text);
}
.subnav__head { display: flex; align-items: baseline; gap: .6em; }
.subnav__name { font-size: .9688rem; font-weight: 600; color: var(--text-strong); }
.subnav__desc {
  display: block; margin-top: 3px;
  font-size: .8125rem; line-height: 1.5; color: var(--text-muted);
}
.subnav__tag {
  flex: none;
  font-size: .625rem; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ws-bronze-ink);
  white-space: nowrap;
}

/* ---- Desktop: floating panel ---- */
@media (min-width: 1080px) {
  /* Stretch the item to full header height so the panel can hang from the
     header's bottom edge rather than from the middle of the label. */
  .site-nav__item--has-sub { align-self: stretch; display: flex; align-items: center; }
  .site-nav__sub-toggle { padding: .35rem 0; border-bottom: 2px solid transparent; white-space: nowrap; }
  .site-nav__sub-toggle:hover,
  .site-nav__sub-toggle[aria-expanded="true"],
  .site-nav__sub-toggle.is-current-section { border-bottom-color: var(--accent); }
  .sub-icon .sub-icon__caret { display: block; }

  .subnav {
    position: absolute; top: 100%; left: -16px; z-index: 60;
    width: 352px;
    /* Transparent bridge: the panel is visually offset from the header but the
       hover area is continuous, so the pointer can travel into the menu. */
    padding-top: 10px;
    display: none;
  }
  .site-nav__item--has-sub:hover > .subnav,
  .site-nav__item--has-sub:focus-within > .subnav,
  .site-nav__sub-toggle[aria-expanded="true"] + .subnav { display: block; }

  .subnav__list {
    background: var(--ws-soft);
    border: 1px solid var(--rule);
    border-radius: 8px;
    padding: 6px;
    box-shadow: 0 16px 36px -26px rgba(18, 18, 16, .34);
  }
  .subnav__item { padding: 12px 14px; }
  .subnav__item:hover { background: var(--ws-bronze-dim); }
  .subnav__item[aria-current="page"] {
    background: var(--ws-bronze-dim);
    box-shadow: inset 2px 0 0 var(--accent);
  }
}

/* ---- Mobile / tablet: accordion inside the drawer ---- */
@media (max-width: 1079px) {
  .site-nav__sub-toggle {
    width: 100%; min-height: 44px;
    justify-content: space-between;
    padding: var(--s3) 0;
    border-bottom: 1px solid var(--rule);
  }
  .sub-icon .sub-icon__plus { display: block; }
  .site-nav__sub-toggle[aria-expanded="true"] .sub-icon .sub-icon__plus { display: none; }
  .site-nav__sub-toggle[aria-expanded="true"] .sub-icon .sub-icon__minus { display: block; }
  .sub-icon svg { width: .95em; height: .95em; }

  .subnav { display: none; }
  .site-nav__sub-toggle[aria-expanded="true"] + .subnav { display: block; }
  .subnav__list { padding: var(--s2) 0 var(--s3); }
  .subnav__item {
    min-height: 44px;
    padding: var(--s3) 0 var(--s3) var(--s4);
    border-left: 2px solid var(--rule);
  }
  .subnav__item[aria-current="page"] { border-left-color: var(--accent); }
}

/* --------------------------------------------------------------------------
   6c. LANGUAGE SWITCHER
   Reuses the product/about dropdown component wholesale — same markup, same
   JS, same keyboard behaviour. Only the sizing differs, so the switcher reads
   as a utility rather than competing with the nav.
   -------------------------------------------------------------------------- */
.site-nav__item--lang .site-nav__sub-toggle { font-size: .875rem; color: var(--text-muted); }
.site-nav__item--lang .site-nav__sub-toggle:hover { color: var(--text-strong); }
.lang-list { list-style: none; margin: 0; padding: 0; max-width: none; }
.lang-list li { margin: 0; }
.lang-list a {
  display: block; text-decoration: none; color: var(--text);
  font-size: .9375rem; border-radius: var(--radius);
}
.lang-list a[aria-current="true"] { font-weight: 700; color: var(--text-strong); }

@media (min-width: 1080px) {
  .site-nav__item--lang { margin-left: var(--s2); }
  .site-nav__item--lang .subnav { width: 190px; left: auto; right: -12px; }
  .lang-list a { padding: 9px 12px; }
  .lang-list a:hover { background: var(--ws-bronze-dim); }
  .lang-list a[aria-current="true"] { background: var(--ws-bronze-dim); box-shadow: inset 2px 0 0 var(--accent); }
}
@media (max-width: 1079px) {
  .lang-list a { min-height: 44px; display: flex; align-items: center; padding: var(--s3) 0 var(--s3) var(--s4); border-left: 2px solid var(--rule); }
  .lang-list a[aria-current="true"] { border-left-color: var(--accent); }
}

/* Untranslated-scaffold notice. Only appears on generated language pages that
   are still awaiting translation; the build removes it once real copy lands. */
.i18n-pending {
  background: var(--ws-bronze-dim);
  border-bottom: 1px solid var(--ws-bronze-vei);
}
.i18n-pending p {
  max-width: var(--container); margin: 0 auto;
  padding: var(--s3) var(--s5);
  font-size: .875rem; line-height: 1.6; color: var(--text-muted);
}

/* Per-language typography hooks. Small and additive — the design system is
   shared, only the things that genuinely differ per script are touched. */
html[lang="ja"] body { line-break: strict; word-break: normal; }
html[lang="ja"] h1, html[lang="ja"] h2, html[lang="ja"] h3 { letter-spacing: 0; }
html[lang="en"] body,
html[lang="ms"] body { letter-spacing: 0; word-break: normal; }
html[lang="en"] h1, html[lang="en"] h2,
html[lang="ms"] h1, html[lang="ms"] h2 { letter-spacing: -.015em; }

/* Each product block pairs an English strapline with a localized subtitle
   below it. On the Japanese and Malay pages that is still two languages side
   by side, which is the original device. On the English page both lines are
   English and say the same thing, so the lower one steps aside there and only
   there. Companion lines that end up word-for-word identical to the heading
   above them are removed at build time instead — see build-i18n.py. */
html[lang="en"] .product__sub-zh { display: none; }

/* No-JS fallback navigation.
   The markup lives inside <noscript>, so it exists only when scripting is
   off. Above the nav breakpoint the horizontal nav already works without
   JavaScript, so the fallback is suppressed there to avoid a duplicate menu. */
.nojs-nav {
  border-bottom: 1px solid var(--rule);
  background: var(--bg-raised);
}
.nojs-nav ul {
  list-style: none; margin: 0 auto; padding: var(--s3) var(--s5);
  max-width: var(--container);
  display: flex; flex-wrap: wrap; gap: var(--s2) var(--s5);
}
.nojs-nav li { margin: 0; }
.nojs-nav a {
  display: inline-block; padding: var(--s2) 0;
  font-size: .9688rem; font-weight: 500; letter-spacing: .02em;
  color: var(--text); text-decoration: none;
  border-bottom: 2px solid transparent;
}
.nojs-nav a:hover { color: var(--text-strong); border-bottom-color: var(--accent); }
.nojs-nav a[aria-current="page"] { color: var(--text-strong); font-weight: 700; border-bottom-color: var(--accent); }
@media (min-width: 1080px) { .nojs-nav { display: none; } }

/* --------------------------------------------------------------------------
   7. HERO
   -------------------------------------------------------------------------- */
.hero { position: relative; padding-block: clamp(var(--s8), 8vw, var(--s10)); overflow: hidden; }
.hero::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(760px 380px at 88% -8%, var(--ws-bronze-dim), transparent 62%),
    radial-gradient(520px 300px at 4% 104%, rgba(209,170,114,.12), transparent 66%);
}
.hero > * { position: relative; z-index: 1; }
.hero__title { max-width: 20ch; }
.hero__lede { margin-top: var(--s5); font-size: clamp(1.0625rem, 1rem + .45vw, 1.3125rem); }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--s4); margin-top: var(--s7); }

.hero--page { padding-block: clamp(var(--s7), 6vw, var(--s9)); border-bottom: 1px solid var(--rule); }
.hero--page .hero__title { max-width: 24ch; }

/* Hero stat strip */
.hero__meta {
  display: flex; flex-wrap: wrap; gap: var(--s6);
  margin-top: var(--s8); padding-top: var(--s5);
  border-top: 1px solid var(--rule);
}
.hero__meta div { min-width: 8rem; }
.hero__meta dt {
  font-size: .6875rem; font-weight: 600; letter-spacing: .18em;
  text-transform: uppercase; color: var(--text-muted); margin-bottom: .35rem;
}
.hero__meta dd { margin: 0; font-size: 1.0625rem; font-weight: 600; color: var(--text-strong); }

/* --------------------------------------------------------------------------
   8. CARDS / PILLARS  (flat + hairline, never "card-heavy dashboard")
   -------------------------------------------------------------------------- */
.pillar { padding-top: var(--s5); border-top: 2px solid var(--accent); }
.pillar h3 { margin-bottom: var(--s3); }
.pillar p { color: var(--text-muted); margin-bottom: 0; font-size: 1rem; }
.pillar__icon { width: 26px; height: 26px; color: var(--accent); margin-bottom: var(--s4); }

.panel {
  background: var(--bg-raised);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: clamp(var(--s5), 3vw, var(--s7));
}
.section--invert .panel { background: #191917; border-color: var(--ws-line-dark); }

/* Numbered editorial feature list */
.feature-list { list-style: none; margin: 0; padding: 0; max-width: none; }
.feature-list > li {
  display: grid; grid-template-columns: auto 1fr; gap: var(--s5);
  padding-block: var(--s6);
  border-top: 1px solid var(--rule);
  margin: 0;
}
.feature-list > li:last-child { border-bottom: 1px solid var(--rule); }
.feature-list__num {
  font-family: var(--font-mono);
  font-size: .8125rem; font-weight: 600; letter-spacing: .1em;
  color: var(--accent); padding-top: .45em; min-width: 2.5rem;
}
.feature-list h3 { margin-bottom: var(--s2); }
.feature-list p { color: var(--text-muted); margin-bottom: 0; }
.section--invert .feature-list > li { border-color: var(--ws-line-dark); }
.section--invert .feature-list__num { color: var(--ws-gold); }
.section--invert .feature-list p { color: #B8B3A9; }

/* Step flow */
.steps { list-style: none; margin: 0; padding: 0; counter-reset: step; max-width: none; display: grid; gap: var(--s5); }
@media (min-width: 940px) { .steps { grid-template-columns: repeat(4, 1fr); gap: var(--s5); } }
.steps > li { counter-increment: step; padding-top: var(--s4); border-top: 1px solid var(--rule); margin: 0; }
.steps > li::before {
  content: counter(step, decimal-leading-zero);
  display: block; font-family: var(--font-mono); font-size: .75rem;
  letter-spacing: .12em; color: var(--accent); margin-bottom: var(--s3);
}
.steps h3 { font-size: 1.0625rem; margin-bottom: var(--s2); }
.steps p { font-size: .9688rem; color: var(--text-muted); margin: 0; }

/* --------------------------------------------------------------------------
   9. PRODUCT SHOWCASE
   -------------------------------------------------------------------------- */
.showcase__figure {
  border: 1px solid var(--rule); border-radius: var(--radius);
  background: var(--bg-raised); padding: var(--s4);
  box-shadow: 0 24px 48px -32px rgba(18,18,16,.28);
}
.showcase__figure img { border-radius: 1px; }
.section--invert .showcase__figure { background: #191917; border-color: var(--ws-line-dark); }

/* Status badge — used for COMING SOON */
.badge {
  display: inline-flex; align-items: center; gap: .55em;
  padding: .4em .85em;
  font-size: .6875rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  border-radius: var(--radius);
  border: 1px solid var(--ws-bronze-vei);
  background: var(--ws-bronze-dim);
  color: var(--text-strong);
}
.badge::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent); flex: none;
}
.section--invert .badge { color: var(--ws-gold); border-color: rgba(209,170,114,.4); background: rgba(209,170,114,.12); }

/* Notice block (honest status statements) */
.notice {
  border-left: 2px solid var(--accent);
  padding: var(--s2) 0 var(--s2) var(--s5);
  color: var(--text-muted);
  max-width: var(--measure);
}
.notice p:last-child { margin-bottom: 0; }
.section--invert .notice { border-left-color: var(--ws-gold); color: #B8B3A9; }

/* --------------------------------------------------------------------------
   10. DEFINITION / CONTACT LIST
   -------------------------------------------------------------------------- */
.contact-list { margin: 0; max-width: none; }
.contact-list > div { padding-block: var(--s5); border-top: 1px solid var(--rule); }
.contact-list > div:last-child { border-bottom: 1px solid var(--rule); }
.contact-list dt {
  font-size: .6875rem; font-weight: 600; letter-spacing: .18em;
  text-transform: uppercase; color: var(--text-muted); margin-bottom: var(--s2);
}
.contact-list dd { margin: 0; font-size: 1.125rem; font-weight: 600; }
.contact-list dd a { color: var(--text-strong); text-decoration: none; border-bottom: 1px solid var(--accent); padding-bottom: 1px; }
.contact-list dd a:hover { color: var(--accent); }
.contact-list__note { display: block; margin-top: var(--s2); font-size: .9375rem; font-weight: 400; color: var(--text-muted); }

/* Profile (leadership) */
.profile__role {
  font-size: .8125rem; font-weight: 600; letter-spacing: .14em;
  text-transform: uppercase; color: var(--text-muted); margin-bottom: var(--s2);
}
.profile__name { font-size: clamp(1.35rem, 1.2rem + .6vw, 1.7rem); margin-bottom: var(--s4); }
.cred-list { list-style: none; margin: 0 0 var(--s5); padding: 0; }
.cred-list li { position: relative; padding-left: 1.15rem; color: var(--text-muted); margin-bottom: var(--s2); }
.cred-list li::before {
  content: ""; position: absolute; left: 0; top: .72em;
  width: 5px; height: 5px; background: var(--accent); border-radius: 50%;
}

/* --------------------------------------------------------------------------
   11. FOOTER
   -------------------------------------------------------------------------- */
.site-footer { background: var(--ws-charcoal); color: #A9A49B; padding-block: var(--s8) var(--s6); }
.site-footer a { color: #DFDAD0; text-decoration: none; }
.site-footer a:hover { color: var(--ws-gold); }
.site-footer__top { display: grid; gap: var(--s7); }
@media (min-width: 800px) { .site-footer__top { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: var(--s8); } }
.site-footer__brand { display: block; margin-bottom: var(--s5); }
/* Width-driven, height auto. Sizing by height plus max-width lets the clamp
   squash the width while the fixed height stays put, distorting the logo on
   narrow screens. */
.site-footer__brand img { width: 320px; max-width: 100%; height: auto; }
.site-footer__blurb { font-size: .9375rem; color: #A9A49B; max-width: 42ch; margin: 0; }
.footer-nav { display: grid; gap: var(--s6); grid-template-columns: repeat(2, minmax(0,1fr)); }
@media (min-width: 560px) { .footer-nav { grid-template-columns: repeat(3, minmax(0,1fr)); } }
.footer-nav h2 {
  font-size: .6875rem; font-weight: 600; letter-spacing: .18em; text-transform: uppercase;
  color: var(--ws-warm-gray); margin-bottom: var(--s4);
}
.footer-nav ul { list-style: none; margin: 0; padding: 0; }
.footer-nav li { margin-bottom: var(--s3); }
.footer-nav a { font-size: .9375rem; }
.footer-nav__tag {
  display: block; margin-top: 2px;
  font-size: .625rem; font-weight: 600; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ws-gold);
}
.site-footer__bottom {
  margin-top: var(--s8); padding-top: var(--s5); border-top: 1px solid var(--ws-line-dark);
  display: flex; flex-wrap: wrap; gap: var(--s4); justify-content: space-between;
  font-size: .875rem; color: var(--ws-warm-gray);
}
.site-footer__bottom p { margin: 0; max-width: none; }

/* --------------------------------------------------------------------------
   12. ERROR PAGE
   -------------------------------------------------------------------------- */
.error-page { display: flex; align-items: center; min-height: 62vh; padding-block: var(--s9); }
.error-page__code {
  font-family: var(--font-mono); font-size: .8125rem; font-weight: 600;
  letter-spacing: .22em; color: var(--accent); margin-bottom: var(--s4); display: block;
}
.error-page__actions { display: flex; flex-wrap: wrap; gap: var(--s4); margin-top: var(--s7); }

/* --------------------------------------------------------------------------
   13. MOTION / PRINT
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
  .btn:hover { transform: none; }
}
@media print {
  .site-header, .site-footer, .nav-toggle, .hero::after { display: none !important; }
  body { background: #fff; color: #000; font-size: 11pt; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; color: #555; }
}

/* ==========================================================================
   HOMEPAGE — product sections, consulting, why
   Both products share one layout language on purpose: same padding, same
   eyebrow, same heading hierarchy, same screenshot treatment, same CTA row.
   Consistency reads as one product system; flipping the columns for variety
   would read as two.
   ========================================================================== */

/* Product section grid: text ~45%, screenshot ~55% */
.grid--product { gap: var(--s6); }
@media (min-width: 940px) {
  .grid--product {
    grid-template-columns: minmax(0, 45fr) minmax(0, 55fr);
    gap: var(--s8);
    align-items: center;
  }
}

.product__eyebrow { display: block; }
.product__title { margin-bottom: var(--s2); }
.product__sub-en {
  margin: 0 0 var(--s1);
  font-size: clamp(1rem, .95rem + .3vw, 1.125rem);
  font-weight: 500;
  color: var(--text-strong);
  letter-spacing: .01em;
}
.product__sub-zh { margin: 0 0 var(--s5); color: var(--text-muted); font-size: 1rem; }
.product__body { margin-bottom: var(--s5); }
.product__actions { display: flex; flex-wrap: wrap; gap: var(--s4); margin-top: var(--s6); }

/* Capabilities — a quiet inline list, deliberately not badges */
.cap-list {
  list-style: none; margin: 0 0 var(--s2); padding: 0; max-width: none;
  display: flex; flex-wrap: wrap; align-items: center;
  gap: .35rem 0;
  font-size: .8125rem; font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: var(--text-muted);
}
.cap-list li { margin: 0; display: inline-flex; align-items: center; }
.cap-list li + li::before {
  content: ""; width: 1px; height: .95em; margin: 0 .85rem;
  background: var(--ws-bronze-vei);
}

/* Screenshot: no perspective, no glow, no gold frame, no fake chrome. */
.product__figure {
  margin: 0;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--ws-soft);
  padding: 10px;
  box-shadow: 0 22px 44px -34px rgba(18, 18, 16, .30);
}
.product__figure img {
  display: block; width: 100%; height: auto;
  object-fit: contain; border-radius: 1px;
}
.section--invert .product__figure { background: #191917; border-color: var(--ws-line-dark); }

/* ---------- Consulting: editorial rows, not cards ---------- */
/* The heading is short and the service rows carry the content, so the wide
   column goes to the list — the opposite of .grid--aside's default split. */
@media (min-width: 940px) {
  .grid--consult { grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); gap: var(--s8); align-items: start; }
}

.consulting-list { list-style: none; margin: 0; padding: 0; max-width: none; }
.consulting-list > li {
  display: grid; grid-template-columns: auto 1fr; gap: var(--s4) var(--s5);
  padding-block: var(--s6);
  border-top: 1px solid var(--rule);
  margin: 0;
}
.consulting-list > li:last-child { border-bottom: 1px solid var(--rule); }
.consulting-list__num {
  font-family: var(--font-mono);
  font-size: .8125rem; font-weight: 600; letter-spacing: .1em;
  color: var(--accent); padding-top: .35em; min-width: 2.5rem;
}
.consulting-list h3 { margin-bottom: var(--s1); }
.consulting-list__en {
  display: block; margin-bottom: var(--s3);
  font-size: .8125rem; font-weight: 600; letter-spacing: .09em;
  text-transform: uppercase; color: var(--text-muted);
}
.consulting-list p { color: var(--text-muted); margin-bottom: 0; }

/* ---------- Customer logo grid ----------
   Flat, evenly spaced, no cards and no colour treatment. Logos keep their own
   colours: recolouring a customer's mark to fit our palette is not ours to do.
   Unused until real assets and publication approval exist. */
.logo-grid {
  list-style: none; margin: var(--s6) 0 0; padding: 0; max-width: none;
  display: grid; gap: var(--s6);
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: center;
}
@media (min-width: 640px)  { .logo-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1040px) { .logo-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.logo-grid__item {
  margin: 0; display: flex; align-items: center; justify-content: center;
  min-height: 84px; padding: var(--s4);
  border: 1px solid var(--rule); border-radius: var(--radius);
  background: var(--ws-soft);
}
.logo-grid__item img { max-width: 100%; max-height: 52px; width: auto; height: auto; object-fit: contain; }

/* ---------- Why W.S. — columns divided by hairlines, no cards ---------- */
.why-grid { display: grid; gap: var(--s6); margin-top: var(--s7); }
@media (min-width: 640px)  { .why-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s6) var(--s7); } }
@media (min-width: 1040px) { .why-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s6); } }
.why-item { position: relative; padding-top: var(--s4); border-top: 1px solid var(--rule); }
.why-item__num {
  font-family: var(--font-mono); font-size: .75rem; letter-spacing: .12em;
  color: var(--accent); display: block; margin-bottom: var(--s3);
}
.why-item__icon { width: 20px; height: 20px; color: var(--accent); margin-bottom: var(--s3); }
.why-item h3 { font-size: 1.0625rem; margin-bottom: var(--s1); }
.why-item__en {
  display: block; margin-bottom: var(--s3);
  font-size: .75rem; font-weight: 600; letter-spacing: .09em;
  text-transform: uppercase; color: var(--text-muted);
}
.why-item p { font-size: .9688rem; color: var(--text-muted); margin: 0; }
@media (min-width: 1040px) {
  /* thin vertical dividers between columns, drawn on the items themselves */
  .why-item + .why-item::after {
    content: ""; position: absolute; left: calc(var(--s6) / -2); top: 0; bottom: 0;
    width: 1px; background: var(--rule);
  }
}
