@press2ai/theme-specialist-glossy 0.8.3 → 0.9.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@press2ai/theme-specialist-glossy",
3
- "version": "0.8.3",
3
+ "version": "0.9.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",
@@ -57,12 +57,12 @@ body > header nav {
57
57
  body > header nav a { color: var(--ink-2); text-decoration: none; font-size: var(--t-sm); font-weight: 500; }
58
58
  body > header nav a strong { font-size: var(--t-md); font-weight: 700; color: var(--ink); }
59
59
 
60
- /* Main — no margin-bottom anywhere, only margin-top */
60
+ /* Main — each block carries its own margin-top, no position-dependent rules */
61
61
  main {
62
62
  max-width: var(--container); margin-inline: auto;
63
- padding-inline: var(--pad); padding-top: 0; padding-bottom: var(--g6);
63
+ padding-inline: var(--pad); padding-top: 0; padding-bottom: 0;
64
64
  }
65
- main > h1:first-child, main > article:first-child { margin-top: var(--g5); }
65
+ main > h1 { margin-top: var(--g5); }
66
66
 
67
67
  /* Footer */
68
68
  body > footer {
@@ -92,7 +92,7 @@ body > footer > small > p {
92
92
  font-size: var(--t-xs); color: var(--ink-3); text-align: left;
93
93
  }
94
94
 
95
- /* Hero — golden ratio: top g6, bottom g5 */
95
+ /* Hero */
96
96
  hgroup {
97
97
  position: relative; text-align: center; isolation: isolate; overflow: hidden;
98
98
  padding: var(--g6) var(--pad) var(--g5);
@@ -127,19 +127,22 @@ hgroup > p:first-child small::before { content: ''; width: 6px; height: 6px; bor
127
127
  hgroup h1 { max-width: 18ch; margin: 0 auto var(--g4); color: var(--ink); }
128
128
  hgroup p { font-size: var(--t-md); line-height: 1.55; color: var(--ink-2); max-width: var(--measure); margin: 0 auto var(--g4); }
129
129
 
130
- /* Hero CTAs */
131
- .hero-ctas {
130
+ /* Hero CTAs — <nav> inside hgroup, first link primary, rest secondary */
131
+ hgroup > nav {
132
132
  display: flex; gap: var(--g2); flex-wrap: wrap; justify-content: center;
133
133
  margin-top: var(--g4); margin-bottom: 0;
134
134
  }
135
- .cta-primary, .cta-secondary {
135
+ hgroup > nav > a {
136
136
  display: inline-flex; align-items: center; height: 44px; padding: 0 var(--g4);
137
137
  border-radius: var(--pill); font-weight: 600; font-size: var(--t-sm); transition: all var(--ease);
138
+ background: var(--white); color: var(--ink); border: 1px solid var(--line);
138
139
  }
139
- .cta-primary { background: var(--violet); color: var(--white); box-shadow: 0 4px 14px var(--violet-glow); }
140
- .cta-primary:hover { background: var(--ink); color: var(--white); transform: translateY(-1px); box-shadow: 0 6px 20px rgba(26,26,46,.2); }
141
- .cta-secondary { background: var(--white); color: var(--ink); border: 1px solid var(--line); }
142
- .cta-secondary:hover { border-color: var(--line-h); background: var(--bg); }
140
+ hgroup > nav > a:first-child {
141
+ background: var(--violet); color: var(--white); border-color: transparent;
142
+ box-shadow: 0 4px 14px var(--violet-glow);
143
+ }
144
+ hgroup > nav > a:first-child:hover { background: var(--ink); color: var(--white); transform: translateY(-1px); box-shadow: 0 6px 20px rgba(26,26,46,.2); }
145
+ hgroup > nav > a:not(:first-child):hover { border-color: var(--line-h); background: var(--bg); }
143
146
 
144
147
  /* Search */
145
148
  form[role="search"] {
@@ -162,34 +165,33 @@ form[role="search"] button {
162
165
  }
163
166
  form[role="search"] button:hover { background: var(--ink); }
164
167
 
165
- /* Stats — margin-top only, visually separated */
166
- section[aria-label="Statystyki"] { margin-top: var(--g6); }
167
- .stat-summary {
168
+ /* Stats — structural selector, no hardcoded aria-label */
169
+ section:has(> dl) { margin-top: var(--g6); }
170
+ section:has(> dl) > p {
168
171
  text-align: center; font-size: var(--t-md); font-weight: 500; line-height: 1.55;
169
172
  color: var(--ink); margin: 0 auto var(--g4); max-width: var(--measure);
170
173
  }
171
- section[aria-label="Statystyki"] > dl {
174
+ section:has(> dl) > dl {
172
175
  display: flex; justify-content: center; gap: var(--g5); margin: 0 auto; padding: 0;
173
176
  border: none; background: none; box-shadow: none;
174
177
  }
175
- section[aria-label="Statystyki"] > dl div { text-align: center; }
176
- .stat-icon { display: flex; align-items: center; justify-content: center; width: 36px; height: 36px; margin: 0 auto var(--g1); background: var(--violet-s); border-radius: 50%; color: var(--violet); }
177
- .stat-icon svg { width: 18px; height: 18px; }
178
- section[aria-label="Statystyki"] > dl dt { font-size: var(--t-lg); font-weight: 800; line-height: 1.2; color: var(--violet); }
179
- section[aria-label="Statystyki"] > dl dd { margin: 2px 0 0; font-size: var(--t-xs); line-height: 1.4; color: var(--ink-3); font-weight: 500; text-transform: uppercase; letter-spacing: 0.06em; }
178
+ section:has(> dl) > dl div { text-align: center; }
179
+ section:has(> dl) > dl div > span:has(> svg) {
180
+ display: flex; align-items: center; justify-content: center; width: 36px; height: 36px;
181
+ margin: 0 auto var(--g1); background: var(--violet-s); border-radius: 50%; color: var(--violet);
182
+ }
183
+ section:has(> dl) > dl div > span:has(> svg) > svg { width: 18px; height: 18px; }
184
+ section:has(> dl) > dl dt { font-size: var(--t-lg); font-weight: 800; line-height: 1.2; color: var(--violet); }
185
+ section:has(> dl) > dl dd { margin: 2px 0 0; font-size: var(--t-xs); line-height: 1.4; color: var(--ink-3); font-weight: 500; text-transform: uppercase; letter-spacing: 0.06em; }
180
186
 
181
- /* Category pills — margin-top only */
187
+ /* Category pills — single accent, no position-dependent colors */
182
188
  nav[aria-label] { display: flex; flex-wrap: wrap; gap: var(--g1); margin-top: var(--g5); }
183
189
  nav[aria-label] a {
184
190
  display: inline-flex; align-items: center; height: 32px; padding: 0 var(--g2);
185
191
  border-radius: var(--pill); font-size: var(--t-xs); font-weight: 500;
186
192
  background: var(--white); border: 1px solid var(--line); color: var(--ink-2); transition: all var(--ease);
187
193
  }
188
- nav[aria-label] a:nth-child(5n+1):hover { border-color: var(--violet); color: var(--violet); background: var(--violet-s); }
189
- nav[aria-label] a:nth-child(5n+2):hover { border-color: var(--teal); color: var(--teal); background: var(--teal-s); }
190
- nav[aria-label] a:nth-child(5n+3):hover { border-color: var(--rose); color: var(--rose); background: var(--rose-s); }
191
- nav[aria-label] a:nth-child(5n+4):hover { border-color: var(--amber); color: var(--amber); background: var(--amber-s); }
192
- nav[aria-label] a:nth-child(5n+5):hover { border-color: var(--sky); color: var(--sky); background: var(--sky-s); }
194
+ nav[aria-label] a:hover { border-color: var(--violet); color: var(--violet); background: var(--violet-s); }
193
195
 
194
196
  /* Steps — full-bleed white band */
195
197
  section:has(> ol) {
@@ -202,7 +204,7 @@ section:has(> ol) > * { max-width: var(--container); margin-inline: auto; }
202
204
  section:has(> ol) > h2 { text-align: center; margin-bottom: var(--g4); }
203
205
  section > ol {
204
206
  list-style: none; padding: 0; display: grid;
205
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--g3); margin: 0; counter-reset: steps;
207
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--g3); margin: 0 auto; counter-reset: steps;
206
208
  }
207
209
  section > ol li {
208
210
  counter-increment: steps; background: var(--bg); border: 1px solid var(--line);
@@ -213,16 +215,12 @@ section > ol li::before {
213
215
  content: counter(steps); display: flex; align-items: center; justify-content: center;
214
216
  width: 40px; height: 40px; margin: 0 auto var(--g2);
215
217
  border-radius: 50%; font-size: var(--t-sm); font-weight: 700;
218
+ background: var(--violet-s); color: var(--violet);
216
219
  }
217
- section > ol li:nth-child(5n+1)::before { background: var(--violet-s); color: var(--violet); }
218
- section > ol li:nth-child(5n+2)::before { background: var(--teal-s); color: var(--teal); }
219
- section > ol li:nth-child(5n+3)::before { background: var(--amber-s); color: var(--amber); }
220
- section > ol li:nth-child(5n+4)::before { background: var(--rose-s); color: var(--rose); }
221
- section > ol li:nth-child(5n+5)::before { background: var(--sky-s); color: var(--sky); }
222
220
  section > ol li strong { display: block; font-size: var(--t-sm); line-height: 1.4; margin-bottom: 4px; color: var(--ink); }
223
221
  section > ol li span { font-size: var(--t-xs); line-height: 1.5; color: var(--ink-3); }
224
222
 
225
- /* Trainer cards — margin-top only */
223
+ /* Trainer cards — no position-dependent colors */
226
224
  section:has(> article[itemscope]) {
227
225
  margin-top: var(--g6);
228
226
  display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: var(--g3);
@@ -236,42 +234,40 @@ article[itemscope] {
236
234
  }
237
235
  article[itemscope]:hover { transform: translateY(-2px); box-shadow: var(--shadow-up); border-color: var(--line-h); }
238
236
 
239
- /* Card avatar */
240
- .card-avatar {
237
+ /* Card avatar — single accent color, position-independent */
238
+ article[itemscope] > div[aria-hidden] {
241
239
  width: 40px; height: 40px; border-radius: 50%;
242
240
  display: flex; align-items: center; justify-content: center;
243
241
  font-size: var(--t-xs); font-weight: 700; color: var(--white);
244
242
  margin-bottom: var(--g2); flex-shrink: 0;
243
+ background: var(--violet);
245
244
  }
246
- article[itemscope]:nth-child(5n+2) .card-avatar { background: var(--violet); }
247
- article[itemscope]:nth-child(5n+3) .card-avatar { background: var(--teal); }
248
- article[itemscope]:nth-child(5n+4) .card-avatar { background: var(--rose); }
249
- article[itemscope]:nth-child(5n+5) .card-avatar { background: var(--amber); }
250
- article[itemscope]:nth-child(5n+6) .card-avatar { background: var(--sky); }
251
- article[itemscope]:nth-child(5n+1) .card-avatar,
252
- article[itemscope]:first-child .card-avatar { background: var(--violet); }
253
245
  article[itemscope] header { margin-bottom: var(--g1); }
254
246
  article[itemscope] h2 { font-size: var(--t-sm); font-weight: 600; line-height: 1.3; margin: 0 0 2px; }
255
247
  article[itemscope] h2 a { color: var(--ink); }
256
248
  article[itemscope] h2 a:hover { color: var(--violet); }
257
249
  article[itemscope] header p { font-size: var(--t-xs); line-height: 1.4; color: var(--ink-3); margin: 0; }
258
- .card-city { display: inline-flex; align-items: center; gap: 4px; margin-top: 2px; color: var(--ink-3); font-size: var(--t-xs); }
259
- .card-city::before { content: ''; display: inline-block; width: 3px; height: 3px; border-radius: 50%; background: var(--ink-3); }
250
+ article[itemscope] header p:has([itemprop="address"]) {
251
+ display: inline-flex; align-items: center; gap: 4px; margin-top: 2px;
252
+ }
253
+ article[itemscope] header p:has([itemprop="address"])::before {
254
+ content: ''; display: inline-block; width: 3px; height: 3px; border-radius: 50%; background: var(--ink-3);
255
+ }
260
256
  article[itemscope] [itemprop="description"] { font-size: var(--t-xs); line-height: 1.5; margin: var(--g1) 0 0; color: var(--ink-2); }
261
257
  article[itemscope] ul { list-style: none; padding: 0; display: flex; flex-wrap: wrap; gap: 4px; margin-top: var(--g1); }
262
258
  article[itemscope] ul li {
263
259
  background: var(--violet-s); color: var(--violet);
264
260
  padding: 1px var(--g1); border-radius: var(--pill); font-size: 0.7rem; font-weight: 500;
265
261
  }
266
- .card-cta {
262
+ article[itemscope] > a:last-child {
267
263
  display: inline-flex; align-items: center; margin-top: auto; padding-top: var(--g2);
268
264
  font-size: var(--t-xs); font-weight: 600; color: var(--violet); transition: all var(--ease);
269
265
  }
270
- .card-cta:hover { color: var(--ink); gap: 4px; }
266
+ article[itemscope] > a:last-child:hover { color: var(--ink); gap: 4px; }
271
267
 
272
268
  /* Single trainer */
273
269
  main > article {
274
- max-width: var(--w-8); margin: 0 auto; background: var(--card);
270
+ max-width: var(--w-8); margin: var(--g5) auto 0; background: var(--card);
275
271
  border: 1px solid var(--line); border-radius: var(--r-lg); padding: var(--g5); box-shadow: var(--shadow-md);
276
272
  }
277
273
  main > article > header { border-bottom: 1px solid var(--line); padding-bottom: var(--g3); margin-bottom: var(--g4); }
@@ -321,6 +317,9 @@ form:not([role="search"]) button[type="submit"] {
321
317
  }
322
318
  form:not([role="search"]) button[type="submit"]:hover { background: var(--ink); transform: translateY(-1px); }
323
319
 
320
+ /* Trust block */
321
+ aside:has(> ul) { margin-top: var(--g5); }
322
+
324
323
  /* Responsive */
325
324
  @media (max-width: 640px) {
326
325
  :root { --pad: var(--g3); }
@@ -328,7 +327,7 @@ form:not([role="search"]) button[type="submit"]:hover { background: var(--ink);
328
327
  hgroup { padding: var(--g5) var(--pad) var(--g4); }
329
328
  section:has(> article[itemscope]) { grid-template-columns: 1fr; }
330
329
  section > ol { grid-template-columns: 1fr; }
331
- section[aria-label="Statystyki"] > dl { gap: var(--g3); }
330
+ section:has(> dl) > dl { gap: var(--g3); }
332
331
  main > article { padding: var(--g3); }
333
332
  main > article dl { grid-template-columns: 1fr; gap: calc(var(--g1) / 2) 0; }
334
333
  main > article dt { margin-top: var(--g2); }
@@ -17,9 +17,9 @@ export function catalogHero(p: CatalogHeroProps): string {
17
17
  <input type="search" name="q" placeholder="${esc(p.searchPlaceholder ?? 'Szukaj...')}" value="${esc(p.searchValue ?? '')}" />
18
18
  <button type="submit">Szukaj</button>
19
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>` : '';
20
+ const ctas = p.ctas?.length ? `<nav>${p.ctas.map(
21
+ c => `<a href="${esc(c.href)}">${esc(c.label)}</a>`
22
+ ).join('\n')}</nav>` : '';
23
23
  return `<hgroup>
24
24
  ${badge}
25
25
  <h1>${p.title}</h1>
@@ -37,10 +37,10 @@ const STAT_ICONS: Record<string, string> = {
37
37
 
38
38
  export function statBar(items: { value: string; label: string; icon?: string }[], summary?: string): string {
39
39
  const divs = items.map(i => {
40
- const icon = i.icon && STAT_ICONS[i.icon] ? `<span class="stat-icon">${STAT_ICONS[i.icon]}</span>` : '';
40
+ const icon = i.icon && STAT_ICONS[i.icon] ? `<span>${STAT_ICONS[i.icon]}</span>` : '';
41
41
  return `<div>${icon}<dt>${esc(i.value)}</dt><dd>${esc(i.label)}</dd></div>`;
42
42
  }).join('\n');
43
- const summaryP = summary ? `<p class="stat-summary">${esc(summary)}</p>` : '';
43
+ const summaryP = summary ? `<p>${esc(summary)}</p>` : '';
44
44
  return `<section aria-label="Statystyki">${summaryP}<dl aria-hidden="true">\n${divs}\n</dl></section>`;
45
45
  }
46
46
 
@@ -57,7 +57,7 @@ export function steps(title: string, items: { title: string; description: string
57
57
 
58
58
  export function trustBlock(title: string, points: string[]): string {
59
59
  const items = points.map(p => `<li>${esc(p)}</li>`).join('\n');
60
- return `<aside class="trust">
60
+ return `<aside>
61
61
  <strong>${esc(title)}</strong>
62
62
  <ul>${items}</ul>
63
63
  </aside>`;
@@ -11,7 +11,7 @@ export function hero(p: Profile): string {
11
11
  const ctas: string[] = [];
12
12
  if (p.email) ctas.push(`<a href="mailto:${esc(p.email)}">Napisz wiadomość</a>`);
13
13
  if (p.phone) ctas.push(`<a href="tel:${esc(p.phone.replace(/\s/g, ''))}">Zadzwoń</a>`);
14
- const ctaBlock = ctas.length ? `<p>${ctas.join('\n')}</p>` : '';
14
+ const ctaBlock = ctas.length ? `<nav>${ctas.join('\n')}</nav>` : '';
15
15
 
16
16
  return `<hgroup>
17
17
  ${badge}
@@ -12,7 +12,7 @@ export interface LayoutProps {
12
12
  footerContent?: string;
13
13
  }
14
14
 
15
- const THEME_VERSION = '0.4.0';
15
+ const THEME_VERSION = '0.9.1';
16
16
 
17
17
  export function layout(props: LayoutProps, body: string): string {
18
18
  const {
@@ -14,14 +14,14 @@ export function profileCard(p: Profile, href: string): string {
14
14
  : '';
15
15
 
16
16
  return `<article itemscope itemtype="https://schema.org/Person">
17
- <div class="card-avatar" aria-hidden="true">${initials}</div>
17
+ <div aria-hidden="true">${initials}</div>
18
18
  <header>
19
19
  <h2><a href="${esc(href)}" itemprop="url"><span itemprop="name">${esc(name)}</span></a></h2>
20
20
  <p><span itemprop="jobTitle">${esc(p.jobTitle)}</span></p>
21
- ${city ? `<p class="card-city">${city}</p>` : ''}
21
+ ${city ? `<p>${city}</p>` : ''}
22
22
  </header>
23
23
  ${bio}
24
24
  ${specs}
25
- <a href="${esc(href)}" class="card-cta">Zobacz profil &rarr;</a>
25
+ <a href="${esc(href)}">Zobacz profil &rarr;</a>
26
26
  </article>`;
27
27
  }