@acms-subir/core 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/cli.mjs +75 -0
  2. package/integration.mjs +286 -0
  3. package/package.json +89 -0
  4. package/src/actions/index.ts +502 -0
  5. package/src/components/DesignManager.tsx +542 -0
  6. package/src/components/LinksManager.tsx +694 -0
  7. package/src/components/Modal.astro +65 -0
  8. package/src/components/NavManager.tsx +168 -0
  9. package/src/components/WidgetRenderer.astro +84 -0
  10. package/src/components/builder/PageBuilder.tsx +575 -0
  11. package/src/components/editor/ImagePicker.tsx +215 -0
  12. package/src/components/editor/PostEditor.tsx +1011 -0
  13. package/src/components/editor/PreviewOverlay.tsx +77 -0
  14. package/src/components/editor/extensions/calendar.tsx +230 -0
  15. package/src/components/editor/extensions/cards.tsx +488 -0
  16. package/src/components/editor/extensions/codeBlock.tsx +70 -0
  17. package/src/components/editor/extensions/infoCards.tsx +270 -0
  18. package/src/components/editor/extensions/mediaCards.tsx +376 -0
  19. package/src/components/editor/extensions/postList.tsx +130 -0
  20. package/src/components/editor/extensions/slash.tsx +250 -0
  21. package/src/components/editor/extensions/tableTyping.ts +63 -0
  22. package/src/components/editor/imaging.ts +146 -0
  23. package/src/components/media/CropModal.tsx +229 -0
  24. package/src/components/media/MediaLibrary.tsx +295 -0
  25. package/src/layouts/Admin.astro +119 -0
  26. package/src/layouts/Site.astro +218 -0
  27. package/src/lib/auth.ts +94 -0
  28. package/src/lib/backup/unzip.ts +38 -0
  29. package/src/lib/backup/zip.ts +105 -0
  30. package/src/lib/blocksToHtml.ts +68 -0
  31. package/src/lib/brand.ts +26 -0
  32. package/src/lib/calendar/ics.ts +402 -0
  33. package/src/lib/calendar/render.ts +275 -0
  34. package/src/lib/calendar/src.ts +68 -0
  35. package/src/lib/content.ts +53 -0
  36. package/src/lib/dates.ts +34 -0
  37. package/src/lib/dynamicBlocks.ts +115 -0
  38. package/src/lib/env.ts +6 -0
  39. package/src/lib/highlightCode.ts +44 -0
  40. package/src/lib/i18n.ts +40 -0
  41. package/src/lib/markdown.ts +7 -0
  42. package/src/lib/media/store.ts +95 -0
  43. package/src/lib/net.ts +51 -0
  44. package/src/lib/preview.ts +28 -0
  45. package/src/lib/repo/d1.ts +44 -0
  46. package/src/lib/repo/index.ts +23 -0
  47. package/src/lib/repo/migrations.ts +231 -0
  48. package/src/lib/repo/search.ts +14 -0
  49. package/src/lib/repo/sql.ts +721 -0
  50. package/src/lib/repo/sqlite.ts +43 -0
  51. package/src/lib/repo/types.ts +132 -0
  52. package/src/lib/schema.ts +286 -0
  53. package/src/lib/seo.ts +37 -0
  54. package/src/lib/theme.ts +206 -0
  55. package/src/lib/widgets.ts +108 -0
  56. package/src/middleware.ts +109 -0
  57. package/src/pages/[...slug].astro +43 -0
  58. package/src/pages/admin/c/[collection]/[id].astro +56 -0
  59. package/src/pages/admin/c/[collection]/index.astro +163 -0
  60. package/src/pages/admin/design.astro +42 -0
  61. package/src/pages/admin/index.astro +145 -0
  62. package/src/pages/admin/links.astro +21 -0
  63. package/src/pages/admin/login.astro +83 -0
  64. package/src/pages/admin/logout.ts +7 -0
  65. package/src/pages/admin/media.astro +13 -0
  66. package/src/pages/admin/navigation.astro +17 -0
  67. package/src/pages/admin/pages/[id].astro +49 -0
  68. package/src/pages/admin/pages/index.astro +100 -0
  69. package/src/pages/admin/posts/[id].astro +6 -0
  70. package/src/pages/admin/posts/index.astro +7 -0
  71. package/src/pages/admin/settings.astro +512 -0
  72. package/src/pages/admin/tags.astro +101 -0
  73. package/src/pages/admin/users.astro +149 -0
  74. package/src/pages/api/backup.ts +63 -0
  75. package/src/pages/api/drafts.ts +106 -0
  76. package/src/pages/api/media/upload.ts +89 -0
  77. package/src/pages/api/restore.ts +102 -0
  78. package/src/pages/author/[slug].astro +66 -0
  79. package/src/pages/blog/[slug].astro +240 -0
  80. package/src/pages/blog/index.astro +51 -0
  81. package/src/pages/blog/tag/[slug].astro +83 -0
  82. package/src/pages/embed/[pageId]/[blockId].ts +45 -0
  83. package/src/pages/go/[id].ts +10 -0
  84. package/src/pages/index.astro +52 -0
  85. package/src/pages/links.astro +110 -0
  86. package/src/pages/llms.txt.ts +47 -0
  87. package/src/pages/media/[...key].ts +18 -0
  88. package/src/pages/preview/[type]/[id].astro +52 -0
  89. package/src/pages/robots.txt.ts +28 -0
  90. package/src/pages/rss.xml.ts +58 -0
  91. package/src/pages/search.astro +83 -0
  92. package/src/pages/sitemap.xml.ts +55 -0
  93. package/src/styles/admin.css +652 -0
  94. package/src/styles/builder.css +121 -0
  95. package/src/styles/cards.css +176 -0
  96. package/src/styles/editor.css +596 -0
  97. package/src/styles/site.css +427 -0
  98. package/src/themes/editorial/templates/home.astro +127 -0
  99. package/src/themes/editorial/templates/post-minimal.astro +50 -0
  100. package/src/themes/editorial/theme.css +108 -0
  101. package/src/themes/editorial/theme.json +20 -0
  102. package/src/themes/field/theme.json +17 -0
  103. package/src/themes/ink/theme.json +17 -0
  104. package/src/themes/night/theme.css +7 -0
  105. package/src/themes/night/theme.json +17 -0
  106. package/src/virtual.d.ts +25 -0
  107. package/src/worker.ts +28 -0
@@ -0,0 +1,121 @@
1
+ /* Widget builder — three-pane layout (palette / canvas / inspector) on Ink.
2
+ Relies on :root tokens from admin.css and .pe-* primitives from editor.css. */
3
+
4
+ .pb-shell { height: 100vh; display: flex; flex-direction: column; background: var(--bg); overflow: hidden; }
5
+
6
+ .pb-topbar {
7
+ display: flex; align-items: center; justify-content: space-between; gap: 12px;
8
+ padding: 8px 14px; border-bottom: 1px solid var(--line); flex: 0 0 auto;
9
+ }
10
+ .pb-topbar-side { display: flex; align-items: center; gap: 10px; min-width: 260px; }
11
+ .pb-topbar-side.right { justify-content: flex-end; }
12
+ .pb-title { font-weight: 700; font-size: 13.5px; }
13
+ .pb-savestate { font-size: 11.5px; color: var(--faint); }
14
+ .pb-savestate.error { color: var(--red); }
15
+
16
+ .pb-body { flex: 1; display: flex; min-height: 0; }
17
+
18
+ /* palette */
19
+ .pb-palette {
20
+ width: 224px; flex: 0 0 224px; overflow-y: auto;
21
+ border-right: 1px solid var(--line); padding: 12px 10px 20px;
22
+ }
23
+ .pb-palette-group {
24
+ font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.07em;
25
+ color: var(--faint); padding: 10px 6px 6px;
26
+ }
27
+ .pb-tile {
28
+ display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
29
+ background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
30
+ padding: 8px 10px; margin-bottom: 6px; cursor: grab; font-family: inherit;
31
+ }
32
+ .pb-tile:hover { border-color: #34363f; }
33
+ .pb-tile.is-dragging { opacity: 0.4; }
34
+ .pb-tile.is-ghost { box-shadow: 0 12px 32px rgb(0 0 0 / 50%); width: 204px; background: var(--panel-2); }
35
+ .pb-tile-icon {
36
+ width: 28px; height: 28px; flex: 0 0 auto; display: grid; place-items: center;
37
+ background: var(--panel-2); border: 1px solid var(--line); border-radius: 7px; color: var(--muted);
38
+ }
39
+ .pb-tile-icon svg { width: 15px; height: 15px; }
40
+ .pb-tile-label { display: block; font-size: 12.5px; font-weight: 600; color: var(--text); }
41
+ .pb-tile-desc { display: block; font-size: 11px; color: var(--faint); }
42
+ .pb-tile-grip { margin-left: auto; color: var(--faint); font-size: 12px; }
43
+ .pb-palette-hint { font-size: 11px; color: var(--faint); padding: 10px 6px; line-height: 1.5; }
44
+
45
+ /* canvas */
46
+ .pb-canvas-wrap { flex: 1; min-width: 0; overflow-y: auto; padding: 22px; display: flex; justify-content: center; background: #0d0e11; }
47
+ .pb-canvas { display: flex; flex-direction: column; gap: 10px; align-self: flex-start; transition: width 0.2s ease; padding-bottom: 80px; }
48
+ .pb-block {
49
+ position: relative; background: var(--panel); border: 1px solid var(--line);
50
+ border-radius: 10px; padding: 30px 18px 16px; cursor: default;
51
+ }
52
+ .pb-block:hover { border-color: #34363f; }
53
+ .pb-block.is-selected { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
54
+ .pb-block.is-dragging { opacity: 0.35; }
55
+ .pb-block.is-ghost { box-shadow: 0 16px 40px rgb(0 0 0 / 55%); width: 520px; max-height: 220px; overflow: hidden; }
56
+ .pb-block-tools {
57
+ position: absolute; top: 6px; left: 8px; right: 8px;
58
+ display: flex; align-items: center; gap: 6px;
59
+ opacity: 0; transition: opacity 0.12s;
60
+ }
61
+ .pb-block:hover .pb-block-tools, .pb-block.is-selected .pb-block-tools { opacity: 1; }
62
+ .pb-block-tools button {
63
+ background: none; border: none; color: var(--faint); cursor: pointer;
64
+ font-size: 12px; padding: 2px 5px; border-radius: 5px; font-family: inherit;
65
+ }
66
+ .pb-block-tools button:hover { color: var(--text); background: rgb(255 255 255 / 5%); }
67
+ .pb-grip { cursor: grab !important; }
68
+ .pb-block-type {
69
+ font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.07em;
70
+ color: var(--accent); margin-right: auto;
71
+ }
72
+ .pb-empty {
73
+ border: 1.5px dashed var(--line); border-radius: 10px; padding: 60px 20px;
74
+ text-align: center; color: var(--faint); font-size: 13px; width: 100%;
75
+ }
76
+ .pb-empty.is-over { border-color: var(--accent); background: var(--accent-soft); color: var(--text); }
77
+
78
+ /* block previews */
79
+ .bp-hero { padding: 18px 8px 14px; }
80
+ .bp-hero-heading { font-size: 24px; font-weight: 700; letter-spacing: -0.02em; }
81
+ .bp-hero-sub { color: var(--muted); margin-top: 6px; font-size: 14px; }
82
+ .bp-hero .bp-btn { margin-top: 14px; }
83
+ .bp-btn {
84
+ display: inline-block; background: var(--accent); color: #fff; font-weight: 600;
85
+ font-size: 13px; padding: 7px 16px; border-radius: 7px;
86
+ }
87
+ .bp-btn.outline { background: none; border: 1px solid var(--accent); color: var(--accent); }
88
+ .bp-text { font-size: 14px; line-height: 1.65; color: var(--text); overflow-wrap: break-word; }
89
+ .bp-text h1, .bp-text h2, .bp-text h3 { margin: 0.6em 0 0.3em; }
90
+ .bp-text p { margin: 0 0 0.7em; }
91
+ .bp-text a { color: var(--accent); }
92
+ .bp-text code { background: var(--panel-2); padding: 1px 4px; border-radius: 4px; font-size: 0.9em; }
93
+ .bp-image img { max-width: 100%; border-radius: 7px; display: block; }
94
+ .bp-image figcaption { text-align: center; color: var(--faint); font-size: 12px; margin-top: 6px; }
95
+ .bp-image { margin: 0; }
96
+ .bp-spacer {
97
+ display: grid; place-items: center; border: 1px dashed var(--line); border-radius: 7px;
98
+ }
99
+ .bp-spacer span { font-size: 10.5px; color: var(--faint); text-transform: uppercase; letter-spacing: 0.06em; }
100
+ .bp-embed { width: 100%; border: 0; border-radius: 7px; background: #0b0c0e; display: block; }
101
+ .bp-placeholder {
102
+ padding: 22px 14px; border: 1px dashed var(--line); border-radius: 7px;
103
+ color: var(--faint); font-size: 12.5px; text-align: center;
104
+ }
105
+
106
+ /* inspector */
107
+ .pb-inspector {
108
+ width: 300px; flex: 0 0 300px; overflow-y: auto;
109
+ border-left: 1px solid var(--line); background: var(--panel);
110
+ padding: 14px 16px 24px;
111
+ }
112
+ .pb-inspector-head { margin-bottom: 14px; }
113
+ .pb-inspector-type { display: block; font-weight: 700; font-size: 14px; }
114
+ .pb-inspector-sub { display: block; font-size: 11.5px; color: var(--faint); }
115
+ .pb-code { font-family: ui-monospace, 'SF Mono', monospace; font-size: 12px; }
116
+ .pb-image-field { display: flex; gap: 6px; }
117
+ .pb-image-field input { flex: 1; min-width: 0; }
118
+ .pb-check {
119
+ display: flex; gap: 8px; align-items: center; font-size: 13px; margin: 4px 0 14px; cursor: pointer;
120
+ }
121
+ .pb-check input { width: auto; }
@@ -0,0 +1,176 @@
1
+ /* Wrapped in @layer base so theme CSS (inlined unlayered by Site.astro)
2
+ always wins ties, regardless of bundle order in the built head. */
3
+ @layer base {
4
+ /* Public rendering of editor cards (.pc-*) — loaded by the site layout so
5
+ posts written in the editor look right without any per-page CSS. */
6
+
7
+ .pc-image { margin: 1.6em 0; }
8
+ .pc-image img { width: 100%; height: auto; border-radius: 8px; display: block; }
9
+ .pc-image figcaption, .pc-embed figcaption { text-align: center; font-size: 0.82em; color: #777; margin-top: 8px; }
10
+
11
+ .pc-embed { margin: 1.6em 0; }
12
+ .pc-embed-frame { width: 100%; border-radius: 8px; overflow: hidden; background: #000; }
13
+ .pc-embed-frame iframe { width: 100%; height: 100%; border: 0; display: block; }
14
+
15
+ .pc-buttoncard { margin: 1.6em 0; }
16
+ .pc-btncard {
17
+ display: inline-block; background: #6e7bff; color: #fff !important; text-decoration: none;
18
+ font-weight: 600; padding: 10px 22px; border-radius: 8px;
19
+ }
20
+ .pc-btncard:hover { background: #7d88ff; }
21
+
22
+ .pc-callout {
23
+ display: flex; gap: 12px; align-items: flex-start;
24
+ background: rgb(110 123 255 / 8%); border: 1px solid rgb(110 123 255 / 22%);
25
+ border-radius: 10px; padding: 14px 16px; margin: 1.6em 0;
26
+ }
27
+ .pc-callout-emoji { font-size: 1.2em; line-height: 1.4; }
28
+ .pc-callout-body { flex: 1; min-width: 0; }
29
+
30
+ .pc-html { margin: 1.6em 0; }
31
+
32
+ /* file / download card */
33
+ .pc-filecard {
34
+ display: flex; align-items: center; gap: 14px; margin: 1.6em 0;
35
+ border: 1px solid rgb(128 128 128 / 25%); border-radius: 10px; padding: 14px 18px;
36
+ text-decoration: none; color: inherit; transition: border-color 0.15s;
37
+ }
38
+ .pc-filecard:hover { border-color: rgb(110 123 255 / 55%); }
39
+ .pc-file-icon {
40
+ display: flex; align-items: center; justify-content: center; flex: none;
41
+ width: 38px; height: 38px; border-radius: 9px; font-size: 1.1em;
42
+ background: rgb(110 123 255 / 12%); color: #6e7bff;
43
+ }
44
+ .pc-file-text { display: flex; flex-direction: column; min-width: 0; }
45
+ .pc-file-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
46
+ .pc-file-meta { font-size: 0.8em; opacity: 0.65; }
47
+
48
+ /* gallery card */
49
+ .pc-gallery { margin: 1.6em 0; }
50
+ .pc-gallery-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
51
+ .pc-gallery-grid[data-count='1'] { grid-template-columns: 1fr; }
52
+ .pc-gallery-grid[data-count='2'], .pc-gallery-grid[data-count='4'] { grid-template-columns: repeat(2, 1fr); }
53
+ .pc-gallery-grid img {
54
+ width: 100%; height: 100%; aspect-ratio: 4 / 3; object-fit: cover;
55
+ border-radius: 8px; display: block;
56
+ }
57
+ .pc-gallery figcaption { text-align: center; font-size: 0.82em; color: #777; margin-top: 8px; }
58
+ @media (max-width: 560px) { .pc-gallery-grid { grid-template-columns: repeat(2, 1fr); } }
59
+
60
+ /* bookmark card */
61
+ .pc-bookmark {
62
+ display: flex; margin: 1.6em 0; border: 1px solid rgb(128 128 128 / 25%);
63
+ border-radius: 10px; overflow: hidden; text-decoration: none; color: inherit;
64
+ transition: border-color 0.15s; min-height: 96px;
65
+ }
66
+ .pc-bookmark:hover { border-color: rgb(110 123 255 / 55%); }
67
+ .pc-bookmark-content {
68
+ flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px;
69
+ padding: 14px 18px; justify-content: center;
70
+ }
71
+ .pc-bookmark-title {
72
+ font-weight: 600; line-height: 1.35;
73
+ display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
74
+ }
75
+ .pc-bookmark-desc {
76
+ font-size: 0.85em; opacity: 0.75; line-height: 1.45;
77
+ display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
78
+ }
79
+ .pc-bookmark-meta { display: flex; align-items: center; gap: 7px; font-size: 0.78em; opacity: 0.65; margin-top: 2px; }
80
+ .pc-bookmark-favicon { width: 16px; height: 16px; border-radius: 3px; }
81
+ .pc-bookmark-thumb { flex: none; width: 33%; max-width: 240px; }
82
+ .pc-bookmark-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
83
+ @media (max-width: 560px) { .pc-bookmark-thumb { display: none; } }
84
+
85
+ }
86
+
87
+ @layer base {
88
+ /* image width variants: wide breaks past the column, full bleeds edge-to-edge.
89
+ Breakouts only engage on viewports wider than the content column. */
90
+ body { overflow-x: clip; }
91
+ @media (min-width: 900px) {
92
+ .pc-image[data-width='wide'] {
93
+ width: min(100vw - 48px, var(--content-width, 760px) + 280px);
94
+ margin-left: calc(50% - min(100vw - 48px, var(--content-width, 760px) + 280px) / 2);
95
+ }
96
+ }
97
+ .pc-image[data-width='full'] {
98
+ width: 100vw;
99
+ margin-left: calc(50% - 50vw);
100
+ }
101
+ .pc-image[data-width='full'] img { border-radius: 0; }
102
+ .pc-image[data-width='full'] figcaption { padding: 0 20px; }
103
+ }
104
+
105
+ /* Info cards (static block): grid of title / badge / description / detail-line
106
+ cards edited in the admin (extensions/infoCards.tsx). Styling API mirrors
107
+ the calendar card: scoped --info-* custom properties (defaulting to theme
108
+ tokens) + stable .pc-info-* class hooks. Theme CSS and Settings → Code
109
+ injection are unlayered, so either overrides any of this without
110
+ !important. Line icons are CSS mask data-URIs mirroring INFO_ICONS in
111
+ infoCards.tsx (keep in sync); themes can recolor them via --info-icon or
112
+ swap any mask-image. */
113
+ @layer base {
114
+ .pc-infocards {
115
+ --info-bg: var(--panel);
116
+ --info-ink: var(--ink);
117
+ --info-muted: var(--muted);
118
+ --info-line: var(--line);
119
+ --info-badge: var(--accent);
120
+ --info-badge-ink: var(--panel);
121
+ --info-icon: var(--accent);
122
+ --info-radius: 14px;
123
+ --info-min: 240px; /* grid column min width */
124
+ --info-gap: 18px;
125
+ display: grid;
126
+ grid-template-columns: repeat(auto-fill, minmax(min(var(--info-min), 100%), 1fr));
127
+ gap: var(--info-gap);
128
+ margin: 1.6em 0;
129
+ }
130
+ .pc-info-card {
131
+ display: flex; flex-direction: column; gap: 8px; min-width: 0;
132
+ background: var(--info-bg); border: 1px solid var(--info-line);
133
+ border-radius: var(--info-radius); padding: 20px 22px;
134
+ color: inherit; text-decoration: none;
135
+ }
136
+ a.pc-info-card { transition: border-color 0.15s; }
137
+ a.pc-info-card:hover { border-color: var(--info-badge); }
138
+ .pc-info-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
139
+ .pc-info-title {
140
+ font-family: var(--font-heading); font-size: 19px; font-weight: 800;
141
+ letter-spacing: -0.01em; line-height: 1.25; color: var(--info-ink); margin: 0;
142
+ }
143
+ .pc-info-badge {
144
+ flex: none; font-size: 12px; font-weight: 600; line-height: 1; white-space: nowrap;
145
+ border-radius: 999px; padding: 5px 12px;
146
+ color: var(--info-ink); border: 1px solid var(--info-line); background: transparent;
147
+ }
148
+ .pc-info-badge.is-filled { background: var(--info-badge); border-color: var(--info-badge); color: var(--info-badge-ink); }
149
+ .pc-info-desc { color: var(--info-muted); font-size: 14.5px; line-height: 1.55; margin: 0; }
150
+ /* margin-top:auto pins the divider row to the card bottom, so cards in the
151
+ same grid row keep their meta lines aligned regardless of text length */
152
+ .pc-info-meta {
153
+ display: flex; flex-wrap: wrap; gap: 6px 18px;
154
+ border-top: 1px solid var(--info-line); padding-top: 12px; margin-top: auto;
155
+ }
156
+ .pc-info-card:not(:has(.pc-info-meta)) .pc-info-head { margin-bottom: 0; }
157
+ .pc-info-row {
158
+ display: inline-flex; align-items: center; gap: 8px; min-width: 0;
159
+ font-size: 14px; color: var(--info-ink);
160
+ }
161
+ .pc-info-row::before {
162
+ content: ''; display: none; flex: none; width: 15px; height: 15px;
163
+ background: var(--info-icon);
164
+ -webkit-mask: center / contain no-repeat;
165
+ mask: center / contain no-repeat;
166
+ }
167
+ .pc-info-row[data-icon='calendar']::before { display: inline-block; -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 5h18v16H3zM3 9h18M8 3v4M16 3v4'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 5h18v16H3zM3 9h18M8 3v4M16 3v4'/%3E%3C/svg%3E"); }
168
+ .pc-info-row[data-icon='clock']::before { display: inline-block; -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3a9 9 0 1 1 0 18 9 9 0 0 1 0-18M12 7v5l3 2'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3a9 9 0 1 1 0 18 9 9 0 0 1 0-18M12 7v5l3 2'/%3E%3C/svg%3E"); }
169
+ .pc-info-row[data-icon='pin']::before { display: inline-block; -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 21s-7-5.6-7-11a7 7 0 0 1 14 0c0 5.4-7 11-7 11zM12 12.5a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 21s-7-5.6-7-11a7 7 0 0 1 14 0c0 5.4-7 11-7 11zM12 12.5a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5'/%3E%3C/svg%3E"); }
170
+ .pc-info-row[data-icon='person']::before { display: inline-block; -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM4 21c0-4 3.6-6.5 8-6.5s8 2.5 8 6.5'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM4 21c0-4 3.6-6.5 8-6.5s8 2.5 8 6.5'/%3E%3C/svg%3E"); }
171
+ .pc-info-row[data-icon='phone']::before { display: inline-block; -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 16.5v3a2 2 0 0 1-2.2 2A19 19 0 0 1 3 4.2 2 2 0 0 1 5 2h3l2 5-2.5 2a15 15 0 0 0 7.5 7.5L17 14l5 2.5z'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 16.5v3a2 2 0 0 1-2.2 2A19 19 0 0 1 3 4.2 2 2 0 0 1 5 2h3l2 5-2.5 2a15 15 0 0 0 7.5 7.5L17 14l5 2.5z'/%3E%3C/svg%3E"); }
172
+ .pc-info-row[data-icon='mail']::before { display: inline-block; -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 6h18v13H3zM3 8l9 6 9-6'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 6h18v13H3zM3 8l9 6 9-6'/%3E%3C/svg%3E"); }
173
+ .pc-info-row[data-icon='link']::before { display: inline-block; -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10 14a5 5 0 0 0 7 0l3-3a5 5 0 0 0-7-7l-1.5 1.5M14 10a5 5 0 0 0-7 0l-3 3a5 5 0 0 0 7 7l1.5-1.5'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10 14a5 5 0 0 0 7 0l3-3a5 5 0 0 0-7-7l-1.5 1.5M14 10a5 5 0 0 0-7 0l-3 3a5 5 0 0 0 7 7l1.5-1.5'/%3E%3C/svg%3E"); }
174
+ .pc-info-row[data-icon='tag']::before { display: inline-block; -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 4h7l9 9-7 7-9-9zM8.5 8.5h.01'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 4h7l9 9-7 7-9-9zM8.5 8.5h.01'/%3E%3C/svg%3E"); }
175
+ .pc-info-row[data-icon='check']::before { display: inline-block; -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12.5l5 5 11-11'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12.5l5 5 11-11'/%3E%3C/svg%3E"); }
176
+ }