summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuben Beltran del Rio <git@r.bdr.sh>2025-09-17 15:59:30 +0200
committerRuben Beltran del Rio <git@r.bdr.sh>2025-09-17 15:59:30 +0200
commitda7e4514cfdbe52e8f1ef6aadd54c401e2b849f5 (patch)
tree86658a61d347ea171a0aa7be24fdb36769ba373c
parent20f3e7c7465cd899b46204d4f07460543e7cb5cc (diff)
Use zola
-rw-r--r--.build.yml9
-rw-r--r--.gitignore1
-rw-r--r--config.toml16
-rw-r--r--content/_index.md66
-rw-r--r--content/impressum/_index.md15
-rw-r--r--content/privacy-policy/_index.md45
-rw-r--r--index.html108
-rw-r--r--static/css/style.css (renamed from css/style.css)50
-rwxr-xr-xstatic/font/LibreCaslonCondensed-Bold.woff2 (renamed from font/LibreCaslonCondensed-Bold.woff2)bin50324 -> 50324 bytes
-rwxr-xr-xstatic/font/LibreCaslonCondensed-BoldItalic.woff2 (renamed from font/LibreCaslonCondensed-BoldItalic.woff2)bin55408 -> 55408 bytes
-rwxr-xr-xstatic/font/LibreCaslonCondensed-Italic.woff2 (renamed from font/LibreCaslonCondensed-Italic.woff2)bin54768 -> 54768 bytes
-rwxr-xr-xstatic/font/LibreCaslonCondensed-Italic[wght].woff2 (renamed from font/LibreCaslonCondensed-Italic[wght].woff2)bin69292 -> 69292 bytes
-rwxr-xr-xstatic/font/LibreCaslonCondensed-Medium.woff2 (renamed from font/LibreCaslonCondensed-Medium.woff2)bin51460 -> 51460 bytes
-rwxr-xr-xstatic/font/LibreCaslonCondensed-MediumItalic.woff2 (renamed from font/LibreCaslonCondensed-MediumItalic.woff2)bin57656 -> 57656 bytes
-rwxr-xr-xstatic/font/LibreCaslonCondensed-Regular.woff2 (renamed from font/LibreCaslonCondensed-Regular.woff2)bin50380 -> 50380 bytes
-rwxr-xr-xstatic/font/LibreCaslonCondensed-SemiBold.woff2 (renamed from font/LibreCaslonCondensed-SemiBold.woff2)bin51788 -> 51788 bytes
-rwxr-xr-xstatic/font/LibreCaslonCondensed-SemiBoldItalic.woff2 (renamed from font/LibreCaslonCondensed-SemiBoldItalic.woff2)bin57696 -> 57696 bytes
-rwxr-xr-xstatic/font/LibreCaslonCondensed[wdth,wght].woff2 (renamed from font/LibreCaslonCondensed[wdth,wght].woff2)bin62484 -> 62484 bytes
-rwxr-xr-xstatic/font/LibreCaslonCondensed[wght].woff2 (renamed from font/LibreCaslonCondensed[wght].woff2)bin62552 -> 62552 bytes
-rw-r--r--static/font/Ronzino-Bold.woff2 (renamed from font/Ronzino-Bold.woff2)bin36908 -> 36908 bytes
-rw-r--r--static/font/Ronzino-BoldOblique.woff2 (renamed from font/Ronzino-BoldOblique.woff2)bin36260 -> 36260 bytes
-rw-r--r--static/font/Ronzino-Medium.woff2 (renamed from font/Ronzino-Medium.woff2)bin36748 -> 36748 bytes
-rw-r--r--static/font/Ronzino-MediumOblique.woff2 (renamed from font/Ronzino-MediumOblique.woff2)bin36304 -> 36304 bytes
-rw-r--r--static/font/Ronzino-Oblique.woff2 (renamed from font/Ronzino-Oblique.woff2)bin36260 -> 36260 bytes
-rw-r--r--static/font/Ronzino-Regular.woff2 (renamed from font/Ronzino-Regular.woff2)bin36316 -> 36316 bytes
-rw-r--r--static/humans.txt (renamed from humans.txt)0
-rw-r--r--static/img/selfie-export.png (renamed from img/selfie-export.png)bin1390 -> 1390 bytes
-rw-r--r--static/img/selfie.png (renamed from img/selfie.png)bin1390 -> 1390 bytes
-rw-r--r--static/js/animation.js (renamed from js/animation.js)0
-rw-r--r--templates/base.html48
-rw-r--r--templates/index.html5
-rw-r--r--templates/shortcodes/window.html8
-rw-r--r--templates/text.html8
33 files changed, 268 insertions, 111 deletions
diff --git a/.build.yml b/.build.yml
index 97d4094..500d281 100644
--- a/.build.yml
+++ b/.build.yml
@@ -9,5 +9,12 @@ secrets:
- a1e0e3da-c1ad-473a-ad69-8878f267a628
- 0b0d3e5e-fbdc-41d0-97ed-ee654fe797ff
tasks:
+ - install_zola: |
+ rustup default stable
+ cargo install zola
+ - generate: |
+ cd ruben.bdr.sh
+ zola build
- sync: |
- rsync -r --exclude '.build.yml' --exclude '.git' ruben.bdr.sh/ deploy@conchos.unlimited.pizza:/srv/http/ruben.bdr.sh
+ cd ruben.bdr.sh/public
+ rsync -r . deploy@conchos.unlimited.pizza:/srv/http/ruben.bdr.sh
diff --git a/.gitignore b/.gitignore
index e43b0f9..592a6ea 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
.DS_Store
+public
diff --git a/config.toml b/config.toml
new file mode 100644
index 0000000..739f807
--- /dev/null
+++ b/config.toml
@@ -0,0 +1,16 @@
+# The URL the site will be built for
+base_url = "https://ruben.bdr.sh"
+
+# Whether to automatically compile all Sass files in the sass directory
+compile_sass = false
+
+# Whether to build a search index to be used later on by a JavaScript library
+build_search_index = true
+
+[markdown]
+# Whether to do syntax highlighting
+# Theme can be customised by setting the `highlight_theme` variable to a theme supported by Zola
+highlight_code = false
+
+[extra]
+# Put all your custom variables here
diff --git a/content/_index.md b/content/_index.md
new file mode 100644
index 0000000..2cd776e
--- /dev/null
+++ b/content/_index.md
@@ -0,0 +1,66 @@
++++
+title = "Holistic Tech Services"
+description = "Rubén Beltrán del Río is a freelance software engineer that offers a wide-range of services, including native iOS and macOS development, web development, backend services, infrastructure, as well as organizational and leadership consulting for tech teams."
++++
+ <section id="introduction">
+ {% window(title="Welcome.") %}
+ <img src="/img/selfie.png" alt="A pixel-art portrait of Rubén doing a peace sign and sticking his tongue out" />
+ <p>Howdy! I'm Rubén, a freelance full-stack software engineer based in Berlin. Looking for some help with your project? I might be able to help!</p>
+ {% end %}
+ </section>
+ <section id="services">
+ <section>
+ <h2>I can help you build.</h2>
+ <ul>
+ <li><strong>Websites</strong> that are fast, accessible and search engine optimized.</li>
+ <li><strong>Native apps</strong> for iOS, iPadOS or macOS.</li>
+ <li><strong>Backend Services</strong> with great observability, clear documentation, and made to scale.</li>
+ <li><strong>Data Pipelines</strong> from tracking planning, to data warehouse extract-load-transform pipelines that give you accurate and actionable information.</li>
+ <li><strong>Infrastructure</strong> that can tie all your services, documented as code.</li>
+ </ul>
+ </section>
+ <section>
+ <h2>Optimize and improve.</h2>
+ <ul>
+ <li><strong>Supply chain analysis</strong> to reduce risk from dependencies across different packaging ecosystems.</li>
+ <li><strong>Automate</strong> code quality and deployment.</li>
+ <li><strong>Reduce cloud cost</strong> by optimizing your resource usage, plans and overall architecture.</li>
+ <li><strong>Optimize Large-Language-Model</strong> usage by creating custom tooling and Model Context Protocol (MCP) servers.</li>
+ </ul>
+ </section>
+ <section>
+ <h2>Or help your team go fast.</h2>
+ <ul>
+ <li><strong>AI Transformation</strong>: Teach your organization how to work with AI, and build the right tools to support it.</li>
+ <li><strong>Upskill Your Team</strong>: Bring your team up to speed with new technologies, architecture patterns or processes.</li>
+ <li><strong>Product Engineering Mindset</strong>: Bring product and engineering closer together.</li>
+ <li><strong>Experimentation mindset</strong>, help your team learn how to design, execute, and interpret experiments.</li>
+ <li><strong>Systems Analysis</strong>: Streamline your operations by understanding how your team, resources and processes come together, finding chokepoints, and reducing waste.</li>
+ </ul>
+ </section>
+ </section>
+ <section id="skills">
+ <section class="textured">
+ <h2>Ain't that right!</h2>
+ <p>With over 25 years of experience, I've worked with big and small teams, ad-supported and sales-driven products, bootstrapped startups looking to launch, and established companies looking to scale up. I've worked with all sorts of stacks:</p>
+ <ul>
+ <li><strong>Languages:</strong> JavaScript, Rust, Ruby, Python, PHP, Swift, Objective-C.</li>
+ <li><strong>Cloud Providers:</strong> AWS, Scaleway, Cloudflare, Google Cloud, Azure.</li>
+ <li><strong>CI Systems:</strong> GitHub, Gitlab, CircleCI, TravisCI, Jenkins, Bitrise.</li>
+ <li><strong>Database Systems:</strong> PostgreSQL, MySQL/Aurora, Redis, MongoDB, Apache Cassandra, Snowflake.</li>
+ <li><strong>Analytics Software:</strong> Google Analytics, Amplitude, PostHog, .</li>
+ </ul>
+ </section>
+ {% window(title="Get in touch.") %}
+ <p>You can book a call to tell me about your project face to face. Or you if you prefer text, you can send me an e-mail!</p>
+ <button><label>Book a call.</label></button>
+ <a role="button" href="mailto:hello@work.bdr.sh?subject=Howdy%2C%20I%27d%20like%20to%20work%20with%20you%21&body=Hi%20Rub%C3%A9n%2C%0D%0A%0D%0AI%20saw%20the%20contact%20form%20on%20your%20website%20and%20would%20like%20to%20see%20if%20we%20can%20work%20together%20on%20my%20project%3A%0D%0A%0D%0A%3CTell%20me%20a%20bit%20about%20your%20project%20here%3E%0D%0A%0D%0ABest%2C%0D%0A%3CYour%20Name%3E"><label>Send an e-mail.</label></a>
+ {% end %}
+ </section>
+ <section id="testimonials">
+ <section class="textured">
+ <h2>But don't take my word for it.</h2>
+ <p>Here's what some lovely people have to say about me.</p>
+ </section>
+ </section>
+
diff --git a/content/impressum/_index.md b/content/impressum/_index.md
new file mode 100644
index 0000000..465b4d8
--- /dev/null
+++ b/content/impressum/_index.md
@@ -0,0 +1,15 @@
++++
+title = "Holistic Tech Services &mdot; Impressum"
+description = "Rubén Beltrán del Río is a freelance software engineer that offers a wide-range of services, including native iOS and macOS development, web development, backend services, infrastructure, as well as organizational and leadership consulting for tech teams."
+template = "text.html"
++++
+## Impressum.
+
+All the content and services in this page are provided by:
+
+**Rubén Fabián Beltrán del Río Vara** <br>
+Ueckermünder Str. 5 <br>
+10439 Berlin <br>
+[inquiries@work.bdr.sh](hello@work.bdr.sh)
+
+You can send any inquiries to the aforementioned e-mail address.
diff --git a/content/privacy-policy/_index.md b/content/privacy-policy/_index.md
new file mode 100644
index 0000000..fe35188
--- /dev/null
+++ b/content/privacy-policy/_index.md
@@ -0,0 +1,45 @@
++++
+title = "Holistic Tech Services &mdot; Privacy Policy"
+description = "Rubén Beltrán del Río is a freelance software engineer that offers a wide-range of services, including native iOS and macOS development, web development, backend services, infrastructure, as well as organizational and leadership consulting for tech teams."
+template = "text.html"
++++
+## Privacy Policy
+
+In order to offer my services, I need to collect some data. This policy shows the entirety of our data collection, and how long we keep it for.
+
+### The What, When, Why and How long of our Data Collection.
+
+#### When you visit this website.
+* **What**: Our server collects IP addresses and browser User-Agents but never links it to your identity.
+* **Why**: We use this data to understand our traffic and block potential malicious actors (eg. Bots)
+* **For how long**: 30 days.
+
+#### When you send me an e-mail or book an appointment.
+* **What**: Your contact information and the content of the messages.
+* **Why**: In order to respond to your inquiries.
+* **How Long**: 2 years if no business relationship develops, 6 years for business correspondence.
+* **Lawful basis**: Legitimate interests.
+
+#### When we work on a project together.
+* **What**: Contact details, business information, invoicing data, project communications.
+* **Why**: This is necessary to fulfill the contract, and for my tax obligations.
+* **For how long**: Business records are kept for 6 years after project completion, financial records for 10 years after final invoice.
+* **Lawful basis**: Contract performance and legal obligation.
+
+### Data Security
+Your data is protected using appropriate technical and organizational measures, including firewalls, encrypted data transmission, and secure server infrastructure.
+
+### Data Sharing
+Your data is never shared with third parties, except as required by law (such as tax authorities or in response to valid legal requests).
+
+### Your Rights
+You can request access to, correction of, deletion of, or object to processing of your data (subject to legal retention requirements).
+
+Contact me at [dataprotection@work.bdr.sh](mailto:dataprotection@work.bdr.sh) for data protection queries. I will respond to your requests within one month.
+
+### Data Controller
+Rubén Fabián Beltrán del Río Vara
+[dataprotection@work.bdr.sh](mailto:dataprotection@work.bdr.sh)
+
+### Governing Law
+This privacy policy and all data processing activities are governed by German law and the European General Data Protection Regulation (GDPR).
diff --git a/index.html b/index.html
deleted file mode 100644
index 652cf13..0000000
--- a/index.html
+++ /dev/null
@@ -1,108 +0,0 @@
-<!DOCTYPE HTML>
-
-<html lang="en">
- <head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <meta name="author" content="Rubén Beltrán del Río">
- <meta name="description" content="Rubén Beltrán del Río is a freelance software engineer that offers a wide-range of services, including native iOS and macOS development, web development, backend services, infrastructure, as well as organizational and leadership consulting for tech teams.">
- <meta name="theme-color" content="#0000f5">
- <meta name="fediverse:creator" content="@ruben@friendship.quest" />
-
- <title>Rubén Beltrán del Río &mdash; Holistic Tech Services</title>
-
- <link rel="preload" href="/font/LibreCaslonCondensed[wdth,wght].woff2" as="font" type="font/woff2" crossorigin>
- <link rel="preload" href="/font/LibreCaslonCondensed-Italic[wght].woff2" as="font" type="font/woff2" crossorigin>
- <link rel="preload" href="/font/Ronzino-Medium.woff2" as="font" type="font/woff2" crossorigin>
- <link rel="preload" href="/font/Ronzino-Bold.woff2" as="font" type="font/woff2" crossorigin>
-
- <link rel="stylesheet" type="text/css" href="/css/style.css">
- <link rel="author" href="humans.txt">
-
- <script type="module" src="/js/animation.js"></script>
- </head>
- <body>
- <header>
- <h1>
- <canvas width="60" height="60" aria-hidden="true"></canvas>
- <a href="/">Rubén Beltrán del Río</a>
- </h1>
- <p>✷ Holistic
- tech
- services ✷</p>
- </header>
- <main>
- <section id="introduction">
- <section class="window cutoff-corners">
- <header class="titlebar">
- <span class="label">Welcome.</span>
- </header>
- <div class="content">
- <img src="/img/selfie.png" alt="A pixel-art portrait of Rubén doing a peace sign and sticking his tongue out" />
- <p>Howdy! I'm Rubén, a freelance full-stack software engineer based in Berlin. Looking for some help with your project? I might be able to help!</p>
- </div>
- </section>
- </section>
- <section id="services">
- <section>
- <h2>I can help you build.</h2>
- <ul>
- <li><strong>Websites</strong> that are fast, accessible and search engine optimized.</li>
- <li><strong>Native apps</strong> for iOS, iPadOS or macOS.</li>
- <li><strong>Backend Services</strong> with great observability, clear documentation, and made to scale.</li>
- <li><strong>Data Pipelines</strong> from tracking planning, to data warehouse extract-load-transform pipelines that give you accurate and actionable information.</li>
- <li><strong>Infrastructure</strong> that can tie all your services, documented as code.</li>
- </ul>
- </section>
- <section>
- <h2>Optimize and improve.</h2>
- <ul>
- <li><strong>Supply chain analysis</strong> to reduce risk from dependencies across different packaging ecosystems.</li>
- <li><strong>Automate</strong> code quality and deployment.</li>
- <li><strong>Reduce cloud cost</strong> by optimizing your resource usage, plans and overall architecture.</li>
- <li><strong>Optimize Large-Language-Model</strong> usage by creating custom tooling and Model Context Protocol (MCP) servers.</li>
- </ul>
- </section>
- <section>
- <h2>Or help your team go fast.</h2>
- <ul>
- <li><strong>AI Transformation</strong>: Teach your organization how to work with AI, and build the right tools to support it.</li>
- <li><strong>Upskill Your Team</strong>: Bring your team up to speed with new technologies, architecture patterns or processes.</li>
- <li><strong>Product Engineering Mindset</strong>: Bring product and engineering closer together.</li>
- <li><strong>Experimentation mindset</strong>, help your team learn how to design, execute, and interpret experiments.</li>
- <li><strong>Systems Analysis</strong>: Streamline your operations by understanding how your team, resources and processes come together, finding chokepoints, and reducing waste.</li>
- </ul>
- </section>
- </section>
- <section id="skills">
- <section class="textured">
- <h2>Ain't that right!</h2>
- <p>With over 25 years of experience, I've worked with big and small teams, ad-supported and sales-driven products, bootstrapped startups looking to launch, and established companies looking to scale up. I've worked with all sorts of stacks:</p>
- <ul>
- <li><strong>Languages:</strong> JavaScript, Rust, Ruby, Python, PHP, Swift, Objective-C.</li>
- <li><strong>Cloud Providers:</strong> AWS, Scaleway, Cloudflare, Google Cloud, Azure.</li>
- <li><strong>CI Systems:</strong> GitHub, Gitlab, CircleCI, TravisCI, Jenkins, Bitrise.</li>
- <li><strong>Database Systems:</strong> PostgreSQL, MySQL/Aurora, Redis, MongoDB, Apache Cassandra, Snowflake.</li>
- <li><strong>Analytics Software:</strong> Google Analytics, Amplitude, PostHog, .</li>
- </ul>
- </section>
- <section class="window cutoff-corners pinned">
- <header class="titlebar">
- <span class="label">Get in touch.</span>
- </header>
- <div class="content">
- <p>You can book a call to tell me about your project face to face. Or you if you prefer text, you can send me an e-mail!</p>
- <button><label>Book a call.</label></button>
- <a role="button" href="mailto:hello@work.bdr.sh?subject=Howdy%2C%20I%27d%20like%20to%20work%20with%20you%21&body=Hi%20Rub%C3%A9n%2C%0D%0A%0D%0AI%20saw%20the%20contact%20form%20on%20your%20website%20and%20would%20like%20to%20see%20if%20we%20can%20work%20together%20on%20my%20project%3A%0D%0A%0D%0A%3CTell%20me%20a%20bit%20about%20your%20project%20here%3E%0D%0A%0D%0ABest%2C%0D%0A%3CYour%20Name%3E"><label>Send an e-mail.</label></a>
- </div>
- </section>
- </section>
- <section id="testimonials">
- <section class="textured">
- <h2>But don't take my word for it.</h2>
- <p>Here's what some lovely people have to say about me.</p>
- </section>
- </section>
- </main>
- </body>
-</html>
diff --git a/css/style.css b/static/css/style.css
index 795a205..7eeb4e0 100644
--- a/css/style.css
+++ b/static/css/style.css
@@ -163,7 +163,8 @@ body {
word-spacing: 100vw;
@media (max-width: 600px) {
- margin-top: 4px
+ margin-top: 0;
+ transform: translateY(4px);
}
}
@@ -200,9 +201,26 @@ main {
transform: translateY(-8px);
}
+ h3 {
+ font-size: 1.25rem;
+ line-height: 1;
+ font-weight: 500;
+ transform: translateY(2px);
+ margin: 2lh 0 1lh;
+ }
+
+ h4 {
+ font-weight: 500;
+ font-size: 1rem;
+ line-height: 1.25;
+ transform: translateY(4px);
+ margin: 1lh 0;
+ }
+
ul {
list-style: none;
margin-left: 0;
+ margin-bottom: var(--base-grid);
}
li {
position: relative;
@@ -220,7 +238,7 @@ main {
#introduction {
- padding: calc(1 * var(--base-grid));
+ padding: var(--base-grid);
.content {
column-gap: var(--base-grid);
@@ -249,6 +267,10 @@ main {
min-width: calc(17 * var(--base-grid));
max-width: calc(25 * var(--base-grid));
+ ul {
+ margin-bottom: 0;
+ }
+
@media (max-width: 360px) {
min-width: calc(100vw - 2 * var(--base-grid));
}
@@ -302,6 +324,30 @@ main {
}
}
+footer {
+
+ color: #fff;
+ padding: calc(2 * var(--base-grid));
+
+ ul {
+ list-style-position: inside;
+ }
+ li {
+ padding: 0 var(--base-grid);
+ list-style-position: inside;
+ float: left;
+ }
+
+ a {
+ color: #fff;
+ }
+}
+
+#text {
+ max-width: calc(35 * var(--base-grid));
+ padding: var(--base-grid);
+}
+
/* The Floating Window */
.cutoff-corners {
background-color: #fff;
diff --git a/font/LibreCaslonCondensed-Bold.woff2 b/static/font/LibreCaslonCondensed-Bold.woff2
index 4a4a681..4a4a681 100755
--- a/font/LibreCaslonCondensed-Bold.woff2
+++ b/static/font/LibreCaslonCondensed-Bold.woff2
Binary files differ
diff --git a/font/LibreCaslonCondensed-BoldItalic.woff2 b/static/font/LibreCaslonCondensed-BoldItalic.woff2
index 944988e..944988e 100755
--- a/font/LibreCaslonCondensed-BoldItalic.woff2
+++ b/static/font/LibreCaslonCondensed-BoldItalic.woff2
Binary files differ
diff --git a/font/LibreCaslonCondensed-Italic.woff2 b/static/font/LibreCaslonCondensed-Italic.woff2
index 6b37d8a..6b37d8a 100755
--- a/font/LibreCaslonCondensed-Italic.woff2
+++ b/static/font/LibreCaslonCondensed-Italic.woff2
Binary files differ
diff --git a/font/LibreCaslonCondensed-Italic[wght].woff2 b/static/font/LibreCaslonCondensed-Italic[wght].woff2
index 0431f04..0431f04 100755
--- a/font/LibreCaslonCondensed-Italic[wght].woff2
+++ b/static/font/LibreCaslonCondensed-Italic[wght].woff2
Binary files differ
diff --git a/font/LibreCaslonCondensed-Medium.woff2 b/static/font/LibreCaslonCondensed-Medium.woff2
index 22bc644..22bc644 100755
--- a/font/LibreCaslonCondensed-Medium.woff2
+++ b/static/font/LibreCaslonCondensed-Medium.woff2
Binary files differ
diff --git a/font/LibreCaslonCondensed-MediumItalic.woff2 b/static/font/LibreCaslonCondensed-MediumItalic.woff2
index dddc7ff..dddc7ff 100755
--- a/font/LibreCaslonCondensed-MediumItalic.woff2
+++ b/static/font/LibreCaslonCondensed-MediumItalic.woff2
Binary files differ
diff --git a/font/LibreCaslonCondensed-Regular.woff2 b/static/font/LibreCaslonCondensed-Regular.woff2
index da1778e..da1778e 100755
--- a/font/LibreCaslonCondensed-Regular.woff2
+++ b/static/font/LibreCaslonCondensed-Regular.woff2
Binary files differ
diff --git a/font/LibreCaslonCondensed-SemiBold.woff2 b/static/font/LibreCaslonCondensed-SemiBold.woff2
index 99396d6..99396d6 100755
--- a/font/LibreCaslonCondensed-SemiBold.woff2
+++ b/static/font/LibreCaslonCondensed-SemiBold.woff2
Binary files differ
diff --git a/font/LibreCaslonCondensed-SemiBoldItalic.woff2 b/static/font/LibreCaslonCondensed-SemiBoldItalic.woff2
index 9b8a820..9b8a820 100755
--- a/font/LibreCaslonCondensed-SemiBoldItalic.woff2
+++ b/static/font/LibreCaslonCondensed-SemiBoldItalic.woff2
Binary files differ
diff --git a/font/LibreCaslonCondensed[wdth,wght].woff2 b/static/font/LibreCaslonCondensed[wdth,wght].woff2
index d280f8a..d280f8a 100755
--- a/font/LibreCaslonCondensed[wdth,wght].woff2
+++ b/static/font/LibreCaslonCondensed[wdth,wght].woff2
Binary files differ
diff --git a/font/LibreCaslonCondensed[wght].woff2 b/static/font/LibreCaslonCondensed[wght].woff2
index 67fff68..67fff68 100755
--- a/font/LibreCaslonCondensed[wght].woff2
+++ b/static/font/LibreCaslonCondensed[wght].woff2
Binary files differ
diff --git a/font/Ronzino-Bold.woff2 b/static/font/Ronzino-Bold.woff2
index 440957c..440957c 100644
--- a/font/Ronzino-Bold.woff2
+++ b/static/font/Ronzino-Bold.woff2
Binary files differ
diff --git a/font/Ronzino-BoldOblique.woff2 b/static/font/Ronzino-BoldOblique.woff2
index 29038fa..29038fa 100644
--- a/font/Ronzino-BoldOblique.woff2
+++ b/static/font/Ronzino-BoldOblique.woff2
Binary files differ
diff --git a/font/Ronzino-Medium.woff2 b/static/font/Ronzino-Medium.woff2
index 6161f9c..6161f9c 100644
--- a/font/Ronzino-Medium.woff2
+++ b/static/font/Ronzino-Medium.woff2
Binary files differ
diff --git a/font/Ronzino-MediumOblique.woff2 b/static/font/Ronzino-MediumOblique.woff2
index 0879928..0879928 100644
--- a/font/Ronzino-MediumOblique.woff2
+++ b/static/font/Ronzino-MediumOblique.woff2
Binary files differ
diff --git a/font/Ronzino-Oblique.woff2 b/static/font/Ronzino-Oblique.woff2
index 0b4e1ac..0b4e1ac 100644
--- a/font/Ronzino-Oblique.woff2
+++ b/static/font/Ronzino-Oblique.woff2
Binary files differ
diff --git a/font/Ronzino-Regular.woff2 b/static/font/Ronzino-Regular.woff2
index b8763ad..b8763ad 100644
--- a/font/Ronzino-Regular.woff2
+++ b/static/font/Ronzino-Regular.woff2
Binary files differ
diff --git a/humans.txt b/static/humans.txt
index b2bdf36..b2bdf36 100644
--- a/humans.txt
+++ b/static/humans.txt
diff --git a/img/selfie-export.png b/static/img/selfie-export.png
index d50ef8f..d50ef8f 100644
--- a/img/selfie-export.png
+++ b/static/img/selfie-export.png
Binary files differ
diff --git a/img/selfie.png b/static/img/selfie.png
index d50ef8f..d50ef8f 100644
--- a/img/selfie.png
+++ b/static/img/selfie.png
Binary files differ
diff --git a/js/animation.js b/static/js/animation.js
index d78ac8f..d78ac8f 100644
--- a/js/animation.js
+++ b/static/js/animation.js
diff --git a/templates/base.html b/templates/base.html
new file mode 100644
index 0000000..04120ba
--- /dev/null
+++ b/templates/base.html
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML>
+
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <meta name="author" content="Rubén Beltrán del Río">
+ <meta name="description" content="{{ section.description }}">
+ <meta name="theme-color" content="#0000f5">
+ <meta name="fediverse:creator" content="@ruben@friendship.quest" />
+
+ <title>Rubén Beltrán del Río &mdash; {{ section.title }}</title>
+
+ <link rel="preload" href="/font/LibreCaslonCondensed[wdth,wght].woff2" as="font" type="font/woff2" crossorigin>
+ <link rel="preload" href="/font/LibreCaslonCondensed-Italic[wght].woff2" as="font" type="font/woff2" crossorigin>
+ <link rel="preload" href="/font/Ronzino-Medium.woff2" as="font" type="font/woff2" crossorigin>
+ <link rel="preload" href="/font/Ronzino-Bold.woff2" as="font" type="font/woff2" crossorigin>
+
+ <link rel="stylesheet" type="text/css" href="/css/style.css">
+ <link rel="author" href="humans.txt">
+
+ <script type="module" src="/js/animation.js"></script>
+ </head>
+ <body>
+ <header>
+ <h1>
+ <canvas width="60" height="60" aria-hidden="true"></canvas>
+ <a href="/">Rubén Beltrán del Río</a>
+ </h1>
+ <p>✷ Holistic
+ tech
+ services ✷</p>
+ </header>
+ <main>
+ {% block content %}{% endblock %}
+ </main>
+ <footer>
+ <menu>
+ <ul>
+ <li><a href="/impressum">Impressum</a></li>
+ <li><a href="/privacy-policy">Privacy Policy</a></li>
+ <li>Check out <a href="https://r.bdr.sh">my personal website.</a></li>
+ </ul>
+ </menu>
+ </footer>
+ </body>
+</html>
+
diff --git a/templates/index.html b/templates/index.html
new file mode 100644
index 0000000..be0db07
--- /dev/null
+++ b/templates/index.html
@@ -0,0 +1,5 @@
+{% extends "base.html" %}
+
+{% block content %}
+{{ section.content | safe }}
+{% endblock %}
diff --git a/templates/shortcodes/window.html b/templates/shortcodes/window.html
new file mode 100644
index 0000000..3fe8b50
--- /dev/null
+++ b/templates/shortcodes/window.html
@@ -0,0 +1,8 @@
+<section class="window cutoff-corners">
+ <header class="titlebar">
+ <span class="label">{{title}}</span>
+ </header>
+ <div class="content">
+ {{ body | safe }}
+ </div>
+</section>
diff --git a/templates/text.html b/templates/text.html
new file mode 100644
index 0000000..9ba2a71
--- /dev/null
+++ b/templates/text.html
@@ -0,0 +1,8 @@
+{% extends "base.html" %}
+
+{% block content %}
+<section id="text">
+
+ {{ section.content | safe }}
+</section>
+{% endblock %}