@press2ai/theme-specialist-glossy 0.4.4 → 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 -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.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,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); }
|
|
@@ -146,18 +173,20 @@ nav[aria-label] a:nth-child(5n+4):hover { border-color: var(--amber); color: var
|
|
|
146
173
|
nav[aria-label] a:nth-child(5n+5):hover { border-color: var(--sky); color: var(--sky); background: var(--sky-s); }
|
|
147
174
|
|
|
148
175
|
/* Steps */
|
|
149
|
-
section:has(> ol) > h2 { text-align: center; }
|
|
176
|
+
section:has(> ol) > h2 { text-align: center; margin-bottom: var(--g5); }
|
|
150
177
|
section > ol {
|
|
151
178
|
list-style: none; padding: 0; display: grid;
|
|
152
|
-
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;
|
|
153
180
|
}
|
|
154
181
|
section > ol li {
|
|
155
182
|
counter-increment: steps; background: var(--white); border: 1px solid var(--line);
|
|
156
|
-
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);
|
|
157
185
|
}
|
|
186
|
+
section > ol li:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
|
|
158
187
|
section > ol li::before {
|
|
159
188
|
content: counter(steps); display: flex; align-items: center; justify-content: center;
|
|
160
|
-
width:
|
|
189
|
+
width: 48px; height: 48px; margin: 0 auto var(--g3);
|
|
161
190
|
border-radius: 50%; font-size: var(--t-md); font-weight: 700;
|
|
162
191
|
}
|
|
163
192
|
section > ol li:nth-child(5n+1)::before { background: var(--violet-s); color: var(--violet); }
|
|
@@ -165,42 +194,64 @@ section > ol li:nth-child(5n+2)::before { background: var(--teal-s); color: var(
|
|
|
165
194
|
section > ol li:nth-child(5n+3)::before { background: var(--amber-s); color: var(--amber); }
|
|
166
195
|
section > ol li:nth-child(5n+4)::before { background: var(--rose-s); color: var(--rose); }
|
|
167
196
|
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-
|
|
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); }
|
|
170
199
|
|
|
171
200
|
/* Trainer cards */
|
|
172
201
|
section:has(> article[itemscope]) {
|
|
173
|
-
display: grid; grid-template-columns: repeat(auto-fill, minmax(
|
|
202
|
+
display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: var(--g4);
|
|
174
203
|
}
|
|
175
204
|
section:has(> article[itemscope]) > h2 { grid-column: 1 / -1; margin-bottom: var(--g4); }
|
|
176
205
|
article[itemscope] {
|
|
177
|
-
|
|
178
|
-
border-radius: var(--r-lg); padding: var(--g4)
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
article[itemscope]:
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
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
|
+
|
|
187
228
|
article[itemscope] header { margin-bottom: var(--g2); }
|
|
188
|
-
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; }
|
|
189
230
|
article[itemscope] h2 a { color: var(--ink); }
|
|
190
231
|
article[itemscope] h2 a:hover { color: var(--violet); }
|
|
191
232
|
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
|
-
|
|
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);
|
|
198
247
|
}
|
|
248
|
+
.card-cta:hover { color: var(--ink); gap: 6px; }
|
|
199
249
|
|
|
200
250
|
/* Single trainer */
|
|
201
251
|
main > article {
|
|
202
252
|
max-width: var(--w-8); margin: 0 auto; background: var(--card);
|
|
203
253
|
border: 1px solid var(--line); border-radius: var(--r-lg); padding: var(--g5);
|
|
254
|
+
box-shadow: var(--shadow-md);
|
|
204
255
|
}
|
|
205
256
|
main > article > header { border-bottom: 1px solid var(--line); padding-bottom: var(--g3); margin-bottom: var(--g4); }
|
|
206
257
|
main > article > header h1 { margin-bottom: var(--g2); }
|
|
@@ -225,49 +276,57 @@ main > article > footer { margin-top: var(--g5); padding-top: var(--g3); border-
|
|
|
225
276
|
/* Pagination */
|
|
226
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); }
|
|
227
278
|
main > nav a {
|
|
228
|
-
height:
|
|
279
|
+
height: 36px; display: inline-flex; align-items: center; padding: 0 var(--g3);
|
|
229
280
|
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);
|
|
281
|
+
font-size: var(--t-xs); font-weight: 500; transition: all var(--ease); box-shadow: var(--shadow);
|
|
231
282
|
}
|
|
232
|
-
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); }
|
|
233
284
|
|
|
234
285
|
/* Trust */
|
|
235
|
-
|
|
236
|
-
margin: var(--
|
|
237
|
-
background: var(--teal-s)
|
|
238
|
-
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);
|
|
239
298
|
}
|
|
240
|
-
|
|
241
|
-
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; }
|
|
242
300
|
|
|
243
301
|
/* Forms */
|
|
244
302
|
label { display: block; font-size: var(--t-sm); color: var(--ink-2); font-weight: 500; margin-bottom: var(--g1); }
|
|
245
303
|
input[type="text"] {
|
|
246
|
-
display: block; width: 100%; margin-top: var(--g1); height:
|
|
247
|
-
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);
|
|
248
306
|
border-radius: var(--r); color: var(--ink); font-size: var(--t-sm); font-family: var(--font);
|
|
249
307
|
transition: border-color var(--ease);
|
|
250
308
|
}
|
|
251
|
-
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); }
|
|
252
310
|
form:not([role="search"]) button[type="submit"] {
|
|
253
|
-
margin-top: var(--g3); height:
|
|
311
|
+
margin-top: var(--g3); height: 48px; padding: 0 var(--g4);
|
|
254
312
|
border: none; border-radius: var(--pill); background: var(--violet); color: var(--white);
|
|
255
313
|
font-size: var(--t-sm); font-weight: 600; font-family: var(--font); cursor: pointer;
|
|
256
|
-
transition:
|
|
314
|
+
transition: all var(--ease); box-shadow: 0 4px 14px var(--violet-glow);
|
|
257
315
|
}
|
|
258
|
-
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); }
|
|
259
317
|
|
|
260
318
|
/* Responsive */
|
|
261
319
|
@media (max-width: 640px) {
|
|
262
320
|
:root { --pad: var(--g3); }
|
|
263
321
|
main { padding: 0 var(--pad) var(--g5); }
|
|
264
|
-
hgroup { padding: var(--
|
|
322
|
+
hgroup { padding: var(--g6) var(--pad) var(--g5); }
|
|
265
323
|
section:has(> article[itemscope]) { grid-template-columns: 1fr; }
|
|
266
324
|
section > ol { grid-template-columns: 1fr; }
|
|
267
|
-
section > dl { grid-template-columns: 1fr; max-width:
|
|
325
|
+
section > dl { grid-template-columns: 1fr; max-width: 100%; padding: var(--g4); }
|
|
268
326
|
main > article { padding: var(--g4); }
|
|
269
327
|
main > article dl { grid-template-columns: 1fr; gap: calc(var(--g1) / 2) 0; }
|
|
270
328
|
main > article dt { margin-top: var(--g2); }
|
|
271
|
-
form[role="search"] { height:
|
|
329
|
+
form[role="search"] { height: 44px; }
|
|
272
330
|
form[role="search"] input { font-size: var(--t-xs); }
|
|
331
|
+
.trust ul { text-align: left; }
|
|
273
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,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
|
}
|