Harbor

Changelog f2a9c4d26a8d

adopt current workspace

@sky · 1 month ago
96 added 0 modified 0 deleted
.harbor +2 -0 added
1 + [workspace]
2 + name = "website"
DESIGN.md +3 -0 added
1 + # Design notes
2 +
3 + 1. No eyebrows.
build.php +151 -0 added
1 + #!/usr/bin/env php
2 + <?php
3 +
4 + declare(strict_types=1);
5 +
6 + require __DIR__ . '/src/helpers.php';
7 +
8 + if (in_array('--help', $argv, true) || in_array('-h', $argv, true)) {
9 + echo "Usage: php build.php\n";
10 + echo "Builds static HTML from src/ into public/ with no external dependencies.\n";
11 + exit(0);
12 + }
13 +
14 + $root = __DIR__;
15 + $sourceRoot = $root . '/src';
16 + $outputRoot = $root . '/public';
17 +
18 + $site = require $sourceRoot . '/site.php';
19 + $pages = [];
20 +
21 + foreach (glob($sourceRoot . '/pages/*.php') ?: [] as $pageFile) {
22 + $page = require $pageFile;
23 + if (!is_array($page)) {
24 + throw new RuntimeException("Page file {$pageFile} must return an array.");
25 + }
26 +
27 + $pages[] = $page;
28 + }
29 +
30 + foreach ($site['projects'] as $index => $project) {
31 + $pages[] = [
32 + 'key' => $project['route'],
33 + 'output' => $project['output'],
34 + 'title' => $project['title'] . ' | Sharkk',
35 + 'description' => $project['summary'],
36 + 'template' => 'project',
37 + 'order' => 100 + $index,
38 + 'project' => $project,
39 + 'slider' => [
40 + 'class' => 'work-header',
41 + ],
42 + ];
43 + }
44 +
45 + foreach ($site['blogPosts'] as $index => $post) {
46 + $pages[] = [
47 + 'key' => $post['route'],
48 + 'output' => $post['output'],
49 + 'title' => $post['title'] . ' | Sharkk',
50 + 'description' => $post['description'],
51 + 'template' => 'blog-post',
52 + 'order' => 200 + $index,
53 + 'post' => $post,
54 + ];
55 + }
56 +
57 + $routes = [];
58 + $outputs = [];
59 +
60 + foreach ($pages as $page) {
61 + foreach (['key', 'output', 'title', 'template'] as $field) {
62 + if (!isset($page[$field]) || $page[$field] === '') {
63 + throw new RuntimeException("Every page must define a non-empty {$field} field.");
64 + }
65 + }
66 +
67 + if (isset($routes[$page['key']])) {
68 + throw new RuntimeException("Duplicate route key: {$page['key']}");
69 + }
70 +
71 + $output = normalize_site_path($page['output']);
72 + if (isset($outputs[$output])) {
73 + throw new RuntimeException("Duplicate output path: {$output}");
74 + }
75 +
76 + $page['output'] = $output;
77 + $routes[$page['key']] = $page;
78 + $outputs[$output] = true;
79 + }
80 +
81 + usort($pages, static fn (array $a, array $b): int => ($a['order'] ?? 999) <=> ($b['order'] ?? 999));
82 +
83 + $renderedPages = [];
84 +
85 + foreach ($pages as $page) {
86 + $currentOutput = $page['output'];
87 + $link = static function (string $routeKey) use ($routes, $currentOutput): string {
88 + if (!isset($routes[$routeKey])) {
89 + throw new RuntimeException("Unknown route key: {$routeKey}");
90 + }
91 +
92 + return relative_url($currentOutput, $routes[$routeKey]['output']);
93 + };
94 + $asset = static fn (string $path): string => relative_url($currentOutput, normalize_site_path($path));
95 +
96 + $renderPartial = null;
97 + $shared = [
98 + 'site' => $site,
99 + 'page' => $page,
100 + 'routes' => $routes,
101 + 'link' => $link,
102 + 'asset' => $asset,
103 + ];
104 +
105 + $renderPartial = static function (string $name, array $vars = []) use ($sourceRoot, $shared, &$renderPartial): string {
106 + return render_template(
107 + $sourceRoot . '/templates/partials/' . normalize_site_path($name) . '.php',
108 + array_merge($shared, $vars, ['renderPartial' => $renderPartial])
109 + );
110 + };
111 +
112 + $bodyHtml = $renderPartial($page['template']);
113 + $html = render_template($sourceRoot . '/templates/layout.php', array_merge($shared, [
114 + 'bodyHtml' => $bodyHtml,
115 + 'renderPartial' => $renderPartial,
116 + ]));
117 +
118 + $renderedPages[] = [
119 + 'page' => $page,
120 + 'html' => $html,
121 + ];
122 + }
123 +
124 + foreach ($renderedPages as $renderedPage) {
125 + $outputPath = join_site_path($outputRoot, $renderedPage['page']['output']);
126 + $outputDir = dirname($outputPath);
127 +
128 + if (!is_dir($outputDir) && !mkdir($outputDir, 0777, true) && !is_dir($outputDir)) {
129 + throw new RuntimeException("Unable to create output directory: {$outputDir}");
130 + }
131 +
132 + if (file_put_contents($outputPath, $renderedPage['html']) === false) {
133 + throw new RuntimeException("Unable to write output file: {$outputPath}");
134 + }
135 + }
136 +
137 + $blogIndexPath = join_site_path($outputRoot, 'blog/search-index.json');
138 + $encodedBlogIndex = json_payload(blog_search_index($site['blogPosts']), true);
139 +
140 + if (file_put_contents($blogIndexPath, $encodedBlogIndex . "\n") === false) {
141 + throw new RuntimeException("Unable to write blog search index: {$blogIndexPath}");
142 + }
143 +
144 + foreach ($renderedPages as $renderedPage) {
145 + validate_local_references($outputRoot, $renderedPage['page']['output'], $renderedPage['html']);
146 + }
147 +
148 + echo 'Built ' . count($renderedPages) . " pages into public/:\n";
149 + foreach ($renderedPages as $renderedPage) {
150 + echo ' - ' . $renderedPage['page']['output'] . "\n";
151 + }
public/.DS_Store added

Binary file diff is not shown.

public/about/index.html +69 -0 added
1 + <!DOCTYPE html>
2 + <html lang="en">
3 + <head>
4 + <meta charset="UTF-8">
5 + <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 + <meta name="description" content="Sharkk is a demo home for fantasy work, design experiments, and whatever strange treasure washes in next.">
7 + <title>About | Sharkk</title>
8 + <link rel="stylesheet" href="../css/fonts.css">
9 + <link rel="stylesheet" href="../css/tokens.css">
10 + <link rel="stylesheet" href="../css/style.css">
11 + </head>
12 + <body>
13 + <div class="container">
14 + <header id="main">
15 + <a id="logo-link" href="../index.html" aria-label="Sharkk home"></a>
16 + <div class="content">
17 + <nav>
18 + <div class="nav-item">
19 + <a href="../work/index.html">
20 + Work <svg class="nav-chevron" viewBox="0 0 42 42" aria-hidden="true" focusable="false">
21 + <path d="M20.833,41.574l-20.674,-20.674l-0.159,-20.9l20.88,20.88l20.879,-20.88l-0.159,20.9l-20.674,20.674l-0,0.093l-0.046,-0.047l-0.047,0.047l0,-0.093Z" />
22 + </svg>
23 + </a>
24 + <div class="nav-dropdown work-list">
25 + <div class="link-list current-work">
26 + <a href="../work/project-1/index.html">Anashti Sul</a>
27 + <a href="../work/planes-of-power/index.html">Planes of Power</a>
28 + <a href="../work/ashbringer/index.html">Ashbringer</a>
29 + </div>
30 + <div class="link-list old-work">
31 + <a href="../work/mad-splash/index.html">Mad Splash</a>
32 + <a href="../work/battles-for-arthos/index.html">Battles for Arthos</a>
33 + <a href="../work/legendarium/index.html">Legendarium</a>
34 + </div>
35 + </div>
36 + </div>
37 + <div class="nav-item">
38 + <a href="../blog/index.html">
39 + Blog </a>
40 + </div>
41 + <div class="nav-item">
42 + <a href="index.html">
43 + About </a>
44 + </div>
45 + </nav>
46 + </div>
47 + </header>
48 + </div>
49 + <div class="container">
50 + <main class="page">
51 + <h1>Built near the breakers</h1>
52 + <p class="copy">Sharkk is a demo home for fantasy work, design experiments, and whatever strange treasure washes in next.</p>
53 + </main>
54 + <footer class="footer">
55 + <div class="brand">
56 + <img src="../img/sharkmark.svg" alt="" aria-hidden="true">
57 + <p>&copy; 2026 Sharkk. No wipeouts, just waves.</p>
58 + </div>
59 + <nav class="links">
60 + <a href="../privacy/index.html">Privacy</a>
61 + <a href="../legal/index.html">Legal</a>
62 + </nav>
63 + </footer>
64 + </div>
65 + <script src="../js/nav-dropdown.js"></script>
66 + <script src="../js/blog-index.js"></script>
67 + <script src="../js/markdown-editor.js"></script>
68 + </body>
69 + </html>
public/blog/arcade-chaos-with-lore-barnacles/index.html +165 -0 added
1 + <!DOCTYPE html>
2 + <html lang="en">
3 + <head>
4 + <meta charset="UTF-8">
5 + <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 + <meta name="description" content="Why even a fast, silly water-racer deserves factions, rumors, and one extremely suspicious trophy.">
7 + <title>Arcade Chaos With Lore Barnacles | Sharkk</title>
8 + <link rel="stylesheet" href="../../css/fonts.css">
9 + <link rel="stylesheet" href="../../css/tokens.css">
10 + <link rel="stylesheet" href="../../css/style.css">
11 + </head>
12 + <body>
13 + <div class="container">
14 + <header id="main">
15 + <a id="logo-link" href="../../index.html" aria-label="Sharkk home"></a>
16 + <div class="content">
17 + <nav>
18 + <div class="nav-item">
19 + <a href="../../work/index.html">
20 + Work <svg class="nav-chevron" viewBox="0 0 42 42" aria-hidden="true" focusable="false">
21 + <path d="M20.833,41.574l-20.674,-20.674l-0.159,-20.9l20.88,20.88l20.879,-20.88l-0.159,20.9l-20.674,20.674l-0,0.093l-0.046,-0.047l-0.047,0.047l0,-0.093Z" />
22 + </svg>
23 + </a>
24 + <div class="nav-dropdown work-list">
25 + <div class="link-list current-work">
26 + <a href="../../work/project-1/index.html">Anashti Sul</a>
27 + <a href="../../work/planes-of-power/index.html">Planes of Power</a>
28 + <a href="../../work/ashbringer/index.html">Ashbringer</a>
29 + </div>
30 + <div class="link-list old-work">
31 + <a href="../../work/mad-splash/index.html">Mad Splash</a>
32 + <a href="../../work/battles-for-arthos/index.html">Battles for Arthos</a>
33 + <a href="../../work/legendarium/index.html">Legendarium</a>
34 + </div>
35 + </div>
36 + </div>
37 + <div class="nav-item">
38 + <a href="../index.html">
39 + Blog </a>
40 + </div>
41 + <div class="nav-item">
42 + <a href="../../about/index.html">
43 + About </a>
44 + </div>
45 + </nav>
46 + </div>
47 + </header>
48 + </div>
49 + <div class="container">
50 + <main class="page blog-post-page">
51 + <article class="blog-post">
52 + <div class="cover-card">
53 + <img class="cover" src="../../img/slides/test3.jpg" alt="">
54 + </div>
55 + <header class="post-header">
56 + <h1>Arcade Chaos With Lore Barnacles</h1>
57 + </header>
58 + <div class="content">
59 + <time datetime="2026-05-11">May 11, 2026</time>
60 + <p class="copy">Why even a fast, silly water-racer deserves factions, rumors, and one extremely suspicious trophy.</p>
61 + <p>Mad Splash wants to move fast, but fast does not have to mean empty. The best arcade nonsense still leaves room for myths in the margins.</p>
62 + <p>Give players a reason to laugh first, then give them just enough lore to wonder who built the impossible shortcut through the storm wall.</p>
63 + <a class="read-more" href="../index.html">Back to Blog</a>
64 + </div>
65 + <section class="comments" aria-label="Comments">
66 + <h2>Comments</h2>
67 + <div class="comment-thread">
68 + <article class="comment">
69 + <div class="avatar" style="--avatar-color: #12AEF5">MR</div>
70 + <div class="bubble">
71 + <header>
72 + <div class="comment-meta">
73 + <strong>Mara</strong>
74 + <span>2 hours ago</span>
75 + </div>
76 + <div class="comment-votes" aria-label="Comment votes">
77 + <button class="vote-up" type="button" aria-label="Upvote Mara's comment">
78 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
79 + <path d="M7 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h3v12Zm2 0V10.6l5.4-7.4c.5-.7 1.5-.9 2.2-.4.6.4.9 1.1.7 1.8L16 10h4.2c1.2 0 2.1 1 1.9 2.2l-1.2 7.2A3 3 0 0 1 18 22H9Z" />
80 + </svg>
81 + </button>
82 + <span>12</span>
83 + <button class="vote-down" type="button" aria-label="Downvote Mara's comment">
84 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
85 + <path d="M7 2H4a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h3V2Zm2 0v11.4l5.4 7.4c.5.7 1.5.9 2.2.4.6-.4.9-1.1.7-1.8L16 14h4.2c1.2 0 2.1-1 1.9-2.2l-1.2-7.2A3 3 0 0 0 18 2H9Z" />
86 + </svg>
87 + </button>
88 + </div>
89 + </header>
90 + <p>This has exactly the right haunted-coast energy. I can already hear the dock bells getting weird.</p>
91 + </div>
92 + </article>
93 + <article class="comment is-right">
94 + <div class="avatar" style="--avatar-color: #7c5cff">JT</div>
95 + <div class="bubble">
96 + <header>
97 + <div class="comment-meta">
98 + <strong>Jett</strong>
99 + <span>1 hour ago</span>
100 + </div>
101 + <div class="comment-votes" aria-label="Comment votes">
102 + <button class="vote-up" type="button" aria-label="Upvote Jett's comment">
103 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
104 + <path d="M7 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h3v12Zm2 0V10.6l5.4-7.4c.5-.7 1.5-.9 2.2-.4.6.4.9 1.1.7 1.8L16 10h4.2c1.2 0 2.1 1 1.9 2.2l-1.2 7.2A3 3 0 0 1 18 22H9Z" />
105 + </svg>
106 + </button>
107 + <span>7</span>
108 + <button class="vote-down" type="button" aria-label="Downvote Jett's comment">
109 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
110 + <path d="M7 2H4a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h3V2Zm2 0v11.4l5.4 7.4c.5.7 1.5.9 2.2.4.6-.4.9-1.1.7-1.8L16 14h4.2c1.2 0 2.1-1 1.9-2.2l-1.2-7.2A3 3 0 0 0 18 2H9Z" />
111 + </svg>
112 + </button>
113 + </div>
114 + </header>
115 + <p>The lore barnacles are load-bearing. Please do not scrape them off.</p>
116 + </div>
117 + </article>
118 + <article class="comment">
119 + <div class="avatar" style="--avatar-color: #ff5c9a">NX</div>
120 + <div class="bubble">
121 + <header>
122 + <div class="comment-meta">
123 + <strong>Nix</strong>
124 + <span>33 minutes ago</span>
125 + </div>
126 + <div class="comment-votes" aria-label="Comment votes">
127 + <button class="vote-up" type="button" aria-label="Upvote Nix's comment">
128 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
129 + <path d="M7 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h3v12Zm2 0V10.6l5.4-7.4c.5-.7 1.5-.9 2.2-.4.6.4.9 1.1.7 1.8L16 10h4.2c1.2 0 2.1 1 1.9 2.2l-1.2 7.2A3 3 0 0 1 18 22H9Z" />
130 + </svg>
131 + </button>
132 + <span>3</span>
133 + <button class="vote-down" type="button" aria-label="Downvote Nix's comment">
134 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
135 + <path d="M7 2H4a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h3V2Zm2 0v11.4l5.4 7.4c.5.7 1.5.9 2.2.4.6-.4.9-1.1.7-1.8L16 14h4.2c1.2 0 2.1-1 1.9-2.2l-1.2-7.2A3 3 0 0 0 18 2H9Z" />
136 + </svg>
137 + </button>
138 + </div>
139 + </header>
140 + <p>I want a whole post about the shrine etiquette. What happens if someone brings the wrong fish?</p>
141 + </div>
142 + </article>
143 + </div>
144 + </section>
145 + <section class="markdown-editor" aria-label="Write a comment" data-markdown-editor>
146 + <textarea data-markdown-input rows="1" aria-label="Write a comment" placeholder="Write a Markdown comment: **bold**, *italic*, `code`, # heading, - list, > quote"></textarea>
147 + </section>
148 + </article>
149 + </main>
150 + <footer class="footer">
151 + <div class="brand">
152 + <img src="../../img/sharkmark.svg" alt="" aria-hidden="true">
153 + <p>&copy; 2026 Sharkk. No wipeouts, just waves.</p>
154 + </div>
155 + <nav class="links">
156 + <a href="../../privacy/index.html">Privacy</a>
157 + <a href="../../legal/index.html">Legal</a>
158 + </nav>
159 + </footer>
160 + </div>
161 + <script src="../../js/nav-dropdown.js"></script>
162 + <script src="../../js/blog-index.js"></script>
163 + <script src="../../js/markdown-editor.js"></script>
164 + </body>
165 + </html>
public/blog/building-demo-pages-that-breathe/index.html +165 -0 added
1 + <!DOCTYPE html>
2 + <html lang="en">
3 + <head>
4 + <meta charset="UTF-8">
5 + <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 + <meta name="description" content="Notes on keeping a concept site lightweight while still giving each project room to feel alive.">
7 + <title>Building Demo Pages That Breathe | Sharkk</title>
8 + <link rel="stylesheet" href="../../css/fonts.css">
9 + <link rel="stylesheet" href="../../css/tokens.css">
10 + <link rel="stylesheet" href="../../css/style.css">
11 + </head>
12 + <body>
13 + <div class="container">
14 + <header id="main">
15 + <a id="logo-link" href="../../index.html" aria-label="Sharkk home"></a>
16 + <div class="content">
17 + <nav>
18 + <div class="nav-item">
19 + <a href="../../work/index.html">
20 + Work <svg class="nav-chevron" viewBox="0 0 42 42" aria-hidden="true" focusable="false">
21 + <path d="M20.833,41.574l-20.674,-20.674l-0.159,-20.9l20.88,20.88l20.879,-20.88l-0.159,20.9l-20.674,20.674l-0,0.093l-0.046,-0.047l-0.047,0.047l0,-0.093Z" />
22 + </svg>
23 + </a>
24 + <div class="nav-dropdown work-list">
25 + <div class="link-list current-work">
26 + <a href="../../work/project-1/index.html">Anashti Sul</a>
27 + <a href="../../work/planes-of-power/index.html">Planes of Power</a>
28 + <a href="../../work/ashbringer/index.html">Ashbringer</a>
29 + </div>
30 + <div class="link-list old-work">
31 + <a href="../../work/mad-splash/index.html">Mad Splash</a>
32 + <a href="../../work/battles-for-arthos/index.html">Battles for Arthos</a>
33 + <a href="../../work/legendarium/index.html">Legendarium</a>
34 + </div>
35 + </div>
36 + </div>
37 + <div class="nav-item">
38 + <a href="../index.html">
39 + Blog </a>
40 + </div>
41 + <div class="nav-item">
42 + <a href="../../about/index.html">
43 + About </a>
44 + </div>
45 + </nav>
46 + </div>
47 + </header>
48 + </div>
49 + <div class="container">
50 + <main class="page blog-post-page">
51 + <article class="blog-post">
52 + <div class="cover-card">
53 + <img class="cover" src="../../img/slides/test4.jpg" alt="">
54 + </div>
55 + <header class="post-header">
56 + <h1>Building Demo Pages That Breathe</h1>
57 + </header>
58 + <div class="content">
59 + <time datetime="2026-04-28">April 28, 2026</time>
60 + <p class="copy">Notes on keeping a concept site lightweight while still giving each project room to feel alive.</p>
61 + <p>The demo site is intentionally small, but the pieces need to feel expandable: reusable chunks, real links, and enough structure to grow without a rewrite.</p>
62 + <p>That means every fake post, project card, and footer link should behave like it already belongs to a larger site.</p>
63 + <a class="read-more" href="../index.html">Back to Blog</a>
64 + </div>
65 + <section class="comments" aria-label="Comments">
66 + <h2>Comments</h2>
67 + <div class="comment-thread">
68 + <article class="comment">
69 + <div class="avatar" style="--avatar-color: #12AEF5">MR</div>
70 + <div class="bubble">
71 + <header>
72 + <div class="comment-meta">
73 + <strong>Mara</strong>
74 + <span>2 hours ago</span>
75 + </div>
76 + <div class="comment-votes" aria-label="Comment votes">
77 + <button class="vote-up" type="button" aria-label="Upvote Mara's comment">
78 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
79 + <path d="M7 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h3v12Zm2 0V10.6l5.4-7.4c.5-.7 1.5-.9 2.2-.4.6.4.9 1.1.7 1.8L16 10h4.2c1.2 0 2.1 1 1.9 2.2l-1.2 7.2A3 3 0 0 1 18 22H9Z" />
80 + </svg>
81 + </button>
82 + <span>12</span>
83 + <button class="vote-down" type="button" aria-label="Downvote Mara's comment">
84 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
85 + <path d="M7 2H4a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h3V2Zm2 0v11.4l5.4 7.4c.5.7 1.5.9 2.2.4.6-.4.9-1.1.7-1.8L16 14h4.2c1.2 0 2.1-1 1.9-2.2l-1.2-7.2A3 3 0 0 0 18 2H9Z" />
86 + </svg>
87 + </button>
88 + </div>
89 + </header>
90 + <p>This has exactly the right haunted-coast energy. I can already hear the dock bells getting weird.</p>
91 + </div>
92 + </article>
93 + <article class="comment is-right">
94 + <div class="avatar" style="--avatar-color: #7c5cff">JT</div>
95 + <div class="bubble">
96 + <header>
97 + <div class="comment-meta">
98 + <strong>Jett</strong>
99 + <span>1 hour ago</span>
100 + </div>
101 + <div class="comment-votes" aria-label="Comment votes">
102 + <button class="vote-up" type="button" aria-label="Upvote Jett's comment">
103 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
104 + <path d="M7 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h3v12Zm2 0V10.6l5.4-7.4c.5-.7 1.5-.9 2.2-.4.6.4.9 1.1.7 1.8L16 10h4.2c1.2 0 2.1 1 1.9 2.2l-1.2 7.2A3 3 0 0 1 18 22H9Z" />
105 + </svg>
106 + </button>
107 + <span>7</span>
108 + <button class="vote-down" type="button" aria-label="Downvote Jett's comment">
109 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
110 + <path d="M7 2H4a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h3V2Zm2 0v11.4l5.4 7.4c.5.7 1.5.9 2.2.4.6-.4.9-1.1.7-1.8L16 14h4.2c1.2 0 2.1-1 1.9-2.2l-1.2-7.2A3 3 0 0 0 18 2H9Z" />
111 + </svg>
112 + </button>
113 + </div>
114 + </header>
115 + <p>The lore barnacles are load-bearing. Please do not scrape them off.</p>
116 + </div>
117 + </article>
118 + <article class="comment">
119 + <div class="avatar" style="--avatar-color: #ff5c9a">NX</div>
120 + <div class="bubble">
121 + <header>
122 + <div class="comment-meta">
123 + <strong>Nix</strong>
124 + <span>33 minutes ago</span>
125 + </div>
126 + <div class="comment-votes" aria-label="Comment votes">
127 + <button class="vote-up" type="button" aria-label="Upvote Nix's comment">
128 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
129 + <path d="M7 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h3v12Zm2 0V10.6l5.4-7.4c.5-.7 1.5-.9 2.2-.4.6.4.9 1.1.7 1.8L16 10h4.2c1.2 0 2.1 1 1.9 2.2l-1.2 7.2A3 3 0 0 1 18 22H9Z" />
130 + </svg>
131 + </button>
132 + <span>3</span>
133 + <button class="vote-down" type="button" aria-label="Downvote Nix's comment">
134 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
135 + <path d="M7 2H4a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h3V2Zm2 0v11.4l5.4 7.4c.5.7 1.5.9 2.2.4.6-.4.9-1.1.7-1.8L16 14h4.2c1.2 0 2.1-1 1.9-2.2l-1.2-7.2A3 3 0 0 0 18 2H9Z" />
136 + </svg>
137 + </button>
138 + </div>
139 + </header>
140 + <p>I want a whole post about the shrine etiquette. What happens if someone brings the wrong fish?</p>
141 + </div>
142 + </article>
143 + </div>
144 + </section>
145 + <section class="markdown-editor" aria-label="Write a comment" data-markdown-editor>
146 + <textarea data-markdown-input rows="1" aria-label="Write a comment" placeholder="Write a Markdown comment: **bold**, *italic*, `code`, # heading, - list, > quote"></textarea>
147 + </section>
148 + </article>
149 + </main>
150 + <footer class="footer">
151 + <div class="brand">
152 + <img src="../../img/sharkmark.svg" alt="" aria-hidden="true">
153 + <p>&copy; 2026 Sharkk. No wipeouts, just waves.</p>
154 + </div>
155 + <nav class="links">
156 + <a href="../../privacy/index.html">Privacy</a>
157 + <a href="../../legal/index.html">Legal</a>
158 + </nav>
159 + </footer>
160 + </div>
161 + <script src="../../js/nav-dropdown.js"></script>
162 + <script src="../../js/blog-index.js"></script>
163 + <script src="../../js/markdown-editor.js"></script>
164 + </body>
165 + </html>
public/blog/designing-the-reef-cities/index.html +165 -0 added
1 + <!DOCTYPE html>
2 + <html lang="en">
3 + <head>
4 + <meta charset="UTF-8">
5 + <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 + <meta name="description" content="A quick look at turning coral skylines, canal markets, and shark-priest politics into adventure hooks.">
7 + <title>Designing the Reef Cities | Sharkk</title>
8 + <link rel="stylesheet" href="../../css/fonts.css">
9 + <link rel="stylesheet" href="../../css/tokens.css">
10 + <link rel="stylesheet" href="../../css/style.css">
11 + </head>
12 + <body>
13 + <div class="container">
14 + <header id="main">
15 + <a id="logo-link" href="../../index.html" aria-label="Sharkk home"></a>
16 + <div class="content">
17 + <nav>
18 + <div class="nav-item">
19 + <a href="../../work/index.html">
20 + Work <svg class="nav-chevron" viewBox="0 0 42 42" aria-hidden="true" focusable="false">
21 + <path d="M20.833,41.574l-20.674,-20.674l-0.159,-20.9l20.88,20.88l20.879,-20.88l-0.159,20.9l-20.674,20.674l-0,0.093l-0.046,-0.047l-0.047,0.047l0,-0.093Z" />
22 + </svg>
23 + </a>
24 + <div class="nav-dropdown work-list">
25 + <div class="link-list current-work">
26 + <a href="../../work/project-1/index.html">Anashti Sul</a>
27 + <a href="../../work/planes-of-power/index.html">Planes of Power</a>
28 + <a href="../../work/ashbringer/index.html">Ashbringer</a>
29 + </div>
30 + <div class="link-list old-work">
31 + <a href="../../work/mad-splash/index.html">Mad Splash</a>
32 + <a href="../../work/battles-for-arthos/index.html">Battles for Arthos</a>
33 + <a href="../../work/legendarium/index.html">Legendarium</a>
34 + </div>
35 + </div>
36 + </div>
37 + <div class="nav-item">
38 + <a href="../index.html">
39 + Blog </a>
40 + </div>
41 + <div class="nav-item">
42 + <a href="../../about/index.html">
43 + About </a>
44 + </div>
45 + </nav>
46 + </div>
47 + </header>
48 + </div>
49 + <div class="container">
50 + <main class="page blog-post-page">
51 + <article class="blog-post">
52 + <div class="cover-card">
53 + <img class="cover" src="../../img/slides/test2.jpg" alt="">
54 + </div>
55 + <header class="post-header">
56 + <h1>Designing the Reef Cities</h1>
57 + </header>
58 + <div class="content">
59 + <time datetime="2026-05-24">May 24, 2026</time>
60 + <p class="copy">A quick look at turning coral skylines, canal markets, and shark-priest politics into adventure hooks.</p>
61 + <p>Reef cities should feel like bright places built on dangerous foundations: beautiful from a distance and full of teeth up close.</p>
62 + <p>The trick is making every landmark pull double duty as scenery, history, and a problem waiting for the players to touch it.</p>
63 + <a class="read-more" href="../index.html">Back to Blog</a>
64 + </div>
65 + <section class="comments" aria-label="Comments">
66 + <h2>Comments</h2>
67 + <div class="comment-thread">
68 + <article class="comment">
69 + <div class="avatar" style="--avatar-color: #12AEF5">MR</div>
70 + <div class="bubble">
71 + <header>
72 + <div class="comment-meta">
73 + <strong>Mara</strong>
74 + <span>2 hours ago</span>
75 + </div>
76 + <div class="comment-votes" aria-label="Comment votes">
77 + <button class="vote-up" type="button" aria-label="Upvote Mara's comment">
78 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
79 + <path d="M7 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h3v12Zm2 0V10.6l5.4-7.4c.5-.7 1.5-.9 2.2-.4.6.4.9 1.1.7 1.8L16 10h4.2c1.2 0 2.1 1 1.9 2.2l-1.2 7.2A3 3 0 0 1 18 22H9Z" />
80 + </svg>
81 + </button>
82 + <span>12</span>
83 + <button class="vote-down" type="button" aria-label="Downvote Mara's comment">
84 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
85 + <path d="M7 2H4a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h3V2Zm2 0v11.4l5.4 7.4c.5.7 1.5.9 2.2.4.6-.4.9-1.1.7-1.8L16 14h4.2c1.2 0 2.1-1 1.9-2.2l-1.2-7.2A3 3 0 0 0 18 2H9Z" />
86 + </svg>
87 + </button>
88 + </div>
89 + </header>
90 + <p>This has exactly the right haunted-coast energy. I can already hear the dock bells getting weird.</p>
91 + </div>
92 + </article>
93 + <article class="comment is-right">
94 + <div class="avatar" style="--avatar-color: #7c5cff">JT</div>
95 + <div class="bubble">
96 + <header>
97 + <div class="comment-meta">
98 + <strong>Jett</strong>
99 + <span>1 hour ago</span>
100 + </div>
101 + <div class="comment-votes" aria-label="Comment votes">
102 + <button class="vote-up" type="button" aria-label="Upvote Jett's comment">
103 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
104 + <path d="M7 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h3v12Zm2 0V10.6l5.4-7.4c.5-.7 1.5-.9 2.2-.4.6.4.9 1.1.7 1.8L16 10h4.2c1.2 0 2.1 1 1.9 2.2l-1.2 7.2A3 3 0 0 1 18 22H9Z" />
105 + </svg>
106 + </button>
107 + <span>7</span>
108 + <button class="vote-down" type="button" aria-label="Downvote Jett's comment">
109 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
110 + <path d="M7 2H4a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h3V2Zm2 0v11.4l5.4 7.4c.5.7 1.5.9 2.2.4.6-.4.9-1.1.7-1.8L16 14h4.2c1.2 0 2.1-1 1.9-2.2l-1.2-7.2A3 3 0 0 0 18 2H9Z" />
111 + </svg>
112 + </button>
113 + </div>
114 + </header>
115 + <p>The lore barnacles are load-bearing. Please do not scrape them off.</p>
116 + </div>
117 + </article>
118 + <article class="comment">
119 + <div class="avatar" style="--avatar-color: #ff5c9a">NX</div>
120 + <div class="bubble">
121 + <header>
122 + <div class="comment-meta">
123 + <strong>Nix</strong>
124 + <span>33 minutes ago</span>
125 + </div>
126 + <div class="comment-votes" aria-label="Comment votes">
127 + <button class="vote-up" type="button" aria-label="Upvote Nix's comment">
128 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
129 + <path d="M7 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h3v12Zm2 0V10.6l5.4-7.4c.5-.7 1.5-.9 2.2-.4.6.4.9 1.1.7 1.8L16 10h4.2c1.2 0 2.1 1 1.9 2.2l-1.2 7.2A3 3 0 0 1 18 22H9Z" />
130 + </svg>
131 + </button>
132 + <span>3</span>
133 + <button class="vote-down" type="button" aria-label="Downvote Nix's comment">
134 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
135 + <path d="M7 2H4a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h3V2Zm2 0v11.4l5.4 7.4c.5.7 1.5.9 2.2.4.6-.4.9-1.1.7-1.8L16 14h4.2c1.2 0 2.1-1 1.9-2.2l-1.2-7.2A3 3 0 0 0 18 2H9Z" />
136 + </svg>
137 + </button>
138 + </div>
139 + </header>
140 + <p>I want a whole post about the shrine etiquette. What happens if someone brings the wrong fish?</p>
141 + </div>
142 + </article>
143 + </div>
144 + </section>
145 + <section class="markdown-editor" aria-label="Write a comment" data-markdown-editor>
146 + <textarea data-markdown-input rows="1" aria-label="Write a comment" placeholder="Write a Markdown comment: **bold**, *italic*, `code`, # heading, - list, > quote"></textarea>
147 + </section>
148 + </article>
149 + </main>
150 + <footer class="footer">
151 + <div class="brand">
152 + <img src="../../img/sharkmark.svg" alt="" aria-hidden="true">
153 + <p>&copy; 2026 Sharkk. No wipeouts, just waves.</p>
154 + </div>
155 + <nav class="links">
156 + <a href="../../privacy/index.html">Privacy</a>
157 + <a href="../../legal/index.html">Legal</a>
158 + </nav>
159 + </footer>
160 + </div>
161 + <script src="../../js/nav-dropdown.js"></script>
162 + <script src="../../js/blog-index.js"></script>
163 + <script src="../../js/markdown-editor.js"></script>
164 + </body>
165 + </html>
public/blog/index.html +163 -0 added
1 + <!DOCTYPE html>
2 + <html lang="en">
3 + <head>
4 + <meta charset="UTF-8">
5 + <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 + <meta name="description" content="A demo blog landing page for dev notes, worldbuilding scraps, and other salt-sprayed updates.">
7 + <title>Blog | Sharkk</title>
8 + <link rel="stylesheet" href="../css/fonts.css">
9 + <link rel="stylesheet" href="../css/tokens.css">
10 + <link rel="stylesheet" href="../css/style.css">
11 + </head>
12 + <body>
13 + <div class="container">
14 + <header id="main">
15 + <a id="logo-link" href="../index.html" aria-label="Sharkk home"></a>
16 + <div class="content">
17 + <nav>
18 + <div class="nav-item">
19 + <a href="../work/index.html">
20 + Work <svg class="nav-chevron" viewBox="0 0 42 42" aria-hidden="true" focusable="false">
21 + <path d="M20.833,41.574l-20.674,-20.674l-0.159,-20.9l20.88,20.88l20.879,-20.88l-0.159,20.9l-20.674,20.674l-0,0.093l-0.046,-0.047l-0.047,0.047l0,-0.093Z" />
22 + </svg>
23 + </a>
24 + <div class="nav-dropdown work-list">
25 + <div class="link-list current-work">
26 + <a href="../work/project-1/index.html">Anashti Sul</a>
27 + <a href="../work/planes-of-power/index.html">Planes of Power</a>
28 + <a href="../work/ashbringer/index.html">Ashbringer</a>
29 + </div>
30 + <div class="link-list old-work">
31 + <a href="../work/mad-splash/index.html">Mad Splash</a>
32 + <a href="../work/battles-for-arthos/index.html">Battles for Arthos</a>
33 + <a href="../work/legendarium/index.html">Legendarium</a>
34 + </div>
35 + </div>
36 + </div>
37 + <div class="nav-item">
38 + <a href="index.html">
39 + Blog </a>
40 + </div>
41 + <div class="nav-item">
42 + <a href="../about/index.html">
43 + About </a>
44 + </div>
45 + </nav>
46 + </div>
47 + </header>
48 + </div>
49 + <div class="container">
50 + <main class="page blog-page">
51 + <section class="hero">
52 + <div class="content">
53 + <h1>Dispatches from the reef</h1>
54 + <p class="copy">A demo blog landing page for dev notes, worldbuilding scraps, and other salt-sprayed updates.</p>
55 + </div>
56 + </section>
57 + <div class="blog-tools" data-blog-index data-search-index="search-index.json">
58 + <div class="blog-filters" aria-label="Filter articles">
59 + <div class="filter-dropdown-chip" data-filter-dropdown>
60 + <button type="button" aria-expanded="false" aria-haspopup="listbox" aria-label="Filter articles by category" data-filter-toggle>
61 + <strong data-filter-label>All</strong>
62 + </button>
63 + <div class="filter-menu" role="listbox" hidden data-filter-menu>
64 + <button class="is-active" type="button" role="option" aria-selected="true" data-blog-filter="">All</button>
65 + <button type="button" role="option" aria-selected="false" data-blog-filter="Design">Design</button>
66 + <button type="button" role="option" aria-selected="false" data-blog-filter="Games">Games</button>
67 + <button type="button" role="option" aria-selected="false" data-blog-filter="Lore">Lore</button>
68 + <button type="button" role="option" aria-selected="false" data-blog-filter="Maps">Maps</button>
69 + <button type="button" role="option" aria-selected="false" data-blog-filter="Site">Site</button>
70 + <button type="button" role="option" aria-selected="false" data-blog-filter="Worldbuilding">Worldbuilding</button>
71 + </div>
72 + </div>
73 + </div>
74 + <input id="blog-search" type="search" placeholder="Search the reef..." autocomplete="off" aria-label="Search articles" data-blog-search>
75 + </div>
76 + <section class="blog-list" aria-label="Blog posts" data-blog-list>
77 + <article class="blog-card" data-blog-card data-post-key="salt-and-star-maps">
78 + <a class="cover" href="salt-and-star-maps/index.html">
79 + <img src="../img/slides/test1.jpg" alt="">
80 + </a>
81 + <div class="summary">
82 + <time datetime="2026-06-02">June 2, 2026</time>
83 + <h2>Salt and Star Maps</h2>
84 + <p>How a coastal fantasy map turns tides, trade routes, and bad omens into playable trouble.</p>
85 + <a class="read-more" href="salt-and-star-maps/index.html">Read More</a>
86 + </div>
87 + </article>
88 + <article class="blog-card is-reversed" data-blog-card data-post-key="designing-the-reef-cities">
89 + <a class="cover" href="designing-the-reef-cities/index.html">
90 + <img src="../img/slides/test2.jpg" alt="">
91 + </a>
92 + <div class="summary">
93 + <time datetime="2026-05-24">May 24, 2026</time>
94 + <h2>Designing the Reef Cities</h2>
95 + <p>A quick look at turning coral skylines, canal markets, and shark-priest politics into adventure hooks.</p>
96 + <a class="read-more" href="designing-the-reef-cities/index.html">Read More</a>
97 + </div>
98 + </article>
99 + <article class="blog-card" data-blog-card data-post-key="arcade-chaos-with-lore-barnacles">
100 + <a class="cover" href="arcade-chaos-with-lore-barnacles/index.html">
101 + <img src="../img/slides/test3.jpg" alt="">
102 + </a>
103 + <div class="summary">
104 + <time datetime="2026-05-11">May 11, 2026</time>
105 + <h2>Arcade Chaos With Lore Barnacles</h2>
106 + <p>Why even a fast, silly water-racer deserves factions, rumors, and one extremely suspicious trophy.</p>
107 + <a class="read-more" href="arcade-chaos-with-lore-barnacles/index.html">Read More</a>
108 + </div>
109 + </article>
110 + <article class="blog-card is-reversed" data-blog-card data-post-key="building-demo-pages-that-breathe">
111 + <a class="cover" href="building-demo-pages-that-breathe/index.html">
112 + <img src="../img/slides/test4.jpg" alt="">
113 + </a>
114 + <div class="summary">
115 + <time datetime="2026-04-28">April 28, 2026</time>
116 + <h2>Building Demo Pages That Breathe</h2>
117 + <p>Notes on keeping a concept site lightweight while still giving each project room to feel alive.</p>
118 + <a class="read-more" href="building-demo-pages-that-breathe/index.html">Read More</a>
119 + </div>
120 + </article>
121 + <article class="blog-card" data-blog-card data-post-key="why-the-sharks-have-temples">
122 + <a class="cover" href="why-the-sharks-have-temples/index.html">
123 + <img src="../img/works/testheader1.jpg" alt="">
124 + </a>
125 + <div class="summary">
126 + <time datetime="2026-04-12">April 12, 2026</time>
127 + <h2>Why the Sharks Have Temples</h2>
128 + <p>A tiny lore pass on holy predators, reef taboos, and the difference between worship and negotiation.</p>
129 + <a class="read-more" href="why-the-sharks-have-temples/index.html">Read More</a>
130 + </div>
131 + </article>
132 + <article class="blog-card is-reversed" data-blog-card data-post-key="making-buttons-feel-like-treasure">
133 + <a class="cover" href="making-buttons-feel-like-treasure/index.html">
134 + <img src="../img/slides/test1.jpg" alt="">
135 + </a>
136 + <div class="summary">
137 + <time datetime="2026-03-30">March 30, 2026</time>
138 + <h2>Making Buttons Feel Like Treasure</h2>
139 + <p>A small UI note about shine, weight, and giving a demo interface just enough arcade confidence.</p>
140 + <a class="read-more" href="making-buttons-feel-like-treasure/index.html">Read More</a>
141 + </div>
142 + </article>
143 + </section>
144 + <p class="blog-empty" hidden data-blog-empty>No articles found. Try another search or filter.</p>
145 + <button class="load-more" type="button" hidden data-blog-load-more>Load More</button>
146 + <script type="application/json" data-blog-search-inline>[{"key":"salt-and-star-maps","title":"Salt and Star Maps","date":"2026-06-02","description":"How a coastal fantasy map turns tides, trade routes, and bad omens into playable trouble.","filters":["Worldbuilding","Maps"],"fields":{"title":"Salt and Star Maps","description":"How a coastal fantasy map turns tides, trade routes, and bad omens into playable trouble.","filters":"Worldbuilding Maps","body":"Every Sharkk map starts with a practical question: what would make travel useful, scary, and just inconvenient enough to become a story? For Anashti Sul, that means reefs that move, stars that lie, and port cities where every bargain has a little salt in the wound."},"text":"Salt and Star Maps 2026-06-02 Worldbuilding Maps How a coastal fantasy map turns tides, trade routes, and bad omens into playable trouble. Every Sharkk map starts with a practical question: what would make travel useful, scary, and just inconvenient enough to become a story? For Anashti Sul, that means reefs that move, stars that lie, and port cities where every bargain has a little salt in the wound."},{"key":"designing-the-reef-cities","title":"Designing the Reef Cities","date":"2026-05-24","description":"A quick look at turning coral skylines, canal markets, and shark-priest politics into adventure hooks.","filters":["Worldbuilding","Design"],"fields":{"title":"Designing the Reef Cities","description":"A quick look at turning coral skylines, canal markets, and shark-priest politics into adventure hooks.","filters":"Worldbuilding Design","body":"Reef cities should feel like bright places built on dangerous foundations: beautiful from a distance and full of teeth up close. The trick is making every landmark pull double duty as scenery, history, and a problem waiting for the players to touch it."},"text":"Designing the Reef Cities 2026-05-24 Worldbuilding Design A quick look at turning coral skylines, canal markets, and shark-priest politics into adventure hooks. Reef cities should feel like bright places built on dangerous foundations: beautiful from a distance and full of teeth up close. The trick is making every landmark pull double duty as scenery, history, and a problem waiting for the players to touch it."},{"key":"arcade-chaos-with-lore-barnacles","title":"Arcade Chaos With Lore Barnacles","date":"2026-05-11","description":"Why even a fast, silly water-racer deserves factions, rumors, and one extremely suspicious trophy.","filters":["Games","Lore"],"fields":{"title":"Arcade Chaos With Lore Barnacles","description":"Why even a fast, silly water-racer deserves factions, rumors, and one extremely suspicious trophy.","filters":"Games Lore","body":"Mad Splash wants to move fast, but fast does not have to mean empty. The best arcade nonsense still leaves room for myths in the margins. Give players a reason to laugh first, then give them just enough lore to wonder who built the impossible shortcut through the storm wall."},"text":"Arcade Chaos With Lore Barnacles 2026-05-11 Games Lore Why even a fast, silly water-racer deserves factions, rumors, and one extremely suspicious trophy. Mad Splash wants to move fast, but fast does not have to mean empty. The best arcade nonsense still leaves room for myths in the margins. Give players a reason to laugh first, then give them just enough lore to wonder who built the impossible shortcut through the storm wall."},{"key":"building-demo-pages-that-breathe","title":"Building Demo Pages That Breathe","date":"2026-04-28","description":"Notes on keeping a concept site lightweight while still giving each project room to feel alive.","filters":["Design","Site"],"fields":{"title":"Building Demo Pages That Breathe","description":"Notes on keeping a concept site lightweight while still giving each project room to feel alive.","filters":"Design Site","body":"The demo site is intentionally small, but the pieces need to feel expandable: reusable chunks, real links, and enough structure to grow without a rewrite. That means every fake post, project card, and footer link should behave like it already belongs to a larger site."},"text":"Building Demo Pages That Breathe 2026-04-28 Design Site Notes on keeping a concept site lightweight while still giving each project room to feel alive. The demo site is intentionally small, but the pieces need to feel expandable: reusable chunks, real links, and enough structure to grow without a rewrite. That means every fake post, project card, and footer link should behave like it already belongs to a larger site."},{"key":"why-the-sharks-have-temples","title":"Why the Sharks Have Temples","date":"2026-04-12","description":"A tiny lore pass on holy predators, reef taboos, and the difference between worship and negotiation.","filters":["Worldbuilding","Lore"],"fields":{"title":"Why the Sharks Have Temples","description":"A tiny lore pass on holy predators, reef taboos, and the difference between worship and negotiation.","filters":"Worldbuilding Lore","body":"The shark temples are less about obedience and more about etiquette. You do not pray because the sea is kind; you pray because the sea has rules. That makes every shrine a social contract, every offering a warning, and every priest a diplomat with very sharp constituents."},"text":"Why the Sharks Have Temples 2026-04-12 Worldbuilding Lore A tiny lore pass on holy predators, reef taboos, and the difference between worship and negotiation. The shark temples are less about obedience and more about etiquette. You do not pray because the sea is kind; you pray because the sea has rules. That makes every shrine a social contract, every offering a warning, and every priest a diplomat with very sharp constituents."},{"key":"making-buttons-feel-like-treasure","title":"Making Buttons Feel Like Treasure","date":"2026-03-30","description":"A small UI note about shine, weight, and giving a demo interface just enough arcade confidence.","filters":["Design","Site"],"fields":{"title":"Making Buttons Feel Like Treasure","description":"A small UI note about shine, weight, and giving a demo interface just enough arcade confidence.","filters":"Design Site","body":"A good demo button should feel obvious without feeling generic. It needs weight, contrast, and just enough gloss to look worth pressing. The goal is not realism. The goal is a small hit of treasure-chest certainty every time the interface asks for a decision."},"text":"Making Buttons Feel Like Treasure 2026-03-30 Design Site A small UI note about shine, weight, and giving a demo interface just enough arcade confidence. A good demo button should feel obvious without feeling generic. It needs weight, contrast, and just enough gloss to look worth pressing. The goal is not realism. The goal is a small hit of treasure-chest certainty every time the interface asks for a decision."}]</script>
147 + </main>
148 + <footer class="footer">
149 + <div class="brand">
150 + <img src="../img/sharkmark.svg" alt="" aria-hidden="true">
151 + <p>&copy; 2026 Sharkk. No wipeouts, just waves.</p>
152 + </div>
153 + <nav class="links">
154 + <a href="../privacy/index.html">Privacy</a>
155 + <a href="../legal/index.html">Legal</a>
156 + </nav>
157 + </footer>
158 + </div>
159 + <script src="../js/nav-dropdown.js"></script>
160 + <script src="../js/blog-index.js"></script>
161 + <script src="../js/markdown-editor.js"></script>
162 + </body>
163 + </html>
public/blog/making-buttons-feel-like-treasure/index.html +165 -0 added
1 + <!DOCTYPE html>
2 + <html lang="en">
3 + <head>
4 + <meta charset="UTF-8">
5 + <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 + <meta name="description" content="A small UI note about shine, weight, and giving a demo interface just enough arcade confidence.">
7 + <title>Making Buttons Feel Like Treasure | Sharkk</title>
8 + <link rel="stylesheet" href="../../css/fonts.css">
9 + <link rel="stylesheet" href="../../css/tokens.css">
10 + <link rel="stylesheet" href="../../css/style.css">
11 + </head>
12 + <body>
13 + <div class="container">
14 + <header id="main">
15 + <a id="logo-link" href="../../index.html" aria-label="Sharkk home"></a>
16 + <div class="content">
17 + <nav>
18 + <div class="nav-item">
19 + <a href="../../work/index.html">
20 + Work <svg class="nav-chevron" viewBox="0 0 42 42" aria-hidden="true" focusable="false">
21 + <path d="M20.833,41.574l-20.674,-20.674l-0.159,-20.9l20.88,20.88l20.879,-20.88l-0.159,20.9l-20.674,20.674l-0,0.093l-0.046,-0.047l-0.047,0.047l0,-0.093Z" />
22 + </svg>
23 + </a>
24 + <div class="nav-dropdown work-list">
25 + <div class="link-list current-work">
26 + <a href="../../work/project-1/index.html">Anashti Sul</a>
27 + <a href="../../work/planes-of-power/index.html">Planes of Power</a>
28 + <a href="../../work/ashbringer/index.html">Ashbringer</a>
29 + </div>
30 + <div class="link-list old-work">
31 + <a href="../../work/mad-splash/index.html">Mad Splash</a>
32 + <a href="../../work/battles-for-arthos/index.html">Battles for Arthos</a>
33 + <a href="../../work/legendarium/index.html">Legendarium</a>
34 + </div>
35 + </div>
36 + </div>
37 + <div class="nav-item">
38 + <a href="../index.html">
39 + Blog </a>
40 + </div>
41 + <div class="nav-item">
42 + <a href="../../about/index.html">
43 + About </a>
44 + </div>
45 + </nav>
46 + </div>
47 + </header>
48 + </div>
49 + <div class="container">
50 + <main class="page blog-post-page">
51 + <article class="blog-post">
52 + <div class="cover-card">
53 + <img class="cover" src="../../img/slides/test1.jpg" alt="">
54 + </div>
55 + <header class="post-header">
56 + <h1>Making Buttons Feel Like Treasure</h1>
57 + </header>
58 + <div class="content">
59 + <time datetime="2026-03-30">March 30, 2026</time>
60 + <p class="copy">A small UI note about shine, weight, and giving a demo interface just enough arcade confidence.</p>
61 + <p>A good demo button should feel obvious without feeling generic. It needs weight, contrast, and just enough gloss to look worth pressing.</p>
62 + <p>The goal is not realism. The goal is a small hit of treasure-chest certainty every time the interface asks for a decision.</p>
63 + <a class="read-more" href="../index.html">Back to Blog</a>
64 + </div>
65 + <section class="comments" aria-label="Comments">
66 + <h2>Comments</h2>
67 + <div class="comment-thread">
68 + <article class="comment">
69 + <div class="avatar" style="--avatar-color: #12AEF5">MR</div>
70 + <div class="bubble">
71 + <header>
72 + <div class="comment-meta">
73 + <strong>Mara</strong>
74 + <span>2 hours ago</span>
75 + </div>
76 + <div class="comment-votes" aria-label="Comment votes">
77 + <button class="vote-up" type="button" aria-label="Upvote Mara's comment">
78 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
79 + <path d="M7 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h3v12Zm2 0V10.6l5.4-7.4c.5-.7 1.5-.9 2.2-.4.6.4.9 1.1.7 1.8L16 10h4.2c1.2 0 2.1 1 1.9 2.2l-1.2 7.2A3 3 0 0 1 18 22H9Z" />
80 + </svg>
81 + </button>
82 + <span>12</span>
83 + <button class="vote-down" type="button" aria-label="Downvote Mara's comment">
84 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
85 + <path d="M7 2H4a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h3V2Zm2 0v11.4l5.4 7.4c.5.7 1.5.9 2.2.4.6-.4.9-1.1.7-1.8L16 14h4.2c1.2 0 2.1-1 1.9-2.2l-1.2-7.2A3 3 0 0 0 18 2H9Z" />
86 + </svg>
87 + </button>
88 + </div>
89 + </header>
90 + <p>This has exactly the right haunted-coast energy. I can already hear the dock bells getting weird.</p>
91 + </div>
92 + </article>
93 + <article class="comment is-right">
94 + <div class="avatar" style="--avatar-color: #7c5cff">JT</div>
95 + <div class="bubble">
96 + <header>
97 + <div class="comment-meta">
98 + <strong>Jett</strong>
99 + <span>1 hour ago</span>
100 + </div>
101 + <div class="comment-votes" aria-label="Comment votes">
102 + <button class="vote-up" type="button" aria-label="Upvote Jett's comment">
103 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
104 + <path d="M7 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h3v12Zm2 0V10.6l5.4-7.4c.5-.7 1.5-.9 2.2-.4.6.4.9 1.1.7 1.8L16 10h4.2c1.2 0 2.1 1 1.9 2.2l-1.2 7.2A3 3 0 0 1 18 22H9Z" />
105 + </svg>
106 + </button>
107 + <span>7</span>
108 + <button class="vote-down" type="button" aria-label="Downvote Jett's comment">
109 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
110 + <path d="M7 2H4a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h3V2Zm2 0v11.4l5.4 7.4c.5.7 1.5.9 2.2.4.6-.4.9-1.1.7-1.8L16 14h4.2c1.2 0 2.1-1 1.9-2.2l-1.2-7.2A3 3 0 0 0 18 2H9Z" />
111 + </svg>
112 + </button>
113 + </div>
114 + </header>
115 + <p>The lore barnacles are load-bearing. Please do not scrape them off.</p>
116 + </div>
117 + </article>
118 + <article class="comment">
119 + <div class="avatar" style="--avatar-color: #ff5c9a">NX</div>
120 + <div class="bubble">
121 + <header>
122 + <div class="comment-meta">
123 + <strong>Nix</strong>
124 + <span>33 minutes ago</span>
125 + </div>
126 + <div class="comment-votes" aria-label="Comment votes">
127 + <button class="vote-up" type="button" aria-label="Upvote Nix's comment">
128 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
129 + <path d="M7 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h3v12Zm2 0V10.6l5.4-7.4c.5-.7 1.5-.9 2.2-.4.6.4.9 1.1.7 1.8L16 10h4.2c1.2 0 2.1 1 1.9 2.2l-1.2 7.2A3 3 0 0 1 18 22H9Z" />
130 + </svg>
131 + </button>
132 + <span>3</span>
133 + <button class="vote-down" type="button" aria-label="Downvote Nix's comment">
134 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
135 + <path d="M7 2H4a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h3V2Zm2 0v11.4l5.4 7.4c.5.7 1.5.9 2.2.4.6-.4.9-1.1.7-1.8L16 14h4.2c1.2 0 2.1-1 1.9-2.2l-1.2-7.2A3 3 0 0 0 18 2H9Z" />
136 + </svg>
137 + </button>
138 + </div>
139 + </header>
140 + <p>I want a whole post about the shrine etiquette. What happens if someone brings the wrong fish?</p>
141 + </div>
142 + </article>
143 + </div>
144 + </section>
145 + <section class="markdown-editor" aria-label="Write a comment" data-markdown-editor>
146 + <textarea data-markdown-input rows="1" aria-label="Write a comment" placeholder="Write a Markdown comment: **bold**, *italic*, `code`, # heading, - list, > quote"></textarea>
147 + </section>
148 + </article>
149 + </main>
150 + <footer class="footer">
151 + <div class="brand">
152 + <img src="../../img/sharkmark.svg" alt="" aria-hidden="true">
153 + <p>&copy; 2026 Sharkk. No wipeouts, just waves.</p>
154 + </div>
155 + <nav class="links">
156 + <a href="../../privacy/index.html">Privacy</a>
157 + <a href="../../legal/index.html">Legal</a>
158 + </nav>
159 + </footer>
160 + </div>
161 + <script src="../../js/nav-dropdown.js"></script>
162 + <script src="../../js/blog-index.js"></script>
163 + <script src="../../js/markdown-editor.js"></script>
164 + </body>
165 + </html>
public/blog/salt-and-star-maps/index.html +165 -0 added
1 + <!DOCTYPE html>
2 + <html lang="en">
3 + <head>
4 + <meta charset="UTF-8">
5 + <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 + <meta name="description" content="How a coastal fantasy map turns tides, trade routes, and bad omens into playable trouble.">
7 + <title>Salt and Star Maps | Sharkk</title>
8 + <link rel="stylesheet" href="../../css/fonts.css">
9 + <link rel="stylesheet" href="../../css/tokens.css">
10 + <link rel="stylesheet" href="../../css/style.css">
11 + </head>
12 + <body>
13 + <div class="container">
14 + <header id="main">
15 + <a id="logo-link" href="../../index.html" aria-label="Sharkk home"></a>
16 + <div class="content">
17 + <nav>
18 + <div class="nav-item">
19 + <a href="../../work/index.html">
20 + Work <svg class="nav-chevron" viewBox="0 0 42 42" aria-hidden="true" focusable="false">
21 + <path d="M20.833,41.574l-20.674,-20.674l-0.159,-20.9l20.88,20.88l20.879,-20.88l-0.159,20.9l-20.674,20.674l-0,0.093l-0.046,-0.047l-0.047,0.047l0,-0.093Z" />
22 + </svg>
23 + </a>
24 + <div class="nav-dropdown work-list">
25 + <div class="link-list current-work">
26 + <a href="../../work/project-1/index.html">Anashti Sul</a>
27 + <a href="../../work/planes-of-power/index.html">Planes of Power</a>
28 + <a href="../../work/ashbringer/index.html">Ashbringer</a>
29 + </div>
30 + <div class="link-list old-work">
31 + <a href="../../work/mad-splash/index.html">Mad Splash</a>
32 + <a href="../../work/battles-for-arthos/index.html">Battles for Arthos</a>
33 + <a href="../../work/legendarium/index.html">Legendarium</a>
34 + </div>
35 + </div>
36 + </div>
37 + <div class="nav-item">
38 + <a href="../index.html">
39 + Blog </a>
40 + </div>
41 + <div class="nav-item">
42 + <a href="../../about/index.html">
43 + About </a>
44 + </div>
45 + </nav>
46 + </div>
47 + </header>
48 + </div>
49 + <div class="container">
50 + <main class="page blog-post-page">
51 + <article class="blog-post">
52 + <div class="cover-card">
53 + <img class="cover" src="../../img/slides/test1.jpg" alt="">
54 + </div>
55 + <header class="post-header">
56 + <h1>Salt and Star Maps</h1>
57 + </header>
58 + <div class="content">
59 + <time datetime="2026-06-02">June 2, 2026</time>
60 + <p class="copy">How a coastal fantasy map turns tides, trade routes, and bad omens into playable trouble.</p>
61 + <p>Every Sharkk map starts with a practical question: what would make travel useful, scary, and just inconvenient enough to become a story?</p>
62 + <p>For Anashti Sul, that means reefs that move, stars that lie, and port cities where every bargain has a little salt in the wound.</p>
63 + <a class="read-more" href="../index.html">Back to Blog</a>
64 + </div>
65 + <section class="comments" aria-label="Comments">
66 + <h2>Comments</h2>
67 + <div class="comment-thread">
68 + <article class="comment">
69 + <div class="avatar" style="--avatar-color: #12AEF5">MR</div>
70 + <div class="bubble">
71 + <header>
72 + <div class="comment-meta">
73 + <strong>Mara</strong>
74 + <span>2 hours ago</span>
75 + </div>
76 + <div class="comment-votes" aria-label="Comment votes">
77 + <button class="vote-up" type="button" aria-label="Upvote Mara's comment">
78 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
79 + <path d="M7 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h3v12Zm2 0V10.6l5.4-7.4c.5-.7 1.5-.9 2.2-.4.6.4.9 1.1.7 1.8L16 10h4.2c1.2 0 2.1 1 1.9 2.2l-1.2 7.2A3 3 0 0 1 18 22H9Z" />
80 + </svg>
81 + </button>
82 + <span>12</span>
83 + <button class="vote-down" type="button" aria-label="Downvote Mara's comment">
84 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
85 + <path d="M7 2H4a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h3V2Zm2 0v11.4l5.4 7.4c.5.7 1.5.9 2.2.4.6-.4.9-1.1.7-1.8L16 14h4.2c1.2 0 2.1-1 1.9-2.2l-1.2-7.2A3 3 0 0 0 18 2H9Z" />
86 + </svg>
87 + </button>
88 + </div>
89 + </header>
90 + <p>This has exactly the right haunted-coast energy. I can already hear the dock bells getting weird.</p>
91 + </div>
92 + </article>
93 + <article class="comment is-right">
94 + <div class="avatar" style="--avatar-color: #7c5cff">JT</div>
95 + <div class="bubble">
96 + <header>
97 + <div class="comment-meta">
98 + <strong>Jett</strong>
99 + <span>1 hour ago</span>
100 + </div>
101 + <div class="comment-votes" aria-label="Comment votes">
102 + <button class="vote-up" type="button" aria-label="Upvote Jett's comment">
103 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
104 + <path d="M7 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h3v12Zm2 0V10.6l5.4-7.4c.5-.7 1.5-.9 2.2-.4.6.4.9 1.1.7 1.8L16 10h4.2c1.2 0 2.1 1 1.9 2.2l-1.2 7.2A3 3 0 0 1 18 22H9Z" />
105 + </svg>
106 + </button>
107 + <span>7</span>
108 + <button class="vote-down" type="button" aria-label="Downvote Jett's comment">
109 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
110 + <path d="M7 2H4a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h3V2Zm2 0v11.4l5.4 7.4c.5.7 1.5.9 2.2.4.6-.4.9-1.1.7-1.8L16 14h4.2c1.2 0 2.1-1 1.9-2.2l-1.2-7.2A3 3 0 0 0 18 2H9Z" />
111 + </svg>
112 + </button>
113 + </div>
114 + </header>
115 + <p>The lore barnacles are load-bearing. Please do not scrape them off.</p>
116 + </div>
117 + </article>
118 + <article class="comment">
119 + <div class="avatar" style="--avatar-color: #ff5c9a">NX</div>
120 + <div class="bubble">
121 + <header>
122 + <div class="comment-meta">
123 + <strong>Nix</strong>
124 + <span>33 minutes ago</span>
125 + </div>
126 + <div class="comment-votes" aria-label="Comment votes">
127 + <button class="vote-up" type="button" aria-label="Upvote Nix's comment">
128 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
129 + <path d="M7 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h3v12Zm2 0V10.6l5.4-7.4c.5-.7 1.5-.9 2.2-.4.6.4.9 1.1.7 1.8L16 10h4.2c1.2 0 2.1 1 1.9 2.2l-1.2 7.2A3 3 0 0 1 18 22H9Z" />
130 + </svg>
131 + </button>
132 + <span>3</span>
133 + <button class="vote-down" type="button" aria-label="Downvote Nix's comment">
134 + <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
135 + <path d="M7 2H4a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h3V2Zm2 0v11.4l5.4 7.4c.5.7 1.5.9 2.2.4.6-.4.9-1.1.7-1.8L16 14h4.2c1.2 0 2.1-1 1.9-2.2l-1.2-7.2A3 3 0 0 0 18 2H9Z" />
136 + </svg>
137 + </button>
138 + </div>
139 + </header>
140 + <p>I want a whole post about the shrine etiquette. What happens if someone brings the wrong fish?</p>
141 + </div>
142 + </article>
143 + </div>
144 + </section>
145 + <section class="markdown-editor" aria-label="Write a comment" data-markdown-editor>
146 + <textarea data-markdown-input rows="1" aria-label="Write a comment" placeholder="Write a Markdown comment: **bold**, *italic*, `code`, # heading, - list, > quote"></textarea>
147 + </section>
148 + </article>
149 + </main>
150 + <footer class="footer">
151 + <div class="brand">
152 + <img src="../../img/sharkmark.svg" alt="" aria-hidden="true">
public/blog/search-index.json added

Inline diff hidden to keep this page fast.

public/blog/why-the-sharks-have-temples/index.html added

Inline diff hidden to keep this page fast.

public/css/fonts.css added

Inline diff hidden to keep this page fast.

public/css/style.css added

Inline diff hidden to keep this page fast.

public/css/tokens.css added

Inline diff hidden to keep this page fast.

public/fonts/.DS_Store added

Inline diff hidden to keep this page fast.

public/fonts/montserrat/Montserrat-Black.ttf added

Inline diff hidden to keep this page fast.

public/fonts/montserrat/Montserrat-BlackItalic.ttf added

Inline diff hidden to keep this page fast.

public/fonts/montserrat/Montserrat-Bold.ttf added

Inline diff hidden to keep this page fast.

public/fonts/montserrat/Montserrat-BoldItalic.ttf added

Inline diff hidden to keep this page fast.

public/fonts/montserrat/Montserrat-ExtraBold.ttf added

Inline diff hidden to keep this page fast.

public/fonts/montserrat/Montserrat-ExtraBoldItalic.ttf added

Inline diff hidden to keep this page fast.

public/fonts/montserrat/Montserrat-ExtraLight.ttf added

Inline diff hidden to keep this page fast.

public/fonts/montserrat/Montserrat-ExtraLightItalic.ttf added

Inline diff hidden to keep this page fast.

public/fonts/montserrat/Montserrat-Italic.ttf added

Inline diff hidden to keep this page fast.

public/fonts/montserrat/Montserrat-Light.ttf added

Inline diff hidden to keep this page fast.

public/fonts/montserrat/Montserrat-LightItalic.ttf added

Inline diff hidden to keep this page fast.

public/fonts/montserrat/Montserrat-Medium.ttf added

Inline diff hidden to keep this page fast.

public/fonts/montserrat/Montserrat-MediumItalic.ttf added

Inline diff hidden to keep this page fast.

public/fonts/montserrat/Montserrat-Regular.ttf added

Inline diff hidden to keep this page fast.

public/fonts/montserrat/Montserrat-SemiBold.ttf added

Inline diff hidden to keep this page fast.

public/fonts/montserrat/Montserrat-SemiBoldItalic.ttf added

Inline diff hidden to keep this page fast.

public/fonts/montserrat/Montserrat-Thin.ttf added

Inline diff hidden to keep this page fast.

public/fonts/montserrat/Montserrat-ThinItalic.ttf added

Inline diff hidden to keep this page fast.

public/fonts/road_rage/Road_Rage.otf added

Inline diff hidden to keep this page fast.

public/img/.DS_Store added

Inline diff hidden to keep this page fast.

public/img/boxart/test1jpg.jpg added

Inline diff hidden to keep this page fast.

public/img/boxart/test2.jpg added

Inline diff hidden to keep this page fast.

public/img/boxart/test3.jpg added

Inline diff hidden to keep this page fast.

public/img/boxart/test4.jpg added

Inline diff hidden to keep this page fast.

public/img/down_arrow.svg added

Inline diff hidden to keep this page fast.

public/img/lines.svg added

Inline diff hidden to keep this page fast.

public/img/logo.svg added

Inline diff hidden to keep this page fast.

public/img/logomark.svg added

Inline diff hidden to keep this page fast.

public/img/sharkkmark.svg added

Inline diff hidden to keep this page fast.

public/img/sharkmark.svg added

Inline diff hidden to keep this page fast.

public/img/slides/test1.jpg added

Inline diff hidden to keep this page fast.

public/img/slides/test2.jpg added

Inline diff hidden to keep this page fast.

public/img/slides/test3.jpg added

Inline diff hidden to keep this page fast.

public/img/slides/test4.jpg added

Inline diff hidden to keep this page fast.

public/img/works/testheader1.jpg added

Inline diff hidden to keep this page fast.

public/index.html added

Inline diff hidden to keep this page fast.

public/js/blog-index.js added

Inline diff hidden to keep this page fast.

public/js/markdown-editor.js added

Inline diff hidden to keep this page fast.

public/js/nav-dropdown.js added

Inline diff hidden to keep this page fast.

public/legal/index.html added

Inline diff hidden to keep this page fast.

public/privacy/index.html added

Inline diff hidden to keep this page fast.

public/work/ashbringer/index.html added

Inline diff hidden to keep this page fast.

public/work/battles-for-arthos/index.html added

Inline diff hidden to keep this page fast.

public/work/index.html added

Inline diff hidden to keep this page fast.

public/work/legendarium/index.html added

Inline diff hidden to keep this page fast.

public/work/mad-splash/index.html added

Inline diff hidden to keep this page fast.

public/work/planes-of-power/index.html added

Inline diff hidden to keep this page fast.

public/work/project-1/index.html added

Inline diff hidden to keep this page fast.

src/helpers.php added

Inline diff hidden to keep this page fast.

src/pages/about.php added

Inline diff hidden to keep this page fast.

src/pages/blog.php added

Inline diff hidden to keep this page fast.

src/pages/home.php added

Inline diff hidden to keep this page fast.

src/pages/legal.php added

Inline diff hidden to keep this page fast.

src/pages/privacy.php added

Inline diff hidden to keep this page fast.

src/pages/work.php added

Inline diff hidden to keep this page fast.

src/site.php added

Inline diff hidden to keep this page fast.

src/templates/layout.php added

Inline diff hidden to keep this page fast.

src/templates/partials/blog-card.php added

Inline diff hidden to keep this page fast.

src/templates/partials/blog-index.php added

Inline diff hidden to keep this page fast.

src/templates/partials/blog-post.php added

Inline diff hidden to keep this page fast.

src/templates/partials/boxart-grid.php added

Inline diff hidden to keep this page fast.

src/templates/partials/boxart-item.php added

Inline diff hidden to keep this page fast.

src/templates/partials/button-list.php added

Inline diff hidden to keep this page fast.

src/templates/partials/centered-page.php added

Inline diff hidden to keep this page fast.

src/templates/partials/chevron.php added

Inline diff hidden to keep this page fast.

src/templates/partials/comments.php added

Inline diff hidden to keep this page fast.

src/templates/partials/detail-card-list.php added

Inline diff hidden to keep this page fast.

src/templates/partials/footer.php added

Inline diff hidden to keep this page fast.

src/templates/partials/header.php added

Inline diff hidden to keep this page fast.

src/templates/partials/home.php added

Inline diff hidden to keep this page fast.

src/templates/partials/markdown-editor.php added

Inline diff hidden to keep this page fast.

src/templates/partials/nav.php added

Inline diff hidden to keep this page fast.

src/templates/partials/project.php added

Inline diff hidden to keep this page fast.

src/templates/partials/simple-page.php added

Inline diff hidden to keep this page fast.

src/templates/partials/slider.php added

Inline diff hidden to keep this page fast.

src/templates/partials/work-card.php added

Inline diff hidden to keep this page fast.

src/templates/partials/work-dropdown.php added

Inline diff hidden to keep this page fast.

src/templates/partials/work-grid.php added

Inline diff hidden to keep this page fast.

src/templates/partials/work-index.php added

Inline diff hidden to keep this page fast.