From e2cf4c0cbd618c99569902391c2e4d1d67423eed Mon Sep 17 00:00:00 2001 From: Kuba Orlik Date: Thu, 25 Jun 2026 20:43:30 +0200 Subject: [PATCH 01/52] Update the fonts config so we get more proper weights versions --- src/fonts.json | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/fonts.json b/src/fonts.json index 9d70f9e..b691d3e 100644 --- a/src/fonts.json +++ b/src/fonts.json @@ -1,9 +1,19 @@ +/* see https://gwfh.mranftl.com/fonts/ for available weights */ { "googleFonts": { "families": { - "Atkinson Hyperlegible": true, - "Libre Baskerville": true, - "Ubuntu Mono": true, + "Atkinson Hyperlegible": { + "wght": [400, 700], + "ital": [400, 700] + }, + "Libre Baskerville": { + "wght": [400, 500, 600, 700], + "ital": [400, 500, 600, 700] + }, + "Ubuntu Mono": { + "wght": [400, 700], + "ital": [400, 700] + }, "Anton": true } } From ac99ddda925f2a1c614e0f7c7d2711e17b1ecb61 Mon Sep 17 00:00:00 2001 From: Kuba Orlik Date: Thu, 16 Jul 2026 23:16:52 +0200 Subject: [PATCH 02/52] Update to the new NestedComponent API. Add side content to Tekst JDD component --- package-lock.json | 32 +++++++++---------- package.json | 4 +-- src/back/jdd-components/quote/quote.css | 10 ++++++ src/back/jdd-components/quote/quote.jdd.tsx | 27 ++++++++++++++++ .../split-view/split-view.jdd.tsx | 24 +++----------- src/back/jdd-components/tekst/tekst.css | 16 ++++++++++ src/back/jdd-components/tekst/tekst.jdd.tsx | 19 +++++++++-- 7 files changed, 92 insertions(+), 40 deletions(-) create mode 100644 src/back/jdd-components/quote/quote.css create mode 100644 src/back/jdd-components/quote/quote.jdd.tsx diff --git a/package-lock.json b/package-lock.json index 1d5de77..69ee888 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,8 +14,8 @@ "@koa/router": "^12.0.1", "@sealcode/add-to-head": "^1.0.0", "@sealcode/file-manager": "^1.0.2", - "@sealcode/jdd": "^0.8.6", - "@sealcode/jdd-editor": "^0.2.23", + "@sealcode/jdd": "^0.8.8", + "@sealcode/jdd-editor": "^0.2.24", "@sealcode/monaco-wrapper": "^0.0.4", "@sealcode/sealgen": "^0.19.21", "@sealcode/show-first-row": "^0.1.0", @@ -1357,9 +1357,9 @@ } }, "node_modules/@sealcode/jdd": { - "version": "0.8.6", - "resolved": "https://registry.npmjs.org/@sealcode/jdd/-/jdd-0.8.6.tgz", - "integrity": "sha512-IPntFEG/pi/ut85Fz0+eFCb0416uFYmugUKaiHyH2VQ0TKBo3MLQj7V6v8mWLNeOKAEkvejROUs0zbaJuTpgvA==", + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/@sealcode/jdd/-/jdd-0.8.8.tgz", + "integrity": "sha512-BsEkKNMFaHPna8wOiDVJMx/t81zBdWE9q2ckBnqEgbgnqvcTNNmEMpvkQYCndQP07OvW8kwkH7YYIynf+ajjPw==", "dependencies": { "@sealcode/file-manager": "^1.0.2", "@sealcode/ts-predicates": "^0.5.3", @@ -1380,12 +1380,12 @@ } }, "node_modules/@sealcode/jdd-editor": { - "version": "0.2.23", - "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.23.tgz", - "integrity": "sha512-YWzzY7bN27M8rwbjVn8/GanQbqRj5BORIFm5VxkAmu2xeZwvXd64G0547CIqQV1yL5Z2q/hs1d5VvlXVwnCYBw==", + "version": "0.2.24", + "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.24.tgz", + "integrity": "sha512-gL9ZJsPhN13ORGlK2mDMpFQYMtdKVfhGa0I+lq8j9VCsPg6I1ZKlgIrltWxVf7i8juN9GXM5imp5bojSkD1IAA==", "dependencies": { "@koa/router": "^13.1.0", - "@sealcode/jdd": "^0.8.6", + "@sealcode/jdd": "^0.8.8", "@sealcode/monaco-wrapper": "^0.0.6", "@sealcode/sealcodemirror": "^5.70.0-beta5", "@sealcode/sealgen": "^0.19.6", @@ -16000,9 +16000,9 @@ } }, "@sealcode/jdd": { - "version": "0.8.6", - "resolved": "https://registry.npmjs.org/@sealcode/jdd/-/jdd-0.8.6.tgz", - "integrity": "sha512-IPntFEG/pi/ut85Fz0+eFCb0416uFYmugUKaiHyH2VQ0TKBo3MLQj7V6v8mWLNeOKAEkvejROUs0zbaJuTpgvA==", + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/@sealcode/jdd/-/jdd-0.8.8.tgz", + "integrity": "sha512-BsEkKNMFaHPna8wOiDVJMx/t81zBdWE9q2ckBnqEgbgnqvcTNNmEMpvkQYCndQP07OvW8kwkH7YYIynf+ajjPw==", "requires": { "@sealcode/file-manager": "^1.0.2", "@sealcode/ts-predicates": "^0.5.3", @@ -16032,12 +16032,12 @@ } }, "@sealcode/jdd-editor": { - "version": "0.2.23", - "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.23.tgz", - "integrity": "sha512-YWzzY7bN27M8rwbjVn8/GanQbqRj5BORIFm5VxkAmu2xeZwvXd64G0547CIqQV1yL5Z2q/hs1d5VvlXVwnCYBw==", + "version": "0.2.24", + "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.24.tgz", + "integrity": "sha512-gL9ZJsPhN13ORGlK2mDMpFQYMtdKVfhGa0I+lq8j9VCsPg6I1ZKlgIrltWxVf7i8juN9GXM5imp5bojSkD1IAA==", "requires": { "@koa/router": "^13.1.0", - "@sealcode/jdd": "^0.8.6", + "@sealcode/jdd": "^0.8.8", "@sealcode/monaco-wrapper": "^0.0.6", "@sealcode/sealcodemirror": "^5.70.0-beta5", "@sealcode/sealgen": "^0.19.6", diff --git a/package.json b/package.json index beefc8c..06489c1 100644 --- a/package.json +++ b/package.json @@ -97,8 +97,8 @@ "@koa/router": "^12.0.1", "@sealcode/add-to-head": "^1.0.0", "@sealcode/file-manager": "^1.0.2", - "@sealcode/jdd": "^0.8.6", - "@sealcode/jdd-editor": "^0.2.23", + "@sealcode/jdd": "^0.8.8", + "@sealcode/jdd-editor": "^0.2.24", "@sealcode/monaco-wrapper": "^0.0.4", "@sealcode/sealgen": "^0.19.21", "@sealcode/show-first-row": "^0.1.0", diff --git a/src/back/jdd-components/quote/quote.css b/src/back/jdd-components/quote/quote.css new file mode 100644 index 0000000..6e54396 --- /dev/null +++ b/src/back/jdd-components/quote/quote.css @@ -0,0 +1,10 @@ +.quote { + background-color: var(--color-brand-accent); + color: var(--color-brand-text-on-accent); + padding: 16px; + + blockquote { + padding: 0; + margin: 0; + } +} diff --git a/src/back/jdd-components/quote/quote.jdd.tsx b/src/back/jdd-components/quote/quote.jdd.tsx new file mode 100644 index 0000000..8fae39b --- /dev/null +++ b/src/back/jdd-components/quote/quote.jdd.tsx @@ -0,0 +1,27 @@ +import { TempstreamJSX } from "tempstream"; +import type { ComponentToHTMLArgs } from "@sealcode/jdd"; +import { Component, ComponentArguments } from "@sealcode/jdd"; + +const component_arguments = { + content: new ComponentArguments.Markdown(), + signature: new ComponentArguments.ShortText(), +} as const; + +export class Quote extends Component { + getArguments() { + return component_arguments; + } + + async toHTML({ + args: { content, signature }, + classes, + jdd_context: { render_markdown, language }, + }: ComponentToHTMLArgs): Promise { + return ( +
+
{render_markdown(language, content)}
+

{signature}

+
+ ); + } +} diff --git a/src/back/jdd-components/split-view/split-view.jdd.tsx b/src/back/jdd-components/split-view/split-view.jdd.tsx index cd6dabf..1358554 100644 --- a/src/back/jdd-components/split-view/split-view.jdd.tsx +++ b/src/back/jdd-components/split-view/split-view.jdd.tsx @@ -21,14 +21,8 @@ export class SplitView extends Component { args: ExtractStructuredComponentArgumentsParsed ) { const result = [ - ...ComponentArguments.NestedComponent.getCSSClumpsForNested( - jdd_context, - (args?.component1 as Record) || {} - ), - ...ComponentArguments.NestedComponent.getCSSClumpsForNested( - jdd_context, - (args?.component2 as Record) || {} - ), + ...(args?.component1?.getCSSClumps(jdd_context) || []), + ...(args?.component2?.getCSSClumps(jdd_context) || []), ]; return result; } @@ -40,18 +34,8 @@ export class SplitView extends Component { }: ComponentToHTMLArgs): Promise { return (
-
- {ComponentArguments.NestedComponent.render({ - jdd_context, - data: component1 as Record, - })} -
-
- {ComponentArguments.NestedComponent.render({ - jdd_context, - data: component2 as Record, - })} -
+
{component1?.render(jdd_context)}
+
{component2?.render(jdd_context)}
); } diff --git a/src/back/jdd-components/tekst/tekst.css b/src/back/jdd-components/tekst/tekst.css index 66cae81..da51923 100644 --- a/src/back/jdd-components/tekst/tekst.css +++ b/src/back/jdd-components/tekst/tekst.css @@ -31,4 +31,20 @@ background-color: var(--color-brand-text-bg); color: var(--color-brand-text-accent2); } + + .side-content { + float: right; + max-width: 250px; + margin: 0 0 16px 16px; + container-type: inline-size; + width: 100%; + margin-right: calc(-1 * var(--bleed-outer-width)); + + @container (max-width: 570px) { + float: none; + max-width: 100%; + margin: 0; + margin-bottom: var(--row-gap); + } + } } diff --git a/src/back/jdd-components/tekst/tekst.jdd.tsx b/src/back/jdd-components/tekst/tekst.jdd.tsx index 964422e..0b3ea0a 100644 --- a/src/back/jdd-components/tekst/tekst.jdd.tsx +++ b/src/back/jdd-components/tekst/tekst.jdd.tsx @@ -10,6 +10,7 @@ import { Component, ComponentArguments } from "@sealcode/jdd"; const component_arguments = { color: new ComponentArguments.Enum(["transparent", "normal", "accent", "accent2"]), content: new ComponentArguments.Markdown(), + side_content: new ComponentArguments.NestedComponent(), } as const; export class Tekst extends Component { @@ -24,17 +25,31 @@ export class Tekst extends Component { return args.content.slice(0, 20) + "..." || null; } + getCSSClumps( + jdd_context: JDDContext, + args: ExtractStructuredComponentArgumentsParsed + ) { + const result = args?.side_content?.getCSSClumps(jdd_context) || []; + return result; + } + toHTML({ - args: { color, content }, + args: { color, content, side_content }, classes, - jdd_context: { render_markdown, language }, + jdd_context, index, }: ComponentToHTMLArgs): FlatTemplatable { + const { render_markdown, language } = jdd_context; return (
+ {side_content.isEmpty() ? ( + "" + ) : ( +
{side_content.render(jdd_context)}
+ )} {render_markdown(language, content)}
); From 5e5c64cbc83bebfec4f211daf0b46d96551d9d87 Mon Sep 17 00:00:00 2001 From: Kuba Orlik Date: Thu, 16 Jul 2026 23:50:00 +0200 Subject: [PATCH 03/52] Fix row spacing in custom page view --- .../custom-css-wrapper.jdd.tsx | 19 ++++++++++++++----- src/back/routes/middlewares/customUrlView.tsx | 2 +- src/main.css | 2 +- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/back/jdd-components/custom-css-wrapper/custom-css-wrapper.jdd.tsx b/src/back/jdd-components/custom-css-wrapper/custom-css-wrapper.jdd.tsx index a4dd5bf..23751e2 100644 --- a/src/back/jdd-components/custom-css-wrapper/custom-css-wrapper.jdd.tsx +++ b/src/back/jdd-components/custom-css-wrapper/custom-css-wrapper.jdd.tsx @@ -1,5 +1,9 @@ import { TempstreamJSX } from "tempstream"; -import type { ComponentToHTMLArgs } from "@sealcode/jdd"; +import type { + ComponentToHTMLArgs, + ExtractStructuredComponentArgumentsParsed, + JDDContext, +} from "@sealcode/jdd"; import { Component, ComponentArguments } from "@sealcode/jdd"; import { v4 as uuid } from "uuid"; @@ -13,6 +17,14 @@ export class CustomCssWrapper extends Component { return component_arguments; } + getCSSClumps( + jdd_context: JDDContext, + args: ExtractStructuredComponentArgumentsParsed + ) { + const result = args?.content?.getCSSClumps(jdd_context) || []; + return result; + } + async toHTML({ args: { custom_css, content }, classes, @@ -26,10 +38,7 @@ export class CustomCssWrapper extends Component { .${unique_class}{ ${custom_css} } ` } - {ComponentArguments.NestedComponent.render({ - jdd_context, - data: content as Record, - })} + {content.render(jdd_context)} ); } diff --git a/src/back/routes/middlewares/customUrlView.tsx b/src/back/routes/middlewares/customUrlView.tsx index eb781ef..ce6edf8 100644 --- a/src/back/routes/middlewares/customUrlView.tsx +++ b/src/back/routes/middlewares/customUrlView.tsx @@ -62,7 +62,7 @@ export const customUrlView = showFooter: !hideNavigation, }, body: ( -
+
{heading?.trim() ?

{heading}

: ""} {jdd.render()}
diff --git a/src/main.css b/src/main.css index acd6123..5fc9d6f 100644 --- a/src/main.css +++ b/src/main.css @@ -88,7 +88,7 @@ body { row-gap: var(--row-gap); & > * { - grid-column: main-column-content-start / main-column-content-end; + grid-column: content; } } From de3b45dfed9a7f1b610cbb5afc33f99f42052af5 Mon Sep 17 00:00:00 2001 From: Kuba Orlik Date: Mon, 20 Jul 2026 21:03:14 +0200 Subject: [PATCH 04/52] Update jdd-editor to fix glitches on hovering blocks --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 69ee888..e0b90a0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "@sealcode/add-to-head": "^1.0.0", "@sealcode/file-manager": "^1.0.2", "@sealcode/jdd": "^0.8.8", - "@sealcode/jdd-editor": "^0.2.24", + "@sealcode/jdd-editor": "^0.2.25", "@sealcode/monaco-wrapper": "^0.0.4", "@sealcode/sealgen": "^0.19.21", "@sealcode/show-first-row": "^0.1.0", @@ -1380,9 +1380,9 @@ } }, "node_modules/@sealcode/jdd-editor": { - "version": "0.2.24", - "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.24.tgz", - "integrity": "sha512-gL9ZJsPhN13ORGlK2mDMpFQYMtdKVfhGa0I+lq8j9VCsPg6I1ZKlgIrltWxVf7i8juN9GXM5imp5bojSkD1IAA==", + "version": "0.2.25", + "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.25.tgz", + "integrity": "sha512-/VFuQIgFpvONsg4SSHIDs5CtZ6JMlaGtKT39AznNOCM8KZwLQ+Ma7WNkJ+g2bk/0kiPvZctIvvn9e2T0mFA6Rg==", "dependencies": { "@koa/router": "^13.1.0", "@sealcode/jdd": "^0.8.8", @@ -16032,9 +16032,9 @@ } }, "@sealcode/jdd-editor": { - "version": "0.2.24", - "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.24.tgz", - "integrity": "sha512-gL9ZJsPhN13ORGlK2mDMpFQYMtdKVfhGa0I+lq8j9VCsPg6I1ZKlgIrltWxVf7i8juN9GXM5imp5bojSkD1IAA==", + "version": "0.2.25", + "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.25.tgz", + "integrity": "sha512-/VFuQIgFpvONsg4SSHIDs5CtZ6JMlaGtKT39AznNOCM8KZwLQ+Ma7WNkJ+g2bk/0kiPvZctIvvn9e2T0mFA6Rg==", "requires": { "@koa/router": "^13.1.0", "@sealcode/jdd": "^0.8.8", diff --git a/package.json b/package.json index 06489c1..e2469b9 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,7 @@ "@sealcode/add-to-head": "^1.0.0", "@sealcode/file-manager": "^1.0.2", "@sealcode/jdd": "^0.8.8", - "@sealcode/jdd-editor": "^0.2.24", + "@sealcode/jdd-editor": "^0.2.25", "@sealcode/monaco-wrapper": "^0.0.4", "@sealcode/sealgen": "^0.19.21", "@sealcode/show-first-row": "^0.1.0", From d68d94553d68614b775e036be59ba850a07574b6 Mon Sep 17 00:00:00 2001 From: Kuba Orlik Date: Mon, 20 Jul 2026 23:31:05 +0200 Subject: [PATCH 05/52] Fale w navbarze --- src/back/routes/common/navbar.css | 115 ++++++++++++++++++++++++++++++ src/back/routes/common/navbar.ts | 25 ++++++- src/icons/hamburger-close.svg | 67 +++++++++++++++++ src/icons/hamburger.svg | 69 ++++++++++++++++++ src/main.css | 21 ------ 5 files changed, 274 insertions(+), 23 deletions(-) create mode 100644 src/back/routes/common/navbar.css create mode 100644 src/icons/hamburger-close.svg create mode 100644 src/icons/hamburger.svg diff --git a/src/back/routes/common/navbar.css b/src/back/routes/common/navbar.css new file mode 100644 index 0000000..a7d15c5 --- /dev/null +++ b/src/back/routes/common/navbar.css @@ -0,0 +1,115 @@ +.nav-logo { + display: flex; + align-items: center; +} + +nav { + display: flex; + flex-flow: row wrap; + justify-content: space-between; + + ul.desktop-menu { + display: flex; + gap: 8px; + padding-left: 0; + + li { + list-style: none; + } + } + + .hamburger-menu__icon { + cursor: pointer; + + svg * { + fill: var(--color-brand-accent) !important; + } + + &:hover { + transform: scale(1.1); + } + } + + .hamburger-menu-toggle { + display: none; + anchor-name: --hamburger-toggle; + + input { + display: none; + } + + .hamburger-menu__open-icon { + display: block; + anchor-name: --my-anchor; + } + + .hamburger-menu__close-icon { + display: none; + } + } + + .hamburger-menu { + display: none; + } + + @media (max-width: 1000px) { + .hamburger-menu-toggle { + display: flex; + align-items: center; + } + + ul.desktop-menu { + display: none; + } + + .hamburger-menu { + position: fixed; + position-anchor: --my-anchor; + top: calc(anchor(top) - 2px); + right: calc(anchor(right) - 14px); + display: flex; + opacity: 0; + transition: opacity 50ms; + pointer-events: none; + box-shadow: -3px 3px var(--color-brand-canvas-07); + background-color: var(--color-brand-canvas); + flex-flow: column; + padding: 12px; + padding-top: 2px; + align-items: flex-end; + + ul { + display: flex !important; + margin: 0; + padding: 0; + + flex-flow: column; + align-items: stretch; + justify-content: stretch; + width: 50%; + width: fit-content; + row-gap: 12px; + + li { + list-style: none; + + a { + margin: 0; + width: 100%; + } + } + } + } + + &:has(#hamburger-menu-toggle-checkbox:checked) { + .hamburger-menu__close-icon { + display: block; + } + + .hamburger-menu { + opacity: 1; + pointer-events: all; + } + } + } +} diff --git a/src/back/routes/common/navbar.ts b/src/back/routes/common/navbar.ts index d10cc0f..e03ac50 100644 --- a/src/back/routes/common/navbar.ts +++ b/src/back/routes/common/navbar.ts @@ -1,5 +1,6 @@ import type { Context } from "koa"; import { button } from "src/back/elements/button.js"; +import { icon } from "src/back/icons.js"; import { tempstream } from "tempstream"; import type { FlatTemplatable } from "tempstream"; import { breadcrumbs } from "./breadcrumbs.js"; @@ -26,7 +27,7 @@ export async function default_navbar(ctx: Context): Promise { ) .join("\n"); - return /* HTML */ tempstream`