From 1e9d11d839be286c558f301d38c75146b0b3f96a Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 29 Jul 2026 15:19:52 +0000 Subject: [PATCH 1/2] feat(site): rebuild the landing page as a full product site Replaces the single-file page with a structured site that explains what Zero Layer is, why it exists, how it works and what it is built on. Structure - Split into index.html + assets/css/styles.css + assets/js/{i18n,main}.js instead of one monolithic file, so copy, styling and behaviour can be changed independently. Design system - Token-based CSS: type scale with clamp(), 8px spacing rhythm, elevation surfaces, gradient-mesh + grain backdrop, consistent motion easing. - Dark remains the base theme; the light theme mirrors every token. New content - Why: the three concrete failure modes of Linux packaging. - The idea: a before/after view of the ELF fields that get rewritten, which is the clearest way to show what "binary translation" means. - Philosophy: the six principles the codebase is held to. - How it works: the real eight-stage install pipeline, with per-stage detail. - Capabilities, 13 sources, a tabbed command explorer, on-disk architecture, a comparison against containers/Flatpak/Snap/manual installs, a 3-step quickstart with copy buttons, and an 8-question FAQ. - CTAs at hero, quickstart and closing; a four-column footer with socials. Interaction - Animated install demo in the hero, scroll progress bar, animated counters, staggered reveals, accessible tabs (arrow-key navigation), copy-to-clipboard with a clipboard fallback, and a collapsible mobile menu. - All of it degrades under prefers-reduced-motion. i18n - All five languages (EN default, IT/FR/ES/DE) cover the new copy, including the meta description, with English as the per-key fallback. Verified with headless Chromium: no JS errors, language switching updates every section, tabs/theme/menu work, no horizontal overflow from 320px to 1440px, tap targets >=40px, one h1, visible focus ring, and text contrast at WCAG AA or better in both themes. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01LAjDSA1954JLqUZnxoJ5sy --- docs/site/assets/css/styles.css | 1108 +++++++++++++++++ docs/site/assets/js/i18n.js | 843 +++++++++++++ docs/site/assets/js/main.js | 358 ++++++ docs/site/index.html | 1983 +++++++++++-------------------- docs/site/sitemap.xml | 2 +- 5 files changed, 3018 insertions(+), 1276 deletions(-) create mode 100644 docs/site/assets/css/styles.css create mode 100644 docs/site/assets/js/i18n.js create mode 100644 docs/site/assets/js/main.js diff --git a/docs/site/assets/css/styles.css b/docs/site/assets/css/styles.css new file mode 100644 index 0000000..4e80182 --- /dev/null +++ b/docs/site/assets/css/styles.css @@ -0,0 +1,1108 @@ +/* ========================================================================== + Zero Layer — design system + Dark is the base theme; light is opt-in via [data-theme="light"]. + ========================================================================== */ + +/* -------------------------------------------------------------------------- + 1. Tokens + -------------------------------------------------------------------------- */ + +:root, +:root[data-theme="dark"] { + /* Surfaces */ + --bg: #07070b; + --bg-elev: #0d0d15; + --surface: #101018; + --surface-2: #15151f; + --surface-hover: #1a1a26; + --border: #1e1e2c; + --border-strong: #2b2b3d; + + /* Text */ + --text: #ecebf5; + --text-2: #a3a3bd; + /* Muted text is kept at WCAG AA (>=4.5:1) against both bg and card. */ + --text-3: #8585a3; + + /* Brand + accents */ + --brand: #7c5bf0; + --brand-2: #a78bfa; + --brand-soft: rgba(124, 91, 240, 0.14); + --brand-line: rgba(124, 91, 240, 0.32); + --green: #34d399; + --blue: #60a5fa; + --orange: #fb923c; + --pink: #f472b6; + --teal: #2dd4bf; + --red: #fb7185; + --yellow: #fbbf24; + + /* Effects */ + --nav-bg: rgba(7, 7, 11, 0.72); + --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4); + --shadow: 0 12px 32px rgba(0, 0, 0, 0.45); + --shadow-lg: 0 32px 80px rgba(0, 0, 0, 0.55); + --glow: 0 0 60px rgba(124, 91, 240, 0.18); + --mesh-1: rgba(124, 91, 240, 0.16); + --mesh-2: rgba(45, 212, 191, 0.08); + --mesh-3: rgba(244, 114, 182, 0.07); + --grain-opacity: 0.028; + --code-bg: #0a0a11; +} + +:root[data-theme="light"] { + --bg: #fbfbfd; + --bg-elev: #ffffff; + --surface: #ffffff; + --surface-2: #f5f5fa; + --surface-hover: #f0f0f7; + --border: #e7e7f0; + --border-strong: #d2d2e2; + + --text: #12121a; + --text-2: #55556e; + --text-3: #6b6b84; + + --brand: #6d4bd8; + --brand-2: #6d4bd8; + --brand-soft: rgba(109, 75, 216, 0.10); + --brand-line: rgba(109, 75, 216, 0.26); + --green: #0f9d70; + --blue: #2563eb; + --orange: #ea580c; + --pink: #db2777; + --teal: #0d9488; + --red: #dc2626; + --yellow: #b45309; + + --nav-bg: rgba(251, 251, 253, 0.78); + --shadow-sm: 0 1px 2px rgba(30, 20, 70, 0.06); + --shadow: 0 12px 32px rgba(40, 25, 90, 0.10); + --shadow-lg: 0 32px 70px rgba(40, 25, 90, 0.14); + --glow: 0 0 60px rgba(124, 91, 240, 0.14); + --mesh-1: rgba(124, 91, 240, 0.16); + --mesh-2: rgba(45, 212, 191, 0.10); + --mesh-3: rgba(244, 114, 182, 0.09); + --grain-opacity: 0.02; + --code-bg: #14141d; +} + +:root { + /* Type scale */ + --font-sans: 'Inter var', Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, system-ui, sans-serif; + --font-mono: 'JetBrains Mono', 'SF Mono', 'Cascadia Code', 'Fira Code', ui-monospace, monospace; + + --step--1: clamp(0.82rem, 0.80rem + 0.10vw, 0.88rem); + --step-0: clamp(0.95rem, 0.92rem + 0.15vw, 1.02rem); + --step-1: clamp(1.08rem, 1.02rem + 0.30vw, 1.22rem); + --step-2: clamp(1.30rem, 1.18rem + 0.60vw, 1.65rem); + --step-3: clamp(1.65rem, 1.40rem + 1.20vw, 2.35rem); + --step-4: clamp(2.10rem, 1.65rem + 2.20vw, 3.30rem); + --step-5: clamp(2.70rem, 1.90rem + 3.90vw, 4.75rem); + + /* Spacing rhythm */ + --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; + --sp-5: 24px; --sp-6: 32px; --sp-7: 48px; --sp-8: 64px; + --sp-9: 96px; --sp-10: 128px; + + --r-sm: 8px; --r-md: 12px; --r-lg: 16px; --r-xl: 22px; --r-2xl: 30px; + --maxw: 1180px; + --nav-h: 68px; + --ease: cubic-bezier(0.22, 1, 0.36, 1); +} + +/* -------------------------------------------------------------------------- + 2. Base + -------------------------------------------------------------------------- */ + +*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; } + +html { + scroll-behavior: smooth; + scroll-padding-top: calc(var(--nav-h) + 16px); + -webkit-text-size-adjust: 100%; +} + +body { + font-family: var(--font-sans); + font-size: var(--step-0); + line-height: 1.65; + background: var(--bg); + color: var(--text); + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + overflow-x: hidden; + font-feature-settings: 'cv02', 'cv03', 'cv04', 'ss01'; + transition: background-color 0.35s var(--ease), color 0.35s var(--ease); +} + +h1, h2, h3, h4 { line-height: 1.15; letter-spacing: -0.025em; font-weight: 700; } +h1 { font-size: var(--step-5); font-weight: 800; letter-spacing: -0.04em; } +h2 { font-size: var(--step-4); font-weight: 800; letter-spacing: -0.032em; } +h3 { font-size: var(--step-1); } +p { color: var(--text-2); } +a { color: inherit; } + +code, pre, .mono, kbd { + font-family: var(--font-mono); + font-variant-ligatures: none; +} + +::selection { background: var(--brand); color: #fff; } + +:where(a, button, select, summary, [tabindex]):focus-visible { + outline: 2px solid var(--brand-2); + outline-offset: 3px; + border-radius: var(--r-sm); +} + +/* -------------------------------------------------------------------------- + 3. Layout primitives + -------------------------------------------------------------------------- */ + +.container { + width: 100%; + max-width: var(--maxw); + margin-inline: auto; + padding-inline: var(--sp-5); + position: relative; + z-index: 1; +} +.container-narrow { max-width: 860px; } + +.section { padding-block: clamp(64px, 9vw, 128px); position: relative; } +.section-alt { background: var(--bg-elev); border-block: 1px solid var(--border); } + +.stack-sm > * + * { margin-top: var(--sp-3); } +.center { text-align: center; } + +/* Backdrop: gradient mesh + grain */ +.backdrop { + position: fixed; + inset: 0; + pointer-events: none; + z-index: 0; + overflow: hidden; +} +.backdrop::before { + content: ''; + position: absolute; + top: -30%; left: 50%; + width: 130vw; height: 110vh; + transform: translateX(-50%); + background: + radial-gradient(42% 42% at 28% 22%, var(--mesh-1), transparent 62%), + radial-gradient(38% 38% at 76% 34%, var(--mesh-3), transparent 64%), + radial-gradient(46% 46% at 52% 78%, var(--mesh-2), transparent 66%); + filter: blur(18px); + animation: drift 22s ease-in-out infinite alternate; +} +.backdrop::after { + content: ''; + position: absolute; + inset: -100%; + opacity: var(--grain-opacity); + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E"); +} +@keyframes drift { + 0% { transform: translateX(-50%) translateY(0) scale(1); } + 100% { transform: translateX(-50%) translateY(-4%) scale(1.08); } +} + +/* -------------------------------------------------------------------------- + 4. Navigation + -------------------------------------------------------------------------- */ + +.nav { + position: fixed; + inset: 0 0 auto 0; + z-index: 100; + background: var(--nav-bg); + backdrop-filter: blur(18px) saturate(180%); + -webkit-backdrop-filter: blur(18px) saturate(180%); + border-bottom: 1px solid transparent; + transition: border-color 0.3s, background-color 0.3s; +} +.nav.is-scrolled { border-bottom-color: var(--border); } + +.nav-progress { + position: absolute; + left: 0; bottom: -1px; + height: 2px; + width: 0%; + background: linear-gradient(90deg, var(--brand), var(--pink), var(--orange)); + transition: width 0.1s linear; +} + +.nav-inner { + max-width: var(--maxw); + margin-inline: auto; + padding-inline: var(--sp-5); + height: var(--nav-h); + display: flex; + align-items: center; + justify-content: space-between; + gap: var(--sp-4); +} + +.brand { + display: inline-flex; + align-items: center; + gap: 10px; + font-weight: 800; + font-size: 1.05rem; + letter-spacing: -0.02em; + text-decoration: none; + color: var(--text); + flex-shrink: 0; +} +.brand svg { width: 30px; height: 30px; border-radius: 9px; display: block; } +.brand-sub { + font-family: var(--font-mono); + font-size: 0.68rem; + font-weight: 600; + color: var(--text-3); + border: 1px solid var(--border); + border-radius: 5px; + padding: 1px 5px; + margin-left: 2px; +} + +.nav-links { display: flex; align-items: center; gap: var(--sp-5); } +.nav-links a { + font-size: 0.9rem; + font-weight: 500; + color: var(--text-2); + text-decoration: none; + transition: color 0.18s; + white-space: nowrap; +} +.nav-links a:hover { color: var(--text); } + +.nav-actions { display: flex; align-items: center; gap: var(--sp-2); flex-shrink: 0; } + +.icon-btn { + display: inline-flex; + align-items: center; + justify-content: center; + width: 40px; height: 40px; + border-radius: var(--r-md); + background: var(--surface); + border: 1px solid var(--border); + color: var(--text-2); + cursor: pointer; + transition: all 0.18s; +} +.icon-btn:hover { color: var(--text); background: var(--surface-hover); border-color: var(--border-strong); } + +.lang { position: relative; display: inline-flex; align-items: center; } +.lang .globe { position: absolute; left: 11px; pointer-events: none; color: var(--text-3); } +.lang::after { + content: ''; + position: absolute; right: 12px; + width: 6px; height: 6px; + border-right: 2px solid var(--text-3); + border-bottom: 2px solid var(--text-3); + transform: rotate(45deg) translateY(-2px); + pointer-events: none; +} +.lang select { + appearance: none; -webkit-appearance: none; + height: 40px; + padding: 0 30px 0 32px; + border-radius: var(--r-md); + background: var(--surface); + border: 1px solid var(--border); + color: var(--text); + font: inherit; font-size: 0.85rem; font-weight: 600; + cursor: pointer; + transition: all 0.18s; +} +.lang select:hover { background: var(--surface-hover); border-color: var(--border-strong); } + +.theme-toggle .moon { display: none; } +:root[data-theme="light"] .theme-toggle .sun { display: none; } +:root[data-theme="light"] .theme-toggle .moon { display: block; } + +.menu-btn { display: none; } + +/* -------------------------------------------------------------------------- + 5. Buttons & pills + -------------------------------------------------------------------------- */ + +.btn { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 9px; + padding: 13px 24px; + border-radius: var(--r-md); + font-size: 0.94rem; + font-weight: 650; + text-decoration: none; + border: 1px solid transparent; + cursor: pointer; + white-space: nowrap; + transition: transform 0.18s var(--ease), box-shadow 0.2s, background-color 0.2s, border-color 0.2s; +} +.btn:active { transform: translateY(0) scale(0.99); } + +.btn-primary { + background: linear-gradient(135deg, var(--brand), #6947e0); + color: #fff; + box-shadow: 0 6px 22px rgba(124, 91, 240, 0.32); +} +.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 12px 34px rgba(124, 91, 240, 0.45); } + +.btn-secondary { + background: var(--surface); + color: var(--text); + border-color: var(--border); +} +.btn-secondary:hover { background: var(--surface-hover); border-color: var(--border-strong); transform: translateY(-2px); } + +.btn-ghost { background: transparent; color: var(--text-2); border-color: var(--border); } +.btn-ghost:hover { color: var(--text); border-color: var(--border-strong); } + +.btn-sm { padding: 9px 16px; font-size: 0.86rem; } +.btn-lg { padding: 15px 30px; font-size: 1rem; } + +.btn-row { display: flex; flex-wrap: wrap; gap: var(--sp-3); } +.btn-row.center { justify-content: center; } + +.pill { + display: inline-flex; + align-items: center; + gap: 8px; + padding: 6px 15px; + border-radius: 100px; + background: var(--brand-soft); + border: 1px solid var(--brand-line); + font-size: 0.82rem; + font-weight: 650; + color: var(--brand-2); + letter-spacing: -0.01em; +} +.pill .dot { + width: 7px; height: 7px; border-radius: 50%; + background: var(--green); + box-shadow: 0 0 0 3px rgba(52, 211, 153, 0.18); + animation: blink 2.4s ease-in-out infinite; +} +@keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } } + +/* -------------------------------------------------------------------------- + 6. Section headers + -------------------------------------------------------------------------- */ + +.sec-head { max-width: 720px; margin-bottom: var(--sp-8); } +.sec-head.center { margin-inline: auto; text-align: center; } + +.eyebrow { + display: inline-flex; + align-items: center; + gap: 8px; + font-family: var(--font-mono); + font-size: 0.76rem; + font-weight: 600; + letter-spacing: 0.12em; + text-transform: uppercase; + color: var(--brand-2); + margin-bottom: var(--sp-3); +} +.eyebrow::before { + content: ''; + width: 18px; height: 1px; + background: currentColor; + opacity: 0.6; +} +.sec-head.center .eyebrow::before { display: none; } + +.sec-title { margin-bottom: var(--sp-4); } +.sec-lede { font-size: var(--step-1); color: var(--text-2); line-height: 1.6; } + +.gradient-text { + background: linear-gradient(115deg, var(--brand-2) 8%, var(--pink) 52%, var(--orange) 92%); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; +} + +/* -------------------------------------------------------------------------- + 7. Hero + -------------------------------------------------------------------------- */ + +.hero { + padding-top: calc(var(--nav-h) + clamp(56px, 8vw, 104px)); + padding-bottom: clamp(56px, 8vw, 96px); + text-align: center; +} +.hero h1 { margin: var(--sp-5) 0 var(--sp-5); } +.hero-lede { + font-size: var(--step-1); + max-width: 660px; + margin: 0 auto var(--sp-6); + color: var(--text-2); +} + +/* Inline install command */ +.install-line { + display: inline-flex; + align-items: center; + gap: var(--sp-3); + max-width: 100%; + margin-top: var(--sp-6); + padding: 10px 10px 10px 18px; + border-radius: 100px; + background: var(--surface); + border: 1px solid var(--border); + font-family: var(--font-mono); + font-size: 0.86rem; + box-shadow: var(--shadow-sm); +} +.install-line code { color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } +.install-line .tick { color: var(--brand-2); } + +.copy-btn { + display: inline-flex; + align-items: center; + gap: 6px; + flex-shrink: 0; + padding: 7px 13px; + border-radius: 100px; + background: var(--surface-2); + border: 1px solid var(--border); + color: var(--text-2); + font-family: var(--font-sans); + font-size: 0.78rem; + font-weight: 600; + cursor: pointer; + transition: all 0.18s; +} +.copy-btn:hover { color: var(--text); border-color: var(--border-strong); background: var(--surface-hover); } +.copy-btn.is-copied { color: var(--green); border-color: var(--green); } + +/* Stats strip */ +.stats { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: var(--sp-4); + margin-top: var(--sp-8); + padding: var(--sp-5) var(--sp-4); + border-radius: var(--r-xl); + background: var(--surface); + border: 1px solid var(--border); +} +.stat { text-align: center; } +.stat-num { + display: block; + font-size: var(--step-3); + font-weight: 800; + letter-spacing: -0.03em; + line-height: 1.1; + font-variant-numeric: tabular-nums; +} +.stat-label { + display: block; + font-size: 0.78rem; + color: var(--text-3); + margin-top: 4px; + letter-spacing: 0.01em; +} + +/* -------------------------------------------------------------------------- + 8. Terminal + -------------------------------------------------------------------------- */ + +.terminal { + max-width: 760px; + margin: var(--sp-8) auto 0; + border-radius: var(--r-xl); + background: var(--code-bg); + border: 1px solid #1e1e2c; + overflow: hidden; + box-shadow: var(--shadow-lg), var(--glow); + text-align: left; +} +.terminal-bar { + display: flex; + align-items: center; + gap: 7px; + padding: 13px 16px; + background: rgba(255, 255, 255, 0.028); + border-bottom: 1px solid #1e1e2c; +} +.tdot { width: 11px; height: 11px; border-radius: 50%; } +.tdot.r { background: #ff5f57; } .tdot.y { background: #febc2e; } .tdot.g { background: #28c840; } +.terminal-title { + margin-left: auto; + font-family: var(--font-mono); + font-size: 0.72rem; + color: #6e6e88; +} +.terminal-body { + padding: 20px 22px 24px; + font-family: var(--font-mono); + font-size: 0.845rem; + line-height: 1.85; + color: #ecebf5; + overflow-x: auto; + min-height: 260px; +} +.terminal-body .prompt { color: var(--brand-2); } +.terminal-body .flag { color: #60a5fa; } +.terminal-body .comment { color: #6e6e88; } +.terminal-body .ok { color: #34d399; } +.terminal-body .warn { color: #fbbf24; } +.terminal-body .dim { color: #8b8ba6; } +.terminal-body .line { white-space: pre; } +.cursor { + display: inline-block; + width: 8px; height: 1.05em; + background: var(--brand-2); + vertical-align: text-bottom; + animation: caret 1.05s step-end infinite; +} +@keyframes caret { 0%, 100% { opacity: 1; } 50% { opacity: 0; } } + +/* -------------------------------------------------------------------------- + 9. Cards & grids + -------------------------------------------------------------------------- */ + +.card { + padding: var(--sp-6); + border-radius: var(--r-lg); + background: var(--surface); + border: 1px solid var(--border); + transition: transform 0.22s var(--ease), border-color 0.22s, background-color 0.22s, box-shadow 0.22s; +} +.card:hover { + background: var(--surface-hover); + border-color: var(--border-strong); + transform: translateY(-3px); + box-shadow: var(--shadow); +} +.card h3 { margin-bottom: var(--sp-2); font-size: var(--step-1); } +.card p { font-size: 0.92rem; line-height: 1.65; } + +.ico { + display: inline-flex; + align-items: center; + justify-content: center; + width: 46px; height: 46px; + border-radius: var(--r-md); + margin-bottom: var(--sp-4); + font-size: 1.25rem; +} + +.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-4); } +.grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--sp-4); } + +/* Bento */ +.bento { + display: grid; + grid-template-columns: repeat(6, 1fr); + gap: var(--sp-4); +} +.bento > .card { grid-column: span 2; } +.bento > .card.span-3 { grid-column: span 3; } +.bento > .card.span-4 { grid-column: span 4; } +.bento > .card.span-6 { grid-column: span 6; } + +.card-feature { + position: relative; + overflow: hidden; +} +.card-feature::after { + content: ''; + position: absolute; + inset: 0; + background: radial-gradient(60% 60% at 80% 0%, var(--brand-soft), transparent 70%); + opacity: 0; + transition: opacity 0.3s; + pointer-events: none; +} +.card-feature:hover::after { opacity: 1; } + +.tag-list { display: flex; flex-wrap: wrap; gap: 7px; margin-top: var(--sp-4); } +.tag { + font-family: var(--font-mono); + font-size: 0.73rem; + padding: 4px 9px; + border-radius: 6px; + background: var(--surface-2); + border: 1px solid var(--border); + color: var(--text-2); +} + +/* -------------------------------------------------------------------------- + 10. Problem cards (contrast section) + -------------------------------------------------------------------------- */ + +.pain { border-left: 2px solid var(--red); } +.pain .ico { background: rgba(251, 113, 133, 0.12); color: var(--red); } +.gain { border-left: 2px solid var(--green); } + +.split { + display: grid; + grid-template-columns: 1fr 1fr; + gap: var(--sp-7); + align-items: center; +} + +/* -------------------------------------------------------------------------- + 11. Pipeline (how it works) + -------------------------------------------------------------------------- */ + +.pipeline { + display: grid; + gap: var(--sp-4); + counter-reset: pstep; + position: relative; +} +.pstep { + position: relative; + display: grid; + grid-template-columns: 56px 1fr; + gap: var(--sp-5); + align-items: start; + padding: var(--sp-5) var(--sp-5) var(--sp-5) 0; + counter-increment: pstep; +} +.pstep::before { + content: counter(pstep, decimal-leading-zero); + display: flex; + align-items: center; + justify-content: center; + width: 56px; height: 56px; + border-radius: var(--r-md); + background: var(--surface); + border: 1px solid var(--border); + font-family: var(--font-mono); + font-size: 0.95rem; + font-weight: 700; + color: var(--brand-2); + z-index: 1; +} +.pstep::after { + content: ''; + position: absolute; + left: 28px; top: 76px; bottom: -16px; + width: 1px; + background: linear-gradient(var(--border-strong), transparent); +} +.pstep:last-child::after { display: none; } +.pstep h3 { font-size: var(--step-1); margin-bottom: 6px; } +.pstep p { font-size: 0.92rem; } +.pstep-meta { + display: inline-block; + margin-top: 10px; + font-family: var(--font-mono); + font-size: 0.74rem; + color: var(--text-3); + padding: 3px 9px; + border-radius: 6px; + background: var(--surface-2); + border: 1px solid var(--border); +} + +/* -------------------------------------------------------------------------- + 12. Sources + -------------------------------------------------------------------------- */ + +.source-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); + gap: var(--sp-3); +} +.source { + display: flex; + align-items: center; + gap: var(--sp-3); + padding: 14px 16px; + border-radius: var(--r-md); + background: var(--surface); + border: 1px solid var(--border); + transition: all 0.2s var(--ease); +} +.source:hover { border-color: var(--border-strong); background: var(--surface-hover); transform: translateY(-2px); } +.source-dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; } +.source-name { font-weight: 650; font-size: 0.92rem; } +.source-desc { display: block; font-size: 0.76rem; color: var(--text-3); font-weight: 400; } + +/* -------------------------------------------------------------------------- + 13. Tabs (command explorer) + -------------------------------------------------------------------------- */ + +.tabs { + display: flex; + flex-wrap: wrap; + gap: 6px; + margin-bottom: var(--sp-5); + padding: 6px; + border-radius: var(--r-md); + background: var(--surface); + border: 1px solid var(--border); +} +.tab { + flex: 1 1 auto; + padding: 9px 16px; + border: none; + border-radius: var(--r-sm); + background: transparent; + color: var(--text-2); + font: inherit; + font-size: 0.87rem; + font-weight: 600; + cursor: pointer; + white-space: nowrap; + transition: all 0.18s; +} +.tab:hover { color: var(--text); background: var(--surface-hover); } +.tab[aria-selected="true"] { + background: var(--brand); + color: #fff; + box-shadow: 0 4px 14px rgba(124, 91, 240, 0.3); +} + +.tabpanel[hidden] { display: none; } + +.codeblock { + position: relative; + border-radius: var(--r-lg); + background: var(--code-bg); + border: 1px solid #1e1e2c; + overflow: hidden; +} +.codeblock pre { + margin: 0; + padding: var(--sp-5) var(--sp-5); + font-family: var(--font-mono); + font-size: 0.845rem; + line-height: 1.9; + color: #ecebf5; + overflow-x: auto; +} +.codeblock .c-cmd { color: #ecebf5; } +.codeblock .c-flag { color: #60a5fa; } +.codeblock .c-note { color: #6e6e88; } +.codeblock .c-prompt { color: var(--brand-2); } +.codeblock .copy-btn { + position: absolute; + top: 12px; right: 12px; + background: rgba(255, 255, 255, 0.05); + border-color: rgba(255, 255, 255, 0.09); + color: #a3a3bd; +} +.codeblock .copy-btn:hover { background: rgba(255, 255, 255, 0.1); color: #fff; } + +/* -------------------------------------------------------------------------- + 14. Comparison table + -------------------------------------------------------------------------- */ + +.table-wrap { + overflow-x: auto; + border-radius: var(--r-lg); + border: 1px solid var(--border); + background: var(--surface); + -webkit-overflow-scrolling: touch; +} +table.compare { + width: 100%; + min-width: 640px; + border-collapse: collapse; + font-size: 0.9rem; +} +table.compare th, table.compare td { + padding: 14px 18px; + text-align: left; + border-bottom: 1px solid var(--border); +} +table.compare thead th { + font-size: 0.78rem; + text-transform: uppercase; + letter-spacing: 0.07em; + color: var(--text-3); + font-weight: 650; + background: var(--surface-2); + white-space: nowrap; +} +table.compare tbody th { font-weight: 600; color: var(--text); white-space: nowrap; } +table.compare td { color: var(--text-2); } +table.compare tbody tr:last-child th, +table.compare tbody tr:last-child td { border-bottom: none; } +table.compare .col-zl { background: var(--brand-soft); color: var(--text); font-weight: 600; } +table.compare thead .col-zl { background: rgba(124, 91, 240, 0.2); color: var(--brand-2); } +.yes { color: var(--green); font-weight: 700; } +.no { color: var(--text-3); } + +/* -------------------------------------------------------------------------- + 15. Steps (get started) + -------------------------------------------------------------------------- */ + +.start-step { display: grid; gap: var(--sp-3); } +.start-step h3 { + display: flex; align-items: center; gap: 10px; + font-size: var(--step-1); +} +.start-step h3 .num { + display: inline-flex; align-items: center; justify-content: center; + width: 28px; height: 28px; flex-shrink: 0; + border-radius: 8px; + background: var(--brand-soft); + border: 1px solid var(--brand-line); + color: var(--brand-2); + font-family: var(--font-mono); + font-size: 0.82rem; + font-weight: 700; +} + +/* -------------------------------------------------------------------------- + 16. FAQ + -------------------------------------------------------------------------- */ + +.faq { display: grid; gap: var(--sp-3); } +.faq details { + border-radius: var(--r-md); + background: var(--surface); + border: 1px solid var(--border); + overflow: hidden; + transition: border-color 0.2s, background-color 0.2s; +} +.faq details[open] { border-color: var(--border-strong); background: var(--surface-2); } +.faq summary { + display: flex; + align-items: center; + justify-content: space-between; + gap: var(--sp-4); + padding: 18px 20px; + font-weight: 650; + font-size: 0.98rem; + cursor: pointer; + list-style: none; +} +.faq summary::-webkit-details-marker { display: none; } +.faq summary::after { + content: ''; + width: 9px; height: 9px; flex-shrink: 0; + border-right: 2px solid var(--text-3); + border-bottom: 2px solid var(--text-3); + transform: rotate(45deg) translateY(-2px); + transition: transform 0.25s var(--ease); +} +.faq details[open] summary::after { transform: rotate(-135deg) translateY(-2px); } +.faq .faq-body { padding: 0 20px 20px; font-size: 0.92rem; color: var(--text-2); line-height: 1.7; } +.faq .faq-body code { + font-size: 0.85em; + padding: 2px 6px; + border-radius: 5px; + background: var(--surface-hover); + border: 1px solid var(--border); +} + +/* -------------------------------------------------------------------------- + 17. CTA + -------------------------------------------------------------------------- */ + +.cta { + position: relative; + overflow: hidden; + border-radius: var(--r-2xl); + padding: clamp(40px, 6vw, 76px) clamp(24px, 5vw, 60px); + text-align: center; + background: + radial-gradient(70% 130% at 50% 0%, rgba(124, 91, 240, 0.16), transparent 70%), + var(--surface); + border: 1px solid var(--brand-line); + box-shadow: var(--shadow); +} +.cta h2 { margin-bottom: var(--sp-4); } +.cta p { font-size: var(--step-1); max-width: 560px; margin: 0 auto var(--sp-6); } + +/* -------------------------------------------------------------------------- + 18. Footer + -------------------------------------------------------------------------- */ + +.footer { + border-top: 1px solid var(--border); + background: var(--bg-elev); + padding-block: var(--sp-8) var(--sp-6); +} +.footer-grid { + display: grid; + grid-template-columns: 1.6fr repeat(3, 1fr); + gap: var(--sp-7); + padding-bottom: var(--sp-7); + border-bottom: 1px solid var(--border); +} +.footer-about p { + font-size: 0.88rem; + max-width: 320px; + margin-top: var(--sp-3); +} +.footer-col h4 { + font-size: 0.78rem; + text-transform: uppercase; + letter-spacing: 0.09em; + color: var(--text-3); + margin-bottom: var(--sp-4); + font-weight: 650; +} +.footer-col ul { list-style: none; display: grid; gap: 10px; } +.footer-col a { + font-size: 0.88rem; + color: var(--text-2); + text-decoration: none; + transition: color 0.18s; +} +.footer-col a:hover { color: var(--text); } + +.socials { display: flex; gap: 10px; margin-top: var(--sp-5); } +.socials a { + display: inline-flex; + align-items: center; + justify-content: center; + width: 40px; height: 40px; + border-radius: var(--r-md); + background: var(--surface); + border: 1px solid var(--border); + color: var(--text-2); + transition: all 0.2s var(--ease); +} +.socials a:hover { color: var(--text); border-color: var(--border-strong); background: var(--surface-hover); transform: translateY(-2px); } + +.footer-bottom { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + gap: var(--sp-3); + padding-top: var(--sp-5); + font-size: 0.83rem; + color: var(--text-3); +} +.footer-bottom a { color: var(--brand-2); text-decoration: none; } +.footer-bottom a:hover { text-decoration: underline; } + +/* -------------------------------------------------------------------------- + 19. Reveal animation + -------------------------------------------------------------------------- */ + +.reveal { + opacity: 0; + transform: translateY(22px); + transition: opacity 0.7s var(--ease), transform 0.7s var(--ease); +} +.reveal.is-visible { opacity: 1; transform: none; } +.reveal-stagger > * { + opacity: 0; + transform: translateY(18px); + transition: opacity 0.6s var(--ease), transform 0.6s var(--ease); +} +.reveal-stagger.is-visible > * { opacity: 1; transform: none; } +.reveal-stagger.is-visible > *:nth-child(1) { transition-delay: 0.04s; } +.reveal-stagger.is-visible > *:nth-child(2) { transition-delay: 0.10s; } +.reveal-stagger.is-visible > *:nth-child(3) { transition-delay: 0.16s; } +.reveal-stagger.is-visible > *:nth-child(4) { transition-delay: 0.22s; } +.reveal-stagger.is-visible > *:nth-child(5) { transition-delay: 0.28s; } +.reveal-stagger.is-visible > *:nth-child(6) { transition-delay: 0.34s; } + +.skip-link { + position: absolute; + left: -9999px; + top: 8px; + z-index: 200; + padding: 10px 18px; + border-radius: var(--r-md); + background: var(--brand); + color: #fff; + font-weight: 600; + text-decoration: none; +} +.skip-link:focus { left: 16px; } + +.visually-hidden { + position: absolute !important; + width: 1px; height: 1px; + overflow: hidden; + clip: rect(0 0 0 0); + white-space: nowrap; +} + +/* -------------------------------------------------------------------------- + 20. Responsive + -------------------------------------------------------------------------- */ + +@media (max-width: 1000px) { + .bento > .card, + .bento > .card.span-3, + .bento > .card.span-4 { grid-column: span 3; } + .footer-grid { grid-template-columns: 1fr 1fr; gap: var(--sp-6); } +} + +@media (max-width: 900px) { + .menu-btn { display: inline-flex; } + .nav-links { + position: absolute; + top: var(--nav-h); left: 0; right: 0; + flex-direction: column; + align-items: stretch; + gap: 2px; + padding: var(--sp-3) var(--sp-5) var(--sp-5); + background: var(--nav-bg); + backdrop-filter: blur(18px) saturate(180%); + -webkit-backdrop-filter: blur(18px) saturate(180%); + border-bottom: 1px solid var(--border); + opacity: 0; + transform: translateY(-10px); + pointer-events: none; + transition: opacity 0.22s var(--ease), transform 0.22s var(--ease); + } + .nav-links.is-open { opacity: 1; transform: none; pointer-events: auto; } + .nav-links a { padding: 12px 6px; font-size: 1rem; border-radius: var(--r-sm); } + .nav-links a:hover { background: var(--surface-hover); } + .split { grid-template-columns: 1fr; gap: var(--sp-5); } + .grid-3 { grid-template-columns: 1fr 1fr; } +} + +@media (max-width: 720px) { + .grid-3, .grid-2 { grid-template-columns: 1fr; } + .bento > .card, + .bento > .card.span-3, + .bento > .card.span-4, + .bento > .card.span-6 { grid-column: span 6; } + .stats { grid-template-columns: 1fr 1fr; gap: var(--sp-5) var(--sp-3); } + .footer-grid { grid-template-columns: 1fr; gap: var(--sp-6); } + .pstep { grid-template-columns: 44px 1fr; gap: var(--sp-4); padding-block: var(--sp-4); } + .pstep::before { width: 44px; height: 44px; font-size: 0.82rem; } + .pstep::after { left: 22px; top: 62px; } + .lang select { width: 56px; padding-left: 30px; padding-right: 24px; font-size: 0; } + .lang select option { font-size: 1rem; } + .terminal-body { font-size: 0.78rem; padding: 16px 16px 20px; min-height: 230px; } + .install-line { font-size: 0.78rem; padding-left: 14px; } + .tab { flex: 1 1 100%; } +} + +@media (max-width: 420px) { + .container, .nav-inner { padding-inline: var(--sp-4); } + .brand-sub { display: none; } +} + +/* -------------------------------------------------------------------------- + 21. Motion / print + -------------------------------------------------------------------------- */ + +@media (prefers-reduced-motion: reduce) { + *, *::before, *::after { + animation-duration: 0.001ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.001ms !important; + } + html { scroll-behavior: auto; } + .reveal, .reveal-stagger > * { opacity: 1; transform: none; } +} + +@media print { + .nav, .backdrop, .cta, .socials { display: none; } + body { background: #fff; color: #000; } +} diff --git a/docs/site/assets/js/i18n.js b/docs/site/assets/js/i18n.js new file mode 100644 index 0000000..a156a1e --- /dev/null +++ b/docs/site/assets/js/i18n.js @@ -0,0 +1,843 @@ +/* ========================================================================== + Zero Layer — translations + English is the default and the fallback for any missing key. + Product names, CLI flags and distro names stay untranslated on purpose. + ========================================================================== */ + +window.ZL_I18N = { + + /* ---------------------------------------------------------------- EN */ + en: { + meta_desc: "Install packages from any source on any Linux distro. Zero Layer translates binaries natively at install time — no containers, no VMs, zero runtime overhead.", + + nav_why: "Why", nav_how: "How it works", nav_sources: "Sources", + nav_commands: "Commands", nav_arch: "Architecture", nav_faq: "FAQ", + nav_menu: "Menu", nav_theme: "Switch theme", nav_lang: "Language", + skip: "Skip to content", + + hero_badge: "v0.2 — Open source, MIT licensed", + hero_t1: "One command.", + hero_t2: "Any package. Any distro.", + hero_lede: "Zero Layer is a universal Linux package manager. It installs software from 13 different ecosystems onto any distribution by translating binaries at install time — not at run time.", + hero_cta1: "Get started", + hero_cta2: "Read the source", + hero_install_note: "One binary. No runtime, no daemon, no dependencies.", + + stat_sources: "package sources", + stat_overhead: "runtime overhead", + stat_tests: "tests, CI green", + stat_cdeps: "C dependencies", + + why_eyebrow: "The problem", + why_title: "Linux packaging is fragmented by design", + why_lede: "Every distribution ships its own format, its own repository and its own idea of where files belong. The software you want is often packaged — just not for your system.", + p1_t: "The package exists, but not for you", + p1_d: "A tool is in the AUR, or only as a .deb, or only as a GitHub release. Your distro packaged it two years ago, or never. You end up compiling from source or going without.", + p2_t: "The workarounds cost you performance", + p2_d: "Containers, virtual machines and compatibility layers all solve this by adding a layer. You pay for it forever: startup latency, memory, disk, and a runtime that must keep running.", + p3_t: "Manual installs rot silently", + p3_d: "Dropping a tarball into /opt works until a library moves. Nothing tracks the files, nothing knows the dependencies, and nothing can cleanly undo it.", + + what_eyebrow: "The idea", + what_title: "Translate once, at install time", + what_lede: "A Linux binary is not tied to a distribution — it is tied to a handful of concrete facts: which dynamic linker loads it, and where its shared libraries live. Both are recorded inside the ELF file, and both can be rewritten.", + what_p1: "Zero Layer reads those fields with goblin, then rewrites them with elb so they point at your system's real linker and library paths. It does this once, while installing.", + what_p2: "After that the binary is simply a native binary on your machine. There is no shim, no wrapper script, no sandbox and no supervising process. That is where the name comes from: the layer is zero.", + what_b1: "No container runtime to install or keep running", + what_b2: "No performance penalty — it is the same machine code", + what_b3: "Files land in normal directories you can inspect", + what_b4: "Everything is tracked, and every install can be rolled back", + + phil_eyebrow: "Philosophy", + phil_title: "Six principles behind every decision", + phil_lede: "Zero Layer is opinionated. These are the rules the codebase is held to.", + ph1_t: "Zero overhead after install", + ph1_d: "All translation work happens once, during installation. Nothing sits between your program and the kernel afterwards.", + ph2_t: "Detect, never assume", + ph2_d: "Architecture, dynamic linker, libc, library directories and filesystem layout are all probed from the running system instead of hardcoded.", + ph3_t: "Atomic or nothing", + ph3_d: "Every install runs inside a transaction that records what it touched. A failure anywhere unwinds the whole operation.", + ph4_t: "One binary, no C", + ph4_d: "redb instead of SQLite, elb instead of patchelf, rustls instead of OpenSSL. Pure Rust means it builds and runs anywhere without a toolchain hunt.", + ph5_t: "The user picks the source", + ph5_d: "When a package exists in several ecosystems, Zero Layer shows all of them and lets you choose. It never silently decides for you.", + ph6_t: "Reversible by default", + ph6_d: "History, rollback, orphan detection and dry-run are core features, not afterthoughts. You can always see what happened and undo it.", + + how_eyebrow: "How it works", + how_title: "What happens when you type install", + how_lede: "Eight stages run between your command and a working binary. Each one is observable with -v, and any failure rolls the whole thing back.", + h1_t: "Resolve", h1_d: "Finds the package and walks its dependency tree recursively, detecting cycles. If a dependency is missing from the primary source, every other enabled source is queried and you choose.", h1_m: "cross-source resolution", + h2_t: "Check conflicts", h2_d: "Five classes are checked before anything is written: file ownership, binary names, library sonames, declared conflicts and version constraints.", h2_m: "5 conflict types", + h3_t: "Download", h3_d: "Packages are fetched straight from their native repositories over four parallel threads, with progress bars and automatic retry with backoff.", h3_m: "4 threads · retry", + h4_t: "Verify", h4_d: "SHA256 checksums are enforced and GPG signatures are checked when the source provides them. An unverifiable signature is reported differently from a bad one.", h4_m: "SHA256 + GPG", + h5_t: "Extract", h5_d: "The archive format is detected and unpacked — deb, rpm, tar, zst, xz, nar, squashfs, zip or AppImage — then normalised to a standard FHS layout.", h5_m: "9 archive formats", + h6_t: "Patch", h6_d: "Every ELF binary is analysed, then its interpreter and RUNPATH are rewritten to match your system. Multi-binary packages are patched in parallel; static binaries are correctly left alone.", h6_m: "goblin + elb", + h7_t: "Install", h7_d: "Files are placed atomically inside a transaction that records every file, directory, symlink and database row it creates. Any error unwinds all of it.", h7_m: "atomic · rollback", + h8_t: "Track", h8_d: "Files, dependencies, ownership and the operation itself are written to an embedded database, which is what makes why, size, doctor and rollback possible later.", h8_m: "redb + graph", + + feat_eyebrow: "Capabilities", + feat_title: "A complete package manager, not a demo", + feat_lede: "Everything you would expect from your distro's tooling, plus the things it never had.", + f1_t: "Native binary translation", + f1_d: "ELF binaries are analysed with goblin and patched with elb at install time. The dynamic linker and RUNPATH are rewritten to match your system, so packages run at full native speed afterwards.", + f2_t: "13 sources in parallel", + f2_d: "Every enabled source is queried simultaneously, results are scored by relevance, and AUR binary variants are discovered automatically.", + f3_t: "Atomic transactions", + f3_d: "An install either completes or leaves no trace. No half-written state, ever.", + f4_t: "Diagnostics built in", + f4_d: "doctor, audit, why, size, diff and history answer the questions package managers usually leave you guessing about.", + f5_t: "Multi-version & environments", + f5_d: "Install versions side by side and switch between them, or spin up an ephemeral environment that disappears when you exit the shell.", + f6_t: "Security aware", + f6_d: "Checksums and signatures on the way in, CVE lookups against OSV.dev on the way out, plus pinning to freeze anything you do not want moving.", + + src_eyebrow: "Sources", + src_title: "Thirteen ecosystems, one interface", + src_lede: "Each source is a plugin implementing the same trait. Enable the ones you want per machine, or filter per command with --from.", + src_note: "Source availability depends on the upstream being reachable. The repository tracks the live status of every plugin.", + src_status_link: "See live plugin status", + + cmd_eyebrow: "Commands", + cmd_title: "The interface, end to end", + cmd_lede: "One binary, twenty-five commands, shell completions for bash, zsh and fish.", + cmd_tab1: "Install", cmd_tab2: "Search", cmd_tab3: "Diagnostics", + cmd_tab4: "History", cmd_tab5: "Environments", + copy: "Copy", copied: "Copied", + + arch_eyebrow: "Under the hood", + arch_title: "Built to be boring in the right places", + arch_lede: "Predictable layout on disk, pure-Rust dependencies, and a test suite that runs on every push.", + arch_layout_t: "Where things land", + arch_layout_d: "Everything lives under one directory you own. Add bin to your PATH and nothing else on the system is touched.", + arch_stack_t: "The stack", + arch_choices_t: "Design constraints", + ac1: "Single binary with zero C dependencies", + ac2: "RUNPATH over RPATH, so LD_LIBRARY_PATH still works", + ac3: "Threads instead of an async runtime", + ac4: "Everything auto-detected from the running system", + ac5: "Rollback is a first-class path, not an error case", + ac6: "Zero clippy warnings, formatted, CI-gated", + + cmp_eyebrow: "Comparison", + cmp_title: "How it differs from the alternatives", + cmp_lede: "Containers and universal package formats solve the same problem by isolating software. Zero Layer solves it by adapting software.", + cmp_c1: "Approach", cmp_c2: "Runtime cost", cmp_c3: "Disk cost", cmp_c4: "Needs a daemon", + cmp_r1: "Zero Layer", cmp_r1a: "Patch binaries at install", cmp_r1b: "None", cmp_r1c: "Shared libraries, deduplicated", cmp_r1d: "No", + cmp_r2a: "Full OS image per app", cmp_r2b: "Process + namespace overhead", cmp_r2c: "Image layers per app", cmp_r2d: "Yes", + cmp_r3a: "Bundled runtimes", cmp_r3b: "Sandbox + portal indirection", cmp_r3c: "Runtime per app family", cmp_r3d: "Yes", + cmp_r4a: "Squashfs + confinement", cmp_r4b: "Mount + confinement layer", cmp_r4c: "Compressed image per app", cmp_r4d: "Yes", + cmp_r5: "Manual tarball", cmp_r5a: "Unpack and hope", cmp_r5b: "None", cmp_r5c: "Whatever you copied", cmp_r5d: "No", + cmp_foot: "Manual installs match Zero Layer on overhead — and lose on everything else: nothing is tracked, nothing resolves dependencies, and nothing can undo it.", + + start_eyebrow: "Get started", + start_title: "Running in under a minute", + start_lede: "One download, one line in your shell profile. No package manager needed to install the package manager.", + s1_t: "Install the binary", + s1_d: "Grab the latest release. Use the second form if you would rather not use sudo.", + s2_t: "Put it on your PATH", + s2_d: "Zero Layer symlinks the executables it installs into its own bin directory.", + s3_t: "Install something", + s3_d: "Leave off --from and Zero Layer will search every enabled source and let you pick.", + start_alt: "Prefer to build it yourself? Requires Rust 1.85 or newer.", + + faq_eyebrow: "FAQ", + faq_title: "Reasonable questions", + q1: "Does this replace my distro's package manager?", + a1: "No, and it does not try to. Zero Layer installs into your home directory and never touches system paths, so pacman, apt or dnf keep managing the base system exactly as before. Use it for the software your distro does not package.", + q2: "Do I need root?", + a2: "No. The default installation lives entirely under ~/.local/share/zl. Root is only relevant if you choose to put the zl binary itself in /usr/local/bin, and even that is optional.", + q3: "Is it really zero overhead?", + a3: "Yes, because after installation there is nothing left running. The patched binary is ordinary machine code executed directly by the kernel — no sandbox, no supervisor, no translation at run time. The work happens once, while installing.", + q4: "What if a package needs a library I do not have?", + a4: "Dependencies are resolved recursively before anything is downloaded, and if one is missing from the primary source, every other enabled source is searched. After install, a post-check warns about any shared library it still cannot locate.", + q5: "What happens when an install fails halfway?", + a5: "Nothing is left behind. Every install runs inside a transaction that records the files, directories, symlinks and database entries it created, and any failure unwinds all of them. You can also preview any operation with --dry-run.", + q6: "Which distributions does it support?", + a6: "Any of them, in principle. Rather than keeping a list, Zero Layer detects the architecture, dynamic linker, libc, library directories and filesystem layout at runtime — including merged-usr, NixOS, Guix, GoboLinux and Termux layouts.", + q7: "Is it production ready?", + a7: "It is early software under active development, and honest about it: the repository tracks exactly which source plugins are verified against their live upstreams and which are still being repaired. The core install path is covered by 349 tests that gate every commit.", + q8: "How do I get rid of it?", + a8: "Delete the directory. Everything Zero Layer installs — packages, database, cache, symlinks — lives under one folder, so removing it removes every trace.", + + cta_title: "Install anything, on anything", + cta_p: "Free and open source under the MIT licence. No account, no telemetry, no daemon.", + cta_b1: "Download latest release", + cta_b2: "Star on GitHub", + + foot_about: "A universal Linux package manager with native binary translation. Install from any source, on any distribution, with zero runtime overhead.", + foot_c1: "Project", foot_c2: "Resources", foot_c3: "Community", + foot_readme: "Documentation", foot_releases: "Releases", foot_status: "Plugin status", foot_license_l: "Licence", + foot_issues: "Report an issue", foot_discussions: "Discussions", foot_contribute: "Contribute", foot_source: "Source code", + foot_builtby: "Built by", foot_license: "Released under the MIT Licence.", + foot_madewith: "Written in Rust." + }, + + /* ---------------------------------------------------------------- IT */ + it: { + meta_desc: "Installa pacchetti da qualsiasi fonte su qualsiasi distribuzione Linux. Zero Layer traduce i binari in modo nativo durante l'installazione — niente container, niente VM, zero overhead a runtime.", + + nav_why: "Perché", nav_how: "Come funziona", nav_sources: "Sorgenti", + nav_commands: "Comandi", nav_arch: "Architettura", nav_faq: "FAQ", + nav_menu: "Menu", nav_theme: "Cambia tema", nav_lang: "Lingua", + skip: "Vai al contenuto", + + hero_badge: "v0.2 — Open source, licenza MIT", + hero_t1: "Un solo comando.", + hero_t2: "Qualsiasi pacchetto. Qualsiasi distro.", + hero_lede: "Zero Layer è un gestore di pacchetti universale per Linux. Installa software proveniente da 13 ecosistemi diversi su qualunque distribuzione, traducendo i binari al momento dell'installazione — non durante l'esecuzione.", + hero_cta1: "Inizia ora", + hero_cta2: "Leggi il codice", + hero_install_note: "Un solo binario. Nessun runtime, nessun demone, nessuna dipendenza.", + + stat_sources: "sorgenti di pacchetti", + stat_overhead: "overhead a runtime", + stat_tests: "test, CI verde", + stat_cdeps: "dipendenze C", + + why_eyebrow: "Il problema", + why_title: "Il packaging su Linux è frammentato per costruzione", + why_lede: "Ogni distribuzione ha il proprio formato, i propri repository e la propria idea di dove vadano i file. Il software che ti serve è spesso già pacchettizzato — solo non per il tuo sistema.", + p1_t: "Il pacchetto esiste, ma non per te", + p1_d: "Uno strumento è nell'AUR, o solo come .deb, o solo come release su GitHub. La tua distro l'ha pacchettizzato due anni fa, oppure mai. Finisci per compilarlo a mano o per rinunciarci.", + p2_t: "Le soluzioni alternative costano prestazioni", + p2_d: "Container, macchine virtuali e livelli di compatibilità risolvono il problema aggiungendo un livello. E lo paghi per sempre: latenza all'avvio, memoria, disco e un runtime che deve restare in esecuzione.", + p3_t: "Le installazioni manuali marciscono in silenzio", + p3_d: "Scompattare un tarball in /opt funziona finché una libreria non si sposta. Nulla tiene traccia dei file, nulla conosce le dipendenze e nulla è in grado di annullare l'operazione.", + + what_eyebrow: "L'idea", + what_title: "Tradurre una volta sola, all'installazione", + what_lede: "Un binario Linux non è legato a una distribuzione: è legato a pochi fatti concreti, ovvero quale linker dinamico lo carica e dove si trovano le sue librerie condivise. Entrambi sono scritti dentro il file ELF, ed entrambi si possono riscrivere.", + what_p1: "Zero Layer legge quei campi con goblin e li riscrive con elb perché puntino al linker e ai percorsi reali del tuo sistema. Lo fa una volta sola, durante l'installazione.", + what_p2: "Da quel momento il binario è semplicemente un binario nativo sulla tua macchina. Nessuno shim, nessuno script wrapper, nessuna sandbox e nessun processo di supervisione. Da qui il nome: il livello è zero.", + what_b1: "Nessun runtime di container da installare o mantenere attivo", + what_b2: "Nessuna penalità prestazionale — è lo stesso codice macchina", + what_b3: "I file finiscono in directory normali, che puoi ispezionare", + what_b4: "Tutto è tracciato e ogni installazione è annullabile", + + phil_eyebrow: "Filosofia", + phil_title: "Sei principi dietro ogni scelta", + phil_lede: "Zero Layer ha una posizione precisa. Queste sono le regole a cui il codice deve rispondere.", + ph1_t: "Zero overhead dopo l'installazione", + ph1_d: "Tutto il lavoro di traduzione avviene una volta sola, durante l'installazione. Dopo non resta nulla tra il tuo programma e il kernel.", + ph2_t: "Rilevare, mai dare per scontato", + ph2_d: "Architettura, linker dinamico, libc, directory delle librerie e struttura del filesystem vengono rilevati dal sistema in esecuzione, non scritti a mano nel codice.", + ph3_t: "Atomico o niente", + ph3_d: "Ogni installazione avviene dentro una transazione che registra ciò che ha toccato. Un errore in qualsiasi punto annulla l'intera operazione.", + ph4_t: "Un binario, zero C", + ph4_d: "redb al posto di SQLite, elb al posto di patchelf, rustls al posto di OpenSSL. Rust puro significa compilare ed eseguire ovunque senza cacce alla toolchain.", + ph5_t: "La fonte la scegli tu", + ph5_d: "Quando un pacchetto esiste in più ecosistemi, Zero Layer li mostra tutti e ti lascia scegliere. Non decide mai al posto tuo in silenzio.", + ph6_t: "Reversibile per impostazione predefinita", + ph6_d: "Cronologia, rollback, rilevamento degli orfani e dry-run sono funzioni centrali, non ripensamenti. Puoi sempre vedere cos'è successo e tornare indietro.", + + how_eyebrow: "Come funziona", + how_title: "Cosa succede quando digiti install", + how_lede: "Tra il tuo comando e un binario funzionante ci sono otto fasi. Ognuna è osservabile con -v, e qualsiasi errore riporta tutto indietro.", + h1_t: "Risoluzione", h1_d: "Trova il pacchetto e percorre ricorsivamente l'albero delle dipendenze, rilevando i cicli. Se una dipendenza manca nella sorgente principale, vengono interrogate tutte le altre attive e scegli tu.", h1_m: "risoluzione cross-sorgente", + h2_t: "Controllo conflitti", h2_d: "Cinque categorie vengono verificate prima di scrivere qualsiasi cosa: proprietà dei file, nomi dei binari, soname delle librerie, conflitti dichiarati e vincoli di versione.", h2_m: "5 tipi di conflitto", + h3_t: "Download", h3_d: "I pacchetti sono scaricati direttamente dai repository nativi su quattro thread paralleli, con barre di avanzamento e ritentativi automatici con backoff.", h3_m: "4 thread · retry", + h4_t: "Verifica", h4_d: "I checksum SHA256 sono obbligatori e le firme GPG vengono controllate quando la sorgente le fornisce. Una firma non verificabile viene segnalata diversamente da una errata.", h4_m: "SHA256 + GPG", + h5_t: "Estrazione", h5_d: "Il formato dell'archivio viene riconosciuto e scompattato — deb, rpm, tar, zst, xz, nar, squashfs, zip o AppImage — poi normalizzato in una struttura FHS standard.", h5_m: "9 formati di archivio", + h6_t: "Patch", h6_d: "Ogni binario ELF viene analizzato, poi interprete e RUNPATH vengono riscritti per il tuo sistema. I pacchetti con più binari sono patchati in parallelo; quelli statici vengono giustamente lasciati intatti.", h6_m: "goblin + elb", + h7_t: "Installazione", h7_d: "I file sono collocati in modo atomico dentro una transazione che registra ogni file, directory, symlink e riga di database creata. Qualsiasi errore annulla tutto.", h7_m: "atomico · rollback", + h8_t: "Tracciamento", h8_d: "File, dipendenze, proprietà e l'operazione stessa vengono scritti in un database integrato: è ciò che rende possibili in seguito why, size, doctor e rollback.", h8_m: "redb + grafo", + + feat_eyebrow: "Funzionalità", + feat_title: "Un gestore di pacchetti completo, non una demo", + feat_lede: "Tutto quello che ti aspetti dagli strumenti della tua distro, più ciò che non hanno mai avuto.", + f1_t: "Traduzione nativa dei binari", + f1_d: "I binari ELF vengono analizzati con goblin e modificati con elb durante l'installazione. Linker dinamico e RUNPATH sono riscritti per il tuo sistema, così i pacchetti girano poi a piena velocità nativa.", + f2_t: "13 sorgenti in parallelo", + f2_d: "Ogni sorgente attiva viene interrogata simultaneamente, i risultati sono ordinati per rilevanza e le varianti binarie AUR vengono trovate in automatico.", + f3_t: "Transazioni atomiche", + f3_d: "Un'installazione o si completa o non lascia traccia. Mai stati scritti a metà.", + f4_t: "Diagnostica integrata", + f4_d: "doctor, audit, why, size, diff e history rispondono alle domande su cui di solito i gestori di pacchetti ti lasciano a indovinare.", + f5_t: "Multi-versione e ambienti", + f5_d: "Installa più versioni affiancate e passa dall'una all'altra, oppure crea un ambiente effimero che sparisce quando esci dalla shell.", + f6_t: "Attento alla sicurezza", + f6_d: "Checksum e firme in entrata, ricerca di CVE su OSV.dev in uscita, più il pinning per congelare ciò che non vuoi si muova.", + + src_eyebrow: "Sorgenti", + src_title: "Tredici ecosistemi, un'unica interfaccia", + src_lede: "Ogni sorgente è un plugin che implementa lo stesso trait. Attiva quelle che vuoi per ogni macchina, o filtra per singolo comando con --from.", + src_note: "La disponibilità di una sorgente dipende dalla raggiungibilità dell'upstream. Il repository tiene traccia dello stato reale di ogni plugin.", + src_status_link: "Vedi lo stato dei plugin", + + cmd_eyebrow: "Comandi", + cmd_title: "L'interfaccia, dall'inizio alla fine", + cmd_lede: "Un binario, venticinque comandi, completamenti per bash, zsh e fish.", + cmd_tab1: "Installazione", cmd_tab2: "Ricerca", cmd_tab3: "Diagnostica", + cmd_tab4: "Cronologia", cmd_tab5: "Ambienti", + copy: "Copia", copied: "Copiato", + + arch_eyebrow: "Sotto il cofano", + arch_title: "Costruito per essere noioso dove conta", + arch_lede: "Struttura prevedibile su disco, dipendenze in Rust puro e una suite di test che gira a ogni push.", + arch_layout_t: "Dove finiscono le cose", + arch_layout_d: "Tutto vive sotto un'unica directory che ti appartiene. Aggiungi bin al PATH e nient'altro nel sistema viene toccato.", + arch_stack_t: "Lo stack", + arch_choices_t: "Vincoli di progetto", + ac1: "Binario unico, zero dipendenze C", + ac2: "RUNPATH invece di RPATH, così LD_LIBRARY_PATH continua a funzionare", + ac3: "Thread invece di un runtime asincrono", + ac4: "Tutto rilevato dal sistema in esecuzione", + ac5: "Il rollback è un percorso di prima classe, non un caso d'errore", + ac6: "Zero warning di clippy, formattato, protetto dalla CI", + + cmp_eyebrow: "Confronto", + cmp_title: "In cosa si distingue dalle alternative", + cmp_lede: "Container e formati universali risolvono lo stesso problema isolando il software. Zero Layer lo risolve adattandolo.", + cmp_c1: "Approccio", cmp_c2: "Costo a runtime", cmp_c3: "Costo su disco", cmp_c4: "Richiede un demone", + cmp_r1: "Zero Layer", cmp_r1a: "Patch dei binari all'installazione", cmp_r1b: "Nessuno", cmp_r1c: "Librerie condivise, deduplicate", cmp_r1d: "No", + cmp_r2a: "Immagine completa di OS per app", cmp_r2b: "Overhead di processo e namespace", cmp_r2c: "Livelli di immagine per app", cmp_r2d: "Sì", + cmp_r3a: "Runtime inclusi", cmp_r3b: "Sandbox e indirezione dei portal", cmp_r3c: "Un runtime per famiglia di app", cmp_r3d: "Sì", + cmp_r4a: "Squashfs e confinamento", cmp_r4b: "Livello di mount e confinamento", cmp_r4c: "Immagine compressa per app", cmp_r4d: "Sì", + cmp_r5: "Tarball manuale", cmp_r5a: "Scompatta e spera", cmp_r5b: "Nessuno", cmp_r5c: "Quello che hai copiato", cmp_r5d: "No", + cmp_foot: "L'installazione manuale pareggia Zero Layer sull'overhead — e perde su tutto il resto: nulla è tracciato, nulla risolve le dipendenze e nulla può annullare l'operazione.", + + start_eyebrow: "Per iniziare", + start_title: "Operativo in meno di un minuto", + start_lede: "Un download, una riga nel profilo della shell. Non serve un gestore di pacchetti per installare il gestore di pacchetti.", + s1_t: "Installa il binario", + s1_d: "Scarica l'ultima release. Usa la seconda forma se preferisci non usare sudo.", + s2_t: "Aggiungilo al PATH", + s2_d: "Zero Layer crea i symlink degli eseguibili che installa nella propria directory bin.", + s3_t: "Installa qualcosa", + s3_d: "Ometti --from e Zero Layer cercherà in tutte le sorgenti attive lasciandoti scegliere.", + start_alt: "Preferisci compilarlo da te? Serve Rust 1.85 o successivo.", + + faq_eyebrow: "FAQ", + faq_title: "Domande legittime", + q1: "Sostituisce il gestore di pacchetti della mia distro?", + a1: "No, e non ci prova. Zero Layer installa nella tua home e non tocca mai i percorsi di sistema, quindi pacman, apt o dnf continuano a gestire il sistema base esattamente come prima. Usalo per il software che la tua distro non pacchettizza.", + q2: "Serve root?", + a2: "No. L'installazione predefinita vive interamente sotto ~/.local/share/zl. Root entra in gioco solo se scegli di mettere il binario zl in /usr/local/bin, e anche quello è facoltativo.", + q3: "È davvero a zero overhead?", + a3: "Sì, perché dopo l'installazione non resta nulla in esecuzione. Il binario modificato è normale codice macchina eseguito direttamente dal kernel — nessuna sandbox, nessun supervisore, nessuna traduzione a runtime. Il lavoro avviene una volta sola, durante l'installazione.", + q4: "E se un pacchetto richiede una libreria che non ho?", + a4: "Le dipendenze vengono risolte ricorsivamente prima di scaricare qualsiasi cosa e, se una manca nella sorgente principale, vengono cercate in tutte le altre attive. Dopo l'installazione, un controllo finale avvisa se resta qualche libreria condivisa non individuabile.", + q5: "Cosa succede se un'installazione fallisce a metà?", + a5: "Non resta nulla. Ogni installazione avviene dentro una transazione che registra file, directory, symlink e voci di database creati, e qualsiasi errore li annulla tutti. Puoi anche vedere l'anteprima di ogni operazione con --dry-run.", + q6: "Quali distribuzioni supporta?", + a6: "In linea di principio tutte. Invece di mantenere un elenco, Zero Layer rileva a runtime architettura, linker dinamico, libc, directory delle librerie e struttura del filesystem — comprese quelle merged-usr, NixOS, Guix, GoboLinux e Termux.", + q7: "È pronto per la produzione?", + a7: "È software giovane, in sviluppo attivo, e lo dice apertamente: il repository tiene traccia di quali plugin sono verificati contro i loro upstream reali e quali sono ancora in riparazione. Il percorso di installazione centrale è coperto da 349 test che vincolano ogni commit.", + q8: "Come lo disinstallo?", + a8: "Cancelli la directory. Tutto ciò che Zero Layer installa — pacchetti, database, cache, symlink — sta dentro un'unica cartella, quindi rimuoverla elimina ogni traccia.", + + cta_title: "Installa qualsiasi cosa, su qualsiasi cosa", + cta_p: "Gratuito e open source con licenza MIT. Nessun account, nessuna telemetria, nessun demone.", + cta_b1: "Scarica l'ultima release", + cta_b2: "Metti una stella su GitHub", + + foot_about: "Un gestore di pacchetti universale per Linux con traduzione nativa dei binari. Installa da qualsiasi sorgente, su qualsiasi distribuzione, con zero overhead a runtime.", + foot_c1: "Progetto", foot_c2: "Risorse", foot_c3: "Community", + foot_readme: "Documentazione", foot_releases: "Release", foot_status: "Stato dei plugin", foot_license_l: "Licenza", + foot_issues: "Segnala un problema", foot_discussions: "Discussioni", foot_contribute: "Contribuisci", foot_source: "Codice sorgente", + foot_builtby: "Creato da", foot_license: "Rilasciato con licenza MIT.", + foot_madewith: "Scritto in Rust." + }, + + /* ---------------------------------------------------------------- FR */ + fr: { + meta_desc: "Installez des paquets depuis n'importe quelle source sur n'importe quelle distribution Linux. Zero Layer traduit les binaires nativement à l'installation — sans conteneurs, sans VM, sans surcoût à l'exécution.", + + nav_why: "Pourquoi", nav_how: "Fonctionnement", nav_sources: "Sources", + nav_commands: "Commandes", nav_arch: "Architecture", nav_faq: "FAQ", + nav_menu: "Menu", nav_theme: "Changer de thème", nav_lang: "Langue", + skip: "Aller au contenu", + + hero_badge: "v0.2 — Open source, licence MIT", + hero_t1: "Une seule commande.", + hero_t2: "N'importe quel paquet. N'importe quelle distro.", + hero_lede: "Zero Layer est un gestionnaire de paquets universel pour Linux. Il installe des logiciels issus de 13 écosystèmes sur n'importe quelle distribution en traduisant les binaires à l'installation — et non à l'exécution.", + hero_cta1: "Commencer", + hero_cta2: "Lire le code", + hero_install_note: "Un seul binaire. Sans runtime, sans démon, sans dépendances.", + + stat_sources: "sources de paquets", + stat_overhead: "surcoût à l'exécution", + stat_tests: "tests, CI au vert", + stat_cdeps: "dépendances C", + + why_eyebrow: "Le problème", + why_title: "L'empaquetage Linux est fragmenté par nature", + why_lede: "Chaque distribution a son format, ses dépôts et sa propre idée de l'endroit où doivent aller les fichiers. Le logiciel que vous cherchez est souvent déjà empaqueté — mais pas pour votre système.", + p1_t: "Le paquet existe, mais pas pour vous", + p1_d: "Un outil est dans l'AUR, ou seulement en .deb, ou seulement en release GitHub. Votre distro l'a empaqueté il y a deux ans, ou jamais. Vous finissez par compiler à la main ou par vous en passer.", + p2_t: "Les contournements coûtent en performances", + p2_d: "Conteneurs, machines virtuelles et couches de compatibilité résolvent le problème en ajoutant une couche. Vous la payez indéfiniment : latence au démarrage, mémoire, disque, et un runtime qui doit rester actif.", + p3_t: "Les installations manuelles pourrissent en silence", + p3_d: "Déposer une archive dans /opt fonctionne jusqu'à ce qu'une bibliothèque bouge. Rien ne suit les fichiers, rien ne connaît les dépendances, et rien ne permet de revenir en arrière proprement.", + + what_eyebrow: "L'idée", + what_title: "Traduire une fois, à l'installation", + what_lede: "Un binaire Linux n'est pas lié à une distribution : il est lié à quelques faits concrets, à savoir quel éditeur de liens dynamique le charge et où se trouvent ses bibliothèques partagées. Les deux sont inscrits dans le fichier ELF, et les deux peuvent être réécrits.", + what_p1: "Zero Layer lit ces champs avec goblin, puis les réécrit avec elb pour qu'ils pointent vers l'éditeur de liens et les chemins réels de votre système. Une seule fois, pendant l'installation.", + what_p2: "Ensuite, le binaire est simplement un binaire natif sur votre machine. Pas de shim, pas de script d'enrobage, pas de bac à sable et pas de processus superviseur. D'où le nom : la couche est nulle.", + what_b1: "Aucun runtime de conteneur à installer ni à maintenir actif", + what_b2: "Aucune pénalité de performance — c'est le même code machine", + what_b3: "Les fichiers arrivent dans des répertoires normaux, inspectables", + what_b4: "Tout est suivi, et chaque installation est annulable", + + phil_eyebrow: "Philosophie", + phil_title: "Six principes derrière chaque décision", + phil_lede: "Zero Layer assume ses partis pris. Voici les règles auxquelles le code est tenu.", + ph1_t: "Zéro surcoût après l'installation", + ph1_d: "Tout le travail de traduction a lieu une seule fois, pendant l'installation. Ensuite, plus rien ne s'interpose entre votre programme et le noyau.", + ph2_t: "Détecter, jamais supposer", + ph2_d: "Architecture, éditeur de liens dynamique, libc, répertoires de bibliothèques et organisation du système de fichiers sont sondés depuis le système en cours, jamais codés en dur.", + ph3_t: "Atomique ou rien", + ph3_d: "Chaque installation s'exécute dans une transaction qui enregistre ce qu'elle a touché. Une erreur, où qu'elle survienne, annule toute l'opération.", + ph4_t: "Un binaire, zéro C", + ph4_d: "redb plutôt que SQLite, elb plutôt que patchelf, rustls plutôt qu'OpenSSL. Du Rust pur signifie compiler et exécuter partout, sans chasse à la chaîne d'outils.", + ph5_t: "C'est vous qui choisissez la source", + ph5_d: "Quand un paquet existe dans plusieurs écosystèmes, Zero Layer les affiche tous et vous laisse choisir. Il ne décide jamais en silence à votre place.", + ph6_t: "Réversible par défaut", + ph6_d: "Historique, retour arrière, détection des orphelins et simulation sont des fonctions centrales, pas des ajouts tardifs. Vous pouvez toujours voir ce qui s'est passé et l'annuler.", + + how_eyebrow: "Fonctionnement", + how_title: "Ce qui se passe quand vous tapez install", + how_lede: "Huit étapes séparent votre commande d'un binaire fonctionnel. Chacune est observable avec -v, et la moindre erreur ramène tout en arrière.", + h1_t: "Résolution", h1_d: "Trouve le paquet et parcourt récursivement son arbre de dépendances en détectant les cycles. Si une dépendance manque dans la source principale, toutes les autres sources actives sont interrogées et vous choisissez.", h1_m: "résolution inter-sources", + h2_t: "Vérification des conflits", h2_d: "Cinq catégories sont contrôlées avant toute écriture : propriété des fichiers, noms de binaires, sonames de bibliothèques, conflits déclarés et contraintes de version.", h2_m: "5 types de conflits", + h3_t: "Téléchargement", h3_d: "Les paquets sont récupérés directement depuis leurs dépôts natifs sur quatre threads parallèles, avec barres de progression et nouvelles tentatives automatiques.", h3_m: "4 threads · reprise", + h4_t: "Vérification", h4_d: "Les sommes SHA256 sont imposées et les signatures GPG contrôlées lorsque la source les fournit. Une signature invérifiable est signalée différemment d'une signature erronée.", h4_m: "SHA256 + GPG", + h5_t: "Extraction", h5_d: "Le format d'archive est détecté et décompressé — deb, rpm, tar, zst, xz, nar, squashfs, zip ou AppImage — puis normalisé vers une arborescence FHS standard.", h5_m: "9 formats d'archive", + h6_t: "Patch", h6_d: "Chaque binaire ELF est analysé, puis son interpréteur et son RUNPATH sont réécrits pour votre système. Les paquets multi-binaires sont traités en parallèle ; les binaires statiques sont laissés intacts, à raison.", h6_m: "goblin + elb", + h7_t: "Installation", h7_d: "Les fichiers sont placés de façon atomique dans une transaction qui consigne chaque fichier, répertoire, lien et ligne de base de données créés. La moindre erreur annule l'ensemble.", h7_m: "atomique · retour arrière", + h8_t: "Suivi", h8_d: "Fichiers, dépendances, propriété et l'opération elle-même sont écrits dans une base embarquée : c'est ce qui rend possibles ensuite why, size, doctor et rollback.", h8_m: "redb + graphe", + + feat_eyebrow: "Fonctionnalités", + feat_title: "Un gestionnaire de paquets complet, pas une démo", + feat_lede: "Tout ce que vous attendez des outils de votre distribution, plus ce qu'ils n'ont jamais eu.", + f1_t: "Traduction native des binaires", + f1_d: "Les binaires ELF sont analysés avec goblin et modifiés avec elb à l'installation. L'éditeur de liens dynamique et le RUNPATH sont réécrits pour votre système : les paquets tournent ensuite à pleine vitesse native.", + f2_t: "13 sources en parallèle", + f2_d: "Toutes les sources actives sont interrogées simultanément, les résultats classés par pertinence, et les variantes binaires de l'AUR détectées automatiquement.", + f3_t: "Transactions atomiques", + f3_d: "Une installation aboutit ou ne laisse aucune trace. Jamais d'état écrit à moitié.", + f4_t: "Diagnostics intégrés", + f4_d: "doctor, audit, why, size, diff et history répondent aux questions que les gestionnaires de paquets laissent d'ordinaire sans réponse.", + f5_t: "Multi-version et environnements", + f5_d: "Installez plusieurs versions côte à côte et basculez entre elles, ou créez un environnement éphémère qui disparaît à la sortie du shell.", + f6_t: "Attentif à la sécurité", + f6_d: "Sommes de contrôle et signatures à l'entrée, recherche de CVE via OSV.dev à la sortie, et épinglage pour figer ce que vous ne voulez pas voir bouger.", + + src_eyebrow: "Sources", + src_title: "Treize écosystèmes, une seule interface", + src_lede: "Chaque source est un greffon implémentant le même trait. Activez celles que vous voulez par machine, ou filtrez par commande avec --from.", + src_note: "La disponibilité d'une source dépend de l'accessibilité de l'amont. Le dépôt suit l'état réel de chaque greffon.", + src_status_link: "Voir l'état des greffons", + + cmd_eyebrow: "Commandes", + cmd_title: "L'interface, de bout en bout", + cmd_lede: "Un binaire, vingt-cinq commandes, complétions pour bash, zsh et fish.", + cmd_tab1: "Installation", cmd_tab2: "Recherche", cmd_tab3: "Diagnostics", + cmd_tab4: "Historique", cmd_tab5: "Environnements", + copy: "Copier", copied: "Copié", + + arch_eyebrow: "Sous le capot", + arch_title: "Conçu pour être ennuyeux là où il faut", + arch_lede: "Une organisation prévisible sur disque, des dépendances en Rust pur et une suite de tests exécutée à chaque push.", + arch_layout_t: "Où atterrissent les fichiers", + arch_layout_d: "Tout vit sous un seul répertoire qui vous appartient. Ajoutez bin au PATH et rien d'autre sur le système n'est touché.", + arch_stack_t: "La stack", + arch_choices_t: "Contraintes de conception", + ac1: "Binaire unique, zéro dépendance C", + ac2: "RUNPATH plutôt que RPATH, pour que LD_LIBRARY_PATH fonctionne encore", + ac3: "Des threads plutôt qu'un runtime asynchrone", + ac4: "Tout est détecté depuis le système en cours d'exécution", + ac5: "Le retour arrière est un chemin de premier plan, pas un cas d'erreur", + ac6: "Zéro avertissement clippy, formaté, verrouillé par la CI", + + cmp_eyebrow: "Comparaison", + cmp_title: "Ce qui le distingue des alternatives", + cmp_lede: "Conteneurs et formats universels résolvent le même problème en isolant le logiciel. Zero Layer le résout en l'adaptant.", + cmp_c1: "Approche", cmp_c2: "Coût à l'exécution", cmp_c3: "Coût disque", cmp_c4: "Démon requis", + cmp_r1: "Zero Layer", cmp_r1a: "Patch des binaires à l'installation", cmp_r1b: "Aucun", cmp_r1c: "Bibliothèques partagées, dédupliquées", cmp_r1d: "Non", + cmp_r2a: "Image système complète par application", cmp_r2b: "Surcoût de processus et d'espaces de noms", cmp_r2c: "Couches d'image par application", cmp_r2d: "Oui", + cmp_r3a: "Runtimes embarqués", cmp_r3b: "Bac à sable et indirection des portails", cmp_r3c: "Un runtime par famille d'applications", cmp_r3d: "Oui", + cmp_r4a: "Squashfs et confinement", cmp_r4b: "Couche de montage et de confinement", cmp_r4c: "Image compressée par application", cmp_r4d: "Oui", + cmp_r5: "Archive manuelle", cmp_r5a: "Décompresser et espérer", cmp_r5b: "Aucun", cmp_r5c: "Ce que vous avez copié", cmp_r5d: "Non", + cmp_foot: "L'installation manuelle égale Zero Layer sur le surcoût — et perd sur tout le reste : rien n'est suivi, rien ne résout les dépendances, et rien ne peut l'annuler.", + + start_eyebrow: "Démarrer", + start_title: "Opérationnel en moins d'une minute", + start_lede: "Un téléchargement, une ligne dans votre profil shell. Pas besoin d'un gestionnaire de paquets pour installer le gestionnaire de paquets.", + s1_t: "Installer le binaire", + s1_d: "Récupérez la dernière version. Utilisez la seconde forme si vous préférez éviter sudo.", + s2_t: "L'ajouter au PATH", + s2_d: "Zero Layer place des liens vers les exécutables qu'il installe dans son propre répertoire bin.", + s3_t: "Installer quelque chose", + s3_d: "Omettez --from et Zero Layer cherchera dans toutes les sources actives en vous laissant choisir.", + start_alt: "Vous préférez le compiler ? Rust 1.85 ou plus récent est requis.", + + faq_eyebrow: "FAQ", + faq_title: "Questions légitimes", + q1: "Cela remplace-t-il le gestionnaire de paquets de ma distribution ?", + a1: "Non, et ce n'est pas son but. Zero Layer installe dans votre dossier personnel et ne touche jamais aux chemins système : pacman, apt ou dnf continuent de gérer le système de base exactement comme avant. Utilisez-le pour les logiciels que votre distribution n'empaquette pas.", + q2: "Faut-il être root ?", + a2: "Non. L'installation par défaut réside entièrement sous ~/.local/share/zl. Root n'intervient que si vous choisissez de placer le binaire zl dans /usr/local/bin, et c'est facultatif.", + q3: "Est-ce vraiment sans surcoût ?", + a3: "Oui, car après l'installation il ne reste rien en cours d'exécution. Le binaire modifié est du code machine ordinaire exécuté directement par le noyau — sans bac à sable, sans superviseur, sans traduction à l'exécution. Le travail a lieu une fois, à l'installation.", + q4: "Et si un paquet a besoin d'une bibliothèque que je n'ai pas ?", + a4: "Les dépendances sont résolues récursivement avant tout téléchargement et, si l'une manque dans la source principale, toutes les autres sources actives sont explorées. Après l'installation, une vérification signale toute bibliothèque partagée encore introuvable.", + q5: "Que se passe-t-il si une installation échoue en cours de route ?", + a5: "Rien ne subsiste. Chaque installation s'exécute dans une transaction qui consigne les fichiers, répertoires, liens et entrées de base de données créés, et la moindre erreur les annule tous. Vous pouvez aussi prévisualiser toute opération avec --dry-run.", + q6: "Quelles distributions sont prises en charge ?", + a6: "Toutes, en principe. Plutôt que de tenir une liste, Zero Layer détecte à l'exécution l'architecture, l'éditeur de liens dynamique, la libc, les répertoires de bibliothèques et l'organisation du système de fichiers — y compris merged-usr, NixOS, Guix, GoboLinux et Termux.", + q7: "Est-ce prêt pour la production ?", + a7: "C'est un logiciel jeune, en développement actif, et il l'assume : le dépôt indique précisément quels greffons sont vérifiés face à leurs amonts réels et lesquels sont encore en réparation. Le chemin d'installation principal est couvert par 349 tests qui verrouillent chaque commit.", + q8: "Comment le désinstaller ?", + a8: "Supprimez le répertoire. Tout ce que Zero Layer installe — paquets, base de données, cache, liens — se trouve dans un seul dossier : le supprimer efface toute trace.", + + cta_title: "Installez n'importe quoi, sur n'importe quoi", + cta_p: "Gratuit et open source sous licence MIT. Sans compte, sans télémétrie, sans démon.", + cta_b1: "Télécharger la dernière version", + cta_b2: "Mettre une étoile sur GitHub", + + foot_about: "Un gestionnaire de paquets universel pour Linux avec traduction native des binaires. Installez depuis n'importe quelle source, sur n'importe quelle distribution, sans surcoût à l'exécution.", + foot_c1: "Projet", foot_c2: "Ressources", foot_c3: "Communauté", + foot_readme: "Documentation", foot_releases: "Versions", foot_status: "État des greffons", foot_license_l: "Licence", + foot_issues: "Signaler un problème", foot_discussions: "Discussions", foot_contribute: "Contribuer", foot_source: "Code source", + foot_builtby: "Créé par", foot_license: "Publié sous licence MIT.", + foot_madewith: "Écrit en Rust." + }, + + /* ---------------------------------------------------------------- ES */ + es: { + meta_desc: "Instala paquetes desde cualquier fuente en cualquier distribución de Linux. Zero Layer traduce los binarios de forma nativa durante la instalación: sin contenedores, sin VM, sin sobrecarga en ejecución.", + + nav_why: "Por qué", nav_how: "Cómo funciona", nav_sources: "Fuentes", + nav_commands: "Comandos", nav_arch: "Arquitectura", nav_faq: "FAQ", + nav_menu: "Menú", nav_theme: "Cambiar tema", nav_lang: "Idioma", + skip: "Ir al contenido", + + hero_badge: "v0.2 — Código abierto, licencia MIT", + hero_t1: "Un solo comando.", + hero_t2: "Cualquier paquete. Cualquier distro.", + hero_lede: "Zero Layer es un gestor de paquetes universal para Linux. Instala software de 13 ecosistemas distintos en cualquier distribución traduciendo los binarios al instalar, no al ejecutar.", + hero_cta1: "Empezar", + hero_cta2: "Ver el código", + hero_install_note: "Un único binario. Sin runtime, sin demonio, sin dependencias.", + + stat_sources: "fuentes de paquetes", + stat_overhead: "sobrecarga en ejecución", + stat_tests: "pruebas, CI en verde", + stat_cdeps: "dependencias de C", + + why_eyebrow: "El problema", + why_title: "El empaquetado en Linux está fragmentado por diseño", + why_lede: "Cada distribución trae su propio formato, sus repositorios y su idea de dónde deben ir los archivos. El software que quieres suele estar empaquetado, pero no para tu sistema.", + p1_t: "El paquete existe, pero no para ti", + p1_d: "Una herramienta está en el AUR, o solo como .deb, o solo como release de GitHub. Tu distro la empaquetó hace dos años, o nunca. Acabas compilando a mano o quedándote sin ella.", + p2_t: "Los apaños cuestan rendimiento", + p2_d: "Contenedores, máquinas virtuales y capas de compatibilidad resuelven esto añadiendo una capa. Y la pagas para siempre: latencia de arranque, memoria, disco y un runtime que debe seguir ejecutándose.", + p3_t: "Las instalaciones manuales se pudren en silencio", + p3_d: "Soltar un tarball en /opt funciona hasta que una biblioteca se mueve. Nada registra los archivos, nada conoce las dependencias y nada puede deshacerlo limpiamente.", + + what_eyebrow: "La idea", + what_title: "Traducir una vez, al instalar", + what_lede: "Un binario de Linux no está atado a una distribución: está atado a unos pocos hechos concretos, es decir, qué enlazador dinámico lo carga y dónde viven sus bibliotecas compartidas. Ambos están escritos dentro del archivo ELF y ambos se pueden reescribir.", + what_p1: "Zero Layer lee esos campos con goblin y los reescribe con elb para que apunten al enlazador y a las rutas reales de tu sistema. Lo hace una sola vez, durante la instalación.", + what_p2: "A partir de ahí el binario es sencillamente un binario nativo en tu máquina. Sin shim, sin script envoltorio, sin sandbox y sin proceso supervisor. De ahí el nombre: la capa es cero.", + what_b1: "Ningún runtime de contenedores que instalar o mantener activo", + what_b2: "Ninguna penalización de rendimiento: es el mismo código máquina", + what_b3: "Los archivos acaban en directorios normales que puedes inspeccionar", + what_b4: "Todo queda registrado y cada instalación se puede revertir", + + phil_eyebrow: "Filosofía", + phil_title: "Seis principios detrás de cada decisión", + phil_lede: "Zero Layer tiene criterio propio. Estas son las reglas a las que se somete el código.", + ph1_t: "Cero sobrecarga tras instalar", + ph1_d: "Todo el trabajo de traducción ocurre una sola vez, durante la instalación. Después no queda nada entre tu programa y el kernel.", + ph2_t: "Detectar, nunca suponer", + ph2_d: "Arquitectura, enlazador dinámico, libc, directorios de bibliotecas y estructura del sistema de archivos se sondean del sistema en ejecución en lugar de fijarse en el código.", + ph3_t: "Atómico o nada", + ph3_d: "Cada instalación se ejecuta dentro de una transacción que registra lo que tocó. Un fallo en cualquier punto revierte la operación entera.", + ph4_t: "Un binario, cero C", + ph4_d: "redb en lugar de SQLite, elb en lugar de patchelf, rustls en lugar de OpenSSL. Rust puro significa compilar y ejecutar en cualquier sitio sin buscar cadenas de herramientas.", + ph5_t: "La fuente la eliges tú", + ph5_d: "Cuando un paquete existe en varios ecosistemas, Zero Layer los muestra todos y te deja elegir. Nunca decide por ti en silencio.", + ph6_t: "Reversible por defecto", + ph6_d: "Historial, reversión, detección de huérfanos y simulación son funciones centrales, no añadidos. Siempre puedes ver qué pasó y deshacerlo.", + + how_eyebrow: "Cómo funciona", + how_title: "Qué ocurre cuando escribes install", + how_lede: "Entre tu comando y un binario funcionando hay ocho etapas. Cada una es observable con -v y cualquier fallo lo revierte todo.", + h1_t: "Resolución", h1_d: "Encuentra el paquete y recorre recursivamente su árbol de dependencias detectando ciclos. Si falta una dependencia en la fuente principal, se consultan todas las demás activas y eliges tú.", h1_m: "resolución entre fuentes", + h2_t: "Comprobación de conflictos", h2_d: "Se revisan cinco categorías antes de escribir nada: propiedad de archivos, nombres de binarios, sonames de bibliotecas, conflictos declarados y restricciones de versión.", h2_m: "5 tipos de conflicto", + h3_t: "Descarga", h3_d: "Los paquetes se obtienen directamente de sus repositorios nativos en cuatro hilos paralelos, con barras de progreso y reintentos automáticos con espera creciente.", h3_m: "4 hilos · reintentos", + h4_t: "Verificación", h4_d: "Se exigen sumas SHA256 y se comprueban las firmas GPG cuando la fuente las proporciona. Una firma no verificable se informa de forma distinta a una incorrecta.", h4_m: "SHA256 + GPG", + h5_t: "Extracción", h5_d: "El formato del archivo se detecta y se descomprime — deb, rpm, tar, zst, xz, nar, squashfs, zip o AppImage — y luego se normaliza a una estructura FHS estándar.", h5_m: "9 formatos de archivo", + h6_t: "Parcheo", h6_d: "Cada binario ELF se analiza y después se reescriben su intérprete y su RUNPATH para tu sistema. Los paquetes con varios binarios se parchean en paralelo; los estáticos se dejan intactos, como corresponde.", h6_m: "goblin + elb", + h7_t: "Instalación", h7_d: "Los archivos se colocan de forma atómica dentro de una transacción que anota cada archivo, directorio, enlace y fila de base de datos que crea. Cualquier error lo deshace todo.", h7_m: "atómico · reversión", + h8_t: "Registro", h8_d: "Archivos, dependencias, propiedad y la propia operación se escriben en una base de datos embebida: es lo que después hace posibles why, size, doctor y rollback.", h8_m: "redb + grafo", + + feat_eyebrow: "Capacidades", + feat_title: "Un gestor de paquetes completo, no una demo", + feat_lede: "Todo lo que esperas de las herramientas de tu distro, más lo que nunca tuvieron.", + f1_t: "Traducción nativa de binarios", + f1_d: "Los binarios ELF se analizan con goblin y se parchean con elb al instalar. El enlazador dinámico y el RUNPATH se reescriben para tu sistema, así que después los paquetes corren a plena velocidad nativa.", + f2_t: "13 fuentes en paralelo", + f2_d: "Todas las fuentes activas se consultan a la vez, los resultados se puntúan por relevancia y las variantes binarias del AUR se detectan automáticamente.", + f3_t: "Transacciones atómicas", + f3_d: "Una instalación se completa o no deja rastro. Nunca queda un estado a medio escribir.", + f4_t: "Diagnóstico incorporado", + f4_d: "doctor, audit, why, size, diff e history responden las preguntas que los gestores de paquetes suelen dejar en el aire.", + f5_t: "Multiversión y entornos", + f5_d: "Instala versiones en paralelo y cambia entre ellas, o levanta un entorno efímero que desaparece al salir del shell.", + f6_t: "Consciente de la seguridad", + f6_d: "Sumas y firmas a la entrada, consulta de CVE en OSV.dev a la salida, y anclaje para congelar lo que no quieras que se mueva.", + + src_eyebrow: "Fuentes", + src_title: "Trece ecosistemas, una sola interfaz", + src_lede: "Cada fuente es un plugin que implementa el mismo trait. Activa las que quieras en cada máquina o filtra por comando con --from.", + src_note: "La disponibilidad de una fuente depende de que el upstream sea accesible. El repositorio registra el estado real de cada plugin.", + src_status_link: "Ver el estado de los plugins", + + cmd_eyebrow: "Comandos", + cmd_title: "La interfaz, de principio a fin", + cmd_lede: "Un binario, veinticinco comandos, autocompletado para bash, zsh y fish.", + cmd_tab1: "Instalación", cmd_tab2: "Búsqueda", cmd_tab3: "Diagnóstico", + cmd_tab4: "Historial", cmd_tab5: "Entornos", + copy: "Copiar", copied: "Copiado", + + arch_eyebrow: "Bajo el capó", + arch_title: "Hecho para ser aburrido donde importa", + arch_lede: "Estructura predecible en disco, dependencias en Rust puro y una batería de pruebas que corre en cada push.", + arch_layout_t: "Dónde acaba cada cosa", + arch_layout_d: "Todo vive bajo un único directorio que es tuyo. Añade bin al PATH y no se toca nada más del sistema.", + arch_stack_t: "El stack", + arch_choices_t: "Restricciones de diseño", + ac1: "Binario único, cero dependencias de C", + ac2: "RUNPATH en vez de RPATH, para que LD_LIBRARY_PATH siga funcionando", + ac3: "Hilos en lugar de un runtime asíncrono", + ac4: "Todo se detecta del sistema en ejecución", + ac5: "La reversión es un camino de primera clase, no un caso de error", + ac6: "Cero avisos de clippy, formateado, protegido por CI", + + cmp_eyebrow: "Comparación", + cmp_title: "En qué se diferencia de las alternativas", + cmp_lede: "Los contenedores y los formatos universales resuelven el mismo problema aislando el software. Zero Layer lo resuelve adaptándolo.", + cmp_c1: "Enfoque", cmp_c2: "Coste en ejecución", cmp_c3: "Coste en disco", cmp_c4: "Requiere demonio", + cmp_r1: "Zero Layer", cmp_r1a: "Parchea binarios al instalar", cmp_r1b: "Ninguno", cmp_r1c: "Bibliotecas compartidas, deduplicadas", cmp_r1d: "No", + cmp_r2a: "Imagen completa del SO por app", cmp_r2b: "Sobrecarga de proceso y espacios de nombres", cmp_r2c: "Capas de imagen por app", cmp_r2d: "Sí", + cmp_r3a: "Runtimes incluidos", cmp_r3b: "Sandbox e indirección de portales", cmp_r3c: "Un runtime por familia de apps", cmp_r3d: "Sí", + cmp_r4a: "Squashfs y confinamiento", cmp_r4b: "Capa de montaje y confinamiento", cmp_r4c: "Imagen comprimida por app", cmp_r4d: "Sí", + cmp_r5: "Tarball manual", cmp_r5a: "Descomprimir y confiar", cmp_r5b: "Ninguno", cmp_r5c: "Lo que hayas copiado", cmp_r5d: "No", + cmp_foot: "La instalación manual empata con Zero Layer en sobrecarga y pierde en todo lo demás: nada queda registrado, nada resuelve dependencias y nada puede deshacerlo.", + + start_eyebrow: "Primeros pasos", + start_title: "Funcionando en menos de un minuto", + start_lede: "Una descarga y una línea en el perfil de tu shell. No hace falta un gestor de paquetes para instalar el gestor de paquetes.", + s1_t: "Instala el binario", + s1_d: "Descarga la última versión. Usa la segunda forma si prefieres no usar sudo.", + s2_t: "Añádelo al PATH", + s2_d: "Zero Layer enlaza los ejecutables que instala en su propio directorio bin.", + s3_t: "Instala algo", + s3_d: "Omite --from y Zero Layer buscará en todas las fuentes activas para que elijas.", + start_alt: "¿Prefieres compilarlo tú? Necesitas Rust 1.85 o superior.", + + faq_eyebrow: "FAQ", + faq_title: "Preguntas razonables", + q1: "¿Sustituye al gestor de paquetes de mi distribución?", + a1: "No, ni lo pretende. Zero Layer instala en tu carpeta personal y nunca toca rutas del sistema, así que pacman, apt o dnf siguen gestionando el sistema base igual que antes. Úsalo para el software que tu distro no empaqueta.", + q2: "¿Necesito root?", + a2: "No. La instalación por defecto vive por completo bajo ~/.local/share/zl. Root solo entra en juego si decides poner el binario zl en /usr/local/bin, y eso es opcional.", + q3: "¿De verdad no hay sobrecarga?", + a3: "Sí, porque tras la instalación no queda nada ejecutándose. El binario parcheado es código máquina normal que ejecuta directamente el kernel: sin sandbox, sin supervisor, sin traducción en ejecución. El trabajo se hace una vez, al instalar.", + q4: "¿Y si un paquete necesita una biblioteca que no tengo?", + a4: "Las dependencias se resuelven de forma recursiva antes de descargar nada y, si falta alguna en la fuente principal, se buscan en todas las demás activas. Tras instalar, una comprobación final avisa de cualquier biblioteca compartida que siga sin localizarse.", + q5: "¿Qué pasa si una instalación falla a medias?", + a5: "No queda nada. Cada instalación corre dentro de una transacción que registra los archivos, directorios, enlaces y entradas de base de datos creados, y cualquier fallo los deshace todos. También puedes previsualizar cualquier operación con --dry-run.", + q6: "¿Qué distribuciones soporta?", + a6: "En principio todas. En lugar de mantener una lista, Zero Layer detecta en tiempo de ejecución la arquitectura, el enlazador dinámico, la libc, los directorios de bibliotecas y la estructura del sistema de archivos, incluidas merged-usr, NixOS, Guix, GoboLinux y Termux.", + q7: "¿Está listo para producción?", + a7: "Es software joven en desarrollo activo, y lo dice con franqueza: el repositorio registra qué plugins están verificados contra sus upstreams reales y cuáles siguen en reparación. La ruta principal de instalación está cubierta por 349 pruebas que condicionan cada commit.", + q8: "¿Cómo lo desinstalo?", + a8: "Borra el directorio. Todo lo que Zero Layer instala — paquetes, base de datos, caché, enlaces — vive en una sola carpeta, así que eliminarla borra cualquier rastro.", + + cta_title: "Instala lo que sea, donde sea", + cta_p: "Gratuito y de código abierto con licencia MIT. Sin cuenta, sin telemetría, sin demonio.", + cta_b1: "Descargar la última versión", + cta_b2: "Dar una estrella en GitHub", + + foot_about: "Un gestor de paquetes universal para Linux con traducción nativa de binarios. Instala desde cualquier fuente, en cualquier distribución, sin sobrecarga en ejecución.", + foot_c1: "Proyecto", foot_c2: "Recursos", foot_c3: "Comunidad", + foot_readme: "Documentación", foot_releases: "Versiones", foot_status: "Estado de los plugins", foot_license_l: "Licencia", + foot_issues: "Reportar un problema", foot_discussions: "Discusiones", foot_contribute: "Contribuir", foot_source: "Código fuente", + foot_builtby: "Creado por", foot_license: "Publicado bajo licencia MIT.", + foot_madewith: "Escrito en Rust." + }, + + /* ---------------------------------------------------------------- DE */ + de: { + meta_desc: "Installiere Pakete aus jeder Quelle auf jeder Linux-Distribution. Zero Layer übersetzt Binärdateien nativ bei der Installation — keine Container, keine VMs, kein Laufzeit-Overhead.", + + nav_why: "Warum", nav_how: "So funktioniert's", nav_sources: "Quellen", + nav_commands: "Befehle", nav_arch: "Architektur", nav_faq: "FAQ", + nav_menu: "Menü", nav_theme: "Thema wechseln", nav_lang: "Sprache", + skip: "Zum Inhalt springen", + + hero_badge: "v0.2 — Open Source, MIT-Lizenz", + hero_t1: "Ein Befehl.", + hero_t2: "Jedes Paket. Jede Distro.", + hero_lede: "Zero Layer ist ein universeller Linux-Paketmanager. Er installiert Software aus 13 verschiedenen Ökosystemen auf jeder Distribution, indem er Binärdateien bei der Installation übersetzt — nicht zur Laufzeit.", + hero_cta1: "Loslegen", + hero_cta2: "Quellcode lesen", + hero_install_note: "Eine Binärdatei. Kein Runtime, kein Daemon, keine Abhängigkeiten.", + + stat_sources: "Paketquellen", + stat_overhead: "Laufzeit-Overhead", + stat_tests: "Tests, CI grün", + stat_cdeps: "C-Abhängigkeiten", + + why_eyebrow: "Das Problem", + why_title: "Linux-Paketierung ist von Grund auf zersplittert", + why_lede: "Jede Distribution bringt ihr eigenes Format, ihre eigenen Repositories und ihre eigene Vorstellung davon mit, wo Dateien hingehören. Die Software, die du willst, ist oft schon paketiert — nur nicht für dein System.", + p1_t: "Das Paket existiert, aber nicht für dich", + p1_d: "Ein Werkzeug liegt im AUR, oder nur als .deb, oder nur als GitHub-Release. Deine Distro hat es vor zwei Jahren paketiert — oder nie. Am Ende kompilierst du selbst oder verzichtest.", + p2_t: "Die Behelfslösungen kosten Leistung", + p2_d: "Container, virtuelle Maschinen und Kompatibilitätsschichten lösen das, indem sie eine Schicht hinzufügen. Die bezahlst du dauerhaft: Startverzögerung, Arbeitsspeicher, Plattenplatz und ein Runtime, das laufen muss.", + p3_t: "Manuelle Installationen verrotten still", + p3_d: "Ein Tarball nach /opt zu entpacken funktioniert, bis eine Bibliothek umzieht. Nichts verfolgt die Dateien, nichts kennt die Abhängigkeiten, und nichts kann es sauber rückgängig machen.", + + what_eyebrow: "Die Idee", + what_title: "Einmal übersetzen, bei der Installation", + what_lede: "Eine Linux-Binärdatei ist nicht an eine Distribution gebunden, sondern an wenige konkrete Fakten: welcher dynamische Linker sie lädt und wo ihre gemeinsamen Bibliotheken liegen. Beides steht in der ELF-Datei, und beides lässt sich umschreiben.", + what_p1: "Zero Layer liest diese Felder mit goblin und schreibt sie mit elb so um, dass sie auf den echten Linker und die echten Bibliothekspfade deines Systems zeigen. Genau einmal, während der Installation.", + what_p2: "Danach ist die Binärdatei schlicht eine native Binärdatei auf deinem Rechner. Kein Shim, kein Wrapper-Skript, keine Sandbox, kein überwachender Prozess. Daher der Name: die Schicht ist null.", + what_b1: "Kein Container-Runtime, das installiert oder am Laufen gehalten werden muss", + what_b2: "Keine Leistungseinbuße — es ist derselbe Maschinencode", + what_b3: "Dateien landen in normalen, einsehbaren Verzeichnissen", + what_b4: "Alles wird verfolgt, und jede Installation lässt sich zurückrollen", + + phil_eyebrow: "Philosophie", + phil_title: "Sechs Prinzipien hinter jeder Entscheidung", + phil_lede: "Zero Layer bezieht Position. Das sind die Regeln, an denen sich der Code messen lassen muss.", + ph1_t: "Null Overhead nach der Installation", + ph1_d: "Die gesamte Übersetzungsarbeit passiert genau einmal, während der Installation. Danach steht nichts mehr zwischen deinem Programm und dem Kernel.", + ph2_t: "Erkennen, niemals annehmen", + ph2_d: "Architektur, dynamischer Linker, libc, Bibliotheksverzeichnisse und Dateisystemaufbau werden vom laufenden System ermittelt statt fest einprogrammiert.", + ph3_t: "Atomar oder gar nicht", + ph3_d: "Jede Installation läuft in einer Transaktion, die festhält, was sie angefasst hat. Ein Fehler an beliebiger Stelle macht den gesamten Vorgang rückgängig.", + ph4_t: "Eine Binärdatei, kein C", + ph4_d: "redb statt SQLite, elb statt patchelf, rustls statt OpenSSL. Reines Rust heißt: überall bauen und laufen lassen, ohne Toolchain-Suche.", + ph5_t: "Die Quelle wählst du", + ph5_d: "Existiert ein Paket in mehreren Ökosystemen, zeigt Zero Layer alle an und lässt dich wählen. Es entscheidet nie stillschweigend für dich.", + ph6_t: "Standardmäßig umkehrbar", + ph6_d: "Verlauf, Rollback, Waisen-Erkennung und Trockenlauf sind Kernfunktionen, keine Nachgedanken. Du kannst immer sehen, was passiert ist, und es zurücknehmen.", + + how_eyebrow: "So funktioniert's", + how_title: "Was passiert, wenn du install eingibst", + how_lede: "Zwischen deinem Befehl und einer lauffähigen Binärdatei liegen acht Stufen. Jede ist mit -v beobachtbar, und jeder Fehler rollt alles zurück.", + h1_t: "Auflösen", h1_d: "Findet das Paket und durchläuft rekursiv seinen Abhängigkeitsbaum, inklusive Zyklenerkennung. Fehlt eine Abhängigkeit in der Hauptquelle, werden alle anderen aktiven Quellen abgefragt und du wählst.", h1_m: "quellenübergreifend", + h2_t: "Konflikte prüfen", h2_d: "Fünf Kategorien werden geprüft, bevor irgendetwas geschrieben wird: Dateibesitz, Binärnamen, Bibliotheks-Sonames, deklarierte Konflikte und Versionsbedingungen.", h2_m: "5 Konfliktarten", + h3_t: "Herunterladen", h3_d: "Pakete werden direkt aus ihren nativen Repositories über vier parallele Threads geholt, mit Fortschrittsbalken und automatischer Wiederholung mit Backoff.", h3_m: "4 Threads · Retry", + h4_t: "Prüfen", h4_d: "SHA256-Prüfsummen werden erzwungen, GPG-Signaturen geprüft, sofern die Quelle sie liefert. Eine nicht überprüfbare Signatur wird anders gemeldet als eine falsche.", h4_m: "SHA256 + GPG", + h5_t: "Entpacken", h5_d: "Das Archivformat wird erkannt und entpackt — deb, rpm, tar, zst, xz, nar, squashfs, zip oder AppImage — und anschließend auf ein Standard-FHS-Layout normalisiert.", h5_m: "9 Archivformate", + h6_t: "Patchen", h6_d: "Jede ELF-Binärdatei wird analysiert, dann werden Interpreter und RUNPATH passend zu deinem System umgeschrieben. Pakete mit mehreren Binärdateien werden parallel gepatcht; statische bleiben korrekterweise unangetastet.", h6_m: "goblin + elb", + h7_t: "Installieren", h7_d: "Dateien werden atomar innerhalb einer Transaktion abgelegt, die jede erzeugte Datei, jedes Verzeichnis, jeden Symlink und jeden Datenbankeintrag festhält. Jeder Fehler nimmt alles zurück.", h7_m: "atomar · Rollback", + h8_t: "Erfassen", h8_d: "Dateien, Abhängigkeiten, Besitz und der Vorgang selbst werden in eine eingebettete Datenbank geschrieben — genau das macht why, size, doctor und rollback später möglich.", h8_m: "redb + Graph", + + feat_eyebrow: "Funktionsumfang", + feat_title: "Ein vollwertiger Paketmanager, keine Demo", + feat_lede: "Alles, was du von den Werkzeugen deiner Distribution erwartest — und das, was sie nie hatten.", + f1_t: "Native Binärübersetzung", + f1_d: "ELF-Binärdateien werden mit goblin analysiert und bei der Installation mit elb gepatcht. Dynamischer Linker und RUNPATH werden für dein System umgeschrieben, sodass Pakete danach mit voller nativer Geschwindigkeit laufen.", + f2_t: "13 Quellen parallel", + f2_d: "Alle aktiven Quellen werden gleichzeitig abgefragt, Ergebnisse nach Relevanz bewertet und AUR-Binärvarianten automatisch gefunden.", + f3_t: "Atomare Transaktionen", + f3_d: "Eine Installation gelingt vollständig oder hinterlässt keine Spur. Niemals ein halb geschriebener Zustand.", + f4_t: "Diagnose eingebaut", + f4_d: "doctor, audit, why, size, diff und history beantworten die Fragen, bei denen Paketmanager dich sonst raten lassen.", + f5_t: "Mehrere Versionen & Umgebungen", + f5_d: "Installiere Versionen nebeneinander und wechsle zwischen ihnen, oder starte eine flüchtige Umgebung, die beim Verlassen der Shell verschwindet.", + f6_t: "Sicherheitsbewusst", + f6_d: "Prüfsummen und Signaturen beim Hereinkommen, CVE-Abfragen über OSV.dev beim Hinausgehen, dazu Pinning, um alles einzufrieren, was sich nicht bewegen soll.", + + src_eyebrow: "Quellen", + src_title: "Dreizehn Ökosysteme, eine Oberfläche", + src_lede: "Jede Quelle ist ein Plugin, das denselben Trait implementiert. Aktiviere pro Rechner, was du brauchst, oder filtere pro Befehl mit --from.", + src_note: "Ob eine Quelle nutzbar ist, hängt von der Erreichbarkeit des Upstreams ab. Das Repository verfolgt den tatsächlichen Zustand jedes Plugins.", + src_status_link: "Plugin-Status ansehen", + + cmd_eyebrow: "Befehle", + cmd_title: "Die Oberfläche, von A bis Z", + cmd_lede: "Eine Binärdatei, fünfundzwanzig Befehle, Shell-Vervollständigung für bash, zsh und fish.", + cmd_tab1: "Installieren", cmd_tab2: "Suchen", cmd_tab3: "Diagnose", + cmd_tab4: "Verlauf", cmd_tab5: "Umgebungen", + copy: "Kopieren", copied: "Kopiert", + + arch_eyebrow: "Unter der Haube", + arch_title: "Gebaut, um an den richtigen Stellen langweilig zu sein", + arch_lede: "Vorhersehbare Ablage auf der Platte, reine Rust-Abhängigkeiten und eine Testsuite, die bei jedem Push läuft.", + arch_layout_t: "Wo alles landet", + arch_layout_d: "Alles liegt unter einem Verzeichnis, das dir gehört. Nimm bin in den PATH auf — sonst wird nichts am System angefasst.", + arch_stack_t: "Der Stack", + arch_choices_t: "Entwurfsvorgaben", + ac1: "Eine Binärdatei, null C-Abhängigkeiten", + ac2: "RUNPATH statt RPATH, damit LD_LIBRARY_PATH weiterhin greift", + ac3: "Threads statt einer asynchronen Laufzeitumgebung", + ac4: "Alles wird vom laufenden System erkannt", + ac5: "Rollback ist ein erstklassiger Pfad, kein Fehlerfall", + ac6: "Null Clippy-Warnungen, formatiert, durch CI abgesichert", + + cmp_eyebrow: "Vergleich", + cmp_title: "Was es von den Alternativen unterscheidet", + cmp_lede: "Container und universelle Paketformate lösen dasselbe Problem, indem sie Software isolieren. Zero Layer löst es, indem es Software anpasst.", + cmp_c1: "Ansatz", cmp_c2: "Laufzeitkosten", cmp_c3: "Plattenkosten", cmp_c4: "Braucht Daemon", + cmp_r1: "Zero Layer", cmp_r1a: "Binärdateien bei Installation patchen", cmp_r1b: "Keine", cmp_r1c: "Gemeinsame Bibliotheken, dedupliziert", cmp_r1d: "Nein", + cmp_r2a: "Vollständiges OS-Image pro App", cmp_r2b: "Prozess- und Namespace-Overhead", cmp_r2c: "Image-Schichten pro App", cmp_r2d: "Ja", + cmp_r3a: "Mitgelieferte Runtimes", cmp_r3b: "Sandbox und Portal-Umweg", cmp_r3c: "Ein Runtime je App-Familie", cmp_r3d: "Ja", + cmp_r4a: "Squashfs und Confinement", cmp_r4b: "Mount- und Confinement-Schicht", cmp_r4c: "Komprimiertes Image pro App", cmp_r4d: "Ja", + cmp_r5: "Manueller Tarball", cmp_r5a: "Entpacken und hoffen", cmp_r5b: "Keine", cmp_r5c: "Was immer du kopiert hast", cmp_r5d: "Nein", + cmp_foot: "Die manuelle Installation zieht beim Overhead mit Zero Layer gleich — und verliert bei allem anderen: nichts wird erfasst, nichts löst Abhängigkeiten auf, und nichts kann es rückgängig machen.", + + start_eyebrow: "Erste Schritte", + start_title: "In unter einer Minute einsatzbereit", + start_lede: "Ein Download, eine Zeile im Shell-Profil. Man braucht keinen Paketmanager, um den Paketmanager zu installieren.", + s1_t: "Binärdatei installieren", + s1_d: "Hol dir das neueste Release. Nimm die zweite Variante, wenn du auf sudo verzichten willst.", + s2_t: "In den PATH aufnehmen", + s2_d: "Zero Layer verlinkt die installierten ausführbaren Dateien in sein eigenes bin-Verzeichnis.", + s3_t: "Etwas installieren", + s3_d: "Lass --from weg, und Zero Layer durchsucht alle aktiven Quellen und lässt dich wählen.", + start_alt: "Lieber selbst bauen? Erfordert Rust 1.85 oder neuer.", + + faq_eyebrow: "FAQ", + faq_title: "Berechtigte Fragen", + q1: "Ersetzt das den Paketmanager meiner Distribution?", + a1: "Nein, und das ist auch nicht das Ziel. Zero Layer installiert in dein Home-Verzeichnis und fasst niemals Systempfade an, sodass pacman, apt oder dnf das Grundsystem weiterhin genau wie bisher verwalten. Nutze es für Software, die deine Distribution nicht paketiert.", + q2: "Brauche ich root?", + a2: "Nein. Die Standardinstallation liegt vollständig unter ~/.local/share/zl. Root ist nur relevant, wenn du die Binärdatei zl selbst nach /usr/local/bin legen willst — und auch das ist optional.", + q3: "Ist es wirklich ohne Overhead?", + a3: "Ja, denn nach der Installation läuft nichts mehr mit. Die gepatchte Binärdatei ist gewöhnlicher Maschinencode, den der Kernel direkt ausführt — keine Sandbox, kein Supervisor, keine Übersetzung zur Laufzeit. Die Arbeit passiert einmal, beim Installieren.", + q4: "Was, wenn ein Paket eine Bibliothek braucht, die ich nicht habe?", + a4: "Abhängigkeiten werden rekursiv aufgelöst, bevor irgendetwas heruntergeladen wird, und fehlt eine in der Hauptquelle, wird in allen anderen aktiven Quellen gesucht. Nach der Installation warnt eine Nachprüfung vor jeder gemeinsamen Bibliothek, die weiterhin nicht auffindbar ist.", + q5: "Was passiert, wenn eine Installation auf halbem Weg scheitert?", + a5: "Es bleibt nichts zurück. Jede Installation läuft in einer Transaktion, die erzeugte Dateien, Verzeichnisse, Symlinks und Datenbankeinträge festhält, und jeder Fehler nimmt sie alle zurück. Du kannst jeden Vorgang außerdem mit --dry-run vorab ansehen.", + q6: "Welche Distributionen werden unterstützt?", + a6: "Im Prinzip alle. Statt eine Liste zu pflegen, erkennt Zero Layer zur Laufzeit Architektur, dynamischen Linker, libc, Bibliotheksverzeichnisse und Dateisystemaufbau — einschließlich merged-usr, NixOS, Guix, GoboLinux und Termux.", + q7: "Ist es produktionsreif?", + a7: "Es ist junge Software in aktiver Entwicklung und sagt das offen: Das Repository hält fest, welche Quell-Plugins gegen ihre echten Upstreams verifiziert sind und welche noch repariert werden. Der zentrale Installationspfad ist durch 349 Tests abgedeckt, die jeden Commit absichern.", + q8: "Wie werde ich es wieder los?", + a8: "Lösche das Verzeichnis. Alles, was Zero Layer installiert — Pakete, Datenbank, Cache, Symlinks — liegt in einem einzigen Ordner; ihn zu entfernen beseitigt jede Spur.", + + cta_title: "Installiere alles, auf allem", + cta_p: "Kostenlos und quelloffen unter der MIT-Lizenz. Kein Konto, keine Telemetrie, kein Daemon.", + cta_b1: "Neuestes Release herunterladen", + cta_b2: "Auf GitHub mit Stern versehen", + + foot_about: "Ein universeller Linux-Paketmanager mit nativer Binärübersetzung. Installiere aus jeder Quelle, auf jeder Distribution, ohne Laufzeit-Overhead.", + foot_c1: "Projekt", foot_c2: "Ressourcen", foot_c3: "Community", + foot_readme: "Dokumentation", foot_releases: "Releases", foot_status: "Plugin-Status", foot_license_l: "Lizenz", + foot_issues: "Problem melden", foot_discussions: "Diskussionen", foot_contribute: "Mitwirken", foot_source: "Quellcode", + foot_builtby: "Erstellt von", foot_license: "Veröffentlicht unter der MIT-Lizenz.", + foot_madewith: "Geschrieben in Rust." + } +}; diff --git a/docs/site/assets/js/main.js b/docs/site/assets/js/main.js new file mode 100644 index 0000000..f798839 --- /dev/null +++ b/docs/site/assets/js/main.js @@ -0,0 +1,358 @@ +/* ========================================================================== + Zero Layer — site behaviour + Theme, language, navigation, tabs, copy buttons, terminal demo, reveals. + ========================================================================== */ + +(function () { + 'use strict'; + + var SUPPORTED = ['en', 'it', 'fr', 'es', 'de']; + var DEFAULT_LANG = 'en'; + var reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches; + + function $(sel, root) { return (root || document).querySelector(sel); } + function $$(sel, root) { return Array.prototype.slice.call((root || document).querySelectorAll(sel)); } + function store(key, val) { try { if (val === undefined) return localStorage.getItem(key); localStorage.setItem(key, val); } catch (e) { return null; } } + + /* ---------------------------------------------------------------- Theme */ + + function setTheme(theme) { + document.documentElement.setAttribute('data-theme', theme); + var meta = $('#theme-color-meta'); + if (meta) meta.setAttribute('content', theme === 'light' ? '#fbfbfd' : '#07070b'); + var btn = $('#theme-toggle'); + if (btn) btn.setAttribute('aria-pressed', theme === 'light' ? 'true' : 'false'); + store('zl-theme', theme); + } + + function initTheme() { + var btn = $('#theme-toggle'); + if (!btn) return; + btn.addEventListener('click', function () { + var current = document.documentElement.getAttribute('data-theme') === 'light' ? 'light' : 'dark'; + setTheme(current === 'light' ? 'dark' : 'light'); + }); + } + + /* ------------------------------------------------------------- Language */ + + function translate(lang) { + var dict = window.ZL_I18N[lang] || window.ZL_I18N[DEFAULT_LANG]; + var fallback = window.ZL_I18N[DEFAULT_LANG]; + + $$('[data-i18n]').forEach(function (el) { + var key = el.getAttribute('data-i18n'); + var value = dict[key] !== undefined ? dict[key] : fallback[key]; + if (value === undefined) return; + // Keys ending in _html may carry inline markup (, ). + if (/_(p1|p2|html)$/.test(key) || /^a[0-9]+$/.test(key)) el.innerHTML = value; + else el.textContent = value; + }); + + $$('[data-i18n-attr]').forEach(function (el) { + // Format: "aria-label:nav_menu" — attribute name, then key. + el.getAttribute('data-i18n-attr').split(',').forEach(function (pair) { + var parts = pair.split(':'); + var attr = parts[0].trim(); + var key = parts[1].trim(); + var value = dict[key] !== undefined ? dict[key] : fallback[key]; + if (value !== undefined) el.setAttribute(attr, value); + }); + }); + + document.documentElement.lang = lang; + var desc = $('meta[name="description"]'); + if (desc && dict.meta_desc) desc.setAttribute('content', dict.meta_desc); + + var select = $('#lang-select'); + if (select) select.value = lang; + store('zl-lang', lang); + resetCopyLabels(); + } + + function initLang() { + var lang = store('zl-lang'); + var param = new URLSearchParams(window.location.search).get('lang'); + if (param && SUPPORTED.indexOf(param) !== -1) lang = param; + if (!lang || SUPPORTED.indexOf(lang) === -1) { + var browser = (navigator.language || DEFAULT_LANG).slice(0, 2).toLowerCase(); + lang = SUPPORTED.indexOf(browser) !== -1 ? browser : DEFAULT_LANG; + } + translate(lang); + + var select = $('#lang-select'); + if (select) select.addEventListener('change', function (e) { translate(e.target.value); }); + } + + /* ------------------------------------------------------------------ Nav */ + + function initNav() { + var nav = $('#nav'); + var progress = $('#nav-progress'); + var links = $('#nav-links'); + var menuBtn = $('#menu-btn'); + + function onScroll() { + var y = window.scrollY; + if (nav) nav.classList.toggle('is-scrolled', y > 8); + if (progress) { + var max = document.documentElement.scrollHeight - window.innerHeight; + progress.style.width = (max > 0 ? (y / max) * 100 : 0) + '%'; + } + } + window.addEventListener('scroll', onScroll, { passive: true }); + onScroll(); + + if (menuBtn && links) { + menuBtn.addEventListener('click', function () { + var open = links.classList.toggle('is-open'); + menuBtn.setAttribute('aria-expanded', open ? 'true' : 'false'); + }); + $$('a', links).forEach(function (a) { + a.addEventListener('click', function () { + links.classList.remove('is-open'); + menuBtn.setAttribute('aria-expanded', 'false'); + }); + }); + document.addEventListener('keydown', function (e) { + if (e.key === 'Escape' && links.classList.contains('is-open')) { + links.classList.remove('is-open'); + menuBtn.setAttribute('aria-expanded', 'false'); + menuBtn.focus(); + } + }); + } + } + + /* ----------------------------------------------------------------- Tabs */ + + function initTabs() { + $$('[data-tabs]').forEach(function (group) { + var tabs = $$('[role="tab"]', group); + var panels = $$('[role="tabpanel"]', group); + + function select(index) { + tabs.forEach(function (tab, i) { + var active = i === index; + tab.setAttribute('aria-selected', active ? 'true' : 'false'); + tab.tabIndex = active ? 0 : -1; + }); + panels.forEach(function (panel, i) { panel.hidden = i !== index; }); + } + + tabs.forEach(function (tab, i) { + tab.addEventListener('click', function () { select(i); }); + tab.addEventListener('keydown', function (e) { + var next = null; + if (e.key === 'ArrowRight') next = (i + 1) % tabs.length; + if (e.key === 'ArrowLeft') next = (i - 1 + tabs.length) % tabs.length; + if (e.key === 'Home') next = 0; + if (e.key === 'End') next = tabs.length - 1; + if (next !== null) { e.preventDefault(); select(next); tabs[next].focus(); } + }); + }); + select(0); + }); + } + + /* --------------------------------------------------------- Copy buttons */ + + function resetCopyLabels() { + $$('.copy-btn').forEach(function (btn) { + if (btn.classList.contains('is-copied')) return; + var label = $('[data-i18n="copy"]', btn); + if (label) { + var lang = document.documentElement.lang; + var dict = window.ZL_I18N[lang] || window.ZL_I18N[DEFAULT_LANG]; + label.textContent = dict.copy; + } + }); + } + + function initCopy() { + $$('.copy-btn').forEach(function (btn) { + btn.addEventListener('click', function () { + var targetSel = btn.getAttribute('data-copy-target'); + var text = targetSel ? ($(targetSel) || {}).innerText : btn.getAttribute('data-copy'); + if (!text) return; + text = text.replace(/^\s*\$\s?/gm, '').trim(); + + var done = function () { + var lang = document.documentElement.lang; + var dict = window.ZL_I18N[lang] || window.ZL_I18N[DEFAULT_LANG]; + var label = $('[data-i18n="copy"]', btn); + btn.classList.add('is-copied'); + if (label) label.textContent = dict.copied; + setTimeout(function () { + btn.classList.remove('is-copied'); + if (label) label.textContent = dict.copy; + }, 1800); + }; + + if (navigator.clipboard && navigator.clipboard.writeText) { + navigator.clipboard.writeText(text).then(done).catch(function () {}); + } else { + var ta = document.createElement('textarea'); + ta.value = text; + ta.style.position = 'fixed'; + ta.style.opacity = '0'; + document.body.appendChild(ta); + ta.select(); + try { document.execCommand('copy'); done(); } catch (e) {} + document.body.removeChild(ta); + } + }); + }); + } + + /* -------------------------------------------------------- Terminal demo */ + + var TERMINAL_SCRIPT = [ + { t: 'cmd', text: 'zl install ripgrep' }, + { t: 'comment', text: '# no --from: every enabled source is queried' }, + { t: 'dim', text: ' ? Found in 4 sources — pacman, apt, nix, github' }, + { t: 'ok', text: ' ✓ Resolved 3 dependencies, no conflicts' }, + { t: 'dim', text: ' [1/4] Downloading ████████████████ 2.4 MB/s' }, + { t: 'ok', text: ' [2/4] Verified SHA256 + GPG signature' }, + { t: 'ok', text: ' [3/4] Patched 1 ELF interpreter + RUNPATH' }, + { t: 'ok', text: ' [4/4] Installed ripgrep 14.1.1 [8 files, 5.1 MB]' }, + { t: 'blank', text: '' }, + { t: 'cmd', text: 'rg --version' }, + { t: 'dim', text: 'ripgrep 14.1.1' }, + { t: 'comment', text: '# a native binary — nothing wrapping it' } + ]; + + function renderLine(entry) { + var div = document.createElement('div'); + div.className = 'line'; + if (entry.t === 'blank') { div.innerHTML = ' '; return div; } + if (entry.t === 'cmd') { + div.innerHTML = '$ ' + escapeHtml(entry.text); + } else { + div.className = 'line ' + entry.t; + div.textContent = entry.text; + } + return div; + } + + function escapeHtml(s) { + return s.replace(/[&<>]/g, function (c) { return ({ '&': '&', '<': '<', '>': '>' })[c]; }); + } + + function initTerminal() { + var body = $('#terminal-body'); + if (!body) return; + + if (reduceMotion) { + TERMINAL_SCRIPT.forEach(function (entry) { body.appendChild(renderLine(entry)); }); + return; + } + + var started = false; + var observer = new IntersectionObserver(function (entries) { + entries.forEach(function (entry) { + if (!entry.isIntersecting || started) return; + started = true; + observer.disconnect(); + play(); + }); + }, { threshold: 0.25 }); + observer.observe(body); + + function play() { + var i = 0; + var cursor = document.createElement('span'); + cursor.className = 'cursor'; + + function step() { + if (i >= TERMINAL_SCRIPT.length) { + body.appendChild(cursor); + return; + } + var entry = TERMINAL_SCRIPT[i++]; + if (cursor.parentNode) cursor.parentNode.removeChild(cursor); + body.appendChild(renderLine(entry)); + body.appendChild(cursor); + body.scrollTop = body.scrollHeight; + setTimeout(step, entry.t === 'cmd' ? 620 : entry.t === 'blank' ? 260 : 400); + } + step(); + } + } + + /* ---------------------------------------------------------- Stat counts */ + + function initCounters() { + var nums = $$('[data-count]'); + if (!nums.length) return; + + if (reduceMotion) { + nums.forEach(function (el) { el.textContent = el.getAttribute('data-count') + (el.getAttribute('data-suffix') || ''); }); + return; + } + + var observer = new IntersectionObserver(function (entries) { + entries.forEach(function (entry) { + if (!entry.isIntersecting) return; + var el = entry.target; + observer.unobserve(el); + var target = parseInt(el.getAttribute('data-count'), 10); + var suffix = el.getAttribute('data-suffix') || ''; + var start = performance.now(); + var duration = 1100; + + function tick(now) { + var p = Math.min((now - start) / duration, 1); + var eased = 1 - Math.pow(1 - p, 3); + el.textContent = Math.round(target * eased) + suffix; + if (p < 1) requestAnimationFrame(tick); + } + requestAnimationFrame(tick); + }); + }, { threshold: 0.5 }); + + nums.forEach(function (el) { observer.observe(el); }); + } + + /* -------------------------------------------------------------- Reveals */ + + function initReveals() { + var items = $$('.reveal, .reveal-stagger'); + if (!items.length) return; + if (reduceMotion) { items.forEach(function (el) { el.classList.add('is-visible'); }); return; } + + var observer = new IntersectionObserver(function (entries) { + entries.forEach(function (entry) { + if (!entry.isIntersecting) return; + entry.target.classList.add('is-visible'); + observer.unobserve(entry.target); + }); + }, { threshold: 0.12, rootMargin: '0px 0px -48px 0px' }); + + items.forEach(function (el) { observer.observe(el); }); + } + + /* ----------------------------------------------------------------- Year */ + + function initYear() { + var el = $('#year'); + if (el) el.textContent = String(new Date().getFullYear()); + } + + /* ------------------------------------------------------------------ Boot */ + + function boot() { + initTheme(); + initLang(); + initNav(); + initTabs(); + initCopy(); + initTerminal(); + initCounters(); + initReveals(); + initYear(); + } + + if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', boot); + else boot(); +})(); diff --git a/docs/site/index.html b/docs/site/index.html index a8b5a94..a968f78 100644 --- a/docs/site/index.html +++ b/docs/site/index.html @@ -1,827 +1,99 @@ - + - - - Zero Layer — Universal Linux Package Manager - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +Zero Layer — Universal Linux Package Manager + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -
+ + - - - - -
- - -
-
-
- - Open Source — MIT License -
-
-

- One command.
- Any package. Any distro. + + + +
+ + + +
+
+ v0.2 — Open source, MIT licensed +

+ One command.
+ Any package. Any distro.

-

- Zero Layer is a universal Linux package manager that translates binaries natively at install time. No containers, no VMs, zero runtime overhead. Written in Rust. +

+ Zero Layer is a universal Linux package manager. It installs software from 13 different ecosystems onto any distribution by translating binaries at install time — not at run time.

-
- - - Download + + - -
-
- - - +
+ $ + curl -Lo zl https://github.com/supercosti21/zero_layer/releases/latest/download/zl-x86_64-unknown-linux-gnu + +
+
+ +
+
+ + zsh — zero layer +
+ +
+ +
+
+ 13 + package sources +
+
+ 0ms + runtime overhead +
+
+ 349 + tests, CI green +
+
+ 0 + C dependencies +
+
+
+ + +
+
+
+ The problem +

Linux packaging is fragmented by design

+

Every distribution ships its own format, its own repository and its own idea of where files belong. The software you want is often packaged — just not for your system.

+
+ +
+
+
+

The package exists, but not for you

+

A tool is in the AUR, or only as a .deb, or only as a GitHub release. Your distro packaged it two years ago, or never.

+
+
+
+

The workarounds cost you performance

+

Containers, virtual machines and compatibility layers all solve this by adding a layer. You pay for it forever.

+
+
+
+

Manual installs rot silently

+

Dropping a tarball into /opt works until a library moves. Nothing tracks the files, and nothing can cleanly undo it.

+
+
+
+
+ + +
+
+
+
+ The idea +

Translate once, at install time

+

A Linux binary is not tied to a distribution — it is tied to a handful of concrete facts: which dynamic linker loads it, and where its shared libraries live.

+

Zero Layer reads those fields with goblin, then rewrites them with elb.

+

After that the binary is simply a native binary on your machine.

+ +
    +
  • No container runtime to install or keep running
  • +
  • No performance penalty — it is the same machine code
  • +
  • Files land in normal directories you can inspect
  • +
  • Everything is tracked, and every install can be rolled back
  • +
-
-
$ zl install firefox --from pacman
-
# An Arch package on Ubuntu? No problem.
-
$ zl install sharkdp/bat --from github
-
✓ Downloaded bat-v0.24.0-x86_64-unknown-linux-gnu.tar.gz
-
✓ Patched 1 ELF binary (interpreter + RUNPATH)
-
✓ Installed bat 0.24.0 [3 files, 2.1 MB]
-
$ zl search vim --from pacman,apt,nix
-
# Search across 13 sources simultaneously
+ +
+
# the ELF fields Zero Layer rewrites
+
+── before ── (built for Arch)
+PT_INTERP  /lib64/ld-linux-x86-64.so.2
+RUNPATH    (none)
+NEEDED     libpcre2-8.so.0, libc.so.6
+
+── after ──  (patched for this host)
+PT_INTERP  /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
+RUNPATH    ~/.local/share/zl/lib
+NEEDED     libpcre2-8.so.0, libc.so.6
+
+# same machine code — it just knows
+# where it lives now
-
- - -
-
- -

Everything you need

-

- A single binary that replaces containers, VMs, and compatibility layers. Install anything, anywhere. -

+
+
+ + +
+
+
+ Philosophy +

Six principles behind every decision

+

Zero Layer is opinionated. These are the rules the codebase is held to.

+
+ +
+
+
+

Zero overhead after install

+

All translation work happens once, during installation.

+
+
+
+

Detect, never assume

+

Architecture, linker, libc and layout are probed from the running system.

+
+
+
+

Atomic or nothing

+

Every install runs inside a transaction that records what it touched.

+
+
+
+

One binary, no C

+

redb instead of SQLite, elb instead of patchelf, rustls instead of OpenSSL.

+
+
+
+

The user picks the source

+

When a package exists in several ecosystems, you choose.

+
+
+
+

Reversible by default

+

History, rollback, orphan detection and dry-run are core features.

+
+
+
+
+ + +
+
+
+ How it works +

What happens when you type install

+

Eight stages run between your command and a working binary. Each one is observable with -v, and any failure rolls the whole thing back.

-
-
-
-

Native Binary Translation

-

ELF binaries are analyzed with goblin and patched with elb at install time. The dynamic linker and RUNPATH are set to match your system. Packages then run at full native speed with zero overhead.

+
+
+

Resolve

Finds the package and walks its dependency tree recursively.

cross-source resolution
+
+
+

Check conflicts

Five classes are checked before anything is written.

5 conflict types
-
-
-

13 Package Sources

-

pacman, apt, dnf, AUR, Nix, Flatpak, Snap, AppImage, GitHub Releases, and more — all queried in parallel.

+
+

Download

Packages are fetched over four parallel threads with automatic retry.

4 threads · retry
-
-
🔎
-

Smart Search

-

Relevance-scored results across every source. Exact matches highlighted, AUR binary variants auto-discovered.

+
+

Verify

SHA256 checksums are enforced and GPG signatures checked.

SHA256 + GPG
-
-
🔒
-

Atomic Transactions

-

Every install is wrapped in a transaction. If anything fails, everything rolls back — no half-installed packages.

+
+

Extract

The archive format is detected, unpacked and normalised to FHS.

9 archive formats
-
-
🔍
-

Cross-Source Dependencies

-

Dependencies missing from the primary source are searched automatically across every other enabled source.

+
+

Patch

Interpreter and RUNPATH are rewritten to match your system.

goblin + elb
-
-
🛠
-

Full Diagnostics

-

doctor, audit, diff, size, history, rollback, why — everything you need to understand and manage your packages.

+
+

Install

Files are placed atomically inside a transaction.

atomic · rollback
+
+
+

Track

Files, dependencies and the operation are written to an embedded database.

redb + graph
-
- - -
-
- -

13 sources, one interface

-

Install from any Linux repository or release platform — Zero Layer handles the translation.

+
+
+ + +
+
+
+ Capabilities +

A complete package manager, not a demo

+

Everything you would expect from your distro's tooling, plus the things it never had.

-
- pacman - AUR - apt - dnf - zypper - apk - xbps - portage - nix - flatpak - snap - appimage - github + +
+
+
+

Native binary translation

+

ELF binaries are analysed with goblin and patched with elb at install time.

+
goblinelbPT_INTERPRUNPATH
+
+
+
+

13 sources in parallel

+

Every enabled source is queried simultaneously and scored by relevance.

+
+
+
🔒
+

Atomic transactions

+

An install either completes or leaves no trace.

+
+
+
🛠
+

Diagnostics built in

+

doctor, audit, why, size, diff and history answer the questions package managers usually leave you guessing about.

+
zl doctorzl whyzl sizezl auditzl diff
+
+
+
+

Multi-version & environments

+

Install versions side by side, or spin up an ephemeral environment.

+
+
+
🛡
+

Security aware

+

Checksums and signatures in, CVE lookups against OSV.dev out.

+
-
- - -
-
- -

Install in 4 steps

-

All translation happens at install time. After that, binaries run at full native speed.

+
+
+ + +
+
+
+ Sources +

Thirteen ecosystems, one interface

+

Each source is a plugin implementing the same trait. Enable the ones you want per machine, or filter per command with --from.

-
-
-

Download

-

Parallel downloads (4 threads) with progress bars, retries, and SHA256 verification. Packages are fetched straight from their native repositories.

+ +
+
pacmanArch Linux
+
aurArch User Repository
+
aptDebian · Ubuntu
+
dnfFedora · RHEL
+
zypperopenSUSE · SLES
+
apkAlpine Linux
+
xbpsVoid Linux
+
portageGentoo binhost
+
nixnixpkgs
+
flatpakFlathub
+
snapSnapcraft Store
+
appimageAppImageHub
+
githubGitHub Releases
+
+ +

+ Source availability depends on the upstream being reachable. + See live plugin status +

+
+
+ + +
+
+
+ Commands +

The interface, end to end

+

One binary, twenty-five commands, shell completions for bash, zsh and fish.

+
+ +
+
+ + + + +
-
-

Verify

-

SHA256 checksums and GPG signatures are checked. The archive format is detected and extracted — deb, rpm, tar, nar, squashfs, zip, or AppImage.

+ +
+ + +
+
$ zl install firefox                 # pick from every source
+$ zl install firefox --from pacman   # force one source
+$ zl install sharkdp/bat --from github
+$ zl install python --version 3.12  # side by side
+$ zl remove firefox --cascade       # drop orphaned deps
+$ zl --dry-run install firefox     # preview only
+$ zl run neofetch                   # run without installing
+
+ + + + + + + + +
+
+
+
+ + +
+
+
+ Under the hood +

Built to be boring in the right places

+

Predictable layout on disk, pure-Rust dependencies, and a test suite that runs on every push.

+
+ +
+
+

Where things land

+

Everything lives under one directory you own. Add bin to your PATH and nothing else on the system is touched.

+

Design constraints

+
    +
  • Single binary with zero C dependencies
  • +
  • RUNPATH over RPATH, so LD_LIBRARY_PATH still works
  • +
  • Threads instead of an async runtime
  • +
  • Everything auto-detected from the running system
  • +
  • Rollback is a first-class path, not an error case
  • +
  • Zero clippy warnings, formatted, CI-gated
  • +
-
-

Patch

-

Every ELF binary is analyzed with goblin. The dynamic linker (PT_INTERP) and library path (RUNPATH) are patched to match your system with elb — in parallel for multi-binary packages.

+ +
+
~/.local/share/zl/
+  bin/        symlinks — add to PATH
+  lib/        shared libraries
+  share/      data files
+  etc/        configuration
+  packages/   one dir per name-version
+  cache/      downloads
+  envs/       ephemeral environments
+  zl.redb     package database
+
+# nothing outside this tree is modified
+# removing the folder removes everything
-
-

Install

-

Files are placed atomically inside a transaction. If anything fails, everything rolls back. Dependencies, files, and history are tracked in a redb database.

+
+ +
+

The stack

+
+ Rust 2024goblinelbredb + petgraphclapreqwest + rustlsindicatif + quick-xmlsha2zstdtarcpio
-
- - -
-
- -

Built with Rust

-

Single binary, zero C dependencies. Pure Rust from ELF parsing to database storage.

+
+
+ + +
+
+
+ Comparison +

How it differs from the alternatives

+

Containers and universal package formats solve the same problem by isolating software. Zero Layer solves it by adapting software.

-
- -
🦀
-

Rust

-

Memory-safe, fast, single binary. Edition 2024 with zero unsafe code in the main crate.

-
- -
👁
-

goblin + elb

-

Pure Rust ELF analysis and binary patching. Read metadata, set the interpreter and RUNPATH.

-
- -
🗃
-

redb

-

Embedded key-value database. ACID transactions, pure Rust — no SQLite, no C dependencies.

-
-
-
📈
-

petgraph

-

Dependency graph with topological sort, cycle detection, and orphan analysis.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ApproachRuntime costDisk costNeeds a daemon
Zero LayerPatch binaries at installNoneShared libraries, deduplicatedNo
Docker / PodmanFull OS image per appProcess + namespace overheadImage layers per appYes
FlatpakBundled runtimesSandbox + portal indirectionRuntime per app familyYes
SnapSquashfs + confinementMount + confinement layerCompressed image per appYes
Manual tarballUnpack and hopeNoneWhatever you copiedNo
+
+

+ Manual installs match Zero Layer on overhead — and lose on everything else. +

+
+
+ + +
+
+
+ Get started +

Running in under a minute

+

One download, one line in your shell profile. No package manager needed to install the package manager.

+
+ +
+
+

1Install the binary

+

Grab the latest release. Use the second form if you would rather not use sudo.

+
+ +
$ curl -Lo zl https://github.com/supercosti21/zero_layer/releases/latest/download/zl-x86_64-unknown-linux-gnu
+$ chmod +x zl && sudo mv zl /usr/local/bin/
+
+# or, without sudo:
+$ mkdir -p ~/.local/bin && mv zl ~/.local/bin/
+
-
-
💻
-

clap

-

CLI parsing with derive macros. Shell completions for bash, zsh, and fish.

+ +
+

2Put it on your PATH

+

Zero Layer symlinks the executables it installs into its own bin directory.

+
+ +
# bash (~/.bashrc) or zsh (~/.zshrc)
+export PATH="$HOME/.local/share/zl/bin:$PATH"
+
+# fish
+fish_add_path ~/.local/share/zl/bin
+
-
-
📦
-

349 Tests

-

Comprehensive unit tests across all core modules. CI runs fmt, clippy, and tests on every push.

+ +
+

3Install something

+

Leave off --from and Zero Layer will search every enabled source and let you pick.

+
+ +
$ zl install ripgrep
+$ zl install sharkdp/bat --from github
+$ zl doctor                # confirm everything is healthy
+
-
- - -
-
-

Ready to try Zero Layer?

-

Grab the latest release and you're up and running. Works on any Linux distro.

- +
+ + +
+
+
+ FAQ +

Reasonable questions

+
+ +
+
+ Does this replace my distro's package manager? +
No, and it does not try to.
+
+
+ Do I need root? +
No.
+
+
+ Is it really zero overhead? +
Yes.
+
+
+ What if a package needs a library I do not have? +
Dependencies are resolved recursively.
+
+
+ What happens when an install fails halfway? +
Nothing is left behind.
+
+
+ Which distributions does it support? +
Any of them, in principle.
+
+
+ Is it production ready? +
It is early software under active development.
+
+
+ How do I get rid of it? +
Delete the directory.
+
+
+
+
+ + +
+
+
+

Install anything, on anything

+

Free and open source under the MIT licence. No account, no telemetry, no daemon.

+
-
+

+ - + - -