/* ============================================================
   VeriPhys 合信智感 — site system
   Light warm HUD · cream paper + warm gold / terracotta
   ============================================================ */
/* ============================================================
   Self-hosted webfonts — no external requests, so typography no
   longer depends on Google Fonts being reachable from mainland CN.

   The CJK families are subset to the glyphs this site actually uses
   (757 hanzi + full ASCII + common punctuation = 920 chars), which is
   what makes self-hosting viable at all: unsubsetted Noto Sans SC is
   17 MB and Noto Serif SC is 24 MB.

   ⚠️ If you edit body copy and introduce a hanzi outside that set, it
   will silently fall back to the next family in the stack. Re-run
   ./subset-fonts.sh after copy changes to regenerate.

   Barlow Condensed · Noto Sans SC · Noto Serif SC · JetBrains Mono
   are SIL Open Font License 1.1 — licence texts in assets/fonts/OFL-*.txt
   ============================================================ */
@font-face{font-family:'Barlow Condensed';src:url('fonts/barlow-condensed-300.woff2') format('woff2');font-weight:300;font-style:normal;font-display:swap}
@font-face{font-family:'Barlow Condensed';src:url('fonts/barlow-condensed-400.woff2') format('woff2');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'Barlow Condensed';src:url('fonts/barlow-condensed-500.woff2') format('woff2');font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:'Barlow Condensed';src:url('fonts/barlow-condensed-600.woff2') format('woff2');font-weight:600;font-style:normal;font-display:swap}
@font-face{font-family:'Barlow Condensed';src:url('fonts/barlow-condensed-700.woff2') format('woff2');font-weight:700;font-style:normal;font-display:swap}
@font-face{font-family:'Noto Sans SC';src:url('fonts/noto-sans-sc-var.woff2') format('woff2');font-weight:100 900;font-style:normal;font-display:swap}
@font-face{font-family:'Noto Serif SC';src:url('fonts/noto-serif-sc-var.woff2') format('woff2');font-weight:200 900;font-style:normal;font-display:swap}
@font-face{font-family:'JetBrains Mono';src:url('fonts/jetbrains-mono-var.woff2') format('woff2');font-weight:100 800;font-style:normal;font-display:swap}

:root{
  --bg:#F4EEE3;
  --bg-2:#ECE3D3;
  --paper:#FAF6EE;
  --ink:#2A2118;
  --ink-2:rgba(42,33,24,.70);
  --ink-3:rgba(42,33,24,.46);
  --ink-4:rgba(42,33,24,.22);
  --line:rgba(42,33,24,.12);
  --line-2:rgba(42,33,24,.22);
  --gold:#B0822E;
  --terra:#B65A36;
  --sage:#6F8F5E;
  --accent:var(--gold);
  --accent-2:var(--terra);
  --accent-soft:color-mix(in oklab, var(--accent) 12%, transparent);
  --dark:#221A13;
  --dark-2:#2C2219;
  --f-display:'Barlow Condensed', 'Noto Sans SC', sans-serif;
  --f-body:'Noto Sans SC', system-ui, sans-serif;
  --f-serif:'Noto Serif SC', serif;
  --f-mono:'JetBrains Mono', ui-monospace, monospace;
  --pad:clamp(20px, 4vw, 64px);
  --maxw:1440px;
  /* Height of the sticky .site-head. In-page sticky elements (directions sub-nav)
     and every scroll-margin-top anchor offset must derive from this, never from a
     hardcoded 72/104 — the real value flips when the status bar is hidden. */
  --head-h:104px;
}
html[data-palette="terra"]{ --accent:var(--terra); --accent-2:var(--gold); }
html[data-hud="1"]{ --head-h:72px }   /* .statusbar is display:none at HUD 1 */

*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  background:var(--bg);
  color:var(--ink);
  font-family:var(--f-body);
  font-size:16px;
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
a{color:inherit;text-decoration:none}
img{max-width:100%;display:block}
p{text-wrap:pretty;margin:0}
h1,h2,h3,h4{margin:0;font-weight:500;text-wrap:balance}

/* ---------- i18n ---------- */
html[data-lang="en"] .zh{display:none !important}
html[data-lang="zh"] .en{display:none !important}

/* ---------- background grid ---------- */
body::before{
  content:"";position:fixed;inset:0;pointer-events:none;z-index:0;
  background-image:
    linear-gradient(var(--line) 1px, transparent 1px),
    linear-gradient(90deg, var(--line) 1px, transparent 1px);
  background-size:96px 96px;
  opacity:.35;
  mask-image:radial-gradient(ellipse 80% 70% at 50% 30%, #000 20%, transparent 85%);
}
html[data-hud="1"] body::before, html[data-hud="2"] body::before{opacity:0}
main, header, footer{position:relative;z-index:1}

/* ---------- mono label ---------- */
.mono{font-family:var(--f-mono);font-size:11px;letter-spacing:.22em;text-transform:uppercase;color:var(--ink-3);font-weight:400}
.mono.acc{color:var(--accent)}
.dot{display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--sage);box-shadow:0 0 0 3px color-mix(in oklab, var(--sage) 20%, transparent);vertical-align:middle;margin-right:10px;animation:blink 2.4s infinite}
.sq{display:inline-block;width:6px;height:6px;background:var(--accent);vertical-align:middle;margin-right:12px}
@keyframes blink{50%{opacity:.35}}

/* ---------- status bar ---------- */
.statusbar{
  height:32px;display:flex;align-items:center;justify-content:space-between;
  padding:0 var(--pad);border-bottom:1px solid var(--line);
  background:color-mix(in oklab, var(--bg) 80%, transparent);
  font-family:var(--f-mono);font-size:10px;letter-spacing:.22em;text-transform:uppercase;color:var(--ink-3);
}
.statusbar .rec{color:var(--terra)}
.statusbar .clock{font-variant-numeric:tabular-nums}
html[data-hud="1"] .statusbar{display:none}
@media (max-width:760px){.statusbar .r{display:none}}

/* ---------- nav ---------- */
.site-head{position:sticky;top:0;z-index:50}
.nav{
  display:flex;align-items:center;gap:40px;height:72px;padding:0 var(--pad);
  background:color-mix(in oklab, var(--bg) 88%, transparent);
  backdrop-filter:blur(14px) saturate(1.2);
  border-bottom:1px solid var(--line);
}
.brand{display:flex;align-items:center;gap:14px}
.brand .word{font-family:var(--f-display);font-weight:600;font-size:21px;letter-spacing:.24em;line-height:1}
.brand .sub{font-family:var(--f-mono);font-size:9px;letter-spacing:.3em;color:var(--ink-3);margin-top:5px;white-space:nowrap}
.nav-links{display:flex;gap:6px;margin-left:auto}
.nav-links a{
  position:relative;padding:10px 14px;font-size:14px;color:var(--ink-2);transition:color .2s;
}
.nav-links a .n{font-family:var(--f-mono);font-size:9px;letter-spacing:.1em;color:var(--ink-3);margin-right:6px}
.nav-links a:hover{color:var(--ink)}
.nav-links a.on{color:var(--ink)}
.nav-links a.on::after{content:"";position:absolute;left:14px;right:14px;bottom:2px;height:1px;background:var(--accent)}
.lang{display:flex;border:1px solid var(--line-2);font-family:var(--f-mono);font-size:11px;letter-spacing:.1em}
.lang button{all:unset;cursor:pointer;padding:6px 10px;color:var(--ink-3)}
.lang button.on{background:var(--ink);color:var(--paper)}
.btn{
  display:inline-flex;align-items:center;gap:12px;cursor:pointer;
  padding:14px 22px;border:1px solid var(--ink);background:var(--ink);color:var(--paper);
  font-family:var(--f-mono);font-size:12px;letter-spacing:.18em;text-transform:uppercase;
  transition:background .25s, color .25s, border-color .25s;
}
.btn:hover{background:var(--accent);border-color:var(--accent)}
.btn.ghost{background:transparent;color:var(--ink)}
.btn.ghost:hover{background:var(--ink);color:var(--paper);border-color:var(--ink)}
.btn .arr{transition:transform .25s}
.btn:hover .arr{transform:translateX(4px)}
.nav .btn{padding:10px 16px;font-size:11px}
.burger{display:none}
@media (max-width:1080px){
  .nav-links{display:none}
  .nav .btn{display:none}
  .burger{display:block;margin-left:auto;all:unset;cursor:pointer;font-family:var(--f-mono);font-size:11px;letter-spacing:.2em;border:1px solid var(--line-2);padding:8px 12px}
  .nav-open .nav-links{display:flex;position:absolute;top:72px;left:0;right:0;flex-direction:column;background:var(--paper);border-bottom:1px solid var(--line);padding:12px var(--pad)}
}

/* ---------- layout ---------- */
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 var(--pad)}
section{position:relative}
.sec{padding:clamp(80px,11vw,160px) 0}
.sec-head{display:grid;grid-template-columns:minmax(200px,1fr) 3fr;gap:40px;margin-bottom:72px;align-items:end}
.sec-head .idx{display:flex;flex-direction:column;gap:10px}
.sec-head .idx .num{font-family:var(--f-display);font-size:15px;letter-spacing:.3em;color:var(--accent)}
.kicker{font-family:var(--f-display);font-weight:500;font-size:clamp(40px,5.2vw,84px);line-height:.95;letter-spacing:.005em;text-transform:uppercase}
.kicker em{font-style:normal;color:var(--accent)}
.lede{font-size:clamp(18px,1.6vw,22px);line-height:1.6;color:var(--ink-2);max-width:760px;margin-top:22px}
.lede b{color:var(--ink);font-weight:500}
@media (max-width:860px){.sec-head{grid-template-columns:1fr;gap:18px}}

.rule{height:1px;background:linear-gradient(90deg, transparent, var(--line-2) 15%, var(--line-2) 85%, transparent)}

/* ---------- HUD frame ---------- */
.hud{position:relative}
.hud > .c{position:absolute;width:18px;height:18px;border:0 solid var(--ink-4);pointer-events:none}
.hud > .c.tl{top:-1px;left:-1px;border-top-width:1px;border-left-width:1px}
.hud > .c.tr{top:-1px;right:-1px;border-top-width:1px;border-right-width:1px}
.hud > .c.bl{bottom:-1px;left:-1px;border-bottom-width:1px;border-left-width:1px}
.hud > .c.br{bottom:-1px;right:-1px;border-bottom-width:1px;border-right-width:1px}
.hud.strong > .c{border-color:var(--ink);width:22px;height:22px}
html[data-hud="1"] .hud > .c{display:none}
.hud-meta{font-family:var(--f-mono);font-size:10px;letter-spacing:.24em;text-transform:uppercase;color:var(--ink-3)}
html[data-hud="1"] .hud-meta, html[data-hud="2"] .hud-meta.x{display:none}
html[data-hud="5"] .hud-meta{color:var(--ink-2)}
html[data-hud="5"] body::before{opacity:.6}

/* ---------- panels ---------- */
.panel{background:var(--paper);border:1px solid var(--line);padding:32px}
.panel.flat{background:transparent}

/* ---------- placeholder imagery ---------- */
.ph{
  position:relative;overflow:hidden;background:var(--bg-2);
  background-image:repeating-linear-gradient(135deg, transparent 0 10px, rgba(42,33,24,.045) 10px 11px);
  display:flex;align-items:flex-end;justify-content:flex-start;
}
.ph span{font-family:var(--f-mono);font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-3);padding:14px 16px}
.ph img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}

/* ---------- metric ---------- */
.metric .v{font-family:var(--f-display);font-weight:400;font-size:clamp(48px,5vw,84px);line-height:1;letter-spacing:-.005em;font-variant-numeric:tabular-nums}
.metric .v small{font-size:.38em;letter-spacing:.08em;color:var(--ink-3);margin-left:6px}
.metric .l{margin-top:14px;font-size:14px;color:var(--ink-2)}

/* ---------- tags ---------- */
.tag{display:inline-block;font-family:var(--f-mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;padding:4px 8px;border:1px solid var(--line-2);color:var(--ink-2)}
.tag.acc{border-color:color-mix(in oklab, var(--accent) 55%, transparent);color:var(--accent);background:var(--accent-soft)}

/* ---------- dark band ---------- */
.band-dark{background:var(--dark);color:#F2EADD;--ink:#F2EADD;--ink-2:rgba(242,234,221,.72);--ink-3:rgba(242,234,221,.46);--ink-4:rgba(242,234,221,.25);--line:rgba(242,234,221,.10);--line-2:rgba(242,234,221,.2);--paper:#2A2018;--bg-2:#2C2219}
.band-dark::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(ellipse 70% 60% at 70% 30%, color-mix(in oklab, var(--accent) 22%, transparent), transparent 70%);opacity:.6}
.band-dark > *{position:relative}
html[data-band="light"] .band-dark{background:var(--bg-2);color:var(--ink);--ink:#2A2118;--ink-2:rgba(42,33,24,.70);--ink-3:rgba(42,33,24,.46);--ink-4:rgba(42,33,24,.22);--line:rgba(42,33,24,.12);--line-2:rgba(42,33,24,.22);--paper:#FAF6EE;--bg-2:#E4D9C6}

/* ---------- page hero (sub pages) ---------- */
.phero{padding:clamp(80px,10vw,140px) 0 clamp(60px,7vw,100px);border-bottom:1px solid var(--line)}
.phero .crumbs{display:flex;gap:14px;align-items:center;margin-bottom:40px}
.phero h1{font-family:var(--f-display);font-weight:500;font-size:clamp(64px,9vw,152px);line-height:.9;text-transform:uppercase;letter-spacing:.005em}
.phero h1 .cn{display:block;font-family:var(--f-body);font-weight:700;font-size:.38em;letter-spacing:.04em;margin-top:.35em;text-transform:none}
.phero .grid{display:grid;grid-template-columns:1.4fr 1fr;gap:60px;align-items:end}
@media (max-width:900px){.phero .grid{grid-template-columns:1fr}}

/* ---------- reveal ---------- */
.rv{opacity:0;transform:translateY(24px);transition:opacity .9s cubic-bezier(.2,.7,.2,1), transform .9s cubic-bezier(.2,.7,.2,1)}
.rv.in{opacity:1;transform:none}
.rv.d1{transition-delay:.08s}.rv.d2{transition-delay:.16s}.rv.d3{transition-delay:.24s}.rv.d4{transition-delay:.32s}.rv.d5{transition-delay:.4s}

/* ---------- CTA ---------- */
.cta{padding:clamp(90px,12vw,170px) 0;text-align:left;border-top:1px solid var(--line)}
.cta h2{font-family:var(--f-serif);font-weight:500;font-size:clamp(34px,4.4vw,68px);line-height:1.25;max-width:1100px}
.cta h2 .en{font-family:var(--f-display);text-transform:uppercase;font-size:1.15em;line-height:1}
.cta .row{display:flex;gap:16px;margin-top:48px;flex-wrap:wrap}

/* ---------- footer ---------- */
.foot{border-top:1px solid var(--line);padding:64px 0 32px;background:var(--bg-2)}
.foot .cols{display:grid;grid-template-columns:1.6fr 1fr 1fr 1.4fr;gap:40px}
.foot h5{margin:0 0 16px;font-family:var(--f-mono);font-size:10px;font-weight:400;letter-spacing:.24em;text-transform:uppercase;color:var(--ink-3)}
.foot ul{list-style:none;margin:0;padding:0;display:grid;gap:10px;font-size:14px;color:var(--ink-2)}
.foot ul a:hover{color:var(--accent)}
.foot .bottom{display:flex;justify-content:space-between;gap:20px;margin-top:64px;padding-top:24px;border-top:1px solid var(--line);flex-wrap:wrap}
/* ICP filing number — required on every page; keeps a normal CJK rhythm instead
   of the .mono uppercase/.22em treatment, and links to the MIIT registry. */
.foot .icp{letter-spacing:.04em;text-transform:none;transition:color .2s}
.foot .icp:hover{color:var(--accent)}
@media (max-width:900px){.foot .cols{grid-template-columns:1fr 1fr}}
.foot .cols > *{min-width:0}
@media (max-width:600px){
  .foot .cols{grid-template-columns:1fr}
  .foot .bottom{flex-direction:column;align-items:flex-start;gap:10px}
  .foot .bottom > *{width:100%}
}
@media (max-width:760px){
  .nav{gap:12px}
  .brand .sub{display:none}
  .brand .word{font-size:17px;letter-spacing:.16em}
  .lang{margin-left:auto}
  /* touch targets: these were shrinking on small screens, the wrong way round.
     Aim for ~44px tall hit areas (Apple HIG / Material). */
  .lang button{padding:11px 13px}
  .burger{margin-left:0 !important;padding:11px 14px}
  /* footer links are inline <a>, so their box was only as tall as the line box.
     the negative margin keeps the labels flush left while widening the hit area
     enough for two-character CJK labels such as 首页. */
  .foot ul{gap:2px}
  .foot ul a{display:inline-block;padding:9px 6px;margin-left:-6px}
  .foot .icp,
  dd a{display:inline-block;padding:9px 0}
  .foot .bottom{margin-top:44px;gap:12px}
  /* trim the desktop section rhythm on phones */
  .sec{padding:64px 0}
}
html,body{max-width:100%;overflow-x:clip}

/* ---------- signal canvas ---------- */
canvas.sig{display:block;width:100%;height:48px}
canvas{display:block}
.hero .r canvas, .modal .scope .viz canvas, .coord canvas{position:absolute;inset:0;width:100%;height:100%}

/* ---------- tweaks panel ---------- */
#tweaks{position:fixed;right:20px;bottom:20px;z-index:1000;width:280px;background:var(--paper);border:1px solid var(--ink);box-shadow:0 20px 50px rgba(42,33,24,.18);font-family:var(--f-mono);font-size:11px;color:#2A2118;display:none}
#tweaks.show{display:block}
#tweaks .th{display:flex;justify-content:space-between;align-items:center;padding:12px 14px;border-bottom:1px solid rgba(42,33,24,.15);letter-spacing:.2em;text-transform:uppercase;cursor:move}
#tweaks .th button{all:unset;cursor:pointer;padding:0 4px;font-size:14px}
#tweaks .tb{padding:14px;display:grid;gap:16px}
#tweaks label{display:block;letter-spacing:.16em;text-transform:uppercase;color:rgba(42,33,24,.55);margin-bottom:8px;font-size:10px}
#tweaks .seg{display:flex;border:1px solid rgba(42,33,24,.25)}
#tweaks .seg button{all:unset;flex:1;text-align:center;padding:8px 4px;cursor:pointer;font-size:11px}
#tweaks .seg button.on{background:#2A2118;color:#FAF6EE}
#tweaks .sw{display:flex;gap:8px}
#tweaks .sw button{all:unset;cursor:pointer;flex:1;height:44px;border:1px solid rgba(42,33,24,.2);display:flex;overflow:hidden}
#tweaks .sw button i{flex:1}
#tweaks .sw button.on{outline:2px solid #2A2118;outline-offset:2px}
#tweaks input[type=range]{width:100%;accent-color:#2A2118}
