diff --git a/web/_includes/footer.html b/web/_includes/footer.html index 11e11fd..17a4908 100644 --- a/web/_includes/footer.html +++ b/web/_includes/footer.html @@ -13,6 +13,7 @@

Install

diff --git a/web/assets/css/style.css b/web/assets/css/style.css index 2c95934..47ce1b8 100644 --- a/web/assets/css/style.css +++ b/web/assets/css/style.css @@ -1,60 +1,55 @@ -/* Keru OS website — dark, modern, animated. - Reference: Gentoo's confident tech look, modernized. */ +/* Keru OS website — Ryoku-style. + 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'); :root { - --bg: #0a0e14; /* near-black blue */ - --bg-2: #0f1520; /* raised surface */ - --bg-3: #161e2e; /* cards */ - --border: #22304a; - --text: #d7e0ee; - --text-dim: #8b9bb4; - --text-bright: #ffffff; - --accent: #8b5cf6; /* keru violet */ - --accent-2: #22d3ee; /* cyan secondary */ - --accent-3: #34d399; /* green success */ - --warn: #f59e0b; /* amber */ - --danger: #ef4444; - --code-bg: #0d1220; + --paper: #000000; /* pure black paper */ + --paper-2: #0d0d0d; /* raised surface */ + --paper-3: #131313; /* cards */ + --hair: #262626; /* hairline borders */ + --ink: #cdc4ba; /* warm bone ink — body */ + --ink-dim: #8b8275; /* subdued ink */ + --ink-faint: #5b5348; /* farthest faded */ + --bone: #f2ede4; /* bright ink, emphasis */ + --accent: #ff3b1f; /* vermillion — the single accent */ + --ok: #58e1c2; + --warn: #f0a35e; + --danger: #ff3b1f; --mono: 'JetBrains Mono', ui-monospace, monospace; --sans: 'Inter', system-ui, -apple-system, sans-serif; - --grad: linear-gradient(135deg, var(--accent), var(--accent-2)); - --shadow: 0 8px 30px rgba(0,0,0,.4); - --radius: 12px; - --nav-h: 64px; + --radius: 0; /* sharp. always. */ + --nav-h: 60px; } * { margin: 0; padding: 0; box-sizing: border-box; } - +::selection { background: var(--accent); color: #000; } html { scroll-behavior: smooth; } body { - background: var(--bg); - color: var(--text); + background: var(--paper); + color: var(--ink); font-family: var(--sans); line-height: 1.65; -webkit-font-smoothing: antialiased; overflow-x: hidden; } -/* subtle animated grid backdrop */ +/* faint scanline texture — a taste of grain, no image */ body::before { content: ""; position: fixed; inset: 0; z-index: -1; background: - radial-gradient(circle at 20% -10%, rgba(139,92,246,.12), transparent 45%), - 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); + repeating-linear-gradient(180deg, transparent 0 3px, rgba(255,255,255,.008) 3px 4px); pointer-events: none; } -a { color: var(--accent-2); text-decoration: none; } -a:hover { text-decoration: underline; } - -::selection { background: var(--accent); color: #fff; } +a { color: var(--ink); text-decoration: none; } +a:hover { color: var(--bone); } /* ---------- top nav ---------- */ nav.top { @@ -62,372 +57,455 @@ nav.top { top: 0; z-index: 100; height: var(--nav-h); - background: rgba(10,14,20,.82); - backdrop-filter: blur(12px); - border-bottom: 1px solid var(--border); + background: rgba(0,0,0,.9); + backdrop-filter: blur(8px); + border-bottom: 1px solid var(--hair); display: flex; align-items: center; - padding: 0 28px; - gap: 8px; + padding: 0 26px; + gap: 4px; } .brand { font-family: var(--mono); font-weight: 700; - color: var(--text-bright); - font-size: 1.05rem; + color: var(--bone); + font-size: 1rem; letter-spacing: .02em; margin-right: auto; display: flex; 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; } nav.top a.navlink { - color: var(--text-dim); - font-size: .92rem; - font-weight: 500; + color: var(--ink-dim); + font-family: var(--mono); + text-transform: uppercase; + font-size: .72rem; + letter-spacing: .12em; padding: 6px 10px; - border-radius: 6px; - transition: color .15s, background .15s; + border: 1px solid transparent; + 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; } /* ---------- hero ---------- */ -.hero { - padding: 96px 28px 64px; - text-align: center; - animation: fadeUp .7s ease both; -} +.hero { padding: 84px 26px 54px; text-align: center; } + .kicker { display: inline-flex; align-items: center; - gap: 8px; + gap: 10px; font-family: var(--mono); - color: var(--accent-2); - border: 1px solid var(--border); - background: var(--bg-2); - padding: 4px 12px; - border-radius: 999px; - font-size: .8rem; - letter-spacing: .08em; + color: var(--ink-dim); text-transform: uppercase; + font-size: .72rem; + letter-spacing: .22em; + border: 1px solid var(--hair); + background: var(--paper-2); + padding: 5px 14px; } .kicker .dot { - width: 7px; height: 7px; border-radius: 50%; - background: var(--accent-3); - animation: pulse 2s infinite; + width: 7px; height: 7px; background: var(--accent); + animation: pulse 1.6s 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 { - font-size: clamp(2.6rem, 6vw, 4.6rem); - font-weight: 800; - line-height: 1.05; - color: var(--text-bright); - margin: 22px auto 18px; - max-width: 900px; - letter-spacing: -.02em; + font-family: var(--mono); + font-size: clamp(1.6rem, 4vw, 2.6rem); + font-weight: 700; + line-height: 1.1; + color: var(--bone); + letter-spacing: .02em; + margin: 14px auto 16px; + text-transform: uppercase; } -.hero h1 .grad { - background: var(--grad); - -webkit-background-clip: text; - background-clip: text; - 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; } +.hero h1 .grad { color: var(--accent); } +.hero p.sub { color: var(--ink-dim); max-width: 620px; margin: 0 auto 30px; font-size: 1rem; } + +.cta-row { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; } .btn { display: inline-flex; align-items: center; - gap: 8px; + gap: 10px; font-family: var(--mono); - font-weight: 500; + text-transform: uppercase; + letter-spacing: .1em; + font-size: .78rem; + font-weight: 700; padding: 12px 22px; - border-radius: 10px; - font-size: .95rem; - transition: transform .15s, box-shadow .15s, background .15s; + border: 1px solid var(--ink-dim); + color: var(--bone); + transition: color .15s, background .15s, border-color .15s, transform .1s; } -.btn:hover { text-decoration: none; transform: translateY(-2px); } -.btn-primary { background: var(--grad); color: #0a0e14; box-shadow: 0 4px 20px rgba(139,92,246,.4); } -.btn-primary:hover { box-shadow: 0 8px 28px rgba(139,92,246,.55); } -.btn-ghost { background: var(--bg-3); color: var(--text); border: 1px solid var(--border); } -.btn-ghost:hover { background: var(--bg-2); } +.btn:hover { text-decoration: none; } +.btn-primary { background: var(--accent); border-color: var(--accent); color: #000; } +.btn-primary:hover { background: #000; color: var(--accent); } +.btn-ghost { background: transparent; color: var(--ink-dim); } +.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 ---------- */ -section { padding: 56px 28px; } +section { padding: 54px 26px; } .wrap { max-width: 1080px; margin: 0 auto; } .section-title { font-family: var(--mono); text-transform: uppercase; - letter-spacing: .12em; - font-size: .82rem; - color: var(--accent-2); + letter-spacing: .2em; + font-size: .7rem; + color: var(--accent); 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; } -.lead { color: var(--text-dim); font-size: 1.05rem; max-width: 720px; margin-bottom: 30px; } +.section-title::before { content: "// "; opacity: .6; } +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-3 { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); } .grid-4 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); } .card { - background: var(--bg-3); - border: 1px solid var(--border); - border-radius: var(--radius); - padding: 22px; - transition: transform .2s, border-color .2s, box-shadow .2s; - animation: fadeUp .6s ease both; + background: var(--paper-2); + border: 1px solid var(--hair); + padding: 20px; + position: relative; + transition: border-color .15s, transform .1s, background .15s; } -.card:hover { transform: translateY(-4px); border-color: var(--accent); box-shadow: var(--shadow); } -.card.h { font-family: var(--mono); font-size: 1.05rem; color: var(--text-bright); margin-bottom: 8px; } -.card p { color: var(--text-dim); font-size: .95rem; } +.card::before { + content: ""; + 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 { font-family: var(--mono); - font-size: .75rem; - color: var(--accent-2); - border: 1px solid var(--border); + font-size: .68rem; + letter-spacing: .14em; + text-transform: uppercase; + color: var(--accent); + border: 1px solid var(--hair); padding: 2px 8px; - border-radius: 6px; display: inline-block; margin-bottom: 10px; } +a.card { color: inherit; } +a.card:hover { text-decoration: none; } -/* ---------- terminal/snippet ---------- */ +/* ---------- terminal / code ---------- */ .terminal { - background: #05080d; - border: 1px solid var(--border); - border-radius: var(--radius); + background: #050505; + border: 1px solid var(--hair); overflow: hidden; - box-shadow: var(--shadow); text-align: left; margin: 0 auto; - max-width: 640px; + max-width: 660px; } .terminal .tbar { - background: var(--bg-2); - padding: 10px 14px; + background: var(--paper-2); + padding: 9px 12px; display: flex; gap: 6px; 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 .y { background: var(--warn); } -.terminal .tbar .g { background: var(--accent-3); } -.terminal .tbar .t { margin-left: 8px; font-family: var(--mono); font-size: .75rem; color: var(--text-dim); } -.terminal pre { - padding: 18px; - overflow-x: auto; +.terminal .tbar .g { background: var(--ok); } +.terminal .tbar .t { + margin-left: 10px; font-family: var(--mono); - font-size: .85rem; - line-height: 1.7; - color: var(--text); + font-size: .72rem; + color: var(--ink-faint); + text-transform: uppercase; + letter-spacing: .1em; } -.terminal .c { color: var(--accent-2); } -.terminal .k { color: var(--accent-3); } -.terminal .p { color: var(--text-dim); } +.terminal pre { padding: 18px; overflow-x: auto; font-family: var(--mono); font-size: .84rem; line-height: 1.75; color: var(--ink); } +.terminal .c { color: var(--accent); } +.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 { - background: var(--code-bg); - border: 1px solid var(--border); - border-radius: 10px; + background: #050505; + border: 1px solid var(--hair); + border-left: 3px solid var(--accent); padding: 18px; overflow-x: auto; margin: 18px 0; - font-size: .85rem; + font-size: .84rem; line-height: 1.7; - color: var(--text); + color: var(--ink); } code:not(.code-block) { - background: var(--bg-3); - border: 1px solid var(--border); - border-radius: 5px; + background: var(--paper-2); + border: 1px solid var(--hair); padding: 2px 6px; font-size: .85em; - color: var(--accent-2); + color: var(--accent); } kbd { - background: var(--bg-3); - border: 1px solid var(--border); + background: var(--paper-2); + border: 1px solid var(--hair); border-bottom-width: 2px; - border-radius: 5px; padding: 1px 6px; font-size: .8em; } -/* ---------- lists / prose ---------- */ +/* ---------- prose ---------- */ .prose { max-width: 760px; margin: 0 auto; } .prose h3 { - color: var(--text-bright); - font-size: 1.25rem; - margin: 34px 0 10px; + font-family: var(--mono); + text-transform: uppercase; + letter-spacing: .04em; + color: var(--bone); + font-size: 1.1rem; + margin: 32px 0 10px; font-weight: 700; } -.prose h4 { color: var(--accent-2); margin: 22px 0 8px; font-size: 1.05rem; } -.prose p { margin: 12px 0; color: var(--text); } -.prose ul, .prose ol { margin: 12px 0 12px 24px; } -.prose li { margin: 6px 0; color: var(--text); } +.prose h3::before { content: "# "; color: var(--accent); } +.prose h4 { color: var(--accent); margin: 22px 0 8px; font-size: .95rem; font-family: var(--mono); } +.prose p { margin: 12px 0; color: var(--ink); } +.prose ul, .prose ol { margin: 12px 0 12px 22px; } +.prose li { margin: 6px 0; color: var(--ink); } .prose li::marker { color: var(--accent); } .prose blockquote { border-left: 3px solid var(--accent); - background: var(--bg-2); + background: var(--paper-2); padding: 14px 18px; - border-radius: 0 8px 8px 0; margin: 18px 0; - color: var(--text-dim); + color: var(--ink-dim); } -.prose blockquote strong { color: var(--text-bright); } -.prose hr { border: none; border-top: 1px solid var(--border); 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); } +.prose blockquote strong { color: var(--bone); } +.prose hr { border: none; border-top: 1px solid var(--hair); margin: 30px 0; } -/* 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 { display: inline-block; font-family: var(--mono); - font-size: .72rem; - letter-spacing: .05em; + font-size: .66rem; + letter-spacing: .12em; text-transform: uppercase; padding: 2px 9px; - border-radius: 999px; - border: 1px solid var(--border); - color: var(--accent-2); + border: 1px solid var(--hair); + color: var(--ink-dim); margin: 2px 4px 2px 0; } -.tag.warn { color: var(--warn); border-color: rgba(245,158,11,.4); } -.tag.danger { color: var(--danger); border-color: rgba(239,68,68,.4); } -.tag.ok { color: var(--accent-3); border-color: rgba(52,211,153,.4); } +.tag.warn { color: var(--warn); border-color: var(--warn); } +.tag.danger { color: var(--danger); border-color: var(--danger); } +.tag.ok { color: var(--ok); border-color: var(--ok); } +.tag.accent { color: var(--accent); border-color: var(--accent); } -/* pill callout */ .callout { - border: 1px solid var(--border); + border: 1px solid var(--hair); border-left: 3px solid var(--accent); - background: var(--bg-2); - border-radius: 8px; + background: var(--paper-2); padding: 14px 18px; margin: 18px 0; } .callout.warn { border-left-color: var(--warn); } .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 li { padding: 10px 0; border-bottom: 1px solid var(--border); display: flex; gap: 12px; } -.features li::before { content: "◆"; color: var(--accent); } +.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); } /* ---------- news ---------- */ .post-list { max-width: 820px; margin: 0 auto; } .post-item { display: block; - background: var(--bg-3); - border: 1px solid var(--border); - border-radius: var(--radius); - padding: 20px 24px; - margin-bottom: 16px; - transition: transform .15s, border-color .15s; + background: var(--paper-2); + border: 1px solid var(--hair); + padding: 20px 22px; + margin-bottom: 14px; + transition: border-color .15s, transform .1s; } .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 .meta { font-family: var(--mono); font-size: .78rem; color: var(--text-dim); margin-bottom: 6px; } -.post-item p { color: var(--text-dim); font-size: .95rem; } +.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: .72rem; color: var(--ink-faint); text-transform: uppercase; letter-spacing: .1em; margin-bottom: 6px; } +.post-item p { color: var(--ink-dim); font-size: .92rem; } /* ---------- footer ---------- */ -footer { - border-top: 1px solid var(--border); - background: var(--bg-2); - padding: 40px 28px 32px; - 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 { border-top: 1px solid var(--hair); background: var(--paper-2); padding: 38px 26px 30px; margin-top: 40px; } +footer .wrap { display: flex; gap: 34px; flex-wrap: wrap; justify-content: space-between; } +footer h4 { color: var(--bone); font-family: var(--mono); font-size: .72rem; text-transform: uppercase; letter-spacing: .16em; margin-bottom: 12px; } +footer h4::before { content: "// "; color: var(--accent); } footer ul { list-style: none; } footer li { margin: 6px 0; } -footer a { color: var(--text-dim); } -footer a:hover { color: var(--text-bright); text-decoration: none; } +footer a { color: var(--ink-dim); } +footer a:hover { color: var(--bone); text-decoration: none; } footer .foot { - margin-top: 30px; - padding-top: 20px; - border-top: 1px solid var(--border); + margin-top: 28px; + padding-top: 18px; + 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-size: .78rem; - color: var(--text-dim); - text-align: center; + display: flex; + 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 { - from { opacity: 0; transform: translateY(18px); } + from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: translateY(0); } } -@keyframes pulse { - 0%, 100% { opacity: 1; } - 50% { opacity: .35; } +@keyframes fadeLeft { + from { opacity: 0; transform: translateX(-14px); } + to { opacity: 1; transform: translateX(0); } } -.reveal { animation: fadeUp .7s ease both; } -.d1 { animation-delay: .1s; } -.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 pulse { 0%,100% { opacity: 1; } 50% { opacity: .25; } } +@keyframes blink { 0%,49% { opacity: 1; } 50%,100% { opacity: 0; } } @keyframes ticker { from { transform: translateX(0); } to { transform: translateX(-50%); } } +@keyframes sweep { + 0% { background-position: -200% 0; } + 100% { background-position: 200% 0; } +} -/* stat blocks */ -.stats { display: flex; gap: 28px; flex-wrap: wrap; justify-content: center; margin: 24px 0; } -.stat { text-align: center; } -.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; } -.stat .lbl { color: var(--text-dim); font-size: .85rem; } +.reveal { animation: fadeUp .6s ease both; } +.d1 { animation-delay: .08s; } +.d2 { animation-delay: .16s; } +.d3 { animation-delay: .24s; } +.d4 { animation-delay: .32s; } +.d5 { animation-delay: .40s; } -/* page header (non-hero pages) */ -.pagehead { padding: 72px 28px 32px; text-align: center; } -.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; } +/* blinking caret after brand */ +.caret { display: inline-block; width: 8px; height: 1em; background: var(--accent); margin-left: 2px; vertical-align: -0.15em; animation: blink 1.1s infinite; } -/* breadcrumb */ -.crumbs { font-family: var(--mono); font-size: .78rem; color: var(--text-dim); max-width: 760px; margin: 20px auto 0; } -.crumbs a { color: var(--accent-2); } +/* accent headline underline sweep on hover */ +.head { background: linear-gradient(90deg, var(--accent), var(--accent), var(--accent)) no-repeat; + 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 */ @media (max-width: 720px) { nav.top { padding: 0 14px; } nav.top a.navlink { display: none; } .menu-toggle { display: inline-flex; } - .hero { padding: 64px 18px 40px; } - section { padding: 40px 18px; } - footer .wrap { gap: 24px; } + .hero { padding: 56px 18px 34px; } + section { padding: 38px 18px; } + footer .wrap { gap: 20px; } + .dossier { grid-template-columns: 1fr; } } \ No newline at end of file diff --git a/web/contact.html b/web/contact.html index 54c51ae..3ebf2b2 100644 --- a/web/contact.html +++ b/web/contact.html @@ -15,7 +15,7 @@

home / community / contact

Contact

-

Use issues for bugs and ideas; the list for discussion.

+

Use issues for bugs and ideas; email for discussion.

@@ -28,16 +28,10 @@

AstralZX/KeruOS issues

- discussion - Mailing list -

Longer conversations about philosophy, design decisions, and direction. Subscribe or join the thread.

-

keru@keru.org (placeholder)

-
-
- channel - Matrix -

A real-time room for early adopters and contributors.

-

#keru:matrix.org (placeholder)

+ direct + Email +

Longer conversations about philosophy, design decisions, and direction.

+

wowastral7@gmail.com

code diff --git a/web/docs.html b/web/docs.html index dbfbb0c..f874119 100644 --- a/web/docs.html +++ b/web/docs.html @@ -21,11 +21,19 @@
+ guideGetting started

From booting the ISO to a first-boot system — the whole arc in one read.

referencemake.conf

The profile file your selections produce, and every variable it knows.

referenceProfile system

How profile/make.conf templates the build and the swappables.

specRecipe format

The formal spec for kama package recipes — fields, hooks, tiers.

+ howtoRecipe authoring

Write your first kama recipe, with real examples from the repo.

referenceBuild pipeline

scripts/build-root.sh and mkfs-root.sh — how a make.conf becomes a rootfs.

+ referenceToolchain bootstrap

binutils → gcc → libc → self-host: what "from scratch" means.

referenceLive init

live/init — how booting the ISO auto-starts the installer.

+ referenceKama configuration

Every kama variable: PKGDIR, ROOT, CACHEDIR, MAKE_CONF, mirrors.

+ referenceMirrors & cache

The download order and the dl/src/stage cache layout.

+ referenceSecurity

Trust model of a source-only build, stated plainly.

+ guideTroubleshooting

Diagnose by stage — boot, network, fetch, build, finalize.

+ referenceRelease process

What a release contains, and how versioning works.

guideSwappables guide

Every component you can choose at install, with the full option list.

guideInstall guide

The end-to-end installation flow, from BIOS to boot.

guideContribute

How to get involved across the three repos and this site.

diff --git a/web/getting-started.html b/web/getting-started.html new file mode 100644 index 0000000..56c6fb8 --- /dev/null +++ b/web/getting-started.html @@ -0,0 +1,77 @@ + + + + + +Getting started — Keru OS + + + + + + + + +
+

home / docs / getting started

+

Getting started

+

Zero to a chosen, booting, source-built system.

+
+ +
+
+
+

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.

+ +

Before you begin

+
    +
  • A working network. The build is fully online — every source tarball is downloaded fresh at install time.
  • +
  • A spare target disk. mkfs-root.sh formats whatever root device the installer points at. It will be written over.
  • +
  • Patience for the first build. Fetch + compile of the full toolchain and system takes a while on modest hardware.
  • +
  • Decisions. Prep your picks ahead — or just press enter; sane defaults are documented on every prompt.
  • +
+ +

The flow

+
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
+ +

Your picks

+ + + + + + + + +
ChoiceDefaultWhy you might change it
Init systemrunitsystemd for optional use — but Keru never forces it.
C libraryglibcmusl for a smaller static-leaning system.
Filesystemext4btrfs snapshots, zfs features, xfs scaling.
Kernellinuxlinux-lts for longevity, hardened for attacks.
Privilege elevationdoassudo if you live in its muscle memory.
Network toolsnmtuinetworkmanager, connman, or systemd-networkd.
+ +
Every option here has a dedicated page. See the swappables guide and its sub-pages before you install, so boot rehearsal is boring by design.
+ +

Day one

+

Keru installs a bare, honest base — the packages you chose plus the few kama needs to run. From there you shape the rest:

+
# 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
+

Everything you don't install, you don't get. No services pretending to be useful, no telemetry phone-home.

+ +
Now read the installer walkthrough for the fine detail, or go straight to troubleshooting when something surprises you.
+ +

← Install overview · Network setup

+
+
+
+ +
+ + + + + + \ No newline at end of file diff --git a/web/index.html b/web/index.html index b11b1fa..e686f3a 100644 --- a/web/index.html +++ b/web/index.html @@ -13,16 +13,28 @@
- independent · source-only · linux -

You don't install a system.
You craft one.

-

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.

-
- ↓ Download 0.1 + independent · source-only · linux + ける +

You don't install a system.
You craft one.

+

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.

+
+
+
NameKeru OS ける
+
StatusUNDER CONSTRUCTION
+
Distributionsource-only linux
+
Package managerkama · ~225 lines
+
Defining traitanti-opinionated
+
Opinions forced0
+
Base packages0 (everything is swappable)
+
Modelboot ISO → choose → built from source
+
+
runit · s6 · openrc · systemd · busybox-init · sysvinit · dinit · shepherd @@ -30,7 +42,7 @@ ext4 · btrfs · xfs · zfs · f2fs · jfs · reiserfs linux · linux-lts · linux-hardened · linux-cachyos · linux-zen doas · sudo · opendoas · su - ける・けいとうてき — craft your system + ける・けいとうてき — craft your system
@@ -52,22 +64,22 @@
-
+
-

live demo

+

live boot

Boot. Choose. Built from source.

-

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.

+

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.

keru@live:~$
[ keru ] Keru OS — craft your system
 Select the components, press enter for defaults.
 
-== Init system ==       [runit]
-== C library ==         [glibc]
-== Filesystem ==        [ext4]
-== Kernel ==            [linux]
+== Init system ==        [runit]
+== C library ==          [glibc]
+== Filesystem ==         [ext4]
+== Kernel ==             [linux]
 == Privilege elevation == [doas]
-== Network tools ==     [nmtui]
+== Network tools ==      [nmtui]
 
 Selecting: btrfs  ← you choose, Keru builds it
 ...fetching source...
@@ -99,8 +111,8 @@ Selecting: btrfs  ← you choose, Keru builds it
     
-
-
+
+

Ready when it's ready.

Keru 0.1 will ship as a bootable ISO. No source builds, no manual tooling — boot, choose, then watch it craft your system.

diff --git a/web/kama-config.html b/web/kama-config.html new file mode 100644 index 0000000..9d51434 --- /dev/null +++ b/web/kama-config.html @@ -0,0 +1,77 @@ + + + + + +Kama configuration — Keru OS + + + + + + + + +
+

home / docs / kama configuration

+

Kama configuration

+

Every knob, every default, every path.

+
+ +
+
+
+

Kama's configuration is environment variables. Nothing to edit inside the script, nothing hidden — set them in the environment (export in a profile, or inline on the command line) and it's done.

+ +

Variables

+ + + + + + + + + +
VariableDefaultWhat it controls
PKGDIRthe kama-packages repo, sibling of the kama scriptWhere recipes are found.
ROOT/tmp/keru/rootWhere installed files land.
CACHEDIR/var/cache/kamaBase for the dirty working dirs.
MAKE_CONF/etc/kama/make.confProfile settings (JOBS, CFLAGS, etc.) if present.
SOURCE_MIRRORunsetMirror tried before upstream (set to e.g. mirror.keru.org).
PURGE_TEMP_DEPS1Purge temp build deps after kama make.
JOBSnprocParallel build jobs; recipes call make -j"$JOBS".
+ +

Cache layout

+
$CACHEDIR/ +├── dl/ downloaded archives +├── src/ extracted source per package +└── stage/ staged installs, committed to $ROOT on success
+ +

Common setups

+
# 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
+ +

make.conf integration

+

Inside an installed Keru system, the profile at MAKE_CONF feeds the same variables into kama and the build scripts. Your make.conf reference lists the full set.

+ +
    +
  • If MAKE_CONF exists it is sourced; missing is not an error.
  • +
  • The installer writes JOBS and CFLAGS from build-host detection.
  • +
  • Every variable has a sane default, so kama runs with zero config.
  • +
+ +
Zero-config by default, fully pointed overrides when you need them. That's the whole story — read on for recipes.
+ +

← kama usage · make.conf

+
+
+
+ +
+ + + + + + \ No newline at end of file diff --git a/web/mirror-cache.html b/web/mirror-cache.html new file mode 100644 index 0000000..17d26a0 --- /dev/null +++ b/web/mirror-cache.html @@ -0,0 +1,73 @@ + + + + + +Mirrors and cache — Keru OS + + + + + + + + +
+

home / docs / mirrors & cache

+

Mirrors and cache

+

Where source comes from, and where it waits.

+
+ +
+
+
+

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.

+ +

Download order

+
    +
  • 1. SOURCE_MIRROR — tried first when set (the org runs mirror.keru.org so the org can carry most of the traffic).
  • +
  • 2. Upstream — the canonical source URL from the recipe. Used when no mirror is set or the mirror lacks a file.
  • +
  • Verification at every step. A file that doesn't match its checksum is dropped, and the next source in line is tried. Tampered files never reach a build.
  • +
+ +

The cache layout

+
/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
+ + + + + + +
DirEverythingPurpose
dlDownloadsAlready-downloaded archives are reused, never re-fetched.
srcExtractedExtraction is skipped when the checked-out source is present.
stageStaged buildsProgress survives a failed build; re-running continues.
+ +

Working offline, or your own mirror

+
# 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
+

Run a mirror yourself and point SOURCE_MIRROR at it. The layout mirrors dl/; the fetch layer treats it as a read-mostly source of truth.

+ +

Cleanup

+
    +
  • rm -rf /var/cache/kama/src/* — free extracted source (re-extracts on next build).
  • +
  • rm -rf /var/cache/kama/dl/* — dump downloads (re-fetches next time).
  • +
  • rm -rf /var/cache/kama/stage/* — discard staged builds.
  • +
+ +
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.
+ +

← kama usage · Troubleshooting

+
+
+
+ +
+ + + + + + \ No newline at end of file diff --git a/web/news/announcing-keru.html b/web/news/announcing-keru.html index bbf25e0..4a94662 100644 --- a/web/news/announcing-keru.html +++ b/web/news/announcing-keru.html @@ -15,7 +15,7 @@

home / news / announcing keru

Introducing Keru OS

-

2026-09-01 · announcement

+

2026-09-01 · announcement

diff --git a/web/news/design-decisions.html b/web/news/design-decisions.html index 89a1c26..09d518b 100644 --- a/web/news/design-decisions.html +++ b/web/news/design-decisions.html @@ -15,7 +15,7 @@

home / news / design decisions

Design decisions, so far

-

2026-09-01 · design

+

2026-09-01 · design

diff --git a/web/news/philosophy-is-architecture.html b/web/news/philosophy-is-architecture.html index 6fe4dca..877dc2d 100644 --- a/web/news/philosophy-is-architecture.html +++ b/web/news/philosophy-is-architecture.html @@ -15,7 +15,7 @@

home / news / philosophy is the architecture

The philosophy is the architecture

-

2026-09-01 · design

+

2026-09-01 · design

diff --git a/web/news/roadmap-0.1.html b/web/news/roadmap-0.1.html index d519a0e..db98701 100644 --- a/web/news/roadmap-0.1.html +++ b/web/news/roadmap-0.1.html @@ -15,7 +15,7 @@

home / news / road to 0.1

The road to 0.1

-

2026-09-01 · roadmap

+

2026-09-01 · roadmap

diff --git a/web/recipe-authoring.html b/web/recipe-authoring.html new file mode 100644 index 0000000..eb38ef4 --- /dev/null +++ b/web/recipe-authoring.html @@ -0,0 +1,97 @@ + + + + + +Recipe authoring — Keru OS + + + + + + + + +
+

home / docs / recipe authoring

+

Recipe authoring

+

Writing a kama recipe, top to bottom.

+
+ +
+
+
+

Every package in a Keru system is described by a recipe: a plain POSIX shell script in kama-packages. Writing one is closer to filling a form than engineering a build.

+ +

The template

+

kama-packages/TEMPLATE.sh is the canonical starting point. Copy it, fill the easy tier:

+
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 +}
+ +

A real, complete recipe

+

This is the entire busybox recipe currently in the repo:

+
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" +}
+

That's it. Kama downloads, extracts, strips the top dir, builds, stages, and installs.

+ +

Stepping up

+ + + + + + + + +
NeedField / function
Colliding with another packageprovides=(...) conflicts=(...)
Build deps that must stayruntime_deps=(...)
Arch-restrictedarch=(x86_64)
Repo or vcs sourcesnoextract=("$url") + own build()
Custom fetch (patch first)pkg_fetch() { default_fetch; patch ...; }
Post-install workpkg_post() · pkg_split() for subpackages
+ +

Rules of the road

+
    +
  • Stage, don't touch. install() installs into $pkgdir. Kama commits the staging dir to $ROOT only after a successful build.
  • +
  • Add pure build deps to deps. They're purged automatically after the build (AUR-style). Keeps the door clean.
  • +
  • Declare the license. license=(SPDX) — supply chain cleanliness starts here.
  • +
  • Pin exactly. A fixed url + version, never a moving "latest".
  • +
+ +

Checking your work

+
sh -n recipe.sh # syntax check +kama info <pkgname> # metadata parses (name from the recipe) +make recipe-check # lint the whole kama-packages repo +kama make <pkgname> # build it for real
+ +
The behavioral spec lives at recipe format. For hands-on, mirror the recipe concept page and start with busybox.sh, the smallest real recipe.
+ +

← Recipe format · The repos

+
+
+
+ +
+ + + + + + \ No newline at end of file diff --git a/web/release-process.html b/web/release-process.html new file mode 100644 index 0000000..a4247a1 --- /dev/null +++ b/web/release-process.html @@ -0,0 +1,67 @@ + + + + + +Release process — Keru OS + + + + + + + + +
+

home / docs / release process

+

Release process

+

How a release leaves the kiln.

+
+ +
+
+
+

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.

+ +

Versioning

+
keru-0.1.0.iso # {major}.{minor}.{patch}
+ + + + + +
BumpWhen
majorThe swappable set changes shape, or the philosophy moves — real milestones like the first ISO.
minorNew swappable or a new kama feature that stays backward-compatible.
patchRecipe fixes, installer bugfixes, docs — anything that changes no contracts.
+ +

What the release ISO contains

+
    +
  • The installer. installer/install.sh plus its payload.
  • +
  • The live init. live/init — boot the ISO, installer auto-runs.
  • +
  • The repos. kama and kama-packages pinned at the release commit.
    Everything else — every source tarball, every toolchain compile — is fetched and built at install time.
  • +
+ +

Release readiness

+ + + + + + +
CheckWhat passes it
Combos bootThe proven set of the offered swappables all boot after install.
Installer cleanA full install from a cold boot, no keyboard runtime.
No blockersNothing warns-but-doesn't-block where it shouldn't; unproven combos warn loudly.
Docs matchmake.conf, recipes, and this website agree with the shipped code.
+ +

Announcements

+

Releases are announced on the news page, 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.

+ +
Deliberately unglamorous. A release is a checkpoint the community can trust, not a marketing event. Read the news for the current one.
+ +

Contribute · → Status / news

+
+
+
+ +
+ + + + + + \ No newline at end of file diff --git a/web/security.html b/web/security.html new file mode 100644 index 0000000..ab415ca --- /dev/null +++ b/web/security.html @@ -0,0 +1,68 @@ + + + + + +Security — Keru OS + + + + + + + + +
+

home / docs / security

+

Security

+

The trust model, stated plainly.

+
+ +
+
+
+

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.

+ +

Source-only by construction

+

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.

+ +

Verified fetch

+
    +
  • Mirror then upstream. Downloads prefer the project mirror and fall back to upstream, never the other way.
  • +
  • Integrity enforced. A fetched tarball that doesn't verify is refused, not untarred. Failed verification is a hard stop.
  • +
  • Pinned sources. Recipes pin the exact url and version. Nothing is ever pulled "latest" implicitly.
  • +
+ +

A toolchain you can audit

+
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
+

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.

+ +

Privilege by your rules

+

Privilege elevation is swappable: doas (slender, auditable) is the default, with sudo, opendoas, and plain su available. Keru never preloads root-owned services or hidden daemons.

+ +

Kernel hardening, if you want it

+

Pick linux-hardened at install for a hardened kernel, or stick with stable linux. The choice is yours and applied at the moment your system is built.

+ +

Licensing, because supply chain is security

+

All three repos are AGPL-3.0. Recipes tag their license explicitly. Nothing in the pipeline is proprietary-black-boxed.

+ +
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.
+ +

Reporting

+

Found a flaw in the installer, kama, or a recipe? File it with the stage and the failing artifact. See contact and troubleshooting.

+ +

← Troubleshooting · Toolchain bootstrap →

+
+
+
+ +
+ + + + + + \ No newline at end of file diff --git a/web/sitemap.html b/web/sitemap.html index 70399dd..fd46ef8 100644 --- a/web/sitemap.html +++ b/web/sitemap.html @@ -37,9 +37,11 @@ install
@@ -98,7 +106,7 @@
-

Total: 32 pages, all served from web/ in the KeruOS repo — plain static HTML, no framework, dark, with a shared nav/footer injected at runtime.

+

Total: 48 pages, all served from web/ in the KeruOS repo — plain static HTML, no framework, pure black, with a shared nav/footer injected at runtime.

diff --git a/web/toolchain.html b/web/toolchain.html new file mode 100644 index 0000000..a04248c --- /dev/null +++ b/web/toolchain.html @@ -0,0 +1,68 @@ + + + + + +Toolchain bootstrap — Keru OS + + + + + + + + +
+

home / docs / toolchain

+

Toolchain bootstrap

+

What "from scratch" actually means.

+
+ +
+
+
+

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.

+ +

Why the order matters

+ + + + + + + +
StepWhat runsWhy first
1binutilsas, ld, ar — you can't compile without an assembler and linker.
2a bare gccThe C compiler, built against nothing but binutils.
3your libcglibc, musl, or uclibc-ng. Everything userspace depends on it.
4a full gccRe-built now that the target libc exists (self-hosting).
5toolchain packageFreezes the whole toolchain as a kama package for the rest of the build.
+ +

A bootstrap run

+
+
$ sh scripts/build-root.sh
+
[ keru ] stage 0: bootstrap toolchain
+[ keru ]   binutils 2.42        ... ok
+[ keru ]   gcc 13.2 (bare)     ... ok
+[ keru ]   glibc 2.39          ... ok
+[ keru ]   gcc 13.2 (self)     ... ok
+[ keru ]   toolchain → ROOT    ... ok
+[ keru ] stage 1: base system
+
+ +

Where it goes wrong

+
    +
  • libc switch. Bootstrapping against musl or uclibc-ng rearranges the early stages; the exact package set lives with the libc page. A combo that isn't proven yet gets a warning — never a silent block.
  • +
  • Host leakage. Everything must link against the freshly built chain, not the build host's. The recipes pass explicit --host/--target and CC/CFLAGS so nothing sneaks in.
  • +
  • Double-build cost. gcc is compiled twice by design. That's the price of honesty; it's also a warm-up for the rest of the arch.
  • +
+ +
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.
+ +

← Security · Build pipeline

+
+
+
+ +
+ + + + + + \ No newline at end of file diff --git a/web/troubleshooting.html b/web/troubleshooting.html new file mode 100644 index 0000000..68dfbe1 --- /dev/null +++ b/web/troubleshooting.html @@ -0,0 +1,78 @@ + + + + + +Troubleshooting — Keru OS + + + + + + + + +
+

home / docs / troubleshooting

+

Troubleshooting

+

Diagnose by stage. The stage points at the file to blame.

+
+ +
+
+
+

Almost every Keru failure lands in exactly one of five stages: live boot, network, fetch, build, or finalize. Figure out which, and you're most of the way to a fix.

+ +

Live boot

+ + + + + +
SymptomCause / fix
Drops to an emergency shelllive/init couldn't find the installer payload or mount buffers. Check the ISO layout and that you wrote the whole image, not just the files.
Installer never auto-startsThe live init runs installer/install.sh on boot. Run it by hand from the shell to see its errors directly.
Nothing on screenTerminal TTY not your display? Verify the kernel picks your console; a plain getty on tty1 is the default.
+ +

Network

+
    +
  • Installer says offline. It probes a few hosts (1.1.1.1, github.com, the project mirror) and loops: it will offer to run nmtui, then re-check. Let it.
  • +
  • DHCP won't bite. Use nmtui and set a static address. The installer doesn't care how the link comes up, only that it does.
  • +
  • Slow fetch. The org mirror mirror.keru.org is tried first; upstream is the fallback. A broken mirror yields timeouts — check SOURCE_MIRROR.
  • +
+ +

Fetch

+
    +
  • 404 on a download. The recipe's url missed a version bump. Fix it or report it — sources are pinned in kama-packages.
  • +
  • Checksum mismatch. The tarball in the cache doesn't match the recipe. Clear the cache dir for that package: rm -rf /var/cache/kama/dl/<pkg>.
  • +
  • Mirror poison. If a third-party mirror serves a tampered file, fetch fails verification and refuses to proceed — by design.
  • +
+ +

Build

+ + + + + + +
SymptomCause / fix
Compile error in a packageOften a C(FLAGS) interaction or a missing build dep. Add the dep and re-run kama make — stage dirs cache progress.
Missing headerThat's a temp-dep gap in the recipe's deps=(). Contribute the fix: one line in kama-packages.
Toolchain failureStage 0 is the sharpest edge. A failing binutils/gcc/libc bootstrap is a bug — file it with the full make.conf combo.
Kernel build dies with no reasonFree disk or memory on the build host first; kernel builds are hungry. Then check KERNEL_CONFIG in make.conf.
+ +

Finalize and first boot

+
    +
  • mkfs fails. The target device is in use or the filesystem tools for your pick are missing. Unmount and retry.
  • +
  • Won't boot. 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.
  • +
  • No network after boot. Your network tool choice (nmtui alone won't auto-connect) needs to be started on default runlevel or its service enabled.
  • +
  • Unstable combo. Keru warns on unproven pairs (musl+systemd, uclibc-ng, zfs root ...). Heed the warning or expect rough edges. It never blocks you.
  • +
+ +
When you file an issue, include the stage, your full make.conf combo, and the failing output. That's everything a maintainer needs. See contact.
+ +

← Getting started · Security model →

+
+
+
+ +
+ + + + + + \ No newline at end of file