Compare commits

...

41 Commits

Author SHA1 Message Date
52a3963d4c Add zrzutka and fix navbar whitespace 2026-08-26 22:10:15 +02:00
5938b39892 Merge remote-tracking branch 'playground/master' 2026-08-26 22:08:59 +02:00
50296818d8 Fix mobilizon svg and optimize other icons 2026-08-26 22:08:17 +02:00
a57157f995 Addmissing svg icons 2026-08-26 19:49:30 +02:00
983dbd754c Fixes for the horizontal scroller styles and behavior 2026-08-26 19:41:29 +02:00
8424b49477 Merge remote-tracking branch 'playground/master' 2026-08-25 14:34:32 +02:00
d715fc54a5 update svg 2026-08-25 14:34:23 +02:00
dc8b988bd6 Merge remote-tracking branch 'playground/master' 2026-08-25 14:22:47 +02:00
67e86f6275 Update svg 2026-08-25 14:22:34 +02:00
c290d42296 Merge remote-tracking branch 'playground/master' 2026-08-25 14:19:32 +02:00
7cecd0abe8 update svg icon 2026-08-25 14:19:14 +02:00
9e76f00246 Merge remote-tracking branch 'playground/master' 2026-08-25 14:16:33 +02:00
61f2b39c6c Add mobilizon icon 2026-08-25 14:16:04 +02:00
e426b0f4d8 nbsp in dynamic grid 2026-08-24 10:09:59 +02:00
6631bd7980 Add pop-out style to dynamic grid 2026-08-24 10:06:27 +02:00
970a7892a1 sendeml: Don't encode images as base64 data uris because gmail doesn't like that 2026-08-21 19:13:41 +02:00
4b92ec1153 Fix Horizontal scroller not working on mobile 2026-08-21 16:57:49 +02:00
2be25d59be Update sealgen to fix endless loop of building in macos 2026-08-20 18:36:26 +02:00
af82fa80c4 Fix lint issues 2026-08-20 17:55:58 +02:00
d16076af92 Fix footer icons balance 2026-08-20 15:21:04 +02:00
99172bb852 Balanced icons in footer 2026-08-20 15:14:11 +02:00
a3fe0e6844 Frame variants padding 2026-08-20 11:58:57 +02:00
9a36e7f655 Subtree fix on nested subgrid 2026-08-20 11:54:38 +02:00
f5327dfe7c More padding in dynamic grid 2026-08-19 23:53:55 +02:00
d1da6d7dc7 Icon tiles option to always show CTA 2026-08-19 23:35:06 +02:00
d08817c729 Spacing adjustments in icon tiles 2026-08-19 23:27:48 +02:00
f7e4060686 Use horizontal images on mobile dynamic grid 2026-08-19 23:25:34 +02:00
1ecea82a61 Sizing and spacing in FAQ 2026-08-19 23:20:26 +02:00
12de366f3a Make headings smaller on mobile 2026-08-19 23:18:09 +02:00
75083f28aa Add missing button code 2026-08-19 23:17:20 +02:00
1bb3f373c3 Add sizez to buttons 2026-08-19 23:14:06 +02:00
ca8e4438bc Configurable bleed for buttons 2026-08-19 22:59:39 +02:00
b462cbb310 Add crooked and frame variants to background wrapper 2026-08-19 22:53:27 +02:00
750ee35ef4 Fix split-view inside subtree 2026-08-19 22:36:49 +02:00
b0ed7171a6 Add heading alignment 2026-08-19 22:28:18 +02:00
cffeb98914 More flexible bleeds in tekst and subtree 2026-08-19 22:22:57 +02:00
dde87bd086 Add anchor component 2026-08-19 22:04:44 +02:00
f844ca660f Fix unnecessary clickable links in dynamic grid 2026-08-18 20:38:11 +02:00
83fe4c4872 Fix vertical tile in dynamic grid vs 2026-08-18 20:32:14 +02:00
67554b020d Reponsive fixes for dynamic grid v2 2026-08-18 08:12:39 +02:00
daeaea5488 Dynamic Grid V2 2026-08-18 08:01:39 +02:00
38 changed files with 671 additions and 308 deletions

14
package-lock.json generated
View File

@ -17,7 +17,7 @@
"@sealcode/jdd": "^0.8.13", "@sealcode/jdd": "^0.8.13",
"@sealcode/jdd-editor": "^0.2.37", "@sealcode/jdd-editor": "^0.2.37",
"@sealcode/monaco-wrapper": "^0.0.12", "@sealcode/monaco-wrapper": "^0.0.12",
"@sealcode/sealgen": "^0.19.23", "@sealcode/sealgen": "^0.19.25",
"@sealcode/show-first-row": "^0.1.0", "@sealcode/show-first-row": "^0.1.0",
"@sealcode/simplemde": "^1.12.1", "@sealcode/simplemde": "^1.12.1",
"@sealcode/sortable": "^0.0.1", "@sealcode/sortable": "^0.0.1",
@ -1463,9 +1463,9 @@
"integrity": "sha512-N4BuMuantv2A63PbFwLg53AJbDZ2/BzKxpgBIRd7jDWyZLw58en6FFZgcbXMLDU7gwKNYfyLOJMLwXyn6aEsnQ==" "integrity": "sha512-N4BuMuantv2A63PbFwLg53AJbDZ2/BzKxpgBIRd7jDWyZLw58en6FFZgcbXMLDU7gwKNYfyLOJMLwXyn6aEsnQ=="
}, },
"node_modules/@sealcode/sealgen": { "node_modules/@sealcode/sealgen": {
"version": "0.19.23", "version": "0.19.25",
"resolved": "https://registry.npmjs.org/@sealcode/sealgen/-/sealgen-0.19.23.tgz", "resolved": "https://registry.npmjs.org/@sealcode/sealgen/-/sealgen-0.19.25.tgz",
"integrity": "sha512-jKMp4LdOWC5lwOzHC6bT9y98NxZ5U6CpzdjoqtghwBIZZQh9Z58FX5+wgLO+u6Vzec7+7Gyt3097x6r4L18DdA==", "integrity": "sha512-ryWLuKn9S53XDsSEmttWjM57Wa/thrOEaMvM2uy5xOYkBVo9saTTBFmInm53In1nnrh44kNkuYogBLG4dXhNfw==",
"dependencies": { "dependencies": {
"@koa/router": "^12.0.1", "@koa/router": "^12.0.1",
"@sealcode/file-manager": "^1.0.2", "@sealcode/file-manager": "^1.0.2",
@ -16383,9 +16383,9 @@
"integrity": "sha512-N4BuMuantv2A63PbFwLg53AJbDZ2/BzKxpgBIRd7jDWyZLw58en6FFZgcbXMLDU7gwKNYfyLOJMLwXyn6aEsnQ==" "integrity": "sha512-N4BuMuantv2A63PbFwLg53AJbDZ2/BzKxpgBIRd7jDWyZLw58en6FFZgcbXMLDU7gwKNYfyLOJMLwXyn6aEsnQ=="
}, },
"@sealcode/sealgen": { "@sealcode/sealgen": {
"version": "0.19.23", "version": "0.19.25",
"resolved": "https://registry.npmjs.org/@sealcode/sealgen/-/sealgen-0.19.23.tgz", "resolved": "https://registry.npmjs.org/@sealcode/sealgen/-/sealgen-0.19.25.tgz",
"integrity": "sha512-jKMp4LdOWC5lwOzHC6bT9y98NxZ5U6CpzdjoqtghwBIZZQh9Z58FX5+wgLO+u6Vzec7+7Gyt3097x6r4L18DdA==", "integrity": "sha512-ryWLuKn9S53XDsSEmttWjM57Wa/thrOEaMvM2uy5xOYkBVo9saTTBFmInm53In1nnrh44kNkuYogBLG4dXhNfw==",
"requires": { "requires": {
"@koa/router": "^12.0.1", "@koa/router": "^12.0.1",
"@sealcode/file-manager": "^1.0.2", "@sealcode/file-manager": "^1.0.2",

View File

@ -104,7 +104,7 @@
"@sealcode/jdd": "^0.8.13", "@sealcode/jdd": "^0.8.13",
"@sealcode/jdd-editor": "^0.2.37", "@sealcode/jdd-editor": "^0.2.37",
"@sealcode/monaco-wrapper": "^0.0.12", "@sealcode/monaco-wrapper": "^0.0.12",
"@sealcode/sealgen": "^0.19.23", "@sealcode/sealgen": "^0.19.25",
"@sealcode/show-first-row": "^0.1.0", "@sealcode/show-first-row": "^0.1.0",
"@sealcode/simplemde": "^1.12.1", "@sealcode/simplemde": "^1.12.1",
"@sealcode/sortable": "^0.0.1", "@sealcode/sortable": "^0.0.1",

View File

@ -12,6 +12,7 @@ export function button({
submit = false, submit = false,
icon, icon,
centered = false, centered = false,
classes = [],
}: { }: {
text: string; text: string;
href: string; href: string;
@ -20,6 +21,7 @@ export function button({
submit?: boolean; submit?: boolean;
icon?: string; icon?: string;
centered?: boolean; centered?: boolean;
classes?: string[];
}): JSX.Element { }): JSX.Element {
const classstr = `button button--color-${variant}`; const classstr = `button button--color-${variant}`;
if (submit) { if (submit) {
@ -33,6 +35,7 @@ export function button({
"button", "button",
`button--color-${variant}`, `button--color-${variant}`,
{ "button--centered": centered }, { "button--centered": centered },
...classes,
]} ]}
href={disabled ? false : href} href={disabled ? false : href}
disabled={disabled} disabled={disabled}

View File

@ -14,7 +14,7 @@ export async function sendEml(
for (const [key, value] of Object.entries(template_data)) { for (const [key, value] of Object.entries(template_data)) {
eml_content = eml_content.replaceAll(`{{${key}}}`, htmlEscape(value)); eml_content = eml_content.replaceAll(`{{${key}}}`, htmlEscape(value));
} }
const parsed = await simpleParser(eml_content); const parsed = await simpleParser(eml_content, { skipImageLinks: true });
const mailer = context.$app.mailer; const mailer = context.$app.mailer;

View File

@ -0,0 +1,20 @@
import { TempstreamJSX } from "tempstream";
import type { ComponentToHTMLArgs } from "@sealcode/jdd";
import { Component, ComponentArguments } from "@sealcode/jdd";
const component_arguments = {
id: new ComponentArguments.ShortText(),
} as const;
export class Anchor extends Component<typeof component_arguments> {
getArguments() {
return component_arguments;
}
async toHTML({
args: { id },
classes,
}: ComponentToHTMLArgs<typeof component_arguments>): Promise<string> {
return <div id={id} class={["anchor", "jdd-no-gap", ...classes]}></div>;
}
}

View File

@ -7,6 +7,18 @@
padding: var(--vertical-padding) 0; padding: var(--vertical-padding) 0;
&.background-wrapper--bleed-none {
grid-column: content !important;
}
&.background-wrapper--bleed-bleed {
grid-column: bleed !important;
}
&.background-wrapper--bleed-screen {
grid-column: 1/-1 !important;
}
&.background-wrapper--padding-no { &.background-wrapper--padding-no {
padding: 0; padding: 0;
} }
@ -37,4 +49,30 @@
color: var(--color-brand-text-on-accent2); color: var(--color-brand-text-on-accent2);
--color-brand-text-fg: var(--color-brand-text-on-accent2); --color-brand-text-fg: var(--color-brand-text-on-accent2);
} }
&.background-wrapper--frame1 {
padding: 16px;
border: 16px dashed var(--color-brand-accent);
background-color: color-mix(
in srgb,
var(--color-brand-accent) 20%,
transparent 80%
);
--color-brand-text-bg: transparent;
}
&.background-wrapper--frame2 {
padding: 16px;
border: 16px dashed var(--color-brand-accent2);
background-color: color-mix(
in srgb,
var(--color-brand-accent2) 20%,
transparent 80%
);
--color-brand-text-bg: transparent;
}
&.background-wrapper--crooked {
transform: scale(1.05) rotate(-2deg);
}
} }

View File

@ -6,7 +6,7 @@ import type {
} from "@sealcode/jdd"; } from "@sealcode/jdd";
import { Component, ComponentArguments } from "@sealcode/jdd"; import { Component, ComponentArguments } from "@sealcode/jdd";
export const background_variants = ["variant1", "variant2"]; export const background_variants = ["variant1", "variant2", "frame1", "frame2"];
const component_arguments = { const component_arguments = {
variant: new ComponentArguments.Enum(background_variants), variant: new ComponentArguments.Enum(background_variants),
@ -14,6 +14,10 @@ const component_arguments = {
padding: new ComponentArguments.Boolean(), padding: new ComponentArguments.Boolean(),
big_padding: new ComponentArguments.Boolean(), big_padding: new ComponentArguments.Boolean(),
margin: new ComponentArguments.Boolean(), margin: new ComponentArguments.Boolean(),
bleed: new ComponentArguments.Enum(["none", "bleed", "screen"]).setDefaultValue(
"screen"
),
crooked: new ComponentArguments.Boolean().setDefaultValue(false),
content: new ComponentArguments.NestedComponent(), content: new ComponentArguments.NestedComponent(),
} as const; } as const;
@ -31,7 +35,16 @@ export class BackgroundWrapper extends Component<typeof component_arguments> {
} }
async toHTML({ async toHTML({
args: { variant, content, grow_to_screen_height, padding, margin, big_padding }, args: {
variant,
content,
grow_to_screen_height,
padding,
margin,
big_padding,
bleed,
crooked,
},
classes, classes,
jdd_context, jdd_context,
}: ComponentToHTMLArgs<typeof component_arguments>): Promise<string> { }: ComponentToHTMLArgs<typeof component_arguments>): Promise<string> {
@ -40,10 +53,12 @@ export class BackgroundWrapper extends Component<typeof component_arguments> {
class={[ class={[
"background-wrapper", "background-wrapper",
`background-wrapper--${variant}`, `background-wrapper--${variant}`,
`background-wrapper--bleed-${bleed}`,
`background-wrapper--padding-${padding ? "yes" : "no"}`, `background-wrapper--padding-${padding ? "yes" : "no"}`,
`background-wrapper--big-padding-${big_padding ? "yes" : "no"}`, `background-wrapper--big-padding-${big_padding ? "yes" : "no"}`,
{ {
"background-wrapper--grow-height": grow_to_screen_height, "background-wrapper--grow-height": grow_to_screen_height,
"background-wrapper--crooked": crooked,
"jdd-no-gap": !margin, "jdd-no-gap": !margin,
}, },
...classes, ...classes,

View File

@ -25,7 +25,51 @@
gap: 24px; gap: 24px;
} }
&.buttons--bleed-none {
grid-column: content !important;
}
&.buttons--bleed-bleed {
grid-column: bleed !important;
}
&.buttons--bleed-screen {
grid-column: 1/-1 !important;
}
.button { .button {
margin: 0; margin: 0;
&.button--size-tiny {
font-size: 10px;
}
&.button--size-small {
font-size: 14px;
}
&.button--size-medium {
font-size: 16px;
@container (max-width: 500px) {
font-size: 15px;
}
}
&.button--size-large {
font-size: 24px;
@container (max-width: 500px) {
font-size: 18px;
}
}
&.button--size-extra-large {
font-size: 32px;
@container (max-width: 500px) {
font-size: 24px;
}
}
} }
} }

View File

@ -6,11 +6,21 @@ import { button, button_variants } from "src/back/elements/button.js";
const component_arguments = { const component_arguments = {
mode: new ComponentArguments.Enum(["column", "row"]), mode: new ComponentArguments.Enum(["column", "row"]),
gap: new ComponentArguments.Enum(["none", "narrow", "medium", "wide"]), gap: new ComponentArguments.Enum(["none", "narrow", "medium", "wide"]),
bleed: new ComponentArguments.Enum(["none", "bleed", "screen"]).setDefaultValue(
"none"
),
buttons: new ComponentArguments.List( buttons: new ComponentArguments.List(
new ComponentArguments.Structured({ new ComponentArguments.Structured({
variant: new ComponentArguments.Enum(button_variants), variant: new ComponentArguments.Enum(button_variants),
text: new ComponentArguments.ShortText(), text: new ComponentArguments.ShortText(),
href: new ComponentArguments.ShortText(), href: new ComponentArguments.ShortText(),
size: new ComponentArguments.Enum([
"tiny",
"small",
"medium",
"large",
"extra-large",
]).setDefaultValue("medium"),
}) })
), ),
} as const; } as const;
@ -21,7 +31,7 @@ export class Buttons extends Component<typeof component_arguments> {
} }
async toHTML({ async toHTML({
args: { buttons, mode, gap }, args: { buttons, mode, gap, bleed },
classes, classes,
}: ComponentToHTMLArgs<typeof component_arguments>): Promise<string> { }: ComponentToHTMLArgs<typeof component_arguments>): Promise<string> {
return ( return (
@ -30,10 +40,17 @@ export class Buttons extends Component<typeof component_arguments> {
"buttons", "buttons",
`buttons--mode-${mode}`, `buttons--mode-${mode}`,
`buttons--gap-${gap}`, `buttons--gap-${gap}`,
`buttons--bleed-${bleed}`,
...classes, ...classes,
]} ]}
> >
{buttons.map((b) => button({ ...b, text: insert_nbsp(b.text) }))} {buttons.map((b) =>
button({
...b,
text: insert_nbsp(b.text),
classes: [`button--size-${b.size}`],
})
)}
</div> </div>
); );
} }

View File

@ -0,0 +1,272 @@
.dynamic-grid {
container-type: inline-size;
&.dynamic-grid--bleed-bleed {
grid-column: bleed !important;
}
&.dynamic-grid--bleed-screen {
grid-column: screen !important;
}
.dynamic-grid-title {
text-align: center;
margin-top: 0;
}
.tiles-container {
display: grid;
grid-gap: 24px;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: min-content;
grid-auto-flow: row dense;
@container (min-width: 900px) {
grid-template-columns: repeat(4, 1fr);
}
.tile {
overflow: hidden;
display: grid;
gap: 0;
grid-template-columns: subgrid;
grid-template-rows: subgrid;
color: var(--color-brand-text-fg);
text-decoration: none;
.tile-content {
grid-row: 2/3;
background-color: var(--tile-bg-color);
color: var(--tile-fg-color);
width: 100%;
padding: 16px;
z-index: 1;
overflow: hidden;
bottom: 0;
box-sizing: border-box;
.tile-content-wrapper {
display: flex;
flex-flow: column;
gap: 16px;
.tile-title {
font-weight: bold;
line-height: 20px;
margin: 0;
}
.tile-subtitle {
line-height: 20px;
margin: 0;
}
}
}
.tile-image {
z-index: 0;
width: 100%;
height: 100%;
grid-row: 1/2;
picture {
height: 100%;
width: 100% !important;
}
}
}
.tile.square {
grid-column: span 1;
grid-row: span 2;
.tile-content {
grid-row: 2/3;
}
.tile-image--horizontal {
display: none;
}
.tile-image--vertical {
display: none;
}
.tile-image--square {
grid-row: 1/2;
picture img {
display: block !important;
}
}
}
.tile.horizontal {
grid-column: span 2;
grid-row: span 2;
.tile-content {
grid-column: 1/3;
}
.tile-image--vertical {
display: none;
}
.tile-image--square {
display: none;
}
.tile-image--horizontal {
grid-column: 1/3;
picture img {
display: block !important;
}
}
}
.tile.vertical {
grid-row: span 4;
grid-column: span 1;
.tile-content {
grid-row: 4/5;
}
.tile-image--horizontal {
display: none;
}
.tile-image--square {
display: none;
}
.tile-image--vertical {
grid-row: 1/4;
picture img {
display: block !important;
}
}
}
.buttons-container {
margin-top: 36px;
display: flex;
justify-content: center;
flex-flow: row wrap;
column-gap: 18px;
row-gap: 16px;
.button {
display: inline-block;
text-align: center;
padding: 8px 24px;
border: 1px solid var(--color-brand-text-fg);
color: var(--text-color);
min-width: 240px;
line-height: 23px;
font-size: 16px;
&.accent {
background-color: var(--color-brand-accent);
--text-color: var(--color-brand-text-on-accent);
}
&.accent2 {
background-color: var(--color-brand-accent2);
--text-color: var(--color-brand-text-on-accent2);
}
}
}
}
@container (max-width: 900px) {
.tiles-container {
grid-template-columns: repeat(3, 1fr);
}
}
@container (max-width: 700px) {
.tiles-container {
grid-template-columns: repeat(2, 1fr);
.tile.vertical {
grid-row: span 2;
grid-column: span 1;
.tile-image--vertical {
display: none;
}
.tile-image--horizontal {
display: none;
}
.tile-image--square {
display: block;
picture img {
display: block !important;
}
}
}
}
}
@container (max-width: 500px) {
.tiles-container {
grid-template-columns: 1fr;
max-width: 700px;
margin: 0 auto;
.tile {
grid-column: span 1 !important;
grid-row: span 2 !important;
.tile-content {
grid-row: 2/3 !important;
}
.tile-image--vertical {
display: none !important;
}
.tile-image--square {
display: none !important;
}
.tile-image--horizontal {
display: block !important;
grid-row: 1/2 !important;
picture img {
display: block !important;
}
}
}
}
}
&.dynamic-grid--style-pop-out {
.tile {
overflow: visible;
.tile-content {
transform: translateY(-20px) translateX(20px);
box-shadow: -10px 10px 0px #00000026;
}
.tile-image {
grid-row: 1/3 !important;
}
.tile-image--vertical {
grid-row: 1/5 !important;
}
}
}
}

View File

@ -0,0 +1,119 @@
import type { FlatTemplatable } from "tempstream";
import { TempstreamJSX } from "tempstream";
import type { ComponentToHTMLArgs, ExtractParsed, JDDContext } from "@sealcode/jdd";
import { Component, ComponentArguments, insert_nbsp } from "@sealcode/jdd";
import { getFgColorVariable } from "src/back/colors.js";
type ExtractArray<T> = T extends Array<infer X> ? X : never;
const component_arguments = {
bleed: new ComponentArguments.Enum(["none", "bleed", "screen"]).setDefaultValue(
"none"
),
style: new ComponentArguments.Enum(["flat", "pop-out"]),
tiles: new ComponentArguments.List(
new ComponentArguments.Structured({
title: new ComponentArguments.ShortText(),
subtitle: new ComponentArguments.ShortText(),
url: new ComponentArguments.ShortText().setDefaultValue(""),
photo: new ComponentArguments.Structured({
image: new ComponentArguments.Image(),
alt: new ComponentArguments.ShortText(),
}),
shape: new ComponentArguments.Enum([
"square",
"horizontal",
"vertical",
]).setDefaultValue("square"),
background: new ComponentArguments.Enum([
"accent",
"accent2",
"text-bg",
]).setDefaultValue("accent"),
})
),
} as const;
export class DynamicGridV2 extends Component<typeof component_arguments> {
getArguments() {
return component_arguments;
}
public image_sizes = {
square: { width: 700, height: 700 },
horizontal: { width: 824, height: 400 },
vertical: { width: 400, height: 824 },
};
renderTile(
jdd_context: JDDContext,
tile: ExtractArray<ExtractParsed<typeof component_arguments.tiles>>
) {
return (
<a
href={tile.url || false}
class={["tile", tile.shape]}
style={[
`--tile-bg-color: var(--color-brand-${tile.background})`,
`--tile-fg-color: var(${getFgColorVariable("brand-" + tile.background)})`,
].join(";")}
>
<div class="tile-content">
<div class="tile-content-wrapper">
{tile.title ? (
<h3 class="tile-title">{insert_nbsp(tile.title)}</h3>
) : (
""
)}
{tile.subtitle ? (
<p class="tile-subtitle">{insert_nbsp(tile.subtitle)}</p>
) : (
""
)}
</div>
</div>
{(["square", "horizontal", "vertical"] as const).map((shape) => (
<div class={["tile-image", `tile-image--${shape}`]}>
{!tile.photo
? ""
: jdd_context.render_image(tile.photo.image, {
sizesAttr:
"(max-width: 730px) 100vw, (max-width: 980px) 50vw, 810px",
alt: tile.photo.alt,
container: {
...this.image_sizes[shape],
objectFit: "cover",
},
crop: this.image_sizes[shape],
imgStyle: "display: none;",
})}
</div>
))}
</a>
);
}
toHTML({
args: { tiles, bleed, style },
jdd_context,
classes,
index,
}: ComponentToHTMLArgs<typeof component_arguments>): FlatTemplatable {
return (
<div
class={[
"dynamic-grid",
`dynamic-grid--bleed-${bleed}`,
`dynamic-grid--style-${style}`,
...classes,
]}
style={`--jdd-index: ${index}`}
>
<div class="tiles-container">
{tiles.map((tile) => this.renderTile(jdd_context, tile))}
</div>
</div>
);
}
}

View File

@ -139,13 +139,11 @@
} }
.question { .question {
font-size: 14px;
line-height: 21px; line-height: 21px;
padding: 10px 0; padding: 10px 0;
} }
.answer p { .answer p {
font-size: 14px;
line-height: 21px; line-height: 21px;
} }

View File

@ -41,7 +41,7 @@ export class FaqComponent extends Component<typeof component_arguments> {
<div class={["faq-component", ...classes]}> <div class={["faq-component", ...classes]}>
<div class="container"> <div class="container">
<div class="title-container"> <div class="title-container">
<div class="title">{title} </div> {title ? <div class="title">{title} </div> : ""}
<div class={["content", `color-${content.color}`]}> <div class={["content", `color-${content.color}`]}>
{render_markdown(language, content.text)}{" "} {render_markdown(language, content.text)}{" "}
</div> </div>

View File

@ -1,4 +1,7 @@
.heading { .heading {
text-wrap: pretty;
text-wrap: balance;
& > * { & > * {
margin-top: 0; margin-top: 0;
margin-bottom: 0; margin-bottom: 0;
@ -10,18 +13,46 @@
&.heading--font-size-small > * { &.heading--font-size-small > * {
font-size: 24px; font-size: 24px;
@container (max-width: 600px) {
font-size: 22px;
}
} }
&.heading--font-size-medium > * { &.heading--font-size-medium > * {
font-size: 32px; font-size: 32px;
@container (max-width: 600px) {
font-size: 24px;
}
} }
&.heading--font-size-large > * { &.heading--font-size-large > * {
font-size: 48px; font-size: 48px;
@container (max-width: 600px) {
font-size: 32px;
}
} }
&.heading--font-size-extra_large > * { &.heading--font-size-extra_large > * {
font-size: 64px; font-size: 64px;
@container (max-width: 600px) {
font-size: 56px;
}
}
&.heading--align-left {
text-align: left;
}
&.heading--align-right {
text-align: right;
}
&.heading--align-center {
text-align: center;
} }
&.heading--color-normal { &.heading--color-normal {

View File

@ -18,6 +18,9 @@ const component_arguments = {
"large", "large",
"extra_large", "extra_large",
]).setDefaultValue("medium"), ]).setDefaultValue("medium"),
align: new ComponentArguments.Enum(["left", "right", "center"]).setDefaultValue(
"left"
),
color: new ComponentArguments.Enum(["normal", "accent1", "accent2"]).setDefaultValue( color: new ComponentArguments.Enum(["normal", "accent1", "accent2"]).setDefaultValue(
"normal" "normal"
), ),
@ -30,7 +33,7 @@ export class Heading extends Component<typeof component_arguments> {
} }
async toHTML({ async toHTML({
args: { title, level, font_size, color }, args: { title, level, font_size, color, align },
classes, classes,
}: ComponentToHTMLArgs<typeof component_arguments>): Promise<string> { }: ComponentToHTMLArgs<typeof component_arguments>): Promise<string> {
return ( return (
@ -39,6 +42,7 @@ export class Heading extends Component<typeof component_arguments> {
"heading", "heading",
`heading--font-size-${font_size}`, `heading--font-size-${font_size}`,
`heading--color-${color}`, `heading--color-${color}`,
`heading--align-${align}`,
...classes, ...classes,
]} ]}
> >

View File

@ -27,9 +27,9 @@
background-color: var(--tile-bg-color); background-color: var(--tile-bg-color);
display: grid; display: grid;
grid-template-rows: subgrid; grid-template-rows: subgrid;
grid-row: span 2; grid-row: span 4;
flex-flow: column; flex-flow: column;
gap: 32px; --gap: 16px;
min-height: 320px; min-height: 320px;
max-width: 400px; max-width: 400px;
text-decoration: none; /* in case it's an a href */ text-decoration: none; /* in case it's an a href */
@ -39,13 +39,8 @@
color: var(--tile-fg-color); color: var(--tile-fg-color);
} }
&:has(.icon), & > * + * {
&:has(.icon-tiles__tile__cta) { margin-top: var(--gap);
grid-row: span 3;
}
&:has(.icon):has(.icon-tiles__tile__cta) {
grid-row: span 4;
} }
svg { svg {
@ -80,7 +75,10 @@
&:hover { &:hover {
transform: scale(1.05); transform: scale(1.05);
}
&:hover,
&.icon-tiles-grid__tile--force-cta {
.icon-tiles__tile__cta { .icon-tiles__tile__cta {
text-align: right; text-align: right;
opacity: 1; opacity: 1;

View File

@ -23,6 +23,7 @@ const component_arguments = {
description: new Args.ShortText(), description: new Args.ShortText(),
url: new Args.ShortText().setExampleValues([""]), url: new Args.ShortText().setExampleValues([""]),
cta: new Args.ShortText().setExampleValues([""]), cta: new Args.ShortText().setExampleValues([""]),
always_show_cta: new Args.Boolean().setDefaultValue(false),
}) })
), ),
} as const; } as const;
@ -42,6 +43,7 @@ export class IconTilesGrid extends Component<typeof component_arguments> {
class={[ class={[
"icon-tiles-grid", "icon-tiles-grid",
{ "icon-tiles-grid--bleed": bleed }, { "icon-tiles-grid--bleed": bleed },
...classes, ...classes,
]} ]}
> >
@ -50,7 +52,13 @@ export class IconTilesGrid extends Component<typeof component_arguments> {
<section class="icon-tiles-grid__grid"> <section class="icon-tiles-grid__grid">
{tiles.map((tile) => ( {tiles.map((tile) => (
<a <a
class="icon-tiles-grid__tile" class={[
"icon-tiles-grid__tile",
{
"icon-tiles-grid__tile--force-cta":
tile.always_show_cta,
},
]}
style={`--tile-bg-color: var(${tile.color}); --tile-fg-color: var(${getFgColorVariable(tile.color, 4.2)})`} style={`--tile-bg-color: var(${tile.color}); --tile-fg-color: var(${getFgColorVariable(tile.color, 4.2)})`}
href={tile.url ? tile.url : false} href={tile.url ? tile.url : false}
> >

View File

@ -3,7 +3,7 @@
display: grid; display: grid;
grid-template-columns: subgrid; grid-template-columns: subgrid;
grid-column: screen !important; grid-column: 1/-1 !important;
.split-view__half { .split-view__half {
flex-basis: 50%; flex-basis: 50%;

View File

@ -64,7 +64,15 @@
.horizontal-scroller.has-next .next-button, .horizontal-scroller.has-next .next-button,
.horizontal-scroller.has-prev .prev-button { .horizontal-scroller.has-prev .prev-button {
display: block; display: flex;
svg {
height: 16px;
* {
fill: var(--fg-color) !important;
}
}
} }
.scroller-wrapper { .scroller-wrapper {
@ -104,7 +112,7 @@
.horizontal-scroller__element { .horizontal-scroller__element {
width: var(--horizontal-scroller-item-width) !important; width: var(--horizontal-scroller-item-width) !important;
max-width: calc(100cqw - 80px); max-width: calc(100cqw - 110px);
flex-shrink: 0; flex-shrink: 0;
container-type: inline-size; container-type: inline-size;
flex-flow: column; flex-flow: column;
@ -115,3 +123,13 @@
} }
} }
} }
.grid-layout-main > .subtree,
.subgrid-layout > .subtree {
display: grid !important;
grid-template-columns: subgrid;
& > * {
grid-column: content;
}
}

View File

@ -7,6 +7,7 @@ import type {
import { Component, ComponentArguments } from "@sealcode/jdd"; import { Component, ComponentArguments } from "@sealcode/jdd";
import { horizontalScroller } from "src/back/routes/common/horizontal-scroller/horizontal-scroller.js"; import { horizontalScroller } from "src/back/routes/common/horizontal-scroller/horizontal-scroller.js";
import { getColorVariables, getFgColorVariable } from "src/back/colors.js"; import { getColorVariables, getFgColorVariable } from "src/back/colors.js";
import { icon } from "src/back/icons.js";
const component_arguments = { const component_arguments = {
mode: new ComponentArguments.Enum(["column", "horizontal-scroller"]).setDefaultValue( mode: new ComponentArguments.Enum(["column", "horizontal-scroller"]).setDefaultValue(
@ -75,7 +76,7 @@ export class Subtree extends Component<typeof component_arguments> {
if (mode == "horizontal-scroller") { if (mode == "horizontal-scroller") {
const button_styles = [ const button_styles = [
`background-color: var(${scroller_mode_arrows_color})`, `background-color: var(${scroller_mode_arrows_color})`,
`color: var(${getFgColorVariable(scroller_mode_arrows_color)})`, `--fg-color: var(${getFgColorVariable(scroller_mode_arrows_color)})`,
].join(";"); ].join(";");
return ( return (
<div <div
@ -92,7 +93,7 @@ export class Subtree extends Component<typeof component_arguments> {
data-action="horizontal-scroller#scrollLeft" data-action="horizontal-scroller#scrollLeft"
style={button_styles} style={button_styles}
> >
← {icon("arrow-left")}
</button> </button>
</div> </div>
<div class="button-panel button-panel--right"> <div class="button-panel button-panel--right">
@ -102,7 +103,7 @@ export class Subtree extends Component<typeof component_arguments> {
data-action="horizontal-scroller#scrollRight" data-action="horizontal-scroller#scrollRight"
style={button_styles} style={button_styles}
> >
→ {icon("arrow-right")}
</button> </button>
</div> </div>
{scroller} {scroller}

View File

@ -11,6 +11,14 @@
font-size: 20px; font-size: 20px;
} }
&.tekst--bleed-none {
grid-column: content !important;
}
&.tekst--bleed-bleed {
grid-column: bleed !important;
}
p { p {
margin: 0; margin: 0;
text-align: justify; text-align: justify;

View File

@ -17,6 +17,7 @@ const component_arguments = {
size: new ComponentArguments.Enum(["small", "normal", "large"]).setDefaultValue( size: new ComponentArguments.Enum(["small", "normal", "large"]).setDefaultValue(
"normal" "normal"
), ),
bleed: new ComponentArguments.Enum(["none", "bleed"]).setDefaultValue("none"),
content: new ComponentArguments.Markdown(), content: new ComponentArguments.Markdown(),
side_content: new ComponentArguments.NestedComponent(), side_content: new ComponentArguments.NestedComponent(),
} as const; } as const;
@ -42,7 +43,7 @@ export class Tekst extends Component<typeof component_arguments> {
} }
toHTML({ toHTML({
args: { color, content, side_content, size }, args: { color, content, side_content, size, bleed },
classes, classes,
jdd_context, jdd_context,
index, index,
@ -55,6 +56,7 @@ export class Tekst extends Component<typeof component_arguments> {
...classes, ...classes,
`tekst--color-${color}`, `tekst--color-${color}`,
`tekst--size-${size}`, `tekst--size-${size}`,
`tekst--bleed-${bleed}`,
]} ]}
style={`--jdd-index: ${index}`} style={`--jdd-index: ${index}`}
> >

View File

@ -51,11 +51,15 @@ footer {
.footer__social_media_icons { .footer__social_media_icons {
display: flex; display: flex;
flex-flow: row wrap; flex-flow: row wrap;
flex-wrap: row balance;
flex-grow: 1; flex-grow: 1;
justify-content: space-between; justify-content: space-between;
row-gap: 16px;
column-gap: 8px;
a { a {
padding: 2px 8px; padding: 2px 8px;
display: inline-flex;
svg { svg {
width: 24px; width: 24px;
@ -66,6 +70,18 @@ footer {
} }
} }
} }
@media (max-width: 800px) {
display: block;
text-align: center;
text-wrap: balance;
line-height: 40px;
& > a {
display: inline;
text-decoration: none;
}
}
} }
.footer__attribution { .footer__attribution {

View File

@ -5,6 +5,7 @@ import { TempstreamJSX } from "tempstream";
const icons = [ const icons = [
{ name: "mastodon", url: "https://mastodon.strona-czynna.pl/@czynna" }, { name: "mastodon", url: "https://mastodon.strona-czynna.pl/@czynna" },
{ name: "mobilizon", url: "https://wydarzenia.strona-czynna.pl/" },
{ name: "peertube", url: "https://video.strona-czynna.pl/" }, { name: "peertube", url: "https://video.strona-czynna.pl/" },
{ name: "matrix", url: "https://matrix.to/#/#strona-czynna:matriks.chat" }, { name: "matrix", url: "https://matrix.to/#/#strona-czynna:matriks.chat" },
{ name: "telegram", url: "https://t.me/+JQl6ryW3_Ho5MDY0" }, { name: "telegram", url: "https://t.me/+JQl6ryW3_Ho5MDY0" },
@ -14,7 +15,7 @@ const icons = [
{ name: "tiktok", url: "https://www.tiktok.com/@stronaczynna" }, { name: "tiktok", url: "https://www.tiktok.com/@stronaczynna" },
{ name: "facebook", url: "https://www.facebook.com/czynna.strona" }, { name: "facebook", url: "https://www.facebook.com/czynna.strona" },
{ name: "linkedin", url: "https://www.linkedin.com/company/strona-czynna/" }, { name: "linkedin", url: "https://www.linkedin.com/company/strona-czynna/" },
{ name: "zrzutka", url: "https://zrzutka.pl/z/strona-czynna" }, { name: "zrzutka", url: "https://zrzutka.pl/z/strona_czynna" },
]; ];
export default async function footer(ctx: Context) { export default async function footer(ctx: Context) {

View File

@ -78,6 +78,16 @@ export default class HorizontalScroller extends Controller {
while (visibility[current_index] == 1 && current_index < visibility.length) { while (visibility[current_index] == 1 && current_index < visibility.length) {
current_index++; current_index++;
} }
if (current_index >= this.visibility.length) {
// edge-case. Content must be wider than the viewing window for some reason and none of the items reach 100% visibility. Returning the index of the first zero-visible element that follows a visible element;
for (let i = visibility.length - 1; i > 0; i--) {
if (visibility[i] === 0 && visibility[i - 1] > 0) {
return i;
}
}
return -1;
}
return current_index; return current_index;
} }

View File

@ -7,6 +7,7 @@ nav {
display: flex; display: flex;
flex-flow: row wrap; flex-flow: row wrap;
justify-content: space-between; justify-content: space-between;
margin-top: 24px;
ul.desktop-menu { ul.desktop-menu {
display: flex; display: flex;

1
src/icons/arrow-down.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 8.467 8.467"><path d="m.219 4.36.897-.902L2.6 4.937q.182.188.37.387.195.205.383.416l.382.415.365.399-.454.11-.033-.52-.022-.57q-.011-.294-.011-.57V.09h1.307v4.912q0 .277-.011.57-.011.294-.028.57-.011.278-.028.521l-.465-.11q.244-.26.493-.538l.51-.553q.254-.272.503-.526l1.484-1.484.903.908-4.015 4.014Z" aria-label="→" style="font-weight:700;font-size:9.06352px;line-height:1.2;font-family:&quot;Adwaita Sans&quot;;-inkscape-font-specification:&quot;Adwaita Sans&quot;;font-variant-numeric:oldstyle-nums tabular-nums;text-align:end;white-space:pre;stroke-width:4.62721;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:50.8993;paint-order:stroke fill markers"/></svg>

After

Width:  |  Height:  |  Size: 754 B

1
src/icons/arrow-left.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 8.467 8.467"><path d="m4.106 8.248.903-.897L3.53 5.867q-.188-.183-.388-.371-.204-.194-.415-.382l-.415-.382-.399-.366-.11.454q.243.017.52.034l.57.022q.294.01.57.01h4.912V3.58H3.464q-.277 0-.57.011-.294.011-.571.028-.277.01-.52.027l.11.466q.26-.244.537-.493l.554-.51q.271-.255.526-.504l1.484-1.484L4.106.22.091 4.233Z" aria-label="→" style="font-weight:700;font-size:9.06352px;line-height:1.2;font-family:&quot;Adwaita Sans&quot;;-inkscape-font-specification:&quot;Adwaita Sans&quot;;font-variant-numeric:oldstyle-nums tabular-nums;text-align:end;white-space:pre;stroke-width:4.62721;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:50.8993;paint-order:stroke fill markers"/></svg>

After

Width:  |  Height:  |  Size: 768 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 8.467 8.467"><path d="m4.36 8.248-.902-.897 1.479-1.484q.188-.183.387-.371.205-.194.416-.382l.415-.382.399-.366.11.454q-.243.017-.52.034l-.57.022q-.294.01-.57.01H.09V3.58h4.912q.277 0 .57.011.294.011.57.028.278.01.521.027l-.11.466q-.26-.244-.538-.493l-.553-.51q-.272-.255-.526-.504L3.453 1.121 4.36.22l4.014 4.014Z" aria-label="→" style="font-weight:700;font-size:9.06352px;line-height:1.2;font-family:&quot;Adwaita Sans&quot;;-inkscape-font-specification:&quot;Adwaita Sans&quot;;font-variant-numeric:oldstyle-nums tabular-nums;text-align:end;white-space:pre;stroke-width:4.62721;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:50.8993;paint-order:stroke fill markers"/></svg>

After

Width:  |  Height:  |  Size: 767 B

1
src/icons/arrow-up.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 8.467 8.467"><path d="m.219 4.106.897.903L2.6 3.53q.182-.188.37-.388.195-.204.383-.415l.382-.415.365-.399-.454-.11-.033.52-.022.57q-.011.294-.011.57v4.912h1.307V3.464q0-.277-.011-.57-.011-.294-.028-.571-.011-.277-.028-.52l-.465.11q.244.26.493.537l.51.554q.254.271.503.526l1.484 1.484.903-.908L4.233.091Z" aria-label="→" style="font-weight:700;font-size:9.06352px;line-height:1.2;font-family:&quot;Adwaita Sans&quot;;-inkscape-font-specification:&quot;Adwaita Sans&quot;;font-variant-numeric:oldstyle-nums tabular-nums;text-align:end;white-space:pre;stroke-width:4.62721;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:50.8993;paint-order:stroke fill markers"/></svg>

After

Width:  |  Height:  |  Size: 756 B

View File

@ -1,41 +1 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" class="bi bi-copy" viewBox="0 0 32 32"><path fill-rule="evenodd" d="M8 4a4 4 0 0 1 4-4h16a4 4 0 0 1 4 4v16a4 4 0 0 1-4 4H12a4 4 0 0 1-4-4Zm4-2a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2Zm-8 8a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2h2v2a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V12a4 4 0 0 1 4-4h2v2z" style="stroke-width:1.99999"/></svg>
<svg
width="32"
height="32"
fill="currentColor"
class="bi bi-copy"
viewBox="0 0 32 32"
version="1.1"
id="svg1"
sodipodi:docname="copy.svg"
inkscape:version="1.4.4 (dcaf3e7d9e, 2026-05-05)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="17.699693"
inkscape:cx="13.361814"
inkscape:cy="13.983294"
inkscape:window-width="1920"
inkscape:window-height="1048"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
fill-rule="evenodd"
d="m 8,4 a 4,4 0 0 1 4,-4 h 16 a 4,4 0 0 1 4,4 v 16 a 4,4 0 0 1 -4,4 H 12 A 4,4 0 0 1 8,20 Z m 4,-2 a 2,2 0 0 0 -2,2 v 16 a 2,2 0 0 0 2,2 h 16 a 2,2 0 0 0 2,-2 V 4 A 2,2 0 0 0 28,2 Z m -8,8 a 2,2 0 0 0 -2,2 v 16 a 2,2 0 0 0 2,2 h 16 a 2,2 0 0 0 2,-2 v -2 h 2 v 2 a 4,4 0 0 1 -4,4 H 4 A 4,4 0 0 1 0,28 V 12 A 4,4 0 0 1 4,8 h 2 v 2 z"
id="path1"
style="stroke-width:1.99999" />
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 440 B

View File

@ -1,67 +1 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path d="m8.894 6.765 16.341 16.341-2.129 2.13L6.765 8.893z"/><path d="M25.236 8.894 8.895 25.235l-2.13-2.129L23.108 6.765z"/></svg>
<svg
id="icon"
width="32"
height="32"
viewBox="0 0 32 32"
version="1.1"
sodipodi:docname="hamburger-close.svg"
inkscape:version="1.4.4 (dcaf3e7d9e, 2026-05-05)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="7.6390567"
inkscape:cx="9.6870599"
inkscape:cy="26.377602"
inkscape:window-width="1536"
inkscape:window-height="832"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="g2" />
<defs
id="defs1">
<style
id="style1">
.cls-1 {
fill: none;
}
</style>
</defs>
<g
id="g1"
transform="translate(-0.33652353,-1.2228587)">
<g
id="g2"
transform="translate(0,1.89814)">
<rect
id="rect1"
width="23.110205"
height="3.0114162"
x="10.832777"
y="-2.2211621"
inkscape:transform-center-x="-8.1456912"
transform="rotate(45)"
inkscape:transform-center-y="8.1456912" />
<rect
id="use2"
width="23.110205"
height="3.0114162"
x="-12.270555"
y="-23.893587"
inkscape:transform-center-x="-7.9605633"
transform="rotate(135)"
inkscape:transform-center-y="-7.960561" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 215 B

View File

@ -1,69 +1 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32" viewBox="0 0 32 32"><g transform="translate(-.337 .675)"><path id="a" d="M4.781 8.049h23.11v3.011H4.781z"/><use xlink:href="#a" id="b" x="0" y="0" transform="translate(0 5.77)"/><use xlink:href="#b" transform="translate(0 5.77)"/></g></svg>
<svg
id="icon"
width="32"
height="32"
viewBox="0 0 32 32"
version="1.1"
sodipodi:docname="hamburger.svg"
inkscape:version="1.4.4 (dcaf3e7d9e, 2026-05-05)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="7.6390567"
inkscape:cx="9.6870599"
inkscape:cy="26.377602"
inkscape:window-width="1536"
inkscape:window-height="832"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="g1" />
<defs
id="defs1">
<style
id="style1">
.cls-1 {
fill: none;
}
</style>
</defs>
<g
id="g1"
transform="translate(-0.33652353,-1.2228587)">
<g
id="g2"
transform="translate(0,1.89814)">
<rect
style=""
id="rect1"
width="23.110205"
height="3.0114162"
x="4.7814212"
y="8.0485344" />
<use
x="0"
y="0"
xlink:href="#rect1"
id="use1"
transform="translate(0,5.7704762)" />
<use
x="0"
y="0"
xlink:href="#use1"
id="use2"
transform="translate(0,5.7704762)" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 346 B

View File

@ -1,11 +1 @@
<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path fill="__color" d="M29.058 11.193c0-6.074-3.98-7.855-3.98-7.855C23.072 2.417 19.626 2.03 16.047 2h-.088c-3.58.03-7.023.417-9.03 1.338 0 0-3.98 1.78-3.98 7.855 0 1.391-.027 3.054.017 4.817.145 5.94 1.09 11.795 6.581 13.248 2.532.67 4.707.81 6.458.715 3.175-.176 4.958-1.133 4.958-1.133l-.105-2.304s-2.27.715-4.818.628c-2.525-.087-5.19-.272-5.598-3.372a6 6 0 0 1-.057-.87s2.479.607 5.62.75c1.92.088 3.722-.112 5.551-.33 3.508-.42 6.563-2.581 6.947-4.556.605-3.112.555-7.593.555-7.593m-4.694 7.826H21.45V11.88c0-1.505-.633-2.268-1.9-2.268-1.4 0-2.102.906-2.102 2.697v3.908h-2.896v-3.908c0-1.791-.702-2.697-2.102-2.697-1.267 0-1.9.763-1.9 2.268v7.139H7.636v-7.355q0-2.255 1.152-3.581c.792-.884 1.83-1.337 3.12-1.337 1.49 0 2.62.573 3.366 1.72L16 9.681l.726-1.217c.746-1.146 1.876-1.719 3.367-1.719 1.288 0 2.326.453 3.12 1.337q1.151 1.325 1.15 3.581z"/></svg>
<svg id="icon" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<defs>
<style>
.cls-1 {
fill: none;
}
</style>
</defs>
<path d="m29.0581,11.1929c0-6.0742-3.9797-7.8545-3.9797-7.8545-2.0066-.9214-5.4522-1.3091-9.0318-1.3384h-.0879c-3.5798.0293-7.023.417-9.0296,1.3384,0,0-3.98,1.7803-3.98,7.8545,0,1.3911-.0271,3.0537.0171,4.8174.1445,5.9404,1.0889,11.7945,6.5811,13.2481,2.5322.6704,4.7063.8105,6.4573.7144,3.1755-.1758,4.958-1.1333,4.958-1.1333l-.1047-2.3037s-2.269.7153-4.8176.6284c-2.5249-.0869-5.1902-.2725-5.5986-3.3726-.0378-.272-.0566-.563-.0566-.8691,0,0,2.4785.606,5.6196.75,1.9207.0879,3.7219-.1128,5.5515-.3311,3.5083-.4189,6.563-2.5806,6.9468-4.5557.605-3.1113.5552-7.5928.5552-7.5928Zm-4.6943,7.8257h-2.9138v-7.1382c0-1.5049-.6331-2.2686-1.8997-2.2686-1.4002,0-2.1018.9058-2.1018,2.6973v3.9077h-2.8967v-3.9077c0-1.7915-.7019-2.6973-2.1021-2.6973-1.2666,0-1.8997.7637-1.8997,2.2686v7.1382h-2.9138v-7.3545c0-1.5029.3828-2.6978,1.1516-3.5811.7927-.8838,1.8308-1.3369,3.1196-1.3369,1.491,0,2.6204.5732,3.367,1.7192l.7256,1.2168.7261-1.2168c.7463-1.146,1.8755-1.7192,3.3667-1.7192,1.2886,0,2.3267.4531,3.1196,1.3369.7686.8833,1.1514,2.0781,1.1514,3.5811v7.3545Z" fill="__color"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 943 B

View File

@ -1,28 +1 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <svg width="32" height="32" viewBox="0 0 32 32"><title>Matrix (protocol) logo</title><g fill="#040404"><path d="M29.082 31.236V.736h-2.19V.004h3.04v32h-3.04v-.732zM10.212 10.436v1.54h.044a4.5 4.5 0 0 1 1.49-1.37c.58-.323 1.25-.485 1.99-.485.72 0 1.38.14 1.97.42q.894.418 1.36 1.48.505-.75 1.38-1.32c.58-.383 1.27-.574 2.06-.574q.904 0 1.67.22.771.221 1.32.707.55.484.859 1.27.308.781.308 1.89v7.63h-3.13v-6.46q0-.575-.044-1.08a2.3 2.3 0 0 0-.242-.882 1.47 1.47 0 0 0-.584-.596q-.385-.22-1.05-.22-.66 0-1.07.253-.408.255-.639.662a2.7 2.7 0 0 0-.308.927 7 7 0 0 0-.078 1.05v6.35h-3.13v-6.4q0-.508-.021-1a2.8 2.8 0 0 0-.188-.916 1.4 1.4 0 0 0-.55-.673q-.386-.252-1.14-.253a2.3 2.3 0 0 0-.584.1 1.95 1.95 0 0 0-.705.374q-.341.276-.584.794t-.242 1.36v6.62h-3.13v-11.4zM2.918.768v30.5h2.19V32h-3.04V0h3.03v.732z"/></g></svg>
<svg
version="1.1"
viewBox="0 0 32 32"
id="svg3"
width="32"
height="32"
>
<defs
id="defs3" />
<title
id="title1">Matrix (protocol) logo</title>
<g
transform="translate(1.982,0.036)"
fill="#040404"
id="g3">
<path
d="M 27.1,31.2 V 0.7 h -2.19 v -0.732 h 3.04 v 32 h -3.04 v -0.732 z"
id="path1" />
<path
d="m 8.23,10.4 v 1.54 h 0.044 c 0.385,-0.564 0.893,-1.03 1.49,-1.37 0.58,-0.323 1.25,-0.485 1.99,-0.485 0.72,0 1.38,0.14 1.97,0.42 0.595,0.279 1.05,0.771 1.36,1.48 0.338,-0.5 0.796,-0.941 1.38,-1.32 0.58,-0.383 1.27,-0.574 2.06,-0.574 0.602,0 1.16,0.074 1.67,0.22 0.514,0.148 0.954,0.383 1.32,0.707 0.366,0.323 0.653,0.746 0.859,1.27 0.205,0.522 0.308,1.15 0.308,1.89 v 7.63 h -3.13 v -6.46 c 0,-0.383 -0.015,-0.743 -0.044,-1.08 -0.0209,-0.307 -0.103,-0.607 -0.242,-0.882 -0.133,-0.251 -0.336,-0.458 -0.584,-0.596 -0.257,-0.146 -0.606,-0.22 -1.05,-0.22 -0.44,0 -0.796,0.085 -1.07,0.253 -0.272,0.17 -0.485,0.39 -0.639,0.662 -0.159,0.287 -0.264,0.602 -0.308,0.927 -0.052,0.347 -0.078,0.697 -0.078,1.05 v 6.35 h -3.13 v -6.4 c 0,-0.338 -0.007,-0.673 -0.021,-1 -0.0114,-0.314 -0.0749,-0.623 -0.188,-0.916 -0.108,-0.277 -0.3,-0.512 -0.55,-0.673 -0.258,-0.168 -0.636,-0.253 -1.14,-0.253 -0.198,0.0083 -0.394,0.042 -0.584,0.1 -0.258,0.0745 -0.498,0.202 -0.705,0.374 -0.228,0.184 -0.422,0.449 -0.584,0.794 -0.161,0.346 -0.242,0.798 -0.242,1.36 v 6.62 h -3.13 v -11.4 z"
id="path2" />
<path
d="m 0.936,0.732 v 30.5 h 2.19 v 0.732 h -3.04 v -32 h 3.03 v 0.732 z"
id="path3" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 818 B

1
src/icons/mobilizon.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 8.467 8.467"><path d="M3.082.76s.362-.129.584-.122.493.052.571.12c.078.067.115.37.115.484s-.037.417-.09.458c-.055.041-.346.139-.548.139s-.574-.08-.634-.143-.085-.372-.09-.446c-.003-.073.018-.44.092-.49m.685 1.621-.06.007zm-.06.007c-.025.003-.05.005-.117.007-.456.011-1.852.212-1.98 2.224-.032.482.048 1.45.539 2.03.49.58 1.238.712 1.915.624.676-.089 1.079-.58 1.34-.933.26-.354.35-.969.323-1.809a2.37 2.37 0 0 0-.752-1.663c-.3-.292-.854-.473-1.354-.47Zm-.046.902c.531.005.72.46.731.49.01.031.179.476.163 1.253s-.27 1.386-.848 1.391-.941-.46-.926-1.605c.016-1.145.374-1.498.88-1.529" style="fill:#000;fill-opacity:1;stroke-width:6.90901;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:75.9989;paint-order:stroke fill markers" transform="translate(-.307 -.68)scale(1.23817)"/></svg>

After

Width:  |  Height:  |  Size: 868 B

View File

@ -1,41 +1 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="none" viewBox="0 0 0.96 0.96"><path d="M.41.016a.18.18 0 0 0-.15.072A.2.2 0 0 0 .225.2v.465c0 .102.032.176.084.22a.26.26 0 0 0 .171.06C.537.945.601.93.652.885.704.843.736.769.736.667V.189A.046.046 0 0 0 .69.143a.046.046 0 0 0-.046.046v.477C.643.75.619.791.59.816a.16.16 0 0 1-.11.036.17.17 0 0 1-.11-.036C.34.791.315.75.315.666V.201c0-.015.007-.042.02-.06C.349.122.364.107.41.107s.064.015.076.034A.1.1 0 0 1 .504.2v.48Q.503.7.496.706C.493.71.491.713.48.713Q.466.712.463.705.457.7.457.682v-.48A.046.046 0 0 0 .41.153a.046.046 0 0 0-.047.047v.48Q.362.727.391.765c.02.024.054.04.09.04a.11.11 0 0 0 .087-.04.13.13 0 0 0 .028-.082v-.48A.2.2 0 0 0 .563.087.18.18 0 0 0 .41.016" style="baseline-shift:baseline;display:inline;overflow:visible;vector-effect:none;fill:#000;stroke-linecap:round;stroke-linejoin:round;stop-color:#000;stop-opacity:1;opacity:1;fill-opacity:1"/></svg>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg
width="32"
height="32"
viewBox="0 0 0.96 0.96"
fill="none"
version="1.1"
id="svg1"
sodipodi:docname="paperclip-svgrepo-com.svg"
inkscape:version="1.4.4 (dcaf3e7d9e, 2026-05-05)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="9.9699453"
inkscape:cx="31.243903"
inkscape:cy="27.933955"
inkscape:window-width="1920"
inkscape:window-height="1048"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
style="baseline-shift:baseline;display:inline;overflow:visible;vector-effect:none;fill:#000000;stroke-linecap:round;stroke-linejoin:round;enable-background:accumulate;stop-color:#000000;stop-opacity:1;opacity:1;fill-opacity:1"
d="m 0.41015625,0.015625 c -0.0704926,0 -0.12242427,0.03231334 -0.15039062,0.07226562 -0.0279664,0.03995229 -0.0351563,0.08229695 -0.0351563,0.11328126 v 0.46484374 c -10e-9,0.10225154 0.0326564,0.17606761 0.0839844,0.22070313 0.051328,0.0446355 0.11568679,0.0585938 0.171875,0.0585938 0.0561877,0 0.12054699,-0.0139582 0.171875,-0.0585938 0.051328,-0.0446356 0.0839844,-0.11845228 0.0839844,-0.22070313 v -0.4765625 a 0.04647825,0.04647825 0 0 0 -0.046875,-0.046875 0.04647825,0.04647825 0 0 0 -0.046875,0.046875 v 0.4765625 c 0,0.0836627 -0.0238919,0.12530886 -0.0527344,0.15039063 -0.0288424,0.0250818 -0.0679394,0.0351563 -0.109375,0.0351563 -0.0414371,0 -0.0824862,-0.0100749 -0.11132812,-0.0351563 -0.0288419,-0.0250813 -0.0527344,-0.0667267 -0.0527344,-0.15039063 V 0.20117188 c 0,-0.0154916 0.006829,-0.0424013 0.0195313,-0.0605469 0.0127018,-0.0181456 0.0285146,-0.0332031 0.0742188,-0.0332031 0.0457043,0 0.0634701,0.0150584 0.0761719,0.0332031 0.0127017,0.0181447 0.0175781,0.045052 0.0175781,0.0605469 v 0.48046874 c 0,0.0108974 -0.004264,0.0190517 -0.007813,0.0234375 -0.003548,0.004386 -0.004893,0.007813 -0.015625,0.007813 -0.0107348,0 -0.0140316,-0.003429 -0.0175781,-0.007813 -0.003547,-0.004383 -0.005859,-0.0125329 -0.005859,-0.0234375 V 0.20117188 a 0.04647825,0.04647825 0 0 0 -0.046875,-0.046875 0.04647825,0.04647825 0 0 0 -0.046875,0.046875 v 0.48046874 c 0,0.0289647 0.007652,0.0576935 0.0273438,0.0820313 0.0196914,0.0243377 0.0541027,0.0410156 0.0898438,0.0410156 0.0357444,0 0.0682009,-0.0166778 0.0878906,-0.0410156 0.0196898,-0.0243378 0.0273438,-0.0530694 0.0273438,-0.0820313 V 0.20117188 c 0,-0.030987 -0.005236,-0.0733296 -0.0332031,-0.11328126 C 0.53453283,0.04793895 0.48064766,0.015625 0.41015625,0.015625 Z"
id="path1" />
</svg>

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 940 B

View File

@ -1,16 +1 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <svg width="32" height="32" viewBox="0 0 0.96 0.96"><path d="M.179.028v.458l.343-.23Zm0 .458v.458L.522.715Zm.343-.23v.459L.866.486Z" style="stroke-width:.0381701"/></svg>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg
fill="#000000"
width="32"
height="32"
viewBox="0 0 0.96 0.96"
role="img"
version="1.1"
>
<path
d="M 0.17882848,0.02791469 V 0.48595566 L 0.5223592,0.25693517 Z m 0,0.45804097 V 0.94399661 L 0.5223592,0.71497613 Z M 0.5223592,0.25693517 V 0.71497613 L 0.86588992,0.48595566 Z"
id="path1"
style="stroke-width:0.0381701" />
</svg>

Before

Width:  |  Height:  |  Size: 505 B

After

Width:  |  Height:  |  Size: 170 B