This is the snapshot the production landing site (nibiru-framework.com) is deployed from. Brings together the recent splash + docs migration to the v4 "Cosmos" design system, the new in-framework AI module, and the framework groundwork that backs the framework-reference extraction. What lands: - docs/: Astro + Starlight site with the v4 dark cosmic palette, GalaxyHero canvas constellation, Mission Control chat (wired to /api/oracle → api.neuronetz.ai via providers.mjs Ollama), 5-panel MMVC stage (Model · AI · Module · Controller · View), translated EN/DE/JA/ES/FR content, PWA + sitemap + llms.txt + Umami analytics. - docs/design-system/: canonical mockup bundle (source/index-v2.html for splash, source/docs-system.html + preview/ for docs, SPEC.md, tokens). - docs/scripts/extraction/framework-reference-v2.md: deep framework reference (~1.6k lines, file:line citations, every public factory and idiom — basis for the LoRA training corpus. - application/module/ai/: AI module with chat / embed / RAG / agent plugins, plus pdoQuery / httpGet / fileRead tools and Modelfile + smoke-test in training/. - application/module/users/: user / ACL / form-factory traits used as the reference plugin pattern for the framework docs. - application/settings/config/database/: schema + seed migrations including the AI module tables (200–203). - Form factory + autogenerator changes the framework-reference-v2 covers. Production secrets stay out: docs/.env, settings.production.ini and ai.production.ini are all gitignored (.example files are in tree). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
759 lines
24 KiB
HTML
759 lines
24 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Documentation page · Nibiru — design mockup</title>
|
|
<meta name="description" content="Design mockup for a typical Nibiru documentation page. Layout, type, components and surfaces — built on the v4 Cosmos design system.">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<meta name="theme-color" content="#0a0414">
|
|
|
|
<!-- Type: Inter Tight (body) + Space Grotesk (display) + JetBrains Mono -->
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link href="https://fonts.googleapis.com/css2?family=Inter+Tight:wght@200..800&family=Space+Grotesk:wght@300..700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
|
|
|
<!-- Canonical Nibiru tokens (also embedded inline below for portability) -->
|
|
<link rel="stylesheet" href="./tokens.css">
|
|
|
|
<style>
|
|
/* ============================================================================
|
|
* Documentation-page mockup — Nibiru v4 Cosmos
|
|
*
|
|
* Standalone HTML the designer can open in a browser and riff on. Mirrors
|
|
* the production stack (Astro + Starlight) at the visual layer: header on
|
|
* top, sidebar nav on the left, article in the middle, on-page TOC on
|
|
* the right. Pure CSS, no JS — open it with file:// and it just works.
|
|
*
|
|
* Hand off: the designer should treat this as the "before" baseline for
|
|
* doc pages. The startpage (separate file) sets the brand tone; this
|
|
* shows how that tone translates to a content-heavy reading layout.
|
|
* ========================================================================= */
|
|
|
|
* { box-sizing: border-box; }
|
|
html, body { margin: 0; padding: 0; }
|
|
|
|
body {
|
|
font-family: 'Inter Tight', ui-sans-serif, system-ui, sans-serif;
|
|
background: var(--nibiru-space, #0a0414);
|
|
background-image:
|
|
radial-gradient(ellipse 70% 50% at 0% 0%, rgba(184, 107, 255, 0.10), transparent 60%),
|
|
radial-gradient(ellipse 60% 40% at 100% 0%, rgba(91, 141, 255, 0.07), transparent 60%);
|
|
background-attachment: fixed;
|
|
color: var(--nibiru-star, #f4eedb);
|
|
font-size: 16px;
|
|
line-height: 1.55;
|
|
font-feature-settings: "ss01", "cv11";
|
|
-webkit-font-smoothing: antialiased;
|
|
text-rendering: optimizeLegibility;
|
|
}
|
|
|
|
a { color: inherit; text-decoration: none; }
|
|
::selection { background: rgba(184, 107, 255, 0.4); color: var(--nibiru-star, #f4eedb); }
|
|
|
|
.mono, code, kbd, pre {
|
|
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;
|
|
}
|
|
.display { font-family: 'Space Grotesk', 'Inter Tight', ui-sans-serif, sans-serif; }
|
|
|
|
/* ============== HEADER ============== */
|
|
.doc-header {
|
|
position: sticky; top: 0; z-index: 60;
|
|
height: 64px;
|
|
display: flex; align-items: center;
|
|
padding: 0 24px;
|
|
background: rgba(6, 3, 15, 0.72);
|
|
border-bottom: 1px solid var(--nibiru-line, rgba(244, 238, 219, 0.12));
|
|
backdrop-filter: saturate(150%) blur(14px);
|
|
-webkit-backdrop-filter: saturate(150%) blur(14px);
|
|
}
|
|
.doc-header-row {
|
|
display: flex; align-items: center; justify-content: space-between;
|
|
width: 100%;
|
|
gap: 24px;
|
|
}
|
|
.brand {
|
|
display: flex; align-items: center; gap: 10px; flex: none;
|
|
font-family: 'Space Grotesk', sans-serif;
|
|
}
|
|
.brand-mark {
|
|
width: 28px; height: 28px;
|
|
border-radius: 50%;
|
|
background:
|
|
radial-gradient(circle at 35% 35%, #f4eedb 0%, #b86bff 40%, #5b8dff 80%, #1c0f3a 100%);
|
|
box-shadow: 0 0 12px rgba(184, 107, 255, 0.5);
|
|
}
|
|
.brand-name {
|
|
font-size: 18px; font-weight: 500; letter-spacing: -0.02em;
|
|
color: var(--nibiru-star, #f4eedb);
|
|
}
|
|
.brand-name em { font-style: normal; font-weight: 300; }
|
|
.nav-version {
|
|
font-family: 'JetBrains Mono', monospace;
|
|
font-size: 11px; letter-spacing: 0.04em;
|
|
color: var(--nibiru-muted, #6e6680);
|
|
padding: 3px 7px;
|
|
border: 1px solid var(--nibiru-line, rgba(244, 238, 219, 0.12));
|
|
border-radius: 999px;
|
|
margin-left: 6px;
|
|
display: inline-flex; align-items: center; gap: 6px;
|
|
}
|
|
.nav-version .dot {
|
|
width: 5px; height: 5px; border-radius: 50%;
|
|
background: #7ad6a3; box-shadow: 0 0 8px rgba(122, 214, 163, 0.7);
|
|
}
|
|
.doc-nav {
|
|
display: flex; gap: 24px; align-items: center;
|
|
flex: 1; justify-content: center;
|
|
}
|
|
.doc-nav a {
|
|
font-size: 14px;
|
|
color: rgba(244, 238, 219, 0.7);
|
|
transition: color 160ms ease;
|
|
}
|
|
.doc-nav a:hover, .doc-nav a[aria-current="page"] {
|
|
color: var(--nibiru-star, #f4eedb);
|
|
}
|
|
.search-inline {
|
|
display: flex; align-items: center; gap: 10px;
|
|
min-width: 220px;
|
|
height: 36px;
|
|
padding: 0 12px;
|
|
background: rgba(244, 238, 219, 0.04);
|
|
border: 1px solid var(--nibiru-line, rgba(244, 238, 219, 0.12));
|
|
border-radius: 999px;
|
|
color: rgba(244, 238, 219, 0.55);
|
|
font-size: 13px;
|
|
transition: border-color 160ms ease, background-color 160ms ease;
|
|
}
|
|
.search-inline:hover { border-color: var(--nibiru-line-strong, rgba(244, 238, 219, 0.28)); }
|
|
.search-inline svg { width: 14px; height: 14px; flex: none; }
|
|
.search-inline kbd {
|
|
margin-left: auto;
|
|
font-family: 'JetBrains Mono', monospace;
|
|
font-size: 11px;
|
|
color: var(--nibiru-muted, #6e6680);
|
|
padding: 2px 6px;
|
|
border: 1px solid var(--nibiru-line, rgba(244, 238, 219, 0.12));
|
|
border-radius: 4px;
|
|
background: rgba(244, 238, 219, 0.03);
|
|
}
|
|
.lang-switcher {
|
|
display: flex; gap: 4px;
|
|
font-family: 'JetBrains Mono', monospace;
|
|
font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase;
|
|
color: var(--nibiru-muted, #6e6680);
|
|
}
|
|
.lang-switcher a { padding: 4px 8px; border-radius: 6px; }
|
|
.lang-switcher a[aria-current="true"] {
|
|
color: var(--nibiru-star, #f4eedb);
|
|
background: rgba(184, 107, 255, 0.12);
|
|
}
|
|
|
|
/* ============== LAYOUT SHELL ============== */
|
|
.doc-shell {
|
|
display: grid;
|
|
grid-template-columns: 280px minmax(0, 1fr) 240px;
|
|
gap: 0;
|
|
max-width: 1400px;
|
|
margin: 0 auto;
|
|
min-height: calc(100vh - 64px);
|
|
}
|
|
@media (max-width: 1100px) {
|
|
.doc-shell { grid-template-columns: 240px 1fr; }
|
|
.doc-toc { display: none; }
|
|
}
|
|
@media (max-width: 768px) {
|
|
.doc-shell { grid-template-columns: 1fr; }
|
|
.doc-sidebar { display: none; }
|
|
}
|
|
|
|
/* ============== SIDEBAR ============== */
|
|
.doc-sidebar {
|
|
position: sticky; top: 64px;
|
|
height: calc(100vh - 64px);
|
|
overflow-y: auto;
|
|
padding: 28px 16px 28px 24px;
|
|
border-right: 1px solid var(--nibiru-line, rgba(244, 238, 219, 0.12));
|
|
background: rgba(10, 4, 20, 0.4);
|
|
backdrop-filter: blur(8px);
|
|
font-size: 14px;
|
|
scrollbar-width: thin;
|
|
scrollbar-color: rgba(184, 107, 255, 0.3) transparent;
|
|
}
|
|
.doc-sidebar h3 {
|
|
font-family: 'JetBrains Mono', monospace;
|
|
font-size: 11px; letter-spacing: 0.10em;
|
|
text-transform: uppercase;
|
|
color: var(--nibiru-muted, #6e6680);
|
|
margin: 22px 0 8px;
|
|
font-weight: 500;
|
|
}
|
|
.doc-sidebar h3:first-child { margin-top: 0; }
|
|
.doc-sidebar ul {
|
|
list-style: none; padding: 0; margin: 0;
|
|
display: flex; flex-direction: column; gap: 1px;
|
|
}
|
|
.doc-sidebar a {
|
|
display: block;
|
|
padding: 7px 12px;
|
|
color: rgba(244, 238, 219, 0.7);
|
|
border-left: 1.5px solid transparent;
|
|
border-radius: 0 8px 8px 0;
|
|
transition: color 160ms ease, border-color 160ms ease, background-color 160ms ease;
|
|
}
|
|
.doc-sidebar a:hover {
|
|
color: var(--nibiru-star, #f4eedb);
|
|
border-left-color: var(--nibiru-iris-soft, #d4b4ff);
|
|
background: rgba(184, 107, 255, 0.06);
|
|
}
|
|
.doc-sidebar a[aria-current="page"] {
|
|
color: var(--nibiru-star, #f4eedb);
|
|
font-weight: 500;
|
|
border-left-color: var(--nibiru-nebula-mag, #b86bff);
|
|
background: rgba(184, 107, 255, 0.10);
|
|
}
|
|
|
|
/* ============== ARTICLE ============== */
|
|
.doc-article {
|
|
min-width: 0;
|
|
padding: 56px 64px 120px;
|
|
max-width: 800px;
|
|
margin: 0 auto;
|
|
}
|
|
@media (max-width: 768px) {
|
|
.doc-article { padding: 32px 24px 80px; }
|
|
}
|
|
.breadcrumbs {
|
|
display: flex; align-items: center; gap: 8px;
|
|
font-family: 'JetBrains Mono', monospace;
|
|
font-size: 12px;
|
|
color: var(--nibiru-muted, #6e6680);
|
|
margin-bottom: 18px;
|
|
flex-wrap: wrap;
|
|
}
|
|
.breadcrumbs a:hover { color: var(--nibiru-star, #f4eedb); }
|
|
.breadcrumbs .sep { color: var(--nibiru-line-strong, rgba(244, 238, 219, 0.28)); }
|
|
|
|
.doc-article h1 {
|
|
font-family: 'Space Grotesk', sans-serif;
|
|
font-size: clamp(2rem, 1.5rem + 1.6vw, 2.75rem);
|
|
line-height: 1.05;
|
|
letter-spacing: -0.04em;
|
|
font-weight: 400;
|
|
margin: 0 0 18px;
|
|
color: var(--nibiru-star, #f4eedb);
|
|
}
|
|
.doc-article h1 em {
|
|
font-style: normal; font-weight: 500;
|
|
background: linear-gradient(110deg, #ffb574 0%, #b86bff 70%);
|
|
-webkit-background-clip: text; background-clip: text;
|
|
-webkit-text-fill-color: transparent;
|
|
color: transparent;
|
|
}
|
|
.doc-lede {
|
|
font-size: 1.18rem;
|
|
line-height: 1.55;
|
|
color: rgba(244, 238, 219, 0.72);
|
|
max-width: 56ch;
|
|
margin: 0 0 36px;
|
|
}
|
|
|
|
.doc-meta {
|
|
display: flex; gap: 28px; align-items: center;
|
|
font-family: 'JetBrains Mono', monospace;
|
|
font-size: 11px; letter-spacing: 0.06em;
|
|
text-transform: uppercase;
|
|
color: var(--nibiru-muted, #6e6680);
|
|
padding-bottom: 28px;
|
|
margin-bottom: 36px;
|
|
border-bottom: 1px solid var(--nibiru-line, rgba(244, 238, 219, 0.12));
|
|
flex-wrap: wrap;
|
|
}
|
|
.doc-meta strong { color: rgba(244, 238, 219, 0.85); font-weight: 500; }
|
|
.doc-meta .pulse {
|
|
width: 6px; height: 6px; border-radius: 50%;
|
|
background: #7ad6a3;
|
|
box-shadow: 0 0 8px rgba(122, 214, 163, 0.7);
|
|
}
|
|
|
|
.doc-article h2 {
|
|
font-family: 'Space Grotesk', sans-serif;
|
|
font-size: 1.6rem;
|
|
font-weight: 500;
|
|
letter-spacing: -0.025em;
|
|
line-height: 1.15;
|
|
margin: 56px 0 16px;
|
|
padding-top: 24px;
|
|
border-top: 1px solid var(--nibiru-line, rgba(244, 238, 219, 0.12));
|
|
color: var(--nibiru-star, #f4eedb);
|
|
}
|
|
.doc-article h3 {
|
|
font-family: 'Space Grotesk', sans-serif;
|
|
font-size: 1.18rem;
|
|
font-weight: 500;
|
|
letter-spacing: -0.02em;
|
|
margin: 36px 0 12px;
|
|
color: var(--nibiru-iris-soft, #d4b4ff);
|
|
}
|
|
.doc-article h4 {
|
|
font-family: 'JetBrains Mono', monospace;
|
|
font-size: 12px;
|
|
letter-spacing: 0.10em;
|
|
text-transform: uppercase;
|
|
color: var(--nibiru-muted, #6e6680);
|
|
margin: 28px 0 10px;
|
|
font-weight: 500;
|
|
}
|
|
.doc-article p {
|
|
color: rgba(244, 238, 219, 0.85);
|
|
margin: 0 0 18px;
|
|
line-height: 1.65;
|
|
}
|
|
.doc-article strong { color: var(--nibiru-star, #f4eedb); font-weight: 600; }
|
|
.doc-article a {
|
|
color: var(--nibiru-iris-soft, #d4b4ff);
|
|
border-bottom: 1px solid rgba(184, 107, 255, 0.4);
|
|
transition: color 200ms ease, border-color 200ms ease;
|
|
}
|
|
.doc-article a:hover {
|
|
color: var(--nibiru-star, #f4eedb);
|
|
border-bottom-color: var(--nibiru-nebula-mag, #b86bff);
|
|
}
|
|
.doc-article ul, .doc-article ol {
|
|
margin: 0 0 18px; padding-left: 24px;
|
|
}
|
|
.doc-article li { margin: 6px 0; color: rgba(244, 238, 219, 0.85); }
|
|
|
|
/* ============== INLINE CODE ============== */
|
|
.doc-article :not(pre) > code {
|
|
font-family: 'JetBrains Mono', monospace;
|
|
font-size: 0.86em;
|
|
background: rgba(184, 107, 255, 0.14);
|
|
color: var(--nibiru-iris-soft, #d4b4ff);
|
|
padding: 0.05em 0.4em;
|
|
border-radius: 6px;
|
|
border: 1px solid rgba(184, 107, 255, 0.20);
|
|
letter-spacing: 0.04em;
|
|
}
|
|
|
|
/* ============== CODE BLOCK ============== */
|
|
.code-block {
|
|
background: var(--nibiru-code-bg, #050208);
|
|
border: 1px solid var(--nibiru-line-strong, rgba(244, 238, 219, 0.28));
|
|
border-radius: 14px;
|
|
overflow: hidden;
|
|
margin: 22px 0;
|
|
box-shadow: 0 30px 60px -30px rgba(0, 0, 0, 0.7);
|
|
}
|
|
.code-block-head {
|
|
display: flex; justify-content: space-between; align-items: center;
|
|
padding: 10px 16px;
|
|
border-bottom: 1px solid rgba(244, 238, 219, 0.08);
|
|
font-family: 'JetBrains Mono', monospace;
|
|
font-size: 11px; letter-spacing: 0.10em; text-transform: uppercase;
|
|
color: var(--nibiru-muted, #6e6680);
|
|
}
|
|
.code-block-head .file { color: var(--nibiru-nebula-mag, #b86bff); }
|
|
.code-block-head .copy {
|
|
background: transparent;
|
|
border: 1px solid rgba(244, 238, 219, 0.12);
|
|
color: rgba(244, 238, 219, 0.7);
|
|
padding: 4px 10px;
|
|
border-radius: 6px;
|
|
font-family: 'JetBrains Mono', monospace;
|
|
font-size: 11px; letter-spacing: 0.10em;
|
|
cursor: pointer;
|
|
}
|
|
.code-block-head .copy:hover { border-color: var(--nibiru-iris-soft, #d4b4ff); color: var(--nibiru-star, #f4eedb); }
|
|
.code-block pre {
|
|
margin: 0; padding: 18px 20px;
|
|
font-family: 'JetBrains Mono', monospace;
|
|
font-size: 13px; line-height: 1.7;
|
|
color: var(--nibiru-star, #f4eedb);
|
|
overflow-x: auto;
|
|
}
|
|
.tk-c { color: #6e6680; font-style: italic; }
|
|
.tk-k { color: #c8a8ff; }
|
|
.tk-cls { color: #f0d4ff; }
|
|
.tk-fn { color: #b8d4ff; }
|
|
.tk-s { color: #ffd9a3; }
|
|
.tk-v { color: #ffb4d8; }
|
|
.tk-attr { color: #d4baff; }
|
|
.tk-n { color: #b8e0c2; }
|
|
|
|
/* ============== CALLOUT / ASIDE ============== */
|
|
.callout {
|
|
background: rgba(184, 107, 255, 0.06);
|
|
border: 1px solid rgba(244, 238, 219, 0.10);
|
|
border-left: 3px solid var(--nibiru-nebula-mag, #b86bff);
|
|
padding: 14px 16px 14px 18px;
|
|
border-radius: 0 10px 10px 0;
|
|
margin: 22px 0;
|
|
}
|
|
.callout--tip { border-left-color: var(--nibiru-nebula-amber, #ffb574); background: rgba(255, 181, 116, 0.06); }
|
|
.callout--danger { border-left-color: #ff8a9d; background: rgba(255, 138, 157, 0.06); }
|
|
.callout-title {
|
|
font-family: 'JetBrains Mono', monospace;
|
|
font-size: 11px; letter-spacing: 0.10em; text-transform: uppercase;
|
|
color: var(--nibiru-muted, #6e6680);
|
|
margin-bottom: 6px;
|
|
font-weight: 500;
|
|
}
|
|
.callout p { margin: 0; }
|
|
|
|
/* ============== TABLE ============== */
|
|
.doc-article table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
margin: 22px 0;
|
|
font-size: 14px;
|
|
}
|
|
.doc-article thead {
|
|
border-bottom: 2px solid var(--nibiru-line-strong, rgba(244, 238, 219, 0.28));
|
|
}
|
|
.doc-article th {
|
|
text-align: left;
|
|
padding: 10px 12px 10px 0;
|
|
font-family: 'JetBrains Mono', monospace;
|
|
font-weight: 500;
|
|
font-size: 11px;
|
|
letter-spacing: 0.10em;
|
|
text-transform: uppercase;
|
|
color: var(--nibiru-muted, #6e6680);
|
|
}
|
|
.doc-article td {
|
|
padding: 10px 12px 10px 0;
|
|
border-bottom: 1px solid var(--nibiru-line, rgba(244, 238, 219, 0.12));
|
|
color: rgba(244, 238, 219, 0.85);
|
|
vertical-align: top;
|
|
}
|
|
|
|
/* ============== ON-PAGE TOC (right rail) ============== */
|
|
.doc-toc {
|
|
position: sticky; top: 64px;
|
|
height: calc(100vh - 64px);
|
|
overflow-y: auto;
|
|
padding: 56px 24px 56px 16px;
|
|
border-left: 1px solid var(--nibiru-line, rgba(244, 238, 219, 0.12));
|
|
font-size: 13px;
|
|
}
|
|
.doc-toc h4 {
|
|
font-family: 'JetBrains Mono', monospace;
|
|
font-size: 11px; letter-spacing: 0.10em;
|
|
text-transform: uppercase;
|
|
color: var(--nibiru-muted, #6e6680);
|
|
margin: 0 0 12px;
|
|
font-weight: 500;
|
|
}
|
|
.doc-toc ul {
|
|
list-style: none; padding: 0; margin: 0;
|
|
display: flex; flex-direction: column; gap: 4px;
|
|
}
|
|
.doc-toc a {
|
|
color: rgba(244, 238, 219, 0.6);
|
|
display: block;
|
|
padding: 4px 0;
|
|
transition: color 160ms ease;
|
|
line-height: 1.4;
|
|
}
|
|
.doc-toc a:hover { color: var(--nibiru-star, #f4eedb); }
|
|
.doc-toc a.active {
|
|
color: var(--nibiru-star, #f4eedb);
|
|
border-left: 2px solid var(--nibiru-nebula-mag, #b86bff);
|
|
margin-left: -10px;
|
|
padding-left: 8px;
|
|
}
|
|
.doc-toc .l2 { padding-left: 12px; font-size: 12px; }
|
|
|
|
/* ============== PAGE FOOTER (prev / next) ============== */
|
|
.page-pagination {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 16px;
|
|
margin-top: 80px;
|
|
padding-top: 36px;
|
|
border-top: 1px solid var(--nibiru-line, rgba(244, 238, 219, 0.12));
|
|
}
|
|
@media (max-width: 600px) {
|
|
.page-pagination { grid-template-columns: 1fr; }
|
|
}
|
|
.page-pagination a {
|
|
background: var(--nibiru-night, #120825);
|
|
border: 1px solid var(--nibiru-line, rgba(244, 238, 219, 0.12));
|
|
border-radius: 14px;
|
|
padding: 16px 18px;
|
|
transition: border-color 200ms, transform 200ms;
|
|
}
|
|
.page-pagination a:hover {
|
|
border-color: var(--nibiru-nebula-mag, #b86bff);
|
|
transform: translateY(-1px);
|
|
}
|
|
.page-pagination .lbl {
|
|
font-family: 'JetBrains Mono', monospace;
|
|
font-size: 11px; letter-spacing: 0.10em;
|
|
text-transform: uppercase;
|
|
color: var(--nibiru-muted, #6e6680);
|
|
display: block;
|
|
margin-bottom: 4px;
|
|
}
|
|
.page-pagination .ttl {
|
|
font-size: 15px; font-weight: 500;
|
|
color: var(--nibiru-star, #f4eedb);
|
|
}
|
|
.page-pagination .next { text-align: right; }
|
|
|
|
/* ============== HELP STRIP ============== */
|
|
.help-strip {
|
|
margin-top: 48px;
|
|
padding: 18px 22px;
|
|
background: rgba(244, 238, 219, 0.03);
|
|
border: 1px solid var(--nibiru-line, rgba(244, 238, 219, 0.12));
|
|
border-radius: 12px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 16px;
|
|
flex-wrap: wrap;
|
|
font-size: 14px;
|
|
}
|
|
.help-strip-text { color: rgba(244, 238, 219, 0.75); }
|
|
.help-strip-actions { display: flex; gap: 8px; }
|
|
.help-strip-actions a {
|
|
padding: 7px 14px;
|
|
border: 1px solid var(--nibiru-line-strong, rgba(244, 238, 219, 0.28));
|
|
border-radius: 999px;
|
|
font-size: 13px;
|
|
color: rgba(244, 238, 219, 0.85);
|
|
transition: color 160ms, border-color 160ms;
|
|
border-bottom: 1px solid var(--nibiru-line-strong, rgba(244, 238, 219, 0.28));
|
|
}
|
|
.help-strip-actions a:hover {
|
|
color: var(--nibiru-star, #f4eedb);
|
|
border-color: var(--nibiru-iris-soft, #d4b4ff);
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<!-- ====================== HEADER ====================== -->
|
|
<header class="doc-header">
|
|
<div class="doc-header-row">
|
|
<a class="brand" href="#">
|
|
<span class="brand-mark"></span>
|
|
<span class="brand-name">Nibiru<em> docs</em></span>
|
|
<span class="nav-version"><span class="dot"></span>v0.9.2</span>
|
|
</a>
|
|
<nav class="doc-nav" aria-label="Primary">
|
|
<a href="#" aria-current="page">Docs</a>
|
|
<a href="#">MMVC</a>
|
|
<a href="#">AI module</a>
|
|
<a href="#">CLI</a>
|
|
<a href="#">Showcase</a>
|
|
</nav>
|
|
<div class="doc-header-tools" style="display: flex; align-items: center; gap: 12px;">
|
|
<div class="search-inline" role="search">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="7"/><path d="m21 21-3-3"/></svg>
|
|
<span>Search the docs</span>
|
|
<kbd>⌘ K</kbd>
|
|
</div>
|
|
<div class="lang-switcher" aria-label="Language">
|
|
<a href="#" aria-current="true">EN</a>
|
|
<a href="#">DE</a>
|
|
<a href="#">JA</a>
|
|
<a href="#">ES</a>
|
|
<a href="#">FR</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- ====================== SHELL ====================== -->
|
|
<div class="doc-shell">
|
|
|
|
<!-- ====== SIDEBAR ====== -->
|
|
<aside class="doc-sidebar" aria-label="Section navigation">
|
|
<h3>Get started</h3>
|
|
<ul>
|
|
<li><a href="#">What is Nibiru?</a></li>
|
|
<li><a href="#">Installation</a></li>
|
|
<li><a href="#">Quick start</a></li>
|
|
<li><a href="#" aria-current="page">Project structure</a></li>
|
|
<li><a href="#">Run it locally</a></li>
|
|
<li><a href="#">Deployment</a></li>
|
|
</ul>
|
|
|
|
<h3>The framework</h3>
|
|
<ul>
|
|
<li><a href="#">Architecture (MMVC)</a></li>
|
|
<li><a href="#">Bootstrap & Dispatcher</a></li>
|
|
<li><a href="#">Routing</a></li>
|
|
<li><a href="#">Controllers</a></li>
|
|
<li><a href="#">Views & Smarty</a></li>
|
|
<li><a href="#">Models</a></li>
|
|
<li><a href="#">Modules</a></li>
|
|
<li><a href="#">Forms</a></li>
|
|
<li><a href="#">Database & Migrations</a></li>
|
|
<li><a href="#">Auth</a></li>
|
|
</ul>
|
|
|
|
<h3>AI in Nibiru</h3>
|
|
<ul>
|
|
<li><a href="#">The AI module</a></li>
|
|
<li><a href="#">Chat plugin</a></li>
|
|
<li><a href="#">Embed plugin</a></li>
|
|
<li><a href="#">RAG plugin</a></li>
|
|
<li><a href="#">Agent plugin</a></li>
|
|
<li><a href="#">Ask the Oracle</a></li>
|
|
</ul>
|
|
</aside>
|
|
|
|
<!-- ====== ARTICLE ====== -->
|
|
<main class="doc-article">
|
|
|
|
<nav class="breadcrumbs" aria-label="Breadcrumb">
|
|
<a href="#">Docs</a>
|
|
<span class="sep">/</span>
|
|
<a href="#">Get started</a>
|
|
<span class="sep">/</span>
|
|
<span>Project structure</span>
|
|
</nav>
|
|
|
|
<h1>Project <em>structure</em></h1>
|
|
<p class="doc-lede">Where Nibiru puts things, and why. The shape on disk maps to the four MMVC roles — read top-down and the framework will explain itself.</p>
|
|
|
|
<div class="doc-meta">
|
|
<span><span class="pulse"></span> <strong>Stable</strong> · v0.9.2</span>
|
|
<span>Updated <strong>2 days ago</strong></span>
|
|
<span>Reading time <strong>~ 6 min</strong></span>
|
|
<span>Edit on <strong>GitHub</strong></span>
|
|
</div>
|
|
|
|
<p>A fresh Nibiru install is just a Composer-managed PHP project with a single CLI binary, an <code>application/</code> tree for your code, and a <code>core/</code> tree for the framework itself. Everything else — Smarty's compiled templates, the public docroot, the migrations history — falls out of those four conventions.</p>
|
|
|
|
<h2 id="overview">Overview</h2>
|
|
<p>Open the repo and you'll see this:</p>
|
|
|
|
<div class="code-block">
|
|
<div class="code-block-head">
|
|
<span class="file">tree.txt</span>
|
|
<button class="copy" type="button">Copy</button>
|
|
</div>
|
|
<pre><span class="tk-c"># A Nibiru project, top level</span>
|
|
my-app/
|
|
├── application/ <span class="tk-c">// your code lives here</span>
|
|
│ ├── controller/
|
|
│ ├── module/
|
|
│ ├── view/
|
|
│ └── settings/
|
|
├── core/ <span class="tk-c">// the framework — don't edit</span>
|
|
├── public/ <span class="tk-c">// docroot — point your vhost here</span>
|
|
├── nibiru <span class="tk-c">// the CLI binary</span>
|
|
├── composer.json
|
|
└── index.php <span class="tk-c">// front controller</span></pre>
|
|
</div>
|
|
|
|
<h3 id="application">application/</h3>
|
|
<p>Your code. Each role in <strong>MMVC</strong> is its own subdirectory: <code>controller/</code>, <code>module/</code>, <code>view/</code>. The fourth — Models — live inside their own <code>module/<name>/models/</code> subtrees, because in MMVC every module owns the data shape it touches.</p>
|
|
|
|
<div class="callout callout--tip">
|
|
<div class="callout-title">Tip</div>
|
|
<p>Run <code>./nibiru -c products</code> and the CLI will scaffold the controller, the module, the navigation entry and a Smarty template into the right places automatically.</p>
|
|
</div>
|
|
|
|
<h3 id="core">core/</h3>
|
|
<p>The framework itself. <strong>Don't edit it.</strong> If you find yourself reaching in here, the answer is almost always to extend a class in <code>application/</code> instead. The single exception: <a href="#">contributing back</a>.</p>
|
|
|
|
<h3 id="public">public/</h3>
|
|
<p>Your vhost docroot. Static assets are served directly from this directory; everything else falls through to the front controller via <code>index.php</code>. The <code>.htaccess</code> in the project root takes care of rewrites for Apache; the included <a href="#"><code>vhost.conf</code></a> shows the equivalent for nginx.</p>
|
|
|
|
<h2 id="naming">Naming conventions</h2>
|
|
<p>Every controller is <code><name>Controller.php</code>, every module sits at <code>application/module/<name>/</code>, every Smarty template lives at <code>application/view/templates/<name>.tpl</code>. The CLI enforces this — you don't have to remember it.</p>
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Path</th>
|
|
<th>Created by</th>
|
|
<th>Owns</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><code>application/controller/</code></td>
|
|
<td><code>./nibiru -c <name></code></td>
|
|
<td>Routing, dispatch, lifecycle</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>application/module/</code></td>
|
|
<td><code>./nibiru -m <name></code></td>
|
|
<td>Capabilities, plugins, models</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>application/view/templates/</code></td>
|
|
<td>scaffolded with controller</td>
|
|
<td>Smarty 3 templates</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>application/settings/migrations/</code></td>
|
|
<td><code>./nibiru -mi-add <n></code></td>
|
|
<td>Timestamped SQL migrations</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<div class="callout">
|
|
<div class="callout-title">Note</div>
|
|
<p>Smarty templates compile to <code>application/view/templates_c/</code> at first request. That directory is gitignored — clear it with <code>./nibiru -cache-clear</code> if a template ever sticks.</p>
|
|
</div>
|
|
|
|
<h2 id="next">Next</h2>
|
|
<p>You know where things go. Now wire one up — the <a href="#">Quick start</a> takes you from an empty project to a running controller in five commands.</p>
|
|
|
|
<!-- prev / next -->
|
|
<nav class="page-pagination" aria-label="Page navigation">
|
|
<a class="prev" href="#">
|
|
<span class="lbl">← Previous</span>
|
|
<span class="ttl">Quick start</span>
|
|
</a>
|
|
<a class="next" href="#">
|
|
<span class="lbl">Next →</span>
|
|
<span class="ttl">Run it locally</span>
|
|
</a>
|
|
</nav>
|
|
|
|
<!-- help strip -->
|
|
<aside class="help-strip">
|
|
<span class="help-strip-text">Was this page helpful?</span>
|
|
<div class="help-strip-actions">
|
|
<a href="#">Yes</a>
|
|
<a href="#">Suggest an edit</a>
|
|
</div>
|
|
</aside>
|
|
|
|
</main>
|
|
|
|
<!-- ====== ON-PAGE TOC ====== -->
|
|
<aside class="doc-toc" aria-label="On this page">
|
|
<h4>On this page</h4>
|
|
<ul>
|
|
<li><a href="#overview" class="active">Overview</a></li>
|
|
<li><a href="#application" class="l2">application/</a></li>
|
|
<li><a href="#core" class="l2">core/</a></li>
|
|
<li><a href="#public" class="l2">public/</a></li>
|
|
<li><a href="#naming">Naming conventions</a></li>
|
|
<li><a href="#next">Next</a></li>
|
|
</ul>
|
|
|
|
<h4 style="margin-top: 36px;">Notes</h4>
|
|
<p style="font-size: 12px; color: var(--nibiru-muted, #6e6680); line-height: 1.5;">
|
|
This is a design mockup, not a real docs page. The TOC scroll-spy, search modal,
|
|
and language-switcher are wired-up in the production Astro/Starlight build —
|
|
treat the visual elements here as the brief.
|
|
</p>
|
|
</aside>
|
|
|
|
</div>
|
|
|
|
</body>
|
|
</html>
|