not_pressed-core 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 (157) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +41 -0
  3. data/README.md +285 -0
  4. data/app/assets/javascripts/not_pressed/lightbox.js +110 -0
  5. data/app/assets/stylesheets/not_pressed/admin.css +1161 -0
  6. data/app/assets/stylesheets/not_pressed/content.css +193 -0
  7. data/app/assets/stylesheets/not_pressed/gallery.css +117 -0
  8. data/app/assets/stylesheets/not_pressed/themes/starter.css +118 -0
  9. data/app/controllers/not_pressed/admin/base_controller.rb +21 -0
  10. data/app/controllers/not_pressed/admin/categories_controller.rb +53 -0
  11. data/app/controllers/not_pressed/admin/content_blocks_controller.rb +73 -0
  12. data/app/controllers/not_pressed/admin/dashboard_controller.rb +19 -0
  13. data/app/controllers/not_pressed/admin/forms_controller.rb +86 -0
  14. data/app/controllers/not_pressed/admin/media_attachments_controller.rb +94 -0
  15. data/app/controllers/not_pressed/admin/pages_controller.rb +122 -0
  16. data/app/controllers/not_pressed/admin/plugins_controller.rb +121 -0
  17. data/app/controllers/not_pressed/admin/settings_controller.rb +19 -0
  18. data/app/controllers/not_pressed/admin/tags_controller.rb +37 -0
  19. data/app/controllers/not_pressed/admin/themes_controller.rb +104 -0
  20. data/app/controllers/not_pressed/application_controller.rb +6 -0
  21. data/app/controllers/not_pressed/blog_controller.rb +83 -0
  22. data/app/controllers/not_pressed/form_submissions_controller.rb +70 -0
  23. data/app/controllers/not_pressed/pages_controller.rb +36 -0
  24. data/app/controllers/not_pressed/robots_controller.rb +34 -0
  25. data/app/controllers/not_pressed/sitemaps_controller.rb +12 -0
  26. data/app/helpers/not_pressed/admin_helper.rb +41 -0
  27. data/app/helpers/not_pressed/application_helper.rb +6 -0
  28. data/app/helpers/not_pressed/code_injection_helper.rb +29 -0
  29. data/app/helpers/not_pressed/content_helper.rb +13 -0
  30. data/app/helpers/not_pressed/form_helper.rb +80 -0
  31. data/app/helpers/not_pressed/media_helper.rb +28 -0
  32. data/app/helpers/not_pressed/seo_helper.rb +69 -0
  33. data/app/helpers/not_pressed/theme_helper.rb +42 -0
  34. data/app/mailers/not_pressed/application_mailer.rb +10 -0
  35. data/app/mailers/not_pressed/form_mailer.rb +15 -0
  36. data/app/models/concerns/not_pressed/sluggable.rb +43 -0
  37. data/app/models/not_pressed/category.rb +16 -0
  38. data/app/models/not_pressed/content_block.rb +46 -0
  39. data/app/models/not_pressed/form.rb +55 -0
  40. data/app/models/not_pressed/form_field.rb +23 -0
  41. data/app/models/not_pressed/form_submission.rb +19 -0
  42. data/app/models/not_pressed/media_attachment.rb +68 -0
  43. data/app/models/not_pressed/page.rb +182 -0
  44. data/app/models/not_pressed/page_version.rb +15 -0
  45. data/app/models/not_pressed/setting.rb +20 -0
  46. data/app/models/not_pressed/tag.rb +15 -0
  47. data/app/models/not_pressed/tagging.rb +12 -0
  48. data/app/plugins/not_pressed/analytics_plugin.rb +106 -0
  49. data/app/plugins/not_pressed/callout_block_plugin.rb +43 -0
  50. data/app/themes/not_pressed/starter_theme.rb +26 -0
  51. data/app/views/layouts/not_pressed/admin.html.erb +745 -0
  52. data/app/views/layouts/not_pressed/application.html.erb +12 -0
  53. data/app/views/layouts/not_pressed/page.html.erb +22 -0
  54. data/app/views/not_pressed/admin/categories/index.html.erb +58 -0
  55. data/app/views/not_pressed/admin/content_blocks/_block.html.erb +18 -0
  56. data/app/views/not_pressed/admin/content_blocks/_block_picker.html.erb +32 -0
  57. data/app/views/not_pressed/admin/content_blocks/create.turbo_stream.erb +3 -0
  58. data/app/views/not_pressed/admin/content_blocks/destroy.turbo_stream.erb +1 -0
  59. data/app/views/not_pressed/admin/content_blocks/editors/_callout.html.erb +38 -0
  60. data/app/views/not_pressed/admin/content_blocks/editors/_code.html.erb +26 -0
  61. data/app/views/not_pressed/admin/content_blocks/editors/_divider.html.erb +4 -0
  62. data/app/views/not_pressed/admin/content_blocks/editors/_form.html.erb +16 -0
  63. data/app/views/not_pressed/admin/content_blocks/editors/_gallery.html.erb +75 -0
  64. data/app/views/not_pressed/admin/content_blocks/editors/_heading.html.erb +26 -0
  65. data/app/views/not_pressed/admin/content_blocks/editors/_html.html.erb +13 -0
  66. data/app/views/not_pressed/admin/content_blocks/editors/_image.html.erb +56 -0
  67. data/app/views/not_pressed/admin/content_blocks/editors/_quote.html.erb +24 -0
  68. data/app/views/not_pressed/admin/content_blocks/editors/_text.html.erb +28 -0
  69. data/app/views/not_pressed/admin/content_blocks/editors/_video.html.erb +25 -0
  70. data/app/views/not_pressed/admin/dashboard/index.html.erb +60 -0
  71. data/app/views/not_pressed/admin/forms/_field_row.html.erb +33 -0
  72. data/app/views/not_pressed/admin/forms/_form.html.erb +75 -0
  73. data/app/views/not_pressed/admin/forms/edit.html.erb +1 -0
  74. data/app/views/not_pressed/admin/forms/index.html.erb +32 -0
  75. data/app/views/not_pressed/admin/forms/new.html.erb +1 -0
  76. data/app/views/not_pressed/admin/forms/submissions.html.erb +34 -0
  77. data/app/views/not_pressed/admin/media_attachments/_media_card.html.erb +21 -0
  78. data/app/views/not_pressed/admin/media_attachments/_picker.html.erb +19 -0
  79. data/app/views/not_pressed/admin/media_attachments/edit.html.erb +57 -0
  80. data/app/views/not_pressed/admin/media_attachments/index.html.erb +48 -0
  81. data/app/views/not_pressed/admin/pages/_form.html.erb +177 -0
  82. data/app/views/not_pressed/admin/pages/_page_tree_node.html.erb +32 -0
  83. data/app/views/not_pressed/admin/pages/edit.html.erb +69 -0
  84. data/app/views/not_pressed/admin/pages/index.html.erb +21 -0
  85. data/app/views/not_pressed/admin/pages/new.html.erb +1 -0
  86. data/app/views/not_pressed/admin/pages/preview.html.erb +17 -0
  87. data/app/views/not_pressed/admin/plugins/_settings_form.html.erb +59 -0
  88. data/app/views/not_pressed/admin/plugins/index.html.erb +48 -0
  89. data/app/views/not_pressed/admin/plugins/show.html.erb +54 -0
  90. data/app/views/not_pressed/admin/settings/code_injection.html.erb +21 -0
  91. data/app/views/not_pressed/admin/shared/_breadcrumbs.html.erb +14 -0
  92. data/app/views/not_pressed/admin/shared/_flash.html.erb +7 -0
  93. data/app/views/not_pressed/admin/shared/_modal.html.erb +9 -0
  94. data/app/views/not_pressed/admin/shared/_sidebar.html.erb +18 -0
  95. data/app/views/not_pressed/admin/tags/index.html.erb +52 -0
  96. data/app/views/not_pressed/admin/themes/index.html.erb +60 -0
  97. data/app/views/not_pressed/admin/themes/show.html.erb +66 -0
  98. data/app/views/not_pressed/blog/_post_card.html.erb +24 -0
  99. data/app/views/not_pressed/blog/feed.rss.builder +22 -0
  100. data/app/views/not_pressed/blog/index.html.erb +56 -0
  101. data/app/views/not_pressed/blog/show.html.erb +41 -0
  102. data/app/views/not_pressed/form_mailer/submission_notification.text.erb +8 -0
  103. data/app/views/not_pressed/pages/show.html.erb +4 -0
  104. data/app/views/themes/starter/layouts/not_pressed/default.html.erb +36 -0
  105. data/app/views/themes/starter/layouts/not_pressed/full_width.html.erb +36 -0
  106. data/app/views/themes/starter/layouts/not_pressed/sidebar.html.erb +41 -0
  107. data/config/routes.rb +81 -0
  108. data/db/migrate/20260310000001_create_not_pressed_pages.rb +20 -0
  109. data/db/migrate/20260310000002_create_not_pressed_content_blocks.rb +17 -0
  110. data/db/migrate/20260310000003_create_not_pressed_media_attachments.rb +14 -0
  111. data/db/migrate/20260310000004_add_content_type_to_not_pressed_pages.rb +8 -0
  112. data/db/migrate/20260310000005_add_publishing_fields_to_not_pressed_pages.rb +8 -0
  113. data/db/migrate/20260310000006_create_not_pressed_page_versions.rb +16 -0
  114. data/db/migrate/20260310000007_add_settings_fields_to_not_pressed_pages.rb +11 -0
  115. data/db/migrate/20260311000001_create_not_pressed_forms.rb +42 -0
  116. data/db/migrate/20260311000002_add_seo_fields_to_not_pressed_pages.rb +10 -0
  117. data/db/migrate/20260311000003_add_code_injection_to_not_pressed_pages.rb +8 -0
  118. data/db/migrate/20260311000004_create_not_pressed_settings.rb +14 -0
  119. data/db/migrate/20260312000001_create_not_pressed_categories.rb +16 -0
  120. data/db/migrate/20260312000002_create_not_pressed_tags.rb +15 -0
  121. data/db/migrate/20260312000003_create_not_pressed_taggings.rb +14 -0
  122. data/db/migrate/20260312000004_add_category_id_to_not_pressed_pages.rb +7 -0
  123. data/lib/generators/not_pressed/install/install_generator.rb +52 -0
  124. data/lib/generators/not_pressed/install/templates/initializer.rb.tt +89 -0
  125. data/lib/generators/not_pressed/install/templates/seeds.rb.tt +131 -0
  126. data/lib/generators/not_pressed/plugin/plugin_generator.rb +37 -0
  127. data/lib/generators/not_pressed/plugin/templates/plugin.rb.tt +23 -0
  128. data/lib/not_pressed/admin/authentication.rb +48 -0
  129. data/lib/not_pressed/admin/menu_registry.rb +100 -0
  130. data/lib/not_pressed/configuration.rb +77 -0
  131. data/lib/not_pressed/content_type.rb +23 -0
  132. data/lib/not_pressed/content_type_builder.rb +51 -0
  133. data/lib/not_pressed/content_type_registry.rb +45 -0
  134. data/lib/not_pressed/engine.rb +132 -0
  135. data/lib/not_pressed/hooks.rb +166 -0
  136. data/lib/not_pressed/navigation/builder.rb +148 -0
  137. data/lib/not_pressed/navigation/menu.rb +54 -0
  138. data/lib/not_pressed/navigation/menu_item.rb +33 -0
  139. data/lib/not_pressed/navigation/node.rb +45 -0
  140. data/lib/not_pressed/navigation/partial_parser.rb +96 -0
  141. data/lib/not_pressed/navigation/route_inspector.rb +98 -0
  142. data/lib/not_pressed/navigation.rb +6 -0
  143. data/lib/not_pressed/plugin.rb +354 -0
  144. data/lib/not_pressed/plugin_importer.rb +133 -0
  145. data/lib/not_pressed/plugin_manager.rb +196 -0
  146. data/lib/not_pressed/plugin_packager.rb +129 -0
  147. data/lib/not_pressed/rendering/block_renderer.rb +222 -0
  148. data/lib/not_pressed/rendering/renderer_registry.rb +154 -0
  149. data/lib/not_pressed/rendering.rb +8 -0
  150. data/lib/not_pressed/seo/sitemap_builder.rb +61 -0
  151. data/lib/not_pressed/theme.rb +191 -0
  152. data/lib/not_pressed/theme_importer.rb +133 -0
  153. data/lib/not_pressed/theme_packager.rb +180 -0
  154. data/lib/not_pressed/theme_registry.rb +123 -0
  155. data/lib/not_pressed/version.rb +5 -0
  156. data/lib/not_pressed.rb +65 -0
  157. metadata +258 -0
@@ -0,0 +1,1161 @@
1
+ :root {
2
+ --np-primary: #4f46e5;
3
+ --np-sidebar-bg: #1e1e2e;
4
+ --np-sidebar-text: #cdd6f4;
5
+ --np-text: #1e293b;
6
+ --np-bg: #f8fafc;
7
+ --np-border: #e2e8f0;
8
+ }
9
+
10
+ * {
11
+ box-sizing: border-box;
12
+ }
13
+
14
+ body {
15
+ display: flex;
16
+ min-height: 100vh;
17
+ margin: 0;
18
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
19
+ color: var(--np-text);
20
+ background-color: var(--np-bg);
21
+ }
22
+
23
+ /* Sidebar */
24
+ #admin-sidebar {
25
+ width: 250px;
26
+ min-width: 250px;
27
+ background-color: var(--np-sidebar-bg);
28
+ color: var(--np-sidebar-text);
29
+ min-height: 100vh;
30
+ display: flex;
31
+ flex-direction: column;
32
+ }
33
+
34
+ .sidebar-header {
35
+ padding: 1.25rem 1rem;
36
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
37
+ }
38
+
39
+ .sidebar-header h1 {
40
+ margin: 0;
41
+ font-size: 1.125rem;
42
+ font-weight: 600;
43
+ color: #fff;
44
+ }
45
+
46
+ #admin-sidebar nav ul {
47
+ list-style: none;
48
+ margin: 0;
49
+ padding: 0.5rem 0;
50
+ }
51
+
52
+ #admin-sidebar nav ul li a {
53
+ display: block;
54
+ padding: 0.625rem 1rem;
55
+ color: var(--np-sidebar-text);
56
+ text-decoration: none;
57
+ transition: background-color 0.15s ease;
58
+ }
59
+
60
+ #admin-sidebar nav ul li a:hover {
61
+ background-color: rgba(255, 255, 255, 0.1);
62
+ color: #fff;
63
+ }
64
+
65
+ /* Wrapper */
66
+ #admin-wrapper {
67
+ flex-grow: 1;
68
+ display: flex;
69
+ flex-direction: column;
70
+ min-width: 0;
71
+ }
72
+
73
+ /* Header */
74
+ #admin-header {
75
+ position: sticky;
76
+ top: 0;
77
+ background-color: #fff;
78
+ border-bottom: 1px solid var(--np-border);
79
+ padding: 0.75rem 1.5rem;
80
+ display: flex;
81
+ align-items: center;
82
+ justify-content: space-between;
83
+ z-index: 10;
84
+ }
85
+
86
+ #admin-header h2 {
87
+ margin: 0;
88
+ font-size: 1.25rem;
89
+ font-weight: 600;
90
+ }
91
+
92
+ .user-info {
93
+ font-size: 0.875rem;
94
+ color: #64748b;
95
+ }
96
+
97
+ /* Content */
98
+ #admin-content {
99
+ flex-grow: 1;
100
+ padding: 1.5rem;
101
+ }
102
+
103
+ /* Flash messages */
104
+ .flash {
105
+ padding: 0.75rem 1rem;
106
+ margin-bottom: 1rem;
107
+ border-radius: 0.375rem;
108
+ font-size: 0.875rem;
109
+ }
110
+
111
+ .flash-notice {
112
+ background-color: #dcfce7;
113
+ color: #166534;
114
+ border: 1px solid #bbf7d0;
115
+ }
116
+
117
+ .flash-alert {
118
+ background-color: #fee2e2;
119
+ color: #991b1b;
120
+ border: 1px solid #fecaca;
121
+ }
122
+
123
+ /* Stats grid */
124
+ .np-stats-grid {
125
+ display: grid;
126
+ grid-template-columns: repeat(4, 1fr);
127
+ gap: 1rem;
128
+ margin-bottom: 2rem;
129
+ }
130
+
131
+ .np-stat-card {
132
+ border: 1px solid var(--np-border);
133
+ border-radius: 0.5rem;
134
+ padding: 1.25rem;
135
+ text-align: center;
136
+ background-color: #fff;
137
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
138
+ }
139
+
140
+ .np-stat-number {
141
+ font-size: 2rem;
142
+ font-weight: 700;
143
+ color: var(--np-primary);
144
+ line-height: 1.2;
145
+ }
146
+
147
+ .np-stat-label {
148
+ font-size: 0.875rem;
149
+ color: #64748b;
150
+ margin-top: 0.25rem;
151
+ }
152
+
153
+ .np-stat-detail {
154
+ font-size: 0.75rem;
155
+ color: #94a3b8;
156
+ margin-top: 0.25rem;
157
+ }
158
+
159
+ /* Badges */
160
+ .np-badge {
161
+ display: inline-block;
162
+ padding: 0.125rem 0.5rem;
163
+ border-radius: 9999px;
164
+ font-size: 0.75rem;
165
+ font-weight: 500;
166
+ line-height: 1.5;
167
+ }
168
+
169
+ .np-badge--draft {
170
+ background-color: #e2e8f0;
171
+ color: #475569;
172
+ }
173
+
174
+ .np-badge--published {
175
+ background-color: #16a34a;
176
+ color: #fff;
177
+ }
178
+
179
+ .np-badge--active {
180
+ background-color: #16a34a;
181
+ color: #fff;
182
+ }
183
+
184
+ .np-badge--archived {
185
+ background-color: #dc2626;
186
+ color: #fff;
187
+ }
188
+
189
+ /* Table */
190
+ .np-table {
191
+ width: 100%;
192
+ border-collapse: collapse;
193
+ margin-bottom: 2rem;
194
+ background-color: #fff;
195
+ border-radius: 0.5rem;
196
+ overflow: hidden;
197
+ border: 1px solid var(--np-border);
198
+ }
199
+
200
+ .np-table th,
201
+ .np-table td {
202
+ padding: 0.625rem 1rem;
203
+ text-align: left;
204
+ border-bottom: 1px solid var(--np-border);
205
+ }
206
+
207
+ .np-table th {
208
+ background-color: #f8fafc;
209
+ font-size: 0.75rem;
210
+ font-weight: 600;
211
+ text-transform: uppercase;
212
+ letter-spacing: 0.05em;
213
+ color: #64748b;
214
+ }
215
+
216
+ .np-table tbody tr:nth-child(even) {
217
+ background-color: #f8fafc;
218
+ }
219
+
220
+ .np-table tbody tr:hover {
221
+ background-color: #f1f5f9;
222
+ }
223
+
224
+ .np-table a {
225
+ color: var(--np-primary);
226
+ text-decoration: none;
227
+ }
228
+
229
+ .np-table a:hover {
230
+ text-decoration: underline;
231
+ }
232
+
233
+ /* Actions */
234
+ .np-actions {
235
+ display: flex;
236
+ gap: 0.75rem;
237
+ flex-wrap: wrap;
238
+ }
239
+
240
+ .np-btn {
241
+ display: inline-block;
242
+ padding: 0.5rem 1rem;
243
+ border-radius: 0.375rem;
244
+ font-size: 0.875rem;
245
+ font-weight: 500;
246
+ text-decoration: none;
247
+ border: 1px solid var(--np-border);
248
+ background-color: #fff;
249
+ color: var(--np-text);
250
+ cursor: pointer;
251
+ transition: background-color 0.15s ease;
252
+ }
253
+
254
+ .np-btn:hover {
255
+ background-color: #f1f5f9;
256
+ }
257
+
258
+ .np-btn--primary {
259
+ background-color: var(--np-primary);
260
+ color: #fff;
261
+ border-color: var(--np-primary);
262
+ }
263
+
264
+ .np-btn--primary:hover {
265
+ background-color: #4338ca;
266
+ }
267
+
268
+ /* Responsive */
269
+ @media (max-width: 1024px) {
270
+ .np-stats-grid {
271
+ grid-template-columns: repeat(2, 1fr);
272
+ }
273
+ }
274
+
275
+ @media (max-width: 768px) {
276
+ #admin-sidebar {
277
+ display: none;
278
+ position: fixed;
279
+ top: 0;
280
+ left: 0;
281
+ z-index: 100;
282
+ height: 100vh;
283
+ }
284
+
285
+ #admin-sidebar.np-sidebar--open {
286
+ display: flex;
287
+ }
288
+
289
+ #admin-content {
290
+ padding: 1rem;
291
+ }
292
+
293
+ .np-stats-grid {
294
+ grid-template-columns: 1fr;
295
+ }
296
+ }
297
+
298
+ /* Flash messages */
299
+ .np-flash {
300
+ display: flex;
301
+ align-items: center;
302
+ justify-content: space-between;
303
+ padding: 0.75rem 1rem;
304
+ margin-bottom: 1rem;
305
+ border-radius: 0.375rem;
306
+ font-size: 0.875rem;
307
+ }
308
+
309
+ .np-flash--notice {
310
+ background-color: #dcfce7;
311
+ color: #166534;
312
+ border: 1px solid #bbf7d0;
313
+ }
314
+
315
+ .np-flash--alert {
316
+ background-color: #fee2e2;
317
+ color: #991b1b;
318
+ border: 1px solid #fecaca;
319
+ }
320
+
321
+ .np-flash-close {
322
+ cursor: pointer;
323
+ border: none;
324
+ background: transparent;
325
+ font-size: 1.25rem;
326
+ line-height: 1;
327
+ padding: 0 0.25rem;
328
+ color: inherit;
329
+ opacity: 0.7;
330
+ }
331
+
332
+ .np-flash-close:hover {
333
+ opacity: 1;
334
+ }
335
+
336
+ /* Breadcrumbs */
337
+ .np-breadcrumbs {
338
+ display: flex;
339
+ align-items: center;
340
+ gap: 0.5rem;
341
+ font-size: 0.875rem;
342
+ margin-bottom: 1rem;
343
+ color: #64748b;
344
+ }
345
+
346
+ .np-breadcrumbs a {
347
+ color: var(--np-primary);
348
+ text-decoration: none;
349
+ }
350
+
351
+ .np-breadcrumbs a:hover {
352
+ text-decoration: underline;
353
+ }
354
+
355
+ .np-breadcrumb-separator {
356
+ color: #94a3b8;
357
+ }
358
+
359
+ /* Modal */
360
+ dialog.np-modal {
361
+ border: none;
362
+ border-radius: 0.5rem;
363
+ padding: 0;
364
+ max-width: 32rem;
365
+ width: 90%;
366
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);
367
+ }
368
+
369
+ dialog.np-modal::backdrop {
370
+ background-color: rgba(0, 0, 0, 0.5);
371
+ }
372
+
373
+ .np-modal-header {
374
+ display: flex;
375
+ align-items: center;
376
+ justify-content: space-between;
377
+ padding: 1rem 1.25rem;
378
+ border-bottom: 1px solid var(--np-border);
379
+ }
380
+
381
+ .np-modal-header h3 {
382
+ margin: 0;
383
+ font-size: 1.125rem;
384
+ font-weight: 600;
385
+ }
386
+
387
+ .np-modal-close {
388
+ cursor: pointer;
389
+ border: none;
390
+ background: transparent;
391
+ font-size: 1.5rem;
392
+ line-height: 1;
393
+ color: #64748b;
394
+ }
395
+
396
+ .np-modal-close:hover {
397
+ color: var(--np-text);
398
+ }
399
+
400
+ .np-modal-body {
401
+ padding: 1.25rem;
402
+ }
403
+
404
+ /* Sidebar active nav */
405
+ .np-nav-active {
406
+ background-color: rgba(255, 255, 255, 0.15);
407
+ color: #fff !important;
408
+ font-weight: 600;
409
+ }
410
+
411
+ /* Header left section */
412
+ .np-header-left {
413
+ display: flex;
414
+ align-items: center;
415
+ gap: 0.75rem;
416
+ }
417
+
418
+ /* Mobile hamburger button */
419
+ .np-hamburger {
420
+ display: none;
421
+ cursor: pointer;
422
+ border: none;
423
+ background: transparent;
424
+ font-size: 1.5rem;
425
+ padding: 0.25rem;
426
+ color: var(--np-text);
427
+ }
428
+
429
+ @media (max-width: 768px) {
430
+ .np-hamburger {
431
+ display: block;
432
+ }
433
+ }
434
+
435
+ /* Page Tree */
436
+ .np-tree {
437
+ background-color: #fff;
438
+ border: 1px solid var(--np-border);
439
+ border-radius: 0.5rem;
440
+ overflow: hidden;
441
+ margin-bottom: 2rem;
442
+ }
443
+
444
+ .np-tree-header {
445
+ display: flex;
446
+ align-items: center;
447
+ padding: 0.625rem 1rem;
448
+ background-color: #f8fafc;
449
+ border-bottom: 1px solid var(--np-border);
450
+ font-size: 0.75rem;
451
+ font-weight: 600;
452
+ text-transform: uppercase;
453
+ letter-spacing: 0.05em;
454
+ color: #64748b;
455
+ }
456
+
457
+ .np-tree-header-title {
458
+ flex: 1;
459
+ min-width: 0;
460
+ padding-left: 2rem;
461
+ }
462
+
463
+ .np-tree-header-actions {
464
+ width: 12rem;
465
+ text-align: right;
466
+ }
467
+
468
+ .np-tree-node {
469
+ display: flex;
470
+ align-items: center;
471
+ padding: 0.5rem 1rem;
472
+ border-bottom: 1px solid var(--np-border);
473
+ transition: background-color 0.15s;
474
+ }
475
+
476
+ .np-tree-node:hover {
477
+ background-color: #f1f5f9;
478
+ }
479
+
480
+ .np-tree-indent {
481
+ display: flex;
482
+ align-items: center;
483
+ flex-shrink: 0;
484
+ }
485
+
486
+ .np-tree-toggle {
487
+ display: inline-flex;
488
+ align-items: center;
489
+ justify-content: center;
490
+ width: 1.5rem;
491
+ height: 1.5rem;
492
+ border: none;
493
+ background: transparent;
494
+ cursor: pointer;
495
+ font-size: 0.75rem;
496
+ color: #64748b;
497
+ padding: 0;
498
+ flex-shrink: 0;
499
+ }
500
+
501
+ .np-tree-toggle:hover {
502
+ color: var(--np-text);
503
+ }
504
+
505
+ .np-tree-toggle--leaf {
506
+ cursor: default;
507
+ color: #cbd5e1;
508
+ }
509
+
510
+ .np-tree-title {
511
+ flex: 1;
512
+ min-width: 0;
513
+ font-weight: 500;
514
+ white-space: nowrap;
515
+ overflow: hidden;
516
+ text-overflow: ellipsis;
517
+ }
518
+
519
+ .np-tree-title a {
520
+ color: var(--np-primary);
521
+ text-decoration: none;
522
+ }
523
+
524
+ .np-tree-title a:hover {
525
+ text-decoration: underline;
526
+ }
527
+
528
+ .np-tree-node[data-tree-level="0"] .np-tree-title {
529
+ font-weight: 600;
530
+ }
531
+
532
+ .np-tree-meta {
533
+ width: 6rem;
534
+ flex-shrink: 0;
535
+ font-size: 0.875rem;
536
+ color: #64748b;
537
+ }
538
+
539
+ .np-tree-actions {
540
+ width: 12rem;
541
+ flex-shrink: 0;
542
+ display: flex;
543
+ gap: 0.375rem;
544
+ justify-content: flex-end;
545
+ }
546
+
547
+ .np-tree-children {
548
+ display: block;
549
+ }
550
+
551
+ .np-tree-children--collapsed {
552
+ display: none;
553
+ }
554
+
555
+ .np-tree-node--dragging {
556
+ opacity: 0.4;
557
+ border: 2px dashed var(--np-primary);
558
+ }
559
+
560
+ .np-tree-node--drop-inside {
561
+ background-color: rgba(79, 70, 229, 0.08);
562
+ outline: 2px solid var(--np-primary);
563
+ outline-offset: -2px;
564
+ }
565
+
566
+ .np-tree-drop-indicator {
567
+ height: 3px;
568
+ background-color: var(--np-primary);
569
+ border-radius: 2px;
570
+ margin: 0;
571
+ }
572
+
573
+ @media (max-width: 768px) {
574
+ .np-tree-meta:nth-child(4),
575
+ .np-tree-meta:nth-child(5) {
576
+ display: none;
577
+ }
578
+
579
+ .np-tree-header .np-tree-meta:nth-child(4),
580
+ .np-tree-header .np-tree-meta:nth-child(5) {
581
+ display: none;
582
+ }
583
+
584
+ .np-tree-indent {
585
+ padding-left: 0 !important;
586
+ }
587
+ }
588
+
589
+ /* Fieldset */
590
+ .np-fieldset {
591
+ border: 1px solid var(--np-border);
592
+ border-radius: 0.5rem;
593
+ padding: 1rem 1.25rem;
594
+ margin-bottom: 1rem;
595
+ }
596
+
597
+ .np-fieldset--no-border {
598
+ border: none;
599
+ padding: 0.5rem 0;
600
+ margin-bottom: 0;
601
+ }
602
+
603
+ .np-legend {
604
+ font-size: 1rem;
605
+ font-weight: 600;
606
+ color: var(--np-text);
607
+ cursor: pointer;
608
+ }
609
+
610
+ .np-fieldset-details {
611
+ margin-bottom: 1rem;
612
+ }
613
+
614
+ .np-fieldset-details summary {
615
+ padding: 0.5rem 0;
616
+ }
617
+
618
+ /* Block Editor */
619
+ .np-block {
620
+ border: 1px solid var(--np-border);
621
+ border-radius: 0.5rem;
622
+ margin-bottom: 0.75rem;
623
+ background-color: #fff;
624
+ }
625
+
626
+ .np-block-header {
627
+ display: flex;
628
+ align-items: center;
629
+ justify-content: space-between;
630
+ padding: 0.5rem 1rem;
631
+ background-color: #f8fafc;
632
+ border-bottom: 1px solid var(--np-border);
633
+ border-radius: 0.5rem 0.5rem 0 0;
634
+ }
635
+
636
+ .np-block-type-label {
637
+ font-size: 0.75rem;
638
+ font-weight: 600;
639
+ text-transform: uppercase;
640
+ letter-spacing: 0.05em;
641
+ color: #64748b;
642
+ }
643
+
644
+ .np-block-body {
645
+ padding: 1rem;
646
+ }
647
+
648
+ .np-block-content-field {
649
+ width: 100%;
650
+ font-family: monospace;
651
+ font-size: 0.8125rem;
652
+ }
653
+
654
+ .np-block-type-picker {
655
+ margin-top: 1rem;
656
+ }
657
+
658
+ .np-block-type-buttons {
659
+ display: flex;
660
+ flex-wrap: wrap;
661
+ gap: 0.5rem;
662
+ }
663
+
664
+ /* Page Settings */
665
+ .np-page-settings summary {
666
+ cursor: pointer;
667
+ }
668
+
669
+ .np-page-settings-body {
670
+ padding: 1rem 0;
671
+ }
672
+
673
+ /* Forms */
674
+ .np-form {
675
+ max-width: 40rem;
676
+ }
677
+
678
+ .np-form-group {
679
+ margin-bottom: 1rem;
680
+ }
681
+
682
+ .np-label {
683
+ display: block;
684
+ font-size: 0.875rem;
685
+ font-weight: 500;
686
+ margin-bottom: 0.25rem;
687
+ color: var(--np-text);
688
+ }
689
+
690
+ .np-input {
691
+ display: block;
692
+ width: 100%;
693
+ padding: 0.5rem 0.75rem;
694
+ font-size: 0.875rem;
695
+ border: 1px solid var(--np-border);
696
+ border-radius: 0.375rem;
697
+ background-color: #fff;
698
+ color: var(--np-text);
699
+ }
700
+
701
+ .np-input:focus {
702
+ outline: none;
703
+ border-color: var(--np-primary);
704
+ box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1);
705
+ }
706
+
707
+ .np-form-actions {
708
+ display: flex;
709
+ gap: 0.75rem;
710
+ margin-top: 1rem;
711
+ }
712
+
713
+ .np-form-errors {
714
+ background-color: #fee2e2;
715
+ border: 1px solid #fecaca;
716
+ color: #991b1b;
717
+ padding: 1rem;
718
+ border-radius: 0.375rem;
719
+ margin-bottom: 1rem;
720
+ font-size: 0.875rem;
721
+ }
722
+
723
+ .np-form-errors h3 {
724
+ margin: 0 0 0.5rem;
725
+ font-size: 0.875rem;
726
+ }
727
+
728
+ .np-form-errors ul {
729
+ margin: 0;
730
+ padding-left: 1.25rem;
731
+ }
732
+
733
+ /* Button variants */
734
+ .np-btn--danger {
735
+ background-color: #dc2626;
736
+ color: #fff;
737
+ border-color: #dc2626;
738
+ }
739
+
740
+ .np-btn--danger:hover {
741
+ background-color: #b91c1c;
742
+ }
743
+
744
+ .np-btn--small {
745
+ padding: 0.25rem 0.5rem;
746
+ font-size: 0.75rem;
747
+ }
748
+
749
+ /* Block Editor Fields */
750
+ .np-editor-field {
751
+ margin-bottom: 0.75rem;
752
+ }
753
+
754
+ .np-editor-field label {
755
+ display: block;
756
+ font-size: 0.875rem;
757
+ font-weight: 500;
758
+ margin-bottom: 0.25rem;
759
+ color: var(--np-text);
760
+ }
761
+
762
+ /* Text Editor */
763
+ .np-editor-text textarea {
764
+ min-height: 150px;
765
+ }
766
+
767
+ /* Heading Editor */
768
+ .np-editor-heading input[type="text"] {
769
+ font-size: 1.25rem;
770
+ font-weight: 600;
771
+ }
772
+
773
+ /* Image Editor */
774
+ .np-editor-image .np-image-preview {
775
+ margin-bottom: 0.75rem;
776
+ }
777
+
778
+ .np-editor-image .np-image-preview img {
779
+ max-width: 100%;
780
+ border: 1px solid var(--np-border);
781
+ border-radius: 0.375rem;
782
+ }
783
+
784
+ /* Code Editor */
785
+ .np-editor-code textarea {
786
+ font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
787
+ background-color: #1e1e2e;
788
+ color: #cdd6f4;
789
+ min-height: 200px;
790
+ }
791
+
792
+ /* Quote Editor */
793
+ .np-editor-quote textarea {
794
+ font-style: italic;
795
+ border-left: 3px solid var(--np-primary);
796
+ }
797
+
798
+ /* Divider Editor */
799
+ .np-editor-divider {
800
+ text-align: center;
801
+ padding: 0.5rem 0;
802
+ }
803
+
804
+ .np-editor-divider .np-divider-preview {
805
+ border: none;
806
+ border-top: 2px solid var(--np-border);
807
+ margin: 0.75rem auto;
808
+ width: 80%;
809
+ }
810
+
811
+ /* HTML Editor */
812
+ .np-editor-html textarea {
813
+ font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
814
+ background-color: #fffde7;
815
+ }
816
+
817
+ .np-html-warning {
818
+ font-size: 0.75rem;
819
+ color: #b45309;
820
+ margin: 0 0 0.5rem;
821
+ }
822
+
823
+ /* Save Indicator */
824
+ .np-save-indicator {
825
+ font-size: 0.75rem;
826
+ color: #16a34a;
827
+ opacity: 0;
828
+ transition: opacity 0.3s;
829
+ }
830
+
831
+ /* Rich Text Toolbar */
832
+ .np-toolbar {
833
+ display: flex;
834
+ flex-wrap: wrap;
835
+ gap: 0.25rem;
836
+ padding: 0.375rem 0.5rem;
837
+ border: 1px solid var(--np-border);
838
+ border-bottom: none;
839
+ border-radius: 0.375rem 0.375rem 0 0;
840
+ background-color: #f8fafc;
841
+ }
842
+
843
+ .np-toolbar-btn {
844
+ display: inline-flex;
845
+ align-items: center;
846
+ justify-content: center;
847
+ min-width: 2rem;
848
+ height: 2rem;
849
+ padding: 0 0.375rem;
850
+ border: 1px solid transparent;
851
+ border-radius: 0.25rem;
852
+ background: transparent;
853
+ font-size: 0.8125rem;
854
+ font-weight: 600;
855
+ color: var(--np-text);
856
+ cursor: pointer;
857
+ transition: background-color 0.15s, border-color 0.15s;
858
+ }
859
+
860
+ .np-toolbar-btn:hover {
861
+ background-color: #e2e8f0;
862
+ border-color: var(--np-border);
863
+ }
864
+
865
+ /* Rich Text Editor (contenteditable) */
866
+ .np-rich-text-editor {
867
+ min-height: 120px;
868
+ padding: 0.75rem;
869
+ border-radius: 0 0 0.375rem 0.375rem;
870
+ line-height: 1.6;
871
+ outline: none;
872
+ }
873
+
874
+ .np-rich-text-editor:focus {
875
+ border-color: var(--np-primary);
876
+ box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1);
877
+ }
878
+
879
+ .np-rich-text-editor p { margin: 0 0 0.5rem; }
880
+ .np-rich-text-editor ul,
881
+ .np-rich-text-editor ol { margin: 0 0 0.5rem; padding-left: 1.5rem; }
882
+
883
+ /* Block Picker Grid */
884
+ .np-block-picker-grid {
885
+ display: grid;
886
+ grid-template-columns: repeat(3, 1fr);
887
+ gap: 0.75rem;
888
+ }
889
+
890
+ @media (max-width: 640px) {
891
+ .np-block-picker-grid {
892
+ grid-template-columns: repeat(2, 1fr);
893
+ }
894
+ }
895
+
896
+ .np-block-picker-card {
897
+ display: flex;
898
+ flex-direction: column;
899
+ align-items: center;
900
+ gap: 0.25rem;
901
+ padding: 1rem 0.75rem;
902
+ border: 1px solid var(--np-border);
903
+ border-radius: 0.5rem;
904
+ background-color: #fff;
905
+ cursor: pointer;
906
+ text-align: center;
907
+ transition: border-color 0.15s, box-shadow 0.15s;
908
+ }
909
+
910
+ .np-block-picker-card:hover {
911
+ border-color: var(--np-primary);
912
+ box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1);
913
+ }
914
+
915
+ .np-block-picker-icon {
916
+ font-size: 1.5rem;
917
+ line-height: 1;
918
+ }
919
+
920
+ .np-block-picker-name {
921
+ font-size: 0.875rem;
922
+ font-weight: 600;
923
+ color: var(--np-text);
924
+ }
925
+
926
+ .np-block-picker-desc {
927
+ font-size: 0.75rem;
928
+ color: #64748b;
929
+ }
930
+
931
+ /* Drag-to-Reorder */
932
+ .np-block--dragging {
933
+ opacity: 0.5;
934
+ border: 2px dashed var(--np-primary);
935
+ }
936
+
937
+ .np-drop-indicator {
938
+ height: 3px;
939
+ background-color: var(--np-primary);
940
+ border-radius: 2px;
941
+ margin: 0.25rem 0;
942
+ }
943
+
944
+ .np-drag-handle {
945
+ cursor: grab;
946
+ font-size: 0.875rem;
947
+ color: #94a3b8;
948
+ padding: 0.125rem 0.25rem;
949
+ user-select: none;
950
+ }
951
+
952
+ .np-drag-handle:hover {
953
+ color: var(--np-text);
954
+ }
955
+
956
+ /* Block Header Left */
957
+ .np-block-header-left {
958
+ display: flex;
959
+ align-items: center;
960
+ gap: 0.5rem;
961
+ }
962
+
963
+ /* Block Picker Modal width override */
964
+ dialog.np-block-picker {
965
+ max-width: 40rem;
966
+ }
967
+
968
+ /* Preview Toggle */
969
+ .np-preview-toggle {
970
+ margin-bottom: 1rem;
971
+ }
972
+
973
+ .np-preview-toggle-buttons {
974
+ display: flex;
975
+ gap: 0.25rem;
976
+ margin-bottom: 1rem;
977
+ }
978
+
979
+ .np-preview-btn--active {
980
+ background-color: var(--np-primary) !important;
981
+ color: #fff !important;
982
+ border-color: var(--np-primary) !important;
983
+ }
984
+
985
+ /* Editor Split Layout */
986
+ .np-editor-split--active {
987
+ display: flex;
988
+ gap: 1rem;
989
+ }
990
+
991
+ .np-editor-pane {
992
+ min-width: 0;
993
+ flex: 1;
994
+ }
995
+
996
+ .np-preview-pane {
997
+ border-left: 1px solid var(--np-border);
998
+ overflow-y: auto;
999
+ min-width: 0;
1000
+ }
1001
+
1002
+ .np-preview-frame {
1003
+ width: 100%;
1004
+ min-height: 600px;
1005
+ height: 100%;
1006
+ border: none;
1007
+ background-color: #fff;
1008
+ }
1009
+
1010
+ /* Form Field Rows */
1011
+ .np-field-list {
1012
+ display: flex;
1013
+ flex-direction: column;
1014
+ gap: 0.5rem;
1015
+ }
1016
+
1017
+ .np-field-row {
1018
+ display: flex;
1019
+ align-items: flex-start;
1020
+ gap: 0.5rem;
1021
+ padding: 0.75rem;
1022
+ border: 1px solid var(--np-border);
1023
+ border-radius: 0.375rem;
1024
+ background-color: #fff;
1025
+ }
1026
+
1027
+ .np-field-row-inputs {
1028
+ flex: 1;
1029
+ display: flex;
1030
+ flex-wrap: wrap;
1031
+ gap: 0.5rem;
1032
+ min-width: 0;
1033
+ }
1034
+
1035
+ .np-field-row-group {
1036
+ min-width: 0;
1037
+ }
1038
+
1039
+ .np-field-row-group--label {
1040
+ flex: 1 1 10rem;
1041
+ }
1042
+
1043
+ .np-field-row-group--type {
1044
+ flex: 0 1 8rem;
1045
+ }
1046
+
1047
+ .np-field-row-group--required {
1048
+ flex: 0 0 auto;
1049
+ display: flex;
1050
+ align-items: center;
1051
+ padding-top: 0.25rem;
1052
+ }
1053
+
1054
+ .np-field-row-group--placeholder {
1055
+ flex: 1 1 10rem;
1056
+ }
1057
+
1058
+ .np-field-row-group--options {
1059
+ flex: 1 1 100%;
1060
+ }
1061
+
1062
+ .np-checkbox-label {
1063
+ font-size: 0.875rem;
1064
+ white-space: nowrap;
1065
+ display: flex;
1066
+ align-items: center;
1067
+ gap: 0.25rem;
1068
+ }
1069
+
1070
+ /* Media Library */
1071
+ .np-media-grid {
1072
+ display: grid;
1073
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
1074
+ gap: 1rem;
1075
+ }
1076
+
1077
+ .np-media-card {
1078
+ border: 1px solid var(--np-border);
1079
+ border-radius: 0.5rem;
1080
+ background-color: #fff;
1081
+ overflow: hidden;
1082
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
1083
+ transition: box-shadow 0.15s;
1084
+ }
1085
+
1086
+ .np-media-card:hover {
1087
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
1088
+ }
1089
+
1090
+ .np-media-card-thumb {
1091
+ width: 100%;
1092
+ height: 140px;
1093
+ display: flex;
1094
+ align-items: center;
1095
+ justify-content: center;
1096
+ background-color: #f1f5f9;
1097
+ overflow: hidden;
1098
+ }
1099
+
1100
+ .np-media-card-thumb img {
1101
+ max-width: 100%;
1102
+ max-height: 100%;
1103
+ object-fit: cover;
1104
+ }
1105
+
1106
+ .np-media-card-icon {
1107
+ font-size: 1.5rem;
1108
+ font-weight: 700;
1109
+ color: #94a3b8;
1110
+ }
1111
+
1112
+ .np-media-card-info {
1113
+ padding: 0.75rem;
1114
+ }
1115
+
1116
+ .np-media-card-title {
1117
+ font-size: 0.875rem;
1118
+ font-weight: 600;
1119
+ white-space: nowrap;
1120
+ overflow: hidden;
1121
+ text-overflow: ellipsis;
1122
+ margin-bottom: 0.25rem;
1123
+ }
1124
+
1125
+ .np-media-card-meta {
1126
+ display: flex;
1127
+ align-items: center;
1128
+ gap: 0.5rem;
1129
+ font-size: 0.75rem;
1130
+ color: #64748b;
1131
+ margin-bottom: 0.25rem;
1132
+ }
1133
+
1134
+ .np-media-card-date {
1135
+ font-size: 0.75rem;
1136
+ color: #94a3b8;
1137
+ }
1138
+
1139
+ .np-media-card-actions {
1140
+ padding: 0.5rem 0.75rem;
1141
+ border-top: 1px solid var(--np-border);
1142
+ display: flex;
1143
+ gap: 0.375rem;
1144
+ }
1145
+
1146
+ @media (max-width: 640px) {
1147
+ .np-media-grid {
1148
+ grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
1149
+ }
1150
+ }
1151
+
1152
+ @media (max-width: 768px) {
1153
+ .np-editor-split--active {
1154
+ flex-direction: column;
1155
+ }
1156
+
1157
+ .np-preview-pane {
1158
+ border-left: none;
1159
+ border-top: 1px solid var(--np-border);
1160
+ }
1161
+ }