Commit Diff


commit - /dev/null
commit + 5d8bab3df1ad4220a43e23137f107e1e1e12d872
blob - /dev/null
blob + 685598e624870be707fd6f90a05700678c444682 (mode 644)
--- /dev/null
+++ LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2025 Isaac Meerloo
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
blob - /dev/null
blob + 8a6c3de43a11b7a049ad2ea35f647153bc633a18 (mode 644)
--- /dev/null
+++ README.md
@@ -0,0 +1,146 @@
+# Soul
+
+A minimal, typography-focused Hugo theme with elegant sidebar navigation and full customization support.
+
+## Features
+
+- **Clean, distraction-free design** - Focus on content and readability
+- **Responsive sidebar navigation** - Converts to horizontal menu on mobile
+- **Typography-first** - Beautiful Inter font with variable font support
+- **Fully customizable** - Configure colors, fonts, layout, and menu via `hugo.toml`
+- **Fast and lightweight** - No JavaScript dependencies, optimized CSS
+- **SEO-ready** - Proper meta tags, OpenGraph, and Twitter card support
+
+## Installation
+
+### As a Git Submodule
+
+```bash
+git submodule add https://github.com/isaacmeerloo/soul.git themes/soul
+```
+
+### Manual Installation
+
+Download and extract the theme into your `themes/` directory:
+
+```bash
+cd themes
+git clone https://github.com/isaacmeerloo/soul.git
+```
+
+## Configuration
+
+Add `theme = 'soul'` to your `hugo.toml` and configure the theme parameters:
+
+```toml
+baseURL = 'https://example.com/'
+languageCode = 'en-us'
+title = 'My Site'
+theme = 'soul'
+
+[params]
+  description = "My personal website"
+  author = "Your Name"
+  keywords = ["blog", "personal"]
+
+  [params.colors]
+    background = "#cdecff"
+    accent = "#ff6300"
+    linkBg = "#fbf1a9"
+    linkHover = "#ffffff"
+    textPrimary = "rgba(0, 0, 0, 0.60)"
+    titleColor = "#ffffff"
+    blockquoteBorder = "#ff6300"
+    themeColor = "#cdecffc"
+
+  [params.typography]
+    enableInterFont = true
+
+  [params.layout]
+    navWidth = "300px"
+    contentMaxWidth = "800px"
+
+  [[params.menu]]
+    name = "Blog"
+    url = "/blog"
+  [[params.menu]]
+    name = "About"
+    url = "/about"
+
+  [params.footer]
+    startYear = "2025"
+```
+
+## Customization
+
+### Colors
+
+All colors can be customized via `params.colors`:
+- `background` - Main page background
+- `accent` - Hover and accent color
+- `linkBg` - Link background color
+- `linkHover` - Link hover background
+- `textPrimary` - Navigation text color
+- `titleColor` - Page title color
+- `blockquoteBorder` - Blockquote border color
+- `themeColor` - Browser theme color
+
+### Layout
+
+Customize layout dimensions via `params.layout`:
+- `navWidth` - Sidebar width (default: "300px")
+- `contentMaxWidth` - Content max width (default: "800px")
+
+### Navigation Menu
+
+Define your menu items in `params.menu`:
+
+```toml
+[[params.menu]]
+  name = "Blog"
+  url = "/blog"
+[[params.menu]]
+  name = "Projects"
+  url = "/projects"
+```
+
+### Typography
+
+Control font loading via `params.typography.enableInterFont` (default: true).
+Set to `false` to use system fonts or provide your own font.
+
+## Advanced Customization
+
+### Overriding Theme Files
+
+You can override any theme file by creating the same file path in your site root. For example:
+- Override navigation: Create `/layouts/partials/nav.html` in your site
+- Custom CSS: Create `/assets/custom.css` and include it in a custom head partial
+- Modify templates: Create `/layouts/_default/single.html` in your site
+
+### Adding Custom CSS
+
+Create `/assets/custom.css` in your site root and include it by overriding the head partial.
+
+## Example Site
+
+See the `exampleSite/` directory for a complete working example.
+
+To run the example:
+
+```bash
+cd exampleSite
+hugo server
+```
+
+## Requirements
+
+- Hugo v0.112.0 or higher (extended version recommended for asset processing)
+
+## License
+
+MIT License - see [LICENSE](LICENSE) file for details.
+
+## Credits
+
+Created by [Isaac Meerloo](https://36.church)
blob - /dev/null
blob + d964fc72316242ecd1db52388b694cd45f8941d3 (mode 644)
--- /dev/null
+++ archetypes/default.md
@@ -0,0 +1,5 @@
+---
+title: '{{ replace .File.ContentBaseName `-` ` ` | title }}'
+date: '{{ now.Format "2006-01-02" }}'
+draft: true
+---
blob - /dev/null
blob + 4666df284eaa1779e633ed9f7c2c9c1ee0ca4ca3 (mode 644)
--- /dev/null
+++ assets/styles.css
@@ -0,0 +1,102 @@
+:root {
+	font-family: Inter, sans-serif;
+	font-feature-settings: 'liga' 1, 'calt' 1; /* fix for Chrome */
+}
+@supports (font-variation-settings: normal) {
+	:root { font-family: InterVariable, sans-serif; }
+}
+
+body {
+	margin: 0;
+	background-color: var(--color-background);
+}
+
+main {
+	display: flex;
+}
+
+.nav {
+	display: flex;
+	flex-direction: column;
+	width: var(--nav-width);
+	position: sticky;
+	top: 0;
+	align-self: flex-start;
+}
+
+.nav ul {
+	list-style-type: none;
+}
+
+.nav a {
+	color: var(--color-text-primary);
+}
+
+.nav a:hover {
+	background-color: var(--color-link-hover);
+}
+
+.titles {
+	color: var(--color-title);
+	text-decoration: none;
+	font-size: 60px;
+	margin: 0;
+}
+
+.article .titles {
+	margin-bottom: 0.5em;
+}
+
+.titles a:hover {
+	color: var(--color-accent);
+}
+
+.article a {
+	color: black;
+	background-color: var(--color-link-bg);
+}
+
+.article a:hover {
+	background-color: var(--color-link-hover);
+}
+
+.article blockquote {
+	border-left: 4px solid var(--color-blockquote-border);
+	padding-left: 1em;
+	margin-left: 0;
+}
+
+.content {
+	max-width: var(--content-max-width);
+	flex-grow: 1;
+}
+
+footer {
+	text-align: center;
+}
+
+.post-meta {
+	color: rgba(0, 0, 0, 0.4);
+}
+
+.post-meta a {
+	color: inherit;
+}
+
+@media (max-width: 800px) {
+	main {
+		flex-direction: column;
+	}
+
+	.nav {
+		width: 100%;
+		position: static;
+	}
+
+	.nav ul {
+		display: flex;
+		flex-direction: row;
+		justify-content: center;
+		margin: 10px;
+	}
+}
blob - /dev/null
blob + e5005e080e16610e553682809c6ab3415ec78678 (mode 644)
--- /dev/null
+++ exampleSite/README.md
@@ -0,0 +1,32 @@
+# Soul Theme Example Site
+
+This directory contains a minimal example site showing how to configure the Soul theme.
+
+## Running the Example
+
+From the theme root directory (`themes/soul/`):
+
+```bash
+hugo server --source=exampleSite --themesDir=../..
+```
+
+Or from this directory:
+
+```bash
+hugo server
+```
+
+## Configuration
+
+See `hugo.toml` for a complete configuration example showing all available parameters for the Soul theme.
+
+## Customization
+
+The Soul theme supports extensive customization through `hugo.toml` parameters:
+- Colors (background, accents, links, etc.)
+- Typography (font loading)
+- Layout (sidebar width, content width)
+- Navigation menu
+- Footer text
+
+Refer to the main [README.md](../README.md) for detailed documentation.
blob - /dev/null
blob + 65e7f1160c0dc6ea54fadedd02630a2805c5eb2d (mode 644)
--- /dev/null
+++ exampleSite/hugo.toml
@@ -0,0 +1,38 @@
+baseURL = 'https://example.com/'
+languageCode = 'en-us'
+title = 'Soul Theme Example'
+theme = 'soul'
+copyright = 'Your Name'
+enableRobotsTXT = true
+
+[params]
+  description = "Example site for the Soul Hugo theme"
+  author = "Your Name"
+  keywords = ["blog", "minimal", "example"]
+
+  [params.colors]
+    background = "#cdecff"
+    accent = "#ff6300"
+    linkBg = "#fbf1a9"
+    linkHover = "#ffffff"
+    textPrimary = "rgba(0, 0, 0, 0.60)"
+    titleColor = "#ffffff"
+    blockquoteBorder = "#ff6300"
+    themeColor = "#cdecffc"
+
+  [params.typography]
+    enableInterFont = true
+
+  [params.layout]
+    navWidth = "300px"
+    contentMaxWidth = "800px"
+
+  [[params.menu]]
+    name = "Blog"
+    url = "/blog"
+  [[params.menu]]
+    name = "About"
+    url = "/about"
+
+  [params.footer]
+    startYear = "2025"
blob - /dev/null
blob + bd3abe4a4797ca28db00d1ac932eeebe27019a89 (mode 644)
--- /dev/null
+++ layouts/404.html
@@ -0,0 +1,7 @@
+{{ define "main"}}
+<main>
+  <div>
+    <h1><a href="/">Go Home</a></h1>
+  </div>
+</main>
+{{ end }}
blob - /dev/null
blob + ae4ed611b2cf1710334b5347ed08b554e5789922 (mode 644)
--- /dev/null
+++ layouts/_default/baseof.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+
+	{{ partial "head.html" . }}
+
+	<body>
+
+		<main>
+
+			{{ partial "nav.html" . }}
+
+			<div class="content">
+
+				{{ partial "header.html" . }}
+
+				{{ block "main" . }}{{ end }}
+
+				{{ partial "footer.html" . }}
+
+			</div>
+
+		</main>
+
+	</body>
+
+</html>
blob - /dev/null
blob + f193e7a25cab0def5a677b057acbd7d1cd7d47af (mode 644)
--- /dev/null
+++ layouts/_default/list.html
@@ -0,0 +1,9 @@
+{{ define "main" }}
+<main>
+  <div>
+    {{ range .Pages }}
+      {{ .Render "summary" }}
+    {{ end }}
+  </div>
+</main>
+{{ end }}
blob - /dev/null
blob + 57f89a7feacba16b8ad3e80fa176a691a8b0c164 (mode 644)
--- /dev/null
+++ layouts/_default/single.html
@@ -0,0 +1,17 @@
+{{ define "main" }}
+	<article class="article">
+		<h1 class="titles">/{{ .Section }}/{{ .Title }}</h1>
+		<div class="post-meta">
+			{{ .Date.Format "15:04" }}, {{ .Date.Format "Monday" }} {{ .Date.Format "Jan 2nd 2006" }} <a href="{{ .Permalink }}">Link to this post</a>
+		</div>
+		{{ .Content }}
+		<div class="post-meta">
+			{{ .Date.Format "15:04" }}, {{ .Date.Format "Monday" }} {{ .Date.Format "Jan 2nd 2006" }} <a href="{{ .Permalink }}">Link to this post</a>
+		</div>
+	</article>
+
+	<section>
+		<h4>{{ .Date.Format "Mon Jan 2, 2006" }}</h4>
+		<h5>{{ .WordCount }} Words</h5>
+	</section>
+{{ end }}
blob - /dev/null
blob + d3e11824cc7273654342b3992319b4e972e48dff (mode 644)
--- /dev/null
+++ layouts/_default/summary.html
@@ -0,0 +1,9 @@
+<a href="{{ .Permalink }}">
+  <div>{{ .Title }}</div>
+  <div>
+    <span>{{ .ReadingTime }} Minutes</span>
+    <span>{{ .Date.Format "Jan 2, 2006" }}</span>
+    <span>{{ .WordCount }} Words</span>
+  </div>
+  <div>{{ .Summary }}</div>
+</a>
blob - /dev/null
blob + a2246be07e6db3000f974c5a8db8c443beb06783 (mode 644)
--- /dev/null
+++ layouts/index.html
@@ -0,0 +1,21 @@
+{{ define "main" }}
+	{{ $latestPost := first 1 .Site.RegularPages }}
+	{{ range $latestPost }}
+		<article class="article">
+			<h1 class="titles">{{ .Title }}</h1>
+			<div class="post-meta">
+				{{ .Date.Format "15:04" }}, {{ .Date.Format "Monday" }} {{ .Date.Format "Jan 2nd 2006" }} <a href="{{ .Permalink }}">Link to this post</a>
+			</div>
+			{{ .Content }}
+			<div class="post-meta">
+				{{ .Date.Format "15:04" }}, {{ .Date.Format "Monday" }} {{ .Date.Format "Jan 2nd 2006" }} <a href="{{ .Permalink }}">Link to this post</a>
+			</div>
+		</article>
+		<section>
+			<h4>{{ .Date.Format "Mon Jan 2, 2006" }}</h4>
+			<h5>{{ .WordCount }} Words</h5>
+		</section>
+	{{ else }}
+		<p>No posts found</p>
+	{{ end }}
+{{ end }}
blob - /dev/null
blob + c1d058390915f69cafd21aaaa75b853e3b249776 (mode 644)
--- /dev/null
+++ layouts/partials/footer.html
@@ -0,0 +1,3 @@
+<footer>
+	<p>Since {{ .Site.Params.footer.startYear | default "March 2025" }}. Copyright &copy; {{ now.Format "2006" }} {{ .Site.Copyright }}</p>
+</footer>
blob - /dev/null
blob + 95e25351049c4254bc7c8575b415566139d7f7b1 (mode 644)
--- /dev/null
+++ layouts/partials/head.html
@@ -0,0 +1,51 @@
+<head>
+
+	<!-- CSS Custom Properties from config -->
+	<style>
+	:root {
+		--color-background: {{ .Site.Params.colors.background | default "#cdecff" | safeCSS }};
+		--color-accent: {{ .Site.Params.colors.accent | default "#ff6300" | safeCSS }};
+		--color-link-bg: {{ .Site.Params.colors.linkBg | default "#fbf1a9" | safeCSS }};
+		--color-link-hover: {{ .Site.Params.colors.linkHover | default "#ffffff" | safeCSS }};
+		--color-text-primary: {{ .Site.Params.colors.textPrimary | default "rgba(0, 0, 0, 0.60)" | safeCSS }};
+		--color-title: {{ .Site.Params.colors.titleColor | default "#ffffff" | safeCSS }};
+		--color-blockquote-border: {{ .Site.Params.colors.blockquoteBorder | default "#ff6300" | safeCSS }};
+		--nav-width: {{ .Site.Params.layout.navWidth | default "300px" | safeCSS }};
+		--content-max-width: {{ .Site.Params.layout.contentMaxWidth | default "800px" | safeCSS }};
+	}
+	</style>
+
+	<!-- Conditional font loading -->
+	{{ if .Site.Params.typography.enableInterFont }}
+	<link rel="preconnect" href="https://rsms.me/">
+	<link rel="stylesheet" href="https://rsms.me/inter/inter.css">
+	{{ end }}
+
+	<!-- Main stylesheet -->
+	{{ $style := resources.Get "styles.css" | minify | fingerprint }}
+	<link rel="stylesheet" href="{{ $style.Permalink }}">
+
+	<meta charset="utf-8">
+	<meta name="keywords" content="{{ delimit .Site.Params.keywords ", " }}" />
+	<meta name="theme-color" content="{{ .Site.Params.colors.themeColor | default "#cdecffc" }}">
+	<meta property="og:site_name" content="{{ $.Site.Title }}" />
+
+	{{ if .IsPage }}
+		<title>{{ .Title }} | {{ $.Site.Title }}</title>
+		<meta property="og:type" content="article" />
+		<meta property="og:title" content="{{ .Title }}" />
+		<meta property="og:description" content="{{ .Summary }}" />
+		<meta name="description" content="{{ .Summary }}" />
+		<meta property="twitter:title" content="{{ .Title }}" />
+		<meta property="twitter:description" content="{{ .Summary }}" />
+		<meta property="article:author" content="{{ .Site.Params.author }}" />
+		<meta property="article:published_time" content="{{ .Date }}" />
+	{{ else }}
+		<title>{{ $.Site.Title }}</title>
+		<meta name="twitter:card" content="summary" />
+		<meta property="og:title" content="{{ $.Site.Title }}" />
+		<meta property="og:description" content="{{ .Site.Params.description }}" />
+		<meta name="description" content="{{ .Site.Params.description }}" />
+	{{ end }}
+
+</head>
blob - /dev/null
blob + 6df42832303a5170d8a59f2051d22a0aad67513a (mode 644)
--- /dev/null
+++ layouts/partials/header.html
@@ -0,0 +1,5 @@
+<header>
+    <h1 class="titles">
+        <a class="titles" href="/">{{ .Site.Title }}</a>
+    </h1>
+</header>
blob - /dev/null
blob + abdd5c23751e54619a1e27b2e54bf7b19a534187 (mode 644)
--- /dev/null
+++ layouts/partials/nav.html
@@ -0,0 +1,7 @@
+<nav class="nav">
+	<ul>
+		{{ range .Site.Params.menu }}
+			<li><a href="{{ .url }}">{{ .name }}</a></li>
+		{{ end }}
+	</ul>
+</nav>
blob - /dev/null
blob + e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 (mode 644)
blob - /dev/null
blob + fff4f3295378cba64d0b1ee68179c179821255ed (mode 644)
--- /dev/null
+++ theme.toml
@@ -0,0 +1,12 @@
+name = "Soul"
+license = "MIT"
+licenselink = "https://github.com/isaacmeerloo/soul/blob/main/LICENSE"
+description = "A minimal, typography-focused Hugo theme with sidebar navigation"
+homepage = "https://github.com/isaacmeerloo/soul"
+tags = ["blog", "minimal", "clean", "typography", "sidebar", "responsive"]
+features = ["responsive", "sidebar-nav", "typography-focused", "configurable"]
+min_version = "0.112.0"
+
+[author]
+  name = "Isaac Meerloo"
+  homepage = "https://36.church"