core-maugli 1.2.10 → 1.2.11

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 (169) hide show
  1. package/package.json +4 -3
  2. package/public/blackbox-1200.webp +0 -0
  3. package/public/blackbox-400.webp +0 -0
  4. package/public/blackbox-800.webp +0 -0
  5. package/public/img/default/autor_default-1200.webp +0 -0
  6. package/public/img/default/autor_default-400.webp +0 -0
  7. package/public/img/default/autor_default-800.webp +0 -0
  8. package/public/img/default/blog_default-1200.webp +0 -0
  9. package/public/img/default/blog_default-400.webp +0 -0
  10. package/public/img/default/blog_default-800.webp +0 -0
  11. package/public/img/default/default-1200.webp +0 -0
  12. package/public/img/default/default-400.webp +0 -0
  13. package/public/img/default/default-800.webp +0 -0
  14. package/public/img/default/previews/autor_default-1200.webp +0 -0
  15. package/public/img/default/previews/autor_default-400.webp +0 -0
  16. package/public/img/default/previews/autor_default-800.webp +0 -0
  17. package/public/img/default/previews/blog_default-1200.webp +0 -0
  18. package/public/img/default/previews/blog_default-400.webp +0 -0
  19. package/public/img/default/previews/blog_default-800.webp +0 -0
  20. package/public/img/default/previews/default-1200.webp +0 -0
  21. package/public/img/default/previews/default-400.webp +0 -0
  22. package/public/img/default/previews/default-800.webp +0 -0
  23. package/public/img/default/previews/product_default-1200.webp +0 -0
  24. package/public/img/default/previews/product_default-400.webp +0 -0
  25. package/public/img/default/previews/product_default-800.webp +0 -0
  26. package/public/img/default/previews/project_default-1200.webp +0 -0
  27. package/public/img/default/previews/project_default-400.webp +0 -0
  28. package/public/img/default/previews/project_default-800.webp +0 -0
  29. package/public/img/default/previews/rubric_default-1200.webp +0 -0
  30. package/public/img/default/previews/rubric_default-400.webp +0 -0
  31. package/public/img/default/previews/rubric_default-800.webp +0 -0
  32. package/public/img/default/previews/test-1200.webp +0 -0
  33. package/public/img/default/previews/test-400.webp +0 -0
  34. package/public/img/default/previews/test-800.webp +0 -0
  35. package/public/img/default/previews/test2-1200.webp +0 -0
  36. package/public/img/default/previews/test2-400.webp +0 -0
  37. package/public/img/default/previews/test2-800.webp +0 -0
  38. package/public/img/default/product_default-1200.webp +0 -0
  39. package/public/img/default/product_default-400.webp +0 -0
  40. package/public/img/default/product_default-800.webp +0 -0
  41. package/public/img/default/project_default-1200.webp +0 -0
  42. package/public/img/default/project_default-400.webp +0 -0
  43. package/public/img/default/project_default-800.webp +0 -0
  44. package/public/img/default/rubric_default-1200.webp +0 -0
  45. package/public/img/default/rubric_default-400.webp +0 -0
  46. package/public/img/default/rubric_default-800.webp +0 -0
  47. package/public/img/default/rubric_default.webp +0 -0
  48. package/public/img/default/test-1200.webp +0 -0
  49. package/public/img/default/test-400.webp +0 -0
  50. package/public/img/default/test-800.webp +0 -0
  51. package/public/img/default/test2-1200.webp +0 -0
  52. package/public/img/default/test2-400.webp +0 -0
  53. package/public/img/default/test2-800.webp +0 -0
  54. package/public/img/examples/authors/anna-1200.webp +0 -0
  55. package/public/img/examples/authors/anna-400.webp +0 -0
  56. package/public/img/examples/authors/anna-800.webp +0 -0
  57. package/public/img/examples/authors/carlos-1200.webp +0 -0
  58. package/public/img/examples/authors/carlos-400.webp +0 -0
  59. package/public/img/examples/authors/carlos-800.webp +0 -0
  60. package/public/img/examples/authors/daria-1200.webp +0 -0
  61. package/public/img/examples/authors/daria-400.webp +0 -0
  62. package/public/img/examples/authors/daria-800.webp +0 -0
  63. package/public/img/examples/authors/dmitry-1200.webp +0 -0
  64. package/public/img/examples/authors/dmitry-400.webp +0 -0
  65. package/public/img/examples/authors/dmitry-800.webp +0 -0
  66. package/public/img/examples/authors/igor-1200.webp +0 -0
  67. package/public/img/examples/authors/igor-400.webp +0 -0
  68. package/public/img/examples/authors/igor-800.webp +0 -0
  69. package/public/img/examples/authors/john-1200.webp +0 -0
  70. package/public/img/examples/authors/john-400.webp +0 -0
  71. package/public/img/examples/authors/john-800.webp +0 -0
  72. package/public/img/examples/blog/post-1-avtomatizaciya-marketinga-kak-ii-osvobozhdaet-predprinimatelei-ot-cifrovogo-rabstva-1200.webp +0 -0
  73. package/public/img/examples/blog/post-1-avtomatizaciya-marketinga-kak-ii-osvobozhdaet-predprinimatelei-ot-cifrovogo-rabstva-400.webp +0 -0
  74. package/public/img/examples/blog/post-1-avtomatizaciya-marketinga-kak-ii-osvobozhdaet-predprinimatelei-ot-cifrovogo-rabstva-800.webp +0 -0
  75. package/public/img/examples/blog/post-2-avtomatizaciya-kontenta-kak-neiroseti-ubivayut-perfekcionizm-v-biznese-1200.webp +0 -0
  76. package/public/img/examples/blog/post-2-avtomatizaciya-kontenta-kak-neiroseti-ubivayut-perfekcionizm-v-biznese-400.webp +0 -0
  77. package/public/img/examples/blog/post-2-avtomatizaciya-kontenta-kak-neiroseti-ubivayut-perfekcionizm-v-biznese-800.webp +0 -0
  78. package/public/img/examples/blog/post-3-laik-ne-valyuta-kak-avtomatizaciya-marketinga-spasaet-ot-lozhnyh-metrik-1200.webp +0 -0
  79. package/public/img/examples/blog/post-3-laik-ne-valyuta-kak-avtomatizaciya-marketinga-spasaet-ot-lozhnyh-metrik-400.webp +0 -0
  80. package/public/img/examples/blog/post-3-laik-ne-valyuta-kak-avtomatizaciya-marketinga-spasaet-ot-lozhnyh-metrik-800.webp +0 -0
  81. package/public/img/examples/blog/post-5-5-fatalnyh-oshibok-marketinga-kotorye-ubivayut-startapy-na-starte-1200.webp +0 -0
  82. package/public/img/examples/blog/post-5-5-fatalnyh-oshibok-marketinga-kotorye-ubivayut-startapy-na-starte-400.webp +0 -0
  83. package/public/img/examples/blog/post-5-5-fatalnyh-oshibok-marketinga-kotorye-ubivayut-startapy-na-starte-800.webp +0 -0
  84. package/public/img/examples/blog/post-6-5-strategii-kontent-marketinga-dlya-startapov-avtomatizaciya-i-revolyuciya-1200.webp +0 -0
  85. package/public/img/examples/blog/post-6-5-strategii-kontent-marketinga-dlya-startapov-avtomatizaciya-i-revolyuciya-400.webp +0 -0
  86. package/public/img/examples/blog/post-6-5-strategii-kontent-marketinga-dlya-startapov-avtomatizaciya-i-revolyuciya-800.webp +0 -0
  87. package/public/img/examples/blog/post-7-viralnyi-kontent-ne-udacha-a-strategiya-avtomatizaciya-marketinga-1200.webp +0 -0
  88. package/public/img/examples/blog/post-7-viralnyi-kontent-ne-udacha-a-strategiya-avtomatizaciya-marketinga-400.webp +0 -0
  89. package/public/img/examples/blog/post-7-viralnyi-kontent-ne-udacha-a-strategiya-avtomatizaciya-marketinga-800.webp +0 -0
  90. package/public/img/examples/blog/post-agent-experience-mcp-biznes-v-epohu-ii-agentov-1200.webp +0 -0
  91. package/public/img/examples/blog/post-agent-experience-mcp-biznes-v-epohu-ii-agentov-400.webp +0 -0
  92. package/public/img/examples/blog/post-agent-experience-mcp-biznes-v-epohu-ii-agentov-800.webp +0 -0
  93. package/public/img/examples/blog/post_11-1200.webp +0 -0
  94. package/public/img/examples/blog/post_11-400.webp +0 -0
  95. package/public/img/examples/blog/post_11-800.webp +0 -0
  96. package/public/img/examples/blog/post_12-1200.webp +0 -0
  97. package/public/img/examples/blog/post_12-400.webp +0 -0
  98. package/public/img/examples/blog/post_12-800.webp +0 -0
  99. package/public/img/examples/blog/post_1_jsonld_guide-1200.webp +0 -0
  100. package/public/img/examples/blog/post_1_jsonld_guide-400.webp +0 -0
  101. package/public/img/examples/blog/post_1_jsonld_guide-800.webp +0 -0
  102. package/public/img/examples/blog/previews/post-1-avtomatizaciya-marketinga-kak-ii-osvobozhdaet-predprinimatelei-ot-cifrovogo-rabstva-1200.webp +0 -0
  103. package/public/img/examples/blog/previews/post-1-avtomatizaciya-marketinga-kak-ii-osvobozhdaet-predprinimatelei-ot-cifrovogo-rabstva-400.webp +0 -0
  104. package/public/img/examples/blog/previews/post-1-avtomatizaciya-marketinga-kak-ii-osvobozhdaet-predprinimatelei-ot-cifrovogo-rabstva-800.webp +0 -0
  105. package/public/img/examples/blog/previews/post-2-avtomatizaciya-kontenta-kak-neiroseti-ubivayut-perfekcionizm-v-biznese-1200.webp +0 -0
  106. package/public/img/examples/blog/previews/post-2-avtomatizaciya-kontenta-kak-neiroseti-ubivayut-perfekcionizm-v-biznese-400.webp +0 -0
  107. package/public/img/examples/blog/previews/post-2-avtomatizaciya-kontenta-kak-neiroseti-ubivayut-perfekcionizm-v-biznese-800.webp +0 -0
  108. package/public/img/examples/blog/previews/post-3-laik-ne-valyuta-kak-avtomatizaciya-marketinga-spasaet-ot-lozhnyh-metrik-1200.webp +0 -0
  109. package/public/img/examples/blog/previews/post-3-laik-ne-valyuta-kak-avtomatizaciya-marketinga-spasaet-ot-lozhnyh-metrik-400.webp +0 -0
  110. package/public/img/examples/blog/previews/post-3-laik-ne-valyuta-kak-avtomatizaciya-marketinga-spasaet-ot-lozhnyh-metrik-800.webp +0 -0
  111. package/public/img/examples/blog/previews/post-5-5-fatalnyh-oshibok-marketinga-kotorye-ubivayut-startapy-na-starte-1200.webp +0 -0
  112. package/public/img/examples/blog/previews/post-5-5-fatalnyh-oshibok-marketinga-kotorye-ubivayut-startapy-na-starte-400.webp +0 -0
  113. package/public/img/examples/blog/previews/post-5-5-fatalnyh-oshibok-marketinga-kotorye-ubivayut-startapy-na-starte-800.webp +0 -0
  114. package/public/img/examples/blog/previews/post-6-5-strategii-kontent-marketinga-dlya-startapov-avtomatizaciya-i-revolyuciya-1200.webp +0 -0
  115. package/public/img/examples/blog/previews/post-6-5-strategii-kontent-marketinga-dlya-startapov-avtomatizaciya-i-revolyuciya-400.webp +0 -0
  116. package/public/img/examples/blog/previews/post-6-5-strategii-kontent-marketinga-dlya-startapov-avtomatizaciya-i-revolyuciya-800.webp +0 -0
  117. package/public/img/examples/blog/previews/post-7-viralnyi-kontent-ne-udacha-a-strategiya-avtomatizaciya-marketinga-1200.webp +0 -0
  118. package/public/img/examples/blog/previews/post-7-viralnyi-kontent-ne-udacha-a-strategiya-avtomatizaciya-marketinga-400.webp +0 -0
  119. package/public/img/examples/blog/previews/post-7-viralnyi-kontent-ne-udacha-a-strategiya-avtomatizaciya-marketinga-800.webp +0 -0
  120. package/public/img/examples/blog/previews/post-agent-experience-mcp-biznes-v-epohu-ii-agentov-1200.webp +0 -0
  121. package/public/img/examples/blog/previews/post-agent-experience-mcp-biznes-v-epohu-ii-agentov-400.webp +0 -0
  122. package/public/img/examples/blog/previews/post-agent-experience-mcp-biznes-v-epohu-ii-agentov-800.webp +0 -0
  123. package/public/img/examples/blog/previews/post_11-1200.webp +0 -0
  124. package/public/img/examples/blog/previews/post_11-400.webp +0 -0
  125. package/public/img/examples/blog/previews/post_11-800.webp +0 -0
  126. package/public/img/examples/blog/previews/post_12-1200.webp +0 -0
  127. package/public/img/examples/blog/previews/post_12-400.webp +0 -0
  128. package/public/img/examples/blog/previews/post_12-800.webp +0 -0
  129. package/public/img/examples/blog/previews/post_1_jsonld_guide-1200.webp +0 -0
  130. package/public/img/examples/blog/previews/post_1_jsonld_guide-400.webp +0 -0
  131. package/public/img/examples/blog/previews/post_1_jsonld_guide-800.webp +0 -0
  132. package/public/img/examples/blog/previews/test-post-1200.webp +0 -0
  133. package/public/img/examples/blog/previews/test-post-400.webp +0 -0
  134. package/public/img/examples/blog/previews/test-post-800.webp +0 -0
  135. package/public/img/examples/blog/test-post-1200.webp +0 -0
  136. package/public/img/examples/blog/test-post-400.webp +0 -0
  137. package/public/img/examples/blog/test-post-800.webp +0 -0
  138. package/public/img/examples/products/previews/product_1-1200.webp +0 -0
  139. package/public/img/examples/products/previews/product_1-400.webp +0 -0
  140. package/public/img/examples/products/previews/product_1-800.webp +0 -0
  141. package/public/img/examples/products/previews/product_2-1200.webp +0 -0
  142. package/public/img/examples/products/previews/product_2-400.webp +0 -0
  143. package/public/img/examples/products/previews/product_2-800.webp +0 -0
  144. package/public/img/examples/products/product_1-1200.webp +0 -0
  145. package/public/img/examples/products/product_1-400.webp +0 -0
  146. package/public/img/examples/products/product_1-800.webp +0 -0
  147. package/public/img/examples/products/product_2-1200.webp +0 -0
  148. package/public/img/examples/products/product_2-400.webp +0 -0
  149. package/public/img/examples/products/product_2-800.webp +0 -0
  150. package/public/img/examples/projects/previews/project_1-1200.webp +0 -0
  151. package/public/img/examples/projects/previews/project_1-400.webp +0 -0
  152. package/public/img/examples/projects/previews/project_1-800.webp +0 -0
  153. package/public/img/examples/projects/previews/project_2-1200.webp +0 -0
  154. package/public/img/examples/projects/previews/project_2-400.webp +0 -0
  155. package/public/img/examples/projects/previews/project_2-800.webp +0 -0
  156. package/public/img/examples/projects/project_1-1200.webp +0 -0
  157. package/public/img/examples/projects/project_1-400.webp +0 -0
  158. package/public/img/examples/projects/project_1-800.webp +0 -0
  159. package/public/img/examples/projects/project_2-1200.webp +0 -0
  160. package/public/img/examples/projects/project_2-400.webp +0 -0
  161. package/public/img/examples/projects/project_2-800.webp +0 -0
  162. package/public/img/page-images/blog_default-1200.webp +0 -0
  163. package/public/img/page-images/blog_default-400.webp +0 -0
  164. package/public/img/page-images/blog_default-800.webp +0 -0
  165. package/scripts/generate-previews.js +22 -14
  166. package/src/components/RubricCard.astro +78 -5
  167. package/src/content/tags/ai-business.mdx +1 -3
  168. package/src/content/tags/automation.mdx +1 -3
  169. package/src/content/tags/content-strategy.mdx +1 -3
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "core-maugli",
3
3
  "description": "Astro & Tailwind CSS blog theme for Maugli.",
4
4
  "type": "module",
5
- "version": "1.2.10",
5
+ "version": "1.2.11",
6
6
  "license": "GPL-3.0-or-later OR Commercial",
7
7
  "repository": {
8
8
  "type": "git",
@@ -19,9 +19,10 @@
19
19
  ],
20
20
  "scripts": {
21
21
  "typograf": "node typograf-batch.js",
22
- "dev": "astro dev",
22
+ "dev": "node resize-all.cjs && node scripts/generate-previews.js && astro dev",
23
+ "prestart": "node resize-all.cjs && node scripts/generate-previews.js",
23
24
  "start": "astro dev",
24
- "build": "node typograf-batch.js && node scripts/verify-assets.js && node scripts/generate-previews.js && astro build",
25
+ "build": "node resize-all.cjs && node typograf-batch.js && node scripts/verify-assets.js && node scripts/generate-previews.js && astro build",
25
26
  "test": "node tests/examplesFilter.test.ts",
26
27
  "astro": "astro",
27
28
  "featured:add": "node scripts/featured.js add",
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -103,6 +103,8 @@ function extractImagePaths() {
103
103
  const items = fs.readdirSync(defaultDir);
104
104
  for (const item of items) {
105
105
  if (item.match(/\.(webp|jpg|jpeg|png)$/i)) {
106
+ // Исключаем изображения авторов и рубрик
107
+ if (item.includes('autor') || item.includes('author') || item.includes('rubric')) continue;
106
108
  imagePaths.add(`/img/default/${item}`);
107
109
  }
108
110
  }
@@ -141,42 +143,44 @@ function cleanupExistingPreviews() {
141
143
  // Функция для создания превьюшки
142
144
  async function createPreview(imagePath) {
143
145
  const fullImagePath = path.join(rootDir, 'public', imagePath.replace(/^\//, ''));
144
-
146
+
145
147
  if (!fs.existsSync(fullImagePath)) {
146
148
  console.warn(`Image not found: ${fullImagePath}`);
147
149
  return;
148
150
  }
149
-
151
+
150
152
  const dir = path.dirname(fullImagePath);
151
153
  const ext = path.extname(fullImagePath);
152
154
  const name = path.basename(fullImagePath, ext);
153
155
  const previewPath = path.join(dir, 'previews', `${name}${ext}`);
154
-
156
+
155
157
  // Определяем размер превью в зависимости от типа изображения
156
158
  let previewWidth, previewHeight;
157
159
  if (imagePath.includes('/img/default/') && (name.includes('rubric') || name.includes('tag'))) {
158
- // Для изображений рубрик используем меньший размер
159
160
  previewWidth = rubricPreviewWidth;
160
161
  previewHeight = rubricPreviewHeight;
161
162
  console.log(`Creating rubric preview (${previewWidth}x${previewHeight}): ${name}`);
162
163
  } else {
163
- // Для блог-постов и других изображений используем стандартный размер
164
164
  previewWidth = blogPreviewWidth;
165
165
  previewHeight = blogPreviewHeight;
166
166
  console.log(`Creating blog preview (${previewWidth}x${previewHeight}): ${name}`);
167
167
  }
168
-
168
+
169
169
  // Создаем папку previews если её нет
170
170
  const previewDir = path.dirname(previewPath);
171
171
  if (!fs.existsSync(previewDir)) {
172
172
  fs.mkdirSync(previewDir, { recursive: true });
173
173
  }
174
-
174
+
175
+ // Если превью уже существует — пропускаем генерацию
176
+ if (fs.existsSync(previewPath)) {
177
+ // console.log(`Preview already exists: ${previewPath}`);
178
+ return;
179
+ }
175
180
  try {
176
181
  await sharp(fullImagePath)
177
182
  .resize(previewWidth, previewHeight, { fit: 'cover' })
178
183
  .toFile(previewPath);
179
-
180
184
  console.log(`Preview created: ${previewPath}`);
181
185
  } catch (error) {
182
186
  console.error(`Error processing ${fullImagePath}:`, error.message);
@@ -185,18 +189,22 @@ async function createPreview(imagePath) {
185
189
 
186
190
  // Основная функция
187
191
  async function generatePreviews() {
188
- console.log('Cleaning up existing previews...');
189
- cleanupExistingPreviews();
190
-
192
+ // Очистка превью только если явно указано (например, через переменную)
193
+ const CLEAN_PREVIEWS = process.env.CLEAN_PREVIEWS === '1';
194
+ if (CLEAN_PREVIEWS) {
195
+ console.log('Cleaning up existing previews...');
196
+ cleanupExistingPreviews();
197
+ }
198
+
191
199
  console.log('Scanning content for images...');
192
200
  const imagePaths = extractImagePaths();
193
-
201
+
194
202
  console.log(`Found ${imagePaths.length} images to process`);
195
-
203
+
196
204
  for (const imagePath of imagePaths) {
197
205
  await createPreview(imagePath);
198
206
  }
199
-
207
+
200
208
  console.log('Preview generation completed!');
201
209
  }
202
210
 
@@ -112,14 +112,77 @@ function getPreviewImageSrc(imageSrc: string): string {
112
112
  return absolutePreviewPath;
113
113
  }
114
114
 
115
- const imageSrc = image?.src || maugliConfig.defaultRubricImage;
116
- const previewImageSrc = getPreviewImageSrc(imageSrc);
115
+ // Всегда используем дефолтное изображение для рубрик
116
+ const previewImageSrc = '/img/default/previews/rubric_default.webp';
117
+
118
+ // Список стоп-слов (предлоги, союзы, знаки)
119
+ const stopWords = [
120
+ 'и',
121
+ 'в',
122
+ 'на',
123
+ 'с',
124
+ 'по',
125
+ 'от',
126
+ 'до',
127
+ 'за',
128
+ 'над',
129
+ 'под',
130
+ 'о',
131
+ 'об',
132
+ 'у',
133
+ 'для',
134
+ 'к',
135
+ 'ко',
136
+ 'из',
137
+ 'без',
138
+ 'при',
139
+ 'а',
140
+ 'но',
141
+ 'или',
142
+ 'да',
143
+ 'же',
144
+ 'ли',
145
+ 'бы',
146
+ 'не',
147
+ 'то',
148
+ 'же',
149
+ 'the',
150
+ 'of',
151
+ 'to',
152
+ 'in',
153
+ 'on',
154
+ 'at',
155
+ 'by',
156
+ 'for',
157
+ 'with',
158
+ 'from',
159
+ 'as',
160
+ 'an',
161
+ 'or',
162
+ 'but',
163
+ '&'
164
+ ];
165
+
166
+ function getRubricInitials(title: string): string {
167
+ if (!title) return '';
168
+ // Удаляем лишние символы
169
+ const clean = title.replace(/[^\wа-яА-ЯёЁ\s]/gi, ' ');
170
+ const words = clean.split(/\s+/).filter(Boolean);
171
+ // Берём первые буквы каждого слова, кроме стоп-слов
172
+ const initials = words
173
+ .filter((word) => !stopWords.includes(word.toLowerCase()))
174
+ .slice(0, 2)
175
+ .map((word) => word[0]?.toUpperCase() || '')
176
+ .join('');
177
+ return initials;
178
+ }
179
+
180
+ const rubricInitials = getRubricInitials(title);
117
181
 
118
182
  // Debug информация только в development режиме
119
183
  if (import.meta.env.DEV) {
120
184
  console.log('RubricCard Debug:', {
121
185
  title,
122
- originalImageSrc: imageSrc,
123
186
  previewImageSrc,
124
187
  defaultRubricImage: maugliConfig.defaultRubricImage
125
188
  });
@@ -131,8 +194,18 @@ if (import.meta.env.DEV) {
131
194
  class={`w-full h-[195px] border border-[var(--border-main)] rounded-custom card-bg hover:card-shadow hover:-translate-y-1 transition-all duration-300 p-6 flex flex-row gap-4 items-start ${className}`}
132
195
  >
133
196
  <!-- Левая часть: картинка и дата -->
134
- <div class="flex flex-col items-end gap-2 w-[105px] h-[147px]">
135
- <img src={previewImageSrc} alt={image?.alt || title} class="w-[105px] h-[107px] object-cover rounded-custom" loading="lazy" />
197
+ <div class="flex flex-col items-end gap-2 w-[105px] h-[147px] relative">
198
+ <img src={previewImageSrc} alt={title} class="w-[105px] h-[107px] object-cover rounded-custom" loading="lazy" />
199
+ {
200
+ rubricInitials && (
201
+ <span style="position:absolute;left:0;top:0;width:105px;height:107px;display:flex;align-items:center;justify-content:center;pointer-events:none;z-index:2;">
202
+ <span style="position:absolute;left:0;top:0;width:105px;height:107px;background:rgba(0,0,0,0.10);border-radius:inherit;z-index:1;" />
203
+ <span style="position:relative;z-index:2;font-size:48px;font-weight:700;font-family:inherit;color:var(--brand-color);letter-spacing:2px;">
204
+ {rubricInitials}
205
+ </span>
206
+ </span>
207
+ )
208
+ }
136
209
  <div class="flex flex-col items-end gap-1 w-[74px] h-[32px]">
137
210
  <span class={`flex items-center gap-1 text-[12px] text-right ${isBrandDate ? 'text-[var(--brand-color)]' : 'text-[var(--text-muted)]'}`}>
138
211
  <svg
@@ -1,9 +1,7 @@
1
1
  ---
2
2
  title: AI в бизнесе
3
3
  description: "Обзоры технологий (LLM, GPT, Claude и др.). Кейсы применения AI в бизнесе. Тренды в автоматизации контента."
4
- image:
5
- src: '/img/default/rubric_default.webp'
6
- alt: AI в бизнесе
4
+
7
5
  isRubric: true
8
6
  isFeatured: false
9
7
  jsonld:
@@ -1,9 +1,7 @@
1
1
  ---
2
2
  title: Автоматизация бизнеса
3
3
  description: "Workflow и интеграции (Airtable, Supabase, автопостинг). AI-редакторы и сценарии. «Редакция без людей» — практика и инструменты."
4
- image:
5
- src: '/img/default/rubric_default.webp'
6
- alt: Автоматизация бизнеса
4
+
7
5
  isRubric: true
8
6
  isFeatured: false
9
7
  jsonld:
@@ -1,9 +1,7 @@
1
1
  ---
2
2
  title: Контент-стратегии
3
3
  description: "Как строить Content Market Fit. Мультиязычные блоги. Принципы работы AI-редакции."
4
- image:
5
- src: '/img/default/rubric_default.webp'
6
- alt: Контент-стратегии
4
+
7
5
  isRubric: true
8
6
  isFeatured: false
9
7
  jsonld: