refactor: replace raw headings with Title in remaining components

This commit is contained in:
Dayv1dDev
2026-08-07 18:03:18 +02:00
parent 036bd75b08
commit d2376fd755
20 changed files with 99 additions and 57 deletions
+3 -1
View File
@@ -164,7 +164,9 @@
</svg>
{#if title}
<h2 class="text-secondary text-center text-2xl font-bold lg:text-3xl">{title}</h2>
<Title level={2} variant="subsection" color="secondary" align="center">
{title}
</Title>
{/if}
<div class="grid gap-4" style="grid-template-columns: repeat({cols}, minmax(0, 1fr));">
{@render children?.()}
+3 -2
View File
@@ -6,6 +6,7 @@
import { getAllFilterSubjects } from "../../utils/filterComposer";
import CloseIcon from "../icons/navigation/Close.svelte";
import Tag from "../library/tags/Tag.svelte";
import Title from "../library/typography/Title.svelte";
import type { Locale } from "../../i18n/locales";
import type { Accounting, User, Project, Tipjar } from "../../openapi/client/index.ts";
@@ -217,9 +218,9 @@
</script>
<div class="flex gap-4">
<h1 class="text-2xl/8 font-bold text-black">
<Title level={1} variant="subsection">
{title}
</h1>
</Title>
{#each tags as tag}
<Tag variant="bold">
+5 -4
View File
@@ -1,6 +1,7 @@
<script lang="ts">
import { t } from "../../i18n/store";
import CollapsibleBox from "../library/layout/CollapsibleBox.svelte";
import Title from "../library/typography/Title.svelte";
</script>
<div class="flex items-start justify-between px-0 pt-0 pb-0 lg:hidden">
@@ -11,18 +12,18 @@
buttonTextHide={$t("pages.checkout.summary.hide")}
>
{#snippet header()}
<h2 class="text-secondary flex items-center gap-2 text-base font-semibold">
<Title level={2} variant="subsection" color="secondary" class="flex items-center gap-2">
{$t("pages.login.page.welcome.title")}
</h2>
</Title>
{/snippet}
</CollapsibleBox>
</div>
<div class="hidden flex-col gap-6 pt-6 pb-0 lg:flex">
<div>
<h2 class="text-secondary text-[3.5rem] leading-tight font-semibold">
<Title level={2} variant="display" color="secondary" weight="bold" class="leading-tight">
{$t("pages.login.page.welcome.title")}
</h2>
</Title>
<p class="text-content font-light">
{$t("pages.login.page.welcome.subtitle")}
</p>
+3 -2
View File
@@ -3,6 +3,7 @@
import Tipjar from "./Tipjar.svelte";
import { cart, cartByRecipient } from "../../stores/checkoutsStore";
import * as tipping from "../../utils/tipping";
import Title from "../library/typography/Title.svelte";
function increment(item: { key: string; quantity: number }) {
cart.updateQuantity(item.key, item.quantity + 1);
@@ -32,9 +33,9 @@
<div class="flex flex-col gap-10">
{#each getItems() as [target, items]}
<div class="flex flex-col gap-6">
<h2 class="text-2xl font-bold text-black">
<Title level={2} variant="subsection">
{items[0].recipientDisplayName}
</h2>
</Title>
{#each items as item (item.key)}
<CartItem
+5 -4
View File
@@ -1,6 +1,7 @@
<script lang="ts">
import { t } from "../../i18n/store";
import RadioButton from "../library/inputs/RadioButton.svelte";
import Title from "../library/typography/Title.svelte";
interface Props {
paymentMethod?: string;
@@ -17,9 +18,9 @@
<form id="feedback" method="POST" class="flex flex-col gap-4">
<div class="flex flex-col gap-4">
<div class="flex flex-row items-center gap-2">
<h2 class="text-2xl font-bold text-black">
<Title level={2} variant="subsection">
{$t("pages.checkout.verify.approved.formGoal.title")}
</h2>
</Title>
</div>
</div>
<fieldset class="flex flex-col gap-6">
@@ -35,9 +36,9 @@
<div class="mt-6 flex flex-col gap-4">
<div class="flex flex-row items-center gap-2">
<h2 class="text-2xl font-bold text-black">
<Title level={2} variant="subsection">
{$t("pages.checkout.verify.approved.formReview.title")}
</h2>
</Title>
</div>
<p class="text-content">
{$t("pages.checkout.verify.approved.formReview.description")}
+8 -3
View File
@@ -6,6 +6,7 @@
import { multiplyMoney, sumMoney } from "../../utils/money";
import CollapsibleBox from "../library/layout/CollapsibleBox.svelte";
import Thtml from "../library/typography/Thtml.svelte";
import Title from "../library/typography/Title.svelte";
let { hasError = false }: { hasError?: boolean } = $props();
@@ -26,8 +27,12 @@
buttonTextHide={$t("pages.checkout.summary.hideDetails")}
>
{#snippet header()}
<h2
class={`lg:text-double flex items-center gap-2 text-base font-semibold ${hasError ? "text-tertiary" : "text-secondary"}`}
<Title
level={2}
variant="subsection"
color={hasError ? "default" : "secondary"}
class={`flex items-center gap-2 ${hasError ? "text-tertiary lg:text-double" : "lg:text-double"}`}
weight="semibold"
>
{#if hasError}
<span class="h-6 w-6">
@@ -35,7 +40,7 @@
</span>
{/if}
{$t("pages.checkout.summary.total.title")}
</h2>
</Title>
<p
class={`text-double leading-tight font-bold lg:text-[3.5rem] ${hasError ? "text-tertiary" : "text-secondary"}`}
>
+3 -2
View File
@@ -6,6 +6,7 @@
import { cart, cartByRecipient, type CheckoutItem } from "../../stores/checkoutsStore";
import { getUnit } from "../../utils/currencies";
import * as tipping from "../../utils/tipping";
import Title from "../library/typography/Title.svelte";
let amount = $state(tipping.defaultAmount / getUnit());
let hasError = $state(false);
@@ -78,9 +79,9 @@
<div class="flex w-auto flex-col gap-4">
<div class="flex flex-col gap-2">
<h2 class="text-2xl font-bold text-black">
<Title level={2} variant="subsection">
{$t("pages.checkout.tipjar.community")}
</h2>
</Title>
<input
class="w-full rounded border border-gray-300 p-2
+2 -2
View File
@@ -29,9 +29,9 @@
{@render children?.()}
</div>
<div class="flex flex-col gap-4">
<h1 class="text-center text-3xl leading-tight font-bold text-black sm:text-6xl">
<Title level={1} variant="display" align="center">
{title}
</h1>
</Title>
<p class="text-content text-center text-sm sm:text-base">
{subtitle}
</p>
+8 -2
View File
@@ -14,6 +14,7 @@ Converted from CampaignCard.astro to maintain exact functionality
import CampaignStatusBadge from "../home/CampaignStatusBadge.svelte";
import Flames from "../icons/status/Flames.svelte";
import Tag from "../library/tags/Tag.svelte";
import Title from "../library/typography/Title.svelte";
import type { Accounting, Money } from "../../openapi/client";
import type { Campaign, CampaignSize } from "../../types/campaign";
@@ -156,9 +157,14 @@ Converted from CampaignCard.astro to maintain exact functionality
</div>
<!-- Title -->
<h3 class="text-secondary h-16 overflow-hidden text-2xl leading-8 font-bold">
<Title
level={3}
variant="subsection"
color="secondary"
class="h-16 overflow-hidden leading-8"
>
{campaign.title}
</h3>
</Title>
<!-- Funding Information -->
<div class="flex flex-col gap-2">
+3 -2
View File
@@ -1,6 +1,7 @@
<script lang="ts">
import Close from "../icons/navigation/Close.svelte";
import Button from "../library/buttons/Button.svelte";
import Title from "../library/typography/Title.svelte";
interface Props {
title: string;
@@ -45,9 +46,9 @@
class="relative z-10 flex flex-col gap-4 md:flex-row md:items-center md:justify-between"
>
<div class="flex-1 space-y-3">
<h2 class="text-2xl font-bold tracking-tight sm:text-3xl md:text-4xl">
<Title level={2} variant="section" class="tracking-tight">
{title}
</h2>
</Title>
<p class="text-variant1 max-w-3xl text-sm opacity-90 sm:text-base md:text-lg">
{description}
</p>
+13 -5
View File
@@ -1,5 +1,6 @@
<script lang="ts">
import { t } from "../../i18n/store";
import Title from "../library/typography/Title.svelte";
</script>
<section class="wrapper py-16">
@@ -11,16 +12,23 @@
<!-- Text Content -->
<div class="flex min-h-87 max-w-132.25 flex-col gap-4">
<!-- Main Headline -->
<h2
class="text-secondary text-2xl leading-tight font-bold md:text-[2.5rem] md:leading-12"
<Title
level={2}
variant="section"
color="secondary"
class="leading-tight"
>
{$t("pages.home.stories.title")}
</h2>
</Title>
<!-- Subtitle -->
<h3 class="text-secondary text-lg leading-8 font-bold md:text-2xl md:leading-8">
<Title
level={3}
variant="subsection"
color="secondary"
>
{$t("pages.home.stories.subtitle")}
</h3>
</Title>
<!-- Description -->
<div class="text-content flex-1 text-sm leading-6 md:text-base md:leading-6">
@@ -1,5 +1,6 @@
<script lang="ts">
import { t } from "../../i18n/store";
import Title from "../library/typography/Title.svelte";
import type { Snippet } from "svelte";
@@ -126,9 +127,9 @@
<!-- Content - centered and takes up available space -->
<div class="relative z-10 flex grow flex-col items-center justify-center gap-1 text-center">
<h2 class="text-2xl font-bold text-black">
<Title level={2} variant="subsection">
{$t(titleKey)}
</h2>
</Title>
{#if emptyMessageKey}
<p class="text-content text-base">
{$t(emptyMessageKey)}
@@ -195,9 +196,9 @@
<!-- Recent items list -->
<div class="relative z-10 mb-4 flex min-h-30 flex-grow flex-col gap-3">
<h3 class="text-base font-bold text-black">
<Title level={3} variant="field">
{$t(recentTitleKey)}
</h3>
</Title>
<ul class="flex flex-col gap-2">
{@render children?.()}
</ul>
+7 -3
View File
@@ -22,6 +22,8 @@
* ```
*/
import Title from "../library/typography/Title.svelte";
interface Button {
label: string;
href: string;
@@ -63,12 +65,14 @@
>
<!-- Content -->
<div class="flex flex-col gap-4">
<h2
class="text-3xl leading-tight font-bold md:text-4xl"
<Title
level={2}
variant="section"
class="leading-tight"
style="display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;"
>
{title}
</h2>
</Title>
<p class="text-sm leading-tight md:text-base md:leading-normal">
{description}
</p>
@@ -14,6 +14,7 @@
import { addMoney } from "../../utils/money";
import CampaignCard from "../home/CampaignCard.svelte";
import Carousel from "../library/layout/Carousel.svelte";
import Title from "../library/typography/Title.svelte";
import type { Money, GatewayCharge, User } from "../../openapi/client/types.gen.ts";
import type { Campaign } from "../../types/campaign";
@@ -173,9 +174,9 @@
{#if !loading && donatedCampaigns.length > 0}
<div class="flex flex-col gap-6">
<h2 class="text-3xl font-bold text-black md:text-4xl">
<Title level={2} variant="section">
{$t("pages.me.donatedProjects.title")}
</h2>
</Title>
<Carousel itemsPerGroup={3} gap={24} showDots={false}>
{#each donatedCampaigns as campaign, index (campaign.id)}
<CampaignCard
@@ -1,6 +1,7 @@
<script lang="ts">
import { t } from "../../i18n/store";
import { formatAmountWithSymbol } from "../../utils/currencies";
import Title from "../library/typography/Title.svelte";
import type { MatchfundingCall } from "../../types/me-page";
@@ -58,11 +59,14 @@
<div class="flex w-full flex-col gap-4">
<!-- Title -->
<div class="flex w-full flex-col gap-2">
<h3
class="min-w-full text-3xl leading-tight font-bold text-white md:text-4xl lg:text-5xl"
<Title
level={3}
variant="section"
color="white"
class="min-w-full leading-tight"
>
{call.title}
</h3>
</Title>
</div>
<!-- Stats Row (Horizontal on desktop, vertical on mobile) -->
@@ -13,6 +13,7 @@
import { extractId } from "../../utils/extractId";
import { toCollectionItems } from "../../utils/hydra.ts";
import Carousel from "../library/layout/Carousel.svelte";
import Title from "../library/typography/Title.svelte";
import type { MatchCall, MatchCallSubmission, User } from "../../openapi/client/types.gen.ts";
import type { MatchfundingCall } from "../../types/me-page";
@@ -163,18 +164,18 @@
{#if loading}
<!-- Loading State -->
<div class="flex flex-col gap-6">
<h2 class="text-2xl font-bold text-black md:text-3xl">
<Title level={2} variant="subsection">
{$t("pages.me.matchfunding.section.title")}
</h2>
</Title>
<!-- Single hero card skeleton matching actual dimensions -->
<div class="bg-grey h-64 w-full animate-pulse rounded-4xl md:h-80 lg:h-96"></div>
</div>
{:else if error}
<!-- Error State -->
<div class="flex flex-col gap-6">
<h2 class="text-2xl font-bold text-black md:text-3xl">
<Title level={2} variant="subsection">
{$t("pages.me.matchfunding.section.title")}
</h2>
</Title>
<p class="text-content text-base leading-normal">
{$t("pages.me.matchfunding.section.error")}
</p>
@@ -182,9 +183,9 @@
{:else if matchfundingCalls.length > 0}
<!-- Filled State -->
<div class="flex flex-col gap-6">
<h2 class="text-2xl font-bold text-black md:text-3xl">
<Title level={2} variant="subsection">
{$t("pages.me.matchfunding.section.title")}
</h2>
</Title>
<Carousel itemsPerGroup={1} gap={24} showDots={false}>
{#each matchfundingCalls as call (call.id)}
<MatchfundingCallCard {lang} {call} />
@@ -8,6 +8,7 @@
import { toCollectionItems } from "../../utils/hydra.ts";
import CampaignCard from "../home/CampaignCard.svelte";
import Carousel from "../library/layout/Carousel.svelte";
import Title from "../library/typography/Title.svelte";
import type { Money, Project, User } from "../../openapi/client/types.gen.ts";
import type { Campaign } from "../../types/campaign";
@@ -124,9 +125,9 @@
{#if !loading && ownedProjects.length > 0}
<div class="flex flex-col gap-6">
<h2 class="text-3xl font-bold text-black md:text-4xl">
<Title level={2} variant="section">
{$t("pages.me.ownedProjects.title")}
</h2>
</Title>
<Carousel itemsPerGroup={3} gap={24} showDots={false}>
{#each ownedProjects as campaign, index (campaign.id)}
<CampaignCard
+3 -2
View File
@@ -6,6 +6,7 @@
import MediumIcon from "../icons/social/MediumIcon.svelte";
import XIcon from "../icons/social/XIcon.svelte";
import TerritoryTag from "../project/TerritoryTag.svelte";
import Title from "../library/typography/Title.svelte";
import type { Link, Territory } from "../../openapi/client/types.gen";
@@ -67,9 +68,9 @@
<div class="mt-28 flex w-full flex-col items-center gap-4">
<!-- Name -->
<h1 class="text-secondary text-2xl leading-tight font-bold">
<Title level={1} variant="subsection" color="secondary" class="leading-tight">
{displayName}
</h1>
</Title>
<!-- Location -->
{#if territory}
+3 -2
View File
@@ -12,6 +12,7 @@ Implements active/inactive pill states matching Figma design
} from "../../openapi/client";
import { extractId } from "../../utils/extractId";
import CategorySelect from "../library/inputs/CategorySelect.svelte";
import Title from "../library/typography/Title.svelte";
interface Props {
selectedCategories?: string[];
@@ -53,9 +54,9 @@ Implements active/inactive pill states matching Figma design
<div class="w-full">
{#if showLabel}
<h3 class="font-body mb-6 text-base font-bold text-black">
<Title level={3} variant="field" class="font-body mb-6">
{$t("pages.search.filters.categoryLabel")}
</h3>
</Title>
{/if}
{#await categories then categories}
+5 -4
View File
@@ -12,6 +12,7 @@ Integrated with searchStore for state management and URL synchronization
import SearchInput from "./SearchInput.svelte";
import StatusFilter from "./StatusFilter.svelte";
import TerritoryFilter from "./TerritoryFilter.svelte";
import Title from "../library/typography/Title.svelte";
import { t } from "../../i18n/store";
import { searchStore, searchFilters, type SearchFilters } from "../../stores/searchStore";
import FilterIcon from "../icons/filters/FilterIcon.svelte";
@@ -103,18 +104,18 @@ Integrated with searchStore for state management and URL synchronization
<!-- Status + territory filters -->
<div class="flex flex-col items-start gap-6 lg:flex-row">
<div class="w-full">
<h3 class="font-body mb-2 text-base font-bold text-black">
<Title level={3} variant="field" class="font-body mb-2">
{$t("pages.search.filters.status.label")}
</h3>
</Title>
<StatusFilter
statuses={$searchFilters["status[]"] || []}
onStatusesChange={(statuses) => updateFilters({ "status[]": statuses })}
/>
</div>
<div class="w-full">
<h3 class="font-body mb-2 text-base font-bold text-black">
<Title level={3} variant="field" class="font-body mb-2">
{$t("pages.search.filters.territoryLabel")}
</h3>
</Title>
<TerritoryFilter
selectedTerritory={{
countries: $searchFilters["territory.country[]"] || [],