@fasl-work/caos-app-shell 0.1.2 → 0.3.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/styles.css CHANGED
@@ -1,221 +1,242 @@
1
- @import "katex/dist/katex.min.css";
2
-
3
- /* @fasl-work/caos-app-shell — shared design system (ADR-0016 + visual-standards palette).
4
- * Theming via CSS custom properties keyed on data-theme on <html> (set pre-paint by an inline
5
- * script in index.html, kept in sync by the shell theme store). Import once per app:
6
- * import "@fasl-work/caos-app-shell/styles.css"; */
7
-
8
- :root,
9
- [data-theme="dark"] {
10
- --color-bg: #0d1117;
11
- --color-surface: #161b22;
12
- --color-surface-2: #1c2230;
13
- --color-border: #30363d;
14
- --color-fg: #c9d1d9;
15
- --color-fg-subtle: #9aa6b2;
16
- --color-fg-faint: #6c7785;
17
- --color-accent: #58a6ff;
18
- --color-accent-fg: #0d1117;
19
- --color-accent-soft: #132036;
20
- --color-accent-2: #3fb1c8;
21
- --color-magenta: #f778ba;
22
- --color-good: #3fb950;
23
- --color-warn: #d29922;
24
- --color-bad: #f85149;
25
- --color-shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 6px 16px rgba(0, 0, 0, 0.45);
26
- --font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
27
- --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
28
- --maxw: 1200px;
29
- }
30
-
31
- [data-theme="light"] {
32
- --color-bg: #f6f8fa;
33
- --color-surface: #ffffff;
34
- --color-surface-2: #f0f3f6;
35
- --color-border: #d0d7de;
36
- --color-fg: #1f2328;
37
- --color-fg-subtle: #57606a;
38
- --color-fg-faint: #6e7781;
39
- --color-accent: #0969da;
40
- --color-accent-fg: #ffffff;
41
- --color-accent-soft: #ddf4ff;
42
- --color-accent-2: #0a7c8a;
43
- --color-magenta: #bf3989;
44
- --color-good: #1a7f37;
45
- --color-warn: #9a6700;
46
- --color-bad: #cf222e;
47
- --color-shadow: 0 1px 2px rgba(31, 35, 40, 0.06), 0 4px 10px rgba(31, 35, 40, 0.04);
48
- }
49
-
50
- * { box-sizing: border-box; }
51
- html, body, #root { height: 100%; }
52
- body {
53
- margin: 0;
54
- font-family: var(--font-sans);
55
- background-color: var(--color-bg);
56
- color: var(--color-fg);
57
- -webkit-font-smoothing: antialiased;
58
- -moz-osx-font-smoothing: grayscale;
59
- line-height: 1.55;
60
- }
61
- a { color: var(--color-accent); text-decoration: none; }
62
- a:hover { text-decoration: underline; }
63
- button { font: inherit; cursor: pointer; color: inherit; }
64
- h1, h2, h3, h4 { line-height: 1.2; font-weight: 650; letter-spacing: -0.01em; }
65
- code, kbd { font-family: var(--font-mono); }
66
-
67
- /* ── Layout primitives ── */
68
- .app-shell { min-height: 100vh; display: flex; flex-direction: column; background: var(--color-bg); color: var(--color-fg); }
69
- .container { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: 1.5rem; }
70
- .page { flex: 1 1 auto; width: 100%; }
71
- .page-body { width: 100%; max-width: var(--maxw); margin-inline: auto; padding: 2.25rem 1.5rem 3rem; }
72
- .muted { color: var(--color-fg-subtle); }
73
- .faint { color: var(--color-fg-faint); }
74
- .mono { font-family: var(--font-mono); font-size: 0.9em; }
75
- .small { font-size: 0.84rem; }
76
- .card { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: 10px; padding: 1.25rem 1.5rem; box-shadow: var(--color-shadow); }
77
- .badge { display: inline-flex; align-items: center; gap: 0.35rem; font-size: 0.78rem; padding: 0.15rem 0.55rem; border-radius: 999px; border: 1px solid var(--color-border); background: var(--color-surface-2); color: var(--color-fg-subtle); }
78
- .badge.live { color: var(--color-good); border-color: color-mix(in oklab, var(--color-good) 45%, transparent); }
79
- .badge.precomputed, .badge.accent { color: var(--color-accent); border-color: color-mix(in oklab, var(--color-accent) 45%, transparent); }
80
- .badge.warn { color: var(--color-warn); border-color: color-mix(in oklab, var(--color-warn) 45%, transparent); }
81
-
82
- /* ── Header ── */
83
- .site-header { position: sticky; top: 0; z-index: 50; border-bottom: 1px solid var(--color-border); background: color-mix(in oklab, var(--color-bg) 82%, transparent); backdrop-filter: blur(8px); }
84
- .header-inner { max-width: var(--maxw); margin-inline: auto; height: 56px; padding-inline: 1.5rem; display: flex; align-items: center; gap: 1rem; }
85
- .brand { display: inline-flex; align-items: center; gap: 0.5rem; font-weight: 700; letter-spacing: -0.02em; color: var(--color-fg); }
86
- .brand:hover { text-decoration: none; }
87
- .brand .brand-mark { color: var(--color-accent); display: inline-flex; flex: none; }
88
- .main-nav { display: flex; align-items: center; gap: 0.15rem; }
89
- .nav-link { padding: 0.4rem 0.7rem; border-radius: 6px; font-size: 0.9rem; color: var(--color-fg-subtle); transition: color 0.15s, background-color 0.15s; }
90
- .nav-link:hover { text-decoration: none; color: var(--color-fg); }
91
- .nav-link.active { color: var(--color-accent); background: var(--color-accent-soft); font-weight: 600; }
92
- .header-actions { margin-left: auto; display: inline-flex; align-items: center; gap: 0.15rem; }
93
- .icon-btn { display: inline-flex; align-items: center; justify-content: center; gap: 0.3rem; padding: 0.4rem 0.5rem; border-radius: 6px; background: transparent; border: none; color: var(--color-fg-subtle); opacity: 0.85; transition: opacity 0.15s, color 0.15s; }
94
- .icon-btn:hover { opacity: 1; color: var(--color-fg); text-decoration: none; }
95
- .icon-btn svg { display: block; flex: none; }
96
- .lang-code { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.06em; font-weight: 600; }
97
- .header-sep { width: 1px; height: 20px; margin-inline: 0.4rem; background: var(--color-border); }
98
-
99
- /* ── Footer ── */
100
- .site-footer { border-top: 1px solid var(--color-border); margin-top: 3rem; background: var(--color-surface); }
101
- .footer-inner { max-width: var(--maxw); margin-inline: auto; padding: 1.5rem; display: flex; flex-direction: column; gap: 0.9rem; font-size: 0.85rem; color: var(--color-fg-faint); }
102
- .footer-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.75rem; }
103
- .footer-build { margin-left: auto; font-family: var(--font-mono); font-size: 0.72rem; color: var(--color-fg-faint); display: inline-flex; gap: 0.6rem; flex-wrap: wrap; }
104
-
105
- /* ── Misc ── */
106
- .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
107
- :where(a[href], button:not([disabled]), [tabindex]:not([tabindex="-1"])):focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; border-radius: 4px; }
108
- @media (max-width: 760px) { .main-nav { display: none; } }
109
- @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; } }
110
-
111
- /* ── Prose / content pages ── (fill the page-body width with grids/figures/sub-tab rails, not a narrow column) */
112
- .prose { font-size: 0.98rem; }
113
- .prose section { margin-block: 1.75rem; }
114
- .measure { max-width: 70ch; }
115
- .fig-row { display: grid; grid-template-columns: 1.1fr 1fr; gap: 1.5rem; align-items: center; margin-block: 1.5rem; }
116
- .fig-row.rev { grid-template-columns: 1fr 1.1fr; }
117
- @media (max-width: 820px) { .fig-row, .fig-row.rev { grid-template-columns: 1fr; } }
118
- .def-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1rem; margin-block: 1.25rem; }
119
- .def { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: 10px; padding: 0.9rem 1.1rem; }
120
- .def h4 { margin: 0 0 0.3rem; color: var(--color-accent); font-size: 0.95rem; }
121
- .def p { margin: 0; font-size: 0.9rem; color: var(--color-fg-subtle); }
122
- .assume { margin-block: 1rem; padding: 0.85rem 1rem; background: var(--color-surface-2); border: 1px solid var(--color-border); border-radius: 8px; }
123
- .assume-title { margin: 0 0 0.4rem; font-size: 0.76rem; font-weight: 650; text-transform: uppercase; letter-spacing: 0.04em; color: var(--color-fg-faint); }
124
- .assume ul { margin: 0; padding-left: 1.2rem; color: var(--color-fg-subtle); }
125
- .assume li { margin-block: 0.3rem; font-size: 0.92rem; }
126
- .references { margin-top: 2.5rem; border-top: 1px solid var(--color-border); padding-top: 1rem; }
127
- .reference-list { font-size: 0.85rem; color: var(--color-fg-subtle); line-height: 1.5; padding-left: 1.4rem; }
128
- .reference-list li { margin-block: 0.5rem; }
129
- .cite-inline { font-style: normal; font-size: 0.92em; color: var(--color-fg-subtle); }
130
- .th-refs { margin-top: 1.25rem; padding-top: 0.6rem; border-top: 1px dashed var(--color-border); font-size: 0.85rem; color: var(--color-fg-subtle); }
131
- .th-refs-label { font-weight: 650; color: var(--color-fg-faint); }
132
- .prose h2 { font-size: 1.3rem; margin-block: 1.4rem 0.6rem; }
133
- .prose h3 { font-size: 1.06rem; margin-block: 1.1rem 0.4rem; }
134
- .prose p { margin-block: 0.6rem; }
135
- .prose ul, .prose ol { margin-block: 0.5rem; padding-left: 1.3rem; }
136
- .prose li { margin-block: 0.35rem; }
137
- .page-head { border-bottom: 1px solid var(--color-border); padding-bottom: 1rem; margin-bottom: 1.25rem; }
138
- .page-head h1 { font-size: 1.7rem; margin: 0 0 0.4rem; }
139
- .lede { color: var(--color-fg-subtle); font-size: 1.08rem; margin: 0; max-width: 70ch; }
140
- .two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 1.25rem; margin-block: 1.5rem; }
141
- @media (max-width: 760px) { .two-col { grid-template-columns: 1fr; } }
142
- .tick-list, .cross-list { list-style: none; padding-left: 0; margin: 0.4rem 0 0; }
143
- .tick-list li, .cross-list li { position: relative; padding-left: 1.5rem; margin-block: 0.5rem; }
144
- .tick-list li::before { content: "✓"; position: absolute; left: 0; color: var(--color-good); font-weight: 700; }
145
- .cross-list li::before { content: "✕"; position: absolute; left: 0; color: var(--color-fg-faint); font-weight: 700; }
146
-
147
- /* ── Callouts ── */
148
- .callout { margin-block: 1rem; padding: 0.8rem 1.1rem; border-left: 3px solid var(--color-border); background: var(--color-surface-2); border-radius: 0 8px 8px 0; }
149
- .callout-honest { border-left-color: var(--color-warn); }
150
- .callout-strong { border-left-color: var(--color-accent); background: var(--color-accent-soft); }
151
- .callout-note { border-left-color: var(--color-fg-faint); }
152
- .callout-title { font-weight: 650; margin: 0 0 0.4rem; color: var(--color-fg); }
153
- .callout-body { color: var(--color-fg-subtle); }
154
- .callout-body p:first-child { margin-top: 0; }
155
- .callout-body p:last-child { margin-bottom: 0; }
156
-
157
- /* ── Tabs ── */
158
- .tablist { display: flex; gap: 0.35rem; padding-bottom: 0.6rem; margin-bottom: 1.5rem; border-bottom: 1px solid var(--color-border); flex-wrap: wrap; }
159
- .tab { padding: 0.5rem 1rem; border: 1px solid transparent; border-radius: 8px; background: transparent; color: var(--color-fg-subtle); font-size: 0.92rem; font-weight: 550; transition: color 0.15s, background-color 0.15s, border-color 0.15s; }
160
- .tab:hover { color: var(--color-fg); background: var(--color-surface-2); }
161
- .tab.active { color: var(--color-accent); background: var(--color-accent-soft); border-color: color-mix(in oklab, var(--color-accent) 35%, transparent); font-weight: 650; }
162
- .tabpanel:focus, .subtabpanel:focus { outline: none; }
163
- .subtabs { margin-block: 1rem; }
164
- .subtablist { display: flex; gap: 0.3rem; flex-wrap: wrap; margin-bottom: 1.1rem; }
165
- .subtab { padding: 0.32rem 0.8rem; border: 1px solid var(--color-border); border-radius: 999px; background: var(--color-surface); color: var(--color-fg-subtle); font-size: 0.84rem; font-weight: 500; transition: color 0.15s, background-color 0.15s, border-color 0.15s; }
166
- .subtab:hover { color: var(--color-fg); border-color: var(--color-fg-faint); }
167
- .subtab.active { color: var(--color-accent); background: var(--color-accent-soft); border-color: color-mix(in oklab, var(--color-accent) 40%, transparent); font-weight: 600; }
168
- .subtabs-vertical { display: grid; grid-template-columns: minmax(180px, 240px) 1fr; gap: 1.5rem; align-items: start; }
169
- .subtabs-vertical .subtablist { flex-direction: column; margin-bottom: 0; }
170
- .subtabs-vertical .subtab { text-align: left; border-radius: 8px; }
171
- @media (max-width: 760px) { .subtabs-vertical { grid-template-columns: 1fr; } .subtabs-vertical .subtablist { flex-direction: row; } }
172
-
173
- /* ── Equations / figures ── */
174
- .equation { margin: 1rem 0; padding: 0.9rem 1rem; background: var(--color-surface); border: 1px solid var(--color-border); border-radius: 8px; overflow-x: auto; }
175
- .equation-caption { margin-top: 0.5rem; font-size: 0.82rem; color: var(--color-fg-faint); text-align: center; }
176
- .katex { color: var(--color-fg); }
177
- .figure { margin: 1.5rem 0; }
178
- .figure-caption, .fig-cap { text-align: center; font-size: 0.84rem; color: var(--color-fg-faint); margin-top: 0.6rem; font-style: italic; }
179
-
180
- /* ── Theme-aware inline SVG figures (teaching diagrams) ── */
181
- .fig-svg { width: 100%; max-width: 560px; height: auto; display: block; margin-inline: auto; }
182
- .fig-svg.wide { max-width: 760px; }
183
- .dg-axis { stroke: var(--color-fg-faint); stroke-width: 1.3; }
184
- .dg-axis-label { fill: var(--color-fg-subtle); font: 12px var(--font-sans); }
185
- .dg-tick { fill: var(--color-fg-faint); font: 11px var(--font-mono); }
186
- .dg-grid { stroke: var(--color-border); stroke-width: 0.5; opacity: 0.6; }
187
- .dg-curve { fill: none; stroke: var(--color-accent); stroke-width: 2.2; stroke-linejoin: round; }
188
- .dg-curve-2 { fill: none; stroke: var(--color-magenta); stroke-width: 2; }
189
- .dg-curve-faint { fill: none; stroke: var(--color-fg-faint); stroke-width: 1.4; stroke-dasharray: 4 3; }
190
- .dg-asymptote { stroke: var(--color-bad); stroke-width: 1.4; stroke-dasharray: 4 4; }
191
- .dg-marker { stroke: var(--color-warn); stroke-width: 1.2; stroke-dasharray: 3 3; }
192
- .dg-marker-label { fill: var(--color-warn); font: 600 11px var(--font-mono); }
193
- .dg-note { fill: var(--color-fg-faint); font: italic 11px var(--font-sans); }
194
- .dg-fill-accent { fill: color-mix(in oklab, var(--color-accent) 16%, transparent); stroke: var(--color-accent); stroke-width: 1; }
195
- .dg-fill-warn { fill: color-mix(in oklab, var(--color-warn) 16%, transparent); stroke: var(--color-warn); stroke-width: 1; }
196
- .dg-box { fill: var(--color-surface); stroke: var(--color-border); stroke-width: 1.3; }
197
- .dg-box.accent { stroke: var(--color-accent); fill: var(--color-accent-soft); }
198
- .dg-box.good { stroke: var(--color-good); }
199
- .dg-box-title { fill: var(--color-fg); font: 650 12px var(--font-sans); }
200
- .dg-box-title.accent { fill: var(--color-accent); }
201
- .dg-box-sub { fill: var(--color-fg-subtle); font: 10.5px var(--font-mono); }
202
- .dg-node { fill: var(--color-surface); stroke: var(--color-accent); stroke-width: 1.4; }
203
- .dg-node-label { fill: var(--color-fg); font: 600 12px var(--font-mono); }
204
- .dg-edge { stroke: var(--color-fg-faint); stroke-width: 1.4; fill: none; }
205
- .dg-edge-label { fill: var(--color-fg-subtle); font: 11px var(--font-mono); }
206
- .dg-arrowhead { fill: var(--color-fg-faint); }
207
- .dg-bar { fill: var(--color-accent); }
208
- .dg-bar-2 { fill: var(--color-magenta); }
209
- .dg-bar-label { fill: var(--color-fg-subtle); font: 11px var(--font-sans); }
210
-
211
- /* ── Generic controls ── */
212
- .btn { border: 1px solid var(--color-border); background: var(--color-surface-2); color: var(--color-fg); padding: 0.4rem 0.9rem; border-radius: 8px; font-weight: 600; font-size: 0.88rem; display: inline-flex; align-items: center; gap: 0.35rem; }
213
- .btn:hover { border-color: var(--color-fg-faint); }
214
- .btn.primary { background: var(--color-accent); color: var(--color-accent-fg); border-color: var(--color-accent); }
215
- .btn:disabled { opacity: 0.5; cursor: default; }
216
- .select { background: var(--color-surface-2); color: var(--color-fg); border: 1px solid var(--color-border); border-radius: 8px; padding: 0.35rem 0.5rem; font-size: 0.85rem; }
217
- .hint { font-size: 0.8rem; color: var(--color-fg-faint); margin: 0; }
218
- .banner { padding: 0.6rem 0.9rem; border-radius: 8px; font-size: 0.85rem; margin-block: 0.6rem; border-left: 3px solid var(--color-border); background: var(--color-surface-2); }
219
- .banner.warn { border-left-color: var(--color-warn); color: var(--color-warn); }
220
- .banner.error { border-left-color: var(--color-bad); color: var(--color-bad); }
221
- .range { width: 100%; accent-color: var(--color-accent); }
1
+ @import "katex/dist/katex.min.css";
2
+
3
+ /* @fasl-work/caos-app-shell — shared design system (ADR-0016 + visual-standards palette).
4
+ * Theming via CSS custom properties keyed on data-theme on <html> (set pre-paint by an inline
5
+ * script in index.html, kept in sync by the shell theme store). Import once per app:
6
+ * import "@fasl-work/caos-app-shell/styles.css"; */
7
+
8
+ :root,
9
+ [data-theme="dark"] {
10
+ --color-bg: #0d1117;
11
+ --color-surface: #161b22;
12
+ --color-surface-2: #1c2230;
13
+ --color-border: #30363d;
14
+ --color-fg: #c9d1d9;
15
+ --color-fg-subtle: #9aa6b2;
16
+ --color-fg-faint: #6c7785;
17
+ --color-accent: #58a6ff;
18
+ --color-accent-fg: #0d1117;
19
+ --color-accent-soft: #132036;
20
+ --color-accent-2: #3fb1c8;
21
+ --color-magenta: #f778ba;
22
+ --color-good: #3fb950;
23
+ --color-warn: #d29922;
24
+ --color-bad: #f85149;
25
+ --color-shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 6px 16px rgba(0, 0, 0, 0.45);
26
+ --font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
27
+ --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
28
+ --maxw: 1200px;
29
+ }
30
+
31
+ [data-theme="light"] {
32
+ --color-bg: #f6f8fa;
33
+ --color-surface: #ffffff;
34
+ --color-surface-2: #f0f3f6;
35
+ --color-border: #d0d7de;
36
+ --color-fg: #1f2328;
37
+ --color-fg-subtle: #57606a;
38
+ --color-fg-faint: #6e7781;
39
+ --color-accent: #0969da;
40
+ --color-accent-fg: #ffffff;
41
+ --color-accent-soft: #ddf4ff;
42
+ --color-accent-2: #0a7c8a;
43
+ --color-magenta: #bf3989;
44
+ --color-good: #1a7f37;
45
+ --color-warn: #9a6700;
46
+ --color-bad: #cf222e;
47
+ --color-shadow: 0 1px 2px rgba(31, 35, 40, 0.06), 0 4px 10px rgba(31, 35, 40, 0.04);
48
+ }
49
+
50
+ * { box-sizing: border-box; }
51
+ html, body, #root { height: 100%; }
52
+ body {
53
+ margin: 0;
54
+ font-family: var(--font-sans);
55
+ background-color: var(--color-bg);
56
+ color: var(--color-fg);
57
+ -webkit-font-smoothing: antialiased;
58
+ -moz-osx-font-smoothing: grayscale;
59
+ line-height: 1.55;
60
+ }
61
+ a { color: var(--color-accent); text-decoration: none; }
62
+ a:hover { text-decoration: underline; }
63
+ button { font: inherit; cursor: pointer; color: inherit; }
64
+ h1, h2, h3, h4 { line-height: 1.2; font-weight: 650; letter-spacing: -0.01em; }
65
+ code, kbd { font-family: var(--font-mono); }
66
+
67
+ /* ── Layout primitives ── */
68
+ .app-shell { min-height: 100vh; display: flex; flex-direction: column; background: var(--color-bg); color: var(--color-fg); }
69
+ .container { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: 1.5rem; }
70
+ .page { flex: 1 1 auto; width: 100%; }
71
+ .page-body { width: 100%; max-width: var(--maxw); margin-inline: auto; padding: 2.25rem 1.5rem 3rem; }
72
+ .muted { color: var(--color-fg-subtle); }
73
+ .faint { color: var(--color-fg-faint); }
74
+ .mono { font-family: var(--font-mono); font-size: 0.9em; }
75
+ .small { font-size: 0.84rem; }
76
+ .card { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: 10px; padding: 1.25rem 1.5rem; box-shadow: var(--color-shadow); }
77
+ .badge { display: inline-flex; align-items: center; gap: 0.35rem; font-size: 0.78rem; padding: 0.15rem 0.55rem; border-radius: 999px; border: 1px solid var(--color-border); background: var(--color-surface-2); color: var(--color-fg-subtle); }
78
+ .badge.live { color: var(--color-good); border-color: color-mix(in oklab, var(--color-good) 45%, transparent); }
79
+ .badge.precomputed, .badge.accent { color: var(--color-accent); border-color: color-mix(in oklab, var(--color-accent) 45%, transparent); }
80
+ .badge.warn { color: var(--color-warn); border-color: color-mix(in oklab, var(--color-warn) 45%, transparent); }
81
+
82
+ /* ── Header ── */
83
+ .site-header { position: sticky; top: 0; z-index: 50; border-bottom: 1px solid var(--color-border); background: color-mix(in oklab, var(--color-bg) 82%, transparent); backdrop-filter: blur(8px); }
84
+ .header-inner { max-width: var(--maxw); margin-inline: auto; height: 56px; padding-inline: 1.5rem; display: flex; align-items: center; gap: 1rem; }
85
+ .brand { display: inline-flex; align-items: center; gap: 0.5rem; font-weight: 700; letter-spacing: -0.02em; color: var(--color-fg); }
86
+ .brand:hover { text-decoration: none; }
87
+ .brand .brand-mark { color: var(--color-accent); display: inline-flex; flex: none; }
88
+ .main-nav { display: flex; align-items: center; gap: 0.15rem; }
89
+ .nav-link { padding: 0.4rem 0.7rem; border-radius: 6px; font-size: 0.9rem; color: var(--color-fg-subtle); transition: color 0.15s, background-color 0.15s; }
90
+ .nav-link:hover { text-decoration: none; color: var(--color-fg); }
91
+ .nav-link.active { color: var(--color-accent); background: var(--color-accent-soft); font-weight: 600; }
92
+ .header-actions { margin-left: auto; display: inline-flex; align-items: center; gap: 0.15rem; }
93
+ .icon-btn { display: inline-flex; align-items: center; justify-content: center; gap: 0.3rem; padding: 0.4rem 0.5rem; border-radius: 6px; background: transparent; border: none; color: var(--color-fg-subtle); opacity: 0.85; transition: opacity 0.15s, color 0.15s; }
94
+ .icon-btn:hover { opacity: 1; color: var(--color-fg); text-decoration: none; }
95
+ .icon-btn svg { display: block; flex: none; }
96
+ .lang-code { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.06em; font-weight: 600; }
97
+ .header-sep { width: 1px; height: 20px; margin-inline: 0.4rem; background: var(--color-border); }
98
+
99
+ /* ── Footer ── */
100
+ .site-footer { border-top: 1px solid var(--color-border); margin-top: 3rem; background: var(--color-surface); }
101
+ .footer-inner { max-width: var(--maxw); margin-inline: auto; padding: 1.5rem; display: flex; flex-direction: column; gap: 0.9rem; font-size: 0.85rem; color: var(--color-fg-faint); }
102
+ .footer-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.75rem; }
103
+ .footer-build { margin-left: auto; font-family: var(--font-mono); font-size: 0.72rem; color: var(--color-fg-faint); display: inline-flex; gap: 0.6rem; flex-wrap: wrap; }
104
+
105
+ /* ── Misc ── */
106
+ .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
107
+ :where(a[href], button:not([disabled]), [tabindex]:not([tabindex="-1"])):focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; border-radius: 4px; }
108
+ @media (max-width: 760px) { .main-nav { display: none; } }
109
+ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; } }
110
+
111
+ /* ── Prose / content pages ── (fill the page-body width with grids/figures/sub-tab rails, not a narrow column) */
112
+ .prose { font-size: 0.98rem; }
113
+ .prose section { margin-block: 1.75rem; }
114
+ .measure { max-width: 70ch; }
115
+ .fig-row { display: grid; grid-template-columns: 1.1fr 1fr; gap: 1.5rem; align-items: center; margin-block: 1.5rem; }
116
+ .fig-row.rev { grid-template-columns: 1fr 1.1fr; }
117
+ @media (max-width: 820px) { .fig-row, .fig-row.rev { grid-template-columns: 1fr; } }
118
+ .def-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1rem; margin-block: 1.25rem; }
119
+ .def { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: 10px; padding: 0.9rem 1.1rem; }
120
+ .def h4 { margin: 0 0 0.3rem; color: var(--color-accent); font-size: 0.95rem; }
121
+ .def p { margin: 0; font-size: 0.9rem; color: var(--color-fg-subtle); }
122
+ .assume { margin-block: 1rem; padding: 0.85rem 1rem; background: var(--color-surface-2); border: 1px solid var(--color-border); border-radius: 8px; }
123
+ .assume-title { margin: 0 0 0.4rem; font-size: 0.76rem; font-weight: 650; text-transform: uppercase; letter-spacing: 0.04em; color: var(--color-fg-faint); }
124
+ .assume ul { margin: 0; padding-left: 1.2rem; color: var(--color-fg-subtle); }
125
+ .assume li { margin-block: 0.3rem; font-size: 0.92rem; }
126
+ .references { margin-top: 2.5rem; border-top: 1px solid var(--color-border); padding-top: 1rem; }
127
+ .reference-list { font-size: 0.85rem; color: var(--color-fg-subtle); line-height: 1.5; padding-left: 1.4rem; }
128
+ .reference-list li { margin-block: 0.5rem; }
129
+ .cite-inline { font-style: normal; font-size: 0.92em; color: var(--color-fg-subtle); }
130
+ .th-refs { margin-top: 1.25rem; padding-top: 0.6rem; border-top: 1px dashed var(--color-border); font-size: 0.85rem; color: var(--color-fg-subtle); }
131
+ .th-refs-label { font-weight: 650; color: var(--color-fg-faint); }
132
+ .prose h2 { font-size: 1.3rem; margin-block: 1.4rem 0.6rem; }
133
+ .prose h3 { font-size: 1.06rem; margin-block: 1.1rem 0.4rem; }
134
+ .prose p { margin-block: 0.6rem; }
135
+ .prose ul, .prose ol { margin-block: 0.5rem; padding-left: 1.3rem; }
136
+ .prose li { margin-block: 0.35rem; }
137
+ .page-head { border-bottom: 1px solid var(--color-border); padding-bottom: 1rem; margin-bottom: 1.25rem; }
138
+ .page-head h1 { font-size: 1.7rem; margin: 0 0 0.4rem; }
139
+ .lede { color: var(--color-fg-subtle); font-size: 1.08rem; margin: 0; max-width: 70ch; }
140
+ .two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 1.25rem; margin-block: 1.5rem; }
141
+ @media (max-width: 760px) { .two-col { grid-template-columns: 1fr; } }
142
+ .tick-list, .cross-list { list-style: none; padding-left: 0; margin: 0.4rem 0 0; }
143
+ .tick-list li, .cross-list li { position: relative; padding-left: 1.5rem; margin-block: 0.5rem; }
144
+ .tick-list li::before { content: "✓"; position: absolute; left: 0; color: var(--color-good); font-weight: 700; }
145
+ .cross-list li::before { content: "✕"; position: absolute; left: 0; color: var(--color-fg-faint); font-weight: 700; }
146
+
147
+ /* ── Callouts ── */
148
+ .callout { margin-block: 1rem; padding: 0.8rem 1.1rem; border-left: 3px solid var(--color-border); background: var(--color-surface-2); border-radius: 0 8px 8px 0; }
149
+ .callout-honest { border-left-color: var(--color-warn); }
150
+ .callout-strong { border-left-color: var(--color-accent); background: var(--color-accent-soft); }
151
+ .callout-note { border-left-color: var(--color-fg-faint); }
152
+ .callout-title { font-weight: 650; margin: 0 0 0.4rem; color: var(--color-fg); }
153
+ .callout-body { color: var(--color-fg-subtle); }
154
+ .callout-body p:first-child { margin-top: 0; }
155
+ .callout-body p:last-child { margin-bottom: 0; }
156
+
157
+ /* ── Tabs ── */
158
+ .tablist { display: flex; gap: 0.35rem; padding-bottom: 0.6rem; margin-bottom: 1.5rem; border-bottom: 1px solid var(--color-border); flex-wrap: wrap; }
159
+ .tab { padding: 0.5rem 1rem; border: 1px solid transparent; border-radius: 8px; background: transparent; color: var(--color-fg-subtle); font-size: 0.92rem; font-weight: 550; transition: color 0.15s, background-color 0.15s, border-color 0.15s; }
160
+ .tab:hover { color: var(--color-fg); background: var(--color-surface-2); }
161
+ .tab.active { color: var(--color-accent); background: var(--color-accent-soft); border-color: color-mix(in oklab, var(--color-accent) 35%, transparent); font-weight: 650; }
162
+ .tabpanel:focus, .subtabpanel:focus { outline: none; }
163
+ .subtabs { margin-block: 1rem; }
164
+ .subtablist { display: flex; gap: 0.3rem; flex-wrap: wrap; margin-bottom: 1.1rem; }
165
+ .subtab { padding: 0.32rem 0.8rem; border: 1px solid var(--color-border); border-radius: 999px; background: var(--color-surface); color: var(--color-fg-subtle); font-size: 0.84rem; font-weight: 500; transition: color 0.15s, background-color 0.15s, border-color 0.15s; }
166
+ .subtab:hover { color: var(--color-fg); border-color: var(--color-fg-faint); }
167
+ .subtab.active { color: var(--color-accent); background: var(--color-accent-soft); border-color: color-mix(in oklab, var(--color-accent) 40%, transparent); font-weight: 600; }
168
+ .subtabs-vertical { display: grid; grid-template-columns: minmax(180px, 240px) 1fr; gap: 1.5rem; align-items: start; }
169
+ .subtabs-vertical .subtablist { flex-direction: column; margin-bottom: 0; }
170
+ .subtabs-vertical .subtab { text-align: left; border-radius: 8px; }
171
+ @media (max-width: 760px) { .subtabs-vertical { grid-template-columns: 1fr; } .subtabs-vertical .subtablist { flex-direction: row; } }
172
+
173
+ /* ── Equations / figures ── */
174
+ .equation { margin: 1rem 0; padding: 0.9rem 1rem; background: var(--color-surface); border: 1px solid var(--color-border); border-radius: 8px; overflow-x: auto; }
175
+ .equation-caption { margin-top: 0.5rem; font-size: 0.82rem; color: var(--color-fg-faint); text-align: center; }
176
+ .katex { color: var(--color-fg); }
177
+ .figure { margin: 1.5rem 0; }
178
+ .figure-caption, .fig-cap { text-align: center; font-size: 0.84rem; color: var(--color-fg-faint); margin-top: 0.6rem; font-style: italic; }
179
+
180
+ /* ── Theme-aware inline SVG figures (teaching diagrams) ── */
181
+ .fig-svg { width: 100%; max-width: 560px; height: auto; display: block; margin-inline: auto; }
182
+ .fig-svg.wide { max-width: 760px; }
183
+ .dg-axis { stroke: var(--color-fg-faint); stroke-width: 1.3; }
184
+ .dg-axis-label { fill: var(--color-fg-subtle); font: 12px var(--font-sans); }
185
+ .dg-tick { fill: var(--color-fg-faint); font: 11px var(--font-mono); }
186
+ .dg-grid { stroke: var(--color-border); stroke-width: 0.5; opacity: 0.6; }
187
+ .dg-curve { fill: none; stroke: var(--color-accent); stroke-width: 2.2; stroke-linejoin: round; }
188
+ .dg-curve-2 { fill: none; stroke: var(--color-magenta); stroke-width: 2; }
189
+ .dg-curve-faint { fill: none; stroke: var(--color-fg-faint); stroke-width: 1.4; stroke-dasharray: 4 3; }
190
+ .dg-asymptote { stroke: var(--color-bad); stroke-width: 1.4; stroke-dasharray: 4 4; }
191
+ .dg-marker { stroke: var(--color-warn); stroke-width: 1.2; stroke-dasharray: 3 3; }
192
+ .dg-marker-label { fill: var(--color-warn); font: 600 11px var(--font-mono); }
193
+ .dg-note { fill: var(--color-fg-faint); font: italic 11px var(--font-sans); }
194
+ .dg-fill-accent { fill: color-mix(in oklab, var(--color-accent) 16%, transparent); stroke: var(--color-accent); stroke-width: 1; }
195
+ .dg-fill-warn { fill: color-mix(in oklab, var(--color-warn) 16%, transparent); stroke: var(--color-warn); stroke-width: 1; }
196
+ .dg-box { fill: var(--color-surface); stroke: var(--color-border); stroke-width: 1.3; }
197
+ .dg-box.accent { stroke: var(--color-accent); fill: var(--color-accent-soft); }
198
+ .dg-box.good { stroke: var(--color-good); }
199
+ .dg-box-title { fill: var(--color-fg); font: 650 12px var(--font-sans); }
200
+ .dg-box-title.accent { fill: var(--color-accent); }
201
+ .dg-box-sub { fill: var(--color-fg-subtle); font: 10.5px var(--font-mono); }
202
+ .dg-node { fill: var(--color-surface); stroke: var(--color-accent); stroke-width: 1.4; }
203
+ .dg-node-label { fill: var(--color-fg); font: 600 12px var(--font-mono); }
204
+ .dg-edge { stroke: var(--color-fg-faint); stroke-width: 1.4; fill: none; }
205
+ .dg-edge-label { fill: var(--color-fg-subtle); font: 11px var(--font-mono); }
206
+ .dg-arrowhead { fill: var(--color-fg-faint); }
207
+ .dg-bar { fill: var(--color-accent); }
208
+ .dg-bar-2 { fill: var(--color-magenta); }
209
+ .dg-bar-label { fill: var(--color-fg-subtle); font: 11px var(--font-sans); }
210
+
211
+ /* ── Generic controls ── */
212
+ .btn { border: 1px solid var(--color-border); background: var(--color-surface-2); color: var(--color-fg); padding: 0.4rem 0.9rem; border-radius: 8px; font-weight: 600; font-size: 0.88rem; display: inline-flex; align-items: center; gap: 0.35rem; }
213
+ .btn:hover { border-color: var(--color-fg-faint); }
214
+ .btn.primary { background: var(--color-accent); color: var(--color-accent-fg); border-color: var(--color-accent); }
215
+ .btn:disabled { opacity: 0.5; cursor: default; }
216
+ .select { background: var(--color-surface-2); color: var(--color-fg); border: 1px solid var(--color-border); border-radius: 8px; padding: 0.35rem 0.5rem; font-size: 0.85rem; }
217
+ .hint { font-size: 0.8rem; color: var(--color-fg-faint); margin: 0; }
218
+ .banner { padding: 0.6rem 0.9rem; border-radius: 8px; font-size: 0.85rem; margin-block: 0.6rem; border-left: 3px solid var(--color-border); background: var(--color-surface-2); }
219
+ .banner.warn { border-left-color: var(--color-warn); color: var(--color-warn); }
220
+ .banner.error { border-left-color: var(--color-bad); color: var(--color-bad); }
221
+ .range { width: 100%; accent-color: var(--color-accent); }
222
+
223
+ /* ── CaseSelector v2 (shared source + case picker) ── */
224
+ .cs { display: flex; flex-direction: column; gap: 0.7rem; }
225
+ .cs-source { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
226
+ .cs-source-label { font-size: 0.78rem; font-weight: 600; color: var(--color-fg-subtle); text-transform: uppercase; letter-spacing: 0.03em; }
227
+ .cs-source-tabs { display: inline-flex; gap: 0.35rem; flex-wrap: wrap; }
228
+ .cs-locked { margin: 0; border-left-color: var(--color-accent); }
229
+ .cs-group { display: flex; flex-direction: column; gap: 0.35rem; }
230
+ .cs-group-label { font-size: 0.76rem; font-weight: 600; color: var(--color-fg-subtle); text-transform: uppercase; letter-spacing: 0.03em; }
231
+ .cs-chips { display: flex; flex-wrap: wrap; gap: 0.4rem; }
232
+ .cs-chip { display: inline-flex; align-items: baseline; gap: 0.4rem; padding: 0.32rem 0.6rem; border: 1px solid var(--color-border); border-radius: 999px; background: var(--color-surface); color: var(--color-fg-subtle); font-size: 0.84rem; font-weight: 500; transition: color 0.15s, background-color 0.15s, border-color 0.15s; }
233
+ .cs-chip:hover:not(:disabled) { color: var(--color-fg); background: var(--color-surface-2); }
234
+ .cs-chip.on { color: var(--color-accent); background: var(--color-accent-soft); border-color: color-mix(in oklab, var(--color-accent) 40%, transparent); font-weight: 600; }
235
+ .cs-chip:disabled { opacity: 0.45; cursor: default; }
236
+ .cs-chip-id { font-family: var(--font-mono, ui-monospace, monospace); font-size: 0.76rem; font-weight: 600; opacity: 0.85; }
237
+ .cs-chip-name { }
238
+ .cs-kind { font-size: 0.62rem; font-weight: 700; line-height: 1; padding: 0.12rem 0.28rem; border-radius: 4px; border: 1px solid var(--color-border); color: var(--color-fg-faint); background: var(--color-surface-2); align-self: center; }
239
+ .cs-kind-real { color: var(--color-accent-2); border-color: color-mix(in oklab, var(--color-accent-2) 40%, transparent); }
240
+ .cs-kind-uploaded { color: var(--color-warn); border-color: color-mix(in oklab, var(--color-warn) 40%, transparent); }
241
+ .cs-modified { display: flex; align-items: center; gap: 0.5rem; }
242
+ .cs-reset { border: none; background: transparent; color: var(--color-accent); font-size: 0.8rem; font-weight: 600; padding: 0.1rem 0.2rem; text-decoration: underline; text-underline-offset: 2px; }