diff options
| -rw-r--r-- | .github/workflows/deploy.yml | 39 | ||||
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | README.md | 33 | ||||
| -rw-r--r-- | config.toml | 17 | ||||
| -rw-r--r-- | content/_index.md | 22 | ||||
| -rw-r--r-- | content/apps/_index.md | 10 | ||||
| -rw-r--r-- | content/apps/daybyday.md | 13 | ||||
| -rw-r--r-- | content/apps/domain-dig.md | 14 | ||||
| -rw-r--r-- | content/apps/hutch.md | 14 | ||||
| -rw-r--r-- | content/apps/solar.md | 13 | ||||
| -rw-r--r-- | content/services/_index.md | 42 | ||||
| -rw-r--r-- | sass/main.scss | 170 | ||||
| -rw-r--r-- | static/CNAME | 1 | ||||
| -rw-r--r-- | static/favicon.svg | 4 | ||||
| -rw-r--r-- | templates/base.html | 30 | ||||
| -rw-r--r-- | templates/index.html | 14 | ||||
| -rw-r--r-- | templates/page.html | 16 | ||||
| -rw-r--r-- | templates/section.html | 29 |
18 files changed, 482 insertions, 0 deletions
diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..50b0584 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,39 @@ +name: Deploy to GitHub Pages + +on: + push: + branches: [main] + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: pages + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Build with Zola + uses: shalzz/zola-deploy-action@master + env: + BUILD_ONLY: true + BUILD_DIR: . + - uses: actions/upload-pages-artifact@v3 + with: + path: public + + deploy: + needs: build + runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - id: deployment + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c75eecc --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/public diff --git a/README.md b/README.md new file mode 100644 index 0000000..0e0b3e8 --- /dev/null +++ b/README.md @@ -0,0 +1,33 @@ +# krz.sh + +Source for [krz.sh](https://krz.sh) — the krazy warez website. Built with +[Zola](https://www.getzola.org/). + +## Develop + +```sh +zola serve +``` + +Then open http://127.0.0.1:1111. + +## Build + +```sh +zola build +``` + +Output is written to `public/`. + +## Structure + +- `config.toml` — site configuration +- `content/` — pages (home, `services/`, `apps/`, `about/`) +- `templates/` — Tera templates +- `sass/main.scss` — styles (compiled to `main.css`) +- `static/` — assets, `favicon.svg`, and `CNAME` + +## Deploy + +Pushing to `main` builds and publishes to GitHub Pages via +`.github/workflows/deploy.yml`. The custom domain is set in `static/CNAME`. diff --git a/config.toml b/config.toml new file mode 100644 index 0000000..950133c --- /dev/null +++ b/config.toml @@ -0,0 +1,17 @@ +base_url = "https://krz.sh" +title = "krazy warez" +description = "Small, durable software focused on utility, privacy, and control." +default_language = "en" + +compile_sass = true +minify_html = true +build_search_index = false +generate_feeds = false + +[markdown] +smart_punctuation = true + +[extra] +email = "[email protected]" +github = "https://github.com/krazywarez" +tagline = "Small, durable software focused on utility, privacy, and control." diff --git a/content/_index.md b/content/_index.md new file mode 100644 index 0000000..8320355 --- /dev/null +++ b/content/_index.md @@ -0,0 +1,22 @@ ++++ +title = "krazy warez" ++++ + +## about + +krazy warez builds native apps and self-hosted, privacy-respecting frontends. two people, a few servers, no investors. local-first data, few dependencies, no ads, no tracking. + +## principles + +- fixed scope. a tool that's done stays done. +- local-first. your data stays on your device, not our servers. +- fewer dependencies. less to break, less to trust. +- maintenance over features. we'd rather fix than pad. + +## status + +active. slow. not recruiting. + +## greetz + +everyone still writing plain text on purpose. diff --git a/content/apps/_index.md b/content/apps/_index.md new file mode 100644 index 0000000..2855663 --- /dev/null +++ b/content/apps/_index.md @@ -0,0 +1,10 @@ ++++ +title = "Apps" +description = "Small, durable apps and privacy-focused frontends from krazy warez." +sort_by = "weight" +template = "section.html" +page_template = "page.html" ++++ + +Native apps and privacy-respecting frontends. Each one is small, focused, and +built to last. Source is on [GitHub](https://github.com/krazywarez). diff --git a/content/apps/daybyday.md b/content/apps/daybyday.md new file mode 100644 index 0000000..8760620 --- /dev/null +++ b/content/apps/daybyday.md @@ -0,0 +1,13 @@ ++++ +title = "Day by Day" +description = "An educational iOS app that helps children learn the calendar." +weight = 5 + +[extra] +link = "https://github.com/krazywarez/daybyday" +link_label = "Source" +appstore = "https://apps.apple.com/app/day-by-day/id000000000" ++++ + +Day by Day is a gentle, ad-free iOS app that helps children learn days, weeks, +months, and seasons. Designed for little hands, with no data collection. diff --git a/content/apps/domain-dig.md b/content/apps/domain-dig.md new file mode 100644 index 0000000..e83d3e2 --- /dev/null +++ b/content/apps/domain-dig.md @@ -0,0 +1,14 @@ ++++ +title = "Domain Dig" +description = "DNS and SSL analysis, in your pocket." +weight = 2 + +[extra] +link = "https://github.com/krazywarez/domain-dig" +link_label = "Source" +appstore = "https://apps.apple.com/app/domain-dig/id000000000" ++++ + +Domain Dig is an iOS app for inspecting DNS records and SSL certificates on the +go. Look up A, AAAA, MX, TXT, and more, and check certificate chains — no +account, no tracking. diff --git a/content/apps/hutch.md b/content/apps/hutch.md new file mode 100644 index 0000000..223842a --- /dev/null +++ b/content/apps/hutch.md @@ -0,0 +1,14 @@ ++++ +title = "Hutch" +description = "A native iOS client for Sourcehut." +weight = 1 + +[extra] +link = "https://github.com/krazywarez/hutch" +link_label = "Source" +appstore = "https://apps.apple.com/app/hutch/id000000000" ++++ + +Hutch is a fast, focused iOS client for [Sourcehut](https://sr.ht) — browse +repositories, read tickets, and follow activity without leaving your phone. +Built to be minimal and offline-friendly. diff --git a/content/apps/solar.md b/content/apps/solar.md new file mode 100644 index 0000000..40e4d2a --- /dev/null +++ b/content/apps/solar.md @@ -0,0 +1,13 @@ ++++ +title = "Solar" +description = "A native iOS client for Cloudflare." +weight = 3 + +[extra] +link = "https://github.com/krazywarez/solar" +link_label = "Source" ++++ + +Solar is an iOS client for [Cloudflare](https://cloudflare.com) — manage DNS, +review analytics, and tweak settings across your zones from a clean, native +interface. diff --git a/content/services/_index.md b/content/services/_index.md new file mode 100644 index 0000000..8a02950 --- /dev/null +++ b/content/services/_index.md @@ -0,0 +1,42 @@ ++++ +title = "Services" +description = "Public self-hosted services from krazy warez." +sort_by = "weight" ++++ + +Public services hosted by krazy warez. + +These are maintained on a best-effort basis. Logging and retention are kept +minimal where practical. + +## proxies / front-ends + +- [AnonymousOverflow](https://ao.krz.sh) — StackOverflow alternative front-end +- [SkunkyArt](https://art.krz.sh) — DeviantArt alternative front-end +- [BiblioReads](https://br.krz.sh) — Goodreads alternative front-end +- [BreezeWiki](https://bw.krz.sh) — Fandom alternative front-end +- [Gothub](https://gh.krz.sh) — alternative GitHub interface +- [hn](https://hn.krz.sh) — Hacker News proxy +- [LibremDB](https://ld.krz.sh) — IMDb alternative front-end +- [Binternet](https://pin.krz.sh) — Pinterest alternative front-end +- [Piped](https://pipedapi.krz.sh) — YouTube alternative front-end +- [Small](https://small.krz.sh) — Medium alternative front-end + +## other services + +- [CyberChef](https://cc.krz.sh) — the Cyber Swiss Army Knife +- [Hat.sh](https://hat.krz.sh) — simple, fast, secure client-side file encryption +- [LibreTranslate](https://lt.krz.sh) — a translation engine +- [Mazanoke](https://mz.krz.sh) — local image optimizer that runs in your browser +- [Office](https://office.krz.sh) — the world's smallest office suite +- [SearXNG](https://search.krz.sh) — a privacy-respecting open metasearch engine +- [Send](https://send.krz.sh) — simple, private file sharing + +## services i built + +- [1kb](https://rogue.krz.sh/1kb/#g) — ultra-small roguelike game +- [1mb](https://rogue.krz.sh/1mb/) — extension of 1kb, showing what's possible with 1mb +- [FlashPaper](https://paste.krz.sh) — one-time encrypted password and secret sharing +- [org-live](https://org.krz.sh) — a basic org-mode editor for the web +- [projects](https://projects.krz.sh) — bare nginx directory listing of web-based projects +- [Slash](https://slash.krz.sh) — bookmark and link sharing platform diff --git a/sass/main.scss b/sass/main.scss new file mode 100644 index 0000000..8c9d15b --- /dev/null +++ b/sass/main.scss @@ -0,0 +1,170 @@ +// krazy warez — plain-text-on-purpose. ascii frames, uppercase labels, +// mono, near-black/white, mostly monochrome with one link accent. + +@mixin dark { + --bg: #0a0a0b; + --surface: #101012; + --border: #2a2a2e; + --text: #f1f1ef; + --muted: #9b9b9e; + --dim: #6a6a6e; + --blue: #6f9dff; + --btn-bg: #f1f1ef; + --btn-fg: #0a0a0b; + --sel-bg: #6f9dff; + --sel-fg: #0a0a0b; +} + +@mixin light { + --bg: #fbfbf9; + --surface: #ffffff; + --border: #d9d8d2; + --text: #17171a; + --muted: #5c5c5f; + --dim: #8a8a8d; + --blue: #2f6bd6; + --btn-bg: #17171a; + --btn-fg: #fbfbf9; + --sel-bg: #2f6bd6; + --sel-fg: #ffffff; +} + +:root { @include dark; } +@media (prefers-color-scheme: light) { :root { @include light; } } + +:root { + --mono: "SF Mono", "JetBrains Mono", "Fira Code", ui-monospace, Menlo, Consolas, monospace; + --max: 52rem; +} + +* { box-sizing: border-box; } +html { -webkit-text-size-adjust: 100%; } + +body { + margin: 0; + background: var(--bg); + color: var(--muted); + font-family: var(--mono); + font-size: 15.5px; + line-height: 1.7; + min-height: 100vh; + display: flex; + flex-direction: column; + -webkit-font-smoothing: antialiased; +} + +a { color: var(--blue); text-decoration: none; } +a:hover { text-decoration: underline; text-underline-offset: 3px; } + +::selection { background: var(--sel-bg); color: var(--sel-fg); } + +// ---- Header ---------------------------------------------------------------- +.site-header { + display: flex; + align-items: center; + justify-content: space-between; + gap: 1rem; + flex-wrap: wrap; + max-width: var(--max); + width: 100%; + margin: 0 auto; + padding: 1.5rem 1.25rem; + border-bottom: 1px solid var(--border); +} +.brand { color: var(--text); font-weight: 700; letter-spacing: -0.01em; } +.brand:hover { text-decoration: none; } + +.site-nav { display: flex; align-items: center; gap: 0.7rem; font-size: 0.92rem; } +.site-nav a { color: var(--muted); } +.site-nav a:hover { color: var(--text); text-decoration: none; } +.sep { color: var(--dim); } + +// ---- Main ------------------------------------------------------------------ +.site-main { + flex: 1; + max-width: var(--max); + width: 100%; + margin: 0 auto; + padding: 3rem 1.25rem 4rem; +} + +// ---- Hero ------------------------------------------------------------------ +.tagline { color: var(--muted); font-size: 1rem; margin: 0 0 2rem; } + +.hero-actions { display: flex; gap: 0.75rem; flex-wrap: wrap; margin: 0 0 1rem; } +.btn { + display: inline-block; + font-family: var(--mono); + font-size: 0.92rem; + padding: 0.6rem 1.1rem; + border: 1px solid var(--border); + color: var(--text); + background: transparent; +} +.btn:hover { text-decoration: none; border-color: var(--dim); } +.btn-primary { background: var(--btn-bg); color: var(--btn-fg); border-color: var(--btn-bg); } +.btn-primary:hover { opacity: 0.88; border-color: var(--btn-bg); } + +// ---- Prose ----------------------------------------------------------------- +.prose { max-width: 44rem; } +.page-label { + color: var(--text); + font-size: 1rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.2em; + margin: 0 0 1.75rem; +} +.prose h2 { + color: var(--dim); + font-size: 0.82rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.18em; + margin: 2.5rem 0 0.85rem; +} +.prose p { margin: 0 0 1rem; } +.prose a { color: var(--blue); } +.prose strong { color: var(--text); font-weight: 700; } +.prose ul { list-style: none; padding-left: 0; margin: 1rem 0; } +.prose li { margin: 0.4rem 0; padding-left: 1.3rem; position: relative; } +.prose li::before { content: "-"; position: absolute; left: 0; color: var(--dim); } +.prose hr { border: 0; border-top: 1px solid var(--border); margin: 2rem 0; } +.prose .lede { color: var(--muted); margin: -0.5rem 0 1.25rem; } + +.back { font-size: 0.9rem; margin: 0 0 1.5rem; } +.back a { color: var(--muted); } + +// ---- Plain list (services / apps) ------------------------------------------ +.plainlist { list-style: none; padding: 0; margin: 1.5rem 0 0; } +.plainlist li { + padding: 0.85rem 0; + border-bottom: 1px solid var(--border); + display: flex; + flex-direction: column; + gap: 0.4rem; +} +.plainlist li:last-child { border-bottom: 0; } +.pl-main { color: var(--muted); } +.pl-name { color: var(--text); font-weight: 700; } +.pl-desc { color: var(--muted); } +.pl-links { display: flex; gap: 1.1rem; font-size: 0.88rem; } +.pl-link { color: var(--blue); } +.pl-link-off { color: var(--dim); cursor: not-allowed; } + +@media (min-width: 40rem) { + .plainlist li { flex-direction: row; align-items: baseline; gap: 1rem; } + .pl-links { margin-left: auto; white-space: nowrap; } +} + +// ---- Footer ---------------------------------------------------------------- +.site-footer { + max-width: var(--max); + width: 100%; + margin: 0 auto; + padding: 1.5rem 1.25rem 2.5rem; + border-top: 1px solid var(--border); +} +.foot-links { color: var(--dim); font-size: 0.85rem; margin: 0; } +.foot-links a { color: var(--muted); } +.foot-links a:hover { color: var(--text); } diff --git a/static/CNAME b/static/CNAME new file mode 100644 index 0000000..d562b09 --- /dev/null +++ b/static/CNAME @@ -0,0 +1 @@ +krz.sh diff --git a/static/favicon.svg b/static/favicon.svg new file mode 100644 index 0000000..d8eb75d --- /dev/null +++ b/static/favicon.svg @@ -0,0 +1,4 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"> + <rect width="32" height="32" fill="#0a0a0b"/> + <text x="16" y="22" font-family="ui-monospace, monospace" font-size="16" font-weight="700" fill="#6f9dff" text-anchor="middle">▚</text> +</svg> diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..09c565d --- /dev/null +++ b/templates/base.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<html lang="{{ lang | default(value="en") }}"> +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <title>{% block title %}{{ config.title }}{% endblock title %}</title> + <meta name="description" content="{% block description %}{{ config.description }}{% endblock description %}"> + <meta name="color-scheme" content="dark light"> + <link rel="stylesheet" href="{{ get_url(path="main.css", cachebust=true) | safe }}"> + <link rel="icon" href="{{ get_url(path="favicon.svg") | safe }}"> +</head> +<body> + <header class="site-header"> + <a class="brand" href="{{ get_url(path="/") | safe }}">krazy warez</a> + <nav class="site-nav"> + <a href="{{ get_url(path="/services/") | safe }}">services</a> + <span class="sep">·</span> + <a href="{{ get_url(path="/apps/") | safe }}">apps</a> + </nav> + </header> + + <main class="site-main"> + {% block content %}{% endblock content %} + </main> + + <footer class="site-footer"> + <p class="foot-links"><a href="mailto:{{ config.extra.email }}">{{ config.extra.email }}</a> · <a href="{{ config.extra.github }}">github</a> · © {{ now() | date(format="%Y") }} · public domain</p> + </footer> +</body> +</html> diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..a9dd0fc --- /dev/null +++ b/templates/index.html @@ -0,0 +1,14 @@ +{% extends "base.html" %} + +{% block content %} +<p class="tagline">small, durable software · privacy-first tools you control</p> + +<div class="hero-actions"> + <a class="btn btn-primary" href="{{ get_url(path="/services/") | safe }}">view services →</a> + <a class="btn" href="{{ get_url(path="/apps/") | safe }}">browse apps</a> +</div> + +<article class="prose"> + {{ section.content | safe }} +</article> +{% endblock content %} diff --git a/templates/page.html b/templates/page.html new file mode 100644 index 0000000..32b1607 --- /dev/null +++ b/templates/page.html @@ -0,0 +1,16 @@ +{% extends "base.html" %} + +{% block title %}{{ page.title | lower }} · {{ config.title }}{% endblock title %} +{% block description %}{{ page.description | default(value=config.description) }}{% endblock description %} + +{% block content %} +<p class="back"><a href="{{ section.permalink | default(value=get_url(path="/")) | safe }}">← back</a></p> +<article class="prose"> + <h1 class="page-label">{{ page.title }}</h1> + {% if page.description %}<p class="lede">{{ page.description }}</p>{% endif %} + {{ page.content | safe }} + {% if page.extra.link %} + <p><a class="btn btn-primary" href="{{ page.extra.link }}">{{ page.extra.link_label | default(value="source") | lower }} →</a></p> + {% endif %} +</article> +{% endblock content %} diff --git a/templates/section.html b/templates/section.html new file mode 100644 index 0000000..c3a9489 --- /dev/null +++ b/templates/section.html @@ -0,0 +1,29 @@ +{% extends "base.html" %} + +{% block title %}{{ section.title | lower }} · {{ config.title }}{% endblock title %} +{% block description %}{{ section.description | default(value=config.description) }}{% endblock description %} + +{% block content %} +<article class="prose"> + <h1 class="page-label">{{ section.title }}</h1> + {{ section.content | safe }} +</article> + +{% if section.pages %} +<ul class="plainlist"> + {% for page in section.pages %} + <li> + <span class="pl-main"> + <span class="pl-name">{{ page.title }}</span> + {% if page.description %}<span class="pl-desc">— {{ page.description }}</span>{% endif %} + </span> + <span class="pl-links"> + {% if page.extra.appstore %}<a class="pl-link" href="{{ page.extra.appstore }}">app store →</a> + {% else %}<span class="pl-link pl-link-off" aria-disabled="true">app store — soon</span>{% endif %} + {% if page.extra.link %}<a class="pl-link" href="{{ page.extra.link }}">{{ page.extra.link_label | default(value="source") | lower }} →</a>{% endif %} + </span> + </li> + {% endfor %} +</ul> +{% endif %} +{% endblock content %} |
