Monorepo for Tangled
0

Configure Feed

Select the types of activity you want to include in your feed.

web/ui: add type tokens & improve Typography.svelte

Signed-off-by: eti <eti@eti.tf>

eti (Jul 15, 2026, 6:22 PM +0200) da1bd235 e089a0c5

+117 -36
+32
web/src/app.css
··· 12 12 here; dark-mode overrides live in the prefers-color-scheme block below. 13 13 ========================================================================= */ 14 14 15 + /* --- typography — synced from Figma "Font Styles" (node 1:186) --- */ 16 + --text-heading-0: 5rem; 17 + --text-heading-0--line-height: 5rem; 18 + --text-heading-0--font-weight: 600; 19 + --text-heading-0--letter-spacing: -0.25px; 20 + --text-heading-1: 3rem; 21 + --text-heading-1--line-height: 3.5rem; 22 + --text-heading-1--font-weight: 500; 23 + --text-heading-2: 1.875rem; 24 + --text-heading-2--line-height: 1.875rem; 25 + --text-heading-2--font-weight: 600; 26 + --text-heading-3: 1.5rem; 27 + --text-heading-3--line-height: 1.875rem; 28 + --text-heading-3--font-weight: 500; 29 + --text-heading-4: 1.25rem; 30 + --text-heading-4--line-height: 1.75rem; 31 + --text-heading-4--font-weight: 500; 32 + --text-paragraph-large: 1rem; 33 + --text-paragraph-large--line-height: 1.6875rem; 34 + --text-paragraph-regular: 0.875rem; 35 + --text-paragraph-regular--line-height: 1.5rem; 36 + --text-paragraph-small: 0.75rem; 37 + --text-paragraph-small--line-height: 1.25rem; 38 + --text-paragraph-mini: 0.625rem; 39 + --text-paragraph-mini--line-height: 1rem; 40 + --text-monospace-large: 1rem; 41 + --text-monospace-large--line-height: 1.5rem; 42 + --text-monospace-regular: 0.875rem; 43 + --text-monospace-regular--line-height: 1.375rem; 44 + --text-monospace-small: 0.75rem; 45 + --text-monospace-small--line-height: 1.25rem; 46 + 15 47 /* --- background --- */ 16 48 --color-background-default: #ffffff; 17 49 --color-background-subtle: #f9fafb;
+50 -15
web/src/lib/components/ui/Typography.stories.svelte
··· 9 9 argTypes: { 10 10 variant: { 11 11 control: { type: "select" }, 12 - options: ["h1", "h2", "h3", "h4", "body", "body-strong", "small", "caption", "mono"] 12 + options: [ 13 + "h0", 14 + "h1", 15 + "h2", 16 + "h3", 17 + "h4", 18 + "large", 19 + "regular", 20 + "small", 21 + "mini", 22 + "mono-large", 23 + "mono", 24 + "mono-small" 25 + ] 26 + }, 27 + weight: { 28 + control: { type: "select" }, 29 + options: ["regular", "semibold", "bold"] 13 30 }, 14 31 as: { control: "text" } 15 32 }, 16 33 args: { 17 - variant: "body" 34 + variant: "regular", 35 + weight: "regular" 18 36 } 19 37 }); 38 + 39 + const paragraphSizes = ["large", "regular", "small", "mini"] as const; 40 + const weights = ["regular", "semibold", "bold"] as const; 20 41 </script> 21 42 22 43 <!-- Typography content comes through its `children` snippet, provided here as Story slot content. --> 44 + <Story name="H0" args={{ variant: "h0" }}>Design that ships</Story> 23 45 <Story name="H1" args={{ variant: "h1" }}>Design that ships</Story> 24 46 <Story name="H2" args={{ variant: "h2" }}>Design that ships</Story> 25 47 <Story name="H3" args={{ variant: "h3" }}>Design that ships</Story> 26 48 <Story name="H4" args={{ variant: "h4" }}>Design that ships</Story> 27 - <Story name="Body" args={{ variant: "body" }}> 49 + <Story name="Paragraph" args={{ variant: "regular" }}> 28 50 Tangled is a social-enabled, decentralized code collaboration platform built on the AT Protocol. 29 51 </Story> 30 - <Story name="BodyStrong" args={{ variant: "body-strong" }}> 52 + <Story name="ParagraphBold" args={{ variant: "regular", weight: "bold" }}> 31 53 Tangled is a social-enabled, decentralized code collaboration platform. 32 54 </Story> 33 55 <Story name="Small" args={{ variant: "small" }}>Last updated 2 hours ago.</Story> 34 - <Story name="Caption" args={{ variant: "caption" }}>Caption text for supporting detail.</Story> 56 + <Story name="Mini" args={{ variant: "mini" }}>Mini text for supporting detail.</Story> 35 57 <Story name="Mono" args={{ variant: "mono" }}>const tangled = true;</Story> 36 58 <Story name="CustomTag" args={{ variant: "h2", as: "div" }}> 37 59 Renders as a div while keeping h2 styling 38 60 </Story> 39 61 62 + <!-- Mirrors the Figma "Font Styles" specimen (node 1:186). --> 40 63 <Story name="Scale"> 41 - <div class="flex flex-col gap-3"> 42 - <Typography variant="h1">Heading 1</Typography> 43 - <Typography variant="h2">Heading 2</Typography> 44 - <Typography variant="h3">Heading 3</Typography> 45 - <Typography variant="h4">Heading 4</Typography> 46 - <Typography variant="body">Body paragraph text.</Typography> 47 - <Typography variant="body-strong">Body strong paragraph text.</Typography> 48 - <Typography variant="small">Small supporting text.</Typography> 49 - <Typography variant="caption">Caption text.</Typography> 50 - <Typography variant="mono">const scale = "type";</Typography> 64 + <div class="flex flex-col gap-12"> 65 + <div class="flex flex-col gap-3"> 66 + <Typography variant="h0">Heading 0</Typography> 67 + <Typography variant="h1">Heading 1</Typography> 68 + <Typography variant="h2">Heading 2</Typography> 69 + <Typography variant="h3">Heading 3</Typography> 70 + <Typography variant="h4">Heading 4</Typography> 71 + </div> 72 + <div class="flex flex-col gap-3"> 73 + {#each paragraphSizes as size (size)} 74 + {#each weights as weight (weight)} 75 + <Typography variant={size} {weight}> 76 + Paragraph {size} / {weight} 77 + </Typography> 78 + {/each} 79 + {/each} 80 + </div> 81 + <div class="flex flex-col gap-3"> 82 + <Typography variant="mono-large">Monospace Large</Typography> 83 + <Typography variant="mono">Monospace Regular</Typography> 84 + <Typography variant="mono-small">Monospace Small</Typography> 85 + </div> 51 86 </div> 52 87 </Story>
+35 -21
web/src/lib/components/ui/Typography.svelte
··· 2 2 import { tv, type VariantProps } from "tailwind-variants"; 3 3 import type { SvelteHTMLElements } from "svelte/elements"; 4 4 5 - // Scale sourced from Figma "Font Styles" (node 1:134): Heading 1-4 map to 6 - // h1-h4, the "Paragraph Regular" size maps to body/body-strong (weight 7 - // axis only), "Paragraph Small"/"Paragraph Mini" map to small/caption, and 8 - // the monospace specimen maps to mono. 9 5 export const typography = tv({ 10 6 base: "font-sans text-foreground-default", 11 7 variants: { 12 8 variant: { 13 - h1: "text-2xl font-bold leading-tight", 14 - h2: "text-xl font-bold leading-tight", 15 - h3: "text-lg font-semibold leading-snug", 16 - h4: "text-base font-semibold leading-snug", 17 - body: "text-base font-normal leading-normal", 18 - "body-strong": "text-base font-semibold leading-normal", 19 - small: "text-sm font-normal leading-normal text-foreground-muted", 20 - caption: "text-xs font-normal leading-normal text-foreground-subtle", 21 - mono: "font-mono text-sm font-normal leading-normal" 9 + h0: "text-heading-0", 10 + h1: "text-heading-1", 11 + h2: "text-heading-2", 12 + h3: "text-heading-3", 13 + h4: "text-heading-4", 14 + large: "text-paragraph-large", 15 + regular: "text-paragraph-regular", 16 + small: "text-paragraph-small", 17 + mini: "text-paragraph-mini", 18 + "mono-large": "font-mono text-monospace-large font-normal", 19 + mono: "font-mono text-monospace-regular font-normal", 20 + "mono-small": "font-mono text-monospace-small font-normal" 21 + }, 22 + weight: { 23 + regular: "", 24 + semibold: "", 25 + bold: "" 22 26 } 23 27 }, 28 + compoundVariants: (["large", "regular", "small", "mini"] as const).flatMap((variant) => [ 29 + { variant, weight: "regular" as const, class: "font-normal" }, 30 + { variant, weight: "semibold" as const, class: "font-medium" }, 31 + { variant, weight: "bold" as const, class: "font-semibold" } 32 + ]), 24 33 defaultVariants: { 25 - variant: "body" 34 + variant: "regular", 35 + weight: "regular" 26 36 } 27 37 }); 28 38 29 39 export type TypographyVariants = VariantProps<typeof typography>; 30 40 31 41 const defaultTag = { 42 + h0: "h1", 32 43 h1: "h1", 33 44 h2: "h2", 34 45 h3: "h3", 35 46 h4: "h4", 36 - body: "p", 37 - "body-strong": "p", 47 + large: "p", 48 + regular: "p", 38 49 small: "span", 39 - caption: "span", 40 - mono: "code" 50 + mini: "span", 51 + "mono-large": "code", 52 + mono: "code", 53 + "mono-small": "code" 41 54 } as const satisfies Record<NonNullable<TypographyVariants["variant"]>, keyof SvelteHTMLElements>; 42 55 </script> 43 56 ··· 46 59 47 60 interface Props { 48 61 variant?: TypographyVariants["variant"]; 62 + weight?: TypographyVariants["weight"]; 49 63 as?: keyof SvelteHTMLElements; 50 64 class?: string; 51 65 children: Snippet; 52 66 } 53 67 54 - let { variant = "body", as, class: className, children }: Props = $props(); 68 + let { variant = "regular", weight = "regular", as, class: className, children }: Props = $props(); 55 69 56 - const tag = $derived(as ?? defaultTag[variant ?? "body"]); 57 - const classes = $derived(typography({ variant, class: className })); 70 + const tag = $derived(as ?? defaultTag[variant ?? "regular"]); 71 + const classes = $derived(typography({ variant, weight, class: className })); 58 72 </script> 59 73 60 74 <svelte:element this={tag} class={classes}>