@gemboss/website-ui 0.5.0 → 0.7.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/AGENTS.md +44 -4
- package/CHANGELOG.md +116 -0
- package/README.md +8 -8
- package/bin/lib/check.mjs +47 -0
- package/css/base.css +12 -0
- package/css/components.css +8 -0
- package/css/footer.css +181 -0
- package/css/forms.css +154 -0
- package/css/ratings.css +78 -0
- package/css/tokens.css +21 -0
- package/demo/assets/avatar-sample.svg +1 -0
- package/demo/footer.html +339 -0
- package/demo/forms.html +505 -0
- package/demo/index.html +2 -0
- package/docs/components.md +197 -7
- package/docs/markup-contract.md +123 -6
- package/docs/theming.md +12 -5
- package/js/website.js +21 -4
- package/js/website.mjs +27 -3
- package/package.json +1 -1
- package/skill/SKILL.md +8 -0
- package/system.json +12 -1
- package/templates/footer.html +119 -16
- package/templates/page.html +16 -11
- package/templates/sections/form.html +42 -0
- package/templates/sections/testimonials.html +58 -0
- package/website.css +457 -1
- package/website.min.css +1 -1
package/skill/SKILL.md
CHANGED
|
@@ -20,6 +20,14 @@ the kit and its rules are how the page ends up looking designed. Compose from th
|
|
|
20
20
|
- An article page (a blog post, a guide) is `KIT/templates/sections/article.html`: breadcrumbs, the meta row, a
|
|
21
21
|
contents list from the article's h2s, the prose, callouts, the FAQ last. Never a callout told by its colour
|
|
22
22
|
alone (it keeps its label: Note, Tip, Warning). The blog index is `KIT/templates/sections/post-list.html`.
|
|
23
|
+
- A form asks as little as it can: one field beats a form, a form keeps two or three fields
|
|
24
|
+
(`KIT/templates/sections/form.html`; one field and its button: `.gw-form-inline`). Label above, the error in
|
|
25
|
+
words under it with `aria-invalid="true"`; the page decides when, the kit draws it.
|
|
26
|
+
- Ratings and testimonials (`KIT/templates/sections/testimonials.html`): only real ones, each linked to the page it
|
|
27
|
+
comes from, the reviewer's words exactly; stars carry their value in words (`aria-label="4.9 out of 5"`).
|
|
28
|
+
- The footer is `KIT/templates/footer.html` (the footer of gemboss.ai), filled once in the site's shared partial:
|
|
29
|
+
fill its rows (columns, family rows, words), delete the optional parts you do not use (Ask AI, newsletter, family
|
|
30
|
+
rows, theme toggle, wordmark), never invent a footer part. Columns fold on phones by themselves (`<details>`).
|
|
23
31
|
- Changed page: keep its kit classes; change words, order and choice of sections.
|
|
24
32
|
- Site CSS only for what the kit cannot know (an illustration, a product mock-up), with the kit's tokens and
|
|
25
33
|
scales, classes in the site's own prefix. Never style a `.gw-*` class, never edit `node_modules`.
|
package/system.json
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"muted": "#686b71",
|
|
12
12
|
"line": "#e5e7ea",
|
|
13
13
|
"line-strong": "#d5d8dd",
|
|
14
|
+
"line-control": "#85888e",
|
|
14
15
|
"action": "#1b1c1e",
|
|
15
16
|
"action-hover": "#000000",
|
|
16
17
|
"on-action": "#ffffff",
|
|
@@ -22,6 +23,9 @@
|
|
|
22
23
|
"success-soft": "#e3f1df",
|
|
23
24
|
"warning": "#9a6700",
|
|
24
25
|
"warning-soft": "#fbf1dc",
|
|
26
|
+
"danger": "#b42318",
|
|
27
|
+
"danger-soft": "#fff0e9",
|
|
28
|
+
"on-danger": "#ffffff",
|
|
25
29
|
"night": "#0c0e14",
|
|
26
30
|
"night-2": "#141722",
|
|
27
31
|
"on-night": "#e3e4e8",
|
|
@@ -36,6 +40,7 @@
|
|
|
36
40
|
"muted": "#9a9ca6",
|
|
37
41
|
"line": "#2a2b33",
|
|
38
42
|
"line-strong": "#383944",
|
|
43
|
+
"line-control": "#6a6d78",
|
|
39
44
|
"action": "#f2f3f5",
|
|
40
45
|
"action-hover": "#ffffff",
|
|
41
46
|
"on-action": "#0d0d12",
|
|
@@ -47,6 +52,9 @@
|
|
|
47
52
|
"success-soft": "#132a22",
|
|
48
53
|
"warning": "#e0b341",
|
|
49
54
|
"warning-soft": "#2b2410",
|
|
55
|
+
"danger": "#ff6b5a",
|
|
56
|
+
"danger-soft": "#2e1714",
|
|
57
|
+
"on-danger": "#0d0d12",
|
|
50
58
|
"night": "#0a0b10",
|
|
51
59
|
"night-2": "#12141c",
|
|
52
60
|
"on-night": "#e3e4e8",
|
|
@@ -62,7 +70,8 @@
|
|
|
62
70
|
"roles": {
|
|
63
71
|
"action": "The thing you click: ink, or the brand's accent when the site chose the accent action profile (profiles.action).",
|
|
64
72
|
"accent": "Links, focus rings, active state, a chart line, the 8px label square; the primary button only through the accent action profile. Never body text, never words in a heading, never a section band.",
|
|
65
|
-
"success/warning": "State only. Their -soft tints are grounds: a tip or a warning callout, a success badge.",
|
|
73
|
+
"success/warning/danger": "State only. Their -soft tints are grounds: a tip or a warning callout, a success or an error badge, a field marked invalid. danger (0.6.0, gap #28) is the dashboard's --gemboss-danger family: the words of a field's error and the fill of a destructive button (on-danger on it).",
|
|
74
|
+
"line-control": "The border of a form control (a field, a checkbox, a radio), 0.6.0: it must reach 3:1 on bg, bg-soft and surface, light and dark, where line and line-strong are hairlines that do not. Like the dashboard's --gemboss-field-line.",
|
|
66
75
|
"wash": "The hero wash and illustrations only."
|
|
67
76
|
}
|
|
68
77
|
},
|
|
@@ -86,6 +95,8 @@
|
|
|
86
95
|
"display": {
|
|
87
96
|
"h1": "clamp(40px, 4.6vw, 68px)",
|
|
88
97
|
"h2": "clamp(32px, 3.4vw, 52px)",
|
|
98
|
+
"wordmark": "clamp(40px, 9vw, 128px)",
|
|
99
|
+
"$comment": "wordmark (0.7.0): the footer's last line on gemboss.ai, the brand's name, faint, at the end of the page. Decoration only, never a heading.",
|
|
89
100
|
"weight": 600,
|
|
90
101
|
"tracking": "-0.03em"
|
|
91
102
|
},
|
package/templates/footer.html
CHANGED
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
<!--
|
|
2
|
-
Footer: one per site, the same on every page
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
Footer: one per site, the same on every page, built from this template (AGENTS.md: brands fill its rows, they never
|
|
3
|
+
invent a footer part). It is the footer of gemboss.ai (0.7.0). In order:
|
|
4
|
+
1. the brand block: logo, one sentence; OPTIONAL the Ask AI row; OPTIONAL the newsletter form (0.6.0)
|
|
5
|
+
2. three to six link columns, each a <details class="gw-footer__fold">: folded rows on phones (below 768px), open
|
|
6
|
+
columns from 768px. Headings one or two words in sentence case, four to seven links each.
|
|
7
|
+
3. OPTIONAL product-family rows: a label and two to eight products, name and one line each; repeat the <nav> for a
|
|
8
|
+
second family
|
|
9
|
+
4. the bottom row: copyright, legal links, OPTIONAL theme toggle, social links. Nothing else.
|
|
10
|
+
5. OPTIONAL the wordmark: the brand's mark and name, large and faint, decoration only
|
|
11
|
+
Replace every [bracketed] placeholder and delete the optional parts you do not use. website.js wires the folds and
|
|
12
|
+
the toggle; without it the footer still works (the browser folds the <details> by itself).
|
|
13
|
+
|
|
14
|
+
Links that leave the site carry <span class="gw-footer__ext" aria-hidden="true"></span> (a drawn ↗). A link with
|
|
15
|
+
target="_blank" also carries <span class="gw-visually-hidden"> (opens in a new tab)</span>; a link without it does not.
|
|
5
16
|
-->
|
|
6
17
|
<footer class="gw-footer">
|
|
7
18
|
<div class="gw-wrap">
|
|
@@ -9,32 +20,124 @@
|
|
|
9
20
|
<div class="gw-footer__brand">
|
|
10
21
|
<a class="gw-brand" href="/"><img class="gw-brand__mark" src="[/logo.svg]" alt="" width="26" height="26"><span class="gw-brand__name">[Brand]</span></a>
|
|
11
22
|
<p>[One sentence on what the brand does for the reader.]</p>
|
|
23
|
+
<!-- OPTIONAL Ask AI: each link opens an assistant with the same neutral question already typed, URL-encoded after
|
|
24
|
+
?q= (spaces as %20). Ask what the brand is and what it does for the reader, never a leading question. Words,
|
|
25
|
+
not the assistants' logos. -->
|
|
26
|
+
<div class="gw-footer__ask">
|
|
27
|
+
<p class="gw-footer__ask-label" id="footer-ask">Ask AI about [Brand]</p>
|
|
28
|
+
<ul aria-labelledby="footer-ask">
|
|
29
|
+
<li><a href="https://chatgpt.com/?q=[URL-encoded question]" target="_blank" rel="noopener">ChatGPT<span class="gw-visually-hidden"> (opens in a new tab)</span></a></li>
|
|
30
|
+
<li><a href="https://claude.ai/new?q=[URL-encoded question]" target="_blank" rel="noopener">Claude<span class="gw-visually-hidden"> (opens in a new tab)</span></a></li>
|
|
31
|
+
<li><a href="https://www.perplexity.ai/search/new?q=[URL-encoded question]" target="_blank" rel="noopener">Perplexity<span class="gw-visually-hidden"> (opens in a new tab)</span></a></li>
|
|
32
|
+
<li><a href="https://www.google.com/search?udm=50&q=[URL-encoded question]" target="_blank" rel="noopener">Google AI Mode<span class="gw-visually-hidden"> (opens in a new tab)</span></a></li>
|
|
33
|
+
</ul>
|
|
34
|
+
</div>
|
|
35
|
+
<!-- OPTIONAL newsletter (0.6.0): keep it only when it is wired to a list that keeps the address and sends what the
|
|
36
|
+
note promises. The note says how often and how to stop, and links to the privacy policy. No box ticked for
|
|
37
|
+
the reader, no "No thanks, I hate saving money". On send: the page sets aria-invalid="true" and the error's
|
|
38
|
+
words, or aria-busy on the button and then a role="status" line. -->
|
|
39
|
+
<form class="gw-footer__newsletter" action="[/newsletter endpoint]" method="post" novalidate>
|
|
40
|
+
<div class="gw-field">
|
|
41
|
+
<label class="gw-field__label" for="footer-email">[Product news by email]</label>
|
|
42
|
+
<div class="gw-form-inline">
|
|
43
|
+
<input class="gw-input" id="footer-email" name="email" type="email" autocomplete="email" required aria-describedby="footer-email-error footer-email-note">
|
|
44
|
+
<button class="gw-btn gw-btn--secondary" type="submit">[Subscribe]</button>
|
|
45
|
+
</div>
|
|
46
|
+
<p class="gw-field__error" id="footer-email-error"></p>
|
|
47
|
+
<p class="gw-field__hint" id="footer-email-note">[How often you write.] Unsubscribe in one click. <a href="[/privacy]">Privacy policy</a></p>
|
|
48
|
+
</div>
|
|
49
|
+
</form>
|
|
12
50
|
</div>
|
|
13
|
-
<nav
|
|
14
|
-
|
|
15
|
-
<
|
|
16
|
-
<
|
|
17
|
-
<
|
|
18
|
-
|
|
19
|
-
|
|
51
|
+
<!-- the columns: three to six. Each is a <nav> named like its heading, and the heading sits inside the <summary>. -->
|
|
52
|
+
<nav class="gw-footer__col" aria-label="[Product]">
|
|
53
|
+
<details class="gw-footer__fold">
|
|
54
|
+
<summary><h2 class="gw-footer__heading">[Product]</h2></summary>
|
|
55
|
+
<ul>
|
|
56
|
+
<li><a href="[/page]">[Page title]</a></li>
|
|
57
|
+
<li><a href="[/page]">[Page title]</a></li>
|
|
58
|
+
<li><a href="[/page]">[Page title]</a></li>
|
|
59
|
+
<li><a href="[/pricing]">[Pricing]</a></li>
|
|
60
|
+
</ul>
|
|
61
|
+
</details>
|
|
20
62
|
</nav>
|
|
21
|
-
<nav class="gw-footer__col" aria-label="[
|
|
22
|
-
<
|
|
23
|
-
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
63
|
+
<nav class="gw-footer__col" aria-label="[Use cases]">
|
|
64
|
+
<details class="gw-footer__fold">
|
|
65
|
+
<summary><h2 class="gw-footer__heading">[Use cases]</h2></summary>
|
|
66
|
+
<ul>
|
|
67
|
+
<li><a href="[/page]">[Page title]</a></li>
|
|
68
|
+
<li><a href="[/page]">[Page title]</a></li>
|
|
69
|
+
<li><a href="[/page]">[Page title]</a></li>
|
|
70
|
+
<li><a href="[/page]">[Page title]</a></li>
|
|
71
|
+
</ul>
|
|
72
|
+
</details>
|
|
73
|
+
</nav>
|
|
74
|
+
<nav class="gw-footer__col" aria-label="[Solutions]">
|
|
75
|
+
<details class="gw-footer__fold">
|
|
76
|
+
<summary><h2 class="gw-footer__heading">[Solutions]</h2></summary>
|
|
77
|
+
<ul>
|
|
78
|
+
<li><a href="[/page]">[Page title]</a></li>
|
|
79
|
+
<li><a href="[/page]">[Page title]</a></li>
|
|
80
|
+
<li><a href="[/page]">[Page title]</a></li>
|
|
81
|
+
<li><a href="[/page]">[Page title]</a></li>
|
|
82
|
+
</ul>
|
|
83
|
+
</details>
|
|
84
|
+
</nav>
|
|
85
|
+
<nav class="gw-footer__col" aria-label="[Resources]">
|
|
86
|
+
<details class="gw-footer__fold">
|
|
87
|
+
<summary><h2 class="gw-footer__heading">[Resources]</h2></summary>
|
|
88
|
+
<ul>
|
|
89
|
+
<li><a href="[/blog]">[Blog]</a></li>
|
|
90
|
+
<li><a href="[/docs]">[Docs]</a></li>
|
|
91
|
+
<li><a href="[/page]">[Page title]</a></li>
|
|
92
|
+
<li><a href="[https://another site of the brand]" rel="noopener">[Changelog]<span class="gw-footer__ext" aria-hidden="true"></span></a></li>
|
|
93
|
+
</ul>
|
|
94
|
+
</details>
|
|
95
|
+
</nav>
|
|
96
|
+
<nav class="gw-footer__col" aria-label="[Company]">
|
|
97
|
+
<details class="gw-footer__fold">
|
|
98
|
+
<summary><h2 class="gw-footer__heading">[Company]</h2></summary>
|
|
99
|
+
<ul>
|
|
100
|
+
<li><a href="[/about]">[About]</a></li>
|
|
101
|
+
<li><a href="[/careers]">[Careers]</a></li>
|
|
102
|
+
<li><a href="[/partners]">[Partners]</a></li>
|
|
103
|
+
<li><a href="[/contact]">[Contact]</a></li>
|
|
104
|
+
</ul>
|
|
105
|
+
</details>
|
|
27
106
|
</nav>
|
|
28
107
|
</div>
|
|
108
|
+
<!-- OPTIONAL product family: one <nav> per row, named like its label. Each item is the product's name (<b>) and one
|
|
109
|
+
line (<i>), a space between them. Another GemCommerce brand lists its siblings here (a GemPages site: GemBoss,
|
|
110
|
+
GemX, GemUpsells). -->
|
|
111
|
+
<nav class="gw-footer__family" aria-label="[More from Brand]">
|
|
112
|
+
<details class="gw-footer__fold">
|
|
113
|
+
<summary><h2 class="gw-footer__heading">[More from Brand]</h2></summary>
|
|
114
|
+
<ul>
|
|
115
|
+
<li><a href="[/product]"><b>[Product]</b> <i>[One line on what it is]</i></a></li>
|
|
116
|
+
<li><a href="[/product]"><b>[Product]</b> <i>[One line on what it is]</i></a></li>
|
|
117
|
+
<li><a href="[https://another site of the brand]" rel="noopener"><b>[Product]<span class="gw-footer__ext" aria-hidden="true"></span></b> <i>[One line on what it is]</i></a></li>
|
|
118
|
+
<li><a href="[https://a sibling brand's site]" target="_blank" rel="noopener"><b>[Product]<span class="gw-footer__ext" aria-hidden="true"></span></b> <i>[One line on what it is]</i><span class="gw-visually-hidden"> (opens in a new tab)</span></a></li>
|
|
119
|
+
</ul>
|
|
120
|
+
</details>
|
|
121
|
+
</nav>
|
|
29
122
|
<div class="gw-footer__bottom">
|
|
30
123
|
<span>© [Year] [Company]. All rights reserved.</span>
|
|
31
124
|
<ul aria-label="Legal">
|
|
32
125
|
<li><a href="[/privacy]">Privacy</a></li>
|
|
33
126
|
<li><a href="[/terms]">Terms</a></li>
|
|
34
127
|
</ul>
|
|
128
|
+
<!-- OPTIONAL theme toggle: the header's toggle, here instead of (or as well as) in the header -->
|
|
129
|
+
<button class="gw-theme-toggle gw-footer__toggle" type="button" data-gw-theme-toggle aria-label="Switch to dark theme"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true"><circle cx="12" cy="12" r="8"/><path d="M12 4a8 8 0 0 1 0 16z" fill="currentColor"/></svg></button>
|
|
35
130
|
<ul aria-label="Social">
|
|
36
131
|
<li><a href="[https://social profile]" rel="noopener">[Network]</a></li>
|
|
132
|
+
<li><a href="[https://social profile]" rel="noopener">[Network]</a></li>
|
|
37
133
|
</ul>
|
|
38
134
|
</div>
|
|
135
|
+
<!-- OPTIONAL wordmark: decoration (aria-hidden="true", the name is already in the brand block). The mark is an
|
|
136
|
+
inline SVG drawn in currentColor, so it takes the faint colour; an <img> cannot, so leave the mark out and keep
|
|
137
|
+
the name. Not shown on phones. -->
|
|
138
|
+
<div class="gw-footer__wordmark" aria-hidden="true">
|
|
139
|
+
<svg viewBox="[0 0 width height]">[the brand's mark, every fill and stroke "currentColor"]</svg>
|
|
140
|
+
<span>[Brand]</span>
|
|
141
|
+
</div>
|
|
39
142
|
</div>
|
|
40
143
|
</footer>
|
package/templates/page.html
CHANGED
|
@@ -95,6 +95,7 @@
|
|
|
95
95
|
</section>
|
|
96
96
|
</main>
|
|
97
97
|
|
|
98
|
+
<!-- the short footer; the full one (Ask AI, family rows, theme toggle, wordmark) is templates/footer.html -->
|
|
98
99
|
<footer class="gw-footer">
|
|
99
100
|
<div class="gw-wrap">
|
|
100
101
|
<div class="gw-footer__grid">
|
|
@@ -103,19 +104,23 @@
|
|
|
103
104
|
<p>[One sentence on what the brand does for the reader.]</p>
|
|
104
105
|
</div>
|
|
105
106
|
<nav class="gw-footer__col" aria-label="[Column heading]">
|
|
106
|
-
<
|
|
107
|
-
|
|
108
|
-
<
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
107
|
+
<details class="gw-footer__fold">
|
|
108
|
+
<summary><h2 class="gw-footer__heading">[Column heading]</h2></summary>
|
|
109
|
+
<ul>
|
|
110
|
+
<li><a href="[/page]">[Page title]</a></li>
|
|
111
|
+
<li><a href="[/page]">[Page title]</a></li>
|
|
112
|
+
<li><a href="[/page]">[Page title]</a></li>
|
|
113
|
+
</ul>
|
|
114
|
+
</details>
|
|
112
115
|
</nav>
|
|
113
116
|
<nav class="gw-footer__col" aria-label="[Column heading]">
|
|
114
|
-
<
|
|
115
|
-
|
|
116
|
-
<
|
|
117
|
-
|
|
118
|
-
|
|
117
|
+
<details class="gw-footer__fold">
|
|
118
|
+
<summary><h2 class="gw-footer__heading">[Column heading]</h2></summary>
|
|
119
|
+
<ul>
|
|
120
|
+
<li><a href="[/page]">[Page title]</a></li>
|
|
121
|
+
<li><a href="[/page]">[Page title]</a></li>
|
|
122
|
+
</ul>
|
|
123
|
+
</details>
|
|
119
124
|
</nav>
|
|
120
125
|
</div>
|
|
121
126
|
<div class="gw-footer__bottom">
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Form: a short form beside the reason to send it (a contact form, "get the guide", a demo request). Ask as little as
|
|
3
|
+
you can: one field beats a form, and a form keeps two or three fields. A question with a good guess is a choice the
|
|
4
|
+
reader confirms (a radio group with the guess checked), not a box to fill.
|
|
5
|
+
- Every field: its <label for> above the control, the error right under it, then the hint; aria-describedby names
|
|
6
|
+
the error first, then the hint. Mark the optional fields "(optional)" in the label; the placeholder is never the label.
|
|
7
|
+
- Validation is the page's: on send, set aria-invalid="true" on each wrong field and write in its .gw-field__error
|
|
8
|
+
what to do ("Enter your work email, like name@example.com"), then move the focus to the first one. The kit adds the
|
|
9
|
+
icon and the colour; the words say it, never the colour alone. Keep the empty error element in the markup.
|
|
10
|
+
- While it is sent: aria-busy="true" on the button. When the answer comes: say what happened in words in the
|
|
11
|
+
role="status" line ("Sent. We'll reply to name@example.com.").
|
|
12
|
+
- Consent boxes start unchecked, say exactly what the reader gets, and are never required to get something else.
|
|
13
|
+
- One field and its button (a newsletter, "email me the guide"): the .gw-form-inline row, see templates/footer.html.
|
|
14
|
+
Limits: three fields, one .gw-btn; no field that the team does not read.
|
|
15
|
+
-->
|
|
16
|
+
<section class="gw-section" aria-labelledby="[form-h]">
|
|
17
|
+
<div class="gw-wrap gw-split">
|
|
18
|
+
<div>
|
|
19
|
+
<p class="gw-label">[Contact]</p>
|
|
20
|
+
<h2 id="[form-h]"><span class="gw-dim">[The reader's question.]</span> [What sending this gets them.]</h2>
|
|
21
|
+
<p class="gw-lead">[One line: who answers and how.]</p>
|
|
22
|
+
</div>
|
|
23
|
+
<form class="gw-card gw-form" action="[/endpoint]" method="post" novalidate>
|
|
24
|
+
<div class="gw-field">
|
|
25
|
+
<label class="gw-field__label" for="[form-email]">[Work email]</label>
|
|
26
|
+
<input class="gw-input" id="[form-email]" name="email" type="email" autocomplete="email" required aria-describedby="[form-email]-error">
|
|
27
|
+
<p class="gw-field__error" id="[form-email]-error"></p>
|
|
28
|
+
</div>
|
|
29
|
+
<div class="gw-field">
|
|
30
|
+
<label class="gw-field__label" for="[form-message]">[What are you building?]</label>
|
|
31
|
+
<textarea class="gw-textarea" id="[form-message]" name="message" rows="3" required aria-describedby="[form-message]-error [form-message]-hint"></textarea>
|
|
32
|
+
<p class="gw-field__error" id="[form-message]-error"></p>
|
|
33
|
+
<p class="gw-field__hint" id="[form-message]-hint">[A sentence or two is enough.]</p>
|
|
34
|
+
</div>
|
|
35
|
+
<label class="gw-check"><input type="checkbox" name="[news]" value="yes"><span>[Also send me product news, once a month]</span></label>
|
|
36
|
+
<div class="gw-actions">
|
|
37
|
+
<button class="gw-btn" type="submit">[Send the request]</button>
|
|
38
|
+
<p class="gw-note" role="status"></p>
|
|
39
|
+
</div>
|
|
40
|
+
</form>
|
|
41
|
+
</div>
|
|
42
|
+
</section>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Testimonials: a rating badge and a wall of short reviews. Every one comes from a page anyone can open, and links to
|
|
3
|
+
it: the badge to the store's review page, each card to its review. Copy only what that page shows: the score and
|
|
4
|
+
the count on the day you copy them (update them when they change), the reviewer's words exactly (cut a long one
|
|
5
|
+
with an ellipsis, never reword it), their name and store as they wrote them. No review you wrote, no score you
|
|
6
|
+
averaged yourself, no source you cannot link: leave the card out. `check` warns about a badge or a card without
|
|
7
|
+
its link (rating-source).
|
|
8
|
+
- Stars: style="--gw-stars: N" and aria-label="N out of 5", the same number (0 to 5, one decimal). A number you also
|
|
9
|
+
show beside them is aria-hidden="true", so it is not read twice.
|
|
10
|
+
- The badge's icon: the generic bag below, or the store's own mark only where its brand rules allow it.
|
|
11
|
+
- Avatars are optional: a photo the reviewer made public with the review, alt="" (the name is beside it).
|
|
12
|
+
Limits: three or six cards; one to three sentences each; one badge.
|
|
13
|
+
-->
|
|
14
|
+
<section class="gw-section gw-section--soft" aria-labelledby="[reviews-h]">
|
|
15
|
+
<div class="gw-wrap">
|
|
16
|
+
<div class="gw-section__head">
|
|
17
|
+
<p class="gw-label">[Reviews]</p>
|
|
18
|
+
<h2 id="[reviews-h]"><span class="gw-dim">[What merchants say.]</span> [In their own words.]</h2>
|
|
19
|
+
<a class="gw-rating-badge" href="[https://apps.shopify.com/your-app/reviews]">
|
|
20
|
+
<span class="gw-rating-badge__icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M5 8h14l-1 12H6z"/><path d="M9 8V6a3 3 0 0 1 6 0v2"/></svg></span>
|
|
21
|
+
<span class="gw-rating-badge__body">
|
|
22
|
+
<span class="gw-rating-badge__score"><span aria-hidden="true">[4.9]</span><span class="gw-stars" role="img" aria-label="[4.9] out of 5" style="--gw-stars: 4.9"></span></span>
|
|
23
|
+
<span class="gw-rating-badge__count">[1,234] reviews on the [Shopify App Store]</span>
|
|
24
|
+
</span>
|
|
25
|
+
</a>
|
|
26
|
+
</div>
|
|
27
|
+
<ul class="gw-testimonials" role="list">
|
|
28
|
+
<li>
|
|
29
|
+
<figure class="gw-card gw-testimonial">
|
|
30
|
+
<span class="gw-stars" role="img" aria-label="[5] out of 5" style="--gw-stars: 5"></span>
|
|
31
|
+
<blockquote class="gw-testimonial__quote"><p>[The reviewer's exact words.]</p></blockquote>
|
|
32
|
+
<figcaption class="gw-testimonial__by">
|
|
33
|
+
<img class="gw-testimonial__avatar" src="[/img/reviewer.webp]" alt="" width="40" height="40" loading="lazy">
|
|
34
|
+
<span><b>[Name]</b>[Store] · <a href="[https://link to the review]">[Shopify App Store]</a></span>
|
|
35
|
+
</figcaption>
|
|
36
|
+
</figure>
|
|
37
|
+
</li>
|
|
38
|
+
<li>
|
|
39
|
+
<figure class="gw-card gw-testimonial">
|
|
40
|
+
<span class="gw-stars" role="img" aria-label="[5] out of 5" style="--gw-stars: 5"></span>
|
|
41
|
+
<blockquote class="gw-testimonial__quote"><p>[The reviewer's exact words.]</p></blockquote>
|
|
42
|
+
<figcaption class="gw-testimonial__by">
|
|
43
|
+
<span><b>[Name]</b>[Store] · <a href="[https://link to the review]">[Shopify App Store]</a></span>
|
|
44
|
+
</figcaption>
|
|
45
|
+
</figure>
|
|
46
|
+
</li>
|
|
47
|
+
<li>
|
|
48
|
+
<figure class="gw-card gw-testimonial">
|
|
49
|
+
<span class="gw-stars" role="img" aria-label="[5] out of 5" style="--gw-stars: 5"></span>
|
|
50
|
+
<blockquote class="gw-testimonial__quote"><p>[The reviewer's exact words.]</p></blockquote>
|
|
51
|
+
<figcaption class="gw-testimonial__by">
|
|
52
|
+
<span><b>[Name]</b>[Store] · <a href="[https://link to the review]">[Shopify App Store]</a></span>
|
|
53
|
+
</figcaption>
|
|
54
|
+
</figure>
|
|
55
|
+
</li>
|
|
56
|
+
</ul>
|
|
57
|
+
</div>
|
|
58
|
+
</section>
|