Replace svelte template with 11ty blog template

This commit is contained in:
nk 2025-08-27 23:45:38 +03:00
parent bb57273c03
commit 5a3f47dee1
49 changed files with 3781 additions and 2891 deletions

9
.editorconfig Normal file
View file

@ -0,0 +1,9 @@
root = true
[*]
indent_style = tab
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
charset = utf-8

1
.gitattributes vendored Normal file
View file

@ -0,0 +1 @@
content/feed/pretty-atom-feed.xsl linguist-vendored

26
.gitignore vendored
View file

@ -1,23 +1,3 @@
node_modules
# Output
.output
.vercel
.netlify
.wrangler
/.svelte-kit
/build
# OS
.DS_Store
Thumbs.db
# Env
.env
.env.*
!.env.example
!.env.test
# Vite
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
_site/
node_modules/
.cache

1
.npmrc
View file

@ -1 +0,0 @@
engine-strict=true

1
.nvmrc Normal file
View file

@ -0,0 +1 @@
20

View file

@ -1,9 +0,0 @@
# Package Managers
package-lock.json
pnpm-lock.yaml
yarn.lock
bun.lock
bun.lockb
# Miscellaneous
/static/

View file

@ -1,15 +0,0 @@
{
"useTabs": true,
"singleQuote": true,
"trailingComma": "none",
"printWidth": 100,
"plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"],
"overrides": [
{
"files": "*.svelte",
"options": {
"parser": "svelte"
}
}
]
}

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 20172024 Zach Leatherman @zachleat
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.

119
README.md
View file

@ -1,8 +1,117 @@
Otomata Labs' site.
# eleventy-base-blog v9
Use pnpm to install dependencies and run the project locally.
A starter repository showing how to build a blog with the [Eleventy](https://www.11ty.dev/) site generator (using the [v3.0 release](https://github.com/11ty/eleventy/releases/tag/v3.0.0)).
## Getting Started
* [Want a more generic/detailed getting started guide?](https://www.11ty.dev/docs/getting-started/)
1. Make a directory and navigate to it:
```bash
pnpm install
pnpm run dev
```
mkdir my-blog-name
cd my-blog-name
```
2. Clone this Repository
```
git clone https://github.com/11ty/eleventy-base-blog.git .
```
_Optional:_ Review `eleventy.config.js` and `_data/metadata.js` to configure the sites options and data.
3. Install dependencies
```
npm install
```
4. Run Eleventy
Generate a production-ready build to the `_site` folder:
```
npx @11ty/eleventy
```
Or build and host on a local development server:
```
npx @11ty/eleventy --serve
```
Or you can run [debug mode](https://www.11ty.dev/docs/debugging/) to see all the internals.
## Features
- Using [Eleventy v3](https://github.com/11ty/eleventy/releases/tag/v3.0.0) with zero-JavaScript output.
- Content is exclusively pre-rendered (this is a static site).
- Can easily [deploy to a subfolder without changing any content](https://www.11ty.dev/docs/plugins/html-base/)
- All URLs are decoupled from the contents location on the file system.
- Configure templates via the [Eleventy Data Cascade](https://www.11ty.dev/docs/data-cascade/)
- **Performance focused**: four-hundos Lighthouse score out of the box!
- _0 Cumulative Layout Shift_
- _0ms Total Blocking Time_
- Local development live reload provided by [Eleventy Dev Server](https://www.11ty.dev/docs/dev-server/).
- Content-driven [navigation menu](https://www.11ty.dev/docs/plugins/navigation/)
- Fully automated [Image optimization](https://www.11ty.dev/docs/plugins/image/)
- Zero-JavaScript output.
- Support for modern image formats automatically (e.g. AVIF and WebP)
- Processes images on-request during `--serve` for speedy local builds.
- Prefers `<img>` markup if possible (single image format) but switches automatically to `<picture>` for multiple image formats.
- Automated `<picture>` syntax markup with `srcset` and optional `sizes`
- Includes `width`/`height` attributes to avoid [content layout shift](https://web.dev/cls/).
- Includes `loading="lazy"` for native lazy loading without JavaScript.
- Includes [`decoding="async"`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/decoding)
- Images can be co-located with blog post files.
- Per page CSS bundles [via `eleventy-plugin-bundle`](https://github.com/11ty/eleventy-plugin-bundle).
- Built-in [syntax highlighter](https://www.11ty.dev/docs/plugins/syntaxhighlight/) (zero-JavaScript output).
- Draft content: use `draft: true` to mark any template as a draft. Drafts are **only** included during `--serve`/`--watch` and are excluded from full builds. This is driven by the `addPreprocessor` configuration API in `eleventy.config.js`. Schema validator will show an error if non-boolean value is set in data cascade.
- Blog Posts
- Automated next/previous links
- Accessible deep links to headings
- Generated Pages
- Home, Archive, and About pages.
- [Atom feed included (with easy one-line swap to use RSS or JSON)](https://www.11ty.dev/docs/plugins/rss/)
- `sitemap.xml`
- Zero-maintenance tag pages ([View on the Demo](https://eleventy-base-blog.netlify.app/tags/))
- Content not found (404) page
## Demos
- [Netlify](https://eleventy-base-blog.netlify.app/)
- [Vercel](https://demo-base-blog.11ty.dev/)
- [Cloudflare Pages](https://eleventy-base-blog-d2a.pages.dev/)
- [Remix on Glitch](https://glitch.com/~11ty-eleventy-base-blog)
- [GitHub Pages](https://11ty.github.io/eleventy-base-blog/)
## Deploy this to your own site
Deploy this Eleventy site in just a few clicks on these services:
- Read more about [Deploying an Eleventy project](https://www.11ty.dev/docs/deployment/) to the web.
- [Deploy this to **Netlify**](https://app.netlify.com/start/deploy?repository=https://github.com/11ty/eleventy-base-blog)
- [Deploy this to **Vercel**](https://vercel.com/import/project?template=11ty%2Feleventy-base-blog)
- Look in `.github/workflows/gh-pages.yml.sample` for information on [Deploying to **GitHub Pages**](https://www.11ty.dev/docs/deployment/#deploy-an-eleventy-project-to-git-hub-pages).
- [Try it out on **Stackblitz**](https://stackblitz.com/github/11ty/eleventy-base-blog)
### Implementation Notes
- `content/about/index.md` is an example of a content page.
- `content/blog/` has the blog posts but really they can live in any directory. They need only the `posts` tag to be included in the blog posts [collection](https://www.11ty.dev/docs/collections/).
- Use the `eleventyNavigation` key (via the [Eleventy Navigation plugin](https://www.11ty.dev/docs/plugins/navigation/)) in your front matter to add a template to the top level site navigation. This is in use on `content/index.njk` and `content/about/index.md`.
- Content can be in _any template format_ (blog posts neednt exclusively be markdown, for example). Configure your projects supported templates in `eleventy.config.js` -> `templateFormats`.
- The `public` folder in your input directory will be copied to the output folder (via `addPassthroughCopy` in the `eleventy.config.js` file). This means `./public/css/*` will live at `./_site/css/*` after your build completes.
- This project uses three [Eleventy Layouts](https://www.11ty.dev/docs/layouts/):
- `_includes/layouts/base.njk`: the top level HTML structure
- `_includes/layouts/home.njk`: the home page template (wrapped into `base.njk`)
- `_includes/layouts/post.njk`: the blog post template (wrapped into `base.njk`)
- `_includes/postslist.njk` is a Nunjucks include and is a reusable component used to display a list of all the posts. `content/index.njk` has an example of how to use it.
#### Content Security Policy
If your site enforces a [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) (as public-facing sites should), you have a few choices (pick one):
1. In `base.njk`, remove `<style>{% getBundle "css" %}</style>` and uncomment `<link rel="stylesheet" href="{% getBundleFileUrl "css" %}">`
2. Configure the server with the CSP directive `style-src: 'unsafe-inline'` (less secure).

43
_config/filters.js Normal file
View file

@ -0,0 +1,43 @@
import { DateTime } from "luxon";
export default function(eleventyConfig) {
eleventyConfig.addFilter("readableDate", (dateObj, format, zone) => {
// Formatting tokens for Luxon: https://moment.github.io/luxon/#/formatting?id=table-of-tokens
return DateTime.fromJSDate(dateObj, { zone: zone || "utc" }).toFormat(format || "dd LLLL yyyy");
});
eleventyConfig.addFilter("htmlDateString", (dateObj) => {
// dateObj input: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-date-string
return DateTime.fromJSDate(dateObj, { zone: "utc" }).toFormat('yyyy-LL-dd');
});
// Get the first `n` elements of a collection.
eleventyConfig.addFilter("head", (array, n) => {
if(!Array.isArray(array) || array.length === 0) {
return [];
}
if( n < 0 ) {
return array.slice(n);
}
return array.slice(0, n);
});
// Return the smallest number argument
eleventyConfig.addFilter("min", (...numbers) => {
return Math.min.apply(null, numbers);
});
// Return the keys used in an object
eleventyConfig.addFilter("getKeys", target => {
return Object.keys(target);
});
eleventyConfig.addFilter("filterTagList", function filterTagList(tags) {
return (tags || []).filter(tag => ["all", "posts"].indexOf(tag) === -1);
});
eleventyConfig.addFilter("sortAlphabetically", strings =>
(strings || []).sort((b, a) => b.localeCompare(a))
);
};

View file

@ -0,0 +1,13 @@
import { z } from "zod";
import { fromZodError } from 'zod-validation-error';
export default function(data) {
// Draft content, validate `draft` front matter
let result = z.object({
draft: z.boolean().or(z.undefined()),
}).safeParse(data);
if(result.error) {
throw fromZodError(result.error);
}
}

6
_data/metadata.js Normal file
View file

@ -0,0 +1,6 @@
export default {
title: "Otomata Labs",
url: "https://otomatalabs.net/",
language: "en",
description: "Pushing old computers to their limits.",
}

View file

@ -0,0 +1,75 @@
<!doctype html>
<html lang="{{ metadata.language }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/png" sizes="32x32" href="{{ path }}/favicon.png">
<title>{{ title or metadata.title }}</title>
<meta name="description" content="{{ description or metadata.description }}">
<link rel="alternate" href="/feed/feed.xml" type="application/atom+xml" title="{{ metadata.title }}">
{#- Uncomment this if youd like folks to know that you used Eleventy to build your site! #}
{#- <meta name="generator" content="{{ eleventy.generator }}"> #}
{#-
Plain-text bundles are provided via the `eleventy-plugin-bundle` plugin:
1. CSS:
* Add to a per-page bundle using `{% css %}{% endcss %}`
* Retrieve bundle content using `{% getBundle "css" %}` or `{% getBundleFileUrl "css" %}`
2. Or for JavaScript:
* Add to a per-page bundle using `{% js %}{% endjs %}`
* Retrieve via `{% getBundle "js" %}` or `{% getBundleFileUrl "js" %}`
3. Learn more: https://github.com/11ty/eleventy-plugin-bundle
#}
{#- Add CSS to the bundle #}
<style>/* This is an arbitrary CSS string added to the bundle */</style>
{#- Add the contents of a file to the bundle #}
<style>{% include "css/index.css" %}</style>
{#- Or you can add from node_modules #}
{# <style>{% include "node_modules/something.css" %}</style> #}
{#- Render the CSS bundle using inlined CSS (for the fastest site performance in production) #}
<style>{% getBundle "css" %}</style>
{#- Renders the CSS bundle using a separate file, if you can't set CSP directive style-src: 'unsafe-inline' #}
{#- <link rel="stylesheet" href="{% getBundleFileUrl "css" %}"> #}
{#- Add the heading-anchors web component to the JavaScript bundle #}
<script type="module">{% include "node_modules/@zachleat/heading-anchors/heading-anchors.js" %}</script>
</head>
<body>
<a href="#main" id="skip-link" class="visually-hidden">Skip to main content</a>
<header>
<a href="/" class="home-link"><img class="logo" src="{{ path }}/res/otomata_labs.svg" alt="{{ metadata.title }}"></a>
{#- Read more about `eleventy-navigation` at https://www.11ty.dev/docs/plugins/navigation/ #}
<nav>
<h2 class="visually-hidden">Top level navigation menu</h2>
<ul class="nav">
{%- for entry in collections.all | eleventyNavigation %}
<li class="nav-item"><a href="{{ entry.url }}"{% if entry.url == page.url %} aria-current="page"{% endif %}>{{ entry.title }}</a></li>
{%- endfor %}
</ul>
</nav>
</header>
<main id="main">
<heading-anchors>
{{ content | safe }}
</heading-anchors>
</main>
<footer>
<p>
<em>Built with <a href="https://www.11ty.dev/">{{ eleventy.generator }}</a></em>
</p>
</footer>
<!-- This page `{{ page.url }}` was built on {% currentBuildDate %} -->
<script type="module" src="{% getBundleFileUrl "js" %}"></script>
</body>
</html>

View file

@ -0,0 +1,5 @@
---
layout: layouts/base.njk
---
{{ content | safe }}

View file

@ -0,0 +1,28 @@
---
layout: layouts/base.njk
---
{# Only include the syntax highlighter CSS on blog posts, included with the CSS per-page bundle #}
<style>{% include "node_modules/prismjs/themes/prism-okaidia.css" %}</style>
<style>{% include "css/prism-diff.css" %}</style>
<h1>{{ title }}</h1>
<ul class="post-metadata">
<li><time datetime="{{ page.date | htmlDateString }}">{{ page.date | readableDate }}</time></li>
{%- for tag in tags | filterTagList %}
{%- set tagUrl %}/tags/{{ tag | slugify }}/{% endset %}
<li><a href="{{ tagUrl }}" class="post-tag">{{ tag }}</a>{%- if not loop.last %}, {% endif %}</li>
{%- endfor %}
</ul>
{{ content | safe }}
{%- if collections.posts %}
{%- set previousPost = collections.posts | getPreviousCollectionItem %}
{%- set nextPost = collections.posts | getNextCollectionItem %}
{%- if nextPost or previousPost %}
<ul class="links-nextprev">
{%- if previousPost %}<li class="links-nextprev-prev">← Previous<br> <a href="{{ previousPost.url }}">{{ previousPost.data.title }}</a></li>{% endif %}
{%- if nextPost %}<li class="links-nextprev-next">Next →<br><a href="{{ nextPost.url }}">{{ nextPost.data.title }}</a></li>{% endif %}
</ul>
{%- endif %}
{%- endif %}

8
_includes/postslist.njk Normal file
View file

@ -0,0 +1,8 @@
<ol reversed class="postlist" style="--postlist-index: {{ (postslistCounter or postslist.length) + 1 }}">
{%- for post in postslist | reverse %}
<li class="postlist-item{% if post.url == url %} postlist-item-active{% endif %}">
<a href="{{ post.url }}" class="postlist-link">{% if post.data.title %}{{ post.data.title }}{% else %}<code>{{ post.url }}</code>{% endif %}</a>
<time class="postlist-date" datetime="{{ post.date | htmlDateString }}">{{ post.date | readableDate("LLLL yyyy") }}</time>
</li>
{%- endfor %}
</ol>

20
content/404.md Normal file
View file

@ -0,0 +1,20 @@
---
permalink: 404.html
eleventyExcludeFromCollections: true
---
# Content not found.
Go <a href="index.njk">home</a>.
<!--
Read more: https://www.11ty.dev/docs/quicktips/not-found/
This is compatible with:
- GitHub Pages: https://help.github.com/articles/creating-a-custom-404-page-for-your-github-pages-site/
- GitLab Pages: https://docs.gitlab.com/ee/user/project/pages/introduction.html#custom-error-codes-pages
- Netlify: https://www.netlify.com/docs/redirects/#custom-404
- Cloudflare Pages: https://developers.cloudflare.com/pages/platform/serving-pages/#not-found-behavior
- Vercel: https://vercel.com/guides/custom-404-page#static-site-generator-ssg
-->

9
content/about.md Normal file
View file

@ -0,0 +1,9 @@
---js
const eleventyNavigation = {
key: "ABOUT",
order: 3
};
---
# About
TODO: Write a description about Otomata Labs

10
content/blog.njk Normal file
View file

@ -0,0 +1,10 @@
---js
const eleventyNavigation = {
key: "ARCHIVE",
order: 2
};
---
<h1>Archive</h1>
{% set postslist = collections.posts %}
{% include "postslist.njk" %}

View file

@ -0,0 +1,18 @@
---js
const title = "Example blog";
const description = "Example description";
const date = "2025-08-27";
const tags = ["example tag", "another example tag", "demoscene"];
const draft = true;
---
# Example header
This post is a draft. You shouldn't see this post in the final build of the website.
## Header 2
Lorem ipsum. This is an example of a blog post. What more can I say?
Well, here is a [link to MOVE 10 STEPS](https://www.pouet.net/prod.php?which=104866).
It takes you to pouet. Wooooahh.
Here is a picture!
<img alt="A screenshot of MOVE 10 STEPS" src="https://content.pouet.net/files/screenshots/00104/00104866.png">

View file

@ -0,0 +1,6 @@
export default {
tags: [
"posts"
],
"layout": "layouts/post.njk",
};

View file

@ -0,0 +1,3 @@
export default {
layout: "layouts/home.njk",
};

89
content/feed/pretty-atom-feed.xsl vendored Normal file

File diff suppressed because one or more lines are too long

29
content/index.njk Normal file
View file

@ -0,0 +1,29 @@
---js
const eleventyNavigation = {
key: "HOME",
order: 1
};
const numberOfLatestPostsToShow = 10;
---
{% set postsCount = collections.posts | length %}
{% set latestPostsCount = postsCount | min(numberOfLatestPostsToShow) %}
<h1>Latest {{ latestPostsCount }} Post{% if latestPostsCount != 1 %}s{% endif %}</h1>
{% set postslist = collections.posts | head(-1 * numberOfLatestPostsToShow) %}
{% set postslistCounter = postsCount %}
{% include "postslist.njk" %}
{% set morePosts = postsCount - numberOfLatestPostsToShow %}
{% if morePosts > 0 %}
<p>{{ morePosts }} more post{% if morePosts != 1 %}s{% endif %} can be found in <a href="blog.njk">the archive</a>.</p>
{% endif %}
{# List every content page in the project #}
{#
<ul>
{%- for entry in collections.all %}
<li><a href="{{ entry.url }}"><code>{{ entry.url }}</code></a></li>
{%- endfor %}
</ul>
#}

View file

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="505"
height="94"
viewBox="0 0 505.00001 94.000002"
version="1.1"
id="svg5"
xml:space="preserve"
sodipodi:docname="otomata_labs.svg"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#999999"
borderopacity="1"
inkscape:showpageshadow="2"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="1.4142136"
inkscape:cx="243.95184"
inkscape:cy="-9.5459415"
inkscape:window-width="1366"
inkscape:window-height="736"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg5"><inkscape:grid
id="grid1"
units="px"
originx="10"
originy="10"
spacingx="1"
spacingy="1"
empcolor="#0099e5"
empopacity="0.30196078"
color="#0099e5"
opacity="0.14901961"
empspacing="5"
enabled="true"
visible="false" /></sodipodi:namedview><defs
id="defs2" /><path
id="rect1"
style="fill:#000000;fill-opacity:1;stroke-width:7.48968;stroke-linecap:round;stroke-linejoin:round"
d="M 0,2.9999999 4.0594023e-8,90.999998 2.9999999,93.999998 315,94 v -4 h 5 v -5 h 15 v -5 h -5 v -5 h 5 v -5 h 15 v -5 h -5 v -5 h 15 v -5 h -5 v -5 h 5 v -5 h 15 v -5 h -5 v -5 h 5 v -5 h 5 v -5 h 15 v -5 h -5 v -5 h 15 v -5 h -5 V 5 h 5 V 0 H 2.9999999 Z M 13.996094,11.003906 H 26 L 28.996094,14 V 80.011718 L 26,83.007812 H 13.996094 L 11,80.011718 V 14 Z m 21.011718,0 h 17.996094 v 5.992188 H 47.011719 V 83.007812 H 41 V 16.996094 h -5.992188 z m 27.003907,0 H 73.996094 L 77.011719,14 v 66.011718 l -3.015625,2.996094 H 62.011719 L 58.996094,80.011718 V 14 Z m 23.988281,0 h 17.99609 L 107.01172,14 v 66.011718 2.996094 H 101 V 80.011718 16.996094 h -2.996094 v 30 h -5.992187 v -30 h -3.015625 v 63.015624 2.996094 H 83.003906 V 80.011718 14 Z m 30,0 h 12.00391 L 131,14 v 66.011718 2.996094 h -5.99219 V 80.011718 46.996094 h -6.01172 v 33.015624 2.996094 h -5.99218 V 80.011718 14 Z m 21.01172,0 h 17.99609 v 5.992188 h -6.01172 v 63.015624 2.996094 h -5.99218 V 80.011718 16.996094 h -5.99219 z m 26.98437,0 H 176 L 178.99609,14 v 69.007812 h -5.99218 V 46.996094 h -5.99219 V 83.007812 H 161 V 14 Z m 45,0 h 6.01172 v 65.992188 h 12.00391 v 6.011718 h -15 l -3.01563,-2.996094 z m 27.00391,0 h 12.00391 L 251,14 v 69.007812 h -5.99219 V 46.996094 h -6.01172 v 36.011718 h -5.99218 V 14 Z m 21.01172,0 h 15 L 275.00781,14 l -0.004,27.003906 -3,3 3,2.996094 0.004,33.011718 -2.99609,2.996094 h -15 z m 26.98437,0 h 15 v 5.992188 H 287.01172 V 41.003906 H 296 L 298.99609,44 V 80.011718 L 296,83.007812 h -15 v -6.011718 h 12.00391 v -30 h -9.00782 L 281,44 V 14 Z M 415,10 v 5 h 5 v -5 z m 40,0 v 5 h 5 v -5 z m 25,5 v 5 h 5 V 15 Z M 17.011719,16.996094 v 60 h 5.992187 v -60 z m 47.996093,0 v 60 H 71 v -60 z m 53.988278,0 v 24.007812 h 6.01172 V 16.996094 Z m 48.01563,0 v 24.007812 h 5.99219 V 16.996094 Z m 71.98437,0 v 24.007812 h 6.01172 V 16.996094 Z m 24.00782,0 v 24.007812 h 5.99218 V 16.996094 Z M 400,20 v 10 h 10 V 20 Z m 40,0 v 5 h 5 v -5 z m 60,5 v 5 h 5 v -5 z m -70,5 v 5 h 5 v -5 z m 20,0 v 10 h 10 V 30 Z m -70,5 v 5 h 5 v -5 z m 25,0 v 5 h 5 v -5 z m 70,0 v 5 h 5 v -5 z m -85,5 v 5 h 5 v -5 z m 100,0 v 5 h 5 v -5 z m -60,5 v 10 h 10 V 45 Z m 15,0 v 5 h 5 v -5 z m -181.99609,1.996094 v 30 h 5.99218 v -30 z M 375,50 v 5 h 5 v -5 z m 40,0 v 5 h 5 v -5 z m 35,5 v 5 h 5 v -5 z m -60,5 v 5 h 5 v -5 z m 30,0 v 5 h 5 v -5 z m -65,5 v 5 h 5 v -5 z m 10,0 v 10 h 10 V 65 Z m 70,0 v 5 h 5 v -5 z m 20,0 v 5 h 5 v -5 z m 15,0 v 5 h 5 v -5 z m -65,5 v 5 h -5 v 19 h 20 V 75 70 h -5 v 5 h -5 v -5 z m -65,5 v 15 h 15 V 75 Z m 50,0 v 5 h 5 v -5 z m 50,0 v 5 h 5 v -5 z m -60,10 v 9 h 10 v -9 z m 65,0 v 5 h 5 v -5 z m -115,5 v 4 h 5 v -4 z m 100,0 v 4 h 5 v -4 z m 30,0 v 4 h 5 v -4 z"
sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" /></svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

17
content/sitemap.xml.njk Normal file
View file

@ -0,0 +1,17 @@
---
permalink: /sitemap.xml
layout: false
eleventyExcludeFromCollections: true
---
<?xml version="1.0" encoding="utf-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
{%- for page in collections.all %}
{% if page.data.permalink != false %}
{% set absoluteUrl %}{{ page.url | htmlBaseUrl(metadata.url) }}{% endset %}
<url>
<loc>{{ absoluteUrl }}</loc>
<lastmod>{{ page.date | htmlDateString }}</lastmod>
</url>
{% endif %}
{%- endfor %}
</urlset>

27
content/tag-pages.njk Normal file
View file

@ -0,0 +1,27 @@
---js
// <script>
const pagination = {
data: "collections",
size: 1,
alias: "tag",
filter: ["all", "posts"],
// addAllPagesToCollections: true,
};
const eleventyExcludeFromCollections = true;
const eleventyComputed = {
title: "Tagged '{{ tag }}'",
permalink: function(data) {
// If DuplicatePermalinkOutputError occurs, check that no tag occurs
// with differing case, e.g. "RSS" and "rss".
return `/tags/${this.slugify(data.tag)}/`;
}
};
---
<h1>Tagged “{{ tag }}”</h1>
{% set postslist = collections[ tag ] %}
{% include "postslist.njk" %}
<p>See <a href="tags.njk">all tags</a>.</p>

8
content/tags.njk Normal file
View file

@ -0,0 +1,8 @@
<h1>Tags</h1>
<ul>
{% for tag in collections | getKeys | filterTagList | sortAlphabetically %}
{% set tagUrl %}/tags/{{ tag | slugify }}/{% endset %}
<li><a href="{{ tagUrl }}" class="post-tag">{{ tag }}</a></li>
{% endfor %}
</ul>

314
css/index.css Normal file
View file

@ -0,0 +1,314 @@
@font-face{
font-family: "Mister Twiggs W01 Heavy";
src: url("{{ path }}/MisterTwiggsHeavy.woff2")format("woff2");
font-weight: normal;
font-style: normal;
font-display: swap;
}
/* Defaults */
:root {
--font-family: sans-serif;
}
/* Theme colors */
:root {
--color-gray-20: #eee;
--color-gray-50: #ccc;
--color-gray-90: #333;
--background-color: #eee;
--body-color: #fff;
--text-color: var(--color-gray-90);
--text-color-link: #ff2121;
--text-color-link-active: #ff5959;
--text-color-link-visited: #000;
--syntax-tab-size: 2;
}
@media (prefers-color-scheme: dark) {
:root {
--color-gray-20: #eee;
--color-gray-50: #ccc;
--color-gray-90: #dad8d8;
/* --text-color is assigned to --color-gray-_ above */
--text-color-link: #ff3939;
--text-color-link-active: #ff7979;
--text-color-link-visited: #fff;
--background-color: #222;
--body-color: #111;
}
.logo {
filter: invert(100%);
}
}
/* Global stylesheet */
* {
box-sizing: border-box;
}
html,
body {
padding: 15px;
margin: 0 auto;
font-family: var(--font-family);
color: var(--text-color);
background-color: var(--background-color);
}
html {
overflow-y: scroll;
background-image: url("{{ path }}/otomata_labs_tile.svg");
background-blend-mode: difference;
}
body {
max-width: 75%;
background-color: var(--body-color);
border: 2px dashed var(--color-gray-90);
}
/* https://www.a11yproject.com/posts/how-to-hide-content/ */
.visually-hidden:not(:focus):not(:active) {
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
/* Fluid images via https://www.zachleat.com/web/fluid-images/ */
img{
max-width: 100%;
}
img[width][height] {
height: auto;
}
img[src$=".svg"] {
width: 100%;
height: auto;
max-width: none;
}
video,
iframe {
width: 100%;
height: auto;
}
iframe {
aspect-ratio: 16/9;
}
p:last-child {
margin-bottom: 0;
}
p {
line-height: 1.5;
}
li {
line-height: 1.5;
}
a[href] {
color: var(--text-color-link);
}
a[href]:visited {
color: var(--text-color-link-visited);
}
a[href]:hover,
a[href]:active {
color: var(--text-color-link-active);
}
main,
footer {
padding: 1rem;
}
main :first-child {
margin-top: 0;
}
header {
border-bottom: 2px dashed var(--color-gray-20);
}
#skip-link {
text-decoration: none;
background: var(--background-color);
color: var(--text-color);
padding: 0.5rem 1rem;
border: 1px solid var(--color-gray-90);
border-radius: 2px;
}
/* Prevent visually-hidden skip link fom pushing content around when focused */
#skip-link.visually-hidden:focus {
position: absolute;
top: 1rem;
left: 1rem;
/* Ensure it is positioned on top of everything else when it is shown */
z-index: 999;
}
.links-nextprev {
display: flex;
justify-content: space-between;
gap: .5em 1em;
list-style: "";
border-top: 1px dashed var(--color-gray-20);
padding: 1em 0;
}
.links-nextprev > * {
flex-grow: 1;
}
.links-nextprev-next {
text-align: right;
}
table {
margin: 1em 0;
}
table td,
table th {
padding-right: 1em;
}
pre,
code {
font-family: monospace;
}
pre:not([class*="language-"]) {
margin: .5em 0;
line-height: 1.375; /* 22px /16 */
-moz-tab-size: var(--syntax-tab-size);
-o-tab-size: var(--syntax-tab-size);
tab-size: var(--syntax-tab-size);
-webkit-hyphens: none;
-ms-hyphens: none;
hyphens: none;
direction: ltr;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
overflow-x: auto;
}
code {
word-break: break-all;
}
/* Header */
header {
font-size: 32pt;
font-family: "Mister Twiggs W01 Heavy";
display: flex;
gap: 5px;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
padding: 5px;
}
.home-link {
flex-grow: 1;
font-size: 1em; /* 16px /16 */
font-weight: 700;
}
.home-link:link:not(:hover) {
text-decoration: none;
}
/* Nav */
.nav {
display: flex;
gap: .5em 1em;
padding: 0;
margin: 0;
list-style: none;
}
.nav-item {
display: inline-block;
}
.nav-item a[href]:not(:hover) {
text-decoration: none;
}
.nav a[href][aria-current="page"] {
text-decoration: underline;
}
/* Posts list */
.postlist {
counter-reset: start-from var(--postlist-index);
list-style: none;
padding: 0;
padding-left: 1.5rem;
}
.postlist-item {
display: flex;
flex-wrap: wrap;
align-items: baseline;
counter-increment: start-from -1;
margin-bottom: 1em;
}
.postlist-item:before {
display: inline-block;
pointer-events: none;
content: "" counter(start-from, decimal-leading-zero) ". ";
line-height: 100%;
text-align: right;
margin-left: -1.5rem;
}
.postlist-date,
.postlist-item:before {
font-size: 0.8125em; /* 13px /16 */
color: var(--color-gray-90);
}
.postlist-date {
word-spacing: -0.5px;
}
.postlist-link {
font-size: 1.1875em; /* 19px /16 */
font-weight: 700;
flex-basis: calc(100% - 1.5rem);
padding-left: .25em;
padding-right: .5em;
text-underline-position: from-font;
text-underline-offset: 0;
text-decoration-thickness: 1px;
}
.postlist-item-active .postlist-link {
font-weight: bold;
}
/* Tags */
.post-tag {
display: inline-flex;
align-items: center;
justify-content: center;
text-transform: capitalize;
font-style: italic;
}
.postlist-item > .post-tag {
align-self: center;
}
/* Tags list */
.post-metadata {
display: inline-flex;
flex-wrap: wrap;
gap: .5em;
list-style: none;
padding: 0;
margin: 0;
}
.post-metadata time {
margin-right: 1em;
}

18
css/message-box.css Normal file
View file

@ -0,0 +1,18 @@
/* Message Box */
.message-box {
--color-message-box: #ffc;
display: block;
background-color: var(--color-message-box);
color: var(--color-gray-90);
padding: 1em 0.625em; /* 16px 10px /16 */
}
.message-box ol {
margin-top: 0;
}
@media (prefers-color-scheme: dark) {
.message-box {
--color-message-box: #082840;
}
}

45
css/prism-diff.css Normal file
View file

@ -0,0 +1,45 @@
/*
* New diff- syntax
*/
pre[class*="language-diff-"] {
--eleventy-code-padding: 1.25em;
padding-left: var(--eleventy-code-padding);
padding-right: var(--eleventy-code-padding);
}
.token.deleted {
background-color: hsl(0, 51%, 37%);
color: inherit;
}
.token.inserted {
background-color: hsl(126, 31%, 39%);
color: inherit;
}
/* Make the + and - characters unselectable for copy/paste */
.token.prefix.unchanged,
.token.prefix.inserted,
.token.prefix.deleted {
-webkit-user-select: none;
user-select: none;
display: inline-flex;
align-items: center;
justify-content: center;
padding-top: 2px;
padding-bottom: 2px;
}
.token.prefix.inserted,
.token.prefix.deleted {
width: var(--eleventy-code-padding);
background-color: rgba(0,0,0,.2);
}
/* Optional: full-width background color */
.token.inserted:not(.prefix),
.token.deleted:not(.prefix) {
display: block;
margin-left: calc(-1 * var(--eleventy-code-padding));
margin-right: calc(-1 * var(--eleventy-code-padding));
text-decoration: none; /* override del, ins, mark defaults */
color: inherit; /* override del, ins, mark defaults */
}

165
eleventy.config.js Normal file
View file

@ -0,0 +1,165 @@
import { IdAttributePlugin, InputPathToUrlTransformPlugin, HtmlBasePlugin } from "@11ty/eleventy";
import { feedPlugin } from "@11ty/eleventy-plugin-rss";
import pluginSyntaxHighlight from "@11ty/eleventy-plugin-syntaxhighlight";
import pluginNavigation from "@11ty/eleventy-navigation";
import { eleventyImageTransformPlugin } from "@11ty/eleventy-img";
import pluginFilters from "./_config/filters.js";
/** @param {import("@11ty/eleventy").UserConfig} eleventyConfig */
export default async function(eleventyConfig) {
// Drafts, see also _data/eleventyDataSchema.js
eleventyConfig.addPreprocessor("drafts", "*", (data, content) => {
if (data.draft) {
data.title = `${data.title} (draft)`;
}
if(data.draft && process.env.ELEVENTY_RUN_MODE === "build") {
return false;
}
});
// Copy the contents of the `public` folder to the output folder
// For example, `./public/css/` ends up in `_site/css/`
eleventyConfig
.addPassthroughCopy({
"./public/": "/"
})
.addPassthroughCopy("./content/feed/pretty-atom-feed.xsl");
// Run Eleventy when these files change:
// https://www.11ty.dev/docs/watch-serve/#add-your-own-watch-targets
// Watch CSS files
eleventyConfig.addWatchTarget("css/**/*.css");
// Watch images for the image pipeline.
eleventyConfig.addWatchTarget("content/**/*.{svg,webp,png,jpg,jpeg,gif}");
// Per-page bundles, see https://github.com/11ty/eleventy-plugin-bundle
// Bundle <style> content and adds a {% css %} paired shortcode
eleventyConfig.addBundle("css", {
toFileDirectory: "dist",
// Add all <style> content to `css` bundle (use <style eleventy:ignore> to opt-out)
// Supported selectors: https://www.npmjs.com/package/posthtml-match-helper
bundleHtmlContentFromSelector: "style",
});
// Bundle <script> content and adds a {% js %} paired shortcode
eleventyConfig.addBundle("js", {
toFileDirectory: "dist",
// Add all <script> content to the `js` bundle (use <script eleventy:ignore> to opt-out)
// Supported selectors: https://www.npmjs.com/package/posthtml-match-helper
bundleHtmlContentFromSelector: "script",
});
// Official plugins
eleventyConfig.addPlugin(pluginSyntaxHighlight, {
preAttributes: { tabindex: 0 }
});
eleventyConfig.addPlugin(pluginNavigation);
eleventyConfig.addPlugin(HtmlBasePlugin);
eleventyConfig.addPlugin(InputPathToUrlTransformPlugin);
eleventyConfig.addPlugin(feedPlugin, {
type: "atom", // or "rss", "json"
outputPath: "/feed/feed.xml",
stylesheet: "pretty-atom-feed.xsl",
templateData: {
eleventyNavigation: {
key: "FEED",
order: 4
}
},
collection: {
name: "posts",
limit: 10,
},
metadata: {
language: "en",
title: "Otomata Labs",
subtitle: "Pushing retro computers to their limits.",
base: "https://otomatalabs.net/",
}
});
// Image optimization: https://www.11ty.dev/docs/plugins/image/#eleventy-transform
eleventyConfig.addPlugin(eleventyImageTransformPlugin, {
// Output formats for each image.
formats: ["avif", "webp", "auto"],
// widths: ["auto"],
failOnError: false,
htmlOptions: {
imgAttributes: {
// e.g. <img loading decoding> assigned on the HTML tag will override these values.
loading: "lazy",
decoding: "async",
}
},
sharpOptions: {
animated: true,
},
});
// Filters
eleventyConfig.addPlugin(pluginFilters);
eleventyConfig.addPlugin(IdAttributePlugin, {
// by default we use Eleventys built-in `slugify` filter:
// slugify: eleventyConfig.getFilter("slugify"),
// selector: "h1,h2,h3,h4,h5,h6", // default
});
eleventyConfig.addShortcode("currentBuildDate", () => {
return (new Date()).toISOString();
});
// Features to make your build faster (when you need them)
// If your passthrough copy gets heavy and cumbersome, add this line
// to emulate the file copy on the dev server. Learn more:
// https://www.11ty.dev/docs/copy/#emulate-passthrough-copy-during-serve
// eleventyConfig.setServerPassthroughCopyBehavior("passthrough");
};
export const config = {
// Control which files Eleventy will process
// e.g.: *.md, *.njk, *.html, *.liquid
templateFormats: [
"md",
"njk",
"html",
"liquid",
"11ty.js",
],
// Pre-process *.md files with: (default: `liquid`)
markdownTemplateEngine: "njk",
// Pre-process *.html files with: (default: `liquid`)
htmlTemplateEngine: "njk",
// These are all optional:
dir: {
input: "content", // default: "."
includes: "../_includes", // default: "_includes" (`input` relative)
data: "../_data", // default: "_data" (`input` relative)
output: "_site"
},
// -----------------------------------------------------------------
// Optional items:
// -----------------------------------------------------------------
// If your site deploys to a subdirectory, change `pathPrefix`.
// Read more: https://www.11ty.dev/docs/config/#deploy-to-a-subdirectory-with-a-path-prefix
// When paired with the HTML <base> plugin https://www.11ty.dev/docs/plugins/html-base/
// it will transform any absolute URLs in your HTML to include this
// folder name and does **not** affect where things go in the output folder.
// pathPrefix: "/",
};

View file

@ -1,40 +0,0 @@
import prettier from 'eslint-config-prettier';
import { includeIgnoreFile } from '@eslint/compat';
import js from '@eslint/js';
import svelte from 'eslint-plugin-svelte';
import globals from 'globals';
import { fileURLToPath } from 'node:url';
import ts from 'typescript-eslint';
import svelteConfig from './svelte.config.js';
const gitignorePath = fileURLToPath(new URL('./.gitignore', import.meta.url));
export default ts.config(
includeIgnoreFile(gitignorePath),
js.configs.recommended,
...ts.configs.recommended,
...svelte.configs.recommended,
prettier,
...svelte.configs.prettier,
{
languageOptions: {
globals: { ...globals.browser, ...globals.node }
},
rules: {
// typescript-eslint strongly recommend that you do not use the no-undef lint rule on TypeScript projects.
// see: https://typescript-eslint.io/troubleshooting/faqs/eslint/#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors
'no-undef': 'off'
}
},
{
files: ['**/*.svelte', '**/*.svelte.ts', '**/*.svelte.js'],
languageOptions: {
parserOptions: {
projectService: true,
extraFileExtensions: ['.svelte'],
parser: ts.parser,
svelteConfig
}
}
}
);

2555
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,44 +1,52 @@
{
"name": "ol-site",
"private": true,
"version": "0.0.1",
"name": "eleventy-base-blog",
"version": "9.0.0",
"description": "A starter repository for a blog web site using the Eleventy site generator.",
"type": "module",
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"prepare": "svelte-kit sync || echo ''",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"format": "prettier --write .",
"lint": "prettier --check . && eslint ."
"build": "npx @11ty/eleventy",
"build-nocolor": "cross-env NODE_DISABLE_COLORS=1 npx @11ty/eleventy",
"build-ghpages": "npx @11ty/eleventy --pathprefix=/eleventy-base-blog/",
"start": "npx @11ty/eleventy --serve --quiet",
"start-ghpages": "npx @11ty/eleventy --pathprefix=/eleventy-base-blog/ --serve --quiet",
"debug": "cross-env DEBUG=Eleventy* npx @11ty/eleventy",
"debugstart": "cross-env DEBUG=Eleventy* npx @11ty/eleventy --serve --quiet",
"benchmark": "cross-env DEBUG=Eleventy:Benchmark* npx @11ty/eleventy"
},
"repository": {
"type": "git",
"url": "git://github.com/11ty/eleventy-base-blog.git"
},
"author": {
"name": "Zach Leatherman",
"email": "zachleatherman@gmail.com",
"url": "https://zachleat.com/"
},
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/11ty"
},
"bugs": {
"url": "https://github.com/11ty/eleventy-base-blog/issues"
},
"homepage": "https://github.com/11ty/eleventy-base-blog#readme",
"devDependencies": {
"@eslint/compat": "^1.2.5",
"@eslint/js": "^9.18.0",
"@sveltejs/adapter-auto": "^6.0.0",
"@sveltejs/kit": "^2.16.0",
"@sveltejs/vite-plugin-svelte": "^5.0.0",
"@tailwindcss/typography": "^0.5.15",
"@tailwindcss/vite": "^4.0.0",
"eslint": "^9.18.0",
"eslint-config-prettier": "^10.0.1",
"eslint-plugin-svelte": "^3.0.0",
"globals": "^16.0.0",
"mdsvex": "^0.12.3",
"prettier": "^3.4.2",
"prettier-plugin-svelte": "^3.3.3",
"prettier-plugin-tailwindcss": "^0.6.11",
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",
"tailwindcss": "^4.0.0",
"typescript": "^5.0.0",
"typescript-eslint": "^8.20.0",
"vite": "^6.2.6"
"@11ty/eleventy": "^3.1.2",
"@11ty/eleventy-img": "^6.0.4",
"@11ty/eleventy-navigation": "^1.0.4",
"@11ty/eleventy-plugin-rss": "^2.0.4",
"@11ty/eleventy-plugin-syntaxhighlight": "^5.0.1",
"cross-env": "^7.0.3",
"luxon": "^3.6.1",
"prismjs": "^1.30.0",
"zod": "^3.25.67",
"zod-validation-error": "^3.5.2"
},
"pnpm": {
"onlyBuiltDependencies": [
"esbuild"
]
"dependencies": {
"@zachleat/heading-anchors": "^1.0.3"
}
}

File diff suppressed because it is too large Load diff

Binary file not shown.

BIN
public/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 B

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="256"
height="256"
viewBox="0 0 256 256"
version="1.1"
id="svg5"
xml:space="preserve"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs2" /><path
d="m 32.001491,24.003531 c -2.20489,0.0029 -3.99159,1.789553 -3.99444,3.994438 -0.004,2.209967 1.78446,4.0046 3.99444,4.007459 h 9.19449 l -19.79252,16.956841 c -2.81947,2.418988 -1.10581,7.040044 2.60915,7.035832 h 3.99444 v 36.002038 c 0.003,2.20479 1.78964,3.99136 3.99444,3.99444 h 16.00379 c 2.20479,-0.003 3.99137,-1.78965 3.99444,-3.99444 V 52.003665 c 0.004,-2.209876 -1.78456,-4.004376 -3.99444,-4.00746 h -13.18634 l 19.78992,-16.956837 c 2.81948,-2.418992 1.10582,-7.040052 -2.60914,-7.035837 z m 32.00759,0 c -2.20997,-0.0045 -4.00461,1.784469 -4.00747,3.994438 -0.005,2.21506 1.79241,4.011807 4.00747,4.007459 h 3.99444 v 31.994574 h -3.99444 c -2.20997,-0.0045 -4.0046,1.784467 -4.00747,3.99444 -0.005,2.215056 1.79241,4.011809 4.00747,4.00746 h 3.99444 v 23.992677 h -3.99444 c -2.21506,-0.005 -4.01181,1.7924 -4.00747,4.007461 0.003,2.20997 1.7975,3.99877 4.00747,3.99443 h 7.98888 c 2.20987,0.004 4.00438,-1.78456 4.00745,-3.99443 V 72.001902 h 15.99078 v 28.000138 c 0.003,2.20997 1.797501,3.99877 4.007461,3.99443 2.20488,-0.003 3.99159,-1.78955 3.99444,-3.99443 V 72.001902 h 4.007468 c 2.20997,-0.0029 3.99877,-1.797496 3.99443,-4.00746 -0.003,-2.204884 -1.78955,-3.991585 -3.99443,-3.99444 H 99.998092 V 32.005428 h 4.007468 c 2.20997,-0.0029 3.99877,-1.797492 3.99443,-4.007459 -0.003,-2.204882 -1.78955,-3.991581 -3.99443,-3.994438 z m 11.99633,8.001897 h 15.99078 v 31.994574 h -15.99078 z m -39.99647,23.992673 h 8.00191 v 31.994578 h -8.00191 z"
style="color:#000000;fill:#333333;stroke-width:5.03891;stroke-linecap:square;stroke-linejoin:bevel;stroke-dashoffset:0.00000001;-inkscape-stroke:none;paint-order:stroke fill markers;fill-opacity:1"
id="path1-6" /><path
id="path1238"
style="color:#000000;fill:#333333;stroke-width:5.03912;stroke-linecap:square;stroke-linejoin:round;stroke-dashoffset:0.00000001;-inkscape-stroke:none;paint-order:stroke fill markers;fill-opacity:1"
d="M 155.99805 152.00195 C 152.44596 152.01265 150.66792 156.30283 153.17188 158.82227 L 186.33984 192 L 153.17188 225.16797 C 151.60852 226.73021 151.60852 229.26393 153.17188 230.82617 C 154.73323 232.38433 157.26287 232.38433 158.82422 230.82617 L 192.00195 197.64844 L 225.16797 230.82617 C 226.73021 232.38954 229.26588 232.38954 230.82812 230.82617 C 232.39148 229.26393 232.39148 226.73021 230.82812 225.16797 L 197.65039 192 L 230.82812 158.82227 C 233.33559 156.29925 231.5493 152.00327 227.99219 152.00195 L 155.99805 152.00195 z M 165.64258 159.99023 L 187.99414 159.99023 L 187.99609 182.33398 L 165.64258 159.99023 z M 195.99609 159.99023 L 218.3457 159.99023 L 195.99609 182.34375 L 195.99609 159.99023 z " /><path
d="m 192.00651,12.008884 c -2.2101,-0.0044 -4.00484,1.784574 -4.0077,3.994673 v 8.002368 h -31.99644 c -2.20501,0.0029 -3.99182,1.789661 -3.99468,3.994673 -0.004,2.210094 1.78459,4.004832 3.99468,4.007691 h 11.99704 V 48 h -11.99704 c -2.2101,0.0029 -3.99901,1.797601 -3.99468,4.007699 0.003,2.205011 1.78967,3.991813 3.99468,3.994669 h 71.99526 c 2.21009,0.0045 4.00483,-1.784567 4.00768,-3.994669 C 232.00931,49.792513 230.2128,47.995653 227.99763,48 H 216.00059 V 32.008289 h 11.99703 c 2.21518,0.0045 4.01203,-1.792505 4.00769,-4.007691 -0.003,-2.210104 -1.7976,-3.999009 -4.00769,-3.994673 h -31.99644 v -8.002368 c -0.003,-2.205012 -1.78966,-3.991817 -3.99467,-3.994673 z m -16.00473,19.999405 h 31.99643 V 48 h -31.99643 z m -3.99467,31.996446 c -2.21001,-0.004 -4.00462,1.784663 -4.0077,3.994669 v 32.009476 c 0.003,2.21 1.79769,3.99878 4.0077,3.99467 h 39.99881 c 2.20492,-0.003 3.99159,-1.78975 3.99467,-3.99467 V 67.999404 c -0.003,-2.204919 -1.78975,-3.991597 -3.99467,-3.994669 z m 3.99467,8.002368 h 31.99643 v 7.994077 h -32 z m -0.004,15.994073 h 32 v 8 h -31.99643 z"
style="color:#000000;fill:#333333;stroke-width:5.0392;stroke-linecap:square;stroke-linejoin:bevel;stroke-dashoffset:0.00000001;-inkscape-stroke:none;paint-order:stroke fill markers;fill-opacity:1"
id="path1" /><path
d="m 64.00335,140.00527 c -2.20991,0.003 -3.99866,1.79744 -3.99433,4.00735 v 8.00168 h -32.0067 c -2.20473,0.003 -3.99125,1.78959 -3.99433,3.99432 v 8.00168 c 0.003,2.20482 1.7895,3.99147 3.99433,3.99433 2.2099,0.004 4.00449,-1.78442 4.00734,-3.99433 v -4.00736 h 8.00168 v 24.00504 h -4.00735 c -2.20482,0.003 -3.99147,1.78951 -3.99433,3.99432 -0.005,2.20991 1.78443,4.0045 3.99433,4.00736 h 8.00168 c 2.20981,-0.003 3.99844,-1.79753 3.99433,-4.00736 v -27.99936 h 24.00503 v 27.99936 c -0.004,2.20983 1.78451,4.00428 3.99433,4.00736 h 16.003361 c 2.20981,-0.003 3.99843,-1.79753 3.99432,-4.00736 v -8.00167 c -0.003,-2.20483 -1.7895,-3.99147 -3.99432,-3.99433 -2.20991,-0.004 -4.004501,1.78442 -4.007361,3.99433 v 4.00735 h -7.98865 v -24.00504 h 15.990331 v 4.00736 c 0.003,2.20991 1.79744,3.99867 4.007349,3.99433 2.20483,-0.003 3.99146,-1.78951 3.99433,-3.99433 v -8.00168 c -0.003,-2.20473 -1.7896,-3.99126 -3.99433,-3.99432 H 67.99767 v -8.00168 c 0.005,-2.20991 -1.78441,-4.00449 -3.99432,-4.00735 z m -19.99768,54.00155 c -2.20482,0.003 -3.99147,1.7895 -3.99433,3.99433 v 1.99717 H 28.00232 c -2.20992,0.003 -3.99867,1.79744 -3.99433,4.00734 0.003,2.20483 1.7895,3.99147 3.99433,3.99434 h 12.00902 v 16.00335 h -4.00735 c -2.20482,0.003 -3.99147,1.7895 -3.99433,3.99433 -0.005,2.2099 1.78443,4.00448 3.99433,4.00735 h 8.00168 c 2.20981,-0.003 3.99844,-1.79754 3.99433,-4.00735 V 208 h 32.00671 v 19.99768 c -0.004,2.20981 1.78451,4.00427 3.99433,4.00735 h 16.00335 c 2.20982,-0.003 3.99844,-1.79754 3.99433,-4.00735 V 219.996 c -0.003,-2.20482 -1.7895,-3.99147 -3.99433,-3.99433 -2.209909,-0.004 -4.004489,1.78442 -4.007349,3.99433 v 4.00735 H 87.99536 v -19.99769 c 0.004,-2.20981 -1.78451,-4.00426 -3.99432,-4.00734 H 48 v -1.99717 c -0.0032,-2.20483 -1.78951,-3.99147 -3.99433,-3.99433 z"
style="color:#000000;fill:#333333;stroke-width:5.03878;stroke-linecap:square;stroke-linejoin:bevel;stroke-dashoffset:0.00000001;-inkscape-stroke:none;paint-order:stroke fill markers;fill-opacity:1"
id="path1-1" /></svg>

After

Width:  |  Height:  |  Size: 6.2 KiB

View file

@ -1,2 +0,0 @@
@import 'tailwindcss';
@plugin '@tailwindcss/typography';

13
src/app.d.ts vendored
View file

@ -1,13 +0,0 @@
// See https://svelte.dev/docs/kit/types#app.d.ts
// for information about these interfaces
declare global {
namespace App {
// interface Error {}
// interface Locals {}
// interface PageData {}
// interface PageState {}
// interface Platform {}
}
}
export {};

View file

@ -1,12 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>

View file

@ -1 +0,0 @@
// place files you want to import through the `$lib` alias in this folder.

View file

@ -1,7 +0,0 @@
<script lang="ts">
import '../app.css';
let { children } = $props();
</script>
{@render children()}

View file

@ -1,2 +0,0 @@
<h1>Welcome to SvelteKit</h1>
<p>Visit <a href="https://svelte.dev/docs/kit">svelte.dev/docs/kit</a> to read the documentation</p>

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="107" height="128" viewBox="0 0 107 128"><title>svelte-logo</title><path d="M94.157 22.819c-10.4-14.885-30.94-19.297-45.792-9.835L22.282 29.608A29.92 29.92 0 0 0 8.764 49.65a31.5 31.5 0 0 0 3.108 20.231 30 30 0 0 0-4.477 11.183 31.9 31.9 0 0 0 5.448 24.116c10.402 14.887 30.942 19.297 45.791 9.835l26.083-16.624A29.92 29.92 0 0 0 98.235 78.35a31.53 31.53 0 0 0-3.105-20.232 30 30 0 0 0 4.474-11.182 31.88 31.88 0 0 0-5.447-24.116" style="fill:#ff3e00"/><path d="M45.817 106.582a20.72 20.72 0 0 1-22.237-8.243 19.17 19.17 0 0 1-3.277-14.503 18 18 0 0 1 .624-2.435l.49-1.498 1.337.981a33.6 33.6 0 0 0 10.203 5.098l.97.294-.09.968a5.85 5.85 0 0 0 1.052 3.878 6.24 6.24 0 0 0 6.695 2.485 5.8 5.8 0 0 0 1.603-.704L69.27 76.28a5.43 5.43 0 0 0 2.45-3.631 5.8 5.8 0 0 0-.987-4.371 6.24 6.24 0 0 0-6.698-2.487 5.7 5.7 0 0 0-1.6.704l-9.953 6.345a19 19 0 0 1-5.296 2.326 20.72 20.72 0 0 1-22.237-8.243 19.17 19.17 0 0 1-3.277-14.502 17.99 17.99 0 0 1 8.13-12.052l26.081-16.623a19 19 0 0 1 5.3-2.329 20.72 20.72 0 0 1 22.237 8.243 19.17 19.17 0 0 1 3.277 14.503 18 18 0 0 1-.624 2.435l-.49 1.498-1.337-.98a33.6 33.6 0 0 0-10.203-5.1l-.97-.294.09-.968a5.86 5.86 0 0 0-1.052-3.878 6.24 6.24 0 0 0-6.696-2.485 5.8 5.8 0 0 0-1.602.704L37.73 51.72a5.42 5.42 0 0 0-2.449 3.63 5.79 5.79 0 0 0 .986 4.372 6.24 6.24 0 0 0 6.698 2.486 5.8 5.8 0 0 0 1.602-.704l9.952-6.342a19 19 0 0 1 5.295-2.328 20.72 20.72 0 0 1 22.237 8.242 19.17 19.17 0 0 1 3.277 14.503 18 18 0 0 1-8.13 12.053l-26.081 16.622a19 19 0 0 1-5.3 2.328" style="fill:#fff"/></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -1,19 +0,0 @@
import { mdsvex } from 'mdsvex';
import adapter from '@sveltejs/adapter-auto';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
/** @type {import('@sveltejs/kit').Config} */
const config = {
// Consult https://svelte.dev/docs/kit/integrations
// for more information about preprocessors
preprocess: [vitePreprocess(), mdsvex()],
kit: {
// adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
// If your environment is not supported, or you settled on a specific environment, switch out the adapter.
// See https://svelte.dev/docs/kit/adapters for more information about adapters.
adapter: adapter()
},
extensions: ['.svelte', '.svx']
};
export default config;

View file

@ -1,19 +0,0 @@
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"moduleResolution": "bundler"
}
// Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
// except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
//
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
// from the referenced tsconfig.json - TypeScript does not merge them in
}

View file

@ -1,7 +0,0 @@
import tailwindcss from '@tailwindcss/vite';
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [tailwindcss(), sveltekit()]
});