anentrypoint-design 0.0.322 → 0.0.324
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 +22 -2
- package/app-shell.css +24 -4782
- package/colors_and_type.css +43 -0
- package/dist/247420.css +74 -3
- package/dist/247420.js +16 -16
- package/package.json +14 -8
- package/src/bootstrap.js +10 -1
- package/src/components/chat-message-parts.js +355 -0
- package/src/components/chat.js +23 -320
- package/src/components/data-density.js +15 -10
- package/src/components/files-modals.js +14 -2
- package/src/components/files.js +5 -1
- package/src/components/freddie/helpers.js +46 -8
- package/src/css/app-shell/base.css +157 -0
- package/src/css/app-shell/catalog-theme.css +144 -0
- package/src/css/app-shell/chat-basic.css +12 -0
- package/src/css/app-shell/chat-polish.css +459 -0
- package/src/css/app-shell/data-density.css +150 -0
- package/src/css/app-shell/files.css +709 -0
- package/src/css/app-shell/hero-content.css +407 -0
- package/src/css/app-shell/kits-appended.css +361 -0
- package/src/css/app-shell/loading-alerts.css +120 -0
- package/src/css/app-shell/panel-row.css +177 -0
- package/src/css/app-shell/primitives.css +197 -0
- package/src/css/app-shell/responsive.css +266 -0
- package/src/css/app-shell/responsive2-workspace.css +465 -0
- package/src/css/app-shell/row-print.css +75 -0
- package/src/css/app-shell/sidebar-misc.css +79 -0
- package/src/css/app-shell/states-interactions.css +696 -0
- package/src/css/app-shell/topbar.css +319 -0
- package/src/deck-stage.js +6 -4
- package/src/highlight.js +20 -4
- package/src/index.js +15 -5
- package/src/kits/os/freddie/pages-chat.js +1 -1
- package/src/kits/os/freddie/pages-core.js +1 -1
- package/src/kits/os/freddie/pages-os.js +1 -1
- package/src/kits/os/freddie/pages-tools.js +1 -1
- package/src/kits/os/wm.js +38 -0
- package/src/kits/slides/deck-stage-overlay.js +68 -0
- package/src/kits/slides/deck-stage-state.js +81 -0
- package/src/kits/slides/deck-stage-style.js +117 -0
- package/src/kits/slides/deck-stage.js +167 -0
- package/src/kits/slides/index.js +5 -0
- package/src/markdown.js +89 -11
- package/src/kits/os/freddie/helpers.js +0 -33
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/* ============================================================
|
|
2
|
+
Primitives
|
|
3
|
+
============================================================ */
|
|
4
|
+
.btn, .btn-primary, .btn-ghost {
|
|
5
|
+
display: inline-flex; align-items: center; justify-content: center; gap: 6px;
|
|
6
|
+
/* Fixed height + horizontal-only padding: the control height is exact and
|
|
7
|
+
alignable (flex centres the label vertically), the way webgeist snaps every
|
|
8
|
+
control to a height ladder. Default is the --ctl-md rung; --btn-sm/--btn-lg
|
|
9
|
+
retune height + h-padding + font per size. Density scales the ladder. */
|
|
10
|
+
height: var(--ctl-md); min-height: var(--ctl-md);
|
|
11
|
+
padding: 0 var(--space-2-75);
|
|
12
|
+
font-family: var(--ff-body);
|
|
13
|
+
font-weight: 600; font-size: var(--fs-sm);
|
|
14
|
+
text-decoration: none;
|
|
15
|
+
white-space: nowrap;
|
|
16
|
+
cursor: pointer;
|
|
17
|
+
/* Rounded-rect app chrome, not a marketing-page stadium CTA.
|
|
18
|
+
Shape vocabulary: r-1/r-2 = actionable buttons, icon-buttons, and
|
|
19
|
+
containers; r-pill = reserved for status/input/chip/badge/progress
|
|
20
|
+
surfaces (composer input, chips, badges, progress bars, theme-toggle
|
|
21
|
+
segments) - never for actions. */
|
|
22
|
+
border-radius: var(--r-1);
|
|
23
|
+
border: var(--bw-hair) solid transparent;
|
|
24
|
+
box-shadow: none;
|
|
25
|
+
/* Restrained hover-lift: a 1px rise + hairline shadow reads as a crisp,
|
|
26
|
+
confident affordance rather than a soft glow-card float. */
|
|
27
|
+
transition: transform var(--dur-base) var(--ease-spring), background var(--dur-snap) var(--ease),
|
|
28
|
+
color var(--dur-snap) var(--ease), box-shadow var(--dur-base) var(--ease-spring),
|
|
29
|
+
border-color var(--dur-snap) var(--ease);
|
|
30
|
+
}
|
|
31
|
+
.btn { background: var(--bg-2); color: var(--fg); border-color: var(--rule); }
|
|
32
|
+
.btn:hover { background: var(--bg-3); color: var(--fg); transform: translateY(-1px); box-shadow: var(--shadow-1); }
|
|
33
|
+
/* Primary CTA — the electric lead as a solid editorial block; hover inverts to
|
|
34
|
+
an ink block with the lead as text, a confident two-tone flip. */
|
|
35
|
+
.btn-primary {
|
|
36
|
+
background: var(--accent); color: var(--accent-fg);
|
|
37
|
+
font-weight: 700;
|
|
38
|
+
}
|
|
39
|
+
.btn-primary:hover { background: var(--fg); color: var(--accent-ink); transform: translateY(-1px); box-shadow: var(--shadow-2); }
|
|
40
|
+
.btn-ghost { background: transparent; color: var(--fg); box-shadow: inset 0 0 0 2px var(--fg); }
|
|
41
|
+
.btn-ghost:hover { background: var(--fg); color: var(--bg); transform: translateY(-1px); }
|
|
42
|
+
.btn:active, .btn-primary:active, .btn-ghost:active { transform: translateY(1px); box-shadow: none; }
|
|
43
|
+
.btn:focus-visible, .btn-primary:focus-visible, .btn-ghost:focus-visible, .ds-icon-btn:focus-visible {
|
|
44
|
+
outline: var(--focus-w) solid var(--focus-color);
|
|
45
|
+
outline-offset: var(--focus-offset);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/* Button size ladder — the size prop on Btn() (sm | md | lg). md is the base
|
|
49
|
+
rule above; sm/lg retune height (off the --ctl-* ladder), horizontal padding,
|
|
50
|
+
and font-size so a size swap is one class, never inline padding overrides
|
|
51
|
+
(the old preview faked sizes with style=). Applies to every variant. */
|
|
52
|
+
.btn-sm, .btn-sm.btn-primary, .btn-sm.btn-ghost {
|
|
53
|
+
height: var(--ctl-sm); min-height: var(--ctl-sm);
|
|
54
|
+
padding: 0 var(--space-2); font-size: var(--fs-tiny); gap: var(--space-1);
|
|
55
|
+
}
|
|
56
|
+
.btn-lg, .btn-lg.btn-primary, .btn-lg.btn-ghost {
|
|
57
|
+
height: var(--ctl-lg); min-height: var(--ctl-lg);
|
|
58
|
+
padding: 0 var(--space-4); font-size: var(--fs-body); gap: var(--space-2);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/* App-mode quiet interactions — the marketing hover-lift (translateY + shadow)
|
|
62
|
+
and the .row .meta slide read as decorative float on a dense working surface.
|
|
63
|
+
Under [data-typescale="app"], state changes are background/border-only: crisp,
|
|
64
|
+
no motion, no elevation. Marketing surfaces (no data-typescale) keep the lift. */
|
|
65
|
+
[data-typescale="app"] .btn:hover,
|
|
66
|
+
[data-typescale="app"] .btn-primary:hover,
|
|
67
|
+
[data-typescale="app"] .btn-ghost:hover { transform: none; box-shadow: none; }
|
|
68
|
+
[data-typescale="app"] .btn:active,
|
|
69
|
+
[data-typescale="app"] .btn-primary:active,
|
|
70
|
+
[data-typescale="app"] .btn-ghost:active { transform: none; }
|
|
71
|
+
[data-typescale="app"] .panel { transition: box-shadow var(--dur-snap) var(--ease), border-color var(--dur-snap) var(--ease); }
|
|
72
|
+
[data-typescale="app"] a.row:hover .meta,
|
|
73
|
+
[data-typescale="app"] .row[role="button"]:hover .meta { transform: none; }
|
|
74
|
+
|
|
75
|
+
/* ============================================================
|
|
76
|
+
IconButton — square icon-only button
|
|
77
|
+
============================================================ */
|
|
78
|
+
.ds-icon-btn {
|
|
79
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
80
|
+
padding: 0; border: none; cursor: pointer;
|
|
81
|
+
border-radius: var(--r-1, 6px);
|
|
82
|
+
background: transparent; color: var(--fg);
|
|
83
|
+
width: 32px; height: 32px;
|
|
84
|
+
}
|
|
85
|
+
.ds-icon-btn-xs { width: 22px; height: 22px; }
|
|
86
|
+
.ds-icon-btn-sm { width: 26px; height: 26px; }
|
|
87
|
+
.ds-icon-btn-base { width: 32px; height: 32px; }
|
|
88
|
+
.ds-icon-btn-lg { width: 40px; height: 40px; }
|
|
89
|
+
.ds-icon-btn-xl { width: 48px; height: 48px; }
|
|
90
|
+
.ds-icon-btn-ghost { background: transparent; }
|
|
91
|
+
.ds-icon-btn-ghost:hover { background: var(--fg); color: var(--bg); }
|
|
92
|
+
.ds-icon-btn-primary { background: var(--accent); color: var(--accent-fg); }
|
|
93
|
+
.ds-icon-btn-primary:hover { background: var(--fg); color: var(--accent-ink); }
|
|
94
|
+
/* warn = destructive ACTION tone; flame stays exclusively error STATUS. */
|
|
95
|
+
.ds-icon-btn-danger { background: var(--warn); color: var(--on-color); }
|
|
96
|
+
.ds-icon-btn-danger:hover { filter: brightness(0.92); }
|
|
97
|
+
.ds-icon-btn:active { transform: translateY(1px); }
|
|
98
|
+
.ds-icon-btn:disabled, .ds-icon-btn.is-disabled {
|
|
99
|
+
opacity: 0.5; cursor: not-allowed; pointer-events: none;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/* ============================================================
|
|
103
|
+
Badge — small inline count/status pill
|
|
104
|
+
============================================================ */
|
|
105
|
+
.ds-badge {
|
|
106
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
107
|
+
min-width: 18px; height: 18px; padding: 0 6px;
|
|
108
|
+
font-size: var(--fs-micro); font-weight: 600; line-height: 1;
|
|
109
|
+
border-radius: var(--r-pill);
|
|
110
|
+
background: var(--bg-3); color: var(--fg-2);
|
|
111
|
+
}
|
|
112
|
+
/* Badge size ladder — sm for dense inline counts, lg for prominent markers.
|
|
113
|
+
Base (above) stays the 18px default. */
|
|
114
|
+
.ds-badge.ds-badge--sm { min-width: 14px; height: 14px; padding: 0 var(--space-1); font-size: 10px; }
|
|
115
|
+
.ds-badge.ds-badge--lg { min-width: 22px; height: 22px; padding: 0 var(--space-2); font-size: var(--fs-tiny); }
|
|
116
|
+
/* Canonical tone names are tone-success / tone-error / tone-neutral. Every
|
|
117
|
+
other tone name grouped into the same rule below (tone-green/tone-live,
|
|
118
|
+
tone-flame, tone-wip, tone-sun/tone-yellow, tone-ok/tone-miss) is a
|
|
119
|
+
true-synonym legacy alias, kept working but sharing one declaration so the
|
|
120
|
+
tone-family colors can't drift apart across names. */
|
|
121
|
+
.ds-badge.tone-green, .ds-badge.tone-live, .ds-badge.tone-success {
|
|
122
|
+
background: var(--green-tint); color: var(--green-deep);
|
|
123
|
+
}
|
|
124
|
+
.ds-badge.tone-flame, .ds-badge.tone-error {
|
|
125
|
+
background: var(--flame); color: var(--on-color);
|
|
126
|
+
}
|
|
127
|
+
.ds-badge.tone-wip, .ds-badge.tone-neutral {
|
|
128
|
+
background: var(--bg-3); color: var(--fg-2);
|
|
129
|
+
}
|
|
130
|
+
.ds-badge.tone-purple { background: var(--purple-tint); color: var(--purple-deep); }
|
|
131
|
+
.ds-badge.tone-mascot { background: var(--mascot-tint); color: var(--ink); }
|
|
132
|
+
.ds-badge.tone-sun, .ds-badge.tone-yellow {
|
|
133
|
+
background: var(--sun); color: var(--ink);
|
|
134
|
+
}
|
|
135
|
+
.ds-badge.tone-blue { background: var(--accent-tint); color: var(--accent-ink); }
|
|
136
|
+
.ds-badge.tone-orange { background: color-mix(in oklab, var(--flame) 30%, var(--sun) 70%); color: var(--ink); }
|
|
137
|
+
|
|
138
|
+
.chip {
|
|
139
|
+
display: inline-flex; align-items: center; gap: var(--space-1-75);
|
|
140
|
+
padding: 3px 10px;
|
|
141
|
+
background: var(--bg-2); color: var(--fg-2);
|
|
142
|
+
font-family: var(--ff-body);
|
|
143
|
+
font-size: var(--fs-tiny); font-weight: 600;
|
|
144
|
+
letter-spacing: var(--tr-caps); text-transform: uppercase;
|
|
145
|
+
border-radius: var(--r-pill);
|
|
146
|
+
}
|
|
147
|
+
/* Chip size ladder — sm for dense toolbars/table cells, lg for prominent
|
|
148
|
+
status. tone-* colouring (below) is orthogonal to size. */
|
|
149
|
+
.chip.chip--sm { padding: var(--space-half) var(--space-2); font-size: var(--fs-micro); gap: var(--space-1); }
|
|
150
|
+
.chip.chip--lg { padding: var(--space-1-75) var(--space-2-75); font-size: var(--fs-xs); }
|
|
151
|
+
/* Tag variant — a rectangular, sentence-case chip for dense data (table cells,
|
|
152
|
+
inline labels) where the all-caps pill reads too shouty and space-hungry.
|
|
153
|
+
Keeps the tone-* palette; drops the caps + pill for a tight --r-0 corner. */
|
|
154
|
+
.chip.chip--tag {
|
|
155
|
+
text-transform: none; letter-spacing: 0; font-weight: 500;
|
|
156
|
+
border-radius: var(--r-0); padding: var(--space-half) var(--space-2);
|
|
157
|
+
}
|
|
158
|
+
/* Same canonical/legacy-alias grouping as .ds-badge above. */
|
|
159
|
+
.chip.tone-green, .chip.tone-live, .chip.tone-success, .chip.tone-ok {
|
|
160
|
+
background: var(--green-tint); color: var(--green-deep);
|
|
161
|
+
}
|
|
162
|
+
.chip.tone-flame, .chip.tone-error, .chip.tone-miss {
|
|
163
|
+
background: var(--flame); color: var(--on-color);
|
|
164
|
+
}
|
|
165
|
+
.chip.tone-wip, .chip.tone-neutral {
|
|
166
|
+
background: var(--bg-3); color: var(--fg-2);
|
|
167
|
+
}
|
|
168
|
+
.chip.tone-purple { background: var(--purple-tint); color: var(--purple-deep); }
|
|
169
|
+
.chip.tone-mascot { background: var(--mascot-tint); color: var(--ink); }
|
|
170
|
+
.chip.tone-sun, .chip.tone-yellow {
|
|
171
|
+
background: var(--sun); color: var(--ink);
|
|
172
|
+
}
|
|
173
|
+
.chip.tone-disabled { background: var(--bg-3); color: var(--fg-3); }
|
|
174
|
+
.chip.tone-blue { background: var(--accent-tint); color: var(--accent-ink); }
|
|
175
|
+
.chip.tone-orange { background: color-mix(in oklab, var(--flame) 30%, var(--sun) 70%); color: var(--ink); }
|
|
176
|
+
.chip.tone-yellow { background: var(--sun); color: var(--ink); }
|
|
177
|
+
|
|
178
|
+
/* ds-pill — plain neutral chip, distinct from the toned .ds-badge/.chip family
|
|
179
|
+
(gmsniff's .pill: a bare rounded label with no semantic tone). */
|
|
180
|
+
.ds-pill {
|
|
181
|
+
display: inline-block;
|
|
182
|
+
padding: 1px 7px;
|
|
183
|
+
border-radius: var(--r-pill);
|
|
184
|
+
font-size: var(--fs-micro);
|
|
185
|
+
background: var(--bg-3); color: var(--fg-2);
|
|
186
|
+
margin: 1px;
|
|
187
|
+
}
|
|
188
|
+
.ds-pill.tone-accent { background: var(--accent-tint); color: var(--accent-ink); }
|
|
189
|
+
.ds-pill.tone-muted { background: transparent; color: var(--fg-3); box-shadow: inset 0 0 0 1px var(--rule); }
|
|
190
|
+
|
|
191
|
+
.glyph {
|
|
192
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
193
|
+
width: 18px; height: 18px;
|
|
194
|
+
font-family: var(--ff-mono); font-size: var(--fs-tiny);
|
|
195
|
+
opacity: 0.8;
|
|
196
|
+
}
|
|
197
|
+
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
|
|
2
|
+
/* ============================================================
|
|
3
|
+
Responsive Design — Mobile (480px), Tablet (1024px), Desktop (1440px+)
|
|
4
|
+
============================================================ */
|
|
5
|
+
|
|
6
|
+
/* --------------------------------------------------------------------
|
|
7
|
+
Mobile Portrait Breakpoint (480px and below)
|
|
8
|
+
---------------------------------------------------------------------- */
|
|
9
|
+
@media (max-width: 480px) {
|
|
10
|
+
/* App Layout: single-column + drawer is handled once in the ≤900px block;
|
|
11
|
+
no need to re-declare grid-template-columns here (was a redundant !important). */
|
|
12
|
+
|
|
13
|
+
/* Topbar Navigation: stack the nav onto its own full-width row below the
|
|
14
|
+
brand and let it scroll horizontally. The brand stays on the first row;
|
|
15
|
+
nav wraps to a second row at 100% width (flex-wrap on .app-topbar). */
|
|
16
|
+
.app-topbar {
|
|
17
|
+
gap: var(--space-2); padding: 12px var(--space-3);
|
|
18
|
+
}
|
|
19
|
+
/* When the topbar is folded into .app-chrome it is a flex:0 0 auto child, so
|
|
20
|
+
it sizes to its nav's content and overflows the viewport instead of letting
|
|
21
|
+
the nav's own overflow-x:auto engage. Constrain it to the chrome width so
|
|
22
|
+
the horizontally-scrolling nav stays inside the screen. */
|
|
23
|
+
.app-chrome > .app-topbar { max-width: 100%; min-width: 0; flex-basis: 100%; }
|
|
24
|
+
.app-topbar > nav {
|
|
25
|
+
flex: 1 1 100%; margin-left: 0; order: 3; min-width: 0; max-width: 100%;
|
|
26
|
+
display: flex; gap: 2px; flex-wrap: nowrap;
|
|
27
|
+
overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch;
|
|
28
|
+
/* Fade the trailing edge so a clipped last item (e.g. "source ->" cut to
|
|
29
|
+
"sour") reads as scrollable content, not a broken/truncated label. */
|
|
30
|
+
mask-image: linear-gradient(90deg, var(--fg) 0 calc(100% - 28px), transparent 100%);
|
|
31
|
+
-webkit-mask-image: linear-gradient(90deg, var(--fg) 0 calc(100% - 28px), transparent 100%);
|
|
32
|
+
}
|
|
33
|
+
.app-topbar nav::-webkit-scrollbar { display: none; }
|
|
34
|
+
.app-topbar nav a {
|
|
35
|
+
flex: 0 0 auto; padding: 10px 12px; min-height: 44px; white-space: nowrap;
|
|
36
|
+
}
|
|
37
|
+
.brand { font-size: var(--fs-tiny); font-weight: 600; }
|
|
38
|
+
|
|
39
|
+
/* Search */
|
|
40
|
+
.app-search {
|
|
41
|
+
display: none; /* Hide search on mobile unless explicitly pinned */
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/* Main Content */
|
|
45
|
+
.app-main { padding: var(--space-4) var(--space-2); }
|
|
46
|
+
.app-main.narrow { max-width: 100%; margin: 0; }
|
|
47
|
+
|
|
48
|
+
/* Headings stay on the fluid base clamps (cqi) — no mobile re-clamp. */
|
|
49
|
+
|
|
50
|
+
/* Panel & Row */
|
|
51
|
+
.panel { margin: 0 0 var(--space-3); }
|
|
52
|
+
.panel-head { padding: var(--space-3) var(--space-2); gap: var(--space-2); }
|
|
53
|
+
.panel-body { padding: var(--space-2); overflow-x: auto; -webkit-overflow-scrolling: touch; }
|
|
54
|
+
.panel-body > table { min-width: 100%; }
|
|
55
|
+
|
|
56
|
+
.row {
|
|
57
|
+
grid-template-columns: minmax(0, 1fr) auto !important;
|
|
58
|
+
gap: var(--space-2); padding: 12px 16px;
|
|
59
|
+
row-gap: 4px !important;
|
|
60
|
+
}
|
|
61
|
+
.row .sub { grid-column: 1 / -1; order: 3; }
|
|
62
|
+
.row .title { font-size: var(--fs-sm); }
|
|
63
|
+
/* 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
|
+
.ds-changelog-row { grid-template-columns: minmax(70px, 10ch) minmax(0, 1fr) !important; }
|
|
66
|
+
.ds-changelog-row .title { grid-column: 1 / -1; }
|
|
67
|
+
|
|
68
|
+
/* Buttons */
|
|
69
|
+
.btn, .btn-primary, .btn-ghost {
|
|
70
|
+
padding: 11px 16px; font-size: var(--fs-tiny);
|
|
71
|
+
min-height: 44px; /* Touch target minimum */
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/* File Grid */
|
|
75
|
+
.ds-file-grid {
|
|
76
|
+
display: flex;
|
|
77
|
+
flex-direction: column;
|
|
78
|
+
gap: 3px;
|
|
79
|
+
}
|
|
80
|
+
.ds-file-row {
|
|
81
|
+
gap: 8px; padding: 10px 12px;
|
|
82
|
+
font-size: var(--fs-xs);
|
|
83
|
+
}
|
|
84
|
+
.ds-file-open { gap: 10px; }
|
|
85
|
+
/* At mobile row widths, a fixed-size meta column (date/size) plus the
|
|
86
|
+
always-visible action buttons leave the flexible title only a few px —
|
|
87
|
+
not enough for even one legible character before the two collide. Drop
|
|
88
|
+
the metadata column here; the title + actions still fully identify and
|
|
89
|
+
operate on the row, and meta stays available in the file viewer. */
|
|
90
|
+
.ds-file-row .ds-file-meta { display: none; }
|
|
91
|
+
.ds-file-row .ds-file-actions { opacity: 1; }
|
|
92
|
+
/* H4: floor finger-sized controls so file actions/sort/filter/breadcrumb are
|
|
93
|
+
reachable by touch (cohesion sweep). */
|
|
94
|
+
.ds-file-act, .ds-file-sort-btn, .ds-crumb-seg { min-height: 44px; }
|
|
95
|
+
.ds-file-filter-input { min-height: 44px; }
|
|
96
|
+
.ds-file-check, .ds-file-selectall, .ds-density-btn { min-height: 44px; min-width: 44px; }
|
|
97
|
+
|
|
98
|
+
/* Chat */
|
|
99
|
+
.chat-stack { max-width: 100%; min-width: 0; }
|
|
100
|
+
.chat-bubble {
|
|
101
|
+
padding: 10px 12px; font-size: var(--fs-sm);
|
|
102
|
+
}
|
|
103
|
+
.chat-avatar { width: 28px; height: 28px; font-size: 11px; }
|
|
104
|
+
.chat-msg:hover { padding: 4px 0; margin: 0; background: transparent; }
|
|
105
|
+
.chat-composer { padding: 8px; gap: 6px; }
|
|
106
|
+
.chat-composer textarea { padding: 10px 12px; font-size: var(--fs-sm); }
|
|
107
|
+
|
|
108
|
+
/* KPI Cards */
|
|
109
|
+
.kpi {
|
|
110
|
+
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
|
|
111
|
+
gap: var(--space-2);
|
|
112
|
+
}
|
|
113
|
+
.kpi-card { padding: var(--space-3); }
|
|
114
|
+
/* Container-relative like the base rule (5vw sized against the viewport and
|
|
115
|
+
jumped across the breakpoint). */
|
|
116
|
+
.kpi-card .num { font-size: clamp(22px, 8cqi, 32px); }
|
|
117
|
+
|
|
118
|
+
/* Empty State */
|
|
119
|
+
.empty { padding: var(--space-5); font-size: var(--fs-xs); }
|
|
120
|
+
|
|
121
|
+
/* Form */
|
|
122
|
+
.row-form { gap: 10px; padding: var(--space-3); }
|
|
123
|
+
.row-form input,
|
|
124
|
+
.row-form textarea { padding: 11px 12px; font-size: var(--fs-sm); }
|
|
125
|
+
|
|
126
|
+
/* Hero Section — keep fluid base font-size, just unconstrain width on mobile. */
|
|
127
|
+
.ds-hero { padding: var(--space-6) 0 var(--space-5); }
|
|
128
|
+
.ds-hero-title { max-width: 100%; }
|
|
129
|
+
.ds-hero-body { max-width: 100%; }
|
|
130
|
+
|
|
131
|
+
/* Table Responsiveness */
|
|
132
|
+
table { font-size: var(--fs-xs); }
|
|
133
|
+
table th,
|
|
134
|
+
table td { padding: 10px 12px; }
|
|
135
|
+
|
|
136
|
+
/* CLI Block */
|
|
137
|
+
.cli {
|
|
138
|
+
flex-direction: column; align-items: flex-start; gap: 10px;
|
|
139
|
+
padding: 16px 12px; font-size: var(--fs-xs);
|
|
140
|
+
}
|
|
141
|
+
.cli .copy { padding: 6px 12px; font-size: var(--fs-micro); }
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/* --------------------------------------------------------------------
|
|
145
|
+
Container Query Responsive (720px and below)
|
|
146
|
+
---------------------------------------------------------------------- */
|
|
147
|
+
@container (max-width: 760px) {
|
|
148
|
+
.app-body { grid-template-columns: 1fr !important; }
|
|
149
|
+
.app-side-shell { border-right: 0; border-bottom: 1px solid var(--rule); }
|
|
150
|
+
.app-topbar nav { font-size: var(--fs-xs); gap: 14px; }
|
|
151
|
+
.row { grid-template-columns: minmax(0, 1fr) auto !important; row-gap: 4px !important; }
|
|
152
|
+
.row .sub { grid-column: 1 / -1; order: 3; }
|
|
153
|
+
.ds-changelog-row { grid-template-columns: minmax(70px, 10ch) minmax(0, 1fr) !important; }
|
|
154
|
+
.ds-changelog-row .title { grid-column: 1 / -1; }
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/* --------------------------------------------------------------------
|
|
158
|
+
Tablet Landscape Breakpoint (768px to 1024px)
|
|
159
|
+
---------------------------------------------------------------------- */
|
|
160
|
+
@media (min-width: 481px) and (max-width: 1024px) {
|
|
161
|
+
/* App Layout — side handled by 900px drawer block; restore for 901-1024 */
|
|
162
|
+
.app-side a {
|
|
163
|
+
padding: 12px 12px; gap: 8px;
|
|
164
|
+
grid-template-columns: 16px 1fr auto;
|
|
165
|
+
font-size: var(--fs-xs);
|
|
166
|
+
min-height: 44px;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/* Topbar Navigation (flex container — no grid-template here) */
|
|
170
|
+
.app-topbar {
|
|
171
|
+
gap: var(--space-3); padding: 12px var(--space-4);
|
|
172
|
+
}
|
|
173
|
+
.app-topbar nav {
|
|
174
|
+
display: flex; gap: 8px; font-size: var(--fs-xs);
|
|
175
|
+
flex-wrap: wrap;
|
|
176
|
+
}
|
|
177
|
+
.app-topbar nav a {
|
|
178
|
+
padding: 12px 12px; font-size: var(--fs-xs);
|
|
179
|
+
min-height: 44px;
|
|
180
|
+
}
|
|
181
|
+
.brand { font-size: var(--fs-sm); }
|
|
182
|
+
|
|
183
|
+
/* Search */
|
|
184
|
+
.app-search {
|
|
185
|
+
display: inline-flex;
|
|
186
|
+
max-width: 280px; font-size: var(--fs-xs);
|
|
187
|
+
padding: 8px 14px;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/* Main Content */
|
|
191
|
+
.app-main { padding: var(--space-6) var(--space-4); }
|
|
192
|
+
.app-main.narrow { max-width: 100%; }
|
|
193
|
+
|
|
194
|
+
/* Headings stay on the fluid base clamps (cqi) — no tablet re-clamp. */
|
|
195
|
+
|
|
196
|
+
/* File list — single column rows on tablet (cards only via data-columns) */
|
|
197
|
+
.ds-file-row {
|
|
198
|
+
grid-template-columns: 24px minmax(0, 1fr) auto auto;
|
|
199
|
+
gap: 12px; padding: 12px 14px;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/* Chat Bubbles */
|
|
203
|
+
.chat-stack { max-width: min(75%, 420px); }
|
|
204
|
+
.chat-bubble {
|
|
205
|
+
padding: 11px 14px; font-size: var(--fs-sm);
|
|
206
|
+
}
|
|
207
|
+
.chat-avatar { width: 32px; height: 32px; font-size: 12px; }
|
|
208
|
+
|
|
209
|
+
/* KPI Cards */
|
|
210
|
+
.kpi {
|
|
211
|
+
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
|
|
212
|
+
gap: var(--space-3);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/* Buttons */
|
|
216
|
+
.btn, .btn-primary, .btn-ghost {
|
|
217
|
+
padding: 12px 18px; font-size: var(--fs-sm);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/* Panel - keep the head on the body's left axis at laptop widths too. */
|
|
221
|
+
.panel-head { padding: var(--space-2) var(--space-3); }
|
|
222
|
+
.panel-body { padding: var(--space-2) var(--space-3); }
|
|
223
|
+
|
|
224
|
+
/* Hero — fluid base font-size; only width unconstrained on tablet. */
|
|
225
|
+
.ds-hero { padding: var(--space-7) 0 var(--space-6); max-width: 100%; }
|
|
226
|
+
.ds-hero-title { max-width: 100%; }
|
|
227
|
+
|
|
228
|
+
/* Row */
|
|
229
|
+
.row {
|
|
230
|
+
grid-template-columns: minmax(90px, 12ch) minmax(0, 1fr) auto;
|
|
231
|
+
gap: var(--space-2); padding: 14px 16px;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/* --------------------------------------------------------------------
|
|
236
|
+
Mid Breakpoint (768px and below) — collapse sidebar + simplify row grid
|
|
237
|
+
---------------------------------------------------------------------- */
|
|
238
|
+
@media (max-width: 768px) {
|
|
239
|
+
/* Sidebar stacks above main rather than sitting beside it */
|
|
240
|
+
.app-body { grid-template-columns: 1fr; }
|
|
241
|
+
.app-side { width: 100%; max-width: none; }
|
|
242
|
+
|
|
243
|
+
/* Row drops the leading code column; title + meta share the line */
|
|
244
|
+
.row {
|
|
245
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
246
|
+
gap: var(--space-2);
|
|
247
|
+
}
|
|
248
|
+
.row .code { display: none; }
|
|
249
|
+
/* Changelog's date lives in span.code — hiding it is data loss, not reflow. */
|
|
250
|
+
.ds-changelog-row .code { display: inline; font-size: var(--fs-micro); }
|
|
251
|
+
.row .sub { grid-column: 1 / -1; }
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/* --------------------------------------------------------------------
|
|
255
|
+
Desktop Breakpoint Enhancements (1025px and up)
|
|
256
|
+
---------------------------------------------------------------------- */
|
|
257
|
+
@media (min-width: 1025px) {
|
|
258
|
+
/* Chat Bubbles */
|
|
259
|
+
.chat-stack { max-width: min(70%, 480px); }
|
|
260
|
+
|
|
261
|
+
/* KPI Cards */
|
|
262
|
+
.kpi {
|
|
263
|
+
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
|
|
264
|
+
gap: var(--space-3);
|
|
265
|
+
}
|
|
266
|
+
}
|