[release] prepare 0.0.248 with demo and UI refinements #197
No files matched your search
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"@luzzle/web": patch
|
||||
---
|
||||
|
||||
Give sign-in a responsive branded card, consistent credential and single sign-on forms, clear error and pending states, and simple return/theme controls instead of the public search navbar. Keep client-side authentication and validated redirects unchanged.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"@luzzle/web": patch
|
||||
---
|
||||
|
||||
Center custom homepage Markdown below the navigation when both latest and random sections are disabled, while preserving normal layouts when either section is enabled.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"@luzzle/web": patch
|
||||
---
|
||||
|
||||
Show dashboard piece types in a compact table while retaining their names, counts, browse links and type-specific create actions.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"@luzzle/web": patch
|
||||
---
|
||||
|
||||
Show a usable search form on unfiltered `/search` visits, sharing controls with the navbar dialog. Keep filtered pages results-only, preserve dialog drafts between openings, and skip querying and hydrating pieces until filters are provided.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"@luzzle/web": patch
|
||||
---
|
||||
|
||||
Start previews through an explicit POST action instead of page loading or link preloading. Merge replayed preview logs by identity and show the latest attempt of each phase so working previews do not fail with duplicate rendering keys.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"@luzzle/web": patch
|
||||
---
|
||||
|
||||
Keep asset editor drafts scoped to their file, reset tag pagination when loaded results change, and ignore obsolete pagination and health-probe responses. Make preview destinations reactive while preserving each job's live progress.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"@luzzle/web": patch
|
||||
---
|
||||
|
||||
Share worker-generated preview files with the web service through a read-only preview mount in the production Compose examples. Document the directory setup and mount update required for existing deployments.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"@luzzle/web": patch
|
||||
---
|
||||
|
||||
Use compact sign-in typography, card sizing and form spacing while preserving themed colors and fonts, 16px credential inputs, 44px controls and existing authentication behavior. Leave public-site typography unchanged.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"@luzzle/web": patch
|
||||
---
|
||||
|
||||
Use the same responsive icon viewport for Preview and Published views, scaling each complete composition uniformly instead of shrinking its individual parts on narrow screens.
|
||||
@@ -1,5 +1,11 @@
|
||||
# @luzzle/cli
|
||||
|
||||
## 0.0.248
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @luzzle/core@0.0.248
|
||||
|
||||
## 0.0.247
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@luzzle/cli",
|
||||
"version": "0.0.247",
|
||||
"version": "0.0.248",
|
||||
"author": "eleith",
|
||||
"scripts": {
|
||||
"lint": "eslint src",
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# @luzzle/core
|
||||
|
||||
## 0.0.248
|
||||
|
||||
## 0.0.247
|
||||
|
||||
## 0.0.246
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@luzzle/core",
|
||||
"version": "0.0.247",
|
||||
"version": "0.0.248",
|
||||
"author": "eleith",
|
||||
"scripts": {
|
||||
"lint": "eslint src",
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# @luzzle/lsp
|
||||
|
||||
## 0.0.248
|
||||
|
||||
## 0.0.247
|
||||
|
||||
## 0.0.246
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@luzzle/lsp",
|
||||
"version": "0.0.247",
|
||||
"version": "0.0.248",
|
||||
"author": "eleith",
|
||||
"description": "LSP proxy for YAML frontmatter validation in Luzzle markdown files",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
# @luzzle/web
|
||||
|
||||
## 0.0.248
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 79d3e90: Give sign-in a responsive branded card, consistent credential and single sign-on forms, clear error and pending states, and simple return/theme controls instead of the public search navbar. Keep client-side authentication and validated redirects unchanged.
|
||||
- b89f433: Center custom homepage Markdown below the navigation when both latest and random sections are disabled, while preserving normal layouts when either section is enabled.
|
||||
- 66dc919: Show dashboard piece types in a compact table while retaining their names, counts, browse links and type-specific create actions.
|
||||
- e730e6f: Show a usable search form on unfiltered `/search` visits, sharing controls with the navbar dialog. Keep filtered pages results-only, preserve dialog drafts between openings, and skip querying and hydrating pieces until filters are provided.
|
||||
- a9151cc: Start previews through an explicit POST action instead of page loading or link preloading. Merge replayed preview logs by identity and show the latest attempt of each phase so working previews do not fail with duplicate rendering keys.
|
||||
- 4ec5e52: Keep asset editor drafts scoped to their file, reset tag pagination when loaded results change, and ignore obsolete pagination and health-probe responses. Make preview destinations reactive while preserving each job's live progress.
|
||||
- 8f3f312: Share worker-generated preview files with the web service through a read-only preview mount in the production Compose examples. Document the directory setup and mount update required for existing deployments.
|
||||
- 2c1c0e0: Use the shared up-left navigation icon instead of the sign-in page's text back link, preserving its home destination, accessible label and keyboard focus with a 44px hit target.
|
||||
- 68c1dd6: Use compact sign-in typography, card sizing and form spacing while preserving themed colors and fonts, 16px credential inputs, 44px controls and existing authentication behavior. Leave public-site typography unchanged.
|
||||
- 2c66a44: Use softer, near-white surface containers in the default light palette and the bundled demo. Preserve dark palettes, accent colors and existing focus behavior.
|
||||
- 99f793f: Use the same responsive icon viewport for Preview and Published views, scaling each complete composition uniformly instead of shrinking its individual parts on narrow screens.
|
||||
- @luzzle/web.db@0.0.1
|
||||
- @luzzle/web.pieces@0.0.1
|
||||
- @luzzle/web.templates@0.0.1
|
||||
|
||||
## 0.0.247
|
||||
|
||||
### Patch Changes
|
||||
|
||||
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 79 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 354 KiB |
|
Before Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 577 KiB |
|
After Width: | Height: | Size: 9.5 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 8.0 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 21 KiB |
@@ -0,0 +1,8 @@
|
||||
import re
|
||||
import unicodedata
|
||||
|
||||
|
||||
def slugify(title: str) -> str:
|
||||
normalized = unicodedata.normalize("NFKD", title)
|
||||
ascii_title = normalized.encode("ascii", "ignore").decode("ascii")
|
||||
return re.sub(r"[^a-z0-9]+", "-", ascii_title.lower()).strip("-")
|
||||
|
After Width: | Height: | Size: 9.0 KiB |
|
After Width: | Height: | Size: 7.9 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"title": "articles",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string",
|
||||
"examples": ["A Small Web Worth Keeping"]
|
||||
},
|
||||
"author": {
|
||||
"type": "string",
|
||||
"examples": ["Mira Chen"]
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"examples": ["https://example.com/articles/a-small-web-worth-keeping"],
|
||||
"pattern": "^https?://"
|
||||
},
|
||||
"summary": {
|
||||
"type": "string",
|
||||
"format": "paragraph"
|
||||
},
|
||||
"word_count": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"date_published": {
|
||||
"type": "string",
|
||||
"format": "date"
|
||||
},
|
||||
"date_read": {
|
||||
"type": "string",
|
||||
"format": "date"
|
||||
},
|
||||
"keywords": {
|
||||
"type": "string",
|
||||
"format": "comma-separated"
|
||||
},
|
||||
"banner": {
|
||||
"type": "string",
|
||||
"format": "asset"
|
||||
}
|
||||
},
|
||||
"required": ["title", "author", "url"],
|
||||
"additionalProperties": true
|
||||
}
|
||||
@@ -27,6 +27,12 @@
|
||||
"enum": ["movie", "tv", "video"],
|
||||
"examples": ["movie"]
|
||||
},
|
||||
"director": {
|
||||
"description": "The director of the film",
|
||||
"type": "string",
|
||||
"examples": ["Mira Sol"],
|
||||
"nullable": true
|
||||
},
|
||||
"people": {
|
||||
"description": "A comma separated list of people involved in the film",
|
||||
"type": "string",
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"title": "generic",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string",
|
||||
"examples": ["A Ticket for the Night Tram"]
|
||||
},
|
||||
"summary": {
|
||||
"type": "string",
|
||||
"format": "paragraph"
|
||||
},
|
||||
"date_added": {
|
||||
"type": "string",
|
||||
"format": "date"
|
||||
},
|
||||
"keywords": {
|
||||
"type": "string",
|
||||
"format": "comma-separated"
|
||||
}
|
||||
},
|
||||
"required": ["title"],
|
||||
"additionalProperties": true
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"title": "music",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string",
|
||||
"examples": ["After the Last Tram"]
|
||||
},
|
||||
"artist": {
|
||||
"type": "string",
|
||||
"examples": ["The Night Windows"]
|
||||
},
|
||||
"summary": {
|
||||
"type": "string",
|
||||
"format": "paragraph"
|
||||
},
|
||||
"album": {
|
||||
"type": "string"
|
||||
},
|
||||
"duration_seconds": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"date_released": {
|
||||
"type": "string",
|
||||
"format": "date"
|
||||
},
|
||||
"date_listened": {
|
||||
"type": "string",
|
||||
"format": "date"
|
||||
},
|
||||
"language": {
|
||||
"type": "string"
|
||||
},
|
||||
"collaborators": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" }
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"pattern": "^https?://"
|
||||
},
|
||||
"cover": {
|
||||
"type": "string",
|
||||
"format": "asset"
|
||||
},
|
||||
"keywords": {
|
||||
"type": "string",
|
||||
"format": "comma-separated"
|
||||
}
|
||||
},
|
||||
"required": ["title", "artist"],
|
||||
"additionalProperties": true
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
{
|
||||
"title": "recipes",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string",
|
||||
"examples": ["Roasted Tomato Pasta"]
|
||||
},
|
||||
"summary": {
|
||||
"type": "string",
|
||||
"format": "paragraph"
|
||||
},
|
||||
"source": {
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"pattern": "^https?://"
|
||||
},
|
||||
"photo": {
|
||||
"type": "string",
|
||||
"format": "asset"
|
||||
},
|
||||
"ingredients": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"item": { "type": "string" },
|
||||
"quantity": { "type": "number", "minimum": 0 },
|
||||
"unit": { "type": "string" },
|
||||
"note": { "type": "string" }
|
||||
},
|
||||
"required": ["item"],
|
||||
"examples": [{ "item": "cherry tomatoes", "quantity": 600, "unit": "g", "note": "halved" }],
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"instructions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"text": { "type": "string" }
|
||||
},
|
||||
"required": ["text"],
|
||||
"examples": [{ "text": "Heat the oven to 220°C." }],
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"prep_minutes": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"cook_minutes": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"total_minutes": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"date_cooked": {
|
||||
"type": "string",
|
||||
"format": "date"
|
||||
},
|
||||
"date_updated": {
|
||||
"type": "string",
|
||||
"format": "date"
|
||||
},
|
||||
"keywords": {
|
||||
"type": "string",
|
||||
"format": "comma-separated"
|
||||
}
|
||||
},
|
||||
"required": ["title", "ingredients", "instructions"],
|
||||
"additionalProperties": true
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"title": "tabletop-games",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string",
|
||||
"examples": ["The Lantern Market"]
|
||||
},
|
||||
"summary": {
|
||||
"type": "string",
|
||||
"format": "paragraph"
|
||||
},
|
||||
"publisher": {
|
||||
"type": "string"
|
||||
},
|
||||
"player_count": {
|
||||
"type": "integer",
|
||||
"examples": [2],
|
||||
"minimum": 1
|
||||
},
|
||||
"play_time_minutes": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"date_published": {
|
||||
"type": "string",
|
||||
"format": "date"
|
||||
},
|
||||
"date_played": {
|
||||
"type": "string",
|
||||
"format": "date"
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"pattern": "^https?://"
|
||||
},
|
||||
"cover": {
|
||||
"type": "string",
|
||||
"format": "asset"
|
||||
},
|
||||
"keywords": {
|
||||
"type": "string",
|
||||
"format": "comma-separated"
|
||||
}
|
||||
},
|
||||
"required": ["title", "player_count"],
|
||||
"additionalProperties": true
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"title": "video-games",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string",
|
||||
"examples": ["Starfall Station"]
|
||||
},
|
||||
"summary": {
|
||||
"type": "string",
|
||||
"format": "paragraph"
|
||||
},
|
||||
"publisher": {
|
||||
"type": "string"
|
||||
},
|
||||
"platform": {
|
||||
"type": "string",
|
||||
"examples": ["Pocket Console"]
|
||||
},
|
||||
"play_time_minutes": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"date_published": {
|
||||
"type": "string",
|
||||
"format": "date"
|
||||
},
|
||||
"date_played": {
|
||||
"type": "string",
|
||||
"format": "date"
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"pattern": "^https?://"
|
||||
},
|
||||
"cover": {
|
||||
"type": "string",
|
||||
"format": "asset"
|
||||
},
|
||||
"keywords": {
|
||||
"type": "string",
|
||||
"format": "comma-separated"
|
||||
}
|
||||
},
|
||||
"required": ["title", "platform"],
|
||||
"additionalProperties": true
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
title: A Small Web Worth Keeping
|
||||
author: Mira Chen
|
||||
url: https://example.com/articles/a-small-web-worth-keeping
|
||||
summary: Personal websites are places to leave useful trails, not just polished destinations.
|
||||
word_count: 1460
|
||||
date_published: 2025-06-12
|
||||
date_read: 2026-10-20
|
||||
keywords: web, writing, digital gardens, keeping things
|
||||
banner: .assets/articles/banner/a-small-web-worth-keeping.png
|
||||
---
|
||||
The part I keep returning to is the idea that a website can be a **workbench**,
|
||||
not a finished exhibition. A reading list, an unfinished recipe and a small
|
||||
collection of useful commands all belong there.
|
||||
|
||||
> Leave enough context that your future self can pick up the thread.
|
||||
|
||||
Things to try on my own site:
|
||||
|
||||
- Link related notes even when neither is finished.
|
||||
- Keep the reason I saved something beside the link.
|
||||
- Prefer a small page I can maintain over a large system I cannot.
|
||||
|
||||
The original article is longer; these are just my notes from reading it.
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
title: The Shape of a Useful Notebook
|
||||
author: Ivo Mercer
|
||||
url: https://example.com/articles/the-shape-of-a-useful-notebook
|
||||
summary: A notebook becomes useful when it is easy to return to, not when every page looks finished.
|
||||
word_count: 980
|
||||
date_published: 2024-09-03
|
||||
date_read: 2026-10-26
|
||||
keywords: writing, notebooks, craft, keeping things
|
||||
banner: .assets/articles/banner/the-shape-of-a-useful-notebook.png
|
||||
---
|
||||
A fictional essay with a practical distinction: collecting an idea and finding
|
||||
it again are two different jobs. A notebook should make both easy enough that
|
||||
neither feels like maintenance.
|
||||
|
||||
I am borrowing three habits:
|
||||
|
||||
1. Leave a few blank lines after an interesting thought.
|
||||
2. Give unfinished questions their own index entry.
|
||||
3. Add a date when returning to an old page rather than rewriting its history.
|
||||
|
||||
The most useful example was a page with several crossed-out headings. You could
|
||||
still see how the question changed, which made the final answer more convincing.
|
||||
@@ -1,31 +0,0 @@
|
||||
---
|
||||
title: A Prayer for the Crown-Shy
|
||||
author: Becky Chambers
|
||||
isbn: "9781250236241"
|
||||
date_read: 2024-02-16
|
||||
subtitle: A Monk and Robot Book
|
||||
pages: 94
|
||||
keywords: becky chambers,science
|
||||
fiction,novel,relationships,friendship,family,space
|
||||
opera,aliens,exploration,hope,diversity,lgbtq+,intergalactic,identity,humanity,technology,solitude,adventure,empathy,acceptance,community,forgiveness,speculative
|
||||
fiction,inspirational,heartwarming,inclusivity,space
|
||||
travel,communication,future,optimism,compassion,belonging,discovery,imagination,growth,reflection,kindness,alien
|
||||
cultures,transformation,thought-provoking,worldbuilding,emotional,encouraging,imaginative,uplifting
|
||||
description: In a quiet corner of the universe, a small remote planet is home to
|
||||
an unusual forest, where trees communicate through a network of fungus and
|
||||
possess a mysterious aversion to touching one another. Among the trees live a
|
||||
community of humans who hold a deep reverence for these sentient beings. When
|
||||
a botanist named Tavor is called to the planet to study the forest and its
|
||||
enigmatic behavior, he forms a unique bond with an eccentric local named
|
||||
Solly. As they navigate the intricacies of the forest's ecosystem, they
|
||||
uncover secrets that challenge their understanding of life, connection, and
|
||||
the power of nature. 'A Prayer for the Crown-Shy' is a beautifully crafted
|
||||
tale that explores the intersection of science, spirituality, and the innate
|
||||
desire for harmony in a world filled with wonder and mystery.
|
||||
cover: .assets/books/cover/a-prayer-for-the-crown-shy.jpg
|
||||
year_first_published: 2022
|
||||
url: https://openlibrary.org/books/OL35097780M
|
||||
coauthors: ""
|
||||
---
|
||||
|
||||
have some tea
|
||||
@@ -1,28 +0,0 @@
|
||||
---
|
||||
title: Debt
|
||||
author: David Graeber
|
||||
url: https://openlibrary.org/works/OL14909099W/Debt
|
||||
subtitle: The First 5000 Years
|
||||
description: "For centuries, scholars have assumed that the origins of money lay
|
||||
in barter. In this provocative and widely acclaimed book, David Graeber argues
|
||||
that this assumption is wrong, that debt, not barter, is the foundation of all
|
||||
our economic systems. Starting with the earliest forms of social organization,
|
||||
Graeber traces the history of debt across cultures and millennia, uncovering a
|
||||
surprising pattern: in every society, from prehistoric hunter-gatherer bands
|
||||
to the modern age, debt has served as both a powerful tool of social control
|
||||
and a potent engine of social change."
|
||||
pages: 544
|
||||
year_first_published: 2011
|
||||
isbn: "9781933633862"
|
||||
keywords: Debt, History, Anthropology, Economics, Social Anthropology, Money,
|
||||
Social Control, Social Change, Barter, Hunter-gatherers, Civilization,
|
||||
Capitalism, Neoliberalism, Ancient History, Mesopotamian, Egyptian, Greek,
|
||||
Roman, Medieval, Renaissance, Enlightenment, Industrial Revolution, Modern,
|
||||
Contemporary, Marxist, Anarchist, Political Economy, Sociology, Philosophy,
|
||||
Psychology, Religion, Culture, Civilization, Globalization, Globalization,
|
||||
Western Civilization, World History
|
||||
date_read: 2024-08-31
|
||||
cover: .assets/books/cover/debt.books-a41371c1.jpg
|
||||
---
|
||||
|
||||
that is a lot of ... debt
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
title: The Atlas of Quiet Places
|
||||
author: Mara Vale
|
||||
description: A mapmaker follows the blank spaces in her father's notebooks and discovers that some places are remembered only by the people who leave them.
|
||||
pages: 286
|
||||
year_first_published: 2018
|
||||
url: https://example.com/books/the-atlas-of-quiet-places
|
||||
cover: .assets/books/cover/the-atlas-of-quiet-places.png
|
||||
date_read: 2026-10-10
|
||||
keywords: fiction, maps, walking, memory, keeping things
|
||||
---
|
||||
A fictional novel about noticing what a map leaves out: the bench that catches
|
||||
the last sunlight, a path that only appears at low tide, a house everyone
|
||||
remembers by a different name.
|
||||
|
||||
The chapters alternate between a journey and the notes for an unfinished atlas.
|
||||
I preferred the small detours to the mystery that ties them together.
|
||||
|
||||
> A useful map tells you where you are. A good one gives you a reason to stay.
|
||||
|
||||
Worth returning to slowly, with a notebook nearby. The final chapter changes
|
||||
the meaning of a very ordinary bridge from the opening pages.
|
||||
@@ -1,31 +0,0 @@
|
||||
---
|
||||
title: The Electric State
|
||||
author: Simon Stålenhag
|
||||
url: https://openlibrary.org/works/OL19761147W/The_electric_state
|
||||
isbn: "9781501181412"
|
||||
description: From the visionary artist behind the acclaimed "Tales from the
|
||||
Loop" comes a dazzling novel of a young woman, a mysterious android, and a
|
||||
journey across a strange and beautiful America. It's 1997. After the death
|
||||
of her parents, sixteen-year-old Michelle carries a box containing an
|
||||
enigmatic android, a box her father told her she was never to open. When the
|
||||
android suddenly awakens, Michelle sets off on a cross-country journey with
|
||||
her brother, a runaway from an orphanage, and a talking dog. They are pursued
|
||||
by a mysterious force, a sinister agency that wants to capture the android and
|
||||
its extraordinary secrets. Along the way, they encounter strange and wonderful
|
||||
characters - an enigmatic robot cowboy, a group of teenagers who live in a
|
||||
dilapidated amusement park, and a woman who drives a vintage car with a
|
||||
sentient AI. As they journey deeper into the heart of America, Michelle
|
||||
begins to understand that the android is not what it seems, and that her life
|
||||
is intertwined with a dark conspiracy that threatens to unravel the very
|
||||
fabric of reality.
|
||||
pages: 133
|
||||
year_first_published: 2018
|
||||
cover: .assets/books/cover/the-electric-state-70071d00.jpg
|
||||
keywords: sci-fi, dystopian, road trip, android, mystery, coming-of-age, robots,
|
||||
artificial intelligence, america, 1990s, alternate history
|
||||
date_read: 2024-09-24
|
||||
coauthors: ""
|
||||
subtitle: ""
|
||||
---
|
||||
|
||||
it was very ... electric
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
title: The House Beyond the Tide
|
||||
author: Elias North
|
||||
description: Three generations take turns keeping a coastal house that the sea allows them to visit for only a few hours each day.
|
||||
pages: 512
|
||||
year_first_published: 2021
|
||||
url: https://example.com/books/the-house-beyond-the-tide
|
||||
cover: .assets/books/cover/the-house-beyond-the-tide.png
|
||||
date_read: 2026-10-11
|
||||
keywords: fiction, coast, family, time, keeping things
|
||||
---
|
||||
A fictional family saga built around a wonderfully impractical house. Every
|
||||
visit begins with checking the tide tables; every departure leaves something
|
||||
unfinished.
|
||||
|
||||
## What stayed with me
|
||||
|
||||
- The grandmother's habit of dating every repair in pencil beneath the stairs.
|
||||
- A room whose purpose changes with each generation.
|
||||
- The long argument about whether keeping a place is the same as preserving it.
|
||||
|
||||
It takes its time. At first the repeated crossings feel excessive, but eventually
|
||||
the rhythm becomes the point: the same walk, a different person carrying the key.
|
||||
@@ -1,22 +0,0 @@
|
||||
---
|
||||
title: "1917"
|
||||
url: https://www.themoviedb.org/movie/530915-1917
|
||||
homepage: https://www.1917.movie/
|
||||
type: movie
|
||||
people: Sam Mendes, Krysty Wilson-Cairns, George MacKay, Dean-Charles Chapman,
|
||||
Mark Strong, Andrew Scott, Richard Madden, Claire Duburcq, Colin Firth,
|
||||
Benedict Cumberbatch, Daniel Mays
|
||||
subtitle: film subtitle
|
||||
summary: At the height of the First World War, two young British soldiers must
|
||||
cross enemy territory and deliver a message that will stop a deadly attack on
|
||||
hundreds of soldiers.
|
||||
keywords: world war i, trench warfare, 1910s, british army, war, soldier, behind
|
||||
enemy lines, no man's land, race against time, one shot, real time, drama,
|
||||
thriller, history
|
||||
date_released: 2019-10-18
|
||||
date_viewed: 2024-11-21
|
||||
runtime: 120
|
||||
language: en
|
||||
poster: .assets/films/poster/1917-0124e26e.jpg
|
||||
---
|
||||
keep. on. running.
|
||||
@@ -1,66 +0,0 @@
|
||||
---
|
||||
title: Godzilla minus one
|
||||
type: movie
|
||||
summary: In postwar Japan, Godzilla brings new devastation to an already
|
||||
scorched landscape. With no military intervention or government help in sight,
|
||||
the survivors must join together in the face of despair and fight back against
|
||||
an unrelenting horror.
|
||||
date_released: 2023-11-03
|
||||
runtime: 124
|
||||
subtitle: Postwar Japan. From zero to minus.
|
||||
language: ja
|
||||
url: https://www.themoviedb.org/movie/940721
|
||||
homepage: https://godzillafilm.co.uk
|
||||
keywords: Science Fiction, Horror, Action, monster, loss of loved one, giant
|
||||
monster, kamikaze, duty, atomic bomb test, radioactivity, naval combat,
|
||||
reboot, kaiju, duringcreditsstinger, post war japan, 1940s, naval battle,
|
||||
naval battleship, found family, godzilla, war orphan, survivor guilt,
|
||||
tokusatsu, 哥斯拉-1.0
|
||||
people: Ryunosuke Kamiki, Minami Hamabe, Yuki Yamada, Munetaka Aoki, Hidetaka
|
||||
Yoshioka, Sakura Ando, Kuranosuke Sasaki, Saki Nakatani, Mio Tanaka, Yuya
|
||||
Endo, Kisuke Iida, Kenji Anan, Kenji Mizuhashi, Kunihiro Suda, Shota
|
||||
Taniguchi, Akio Nakadai, Ippei Sasaki, Ozuno Nakamura, Masaichi Wanibuchi, Sho
|
||||
Nishigaki, Fuma Sasaki, Tsutomu Osabe, Yuji Komatsu, Yosuke Minokawa, Sentarou
|
||||
Kusakabe, Kota Kawabata, Genki Furugen, Yuto Yoshikawa, Yuya Oshima, Hirotaka
|
||||
Akatsuma, Ryo Hamanaka, Kiyomi Aratani, Yukio Tsukamoto, Shoji Omiya, Michael
|
||||
Arias, Masataka Matsubara, Kentaro Furuyama, Takumi Matsui, Tetsu Hirahara,
|
||||
Hiroyuki Toritani, Seitaro Chiba, Tatsuki Oguma, Hidemasa Mase, Jun Ohnishi,
|
||||
Yuho Mochinaga, Daiki Ichikawa, Yasunori Ota, Ryota Tsuchihashi, Atsushi
|
||||
Saitou, Masayuki Yamada, Goro Sato, Keisuke Fujita, Yuta Wakabayashi, Koya
|
||||
Fukuda, Shunpeter Sugisaki, Yuki Takao, Yusuke Karita, Makoto Matsumoto,
|
||||
Shinji Nagashima, Akihiro Yamamoto, Hidehiko Yamada, Atomu Ito, Django Yamada,
|
||||
Gomez Hori, Shohei Abe, Gen Shimada, Masatoshi Kihara, Masaru Yahagi, Touta
|
||||
Tawaragi, Etsuji Harada, Senji Nakagi, Tetsunori Akira, Mao Ohno, Ami
|
||||
Kitamikado, Yoka, Mami Tokuda, Yukihide Ueda, Sho Tsuruta, Makoto Araki,
|
||||
Yamato Aizawa, Mizuki Hasegawa, Kisuke Inoue, Miki Mirai, Daichi Abe, Rikako
|
||||
Miura, Gohshuu, Yuko Onose, Seiji Okuda, Eisuke Sasai, Shinsuke Kasai, Saori,
|
||||
Takato Yonemoto, Yoshiyo Naka, Ikumu Shigeta, Keita Chiba, Masato Nakano,
|
||||
Kiyoshi Uchida, Aya Sakura, Ayane Kamoi, Risa Miyake, Mami Aoki, Takashi
|
||||
Yamazaki, Takashi Yamazaki, Naoki Sato, Kōzō Shibazaki, Ryuji Miyajima, Go
|
||||
Abe, Shuji Abe, Minami Ichikawa, Kazuaki Kishida, Keiichiro Moriya, Hisashi
|
||||
Usui, Kenji Yamada, Tsuyoshi Sugino, Anri Jojo, Aiko Mizushima, Michiyo
|
||||
Miyauchi, Michiyo Miyauchi, Kohei Adachi, Kiyoko Shibuya, Takashi Yamazaki,
|
||||
Nariyuki Ueda, Tatsuji Nojima, Hiroshi Sakurai, Masaki Takahashi, Hisafumi
|
||||
Takeuchi, Masahiro Ishiyama, Taichi Ueda, Akihiro Yamauchi, Natsuko Inoue,
|
||||
Tetsuji Tatsuta, Michael Arias, Nozomu Aida, Akira Ifukube, Fay Kanagy,
|
||||
Sakurako Morita, Yoshihito Yokoi, Tetsuji Tatsuta, Natsuko Inoue, Natsuko
|
||||
Inoue, Natsuko Inoue, Hisafumi Takeuchi, Hisafumi Takeuchi, Junya Ando,
|
||||
Michael Arias, Koji Busaka, Sachiko Eba, Mika Emura, Kaito Hasegawa, Tatsuya
|
||||
Hayasaki, Tatsuya Hayasaki, Takafumi Iwata, Khitish Shekhar Karua, Yûki
|
||||
Kawahara, Makoto Kazamaki, Toshihiko Masaki, Ryô Matsumoto, Shinji Miyake,
|
||||
Tomoyuki Miyake, Tatsuji Nojima, Tatsuji Nojima, Yoshihito Odaka, Eisin Okubo,
|
||||
Junpei Sakô, Shôichirô Satô, Shôichirô Satô, Takeyuki Shirahama, Kazutaka
|
||||
Sugiyama, Katsumi Suzuki, Shinya Suzuki, Kosuke Taguchi, Masaaki Tokaji,
|
||||
Takayuki Ueki, Takuya Uenishi, Motohiro Yamada, Takushi Yamaguchi, Satoru
|
||||
Okuda, Tomoki Andô, Kôzô Araki, Takumi Hasegawa, Hitoshi Imai, Toshitsugu
|
||||
Inoue, Naoki Ishiyama, Shun Itô, Masami Iwasa, Kazuhiro Kajihara, Yuto Kamei,
|
||||
Hikaru Koga, Tadayori Matsumoto, Takayuki Mogami, Mina Muranaka, Koichiro
|
||||
Muroya, Hidehito Naka, Sayoko Narukawa, Kôichi Nonoshita, Mizuki Ogura,
|
||||
Masamichi Sasazaki, Naoki Sato, Naoki Sato, Keisuke Sumikawa, Atsushi
|
||||
Takahashi, Jun'ichirô Taku, Shinsuke Tomizuka, Shinpei Tsugita, Ken'ichi
|
||||
Tsujimoto, Yoshiyuki Uema, Shunji Yamaguchi, Reo Yoshida, Chikako Aho
|
||||
poster: .assets/films/poster/godzilla-minus-one-40db669b.jpg
|
||||
date_viewed: 6/7/24
|
||||
---
|
||||
|
||||
run!
|
||||
@@ -1,30 +0,0 @@
|
||||
---
|
||||
title: mars express
|
||||
type: movie
|
||||
summary: In 2200, private detective Aline Ruby and her android partner Carlos
|
||||
Rivera are hired by a wealthy businessman to track down a notorious hacker. On
|
||||
Mars, they descend deep into the underbelly of the planet's capital city where
|
||||
they uncover a darker story of brain farms, corruption, and a missing girl who
|
||||
holds a secret about the robots that threatens to change the face of the
|
||||
universe.
|
||||
date_released: 2023-11-22
|
||||
runtime: 89
|
||||
subtitle: Built to serve. Programmed to live.
|
||||
language: fr
|
||||
url: https://www.themoviedb.org/movie/586810
|
||||
homepage: https://gkids.com/films/mars-express
|
||||
keywords: Animation, Science Fiction, Action, Mystery, android, planet mars,
|
||||
hacker, private detective, near future, arrogant, cliché
|
||||
people: Léa Drucker, Mathieu Amalric, Daniel Njo Lobé, Marie Bouvet, Sébastien
|
||||
Chassagne, Marthe Keller, Geneviève Doang, Thomas Roditi, Usul, Nicolas
|
||||
Justamon, Jérémie Bédrune, Thierry Jahn, Serge Faliu, Eilias Changuel, Barbara
|
||||
Delsol, Nathalie Karsenti, Angéline Henneguelle, Charlotte Junière, Fanny
|
||||
Vambacas, Delphine Braillon, Emmanuel Bonami, Martial Le Minoux, Renaud
|
||||
Jesionek, Maxime Pacaud, Marie Chevalot, Laurent Sarfati, Jérémie Périn,
|
||||
Philippe Monthaye, Jérémie Périn, Laurent Sarfati, Jérémie Périn, Fred Avril,
|
||||
Mikael Robert, Arnauld Boulard, Fanny Bricoteau, Kévin Feildel, Grégory
|
||||
Vincent, Cyprien Nozières, Lila Desiles
|
||||
poster: .assets/films/poster/mars-express-a7f29435.jpg
|
||||
date_viewed: 6/21/24
|
||||
---
|
||||
robots.
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
title: Postcards from the Inland Sea
|
||||
type: movie
|
||||
summary: A retired postal worker crosses a chain of islands to deliver a box of letters that were never sent, collecting new messages along the way.
|
||||
subtitle: The long way home is still a way home.
|
||||
director: Ren Okada
|
||||
people: Aya Mori, Samir Hale, Rosa Bell
|
||||
runtime: 87
|
||||
language: ja
|
||||
date_released: 2024-04-19
|
||||
date_viewed: 2026-10-13
|
||||
url: https://example.com/films/postcards-from-the-inland-sea
|
||||
poster: .assets/films/poster/postcards-from-the-inland-sea.png
|
||||
backdrop: .assets/films/backdrop/postcards-from-the-inland-sea.png
|
||||
keywords: films, islands, travel, letters, keeping things
|
||||
---
|
||||
A fictional film made of ferry crossings, short conversations and meals that
|
||||
last a little longer than expected. There is very little urgency, which is
|
||||
exactly what the story needs.
|
||||
|
||||
The framing keeps finding rectangles inside the landscape: envelopes, cabin
|
||||
windows, the bright doorway of a shop at closing time.
|
||||
|
||||
> Not every letter needs an answer. Some only need to arrive.
|
||||
|
||||
A good companion to a quiet afternoon. I wanted another ten minutes with the
|
||||
family who run the smallest post office on the route.
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
title: The Last Light on Platform Nine
|
||||
type: movie
|
||||
summary: On the final night before a mountain station closes, its signal keeper receives a request to hold the last train for a passenger nobody remembers seeing.
|
||||
subtitle: Some departures are worth delaying.
|
||||
director: Mira Sol
|
||||
people: Lena Sato, Theo Marin, Imani Reed
|
||||
runtime: 104
|
||||
language: en
|
||||
date_released: 2022-10-14
|
||||
date_viewed: 2026-10-12
|
||||
url: https://example.com/films/the-last-light-on-platform-nine
|
||||
poster: .assets/films/poster/the-last-light-on-platform-nine.png
|
||||
backdrop: .assets/films/backdrop/the-last-light-on-platform-nine.png
|
||||
keywords: films, mystery, trains, night walks, memory
|
||||
---
|
||||
A fictional, mostly nocturnal mystery that makes a railway timetable feel like
|
||||
a collection of promises.
|
||||
|
||||
The best scenes barely move: a kettle coming to the boil, a signal changing in
|
||||
the distance, two people listening for the same train. The warm station windows
|
||||
against the blue mountains do almost as much storytelling as the dialogue.
|
||||
|
||||
I liked that the ending answers the practical question and leaves the emotional
|
||||
one open. Watch without looking up the plot first.
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
title: A Key with No Door
|
||||
summary: A brass key from a tin of spare buttons, kept for its shape long after anyone remembered the lock.
|
||||
date_added: 2026-10-31
|
||||
keywords: keepsakes, objects, family, keeping things
|
||||
---
|
||||
The label fell off years ago. Nobody in the family can agree whether the key
|
||||
belonged to a desk, a garden gate or the cupboard under the stairs.
|
||||
|
||||
It has a pleasing weight and a small crescent worn into one edge. I keep it on
|
||||
the shelf beside the tram ticket, which is probably not a classification system
|
||||
but is good enough for now.
|
||||
|
||||
> An object can lose its purpose without losing its story.
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
title: A Ticket for the Night Tram
|
||||
summary: A small paper reminder of a long walk, a missed stop and an unexpectedly good evening.
|
||||
date_added: 2026-10-25
|
||||
keywords: keepsakes, night walks, travel, keeping things
|
||||
---
|
||||
Some things are worth keeping before I know which collection they belong in.
|
||||
This ticket has a faded date, a blue stripe and a corner folded by too many
|
||||
trips through a coat pocket.
|
||||
|
||||
The tram stopped short of the river, so we walked the rest of the way. There
|
||||
was a bakery still open near the bridge.
|
||||
|
||||
- Keep the story beside the object.
|
||||
- Leave room to add a photograph later.
|
||||
- Do not invent a special category just to save one good memory.
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
title: After the Last Tram
|
||||
artist: The Night Windows
|
||||
summary: Warm bass, sparse French vocals and a melody that takes its time getting home.
|
||||
album: Small Hours
|
||||
duration_seconds: 247
|
||||
date_released: 2024-08-16
|
||||
date_listened: 2026-10-22
|
||||
language: fr
|
||||
collaborators:
|
||||
- Mira Chen
|
||||
- Alex Rivera
|
||||
url: https://example.com/music/after-the-last-tram
|
||||
cover: .assets/music/cover/after-the-last-tram.png
|
||||
keywords: music, night walks, electronic, keeping things
|
||||
---
|
||||
A fictional track for an imaginary walk home after the city has gone quiet.
|
||||
|
||||
I like the way the bass arrives before the drums. The little keyboard figure
|
||||
returns near the end, but a few notes have moved; it feels familiar without
|
||||
quite landing in the same place.
|
||||
|
||||
**Best moment:** the pause just before the final chorus. Listen with headphones
|
||||
rather than leaving it in the background.
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
title: Morning in the Glasshouse
|
||||
artist: Juniper Lines
|
||||
summary: Fingerpicked guitar and a small choir of room sounds, recorded as the sun moved across a greenhouse floor.
|
||||
album: Glass and Air
|
||||
duration_seconds: 193
|
||||
date_released: 2023-05-11
|
||||
date_listened: 2026-10-28
|
||||
language: en
|
||||
collaborators:
|
||||
- Emery Stone
|
||||
url: https://example.com/music/morning-in-the-glasshouse
|
||||
cover: .assets/music/cover/morning-in-the-glasshouse.png
|
||||
keywords: music, acoustic, mornings, gardens
|
||||
---
|
||||
A fictional song that leaves the little sounds in: a chair moving, a breath
|
||||
before the verse, something tapping gently against the glass.
|
||||
|
||||
The guitar is close and dry, but the backing voices seem to come from the far
|
||||
end of the room. It is a lovely contrast to the late-night bass of
|
||||
*After the Last Tram*.
|
||||
|
||||
Play this one while making breakfast, then start it again when the room is quiet.
|
||||
@@ -0,0 +1,50 @@
|
||||
---
|
||||
title: Lemon and White Bean Soup
|
||||
summary: Creamy white beans, rosemary and a whole lemon make a bright soup from a short cupboard list.
|
||||
source: Demo Kitchen
|
||||
url: https://example.com/recipes/lemon-and-white-bean-soup
|
||||
photo: .assets/recipes/photo/lemon-and-white-bean-soup.png
|
||||
ingredients:
|
||||
- item: olive oil
|
||||
quantity: 2
|
||||
unit: tbsp
|
||||
note: for softening the onion
|
||||
- item: onion
|
||||
quantity: 1
|
||||
unit: piece
|
||||
note: finely diced
|
||||
- item: white beans
|
||||
quantity: 800
|
||||
unit: g
|
||||
note: cooked and drained
|
||||
- item: vegetable stock
|
||||
quantity: 1000
|
||||
unit: ml
|
||||
note: keep a little extra for reheating
|
||||
- item: lemon
|
||||
quantity: 1
|
||||
unit: piece
|
||||
note: zest and juice
|
||||
- item: rosemary
|
||||
quantity: 2
|
||||
unit: sprigs
|
||||
note: leaves finely chopped
|
||||
instructions:
|
||||
- text: Warm the oil in a large saucepan. Add the onion and a pinch of salt, then cook gently until soft.
|
||||
- text: Stir in the rosemary and lemon zest for a minute before adding the beans and stock.
|
||||
- text: Simmer for 30 minutes. Crush a few spoonfuls of beans against the side of the pan to thicken the soup.
|
||||
- text: Add the lemon juice gradually, tasting as you go. Serve with toast and a little olive oil.
|
||||
prep_minutes: 15
|
||||
cook_minutes: 30
|
||||
total_minutes: 45
|
||||
date_cooked: 2026-10-27
|
||||
date_updated: 2026-10-27
|
||||
keywords: cooking, soup, beans, lemon, weeknight
|
||||
---
|
||||
Makes four modest bowls. The beans do the thickening, so there is no need for
|
||||
cream or a blender.
|
||||
|
||||
Start with half the lemon juice and taste before adding the rest. On the second
|
||||
day the soup needs a splash of water and another squeeze of lemon to wake it up.
|
||||
|
||||
A handful of chopped greens would fit nicely near the end of cooking.
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
title: Roasted Tomato Pasta
|
||||
summary: A tray of blistered tomatoes becomes a bright, garlicky sauce while the pasta cooks.
|
||||
source: Demo Kitchen
|
||||
url: https://example.com/recipes/roasted-tomato-pasta
|
||||
photo: .assets/recipes/photo/roasted-tomato-pasta.png
|
||||
ingredients:
|
||||
- item: cherry tomatoes
|
||||
quantity: 600
|
||||
unit: g
|
||||
note: halved
|
||||
- item: olive oil
|
||||
quantity: 3
|
||||
unit: tbsp
|
||||
note: plus a little for serving
|
||||
- item: garlic
|
||||
quantity: 4
|
||||
unit: cloves
|
||||
note: peeled and lightly crushed
|
||||
- item: pasta
|
||||
quantity: 300
|
||||
unit: g
|
||||
note: short shapes hold the sauce well
|
||||
- item: basil
|
||||
quantity: 8
|
||||
unit: leaves
|
||||
note: torn just before serving
|
||||
instructions:
|
||||
- text: Heat the oven to 220°C. Toss the tomatoes, oil and garlic in a roasting dish and season with salt.
|
||||
- text: Roast for 25 minutes, until the tomatoes soften and their edges begin to darken.
|
||||
- text: Meanwhile, cook the pasta in salted water. Reserve a mug of cooking water before draining.
|
||||
- text: Mash the tomatoes and garlic with a fork. Toss with the pasta, loosening the sauce with a splash of cooking water.
|
||||
- text: Fold in the basil and serve with another drizzle of olive oil.
|
||||
prep_minutes: 10
|
||||
cook_minutes: 25
|
||||
total_minutes: 35
|
||||
date_cooked: 2026-10-21
|
||||
date_updated: 2026-10-22
|
||||
keywords: cooking, pasta, tomatoes, weeknight
|
||||
---
|
||||
Enough for two hungry people, or three with a salad.
|
||||
|
||||
The first time I made this, I drained the pasta too thoroughly. Keeping some
|
||||
starchy water nearby makes the sauce cling instead of collecting underneath.
|
||||
|
||||
Next time: add a spoonful of capers to the roasting dish and save a portion for
|
||||
lunch.
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
title: A Readable Slug
|
||||
summary: Turn a short title into a lowercase ASCII slug, keeping word boundaries and dropping punctuation.
|
||||
date_added: 2026-11-02
|
||||
date_updated: 2026-11-03
|
||||
keywords: python, text, utilities, web
|
||||
files:
|
||||
- file: .assets/snippets/a-readable-slug.snippets/slugify.py
|
||||
name: slugify.py
|
||||
type: snippet
|
||||
format: python
|
||||
---
|
||||
A small Python helper for filenames and draft URLs. For example,
|
||||
`slugify("Café by the River!")` produces `cafe-by-the-river`.
|
||||
|
||||
This is deliberately a narrow tool: it transliterates to ASCII and does not
|
||||
make duplicate titles unique. Keep the original title beside the slug if it
|
||||
needs to be displayed later.
|
||||
@@ -0,0 +1,21 @@
|
||||
---
|
||||
title: Cloud Harbor
|
||||
summary: Build a floating harbor together, then decide which ships can dock before the weather turns.
|
||||
publisher: Folding Map Studio
|
||||
player_count: 2
|
||||
play_time_minutes: 25
|
||||
date_published: 2025-01-17
|
||||
date_played: 2026-10-30
|
||||
url: https://example.com/games/cloud-harbor
|
||||
cover: .assets/tabletop-games/cover/cloud-harbor.png
|
||||
keywords: games, cards, cooperation, clouds
|
||||
---
|
||||
A fictional two-player game that fits on a small table. Each card is either a
|
||||
piece of harbor or a promise to a ship that has not arrived yet.
|
||||
|
||||
We lost the first game by making the harbor beautiful and forgetting that ships
|
||||
need somewhere to turn. The second attempt was much less symmetrical and much
|
||||
more useful.
|
||||
|
||||
Twenty-five minutes is about right, including the discussion afterward about
|
||||
which decision started the trouble. Leave time for a second game.
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
title: The Lantern Market
|
||||
summary: Trade small treasures, light the market stalls and guess which visitor will arrive before dawn.
|
||||
publisher: Paper Lantern Games
|
||||
player_count: 4
|
||||
play_time_minutes: 45
|
||||
date_published: 2024-02-10
|
||||
date_played: 2026-10-24
|
||||
url: https://example.com/games/the-lantern-market
|
||||
cover: .assets/tabletop-games/cover/the-lantern-market.png
|
||||
keywords: games, cards, trading, friends
|
||||
---
|
||||
A fictional card game for an evening around the kitchen table. Every round,
|
||||
one player knows which visitor is coming, but needs help gathering the right
|
||||
collection of goods.
|
||||
|
||||
Our four-player game took about 45 minutes, including a practice round. Once
|
||||
we stopped trying to win every trade, the little alliances became much more
|
||||
interesting.
|
||||
|
||||
> The best deal was the one that gave someone else a reason to help later.
|
||||
|
||||
Next time, leave the scoring cards face up for the first two rounds so new
|
||||
players can see what they are working toward.
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
title: Mosslight Valley
|
||||
summary: Bring an abandoned hillside garden back to life by learning where its water, seeds and wandering paths want to go.
|
||||
publisher: Fern and Fern
|
||||
platform: Desktop
|
||||
play_time_minutes: 915
|
||||
date_published: 2025-03-21
|
||||
date_played: 2026-10-29
|
||||
url: https://example.com/games/mosslight-valley
|
||||
cover: .assets/video-games/cover/mosslight-valley.png
|
||||
keywords: games, gardens, exploration, puzzles
|
||||
---
|
||||
A fictional gardening adventure with a very forgiving idea of progress. A wrong
|
||||
turn usually reveals a new plant rather than costing an afternoon.
|
||||
|
||||
The best puzzles involve understanding the slope of the land. Once the first
|
||||
stream reaches the lower beds, several earlier scenes make more sense.
|
||||
|
||||
## Still to do
|
||||
|
||||
- [x] Reopen the old glasshouse.
|
||||
- [x] Find a route for the spring water.
|
||||
- [ ] Work out why the blue flowers only open after sunset.
|
||||
|
||||
Fifteen hours in, I am mostly rearranging paths and visiting places that no
|
||||
longer need any help. That feels like a good ending.
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
title: Starfall Station
|
||||
summary: Repair a quiet orbital station by following its old maintenance routes and the stories left behind.
|
||||
publisher: Local Orbit
|
||||
platform: Pocket Console
|
||||
play_time_minutes: 245
|
||||
date_published: 2023-09-08
|
||||
date_played: 2026-10-23
|
||||
url: https://example.com/games/starfall-station
|
||||
cover: .assets/video-games/cover/starfall-station.png
|
||||
keywords: games, exploration, space, puzzles
|
||||
---
|
||||
A fictional exploration game with no timer and very few instructions. Each
|
||||
repaired room makes the station a little warmer and opens a new way through.
|
||||
|
||||
## What worked
|
||||
|
||||
- The map remembers the paths I actually walked.
|
||||
- Small environmental details explain what happened without stopping play.
|
||||
- Returning to the first room after restoring power changes its meaning.
|
||||
|
||||
I spent just over four hours here. The optional observatory puzzle was worth
|
||||
coming back for after the credits.
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
title: Notes from a Rainy Window
|
||||
subtitle: An unhurried afternoon
|
||||
summary: A few observations from the kitchen table while the weather decided what to do next.
|
||||
date_published: 2026-11-01
|
||||
keywords: writing, rain, slow days, keeping things
|
||||
---
|
||||
## Before the rain
|
||||
|
||||
The street was unusually quiet. Someone had left a blue umbrella open on a
|
||||
balcony, as if it were waiting for instructions.
|
||||
|
||||
## During
|
||||
|
||||
- Water found the same crack in the windowsill it found last winter.
|
||||
- The tree across the road became several different greens.
|
||||
- A delivery rider stopped beneath the awning and ate an orange.
|
||||
|
||||
> Staying in one place is sometimes enough to notice a journey.
|
||||
|
||||
## After
|
||||
|
||||
I meant to make a list of things to finish. Instead, I wrote down three things
|
||||
I would otherwise have forgotten. The unfinished work was still there when the
|
||||
sun came back, but the afternoon no longer felt empty.
|
||||
@@ -174,6 +174,175 @@ pieces:
|
||||
- representative_image
|
||||
attachments:
|
||||
- attachments
|
||||
- type: articles
|
||||
templates:
|
||||
icon:
|
||||
name: browser-window
|
||||
mapping:
|
||||
image: banner
|
||||
url: url
|
||||
page:
|
||||
name: article
|
||||
mapping:
|
||||
image: banner
|
||||
url: url
|
||||
author: author
|
||||
wordCount: word_count
|
||||
datePublished: date_published
|
||||
opengraph:
|
||||
name: browser-window
|
||||
mapping:
|
||||
image: banner
|
||||
url: url
|
||||
author: author
|
||||
wordCount: word_count
|
||||
fields:
|
||||
title: title
|
||||
summary: summary
|
||||
date_consumed: date_read
|
||||
tags: keywords
|
||||
media:
|
||||
- banner
|
||||
- type: recipes
|
||||
templates:
|
||||
icon:
|
||||
name: recipe-card
|
||||
mapping:
|
||||
image: photo
|
||||
ingredients:
|
||||
each: ingredients
|
||||
fields:
|
||||
item: item
|
||||
page:
|
||||
name: recipe
|
||||
mapping:
|
||||
image: photo
|
||||
url: url
|
||||
ingredients:
|
||||
each: ingredients
|
||||
fields:
|
||||
item: item
|
||||
quantity: quantity
|
||||
unit: unit
|
||||
note: note
|
||||
instructions:
|
||||
each: instructions
|
||||
fields:
|
||||
text: text
|
||||
prepMinutes: prep_minutes
|
||||
cookMinutes: cook_minutes
|
||||
totalMinutes: total_minutes
|
||||
dateUpdated: date_updated
|
||||
opengraph:
|
||||
name: recipe-card
|
||||
mapping:
|
||||
image: photo
|
||||
source: source
|
||||
ingredients:
|
||||
each: ingredients
|
||||
fields:
|
||||
item: item
|
||||
prepMinutes: prep_minutes
|
||||
cookMinutes: cook_minutes
|
||||
totalMinutes: total_minutes
|
||||
fields:
|
||||
title: title
|
||||
summary: summary
|
||||
date_consumed: date_cooked
|
||||
tags: keywords
|
||||
media:
|
||||
- photo
|
||||
- type: music
|
||||
templates:
|
||||
icon:
|
||||
name: vinyl-record
|
||||
mapping:
|
||||
image: cover
|
||||
page:
|
||||
name: music
|
||||
mapping:
|
||||
image: cover
|
||||
artist: artist
|
||||
durationSeconds: duration_seconds
|
||||
album: album
|
||||
dateReleased: date_released
|
||||
language: language
|
||||
collaborators: collaborators
|
||||
url: url
|
||||
opengraph:
|
||||
name: vinyl-record
|
||||
mapping:
|
||||
image: cover
|
||||
artist: artist
|
||||
durationSeconds: duration_seconds
|
||||
fields:
|
||||
title: title
|
||||
summary: summary
|
||||
date_consumed: date_listened
|
||||
tags: keywords
|
||||
media:
|
||||
- cover
|
||||
- type: video-games
|
||||
templates:
|
||||
icon:
|
||||
name: video-game-cartridge
|
||||
mapping:
|
||||
image: cover
|
||||
page:
|
||||
name: video-game
|
||||
mapping:
|
||||
image: cover
|
||||
url: url
|
||||
publisher: publisher
|
||||
datePublished: date_published
|
||||
playTimeMinutes: play_time_minutes
|
||||
platform: platform
|
||||
opengraph:
|
||||
name: video-game-cartridge
|
||||
mapping:
|
||||
image: cover
|
||||
publisher: publisher
|
||||
platform: platform
|
||||
playTimeMinutes: play_time_minutes
|
||||
fields:
|
||||
title: title
|
||||
summary: summary
|
||||
date_consumed: date_played
|
||||
tags: keywords
|
||||
media:
|
||||
- cover
|
||||
- type: tabletop-games
|
||||
templates:
|
||||
icon:
|
||||
name: playing-cards
|
||||
page:
|
||||
name: tabletop-game
|
||||
mapping:
|
||||
image: cover
|
||||
url: url
|
||||
publisher: publisher
|
||||
datePublished: date_published
|
||||
playTimeMinutes: play_time_minutes
|
||||
playerCount: player_count
|
||||
opengraph:
|
||||
name: playing-cards
|
||||
mapping:
|
||||
backdrop: cover
|
||||
publisher: publisher
|
||||
playTimeMinutes: play_time_minutes
|
||||
fields:
|
||||
title: title
|
||||
summary: summary
|
||||
date_consumed: date_played
|
||||
tags: keywords
|
||||
media:
|
||||
- cover
|
||||
- type: generic
|
||||
fields:
|
||||
title: title
|
||||
summary: summary
|
||||
date_consumed: date_added
|
||||
tags: keywords
|
||||
|
||||
theme:
|
||||
globals:
|
||||
@@ -282,10 +451,10 @@ theme:
|
||||
color-on-surface-variant: '#57534e'
|
||||
color-on-surface-inverse: '#fafaf9'
|
||||
color-surface-container-lowest: '#ffffff'
|
||||
color-surface-container-low: '#f5f5f4'
|
||||
color-surface-container: '#e7e5e4'
|
||||
color-surface-container-high: '#d6d3d1'
|
||||
color-surface-container-highest: '#a8a29e'
|
||||
color-surface-container-low: '#fafaf9'
|
||||
color-surface-container: '#f8f7f6'
|
||||
color-surface-container-high: '#f5f4f2'
|
||||
color-surface-container-highest: '#f2f0ee'
|
||||
color-shadow: hsla(0, 0%, 0%, 0.2)
|
||||
color-outline: '#78716c'
|
||||
color-outline-variant: '#d6d3d1'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@luzzle/web",
|
||||
"version": "0.0.247",
|
||||
"version": "0.0.248",
|
||||
"private": true,
|
||||
"files": [
|
||||
"build",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { resolve } from '$app/paths'
|
||||
import ArrowLeftIcon from 'virtual:icons/ph/arrow-left'
|
||||
import NavigationIcon from 'virtual:icons/ph/arrow-up-left'
|
||||
import SeoHead from '#lib/components/layout/simple/SeoHead.svelte'
|
||||
import ThemeToggle from '#lib/components/layout/simple/ThemeToggle.svelte'
|
||||
|
||||
@@ -11,9 +11,8 @@
|
||||
|
||||
<div class="signin-shell">
|
||||
<header class="signin-tools">
|
||||
<a href={resolve('')}>
|
||||
<ArrowLeftIcon aria-hidden="true" focusable="false" />
|
||||
Back to site
|
||||
<a href={resolve('')} aria-label="main page">
|
||||
<NavigationIcon aria-hidden="true" focusable="false" />
|
||||
</a>
|
||||
<ThemeToggle />
|
||||
</header>
|
||||
@@ -40,15 +39,17 @@
|
||||
.signin-tools a {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
justify-content: center;
|
||||
min-width: 44px;
|
||||
min-height: 44px;
|
||||
border-radius: var(--radius-small);
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.signin-tools a:hover {
|
||||
text-decoration: underline;
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.signin-tools :global(button) {
|
||||
|
||||
@@ -88,8 +88,7 @@ test('the sign-in layout keeps branding, theme and return navigation without pub
|
||||
const result = render(SigninTree, { props: { data } })
|
||||
|
||||
expect(result.body.match(/<main\b/g)).toHaveLength(1)
|
||||
expect(result.body).toContain('href="/"')
|
||||
expect(result.body).toContain('Back to site')
|
||||
expect(result.body).toMatch(/<a\b(?=[^>]*\bhref="\/")(?=[^>]*\baria-label="main page")[^>]*>/)
|
||||
expect(result.body).toContain('aria-label="change theme"')
|
||||
expect(result.body).not.toContain('aria-label="search"')
|
||||
expect(result.head).toContain('rel="icon" href="/assets/favicon/garden.svg"')
|
||||
|
||||
@@ -590,10 +590,10 @@ const LightPaletteSchema = Type.Object(
|
||||
"color-on-surface-variant": Type.String({ default: "#495057" }),
|
||||
"color-on-surface-inverse": Type.String({ default: "#f8f9fa" }),
|
||||
"color-surface-container-lowest": Type.String({ default: "#ffffff" }),
|
||||
"color-surface-container-low": Type.String({ default: "#e9ecef" }),
|
||||
"color-surface-container": Type.String({ default: "#dee2e6" }),
|
||||
"color-surface-container-high": Type.String({ default: "#ced4da" }),
|
||||
"color-surface-container-highest": Type.String({ default: "#adb5bd" }),
|
||||
"color-surface-container-low": Type.String({ default: "#f8f9fa" }),
|
||||
"color-surface-container": Type.String({ default: "#f4f6f8" }),
|
||||
"color-surface-container-high": Type.String({ default: "#f0f2f5" }),
|
||||
"color-surface-container-highest": Type.String({ default: "#eceff3" }),
|
||||
"color-shadow": Type.String({ default: "hsla(0, 0%, 0%, 0.15)" }),
|
||||
"color-outline": Type.String({ default: "#6c757d" }),
|
||||
"color-outline-variant": Type.String({ default: "#ced4da" }),
|
||||
|
||||
@@ -713,19 +713,19 @@
|
||||
"type": "string"
|
||||
},
|
||||
"color-surface-container-low": {
|
||||
"default": "#e9ecef",
|
||||
"default": "#f8f9fa",
|
||||
"type": "string"
|
||||
},
|
||||
"color-surface-container": {
|
||||
"default": "#dee2e6",
|
||||
"default": "#f4f6f8",
|
||||
"type": "string"
|
||||
},
|
||||
"color-surface-container-high": {
|
||||
"default": "#ced4da",
|
||||
"default": "#f0f2f5",
|
||||
"type": "string"
|
||||
},
|
||||
"color-surface-container-highest": {
|
||||
"default": "#adb5bd",
|
||||
"default": "#eceff3",
|
||||
"type": "string"
|
||||
},
|
||||
"color-shadow": {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# @luzzle/web.lsp
|
||||
|
||||
## 0.0.248
|
||||
|
||||
## 0.0.247
|
||||
|
||||
## 0.0.246
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@luzzle/web.lsp",
|
||||
"version": "0.0.247",
|
||||
"version": "0.0.248",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"description": "Luzzle Web LSP WebSocket Bridge",
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# @luzzle/web.proxy
|
||||
|
||||
## 0.0.248
|
||||
|
||||
## 0.0.247
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@luzzle/web.proxy",
|
||||
"version": "0.0.247",
|
||||
"version": "0.0.248",
|
||||
"private": true,
|
||||
"description": "Nginx caching layer for Luzzle Web Explorer",
|
||||
"scripts": {
|
||||
|
||||
@@ -9494,19 +9494,19 @@
|
||||
"type": "string"
|
||||
},
|
||||
"color-surface-container-low": {
|
||||
"default": "#e9ecef",
|
||||
"default": "#f8f9fa",
|
||||
"type": "string"
|
||||
},
|
||||
"color-surface-container": {
|
||||
"default": "#dee2e6",
|
||||
"default": "#f4f6f8",
|
||||
"type": "string"
|
||||
},
|
||||
"color-surface-container-high": {
|
||||
"default": "#ced4da",
|
||||
"default": "#f0f2f5",
|
||||
"type": "string"
|
||||
},
|
||||
"color-surface-container-highest": {
|
||||
"default": "#adb5bd",
|
||||
"default": "#eceff3",
|
||||
"type": "string"
|
||||
},
|
||||
"color-shadow": {
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
# @luzzle/web.worker
|
||||
|
||||
## 0.0.248
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2c66a44: Use softer, near-white surface containers in the default light palette and the bundled demo. Preserve dark palettes, accent colors and existing focus behavior.
|
||||
- @luzzle/core@0.0.248
|
||||
- @luzzle/web.db@0.0.1
|
||||
- @luzzle/web.jobs@0.0.1
|
||||
- @luzzle/web.pieces@0.0.1
|
||||
- @luzzle/web.templates@0.0.1
|
||||
|
||||
## 0.0.247
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@luzzle/web.worker",
|
||||
"version": "0.0.247",
|
||||
"version": "0.0.248",
|
||||
"author": "eleith",
|
||||
"private": true,
|
||||
"description": "luzzle publish worker — runs heavy jobs (transforms, rclone) handed off by the explorer",
|
||||
|
||||