@commonpub/layer 0.3.37 → 0.4.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.
- package/components/CookieConsent.vue +91 -0
- package/composables/useCookieConsent.ts +117 -0
- package/composables/useTheme.ts +45 -24
- package/layouts/admin.vue +1 -0
- package/layouts/default.vue +6 -1
- package/nuxt.config.ts +17 -0
- package/package.json +7 -6
- package/pages/admin/theme.vue +500 -0
- package/pages/auth/register.vue +22 -0
- package/pages/cookies.vue +186 -0
- package/pages/privacy.vue +207 -0
- package/pages/settings/account.vue +9 -0
- package/pages/settings/appearance.vue +143 -38
- package/pages/terms.vue +168 -0
- package/plugins/theme.ts +32 -0
- package/server/api/admin/settings.get.ts +7 -3
- package/server/api/admin/settings.put.ts +6 -1
- package/server/api/auth/delete-user.post.ts +55 -0
- package/server/api/auth/export-data.get.ts +15 -0
- package/server/middleware/theme.ts +34 -0
- package/server/utils/instanceTheme.ts +67 -0
- package/theme/agora-dark.css +157 -0
- package/theme/agora.css +156 -0
- package/utils/themeConfig.ts +39 -0
package/theme/agora.css
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
@layer commonpub {
|
|
2
|
+
/* ===========================================
|
|
3
|
+
CommonPub Agora Theme — Light
|
|
4
|
+
Warm institutional aesthetic: parchment
|
|
5
|
+
backgrounds, green accent, serif display
|
|
6
|
+
font, offset shadows.
|
|
7
|
+
=========================================== */
|
|
8
|
+
|
|
9
|
+
[data-theme="agora"] {
|
|
10
|
+
/* === SURFACES (warm, paper-like) === */
|
|
11
|
+
--bg: #f7f4ed;
|
|
12
|
+
--surface: #faf8f3;
|
|
13
|
+
--surface2: #ece8de;
|
|
14
|
+
--surface3: #e2ddd2;
|
|
15
|
+
|
|
16
|
+
--color-surface: var(--surface);
|
|
17
|
+
--color-surface-alt: var(--surface2);
|
|
18
|
+
--color-surface-raised: var(--surface);
|
|
19
|
+
--color-surface-overlay: rgba(26, 26, 26, 0.5);
|
|
20
|
+
--color-surface-overlay-light: rgba(26, 26, 26, 0.4);
|
|
21
|
+
--color-surface-scrim: rgba(247, 244, 237, 0.75);
|
|
22
|
+
--color-surface-hover: var(--surface2);
|
|
23
|
+
--color-bg-subtle: var(--bg);
|
|
24
|
+
|
|
25
|
+
/* === TEXT (ink gradations) === */
|
|
26
|
+
--text: #1a1a1a;
|
|
27
|
+
--text-dim: #4a4a44;
|
|
28
|
+
--text-faint: #7a7a72;
|
|
29
|
+
|
|
30
|
+
--color-text: var(--text);
|
|
31
|
+
--color-text-secondary: var(--text-dim);
|
|
32
|
+
--color-text-muted: var(--text-faint);
|
|
33
|
+
--color-text-inverse: #f7f4ed;
|
|
34
|
+
|
|
35
|
+
/* === BORDERS (warm) === */
|
|
36
|
+
--border: #1a1a1a;
|
|
37
|
+
--border2: #d4cfc4;
|
|
38
|
+
|
|
39
|
+
--color-border: var(--border2);
|
|
40
|
+
--color-border-strong: var(--border);
|
|
41
|
+
--color-border-focus: var(--accent);
|
|
42
|
+
|
|
43
|
+
/* === ACCENT (commons green) === */
|
|
44
|
+
--accent: #3d8b5e;
|
|
45
|
+
--accent-bg: rgba(61, 139, 94, 0.08);
|
|
46
|
+
--accent-bg-strong: rgba(61, 139, 94, 0.2);
|
|
47
|
+
--accent-bg-heavy: rgba(61, 139, 94, 0.4);
|
|
48
|
+
--accent-bg-solid: rgba(61, 139, 94, 0.6);
|
|
49
|
+
--accent-border: rgba(61, 139, 94, 0.25);
|
|
50
|
+
--accent-focus-ring: 0 0 0 3px rgba(61, 139, 94, 0.12);
|
|
51
|
+
|
|
52
|
+
--color-primary: var(--accent);
|
|
53
|
+
--color-primary-hover: #348050;
|
|
54
|
+
--color-primary-text: #ffffff;
|
|
55
|
+
--color-on-primary: #ffffff;
|
|
56
|
+
--color-accent: var(--accent);
|
|
57
|
+
--color-accent-hover: #348050;
|
|
58
|
+
--color-accent-text: #ffffff;
|
|
59
|
+
--color-on-accent: #ffffff;
|
|
60
|
+
--color-accent-bg: var(--accent-bg);
|
|
61
|
+
--color-accent-border: var(--accent-border);
|
|
62
|
+
|
|
63
|
+
/* === SEMANTIC COLORS (warm palette) === */
|
|
64
|
+
--green: #3d8b5e;
|
|
65
|
+
--green-bg: rgba(61, 139, 94, 0.08);
|
|
66
|
+
--green-border: rgba(61, 139, 94, 0.25);
|
|
67
|
+
|
|
68
|
+
--yellow: #c4882a;
|
|
69
|
+
--yellow-bg: rgba(196, 136, 42, 0.08);
|
|
70
|
+
--yellow-border: rgba(196, 136, 42, 0.25);
|
|
71
|
+
|
|
72
|
+
--red: #c4443a;
|
|
73
|
+
--red-bg: rgba(196, 68, 58, 0.08);
|
|
74
|
+
--red-border: rgba(196, 68, 58, 0.25);
|
|
75
|
+
|
|
76
|
+
--purple: #7b5ea7;
|
|
77
|
+
--purple-bg: rgba(123, 94, 167, 0.08);
|
|
78
|
+
--purple-border: rgba(123, 94, 167, 0.25);
|
|
79
|
+
|
|
80
|
+
--teal: #2a9d8f;
|
|
81
|
+
--teal-bg: rgba(42, 157, 143, 0.08);
|
|
82
|
+
--teal-border: rgba(42, 157, 143, 0.25);
|
|
83
|
+
|
|
84
|
+
--pink: #b85a7a;
|
|
85
|
+
--pink-bg: rgba(184, 90, 122, 0.08);
|
|
86
|
+
--pink-border: rgba(184, 90, 122, 0.25);
|
|
87
|
+
|
|
88
|
+
--color-success: var(--green);
|
|
89
|
+
--color-warning: var(--yellow);
|
|
90
|
+
--color-error: var(--red);
|
|
91
|
+
--color-info: #4a7fb8;
|
|
92
|
+
--color-success-bg: var(--green-bg);
|
|
93
|
+
--color-warning-bg: var(--yellow-bg);
|
|
94
|
+
--color-error-bg: var(--red-bg);
|
|
95
|
+
--color-info-bg: rgba(74, 127, 184, 0.08);
|
|
96
|
+
|
|
97
|
+
/* === OVERLAYS === */
|
|
98
|
+
--color-badge-overlay: rgba(26, 26, 26, 0.75);
|
|
99
|
+
|
|
100
|
+
/* === INTERACTIVE === */
|
|
101
|
+
--color-link: var(--accent);
|
|
102
|
+
--color-link-hover: #2a6342;
|
|
103
|
+
|
|
104
|
+
/* === TYPOGRAPHY (warm, distinctive) === */
|
|
105
|
+
--font-sans: 'Work Sans', system-ui, -apple-system, sans-serif;
|
|
106
|
+
--font-mono: 'JetBrains Mono', ui-monospace, monospace;
|
|
107
|
+
--font-display: 'Fraunces', Georgia, 'Times New Roman', serif;
|
|
108
|
+
|
|
109
|
+
--font-heading: var(--font-display);
|
|
110
|
+
--font-body: var(--font-sans);
|
|
111
|
+
|
|
112
|
+
/* Font Sizes (Agora scale) */
|
|
113
|
+
--text-xs: 0.6875rem; /* 11px */
|
|
114
|
+
--text-sm: 0.8125rem; /* 13px */
|
|
115
|
+
--text-base: 0.9375rem; /* 15px */
|
|
116
|
+
--text-md: 1.0625rem; /* 17px */
|
|
117
|
+
--text-lg: 1.25rem; /* 20px */
|
|
118
|
+
--text-xl: 1.5rem; /* 24px */
|
|
119
|
+
--text-2xl: 1.875rem; /* 30px */
|
|
120
|
+
--text-3xl: 2.375rem; /* 38px */
|
|
121
|
+
--text-4xl: 3rem; /* 48px */
|
|
122
|
+
--text-5xl: 4rem; /* 64px */
|
|
123
|
+
--text-label: 0.625rem; /* 10px — monospace UI labels */
|
|
124
|
+
|
|
125
|
+
/* Line Heights */
|
|
126
|
+
--leading-tight: 1.15;
|
|
127
|
+
--leading-snug: 1.35;
|
|
128
|
+
--leading-normal: 1.7;
|
|
129
|
+
--leading-relaxed: 1.9;
|
|
130
|
+
|
|
131
|
+
/* Letter Spacing */
|
|
132
|
+
--tracking-tight: -0.02em;
|
|
133
|
+
--tracking-normal: 0;
|
|
134
|
+
--tracking-wide: 0.06em;
|
|
135
|
+
--tracking-wider: 0.1em;
|
|
136
|
+
--tracking-widest: 0.16em;
|
|
137
|
+
|
|
138
|
+
/* === SHADOWS (offset, warm ink) === */
|
|
139
|
+
--shadow-sm: 2px 2px 0 var(--border);
|
|
140
|
+
--shadow-md: 4px 4px 0 var(--border);
|
|
141
|
+
--shadow-lg: 6px 6px 0 var(--border);
|
|
142
|
+
--shadow-xl: 8px 8px 0 var(--border);
|
|
143
|
+
--shadow-accent: 4px 4px 0 var(--accent);
|
|
144
|
+
|
|
145
|
+
/* === FOCUS === */
|
|
146
|
+
--focus-ring: var(--shadow-accent);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/* === CONTENT TYPE BADGE COLORS (Agora palette) === */
|
|
150
|
+
[data-theme="agora"] [data-content-type="article"] { --badge-color: #4a7fb8; --badge-bg: rgba(74, 127, 184, 0.08); }
|
|
151
|
+
[data-theme="agora"] [data-content-type="blog"] { --badge-color: #3d8b5e; --badge-bg: rgba(61, 139, 94, 0.08); }
|
|
152
|
+
[data-theme="agora"] [data-content-type="project"] { --badge-color: #7b5ea7; --badge-bg: rgba(123, 94, 167, 0.08); }
|
|
153
|
+
[data-theme="agora"] [data-content-type="explainer"] { --badge-color: #2a9d8f; --badge-bg: rgba(42, 157, 143, 0.08); }
|
|
154
|
+
[data-theme="agora"] [data-content-type="video"] { --badge-color: #c4443a; --badge-bg: rgba(196, 68, 58, 0.08); }
|
|
155
|
+
[data-theme="agora"] [data-content-type="tutorial"] { --badge-color: #c4882a; --badge-bg: rgba(196, 136, 42, 0.08); }
|
|
156
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared theme family configuration.
|
|
3
|
+
* Used by both server (instanceTheme.ts) and client (useTheme.ts).
|
|
4
|
+
*
|
|
5
|
+
* To add a new theme:
|
|
6
|
+
* 1. Create the CSS file(s) in packages/ui/theme/
|
|
7
|
+
* 2. Register in packages/ui/src/theme.ts BUILT_IN_THEMES
|
|
8
|
+
* 3. Add the family mapping here
|
|
9
|
+
* 4. Add theme ID to VALID_IDS in server/utils/instanceTheme.ts
|
|
10
|
+
* 5. Add CSS import in layers/base/nuxt.config.ts
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/** Map every theme ID to its family name */
|
|
14
|
+
export const THEME_TO_FAMILY: Record<string, string> = {
|
|
15
|
+
base: 'classic',
|
|
16
|
+
dark: 'classic',
|
|
17
|
+
generics: 'generics',
|
|
18
|
+
agora: 'agora',
|
|
19
|
+
'agora-dark': 'agora',
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/** Light/dark variants for each family */
|
|
23
|
+
export const FAMILY_VARIANTS: Record<string, { light: string; dark: string }> = {
|
|
24
|
+
classic: { light: 'base', dark: 'dark' },
|
|
25
|
+
agora: { light: 'agora', dark: 'agora-dark' },
|
|
26
|
+
generics: { light: 'generics', dark: 'generics' },
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/** Whether a theme ID is a dark theme */
|
|
30
|
+
export const IS_DARK: Record<string, boolean> = {
|
|
31
|
+
base: false,
|
|
32
|
+
dark: true,
|
|
33
|
+
generics: true,
|
|
34
|
+
agora: false,
|
|
35
|
+
'agora-dark': true,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/** All valid theme IDs */
|
|
39
|
+
export const VALID_THEME_IDS = new Set(Object.keys(THEME_TO_FAMILY));
|