@vit-foundation/ui 0.24.1 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/README.md +11 -11
  2. package/dist/components/pages/GetInvolvedPage.svelte +139 -0
  3. package/dist/components/pages/GetInvolvedPage.svelte.d.ts +36 -0
  4. package/dist/components/pages/HomePage.svelte +256 -0
  5. package/dist/components/pages/HomePage.svelte.d.ts +36 -0
  6. package/dist/components/pages/LegalPage.svelte +39 -0
  7. package/dist/components/pages/LegalPage.svelte.d.ts +14 -0
  8. package/dist/components/pages/ProjectPage.svelte +128 -0
  9. package/dist/components/pages/ProjectPage.svelte.d.ts +17 -0
  10. package/dist/components/pages/TransparencyPage.svelte +164 -0
  11. package/dist/components/pages/TransparencyPage.svelte.d.ts +40 -0
  12. package/dist/components/pages/WeekliesPage.svelte +184 -0
  13. package/dist/components/pages/WeekliesPage.svelte.d.ts +46 -0
  14. package/dist/components/pages/WeeklyPage.svelte +203 -0
  15. package/dist/components/pages/WeeklyPage.svelte.d.ts +35 -0
  16. package/dist/components/pages/WhatWeDoPage.svelte +107 -0
  17. package/dist/components/pages/WhatWeDoPage.svelte.d.ts +27 -0
  18. package/dist/components/pages/WhoWeArePage.svelte +108 -0
  19. package/dist/components/pages/WhoWeArePage.svelte.d.ts +32 -0
  20. package/dist/components/ui/Logo.svelte +19 -3
  21. package/dist/config/messages.js +22 -0
  22. package/dist/config/types.d.ts +36 -0
  23. package/dist/content/index.d.ts +3 -1
  24. package/dist/content/index.js +1 -0
  25. package/dist/content/pages.d.ts +64 -0
  26. package/dist/content/pages.js +71 -0
  27. package/dist/content/types.d.ts +45 -0
  28. package/dist/content/types.js +0 -5
  29. package/dist/content-components.d.ts +18 -0
  30. package/dist/content-components.js +12 -0
  31. package/dist/contract.d.ts +3 -0
  32. package/dist/contract.js +4 -0
  33. package/package.json +1 -1
@@ -0,0 +1,203 @@
1
+ <script module lang="ts">
2
+ import type { ArticleEdit } from '../../content/types.js';
3
+
4
+ /**
5
+ * What a CMS may open on a weekly's own page: title, excerpt, and the body
6
+ * as rich text. The «Dades i fonts» and «Segueix explorant» headings and
7
+ * the back link edit through `config.messageEdit` over their own keys.
8
+ */
9
+ export type WeeklyPageEdit = ArticleEdit;
10
+ </script>
11
+
12
+ <script lang="ts">
13
+ import { getUiConfig } from '../../config/context.js';
14
+ import type {
15
+ CommentThreadData,
16
+ ReactionSummary,
17
+ WeeklyArticleData,
18
+ WeeklyCardData
19
+ } from '../../content/types.js';
20
+ import ActionLabel from '../../edit/ActionLabel.svelte';
21
+ import Editable from '../../edit/Editable.svelte';
22
+ import PageShell from '../layout/PageShell.svelte';
23
+ import DateText from '../ui/DateText.svelte';
24
+ import Link from '../ui/Link.svelte';
25
+ import RichText from '../ui/RichText.svelte';
26
+ import ShareRow from '../ui/ShareRow.svelte';
27
+ import CommentSection, { type CommentFormInstance } from '../weeklies/CommentSection.svelte';
28
+ import ReactionBar, { type ReactionBarForms } from '../weeklies/ReactionBar.svelte';
29
+ import WeeklieCard from '../weeklies/WeeklieCard.svelte';
30
+
31
+ /**
32
+ * A weekly's own page: number and date, title, excerpt, the square hero,
33
+ * the body, Instagram and sources, share, reactions, comments, and the
34
+ * related weeklies. The community forms arrive preflighted by the host —
35
+ * the website's remote forms, a CMS mirror's inert mocks — and
36
+ * `isLoggedIn` is the host's auth answer; those are the props the hosts
37
+ * fill differently. `related` is its own prop because vit-brain loads it
38
+ * apart from the weekly, where the website nests it.
39
+ */
40
+ interface Props {
41
+ weekly: WeeklyArticleData;
42
+ related: WeeklyCardData[];
43
+ comments: CommentThreadData[];
44
+ reactions: ReactionSummary[];
45
+ isLoggedIn: boolean;
46
+ /** The main comment box, preflighted; see CommentSection. */
47
+ commentForm: CommentFormInstance;
48
+ /** One preflighted instance per reply box; see CommentSection. */
49
+ replyFormFor: (threadId: string) => CommentFormInstance;
50
+ reactionForms: ReactionBarForms;
51
+ edit?: WeeklyPageEdit;
52
+ }
53
+
54
+ let {
55
+ weekly,
56
+ related,
57
+ comments,
58
+ reactions,
59
+ isLoggedIn,
60
+ commentForm,
61
+ replyFormFor,
62
+ reactionForms,
63
+ edit
64
+ }: Props = $props();
65
+
66
+ const config = getUiConfig();
67
+ const msg = $derived(config.messages);
68
+ </script>
69
+
70
+ <PageShell title={weekly.title} description={weekly.excerpt} variant="reading">
71
+ <p class="back">
72
+ <ActionLabel edit={config.messageEdit?.('back_label')} value={msg.back_label()}>
73
+ {#snippet control()}
74
+ <Link href="/weeklies">← {msg.back_label()}</Link>
75
+ {/snippet}
76
+ </ActionLabel>
77
+ </p>
78
+
79
+ <header>
80
+ <p class="meta">
81
+ <span class="number">{msg.weeklie_number({ number: weekly.number })}</span>
82
+ <DateText value={weekly.publishedOn} />
83
+ </p>
84
+ <Editable edit={edit?.title} value={weekly.title}>
85
+ {#snippet children(text, attrs)}<h1 {...attrs}>{text}</h1>{/snippet}
86
+ </Editable>
87
+ <Editable edit={edit?.excerpt} value={weekly.excerpt}>
88
+ {#snippet children(text, attrs)}<p class="excerpt" {...attrs}>{text}</p>{/snippet}
89
+ </Editable>
90
+ </header>
91
+
92
+ <img class="hero" src={weekly.imageUrl} alt="" width="600" height="600" />
93
+
94
+ {#if weekly.body}
95
+ <RichText body={weekly.body} edit={edit?.body} />
96
+ {/if}
97
+
98
+ {#if weekly.instagramUrl}
99
+ <p><a href={weekly.instagramUrl} rel="external noopener">Instagram ↗</a></p>
100
+ {/if}
101
+
102
+ {#if weekly.sources.length > 0}
103
+ <section aria-labelledby="sources-heading">
104
+ <Editable edit={config.messageEdit?.('weeklie_sources')} value={msg.weeklie_sources()}>
105
+ {#snippet children(text, attrs)}
106
+ <h2 class="subsection-heading" id="sources-heading" {...attrs}>{text}</h2>
107
+ {/snippet}
108
+ </Editable>
109
+ <ul>
110
+ {#each weekly.sources as source (source.url)}
111
+ <li><a href={source.url} rel="external noopener">{source.label}</a></li>
112
+ {/each}
113
+ </ul>
114
+ </section>
115
+ {/if}
116
+
117
+ <ShareRow title={weekly.title} />
118
+
119
+ <ReactionBar
120
+ {reactions}
121
+ target={{ kind: 'weekly', slug: weekly.slug }}
122
+ {isLoggedIn}
123
+ forms={reactionForms}
124
+ />
125
+
126
+ <CommentSection
127
+ {comments}
128
+ weeklySlug={weekly.slug}
129
+ {isLoggedIn}
130
+ {commentForm}
131
+ {replyFormFor}
132
+ {reactionForms}
133
+ />
134
+
135
+ {#if related.length > 0}
136
+ <section aria-labelledby="related-heading">
137
+ <Editable
138
+ edit={config.messageEdit?.('weeklie_keepExploring')}
139
+ value={msg.weeklie_keepExploring()}
140
+ >
141
+ {#snippet children(text, attrs)}
142
+ <h2 class="subsection-heading" id="related-heading" {...attrs}>{text}</h2>
143
+ {/snippet}
144
+ </Editable>
145
+ <div class="related">
146
+ {#each related as card (card.slug)}
147
+ <WeeklieCard weekly={card} />
148
+ {/each}
149
+ </div>
150
+ </section>
151
+ {/if}
152
+ </PageShell>
153
+
154
+ <style>
155
+ .back :global(a) {
156
+ text-decoration: none;
157
+ color: var(--color-ink-secondary);
158
+ }
159
+
160
+ .meta {
161
+ display: flex;
162
+ gap: var(--space-3);
163
+ color: var(--color-ink-muted);
164
+ font-size: var(--text-sm);
165
+ margin: 0;
166
+ }
167
+
168
+ .number {
169
+ font-weight: 700;
170
+ color: var(--color-brand);
171
+ }
172
+
173
+ h1 {
174
+ margin: var(--space-2) 0;
175
+ }
176
+
177
+ .excerpt {
178
+ font-size: var(--text-lg);
179
+ color: var(--color-ink-secondary);
180
+ }
181
+
182
+ .hero {
183
+ border-radius: var(--radius-lg);
184
+ margin-block: var(--space-4);
185
+ background: var(--color-band-grey);
186
+ width: 100%;
187
+ max-width: 32rem;
188
+ }
189
+
190
+ ul {
191
+ padding-left: var(--space-4);
192
+ }
193
+
194
+ a {
195
+ color: var(--color-brand);
196
+ }
197
+
198
+ .related {
199
+ display: grid;
200
+ grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
201
+ gap: var(--space-4);
202
+ }
203
+ </style>
@@ -0,0 +1,35 @@
1
+ import type { ArticleEdit } from '../../content/types.js';
2
+ /**
3
+ * What a CMS may open on a weekly's own page: title, excerpt, and the body
4
+ * as rich text. The «Dades i fonts» and «Segueix explorant» headings and
5
+ * the back link edit through `config.messageEdit` over their own keys.
6
+ */
7
+ export type WeeklyPageEdit = ArticleEdit;
8
+ import type { CommentThreadData, ReactionSummary, WeeklyArticleData, WeeklyCardData } from '../../content/types.js';
9
+ import { type CommentFormInstance } from '../weeklies/CommentSection.svelte';
10
+ import { type ReactionBarForms } from '../weeklies/ReactionBar.svelte';
11
+ /**
12
+ * A weekly's own page: number and date, title, excerpt, the square hero,
13
+ * the body, Instagram and sources, share, reactions, comments, and the
14
+ * related weeklies. The community forms arrive preflighted by the host —
15
+ * the website's remote forms, a CMS mirror's inert mocks — and
16
+ * `isLoggedIn` is the host's auth answer; those are the props the hosts
17
+ * fill differently. `related` is its own prop because vit-brain loads it
18
+ * apart from the weekly, where the website nests it.
19
+ */
20
+ interface Props {
21
+ weekly: WeeklyArticleData;
22
+ related: WeeklyCardData[];
23
+ comments: CommentThreadData[];
24
+ reactions: ReactionSummary[];
25
+ isLoggedIn: boolean;
26
+ /** The main comment box, preflighted; see CommentSection. */
27
+ commentForm: CommentFormInstance;
28
+ /** One preflighted instance per reply box; see CommentSection. */
29
+ replyFormFor: (threadId: string) => CommentFormInstance;
30
+ reactionForms: ReactionBarForms;
31
+ edit?: WeeklyPageEdit;
32
+ }
33
+ declare const WeeklyPage: import("svelte").Component<Props, {}, "">;
34
+ type WeeklyPage = ReturnType<typeof WeeklyPage>;
35
+ export default WeeklyPage;
@@ -0,0 +1,107 @@
1
+ <script module lang="ts">
2
+ import type { CopyEditFor } from '../../content/pages.js';
3
+ import type { ProjectCardData } from '../../content/types.js';
4
+ import type { ProjectEditMap } from '../projects/ProjectCard.svelte';
5
+
6
+ /** What a CMS may open on /what-we-do; `projectFor` answers per card by its `id`. */
7
+ export interface WhatWeDoPageEdit {
8
+ copy?: CopyEditFor<'what-we-do'>;
9
+ projectFor?: (project: ProjectCardData) => ProjectEditMap | undefined;
10
+ }
11
+ </script>
12
+
13
+ <script lang="ts">
14
+ import { getUiConfig } from '../../config/context.js';
15
+ import type { PageCopy } from '../../content/pages.js';
16
+ import Editable from '../../edit/Editable.svelte';
17
+ import PageShell from '../layout/PageShell.svelte';
18
+ import ProjectCard from '../projects/ProjectCard.svelte';
19
+ import CopyIntro from '../ui/CopyIntro.svelte';
20
+
21
+ /**
22
+ * The projects page: a showcase of the latest project, the collaborations
23
+ * as wide rows, the passion projects as a grid. The three groups are the
24
+ * website's load's (`getLatest`, one `list(kind)` each); a host that
25
+ * groups differently (vit-brain's `projectSections`) answers the same
26
+ * three props.
27
+ */
28
+ interface Props {
29
+ content: PageCopy<'what-we-do'>;
30
+ /** The showcase slot; `null`/absent renders no «Últim projecte» band. */
31
+ latest?: ProjectCardData | null;
32
+ collaborations: ProjectCardData[];
33
+ passion: ProjectCardData[];
34
+ edit?: WhatWeDoPageEdit;
35
+ }
36
+
37
+ let { content, latest = null, collaborations, passion, edit }: Props = $props();
38
+
39
+ const config = getUiConfig();
40
+ const msg = $derived(config.messages);
41
+ </script>
42
+
43
+ <PageShell title={msg.nav_whatWeDo()}>
44
+ <Editable edit={config.messageEdit?.('nav_whatWeDo')} value={msg.nav_whatWeDo()}>
45
+ {#snippet children(text, attrs)}<h1 {...attrs}>{text}</h1>{/snippet}
46
+ </Editable>
47
+
48
+ {#if latest}
49
+ <section class="latest" aria-labelledby="latest-heading">
50
+ <Editable edit={edit?.copy?.('latest_heading')} value={content.latest_heading}>
51
+ {#snippet children(text, attrs)}
52
+ <h2 class="section-heading" id="latest-heading" {...attrs}>{text}</h2>
53
+ {/snippet}
54
+ </Editable>
55
+ <ProjectCard project={latest} variant="wide" edit={edit?.projectFor?.(latest)} />
56
+ </section>
57
+ {/if}
58
+
59
+ <section aria-labelledby="collaborations-heading">
60
+ <Editable edit={edit?.copy?.('collaborations_heading')} value={content.collaborations_heading}>
61
+ {#snippet children(text, attrs)}
62
+ <h2 class="section-heading" id="collaborations-heading" {...attrs}>
63
+ {text}
64
+ </h2>
65
+ {/snippet}
66
+ </Editable>
67
+ <CopyIntro text={content.collaborations_intro} edit={edit?.copy?.('collaborations_intro')} />
68
+ <div class="stack">
69
+ {#each collaborations as project (project.slug)}
70
+ <ProjectCard {project} variant="wide" edit={edit?.projectFor?.(project)} />
71
+ {/each}
72
+ </div>
73
+ </section>
74
+
75
+ <section aria-labelledby="passion-heading">
76
+ <Editable edit={edit?.copy?.('passion_heading')} value={content.passion_heading}>
77
+ {#snippet children(text, attrs)}
78
+ <h2 class="section-heading" id="passion-heading" {...attrs}>{text}</h2>
79
+ {/snippet}
80
+ </Editable>
81
+ <CopyIntro text={content.passion_intro} edit={edit?.copy?.('passion_intro')} />
82
+ <div class="grid">
83
+ {#each passion as project (project.slug)}
84
+ <ProjectCard {project} variant="grid" edit={edit?.projectFor?.(project)} />
85
+ {/each}
86
+ </div>
87
+ </section>
88
+ </PageShell>
89
+
90
+ <style>
91
+ .latest {
92
+ padding-block-end: var(--space-4);
93
+ border-bottom: 1px solid var(--color-hairline);
94
+ }
95
+
96
+ .stack {
97
+ display: flex;
98
+ flex-direction: column;
99
+ gap: var(--space-5);
100
+ }
101
+
102
+ .grid {
103
+ display: grid;
104
+ grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
105
+ gap: var(--space-5) var(--space-4);
106
+ }
107
+ </style>
@@ -0,0 +1,27 @@
1
+ import type { CopyEditFor } from '../../content/pages.js';
2
+ import type { ProjectCardData } from '../../content/types.js';
3
+ import type { ProjectEditMap } from '../projects/ProjectCard.svelte';
4
+ /** What a CMS may open on /what-we-do; `projectFor` answers per card by its `id`. */
5
+ export interface WhatWeDoPageEdit {
6
+ copy?: CopyEditFor<'what-we-do'>;
7
+ projectFor?: (project: ProjectCardData) => ProjectEditMap | undefined;
8
+ }
9
+ import type { PageCopy } from '../../content/pages.js';
10
+ /**
11
+ * The projects page: a showcase of the latest project, the collaborations
12
+ * as wide rows, the passion projects as a grid. The three groups are the
13
+ * website's load's (`getLatest`, one `list(kind)` each); a host that
14
+ * groups differently (vit-brain's `projectSections`) answers the same
15
+ * three props.
16
+ */
17
+ interface Props {
18
+ content: PageCopy<'what-we-do'>;
19
+ /** The showcase slot; `null`/absent renders no «Últim projecte» band. */
20
+ latest?: ProjectCardData | null;
21
+ collaborations: ProjectCardData[];
22
+ passion: ProjectCardData[];
23
+ edit?: WhatWeDoPageEdit;
24
+ }
25
+ declare const WhatWeDoPage: import("svelte").Component<Props, {}, "">;
26
+ type WhatWeDoPage = ReturnType<typeof WhatWeDoPage>;
27
+ export default WhatWeDoPage;
@@ -0,0 +1,108 @@
1
+ <script module lang="ts">
2
+ import type { CopyEditFor } from '../../content/pages.js';
3
+ import type { CollaboratorData, TeamMemberData } from '../../content/types.js';
4
+ import type { CollectionRef } from '../../edit/types.js';
5
+ import type { CollaboratorEditMap } from '../team/CollaboratorList.svelte';
6
+ import type { TeamMemberEditMap } from '../team/TeamMemberCard.svelte';
7
+
8
+ /**
9
+ * What a CMS may open on /who-we-are. `memberFor` answers per row, so a
10
+ * host reads the identity it put on `TeamMemberData.id`; `collaborators`
11
+ * names the list's collection, which turns on its add slot and removes.
12
+ */
13
+ export interface WhoWeArePageEdit {
14
+ copy?: CopyEditFor<'who-we-are'>;
15
+ memberFor?: (member: TeamMemberData) => TeamMemberEditMap | undefined;
16
+ collaboratorFor?: (collaborator: CollaboratorData) => CollaboratorEditMap | undefined;
17
+ collaborators?: CollectionRef;
18
+ }
19
+ </script>
20
+
21
+ <script lang="ts">
22
+ import { getUiConfig } from '../../config/context.js';
23
+ import type { PageCopy } from '../../content/pages.js';
24
+ import Editable from '../../edit/Editable.svelte';
25
+ import PageShell from '../layout/PageShell.svelte';
26
+ import CollaboratorList from '../team/CollaboratorList.svelte';
27
+ import TeamMemberCard from '../team/TeamMemberCard.svelte';
28
+ import CopyIntro from '../ui/CopyIntro.svelte';
29
+
30
+ /**
31
+ * The team page: the featured members, the board, the collaborators. The
32
+ * split into `featured` and `board` is the website's load's (one `isBoard`
33
+ * filter each), so the module takes the two lists rather than re-deciding.
34
+ */
35
+ interface Props {
36
+ content: PageCopy<'who-we-are'>;
37
+ featured: TeamMemberData[];
38
+ board: TeamMemberData[];
39
+ collaborators: CollaboratorData[];
40
+ edit?: WhoWeArePageEdit;
41
+ }
42
+
43
+ let { content, featured, board, collaborators, edit }: Props = $props();
44
+
45
+ const config = getUiConfig();
46
+ const msg = $derived(config.messages);
47
+ </script>
48
+
49
+ <PageShell title={msg.nav_whoWeAre()}>
50
+ <Editable edit={config.messageEdit?.('nav_whoWeAre')} value={msg.nav_whoWeAre()}>
51
+ {#snippet children(text, attrs)}<h1 {...attrs}>{text}</h1>{/snippet}
52
+ </Editable>
53
+
54
+ <section aria-labelledby="team-heading">
55
+ <Editable edit={edit?.copy?.('team_heading')} value={content.team_heading}>
56
+ {#snippet children(text, attrs)}
57
+ <h2 class="section-heading" id="team-heading" {...attrs}>{text}</h2>
58
+ {/snippet}
59
+ </Editable>
60
+ <CopyIntro text={content.team_intro} edit={edit?.copy?.('team_intro')} />
61
+ <div class="featured">
62
+ {#each featured as member (member.slug)}
63
+ <TeamMemberCard {member} variant="featured" edit={edit?.memberFor?.(member)} />
64
+ {/each}
65
+ </div>
66
+ </section>
67
+
68
+ <section aria-labelledby="board-heading">
69
+ <Editable edit={edit?.copy?.('board_heading')} value={content.board_heading}>
70
+ {#snippet children(text, attrs)}
71
+ <h2 class="section-heading" id="board-heading" {...attrs}>{text}</h2>
72
+ {/snippet}
73
+ </Editable>
74
+ <CopyIntro text={content.board_intro} edit={edit?.copy?.('board_intro')} />
75
+ <div class="board">
76
+ {#each board as member (member.slug)}
77
+ <TeamMemberCard {member} variant="board" edit={edit?.memberFor?.(member)} />
78
+ {/each}
79
+ </div>
80
+ </section>
81
+
82
+ <section aria-labelledby="collaborators-heading">
83
+ <Editable edit={edit?.copy?.('collaborators_heading')} value={content.collaborators_heading}>
84
+ {#snippet children(text, attrs)}
85
+ <h2 class="section-heading" id="collaborators-heading" {...attrs}>{text}</h2>
86
+ {/snippet}
87
+ </Editable>
88
+ <CollaboratorList
89
+ {collaborators}
90
+ editFor={edit?.collaboratorFor}
91
+ collection={edit?.collaborators}
92
+ />
93
+ </section>
94
+ </PageShell>
95
+
96
+ <style>
97
+ .featured {
98
+ display: grid;
99
+ grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
100
+ gap: var(--space-4);
101
+ }
102
+
103
+ .board {
104
+ display: grid;
105
+ grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
106
+ gap: var(--space-4);
107
+ }
108
+ </style>
@@ -0,0 +1,32 @@
1
+ import type { CopyEditFor } from '../../content/pages.js';
2
+ import type { CollaboratorData, TeamMemberData } from '../../content/types.js';
3
+ import type { CollectionRef } from '../../edit/types.js';
4
+ import type { CollaboratorEditMap } from '../team/CollaboratorList.svelte';
5
+ import type { TeamMemberEditMap } from '../team/TeamMemberCard.svelte';
6
+ /**
7
+ * What a CMS may open on /who-we-are. `memberFor` answers per row, so a
8
+ * host reads the identity it put on `TeamMemberData.id`; `collaborators`
9
+ * names the list's collection, which turns on its add slot and removes.
10
+ */
11
+ export interface WhoWeArePageEdit {
12
+ copy?: CopyEditFor<'who-we-are'>;
13
+ memberFor?: (member: TeamMemberData) => TeamMemberEditMap | undefined;
14
+ collaboratorFor?: (collaborator: CollaboratorData) => CollaboratorEditMap | undefined;
15
+ collaborators?: CollectionRef;
16
+ }
17
+ import type { PageCopy } from '../../content/pages.js';
18
+ /**
19
+ * The team page: the featured members, the board, the collaborators. The
20
+ * split into `featured` and `board` is the website's load's (one `isBoard`
21
+ * filter each), so the module takes the two lists rather than re-deciding.
22
+ */
23
+ interface Props {
24
+ content: PageCopy<'who-we-are'>;
25
+ featured: TeamMemberData[];
26
+ board: TeamMemberData[];
27
+ collaborators: CollaboratorData[];
28
+ edit?: WhoWeArePageEdit;
29
+ }
30
+ declare const WhoWeArePage: import("svelte").Component<Props, {}, "">;
31
+ type WhoWeArePage = ReturnType<typeof WhoWeArePage>;
32
+ export default WhoWeArePage;
@@ -9,16 +9,32 @@
9
9
  let { size = 32, withWordmark = false }: Props = $props();
10
10
  </script>
11
11
 
12
+ <!--
13
+ The mark is ALWAYS decorative. It carries no accessible name of its own, in
14
+ either branch, because at every call site something else already supplies
15
+ one — and when it tried, it doubled.
16
+
17
+ `withWordmark` used to flip three accessibility facts together:
18
+ `aria-hidden`, `role="img"` and the presence of `<title>`. With the wordmark
19
+ on, the mark was named "Brain VIT" AND the wordmark rendered the same string
20
+ beside it, so a screen reader announced the name twice on all three of
21
+ Brain's sign-in pages. Inverting the branch does not help: with the wordmark
22
+ off, the rail already names it through `<a aria-label="Home">` and the print
23
+ sheet sits it beside an `<h1>`, so naming the mark there doubles at the other
24
+ end.
25
+
26
+ Which leaves one honest rule — never name it — and the naming stays where
27
+ the context is: the visible wordmark below, the anchor around it, or the
28
+ heading beside it. `Logo.svelte.test.ts` pins both branches.
29
+ -->
12
30
  <span class="logo">
13
31
  <svg
14
32
  viewBox="0 0 48 56"
15
33
  width={size * (48 / 56)}
16
34
  height={size}
17
- aria-hidden={withWordmark ? undefined : true}
18
- role={withWordmark ? 'img' : undefined}
35
+ aria-hidden="true"
19
36
  focusable="false"
20
37
  >
21
- {#if withWordmark}<title>Brain VIT</title>{/if}
22
38
  <path
23
39
  d="M25 2c11.6 0 21 9.4 21 21 0 6.9-3.3 13-8.5 16.8V54H17v-9h-4.5A4.5 4.5 0 0 1 8 40.5V34H4.2c-1.7 0-2.7-1.9-1.7-3.3L8 22.4C9 11 16.2 2 25 2Z"
24
40
  fill="currentColor"
@@ -105,6 +105,28 @@ export const defaultMessages = {
105
105
  category_education: () => 'Educació',
106
106
  category_collaboration: () => 'Col·laboració',
107
107
  category_press: () => 'Premsa',
108
+ nav_whoWeAre: () => 'Qui som',
109
+ nav_whatWeDo: () => 'Què fem',
110
+ nav_getInvolved: () => "Implica-t'hi",
111
+ nav_weeklies: () => 'Weeklies',
112
+ common_seeAll: () => 'Mostra-ho tot',
113
+ common_seeAllHref: () => '/transparency',
114
+ cta_meetTeam: () => "Coneix l'equip",
115
+ cta_meetTeamHref: () => '/who-we-are',
116
+ cta_contactUs: () => "Contacta'ns",
117
+ cta_contactUsHref: () => '/get-involved',
118
+ weeklies_searchPlaceholder: () => 'Cerca un tema…',
119
+ weeklies_exploreOne: () => "…o explora'n un d'aquests",
120
+ weeklies_filterLabel: () => 'Filtra per tema',
121
+ weeklies_searchResultsLabel: () => 'Resultats de la cerca',
122
+ weeklies_loadError: () => "No s'han pogut carregar els resultats. Torna-ho a provar.",
123
+ weeklies_empty: () => 'No hem trobat cap weekly amb aquests criteris.',
124
+ timeline_searchPlaceholder: () => 'Què hem estat fent?',
125
+ timeline_filterLabel: () => 'Filtra per categoria',
126
+ timeline_empty: () => 'No hem trobat cap fita amb aquests criteris.',
127
+ back_label: () => 'Torna enrere',
128
+ weeklie_sources: () => 'Dades i fonts',
129
+ weeklie_keepExploring: () => 'Segueix explorant',
108
130
  status_published: () => 'Publicat',
109
131
  status_draft: () => 'Esborrany',
110
132
  status_open: () => 'Oberta',
@@ -149,6 +149,42 @@ export interface UiMessages {
149
149
  category_education(): string;
150
150
  category_collaboration(): string;
151
151
  category_press(): string;
152
+ /**
153
+ * The wording the PAGE MODULES read (`components/pages/*`), REQUIRED like
154
+ * every key but the *Href pair above.
155
+ *
156
+ * ⚠ Adding them was a compile-break for any host whose `messages` object
157
+ * lacked one — `messages` is all-or-nothing (see ./messages.js), so a
158
+ * catalog that compiled against 0.24 stops compiling here rather than
159
+ * rendering a hole. Both hosts already carried every key (the website's
160
+ * Paraglide catalog, vit-brain's `ui_messages` table) because the nine
161
+ * route files read them by hand before the pages moved in; the only thing
162
+ * that changed is that the package now names what it reads. The four
163
+ * `*Href` keys are destinations edited as wording (fndvit-website#11) —
164
+ * a link's text and address are one editorial gesture, so both are keys.
165
+ */
166
+ nav_whoWeAre(): string;
167
+ nav_whatWeDo(): string;
168
+ nav_getInvolved(): string;
169
+ nav_weeklies(): string;
170
+ common_seeAll(): string;
171
+ common_seeAllHref(): string;
172
+ cta_meetTeam(): string;
173
+ cta_meetTeamHref(): string;
174
+ cta_contactUs(): string;
175
+ cta_contactUsHref(): string;
176
+ weeklies_searchPlaceholder(): string;
177
+ weeklies_exploreOne(): string;
178
+ weeklies_filterLabel(): string;
179
+ weeklies_searchResultsLabel(): string;
180
+ weeklies_loadError(): string;
181
+ weeklies_empty(): string;
182
+ timeline_searchPlaceholder(): string;
183
+ timeline_filterLabel(): string;
184
+ timeline_empty(): string;
185
+ back_label(): string;
186
+ weeklie_sources(): string;
187
+ weeklie_keepExploring(): string;
152
188
  /**
153
189
  * Editorial state, as the panel's `flag` rows word it: a card's
154
190
  * published/draft pair, an opening's open/closed pair. Catalog keys rather
@@ -1,4 +1,6 @@
1
1
  export { renderBody } from './richtext.js';
2
2
  export type { RichTextBlock } from './richtext.js';
3
+ export { GET_INVOLVED_REASON_KEYS, PAGE_COPY_KEYS } from './pages.js';
4
+ export type { CopyEditFor, CopyKey, PageCopy, PageId } from './pages.js';
3
5
  export { COMMENT_STATUSES, CONTACT_CATEGORIES, MILESTONE_CATEGORIES, PROJECT_KINDS, REACTIONS } from './types.js';
4
- export type { CollaboratorData, CommentData, CommentThreadData, CommentStatus, ContactCategory, FieldConstraint, FormFailReason, JobOpeningData, MilestoneCategory, MilestoneData, ProjectCardData, ProjectKind, Reaction, ReactionSummary, ReactionTarget, SortDirection, TeamMemberData, WeeklyCardData } from './types.js';
6
+ export type { ArticleEdit, CollaboratorData, CommentData, CommentThreadData, CommentStatus, ContactCategory, FieldConstraint, FormFailReason, JobOpeningData, MilestoneCategory, MilestoneData, ProjectArticleData, ProjectCardData, ProjectKind, Reaction, ReactionSummary, ReactionTarget, SortDirection, TeamMemberData, ThemeData, WeeklyArticleData, WeeklyCardData, WeeklySourceData } from './types.js';
@@ -1,2 +1,3 @@
1
1
  export { renderBody } from './richtext.js';
2
+ export { GET_INVOLVED_REASON_KEYS, PAGE_COPY_KEYS } from './pages.js';
2
3
  export { COMMENT_STATUSES, CONTACT_CATEGORIES, MILESTONE_CATEGORIES, PROJECT_KINDS, REACTIONS } from './types.js';