init: scaffold OPENBUREAU site with shibui-derived theme
- Hugo site for openbureau.ch (Deutsch, i18n-ready for EN/IT) - Theme themes/openbureau/ = local copy of shibui, customized via site-level layouts and assets to keep the theme reference clean - Editorial typography stack: Newsreader serif body, Space Grotesk display, Inter for listings, IBM Plex Mono for technical meta - Content structure: library/ (Theorie, Büroführung, Software) with manifest and colophon at root; software is a library category, not a separate top-level - Three views over one source: Journal (chronological home), Library (atlas grouped by section + tag cloud), single articles Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+77
@@ -0,0 +1,77 @@
|
||||
|
||||
<style>
|
||||
* { cursor: none !important; }
|
||||
body { min-height: 400px; display: flex; align-items: center; justify-content: center; flex-direction: column; gap: 2rem; font-family: monospace; }
|
||||
#cursor {
|
||||
position: fixed;
|
||||
pointer-events: none;
|
||||
z-index: 9999;
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
.demo-box {
|
||||
padding: 1.5rem 2rem;
|
||||
border: 0.5px solid var(--color-border-tertiary);
|
||||
border-radius: 8px;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
</style>
|
||||
|
||||
<h2 class="sr-only">8-bit cursor preview</h2>
|
||||
<div class="demo-box">bewege die maus hier</div>
|
||||
<canvas id="cursor"></canvas>
|
||||
|
||||
<script>
|
||||
const canvas = document.getElementById('cursor');
|
||||
const ctx = canvas.getContext('2d');
|
||||
const P = 3;
|
||||
|
||||
// B=black, W=white, _=transparent
|
||||
// Pixel-genaue Nachzeichnung des klassischen Windows-Cursors
|
||||
const grid = [
|
||||
'B_____________',
|
||||
'BB____________',
|
||||
'BWB___________',
|
||||
'BWWB__________',
|
||||
'BWWWB_________',
|
||||
'BWWWWB________',
|
||||
'BWWWWWB_______',
|
||||
'BWWWWWWB______',
|
||||
'BWWWWWWWB_____',
|
||||
'BWWWWWWWWB____',
|
||||
'BWWWWWWWWWB___',
|
||||
'BWWWWWWBBB____',
|
||||
'BWWWBWWB______',
|
||||
'BWWB_BWWB_____',
|
||||
'BWB___BWWB____',
|
||||
'BB_____BWWB___',
|
||||
'B_______BWB___',
|
||||
'________BB____',
|
||||
];
|
||||
|
||||
const rows = grid.length;
|
||||
const cols = grid[0].length;
|
||||
canvas.width = cols * P;
|
||||
canvas.height = rows * P;
|
||||
canvas.style.width = cols * P + 'px';
|
||||
canvas.style.height = rows * P + 'px';
|
||||
|
||||
grid.forEach((row, y) => {
|
||||
for (let x = 0; x < row.length; x++) {
|
||||
const c = row[x];
|
||||
if (c === 'B') {
|
||||
ctx.fillStyle = '#000000';
|
||||
ctx.fillRect(x * P, y * P, P, P);
|
||||
} else if (c === 'W') {
|
||||
ctx.fillStyle = '#ffffff';
|
||||
ctx.fillRect(x * P, y * P, P, P);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('mousemove', e => {
|
||||
canvas.style.left = e.clientX + 'px';
|
||||
canvas.style.top = e.clientY + 'px';
|
||||
});
|
||||
</script>
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
<!-- This partial can be replaced to support other commenting engines -->
|
||||
{{ template "_internal/disqus.html" . }}
|
||||
+1
@@ -0,0 +1 @@
|
||||
<time datetime="{{ . | time.Format "2006-01-02" }}">{{ . | time.Format "2006" }} </time>
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
<p>© {{ now.Year }} karimgabrielevarano.xyz</p>
|
||||
<p><a href="/legal-notice/">legal notice</a></p>
|
||||
<script src="/js/auto-carousel.js"></script>
|
||||
<link rel="stylesheet" href="/css/auto-carousel.css">
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="color-scheme" content="light" />
|
||||
<link rel="preconnect" href="https://cdn.jsdelivr.net">
|
||||
<link rel="dns-prefetch" href="https://cdn.jsdelivr.net">
|
||||
<title>
|
||||
{{ if .IsHome }}{{ site.Title }}{{ else }}{{ printf "%s | %s" .Title
|
||||
site.Title }}{{ end }}
|
||||
</title>
|
||||
{{ with .Description | default .Site.Params.description }}<meta
|
||||
name="description"
|
||||
content="{{ . }}"
|
||||
/>{{ end }} {{/* Canonical URL */}}
|
||||
<link rel="canonical" href="{{ .Permalink }}" />
|
||||
|
||||
{{/* Open Graph */}}
|
||||
<meta property="og:title" content="{{ .Title }}" />
|
||||
{{ with .Description | default .Site.Params.description }}<meta
|
||||
property="og:description"
|
||||
content="{{ . }}"
|
||||
/>{{ end }}
|
||||
<meta
|
||||
property="og:type"
|
||||
content="{{ if .IsPage }}article{{ else }}website{{ end }}"
|
||||
/>
|
||||
<meta property="og:url" content="{{ .Permalink }}" />
|
||||
{{ with .Site.Params.ogImage }}<meta
|
||||
property="og:image"
|
||||
content="{{ . | absURL }}"
|
||||
/>{{ end }} {{/* Twitter Card */}}
|
||||
<meta name="twitter:card" content="summary" />
|
||||
<meta name="twitter:title" content="{{ .Title }}" />
|
||||
{{ with .Description | default .Site.Params.description }}<meta
|
||||
name="twitter:description"
|
||||
content="{{ . }}"
|
||||
/>{{ end }} {{ with .Site.Params.twitterHandle }}<meta
|
||||
name="twitter:site"
|
||||
content="@{{ . }}"
|
||||
/>{{ end }} {{ with .Site.Params.ogImage }}<meta
|
||||
name="twitter:image"
|
||||
content="{{ . | absURL }}"
|
||||
/>{{ end }} {{/* RSS Feed */}} {{ with .OutputFormats.Get "rss" -}} {{ printf
|
||||
`<link rel="%s" type="%s" href="%s" title="%s" />` .Rel .MediaType.Type
|
||||
.Permalink site.Title | safeHTML }} {{ end }} {{/* JSON-LD Structured Data for
|
||||
Articles */}} {{ if .IsPage }}
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Article",
|
||||
"headline": "{{ .Title }}",
|
||||
"url": "{{ .Permalink }}",
|
||||
"datePublished": "{{ .Date.Format "2006-01-02T15:04:05Z07:00" }}",
|
||||
"dateModified": "{{ .Lastmod.Format "2006-01-02T15:04:05Z07:00" }}"
|
||||
{{- with .Site.Params.author }},
|
||||
"author": {
|
||||
"@type": "Person",
|
||||
"name": "{{ .name | default . }}"
|
||||
}
|
||||
{{- end }}
|
||||
{{- with $.Description | default $.Site.Params.description }},
|
||||
"description": "{{ . }}"
|
||||
{{- end }}
|
||||
}
|
||||
</script>
|
||||
{{ end }} {{ partialCached "head/favicon.html" . }} {{ partialCached
|
||||
"head/css.html" . }}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
{{- with resources.Get "css/main.css" }}
|
||||
{{- if hugo.IsDevelopment }}
|
||||
<link rel="stylesheet" href="{{ .RelPermalink }}">
|
||||
{{- else }}
|
||||
{{- with . | minify | fingerprint }}
|
||||
<link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- with resources.Get "css/custom.css" }}
|
||||
{{- if hugo.IsDevelopment }}
|
||||
<link rel="stylesheet" href="{{ .RelPermalink }}">
|
||||
{{- else }}
|
||||
{{- with . | minify | fingerprint }}
|
||||
<link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="{{ "favicon_io/apple-icon-57x57.png" | relURL }}">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="{{ "favicon_io/apple-icon-60x60.png" | relURL }}">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="{{ "favicon_io/apple-icon-72x72.png" | relURL }}">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="{{ "favicon_io/apple-icon-76x76.png" | relURL }}">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="{{ "favicon_io/apple-icon-114x114.png" | relURL }}">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="{{ "favicon_io/apple-icon-120x120.png" | relURL }}">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="{{ "favicon_io/apple-icon-144x144.png" | relURL }}">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="{{ "favicon_io/apple-icon-152x152.png" | relURL }}">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="{{ "favicon_io/apple-icon-180x180.png" | relURL }}">
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="{{ "favicon_io/android-icon-192x192.png" | relURL }}">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="{{ "favicon_io/favicon-32x32.png" | relURL }}">
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="{{ "favicon_io/favicon-96x96.png" | relURL }}">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="{{ "favicon_io/favicon-16x16.png" | relURL }}">
|
||||
<link rel="manifest" href="{{ "favicon_io/manifest.json" | relURL }}">
|
||||
<meta name="msapplication-TileColor" content="#ffffff">
|
||||
<meta name="msapplication-TileImage" content="{{ "favicon_io/ms-icon-144x144.png" | relURL }}">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
<nav class="path-nav" aria-label="Breadcrumb">
|
||||
<ol>
|
||||
{{ template "breadcrumbnav" (dict "p1" . "p2" .) }}
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
{{ define "breadcrumbnav" }}
|
||||
{{ if .p1.Parent }}
|
||||
{{ template "breadcrumbnav" (dict "p1" .p1.Parent "p2" .p2 ) }}
|
||||
{{ else if not .p1.IsHome }}
|
||||
{{ template "breadcrumbnav" (dict "p1" .p1.Site.Home "p2" .p2 ) }}
|
||||
{{ end }}
|
||||
<li{{ if eq .p1 .p2 }} class="current"{{ end }}>
|
||||
{{ if .p1.IsHome }}/{{ end }}
|
||||
<a href="{{ .p1.RelPermalink }}">{{ if .p1.IsHome }}{{ .p1.Site.Title }}{{ else }}{{ .p1.Title }}{{ end }}</a>
|
||||
{{ if ne .p1 .p2 }}/{{ end }}
|
||||
</li>
|
||||
{{ end }}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
{{- $duration := "7000" -}}
|
||||
{{- $content := $ -}}
|
||||
{{- $imageListPattern := `<ul>\s*(?:<li><figure>\s*<img[^>]*/?>\s*</figure>\s*</li>\s*)+</ul>` -}}
|
||||
{{- $imageLists := findRE $imageListPattern $content -}}
|
||||
{{- range $index,$il := $imageLists -}}
|
||||
{{- $listItems := findRE `<li><figure>\s*<img[^>]*/?>\s*</figure>\s*</li>` $il -}}
|
||||
{{- $items := `<ul>` -}}
|
||||
{{- range $i,$li := $listItems -}}
|
||||
{{- $img := index (findRE `<img[^>]*/?>` $li) 0 -}}
|
||||
{{- $items = print $items `<li id="c` $index `_slide` $i `">` $img `</li>` -}}
|
||||
{{- end -}}
|
||||
{{- $items = print $items `</ul>` -}}
|
||||
{{- $indicators := `<ol>` -}}
|
||||
{{- range $i,$li := $listItems -}}
|
||||
{{- $indicators = print $indicators `<li><a href="#c` $index `_slide` $i `"></a></li>` -}}
|
||||
{{- end -}}
|
||||
{{- $indicators = print $indicators `</ol>` -}}
|
||||
{{- $replacement := print `<div id="carousel_` $index `" class="auto-carousel" duration="` $duration `">` $items $indicators `<div class="prev">‹</div><div class="next">›</div></div>` -}}
|
||||
{{- $content = replace $content $il $replacement -}}
|
||||
{{- end -}}
|
||||
{{- $content | safeHTML -}}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
{{- /*
|
||||
Renders a menu for the given menu ID.
|
||||
|
||||
@context {page} page The current page.
|
||||
@context {string} menuID The menu ID.
|
||||
|
||||
@example: {{ partial "menu.html" (dict "menuID" "main" "page" .) }}
|
||||
*/}}
|
||||
|
||||
{{- $page := .page }}
|
||||
{{- $menuID := .menuID }}
|
||||
|
||||
{{- with index site.Menus $menuID }}
|
||||
<nav aria-label="Main navigation">
|
||||
<ul>
|
||||
{{- partial "inline/menu/walk.html" (dict "page" $page "menuEntries" .) }}
|
||||
</ul>
|
||||
</nav>
|
||||
{{- end }}
|
||||
|
||||
{{- define "_partials/inline/menu/walk.html" }}
|
||||
{{- $page := .page }}
|
||||
{{- range .menuEntries }}
|
||||
{{- $attrs := dict "href" .URL }}
|
||||
{{- if $page.IsMenuCurrent .Menu . }}
|
||||
{{- $attrs = merge $attrs (dict "class" "active" "aria-current" "page") }}
|
||||
{{- else if $page.HasMenuCurrent .Menu .}}
|
||||
{{- $attrs = merge $attrs (dict "class" "ancestor" "aria-current" "true") }}
|
||||
{{- end }}
|
||||
{{- $name := .Name }}
|
||||
{{- with .Identifier }}
|
||||
{{- with T . }}
|
||||
{{- $name = . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
<li>
|
||||
<a
|
||||
{{- range $k, $v := $attrs }}
|
||||
{{- with $v }}
|
||||
{{- printf " %s=%q" $k $v | safeHTMLAttr }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
>{{ $name }}</a>
|
||||
{{- with .Children }}
|
||||
<ul>
|
||||
{{- partial "inline/menu/walk.html" (dict "page" $page "menuEntries" .) }}
|
||||
</ul>
|
||||
{{- end }}
|
||||
</li>
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
{{- /*
|
||||
For a given taxonomy, renders a list of terms assigned to the page.
|
||||
|
||||
@context {page} page The current page.
|
||||
@context {string} taxonomy The taxonomy.
|
||||
|
||||
@example: {{ partial "terms.html" (dict "taxonomy" "tags" "page" .) }}
|
||||
*/}}
|
||||
|
||||
{{- $page := .page }}
|
||||
{{- $taxonomy := .taxonomy }}
|
||||
|
||||
{{- with $page.GetTerms $taxonomy }}
|
||||
{{- $label := (index . 0).Parent.LinkTitle }}
|
||||
<div class="terms-list">
|
||||
<ul>
|
||||
{{- range . }}
|
||||
<li><a href="{{ .RelPermalink }}">#{{ .LinkTitle }}</a></li>
|
||||
{{- end }}
|
||||
</ul>
|
||||
</div>
|
||||
{{- end }}
|
||||
Reference in New Issue
Block a user