65 lines
18 KiB
Python
65 lines
18 KiB
Python
from pathlib import Path
|
||
import html
|
||
O=Path('/Users/adolforeyna/brain/exports')
|
||
# Original illustration system: cut-paper community scenes, not stock imagery.
|
||
ink='#172b45'; blue='#2851bf'; cream='#f7f2e7'; yellow='#f3c653'; coral='#e57550'; green='#507969'
|
||
def person(x,y,s=1,shirt=blue,skin='#bb7953',hair=ink,pose='open'):
|
||
arms = '<path d="M-36 105 Q-66 142 -102 121 M37 104 Q65 136 104 100"/>' if pose=='open' else '<path d="M-35 107 L-62 158 L5 173 M36 106 L67 152 L18 168"/>'
|
||
return f'''<g transform="translate({x} {y}) scale({s})"><path d="M-29 172 L-32 265 L-61 267 M28 172 L39 265 L69 268" stroke="{ink}" stroke-width="23" fill="none" stroke-linecap="round"/><path d="M-43 96 Q0 76 44 97 L55 190 Q0 207 -53 187Z" fill="{shirt}"/><g fill="none" stroke="{skin}" stroke-width="19" stroke-linecap="round">{arms}</g><path d="M-10 60 L-10 92 Q2 104 13 90 L12 59" fill="{skin}"/><path d="M-28 12 Q-35 47 -19 66 Q8 86 30 52 L31 15Z" fill="{skin}"/><path d="M-31 34 Q-50 -15 -9 -23 Q33 -35 39 12 L28 29 L20 1 Q-1 21 -31 16Z" fill="{hair}"/><path d="M6 32 L3 46 L12 46 M-9 55 Q3 61 14 54" stroke="{ink}" stroke-width="2.5" fill="none"/><path d="M-17 31 L-11 31 M15 30 L21 30" stroke="{ink}" stroke-width="3"/><path d="M-26 116 L-22 172 M25 119 L31 173" stroke="{cream}" opacity=".4" stroke-width="3"/></g>'''
|
||
def plant(x,y,s=1):
|
||
return f'<g transform="translate({x} {y}) scale({s})"><path d="M0 0 L5 -160 M3 -65 Q-77 -81 -65 -136 Q-4 -135 3 -65 M4 -106 Q64 -116 67 -179 Q8 -174 4 -106" fill="{green}" stroke="{green}" stroke-width="6"/><path d="M-40 -12 L-27 58 L34 58 L47 -12Z" fill="{coral}"/><path d="M-29 0 L36 0" stroke="{cream}" stroke-width="5"/></g>'
|
||
def house(x,y,w,h,c):
|
||
return f'<g><path d="M{x} {y+h}V{y+45}L{x+w/2} {y}L{x+w} {y+45}V{y+h}Z" fill="{c}" stroke="{ink}" stroke-width="3"/><path d="M{x-8} {y+49}L{x+w/2} {y-6}L{x+w+9} {y+49}" stroke="{ink}" stroke-width="12" fill="none"/><path d="M{x+w*.43} {y+h}V{y+h-92}Q{x+w*.58} {y+h-114} {x+w*.72} {y+h-92}V{y+h}" fill="{ink}"/><rect x="{x+w*.14}" y="{y+65}" width="{w*.22}" height="44" fill="{cream}" stroke="{ink}" stroke-width="3"/><path d="M{x+w*.25} {y+65}V{y+109}" stroke="{ink}" stroke-width="5"/></g>'
|
||
def svg(scene):
|
||
p=[]
|
||
if scene in ['family','street']:
|
||
p += [f'<path d="M0 460 Q170 337 370 465 T900 423V900H0Z" fill="{yellow}"/>',house(30,180,220,280,coral),house(260,80,275,380,cream),house(558,160,265,325,green)]
|
||
p += ['<path d="M307 100 L490 100 M296 119 L501 119 M286 138 L510 138" stroke="#172b45" stroke-width="4" opacity=".25"/>']
|
||
p += [person(155,445,1.0,blue,'#d9a77d',ink),person(390,375,1.15,cream,'#825438',ink,'book'),person(648,430,1.06,coral,'#b77a54',ink),person(525,561,.68,green,'#d9a77d',ink,'book'),plant(790,720,.8)]
|
||
p += [f'<path d="M0 855 Q366 785 900 843" fill="none" stroke="{ink}" stroke-width="3"/>']
|
||
elif scene in ['table','gather']:
|
||
p += [f'<path d="M90 620V190Q90 70 220 70H704V620" stroke="{coral}" stroke-width="38" fill="none"/>',f'<path d="M140 210H655 M510 80V467" stroke="{yellow}" stroke-width="9"/>']
|
||
p += [person(205,278,.98,green,'#bb7953',ink),person(418,214,1.15,cream,'#825438','#ddd9c9','book'),person(670,290,1.0,coral,'#d9a77d',ink)]
|
||
p += [f'<path d="M99 555 L729 555 L824 659 L37 659Z" fill="{yellow}"/><path d="M96 659L83 854 M750 659L775 854" stroke="{ink}" stroke-width="29"/><path d="M320 591 L406 568 L492 593 L413 620Z" fill="{cream}"/><path d="M406 570 L413 619" stroke="{ink}" stroke-width="3"/><path d="M560 585h39v36h-39Z M568 575v-14" stroke="{ink}" fill="{coral}" stroke-width="4"/>',plant(848,771,.66)]
|
||
elif scene=='mentor':
|
||
p += [f'<path d="M37 817H882V685H662V555H433V425H208V300H37Z" fill="{yellow}"/>']
|
||
p += [person(237,202,1.43,cream,'#bb7953','#ddd9c9'),person(611,312,1.26,coral,'#d9a77d',ink,'book')]
|
||
p += [f'<path d="M348 372Q430 270 518 354" fill="none" stroke="{cream}" stroke-width="8" stroke-dasharray="7 11"/>',plant(815,806,.7)]
|
||
elif scene=='service':
|
||
p += [house(140,80,620,645,cream),f'<path d="M164 297H739L704 219H198Z" fill="{coral}"/><path d="M240 220L221 297 M327 220L317 297 M417 220V297 M507 220L517 297 M594 220L614 297 M674 220L703 297" stroke="{cream}" stroke-width="20"/><rect x="205" y="330" width="472" height="297" fill="{yellow}"/>']
|
||
p += [person(342,355,1.05,blue,'#825438',ink,'book'),person(586,416,.85,green,'#d9a77d',ink)]
|
||
p += [f'<rect x="180" y="609" width="529" height="146" fill="{coral}"/><path d="M441 640V720 M401 680H481" stroke="{cream}" stroke-width="22"/>',plant(100,765,.75)]
|
||
elif scene=='door':
|
||
p += [f'<path d="M151 812V200Q151 78 352 78H675V812Z" fill="{yellow}"/><path d="M202 812V229Q202 130 374 130H620V812Z" fill="{blue}"/><path d="M620 130L809 209V844L620 810Z" fill="{coral}"/><path d="M658 426V469" stroke="{cream}" stroke-width="10"/>']
|
||
p += [person(430,313,1.46,cream,'#bb7953',ink),plant(120,778,.85)]
|
||
if scene=='gather':
|
||
p=[house(35,112,265,300,coral),house(533,73,288,330,green),f'<path d="M93 710Q422 400 793 723" stroke="{cream}" stroke-width="72" fill="none"/>',person(204,451,1.04,blue,'#bb7953',ink),person(454,355,1.12,cream,'#825438','#ddd9c9'),person(699,472,1.03,coral,'#d9a77d',ink,'book'),plant(90,820,.65)]
|
||
# Signature etched marks, consistent throughout illustrations.
|
||
p += [f'<path d="M50 868H830 M60 880H700" stroke="{ink}" stroke-width="3" opacity=".28"/>']
|
||
return '<svg viewBox="0 0 900 900" xmlns="http://www.w3.org/2000/svg" aria-label="Original symbolic illustration of '+scene+'; not a documentary depiction">'+''.join(p)+'</svg>'
|
||
slides=[]
|
||
def slide(kicker,content,cls=''):
|
||
n=len(slides)+1
|
||
slides.append(f'<section class="slide {cls}" id="slide-{n}"><div class="eyebrow">EMI / LATIN AMERICA <span>{kicker}</span></div>{content}<footer><span>VISION & MISSION · 2026</span><span>{n:02d} / 11</span></footer></section>')
|
||
def art(scene,style=''):
|
||
return '<div class="art" style="'+style+'">'+svg(scene)+'</div>'
|
||
def note(t):return '<div class="note">'+t+'</div>'
|
||
slide('A FAMILY SENT TO ESTABLISH', '<div class="covercopy"><div class="smalltag">ONE VISION. A SHARED CALLING.</div><h1>Not just<br>a visit.<br><em>A family<br>that remains.</em></h1><p>Establishing the Kingdom and family of God<br>among every people in Latin America.</p></div>'+art('family'),'cover')
|
||
slide('01 / THE VISION', '<div class="wide"><div class="smalltag">WHAT WE LONG TO SEE ESTABLISHED</div><h1>Every nation.<br>Every people.<br><em>The Kingdom and<br>family of God.</em></h1><p class="lead">Every <i>ethnos</i> in Latin America—not only the<br>places and people we already know.</p></div><div class="commission"><div class="smalltag">ROOTED IN MATTHEW 28:18–20</div><h2>Go.<br>Make disciples.<br>Baptize.<br>Teach obedience.</h2><p>More than building churches.<br>More than a short evangelistic visit.</p><div class="rule"></div><p class="fine">A summary of the source’s reading<br>of the Great Commission.</p></div>','blue')
|
||
slide('02 / THE MISSION', '<div class="copy"><div class="smalltag">HOW WE CARRY THE VISION</div><h1>Work together.<br><em>Establish<br>what lasts.</em></h1><p class="lead">A cohesive regional company.<br>A spiritual family with shared responsibility.</p><ul class="plain"><li>Prayer and shared spiritual life</li><li>Relationships, fellowship and presence</li><li>Discipleship and leadership development</li><li>Practical service and shared resources</li></ul></div>'+art('table'),'light')
|
||
slide('03 / FROM CONTACT TO COMMITMENT', '<div class="wide"><h1>Evangelism is essential.<br><em>Establishment is the aim.</em></h1></div><div class="journey"><div><b>01</b><h2>Go beyond<br>the familiar.</h2><p>Seek new relationships, believers<br>and works where a foundation<br>does not yet exist.</p></div><div><b>02</b><h2>Build into<br>people’s lives.</h2><p>Make disciples. Develop leaders.<br>Form relationships and<br>spiritual families.</p></div><div><b>03</b><h2>Stay responsible<br>for the field.</h2><p>Send people. Develop resources.<br>Create sustainable structures<br>and lasting local footholds.</p></div></div><div class="bottomcall">“Own the field” <span>Long-term commitment to a nation or city. <i>In the spirit of Romans 15:20.</i></span></div>','light journey-slide')
|
||
slide('04 / CORPORATE FAMILY RESPONSIBILITY', '<div class="copy"><h1>Not only<br>“my ministry.”<br><em>Our family.</em></h1><p class="lead">Local assignments belong within<br>one larger Kingdom vision.</p><p>Regional families increasingly carry<br>their regions—not one international<br>leader carrying the whole work.</p><div class="pull">“Is the family advancing?”</div></div>'+art('gather'),'yellow')
|
||
slide('05 / GENERATIONAL CONTINUITY', '<div class="copy"><h1>Give the next<br>generation<br><em>room to lead.</em></h1><p class="lead">Begin while mature leaders can still<br>coach, affirm and equip.</p><ul class="plain"><li>Engage younger leaders early.</li><li>Share wisdom and experience.</li><li>Give them a visible place to function.</li></ul><p class="fine">Moses & Joshua. David & Solomon.<br>Continuity—not starting over.</p></div>'+art('mentor'),'blue')
|
||
slide('06 / PRACTICAL KINGDOM EXPRESSION', '<div class="copy"><h1>Let good<br>work travel.</h1><p class="lead">Share people, experience and resources.<br>Adapt the work—not just copy it.</p><div class="feature"><h3>From the source: Venezuela’s medical work</h3><p>Explore its adaptation where language,<br>needs, regulations, permits and<br>relationships make service possible.</p></div><p>Medicine. Business. Education. Finances.<br>Professional skills and everyday relationships.</p><p class="fine">Those who cannot travel carry the same vision locally.</p></div>'+art('service'),'light')
|
||
slide('07 / IMMEDIATE PRIORITIES · ALIGN & CONNECT', '<div class="wide"><div class="smalltag">START WITH PEOPLE, NOT A PROGRAM</div><h1>One vision.<br><em>Stronger relationships.</em></h1></div><div class="priority-list"><div><b>1</b><h2>Share one understanding.</h2><p>Agree on the vision and where the family is going.</p></div><div><b>2</b><h2>Strengthen relationships.</h2><p>Connect regional leaders and families—including Chiapas and San Luis.</p></div><div><b>3</b><h2>Embrace the vision personally.</h2><p>Move beyond intellectual agreement toward shared ownership.</p></div></div><div class="marginword">ALIGN<br>CONNECT<br>OWN</div>','light priorities')
|
||
slide('08 / IMMEDIATE PRIORITIES · ACT TOGETHER', '<div class="copy"><h1>Pray regularly.<br><em>Show up.<br>Start clearly.</em></h1><div class="compact-priorities"><p><b>4 / EXCHANGE</b> Cross-pollinate ideas, strategies,<br>people, abilities and resources.</p><p><b>5 / PRAY</b> Establish regular regional prayer.</p><p><b>6 / STRENGTHEN CHILE</b> Encourage the brother<br>already there: he is part of the family, not alone.</p><p><b>7 / FOCUS</b> Begin with a limited number<br>of clear priorities—not everything at once.</p></div></div>'+art('door'),'yellow')
|
||
slide('09 / A MEDIUM- & LONG-TERM OBJECTIVE', '<div class="copy"><div class="smalltag">LATIN AMERICAN FAMILY GATHERING</div><h1>More than<br>an event.<br><em>A family<br>in motion.</em></h1><p class="lead">A catalyst for what continues<br>between gatherings.</p></div><div class="gathering"><div><h2>Belong & align</h2><p>Relationships, family identity,<br>a shared vision and prayer.</p></div><div><h2>Develop & continue</h2><p>Leadership formation, generational<br>transition and the next generation.</p></div><div><h2>Share & go</h2><p>Strategic collaboration, resources,<br>evangelism and outreach.</p></div><div class="gather-note">Nations strengthening one another.<br>Isolated leaders knowing they belong.</div></div>','light')
|
||
slide('10 / THE CONVERSATION BECOMES A COMMITMENT', '<div class="closing-title"><h1>What will we carry<br><em>together?</em></h1><p class="lead">Three purposes for the next regional conversations.</p></div><div class="closing-actions"><div><span>01</span><h2>Name the<br>shared vision.</h2><p>One understanding<br>of where we are going.</p></div><div><span>02</span><h2>Understand<br>each assignment.</h2><p>Know what each person<br>and group is called to carry.</p></div><div><span>03</span><h2>Find practical<br>mutual support.</h2><p>Prayer. Presence. Relationships.<br>Abilities and resources.</p></div></div><div class="source">Adapted from Adolfo Reyna / EMI, “Vision and Mission for Latin America” · Source capture: 22 September 2026.<br>Illustrations are original symbolic scenes, not depictions of actual people or sites. Priorities reflect the source, not new commitments.</div>','blue closing')
|
||
css='''
|
||
*{box-sizing:border-box}html{background:#182b45}body{margin:0;color:#172b45;font-family:"Helvetica Neue",Arial,sans-serif;-webkit-print-color-adjust:exact;print-color-adjust:exact}.slide{width:1920px;height:1080px;position:relative;padding:72px 100px 70px;background:#f7f2e7;overflow:hidden;break-after:page}.slide:last-child{break-after:auto}.eyebrow{font-size:21px;letter-spacing:2px;font-weight:700;display:flex;justify-content:space-between;border-bottom:2px solid currentColor;padding-bottom:21px;position:relative;z-index:2}.eyebrow span{font-size:20px;letter-spacing:1.8px}footer{position:absolute;bottom:31px;left:100px;right:100px;display:flex;justify-content:space-between;font-size:17px;letter-spacing:2px;font-weight:600;z-index:4}h1,h2,h3,p{margin:0}h1{font-size:100px;line-height:1.04;letter-spacing:-4.8px;font-weight:650}h1 em{font-family:Georgia,serif;font-weight:400;letter-spacing:-4px}h2{font-size:47px;line-height:1.12;letter-spacing:-1.3px}h3{font-size:28px;line-height:1.3}p,li{font-size:32px;line-height:1.4;font-weight:400}p{margin-top:28px}.lead{font-size:37px;line-height:1.35}.smalltag{font-size:22px;font-weight:700;letter-spacing:2.5px;margin-bottom:28px}.copy{position:relative;z-index:2;width:980px;padding-top:65px}.copy>p{max-width:960px}.wide{padding-top:63px;position:relative;z-index:2}.art{position:absolute;right:45px;top:152px;width:870px;height:870px}.art svg{width:100%;height:100%}.cover{background:#f7f2e7}.covercopy{padding-top:61px;position:relative;z-index:2}.cover h1{font-size:119px;line-height:.99;max-width:1060px}.cover h1 em{color:#2851bf}.cover p{font-size:32px;margin-top:38px}.cover .art{width:970px;height:970px;right:-27px;top:110px}.blue{background:#2851bf;color:#f7f2e7}.blue h1 em{color:#f3c653}.yellow{background:#f3c653}.plain{list-style:none;padding:0;margin:35px 0}.plain li{padding:13px 0 13px 29px;border-top:1px solid currentColor;max-width:880px;position:relative}.plain li:before{content:'—';position:absolute;left:0}.fine{font-size:23px;line-height:1.4}.commission{position:absolute;left:1195px;top:204px;width:620px;border-left:2px solid #f3c653;padding-left:70px}.commission h2{font-size:64px;line-height:1.25;color:#f3c653}.commission p{font-size:29px}.commission .fine{font-size:23px}.rule{height:2px;background:#f7f2e7;margin-top:37px;width:90px}.journey-slide h1{font-size:90px}.journey{display:flex;position:absolute;left:100px;right:100px;top:490px;gap:65px}.journey>div{width:33.333%;border-top:7px solid #2851bf;padding-top:25px}.journey b{font-size:26px;color:#2851bf;display:block;margin-bottom:22px}.journey h2{font-size:46px}.journey p{font-size:29px;margin-top:22px}.bottomcall{position:absolute;left:100px;bottom:106px;right:100px;border-top:1px solid #172b45;padding-top:23px;font-size:30px;font-weight:700}.bottomcall span{font-size:25px;font-weight:400;margin-left:22px}.bottomcall i{font-size:22px}.pull{font-family:Georgia,serif;font-style:italic;font-size:41px;margin-top:42px;border-left:5px solid #2851bf;padding-left:22px}.feature{border-left:6px solid #e57550;padding-left:29px;margin-top:33px;max-width:830px}.feature p{font-size:30px;margin-top:15px}.priority-list{position:absolute;left:100px;top:485px;width:1390px}.priority-list>div{position:relative;border-top:2px solid #172b45;padding:25px 0 25px 86px}.priority-list b{position:absolute;left:0;top:26px;font-size:50px;color:#2851bf}.priority-list h2{font-size:40px}.priority-list p{margin-top:10px;font-size:30px}.marginword{position:absolute;right:100px;top:511px;writing-mode:vertical-rl;font-size:45px;letter-spacing:4px;font-weight:750;color:#2851bf;line-height:1.45}.compact-priorities{margin-top:30px}.compact-priorities p{font-size:29px;margin-top:23px}.compact-priorities b{font-size:21px;letter-spacing:1px;display:block;margin-bottom:6px}.gathering{position:absolute;left:1110px;top:206px;right:100px}.gathering>div{border-top:4px solid #2851bf;padding:23px 0 30px}.gathering h2{font-size:46px;color:#2851bf}.gathering p{font-size:31px;margin-top:13px}.gathering .gather-note{font-size:29px;font-weight:650;border-top:0;background:#f3c653;padding:26px 30px;line-height:1.4}.closing-title{padding-top:67px}.closing-title h1{font-size:113px}.closing-title p{margin-top:30px}.closing-actions{position:absolute;left:100px;right:100px;top:568px;display:flex;gap:65px}.closing-actions>div{flex:1;border-top:3px solid #f3c653;padding-top:23px}.closing-actions span{font-size:25px;color:#f3c653}.closing-actions h2{margin-top:19px;font-size:47px}.closing-actions p{font-size:30px;margin-top:20px}.source{position:absolute;left:100px;bottom:89px;font-size:19px;line-height:1.5;opacity:.9}@page{size:20in 11.25in;margin:0}@media screen{.slide{margin:0 auto 32px;box-shadow:0 6px 40px #0003}}@media print{html,body{background:none}.slide{margin:0;box-shadow:none}}
|
||
'''
|
||
css += '\n#slide-9 h1{font-size:88px} #slide-9 .copy{padding-top:53px} #slide-9 .compact-priorities{margin-top:22px} #slide-9 .compact-priorities p{margin-top:17px;font-size:29px;line-height:1.3} #slide-9 .compact-priorities b{margin-bottom:5px}\n'
|
||
page='<!doctype html><html lang="en"><head><meta charset="UTF-8"><title>EMI — A family that remains</title><style>'+css+'</style></head><body>'+''.join(slides)+'</body></html>'
|
||
(O/'emi_astra_family_that_remains.html').write_text(page)
|
||
print('Authored',len(slides),'slides:',O/'emi_astra_family_that_remains.html')
|