@@ -4038,3 +4038,183 @@ export function AeonGapFigure() {
40384038 </ svg >
40394039 ) ;
40404040}
4041+
4042+ /** Lindy architecture — push email core surrounded by polling integrations. */
4043+ export function LindyArchFigure ( ) {
4044+ return (
4045+ < svg viewBox = "0 0 320 320" className = "w-full" role = "img" aria-labelledby = "lindy-arch-title" >
4046+ < title id = "lindy-arch-title" > Lindy architecture: push-based email core with polling integrations around it</ title >
4047+ < defs >
4048+ < radialGradient id = "lindy-core-grad" cx = "50%" cy = "45%" r = "30%" >
4049+ < stop offset = "0%" stopColor = { C . rose } stopOpacity = "0.5" />
4050+ < stop offset = "100%" stopColor = { C . rose } stopOpacity = "0.1" />
4051+ </ radialGradient >
4052+ </ defs >
4053+ { /* Central push core */ }
4054+ < circle cx = "160" cy = "145" r = "55" fill = "url(#lindy-core-grad)" />
4055+ < circle cx = "160" cy = "145" r = "55" fill = "none" stroke = { C . ink } strokeWidth = "1.5" />
4056+ { /* Envelope icon */ }
4057+ < rect x = "140" y = "130" width = "40" height = "28" rx = "3" fill = "none" stroke = { C . ink } strokeWidth = "1.4" />
4058+ < path d = "M140 130 L160 148 L200 130" fill = "none" stroke = { C . ink } strokeWidth = "1.4" strokeLinejoin = "round" />
4059+ < text x = "160" y = "175" textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "8" fill = { C . ink } > push</ text >
4060+ { /* Lightning bolt for real-time */ }
4061+ < path d = "M155 118 L159 126 L153 126 L157 134" fill = "none" stroke = { C . terracotta } strokeWidth = "1.5" strokeLinecap = "round" strokeLinejoin = "round" />
4062+ { /* Outer polling ring */ }
4063+ < circle cx = "160" cy = "145" r = "110" fill = "none" stroke = { C . rule } strokeWidth = "1" strokeDasharray = "6 4" />
4064+ { /* Polling integration nodes */ }
4065+ { [
4066+ { label : "Notion" , angle : - 60 } ,
4067+ { label : "Confluence" , angle : - 20 } ,
4068+ { label : "Slack" , angle : 20 } ,
4069+ { label : "HubSpot" , angle : 60 } ,
4070+ ] . map ( ( { label, angle } , i ) => {
4071+ const rad = ( ( angle - 90 ) * Math . PI ) / 180 ;
4072+ const x = 160 + Math . cos ( rad ) * 110 ;
4073+ const y = 145 + Math . sin ( rad ) * 110 ;
4074+ return (
4075+ < g key = { i } >
4076+ < circle cx = { x } cy = { y } r = "18" fill = { C . butter } opacity = "0.4" />
4077+ < circle cx = { x } cy = { y } r = "18" fill = "none" stroke = { C . ink } strokeWidth = "1.2" />
4078+ < text x = { x } y = { y + 3 } textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "6.5" fill = { C . ink } > { label } </ text >
4079+ { /* Dashed line to core — poll */ }
4080+ < line x1 = { x + ( 160 - x ) * 0.18 } y1 = { y + ( 145 - y ) * 0.18 } x2 = { 160 + ( x - 160 ) * 0.5 } y2 = { 145 + ( y - 145 ) * 0.5 } stroke = { C . faint } strokeWidth = "0.9" strokeDasharray = "3 3" />
4081+ </ g >
4082+ ) ;
4083+ } ) }
4084+ { /* iMessage delivery arrow going down */ }
4085+ < path d = "M160 200 L160 265" stroke = { C . ink } strokeWidth = "1.4" fill = "none" />
4086+ < path d = "M155 260 L160 268 L165 260" fill = "none" stroke = { C . ink } strokeWidth = "1.4" strokeLinejoin = "round" />
4087+ { /* Phone icon */ }
4088+ < rect x = "148" y = "270" width = "24" height = "36" rx = "4" fill = "none" stroke = { C . ink } strokeWidth = "1.3" />
4089+ < line x1 = "155" y1 = "298" x2 = "165" y2 = "298" stroke = { C . ink } strokeWidth = "1" strokeLinecap = "round" />
4090+ < text x = "160" y = "318" textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "7" fill = { C . faint } > iMessage</ text >
4091+ < text x = "280" y = "50" textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "7.5" fill = { C . faint } > poll every 10–15 min</ text >
4092+ < path d = "M265 53 L275 60" stroke = { C . faint } strokeWidth = "0.7" strokeDasharray = "2 2" />
4093+ </ svg >
4094+ ) ;
4095+ }
4096+
4097+ /** Lindy polling trigger — clock ticking with a configurable interval field. */
4098+ export function LindyPollFigure ( ) {
4099+ return (
4100+ < svg viewBox = "0 0 320 320" className = "w-full" role = "img" aria-labelledby = "lindy-poll-title" >
4101+ < title id = "lindy-poll-title" > Lindy polling triggers: configurable intervals mask a poll-based architecture</ title >
4102+ { /* Two trigger cards side by side */ }
4103+ { /* Left card: Email — push */ }
4104+ < rect x = "20" y = "30" width = "125" height = "140" rx = "8" fill = { C . sage } opacity = "0.15" />
4105+ < rect x = "20" y = "30" width = "125" height = "140" rx = "8" fill = "none" stroke = { C . ink } strokeWidth = "1.4" />
4106+ < text x = "82" y = "55" textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "9" fill = { C . ink } > Gmail trigger</ text >
4107+ { /* Lightning bolt */ }
4108+ < path d = "M75 70 L82 85 L72 85 L79 100" fill = "none" stroke = { C . moss } strokeWidth = "2" strokeLinecap = "round" strokeLinejoin = "round" />
4109+ < text x = "82" y = "120" textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "8" fill = { C . moss } > push-based</ text >
4110+ < text x = "82" y = "135" textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "7" fill = { C . faint } > Pub/Sub</ text >
4111+ < text x = "82" y = "150" textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "7" fill = { C . faint } > fires instantly</ text >
4112+ { /* Right card: Confluence — poll */ }
4113+ < rect x = "175" y = "30" width = "125" height = "140" rx = "8" fill = { C . butter } opacity = "0.15" />
4114+ < rect x = "175" y = "30" width = "125" height = "140" rx = "8" fill = "none" stroke = { C . ink } strokeWidth = "1.4" />
4115+ < text x = "237" y = "55" textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "9" fill = { C . ink } > Confluence trigger</ text >
4116+ { /* Clock icon */ }
4117+ < circle cx = "237" cy = "82" r = "14" fill = "none" stroke = { C . terracotta } strokeWidth = "1.5" />
4118+ < line x1 = "237" y1 = "82" x2 = "237" y2 = "73" stroke = { C . terracotta } strokeWidth = "1.5" strokeLinecap = "round" />
4119+ < line x1 = "237" y1 = "82" x2 = "244" y2 = "85" stroke = { C . terracotta } strokeWidth = "1.2" strokeLinecap = "round" />
4120+ < text x = "237" y = "120" textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "8" fill = { C . terracotta } > poll-based</ text >
4121+ < text x = "237" y = "135" textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "7" fill = { C . faint } > every 900s</ text >
4122+ < text x = "237" y = "150" textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "7" fill = { C . faint } > ≈ 15 min delay</ text >
4123+ { /* Divider */ }
4124+ < line x1 = "160" y1 = "45" x2 = "160" y2 = "155" stroke = { C . rule } strokeWidth = "1" strokeDasharray = "4 3" />
4125+ { /* Bottom: same UI, different architecture */ }
4126+ < rect x = "40" y = "200" width = "240" height = "65" rx = "6" fill = { C . paper } stroke = { C . rule } strokeWidth = "1" />
4127+ < text x = "160" y = "222" textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "8.5" fill = { C . ink } > Agent Builder UI</ text >
4128+ < text x = "160" y = "238" textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "7.5" fill = { C . faint } > same interface, different latency</ text >
4129+ < text x = "160" y = "252" textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "7.5" fill = { C . faint } > user sees no distinction</ text >
4130+ { /* Arrows from cards to UI */ }
4131+ < path d = "M82 170 L82 200" stroke = { C . ink } strokeWidth = "0.9" strokeDasharray = "3 3" />
4132+ < path d = "M237 170 L237 200" stroke = { C . ink } strokeWidth = "0.9" strokeDasharray = "3 3" />
4133+ < text x = "160" y = "292" textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "8" fill = { C . terracotta } >
4134+ uniform UX hides the latency gap
4135+ </ text >
4136+ </ svg >
4137+ ) ;
4138+ }
4139+
4140+ /** Lindy scorecard — three primitives with fill levels. */
4141+ export function LindyScorecardFigure ( ) {
4142+ return (
4143+ < svg viewBox = "0 0 320 320" className = "w-full" role = "img" aria-labelledby = "lindy-score-title" >
4144+ < title id = "lindy-score-title" > Lindy scorecard: clock full, listener half, inbox full</ title >
4145+ { /* Three vertical bars */ }
4146+ { [
4147+ { label : "clock" , fill : 1.0 , color : C . sage , status : "✓" } ,
4148+ { label : "listener" , fill : 0.55 , color : C . butter , status : "~" } ,
4149+ { label : "inbox" , fill : 1.0 , color : C . rose , status : "✓" } ,
4150+ ] . map ( ( { label, fill, color, status } , i ) => {
4151+ const x = 55 + i * 90 ;
4152+ const barH = 160 ;
4153+ const barY = 60 ;
4154+ const fillH = barH * fill ;
4155+ return (
4156+ < g key = { i } >
4157+ { /* Bar background */ }
4158+ < rect x = { x } y = { barY } width = "50" height = { barH } rx = "6" fill = { C . rule } opacity = "0.3" />
4159+ < rect x = { x } y = { barY } width = "50" height = { barH } rx = "6" fill = "none" stroke = { C . ink } strokeWidth = "1.3" />
4160+ { /* Fill from bottom */ }
4161+ < rect x = { x + 3 } y = { barY + barH - fillH + 3 } width = "44" height = { fillH - 6 } rx = "4" fill = { color } opacity = "0.5" />
4162+ { /* Status badge */ }
4163+ < circle cx = { x + 25 } cy = { barY + 20 } r = "10" fill = { fill >= 1 ? C . sage : C . butter } opacity = "0.6" />
4164+ < text x = { x + 25 } y = { barY + 24 } textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "11" fill = { C . ink } > { status } </ text >
4165+ { /* Label */ }
4166+ < text x = { x + 25 } y = { barY + barH + 22 } textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "9" fill = { C . ink } > { label } </ text >
4167+ </ g >
4168+ ) ;
4169+ } ) }
4170+ { /* Annotation for listener */ }
4171+ < text x = "160" y = "270" textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "7.5" fill = { C . faint } >
4172+ email: push · everything else: poll
4173+ </ text >
4174+ < text x = "160" y = "300" textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "9" fill = { C . terracotta } >
4175+ ≈ 2.5 / 3
4176+ </ text >
4177+ </ svg >
4178+ ) ;
4179+ }
4180+
4181+ /** Lindy tradeoff — consumer polish on one side, infrastructure depth on the other. */
4182+ export function LindyTradeoffFigure ( ) {
4183+ return (
4184+ < svg viewBox = "0 0 320 320" className = "w-full" role = "img" aria-labelledby = "lindy-trade-title" >
4185+ < title id = "lindy-trade-title" > Lindy tradeoff: consumer polish versus infrastructure depth</ title >
4186+ { /* Balance beam */ }
4187+ < circle cx = "160" cy = "170" r = "6" fill = { C . ink } />
4188+ < line x1 = "160" y1 = "170" x2 = "160" y2 = "240" stroke = { C . ink } strokeWidth = "2" />
4189+ < rect x = "130" y = "240" width = "60" height = "8" rx = "3" fill = { C . ink } />
4190+ { /* Beam — tilted left (consumer polish heavier) */ }
4191+ < line x1 = "50" y1 = "140" x2 = "270" y2 = "160" stroke = { C . ink } strokeWidth = "2" strokeLinecap = "round" />
4192+ { /* Left pan — Consumer polish (lower = heavier) */ }
4193+ < line x1 = "50" y1 = "140" x2 = "50" y2 = "145" stroke = { C . ink } strokeWidth = "1.2" />
4194+ < path d = "M20 145 Q50 160 80 145" fill = "none" stroke = { C . ink } strokeWidth = "1.4" />
4195+ < rect x = "22" y = "105" width = "56" height = "32" rx = "5" fill = { C . rose } opacity = "0.3" />
4196+ < rect x = "22" y = "105" width = "56" height = "32" rx = "5" fill = "none" stroke = { C . ink } strokeWidth = "1" />
4197+ < text x = "50" y = "118" textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "7" fill = { C . ink } > consumer</ text >
4198+ < text x = "50" y = "130" textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "7" fill = { C . ink } > polish</ text >
4199+ { /* Right pan — Infrastructure depth (higher = lighter) */ }
4200+ < line x1 = "270" y1 = "160" x2 = "270" y2 = "165" stroke = { C . ink } strokeWidth = "1.2" />
4201+ < path d = "M240 165 Q270 180 300 165" fill = "none" stroke = { C . ink } strokeWidth = "1.4" />
4202+ < rect x = "242" y = "125" width = "56" height = "32" rx = "5" fill = { C . lavender } opacity = "0.3" />
4203+ < rect x = "242" y = "125" width = "56" height = "32" rx = "5" fill = "none" stroke = { C . ink } strokeWidth = "1" />
4204+ < text x = "270" y = "138" textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "7" fill = { C . ink } > infra</ text >
4205+ < text x = "270" y = "150" textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "7" fill = { C . ink } > depth</ text >
4206+ { /* Annotations */ }
4207+ < text x = "50" y = "80" textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "7" fill = { C . faint } > iMessage, onboarding</ text >
4208+ < text x = "50" y = "91" textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "7" fill = { C . faint } > 2,500 integrations</ text >
4209+ < text x = "270" y = "105" textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "7" fill = { C . faint } > state opacity</ text >
4210+ < text x = "270" y = "116" textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "7" fill = { C . faint } > scoped auth gap</ text >
4211+ { /* Bottom label */ }
4212+ < text x = "160" y = "280" textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "8" fill = { C . terracotta } >
4213+ Lindy chose polish first, infrastructure second
4214+ </ text >
4215+ < text x = "160" y = "296" textAnchor = "middle" fontFamily = "var(--font-mono)" fontSize = "7.5" fill = { C . faint } >
4216+ right call for the target user
4217+ </ text >
4218+ </ svg >
4219+ ) ;
4220+ }
0 commit comments