{
 "que_es": "Spec machine-readable de los 41 módulos de presentación de Magoya. El deck kit navegable (con export .pptx) vive en slides.html — esta es la receta para que una AI reconstruya cualquier módulo.",
 "si_tu_fetch_trunca": "Este archivo es grande (~86KB). Si tu fetch llega cortado o resumido, usa los archivos por familia (2-10KB, mismo formato): https://brand.magoya.com/ai/slides/A.json hasta https://brand.magoya.com/ai/slides/M.json — una familia por archivo, con layout_src completo por modulo.",
 "lienzo": {
  "ancho_px": 1920,
  "alto_px": 1080,
  "margen_interior": "7%",
  "fondos": [
   "blanco #FFFFFF",
   "sage #EFF3EE",
   "oscuro #133825 (solo apertura/cierre/citas)"
  ],
  "escala_tipografica_pt": [
   126,
   84,
   56,
   42
  ],
  "conversion": "1pt = 1.333px sobre el lienzo de 1920x1080 (126pt = 168px). La unidad s del DSL se convierte a pt en la funcion paint() incluida en dsl_src.",
  "reglas": [
   "un golpe de lima #A2FF00 por slide como máximo",
   "máximo dos recursos gráficos además de la tipografía",
   "wordmark chico arriba-izquierda en slides interiores"
  ]
 },
 "layouts": {
  "como_leer": "Cada modulo trae layout_src: la funcion JS literal del exportador .pptx con la geometria exacta. Coordenadas en % de un lienzo de 100 de ancho x 56.25 de alto (16:9). Helpers: T(texto,{x,y,w,h,s,b,c,al,lh,...})=texto, IMG({src,x,y,w,h,fit,...})=imagen (src relativo a la raiz del sitio), R(...)=rectangulo, bg(fill)=fondo full-bleed, chrome(pg,dark)=wordmark chico arriba-izquierda + numero de pagina. Constantes de color y conversion de unidades: ver dsl_src (la funcion paint() muestra como s se convierte a puntos).",
  "dsl_src": "var C={w:'FFFFFF',ink:'161616',g950:'0C2117',g900:'133825',g800:'1A4A31',lime:'A2FF00',\n  em5:'00DE68',em7:'009145',cr50:'F6F1EB',cr100:'ECE3DB',cr200:'DCD0C4',cr300:'C4B5A6',\n  sage:'EEF2EC',g700:'235F40',g800:'222222',g600:'666666',g400:'AAAAAA',g300:'D0D0D0',g200:'DFDFDF',g100:'EFEFEF',hair:'E7E7E2'};\nvar A='assets/';\nvar WMB=A+'magoya-wordmark-black.svg', WMC=A+'magoya-wordmark-cream.svg';\nvar AG=A+'studio/icons/agro/', AI=A+'studio/icons/ai/', CL=A+'logos/clients/', PT=A+'logos/partners/', PH=A+'photos/';\n\nfunction R(o){o.k='r';return o;}\nfunction T(text,o){o=o||{};o.k='t';o.text=text;return o;}\nfunction IMG(o){o.k='i';return o;}\nfunction CH(o){o.k='c';return o;}\nfunction bg(fill){return R({x:0,y:0,w:100,h:56.25,fill:fill});}\n/* barra superior de slide de contenido + número */\nfunction chrome(pg,dark,x){\n  x=(x===undefined)?7.5:x;\n  return [IMG({src:dark?WMC:WMB,x:x,y:3.2,w:11,h:3.007}),\n          T(pg,{x:76.5,y:3.5,w:16,h:2.2,s:1.15,b:true,c:dark?C.cr300:C.g400,al:'right',cs:1.1})];\n}\n/* label + valor de stat */\nfunction stat(x,y,val,desc,size,c,dc,wd){\n  return [T(val,{x:x,y:y,w:wd||24,h:size*0.9,s:size,b:true,c:c||C.ink,tight:true,lh:.95}),\n          T(desc,{x:x,y:y+size*0.92,w:wd||24,h:6,s:1.4,c:dc||C.g600,lh:1.25})];\n}\nfunction rule(x,y,w){return R({x:x,y:y,w:w||14,h:.8,fill:C.lime,radius:.4});}\nfunction chip(x,y,text,col,w){\n  return [R({x:x,y:y,w:w,h:3.1,fill:null,line:col,lw:.85,radius:1.55}),\n          T(text,{x:x,y:y,w:w,h:3.1,s:1.25,b:true,c:col,al:'center',va:'middle'})];\n}\n\n/* ---------- 5. carga y rasterizado de assets ---------- */\nvar cache={};\nfunction fetchText(u){return fetch(u).then(function(r){if(!r.ok)throw new Error(u);return r.text();});}\nfunction blobToDataURL(b){return new Promise(function(res,rej){var f=new FileReader();\n  f.onload=function(){res(f.result);};f.onerror=rej;f.readAsDataURL(b);});}\nfunction rasterize(url,w,h,gray,mime){\n  return new Promise(function(res,rej){\n    var im=new Image();\n    im.onload=function(){\n      var cv=document.createElement('canvas');cv.width=w;cv.height=h;\n      var cx=cv.getContext('2d');\n      if(mime==='image/jpeg'){cx.fillStyle='#FFFFFF';cx.fillRect(0,0,w,h);}\n      cx.drawImage(im,0,0,w,h);\n      if(gray){try{var d=cx.getImageData(0,0,w,h),p=d.data;\n        for(var i=0;i<p.length;i+=4){var l=0.299*p[i]+0.587*p[i+1]+0.114*p[i+2];p[i]=p[i+1]=p[i+2]=l;}\n        cx.putImageData(d,0,0);}catch(e){}}\n      res(mime==='image/jpeg'?cv.toDataURL('image/jpeg',0.86):cv.toDataURL('image/png'));\n    };\n    im.onerror=function(){rej(new Error('img '+url));};\n    im.src=url;\n  });\n}\n/* ancho de rasterizado según el tamaño real en el slide (200 ppi) */\nfunction pxFor(cqw){return Math.max(140,Math.min(1500,Math.round((cqw||10)*U*200)));}\n/* svg → png (permite teñir currentColor / swap de hex) */\nfunction svgPng(src,opt){\n  opt=opt||{};\n  var px=pxFor(opt.w);\n  return fetchText(src).then(function(t){\n    if(opt.tint)t=t.replace(/currentColor/g,opt.tint);\n    if(opt.swap)opt.swap.forEach(function(p){t=t.split(p[0]).join(p[1]);});\n    var vb=/viewBox=\"([\\d.\\-\\s]+)\"/.exec(t), ar=1;\n    if(vb){var n=vb[1].trim().split(/\\s+/).map(Number);if(n[2]&&n[3])ar=n[3]/n[2];}\n    t=t.replace(/<svg([^>]*)>/,function(m,at){\n      at=at.replace(/\\s(width|height)=\"[^\"]*\"/g,'');\n      return '<svg'+at+' width=\"'+px+'\" height=\"'+Math.round(px*ar)+'\">';\n    });\n    var url='data:image/svg+xml;charset=utf-8,'+encodeURIComponent(t);\n    return rasterize(url,px,Math.round(px*ar),opt.gray);\n  });\n}\nfunction asset(src,opt){\n  opt=opt||{};\n  var px=pxFor(opt.w);\n  var key=src+'|'+(opt.tint||'')+'|'+(opt.gray?'g':'')+'|'+px+'|'+(opt.swap?JSON.stringify(opt.swap):'');\n  if(cache[key])return cache[key];\n  var p;\n  if(/\\.svg$/i.test(src)) p=svgPng(src,opt);\n  else p=fetch(src).then(function(r){if(!r.ok)throw new Error(src);return r.blob();}).then(blobToDataURL)\n      .then(function(d){return new Promise(function(res,rej){var im=new Image();\n        im.onload=function(){\n          var w=Math.min(im.naturalWidth,px*2);\n          res(rasterize(d,w,Math.round(w*im.naturalHeight/im.naturalWidth),opt.gray,'image/jpeg'));};\n        im.onerror=rej;im.src=d;});});\n  p=p.catch(function(e){console.warn('[deck-kit] asset omitido:',src,e.message);return null;});\n  cache[key]=p;return p;\n}\n\n/* ---------- 6. render de un spec a una slide del pptx ----------\n   Las imágenes se precargan ANTES de pintar para que el orden del array\n   sea el orden z real (scrims y paños quedan detrás del texto). */\nfunction paint(pptx,slide,shapes){\n  shapes=shapes.filter(Boolean);\n  var imgs=shapes.filter(function(s){return s.k==='i';});\n  return Promise.all(imgs.map(function(s){return asset(s.src,s);})).then(function(data){\n    var map={};imgs.forEach(function(s,i){map[i]=data[i];s._ix=i;});\n    shapes.forEach(function(s){\n      if(s.k==='r'){\n        slide.addShape(s.radius?pptx.ShapeType.roundRect:pptx.ShapeType.rect,{\n          x:IN(s.x),y:IN(s.y),w:IN(s.w),h:IN(s.h),\n          fill:s.fill?(s.alpha!==undefined?{color:s.fill,transparency:s.alpha}:{color:s.fill}):{type:'none'},\n          line:s.line?{color:s.line,width:s.lw||1}:{type:'none'},\n          rectRadius:s.radius?IN(s.radius):0});\n      } else if(s.k==='t'){\n        var size=s.s||1.75;\n        slide.addText(s.text,{x:IN(s.x),y:IN(s.y),w:IN(s.w),h:IN(s.h||5),\n          fontFace:'Manrope',fontSize:FS(size),bold:!!s.b,color:s.c||C.ink,\n          align:s.al||'left',valign:s.va||'top',\n          charSpacing:s.cs!==undefined?s.cs:(s.tight?-(FS(size)*0.03):0),\n          lineSpacingMultiple:s.lh||1.2,margin:0,isTextBox:true});\n      } else if(s.k==='i'){\n        var d=map[s._ix];if(!d)return;\n        var o={data:d,x:IN(s.x),y:IN(s.y),w:IN(s.w),h:IN(s.h)};\n        if(s.fit)o.sizing={type:s.fit,w:IN(s.w),h:IN(s.h)};\n        slide.addImage(o);\n      } else if(s.k==='c'){\n        slide.addChart(s.type,s.data,Object.assign({\n          x:IN(s.x),y:IN(s.y),w:IN(s.w),h:IN(s.h),\n          showLegend:false,showTitle:false,showValue:false,\n          catAxisLabelFontFace:'Manrope',catAxisLabelFontSize:11,catAxisLabelColor:C.g600,\n          valAxisHidden:true,catAxisLineShow:false,valGridLine:{style:'none'},\n          chartArea:{fill:{type:'none'}},plotArea:{fill:{type:'none'}}},s.opts||{}));\n      } else if(s.k==='tb'){\n        slide.addTable(s.rows,Object.assign({\n          x:IN(s.x),y:IN(s.y),w:IN(s.w),fontFace:'Manrope',fontSize:FS(1.5),\n          color:C.ink,valign:'middle',autoPage:false},s.opts||{}));\n      }\n    });\n  });\n}\n\n/* ---------- 7. helpers de composición ---------- */\nfunction rowsBlock(x,y,w,items,hl,numC){\n  var out=[],rh=6.2;\n  items.forEach(function(it,i){\n    var yy=y+i*rh;\n    if(i===hl)out.push(R({x:x,y:yy,w:w,h:rh-.5,fill:C.lime,radius:.7}));\n    else out.push(R({x:x,y:yy+rh-.55,w:w,h:.12,fill:C.hair}));\n    out.push(T(it.n,{x:x+1.2,y:yy+1.4,w:6.5,h:3,s:2.2,b:true,c:(i===hl)?C.ink:(numC||C.ink)}));\n    out.push(T(it.t,{x:x+8.5,y:yy+1.7,w:w-10,h:4,s:1.6,b:i===hl,lh:1.2}));\n  });\n  return out;\n}\nfunction timeline(x,y,w,steps,on){\n  var out=[R({x:x+1,y:y+.68,w:w-3,h:.18,fill:C.g300})],sw=w/steps.length;\n  steps.forEach(function(s,i){\n    var sx=x+i*sw;\n    out.push(R({x:sx,y:y,w:1.5,h:1.5,fill:(i===on)?C.lime:C.g900,radius:.75}));\n    out.push(T(s.b,{x:sx,y:y+2.5,w:sw-2,h:2.4,s:1.5,b:true,lh:1.1}));\n    out.push(T(s.s,{x:sx,y:y+4.9,w:sw-2,h:4.5,s:1.25,c:C.g600,lh:1.25}));\n  });\n  return out;\n}\nfunction card(x,y,w,h,fill,line){return R({x:x,y:y,w:w,h:h,fill:fill,line:line,lw:.75,radius:1.4});}\nfunction iconDot(x,y,d,ic,lime){\n  return [R({x:x,y:y,w:d,h:d,fill:lime?C.lime:C.ink,radius:d/2}),\n          IMG({src:AG+ic,x:x+d*0.28,y:y+d*0.28,w:d*0.44,h:d*0.44,tint:lime?'#161616':'#F6F1EB'})];\n}\nfunction checkLine(x,y,w,t){\n  return [T('→',{x:x,y:y,w:3,h:2.6,s:1.6,b:true,c:C.em7}),\n          T(t,{x:x+2.6,y:y,w:w-2.6,h:4,s:1.55,lh:1.25})];\n}\nfunction logoRow(list,x,y,w,h,cols,gapx,gapy){\n  var out=[],cw=(w-gapx*(cols-1))/cols;\n  list.forEach(function(src,i){\n    var c=i%cols,r=Math.floor(i/cols);\n    out.push(IMG({src:src,x:x+c*(cw+gapx),y:y+r*(h+gapy),w:cw,h:h,fit:'contain',gray:true}));\n  });\n  return out;\n}\n\n/* ---------- 8. specs de los 41 módulos ---------- */\nvar SPEC={};\n\n/* --- A · apertura --- */\nSPEC.A1=function(){return [bg(C.w),\n  T('PRODUCT STRATEGY',{x:7.5,y:8,w:60,h:2.6,s:1.5,b:true,c:C.em7,cs:1.8}),\n  T('AgTech challenges\\ndemand more than code.',{x:7.5,y:13,w:85,h:26,s:8.2,b:true,tight:true,lh:1.02}),\n  R({x:7.5,y:38.6,w:47,h:.85,fill:C.em5,radius:.42})];};\n\nSPEC.A2=function(p){return [bg(C.w)].concat(chrome(p),[\n  T('Embedded teams,\\nnot outsourced tickets.',{x:7.5,y:13,w:44,h:22,s:5.6,b:true,tight:true,lh:1.05}),\n  T('Magoya blends product strategy, engineering and agronomy in one senior pod that works inside your process — same rituals, same backlog, same accountability.',\n    {x:55,y:14,w:37.5,h:20,s:1.75,c:C.g800,lh:1.5})]);};\n\nSPEC.A3=function(p){return [bg(C.w)].concat(chrome(p),[\n  T('Agenda',{x:7.5,y:13,w:34,h:8,s:5.6,b:true,tight:true}),\n  T('45 minutes · 5 blocks',{x:7.5,y:22.5,w:30,h:3,s:1.45,c:C.g600})],\n  rowsBlock(44,12.5,48.5,[{n:'01',t:'Who we are — and how we embed'},{n:'02',t:\"What we've built in AgTech\"},\n    {n:'03',t:'The Magoya method'},{n:'04',t:'Investment scenarios'},{n:'05',t:'Next steps'}],1,C.em7));};\n\nSPEC.A4=function(){return [bg(C.g950),\n  IMG({src:A+'motif-semis.svg',x:0,y:41.25,w:100,h:15,fit:'cover',swap:[['#00DE68','#ECE3DB']]}),\n  IMG({src:WMC,x:7.5,y:7,w:11,h:3.007}),\n  T('02',{x:7.5,y:14,w:30,h:12,s:12,b:true,c:C.lime,tight:true,lh:.9}),\n  T(\"What we've built\\nin AgTech\",{x:7.5,y:26,w:60,h:13,s:5.6,b:true,c:C.cr50,tight:true,lh:1.05})];};\n\nSPEC.A5=function(p){return [bg(C.sage)].concat(chrome(p),[\n  T('REMOTE SENSING',{x:7.5,y:13,w:50,h:2.6,s:1.5,b:true,c:C.em7,cs:1.8}),\n  T('Satellite data that reaches the agronomist, not the archive.',{x:7.5,y:17.5,w:50,h:18,s:4.8,b:true,tight:true,lh:1.08}),\n  rule(7.5,37.5,14),\n  IMG({src:AG+'satelite.svg',x:63.5,y:15,w:26,h:26,tint:'#161616'})]);};\n\n/* --- B · servicios --- */\nSPEC.B1=function(p){\n  var s=[bg(C.sage)].concat(chrome(p),[T('How we partner',{x:7.5,y:11.5,w:60,h:7,s:4.6,b:true,tight:true})]);\n  var d=[{i:'semilla.svg',h:'Product Development',p:'A dedicated team owns the full lifecycle — discovery, prototyping, MVP and scaling.',l:0},\n         {i:'chat-ia.svg',h:'Team Extension',p:'We split responsibilities inside your product process — embedded, not outsourced.',l:1},\n         {i:'grafico.svg',h:'Staff Augmentation',p:'Senior talent on your products, under your processes and daily management.',l:0}];\n  d.forEach(function(c,i){var x=7.5+i*29,y=21,w=27,h=27;\n    s.push(card(x,y,w,h,C.w,C.hair));\n    s=s.concat(iconDot(x+2.2,y+2.2,4.4,c.i,c.l));\n    s.push(T(c.h,{x:x+2.2,y:y+8.4,w:w-4.4,h:5,s:2.1,b:true,tight:true,lh:1.05}));\n    s.push(T(c.p,{x:x+2.2,y:y+13.6,w:w-4.4,h:9,s:1.4,c:C.g600,lh:1.35}));\n    s.push(T('Learn more ↗',{x:x+2.2,y:y+h-4,w:w-4.4,h:2.6,s:1.4,b:true}));});\n  return s;};\n\nSPEC.B2=function(p){\n  var s=[bg(C.w)].concat(chrome(p),[T('Engagement models',{x:7.5,y:11.5,w:70,h:7,s:4.4,b:true,tight:true})]);\n  var d=[{h:'Product Development',a:'How it works: we assemble every role needed and own the process end to end.',b:'Best for: building a product from discovery to launch.',f:'Fixed scope · milestone billing',dk:0},\n         {h:'Team Extension',a:'How it works: shared responsibilities inside your product development process.',b:'Best for: scaling an existing team with AgTech fluency.',f:'Monthly per role · 3-month cycles',dk:1},\n         {h:'Staff Augmentation',a:'How it works: we provide the talent; you keep your processes and management.',b:'Best for: filling senior roles fast, without hiring overhead.',f:'Monthly per role · your PM',dk:0}];\n  d.forEach(function(c,i){var x=7.5+i*29,y=20.5,w=27,h=28.5;\n    s.push(card(x,y,w,h,c.dk?C.g900:C.sage,null));\n    s.push(T(c.h,{x:x+2.2,y:y+2.2,w:w-4.4,h:5,s:2.1,b:true,tight:true,c:c.dk?C.cr50:C.ink,lh:1.05}));\n    s.push(T(c.a,{x:x+2.2,y:y+8,w:w-4.4,h:8,s:1.4,c:c.dk?C.cr200:C.g600,lh:1.35}));\n    s.push(T(c.b,{x:x+2.2,y:y+15.5,w:w-4.4,h:7,s:1.4,c:c.dk?C.cr200:C.g600,lh:1.35}));\n    s.push(R({x:x+2.2,y:y+h-6,w:w-4.4,h:.1,fill:c.dk?C.g700:C.hair}));\n    s.push(T(c.f,{x:x+2.2,y:y+h-4.6,w:w-4.4,h:3,s:1.5,b:true,c:c.dk?C.lime:C.ink}));});\n  return s;};\n\nSPEC.B3=function(p){\n  var s=[bg(C.sage)].concat(chrome(p),[T('What the pod covers',{x:7.5,y:11.5,w:70,h:7,s:4.4,b:true,tight:true})]);\n  var d=[['escaneo.svg','Discovery','Field immersion with growers and agronomists.',0],\n         ['lote.svg','Product design','Flows built for gloves, dust and low signal.',0],\n         ['chat-ia.svg','Data & AI','Models and copilots on agronomic data.',1],\n         ['satelite.svg','Platform engineering','APIs, pipelines and cloud that hold a season.',0],\n         ['hoja.svg','Agronomy','Agronomists in the pod, not on call.',0],\n         ['tractor.svg','Field validation','Every release tested on real operations.',0]];\n  d.forEach(function(c,i){var col=i%3,row=Math.floor(i/3),x=7.5+col*29.5,y=21+row*13.5;\n    s=s.concat(iconDot(x,y,3.6,c[0],c[3]));\n    s.push(T(c[1],{x:x+5,y:y+.2,w:23,h:3,s:1.75,b:true,tight:true}));\n    s.push(T(c[2],{x:x+5,y:y+3.4,w:23,h:6,s:1.45,c:C.g600,lh:1.3}));});\n  return s;};\n\n/* --- C · cifras --- */\nSPEC.C1=function(p){\n  var s=[bg(C.w)].concat(chrome(p),[T('Proof,\\nnot promises.',{x:7.5,y:14,w:36,h:16,s:5.6,b:true,tight:true,lh:1.05})]);\n  var d=[['95%','Client retention across engagements'],['5+','Years of average client relationship'],\n         ['21','AgTech domains covered by the team'],['10','Countries where our products operate']];\n  d.forEach(function(c,i){var x=51+(i%2)*22,y=15+Math.floor(i/2)*15;\n    s=s.concat(stat(x,y,c[0],c[1],4.6,C.ink,C.g600,20));});\n  return s;};\n\nSPEC.C2=function(p){\n  var s=[bg(C.sage)].concat(chrome(p),[T('Our footprint',{x:7.5,y:11.5,w:60,h:7,s:4.6,b:true,tight:true})]);\n  var d=[['25','k','Agronomic recommendations delivered'],['3','k','Monthly active users in the field'],['8','×','Faster time-to-field per release']];\n  d.forEach(function(c,i){var x=7.5+i*28.5;\n    s.push(T([{text:c[0],options:{color:C.ink}},{text:c[1],options:{color:C.em7}}],\n      {x:x,y:30,w:24,h:8,s:7,b:true,tight:true,lh:.95}));\n    s.push(T(c[2],{x:x,y:39.5,w:23,h:7,s:1.6,c:C.g600,lh:1.3}));});\n  return s;};\n\nSPEC.C3=function(p){return [bg(C.g950)].concat(chrome(p,true),[\n  T([{text:'95',options:{fontSize:FS(44)}},{text:'%',options:{fontSize:FS(18)}}],\n    {x:7.5,y:9.5,w:85,h:33,s:44,b:true,c:C.lime,tight:true,lh:.8,va:'middle'}),\n  T('Client retention across every engagement since 2017.',{x:7.5,y:44.5,w:56,h:7,s:2.2,b:true,c:C.cr100,lh:1.25})]);};\n\nSPEC.C4=function(p){\n  var s=[bg(C.w)].concat(chrome(p),[T('SINCE 2017',{x:7.5,y:12,w:40,h:2.6,s:1.5,b:true,c:C.em7,cs:1.8})]);\n  var d=[['21','AgTech domains covered in-house'],['10','Countries running our products'],['5+','Years of average client relationship']];\n  d.forEach(function(c,i){var x=7.5+i*29;\n    s.push(T(c[0],{x:x,y:19,w:26,h:15,s:15,b:true,tight:true,lh:.9}));\n    s.push(T(c[1],{x:x,y:36.5,w:24,h:7,s:1.5,c:C.g600,lh:1.3}));});\n  s.push(rule(7.5,45.5,14));return s;};\n\n/* --- D · gráficos --- */\nSPEC.D1=function(p){return [bg(C.w)].concat(chrome(p),[\n  T('Adoption grows season over season',{x:7.5,y:11.5,w:38,h:16,s:4.2,b:true,tight:true,lh:1.08}),\n  T(\"Active users per campaign across four seasons. Lime marks the first season with an embedded Magoya pod.\",\n    {x:7.5,y:30,w:33,h:10,s:1.45,c:C.g600,lh:1.4}),\n  CH({type:'bar',x:50,y:14,w:42.5,h:33,\n    data:[{name:'Active users',labels:['S1','S2','S3','S4'],values:[900,1400,1800,2400]}],\n    opts:{barDir:'col',barGapWidthPct:60,chartColors:[C.g900,C.g900,C.g900,C.lime]}})]);};\n\nSPEC.D2=function(p){return [bg(C.w)].concat(chrome(p),[\n  T('Fields with an embedded pod close the loop faster',{x:7.5,y:11.5,w:66,h:11,s:4.2,b:true,tight:true,lh:1.08}),\n  CH({type:'bar',x:6,y:24,w:56,h:24,\n    data:[{name:'Baseline',labels:['Q1','Q2','Q3','Q4'],values:[700,850,900,1000]},\n          {name:'Embedded pod',labels:['Q1','Q2','Q3','Q4'],values:[1000,1400,1800,2200]}],\n    opts:{barDir:'col',barGrouping:'clustered',barGapWidthPct:70,chartColors:[C.g300,C.g900]}}),\n  T(\"Recommendations accepted per quarter. Baseline is the client's previous vendor setup.\",\n    {x:66,y:30,w:26,h:10,s:1.45,c:C.g600,lh:1.4}),\n  R({x:7.5,y:49.5,w:1.1,h:1.1,fill:C.g300,radius:.3}),T('Baseline',{x:9.2,y:49.5,w:12,h:2,s:1.2,b:true,c:C.g600}),\n  R({x:22,y:49.5,w:1.1,h:1.1,fill:C.g900,radius:.3}),T('Embedded pod',{x:23.7,y:49.5,w:16,h:2,s:1.2,b:true,c:C.g600})]);};\n\nSPEC.D3=function(p){return [bg(C.w)].concat(chrome(p),[\n  T('Twelve months of compounding adoption',{x:7.5,y:11.5,w:62,h:11,s:4.2,b:true,tight:true,lh:1.08}),\n  CH({type:'line',x:6,y:24,w:58,h:24,\n    data:[{name:'With Magoya',labels:['M1','M3','M5','M7','M9','M12'],values:[100,180,290,430,570,700]},\n          {name:'Baseline',labels:['M1','M3','M5','M7','M9','M12'],values:[100,118,134,146,158,170]}],\n    opts:{chartColors:[C.g900,C.g300],lineSize:4,lineSmooth:false,lineDataSymbolSize:8,\n      lineDataSymbol:'circle',lineDataSymbolLineColor:C.g900}}),\n  T('+312%',{x:68,y:26,w:24,h:6,s:4,b:true,tight:true}),\n  T('Monthly active growers, month 1 to 12',{x:68,y:32,w:24,h:7,s:1.4,c:C.g600,lh:1.3}),\n  R({x:68,y:41,w:1.1,h:1.1,fill:C.g900,radius:.3}),T('With Magoya',{x:69.7,y:41,w:20,h:2,s:1.2,b:true,c:C.g600}),\n  R({x:68,y:44,w:1.1,h:1.1,fill:C.g300,radius:.3}),T('Baseline forecast',{x:69.7,y:44,w:22,h:2,s:1.2,b:true,c:C.g600})]);};\n\nSPEC.D4=function(p){\n  var s=[bg(C.sage)].concat(chrome(p),[\n    T('Discovery outcomes, quantified',{x:7.5,y:11.5,w:60,h:7,s:4.2,b:true,tight:true}),\n    CH({type:'doughnut',x:6,y:22,w:24,h:24,\n      data:[{name:'Validated',labels:['Validated','Open'],values:[68,32]}],\n      opts:{holeSize:62,chartColors:[C.g900,C.g200],dataLabelFormatCode:' '}}),\n    T('68%',{x:11.6,y:31.5,w:13,h:5,s:3.4,b:true,al:'center',tight:true}),\n    T('validated',{x:11.6,y:36,w:13,h:2.4,s:1.15,b:true,al:'center',c:C.g600}),\n    T('Of 25 hypotheses raised in a 6-week paid discovery, two thirds survived contact with real operations.',\n      {x:34,y:21,w:38,h:8,s:1.75,c:C.g800,lh:1.45})]);\n  var d=[['Hypotheses validated in the field','68%',68,0],['Flows reworked after grower testing','44%',44,0],['Scope removed before build','31%',31,1]];\n  d.forEach(function(r,i){var y=30+i*6.4,w=52;\n    s.push(T(r[0],{x:34,y:y,w:38,h:2.4,s:1.35,b:true}));\n    s.push(T(r[1],{x:74,y:y,w:18,h:2.4,s:1.35,b:true,c:C.g600,al:'right'}));\n    s.push(R({x:34,y:y+3,w:w+6,h:1,fill:C.g200,radius:.5}));\n    s.push(R({x:34,y:y+3,w:(w+6)*r[2]/100,h:1,fill:r[3]?C.lime:C.g900,radius:.5}));});\n  return s;};\n\n/* --- E · listas & tablas --- */\nSPEC.E1=function(p){return [bg(C.w)].concat(chrome(p),[\n  T('The Magoya method',{x:7.5,y:14,w:32,h:16,s:5.6,b:true,tight:true,lh:1.05})],\n  rowsBlock(44,14,48.5,[{n:'1',t:'Discover — immersion in your product, market and users.'},\n    {n:'2',t:'Align — one plan, shared metrics, no surprises.'},\n    {n:'3',t:'Execute — the embedded senior pod ships and iterates.'},\n    {n:'4',t:'Learn — measure in the field, evolve the roadmap.'}],2));};\n\nSPEC.E2=function(p){\n  var s=[bg(C.sage)].concat(chrome(p),[T('Why teams choose Magoya',{x:7.5,y:11.5,w:70,h:7,s:4.4,b:true,tight:true})]);\n  var g=[{h:'Domain expertise',l:['We work only in agribusiness, and have since 2017.','Agronomists sitting next to engineers.','Fluency with grower and retail workflows.']},\n         {h:'Proven methodology',l:['A collaborative path from discovery to launch.','Senior pods assembled around your product.','Results that outlast the roadmap.']}];\n  g.forEach(function(c,i){var x=7.5+i*43.5,y=21,w=41.5,h=28.2;\n    s.push(card(x,y,w,h,C.w,C.hair));\n    s.push(T(c.h,{x:x+2.2,y:y+2.2,w:w-4.4,h:4,s:2.1,b:true,tight:true}));\n    c.l.forEach(function(t,j){s=s.concat(checkLine(x+2.2,y+8+j*5.6,w-4.4,t));});});\n  return s;};\n\nSPEC.E3=function(p){\n  var s=[bg(C.w)].concat(chrome(p),[\n    T('Two ways to staff this',{x:7.5,y:11.5,w:46,h:7,s:4,b:true,tight:true})],\n    chip(70,12,'Scenario 1 of 2 · scope',C.em7,22.5));\n  var rows=[[{text:'Role in the pod'},{text:'Lean'},{text:'Recommended'},{text:'What changes'}],\n    ['Engagement lead','0.2','0.5','Weekly steering instead of monthly.'],\n    ['Product designer','0.5','1.0','Field research runs in parallel with build.'],\n    ['Senior engineers','2.0','3.0','Two workstreams instead of one queue.'],\n    ['Data & AI engineer','—','1.0','Agronomic models enter the MVP, not phase 2.'],\n    ['Agronomist','0.2','0.5','Validation on real operations every sprint.'],\n    ['QA','0.3','0.5','Regression coverage before each season.'],\n    ['Total FTE','3.2','6.5','Recommended halves time-to-field.']];\n  var trows=rows.map(function(r,i){\n    var head=i===0,tot=i===rows.length-1;\n    return r.map(function(cell,j){\n      var txt=(typeof cell==='object')?cell.text:cell;\n      return {text:txt,options:{\n        bold:head||tot||j===0,fontSize:FS(head?1.2:(tot?1.7:1.5)),\n        color:head?C.g600:C.ink,align:(j===1||j===2)?'center':'left',\n        fill:(j===2)?(tot?C.lime:C.sage):undefined,\n        valign:'middle',margin:[6,8,6,8]}};});});\n  s.push({k:'tb',x:7.5,y:21,w:85,rows:trows,\n    opts:{colW:[IN(26),IN(11),IN(15),IN(33)],rowH:IN(3.9),\n      border:[{type:'none'},{type:'none'},{type:'solid',color:C.hair,pt:.5},{type:'none'}]}});\n  return s;};\n\nSPEC.E4=function(p){\n  var s=[bg(C.w)].concat(chrome(p),[\n    T('Timing and investment',{x:7.5,y:11.5,w:46,h:7,s:4,b:true,tight:true})],\n    chip(69,12,'Scenario 2 of 2 · numbers',C.em7,23.5));\n  var d=[{h:'Lean',f:'3.2 FTE',n:[['9','months to MVP'],['1','workstream'],['Q3','first field season']],ft:'Phase 2 required for data & AI',dk:0},\n         {h:'Recommended',f:'6.5 FTE',n:[['5','months to MVP'],['2','workstreams'],['Q1','first field season']],ft:'Data & AI included from sprint 1',dk:1}];\n  d.forEach(function(c,i){var x=7.5+i*43.5,y=20.5,w=41.5,h=17.5;\n    s.push(card(x,y,w,h,c.dk?C.g900:C.sage,null));\n    s.push(T(c.h,{x:x+2.2,y:y+2,w:24,h:4,s:2.1,b:true,tight:true,c:c.dk?C.cr50:C.ink}));\n    s.push(T(c.f,{x:x+w-14,y:y+2.6,w:12,h:3,s:1.45,c:c.dk?C.cr300:C.g600,al:'right'}));\n    c.n.forEach(function(v,j){var vx=x+2.2+j*12.6;\n      s.push(T(v[0],{x:vx,y:y+7.6,w:12,h:4,s:3.4,b:true,tight:true,c:c.dk?C.cr50:C.ink}));\n      s.push(T(v[1],{x:vx,y:y+11.6,w:11.5,h:3.5,s:1.2,c:c.dk?C.cr300:C.g600,lh:1.2}));});\n    s.push(T(c.ft,{x:x+2.2,y:y+h-3.2,w:w-4.4,h:2.6,s:1.4,b:true,c:c.dk?C.lime:C.ink}));});\n  return s.concat(timeline(7.5,42,85,[{b:'Kick-off',s:'Week 0'},{b:'Discovery closed',s:'Week 6'},\n    {b:'MVP in the field',s:'Month 5 · recommended'},{b:'MVP in the field',s:'Month 9 · lean'},\n    {b:'Season review',s:'Month 12'}],2));};\n\n/* --- F · proceso --- */\nSPEC.F1=function(p){return [bg(C.w)].concat(chrome(p),[\n  T('From discovery to the field',{x:7.5,y:12,w:70,h:7,s:4.4,b:true,tight:true})],\n  timeline(7.5,30,85,[{b:'Discovery',s:'Immersion, users, constraints'},{b:'Ideation',s:'Concepts and priorities'},\n    {b:'Prototyping',s:'Tested with real growers'},{b:'MVP',s:'Ship the core loop'},\n    {b:'Scaling',s:'Evolve with the seasons'}],2));};\n\nSPEC.F2=function(p){\n  var s=[bg(C.sage)].concat(chrome(p),[T('How the work runs',{x:7.5,y:11.5,w:70,h:7,s:4.4,b:true,tight:true})]);\n  var d=[['Phase 01','Discover','Immersion in the product, the market and the people who use it in the field.',0],\n         ['Phase 02','Align','One plan, shared metrics and a scope both teams can defend.',0],\n         ['Phase 03','Execute','The embedded senior pod ships in your rituals, with your definition of done.',1],\n         ['Phase 04','Learn','Measure on real operations and feed the next season’s roadmap.',0]];\n  d.forEach(function(c,i){var x=7.5+i*21.8,y=21,w=20.2,h=28.2;\n    s.push(card(x,y,w,h,C.w,C.hair));\n    if(c[3])s.push(R({x:x,y:y,w:w,h:.5,fill:C.lime}));\n    s.push(T(c[0].toUpperCase(),{x:x+1.8,y:y+2.2,w:w-3.6,h:2.2,s:1.15,b:true,c:C.g600,cs:1.3}));\n    s.push(T(c[1],{x:x+1.8,y:y+5,w:w-3.6,h:4,s:1.9,b:true,tight:true}));\n    s.push(T(c[2],{x:x+1.8,y:y+9.5,w:w-3.6,h:14,s:1.4,c:C.g600,lh:1.35}));});\n  return s;};\n\nSPEC.F3=function(p){\n  var s=[bg(C.w)].concat(chrome(p),[T('One recommendation, four hands',{x:7.5,y:11.5,w:70,h:7,s:3.9,b:true,tight:true})]);\n  var lw=13,gap=.7,cw=(85-lw-gap*4)/4, x0=7.5+lw+gap;\n  s.push(T('FIELD SIGNAL',{x:x0,y:19,w:cw,h:2,s:1.05,b:true,c:C.em7,cs:1}));\n  s.push(T('DECISION',{x:x0+2*(cw+gap),y:19,w:cw,h:2,s:1.05,b:true,c:C.em7,cs:1}));\n  s.push(T('ACTION',{x:x0+3.4*(cw+gap),y:19,w:cw,h:2,s:1.05,b:true,c:C.em7,cs:1,al:'right'}));\n  s.push(R({x:x0,y:20.2,w:85-lw-gap,h:.18,fill:C.g300}));\n  var lanes=[['Grower',[['Flags a problem from the cab, offline',0],['Waits',2],['Reviews the recommendation on WhatsApp',0],['Applies it and confirms in one tap',3]]],\n             ['Agronomist',[['Notified',2],['Validates against the field history',0],['Signs off or adjusts the dose',0],['Audits the outcome',2]]],\n             ['Platform',[['Syncs when signal returns',1],['Runs the agronomic model',1],[\"Delivers to the grower's channel\",1],['Logs the applied action',1]]],\n             ['Magoya pod',[['Instruments the event',2],['Tunes the model with agronomy',2],['Tests the channel with real users',2],['Reads adoption weekly',2]]]];\n  lanes.forEach(function(ln,r){var y=22+r*6.6;\n    s.push(T(ln[0].toUpperCase(),{x:7.5,y:y+1.6,w:lw-1,h:3,s:1.15,b:true,c:C.g600,cs:1}));\n    ln[1].forEach(function(cell,ci){var cx=x0+ci*(cw+gap),kind=cell[1];\n      s.push(R({x:cx,y:y,w:cw,h:6,fill:kind===1?C.g900:(kind===3?C.lime:C.w),\n        line:kind===0?C.hair:(kind===2?C.g300:null),lw:.75,radius:.8}));\n      s.push(T(cell[0],{x:cx+1,y:y+.9,w:cw-2,h:4.4,s:1.25,c:kind===1?C.cr50:(kind===2?C.g600:C.ink),\n        b:kind===3,lh:1.28}));});});\n  return s;};\n\nSPEC.F4=function(p){\n  var s=[bg(C.sage)].concat(chrome(p),[T('What comes out of a discovery',{x:7.5,y:11.5,w:70,h:7,s:4.2,b:true,tight:true})]);\n  var caps=['01 · Wireframes','02 · Clickable prototype','03 · Prioritised backlog'];\n  for(var i=0;i<3;i++){var x=7.5+i*29.5,y=21,w=27,h=28.2;\n    s.push(card(x,y,w,h,C.w,C.hair));\n    s.push(R({x:x,y:y,w:w,h:2.4,fill:C.g100}));\n    for(var k=0;k<3;k++)s.push(R({x:x+1.2+k*1.2,y:y+.9,w:.65,h:.65,fill:C.g300,radius:.32}));\n    if(i===0){s.push(R({x:x+1.6,y:y+4,w:16,h:1.7,fill:C.g200,radius:.3}));\n      s.push(R({x:x+1.6,y:y+6.6,w:w-3.2,h:5.4,fill:C.g100,radius:.3}));\n      s.push(R({x:x+1.6,y:y+13,w:19,h:.9,fill:C.g200,radius:.3}));\n      s.push(R({x:x+1.6,y:y+14.6,w:10,h:.9,fill:C.g200,radius:.3}));}\n    else if(i===1){s.push(R({x:x+1.6,y:y+4,w:16,h:1.7,fill:C.g900,radius:.3}));\n      s.push(R({x:x+1.6,y:y+6.6,w:(w-4)/2,h:5.4,fill:C.g100,radius:.3}));\n      s.push(R({x:x+2.4+(w-4)/2,y:y+6.6,w:(w-4)/2,h:5.4,fill:C.lime,radius:.3}));\n      s.push(R({x:x+1.6,y:y+13,w:19,h:.9,fill:C.g200,radius:.3}));}\n    else{s.push(R({x:x+1.6,y:y+4,w:16,h:1.7,fill:C.g200,radius:.3}));\n      [0,1,2,3,4].forEach(function(k){s.push(R({x:x+1.6,y:y+6.8+k*2,w:(k%2?18:w-3.2),h:.9,fill:C.g200,radius:.3}));});}\n    s.push(T(caps[i],{x:x+1.6,y:y+h-3.4,w:w-3.2,h:2.4,s:1.15,b:true,c:C.g600,cs:1}));}\n  return s;};\n\n/* --- G · casos de éxito --- */\nSPEC.G1=function(p){\n  var s=[bg(C.w)].concat(chrome(p),[\n    IMG({src:CL+'bunge.svg',x:7.5,y:11.5,w:12,h:4,fit:'contain',gray:true})],\n    chip(22,11.8,'Company challenge · fragmented grower data',C.ink,32),\n    chip(56,11.8,'Urgent need · one season to launch',C.em7,26),[\n    T('Six data sources, one decision screen for the agronomist.',{x:7.5,y:18.5,w:62,h:10,s:3.7,b:true,tight:true,lh:1.12})]);\n  var d=[['Challenge','Grower data lived in six systems. Agronomists rebuilt the same picture by hand every week.',0],\n         ['Team','Embedded pod of 6: engagement lead, designer, three engineers and one agronomist.',0],\n         ['Adaptation','We joined their rituals and their QA gates, and moved AI into sprint 1 instead of phase 2.',0],\n         ['Results','',1]];\n  d.forEach(function(c,i){var x=7.5+i*21.8,y=31,w=20.2;\n    s.push(R({x:x,y:y,w:w,h:.42,fill:c[2]?C.lime:C.ink}));\n    s.push(T(c[0].toUpperCase(),{x:x,y:y+1.6,w:w,h:2.2,s:1.1,b:true,c:C.g600,cs:1}));\n    if(c[2]){\n      s.push(T([{text:'8×',options:{}}],{x:x,y:y+4.4,w:w,h:4,s:3,b:true,tight:true}));\n      s.push(T('faster time-to-field',{x:x,y:y+8,w:w,h:2.4,s:1.26,b:true,c:C.g600}));\n      s.push(T('3k',{x:x,y:y+11,w:w,h:4,s:3,b:true,tight:true}));\n      s.push(T('monthly active users',{x:x,y:y+14.6,w:w,h:2.4,s:1.26,b:true,c:C.g600}));\n    } else s.push(T(c[1],{x:x,y:y+4.4,w:w,h:12,s:1.32,lh:1.4}));});\n  return s;};\n\nSPEC.G2=function(p){\n  var s=[bg(C.sage)].concat(chrome(p),[\n    IMG({src:CL+'precision-planting.svg',x:7.5,y:11.5,w:14,h:4,fit:'contain',gray:true})],\n    chip(24,11.8,'Urgent need · planting window in 11 weeks',C.ink,31),[\n    T('From a spreadsheet ritual to a planting plan the crew trusts.',{x:7.5,y:18.5,w:58,h:10,s:3.7,b:true,tight:true,lh:1.12})]);\n  var d=[['Before','6 days','to close a planting plan across 40 fields',C.ink],\n         ['After 11 weeks','4 hours','same 40 fields, same two agronomists',C.em7],\n         ['Held for','3','consecutive seasons without extra headcount',C.ink]];\n  d.forEach(function(c,i){var x=7.5+i*29.5;\n    s.push(T(c[0].toUpperCase(),{x:x,y:31,w:26,h:2.2,s:1.15,b:true,c:C.g600,cs:1}));\n    s.push(T(c[1],{x:x,y:34,w:26,h:7,s:6.4,b:true,tight:true,c:c[3],lh:.95}));\n    s.push(T(c[2],{x:x,y:41.5,w:25,h:6,s:1.4,c:C.g600,lh:1.3}));});\n  s.push(T('→',{x:33.5,y:35,w:6,h:5,s:3,b:true,c:C.g300}));\n  s.push(rule(7.5,47.5,14));return s;};\n\n/* --- H · fotografía --- */\nSPEC.H1=function(p){return [bg(C.w),\n  IMG({src:PH+'field-terraces.jpg',x:0,y:0,w:44,h:56.25,fit:'cover'})].concat(chrome(p,false,48),[\n  T('MARKET CONTEXT',{x:51,y:16,w:40,h:2.6,s:1.5,b:true,c:C.em7,cs:1.8}),\n  T('Every region is a different product problem.',{x:51,y:20.5,w:41,h:13,s:3.7,b:true,tight:true,lh:1.12}),\n  T('Terraces, centre pivots and rainfed lots do not share a workflow. We design for the operation in front of us, then generalise — not the other way round.',\n    {x:51,y:34,w:41,h:11,s:1.75,c:C.g800,lh:1.45})],\n  chip(51,46.5,'10 countries · 21 domains',C.em7,24));};\n\nSPEC.H2=function(p){return [bg(C.sage),\n  IMG({src:PH+'field-corn.jpg',x:56,y:0,w:44,h:56.25,fit:'cover'})].concat(chrome(p,false,7.5),[\n  T('FIELD FIRST',{x:7.5,y:16,w:40,h:2.6,s:1.5,b:true,c:C.em7,cs:1.8}),\n  T('Software that survives dust, gloves and no signal.',{x:7.5,y:20.5,w:41,h:13,s:3.7,b:true,tight:true,lh:1.12}),\n  T('Every release is tested on a real operation before it ships. If it does not work at 6am with one bar of signal, it does not work.',\n    {x:7.5,y:34,w:41,h:10,s:1.75,c:C.g800,lh:1.45}),\n  rule(7.5,46.5,14)]);};\n\nSPEC.H3=function(p){return [bg(C.g950),\n  IMG({src:PH+'field-bali.jpg',x:0,y:0,w:100,h:56.25,fit:'cover'}),\n  R({x:0,y:0,w:100,h:56.25,fill:C.g950,alpha:28})].concat(chrome(p,true),[\n  T('The planting window doesn’t move. Your release date does.',{x:7.5,y:29,w:62,h:14,s:5.6,b:true,c:C.cr50,tight:true,lh:1.05}),\n  T('We plan against the crop calendar. If a feature misses the window, it waits a year — so we ship what the season can use, then keep building.',\n    {x:7.5,y:43.5,w:46,h:7,s:1.75,c:C.cr100,lh:1.45})]);};\n\nSPEC.H4=function(p){\n  var s=[bg(C.w)].concat(chrome(p),[T('Ten countries, one product language',{x:7.5,y:11.5,w:58,h:11,s:4.2,b:true,tight:true,lh:1.08})]);\n  var ph=[['field-rows.jpg','Row crops · Argentina & Brazil'],['field-terraces.jpg','Terraced systems · Southeast Asia'],['field-corn.jpg','Corn belt · United States']];\n  ph.forEach(function(c,i){var x=7.5+i*28.7,w=27.3;\n    s.push(IMG({src:PH+c[0],x:x,y:23,w:w,h:20,fit:'cover'}));\n    s.push(T(c[1],{x:x,y:44,w:w,h:4,s:1.45,c:C.g600,lh:1.3}));});\n  return s;};\n\n/* --- I · ilustración --- */\nSPEC.I1=function(p){return [bg(C.w),\n  IMG({src:A+'illus/char-jumping.svg',x:57,y:7.5,w:48.7,h:50})].concat(chrome(p),[\n  T('CLARITY · CONFIDENCE · COMMITMENT',{x:7.5,y:26,w:48,h:2.6,s:1.5,b:true,c:C.em7,cs:1.8}),\n  T('Complexity in,\\na clear plan out.',{x:7.5,y:30.5,w:48,h:16,s:5.2,b:true,tight:true,lh:1.05})]);};\n\nSPEC.I2=function(p){return [bg(C.sage),\n  IMG({src:A+'illus/char-chart-duo.svg',x:-6,y:8.25,w:40.3,h:48})].concat(chrome(p,false,44),[\n  T('21',{x:48,y:22,w:44.5,h:10,s:9,b:true,tight:true,al:'right',lh:.95}),\n  T('AgTech domains covered by the same team',{x:48,y:32.5,w:44.5,h:8,s:2.8,b:true,al:'right',lh:1.25}),\n  T('Agronomy, logistics, traceability, carbon, retail, crop protection and fifteen more.',\n    {x:56,y:42,w:36.5,h:6,s:1.45,c:C.g600,al:'right',lh:1.35})]);};\n\n/* --- J · personas --- */\nSPEC.J1=function(){return [bg(C.sage),\n  card(21,10,58,36.5,C.w,null),\n  T('“Magoya’s expertise in UX, digital ag platform development and agronomic know-how, combined with their understanding of farmer and retail needs, made our transformation possible.”',\n    {x:24.2,y:13.2,w:51.6,h:16,s:2.2,b:true,lh:1.42}),\n  R({x:24.2,y:32,w:12,h:.65,fill:C.lime,radius:.32}),\n  T('Varina Baldi',{x:24.2,y:35.4,w:40,h:3,s:1.45,b:true}),\n  T('Founder & CEO',{x:24.2,y:38.2,w:40,h:3,s:1.45,c:C.g600})];};\n\nSPEC.J2=function(p){return [bg(C.g950),\n  IMG({src:PH+'cami-agtech-bw.jpg',x:0,y:0,w:100,h:56.25,fit:'cover',gray:true}),\n  R({x:0,y:0,w:100,h:56.25,fill:C.g950,alpha:30})].concat(chrome(p,true),[\n  T('“They did not join to deliver a project. They joined to own the outcome with us.”',\n    {x:7.5,y:28,w:60,h:14,s:2.6,b:true,c:C.cr50,lh:1.38}),\n  R({x:7.5,y:42.6,w:24,h:.7,fill:C.lime,radius:.35}),\n  T('Camila López Colmano',{x:7.5,y:45,w:40,h:3,s:1.7,b:true,c:C.cr50}),\n  T('AgTech Expert',{x:7.5,y:47.8,w:40,h:3,s:1.45,c:C.cr300})]);};\n\nSPEC.J3=function(p){\n  var s=[bg(C.w)].concat(chrome(p),[\n    T('The team you actually get',{x:7.5,y:11.5,w:44,h:8,s:4.2,b:true,tight:true}),\n    T('Named people, not a bench. The pod grows with agronomy and QA from the same team.',\n      {x:66,y:12,w:26,h:7,s:1.45,c:C.g600,lh:1.35})]);\n  var t=[['Varina Baldi','Founder & CEO','varu-baldi-bw.jpg'],['Francisco Facal','Solutions Architecture','varu-ceo-bw.jpg'],\n         ['Camila López Colmano','AgTech Expert','cami-agtech-bw.jpg']];\n  t.forEach(function(c,i){var x=7.5+i*29.5,w=26.9;\n    s.push(IMG({src:PH+c[2],x:x,y:18,w:w,h:26,fit:'cover',gray:true}));\n    s.push(T(c[0],{x:x,y:44.8,w:w,h:3,s:1.6,b:true,tight:true}));\n    s.push(T(c[1],{x:x,y:47.7,w:w,h:3,s:1.3,c:C.g600}));});\n  return s;};\n\n/* --- K · tecnología & AI --- */\nSPEC.K1=function(p){\n  var s=[bg(C.sage)].concat(chrome(p),[\n    T('The stack we work in',{x:7.5,y:11.5,w:50,h:7,s:4.2,b:true,tight:true})],\n    chip(65.5,12,'No new vendor to onboard',C.em7,27));\n  var cols=[['Product surfaces',['react.svg','nextjs.svg']],\n            ['Services & data',['nodejs.svg','django.svg','postgresql.svg','mongodb.svg']],\n            ['Cloud',['aws.svg','google-cloud.svg','azure.svg']],\n            ['Delivery & ML ops',['docker.svg','kubernetes.svg','terraform.svg','jupyter.svg']]];\n  cols.forEach(function(c,i){var x=7.5+i*21.8,y=21,w=20.2,h=26;\n    s.push(card(x,y,w,h,C.w,C.hair));\n    s.push(T(c[0].toUpperCase(),{x:x+1.6,y:y+2,w:w-3.2,h:3,s:1.15,b:true,c:C.g600,cs:1,lh:1.2}));\n    s=s.concat(logoRow(c[1].map(function(f){return PT+f;}),x+1.6,y+7,w-3.2,3.6,2,1.2,1.6));});\n  return s;};\n\nSPEC.K2=function(p){\n  var s=[bg(C.w)].concat(chrome(p),[\n    T('What we ship with AI',{x:7.5,y:11.5,w:50,h:7,s:4.2,b:true,tight:true}),rule(82.5,13.5,10)]);\n  var d=[['openai.svg','Agronomic copilots',\"Conversational assistants over the client's own agronomy, in WhatsApp and in-product.\"],\n         ['anthropic.svg','Retrieval over field data','RAG on trial results, labels and protocols — answers with the source attached.'],\n         ['huggingface.svg','Vision on crop imagery','Disease and weed detection from phone, drone and satellite captures.'],\n         ['ollama.svg','On-premise inference','Local models when the data cannot leave the client’s environment.']];\n  d.forEach(function(c,i){var x=7.5+(i%2)*44,y=22+Math.floor(i/2)*13.5;\n    s.push(IMG({src:AI+c[0],x:x,y:y,w:2.8,h:2.8,fit:'contain'}));\n    s.push(T(c[1],{x:x+4.2,y:y-.2,w:36,h:3,s:1.7,b:true,tight:true}));\n    s.push(T(c[2],{x:x+4.2,y:y+3,w:36,h:7,s:1.3,c:C.g600,lh:1.35}));});\n  return s;};\n\n/* --- L · clientes --- */\nSPEC.L1=function(p){\n  var s=[bg(C.w)].concat(chrome(p),[\n    T('Nine years inside agribusiness',{x:7.5,y:11.5,w:46,h:11,s:4.2,b:true,tight:true,lh:1.08}),\n    T('5+',{x:70,y:12,w:22.5,h:5,s:3.4,b:true,tight:true,al:'right'}),\n    T('years of average relationship',{x:66,y:16.6,w:26.5,h:3,s:1.4,c:C.g600,al:'right'})]);\n  var names=['apeel-sciences','bunge','corteva','syngenta','climate-fieldview','precision-planting',\n             'bayer-crop-science','indigo','gdm','biome-makers','sound-agriculture','xarvio'];\n  return s.concat(logoRow(names.map(function(n){return CL+n+'.svg';}),7.5,26,85,5,6,2.8,7));};\n\n/* --- M · portada & cierre --- */\nSPEC.M1=function(){return [bg(C.g950),\n  IMG({src:PH+'field-rows.jpg',x:0,y:0,w:100,h:56.25,fit:'cover'}),\n  R({x:0,y:0,w:100,h:56.25,fill:C.g950,alpha:30}),\n  IMG({src:WMC,x:7.5,y:7,w:11,h:3.007})].concat(\n  chip(63.5,7,'Partnership proposal · 2026',C.cr100,29),[\n  T('Digital product\\ndevelopment\\nfor agribusiness',{x:7.5,y:24,w:60,h:22,s:6.8,b:true,c:C.cr50,tight:true,lh:1.02}),\n  T('We design, build and evolve the products and platforms that modern agribusinesses run on.',\n    {x:7.5,y:46.5,w:46,h:6,s:1.75,c:C.cr100,lh:1.45})]);};\n\nSPEC.M2=function(){return [bg(C.g950),\n  IMG({src:A+'motif-semis.svg',x:70,y:0,w:30,h:56.25}),\n  IMG({src:WMC,x:7.5,y:7,w:11,h:3.007})].concat(\n  chip(63.5,7,'Partnership proposal · 2026',C.cr100,29),[\n  T('AgTech challenges demand more than code.',{x:7.5,y:24,w:58,h:22,s:6.8,b:true,c:C.cr50,tight:true,lh:1.02}),\n  T('Clarity, confidence and commitment — the three things a nine-year AgTech partnership is actually made of.',\n    {x:7.5,y:46.5,w:44,h:7,s:1.75,c:C.cr200,lh:1.45})]);};\n\nSPEC.M3=function(p){return [bg(C.sage)].concat(chrome(p),[\n  T('Next step:\\na paid discovery.',{x:7.5,y:13,w:42,h:14,s:4.6,b:true,tight:true,lh:1.05}),\n  T('Six weeks, fixed price, a working prototype and a prioritised backlog at the end. If we are not the right partner after that, you keep everything.',\n    {x:7.5,y:27,w:36,h:11,s:1.75,c:C.g800,lh:1.45}),\n  R({x:7.5,y:41,w:32,h:5.2,fill:C.lime,radius:.75}),\n  T('Book the discovery kickoff',{x:7.5,y:41,w:32,h:5.2,s:1.7,b:true,al:'center',va:'middle'})],\n  rowsBlock(48,13,44.5,[{n:'01',t:'This week — scope call with your product lead'},\n    {n:'02',t:'Week 2 — discovery kickoff with the embedded pod'},\n    {n:'03',t:'Week 8 — prototype, backlog and staffing decision'},\n    {n:'04',t:'Q1 — first release in the field'}],-1,C.em7));};\n\n/* ---------- 9. driver de export ---------- */\nvar PPTX_CDN='https://cdn.jsdelivr.net/npm/pptxgenjs@3.12.0/dist/pptxgen.bundle.js';\nvar libP=null;\nfunction lib(){\n  if(libP)return libP;\n  libP=new Promise(function(res,rej){\n    if(window.PptxGenJS)return res(window.PptxGenJS);\n    var sc=document.createElement('script');sc.src=PPTX_CDN;\n    sc.onload=function(){window.PptxGenJS?res(window.PptxGenJS):rej(new Error('PptxGenJS no cargó'));};\n    sc.onerror=function(){rej(new Error('no se pudo cargar PptxGenJS desde el CDN'));};\n    document.head.appendChild(sc);\n  });\n  return libP;\n}\nfunction buildDeck(ids){\n  return lib().then(function(Lib){\n    var pptx=new Lib();\n    pptx.defineLayout({name:'MAGOYA16x9',width:SW,height:SH});\n    pptx.layout='MAGOYA16x9';\n    pptx.author='Magoya';pptx.company='Magoya';pptx.title='Magoya · Deck kit';\n    var chain=Promise.resolve();\n    ids.forEach(function(id,i){\n      chain=chain.then(function(){\n        var fn=SPEC[id];\n        if(!fn){console.warn('[deck-kit] sin spec para',id);return;}\n        var shapes=fn(String(i+3).padStart(2,'0'));\n        var sl=pptx.addSlide();\n        return paint(pptx,sl,shapes);\n      });\n    });\n    return chain.then(function(){return pptx;});\n  });\n}\n"
 },
 "familias": [
  {
   "id": "A",
   "nombre": "A · Apertura",
   "que_cubre": "statements, agenda y divisores de sección"
  },
  {
   "id": "B",
   "nombre": "B · Servicios & cards",
   "que_cubre": "modelos de engagement y capacidades"
  },
  {
   "id": "C",
   "nombre": "C · Cifras",
   "que_cubre": "stats, métricas al palo, números que se leen de lejos"
  },
  {
   "id": "D",
   "nombre": "D · Gráficos",
   "que_cubre": "barras, barras agrupadas, líneas y progreso"
  },
  {
   "id": "E",
   "nombre": "E · Listas & tablas",
   "que_cubre": "método, checklists y escenarios de inversión"
  },
  {
   "id": "F",
   "nombre": "F · Proceso",
   "que_cubre": "timelines, método, journey de actores y artefactos"
  },
  {
   "id": "G",
   "nombre": "G · Casos de éxito",
   "que_cubre": "estructura challenge → equipo → adaptación → resultados"
  },
  {
   "id": "H",
   "nombre": "H · Fotografía",
   "que_cubre": "aéreas de campo a sangre, scrim y tiras"
  },
  {
   "id": "I",
   "nombre": "I · Ilustración",
   "que_cubre": "personajes planos recortados por un borde"
  },
  {
   "id": "J",
   "nombre": "J · Personas",
   "que_cubre": "quotes y equipo — retratos siempre en B&amp;N"
  },
  {
   "id": "K",
   "nombre": "K · Tecnología & AI",
   "que_cubre": "stack de partners y capacidades de AI"
  },
  {
   "id": "L",
   "nombre": "L · Clientes",
   "que_cubre": "logo wall — logos reales, siempre en gris"
  },
  {
   "id": "M",
   "nombre": "M · Portada & cierre",
   "que_cubre": "covers y next step con CTA"
  }
 ],
 "modulos": [
  {
   "id": "A1",
   "nombre": "Statement hero (126pt)",
   "cuando_usarlo": "primera slide después de la portada, o para abrir un bloque con una sola idea. Una frase, nada más. La frase que carga el sentido va en lima.",
   "layout_src": "SPEC.A1=function(){return [bg(C.w),\n  T('PRODUCT STRATEGY',{x:7.5,y:8,w:60,h:2.6,s:1.5,b:true,c:C.em7,cs:1.8}),\n  T('AgTech challenges\\ndemand more than code.',{x:7.5,y:13,w:85,h:26,s:8.2,b:true,tight:true,lh:1.02}),\n  R({x:7.5,y:38.6,w:47,h:.85,fill:C.em5,radius:.42})];};"
  },
  {
   "id": "A2",
   "nombre": "Título + bajada (2 columnas)",
   "cuando_usarlo": "cuando el statement necesita una aclaración de contexto. El display manda; la bajada no pasa de tres líneas.",
   "layout_src": "SPEC.A2=function(p){return [bg(C.w)].concat(chrome(p),[\n  T('Embedded teams,\\nnot outsourced tickets.',{x:7.5,y:13,w:44,h:22,s:5.6,b:true,tight:true,lh:1.05}),\n  T('Magoya blends product strategy, engineering and agronomy in one senior pod that works inside your process — same rituals, same backlog, same accountability.',\n    {x:55,y:14,w:37.5,h:20,s:1.75,c:C.g800,lh:1.5})]);};"
  },
  {
   "id": "A3",
   "nombre": "Agenda / índice",
   "cuando_usarlo": "slide 2 de todo deck de más de 10 slides. Se repite antes de cada bloque moviendo la fila en lima a la sección que arranca.",
   "layout_src": "SPEC.A3=function(p){return [bg(C.w)].concat(chrome(p),[\n  T('Agenda',{x:7.5,y:13,w:34,h:8,s:5.6,b:true,tight:true}),\n  T('45 minutes · 5 blocks',{x:7.5,y:22.5,w:30,h:3,s:1.45,c:C.g600})],\n  rowsBlock(44,12.5,48.5,[{n:'01',t:'Who we are — and how we embed'},{n:'02',t:\"What we've built in AgTech\"},\n    {n:'03',t:'The Magoya method'},{n:'04',t:'Investment scenarios'},{n:'05',t:'Next steps'}],1,C.em7));};"
  },
  {
   "id": "A4",
   "nombre": "Divisor de sección (paño de semicírculos al corte)",
   "cuando_usarlo": "respiro entre bloques. El paño nace del borde inferior y se corta contra los tres bordes de la pieza — nunca flota en el aire. Número en lima, título en crema.",
   "layout_src": "SPEC.A4=function(){return [bg(C.g950),\n  IMG({src:A+'motif-semis.svg',x:0,y:41.25,w:100,h:15,fit:'cover',swap:[['#00DE68','#ECE3DB']]}),\n  IMG({src:WMC,x:7.5,y:7,w:11,h:3.007}),\n  T('02',{x:7.5,y:14,w:30,h:12,s:12,b:true,c:C.lime,tight:true,lh:.9}),\n  T(\"What we've built\\nin AgTech\",{x:7.5,y:26,w:60,h:13,s:5.6,b:true,c:C.cr50,tight:true,lh:1.05})];};"
  },
  {
   "id": "A5",
   "nombre": "Título + ícono semántico grande",
   "cuando_usarlo": "abrir un capítulo temático. El ícono",
   "layout_src": "SPEC.A5=function(p){return [bg(C.sage)].concat(chrome(p),[\n  T('REMOTE SENSING',{x:7.5,y:13,w:50,h:2.6,s:1.5,b:true,c:C.em7,cs:1.8}),\n  T('Satellite data that reaches the agronomist, not the archive.',{x:7.5,y:17.5,w:50,h:18,s:4.8,b:true,tight:true,lh:1.08}),\n  rule(7.5,37.5,14),\n  IMG({src:AG+'satelite.svg',x:63.5,y:15,w:26,h:26,tint:'#161616'})]);};\n\n/* --- B · servicios --- */;"
  },
  {
   "id": "B1",
   "nombre": "3 cards de servicio con ícono semántico (sage)",
   "cuando_usarlo": "presentar los tres modelos de trabajo. El ícono en lima marca el modelo que estás proponiendo — ése es el golpe de lima de la slide.",
   "layout_src": "SPEC.B1=function(p){\n  var s=[bg(C.sage)].concat(chrome(p),[T('How we partner',{x:7.5,y:11.5,w:60,h:7,s:4.6,b:true,tight:true})]);\n  var d=[{i:'semilla.svg',h:'Product Development',p:'A dedicated team owns the full lifecycle — discovery, prototyping, MVP and scaling.',l:0},\n         {i:'chat-ia.svg',h:'Team Extension',p:'We split responsibilities inside your product process — embedded, not outsourced.',l:1},\n         {i:'grafico.svg',h:'Staff Augmentation',p:'Senior talent on your products, under your processes and daily management.',l:0}];\n  d.forEach(function(c,i){var x=7.5+i*29,y=21,w=27,h=27;\n    s.push(card(x,y,w,h,C.w,C.hair));\n    s=s.concat(iconDot(x+2.2,y+2.2,4.4,c.i,c.l));\n    s.push(T(c.h,{x:x+2.2,y:y+8.4,w:w-4.4,h:5,s:2.1,b:true,tight:true,lh:1.05}));\n    s.push(T(c.p,{x:x+2.2,y:y+13.6,w:w-4.4,h:9,s:1.4,c:C.g600,lh:1.35}));\n    s.push(T('Learn more ↗',{x:x+2.2,y:y+h-4,w:w-4.4,h:2.6,s:1.4,b:true}));});\n  return s;};"
  },
  {
   "id": "B2",
   "nombre": "3 boxes de modelo comercial (uno destacado en verde profundo)",
   "cuando_usarlo": "cuando hay que comparar cómo se factura cada modelo. La caja oscura es la recomendada; el resto queda en sage.",
   "layout_src": "SPEC.B2=function(p){\n  var s=[bg(C.w)].concat(chrome(p),[T('Engagement models',{x:7.5,y:11.5,w:70,h:7,s:4.4,b:true,tight:true})]);\n  var d=[{h:'Product Development',a:'How it works: we assemble every role needed and own the process end to end.',b:'Best for: building a product from discovery to launch.',f:'Fixed scope · milestone billing',dk:0},\n         {h:'Team Extension',a:'How it works: shared responsibilities inside your product development process.',b:'Best for: scaling an existing team with AgTech fluency.',f:'Monthly per role · 3-month cycles',dk:1},\n         {h:'Staff Augmentation',a:'How it works: we provide the talent; you keep your processes and management.',b:'Best for: filling senior roles fast, without hiring overhead.',f:'Monthly per role · your PM',dk:0}];\n  d.forEach(function(c,i){var x=7.5+i*29,y=20.5,w=27,h=28.5;\n    s.push(card(x,y,w,h,c.dk?C.g900:C.sage,null));\n    s.push(T(c.h,{x:x+2.2,y:y+2.2,w:w-4.4,h:5,s:2.1,b:true,tight:true,c:c.dk?C.cr50:C.ink,lh:1.05}));\n    s.push(T(c.a,{x:x+2.2,y:y+8,w:w-4.4,h:8,s:1.4,c:c.dk?C.cr200:C.g600,lh:1.35}));\n    s.push(T(c.b,{x:x+2.2,y:y+15.5,w:w-4.4,h:7,s:1.4,c:c.dk?C.cr200:C.g600,lh:1.35}));\n    s.push(R({x:x+2.2,y:y+h-6,w:w-4.4,h:.1,fill:c.dk?C.g700:C.hair}));\n    s.push(T(c.f,{x:x+2.2,y:y+h-4.6,w:w-4.4,h:3,s:1.5,b:true,c:c.dk?C.lime:C.ink}));});\n  return s;};"
  },
  {
   "id": "B3",
   "nombre": "Grilla de capacidades 2×3 con iconografía semántica",
   "cuando_usarlo": "resumir qué hace el equipo sin párrafos. Un ícono del set agro por capacidad, texto de una línea. El destacado va en lima.",
   "layout_src": "SPEC.B3=function(p){\n  var s=[bg(C.sage)].concat(chrome(p),[T('What the pod covers',{x:7.5,y:11.5,w:70,h:7,s:4.4,b:true,tight:true})]);\n  var d=[['escaneo.svg','Discovery','Field immersion with growers and agronomists.',0],\n         ['lote.svg','Product design','Flows built for gloves, dust and low signal.',0],\n         ['chat-ia.svg','Data & AI','Models and copilots on agronomic data.',1],\n         ['satelite.svg','Platform engineering','APIs, pipelines and cloud that hold a season.',0],\n         ['hoja.svg','Agronomy','Agronomists in the pod, not on call.',0],\n         ['tractor.svg','Field validation','Every release tested on real operations.',0]];\n  d.forEach(function(c,i){var col=i%3,row=Math.floor(i/3),x=7.5+col*29.5,y=21+row*13.5;\n    s=s.concat(iconDot(x,y,3.6,c[0],c[3]));\n    s.push(T(c[1],{x:x+5,y:y+.2,w:23,h:3,s:1.75,b:true,tight:true}));\n    s.push(T(c[2],{x:x+5,y:y+3.4,w:23,h:6,s:1.45,c:C.g600,lh:1.3}));});\n  return s;};\n\n/* --- C · cifras --- */;"
  },
  {
   "id": "C1",
   "nombre": "Título + grilla de 4 stats",
   "cuando_usarlo": "credenciales de la compañía. Cuatro cifras, cada una con un descriptor de una línea. Nunca más de cuatro en esta grilla.",
   "layout_src": "SPEC.C1=function(p){\n  var s=[bg(C.w)].concat(chrome(p),[T('Proof,\\nnot promises.',{x:7.5,y:14,w:36,h:16,s:5.6,b:true,tight:true,lh:1.05})]);\n  var d=[['95%','Client retention across engagements'],['5+','Years of average client relationship'],\n         ['21','AgTech domains covered by the team'],['10','Countries where our products operate']];\n  d.forEach(function(c,i){var x=51+(i%2)*22,y=15+Math.floor(i/2)*15;\n    s=s.concat(stat(x,y,c[0],c[1],4.6,C.ink,C.g600,20));});\n  return s;};"
  },
  {
   "id": "C2",
   "nombre": "Data hero — 3 métricas de producto (sage)",
   "cuando_usarlo": "resultado de un producto puntual. El sufijo (k, ×, %) va en verde digital para que la cifra respire.",
   "layout_src": "SPEC.C2=function(p){\n  var s=[bg(C.sage)].concat(chrome(p),[T('Our footprint',{x:7.5,y:11.5,w:60,h:7,s:4.6,b:true,tight:true})]);\n  var d=[['25','k','Agronomic recommendations delivered'],['3','k','Monthly active users in the field'],['8','×','Faster time-to-field per release']];\n  d.forEach(function(c,i){var x=7.5+i*28.5;\n    s.push(T([{text:c[0],options:{color:C.ink}},{text:c[1],options:{color:C.em7}}],\n      {x:x,y:30,w:24,h:8,s:7,b:true,tight:true,lh:.95}));\n    s.push(T(c[2],{x:x,y:39.5,w:23,h:7,s:1.6,c:C.g600,lh:1.3}));});\n  return s;};"
  },
  {
   "id": "C3",
   "nombre": "Porcentaje al palo — una cifra gigante (44cqw ≈ 65% del ancho)",
   "cuando_usarlo": "cuando el dato es el argumento. La cifra ocupa ~70% del slide y no comparte protagonismo con nada. Lima como display sobre verde profundo.",
   "layout_src": "SPEC.C3=function(p){return [bg(C.g950)].concat(chrome(p,true),[\n  T([{text:'95',options:{fontSize:FS(44)}},{text:'%',options:{fontSize:FS(18)}}],\n    {x:7.5,y:9.5,w:85,h:33,s:44,b:true,c:C.lime,tight:true,lh:.8,va:'middle'}),\n  T('Client retention across every engagement since 2017.',{x:7.5,y:44.5,w:56,h:7,s:2.2,b:true,c:C.cr100,lh:1.25})]);};"
  },
  {
   "id": "C4",
   "nombre": "Tres cifras grandes en línea (15cqw)",
   "cuando_usarlo": "cuando tres datos cuentan una sola historia. Un descriptor corto abajo de cada uno y una regla lima para anclar el bloque.",
   "layout_src": "SPEC.C4=function(p){\n  var s=[bg(C.w)].concat(chrome(p),[T('SINCE 2017',{x:7.5,y:12,w:40,h:2.6,s:1.5,b:true,c:C.em7,cs:1.8})]);\n  var d=[['21','AgTech domains covered in-house'],['10','Countries running our products'],['5+','Years of average client relationship']];\n  d.forEach(function(c,i){var x=7.5+i*29;\n    s.push(T(c[0],{x:x,y:19,w:26,h:15,s:15,b:true,tight:true,lh:.9}));\n    s.push(T(c[1],{x:x,y:36.5,w:24,h:7,s:1.5,c:C.g600,lh:1.3}));});\n  s.push(rule(7.5,45.5,14));return s;};\n\n/* --- D · gráficos --- */;"
  },
  {
   "id": "D1",
   "nombre": "Barras simples (una serie, última barra en lima)",
   "cuando_usarlo": "una sola serie temporal. La barra en lima es el período que querés que se recuerde; el resto en verde profundo.",
   "layout_src": "SPEC.D1=function(p){return [bg(C.w)].concat(chrome(p),[\n  T('Adoption grows season over season',{x:7.5,y:11.5,w:38,h:16,s:4.2,b:true,tight:true,lh:1.08}),\n  T(\"Active users per campaign across four seasons. Lime marks the first season with an embedded Magoya pod.\",\n    {x:7.5,y:30,w:33,h:10,s:1.45,c:C.g600,lh:1.4}),\n  CH({type:'bar',x:50,y:14,w:42.5,h:33,\n    data:[{name:'Active users',labels:['S1','S2','S3','S4'],values:[900,1400,1800,2400]}],\n    opts:{barDir:'col',barGapWidthPct:60,chartColors:[C.g900,C.g900,C.g900,C.lime]}})]);};"
  },
  {
   "id": "D2",
   "nombre": "Barras agrupadas (dos series + leyenda en chips)",
   "cuando_usarlo": "comparar dos cohortes o dos escenarios en el mismo eje. Máximo dos series y cuatro grupos: más que eso deja de leerse en pantalla.",
   "layout_src": "SPEC.D2=function(p){return [bg(C.w)].concat(chrome(p),[\n  T('Fields with an embedded pod close the loop faster',{x:7.5,y:11.5,w:66,h:11,s:4.2,b:true,tight:true,lh:1.08}),\n  CH({type:'bar',x:6,y:24,w:56,h:24,\n    data:[{name:'Baseline',labels:['Q1','Q2','Q3','Q4'],values:[700,850,900,1000]},\n          {name:'Embedded pod',labels:['Q1','Q2','Q3','Q4'],values:[1000,1400,1800,2200]}],\n    opts:{barDir:'col',barGrouping:'clustered',barGapWidthPct:70,chartColors:[C.g300,C.g900]}}),\n  T(\"Recommendations accepted per quarter. Baseline is the client's previous vendor setup.\",\n    {x:66,y:30,w:26,h:10,s:1.45,c:C.g600,lh:1.4}),\n  R({x:7.5,y:49.5,w:1.1,h:1.1,fill:C.g300,radius:.3}),T('Baseline',{x:9.2,y:49.5,w:12,h:2,s:1.2,b:true,c:C.g600}),\n  R({x:22,y:49.5,w:1.1,h:1.1,fill:C.g900,radius:.3}),T('Embedded pod',{x:23.7,y:49.5,w:16,h:2,s:1.2,b:true,c:C.g600})]);};"
  },
  {
   "id": "D3",
   "nombre": "Gráfico de líneas (serie principal + baseline punteada)",
   "cuando_usarlo": "tendencia larga. La serie de Magoya va sólida en verde profundo con el último punto en lima; el baseline queda punteado en gris.",
   "layout_src": "SPEC.D3=function(p){return [bg(C.w)].concat(chrome(p),[\n  T('Twelve months of compounding adoption',{x:7.5,y:11.5,w:62,h:11,s:4.2,b:true,tight:true,lh:1.08}),\n  CH({type:'line',x:6,y:24,w:58,h:24,\n    data:[{name:'With Magoya',labels:['M1','M3','M5','M7','M9','M12'],values:[100,180,290,430,570,700]},\n          {name:'Baseline',labels:['M1','M3','M5','M7','M9','M12'],values:[100,118,134,146,158,170]}],\n    opts:{chartColors:[C.g900,C.g300],lineSize:4,lineSmooth:false,lineDataSymbolSize:8,\n      lineDataSymbol:'circle',lineDataSymbolLineColor:C.g900}}),\n  T('+312%',{x:68,y:26,w:24,h:6,s:4,b:true,tight:true}),\n  T('Monthly active growers, month 1 to 12',{x:68,y:32,w:24,h:7,s:1.4,c:C.g600,lh:1.3}),\n  R({x:68,y:41,w:1.1,h:1.1,fill:C.g900,radius:.3}),T('With Magoya',{x:69.7,y:41,w:20,h:2,s:1.2,b:true,c:C.g600}),\n  R({x:68,y:44,w:1.1,h:1.1,fill:C.g300,radius:.3}),T('Baseline forecast',{x:69.7,y:44,w:22,h:2,s:1.2,b:true,c:C.g600})]);};"
  },
  {
   "id": "D4",
   "nombre": "Donut + barras de progreso (sage)",
   "cuando_usarlo": "una proporción principal más dos o tres avances secundarios. El donut lleva la cifra adentro; una sola barra va en lima.",
   "layout_src": "SPEC.D4=function(p){\n  var s=[bg(C.sage)].concat(chrome(p),[\n    T('Discovery outcomes, quantified',{x:7.5,y:11.5,w:60,h:7,s:4.2,b:true,tight:true}),\n    CH({type:'doughnut',x:6,y:22,w:24,h:24,\n      data:[{name:'Validated',labels:['Validated','Open'],values:[68,32]}],\n      opts:{holeSize:62,chartColors:[C.g900,C.g200],dataLabelFormatCode:' '}}),\n    T('68%',{x:11.6,y:31.5,w:13,h:5,s:3.4,b:true,al:'center',tight:true}),\n    T('validated',{x:11.6,y:36,w:13,h:2.4,s:1.15,b:true,al:'center',c:C.g600}),\n    T('Of 25 hypotheses raised in a 6-week paid discovery, two thirds survived contact with real operations.',\n      {x:34,y:21,w:38,h:8,s:1.75,c:C.g800,lh:1.45})]);\n  var d=[['Hypotheses validated in the field','68%',68,0],['Flows reworked after grower testing','44%',44,0],['Scope removed before build','31%',31,1]];\n  d.forEach(function(r,i){var y=30+i*6.4,w=52;\n    s.push(T(r[0],{x:34,y:y,w:38,h:2.4,s:1.35,b:true}));\n    s.push(T(r[1],{x:74,y:y,w:18,h:2.4,s:1.35,b:true,c:C.g600,al:'right'}));\n    s.push(R({x:34,y:y+3,w:w+6,h:1,fill:C.g200,radius:.5}));\n    s.push(R({x:34,y:y+3,w:(w+6)*r[2]/100,h:1,fill:r[3]?C.lime:C.g900,radius:.5}));});\n  return s;};\n\n/* --- E · listas & tablas --- */;"
  },
  {
   "id": "E1",
   "nombre": "Lista numerada con fila destacada (lima)",
   "cuando_usarlo": "secuencias de 4 a 5 pasos. La fila en lima es el paso donde está el cliente hoy — se mueve según la conversación.",
   "layout_src": "SPEC.E1=function(p){return [bg(C.w)].concat(chrome(p),[\n  T('The Magoya method',{x:7.5,y:14,w:32,h:16,s:5.6,b:true,tight:true,lh:1.05})],\n  rowsBlock(44,14,48.5,[{n:'1',t:'Discover — immersion in your product, market and users.'},\n    {n:'2',t:'Align — one plan, shared metrics, no surprises.'},\n    {n:'3',t:'Execute — the embedded senior pod ships and iterates.'},\n    {n:'4',t:'Learn — measure in the field, evolve the roadmap.'}],2));};"
  },
  {
   "id": "E2",
   "nombre": "Checklist en dos columnas",
   "cuando_usarlo": "argumentos de diferenciación. Tres ítems por columna como máximo, cada uno de una línea. El check va en verde digital.",
   "layout_src": "SPEC.E2=function(p){\n  var s=[bg(C.sage)].concat(chrome(p),[T('Why teams choose Magoya',{x:7.5,y:11.5,w:70,h:7,s:4.4,b:true,tight:true})]);\n  var g=[{h:'Domain expertise',l:['We work only in agribusiness, and have since 2017.','Agronomists sitting next to engineers.','Fluency with grower and retail workflows.']},\n         {h:'Proven methodology',l:['A collaborative path from discovery to launch.','Senior pods assembled around your product.','Results that outlast the roadmap.']}];\n  g.forEach(function(c,i){var x=7.5+i*43.5,y=21,w=41.5,h=28.2;\n    s.push(card(x,y,w,h,C.w,C.hair));\n    s.push(T(c.h,{x:x+2.2,y:y+2.2,w:w-4.4,h:4,s:2.1,b:true,tight:true}));\n    c.l.forEach(function(t,j){s=s.concat(checkLine(x+2.2,y+8+j*5.6,w-4.4,t));});});\n  return s;};"
  },
  {
   "id": "E3",
   "nombre": "Tabla comparativa de scope — Lean vs Recommended",
   "cuando_usarlo": "primera de las dos slides de escenarios de inversión:",
   "layout_src": "SPEC.E3=function(p){\n  var s=[bg(C.w)].concat(chrome(p),[\n    T('Two ways to staff this',{x:7.5,y:11.5,w:46,h:7,s:4,b:true,tight:true})],\n    chip(70,12,'Scenario 1 of 2 · scope',C.em7,22.5));\n  var rows=[[{text:'Role in the pod'},{text:'Lean'},{text:'Recommended'},{text:'What changes'}],\n    ['Engagement lead','0.2','0.5','Weekly steering instead of monthly.'],\n    ['Product designer','0.5','1.0','Field research runs in parallel with build.'],\n    ['Senior engineers','2.0','3.0','Two workstreams instead of one queue.'],\n    ['Data & AI engineer','—','1.0','Agronomic models enter the MVP, not phase 2.'],\n    ['Agronomist','0.2','0.5','Validation on real operations every sprint.'],\n    ['QA','0.3','0.5','Regression coverage before each season.'],\n    ['Total FTE','3.2','6.5','Recommended halves time-to-field.']];\n  var trows=rows.map(function(r,i){\n    var head=i===0,tot=i===rows.length-1;\n    return r.map(function(cell,j){\n      var txt=(typeof cell==='object')?cell.text:cell;\n      return {text:txt,options:{\n        bold:head||tot||j===0,fontSize:FS(head?1.2:(tot?1.7:1.5)),\n        color:head?C.g600:C.ink,align:(j===1||j===2)?'center':'left',\n        fill:(j===2)?(tot?C.lime:C.sage):undefined,\n        valign:'middle',margin:[6,8,6,8]}};});});\n  s.push({k:'tb',x:7.5,y:21,w:85,rows:trows,\n    opts:{colW:[IN(26),IN(11),IN(15),IN(33)],rowH:IN(3.9),\n      border:[{type:'none'},{type:'none'},{type:'solid',color:C.hair,pt:.5},{type:'none'}]}});\n  return s;};"
  },
  {
   "id": "E4",
   "nombre": "Escenarios de inversión — timing + números",
   "cuando_usarlo": "segunda slide de escenarios:",
   "layout_src": "SPEC.E4=function(p){\n  var s=[bg(C.w)].concat(chrome(p),[\n    T('Timing and investment',{x:7.5,y:11.5,w:46,h:7,s:4,b:true,tight:true})],\n    chip(69,12,'Scenario 2 of 2 · numbers',C.em7,23.5));\n  var d=[{h:'Lean',f:'3.2 FTE',n:[['9','months to MVP'],['1','workstream'],['Q3','first field season']],ft:'Phase 2 required for data & AI',dk:0},\n         {h:'Recommended',f:'6.5 FTE',n:[['5','months to MVP'],['2','workstreams'],['Q1','first field season']],ft:'Data & AI included from sprint 1',dk:1}];\n  d.forEach(function(c,i){var x=7.5+i*43.5,y=20.5,w=41.5,h=17.5;\n    s.push(card(x,y,w,h,c.dk?C.g900:C.sage,null));\n    s.push(T(c.h,{x:x+2.2,y:y+2,w:24,h:4,s:2.1,b:true,tight:true,c:c.dk?C.cr50:C.ink}));\n    s.push(T(c.f,{x:x+w-14,y:y+2.6,w:12,h:3,s:1.45,c:c.dk?C.cr300:C.g600,al:'right'}));\n    c.n.forEach(function(v,j){var vx=x+2.2+j*12.6;\n      s.push(T(v[0],{x:vx,y:y+7.6,w:12,h:4,s:3.4,b:true,tight:true,c:c.dk?C.cr50:C.ink}));\n      s.push(T(v[1],{x:vx,y:y+11.6,w:11.5,h:3.5,s:1.2,c:c.dk?C.cr300:C.g600,lh:1.2}));});\n    s.push(T(c.ft,{x:x+2.2,y:y+h-3.2,w:w-4.4,h:2.6,s:1.4,b:true,c:c.dk?C.lime:C.ink}));});\n  return s.concat(timeline(7.5,42,85,[{b:'Kick-off',s:'Week 0'},{b:'Discovery closed',s:'Week 6'},\n    {b:'MVP in the field',s:'Month 5 · recommended'},{b:'MVP in the field',s:'Month 9 · lean'},\n    {b:'Season review',s:'Month 12'}],2));};\n\n/* --- F · proceso --- */;"
  },
  {
   "id": "F1",
   "nombre": "Timeline horizontal de 5 etapas (etapa activa en lima)",
   "cuando_usarlo": "mostrar dónde arranca y dónde termina el trabajo. Cinco hitos como máximo; el nodo lima es el que se está negociando.",
   "layout_src": "SPEC.F1=function(p){return [bg(C.w)].concat(chrome(p),[\n  T('From discovery to the field',{x:7.5,y:12,w:70,h:7,s:4.4,b:true,tight:true})],\n  timeline(7.5,30,85,[{b:'Discovery',s:'Immersion, users, constraints'},{b:'Ideation',s:'Concepts and priorities'},\n    {b:'Prototyping',s:'Tested with real growers'},{b:'MVP',s:'Ship the core loop'},\n    {b:'Scaling',s:'Evolve with the seasons'}],2));};"
  },
  {
   "id": "F2",
   "nombre": "Método en 4 columnas — Discover · Align · Execute · Learn",
   "cuando_usarlo": "explicar el método propio con una frase por fase. La fase Execute lleva el golpe de lima porque es donde vive el equipo embebido.",
   "layout_src": "SPEC.F2=function(p){\n  var s=[bg(C.sage)].concat(chrome(p),[T('How the work runs',{x:7.5,y:11.5,w:70,h:7,s:4.4,b:true,tight:true})]);\n  var d=[['Phase 01','Discover','Immersion in the product, the market and the people who use it in the field.',0],\n         ['Phase 02','Align','One plan, shared metrics and a scope both teams can defend.',0],\n         ['Phase 03','Execute','The embedded senior pod ships in your rituals, with your definition of done.',1],\n         ['Phase 04','Learn','Measure on real operations and feed the next season’s roadmap.',0]];\n  d.forEach(function(c,i){var x=7.5+i*21.8,y=21,w=20.2,h=28.2;\n    s.push(card(x,y,w,h,C.w,C.hair));\n    if(c[3])s.push(R({x:x,y:y,w:w,h:.5,fill:C.lime}));\n    s.push(T(c[0].toUpperCase(),{x:x+1.8,y:y+2.2,w:w-3.6,h:2.2,s:1.15,b:true,c:C.g600,cs:1.3}));\n    s.push(T(c[1],{x:x+1.8,y:y+5,w:w-3.6,h:4,s:1.9,b:true,tight:true}));\n    s.push(T(c[2],{x:x+1.8,y:y+9.5,w:w-3.6,h:14,s:1.4,c:C.g600,lh:1.35}));});\n  return s;};"
  },
  {
   "id": "F3",
   "nombre": "Journey de actores y plataformas (swimlanes)",
   "cuando_usarlo": "mostrar la interacción entre personas y sistemas. Un carril por actor, una etapa por columna, celdas vacías cuando el actor no participa. Nunca llenar la grilla entera: eso es el \"bingo\" que hay que evitar.",
   "layout_src": "SPEC.F3=function(p){\n  var s=[bg(C.w)].concat(chrome(p),[T('One recommendation, four hands',{x:7.5,y:11.5,w:70,h:7,s:3.9,b:true,tight:true})]);\n  var lw=13,gap=.7,cw=(85-lw-gap*4)/4, x0=7.5+lw+gap;\n  s.push(T('FIELD SIGNAL',{x:x0,y:19,w:cw,h:2,s:1.05,b:true,c:C.em7,cs:1}));\n  s.push(T('DECISION',{x:x0+2*(cw+gap),y:19,w:cw,h:2,s:1.05,b:true,c:C.em7,cs:1}));\n  s.push(T('ACTION',{x:x0+3.4*(cw+gap),y:19,w:cw,h:2,s:1.05,b:true,c:C.em7,cs:1,al:'right'}));\n  s.push(R({x:x0,y:20.2,w:85-lw-gap,h:.18,fill:C.g300}));\n  var lanes=[['Grower',[['Flags a problem from the cab, offline',0],['Waits',2],['Reviews the recommendation on WhatsApp',0],['Applies it and confirms in one tap',3]]],\n             ['Agronomist',[['Notified',2],['Validates against the field history',0],['Signs off or adjusts the dose',0],['Audits the outcome',2]]],\n             ['Platform',[['Syncs when signal returns',1],['Runs the agronomic model',1],[\"Delivers to the grower's channel\",1],['Logs the applied action',1]]],\n             ['Magoya pod',[['Instruments the event',2],['Tunes the model with agronomy',2],['Tests the channel with real users',2],['Reads adoption weekly',2]]]];\n  lanes.forEach(function(ln,r){var y=22+r*6.6;\n    s.push(T(ln[0].toUpperCase(),{x:7.5,y:y+1.6,w:lw-1,h:3,s:1.15,b:true,c:C.g600,cs:1}));\n    ln[1].forEach(function(cell,ci){var cx=x0+ci*(cw+gap),kind=cell[1];\n      s.push(R({x:cx,y:y,w:cw,h:6,fill:kind===1?C.g900:(kind===3?C.lime:C.w),\n        line:kind===0?C.hair:(kind===2?C.g300:null),lw:.75,radius:.8}));\n      s.push(T(cell[0],{x:cx+1,y:y+.9,w:cw-2,h:4.4,s:1.25,c:kind===1?C.cr50:(kind===2?C.g600:C.ink),\n        b:kind===3,lh:1.28}));});});\n  return s;};"
  },
  {
   "id": "F4",
   "nombre": "Artefactos de proceso (wireframe · prototipo · output de discovery)",
   "cuando_usarlo": "cuando hay que mostrar",
   "layout_src": "SPEC.F4=function(p){\n  var s=[bg(C.sage)].concat(chrome(p),[T('What comes out of a discovery',{x:7.5,y:11.5,w:70,h:7,s:4.2,b:true,tight:true})]);\n  var caps=['01 · Wireframes','02 · Clickable prototype','03 · Prioritised backlog'];\n  for(var i=0;i<3;i++){var x=7.5+i*29.5,y=21,w=27,h=28.2;\n    s.push(card(x,y,w,h,C.w,C.hair));\n    s.push(R({x:x,y:y,w:w,h:2.4,fill:C.g100}));\n    for(var k=0;k<3;k++)s.push(R({x:x+1.2+k*1.2,y:y+.9,w:.65,h:.65,fill:C.g300,radius:.32}));\n    if(i===0){s.push(R({x:x+1.6,y:y+4,w:16,h:1.7,fill:C.g200,radius:.3}));\n      s.push(R({x:x+1.6,y:y+6.6,w:w-3.2,h:5.4,fill:C.g100,radius:.3}));\n      s.push(R({x:x+1.6,y:y+13,w:19,h:.9,fill:C.g200,radius:.3}));\n      s.push(R({x:x+1.6,y:y+14.6,w:10,h:.9,fill:C.g200,radius:.3}));}\n    else if(i===1){s.push(R({x:x+1.6,y:y+4,w:16,h:1.7,fill:C.g900,radius:.3}));\n      s.push(R({x:x+1.6,y:y+6.6,w:(w-4)/2,h:5.4,fill:C.g100,radius:.3}));\n      s.push(R({x:x+2.4+(w-4)/2,y:y+6.6,w:(w-4)/2,h:5.4,fill:C.lime,radius:.3}));\n      s.push(R({x:x+1.6,y:y+13,w:19,h:.9,fill:C.g200,radius:.3}));}\n    else{s.push(R({x:x+1.6,y:y+4,w:16,h:1.7,fill:C.g200,radius:.3}));\n      [0,1,2,3,4].forEach(function(k){s.push(R({x:x+1.6,y:y+6.8+k*2,w:(k%2?18:w-3.2),h:.9,fill:C.g200,radius:.3}));});}\n    s.push(T(caps[i],{x:x+1.6,y:y+h-3.4,w:w-3.2,h:2.4,s:1.15,b:true,c:C.g600,cs:1}));}\n  return s;};\n\n/* --- G · casos de éxito --- */;"
  },
  {
   "id": "G1",
   "nombre": "Caso estructurado — challenge · team · adaptation · results",
   "cuando_usarlo": "el caso de éxito canónico. Los chips dejan visibles el",
   "layout_src": "SPEC.G1=function(p){\n  var s=[bg(C.w)].concat(chrome(p),[\n    IMG({src:CL+'bunge.svg',x:7.5,y:11.5,w:12,h:4,fit:'contain',gray:true})],\n    chip(22,11.8,'Company challenge · fragmented grower data',C.ink,32),\n    chip(56,11.8,'Urgent need · one season to launch',C.em7,26),[\n    T('Six data sources, one decision screen for the agronomist.',{x:7.5,y:18.5,w:62,h:10,s:3.7,b:true,tight:true,lh:1.12})]);\n  var d=[['Challenge','Grower data lived in six systems. Agronomists rebuilt the same picture by hand every week.',0],\n         ['Team','Embedded pod of 6: engagement lead, designer, three engineers and one agronomist.',0],\n         ['Adaptation','We joined their rituals and their QA gates, and moved AI into sprint 1 instead of phase 2.',0],\n         ['Results','',1]];\n  d.forEach(function(c,i){var x=7.5+i*21.8,y=31,w=20.2;\n    s.push(R({x:x,y:y,w:w,h:.42,fill:c[2]?C.lime:C.ink}));\n    s.push(T(c[0].toUpperCase(),{x:x,y:y+1.6,w:w,h:2.2,s:1.1,b:true,c:C.g600,cs:1}));\n    if(c[2]){\n      s.push(T([{text:'8×',options:{}}],{x:x,y:y+4.4,w:w,h:4,s:3,b:true,tight:true}));\n      s.push(T('faster time-to-field',{x:x,y:y+8,w:w,h:2.4,s:1.26,b:true,c:C.g600}));\n      s.push(T('3k',{x:x,y:y+11,w:w,h:4,s:3,b:true,tight:true}));\n      s.push(T('monthly active users',{x:x,y:y+14.6,w:w,h:2.4,s:1.26,b:true,c:C.g600}));\n    } else s.push(T(c[1],{x:x,y:y+4.4,w:w,h:12,s:1.32,lh:1.4}));});\n  return s;};"
  },
  {
   "id": "G2",
   "nombre": "Caso en resultados — antes / después",
   "cuando_usarlo": "variante corta del caso, para cuando el deck ya explicó el contexto. Se usa alternada con G1 para que dos casos seguidos no se vean iguales.",
   "layout_src": "SPEC.G2=function(p){\n  var s=[bg(C.sage)].concat(chrome(p),[\n    IMG({src:CL+'precision-planting.svg',x:7.5,y:11.5,w:14,h:4,fit:'contain',gray:true})],\n    chip(24,11.8,'Urgent need · planting window in 11 weeks',C.ink,31),[\n    T('From a spreadsheet ritual to a planting plan the crew trusts.',{x:7.5,y:18.5,w:58,h:10,s:3.7,b:true,tight:true,lh:1.12})]);\n  var d=[['Before','6 days','to close a planting plan across 40 fields',C.ink],\n         ['After 11 weeks','4 hours','same 40 fields, same two agronomists',C.em7],\n         ['Held for','3','consecutive seasons without extra headcount',C.ink]];\n  d.forEach(function(c,i){var x=7.5+i*29.5;\n    s.push(T(c[0].toUpperCase(),{x:x,y:31,w:26,h:2.2,s:1.15,b:true,c:C.g600,cs:1}));\n    s.push(T(c[1],{x:x,y:34,w:26,h:7,s:6.4,b:true,tight:true,c:c[3],lh:.95}));\n    s.push(T(c[2],{x:x,y:41.5,w:25,h:6,s:1.4,c:C.g600,lh:1.3}));});\n  s.push(T('→',{x:33.5,y:35,w:6,h:5,s:3,b:true,c:C.g300}));\n  s.push(rule(7.5,47.5,14));return s;};\n\n/* --- H · fotografía --- */;"
  },
  {
   "id": "H1",
   "nombre": "Foto a sangre a la izquierda + texto a la derecha",
   "cuando_usarlo": "abrir un bloque de contexto de mercado. La foto va a sangre por tres bordes y el texto respira en el lienzo blanco — nunca texto encima de la foto en esta variante.",
   "layout_src": "SPEC.H1=function(p){return [bg(C.w),\n  IMG({src:PH+'field-terraces.jpg',x:0,y:0,w:44,h:56.25,fit:'cover'})].concat(chrome(p,false,48),[\n  T('MARKET CONTEXT',{x:51,y:16,w:40,h:2.6,s:1.5,b:true,c:C.em7,cs:1.8}),\n  T('Every region is a different product problem.',{x:51,y:20.5,w:41,h:13,s:3.7,b:true,tight:true,lh:1.12}),\n  T('Terraces, centre pivots and rainfed lots do not share a workflow. We design for the operation in front of us, then generalise — not the other way round.',\n    {x:51,y:34,w:41,h:11,s:1.75,c:C.g800,lh:1.45})],\n  chip(51,46.5,'10 countries · 21 domains',C.em7,24));};"
  },
  {
   "id": "H2",
   "nombre": "Foto a sangre a la derecha + texto a la izquierda (sage)",
   "cuando_usarlo": "el espejo de H1, para alternar ritmo cuando hay dos slides de foto seguidas. Lienzo sage para diferenciarla.",
   "layout_src": "SPEC.H2=function(p){return [bg(C.sage),\n  IMG({src:PH+'field-corn.jpg',x:56,y:0,w:44,h:56.25,fit:'cover'})].concat(chrome(p,false,7.5),[\n  T('FIELD FIRST',{x:7.5,y:16,w:40,h:2.6,s:1.5,b:true,c:C.em7,cs:1.8}),\n  T('Software that survives dust, gloves and no signal.',{x:7.5,y:20.5,w:41,h:13,s:3.7,b:true,tight:true,lh:1.12}),\n  T('Every release is tested on a real operation before it ships. If it does not work at 6am with one bar of signal, it does not work.',\n    {x:7.5,y:34,w:41,h:10,s:1.75,c:C.g800,lh:1.45}),\n  rule(7.5,46.5,14)]);};"
  },
  {
   "id": "H3",
   "nombre": "Foto de fondo completo + scrim verde + statement",
   "cuando_usarlo": "statement de impacto a mitad de deck. El scrim verde profundo 55→86% es obligatorio cuando hay texto encima; es el único degradado permitido.",
   "layout_src": "SPEC.H3=function(p){return [bg(C.g950),\n  IMG({src:PH+'field-bali.jpg',x:0,y:0,w:100,h:56.25,fit:'cover'}),\n  R({x:0,y:0,w:100,h:56.25,fill:C.g950,alpha:28})].concat(chrome(p,true),[\n  T('The planting window doesn’t move. Your release date does.',{x:7.5,y:29,w:62,h:14,s:5.6,b:true,c:C.cr50,tight:true,lh:1.05}),\n  T('We plan against the crop calendar. If a feature misses the window, it waits a year — so we ship what the season can use, then keep building.',\n    {x:7.5,y:43.5,w:46,h:7,s:1.75,c:C.cr100,lh:1.45})]);};"
  },
  {
   "id": "H4",
   "nombre": "Tira de 3 fotos + título",
   "cuando_usarlo": "mostrar rango geográfico o de cultivos sin caer en un collage. Tres aéreas, mismo alto, un rótulo por foto. Sin texto encima de las imágenes.",
   "layout_src": "SPEC.H4=function(p){\n  var s=[bg(C.w)].concat(chrome(p),[T('Ten countries, one product language',{x:7.5,y:11.5,w:58,h:11,s:4.2,b:true,tight:true,lh:1.08})]);\n  var ph=[['field-rows.jpg','Row crops · Argentina & Brazil'],['field-terraces.jpg','Terraced systems · Southeast Asia'],['field-corn.jpg','Corn belt · United States']];\n  ph.forEach(function(c,i){var x=7.5+i*28.7,w=27.3;\n    s.push(IMG({src:PH+c[0],x:x,y:23,w:w,h:20,fit:'cover'}));\n    s.push(T(c[1],{x:x,y:44,w:w,h:4,s:1.45,c:C.g600,lh:1.3}));});\n  return s;};\n\n/* --- I · ilustración --- */;"
  },
  {
   "id": "I1",
   "nombre": "Personaje + display al palo",
   "cuando_usarlo": "statement conceptual sin foto. El personaje se recorta contra el borde derecho, ocupa ~47% del ancho y va sobre lienzo plano —",
   "layout_src": "SPEC.I1=function(p){return [bg(C.w),\n  IMG({src:A+'illus/char-jumping.svg',x:57,y:7.5,w:48.7,h:50})].concat(chrome(p),[\n  T('CLARITY · CONFIDENCE · COMMITMENT',{x:7.5,y:26,w:48,h:2.6,s:1.5,b:true,c:C.em7,cs:1.8}),\n  T('Complexity in,\\na clear plan out.',{x:7.5,y:30.5,w:48,h:16,s:5.2,b:true,tight:true,lh:1.05})]);};"
  },
  {
   "id": "I2",
   "nombre": "Personaje a la izquierda + dato al palo (sage)",
   "cuando_usarlo": "espejo de I1 para alternar el lado. El texto siempre va del lado opuesto al personaje; la cifra hace de display.",
   "layout_src": "SPEC.I2=function(p){return [bg(C.sage),\n  IMG({src:A+'illus/char-chart-duo.svg',x:-6,y:8.25,w:40.3,h:48})].concat(chrome(p,false,44),[\n  T('21',{x:48,y:22,w:44.5,h:10,s:9,b:true,tight:true,al:'right',lh:.95}),\n  T('AgTech domains covered by the same team',{x:48,y:32.5,w:44.5,h:8,s:2.8,b:true,al:'right',lh:1.25}),\n  T('Agronomy, logistics, traceability, carbon, retail, crop protection and fifteen more.',\n    {x:56,y:42,w:36.5,h:6,s:1.45,c:C.g600,al:'right',lh:1.35})]);};\n\n/* --- J · personas --- */;"
  },
  {
   "id": "J1",
   "nombre": "Quote destacada en card (sage)",
   "cuando_usarlo": "testimonio con nombre y rol. La regla lima abajo del texto es el golpe de color; la card nunca lleva foto además del texto.",
   "layout_src": "SPEC.J1=function(){return [bg(C.sage),\n  card(21,10,58,36.5,C.w,null),\n  T('“Magoya’s expertise in UX, digital ag platform development and agronomic know-how, combined with their understanding of farmer and retail needs, made our transformation possible.”',\n    {x:24.2,y:13.2,w:51.6,h:16,s:2.2,b:true,lh:1.42}),\n  R({x:24.2,y:32,w:12,h:.65,fill:C.lime,radius:.32}),\n  T('Varina Baldi',{x:24.2,y:35.4,w:40,h:3,s:1.45,b:true}),\n  T('Founder & CEO',{x:24.2,y:38.2,w:40,h:3,s:1.45,c:C.g600})];};"
  },
  {
   "id": "J2",
   "nombre": "Quote sobre foto B&N + scrim",
   "cuando_usarlo": "cuando el testimonio tiene que poner cara. Retrato en B&amp;N a sangre, scrim verde profundo y la frase que carga el sentido en lima.",
   "layout_src": "SPEC.J2=function(p){return [bg(C.g950),\n  IMG({src:PH+'cami-agtech-bw.jpg',x:0,y:0,w:100,h:56.25,fit:'cover',gray:true}),\n  R({x:0,y:0,w:100,h:56.25,fill:C.g950,alpha:30})].concat(chrome(p,true),[\n  T('“They did not join to deliver a project. They joined to own the outcome with us.”',\n    {x:7.5,y:28,w:60,h:14,s:2.6,b:true,c:C.cr50,lh:1.38}),\n  R({x:7.5,y:42.6,w:24,h:.7,fill:C.lime,radius:.35}),\n  T('Camila López Colmano',{x:7.5,y:45,w:40,h:3,s:1.7,b:true,c:C.cr50}),\n  T('AgTech Expert',{x:7.5,y:47.8,w:40,h:3,s:1.45,c:C.cr300})]);};"
  },
  {
   "id": "J3",
   "nombre": "Equipo — retratos B&N + rol",
   "cuando_usarlo": "presentar el pod concreto de la propuesta, con nombre y rol reales. Los retratos van siempre en B&amp;N.",
   "layout_src": "SPEC.J3=function(p){\n  var s=[bg(C.w)].concat(chrome(p),[\n    T('The team you actually get',{x:7.5,y:11.5,w:44,h:8,s:4.2,b:true,tight:true}),\n    T('Named people, not a bench. The pod grows with agronomy and QA from the same team.',\n      {x:66,y:12,w:26,h:7,s:1.45,c:C.g600,lh:1.35})]);\n  var t=[['Varina Baldi','Founder & CEO','varu-baldi-bw.jpg'],['Francisco Facal','Solutions Architecture','varu-ceo-bw.jpg'],\n         ['Camila López Colmano','AgTech Expert','cami-agtech-bw.jpg']];\n  t.forEach(function(c,i){var x=7.5+i*29.5,w=26.9;\n    s.push(IMG({src:PH+c[2],x:x,y:18,w:w,h:26,fit:'cover',gray:true}));\n    s.push(T(c[0],{x:x,y:44.8,w:w,h:3,s:1.6,b:true,tight:true}));\n    s.push(T(c[1],{x:x,y:47.7,w:w,h:3,s:1.3,c:C.g600}));});\n  return s;};\n\n/* --- K · tecnología & AI --- */;"
  },
  {
   "id": "K1",
   "nombre": "Stack tecnológico por capa (logos reales en gris)",
   "cuando_usarlo": "validación técnica frente a un CTO. Logos reales de",
   "layout_src": "SPEC.K1=function(p){\n  var s=[bg(C.sage)].concat(chrome(p),[\n    T('The stack we work in',{x:7.5,y:11.5,w:50,h:7,s:4.2,b:true,tight:true})],\n    chip(65.5,12,'No new vendor to onboard',C.em7,27));\n  var cols=[['Product surfaces',['react.svg','nextjs.svg']],\n            ['Services & data',['nodejs.svg','django.svg','postgresql.svg','mongodb.svg']],\n            ['Cloud',['aws.svg','google-cloud.svg','azure.svg']],\n            ['Delivery & ML ops',['docker.svg','kubernetes.svg','terraform.svg','jupyter.svg']]];\n  cols.forEach(function(c,i){var x=7.5+i*21.8,y=21,w=20.2,h=26;\n    s.push(card(x,y,w,h,C.w,C.hair));\n    s.push(T(c[0].toUpperCase(),{x:x+1.6,y:y+2,w:w-3.2,h:3,s:1.15,b:true,c:C.g600,cs:1,lh:1.2}));\n    s=s.concat(logoRow(c[1].map(function(f){return PT+f;}),x+1.6,y+7,w-3.2,3.6,2,1.2,1.6));});\n  return s;};"
  },
  {
   "id": "K2",
   "nombre": "Capacidades de AI (logos de modelos + qué hacemos con ellos)",
   "cuando_usarlo": "cuando la conversación entra en AI y hay que ser explícito. Cada fila nombra una capacidad concreta, no \"AI-powered\". Los logos de",
   "layout_src": "SPEC.K2=function(p){\n  var s=[bg(C.w)].concat(chrome(p),[\n    T('What we ship with AI',{x:7.5,y:11.5,w:50,h:7,s:4.2,b:true,tight:true}),rule(82.5,13.5,10)]);\n  var d=[['openai.svg','Agronomic copilots',\"Conversational assistants over the client's own agronomy, in WhatsApp and in-product.\"],\n         ['anthropic.svg','Retrieval over field data','RAG on trial results, labels and protocols — answers with the source attached.'],\n         ['huggingface.svg','Vision on crop imagery','Disease and weed detection from phone, drone and satellite captures.'],\n         ['ollama.svg','On-premise inference','Local models when the data cannot leave the client’s environment.']];\n  d.forEach(function(c,i){var x=7.5+(i%2)*44,y=22+Math.floor(i/2)*13.5;\n    s.push(IMG({src:AI+c[0],x:x,y:y,w:2.8,h:2.8,fit:'contain'}));\n    s.push(T(c[1],{x:x+4.2,y:y-.2,w:36,h:3,s:1.7,b:true,tight:true}));\n    s.push(T(c[2],{x:x+4.2,y:y+3,w:36,h:7,s:1.3,c:C.g600,lh:1.35}));});\n  return s;};\n\n/* --- L · clientes --- */;"
  },
  {
   "id": "L1",
   "nombre": "Logo wall de clientes (12 logos, grilla pareja)",
   "cuando_usarlo": "prueba social después de la portada o antes del cierre. Logos",
   "layout_src": "SPEC.L1=function(p){\n  var s=[bg(C.w)].concat(chrome(p),[\n    T('Nine years inside agribusiness',{x:7.5,y:11.5,w:46,h:11,s:4.2,b:true,tight:true,lh:1.08}),\n    T('5+',{x:70,y:12,w:22.5,h:5,s:3.4,b:true,tight:true,al:'right'}),\n    T('years of average relationship',{x:66,y:16.6,w:26.5,h:3,s:1.4,c:C.g600,al:'right'})]);\n  var names=['apeel-sciences','bunge','corteva','syngenta','climate-fieldview','precision-planting',\n             'bayer-crop-science','indigo','gdm','biome-makers','sound-agriculture','xarvio'];\n  return s.concat(logoRow(names.map(function(n){return CL+n+'.svg';}),7.5,26,85,5,6,2.8,7));};\n\n/* --- M · portada & cierre --- */;"
  },
  {
   "id": "M1",
   "nombre": "Portada — aérea de campo + scrim verde",
   "cuando_usarlo": "portada por defecto. Wordmark crema arriba a la izquierda, chip de contexto a la derecha, display abajo. El scrim es obligatorio: sin él el texto no lee.",
   "layout_src": "SPEC.M1=function(){return [bg(C.g950),\n  IMG({src:PH+'field-rows.jpg',x:0,y:0,w:100,h:56.25,fit:'cover'}),\n  R({x:0,y:0,w:100,h:56.25,fill:C.g950,alpha:30}),\n  IMG({src:WMC,x:7.5,y:7,w:11,h:3.007})].concat(\n  chip(63.5,7,'Partnership proposal · 2026',C.cr100,29),[\n  T('Digital product\\ndevelopment\\nfor agribusiness',{x:7.5,y:24,w:60,h:22,s:6.8,b:true,c:C.cr50,tight:true,lh:1.02}),\n  T('We design, build and evolve the products and platforms that modern agribusinesses run on.',\n    {x:7.5,y:46.5,w:46,h:6,s:1.75,c:C.cr100,lh:1.45})]);};"
  },
  {
   "id": "M2",
   "nombre": "Portada alternativa — verde profundo + paño al corte",
   "cuando_usarlo": "cuando no hay una foto que aporte, o cuando el deck ya abre con foto y hace falta contraste. El paño nace del borde derecho y se corta contra él.",
   "layout_src": "SPEC.M2=function(){return [bg(C.g950),\n  IMG({src:A+'motif-semis.svg',x:70,y:0,w:30,h:56.25}),\n  IMG({src:WMC,x:7.5,y:7,w:11,h:3.007})].concat(\n  chip(63.5,7,'Partnership proposal · 2026',C.cr100,29),[\n  T('AgTech challenges demand more than code.',{x:7.5,y:24,w:58,h:22,s:6.8,b:true,c:C.cr50,tight:true,lh:1.02}),\n  T('Clarity, confidence and commitment — the three things a nine-year AgTech partnership is actually made of.',\n    {x:7.5,y:46.5,w:44,h:7,s:1.75,c:C.cr200,lh:1.45})]);};"
  },
  {
   "id": "M3",
   "nombre": "Cierre / next step con CTA + flecha a mano",
   "cuando_usarlo": "última slide, siempre. Tres próximos pasos concretos con fecha y un solo CTA. La flecha a mano nace del texto y su punta cae sobre el botón — una sola marca por slide.",
   "layout_src": "SPEC.M3=function(p){return [bg(C.sage)].concat(chrome(p),[\n  T('Next step:\\na paid discovery.',{x:7.5,y:13,w:42,h:14,s:4.6,b:true,tight:true,lh:1.05}),\n  T('Six weeks, fixed price, a working prototype and a prioritised backlog at the end. If we are not the right partner after that, you keep everything.',\n    {x:7.5,y:27,w:36,h:11,s:1.75,c:C.g800,lh:1.45}),\n  R({x:7.5,y:41,w:32,h:5.2,fill:C.lime,radius:.75}),\n  T('Book the discovery kickoff',{x:7.5,y:41,w:32,h:5.2,s:1.7,b:true,al:'center',va:'middle'})],\n  rowsBlock(48,13,44.5,[{n:'01',t:'This week — scope call with your product lead'},\n    {n:'02',t:'Week 2 — discovery kickoff with the embedded pod'},\n    {n:'03',t:'Week 8 — prototype, backlog and staffing decision'},\n    {n:'04',t:'Q1 — first release in the field'}],-1,C.em7));};\n\n/* ---------- 9. driver de export ---------- */\nvar PPTX_CDN='https://cdn.jsdelivr.net/npm/pptxgenjs@3.12.0/dist/pptxgen.bundle.js';\nvar libP=null;\nfunction lib(){\n  if(libP)return libP;\n  libP=new Promise(function(res,rej){\n    if(window.PptxGenJS)return res(window.PptxGenJS);\n    var sc=document.createElement('script');sc.src=PPTX_CDN;\n    sc.onload=function(){window.PptxGenJS?res(window.PptxGenJS):rej(new Error('PptxGenJS no cargó'));};\n    sc.onerror=function(){rej(new Error('no se pudo cargar PptxGenJS desde el CDN'));};\n    document.head.appendChild(sc);\n  });\n  return libP;\n}\nfunction buildDeck(ids){\n  return lib().then(function(Lib){\n    var pptx=new Lib();\n    pptx.defineLayout({name:'MAGOYA16x9',width:SW,height:SH});\n    pptx.layout='MAGOYA16x9';\n    pptx.author='Magoya';pptx.company='Magoya';pptx.title='Magoya · Deck kit';\n    var chain=Promise.resolve();\n    ids.forEach(function(id,i){\n      chain=chain.then(function(){\n        var fn=SPEC[id];\n        if(!fn){console.warn('[deck-kit] sin spec para',id);return;}\n        var shapes=fn(String(i+3).padStart(2,'0'));\n        var sl=pptx.addSlide();\n        return paint(pptx,sl,shapes);\n      });\n    });\n    return chain.then(function(){return pptx;});\n  });\n};"
  }
 ],
 "fuente_de_verdad": "https://brand.magoya.com/slides.html"
}