redesign website to black and bone, add user contact

This commit is contained in:
Astral
2026-09-01 11:39:33 +02:00
parent da28f784a8
commit 0e8885c162
18 changed files with 996 additions and 284 deletions
+7
View File
@@ -13,6 +13,7 @@
<h4>Install</h4> <h4>Install</h4>
<ul> <ul>
<li><a href="./install.html">Install Keru</a></li> <li><a href="./install.html">Install Keru</a></li>
<li><a href="./getting-started.html">Getting started</a></li>
<li><a href="./installer-walkthrough.html">Installer walkthrough</a></li> <li><a href="./installer-walkthrough.html">Installer walkthrough</a></li>
<li><a href="./installation-requirements.html">Requirements</a></li> <li><a href="./installation-requirements.html">Requirements</a></li>
<li><a href="./network-setup.html">Network setup</a></li> <li><a href="./network-setup.html">Network setup</a></li>
@@ -44,7 +45,13 @@
<li><a href="./docs.html">Docs home</a></li> <li><a href="./docs.html">Docs home</a></li>
<li><a href="./make-conf.html">make.conf</a></li> <li><a href="./make-conf.html">make.conf</a></li>
<li><a href="./recipe-format.html">Recipe format</a></li> <li><a href="./recipe-format.html">Recipe format</a></li>
<li><a href="./recipe-authoring.html">Recipe authoring</a></li>
<li><a href="./build-pipeline.html">Build pipeline</a></li> <li><a href="./build-pipeline.html">Build pipeline</a></li>
<li><a href="./toolchain.html">Toolchain bootstrap</a></li>
<li><a href="./kama-config.html">Kama config</a></li>
<li><a href="./mirror-cache.html">Mirrors &amp; cache</a></li>
<li><a href="./security.html">Security</a></li>
<li><a href="./troubleshooting.html">Troubleshooting</a></li>
<li><a href="./live-init.html">Live init</a></li> <li><a href="./live-init.html">Live init</a></li>
</ul> </ul>
</div> </div>
+329 -251
View File
@@ -1,60 +1,55 @@
/* Keru OS website — dark, modern, animated. /* Keru OS website — Ryoku-style.
Reference: Gentoo's confident tech look, modernized. */ Pure-black paper, warm bone ink, one vermillion accent.
Radius 0. No shadow. Flat hairline surfaces. Monospace tech labels.
Animations are loud enough to feel alive, flat enough to stay cool. */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;700&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;700&display=swap');
:root { :root {
--bg: #0a0e14; /* near-black blue */ --paper: #000000; /* pure black paper */
--bg-2: #0f1520; /* raised surface */ --paper-2: #0d0d0d; /* raised surface */
--bg-3: #161e2e; /* cards */ --paper-3: #131313; /* cards */
--border: #22304a; --hair: #262626; /* hairline borders */
--text: #d7e0ee; --ink: #cdc4ba; /* warm bone ink — body */
--text-dim: #8b9bb4; --ink-dim: #8b8275; /* subdued ink */
--text-bright: #ffffff; --ink-faint: #5b5348; /* farthest faded */
--accent: #8b5cf6; /* keru violet */ --bone: #f2ede4; /* bright ink, emphasis */
--accent-2: #22d3ee; /* cyan secondary */ --accent: #ff3b1f; /* vermillion — the single accent */
--accent-3: #34d399; /* green success */ --ok: #58e1c2;
--warn: #f59e0b; /* amber */ --warn: #f0a35e;
--danger: #ef4444; --danger: #ff3b1f;
--code-bg: #0d1220;
--mono: 'JetBrains Mono', ui-monospace, monospace; --mono: 'JetBrains Mono', ui-monospace, monospace;
--sans: 'Inter', system-ui, -apple-system, sans-serif; --sans: 'Inter', system-ui, -apple-system, sans-serif;
--grad: linear-gradient(135deg, var(--accent), var(--accent-2)); --radius: 0; /* sharp. always. */
--shadow: 0 8px 30px rgba(0,0,0,.4); --nav-h: 60px;
--radius: 12px;
--nav-h: 64px;
} }
* { margin: 0; padding: 0; box-sizing: border-box; } * { margin: 0; padding: 0; box-sizing: border-box; }
::selection { background: var(--accent); color: #000; }
html { scroll-behavior: smooth; } html { scroll-behavior: smooth; }
body { body {
background: var(--bg); background: var(--paper);
color: var(--text); color: var(--ink);
font-family: var(--sans); font-family: var(--sans);
line-height: 1.65; line-height: 1.65;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
overflow-x: hidden; overflow-x: hidden;
} }
/* subtle animated grid backdrop */ /* faint scanline texture — a taste of grain, no image */
body::before { body::before {
content: ""; content: "";
position: fixed; position: fixed;
inset: 0; inset: 0;
z-index: -1; z-index: -1;
background: background:
radial-gradient(circle at 20% -10%, rgba(139,92,246,.12), transparent 45%), repeating-linear-gradient(180deg, transparent 0 3px, rgba(255,255,255,.008) 3px 4px);
radial-gradient(circle at 90% 10%, rgba(34,211,238,.08), transparent 40%),
repeating-linear-gradient(0deg, transparent 0 39px, rgba(255,255,255,.02) 39px 40px);
pointer-events: none; pointer-events: none;
} }
a { color: var(--accent-2); text-decoration: none; } a { color: var(--ink); text-decoration: none; }
a:hover { text-decoration: underline; } a:hover { color: var(--bone); }
::selection { background: var(--accent); color: #fff; }
/* ---------- top nav ---------- */ /* ---------- top nav ---------- */
nav.top { nav.top {
@@ -62,372 +57,455 @@ nav.top {
top: 0; top: 0;
z-index: 100; z-index: 100;
height: var(--nav-h); height: var(--nav-h);
background: rgba(10,14,20,.82); background: rgba(0,0,0,.9);
backdrop-filter: blur(12px); backdrop-filter: blur(8px);
border-bottom: 1px solid var(--border); border-bottom: 1px solid var(--hair);
display: flex; display: flex;
align-items: center; align-items: center;
padding: 0 28px; padding: 0 26px;
gap: 8px; gap: 4px;
} }
.brand { .brand {
font-family: var(--mono); font-family: var(--mono);
font-weight: 700; font-weight: 700;
color: var(--text-bright); color: var(--bone);
font-size: 1.05rem; font-size: 1rem;
letter-spacing: .02em; letter-spacing: .02em;
margin-right: auto; margin-right: auto;
display: flex; display: flex;
align-items: center; align-items: center;
gap: 8px; gap: 9px;
}
.brand .kanji {
color: var(--accent);
font-size: 1.15rem;
text-shadow: 0 0 14px rgba(255,59,31,.55);
} }
.brand .kanji { color: var(--accent); }
.brand:hover { text-decoration: none; } .brand:hover { text-decoration: none; }
nav.top a.navlink { nav.top a.navlink {
color: var(--text-dim); color: var(--ink-dim);
font-size: .92rem; font-family: var(--mono);
font-weight: 500; text-transform: uppercase;
font-size: .72rem;
letter-spacing: .12em;
padding: 6px 10px; padding: 6px 10px;
border-radius: 6px; border: 1px solid transparent;
transition: color .15s, background .15s; transition: color .15s, border-color .15s, background .15s;
}
nav.top a.navlink:hover {
color: var(--bone);
border-color: var(--hair);
background: var(--paper-2);
text-decoration: none;
} }
nav.top a.navlink:hover { color: var(--text-bright); background: var(--bg-3); text-decoration: none; }
.menu-toggle { display: none; } .menu-toggle { display: none; }
/* ---------- hero ---------- */ /* ---------- hero ---------- */
.hero { .hero { padding: 84px 26px 54px; text-align: center; }
padding: 96px 28px 64px;
text-align: center;
animation: fadeUp .7s ease both;
}
.kicker { .kicker {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
gap: 8px; gap: 10px;
font-family: var(--mono); font-family: var(--mono);
color: var(--accent-2); color: var(--ink-dim);
border: 1px solid var(--border);
background: var(--bg-2);
padding: 4px 12px;
border-radius: 999px;
font-size: .8rem;
letter-spacing: .08em;
text-transform: uppercase; text-transform: uppercase;
font-size: .72rem;
letter-spacing: .22em;
border: 1px solid var(--hair);
background: var(--paper-2);
padding: 5px 14px;
} }
.kicker .dot { .kicker .dot {
width: 7px; height: 7px; border-radius: 50%; width: 7px; height: 7px; background: var(--accent);
background: var(--accent-3); animation: pulse 1.6s infinite;
animation: pulse 2s infinite; }
.kicker .dot.dim { background: var(--ink-faint); }
.hero .seal {
font-size: 5rem;
line-height: 1;
color: var(--bone);
user-select: none;
display: block;
margin: 18px auto 6px;
animation: fadeUp .7s ease both;
} }
.hero h1 { .hero h1 {
font-size: clamp(2.6rem, 6vw, 4.6rem); font-family: var(--mono);
font-weight: 800; font-size: clamp(1.6rem, 4vw, 2.6rem);
line-height: 1.05; font-weight: 700;
color: var(--text-bright); line-height: 1.1;
margin: 22px auto 18px; color: var(--bone);
max-width: 900px; letter-spacing: .02em;
letter-spacing: -.02em; margin: 14px auto 16px;
text-transform: uppercase;
} }
.hero h1 .grad { .hero h1 .grad { color: var(--accent); }
background: var(--grad); .hero p.sub { color: var(--ink-dim); max-width: 620px; margin: 0 auto 30px; font-size: 1rem; }
-webkit-background-clip: text;
background-clip: text; .cta-row { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }
color: transparent;
}
.hero p.sub {
max-width: 640px;
margin: 0 auto 30px;
color: var(--text-dim);
font-size: 1.12rem;
}
.cta-row { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; }
.btn { .btn {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
gap: 8px; gap: 10px;
font-family: var(--mono); font-family: var(--mono);
font-weight: 500; text-transform: uppercase;
letter-spacing: .1em;
font-size: .78rem;
font-weight: 700;
padding: 12px 22px; padding: 12px 22px;
border-radius: 10px; border: 1px solid var(--ink-dim);
font-size: .95rem; color: var(--bone);
transition: transform .15s, box-shadow .15s, background .15s; transition: color .15s, background .15s, border-color .15s, transform .1s;
} }
.btn:hover { text-decoration: none; transform: translateY(-2px); } .btn:hover { text-decoration: none; }
.btn-primary { background: var(--grad); color: #0a0e14; box-shadow: 0 4px 20px rgba(139,92,246,.4); } .btn-primary { background: var(--accent); border-color: var(--accent); color: #000; }
.btn-primary:hover { box-shadow: 0 8px 28px rgba(139,92,246,.55); } .btn-primary:hover { background: #000; color: var(--accent); }
.btn-ghost { background: var(--bg-3); color: var(--text); border: 1px solid var(--border); } .btn-ghost { background: transparent; color: var(--ink-dim); }
.btn-ghost:hover { background: var(--bg-2); } .btn-ghost:hover { background: var(--paper-2); color: var(--bone); border-color: var(--accent); }
/* ---------- marquee ticker ---------- */
.ticker {
overflow: hidden;
border-top: 1px solid var(--hair);
border-bottom: 1px solid var(--hair);
padding: 13px 0;
background: var(--paper-2);
white-space: nowrap;
}
.ticker-inner {
display: inline-block;
animation: ticker 32s linear infinite;
font-family: var(--mono);
font-size: .8rem;
text-transform: uppercase;
letter-spacing: .1em;
color: var(--ink-faint);
}
.ticker-inner span { margin: 0 26px; }
.ticker-inner b { color: var(--bone); font-weight: 500; }
.ticker-inner .a { color: var(--accent); }
/* ---------- sections ---------- */ /* ---------- sections ---------- */
section { padding: 56px 28px; } section { padding: 54px 26px; }
.wrap { max-width: 1080px; margin: 0 auto; } .wrap { max-width: 1080px; margin: 0 auto; }
.section-title { .section-title {
font-family: var(--mono); font-family: var(--mono);
text-transform: uppercase; text-transform: uppercase;
letter-spacing: .12em; letter-spacing: .2em;
font-size: .82rem; font-size: .7rem;
color: var(--accent-2); color: var(--accent);
margin-bottom: 10px; margin-bottom: 10px;
} }
h2.head { font-size: clamp(1.6rem, 3.5vw, 2.4rem); color: var(--text-bright); font-weight: 700; margin-bottom: 14px; letter-spacing: -.01em; } .section-title::before { content: "// "; opacity: .6; }
.lead { color: var(--text-dim); font-size: 1.05rem; max-width: 720px; margin-bottom: 30px; } h2.head {
font-family: var(--mono);
font-size: clamp(1.25rem, 3vw, 1.9rem);
color: var(--bone);
font-weight: 700;
margin-bottom: 12px;
text-transform: uppercase;
letter-spacing: .02em;
}
.lead { color: var(--ink-dim); font-size: 1rem; max-width: 720px; margin-bottom: 28px; }
.grid { display: grid; gap: 22px; } .grid { display: grid; gap: 18px; }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); } .grid-2 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); } .grid-3 { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); } .grid-4 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
.card { .card {
background: var(--bg-3); background: var(--paper-2);
border: 1px solid var(--border); border: 1px solid var(--hair);
border-radius: var(--radius); padding: 20px;
padding: 22px; position: relative;
transition: transform .2s, border-color .2s, box-shadow .2s; transition: border-color .15s, transform .1s, background .15s;
animation: fadeUp .6s ease both;
} }
.card:hover { transform: translateY(-4px); border-color: var(--accent); box-shadow: var(--shadow); } .card::before {
.card.h { font-family: var(--mono); font-size: 1.05rem; color: var(--text-bright); margin-bottom: 8px; } content: "";
.card p { color: var(--text-dim); font-size: .95rem; } position: absolute;
left: 0; top: 0; bottom: 0;
width: 2px;
background: var(--accent);
transform: scaleY(0);
transform-origin: top;
transition: transform .25s cubic-bezier(.2,.8,.2,1);
}
.card:hover { border-color: var(--accent); background: var(--paper-3); transform: translateY(-2px); }
.card:hover::before { transform: scaleY(1); }
.card.h {
font-family: var(--mono);
font-size: 1rem;
text-transform: uppercase;
letter-spacing: .06em;
color: var(--bone);
margin-bottom: 8px;
}
.card p { color: var(--ink-dim); font-size: .92rem; }
.card .num { .card .num {
font-family: var(--mono); font-family: var(--mono);
font-size: .75rem; font-size: .68rem;
color: var(--accent-2); letter-spacing: .14em;
border: 1px solid var(--border); text-transform: uppercase;
color: var(--accent);
border: 1px solid var(--hair);
padding: 2px 8px; padding: 2px 8px;
border-radius: 6px;
display: inline-block; display: inline-block;
margin-bottom: 10px; margin-bottom: 10px;
} }
a.card { color: inherit; }
a.card:hover { text-decoration: none; }
/* ---------- terminal/snippet ---------- */ /* ---------- terminal / code ---------- */
.terminal { .terminal {
background: #05080d; background: #050505;
border: 1px solid var(--border); border: 1px solid var(--hair);
border-radius: var(--radius);
overflow: hidden; overflow: hidden;
box-shadow: var(--shadow);
text-align: left; text-align: left;
margin: 0 auto; margin: 0 auto;
max-width: 640px; max-width: 660px;
} }
.terminal .tbar { .terminal .tbar {
background: var(--bg-2); background: var(--paper-2);
padding: 10px 14px; padding: 9px 12px;
display: flex; display: flex;
gap: 6px; gap: 6px;
align-items: center; align-items: center;
border-bottom: 1px solid var(--border); border-bottom: 1px solid var(--hair);
} }
.terminal .tbar span.dot { width: 11px; height: 11px; border-radius: 50%; display: inline-block; } .terminal .tbar span.dot { width: 9px; height: 9px; display: inline-block; }
.terminal .tbar .r { background: var(--danger); } .terminal .tbar .r { background: var(--danger); }
.terminal .tbar .y { background: var(--warn); } .terminal .tbar .y { background: var(--warn); }
.terminal .tbar .g { background: var(--accent-3); } .terminal .tbar .g { background: var(--ok); }
.terminal .tbar .t { margin-left: 8px; font-family: var(--mono); font-size: .75rem; color: var(--text-dim); } .terminal .tbar .t {
.terminal pre { margin-left: 10px;
padding: 18px;
overflow-x: auto;
font-family: var(--mono); font-family: var(--mono);
font-size: .85rem; font-size: .72rem;
line-height: 1.7; color: var(--ink-faint);
color: var(--text); text-transform: uppercase;
letter-spacing: .1em;
} }
.terminal .c { color: var(--accent-2); } .terminal pre { padding: 18px; overflow-x: auto; font-family: var(--mono); font-size: .84rem; line-height: 1.75; color: var(--ink); }
.terminal .k { color: var(--accent-3); } .terminal .c { color: var(--accent); }
.terminal .p { color: var(--text-dim); } .terminal .k { color: var(--bone); }
.terminal .p { color: var(--ink-faint); }
/* ---------- code blocks ---------- */ pre, code, kbd { font-family: var(--mono); }
pre, code, kbd {
font-family: var(--mono);
}
.code-block { .code-block {
background: var(--code-bg); background: #050505;
border: 1px solid var(--border); border: 1px solid var(--hair);
border-radius: 10px; border-left: 3px solid var(--accent);
padding: 18px; padding: 18px;
overflow-x: auto; overflow-x: auto;
margin: 18px 0; margin: 18px 0;
font-size: .85rem; font-size: .84rem;
line-height: 1.7; line-height: 1.7;
color: var(--text); color: var(--ink);
} }
code:not(.code-block) { code:not(.code-block) {
background: var(--bg-3); background: var(--paper-2);
border: 1px solid var(--border); border: 1px solid var(--hair);
border-radius: 5px;
padding: 2px 6px; padding: 2px 6px;
font-size: .85em; font-size: .85em;
color: var(--accent-2); color: var(--accent);
} }
kbd { kbd {
background: var(--bg-3); background: var(--paper-2);
border: 1px solid var(--border); border: 1px solid var(--hair);
border-bottom-width: 2px; border-bottom-width: 2px;
border-radius: 5px;
padding: 1px 6px; padding: 1px 6px;
font-size: .8em; font-size: .8em;
} }
/* ---------- lists / prose ---------- */ /* ---------- prose ---------- */
.prose { max-width: 760px; margin: 0 auto; } .prose { max-width: 760px; margin: 0 auto; }
.prose h3 { .prose h3 {
color: var(--text-bright); font-family: var(--mono);
font-size: 1.25rem; text-transform: uppercase;
margin: 34px 0 10px; letter-spacing: .04em;
color: var(--bone);
font-size: 1.1rem;
margin: 32px 0 10px;
font-weight: 700; font-weight: 700;
} }
.prose h4 { color: var(--accent-2); margin: 22px 0 8px; font-size: 1.05rem; } .prose h3::before { content: "# "; color: var(--accent); }
.prose p { margin: 12px 0; color: var(--text); } .prose h4 { color: var(--accent); margin: 22px 0 8px; font-size: .95rem; font-family: var(--mono); }
.prose ul, .prose ol { margin: 12px 0 12px 24px; } .prose p { margin: 12px 0; color: var(--ink); }
.prose li { margin: 6px 0; color: var(--text); } .prose ul, .prose ol { margin: 12px 0 12px 22px; }
.prose li { margin: 6px 0; color: var(--ink); }
.prose li::marker { color: var(--accent); } .prose li::marker { color: var(--accent); }
.prose blockquote { .prose blockquote {
border-left: 3px solid var(--accent); border-left: 3px solid var(--accent);
background: var(--bg-2); background: var(--paper-2);
padding: 14px 18px; padding: 14px 18px;
border-radius: 0 8px 8px 0;
margin: 18px 0; margin: 18px 0;
color: var(--text-dim); color: var(--ink-dim);
} }
.prose blockquote strong { color: var(--text-bright); } .prose blockquote strong { color: var(--bone); }
.prose hr { border: none; border-top: 1px solid var(--border); margin: 30px 0; } .prose hr { border: none; border-top: 1px solid var(--hair); margin: 30px 0; }
table { border-collapse: collapse; width: 100%; margin: 18px 0; font-size: .92rem; }
th, td { border: 1px solid var(--border); padding: 9px 12px; text-align: left; }
th { background: var(--bg-2); color: var(--text-bright); font-family: var(--mono); font-size: .82rem; }
tr:nth-child(even) td { background: rgba(255,255,255,.015); }
/* tag chips */ table { border-collapse: collapse; width: 100%; margin: 18px 0; font-size: .92rem; }
th, td { border: 1px solid var(--hair); padding: 9px 12px; text-align: left; }
th { background: var(--paper-2); color: var(--bone); font-family: var(--mono); font-size: .78rem; text-transform: uppercase; letter-spacing: .05em; }
tr:nth-child(even) td { background: rgba(255,255,255,.02); }
/* tags / callouts */
.tag { .tag {
display: inline-block; display: inline-block;
font-family: var(--mono); font-family: var(--mono);
font-size: .72rem; font-size: .66rem;
letter-spacing: .05em; letter-spacing: .12em;
text-transform: uppercase; text-transform: uppercase;
padding: 2px 9px; padding: 2px 9px;
border-radius: 999px; border: 1px solid var(--hair);
border: 1px solid var(--border); color: var(--ink-dim);
color: var(--accent-2);
margin: 2px 4px 2px 0; margin: 2px 4px 2px 0;
} }
.tag.warn { color: var(--warn); border-color: rgba(245,158,11,.4); } .tag.warn { color: var(--warn); border-color: var(--warn); }
.tag.danger { color: var(--danger); border-color: rgba(239,68,68,.4); } .tag.danger { color: var(--danger); border-color: var(--danger); }
.tag.ok { color: var(--accent-3); border-color: rgba(52,211,153,.4); } .tag.ok { color: var(--ok); border-color: var(--ok); }
.tag.accent { color: var(--accent); border-color: var(--accent); }
/* pill callout */
.callout { .callout {
border: 1px solid var(--border); border: 1px solid var(--hair);
border-left: 3px solid var(--accent); border-left: 3px solid var(--accent);
background: var(--bg-2); background: var(--paper-2);
border-radius: 8px;
padding: 14px 18px; padding: 14px 18px;
margin: 18px 0; margin: 18px 0;
} }
.callout.warn { border-left-color: var(--warn); } .callout.warn { border-left-color: var(--warn); }
.callout.danger { border-left-color: var(--danger); } .callout.danger { border-left-color: var(--danger); }
.callout.ok { border-left-color: var(--accent-3); } .callout.ok { border-left-color: var(--ok); }
/* ---------- comparison tables / feature list ---------- */
.features { list-style: none; margin: 0; } .features { list-style: none; margin: 0; }
.features li { padding: 10px 0; border-bottom: 1px solid var(--border); display: flex; gap: 12px; } .features li { padding: 9px 0; border-bottom: 1px solid var(--hair); display: flex; gap: 12px; color: var(--ink); }
.features li::before { content: "◆"; color: var(--accent); } .features li::before { content: "▸"; color: var(--accent); }
/* ---------- news ---------- */ /* ---------- news ---------- */
.post-list { max-width: 820px; margin: 0 auto; } .post-list { max-width: 820px; margin: 0 auto; }
.post-item { .post-item {
display: block; display: block;
background: var(--bg-3); background: var(--paper-2);
border: 1px solid var(--border); border: 1px solid var(--hair);
border-radius: var(--radius); padding: 20px 22px;
padding: 20px 24px; margin-bottom: 14px;
margin-bottom: 16px; transition: border-color .15s, transform .1s;
transition: transform .15s, border-color .15s;
} }
.post-item:hover { transform: translateX(4px); border-color: var(--accent); text-decoration: none; } .post-item:hover { transform: translateX(4px); border-color: var(--accent); text-decoration: none; }
.post-item h3 { color: var(--text-bright); font-size: 1.2rem; margin-bottom: 6px; } .post-item h3 { color: var(--bone); font-family: var(--mono); font-size: 1.05rem; text-transform: uppercase; letter-spacing: .03em; margin-bottom: 6px; }
.post-item .meta { font-family: var(--mono); font-size: .78rem; color: var(--text-dim); margin-bottom: 6px; } .post-item .meta { font-family: var(--mono); font-size: .72rem; color: var(--ink-faint); text-transform: uppercase; letter-spacing: .1em; margin-bottom: 6px; }
.post-item p { color: var(--text-dim); font-size: .95rem; } .post-item p { color: var(--ink-dim); font-size: .92rem; }
/* ---------- footer ---------- */ /* ---------- footer ---------- */
footer { footer { border-top: 1px solid var(--hair); background: var(--paper-2); padding: 38px 26px 30px; margin-top: 40px; }
border-top: 1px solid var(--border); footer .wrap { display: flex; gap: 34px; flex-wrap: wrap; justify-content: space-between; }
background: var(--bg-2); footer h4 { color: var(--bone); font-family: var(--mono); font-size: .72rem; text-transform: uppercase; letter-spacing: .16em; margin-bottom: 12px; }
padding: 40px 28px 32px; footer h4::before { content: "// "; color: var(--accent); }
margin-top: 40px;
}
footer .wrap { display: flex; gap: 40px; flex-wrap: wrap; justify-content: space-between; }
footer h4 { color: var(--text-bright); font-family: var(--mono); font-size: .85rem; text-transform: uppercase; letter-spacing: .1em; margin-bottom: 12px; }
footer ul { list-style: none; } footer ul { list-style: none; }
footer li { margin: 6px 0; } footer li { margin: 6px 0; }
footer a { color: var(--text-dim); } footer a { color: var(--ink-dim); }
footer a:hover { color: var(--text-bright); text-decoration: none; } footer a:hover { color: var(--bone); text-decoration: none; }
footer .foot { footer .foot {
margin-top: 30px; margin-top: 28px;
padding-top: 20px; padding-top: 18px;
border-top: 1px solid var(--border); border-top: 1px solid var(--hair);
font-family: var(--mono);
font-size: .72rem;
color: var(--ink-faint);
text-align: center;
text-transform: uppercase;
letter-spacing: .12em;
}
footer .marks { color: var(--accent); }
/* ---------- stats ---------- */
.stats { display: flex; gap: 30px; flex-wrap: wrap; justify-content: center; margin: 22px 0; }
.stat { text-align: center; border: 1px solid var(--hair); padding: 18px 26px; background: var(--paper-2); min-width: 150px; }
.stat .big { font-family: var(--mono); font-size: 2.2rem; font-weight: 700; color: var(--bone); }
.stat .lbl { color: var(--ink-faint); font-size: .72rem; text-transform: uppercase; letter-spacing: .12em; font-family: var(--mono); }
/* dossier block (Ryoku-style system sheet) */
.dossier {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1px;
background: var(--hair);
border: 1px solid var(--hair);
margin: 26px auto;
max-width: 680px;
text-align: left;
}
.dossier .row {
background: var(--paper-2);
padding: 12px 18px;
font-family: var(--mono); font-family: var(--mono);
font-size: .78rem; font-size: .78rem;
color: var(--text-dim); display: flex;
text-align: center; justify-content: space-between;
gap: 16px;
} }
footer .marks { font-family: var(--mono); color: var(--accent-2); } .dossier .row .lbl { color: var(--ink-faint); text-transform: uppercase; letter-spacing: .1em; }
.dossier .row .val { color: var(--bone); text-align: right; }
.dossier .row .val.a { color: var(--accent); }
/* ---------- animation utilities ---------- */ /* ---------- animations ---------- */
@keyframes fadeUp { @keyframes fadeUp {
from { opacity: 0; transform: translateY(18px); } from { opacity: 0; transform: translateY(14px); }
to { opacity: 1; transform: translateY(0); } to { opacity: 1; transform: translateY(0); }
} }
@keyframes pulse { @keyframes fadeLeft {
0%, 100% { opacity: 1; } from { opacity: 0; transform: translateX(-14px); }
50% { opacity: .35; } to { opacity: 1; transform: translateX(0); }
} }
.reveal { animation: fadeUp .7s ease both; } @keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: .25; } }
.d1 { animation-delay: .1s; } @keyframes blink { 0%,49% { opacity: 1; } 50%,100% { opacity: 0; } }
.d2 { animation-delay: .2s; }
.d3 { animation-delay: .3s; }
.d4 { animation-delay: .4s; }
/* scrolling feature ticker on landing */
.ticker {
overflow: hidden;
border-top: 1px solid var(--border);
border-bottom: 1px solid var(--border);
padding: 14px 0;
background: var(--bg-2);
white-space: nowrap;
}
.ticker-inner {
display: inline-block;
animation: ticker 30s linear infinite;
font-family: var(--mono);
color: var(--text-dim);
}
.ticker-inner span { margin: 0 28px; }
.ticker-inner b { color: var(--accent-2); }
@keyframes ticker { from { transform: translateX(0); } to { transform: translateX(-50%); } } @keyframes ticker { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@keyframes sweep {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}
/* stat blocks */ .reveal { animation: fadeUp .6s ease both; }
.stats { display: flex; gap: 28px; flex-wrap: wrap; justify-content: center; margin: 24px 0; } .d1 { animation-delay: .08s; }
.stat { text-align: center; } .d2 { animation-delay: .16s; }
.stat .big { font-family: var(--mono); font-size: 2.4rem; font-weight: 700; color: var(--text-bright); background: var(--grad); -webkit-background-clip: text; background-clip: text; color: transparent; } .d3 { animation-delay: .24s; }
.stat .lbl { color: var(--text-dim); font-size: .85rem; } .d4 { animation-delay: .32s; }
.d5 { animation-delay: .40s; }
/* page header (non-hero pages) */ /* blinking caret after brand */
.pagehead { padding: 72px 28px 32px; text-align: center; } .caret { display: inline-block; width: 8px; height: 1em; background: var(--accent); margin-left: 2px; vertical-align: -0.15em; animation: blink 1.1s infinite; }
.pagehead h1 { color: var(--text-bright); font-size: clamp(2rem, 5vw, 3.2rem); font-weight: 800; letter-spacing: -.02em; }
.pagehead p { color: var(--text-dim); max-width: 640px; margin: 14px auto 0; }
/* breadcrumb */ /* accent headline underline sweep on hover */
.crumbs { font-family: var(--mono); font-size: .78rem; color: var(--text-dim); max-width: 760px; margin: 20px auto 0; } .head { background: linear-gradient(90deg, var(--accent), var(--accent), var(--accent)) no-repeat;
.crumbs a { color: var(--accent-2); } background-size: 0% 2px; background-position: 0 100%; transition: background-size .3s ease; }
.head:hover { background-size: 100% 2px; }
/* text flicker on the kanji seal */
.seal { animation: flicker 4s infinite; }
@keyframes flicker {
0%,100% { opacity: 1; }
92% { opacity: 1; } 93% { opacity: .4; } 94% { opacity: 1; }
}
/* ---------- pagehead ---------- */
.pagehead { padding: 64px 26px 30px; text-align: center; }
.pagehead h1 { font-family: var(--mono); text-transform: uppercase; letter-spacing: .02em; color: var(--bone); font-size: clamp(1.6rem, 4vw, 2.4rem); font-weight: 700; }
.pagehead p { color: var(--ink-dim); max-width: 620px; margin: 12px auto 0; }
.crumbs { font-family: var(--mono); font-size: .72rem; color: var(--ink-faint); text-transform: uppercase; letter-spacing: .12em; max-width: 760px; margin: 18px auto 0; }
.crumbs a { color: var(--ink-dim); }
.crumbs a:hover { color: var(--accent); }
.crumbs span { color: var(--accent); }
/* responsive */ /* responsive */
@media (max-width: 720px) { @media (max-width: 720px) {
nav.top { padding: 0 14px; } nav.top { padding: 0 14px; }
nav.top a.navlink { display: none; } nav.top a.navlink { display: none; }
.menu-toggle { display: inline-flex; } .menu-toggle { display: inline-flex; }
.hero { padding: 64px 18px 40px; } .hero { padding: 56px 18px 34px; }
section { padding: 40px 18px; } section { padding: 38px 18px; }
footer .wrap { gap: 24px; } footer .wrap { gap: 20px; }
.dossier { grid-template-columns: 1fr; }
} }
+5 -11
View File
@@ -15,7 +15,7 @@
<header class="pagehead"> <header class="pagehead">
<p class="crumbs"><a href="index.html">home</a> / <a href="community.html">community</a> / contact</p> <p class="crumbs"><a href="index.html">home</a> / <a href="community.html">community</a> / contact</p>
<h1>Contact</h1> <h1>Contact</h1>
<p>Use issues for bugs and ideas; the list for discussion.</p> <p>Use issues for bugs and ideas; email for discussion.</p>
</header> </header>
<section> <section>
@@ -28,16 +28,10 @@
<p><a href="https://github.com/AstralZX/KeruOS/issues">AstralZX/KeruOS issues</a></p> <p><a href="https://github.com/AstralZX/KeruOS/issues">AstralZX/KeruOS issues</a></p>
</div> </div>
<div class="card"> <div class="card">
<span class="num">discussion</span> <span class="num">direct</span>
<span class="h">Mailing list</span> <span class="h">Email</span>
<p>Longer conversations about philosophy, design decisions, and direction. Subscribe or join the thread.</p> <p>Longer conversations about philosophy, design decisions, and direction.</p>
<p><a href="mailto:[email protected]">[email protected]</a> (placeholder)</p> <p><a href="mailto:[email protected]">[email protected]</a></p>
</div>
<div class="card">
<span class="num">channel</span>
<span class="h">Matrix</span>
<p>A real-time room for early adopters and contributors.</p>
<p><a href="https://matrix.to/#/#keru:matrix.org">#keru:matrix.org</a> (placeholder)</p>
</div> </div>
<div class="card"> <div class="card">
<span class="num">code</span> <span class="num">code</span>
+8
View File
@@ -21,11 +21,19 @@
<section> <section>
<div class="wrap"> <div class="wrap">
<div class="grid grid-2"> <div class="grid grid-2">
<a class="card" href="getting-started.html"><span class="num">guide</span><span class="h">Getting started</span><p>From booting the ISO to a first-boot system — the whole arc in one read.</p></a>
<a class="card" href="make-conf.html"><span class="num">reference</span><span class="h">make.conf</span><p>The profile file your selections produce, and every variable it knows.</p></a> <a class="card" href="make-conf.html"><span class="num">reference</span><span class="h">make.conf</span><p>The profile file your selections produce, and every variable it knows.</p></a>
<a class="card" href="profile.html"><span class="num">reference</span><span class="h">Profile system</span><p>How profile/make.conf templates the build and the swappables.</p></a> <a class="card" href="profile.html"><span class="num">reference</span><span class="h">Profile system</span><p>How profile/make.conf templates the build and the swappables.</p></a>
<a class="card" href="recipe-format.html"><span class="num">spec</span><span class="h">Recipe format</span><p>The formal spec for kama package recipes — fields, hooks, tiers.</p></a> <a class="card" href="recipe-format.html"><span class="num">spec</span><span class="h">Recipe format</span><p>The formal spec for kama package recipes — fields, hooks, tiers.</p></a>
<a class="card" href="recipe-authoring.html"><span class="num">howto</span><span class="h">Recipe authoring</span><p>Write your first kama recipe, with real examples from the repo.</p></a>
<a class="card" href="build-pipeline.html"><span class="num">reference</span><span class="h">Build pipeline</span><p>scripts/build-root.sh and mkfs-root.sh — how a make.conf becomes a rootfs.</p></a> <a class="card" href="build-pipeline.html"><span class="num">reference</span><span class="h">Build pipeline</span><p>scripts/build-root.sh and mkfs-root.sh — how a make.conf becomes a rootfs.</p></a>
<a class="card" href="toolchain.html"><span class="num">reference</span><span class="h">Toolchain bootstrap</span><p>binutils → gcc → libc → self-host: what "from scratch" means.</p></a>
<a class="card" href="live-init.html"><span class="num">reference</span><span class="h">Live init</span><p>live/init — how booting the ISO auto-starts the installer.</p></a> <a class="card" href="live-init.html"><span class="num">reference</span><span class="h">Live init</span><p>live/init — how booting the ISO auto-starts the installer.</p></a>
<a class="card" href="kama-config.html"><span class="num">reference</span><span class="h">Kama configuration</span><p>Every kama variable: PKGDIR, ROOT, CACHEDIR, MAKE_CONF, mirrors.</p></a>
<a class="card" href="mirror-cache.html"><span class="num">reference</span><span class="h">Mirrors &amp; cache</span><p>The download order and the dl/src/stage cache layout.</p></a>
<a class="card" href="security.html"><span class="num">reference</span><span class="h">Security</span><p>Trust model of a source-only build, stated plainly.</p></a>
<a class="card" href="troubleshooting.html"><span class="num">guide</span><span class="h">Troubleshooting</span><p>Diagnose by stage — boot, network, fetch, build, finalize.</p></a>
<a class="card" href="release-process.html"><span class="num">reference</span><span class="h">Release process</span><p>What a release contains, and how versioning works.</p></a>
<a class="card" href="swappables.html"><span class="num">guide</span><span class="h">Swappables guide</span><p>Every component you can choose at install, with the full option list.</p></a> <a class="card" href="swappables.html"><span class="num">guide</span><span class="h">Swappables guide</span><p>Every component you can choose at install, with the full option list.</p></a>
<a class="card" href="install.html"><span class="num">guide</span><span class="h">Install guide</span><p>The end-to-end installation flow, from BIOS to boot.</p></a> <a class="card" href="install.html"><span class="num">guide</span><span class="h">Install guide</span><p>The end-to-end installation flow, from BIOS to boot.</p></a>
<a class="card" href="contribute.html"><span class="num">guide</span><span class="h">Contribute</span><p>How to get involved across the three repos and this site.</p></a> <a class="card" href="contribute.html"><span class="num">guide</span><span class="h">Contribute</span><p>How to get involved across the three repos and this site.</p></a>
+77
View File
@@ -0,0 +1,77 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Getting started — Keru OS</title>
<meta name="description" content="From booting the Keru ISO to a first-boot system: prerequisites, the install flow, network, and day one.">
<link rel="stylesheet" href="assets/css/style.css">
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>ける</text></svg>">
</head>
<body>
<nav class="top" data-nav></nav>
<header class="pagehead">
<p class="crumbs"><a href="index.html">home</a> / <a href="docs.html">docs</a> / getting started</p>
<h1>Getting started</h1>
<p>Zero to a chosen, booting, source-built system.</p>
</header>
<section>
<div class="wrap">
<div class="prose">
<p>Keru 0.1 ships as an ISO. There is no source build to DIY, no binary download, no flashing a rootfs tarball. Boot the ISO, answer the installer, and Keru builds exactly what you chose while you watch.</p>
<h3>Before you begin</h3>
<ul class="features">
<li><strong>A working network.</strong> The build is fully online — every source tarball is downloaded fresh at install time.</li>
<li><strong>A spare target disk.</strong> <code>mkfs-root.sh</code> formats whatever root device the installer points at. It will be written over.</li>
<li><strong>Patience for the first build.</strong> Fetch + compile of the full toolchain and system takes a while on modest hardware.</li>
<li><strong>Decisions.</strong> Prep your picks ahead — or just press enter; sane defaults are documented on every prompt.</li>
</ul>
<h3>The flow</h3>
<div class="code-block">1. Write the ISO to USB sudo dd if=keru-0.1.iso of=/dev/sdX bs=4M status=progress
2. Boot the stick BIOS/UEFI → the live image starts by itself
3. live/init mounts & runs the installer launches automatically on boot
4. Connect to the network the installer runs nmtui for you when offline
5. Make your picks init · libc · fs · kernel · sudo · net
6. Keru builds the system fetch → stage 0 toolchain → base → swappables
7. First boot your crafted system, exactly as chosen</div>
<h3>Your picks</h3>
<table>
<tr><th>Choice</th><th>Default</th><th>Why you might change it</th></tr>
<tr><td>Init system</td><td><code>runit</code></td><td>systemd for optional use — but Keru never forces it.</td></tr>
<tr><td>C library</td><td><code>glibc</code></td><td>musl for a smaller static-leaning system.</td></tr>
<tr><td>Filesystem</td><td><code>ext4</code></td><td>btrfs snapshots, zfs features, xfs scaling.</td></tr>
<tr><td>Kernel</td><td><code>linux</code></td><td>linux-lts for longevity, hardened for attacks.</td></tr>
<tr><td>Privilege elevation</td><td><code>doas</code></td><td>sudo if you live in its muscle memory.</td></tr>
<tr><td>Network tools</td><td><code>nmtui</code></td><td>networkmanager, connman, or systemd-networkd.</td></tr>
</table>
<div class="callout">Every option here has a dedicated page. See <a href="swappables.html">the swappables guide</a> and its sub-pages before you install, so boot rehearsal is boring by design.</div>
<h3>Day one</h3>
<p>Keru installs a bare, honest base — the packages you chose plus the few kama needs to run. From there you shape the rest:</p>
<div class="code-block"># your system, your way
kama make vim # build anything else from source
kama info busybox # peek at a recipe's metadata
doas kama install tmux</div>
<p>Everything you don't install, you don't get. No services pretending to be useful, no telemetry phone-home.</p>
<div class="callout ok">Now read the <a href="installer-walkthrough.html">installer walkthrough</a> for the fine detail, or go straight to <a href="troubleshooting.html">troubleshooting</a> when something surprises you.</div>
<p><a href="install.html">← Install overview</a> · <a href="network-setup.html">Network setup</a></p>
</div>
</div>
</section>
<footer data-footer></footer>
<noscript><div style="text-align:center;padding:16px">See the <a href="sitemap.html">sitemap</a> for all pages.</div></noscript>
<script src="assets/js/include.js" data-base="."></script>
</body>
</html>
+23 -11
View File
@@ -13,16 +13,28 @@
<nav class="top" data-nav></nav> <nav class="top" data-nav></nav>
<header class="hero"> <header class="hero">
<span class="kicker"><span class="dot"></span> independent · source-only · linux</span> <span class="kicker reveal"><span class="dot"></span> independent · source-only · linux</span>
<h1>You don't install a system.<br>You <span class="grad">craft</span> one.</h1> <span class="seal reveal d1">ける</span>
<p class="sub">Keru is an anti-opinionated Linux distribution. Choose your init, libc, filesystem, kernel, and tools at install time — and it builds exactly what you chose from source. Nothing forced, nothing you didn't ask for.</p> <h1 class="reveal d1">You don't install a system.<br>You <span class="grad">craft</span> one.</h1>
<div class="cta-row"> <p class="sub reveal d2">Keru is an anti-opinionated Linux distribution. Choose your init, libc, filesystem, kernel, and tools at install time — and it builds exactly what you chose from source. Nothing forced, nothing you didn't ask for.</p>
<a class="btn btn-primary" href="install.html">↓ Download 0.1</a> <div class="cta-row reveal d3">
<a class="btn btn-primary" href="install.html">↓ Install 0.1</a>
<a class="btn btn-ghost" href="philosophy.html">Read the philosophy</a> <a class="btn btn-ghost" href="philosophy.html">Read the philosophy</a>
<a class="btn btn-ghost" href="swappables.html">See what's swappable</a> <a class="btn btn-ghost" href="swappables.html">See what's swappable</a>
</div> </div>
</header> </header>
<div class="dossier reveal d4">
<div class="row"><span class="lbl">Name</span><span class="val">Keru OS ける</span></div>
<div class="row"><span class="lbl">Status</span><span class="val a">UNDER CONSTRUCTION</span></div>
<div class="row"><span class="lbl">Distribution</span><span class="val">source-only linux</span></div>
<div class="row"><span class="lbl">Package manager</span><span class="val">kama · ~225 lines</span></div>
<div class="row"><span class="lbl">Defining trait</span><span class="val">anti-opinionated</span></div>
<div class="row"><span class="lbl">Opinions forced</span><span class="val a">0</span></div>
<div class="row"><span class="lbl">Base packages</span><span class="val">0 (everything is swappable)</span></div>
<div class="row"><span class="lbl">Model</span><span class="val">boot ISO → choose → built from source</span></div>
</div>
<div class="ticker"> <div class="ticker">
<div class="ticker-inner"> <div class="ticker-inner">
<span><b>runit</b> · <b>s6</b> · <b>openrc</b> · <b>systemd</b> · <b>busybox-init</b> · <b>sysvinit</b> · <b>dinit</b> · <b>shepherd</b></span> <span><b>runit</b> · <b>s6</b> · <b>openrc</b> · <b>systemd</b> · <b>busybox-init</b> · <b>sysvinit</b> · <b>dinit</b> · <b>shepherd</b></span>
@@ -30,7 +42,7 @@
<span><b>ext4</b> · <b>btrfs</b> · <b>xfs</b> · <b>zfs</b> · <b>f2fs</b> · <b>jfs</b> · <b>reiserfs</b></span> <span><b>ext4</b> · <b>btrfs</b> · <b>xfs</b> · <b>zfs</b> · <b>f2fs</b> · <b>jfs</b> · <b>reiserfs</b></span>
<span><b>linux</b> · <b>linux-lts</b> · <b>linux-hardened</b> · <b>linux-cachyos</b> · <b>linux-zen</b></span> <span><b>linux</b> · <b>linux-lts</b> · <b>linux-hardened</b> · <b>linux-cachyos</b> · <b>linux-zen</b></span>
<span><b>doas</b> · <b>sudo</b> · <b>opendoas</b> · <b>su</b></span> <span><b>doas</b> · <b>sudo</b> · <b>opendoas</b> · <b>su</b></span>
<span>ける・けいとうてき — craft your system</span> <span class="a">ける・けいとうてき <b>— craft your system</b></span>
</div> </div>
</div> </div>
@@ -52,11 +64,11 @@
</div> </div>
</section> </section>
<section style="background:var(--bg-2);border-top:1px solid var(--border);border-bottom:1px solid var(--border)"> <section style="background:var(--paper-2);border-top:1px solid var(--hair);border-bottom:1px solid var(--hair)">
<div class="wrap"> <div class="wrap">
<p class="section-title" style="text-align:center">live demo</p> <p class="section-title" style="text-align:center">live boot</p>
<h2 class="head" style="text-align:center">Boot. Choose. Built from source.</h2> <h2 class="head" style="text-align:center">Boot. Choose. Built from source.</h2>
<p class="lead" style="text-align:center">The ISO carries only the installer. Boot it, it starts the installer automatically, you make your picks — and it builds your entire system from source.</p> <p class="lead" style="text-align:center">The ISO carries only the installer. Boot it, it starts the installer automatically, you make your picks — and it builds your entire system from source, live.</p>
<div class="terminal reveal"> <div class="terminal reveal">
<div class="tbar"><span class="dot r"></span><span class="dot y"></span><span class="dot g"></span><span class="t">keru@live:~$</span></div> <div class="tbar"><span class="dot r"></span><span class="dot y"></span><span class="dot g"></span><span class="t">keru@live:~$</span></div>
<pre><span class="c">[ keru ]</span> <span class="k">Keru OS — craft your system</span> <pre><span class="c">[ keru ]</span> <span class="k">Keru OS — craft your system</span>
@@ -99,8 +111,8 @@ Selecting: <span class="c">btrfs</span> ← you choose, Keru builds it
</div> </div>
</section> </section>
<section style="text-align:center;background:var(--bg-2);border-top:1px solid var(--border)"> <section style="background:var(--paper-2);border-top:1px solid var(--hair)">
<div class="wrap"> <div class="wrap" style="text-align:center">
<h2 class="head">Ready when it's ready.</h2> <h2 class="head">Ready when it's ready.</h2>
<p class="lead" style="margin:0 auto 24px">Keru 0.1 will ship as a bootable ISO. No source builds, no manual tooling — boot, choose, then watch it craft your system.</p> <p class="lead" style="margin:0 auto 24px">Keru 0.1 will ship as a bootable ISO. No source builds, no manual tooling — boot, choose, then watch it craft your system.</p>
<div class="cta-row"> <div class="cta-row">
+77
View File
@@ -0,0 +1,77 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Kama configuration — Keru OS</title>
<meta name="description" content="The full kama configuration reference: PKGDIR, CACHEDIR, ROOT, MAKE_CONF, PURGE_TEMP_DEPS, SOURCE_MIRROR, and the cache layout.">
<link rel="stylesheet" href="assets/css/style.css">
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>ける</text></svg>">
</head>
<body>
<nav class="top" data-nav></nav>
<header class="pagehead">
<p class="crumbs"><a href="index.html">home</a> / <a href="docs.html">docs</a> / kama configuration</p>
<h1>Kama configuration</h1>
<p>Every knob, every default, every path.</p>
</header>
<section>
<div class="wrap">
<div class="prose">
<p>Kama's configuration is environment variables. Nothing to edit inside the script, nothing hidden — set them in the environment (<code>export</code> in a profile, or inline on the command line) and it's done.</p>
<h3>Variables</h3>
<table>
<tr><th>Variable</th><th>Default</th><th>What it controls</th></tr>
<tr><td><code>PKGDIR</code></td><td>the kama-packages repo, sibling of the kama script</td><td>Where recipes are found.</td></tr>
<tr><td><code>ROOT</code></td><td><code>/tmp/keru/root</code></td><td>Where installed files land.</td></tr>
<tr><td><code>CACHEDIR</code></td><td><code>/var/cache/kama</code></td><td>Base for the dirty working dirs.</td></tr>
<tr><td><code>MAKE_CONF</code></td><td><code>/etc/kama/make.conf</code></td><td>Profile settings (JOBS, CFLAGS, etc.) if present.</td></tr>
<tr><td><code>SOURCE_MIRROR</code></td><td>unset</td><td>Mirror tried before upstream (set to e.g. <code>mirror.keru.org</code>).</td></tr>
<tr><td><code>PURGE_TEMP_DEPS</code></td><td><code>1</code></td><td>Purge temp build deps after <code>kama make</code>.</td></tr>
<tr><td><code>JOBS</code></td><td><code>nproc</code></td><td>Parallel build jobs; recipes call <code>make -j"$JOBS"</code>.</td></tr>
</table>
<h3>Cache layout</h3>
<div class="code-block">$CACHEDIR/
├── dl/ downloaded archives
├── src/ extracted source per package
└── stage/ staged installs, committed to $ROOT on success</div>
<h3>Common setups</h3>
<div class="code-block"># build into a scratch root
ROOT=/mnt/keru-root kama make busybox
# migrate cache to a big disk
export CACHEDIR=/mnt/cache/kama
export SOURCE_MIRROR=https://mirror.example.org
# keep temp deps this run (default removes them)
PURGE_TEMP_DEPS=0 kama make firefox</div>
<h3>make.conf integration</h3>
<p>Inside an installed Keru system, the profile at <code>MAKE_CONF</code> feeds the same variables into kama and the build scripts. Your <a href="make-conf.html">make.conf reference</a> lists the full set.</p>
<ul class="features">
<li>If <code>MAKE_CONF</code> exists it is sourced; missing is not an error.</li>
<li>The installer writes <code>JOBS</code> and <code>CFLAGS</code> from build-host detection.</li>
<li>Every variable has a sane default, so kama runs with zero config.</li>
</ul>
<div class="callout">Zero-config by default, fully pointed overrides when you need them. That's the whole story — read on for <a href="recipe-format.html">recipes</a>.</div>
<p><a href="kama-usage.html">← kama usage</a> · <a href="make-conf.html">make.conf</a></p>
</div>
</div>
</section>
<footer data-footer></footer>
<noscript><div style="text-align:center;padding:16px">See the <a href="sitemap.html">sitemap</a> for all pages.</div></noscript>
<script src="assets/js/include.js" data-base="."></script>
</body>
</html>
+73
View File
@@ -0,0 +1,73 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Mirrors and cache — Keru OS</title>
<meta name="description" content="How Keru and Kama download source: the project mirror, upstream fallback, and the download/source/stage cache layout.">
<link rel="stylesheet" href="assets/css/style.css">
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>ける</text></svg>">
</head>
<body>
<nav class="top" data-nav></nav>
<header class="pagehead">
<p class="crumbs"><a href="index.html">home</a> / <a href="docs.html">docs</a> / mirrors &amp; cache</p>
<h1>Mirrors and cache</h1>
<p>Where source comes from, and where it waits.</p>
</header>
<section>
<div class="wrap">
<div class="prose">
<p>Every Keru build is a network operation. Two mechanisms keep that sane and reproducible: a mirror-first download policy, and a well-defined cache on disk.</p>
<h3>Download order</h3>
<ul class="features">
<li><strong>1. <code>SOURCE_MIRROR</code></strong> — tried first when set (the org runs <code>mirror.keru.org</code> so the org can carry most of the traffic).</li>
<li><strong>2. Upstream</strong> — the canonical source URL from the recipe. Used when no mirror is set or the mirror lacks a file.</li>
<li><strong>Verification at every step.</strong> A file that doesn't match its checksum is dropped, and the next source in line is tried. Tampered files never reach a build.</li>
</ul>
<h3>The cache layout</h3>
<div class="code-block">/var/cache/kama/ # CACHEDIR (set CACHEDIR=/path to relocate)
├── dl/ # downloaded tarballs, one per package
├── src/ # extracted source (per package dir)
└── stage/ # staged installs before they commit to $ROOT</div>
<table>
<tr><th>Dir</th><th>Everything</th><th>Purpose</th></tr>
<tr><td><code>dl</code></td><td>Downloads</td><td>Already-downloaded archives are reused, never re-fetched.</td></tr>
<tr><td><code>src</code></td><td>Extracted</td><td>Extraction is skipped when the checked-out source is present.</td></tr>
<tr><td><code>stage</code></td><td>Staged builds</td><td>Progress survives a failed build; re-running continues.</td></tr>
</table>
<h3>Working offline, or your own mirror</h3>
<div class="code-block"># warm the cache once, then build with the network down
SOURCE_MIRROR=mirror.keru.org kama fetch busybox
...
CACHEDIR=/var/cache/kama kama make busybox # no network needed</div>
<p>Run a mirror yourself and point <code>SOURCE_MIRROR</code> at it. The layout mirrors <code>dl/</code>; the fetch layer treats it as a read-mostly source of truth.</p>
<h3>Cleanup</h3>
<ul class="features">
<li><code>rm -rf /var/cache/kama/src/*</code> — free extracted source (re-extracts on next build).</li>
<li><code>rm -rf /var/cache/kama/dl/*</code> — dump downloads (re-fetches next time).</li>
<li><code>rm -rf /var/cache/kama/stage/*</code> — discard staged builds.</li>
</ul>
<div class="callout">A corrupt cache is the #1 source of confusing fetch errors. When in doubt, clear the relevant dir — downloads verify anyway, so you lose nothing but time.</div>
<p><a href="kama-usage.html">← kama usage</a> · <a href="troubleshooting.html">Troubleshooting</a></p>
</div>
</div>
</section>
<footer data-footer></footer>
<noscript><div style="text-align:center;padding:16px">See the <a href="sitemap.html">sitemap</a> for all pages.</div></noscript>
<script src="assets/js/include.js" data-base="."></script>
</body>
</html>
+1 -1
View File
@@ -15,7 +15,7 @@
<header class="pagehead"> <header class="pagehead">
<p class="crumbs"><a href="../index.html">home</a> / <a href="../news.html">news</a> / announcing keru</p> <p class="crumbs"><a href="../index.html">home</a> / <a href="../news.html">news</a> / announcing keru</p>
<h1>Introducing Keru OS</h1> <h1>Introducing Keru OS</h1>
<p class="meta" style="font-family:var(--mono);color:var(--text-dim);font-size:.85rem">2026-09-01 · announcement</p> <p class="meta" style="font-family:var(--mono);color:var(--ink-dim);font-size:.85rem">2026-09-01 · announcement</p>
</header> </header>
<section> <section>
+1 -1
View File
@@ -15,7 +15,7 @@
<header class="pagehead"> <header class="pagehead">
<p class="crumbs"><a href="../index.html">home</a> / <a href="../news.html">news</a> / design decisions</p> <p class="crumbs"><a href="../index.html">home</a> / <a href="../news.html">news</a> / design decisions</p>
<h1>Design decisions, so far</h1> <h1>Design decisions, so far</h1>
<p class="meta" style="font-family:var(--mono);color:var(--text-dim);font-size:.85rem">2026-09-01 · design</p> <p class="meta" style="font-family:var(--mono);color:var(--ink-dim);font-size:.85rem">2026-09-01 · design</p>
</header> </header>
<section> <section>
+1 -1
View File
@@ -15,7 +15,7 @@
<header class="pagehead"> <header class="pagehead">
<p class="crumbs"><a href="../index.html">home</a> / <a href="../news.html">news</a> / philosophy is the architecture</p> <p class="crumbs"><a href="../index.html">home</a> / <a href="../news.html">news</a> / philosophy is the architecture</p>
<h1>The philosophy is the architecture</h1> <h1>The philosophy is the architecture</h1>
<p class="meta" style="font-family:var(--mono);color:var(--text-dim);font-size:.85rem">2026-09-01 · design</p> <p class="meta" style="font-family:var(--mono);color:var(--ink-dim);font-size:.85rem">2026-09-01 · design</p>
</header> </header>
<section> <section>
+1 -1
View File
@@ -15,7 +15,7 @@
<header class="pagehead"> <header class="pagehead">
<p class="crumbs"><a href="../index.html">home</a> / <a href="../news.html">news</a> / road to 0.1</p> <p class="crumbs"><a href="../index.html">home</a> / <a href="../news.html">news</a> / road to 0.1</p>
<h1>The road to 0.1</h1> <h1>The road to 0.1</h1>
<p class="meta" style="font-family:var(--mono);color:var(--text-dim);font-size:.85rem">2026-09-01 · roadmap</p> <p class="meta" style="font-family:var(--mono);color:var(--ink-dim);font-size:.85rem">2026-09-01 · roadmap</p>
</header> </header>
<section> <section>
+97
View File
@@ -0,0 +1,97 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Recipe authoring — Keru OS</title>
<meta name="description" content="A practical HOWTO for writing kama package recipes: easy tier, real examples, common patterns, and how to get it merged into kama-packages.">
<link rel="stylesheet" href="assets/css/style.css">
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>ける</text></svg>">
</head>
<body>
<nav class="top" data-nav></nav>
<header class="pagehead">
<p class="crumbs"><a href="index.html">home</a> / <a href="docs.html">docs</a> / recipe authoring</p>
<h1>Recipe authoring</h1>
<p>Writing a kama recipe, top to bottom.</p>
</header>
<section>
<div class="wrap">
<div class="prose">
<p>Every package in a Keru system is described by a recipe: a plain POSIX shell script in <code>kama-packages</code>. Writing one is closer to filling a form than engineering a build.</p>
<h3>The template</h3>
<p><code>kama-packages/TEMPLATE.sh</code> is the canonical starting point. Copy it, fill the easy tier:</p>
<div class="code-block">name=hello # required
version=2.12.1 # required for fetch
url=https://ftp.gnu.org/gnu/hello/hello-2.12.1.tar.gz
deps=() # build-time deps, compiled then purged
build() {
./configure --prefix=/usr
make -j"$JOBS"
}
install() {
make install DESTDIR="$pkgdir" # stage, never $ROOT
}</div>
<h3>A real, complete recipe</h3>
<p>This is the entire busybox recipe currently in the repo:</p>
<div class="code-block">name=busybox
version=1.36.1
url=https://busybox.net/downloads/busybox-1.36.1.tar.bz2
deps=()
build() {
make defconfig
make -j"$JOBS"
}
install() {
make install CONFIG_PREFIX="$pkgdir"
}</div>
<p>That's it. Kama downloads, extracts, strips the top dir, builds, stages, and installs.</p>
<h3>Stepping up</h3>
<table>
<tr><th>Need</th><th>Field / function</th></tr>
<tr><td>Colliding with another package</td><td><code>provides=(...) conflicts=(...)</code></td></tr>
<tr><td>Build deps that must stay</td><td><code>runtime_deps=(...)</code></td></tr>
<tr><td>Arch-restricted</td><td><code>arch=(x86_64)</code></td></tr>
<tr><td>Repo or vcs sources</td><td><code>noextract=("$url")</code> + own <code>build()</code></td></tr>
<tr><td>Custom fetch (patch first)</td><td><code>pkg_fetch() { default_fetch; patch ...; }</code></td></tr>
<tr><td>Post-install work</td><td><code>pkg_post()</code> · <code>pkg_split()</code> for subpackages</td></tr>
</table>
<h3>Rules of the road</h3>
<ul class="features">
<li><strong>Stage, don't touch.</strong> <code>install()</code> installs into <code>$pkgdir</code>. Kama commits the staging dir to <code>$ROOT</code> only after a successful build.</li>
<li><strong>Add pure build deps to <code>deps</code>.</strong> They're purged automatically after the build (AUR-style). Keeps the door clean.</li>
<li><strong>Declare the license.</strong> <code>license=(SPDX)</code> — supply chain cleanliness starts here.</li>
<li><strong>Pin exactly.</strong> A fixed <code>url</code> + <code>version</code>, never a moving "latest".</li>
</ul>
<h3>Checking your work</h3>
<div class="code-block">sh -n recipe.sh # syntax check
kama info &lt;pkgname&gt; # metadata parses (name from the recipe)
make recipe-check # lint the whole kama-packages repo
kama make &lt;pkgname&gt; # build it for real</div>
<div class="callout">The behavioral spec lives at <a href="recipe-format.html">recipe format</a>. For hands-on, mirror the <a href="kama-recipes.html">recipe concept</a> page and start with <code>busybox.sh</code>, the smallest real recipe.</div>
<p><a href="recipe-format.html">← Recipe format</a> · <a href="kama-repos.html">The repos</a></p>
</div>
</div>
</section>
<footer data-footer></footer>
<noscript><div style="text-align:center;padding:16px">See the <a href="sitemap.html">sitemap</a> for all pages.</div></noscript>
<script src="assets/js/include.js" data-base="."></script>
</body>
</html>
+67
View File
@@ -0,0 +1,67 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Release process — Keru OS</title>
<meta name="description" content="How Keru versions work, what a release contains, and the honest '0.1 when it's ready' timeline.">
<link rel="stylesheet" href="assets/css/style.css">
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>ける</text></svg>">
</head>
<body>
<nav class="top" data-nav></nav>
<header class="pagehead">
<p class="crumbs"><a href="index.html">home</a> / <a href="docs.html">docs</a> / release process</p>
<h1>Release process</h1>
<p>How a release leaves the kiln.</p>
</header>
<section>
<div class="wrap">
<div class="prose">
<p>Keru's releases are honest about being releases: each one is a tested point in time of the three repos, assembled into an ISO that boots and installs without fanfare.</p>
<h3>Versioning</h3>
<div class="code-block">keru-0.1.0.iso # {major}.{minor}.{patch}</div>
<table>
<tr><th>Bump</th><th>When</th></tr>
<tr><td>major</td><td>The swappable set changes shape, or the philosophy moves — real milestones like the first ISO.</td></tr>
<tr><td>minor</td><td>New swappable or a new kama feature that stays backward-compatible.</td></tr>
<tr><td>patch</td><td>Recipe fixes, installer bugfixes, docs — anything that changes no contracts.</td></tr>
</table>
<h3>What the release ISO contains</h3>
<ul class="features">
<li><strong>The installer.</strong> <code>installer/install.sh</code> plus its payload.</li>
<li><strong>The live init.</strong> <code>live/init</code> — boot the ISO, installer auto-runs.</li>
<li><strong>The repos.</strong> kama and kama-packages pinned at the release commit.<br>Everything else — every source tarball, every toolchain compile — is fetched and built at install time.</li>
</ul>
<h3>Release readiness</h3>
<table>
<tr><th>Check</th><th>What passes it</th></tr>
<tr><td>Combos boot</td><td>The proven set of the offered swappables all boot after install.</td></tr>
<tr><td>Installer clean</td><td>A full install from a cold boot, no keyboard runtime.</td></tr>
<tr><td>No blockers</td><td>Nothing warns-but-doesn't-block where it shouldn't; unproven combos warn loudly.</td></tr>
<tr><td>Docs match</td><td>make.conf, recipes, and this website agree with the shipped code.</td></tr>
</table>
<h3>Announcements</h3>
<p>Releases are announced on the <a href="news.html">news page</a>, with a changelog and the exact repos/commits the ISO was cut from. "0.1 when it's ready" — as tracked in the status above — remains the only roadmap.</p>
<div class="callout">Deliberately unglamorous. A release is a checkpoint the community can trust, not a marketing event. Read the <a href="news.html">news</a> for the current one.</div>
<p><a href="contribute.html">Contribute</a> · <a href="news.html">→ Status / news</a></p>
</div>
</div>
</section>
<footer data-footer></footer>
<noscript><div style="text-align:center;padding:16px">See the <a href="sitemap.html">sitemap</a> for all pages.</div></noscript>
<script src="assets/js/include.js" data-base="."></script>
</body>
</html>
+68
View File
@@ -0,0 +1,68 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Security — Keru OS</title>
<meta name="description" content="Keru's trust model: source-only builds, verification against fetch, no binary packages, a small auditable toolchain, and clean licensing.">
<link rel="stylesheet" href="assets/css/style.css">
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>ける</text></svg>">
</head>
<body>
<nav class="top" data-nav></nav>
<header class="pagehead">
<p class="crumbs"><a href="index.html">home</a> / <a href="docs.html">docs</a> / security</p>
<h1>Security</h1>
<p>The trust model, stated plainly.</p>
</header>
<section>
<div class="wrap">
<div class="prose">
<p>Keru's security stance follows from its design. No binaries, no opaque machinery, no hidden services. That shrinks the attack surface to things you can actually read.</p>
<h3>Source-only by construction</h3>
<p>There is no binary package store to compromise. Every package is compiled in your install from original source fetched over the network. The "prebuilt artifact" class of attack simply doesn't exist.</p>
<h3>Verified fetch</h3>
<ul class="features">
<li><strong>Mirror then upstream.</strong> Downloads prefer the project mirror and fall back to upstream, never the other way.</li>
<li><strong>Integrity enforced.</strong> A fetched tarball that doesn't verify is refused, not untarred. Failed verification is a hard stop.</li>
<li><strong>Pinned sources.</strong> Recipes pin the exact <code>url</code> and version. Nothing is ever pulled "latest" implicitly.</li>
</ul>
<h3>A toolchain you can audit</h3>
<div class="code-block">scripts/build-root.sh # ~shell; reads your make.conf
profile/make.conf # your choices, explicit
kama # ~225-line package manager
kama-packages/*.sh # recipes as plain shell you can read top to bottom</div>
<p>The whole vertical slice from "make.conf" to "booted system" is a handful of shell files. That's the honest counter to the "trust the distro binary blob" model.</p>
<h3>Privilege by your rules</h3>
<p>Privilege elevation is swappable: <code>doas</code> (slender, auditable) is the default, with sudo, opendoas, and plain <code>su</code> available. Keru never preloads root-owned services or hidden daemons.</p>
<h3>Kernel hardening, if you want it</h3>
<p>Pick <code>linux-hardened</code> at install for a hardened kernel, or stick with stable <code>linux</code>. The choice is yours and applied at the moment your system is built.</p>
<h3>Licensing, because supply chain is security</h3>
<p>All three repos are <span class="tag accent">AGPL-3.0</span>. Recipes tag their <code>license</code> explicitly. Nothing in the pipeline is proprietary-black-boxed.</p>
<div class="callout">Trust is transitive: you still trust the sources you install and the mirror that serves them. Keru's job is to make that trust chain visible and verifiable — not to pretend you can be protected from everything.</div>
<h3>Reporting</h3>
<p>Found a flaw in the installer, kama, or a recipe? File it with the stage and the failing artifact. See <a href="contact.html">contact</a> and <a href="troubleshooting.html">troubleshooting</a>.</p>
<p><a href="troubleshooting.html">← Troubleshooting</a> · <a href="toolchain.html">Toolchain bootstrap →</a></p>
</div>
</div>
</section>
<footer data-footer></footer>
<noscript><div style="text-align:center;padding:16px">See the <a href="sitemap.html">sitemap</a> for all pages.</div></noscript>
<script src="assets/js/include.js" data-base="."></script>
</body>
</html>
+10 -2
View File
@@ -37,9 +37,11 @@
<span class="tag">install</span> <span class="tag">install</span>
<ul class="features"> <ul class="features">
<li><a href="install.html">Install</a></li> <li><a href="install.html">Install</a></li>
<li><a href="installer-walkthrough.html">Installer walkthrough</a></li> <li><a href="getting-started.html">Getting started</a></li>
<li><a href="installation-requirements.html">Requirements</a></li> <li><a href="installation-requirements.html">Requirements</a></li>
<li><a href="installer-walkthrough.html">Installer walkthrough</a></li>
<li><a href="network-setup.html">Network setup</a></li> <li><a href="network-setup.html">Network setup</a></li>
<li><a href="troubleshooting.html">Troubleshooting</a></li>
</ul> </ul>
</div> </div>
<div> <div>
@@ -66,9 +68,15 @@
<li><a href="make-conf.html">make.conf</a></li> <li><a href="make-conf.html">make.conf</a></li>
<li><a href="profile.html">Profile system</a></li> <li><a href="profile.html">Profile system</a></li>
<li><a href="recipe-format.html">Recipe format</a></li> <li><a href="recipe-format.html">Recipe format</a></li>
<li><a href="recipe-authoring.html">Recipe authoring</a></li>
<li><a href="build-pipeline.html">Build pipeline</a></li> <li><a href="build-pipeline.html">Build pipeline</a></li>
<li><a href="toolchain.html">Toolchain bootstrap</a></li>
<li><a href="mkfs-root.html">mkfs-root</a></li> <li><a href="mkfs-root.html">mkfs-root</a></li>
<li><a href="live-init.html">Live init</a></li> <li><a href="live-init.html">Live init</a></li>
<li><a href="kama-config.html">Kama configuration</a></li>
<li><a href="mirror-cache.html">Mirrors &amp; cache</a></li>
<li><a href="security.html">Security</a></li>
<li><a href="release-process.html">Release process</a></li>
</ul> </ul>
</div> </div>
<div> <div>
@@ -98,7 +106,7 @@
</div> </div>
<div class="prose" style="margin-top:40px"> <div class="prose" style="margin-top:40px">
<p>Total: 32 pages, all served from <code>web/</code> in the KeruOS repo — plain static HTML, no framework, dark, with a shared nav/footer injected at runtime.</p> <p>Total: 48 pages, all served from <code>web/</code> in the KeruOS repo — plain static HTML, no framework, pure black, with a shared nav/footer injected at runtime.</p>
</div> </div>
</div> </div>
</section> </section>
+68
View File
@@ -0,0 +1,68 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Toolchain bootstrap — Keru OS</title>
<meta name="description" content="Stage 0 in depth: how Keru bootstraps binutils, gcc, and a C library from nothing, and then builds everything else on top.">
<link rel="stylesheet" href="assets/css/style.css">
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>ける</text></svg>">
</head>
<body>
<nav class="top" data-nav></nav>
<header class="pagehead">
<p class="crumbs"><a href="index.html">home</a> / <a href="docs.html">docs</a> / toolchain</p>
<h1>Toolchain bootstrap</h1>
<p>What "from scratch" actually means.</p>
</header>
<section>
<div class="wrap">
<div class="prose">
<p>A source distro that seeds its compiler is a lie wearing a costume. Keru's stage 0 builds the toolchain from nothing — the assembler, the compiler, the C library, then a self-hosted toolchain package — before a single package in your system tree is compiled.</p>
<h3>Why the order matters</h3>
<table>
<tr><th>Step</th><th>What runs</th><th>Why first</th></tr>
<tr><td>1</td><td><code>binutils</code></td><td>as, ld, ar — you can't compile without an assembler and linker.</td></tr>
<tr><td>2</td><td>a bare <code>gcc</code></td><td>The C compiler, built against nothing but binutils.</td></tr>
<tr><td>3</td><td>your <code>libc</code></td><td>glibc, musl, or uclibc-ng. Everything userspace depends on it.</td></tr>
<tr><td>4</td><td>a full <code>gcc</code></td><td>Re-built now that the target libc exists (self-hosting).</td></tr>
<tr><td>5</td><td><code>toolchain</code> package</td><td>Freezes the whole toolchain as a kama package for the rest of the build.</td></tr>
</table>
<h3>A bootstrap run</h3>
<div class="terminal">
<div class="tbar"><span class="dot r"></span><span class="dot y"></span><span class="dot g"></span><span class="t">$ sh scripts/build-root.sh</span></div>
<pre><span class="c">[ keru ]</span> stage 0: bootstrap toolchain
<span class="c">[ keru ]</span> binutils 2.42 <span class="p">... ok</span>
<span class="c">[ keru ]</span> gcc 13.2 (bare) <span class="p">... ok</span>
<span class="c">[ keru ]</span> glibc 2.39 <span class="p">... ok</span>
<span class="c">[ keru ]</span> gcc 13.2 (self) <span class="p">... ok</span>
<span class="c">[ keru ]</span> toolchain → ROOT <span class="k">... ok</span>
<span class="c">[ keru ]</span> stage 1: base system</pre>
</div>
<h3>Where it goes wrong</h3>
<ul class="features">
<li><strong>libc switch.</strong> Bootstrapping against musl or uclibc-ng rearranges the early stages; the exact package set lives with the <a href="libcs.html">libc page</a>. A combo that isn't proven yet gets a warning — never a silent block.</li>
<li><strong>Host leakage.</strong> Everything must link against the freshly built chain, not the build host's. The recipes pass explicit <code>--host/--target</code> and <code>CC</code>/<code>CFLAGS</code> so nothing sneaks in.</li>
<li><strong>Double-build cost.</strong> gcc is compiled twice by design. That's the price of honesty; it's also a warm-up for the rest of the arch.</li>
</ul>
<div class="callout">This is the line Keru draws: before your base system, a full self-hosting toolchain exists that didn't exist before. After that, the rest is just — as one long build script — more of the same.</div>
<p><a href="security.html">← Security</a> · <a href="build-pipeline.html">Build pipeline</a></p>
</div>
</div>
</section>
<footer data-footer></footer>
<noscript><div style="text-align:center;padding:16px">See the <a href="sitemap.html">sitemap</a> for all pages.</div></noscript>
<script src="assets/js/include.js" data-base="."></script>
</body>
</html>
+78
View File
@@ -0,0 +1,78 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Troubleshooting — Keru OS</title>
<meta name="description" content="Common Keru problems by stage — live boot, network, fetch, build, install, first boot — and how to fix each.">
<link rel="stylesheet" href="assets/css/style.css">
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>ける</text></svg>">
</head>
<body>
<nav class="top" data-nav></nav>
<header class="pagehead">
<p class="crumbs"><a href="index.html">home</a> / <a href="docs.html">docs</a> / troubleshooting</p>
<h1>Troubleshooting</h1>
<p>Diagnose by stage. The stage points at the file to blame.</p>
</header>
<section>
<div class="wrap">
<div class="prose">
<p>Almost every Keru failure lands in exactly one of five stages: <strong>live boot</strong>, <strong>network</strong>, <strong>fetch</strong>, <strong>build</strong>, or <strong>finalize</strong>. Figure out which, and you're most of the way to a fix.</p>
<h3>Live boot</h3>
<table>
<tr><th>Symptom</th><th>Cause / fix</th></tr>
<tr><td>Drops to an emergency shell</td><td><code>live/init</code> couldn't find the installer payload or mount buffers. Check the ISO layout and that you wrote the whole image, not just the files.</td></tr>
<tr><td>Installer never auto-starts</td><td>The live init runs <code>installer/install.sh</code> on boot. Run it by hand from the shell to see its errors directly.</td></tr>
<tr><td>Nothing on screen</td><td>Terminal TTY not your display? Verify the kernel picks your console; a plain <code>getty</code> on tty1 is the default.</td></tr>
</table>
<h3>Network</h3>
<ul class="features">
<li><strong>Installer says offline.</strong> It probes a few hosts (<code>1.1.1.1</code>, <code>github.com</code>, the project mirror) and loops: it will offer to run <code>nmtui</code>, then re-check. Let it.</li>
<li><strong>DHCP won't bite.</strong> Use <code>nmtui</code> and set a static address. The installer doesn't care how the link comes up, only that it does.</li>
<li><strong>Slow fetch.</strong> The org mirror <code>mirror.keru.org</code> is tried first; upstream is the fallback. A broken mirror yields timeouts — check <code>SOURCE_MIRROR</code>.</li>
</ul>
<h3>Fetch</h3>
<ul class="features">
<li><strong>404 on a download.</strong> The recipe's <code>url</code> missed a version bump. Fix it or report it — sources are pinned in kama-packages.</li>
<li><strong>Checksum mismatch.</strong> The tarball in the cache doesn't match the recipe. Clear the cache dir for that package: <code>rm -rf /var/cache/kama/dl/&lt;pkg&gt;</code>.</li>
<li><strong>Mirror poison.</strong> If a third-party mirror serves a tampered file, fetch fails verification and refuses to proceed — by design.</li>
</ul>
<h3>Build</h3>
<table>
<tr><th>Symptom</th><th>Cause / fix</th></tr>
<tr><td>Compile error in a package</td><td>Often a <code>C(FLAGS)</code> interaction or a missing build dep. Add the dep and re-run <code>kama make</code> — stage dirs cache progress.</td></tr>
<tr><td>Missing header</td><td>That's a temp-dep gap in the recipe's <code>deps=()</code>. Contribute the fix: one line in kama-packages.</td></tr>
<tr><td>Toolchain failure</td><td>Stage 0 is the sharpest edge. A failing binutils/gcc/libc bootstrap is a bug — file it with the full <code>make.conf</code> combo.</td></tr>
<tr><td>Kernel build dies with no reason</td><td>Free disk or memory on the build host first; kernel builds are hungry. Then check <code>KERNEL_CONFIG</code> in make.conf.</td></tr>
</table>
<h3>Finalize and first boot</h3>
<ul class="features">
<li><strong>mkfs fails.</strong> The target device is in use or the filesystem tools for your pick are missing. Unmount and retry.</li>
<li><strong>Won't boot.</strong> The init you chose must agree with how your bootloader was told to run it — check the boot command line and your init's expectations.</li>
<li><strong>No network after boot.</strong> Your network tool choice (nmtui alone won't auto-connect) needs to be started on <code>default</code> runlevel or its service enabled.</li>
<li><strong>Unstable combo.</strong> Keru warns on unproven pairs (musl+systemd, uclibc-ng, zfs root ...). Heed the warning or expect rough edges. It never blocks you.</li>
</ul>
<div class="callout">When you file an issue, include the stage, your full <code>make.conf</code> combo, and the failing output. That's everything a maintainer needs. See <a href="contact.html">contact</a>.</div>
<p><a href="getting-started.html">← Getting started</a> · <a href="security.html">Security model →</a></p>
</div>
</div>
</section>
<footer data-footer></footer>
<noscript><div style="text-align:center;padding:16px">See the <a href="sitemap.html">sitemap</a> for all pages.</div></noscript>
<script src="assets/js/include.js" data-base="."></script>
</body>
</html>