@press2ai/theme-specialist-glossy 0.4.4 → 0.5.1
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 +151 -79
- package/src/templates/catalog.ts +24 -6
- 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.1",
|
|
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,30 +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 */
|
|
124
|
-
section[aria-label] > p { text-align: center; font-size: var(--t-sm); color: var(--ink-2); margin: 0 auto var(--
|
|
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); }
|
|
125
148
|
section:has(> dl) { margin-bottom: 0; }
|
|
126
149
|
section > dl {
|
|
127
|
-
display: grid; grid-template-columns: repeat(auto-fit, minmax(
|
|
128
|
-
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);
|
|
129
152
|
background: var(--white); border: 1px solid var(--line); border-radius: var(--r-lg);
|
|
153
|
+
box-shadow: var(--shadow-md);
|
|
130
154
|
}
|
|
131
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; }
|
|
132
158
|
section > dl dt { font-size: var(--t-xl); font-weight: 800; line-height: 1.2; color: var(--violet); }
|
|
133
|
-
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; }
|
|
134
160
|
|
|
135
161
|
/* Category pills */
|
|
136
|
-
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); }
|
|
137
163
|
nav[aria-label] a {
|
|
138
|
-
display: inline-flex; align-items: center; height:
|
|
164
|
+
display: inline-flex; align-items: center; height: 36px; padding: 0 var(--g3);
|
|
139
165
|
border-radius: var(--pill); font-size: var(--t-xs); font-weight: 500;
|
|
140
|
-
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);
|
|
141
168
|
}
|
|
142
169
|
nav[aria-label] a:nth-child(5n+1):hover { border-color: var(--violet); color: var(--violet); background: var(--violet-s); }
|
|
143
170
|
nav[aria-label] a:nth-child(5n+2):hover { border-color: var(--teal); color: var(--teal); background: var(--teal-s); }
|
|
@@ -145,19 +172,34 @@ nav[aria-label] a:nth-child(5n+3):hover { border-color: var(--rose); color: var(
|
|
|
145
172
|
nav[aria-label] a:nth-child(5n+4):hover { border-color: var(--amber); color: var(--amber); background: var(--amber-s); }
|
|
146
173
|
nav[aria-label] a:nth-child(5n+5):hover { border-color: var(--sky); color: var(--sky); background: var(--sky-s); }
|
|
147
174
|
|
|
175
|
+
/* How it works — full-bleed band */
|
|
176
|
+
.how-it-works {
|
|
177
|
+
margin: 0 calc(50% - 50vw) var(--g7) calc(50% - 50vw);
|
|
178
|
+
padding: var(--g7) var(--pad);
|
|
179
|
+
background: var(--white);
|
|
180
|
+
border-top: 1px solid var(--line);
|
|
181
|
+
border-bottom: 1px solid var(--line);
|
|
182
|
+
}
|
|
183
|
+
.how-it-works > section {
|
|
184
|
+
max-width: var(--container);
|
|
185
|
+
margin: 0 auto;
|
|
186
|
+
}
|
|
187
|
+
|
|
148
188
|
/* Steps */
|
|
149
|
-
section:has(> ol) > h2 { text-align: center; }
|
|
189
|
+
section:has(> ol) > h2 { text-align: center; margin-bottom: var(--g5); }
|
|
150
190
|
section > ol {
|
|
151
191
|
list-style: none; padding: 0; display: grid;
|
|
152
|
-
grid-template-columns: repeat(auto-fit, minmax(
|
|
192
|
+
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--g4); margin: 0; counter-reset: steps;
|
|
153
193
|
}
|
|
154
194
|
section > ol li {
|
|
155
195
|
counter-increment: steps; background: var(--white); border: 1px solid var(--line);
|
|
156
|
-
border-radius: var(--r-lg); padding: var(--g5) var(--
|
|
196
|
+
border-radius: var(--r-lg); padding: var(--g5) var(--g4); text-align: center;
|
|
197
|
+
box-shadow: var(--shadow); transition: all var(--ease);
|
|
157
198
|
}
|
|
199
|
+
section > ol li:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
|
|
158
200
|
section > ol li::before {
|
|
159
201
|
content: counter(steps); display: flex; align-items: center; justify-content: center;
|
|
160
|
-
width:
|
|
202
|
+
width: 48px; height: 48px; margin: 0 auto var(--g3);
|
|
161
203
|
border-radius: 50%; font-size: var(--t-md); font-weight: 700;
|
|
162
204
|
}
|
|
163
205
|
section > ol li:nth-child(5n+1)::before { background: var(--violet-s); color: var(--violet); }
|
|
@@ -165,42 +207,64 @@ section > ol li:nth-child(5n+2)::before { background: var(--teal-s); color: var(
|
|
|
165
207
|
section > ol li:nth-child(5n+3)::before { background: var(--amber-s); color: var(--amber); }
|
|
166
208
|
section > ol li:nth-child(5n+4)::before { background: var(--rose-s); color: var(--rose); }
|
|
167
209
|
section > ol li:nth-child(5n+5)::before { background: var(--sky-s); color: var(--sky); }
|
|
168
|
-
section > ol li strong { display: block; font-size: var(--t-
|
|
169
|
-
section > ol li span { font-size: var(--t-
|
|
210
|
+
section > ol li strong { display: block; font-size: var(--t-md); line-height: 1.4; margin-bottom: var(--g1); color: var(--ink); }
|
|
211
|
+
section > ol li span { font-size: var(--t-sm); line-height: 1.5; color: var(--ink-3); }
|
|
170
212
|
|
|
171
213
|
/* Trainer cards */
|
|
172
214
|
section:has(> article[itemscope]) {
|
|
173
|
-
display: grid; grid-template-columns: repeat(auto-fill, minmax(
|
|
215
|
+
display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: var(--g4);
|
|
174
216
|
}
|
|
175
217
|
section:has(> article[itemscope]) > h2 { grid-column: 1 / -1; margin-bottom: var(--g4); }
|
|
176
218
|
article[itemscope] {
|
|
177
|
-
|
|
178
|
-
border-radius: var(--r-lg); padding: var(--g4)
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
article[itemscope]:
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
219
|
+
position: relative; background: var(--card); border: 1px solid var(--line);
|
|
220
|
+
border-radius: var(--r-lg); padding: var(--g4);
|
|
221
|
+
display: flex; flex-direction: column;
|
|
222
|
+
box-shadow: var(--shadow); transition: all var(--ease);
|
|
223
|
+
}
|
|
224
|
+
article[itemscope]:hover { transform: translateY(-3px); box-shadow: var(--shadow-up); border-color: var(--line-h); }
|
|
225
|
+
|
|
226
|
+
/* Card avatar */
|
|
227
|
+
.card-avatar {
|
|
228
|
+
width: 48px; height: 48px; border-radius: 50%;
|
|
229
|
+
display: flex; align-items: center; justify-content: center;
|
|
230
|
+
font-size: var(--t-sm); font-weight: 700; color: var(--white);
|
|
231
|
+
margin-bottom: var(--g3); flex-shrink: 0;
|
|
232
|
+
}
|
|
233
|
+
article[itemscope]:nth-child(5n+2) .card-avatar { background: var(--violet); }
|
|
234
|
+
article[itemscope]:nth-child(5n+3) .card-avatar { background: var(--teal); }
|
|
235
|
+
article[itemscope]:nth-child(5n+4) .card-avatar { background: var(--rose); }
|
|
236
|
+
article[itemscope]:nth-child(5n+5) .card-avatar { background: var(--amber); }
|
|
237
|
+
article[itemscope]:nth-child(5n+6) .card-avatar { background: var(--sky); }
|
|
238
|
+
article[itemscope]:nth-child(5n+1) .card-avatar,
|
|
239
|
+
article[itemscope]:first-child .card-avatar { background: var(--violet); }
|
|
240
|
+
|
|
187
241
|
article[itemscope] header { margin-bottom: var(--g2); }
|
|
188
|
-
article[itemscope] h2 { font-size: var(--t-md); line-height: 1.
|
|
242
|
+
article[itemscope] h2 { font-size: var(--t-md); line-height: 1.3; margin: 0 0 4px; }
|
|
189
243
|
article[itemscope] h2 a { color: var(--ink); }
|
|
190
244
|
article[itemscope] h2 a:hover { color: var(--violet); }
|
|
191
245
|
article[itemscope] header p { font-size: var(--t-xs); line-height: 1.5; color: var(--ink-3); margin: 0; }
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
article[itemscope] [itemprop="
|
|
195
|
-
article[itemscope]
|
|
196
|
-
|
|
197
|
-
|
|
246
|
+
.card-city { display: inline-flex; align-items: center; gap: 4px; margin-top: 4px; color: var(--ink-3); font-size: var(--t-xs); }
|
|
247
|
+
.card-city::before { content: ''; display: inline-block; width: 3px; height: 3px; border-radius: 50%; background: var(--ink-3); }
|
|
248
|
+
article[itemscope] [itemprop="description"] { font-size: var(--t-xs); line-height: 1.5; margin: var(--g2) 0 0; color: var(--ink-2); }
|
|
249
|
+
article[itemscope] ul { list-style: none; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; margin-top: var(--g2); }
|
|
250
|
+
article[itemscope] ul li {
|
|
251
|
+
background: var(--violet-s); color: var(--violet);
|
|
252
|
+
padding: 2px var(--g1); border-radius: var(--pill); font-size: 0.7rem; font-weight: 500;
|
|
198
253
|
}
|
|
199
254
|
|
|
255
|
+
/* Card CTA */
|
|
256
|
+
.card-cta {
|
|
257
|
+
display: inline-flex; align-items: center; margin-top: auto; padding-top: var(--g3);
|
|
258
|
+
font-size: var(--t-xs); font-weight: 600; color: var(--violet);
|
|
259
|
+
transition: all var(--ease);
|
|
260
|
+
}
|
|
261
|
+
.card-cta:hover { color: var(--ink); gap: 6px; }
|
|
262
|
+
|
|
200
263
|
/* Single trainer */
|
|
201
264
|
main > article {
|
|
202
265
|
max-width: var(--w-8); margin: 0 auto; background: var(--card);
|
|
203
266
|
border: 1px solid var(--line); border-radius: var(--r-lg); padding: var(--g5);
|
|
267
|
+
box-shadow: var(--shadow-md);
|
|
204
268
|
}
|
|
205
269
|
main > article > header { border-bottom: 1px solid var(--line); padding-bottom: var(--g3); margin-bottom: var(--g4); }
|
|
206
270
|
main > article > header h1 { margin-bottom: var(--g2); }
|
|
@@ -225,49 +289,57 @@ main > article > footer { margin-top: var(--g5); padding-top: var(--g3); border-
|
|
|
225
289
|
/* Pagination */
|
|
226
290
|
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); }
|
|
227
291
|
main > nav a {
|
|
228
|
-
height:
|
|
292
|
+
height: 36px; display: inline-flex; align-items: center; padding: 0 var(--g3);
|
|
229
293
|
border-radius: var(--pill); background: var(--white); border: 1px solid var(--line);
|
|
230
|
-
font-size: var(--t-xs); font-weight: 500; transition: all var(--ease);
|
|
294
|
+
font-size: var(--t-xs); font-weight: 500; transition: all var(--ease); box-shadow: var(--shadow);
|
|
231
295
|
}
|
|
232
|
-
main > nav a:hover { border-color: var(--violet); color: var(--violet); }
|
|
296
|
+
main > nav a:hover { border-color: var(--violet); color: var(--violet); transform: translateY(-1px); }
|
|
233
297
|
|
|
234
298
|
/* Trust */
|
|
235
|
-
|
|
236
|
-
margin: var(--
|
|
237
|
-
background: var(--teal-s)
|
|
238
|
-
border-radius: var(--r-lg); text-align: center;
|
|
299
|
+
.trust {
|
|
300
|
+
margin: var(--g6) auto; padding: var(--g5); max-width: var(--w-8);
|
|
301
|
+
background: linear-gradient(135deg, var(--teal-s) 0%, #f0fdf8 100%);
|
|
302
|
+
border: 1px solid rgba(13,148,136,.15); border-radius: var(--r-lg); text-align: center;
|
|
303
|
+
}
|
|
304
|
+
.trust strong {
|
|
305
|
+
display: block; font-size: var(--t-lg); line-height: 1.3; margin-bottom: var(--g4); color: var(--teal);
|
|
306
|
+
}
|
|
307
|
+
.trust ul { list-style: none; padding: 0; display: flex; flex-direction: column; gap: var(--g2); }
|
|
308
|
+
.trust li {
|
|
309
|
+
font-size: var(--t-sm); color: var(--ink-2); line-height: 1.5;
|
|
310
|
+
display: flex; align-items: center; justify-content: center; gap: var(--g1);
|
|
239
311
|
}
|
|
240
|
-
|
|
241
|
-
blockquote p { color: var(--ink-2); margin: 0 auto; font-size: var(--t-sm); }
|
|
312
|
+
.trust li::before { content: '✓'; color: var(--teal); font-weight: 700; }
|
|
242
313
|
|
|
243
314
|
/* Forms */
|
|
244
315
|
label { display: block; font-size: var(--t-sm); color: var(--ink-2); font-weight: 500; margin-bottom: var(--g1); }
|
|
245
316
|
input[type="text"] {
|
|
246
|
-
display: block; width: 100%; margin-top: var(--g1); height:
|
|
247
|
-
padding: 0 var(--
|
|
317
|
+
display: block; width: 100%; margin-top: var(--g1); height: 48px;
|
|
318
|
+
padding: 0 var(--g3); background: var(--white); border: 1px solid var(--line);
|
|
248
319
|
border-radius: var(--r); color: var(--ink); font-size: var(--t-sm); font-family: var(--font);
|
|
249
320
|
transition: border-color var(--ease);
|
|
250
321
|
}
|
|
251
|
-
input[type="text"]:focus { outline: none; border-color: var(--violet); box-shadow: 0 0 0 3px
|
|
322
|
+
input[type="text"]:focus { outline: none; border-color: var(--violet); box-shadow: 0 0 0 3px var(--violet-glow); }
|
|
252
323
|
form:not([role="search"]) button[type="submit"] {
|
|
253
|
-
margin-top: var(--g3); height:
|
|
324
|
+
margin-top: var(--g3); height: 48px; padding: 0 var(--g4);
|
|
254
325
|
border: none; border-radius: var(--pill); background: var(--violet); color: var(--white);
|
|
255
326
|
font-size: var(--t-sm); font-weight: 600; font-family: var(--font); cursor: pointer;
|
|
256
|
-
transition:
|
|
327
|
+
transition: all var(--ease); box-shadow: 0 4px 14px var(--violet-glow);
|
|
257
328
|
}
|
|
258
|
-
form:not([role="search"]) button[type="submit"]:hover { background: var(--ink); }
|
|
329
|
+
form:not([role="search"]) button[type="submit"]:hover { background: var(--ink); transform: translateY(-1px); }
|
|
259
330
|
|
|
260
331
|
/* Responsive */
|
|
261
332
|
@media (max-width: 640px) {
|
|
262
333
|
:root { --pad: var(--g3); }
|
|
263
334
|
main { padding: 0 var(--pad) var(--g5); }
|
|
264
|
-
hgroup { padding: var(--
|
|
335
|
+
hgroup { padding: var(--g6) var(--pad) var(--g5); }
|
|
265
336
|
section:has(> article[itemscope]) { grid-template-columns: 1fr; }
|
|
266
337
|
section > ol { grid-template-columns: 1fr; }
|
|
267
|
-
section > dl { grid-template-columns: 1fr; max-width:
|
|
338
|
+
section > dl { grid-template-columns: 1fr; max-width: 100%; padding: var(--g4); }
|
|
268
339
|
main > article { padding: var(--g4); }
|
|
269
340
|
main > article dl { grid-template-columns: 1fr; gap: calc(var(--g1) / 2) 0; }
|
|
270
341
|
main > article dt { margin-top: var(--g2); }
|
|
271
|
-
form[role="search"] { height:
|
|
342
|
+
form[role="search"] { height: 44px; }
|
|
272
343
|
form[role="search"] input { font-size: var(--t-xs); }
|
|
344
|
+
.trust ul { text-align: left; }
|
|
273
345
|
}
|
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,16 +17,29 @@ 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
|
-
|
|
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');
|
|
29
43
|
const summaryP = summary ? `<p>${esc(summary)}</p>` : '';
|
|
30
44
|
return `<section aria-label="Statystyki">${summaryP}<dl>\n${divs}\n</dl></section>`;
|
|
31
45
|
}
|
|
@@ -41,8 +55,12 @@ export function steps(title: string, items: { title: string; description: string
|
|
|
41
55
|
return `<section>\n<h2>${esc(title)}</h2>\n<ol>\n${lis}\n</ol>\n</section>`;
|
|
42
56
|
}
|
|
43
57
|
|
|
44
|
-
export function trustBlock(title: string,
|
|
45
|
-
|
|
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>`;
|
|
46
64
|
}
|
|
47
65
|
|
|
48
66
|
export interface PaginationProps {
|
|
@@ -59,6 +77,6 @@ export function pagination(p: PaginationProps): string {
|
|
|
59
77
|
const base = p.baseHref ?? '/';
|
|
60
78
|
const extra = p.extraParams ?? '';
|
|
61
79
|
const prev = p.current > 1 ? `<a href="${esc(base)}?p=${p.current - 1}${extra}">${esc(p.prevLabel ?? '\u2190 Poprzednia')}</a>` : '';
|
|
62
|
-
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>` : '';
|
|
63
81
|
return `<nav><p>${prev} Strona ${p.current} z ${p.total} ${next}</p></nav>`;
|
|
64
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
|
}
|