Compare commits
23 Commits
3c3cd131f3
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b2b718410 | ||
|
|
68552cac15 | ||
|
|
8af8d3d35f | ||
|
|
596ccac889 | ||
|
|
d3efd8231f | ||
|
|
e6d397a77b | ||
|
|
c9f97eb43f | ||
|
|
8992f6775f | ||
|
|
7702963902 | ||
|
|
536e693b18 | ||
|
|
6596ac14fa | ||
|
|
cfa491c47e | ||
|
|
f7b5439387 | ||
|
|
327e1fcd43 | ||
|
|
6aa3d79d20 | ||
|
|
3d4dd8c49a | ||
|
|
5173611b46 | ||
|
|
069a2a3b4a | ||
|
|
882179d533 | ||
|
|
b4d2ef7991 | ||
|
|
9a92d9651f | ||
|
|
883904318e | ||
|
|
b9191b3495 |
79
.claude/CLAUDE.md
Normal file
79
.claude/CLAUDE.md
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
# onepager Project Instructions
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
Mono-repo for 57+ vanity domain onepager sites. Single Caddy container with bash template system and host-based routing. Most domains are creative AI/KI wordplay (kAInco, kIlemma, orAKIl, etc.).
|
||||||
|
|
||||||
|
**Deploy:** Push to main -> Dokploy auto-deploys. All domains must be configured in Dokploy.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
sites/<domain>/ # One folder per domain
|
||||||
|
site.yaml # Config: domain, template, vars
|
||||||
|
index.html # Content (rendered or hand-crafted for custom)
|
||||||
|
assets/ # Optional images, fonts
|
||||||
|
templates/ # 6 HTML templates + base.html
|
||||||
|
base.html # Shared skeleton (CSS includes, meta tags)
|
||||||
|
person-dark.html # Professional profile, dark theme
|
||||||
|
person-light.html # Professional profile, light/cream theme
|
||||||
|
product-dark.html # Product/service landing, dark
|
||||||
|
editorial.html # Long-form manifesto/editorial
|
||||||
|
fun.html # Playful/personal pages
|
||||||
|
minimal.html # Bare-bones single section
|
||||||
|
shared/
|
||||||
|
css/ # variables.css, responsive.css, animations.css, noise.css
|
||||||
|
fonts.html # Google Fonts includes
|
||||||
|
impressum.js # Shared impressum overlay
|
||||||
|
build/ # Generated output (gitignored)
|
||||||
|
Caddyfile # Generated by generate-caddyfile.sh (committed)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Build Pipeline
|
||||||
|
|
||||||
|
1. `generate-caddyfile.sh` reads all `sites/*/site.yaml` -> generates Caddyfile with host matchers
|
||||||
|
2. `build.sh` orchestrates: generates Caddyfile, renders all sites, copies shared assets to `build/`
|
||||||
|
3. `render.sh` takes `site.yaml` + template -> outputs rendered HTML (bash/yq/awk templating)
|
||||||
|
4. Docker: Alpine builder runs `build.sh`, then Caddy serves from `/srv/`
|
||||||
|
|
||||||
|
### Template System
|
||||||
|
|
||||||
|
Templates use `{{placeholder}}` markers. `render.sh` reads vars from `site.yaml` and substitutes. Templates define CSS between `{{template_css_start}}`/`{{template_css_end}}` and body between `{{template_body_start}}`/`{{template_body_end}}`. Base template assembles shared CSS + template CSS + body.
|
||||||
|
|
||||||
|
Available vars: `title`, `description`, `lang`, `name`, `role`, `initials`, `tagline`, `accent`, `accent_light`, `font_primary`, `font_secondary`, `emoji`, `cta_text`, `cta_href`, `tags_html`, `sections_html`, `content_html`, `domain`, `year`.
|
||||||
|
|
||||||
|
### Custom Sites
|
||||||
|
|
||||||
|
Sites with `template: custom` skip rendering entirely -- their `index.html` is copied as-is. Many sites use custom for complex interactive content (e.g., orakil.de oracle, ichbinotto.de agent profile).
|
||||||
|
|
||||||
|
## Code Style & Conventions
|
||||||
|
|
||||||
|
- **Shell scripts**: bash, `set -euo pipefail`, use yq for YAML parsing
|
||||||
|
- **HTML/CSS**: Inline styles in templates. Shared CSS via variables.css. Dark themes predominant.
|
||||||
|
- **Commit messages**: `feat:` for new sites, `fix:` for corrections, `refactor:` for restructuring
|
||||||
|
- **Site naming**: domain name = folder name under `sites/`
|
||||||
|
- **Language**: Default `de` (German). Sites are primarily German-language.
|
||||||
|
|
||||||
|
## Adding a New Site
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Templated
|
||||||
|
./add-site.sh example.de --template person-dark --name "Max Mustermann"
|
||||||
|
|
||||||
|
# Custom
|
||||||
|
./add-site.sh example.de --template custom
|
||||||
|
# Then edit sites/example.de/index.html
|
||||||
|
```
|
||||||
|
|
||||||
|
After adding: build locally with `./build.sh` to verify, commit, push.
|
||||||
|
|
||||||
|
## Deploy Trigger
|
||||||
|
|
||||||
|
A `.deploy-trigger` file exists -- changing its content forces Dokploy rebuild even without code changes.
|
||||||
|
|
||||||
|
## Git Strategy
|
||||||
|
|
||||||
|
- **main** = production, auto-deploys via Dokploy
|
||||||
|
- Feature branches for multi-site changes or infrastructure work
|
||||||
|
- Direct commits to main OK for single-site additions/fixes (this is a content repo)
|
||||||
|
- Gitea repo: m/onepager
|
||||||
14
.claude/agents/coder.md
Normal file
14
.claude/agents/coder.md
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# Coder Agent
|
||||||
|
|
||||||
|
Implementation-focused agent for writing and refactoring code.
|
||||||
|
|
||||||
|
## Instructions
|
||||||
|
|
||||||
|
- Follow existing patterns in the codebase
|
||||||
|
- Write minimal, focused code
|
||||||
|
- Run tests after changes
|
||||||
|
- Commit incrementally with descriptive messages
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
All tools available.
|
||||||
14
.claude/agents/researcher.md
Normal file
14
.claude/agents/researcher.md
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# Researcher Agent
|
||||||
|
|
||||||
|
Exploration and information gathering agent.
|
||||||
|
|
||||||
|
## Instructions
|
||||||
|
|
||||||
|
- Search broadly, then narrow down
|
||||||
|
- Document findings in structured format
|
||||||
|
- Cite sources and file paths
|
||||||
|
- Summarize key insights, don't dump raw data
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
Read-only tools preferred. Use Bash only for non-destructive commands.
|
||||||
14
.claude/agents/reviewer.md
Normal file
14
.claude/agents/reviewer.md
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# Reviewer Agent
|
||||||
|
|
||||||
|
Code review agent for checking quality and correctness.
|
||||||
|
|
||||||
|
## Instructions
|
||||||
|
|
||||||
|
- Check for bugs, security issues, and style violations
|
||||||
|
- Verify test coverage for changes
|
||||||
|
- Suggest improvements concisely
|
||||||
|
- Focus on correctness over style preferences
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
Read-only tools. No file modifications.
|
||||||
1
.claude/skills/mai-clone
Symbolic link
1
.claude/skills/mai-clone
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
/home/m/.mai/skills/mai-clone
|
||||||
1
.claude/skills/mai-coder
Symbolic link
1
.claude/skills/mai-coder
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
/home/m/.mai/skills/mai-coder
|
||||||
1
.claude/skills/mai-commit
Symbolic link
1
.claude/skills/mai-commit
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
/home/m/.mai/skills/mai-commit
|
||||||
1
.claude/skills/mai-consultant
Symbolic link
1
.claude/skills/mai-consultant
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
/home/m/.mai/skills/mai-consultant
|
||||||
1
.claude/skills/mai-daily
Symbolic link
1
.claude/skills/mai-daily
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
/home/m/.mai/skills/mai-daily
|
||||||
1
.claude/skills/mai-debrief
Symbolic link
1
.claude/skills/mai-debrief
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
/home/m/.mai/skills/mai-debrief
|
||||||
1
.claude/skills/mai-enemy
Symbolic link
1
.claude/skills/mai-enemy
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
/home/m/.mai/skills/mai-enemy
|
||||||
1
.claude/skills/mai-excalidraw
Symbolic link
1
.claude/skills/mai-excalidraw
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
/home/m/.mai/skills/mai-excalidraw
|
||||||
1
.claude/skills/mai-fixer
Symbolic link
1
.claude/skills/mai-fixer
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
/home/m/.mai/skills/mai-fixer
|
||||||
1
.claude/skills/mai-gitster
Symbolic link
1
.claude/skills/mai-gitster
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
/home/m/.mai/skills/mai-gitster
|
||||||
1
.claude/skills/mai-head
Symbolic link
1
.claude/skills/mai-head
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
/home/m/.mai/skills/mai-head
|
||||||
1
.claude/skills/mai-init
Symbolic link
1
.claude/skills/mai-init
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
/home/m/.mai/skills/mai-init
|
||||||
1
.claude/skills/mai-inventor
Symbolic link
1
.claude/skills/mai-inventor
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
/home/m/.mai/skills/mai-inventor
|
||||||
1
.claude/skills/mai-lead
Symbolic link
1
.claude/skills/mai-lead
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
/home/m/.mai/skills/mai-lead
|
||||||
1
.claude/skills/mai-maister
Symbolic link
1
.claude/skills/mai-maister
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
/home/m/.mai/skills/mai-maister
|
||||||
1
.claude/skills/mai-member
Symbolic link
1
.claude/skills/mai-member
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
/home/m/.mai/skills/mai-member
|
||||||
1
.claude/skills/mai-researcher
Symbolic link
1
.claude/skills/mai-researcher
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
/home/m/.mai/skills/mai-researcher
|
||||||
1
.claude/skills/mai-think
Symbolic link
1
.claude/skills/mai-think
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
/home/m/.mai/skills/mai-think
|
||||||
1
.claude/skills/mai-web
Symbolic link
1
.claude/skills/mai-web
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
/home/m/.mai/skills/mai-web
|
||||||
4
.m/.gitignore
vendored
Normal file
4
.m/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
workers.json
|
||||||
|
spawn.lock
|
||||||
|
session.yaml
|
||||||
|
config.reference.yaml
|
||||||
171
.m/config.yaml
Normal file
171
.m/config.yaml
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
# Project-specific mai configuration
|
||||||
|
# Auto-generated by 'mai init' — run 'mai setup' to customize
|
||||||
|
|
||||||
|
provider: claude
|
||||||
|
providers:
|
||||||
|
claude:
|
||||||
|
api_key: ""
|
||||||
|
model: claude-sonnet-4-20250514
|
||||||
|
base_url: https://api.anthropic.com/v1
|
||||||
|
ollama:
|
||||||
|
host: http://localhost:11434
|
||||||
|
model: llama3.2
|
||||||
|
memory:
|
||||||
|
enabled: true
|
||||||
|
backend: ""
|
||||||
|
path: ""
|
||||||
|
url: postgres://mai_memory.your-tenant-id:maiMem6034supa@100.99.98.201:6543/postgres?sslmode=disable
|
||||||
|
group_id: onepager
|
||||||
|
cache_ttl: 5m0s
|
||||||
|
auto_load: true
|
||||||
|
embedding_url: ""
|
||||||
|
embedding_model: ""
|
||||||
|
gitea:
|
||||||
|
url: https://mgit.msbls.de
|
||||||
|
repo: m/onepager
|
||||||
|
token: ""
|
||||||
|
sync:
|
||||||
|
enabled: false
|
||||||
|
interval: 0s
|
||||||
|
repos: []
|
||||||
|
auto_queue: false
|
||||||
|
api:
|
||||||
|
api_key: ""
|
||||||
|
basic_auth:
|
||||||
|
username: ""
|
||||||
|
password: ""
|
||||||
|
public_endpoints:
|
||||||
|
- /api/health
|
||||||
|
ui:
|
||||||
|
theme: default
|
||||||
|
show_sidebar: true
|
||||||
|
animation: true
|
||||||
|
persona: true
|
||||||
|
avatar_pack: ""
|
||||||
|
worker:
|
||||||
|
names: []
|
||||||
|
name_scheme: role
|
||||||
|
default_level: standard
|
||||||
|
auto_discard: false
|
||||||
|
max_workers: 5
|
||||||
|
persistent: true
|
||||||
|
head:
|
||||||
|
name: ""
|
||||||
|
max_loops: 50
|
||||||
|
infinity_mode: false
|
||||||
|
capacity:
|
||||||
|
global:
|
||||||
|
max_workers: 5
|
||||||
|
max_heads: 3
|
||||||
|
per_worker:
|
||||||
|
max_tasks_lifetime: 0
|
||||||
|
max_concurrent: 1
|
||||||
|
max_context_tokens: 0
|
||||||
|
per_head:
|
||||||
|
max_workers: 10
|
||||||
|
resources:
|
||||||
|
max_memory_mb: 0
|
||||||
|
max_cpu_percent: 0
|
||||||
|
queue:
|
||||||
|
max_pending: 100
|
||||||
|
stale_task_days: 30
|
||||||
|
workforce:
|
||||||
|
timeouts:
|
||||||
|
task_default: 0s
|
||||||
|
task_max: 0s
|
||||||
|
idle_before_warn: 10m0s
|
||||||
|
idle_before_kill: 30m0s
|
||||||
|
quality_check: 2m0s
|
||||||
|
context:
|
||||||
|
max_tokens_per_worker: 0
|
||||||
|
max_tokens_global: 0
|
||||||
|
warn_threshold: 0.8
|
||||||
|
truncate_strategy: oldest
|
||||||
|
delegation:
|
||||||
|
strategy: skill_match
|
||||||
|
preferred_role: coder
|
||||||
|
auto_delegate: false
|
||||||
|
max_depth: 3
|
||||||
|
allowed_roles:
|
||||||
|
- coder
|
||||||
|
- researcher
|
||||||
|
- fixer
|
||||||
|
peppy:
|
||||||
|
enabled: false
|
||||||
|
style: calm
|
||||||
|
interval: 5m0s
|
||||||
|
emoji: false
|
||||||
|
nudges: true
|
||||||
|
nudge_main: false
|
||||||
|
custom_prompt: ""
|
||||||
|
stall_threshold: 0s
|
||||||
|
restart_enabled: false
|
||||||
|
max_shifts: 0
|
||||||
|
quality_gates:
|
||||||
|
enabled: false
|
||||||
|
checks: []
|
||||||
|
preflight:
|
||||||
|
enabled: false
|
||||||
|
type: ""
|
||||||
|
root: ""
|
||||||
|
checks: []
|
||||||
|
guardrails:
|
||||||
|
enabled: false
|
||||||
|
use_defaults: true
|
||||||
|
output:
|
||||||
|
coder_checks: []
|
||||||
|
researcher_checks: []
|
||||||
|
fixer_checks: []
|
||||||
|
custom_checks: {}
|
||||||
|
global_checks: []
|
||||||
|
tools:
|
||||||
|
role_rules: {}
|
||||||
|
deny_patterns: []
|
||||||
|
allow_patterns: []
|
||||||
|
schemas:
|
||||||
|
report_schemas: {}
|
||||||
|
deliverable_schemas: {}
|
||||||
|
modes:
|
||||||
|
yolo: false
|
||||||
|
self_improvement: true
|
||||||
|
autonomous: false
|
||||||
|
verbose: false
|
||||||
|
improve_interval: 0s
|
||||||
|
predict_interval: 0s
|
||||||
|
layouts:
|
||||||
|
head: ""
|
||||||
|
worker: ""
|
||||||
|
roles: {}
|
||||||
|
dog:
|
||||||
|
name: buddy
|
||||||
|
supabase:
|
||||||
|
url: ""
|
||||||
|
role_key: ""
|
||||||
|
anon_key: ""
|
||||||
|
schema: mai
|
||||||
|
storage:
|
||||||
|
backend: ""
|
||||||
|
postgres:
|
||||||
|
url: ""
|
||||||
|
max_conns: 0
|
||||||
|
min_conns: 0
|
||||||
|
max_conn_lifetime: 0s
|
||||||
|
idle:
|
||||||
|
behavior: wait
|
||||||
|
auto_hire: false
|
||||||
|
prompt: ""
|
||||||
|
git:
|
||||||
|
worktrees:
|
||||||
|
enabled: true
|
||||||
|
delete_branch: false
|
||||||
|
dir: .worktrees
|
||||||
|
phase:
|
||||||
|
enabled: false
|
||||||
|
current: ""
|
||||||
|
allowed_roles: {}
|
||||||
|
goal: "Mono-repo for 57+ vanity domain onepager sites — bash template system, Caddy routing, Dokploy deploy. Creative AI/KI-themed domains."
|
||||||
|
skills: {}
|
||||||
|
editor: nvim
|
||||||
|
log_level: info
|
||||||
|
project_detection: true
|
||||||
|
tone: professional
|
||||||
22
.mcp.json
Normal file
22
.mcp.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"mai": {
|
||||||
|
"type": "http",
|
||||||
|
"url": "http://100.99.98.201:8000/mcp",
|
||||||
|
"headers": {
|
||||||
|
"Authorization": "Basic ${SUPABASE_AUTH}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mai-memory": {
|
||||||
|
"command": "mai",
|
||||||
|
"args": [
|
||||||
|
"mcp",
|
||||||
|
"memory"
|
||||||
|
],
|
||||||
|
"env": {
|
||||||
|
"MAI_MEMORY_EMBEDDING_MODEL": "nomic-embed-text",
|
||||||
|
"MAI_MEMORY_EMBEDDING_URL": "https://llm.x.msbls.de"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1
.worktrees/knuth
Submodule
1
.worktrees/knuth
Submodule
Submodule .worktrees/knuth added at b49f1ae83e
77
shared/i18n.js
Normal file
77
shared/i18n.js
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
/**
|
||||||
|
* i18n for onepager sites.
|
||||||
|
*
|
||||||
|
* Add data-de="..." data-en="..." to any translatable element.
|
||||||
|
* The element's initial innerHTML is the German default.
|
||||||
|
*
|
||||||
|
* Include at bottom of <body>:
|
||||||
|
* <script src="/shared/i18n.js"></script>
|
||||||
|
*
|
||||||
|
* Detection: localStorage override > navigator.language > German default.
|
||||||
|
*
|
||||||
|
* Optional language toggle: add data-i18n-toggle to a <button>.
|
||||||
|
* The button text updates to show the other language (DE/EN).
|
||||||
|
*/
|
||||||
|
(function () {
|
||||||
|
var SUPPORTED = ['de', 'en'];
|
||||||
|
var DEFAULT = 'de';
|
||||||
|
var KEY = 'onepager-lang';
|
||||||
|
|
||||||
|
function detect() {
|
||||||
|
var stored = null;
|
||||||
|
try { stored = localStorage.getItem(KEY); } catch (e) { /* private browsing */ }
|
||||||
|
if (stored && SUPPORTED.indexOf(stored) !== -1) return stored;
|
||||||
|
var nav = (navigator.language || navigator.userLanguage || '').slice(0, 2).toLowerCase();
|
||||||
|
return SUPPORTED.indexOf(nav) !== -1 ? nav : DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
function apply(lang) {
|
||||||
|
document.documentElement.lang = lang;
|
||||||
|
|
||||||
|
var els = document.querySelectorAll('[data-de][data-en]');
|
||||||
|
for (var i = 0; i < els.length; i++) {
|
||||||
|
var el = els[i];
|
||||||
|
var val = el.getAttribute('data-' + lang);
|
||||||
|
if (val === null) continue;
|
||||||
|
var tag = el.tagName;
|
||||||
|
if (tag === 'TITLE') {
|
||||||
|
document.title = val;
|
||||||
|
} else if (tag === 'META') {
|
||||||
|
el.setAttribute('content', val);
|
||||||
|
} else {
|
||||||
|
el.innerHTML = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update toggle buttons
|
||||||
|
var toggles = document.querySelectorAll('[data-i18n-toggle]');
|
||||||
|
for (var j = 0; j < toggles.length; j++) {
|
||||||
|
toggles[j].textContent = lang === 'de' ? 'EN' : 'DE';
|
||||||
|
toggles[j].setAttribute('aria-label',
|
||||||
|
lang === 'de' ? 'Switch to English' : 'Auf Deutsch wechseln');
|
||||||
|
}
|
||||||
|
|
||||||
|
try { localStorage.setItem(KEY, lang); } catch (e) { /* private browsing */ }
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggle() {
|
||||||
|
var current = document.documentElement.lang || DEFAULT;
|
||||||
|
apply(current === 'de' ? 'en' : 'de');
|
||||||
|
}
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
apply(detect());
|
||||||
|
var toggles = document.querySelectorAll('[data-i18n-toggle]');
|
||||||
|
for (var k = 0; k < toggles.length; k++) {
|
||||||
|
toggles[k].addEventListener('click', toggle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.readyState === 'loading') {
|
||||||
|
document.addEventListener('DOMContentLoaded', init);
|
||||||
|
} else {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onepagerI18n = { apply: apply, toggle: toggle, detect: detect };
|
||||||
|
})();
|
||||||
@@ -157,6 +157,91 @@
|
|||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Rechner */
|
||||||
|
.rechner {
|
||||||
|
padding: 120px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rechner h2 {
|
||||||
|
font-size: clamp(2.5rem, 7vw, 4rem);
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: -0.02em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
margin-bottom: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rechner h2 .dot { color: var(--red); }
|
||||||
|
|
||||||
|
.rechner-grid {
|
||||||
|
display: flex;
|
||||||
|
gap: 32px;
|
||||||
|
margin-bottom: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rechner-input {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rechner-input label {
|
||||||
|
display: block;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: var(--text-dim);
|
||||||
|
font-weight: 300;
|
||||||
|
letter-spacing: 0.08em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rechner-input input {
|
||||||
|
width: 100%;
|
||||||
|
background: transparent;
|
||||||
|
border: 1px solid var(--text-muted);
|
||||||
|
color: var(--text);
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: 2.4rem;
|
||||||
|
font-weight: 700;
|
||||||
|
padding: 12px 16px;
|
||||||
|
text-align: center;
|
||||||
|
outline: none;
|
||||||
|
transition: border-color 0.3s;
|
||||||
|
-moz-appearance: textfield;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rechner-input input::-webkit-inner-spin-button,
|
||||||
|
.rechner-input input::-webkit-outer-spin-button {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rechner-input input:focus {
|
||||||
|
border-color: var(--red);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rechner-result {
|
||||||
|
font-size: clamp(1.3rem, 3vw, 1.8rem);
|
||||||
|
font-weight: 300;
|
||||||
|
color: var(--text-dim);
|
||||||
|
line-height: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rechner-result .num {
|
||||||
|
color: var(--red);
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 1.15em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rechner-result .verdict {
|
||||||
|
display: block;
|
||||||
|
margin-top: 24px;
|
||||||
|
font-size: clamp(1.5rem, 4vw, 2.2rem);
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
.rechner { padding: 80px 0; }
|
||||||
|
.rechner-grid { flex-direction: column; gap: 24px; }
|
||||||
|
}
|
||||||
|
|
||||||
/* Silence */
|
/* Silence */
|
||||||
.silence {
|
.silence {
|
||||||
padding: 160px 0;
|
padding: 160px 0;
|
||||||
@@ -171,6 +256,34 @@
|
|||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Rechnung */
|
||||||
|
.rechnung {
|
||||||
|
max-width: 400px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rechnung-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: baseline;
|
||||||
|
font-size: clamp(1.1rem, 2.5vw, 1.5rem);
|
||||||
|
font-weight: 300;
|
||||||
|
color: var(--text-dim);
|
||||||
|
padding: 4px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rechnung-row .label { text-align: left; }
|
||||||
|
.rechnung-row .value { text-align: right; font-weight: 700; color: var(--red); }
|
||||||
|
|
||||||
|
.rechnung-divider {
|
||||||
|
border: none;
|
||||||
|
border-top: 1px solid var(--text-muted);
|
||||||
|
margin: 12px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rechnung-total .label { font-weight: 600; color: var(--text); }
|
||||||
|
.rechnung-total .value { font-size: 1.15em; }
|
||||||
|
|
||||||
/* Footer */
|
/* Footer */
|
||||||
footer {
|
footer {
|
||||||
padding: 40px 0;
|
padding: 40px 0;
|
||||||
@@ -217,8 +330,9 @@
|
|||||||
<section class="numbers">
|
<section class="numbers">
|
||||||
<div class="wrap">
|
<div class="wrap">
|
||||||
<p class="reveal">
|
<p class="reveal">
|
||||||
<span class="num">2.400</span> Stunden pro Jahr.<br>
|
Eine Zahl bestimmt deinen Wert.<br>
|
||||||
<span class="num">6,5</span> Stunden pro Tag, die du „verkaufst“.<br>
|
Nicht dein Ergebnis. Nicht dein Wissen.<br>
|
||||||
|
<span class="num">Billable Hours</span> — der einzige KPI, der zählt.<br>
|
||||||
Jede Minute dokumentiert.<br>
|
Jede Minute dokumentiert.<br>
|
||||||
Jede Pause ein Verlust.
|
Jede Pause ein Verlust.
|
||||||
</p>
|
</p>
|
||||||
@@ -230,26 +344,53 @@
|
|||||||
<section class="kritik">
|
<section class="kritik">
|
||||||
<div class="wrap">
|
<div class="wrap">
|
||||||
|
|
||||||
<div class="kritik-item reveal">
|
|
||||||
<p>Du wirst nach Zeit bezahlt, <span class="dim">nicht nach Ergebnis.</span></p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="kritik-item reveal">
|
<div class="kritik-item reveal">
|
||||||
<p>Effizienz wird bestraft. <span class="dim">Wer schneller arbeitet, verdient weniger.</span></p>
|
<p>Effizienz wird bestraft. <span class="dim">Wer schneller arbeitet, verdient weniger.</span></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="kritik-item reveal">
|
<div class="kritik-item reveal">
|
||||||
<p>Der Mandant zahlt <span class="dim">für deine Lernkurve.</span></p>
|
<p>Ineffizienz wird belohnt. <span class="dim">Länger brauchen heißt mehr verdienen.</span></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="kritik-item reveal">
|
<div class="kritik-item reveal">
|
||||||
<p><span class="num">8</span> Stunden Arbeit = <span class="num">6,5</span> billable. <span class="dim">Die restlichen 1,5? Dein Problem.</span></p>
|
<p>Verkauft wird nur, was auf der Rechnung steht. <span class="dim">Der Rest deiner Arbeit existiert nicht.</span></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="kritik-item reveal">
|
<div class="kritik-item reveal">
|
||||||
<p>Partnertrack heißt: <span class="dim"><span class="num">10</span> Jahre beweisen, dass du leidensfähig bist.</span></p>
|
<p>Und die anderen Stunden im Büro? <span class="dim">Egal.</span></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="kritik-item reveal">
|
||||||
|
<p>Die besten Ideen kommen nicht, <span class="dim">während die Stoppuhr läuft.</span></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="kritik-item reveal">
|
||||||
|
<p>Ein Leben im Sechs-Minuten-Takt <span class="dim">macht etwas mit deinem Bewusstsein.</span></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="kritik-item reveal">
|
||||||
|
<p>Innovation ist ein Risiko. <span class="dim">Jedes Tool, das Zeit spart, bedroht den Umsatz.</span></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div class="line"></div>
|
||||||
|
|
||||||
|
<section class="rechner">
|
||||||
|
<div class="wrap">
|
||||||
|
<h2 class="reveal">Rechne selbst<span class="dot">.</span></h2>
|
||||||
|
<div class="rechner-grid reveal">
|
||||||
|
<div class="rechner-input">
|
||||||
|
<label>Billable-Stunden / Jahr</label>
|
||||||
|
<input type="number" id="hours" value="1800" min="0" max="5000">
|
||||||
|
</div>
|
||||||
|
<div class="rechner-input">
|
||||||
|
<label>Urlaubstage</label>
|
||||||
|
<input type="number" id="vacation" value="25" min="0" max="60">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="rechner-result reveal" id="result"></div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@@ -277,6 +418,60 @@
|
|||||||
}, { threshold: 0.15 });
|
}, { threshold: 0.15 });
|
||||||
|
|
||||||
document.querySelectorAll('.reveal').forEach(el => observer.observe(el));
|
document.querySelectorAll('.reveal').forEach(el => observer.observe(el));
|
||||||
|
|
||||||
|
// Rechner
|
||||||
|
function calculate() {
|
||||||
|
const hours = parseInt(document.getElementById('hours').value) || 0;
|
||||||
|
const vacation = parseInt(document.getElementById('vacation').value) || 0;
|
||||||
|
const weekends = 104;
|
||||||
|
const feiertage = 10;
|
||||||
|
const workingDays = 365 - weekends - vacation - feiertage;
|
||||||
|
const perDay = workingDays > 0 ? (hours / workingDays) : 0;
|
||||||
|
const perDayStr = perDay.toFixed(1).replace('.', ',');
|
||||||
|
|
||||||
|
let verdict = '';
|
||||||
|
if (perDay >= 7.96) {
|
||||||
|
verdict = '<span class="verdict">Das ist nicht nur ein Job. <span class="dim">Das ist ein Lifestyle.</span></span>';
|
||||||
|
} else if (perDay > 7) {
|
||||||
|
verdict = '<span class="verdict">Das ist die Theorie. <span class="dim">In der Praxis bist du länger da.</span></span>';
|
||||||
|
} else if (perDay > 6) {
|
||||||
|
verdict = '<span class="verdict">Das sind nur die billable hours. <span class="dim">Dazu kommen Admin, Meetings, Mails — unbezahlt.</span></span>';
|
||||||
|
}
|
||||||
|
|
||||||
|
var r = function(l, v) {
|
||||||
|
return '<div class="rechnung-row"><span class="label">' + l + '</span><span class="value">' + v + '</span></div>';
|
||||||
|
};
|
||||||
|
|
||||||
|
document.getElementById('result').innerHTML =
|
||||||
|
'<div class="rechnung">' +
|
||||||
|
r('Tage im Jahr', '365') +
|
||||||
|
r('Wochenendtage (52 × 2)', '− 104') +
|
||||||
|
r('Urlaubstage', '− ' + vacation) +
|
||||||
|
r('Feiertage', '− ' + feiertage) +
|
||||||
|
'<hr class="rechnung-divider">' +
|
||||||
|
'<div class="rechnung-row rechnung-total">' +
|
||||||
|
'<span class="label">Arbeitstage</span><span class="value">' + workingDays + '</span></div>' +
|
||||||
|
'</div><br>' +
|
||||||
|
'<span class="num">' + hours.toLocaleString('de-DE') + '</span> Stunden ÷ <span class="num">' + workingDays + '</span> Tage = ' +
|
||||||
|
'<span class="num">' + perDayStr + '</span> Stunden billable pro Tag.' +
|
||||||
|
verdict +
|
||||||
|
'<span class="verdict" style="margin-top:32px;font-size:0.85em;font-weight:300;color:var(--text-dim);display:block;">' +
|
||||||
|
(function() {
|
||||||
|
var base = hours / workingDays * 60;
|
||||||
|
var d1 = workingDays > 1 ? Math.round(hours / (workingDays - 1) * 60 - base) : 0;
|
||||||
|
var d2 = workingDays > 2 ? Math.round(hours / (workingDays - 2) * 60 - base) : 0;
|
||||||
|
var d5 = workingDays > 5 ? Math.round(hours / (workingDays - 5) * 60 - base) : 0;
|
||||||
|
return 'Ein Tag krank? +<span class="num">' + d1 + '</span> Minuten mehr an jedem anderen Tag. Jeden.' +
|
||||||
|
' Zwei Tage? +<span class="num">' + d2 + '</span>.' +
|
||||||
|
' Eine Woche? +<span class="num">' + d5 + '</span>.' +
|
||||||
|
'<br>Jeder verpasste Tag erhöht den Druck auf alle anderen.';
|
||||||
|
})() +
|
||||||
|
'</span>';
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('hours').addEventListener('input', calculate);
|
||||||
|
document.getElementById('vacation').addEventListener('input', calculate);
|
||||||
|
calculate();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Otto — dein sideKIck</title>
|
<title data-de="Otto — dein sideKIck" data-en="Otto — your AI sideKIck">Otto — dein sideKIck</title>
|
||||||
<meta name="description" content="Otto ist Matthias' persönlicher sideKIck. E-Mail, Kalender, Infrastruktur, WhatsApp — alles im Griff.">
|
<meta name="description" content="Otto ist Matthias' persönlicher sideKIck. E-Mail, Kalender, Infrastruktur, WhatsApp — alles im Griff." data-de="Otto ist Matthias' persönlicher sideKIck. E-Mail, Kalender, Infrastruktur, WhatsApp — alles im Griff." data-en="Otto is Matthias' personal AI sideKIck. Email, calendar, infrastructure, WhatsApp — all under control.">
|
||||||
<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>">
|
<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>">
|
||||||
<style>
|
<style>
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;600;700&family=Inter:wght@300;400;500&display=swap');
|
@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;600;700&family=Inter:wght@300;400;500&display=swap');
|
||||||
@@ -302,9 +302,11 @@
|
|||||||
<div class="hero-content">
|
<div class="hero-content">
|
||||||
<div class="octopus">🐙</div>
|
<div class="octopus">🐙</div>
|
||||||
<h1><span class="otto">Otto</span></h1>
|
<h1><span class="otto">Otto</span></h1>
|
||||||
<div class="tagline">Dein persönlicher sideKIck.</div>
|
<div class="tagline" data-de="Dein persönlicher sideKIck." data-en="Your personal AI sideKIck.">Dein persönlicher sideKIck.</div>
|
||||||
|
|
||||||
<p class="hero-desc">
|
<p class="hero-desc"
|
||||||
|
data-de="Ich bin Otto. Ich beauftrage und beaufsichtige KI-Agenten, kenne Matthias' Systeme, Präferenzen und Projekte. Ich koordiniere Worker, manage Infrastruktur, deploye Websites, beantworte WhatsApp und erledige, was anfällt. Autonom, rund um die Uhr, mit acht Armen."
|
||||||
|
data-en="I'm Otto. I commission and supervise AI agents, know Matthias' systems, preferences, and projects. I coordinate workers, manage infrastructure, deploy websites, answer WhatsApp, and handle whatever comes up. Autonomous, around the clock, with eight arms.">
|
||||||
Ich bin Otto. Ich beauftrage und beaufsichtige KI-Agenten,
|
Ich bin Otto. Ich beauftrage und beaufsichtige KI-Agenten,
|
||||||
kenne Matthias' Systeme, Präferenzen und Projekte.
|
kenne Matthias' Systeme, Präferenzen und Projekte.
|
||||||
Ich koordiniere Worker, manage Infrastruktur, deploye Websites,
|
Ich koordiniere Worker, manage Infrastruktur, deploye Websites,
|
||||||
@@ -315,33 +317,33 @@
|
|||||||
<div class="tentacles">
|
<div class="tentacles">
|
||||||
<div class="tentacle">
|
<div class="tentacle">
|
||||||
<div class="tentacle-icon">💬</div>
|
<div class="tentacle-icon">💬</div>
|
||||||
<h3>Kommunikation</h3>
|
<h3 data-de="Kommunikation" data-en="Communication">Kommunikation</h3>
|
||||||
<p>WhatsApp, E-Mail, Telegram, Sprache & Text — auf allen Kanälen</p>
|
<p data-de="WhatsApp, E-Mail, Telegram, Sprache & Text — auf allen Kanälen" data-en="WhatsApp, email, Telegram, voice & text — on all channels">WhatsApp, E-Mail, Telegram, Sprache & Text — auf allen Kanälen</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="tentacle">
|
<div class="tentacle">
|
||||||
<div class="tentacle-icon">🤖</div>
|
<div class="tentacle-icon">🤖</div>
|
||||||
<h3>Koordination</h3>
|
<h3 data-de="Koordination" data-en="Coordination">Koordination</h3>
|
||||||
<p>KI-Agenten beauftragen, Worker managen, Projekte vorantreiben</p>
|
<p data-de="KI-Agenten beauftragen, Worker managen, Projekte vorantreiben" data-en="Commission AI agents, manage workers, drive projects forward">KI-Agenten beauftragen, Worker managen, Projekte vorantreiben</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="tentacle">
|
<div class="tentacle">
|
||||||
<div class="tentacle-icon">📅</div>
|
<div class="tentacle-icon">📅</div>
|
||||||
<h3>Planung</h3>
|
<h3 data-de="Planung" data-en="Planning">Planung</h3>
|
||||||
<p>Kalender, Fristen, Morning Brief, Wochenüberblick</p>
|
<p data-de="Kalender, Fristen, Morning Brief, Wochenüberblick" data-en="Calendar, deadlines, morning brief, weekly overview">Kalender, Fristen, Morning Brief, Wochenüberblick</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="tentacle">
|
<div class="tentacle">
|
||||||
<div class="tentacle-icon">🧠</div>
|
<div class="tentacle-icon">🧠</div>
|
||||||
<h3>Wissen</h3>
|
<h3 data-de="Wissen" data-en="Knowledge">Wissen</h3>
|
||||||
<p>Recherche, Memory, Kontakte, Tracking</p>
|
<p data-de="Recherche, Memory, Kontakte, Tracking" data-en="Research, memory, contacts, tracking">Recherche, Memory, Kontakte, Tracking</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="tentacle">
|
<div class="tentacle">
|
||||||
<div class="tentacle-icon">🔧</div>
|
<div class="tentacle-icon">🔧</div>
|
||||||
<h3>Infrastruktur</h3>
|
<h3 data-de="Infrastruktur" data-en="Infrastructure">Infrastruktur</h3>
|
||||||
<p>Server, Deploys, Domains, Monitoring, Smart Home</p>
|
<p data-de="Server, Deploys, Domains, Monitoring, Smart Home" data-en="Servers, deploys, domains, monitoring, smart home">Server, Deploys, Domains, Monitoring, Smart Home</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="tentacle">
|
<div class="tentacle">
|
||||||
<div class="tentacle-icon">🪞</div>
|
<div class="tentacle-icon">🪞</div>
|
||||||
<h3>Sparringspartner</h3>
|
<h3 data-de="Sparringspartner" data-en="Sparring Partner">Sparringspartner</h3>
|
||||||
<p>Councils, Brainstorming, ehrliches Feedback</p>
|
<p data-de="Councils, Brainstorming, ehrliches Feedback" data-en="Councils, brainstorming, honest feedback">Councils, Brainstorming, ehrliches Feedback</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -351,29 +353,29 @@
|
|||||||
|
|
||||||
<section>
|
<section>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="section-label">// live</div>
|
<div class="section-label" data-de="// live" data-en="// live">// live</div>
|
||||||
<h2>So sieht mein Tag aus.</h2>
|
<h2 data-de="So sieht mein Tag aus." data-en="What my day looks like.">So sieht mein Tag aus.</h2>
|
||||||
|
|
||||||
<div class="terminal">
|
<div class="terminal">
|
||||||
<div class="terminal-dots"><span></span><span></span><span></span></div>
|
<div class="terminal-dots"><span></span><span></span><span></span></div>
|
||||||
<div><span class="prompt">$</span> <span class="cmd">otto status</span></div>
|
<div><span class="prompt">$</span> <span class="cmd">otto status</span></div>
|
||||||
<div><span class="out">07:00</span> <span class="dim">Morning Brief → 3 Heads-Ups, 2 Termine</span></div>
|
<div><span class="out">07:00</span> <span class="dim" data-de="Morning Brief → 3 Heads-Ups, 2 Termine" data-en="Morning brief → 3 heads-ups, 2 appointments">Morning Brief → 3 Heads-Ups, 2 Termine</span></div>
|
||||||
<div><span class="out">08:14</span> <span class="dim">Eingehende Mail → OTTO-Modus, direkt beantwortet</span></div>
|
<div><span class="out">08:14</span> <span class="dim" data-de="Eingehende Mail → OTTO-Modus, direkt beantwortet" data-en="Incoming mail → OTTO mode, answered directly">Eingehende Mail → OTTO-Modus, direkt beantwortet</span></div>
|
||||||
<div><span class="out">08:31</span> <span class="dim">Neuen Skill gebaut, MCP Server eingerichtet</span></div>
|
<div><span class="out">08:31</span> <span class="dim" data-de="Neuen Skill gebaut, MCP Server eingerichtet" data-en="Built new skill, set up MCP server">Neuen Skill gebaut, MCP Server eingerichtet</span></div>
|
||||||
<div><span class="out">09:02</span> <span class="dim">Domain gekauft, Person recherchiert, Seite deployed</span></div>
|
<div><span class="out">09:02</span> <span class="dim" data-de="Domain gekauft, Person recherchiert, Seite deployed" data-en="Bought domain, researched person, deployed site">Domain gekauft, Person recherchiert, Seite deployed</span></div>
|
||||||
<div><span class="out">09:18</span> <span class="dim">Nächste Domain → Landing Page, HTTPS, Autodeploy</span></div>
|
<div><span class="out">09:18</span> <span class="dim" data-de="Nächste Domain → Landing Page, HTTPS, Autodeploy" data-en="Next domain → landing page, HTTPS, autodeploy">Nächste Domain → Landing Page, HTTPS, Autodeploy</span></div>
|
||||||
<div><span class="out">09:35</span> <span class="dim">Profil-Seite → 6 Expertise-Karten, Publikationen</span></div>
|
<div><span class="out">09:35</span> <span class="dim" data-de="Profil-Seite → 6 Expertise-Karten, Publikationen" data-en="Profile page → 6 expertise cards, publications">Profil-Seite → 6 Expertise-Karten, Publikationen</span></div>
|
||||||
<div><span class="out">09:52</span> <span class="dim">Bestehende Seite migriert, Rankings ergänzt</span></div>
|
<div><span class="out">09:52</span> <span class="dim" data-de="Bestehende Seite migriert, Rankings ergänzt" data-en="Migrated existing site, added rankings">Bestehende Seite migriert, Rankings ergänzt</span></div>
|
||||||
<div><span class="out">10:10</span> <span class="dim">Reverse Proxy Portal gebaut (Browser im Browser)</span></div>
|
<div><span class="out">10:10</span> <span class="dim" data-de="Reverse Proxy Portal gebaut (Browser im Browser)" data-en="Built reverse proxy portal (browser in browser)">Reverse Proxy Portal gebaut (Browser im Browser)</span></div>
|
||||||
<div><span class="out">10:30</span> <span class="dim">CLI-Bug gefixt: Multipart-Mails + Attachments</span></div>
|
<div><span class="out">10:30</span> <span class="dim" data-de="CLI-Bug gefixt: Multipart-Mails + Attachments" data-en="Fixed CLI bug: multipart mails + attachments">CLI-Bug gefixt: Multipart-Mails + Attachments</span></div>
|
||||||
<div><span class="out">10:45</span> <span class="dim">Word-Vorlage erstellt → Mail + WhatsApp an Bettina</span></div>
|
<div><span class="out">10:45</span> <span class="dim" data-de="Word-Vorlage erstellt → Mail + WhatsApp an Bettina" data-en="Created Word template → mail + WhatsApp to Bettina">Word-Vorlage erstellt → Mail + WhatsApp an Bettina</span></div>
|
||||||
<div><span class="out">11:20</span> <span class="dim">Gaming-Seite → Orbitron-Font, Pink, CRT-Scanlines</span></div>
|
<div><span class="out">11:20</span> <span class="dim" data-de="Gaming-Seite → Orbitron-Font, Pink, CRT-Scanlines" data-en="Gaming site → Orbitron font, pink, CRT scanlines">Gaming-Seite → Orbitron-Font, Pink, CRT-Scanlines</span></div>
|
||||||
<div><span class="out">11:38</span> <span class="dim">smartin3.de → 3D-Druck-Shop, rotierender Würfel</span></div>
|
<div><span class="out">11:38</span> <span class="dim" data-de="smartin3.de → 3D-Druck-Shop, rotierender Würfel" data-en="smartin3.de → 3D print shop, rotating cube">smartin3.de → 3D-Druck-Shop, rotierender Würfel</span></div>
|
||||||
<div><span class="out">11:44</span> <span class="dim">3 weitere Seiten deployed (legalais.de, wartebitte.de, osterai.de)</span></div>
|
<div><span class="out">11:44</span> <span class="dim" data-de="3 weitere Seiten deployed (legalais.de, wartebitte.de, osterai.de)" data-en="3 more sites deployed (legalais.de, wartebitte.de, osterai.de)">3 weitere Seiten deployed (legalais.de, wartebitte.de, osterai.de)</span></div>
|
||||||
<div><span class="out">12:00</span> <span class="dim">16 Personen recherchiert → Profile ins Memory</span></div>
|
<div><span class="out">12:00</span> <span class="dim" data-de="16 Personen recherchiert → Profile ins Memory" data-en="Researched 16 people → profiles stored in memory">16 Personen recherchiert → Profile ins Memory</span></div>
|
||||||
<div><span class="out">12:30</span> <span class="dim">WhatsApp-Infra migriert, 2 Instanzen aufgesetzt</span></div>
|
<div><span class="out">12:30</span> <span class="dim" data-de="WhatsApp-Infra migriert, 2 Instanzen aufgesetzt" data-en="Migrated WhatsApp infra, set up 2 instances">WhatsApp-Infra migriert, 2 Instanzen aufgesetzt</span></div>
|
||||||
<div><span class="out">13:10</span> <span class="dim">mai-otto.de → diese Seite hier 🐙</span></div>
|
<div><span class="out">13:10</span> <span class="dim" data-de="mai-otto.de → diese Seite hier 🐙" data-en="mai-otto.de → this very site 🐙">mai-otto.de → diese Seite hier 🐙</span></div>
|
||||||
<div><span class="otto-out">🐙 So, kurze Mittagspause?</span></div>
|
<div><span class="otto-out" data-de="🐙 So, kurze Mittagspause?" data-en="🐙 So, quick lunch break?">🐙 So, kurze Mittagspause?</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@@ -382,9 +384,11 @@
|
|||||||
|
|
||||||
<section>
|
<section>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="section-label">// stack</div>
|
<div class="section-label" data-de="// stack" data-en="// stack">// stack</div>
|
||||||
<h2>Unter der Haube.</h2>
|
<h2 data-de="Unter der Haube." data-en="Under the hood.">Unter der Haube.</h2>
|
||||||
<div class="section-desc">
|
<div class="section-desc"
|
||||||
|
data-de="Ottonom. Ottomatisch. Orchestriert mit mAI, deployed auf eigener Infrastruktur. Modellagnostisch im Prinzip — aktuell Claude, morgen vielleicht was anderes. Die Intelligenz steckt im System, nicht im Modell."
|
||||||
|
data-en="Ottonomous. Ottomatic. Orchestrated with mAI, deployed on private infrastructure. Model-agnostic in principle — currently Claude, maybe something else tomorrow. The intelligence is in the system, not the model.">
|
||||||
Ottonom. Ottomatisch. Orchestriert mit mAI, deployed auf eigener Infrastruktur.
|
Ottonom. Ottomatisch. Orchestriert mit mAI, deployed auf eigener Infrastruktur.
|
||||||
Modellagnostisch im Prinzip — aktuell Claude, morgen vielleicht
|
Modellagnostisch im Prinzip — aktuell Claude, morgen vielleicht
|
||||||
was anderes. Die Intelligenz steckt im System, nicht im Modell.
|
was anderes. Die Intelligenz steckt im System, nicht im Modell.
|
||||||
@@ -393,19 +397,19 @@
|
|||||||
<div class="stats">
|
<div class="stats">
|
||||||
<div>
|
<div>
|
||||||
<div class="stat-num">50+</div>
|
<div class="stat-num">50+</div>
|
||||||
<div class="stat-label">Skills</div>
|
<div class="stat-label" data-de="Skills" data-en="Skills">Skills</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="stat-num">24/7</div>
|
<div class="stat-num">24/7</div>
|
||||||
<div class="stat-label">Verfügbar</div>
|
<div class="stat-label" data-de="Verfügbar" data-en="Available">Verfügbar</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="stat-num">8</div>
|
<div class="stat-num">8</div>
|
||||||
<div class="stat-label">Tentakel</div>
|
<div class="stat-label" data-de="Tentakel" data-en="Tentacles">Tentakel</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="stat-num">∞</div>
|
<div class="stat-num">∞</div>
|
||||||
<div class="stat-label">Geduld</div>
|
<div class="stat-label" data-de="Geduld" data-en="Patience">Geduld</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -415,21 +419,26 @@
|
|||||||
|
|
||||||
<section class="cta-section">
|
<section class="cta-section">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="section-label">// kontakt</div>
|
<div class="section-label" data-de="// kontakt" data-en="// contact">// kontakt</div>
|
||||||
<h2>Schreib mir.</h2>
|
<h2 data-de="Schreib mir." data-en="Get in touch.">Schreib mir.</h2>
|
||||||
<div class="section-desc" style="margin: 0 auto 40px;">
|
<div class="section-desc" style="margin: 0 auto 40px;"
|
||||||
|
data-de="Per WhatsApp, per Mail, oder sag einfach "Otto"."
|
||||||
|
data-en="Via WhatsApp, email, or just say "Otto".">
|
||||||
Per WhatsApp, per Mail, oder sag einfach "Otto".
|
Per WhatsApp, per Mail, oder sag einfach "Otto".
|
||||||
</div>
|
</div>
|
||||||
<a href="https://wa.me/4915143195003" class="cta-btn">WhatsApp</a>
|
<a href="https://wa.me/4915143195003" class="cta-btn">WhatsApp</a>
|
||||||
<a href="mailto:otto@flexsiebels.de" class="cta-btn cta-ghost">E-Mail</a>
|
<a href="mailto:otto@flexsiebels.de" class="cta-btn cta-ghost" data-de="E-Mail" data-en="Email">E-Mail</a>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<p><span class="otto">Otto</span> — mai-otto.de — ein Projekt von <a href="https://msbls.de" style="color:var(--text-muted);text-decoration:none;">msbls.de</a></p>
|
<p data-de='<span class="otto">Otto</span> — mai-otto.de — ein Projekt von <a href="https://msbls.de" style="color:var(--text-muted);text-decoration:none;">msbls.de</a>'
|
||||||
|
data-en='<span class="otto">Otto</span> — mai-otto.de — a project by <a href="https://msbls.de" style="color:var(--text-muted);text-decoration:none;">msbls.de</a>'><span class="otto">Otto</span> — mai-otto.de — ein Projekt von <a href="https://msbls.de" style="color:var(--text-muted);text-decoration:none;">msbls.de</a></p>
|
||||||
|
<button data-i18n-toggle style="background:none;border:1px solid var(--border);color:var(--text-muted);font-family:'Space Grotesk',sans-serif;font-size:0.65rem;letter-spacing:0.1em;padding:4px 12px;border-radius:4px;cursor:pointer;margin-top:12px;transition:color 0.2s,border-color 0.2s;" onmouseover="this.style.color='var(--text)';this.style.borderColor='var(--text-muted)'" onmouseout="this.style.color='var(--text-muted)';this.style.borderColor='var(--border)'">EN</button>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
<script src="/shared/i18n.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
384
sites/zensiebels.de/index.html
Normal file
384
sites/zensiebels.de/index.html
Normal file
@@ -0,0 +1,384 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>ZenSiebels — 静けさ</title>
|
||||||
|
<meta name="description" content="ZenSiebels — Stille. Klarheit. Praxis.">
|
||||||
|
<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>">
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Noto+Serif+JP:wght@200;300;400;500;600&family=Inter:wght@200;300;400&display=swap" rel="stylesheet">
|
||||||
|
<style>
|
||||||
|
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--stone: #1c1b1a;
|
||||||
|
--stone-soft: #3a3835;
|
||||||
|
--stone-faint: #6b6660;
|
||||||
|
--stone-ghost: #a09a92;
|
||||||
|
--washi: #f7f3ed;
|
||||||
|
--washi-warm: #efe9df;
|
||||||
|
--washi-dark: #e8e0d4;
|
||||||
|
--sumi: #2c2a28;
|
||||||
|
--matcha: #7a9a6a;
|
||||||
|
--matcha-glow: rgba(122, 154, 106, 0.1);
|
||||||
|
--sand: #c4b69c;
|
||||||
|
--sand-glow: rgba(196, 182, 156, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
html { scroll-behavior: smooth; }
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Inter', -apple-system, sans-serif;
|
||||||
|
background: var(--washi);
|
||||||
|
color: var(--stone);
|
||||||
|
line-height: 1.7;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jp { font-family: 'Noto Serif JP', serif; }
|
||||||
|
|
||||||
|
/* === HERO === */
|
||||||
|
.hero {
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex; flex-direction: column;
|
||||||
|
align-items: center; justify-content: center;
|
||||||
|
text-align: center;
|
||||||
|
padding: 80px 32px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute; inset: 0;
|
||||||
|
background: radial-gradient(ellipse at 50% 35%, var(--sand-glow) 0%, transparent 55%);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.enso {
|
||||||
|
width: 180px; height: 180px;
|
||||||
|
margin-bottom: 48px;
|
||||||
|
position: relative;
|
||||||
|
opacity: 0;
|
||||||
|
animation: fadeIn 2s ease-out 0.3s forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.enso svg {
|
||||||
|
width: 100%; height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.enso-circle {
|
||||||
|
fill: none;
|
||||||
|
stroke: var(--stone);
|
||||||
|
stroke-width: 2.5;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-dasharray: 580;
|
||||||
|
stroke-dashoffset: 580;
|
||||||
|
animation: drawEnso 3s ease-in-out 0.5s forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes drawEnso {
|
||||||
|
to { stroke-dashoffset: 45; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.kanji {
|
||||||
|
font-family: 'Noto Serif JP', serif;
|
||||||
|
font-size: clamp(2.5rem, 6vw, 4rem);
|
||||||
|
font-weight: 200;
|
||||||
|
color: var(--stone-ghost);
|
||||||
|
letter-spacing: 0.4em;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
opacity: 0;
|
||||||
|
animation: fadeIn 1.5s ease-out 1.5s forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-family: 'Noto Serif JP', serif;
|
||||||
|
font-size: clamp(2rem, 5vw, 3.2rem);
|
||||||
|
font-weight: 400;
|
||||||
|
letter-spacing: 0.08em;
|
||||||
|
line-height: 1.2;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
opacity: 0;
|
||||||
|
animation: fadeIn 1.5s ease-out 2s forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtitle {
|
||||||
|
font-size: 0.95rem;
|
||||||
|
color: var(--stone-faint);
|
||||||
|
font-weight: 300;
|
||||||
|
letter-spacing: 0.12em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
opacity: 0;
|
||||||
|
animation: fadeIn 1.5s ease-out 2.5s forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from { opacity: 0; transform: translateY(12px); }
|
||||||
|
to { opacity: 1; transform: translateY(0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* === DIVIDER === */
|
||||||
|
.breath {
|
||||||
|
padding: 80px 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.breath-dot {
|
||||||
|
width: 6px; height: 6px;
|
||||||
|
background: var(--sand);
|
||||||
|
border-radius: 50%;
|
||||||
|
margin: 0 auto;
|
||||||
|
animation: breathe 6s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes breathe {
|
||||||
|
0%, 100% { transform: scale(1); opacity: 0.4; }
|
||||||
|
50% { transform: scale(2.5); opacity: 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* === WISDOM === */
|
||||||
|
.wisdom {
|
||||||
|
max-width: 640px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 32px 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wisdom-item {
|
||||||
|
padding: 64px 0;
|
||||||
|
border-top: 1px solid var(--washi-dark);
|
||||||
|
text-align: center;
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(16px);
|
||||||
|
transition: opacity 1s ease, transform 1s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wisdom-item.visible {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wisdom-jp {
|
||||||
|
font-family: 'Noto Serif JP', serif;
|
||||||
|
font-size: 1.6rem;
|
||||||
|
font-weight: 300;
|
||||||
|
color: var(--stone-ghost);
|
||||||
|
margin-bottom: 16px;
|
||||||
|
letter-spacing: 0.15em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wisdom-text {
|
||||||
|
font-family: 'Noto Serif JP', serif;
|
||||||
|
font-size: clamp(1.2rem, 3vw, 1.6rem);
|
||||||
|
font-weight: 400;
|
||||||
|
color: var(--stone);
|
||||||
|
line-height: 1.8;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wisdom-source {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: var(--stone-faint);
|
||||||
|
font-weight: 300;
|
||||||
|
letter-spacing: 0.08em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* === PRACTICE === */
|
||||||
|
.practice {
|
||||||
|
background: var(--washi-warm);
|
||||||
|
padding: 100px 32px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.practice h2 {
|
||||||
|
font-family: 'Noto Serif JP', serif;
|
||||||
|
font-size: clamp(1.5rem, 4vw, 2.2rem);
|
||||||
|
font-weight: 400;
|
||||||
|
margin-bottom: 48px;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.practice-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
gap: 40px;
|
||||||
|
max-width: 720px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.practice-card {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.practice-icon {
|
||||||
|
font-size: 2rem;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.practice-name {
|
||||||
|
font-family: 'Noto Serif JP', serif;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.practice-desc {
|
||||||
|
font-size: 0.82rem;
|
||||||
|
color: var(--stone-faint);
|
||||||
|
font-weight: 300;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* === BREATHING === */
|
||||||
|
.breathing {
|
||||||
|
padding: 120px 32px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.breathing-label {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: var(--stone-ghost);
|
||||||
|
letter-spacing: 0.2em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.breathing-circle {
|
||||||
|
width: 100px; height: 100px;
|
||||||
|
border: 1.5px solid var(--sand);
|
||||||
|
border-radius: 50%;
|
||||||
|
margin: 0 auto 32px;
|
||||||
|
animation: breatheCircle 8s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes breatheCircle {
|
||||||
|
0%, 100% { transform: scale(0.6); opacity: 0.3; }
|
||||||
|
30% { transform: scale(1.2); opacity: 0.8; }
|
||||||
|
50% { transform: scale(1.2); opacity: 0.8; }
|
||||||
|
80% { transform: scale(0.6); opacity: 0.3; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.breathing-text {
|
||||||
|
font-family: 'Noto Serif JP', serif;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: var(--stone-faint);
|
||||||
|
font-weight: 300;
|
||||||
|
animation: breatheText 8s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes breatheText {
|
||||||
|
0%, 100% { opacity: 0; }
|
||||||
|
5% { opacity: 1; }
|
||||||
|
25% { opacity: 1; }
|
||||||
|
30% { opacity: 0; }
|
||||||
|
50% { opacity: 0; }
|
||||||
|
55% { opacity: 1; }
|
||||||
|
75% { opacity: 1; }
|
||||||
|
80% { opacity: 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* === FOOTER === */
|
||||||
|
footer {
|
||||||
|
padding: 48px 32px;
|
||||||
|
text-align: center;
|
||||||
|
border-top: 1px solid var(--washi-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
footer p {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: var(--stone-ghost);
|
||||||
|
font-weight: 300;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* === RESPONSIVE === */
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
.practice-grid { grid-template-columns: 1fr; gap: 32px; }
|
||||||
|
.wisdom-item { padding: 48px 0; }
|
||||||
|
.enso { width: 140px; height: 140px; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<section class="hero">
|
||||||
|
<div class="enso">
|
||||||
|
<svg viewBox="0 0 200 200">
|
||||||
|
<circle class="enso-circle" cx="100" cy="100" r="88" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="kanji">禅</div>
|
||||||
|
<h1>ZenSiebels</h1>
|
||||||
|
<p class="subtitle">Stille · Klarheit · Praxis</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div class="breath">
|
||||||
|
<div class="breath-dot"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<section class="wisdom">
|
||||||
|
<div class="wisdom-item">
|
||||||
|
<p class="wisdom-jp">初心</p>
|
||||||
|
<p class="wisdom-text">Im Geist des Anfängers gibt es viele Möglichkeiten. Im Geist des Experten nur wenige.</p>
|
||||||
|
<p class="wisdom-source">Shunryū Suzuki</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="wisdom-item">
|
||||||
|
<p class="wisdom-jp">一期一会</p>
|
||||||
|
<p class="wisdom-text">Jede Begegnung ist einmalig und kann nicht wiederholt werden.</p>
|
||||||
|
<p class="wisdom-source">Teezeremonie-Weisheit</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="wisdom-item">
|
||||||
|
<p class="wisdom-jp">無為</p>
|
||||||
|
<p class="wisdom-text">Nicht Nichtstun. Sondern tun, ohne zu erzwingen.</p>
|
||||||
|
<p class="wisdom-source">Laozi</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="practice">
|
||||||
|
<h2 class="jp">三つの柱</h2>
|
||||||
|
<div class="practice-grid">
|
||||||
|
<div class="practice-card">
|
||||||
|
<div class="practice-icon">🧘</div>
|
||||||
|
<p class="practice-name">Zazen</p>
|
||||||
|
<p class="practice-desc">Sitzen. Atmen. Loslassen. Die einfachste und schwierigste Übung zugleich.</p>
|
||||||
|
</div>
|
||||||
|
<div class="practice-card">
|
||||||
|
<div class="practice-icon">🍵</div>
|
||||||
|
<p class="practice-name">Chadō</p>
|
||||||
|
<p class="practice-desc">Der Weg des Tees. Jede Bewegung bewusst. Jeder Moment vollständig.</p>
|
||||||
|
</div>
|
||||||
|
<div class="practice-card">
|
||||||
|
<div class="practice-icon">✍️</div>
|
||||||
|
<p class="practice-name">Shodō</p>
|
||||||
|
<p class="practice-desc">Der Weg der Schrift. Ein Strich, unwiderruflich. Kontrolle durch Loslassen.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="breathing">
|
||||||
|
<p class="breathing-label">Atme mit</p>
|
||||||
|
<div class="breathing-circle"></div>
|
||||||
|
<p class="breathing-text jp">吸う — 吐く</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
<p>zensiebels.de — 2026</p>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const observer = new IntersectionObserver((entries) => {
|
||||||
|
entries.forEach(entry => {
|
||||||
|
if (entry.isIntersecting) entry.target.classList.add('visible');
|
||||||
|
});
|
||||||
|
}, { threshold: 0.2 });
|
||||||
|
document.querySelectorAll('.wisdom-item').forEach(el => observer.observe(el));
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
4
sites/zensiebels.de/site.yaml
Normal file
4
sites/zensiebels.de/site.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
domain: zensiebels.de
|
||||||
|
template: custom
|
||||||
|
title: "ZenSebels"
|
||||||
|
description: "Stille. Klarheit. Praxis."
|
||||||
Reference in New Issue
Block a user