jekyll-theme-zer0 1.25.0 → 1.26.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.
@@ -0,0 +1,276 @@
1
+ // ============================================================================
2
+ // Page-feedback widget — global FAB + capture modal
3
+ // ----------------------------------------------------------------------------
4
+ // Markup: _includes/components/page-feedback.html
5
+ // Behaviour: assets/js/page-feedback.js
6
+ // Tokens: shared FAB + layer scale (_sass/tokens/_spacing.scss, _layers.scss)
7
+ // Theming: leans on Bootstrap 5.3 CSS variables (--bs-body-bg / -color /
8
+ // -border-color) so it follows [data-bs-theme] light/dark for free.
9
+ // ============================================================================
10
+
11
+ // --- Global FAB (bottom-left, clear of the right-hand FAB stack) ------------
12
+ .pf-fab {
13
+ position: fixed;
14
+ bottom: var(--zer0-space-fab-offset, 1rem);
15
+ left: var(--zer0-space-fab-offset, 1rem);
16
+ z-index: var(--zer0-layer-fab-feedback, 1051);
17
+
18
+ display: inline-flex;
19
+ align-items: center;
20
+ justify-content: center;
21
+ width: var(--zer0-space-fab-size, 3.5rem);
22
+ height: var(--zer0-space-fab-size, 3.5rem);
23
+ padding: 0;
24
+ border: 0;
25
+ border-radius: 50%;
26
+ background-color: var(--zer0-color-primary, var(--bs-primary));
27
+ color: #fff;
28
+ font-size: 1.25rem;
29
+ opacity: .9;
30
+ box-shadow: var(--zer0-shadow-fab, 0 .5rem 1rem rgba(0, 0, 0, .25));
31
+ transition:
32
+ opacity var(--zer0-motion-duration-fast, 120ms) var(--zer0-motion-ease-standard, ease),
33
+ transform var(--zer0-motion-duration-fast, 120ms) var(--zer0-motion-ease-standard, ease);
34
+
35
+ &:hover,
36
+ &:focus-visible {
37
+ opacity: 1;
38
+ color: #fff;
39
+ transform: translateY(-2px);
40
+ }
41
+ }
42
+
43
+ // Lock background scroll while the dialog is open (set by page-feedback.js).
44
+ .pf-no-scroll { overflow: hidden; }
45
+
46
+ // --- Modal overlay ----------------------------------------------------------
47
+ .pf-overlay {
48
+ position: fixed;
49
+ inset: 0;
50
+ z-index: var(--zer0-layer-feedback-modal, 1096); // above the cookie banner (1095)
51
+ display: flex;
52
+ align-items: flex-end; // bottom sheet on phones
53
+ justify-content: center;
54
+ background: rgba(0, 0, 0, .5);
55
+ opacity: 0;
56
+ transition: opacity var(--zer0-motion-duration, 180ms) var(--zer0-motion-ease-standard, ease);
57
+
58
+ &[hidden] { display: none; }
59
+ &.pf-overlay--open { opacity: 1; }
60
+
61
+ @media (min-width: 576px) {
62
+ align-items: center;
63
+ padding: var(--zer0-space-3, 1rem);
64
+ }
65
+ }
66
+
67
+ .pf-dialog {
68
+ display: flex;
69
+ flex-direction: column;
70
+ width: 100%;
71
+ max-width: 40rem;
72
+ max-height: 92vh;
73
+ overflow: hidden;
74
+ color: var(--bs-body-color);
75
+ background: var(--bs-body-bg);
76
+ border: 1px solid var(--bs-border-color, rgba(0, 0, 0, .15));
77
+ border-radius: 1rem 1rem 0 0;
78
+ transform: translateY(20px);
79
+ transition: transform var(--zer0-motion-duration, 180ms) var(--zer0-motion-ease-standard, ease);
80
+
81
+ .pf-overlay--open & { transform: translateY(0); }
82
+
83
+ @media (min-width: 576px) { border-radius: 1rem; }
84
+ }
85
+
86
+ // --- Header -----------------------------------------------------------------
87
+ .pf-header {
88
+ display: flex;
89
+ align-items: flex-start;
90
+ justify-content: space-between;
91
+ gap: var(--zer0-space-2, .5rem);
92
+ padding: var(--zer0-space-3, 1rem) var(--zer0-space-3, 1rem) var(--zer0-space-2, .5rem);
93
+ border-bottom: 1px solid var(--bs-border-color, rgba(0, 0, 0, .1));
94
+ }
95
+
96
+ .pf-title { display: flex; align-items: center; }
97
+
98
+ .pf-intro { font-size: .875rem; line-height: 1.4; }
99
+
100
+ .pf-close {
101
+ flex-shrink: 0;
102
+ color: var(--bs-body-color);
103
+ background: transparent;
104
+ border: 0;
105
+ opacity: .6;
106
+ &:hover, &:focus-visible { opacity: 1; }
107
+ }
108
+
109
+ // --- Body (scrolls) ---------------------------------------------------------
110
+ .pf-body {
111
+ flex: 1 1 auto;
112
+ overflow-y: auto;
113
+ padding: var(--zer0-space-3, 1rem);
114
+ display: flex;
115
+ flex-direction: column;
116
+ gap: var(--zer0-space-3, 1rem);
117
+ }
118
+
119
+ .pf-field { border: 0; padding: 0; margin: 0; min-width: 0; }
120
+
121
+ .pf-legend,
122
+ .pf-label {
123
+ display: block;
124
+ font-size: .8125rem;
125
+ font-weight: 600;
126
+ text-transform: uppercase;
127
+ letter-spacing: .02em;
128
+ color: var(--bs-secondary-color, var(--zer0-color-ink-muted, #6c757d));
129
+ margin-bottom: var(--zer0-space-2, .5rem);
130
+ }
131
+
132
+ .pf-help { font-size: .8125rem; margin: .35rem 0 0; }
133
+
134
+ // --- Type selector ----------------------------------------------------------
135
+ .pf-types-group {
136
+ font-size: .75rem;
137
+ font-weight: 600;
138
+ color: var(--bs-secondary-color, #6c757d);
139
+ margin: var(--zer0-space-2, .5rem) 0 .35rem;
140
+ }
141
+
142
+ .pf-types-grid {
143
+ display: grid;
144
+ grid-template-columns: 1fr;
145
+ gap: .5rem;
146
+
147
+ @media (min-width: 480px) { grid-template-columns: 1fr 1fr; }
148
+ }
149
+
150
+ .pf-type {
151
+ display: flex;
152
+ align-items: flex-start;
153
+ gap: .625rem;
154
+ text-align: left;
155
+ padding: .625rem .75rem;
156
+ background: var(--bs-body-bg);
157
+ border: 1px solid var(--bs-border-color, rgba(0, 0, 0, .15));
158
+ border-radius: .625rem;
159
+ cursor: pointer;
160
+ transition: border-color 120ms ease, background-color 120ms ease;
161
+
162
+ &:hover { border-color: var(--zer0-color-primary, var(--bs-primary)); }
163
+
164
+ &:focus-visible {
165
+ outline: 2px solid var(--zer0-color-primary, var(--bs-primary));
166
+ outline-offset: 2px;
167
+ }
168
+
169
+ &.pf-type--active {
170
+ border-color: var(--zer0-color-primary, var(--bs-primary));
171
+ background: color-mix(in srgb, var(--bs-primary) 10%, transparent);
172
+ box-shadow: inset 0 0 0 1px var(--zer0-color-primary, var(--bs-primary));
173
+ }
174
+ }
175
+
176
+ .pf-type-icon { flex-shrink: 0; margin-top: .1rem; font-size: 1rem; color: var(--zer0-color-primary, var(--bs-primary)); }
177
+ .pf-type-text { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
178
+ .pf-type-label { font-weight: 600; font-size: .9rem; line-height: 1.2; }
179
+ .pf-type-desc { font-size: .78rem; line-height: 1.3; color: var(--bs-secondary-color, #6c757d); }
180
+
181
+ // --- Context / logs ---------------------------------------------------------
182
+ .pf-summary { cursor: pointer; font-weight: 600; font-size: .875rem; }
183
+ .pf-context-count { color: var(--bs-secondary-color, #6c757d); font-weight: 400; }
184
+
185
+ .pf-context-list {
186
+ list-style: none;
187
+ margin: .5rem 0 0;
188
+ padding: 0;
189
+ font-size: .8125rem;
190
+
191
+ li { display: flex; gap: .5rem; padding: .15rem 0; }
192
+ }
193
+ .pf-context-key { flex: 0 0 4rem; color: var(--bs-secondary-color, #6c757d); }
194
+ .pf-context-val { min-width: 0; word-break: break-word; }
195
+
196
+ .pf-logs { margin-top: .75rem; }
197
+ .pf-check { display: flex; align-items: center; gap: .4rem; font-size: .8125rem; font-weight: 500; }
198
+ .pf-logs-preview {
199
+ max-height: 9rem;
200
+ overflow: auto;
201
+ margin: .5rem 0 0;
202
+ padding: .5rem .625rem;
203
+ font-size: .72rem;
204
+ line-height: 1.4;
205
+ white-space: pre-wrap;
206
+ word-break: break-word;
207
+ background: var(--bs-tertiary-bg, rgba(0, 0, 0, .04));
208
+ border: 1px solid var(--bs-border-color, rgba(0, 0, 0, .1));
209
+ border-radius: .5rem;
210
+ }
211
+
212
+ // --- AI enrichment ----------------------------------------------------------
213
+ .pf-ai-head { display: flex; align-items: center; flex-wrap: wrap; gap: .5rem; }
214
+ .pf-ai-hint { font-size: .8125rem; }
215
+ .pf-ai-result { margin-top: .625rem; font-size: .875rem; }
216
+ .pf-ai-card {
217
+ padding: .75rem .875rem;
218
+ background: var(--bs-tertiary-bg, rgba(0, 0, 0, .04));
219
+ border: 1px solid var(--bs-border-color, rgba(0, 0, 0, .1));
220
+ border-radius: .625rem;
221
+
222
+ p { margin: 0 0 .5rem; }
223
+ p:last-child { margin-bottom: 0; }
224
+ }
225
+ .pf-ai-badges .badge { margin-right: .25rem; }
226
+ .pf-ai-questions { margin: .25rem 0 .5rem 1.1rem; padding: 0; }
227
+ .pf-ai-labels code { font-size: .78rem; }
228
+ .pf-ai-error { color: var(--bs-danger-text-emphasis, var(--bs-danger)); }
229
+ .pf-ai-spinner,
230
+ .pf-ai-note i { color: var(--zer0-color-primary, var(--bs-primary)); }
231
+ .pf-ai-spinner {
232
+ display: inline-block;
233
+ width: .85rem;
234
+ height: .85rem;
235
+ border: 2px solid currentColor;
236
+ border-right-color: transparent;
237
+ border-radius: 50%;
238
+ vertical-align: -.1rem;
239
+ animation: pf-spin .7s linear infinite;
240
+ }
241
+ @keyframes pf-spin { to { transform: rotate(360deg); } }
242
+
243
+ // --- Status line ------------------------------------------------------------
244
+ .pf-status:empty { display: none; }
245
+ .pf-status {
246
+ font-size: .8125rem;
247
+ margin: 0;
248
+ padding: .5rem .625rem;
249
+ border-radius: .5rem;
250
+
251
+ &.pf-status--ok { background: var(--bs-success-bg-subtle, #d1e7dd); color: var(--bs-success-text-emphasis, #0a3622); }
252
+ &.pf-status--warn { background: var(--bs-warning-bg-subtle, #fff3cd); color: var(--bs-warning-text-emphasis, #664d03); }
253
+ &.pf-status--pending { background: var(--bs-info-bg-subtle, #cff4fc); color: var(--bs-info-text-emphasis, #055160); }
254
+ a { color: inherit; text-decoration: underline; }
255
+ }
256
+
257
+ // --- Footer -----------------------------------------------------------------
258
+ .pf-footer {
259
+ display: flex;
260
+ align-items: center;
261
+ justify-content: space-between;
262
+ gap: var(--zer0-space-2, .5rem);
263
+ padding: var(--zer0-space-2, .5rem) var(--zer0-space-3, 1rem);
264
+ border-top: 1px solid var(--bs-border-color, rgba(0, 0, 0, .1));
265
+ background: var(--bs-body-bg);
266
+ }
267
+ .pf-footer-primary { display: flex; gap: .5rem; }
268
+ .pf-copy { text-decoration: none; }
269
+
270
+ // --- Reduced motion ---------------------------------------------------------
271
+ @media (prefers-reduced-motion: reduce) {
272
+ .pf-fab,
273
+ .pf-overlay,
274
+ .pf-dialog { transition: none; }
275
+ .pf-ai-spinner { animation: none; }
276
+ }
@@ -546,7 +546,8 @@ a.bd-intro-badge--tag:focus {
546
546
  white-space: nowrap;
547
547
  }
548
548
 
549
- // Plain link buttons: reserve the same trailing space as .dropdown-toggle::after.
549
+ // Plain link buttons: reserve the same trailing space as .dropdown-toggle::after
550
+ // so the plain "Improve" / "Edit on GitHub" buttons line up with the Share caret.
550
551
  .bd-intro-action-link.btn::after {
551
552
  content: "";
552
553
  display: inline-block;
@@ -554,83 +555,6 @@ a.bd-intro-badge--tag:focus {
554
555
  flex-shrink: 0;
555
556
  visibility: hidden;
556
557
  }
557
-
558
- // Copilot Agent prompt menu — compact, proportional to the trigger button.
559
- // Scoped here so the Share dropdown keeps Bootstrap defaults.
560
- .copilot-agent-menu.dropdown-menu {
561
- --bs-dropdown-min-width: 0;
562
- width: max-content;
563
- max-width: min(22rem, 90vw);
564
- padding: var(--zer0-space-1) 0;
565
- border-radius: var(--bs-border-radius);
566
- border-color: var(--zer0-color-border);
567
- }
568
-
569
- .copilot-agent-menu {
570
- .dropdown-header {
571
- padding: var(--zer0-space-1) var(--zer0-space-2) calc(var(--zer0-space-1) * .5);
572
- font-size: var(--zer0-text-sm);
573
- font-weight: var(--zer0-font-weight-semibold);
574
- line-height: var(--zer0-leading-tight);
575
- color: var(--zer0-color-ink-muted);
576
- white-space: normal;
577
- }
578
-
579
- .dropdown-divider {
580
- margin: var(--zer0-space-1) 0;
581
- }
582
-
583
- .dropdown-item {
584
- white-space: normal;
585
- padding: var(--zer0-space-1) var(--zer0-space-2);
586
- line-height: var(--zer0-leading-normal);
587
- border-radius: calc(var(--bs-border-radius) - 2px);
588
-
589
- &:hover,
590
- &:focus {
591
- .copilot-agent-item__desc {
592
- color: inherit;
593
- opacity: .85;
594
- }
595
- }
596
- }
597
- }
598
-
599
- .copilot-agent-item {
600
- display: flex;
601
- align-items: flex-start;
602
- gap: var(--zer0-space-2);
603
- min-width: 0;
604
- }
605
-
606
- .copilot-agent-item__icon {
607
- flex-shrink: 0;
608
- margin-top: .125rem;
609
- font-size: var(--zer0-text-sm);
610
- line-height: 1;
611
- opacity: .85;
612
- }
613
-
614
- .copilot-agent-item__text {
615
- display: flex;
616
- flex-direction: column;
617
- gap: .125rem;
618
- min-width: 0;
619
- }
620
-
621
- .copilot-agent-item__label {
622
- font-size: var(--zer0-text-sm);
623
- font-weight: var(--zer0-font-weight-medium);
624
- line-height: var(--zer0-leading-tight);
625
- }
626
-
627
- .copilot-agent-item__desc {
628
- display: block;
629
- font-size: .8125rem;
630
- font-weight: var(--zer0-font-weight-regular);
631
- line-height: var(--zer0-leading-normal);
632
- color: var(--zer0-color-ink-muted);
633
- }
634
558
  }
635
559
 
636
560
  .bd-toc {
@@ -18,6 +18,7 @@
18
18
 
19
19
  // Floating action buttons (stack bottom-to-top) --------------------------
20
20
  --zer0-layer-fab-back-to-top: 1050;
21
+ --zer0-layer-fab-feedback: 1051; // page-feedback FAB (bottom-left)
21
22
  --zer0-layer-fab-chat: 1052;
22
23
  --zer0-layer-fab-toc: 1055;
23
24
  --zer0-layer-fab-local-graph: 1060;
@@ -25,6 +26,9 @@
25
26
  // Overlay surfaces -------------------------------------------------------
26
27
  --zer0-layer-offcanvas: 1045;
27
28
  --zer0-layer-modal: 1055;
29
+ --zer0-layer-feedback-modal: 1096; // page-feedback dialog — a focused dialog wins over
30
+ // every FAB, toast, AND the cookie banner (1095) so its
31
+ // controls are never intercepted; still below skip-link (1100)
28
32
  --zer0-layer-popover: 1070;
29
33
  --zer0-layer-tooltip: 1080;
30
34
 
data/assets/css/main.scss CHANGED
@@ -39,6 +39,7 @@
39
39
  @import "components/theme-preview";
40
40
  @import "components/content-tables";
41
41
  @import "components/search-modal";
42
+ @import "components/page-feedback";
42
43
 
43
44
  // 6. Layout partials
44
45
  @import "layouts/landing";