@fasl-work/caos-app-shell 0.6.13 → 0.7.1
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 +71 -32
- package/bin/caos-shell-gate.mjs +67 -0
- package/chart.css +19 -0
- package/dist/chart.d.ts +58 -0
- package/dist/chart.js +153 -0
- package/dist/chunk-LOSSTLPP.js +174 -0
- package/dist/chunk-X6Y5CDUD.js +16 -0
- package/dist/index.d.ts +398 -119
- package/dist/index.js +708 -184
- package/dist/keys-CnvqkckF.d.ts +135 -0
- package/dist/keys.d.ts +4 -0
- package/dist/keys.js +1 -0
- package/dist/text-BlY47nIt.d.ts +21 -0
- package/dist/tokens-CSV0MOgR.d.ts +41 -0
- package/gate/inpage.mjs +494 -0
- package/gate/png.mjs +149 -0
- package/gate/run.mjs +595 -0
- package/gate/serve.mjs +97 -0
- package/package.json +40 -7
- package/reserved-classes.json +224 -0
- package/styles.css +225 -9
package/styles.css
CHANGED
|
@@ -27,9 +27,11 @@
|
|
|
27
27
|
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
28
28
|
--maxw: 1200px; /* reading width, for PROSE pages */
|
|
29
29
|
--maxw-wide: 100%; /* instrument width, for workbench pages */
|
|
30
|
+
color-scheme: dark;
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
[data-theme="light"] {
|
|
34
|
+
color-scheme: light;
|
|
33
35
|
--color-bg: #f6f8fa;
|
|
34
36
|
--color-surface: #ffffff;
|
|
35
37
|
--color-surface-2: #f0f3f6;
|
|
@@ -49,7 +51,11 @@
|
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
* { box-sizing: border-box; }
|
|
52
|
-
|
|
54
|
+
/* Known shell defect 1 (fixed 0.7.0): `height: 100%` with `overflow-x: hidden` made html and body scroll containers
|
|
55
|
+
pinned to the viewport, so a tall page could not scroll by script or anchor. Content-height documents. */
|
|
56
|
+
html, body, #root { height: auto; min-height: 100%; }
|
|
57
|
+
/* Known shell defect 2 (fixed 0.7.0): any author `display` un-hid a `[hidden]` panel. */
|
|
58
|
+
[hidden] { display: none !important; }
|
|
53
59
|
body {
|
|
54
60
|
margin: 0;
|
|
55
61
|
font-family: var(--font-sans);
|
|
@@ -79,7 +85,7 @@ code, kbd { font-family: var(--font-mono); }
|
|
|
79
85
|
.mono { font-family: var(--font-mono); font-size: 0.9em; }
|
|
80
86
|
.small { font-size: 0.84rem; }
|
|
81
87
|
.card { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: 10px; padding: 1.25rem 1.5rem; box-shadow: var(--color-shadow); }
|
|
82
|
-
.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); }
|
|
88
|
+
.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); white-space: nowrap; }
|
|
83
89
|
.badge.live { color: var(--color-good); border-color: color-mix(in oklab, var(--color-good) 45%, transparent); }
|
|
84
90
|
.badge.precomputed, .badge.accent { color: var(--color-accent); border-color: color-mix(in oklab, var(--color-accent) 45%, transparent); }
|
|
85
91
|
.badge.warn { color: var(--color-warn); border-color: color-mix(in oklab, var(--color-warn) 45%, transparent); }
|
|
@@ -90,7 +96,10 @@ code, kbd { font-family: var(--font-mono); }
|
|
|
90
96
|
.brand { display: inline-flex; align-items: center; gap: 0.5rem; font-weight: 700; letter-spacing: -0.02em; color: var(--color-fg); }
|
|
91
97
|
.brand:hover { text-decoration: none; }
|
|
92
98
|
.brand .brand-mark { color: var(--color-accent); display: inline-flex; flex: none; }
|
|
93
|
-
.main-nav { display: flex; align-items: center; gap: 0.15rem; }
|
|
99
|
+
.main-nav { display: flex; align-items: center; gap: 0.15rem; flex: 1 1 auto; min-width: 0; overflow-x: auto; overflow-y: hidden; white-space: nowrap; scrollbar-width: none; }
|
|
100
|
+
.main-nav::-webkit-scrollbar { display: none; }
|
|
101
|
+
.main-nav .nav-link { flex: none; }
|
|
102
|
+
.brand, .header-actions { flex: none; }
|
|
94
103
|
.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; }
|
|
95
104
|
.nav-link:hover { text-decoration: none; color: var(--color-fg); }
|
|
96
105
|
.nav-link.active { color: var(--color-accent); background: var(--color-accent-soft); font-weight: 600; }
|
|
@@ -123,8 +132,13 @@ code, kbd { font-family: var(--font-mono); }
|
|
|
123
132
|
.main-nav::-webkit-scrollbar { display: none; }
|
|
124
133
|
.main-nav .nav-link { flex: none; padding: 0.3rem 0.3rem; font-size: 0.7rem; }
|
|
125
134
|
}
|
|
126
|
-
@media (max-width:
|
|
135
|
+
@media (max-width: 480px) {
|
|
127
136
|
.brand span:last-child { display: none; }
|
|
137
|
+
/* The route row needs the room on every phone: on Linux fonts "Implementation" is about 100 px, and the row was about
|
|
138
|
+
90 px at 320 px and narrower than the link at 390 px, so a route could not be shown whole (shell CI and its gate
|
|
139
|
+
self-test, 2026-10-05). The brand keeps its mark and its accessible name; the toggle keeps its icon and its label. */
|
|
140
|
+
.header-sep, .lang-code { display: none; }
|
|
141
|
+
.header-actions .icon-btn { padding: 0.2rem; }
|
|
128
142
|
}
|
|
129
143
|
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; } }
|
|
130
144
|
|
|
@@ -208,6 +222,10 @@ code, kbd { font-family: var(--font-mono); }
|
|
|
208
222
|
|
|
209
223
|
/* ── Equations / figures ── */
|
|
210
224
|
.equation { margin: 1rem 0; padding: 0.9rem 1rem; background: var(--color-surface); border: 1px solid var(--color-border); border-radius: 8px; overflow-x: auto; }
|
|
225
|
+
/* Wide content in a document scrolls inside its own box; the contained page never cuts it (G5). */
|
|
226
|
+
.prose table { display: block; max-width: 100%; overflow-x: auto; }
|
|
227
|
+
.prose pre { max-width: 100%; overflow-x: auto; }
|
|
228
|
+
.prose img, .prose svg, .prose video { max-width: 100%; height: auto; }
|
|
211
229
|
.equation-caption { margin-top: 0.5rem; font-size: 0.82rem; color: var(--color-fg-faint); text-align: center; }
|
|
212
230
|
.katex { color: var(--color-fg); }
|
|
213
231
|
.figure { margin: 1.5rem 0; }
|
|
@@ -218,7 +236,7 @@ code, kbd { font-family: var(--font-mono); }
|
|
|
218
236
|
.fig-svg.wide { max-width: 760px; }
|
|
219
237
|
.dg-axis { stroke: var(--color-fg-faint); stroke-width: 1.3; }
|
|
220
238
|
.dg-axis-label { fill: var(--color-fg-subtle); font: 12px var(--font-sans); }
|
|
221
|
-
.dg-tick { fill: var(--color-fg-
|
|
239
|
+
.dg-tick { fill: var(--color-fg-subtle); font: 11px var(--font-mono); }
|
|
222
240
|
.dg-grid { stroke: var(--color-border); stroke-width: 0.5; opacity: 0.6; }
|
|
223
241
|
.dg-curve { fill: none; stroke: var(--color-accent); stroke-width: 2.2; stroke-linejoin: round; }
|
|
224
242
|
.dg-curve-2 { fill: none; stroke: var(--color-magenta); stroke-width: 2; }
|
|
@@ -226,7 +244,7 @@ code, kbd { font-family: var(--font-mono); }
|
|
|
226
244
|
.dg-asymptote { stroke: var(--color-bad); stroke-width: 1.4; stroke-dasharray: 4 4; }
|
|
227
245
|
.dg-marker { stroke: var(--color-warn); stroke-width: 1.2; stroke-dasharray: 3 3; }
|
|
228
246
|
.dg-marker-label { fill: var(--color-warn); font: 600 11px var(--font-mono); }
|
|
229
|
-
.dg-note { fill: var(--color-fg-
|
|
247
|
+
.dg-note { fill: var(--color-fg-subtle); font: italic 11px var(--font-sans); }
|
|
230
248
|
.dg-fill-accent { fill: color-mix(in oklab, var(--color-accent) 16%, transparent); stroke: var(--color-accent); stroke-width: 1; }
|
|
231
249
|
.dg-fill-warn { fill: color-mix(in oklab, var(--color-warn) 16%, transparent); stroke: var(--color-warn); stroke-width: 1; }
|
|
232
250
|
.dg-box { fill: var(--color-surface); stroke: var(--color-border); stroke-width: 1.3; }
|
|
@@ -274,7 +292,8 @@ code, kbd { font-family: var(--font-mono); }
|
|
|
274
292
|
.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; }
|
|
275
293
|
.cs-kind-real { color: var(--color-accent-2); border-color: color-mix(in oklab, var(--color-accent-2) 40%, transparent); }
|
|
276
294
|
.cs-kind-uploaded { color: var(--color-warn); border-color: color-mix(in oklab, var(--color-warn) 40%, transparent); }
|
|
277
|
-
.cs-modified { display: flex; align-items: center; gap: 0.5rem; }
|
|
295
|
+
.cs-modified { display: flex; align-items: center; gap: 0.35rem 0.5rem; flex-wrap: wrap; min-width: 0; }
|
|
296
|
+
.cs-modified .badge { white-space: normal; max-width: 100%; }
|
|
278
297
|
.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; }
|
|
279
298
|
|
|
280
299
|
/* Authenticated workbench frame. Product styles may refine tokens and controls, but the package owns
|
|
@@ -323,7 +342,7 @@ html, body { overflow-x: hidden; }
|
|
|
323
342
|
`.app-shell.fixed` and let flex distribute the height. */
|
|
324
343
|
.app-shell.fixed { height: 100dvh; min-height: 100dvh; overflow: hidden; }
|
|
325
344
|
.app-shell.fixed > .page { flex: 1 1 auto; min-height: 0; display: flex; }
|
|
326
|
-
.app-shell.fixed .page-body.wide { flex: 1 1 auto; min-height: 0; padding-top:
|
|
345
|
+
.app-shell.fixed .page-body.wide { flex: 1 1 auto; min-height: 0; padding-top: 0.75rem; padding-bottom: 0.75rem; }
|
|
327
346
|
|
|
328
347
|
/* A viewport-filling app must not carry the prose footer margin: it becomes dead space between the
|
|
329
348
|
content and the chrome. Measured on ChargeCascade as exactly 48px (3rem). */
|
|
@@ -357,7 +376,7 @@ html, body { overflow-x: hidden; }
|
|
|
357
376
|
.cs-select { width: 100%; max-width: 460px; }
|
|
358
377
|
|
|
359
378
|
/* ADR-0070: additive, shell-owned, full-viewport scenario focus frame. */
|
|
360
|
-
.caos-focus-shell { position: fixed; inset: 0; z-index: 100; display: grid; grid-template-columns: minmax(0,1fr) clamp(
|
|
379
|
+
.caos-focus-shell { position: fixed; inset: 0; z-index: 100; display: grid; grid-template-columns: minmax(0,1fr) clamp(248px,19vw,340px); min-width: 0; height: 100dvh; background: var(--color-bg); color: var(--color-fg); }
|
|
361
380
|
.caos-focus-stage { position: relative; min-width: 0; min-height: 0; overflow: hidden; background: var(--color-bg); }
|
|
362
381
|
.caos-focus-instrument { position: absolute; inset: 0; min-width: 0; min-height: 0; }
|
|
363
382
|
.caos-focus-label, .caos-focus-hud > div { background: color-mix(in oklab,var(--color-surface) 82%,transparent); backdrop-filter: blur(6px); border: 1px solid var(--color-border); border-radius: 6px; }
|
|
@@ -381,3 +400,200 @@ html, body { overflow-x: hidden; }
|
|
|
381
400
|
.caos-focus-hud span { font-size: 0.48rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
382
401
|
.caos-focus-actions { top: 7px; right: 7px; }
|
|
383
402
|
}
|
|
403
|
+
|
|
404
|
+
/* == Workbench primitives (0.7.0) ==============================================================================
|
|
405
|
+
The App route of every product: WorkbenchLayout, CaseWorkbench, VariantBar, LaneBadge, Readout, Gauge, Verdict,
|
|
406
|
+
PlotCard; and DocPage/DocSection for documentation routes. Owned here so products compose them and never
|
|
407
|
+
redefine them (ADR-0016 s9, ADR-0017, ADR-0071, as amended 2026-10-04). */
|
|
408
|
+
|
|
409
|
+
/* Chips: a one-of-N choice rendered as pills; `.on` is the selected state. */
|
|
410
|
+
.chip { display: inline-flex; align-items: center; gap: 0.35rem; background: var(--color-surface); border: 1px solid var(--color-border); color: var(--color-fg-subtle); border-radius: 999px; padding: 0.3rem 0.72rem; font-size: 0.82rem; font-weight: 500; white-space: nowrap; transition: color 0.15s, background-color 0.15s, border-color 0.15s; }
|
|
411
|
+
.chip:hover:not(:disabled) { color: var(--color-fg); border-color: var(--color-fg-faint); }
|
|
412
|
+
.chip.on { background: var(--color-accent); color: var(--color-accent-fg); border-color: transparent; font-weight: 600; }
|
|
413
|
+
.chip:disabled { opacity: 0.45; cursor: default; }
|
|
414
|
+
/* ONE row of chips (ADR-0071 rule 4): it scrolls horizontally instead of wrapping into more rows. */
|
|
415
|
+
.caos-chip-row { display: flex; flex-wrap: nowrap; gap: 0.35rem; overflow-x: auto; overflow-y: hidden; min-width: 0; scrollbar-width: none; padding-bottom: 2px; }
|
|
416
|
+
.caos-chip-row::-webkit-scrollbar { display: none; }
|
|
417
|
+
.caos-chip-row > * { flex: 0 0 auto; }
|
|
418
|
+
|
|
419
|
+
/* WorkbenchLayout: a sized rail beside the instrument, on the full viewport. */
|
|
420
|
+
.caos-wb { display: grid; grid-template-columns: clamp(248px, 19vw, 340px) minmax(0, 1fr); gap: 0.9rem; align-items: stretch; min-width: 0; padding-top: 0.75rem; padding-bottom: 0.75rem; }
|
|
421
|
+
.caos-wb > * { min-width: 0; }
|
|
422
|
+
.caos-wb-rail { display: flex; flex-direction: column; gap: 0.75rem; min-height: 0; overflow-y: auto; overflow-x: hidden; background: var(--color-surface); border: 1px solid var(--color-border); border-radius: 10px; padding: 0.85rem; }
|
|
423
|
+
.caos-wb-rail-sections { display: flex; flex-wrap: nowrap; gap: 0.3rem; overflow-x: auto; scrollbar-width: none; flex: 0 0 auto; }
|
|
424
|
+
.caos-wb-rail-sections::-webkit-scrollbar { display: none; }
|
|
425
|
+
.caos-wb-rail-panel { display: flex; flex-direction: column; gap: 0.8rem; min-height: 0; }
|
|
426
|
+
.caos-wb-rail label, .caos-field { display: flex; flex-direction: column; gap: 0.3rem; font-size: 0.8rem; color: var(--color-fg-subtle); }
|
|
427
|
+
.caos-wb-rail .select, .caos-wb-rail .range { width: 100%; }
|
|
428
|
+
.caos-wb-main { display: flex; flex-direction: column; min-height: 0; min-width: 0; }
|
|
429
|
+
|
|
430
|
+
/* CaseWorkbench: the variant bar, then ONE row of at most six question groups; the panel owns its scroll. */
|
|
431
|
+
.caos-cw { display: flex; flex-direction: column; min-height: 0; min-width: 0; flex: 1 1 auto; }
|
|
432
|
+
.caos-cw > .tabs { display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto; }
|
|
433
|
+
.caos-cw > .tabs > .tabpanel:not([hidden]) { flex: 1 1 auto; min-height: 0; overflow: auto; }
|
|
434
|
+
.caos-cw-panel { display: flex; flex-direction: column; gap: 0.6rem; min-width: 0; }
|
|
435
|
+
.caos-cw-panel-head { display: flex; justify-content: flex-end; }
|
|
436
|
+
.caos-cw-context { max-width: 92ch; }
|
|
437
|
+
.caos-variant-bar { display: flex; flex-direction: column; gap: 0.4rem; margin-bottom: 0.7rem; min-width: 0; }
|
|
438
|
+
.caos-variant-head { display: flex; align-items: center; gap: 0.4rem 0.6rem; flex-wrap: wrap; }
|
|
439
|
+
.caos-variant-title { font-size: 0.74rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--color-fg-faint); font-weight: 600; }
|
|
440
|
+
.caos-variant-note { margin: 0; font-size: 0.88rem; color: var(--color-fg-subtle); font-style: italic; }
|
|
441
|
+
|
|
442
|
+
/* LaneBadge: which lane produced the values on screen. */
|
|
443
|
+
.caos-lane-live { color: var(--color-good); border-color: color-mix(in oklab, var(--color-good) 45%, transparent); }
|
|
444
|
+
.caos-lane-replay { color: var(--color-accent); border-color: color-mix(in oklab, var(--color-accent) 45%, transparent); }
|
|
445
|
+
.caos-lane-offline { color: var(--color-warn); border-color: color-mix(in oklab, var(--color-warn) 45%, transparent); }
|
|
446
|
+
|
|
447
|
+
/* Tones shared by readouts, gauges and verdicts. */
|
|
448
|
+
.tone-good { --tone: var(--color-good); }
|
|
449
|
+
.tone-warn { --tone: var(--color-warn); }
|
|
450
|
+
.tone-bad { --tone: var(--color-bad); }
|
|
451
|
+
.tone-accent { --tone: var(--color-accent); }
|
|
452
|
+
.tone-neutral { --tone: var(--color-fg-faint); }
|
|
453
|
+
|
|
454
|
+
/* Readout: labelled live values with units. */
|
|
455
|
+
.caos-readout { display: flex; flex-direction: column; gap: 0.35rem; }
|
|
456
|
+
.caos-readout-title, .caos-gauge-title, .caos-verdict-title { margin: 0; font-size: 0.74rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--color-fg-faint); font-weight: 600; }
|
|
457
|
+
.caos-readout dl { margin: 0; display: grid; gap: 0.25rem; }
|
|
458
|
+
.caos-readout-row { display: flex; justify-content: space-between; gap: 0.75rem; font-size: 0.84rem; border-left: 3px solid var(--tone); padding-left: 0.5rem; }
|
|
459
|
+
.caos-readout-row dt { color: var(--color-fg-subtle); }
|
|
460
|
+
.caos-readout-row dd { margin: 0; text-align: right; }
|
|
461
|
+
.caos-readout-value { font-family: var(--font-mono); font-weight: 650; color: var(--color-fg); }
|
|
462
|
+
.caos-readout-unit { color: var(--color-fg-faint); font-size: 0.78rem; }
|
|
463
|
+
|
|
464
|
+
/* Gauge: a value against labelled zones. */
|
|
465
|
+
.caos-gauge-track { position: relative; height: 14px; border-radius: 7px; background: var(--color-surface-2); overflow: hidden; margin-top: 0.35rem; }
|
|
466
|
+
.caos-gauge-zone { position: absolute; top: 0; height: 100%; background: var(--tone); opacity: 0.45; }
|
|
467
|
+
.caos-gauge-needle { position: absolute; top: 0; width: 3px; height: 100%; background: var(--color-fg); transform: translateX(-1px); }
|
|
468
|
+
.caos-gauge-scale { display: flex; justify-content: space-between; font-size: 0.72rem; color: var(--color-fg-faint); margin-top: 0.2rem; }
|
|
469
|
+
.caos-gauge-value { color: var(--color-fg); font-weight: 700; font-family: var(--font-mono); }
|
|
470
|
+
.caos-gauge-legend { display: flex; flex-wrap: wrap; gap: 0.5rem; font-size: 0.72rem; color: var(--color-fg-subtle); margin-top: 0.25rem; }
|
|
471
|
+
.caos-gauge-legend .dot { display: inline-block; width: 8px; height: 8px; border-radius: 2px; margin-right: 0.25rem; background: var(--tone); }
|
|
472
|
+
|
|
473
|
+
/* Verdict: the current diagnosis, coloured by its tone. */
|
|
474
|
+
.caos-verdict { border: 1px solid var(--color-border); border-left: 4px solid var(--tone); border-radius: 8px; padding: 0.7rem 0.85rem; background: var(--color-surface-2); }
|
|
475
|
+
.caos-verdict-text { margin: 0.2rem 0 0; font-weight: 650; color: var(--color-fg); }
|
|
476
|
+
.caos-verdict.compact { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.15rem 0.6rem; padding: 0.4rem 0.7rem; }
|
|
477
|
+
.caos-verdict.compact .caos-verdict-text { margin: 0; }
|
|
478
|
+
|
|
479
|
+
/* PlotCard: the frame every chart or table sits in. */
|
|
480
|
+
.caos-plot { margin: 0; background: var(--color-surface); border: 1px solid var(--color-border); border-radius: 10px; padding: 0.45rem 0.6rem 0.4rem; min-width: 0; }
|
|
481
|
+
.caos-plot-head { display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; margin-bottom: 0.2rem; font-style: normal; text-align: left; min-height: 1.5rem; }
|
|
482
|
+
.caos-plot-head .badge { font-size: 0.68rem; padding: 0.05rem 0.45rem; }
|
|
483
|
+
.caos-plot-title { font-size: 0.84rem; color: var(--color-fg-subtle); font-weight: 600; }
|
|
484
|
+
.caos-plot-actions { display: inline-flex; gap: 0.3rem; }
|
|
485
|
+
.caos-plot-body { position: relative; min-width: 0; overflow-x: auto; }
|
|
486
|
+
.caos-plot-note { margin: 0.4rem 0 0; font-size: 0.78rem; color: var(--color-fg-faint); }
|
|
487
|
+
|
|
488
|
+
/* DocPage / DocSection. */
|
|
489
|
+
.caos-doc-section { margin-block: 1.75rem; }
|
|
490
|
+
|
|
491
|
+
/* contain: every route is the viewport. The workbench fills the main container; a documentation route scrolls
|
|
492
|
+
inside it, so the header and footer stay in view and the document never scrolls (ADR-0071 rule 1). */
|
|
493
|
+
.app-shell.fixed.contain > .page { display: flex; flex-direction: column; overflow: hidden; }
|
|
494
|
+
.app-shell.fixed.contain > .page > .caos-wb { flex: 1 1 auto; min-height: 0; }
|
|
495
|
+
/* The chrome of a contained app spans the instrument's width with its inset, so at 2560 px the header and footer
|
|
496
|
+
do not float in a 1200 px column above a full-width workbench (found by the template capture review). */
|
|
497
|
+
.app-shell.fixed.contain .header-inner, .app-shell.fixed.contain .site-footer .footer-inner { max-width: var(--maxw-wide); padding-inline: 1rem; }
|
|
498
|
+
.app-shell.fixed.contain > .page:has(> .page-body:not(.caos-wb)) { display: block; overflow-y: auto; overscroll-behavior: contain; }
|
|
499
|
+
@media (max-width: 900px) {
|
|
500
|
+
/* A phone stacks the rail over the instrument and lets the document scroll: the viewport rule is measured at
|
|
501
|
+
1280x800 and above (ADR-0071 Verification). */
|
|
502
|
+
.caos-wb { grid-template-columns: minmax(0, 1fr); }
|
|
503
|
+
.app-shell.fixed.contain { height: auto; min-height: 100dvh; overflow: visible; }
|
|
504
|
+
.app-shell.fixed.contain > .page { display: block; overflow: visible; }
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/* == 0.7.0: closed known defects and the new primitives ======================================================== */
|
|
508
|
+
|
|
509
|
+
/* Native controls follow the theme (S2; known shell defect 13). */
|
|
510
|
+
.app-shell select, .app-shell textarea, .app-shell input:not([type="range"]):not([type="checkbox"]):not([type="radio"]) { background: var(--color-surface-2); color: var(--color-fg); border: 1px solid var(--color-border); border-radius: 6px; }
|
|
511
|
+
.app-shell button { color: inherit; }
|
|
512
|
+
.caos-arch-toggle { margin: 0 0 8px; font-size: 12px; padding: 5px 10px; color: var(--color-fg); background: var(--color-surface-2); border: 1px solid var(--color-border); border-radius: 6px; cursor: pointer; }
|
|
513
|
+
|
|
514
|
+
/* A scrolling row says that it scrolls (known shell defect 11): the hidden end fades. */
|
|
515
|
+
.main-nav[data-fade-end="1"], .tablist[data-fade-end="1"], .subtablist[data-fade-end="1"] { mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent); }
|
|
516
|
+
.main-nav[data-fade-start="1"], .tablist[data-fade-start="1"], .subtablist[data-fade-start="1"] { mask-image: linear-gradient(to left, #000 calc(100% - 28px), transparent); }
|
|
517
|
+
.main-nav[data-fade-start="1"][data-fade-end="1"], .tablist[data-fade-start="1"][data-fade-end="1"], .subtablist[data-fade-start="1"][data-fade-end="1"] { mask-image: linear-gradient(to right, transparent, #000 28px, #000 calc(100% - 28px), transparent); }
|
|
518
|
+
.subtablist:not([aria-orientation="vertical"]) { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
|
|
519
|
+
.subtablist::-webkit-scrollbar { display: none; }
|
|
520
|
+
.subtablist .subtab { flex: none; white-space: nowrap; }
|
|
521
|
+
/* The phone footer of a contained surface stays one row (the instrument keeps the viewport) and says that it
|
|
522
|
+
scrolls: its hidden end fades, and a focused link is scrolled into view (useOverflowFade). */
|
|
523
|
+
.app-shell.fixed .footer-meta[data-fade-end="1"] { mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent); }
|
|
524
|
+
.app-shell.fixed .footer-meta[data-fade-start="1"] { mask-image: linear-gradient(to left, #000 calc(100% - 28px), transparent); }
|
|
525
|
+
.app-shell.fixed .footer-meta[data-fade-start="1"][data-fade-end="1"] { mask-image: linear-gradient(to right, transparent, #000 28px, #000 calc(100% - 28px), transparent); }
|
|
526
|
+
|
|
527
|
+
/* A failed view (PanelBoundary): an inline message in its own frame, never a blank page. */
|
|
528
|
+
.caos-panel-error { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: baseline; padding: 0.7rem 0.9rem; border: 1px solid color-mix(in oklab, var(--color-bad) 45%, transparent); border-left: 4px solid var(--color-bad); border-radius: 8px; background: var(--color-surface-2); color: var(--color-fg); font-size: 0.86rem; }
|
|
529
|
+
.caos-panel-error code { flex-basis: 100%; font-size: 0.78rem; color: var(--color-fg-subtle); }
|
|
530
|
+
|
|
531
|
+
/* Lane and provenance badges. */
|
|
532
|
+
.caos-badges { display: inline-flex; gap: 0.3rem; flex-wrap: wrap; }
|
|
533
|
+
.caos-prov-real { color: var(--color-accent-2); border-color: color-mix(in oklab, var(--color-accent-2) 45%, transparent); }
|
|
534
|
+
.caos-prov-synthetic { color: var(--color-magenta); border-color: color-mix(in oklab, var(--color-magenta) 45%, transparent); }
|
|
535
|
+
.caos-prov-published { color: var(--color-fg-subtle); }
|
|
536
|
+
|
|
537
|
+
/* Staleness: a view showing data for an earlier selection says so. */
|
|
538
|
+
.caos-stale .caos-plot-body > :not(.caos-stale-overlay), .caos-readout.caos-stale dl { opacity: 0.45; }
|
|
539
|
+
.caos-stale-overlay { position: absolute; inset: auto 0.5rem 0.5rem auto; padding: 0.25rem 0.55rem; border-radius: 6px; background: var(--color-surface-2); border: 1px solid var(--color-border); font-size: 0.76rem; color: var(--color-warn); }
|
|
540
|
+
.caos-stale-note { margin: 0.2rem 0 0; font-size: 0.76rem; color: var(--color-warn); }
|
|
541
|
+
.caos-readout-head { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; flex-wrap: wrap; }
|
|
542
|
+
|
|
543
|
+
/* Registered controls. */
|
|
544
|
+
.caos-knob { display: flex; flex-direction: column; gap: 0.25rem; }
|
|
545
|
+
.caos-knob-head { display: flex; justify-content: space-between; gap: 0.5rem; font-size: 0.8rem; color: var(--color-fg-subtle); }
|
|
546
|
+
.caos-knob-value { font-family: var(--font-mono); color: var(--color-fg); font-weight: 600; }
|
|
547
|
+
.caos-chipgroup { display: flex; flex-direction: column; gap: 0.3rem; min-width: 0; }
|
|
548
|
+
.caos-chipgroup-label { font-size: 0.8rem; color: var(--color-fg-subtle); }
|
|
549
|
+
|
|
550
|
+
/* The height chain of the instrument (failure class 4: drawings at zero or at a guessed size). The open group's panel
|
|
551
|
+
fills the workbench; a filling view (PlotCard fill, or a .caos-views-row of them) takes the height the panel leaves,
|
|
552
|
+
so a Stage or a filling chart inside it has a real size. Sub-tabs inside a panel pass the height down. Below 900 px
|
|
553
|
+
the document scrolls, and a filling view gets a fixed readable height instead. */
|
|
554
|
+
.caos-cw > .tabs > .tabpanel:not([hidden]) { display: flex; flex-direction: column; }
|
|
555
|
+
.caos-cw-panel { flex: 1 1 auto; min-height: 0; }
|
|
556
|
+
/* In the workbench the group row is a compact header of the instrument, not a page section break. */
|
|
557
|
+
.caos-cw > .tabs > .tablist { margin-bottom: 0.5rem; padding-bottom: 0.25rem; }
|
|
558
|
+
.caos-cw > .tabs > .tablist .tab { padding: 0.38rem 0.85rem; }
|
|
559
|
+
/* The rail head: the case and variant pickers; the variants wrap in the rail instead of scrolling. */
|
|
560
|
+
.caos-wb-rail-head { display: flex; flex-direction: column; gap: 0.75rem; padding-bottom: 0.75rem; border-bottom: 1px solid var(--color-border); }
|
|
561
|
+
.caos-wb-rail .caos-variant-bar { margin-bottom: 0; }
|
|
562
|
+
.caos-wb-rail .caos-chip-row { flex-wrap: wrap; overflow: visible; }
|
|
563
|
+
.caos-wb-rail .caos-variant-note { font-size: 0.8rem; }
|
|
564
|
+
.caos-cw-panel > .subtabs { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; margin-block: 0; }
|
|
565
|
+
.caos-cw-panel > .subtabs > .subtablist { margin-bottom: 0.45rem; }
|
|
566
|
+
/* Known shell defect 16: the group row and the sub-tab row are scroll containers (overflow-x auto), so their
|
|
567
|
+
automatic minimum height is zero, and in this column flex chain they shrank with a panel taller than the
|
|
568
|
+
instrument: the rows were clipped and the panel's top covered the sub-tabs (CAOS_Contraste, 2026-10-05). A tab
|
|
569
|
+
row keeps its height; the panel below it scrolls. */
|
|
570
|
+
.caos-cw > .tabs > .tablist, .caos-cw-panel > .subtabs > .subtablist { flex: none; }
|
|
571
|
+
.page-body.wide.caos-wb { padding-inline: 1rem; }
|
|
572
|
+
.caos-cw-panel > .subtabs > .subtabpanels, .caos-cw-panel > .subtabs > .subtabpanels > .subtabpanel { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
|
|
573
|
+
.caos-cw-panel > .subtabs > .subtabpanels > .subtabpanel { gap: 0.6rem; }
|
|
574
|
+
.caos-views-row { display: flex; gap: 0.9rem; flex: 1 1 auto; min-height: 0; min-width: 0; }
|
|
575
|
+
.caos-views-row > * { flex: 1 1 0; min-width: 0; }
|
|
576
|
+
.caos-plot.fill { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
|
|
577
|
+
.caos-plot.fill > .caos-plot-body { flex: 1 1 0; min-height: 0; overflow: hidden; }
|
|
578
|
+
@media (max-width: 900px) {
|
|
579
|
+
.caos-views-row { flex-direction: column; }
|
|
580
|
+
.caos-plot.fill > .caos-plot-body { flex: none; height: clamp(260px, 48vh, 440px); }
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
/* Tables in views and documents: tabular figures, compact rows, a header that stays in view while the body scrolls.
|
|
584
|
+
Products use .caos-table instead of styling their own (S17: shell classes are reserved). */
|
|
585
|
+
.caos-table { width: 100%; border-collapse: collapse; font-size: 0.84rem; font-variant-numeric: tabular-nums; color: var(--color-fg); }
|
|
586
|
+
.caos-table th, .caos-table td { padding: 0.35rem 0.6rem; border-bottom: 1px solid var(--color-border); text-align: right; white-space: nowrap; }
|
|
587
|
+
.caos-table th:first-child, .caos-table td:first-child { text-align: left; }
|
|
588
|
+
/* A column of words (a description, an expected band) reads left-aligned and wraps; numbers stay right-aligned. */
|
|
589
|
+
.caos-table th.caos-col-text, .caos-table td.caos-col-text { text-align: left; white-space: normal; min-width: 16ch; }
|
|
590
|
+
.caos-table thead th { position: sticky; top: 0; background: var(--color-surface); color: var(--color-fg-subtle); font-weight: 600; border-bottom-color: var(--color-fg-faint); }
|
|
591
|
+
.caos-table tbody tr:hover { background: var(--color-surface-2); }
|
|
592
|
+
/* A phone wraps the cells instead of pushing the table past the page (found by the gate on the template, 390 px). */
|
|
593
|
+
@media (max-width: 600px) { .caos-table th, .caos-table td { white-space: normal; padding: 0.3rem 0.4rem; } }
|
|
594
|
+
|
|
595
|
+
/* A view whose data is not there yet: it says so (and declares data-state="loading" for the gate). */
|
|
596
|
+
.caos-pending { margin: auto; padding: 1.5rem; color: var(--color-fg-faint); font-size: 0.86rem; text-align: center; }
|
|
597
|
+
|
|
598
|
+
/* Stage: the drawing surface of an instrument, sized by its container. */
|
|
599
|
+
.caos-stage { position: relative; width: 100%; height: 100%; min-width: 0; min-height: 0; }
|