anentrypoint-design 0.0.382 → 0.0.383
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/dist/247420.css +180 -20
- package/dist/247420.js +27 -27
- package/package.json +1 -1
- package/src/components/files-modals.js +1 -1
- package/src/components/overlay-primitives/menus.js +5 -1
- package/src/css/app-shell/base.css +54 -1
- package/src/css/app-shell/kits-appended.css +19 -0
- package/src/css/app-shell/responsive.css +28 -8
- package/src/css/app-shell/responsive2-workspace.css +16 -4
- package/src/css/app-shell/states-interactions.css +21 -4
- package/src/css/app-shell/topbar.css +5 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "anentrypoint-design",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.383",
|
|
4
4
|
"description": "247420 design system SDK — webjsx + modified ripple-ui, single-file ESM bundle for reproducible use of the AnEntrypoint design.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/247420.js",
|
|
@@ -159,7 +159,7 @@ function Modal({ onClose, kind = '', head, headClass = '', headAttrs = {}, body,
|
|
|
159
159
|
// mutation is visible at the point of action, inside the focus trap — not a
|
|
160
160
|
// sibling stuck in page flow behind the fixed backdrop).
|
|
161
161
|
function modalError(error) {
|
|
162
|
-
return error ? h('p', { class: 'ds-modal-error
|
|
162
|
+
return error ? h('p', { class: 'ds-modal-error', role: 'alert' }, String(error)) : null;
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
// `error` renders inside .ds-modal-body (role=alert, error tone). `busy`
|
|
@@ -109,7 +109,11 @@ export function MenuButton({ trigger, items = [], selected, onSelect, onRetry, p
|
|
|
109
109
|
: h('button', {
|
|
110
110
|
key: it.id || i, type: 'button', role: 'menuitemradio',
|
|
111
111
|
'aria-checked': it.id === selected ? 'true' : 'false',
|
|
112
|
-
|
|
112
|
+
// No disabled modifier class: editor-primitives.css styles
|
|
113
|
+
// .ov-menubutton-item[aria-disabled="true"] directly, so the
|
|
114
|
+
// aria attribute below is both the semantics and the hook.
|
|
115
|
+
// (This was a ternary whose branches returned the same string.)
|
|
116
|
+
class: 'ov-menubutton-item',
|
|
113
117
|
'aria-disabled': it.disabled ? 'true' : 'false',
|
|
114
118
|
tabindex: '-1', onclick: () => select(it),
|
|
115
119
|
},
|
|
@@ -21,7 +21,7 @@ button, input, select, textarea { font: inherit; }
|
|
|
21
21
|
left: 0;
|
|
22
22
|
background: var(--accent);
|
|
23
23
|
color: var(--accent-fg);
|
|
24
|
-
padding:
|
|
24
|
+
padding: var(--space-2) var(--space-3);
|
|
25
25
|
text-decoration: none;
|
|
26
26
|
/* Must outrank every layer of chrome once focused, or the first Tab press
|
|
27
27
|
lands on a control hidden behind the sticky header (was z-index:100,
|
|
@@ -36,6 +36,35 @@ button, input, select, textarea { font: inherit; }
|
|
|
36
36
|
outline: var(--focus-w) solid var(--focus-color);
|
|
37
37
|
outline-offset: var(--focus-offset);
|
|
38
38
|
}
|
|
39
|
+
/* Visually-hidden but still in the accessibility tree. Emitted by Row() (the
|
|
40
|
+
rail status word), FilterBar()/FileGrid() (aria-live result counts) and
|
|
41
|
+
form-primitives' required marker — all of which shipped BEFORE this rule
|
|
42
|
+
existed anywhere the app shell loads. The only other definitions live in
|
|
43
|
+
app-surfaces.css (pre-scoped to `.ds-247420`, so it never reaches a kit that
|
|
44
|
+
does not mount that root) and editor-primitives.css (a separate opt-in
|
|
45
|
+
<link>), which left every app-shell consumer rendering screen-reader-only
|
|
46
|
+
text VISIBLY the moment it passed `rail`/`resultCount`.
|
|
47
|
+
Deliberately NOT `display:none` / `visibility:hidden` / `width:0`: those
|
|
48
|
+
remove the node from the accessibility tree too, which defeats the entire
|
|
49
|
+
purpose — the text exists only for AT. The clip + 1px box is what keeps it
|
|
50
|
+
announced while occupying no visible area.
|
|
51
|
+
`margin: -1px` is OFF-SCALE ON PURPOSE — it is not rhythm, it is one half of
|
|
52
|
+
the canonical visually-hidden idiom: the negative margin cancels the 1px box
|
|
53
|
+
so the clipped element contributes zero layout. Snapping it to a --space-*
|
|
54
|
+
rung would reintroduce a measurable gap. `clip` is deprecated but retained
|
|
55
|
+
alongside `clip-path` for older AT/browser pairs that ignore the latter. */
|
|
56
|
+
.sr-only {
|
|
57
|
+
position: absolute;
|
|
58
|
+
width: 1px;
|
|
59
|
+
height: 1px;
|
|
60
|
+
padding: 0;
|
|
61
|
+
margin: -1px;
|
|
62
|
+
overflow: hidden;
|
|
63
|
+
clip: rect(0, 0, 0, 0);
|
|
64
|
+
clip-path: inset(50%);
|
|
65
|
+
white-space: nowrap;
|
|
66
|
+
border: 0;
|
|
67
|
+
}
|
|
39
68
|
body {
|
|
40
69
|
background: var(--bg);
|
|
41
70
|
color: var(--fg);
|
|
@@ -124,6 +153,30 @@ h4, .t-h4 { font-family: var(--ff-display); font-size: var(--fs-h4); line-height
|
|
|
124
153
|
.ds-prose h1 { font-size: clamp(34px, 5.4cqi, 64px); margin-bottom: var(--space-3); }
|
|
125
154
|
.ds-prose h2 { margin: var(--space-6) 0 var(--space-3); }
|
|
126
155
|
.ds-prose h3 { margin: var(--space-5) 0 var(--space-2); font-size: var(--fs-lg); font-weight: 600; }
|
|
156
|
+
/* Closing line of an article ("end. reply by opening a pr."), set off from the
|
|
157
|
+
body it terminates. Quieter and smaller than the prose around it: it takes
|
|
158
|
+
the mono face and the --fg-3 tone the house uses for ancillary voices
|
|
159
|
+
(.t-micro, .dim), so the endnote reads as chrome around the article rather
|
|
160
|
+
than a final paragraph of it. The --space-5 lead does the "set off" — it
|
|
161
|
+
breaks the paragraph rhythm so the eye registers the piece has ended before
|
|
162
|
+
reading the words; margin-bottom:0 overrides .ds-prose p's --space-4 so the
|
|
163
|
+
article does not end on dead space.
|
|
164
|
+
Lives here, beside the rest of the .ds-prose family, NOT in gm-prose.css:
|
|
165
|
+
the blog kit that uses this class links only colors_and_type.css +
|
|
166
|
+
app-shell.css, so a rule in that separately-<link>-ed export would be exactly
|
|
167
|
+
as undefined as the class was before. Sized at --fs-xs, not the --fs-micro
|
|
168
|
+
label rung: this is a readable sentence with a link in it, not a micro-label.
|
|
169
|
+
The link inherits .ds-prose a's --accent-ink treatment (a readable TEXT tone;
|
|
170
|
+
the bare --accent fill is ~1.07:1 on paper) — deliberately not re-stated. */
|
|
171
|
+
.ds-prose .ds-prose-endnote,
|
|
172
|
+
.ds-prose-endnote {
|
|
173
|
+
margin-top: var(--space-5);
|
|
174
|
+
margin-bottom: 0;
|
|
175
|
+
font-family: var(--ff-mono);
|
|
176
|
+
font-size: var(--fs-xs);
|
|
177
|
+
line-height: var(--lh-base);
|
|
178
|
+
color: var(--fg-3);
|
|
179
|
+
}
|
|
127
180
|
|
|
128
181
|
.dim { color: var(--fg-3); }
|
|
129
182
|
|
|
@@ -806,3 +806,22 @@
|
|
|
806
806
|
.cursor-blink { animation: ds-cursor-blink 1s step-end infinite; }
|
|
807
807
|
@keyframes ds-cursor-blink { 50% { opacity: 0; } }
|
|
808
808
|
}
|
|
809
|
+
|
|
810
|
+
/* == appended: panel width modifier == */
|
|
811
|
+
/* .panel.panel-inline-wide — a width-capped inline note panel. Companion to
|
|
812
|
+
the .panel-inline / .panel-wide modifiers in panel-row.css: those two change
|
|
813
|
+
the panel's SURFACE (tonal fill / chrome-stripped), this one changes only
|
|
814
|
+
its MEASURE, so it composes with either. Introduced when ui_kits/docs's
|
|
815
|
+
`[!] note` panel traded `style="max-width:640px"` for a class (the inline-
|
|
816
|
+
style sweep) but never got a rule written, leaving that panel to run the
|
|
817
|
+
full column width. 640px is the note measure, deliberately narrower than
|
|
818
|
+
--measure-narrow (760px): the aside is meant to read as a set-aside block
|
|
819
|
+
against the surrounding prose, not to match its column. It is a literal
|
|
820
|
+
rather than a new token because it has exactly one consumer — promote it to
|
|
821
|
+
--measure-note the moment a second surface wants the same cap.
|
|
822
|
+
`margin-right: auto` (not `margin: 0 auto`) keeps the panel left-aligned to
|
|
823
|
+
the prose it interrupts and preserves .panel's own --space-4 stack margin. */
|
|
824
|
+
.panel.panel-inline-wide {
|
|
825
|
+
max-width: 640px;
|
|
826
|
+
margin-right: auto;
|
|
827
|
+
}
|
|
@@ -53,16 +53,28 @@
|
|
|
53
53
|
.panel-body { padding: var(--space-2); overflow-x: auto; -webkit-overflow-scrolling: touch; }
|
|
54
54
|
.panel-body > table { min-width: 100%; }
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
/* Scoped to the `.app` shell so this wins on SPECIFICITY (0,2,0) rather than
|
|
57
|
+
on an !important flag. Three rules would otherwise beat a bare `.row`
|
|
58
|
+
(0,1,0) here: `.row.row-nocode` (0,2,0, panel-row.css) out-specifies it,
|
|
59
|
+
and the `@media(481-1024)` + `@media(max-width:768px)` `.row` rules later
|
|
60
|
+
in THIS file win on source order (a media query adds no specificity).
|
|
61
|
+
`.app` is safe to require: `.app-body`/`.row` only ever render inside it
|
|
62
|
+
(single call site, shell.js AppShell). */
|
|
63
|
+
.app .row {
|
|
64
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
58
65
|
gap: var(--space-2); padding: var(--space-2-75) var(--space-3);
|
|
59
|
-
row-gap: var(--space-1)
|
|
66
|
+
row-gap: var(--space-1);
|
|
60
67
|
}
|
|
61
68
|
.row .sub { grid-column: 1 / -1; order: 3; }
|
|
62
69
|
.row .title { font-size: var(--fs-sm); }
|
|
63
70
|
/* Changelog carries 3 children: give date+ver line one, message wraps below
|
|
64
|
-
(the generic 2-col .row override staggers it into an implicit row).
|
|
65
|
-
|
|
71
|
+
(the generic 2-col .row override staggers it into an implicit row).
|
|
72
|
+
Needs (0,3,0) to clear BOTH the `.app .row` rule directly above and
|
|
73
|
+
`.ds-changelog-row`'s own !important base in hero-content.css — an
|
|
74
|
+
!important base can only be beaten by another !important, so this one
|
|
75
|
+
stays until that upstream flag is removed (hero-content.css is outside
|
|
76
|
+
this change's scope). */
|
|
77
|
+
.app .row.ds-changelog-row { grid-template-columns: minmax(70px, 10ch) minmax(0, 1fr) !important; }
|
|
66
78
|
.ds-changelog-row .title { grid-column: 1 / -1; }
|
|
67
79
|
|
|
68
80
|
/* Buttons */
|
|
@@ -150,12 +162,20 @@
|
|
|
150
162
|
Container Query Responsive (720px and below)
|
|
151
163
|
---------------------------------------------------------------------- */
|
|
152
164
|
@container (max-width: 760px) {
|
|
153
|
-
|
|
165
|
+
/* `.app`-scoped for specificity, not an !important flag: the bare `.app-body`
|
|
166
|
+
(0,1,0) was out-specified by `.app-body.no-side` (0,2,0) in topbar.css, so
|
|
167
|
+
a sidebar-less shell kept its base template. `.app .app-body` is (0,2,0)
|
|
168
|
+
and lands later in source, beating both topbar.css rules on merit. */
|
|
169
|
+
.app .app-body { grid-template-columns: 1fr; }
|
|
154
170
|
.app-side-shell { border-right: 0; border-bottom: 1px solid var(--rule); }
|
|
155
171
|
.app-topbar nav { font-size: var(--fs-xs); gap: var(--space-2-75); }
|
|
156
|
-
|
|
172
|
+
/* Same (0,2,0) lift as the 480px block above — clears `.row.row-nocode` and
|
|
173
|
+
the later `@media` `.row` rules in this file without a flag. */
|
|
174
|
+
.app .row { grid-template-columns: minmax(0, 1fr) auto; row-gap: var(--space-1); }
|
|
157
175
|
.row .sub { grid-column: 1 / -1; order: 3; }
|
|
158
|
-
|
|
176
|
+
/* (0,3,0) + !important: still required to beat `.ds-changelog-row`'s
|
|
177
|
+
!important base in hero-content.css (see the 480px block). */
|
|
178
|
+
.app .row.ds-changelog-row { grid-template-columns: minmax(70px, 10ch) minmax(0, 1fr) !important; }
|
|
159
179
|
.ds-changelog-row .title { grid-column: 1 / -1; }
|
|
160
180
|
}
|
|
161
181
|
|
|
@@ -10,8 +10,16 @@
|
|
|
10
10
|
even on a wide desktop. Drawer/scrim/toggle are absolute (anchored to .app), so
|
|
11
11
|
they overlay the window, not the page. */
|
|
12
12
|
@container (max-width: 900px) {
|
|
13
|
-
.
|
|
14
|
-
|
|
13
|
+
/* `.app`-scoped for specificity instead of an !important flag. The bare
|
|
14
|
+
`.app-body` half of this list is (0,1,0) and was out-specified by
|
|
15
|
+
`.app-body.no-side` (0,2,0) in topbar.css; scoping lifts both halves to
|
|
16
|
+
(0,2,0)/(0,3,0), which also lands later in source than topbar.css, so the
|
|
17
|
+
drawer collapse wins on merit. `.app` is guaranteed: `.app-body` is
|
|
18
|
+
emitted only as a direct child of `.app` (single call site, shell.js
|
|
19
|
+
AppShell), and this @container query already requires `.app` as its
|
|
20
|
+
container ancestor. */
|
|
21
|
+
.app .app-body,
|
|
22
|
+
.app .app-body.no-side { grid-template-columns: 1fr; }
|
|
15
23
|
.app-side-shell {
|
|
16
24
|
position: absolute;
|
|
17
25
|
/* Full-height overlay drawer: the merged .app-chrome wraps and its real
|
|
@@ -36,9 +44,13 @@
|
|
|
36
44
|
.app-side-shell.open,
|
|
37
45
|
.app-side.open,
|
|
38
46
|
.app-body.side-open .app-side-shell { transform: translateX(0); }
|
|
47
|
+
/* No flags needed: the ONLY other rule that touches these properties is the
|
|
48
|
+
`.app-side` base in topbar.css, which already sets `flex-direction: column`
|
|
49
|
+
and never sets `flex-wrap` (nowrap is the initial value anyway). This rule
|
|
50
|
+
is equal-specificity and later in source, so it wins unaided. */
|
|
39
51
|
.app-side {
|
|
40
|
-
flex-direction: column
|
|
41
|
-
flex-wrap: nowrap
|
|
52
|
+
flex-direction: column;
|
|
53
|
+
flex-wrap: nowrap;
|
|
42
54
|
gap: var(--space-2);
|
|
43
55
|
padding: var(--space-3);
|
|
44
56
|
font-size: var(--fs-sm);
|
|
@@ -56,11 +56,16 @@ button:disabled, [disabled] {
|
|
|
56
56
|
animation: spinner-rotate 0.8s linear infinite;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
/* Error state
|
|
59
|
+
/* Error state.
|
|
60
|
+
No !important: the only rule in the kit that also resets a matching element's
|
|
61
|
+
border-color is the bare-control base below (`textarea:where(:not(.input))`
|
|
62
|
+
et al, which use the `border: 0` shorthand). Those selectors are (0,0,1) —
|
|
63
|
+
the :where() guard adds nothing — so every selector in this list out-specifies
|
|
64
|
+
them on merit, and specificity beats the later source position. */
|
|
60
65
|
.error, [data-state="error"],
|
|
61
66
|
.row.error, input.error,
|
|
62
67
|
textarea.error {
|
|
63
|
-
border-color: var(--warn)
|
|
68
|
+
border-color: var(--warn);
|
|
64
69
|
background-color: color-mix(in oklab, var(--warn) 6%, var(--bg));
|
|
65
70
|
}
|
|
66
71
|
.error::placeholder { color: color-mix(in oklab, var(--warn) 60%, var(--fg-3)); }
|
|
@@ -576,7 +581,17 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
|
|
|
576
581
|
.skip-to-main:focus { top: 10px; }
|
|
577
582
|
|
|
578
583
|
/* Reduced motion preferences — scoped to the DS surface so it doesn't reach
|
|
579
|
-
into and neutralize the host document's own motion.
|
|
584
|
+
into and neutralize the host document's own motion.
|
|
585
|
+
The !important flags here are LOAD-BEARING and must not be "cleaned up":
|
|
586
|
+
`.ds-247420 *` / `.app *` is only (0,1,0) — the universal selector adds
|
|
587
|
+
nothing — yet it has to defeat every animation/transition declaration in the
|
|
588
|
+
kit, many of which are strictly more specific. Concrete rules it would
|
|
589
|
+
otherwise lose to: `.ds-dropzone.dragover` (0,2,0, files.css),
|
|
590
|
+
`.ds-upload-bar.indeterminate .ds-upload-fill` (0,3,0, files.css),
|
|
591
|
+
`.list-item.drag-after::after` (0,2,1, this file). Raising this selector to
|
|
592
|
+
out-specify an open-ended set of future component rules is not possible, so
|
|
593
|
+
the flag is the only correct mechanism — this is a WCAG 2.3.3 guarantee,
|
|
594
|
+
not a stylistic preference. */
|
|
580
595
|
@media (prefers-reduced-motion: reduce) {
|
|
581
596
|
.ds-247420 *, .app * {
|
|
582
597
|
animation-duration: 0.01ms !important;
|
|
@@ -584,7 +599,9 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
|
|
|
584
599
|
transition-duration: 0.01ms !important;
|
|
585
600
|
}
|
|
586
601
|
/* Kill the residual paint frame of looping skeleton/shimmer placeholders and
|
|
587
|
-
give reduced-motion users a steady placeholder fill instead.
|
|
602
|
+
give reduced-motion users a steady placeholder fill instead.
|
|
603
|
+
Also load-bearing: `.skeleton` is (0,1,0) and must override
|
|
604
|
+
`.ds-session-row-skeleton .ds-skel` (0,2,0), which sets its own shimmer. */
|
|
588
605
|
.skeleton, .ds-skeleton, .ds-session-row-skeleton .ds-skel {
|
|
589
606
|
animation: none !important;
|
|
590
607
|
background: var(--bg-2) !important;
|
|
@@ -201,7 +201,11 @@ body.canvas-host { background: transparent !important; }
|
|
|
201
201
|
border-radius: var(--r-pill);
|
|
202
202
|
}
|
|
203
203
|
/* The lime active pill is the sidebar's one accent moment; its own count
|
|
204
|
-
chip rides the ink-on-accent pair instead of a second competing hue.
|
|
204
|
+
chip rides the ink-on-accent pair instead of a second competing hue.
|
|
205
|
+
The bare --accent here is deliberate and is NOT the usual accent-as-text
|
|
206
|
+
defect: the chip's own background is --accent-fg (ink), so this is the
|
|
207
|
+
INVERTED pair -- lime on ink, which is the high-contrast direction. Only
|
|
208
|
+
accent-coloured text on a normal background needs --accent-ink. */
|
|
205
209
|
.app-side a.active .count {
|
|
206
210
|
background: color-mix(in oklab, var(--accent-fg) 82%, transparent);
|
|
207
211
|
color: var(--accent);
|