summer hours 2024!

This commit is contained in:
Thomas 2024-06-18 07:23:06 +01:00
parent 9a1547af47
commit a32392fc1e
5 changed files with 253 additions and 176 deletions

View file

@ -1,49 +1,50 @@
<script lang="ts"> <script lang="ts">
import { writable } from 'svelte/store'; import { writable } from "svelte/store";
import { onMount, onDestroy, createEventDispatcher } from 'svelte'; import { onMount, onDestroy, createEventDispatcher } from "svelte";
const dispatch = createEventDispatcher<{ change: string }>(); const dispatch = createEventDispatcher<{ change: string }>();
let apiPassword = ''; let apiPassword = "";
let state: 'edit' | 'view' = 'edit'; let state: "edit" | "view" = "edit";
let unsubscribe: () => void; let unsubscribe: () => void;
function onSubmit() { function onSubmit() {
state = 'view'; state = "view";
if (localStorage) { if (localStorage) {
localStorage.setItem('apiPassword', apiPassword); localStorage.setItem("apiPassword", apiPassword);
} }
dispatch('change', apiPassword); dispatch("change", apiPassword);
} }
function onEdit() { function onEdit() {
state = 'edit'; state = "edit";
} }
onMount(() => { onMount(() => {
if (localStorage !== undefined) { if (localStorage !== undefined) {
apiPassword = localStorage.getItem('apiPassword') || ''; apiPassword = localStorage.getItem("apiPassword") || "";
} }
if (apiPassword.length > 0) { if (apiPassword.length > 0) {
dispatch('change', apiPassword); dispatch("change", apiPassword);
state = 'view'; state = "view";
} }
}); });
</script> </script>
<section> <section>
{#if apiPassword.length === 0} {#if apiPassword.length === 0}
<p> <p>
To save things to the ledger you need to enter the password. Right now you haven't set one. To save things to the ledger you need to enter the password. Right now you
</p> haven't set one.
{/if} </p>
{#if state === 'view'} {/if}
<button on:click={onEdit}>Edit Password</button> {#if state === "view"}
{:else} <button on:click={onEdit}>Edit Password</button>
<form on:submit|preventDefault={onSubmit}> {:else}
<input type="text" bind:value={apiPassword} /> <form on:submit|preventDefault={onSubmit}>
<input type="submit" value="Set Password" /> <input type="text" bind:value={apiPassword} />
</form> <input type="submit" value="Set Password" />
{/if} </form>
{/if}
</section> </section>

View file

@ -0,0 +1,16 @@
---
title: Summer Hours 2024
date: 2024-06-18T06:18:13.110Z
slug: 2024-06-18-summer-hours-2024
author: Thomas Wilson
---
It's that time of year when I intentionally set-aside the guilt of not writing all the blog posts I want to, in favour of spending time outside.
In the great tradition, I'll be on Summer Hours for the next few months. Spending times outside, ideally eating and drinking good food.
In July I'm getting married - which I am _incredibly_ excited for.
Around that, I'll be attending other weddings, spending time with family and friends, and lapping up what little sunshine as are bestowed on these Great British Isles.
✌️☀️

View file

@ -43,19 +43,30 @@
<Navbar /> <Navbar />
<main class="thomaswilson-container"> <main class="thomaswilson-container">
<section class="thomaswilson-strapline section"> <section class="thomaswilson-strapline section heading">
<h1>Blog</h1> <h1>Blog</h1>
<p> <div class="summer-hours">
<p class="summer-hours__emoji">☀️🥂🌻</p>
<p class="summer-hours__text">
I'm currently out of office for the summer. I'm getting married in July,
and I'll be spending as much time as possible out-of-doors in August.
I'll be back at keyboard in September.
</p>
<p class="summer-hours__signature">--TJW 2024-06-17</p>
</div>
<p class="heading__text">
It has been been It has been been
<span <span
class="days-since" class="days-since"
class:days-since-success="{daysSinceLastPublish === 0}" class:days-since-success={daysSinceLastPublish === 0}
> >
{daysSinceLastPublish} {daysSinceLastPublish}
</span> </span>
{daysSinceLastPublish === 1 ? "day" : "days"} since I last published something. {daysSinceLastPublish === 1 ? "day" : "days"} since I last published something.
</p> </p>
<p>
<p class="heading__text">
I have written {numberOfBlogPostsThisYear} I have written {numberOfBlogPostsThisYear}
{numberOfBlogPostsThisYear === 1 ? "piece" : "pieces"} so far this year. On {numberOfBlogPostsThisYear === 1 ? "piece" : "pieces"} so far this year. On
average I publish something every {averageDaysBetweenPosts} days ({numberOfPosts} average I publish something every {averageDaysBetweenPosts} days ({numberOfPosts}
@ -70,14 +81,14 @@
<ul class="posts"> <ul class="posts">
{#each posts as post, index} {#each posts as post, index}
<BlogPostListItem <BlogPostListItem
index="{index}" {index}
content_type="{post.content_type}" content_type={post.content_type}
book_review="{post.book_review}" book_review={post.book_review}
date="{post.date}" date={post.date}
numberOfPosts="{posts.length}" numberOfPosts={posts.length}
preview="{post.preview}" preview={post.preview}
slug="{post.slug}" slug={post.slug}
title="{post.title}" title={post.title}
/> />
{/each} {/each}
</ul> </ul>
@ -85,6 +96,12 @@
</main> </main>
<style lang="scss"> <style lang="scss">
.heading {
gap: var(--spacing-base);
display: grid;
grid-template-columns: 100%;
}
.posts { .posts {
list-style: none; list-style: none;
margin: 0; margin: 0;
@ -122,4 +139,31 @@
box-shadow: 0 0 0 5px rgba(54, 130, 127, 0); box-shadow: 0 0 0 5px rgba(54, 130, 127, 0);
} }
} }
.summer-hours {
border: 2px solid var(--brand-orange);
padding: var(--spacing-md) var(--spacing-lg);
border-radius: 8px;
margin-top: var(--spacing-base);
gap: 0px;
font-size: var(--font-size-sm);
}
.summer-hours__emoji {
font-family: sans-serif;
font-size: var(--font-size-xl);
margin: 0;
}
.summer-hours__text {
margin: 0;
font-size: var(--font-size-base);
line-height: 150%;
}
.summer-hours__signature {
margin: 0;
font-size: var(--font-size-sm);
text-align: right;
}
</style> </style>

View file

@ -12,17 +12,18 @@
<section class="homepage-header"> <section class="homepage-header">
<h1 class="title">(Thomas) Wilson</h1> <h1 class="title">(Thomas) Wilson</h1>
<p class="body"> <p class="body">Hand-maker of things, notably software and clothes.</p>
I love the craft of making well-built things, especially software and <p class="body">My personal goal is to:</p>
clothes. My embarrassing but earnest goal is to:
</p>
<blockquote class="mission-statement"> <blockquote class="mission-statement">
make things stronger which don&apos;t rely on exploitation, excessive waste, or make things stronger which don&apos;t rely on exploitation, excessive waste,
dishonesty; and to try and build a kinder, fairer world even when it's hard. or dishonesty; and to try and build a kinder, fairer world even when it's
hard.
</blockquote> </blockquote>
<p class="body"> <p class="body">
I try to think and be curious, which is why I keep a <a href="/blog">weblog</a I try to think and be curious, which is why I keep a <a href="/blog"
> and, equally worth mentioning, what got me through a >weblog</a
>
and, equally worth mentioning, what got me through a
<a <a
class="thesis" class="thesis"
target="_blank" target="_blank"
@ -49,8 +50,8 @@
href="https://www.laka.co.uk" href="https://www.laka.co.uk"
target="_blank" target="_blank"
rel="noopener noreferrer">Laka</a rel="noopener noreferrer">Laka</a
>, making insurance genuinely fairer. Before that, I was Head of >, making insurance genuinely fairer. Before that, I was Head of Software
Software Engineering at Engineering at
<a href="https://www.oxwash.com" target="_blank" rel="noopener noreferrer" <a href="https://www.oxwash.com" target="_blank" rel="noopener noreferrer"
>Oxwash</a >Oxwash</a
>, building tools for actually sustainable laundry and wet cleaning. >, building tools for actually sustainable laundry and wet cleaning.
@ -83,6 +84,7 @@
.body { .body {
text-align: left; text-align: left;
line-height: 160%;
} }
.latest-blog-posts { .latest-blog-posts {

View file

@ -1,99 +1,113 @@
@font-face { @font-face {
font-family: 'FivoSansModern-Regular'; font-family: "FivoSansModern-Regular";
src: url('/FivoSansModern-Regular.otf'); src: url("/FivoSansModern-Regular.otf");
font-display: swap; font-display: swap;
} }
:root { :root {
--brand-orange: #ff8c0d; --brand-orange: #ff8c0d;
--brand-purple: #464d77; --brand-purple: #464d77;
--brand-green: #36827f; --brand-green: #36827f;
--brand-blue: #00a0e9; --brand-blue: #00a0e9;
--white: #fff; --white: #fff;
--gray-100: #f8f9fa; --gray-100: #f8f9fa;
--gray-200: #e9ecef; --gray-200: #e9ecef;
--gray-300: #dee2e6; --gray-300: #dee2e6;
--gray-400: #ced4da; --gray-400: #ced4da;
--gray-500: #adb5bd; --gray-500: #adb5bd;
--gray-600: #6c757d; --gray-600: #6c757d;
--gray-700: #495057; --gray-700: #495057;
--gray-800: #343a40; --gray-800: #343a40;
--gray-900: #212529; --gray-900: #212529;
--gray-950: #1a1e23; --gray-950: #1a1e23;
--gray-1000: #0a0c0e; --gray-1000: #0a0c0e;
--font-family-mono: monospace; --font-family-mono: monospace;
--font-family-title: 'FivoSansModern-Regular', sans-serif; --font-family-title: "FivoSansModern-Regular", sans-serif;
--font-family-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', --font-family-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji",
--font-family-serif: Georgia, Cambria, 'Times New Roman', Times, serif; "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
--font-family-serif: Georgia, Cambria, "Times New Roman", Times, serif;
--line-height: 120%; --line-height: 120%;
--line-height-sm: 120%; --line-height-sm: 120%;
--line-height-md: 138%; --line-height-md: 138%;
--line-height-lg: 145%; --line-height-lg: 145%;
--font-size-base: 1rem; --font-size-xs: 0.75rem;
--spacing-base: 1rem; --font-size-sm: 0.875rem;
--spacing-sm: 0.25rem; --font-size-base: 1rem;
--spacing-md: 0.5rem; --font-size-lg: 1.25rem;
--spacing-lg: 1rem; --font-size-xl: 1.5rem;
--spacing-xl: 1.5rem; --font-size-2xl: 2rem;
--navbar-height: 75px; --spacing-base: 1rem;
--spacing-sm: 0.25rem;
--spacing-md: 0.5rem;
--spacing-lg: 1rem;
--spacing-xl: 1.5rem;
--navbar-height: 75px;
--font-size-sm: 0.875rem; --font-size-sm: 0.875rem;
--font-size: 1.12rem; --font-size: 1.12rem;
--font-size-md: 1.25rem; --font-size-md: 1.25rem;
--font-size-lg: 1.5rem; --font-size-lg: 1.5rem;
--btn-border: 0; --btn-border: 0;
--btn-padding: var(--spacing-sm); --btn-padding: var(--spacing-sm);
--btn-border-radius: 0.25rem; --btn-border-radius: 0.25rem;
--btn-font-size: 1.08rem; --btn-font-size: 1.08rem;
--btn-text-decoration: none; --btn-text-decoration: none;
} }
body { body {
font-family: var(--font-family-sans); font-family: var(--font-family-sans);
line-height: var(--line-height-md); line-height: var(--line-height-md);
min-height: 100vh; min-height: 100vh;
background-color: var(--colour-scheme-background); background-color: var(--colour-scheme-background);
color: var(--colour-scheme-text); color: var(--colour-scheme-text);
transition: 0.3s ease; transition: 0.3s ease;
transition-property: background-color, color; transition-property: background-color, color;
} }
.thomaswilson-container { .thomaswilson-container {
--container-padding: 24px; --container-padding: 24px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
min-height: calc(100vh - var(--navbar-height) - calc(2 * var(--container-padding))); min-height: calc(
padding: var(--container-padding); 100vh - var(--navbar-height) - calc(2 * var(--container-padding))
);
padding: var(--container-padding);
} }
.thomaswilson-container .section { .thomaswilson-container .section {
padding: 24px; padding: 24px;
width: 100%; width: 100%;
max-width: 750px; max-width: 750px;
font-size: 1.19rem; font-size: 1.19rem;
line-height: var(--line-height-md); line-height: var(--line-height-md);
padding-bottom: var(--spacing-base); padding-bottom: var(--spacing-base);
padding-bottom: 2rem; padding-bottom: 2rem;
} }
.thomaswilson-strapline .title { .thomaswilson-strapline .title {
font-family: var(--font-family-title); font-family: var(--font-family-title);
font-size: var(--font-size-base); font-size: var(--font-size-base);
font-weight: 700; font-weight: 700;
margin: 0; margin: 0;
} }
.thomaswilson-strapline p { .thomaswilson-strapline p {
font-size: 1.4rem; font-size: var(--font-size-md);
line-height: var(--line-height-md); line-height: var(--line-height-md);
letter-spacing: -0.25px; letter-spacing: -0.25px;
font-weight: 200; font-weight: 200;
}
@container (width < 500px) {
.thomaswilson-strapline p {
font-size: ;
}
} }
h1, h1,
@ -102,73 +116,73 @@ h3,
h4, h4,
h5, h5,
h6 { h6 {
font-family: var(--font-family-title); font-family: var(--font-family-title);
font-weight: 700; font-weight: 700;
margin: 0; margin: 0;
color: var(--colour-scheme-text); color: var(--colour-scheme-text);
padding-top: 12px; padding-top: 12px;
padding-bottom: 8px; padding-bottom: 8px;
line-height: var(--line-height); line-height: var(--line-height);
} }
h2 { h2 {
font-size: 2.25rem; font-size: 2.25rem;
padding-top: 0.7rem; padding-top: 0.7rem;
padding-bottom: 0.5rem; padding-bottom: 0.5rem;
} }
p, p,
li, li,
a, a,
blockquote { blockquote {
font-size: var(--font-size); font-size: var(--font-size);
line-height: var(--line-height-lg); line-height: var(--line-height-lg);
font-family: var(--font-family-mono); font-family: var(--font-family-mono);
margin: 0; margin: 0;
color: var(--colour-scheme-text); color: var(--colour-scheme-text);
padding: 8px 0; padding: 8px 0;
} }
blockquote { blockquote {
border-style: solid; border-style: solid;
padding: 0.25rem 0 0.5rem 1rem; padding: 0.25rem 0 0.5rem 1rem;
border-width: 0px; border-width: 0px;
border-left: 4px solid var(--brand-orange); border-left: 4px solid var(--brand-orange);
opacity: 0.85; opacity: 0.85;
max-width: 60ch; max-width: 60ch;
} }
ul, ul,
ol { ol {
padding-left: var(--spacing-base); padding-left: var(--spacing-base);
} }
.thomaswilson-button { .thomaswilson-button {
border: var(--btn-border); border: var(--btn-border);
padding: var(--btn-padding); padding: var(--btn-padding);
border-radius: var(--btn-border-radius); border-radius: var(--btn-border-radius);
font-size: var(--btn-font-size); font-size: var(--btn-font-size);
text-decoration: var(--btn-text-decoration); text-decoration: var(--btn-text-decoration);
} }
.thomaswilson-button:hover { .thomaswilson-button:hover {
text-decoration: none; text-decoration: none;
cursor: pointer; cursor: pointer;
} }
.sr-only { .sr-only {
position: absolute; position: absolute;
width: 1px; width: 1px;
height: 1px; height: 1px;
padding: 0; padding: 0;
margin: -1px; margin: -1px;
overflow: hidden; overflow: hidden;
clip: rect(0, 0, 0, 0); clip: rect(0, 0, 0, 0);
white-space: nowrap; white-space: nowrap;
border-width: 0; border-width: 0;
} }
img { img {
max-width: 100%; max-width: 100%;
height: auto; height: auto;
} }