diff options
Diffstat (limited to 'site/themes/hugo-starter')
19 files changed, 545 insertions, 0 deletions
diff --git a/site/themes/hugo-starter/README.md b/site/themes/hugo-starter/README.md new file mode 100644 index 0000000..12cbe06 --- /dev/null +++ b/site/themes/hugo-starter/README.md @@ -0,0 +1,4 @@ +# Hugo starter +Note: this is a fork of https://github.com/ericmurphyxyz/hugo-starter-theme. + +This is a barebones theme template to get you up and running really fast. If you're interested in creating your own hugo theme, I wrote something about that [here.](https://dev.to/vinliao/create-your-own-hugo-theme-from-scratch-5df9) diff --git a/site/themes/hugo-starter/archetypes/default.md b/site/themes/hugo-starter/archetypes/default.md new file mode 100644 index 0000000..fdccff8 --- /dev/null +++ b/site/themes/hugo-starter/archetypes/default.md @@ -0,0 +1,4 @@ +--- +title: "{{ replace .Name "-" " " | title }}" +date: {{ .Date }} +--- diff --git a/site/themes/hugo-starter/config.toml b/site/themes/hugo-starter/config.toml new file mode 100644 index 0000000..cbc85dd --- /dev/null +++ b/site/themes/hugo-starter/config.toml @@ -0,0 +1,13 @@ +[params.background] + spacing = 24 # distance between dots + maxRadius = 10 # max dot radius + baseOffset = 120 # baseline from bottom + freq = 0.008 # wave frequency (lower = wider waves) + speed = 0.01 # wave speed (lower = slower movement) + + # envelope controls (controls variance) + baseAmp = 100 + envelope1Freq = 0.002 + envelope1Amp = 120 + envelope2Freq = 0.0005 + envelope2Amp = 200 diff --git a/site/themes/hugo-starter/config/_default/hugo.toml b/site/themes/hugo-starter/config/_default/hugo.toml new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/site/themes/hugo-starter/config/_default/hugo.toml diff --git a/site/themes/hugo-starter/exampleSite/config.toml b/site/themes/hugo-starter/exampleSite/config.toml new file mode 100644 index 0000000..ff46f8e --- /dev/null +++ b/site/themes/hugo-starter/exampleSite/config.toml @@ -0,0 +1,15 @@ +baseURL = "https://example.com" +title = "Hugo template" + +[menu] + [[menu.main]] + identifier = "posts" + name = "Posts" + url = "/posts" + weight = 10 + + [[menu.main]] + identifier = "about" + name = "About" + url = "/about" + weight = 20 diff --git a/site/themes/hugo-starter/layouts/404.html b/site/themes/hugo-starter/layouts/404.html new file mode 100644 index 0000000..12883f1 --- /dev/null +++ b/site/themes/hugo-starter/layouts/404.html @@ -0,0 +1,5 @@ +{{ define "main" }} +<h1>Page Not Found</h1> + +<p>Sorry, this page doesn't exist.</p> +{{ end }} diff --git a/site/themes/hugo-starter/layouts/_default/baseof.html b/site/themes/hugo-starter/layouts/_default/baseof.html new file mode 100644 index 0000000..89f10a8 --- /dev/null +++ b/site/themes/hugo-starter/layouts/_default/baseof.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<html data-theme="dark"> + <head> + {{- partial "head.html" . -}} + </head> + <body> + + <canvas id="background"></canvas> + + <div id="main"> + {{- partial "nav.html" . -}} + <div id="content"> + {{- block "main" . }}{{- end }} + <footer> + {{- partial "footer.html" . -}} + </footer> + </div> + </div> + + <!-- Background --> + <script id="background-config" type="application/json"> + {{ site.Params.background | jsonify | safeJS }} + </script> + <script src="{{ "/js/background.js" | relURL }}"></script> + + <!-- Theme Switcher --> + <script src="{{ "/js/switch-theme.js" | relURL }}"></script> + + <body> +</html> diff --git a/site/themes/hugo-starter/layouts/_default/list.html b/site/themes/hugo-starter/layouts/_default/list.html new file mode 100644 index 0000000..c51e7d6 --- /dev/null +++ b/site/themes/hugo-starter/layouts/_default/list.html @@ -0,0 +1,16 @@ +{{ define "main" }} +<h1>{{ .Title }}</h1> + +{{- .Content -}} + +{{ range.Data.Pages }} +<article class="post-snippet"> + <h3> + <a href="{{ .RelPermalink }}">{{ .Title }}</a> + </h3> + <time datetime="{{ .Date.Format "2006-01-02T15:04:05Z07:00" }}"> + {{ .Date.Format "January 2, 2006" }} + </time> +</article> +{{ end }} +{{ end }} diff --git a/site/themes/hugo-starter/layouts/_default/single.html b/site/themes/hugo-starter/layouts/_default/single.html new file mode 100644 index 0000000..3ba2777 --- /dev/null +++ b/site/themes/hugo-starter/layouts/_default/single.html @@ -0,0 +1,7 @@ +{{ define "main" }} + +<h1>{{ .Title }}</h1> + +{{- .Content -}} + +{{ end }} diff --git a/site/themes/hugo-starter/layouts/index.html b/site/themes/hugo-starter/layouts/index.html new file mode 100644 index 0000000..2acde8d --- /dev/null +++ b/site/themes/hugo-starter/layouts/index.html @@ -0,0 +1,4 @@ +{{ define "main" }} + {{- .Content -}} + <p>{{ .Site.Params.description }}</p> +{{ end }} diff --git a/site/themes/hugo-starter/layouts/partials/footer.html b/site/themes/hugo-starter/layouts/partials/footer.html new file mode 100644 index 0000000..24373ca --- /dev/null +++ b/site/themes/hugo-starter/layouts/partials/footer.html @@ -0,0 +1 @@ +<p>©{{ dateFormat "2006" now }} {{ .Site.Title }}</p> diff --git a/site/themes/hugo-starter/layouts/partials/head.html b/site/themes/hugo-starter/layouts/partials/head.html new file mode 100644 index 0000000..e7c23e5 --- /dev/null +++ b/site/themes/hugo-starter/layouts/partials/head.html @@ -0,0 +1,36 @@ +<meta charset="UTF-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1.0" /> + +<title>{{ if not .IsHome }}{{ .Title }} | {{ end }}{{ .Site.Title }}</title> + +<!-- Scuffed fix for theme change flash --> +<script> + // Run as early as possible + (function() { + const theme = localStorage.getItem("theme"); + const preloadClass = theme === "dark" ? "preload-dark" : "preload-light"; + + // Add preload class to <html> + document.documentElement.classList.add(preloadClass); + + // Wait for stylesheet(s) to load, then remove class + window.addEventListener("load", function() { + document.documentElement.classList.remove(preloadClass); + }); + })(); +</script> +<style> + /* Temporary background colors before stylesheet is fully loaded */ + .preload-light * { + background: #ffffff !important; + } + .preload-dark * { + background: #161616 !important; + } +</style> + +<link rel="stylesheet" href="/css/style.css" type="text/css" media="all" /> + +{{ with .OutputFormats.Get "rss" -}} + {{ printf `<link rel="%s" type="%s" href="%s" title="%s" />` .Rel .MediaType.Type .Permalink $.Site.Title | safeHTML }} +{{ end -}} diff --git a/site/themes/hugo-starter/layouts/partials/header.html b/site/themes/hugo-starter/layouts/partials/header.html new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/site/themes/hugo-starter/layouts/partials/header.html diff --git a/site/themes/hugo-starter/layouts/partials/nav.html b/site/themes/hugo-starter/layouts/partials/nav.html new file mode 100644 index 0000000..cef3405 --- /dev/null +++ b/site/themes/hugo-starter/layouts/partials/nav.html @@ -0,0 +1,17 @@ +<header class="site-header"> + <nav class="navbar"> + <div> + <a class="logo" href="{{ .Site.BaseURL }}"> + {{ .Site.Title }} + </a> + <button type="button" id="toggleTheme" data-theme-toggle aria-label="switch theme"></button> + </div> + <ul class="nav-links"> + {{ range.Site.Menus.main }} + <li> + <a href="{{ .URL }}">{{ .Name }}</a> + </li> + {{ end }} + </ul> + </nav> +</header> diff --git a/site/themes/hugo-starter/static/css/style.css b/site/themes/hugo-starter/static/css/style.css new file mode 100644 index 0000000..f88f30b --- /dev/null +++ b/site/themes/hugo-starter/static/css/style.css @@ -0,0 +1,179 @@ +/* COLORS */ +@import url('themes/oxocarbon-light.css'); +@import url('themes/oxocarbon-dark.css'); + +#toggleTheme { + font-family: "kirsch"; + font-size: 2rem; + color: var(--fg); + border: none; + background: none; + cursor: pointer; + position: relative; + top: 2px; + margin: -4px; +} + +/* FONT */ + +@font-face { + font-family: "kirsch"; + src: + local("kirsch"), + url("https://cdn.jsdelivr.net/npm/kirsch@latest/out/kirsch.woff2") format("woff2"), + url("https://cdn.jsdelivr.net/npm/kirsch@latest/out/kirsch.ttf") format("truetype"); + font-display: block; +} + +/* LAYOUT */ + +body { + color: var(--fg); + background-color: transparent; + font-size: 175%; + line-height: 1.2; + max-width: 45rem; + padding: 1rem; + margin: 0 auto; + font-family: "kirsch"; + font-display: block; +} + +#main { + margin: 2% auto; + display: flex; + flex-direction: column; + justify-content: center; +} + +#content { + border-style: solid; + border-color: var(--fg); + background-color: var(--bg); + + padding: 3% 5%; + overflow: auto; +} + +/* NAVIGATION */ + +.navbar { + background-color: var(--bg); + border-style: dashed; + border-color: var(--fg); + + font-size: 110%; + + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + max-width: 1200px; + margin: 0 auto; + padding: 10px 20px; + box-sizing: border-box; + + margin-bottom: 2%; +} + +.logo { + flex-shrink: 0; + /* margin: 0 0%; */ +} + +.nav-links { + list-style-type: none; + display: flex; + gap: 20px; + flex-shrink: 0; + /* overflow-x: auto; */ + overflow: visible; + margin: 0; + padding: 0; +} + +.navbar a { + display: inline-block; + white-space: nowrap; + flex-shrink: 0; + + color: var(--fg); + font-weight: bold; + text-decoration: none; +} + +@media (max-width: 768px) { + .nav-links { + gap: 10px; + } +} + +@media (max-width: 480px) { + .nav-links a { + font-size: 14px; + } +} +.main-menu { + display: flex; + list-style: none; + margin: 0; + padding: 0; +} + +@media screen and (max-width: 48rem) { + .site-nav, + .main-menu { + flex-direction: column; + } + + .site-nav a { + padding: 0.5rem; + padding-left: 0; + } +} + +/* Canvas Background */ +#background { + position: fixed; + inset: 0; /* stretch full screen */ + z-index: -1; /* behind content */ + pointer-events: none; /* don’t block clicks */ + display: block; /* remove inline-gap issues */ + + background-color: var(--bg); +} + +/* SINGLES */ +#content * { + margin: 14px 0; +} + +#content h1 { + margin: 0; + text-align: center; +} + +#content ul { + list-style-type: square; +} + +#content li { + margin: 0; +} + +#content a { + color: var(--base0B); +} + +#content a:visited { + color: var(--base0E); +} + +#content footer { + margin-bottom: 0; + text-align: center; +} + +#content footer p { + margin-bottom: 0; +} diff --git a/site/themes/hugo-starter/static/css/themes/oxocarbon-dark.css b/site/themes/hugo-starter/static/css/themes/oxocarbon-dark.css new file mode 100644 index 0000000..3283009 --- /dev/null +++ b/site/themes/hugo-starter/static/css/themes/oxocarbon-dark.css @@ -0,0 +1,22 @@ +/* COLORS */ +[data-theme="dark"] { + --base00: #161616; + --base01: #262626; + --base02: #393939; + --base03: #525252; + --base04: #dde1e6; + --base05: #f2f4f8; + --base06: #ffffff; + --base07: #08bdba; + --base08: #3ddbd9; + --base09: #78a9ff; + --base0A: #ee5396; + --base0B: #33b1ff; + --base0C: #ff7eb6; + --base0D: #42be65; + --base0E: #be95ff; + --base0F: #82cfff; + + --fg: var(--base06); + --bg: var(--base00); +} diff --git a/site/themes/hugo-starter/static/css/themes/oxocarbon-light.css b/site/themes/hugo-starter/static/css/themes/oxocarbon-light.css new file mode 100644 index 0000000..7cd48ee --- /dev/null +++ b/site/themes/hugo-starter/static/css/themes/oxocarbon-light.css @@ -0,0 +1,22 @@ +/* COLORS */ +[data-theme="light"] { + --base00: #ffffff; + --base01: #f2f2f2; + --base02: #d0d0d0; + --base03: #161616; + --base04: #37474f; + --base05: #90a4ae; + --base06: #525252; + --base07: #08bdba; + --base08: #ff7eb6; + --base09: #ee5396; + --base0A: #FF6F00; + --base0B: #0f62fe; + --base0C: #673ab7; + --base0D: #42be65; + --base0E: #be95ff; + --base0F: #ffab91; + + --fg: var(--base03); + --bg: var(--base00); +} diff --git a/site/themes/hugo-starter/static/js/background.js b/site/themes/hugo-starter/static/js/background.js new file mode 100644 index 0000000..e9b61a2 --- /dev/null +++ b/site/themes/hugo-starter/static/js/background.js @@ -0,0 +1,82 @@ +document.addEventListener("DOMContentLoaded", () => { + const canvas = document.getElementById("background"); + if (!canvas) return; + const ctx = canvas.getContext("2d"); + + // Grab config from the embedded <script> + const configEl = document.getElementById("background-config"); + const config = configEl ? JSON.parse(configEl.textContent) : {}; + + // Use config values with defaults as fallback + const spacing = config.spacing ?? 24; + const maxRadius = config.maxRadius ?? 8; + const baseOffset = config.baseOffset ?? 120; + const freq = config.freq ?? 0.008; + const speed = config.speed ?? 0.02; + + const baseAmp = config.baseAmp ?? 100; + const env1Freq = config.envelope1Freq ?? 0.002; + const env1Amp = config.envelope1Amp ?? 120; + const env2Freq = config.envelope2Freq ?? 0.0005; + const env2Amp = config.envelope2Amp ?? 200; + + let t = parseFloat(localStorage.getItem("waveProgress")) || 0; + let widthCss = window.innerWidth; + let heightCss = window.innerHeight; + let pixelRatio = window.devicePixelRatio || 1; + + function resize() { + widthCss = window.innerWidth; + heightCss = window.innerHeight; + pixelRatio = window.devicePixelRatio || 1; + + canvas.width = Math.floor(widthCss * pixelRatio); + canvas.height = Math.floor(heightCss * pixelRatio); + canvas.style.width = widthCss + "px"; + canvas.style.height = heightCss + "px"; + ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0); + } + window.addEventListener("resize", resize); + resize(); + + function draw() { + const styles = getComputedStyle(document.documentElement); + const fg = styles.getPropertyValue("--fg").trim(); + + ctx.clearRect(0, 0, widthCss, heightCss); + ctx.fillStyle = fg; + + for (let x = 0; x <= widthCss + spacing; x += spacing) { + // envelope: controls crest variance + const envelope = + baseAmp + + Math.sin(x * env1Freq + t * 0.1) * env1Amp + + Math.sin(x * env2Freq + t * 0.05) * env2Amp; + + const waveY = heightCss - (Math.sin(x * freq + t) * envelope + baseOffset); + // const waveY = Math.max(heightCss - 50, heightCss - (Math.sin(x * freq + t) * envelope + baseOffset)); + + for (let y = heightCss; y >= 0; y -= spacing) { + const dist = Math.max(0, y - waveY); + const radius = Math.min(maxRadius, dist / 40); + if (radius > 0.2) { + ctx.beginPath(); + // ctx.arc(x + spacing / 2, y - spacing / 2, radius, 0, Math.PI * 2); + ctx.fillRect( + x + spacing / 2 - radius, + y - spacing / 2 - radius, + radius * 2, + radius * 2 + ); + ctx.fill(); + } + } + } + + t += speed; + localStorage.setItem("waveProgress", t); + requestAnimationFrame(draw); + } + + draw(); +}); diff --git a/site/themes/hugo-starter/static/js/switch-theme.js b/site/themes/hugo-starter/static/js/switch-theme.js new file mode 100644 index 0000000..5052f39 --- /dev/null +++ b/site/themes/hugo-starter/static/js/switch-theme.js @@ -0,0 +1,88 @@ +// const root = document.documentElement; // <html>, not <body> +// const btn = document.getElementById("toggleTheme"); +// +// const savedTheme = localStorage.getItem("theme") || "light"; +// root.className = savedTheme; +// btn.innerHTML = savedTheme === "dark" ? "✧" : "☾"; +// +// btn.addEventListener("click", () => { +// const newTheme = root.classList.contains("light") ? "dark" : "light"; +// root.className = newTheme; +// localStorage.setItem("theme", newTheme); +// btn.innerHTML = newTheme === "dark" ? "✧" : "☾"; +// }); + +/** +* Utility function to calculate the current theme setting. +* Look for a local storage value. +* Fall back to system setting. +* Fall back to light mode. +*/ +function calculateSettingAsThemeString({ localStorageTheme, systemSettingDark }) { + if (localStorageTheme !== null) { + return localStorageTheme; + } + + if (systemSettingDark.matches) { + return "dark"; + } + + return "light"; +} + +/** +* Utility function to update the button text and aria-label. +*/ +function updateButton({ buttonEl, isDark }) { + const newCta = isDark ? "Change to light theme" : "Change to dark theme"; + + const newInnerText = isDark ? "✧" : "☾"; + // use an aria-label if you are omitting text on the button + // and using a sun/moon icon, for example + buttonEl.setAttribute("aria-label", newCta); + buttonEl.innerText = newInnerText; +} + +/** +* Utility function to update the theme setting on the html tag +*/ +function updateThemeOnHtmlEl({ theme }) { + document.querySelector("html").setAttribute("data-theme", theme); +} + + +/** +* On page load: +*/ + +/** +* 1. Grab what we need from the DOM and system settings on page load +*/ +const button = document.querySelector("[data-theme-toggle]"); +const localStorageTheme = localStorage.getItem("theme"); +const systemSettingDark = window.matchMedia("(prefers-color-scheme: dark)"); + +/** +* 2. Work out the current site settings +*/ +let currentThemeSetting = calculateSettingAsThemeString({ localStorageTheme, systemSettingDark }); + +/** +* 3. Update the theme setting and button text accoridng to current settings +*/ +updateButton({ buttonEl: button, isDark: currentThemeSetting === "dark" }); +updateThemeOnHtmlEl({ theme: currentThemeSetting }); + +/** +* 4. Add an event listener to toggle the theme +*/ +button.addEventListener("click", (event) => { + const newTheme = currentThemeSetting === "dark" ? "light" : "dark"; + + localStorage.setItem("theme", newTheme); + updateButton({ buttonEl: button, isDark: newTheme === "dark" }); + updateThemeOnHtmlEl({ theme: newTheme }); + + currentThemeSetting = newTheme; +}); + |
