ultimate-jekyll-manager 1.7.2 → 1.8.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.
Files changed (85) hide show
  1. package/.claude/scheduled_tasks.lock +1 -0
  2. package/CHANGELOG.md +61 -1
  3. package/CLAUDE.md +36 -15
  4. package/README.md +4 -2
  5. package/TODO-AUTH-TESTING.md +1 -1
  6. package/dist/assets/themes/newsflash/README.md +58 -0
  7. package/dist/assets/themes/newsflash/_config.scss +138 -0
  8. package/dist/assets/themes/newsflash/_theme.js +27 -0
  9. package/dist/assets/themes/newsflash/_theme.scss +37 -0
  10. package/dist/assets/themes/newsflash/css/base/_mixins.scss +50 -0
  11. package/dist/assets/themes/newsflash/css/base/_root.scss +134 -0
  12. package/dist/assets/themes/newsflash/css/base/_typography.scss +49 -0
  13. package/dist/assets/themes/newsflash/css/base/_utilities.scss +58 -0
  14. package/dist/assets/themes/newsflash/css/components/_badges.scss +65 -0
  15. package/dist/assets/themes/newsflash/css/components/_buttons.scss +139 -0
  16. package/dist/assets/themes/newsflash/css/components/_cards.scss +52 -0
  17. package/dist/assets/themes/newsflash/css/components/_editorial.scss +182 -0
  18. package/dist/assets/themes/newsflash/css/components/_forms.scss +75 -0
  19. package/dist/assets/themes/newsflash/css/components/_infinite-scroll.scss +102 -0
  20. package/dist/assets/themes/newsflash/css/components/_panels.scss +91 -0
  21. package/dist/assets/themes/newsflash/css/components/_ticker.scss +70 -0
  22. package/dist/assets/themes/newsflash/css/layout/_general.scss +264 -0
  23. package/dist/assets/themes/newsflash/css/layout/_navigation.scss +164 -0
  24. package/dist/assets/themes/newsflash/js/initialize-tooltips.js +20 -0
  25. package/dist/assets/themes/newsflash/js/masthead-scroll.js +29 -0
  26. package/dist/assets/themes/newsflash/pages/404/index.scss +27 -0
  27. package/dist/assets/themes/newsflash/pages/about/index.scss +70 -0
  28. package/dist/assets/themes/newsflash/pages/blog/index.scss +17 -0
  29. package/dist/assets/themes/newsflash/pages/blog/post.js +29 -0
  30. package/dist/assets/themes/newsflash/pages/blog/post.scss +164 -0
  31. package/dist/assets/themes/newsflash/pages/index.scss +159 -0
  32. package/dist/assets/themes/newsflash/pages/pricing/index.scss +194 -0
  33. package/dist/assets/themes/newsflash/pages/test/libraries/layers/index.js +9 -0
  34. package/dist/assets/themes/newsflash/pages/test/libraries/layers/index.scss +7 -0
  35. package/dist/commands/blogify.js +6 -3
  36. package/dist/commands/test.js +34 -5
  37. package/dist/defaults/CLAUDE.md +17 -4
  38. package/dist/defaults/dist/_includes/core/pricing/resolve-plan.html +59 -0
  39. package/dist/defaults/dist/_includes/themes/classy/frontend/sections/footer.html +20 -3
  40. package/dist/defaults/dist/_layouts/themes/classy/admin/core/minimal-viewport-locked.html +1 -1
  41. package/dist/defaults/dist/_layouts/themes/classy/admin/core/minimal.html +1 -1
  42. package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/pricing.html +5 -40
  43. package/dist/defaults/dist/_layouts/themes/neobrutalism/frontend/pages/pricing.html +33 -34
  44. package/dist/defaults/dist/_layouts/themes/newsflash/frontend/core/base.html +61 -0
  45. package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/404.html +86 -0
  46. package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/about.html +353 -0
  47. package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/blog/categories/category.html +105 -0
  48. package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/blog/categories/index.html +93 -0
  49. package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/blog/index.html +373 -0
  50. package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/blog/post.html +289 -0
  51. package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/blog/tags/index.html +90 -0
  52. package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/blog/tags/tag.html +107 -0
  53. package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/contact.html +340 -0
  54. package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/index.html +522 -0
  55. package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/pricing.html +485 -0
  56. package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/team/index.html +207 -0
  57. package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/team/member.html +134 -0
  58. package/dist/defaults/test/README.md +4 -0
  59. package/dist/gulp/tasks/jekyll.js +4 -2
  60. package/dist/test/runner.js +50 -3
  61. package/dist/test/suites/build/attach-log-file.test.js +102 -0
  62. package/dist/test/suites/build/theme-contract.test.js +173 -0
  63. package/dist/test/utils/extended-mode-warning.js +13 -0
  64. package/dist/utils/attach-log-file.js +70 -43
  65. package/docs/appearance.md +1 -0
  66. package/docs/assets.md +9 -0
  67. package/docs/audit.md +27 -7
  68. package/docs/build-system.md +57 -0
  69. package/docs/common-mistakes.md +15 -0
  70. package/docs/{project-structure.md → directory-structure.md} +1 -1
  71. package/docs/environment-detection.md +1 -1
  72. package/docs/javascript-libraries.md +38 -1
  73. package/docs/layouts-and-pages.md +146 -0
  74. package/docs/local-development.md +1 -8
  75. package/docs/logging.md +30 -0
  76. package/docs/migration.md +131 -0
  77. package/docs/no-inline-scripts.md +304 -0
  78. package/docs/purgecss.md +164 -0
  79. package/docs/seo.md +131 -4
  80. package/docs/templating.md +23 -0
  81. package/docs/test-boot-layer.md +1 -1
  82. package/docs/test-framework.md +56 -8
  83. package/docs/themes.md +254 -13
  84. package/logs/test.log +111 -0
  85. package/package.json +1 -1
@@ -0,0 +1,340 @@
1
+ ---
2
+ ### ALL PAGES ###
3
+ layout: themes/[ site.theme.id ]/frontend/core/base
4
+
5
+ ### PAGE CONFIG ###
6
+ # News voice throughout: a theme's frontmatter defaults are part of its
7
+ # identity (see docs/themes.md "Frontmatter defaults").
8
+ # Hero Section
9
+ hero:
10
+ headline: "Contact the"
11
+ headline_accent: "desk"
12
+ subheadline: "Questions, tips, corrections — the {{ site.brand.name }} newsroom reads everything"
13
+
14
+ # Contact Methods Section
15
+ contact_methods:
16
+ - title: "Email the newsroom"
17
+ description: "Get a reply within 24 hours"
18
+ icon: "envelope"
19
+ value: "Email us"
20
+ link: "#form"
21
+ - title: "Send a tip"
22
+ description: "Confidential — straight to our reporters"
23
+ icon: "user-secret"
24
+ value: "Share a tip"
25
+ link: "#form"
26
+
27
+ # Contact Form Section
28
+ contact_form:
29
+ superheadline:
30
+ icon: "envelope"
31
+ text: "The mailbag"
32
+ headline: "Send us a"
33
+ headline_accent: "message"
34
+ subheadline: "Fill out the form below and we'll get back to you within 24 hours."
35
+
36
+ # Stats Section
37
+ stats:
38
+ items:
39
+ - number: "<15m"
40
+ label: "Response time"
41
+ icon: "clock"
42
+ color: "primary"
43
+ - number: "24/7"
44
+ label: "Tips line"
45
+ icon: "user-secret"
46
+ color: "success"
47
+ - number: "4.9"
48
+ label: "Reader rating"
49
+ icon: "star"
50
+ color: "warning"
51
+ - number: "50+"
52
+ label: "Languages"
53
+ icon: "globe"
54
+ color: "info"
55
+
56
+ # Testimonials Section
57
+ testimonials:
58
+ superheadline:
59
+ icon: "megaphone"
60
+ text: "From our readers"
61
+ headline: "What our readers"
62
+ headline_accent: "say"
63
+ subheadline: "Hear from people who've written to the desk"
64
+ items:
65
+ - quote: "I flagged a typo at 7am and had a reply from an actual editor by 7:15."
66
+ author: "Jessica Martinez"
67
+ role: "Marketing Manager"
68
+ company: "TechCorp"
69
+ initial: "J"
70
+ - quote: "Sent a tip on a Friday night. They ran the story — and protected the source."
71
+ author: "David Thompson"
72
+ role: "Product Designer"
73
+ company: "StartupCo"
74
+ initial: "D"
75
+ - quote: "The rare publication that answers reader mail like it matters. Because to them it does."
76
+ author: "Lisa Chen"
77
+ role: "Developer"
78
+ company: "InnovateLab"
79
+ initial: "L"
80
+
81
+ # FAQs Section
82
+ faqs:
83
+ superheadline:
84
+ icon: "messages-question"
85
+ text: "FAQs"
86
+ headline: "Frequently asked"
87
+ headline_accent: "questions"
88
+ subheadline: "Everything you need to know about reaching the newsroom."
89
+ items:
90
+ - question: "How do I submit a news tip?"
91
+ answer: "Use the form above and choose \"News tip\" as the subject — it routes straight to our reporters. We protect our sources and never publish identifying details without consent."
92
+ - question: "How do I request a correction?"
93
+ answer: "Choose \"Request a correction\" in the form and include a link to the story. We review every report, fix verified errors fast, and log them on our public corrections page."
94
+ - question: "Can I republish your stories?"
95
+ answer: "Often, yes! Choose \"Press & partnerships\" and tell us what you'd like to republish — we offer syndication arrangements for most of our reporting."
96
+ ---
97
+
98
+ {% comment %}
99
+ NEWSFLASH CONTACT
100
+ Same data contract as the classy contact page, presented as "contact the
101
+ desk": serif masthead opening, framed contact-method cards, the contact form
102
+ (markup kept verbatim — FormManager wiring) inside a framed paper card,
103
+ stroked-numeral support stats, and the FAQ accordion.
104
+ {% endcomment %}
105
+
106
+ <!-- Hero -->
107
+ <section class="pb-4">
108
+ <div class="container text-center" data-lazy="@class animation-slide-up">
109
+ <span class="kicker mb-3">Contact</span>
110
+ <h1 class="display-4 my-3">
111
+ {{ page.resolved.hero.headline }} <span class="text-accent">{{ page.resolved.hero.headline_accent }}</span>
112
+ </h1>
113
+ {% iftruthy page.resolved.hero.subheadline %}
114
+ <p class="lead mb-0">{{ page.resolved.hero.subheadline }}</p>
115
+ {% endiftruthy %}
116
+ </div>
117
+ </section>
118
+
119
+ <!-- Contact Methods -->
120
+ <section class="pt-0">
121
+ <div class="container">
122
+ <div class="row g-4 justify-content-center">
123
+ {% assign method_count = page.resolved.contact_methods | size %}
124
+
125
+ <!-- Determine column classes based on number of contact methods -->
126
+ {% if method_count == 1 %}
127
+ {% assign col_classes = "col-12 col-md-8 col-lg-6 col-xl-5" %}
128
+ {% elsif method_count == 2 %}
129
+ {% assign col_classes = "col-12 col-md-6 col-lg-6 col-xl-5" %}
130
+ {% elsif method_count == 3 %}
131
+ {% assign col_classes = "col-12 col-md-6 col-lg-4" %}
132
+ {% elsif method_count == 4 %}
133
+ {% assign col_classes = "col-12 col-md-6 col-lg-6 col-xl-3" %}
134
+ {% elsif method_count == 5 %}
135
+ {% assign col_classes = "col-12 col-md-6 col-lg-4" %}
136
+ {% else %}
137
+ <!-- Fallback for 6+ methods -->
138
+ {% assign col_classes = "col-12 col-md-6 col-lg-4 col-xl-3" %}
139
+ {% endif %}
140
+
141
+ {% for method in page.resolved.contact_methods %}
142
+ <div class="{{ col_classes }}">
143
+ <div class="card h-100 text-center p-4" data-lazy="@class animation-slide-up">
144
+ <span class="feature-icon d-inline-flex align-items-center justify-content-center rounded-circle text-bg-primary mb-3 mx-auto">
145
+ {% uj_icon method.icon %}
146
+ </span>
147
+ <h3 class="h5 mb-1">{{ method.title }}</h3>
148
+ <p class="text-body-secondary mb-3">{{ method.description }}</p>
149
+ <div>
150
+ <a href="{{ method.link }}" class="btn btn-outline-dark btn-sm">{{ method.value }}</a>
151
+ </div>
152
+ </div>
153
+ </div>
154
+ {% endfor %}
155
+ </div>
156
+ </div>
157
+ </section>
158
+
159
+ <!-- Contact Form -->
160
+ <section id="form" class="pt-0">
161
+ <div class="container">
162
+ <div class="row justify-content-center">
163
+ <div class="col-lg-8">
164
+ <div class="card shadow" data-lazy="@class animation-slide-up">
165
+ <div class="card-body p-4 p-md-5">
166
+ <div class="text-center mb-4">
167
+ {% iftruthy page.resolved.contact_form.superheadline.text %}
168
+ <span class="kicker mb-2">
169
+ {% iftruthy page.resolved.contact_form.superheadline.icon %}
170
+ {% uj_icon page.resolved.contact_form.superheadline.icon, "me-1" %}
171
+ {% endiftruthy %}
172
+ {{ page.resolved.contact_form.superheadline.text }}
173
+ </span>
174
+ {% endiftruthy %}
175
+ <h2 class="h3 mb-2">
176
+ {{ page.resolved.contact_form.headline }}
177
+ {% iftruthy page.resolved.contact_form.headline_accent %}
178
+ <span class="text-accent">{{ page.resolved.contact_form.headline_accent }}</span>
179
+ {% endiftruthy %}
180
+ </h2>
181
+ {% iftruthy page.resolved.contact_form.subheadline %}
182
+ <p class="text-body-secondary">{{ page.resolved.contact_form.subheadline }}</p>
183
+ {% endiftruthy %}
184
+ </div>
185
+
186
+ <form id="contact-form" autocomplete="on" onsubmit="return false">
187
+ <div class="row g-3 mb-4">
188
+ <div class="col-md-6">
189
+ <label for="first_name" class="form-label fw-semibold">First name <span class="text-danger">*</span></label>
190
+ <input type="text" class="form-control form-control-lg" id="first_name" name="first_name"
191
+ placeholder="Enter your first name"
192
+ autocomplete="given-name"
193
+ minlength="2"
194
+ maxlength="50"
195
+ required>
196
+ <div class="invalid-feedback"></div>
197
+ </div>
198
+ <div class="col-md-6">
199
+ <label for="last_name" class="form-label fw-semibold">Last name <span class="text-danger">*</span></label>
200
+ <input type="text" class="form-control form-control-lg" id="last_name" name="last_name"
201
+ placeholder="Enter your last name"
202
+ autocomplete="family-name"
203
+ minlength="2"
204
+ maxlength="50"
205
+ required>
206
+ <div class="invalid-feedback"></div>
207
+ </div>
208
+ </div>
209
+
210
+ <!-- Honeypot field (bot detection) -->
211
+ <div class="form-group mb-3" style="display: none;" aria-hidden="true">
212
+ <input type="text" class="form-control" name="honey" tabindex="-1" autocomplete="off">
213
+ </div>
214
+
215
+ <!-- Hidden auth field (auto-populated via bindings) -->
216
+ <input type="hidden" aria-hidden="true" name="uid" data-wm-bind="@value auth.user.uid">
217
+
218
+ <div class="mb-4">
219
+ <label for="email" class="form-label fw-semibold">Email address <span class="text-danger">*</span></label>
220
+ <input type="email" class="form-control form-control-lg" id="email" name="email"
221
+ placeholder="Enter your email address"
222
+ autocomplete="email"
223
+ data-wm-bind="@value auth.user.email"
224
+ required>
225
+ <div class="invalid-feedback"></div>
226
+ </div>
227
+
228
+ <div class="mb-4">
229
+ <label for="company" class="form-label fw-semibold">Company</label>
230
+ <input type="text" class="form-control form-control-lg" id="company" name="company"
231
+ placeholder="Enter your company name (optional)"
232
+ autocomplete="organization"
233
+ maxlength="100">
234
+ </div>
235
+
236
+ <div class="mb-4">
237
+ <label for="subject" class="form-label fw-semibold">Subject <span class="text-danger">*</span></label>
238
+ <select class="form-select form-select-lg" id="subject" name="subject" required>
239
+ <option value="">Choose a topic...</option>
240
+ <option value="general">General inquiry</option>
241
+ <option value="tip">News tip</option>
242
+ <option value="correction">Request a correction</option>
243
+ <option value="partnership">Press & partnerships</option>
244
+ <option value="billing">Membership & billing</option>
245
+ <option value="other">Other</option>
246
+ </select>
247
+ <div class="invalid-feedback"></div>
248
+ </div>
249
+
250
+ <div class="mb-4">
251
+ <label for="message" class="form-label fw-semibold">Message <span class="text-danger">*</span></label>
252
+ <textarea class="form-control form-control-lg" id="message" name="message" rows="3"
253
+ placeholder="Tell us how we can help you..."
254
+ minlength="10"
255
+ maxlength="5000"
256
+ required></textarea>
257
+ <div class="invalid-feedback"></div>
258
+ </div>
259
+
260
+ <div class="d-grid gap-2 d-md-flex justify-content-md-between align-items-center">
261
+ <button type="submit" class="btn btn-primary btn-lg px-5">
262
+ {% uj_icon "paper-plane", "me-2" %}
263
+ Send message
264
+ </button>
265
+ <a href="{{ site.url }}" class="btn btn-link">
266
+ {% uj_icon "arrow-left", "me-1" %}
267
+ Back to home
268
+ </a>
269
+ </div>
270
+ </form>
271
+ </div>
272
+ </div>
273
+ </div>
274
+ </div>
275
+ </div>
276
+ </section>
277
+
278
+ <!-- Stats -->
279
+ <section class="pt-0">
280
+ <div class="container">
281
+ <div class="section-head" data-lazy="@class animation-slide-up">
282
+ <h2>The support desk</h2>
283
+ <span class="rule"></span>
284
+ </div>
285
+ <div class="row text-center g-4">
286
+ {% for stat in page.resolved.stats.items %}
287
+ <div class="col-lg-3 col-md-6" data-lazy="@class animation-slide-up">
288
+ <div class="stat-num">{{ stat.number }}</div>
289
+ <div class="fw-bold">{% uj_icon stat.icon, "me-2 text-primary" %}{{ stat.label }}</div>
290
+ </div>
291
+ {% endfor %}
292
+ </div>
293
+ </div>
294
+ </section>
295
+
296
+ <!-- FAQ -->
297
+ <section class="pt-0">
298
+ <div class="container">
299
+ <div class="row justify-content-center">
300
+ <div class="col-lg-8">
301
+ <div class="section-head" data-lazy="@class animation-slide-up">
302
+ {% iftruthy page.resolved.faqs.superheadline.text %}
303
+ <h2>{{ page.resolved.faqs.superheadline.text }}</h2>
304
+ {% endiftruthy %}
305
+ <span class="rule"></span>
306
+ </div>
307
+ <header class="mb-4" data-lazy="@class animation-slide-up">
308
+ <h2 class="h1 mb-2">
309
+ {{ page.resolved.faqs.headline }}
310
+ {% iftruthy page.resolved.faqs.headline_accent %}
311
+ <span class="text-accent">{{ page.resolved.faqs.headline_accent }}</span>
312
+ {% endiftruthy %}
313
+ </h2>
314
+ {% iftruthy page.resolved.faqs.subheadline %}
315
+ <p class="lead mb-0">{{ page.resolved.faqs.subheadline }}</p>
316
+ {% endiftruthy %}
317
+ </header>
318
+
319
+ {% if page.resolved.faqs.items %}
320
+ <div class="accordion" id="contactFaqAccordion">
321
+ {% for faq in page.resolved.faqs.items %}
322
+ <div class="accordion-item mb-3" data-lazy="@class animation-slide-up">
323
+ <h2 class="accordion-header">
324
+ <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#contactFaq{{ forloop.index }}" aria-expanded="false" aria-controls="contactFaq{{ forloop.index }}">
325
+ <span class="fw-bold">{{ faq.question }}</span>
326
+ </button>
327
+ </h2>
328
+ <div id="contactFaq{{ forloop.index }}" class="accordion-collapse collapse" data-bs-parent="#contactFaqAccordion">
329
+ <div class="accordion-body">{{ faq.answer }}</div>
330
+ </div>
331
+ </div>
332
+ {% endfor %}
333
+ </div>
334
+ {% endif %}
335
+ </div>
336
+ </div>
337
+ </div>
338
+ </section>
339
+
340
+ {{ content | uj_content_format }}