@press2ai/theme-specialist-glossy 0.4.3 → 0.5.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/package.json +1 -1
- package/src/styles/glossy.css +138 -78
- package/src/templates/catalog.ts +26 -7
- package/src/templates/profile-card.ts +7 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@press2ai/theme-specialist-glossy",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Classless, AI-first theme inspired by Stripe. Framework-agnostic templates (Hono, Astro, raw HTML). Semantic HTML, Schema.org microdata, JSON-LD — built for LLM crawlers.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
package/src/styles/glossy.css
CHANGED
|
@@ -6,18 +6,19 @@
|
|
|
6
6
|
--t-xs: 0.8rem; --t-sm: 1rem; --t-md: 1.25rem; --t-lg: 1.563rem; --t-xl: 1.953rem; --t-2xl: 2.441rem;
|
|
7
7
|
--container: 1080px; --pad: var(--g4);
|
|
8
8
|
--w-6: 495px; --w-8: 667px; --w-10: 839px; --measure: 38rem;
|
|
9
|
-
--white: #ffffff; --bg: #
|
|
9
|
+
--white: #ffffff; --bg: #f8f9fb; --card: #ffffff;
|
|
10
10
|
--ink: #1a1a2e; --ink-2: #4a4a68; --ink-3: #8b8ba3;
|
|
11
11
|
--line: #e8e8ef; --line-h: #d0d0de;
|
|
12
|
-
--violet: #7c5cfc; --violet-s: #f3f0ff;
|
|
12
|
+
--violet: #7c5cfc; --violet-s: #f3f0ff; --violet-glow: rgba(124,92,252,.18);
|
|
13
13
|
--teal: #0d9488; --teal-s: #ecfdf5;
|
|
14
14
|
--rose: #e11d63; --rose-s: #fff1f5;
|
|
15
15
|
--amber: #d97706; --amber-s: #fffbeb;
|
|
16
16
|
--sky: #0284c7; --sky-s: #f0f9ff;
|
|
17
|
-
--r:
|
|
17
|
+
--r: 16px; --r-lg: 20px; --pill: 999px;
|
|
18
18
|
--shadow: 0 1px 3px rgba(0,0,0,.04);
|
|
19
|
-
--shadow-
|
|
20
|
-
--
|
|
19
|
+
--shadow-md: 0 4px 16px rgba(0,0,0,.06), 0 1px 3px rgba(0,0,0,.04);
|
|
20
|
+
--shadow-up: 0 8px 24px rgba(0,0,0,.08), 0 2px 6px rgba(0,0,0,.03);
|
|
21
|
+
--ease: 200ms cubic-bezier(.4,0,.2,1);
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
*, *::before, *::after { box-sizing: border-box; margin: 0; }
|
|
@@ -28,12 +29,12 @@ body {
|
|
|
28
29
|
font-feature-settings: 'cv11', 'ss01';
|
|
29
30
|
color: var(--ink);
|
|
30
31
|
background: var(--bg);
|
|
31
|
-
line-height: 1.
|
|
32
|
+
line-height: 1.6;
|
|
32
33
|
overflow-x: clip;
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
h1, h2, h3 { color: var(--ink); letter-spacing: -0.02em; }
|
|
36
|
-
h1 { font-size: clamp(var(--t-xl),
|
|
37
|
+
h1 { font-size: clamp(var(--t-xl), 5vw, var(--t-2xl)); font-weight: 800; line-height: 1.1; letter-spacing: -0.035em; margin-bottom: var(--g4); }
|
|
37
38
|
h2 { font-size: var(--t-lg); font-weight: 700; line-height: 1.25; margin-bottom: var(--g3); }
|
|
38
39
|
h3 { font-size: var(--t-md); font-weight: 600; line-height: 1.35; margin-bottom: var(--g2); }
|
|
39
40
|
p { font-size: var(--t-sm); line-height: 1.6; color: var(--ink-2); margin-bottom: var(--g3); max-width: var(--measure); }
|
|
@@ -45,13 +46,13 @@ strong { color: var(--ink); font-weight: 600; }
|
|
|
45
46
|
/* Header */
|
|
46
47
|
body > header {
|
|
47
48
|
position: sticky; top: 0; z-index: 50;
|
|
48
|
-
background: rgba(255,255,255,.
|
|
49
|
-
backdrop-filter: blur(
|
|
49
|
+
background: rgba(255,255,255,.82);
|
|
50
|
+
backdrop-filter: saturate(180%) blur(16px); -webkit-backdrop-filter: saturate(180%) blur(16px);
|
|
50
51
|
border-bottom: 1px solid var(--line);
|
|
51
52
|
}
|
|
52
53
|
body > header nav {
|
|
53
54
|
max-width: var(--container); margin-inline: auto; padding-inline: var(--pad);
|
|
54
|
-
height:
|
|
55
|
+
height: 56px; display: flex; align-items: center; justify-content: space-between;
|
|
55
56
|
}
|
|
56
57
|
body > header nav a { color: var(--ink-2); text-decoration: none; font-size: var(--t-sm); font-weight: 500; }
|
|
57
58
|
body > header nav a strong { font-size: var(--t-md); font-weight: 700; color: var(--ink); }
|
|
@@ -59,10 +60,10 @@ body > header nav a strong { font-size: var(--t-md); font-weight: 700; color: va
|
|
|
59
60
|
/* Main */
|
|
60
61
|
main {
|
|
61
62
|
max-width: var(--container); margin-inline: auto;
|
|
62
|
-
padding-inline: var(--pad); padding-top: 0; padding-bottom: var(--
|
|
63
|
+
padding-inline: var(--pad); padding-top: 0; padding-bottom: var(--g7);
|
|
63
64
|
}
|
|
64
65
|
main > h1:first-child, main > article:first-child { margin-top: var(--g6); }
|
|
65
|
-
main > section { margin-bottom: var(--
|
|
66
|
+
main > section { margin-bottom: var(--g7); }
|
|
66
67
|
|
|
67
68
|
/* Footer */
|
|
68
69
|
body > footer { border-top: 1px solid var(--line); padding: var(--g5) 0; text-align: center; }
|
|
@@ -71,42 +72,64 @@ body > footer a { color: var(--violet); }
|
|
|
71
72
|
|
|
72
73
|
/* Hero */
|
|
73
74
|
hgroup {
|
|
74
|
-
position: relative; text-align: center;
|
|
75
|
-
padding: var(--
|
|
76
|
-
margin: 0 calc(50% - 50vw) var(--
|
|
75
|
+
position: relative; text-align: center; isolation: isolate; overflow: hidden;
|
|
76
|
+
padding: var(--g7) var(--pad) var(--g6);
|
|
77
|
+
margin: 0 calc(50% - 50vw) var(--g7) calc(50% - 50vw);
|
|
78
|
+
background:
|
|
79
|
+
radial-gradient(ellipse 70% 50% at 20% 30%, var(--violet-glow) 0%, transparent 60%),
|
|
80
|
+
radial-gradient(ellipse 50% 60% at 80% 20%, rgba(13,148,136,.12) 0%, transparent 55%),
|
|
81
|
+
radial-gradient(ellipse 60% 40% at 50% 100%, rgba(225,29,99,.08) 0%, transparent 50%),
|
|
82
|
+
linear-gradient(180deg, #fff 0%, var(--bg) 100%);
|
|
77
83
|
border-bottom: 1px solid var(--line);
|
|
78
84
|
}
|
|
85
|
+
hgroup::before {
|
|
86
|
+
content: ''; position: absolute; inset: 0;
|
|
87
|
+
background-image:
|
|
88
|
+
linear-gradient(rgba(124,92,252,.04) 1px, transparent 1px),
|
|
89
|
+
linear-gradient(90deg, rgba(124,92,252,.04) 1px, transparent 1px);
|
|
90
|
+
background-size: 48px 48px;
|
|
91
|
+
mask-image: radial-gradient(ellipse 60% 50% at 50% 40%, black 0%, transparent 70%);
|
|
92
|
+
-webkit-mask-image: radial-gradient(ellipse 60% 50% at 50% 40%, black 0%, transparent 70%);
|
|
93
|
+
z-index: -1;
|
|
94
|
+
}
|
|
79
95
|
hgroup > * { position: relative; }
|
|
80
96
|
hgroup > p:first-child { display: inline-flex; margin-bottom: var(--g4); padding: 0; }
|
|
81
97
|
hgroup > p:first-child small {
|
|
82
98
|
display: inline-flex; align-items: center; gap: var(--g1);
|
|
83
|
-
background:
|
|
99
|
+
background: rgba(255,255,255,.7); backdrop-filter: blur(8px);
|
|
100
|
+
padding: var(--g1) var(--g2); border: 1px solid var(--line);
|
|
84
101
|
border-radius: var(--pill); font-size: var(--t-xs); font-weight: 600; color: var(--teal);
|
|
102
|
+
box-shadow: var(--shadow);
|
|
85
103
|
}
|
|
86
|
-
hgroup > p:first-child small::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background:
|
|
87
|
-
hgroup h1 { max-width:
|
|
88
|
-
hgroup p { font-size: var(--t-md); line-height: 1.
|
|
89
|
-
|
|
104
|
+
hgroup > p:first-child small::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: #00d24a; box-shadow: 0 0 0 3px rgba(0,210,74,.2); }
|
|
105
|
+
hgroup h1 { max-width: 18ch; margin: 0 auto var(--g4); color: var(--ink); }
|
|
106
|
+
hgroup p { font-size: var(--t-md); line-height: 1.55; color: var(--ink-2); max-width: var(--measure); margin: 0 auto 0; }
|
|
107
|
+
|
|
108
|
+
/* Hero CTAs */
|
|
109
|
+
.hero-ctas {
|
|
90
110
|
display: flex; gap: var(--g2); flex-wrap: wrap; justify-content: center;
|
|
91
111
|
margin-top: var(--g5); margin-bottom: 0;
|
|
92
112
|
}
|
|
93
|
-
|
|
94
|
-
display: inline-flex; align-items: center; height:
|
|
113
|
+
.cta-primary, .cta-secondary {
|
|
114
|
+
display: inline-flex; align-items: center; height: 48px; padding: 0 var(--g4);
|
|
95
115
|
border-radius: var(--pill); font-weight: 600; font-size: var(--t-sm); transition: all var(--ease);
|
|
96
116
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
117
|
+
.cta-primary {
|
|
118
|
+
background: var(--violet); color: var(--white);
|
|
119
|
+
box-shadow: 0 4px 14px var(--violet-glow);
|
|
120
|
+
}
|
|
121
|
+
.cta-primary:hover { background: var(--ink); color: var(--white); transform: translateY(-1px); box-shadow: 0 6px 20px rgba(26,26,46,.2); }
|
|
122
|
+
.cta-secondary { background: var(--white); color: var(--ink); border: 1px solid var(--line); }
|
|
123
|
+
.cta-secondary:hover { border-color: var(--line-h); background: var(--bg); }
|
|
101
124
|
|
|
102
125
|
/* Search */
|
|
103
126
|
form[role="search"] {
|
|
104
|
-
display: flex; max-width: var(--w-6); height:
|
|
127
|
+
display: flex; max-width: var(--w-6); height: 52px;
|
|
105
128
|
margin: var(--g5) auto 0; background: var(--white);
|
|
106
129
|
border: 1px solid var(--line); border-radius: var(--pill);
|
|
107
|
-
overflow: hidden; box-shadow: var(--shadow-
|
|
130
|
+
overflow: hidden; box-shadow: var(--shadow-md); transition: all var(--ease);
|
|
108
131
|
}
|
|
109
|
-
form[role="search"]:focus-within { border-color: var(--violet); }
|
|
132
|
+
form[role="search"]:focus-within { border-color: var(--violet); box-shadow: 0 4px 16px var(--violet-glow); }
|
|
110
133
|
form[role="search"] input {
|
|
111
134
|
flex: 1; min-width: 0; border: none; background: transparent; color: var(--ink);
|
|
112
135
|
padding: 0 var(--g3); font-size: var(--t-sm); font-family: var(--font); outline: none;
|
|
@@ -114,29 +137,34 @@ form[role="search"] input {
|
|
|
114
137
|
}
|
|
115
138
|
form[role="search"] input::placeholder { color: var(--ink-3); }
|
|
116
139
|
form[role="search"] button {
|
|
117
|
-
flex-shrink: 0; border: none; background: var(--violet); color: var(--white);
|
|
140
|
+
flex-shrink: 0; height: 100%; border: none; background: var(--violet); color: var(--white);
|
|
118
141
|
padding: 0 var(--g4); font-size: var(--t-sm); font-weight: 600;
|
|
119
142
|
font-family: var(--font); cursor: pointer; transition: background var(--ease);
|
|
120
143
|
}
|
|
121
144
|
form[role="search"] button:hover { background: var(--ink); }
|
|
122
145
|
|
|
123
146
|
/* Stats */
|
|
147
|
+
section[aria-label] > p { text-align: center; font-size: var(--t-sm); color: var(--ink-2); margin: 0 auto var(--g4); max-width: var(--measure); }
|
|
124
148
|
section:has(> dl) { margin-bottom: 0; }
|
|
125
149
|
section > dl {
|
|
126
|
-
display: grid; grid-template-columns: repeat(auto-fit, minmax(
|
|
127
|
-
padding: var(--g5)
|
|
150
|
+
display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: var(--g4);
|
|
151
|
+
padding: var(--g5); margin: 0 auto var(--g7); max-width: var(--w-8);
|
|
128
152
|
background: var(--white); border: 1px solid var(--line); border-radius: var(--r-lg);
|
|
153
|
+
box-shadow: var(--shadow-md);
|
|
129
154
|
}
|
|
130
155
|
section > dl div { text-align: center; }
|
|
156
|
+
.stat-icon { display: flex; align-items: center; justify-content: center; width: 40px; height: 40px; margin: 0 auto var(--g2); background: var(--violet-s); border-radius: 50%; color: var(--violet); }
|
|
157
|
+
.stat-icon svg { width: 20px; height: 20px; }
|
|
131
158
|
section > dl dt { font-size: var(--t-xl); font-weight: 800; line-height: 1.2; color: var(--violet); }
|
|
132
|
-
section > dl dd { margin: 0; font-size: var(--t-xs); line-height: 1.5; color: var(--ink-3); font-weight: 500; text-transform: uppercase; letter-spacing: 0.06em; }
|
|
159
|
+
section > dl dd { margin: var(--g1) 0 0; font-size: var(--t-xs); line-height: 1.5; color: var(--ink-3); font-weight: 500; text-transform: uppercase; letter-spacing: 0.06em; }
|
|
133
160
|
|
|
134
161
|
/* Category pills */
|
|
135
|
-
nav[aria-label] { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--g2); margin-bottom: var(--
|
|
162
|
+
nav[aria-label] { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--g2); margin-bottom: var(--g7); }
|
|
136
163
|
nav[aria-label] a {
|
|
137
|
-
display: inline-flex; align-items: center; height:
|
|
164
|
+
display: inline-flex; align-items: center; height: 36px; padding: 0 var(--g3);
|
|
138
165
|
border-radius: var(--pill); font-size: var(--t-xs); font-weight: 500;
|
|
139
|
-
background: var(--white); border: 1px solid var(--line); color: var(--ink-2);
|
|
166
|
+
background: var(--white); border: 1px solid var(--line); color: var(--ink-2);
|
|
167
|
+
transition: all var(--ease); box-shadow: var(--shadow);
|
|
140
168
|
}
|
|
141
169
|
nav[aria-label] a:nth-child(5n+1):hover { border-color: var(--violet); color: var(--violet); background: var(--violet-s); }
|
|
142
170
|
nav[aria-label] a:nth-child(5n+2):hover { border-color: var(--teal); color: var(--teal); background: var(--teal-s); }
|
|
@@ -145,18 +173,20 @@ nav[aria-label] a:nth-child(5n+4):hover { border-color: var(--amber); color: var
|
|
|
145
173
|
nav[aria-label] a:nth-child(5n+5):hover { border-color: var(--sky); color: var(--sky); background: var(--sky-s); }
|
|
146
174
|
|
|
147
175
|
/* Steps */
|
|
148
|
-
section:has(> ol) > h2 { text-align: center; }
|
|
176
|
+
section:has(> ol) > h2 { text-align: center; margin-bottom: var(--g5); }
|
|
149
177
|
section > ol {
|
|
150
178
|
list-style: none; padding: 0; display: grid;
|
|
151
|
-
grid-template-columns: repeat(auto-fit, minmax(
|
|
179
|
+
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--g4); margin: 0; counter-reset: steps;
|
|
152
180
|
}
|
|
153
181
|
section > ol li {
|
|
154
182
|
counter-increment: steps; background: var(--white); border: 1px solid var(--line);
|
|
155
|
-
border-radius: var(--r-lg); padding: var(--g5) var(--
|
|
183
|
+
border-radius: var(--r-lg); padding: var(--g5) var(--g4); text-align: center;
|
|
184
|
+
box-shadow: var(--shadow); transition: all var(--ease);
|
|
156
185
|
}
|
|
186
|
+
section > ol li:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
|
|
157
187
|
section > ol li::before {
|
|
158
188
|
content: counter(steps); display: flex; align-items: center; justify-content: center;
|
|
159
|
-
width:
|
|
189
|
+
width: 48px; height: 48px; margin: 0 auto var(--g3);
|
|
160
190
|
border-radius: 50%; font-size: var(--t-md); font-weight: 700;
|
|
161
191
|
}
|
|
162
192
|
section > ol li:nth-child(5n+1)::before { background: var(--violet-s); color: var(--violet); }
|
|
@@ -164,42 +194,64 @@ section > ol li:nth-child(5n+2)::before { background: var(--teal-s); color: var(
|
|
|
164
194
|
section > ol li:nth-child(5n+3)::before { background: var(--amber-s); color: var(--amber); }
|
|
165
195
|
section > ol li:nth-child(5n+4)::before { background: var(--rose-s); color: var(--rose); }
|
|
166
196
|
section > ol li:nth-child(5n+5)::before { background: var(--sky-s); color: var(--sky); }
|
|
167
|
-
section > ol li strong { display: block; font-size: var(--t-
|
|
168
|
-
section > ol li span { font-size: var(--t-
|
|
197
|
+
section > ol li strong { display: block; font-size: var(--t-md); line-height: 1.4; margin-bottom: var(--g1); color: var(--ink); }
|
|
198
|
+
section > ol li span { font-size: var(--t-sm); line-height: 1.5; color: var(--ink-3); }
|
|
169
199
|
|
|
170
200
|
/* Trainer cards */
|
|
171
201
|
section:has(> article[itemscope]) {
|
|
172
|
-
display: grid; grid-template-columns: repeat(auto-fill, minmax(
|
|
202
|
+
display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: var(--g4);
|
|
173
203
|
}
|
|
174
204
|
section:has(> article[itemscope]) > h2 { grid-column: 1 / -1; margin-bottom: var(--g4); }
|
|
175
205
|
article[itemscope] {
|
|
176
|
-
|
|
177
|
-
border-radius: var(--r-lg); padding: var(--g4)
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
article[itemscope]:
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
206
|
+
position: relative; background: var(--card); border: 1px solid var(--line);
|
|
207
|
+
border-radius: var(--r-lg); padding: var(--g4);
|
|
208
|
+
display: flex; flex-direction: column;
|
|
209
|
+
box-shadow: var(--shadow); transition: all var(--ease);
|
|
210
|
+
}
|
|
211
|
+
article[itemscope]:hover { transform: translateY(-3px); box-shadow: var(--shadow-up); border-color: var(--line-h); }
|
|
212
|
+
|
|
213
|
+
/* Card avatar */
|
|
214
|
+
.card-avatar {
|
|
215
|
+
width: 48px; height: 48px; border-radius: 50%;
|
|
216
|
+
display: flex; align-items: center; justify-content: center;
|
|
217
|
+
font-size: var(--t-sm); font-weight: 700; color: var(--white);
|
|
218
|
+
margin-bottom: var(--g3); flex-shrink: 0;
|
|
219
|
+
}
|
|
220
|
+
article[itemscope]:nth-child(5n+2) .card-avatar { background: var(--violet); }
|
|
221
|
+
article[itemscope]:nth-child(5n+3) .card-avatar { background: var(--teal); }
|
|
222
|
+
article[itemscope]:nth-child(5n+4) .card-avatar { background: var(--rose); }
|
|
223
|
+
article[itemscope]:nth-child(5n+5) .card-avatar { background: var(--amber); }
|
|
224
|
+
article[itemscope]:nth-child(5n+6) .card-avatar { background: var(--sky); }
|
|
225
|
+
article[itemscope]:nth-child(5n+1) .card-avatar,
|
|
226
|
+
article[itemscope]:first-child .card-avatar { background: var(--violet); }
|
|
227
|
+
|
|
186
228
|
article[itemscope] header { margin-bottom: var(--g2); }
|
|
187
|
-
article[itemscope] h2 { font-size: var(--t-md); line-height: 1.
|
|
229
|
+
article[itemscope] h2 { font-size: var(--t-md); line-height: 1.3; margin: 0 0 4px; }
|
|
188
230
|
article[itemscope] h2 a { color: var(--ink); }
|
|
189
231
|
article[itemscope] h2 a:hover { color: var(--violet); }
|
|
190
232
|
article[itemscope] header p { font-size: var(--t-xs); line-height: 1.5; color: var(--ink-3); margin: 0; }
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
article[itemscope] [itemprop="
|
|
194
|
-
article[itemscope]
|
|
195
|
-
|
|
196
|
-
|
|
233
|
+
.card-city { display: inline-flex; align-items: center; gap: 4px; margin-top: 4px; color: var(--ink-3); font-size: var(--t-xs); }
|
|
234
|
+
.card-city::before { content: ''; display: inline-block; width: 3px; height: 3px; border-radius: 50%; background: var(--ink-3); }
|
|
235
|
+
article[itemscope] [itemprop="description"] { font-size: var(--t-xs); line-height: 1.5; margin: var(--g2) 0 0; color: var(--ink-2); }
|
|
236
|
+
article[itemscope] ul { list-style: none; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; margin-top: var(--g2); }
|
|
237
|
+
article[itemscope] ul li {
|
|
238
|
+
background: var(--violet-s); color: var(--violet);
|
|
239
|
+
padding: 2px var(--g1); border-radius: var(--pill); font-size: 0.7rem; font-weight: 500;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/* Card CTA */
|
|
243
|
+
.card-cta {
|
|
244
|
+
display: inline-flex; align-items: center; margin-top: auto; padding-top: var(--g3);
|
|
245
|
+
font-size: var(--t-xs); font-weight: 600; color: var(--violet);
|
|
246
|
+
transition: all var(--ease);
|
|
197
247
|
}
|
|
248
|
+
.card-cta:hover { color: var(--ink); gap: 6px; }
|
|
198
249
|
|
|
199
250
|
/* Single trainer */
|
|
200
251
|
main > article {
|
|
201
252
|
max-width: var(--w-8); margin: 0 auto; background: var(--card);
|
|
202
253
|
border: 1px solid var(--line); border-radius: var(--r-lg); padding: var(--g5);
|
|
254
|
+
box-shadow: var(--shadow-md);
|
|
203
255
|
}
|
|
204
256
|
main > article > header { border-bottom: 1px solid var(--line); padding-bottom: var(--g3); margin-bottom: var(--g4); }
|
|
205
257
|
main > article > header h1 { margin-bottom: var(--g2); }
|
|
@@ -224,49 +276,57 @@ main > article > footer { margin-top: var(--g5); padding-top: var(--g3); border-
|
|
|
224
276
|
/* Pagination */
|
|
225
277
|
main > nav p { display: flex; align-items: center; justify-content: center; gap: var(--g3); padding: var(--g4) 0; font-size: var(--t-sm); color: var(--ink-3); }
|
|
226
278
|
main > nav a {
|
|
227
|
-
height:
|
|
279
|
+
height: 36px; display: inline-flex; align-items: center; padding: 0 var(--g3);
|
|
228
280
|
border-radius: var(--pill); background: var(--white); border: 1px solid var(--line);
|
|
229
|
-
font-size: var(--t-xs); font-weight: 500; transition: all var(--ease);
|
|
281
|
+
font-size: var(--t-xs); font-weight: 500; transition: all var(--ease); box-shadow: var(--shadow);
|
|
230
282
|
}
|
|
231
|
-
main > nav a:hover { border-color: var(--violet); color: var(--violet); }
|
|
283
|
+
main > nav a:hover { border-color: var(--violet); color: var(--violet); transform: translateY(-1px); }
|
|
232
284
|
|
|
233
285
|
/* Trust */
|
|
234
|
-
|
|
235
|
-
margin: var(--
|
|
236
|
-
background: var(--teal-s)
|
|
237
|
-
border-radius: var(--r-lg); text-align: center;
|
|
286
|
+
.trust {
|
|
287
|
+
margin: var(--g6) auto; padding: var(--g5); max-width: var(--w-8);
|
|
288
|
+
background: linear-gradient(135deg, var(--teal-s) 0%, #f0fdf8 100%);
|
|
289
|
+
border: 1px solid rgba(13,148,136,.15); border-radius: var(--r-lg); text-align: center;
|
|
290
|
+
}
|
|
291
|
+
.trust strong {
|
|
292
|
+
display: block; font-size: var(--t-lg); line-height: 1.3; margin-bottom: var(--g4); color: var(--teal);
|
|
293
|
+
}
|
|
294
|
+
.trust ul { list-style: none; padding: 0; display: flex; flex-direction: column; gap: var(--g2); }
|
|
295
|
+
.trust li {
|
|
296
|
+
font-size: var(--t-sm); color: var(--ink-2); line-height: 1.5;
|
|
297
|
+
display: flex; align-items: center; justify-content: center; gap: var(--g1);
|
|
238
298
|
}
|
|
239
|
-
|
|
240
|
-
blockquote p { color: var(--ink-2); margin: 0 auto; font-size: var(--t-sm); }
|
|
299
|
+
.trust li::before { content: '✓'; color: var(--teal); font-weight: 700; }
|
|
241
300
|
|
|
242
301
|
/* Forms */
|
|
243
302
|
label { display: block; font-size: var(--t-sm); color: var(--ink-2); font-weight: 500; margin-bottom: var(--g1); }
|
|
244
303
|
input[type="text"] {
|
|
245
|
-
display: block; width: 100%; margin-top: var(--g1); height:
|
|
246
|
-
padding: 0 var(--
|
|
304
|
+
display: block; width: 100%; margin-top: var(--g1); height: 48px;
|
|
305
|
+
padding: 0 var(--g3); background: var(--white); border: 1px solid var(--line);
|
|
247
306
|
border-radius: var(--r); color: var(--ink); font-size: var(--t-sm); font-family: var(--font);
|
|
248
307
|
transition: border-color var(--ease);
|
|
249
308
|
}
|
|
250
|
-
input[type="text"]:focus { outline: none; border-color: var(--violet); box-shadow: 0 0 0 3px
|
|
309
|
+
input[type="text"]:focus { outline: none; border-color: var(--violet); box-shadow: 0 0 0 3px var(--violet-glow); }
|
|
251
310
|
form:not([role="search"]) button[type="submit"] {
|
|
252
|
-
margin-top: var(--g3); height:
|
|
311
|
+
margin-top: var(--g3); height: 48px; padding: 0 var(--g4);
|
|
253
312
|
border: none; border-radius: var(--pill); background: var(--violet); color: var(--white);
|
|
254
313
|
font-size: var(--t-sm); font-weight: 600; font-family: var(--font); cursor: pointer;
|
|
255
|
-
transition:
|
|
314
|
+
transition: all var(--ease); box-shadow: 0 4px 14px var(--violet-glow);
|
|
256
315
|
}
|
|
257
|
-
form:not([role="search"]) button[type="submit"]:hover { background: var(--ink); }
|
|
316
|
+
form:not([role="search"]) button[type="submit"]:hover { background: var(--ink); transform: translateY(-1px); }
|
|
258
317
|
|
|
259
318
|
/* Responsive */
|
|
260
319
|
@media (max-width: 640px) {
|
|
261
320
|
:root { --pad: var(--g3); }
|
|
262
321
|
main { padding: 0 var(--pad) var(--g5); }
|
|
263
|
-
hgroup { padding: var(--
|
|
322
|
+
hgroup { padding: var(--g6) var(--pad) var(--g5); }
|
|
264
323
|
section:has(> article[itemscope]) { grid-template-columns: 1fr; }
|
|
265
324
|
section > ol { grid-template-columns: 1fr; }
|
|
266
|
-
section > dl { grid-template-columns: 1fr; max-width:
|
|
325
|
+
section > dl { grid-template-columns: 1fr; max-width: 100%; padding: var(--g4); }
|
|
267
326
|
main > article { padding: var(--g4); }
|
|
268
327
|
main > article dl { grid-template-columns: 1fr; gap: calc(var(--g1) / 2) 0; }
|
|
269
328
|
main > article dt { margin-top: var(--g2); }
|
|
270
|
-
form[role="search"] { height:
|
|
329
|
+
form[role="search"] { height: 44px; }
|
|
271
330
|
form[role="search"] input { font-size: var(--t-xs); }
|
|
331
|
+
.trust ul { text-align: left; }
|
|
272
332
|
}
|
package/src/templates/catalog.ts
CHANGED
|
@@ -7,6 +7,7 @@ export interface CatalogHeroProps {
|
|
|
7
7
|
searchAction?: string;
|
|
8
8
|
searchPlaceholder?: string;
|
|
9
9
|
searchValue?: string;
|
|
10
|
+
ctas?: { label: string; href: string }[];
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
export function catalogHero(p: CatalogHeroProps): string {
|
|
@@ -16,17 +17,31 @@ export function catalogHero(p: CatalogHeroProps): string {
|
|
|
16
17
|
<input type="search" name="q" placeholder="${esc(p.searchPlaceholder ?? 'Szukaj...')}" value="${esc(p.searchValue ?? '')}" />
|
|
17
18
|
<button type="submit">Szukaj</button>
|
|
18
19
|
</form>` : '';
|
|
20
|
+
const ctas = p.ctas?.length ? `<p class="hero-ctas">${p.ctas.map(
|
|
21
|
+
(c, i) => `<a href="${esc(c.href)}" class="${i === 0 ? 'cta-primary' : 'cta-secondary'}">${esc(c.label)}</a>`
|
|
22
|
+
).join('\n')}</p>` : '';
|
|
19
23
|
return `<hgroup>
|
|
20
24
|
${badge}
|
|
21
|
-
<h1>${
|
|
25
|
+
<h1>${p.title}</h1>
|
|
22
26
|
${subtitle}
|
|
23
27
|
${search}
|
|
28
|
+
${ctas}
|
|
24
29
|
</hgroup>`;
|
|
25
30
|
}
|
|
26
31
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
const STAT_ICONS: Record<string, string> = {
|
|
33
|
+
people: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>',
|
|
34
|
+
city: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 21h18"/><path d="M5 21V7l8-4v18"/><path d="M19 21V11l-6-4"/><path d="M9 9v.01M9 12v.01M9 15v.01M9 18v.01"/></svg>',
|
|
35
|
+
free: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>',
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export function statBar(items: { value: string; label: string; icon?: string }[], summary?: string): string {
|
|
39
|
+
const divs = items.map(i => {
|
|
40
|
+
const icon = i.icon && STAT_ICONS[i.icon] ? `<span class="stat-icon">${STAT_ICONS[i.icon]}</span>` : '';
|
|
41
|
+
return `<div>${icon}<dt>${esc(i.value)}</dt><dd>${esc(i.label)}</dd></div>`;
|
|
42
|
+
}).join('\n');
|
|
43
|
+
const summaryP = summary ? `<p>${esc(summary)}</p>` : '';
|
|
44
|
+
return `<section aria-label="Statystyki">${summaryP}<dl>\n${divs}\n</dl></section>`;
|
|
30
45
|
}
|
|
31
46
|
|
|
32
47
|
export function categoryNav(items: { href: string; label: string }[], ariaLabel = 'Kategorie'): string {
|
|
@@ -40,8 +55,12 @@ export function steps(title: string, items: { title: string; description: string
|
|
|
40
55
|
return `<section>\n<h2>${esc(title)}</h2>\n<ol>\n${lis}\n</ol>\n</section>`;
|
|
41
56
|
}
|
|
42
57
|
|
|
43
|
-
export function trustBlock(title: string,
|
|
44
|
-
|
|
58
|
+
export function trustBlock(title: string, points: string[]): string {
|
|
59
|
+
const items = points.map(p => `<li>${esc(p)}</li>`).join('\n');
|
|
60
|
+
return `<aside class="trust">
|
|
61
|
+
<strong>${esc(title)}</strong>
|
|
62
|
+
<ul>${items}</ul>
|
|
63
|
+
</aside>`;
|
|
45
64
|
}
|
|
46
65
|
|
|
47
66
|
export interface PaginationProps {
|
|
@@ -58,6 +77,6 @@ export function pagination(p: PaginationProps): string {
|
|
|
58
77
|
const base = p.baseHref ?? '/';
|
|
59
78
|
const extra = p.extraParams ?? '';
|
|
60
79
|
const prev = p.current > 1 ? `<a href="${esc(base)}?p=${p.current - 1}${extra}">${esc(p.prevLabel ?? '\u2190 Poprzednia')}</a>` : '';
|
|
61
|
-
const next = p.current < p.total ? `<a href="${esc(base)}?p=${p.current + 1}${extra}">${esc(p.nextLabel ?? '
|
|
80
|
+
const next = p.current < p.total ? `<a href="${esc(base)}?p=${p.current + 1}${extra}">${esc(p.nextLabel ?? 'Następna \u2192')}</a>` : '';
|
|
62
81
|
return `<nav><p>${prev} Strona ${p.current} z ${p.total} ${next}</p></nav>`;
|
|
63
82
|
}
|
|
@@ -3,21 +3,25 @@ import { esc, fullName } from './helpers.ts';
|
|
|
3
3
|
|
|
4
4
|
export function profileCard(p: Profile, href: string): string {
|
|
5
5
|
const name = fullName(p);
|
|
6
|
+
const initials = `${(p.firstName?.[0] ?? '').toUpperCase()}${(p.lastName?.[0] ?? '').toUpperCase()}`;
|
|
6
7
|
|
|
7
|
-
const city = p.city ?
|
|
8
|
+
const city = p.city ? `<span itemprop="address" itemscope itemtype="https://schema.org/PostalAddress"><span itemprop="addressLocality">${esc(p.city)}</span></span>` : '';
|
|
8
9
|
|
|
9
10
|
const bio = p.bio ? `<p itemprop="description">${esc(p.bio)}</p>` : '';
|
|
10
11
|
|
|
11
12
|
const specs = p.specialties.length > 0
|
|
12
|
-
? `<
|
|
13
|
+
? `<ul>${p.specialties.slice(0, 3).map(s => `<li>${esc(s)}</li>`).join('')}</ul>`
|
|
13
14
|
: '';
|
|
14
15
|
|
|
15
16
|
return `<article itemscope itemtype="https://schema.org/Person">
|
|
17
|
+
<div class="card-avatar" aria-hidden="true">${initials}</div>
|
|
16
18
|
<header>
|
|
17
19
|
<h2><a href="${esc(href)}" itemprop="url"><span itemprop="name">${esc(name)}</span></a></h2>
|
|
18
|
-
<p><span itemprop="jobTitle">${esc(p.jobTitle)}</span
|
|
20
|
+
<p><span itemprop="jobTitle">${esc(p.jobTitle)}</span></p>
|
|
21
|
+
${city ? `<p class="card-city">${city}</p>` : ''}
|
|
19
22
|
</header>
|
|
20
23
|
${bio}
|
|
21
24
|
${specs}
|
|
25
|
+
<a href="${esc(href)}" class="card-cta">Zobacz profil →</a>
|
|
22
26
|
</article>`;
|
|
23
27
|
}
|