@axle-lang/ui 0.1.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.
- package/LICENSE +21 -0
- package/README.md +70 -0
- package/dist/app.css +337 -0
- package/dist/components/Seo.svelte +38 -0
- package/dist/components/Seo.svelte.d.ts +8 -0
- package/dist/components/atoms/Badge.svelte +11 -0
- package/dist/components/atoms/Badge.svelte.d.ts +8 -0
- package/dist/components/atoms/Button.svelte +32 -0
- package/dist/components/atoms/Button.svelte.d.ts +12 -0
- package/dist/components/atoms/Callout.svelte +11 -0
- package/dist/components/atoms/Callout.svelte.d.ts +8 -0
- package/dist/components/atoms/CodeChip.svelte +11 -0
- package/dist/components/atoms/CodeChip.svelte.d.ts +8 -0
- package/dist/components/atoms/Eyebrow.svelte +9 -0
- package/dist/components/atoms/Eyebrow.svelte.d.ts +8 -0
- package/dist/components/atoms/HandNote.svelte +15 -0
- package/dist/components/atoms/HandNote.svelte.d.ts +9 -0
- package/dist/components/atoms/Icon.svelte +40 -0
- package/dist/components/atoms/Icon.svelte.d.ts +11 -0
- package/dist/components/atoms/Kbd.svelte +11 -0
- package/dist/components/atoms/Kbd.svelte.d.ts +8 -0
- package/dist/components/atoms/Logo.svelte +18 -0
- package/dist/components/atoms/Logo.svelte.d.ts +6 -0
- package/dist/components/atoms/SearchButton.svelte +23 -0
- package/dist/components/atoms/SearchButton.svelte.d.ts +8 -0
- package/dist/components/atoms/Tag.svelte +21 -0
- package/dist/components/atoms/Tag.svelte.d.ts +10 -0
- package/dist/components/atoms/ThemeToggle.svelte +30 -0
- package/dist/components/atoms/ThemeToggle.svelte.d.ts +6 -0
- package/dist/components/code/Code.svelte +22 -0
- package/dist/components/code/Code.svelte.d.ts +9 -0
- package/dist/components/code/CodeWindow.svelte +42 -0
- package/dist/components/code/CodeWindow.svelte.d.ts +13 -0
- package/dist/components/code/CopyCommand.svelte +28 -0
- package/dist/components/code/CopyCommand.svelte.d.ts +7 -0
- package/dist/components/landing/BenchExplorer.svelte +157 -0
- package/dist/components/landing/BenchExplorer.svelte.d.ts +7 -0
- package/dist/components/landing/CTASection.svelte +12 -0
- package/dist/components/landing/CTASection.svelte.d.ts +11 -0
- package/dist/components/landing/ComparisonPanel.svelte +75 -0
- package/dist/components/landing/ComparisonPanel.svelte.d.ts +19 -0
- package/dist/components/landing/FeatureCard.svelte +19 -0
- package/dist/components/landing/FeatureCard.svelte.d.ts +10 -0
- package/dist/components/landing/FeatureGrid.svelte +26 -0
- package/dist/components/landing/FeatureGrid.svelte.d.ts +13 -0
- package/dist/components/landing/Hero.svelte +23 -0
- package/dist/components/landing/Hero.svelte.d.ts +14 -0
- package/dist/components/landing/RecipeDeck.svelte +137 -0
- package/dist/components/landing/RecipeDeck.svelte.d.ts +19 -0
- package/dist/components/layout/DocLayout.svelte +36 -0
- package/dist/components/layout/DocLayout.svelte.d.ts +21 -0
- package/dist/components/layout/PageShell.svelte +15 -0
- package/dist/components/layout/PageShell.svelte.d.ts +7 -0
- package/dist/components/molecules/Card.svelte +18 -0
- package/dist/components/molecules/Card.svelte.d.ts +9 -0
- package/dist/components/molecules/DataTable.svelte +43 -0
- package/dist/components/molecules/DataTable.svelte.d.ts +12 -0
- package/dist/components/molecules/PageHeading.svelte +23 -0
- package/dist/components/molecules/PageHeading.svelte.d.ts +10 -0
- package/dist/components/molecules/Section.svelte +20 -0
- package/dist/components/molecules/Section.svelte.d.ts +10 -0
- package/dist/components/molecules/SectionHeading.svelte +27 -0
- package/dist/components/molecules/SectionHeading.svelte.d.ts +10 -0
- package/dist/components/nav/DocHeader.svelte +44 -0
- package/dist/components/nav/DocHeader.svelte.d.ts +7 -0
- package/dist/components/nav/Footer.svelte +67 -0
- package/dist/components/nav/Footer.svelte.d.ts +3 -0
- package/dist/components/nav/Header.svelte +55 -0
- package/dist/components/nav/Header.svelte.d.ts +6 -0
- package/dist/components/nav/PrevNext.svelte +27 -0
- package/dist/components/nav/PrevNext.svelte.d.ts +13 -0
- package/dist/components/nav/RightRail.svelte +30 -0
- package/dist/components/nav/RightRail.svelte.d.ts +11 -0
- package/dist/components/nav/Sidebar.svelte +33 -0
- package/dist/components/nav/Sidebar.svelte.d.ts +18 -0
- package/dist/components/reference/MethodDetail.svelte +72 -0
- package/dist/components/reference/MethodDetail.svelte.d.ts +7 -0
- package/dist/components/reference/MethodSummary.svelte +41 -0
- package/dist/components/reference/MethodSummary.svelte.d.ts +8 -0
- package/dist/i18n/index.d.ts +47 -0
- package/dist/i18n/index.js +23 -0
- package/dist/i18n/messages/en.d.ts +43 -0
- package/dist/i18n/messages/en.js +50 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.js +54 -0
- package/dist/site/site.d.ts +45 -0
- package/dist/site/site.js +66 -0
- package/dist/utils/cn.d.ts +6 -0
- package/dist/utils/cn.js +9 -0
- package/dist/utils/icons.d.ts +26 -0
- package/dist/utils/icons.js +55 -0
- package/dist/utils/tokenizer.d.ts +12 -0
- package/dist/utils/tokenizer.js +181 -0
- package/dist/utils/types.d.ts +50 -0
- package/dist/utils/types.js +4 -0
- package/dist/utils/variants.d.ts +20 -0
- package/dist/utils/variants.js +50 -0
- package/package.json +77 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Hero shell. Left column = `children` (kicker, headline, lead, actions).
|
|
4
|
+
* Right column = the `media` snippet (e.g. <RecipeDeck />). The route owns
|
|
5
|
+
* all the actual content.
|
|
6
|
+
*/
|
|
7
|
+
import type { Snippet } from 'svelte';
|
|
8
|
+
|
|
9
|
+
let {
|
|
10
|
+
media,
|
|
11
|
+
class: klass = '',
|
|
12
|
+
children
|
|
13
|
+
}: { media?: Snippet; class?: string; children?: Snippet } = $props();
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<section
|
|
17
|
+
class="max-w-[1180px] mx-auto px-6 pt-16 pb-12 grid lg:grid-cols-[1fr_minmax(0,560px)] gap-12 lg:gap-16 items-center {klass}"
|
|
18
|
+
>
|
|
19
|
+
<div>{@render children?.()}</div>
|
|
20
|
+
{#if media}
|
|
21
|
+
<div class="lg:pl-4">{@render media()}</div>
|
|
22
|
+
{/if}
|
|
23
|
+
</section>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hero shell. Left column = `children` (kicker, headline, lead, actions).
|
|
3
|
+
* Right column = the `media` snippet (e.g. <RecipeDeck />). The route owns
|
|
4
|
+
* all the actual content.
|
|
5
|
+
*/
|
|
6
|
+
import type { Snippet } from 'svelte';
|
|
7
|
+
type $$ComponentProps = {
|
|
8
|
+
media?: Snippet;
|
|
9
|
+
class?: string;
|
|
10
|
+
children?: Snippet;
|
|
11
|
+
};
|
|
12
|
+
declare const Hero: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
13
|
+
type Hero = ReturnType<typeof Hero>;
|
|
14
|
+
export default Hero;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import Code from '../code/Code.svelte';
|
|
3
|
+
import Icon from '../atoms/Icon.svelte';
|
|
4
|
+
import { cn } from '../../utils/cn.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The scattered Console-card stack. Auto-advances; pauses on hover.
|
|
8
|
+
* Click a card / dot / arrow to bring a recipe to the front.
|
|
9
|
+
* Data comes from the route (parsed from content/recipes/*.md).
|
|
10
|
+
*/
|
|
11
|
+
interface Recipe {
|
|
12
|
+
file: string;
|
|
13
|
+
title: string;
|
|
14
|
+
note: string;
|
|
15
|
+
src: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let {
|
|
19
|
+
recipes = [],
|
|
20
|
+
interval = 5000,
|
|
21
|
+
class: klass = ''
|
|
22
|
+
}: { recipes?: Recipe[]; interval?: number; class?: string } = $props();
|
|
23
|
+
|
|
24
|
+
let index = $state(0);
|
|
25
|
+
let paused = $state(false);
|
|
26
|
+
let timer: ReturnType<typeof setTimeout>;
|
|
27
|
+
|
|
28
|
+
const scatter = [
|
|
29
|
+
'translate(-26px,10px) rotate(-6deg) scale(.94)',
|
|
30
|
+
'translate(22px,15px) rotate(5deg) scale(.95)',
|
|
31
|
+
'translate(-12px,30px) rotate(-3deg) scale(.93)',
|
|
32
|
+
'translate(28px,4px) rotate(7deg) scale(.94)',
|
|
33
|
+
'translate(6px,36px) rotate(-8deg) scale(.92)',
|
|
34
|
+
'translate(-20px,24px) rotate(3deg) scale(.95)'
|
|
35
|
+
];
|
|
36
|
+
const scatterZ = [22, 18, 26, 14, 20, 16];
|
|
37
|
+
|
|
38
|
+
const active = $derived(recipes[index]);
|
|
39
|
+
|
|
40
|
+
function schedule() {
|
|
41
|
+
clearTimeout(timer);
|
|
42
|
+
if (paused) return;
|
|
43
|
+
timer = setTimeout(() => go(index + 1), interval);
|
|
44
|
+
}
|
|
45
|
+
function go(n: number) {
|
|
46
|
+
const len = recipes.length;
|
|
47
|
+
if (len === 0) return;
|
|
48
|
+
index = ((n % len) + len) % len;
|
|
49
|
+
schedule();
|
|
50
|
+
}
|
|
51
|
+
$effect(() => {
|
|
52
|
+
// Read both synchronously so the effect re-arms when either changes.
|
|
53
|
+
const _deps = [index, paused];
|
|
54
|
+
schedule();
|
|
55
|
+
return () => clearTimeout(timer);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
function transformFor(i: number) {
|
|
59
|
+
return i === index
|
|
60
|
+
? 'translate(0px,-10px) rotate(-0.5deg) scale(1.03)'
|
|
61
|
+
: scatter[i % scatter.length];
|
|
62
|
+
}
|
|
63
|
+
function zFor(i: number) {
|
|
64
|
+
return i === index ? 60 : scatterZ[i % scatterZ.length];
|
|
65
|
+
}
|
|
66
|
+
</script>
|
|
67
|
+
|
|
68
|
+
<div
|
|
69
|
+
class={klass}
|
|
70
|
+
onmouseenter={() => (paused = true)}
|
|
71
|
+
onmouseleave={() => (paused = false)}
|
|
72
|
+
role="group"
|
|
73
|
+
>
|
|
74
|
+
<div class="relative h-[372px]">
|
|
75
|
+
{#each recipes as r, i}
|
|
76
|
+
<button
|
|
77
|
+
type="button"
|
|
78
|
+
onclick={() => go(i)}
|
|
79
|
+
class="absolute inset-x-0 top-1 text-left rounded-xl border border-white/10 bg-codebg dark-code overflow-hidden shadow-2xl shadow-black/40 cursor-pointer transition-all duration-500"
|
|
80
|
+
style="transform:{transformFor(i)};z-index:{zFor(i)};opacity:{i === index
|
|
81
|
+
? 1
|
|
82
|
+
: 0.84};transition-timing-function:cubic-bezier(.2,.7,.2,1)"
|
|
83
|
+
>
|
|
84
|
+
<div class="flex items-center gap-2 px-4 h-10 border-b border-white/[0.08]">
|
|
85
|
+
<span class="h-2.5 w-2.5 rounded-full bg-[#ff5f57]"></span>
|
|
86
|
+
<span class="h-2.5 w-2.5 rounded-full bg-[#febc2e]"></span>
|
|
87
|
+
<span class="h-2.5 w-2.5 rounded-full bg-[#28c840]"></span>
|
|
88
|
+
<span class="ml-2 text-[12px] text-white/45 font-mono">{r.file}</span>
|
|
89
|
+
</div>
|
|
90
|
+
<div class="px-5 py-4 h-[268px] overflow-hidden">
|
|
91
|
+
<Code code={r.src} fontSize={12.5} lineHeight={19} />
|
|
92
|
+
</div>
|
|
93
|
+
</button>
|
|
94
|
+
{/each}
|
|
95
|
+
</div>
|
|
96
|
+
|
|
97
|
+
<!-- Fixed height so a 1- vs 2-line note never reflows the sections below. -->
|
|
98
|
+
<div class="mt-6 h-[76px] overflow-hidden">
|
|
99
|
+
{#if active}
|
|
100
|
+
<div class="text-[15px] font-semibold tracking-tight truncate">{active.title}</div>
|
|
101
|
+
<div class="mt-1.5 flex items-start gap-2 text-[13px] text-muted">
|
|
102
|
+
<span class="mt-[7px] h-1.5 w-1.5 shrink-0 rounded-full bg-accent"></span>
|
|
103
|
+
<span class="leading-relaxed line-clamp-2">{active.note}</span>
|
|
104
|
+
</div>
|
|
105
|
+
{/if}
|
|
106
|
+
</div>
|
|
107
|
+
|
|
108
|
+
<div class="mt-4 flex items-center gap-3">
|
|
109
|
+
<button
|
|
110
|
+
type="button"
|
|
111
|
+
aria-label="Previous recipe"
|
|
112
|
+
onclick={() => go(index - 1)}
|
|
113
|
+
class="h-9 w-9 grid place-items-center rounded-lg border border-line text-muted hover:text-fg hover:bg-surface transition-colors shrink-0"
|
|
114
|
+
><Icon name="prev" /></button
|
|
115
|
+
>
|
|
116
|
+
<div class="flex-1 flex justify-center items-center gap-2">
|
|
117
|
+
{#each recipes as _, i}
|
|
118
|
+
<button
|
|
119
|
+
type="button"
|
|
120
|
+
aria-label="Go to recipe {i + 1}"
|
|
121
|
+
onclick={() => go(i)}
|
|
122
|
+
class={cn(
|
|
123
|
+
'h-1.5 rounded-full transition-all',
|
|
124
|
+
i === index ? 'w-5 bg-accent' : 'w-1.5 bg-fg/20 hover:bg-fg/40'
|
|
125
|
+
)}
|
|
126
|
+
></button>
|
|
127
|
+
{/each}
|
|
128
|
+
</div>
|
|
129
|
+
<button
|
|
130
|
+
type="button"
|
|
131
|
+
aria-label="Next recipe"
|
|
132
|
+
onclick={() => go(index + 1)}
|
|
133
|
+
class="h-9 w-9 grid place-items-center rounded-lg border border-line text-muted hover:text-fg hover:bg-surface transition-colors shrink-0"
|
|
134
|
+
><Icon name="next" /></button
|
|
135
|
+
>
|
|
136
|
+
</div>
|
|
137
|
+
</div>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The scattered Console-card stack. Auto-advances; pauses on hover.
|
|
3
|
+
* Click a card / dot / arrow to bring a recipe to the front.
|
|
4
|
+
* Data comes from the route (parsed from content/recipes/*.md).
|
|
5
|
+
*/
|
|
6
|
+
interface Recipe {
|
|
7
|
+
file: string;
|
|
8
|
+
title: string;
|
|
9
|
+
note: string;
|
|
10
|
+
src: string;
|
|
11
|
+
}
|
|
12
|
+
type $$ComponentProps = {
|
|
13
|
+
recipes?: Recipe[];
|
|
14
|
+
interval?: number;
|
|
15
|
+
class?: string;
|
|
16
|
+
};
|
|
17
|
+
declare const RecipeDeck: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
18
|
+
type RecipeDeck = ReturnType<typeof RecipeDeck>;
|
|
19
|
+
export default RecipeDeck;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import DocHeader from '../nav/DocHeader.svelte';
|
|
4
|
+
import Sidebar from '../nav/Sidebar.svelte';
|
|
5
|
+
import RightRail from '../nav/RightRail.svelte';
|
|
6
|
+
import PrevNext from '../nav/PrevNext.svelte';
|
|
7
|
+
|
|
8
|
+
// Full docs shell: header + sidebar + main content + right TOC + prev/next.
|
|
9
|
+
let {
|
|
10
|
+
crumb = '',
|
|
11
|
+
toc = [],
|
|
12
|
+
prev,
|
|
13
|
+
next,
|
|
14
|
+
children
|
|
15
|
+
}: {
|
|
16
|
+
crumb?: string;
|
|
17
|
+
toc?: { id: string; label: string; sub?: boolean }[];
|
|
18
|
+
prev?: { label: string; href: string };
|
|
19
|
+
next?: { label: string; href: string };
|
|
20
|
+
children?: Snippet;
|
|
21
|
+
} = $props();
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<div class="min-h-screen flex flex-col">
|
|
25
|
+
<DocHeader {crumb} />
|
|
26
|
+
<div class="flex-1 w-full max-w-[1400px] mx-auto flex items-start">
|
|
27
|
+
<Sidebar />
|
|
28
|
+
<main class="flex-1 min-w-0 px-6 md:px-12 py-10 max-w-[860px]">
|
|
29
|
+
<article>
|
|
30
|
+
{@render children?.()}
|
|
31
|
+
<PrevNext {prev} {next} />
|
|
32
|
+
</article>
|
|
33
|
+
</main>
|
|
34
|
+
<RightRail items={toc} />
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
crumb?: string;
|
|
4
|
+
toc?: {
|
|
5
|
+
id: string;
|
|
6
|
+
label: string;
|
|
7
|
+
sub?: boolean;
|
|
8
|
+
}[];
|
|
9
|
+
prev?: {
|
|
10
|
+
label: string;
|
|
11
|
+
href: string;
|
|
12
|
+
};
|
|
13
|
+
next?: {
|
|
14
|
+
label: string;
|
|
15
|
+
href: string;
|
|
16
|
+
};
|
|
17
|
+
children?: Snippet;
|
|
18
|
+
};
|
|
19
|
+
declare const DocLayout: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
20
|
+
type DocLayout = ReturnType<typeof DocLayout>;
|
|
21
|
+
export default DocLayout;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
// Marketing page chrome: header + content + footer on the base canvas.
|
|
4
|
+
// Used by every landing-side page so the wrapper lives in one place.
|
|
5
|
+
import Header from '../nav/Header.svelte';
|
|
6
|
+
import Footer from '../nav/Footer.svelte';
|
|
7
|
+
|
|
8
|
+
let { children }: { children?: Snippet } = $props();
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<div class="font-sans antialiased text-fg bg-canvas min-h-screen">
|
|
12
|
+
<Header />
|
|
13
|
+
{@render children?.()}
|
|
14
|
+
<Footer />
|
|
15
|
+
</div>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import { cn } from '../../utils/cn.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Bordered, rounded container. `tone` picks the surface (the design
|
|
7
|
+
* `.card` / `.card-muted` primitives); pass extra layout via `class`.
|
|
8
|
+
*/
|
|
9
|
+
let {
|
|
10
|
+
tone = 'canvas',
|
|
11
|
+
class: klass = '',
|
|
12
|
+
children
|
|
13
|
+
}: { tone?: 'canvas' | 'surface'; class?: string; children?: Snippet } = $props();
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<div class={cn(tone === 'surface' ? 'card-muted' : 'card', klass)}>
|
|
17
|
+
{@render children?.()}
|
|
18
|
+
</div>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
tone?: 'canvas' | 'surface';
|
|
4
|
+
class?: string;
|
|
5
|
+
children?: Snippet;
|
|
6
|
+
};
|
|
7
|
+
declare const Card: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
8
|
+
type Card = ReturnType<typeof Card>;
|
|
9
|
+
export default Card;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
interface CodeCell {
|
|
3
|
+
code?: boolean;
|
|
4
|
+
text: string;
|
|
5
|
+
}
|
|
6
|
+
type Cell = string | CodeCell;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Generic doc table. Pass `head` (column labels) and `rows` (array of cell arrays).
|
|
10
|
+
* A cell can be a string, or { code:true, text } to render monospace/accent.
|
|
11
|
+
*/
|
|
12
|
+
let { head = [], rows = [] }: { head?: string[]; rows?: Cell[][] } = $props();
|
|
13
|
+
|
|
14
|
+
const isCode = (c: Cell): boolean => typeof c === 'object' && !!c?.code;
|
|
15
|
+
const text = (c: Cell): string => (typeof c === 'object' ? c.text : c);
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<div class="overflow-x-auto axle-scroll rounded-xl border border-line">
|
|
19
|
+
<table class="w-full text-[13.5px] border-separate border-spacing-0">
|
|
20
|
+
{#if head.length}
|
|
21
|
+
<thead>
|
|
22
|
+
<tr class="bg-surface text-left">
|
|
23
|
+
{#each head as h}
|
|
24
|
+
<th class="font-semibold py-2.5 px-4 text-fg whitespace-nowrap">{h}</th>
|
|
25
|
+
{/each}
|
|
26
|
+
</tr>
|
|
27
|
+
</thead>
|
|
28
|
+
{/if}
|
|
29
|
+
<tbody>
|
|
30
|
+
{#each rows as row}
|
|
31
|
+
<tr>
|
|
32
|
+
{#each row as cell}
|
|
33
|
+
<td
|
|
34
|
+
class="py-2.5 px-4 border-t border-line {isCode(cell)
|
|
35
|
+
? 'font-mono text-accent text-[12.5px] whitespace-nowrap'
|
|
36
|
+
: 'text-muted'}">{text(cell)}</td
|
|
37
|
+
>
|
|
38
|
+
{/each}
|
|
39
|
+
</tr>
|
|
40
|
+
{/each}
|
|
41
|
+
</tbody>
|
|
42
|
+
</table>
|
|
43
|
+
</div>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface CodeCell {
|
|
2
|
+
code?: boolean;
|
|
3
|
+
text: string;
|
|
4
|
+
}
|
|
5
|
+
type Cell = string | CodeCell;
|
|
6
|
+
type $$ComponentProps = {
|
|
7
|
+
head?: string[];
|
|
8
|
+
rows?: Cell[][];
|
|
9
|
+
};
|
|
10
|
+
declare const DataTable: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
11
|
+
type DataTable = ReturnType<typeof DataTable>;
|
|
12
|
+
export default DataTable;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Doc page title block: optional breadcrumb + h1 + lead paragraph.
|
|
6
|
+
*/
|
|
7
|
+
let {
|
|
8
|
+
crumb = '',
|
|
9
|
+
leaf = '',
|
|
10
|
+
title,
|
|
11
|
+
children
|
|
12
|
+
}: { crumb?: string; leaf?: string; title: string; children?: Snippet } = $props();
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
{#if crumb}
|
|
16
|
+
<div class="text-[13px] text-muted flex items-center gap-2">
|
|
17
|
+
{crumb} <span class="text-line">/</span> <span class="text-fg">{leaf}</span>
|
|
18
|
+
</div>
|
|
19
|
+
{/if}
|
|
20
|
+
<h1 class="mt-3 text-[34px] font-semibold tracking-[-0.02em] leading-tight">{title}</h1>
|
|
21
|
+
{#if children}
|
|
22
|
+
<p class="mt-4 text-[17px] leading-[1.65] text-muted">{@render children()}</p>
|
|
23
|
+
{/if}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
crumb?: string;
|
|
4
|
+
leaf?: string;
|
|
5
|
+
title: string;
|
|
6
|
+
children?: Snippet;
|
|
7
|
+
};
|
|
8
|
+
declare const PageHeading: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
9
|
+
type PageHeading = ReturnType<typeof PageHeading>;
|
|
10
|
+
export default PageHeading;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Generic section shell — max-width container with consistent padding.
|
|
6
|
+
* Put all content (eyebrow, heading, body) inside as children.
|
|
7
|
+
*/
|
|
8
|
+
let {
|
|
9
|
+
muted = false,
|
|
10
|
+
bordered = false,
|
|
11
|
+
class: klass = '',
|
|
12
|
+
children
|
|
13
|
+
}: { muted?: boolean; bordered?: boolean; class?: string; children?: Snippet } = $props();
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<section class="{bordered ? 'border-t border-line ' : ''}{muted ? 'bg-surface ' : ''}{klass}">
|
|
17
|
+
<div class="max-w-[1180px] mx-auto px-6 py-20">
|
|
18
|
+
{@render children?.()}
|
|
19
|
+
</div>
|
|
20
|
+
</section>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
muted?: boolean;
|
|
4
|
+
bordered?: boolean;
|
|
5
|
+
class?: string;
|
|
6
|
+
children?: Snippet;
|
|
7
|
+
};
|
|
8
|
+
declare const Section: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
9
|
+
type Section = ReturnType<typeof Section>;
|
|
10
|
+
export default Section;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import Eyebrow from '../atoms/Eyebrow.svelte';
|
|
4
|
+
import { cn } from '../../utils/cn.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Section heading block: eyebrow + h2 + optional lead (children).
|
|
8
|
+
*/
|
|
9
|
+
let {
|
|
10
|
+
eyebrow = '',
|
|
11
|
+
title = '',
|
|
12
|
+
class: klass = '',
|
|
13
|
+
children
|
|
14
|
+
}: { eyebrow?: string; title?: string; class?: string; children?: Snippet } = $props();
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<div class={cn('max-w-[700px]', klass)}>
|
|
18
|
+
{#if eyebrow}<Eyebrow>{eyebrow}</Eyebrow>{/if}
|
|
19
|
+
{#if title}
|
|
20
|
+
<h2 class="text-[clamp(27px,3.6vw,40px)] font-semibold tracking-[-0.02em] mt-3 leading-[1.1]">
|
|
21
|
+
{title}
|
|
22
|
+
</h2>
|
|
23
|
+
{/if}
|
|
24
|
+
{#if children}
|
|
25
|
+
<p class="mt-4 text-[16px] leading-relaxed text-muted">{@render children()}</p>
|
|
26
|
+
{/if}
|
|
27
|
+
</div>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
eyebrow?: string;
|
|
4
|
+
title?: string;
|
|
5
|
+
class?: string;
|
|
6
|
+
children?: Snippet;
|
|
7
|
+
};
|
|
8
|
+
declare const SectionHeading: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
9
|
+
type SectionHeading = ReturnType<typeof SectionHeading>;
|
|
10
|
+
export default SectionHeading;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import Logo from '../atoms/Logo.svelte';
|
|
3
|
+
import Badge from '../atoms/Badge.svelte';
|
|
4
|
+
import Icon from '../atoms/Icon.svelte';
|
|
5
|
+
import SearchButton from '../atoms/SearchButton.svelte';
|
|
6
|
+
import ThemeToggle from '../atoms/ThemeToggle.svelte';
|
|
7
|
+
import { getSite } from '../../site/site.js';
|
|
8
|
+
import { t } from 'svelte-i18n';
|
|
9
|
+
import { K } from '../../i18n/index.js';
|
|
10
|
+
|
|
11
|
+
// Docs top bar (slimmer than the landing header). Version + repo link
|
|
12
|
+
// come from the site context (injected by the app layout).
|
|
13
|
+
let { crumb = '', onsearch }: { crumb?: string; onsearch?: () => void } = $props();
|
|
14
|
+
|
|
15
|
+
const { route, version } = getSite();
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<header class="sticky top-0 z-[70] h-14 border-b border-line bg-canvas/85 backdrop-blur-md">
|
|
19
|
+
<div class="h-full px-5 flex items-center gap-4">
|
|
20
|
+
<a href={route('home')} class="flex items-center gap-2.5 select-none shrink-0 text-fg">
|
|
21
|
+
<Logo size={20} />
|
|
22
|
+
<span class="text-[15.5px] font-semibold tracking-tight">Axle</span>
|
|
23
|
+
<Badge class="ml-0.5 px-1.5 text-[10.5px] text-faint">{version}</Badge>
|
|
24
|
+
</a>
|
|
25
|
+
|
|
26
|
+
{#if crumb}
|
|
27
|
+
<span class="hidden md:flex items-center gap-2 text-[13px] text-muted min-w-0">
|
|
28
|
+
<span class="text-line">/</span>
|
|
29
|
+
<span class="truncate">{crumb}</span>
|
|
30
|
+
</span>
|
|
31
|
+
{/if}
|
|
32
|
+
|
|
33
|
+
<div class="ml-auto flex items-center gap-2">
|
|
34
|
+
<SearchButton class="hidden sm:flex w-[200px]" label={$t(K.search.docs)} onclick={onsearch} />
|
|
35
|
+
<ThemeToggle />
|
|
36
|
+
<a
|
|
37
|
+
href={route('repo')}
|
|
38
|
+
aria-label="Repository"
|
|
39
|
+
class="hidden sm:grid h-9 w-9 place-items-center rounded-lg border border-line bg-surface text-muted hover:text-fg transition-colors"
|
|
40
|
+
><Icon name="git" /></a
|
|
41
|
+
>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
</header>
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import Logo from '../atoms/Logo.svelte';
|
|
3
|
+
import { getSite } from '../../site/site.js';
|
|
4
|
+
import { t } from 'svelte-i18n';
|
|
5
|
+
import { K } from '../../i18n/index.js';
|
|
6
|
+
|
|
7
|
+
const { route } = getSite();
|
|
8
|
+
const cols = $derived([
|
|
9
|
+
{
|
|
10
|
+
title: $t(K.footer.docs),
|
|
11
|
+
links: [
|
|
12
|
+
[$t(K.footer.link.guide), route('guide')],
|
|
13
|
+
[$t(K.footer.link.reference), route('reference')],
|
|
14
|
+
[$t(K.footer.link.recipes), route('recipes')]
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
title: $t(K.footer.project),
|
|
19
|
+
links: [
|
|
20
|
+
[$t(K.footer.link.repo), route('repo')],
|
|
21
|
+
[$t(K.footer.link.roadmap), route('roadmap')],
|
|
22
|
+
[$t(K.footer.link.issues), route('issues')]
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
title: $t(K.footer.language),
|
|
27
|
+
links: [
|
|
28
|
+
[$t(K.footer.link.memory), route('memory')],
|
|
29
|
+
[$t(K.footer.link.simd), route('simd')],
|
|
30
|
+
[$t(K.footer.link.ffi), route('ffi')]
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
]);
|
|
34
|
+
</script>
|
|
35
|
+
|
|
36
|
+
<footer class="border-t border-line bg-surface">
|
|
37
|
+
<div
|
|
38
|
+
class="max-w-[1180px] mx-auto px-6 py-14 grid sm:grid-cols-2 lg:grid-cols-[1.4fr_1fr_1fr_1fr] gap-10"
|
|
39
|
+
>
|
|
40
|
+
<div>
|
|
41
|
+
<span class="flex items-center gap-2.5 text-fg">
|
|
42
|
+
<Logo size={20} /><span class="text-[16px] font-semibold tracking-tight">Axle</span>
|
|
43
|
+
</span>
|
|
44
|
+
<p class="mt-4 text-[13px] leading-relaxed text-muted max-w-[34ch]">
|
|
45
|
+
{$t(K.footer.tagline)}
|
|
46
|
+
</p>
|
|
47
|
+
</div>
|
|
48
|
+
{#each cols as col}
|
|
49
|
+
<div class="flex flex-col gap-2.5 text-[13.5px]">
|
|
50
|
+
<span class="text-[12px] font-semibold uppercase tracking-wider text-faint mb-1"
|
|
51
|
+
>{col.title}</span
|
|
52
|
+
>
|
|
53
|
+
{#each col.links as [label, href]}
|
|
54
|
+
<a {href} class="text-muted hover:text-fg">{label}</a>
|
|
55
|
+
{/each}
|
|
56
|
+
</div>
|
|
57
|
+
{/each}
|
|
58
|
+
</div>
|
|
59
|
+
<div class="border-t border-line">
|
|
60
|
+
<div
|
|
61
|
+
class="max-w-[1180px] mx-auto px-6 h-14 flex items-center justify-between text-[12.5px] text-faint"
|
|
62
|
+
>
|
|
63
|
+
<span>© 2026 Axle Language</span>
|
|
64
|
+
<span class="font-mono">{$t(K.footer.note)}</span>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
</footer>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import Logo from '../atoms/Logo.svelte';
|
|
3
|
+
import Badge from '../atoms/Badge.svelte';
|
|
4
|
+
import Button from '../atoms/Button.svelte';
|
|
5
|
+
import Icon from '../atoms/Icon.svelte';
|
|
6
|
+
import SearchButton from '../atoms/SearchButton.svelte';
|
|
7
|
+
import ThemeToggle from '../atoms/ThemeToggle.svelte';
|
|
8
|
+
import { getSite } from '../../site/site.js';
|
|
9
|
+
import { t } from 'svelte-i18n';
|
|
10
|
+
import { K } from '../../i18n/index.js';
|
|
11
|
+
|
|
12
|
+
// Landing top bar. Version + links come from the site context; labels
|
|
13
|
+
// from i18n ($t). Nothing is hardcoded at the call site.
|
|
14
|
+
let { onsearch }: { onsearch?: () => void } = $props();
|
|
15
|
+
|
|
16
|
+
const { route, version } = getSite();
|
|
17
|
+
const links = $derived([
|
|
18
|
+
{ label: $t(K.nav.guide), href: route('guide') },
|
|
19
|
+
{ label: $t(K.nav.reference), href: route('reference') },
|
|
20
|
+
{ label: $t(K.nav.benchmarks), href: route('benchmarks') },
|
|
21
|
+
{ label: $t(K.nav.recipes), href: route('recipes') }
|
|
22
|
+
]);
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<header class="sticky top-0 z-[70] border-b border-line bg-canvas/80 backdrop-blur-md">
|
|
26
|
+
<div class="max-w-[1180px] mx-auto px-6 h-16 flex items-center gap-6">
|
|
27
|
+
<a href={route('home')} class="flex items-center gap-2.5 select-none text-fg">
|
|
28
|
+
<Logo />
|
|
29
|
+
<span class="text-[17px] font-semibold tracking-tight">Axle</span>
|
|
30
|
+
<Badge class="ml-0.5">{version}</Badge>
|
|
31
|
+
</a>
|
|
32
|
+
|
|
33
|
+
<nav class="hidden md:flex items-center gap-0.5 ml-2 text-[14px]">
|
|
34
|
+
{#each links as link}
|
|
35
|
+
<a
|
|
36
|
+
href={link.href}
|
|
37
|
+
class="px-3 py-2 rounded-md text-muted hover:text-fg hover:bg-surface transition-colors"
|
|
38
|
+
>{link.label}</a
|
|
39
|
+
>
|
|
40
|
+
{/each}
|
|
41
|
+
</nav>
|
|
42
|
+
|
|
43
|
+
<div class="ml-auto flex items-center gap-2">
|
|
44
|
+
<SearchButton class="hidden sm:flex" onclick={onsearch} />
|
|
45
|
+
<ThemeToggle />
|
|
46
|
+
<a
|
|
47
|
+
href={route('repo')}
|
|
48
|
+
aria-label="Repository"
|
|
49
|
+
class="hidden sm:grid h-9 w-9 place-items-center rounded-lg border border-line bg-surface text-muted hover:text-fg transition-colors"
|
|
50
|
+
><Icon name="git" /></a
|
|
51
|
+
>
|
|
52
|
+
<Button href={route('guide')} size="sm">{$t(K.nav.getStarted)}</Button>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
</header>
|