8-channel QEEG in five minutes.
戴上 8 通道腦波儀,五分鐘完成臨床級腦電評估,輸出 7 項認知指標報告。
A unified light theme and reading-first type scale for the nine sigmacog properties. Built on paper, weighed in ink — designed for clinicians, operators, and forty-something eyes that need to work all day.
The platform reads on cream paper. Every surface, every line of type, every line of rule derives from three layered ramps. Avoid pure white — its coldness on a 4K panel tires older eyes within hours of clinical use.
Seven semantic accents replace the 60+ scattered hex values currently
spread across nine repos. Every accent is vetted against
--paper-base
— the primary surface — for WCAG AA contrast or stronger.
Replaces every navy, indigo, and "primary blue" across the platform. Used for primary buttons, active nav, key headings, link color.
Inherits artisebio's signature cyan, darkened for paper. EEG and bio-signal accents, hover states, secondary key data.
Dual-purpose: positive metrics, completed states, "good" health indicators, neurofeedback reward markers.
Caution states, draft banners, "needs review" markers. Pair with #bd8411 background tint for badge / alert chips.
Errors, destructive actions, "out of credits" alerts, hard-stop indicators. Use sparingly to preserve its weight.
Secondary categorization, cognitive-task family markers, MyndScape domain labels, optional decorative role.
Hover state for sapphire buttons, emphasis headings, the deepest tint of the brand family.
Forty-something eyes don't read fonts.
They read shapes, spacing, and the courage of a system to slow down.
Body baseline lifts from 16 px to 18 px — the single most impactful change for our 40+ users. Headings de-escalate proportionally; line-height generous; tap targets ≥ 44 px. All four families are already deployed in at least one sigmacog repo, so no new font dependency.
Operation guide · sample
A clinical-grade brain-wave assessment in five minutes.
為個案戴上 8 通道腦波儀,確認每個電極都貼合頭皮。在主畫面點「連接裝置」按鈕,從藍牙清單中選擇對應的腦波儀型號。連接成功後,進入「阻抗」分頁確認每個通道阻抗低於 10 kΩ(綠色)。
阻抗通過後,於「錄製」分頁點右上角綠色「開始錄製」按鈕,引導個案放鬆並閉上眼睛。錄製時長達到設定值後系統自動停止,也可手動點「停止」結束錄製。
本評估僅供討論與訓練參考,不取代醫療專業意見。
Nine properties; nine different navies, eight different ambers, eight different greens. Every "brand role" has fragmented into a constellation of near-misses. One unified accent token absorbs them all.
The two light-theme prior arts — BrainQ10 (paper/ink/sapphire) and MyndScape (sage/forest) — already work. We collapse the seven dark repos onto BrainQ10's foundation rather than invent a new aesthetic.
Layout, structure, copy, and JavaScript are unchanged. Only color values, font-family, font-size, and line-height shift. Every dark frame on the left is current production; every light frame on the right is the proposed migration target.
建立個案、追蹤訓練進度、寄送報告 — 整合所有 sigmacog app 的個案管理面板。
建立個案、追蹤訓練進度、寄送報告 — 整合所有 sigmacog app 的個案管理面板。
| 個案 | App | 分數 |
|---|---|---|
| c_8a72f1 | EEG | 52.4 |
| c_4f93b8 | SoraMynd | 48.1 |
| c_2c815d | Poseidon | 56.7 |
| 個案 | App | 分數 |
|---|---|---|
| c_8a72f1 | EEG | 52.4 |
| c_4f93b8 | SoraMynd | 48.1 |
| c_2c815d | Poseidon | 56.7 |
Each property keeps a single accent role to preserve its identity within the family — EEG stays cyan-flavored, VisioMynd stays vermilion-flavored, SoraMynd stays jade-flavored. The shared paper-ink-rule foundation makes the family read as one product.
戴上 8 通道腦波儀,五分鐘完成臨床級腦電評估,輸出 7 項認知指標報告。
以攝影機進行非接觸式心率、HRV、血氧、呼吸與壓力指數量測。
動物主題的持續注意力表現測驗,適用兒童與成人雙模式版本。
可調頻雙耳節拍播放器,輔助放鬆、專注與情緒調節練習。
以腦波即時回饋的神經回饋訓練遊戲,四款基礎情境可調節獎勵機制。
多通道 sLORETA 來源定位神經回饋,搭配 26 個功能網絡離線分析。
13 份標準化心理與發展量表,依年齡與填答者關係自動篩選適用量表。
12 項認知作業組成的測驗套組,涵蓋注意力、工作記憶、執行功能等領域。
整合評估、監測、訓練三軸的閉環方案,將神經解碼從實驗室帶進日常生活。
The complete token set, ready to paste into each repo's
:root.
Per-repo migration touches CSS only — no JavaScript, no HTML structure,
no functional logic.
/* sigmacog design tokens v0.1 — light theme */ :root { /* paper · ink · rule */ --paper-deep: #efe9d8; --paper-base: #f6f1e4; --paper-raised: #fbf8ef; --paper-card: #ffffff; --ink-primary: #0c1620; --ink-secondary: #394a5e; --ink-muted: #6a7a8d; --ink-faint: #a2adba; --rule-strong: rgba(12,22,32,.22); --rule: rgba(12,22,32,.12); --rule-soft: rgba(12,22,32,.08); --rule-faint: rgba(12,22,32,.04); /* brand · accent · signal */ --brand: #1e4a8f; --brand-deep: #14315c; --brand-light: #4a78c2; --brand-tint: rgba(30,74,143,.08); --accent-cyan: #0e7d8e; --accent-teal: #0f8f72; --accent-lavender: #6a4bb1; --signal-warn: #8a5e08; --signal-warn-bg: #bd8411; --signal-danger: #c8442a; --signal-danger-bg: #e0654a; --signal-success: #0f8f72; /* typography */ --font-display: 'Fraunces','Noto Serif TC',Georgia,serif; --font-italic: 'Crimson Pro','Noto Serif TC',Georgia,serif; --font-body: 'IBM Plex Sans TC','Noto Sans TC',system-ui,sans-serif; --font-mono: 'IBM Plex Mono','JetBrains Mono',monospace; --text-xs: 0.875rem; --text-sm: 1rem; --text-base: 1.125rem; /* ← 40+ baseline */ --text-lg: 1.25rem; --text-xl: 1.5rem; --text-2xl: 1.875rem; --text-3xl: 2.375rem; --text-4xl: 3.125rem; --text-display: 4.5rem; --lh-tight: 1.2; --lh-snug: 1.4; --lh-base: 1.75; --lh-loose: 1.85; --tap-min: 44px; }
tokens.css in each repo — copy the same file into css/tokens.css (or framework equivalent). No build pipeline required.:root, replace declarations with token references — e.g. --navy: var(--brand-deep). Existing component CSS continues to work via the indirection.body background from var(--navy) family to var(--paper-base); flip default text color to var(--ink-primary).#xxxxxx in component CSS gets mapped to its closest token role. Estimate 30–90 minutes per repo.var(--text-base) (1.125 rem). Adjust component sizes proportionally — most will already scale via em-based padding.box-shadow: 0 0 0 3px var(--brand-tint) on :focus-visible.
Each sub-app keeps its own primary accent so operators recognise it at a glance.
The chassis (paper, ink, rule) is identical across the suite; only the brand-position
accent shifts. Do not paint a sub-app with another's identity. When
in doubt, default to --brand.
| App | Identity token | Used for |
|---|---|---|
| sgimacog EEG | --brand #5b7593 |
primary CTA, active tab, logo wordmark |
| SoraMynd NFB | --accent-teal #7a9580 + lavender-deep logo |
success cards, NFB reward state, "Sr" logo italic |
| VeloMynd CPT | --velo-indigo #7e7ea5 |
card top accent, "Ve" logo glyph, primary button, monitor dp-val |
| VisioMynd rPPG | teal→brand gradient (CVRI ring) |
CVRI score ring, step indicator done state |
| ViboMynd BNB | — pending demo | not yet migrated; audit baseline missing |
sgimacog operates 1–4 STEEG devices in parallel. Each gets a Morandi-desaturated accent; these replace the legacy high-saturation RGB palette. Per-channel waveform colors form a separate 8-color set shared across all devices — channels are identified by colour, not by device.
Five recurring failure modes burned ≈ 10 round-trips during the 2026-05-25 migration. Every one is mechanical. Run the four greps below before submitting any theme change.
--*-tint tokens are background-only
Every --*-tint in the
palette is a 12–16% alpha. Using one as a foreground color:
gives ≤ 1.5:1 contrast — invisible on paper-cream. Text colour must use
--ink-*,
--brand-deep,
--*-deep, or full-opacity accent.
grep -rnE "color: ['\"]var\(--[a-z-]+-tint\)['\"]" src/
Pre-Morandi text colours from the dark theme — pale blue, mint green, salmon — render
invisible on paper. Any rgba(1NN, 1NN, 2NN, 0.5–0.9)
in a color: property is suspect.
grep -rnE "color: ['\"]rgba\(1[0-9]{2},[12][0-9]{2}" src/
The chassis convention: cards sit on white (--paper-card),
chrome sits on cream (--paper-raised).
VeloMynd's monitor had these inverted across 10 surfaces, making cards visually receded
and chrome bright. When porting from dark theme, double-check every background.
Pre-Morandi: bright teal #48baa6 /
rgba(72,186,166, …);
lime green #80c854 /
rgba(63,185,80, …);
GitHub red #f85149 /
rgba(248,81,73, …);
per-device hi-sat #52b8d8 / #80c854 / #dc7860 / #b060c8.
grep -rnE "#48baa6|#f85149|#52b8d8|#80c854|#dc7860|#b060c8|rgba\(72,186,166" src/
Proportional fonts (Crimson Pro, Cormorant Garamond) render "1000" wider than "999".
When the value sits in a banner alongside fixed-width siblings, the row bounces with every refresh.
Two fixes: set font-variant-numeric: tabular-nums; font-feature-settings: "tnum"
on the value, and give the container a fixed
width (not just min-width).
Unlocking a UI option behind cond1 && asyncCond2 is a race trap — if
setState(asyncCond2 = true) is batched out or the resolution dispatches before the
consumer remounts, the option stays disabled forever. Decouple UI gates from compute gates.
Gate the picker by the synchronous condition only; let the compute gate sit deeper.
Two non-obvious build flags decide whether the staged bundle works on the staged Worker. Miss either and the symptom is silent — the page renders, but EEG packets never flow.
VITE_API_BASE='' when building for *-staging
Every sub-app's wasm.ts
defaults API_BASE to 'https://www.sigmacog.xyz' for prod.
A local bun run build with no env override bakes that prod URL into the
bundle — the staged bundle then fetches the WASM key from prod (different key) and
decryption fails. Always prefix with VITE_API_BASE=''
so the bundle uses same-origin (= staging.sigmacog.xyz).
VITE_API_BASE='' bun run build bunx wrangler pages deploy dist \ --project-name=<app>-staging --branch=staging --commit-dirty=true # verify: deployed bundle must contain Bt=`` (empty), not Bt=`https://www.sigmacog.xyz` PROXY=$(grep PROXY_SECRET ~/.staging-secrets | cut -d= -f2-) curl -s -H "x-proxy-secret: $PROXY" $URL/assets/main-*.js | grep -oE 'Bt=`[^`]*`'
bun run build alone copies the
raw .wasm into dist.
Runtime expects AES-GCM ciphertext. NFB & Poseidon must run
build:full (build:wasm → encrypt:wasm → build) the
first time, then incremental edits can use plain build since the encrypted blob is committed.
sgimacog auto-chains since 2026-05-02 (commit d0bf7a5).
Every theme push to staging is followed by an inline audit against the deployed bytes —
fetch the bundle, grep for the four expected fingerprints (root tokens, identity colours,
legacy hex absent, VITE_API_BASE empty). "It compiled" is not evidence the
change is live; CF Pages edge cache can serve stale bytes for hours after the deployment URL
is announced.
# post-deploy audit — minimum 4 checks curl -s -H "x-proxy-secret: $PROXY" $URL/assets/main-*.css | grep -oE '--paper-base:[^;}]+' curl -s -H "x-proxy-secret: $PROXY" $URL/assets/main-*.css | grep -oE '--brand:[^;}]+' curl -s -H "x-proxy-secret: $PROXY" $URL/assets/main-*.js | grep -oE 'Bt=`[^`]*`' curl -s -H "x-proxy-secret: $PROXY" $URL/assets/main-*.js | grep -cE '#52b8d8|#80c854|#f85149' # must be 0
| App | Source path | Staging project |
|---|---|---|
| sgimacog | /Users/swryociao/sgimacog-web/web | sgimacog-web-staging |
| SoraMynd | /Users/swryociao/NFB-Webapp/web | nfb-webapp-staging |
| VisioMynd | /Users/swryociao/rppg-webapp | rppg-web-staging |
| VeloMynd | /Users/swryociao/acpt-web (→ "Animal CPT Web" GH mirror) | animal-cpt-web-staging |