@farming-labs/astro-theme 0.0.3-beta.3 → 0.0.3-beta.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farming-labs/astro-theme",
3
- "version": "0.0.3-beta.3",
3
+ "version": "0.0.3-beta.5",
4
4
  "description": "Astro UI components for @farming-labs/docs — layout, sidebar, TOC, search, and theme toggle",
5
5
  "keywords": [
6
6
  "astro",
@@ -79,8 +79,8 @@
79
79
  },
80
80
  "dependencies": {
81
81
  "sugar-high": "^0.9.5",
82
- "@farming-labs/docs": "0.0.3-beta.3",
83
- "@farming-labs/astro": "0.0.3-beta.3"
82
+ "@farming-labs/docs": "0.0.3-beta.5",
83
+ "@farming-labs/astro": "0.0.3-beta.5"
84
84
  },
85
85
  "peerDependencies": {
86
86
  "astro": ">=4.0.0"
@@ -281,14 +281,46 @@ const parentUrl = segments.length >= 2
281
281
 
282
282
  const activeSet = new Set();
283
283
  let tocUpdateScheduled = false;
284
+ let lastStableId = null;
285
+ let scrollRafId = 0;
286
+ const ACTIVE_ZONE_TOP = 120;
287
+ const HYSTERESIS_PX = 65; /* same as Nuxt/Svelte — keeps TOC highlight smooth (no flicker) */
284
288
 
285
- function scheduleTocActiveUpdate() {
289
+ function getDistanceToZone(id) {
290
+ const el = document.getElementById(id);
291
+ if (!el) return Infinity;
292
+ const rect = el.getBoundingClientRect();
293
+ const mid = rect.top + rect.height / 2;
294
+ return Math.abs(mid - ACTIVE_ZONE_TOP);
295
+ }
296
+
297
+ function getClosestId() {
298
+ let bestId = null;
299
+ let bestDistance = Infinity;
300
+ tocItems.forEach(function(item) {
301
+ const d = getDistanceToZone(item.id);
302
+ if (d < bestDistance) {
303
+ bestDistance = d;
304
+ bestId = item.id;
305
+ }
306
+ });
307
+ return bestId;
308
+ }
309
+
310
+ function isInView(id) {
311
+ const el = document.getElementById(id);
312
+ if (!el) return false;
313
+ const rect = el.getBoundingClientRect();
314
+ return rect.top < window.innerHeight && rect.bottom > 0;
315
+ }
316
+
317
+ function applyActiveSet() {
286
318
  if (tocUpdateScheduled) return;
287
319
  tocUpdateScheduled = true;
288
- requestAnimationFrame(() => {
320
+ requestAnimationFrame(function() {
289
321
  tocUpdateScheduled = false;
290
322
  if (isClerk) {
291
- tocList.querySelectorAll('.fd-toc-clerk-link').forEach(link => {
323
+ tocList.querySelectorAll('.fd-toc-clerk-link').forEach(function(link) {
292
324
  const id = link.getAttribute('href')?.slice(1);
293
325
  if (activeSet.has(id)) {
294
326
  link.setAttribute('data-active', 'true');
@@ -298,7 +330,7 @@ const parentUrl = segments.length >= 2
298
330
  });
299
331
  if (typeof updateThumb === 'function') updateThumb(activeSet);
300
332
  } else {
301
- tocList.querySelectorAll('.fd-toc-link').forEach(link => {
333
+ tocList.querySelectorAll('.fd-toc-link').forEach(function(link) {
302
334
  const id = link.getAttribute('href')?.slice(1);
303
335
  link.classList.toggle('fd-toc-link-active', activeSet.has(id));
304
336
  });
@@ -306,18 +338,50 @@ const parentUrl = segments.length >= 2
306
338
  });
307
339
  }
308
340
 
309
- const observer = new IntersectionObserver((entries) => {
310
- for (const entry of entries) {
311
- if (entry.isIntersecting) {
312
- activeSet.add(entry.target.id);
313
- } else {
314
- activeSet.delete(entry.target.id);
315
- }
341
+ function updateTocFromScroll() {
342
+ scrollRafId = 0;
343
+ const newId = getClosestId();
344
+ if (!newId) {
345
+ activeSet.clear();
346
+ applyActiveSet();
347
+ return;
348
+ }
349
+ if (lastStableId === null) {
350
+ lastStableId = newId;
351
+ activeSet.clear();
352
+ activeSet.add(newId);
353
+ applyActiveSet();
354
+ return;
316
355
  }
317
- scheduleTocActiveUpdate();
318
- }, { rootMargin: '-80px 0px -80% 0px' });
356
+ if (newId === lastStableId) {
357
+ activeSet.clear();
358
+ activeSet.add(newId);
359
+ applyActiveSet();
360
+ return;
361
+ }
362
+ const newDist = getDistanceToZone(newId);
363
+ const currentDist = getDistanceToZone(lastStableId);
364
+ const switchToNew = newDist <= currentDist - HYSTERESIS_PX || !isInView(lastStableId);
365
+ if (switchToNew) lastStableId = newId;
366
+ activeSet.clear();
367
+ activeSet.add(lastStableId);
368
+ applyActiveSet();
369
+ }
319
370
 
320
- headings.forEach(el => observer.observe(el));
371
+ function scheduleTocFromScroll() {
372
+ if (scrollRafId !== 0) return;
373
+ scrollRafId = requestAnimationFrame(updateTocFromScroll);
374
+ }
375
+
376
+ window.addEventListener('scroll', scheduleTocFromScroll, { passive: true, capture: true });
377
+ document.addEventListener('scroll', scheduleTocFromScroll, { passive: true, capture: true });
378
+
379
+ var initialId = getClosestId();
380
+ if (initialId) {
381
+ lastStableId = initialId;
382
+ activeSet.add(initialId);
383
+ }
384
+ applyActiveSet();
321
385
 
322
386
  if (tocAside) tocAside.setAttribute('data-toc-ready', 'true');
323
387
  }
@@ -130,6 +130,8 @@ const { config = null } = Astro.props;
130
130
  if (dialog) {
131
131
  dialog.style.display = "block";
132
132
  document.body.style.overflow = "hidden";
133
+ bindListboxDelegation();
134
+ ensureListboxClickBound();
133
135
  setTimeout(function () {
134
136
  var input = getInput();
135
137
  if (input) { input.value = ""; input.focus(); }
@@ -237,49 +239,95 @@ const { config = null } = Astro.props;
237
239
  scrollActiveIntoView();
238
240
  }
239
241
 
242
+ function navigateToUrl(url, newTab) {
243
+ if (!url) return;
244
+ if (newTab || url.startsWith("http")) {
245
+ try {
246
+ window.open(url, "_blank", "noopener,noreferrer");
247
+ } catch (err) {
248
+ window.location.assign(url);
249
+ }
250
+ } else {
251
+ window.location.assign(url);
252
+ }
253
+ }
254
+
255
+ function handleOmniItemClick(e) {
256
+ var dialog = getDialog();
257
+ if (!dialog || dialog.style.display === "none") return;
258
+ var withinDialog = e.target.closest && e.target.closest("#fd-search-dialog");
259
+ if (!withinDialog) return;
260
+
261
+ var ext = e.target.closest && e.target.closest("a.omni-item-ext");
262
+ if (ext) {
263
+ e.preventDefault();
264
+ e.stopPropagation();
265
+ var url = ext.getAttribute("data-ext-url") || ext.getAttribute("href");
266
+ navigateToUrl(url, true);
267
+ return;
268
+ }
269
+ var row = e.target.closest && e.target.closest(".omni-item[data-url]");
270
+ if (row) {
271
+ e.preventDefault();
272
+ e.stopPropagation();
273
+ var url = row.getAttribute("data-url");
274
+ if (!url) return;
275
+ var labelEl = row.querySelector(".omni-item-label");
276
+ var label = labelEl ? labelEl.textContent : url;
277
+ saveRecent({ id: url, label: label, url: url });
278
+ closeDialog();
279
+ navigateToUrl(url, url.startsWith("http"));
280
+ }
281
+ }
282
+
283
+ function handleOmniItemMouseOver(e) {
284
+ var dialog = getDialog();
285
+ if (!dialog || dialog.style.display === "none") return;
286
+ var row = e.target.closest && e.target.closest(".omni-item[data-url]");
287
+ if (row) {
288
+ var container = row.closest("#fd-omni-recent-items") || row.closest("#fd-omni-docs-items");
289
+ if (container) {
290
+ var items = container.querySelectorAll(".omni-item[data-url]");
291
+ var idx = Array.prototype.indexOf.call(items, row);
292
+ if (idx >= 0) { activeIndex = idx; render(); }
293
+ }
294
+ }
295
+ }
296
+
240
297
  function bindListboxDelegation() {
298
+ if (document.body.hasAttribute("data-fd-omni-click-delegation")) return;
299
+ document.body.setAttribute("data-fd-omni-click-delegation", "true");
300
+ document.addEventListener("click", handleOmniItemClick, true);
301
+ document.addEventListener("mouseover", handleOmniItemMouseOver, true);
302
+ }
303
+
304
+ function ensureListboxClickBound() {
241
305
  var listbox = getListbox();
242
- if (!listbox || listbox._fdOmniBound) return;
243
- listbox._fdOmniBound = true;
244
- listbox.addEventListener("click", function (e) {
306
+ if (!listbox || listbox._fdOmniClickBound) return;
307
+ listbox._fdOmniClickBound = true;
308
+ function onListboxClick(e) {
245
309
  var ext = e.target.closest && e.target.closest("a.omni-item-ext");
246
310
  if (ext) {
247
311
  e.preventDefault();
248
312
  e.stopPropagation();
249
313
  var url = ext.getAttribute("data-ext-url") || ext.getAttribute("href");
250
- if (url) {
251
- try {
252
- window.open(url, "_blank", "noopener,noreferrer");
253
- } catch (err) {
254
- window.location.href = url;
255
- }
256
- }
314
+ navigateToUrl(url, true);
257
315
  return;
258
316
  }
259
317
  var row = e.target.closest && e.target.closest(".omni-item[data-url]");
260
318
  if (row) {
261
319
  e.preventDefault();
320
+ e.stopPropagation();
262
321
  var url = row.getAttribute("data-url");
263
322
  if (!url) return;
264
323
  var labelEl = row.querySelector(".omni-item-label");
265
324
  var label = labelEl ? labelEl.textContent : url;
266
325
  saveRecent({ id: url, label: label, url: url });
267
- if (url.startsWith("http")) window.open(url, "_blank", "noopener,noreferrer");
268
- else window.location.href = url;
269
326
  closeDialog();
327
+ navigateToUrl(url, url.startsWith("http"));
270
328
  }
271
- });
272
- listbox.addEventListener("mouseover", function (e) {
273
- var row = e.target.closest && e.target.closest(".omni-item[data-url]");
274
- if (row) {
275
- var container = row.closest("#fd-omni-recent-items") || row.closest("#fd-omni-docs-items");
276
- if (container) {
277
- var items = container.querySelectorAll(".omni-item[data-url]");
278
- var idx = Array.prototype.indexOf.call(items, row);
279
- if (idx >= 0) { activeIndex = idx; render(); }
280
- }
281
- }
282
- });
329
+ }
330
+ listbox.addEventListener("click", onListboxClick, true);
283
331
  }
284
332
 
285
333
  function scrollActiveIntoView() {
@@ -71,7 +71,9 @@ h3 {
71
71
  font-weight: 600;
72
72
  line-height: 1.3;
73
73
  }
74
-
74
+ .fd-docs-content {
75
+ border: none !important;
76
+ }
75
77
  .fd-docs-content p {
76
78
  font-size: 1rem;
77
79
  line-height: 1.7;
@@ -86,40 +88,38 @@ aside#nd-sidebar,
86
88
  #nd-docs-layout aside,
87
89
  .fd-sidebar {
88
90
  border: none;
89
- border-right: none;
91
+ border-right: 1px solid var(--color-fd-border);
90
92
  border-left: none;
91
- border-color: transparent;
92
93
  box-shadow: none;
93
94
  background: var(--color-fd-background);
94
95
  }
95
96
 
96
97
  .dark .fd-sidebar {
97
- background: var(--fd-sidebar-bg, #1a1a1a);
98
+ background: var(--color-fd-background);
98
99
  }
99
100
 
100
101
  .dark .fd-sidebar .fd-sidebar-title {
101
102
  font-size: 1.125rem;
102
103
  font-weight: 600;
103
- color: #e0e0e0;
104
+ color: var(--color-fd-foreground);
104
105
  }
105
106
 
106
- /* Search bar — rounded, darker grey background, ⌘ K badges */
107
107
  .dark .fd-sidebar .fd-sidebar-search-btn {
108
- background: var(--fd-sidebar-card-bg, #252525) !important;
109
- border: 1px solid var(--fd-sidebar-indent-line, #3c3c3c);
108
+ background: var(--color-fd-secondary) !important;
109
+ border: 1px solid var(--color-fd-border);
110
110
  border-radius: 8px;
111
- color: #a0a0a0;
111
+ color: var(--color-fd-muted-foreground);
112
112
  font-size: 0.875rem;
113
113
  }
114
114
 
115
115
  .dark .fd-sidebar .fd-sidebar-search-btn:hover {
116
- background: #2d2d2d !important;
116
+ background: var(--color-fd-accent) !important;
117
117
  }
118
118
 
119
119
  .dark .fd-sidebar .fd-sidebar-search-btn kbd {
120
- background: #404040 !important;
121
- border-color: #3c3c3c;
122
- color: #a0a0a0;
120
+ background: var(--color-fd-muted) !important;
121
+ border-color: var(--color-fd-border);
122
+ color: var(--color-fd-muted-foreground);
123
123
  border-radius: 4px;
124
124
  padding: 2px 6px;
125
125
  font-size: 11px;
@@ -135,7 +135,7 @@ aside a[data-active],
135
135
  .fd-sidebar .fd-sidebar-link {
136
136
  font-size: 0.875rem;
137
137
  line-height: 1.5;
138
- font-weight: 400;
138
+ font-weight: 500;
139
139
  padding: 6px 10px;
140
140
  border-radius: 8px;
141
141
  color: var(--color-fd-muted-foreground);
@@ -143,7 +143,7 @@ aside a[data-active],
143
143
  }
144
144
 
145
145
  .dark .fd-sidebar .fd-sidebar-link {
146
- color: #e0e0e0;
146
+ color: var(--color-fd-muted-foreground);
147
147
  }
148
148
 
149
149
  aside a[data-active]:hover,
@@ -153,69 +153,50 @@ aside a[data-active]:hover,
153
153
  }
154
154
 
155
155
  .dark .fd-sidebar .fd-sidebar-link:hover {
156
- color: #e0e0e0;
157
- background: #2d2d2d;
156
+ color: var(--color-fd-foreground);
157
+ background: var(--color-fd-accent);
158
158
  }
159
159
 
160
+ /* Active sidebar item — green tinted background + left highlight line */
160
161
  aside a[data-active="true"],
161
162
  .fd-sidebar .fd-sidebar-link-active,
162
163
  .fd-sidebar .fd-sidebar-link[data-active="true"] {
164
+ position: relative !important;
163
165
  color: var(--color-fd-primary) !important;
164
166
  font-weight: 600 !important;
165
- background: transparent !important;
166
- background-color: transparent !important;
167
+ background: rgba(13, 147, 115, 0.08) !important;
168
+ background-color: rgba(13, 147, 115, 0.08) !important;
167
169
  }
168
170
 
169
171
  .dark .fd-sidebar .fd-sidebar-link-active,
170
172
  .dark .fd-sidebar .fd-sidebar-link[data-active="true"] {
171
- color: var(--fd-sidebar-active-text, #50c878) !important;
172
- background: transparent !important;
173
- background-color: transparent !important;
173
+ color: var(--color-fd-primary) !important;
174
+ background: rgba(38, 189, 108, 0.1) !important;
175
+ background-color: rgba(38, 189, 108, 0.1) !important;
174
176
  }
175
177
 
176
178
  .fd-sidebar-folder-content .fd-sidebar-link-active::before,
177
179
  .fd-sidebar-folder-content .fd-sidebar-link[data-active="true"]::before {
178
- content: "";
179
- position: absolute;
180
- left: 0;
181
- top: 0;
182
- bottom: 0;
183
- width: 2px;
184
- background: var(--fd-sidebar-active-line, #50c878);
185
- border-radius: 0;
186
- }
187
-
188
- .dark .fd-sidebar-folder-content .fd-sidebar-link-active::before,
189
- .dark .fd-sidebar-folder-content .fd-sidebar-link[data-active="true"]::before {
190
- background: var(--fd-sidebar-active-line, #50c878);
180
+ content: "" !important;
181
+ display: block !important;
182
+ position: absolute !important;
183
+ left: -9px !important;
184
+ top: 20% !important;
185
+ bottom: 20% !important;
186
+ width: 3px !important;
187
+ background: var(--color-fd-primary) !important;
191
188
  }
192
189
 
193
190
  .fd-sidebar .fd-sidebar-top-link.fd-sidebar-link-active,
194
191
  .fd-sidebar .fd-sidebar-top-link[data-active="true"] {
195
- background: transparent !important;
196
- background-color: transparent !important;
192
+ background: rgba(13, 147, 115, 0.08) !important;
193
+ background-color: rgba(13, 147, 115, 0.08) !important;
197
194
  }
198
195
 
199
- .fd-sidebar .fd-sidebar-top-link.fd-sidebar-link-active::before,
200
- .fd-sidebar .fd-sidebar-top-link[data-active="true"]::before {
201
- content: "";
202
- position: absolute;
203
- left: 0;
204
- top: 25%;
205
- bottom: 25%;
206
- width: 2px;
207
- background: var(--color-fd-primary);
208
- border-radius: 1px;
209
- }
210
-
211
- .dark .fd-sidebar .fd-sidebar-top-link.fd-sidebar-link-active::before,
212
- .dark .fd-sidebar .fd-sidebar-top-link[data-active="true"]::before {
213
- background: var(--fd-sidebar-active-line, #50c878);
214
- }
215
-
216
- aside a[data-active="true"]::before {
217
- background-color: transparent;
218
- width: 0;
196
+ .dark .fd-sidebar .fd-sidebar-top-link.fd-sidebar-link-active,
197
+ .dark .fd-sidebar .fd-sidebar-top-link[data-active="true"] {
198
+ background: rgba(38, 189, 108, 0.1) !important;
199
+ background-color: rgba(38, 189, 108, 0.1) !important;
219
200
  }
220
201
 
221
202
  .dark .fd-sidebar .fd-sidebar-folder {
@@ -236,14 +217,14 @@ aside a[data-active].w-full,
236
217
  font-weight: 600;
237
218
  font-size: 0.875rem;
238
219
  color: var(--color-fd-foreground);
239
- padding: 7px 10px 8px 10px;
220
+ padding: 4px 10px 4px 10px;
240
221
  margin-top: 0;
241
222
  border: none;
242
223
  background: transparent !important;
243
224
  }
244
225
 
245
226
  .dark .fd-sidebar .fd-sidebar-folder-trigger {
246
- color: #e0e0e0;
227
+ color: var(--color-fd-muted-foreground);
247
228
  }
248
229
 
249
230
  .fd-sidebar .fd-sidebar-folder-trigger:hover {
@@ -251,7 +232,7 @@ aside a[data-active].w-full,
251
232
  }
252
233
 
253
234
  .dark .fd-sidebar .fd-sidebar-folder-trigger:hover {
254
- background: #2d2d2d !important;
235
+ background: var(--color-fd-accent) !important;
255
236
  }
256
237
 
257
238
  aside a[data-active].w-full:first-child,
@@ -277,7 +258,7 @@ aside a[data-active="true"].w-full,
277
258
 
278
259
  .dark .fd-sidebar .fd-sidebar-top-link.fd-sidebar-link-active,
279
260
  .dark .fd-sidebar .fd-sidebar-top-link[data-active="true"] {
280
- color: var(--fd-sidebar-active-text, #50c878) !important;
261
+ color: var(--color-fd-primary) !important;
281
262
  }
282
263
 
283
264
  aside div.w-full:not([role]) {
@@ -293,14 +274,15 @@ aside div.w-full:not([role]) {
293
274
  position: relative;
294
275
  padding-left: 16px;
295
276
  margin-left: 8px;
296
- margin-top: 2px;
277
+ margin-top: -12px;
297
278
  }
298
279
 
299
280
  .fd-sidebar .fd-sidebar-folder-content::before {
300
281
  content: "";
301
282
  position: absolute;
302
- left: 4px;
303
- top: 4px;
283
+ left: 8px;
284
+ top: 8px;
285
+ height: 90%;
304
286
  bottom: 4px;
305
287
  width: 1px;
306
288
  background: var(--color-fd-border);
@@ -322,7 +304,7 @@ aside .border-t,
322
304
  aside [class*="border-t"],
323
305
  .fd-sidebar .fd-sidebar-footer,
324
306
  .fd-sidebar .fd-sidebar-footer-custom {
325
- border-top-color: transparent;
307
+ border-top: 1px solid var(--color-fd-border);
326
308
  }
327
309
 
328
310
  /* ═══════════════════════════════════════════════════════════════════
@@ -369,7 +351,6 @@ nav[class*="header"] {
369
351
  border-spacing: 0;
370
352
  background: var(--color-fd-card);
371
353
  border-radius: 8px;
372
- border: 1px solid var(--color-fd-border);
373
354
  overflow: hidden;
374
355
  width: 100%;
375
356
  }
@@ -393,6 +374,10 @@ nav[class*="header"] {
393
374
  .fd-docs-content tr:last-child td {
394
375
  border-bottom: none;
395
376
  }
377
+ .fd-last-modified-below-title p {
378
+ font-size: 0.65rem;
379
+ color: var(--color-fd-muted-foreground);
380
+ }
396
381
 
397
382
  .fd-docs-content blockquote {
398
383
  border-left: 3px solid var(--color-fd-primary);
@@ -402,6 +387,24 @@ nav[class*="header"] {
402
387
  margin: 1rem 0;
403
388
  }
404
389
 
390
+ .fd-page-actions, [data-page-actions] {
391
+ gap: 0 !important;
392
+ }
393
+
394
+ .fd-page-actions .fd-page-action-btn:nth-child(2) {
395
+ border-top-right-radius: 0 !important;
396
+ border-bottom-right-radius: 0 !important;
397
+ }
398
+
399
+ .fd-page-actions, [data-page-actions] .fd-page-action-btn:first-child {
400
+ border-top-left-radius: 0 !important;
401
+ border-bottom-left-radius: 0 !important;
402
+ border-left: none !important;
403
+ }
404
+ /* .fd-page-actions > :first-child > .fd-page-action-btn {
405
+ border-right: none !important;
406
+ background: red !important;
407
+ } */
405
408
  .fd-docs-content hr {
406
409
  border-color: var(--color-fd-border);
407
410
  }
@@ -539,21 +542,31 @@ details > :not(summary) {
539
542
  padding: 0.75rem 1rem;
540
543
  }
541
544
 
542
- #nd-toc a[data-active="true"] {
545
+ /* TOC — use .fd-toc (matches layout); transition reduces flash when scroll spy toggles active */
546
+ .fd-toc .fd-toc-link,
547
+ .fd-toc .fd-toc-clerk-link {
548
+ transition: color 0.2s ease;
549
+ }
550
+
551
+ .fd-toc .fd-toc-link-active,
552
+ .fd-toc .fd-toc-link[data-active="true"],
553
+ .fd-toc .fd-toc-clerk-link[data-active="true"] {
543
554
  color: var(--color-fd-primary);
544
555
  font-weight: 500;
545
556
  }
546
557
 
547
- #nd-toc a[data-active="false"] {
558
+ .fd-toc .fd-toc-link:not(.fd-toc-link-active):not([data-active="true"]),
559
+ .fd-toc .fd-toc-clerk-link:not([data-active="true"]) {
548
560
  color: var(--color-fd-muted-foreground);
549
561
  }
550
562
 
551
- #nd-toc a {
563
+ .fd-toc .fd-toc-link,
564
+ .fd-toc .fd-toc-clerk-link {
552
565
  font-size: 0.875rem;
553
566
  line-height: 1.3;
554
567
  }
555
568
 
556
- #nd-toc h3 {
569
+ .fd-toc .fd-toc-title {
557
570
  font-size: 0.875rem;
558
571
  font-weight: 500;
559
572
  }
@@ -591,6 +604,7 @@ details > :not(summary) {
591
604
  }
592
605
 
593
606
  .fd-page-description {
607
+ margin-bottom: 1rem;
594
608
  font-size: 1rem;
595
609
  line-height: 1.7;
596
610
  color: var(--color-fd-muted-foreground);
@@ -692,11 +706,42 @@ details > :not(summary) {
692
706
  filter: brightness(1.1);
693
707
  }
694
708
 
695
- .fd-ai-suggestion,
709
+ .fd-ai-suggestion {
710
+ border-radius: 10px;
711
+ }
712
+
696
713
  .fd-ai-result {
697
714
  border-radius: 10px;
698
715
  }
699
716
 
717
+ .fd-ai-fm-input-container {
718
+ border-radius: 12px;
719
+ }
720
+
721
+ .fd-ai-fm-send-btn {
722
+ border-radius: 9999px;
723
+ }
724
+
725
+ .fd-ai-fm-suggestion {
726
+ border-radius: 9999px;
727
+ }
728
+
729
+ .fd-ai-fm-trigger-btn {
730
+ border-radius: 16px;
731
+ }
732
+
733
+ .fd-ai-fm-close-btn {
734
+ border-radius: 9999px;
735
+ }
736
+
737
+ .fd-ai-code-block {
738
+ border-radius: 10px;
739
+ }
740
+
741
+ .fd-ai-code-copy {
742
+ border-radius: 6px;
743
+ }
744
+
700
745
  .fd-sidebar-search-ai-row {
701
746
  display: flex;
702
747
  gap: 8px;
@@ -773,54 +818,7 @@ details > :not(summary) {
773
818
  height: 16px;
774
819
  }
775
820
 
776
- .fd-page-actions {
777
- display: flex;
778
- gap: 0;
779
- align-items: stretch;
780
- }
781
-
782
- .fd-page-action-btn {
783
- display: inline-flex;
784
- align-items: center;
785
- gap: 6px;
786
- padding: 6px 12px;
787
- font-size: 0.8125rem;
788
- font-weight: 500;
789
- color: var(--color-fd-muted-foreground);
790
- background: transparent;
791
- border: 1px solid var(--color-fd-border);
792
- cursor: pointer;
793
- transition:
794
- background-color 150ms,
795
- color 150ms;
796
- white-space: nowrap;
797
- }
798
-
799
- .fd-page-action-btn:hover {
800
- background: var(--color-fd-accent);
801
- color: var(--color-fd-foreground);
802
- }
803
-
804
- .fd-page-actions .fd-page-action-btn:first-child {
805
- border-radius: 8px 0 0 8px;
806
- border-right: none;
807
- }
808
-
809
- .fd-page-actions .fd-page-action-dropdown:last-child .fd-page-action-btn,
810
- .fd-page-actions > .fd-page-action-btn:last-child {
811
- border-radius: 0 8px 8px 0;
812
- border-left: 1px solid var(--color-fd-border);
813
- padding: 6px 8px;
814
- }
815
-
816
- .fd-page-actions .fd-page-action-btn:only-child {
817
- border-radius: 8px;
818
- border: 1px solid var(--color-fd-border);
819
- }
820
-
821
- .fd-page-action-dropdown {
822
- position: relative;
823
- }
821
+ /* Page actions — greentree style overrides on top of Astro base layout */
824
822
 
825
823
  .fd-sidebar::-webkit-scrollbar {
826
824
  width: 4px;
@@ -705,3 +705,41 @@ code:not(pre code) {
705
705
  .fd-ai-code-block code {
706
706
  font-family: var(--fd-font-mono, ui-monospace, monospace);
707
707
  }
708
+
709
+ /* Light mode: AI code blocks — light bg + dark text + visible pixel border */
710
+ :root:not(.dark) .fd-ai-code-block {
711
+ background: #f4f4f5 !important;
712
+ box-shadow: 3px 3px 0 0 hsl(0 0% 75%);
713
+ --sh-class: #b45309;
714
+ --sh-identifier: #1f2937;
715
+ --sh-keyword: #7c3aed;
716
+ --sh-string: #0d9488;
717
+ --sh-property: #dc2626;
718
+ --sh-entity: #059669;
719
+ --sh-sign: #374151;
720
+ --sh-comment: #6b7280;
721
+ --sh-jsxliterals: #7c3aed;
722
+ }
723
+
724
+ :root:not(.dark) .fd-ai-code-header {
725
+ border-bottom-color: hsl(0 0% 80%);
726
+ background: color-mix(in srgb, #e4e4e7 90%, transparent);
727
+ }
728
+
729
+ :root:not(.dark) .fd-ai-code-lang {
730
+ color: #52525b;
731
+ }
732
+
733
+ :root:not(.dark) .fd-ai-code-copy {
734
+ color: #52525b;
735
+ border-color: hsl(0 0% 75%);
736
+ }
737
+
738
+ :root:not(.dark) .fd-ai-code-copy:hover {
739
+ color: #18181b;
740
+ background: color-mix(in srgb, #d4d4d8 70%, transparent);
741
+ }
742
+
743
+ :root:not(.dark) .fd-ai-code-block code {
744
+ color: #1f2937;
745
+ }