PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.7
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.7
2.0.13 2.0.12 2.0.11 2.0.10 2.0.9 trunk 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8
blockenberg / blocks / recipe-card / index.js

index.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.7, at blocks/recipe-card/index.js

397 lines 23.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 ( function () {
2 var el = window.wp.element.createElement;
3 var { registerBlockType } = window.wp.blocks;
4 var { InspectorControls, MediaUpload, MediaUploadCheck, PanelColorSettings, useBlockProps } = window.wp.blockEditor;
5 var { PanelBody, RangeControl, SelectControl, TextControl, TextareaControl, ToggleControl, Button } = window.wp.components;
6 var { __ } = window.wp.i18n;
7
8 var DIFFICULTIES = ['Easy','Medium','Hard'].map(v=>({label:v,value:v}));
9
10 var _tc; function getTypoControl() { return _tc || (_tc = window.bkbgTypographyControl); }
11 var _tv; function getTypoCssVars() { return _tv || (_tv = window.bkbgTypoCssVars); }
12
13 var v1Attributes = {
14 recipeName:{type:'string',default:'Classic Pancakes'},
15 description:{type:'string',default:'Fluffy, golden pancakes the whole family will love. Ready in 30 minutes.'},
16 imageUrl:{type:'string',default:''},
17 imageId:{type:'number',default:0},
18 prepTime:{type:'string',default:'10 min'},
19 cookTime:{type:'string',default:'20 min'},
20 totalTime:{type:'string',default:'30 min'},
21 servings:{type:'string',default:'4 servings'},
22 difficulty:{type:'string',default:'Easy'},
23 cuisine:{type:'string',default:'American'},
24 category:{type:'string',default:'Breakfast'},
25 ingredients:{type:'string',default:'1 cup all-purpose flour\n1 tbsp sugar\n1 tsp baking powder\n\u00bd tsp baking soda\n\u00bc tsp salt\n1 cup buttermilk\n1 egg\n2 tbsp melted butter'},
26 instructions:{type:'string',default:'Mix dry ingredients in a large bowl.\nWhisk wet ingredients separately.\nCombine wet and dry ingredients until just mixed.\nHeat a skillet over medium heat and grease lightly.\nPour \u00bc cup batter per pancake and cook until bubbles form.\nFlip and cook 1-2 more minutes until golden.'},
27 calories:{type:'string',default:'285'},
28 protein:{type:'string',default:'8g'},
29 carbs:{type:'string',default:'42g'},
30 fat:{type:'string',default:'9g'},
31 showNutrition:{type:'boolean',default:true},
32 showRating:{type:'boolean',default:true},
33 rating:{type:'number',default:5},
34 ratingCount:{type:'string',default:'24'},
35 notes:{type:'string',default:''},
36 accentColor:{type:'string',default:'#f59e0b'},
37 cardBg:{type:'string',default:'#ffffff'},
38 cardRadius:{type:'number',default:16},
39 cardShadow:{type:'boolean',default:true},
40 schemaEnabled:{type:'boolean',default:true},
41 titleFontSize:{type:'number',default:28},
42 titleFontWeight:{type:'number',default:800},
43 titleLineHeight:{type:'number',default:1.2},
44 bodyFontSize:{type:'number',default:15},
45 bodyFontWeight:{type:'number',default:400},
46 bodyLineHeight:{type:'number',default:1.6}
47 };
48
49 function Stars(rating, color) {
50 var stars = [];
51 for (var i=1; i<=5; i++) {
52 stars.push(el('span',{key:i,style:{color: i<=rating ? color : '#d1d5db',fontSize:'20px'}}, i<=rating ? '�
53 ' : ''));
54 }
55 return el('div',{style:{display:'flex',gap:'2px'}},stars);
56 }
57
58 function MetaBadge(icon, label, value, color) {
59 return el('div',{className:'bkrc2-meta',style:{display:'flex',flexDirection:'column',alignItems:'center',gap:'4px',padding:'12px 16px',background:'#f9fafb',borderRadius:'10px',flex:1,minWidth:'80px'}},
60 el('span',{className:'dashicons dashicons-'+icon,style:{color:color,fontSize:'22px',width:'22px',height:'22px',lineHeight:1}}),
61 el('span',{style:{fontSize:'11px',color:'#9ca3af',fontWeight:500,textTransform:'uppercase',letterSpacing:'0.5px'}},label),
62 el('span',{style:{fontWeight:700,fontSize:'14px',color:'#1f2937'}},value),
63 );
64 }
65
66 function RecipePreview(a) {
67 var acc = a.accentColor;
68 var ingredients = (a.ingredients||'').split('\n').filter(Boolean);
69 var steps = (a.instructions||'').split('\n').filter(Boolean);
70
71 return el('div',{className:'bkrc2-card',style:{
72 background:a.cardBg, borderRadius:a.cardRadius+'px',
73 boxShadow:a.cardShadow?'0 8px 40px rgba(0,0,0,0.10)':'none',
74 overflow:'hidden', maxWidth:'780px', width:'100%', margin:'0 auto',
75 }},
76
77 a.imageUrl && el('div',{className:'bkrc2-hero',style:{height:'280px',background:'url('+a.imageUrl+') center/cover no-repeat'}}),
78
79 el('div',{className:'bkrc2-body',style:{padding:'32px'}},
80
81 el('div',{style:{display:'flex',justifyContent:'space-between',alignItems:'flex-start',flexWrap:'wrap',gap:'12px',marginBottom:'12px'}},
82 el('h2',{className:'bkrc2-name',style:{margin:0,color:'#1f2937',flex:1}},a.recipeName),
83 a.difficulty && el('span',{style:{background:acc,color:'#fff',borderRadius:'20px',padding:'4px 14px',fontSize:'12px',fontWeight:700,flexShrink:0,alignSelf:'center'}},a.difficulty),
84 ),
85
86 a.showRating && el('div',{style:{display:'flex',alignItems:'center',gap:'8px',marginBottom:'12px'}},
87 Stars(a.rating||5, acc),
88 el('span',{style:{fontSize:'13px',color:'#6b7280'}},'('+a.ratingCount+' reviews)'),
89 ),
90
91 a.description && el('p',{className:'bkrc2-desc',style:{color:'#4b5563',margin:'0 0 24px'}},a.description),
92
93 el('div',{className:'bkrc2-meta-row',style:{display:'flex',gap:'8px',flexWrap:'wrap',marginBottom:'28px'}},
94 MetaBadge('clock','Prep',a.prepTime,acc),
95 MetaBadge('clock','Cook',a.cookTime,acc),
96 MetaBadge('backup','Total',a.totalTime,acc),
97 MetaBadge('groups','Serves',a.servings,acc),
98 ),
99
100 el('div',{className:'bkrc2-cols',style:{display:'grid',gridTemplateColumns:'1fr 1fr',gap:'32px',marginBottom:'24px'}},
101
102 el('div',{className:'bkrc2-ingredients'},
103 el('h3',{style:{fontSize:'17px',fontWeight:700,color:'#1f2937',margin:'0 0 14px',paddingBottom:'8px',borderBottom:'2px solid '+acc}},
104 el('span',{className:'dashicons dashicons-carrot',style:{color:acc,marginRight:'6px'}}),__('Ingredients')),
105 el('ul',{style:{margin:0,padding:'0 0 0 18px',listStyle:'disc',listStyleColor:acc}},
106 ingredients.map((ing,i)=>el('li',{key:i,style:{marginBottom:'6px',color:'#374151',lineHeight:1.5,fontSize:'14px'}},ing))
107 )
108 ),
109
110 el('div',{className:'bkrc2-instructions'},
111 el('h3',{style:{fontSize:'17px',fontWeight:700,color:'#1f2937',margin:'0 0 14px',paddingBottom:'8px',borderBottom:'2px solid '+acc}},
112 el('span',{className:'dashicons dashicons-list-view',style:{color:acc,marginRight:'6px'}}),__('Instructions')),
113 el('ol',{style:{margin:0,padding:'0 0 0 18px'}},
114 steps.map((step,i)=>el('li',{key:i,style:{marginBottom:'10px',color:'#374151',lineHeight:1.6,fontSize:'14px'}},step))
115 )
116 ),
117 ),
118
119 a.showNutrition && el('div',{className:'bkrc2-nutrition',style:{background:'#f9fafb',borderRadius:'10px',padding:'16px 20px',marginBottom:'16px'}},
120 el('h4',{style:{margin:'0 0 12px',fontSize:'14px',fontWeight:700,color:'#374151',textTransform:'uppercase',letterSpacing:'1px'}},__('Nutrition (per serving)')),
121 el('div',{style:{display:'flex',gap:'24px',flexWrap:'wrap'}},
122 [{l:'Calories',v:a.calories},{l:'Protein',v:a.protein},{l:'Carbs',v:a.carbs},{l:'Fat',v:a.fat}].map((n,i)=>
123 el('div',{key:i,style:{textAlign:'center'}},
124 el('div',{style:{fontSize:'20px',fontWeight:800,color:acc}},n.v),
125 el('div',{style:{fontSize:'11px',color:'#9ca3af',fontWeight:600,textTransform:'uppercase'}},n.l)
126 )
127 )
128 )
129 ),
130
131 a.notes && el('div',{style:{background:'#fef9ec',border:'1px solid #fde68a',borderRadius:'10px',padding:'14px 18px'}},
132 el('strong',{style:{fontSize:'13px',color:'#92400e'}},'📝 '+__('Notes')+': '),
133 el('span',{style:{fontSize:'14px',color:'#78350f'}},a.notes),
134 ),
135 )
136 );
137 }
138
139 registerBlockType('blockenberg/recipe-card', {
140 edit: function(props) {
141 var a = props.attributes;
142 var set = props.setAttributes;
143 var TC = getTypoControl();
144 var blockProps = useBlockProps((function() {
145 var _tvFn = getTypoCssVars();
146 var s = {};
147 if (_tvFn) {
148 Object.assign(s, _tvFn(a.titleTypo || {}, '--bkrc2-tt-'));
149 Object.assign(s, _tvFn(a.bodyTypo || {}, '--bkrc2-bt-'));
150 }
151 return { style: s };
152 })());
153 return el('div',blockProps,
154 el(InspectorControls,null,
155 el(PanelBody,{title:__('Basic Info'),initialOpen:true},
156 el(TextControl,{label:__('Recipe Name'),value:a.recipeName,onChange:v=>set({recipeName:v})}),
157 el(TextareaControl,{label:__('Description'),value:a.description,rows:3,onChange:v=>set({description:v})}),
158 el(SelectControl,{label:__('Difficulty'),value:a.difficulty,options:DIFFICULTIES,onChange:v=>set({difficulty:v})}),
159 el(TextControl,{label:__('Cuisine'),value:a.cuisine,onChange:v=>set({cuisine:v})}),
160 el(TextControl,{label:__('Category'),value:a.category,onChange:v=>set({category:v})}),
161 ),
162 el(PanelBody,{title:__('Typography','blockenberg'),initialOpen:false},
163 TC && el(TC, { label: __('Title', 'blockenberg'), value: a.titleTypo || {}, onChange: function(v) { set({ titleTypo: v }); } }),
164 TC && el(TC, { label: __('Body / Description', 'blockenberg'), value: a.bodyTypo || {}, onChange: function(v) { set({ bodyTypo: v }); } })
165 ),
166 el(PanelBody,{title:__('Photo'),initialOpen:false},
167 el(MediaUploadCheck,null,
168 el(MediaUpload,{
169 onSelect:m=>set({imageUrl:m.url,imageId:m.id}),
170 allowedTypes:['image'],value:a.imageId,
171 render:({open})=>el(Button,{onClick:open,variant:'secondary',style:{width:'100%',justifyContent:'center',marginBottom:'8px'}},
172 a.imageUrl?__('Change Image'):__('Select Hero Image'))
173 })
174 ),
175 a.imageUrl&&el(Button,{isDestructive:true,isSmall:true,onClick:()=>set({imageUrl:'',imageId:0})},__('Remove Image')),
176 ),
177 el(PanelBody,{title:__('Times & Servings'),initialOpen:false},
178 el(TextControl,{label:__('Prep Time'),value:a.prepTime,onChange:v=>set({prepTime:v})}),
179 el(TextControl,{label:__('Cook Time'),value:a.cookTime,onChange:v=>set({cookTime:v})}),
180 el(TextControl,{label:__('Total Time'),value:a.totalTime,onChange:v=>set({totalTime:v})}),
181 el(TextControl,{label:__('Servings'),value:a.servings,onChange:v=>set({servings:v})}),
182 ),
183 el(PanelBody,{title:__('Ingredients'),initialOpen:false},
184 el(TextareaControl,{label:__('One ingredient per line'),value:a.ingredients,rows:8,onChange:v=>set({ingredients:v})}),
185 ),
186 el(PanelBody,{title:__('Instructions'),initialOpen:false},
187 el(TextareaControl,{label:__('One step per line'),value:a.instructions,rows:8,onChange:v=>set({instructions:v})}),
188 ),
189 el(PanelBody,{title:__('Nutrition'),initialOpen:false},
190 el(ToggleControl,{label:__('Show Nutrition'),checked:a.showNutrition,onChange:v=>set({showNutrition:v}),__nextHasNoMarginBottom:true}),
191 el(TextControl,{label:__('Calories'),value:a.calories,onChange:v=>set({calories:v})}),
192 el(TextControl,{label:__('Protein'),value:a.protein,onChange:v=>set({protein:v})}),
193 el(TextControl,{label:__('Carbs'),value:a.carbs,onChange:v=>set({carbs:v})}),
194 el(TextControl,{label:__('Fat'),value:a.fat,onChange:v=>set({fat:v})}),
195 ),
196 el(PanelBody,{title:__('Rating'),initialOpen:false},
197 el(ToggleControl,{label:__('Show Rating'),checked:a.showRating,onChange:v=>set({showRating:v}),__nextHasNoMarginBottom:true}),
198 el(RangeControl,{label:__('Star Rating (1-5)'),value:a.rating,min:1,max:5,onChange:v=>set({rating:v})}),
199 el(TextControl,{label:__('Review Count'),value:a.ratingCount,onChange:v=>set({ratingCount:v})}),
200 ),
201 el(PanelBody,{title:__('Notes'),initialOpen:false},
202 el(TextareaControl,{label:__('Chef Notes (optional)'),value:a.notes,rows:3,onChange:v=>set({notes:v})}),
203 ),
204 el(PanelBody,{title:__('Style'),initialOpen:false},
205 el(RangeControl,{label:__('Card Radius (px)'),value:a.cardRadius,min:0,max:32,onChange:v=>set({cardRadius:v})}),
206 el(ToggleControl,{label:__('Card Shadow'),checked:a.cardShadow,onChange:v=>set({cardShadow:v}),__nextHasNoMarginBottom:true}),
207 el(ToggleControl,{label:__('Schema.org Markup'),checked:a.schemaEnabled,onChange:v=>set({schemaEnabled:v}),__nextHasNoMarginBottom:true}),
208 ),
209 el(PanelColorSettings,{title:__('Colors'),initialOpen:false,colorSettings:[
210 {label:__('Accent Color'),value:a.accentColor,onChange:v=>set({accentColor:v||'#f59e0b'})},
211 {label:__('Card Background'),value:a.cardBg,onChange:v=>set({cardBg:v||'#ffffff'})},
212 ]}),
213 ),
214 RecipePreview(a),
215 );
216 },
217
218 save: function({attributes:a}) {
219 var acc = a.accentColor;
220 var ingredients = (a.ingredients||'').split('\n').filter(Boolean);
221 var steps = (a.instructions||'').split('\n').filter(Boolean);
222 var _tvFn = window.bkbgTypoCssVars;
223 var wrapStyle = {};
224 if (_tvFn) {
225 Object.assign(wrapStyle, _tvFn(a.titleTypo || {}, '--bkrc2-tt-'));
226 Object.assign(wrapStyle, _tvFn(a.bodyTypo || {}, '--bkrc2-bt-'));
227 }
228
229 return el('div',{
230 className:'bkrc2-wrap',
231 style: wrapStyle,
232 'data-schema': a.schemaEnabled ? '1' : '0',
233 'data-recipe': JSON.stringify({
234 name:a.recipeName,description:a.description,
235 prepTime:a.prepTime,cookTime:a.cookTime,totalTime:a.totalTime,
236 servings:a.servings,cuisine:a.cuisine,category:a.category,
237 calories:a.calories,ingredients:ingredients,steps:steps,
238 rating:a.rating,ratingCount:a.ratingCount,image:a.imageUrl,
239 }),
240 },
241 el('div',{className:'bkrc2-card',style:{
242 background:a.cardBg, borderRadius:a.cardRadius+'px',
243 boxShadow:a.cardShadow?'0 8px 40px rgba(0,0,0,0.10)':'none',
244 overflow:'hidden', maxWidth:'780px', width:'100%', margin:'0 auto',
245 }},
246 a.imageUrl&&el('div',{className:'bkrc2-hero',style:{height:'280px',background:'url('+a.imageUrl+') center/cover no-repeat'}}),
247
248 el('div',{className:'bkrc2-body',style:{padding:'32px'}},
249 el('div',{style:{display:'flex',justifyContent:'space-between',alignItems:'flex-start',flexWrap:'wrap',gap:'12px',marginBottom:'12px'}},
250 el('h2',{className:'bkrc2-name',style:{margin:0,color:'#1f2937',flex:1}},a.recipeName),
251 a.difficulty&&el('span',{style:{background:acc,color:'#fff',borderRadius:'20px',padding:'4px 14px',fontSize:'12px',fontWeight:700}},a.difficulty),
252 ),
253
254 a.showRating&&el('div',{style:{display:'flex',alignItems:'center',gap:'8px',marginBottom:'12px'}},
255 el('span',{className:'bkrc2-stars','data-rating':a.rating,style:{color:acc,fontSize:'20px',letterSpacing:'2px'}},
256 '�
257 '.repeat(a.rating)+''.repeat(5-a.rating)),
258 el('span',{style:{fontSize:'13px',color:'#6b7280'}},'('+a.ratingCount+' reviews)'),
259 ),
260
261 a.description&&el('p',{className:'bkrc2-desc',style:{color:'#4b5563',margin:'0 0 24px'}},a.description),
262
263 el('div',{className:'bkrc2-meta-row',style:{display:'flex',gap:'8px',flexWrap:'wrap',marginBottom:'28px'}},
264 [{icon:'clock',label:'Prep',val:a.prepTime},{icon:'clock',label:'Cook',val:a.cookTime},{icon:'backup',label:'Total',val:a.totalTime},{icon:'groups',label:'Serves',val:a.servings}]
265 .map((m,i)=>el('div',{key:i,className:'bkrc2-meta',style:{display:'flex',flexDirection:'column',alignItems:'center',gap:'4px',padding:'12px 16px',background:'#f9fafb',borderRadius:'10px',flex:1,minWidth:'80px'}},
266 el('span',{className:'dashicons dashicons-'+m.icon,style:{color:acc,fontSize:'22px',width:'22px',height:'22px',lineHeight:1}}),
267 el('span',{style:{fontSize:'11px',color:'#9ca3af',fontWeight:500,textTransform:'uppercase',letterSpacing:'0.5px'}},m.label),
268 el('span',{style:{fontWeight:700,fontSize:'14px',color:'#1f2937'}},m.val),
269 ))
270 ),
271
272 el('div',{style:{display:'grid',gridTemplateColumns:'1fr 1fr',gap:'32px',marginBottom:'24px'}},
273 el('div',null,
274 el('h3',{style:{fontSize:'17px',fontWeight:700,color:'#1f2937',margin:'0 0 14px',paddingBottom:'8px',borderBottom:'2px solid '+acc}},'Ingredients'),
275 el('ul',{style:{margin:0,padding:'0 0 0 18px'}},
276 ingredients.map((ing,i)=>el('li',{key:i,style:{marginBottom:'6px',color:'#374151',lineHeight:1.5,fontSize:'14px'}},ing))
277 )
278 ),
279 el('div',null,
280 el('h3',{style:{fontSize:'17px',fontWeight:700,color:'#1f2937',margin:'0 0 14px',paddingBottom:'8px',borderBottom:'2px solid '+acc}},'Instructions'),
281 el('ol',{style:{margin:0,padding:'0 0 0 18px'}},
282 steps.map((step,i)=>el('li',{key:i,style:{marginBottom:'10px',color:'#374151',lineHeight:1.6,fontSize:'14px'}},step))
283 )
284 ),
285 ),
286
287 a.showNutrition&&el('div',{style:{background:'#f9fafb',borderRadius:'10px',padding:'16px 20px',marginBottom:'16px'}},
288 el('h4',{style:{margin:'0 0 12px',fontSize:'14px',fontWeight:700,color:'#374151',textTransform:'uppercase',letterSpacing:'1px'}},'Nutrition (per serving)'),
289 el('div',{style:{display:'flex',gap:'24px',flexWrap:'wrap'}},
290 [{l:'Calories',v:a.calories},{l:'Protein',v:a.protein},{l:'Carbs',v:a.carbs},{l:'Fat',v:a.fat}].map((n,i)=>
291 el('div',{key:i,style:{textAlign:'center'}},
292 el('div',{style:{fontSize:'20px',fontWeight:800,color:acc}},n.v),
293 el('div',{style:{fontSize:'11px',color:'#9ca3af',fontWeight:600,textTransform:'uppercase'}},n.l)
294 )
295 )
296 )
297 ),
298
299 a.notes&&el('div',{style:{background:'#fef9ec',border:'1px solid #fde68a',borderRadius:'10px',padding:'14px 18px'}},
300 el('strong',{style:{fontSize:'13px',color:'#92400e'}},'📝 Notes: '),
301 el('span',{style:{fontSize:'14px',color:'#78350f'}},a.notes),
302 ),
303 )
304 )
305 );
306 },
307
308 deprecated: [
309 {
310 attributes: v1Attributes,
311 save: function({attributes:a}) {
312 var acc = a.accentColor;
313 var ingredients = (a.ingredients||'').split('\n').filter(Boolean);
314 var steps = (a.instructions||'').split('\n').filter(Boolean);
315
316 return el('div',{
317 className:'bkrc2-wrap',
318 'data-schema': a.schemaEnabled ? '1' : '0',
319 'data-recipe': JSON.stringify({
320 name:a.recipeName,description:a.description,
321 prepTime:a.prepTime,cookTime:a.cookTime,totalTime:a.totalTime,
322 servings:a.servings,cuisine:a.cuisine,category:a.category,
323 calories:a.calories,ingredients:ingredients,steps:steps,
324 rating:a.rating,ratingCount:a.ratingCount,image:a.imageUrl,
325 }),
326 },
327 el('div',{className:'bkrc2-card',style:{
328 background:a.cardBg, borderRadius:a.cardRadius+'px',
329 boxShadow:a.cardShadow?'0 8px 40px rgba(0,0,0,0.10)':'none',
330 overflow:'hidden', maxWidth:'780px', width:'100%', margin:'0 auto',
331 }},
332 a.imageUrl&&el('div',{className:'bkrc2-hero',style:{height:'280px',background:'url('+a.imageUrl+') center/cover no-repeat'}}),
333
334 el('div',{className:'bkrc2-body',style:{padding:'32px'}},
335 el('div',{style:{display:'flex',justifyContent:'space-between',alignItems:'flex-start',flexWrap:'wrap',gap:'12px',marginBottom:'12px'}},
336 el('h2',{className:'bkrc2-name',style:{margin:0,fontSize:'28px',fontWeight:800,color:'#1f2937',flex:1}},a.recipeName),
337 a.difficulty&&el('span',{style:{background:acc,color:'#fff',borderRadius:'20px',padding:'4px 14px',fontSize:'12px',fontWeight:700}},a.difficulty),
338 ),
339
340 a.showRating&&el('div',{style:{display:'flex',alignItems:'center',gap:'8px',marginBottom:'12px'}},
341 el('span',{className:'bkrc2-stars','data-rating':a.rating,style:{color:acc,fontSize:'20px',letterSpacing:'2px'}},
342 '�
343 '.repeat(a.rating)+''.repeat(5-a.rating)),
344 el('span',{style:{fontSize:'13px',color:'#6b7280'}},'('+a.ratingCount+' reviews)'),
345 ),
346
347 a.description&&el('p',{style:{color:'#4b5563',lineHeight:1.6,margin:'0 0 24px',fontSize:'15px'}},a.description),
348
349 el('div',{className:'bkrc2-meta-row',style:{display:'flex',gap:'8px',flexWrap:'wrap',marginBottom:'28px'}},
350 [{icon:'clock',label:'Prep',val:a.prepTime},{icon:'clock',label:'Cook',val:a.cookTime},{icon:'backup',label:'Total',val:a.totalTime},{icon:'groups',label:'Serves',val:a.servings}]
351 .map((m,i)=>el('div',{key:i,className:'bkrc2-meta',style:{display:'flex',flexDirection:'column',alignItems:'center',gap:'4px',padding:'12px 16px',background:'#f9fafb',borderRadius:'10px',flex:1,minWidth:'80px'}},
352 el('span',{className:'dashicons dashicons-'+m.icon,style:{color:acc,fontSize:'22px',width:'22px',height:'22px',lineHeight:1}}),
353 el('span',{style:{fontSize:'11px',color:'#9ca3af',fontWeight:500,textTransform:'uppercase',letterSpacing:'0.5px'}},m.label),
354 el('span',{style:{fontWeight:700,fontSize:'14px',color:'#1f2937'}},m.val),
355 ))
356 ),
357
358 el('div',{style:{display:'grid',gridTemplateColumns:'1fr 1fr',gap:'32px',marginBottom:'24px'}},
359 el('div',null,
360 el('h3',{style:{fontSize:'17px',fontWeight:700,color:'#1f2937',margin:'0 0 14px',paddingBottom:'8px',borderBottom:'2px solid '+acc}},'Ingredients'),
361 el('ul',{style:{margin:0,padding:'0 0 0 18px'}},
362 ingredients.map((ing,i)=>el('li',{key:i,style:{marginBottom:'6px',color:'#374151',lineHeight:1.5,fontSize:'14px'}},ing))
363 )
364 ),
365 el('div',null,
366 el('h3',{style:{fontSize:'17px',fontWeight:700,color:'#1f2937',margin:'0 0 14px',paddingBottom:'8px',borderBottom:'2px solid '+acc}},'Instructions'),
367 el('ol',{style:{margin:0,padding:'0 0 0 18px'}},
368 steps.map((step,i)=>el('li',{key:i,style:{marginBottom:'10px',color:'#374151',lineHeight:1.6,fontSize:'14px'}},step))
369 )
370 ),
371 ),
372
373 a.showNutrition&&el('div',{style:{background:'#f9fafb',borderRadius:'10px',padding:'16px 20px',marginBottom:'16px'}},
374 el('h4',{style:{margin:'0 0 12px',fontSize:'14px',fontWeight:700,color:'#374151',textTransform:'uppercase',letterSpacing:'1px'}},'Nutrition (per serving)'),
375 el('div',{style:{display:'flex',gap:'24px',flexWrap:'wrap'}},
376 [{l:'Calories',v:a.calories},{l:'Protein',v:a.protein},{l:'Carbs',v:a.carbs},{l:'Fat',v:a.fat}].map((n,i)=>
377 el('div',{key:i,style:{textAlign:'center'}},
378 el('div',{style:{fontSize:'20px',fontWeight:800,color:acc}},n.v),
379 el('div',{style:{fontSize:'11px',color:'#9ca3af',fontWeight:600,textTransform:'uppercase'}},n.l)
380 )
381 )
382 )
383 ),
384
385 a.notes&&el('div',{style:{background:'#fef9ec',border:'1px solid #fde68a',borderRadius:'10px',padding:'14px 18px'}},
386 el('strong',{style:{fontSize:'13px',color:'#92400e'}},'📝 Notes: '),
387 el('span',{style:{fontSize:'14px',color:'#78350f'}},a.notes),
388 ),
389 )
390 )
391 );
392 }
393 }
394 ]
395 });
396 }() );
397