@glossarist/concept-browser 0.7.100 → 0.7.102
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.
- package/cli/index.mjs +14 -251
- package/cli/index.ts +289 -0
- package/package.json +3 -2
- package/src/__tests__/__fixtures__/concepts.ts +3 -3
- package/src/__tests__/components/learn/learn-card-dimension-card.test.ts +112 -0
- package/src/__tests__/composables/use-concept-edges-v2.test.ts +1 -0
- package/src/__tests__/designation-relationship.test.ts +2 -2
- package/src/__tests__/perf/serialization-perf.test.ts +1 -0
- package/src/__tests__/use-rdf-document.test.ts +1 -0
- package/src/__tests__/views/learn/learn-designations-view.test.ts +84 -0
- package/src/__tests__/views/learn/learn-index-view.test.ts +45 -0
- package/src/__tests__/views/learn/learn-relationships-view.test.ts +83 -0
- package/src/__tests__/views/learn/learn-statuses-view.test.ts +60 -0
- package/src/adapters/bibliography-adapter.ts +1 -1
- package/src/adapters/model-bridge.ts +15 -15
- package/src/adapters/non-verbal/figure-bridge.ts +2 -2
- package/src/adapters/non-verbal/formula-bridge.ts +2 -2
- package/src/adapters/non-verbal/table-bridge.ts +2 -2
- package/src/components/CitationDisplay.vue +1 -1
- package/src/components/ConceptDetail.vue +2 -2
- package/src/components/ConceptDiffModal.vue +2 -2
- package/src/components/ConceptDiffView.vue +1 -1
- package/src/components/DesignationList.vue +4 -4
- package/src/components/NavIcon.vue +1 -0
- package/src/components/RelationSphere.vue +1 -1
- package/src/components/figure/FigureDisplay.vue +5 -5
- package/src/components/formula/FormulaDisplay.vue +4 -4
- package/src/components/learn/DimensionCard.vue +71 -0
- package/src/components/learn/LearnCard.vue +59 -0
- package/src/components/table/TableDisplay.vue +3 -3
- package/src/components/use-rdf-document.ts +16 -7
- package/src/composables/use-concept-content.ts +3 -3
- package/src/composables/use-concept-diff.ts +2 -2
- package/src/composables/use-concept-edges.ts +3 -3
- package/src/config/page-types.ts +1 -1
- package/src/i18n/locales/eng.yml +114 -9
- package/src/i18n/locales/fra.yml +114 -9
- package/src/layouts/Default.astro +32 -2
- package/src/router/index.ts +21 -2
- package/src/utils/content-renderer.ts +1 -1
- package/src/utils/partitive-multiplicity.ts +3 -2
- package/src/views/ConceptView.vue +3 -3
- package/src/views/learn/LearnDesignationsView.vue +190 -0
- package/src/views/learn/LearnIndexView.vue +75 -0
- package/src/views/learn/LearnRelationshipsView.vue +317 -0
- package/src/views/learn/LearnStatusesView.vue +114 -0
- package/tailwind.config.js +3 -3
- package/tsconfig.json +1 -1
- package/src/__tests__/views/relation-types-view.test.ts +0 -85
- package/src/adapters/model-bridge/bridges.ts +0 -159
- package/src/adapters/model-bridge/concept.ts +0 -97
- package/src/adapters/model-bridge/entity-refs.ts +0 -49
- package/src/adapters/model-bridge/hyperedge.ts +0 -103
- package/src/adapters/model-bridge/index.ts +0 -46
- package/src/adapters/model-bridge/mappers.ts +0 -277
- package/src/adapters/model-bridge/partitive.ts +0 -79
- package/src/adapters/non-verbal/glossarist-augment.d.ts +0 -339
- /package/src/adapters/{model-bridge/jsonld-types.ts → jsonld-types.ts} +0 -0
|
@@ -12,6 +12,30 @@ interface Props {
|
|
|
12
12
|
|
|
13
13
|
const { title, description = '', conceptTerm, conceptDefinition } = Astro.props;
|
|
14
14
|
const siteConfig = await getSiteConfig();
|
|
15
|
+
|
|
16
|
+
// Derive Google Fonts URL from siteConfig branding (build-time SSG).
|
|
17
|
+
// Falls back to the default DM Sans / DM Serif Display / JetBrains Mono
|
|
18
|
+
// when no branding.fonts is declared.
|
|
19
|
+
const brandingFonts = siteConfig?.branding?.fonts;
|
|
20
|
+
const fontParts: string[] = [];
|
|
21
|
+
if (brandingFonts?.header?.source === 'google' && brandingFonts.header.family) {
|
|
22
|
+
const w = (brandingFonts.header.weights || [400, 700]).join(';');
|
|
23
|
+
fontParts.push(`family=${brandingFonts.header.family.replace(/ /g, '+')}:wght@${w}`);
|
|
24
|
+
}
|
|
25
|
+
if (brandingFonts?.body?.source === 'google' && brandingFonts.body.family) {
|
|
26
|
+
const w = (brandingFonts.body.weights || [400, 700]).join(';');
|
|
27
|
+
fontParts.push(`family=${brandingFonts.body.family.replace(/ /g, '+')}:wght@${w}`);
|
|
28
|
+
}
|
|
29
|
+
const fontsUrl = fontParts.length > 0
|
|
30
|
+
? `https://fonts.googleapis.com/css2?${fontParts.join('&')}&display=swap`
|
|
31
|
+
: 'https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;0,9..40,600;0,9..40,700;1,9..40,400&family=DM+Serif+Display:ital@0;1&family=JetBrains+Mono:wght@400;500&display=swap';
|
|
32
|
+
|
|
33
|
+
const fontHeader = brandingFonts?.header?.family
|
|
34
|
+
? `'${brandingFonts.header.family}', Georgia, serif`
|
|
35
|
+
: `'DM Serif Display', Georgia, serif`;
|
|
36
|
+
const fontBody = brandingFonts?.body?.family
|
|
37
|
+
? `'${brandingFonts.body.family}', system-ui, sans-serif`
|
|
38
|
+
: `'DM Sans', system-ui, sans-serif`;
|
|
15
39
|
---
|
|
16
40
|
|
|
17
41
|
<!DOCTYPE html>
|
|
@@ -42,8 +66,14 @@ const siteConfig = await getSiteConfig();
|
|
|
42
66
|
<title>{title}</title>
|
|
43
67
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
44
68
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
45
|
-
<link rel="preload" as="style" href=
|
|
46
|
-
<noscript><link href=
|
|
69
|
+
<link rel="preload" as="style" href={fontsUrl} onload="this.rel='stylesheet'">
|
|
70
|
+
<noscript><link href={fontsUrl} rel="stylesheet"></noscript>
|
|
71
|
+
<style is:global>
|
|
72
|
+
:root {
|
|
73
|
+
--font-header: ${fontHeader};
|
|
74
|
+
--font-body: ${fontBody};
|
|
75
|
+
}
|
|
76
|
+
</style>
|
|
47
77
|
<script is:inline>
|
|
48
78
|
(function() {
|
|
49
79
|
const c = document.cookie.split(';').map(s => s.trim()).find(s => s.startsWith('theme='));
|
package/src/router/index.ts
CHANGED
|
@@ -96,8 +96,27 @@ export const routes: RouteRecordRaw[] = [
|
|
|
96
96
|
},
|
|
97
97
|
{
|
|
98
98
|
path: '/relation-types',
|
|
99
|
-
|
|
100
|
-
|
|
99
|
+
redirect: '/learn/relationships',
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
path: '/learn',
|
|
103
|
+
name: 'learn',
|
|
104
|
+
component: () => import('../views/learn/LearnIndexView.vue'),
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
path: '/learn/relationships',
|
|
108
|
+
name: 'learn-relationships',
|
|
109
|
+
component: () => import('../views/learn/LearnRelationshipsView.vue'),
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
path: '/learn/designations',
|
|
113
|
+
name: 'learn-designations',
|
|
114
|
+
component: () => import('../views/learn/LearnDesignationsView.vue'),
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
path: '/learn/statuses',
|
|
118
|
+
name: 'learn-statuses',
|
|
119
|
+
component: () => import('../views/learn/LearnStatusesView.vue'),
|
|
101
120
|
},
|
|
102
121
|
{
|
|
103
122
|
path: '/about',
|
|
@@ -183,7 +183,7 @@ function resolveUrnRefs(text: string, opts: RenderOptions): string {
|
|
|
183
183
|
function resolveMentions(text: string, opts: RenderOptions): string {
|
|
184
184
|
return text.replace(/\{\{([^{}]+?)\}\}/g, (_orig, body) => {
|
|
185
185
|
const parsed = parseMention(body);
|
|
186
|
-
const p = parsed as Record<string, unknown>;
|
|
186
|
+
const p = parsed as unknown as Record<string, unknown>;
|
|
187
187
|
|
|
188
188
|
switch (p.kind) {
|
|
189
189
|
case 'fig-ref':
|
|
@@ -28,10 +28,11 @@ import {
|
|
|
28
28
|
multiplicityFromPair,
|
|
29
29
|
isValidPresence,
|
|
30
30
|
isValidCount,
|
|
31
|
-
type PartitivePresence,
|
|
32
|
-
type PartitiveCount,
|
|
33
31
|
} from 'glossarist/models';
|
|
34
32
|
|
|
33
|
+
type PartitivePresence = (typeof PARTITIVE_PRESENCE.VALUES)[number];
|
|
34
|
+
type PartitiveCount = (typeof PARTITIVE_COUNT.VALUES)[number];
|
|
35
|
+
|
|
35
36
|
// ── Two independent axes (re-exported SSOT) ────────────────────────────
|
|
36
37
|
|
|
37
38
|
export { PARTITIVE_PRESENCE, PARTITIVE_COUNT };
|
|
@@ -60,7 +60,7 @@ const activeRegisterId = computed(() => sphereFocusPayload.value?.registerId ??
|
|
|
60
60
|
const adjacent = ref({ prev: null as string | null, next: null as string | null });
|
|
61
61
|
|
|
62
62
|
const { conceptPartitiveRelations, conceptGenericRelations } = useConceptEdges(
|
|
63
|
-
concept,
|
|
63
|
+
computed(() => concept.value as any),
|
|
64
64
|
activeRegisterId,
|
|
65
65
|
manifest,
|
|
66
66
|
edges,
|
|
@@ -284,7 +284,7 @@ onUnmounted(() => window.removeEventListener('keydown', onKeydown));
|
|
|
284
284
|
<!-- Sphere mode — receives concept + edges directly, no URI matching -->
|
|
285
285
|
<RelationSphere
|
|
286
286
|
v-if="viewMode === 'sphere'"
|
|
287
|
-
:concept="concept"
|
|
287
|
+
:concept="concept as any"
|
|
288
288
|
:manifest="manifest"
|
|
289
289
|
:register-id="activeRegisterId"
|
|
290
290
|
:edges="edges"
|
|
@@ -295,7 +295,7 @@ onUnmounted(() => window.removeEventListener('keydown', onKeydown));
|
|
|
295
295
|
<!-- Detail mode -->
|
|
296
296
|
<ConceptDetail
|
|
297
297
|
v-else
|
|
298
|
-
:concept="concept"
|
|
298
|
+
:concept="concept as any"
|
|
299
299
|
:manifest="manifest"
|
|
300
300
|
:edges="edges"
|
|
301
301
|
:adjacent="adjacent"
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* LearnDesignationsView — explains the term/designation vocabulary.
|
|
4
|
+
*
|
|
5
|
+
* Three cards:
|
|
6
|
+
* 1. Normative status (preferred / admitted / deprecated) — ISO 10241-1:2011 §3.4.1.3.
|
|
7
|
+
* Each explicitly allows multiple (per ISO Notes 1).
|
|
8
|
+
* 2. Kinds and forms of term (full form, abbreviated form, borrowed, variant) —
|
|
9
|
+
* ISO 10241-1:2011 §3.4.1.2.
|
|
10
|
+
* 3. Designation types (term / proper name / symbol) with abbreviation subtypes
|
|
11
|
+
* (acronym vs initialism) — ISO 704:2022 §7.
|
|
12
|
+
*
|
|
13
|
+
* Addresses the user's specific concerns:
|
|
14
|
+
* - "preferred/admitted term means, that they can be multiple" → Card 1
|
|
15
|
+
* - "types of acronym" → Card 3 (acronym vs initialism vs symbol)
|
|
16
|
+
*/
|
|
17
|
+
import { useI18n } from '../../i18n';
|
|
18
|
+
import LearnCard from '../../components/learn/LearnCard.vue';
|
|
19
|
+
|
|
20
|
+
const { t } = useI18n();
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<template>
|
|
24
|
+
<div class="learn-designations max-w-5xl mx-auto px-4 py-8">
|
|
25
|
+
<header class="mb-8">
|
|
26
|
+
<h1 class="text-3xl font-serif text-ink-800 dark:text-ink-50 mb-2">
|
|
27
|
+
{{ t('learn.designations.title') }}
|
|
28
|
+
</h1>
|
|
29
|
+
<p class="text-ink-500 dark:text-ink-300 max-w-3xl">{{ t('learn.designations.intro') }}</p>
|
|
30
|
+
</header>
|
|
31
|
+
|
|
32
|
+
<!-- ── Normative status ──────────────────────────────────────── -->
|
|
33
|
+
<section class="mb-12" :aria-label="t('learn.designations.normativeSection')">
|
|
34
|
+
<h2 class="text-xl font-semibold text-ink-700 dark:text-ink-100 mb-4 border-b border-ink-100 dark:border-ink-700 pb-2">
|
|
35
|
+
{{ t('learn.designations.normativeSection') }}
|
|
36
|
+
</h2>
|
|
37
|
+
<p class="text-sm text-ink-500 dark:text-ink-400 mb-4">
|
|
38
|
+
{{ t('learn.designations.normativeIntro') }}
|
|
39
|
+
</p>
|
|
40
|
+
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
41
|
+
<LearnCard
|
|
42
|
+
:title="t('learn.designations.preferred.label')"
|
|
43
|
+
iso-reference="ISO 10241-1:2011 §3.4.1.3.1"
|
|
44
|
+
learn-more-url="https://www.glossarist.org/model/designations"
|
|
45
|
+
>
|
|
46
|
+
<p>{{ t('learn.designations.preferred.meaning') }}</p>
|
|
47
|
+
<p class="mt-3 text-xs italic text-ink-500 dark:text-ink-400">
|
|
48
|
+
{{ t('learn.designations.preferred.multipleNote') }}
|
|
49
|
+
</p>
|
|
50
|
+
<template #example>
|
|
51
|
+
VIM 1.9: <strong>measurement unit</strong> (preferred) — the primary term.
|
|
52
|
+
</template>
|
|
53
|
+
</LearnCard>
|
|
54
|
+
|
|
55
|
+
<LearnCard
|
|
56
|
+
:title="t('learn.designations.admitted.label')"
|
|
57
|
+
iso-reference="ISO 10241-1:2011 §3.4.1.3.2"
|
|
58
|
+
>
|
|
59
|
+
<p>{{ t('learn.designations.admitted.meaning') }}</p>
|
|
60
|
+
<p class="mt-3 text-xs italic text-ink-500 dark:text-ink-400">
|
|
61
|
+
{{ t('learn.designations.admitted.multipleNote') }}
|
|
62
|
+
</p>
|
|
63
|
+
<template #example>
|
|
64
|
+
VIM 1.9: <strong>unit of measurement</strong> (admitted) — a synonym for "measurement unit".
|
|
65
|
+
</template>
|
|
66
|
+
</LearnCard>
|
|
67
|
+
|
|
68
|
+
<LearnCard
|
|
69
|
+
:title="t('learn.designations.deprecated.label')"
|
|
70
|
+
iso-reference="ISO 10241-1:2011 §3.4.1.3.3"
|
|
71
|
+
>
|
|
72
|
+
<p>{{ t('learn.designations.deprecated.meaning') }}</p>
|
|
73
|
+
<p class="mt-3 text-xs italic text-ink-500 dark:text-ink-400">
|
|
74
|
+
{{ t('learn.designations.deprecated.multipleNote') }}
|
|
75
|
+
</p>
|
|
76
|
+
<template #example>
|
|
77
|
+
A term still in use but discouraged, e.g. an outdated spelling or a vendor name
|
|
78
|
+
used as a generic term.
|
|
79
|
+
</template>
|
|
80
|
+
</LearnCard>
|
|
81
|
+
</div>
|
|
82
|
+
</section>
|
|
83
|
+
|
|
84
|
+
<!-- ── Kinds and forms of term ───────────────────────────────── -->
|
|
85
|
+
<section class="mb-12" :aria-label="t('learn.designations.kindsSection')">
|
|
86
|
+
<h2 class="text-xl font-semibold text-ink-700 dark:text-ink-100 mb-4 border-b border-ink-100 dark:border-ink-700 pb-2">
|
|
87
|
+
{{ t('learn.designations.kindsSection') }}
|
|
88
|
+
</h2>
|
|
89
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
90
|
+
<LearnCard
|
|
91
|
+
:title="t('learn.designations.fullForm.label')"
|
|
92
|
+
iso-reference="ISO 10241-1:2011 §3.4.1.2.3"
|
|
93
|
+
>
|
|
94
|
+
<p>{{ t('learn.designations.fullForm.meaning') }}</p>
|
|
95
|
+
<template #example>
|
|
96
|
+
<strong>compact disc</strong> is the full form of "CD".
|
|
97
|
+
</template>
|
|
98
|
+
</LearnCard>
|
|
99
|
+
|
|
100
|
+
<LearnCard
|
|
101
|
+
:title="t('learn.designations.abbreviatedForm.label')"
|
|
102
|
+
iso-reference="ISO 10241-1:2011 §3.4.1.2.4"
|
|
103
|
+
>
|
|
104
|
+
<p>{{ t('learn.designations.abbreviatedForm.meaning') }}</p>
|
|
105
|
+
<p class="mt-3 text-xs italic text-ink-500 dark:text-ink-400">
|
|
106
|
+
{{ t('learn.designations.abbreviatedForm.multipleNote') }}
|
|
107
|
+
</p>
|
|
108
|
+
<template #example>
|
|
109
|
+
<strong>CD</strong> is the abbreviated form of "compact disc".
|
|
110
|
+
World Wide Web has two: <strong>WWW</strong> and <strong>W3</strong>.
|
|
111
|
+
</template>
|
|
112
|
+
</LearnCard>
|
|
113
|
+
|
|
114
|
+
<LearnCard
|
|
115
|
+
:title="t('learn.designations.borrowed.label')"
|
|
116
|
+
iso-reference="ISO 10241-1:2011 §3.4.1.2.1"
|
|
117
|
+
>
|
|
118
|
+
<p>{{ t('learn.designations.borrowed.meaning') }}</p>
|
|
119
|
+
<template #example>
|
|
120
|
+
English "kindergarten" (borrowed from German).
|
|
121
|
+
</template>
|
|
122
|
+
</LearnCard>
|
|
123
|
+
|
|
124
|
+
<LearnCard
|
|
125
|
+
:title="t('learn.designations.variant.label')"
|
|
126
|
+
iso-reference="ISO 10241-1:2011 §3.4.1.2.2"
|
|
127
|
+
>
|
|
128
|
+
<p>{{ t('learn.designations.variant.meaning') }}</p>
|
|
129
|
+
<template #example>
|
|
130
|
+
<strong>colour</strong> (UK) ↔ <strong>color</strong> (US);
|
|
131
|
+
<strong>multi-word term</strong> ↔ <strong>multiword term</strong>.
|
|
132
|
+
</template>
|
|
133
|
+
</LearnCard>
|
|
134
|
+
</div>
|
|
135
|
+
</section>
|
|
136
|
+
|
|
137
|
+
<!-- ── Designation types ─────────────────────────────────────── -->
|
|
138
|
+
<section :aria-label="t('learn.designations.typesSection')">
|
|
139
|
+
<h2 class="text-xl font-semibold text-ink-700 dark:text-ink-100 mb-4 border-b border-ink-100 dark:border-ink-700 pb-2">
|
|
140
|
+
{{ t('learn.designations.typesSection') }}
|
|
141
|
+
</h2>
|
|
142
|
+
<p class="text-sm text-ink-500 dark:text-ink-400 mb-4">
|
|
143
|
+
{{ t('learn.designations.typesIntro') }}
|
|
144
|
+
</p>
|
|
145
|
+
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
|
|
146
|
+
<LearnCard
|
|
147
|
+
:title="t('learn.designations.term.label')"
|
|
148
|
+
iso-reference="ISO 704:2022 §7.3"
|
|
149
|
+
>
|
|
150
|
+
<p>{{ t('learn.designations.term.meaning') }}</p>
|
|
151
|
+
<template #example>
|
|
152
|
+
<strong>system of quantities</strong> (VIM 1.3)
|
|
153
|
+
</template>
|
|
154
|
+
</LearnCard>
|
|
155
|
+
|
|
156
|
+
<LearnCard
|
|
157
|
+
:title="t('learn.designations.acronym.label')"
|
|
158
|
+
iso-reference="ISO 704:2022 §7.3.2"
|
|
159
|
+
>
|
|
160
|
+
<p>{{ t('learn.designations.acronym.meaning') }}</p>
|
|
161
|
+
<template #example>
|
|
162
|
+
<strong>laser</strong> — light amplification by stimulated emission of radiation.
|
|
163
|
+
Pronounced as one word.
|
|
164
|
+
</template>
|
|
165
|
+
</LearnCard>
|
|
166
|
+
|
|
167
|
+
<LearnCard
|
|
168
|
+
:title="t('learn.designations.initialism.label')"
|
|
169
|
+
iso-reference="ISO 704:2022 §7.3.2"
|
|
170
|
+
>
|
|
171
|
+
<p>{{ t('learn.designations.initialism.meaning') }}</p>
|
|
172
|
+
<template #example>
|
|
173
|
+
<strong>OIML</strong> — Organisation Internationale de Métrologie Légale.
|
|
174
|
+
Each letter pronounced separately.
|
|
175
|
+
</template>
|
|
176
|
+
</LearnCard>
|
|
177
|
+
|
|
178
|
+
<LearnCard
|
|
179
|
+
:title="t('learn.designations.symbol.label')"
|
|
180
|
+
iso-reference="ISO 704:2022 §7.5 + ISO 80000"
|
|
181
|
+
>
|
|
182
|
+
<p>{{ t('learn.designations.symbol.meaning') }}</p>
|
|
183
|
+
<template #example>
|
|
184
|
+
<strong>kg</strong> for kilogram. <strong>m/s</strong> for metre per second.
|
|
185
|
+
</template>
|
|
186
|
+
</LearnCard>
|
|
187
|
+
</div>
|
|
188
|
+
</section>
|
|
189
|
+
</div>
|
|
190
|
+
</template>
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* LearnIndexView — entry point for the /learn section.
|
|
4
|
+
*
|
|
5
|
+
* Cards link to each topic with a one-line description. Phase 1 pages
|
|
6
|
+
* (relationships, designations, statuses) are linked; Phase 2 pages
|
|
7
|
+
* are not yet wired.
|
|
8
|
+
*
|
|
9
|
+
* Reader-focused: this section explains how to READ this site and the
|
|
10
|
+
* terminology behind its labels. For authoring datasets in glossarist
|
|
11
|
+
* format, see glossarist.org.
|
|
12
|
+
*/
|
|
13
|
+
import { useI18n } from '../../i18n';
|
|
14
|
+
import LearnCard from '../../components/learn/LearnCard.vue';
|
|
15
|
+
|
|
16
|
+
const { t } = useI18n();
|
|
17
|
+
|
|
18
|
+
interface TopicLink {
|
|
19
|
+
to: string;
|
|
20
|
+
title: string;
|
|
21
|
+
description: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const phase1Topics: readonly TopicLink[] = [
|
|
25
|
+
{
|
|
26
|
+
to: '/learn/relationships',
|
|
27
|
+
title: t('learn.relationships.title'),
|
|
28
|
+
description: t('learn.relationships.short'),
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
to: '/learn/designations',
|
|
32
|
+
title: t('learn.designations.title'),
|
|
33
|
+
description: t('learn.designations.short'),
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
to: '/learn/statuses',
|
|
37
|
+
title: t('learn.statuses.title'),
|
|
38
|
+
description: t('learn.statuses.short'),
|
|
39
|
+
},
|
|
40
|
+
];
|
|
41
|
+
</script>
|
|
42
|
+
|
|
43
|
+
<template>
|
|
44
|
+
<div class="learn-index max-w-5xl mx-auto px-4 py-8">
|
|
45
|
+
<header class="mb-8">
|
|
46
|
+
<h1 class="text-3xl font-serif text-ink-800 dark:text-ink-50 mb-2">
|
|
47
|
+
{{ t('nav.learn') }}
|
|
48
|
+
</h1>
|
|
49
|
+
<p class="text-ink-500 dark:text-ink-300 max-w-2xl">{{ t('learn.intro') }}</p>
|
|
50
|
+
</header>
|
|
51
|
+
|
|
52
|
+
<nav class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4" aria-label="Learn topics">
|
|
53
|
+
<RouterLink v-for="topic in phase1Topics" :key="topic.to" :to="topic.to"
|
|
54
|
+
class="learn-topic-link block no-underline">
|
|
55
|
+
<LearnCard :title="topic.title">
|
|
56
|
+
<div class="flex items-center justify-between">
|
|
57
|
+
<h2 class="text-base font-semibold text-ink-800 dark:text-ink-50">{{ topic.title }}</h2>
|
|
58
|
+
<span class="text-ink-300 dark:text-ink-500 text-sm">→</span>
|
|
59
|
+
</div>
|
|
60
|
+
<p class="text-sm text-ink-600 dark:text-ink-300 mt-1">{{ topic.description }}</p>
|
|
61
|
+
</LearnCard>
|
|
62
|
+
</RouterLink>
|
|
63
|
+
</nav>
|
|
64
|
+
|
|
65
|
+
<p class="text-xs text-ink-400 dark:text-ink-500 mt-8">
|
|
66
|
+
{{ t('learn.glossaristOrgNote') }}
|
|
67
|
+
</p>
|
|
68
|
+
</div>
|
|
69
|
+
</template>
|
|
70
|
+
|
|
71
|
+
<style scoped>
|
|
72
|
+
.learn-topic-link:hover :deep(.learn-card) {
|
|
73
|
+
border-color: var(--color-accent, #0d9488);
|
|
74
|
+
}
|
|
75
|
+
</style>
|