diff --git a/docusaurus.config.ts b/docusaurus.config.ts index aae4361..6f3a9c9 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -35,7 +35,7 @@ const config: Config = { locales: ['en', 'it'], localeConfigs: { en: { label: 'English' }, - it: { label: 'Italiano' }, + it: { label: 'Italiano', htmlLang: 'it-IT' }, }, }, @@ -68,8 +68,24 @@ const config: Config = { ], themeConfig: { - // Social sharing image - image: '/assets/social/social-card.svg', + // Social sharing image (OG + Twitter Cards) + image: 'assets/social/social-card.png', + metadata: [ + {name: 'keywords', content: 'markdown, linter, docusaurus, mkdocs, static analysis, documentation, security, broken links, orphan pages'}, + {name: 'twitter:card', content: 'summary_large_image'}, + {name: 'twitter:site', content: '@PythonWoods'}, + {name: 'twitter:creator', content: '@PythonWoods'}, + {name: 'theme-color', content: '#4f46e5'}, + ], + headTags: [ + { + tagName: 'link', + attributes: { + rel: 'canonical', + href: 'https://zenzic.dev/', + }, + }, + ], colorMode: { defaultMode: 'dark', respectPrefersColorScheme: true, diff --git a/i18n/en/code.json b/i18n/en/code.json index dd73e23..0d18285 100644 --- a/i18n/en/code.json +++ b/i18n/en/code.json @@ -89,19 +89,19 @@ "message": "Scans every URL for leaked credentials - API keys, tokens. Exits with code 2 immediately." }, "homepage.hero.badge": { - "message": "v0.6.0a2 \"Obsidian Glass\" Released", + "message": "v0.6.1 \"Obsidian Glass\" Stable", "description": "Wait release version badge" }, "homepage.hero.title": { - "message": "High-performance linter", + "message": "The Safe Harbor", "description": "Main hero headline" }, "homepage.hero.titleMuted": { - "message": "for Markdown.", + "message": "for Markdown Documentation.", "description": "Muted part of the hero headline" }, "homepage.hero.subtitle": { - "message": "Catch broken links, orphan pages, and leaked credentials - before your users do. Engineering-grade and engine-agnostic.", + "message": "High-performance, engine-agnostic, and security-hardened static analysis.", "description": "Hero sub headline" }, "homepage.hero.getStarted": { @@ -211,6 +211,57 @@ "sentinel.summary.failed": { "message": "FAILED: One or more checks failed." }, + "sentinel.label": { + "message": "Reporter & Shield" + }, + "score.label": { + "message": "Health Metrics" + }, + "ledger.label": { + "message": "The Obsidian Engineering Ledger" + }, + "ledger.heading": { + "message": "Three invariants enforced on every commit." + }, + "ledger.heading.muted": { + "message": "No exceptions. No shortcuts." + }, + "ledger.sub": { + "message": "These are not aspirations \u2014 they are gates. Every release of Zenzic ships only when all three pass." + }, + "ledger.01.title": { + "message": "Zero Assumptions at System Boundaries" + }, + "ledger.01.desc": { + "message": "Every public entry point validates its inputs at the boundary. Internal hot paths carry no defensive checks \u2014 the shape is guaranteed by the type system, enforced by mypy --strict on every merge." + }, + "ledger.02.title": { + "message": "Subprocess-Free Analysis" + }, + "ledger.02.desc": { + "message": "Production-grade tools do not shell out during analysis. No subprocess.run(), no os.system() inside per-item loops. Zenzic validates your documentation stack without executing it." + }, + "ledger.03.title": { + "message": "Deterministic Dependency Graph" + }, + "ledger.03.desc": { + "message": "Every dependency is pinned in a lockfile, audited by Dependabot, and scanned for SPDX licence compatibility. No transitive surprises at release time. uv lock and reuse lint run on every commit." + }, + "quickstart.label": { + "message": "Get Started" + }, + "quickstart.heading": { + "message": "From zero to documentation integrity in one command." + }, + "quickstart.sub": { + "message": "No configuration required. No account needed. Works on any Markdown project." + }, + "quickstart.github": { + "message": "Star on GitHub" + }, + "quickstart.docs": { + "message": "Read the full docs \u2192" + }, "theme.ErrorPageContent.title": { "message": "This page crashed.", "description": "The title of the fallback page when the page crashed" diff --git a/i18n/it/code.json b/i18n/it/code.json index 39dc999..67c0626 100644 --- a/i18n/it/code.json +++ b/i18n/it/code.json @@ -680,19 +680,19 @@ "message": "Scans every URL for leaked credentials - API keys, tokens. Exits with code 2 immediately." }, "homepage.hero.badge": { - "message": "v0.6.0a1 \"Obsidian Glass\" Released", + "message": "v0.6.1 \"Obsidian Glass\" Stable", "description": "Wait release version badge" }, "homepage.hero.title": { - "message": "High-performance linter", + "message": "Il Safe Harbor", "description": "Main hero headline" }, "homepage.hero.titleMuted": { - "message": "for Markdown.", + "message": "per la Documentazione Markdown.", "description": "Muted part of the hero headline" }, "homepage.hero.subtitle": { - "message": "Catch broken links, orphan pages, and leaked credentials - before your users do. Engineering-grade and engine-agnostic.", + "message": "Analisi statica ad alte prestazioni, agnostica rispetto al motore e con sicurezza integrata.", "description": "Hero sub headline" }, "homepage.hero.getStarted": { @@ -792,5 +792,56 @@ }, "sentinel.summary.failed": { "message": "FAILED: One or more checks failed." + }, + "sentinel.label": { + "message": "Reporter & Shield" + }, + "score.label": { + "message": "Metriche di Qualit\u00e0" + }, + "ledger.label": { + "message": "L\u2019Obsidian Engineering Ledger" + }, + "ledger.heading": { + "message": "Tre invarianti verificati ad ogni commit." + }, + "ledger.heading.muted": { + "message": "Nessuna eccezione. Nessuna scorciatoia." + }, + "ledger.sub": { + "message": "Non sono aspirazioni \u2014 sono requisiti. Zenzic viene rilasciato solo quando tutti e tre passano." + }, + "ledger.01.title": { + "message": "Zero Assunzioni ai Confini del Sistema" + }, + "ledger.01.desc": { + "message": "Ogni entry point pubblico valida i propri input al confine. I percorsi interni non contengono controlli difensivi \u2014 la forma \u00e8 garantita dal sistema di tipi, imposta da mypy --strict ad ogni merge." + }, + "ledger.02.title": { + "message": "Analisi Senza Sottoprocessi" + }, + "ledger.02.desc": { + "message": "Gli strumenti di livello produzione non eseguono shell durante l\u2019analisi. Nessun subprocess.run(), nessun os.system() nei loop per-item. Zenzic valida il tuo stack documentale senza eseguirlo." + }, + "ledger.03.title": { + "message": "Grafo delle Dipendenze Deterministico" + }, + "ledger.03.desc": { + "message": "Ogni dipendenza \u00e8 bloccata in un lockfile, verificata da Dependabot e analizzata per compatibilit\u00e0 SPDX. Nessuna sorpresa transitiva al momento del rilascio. uv lock e reuse lint vengono eseguiti ad ogni commit." + }, + "quickstart.label": { + "message": "Inizia" + }, + "quickstart.heading": { + "message": "Da zero all\u2019integrit\u00e0 documentale in un solo comando." + }, + "quickstart.sub": { + "message": "Nessuna configurazione richiesta. Nessun account necessario. Funziona su qualsiasi progetto Markdown." + }, + "quickstart.github": { + "message": "Star su GitHub" + }, + "quickstart.docs": { + "message": "Leggi la documentazione completa \u2192" } } diff --git a/src/components/Homepage/EngineeringLedger.tsx b/src/components/Homepage/EngineeringLedger.tsx new file mode 100644 index 0000000..45681b3 --- /dev/null +++ b/src/components/Homepage/EngineeringLedger.tsx @@ -0,0 +1,175 @@ +// SPDX-FileCopyrightText: 2026 PythonWoods +// SPDX-License-Identifier: Apache-2.0 +import React from 'react'; +import Translate from '@docusaurus/Translate'; + +// ── Minimal terminal box ─────────────────────────────────────────────────── +function LedgerTerminal({ + filename, + children, +}: { + filename: string; + children: React.ReactNode; +}): React.JSX.Element { + return ( +
+
+
+
+ {children} +
+
+ ); +} + +// ── One ledger row ───────────────────────────────────────────────────────── +function LedgerRow({ + index, + title, + desc, + terminal, +}: { + index: string; + title: React.ReactNode; + desc: React.ReactNode; + terminal: React.ReactNode; +}): React.JSX.Element { + return ( +
+
+ + {index} + +

+ {title} +

+

{desc}

+
+
{terminal}
+
+ ); +} + +// ── The Obsidian Engineering Ledger ─────────────────────────────────────── +export default function EngineeringLedger(): React.JSX.Element { + return ( +
+
+ {/* Section header */} +
+

+ The Obsidian Engineering Ledger +

+

+ Three invariants enforced on every commit.{' '} + + No exceptions. No shortcuts. + +

+

+ + These are not aspirations — they are gates. Every release of Zenzic ships only when + all three pass. + +

+
+ + {/* ── 01 — Zero Assumptions ─────────────────────────────────────── */} + Zero Assumptions at System Boundaries + } + desc={ + + Every public entry point validates its inputs at the boundary. Internal hot paths + carry no defensive checks — the shape is guaranteed by the type system, enforced by + mypy --strict on every merge. + + } + terminal={ + +
+                
+                  {`[tool.mypy]
+strict            = true
+warn_return_any   = true
+warn_unreachable  = true
+
+# Every public function has a typed signature.
+# Every Any must be justified in a comment.`}
+                
+              
+
+ } + /> + + {/* ── 02 — Subprocess-Free ──────────────────────────────────────── */} + Subprocess-Free Analysis} + desc={ + + Production-grade tools do not shell out during analysis. No subprocess.run(), no + os.system() inside per-item loops. Zenzic validates your documentation stack without + executing it. + + } + terminal={ + +
+                
+                  {`# ✓ ALLOWED — single setup phase
+class ZenzicEngine:
+    def __init__(self, config: Config):
+        self._vsm = build_vsm(config)   # I/O once
+
+# ✗ BLOCKED — subprocess inside analysis loop
+for page in corpus:
+    subprocess.run([...])  # ← architectural defect`}
+                
+              
+
+ } + /> + + {/* ── 03 — Deterministic Dependency Graph ───────────────────────── */} + Deterministic Dependency Graph + } + desc={ + + Every dependency is pinned in a lockfile, audited by Dependabot, and scanned for + SPDX licence compatibility. No transitive surprises at release time. uv lock and + reuse lint run on every commit. + + } + terminal={ + +
+                
+                  {`# runs on every commit via pre-commit
+nox -s reuse
+
+✓ SPDX headers present   │ all source files
+✓ Apache-2.0 declared    │ LICENSES/
+✓ Third-party notices    │ NOTICE
+# No dependency ships
+# without a licence audit.`}
+                
+              
+
+ } + /> +
+
+ ); +} diff --git a/src/components/Homepage/Hero.tsx b/src/components/Homepage/Hero.tsx index 787e92f..473b157 100644 --- a/src/components/Homepage/Hero.tsx +++ b/src/components/Homepage/Hero.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import Link from '@docusaurus/Link'; import useBaseUrl from '@docusaurus/useBaseUrl'; import Translate, { translate } from '@docusaurus/Translate'; @@ -13,42 +12,44 @@ export function SentinelBadge(): React.JSX.Element { } export default function Hero(): React.JSX.Element { - const docsHref = useBaseUrl('/docs/'); const iconUrl = useBaseUrl('/assets/brand/svg/zenzic-icon.svg'); return (
{/* Stealth Logo */} - Zenzic Icon + Zenzic Icon
- v0.6.0a1 "Obsidian Glass" Released + v0.6.1 "Obsidian Glass" Stable

- High-performance linter + The Safe Harbor
- for Markdown. + for Markdown Documentation.

- Catch broken links, orphan pages, and leaked credentials - before your users do. Engineering-grade and engine-agnostic. + High-performance, engine-agnostic, and security-hardened static analysis.

- + Get started - + View on GitHub diff --git a/src/components/Homepage/QualityScore.tsx b/src/components/Homepage/QualityScore.tsx index 6c50be1..c8f8e37 100644 --- a/src/components/Homepage/QualityScore.tsx +++ b/src/components/Homepage/QualityScore.tsx @@ -39,6 +39,9 @@ export default function QualityScore(): React.JSX.Element {
+

+ Health Metrics +

Quality Score

@@ -73,18 +76,18 @@ export default function QualityScore(): React.JSX.Element {
Internal Links Health} value="99" />
- } label={Anchor stability} value="28" /> - } label={External references} value="16" /> + } label={Anchor stability} value="100" /> + } label={External references} value="97" />
- Orphan Detection} value="21" /> + Orphan Detection} value="95" />
- } label={Unused Assets} value="12" /> - } label={Nav Isolation} value="9" /> + } label={Unused Assets} value="91" /> + } label={Nav Isolation} value="100" />
diff --git a/src/components/Homepage/Quickstart.tsx b/src/components/Homepage/Quickstart.tsx new file mode 100644 index 0000000..9fbd5a2 --- /dev/null +++ b/src/components/Homepage/Quickstart.tsx @@ -0,0 +1,105 @@ +// SPDX-FileCopyrightText: 2026 PythonWoods +// SPDX-License-Identifier: Apache-2.0 +import React from 'react'; +import Link from '@docusaurus/Link'; +import useBaseUrl from '@docusaurus/useBaseUrl'; +import Translate from '@docusaurus/Translate'; + +export default function Quickstart(): React.JSX.Element { + const docsHref = useBaseUrl('/docs/'); + + return ( +
+ +
+ ); +} diff --git a/src/components/Homepage/SentinelSection.tsx b/src/components/Homepage/SentinelSection.tsx index 5067e61..f06974d 100644 --- a/src/components/Homepage/SentinelSection.tsx +++ b/src/components/Homepage/SentinelSection.tsx @@ -6,6 +6,9 @@ export default function SentinelSection(): React.JSX.Element {
+

+ Reporter & Shield +

Sentinel in Action

diff --git a/src/css/homepage.css b/src/css/homepage.css index 5eed141..2d7b550 100644 --- a/src/css/homepage.css +++ b/src/css/homepage.css @@ -25,3 +25,8 @@ .zz-homepage a:hover { text-decoration: none; } + +/* Smooth scroll for the #quickstart anchor */ +.zz-homepage { + scroll-behavior: smooth; +} diff --git a/src/pages/index.tsx b/src/pages/index.tsx index f22731c..8a5314c 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -4,29 +4,53 @@ import Layout from '@theme/Layout'; import '@site/src/css/homepage.css'; import Hero from '../components/Homepage/Hero'; -import Features from '../components/Homepage/Features'; +import EngineeringLedger from '../components/Homepage/EngineeringLedger'; import SentinelSection from '../components/Homepage/SentinelSection'; import QualityScore from '../components/Homepage/QualityScore'; +import Quickstart from '../components/Homepage/Quickstart'; export default function Home(): React.JSX.Element { return (
- + + + + + + + + +
- + +