@digithings-ai/design 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +343 -2
- package/app-shell-terminal/index.js +300 -0
- package/app-shell-terminal/slash-commands.js +59 -0
- package/app-shell-terminal/styles.css +234 -0
- package/fonts.ts +15 -0
- package/html-escape.js +19 -0
- package/motion.json +6 -0
- package/package.json +48 -4
- package/palettes.css +1942 -0
- package/quant-native/styles.css +99 -0
- package/quant-native/ticker.js +100 -0
- package/releases.json +122 -0
- package/site/README.md +609 -0
- package/site/site.css +475 -0
- package/tokens.css +268 -0
- package/tokens.ts +508 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/* ==========================================================================
|
|
2
|
+
@digithings-ai/design — quant-native/styles.css
|
|
3
|
+
Scoped under `.qn-*`. Consumes tokens from ../tokens.css.
|
|
4
|
+
Muted emerald / muted copper for directional color — never Bloomberg red.
|
|
5
|
+
========================================================================== */
|
|
6
|
+
|
|
7
|
+
/* --- Blueprint background ---------------------------------------------- */
|
|
8
|
+
.qn-blueprint-bg {
|
|
9
|
+
background-image: repeating-linear-gradient(
|
|
10
|
+
to bottom,
|
|
11
|
+
rgba(255, 255, 255, 0.02) 0,
|
|
12
|
+
rgba(255, 255, 255, 0.02) 1px,
|
|
13
|
+
transparent 1px,
|
|
14
|
+
transparent 8px
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/* --- Directional colors (muted) ---------------------------------------- */
|
|
19
|
+
.qn-up { color: var(--accent-digiquant); }
|
|
20
|
+
.qn-down { color: var(--accent-digibot); }
|
|
21
|
+
|
|
22
|
+
/* WCAG 1.4.3 fix (2026-08-12, #2280): --accent-digiquant/--accent-digibot's
|
|
23
|
+
light-theme values (#0E8C7F, #b87840) are tuned to stay LIGHT ENOUGH to
|
|
24
|
+
serve as a background under .accent-<module>'s pinned dark --on-accent
|
|
25
|
+
text (tokens.css) — the opposite of what .qn-up/.qn-down need here, where
|
|
26
|
+
the token is read as literal TEXT color on the page's own light surface
|
|
27
|
+
(4.14:1/3.62:1 as measured, both under the 4.5:1 minimum for normal text).
|
|
28
|
+
Darkened locally rather than in the shared tokens: darkening the tokens
|
|
29
|
+
themselves would break their background role (see tokens.css's own
|
|
30
|
+
comment on --accent-digiquant). Same hues, deepened for paper the same
|
|
31
|
+
way --accent/--up/--down already are (tokens.css line ~208). */
|
|
32
|
+
:root[data-theme="light"] .qn-up { color: #0C7C71; }
|
|
33
|
+
:root[data-theme="light"] .qn-down { color: #976235; }
|
|
34
|
+
|
|
35
|
+
/* --- Metric (tabular numerics) ----------------------------------------- */
|
|
36
|
+
.qn-metric {
|
|
37
|
+
font-family: var(--font-family-mono);
|
|
38
|
+
font-feature-settings: "tnum" 1, "ss01" 1;
|
|
39
|
+
letter-spacing: 0.01em;
|
|
40
|
+
text-align: right;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* --- Chart frame ------------------------------------------------------- */
|
|
44
|
+
.qn-chart-frame {
|
|
45
|
+
border: 1px solid var(--hair);
|
|
46
|
+
border-radius: var(--radius-md);
|
|
47
|
+
background: var(--surface);
|
|
48
|
+
padding: var(--space-3);
|
|
49
|
+
}
|
|
50
|
+
.qn-chart-frame > svg {
|
|
51
|
+
display: block;
|
|
52
|
+
width: 100%;
|
|
53
|
+
height: auto;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/* --- Ticker ------------------------------------------------------------
|
|
57
|
+
Component sizing tokens: the tape's own band rhythm. The global scale has
|
|
58
|
+
no step for 0.625rem / 1.75rem, so these stay local rather than inventing
|
|
59
|
+
one. Declared on the ticker root; items inherit them. */
|
|
60
|
+
.qn-ticker {
|
|
61
|
+
--qn-ticker-pad-block: 0.625rem;
|
|
62
|
+
--qn-ticker-item-gap: 0.375rem;
|
|
63
|
+
--qn-ticker-item-pad-inline: 1.75rem;
|
|
64
|
+
|
|
65
|
+
position: relative;
|
|
66
|
+
overflow: hidden;
|
|
67
|
+
border-top: 1px solid var(--hair);
|
|
68
|
+
border-bottom: 1px solid var(--hair);
|
|
69
|
+
background: rgba(10, 10, 10, 0.7);
|
|
70
|
+
font-family: var(--font-family-mono);
|
|
71
|
+
font-size: 0.75rem;
|
|
72
|
+
color: var(--ink);
|
|
73
|
+
padding: var(--qn-ticker-pad-block) 0;
|
|
74
|
+
}
|
|
75
|
+
.qn-ticker-track {
|
|
76
|
+
display: inline-flex;
|
|
77
|
+
white-space: nowrap;
|
|
78
|
+
will-change: transform;
|
|
79
|
+
}
|
|
80
|
+
.qn-ticker-item {
|
|
81
|
+
display: inline-flex;
|
|
82
|
+
align-items: baseline;
|
|
83
|
+
gap: var(--qn-ticker-item-gap);
|
|
84
|
+
padding: 0 var(--qn-ticker-item-pad-inline);
|
|
85
|
+
border-right: 1px dashed var(--hair);
|
|
86
|
+
}
|
|
87
|
+
.qn-ticker-sym {
|
|
88
|
+
color: var(--ink);
|
|
89
|
+
letter-spacing: 0.04em;
|
|
90
|
+
}
|
|
91
|
+
.qn-ticker-px { margin-left: 0.125rem; }
|
|
92
|
+
.qn-ticker-delta { margin-left: 0.125rem; }
|
|
93
|
+
|
|
94
|
+
@media (prefers-reduced-motion: reduce) {
|
|
95
|
+
.qn-ticker-track {
|
|
96
|
+
transform: translateX(0) !important;
|
|
97
|
+
padding-left: var(--space-3);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/* ==========================================================================
|
|
2
|
+
@digithings-ai/design — quant-native/ticker
|
|
3
|
+
--------------------------------------------------------------------------
|
|
4
|
+
JS-driven horizontal ticker. No CSS marquee — we translate on a RAF loop
|
|
5
|
+
so the cadence is deterministic and pause-on-hover is trivial.
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
import { initTicker } from '@digithings-ai/design/quant-native';
|
|
9
|
+
import '@digithings-ai/design/quant-native/styles.css';
|
|
10
|
+
|
|
11
|
+
initTicker({
|
|
12
|
+
elementId: 'ticker',
|
|
13
|
+
symbols: [{ sym: 'RESEARCH', price: '184.22', delta: '+0.42%' }],
|
|
14
|
+
cadence: 60, // px/sec
|
|
15
|
+
});
|
|
16
|
+
Ticker rows use DOM APIs (textContent), not innerHTML (DESLOP-028 / wave 7h).
|
|
17
|
+
========================================================================== */
|
|
18
|
+
|
|
19
|
+
function buildRow(symbols) {
|
|
20
|
+
const frag = document.createDocumentFragment();
|
|
21
|
+
for (const s of symbols) {
|
|
22
|
+
const item = document.createElement('span');
|
|
23
|
+
item.className = 'qn-ticker-item';
|
|
24
|
+
const dir = typeof s.delta === 'string' && s.delta.trim().startsWith('-') ? 'down' : 'up';
|
|
25
|
+
const sym = document.createElement('span');
|
|
26
|
+
sym.className = 'qn-ticker-sym';
|
|
27
|
+
sym.textContent = String(s.sym ?? '');
|
|
28
|
+
const px = document.createElement('span');
|
|
29
|
+
px.className = 'qn-metric qn-ticker-px';
|
|
30
|
+
px.textContent = String(s.price ?? '');
|
|
31
|
+
const delta = document.createElement('span');
|
|
32
|
+
delta.className = `qn-${dir} qn-ticker-delta`;
|
|
33
|
+
delta.textContent = String(s.delta ?? '');
|
|
34
|
+
item.append(sym, px, delta);
|
|
35
|
+
frag.appendChild(item);
|
|
36
|
+
}
|
|
37
|
+
return frag;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function initTicker({ elementId, symbols, cadence = 60 } = {}) {
|
|
41
|
+
const host = document.getElementById(elementId);
|
|
42
|
+
if (!host) throw new Error(`initTicker: no element with id "${elementId}"`);
|
|
43
|
+
if (!Array.isArray(symbols) || symbols.length === 0) return { destroy() {} };
|
|
44
|
+
|
|
45
|
+
const prefersReduced = typeof window !== 'undefined'
|
|
46
|
+
&& window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
47
|
+
|
|
48
|
+
host.classList.add('qn-ticker');
|
|
49
|
+
host.replaceChildren();
|
|
50
|
+
const track = document.createElement('div');
|
|
51
|
+
track.className = 'qn-ticker-track';
|
|
52
|
+
// Duplicate so the seam is always off-screen.
|
|
53
|
+
track.appendChild(buildRow(symbols));
|
|
54
|
+
track.appendChild(buildRow(symbols));
|
|
55
|
+
host.appendChild(track);
|
|
56
|
+
|
|
57
|
+
let offset = 0;
|
|
58
|
+
let last = 0;
|
|
59
|
+
let raf = 0;
|
|
60
|
+
let paused = false;
|
|
61
|
+
|
|
62
|
+
function measureHalf() {
|
|
63
|
+
// Total track width / 2 — equals one full sequence.
|
|
64
|
+
return track.scrollWidth / 2;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function frame(now) {
|
|
68
|
+
if (!last) last = now;
|
|
69
|
+
const dt = (now - last) / 1000;
|
|
70
|
+
last = now;
|
|
71
|
+
if (!paused) {
|
|
72
|
+
offset += cadence * dt;
|
|
73
|
+
const half = measureHalf();
|
|
74
|
+
if (offset >= half) offset -= half;
|
|
75
|
+
track.style.transform = `translateX(${-offset}px)`;
|
|
76
|
+
}
|
|
77
|
+
raf = requestAnimationFrame(frame);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (prefersReduced) {
|
|
81
|
+
track.style.transform = 'translateX(0)';
|
|
82
|
+
} else {
|
|
83
|
+
raf = requestAnimationFrame(frame);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const onEnter = () => { paused = true; };
|
|
87
|
+
const onLeave = () => { paused = false; last = 0; };
|
|
88
|
+
host.addEventListener('mouseenter', onEnter);
|
|
89
|
+
host.addEventListener('mouseleave', onLeave);
|
|
90
|
+
|
|
91
|
+
return {
|
|
92
|
+
destroy() {
|
|
93
|
+
if (raf) cancelAnimationFrame(raf);
|
|
94
|
+
host.removeEventListener('mouseenter', onEnter);
|
|
95
|
+
host.removeEventListener('mouseleave', onLeave);
|
|
96
|
+
host.replaceChildren();
|
|
97
|
+
host.classList.remove('qn-ticker');
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
package/releases.json
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"date": "2026-09-29",
|
|
4
|
+
"version": "digichat v2.4.0",
|
|
5
|
+
"title": "Search-engine preference, container license heartbeat, and the single-route embed",
|
|
6
|
+
"href": "https://github.com/digithings-ai/digithings/releases/tag/digichat-v2.4.0",
|
|
7
|
+
"tag": "release",
|
|
8
|
+
"product": "digichat"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"date": "2026-09-21",
|
|
12
|
+
"version": "digichat v2.3.2",
|
|
13
|
+
"title": "The embed Send button submits the composer, so the free-turn gate sees it",
|
|
14
|
+
"href": "https://github.com/digithings-ai/digithings/releases/tag/digichat-v2.3.2",
|
|
15
|
+
"tag": "fix",
|
|
16
|
+
"product": "digichat"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"date": "2026-09-20",
|
|
20
|
+
"version": "digichat v2.3.1",
|
|
21
|
+
"title": "The embed paints one canvas token from the first byte",
|
|
22
|
+
"href": "https://github.com/digithings-ai/digithings/releases/tag/digichat-v2.3.1",
|
|
23
|
+
"tag": "fix",
|
|
24
|
+
"product": "digichat"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"date": "2026-09-19",
|
|
28
|
+
"version": "digichat v2.3.0",
|
|
29
|
+
"title": "Config-driven welcome copy, pre-painted theme frame, kit promotions for the sites rebuild",
|
|
30
|
+
"href": "https://github.com/digithings-ai/digithings/releases/tag/digichat-v2.3.0",
|
|
31
|
+
"tag": "release",
|
|
32
|
+
"product": "digichat"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"date": "2026-09-16",
|
|
36
|
+
"version": "digichat v2.2.0",
|
|
37
|
+
"title": "Retryable upstream-failure card, configurable view modes, Gloomberb attribution, hosted MCP servers",
|
|
38
|
+
"href": "https://github.com/digithings-ai/digithings/releases/tag/digichat-v2.2.0",
|
|
39
|
+
"tag": "release",
|
|
40
|
+
"product": "digichat"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"date": "2026-09-16",
|
|
44
|
+
"version": "digichat v2.1.0",
|
|
45
|
+
"title": "Assistant-ui parity, DataTap trial embed, painted block caret, read-only ticket MCP",
|
|
46
|
+
"href": "https://github.com/digithings-ai/digithings/releases/tag/digichat-v2.1.0",
|
|
47
|
+
"tag": "release",
|
|
48
|
+
"product": "digichat"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"date": "2026-09-05",
|
|
52
|
+
"version": "digichat v1.5.0",
|
|
53
|
+
"title": "Sidebar search, markdown copy, regen and edit, opt-in web search, popup widget embed, slash palette",
|
|
54
|
+
"href": "https://github.com/digithings-ai/digithings/releases/tag/digichat-v1.5.0",
|
|
55
|
+
"tag": "release",
|
|
56
|
+
"product": "digichat"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"date": "2026-09-02",
|
|
60
|
+
"version": "digichat v1.4.0",
|
|
61
|
+
"title": "Utilitarian-terminal composer chrome and BYOK hardening follow-ups",
|
|
62
|
+
"href": "https://github.com/digithings-ai/digithings/releases/tag/digichat-v1.4.0",
|
|
63
|
+
"tag": "release",
|
|
64
|
+
"product": "digichat"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"date": "2026-08-21",
|
|
68
|
+
"version": "digichat v1.3.2",
|
|
69
|
+
"title": "Kill a dead BYOK auth argument and a refusal that named the wrong model",
|
|
70
|
+
"href": "https://github.com/digithings-ai/digithings/releases/tag/digichat-v1.3.2",
|
|
71
|
+
"tag": "fix",
|
|
72
|
+
"product": "digichat"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"date": "2026-08-20",
|
|
76
|
+
"version": "digichat v1.3.1",
|
|
77
|
+
"title": "Tell an embed visitor a BYOK refusal is fixable",
|
|
78
|
+
"href": "https://github.com/digithings-ai/digithings/releases/tag/digichat-v1.3.1",
|
|
79
|
+
"tag": "fix",
|
|
80
|
+
"product": "digichat"
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"date": "2026-08-15",
|
|
84
|
+
"version": "digichat v1.3.0",
|
|
85
|
+
"title": "BYOK provider/model catalog and live model list at the key step",
|
|
86
|
+
"href": "https://github.com/digithings-ai/digithings/releases/tag/digichat-v1.3.0",
|
|
87
|
+
"tag": "release",
|
|
88
|
+
"product": "digichat"
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"date": "2026-08-15",
|
|
92
|
+
"version": "digiskills v0.2.1",
|
|
93
|
+
"title": "Move pytest/ruff into a uv dependency-group",
|
|
94
|
+
"href": "https://github.com/digithings-ai/digithings/releases/tag/digiskills-v0.2.1",
|
|
95
|
+
"tag": "fix",
|
|
96
|
+
"product": "digiskills"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"date": "2026-08-13",
|
|
100
|
+
"version": "digichat v1.2.0",
|
|
101
|
+
"title": "Mermaid/code-block rendering on the primary chat page; agentic retrieval",
|
|
102
|
+
"href": "https://github.com/digithings-ai/digithings/releases/tag/digichat-v1.2.0",
|
|
103
|
+
"tag": "release",
|
|
104
|
+
"product": "digichat"
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"date": "2026-08-11",
|
|
108
|
+
"version": "digichat v1.1.0",
|
|
109
|
+
"title": "Curated language list, browser detection, and response-language header",
|
|
110
|
+
"href": "https://github.com/digithings-ai/digithings/releases/tag/digichat-v1.1.0",
|
|
111
|
+
"tag": "release",
|
|
112
|
+
"product": "digichat"
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"date": "2026-07-10",
|
|
116
|
+
"version": "digiskills v0.2.0",
|
|
117
|
+
"title": "Skill compiler core, CLI corpus-cap flags, remote-ingestion hardening",
|
|
118
|
+
"href": "https://github.com/digithings-ai/digithings/releases/tag/digiskills-v0.2.0",
|
|
119
|
+
"tag": "release",
|
|
120
|
+
"product": "digiskills"
|
|
121
|
+
}
|
|
122
|
+
]
|