summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.build.yml8
-rw-r--r--content/_index.md111
-rw-r--r--static/css/style.css62
-rw-r--r--static/font/LibreCaslonText-Italic[wght].woff2bin0 -> 63024 bytes
-rw-r--r--static/font/LibreCaslonText[wght].woff2bin0 -> 57616 bytes
-rw-r--r--static/font/Ronzino-Bold.woff2bin36908 -> 0 bytes
-rw-r--r--static/font/Ronzino-BoldOblique.woff2bin36260 -> 0 bytes
-rw-r--r--static/font/Ronzino-Medium.woff2bin36748 -> 0 bytes
-rw-r--r--static/font/Ronzino-MediumOblique.woff2bin36304 -> 0 bytes
-rw-r--r--static/font/Ronzino-Oblique.woff2bin36260 -> 0 bytes
-rw-r--r--static/font/Ronzino-Regular.woff2bin36316 -> 0 bytes
-rw-r--r--static/img/darkgrid.svg4
-rw-r--r--static/img/lightgrid.svg4
13 files changed, 97 insertions, 92 deletions
diff --git a/.build.yml b/.build.yml
index 6cde9a1..6ef217c 100644
--- a/.build.yml
+++ b/.build.yml
@@ -4,14 +4,14 @@ packages:
- rsync
- zola
sources:
- - git@git.sr.ht:~rbdr/ruben.bdr.sh
+ - git@git.sr.ht:~rbdr/www.holistic.services
secrets:
- a1e0e3da-c1ad-473a-ad69-8878f267a628
- deedaf0c-1534-445d-a9b8-0910b22478b4
tasks:
- generate: |
- cd ruben.bdr.sh
+ cd www.holistic.services
zola build
- sync: |
- cd ruben.bdr.sh/public
- rsync -r . deploy@conchos.bdr.sh:/srv/http/ruben.bdr.sh
+ cd www.holistic.services/public
+ rsync -r . deploy@conchos.bdr.sh:/srv/http/www.holistic.services
diff --git a/content/_index.md b/content/_index.md
index b0dbc3b..85c9ad2 100644
--- a/content/_index.md
+++ b/content/_index.md
@@ -5,62 +5,67 @@ description = "Freelance Software Engineer | iOS, macOS, Web & Backend Developme
<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 Beltrán del Río, a freelance software engineer based in Berlin. I build iOS and macOS apps, web applications, backend services, and help teams with technical leadership. Looking for some help with your project? I might be able to help!</p>
+ <p>
+ Howdy! I'm Rubén, a freelance software engineer and technical leader
+ based in Berlin. I love building software and helping teams figure out
+ <em>how</em> to build: how systems of people and technology, processes,
+ and culture can make the difference between chaos and meaningful work.
+ </p>
{% end %}
</section>
- <section id="services">
- <section>
- <h2>I can help you build.</h2>
- <ul>
- <li><strong>Fast, accessible websites</strong> with <abbr title="Search Engine Optimization">SEO</abbr> optimization and cutting edge web development best practices.</li>
- <li><strong>Native iOS, iPadOS, and macOS apps</strong> using Swift, Catalyst, SwiftUI, or UIKit.</li>
- <li><strong>Scalable backend services</strong> with great observability, clear documentation, and cloude-native infrastructure.</li>
- <li><strong>End-to-end data pipelines</strong> from tracking planning, to <abbr title="Extract-Load-Transform">ELT</abbr>/<abbr title="Extract-Transform-Load">ETL</abbr> workflows that deliver accurate and actionable analytics insights.</li>
- <li><strong>Infrastructure as code</strong> that can orchestrate and manage all your services on AWS, Scaleway, Azure or any cloud provider.</li>
- </ul>
- </section>
- <section>
- <h2>Optimize and improve.</h2>
- <ul>
- <li><strong>Supply chain analysis</strong> to reduce risk from dependencies across different languages and packaging ecosystems.</li>
- <li><strong><abbr title="Continuous Integration">CI</abbr> &amp; <abbr title="Continuous Delivery">CD</abbr> automation</strong> to improve code quality, testing, and deployment.</li>
- <li><strong>Cloud cost optimization</strong> through right-sizing, architecture improvements, and spending analysis for AWS, GCP, Azure and other cloud providers.</li>
- <li><strong><abbr title="Large Language Models">LLM</abbr> integration &amp; optimization</strong> using custom tooling, prompt engineering, 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>, and bring them up to speed with new technologies, architecture patterns or processes.</li>
- <li><strong>Build a product engineering mindset</strong> and ehelp your product and engineering teams speak the same language, and work closer together.</li>
- <li><strong>Experimentation mindset</strong> to enable your team to design, execute, and interpret A/B tests and multivariate experiments.</li>
- <li><strong>Systems analysis</strong> to streamline your operations by understanding how your team, resources and processes come together, finding chokepoints, and reducing waste.</li>
- </ul>
+ <section id="intro" class="columns">
+ <article>
+ <p>I've spent over 20 years helping teams — whether it's startups
+ just shipping their first product, to scale-ups experiencing growing
+ pains. As a tech lead, I've seen this familiar picture: legacy systems
+ that hinder more than they help, unpredictable release cycles that
+ add more bugs than value, and teams good at moving code but not
+ moving the needle.</p>
+ </article>
+ <article>
+ <p>I work <strong>holistically</strong> because problems rarely have
+ their root in just one place. A slow release pipeline that looks like
+ a technical issue, reveals itself to be a trust problem when you look
+ under the surface. A product launch failing to achieve its goals seems
+ like a clear case of poor planning, but instead reveals how different
+ parts of the organization have a different language and view of reality.
+ I help teams understand the big picture, and find solutions that can
+ address their problems at every level.</p>
+ </article>
</section>
+ <section class="columns">
+ <a role="button" href="https://fantastical.app/rbdr/initial-consultation">Book a call.</a>
+ <a role="button" href="mailto:hello@holistic.services?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>
</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, Indicative.</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>
- <a role="button" href="https://fantastical.app/rbdr/initial-consultation">Book a call.</a>
- <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 id="services" class="columns lighttexture">
+ <article>
+ <h2>How I Can Help.</h2>
+ <p><strong>Sometimes you need someone to roll up their sleeves and build</strong>: Plan a system, put your product in your customers' hands, and have an infrastructure you can trust not to wake you up at night.</p>
+ <p><strong>Sometimes you need help seeing the problem clearly</strong>: A second pair of eyes on a difficult problem, a diagnosis of why things seem harder and slower than they should, or a training that can change the way your team works.</p>
+ <p>I can do both.</p>
+ </article>
+ <article>
+ <h2>What Does That Look Like?.</h2>
+ <p>One team's releases took months and shipped broken. I helped them
+ move to predictable weekly releases that consistently shipped with zero
+ major bugs.</p>
+ <p>Another team's website took over 2 seconds to load. We got it under
+ 100ms at the 95th percentile, which helped SEO rankings climb steadily
+ afterwards.</p>
+ <p>And one of the most common problems I encounter: several teams were
+ fighting a legacy system and spending their days fighting fires. We deleted
+ hundreds of thousands of lines of code, and started with a simple system
+ that led the team to finally work on new features and improvements.</p>
+ </article>
</section>
+ <section id="book" class="columns darktexture">
+ <article>
+
+ ## Let's talk!
+ You can book a call or send me an e-mail to tell me about your project or problem, I might be able to help!
+
+ <a role="button" href="https://fantastical.app/rbdr/initial-consultation">Book a call.</a>
+ <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>
+ </article>
+ </section>
diff --git a/static/css/style.css b/static/css/style.css
index 9125736..6b95e9c 100644
--- a/static/css/style.css
+++ b/static/css/style.css
@@ -1,6 +1,23 @@
/* Font Faces */
@font-face {
font-family: 'Libre Caslon';
+ src: url('/font/LibreCaslonText[wght].woff2') format('woff2-variations');
+ font-weight: 400 700;
+ font-style: normal;
+ font-display: swap;
+ size-adjust: 100%;
+}
+
+@font-face {
+ font-family: 'Libre Caslon';
+ src: url('/font/LibreCaslonText-Italic[wght].woff2') format('woff2-variations');
+ font-weight: 400 700;
+ font-style: italic;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Libre Caslon Condensed';
src: url('/font/LibreCaslonCondensed[wdth,wght].woff2') format('woff2-variations');
font-weight: 400 700;
font-stretch: 75% 100%;
@@ -10,7 +27,7 @@
}
@font-face {
- font-family: 'Libre Caslon';
+ font-family: 'Libre Caslon Condensed';
src: url('/font/LibreCaslonCondensed-Italic[wght].woff2') format('woff2-variations');
font-weight: 400 700;
font-style: italic;
@@ -24,8 +41,11 @@
--foreground: #000019;
--foreground-emphasis: #191919;
--selection-color: #ccc;
- --font-display: 'Libre Caslon', 'Times New Roman', 'Georgia', serif;
- --font-body: 'Helvetica Neue', Helvetica, Arial, sans-serif;
+ --font-display: 'Libre Caslon Condensed', 'Times New Roman', Georgia, serif;
+ --font-body: 'Libre Caslon', 'Times New Roman', Georgia, serif;
+ --font-windows: 'Helvetica Neue', Helvetica, Arial, sans-serif;
+ /* There's an issue with Helvetica Neue Bold's glyph sizing that wrecks the grid. */
+ --font-windows-bold: Helvetica, Arial, sans-serif;
--root-font-size: 1rem;
--base-grid: 1.5625rem;
--radius: 4px;
@@ -51,7 +71,7 @@ li,p {
transform: translateY(7px);
}
strong {
- font-family: Helvetica, Arial, sans-serif;
+ font-family: var(--font-body);
color: var(--foreground-emphasis);
font-weight: 700;
line-height: 1;
@@ -87,7 +107,6 @@ button {
.textured {
h2, p, ul {
- -webkit-text-stroke: calc(8 * var(--border-width)) var(--background);
paint-order: stroke fill;
}
}
@@ -253,7 +272,7 @@ main {
}
}
-#services {
+.columns {
column-gap: calc(2 * var(--base-grid));
row-gap: calc(3 * var(--base-grid));
padding: calc(2 * var(--base-grid));
@@ -264,7 +283,7 @@ main {
justify-content: center;
flex-wrap: wrap;
- section {
+ article {
flex: 1;
min-width: calc(13 * var(--base-grid));
max-width: calc(25 * var(--base-grid));
@@ -280,33 +299,11 @@ main {
}
-#skills, #testimonials {
- column-gap: calc(4 * var(--base-grid));
- display: flex;
- flex-wrap: wrap;
- padding: calc(2 * var(--base-grid));
- row-gap: calc(3 * var(--base-grid));
- width: 100%;
-
- @media (max-width: 425px) {
- padding: calc(2 * var(--base-grid)) var(--base-grid);
- }
-
- section {
- flex: 1;
- min-width: calc(13 * var(--base-grid));
-
- @media (max-width: 360px) {
- min-width: calc(100vw - 3 * var(--base-grid));
- }
- }
-}
-
-#skills {
+.darktexture {
background-image: url('/img/darkgrid.svg');
}
-#testimonials {
+.lighttexture {
background-image: url('/img/lightgrid.svg');
}
@@ -357,8 +354,11 @@ footer {
.window {
+ font-family: var(--font-windows);
+
.titlebar {
border-bottom: var(--border-width) solid #000;
+ font-family: var(--font-windows-bold);
padding: calc(6 * var(--border-width)) calc(8 * var(--border-width)) calc(6 * var(--border-width)) ;
line-height: calc(9 * var(--border-width));
text-align: center;
diff --git a/static/font/LibreCaslonText-Italic[wght].woff2 b/static/font/LibreCaslonText-Italic[wght].woff2
new file mode 100644
index 0000000..a771694
--- /dev/null
+++ b/static/font/LibreCaslonText-Italic[wght].woff2
Binary files differ
diff --git a/static/font/LibreCaslonText[wght].woff2 b/static/font/LibreCaslonText[wght].woff2
new file mode 100644
index 0000000..336029c
--- /dev/null
+++ b/static/font/LibreCaslonText[wght].woff2
Binary files differ
diff --git a/static/font/Ronzino-Bold.woff2 b/static/font/Ronzino-Bold.woff2
deleted file mode 100644
index 440957c..0000000
--- a/static/font/Ronzino-Bold.woff2
+++ /dev/null
Binary files differ
diff --git a/static/font/Ronzino-BoldOblique.woff2 b/static/font/Ronzino-BoldOblique.woff2
deleted file mode 100644
index 29038fa..0000000
--- a/static/font/Ronzino-BoldOblique.woff2
+++ /dev/null
Binary files differ
diff --git a/static/font/Ronzino-Medium.woff2 b/static/font/Ronzino-Medium.woff2
deleted file mode 100644
index 6161f9c..0000000
--- a/static/font/Ronzino-Medium.woff2
+++ /dev/null
Binary files differ
diff --git a/static/font/Ronzino-MediumOblique.woff2 b/static/font/Ronzino-MediumOblique.woff2
deleted file mode 100644
index 0879928..0000000
--- a/static/font/Ronzino-MediumOblique.woff2
+++ /dev/null
Binary files differ
diff --git a/static/font/Ronzino-Oblique.woff2 b/static/font/Ronzino-Oblique.woff2
deleted file mode 100644
index 0b4e1ac..0000000
--- a/static/font/Ronzino-Oblique.woff2
+++ /dev/null
Binary files differ
diff --git a/static/font/Ronzino-Regular.woff2 b/static/font/Ronzino-Regular.woff2
deleted file mode 100644
index b8763ad..0000000
--- a/static/font/Ronzino-Regular.woff2
+++ /dev/null
Binary files differ
diff --git a/static/img/darkgrid.svg b/static/img/darkgrid.svg
index 58c586f..d49ef97 100644
--- a/static/img/darkgrid.svg
+++ b/static/img/darkgrid.svg
@@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="4" height="4">
- <rect x="0" y="0" width="1" height="1" fill="black"/>
- <rect x="2" y="2" width="1" height="1" fill="black"/>
+ <rect x="0" y="0" width="1" height="1" fill="#aaa"/>
+ <rect x="2" y="2" width="1" height="1" fill="#aaa"/>
</svg>
diff --git a/static/img/lightgrid.svg b/static/img/lightgrid.svg
index e16971b..7f7318c 100644
--- a/static/img/lightgrid.svg
+++ b/static/img/lightgrid.svg
@@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="6" height="6">
- <rect x="0" y="0" width="1" height="1" fill="black"/>
- <rect x="3" y="3" width="1" height="1" fill="black"/>
+ <rect x="0" y="0" width="1" height="1" fill="#aaa"/>
+ <rect x="3" y="3" width="1" height="1" fill="#aaa"/>
</svg>