/*
 * wiki.css — the editorial pages: the /agents landing, /docs and /research, and
 * on trade-agents.com the product's shell around every page there (masthead,
 * Markets bar on the dashboards, paper plane, footer, one column; see
 * `_ta_shell` in base.html).
 *
 * Hand-written rather than Tailwind utilities for the reason CLAUDE.md gives for
 * the DCA peer panel: css/tailwind.css is *compiled*, so a class that only these
 * pages use can be missing from the bundle, and a missing utility fails silently.
 * Everything here is one file the pages link, with nothing to rebuild.
 *
 * Tokens are --w-*, light first with .dark overriding, matching the --t-* set in
 * base.html (and falling back to a readable page if the class is ever dropped).
 * Light mode uses a warm paper plane rather than the dashboards' slate-50: these
 * are reading pages, and the grid is drawn on the paper. Dark mode keeps the
 * site's own slate-950 so the sticky header does not change colour between a
 * dashboard and a doc.
 *
 * Contrast was checked, not eyeballed: --w-muted is 5.5:1 on the light paper and
 * 7:1 on dark, and every accent ink clears AA on the surface it sits on. The one
 * deliberately faint colour is --w-grid, which is decoration.
 */

:root {
  --w-paper:       #f6f6f1;
  --w-grid:        rgba(15, 23, 42, .045);
  --w-ink:         #13161b;
  --w-body:        #3d4450;
  --w-muted:       #5c6470;
  --w-line:        #e1e2da;
  --w-line-strong: #c9cbc1;
  --w-card:        #ffffff;
  --w-well:        #efefe8;
  --w-accent:      #4338ca;
  --w-accent-line: #c7d2fe;
  --w-accent-soft: rgba(79, 70, 229, .075);
  --w-num:         #c2410c;
  --w-good:        #047857;
  --w-bad:         #b91c1c;
  --w-warn:        #a16207;
  --w-term:        #0e1216;
  --w-term-line:   #242a31;
  --w-shadow:      0 1px 2px rgba(16, 24, 40, .04), 0 18px 40px -22px rgba(16, 24, 40, .22);

  /* Display: Fraunces when the (non-blocking) web font arrives, otherwise the
     best serif each platform already has. The Han fallbacks are named before
     the generic `serif` because that resolves to SimSun on Windows, which is
     unreadable bold at display sizes; YaHei is the better failure there. */
  --w-serif: 'Fraunces', 'Iowan Old Style', 'Palatino Linotype', Palatino, Georgia,
             'Songti SC', 'Noto Serif SC', 'Source Han Serif SC', 'PingFang SC',
             'Microsoft YaHei', serif;
  /* Reading serif for leads and figures. Georgia's old-style numerals are part
     of the look, so it leads here even where Fraunces has loaded. */
  --w-read:  Georgia, 'Iowan Old Style', 'Palatino Linotype', 'Songti SC',
             'Noto Serif SC', 'PingFang SC', 'Microsoft YaHei', serif;
  --w-mono:  'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* The masthead's height, border included, and the Markets bar's under it
     on a dashboard (0 elsewhere). Whatever sticks beneath the header reads
     their sum, --w-head-h: the docs sidebar here, the run page's jump bar in
     agents.html, the dashboards' section bars in their own templates. */
  --w-top-h: 69px;
  --w-sub-h: 0px;
}

.dark {
  --w-paper:       #020617;
  --w-grid:        rgba(148, 163, 184, .06);
  --w-ink:         #f1f5f9;
  --w-body:        #cbd5e1;
  --w-muted:       #94a3b8;
  --w-line:        #1e293b;
  --w-line-strong: #334155;
  --w-card:        #0b1222;
  --w-well:        #0a101d;
  --w-accent:      #a5b4fc;
  --w-accent-line: #3730a3;
  --w-accent-soft: rgba(99, 102, 241, .13);
  --w-num:         #fb923c;
  --w-good:        #34d399;
  --w-bad:         #f87171;
  --w-warn:        #facc15;
  --w-term:        #03060d;
  --w-term-line:   #1f2937;
  --w-shadow:      0 1px 2px rgba(0, 0, 0, .35), 0 22px 48px -24px rgba(0, 0, 0, .7);
}

/* ── The page plane ──────────────────────────────────────────────────────────
   On <body>, not a wrapper, so the grid runs edge to edge under a centred
   column without a 100vw trick (which overflows by the scrollbar's width on
   Windows). `html.dark body.w-paper` is spelled out because Tailwind's
   `.dark .dark\:bg-slate-950` on the same element is (0,2,0) and would win. */
body.w-paper,
html.dark body.w-paper {
  background-color: var(--w-paper);
  background-image:
    linear-gradient(var(--w-grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--w-grid) 1px, transparent 1px);
  background-size: 44px 44px;
  background-position: center -1px;
}
/* The sticky header's full height. Declared on <body>, not :root, because a
   custom property's var()s resolve where it is declared: on :root this would
   read :root's --w-sub-h and never see the dashboards' own below. */
body.w-paper { --w-head-h: calc(var(--w-top-h) + var(--w-sub-h)); }
body.w-markets { --w-sub-h: 45px; }

.w-wrap { max-width: 1180px; margin: 0 auto; }
.w-wide { max-width: 1260px; margin: 0 auto; }

/* ── Type ─────────────────────────────────────────────────────────────────── */
.w-kicker {
  font-family: var(--w-mono); font-size: 12px; font-weight: 500;
  letter-spacing: .14em; text-transform: uppercase; color: var(--w-accent);
}
.w-kicker.is-quiet { color: var(--w-muted); }
html[lang^="zh"] .w-kicker { letter-spacing: .08em; }

.w-display {
  font-family: var(--w-serif); font-weight: 700; color: var(--w-ink);
  font-size: clamp(46px, 7.4vw, 100px); line-height: .98; letter-spacing: -.025em;
  margin: 18px 0 0; font-optical-sizing: auto; text-wrap: balance;
}
.w-h2 {
  font-family: var(--w-serif); font-weight: 700; color: var(--w-ink);
  font-size: clamp(32px, 4.3vw, 56px); line-height: 1.04; letter-spacing: -.02em;
  margin: 0; text-wrap: balance;
}
/* Han glyphs are square and already heavy at display sizes: a smaller scale,
   looser leading and no negative tracking, or a line of 汉字 collides. */
html[lang^="zh"] .w-display { font-size: clamp(38px, 6vw, 80px); line-height: 1.14; letter-spacing: 0; }
html[lang^="zh"] .w-h2 { font-size: clamp(28px, 3.6vw, 46px); line-height: 1.2; letter-spacing: 0; }
/* Chinese may break between any two characters, so a display line split 投 / 研
   through the middle of a word. keep-all confines breaks to punctuation and to
   <wbr> hints placed in the markup; overflow-wrap is the net for a run that
   still does not fit a narrow screen, so it wraps rather than overflows. */
html[lang^="zh"] :is(.w-display, .w-h2, .w-doc-title, .w-page-title, .w-article-title, .w-post-link h2,
                     .w-prose h2, .w-card-title.is-serif) {
  word-break: keep-all; overflow-wrap: anywhere;
}

.w-lead {
  font-size: 19px; line-height: 1.62; color: var(--w-body);
  max-width: 38rem; margin: 26px 0 0;
}
.w-muted { color: var(--w-muted); }

/* ── Buttons ──────────────────────────────────────────────────────────────── */
.w-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 30px; align-items: center; }
.w-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 44px; padding: 0 18px; border-radius: 6px;
  font-size: 15px; font-weight: 650; line-height: 1; text-decoration: none;
  color: var(--w-ink); background: var(--w-card);
  border: 1px solid var(--w-line-strong);
  transition: border-color .15s, background-color .15s, transform .15s;
}
.w-btn:hover { border-color: var(--w-ink); }
.w-btn:focus-visible { outline: 2px solid var(--w-accent); outline-offset: 2px; }
.w-btn-primary { color: var(--w-paper); background: var(--w-ink); border-color: var(--w-ink); }
.w-btn-primary:hover { transform: translateY(-1px); }
.w-btn-sm { min-height: 36px; padding: 0 14px; font-size: 14px; }
.w-textlink { color: var(--w-accent); font-weight: 600; font-size: 15px; text-decoration: none; }
.w-textlink:hover { text-decoration: underline; text-underline-offset: 3px; }

/* ── Product bar (docs + research) ────────────────────────────────────────── */
.w-bar {
  display: flex; align-items: center; gap: 22px; flex-wrap: wrap;
  padding: 4px 0 16px; margin-bottom: 8px; border-bottom: 1px solid var(--w-line);
}
.w-bar-brand {
  display: inline-flex; align-items: baseline; gap: 8px; text-decoration: none;
  font-family: var(--w-serif); font-weight: 700; font-size: 21px; color: var(--w-ink);
}
.w-bar-brand small {
  font-family: var(--w-mono); font-weight: 500; font-size: 11px;
  letter-spacing: .12em; text-transform: uppercase; color: var(--w-muted);
}
.w-bar-nav { display: flex; gap: 20px; flex-wrap: wrap; }
.w-bar-nav a {
  font-size: 14px; font-weight: 550; color: var(--w-body); text-decoration: none;
  padding: 6px 0;
}
.w-bar-nav a:hover { color: var(--w-ink); }
.w-bar-nav a.is-current { color: var(--w-ink); box-shadow: inset 0 -2px 0 var(--w-accent); }
.w-bar .w-btn { margin-left: auto; }
@media (max-width: 640px) {
  .w-bar { gap: 12px; }
  .w-bar-nav { order: 3; width: 100%; gap: 16px; overflow-x: auto; flex-wrap: nowrap; }
  .w-bar-nav a { white-space: nowrap; }
}

/* ── Masthead (trade-agents.com) ──────────────────────────────────────────────
   Stands in for base.html's bar on every page there (_ta_masthead.html,
   drawn when base.html's `_ta_shell` holds). Sticky and
   translucent over the paper grid; the rule beneath it appears only once the
   page scrolls (.is-scrolled), so at the top the bar and the page read as one
   plane. The inner column is .w-wrap's 1180px plus <main>'s own side padding,
   so the wordmark sits flush over the landing's first letter and the run
   page's form -- the same on every page, as vibetrading.wiki's bar is, even
   where a page's own column is wider (the docs).
   The opaque background is the fallback: a browser without color-mix() drops
   that declaration and keeps this one, which is legible if less pretty. */
.w-top {
  position: sticky; top: 0; z-index: 50;
  background: var(--w-paper);
  border-bottom: 1px solid transparent;
  transition: border-color .2s;
}
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .w-top {
    background: color-mix(in srgb, var(--w-paper) 84%, transparent);
    -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  }
}
.w-top.is-scrolled { border-bottom-color: var(--w-line); }
.w-top-inner {
  display: flex; align-items: center; gap: 28px;
  max-width: calc(1180px + 48px); min-height: 68px; margin: 0 auto; padding: 0 24px;
}
.w-top-brand { display: inline-flex; align-items: center; gap: 11px; flex-shrink: 0; text-decoration: none; }
.w-top-mark { display: block; width: 34px; height: 34px; flex-shrink: 0; }
.w-top-name {
  font-family: var(--w-serif); font-weight: 700; font-size: 20px;
  letter-spacing: -.01em; color: var(--w-ink); white-space: nowrap;
}
/* The section a docs or Research Lab page belongs to, set after the wordmark
   in the mono of the kickers -- the label the product bar carried there. */
.w-top-name small {
  margin-left: 8px; font-family: var(--w-mono); font-size: 11px; font-weight: 500;
  letter-spacing: .12em; text-transform: uppercase; color: var(--w-muted);
}
html[lang^="zh"] .w-top-name small { letter-spacing: .06em; }
.w-top-nav { display: flex; align-items: center; gap: 24px; margin: 0 auto; }
.w-top-nav a {
  padding: 6px 0; font-size: 14.5px; font-weight: 600; white-space: nowrap;
  color: var(--w-muted); text-decoration: none;
}
.w-top-nav a:hover { color: var(--w-ink); }
.w-top-nav a.is-current { color: var(--w-ink); box-shadow: inset 0 -2px 0 var(--w-accent); }
.w-top-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.w-top-btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 36px; height: 36px; padding: 0 10px; border-radius: 6px;
  border: 1px solid var(--w-line-strong); background: var(--w-card); color: var(--w-ink);
  font-size: 13px; font-weight: 600; line-height: 1; cursor: pointer;
  transition: border-color .15s;
}
.w-top-btn:hover { border-color: var(--w-ink); }
.w-top-btn:focus-visible, .w-top-brand:focus-visible, .w-top-nav a:focus-visible {
  outline: 2px solid var(--w-accent); outline-offset: 2px;
}
.w-top-icon { width: 36px; padding: 0; }
.w-top-icon svg { width: 16px; height: 16px; }
/* The icon that shows is the theme a click would switch *to*, as in base.html's
   bar, and it follows the class on <html>, so the first paint is already right. */
.w-top-sun { display: none; }
.dark .w-top-sun { display: block; }
.dark .w-top-moon { display: none; }
.w-top-short { display: none; }

/* The account menu, signed in: the reader's picture (or initial) opens a panel
   under the bar. `hidden` is restated because the UA's [hidden] loses to an
   author display rule, as .w-run and .w-docs note below. */
.w-acct { position: relative; }
.w-acct-btn { width: 36px; padding: 0; overflow: hidden; border-radius: 50%; }
.w-acct-btn img { display: block; width: 100%; height: 100%; object-fit: cover; }
.w-acct-initial { font-family: var(--w-serif); font-size: 15px; color: var(--w-accent); }
.w-acct-menu {
  position: absolute; top: calc(100% + 10px); right: 0; z-index: 60; width: 248px;
  padding: 6px; border: 1px solid var(--w-line); border-radius: 8px;
  background: var(--w-card); box-shadow: var(--w-shadow);
}
.w-acct-menu[hidden] { display: none; }
.w-acct-who { margin: 0 0 6px; padding: 8px 10px 10px; border-bottom: 1px solid var(--w-line); }
.w-acct-who b { display: block; font-size: 14px; font-weight: 650; color: var(--w-ink); }
.w-acct-who span {
  display: block; margin-top: 2px; font-size: 12.5px; color: var(--w-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* What is left to spend: a line to read, not an item to press, so it takes the
   menu's inset but none of an item's hover. */
.w-acct-balance {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  margin: 0; padding: 4px 10px 6px; font-size: 13px; color: var(--w-muted);
}
.w-acct-balance b { font-family: var(--w-mono); font-size: 14px; font-weight: 600; color: var(--w-ink); }
.w-acct-item {
  display: flex; align-items: center; width: 100%; padding: 9px 10px; border: 0; border-radius: 6px;
  background: none; font: inherit; font-size: 14px; color: var(--w-body);
  text-align: left; text-decoration: none; cursor: pointer;
}
.w-acct-item:hover { background: var(--w-well); color: var(--w-ink); }
.w-acct-item:focus-visible { outline: 2px solid var(--w-accent); outline-offset: -2px; }
.w-acct-item:disabled { opacity: .55; cursor: default; }
/* Both set a display, which beats the UA's [hidden]: the plan line and the Pro
   link start hidden until /api/agents/balance answers, and stay hidden when Pro
   is switched off. */
.w-acct-balance[hidden], .w-acct-item[hidden] { display: none; }
.w-acct-sep { height: 1px; margin: 6px 4px; background: var(--w-line); }

@media (max-width: 1040px) {
  .w-top-inner { gap: 20px; }
  .w-top-nav { gap: 18px; }
}
/* The full bar -- a section label, five links, and signed in a long call to
   action beside the account button -- needs about 1130px on a Research Lab page,
   and measured, it ran the docs page 120px past the viewport at 881px. So the
   label goes first and a signed-in reader's "Run an analysis" becomes "Run",
   with a Windows scrollbar's 17px to spare; then, signed in, the links, which a
   signed-out bar can keep down to 880px. */
@media (max-width: 1180px) {
  .w-top-name small { display: none; }
  .w-top[data-signed-in] .w-top-long { display: none; }
  .w-top[data-signed-in] .w-top-short { display: inline; }
}
/* Signed in, the bar also carries the Research desk link (2026-10-04), and at
   full length -- label, "Research desk", "Run an analysis" -- it measured 49px
   past the viewport on a Research Lab page at 1181px in English. So for a
   signed-in reader the label and the long forms go 80px sooner. */
@media (max-width: 1260px) {
  .w-top[data-signed-in] .w-top-name small { display: none; }
  .w-top[data-signed-in] .w-top-long { display: none; }
  .w-top[data-signed-in] .w-top-short { display: inline; }
}
@media (max-width: 960px) {
  .w-top[data-signed-in] .w-top-nav { display: none; }
  .w-top[data-signed-in] .w-top-actions { margin-left: auto; }
}
/* Below this the links would crowd the controls, so they leave the bar: for a
   row of their own under it on a page without the Markets bar (below), and on
   a dashboard, where that bar holds the row, for the footer. */
@media (max-width: 880px) {
  .w-top-nav { display: none; }
  .w-top-actions { margin-left: auto; }
  /* One size for the controls in both rows. The language toggle is a 36px
     square like theme, search and ↻: its label made it 36px wide in Chinese
     ("EN") and 44px in English ("中文"), so every switch moved the bar. The
     call to action beside it keeps its label and takes their type. */
  .w-top .lang-toggle-btn { width: 36px; padding: 0; }
  .w-top-actions > .w-btn { padding: 0 12px; font-size: 13px; font-weight: 600; }
}
@media (max-width: 640px) {
  :root { --w-top-h: 61px; }
  .w-top-inner { min-height: 60px; padding: 0 16px; gap: 12px; }
  .w-top-mark { width: 30px; height: 30px; }
  .w-top-name { font-size: 18px; }
}
@media (max-width: 520px) {
  .w-top-long { display: none; }
  .w-top-short { display: inline; }
  /* Signed in, the account button takes the call to action's place: at 390px
     the two do not fit beside the wordmark, and the menu leads to the desk. */
  .w-top[data-signed-in] .w-top-actions > .w-btn-primary { display: none; }
}
/* 360px, the common Android width, ran the signed-out bar 5px past the edge,
   and 320px by 45: tighter gaps and a smaller wordmark, then the mark itself. */
@media (max-width: 400px) {
  .w-top-inner { gap: 10px; }
  .w-top-actions { gap: 6px; }
  .w-top-name { font-size: 17px; }
}
@media (max-width: 355px) {
  .w-top-mark { display: none; }
}

/* The links' own row, on a page without the Markets bar, once the bar has let
   them go (960px signed in, 880px out; one breakpoint here, so a signed-out
   page moves them 80px early). It is inside the masthead, pinned with it, and
   scrolls sideways as the Markets bar's links do on a dashboard -- where that
   bar takes this row's place, since a third pinned row would be a quarter of a
   phone's screen. A grid rather than a wrap, because a wrapped flex line is
   only as tall as its tallest item and the bar's own row would shrink to its
   36px buttons. --w-top-h is the new height: 68 + 45 + the 1px rule under the
   masthead, 60 + 45 + 1 on a phone. The fade is kept to a side with more to
   see (data-fade, set by the masthead's script). The landing's sections are
   given back the clearance their top padding gave them under a 61px masthead,
   or Pricing and Samples land under this one. */
@media (max-width: 960px) {
  body:not(.w-markets) { --w-top-h: 114px; }
  body:not(.w-markets) .w-top-inner {
    display: grid; grid-template-columns: auto minmax(0, 1fr) auto; grid-template-rows: 68px 45px;
    row-gap: 0; align-items: center;
  }
  body:not(.w-markets) .w-top-brand { grid-area: 1 / 1; }
  body:not(.w-markets) .w-top-actions { grid-area: 1 / 3; }
  body:not(.w-markets) .w-top .w-top-nav {
    display: flex; grid-area: 2 / 1 / 3 / -1; align-self: stretch; align-items: stretch; gap: 0;
    margin: 0 -24px; padding: 0 14px; border-top: 1px solid var(--w-line);
    overflow-x: auto; scrollbar-width: none; overscroll-behavior-x: contain;
    -webkit-tap-highlight-color: transparent;
  }
  body:not(.w-markets) .w-top-nav::-webkit-scrollbar { display: none; }
  body:not(.w-markets) .w-top-nav[data-fade="right"] {
    -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 32px), transparent);
            mask-image: linear-gradient(90deg, #000 calc(100% - 32px), transparent);
  }
  body:not(.w-markets) .w-top-nav[data-fade="left"] {
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 32px);
            mask-image: linear-gradient(90deg, transparent, #000 32px);
  }
  body:not(.w-markets) .w-top-nav[data-fade="both"] {
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 32px, #000 calc(100% - 32px), transparent);
            mask-image: linear-gradient(90deg, transparent, #000 32px, #000 calc(100% - 32px), transparent);
  }
  body:not(.w-markets) .w-top-nav a {
    display: inline-flex; align-items: center; flex-shrink: 0; padding: 0 10px; font-size: 14px;
  }
  body:not(.w-markets) .w-top-nav a:active { color: var(--w-ink); }
  /* Under the word, not the padding either side of it. */
  body:not(.w-markets) .w-top-nav a.is-current {
    box-shadow: none;
    background: linear-gradient(var(--w-accent), var(--w-accent)) no-repeat center bottom / calc(100% - 20px) 2px;
  }
  body:not(.w-markets) .w-top ~ main .w-section[id] { scroll-margin-top: calc(var(--w-head-h) - 48px); }
}
@media (max-width: 640px) {
  body:not(.w-markets) { --w-top-h: 106px; }
  body:not(.w-markets) .w-top-inner { grid-template-rows: 60px 45px; }
  body:not(.w-markets) .w-top .w-top-nav { margin: 0 -16px; padding: 0 6px; }
}

/* ── Markets bar (trade-agents.com's dashboards) ─────────────────────────────
   The dashboards' own navigation, as a second row under the masthead
   (_ta_markets_bar.html), in the masthead's column so its first link sits
   under the wordmark. Sticky beneath the masthead, and under its z-index, so
   the account menu still opens over it; the dashboards' section bars stick
   under both (--w-head-h). The masthead's own rule appears as the page scrolls,
   and so parts the two rows exactly when there is content behind them. */
.w-sub {
  position: sticky; top: var(--w-top-h); z-index: 45;
  background: var(--w-paper);
  border-bottom: 1px solid var(--w-line);
}
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .w-sub {
    background: color-mix(in srgb, var(--w-paper) 84%, transparent);
    -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  }
}
.w-sub-inner {
  display: flex; align-items: center; gap: 20px;
  max-width: calc(1180px + 48px); min-height: 44px; margin: 0 auto; padding: 0 24px;
}
/* The links scroll sideways at any width they do not fit, fading on the side
   with more to see (data-fade, set by the bar's script). Only the phone had
   this while the row held the Sectors and Macro menus, which a scrolling box
   would clip; with every link a plain link, a laptop narrower than the row
   scrolls it too, rather than letting it run under ↻ Refresh. */
.w-sub-links {
  display: flex; align-items: center; gap: 20px; min-width: 0;
  overflow-x: auto; scrollbar-width: none; overscroll-behavior-x: contain;
}
.w-sub-links::-webkit-scrollbar { display: none; }
.w-sub-links[data-fade="right"] {
  -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 32px), transparent);
          mask-image: linear-gradient(90deg, #000 calc(100% - 32px), transparent);
}
.w-sub-links[data-fade="left"] {
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 32px);
          mask-image: linear-gradient(90deg, transparent, #000 32px);
}
.w-sub-links[data-fade="both"] {
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 32px, #000 calc(100% - 32px), transparent);
          mask-image: linear-gradient(90deg, transparent, #000 32px, #000 calc(100% - 32px), transparent);
}
.w-sub-link {
  display: inline-flex; align-items: center; gap: 5px; height: 44px; padding: 0;
  border: 0; background: none; font: inherit; font-size: 13.5px; font-weight: 600;
  white-space: nowrap; color: var(--w-muted); text-decoration: none; cursor: pointer;
}
.w-sub-link:hover { color: var(--w-ink); }
.w-sub-link.is-current { color: var(--w-ink); box-shadow: inset 0 -2px 0 var(--w-accent); }
.w-sub-link:focus-visible { outline: 2px solid var(--w-accent); outline-offset: -2px; }
.w-sub-tools { display: flex; align-items: center; gap: 8px; flex-shrink: 0; margin-left: auto; }

/* The ticker search's panel, the one menu left in the bar. No display of its
   own, so the `hidden` attribute that opens and closes it is not overruled. */
.w-sub-menu {
  position: absolute; top: calc(100% + 6px); left: -12px; z-index: 60; min-width: 220px;
  padding: 6px; border: 1px solid var(--w-line); border-radius: 8px;
  background: var(--w-card); box-shadow: var(--w-shadow);
}
.w-sub-menu > a {
  display: block; padding: 8px 10px; border-radius: 6px;
  font-size: 14px; color: var(--w-body); text-decoration: none;
}
.w-sub-menu > a:hover { background: var(--w-well); color: var(--w-ink); }
.w-sub-menu > a.w-sub-menu-foot {
  margin-top: 4px; padding-top: 9px; border-top: 1px solid var(--w-line); border-radius: 0 0 6px 6px;
  font-size: 13px; font-weight: 600; color: var(--w-accent); text-align: center;
}
.w-sub-search { position: relative; }
.w-sub-search .w-top-icon svg { width: 16px; height: 16px; }
.w-sub-panel { left: auto; right: 0; width: min(340px, calc(100vw - 32px)); padding: 0; overflow: hidden; }
.w-sub-panel-field { padding: 8px; border-bottom: 1px solid var(--w-line); }
.w-sub-panel-field .w-input { min-height: 38px; padding: 7px 10px; font-family: var(--w-mono); text-transform: uppercase; }
.w-sub-panel-field .w-input::placeholder { text-transform: none; font-family: inherit; }
.w-sub-panel-results { max-height: 18rem; overflow-y: auto; padding: 4px 0; }
.w-sub-panel > a.w-sub-menu-foot { margin: 0; padding: 9px 10px; border-radius: 0; }

/* ↻ Refresh and the tooltip saying what it refetches. base.html's cooldown
   dims the button and takes its href away, and turns pointer events back on
   for this wrapper so the tooltip still explains why. */
.w-sub-refresh { position: relative; }
.w-sub-refresh-icon { display: none; width: 16px; height: 16px; }
.w-sub-tip {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 60; width: 264px;
  padding: 10px 12px; border: 1px solid var(--w-line); border-radius: 8px;
  background: var(--w-card); box-shadow: var(--w-shadow);
  font-size: 12.5px; line-height: 1.5; color: var(--w-body);
  opacity: 0; pointer-events: none; transition: opacity .15s;
}
.w-sub-tip p:first-child { margin-bottom: 4px; font-weight: 650; color: var(--w-ink); }
.w-sub-refresh:hover .w-sub-tip, .w-sub-refresh:focus-within .w-sub-tip { opacity: 1; }

/* A phone: the row stays pinned under the masthead, as it is on a laptop. It
   used to scroll away with the page, to save the 45px a second pinned row
   costs, and then a reader who had scrolled a dashboard had to go back to the
   top to find its navigation. Its links scroll sideways, as they do at any
   width they do not fit.
   The links get the row but for two icons: at 390px "↻ Refresh" beside the
   search button left twelve links 220px, three and a half of them in English.
   The row runs out to the screen's edge, so a link scrolls off the side rather
   than being cut short of it; each link's hit area spans the gap to the next,
   so a 13F is not a 22px target; and the fade is only on a side with more to
   see -- data-fade, set by the bar's script, whose page link it keeps in view.
   Without the script the row keeps the right-hand fade it starts with. */
@media (max-width: 880px) {
  .w-sub-inner { position: relative; gap: 8px; }
  .w-sub-links {
    flex: 1; align-self: stretch; gap: 0; margin-left: -24px; padding-left: 14px;
    -webkit-tap-highlight-color: transparent;
  }
  /* Before the script has measured anything, a phone's row is sure to run on. */
  .w-sub-links:not([data-fade]) {
    -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 32px), transparent);
            mask-image: linear-gradient(90deg, #000 calc(100% - 32px), transparent);
  }
  .w-sub-link { padding: 0 10px; font-size: 14px; }
  .w-sub-link:active { color: var(--w-ink); }
  /* Under the word, not the padding either side of it. */
  .w-sub-link.is-current {
    box-shadow: none;
    background: linear-gradient(var(--w-accent), var(--w-accent)) no-repeat center bottom / calc(100% - 20px) 2px;
  }
  .w-sub-tools { gap: 6px; }
  .w-sub-refresh-btn { width: 36px; padding: 0; }
  .w-sub-refresh-icon { display: block; }
  .w-sub-refresh-label {
    position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden;
    clip: rect(0, 0, 0, 0); white-space: nowrap;
  }
  /* Right-aligned to its icon, the search panel's 340px ran off the left edge
     of a phone; here it spans the row instead, inset like the page. */
  .w-sub-search { position: static; }
  .w-sub-panel { left: 24px; right: 24px; width: auto; top: calc(100% + 4px); }
}
@media (max-width: 640px) {
  .w-sub-inner { padding: 0 16px; }
  .w-sub-links { margin-left: -16px; padding-left: 6px; }
  .w-sub-panel { left: 16px; right: 16px; }
}

/* ── Sections ─────────────────────────────────────────────────────────────── */
.w-section { padding-top: 104px; }
.w-section-head {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2.25fr);
  gap: 24px; align-items: end; margin-bottom: 30px;
}
.w-section-head .w-kicker { padding-bottom: 12px; }
.w-section-head p.w-lead { grid-column: 2; margin-top: 0; font-size: 17px; }
@media (max-width: 860px) {
  .w-section { padding-top: 72px; }
  .w-section-head { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .w-section-head p.w-lead { grid-column: 1; }
  .w-section-head .w-kicker { padding-bottom: 0; }
}

.w-grid4, .w-grid5, .w-grid3 { display: grid; gap: 14px; }
.w-grid4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.w-grid5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.w-grid3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 1080px) {
  .w-grid5 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .w-grid4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
  .w-grid5, .w-grid4, .w-grid3 { grid-template-columns: minmax(0, 1fr); }
}

.w-card {
  display: block; position: relative; background: var(--w-card);
  border: 1px solid var(--w-line); border-radius: 8px; padding: 20px 20px 22px;
  color: var(--w-body); text-decoration: none;
}
a.w-card { transition: border-color .15s, transform .15s, box-shadow .15s; }
a.w-card:hover { border-color: var(--w-line-strong); transform: translateY(-2px); box-shadow: var(--w-shadow); }
a.w-card:focus-visible { outline: 2px solid var(--w-accent); outline-offset: 2px; }
.w-card-num { font-family: var(--w-mono); font-size: 12px; font-weight: 600; color: var(--w-num); }
.w-card-title {
  display: block; margin-top: 26px; font-size: 17px; font-weight: 650;
  color: var(--w-ink); line-height: 1.3;
}
.w-card-title.is-serif {
  margin-top: 0; font-family: var(--w-serif); font-weight: 700;
  font-size: 26px; line-height: 1.12; letter-spacing: -.01em;
}
.w-card-body { display: block; margin-top: 9px; font-size: 15px; line-height: 1.6; color: var(--w-body); }
.w-card-foot { display: block; margin-top: 16px; font-size: 13px; font-weight: 600; color: var(--w-accent); }
.w-card-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: 8px;
  color: var(--w-accent); background: var(--w-accent-soft);
}
.w-card-icon svg { width: 20px; height: 20px; }
.w-card-icon + .w-card-title { margin-top: 18px; }

/* ── Hero ─────────────────────────────────────────────────────────────────── */
.w-hero {
  display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: 56px; align-items: center; padding: 64px 0 8px;
}
@media (max-width: 1000px) {
  .w-hero { grid-template-columns: minmax(0, 1fr); gap: 40px; padding-top: 28px; }
}

/* The run log. Dark in both themes on purpose -- a terminal is dark, and a
   light terminal on light paper would read as one more card. */
.w-term {
  background: var(--w-term); border: 1px solid var(--w-term-line); border-radius: 10px;
  box-shadow: var(--w-shadow); overflow: hidden;
  font-family: var(--w-mono); font-size: 13px; line-height: 1.5; color: #d7dde5;
}
.w-term-bar {
  display: flex; align-items: center; gap: 7px; padding: 11px 14px;
  border-bottom: 1px solid var(--w-term-line); color: #9aa4b2; font-size: 12px;
}
.w-term-bar i { width: 11px; height: 11px; border-radius: 50%; display: inline-block; }
.w-term-bar i:nth-child(1) { background: #ef4444; }
.w-term-bar i:nth-child(2) { background: #f59e0b; }
.w-term-bar i:nth-child(3) { background: #22c55e; }
.w-term-bar b { font-weight: 600; color: #e5e7eb; margin-left: 8px; }
.w-term-bar em { margin-left: auto; font-style: normal; color: #86efac; }
.w-term-body { padding: 14px 16px 16px; }
.w-term-cmd { color: #e5e7eb; margin-bottom: 10px; overflow-wrap: anywhere; }
.w-term-cmd::before { content: '$ '; color: #fb923c; }
.w-log { list-style: none; margin: 0; padding: 0; }
.w-log li {
  display: grid; grid-template-columns: 22px minmax(0, 11.5em) minmax(0, 1fr) 18px;
  gap: 8px; align-items: baseline; padding: 3px 0; color: #7b8595;
  transition: color .25s;
}
.w-log .w-log-ico { text-align: center; }
.w-log .w-log-who { color: #aab3c0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.w-log .w-log-what { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.w-log .w-log-state { text-align: right; }
.w-log li[data-state="done"] { color: #9aa4b2; }
.w-log li[data-state="done"] .w-log-who { color: #e5e7eb; }
.w-log li[data-state="done"] .w-log-state::before { content: '✓'; color: #4ade80; }
.w-log li[data-state="active"] { color: #e5e7eb; }
.w-log li[data-state="active"] .w-log-who { color: #fde68a; }
.w-log li[data-state="active"] .w-log-state::before { content: '▸'; color: #fbbf24; animation: wBlink 1s steps(2, start) infinite; }
.w-log li[data-state="todo"] .w-log-state::before { content: '·'; color: #4b5563; }
.w-log li.is-divider { display: block; margin: 7px 0 4px; padding: 0; color: #5b6574; font-size: 11px; letter-spacing: .1em; text-transform: uppercase; }
.w-term-foot { margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--w-term-line); color: #9aa4b2; }
.w-term-foot b { color: #86efac; font-weight: 600; }
@keyframes wBlink { to { visibility: hidden; } }
@media (max-width: 480px) {
  .w-log li { grid-template-columns: 20px minmax(0, 1fr) 16px; }
  .w-log .w-log-what { display: none; }
}

.w-chips { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; margin-top: 12px; }
.w-chip {
  border: 1px solid var(--w-line); background: var(--w-card); border-radius: 6px;
  padding: 9px 6px 8px; text-align: center; font-family: var(--w-mono); font-size: 12.5px;
  color: var(--w-ink); cursor: pointer; transition: border-color .15s, box-shadow .15s;
}
.w-chip:hover { border-color: var(--w-line-strong); }
.w-chip:focus-visible { outline: 2px solid var(--w-accent); outline-offset: 2px; }
.w-chip[aria-pressed="true"] { border-color: var(--w-accent); box-shadow: inset 0 0 0 1px var(--w-accent); }
.w-chip small { display: block; margin-top: 2px; font-family: inherit; font-size: 10.5px; color: var(--w-muted); letter-spacing: .04em; }

.w-hero-note { margin: 18px 0 0; font-size: 13.5px; color: var(--w-muted); }
.w-more { margin: 18px 0 0; font-size: 15px; }
.w-grid-auto { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.w-run { margin: 0; }
/* Rows and the done line toggle `hidden`; `.w-log li` sets display:grid and
   would otherwise win over the UA's [hidden], leaving A-share rows showing on
   a US ticker. */
.w-run [hidden] { display: none !important; }
.w-sr {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* ── Desk roster ──────────────────────────────────────────────────────────── */
.w-desk { border: 1px solid var(--w-line); border-radius: 10px; background: var(--w-card); overflow: hidden; }
.w-desk-row {
  display: grid; grid-template-columns: 190px minmax(0, 1fr); gap: 16px;
  padding: 16px 20px; align-items: center;
}
.w-desk-row + .w-desk-row { border-top: 1px solid var(--w-line); }
.w-desk-team { font-family: var(--w-mono); font-size: 11.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--w-muted); }
.w-desk-seats { display: flex; flex-wrap: wrap; gap: 8px; }
.w-seat {
  display: inline-flex; align-items: center; gap: 7px; padding: 6px 11px 6px 9px;
  border-radius: 999px; border: 1px solid var(--w-line); background: var(--w-well);
  font-size: 13.5px; color: var(--w-ink); line-height: 1.2;
  box-shadow: inset 3px 0 0 var(--seat, var(--w-accent));
}
.w-seat-tag {
  font-family: var(--w-mono); font-size: 10px; letter-spacing: .06em;
  color: var(--w-num); border: 1px solid currentColor; border-radius: 4px; padding: 0 4px;
}
@media (max-width: 700px) {
  .w-desk-row { grid-template-columns: minmax(0, 1fr); gap: 10px; }
}

/* ── Pricing ──────────────────────────────────────────────────────────────── */
.w-price-num { font-family: var(--w-read); font-size: 40px; font-weight: 700; color: var(--w-ink); line-height: 1; margin-top: 18px; display: block; }
.w-price-num small { font-family: var(--w-mono); font-size: 13px; font-weight: 500; color: var(--w-muted); margin-left: 6px; }
.w-price-per { display: block; margin-top: 8px; font-family: var(--w-mono); font-size: 12.5px; color: var(--w-muted); }
.w-card.is-free { background: var(--w-accent-soft); border-color: var(--w-accent-line); }
.w-card.is-pro { border-color: var(--w-accent-line); box-shadow: var(--w-shadow); }
.w-card.is-pro .w-card-foot { margin-top: 14px; }

/* ── Boundary + footer strip ──────────────────────────────────────────────── */
.w-boundary {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr); gap: 48px;
  margin-top: 104px; padding-top: 56px; border-top: 1px solid var(--w-line);
}
.w-boundary p:not(.w-kicker) { font-size: 17px; line-height: 1.7; color: var(--w-body); margin: 26px 0 0; }
/* The kicker is a <p> as well. Under a bare `.w-boundary p` (0,1,1 beats the
   kicker's 0,1,0) it rendered as 17px body copy, the one section eyebrow on the
   page that did not look like the others. The top margin keeps it level with
   the paragraph in the next column. */
.w-boundary .w-kicker { margin: 26px 0 10px; }
@media (max-width: 860px) { .w-boundary { grid-template-columns: minmax(0, 1fr); gap: 0; margin-top: 72px; } }
/* One column, for a reading-width page (a shared report is 56rem): side by side
   there, the heading broke into four lines beside a two-line paragraph. */
.w-boundary.is-stacked { grid-template-columns: minmax(0, 1fr); gap: 0; }
.w-boundary.is-stacked p:not(.w-kicker) { max-width: 40rem; margin-top: 18px; }

.w-foot {
  display: flex; flex-wrap: wrap; gap: 14px 28px; justify-content: space-between; align-items: center;
  margin-top: 72px; padding: 18px 0 8px; border-top: 1px solid var(--w-line);
  font-size: 13.5px; color: var(--w-muted);
}
.w-foot b { font-family: var(--w-serif); font-size: 16px; color: var(--w-ink); }
.w-foot nav { display: flex; flex-wrap: wrap; gap: 18px; }
.w-foot a { color: var(--w-body); text-decoration: none; }
.w-foot a:hover { color: var(--w-ink); }

/* ── trade-agents.com's shell: footer and page column ────────────────────────
   The footer (_ta_footer.html) closes every page in the shell, in the
   masthead's column so the two frame the page alike. <main>'s own bottom
   padding sits above it, which is why its margin is small. */
.w-footer { margin-top: 40px; border-top: 1px solid var(--w-line); }
.w-footer-inner { max-width: calc(1180px + 48px); margin: 0 auto; padding: 22px 24px 36px; }
.w-footer-row {
  display: flex; flex-wrap: wrap; gap: 14px 28px; justify-content: space-between; align-items: center;
}
.w-footer-brand {
  display: inline-flex; align-items: center; gap: 9px; text-decoration: none;
  font-family: var(--w-serif); font-weight: 700; font-size: 17px; color: var(--w-ink);
}
.w-footer-mark { display: block; width: 24px; height: 24px; flex-shrink: 0; }
.w-footer nav { display: flex; flex-wrap: wrap; gap: 8px 20px; font-size: 13.5px; }
.w-footer nav a { color: var(--w-body); text-decoration: none; }
.w-footer nav a:hover { color: var(--w-ink); }
.w-footer-brand:focus-visible, .w-footer nav a:focus-visible { outline: 2px solid var(--w-accent); outline-offset: 2px; }
.w-footer-note { margin: 14px 0 0; max-width: 52rem; font-size: 12.5px; line-height: 1.6; color: var(--w-muted); }
/* On a phone the links are a grid rather than a line that wraps wherever a
   label runs out: at 390px seven of them broke after "What's new", leaving
   "Markets" and "Contact" on a second line, each a 20px-tall target. Here
   every link is a 40px row in columns that fit the screen -- three from 375px,
   two at 360 and below -- and a dashboard's ten fill the same grid. */
@media (max-width: 640px) {
  .w-footer-inner { padding: 20px 16px 30px; }
  .w-footer nav {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
    gap: 0 12px; width: 100%; font-size: 14px;
  }
  .w-footer nav a { display: flex; align-items: center; min-height: 40px; }
}

/* ── The reading wall (trade-agents.com's dashboards, signed out) ─────────────
   _ta_wall.html. Everything in <main> below the fold sits under a blur and a
   veil of the paper, with the card pinned in view while the reader scrolls
   through it. Absolute in <main>, so it grows with the page as panels load,
   and the footer below stays readable. Its z-index is under the pages' own
   pinned bars (/markets' section bar is 30, /history's 20), which stay usable
   above it, and the blur fades in over 96px rather than starting at a hard
   edge. The fold defaults to about one screen down; a page moves it with
   `data-wall-start`. Without color-mix() the veil is the paper itself, which
   hides more than it blurs and still walls. */
body.w-walled main { position: relative; }
.w-wall {
  position: absolute; left: 0; right: 0; bottom: 0; top: var(--w-wall-top, max(560px, 72vh));
  z-index: 15; padding: 132px 16px 56px;
  background: var(--w-paper);
  background: linear-gradient(color-mix(in srgb, var(--w-paper) 30%, transparent),
                              color-mix(in srgb, var(--w-paper) 78%, transparent) 480px);
  -webkit-backdrop-filter: blur(7px); backdrop-filter: blur(7px);
  -webkit-mask-image: linear-gradient(transparent, #000 96px);
          mask-image: linear-gradient(transparent, #000 96px);
}
/* Stood down by _ta_wall.html's script where <main> is too short to hold it. */
.w-wall[hidden] { display: none; }
.w-wall-card {
  position: sticky; top: calc(var(--w-head-h) + 14vh);
  max-width: 440px; margin: 0 auto; padding: 24px 22px; text-align: center;
  background: var(--w-card); border: 1px solid var(--w-line); border-radius: 10px;
  box-shadow: var(--w-shadow);
}
.w-wall-title {
  margin: 8px 0 0; font-family: var(--w-serif); font-weight: 700; font-size: 24px;
  line-height: 1.2; color: var(--w-ink);
}
html[lang^="zh"] .w-wall-title { word-break: keep-all; overflow-wrap: anywhere; }
.w-wall-lead { margin: 10px 0 18px; font-size: 15px; line-height: 1.55; color: var(--w-body); }

/* A page whose content should sit in the masthead's column: <main> takes this
   in place of the dashboards' .app-container, keeping its own side padding,
   so 1228px less 2 x 24px is .w-wrap's 1180. */
.w-main { max-width: calc(1180px + 48px); margin-left: auto; margin-right: auto; }

/* A page head -- kicker, serif title, lead -- for the shell's pages that are
   not documents: the run page, a shared report, sign-in, contact. The type is
   .w-doc-title's, a step smaller, since these heads sit above a working page. */
.w-page-head { padding: 26px 0 30px; }
.w-page-title {
  font-family: var(--w-serif); font-weight: 700; color: var(--w-ink);
  font-size: clamp(36px, 4.6vw, 58px); line-height: 1.02; letter-spacing: -.024em;
  margin: 12px 0 0; text-wrap: balance;
}
html[lang^="zh"] .w-page-title { font-size: clamp(30px, 3.8vw, 46px); line-height: 1.2; letter-spacing: 0; }
.w-page-title small {
  margin-left: .35em; font-family: var(--w-read); font-size: .42em; font-weight: 400;
  letter-spacing: 0; color: var(--w-muted);
}
.w-page-lead { margin: 18px 0 0; max-width: 44rem; font-size: 18px; line-height: 1.62; color: var(--w-body); }
.w-page-note { margin: 10px 0 0; max-width: 44rem; font-size: 14px; line-height: 1.55; color: var(--w-muted); }
.w-page-meta { margin: 12px 0 0; font-size: 14px; line-height: 1.55; color: var(--w-muted); }
.w-page-meta b { font-weight: 600; color: var(--w-body); }
.w-page-links { display: flex; flex-wrap: wrap; gap: 6px 22px; margin: 18px 0 0; }

/* A shared report's head: the ticker as the title, its verdict and the PDF on
   the same line, and the sharer's note -- typed text, so its line breaks are
   kept. */
.w-share-head {
  display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 12px 24px;
}
.w-share-actions { display: flex; align-items: center; gap: 10px; padding-bottom: 6px; }
.w-share-note { white-space: pre-wrap; margin-bottom: 0; }
/* A dead share link: nothing else on the page, so the head is set lower and
   narrower, in the reading measure. */
.w-gone { max-width: 46rem; padding-top: 72px; min-height: 46vh; }

/* Two columns, words then the thing to do: sign-in and contact. */
.w-split {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 440px);
  gap: 72px; align-items: start; padding: 48px 0 16px;
}
.w-split .w-page-head { padding: 0; }
@media (max-width: 900px) {
  .w-split { grid-template-columns: minmax(0, 1fr); gap: 28px; padding-top: 12px; }
}
.w-panel { padding: 26px 26px 24px; }
.w-panel-title { margin: 0; font-family: var(--w-serif); font-weight: 700; font-size: 22px; line-height: 1.2; color: var(--w-ink); }
.w-panel-sub { margin: 6px 0 0; font-size: 14px; line-height: 1.55; color: var(--w-muted); }
.w-btn-wide { width: 100%; }
/* Google's button, drawn into this box when its script arrives. The height is
   held in advance so the panel does not jump when it does. */
.w-gsi { margin-top: 20px; min-height: 40px; }

.w-checks { list-style: none; margin: 22px 0 0; padding: 0; display: grid; gap: 10px; }
.w-checks li {
  display: grid; grid-template-columns: 18px minmax(0, 1fr); gap: 10px;
  font-size: 15px; line-height: 1.55; color: var(--w-body);
}
.w-checks li::before { content: '✓'; font-weight: 700; color: var(--w-good); }

.w-or {
  display: flex; align-items: center; gap: 12px; margin: 20px 0;
  font-family: var(--w-mono); font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--w-muted);
}
.w-or::before, .w-or::after { content: ''; flex: 1; height: 1px; background: var(--w-line); }

.w-field { display: block; margin-top: 16px; }
.w-field > span {
  display: block; margin-bottom: 6px; font-family: var(--w-mono); font-size: 11px;
  letter-spacing: .12em; text-transform: uppercase; color: var(--w-muted);
}
html[lang^="zh"] .w-field > span { letter-spacing: .06em; }
.w-input {
  display: block; width: 100%; min-height: 44px; padding: 10px 12px; border-radius: 6px;
  font: inherit; font-size: 15px; line-height: 1.5; color: var(--w-ink);
  background: var(--w-well); border: 1px solid var(--w-line);
}
.w-input::placeholder { color: var(--w-muted); opacity: 1; }
.w-input:focus { outline: 2px solid var(--w-accent); outline-offset: 0; border-color: transparent; }
textarea.w-input { min-height: 140px; resize: vertical; }

/* The shell's sticky things sit under the masthead, which is taller than the
   dashboards' 56px bar the defaults below were set for. The sidebar only above
   the width where it stops being sticky: these selectors outrank that media
   query's plain `.w-side`, and would otherwise cap the phone's open menu. */
@media (min-width: 861px) {
  .w-top ~ main .w-side { top: calc(var(--w-head-h) + 16px); max-height: calc(100vh - var(--w-head-h) - 32px); }
}
.w-top ~ main .w-toc { top: calc(var(--w-head-h) + 32px); }
.w-top ~ main .w-prose h2 { scroll-margin-top: calc(var(--w-head-h) + 24px); }
/* A link to a docs section targets the <section>, not its h2, so the rule above
   never applied to one: the heading landed under the masthead, and 59px under
   it once the phone's masthead grew its row of links. A section opens with 8px
   of padding, a 1px rule and the h2's 38px margin, so this lands the heading
   24px under the header, where the h2 rule meant it to be. */
.w-top ~ main .w-prose section[id] { scroll-margin-top: calc(var(--w-head-h) - 23px); }

/* ── Docs layout ──────────────────────────────────────────────────────────── */
.w-docs {
  display: grid; grid-template-columns: 272px minmax(0, 1fr) 190px;
  gap: 44px; align-items: start; padding-top: 18px;
}
.w-side {
  position: sticky; top: 72px; max-height: calc(100vh - 88px); overflow-y: auto;
  background: var(--w-card); border: 1px solid var(--w-line); border-radius: 10px;
  padding: 12px 8px 14px;
}
.w-side summary { display: none; }
.w-side-search { padding: 4px 6px 10px; border-bottom: 1px solid var(--w-line); margin-bottom: 4px; }
.w-side-search label { display: block; font-family: var(--w-mono); font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--w-muted); margin: 2px 2px 6px; }
.w-side-search input {
  width: 100%; height: 38px; padding: 0 11px; border-radius: 6px; font-size: 14px;
  color: var(--w-ink); background: var(--w-well); border: 1px solid var(--w-line);
}
.w-side-search input:focus { outline: 2px solid var(--w-accent); outline-offset: 0; border-color: transparent; }
.w-side-group {
  font-family: var(--w-mono); font-size: 11px; font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; color: var(--w-num); margin: 16px 10px 4px;
}
.w-side-link { display: block; padding: 8px 10px; border-radius: 6px; text-decoration: none; }
.w-side-link b { display: block; font-size: 14px; font-weight: 600; color: var(--w-ink); }
.w-side-link span.w-side-desc { display: block; margin-top: 2px; font-size: 12.5px; line-height: 1.45; color: var(--w-muted); }
.w-side-link:hover { background: var(--w-well); }
.w-side-link.is-current { background: var(--w-accent-soft); box-shadow: inset 0 0 0 1px var(--w-accent-line); }
.w-side-empty { display: none; padding: 10px; font-size: 13px; color: var(--w-muted); }
/* The filter and the contents list toggle `hidden`, and the UA's [hidden] rule
   loses to any author `display` of equal specificity loaded later — which is
   every rule in this file. Without this the filter hid nothing. */
.w-docs [hidden] { display: none !important; }

.w-toc { position: sticky; top: 88px; font-size: 13px; }
.w-toc .w-kicker { color: var(--w-num); font-size: 11px; font-weight: 600; }
.w-toc ol { list-style: none; margin: 10px 0 0; padding: 0; border-left: 1px solid var(--w-line); }
.w-toc a { display: block; padding: 4px 0 4px 12px; margin-left: -1px; color: var(--w-muted); text-decoration: none; border-left: 2px solid transparent; }
.w-toc a:hover { color: var(--w-ink); }
.w-toc a.is-active { color: var(--w-ink); border-left-color: var(--w-accent); }

.w-doc-head { padding-bottom: 26px; border-bottom: 1px solid var(--w-line); margin-bottom: 8px; }
.w-doc-head .w-kicker { color: var(--w-accent); }
.w-doc-title {
  font-family: var(--w-serif); font-weight: 700; color: var(--w-ink);
  font-size: clamp(40px, 5.2vw, 68px); line-height: 1.02; letter-spacing: -.025em; margin: 12px 0 0;
}
html[lang^="zh"] .w-doc-title { font-size: clamp(34px, 4.4vw, 54px); line-height: 1.18; letter-spacing: 0; }
.w-doc-lead { font-size: 18.5px; line-height: 1.6; color: var(--w-body); margin: 18px 0 0; max-width: 44rem; }

.w-pager { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; margin-top: 56px; }
.w-pager a { display: block; padding: 16px 18px; border: 1px solid var(--w-line); border-radius: 8px; background: var(--w-card); text-decoration: none; }
.w-pager a:hover { border-color: var(--w-line-strong); }
.w-pager small { display: block; font-family: var(--w-mono); font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--w-muted); }
.w-pager b { display: block; margin-top: 4px; font-size: 16px; color: var(--w-ink); }
.w-pager .is-next { text-align: right; grid-column: 2; }

@media (max-width: 1200px) {
  .w-docs { grid-template-columns: 250px minmax(0, 1fr); gap: 36px; }
  .w-toc { display: none; }
}
@media (max-width: 860px) {
  .w-docs { grid-template-columns: minmax(0, 1fr); gap: 20px; padding-top: 6px; }
  .w-side { position: static; max-height: none; padding: 0; }
  .w-side summary {
    display: flex; align-items: center; justify-content: space-between; cursor: pointer;
    padding: 12px 14px; font-weight: 600; font-size: 14px; color: var(--w-ink); list-style: none;
  }
  .w-side summary::-webkit-details-marker { display: none; }
  .w-side summary::after { content: '▾'; color: var(--w-muted); }
  .w-side[open] summary { border-bottom: 1px solid var(--w-line); }
  .w-side-inner { padding: 10px 8px 14px; }
}

/* ── Prose ────────────────────────────────────────────────────────────────── */
.w-prose { color: var(--w-body); font-size: 16.5px; line-height: 1.75; }
.w-prose > section { padding: 8px 0 18px; }
.w-prose > section + section { border-top: 1px solid var(--w-line); }
.w-prose h2 {
  font-family: var(--w-serif); font-weight: 700; color: var(--w-ink);
  font-size: clamp(28px, 3vw, 38px); line-height: 1.12; letter-spacing: -.015em;
  margin: 38px 0 14px; scroll-margin-top: 80px;
}
.w-prose h3 { font-family: var(--w-serif); font-weight: 700; color: var(--w-ink); font-size: 21px; line-height: 1.25; margin: 30px 0 8px; }
.w-prose p { margin: 0 0 16px; }
.w-prose ul, .w-prose ol { margin: 0 0 18px; padding-left: 1.35em; }
.w-prose ul { list-style: disc; }
.w-prose ol { list-style: decimal; }
.w-prose li { margin: 7px 0; padding-left: 2px; }
.w-prose li::marker { color: var(--w-muted); }
.w-prose strong { color: var(--w-ink); font-weight: 650; }
.w-prose a { color: var(--w-accent); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.w-prose code {
  font-family: var(--w-mono); font-size: .86em; color: var(--w-ink);
  background: var(--w-well); border: 1px solid var(--w-line); border-radius: 4px; padding: 1px 5px;
}
.w-prose pre {
  margin: 8px 0 20px; padding: 14px 16px; overflow-x: auto;
  background: var(--w-well); border: 1px solid var(--w-line); border-radius: 8px;
  font-family: var(--w-mono); font-size: 13.5px; line-height: 1.65; color: var(--w-ink);
}
.w-prose pre code { background: none; border: 0; padding: 0; font-size: inherit; }
.w-table-wrap { overflow-x: auto; margin: 6px 0 20px; }
.w-prose table { width: 100%; border-collapse: collapse; font-size: 14.5px; line-height: 1.5; }
.w-prose th {
  text-align: left; font-weight: 600; font-size: 12.5px; color: var(--w-muted);
  border-bottom: 1px solid var(--w-line-strong); padding: 8px 12px 8px 0; white-space: nowrap;
}
.w-prose td { border-bottom: 1px solid var(--w-line); padding: 9px 12px 9px 0; vertical-align: top; }
.w-prose td.num, .w-prose th.num { text-align: right; font-family: var(--w-mono); font-size: 13.5px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.w-prose td.good { color: var(--w-good); }
.w-prose td.bad { color: var(--w-bad); }
.w-prose kbd { font-family: var(--w-mono); font-size: .82em; border: 1px solid var(--w-line-strong); border-bottom-width: 2px; border-radius: 4px; padding: 0 5px; }

.w-callout {
  margin: 22px 0; padding: 14px 18px; border-left: 3px solid var(--w-accent);
  background: var(--w-well); border-radius: 0 8px 8px 0; font-size: 15.5px; line-height: 1.65;
}
.w-callout.is-warn { border-left-color: var(--w-num); }
.w-callout p:last-child { margin-bottom: 0; }
.w-callout.is-good { border-left-color: var(--w-good); }

.w-stats {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px 24px;
  margin: 24px 0; padding: 22px 24px; border: 1px solid var(--w-line); border-radius: 10px;
  background: var(--w-well);
}
.w-stat-label { display: block; font-family: var(--w-mono); font-size: 11px; line-height: 1.4; letter-spacing: .12em; text-transform: uppercase; color: var(--w-muted); }
.w-stat-value { display: block; margin: 6px 0 2px; font-family: var(--w-read); font-weight: 700; font-size: 34px; line-height: 1.08; color: var(--w-ink); }
.w-stat-value.is-good { color: var(--w-good); }
.w-stat-value.is-bad { color: var(--w-bad); }
.w-stat-value.is-num { color: var(--w-num); }
/* Block, not inline: an inline span takes its line box from the parent's
   line-height, which inside .w-prose is the 1.75 body leading. */
.w-stat-note { display: block; font-size: 14px; line-height: 1.45; color: var(--w-body); }
@media (max-width: 640px) { .w-stats { grid-template-columns: minmax(0, 1fr); } }

.w-roles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin: 10px 0 22px; }
.w-role {
  border: 1px solid var(--w-line); border-radius: 8px; background: var(--w-card);
  padding: 14px 16px; box-shadow: inset 3px 0 0 var(--seat, var(--w-accent));
}
.w-role-name { display: flex; flex-wrap: wrap; gap: 2px 8px; align-items: baseline; font-weight: 650; color: var(--w-ink); font-size: 15px; }
.w-role-name small { font-weight: 500; color: var(--w-muted); font-size: 12.5px; }
.w-role p { margin: 6px 0 0; font-size: 14.5px; line-height: 1.6; }
@media (max-width: 640px) { .w-roles { grid-template-columns: minmax(0, 1fr); } }

/* ── Research Lab ─────────────────────────────────────────────────────────── */
.w-lab-hero { padding: 72px 0 12px; max-width: 900px; }
.w-lab-hero .w-display { font-size: clamp(52px, 8vw, 112px); }
.w-postlist { list-style: none; margin: 72px 0 0; padding: 0; }
.w-postlist > li { padding: 34px 0 36px; border-top: 1px solid var(--w-line); display: grid; grid-template-columns: 170px minmax(0, 1fr); gap: 28px; }
.w-postlist > li:last-child { border-bottom: 1px solid var(--w-line); }
.w-post-date { font-family: var(--w-mono); font-size: 13px; color: var(--w-body); padding-top: 10px; }
.w-post-date small { display: block; margin-top: 4px; color: var(--w-muted); font-size: 12px; }
.w-post-link { text-decoration: none; }
.w-post-link h2 {
  font-family: var(--w-serif); font-weight: 700; color: var(--w-ink);
  font-size: clamp(30px, 3.6vw, 46px); line-height: 1.06; letter-spacing: -.02em; margin: 0;
  text-wrap: balance;
}
html[lang^="zh"] .w-post-link h2 { line-height: 1.22; letter-spacing: 0; }
.w-post-link:hover h2 { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 6px; }
.w-post-sum { margin: 14px 0 0; font-size: 16.5px; line-height: 1.65; color: var(--w-body); max-width: 46rem; }
.w-tags { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.w-tag {
  display: inline-block; padding: 3px 10px; border-radius: 999px;
  border: 1px solid var(--w-line-strong); background: var(--w-card);
  font-family: var(--w-mono); font-size: 11.5px; color: var(--w-body);
}
@media (max-width: 760px) {
  .w-postlist > li { grid-template-columns: minmax(0, 1fr); gap: 8px; }
  .w-post-date { padding-top: 0; }
}

.w-article { max-width: 760px; margin: 0 auto; padding-top: 40px; }
.w-article-trail { font-family: var(--w-mono); font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--w-muted); }
.w-article-trail a { color: inherit; text-decoration: none; }
.w-article-trail a:hover { color: var(--w-ink); }
.w-article-title {
  font-family: var(--w-serif); font-weight: 700; color: var(--w-ink);
  font-size: clamp(38px, 5.4vw, 62px); line-height: 1.04; letter-spacing: -.022em; margin: 14px 0 0;
  text-wrap: balance;
}
html[lang^="zh"] .w-article-title { font-size: clamp(32px, 4.4vw, 50px); line-height: 1.2; letter-spacing: 0; }
.w-article-meta { margin-top: 16px; font-family: var(--w-mono); font-size: 12.5px; color: var(--w-muted); }
.w-article-lead {
  font-family: var(--w-read); font-size: 19.5px; line-height: 1.62; color: var(--w-ink);
  margin: 22px 0 0; padding-bottom: 30px; border-bottom: 1px solid var(--w-line);
}
.w-article .w-prose > section + section { border-top: 0; }
.w-article .w-prose h2 { margin-top: 44px; }
.w-repro { margin-top: 20px; }
.w-article-foot { margin-top: 56px; padding-top: 22px; border-top: 1px solid var(--w-line); font-size: 14px; line-height: 1.65; color: var(--w-muted); }

/* A figure of horizontal bars drawn in CSS: a handful of numbers does not need
   a charting library, and a canvas would need the CT.c() theme mapping. */
.w-hbars { margin: 10px 0 22px; display: grid; gap: 7px; }
.w-hbar-row { display: grid; grid-template-columns: minmax(0, 13em) minmax(0, 1fr) 5.2em; gap: 10px; align-items: center; font-size: 14px; }
.w-hbar-row .w-hbar-label { color: var(--w-ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.w-hbar-track { position: relative; height: 12px; background: var(--w-well); border: 1px solid var(--w-line); border-radius: 3px; }
.w-hbar-fill { position: absolute; top: -1px; bottom: -1px; border-radius: 3px; background: var(--w-good); }
.w-hbar-fill.is-neg { background: var(--w-bad); }
.w-hbar-zero { position: absolute; top: -3px; bottom: -3px; width: 1px; background: var(--w-line-strong); }
.w-hbar-val { text-align: right; font-family: var(--w-mono); font-size: 13px; font-variant-numeric: tabular-nums; color: var(--w-ink); }
@media (max-width: 560px) { .w-hbar-row { grid-template-columns: minmax(0, 8.5em) minmax(0, 1fr) 4.6em; font-size: 13px; } }

@media (prefers-reduced-motion: reduce) {
  a.w-card, .w-btn, .w-log li, .w-top, .w-top-btn { transition: none; }
  a.w-card:hover, .w-btn-primary:hover { transform: none; }
  .w-log li[data-state="active"] .w-log-state::before { animation: none; }
}

/* ── /subscribe: TradeAgents Pro ──────────────────────────────────────────────
   Two plan cards, the yearly one marked, then what Pro includes, the
   comparison and the questions. `.w-pro-*`, not `.w-sub-*`: that prefix is the
   Markets bar's. [hidden] is restated because .w-callout's children set no
   display of their own but a later rule could, the trap noted at .w-run. */
.w-pro { padding-bottom: 32px; }
.w-pro [hidden] { display: none; }
.w-pro .w-callout { max-width: 860px; margin: 0 0 22px; }
.w-pro .w-callout .w-textlink { margin-left: 8px; font-size: inherit; }
.w-pro-status { max-width: 860px; margin: 0 0 26px; }
.w-pro-status .w-actions { margin-top: 20px; gap: 10px 16px; }
.w-pro-status .w-actions .w-muted { font-size: 13.5px; }
.w-pro-plans {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px;
  max-width: 860px; padding-top: 12px;
}
@media (max-width: 720px) { .w-pro-plans { grid-template-columns: minmax(0, 1fr); } }
.w-pro-plan { display: flex; flex-direction: column; padding: 24px 24px 22px; }
.w-pro-plan .w-price-num { margin-top: 16px; }
.w-pro-plan.is-featured { border-color: var(--w-accent-line); box-shadow: var(--w-shadow); }
.w-pro-badge {
  position: absolute; top: -12px; right: 18px; padding: 4px 10px; border-radius: 999px;
  font-family: var(--w-mono); font-size: 11px; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--w-paper); background: var(--w-accent);
}
html[lang^="zh"] .w-pro-badge { letter-spacing: .04em; }
.w-pro-cta { margin-top: auto; padding-top: 22px; }
.w-btn[aria-disabled="true"] { opacity: .55; cursor: default; }
.w-btn[aria-disabled="true"]:hover { border-color: var(--w-line-strong); transform: none; }
.w-pro-fine { max-width: 860px; margin: 16px 0 0; font-size: 13.5px; line-height: 1.6; color: var(--w-muted); }
.w-pro-section { max-width: 860px; padding-top: 56px; }
.w-pro-h {
  margin: 0; font-family: var(--w-serif); font-weight: 700; color: var(--w-ink);
  font-size: clamp(24px, 2.6vw, 32px); line-height: 1.15; letter-spacing: -.01em;
}
html[lang^="zh"] .w-pro-h { letter-spacing: 0; }
.w-pro-section .w-table-wrap { margin-top: 18px; overflow-x: auto; }
.w-pro-section table td:first-child { color: var(--w-ink); }
/* Figures stay in the column's own alignment, under its heading. */
.w-pro-section table td.w-pro-fig { font-family: var(--w-mono); font-size: 13.5px; font-variant-numeric: tabular-nums; }
.w-pro-faq details { border-bottom: 1px solid var(--w-line); padding: 14px 0; }
.w-pro-faq details:first-of-type { margin-top: 14px; border-top: 1px solid var(--w-line); }
.w-pro-faq summary { cursor: pointer; font-weight: 650; color: var(--w-ink); font-size: 16px; line-height: 1.45; }
.w-pro-faq summary:focus-visible { outline: 2px solid var(--w-accent); outline-offset: 2px; }
.w-pro-faq details p { margin: 10px 0 0; font-size: 15px; line-height: 1.65; color: var(--w-body); }

/* The reading wall's second button, for a reader who is already subscribed. */
.w-wall-alt { display: block; margin-top: 12px; font-size: 13.5px; color: var(--w-muted); }
.w-wall-alt a { color: var(--w-accent); font-weight: 600; text-decoration: none; }
.w-wall-alt a:hover { text-decoration: underline; text-underline-offset: 3px; }
