1<!DOCTYPE html> 2<html> 3<head> 4<meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> 5<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> 6 7<!--[if IE]><link rel="shortcut icon" href="/assets/favicon/favicon-a50e0f178a55cb7f0e5bf6f4e9f2be419700f9d1bdf04183b790ca08ea36b87d.ico"><![endif]--> 8 <link 9 rel="icon" 10 href="/assets/favicon/favicon-32-301c1f60736808a932b7d77d1cdcf6143c7e314f9193c48a160d1440dc7f5909.png" 11 type="image/png" 12 sizes="32x32" 13 > 14 15<title>yUML â Diagrams AI can write. Humans can read at a glance.</title> 16 <link rel="stylesheet" media="all" href="/assets/application-e04339ac6339af8a5eab75a7f9ad6800179baa46dce951889100034cf21f1f3e.css" /> 17
17<script src="/assets/application-dfb50923a40df6206f754274d1a904d7e67bd9b17651a74701ae07aa85f3d119.js"></script>
17 18 <!-- Hotjar Tracking Code for https://yuml.me -->
19<script>
vendor: 125 bytes, lines 19-22
19 20 (function(h,o,t,j,a,r){ 21 h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)}; 22 h._hjSettings={hjid:
22987660
vendor: 258 bytes, lines 22-27
22,hjsv:6}; 23 a=o.getElementsByTagName('head')[0]; 24 r=o.createElement('script');r.async=1; 25 r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv; 26 a.appendChild(r); 27 })(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv=');
28</script>
28 29 <meta name="csrf-param" content="authenticity_token" /> 30<meta name="csrf-token" content="tN55PYXcCF60s7mDjuR0WiM5vFMRnSkK2IPXioEQudQkhUBSWK9066bEqyMCBgUGRG+OnATWtLJILjQ1R9tYYA==" /> 31
31<script type="text/javascript"> 32 // We already have Google Analytics and HotJar 33 // GA behaviour flow isn't working so well because namespace page have custom names 34 // HotJar is OK but again, funnels seem limited 35 36 (function(e,t){var n=e.amplitude||{_q:[],_iq:{}};var r=t.createElement("script") 37 ;r.type="text/javascript" 38 ;r.integrity="sha384-vYYnQ3LPdp/RkQjoKBTGSq0X5F73gXU3G2QopHaIfna0Ct1JRWzwrmEz115NzOta" 39 ;r.crossOrigin="anonymous";r.async=true 40 ;r.src="https://cdn.amplitude.com/libs/amplitude-5.8.0-min.gz.js" 41 ;r.onload=function(){if(!e.amplitude.runQueuedFunctions){ 42 console.log("[Amplitude] Error: could not load SDK")}} 43 ;var i=t.getElementsByTagName("script")[0];i.parentNode.insertBefore(r,i) 44 ;function s(e,t){e.prototype[t]=function(){ 45 this._q.push([t].concat(Array.prototype.slice.call(arguments,0)));return this}} 46 var o=function(){this._q=[];return this} 47 ;var a=["add","append","clearAll","prepend","set","setOnce","unset"] 48 ;for(var u=0;u<a.length;u++){s(o,a[u])}n.Identify=o;var c=function(){this._q=[] 49 ;return this} 50 ;var l=["setProductId","setQuantity","setPrice","setRevenueType","setEventProperties"] 51 ;for(var p=0;p<l.length;p++){s(c,l[p])}n.Revenue=c 52 ;var d=["init","logEvent","logRevenue","setUserId","setUserProperties","setOptOut","setVersionName","setDomain","setDeviceId", "enableTracking", "setGlobalUserProperties","identify","clearUserProperties","setGroup","logRevenueV2","regenerateDeviceId","groupIdentify","onInit","logEventWithTimestamp","logEventWithGroups","setSessionId","resetSessionId"] 53 ;function v(e){function t(t){e[t]=function(){ 54 e._q.push([t].concat(Array.prototype.slice.call(arguments,0)))}} 55 for(var n=0;n<d.length;n++){t(d[n])}}v(n);n.getInstance=function(e){ 56 e=(!e||e.length===0?"$default_instance":e).toLowerCase() 57 ;if(!n._iq.hasOwnProperty(e)){n._iq[e]={_q:[]};v(n._iq[e])}return n._iq[e]} 58 ;e.amplitude=n})(window,document); 59 60 amplitude.getInstance().init("afce9ddb7db9d4004f35997d2ada7ebb"); 61 amplitude.getInstance().init('afce9ddb7db9d4004f35997d2ada7ebb', null, {includeReferrer: true, includeUtm: true}); 62 63</script>
63 64 65 <meta name="twitter:card" content="summary_large_image"> 66<meta name="twitter:site" content="@yuml_app"> 67<meta name="twitter:creator" content="@tobinharris"> 68<meta name="twitter:title" content="yUML"> 69<meta name="twitter:description" content="Create simple UML diagrams online in seconds. Then share them in your blogs, wikis, issue trackers and chat clients."> 70<meta name="twitter:image" content="https://yuml.me/images/twitter_card_home_preview.jpg"> 71</head> 72 <body class="index-bg"> 73 <nav class="navbar is-spaced is-dark" role="navigation" aria-label="main navigation" style="background: #1F1F1F;"> 74 <div class="navbar-brand"> 75 <a class="navbar-item" href="/"> 76 <img style="height: 28px; width: auto;" src="/assets/yuml_logo_v2_light-5b2d52c70c8767cbeb07aa8cb3b8527e5c4f4cbcfc4f7c8cc0c45f36e5631418.svg" /> 77 </a> 78 79 <a role="button" class="navbar-burger burger" aria-label="menu" aria-expanded="false" data-target="navbarBasicExample"> 80 <span aria-hidden="true"></span> 81 <span aria-hidden="true"></span> 82 <span aria-hidden="true"></span> 83 </a> 84 </div> 85 86 <div id="navbarBasicExample" class="navbar-menu"> 87 <div class="navbar-start"> 88 <a href="https://app.yuml.me/playground" class="navbar-item" target="_blank" rel="noopener">Playground</a> 89 <a href="https://app.yuml.me/pricing" class="navbar-item" target="_blank" rel="noopener">Pricing</a> 90 <a href="https://app.yuml.me/showcase" class="navbar-item" target="_blank" rel="noopener">Gallery</a> 91 <a href="/docs" class="navbar-item">Docs</a> 92 </div> 93 94 <div class="navbar-end"> 95 <div class="navbar-item"> 96 <div class="buttons"> 97 <a href="https://app.yuml.me/users/sign_up" class="button is-primary has-text-weight-bold" target="_blank" rel="noopener">Sign Up Free</a> 98 <a href="https://app.yuml.me/users/sign_in" class="button is-light" target="_blank" rel="noopener">Log In</a> 99 </div> 100 </div> 101 </div> 102 </div> 103</nav> 104 105 <div id="birthday-banner" style="background: #0A0A0A; color: #A8A29E; text-align: center; padding: 10px 16px; font-family: 'DM Sans', system-ui, sans-serif; font-size: 15px; position: relative; border-bottom: 1px solid #262626;"> 106 🎂 It's our <strong style="color: #D97706;">birthday month!</strong> yUML is 17 â get <strong style="color: #D97706;">17% off Pro</strong> with code <strong style="color: #D97706; letter-spacing: 0.5px;">HAPPY-17TH-BIRTHDAY</strong> 107 <a href="https://app.yuml.me/pricing" style="display: inline-block; background: #fff; color: #0A0A0A; font-weight: 700; text-decoration: none; padding: 4px 14px; border-radius: 4px; margin-left: 10px; font-size: 13px;">Claim 17% off →</a> 108 <button onclick="this.parentElement.style.display='none'; try{localStorage.setItem('v1-birthday-dismissed','1')}catch(e){}" style="position: absolute; right: 12px; top: 50%; transform: translateY(-50%); background: none; border: none; color: #78716C; font-size: 18px; cursor: pointer; padding: 0 4px; line-height: 1;" title="Dismiss">×</button> 109 </div> 110
110<script>try{if(localStorage.getItem('v1-birthday-dismissed')){document.getElementById('birthday-banner').style.display='none';}}catch(e){}</script>
110 111 <div id="content"> 112 113 114
115<script> 116 amplitude.getInstance().logEvent("Viewed Home Page") 117</script>
117 118 119<style> 120 .lp-hero { background: #1F1F1F; } 121 .lp-hero h1 { color: #f5f5f4; } 122 .lp-hero p { color: #d6d3d1; } 123 .lp-hero .lp-stats { color: #a8a29e; } 124 .lp-hero .lp-stats .lp-heart { color: #D97706; } 125 126 .lp-btn-primary { background: #577939; color: #fff; border: none; } 127 .lp-btn-primary:hover { background: #4A6830; color: #fff; } 128 .lp-btn-outline { background: transparent; color: #e7e5e4; border: 2px solid #a8a29e; } 129 .lp-btn-outline:hover { border-color: #e7e5e4; color: #fff; } 130 131 .lp-logos { background: #F3F1EE; } 132 .lp-logos img { filter: grayscale(100%) opacity(0.7); } 133 .lp-logos p { color: #78716c; } 134 135 .lp-warm { background: #FAF9F7; } 136 .lp-stone { background: #F3F1EE; } 137 .lp-dark { background: #1F1F1F; color: #e7e5e4; } 138 139 .lp-step-num { 140 display: inline-flex; width: 40px; height: 40px; border-radius: 50%; 141 align-items: center; justify-content: center; 142 background: #D97706; color: #fff; font-weight: 700; font-size: 1.1rem; 143 margin-bottom: 0.75rem; 144 } 145 146 .lp-diagram-card { 147 background: #fff; border-radius: 8px; overflow: hidden; 148 box-shadow: 0 2px 12px rgba(0,0,0,0.06); 149 margin-bottom: 1.5rem; 150 cursor: pointer; 151 transition: transform 200ms ease, box-shadow 200ms ease; 152 } 153 .lp-diagram-card:hover, .lp-diagram-card:focus-visible { 154 transform: translateY(-2px); 155 box-shadow: 0 8px 22px rgba(0,0,0,0.12); 156 outline: none; 157 } 158 .lp-diagram-card object { width: 100%; height: 180px; display: block; pointer-events: none; } 159 .lp-diagram-card .lp-card-label { 160 padding: 0.5rem 0.75rem; font-weight: 600; font-size: 0.9rem; 161 text-align: center; color: #44403c; 162 } 163 164 /* Lightbox */ 165 .lp-lightbox { 166 position: fixed; inset: 0; z-index: 1000; 167 background: rgba(20, 18, 16, 0.9); 168 display: none; align-items: center; justify-content: center; 169 padding: 2rem; 170 opacity: 0; transition: opacity 200ms ease; 171 } 172 .lp-lightbox.open { display: flex; opacity: 1; } 173 .lp-lightbox-content { 174 position: relative; background: #fff; border-radius: 12px; 175 box-shadow: 0 24px 60px rgba(0,0,0,0.5); 176 display: flex; flex-direction: column; overflow: hidden; 177 max-width: min(90vw, 1100px); width: 100%; 178 } 179 .lp-lightbox-content object { 180 width: 100%; height: min(72vh, 700px); 181 display: block; pointer-events: none; 182 } 183 .lp-lightbox-label { 184 padding: 0.75rem 1rem; text-align: center; 185 font-weight: 600; color: #44403c; 186 border-top: 1px solid #e7e5e4; 187 } 188 .lp-lightbox-close, .lp-lightbox-nav { 189 position: absolute; 190 background: rgba(255,255,255,0.95); color: #1c1917; 191 border: none; border-radius: 50%; 192 width: 44px; height: 44px; 193 display: flex; align-items: center; justify-content: center; 194 cursor: pointer; 195 box-shadow: 0 4px 14px rgba(0,0,0,0.35); 196 font-size: 1.2rem; font-weight: 700; line-height: 1; 197 transition: background 150ms ease, transform 150ms ease; 198 } 199 .lp-lightbox-close:hover, .lp-lightbox-nav:hover { background: #fff; } 200 .lp-lightbox-close { 201 top: 1.5rem; right: 1.5rem; z-index: 2; 202 font-size: 1.4rem; 203 } 204 .lp-lightbox-nav { 205 top: 50%; transform: translateY(-50%); 206 } 207 .lp-lightbox-nav.prev { left: 1.5rem; } 208 .lp-lightbox-nav.next { right: 1.5rem; } 209 .lp-lightbox-nav:hover { transform: translateY(-50%) scale(1.08); } 210 body.lp-lightbox-open { overflow: hidden; } 211 212 .lp-code { 213 background: #1F1F1F; color: #e7e5e4; border-radius: 8px; 214 padding: 1.5rem; font-family: 'Menlo', 'Monaco', monospace; 215 font-size: 0.9rem; line-height: 1.7; white-space: pre; overflow-x: auto; 216 } 217 218 .lp-dark h2 { color: #f5f5f4; } 219 .lp-dark h3 { color: #fff; } 220 .lp-dark p { color: #d6d3d1; } 221 222 .lp-heading { color: #1C1917; } 223 .lp-body { color: #44403C; } 224 .lp-muted { color: #78716C; } 225 226 .lp-link { color: #577939; font-weight: 600; } 227 .lp-link:hover { color: #4A6830; } 228 229 .lp-hero-diagram { 230 max-width: 520px; width: 100%; height: 340px; 231 border-radius: 8px; box-shadow: 0 8px 30px rgba(0,0,0,0.3); background: #fff; 232 pointer-events: none; 233 } 234 235 /* Hero animated card deck */ 236 .hero-deck-wrap { 237 position: relative; width: 100%; max-width: 600px; margin: 0 auto; 238 padding: 1rem 3rem 1.5rem 1rem; 239 } 240 .hero-deck { 241 position: relative; width: 100%; padding-bottom: 62%; 242 } 243 .hero-deck-card { 244 position: absolute; inset: 0; 245 background: #fff; border-radius: 10px; 246 box-shadow: 0 12px 32px rgba(0,0,0,0.28), 0 2px 6px rgba(0,0,0,0.12); 247 overflow: hidden; pointer-events: none; 248 display: flex; flex-direction: column; 249 padding: 0.75rem 0.9rem 0.4rem; 250 transform-origin: 50% 100%; 251 transition: transform 750ms cubic-bezier(.2,.8,.2,1), opacity 850ms ease-out, box-shadow 500ms ease; 252 will-change: transform; 253 --pos: 0; 254 transform: 255 translate(calc(var(--pos) * 5px), calc(var(--pos) * 3px)) 256 rotate(calc(var(--pos) * 1.6deg)); 257 z-index: calc(20 - var(--pos)); 258 } 259 .hero-deck-card object { 260 flex: 1; width: 100%; min-height: 0; display: block; pointer-events: none; 261 } 262 .hero-deck-label { 263 text-align: center; font-weight: 600; font-size: 0.85rem; 264 color: #44403c; padding: 0.3rem 0 0; letter-spacing: 0.02em; 265 } 266 /* Cap visible cards in the deck to the top 3 â JS sets this class on 267 anything beyond pos 2, so the rest queue invisibly behind. As cards 268 advance, pos 3 â pos 2 fades in via the standard opacity transition. */ 269 .hero-deck-card.hero-deck-hidden { 270 opacity: 0; 271 } 272 /* Applied while a card is being re-seated at the back so it can fade in */ 273 .hero-deck-card.entering { 274 opacity: 0; 275 transition: none; 276 } 277 /* Hover lift â pauses the cycle and raises the top card toward the viewer */ 278 .hero-deck-card.lift-active { 279 transition: transform 320ms cubic-bezier(.2,.8,.2,1), box-shadow 320ms ease, opacity 320ms ease-out; 280 } 281 .hero-deck-card.lifted { 282 transform: translate(0, -22px) rotate(0deg) scale(1.08) !important; 283 box-shadow: 0 32px 56px rgba(0,0,0,0.32), 0 8px 18px rgba(0,0,0,0.14); 284 z-index: 25; 285 } 286 /* Swipe â defined last so its !important transform beats .lifted when both apply */ 287 .hero-deck-card.swiping { 288 transform: translate(125%, -4%) rotate(18deg) !important; 289 opacity: 0; 290 transition: transform 850ms cubic-bezier(.4,.05,.3,1), opacity 700ms ease; 291 z-index: 30; 292 } 293 @media (prefers-reduced-motion: reduce) { 294 .hero-deck-card, .hero-deck-card.swiping { transition: none; } 295 } 296</style> 297 298<!-- HERO --> 299<section class="hero is-medium lp-hero"> 300 <div class="hero-body"> 301 <div class="container"> 302 <div class="columns is-vcentered"> 303 <div class="column is-6"> 304 <h1 class="title is-size-1 is-size-3-mobile" style="line-height: 1.15;"> 305 Create and share diagrams that <span style="color: #D97706">communicate your ideas, fast.</span> 306 </h1> 307 <p class="is-size-5 is-size-6-mobile" style="margin-bottom: 2rem; max-width: 480px;"> 308 Since 2007, yuml has helped over 500,000 people create beautiful diagrams using only words. No mucking about with projects or layout. 309 </p> 310 <p> 311 <a href="https://app.yuml.me/playground" target="_blank" rel="noopener" class="button is-medium is-rounded lp-btn-primary">Open the Playground →</a> 312 313 <a href="https://app.yuml.me/showcase" target="_blank" rel="noopener" class="button is-medium is-rounded lp-btn-outline">See Examples</a> 314 </p> 315 <p class="lp-stats is-size-6" style="margin-top: 2rem;">
316 <span class="lp-heart"><i class="fas fa-heart"></i></span> 317 <b>1,855</b> 318 diagrams rendered today 319 </p> 320 </div> 321 <div class="column is-6"> 322 <div class="hero-deck-wrap" aria-hidden="true"> 323 <div class="hero-deck" id="hero-deck"> 324 <div class="hero-deck-card" style="--pos: 0;"> 325 <object data="/assets/v2/pie-sketch-fb9112bd201b002f39af3c364451c2b6e0c62e12d0cd021ae672bd780f7fafd4.svg" type="image/svg+xml"></object> 326 <div class="hero-deck-label">Pie Chart</div> 327 </div> 328 <div class="hero-deck-card" style="--pos: 1;"> 329 <object data="/assets/v2/journey-sketch-254bfefd107f77a9fedddee13851132d1b03d6198af9c7d8b69b693d2edf1412.svg" type="image/svg+xml"></object> 330 <div class="hero-deck-label">User Journey</div> 331 </div> 332 <div class="hero-deck-card" style="--pos: 2;"> 333 <object data="/assets/v2/sequence-sketch-4cb5ba284f3f0f81481041efab9e6ac041fc868d7d370bdc78c59e9b232e905e.svg" type="image/svg+xml"></object> 334 <div class="hero-deck-label">Sequence</div> 335 </div> 336 <div class="hero-deck-card hero-deck-hidden" style="--pos: 3;"> 337 <object data="/assets/v2/state-sketch-c232e3651811b2d762083a2c7e2d8dae51cbb97dbfa687aec491df6366cb4d64.svg" type="image/svg+xml"></object> 338 <div class="hero-deck-label">
338State</div> 339 </div> 340 <div class="hero-deck-card hero-deck-hidden" style="--pos: 4;"> 341 <object data="/assets/v2/class-sketch-b2981cfe281b34b992d1aa56b01acf4af581c725cfbaa11bd07b13bb41ab2f5c.svg" type="image/svg+xml"></object> 342 <div class="hero-deck-label">Class</div> 343 </div> 344 <div class="hero-deck-card hero-deck-hidden" style="--pos: 5;"> 345 <object data="/assets/v2/bar-sketch-7335b4e47d73b6198552b6f658df3bbe22b80063f9b12d12ccfa59772eb1432e.svg" type="image/svg+xml"></object> 346 <div class="hero-deck-label">Bar Chart</div> 347 </div> 348 <div class="hero-deck-card hero-deck-hidden" style="--pos: 6;"> 349 <object data="/assets/v2/activity-sketch-1e7db1db9d6147c54feb69d36ebd70555323804b6a45036dadf9149e0738a1e1.svg" type="image/svg+xml"></object> 350 <div class="hero-deck-label">Activity</div> 351 </div> 352 <div class="hero-deck-card hero-deck-hidden" style="--pos: 7;"> 353 <object data="/assets/v2/column-sketch-9bfcdc51ab41b17daa999e8fa7137a60b4c435e9d15a4d0f8442791faa94ea3f.svg" type="image/svg+xml"></object> 354 <div class="hero-deck-label">Column Chart</div> 355 </div> 356 <div class="hero-deck-card hero-deck-hidden" style="--pos: 8;"> 357 <object data="/assets/v2/timeline-sketch-a61d237eb48eb1a62ddd271fde45c51a6928c306846493e0b37f2b81dfab758c.svg" type="image/svg+xml"></object> 358 <div class="hero-deck-label">Timeline</div> 359 </div> 360 <div class="hero-deck-card hero-deck-hidden" style="--pos: 9;"> 361 <object data="/assets/v2/usecase-sketch-b3b7ed4e47d0d9d49aaf6055355e88889b88b0095d699ef08742c7279cef1f6f.svg" type="image/svg+xml"></object> 362 <div class="hero-deck-label">Use Case</div> 363 </div> 364 <div class="hero-deck-card hero-deck-hidden" style="--pos: 10;"> 365 <object data="/assets/v2/line-sketch-2ab1d859718dfba1d187502f47a899241d267c5ced4418eedd687d5fb4dcb57c.svg" type="image/svg+xml"></object> 366 <div class="hero-deck-label">Line Chart</div> 367 </div> 368 <div class="hero-deck-card hero-deck-hidden" style="--pos: 11;"> 369 <object data="/assets/v2/roadmap-sketch-cf7828d6ae59d7e8257261debf90059337cd984205cd5bdaa470f9a76b74d3ba.svg" type="image/svg+xml"></object> 370 <div class="hero-deck-label">Roadmap</div> 371 </div> 372 <div class="hero-deck-card hero-deck-hidden" style="--pos: 12;"> 373 <object data="/assets/v2/c4-sketch-b444c9b24c9071c72b78301bb94cac5865e37fa120405071b6f5164f353c9323.svg" type="image/svg+xml"></object> 374 <div class="hero-deck-label">C4 Architecture</div> 375 </div> 376 </div> 377 </div> 378 </div> 379 </div> 380 </div> 381 </div> 382</section> 383 384<!-- DIAGRAM EXPLORER â big diagram on the left, click a use case on the right. --> 385 386<section class="lp-explorer"> 387 <style> 388 /* Themable via CSS variables â .is-dark below overrides the palette 389 so swapping to a blueprint diagram flips the whole section. */ 390 .lp-explorer { 391 --bg: #FAF9F7; 392 --heading-fg: #1C1917; 393 --sub-fg: #78716C; 394 --sub-strong: #44403C; 395 --canvas-bg: #fff; 396 --canvas-shadow: 0 8px 28px rgba(20, 18, 16, 0.10); 397 --item-fg: #44403C; 398 --item-hover-bg: #F3F1EE; 399 --item-hover-fg: #1C1917; 400 --item-active-bg: #1F1F1F; 401 --item-active-fg: #fff; 402 --item-arrow: #D97706; 403 --embed-bg: #F3F1EE; 404 --embed-border: #E7E5E4; 405 --embed-fg: #44403C; 406 --embed-strong: #1C1917; 407 --embed-label: #78716C; 408 --embed-btn-bg: #fff; 409 --embed-btn-fg: #44403C; 410 --embed-btn-border: #D6D3D1; 411 412 background: var(--bg); 413 padding: 5rem 0 5.5rem; 414 transition: background 320ms ease; 415 } 416 /* Dark mode (blueprint use case active):
417 - Section bg = on-brand charcoal (matches hero, code blocks) 418 - Canvas card = blueprint navy paper (merges with the diagram's 419 own paper for a "drawn directly on it" feel) 420 - Embed strip = a shade darker than the card, still navy family 421 - Active menu item = warm white with dark text â the only light 422 tile against the dark section, so the choice reads at a glance 423 and the navy stays out of the menu */ 424 .lp-explorer.is-dark { 425 --bg: #1F1F1F; 426 --heading-fg: #f5f5f4; 427 --sub-fg: #a8a29e; 428 --sub-strong: #d6d3d1; 429 --canvas-bg: #1a3a5c; 430 --canvas-shadow: 0 12px 36px rgba(0, 0, 0, 0.55); 431 --item-fg: #d6d3d1; 432 --item-hover-bg: rgba(255, 255, 255, 0.06); 433 --item-hover-fg: #fff; 434 --item-active-bg: #FAF9F7; 435 --item-active-fg: #1C1917; 436 --item-arrow: #D97706; 437 438 --embed-bg: #0a2040; 439 --embed-border: rgba(255, 255, 255, 0.08); 440 --embed-fg: #d6d3d1; 441 --embed-strong: #fbbf24; 442 --embed-label: #a8a29e; 443 --embed-btn-bg: rgba(255, 255, 255, 0.08); 444 --embed-btn-fg: #f5f5f4; 445 --embed-btn-border: rgba(255, 255, 255, 0.18); 446 } 447 .lp-explorer .lp-explorer-head { 448 text-align: center; 449 max-width: 820px; 450 margin: 0 auto 2.5rem; 451 padding: 0 1.5rem; 452 } 453 .lp-explorer h2 { 454 color: var(--heading-fg); 455 font-size: 2rem; line-height: 1.2; font-weight: 700; 456 margin: 0; 457 transition: color 320ms ease; 458 } 459 .lp-explorer .lp-explorer-sub { 460 color: var(--sub-fg); 461 font-size: 1rem; 462 margin-top: 0.75rem; 463 transition: color 320ms ease; 464 } 465 .lp-explorer .lp-explorer-sub b { 466 color: var(--sub-strong); font-weight: 600; 467 transition: color 320ms ease; 468 } 469 470 .lp-explorer-row { 471 max-width: 1400px; 472 margin: 0 auto; 473 padding: 0 1.5rem; 474 display: flex; 475 gap: 2rem; 476 align-items: stretch; 477 } 478 479 /* LHS â big canvas. Card bg + shadow are themed so a blueprint 480 diagram lands on matching navy paper rather than white. */ 481 .lp-explorer-canvas { 482 flex: 1 1 60%; 483 min-width: 0; 484 background: var(--canvas-bg); 485 border-radius: 14px; 486 box-shadow: var(--canvas-shadow); 487 display: flex; flex-direction: column; 488 min-height: 580px; 489 overflow: hidden; 490 transition: background 320ms ease, box-shadow 320ms ease; 491 } 492 .lp-explorer-stage { 493 flex: 1; min-height: 0; 494 display: flex; align-items: center; justify-content: center; 495 padding: 1.5rem; 496 } 497 .lp-explorer-stage object { 498 width: 100%; height: 100%; 499 max-height: 500px; 500 display: block; 501 pointer-events: none; 502 transition: opacity 220ms ease; 503 } 504 .lp-explorer-canvas.is-swapping .lp-explorer-stage object { opacity: 0; } 505 506 /* Embed strip â code line + copy button. The marketing punch: 507 "every diagram on this page is one URL". */ 508 .lp-explorer-embed { 509 flex: 0 0 auto; 510 background: var(--embed-bg); 511 border-top: 1px solid var(--embed-border); 512 padding: 0.75rem 1rem; 513 display: flex; align-items: center; gap: 0.75rem; 514 transition: background 320ms ease, border-color 320ms ease; 515 } 516 .lp-explorer-embed-label { 517 flex: 0 0 auto; 518 font-size: 0.7rem; font-weight: 700; 519 letter-spacing: 0.08em; text-transform: uppercase; 520 color: var(--embed-label); 521 transition: color 320ms ease; 522 } 523 .lp-explorer-embed-code { 524 flex: 1 1 auto; min-width: 0; 525 font-family: 'Menlo', 'Monaco', 'Consolas', monospace; 526 font-size: 0.78rem; line-height: 1.5; 527 color: var(--embed-fg); 528 background: transparent; 529 overflow-x: auto; 530 white-space: nowrap; 531 padding: 0.25rem 0; 532 transition: color 320ms ease; 533 } 534 .lp-explorer-embed-code .lp-embed-strong { 535 color: var(--embed-strong); font-weight: 600; 536 transition: color 320ms ease; 537 } 538 .lp-explorer-embed-btn { 539 flex: 0 0 auto; 540 appearance: none; 541 background: var(--embed-btn-bg); 542 color: var(--embed-btn-fg); 543 border: 1px solid var(--embed-btn-border); 544 border-radius: 6px; 545 padding: 0.4rem 0.75rem; 546 font-size: 0.78rem; font-weight: 600; 547 cursor: pointer; 548 text-decoration: none; 549 display: inline-flex; align-items: center; gap: 0.3rem; 550 transition: background 150ms ease, color 320ms ease, border-color 320ms ease; 551 } 552 .lp-explorer-embed-btn:hover { filter: brightness(0.96); } 553 .lp-explorer-embed-open { color: var(--embed-btn-fg); } 554 .lp-explorer-embed-open:hover, .lp-explorer-embed-open:focus-visible { 555 color: var(--embed-btn-fg); 556 outline: none; 557 } 558 .lp-explorer-embed-copy.is-copied { 559 background: #577939; color: #fff; border-color: #577939; 560 } 561 562 /* RHS â vertical menu of use cases. */ 563 .lp-explorer-menu { 564 flex: 0 0 380px; 565 display: flex; flex-direction: column; 566 gap: 0.5rem; 567 list-style: none; 568 margin: 0; padding: 0; 569 } 570 .lp-explorer-item { 571 appearance: none; 572 background: transparent; 573 border: 1.5px solid transparent; 574 color: var(--item-fg); 575 font-size: 1.05rem; font-weight: 500; 576 text-align: left; 577 padding: 0.85rem 1rem 0.85rem 1.1rem; 578 border-radius: 10px; 579 cursor: pointer; 580 display: flex; align-items: center; gap: 0.65rem; 581 transition: background 150ms ease, color 320ms ease, border-color 150ms ease; 582 width: 100%; 583 } 584 .lp-explorer-item:hover { 585 background: var(--item-hover-bg); 586 color: var(--item-hover-fg); 587 } 588 .lp-explorer-item.is-active { 589 background: var(--item-active-bg); 590 border-color: var(--item-active-bg); 591 color: var(--item-active-fg); 592 font-weight: 600; 593 } 594 .lp-explorer-item .lp-explorer-arrow { 595 color: var(--item-arrow); 596 font-weight: 700; 597 opacity: 0; 598 transform: translateX(-4px); 599 transition: opacity 150ms ease, transform 150ms ease, color 320ms ease; 600 } 601 .lp-explorer-item.is-active .lp-explorer-arrow { 602 opacity: 1; 603 transform: translateX(0); 604 } 605 606 @media (max-width: 1000px) { 607 .lp-explorer-row { flex-direction: column; } 608 .lp-explorer-canvas { min-height: 420px; } 609 .lp-explorer-stage object { max-height: 380px; } 610 .lp-explorer-menu { flex: 1 1 auto; } 611 } 612 613 @media (prefers-reduced-motion: reduce) { 614 .lp-explorer, 615 .lp-explorer h2, 616 .lp-explorer .lp-explorer-sub, 617 .lp-explorer .lp-explorer-sub b, 618 .lp-explorer-canvas, 619 .lp-explorer-stage object, 620 .lp-explorer-item, 621 .lp-explorer-item .lp-explorer-arrow, 622 .lp-explorer-embed, 623 .lp-explorer-embed-label, 624 .lp-explorer-embed-code, 625 .lp-explorer-embed-copy { transition: none; } 626 } 627 628 @media (max-width: 700px) { 629 .lp-explorer-embed { flex-wrap: wrap; } 630 .lp-explorer-embed-code { font-size: 0.72rem; } 631 } 632 </style> 633 634 <div class="lp-explorer-head"> 635 <h2>Visualise your software, UX or product thinking.</h2> 636 <p class="lp-explorer-sub">From whiteboard sketches to architecture docs — <b>one DSL</b>, eight styles.</p> 637 </div> 638 639 <div class="lp-explorer-row"> 640 <div class="lp-explorer-canvas" id="lp-explorer-canvas"> 641 <div class="lp-explorer-stage"> 642 <object id="lp-explorer-svg" 643 type="image/svg+xml" 644 data="/assets/v2/styles/style-uml-usecase-1d8850f761fa108582bb5ecc4cceb7d5a846831bb1f6f1136d7864c8e69773f8.svg" 645 aria-label="Sketch out your use cases"></object> 646 </div> 647 <div class="lp-explorer-embed" id="lp-explorer-embed">
648 <span class="lp-explorer-embed-label">Embed</span> 649 <code class="lp-explorer-embed-code" id="lp-explorer-embed-code"><img src="https://app.yuml.me/diagram/v1/usecase/blueprint/[Customer]-(Browse Products)%0A[Customer]-(Add to Basket)%0A[Customer]-(Checkout)%0A(Checkout)>(Pay)%0A(Checkout)>(Get Receipt)%0A[Admin]-(Manage Inventory).svg" /></code> 650 <a class="lp-explorer-embed-btn lp-explorer-embed-open" id="lp-explorer-embed-open" 651 href="https://app.yuml.me/playground#pako:eJxdzrEKwjAQBuBXCZla0BdwKLQdagehFDd1iMmhoW2u5C5KEN_d1EXp9vP93PG_pKFR7uSpDsQ4gb9ss8rjk0B0Hk3QTPnZ_belMYJRVIoG4FVX30EPGBb-5SLrVFxJAyx60GDn74vSTNal-4Ny6gaidQ9wjD7mciM5zpAGBgKtCBIQx3GR6xhg9tZxMmM9aLbokvdtsz_K9wfUgUuc" target="_blank" rel="noopener" 652 aria-label="Open this diagram in the playground"> 653 Open in Playground <span aria-hidden="true">↗</span> 654 </a> 655 <button class="lp-explorer-embed-btn lp-explorer-embed-copy" id="lp-explorer-embed-copy" 656 type="button" data-clipboard="<img src="https://app.yuml.me/diagram/v1/usecase/blueprint/[Customer]-(Browse Products)%0A[Customer]-(Add to Basket)%0A[Customer]-(Checkout)%0A(Checkout)>(Pay)%0A(Checkout)>(Get Receipt)%0A[Admin]-(Manage Inventory).svg" />">Copy</button> 657 </div> 658 </div> 659 <ul class="lp-explorer-menu" role="tablist" aria-label="Diagram use cases"> 660 <li> 661 <button class="lp-explorer-item is-active" 662 type="button" 663 role="tab" 664 data-src="/assets/v2/styles/style-uml-usecase-1d8850f761fa108582bb5ecc4cceb7d5a846831bb1f6f1136d7864c8e69773f8.svg" 665 data-label="Sketch out your use cases" 666 data-theme="dark" 667 data-embed="<img src="https://app.yuml.me/diagram/v1/usecase/blueprint/[Customer]-(Browse Products)%0A[Customer]-(Add to Basket)%0A[Customer]-(Checkout)%0A(Checkout)>(Pay)%0A(Checkout)>(Get Receipt)%0A[Admin]-(Manage Inventory).svg" />" 668 data-href="https://app.yuml.me/diagram/v1/usecase/blueprint/%5BCustomer%5D-%28Browse%20Products%29%0A%5BCustomer%5D-%28Add%20to%20Basket%29%0A%5BCustomer%5D-%28Checkout%29%0A%28Checkout%29%3E%28Pay%29%0A%28Checkout%29%3E%28Get%20Receipt%29%0A%5BAdmin%5D-%28Manage%20Inventory%29.svg" 669 data-playground="https://app.yuml.me/playground#pako:eJxdzrEKwjAQBuBXCZla0BdwKLQdagehFDd1iMmhoW2u5C5KEN_d1EXp9vP93PG_pKFR7uSpDsQ4gb9ss8rjk0B0Hk3QTPnZ_belMYJRVIoG4FVX30EPGBb-5SLrVFxJAyx60GDn74vSTNal-4Ny6gaidQ9wjD7mciM5zpAGBgKtCBIQx3GR6xhg9tZxMmM9aLbokvdtsz_K9wfUgUuc" 670 aria-selected="true"> 671 <span class="lp-explorer-arrow" aria-hidden="true">→</span> 672 <span>Sketch out your use cases</span> 673 </button> 674 </li> 675 <li> 676 <button class="lp-explorer-item" 677 type="button" 678 role="tab" 679 data-src="/assets/v2/styles/style-prod-journeyflow-f52ec9e334426759c2f9f3fed19908f584e266a586bc6a1dc61a9969fe6f4571.svg" 680 data-label="Map your onboarding user journey" 681 data-theme="light" 682 data-embed="<img src="https://app.yuml.me/diagram/v1/journeyflow/sketch/(Sign up)->%0A[ð Find website]->%0A[ð Verify email{bg:wheat}]->%0A(First use)->%0A[ð Complete first task]->%0A[ð "That was quicker than I thought"]->%0A[ð Recommend{bg:lightgreen}].svg" />" 683 data-href="https://app.yuml.me/diagram/v1/journeyflow/sketch/%28Sign%20up%29-%3E%0A%5B%F0%9F%98%90%20Find%20website%5D-%3E%0A%5B%F0%9F%98%9F%20Verify%20email%7Bbg%3Awheat%7D%5D-%3E%0A%28First%20use%29-%3E%0A%5B%F0%9F%98%8A%20Complete%20first%20task%5D-%3E%0A%5B%F0%9F%98%8A%20%22That%20was%20quicker%20than%20I%20thought%22%5D-%3E%0A%5B%F0%9F%98%8A%20Recommend%7Bbg%3Alightgreen%7D%5D.svg" 684 data-playground="https://app.yuml.me/playground#pako:eJxNj00OgjAQha8y6QoTvQALNyYkbtW4ERYFBlopLbbTEEK4gCuX7riiRxBI_FlN8n0v72V6ljvFQhYcZanBN6vNNtaX1_h8QCR1Di2mThImHzzCGa0sOsCaS9WnZdgK5DQsgSCS1hF4h9-aO-xM3SgkhGKRxF2V_GzMToITtNzBzcusQgskuIb9dIwvBcXsL33AzNQ16nweVnLSpUXUQ8LWjLoGp0euxluNXaFMO0FHnZqpq5AywYY3qV9agA" 685 aria-selected="false">
686 <span class="lp-explorer-arrow" aria-hidden="true">→</span> 687 <span>Map your onboarding user journey</span> 688 </button> 689 </li> 690 <li> 691 <button class="lp-explorer-item" 692 type="button" 693 role="tab" 694 data-src="/assets/v2/styles/style-prod-timeline-33c632bde4e2de3ddefbe4cd190e2d4cf8175e9763da2bf9de156ee9589e3503.svg" 695 data-label="Show your key product milestones" 696 data-theme="light" 697 data-embed="<img src="https://app.yuml.me/diagram/v1/timeline/sketch/(2024 Q1|Research|Interviewed 50 users)->%0A[Team assembled]->%0A(2024 Q2|Beta launch{bg:wheat})->%0A[First paying customer]->%0A(2024 Q3|Public release)->%0A(2024 Q4|Scale ops)->%0A[Hit 1k users{bg:lightgreen}]->%0A(2025 Q1|Series A|Raised £2M).svg" />" 698 data-href="https://app.yuml.me/diagram/v1/timeline/sketch/%282024%20Q1%7CResearch%7CInterviewed%2050%20users%29-%3E%0A%5BTeam%20assembled%5D-%3E%0A%282024%20Q2%7CBeta%20launch%7Bbg%3Awheat%7D%29-%3E%0A%5BFirst%20paying%20customer%5D-%3E%0A%282024%20Q3%7CPublic%20release%29-%3E%0A%282024%20Q4%7CScale%20ops%29-%3E%0A%5BHit%201k%20users%7Bbg%3Alightgreen%7D%5D-%3E%0A%282025%20Q1%7CSeries%20A%7CRaised%20%C2%A32M%29.svg" 699 data-playground="https://app.yuml.me/playground#pako:eJxNj8FKw0AURX_lMSsDCm1sN10IuhBdFGrrTl1MJpfk0ck0zHuxhE6-xj_xy0xokW7P4953z8mU4s3K3OSzfEFv87SFwEZXp9egiN-MI0pazqgTRMnuHj7DxztsQ1YETeFRfk3sEs_TE9SSt11w9amoVscaVodz7JmjKLW251CR60QPDeJ1-j5tusKzowgPK8iubou0c9aDDu1lxAsrzffnWdMnz1WtVQTC8N-5nIR2iAyhx7S1LKPL70--zsyt0b7FKK7cwHPASER7PyHZQ11thj8sVF_a" 700 aria-selected="false"> 701 <span class="lp-explorer-arrow" aria-hidden="true">→</span> 702 <span>Show your key product milestones</span> 703 </button> 704 </li> 705 <li> 706 <button class="lp-explorer-item" 707 type="button" 708 role="tab" 709 data-src="/assets/v2/styles/style-uml-class-d24ef76cb204f2d349fac749449fb55a08ba7a4f03c20d5f3c01c3204b9f3e9c.svg" 710 data-label="Sketch your domain model" 711 data-theme="light" 712 data-embed="<img src="https://app.yuml.me/diagram/v1/class/scruffy/[Vehicle{bg:lightskyblue}|make;model;year]^[Car|doors;fuelType]%0A[Vehicle]^[Truck|payload;axles]%0A[Vehicle]^[Bike|gears]%0A[Driver]-drives>[Vehicle].svg" />" 713 data-href="https://app.yuml.me/diagram/v1/class/scruffy/%5BVehicle%7Bbg%3Alightskyblue%7D%7Cmake%3Bmodel%3Byear%5D%5E%5BCar%7Cdoors%3BfuelType%5D%0A%5BVehicle%5D%5E%5BTruck%7Cpayload%3Baxles%5D%0A%5BVehicle%5D%5E%5BBike%7Cgears%5D%0A%5BDriver%5D-drives%3E%5BVehicle%5D.svg" 714 data-playground="https://app.yuml.me/playground#pako:eJxVjkEKwjAQRe-StV6gARfatW6KLmqFNJm2IdOmZBIxNL27qaDgavjvfx6zMEXIClZfYdASYWn7AnU_eDKxxQBrGoUBPloFyCMI1zzqk3BJWeuIdwGwijM09-kryH3lgjRpFhGtUFy8EOh_cNQGUp9lH146_QTX7NV26fDbsR3z2Z2fkyiIciQfccskXei6mInSDqTXdsq0vNzObH0D6tRN3g" 715 aria-selected="false"> 716 <span class="lp-explorer-arrow" aria-hidden="true">→</span> 717 <span>Sketch your domain model</span> 718 </button> 719 </li> 720 <li> 721 <button class="lp-explorer-item" 722 type="button" 723 role="tab" 724 data-src="/assets/v2/styles/style-biz-bar-89b1e2d34008e750615e08482c3e70cad820541e1762159dff1f3bc0661f32e9.svg" 725 data-label="Communicate your growth" 726 data-theme="light" 727 data-embed="<img src="https://app.yuml.me/diagram/v1/bar/napkin/@heading Pipeline by region%0A@hatch off%0AEMEA: 142 {bg:lightgreen}%0ANorth America: 118 {bg:lightskyblue}%0AAPAC: 87 {bg:wheat}%0ALATAM: 41 {bg:thistle}.svg" />" 728 data-href="https://app.yuml.me/diagram/v1/bar/napkin/%40heading%20Pipeline%20by%20region%0A%40hatch%20off%0AEMEA%3A%20142%20%7Bbg%3Alightgreen%7D%0ANorth%20America%3A%20118%20%7Bbg%3Alightskyblue%7D%0AAPAC%3A%2087%20%7Bbg%3Awheat%7D%0ALATAM%3A%2041%20%7Bbg%3Athistle%7D.svg" 729 data-playground="https://app.yuml.me/playground#pako:eJxFjrEKgzAURX_lkbmLRahkMhS3tjh0dEn0mTxMn5KkFBH_valLx3vugXs3MUQvpKgd6oHYQksLemIEs0JASzN3XDudegfzOHbc3BsloSjPs
729BkrPVmXbEDkvePHHJID9cJAvc5OUf2dOK3GvzFbqlVXCdXl6D55NmV4U091l1AWB02OYvK4i5NI64L5ntEhh5hW_0usl4lY7F9POEDF" 730 aria-selected="false"> 731 <span class="lp-explorer-arrow" aria-hidden="true">→</span> 732 <span>Communicate your growth</span> 733 </button> 734 </li> 735 <li> 736 <button class="lp-explorer-item" 737 type="button" 738 role="tab" 739 data-src="/assets/v2/styles/style-biz-canvas-c30ecdb4f567fe9f14f4063bf3f0ae22f1a6fa431ff8ac83adc87ca885b5c034.svg" 740 data-label="Summarise your SWOT analysis" 741 data-theme="light" 742 data-embed="<img src="https://app.yuml.me/diagram/v1/canvas/clean/@heading SWOT â Q3 review%0A%0A# Strengths%0ADeep ML talent%0AProfitable since year 2%0A%0A# Weaknesses%0ALimited marketing budget%0ASlow release cycle%0A%0A# Opportunities%0AEnterprise AI demand%0AAPAC expansion%0A%0A# Threats%0ABig-tech entrants%0ATalent retention.svg" />" 743 data-href="https://app.yuml.me/diagram/v1/canvas/clean/%40heading%20SWOT%20%E2%80%94%20Q3%20review%0A%0A%23%20Strengths%0ADeep%20ML%20talent%0AProfitable%20since%20year%202%0A%0A%23%20Weaknesses%0ALimited%20marketing%20budget%0ASlow%20release%20cycle%0A%0A%23%20Opportunities%0AEnterprise%20AI%20demand%0AAPAC%20expansion%0A%0A%23%20Threats%0ABig-tech%20entrants%0ATalent%20retention.svg" 744 data-playground="https://app.yuml.me/playground#pako:eJwlkM1Ow0AMhF_FWq5wgRsnws8BqahFidRLLm52SFbdOKtdtyVCSDwET8iT4LQnyyN_MyN_OV-iu3cPA9gH6anerhv6-_ml9zvKOAacWmnlimrNkF6H0sozkOhtRcoRoq1s8vQRlHcRVIJ0oBmc6fbCbcF7QSkwcBXGoPA0ct5Dl7TdwfcwizpOJ4uL4ALq5i7iQq9TmrIeJGhYDF5EkVMOdlS9ksfI4lupNtUT4TOxlDDJBWyGDFZDHkN_o-gGsqqZZZGac2-LUxtGuGunc4J9oWM5crG96BzPgjUS9_0PIpVrow" 745 aria-selected="false"> 746 <span class="lp-explorer-arrow" aria-hidden="true">→</span> 747 <span>Summarise your SWOT analysis</span> 748 </button> 749 </li> 750 <li> 751 <button class="lp-explorer-item" 752 type="button" 753 role="tab" 754 data-src="/assets/v2/styles/style-prod-activity-6fbc03c8e266468f0c682623e42270a069db7770d59d22a0fc80392f97be2f94.svg" 755 data-label="Map out the key steps" 756 data-theme="light" 757 data-embed="<img src="https://app.yuml.me/diagram/v1/activity/sketch/(start)->[Receive Order{bg:wheat}]->|f|%0A|f|->[Charge Card]->|j|%0A|f|->[Reserve Stock]->|j|%0A|j|->[Ship{bg:lightgreen}]->(end).svg" />" 758 data-href="https://app.yuml.me/diagram/v1/activity/sketch/%28start%29-%3E%5BReceive%20Order%7Bbg%3Awheat%7D%5D-%3E%7Cf%7C%0A%7Cf%7C-%3E%5BCharge%20Card%5D-%3E%7Cj%7C%0A%7Cf%7C-%3E%5BReserve%20Stock%5D-%3E%7Cj%7C%0A%7Cj%7C-%3E%5BShip%7Bbg%3Alightgreen%7D%5D-%3E%28end%29.svg" 759 data-playground="https://app.yuml.me/playground#pako:eJw9jjEOgzAMRa-CMoFULsDAwtB2qhTY2g5p4iYBFJBjUSHg7nUWlj-8Z3_9TZg4ikrkkRRSUdZPCRr8AtkDDeD2sdXPgaLjXdb7d38FDj5qnEILWaPQJNGfQkIE5O-WJj2cqk-qdX5OfaO3jiwChFSaQzCFuAhaZ-AdSpNfPK1MIq1jQnEA0o6B8Qisp8BQ3q-3Thx_qadDVQ" 760 aria-selected="false"> 761 <span class="lp-explorer-arrow" aria-hidden="true">→</span> 762 <span>Map out the key steps</span> 763 </button> 764 </li> 765 <li> 766 <button class="lp-explorer-item" 767 type="button" 768 role="tab" 769 data-src="/assets/v2/styles/style-arch-c4-container-d61a19963442ae22cefcfa9a2f9802dae7525e8f50fb5cf25437b743a4673fe3.svg" 770 data-label="Show the deployed systems" 771 data-theme="light" 772 data-embed="<img src="https://app.yuml.me/diagram/v1/c4/clean/@heading Banking System â Containers%0A[Customer|Person|Mobile + web user]%0A{Banking System%0A [Web App|Container|React SPA]%0A [API|Container|Node service]%0A [Database|Container|Postgres :database:]%0A [Cache|Container|Redis :database:]%0A}%0A[Customer]-Uses->[Web App]%0A[Web App]-Calls->[API]%0A[API]-Reads/Writes->[Database]%0A[API]-Caches->[Cache].svg" />" 773 data-href="https://app.yuml.me/diagram/v1/c4/clean/%40heading%20B
773anking%20System%20%E2%80%94%20Containers%0A%5BCustomer%7CPerson%7CMobile%20%2B%20web%20user%5D%0A%7BBanking%20System%0A%20%20%5BWeb%20App%7CContainer%7CReact%20SPA%5D%0A%20%20%5BAPI%7CContainer%7CNode%20service%5D%0A%20%20%5BDatabase%7CContainer%7CPostgres%20%3Adatabase%3A%5D%0A%20%20%5BCache%7CContainer%7CRedis%20%3Adatabase%3A%5D%0A%7D%0A%5BCustomer%5D-Uses-%3E%5BWeb%20App%5D%0A%5BWeb%20App%5D-Calls-%3E%5BAPI%5D%0A%5BAPI%5D-Reads%2FWrites-%3E%5BDatabase%5D%0A%5BAPI%5D-Caches-%3E%5BCache%5D.svg" 774 data-playground="https://app.yuml.me/playground#pako:eJxdkE1OwzAQha8y8hYiNqyyQIQgQRegqAV10WTh2KPWwrUjjwuKmkocghNyEmyXRmlX8_M9z7zxnknSLGf3G-RSmTU8cPMR46Inj1v4_f6B0hrPlUFHtVmVO_J2i26oQm3N8GJbpRGu4Atb2BG6pjb78yG1AVgtAy66bhiHDXPkwsOiKpokKKrZBL5aiRCmfSqBR_7IPW854URUWfJrhwS5_If5UVtyscGzVVJdqA6TW5rsnZCyu5PJgMc0K7nWkQV_sR9DFqxLulk65dOzk7WRp_2RpKRh18z3HYZvFrchJ9_rVGjkJtRSORReWRN689nT8xs7_AGZjJG-" 775 aria-selected="false"> 776 <span class="lp-explorer-arrow" aria-hidden="true">→</span> 777 <span>Show the deployed systems</span> 778 </button> 779 </li> 780 </ul> 781 </div> 782 783
783<script> 784 (function() { 785 var section = document.querySelector('.lp-explorer'); 786 var canvas = document.getElementById('lp-explorer-canvas'); 787 var svg = document.getElementById('lp-explorer-svg'); 788 var embedCode = document.getElementById('lp-explorer-embed-code'); 789 var embedOpen = document.getElementById('lp-explorer-embed-open'); 790 var embedCopy = document.getElementById('lp-explorer-embed-copy'); 791 var items = Array.prototype.slice.call(document.querySelectorAll('.lp-explorer-item')); 792 if (!section || !canvas || !svg || !items.length) return; 793 794 // Initial dark state from whichever item starts active. 795 var startActive = items.find(function(i) { return i.classList.contains('is-active'); }) || items[0]; 796 section.classList.toggle('is-dark', startActive.dataset.theme === 'dark'); 797 798 // Pre-fetch every SVG so the swap is instant after the first click. 799 items.forEach(function(it) { 800 var l = document.createElement('link'); 801 l.rel = 'prefetch'; 802 l.as = 'image'; 803 l.type = 'image/svg+xml'; 804 l.href = it.dataset.src; 805 document.head.appendChild(l); 806 }); 807 808 // Highlight the URL portion of <img src="..."> in the accent colour. 809 // Plain span (not a link) â visitors who want to follow it use the 810 // Open button, which lands them in the live playground rather than 811 // a bare SVG. 812 function decorateEmbed(snippet) { 813 return snippet.replace( 814 /src="([^&]+)"/, 815 'src="<span class="lp-embed-strong">$1</span>"' 816 ); 817 } 818 819 function setEmbed(snippet, href, playground) { 820 if (!embedCode) return; 821 var encoded = snippet 822 .replace(/&/g, '&') 823 .replace(/</g, '<') 824 .replace(/>/g, '>') 825 .replace(/"/g, '"'); 826 embedCode.innerHTML = decorateEmbed(encoded); 827 if (embedCopy) embedCopy.dataset.clipboard = snippet; 828 if (embedOpen && playground) embedOpen.setAttribute('href', playground); 829 } 830 831 // Initial decoration for the server-rendered first embed. 832 if (embedCode) { 833 var firstSnippet = items[0] && items[0].dataset.embed; 834 var firstHref = items[0] && items[0].dataset.href; 835 var firstPlayground = items[0] && items[0].dataset.playground; 836 if (firstSnippet) setEmbed(firstSnippet, firstHref, firstPlayground); 837 } 838 839 function activate(item) { 840 if (item.classList.contains('is-active')) return; 841 items.forEach(function(o) { 842 var on = o === item; 843 o.classList.toggle('is-active', on); 844 o.setAttribute('aria-selected', on ? 'true' : 'false'); 845 }); 846 // Flip the section theme to match the diagram's natural backdrop. 847 section.classList.toggle('is-dark', item.dataset.theme === 'dark'); 848 // Swap the embed snippet to match. 849 setEmbed(item.dataset.embed || '', item.dataset.href || '', item.dataset.playground || ''); 850 // Fade out â swap data â fade back in. <object> takes a moment 851 // to load; we just commit the new src and rely on the CSS 852 // transition for the visual handoff. 853 canvas.classList.add('is-swapping'); 854 // Build a fresh <object> so the load event fires reliably. 855 var fresh = document.createElement('object'); 856 fresh.id = 'lp-explorer-svg'; 857 fresh.type = 'image/svg+xml'; 858 fresh.setAttribute('aria-label', item.dataset.label); 859 fresh.style.opacity = '0'; 860 fresh.addEventListener('load', function() { 861 canvas.classList.remove('is-swapping'); 862 fresh.style.opacity = ''; 863 }, { once: true }); 864 // Safety: reveal after 800ms even if load doesn't fire (cached). 865 setTimeout(function() { 866 canvas.classList.remove('is-swapping'); 867 fresh.style.opacity = ''; 868 }, 800); 869 fresh.data = item.dataset.src; 870 svg.replaceWith(fresh); 871 svg = fresh; 872 } 873 874 items.forEach(function(it) { 875 it.addEventListener('click', function() { activate(it); }); 876 }); 877
878 // Copy-to-clipboard with visual feedback. 879 if (embedCopy) { 880 var copyResetTimer = null; 881 embedCopy.addEventListener('click', function() { 882 var text = embedCopy.dataset.clipboard || ''; 883 if (!text) return; 884 var done = function() { 885 embedCopy.textContent = 'Copied'; 886 embedCopy.classList.add('is-copied'); 887 if (copyResetTimer) clearTimeout(copyResetTimer); 888 copyResetTimer = setTimeout(function() { 889 embedCopy.textContent = 'Copy'; 890 embedCopy.classList.remove('is-copied'); 891 }, 1800); 892 }; 893 if (navigator.clipboard && navigator.clipboard.writeText) { 894 navigator.clipboard.writeText(text).then(done).catch(function() { 895 // Fallback path 896 fallbackCopy(text); 897 done(); 898 }); 899 } else { 900 fallbackCopy(text); 901 done(); 902 } 903 }); 904 } 905 function fallbackCopy(text) { 906 var ta = document.createElement('textarea'); 907 ta.value = text; 908 ta.setAttribute('readonly', ''); 909 ta.style.position = 'fixed'; 910 ta.style.opacity = '0'; 911 document.body.appendChild(ta); 912 ta.select(); 913 try { document.execCommand('copy'); } catch (e) {} 914 document.body.removeChild(ta); 915 } 916 })(); 917 </script>
917 918</section> 919 920<!-- GENERATE WITH AI --> 921<section class="section is-medium lp-ai-demo"> 922 <style> 923 .lp-ai-demo { background: #FFFFFF; padding-top: 5rem; padding-bottom: 5rem; } 924 .lp-ai-demo .lp-ai-eyebrow { 925 display: inline-flex; align-items: center; gap: 0.5rem; 926 padding: 0.4rem 0.85rem; border-radius: 999px; 927 background: #FFF6E5; color: #B45309; 928 font-weight: 600; font-size: 0.78rem; letter-spacing: 0.02em; 929 } 930 .lp-ai-demo .lp-ai-eyebrow-dot { 931 width: 7px; height: 7px; border-radius: 50%; background: #D97706; 932 } 933 .lp-ai-prompt { 934 max-width: 760px; margin: 0 auto 2.5rem; 935 background: #fff; border-radius: 14px; 936 border: 1.5px solid #e7e5e4; 937 box-shadow: 0 4px 18px rgba(20, 18, 16, 0.06); 938 padding: 1rem 1.25rem; 939 display: flex; align-items: center; gap: 0.85rem; 940 min-height: 56px; 941 } 942 .lp-ai-prompt-icon { 943 width: 36px; height: 36px; flex-shrink: 0; 944 border-radius: 8px; 945 background: linear-gradient(135deg, #D97706, #B45309); 946 color: #fff; font-size: 1rem; 947 display: inline-flex; align-items: center; justify-content: center; 948 } 949 .lp-ai-prompt-text { 950 flex: 1; color: #1c1917; line-height: 1.4; 951 font-size: 1rem; 952 font-family: 'Menlo', 'Monaco', 'Consolas', monospace; 953 overflow: hidden; 954 } 955 .lp-ai-caret { 956 display: inline-block; width: 2px; height: 1.05em; 957 background: #1c1917; vertical-align: -2px; 958 margin-left: 2px; 959 animation: lp-ai-blink 1s infinite step-end; 960 } 961 @keyframes lp-ai-blink { 50% { opacity: 0; } } 962 .lp-ai-output { 963 max-width: 1100px; margin: 0 auto; 964 min-height: 560px; 965 opacity: 0; transform: translateY(14px); 966 transition: opacity 600ms ease-out, transform 600ms ease-out; 967 display: flex; align-items: center; justify-content: center; 968 } 969 .lp-ai-output.visible { opacity: 1; transform: translateY(0); } 970 .lp-ai-output object { 971 width: 100%; height: auto; display: block; 972 pointer-events: none; 973 border-radius: 8px; 974 filter: drop-shadow(0 12px 28px rgba(20, 18, 16, 0.12)) drop-shadow(0 4px 8px rgba(20, 18, 16, 0.06)); 975 } 976 @media (prefers-reduced-motion: reduce) { 977 .lp-ai-output { opacity: 1; transform: none; transition: none; } 978 .lp-ai-caret { animation: none; } 979 } 980 </style> 981 982 <div class="container"> 983 <div class="has-text-centered" style="margin-bottom: 2rem;"> 984 <span class="lp-ai-eyebrow"> 985 <span class="lp-ai-eyebrow-dot"></span> 986 <span>GENERATE WITH AI</span> 987 </span> 988 <h2 class="title is-3 lp-heading" style="margin-top: 1.25rem;"> 989 Describe what you need. Get a diagram. 990 </h2> 991 <p class="lp-muted" style="max-width: 620px; margin: 0.75rem auto 0;"> 992 Type a sentence in plain English. yUML's AI turns it into an editable diagram you can refine, save, or share. 993 </p> 994 </div> 995 996 <div class="lp-ai-prompt" aria-hidden="true"> 997 <div class="lp-ai-prompt-icon"><i class="fas fa-magic"></i></div> 998 <div class="lp-ai-prompt-text" id="lp-ai-prompt-text"><span class="lp-ai-caret"></span></div> 999 </div> 1000 1001 <div class="lp-ai-output" id="lp-ai-output"></div> 1002 1003 <link rel="prefetch" href="/assets/v2/ai-journey-onboarding-b26f3ca47f55f578253506bd22820993dce4ddfd926828f56e773c506254d6cb.svg" as="image" type="image/svg+xml"> 1004 <link rel="prefetch" href="/assets/v2/ai-class-domain-aece7ccff1280d85b537732c332b79a5e48fc8d42ab90263afed9055046a4752.svg" as="image" type="image/svg+xml"> 1005 <link rel="prefetch" href="/assets/v2/ai-roadmap-quarters-0ed679abfc24461b79e3bfa2c6d748cd9e6f1a92958ef20226db72d4a9182302.svg" as="image" type="image/svg+xml"> 1006 </div> 1007 1008
1008<script> 1009 (function() { 1010 var promptEl = document.getElementById('lp-ai-prompt-text'); 1011 var outputEl = document.getElementById('lp-ai-output'); 1012 if (!promptEl || !outputEl) return; 1013 1014 var EXAMPLES = [ 1015 { 1016 prompt: "Show user onboarding pain points from these 20 reviews.", 1017 src: "/assets/v2/ai-journey-onboarding-b26f3ca47f55f578253506bd22820993dce4ddfd926828f56e773c506254d6cb.svg", 1018 alt: "Journey map of onboarding pain points" 1019 }, 1020 { 1021 prompt: "Extract the domain model from this architecture call transcript.", 1022 src: "/assets/v2/ai-class-domain-aece7ccff1280d85b537732c332b79a5e48fc8d42ab90263afed9055046a4752.svg", 1023 alt: "Class diagram of a SaaS domain model" 1024 }, 1025 { 1026 prompt: "Turn this stakeholder email into a now / next / later roadmap.", 1027 src: "/assets/v2/ai-roadmap-quarters-0ed679abfc24461b79e3bfa2c6d748cd9e6f1a92958ef20226db72d4a9182302.svg", 1028 alt: "Roadmap with Now, Next and Later columns" 1029 } 1030 ]; 1031 1032 var CARET = '<span class="lp-ai-caret"></span>'; 1033 var reduced = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches; 1034 1035 // Random first slide so different visitors land on different examples. 1036 var idx = Math.floor(Math.random() * EXAMPLES.length); 1037 1038 // Build a fresh <object> per cycle. Object (not img) is required so the 1039 // SVG can fetch its own Google Fonts (Playpen Sans for napkin theme). 1040 // Recreating the element ensures the load event fires reliably. 1041 function makeObject(ex, onLoad) { 1042 var obj = document.createElement('object'); 1043 obj.type = 'image/svg+xml'; 1044 obj.setAttribute('aria-label', ex.alt); 1045 obj.addEventListener('load', function() { onLoad && onLoad(); }, { once: true }); 1046 obj.data = ex.src; 1047 return obj; 1048 } 1049 1050 if (reduced) { 1051 var ex = EXAMPLES[idx]; 1052 promptEl.innerHTML = ex.prompt + CARET; 1053 outputEl.appendChild(makeObject(ex)); 1054 outputEl.classList.add('visible'); 1055 return; 1056 } 1057 1058 function type(text, i, done) { 1059 if (i > text.length) { done(); return; } 1060 promptEl.innerHTML = text.slice(0, i) + CARET; 1061 setTimeout(function() { type(text, i + 1, done); }, 45 + Math.random() * 45); 1062 } 1063 1064 function cycle() { 1065 var ex = EXAMPLES[idx]; 1066 idx = (idx + 1) % EXAMPLES.length; 1067 promptEl.innerHTML = CARET; 1068 outputEl.classList.remove('visible'); 1069 1070 setTimeout(function() { 1071 type(ex.prompt, 0, function() { 1072 // Build the <object> once typing finishes; reveal only after 1073 // it loads so we never show a half-rendered SVG (or fallback fonts). 1074 var obj = makeObject(ex, function() { 1075 outputEl.classList.add('visible'); 1076 setTimeout(cycle, 9000); 1077 }); 1078 // Replace previous object (if any) with the fresh one. 1079 outputEl.innerHTML = ''; 1080 outputEl.appendChild(obj); 1081 // Safety net: if load never fires (cached, or quirky browser), 1082 // reveal after a short timeout anyway. 1083 setTimeout(function() { 1084 if (!outputEl.classList.contains('visible')) { 1085 outputEl.classList.add('visible'); 1086 setTimeout(cycle, 9000); 1087 } 1088 }, 1500); 1089 }); 1090 }, 700); 1091 } 1092 1093 // Start when the section scrolls into view, then loop indefinitely. 1094 if ('IntersectionObserver' in window) { 1095 var io = new IntersectionObserver(function(entries) { 1096 entries.forEach(function(e) { 1097 if (e.isIntersecting) { cycle(); io.disconnect(); } 1098 }); 1099 }, { threshold: 0.25 }); 1100 io.observe(outputEl); 1101 } else { 1102 cycle(); 1103 } 1104 })(); 1105 </script>
1105 1106</section> 1107 1108<!-- LOGO BAR --> 1109<section class="section lp-logos" style="padding: 2rem 1.5rem;"> 1110 <div class="container"> 1111 <p class="has-text-centered has-text-weight-semibold is-size-7 is-uppercase" style="letter-spacing: 0.08em; margin-bottom: 1rem;"> 1112 Trusted by teams at — since 2009 1113 </p> 1114 <div class="columns is-mobile is-multiline is-centered is-vcentered"> 1115 <div class="column is-4-mobile is-2-desktop has-text-centered" style="padding: 1rem 1.5rem;"><img style="width: 140px; height: auto;" src="/assets/microsoft-ad282b080372d1ca7a955dc575d1309ccbd5ac232ca913e284c830d8e69c006b.png" /></div> 1116 <div class="column is-4-mobile is-2-desktop has-text-centered" style="padding: 1rem 1.5rem;"><img style="width: 140px; height: auto;" src="/assets/lockheed_martin-83ce3e2225a5f0a1d9929ab0dc3433a1177aeecbb17f14e2f61fb3e8790af009.png" /></div> 1117 <div class="column is-4-mobile is-2-desktop has-text-centered" style="padding: 1rem 1.5rem;"><img style="width: 140px; height: auto;" src="/assets/twitter_logo-353bc6390889b29e8999fbb55ae4c64c25ef0b98770774bde5f9fc7801b5116c.png" /></div> 1118 <div class="column is-4-mobile is-2-desktop has-text-centered" style="padding: 1rem 1.5rem;"><img style="width: 140px; height: auto;" src="/assets/mclaren-2f3be345e9cc3efccdad63ffe4675f214211b79b1db80c2734a281bef33fc68d.png" /></div> 1119 <div class="column is-4-mobile is-2-desktop has-text-centered" style="padding: 1rem 1.5rem;"><img style="width: 140px; height: auto;" src="/assets/bose-1bd1e8bd27297184c562669e2bb83f691ae750d876a6b08b2c509a0eadbd32b0.png" /></div> 1120 <div class="column is-4-mobile is-2-desktop has-text-centered" style="padding: 1rem 1.5rem;"><img style="width: 140px; height: auto;" src="/assets/amazon-d67c715f309d67a677eb2316edbdc118cb2444510e5b959214443031f9157863.png" /></div> 1121 </div> 1122 </div> 1123</section> 1124 1125<!-- PRODUCT ORIENTATION --> 1126 1127<style> 1128 .lp-product { background: #FAF9F7; } 1129 .lp-product .lp-product-screenshot, 1130 .lp-product .lp-product-screenshot-placeholder { 1131 width: 100%; max-width: 620px; margin: 0 auto; 1132 border-radius: 12px; 1133 display: block; 1134 } 1135 .lp-product .lp-product-screenshot { 1136 filter: drop-shadow(0 18px 30px rgba(20, 18, 16, 0.14)) drop-shadow(0 4px 10px rgba(20, 18, 16, 0.06)); 1137 } 1138 .lp-product .lp-product-screenshot-placeholder { 1139 aspect-ratio: 16 / 10; 1140 background: linear-gradient(135deg, #F3F1EE 0%, #E7E5E4 100%); 1141 box-shadow: 0 18px 50px rgba(20, 18, 16, 0.18), 0 4px 12px rgba(20, 18, 16, 0.08); 1142 display: flex; align-items: center; justify-content: center; 1143 color: #78716C; font-size: 0.9rem; text-align: center; padding: 1.5rem; 1144 } 1145 .lp-product .lp-product-screenshot-placeholder code { 1146 background: rgba(20, 18, 16, 0.06); padding: 0.15rem 0.4rem; 1147 border-radius: 4px; font-size: 0.82rem; color: #44403C; 1148 } 1149 .lp-product .lp-value-card { 1150 background: #fff; border-radius: 10px; 1151 padding: 1.25rem 1.25rem 1.1rem; 1152 box-shadow: 0 2px 10px rgba(20, 18, 16, 0.06); 1153 height: 100%; 1154 } 1155 .lp-product .lp-value-icon { 1156 width: 36px; height: 36px; border-radius: 8px; 1157 display: inline-flex; align-items: center; justify-content: center; 1158 background: #EEF3E8; color: #577939; font-size: 1rem; 1159 margin-bottom: 0.85rem; 1160 } 1161 .lp-product .lp-value-card h4 { 1162 color: #1C1917; font-size: 1rem; font-weight: 700; 1163 margin-bottom: 0.35rem; 1164 } 1165 .lp-product .lp-value-card p { 1166 color: #57534E; font-size: 0.9rem; line-height: 1.5; margin: 0; 1167 } 1168</style> 1169 1170<section id="product" class="section is-medium lp-product" style="padding-top: 5rem; padding-bottom: 5rem;"> 1171 <div class="container"> 1172 1173 <div class="columns is-vcentered" style="margin-bottom: 3rem;"> 1174 <div class="column is-6"> 1175 <img alt="The yUML playground showing a few lines of text on the left and a polished diagram rendered on the right" class="lp-product-screenshot" src="/assets/v2/playground-hero-294af08f4a6f87a8efe8f6c106f37375c4308a3948b6d01d8aeaef5e3c50c2d9.png" /> 1176 </div> 1177 1178 <div class="column is-5 is-offset-1"> 1179 <h2 class="title is-2 is-size-3-mobile lp-heading" style="line-height: 1.15; margin-bottom: 1rem;"> 1180 Write it, script it or generate with AI. 1181 </h2> 1182 <p class="is-size-5 is-size-6-mobile lp-body" style="margin-bottom: 2rem; max-width: 480px;"> 1183 Describe what you want in a few lines of text. yUML creates beautiful diagrams to
1183share or save. No fiddling with layout. 1184 </p> 1185 <p> 1186 <a href="https://app.yuml.me/playground" target="_blank" rel="noopener" class="button is-medium is-rounded lp-btn-primary"> 1187 Open the Playground → 1188 </a> 1189 </p> 1190 </div> 1191 </div> 1192 1193 <div class="columns is-multiline" style="margin-top: 1rem;"> 1194 <div class="column is-3"> 1195 <div class="lp-value-card"> 1196 <div class="lp-value-icon"><i class="fas fa-bolt"></i></div> 1197 <h4>Idea to diagram in seconds</h4> 1198 <p>Describe a software architecture, user flow or chart in plain text. Your diagram appears as you type.</p> 1199 </div> 1200 </div> 1201 <div class="column is-3"> 1202 <div class="lp-value-card"> 1203 <div class="lp-value-icon"><i class="fas fa-palette"></i></div> 1204 <h4>Eight visual styles</h4> 1205 <p>Sketch, napkin, blueprint, clean, midnight and more. Find a look that works for your blog, book or document.</p> 1206 </div> 1207 </div> 1208 <div class="column is-3"> 1209 <div class="lp-value-card"> 1210 <div class="lp-value-icon"><i class="fas fa-terminal"></i></div> 1211 <h4>Hand-typed or scripted</h4> 1212 <p>Write yUML in the playground, or generate it from a script, CI pipeline or AI agent. Same DSL either way.</p> 1213 </div> 1214 </div> 1215 <div class="column is-3"> 1216 <div class="lp-value-card"> 1217 <div class="lp-value-icon"><i class="fas fa-history"></i></div> 1218 <h4>Save, version, export</h4> 1219 <p>Every diagram lives as plain text. Roll back changes, copy the DSL anywhere, take it with you.</p> 1220 </div> 1221 </div> 1222 </div> 1223 1224 </div> 1225</section> 1226 1227 1228<!-- STORIES (Pro Beta) --> 1229 1230<style> 1231 .lp-stories { background: #F3F1EE; } 1232 .lp-stories .lp-eyebrow { 1233 display: inline-flex; align-items: center; gap: 0.5rem; 1234 padding: 0.4rem 0.9rem; border-radius: 999px; 1235 background: #FFF6E5; color: #B45309; 1236 font-size: 0.85rem; font-weight: 600; 1237 margin-bottom: 1.25rem; 1238 } 1239 .lp-stories .lp-eyebrow-dot { 1240 width: 7px; height: 7px; border-radius: 50%; background: #D97706; 1241 box-shadow: 0 0 0 4px rgba(217, 119, 6, 0.18); 1242 } 1243 .lp-stories .lp-stories-screenshot, 1244 .lp-stories .lp-stories-screenshot-placeholder { 1245 width: 100%; max-width: 620px; margin: 0 auto; 1246 border-radius: 12px; 1247 box-shadow: 0 18px 50px rgba(20, 18, 16, 0.18), 0 4px 12px rgba(20, 18, 16, 0.08); 1248 background: #fff; display: block; 1249 } 1250 .lp-stories .lp-stories-screenshot-placeholder { 1251 aspect-ratio: 16 / 10; 1252 background: linear-gradient(135deg, #F3F1EE 0%, #E7E5E4 100%); 1253 display: flex; align-items: center; justify-content: center; 1254 color: #78716C; font-size: 0.9rem; text-align: center; padding: 1.5rem; 1255 } 1256 .lp-stories .lp-stories-screenshot-placeholder code { 1257 background: rgba(20, 18, 16, 0.06); padding: 0.15rem 0.4rem; 1258 border-radius: 4px; font-size: 0.82rem; color: #44403C; 1259 } 1260 .lp-stories .lp-value-card { 1261 background: #fff; border-radius: 10px; 1262 padding: 1.25rem 1.25rem 1.1rem; 1263 box-shadow: 0 2px 10px rgba(20, 18, 16, 0.06); 1264 height: 100%; 1265 } 1266 .lp-stories .lp-value-icon { 1267 width: 36px; height: 36px; border-radius: 8px; 1268 display: inline-flex; align-items: center; justify-content: center; 1269 background: #EEF3E8; color: #577939; font-size: 1rem; 1270 margin-bottom: 0.85rem; 1271 } 1272 .lp-stories .lp-value-card h4 { 1273 color: #1C1917; font-size: 1rem; font-weight: 700; 1274 margin-bottom: 0.35rem; 1275 } 1276 .lp-stories .lp-value-card p { 1277 color: #57534E; font-size: 0.9rem; line-height: 1.5; margin: 0; 1278 } 1279 1280</style> 1281 1282<section id="stories" class="section is-medium lp-stories" style="padding-top: 5rem; padding-bottom: 5rem;"> 1283 <div class="container"> 1284 1285 <div class="columns is-vcentered" style="margin-bottom: 3rem;"> 1286 <div class="column is-5"> 1287 <span class="lp-eyebrow"> 1288 <span class="lp-eyebrow-dot"></span> 1289 Early access available for Pro subscribers 1290 </span> 1291 <h2 class="title is-2 is-size-3-mobile lp-heading" style="line-height: 1.15; margin-bottom: 1rem;"> 1292 Try Stories - a new way to think things through. 1293 </h2> 1294 <p class="is-size-5 is-size-6-mobile lp-body" style="margin-bottom: 2rem; max-width: 480px;"> 1295 Stories give you a visual notepad for exploring ideas. Combine markdown with diagrams for architecture, user journeys, roadmaps and data. 1296 </p> 1297 <p style="display: flex; align-items: center; flex-wrap: wrap; gap: 1rem;"> 1298 <a href="https://app.yuml.me/pricing" class="button is-medium is-rounded lp-btn-primary"> 1299 Get Stories with Pro → 1300 </a> 1301 <a href="https://app.yuml.me/pricing" class="lp-link is-size-6"> 1302 See all plans → 1303 </a> 1304 </p> 1305 </div> 1306 1307 <div class="column is-6 is-offset-1">
1308 <video autoplay="autoplay" muted="muted" loop="loop" playsinline="true" aria-label="An animated yuml Story flipping through prose, a user journey, a chart and a C4 diagram across multiple pages" class="lp-stories-screenshot" src="/assets/v2/stories-hero-611634296451d6ff513d2671e953cc0576320c77e83a1cdd46e15470eb695695.mp4"></video> 1309 </div> 1310 </div> 1311 1312 <div class="columns is-multiline" style="margin-top: 1rem;"> 1313 <div class="column is-3"> 1314 <div class="lp-value-card"> 1315 <div class="lp-value-icon"><i class="fas fa-layer-group"></i></div> 1316 <h4>Let your thoughts unfold</h4> 1317 <p>One diagram is rarely the whole idea. Stories let you combine text and multiple diagrams whilst exploring ideas.</p> 1318 </div> 1319 </div> 1320 <div class="column is-3"> 1321 <div class="lp-value-card"> 1322 <div class="lp-value-icon"><i class="fas fa-chart-bar"></i></div> 1323 <h4>Data woven in</h4> 1324 <p>Drop charts beside diagrams. Show roadmap calls in the context of the numbers behind them.</p> 1325 </div> 1326 </div> 1327 <div class="column is-3"> 1328 <div class="lp-value-card"> 1329 <div class="lp-value-icon"><i class="fas fa-magic"></i></div> 1330 <h4>AI when you want it</h4> 1331 <p>Paste raw notes, ask for a class diagram, user journey map or a C4 context diagram. Or write every word yourself. </p> 1332 </div> 1333 </div> 1334 <div class="column is-3"> 1335 <div class="lp-value-card"> 1336 <div class="lp-value-icon"><i class="fas fa-share-alt"></i></div> 1337 <h4>Share or co-edit</h4> 1338 <p>Private links for stakeholders. Team workspaces let others edit alongside you. Private and public sharing.</p> 1339 </div> 1340 </div> 1341 </div> 1342 1343 </div> 1344</section> 1345 1346 1347<!-- HOW IT WORKS --> 1348<section class="section is-medium lp-warm"> 1349 <div class="container"> 1350 <h2 class="title is-3 has-text-centered lp-heading">Three ways to create diagrams</h2> 1351 <p class="has-text-centered lp-muted" style="margin-bottom: 2.5rem;">No fiddly drag-and-drop layout. Just type, render, and share.</p> 1352 1353 <!-- Panel 1: Editor --> 1354 <div class="columns is-vcentered" style="margin-bottom: 3rem;"> 1355 <div class="column is-6"> 1356 <div class="lp-code" style="font-size: 0.85rem;">[Customer|name;email|placeOrder()] 1357[Order|date;total;status|ship();cancel()] 1358[Product|name;sku;price] 1359[Customer]-0..*>[Order] 1360[Order]++-*>[Product]</div> 1361 </div> 1362 <div class="column is-5 is-offset-1"> 1363 <div class="lp-step-num">1</div> 1364 <h3 class="title is-4 lp-heading">Type it in the editor</h3> 1365 <p class="lp-body"> 1366 Write a few words of concise syntax and see your diagram update live. 1367 No alignment tools, no snapping, no layout headaches. 1368 </p> 1369 <p style="margin-top: 1rem;"> 1370 <a href="https://app.yuml.me/playground" target="_blank" rel="noopener" class="lp-link">Open the playground →</a> 1371 </p> 1372 </div> 1373 </div> 1374 1375 <!-- Panel 2: API --> 1376 <div class="columns is-vcentered" style="margin-bottom: 3rem;"> 1377 <div class="column is-5"> 1378 <div class="lp-step-num">2</div> 1379 <h3 class="title is-4 lp-heading">Generate from code or CI</h3> 1380 <p class="lp-body"> 1381 Because diagrams are text, you can create them from scripts, 1382 CI pipelines, or any language that can make an HTTP request. 1383 Tool vendors use this to integrate yUML with blogs, wikis, and docs. 1384 </p> 1385 </div> 1386 <div class="column is-6 is-offset-1"> 1387 <div class="lp-code" style="font-size: 0.8rem;"><span style="color: #78716c;"># Render a class diagram via the API</span> 1388curl https://app.yuml.me/diagram/v1/class/sketch/ \ 1389 %5BUser%7Cname%5D-%3E%5BAccount%5D.svg \ 1390 -o diagram.svg 1391 1392<span style="color: #78716c;"># Or embed directly in Markdown</span> 1393</div> 1395 </div> 1396 </div> 1397 1398 <!-- Panel 3: Embed --> 1399 <div class="columns is-vcentered"> 1400 <div class="column is-6"> 1401 <div class="lp-code" style="font-size: 0.8rem;"><span style="color: #78716c;"><!-- Embed in any web page or wiki --></span> 1402<img src="https://app.yuml.me/diagram/v1/ 1403 class/sketch/%5BUser%5D-%3E%5BAccount%5D.svg" 1404 alt="Class diagram" /> 1405 1406<span style="color: #78716c;"><!-- Or use the SVG in Figma, Slack, </span> 1407<span style="color: #78716c;"> Confluence, Notion... anywhere. --></span></div> 1408 </div> 1409 <div class="column is-5 is-offset-1"> 1410 <div class="lp-step-num">3</div> 1411 <h3 class="title is-4 lp-heading">
1411Embed anywhere</h3> 1412 <p class="lp-body"> 1413 Drop a URL into GitHub, Slack, Confluence, Notion, or a plain 1414 <code><img></code> tag. The SVG renders beautifully at any size. 1415 Copy into Figma, Keynote, or Google Slides as a vector. 1416 </p> 1417 </div> 1418 </div> 1419 </div> 1420</section> 1421 1422<!-- DIAGRAM TYPES --> 1423<section id="diagram-types" class="section is-medium lp-stone"> 1424 <div class="container"> 1425 <h2 class="title is-3 has-text-centered lp-heading">13 diagram types and counting</h2> 1426 <p class="has-text-centered lp-muted" style="margin-bottom: 2.5rem;">Software, product, and chart diagrams — all from text</p> 1427 1428 <div class="columns is-centered"> 1429 <div class="column is-4"> 1430 <div class="lp-diagram-card" 1431 role="button" tabindex="0" 1432 data-index="0" 1433 data-src="/assets/v2/pie-sketch-fb9112bd201b002f39af3c364451c2b6e0c62e12d0cd021ae672bd780f7fafd4.svg" 1434 data-label="Pie Chart"> 1435 <object data="/assets/v2/pie-sketch-fb9112bd201b002f39af3c364451c2b6e0c62e12d0cd021ae672bd780f7fafd4.svg" type="image/svg+xml"></object> 1436 <div class="lp-card-label">Pie Chart</div> 1437 </div> 1438 </div> 1439 <div class="column is-4"> 1440 <div class="lp-diagram-card" 1441 role="button" tabindex="0" 1442 data-index="1" 1443 data-src="/assets/v2/journey-sketch-254bfefd107f77a9fedddee13851132d1b03d6198af9c7d8b69b693d2edf1412.svg" 1444 data-label="User Journey"> 1445 <object data="/assets/v2/journey-sketch-254bfefd107f77a9fedddee13851132d1b03d6198af9c7d8b69b693d2edf1412.svg" type="image/svg+xml"></object> 1446 <div class="lp-card-label">User Journey</div> 1447 </div> 1448 </div> 1449 <div class="column is-4"> 1450 <div class="lp-diagram-card" 1451 role="button" tabindex="0" 1452 data-index="2" 1453 data-src="/assets/v2/sequence-sketch-4cb5ba284f3f0f81481041efab9e6ac041fc868d7d370bdc78c59e9b232e905e.svg" 1454 data-label="Sequence"> 1455 <object data="/assets/v2/sequence-sketch-4cb5ba284f3f0f81481041efab9e6ac041fc868d7d370bdc78c59e9b232e905e.svg" type="image/svg+xml"></object> 1456 <div class="lp-card-label">Sequence</div> 1457 </div> 1458 </div> 1459 </div> 1460 <div class="columns is-centered"> 1461 <div class="column is-4"> 1462 <div class="lp-diagram-card" 1463 role="button" tabindex="0" 1464 data-index="3" 1465 data-src="/assets/v2/state-sketch-c232e3651811b2d762083a2c7e2d8dae51cbb97dbfa687aec491df6366cb4d64.svg" 1466 data-label="State"> 1467 <object data="/assets/v2/state-sketch-c232e3651811b2d762083a2c7e2d8dae51cbb97dbfa687aec491df6366cb4d64.svg" type="image/svg+xml"></object> 1468 <div class="lp-card-label">
1468State</div> 1469 </div> 1470 </div> 1471 <div class="column is-4"> 1472 <div class="lp-diagram-card" 1473 role="button" tabindex="0" 1474 data-index="4" 1475 data-src="/assets/v2/class-sketch-b2981cfe281b34b992d1aa56b01acf4af581c725cfbaa11bd07b13bb41ab2f5c.svg" 1476 data-label="Class"> 1477 <object data="/assets/v2/class-sketch-b2981cfe281b34b992d1aa56b01acf4af581c725cfbaa11bd07b13bb41ab2f5c.svg" type="image/svg+xml"></object> 1478 <div class="lp-card-label">Class</div> 1479 </div> 1480 </div> 1481 <div class="column is-4"> 1482 <div class="lp-diagram-card" 1483 role="button" tabindex="0" 1484 data-index="5" 1485 data-src="/assets/v2/bar-sketch-7335b4e47d73b6198552b6f658df3bbe22b80063f9b12d12ccfa59772eb1432e.svg" 1486 data-label="Bar Chart"> 1487 <object data="/assets/v2/bar-sketch-7335b4e47d73b6198552b6f658df3bbe22b80063f9b12d12ccfa59772eb1432e.svg" type="image/svg+xml"></object> 1488 <div class="lp-card-label">Bar Chart</div> 1489 </div> 1490 </div> 1491 </div> 1492 <div class="columns is-centered"> 1493 <div class="column is-4"> 1494 <div class="lp-diagram-card" 1495 role="button" tabindex="0" 1496 data-index="6" 1497 data-src="/assets/v2/activity-sketch-1e7db1db9d6147c54feb69d36ebd70555323804b6a45036dadf9149e0738a1e1.svg" 1498 data-label="Activity"> 1499 <object data="/assets/v2/activity-sketch-1e7db1db9d6147c54feb69d36ebd70555323804b6a45036dadf9149e0738a1e1.svg" type="image/svg+xml"></object> 1500 <div class="lp-card-label">Activity</div> 1501 </div> 1502 </div> 1503 <div class="column is-4"> 1504 <div class="lp-diagram-card" 1505 role="button" tabindex="0" 1506 data-index="7" 1507 data-src="/assets/v2/column-sketch-9bfcdc51ab41b17daa999e8fa7137a60b4c435e9d15a4d0f8442791faa94ea3f.svg" 1508 data-label="Column Chart"> 1509 <object data="/assets/v2/column-sketch-9bfcdc51ab41b17daa999e8fa7137a60b4c435e9d15a4d0f8442791faa94ea3f.svg" type="image/svg+xml"></object> 1510 <div class="lp-card-label">Column Chart</div> 1511 </div> 1512 </div> 1513 <div class="column is-4"> 1514 <div class="lp-diagram-card" 1515 role="button" tabindex="0" 1516 data-index="8" 1517 data-src="/assets/v2/timeline-sketch-a61d237eb48eb1a62ddd271fde45c51a6928c306846493e0b37f2b81dfab758c.svg" 1518 data-label="Timeline"> 1519 <object data="/assets/v2/timeline-sketch-a61d237eb48eb1a62ddd271fde45c51a6928c306846493e0b37f2b81dfab758c.svg" type="image/svg+xml"></object> 1520 <div class="lp-card-label">Timeline</div> 1521 </div> 1522 </div> 1523 </div> 1524 <div class="columns is-centered"> 1525 <div class="column is-4"> 1526 <div class="lp-diagram-card" 1527 role="button" tabindex="0" 1528 data-index="9" 1529 data-src="/assets/v2/usecase-sketch-b3b7ed4e47d0d9d49aaf6055355e88889b88b0095d699ef08742c7279cef1f6f.svg" 1530 data-label="Use Case"> 1531 <object data="/assets/v2/usecase-sketch-b3b7ed4e47d0d9d49aaf6055355e88889b88b0095d699ef08742c7279cef1f6f.svg" type="image/svg+xml"></object> 1532 <div class="lp-card-label">Use Case</div> 1533 </div> 1534 </div> 1535 <div class="column is-4"> 1536 <div class="lp-diagram-card" 1537 role="button" tabindex="0" 1538 data-index="10" 1539 data-src="/assets/v2/line-sketch-2ab1d859718dfba1d187502f47a899241d267c5ced4418eedd687d5fb4dcb57c.svg" 1540 data-label="Line Chart"> 1541 <object data="/assets/v2/line-sketch-2ab1d859718dfba1d187502f47a899241d267c5ced4418eedd687d5fb4dcb57c.svg" type="image/svg+xml"></object> 1542 <div class="lp-card-label">Line Chart</div> 1543 </div> 1544 </div> 1545 <div class="column is-4"> 1546 <div class="lp-diagram-card" 1547 role="button" tabindex="0" 1548 data-index="11" 1549 data-src="/assets/v2/roadmap-sketch-cf7828d6ae59d7e8257261debf90059337cd984205cd5bdaa470f9a76b74d3ba.svg" 1550 data-label="Roadmap"> 1551 <object data="/assets/v2/roadmap-sketch-cf7828d6ae59d7e8257261debf90059337cd984205cd5bdaa470f9a76b74d3ba.svg" type="image/svg+xml"></object> 1552 <div class="lp-card-label">Roadmap</div> 1553 </div> 1554 </div> 1555 </div> 1556 <div class="columns is-centered"> 1557 <div class="column is-4"> 1558 <div class="lp-diagram-card" 1559 role="button" tabindex="0" 1560 data-index="12" 1561 data-src="/assets/v2/c4-sketch-b444c9b24c9071c72b78301bb94cac5865e37fa120405071b6f5164f353c9323.svg" 1562 data-label="C4 Architecture"> 1563 <object data="/assets/v2/c4-sketch-b444c9b24c9071c72b78301bb94cac5865e37fa120405071b6f5164f353c9323.svg" type="image/svg+xml"></object> 1564 <div class="lp-card-label">C4 Architecture</div> 1565 </div> 1566 </div> 1567 </div> 1568 1569 <div class="has-text-centered" style="margin-top: 2.5rem;"> 1570 <a href="https://app.yuml.me/showcase" target="_blank" rel="noopener" class="lp-heading has-text-weight-bold is-size-5" style="text-decoration: none;"> 1571 Explore the Gallery → 1572 </a> 1573 <p class="lp-muted is-size-6" style="margin-top: 0.25rem;">See all styles applied to every diagram type</p> 1574 </div> 1575 </div> 1576</section> 1577 1578<!-- CODE EXAMPLE --> 1579<section class="section is-medium lp-warm"> 1580 <div class="container"> 1581 <div class="columns is-vcentered"> 1582 <div class="column is-5"> 1583 <div class="lp-code">[Customer|name;email|placeOrder()] 1584[Order|date;total|ship()] 1585[Customer]-orders>[Order]</div> 1586 </div> 1587 <div class="column is-offset-1 is-5"> 1588 <object 1589 data="/assets/v2/code-example-564047e6e60edd1d60ca2517e27549e724fb114f7d974ebda32627fbd7beeb01.svg" 1590 type="image/svg+xml" 1591 style="width: 100%; max-height: 300px; border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.08); background: #fff; padding: 1rem;" 1592 ></object> 1593 <p class="lp-heading has-text-weight-bold is-size-5" style="margin-top: 1.25rem;"> 1594 Shorter than other text-to-diagram tools. 1595 </p> 1596 <p class="lp-body" style="margin-top: 0.5rem;"> 1597 yUML's concise syntax means fewer characters, fewer errors, and fewer AI tokens when generating diagrams with LLMs. 1598 </p> 1599 <p style="margin-top: 1rem;"> 1600 <a href="https://app.yuml.me/playground" target="_blank" rel="noopener" class="lp-link is-size-5">Try it in the playground →</a> 1601 </p> 1602 </div> 1603 </div> 1604 </div> 1605</section> 1606 1607<!-- BUILT FOR AI --> 1608<section class="section is-medium lp-dark">
1609 <div class="container"> 1610 <h2 class="title is-3 has-text-centered">Built for the age of AI agents</h2> 1611 <div class="columns" style="margin-top: 2rem;"> 1612 <div class="column has-text-centered"> 1613 <h3 class="title is-5">Structured syntax</h3> 1614 <p>A consistent, predictable grammar that AI models can learn and reproduce reliably</p> 1615 </div> 1616 <div class="column has-text-centered"> 1617 <h3 class="title is-5">API-first</h3> 1618 <p>Server-side rendering with a simple authenticated API — perfect for automation</p> 1619 </div> 1620 <div class="column has-text-centered"> 1621 <h3 class="title is-5">Fewest tokens</h3> 1622 <p>The most concise syntax of any text-to-diagram tool — fewer tokens, fewer errors</p> 1623 </div> 1624 </div> 1625 </div> 1626</section> 1627 1628<!-- FOR WRITERS, FOUNDERS, EDUCATORS --> 1629<section class="section is-medium lp-stone"> 1630 <div class="container"> 1631 <div class="columns is-vcentered"> 1632 <div class="column is-6"> 1633 <h2 class="title is-3 lp-heading">For writers, founders and educators</h2> 1634 <p class="lp-body" style="margin-top: 1rem;"> 1635 Diagrams take time. Most blog posts, decks and explainers ship without one, 1636 or with one that took longer than the rest of the work. yUML brings the cost 1637 down enough that adding a diagram feels closer to adding a code block. 1638 </p> 1639 <ul class="lp-body" style="margin-top: 1rem; padding-left: 1.25rem; list-style: disc;"> 1640 <li style="margin-bottom: 0.5rem;">A few lines of text becomes a polished SVG you can paste into any blog, deck or doc.</li> 1641 <li style="margin-bottom: 0.5rem;">Saved diagrams stay editable, so you can revise them as your post or pitch evolves.</li> 1642 <li style="margin-bottom: 0.5rem;">Export the SVG and edit in Figma if you ever need to. Nothing about your work is locked into yUML.</li> 1643 </ul> 1644 <p style="margin-top: 1.25rem;"> 1645 <a href="https://app.yuml.me/playground" target="_blank" rel="noopener" class="lp-link">Open the playground →</a> 1646 </p> 1647 </div> 1648 <div class="column is-5 is-offset-1 has-text-centered"> 1649 <object 1650 data="/assets/v2/column-sketch-9bfcdc51ab41b17daa999e8fa7137a60b4c435e9d15a4d0f8442791faa94ea3f.svg" 1651 type="image/svg+xml" 1652 style="width: 100%; max-height: 320px; border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.08); background: #fff; padding: 1rem;" 1653 ></object> 1654 <p class="lp-muted is-size-7" style="margin-top: 0.5rem;"> 1655 Hand-drawn charts, generated from text in a few seconds. 1656 </p> 1657 </div> 1658 </div> 1659 </div> 1660</section> 1661 1662<!-- FOR ENGINEERS, DEVOPS, AI BUILDERS --> 1663<section class="section is-medium lp-warm"> 1664 <div class="container"> 1665 <div class="columns is-vcentered"> 1666 <div class="column is-6"> 1667 <div class="lp-code" style="font-size: 0.8rem;"><span style="color: #78716c;"># Generate an architecture diagram</span> 1668<span style="color: #78716c;"># from CI after each deploy</span> 1669curl -X POST https://app.yuml.me/diagram \ 1670 -H "Authorization: Bearer $YUML_KEY" \ 1671 -H "Content-Type: application/json" \ 1672 -d '{ 1673 "type": "c4", 1674 "style": "clean", 1675 "dsl": "[Web]->[API]->[Database]" 1676 }' > architecture.svg 1677 1678<span style="color: #78716c;"># Or have an AI agent draft one</span> 1679<span style="color: #78716c;"># from your repo and POST it for you.</span></div> 1680 </div> 1681 <div class="column is-5 is-offset-1"> 1682 <h2 class="title is-3 lp-heading">For engineers and AI builders</h2> 1683 <p class="lp-body" style="margin-top: 1rem;"> 1684 Architecture diagrams in docs tend to drift out of date because updating them 1685 is a separate task. yUML's text format means diagrams can live alongside code, 1686 generated from CI on every PR, from a script when something changes, or from 1687 an AI agent looking at the codebase. 1688 </p> 1689 <ul class="lp-body" style="margin-top: 1rem; padding-left: 1.25rem; list-style: disc;"> 1690 <li style="margin-bottom: 0.5rem;">One HTTP call per diagram, returning SVG or PNG. Works from any language or workflow that can call an API.</li> 1691 <li style="margin-bottom: 0.5rem;">Concise syntax that AI models already write fluently, often in fewer tokens than alternatives.</li> 1692 <li style="margin-bottom: 0.5rem;">Pro accounts can bypass our render cache, so the diagrams you generate aren't held on our servers.</li> 1693 </ul> 1694 <p style="margin-top: 1.25rem;"> 1695 <a href="https://app.yuml.me/docs" target="_blank" rel="noopener" class="lp-link">Read the API docs →</a> 1696 </p> 1697 </div> 1698 </div> 1699 </div> 1700</section> 1701 1702<!-- FINAL CTA --> 1703<section class="section is-medium lp-warm"> 1704 <div class="container has-text-centered"> 1705 <h2 class="title is-2 lp-heading">Start diagramming in seconds</h2> 1706 <p style="margin-bottom: 2rem;"> 1707 <a href="https://app.yuml.me/users/sign_up" target="_blank" rel="noopener" class="button is-medium is-rounded lp-btn-primary">Create Free Account</a> 1708 </p> 1709 <p class="lp-muted"> 1710 Or <a href="https://app.yuml.me/playground" target="_blank" rel="noopener" class="lp-link">try the playground first →</a> 1711 </p> 1712 <p class="lp-muted is-size-7" style="margin-top: 1rem;">No credit card required.</p> 1713 </div> 1714</section> 1715 1716<!-- Lightbox overlay --> 1717<div id="lp-lightbox" class="lp-lightbox" role="dialog" aria-modal="true" aria-hidden="true" aria-label="Diagram preview"> 1718 <button class="lp-lightbox-nav prev" type="button" aria-label="Previous diagram">←</button> 1719 <div class="lp-lightbox-content"> 1720 <button class="lp-lightbox-close" type="button" aria-label="Close">×</button> 1721 <object id="lp-lightbox-object" type="image/svg+xml"></object> 1722 <div class="lp-lightbox-label" id="lp-lightbox-label"></div> 1723 </div> 1724 <button class="lp-lightbox-nav next" type="button" aria-label="Next diagram">→</button> 1725</div> 1726
1727<script> 1728 (function() { 1729 var box = document.getElementById('lp-lightbox'); 1730 var obj = document.getElementById('lp-lightbox-object'); 1731 var label = document.getElementById('lp-lightbox-label'); 1732 if (!box || !obj) return; 1733 var closeBtn = box.querySelector('.lp-lightbox-close'); 1734 var prevBtn = box.querySelector('.lp-lightbox-nav.prev'); 1735 var nextBtn = box.querySelector('.lp-lightbox-nav.next'); 1736 var cards = Array.prototype.slice.call(document.querySelectorAll('#diagram-types .lp-diagram-card[data-index]')); 1737 if (!cards.length) return; 1738 var current = 0; 1739 var lastFocus = null; 1740 1741 function render() { 1742 var card = cards[current]; 1743 // Build a fresh <object> per render â mutating `data` on an existing 1744 // <object> doesn't reliably reload the SVG (Safari especially), so 1745 // every click would show whichever diagram loaded first. 1746 var fresh = document.createElement('object'); 1747 fresh.id = 'lp-lightbox-object'; 1748 fresh.type = 'image/svg+xml'; 1749 fresh.data = card.dataset.src; 1750 obj.replaceWith(fresh); 1751 obj = fresh; 1752 label.textContent = card.dataset.label; 1753 } 1754 function open(i) { 1755 current = i; 1756 lastFocus = document.activeElement; 1757 // Tag the lightbox so the marquee closure (also bound to prev/next) 1758 // knows not to step its own cards while a grid card is showing. 1759 box.dataset.source = 'grid'; 1760 render(); 1761 box.classList.add('open'); 1762 box.setAttribute('aria-hidden', 'false'); 1763 document.body.classList.add('lp-lightbox-open'); 1764 closeBtn.focus(); 1765 } 1766 function close() { 1767 box.classList.remove('open'); 1768 box.setAttribute('aria-hidden', 'true'); 1769 document.body.classList.remove('lp-lightbox-open'); 1770 obj.removeAttribute('data'); 1771 delete box.dataset.source; 1772 if (lastFocus && lastFocus.focus) lastFocus.focus(); 1773 } 1774 function step(dir) { 1775 if (box.dataset.source !== 'grid') return; 1776 current = (current + dir + cards.length) % cards.length; 1777 render(); 1778 } 1779 1780 cards.forEach(function(c, i) { 1781 c.addEventListener('click', function() { open(i); }); 1782 c.addEventListener('keydown', function(e) { 1783 if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); open(i); } 1784 }); 1785 }); 1786 closeBtn.addEventListener('click', close); 1787 prevBtn.addEventListener('click', function(e) { e.stopPropagation(); step(-1); }); 1788 nextBtn.addEventListener('click', function(e) { e.stopPropagation(); step(1); }); 1789 box.addEventListener('click', function(e) { if (e.target === box) close(); }); 1790 document.addEventListener('keydown', function(e) { 1791 if (!box.classList.contains('open')) return; 1792 if (e.key === 'Escape') close(); 1793 else if (e.key === 'ArrowLeft') step(-1); 1794 else if (e.key === 'ArrowRight') step(1); 1795 }); 1796 })(); 1797 1798 (function() { 1799 var deck = document.getElementById('hero-deck'); 1800 if (!deck) return; 1801 if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) return; 1802 var cards = Array.prototype.slice.call(deck.children); 1803 var max = cards.length - 1; 1804 var intervalId = null; 1805 1806 var VISIBLE_COUNT = 3; 1807 function parsePos(c) { return parseInt(c.style.getPropertyValue('--pos') || '0', 10); } 1808 function setPos(c, p) { 1809 c.style.setProperty('--pos', String(p)); 1810 // Anything beyond the top VISIBLE_COUNT positions queues invisibly; 1811 // pos 3 â 2 fades back in via the standard opacity transition. 1812 c.classList.toggle('hero-deck-hidden', p >= VISIBLE_COUNT); 1813 } 1814 1815 function advance() { 1816 var top = null; 1817 for (var i = 0; i < cards.length; i++) if (parsePos(cards[i]) === 0) { top = cards[i]; break; } 1818 if (!top) return; 1819 1820 // Visual-only clone that flies off â lets the real card reseat in parallel. 1821 // If the top card is currently hover-lifted, the ghost inherits that state 1822 // and flies off from the elevated position. 1823 var ghost = top.cloneNode(true); 1824 top.parentNode.appendChild(ghost); 1825 1826 // Strip any hover-lift classes from the real card before reseating 1827 top.classList.remove('lifted', 'lift-active'); 1828 1829 // Reseat real card at the back, invisible 1830 top.classList.add('entering'); 1831 setPos(top, max); 1832 // Shift everyone else forward by one 1833 for (var j = 0; j < cards.length; j++) { 1834 if (cards[j] !== top) setPos(cards[j], parsePos(cards[j]) - 1); 1835 } 1836 void top.offsetHeight; // commit reseat + ghost's initial pos=0 state 1837 1838 // Kick off swipe and fade-in on the same frame 1839 requestAnimationFrame(function() { 1840 top.classList.remove('entering'); // opacity 0 -> 1 (850ms) 1841 ghost.classList.add('swiping'); // translate + fade out (850ms) 1842 }); 1843 1844 // Ghost is off-screen and invisible by now â remove it 1845 setTimeout(function() { 1846 if (ghost.parentNode) ghost.parentNode.removeChild(ghost); 1847 }, 1000); 1848 } 1849 1850 var TICK_MS = 3000; 1851 1852 function start() { if (!intervalId) intervalId = setInterval(advance, TICK_MS); } 1853 function stop() { if (intervalId) { clearInterval(intervalId); intervalId = null; } } 1854 1855 // Pause when tab hidden to avoid drift/battery waste 1856 document.addEventListener('visibilitychange', function() { 1857 if (document.hidden) stop(); else if (!isHovered) start(); 1858 }); 1859 1860 // Hover â pause cycle, lift the top card. Unhover â drop, resume. 1861 var wrap = deck.parentNode; 1862 var isHovered = false;
1863 var liftedCard = null; 1864 var dropTimer = null; 1865 1866 function findTop() { 1867 for (var i = 0; i < cards.length; i++) if (parsePos(cards[i]) === 0) return cards[i]; 1868 return null; 1869 } 1870 1871 wrap.addEventListener('mouseenter', function() { 1872 isHovered = true; 1873 stop(); 1874 if (dropTimer) { clearTimeout(dropTimer); dropTimer = null; } 1875 var top = findTop(); 1876 if (top) { 1877 liftedCard = top; 1878 top.classList.add('lift-active', 'lifted'); 1879 } 1880 }); 1881 wrap.addEventListener('mouseleave', function() { 1882 isHovered = false; 1883 if (dropTimer) { clearTimeout(dropTimer); dropTimer = null; } 1884 liftedCard = null; 1885 // Flick the lifted card off right away; advance() handles the liftâswipe 1886 // transition because the ghost inherits the .lifted class state. 1887 advance(); 1888 start(); 1889 }); 1890 1891 start(); 1892 })(); 1893</script>
1893 1894 1895 </div> 1896 1897 <footer class="footer" style="background: #181818; color: #a8a29e; padding: 3rem 1.5rem;"> 1898 <div class="container"> 1899 <div class="columns"> 1900 <div class="column is-4"> 1901 <p style="margin-bottom: 0.5rem;"><img style="height: 32px; width: auto;" src="/assets/yuml_mark_v2-71965635163b1ecbcd3ce7502fb00cfdeca6f2f6c2077c7d1bb1f73d71ac73dd.svg" /></p> 1902 <p>Diagrams AI can write. Humans can read at a glance.</p> 1903 <br> 1904 <p><a href="https://pocketworks.co.uk" style="color: #78716c;" target="_blank" rel="noopener noreferrer">By Pocketworks</a></p> 1905 </div> 1906 1907 <div class="column is-offset-1 is-2"> 1908 <h5 style="color: #e7e5e4; margin-bottom: 0.5rem;">Product</h5> 1909 <ul style="list-style: none;"> 1910 <li><a href="https://app.yuml.me/playground" style="color: #a8a29e;" target="_blank" rel="noopener">Playground</a></li> 1911 <li><a href="https://app.yuml.me/pricing" style="color: #a8a29e;" target="_blank" rel="noopener">Pricing</a></li> 1912 <li><a href="https://app.yuml.me/users/sign_up" style="color: #a8a29e;" target="_blank" rel="noopener">Sign Up</a></li> 1913 <li><a href="https://app.yuml.me/users/sign_in" style="color: #a8a29e;" target="_blank" rel="noopener">Log In</a></li> 1914 </ul> 1915 </div> 1916 1917 <div class="column is-2"> 1918 <h5 style="color: #e7e5e4; margin-bottom: 0.5rem;">Help</h5> 1919 <ul style="list-style: none;"> 1920 <li><a href="/docs" style="color: #a8a29e;">Documentation</a></li> 1921 <li><a href="/changelog" style="color: #a8a29e;">Changelog</a></li> 1922 </ul> 1923 </div> 1924 1925 <div class="column is-2"> 1926 <h5 style="color: #e7e5e4; margin-bottom: 0.5rem;">Legacy</h5> 1927 <ul style="list-style: none;"> 1928 <li><a href="/integrations" style="color: #78716c;">Integrations</a></li> 1929 <li><a href="/selfhosting" style="color: #78716c;">Self Hosting</a></li> 1930 <li><a href="/diagram/scruffy/class/draw" style="color: #78716c;">Draw (v1)</a></li> 1931 <li><a href="/diagram/scruffy/class/samples" style="color: #78716c;">Samples (v1)</a></li> 1932 <li><a href="/users/sign_in" style="color: #78716c;">v1 Login</a></li> 1933 <li><a style="color: #78716c;" href="/pricing">v1 Pricing</a></li> 1934 </ul> 1935 </div> 1936 </div> 1937 1938 <hr style="background: #333; height: 1px; border: none; margin: 2rem 0;"> 1939 <div style="display: flex; justify-content: space-between; align-items: center;"> 1940 <p style="font-size: 0.85rem;">© 2026 yUML by Pocketworks Mobile Ltd.</p> 1941 <div> 1942 <a href="//twitter.com/yuml_app" style="color: #78716c; margin-left: 1rem;" target="_blank" rel="noopener noreferrer"><i class="fab fa-twitter"></i></a> 1943 <a href="mailto:[email protected]" style="color: #78716c; margin-left: 1rem;" target="_blank" rel="noopener noreferrer"><i class="fas fa-at"></i></a> 1944 </div> 1945 </div> 1946 </div> 1947</footer> 1948 1949 <!-- Google Analytics-->
1950<script type="text/javascript"> 1951var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); 1952document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E")); 1953</script>
vendor: 1 bytes, line 1953
1953
1954<script type="text/javascript"> 1955try { 1956var pageTracker = _gat._getTracker("UA-4340115-4"); 1957pageTracker._trackPageview(); 1958} catch(err) {}</script>
1958 1959 1960 </body> 1961</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.