plum-cms 0.1.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 (178) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +20 -0
  3. data/LICENSE.txt +21 -0
  4. data/README.md +252 -0
  5. data/app/assets/builds/tailwind.css +2 -0
  6. data/app/assets/images/plum-mark.svg +7 -0
  7. data/app/assets/images/table-needs-logo.svg +83 -0
  8. data/app/assets/javascripts/plum/application.js +15 -0
  9. data/app/assets/stylesheets/application.css +10 -0
  10. data/app/assets/stylesheets/plum/control_panel.css +2 -0
  11. data/app/assets/tailwind/application.css +47 -0
  12. data/app/controllers/plum/application_controller.rb +34 -0
  13. data/app/controllers/plum/cp/assets_controller.rb +84 -0
  14. data/app/controllers/plum/cp/base_controller.rb +45 -0
  15. data/app/controllers/plum/cp/content_types_controller.rb +59 -0
  16. data/app/controllers/plum/cp/dashboard_controller.rb +10 -0
  17. data/app/controllers/plum/cp/entries_controller.rb +240 -0
  18. data/app/controllers/plum/cp/form_definitions_controller.rb +105 -0
  19. data/app/controllers/plum/cp/form_submissions_controller.rb +26 -0
  20. data/app/controllers/plum/cp/globals_controller.rb +84 -0
  21. data/app/controllers/plum/cp/nav_items_controller.rb +68 -0
  22. data/app/controllers/plum/cp/nav_menus_controller.rb +56 -0
  23. data/app/controllers/plum/cp/site_settings_controller.rb +87 -0
  24. data/app/controllers/plum/cp/taxonomies_controller.rb +56 -0
  25. data/app/controllers/plum/cp/terms_controller.rb +55 -0
  26. data/app/controllers/plum/cp/theme_previews_controller.rb +27 -0
  27. data/app/controllers/plum/cp/themes_controller.rb +98 -0
  28. data/app/controllers/plum/form_submissions_controller.rb +44 -0
  29. data/app/controllers/plum/pages_controller.rb +161 -0
  30. data/app/controllers/plum/sessions_controller.rb +25 -0
  31. data/app/controllers/plum/theme_assets_controller.rb +14 -0
  32. data/app/helpers/application_helper.rb +2 -0
  33. data/app/helpers/markdown_helper.rb +21 -0
  34. data/app/helpers/plum/cp/assets_helper.rb +21 -0
  35. data/app/helpers/plum/cp/theme_settings_helper.rb +26 -0
  36. data/app/javascript/application.js +18 -0
  37. data/app/javascript/controllers/application.js +9 -0
  38. data/app/javascript/controllers/index.js +4 -0
  39. data/app/javascript/controllers/plum/blocks_editor_controller.js +275 -0
  40. data/app/javascript/controllers/plum/blueprint_controller.js +120 -0
  41. data/app/javascript/controllers/plum/form_fields_controller.js +84 -0
  42. data/app/javascript/controllers/plum/image_picker_controller.js +143 -0
  43. data/app/javascript/controllers/plum/theme_settings_controller.js +17 -0
  44. data/app/models/plum/application_record.rb +5 -0
  45. data/app/models/plum/asset.rb +69 -0
  46. data/app/models/plum/content_type.rb +35 -0
  47. data/app/models/plum/entry.rb +67 -0
  48. data/app/models/plum/entry_term.rb +8 -0
  49. data/app/models/plum/form_definition.rb +68 -0
  50. data/app/models/plum/form_submission.rb +76 -0
  51. data/app/models/plum/global.rb +24 -0
  52. data/app/models/plum/nav_item.rb +58 -0
  53. data/app/models/plum/nav_menu.rb +24 -0
  54. data/app/models/plum/site.rb +112 -0
  55. data/app/models/plum/site_scoped.rb +17 -0
  56. data/app/models/plum/site_setting.rb +35 -0
  57. data/app/models/plum/taxonomy.rb +24 -0
  58. data/app/models/plum/term.rb +23 -0
  59. data/app/models/plum/user.rb +16 -0
  60. data/app/services/plum/base_blocks.rb +161 -0
  61. data/app/services/plum/block_editor_config.rb +65 -0
  62. data/app/services/plum/block_library.rb +31 -0
  63. data/app/services/plum/builder_renderer.rb +63 -0
  64. data/app/services/plum/field_expander.rb +78 -0
  65. data/app/services/plum/form_renderer.rb +110 -0
  66. data/app/services/plum/liquid_context.rb +335 -0
  67. data/app/services/plum/liquid_filters.rb +58 -0
  68. data/app/services/plum/liquid_renderer.rb +49 -0
  69. data/app/services/plum/theme.rb +160 -0
  70. data/app/services/plum/theme_asset_path.rb +31 -0
  71. data/app/services/plum/theme_package_installer.rb +287 -0
  72. data/app/services/plum/theme_registry.rb +63 -0
  73. data/app/services/plum/theme_resolver.rb +55 -0
  74. data/app/services/plum/theme_settings_params.rb +54 -0
  75. data/app/themes/bagel-boy/assets/screenshot.svg +92 -0
  76. data/app/themes/bagel-boy/assets/theme.css +184 -0
  77. data/app/themes/bagel-boy/blocks/hours.liquid +4 -0
  78. data/app/themes/bagel-boy/blocks/menu_item.liquid +7 -0
  79. data/app/themes/bagel-boy/layouts/base.liquid +64 -0
  80. data/app/themes/bagel-boy/templates/collections/posts.liquid +32 -0
  81. data/app/themes/bagel-boy/templates/entries/_default.liquid +13 -0
  82. data/app/themes/bagel-boy/templates/entries/landing.liquid +4 -0
  83. data/app/themes/bagel-boy/templates/entries/pages.liquid +18 -0
  84. data/app/themes/bagel-boy/templates/entries/posts.liquid +8 -0
  85. data/app/themes/bagel-boy/templates/index.liquid +10 -0
  86. data/app/themes/bagel-boy/templates/search.liquid +28 -0
  87. data/app/themes/bagel-boy/theme.yml +47 -0
  88. data/app/themes/bagel-shop/assets/screenshot.svg +28 -0
  89. data/app/themes/bagel-shop/assets/theme.css +7 -0
  90. data/app/themes/bagel-shop/layouts/base.liquid +507 -0
  91. data/app/themes/bagel-shop/templates/entries/_default.liquid +15 -0
  92. data/app/themes/bagel-shop/templates/entries/pages.liquid +12 -0
  93. data/app/themes/bagel-shop/templates/entries/posts.liquid +19 -0
  94. data/app/themes/bagel-shop/templates/index.liquid +55 -0
  95. data/app/themes/bagel-shop/theme.yml +30 -0
  96. data/app/themes/default/assets/screenshot.svg +24 -0
  97. data/app/themes/default/assets/theme.css +89 -0
  98. data/app/themes/default/layouts/base.liquid +117 -0
  99. data/app/themes/default/templates/collections/_default.liquid +16 -0
  100. data/app/themes/default/templates/collections/posts.liquid +27 -0
  101. data/app/themes/default/templates/entries/_default.liquid +26 -0
  102. data/app/themes/default/templates/entries/landing.liquid +5 -0
  103. data/app/themes/default/templates/entries/pages.liquid +17 -0
  104. data/app/themes/default/templates/entries/posts.liquid +20 -0
  105. data/app/themes/default/templates/index.liquid +22 -0
  106. data/app/themes/default/templates/search.liquid +28 -0
  107. data/app/themes/default/templates/taxonomies/_default.liquid +25 -0
  108. data/app/themes/default/templates/taxonomies/_default_index.liquid +14 -0
  109. data/app/themes/default/theme.yml +23 -0
  110. data/app/views/layouts/plum/cp.html.erb +138 -0
  111. data/app/views/layouts/plum/session.html.erb +43 -0
  112. data/app/views/plum/cp/assets/_form.html.erb +44 -0
  113. data/app/views/plum/cp/assets/edit.html.erb +14 -0
  114. data/app/views/plum/cp/assets/index.html.erb +52 -0
  115. data/app/views/plum/cp/assets/new.html.erb +9 -0
  116. data/app/views/plum/cp/content_types/_form.html.erb +113 -0
  117. data/app/views/plum/cp/content_types/edit.html.erb +8 -0
  118. data/app/views/plum/cp/content_types/index.html.erb +48 -0
  119. data/app/views/plum/cp/content_types/new.html.erb +5 -0
  120. data/app/views/plum/cp/content_types/show.html.erb +59 -0
  121. data/app/views/plum/cp/dashboard/show.html.erb +50 -0
  122. data/app/views/plum/cp/entries/_form.html.erb +196 -0
  123. data/app/views/plum/cp/entries/edit.html.erb +9 -0
  124. data/app/views/plum/cp/entries/index.html.erb +51 -0
  125. data/app/views/plum/cp/entries/new.html.erb +5 -0
  126. data/app/views/plum/cp/form_definitions/_form.html.erb +90 -0
  127. data/app/views/plum/cp/form_definitions/edit.html.erb +11 -0
  128. data/app/views/plum/cp/form_definitions/index.html.erb +43 -0
  129. data/app/views/plum/cp/form_definitions/new.html.erb +5 -0
  130. data/app/views/plum/cp/form_definitions/show.html.erb +70 -0
  131. data/app/views/plum/cp/form_submissions/show.html.erb +20 -0
  132. data/app/views/plum/cp/globals/_form.html.erb +44 -0
  133. data/app/views/plum/cp/globals/edit.html.erb +11 -0
  134. data/app/views/plum/cp/globals/index.html.erb +41 -0
  135. data/app/views/plum/cp/globals/new.html.erb +5 -0
  136. data/app/views/plum/cp/globals/show.html.erb +14 -0
  137. data/app/views/plum/cp/nav_items/_form.html.erb +56 -0
  138. data/app/views/plum/cp/nav_items/edit.html.erb +11 -0
  139. data/app/views/plum/cp/nav_items/new.html.erb +6 -0
  140. data/app/views/plum/cp/nav_menus/_form.html.erb +33 -0
  141. data/app/views/plum/cp/nav_menus/_nav_item.html.erb +24 -0
  142. data/app/views/plum/cp/nav_menus/edit.html.erb +11 -0
  143. data/app/views/plum/cp/nav_menus/index.html.erb +41 -0
  144. data/app/views/plum/cp/nav_menus/new.html.erb +5 -0
  145. data/app/views/plum/cp/nav_menus/show.html.erb +24 -0
  146. data/app/views/plum/cp/shared/_icon.html.erb +39 -0
  147. data/app/views/plum/cp/shared/_image_picker.html.erb +38 -0
  148. data/app/views/plum/cp/site_settings/edit.html.erb +145 -0
  149. data/app/views/plum/cp/site_settings/show.html.erb +62 -0
  150. data/app/views/plum/cp/taxonomies/_form.html.erb +38 -0
  151. data/app/views/plum/cp/taxonomies/edit.html.erb +2 -0
  152. data/app/views/plum/cp/taxonomies/index.html.erb +38 -0
  153. data/app/views/plum/cp/taxonomies/new.html.erb +2 -0
  154. data/app/views/plum/cp/taxonomies/show.html.erb +46 -0
  155. data/app/views/plum/cp/terms/_form.html.erb +30 -0
  156. data/app/views/plum/cp/terms/edit.html.erb +2 -0
  157. data/app/views/plum/cp/terms/new.html.erb +2 -0
  158. data/app/views/plum/cp/themes/index.html.erb +160 -0
  159. data/app/views/plum/form_mailer/submission_notification.html.erb +13 -0
  160. data/app/views/plum/form_mailer/submission_notification.text.erb +7 -0
  161. data/app/views/plum/sessions/new.html.erb +20 -0
  162. data/compat/plum-cms.rb +1 -0
  163. data/config/locales/en.yml +31 -0
  164. data/config/plum_importmap.rb +4 -0
  165. data/config/plum_routes.rb +34 -0
  166. data/db/engine_migrate/20260101000001_create_plum_tables.rb +154 -0
  167. data/lib/generators/plum/install/install_generator.rb +54 -0
  168. data/lib/generators/plum/install/templates/plum_initializer.rb +37 -0
  169. data/lib/plum/configuration.rb +88 -0
  170. data/lib/plum/content_source.rb +45 -0
  171. data/lib/plum/content_source_context.rb +30 -0
  172. data/lib/plum/content_source_registry.rb +120 -0
  173. data/lib/plum/engine.rb +30 -0
  174. data/lib/plum/liquid_tags/form_tag.rb +17 -0
  175. data/lib/plum/version.rb +7 -0
  176. data/lib/plum.rb +11 -0
  177. data/vendor/javascript/lexxy.js +11859 -0
  178. metadata +405 -0
@@ -0,0 +1,507 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>{{ entry.title | default: site.seo_title | default: site.name }} - {{ site.name }}</title>
7
+ <meta name="description" content="{{ site.seo_description }}">
8
+ <link rel="icon" href="/icon.svg" type="image/svg+xml">
9
+ <link rel="stylesheet" href="{{ 'theme.css' | theme_asset_url }}">
10
+ <style>
11
+ :root {
12
+ --bagel-ink: #2b2119;
13
+ --bagel-muted: #765f4b;
14
+ --bagel-paper: #fffaf0;
15
+ --bagel-cream: #f5e7cf;
16
+ --bagel-crust: #b9652d;
17
+ --bagel-crust-dark: #7d3f1d;
18
+ --bagel-accent: {{ site.theme_settings.accent_color | default: site.primary_color | default: "#1f6f63" }};
19
+ --bagel-radius: {% if site.theme_settings.corner_style == "square" %}0.15rem{% else %}0.5rem{% endif %};
20
+ }
21
+
22
+ * { box-sizing: border-box; margin: 0; padding: 0; }
23
+
24
+ body {
25
+ background: var(--bagel-paper);
26
+ color: var(--bagel-ink);
27
+ font-family: ui-serif, Georgia, Cambria, "Times New Roman", serif;
28
+ line-height: 1.65;
29
+ }
30
+
31
+ a { color: inherit; }
32
+
33
+ .page {
34
+ min-height: 100vh;
35
+ display: flex;
36
+ flex-direction: column;
37
+ }
38
+
39
+ .site-header {
40
+ border-bottom: 2px solid rgba(43, 33, 25, 0.12);
41
+ background: #fff7e8;
42
+ }
43
+
44
+ .header-inner {
45
+ max-width: 1080px;
46
+ margin: 0 auto;
47
+ padding: 1.1rem 1.25rem;
48
+ display: flex;
49
+ align-items: center;
50
+ justify-content: space-between;
51
+ gap: 1rem;
52
+ }
53
+
54
+ .brand {
55
+ display: inline-flex;
56
+ align-items: center;
57
+ gap: 0.8rem;
58
+ color: var(--bagel-ink);
59
+ text-decoration: none;
60
+ min-width: 0;
61
+ }
62
+
63
+ .bagel-mark {
64
+ width: 3rem;
65
+ height: 3rem;
66
+ flex: 0 0 auto;
67
+ border-radius: 50%;
68
+ background:
69
+ radial-gradient(circle at center, var(--bagel-paper) 0 23%, transparent 24%),
70
+ radial-gradient(circle at 38% 28%, #f7d58a 0 5%, transparent 6%),
71
+ radial-gradient(circle at 64% 35%, #f7d58a 0 4%, transparent 5%),
72
+ radial-gradient(circle at 50% 67%, #f7d58a 0 4%, transparent 5%),
73
+ linear-gradient(140deg, #d99045, var(--bagel-crust) 62%, var(--bagel-crust-dark));
74
+ box-shadow: inset -0.25rem -0.35rem 0 rgba(69, 38, 19, 0.18), 0 0.2rem 0 rgba(43, 33, 25, 0.14);
75
+ }
76
+
77
+ .brand-name {
78
+ display: block;
79
+ font-size: 2.2rem;
80
+ line-height: 1;
81
+ font-weight: 800;
82
+ letter-spacing: 0;
83
+ }
84
+
85
+ .brand-tagline {
86
+ display: block;
87
+ margin-top: 0.2rem;
88
+ color: var(--bagel-muted);
89
+ font-family: ui-sans-serif, system-ui, sans-serif;
90
+ font-size: 0.88rem;
91
+ }
92
+
93
+ .header-link {
94
+ color: var(--bagel-accent);
95
+ font-family: ui-sans-serif, system-ui, sans-serif;
96
+ font-size: 0.9rem;
97
+ font-weight: 700;
98
+ text-decoration: none;
99
+ white-space: nowrap;
100
+ }
101
+
102
+ .header-actions {
103
+ display: flex;
104
+ align-items: center;
105
+ justify-content: flex-end;
106
+ gap: 1rem;
107
+ flex-wrap: wrap;
108
+ }
109
+
110
+ .site-nav {
111
+ display: flex;
112
+ align-items: center;
113
+ justify-content: flex-end;
114
+ gap: 0.4rem 0.9rem;
115
+ flex-wrap: wrap;
116
+ font-family: ui-sans-serif, system-ui, sans-serif;
117
+ font-size: 0.9rem;
118
+ font-weight: 700;
119
+ }
120
+
121
+ .site-nav a {
122
+ color: var(--bagel-ink);
123
+ text-decoration: none;
124
+ }
125
+
126
+ .site-nav a:hover {
127
+ color: var(--bagel-accent);
128
+ }
129
+
130
+ main {
131
+ flex: 1;
132
+ }
133
+
134
+ .wrap {
135
+ width: min(1080px, calc(100% - 2rem));
136
+ margin: 0 auto;
137
+ }
138
+
139
+ .hero {
140
+ display: grid;
141
+ grid-template-columns: minmax(0, 1fr) 18rem;
142
+ gap: 3rem;
143
+ align-items: center;
144
+ padding: 6rem 0;
145
+ border-bottom: 2px solid rgba(43, 33, 25, 0.12);
146
+ }
147
+
148
+ .kicker {
149
+ display: inline-block;
150
+ margin-bottom: 1rem;
151
+ color: var(--bagel-accent);
152
+ font-family: ui-sans-serif, system-ui, sans-serif;
153
+ font-size: 0.78rem;
154
+ font-weight: 800;
155
+ letter-spacing: 0;
156
+ text-transform: uppercase;
157
+ }
158
+
159
+ h1 {
160
+ max-width: 13ch;
161
+ font-size: 6.5rem;
162
+ line-height: 0.92;
163
+ letter-spacing: 0;
164
+ }
165
+
166
+ .lede {
167
+ max-width: 40rem;
168
+ margin-top: 1.3rem;
169
+ color: var(--bagel-muted);
170
+ font-family: ui-sans-serif, system-ui, sans-serif;
171
+ font-size: 1.25rem;
172
+ line-height: 1.6;
173
+ }
174
+
175
+ .hero-card {
176
+ background: var(--bagel-cream);
177
+ border: 2px solid rgba(43, 33, 25, 0.16);
178
+ border-radius: var(--bagel-radius);
179
+ padding: 1.35rem;
180
+ transform: rotate(1deg);
181
+ }
182
+
183
+ .hero-bagel {
184
+ width: 100%;
185
+ aspect-ratio: 1;
186
+ border-radius: 50%;
187
+ background:
188
+ radial-gradient(circle at center, var(--bagel-cream) 0 25%, transparent 26%),
189
+ radial-gradient(circle at 35% 28%, #f9db8d 0 4%, transparent 5%),
190
+ radial-gradient(circle at 59% 24%, #f9db8d 0 3.5%, transparent 4.5%),
191
+ radial-gradient(circle at 69% 54%, #f9db8d 0 4%, transparent 5%),
192
+ radial-gradient(circle at 43% 72%, #f9db8d 0 3%, transparent 4%),
193
+ linear-gradient(150deg, #e5a24d, var(--bagel-crust) 60%, var(--bagel-crust-dark));
194
+ box-shadow: inset -0.8rem -1rem 0 rgba(69, 38, 19, 0.16);
195
+ }
196
+
197
+ .hero-note {
198
+ margin-top: 1rem;
199
+ color: var(--bagel-muted);
200
+ font-family: ui-sans-serif, system-ui, sans-serif;
201
+ font-size: 0.92rem;
202
+ text-align: center;
203
+ }
204
+
205
+ .section {
206
+ padding: 3rem 0;
207
+ }
208
+
209
+ .section h2 {
210
+ margin-bottom: 1.2rem;
211
+ font-size: 2.5rem;
212
+ line-height: 1;
213
+ }
214
+
215
+ .post-list {
216
+ display: grid;
217
+ gap: 1rem;
218
+ list-style: none;
219
+ }
220
+
221
+ .post-list a {
222
+ display: block;
223
+ padding: 1.1rem 1.2rem;
224
+ border: 2px solid rgba(43, 33, 25, 0.12);
225
+ border-radius: var(--bagel-radius);
226
+ background: #fffdf8;
227
+ color: var(--bagel-ink);
228
+ text-decoration: none;
229
+ }
230
+
231
+ .post-list a:hover {
232
+ border-color: var(--bagel-accent);
233
+ }
234
+
235
+ .host-details {
236
+ display: grid;
237
+ gap: 0.8rem;
238
+ margin-top: 1.4rem;
239
+ color: var(--bagel-muted);
240
+ font-family: ui-sans-serif, system-ui, sans-serif;
241
+ font-size: 1rem;
242
+ }
243
+
244
+ .menu-list {
245
+ display: grid;
246
+ gap: 0.85rem;
247
+ list-style: none;
248
+ }
249
+
250
+ .menu-item {
251
+ display: grid;
252
+ grid-template-columns: minmax(0, 1fr) auto;
253
+ gap: 1rem;
254
+ align-items: baseline;
255
+ padding: 1rem 1.1rem;
256
+ border: 2px solid rgba(43, 33, 25, 0.12);
257
+ border-radius: var(--bagel-radius);
258
+ background: #fffdf8;
259
+ font-family: ui-sans-serif, system-ui, sans-serif;
260
+ }
261
+
262
+ .menu-item h3 {
263
+ font-size: 1rem;
264
+ line-height: 1.3;
265
+ }
266
+
267
+ .menu-price {
268
+ color: var(--bagel-accent);
269
+ font-weight: 800;
270
+ white-space: nowrap;
271
+ }
272
+
273
+ .contact-panel {
274
+ max-width: 42rem;
275
+ }
276
+
277
+ .plum-form {
278
+ display: grid;
279
+ gap: 1rem;
280
+ font-family: ui-sans-serif, system-ui, sans-serif;
281
+ }
282
+
283
+ .plum-form-field {
284
+ display: grid;
285
+ gap: 0.35rem;
286
+ }
287
+
288
+ .plum-form label {
289
+ color: var(--bagel-ink);
290
+ font-size: 0.9rem;
291
+ font-weight: 800;
292
+ }
293
+
294
+ .plum-form input[type="text"],
295
+ .plum-form input[type="email"],
296
+ .plum-form textarea,
297
+ .plum-form select {
298
+ width: 100%;
299
+ border: 2px solid rgba(43, 33, 25, 0.16);
300
+ border-radius: var(--bagel-radius);
301
+ background: #fffdf8;
302
+ color: var(--bagel-ink);
303
+ padding: 0.7rem 0.8rem;
304
+ font: inherit;
305
+ }
306
+
307
+ .plum-form textarea {
308
+ min-height: 8rem;
309
+ }
310
+
311
+ .plum-form input[type="checkbox"] {
312
+ width: 1rem;
313
+ height: 1rem;
314
+ }
315
+
316
+ .plum-form-submit {
317
+ justify-self: start;
318
+ border: 0;
319
+ border-radius: var(--bagel-radius);
320
+ background: var(--bagel-accent);
321
+ color: #fff;
322
+ padding: 0.75rem 1rem;
323
+ font-weight: 800;
324
+ cursor: pointer;
325
+ }
326
+
327
+ article {
328
+ width: min(760px, calc(100% - 2rem));
329
+ margin: 0 auto;
330
+ padding: 5rem 0;
331
+ }
332
+
333
+ article h1 {
334
+ max-width: 14ch;
335
+ font-size: 5.8rem;
336
+ }
337
+
338
+ .meta {
339
+ margin-top: 1rem;
340
+ color: var(--bagel-muted);
341
+ font-family: ui-sans-serif, system-ui, sans-serif;
342
+ font-size: 0.95rem;
343
+ }
344
+
345
+ .content {
346
+ margin-top: 2rem;
347
+ font-family: ui-sans-serif, system-ui, sans-serif;
348
+ font-size: 1.08rem;
349
+ line-height: 1.8;
350
+ }
351
+
352
+ .entry-hero-image {
353
+ width: 100%;
354
+ margin-top: 2rem;
355
+ border: 2px solid rgba(43, 33, 25, 0.16);
356
+ border-radius: var(--bagel-radius);
357
+ }
358
+
359
+ .content p,
360
+ .content ul,
361
+ .content ol {
362
+ margin-bottom: 1.1rem;
363
+ }
364
+
365
+ .content ul,
366
+ .content ol {
367
+ padding-left: 1.35rem;
368
+ }
369
+
370
+ .content h2,
371
+ .content h3 {
372
+ margin: 2rem 0 0.8rem;
373
+ font-family: ui-serif, Georgia, Cambria, "Times New Roman", serif;
374
+ line-height: 1.1;
375
+ }
376
+
377
+ .content a {
378
+ color: var(--bagel-accent);
379
+ font-weight: 700;
380
+ }
381
+
382
+ .excerpt {
383
+ margin-top: 2rem;
384
+ padding: 1rem 1.2rem;
385
+ border-left: 0.35rem solid var(--bagel-accent);
386
+ background: var(--bagel-cream);
387
+ color: var(--bagel-muted);
388
+ font-family: ui-sans-serif, system-ui, sans-serif;
389
+ }
390
+
391
+ .site-footer {
392
+ margin-top: auto;
393
+ border-top: 2px solid rgba(43, 33, 25, 0.12);
394
+ background: #2b2119;
395
+ color: #fff7e8;
396
+ }
397
+
398
+ .footer-inner {
399
+ max-width: 1080px;
400
+ margin: 0 auto;
401
+ padding: 1.5rem 1.25rem;
402
+ display: flex;
403
+ justify-content: space-between;
404
+ gap: 1rem;
405
+ font-family: ui-sans-serif, system-ui, sans-serif;
406
+ font-size: 0.9rem;
407
+ }
408
+
409
+ .footer-inner a {
410
+ color: #f5d38f;
411
+ text-decoration: none;
412
+ }
413
+
414
+ {% if site.custom_css %}
415
+ {{ site.custom_css }}
416
+ {% endif %}
417
+
418
+ @media (max-width: 760px) {
419
+ .brand-name {
420
+ font-size: 1.5rem;
421
+ }
422
+
423
+ .header-inner,
424
+ .footer-inner {
425
+ align-items: flex-start;
426
+ flex-direction: column;
427
+ }
428
+
429
+ .header-actions,
430
+ .site-nav {
431
+ justify-content: flex-start;
432
+ }
433
+
434
+ h1,
435
+ article h1 {
436
+ font-size: 3.2rem;
437
+ }
438
+
439
+ .lede {
440
+ font-size: 1.05rem;
441
+ }
442
+
443
+ .section h2 {
444
+ font-size: 1.9rem;
445
+ }
446
+
447
+ .hero {
448
+ grid-template-columns: 1fr;
449
+ gap: 2rem;
450
+ padding: 3rem 0;
451
+ }
452
+
453
+ .hero-card {
454
+ width: min(18rem, 100%);
455
+ transform: none;
456
+ }
457
+
458
+ article {
459
+ padding: 3rem 0;
460
+ }
461
+ }
462
+ </style>
463
+ </head>
464
+ <body>
465
+ <div class="page">
466
+ <header class="site-header">
467
+ <div class="header-inner">
468
+ <a class="brand" href="{{ site.url }}">
469
+ <span class="bagel-mark" aria-hidden="true"></span>
470
+ <span>
471
+ <span class="brand-name">{{ site.name }}</span>
472
+ {% if site.tagline %}<span class="brand-tagline">{{ site.tagline }}</span>{% endif %}
473
+ </span>
474
+ </a>
475
+ <div class="header-actions">
476
+ {% if nav.main.items.size > 0 %}
477
+ <nav class="site-nav" aria-label="Main navigation">
478
+ {% for item in nav.main.items %}
479
+ <a href="{{ item.url }}">{{ item.label }}</a>
480
+ {% endfor %}
481
+ </nav>
482
+ {% endif %}
483
+
484
+ {% if site.support_email %}
485
+ <a class="header-link" href="mailto:{{ site.support_email }}">Order ahead</a>
486
+ {% endif %}
487
+ </div>
488
+ </div>
489
+ </header>
490
+
491
+ <main>
492
+ {{ content }}
493
+ </main>
494
+
495
+ <footer class="site-footer">
496
+ <div class="footer-inner">
497
+ <span>{{ site.name }}</span>
498
+ {% unless site.theme_settings.show_powered_by == false %}
499
+ <span>Powered by Plum CMS</span>
500
+ {% else %}
501
+ <span><a href="{{ site.url }}">Back to top</a></span>
502
+ {% endunless %}
503
+ </div>
504
+ </footer>
505
+ </div>
506
+ </body>
507
+ </html>
@@ -0,0 +1,15 @@
1
+ <article>
2
+ <span class="kicker">From {{ site.name }}</span>
3
+ <h1>{{ entry.title }}</h1>
4
+ {% if entry.published_at %}
5
+ <p class="meta">Posted {{ entry.published_at | date: "%B %d, %Y" }}</p>
6
+ {% endif %}
7
+
8
+ {% if entry.data.hero_image.url %}
9
+ <img class="entry-hero-image" src="{{ entry.data.hero_image.url }}" alt="{{ entry.data.hero_image.alt_text | default: entry.title }}">
10
+ {% endif %}
11
+
12
+ <div class="content">
13
+ {{ entry.data.body | markdown }}
14
+ </div>
15
+ </article>
@@ -0,0 +1,12 @@
1
+ <article>
2
+ <span class="kicker">Page</span>
3
+ <h1>{{ entry.title }}</h1>
4
+
5
+ {% if entry.data.hero_image.url %}
6
+ <img class="entry-hero-image" src="{{ entry.data.hero_image.url }}" alt="{{ entry.data.hero_image.alt_text | default: entry.title }}">
7
+ {% endif %}
8
+
9
+ <div class="content">
10
+ {{ entry.data.body | markdown }}
11
+ </div>
12
+ </article>
@@ -0,0 +1,19 @@
1
+ <article>
2
+ <span class="kicker">Shop Note</span>
3
+ <h1>{{ entry.title }}</h1>
4
+ {% if entry.published_at %}
5
+ <p class="meta">Posted {{ entry.published_at | date: "%B %d, %Y" }}</p>
6
+ {% endif %}
7
+
8
+ {% if entry.data.hero_image.url %}
9
+ <img class="entry-hero-image" src="{{ entry.data.hero_image.url }}" alt="{{ entry.data.hero_image.alt_text | default: entry.title }}">
10
+ {% endif %}
11
+
12
+ <div class="content">
13
+ {{ entry.data.body | markdown }}
14
+ </div>
15
+
16
+ {% if entry.data.excerpt %}
17
+ <aside class="excerpt">{{ entry.data.excerpt }}</aside>
18
+ {% endif %}
19
+ </article>
@@ -0,0 +1,55 @@
1
+ <section class="wrap hero">
2
+ <div>
3
+ <span class="kicker">Fresh from the oven</span>
4
+ <h1>{{ restaurant.name | default: site.name }}</h1>
5
+ {% if site.tagline %}
6
+ <p class="lede">{{ site.tagline }}</p>
7
+ {% else %}
8
+ <p class="lede">Hand-rolled bagels, steady coffee, and a counter that knows your order.</p>
9
+ {% endif %}
10
+ {% if hours.today %}
11
+ <div class="host-details">
12
+ <p>Open today: {{ hours.today }}</p>
13
+ </div>
14
+ {% endif %}
15
+ </div>
16
+
17
+ <aside class="hero-card" aria-label="Bagel shop feature">
18
+ <div class="hero-bagel" aria-hidden="true"></div>
19
+ <p class="hero-note">{{ site.theme_settings.hero_note | default: "Boiled, baked, and ready early." }}</p>
20
+ </aside>
21
+ </section>
22
+
23
+ {% if menu.items.size > 0 %}
24
+ <section class="wrap section">
25
+ <h2>Menu Favorites</h2>
26
+ <ul class="menu-list">
27
+ {% for item in menu.items limit: 6 %}
28
+ <li class="menu-item">
29
+ <h3>{{ item.name }}</h3>
30
+ {% if item.price %}<span class="menu-price">{{ item.price }}</span>{% endif %}
31
+ </li>
32
+ {% endfor %}
33
+ </ul>
34
+ </section>
35
+ {% endif %}
36
+
37
+ {% if entries.posts.size > 0 %}
38
+ <section class="wrap section">
39
+ <h2>Shop Notes</h2>
40
+ <ul class="post-list">
41
+ {% for post in entries.posts %}
42
+ <li><a href="{{ post.url }}">{{ post.title }}</a></li>
43
+ {% endfor %}
44
+ </ul>
45
+ </section>
46
+ {% endif %}
47
+
48
+ {% if forms.contact %}
49
+ <section class="wrap section">
50
+ <h2>Contact the Counter</h2>
51
+ <div class="contact-panel">
52
+ {% form "contact" %}
53
+ </div>
54
+ </section>
55
+ {% endif %}
@@ -0,0 +1,30 @@
1
+ name: Bagel Shop
2
+ handle: bagel-shop
3
+ version: 0.1.0
4
+ author: Plum
5
+ category: Restaurant
6
+ screenshot: screenshot.svg
7
+ description: Warm retail theme for bagel shops, cafes, bakeries, and small neighborhood food brands.
8
+ settings:
9
+ fields:
10
+ - handle: accent_color
11
+ type: color
12
+ label: Accent Color
13
+ default: "#1f6f63"
14
+ - handle: hero_note
15
+ type: text
16
+ label: Hero Note
17
+ default: Boiled, baked, and ready early.
18
+ - handle: show_powered_by
19
+ type: boolean
20
+ label: Show Powered By
21
+ default: true
22
+ - handle: corner_style
23
+ type: select
24
+ label: Corner Style
25
+ options:
26
+ - label: Soft
27
+ value: soft
28
+ - label: Square
29
+ value: square
30
+ default: soft
@@ -0,0 +1,24 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 750" role="img" aria-labelledby="title desc">
2
+ <title id="title">Default theme screenshot</title>
3
+ <desc id="desc">A clean editorial website layout with a simple header and content column.</desc>
4
+ <rect width="1200" height="750" fill="#f8fafc"/>
5
+ <rect x="116" y="82" width="968" height="586" rx="20" fill="#ffffff" stroke="#e5e7eb" stroke-width="3"/>
6
+ <rect x="156" y="122" width="888" height="74" fill="#ffffff"/>
7
+ <circle cx="178" cy="159" r="18" fill="#7c3aed"/>
8
+ <rect x="212" y="145" width="142" height="14" rx="7" fill="#111827"/>
9
+ <rect x="212" y="167" width="88" height="9" rx="4.5" fill="#9ca3af"/>
10
+ <rect x="772" y="148" width="72" height="12" rx="6" fill="#d1d5db"/>
11
+ <rect x="868" y="148" width="72" height="12" rx="6" fill="#d1d5db"/>
12
+ <rect x="156" y="228" width="560" height="58" rx="8" fill="#111827"/>
13
+ <rect x="156" y="306" width="440" height="22" rx="11" fill="#6b7280"/>
14
+ <rect x="156" y="346" width="504" height="16" rx="8" fill="#d1d5db"/>
15
+ <rect x="156" y="374" width="448" height="16" rx="8" fill="#d1d5db"/>
16
+ <rect x="156" y="402" width="386" height="16" rx="8" fill="#d1d5db"/>
17
+ <rect x="156" y="468" width="256" height="20" rx="10" fill="#111827"/>
18
+ <rect x="156" y="510" width="318" height="24" rx="12" fill="#ede9fe"/>
19
+ <rect x="156" y="552" width="392" height="24" rx="12" fill="#ede9fe"/>
20
+ <rect x="754" y="244" width="232" height="232" rx="20" fill="#f3f4f6"/>
21
+ <path d="M820 386c55-77 97-77 143 0" fill="none" stroke="#7c3aed" stroke-width="14" stroke-linecap="round"/>
22
+ <circle cx="846" cy="324" r="24" fill="#111827"/>
23
+ <circle cx="926" cy="324" r="24" fill="#111827"/>
24
+ </svg>