Merge branch 'main' into feat/external-link-indicator

This commit is contained in:
Óscar 2025-02-15 09:30:25 +01:00 committed by GitHub
commit c82e471dde
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
77 changed files with 953 additions and 141 deletions

View file

@ -12,4 +12,4 @@ show_projects_first = false
social_media_card = "ca.jpg"
+++
tabi és un tema accessible per a Zola amb [cerca](https://welpo.github.io/tabi/ca/blog/mastering-tabi-settings/#cerca), [suport multilingüe](https://welpo.github.io/tabi/ca/blog/faq-languages/), [JavaScript opcional](https://welpo.github.io/tabi/ca/blog/javascript/), una puntuació perfecta a Lighthouse i [documentació exhaustiva](https://welpo.github.io/tabi/ca). Dissenyat per a llocs web i blogs personals.
tabi és un tema accessible per a Zola amb [cerca](@/blog/mastering-tabi-settings/index.ca.md#cerca), [suport multilingüe](@/blog/faq-languages/index.ca.md), [JavaScript opcional](@/blog/javascript/index.ca.md), una puntuació perfecta a Lighthouse i documentació exhaustiva. Dissenyat per a llocs web i blogs personals.

View file

@ -12,4 +12,4 @@ show_projects_first = false
social_media_card = "es.jpg"
+++
tabi es un tema accesible para [Zola](https://www.getzola.org) con [búsqueda](https://welpo.github.io/tabi/es/blog/mastering-tabi-settings/#busqueda), [soporte multilingüe](https://welpo.github.io/tabi/es/blog/faq-languages/), [JavaScript opcional](https://welpo.github.io/tabi/es/blog/javascript/), una puntuación perfecta en Lighthouse y [documentación exhaustiva](https://welpo.github.io/tabi/es). Diseñado para sitios web y blogs personales.
tabi es un tema accesible para [Zola](https://www.getzola.org) con [búsqueda](@/blog/mastering-tabi-settings/index.es.md#busqueda), [soporte multilingüe](@/blog/faq-languages/index.es.md), [JavaScript opcional](@/blog/javascript/index.es.md), una puntuación perfecta en Lighthouse y documentación exhaustiva. Diseñado para sitios web y blogs personales.

View file

@ -12,4 +12,4 @@ show_projects_first = false
social_media_card = "index.jpg"
+++
tabi is an accessible [Zola](https://www.getzola.org) theme with [search](https://welpo.github.io/tabi/blog/mastering-tabi-settings/#search), [multi-language support](https://welpo.github.io/tabi/blog/faq-languages/), [optional JavaScript](https://welpo.github.io/tabi/blog/javascript/), a perfect Lighthouse score, and [comprehensive documentation](https://welpo.github.io/tabi). Crafted for personal websites and blogs.
tabi is an accessible [Zola](https://www.getzola.org) theme with [search](@/blog/mastering-tabi-settings/index.md#search), [multi-language support](@/blog/faq-languages/index.md), [optional JavaScript](@/blog/javascript/index.md), a perfect Lighthouse score, and comprehensive documentation. Crafted for personal websites and blogs.

View file

@ -1,7 +1,7 @@
+++
title = "Optimitza la càrrega amb un subconjunt de font personalitzat"
date = 2023-04-29
updated = 2023-07-08
updated = 2025-01-12
description = "Aprèn com crear un subconjunt personalitzat que només inclogui els glifs necessaris."
[taxonomies]
@ -21,7 +21,11 @@ Per solucionar això, tabi carrega un subconjunt de glifs per a l'encapçalament
Per defecte, tabi inclou fitxers de subconjunts per a caràcters en anglès i espanyol (amb alguns símbols). Aquests fitxers es carreguen quan la pàgina o el lloc web de Zola està en aquest idioma.
Per a una optimització addicional, pots crear un subconjunt de fonts personalitzat que només inclogui els caràcters utilitzats en el teu encapçalament.
{% admonition(type="tip") %}
Si estàs fent servir una font personalitzada, pots crear el teu propi subconjunt (segueix llegint) o desactivar completament els subconjunts predeterminats amb `enable_subset = false` a `config.toml`.
{% end %}
Per a una optimització addicional, a continuació t'expliquem com crear un subconjunt de fonts personalitzat que només inclogui els caràcters utilitzats en el teu encapçalament.
## Requisits

View file

@ -1,7 +1,7 @@
+++
title = "Optimiza la carga con un subconjunto de fuente personalizado"
date = 2023-04-29
updated = 2023-07-08
updated = 2025-01-12
description = "Aprende cómo crear un subconjunto personalizado que solo incluya los glifos necesarios."
[taxonomies]
@ -21,7 +21,11 @@ Para solucionar esto, tabi carga un subconjunto de glifos para el encabezado. Da
Por defecto, tabi incluye archivos de subconjuntos para caracteres en inglés y español (con algunos símbolos). Estos archivos se cargan cuando la página o el sitio de Zola está en ese idioma.
Para una optimización adicional, puedes crear un subconjunto de fuentes personalizado que solo incluya los caracteres utilizados en tu encabezado.
{% admonition(type="tip") %}
Si estás usando una fuente personalizada, puedes crear tu propio subconjunto (ver más abajo) o desactivar completamente los subconjuntos predeterminados con `enable_subset = false` en tu `config.toml`.
{% end %}
Para una optimización adicional, a continuación verás cómo crear un subconjunto de fuentes personalizado que solo incluya los caracteres utilizados en tu encabezado.
## Requisitos

View file

@ -1,7 +1,7 @@
+++
title = "Optimise loading times with a custom font subset"
date = 2023-04-29
updated = 2023-07-08
updated = 2025-01-12
description = "Learn how to create a custom subset that only includes the necessary glyphs."
[taxonomies]
@ -21,7 +21,11 @@ To fix this, tabi loads a subset of glyphs for the header. Since this (slightly)
By default, there are subset files for English and Spanish characters (with a few symbols). These files are loaded when the Zola page/site is set to that language.
For further optimisation, you can create a custom font subset that only includes the characters used in your header.
{% admonition(type="tip") %}
If you're using a custom font, either create your custom subset (see below) or disable the built-in subsets completely with `enable_subset = false` in your `config.toml`.
{% end %}
Here's how you can create a custom font subset that only includes the characters used in your header, for maximum efficiency.
## Requirements

View file

@ -1,7 +1,7 @@
+++
title = "Sense JavaScript obligatori"
date = 2023-01-06
updated = 2024-11-16
updated = 2024-12-15
description = "JavaScript només s'utilitza quan HTML i CSS no són suficients."
[taxonomies]
@ -25,7 +25,7 @@ Aquest tema no requereix JavaScript obligatori. Opcionalment, pot carregar una q
Les següents opcions es poden especificar per a publicacions, seccions i globalment, seguint la jerarquia de `pàgina > secció > config.toml`:
- [**Suport de KaTeX**](@/blog/markdown/index.ca.md#katex). Habilitat configurant `katex = true` (274 KB).
- [**Suport de KaTeX**](@/blog/markdown/index.ca.md#katex). Habilitat configurant `katex = true` (274 KB). Per renderitzar fórmules sense JS, prova [MathML](https://developer.mozilla.org/docs/Web/MathML/).
- [**Diagrames de Mermaid**](@/blog/shortcodes/index.ca.md#diagrames-de-mermaid). Habilitat configurant `mermaid = true` (~2.5 MB).
- [**Còpia de blocs de codi amb un sol clic**](@/blog/markdown/index.ca.md#bloc-de-codi). Habilitada configurant `copy_button = true`. (~700 bytes)
- [**Mostrar ruta/URL a blocs de codi**](@/blog/shortcodes/index.ca.md#mostrar-ruta-o-url). S'activa configurant `add_src_to_code_block = true`. (~400 bytes)

View file

@ -1,7 +1,7 @@
+++
title = "Sin JavaScript obligatorio"
date = 2023-01-06
updated = 2024-11-16
updated = 2024-12-15
description = "JavaScript solo se utiliza cuando HTML y CSS no son suficientes."
[taxonomies]
@ -25,7 +25,7 @@ Este tema no requiere JavaScript de manera obligatoria. Opcionalmente, puede car
Las siguientes opciones pueden especificarse para publicaciones, secciones y a nivel global, siguiendo la jerarquía de `página > sección > config.toml`:
- [**Soporte de KaTeX**](@/blog/markdown/index.es.md#katex). Habilitado al configurar `katex = true` (274 KB).
- [**Soporte de KaTeX**](@/blog/markdown/index.es.md#katex). Habilitado al configurar `katex = true` (274 KB). Para renderizar fórmulas sin JS, prueba [MathML](https://developer.mozilla.org/docs/Web/MathML/).
- [**Diagramas de Mermaid**](@/blog/shortcodes/index.es.md#diagramas-de-mermaid). Habilitado al configurar `mermaid = true` (~2.5 MB).
- [**Copia de bloques de código con un solo clic**](@/blog/markdown/index.es.md#bloque-de-codigo). Habilitado al configurar `copy_button = true` (~700 bytes).
- [**Mostrar ruta/URL en bloques de código**](@/blog/shortcodes/index.es.md#mostrar-ruta-o-url). Se activa configurando `add_src_to_code_block = true`. (~400 bytes)

View file

@ -1,7 +1,7 @@
+++
title = "No mandatory JavaScript"
date = 2023-01-06
updated = 2024-11-16
updated = 2024-12-15
description = "JavaScript is only used when HTML and CSS aren't enough."
[taxonomies]
@ -25,7 +25,7 @@ This theme has no mandatory JavaScript. Optionally, it can load a minimal amount
The following settings can be specified for posts, sections and globally, following the hierarchy of `page > section > config.toml`:
- [**KaTeX support**](@/blog/markdown/index.md#katex). Enabled by setting `katex = true` (274 KB).
- [**KaTeX support**](@/blog/markdown/index.md#katex). Enabled by setting `katex = true` (274 KB). To render math without JS, check out [MathML](https://developer.mozilla.org/docs/Web/MathML/).
- [**Mermaid diagrams**](@/blog/shortcodes/index.md#mermaid-diagrams). Enabled by setting `mermaid = true` (~2.5 MB).
- [**One-click copy of code blocks**](@/blog/markdown/index.md#code-block). Enabled by setting `copy_button = true`. (~700 bytes)
- [**Showing source (path or URL) in code blocks**](@/blog/shortcodes/index.md#show-source-or-path). Enabled by setting `add_src_to_code_block = true`. (~300 bytes)

View file

@ -172,13 +172,16 @@ pinned = true
{{ admonition(type="warning", text='Quan s'utilitza la paginació (`paginate_by`), les entrades fixades poden aparèixer dues vegades: una vegada a la part superior de la primera pàgina, i una altra en la seva posició cronològica normal en pàgines posteriors.') }}
##### Mostrar la data dels articles al llistat
Per defecte, quan es llisten els articles, es mostra la data de creació. Pots configurar quina(es) data(es) mostrar utilitzant l'opció `post_listing_date`. Configuracions disponibles:
- `date`: Mostra només la data de publicació original de l'article (opció per defecte).
- `updated`: Mostra només la data de l'última actualització de l'article. Si no hi ha data d'actualització, es mostra la data de publicació original.
- `both`: Mostra tant la data de publicació original com la data de l'última actualització.
{% admonition(type="tip") %}
Aquesta configuració segueix la jerarquia: pots establir un valor global a `config.toml` o canviar-lo per a seccions específiques al seu arxiu `_index.md`. En ambdós casos, afegeix-lo a la secció `[extra]`.
{% end %}
#### Llistat de Projectes
Pots mostrar una selecció de projectes a la teva pàgina principal. Per fer això, primer necessitaràs configurar el directori `projects`.
@ -304,11 +307,11 @@ Si configures `tag_sorting = "frequency"`, s'ordenaran segons el nombre de publi
---
### Sèries
## Sèries
Per a una explicació detallada, consulta la [documentació de sèries](@/blog/series/index.ca.md).
#### Enllaç per saltar a les publicacions
### Enllaç per saltar a les publicacions
| Pàgina | Secció | `config.toml` | Segueix la jerarquia | Requereix JavaScript |
|:------:|:-------:|:-------------:|:------------------:|:-------------------:|
@ -320,7 +323,7 @@ Per defecte, apareix automàticament un enllaç "Salta a les publicacions" al co
Estableix `show_jump_to_posts = true` per forçar l'activació de la funció i `show_jump_to_posts = false` per desactivar-la.
#### Indexació de pàgines de sèries
### Indexació de pàgines de sèries
| Pàgina | Secció | `config.toml` | Segueix la jerarquia | Requereix JavaScript |
|:------:|:-------:|:-------------:|:------------------:|:-------------------:|
@ -457,10 +460,14 @@ Per defecte, l'arxiu llistarà les publicacions situades a `blog/`. Per personal
section_path = ["blog/", "notes/", "camí-tres/"]
```
**Nota**:
L'arxiu mostra les publicacions en ordre cronològic invers (les més recents primer). Pots invertir aquest ordre establint `archive_reverse = true` a la secció `[extra]`:
- La pàgina d'arxiu només llistarà publicacions amb data.
- L'ordre de les publicacions ve determinada per la variable `sort_by` de les seccions arxivades. Aquesta demo utilitza `sort_by = "date"` en `blog/_index.md`.
```toml
[extra]
archive_reverse = true # mostra les publicacions més antigues primer
```
{{ admonition(type="note", title="nota" text="La pàgina d'arxiu només llistarà publicacions que tinguin data al seu encapçalament.") }}
### Etiquetes
@ -509,6 +516,17 @@ path = "about"
Fixa't com s'estableix `path = "about"`. Zola situarà la pàgina a `$base_url/about/`. Si vols que la pàgina estigui disponible a `/contacte/`, hauries d'establir `path = "contacte"`.
La plantilla `info-page.html` també es pot utilitzar per crear landing pages a la ruta arrel (`"/"`). Per fer-ho, l'arxiu `content/_index.md` hauria de ser així:
```markdown
+++
title = "Títol de la pàgina"
template = "info-page.html"
+++
Contingut amb Markdown.
```
---
## SEO
@ -595,7 +613,9 @@ fediverse_creator = { handle = "username", domain = "example.com" }
|:------:|:------:|:-------------:|:---------------:|:-------------------:|
| ❌ | ❌ | ✅ | ❌ | ❌ |
La barra de navegació és la franja a la part superior de la pàgina que conté el títol del lloc i el menú de navegació. Pots personalitzar els elements que apareixen configurant `menu` en `config.toml`. Per exemple:
La barra de navegació és la franja a la part superior de la pàgina que conté el títol del lloc i el menú de navegació. Pots personalitzar els elements que apareixen configurant `menu` en `config.toml`.
Soporta links relatius per a pàgines internes i links absoluts per a enllaços externs. Per exemple:
```toml
menu = [
@ -604,6 +624,7 @@ menu = [
{ name = "etiquetes", url = "tags", trailing_slash = true },
{ name = "projectes", url = "projects", trailing_slash = true },
{ name = "sobre nosaltres", url = "about", trailing_slash = true },
{ name = "github", url = "https://github.com/welpo/tabi", trailing_slash = false },
]
```
@ -718,10 +739,12 @@ Consulta la [documentació de Mermaid](@/blog/shortcodes/index.ca.md#diagrames-d
|:------:|:------:|:-------------:|:------------------:|:--------------------:|
| ❌ | ❌ | ✅ | ❌ | ❌ |
Les tipus de lletra personalitzades causen parpalleig del text en Firefox. Per resoldre això, tabi carrega un subconjunt de glifs per a la capçalera. Donat que això (lleugerament) augmenta el temps de càrrega inicial, és una bona idea intentar minimitzar la mida d'aquest subconjunt.
Les tipus de lletra personalitzades causen parpalleig del text en Firefox. Per resoldre això, tabi carrega un subconjunt de glifs per a la capçalera. Donat que això (lleugerament) augmenta el temps de càrrega inicial, és una bona idea intentar minimitzar la mida d'aquest subconjunt, o desactivar-lo completament si no estàs fent servir un tipus de lletra personalitzat al teu tema.
Pots crear un subconjunt personalitzat adaptat al teu lloc, guardar-lo com a `static/custom_subset.css`, i fer que es carregui amb `custom_subset = true`.
Per desactivar el subconjunt, utilitza `enable_subset = false`.
Per obtenir més informació, incloent instruccions sobre com crear un subconjunt personalitzat, consulta la [documentació](@/blog/custom-font-subset/index.ca.md).
### Contingut complet al feed

View file

@ -179,6 +179,10 @@ Por defecto, cuando se listan los artículos, se muestra la fecha de creación.
- `updated`: Muestra solo la fecha de la última actualización del artículo. Si no hay fecha de actualización, muestra la fecha de publicación original.
- `both`: Muestra tanto la fecha de publicación original como la fecha de la última actualización.
{% admonition(type="tip") %}
Esta configuración sigue la jerarquía: puedes establecer un valor global en `config.toml` o configurarlo para secciones específicas en su archivo `_index.md`. En ambos casos, añádelo a la sección `[extra]`.
{% end %}
#### Listado de proyectos
Puedes mostrar una selección de proyectos en tu página principal. Para hacer esto, primero necesitarás configurar el directorio `projects`.
@ -304,11 +308,11 @@ Si configuras `tag_sorting = "frequency"`, se ordenarán según el número de pu
---
### Series
## Series
Para una explicación detallada, consulta la [documentación de series](@/blog/series/index.es.md).
#### Enlace para saltar a las publicaciones
### Enlace para saltar a las publicaciones
| Página | Sección | `config.toml` | Sigue jerarquía | Requiere JavaScript |
|:------:|:-------:|:-------------:|:------------------:|:-------------------:|
@ -320,7 +324,7 @@ Por defecto, aparece automáticamente un enlace "Saltar a publicaciones" junto a
Establece `show_jump_to_posts = true` para forzar la activación de la función y `show_jump_to_posts = false` para desactivarla.
#### Indexación de páginas de series
### Indexación de páginas de series
| Página | Sección | `config.toml` | Sigue la jerarquía | Requiere JavaScript |
|:------:|:-------:|:-------------:|:------------------:|:-------------------:|
@ -457,10 +461,14 @@ Por defecto, el archivo mostrará las publicaciones ubicadas en `blog/`. Para pe
section_path = ["blog/", "notas/", "ruta-tres/"]
```
**Nota**:
El archivo muestra las publicaciones en orden cronológico inverso (las más recientes primero). Puedes invertir este orden estableciendo `archive_reverse = true` en la sección `[extra]`:
- La página de Archivo sólo listará publicaciones con fecha.
- El orden las publicaciones viene determinada por la variable `sort_by` de las secciones archivadas. Esta demo utiliza `sort_by = "date"` en `blog/_index.md`.
```toml
[extra]
archive_reverse = true # muestra las publicaciones más antiguas primero
```
{{ admonition(type="note", title="nota" text="La página de Archivo sólo listará publicaciones que tengan fecha en su encabezado.") }}
### Etiquetas
@ -509,6 +517,17 @@ path = "about"
Fíjate cómo se establece `path = "about"`. Zola colocará la página en `$base_url/about/`. Si deseas que la página esté disponible en `/contacto/`, tendrías que establecer `path = "contacto"`.
La plantilla `info-page.html` también se puede utilizar para crear lading pages en la ruta raíz (`"/"`). Para hacerlo, el archivo `content/_index.md` debería verse así:
```markdown
+++
title = "Título de la página"
template = "info-page.html"
+++
Contenido con Markdown.
```
---
## SEO
@ -595,7 +614,9 @@ fediverse_creator = { handle = "username", domain = "example.com" }
|:------:|:-------:|:-------------:|:---------------:|:-------------------:|
| ❌ | ❌ | ✅ | ❌ | ❌ |
La barra de navegación es la barra en la parte superior de la página que contiene el título del sitio y el menú de navegación. Puedes personalizar los elementos que aparecen configurando `menu` en `config.toml`. Por ejemplo:
La barra de navegación es la barra en la parte superior de la página que contiene el título del sitio y el menú de navegación. Puedes personalizar los elementos que aparecen configurando `menu` en `config.toml`.
Soporta links relativos para páginas internas y links absolutos para enlaces externos. Por ejemplo:
```toml
menu = [
@ -604,6 +625,7 @@ menu = [
{ name = "etiquetas", url = "tags", trailing_slash = true },
{ name = "proyectos", url = "projects", trailing_slash = true },
{ name = "acerca de", url = "about", trailing_slash = true },
{ name = "github", url = "https://github.com/welpo/tabi", trailing_slash = false },
]
```
@ -718,10 +740,12 @@ Consulta la [documentación de Mermaid](@/blog/shortcodes/index.es.md#diagramas-
|:------:|:-------:|:-------------:|:---------------:|:-------------------:|
| ❌ | ❌ | ✅ | ❌ | ❌ |
Las fuentes personalizadas causan parpadeo del texto en Firefox. Para solucionar esto, tabi carga un subconjunto de glifos para el encabezado. Dado que esto (ligeramente) aumenta el tiempo de carga inicial, es una buena idea intentar minimizar el tamaño de este subconjunto.
Las fuentes personalizadas causan parpadeo del texto en Firefox. Para solucionar esto, tabi carga un subconjunto de glifos para el encabezado. Dado que esto (ligeramente) aumenta el tiempo de carga inicial, es una buena idea intentar minimizar el tamaño de este subconjunto, o desactivarlo por completo si no estás usando una fuente personalizada en tu tema.
Puedes crear un subconjunto personalizado adaptado a tu sitio, guardarlo como `static/custom_subset.css`, y hacer que se cargue con `custom_subset = true`.
Para desactivar el subconjunto, puedes usar `enable_subset = false`.
Para obtener más información, incluyendo instrucciones sobre cómo crear un subconjunto personalizado, consulta la [documentación](@/blog/custom-font-subset/index.es.md).
### Contenido completo en el feed

View file

@ -183,6 +183,10 @@ By default, when listing posts, the date of post creation is shown. You can conf
post_listing_date = "date"
```
{% admonition(type="tip") %}
This setting follows the hierarchy: you can set a global value in `config.toml` or override it for specific sections in their `_index.md` file. In both cases, add it to the `[extra]` section.
{% end %}
#### Listing Projects
You can showcase a selection of projects on your main page. To do this, you'll need to set up the `projects` directory first.
@ -309,11 +313,11 @@ Setting `tag_sorting = "frequency"` will sort them by number-of-posts (descendin
---
### Series
## Series
For a detailed explanation of the series feature, see the [series documentation](@/blog/series/index.md).
#### Jump to posts link
### Jump to posts link
| Page | Section | `config.toml` | Follows Hierarchy | Requires JavaScript |
|:----:|:-------:|:-------------:|:-----------------:|:-------------------:|
@ -325,7 +329,7 @@ By default, a "Jump to posts" link automatically appears next to the series titl
Set `show_jump_to_posts = true` to force the feature on and `show_jump_to_posts = false` to force it off.
#### Series pages indexation
### Series pages indexation
| Page | Section | `config.toml` | Follows Hierarchy | Requires JavaScript |
|:----:|:-------:|:-------------:|:-----------------:|:-------------------:|
@ -462,10 +466,14 @@ By default, the archive will list posts located in `blog/`. To customise this, y
section_path = ["blog/", "notes/", "path-three/"]
```
**Notes**:
The archive displays posts in reverse chronological order (newest first). You can reverse this order by setting `archive_reverse = true` in the `[extra]` section:
- the Archive page will only list posts that have a date in their front matter.
- Post sorting is determined by the `sort_by` variable of the sections you are archiving. This demo uses `sort_by = "date"` set in the `blog/_index.md`.
```toml
[extra]
archive_reverse = true # displays oldest posts first.
```
{{ admonition(type="note", text="The Archive page will only list posts that have a date in their front matter.") }}
### Tags
@ -514,6 +522,17 @@ path = "about"
Notice how the `path` is set to `about`. Zola will place the page at `$base_url/about/`. If you'd like to have the page available at `/contact/`, you'd set `path = "contact"`.
The `info-page.html` template can also be used to create landing pages at the path root (`"/"`). To do that, the `content/_index.md` file should look like this:
```markdown
+++
title = "Landing Page Title"
template = "info-page.html"
+++
Place your landing page Markdown content here.
```
---
## SEO
@ -602,7 +621,9 @@ This adds metadata to your HTML, allowing Mastodon to display the author's fediv
|:----:|:-------:|:-------------:|:-----------------:|:-------------------:|
| ❌ | ❌ | ✅ | ❌ | ❌ |
The navigation bar is the bar at the top of the page that contains the site title and the navigation menu. You can customise which items appear by setting `menu` in `config.toml`. For example:
The navigation bar is the bar at the top of the page that contains the site title and the navigation menu. You can customise which items appear by setting `menu` in `config.toml`.
The menu supports both relative URLs for internal pages and absolute URLs for external links. For example:
```toml
menu = [
@ -611,6 +632,7 @@ menu = [
{ name = "tags", url = "tags", trailing_slash = true },
{ name = "projects", url = "projects", trailing_slash = true },
{ name = "about", url = "about", trailing_slash = true },
{ name = "github", url = "https://github.com/welpo/tabi", trailing_slash = false },
]
```
@ -728,9 +750,9 @@ See the [Mermaid documentation](@/blog/shortcodes/index.md#mermaid-diagrams) for
|:----:|:-------:|:-------------:|:-----------------:|:-------------------:|
| ❌ | ❌ | ✅ | ❌ | ❌ |
Custom fonts cause flashing text in Firefox. To amend this, tabi loads a subset of glyphs for the header. Since this (slightly) increases the initial load time, it's a good idea to try and minimise the size of this subset.
Custom fonts cause flashing text in Firefox. To amend this, tabi loads a subset of glyphs for the header. Since this (slightly) increases the initial load time, it's a good idea to try and minimise the size of this subset, or disable it completely if you're not using a custom font in your skin.
You can create a custom subset tailored to your site, save it as `static/custom_subset.css`, and have it load with `custom_subset = true`.
You can create a custom subset tailored to your site, save it as `static/custom_subset.css`, and have it load with `custom_subset = true`. Disabling the subset can be done with `enable_subset = false`.
For more information, including instructions on how to create a custom subset, see the [docs](@/blog/custom-font-subset/index.md).

View file

@ -1,7 +1,7 @@
+++
title = "Shortcodes personalitzats"
date = 2023-02-19
updated = 2024-11-27
updated = 2024-12-28
description = "Aquest tema inclou alguns shortcodes personalitzats útils que pots utilitzar per millorar les teves publicacions. Ja sigui per mostrar imatges que s'adapten als temes clar i fosc, o per donar format a una secció de referències amb un aspecte professional, aquests shortcodes personalitzats t'ajudaran."
[taxonomies]
@ -216,6 +216,38 @@ dist/
## Shortcodes de text
### Aside (nota al marge)
Afegeix contingut complementari als marges en pantalles amples, o com a blocs distintius en mòbil.
{{ aside(text="*Nota al marge* ve de *nota* (del llatí, 'marca' o 'senyal') i *marge* (del llatí *margo*, 'vora' o 'límit').") }}
El shortcode accepta dos paràmetres:
- `position`: Establir com a `"right"` per col·locar al marge dret (per defecte, esquerre)
- El contingut es pot proporcionar mitjançant el paràmetre `text` o entre les etiquetes del shortcode
#### Ús
{{ admonition(type="warning", text="Separa la definició de la nota del shortcode amb dues línies en blanc per evitar errors de renderització.") }}
Fent servir el paràmetre `text`:
```
{{/* aside(text="*Nota al marge* ve de *nota* (del llatí, 'marca' o 'senyal') i *marge* (del llatí *margo*, 'vora' o 'límit').") */}}
```
Fent servir el cos del contingut i indicant la posició a la dreta:
```
{%/* aside(position="right") */%}
Una nota més llarga que
pot ocupar diverses línies.
S'admet *Markdown*.
{%/* end */%}
```
### Text remot
Afegeix text des d'una URL remota o un arxiu local.

View file

@ -1,7 +1,7 @@
+++
title = "Shortcodes personalizados"
date = 2023-02-19
updated = 2024-11-27
updated = 2024-12-28
description = "Este tema incluye algunos shortcodes personalizados útiles que puedes utilizar para mejorar tus publicaciones. Puedes mostrar imágenes que se adapten a los temas claro y oscuro, dar formato a una sección de referencias con un aspecto profesional, y más."
[taxonomies]
@ -215,6 +215,38 @@ dist/
## Shortcodes de texto
### Aside (nota al margen)
Añade contenido complementario en los márgenes en pantallas anchas, o como bloques distintivos en móvil.
{{ aside(text="*Nota al margen* viene de *nota* (del latín, 'marca' o 'señal') y *margen* (del latín *margo*, 'borde' o 'límite').") }}
El shortcode acepta dos parámetros:
- `position`: Establecer como `"right"` para colocar en el margen derecho (por defecto, izquierdo)
- El contenido puede proporcionarse mediante el parámetro `text` o entre las etiquetas del shortcode
#### Uso
{{ admonition(type="warning", text="Separa la llamada al shortcode con saltos de línea para evitar errores de renderizado.") }}
Usando el parámetro `text`:
```
{{/* aside(text="*Nota al margen* viene de *nota* (del latín, 'marca' o 'señal') y *margen* (del latín *margo*, 'borde' o 'límite').") */}}
```
Usando el cuerpo del contenido e indicando la posición:
```
{%/* aside(position="right") */%}
Una nota más larga que
puede ocupar varias líneas.
Se admite *Markdown*.
{%/* end */%}
```
### Texto remoto
Añade texto desde una URL remota o un archivo local.

View file

@ -1,7 +1,7 @@
+++
title = "Custom shortcodes"
date = 2023-02-19
updated = 2024-11-27
updated = 2024-12-28
description = "This theme includes some useful custom shortcodes that you can use to enhance your posts. Whether you want to display images that adapt to light and dark themes, or format a professional-looking reference section, these custom shortcodes have got you covered."
[taxonomies]
@ -216,6 +216,38 @@ dist/
## Text shortcodes
### Aside (side/margin note)
Add supplementary content in the margins on wide screens, or as distinct blocks on mobile.
{{ aside(text="*Sidenote* comes from Latin *nota* ('mark') + Old English *síde* ('side').") }}
The shortcode accepts two parameters:
- `position`: Set to `"right"` to place in right margin (defaults to left)
- Content can be provided via `text` parameter or between shortcode tags
#### Usage
{{ admonition(type="warning", text="Place the aside shortcode on its own line to prevent formatting issues.") }}
Using the `text` parameter:
```
{{/* aside(text="*Sidenote* comes from Latin *nota* ('mark') + Old English *síde* ('side').") */}}
```
Using the content body and setting the position to right:
```
{%/* aside(position="right") */%}
A longer note that
can span multiple lines.
*Markdown* is supported.
{%/* end */%}
```
### Remote text
Embed text from a remote URL or a local file. To display the path or URL on the code block, see the [show source or path shortcode](#show-source-or-path).

View file

@ -0,0 +1,35 @@
+++
title = "nemui"
description = "Ajusta gradualment el teu horari de son amb suport per horari d'estiu."
weight = 22
[taxonomies]
tags = ["son", "interactiu", "web app", "web", "JavaScript"]
[extra]
local_image = "projects/nemui/nemui_logo.webp"
canonical_url = "https://osc.garden/ca/projects/tabi/"
social_media_card = "social_cards/projects_nemui.jpg"
+++
nemui és una aplicació web que t'ajuda a fer una transició suau a un nou horari de son. El seu nom ve de les paraules japoneses per dormir (<ruby><rt>nemu</rt></ruby>) i transició (<ruby><rt>i</rt></ruby>), que es llegeix com <ruby>眠い<rt>nemui</rt></ruby> (somnolent).
#### [Prova-la ara](https://nemui.osc.garden) • [GitHub](https://github.com/welpo/nemui) • [Blog](https://osc.garden/ca/blog/nemui-sleep-schedule-planner/) {.centered-text}
## Característiques
- Interfície interactiva de rellotge inspirada en Apple
- Ajust gradual de l'horari de son basat en la ciència del son
- Suport complet per a l'horari d'estiu (DST)
- Exportació a calendari (.ics) amb recordatoris per anar a dormir
- Emmagatzematge local per seguir el teu progrés
- Accessible: compatible amb navegació per teclat i lectors de pantalla
## Per què nemui?
A diferència dels canvis bruscos que poden alterar el teu ritme circadià, nemui t'ajuda a ajustar el teu horari de son de manera gradual. És especialment útil per a:
- Adaptar-te a nous horaris de feina/estudi
- Preparar-te per a canvis de zona horària
- Fer una transició suau durant els canvis d'hora
- Corregir un horari de son desajustat

View file

@ -0,0 +1,35 @@
+++
title = "nemui"
description = "Ajusta gradualmente tu horario de sueño con soporte para horario de verano."
weight = 32
[taxonomies]
tags = ["sueño", "interactivo", "web app", "web", "JavaScript"]
[extra]
local_image = "projects/nemui/nemui_logo.webp"
canonical_url = "https://osc.garden/es/projects/tabi/"
social_media_card = "social_cards/projects_nemui.jpg"
+++
nemui es una aplicación web que te ayuda a hacer una transición suave a un nuevo horario de sueño. Su nombre viene de las palabras japonesas para dormir (<ruby><rt>nemu</rt></ruby>) y transición (<ruby><rt>i</rt></ruby>), que se lee como <ruby>眠い<rt>nemui</rt></ruby> (somnoliento).
#### [Pruébala ahora](https://nemui.osc.garden) • [GitHub](https://github.com/welpo/nemui) • [Blog](https://osc.garden/es/blog/nemui-sleep-schedule-planner/) {.centered-text}
## Características
- Interfaz interactiva de reloj inspirada en Apple
- Ajuste gradual del horario de sueño basado en la ciencia del sueño
- Soporte completo para el horario de verano (DST)
- Exportación a calendario (.ics) con recordatorios para dormir
- Almacenamiento local para seguir tu progreso
- Accesible: compatible con navegación por teclado y lectores de pantalla
## ¿Por qué nemui?
A diferencia de los cambios bruscos que pueden alterar tu ritmo circadiano, nemui te ayuda a ajustar tu horario de sueño de forma gradual. Es especialmente útil para:
- Adaptarte a nuevos horarios de trabajo/estudio
- Prepararte para cambios de zona horaria
- Hacer una transición suave durante los cambios de hora
- Corregir un horario de sueño desajustado

View file

@ -0,0 +1,35 @@
+++
title = "nemui"
description = "Gradually adjust your sleep schedule with support for DST transitions."
weight = 32
[taxonomies]
tags = ["sleep", "interactive", "web app", "web", "JavaScript"]
[extra]
local_image = "projects/nemui/nemui_logo.webp"
canonical_url = "https://osc.garden/projects/tabi/"
social_media_card = "social_cards/projects_nemui.jpg"
+++
nemui is a web app that helps you smoothly transition to a new sleep schedule. Named after the Japanese words for sleep (<ruby><rt>nemu</rt></ruby>) and transition (<ruby><rt>i</rt></ruby>), reading as <ruby>眠い<rt>nemui</rt></ruby> (sleepy).
#### [Try it now](https://nemui.osc.garden) • [GitHub](https://github.com/welpo/nemui) • [Blog post](https://osc.garden/blog/nemui-sleep-schedule-planner/) {.centered-text}
## Features
- Interactive clock interface inspired by Apple
- Gradual sleep schedule adjustment based on sleep science
- Full Daylight Saving Time (DST) support
- Calendar (.ics) export with bedtime reminders
- Local storage for progress tracking
- Accessible: supports keyboard navigation and screen readers
## Why nemui?
Unlike abrupt changes that can disrupt your circadian rhythm, nemui helps you adjust your sleep schedule gradually. It's particularly useful for:
- Adapting to new work/study schedules
- Preparing for timezone changes
- Smoothly transitioning through DST changes
- Fixing a misaligned sleep schedule

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

View file

@ -1,7 +1,7 @@
+++
title = "ラム (ramu)"
title = "ramu"
description = "Una aplicació web per practicar la lectura i comprensió auditiva de nombres en japonès."
weight = 30
weight = 35
[taxonomies]
tags = ["Japonès", "interactiu", "web app", "web", "PWA", "JavaScript"]

View file

@ -1,7 +1,7 @@
+++
title = "ラム (ramu)"
title = "ramu"
description = "Una aplicación web para practicar la lectura y comprensión auditiva de números en japonés."
weight = 30
weight = 35
[taxonomies]
tags = ["Japonés", "interactivo", "web app", "web", "PWA", "JavaScript"]

View file

@ -1,7 +1,7 @@
+++
title = "ラム (ramu)"
title = "ramu"
description = "A web app to practice reading and listening to Japanese numbers."
weight = 30
weight = 35
[taxonomies]
tags = ["Japanese", "interactive", "web app", "web", "PWA", "JavaScript"]

View file

@ -0,0 +1,48 @@
+++
title = "shuku"
description = "Condensa pel·lícules i sèries per quedar-te només amb el diàleg. Dissenyat per aprendre idiomes."
weight = 20
[taxonomies]
tags = ["Python", "media", "linguistics", "CLI"]
[extra]
local_image = "projects/shuku/shuku_logo.webp"
social_media_card = "social_cards/projects_shuku.jpg"
canonical_url = "https://osc.garden/ca/projects/shuku/"
+++
**shuku** (<ruby><rb></rb><rt>しゅく</rt></ruby><ruby><rb></rb><rt>しょう</rt></ruby>: «minificació») crea versions condensades de pel·lícules i sèries conservant només els diàlegs.
<video class="invertible-image" controls muted width="800" loop="true" autoplay="autoplay" title="demo de shuku" src="https://cdn.jsdelivr.net/gh/welpo/shuku/assets/animation_demo/shuku_demo.mov"></video>
#### [GitHub](https://github.com/welpo/shuku) • [Blog](https://osc.garden/ca/blog/shuku-condensed-media-language-learning/) • [Documentació](https://github.com/welpo/shuku#readme) • [PyPI](https://pypi.org/project/shuku/) {.centered-text}
## Característiques
### Gestió intel·ligent de continguts
- Detecció i correspondència automàtica de subtítols amb cerca difusa (fuzzy matching)
- Selecció intel·ligent de pistes d'àudio/subtítols
- Extracció de metadades (títol, temporada, número d'episodi)
### Output flexible
- Àudio condensat (MP3, FLAC, AAC, Opus…)
- Vídeo condensat
- Subtítols sincronitzats (SRT, ASS, o LRC per a apps tipus karaoke)
### Alta personalització
- Qualitat i còdecs d'àudio/vídeo configurables
- Ajust de temps de subtítols i farciment
- Filtra subtítols (efectes de so, lletres, capítols específics)
- Suport per a arguments personalitzats de FFmpeg
### Experiència de l'usuari
- Multiplataforma: GNU+Linux, macOS i Windows
- Logging detallat amb indicadors de progrés
- Suport per a processament per lots
[![targeta social de shuku](/img/social_cards/projects_shuku.jpg)](https://github.com/welpo/shuku)

View file

@ -0,0 +1,48 @@
+++
title = "shuku"
description = "Condensa películas y series para quedarte solo con el diálogo. Diseñado para aprender idiomas."
weight = 20
[taxonomies]
tags = ["Python", "media", "linguistics", "CLI"]
[extra]
local_image = "projects/shuku/shuku_logo.webp"
social_media_card = "social_cards/projects_shuku.jpg"
canonical_url = "https://osc.garden/es/projects/shuku/"
+++
**shuku** (<ruby><rb></rb><rt>しゅく</rt></ruby><ruby><rb></rb><rt>しょう</rt></ruby>: «minificación») crea versiones condensadas de películas y series conservando solo los diálogos.
<video class="invertible-image" controls muted width="800" loop="true" autoplay="autoplay" title="demo de shuku" src="https://cdn.jsdelivr.net/gh/welpo/shuku/assets/animation_demo/shuku_demo.mov"></video>
#### [GitHub](https://github.com/welpo/shuku) • [Blog](https://osc.garden/es/blog/shuku-condensed-media-language-learning/) • [Documentación](https://github.com/welpo/shuku#readme) • [PyPI](https://pypi.org/project/shuku/) {.centered-text}
## Características
### Manejo inteligente de medios
- Detección y correspondencia automática de subtítulos con búsqueda difusa (fuzzy matching)
- Selección inteligente de pistas de audio/subtítulos
- Extracción de metadatos (título, temporada, número de episodio)
### Output flexible
- Audio condensado (MP3, FLAC, AAC, Opus…)
- Video condensado
- Subtítulos sincronizados (SRT, ASS, o LRC para apps tipo karaoke)
### Alta personalización
- Calidad y códecs de audio/video configurables
- Ajuste de tiempo de subtítulos y relleno
- Filtra subtítulos (efectos de sonido, letras, capítulos específicos)
- Soporte para argumentos personalizados de FFmpeg
### Experiencia del usuario
- Multiplataforma: GNU+Linux, macOS y Windows
- Logging detallado con indicadores de progreso
- Soporte para procesamiento por lotes
[![tarjeta social de shuku](/img/social_cards/projects_shuku.jpg)](https://github.com/welpo/shuku)

View file

@ -0,0 +1,56 @@
+++
title = "shuku"
description = "Shrink media to keep only the dialogue. For immersion language learning."
weight = 20
[taxonomies]
tags = ["Python", "media", "linguistics", "CLI"]
[extra]
local_image = "projects/shuku/shuku_logo.webp"
social_media_card = "social_cards/projects_shuku.jpg"
canonical_url = "https://osc.garden/projects/shuku/"
+++
**shuku** (<ruby><rb></rb><rt>しゅく</rt></ruby><ruby><rb></rb><rt>しょう</rt></ruby>: "minification") creates condensed versions of films and TV shows by keeping only the dialogue.
<video class="invertible-image" controls muted width="800" loop="true" autoplay="autoplay" title="shuku demo" src="https://cdn.jsdelivr.net/gh/welpo/shuku/assets/animation_demo/shuku_demo.mov"></video>
#### [GitHub](https://github.com/welpo/shuku) • [Blog post](https://osc.garden/blog/shuku-condensed-media-language-learning/) • [Documentation](https://github.com/welpo/shuku#readme) • [PyPI](https://pypi.org/project/shuku/) {.centered-text}
## Features
### Smart media handling
- Automatic subtitle detection and matching with fuzzy search
- Intelligent audio/subtitle track selection
- Metadata extraction (title, season, episode number)
### Flexible output
- Condensed audio (MP3, FLAC, AAC, Opus...)
- Condensed video
- Synchronized subtitles (including LRC for karaoke-style review)
- Clean filenames in output
### High customization
- Configurable audio/video quality and codecs
- Subtitle timing adjustment and padding
- Skip unwanted content (sound effects, lyrics, specific chapters)
- Custom FFmpeg arguments support
### User experience
- Cross-platform: GNU+Linux, macOS, and Windows
- Detailed logging with progress indicators
- Batch processing support
## Development best practices
- Comprehensive testing: 100% code coverage
- Clean code: Type-hinted Python with clear responsibilities
- Continuous Integration/Deployment
- Comprehensive documentation
[![shuku social media card](/img/social_cards/projects_shuku.jpg)](https://github.com/welpo/shuku)

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

View file

@ -4,7 +4,7 @@ description = "Una eina per calcular els royalties de streaming per a músics."
weight = 45
[taxonomies]
tags = ["música", "web app", "web", "JavaScript", "anàlisi de dades"]
tags = ["música", "interactiu", "web app", "web", "JavaScript", "anàlisi de dades"]
[extra]
local_image = "projects/streaming-royalties-calculator/streaming-royalties-calculator_logo.webp"

View file

@ -4,7 +4,7 @@ description = "Una herramienta para calcular los royalties de streaming para mú
weight = 45
[taxonomies]
tags = ["música", "web app", "web", "JavaScript", "análisis de datos"]
tags = ["música", "interactivo", "web app", "web", "JavaScript", "análisis de datos"]
[extra]
local_image = "projects/streaming-royalties-calculator/streaming-royalties-calculator_logo.webp"

View file

@ -4,7 +4,7 @@ description = "A tool to calculate streaming royalties for musicians."
weight = 45
[taxonomies]
tags = ["music", "web app", "web", "JavaScript", "data analysis"]
tags = ["music", "interactive", "web app", "web", "JavaScript", "data analysis"]
[extra]
local_image = "projects/streaming-royalties-calculator/streaming-royalties-calculator_logo.webp"

View file

@ -0,0 +1,51 @@
+++
title = "zutsu"
description = "Una aplicació minimalista i privada de gestió de tasques."
weight = 32
[taxonomies]
tags = ["interactiu", "productivitat", "web app", "web", "JavaScript"]
[extra]
local_image = "projects/zutsu/zutsu_logo.webp"
canonical_url = "https://osc.garden/ca/projects/zutsu/"
social_media_card = "social_cards/projects_zutsu.jpg"
+++
{% wide_container() %}
<video controls src="https://cdn.jsdelivr.net/gh/welpo/zutsu/assets/ずつ_demo.mov" title="demostració de zutsu"></video>
{% end %}
#### [Prova-la ara](https://zutsu.osc.garden) • [GitHub](https://github.com/welpo/zutsu) • [Article](https://osc.garden/ca/blog/zutsu-offline-task-planner-web-app/) {.centered-text}
<ruby><rt>zu</rt><rt>tsu</rt></ruby> és una aplicació web de gestió de tasques dissenyada per ajudar-te a centrar-te en una tasca cada vegada. El nom ve de <ruby>一つ<rt>hitotsu</rt>ずつ<rt>zutsu</rt></ruby>, que significa «d'un en un» en <ruby>日本語<rt>japonès</rt></ruby>.
## Per què?
Volia substituir els esdeveniments de calendari inflexibles per a les sessions d'estudi per alguna cosa senzilla i adaptable. Sense aplicacions de tercers, sense sincronització al núvol, només un espai centrat en a la gestió de tasques.
## Funcionalitats
### Principals
- Gestió de tasques amb possibilitat de reordenar-les arrossegant
- Temporitzador amb durada personalitzable per tasca
- Privada i offline —sense comptes, seguiment ni emmagatzematge al servidor
- Importació/exportació de llistes de tasques (JSON)
### Utilitats
- Temporitzador Pomodoro
- Calendari d'activitat (vista de 30 dies)
- Comptador i cronòmetre
- Espai per prendre notes
- Selectors aleatoris
### Qualitat de vida
- Tema fosc i clar
- Notificacions del navegador i so
- Dreceres de teclat
- Disseny responsive
[![targeta social de zutsu](social_cards/projects_zutsu.jpg)](https://zutsu.osc.garden)

View file

@ -0,0 +1,51 @@
+++
title = "zutsu"
description = "Una aplicación minimalista y privada de gestión de tareas."
weight = 32
[taxonomies]
tags = ["interactivo", "productividad", "web app", "web", "JavaScript"]
[extra]
local_image = "projects/zutsu/zutsu_logo.webp"
canonical_url = "https://osc.garden/es/projects/zutsu/"
social_media_card = "social_cards/projects_zutsu.jpg"
+++
{% wide_container() %}
<video controls src="https://cdn.jsdelivr.net/gh/welpo/zutsu/assets/ずつ_demo.mov" title="demostración de zutsu"></video>
{% end %}
#### [Pruébala ahora](https://zutsu.osc.garden) • [GitHub](https://github.com/welpo/zutsu) • [Artículo](https://osc.garden/es/blog/zutsu-offline-task-planner-web-app/) {.centered-text}
<ruby><rt>zu</rt><rt>tsu</rt></ruby> es una aplicación web de gestión de tareas diseñada para ayudarte a centrarte en una tarea a la vez. El nombre viene de <ruby>一つ<rt>hitotsu</rt>ずつ<rt>zutsu</rt></ruby>, que significa «uno por uno» en <ruby>日本語<rt>japonés</rt></ruby>.
## ¿Por qué?
Quería sustituir la inflexibilidad del calendario para planificar las sesiones de estudio por algo simple y adaptable. Sin aplicaciones de terceros, sin sincronización en la nube —solo un espacio centrado en la gestión de tareas.
## Funcionalidades
### Principales
- Gestión de tareas con posibilidad de reordenarlas arrastrando y soltando
- Temporizador con duración personalizable por tarea
- Privada y offline —sin cuentas, seguimiento ni almacenamiento en servidor
- Importación/exportación de listas de tareas (JSON)
### Utilidades
- Temporizador Pomodoro
- Calendario de actividad (vista de 30 días)
- Contador y cronómetro
- Espacio para tomar notas
- Selectores aleatorios
### Calidad de vida
- Tema oscuro y claro
- Notificaciones del navegador y sonido
- Atajos de teclado
- Diseño responsive
[![tarjeta social de zutsu](social_cards/projects_zutsu.jpg)](https://zutsu.osc.garden)

View file

@ -0,0 +1,51 @@
+++
title = "zutsu"
description = "A private minimalist task management app."
weight = 32
[taxonomies]
tags = ["interactive", "productivity", "web app", "web", "JavaScript"]
[extra]
local_image = "projects/zutsu/zutsu_logo.webp"
canonical_url = "https://osc.garden/projects/zutsu/"
social_media_card = "social_cards/projects_zutsu.jpg"
+++
{% wide_container() %}
<video controls src="https://cdn.jsdelivr.net/gh/welpo/zutsu/assets/ずつ_demo.mov" title="zutsu demo"></video>
{% end %}
#### [Try it now](https://zutsu.osc.garden) • [GitHub](https://github.com/welpo/zutsu) • [Blog post](https://osc.garden/blog/zutsu-offline-task-planner-web-app/) {.centered-text}
<ruby><rt>zu</rt><rt>tsu</rt></ruby> is a task management web app designed to help you focus on one task at a time. The name comes from <ruby>一つ<rt>hitotsu</rt>ずつ<rt>zutsu</rt></ruby> which means "one at a time" in <ruby>日本語<rt>Japanese</rt></ruby>.
## Why?
I wanted to replace inflexible calendar events for study sessions with something simple and adaptable. No third-party apps, no cloud sync —just a focused space for task management.
## Features
### Core
- Task management with drag-and-drop reordering
- Timer with customizable duration for each task
- Private & offline—no accounts, tracking, or server storage
- Import/export task lists (JSON)
### Utilities
- Pomodoro timer
- Activity calendar (30-day view)
- Counter & stopwatch
- Note-taking space
- Random choice makers
### Quality of life
- Dark and light theme support
- Browser and sound notifications
- Keyboard shortcuts
- Responsive design
[![zutsu social media card](social_cards/projects_zutsu.jpg)](https://zutsu.osc.garden)

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB