@veluai/velu 0.2.41 → 0.2.43

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.
Files changed (42) hide show
  1. package/dist/cli.js +43 -43
  2. package/docs/kadhir.md +31 -0
  3. package/docs/mintlify-migration.md +2 -0
  4. package/package.json +3 -2
  5. package/runtime/velu-ui/base.css +4 -0
  6. package/runtime/velu-ui/components/ApiReferencePage.jsx +4 -4
  7. package/runtime/velu-ui/components/ApiSamples.jsx +2 -2
  8. package/runtime/velu-ui/components/Card.jsx +6 -1
  9. package/runtime/velu-ui/components/PageFooter.jsx +1 -1
  10. package/runtime/velu-ui/components/PageHeader.jsx +8 -19
  11. package/runtime/velu-ui/components/PoweredBy.jsx +2 -0
  12. package/runtime/velu-ui/components/VepaFooter.jsx +5 -4
  13. package/runtime/velu-ui/components/api-page.css +6 -6
  14. package/runtime/velu-ui/components/api.css +2 -2
  15. package/runtime/velu-ui/components/ask-bar.css +3 -3
  16. package/runtime/velu-ui/components/changelog-filters.css +5 -5
  17. package/runtime/velu-ui/components/chatbot.css +5 -5
  18. package/runtime/velu-ui/components/code-block.css +2 -2
  19. package/runtime/velu-ui/components/context-menu.css +1 -1
  20. package/runtime/velu-ui/components/docs-layout.css +3 -3
  21. package/runtime/velu-ui/components/field.css +1 -1
  22. package/runtime/velu-ui/components/image.css +1 -1
  23. package/runtime/velu-ui/components/not-found.css +1 -1
  24. package/runtime/velu-ui/components/page-feedback.css +5 -5
  25. package/runtime/velu-ui/components/page-footer.css +1 -1
  26. package/runtime/velu-ui/components/page-header.css +11 -3
  27. package/runtime/velu-ui/components/page-nav.css +1 -1
  28. package/runtime/velu-ui/components/powered-by.css +1 -1
  29. package/runtime/velu-ui/components/prompt.css +2 -2
  30. package/runtime/velu-ui/components/search.css +1 -1
  31. package/runtime/velu-ui/components/sidebar.css +2 -2
  32. package/runtime/velu-ui/components/toc-bar.css +2 -2
  33. package/runtime/velu-ui/components/update.css +1 -1
  34. package/runtime/velu-ui/lib/velu-mark.jsx +20 -0
  35. package/runtime/velu-ui/styles.css +13 -1
  36. package/runtime/velu-ui/themes/aalam.css +19 -8
  37. package/runtime/velu-ui/themes/kadhir.css +77 -0
  38. package/runtime/velu-ui/themes/nila.css +6 -1
  39. package/runtime/velu-ui/themes/thulir.css +240 -231
  40. package/runtime/velu-ui/themes/vepa.css +21 -10
  41. package/schema/velu.schema.json +1 -1
  42. package/src/runtime/App.jsx +49 -37
@@ -40,7 +40,7 @@
40
40
  backdrop-filter: none;
41
41
  }
42
42
  [data-site-theme='vepa'] .velu-header__top {
43
- height: 48px;
43
+ height: 56px;
44
44
  padding-inline: 24px;
45
45
  grid-template-columns: repeat(3, minmax(0, 1fr));
46
46
  gap: 0;
@@ -48,7 +48,7 @@
48
48
  [data-site-theme='vepa'] .velu-header__col--center { width: 100%; padding-inline: 8px; }
49
49
  [data-site-theme='vepa'] .velu-header__col--center > * { justify-content: center !important; flex-wrap: nowrap !important; }
50
50
  [data-site-theme='vepa'] .velu-logo { height: 22px; }
51
- [data-site-theme='vepa'] .velu-header__wordmark { font-family: inherit; font-size: 30px; line-height: 35px; font-weight: 700; }
51
+ [data-site-theme='vepa'] .velu-header__wordmark { font-family: var(--font-wordmark); font-size: 30px; line-height: 35px; font-weight: 300; }
52
52
  [data-site-theme='vepa'] .velu-header__mark { display: none; }
53
53
  [data-site-theme='vepa'] .velu-header__action { font-size: 14px; line-height: 20px; border-radius: 8px; padding: 6px 12px; border: 0; }
54
54
  [data-site-theme='vepa'] .velu-header__action--primary { font-weight: 500; }
@@ -57,8 +57,8 @@
57
57
  [data-site-theme='vepa'] .velu-search__trigger { inline-size: 256px !important; height: 32px; padding: 0 8px; gap: 4px; background: var(--surface-color); border-color: var(--vepa-hairline); border-radius: 8px; font-size: 14px; }
58
58
  [data-site-theme='vepa'] .velu-search__trigger-icon svg { width: 16px; height: 16px; }
59
59
  [data-site-theme='vepa'] .velu-search__kbd { background: var(--page-bg); border: 0; padding: 2px 6px; font: 500 12px/16px var(--font-sans); border-radius: 4px; }
60
- [data-site-theme='vepa'] .velu-header__tabs { height: 48px; padding: 0 24px; background: var(--surface-color); }
61
- [data-site-theme='vepa'] .velu-header__tab { height: 48px; padding-block: 0; font-size: 14px; line-height: 20px; }
60
+ [data-site-theme='vepa'] .velu-header__tabs { height: 52px; padding: 0 24px; background: var(--surface-color); }
61
+ [data-site-theme='vepa'] .velu-header__tab { height: 52px; padding-block: 0; font-size: 14px; line-height: 20px; }
62
62
  @container docs (min-width: 1024px) {
63
63
  [data-site-theme='vepa'] .velu-header[data-has-tabs='false'] .velu-header__tabs { display: none !important; }
64
64
  [data-site-theme='vepa'] .velu-header__crumbs,
@@ -71,6 +71,16 @@
71
71
  [data-site-theme='vepa'] .velu-docs-layout__main { padding: 24px; }
72
72
  [data-site-theme='vepa'] .velu-docs-layout__article { max-inline-size: 648px; position: relative; }
73
73
  [data-site-theme='vepa'] .velu-sidebar { margin: 0; width: 100%; }
74
+ /* Disappearing rail scrollbar (Aspen-style): no permanent gutter — thumb
75
+ reveals on hover, like Nila. Overrides the always-on base rail. */
76
+ [data-site-theme='vepa'] .velu-docs-nav-scroll { overflow-y: auto; background-image: none; scrollbar-color: transparent transparent; }
77
+ [data-site-theme='vepa'] .velu-docs-nav-scroll:hover { scrollbar-color: var(--border-color) transparent; }
78
+ [data-site-theme='vepa'] .velu-docs-nav-scroll::-webkit-scrollbar-track { background: transparent; }
79
+ [data-site-theme='vepa'] .velu-docs-nav-scroll::-webkit-scrollbar-thumb { background: transparent; }
80
+ [data-site-theme='vepa'] .velu-docs-nav-scroll:hover::-webkit-scrollbar-thumb { background: var(--border-color); }
81
+ /* Ask AI entry keeps a hairline + surface wash like Mintlify Sequoia's Ask
82
+ button (the base vepa action style strips borders everywhere). */
83
+ [data-site-theme='vepa'] #assistant-entry { border: var(--border-width) solid var(--vepa-hairline); background: var(--surface-color); }
74
84
  [data-site-theme='vepa'] :is(.velu-sidebar__section, .velu-api-sidebar__section) { position: static; font: 400 12px/16px var(--font-sans); text-transform: none; letter-spacing: 0; padding: 0 24px 8px; color: var(--vepa-heading); }
75
85
  [data-site-theme='vepa'] .velu-sidebar__section::after,
76
86
  [data-site-theme='vepa'] .velu-sidebar__indicator { display: none; }
@@ -119,7 +129,7 @@
119
129
  /* Sticky on-page TocBar (used below the right-rail breakpoint). */
120
130
  [data-site-theme='vepa'] .velu-toc-bar {
121
131
  border-block-end-color: var(--vepa-hairline);
122
- background: color-mix(in srgb, var(--page-bg) 88%, transparent);
132
+ background: rgb(from var(--page-bg) r g b / 88%);
123
133
  }
124
134
  [data-site-theme='vepa'] .velu-toc-bar__toggle {
125
135
  padding-block: 10px;
@@ -229,7 +239,7 @@
229
239
  [data-site-theme='vepa'] .velu-docs-layout__drawer-brand .velu-header__wordmark {
230
240
  font-size: 20px;
231
241
  line-height: 28px;
232
- font-weight: 700;
242
+ font-weight: 300;
233
243
  }
234
244
  [data-site-theme='vepa'] .velu-docs-layout__drawer-close {
235
245
  width: 32px;
@@ -341,14 +351,14 @@
341
351
  .vepa-footer__inner { display: flex; flex-direction: column; gap: 48px; max-width: 984px; width: 100%; margin: auto; padding: 112px 32px; }
342
352
  .vepa-footer__top { display: flex; justify-content: space-between; gap: 32px; }
343
353
  .vepa-footer__brand-column { display: flex; flex-direction: column; justify-content: space-between; align-items: flex-start; min-width: 192px; gap: 96px; }
344
- .vepa-footer__brand { color: var(--vepa-heading); text-decoration: none; font-family: inherit; font-size: 30px; line-height: 35px; font-weight: 700; }
354
+ .vepa-footer__brand { display: inline-flex; align-items: center; gap: 8px; color: var(--vepa-heading); text-decoration: none; font-family: var(--font-wordmark); font-size: 30px; line-height: 35px; font-weight: 700; }
345
355
  .vepa-footer__brand .velu-logo { height: 26px; max-width: 192px; }
346
356
  .vepa-footer__columns { display: grid; grid-template-columns: repeat(var(--footer-columns), minmax(0,1fr)); gap: 32px; flex: 1; min-width: 0; }
347
357
  .vepa-footer__column { display: flex; flex-direction: column; align-items: center; }
348
358
  .vepa-footer__links { display: flex; flex-direction: column; gap: 16px; min-width: 0; max-width: 100%; }
349
359
  .vepa-footer__heading { margin: 0 0 4px; color: var(--vepa-gray-950); font: 600 14px/20px var(--font-sans); }
350
- .vepa-footer__link { font: 400 14px/20px var(--font-sans); color: color-mix(in srgb, var(--vepa-gray-950) 50%, transparent); max-width: 144px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-decoration: none; }
351
- .vepa-footer__link:hover { color: color-mix(in srgb, var(--vepa-gray-950) 70%, transparent); }
360
+ .vepa-footer__link { font: 400 14px/20px var(--font-sans); color: rgb(from var(--vepa-gray-950) r g b / 50%); max-width: 144px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-decoration: none; }
361
+ .vepa-footer__link:hover { color: rgb(from var(--vepa-gray-950) r g b / 70%); }
352
362
  .vepa-footer .velu-socials { gap: 16px !important; min-width: 140px; max-width: 492px; height: fit-content; }
353
363
  .vepa-footer .velu-social { width: 20px; height: 20px; color: var(--vepa-gray-500); }
354
364
  .vepa-footer .velu-social svg { width: 20px; height: 20px; }
@@ -359,7 +369,8 @@
359
369
  .vepa-footer__divider { height: 1px; background: var(--vepa-hairline); }
360
370
  .vepa-footer__bottom { display: flex; justify-content: space-between; align-items: center; }
361
371
  .vepa-footer__powered { display: flex; align-items: baseline; gap: 4px; color: var(--vepa-gray-400); font: 400 14px/20px var(--font-sans); text-decoration: none; }
362
- .vepa-footer__powered strong { font-size: 16px; font-weight: 600; }
372
+ .vepa-footer__powered strong { font-family: var(--font-wordmark); font-size: 16px; font-weight: 300; }
373
+ .vepa-footer__powered-mark { flex: none; height: 1.1em; width: auto; }
363
374
  .vepa-footer-theme { display: flex; gap: 8px; }
364
375
  .vepa-footer-theme button { display: grid; place-items: center; padding: 6px; background: transparent; border: 0; border-radius: 8px; color: var(--vepa-gray-400); cursor: pointer; }
365
376
  .vepa-footer-theme button[aria-pressed='true'] { color: var(--vepa-gray-600); background: var(--vepa-gray-200); }
@@ -9,7 +9,7 @@
9
9
  "properties": {
10
10
  "theme": {
11
11
  "type": "string",
12
- "enum": ["velu", "vepa", "thulir", "aalam", "nila"],
12
+ "enum": ["velu", "vepa", "thulir", "aalam", "nila", "kadhir"],
13
13
  "description": "Visual preset. Vepa follows Mintlify Sequoia, Thulir follows Mintlify Mint, and Aalam follows Mintlify Maple; light/dark preference is independent. Defaults to velu."
14
14
  },
15
15
  "$schema": {
@@ -929,7 +929,7 @@ function DocsPage() {
929
929
  // against it like any other heading.
930
930
  const pageId = React.useMemo(() => {
931
931
  if (!frontmatter.title) return null;
932
- if (site.theme === 'vepa' || ['thulir', 'aalam', 'nila'].includes(site.theme)) return 'page-title';
932
+ if (site.theme === 'vepa' || ['thulir', 'aalam', 'nila', 'kadhir'].includes(site.theme)) return 'page-title';
933
933
  return new GithubSlugger().slug(frontmatter.title);
934
934
  }, [frontmatter.title, site.theme]);
935
935
 
@@ -969,7 +969,7 @@ function DocsPage() {
969
969
  const root = drawerRef.current?.parentElement;
970
970
  if (!root) return;
971
971
  const observer = new ResizeObserver(([entry]) => {
972
- const narrow = entry.contentRect.width <= (['thulir', 'aalam', 'nila'].includes(site.theme) ? 1023 : 640);
972
+ const narrow = entry.contentRect.width <= (['thulir', 'aalam', 'nila', 'kadhir'].includes(site.theme) ? 1023 : 640);
973
973
  setDrawerViewport(narrow);
974
974
  if (!narrow) setDrawerOpen(false);
975
975
  });
@@ -1254,34 +1254,39 @@ function DocsPage() {
1254
1254
  };
1255
1255
  }, [footerEl]);
1256
1256
 
1257
- // Sticky AskBar fades out once the user scrolls near the PageFeedback
1258
- // widget — so it doesn't sit on top of the page-foot widgets.
1257
+ // Sticky AskBar fades out once the user scrolls near the page-foot
1258
+ // widgets — so it doesn't sit on top of them. Anchor priority:
1259
+ // PageFeedback (default theme) → pagination → site footer, so pages
1260
+ // without feedback or prev/next links (e.g. changelogs) still fade
1261
+ // the bar out at the bottom.
1259
1262
  const [feedbackEl, setFeedbackEl] = React.useState(null);
1263
+ const [navAnchorEl, setNavAnchorEl] = React.useState(null);
1260
1264
  const [askBarHidden, setAskBarHidden] = React.useState(false);
1261
1265
  React.useEffect(() => {
1262
- if (!feedbackEl) {
1266
+ const anchorEl = feedbackEl ?? navAnchorEl ?? footerEl;
1267
+ if (!anchorEl) {
1263
1268
  setAskBarHidden(false);
1264
1269
  return undefined;
1265
1270
  }
1266
1271
  const FADE_BUFFER = 64; // matches the rootMargin below
1267
1272
  const apply = (rect) => {
1268
- // Hide whenever the feedback's top has reached the (effective)
1269
- // viewport-bottom line — covers both "feedback is in view" AND
1270
- // "feedback is already scrolled past" without flickering back on.
1273
+ // Hide whenever the anchor's top has reached the (effective)
1274
+ // viewport-bottom line — covers both "anchor is in view" AND
1275
+ // "anchor is already scrolled past" without flickering back on.
1271
1276
  // Threshold matches the IO's rootMargin so the show/hide flip is
1272
1277
  // exactly at the same line in both scroll directions.
1273
1278
  setAskBarHidden(rect.top < window.innerHeight - FADE_BUFFER);
1274
1279
  };
1275
- apply(feedbackEl.getBoundingClientRect());
1280
+ apply(anchorEl.getBoundingClientRect());
1276
1281
  const io = new IntersectionObserver(
1277
1282
  ([entry]) => apply(entry.boundingClientRect),
1278
- // Trigger ~64px before the feedback enters the viewport, so the
1283
+ // Trigger ~64px before the anchor enters the viewport, so the
1279
1284
  // AskBar fades just as the widget starts to peek up from below.
1280
1285
  { rootMargin: '0px 0px -64px 0px' },
1281
1286
  );
1282
- io.observe(feedbackEl);
1287
+ io.observe(anchorEl);
1283
1288
  return () => io.disconnect();
1284
- }, [feedbackEl]);
1289
+ }, [feedbackEl, navAnchorEl, footerEl]);
1285
1290
 
1286
1291
  const scrollTo = React.useCallback(
1287
1292
  (id) => {
@@ -1350,8 +1355,8 @@ function DocsPage() {
1350
1355
  logo: site.logo,
1351
1356
  }}
1352
1357
  brandTrailing={
1353
- (versionSwitcher || (site.theme === 'nila' && productSwitcher)) && (
1354
- <span className="velu-hide-on-mobile">{versionSwitcher}{site.theme === 'nila' && productSwitcher}</span>
1358
+ (versionSwitcher || (['nila', 'kadhir'].includes(site.theme) && productSwitcher)) && (
1359
+ <span className="velu-hide-on-mobile">{versionSwitcher}{['nila', 'kadhir'].includes(site.theme) && productSwitcher}</span>
1355
1360
  )
1356
1361
  }
1357
1362
  center={
@@ -1382,7 +1387,7 @@ function DocsPage() {
1382
1387
  </Cluster>
1383
1388
  }
1384
1389
  actions={navActions}
1385
- trailing={<ThemeToggle variant={site.theme === 'aalam' ? 'inline' : site.theme === 'vepa' || ['thulir', 'nila'].includes(site.theme) ? 'menu' : undefined} />}
1390
+ trailing={<ThemeToggle variant={site.theme === 'aalam' ? 'inline' : site.theme === 'vepa' || ['thulir', 'nila', 'kadhir'].includes(site.theme) ? 'menu' : undefined} />}
1386
1391
  tabsTrailing={
1387
1392
  chrome.mode === 'custom' || chrome.mode === 'assistant'
1388
1393
  ? undefined
@@ -1398,7 +1403,7 @@ function DocsPage() {
1398
1403
  breadcrumb={
1399
1404
  chrome.mode === 'custom' || chrome.mode === 'assistant'
1400
1405
  ? []
1401
- : ['thulir', 'aalam', 'nila'].includes(site.theme) ? (nav?.breadcrumb ?? []).slice(-2) : (nav?.breadcrumb ?? [])
1406
+ : ['thulir', 'aalam', 'nila', 'kadhir'].includes(site.theme) ? (nav?.breadcrumb ?? []).slice(-2) : (nav?.breadcrumb ?? [])
1402
1407
  }
1403
1408
  activeTab={nav?.activeTab}
1404
1409
  tabs={
@@ -1444,7 +1449,10 @@ function DocsPage() {
1444
1449
  className="velu-docs-layout__drawer-brand"
1445
1450
  >
1446
1451
  {site.logo ? (
1447
- <Logo logo={site.logo} alt={site.name} />
1452
+ <>
1453
+ <Logo logo={site.logo} alt="" />
1454
+ <span className="velu-header__wordmark" title={site.name}>{site.name}</span>
1455
+ </>
1448
1456
  ) : (
1449
1457
  <>
1450
1458
  <VeluMark />
@@ -1452,7 +1460,7 @@ function DocsPage() {
1452
1460
  </>
1453
1461
  )}
1454
1462
  </RouterLink>
1455
- <ThemeToggle variant={site.theme === 'vepa' || ['thulir', 'nila'].includes(site.theme) ? 'menu' : undefined} />
1463
+ <ThemeToggle variant={site.theme === 'vepa' || ['thulir', 'nila', 'kadhir'].includes(site.theme) ? 'menu' : undefined} />
1456
1464
  <button
1457
1465
  type="button"
1458
1466
  className="velu-docs-layout__drawer-close"
@@ -1596,7 +1604,7 @@ function DocsPage() {
1596
1604
  left column, including anchors, in one overflow. */}
1597
1605
  <div className="velu-docs-nav-region">
1598
1606
  <div
1599
- id={site.theme === 'vepa' || ['thulir', 'aalam', 'nila'].includes(site.theme) ? 'navigation-items' : 'sidebar-content'}
1607
+ id={site.theme === 'vepa' || ['thulir', 'aalam', 'nila', 'kadhir'].includes(site.theme) ? 'navigation-items' : 'sidebar-content'}
1600
1608
  ref={leftAsideRef}
1601
1609
  className={`velu-docs-nav-scroll${site.theme === 'aalam' ? '' : ' velu-hide-scrollbar'}`}
1602
1610
  style={{
@@ -1694,12 +1702,12 @@ function DocsPage() {
1694
1702
  />
1695
1703
  ) : isChangelog && changelogTags.length && site.theme !== 'vepa' ? (
1696
1704
  <ChangelogFilters tags={changelogTags} />
1697
- ) : site.theme === 'vepa' || ['thulir', 'aalam', 'nila'].includes(site.theme) ? (
1705
+ ) : site.theme === 'vepa' || ['thulir', 'aalam', 'nila', 'kadhir'].includes(site.theme) ? (
1698
1706
  <>
1699
1707
  {isChangelog && changelogTags.length > 0 ? (
1700
1708
  <ChangelogFilters tags={changelogTags} />
1701
1709
  ) : null}
1702
- <VepaToc items={pageToc} activeId={['thulir', 'aalam', 'nila'].includes(site.theme) && activeId === pageId ? pageToc[0]?.id : activeId} onSelect={scrollTo} />
1710
+ <VepaToc items={pageToc} activeId={['thulir', 'aalam', 'nila', 'kadhir'].includes(site.theme) && activeId === pageId ? pageToc[0]?.id : activeId} onSelect={scrollTo} />
1703
1711
  </>
1704
1712
  ) : (
1705
1713
  <Toc id="table-of-contents-content" items={toc} activeId={activeId} onSelect={scrollTo} />
@@ -1744,7 +1752,7 @@ function DocsPage() {
1744
1752
  on tab/mobile we keep the normal TOC bar (no filters). Hidden
1745
1753
  entirely when the page mode has no table of contents. */}
1746
1754
  {chrome.toc && (
1747
- <TocBar items={toc} activeId={activeId} onSelect={scrollTo} label={['thulir', 'aalam', 'nila'].includes(site.theme) ? 'On this page' : undefined} />
1755
+ <TocBar items={toc} activeId={activeId} onSelect={scrollTo} label={['thulir', 'aalam', 'nila', 'kadhir'].includes(site.theme) ? 'On this page' : undefined} />
1748
1756
  )}
1749
1757
  <main
1750
1758
  id="content-area"
@@ -1784,7 +1792,7 @@ function DocsPage() {
1784
1792
  </span>
1785
1793
  </button>
1786
1794
  )}
1787
- <div id={site.theme === 'vepa' || ['thulir', 'aalam', 'nila'].includes(site.theme) ? undefined : 'content'} data-contextual-actions={site.contextual?.options?.length ? 'true' : 'false'} className="velu-docs-layout__article" data-pagefind-body={chrome.assistant ? undefined : ""}>
1795
+ <div id={site.theme === 'vepa' || ['thulir', 'aalam', 'nila', 'kadhir'].includes(site.theme) ? undefined : 'content'} data-contextual-actions={site.contextual?.options?.length ? 'true' : 'false'} className="velu-docs-layout__article" data-pagefind-body={chrome.assistant ? undefined : ""}>
1788
1796
  {/* Per-page agent/IDE action bar: the section eyebrow + a
1789
1797
  "Copy Page" split-button whose dropdown is driven by the
1790
1798
  Mintlify-compatible `contextual` config. Renders nothing
@@ -1814,7 +1822,7 @@ function DocsPage() {
1814
1822
  Custom / frame / assistant are a blank canvas — no auto hero. */}
1815
1823
  {chrome.hero && (frontmatter.title || frontmatter.description) && (
1816
1824
  <div className="velu-hero">
1817
- {frontmatter.title && <h1 id={site.theme === 'vepa' || ['thulir', 'aalam', 'nila'].includes(site.theme) ? 'page-title' : pageId}>{frontmatter.title}</h1>}
1825
+ {frontmatter.title && <h1 id={site.theme === 'vepa' || ['thulir', 'aalam', 'nila', 'kadhir'].includes(site.theme) ? 'page-title' : pageId}>{frontmatter.title}</h1>}
1818
1826
  {frontmatter.description && (
1819
1827
  <p
1820
1828
  style={{
@@ -1835,7 +1843,7 @@ function DocsPage() {
1835
1843
  level. Falls back to a not-found / missing-file notice
1836
1844
  when the route has no page (or its file is absent). */}
1837
1845
  <MDXProvider components={defaultMdxComponents}>
1838
- <mdx-content key={site.theme === 'vepa' ? pathname : undefined} id={(site.theme === 'vepa' || ['thulir', 'aalam', 'nila'].includes(site.theme)) && !entry?.api ? 'content' : undefined} class="velu-prose">
1846
+ <mdx-content key={site.theme === 'vepa' ? pathname : undefined} id={(site.theme === 'vepa' || ['thulir', 'aalam', 'nila', 'kadhir'].includes(site.theme)) && !entry?.api ? 'content' : undefined} class="velu-prose">
1839
1847
  {PageComponent ? (
1840
1848
  <ErrorBoundary key={pathname} file={entry?.relPath}>
1841
1849
  {entry?.mdxApi ? <ApiReferencePage {...entry.mdxApi} preset={site.theme}><PageComponent /></ApiReferencePage> : <PageComponent />}
@@ -1851,7 +1859,7 @@ function DocsPage() {
1851
1859
  </MDXProvider>
1852
1860
  {/* Page-foot feedback widget — ref'd so the sticky AskBar
1853
1861
  above can hide as the user scrolls near it. */}
1854
- {chrome.articleChrome && !['thulir', 'aalam', 'nila'].includes(site.theme) && (
1862
+ {chrome.articleChrome && !['thulir', 'aalam', 'nila', 'kadhir'].includes(site.theme) && (
1855
1863
  <div ref={setFeedbackEl} style={{ marginTop: 'var(--s3)' }}>
1856
1864
  {/* key resets the widget's vote state on page change. "Yes"
1857
1865
  submits immediately; "No" submits once its form is sent.
@@ -1868,16 +1876,20 @@ function DocsPage() {
1868
1876
  </div>
1869
1877
  )}
1870
1878
  {/* Previous / next page navigation — derived from the
1871
- sidebar reading order of the active section. */}
1879
+ sidebar reading order of the active section. The wrapper
1880
+ doubles as the AskBar fade anchor on themes without a
1881
+ PageFeedback widget (see the observer above). */}
1872
1882
  {chrome.articleChrome && !frontmatter.hidePagination && (nav?.prev || nav?.next) && (
1873
- <PageNav
1874
- id="pagination"
1875
- style={['thulir', 'aalam', 'nila'].includes(site.theme) ? undefined : { marginTop: 'var(--s2)' }}
1876
- variant={site.theme === 'aalam' ? 'aalam' : 'default'}
1877
- prev={nav?.prev}
1878
- next={nav?.next}
1879
- linkComponent={RouterLink}
1880
- />
1883
+ <div ref={setNavAnchorEl}>
1884
+ <PageNav
1885
+ id="pagination"
1886
+ style={['thulir', 'aalam', 'nila', 'kadhir'].includes(site.theme) ? undefined : { marginTop: 'var(--s2)' }}
1887
+ variant={site.theme === 'aalam' ? 'aalam' : 'default'}
1888
+ prev={nav?.prev}
1889
+ next={nav?.next}
1890
+ linkComponent={RouterLink}
1891
+ />
1892
+ </div>
1881
1893
  )}
1882
1894
  {/* "Ask a question" bar — sticky to viewport-bottom while the
1883
1895
  article column is in view; lives inside the prose-column
@@ -1913,7 +1925,7 @@ function DocsPage() {
1913
1925
  full footer section); with link columns they live in the full
1914
1926
  footer below instead. */}
1915
1927
  {chrome.articleChrome && (footerHasLinks ? (
1916
- site.theme === 'vepa' || ['thulir', 'aalam', 'nila'].includes(site.theme) ? null : <PoweredBy />
1928
+ site.theme === 'vepa' || ['thulir', 'aalam', 'nila', 'kadhir'].includes(site.theme) ? null : <PoweredBy />
1917
1929
  ) : (
1918
1930
  <div className="velu-content-foot">
1919
1931
  <SocialLinks socials={footerSocials} />
@@ -1932,7 +1944,7 @@ function DocsPage() {
1932
1944
  overlap via footerOverlap below. */}
1933
1945
  {footerHasLinks && chrome.footer && (
1934
1946
  <advanced-footer
1935
- id={site.theme === 'vepa' || ['thulir', 'aalam', 'nila'].includes(site.theme) ? undefined : 'footer'}
1947
+ id={site.theme === 'vepa' || ['thulir', 'aalam', 'nila', 'kadhir'].includes(site.theme) ? undefined : 'footer'}
1936
1948
  ref={setFooterEl}
1937
1949
  data-velu-footer
1938
1950
  style={{ position: 'relative', zIndex: 20 }}