Skip to main content

logicaffeine_web/ui/pages/
crates.rs

1//! Crate documentation landing page.
2//!
3//! Displays a grid of crate cards with descriptions, linking to rustdoc HTML.
4//! Each card links directly to `/crates/{crate_name}/index.html`.
5
6use dioxus::prelude::*;
7#[cfg(all(feature = "split", target_arch = "wasm32"))]
8use dioxus::wasm_split;
9use crate::ui::components::main_nav::{MainNav, ActivePage};
10use crate::ui::components::footer::Footer;
11use crate::ui::seo::{JsonLdMultiple, PageHead, organization_schema, tech_article_schema, breadcrumb_schema, BreadcrumbItem, pages as seo_pages};
12
13const CRATES_STYLE: &str = r#"
14.crates-page {
15    min-height: 100vh;
16    color: var(--text-primary);
17    background:
18        radial-gradient(1200px 600px at 50% -120px, rgba(167,139,250,0.14), transparent 60%),
19        radial-gradient(900px 500px at 15% 30%, rgba(96,165,250,0.14), transparent 60%),
20        radial-gradient(800px 450px at 90% 45%, rgba(34,197,94,0.08), transparent 62%),
21        linear-gradient(180deg, #070a12, #0b1022 55%, #070a12);
22    font-family: var(--font-sans);
23}
24
25.crates-hero {
26    max-width: 1280px;
27    margin: 0 auto;
28    padding: 60px var(--spacing-xl) 40px;
29}
30
31.crates-hero h1 {
32    font-size: var(--font-display-lg);
33    font-weight: 900;
34    letter-spacing: -1.5px;
35    line-height: 1.1;
36    background: linear-gradient(180deg, #ffffff 0%, rgba(229,231,235,0.78) 65%, rgba(229,231,235,0.62) 100%);
37    -webkit-background-clip: text;
38    -webkit-text-fill-color: transparent;
39    margin: 0 0 var(--spacing-lg);
40}
41
42.crates-hero p {
43    font-size: var(--font-body-lg);
44    color: var(--text-secondary);
45    max-width: 600px;
46    line-height: 1.6;
47    margin: 0;
48}
49
50.crates-hero-badge {
51    display: inline-flex;
52    align-items: center;
53    gap: var(--spacing-sm);
54    padding: var(--spacing-sm) 14px;
55    border-radius: var(--radius-full);
56    background: rgba(255,255,255,0.06);
57    border: 1px solid rgba(255,255,255,0.10);
58    font-size: var(--font-caption-md);
59    font-weight: 600;
60    color: var(--text-primary);
61    margin-bottom: var(--spacing-xl);
62}
63
64.crates-hero-badge .dot {
65    width: 8px;
66    height: 8px;
67    border-radius: 50%;
68    background: var(--color-accent-purple);
69    box-shadow: 0 0 0 4px rgba(167,139,250,0.15);
70}
71
72.crates-content {
73    max-width: 1280px;
74    margin: 0 auto;
75    padding: 0 var(--spacing-xl) 80px;
76}
77
78.crates-grid {
79    display: grid;
80    grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
81    gap: 24px;
82}
83
84.crate-card {
85    display: block;
86    background: rgba(255,255,255,0.03);
87    border: 1px solid rgba(255,255,255,0.08);
88    border-radius: var(--radius-xl);
89    padding: 24px;
90    text-decoration: none;
91    color: inherit;
92    transition: transform 0.2s, border-color 0.2s, background 0.2s, box-shadow 0.2s;
93}
94
95.crate-card:hover {
96    transform: translateY(-2px);
97    border-color: rgba(167,139,250,0.4);
98    background: rgba(255,255,255,0.05);
99    box-shadow: 0 12px 30px rgba(167,139,250,0.08);
100}
101
102.crate-header {
103    display: flex;
104    justify-content: space-between;
105    align-items: flex-start;
106    margin-bottom: 12px;
107}
108
109.crate-name {
110    font-size: 18px;
111    font-weight: 700;
112    color: #fff;
113    margin: 0;
114    font-family: var(--font-mono);
115    display: flex;
116    align-items: center;
117    gap: 8px;
118}
119
120.crate-badge {
121    display: inline-flex;
122    align-items: center;
123    font-size: 11px;
124    font-weight: 700;
125    padding: 3px 8px;
126    border-radius: 999px;
127}
128
129.crate-badge.core {
130    background: linear-gradient(135deg, rgba(96,165,250,0.9), rgba(167,139,250,0.9));
131    color: #060814;
132}
133
134.crate-badge.app {
135    background: rgba(34,197,94,0.2);
136    color: #22c55e;
137    border: 1px solid rgba(34,197,94,0.3);
138}
139
140.crate-description {
141    color: var(--text-secondary);
142    font-size: 14px;
143    line-height: 1.6;
144    margin: 0;
145}
146
147.crate-arrow {
148    display: flex;
149    align-items: center;
150    justify-content: flex-end;
151    margin-top: 16px;
152    color: var(--text-tertiary);
153    font-size: 13px;
154    gap: 6px;
155    transition: color 0.2s;
156}
157
158.crate-card:hover .crate-arrow {
159    color: var(--color-accent-purple);
160}
161
162.crate-arrow svg {
163    width: 16px;
164    height: 16px;
165    transition: transform 0.2s;
166}
167
168.crate-card:hover .crate-arrow svg {
169    transform: translateX(3px);
170}
171
172.crate-links {
173    display: flex;
174    gap: 12px;
175    margin-top: 16px;
176    padding-top: 16px;
177    border-top: 1px solid rgba(255,255,255,0.06);
178}
179
180.crate-link {
181    display: inline-flex;
182    align-items: center;
183    gap: 6px;
184    padding: 8px 14px;
185    border-radius: var(--radius-md);
186    font-size: var(--font-caption-md);
187    font-weight: 600;
188    text-decoration: none;
189    transition: all 0.2s ease;
190}
191
192.crate-link.docs {
193    background: rgba(167,139,250,0.15);
194    color: #a78bfa;
195    border: 1px solid rgba(167,139,250,0.3);
196}
197
198.crate-link.docs:hover {
199    background: rgba(167,139,250,0.25);
200    border-color: rgba(167,139,250,0.5);
201}
202
203.crate-link.crates-io {
204    background: rgba(249,115,22,0.15);
205    color: #fb923c;
206    border: 1px solid rgba(249,115,22,0.3);
207}
208
209.crate-link.crates-io:hover {
210    background: rgba(249,115,22,0.25);
211    border-color: rgba(249,115,22,0.5);
212}
213
214.crate-link svg {
215    width: 16px;
216    height: 16px;
217}
218
219.crates-section {
220    margin-bottom: 48px;
221}
222
223.crates-section-title {
224    font-size: var(--font-body-md);
225    font-weight: 700;
226    text-transform: uppercase;
227    letter-spacing: 1.5px;
228    color: var(--text-tertiary);
229    margin: 0 0 24px;
230    padding-bottom: var(--spacing-md);
231    border-bottom: 1px solid rgba(255,255,255,0.08);
232}
233
234@media (max-width: 768px) {
235    .crates-grid {
236        grid-template-columns: 1fr;
237    }
238
239    .crates-hero h1 {
240        font-size: var(--font-display-md);
241    }
242
243    .crates-hero {
244        padding: 40px var(--spacing-xl) var(--spacing-xxl);
245    }
246}
247"#;
248
249#[derive(Clone, Copy, PartialEq)]
250struct CrateInfo {
251    name: &'static str,
252    description: &'static str,
253    is_core: bool,
254    crates_io: Option<&'static str>,
255}
256
257const CORE_CRATES: &[CrateInfo] = &[
258    CrateInfo {
259        name: "logicaffeine_language",
260        description: "Core LOGOS language implementation including AST, parser, and first-order logic transpiler.",
261        is_core: true,
262        crates_io: Some("https://crates.io/crates/logicaffeine-language"),
263    },
264    CrateInfo {
265        name: "logicaffeine_compile",
266        description: "Code generation and compilation from LOGOS to executable formats.",
267        is_core: true,
268        crates_io: Some("https://crates.io/crates/logicaffeine-compile"),
269    },
270    CrateInfo {
271        name: "logicaffeine_lsp",
272        description: "Language Server Protocol implementation for IDE integration with diagnostics, completion, and refactoring.",
273        is_core: true,
274        crates_io: Some("https://crates.io/crates/logicaffeine-lsp"),
275    },
276    CrateInfo {
277        name: "logicaffeine_kernel",
278        description: "Runtime kernel for executing LOGOS programs with built-in inference.",
279        is_core: true,
280        crates_io: Some("https://crates.io/crates/logicaffeine-kernel"),
281    },
282    CrateInfo {
283        name: "logicaffeine_proof",
284        description: "Proof assistant and formal verification engine for logical reasoning.",
285        is_core: true,
286        crates_io: Some("https://crates.io/crates/logicaffeine-proof"),
287    },
288    CrateInfo {
289        name: "logicaffeine_lexicon",
290        description: "Vocabulary database and lexical analysis for natural language parsing.",
291        is_core: true,
292        crates_io: Some("https://crates.io/crates/logicaffeine-lexicon"),
293    },
294    CrateInfo {
295        name: "logicaffeine_base",
296        description: "Shared base types, traits, and utilities used across all crates.",
297        is_core: true,
298        crates_io: Some("https://crates.io/crates/logicaffeine-base"),
299    },
300    CrateInfo {
301        name: "logicaffeine_data",
302        description: "Data structures and persistent storage for programs and proofs.",
303        is_core: true,
304        crates_io: Some("https://crates.io/crates/logicaffeine-data"),
305    },
306    CrateInfo {
307        name: "logicaffeine_system",
308        description: "System integration layer for platform-specific functionality.",
309        is_core: true,
310        crates_io: Some("https://crates.io/crates/logicaffeine-system"),
311    },
312    CrateInfo {
313        name: "logicaffeine_runtime",
314        description: "Deterministic concurrency runtime — task scheduler, FIFO channels, Select, and seed/trace replay for the interpreter and VM.",
315        is_core: true,
316        crates_io: Some("https://crates.io/crates/logicaffeine-runtime"),
317    },
318    CrateInfo {
319        name: "logicaffeine_forge",
320        description: "Copy-and-patch JIT for LOGOS — executable-memory layer, stencil runtime, and register-allocating x86-64 backend (EXODIA).",
321        is_core: true,
322        crates_io: Some("https://crates.io/crates/logicaffeine-forge"),
323    },
324    CrateInfo {
325        name: "logicaffeine_jit",
326        description: "Native execution tier — wires the copy-and-patch forge JIT to VM bytecode for hot functions and loop regions.",
327        is_core: true,
328        crates_io: Some("https://crates.io/crates/logicaffeine-jit"),
329    },
330];
331
332const VERIFY_CRATES: &[CrateInfo] = &[
333    CrateInfo {
334        name: "logicaffeine_verify",
335        description: "Z3-based static verification — BMC, k-induction, IC3, interpolation, equivalence, and SVA.",
336        is_core: true,
337        crates_io: Some("https://crates.io/crates/logicaffeine-verify"),
338    },
339    CrateInfo {
340        name: "logicaffeine_tv",
341        description: "SMT translation validation — proves the emitted Rust is observationally equivalent to the LOGOS source on every compile.",
342        is_core: true,
343        crates_io: Some("https://crates.io/crates/logicaffeine-tv"),
344    },
345];
346
347const APP_CRATES: &[CrateInfo] = &[
348    CrateInfo {
349        name: "logicaffeine_cli",
350        description: "Command-line interface for the LOGOS toolchain (largo).",
351        is_core: false,
352        crates_io: Some("https://crates.io/crates/logicaffeine-cli"),
353    },
354    CrateInfo {
355        name: "logicaffeine_web",
356        description: "Web frontend components built with Dioxus for the learning platform.",
357        is_core: false,
358        crates_io: None,
359    },
360];
361
362#[component(lazy)]
363pub fn Crates() -> Element {
364    let breadcrumbs = vec![
365        BreadcrumbItem { name: "Home", path: "/" },
366        BreadcrumbItem { name: "Crates", path: "/crates" },
367    ];
368    let schemas = vec![
369        organization_schema(),
370        tech_article_schema("LOGICAFFEINE Crate Documentation", "Technical API documentation for all LOGICAFFEINE Rust crates. Integrate First-Order Logic parsing into your applications.", "/crates"),
371        breadcrumb_schema(&breadcrumbs),
372    ];
373
374    rsx! {
375        PageHead {
376            title: seo_pages::CRATES.title,
377            description: seo_pages::CRATES.description,
378            canonical_path: seo_pages::CRATES.canonical_path,
379        }
380        style { "{CRATES_STYLE}" }
381        JsonLdMultiple { schemas }
382
383        div { class: "crates-page",
384            MainNav {
385                active: ActivePage::Crates,
386                subtitle: Some("Crate Documentation"),
387            }
388
389            header { class: "crates-hero",
390                div { class: "crates-hero-badge",
391                    div { class: "dot" }
392                    span { "Rustdoc" }
393                }
394                h1 { "Crate Documentation" }
395                p {
396                    "Explore the API documentation for all LOGICAFFEINE crates. Each crate is documented with examples and detailed type information."
397                }
398            }
399
400            main { class: "crates-content",
401                section { class: "crates-section",
402                    h2 { class: "crates-section-title", "Core Crates" }
403                    div { class: "crates-grid",
404                        for crate_info in CORE_CRATES.iter() {
405                            CrateCard { info: crate_info }
406                        }
407                    }
408                }
409
410                section { class: "crates-section",
411                    h2 { class: "crates-section-title", "Verification" }
412                    div { class: "crates-grid",
413                        for crate_info in VERIFY_CRATES.iter() {
414                            CrateCard { info: crate_info }
415                        }
416                    }
417                }
418
419                section { class: "crates-section",
420                    h2 { class: "crates-section-title", "Application Crates" }
421                    div { class: "crates-grid",
422                        for crate_info in APP_CRATES.iter() {
423                            CrateCard { info: crate_info }
424                        }
425                    }
426                }
427            }
428
429            Footer {}
430        }
431    }
432}
433
434#[component]
435fn CrateCard(info: &'static CrateInfo) -> Element {
436    let doc_url = format!("https://docs.logicaffeine.com/{}/index.html", info.name);
437
438    rsx! {
439        div { class: "crate-card",
440            div { class: "crate-header",
441                h3 { class: "crate-name",
442                    "{info.name}"
443                }
444                span {
445                    class: if info.is_core { "crate-badge core" } else { "crate-badge app" },
446                    if info.is_core { "Core" } else { "App" }
447                }
448            }
449            p { class: "crate-description", "{info.description}" }
450            div { class: "crate-links",
451                a {
452                    class: "crate-link docs",
453                    href: "{doc_url}",
454                    target: "_blank",
455                    rel: "noopener",
456                    svg {
457                        xmlns: "http://www.w3.org/2000/svg",
458                        fill: "none",
459                        view_box: "0 0 24 24",
460                        stroke: "currentColor",
461                        stroke_width: "2",
462                        path {
463                            stroke_linecap: "round",
464                            stroke_linejoin: "round",
465                            d: "M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"
466                        }
467                    }
468                    "Docs"
469                }
470                if let Some(crates_url) = info.crates_io {
471                    a {
472                        class: "crate-link crates-io",
473                        href: "{crates_url}",
474                        target: "_blank",
475                        rel: "noopener",
476                        svg {
477                            xmlns: "http://www.w3.org/2000/svg",
478                            fill: "none",
479                            view_box: "0 0 24 24",
480                            stroke: "currentColor",
481                            stroke_width: "2",
482                            path {
483                                stroke_linecap: "round",
484                                stroke_linejoin: "round",
485                                d: "M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4"
486                            }
487                        }
488                        "crates.io"
489                    }
490                }
491            }
492        }
493    }
494}