{"id":15080,"date":"2026-10-08T10:07:49","date_gmt":"2026-10-08T07:07:49","guid":{"rendered":"https:\/\/mini-talks.org\/?page_id=15080"},"modified":"2026-10-10T11:55:35","modified_gmt":"2026-10-10T08:55:35","slug":"fig-talks","status":"publish","type":"page","link":"https:\/\/mini-talks.org\/da\/mini-kits\/fig-talks\/","title":{"rendered":"Fig-Talks"},"content":{"rendered":"<div data-elementor-type=\"wp-page\" data-elementor-id=\"15080\" class=\"elementor elementor-15080\">\n\t\t\t\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-0d9c969 elementor-section-full_width elementor-section-height-default elementor-section-height-default\" data-id=\"0d9c969\" data-element_type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-4ec927e\" data-id=\"4ec927e\" data-element_type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-element elementor-element-a26ca74 elementor-widget elementor-widget-html\" data-id=\"a26ca74\" data-element_type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t<!-- Fig-Talks \u00b7 Elementor HTML widget (Elementor Full Width sayfa). Header\/footer sitenin kendisinden gelir.\n     AYAR: 3D klas\u00f6r adresi ve Media Library klas\u00f6r\u00fc a\u015fa\u011f\u0131daki iki sat\u0131rda. -->\n<script>\nwindow.FT_BASE='https:\/\/mini-talks.org\/fig-talks-3d\/';\nwindow.FT_MEDIA_BASE=new URL('\/wp-content\/uploads\/2026\/10\/',location.href).href;\n\/* Media Library g\u00f6rseli .png yoksa s\u0131rayla .jpg \/ .jpeg \/ .webp dener *\/\n(function(){var EXTS=['.png','.jpg','.jpeg','.webp'];\ndocument.addEventListener('error',function(e){var img=e.target;if(!img||img.tagName!=='IMG'||!img.closest||!img.closest('#ftw'))return;\nvar src=img.src;if(src.indexOf(window.FT_MEDIA_BASE)!==0)return;var m=src.match(\/\\.(png|jpe?g|webp)(\\?.*)?$\/i);if(!m)return;\nvar base=src.slice(0,m.index),cur='.'+m[1].toLowerCase(),tried=(img.getAttribute('data-ft-tried')||'').split(',').filter(Boolean);\nif(tried.indexOf(cur)<0)tried.push(cur);var next=null;for(var i=0;i<EXTS.length;i++)if(tried.indexOf(EXTS[i])<0){next=EXTS[i];break;}\nimg.setAttribute('data-ft-tried',tried.join(','));if(!next)return;var a=img.closest('a'),nu=base+next;if(a&&a.href===src)a.href=nu;img.src=nu;},true);})();\n<\/script>\n<link rel=\"stylesheet\" href=\"https:\/\/fonts.googleapis.com\/css2?family=Montserrat:wght@400;600;700;800;900&display=swap\">\n<style>\n\/* tema\/Elementor stillerinden yal\u0131t\u0131m: \u00f6nce taray\u0131c\u0131 varsay\u0131lan\u0131na d\u00f6n, sonra sayfa stili (#ftw ile) *\/\n#ftw{all:initial;display:block;width:100%}\n#ftw :where(*:not(svg,svg *,img,canvas,video)),#ftw :where(*:not(svg,svg *))::before,#ftw :where(*:not(svg,svg *))::after{all:revert}\n#ftw :where(img,canvas,video){border:revert;border-radius:revert;box-shadow:revert;margin:revert;padding:revert;max-width:revert;min-width:revert;opacity:revert;filter:revert;transform:revert;vertical-align:revert;float:revert;object-fit:revert}\n#ftw :where([hidden]:not([hidden=until-found i])){display:none}\n#ftw :where(input,textarea,select)::-webkit-slider-thumb{all:revert}\n#ftw :where(input,textarea,select)::-webkit-slider-runnable-track{all:revert}\n#ftw :where(input,textarea,select)::-moz-range-thumb{all:revert}\n#ftw :where(input,textarea,select)::-moz-range-track{all:revert}\n#ftw :where(input,textarea,select)::-moz-range-progress{all:revert}\n#ftw :where(input,textarea,select)::placeholder{all:revert}\n#ftw :where(input,textarea,select)::-webkit-inner-spin-button{all:revert}\n#ftw :where(input,textarea,select)::-webkit-outer-spin-button{all:revert}\n#ftw :where(input,textarea,select)::file-selector-button{all:revert}\n#ftw :where(input,textarea,select)::-webkit-search-cancel-button{all:revert}\n#ftw .ft-page{--red:#E52828;--yellow:#FFCC00;--blue:#0055BF;--green:#237841;--ink:#1D1D1B;--white:#fff;width:100%;color:var(--ink);font-family:'Montserrat',sans-serif;line-height:1.75;background:#fff}\n#ftw .ft-page,#ftw .ft-page *{box-sizing:border-box}\n#ftw .ft-page img{display:block;max-width:100%;height:auto}\n#ftw .ft-page a{font-family:inherit}\n#ftw .ft-page .ft-wrap{width:82%;margin:0 auto}\n#ftw .ft-page .ft-section{padding:0 0 66px}\n#ftw .ft-page h2{margin:0 0 12px;font-family:inherit;font-size:clamp(26px,2.6vw,40px);font-weight:900;line-height:1.2;color:var(--section-color,var(--blue))}\n#ftw .ft-page h3{margin:0 0 12px;font-family:inherit;font-size:clamp(19px,1.5vw,23px);font-weight:900;line-height:1.3;color:var(--ink)}\n#ftw .ft-page p{margin:0 0 18px;font-size:clamp(15px,1.25vw,18px);font-weight:600;line-height:1.8}\n#ftw .ft-page p:last-child{margin-bottom:0}\n#ftw .ft-page .ft-bars{display:flex;width:260px;max-width:70%;height:8px;margin:0 0 24px;overflow:hidden}\n#ftw .ft-page .ft-bars span{flex:1}\n#ftw .ft-page .ft-bars span:nth-child(1){background:var(--red)}\n#ftw .ft-page .ft-bars span:nth-child(2){background:var(--yellow)}\n#ftw .ft-page .ft-bars span:nth-child(3){background:var(--blue)}\n#ftw .ft-page .ft-bars span:nth-child(4){background:var(--green)}\n#ftw .ft-page .ft-hero{padding:40px 0 24px}\n#ftw .ft-page .ft-hero-flex{display:grid;grid-template-columns:minmax(0,1fr) 360px;align-items:center;gap:40px}\n#ftw .ft-page .ft-hero-copy{flex:0 0 58%;min-width:0}\n#ftw .ft-page .ft-title{font-family: 'Montserrat', Arial, sans-serif;\n  font-weight: 900;\n  font-size: clamp(38px, 3.8vw, 56px);\n  letter-spacing: -.035em;\n  line-height: 1.16;\n  color: #FFFFFF;\n  -webkit-text-stroke: 3px #E52828;\n  paint-order: stroke fill;\n  text-shadow: 3px 0 #E52828, -3px 0 #E52828,\n    0 3px #E52828, 0 -3px #E52828,\n    3px 3px #E52828, -3px -3px #E52828,\n    3px -3px #E52828, -3px 3px #E52828;\n  margin: 0 0 20px;\nfont-style:normal;}\n#ftw .ft-page .ft-hero .ft-bars{width:80%;max-width:none;height:10px}\n#ftw .ft-page .ft-hero-copy p{font-weight:700;line-height:1.65}\n#ftw .ft-page .ft-hero-visual{width:360px;max-width:100%;min-width:0;height:220px;padding:0;background:var(--yellow);border-radius:20px;display:flex;align-items:center;justify-content:center;overflow:hidden}\n#ftw .ft-page .ft-hero-visual img{width:min(100%,152.450704px);height:auto;max-width:100%;max-height:none;flex:none;display:block;margin:0;padding:0;border:0;border-radius:0;object-fit:contain}\n#ftw .ft-page .ft-intro{padding:48px 0 58px;--section-color:var(--red)}\n#ftw .ft-page .ft-quote{display:flex;gap:2px;margin:0 0 14px}\n#ftw .ft-page .ft-quote img{width:24px;height:auto}\n#ftw .ft-page .ft-quote-end{justify-content:flex-end;margin:16px 0 0}\n#ftw .ft-page .ft-quote-end img{transform:rotate(180deg)}\n#ftw .ft-page .ft-lead{font-size:clamp(20px,1.7vw,26px);font-weight:900;line-height:1.58;color:var(--green)}\n#ftw .ft-page .ft-split{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);gap:42px;align-items:center}\n#ftw .ft-page figure{margin:0;min-width:0}\n#ftw .ft-page .ft-figure-panel{padding:28px;background:#F5F7F8;border-radius:16px;border-bottom:8px solid var(--blue)}\n#ftw .ft-page .ft-figure-panel img{width:100%;height:420px;object-fit:contain}\n#ftw .ft-page figcaption{margin-top:14px;font-size:12px;font-weight:600;line-height:1.6;color:#555;text-align:center}\n#ftw .ft-page .ft-eyebrow{margin:0 0 10px;font-size:13px;font-weight:900;letter-spacing:.07em;text-transform:uppercase;color:var(--green)}\n#ftw .ft-page .ft-note{margin-top:24px;padding:22px 25px;background:#F4F8F5;border-left:6px solid var(--green);border-radius:10px}\n#ftw .ft-page .ft-note p{color:var(--green);font-weight:800}\n#ftw .ft-page .ft-section-head{margin-bottom:30px}\n#ftw .ft-page .ft-section-head>p{max-width:960px}\n#ftw .ft-page .ft-steps{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:26px;list-style:none;margin:0;padding:0}\n#ftw .ft-page .ft-step{--card:var(--blue);position:relative;display:flex;flex-direction:column;min-width:0;margin-top:36px;padding:22px 8px 8px;background:var(--card);border-radius:14px}\n#ftw .ft-page .ft-step:nth-child(2){--card:var(--yellow)}\n#ftw .ft-page .ft-step:nth-child(3){--card:var(--green)}\n#ftw .ft-page .ft-step::before{content:\"\";position:absolute;top:-35px;left:0;width:100%;height:36px;background:var(--card);-webkit-mask:url('https:\/\/mini-talks.org\/wp-content\/uploads\/2026\/02\/yeni-sari-4.png') center bottom\/100% auto no-repeat;mask:url('https:\/\/mini-talks.org\/wp-content\/uploads\/2026\/02\/yeni-sari-4.png') center bottom\/100% auto no-repeat}\n#ftw .ft-page .ft-step-inner{flex:1;padding:24px 22px;background:#fff;border-radius:10px}\n#ftw .ft-page .ft-number{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;margin-bottom:18px;background:var(--card);color:#fff;border-radius:10px;font-size:20px;font-weight:900}\n#ftw .ft-page .ft-step:nth-child(2) .ft-number{color:var(--ink)}\n#ftw .ft-page .ft-step p{font-size:15px}\n#ftw .ft-page .ft-module{padding:30px;border:4px solid var(--red);border-bottom:10px solid var(--blue);border-radius:16px;gap:36px}\n#ftw .ft-page .ft-module img{width:100%;max-height:380px;object-fit:contain}\n#ftw .ft-page .ft-feature-list{list-style:none;margin:20px 0 0;padding:0}\n#ftw .ft-page .ft-feature-list li{position:relative;margin-bottom:14px;padding-left:24px;font-size:16px;font-weight:600;line-height:1.7}\n#ftw .ft-page .ft-feature-list li::before{content:\"\";position:absolute;top:9px;left:0;width:10px;height:10px;border-radius:2px;background:var(--blue)}\n#ftw .ft-page .ft-link{color:var(--blue);font-weight:800;text-decoration:underline;text-decoration-thickness:2px;text-underline-offset:4px}\n#ftw .ft-page .ft-link:hover{color:var(--red)}\n#ftw .ft-page .ft-outline-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:24px}\n#ftw .ft-page .ft-outline{padding:25px;border:4px solid var(--blue);border-bottom-width:10px;border-radius:14px}\n#ftw .ft-page .ft-outline:nth-child(2){border-color:var(--green)}\n#ftw .ft-page .ft-outline:nth-child(3){border-color:var(--red)}\n#ftw .ft-page .ft-outline p{font-size:15px}\n#ftw .ft-page .ft-boundary{padding:24px 28px;border-left:6px solid var(--blue);border-radius:10px;background:#F3F7FC}\n#ftw .ft-page .ft-boundary h2{font-size:clamp(22px,2vw,30px)}\n#ftw .ft-page .ft-closing{position:relative;margin-top:24px;background:var(--yellow)}\n#ftw .ft-page .ft-closing::before{content:\"\";position:absolute;top:-24px;left:0;width:100%;height:24px;background:url('https:\/\/mini-talks.org\/wp-content\/uploads\/2026\/02\/yeni-3-sari.png') repeat-x center bottom\/auto 24px}\n#ftw .ft-page .ft-closing-inner{display:flex;align-items:center;justify-content:space-between;gap:44px;padding:40px 0 44px}\n#ftw .ft-page .ft-closing-copy{flex:1;min-width:0}\n#ftw .ft-page .ft-closing h2{color:var(--ink);font-size:clamp(27px,2.6vw,40px)}\n#ftw .ft-page .ft-closing h2 span{color:var(--blue)}\n#ftw .ft-page .ft-closing-copy>p:last-child{max-width:700px}\n#ftw .ft-page .ft-actions{flex-shrink:0;padding:0 6px 6px 0}\n#ftw .ft-page .ft-button{display:inline-flex;align-items:center;justify-content:center;gap:10px;min-height:56px;padding:16px 24px;background:var(--ink)!important;border:3px solid var(--ink)!important;border-radius:999px;box-shadow:5px 5px 0 var(--red);color:#fff!important;font-size:14px;font-weight:900;line-height:1.4;text-decoration:none!important;text-align:center;transition:transform .16s,box-shadow .16s,background-color .16s}\n#ftw .ft-page .ft-button:hover,#ftw .ft-page .ft-button:focus-visible{background:var(--blue)!important;border-color:#fff!important;box-shadow:3px 3px 0 var(--red);transform:translate(2px,2px)}\n#ftw .ft-page a:focus-visible{outline:3px solid var(--blue);outline-offset:5px}\n#ftw .ft-page .ft-button:focus-visible{outline-color:var(--ink)}\n@media(max-width:1100px){#ftw .ft-page .ft-steps,#ftw .ft-page .ft-outline-grid{gap:18px}\n#ftw .ft-page .ft-step-inner,#ftw .ft-page .ft-outline{padding:20px 16px}}\n@media(max-width:992px){#ftw .ft-page .ft-split{grid-template-columns:1fr;gap:28px}\n#ftw .ft-page .ft-figure-panel img{height:360px}\n#ftw .ft-page .ft-steps,#ftw .ft-page .ft-outline-grid{grid-template-columns:1fr}\n#ftw .ft-page .ft-closing-inner{flex-direction:column;align-items:flex-start;gap:24px}}\n@media(max-width:768px){#ftw .ft-page .ft-wrap{width:92%}\n#ftw .ft-page .ft-hero{padding-top:30px}\n#ftw .ft-page .ft-hero-flex{grid-template-columns:minmax(0,1fr);gap:28px}\n#ftw .ft-page .ft-hero-copy{flex:none;width:100%}\n#ftw .ft-page .ft-hero .ft-bars{width:100%}\n#ftw .ft-page .ft-hero-visual{width:100%;max-width:360px;height:160px;margin:0 auto}\n#ftw .ft-page .ft-hero-visual img{width:min(100%,110.873239px)}\n#ftw .ft-page .ft-intro{padding:38px 0 46px}\n#ftw .ft-page .ft-section{padding-bottom:48px}\n#ftw .ft-page .ft-bars{height:7px}\n#ftw .ft-page .ft-module{padding:20px}\n#ftw .ft-page .ft-figure-panel{padding:20px}\n#ftw .ft-page .ft-figure-panel img{height:320px}\n#ftw .ft-page .ft-note,#ftw .ft-page .ft-boundary{padding:21px 19px}\n#ftw .ft-page .ft-closing-inner{padding:28px 0 30px}\n#ftw .ft-page .ft-actions,#ftw .ft-page .ft-button{width:100%}\n#ftw .ft-page .ft-step-inner{padding:22px}\n#ftw .ft-page h3{overflow-wrap:anywhere}}\n@media(prefers-reduced-motion:reduce){#ftw .ft-page .ft-button{transition:none;transform:none}}\nhtml{scroll-behavior:smooth;scroll-padding-top:90px}\n#ftw .ft-page{font-family:Montserrat,Arial,sans-serif}\n#ftw .ft-page button,#ftw .ft-page select{font:inherit}\n#ftw .ft-page button{cursor:pointer;border:2px solid #d8dce0;background:white;padding:10px 15px;border-radius:10px;font-size:13px;font-weight:800;color:var(--ink)}\n#ftw .ft-page button:hover{border-color:var(--blue)}\n#ftw .ft-page button[aria-pressed=true]{background:var(--blue);color:#fff;border-color:var(--blue)}\n#ftw .ft-page button:disabled{opacity:.4;cursor:default}\n#ftw .ft-page :focus-visible{outline:3px solid var(--blue);outline-offset:3px}\n#ftw .site-head{display:flex;align-items:center;justify-content:space-between;padding:22px 0;border-bottom:1px solid #eee}\n#ftw .site-head img{width:140px}\n#ftw .site-head a{color:var(--blue);font-size:12px;font-weight:800;text-decoration:none}\n#ftw .hero{display:grid;grid-template-columns:.85fr 1.15fr;gap:50px;align-items:center;padding:48px 0 60px}\n#ftw .hero-copy h2{font-size:clamp(34px,3.5vw,54px);color:var(--ink);letter-spacing:-.04em}\n#ftw .hero-copy .gentle{font-size:13px;color:var(--green);margin-top:25px;max-width:340px}\n#ftw .hero-product{background:#fff9da;border-radius:24px;padding:16px 22px;text-align:center}\n#ftw .model-stage{position:relative;overflow:hidden;border-radius:14px;background:#fafbfc;min-width:0}\n#ftw .model-stage canvas{width:100%;height:100%;display:block;touch-action:none}\n#ftw .hero-stage{height:475px}\n#ftw .hero-product .view-bar{margin:10px 0}\n#ftw .view-bar{display:flex;justify-content:center;gap:6px;flex-wrap:wrap;margin:12px 0}\n#ftw .view-bar button{padding:7px 12px;font-size:12px}\n#ftw .module-actions{display:flex;gap:8px;justify-content:center;margin:16px 0 8px}\n#ftw .module-actions button{flex:1;background:var(--yellow);border-color:var(--yellow)}\n#ftw .ft-page #module-status{font-size:13px;margin:10px 0}\n#ftw .rear-choice{display:flex;justify-content:center;align-items:center;gap:12px;font-size:12px;font-weight:800}\n#ftw .rear-choice select{padding:8px;border:1px solid #d2cba7;border-radius:8px;background:white}\n#ftw .ft-page .model-hint,#ftw .ft-page .small-note{font-size:12px;color:#58626b;line-height:1.65;margin:12px 0}\n#ftw .assembly-unfocus{position:absolute;z-index:1;top:8px;left:8px}\n#ftw .assembly-unfocus[hidden]{display:none}\n#ftw .chapter-nav{position:sticky;top:0;z-index:5;background:#fff;border-block:1px solid #e8e8e8}\n#ftw .chapter-nav>div{display:flex;justify-content:space-between;gap:10px;overflow:auto}\n#ftw .chapter-nav a{white-space:nowrap;padding:20px 0;color:var(--ink);text-decoration:none;font-weight:800;font-size:13px}\n#ftw .chapter-nav a:hover{color:var(--red)}\n#ftw .chapter{padding-top:72px}\n#ftw .section-intro{max-width:760px;margin-bottom:30px}\n#ftw .section-intro p{font-size:16px}\n#ftw .section-intro h2{color:var(--red)}\n#ftw #connections h2,#ftw #software h2{color:var(--green)}\n#ftw .parts-layout{display:grid;grid-template-columns:235px minmax(0,1fr);gap:28px;align-items:start}\n#ftw .parts-layout aside{max-height:760px;overflow:auto;padding-right:8px}\n#ftw .part-group h3{font-size:12px;text-transform:uppercase;letter-spacing:.07em;margin:20px 0 10px;color:var(--green)}\n#ftw .part-group:first-child h3{margin-top:0}\n#ftw .part-group button{display:block;width:100%;text-align:left;border-width:1px;margin-bottom:5px;padding:10px 12px}\n#ftw .part-detail{border:2px solid #e4e8eb;border-radius:18px;padding:24px;min-width:0}\n#ftw .part-heading{display:flex;justify-content:space-between;align-items:center}\n#ftw .part-heading h3{font-size:26px}\n#ftw .part-heading>span{font-size:12px;color:#60676c}\n#ftw #part-description{font-size:14px;min-height:2.5em}\n#ftw .part-stage{height:365px}\n#ftw .file-links{display:flex;gap:8px;flex-wrap:wrap;margin:20px 0 0}\n#ftw .file-links a{font-size:12px;font-weight:800;border:2px solid var(--blue);border-radius:8px;padding:10px 14px;color:var(--blue);text-decoration:none}\n#ftw .file-links a:hover{background:var(--blue);color:white}\n#ftw .ft-page details{border-top:1px solid #ddd;padding-top:14px;margin-top:20px}\n#ftw .ft-page summary{cursor:pointer;font-size:13px;font-weight:800}\n#ftw .eight-views{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-top:16px}\n#ftw .eight-views a{border:1px solid #e6e6e6;border-radius:8px;overflow:hidden;font-size:10px;text-decoration:none;text-align:center;color:var(--ink);font-weight:700}\n#ftw .eight-views img{width:100%}\n#ftw .connection-layout{display:grid;grid-template-columns:minmax(0,1.8fr) minmax(240px,1fr);gap:30px;align-items:center}\n#ftw .connection-map{position:relative;aspect-ratio:800\/590;background:#f7f9fb;border-radius:20px}\n#ftw .connection-map svg{position:absolute;inset:0;width:100%;height:100%;fill:none;stroke:#b5c5d7;stroke-width:4}\n#ftw .connection-map path.active{stroke:var(--green);stroke-width:6}\n#ftw .map-core,#ftw .map-module{position:absolute!important;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px}\n#ftw .ft-page .map-module{width:28%;height:35%;padding:7px;background:white;border-radius:15px;border-width:2px}\n#ftw .map-module img{height:68%;width:100%;object-fit:contain}\n#ftw .map-module strong,#ftw .map-core strong{font-size:12px}\n#ftw .map-module small{font-size:10px;font-weight:600}\n#ftw .map-mic{left:3%;top:5%}\n#ftw .map-speaker{right:3%;top:5%}\n#ftw .map-button{left:3%;bottom:5%}\n#ftw .map-battery{right:3%;bottom:5%}\n#ftw .map-core{width:23%;height:33%;left:38.5%;top:33.5%;background:white;border:2px solid var(--red);border-radius:14px;padding:4px}\n#ftw .map-core img{height:80%;object-fit:contain}\n#ftw .connection-detail{border-left:5px solid var(--green);padding-left:24px}\n#ftw .connection-detail p{font-size:14px}\n#ftw .connection-detail table{border-collapse:collapse;width:100%;font-size:12px}\n#ftw .connection-detail th{text-align:left;background:#f0f5f2}\n#ftw .connection-detail th,#ftw .connection-detail td{padding:8px;border-bottom:1px solid #e3e7e4}\n#ftw .build-tabs{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:22px}\n#ftw .ft-page .build-tabs button{padding:16px;border-color:var(--blue)}\n#ftw .build-layout{display:grid;grid-template-columns:minmax(0,1.7fr) minmax(250px,1fr);gap:32px;border:3px solid var(--blue);border-bottom-width:9px;border-radius:20px;padding:24px}\n#ftw .build-stage{height:440px}\n#ftw .build-layout aside{align-self:center}\n#ftw .build-layout p,#ftw .build-layout li{font-size:14px}\n#ftw .build-layout ol{padding-left:20px}\n#ftw .build-layout li{margin-bottom:10px}\n#ftw .separation{display:block;margin:20px 0;font-size:13px;font-weight:800}\n#ftw .separation input{display:block;width:100%;accent-color:var(--blue);margin-top:14px}\n#ftw .software-panel{background:#f3f8f4;border-radius:20px;padding:40px;display:grid;grid-template-columns:1fr 1fr;gap:48px;border-bottom:8px solid var(--green)}\n#ftw .software-panel p,#ftw .software-panel li{font-size:15px}\n#ftw .software-panel li{margin-bottom:12px}\n#ftw .pending-badge{display:inline-block;padding:7px 12px;border:1px solid var(--green);border-radius:6px;color:var(--green);font-size:11px;font-weight:800;margin-bottom:20px}\n#ftw .try-device-content{display:grid;grid-template-columns:minmax(0,1.7fr) minmax(250px,1fr);gap:35px;border:3px solid var(--red);border-radius:20px;padding:24px}\n#ftw .try-device-scenario{align-self:center}\n#ftw .try-device-scenario li{font-size:14px;margin:0 0 14px}\n#ftw .try-device-scenario p{font-size:12px;color:#58626b}\n#ftw .ft-page .ft-demo-controls [data-demo=power]{background:var(--blue);color:white}\n#ftw .ft-page .ft-demo-controls [data-demo=record]{background:var(--green);color:white}\n#ftw .ft-page .ft-demo-controls [data-demo=play]{background:var(--yellow)}\n#ftw .page-footer{display:flex;justify-content:space-between;padding:26px 0;font-size:12px;font-weight:700}\n#ftw .page-footer a{color:var(--blue)}\n#ftw .ft-page .ft-closing{margin-top:30px}\n#ftw .ft-page .ft-closing::before{background:none}\n#ftw .part-error{padding:40px;font-size:14px;color:#7e2222}\n@media(min-width:1600px){#ftw .ft-page .ft-wrap{max-width:1320px}}\n@media(max-width:1000px){#ftw .hero{gap:25px}\n#ftw .hero-stage{height:390px}\n#ftw .parts-layout{grid-template-columns:190px 1fr}\n#ftw .build-layout,#ftw .connection-layout{gap:20px}\n#ftw .ft-page .ft-wrap{width:90%}}\n@media(max-width:760px){html{scroll-padding-top:70px}\n#ftw .hero{grid-template-columns:1fr;padding-top:30px}\n#ftw .hero-copy{max-width:550px}\n#ftw .hero-stage{height:440px}\n#ftw .chapter-nav a{font-size:11px;padding:16px 0}\n#ftw .parts-layout,#ftw .connection-layout,#ftw .build-layout,#ftw .software-panel,#ftw .try-device-content{grid-template-columns:1fr}\n#ftw .parts-layout aside{max-height:230px;border:1px solid #ddd;border-radius:12px;padding:12px}\n#ftw .part-group button{display:inline-block;width:auto;margin-right:5px;font-size:11px}\n#ftw .part-group h3{margin:10px 0}\n#ftw .part-stage{height:300px}\n#ftw .part-detail{padding:16px}\n#ftw .build-tabs{gap:5px}\n#ftw .ft-page .build-tabs button{font-size:11px;padding:12px 4px}\n#ftw .build-layout,#ftw .software-panel,#ftw .try-device-content{padding:18px}\n#ftw .build-stage{height:350px}\n#ftw .connection-detail{margin-top:10px}\n#ftw .chapter{padding-top:48px}\n#ftw .ft-page .map-module strong{font-size:10px}\n#ftw .module-actions button{font-size:11px;padding:10px 5px}\n#ftw .site-head img{width:110px}\n#ftw .ft-page .ft-demo-model{height:360px}\n#ftw .eight-views{grid-template-columns:repeat(2,1fr)}}\n@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}}\n#ftw .assembly-pose-bar{display:grid;gap:12px;padding:15px 0;font-size:12px}\n#ftw .assembly-pose-bar label{display:flex;justify-content:center;align-items:center;gap:10px}\n#ftw .assembly-pose-bar select{max-width:200px;border:1px solid #ddd;padding:6px;border-radius:6px}\n#ftw .assembly-pose-bar input[type=range]{accent-color:var(--blue)}\n#ftw .assembly-pose-gizmo{position:absolute;transform:translate(-50%,-50%);display:flex;align-items:center;gap:6px;padding:6px;background:white;border-radius:8px;font-size:11px;box-shadow:0 2px 12px #0002}\n#ftw .assembly-pose-gizmo[hidden]{display:none}\n#ftw .firmware-source{max-height:360px;overflow:auto;white-space:pre;font:12px\/1.65 ui-monospace,monospace;text-align:left;background:#fff;border:1px solid #d4dfd7;border-radius:8px;padding:16px}\n#ftw .software-panel>div{min-width:0}\n#ftw .circuit-render{margin:0 0 36px;padding:24px;border:2px solid #d8dde0;border-radius:20px;background:#f8fafb}\n#ftw .circuit-render h3{margin-top:0}\n#ftw .circuit-render img{display:block;width:100%;height:auto;margin:20px 0;border-radius:12px}\n#ftw .circuit-render>p{font-size:14px}\n#ftw .circuit-stage{height:580px}\n@media(max-width:760px){#ftw .circuit-stage{height:420px}}\n#ftw .circuit-label{position:absolute;pointer-events:none;transform:translate(-50%,-50%);font-size:12px;font-weight:800;color:#24313d;background:#ffffffd9;border-radius:4px;padding:3px 6px;white-space:nowrap}\n#ftw .circuit-stage{height:620px}\n@media(max-width:760px){#ftw .circuit-stage{height:510px}\n#ftw .circuit-label{font-size:10px}}\n#ftw .connections-workspace{display:grid;grid-template-columns:minmax(0,1.7fr) minmax(260px,1fr);gap:20px;align-items:start}\n#ftw .connections-workspace .circuit-render{margin:0;padding:16px;min-width:0}\n#ftw .connections-workspace .circuit-render h3{font-size:19px;margin:0 0 12px}\n#ftw .connections-workspace .circuit-stage{height:440px}\n#ftw .connections-workspace .connection-layout{display:block;min-width:0}\n#ftw .connections-workspace .connection-map{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;aspect-ratio:auto;min-height:0;height:auto;padding:0;background:none;position:static;border-radius:0}\n#ftw .connections-workspace .map-module{position:static!important;inset:auto!important;transform:none!important;width:auto!important;height:auto;min-height:62px;min-width:0;display:grid;grid-template-columns:48px minmax(0,1fr);align-items:center;gap:7px;padding:8px!important;border-radius:10px}\n#ftw .connections-workspace .map-module img{width:48px;height:42px;object-fit:contain;margin:0}\n#ftw .connections-workspace .map-module strong{font-size:11px;line-height:1.25;text-align:left}\n#ftw .connections-workspace .map-module small{display:none}\n#ftw .connections-workspace .connection-detail{margin-top:18px;padding-left:14px;border-left:3px solid var(--green)}\n#ftw .connections-workspace .connection-detail>span{font-size:10px}\n#ftw .connections-workspace .connection-detail h3{font-size:18px;margin:6px 0 8px;line-height:1.3}\n#ftw .connections-workspace .connection-detail p{font-size:12px;margin:8px 0;line-height:1.5}\n#ftw .connections-workspace .connection-detail th,#ftw .connections-workspace .connection-detail td{font-size:12px;padding:6px 8px}\n#ftw .connections-workspace .view-bar{gap:4px;margin:8px 0}\n#ftw .connections-workspace .view-bar button{font-size:11px;padding:6px 8px}\n#ftw .connections-workspace .rear-choice{font-size:11px;justify-content:flex-end;gap:6px}\n#ftw .connections-workspace .rear-choice select{font-size:11px;padding:5px}\n#ftw .connections-workspace .small-note{margin:8px 0 0;font-size:11px}\n@media(max-width:900px){#ftw .connections-workspace{grid-template-columns:1fr}\n#ftw .connections-workspace .circuit-stage{height:390px}\n#ftw .connections-workspace .connection-layout{display:grid;grid-template-columns:minmax(130px,.8fr) minmax(0,1.2fr);gap:14px}\n#ftw .connections-workspace .connection-map{grid-template-columns:1fr;align-content:start}\n#ftw .connections-workspace .connection-detail{margin-top:0}}\n@media(max-width:440px){#ftw .connections-workspace .connection-layout{grid-template-columns:1fr}\n#ftw .connections-workspace .connection-map{grid-template-columns:repeat(2,minmax(0,1fr))}\n#ftw .connections-workspace .circuit-stage{height:340px}}\n#ftw .circuit-stage[hidden]{display:none}\n#ftw .connections-workspace .circuit-layout-switch{justify-content:flex-start;margin:0 0 12px}\n#ftw .circuit-layout-switch button{flex:1}\n#ftw .part-view-card{display:flex;gap:3px;min-width:0}\n#ftw .part-view-card>a{flex:1;min-width:0;display:block}\n#ftw .ft-page{--red:#E52828;--yellow:#FFCC00;--blue:#0055BF;--green:#237841;--ink:#1D1D1B;--white:#fff;width:100%;color:var(--ink);font-family:'Montserrat',sans-serif;line-height:1.75;background:#fff}\n#ftw .ft-page,#ftw .ft-page *{box-sizing:border-box}\n#ftw .ft-page img{display:block;max-width:100%;height:auto}\n#ftw .ft-page a{font-family:inherit}\n#ftw .ft-page .ft-wrap{width:82%;margin:0 auto}\n#ftw .ft-page .ft-section{padding:0 0 66px}\n#ftw .ft-page h2{margin:0 0 12px;font-family:inherit;font-size:clamp(26px,2.6vw,40px);font-weight:900;line-height:1.2;color:var(--section-color,var(--blue))}\n#ftw .ft-page h3{margin:0 0 12px;font-family:inherit;font-size:clamp(19px,1.5vw,23px);font-weight:900;line-height:1.3;color:var(--ink)}\n#ftw .ft-page p{margin:0 0 18px;font-size:clamp(15px,1.25vw,18px);font-weight:600;line-height:1.8}\n#ftw .ft-page p:last-child{margin-bottom:0}\n#ftw .ft-page .ft-bars{display:flex;width:260px;max-width:70%;height:8px;margin:0 0 24px;overflow:hidden}\n#ftw .ft-page .ft-bars span{flex:1}\n#ftw .ft-page .ft-bars span:nth-child(1){background:var(--red)}\n#ftw .ft-page .ft-bars span:nth-child(2){background:var(--yellow)}\n#ftw .ft-page .ft-bars span:nth-child(3){background:var(--blue)}\n#ftw .ft-page .ft-bars span:nth-child(4){background:var(--green)}\n#ftw .ft-page .ft-hero{padding:40px 0 24px}\n#ftw .ft-page .ft-hero-flex{display:grid;grid-template-columns:minmax(0,1fr) 360px;align-items:center;gap:40px}\n#ftw .ft-page .ft-hero-copy{flex:0 0 58%;min-width:0}\n#ftw .ft-page .ft-title{font-family: 'Montserrat', Arial, sans-serif;\n  font-weight: 900;\n  font-size: clamp(38px, 3.8vw, 56px);\n  letter-spacing: -.035em;\n  line-height: 1.16;\n  color: #FFFFFF;\n  -webkit-text-stroke: 3px #E52828;\n  paint-order: stroke fill;\n  text-shadow: 3px 0 #E52828, -3px 0 #E52828,\n    0 3px #E52828, 0 -3px #E52828,\n    3px 3px #E52828, -3px -3px #E52828,\n    3px -3px #E52828, -3px 3px #E52828;\n  margin: 0 0 20px;\nfont-style:normal;}\n#ftw .ft-page .ft-hero .ft-bars{width:80%;max-width:none;height:10px}\n#ftw .ft-page .ft-hero-copy p{font-weight:700;line-height:1.65}\n#ftw .ft-page .ft-hero-visual{width:360px;max-width:100%;min-width:0;height:220px;padding:0;background:var(--yellow);border-radius:20px;display:flex;align-items:center;justify-content:center;overflow:hidden}\n#ftw .ft-page .ft-hero-visual img{width:min(100%,152.450704px);height:auto;max-width:100%;max-height:none;flex:none;display:block;margin:0;padding:0;border:0;border-radius:0;object-fit:contain}\n#ftw .ft-page .ft-intro{padding:48px 0 58px;--section-color:var(--red)}\n#ftw .ft-page .ft-quote{display:flex;gap:2px;margin:0 0 14px}\n#ftw .ft-page .ft-quote img{width:24px;height:auto}\n#ftw .ft-page .ft-quote-end{justify-content:flex-end;margin:16px 0 0}\n#ftw .ft-page .ft-quote-end img{transform:rotate(180deg)}\n#ftw .ft-page .ft-lead{font-size:clamp(20px,1.7vw,26px);font-weight:900;line-height:1.58;color:var(--green)}\n#ftw .ft-page .ft-split{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);gap:42px;align-items:center}\n#ftw .ft-page figure{margin:0;min-width:0}\n#ftw .ft-page .ft-figure-panel{padding:28px;background:#F5F7F8;border-radius:16px;border-bottom:8px solid var(--blue)}\n#ftw .ft-page .ft-figure-panel img{width:100%;height:420px;object-fit:contain}\n#ftw .ft-page figcaption{margin-top:14px;font-size:12px;font-weight:600;line-height:1.6;color:#555;text-align:center}\n#ftw .ft-page .ft-eyebrow{margin:0 0 10px;font-size:13px;font-weight:900;letter-spacing:.07em;text-transform:uppercase;color:var(--green)}\n#ftw .ft-page .ft-note{margin-top:24px;padding:22px 25px;background:#F4F8F5;border-left:6px solid var(--green);border-radius:10px}\n#ftw .ft-page .ft-note p{color:var(--green);font-weight:800}\n#ftw .ft-page .ft-section-head{margin-bottom:30px}\n#ftw .ft-page .ft-section-head>p{max-width:960px}\n#ftw .ft-page .ft-steps{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:26px;list-style:none;margin:0;padding:0}\n#ftw .ft-page .ft-step{--card:var(--blue);position:relative;display:flex;flex-direction:column;min-width:0;margin-top:36px;padding:22px 8px 8px;background:var(--card);border-radius:14px}\n#ftw .ft-page .ft-step:nth-child(2){--card:var(--yellow)}\n#ftw .ft-page .ft-step:nth-child(3){--card:var(--green)}\n#ftw .ft-page .ft-step::before{content:\"\";position:absolute;top:-35px;left:0;width:100%;height:36px;background:var(--card);-webkit-mask:url('https:\/\/mini-talks.org\/wp-content\/uploads\/2026\/02\/yeni-sari-4.png') center bottom\/100% auto no-repeat;mask:url('https:\/\/mini-talks.org\/wp-content\/uploads\/2026\/02\/yeni-sari-4.png') center bottom\/100% auto no-repeat}\n#ftw .ft-page .ft-step-inner{flex:1;padding:24px 22px;background:#fff;border-radius:10px}\n#ftw .ft-page .ft-number{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;margin-bottom:18px;background:var(--card);color:#fff;border-radius:10px;font-size:20px;font-weight:900}\n#ftw .ft-page .ft-step:nth-child(2) .ft-number{color:var(--ink)}\n#ftw .ft-page .ft-step p{font-size:15px}\n#ftw .ft-page .ft-module{padding:30px;border:4px solid var(--red);border-bottom:10px solid var(--blue);border-radius:16px;gap:36px}\n#ftw .ft-page .ft-module img{width:100%;max-height:380px;object-fit:contain}\n#ftw .ft-page .ft-feature-list{list-style:none;margin:20px 0 0;padding:0}\n#ftw .ft-page .ft-feature-list li{position:relative;margin-bottom:14px;padding-left:24px;font-size:16px;font-weight:600;line-height:1.7}\n#ftw .ft-page .ft-feature-list li::before{content:\"\";position:absolute;top:9px;left:0;width:10px;height:10px;border-radius:2px;background:var(--blue)}\n#ftw .ft-page .ft-link{color:var(--blue);font-weight:800;text-decoration:underline;text-decoration-thickness:2px;text-underline-offset:4px}\n#ftw .ft-page .ft-link:hover{color:var(--red)}\n#ftw .ft-page .ft-outline-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:24px}\n#ftw .ft-page .ft-outline{padding:25px;border:4px solid var(--blue);border-bottom-width:10px;border-radius:14px}\n#ftw .ft-page .ft-outline:nth-child(2){border-color:var(--green)}\n#ftw .ft-page .ft-outline:nth-child(3){border-color:var(--red)}\n#ftw .ft-page .ft-outline p{font-size:15px}\n#ftw .ft-page .ft-boundary{padding:24px 28px;border-left:6px solid var(--blue);border-radius:10px;background:#F3F7FC}\n#ftw .ft-page .ft-boundary h2{font-size:clamp(22px,2vw,30px)}\n#ftw .ft-page .ft-closing{position:relative;margin-top:24px;background:var(--yellow)}\n#ftw .ft-page .ft-closing::before{content:\"\";position:absolute;top:-24px;left:0;width:100%;height:24px;background:url('https:\/\/mini-talks.org\/wp-content\/uploads\/2026\/02\/yeni-3-sari.png') repeat-x center bottom\/auto 24px}\n#ftw .ft-page .ft-closing-inner{display:flex;align-items:center;justify-content:space-between;gap:44px;padding:40px 0 44px}\n#ftw .ft-page .ft-closing-copy{flex:1;min-width:0}\n#ftw .ft-page .ft-closing h2{color:var(--ink);font-size:clamp(27px,2.6vw,40px)}\n#ftw .ft-page .ft-closing h2 span{color:var(--blue)}\n#ftw .ft-page .ft-closing-copy>p:last-child{max-width:700px}\n#ftw .ft-page .ft-actions{flex-shrink:0;padding:0 6px 6px 0}\n#ftw .ft-page .ft-button{display:inline-flex;align-items:center;justify-content:center;gap:10px;min-height:56px;padding:16px 24px;background:var(--ink)!important;border:3px solid var(--ink)!important;border-radius:999px;box-shadow:5px 5px 0 var(--red);color:#fff!important;font-size:14px;font-weight:900;line-height:1.4;text-decoration:none!important;text-align:center;transition:transform .16s,box-shadow .16s,background-color .16s}\n#ftw .ft-page .ft-button:hover,#ftw .ft-page .ft-button:focus-visible{background:var(--blue)!important;border-color:#fff!important;box-shadow:3px 3px 0 var(--red);transform:translate(2px,2px)}\n#ftw .ft-page a:focus-visible{outline:3px solid var(--blue);outline-offset:5px}\n#ftw .ft-page .ft-button:focus-visible{outline-color:var(--ink)}\n@media(max-width:1100px){#ftw .ft-page .ft-steps,#ftw .ft-page .ft-outline-grid{gap:18px}\n#ftw .ft-page .ft-step-inner,#ftw .ft-page .ft-outline{padding:20px 16px}}\n@media(max-width:992px){#ftw .ft-page .ft-split{grid-template-columns:1fr;gap:28px}\n#ftw .ft-page .ft-figure-panel img{height:360px}\n#ftw .ft-page .ft-steps,#ftw .ft-page .ft-outline-grid{grid-template-columns:1fr}\n#ftw .ft-page .ft-closing-inner{flex-direction:column;align-items:flex-start;gap:24px}}\n@media(max-width:768px){#ftw .ft-page .ft-wrap{width:92%}\n#ftw .ft-page .ft-hero{padding-top:30px}\n#ftw .ft-page .ft-hero-flex{grid-template-columns:minmax(0,1fr);gap:28px}\n#ftw .ft-page .ft-hero-copy{flex:none;width:100%}\n#ftw .ft-page .ft-hero .ft-bars{width:100%}\n#ftw .ft-page .ft-hero-visual{width:100%;max-width:360px;height:160px;margin:0 auto}\n#ftw .ft-page .ft-hero-visual img{width:min(100%,110.873239px)}\n#ftw .ft-page .ft-intro{padding:38px 0 46px}\n#ftw .ft-page .ft-section{padding-bottom:48px}\n#ftw .ft-page .ft-bars{height:7px}\n#ftw .ft-page .ft-module{padding:20px}\n#ftw .ft-page .ft-figure-panel{padding:20px}\n#ftw .ft-page .ft-figure-panel img{height:320px}\n#ftw .ft-page .ft-note,#ftw .ft-page .ft-boundary{padding:21px 19px}\n#ftw .ft-page .ft-closing-inner{padding:28px 0 30px}\n#ftw .ft-page .ft-actions,#ftw .ft-page .ft-button{width:100%}\n#ftw .ft-page .ft-step-inner{padding:22px}\n#ftw .ft-page h3{overflow-wrap:anywhere}}\n@media(prefers-reduced-motion:reduce){#ftw .ft-page .ft-button{transition:none;transform:none}}\n#ftw .ft-page .chapter-box{margin:42px auto 64px;padding:28px;border:4px solid var(--box-color,var(--blue));border-bottom-width:10px;border-radius:14px;scroll-margin-top:90px}\n#ftw .chapter-box:nth-of-type(3n){--box-color:var(--green)}\n#ftw .chapter-box:nth-of-type(3n + 1){--box-color:var(--red)}\n#ftw .chapter-nav .ft-wrap{gap:18px;overflow:auto;white-space:nowrap}\n#ftw .chapter-nav a{font-size:12px}\n#ftw .build-tabs{grid-template-columns:repeat(5,1fr)}\n#ftw .personal-layout,#ftw .sync-layout{display:grid;grid-template-columns:minmax(0,1.5fr) minmax(230px,1fr);gap:24px;align-items:center}\n#ftw .personal-stage{height:440px}\n#ftw .personal-steps{display:grid;gap:8px;margin:18px 0}\n#ftw .personal-layout aside p,#ftw .sync-layout aside p{font-size:14px}\n#ftw .sync-layout .hero-product{min-width:0}\n#ftw .sync-layout .hero-stage{height:450px}\n#ftw .sync-layout svg{width:100%;margin-top:24px}\n#ftw .sample-recording{display:flex;gap:10px;padding:14px;background:#f0f5f2;border-radius:10px;font-size:12px}\n#ftw .transfer-motion{margin-left:auto;color:var(--green);animation:transfer 2s ease-in-out infinite}\n@keyframes transfer{50%{transform:translateX(7px);opacity:.5}}\n#ftw .usb-lead{stroke-dasharray:8 3;animation:flow 1s linear infinite}\n@keyframes flow{to{stroke-dashoffset:-22}}\n#ftw #figure-preview{margin-top:14px}\n#ftw .ft-page .ft-closing::before{background:url('https:\/\/mini-talks.org\/wp-content\/uploads\/2026\/02\/yeni-3-sari.png') repeat-x center bottom\/auto 24px}\n#ftw .section-intro{margin-bottom:24px}\n@media(max-width:900px){#ftw .personal-layout,#ftw .sync-layout{grid-template-columns:1fr}\n#ftw .ft-page .chapter-box{padding:18px;width:92%}\n#ftw .build-tabs{gap:4px}\n#ftw .build-tabs button{font-size:11px;padding:10px 4px}\n#ftw .personal-stage{height:340px}}\n@media(prefers-reduced-motion:reduce){#ftw .transfer-motion,#ftw .usb-lead{animation:none}}\n#ftw .ft-page .profile-link{font-size:12px;padding:12px 16px;min-height:46px;margin-top:14px}\n#ftw .profile-path{margin-top:24px!important;font-size:12px!important}\n#ftw .ft-page .chapter-box{--panel-tint:color-mix(in srgb,var(--box-color,var(--blue)) 5%,white)}\n#ftw .ft-page .chapter-box :is(.part-detail,.circuit-render,.build-layout,.personal-layout,.software-panel,.try-device-content,.sync-layout){\n background:var(--panel-tint);border:0;border-bottom:8px solid var(--box-color,var(--blue));border-radius:20px;min-width:0;\n}\n#ftw .ft-page .chapter-box :is(.personal-layout,.sync-layout){padding:24px}\n#ftw .ft-page .chapter-box .connection-detail{background:var(--panel-tint);border:0;border-bottom:6px solid var(--box-color,var(--blue));border-radius:16px;padding:18px}\n#ftw .ft-page .chapter-box .connection-detail th{background:color-mix(in srgb,var(--box-color,var(--blue)) 9%,white)}\n#ftw .ft-page .chapter-box .sync-layout .hero-product{background:transparent;padding:0}\n#ftw .ft-page .software-panel{grid-template-columns:minmax(0,1.1fr) minmax(0,.9fr);align-items:start;gap:32px}\n#ftw .ft-page .personal-layout{grid-template-columns:minmax(0,1.55fr) minmax(230px,1fr)}\n#ftw .ft-page .sync-layout{grid-template-columns:minmax(0,1.35fr) minmax(250px,1fr)}\n@media(max-width:900px){#ftw .ft-page .chapter-box :is(.personal-layout,.sync-layout){padding:18px;grid-template-columns:1fr}\n#ftw .ft-page .software-panel{grid-template-columns:1fr;gap:24px}\n#ftw .ft-page .chapter-box .connection-detail{padding:16px}\n\n}\n#ftw .ft-page .figure-pose-panel{margin:16px 0 24px;padding:14px 16px;background:white;border:2px solid #d8dce0;border-radius:14px;text-align:left}\n#ftw .ft-page .figure-pose-panel summary{cursor:pointer;color:var(--blue);font-weight:800;font-size:14px}\n#ftw .ft-page .figure-pose-panel .assembly-pose-bar{position:static;display:flex;flex-wrap:wrap;gap:12px;margin-top:14px;padding:0;background:transparent;box-shadow:none}\n#ftw .ft-page #connect-sync .sync-layout{align-items:start}\n#ftw .ft-page #connect-sync aside{padding-top:24px}\n#ftw .ft-page #profile-sync .profile-scene-card{background:var(--panel-tint);border-radius:20px;border-bottom:8px solid var(--box-color);padding:24px}\n#ftw .ft-page #profile-scene{height:540px;width:100%;border-radius:16px}\n#ftw .ft-page .profile-scene-actions{display:flex;flex-wrap:wrap;justify-content:center;gap:10px;margin:18px 0}\n#ftw .ft-page #profile-scene-status{text-align:center;font-size:14px;font-weight:700}\n#ftw .ft-page .profile-guide{display:grid;grid-template-columns:1.1fr 1fr;gap:32px;margin-top:28px;border-top:2px solid #d8dce0;padding-top:24px;align-items:center}\n#ftw .ft-page .profile-guide p{font-size:14px}\n@media(max-width:700px){#ftw .ft-page #profile-scene{height:360px}\n#ftw .ft-page #profile-sync .profile-scene-card{padding:12px}\n#ftw .ft-page .profile-guide{grid-template-columns:1fr;gap:14px}\n#ftw .ft-page .profile-scene-actions button{font-size:11px}}\n#ftw .ft-page .personal-downloads{display:grid;gap:8px;margin:16px 0}\n#ftw .ft-page .personal-downloads a{display:flex;flex-direction:column;gap:3px;padding:11px 14px;border:1px solid #d8dce0;border-radius:10px;background:white;color:var(--blue);text-decoration:none}\n#ftw .ft-page .personal-downloads a:hover{border-color:var(--blue)}\n#ftw .ft-page .personal-downloads strong{font-size:14px}\n#ftw .ft-page .personal-downloads span{font-size:11px;color:#59636b;line-height:1.4}\n#ftw .ft-page .build-tabs{gap:8px}\n#ftw .ft-page .build-tabs button{display:flex;align-items:center;justify-content:flex-start;gap:9px;padding:10px;min-width:0;text-align:left;border-color:#d8dce0}\n#ftw .ft-page .build-tabs button[aria-pressed=true]{border-color:var(--blue)}\n#ftw .ft-page .build-tabs img{width:56px;height:56px;object-fit:contain;flex:0 0 56px;border-radius:7px;background:#f9fafc}\n#ftw .ft-page .build-tabs span{font-size:13px;line-height:1.25}\n#ftw .ft-page .build-tabs button:hover{border-color:var(--blue)}\n@media(max-width:700px){#ftw .ft-page .build-tabs{grid-template-columns:repeat(2,minmax(0,1fr))}\n#ftw .ft-page .build-tabs img{width:44px;height:44px;flex-basis:44px}\n#ftw .ft-page .build-tabs button{padding:8px}\n#ftw .ft-page .build-tabs span{font-size:12px}}\n#ftw .ft-page .fig-introduction{display:grid;grid-template-columns:1.15fr 1fr;gap:28px;margin:8px auto 30px;padding:22px 0;border-top:1px solid #e2e5e8;border-bottom:1px solid #e2e5e8}\n#ftw .ft-page .fig-introduction h2,#ftw .ft-page .fig-introduction h3{font-size:23px;margin-bottom:10px}\n#ftw .ft-page .fig-introduction p{font-size:14px;line-height:1.65;margin-bottom:10px}\n#ftw .ft-page .fig-introduction .ft-eyebrow{font-size:11px;margin-bottom:7px}\n#ftw .ft-page .fig-introduction .small-note{font-size:12px;color:#59636b}\n#ftw .ft-page .fig-introduction article+article{padding-left:28px;border-left:3px solid var(--green)}\n@media(max-width:700px){#ftw .ft-page .fig-introduction{grid-template-columns:1fr;gap:18px}\n#ftw .ft-page .fig-introduction article+article{padding-left:16px}}\n:root{--site-header-h:156px;--chapter-rail:208px}\nhtml{scroll-padding-top:calc(var(--site-header-h) + 14px)}\n#ftw main.ft-page{margin-left:var(--chapter-rail);padding:18px 24px 0;min-width:0}\n#ftw .ft-page .chapter-nav{position:fixed;top:var(--site-header-h);left:0;bottom:0;width:var(--chapter-rail);z-index:100;background:#fff;border-right:1px solid #dce1e6;border-bottom:0;overflow:auto;padding:18px 10px;box-sizing:border-box}\n#ftw .ft-page .chapter-nav .ft-wrap{display:flex;flex-direction:column;gap:5px;width:100%;margin:0;overflow:visible;white-space:normal}\n#ftw .ft-page .chapter-nav a{display:flex;align-items:center;gap:9px;padding:12px 9px;font-size:12px;line-height:1.35;border:0;border-radius:9px;text-decoration:none;color:#33404b}\n#ftw .ft-page .chapter-nav a:hover{background:#edf4fc}\n#ftw .ft-page .chapter-nav a[aria-current=location]{background:var(--blue);color:white}\n#ftw .ft-page .chapter-number{font-size:10px;opacity:.65;flex:0 0 18px}\n#ftw .ft-page>.ft-wrap{width:100%;max-width:none}\n#ftw .ft-page .chapter-box{width:100%;margin:0 0 22px;padding:20px;border-width:2px;border-bottom-width:6px;scroll-margin-top:0}\n#ftw .ft-page .section-intro{margin-bottom:16px}\n#ftw .ft-page .section-intro h2{font-size:clamp(24px,2.5vw,34px);margin-bottom:8px}\n#ftw .ft-page .section-intro p{font-size:14px;line-height:1.6;margin-bottom:8px}\n#ftw .ft-page #about .ft-hero{padding:0;margin-bottom:12px;width:100%}\n#ftw .ft-page #about .ft-hero-flex{grid-template-columns:1fr 210px;gap:20px}\n#ftw .ft-page #about .ft-title{display:none}\n#ftw .ft-page #about .ft-hero-visual{height:150px;max-width:210px}\n#ftw .ft-page #about .ft-hero-visual img{height:140px;width:auto;margin:auto}\n#ftw .ft-page #about .ft-hero p{font-size:17px}\n#ftw .ft-page #about .fig-introduction{width:100%;margin:0;padding:16px 0 0;border-bottom:0;gap:20px}\n#ftw .ft-page .build-layout,#ftw .ft-page .try-device-content,#ftw .ft-page .software-panel{padding:18px;gap:20px}\n#ftw .ft-page .chapter-box .personal-layout,#ftw .ft-page .chapter-box .sync-layout{padding:18px;gap:20px}\n#ftw .ft-page .part-detail{padding:18px}\n#ftw .ft-page .part-stage,#ftw .ft-page .build-stage,#ftw .ft-page .personal-stage{height:340px}\n#ftw .ft-page .sync-layout .hero-stage{height:380px}\n#ftw .ft-page .ft-demo-model{height:390px}\n#ftw .ft-page #profile-scene{height:410px}\n@media(max-width:1200px){:root{--chapter-rail:174px}\n#ftw .ft-page .build-tabs{grid-template-columns:repeat(3,minmax(0,1fr))}\n#ftw .ft-page .parts-layout{grid-template-columns:160px minmax(0,1fr)}\n#ftw .ft-page .connections-workspace,#ftw .ft-page .build-layout,#ftw .ft-page .try-device-content{grid-template-columns:1fr}\n#ftw .ft-page .connection-layout{grid-template-columns:1fr 1.2fr}\n#ftw .ft-page .connections-workspace .connection-map{grid-template-columns:repeat(2,minmax(0,1fr))}}\n@media(max-width:700px){:root{--chapter-rail:122px}\n#ftw main.ft-page{padding:12px 10px 0}\n#ftw .ft-page .chapter-nav{padding:12px 5px}\n#ftw .ft-page .chapter-nav a{padding:10px 6px;gap:5px;font-size:11px}\n#ftw .ft-page .chapter-number{flex-basis:14px}\n#ftw .ft-page .chapter-box{padding:12px;margin-bottom:16px}\n#ftw .ft-page #about .ft-hero-flex,#ftw .ft-page #about .fig-introduction,#ftw .ft-page .parts-layout,#ftw .ft-page .connection-layout{grid-template-columns:1fr}\n#ftw .ft-page .part-stage,#ftw .ft-page .build-stage,#ftw .ft-page .personal-stage,#ftw .ft-page .ft-demo-model,#ftw .ft-page .sync-layout .hero-stage{height:290px}\n#ftw .ft-page #profile-scene{height:280px}\n#ftw .ft-page .build-tabs{grid-template-columns:repeat(2,minmax(0,1fr))}\n#ftw .ft-page .build-tabs img{width:30px;height:30px;flex-basis:30px}\n#ftw .ft-page .build-tabs span{font-size:10px}\n#ftw .ft-page .section-intro h2{font-size:23px}\n#ftw .ft-page .view-bar{flex-wrap:wrap}\n#ftw .ft-page .profile-scene-actions{gap:5px}}\n#ftw main.ft-page{width:calc(100% - var(--chapter-rail));box-sizing:border-box}\n#ftw .ft-page .chapter-nav a{white-space:normal;overflow-wrap:anywhere;flex-shrink:0}\n#ftw main.ft-page{width:100%;margin:0;padding:0}\n#ftw .ft-page>.ft-hero.ft-wrap{width:82%;max-width:1320px;margin:0 auto;padding:40px 0 24px}\n#ftw .ft-page .chapter-workspace{display:grid;grid-template-columns:var(--chapter-rail) minmax(0,1fr);gap:22px;width:94%;max-width:1600px;margin:18px auto 0;align-items:start}\n#ftw .ft-page .chapter-content{min-width:0}\n#ftw .ft-page .chapter-content>.ft-wrap{width:100%;max-width:none}\n#ftw .ft-page .chapter-workspace>.chapter-nav{position:sticky;top:calc(var(--site-header-h) + 12px);left:auto;bottom:auto;width:100%;height:auto;max-height:calc(100vh - var(--site-header-h) - 24px);padding:6px;align-self:start;border:1px solid #dce1e6;border-radius:12px}\n#ftw .ft-page>.ft-closing{width:82%;margin:28px auto 0}\n@media(max-width:700px){#ftw .ft-page>.ft-hero.ft-wrap{width:92%;padding:26px 0 18px}\n#ftw .ft-page .chapter-workspace{width:96%;gap:10px;margin-top:12px}\n#ftw .ft-page>.ft-closing{width:92%}}\n#ftw .ft-page #connect-sync .sync-layout{grid-template-columns:minmax(0,1.2fr) minmax(230px,1fr);gap:16px;padding:14px;align-items:center}\n#ftw .ft-page #connect-sync aside{padding:0;min-width:0}\n#ftw .ft-page #connect-sync .hero-stage{height:340px}\n#ftw .ft-page #connect-sync .view-bar{margin:6px 0 0}\n#ftw .ft-page #connect-sync h3{margin:0 0 8px;font-size:20px}\n#ftw .ft-page #connect-sync .figure-pose-panel{padding:10px;margin:8px 0 12px}\n#ftw .ft-page #connect-sync .assembly-pose-bar{gap:8px;margin-top:8px}\n#ftw .ft-page #connect-sync .module-actions{margin:12px 0 6px;gap:5px}\n#ftw .ft-page #connect-sync .module-actions button{font-size:11px;padding:8px 5px}\n#ftw .ft-page #connect-sync .rear-choice{justify-content:flex-start;gap:8px}\n#ftw .ft-page #connect-sync .model-hint{margin:6px 0 0;font-size:11px}\n#ftw .ft-page #profile-sync .profile-scene-card{display:grid;grid-template-columns:minmax(0,1.5fr) minmax(220px,1fr);gap:16px;padding:14px;align-items:center}\n#ftw .ft-page #profile-sync .profile-visual{min-width:0}\n#ftw .ft-page #profile-sync #profile-scene{height:300px}\n#ftw .ft-page #profile-sync .profile-guide{display:block;margin:0;padding:0;border:0}\n#ftw .ft-page #profile-sync .profile-guide h3{font-size:20px;margin:0 0 8px}\n#ftw .ft-page #profile-sync .profile-guide p{font-size:12px;line-height:1.5;margin:8px 0}\n#ftw .ft-page #profile-sync .profile-link{font-size:12px;padding:12px 14px;display:block;text-align:center}\n#ftw .ft-page #profile-sync .profile-scene-actions{gap:5px;margin:8px 0 4px}\n#ftw .ft-page #profile-sync .profile-scene-actions button{font-size:11px;padding:8px}\n#ftw .ft-page #profile-sync #profile-scene-status{font-size:11px;margin:6px 0 0}\n@media(max-width:850px){#ftw .ft-page #connect-sync .sync-layout,#ftw .ft-page #profile-sync .profile-scene-card{grid-template-columns:1fr;gap:12px}\n#ftw .ft-page #connect-sync .hero-stage{height:300px}\n#ftw .ft-page #profile-sync #profile-scene{height:260px}}\n#ftw .ft-page #connect-sync aside>.view-bar{justify-content:flex-start;margin:0 0 12px}\n#ftw .ft-page #profile-sync .profile-scene-actions{justify-content:flex-start;margin:0 0 8px}\n#ftw .ft-page #profile-sync #profile-scene-status{text-align:left;margin:0 0 16px}\n#ftw .ft-page>.ft-closing{width:100%;max-width:none;margin:28px 0 0}\n#ftw .ft-page #about .fig-introduction{grid-template-columns:repeat(2,minmax(0,1fr));gap:0}\n#ftw .ft-page #about .fig-introduction article{min-width:0;padding-right:24px}\n#ftw .ft-page #about .fig-introduction article+article{padding:0 0 0 24px;border-left:3px solid var(--green)}\n#ftw .ft-page #about .about-label{font-size:14px;line-height:1.5;color:var(--green);letter-spacing:.04em;margin:0}\n@media(max-width:700px){#ftw .ft-page #about .fig-introduction{grid-template-columns:1fr;gap:16px}\n#ftw .ft-page #about .fig-introduction article{padding:0}\n#ftw .ft-page #about .fig-introduction article+article{padding:16px 0 0;border-left:0;border-top:3px solid var(--green)}}\n#ftw .ft-page #explorer #part-list{display:grid;gap:8px;margin-bottom:16px}\n#ftw .ft-page #explorer .part-group{display:grid;grid-template-columns:115px repeat(6,minmax(0,1fr));gap:6px;align-items:stretch}\n#ftw .ft-page #explorer .part-group:first-child{grid-template-columns:115px repeat(6,minmax(0,1fr))}\n#ftw .ft-page #explorer .part-group h3{display:flex;align-items:center;margin:0;font-size:11px;letter-spacing:.03em}\n#ftw .ft-page #explorer .part-choice{min-width:0;border:2px solid #d8dce0;border-radius:12px;background:#fff;overflow:hidden}\n#ftw .ft-page #explorer .part-choice:has(input:checked){background:#edf4ff;border-color:var(--blue)}\n#ftw .ft-page #explorer .part-choice[data-active=\"true\"]{box-shadow:0 0 0 2px rgba(0,86,184,.15)}\n#ftw .ft-page #explorer .part-select{display:flex;align-items:center;gap:4px;min-height:49px;padding:5px 6px;cursor:pointer;font-size:10px;font-weight:800;line-height:1.25}\n#ftw .ft-page #explorer .part-select input{flex:none;width:15px;height:15px;margin:0;accent-color:var(--blue);cursor:pointer}\n#ftw .ft-page #explorer .part-select img{flex:none;width:34px;height:34px;object-fit:contain;border-radius:5px;background:#f8f9fb}\n#ftw .ft-page #explorer .part-select span{min-width:0;overflow-wrap:anywhere}\n#ftw .ft-page #explorer .part-view-mode{display:flex;align-items:center;gap:8px;min-height:34px;margin:0 0 8px;color:#58626b;font-size:11px;font-weight:800}\n#ftw .ft-page #explorer .part-view-mode span{margin-right:auto}\n#ftw .ft-page #explorer .part-view-mode button{padding:6px 10px;border-color:var(--blue);color:var(--blue);font-size:11px}\n#ftw .ft-page #explorer .part-view-mode button:hover{background:var(--blue);color:#fff}\n#ftw .ft-page #explorer .parts-layout{grid-template-columns:minmax(0,1.35fr) minmax(270px,1fr);gap:16px;align-items:start}\n#ftw .ft-page #explorer .part-resources{max-height:none;overflow:visible;padding:0;border:0;min-width:0}\n#ftw .ft-page #explorer .file-links{margin:0;gap:6px}\n#ftw .ft-page #explorer .file-links a{padding:8px 12px}\n#ftw .ft-page #explorer .part-resources h3{font-size:16px;margin:14px 0 8px}\n#ftw .ft-page #explorer .eight-views{grid-template-columns:repeat(4,minmax(0,1fr));gap:6px;margin:0}\n#ftw .ft-page #explorer #part-gallery[hidden],#ftw .ft-page #explorer .part-resources h3[hidden]{display:none}\n#ftw .ft-page #explorer .part-view-card{min-width:0;display:flex;flex-direction:column;gap:2px}\n#ftw .ft-page #explorer .part-view-card a{display:block;font-size:9px;line-height:1.35;background:#f8f9fb}\n#ftw .ft-page #explorer .part-view-card img{width:100%;aspect-ratio:1;object-fit:contain}\n#ftw .ft-page #explorer #part-description{min-height:0;margin-bottom:8px}\n#ftw .ft-page #explorer #part-selected-summary[hidden]{display:none}\n#ftw .ft-page #explorer[data-multi=\"true\"] :is(.part-heading,#part-description,#part-rear-design,#part-files,#part-file-note,#part-gallery,.part-resources>h3){display:none!important}\n#ftw .ft-page #explorer[data-multi=\"true\"] .part-resources{border:1px solid #d8dce0;border-radius:14px;padding:16px;background:#fff}\n#ftw .ft-page #explorer #part-selected-summary h3{margin:0 0 12px;font-size:18px}\n#ftw .ft-page #explorer .selected-parts-list{list-style:none;margin:0;padding:0;display:grid;gap:0}\n#ftw .ft-page #explorer .selected-parts-list li{padding:11px 0;border-top:1px solid #e4e7e9}\n#ftw .ft-page #explorer .selected-parts-list .ft-eyebrow{display:block;margin:0 0 2px;font-size:10px}\n#ftw .ft-page #explorer .selected-parts-list strong{display:block;font-size:14px}\n#ftw .ft-page #explorer .selected-parts-list p{margin:3px 0 0;font-size:12px;line-height:1.45;color:#58626b}\n@media(max-width:1000px){#ftw .ft-page #explorer .part-group,#ftw .ft-page #explorer .part-group:first-child{grid-template-columns:repeat(3,minmax(0,1fr))}\n#ftw .ft-page #explorer .part-group h3{grid-column:1\/-1}\n#ftw .ft-page #explorer .parts-layout{grid-template-columns:1fr}\n#ftw .ft-page #explorer .eight-views{grid-template-columns:repeat(4,minmax(0,1fr))}}\n@media(min-width:1001px){#ftw .ft-page #explorer .part-choice[data-part=\"fig-talks-battery-panel\"] .part-select span{font-size:9px}}\n@media(max-width:700px){#ftw .ft-page #explorer .part-group,#ftw .ft-page #explorer .part-group:first-child{grid-template-columns:repeat(2,minmax(0,1fr))}}\n#ftw .ft-page #profile-sync>.profile-scene-actions{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;margin:0 0 16px}\n#ftw .ft-page #profile-sync>.profile-scene-actions button{width:100%;min-height:56px;padding:12px;border:2px solid var(--blue);border-radius:12px;background:#fff;color:var(--ink);font-size:13px;font-weight:800;text-align:center}\n#ftw .ft-page #profile-sync>.profile-scene-actions button:hover,#ftw .ft-page #profile-sync>.profile-scene-actions button:focus-visible{background:var(--blue);color:#fff}\n@media(max-width:700px){#ftw .ft-page #profile-sync>.profile-scene-actions{grid-template-columns:1fr;gap:6px}\n#ftw .ft-page #profile-sync>.profile-scene-actions button{min-height:42px;padding:8px;font-size:11px}}\n#ftw .ft-page #connect-sync>.module-actions{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;margin:0 0 16px}\n#ftw .ft-page #connect-sync>.module-actions button{width:100%;min-height:56px;padding:12px;border:2px solid var(--blue);border-radius:12px;background:#fff;color:var(--ink);font-size:13px;font-weight:800;text-align:center}\n#ftw .ft-page #connect-sync>.module-actions button:hover:not(:disabled),#ftw .ft-page #connect-sync>.module-actions button:focus-visible{background:var(--blue);color:#fff}\n@media(max-width:700px){#ftw .ft-page #connect-sync>.module-actions{grid-template-columns:1fr;gap:6px}\n#ftw .ft-page #connect-sync>.module-actions button{min-height:42px;padding:8px;font-size:11px}}\n#ftw .ft-page .personal-steps{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:8px;margin:0 0 14px}\n#ftw .ft-page .personal-steps button{display:flex;align-items:center;gap:9px;min-width:0;padding:9px;text-align:left;border-color:#d8dce0}\n#ftw .ft-page .personal-steps button[aria-pressed=true]{border-color:var(--blue)}\n#ftw .ft-page .personal-steps img{width:72px;height:52px;flex:0 0 72px;object-fit:contain;border-radius:7px;background:#f9fafc}\n#ftw .ft-page .personal-steps span{font-size:12px;line-height:1.25}\n#ftw .ft-page .personal-downloads [hidden]{display:none!important}\n#ftw .ft-page #personal-step-title{margin:4px 0 8px}\n#ftw .ft-page #personal-status{min-height:2.8em}\n@media(max-width:800px){#ftw .ft-page .personal-steps{grid-template-columns:repeat(2,minmax(0,1fr))}\n#ftw .ft-page .personal-steps img{width:58px;height:42px;flex-basis:58px}}\n#ftw .ft-page #explorer .part-rear-design{margin:8px 0 10px;padding:12px;border:1px solid #d8dce0;border-radius:12px;background:#f7f9fc}\n#ftw .ft-page #explorer .part-rear-design .ft-eyebrow{display:block;margin:0 0 8px;font-size:11px}\n#ftw .ft-page #explorer .part-rear-options{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:6px}\n#ftw .ft-page #explorer .part-rear-options button{min-height:39px;padding:6px 5px;font-size:10px;line-height:1.2}\n#ftw .ft-page #explorer #part-rear-name-field{display:flex;align-items:center;gap:10px;margin-top:10px;font-size:11px;font-weight:800}\n#ftw .ft-page #explorer #part-rear-name-field[hidden]{display:none}\n#ftw .ft-page #explorer #part-rear-name{flex:1;min-width:0;padding:8px 10px;border:1px solid #b7c4d2;border-radius:8px;background:#fff;font:inherit}\n#ftw .ft-page #explorer #part-rear-hint{margin:6px 0 0;font-size:10px}\n@media(max-width:620px){#ftw .ft-page #explorer .part-rear-options{grid-template-columns:repeat(2,minmax(0,1fr))}}\n\n\n<\/style>\n<div id=\"ftw\">\n<main class=\"ft-page\">\n<section class=\"ft-hero ft-wrap\" aria-labelledby=\"ft-title\">\n    <div class=\"ft-hero-flex\">\n      <div class=\"ft-hero-copy\">\n        <h1 class=\"ft-title\" id=\"ft-title\">Fig-Talks<\/h1>\n        <div class=\"ft-bars\" aria-hidden=\"true\"><span><\/span><span><\/span><span><\/span><span><\/span><\/div>\n        <p>G\u00f8r din figur personlig.<br>Optag og afspil din stemme.<br>Lad din egen krop tale.<\/p>\n      <\/div>\n      <div class=\"ft-hero-visual\"><img data-ft-src=\"mini_kits_fig_talks.png\" alt=\"Fig-Talks character with red glasses and a red shirt\" width=\"984\" height=\"1420\"><\/div>\n    <\/div>\n  <\/section>\n<div class=\"chapter-workspace\"><nav class=\"chapter-nav\" aria-label=\"Fig-Talks sections\"><div class=\"ft-wrap\"><a href=\"#about\"><span class=\"chapter-number\">01<\/span><span>What is Fig-Talks?<\/span><\/a><a href=\"#explorer\"><span class=\"chapter-number\">02<\/span><span>Parts<\/span><\/a><a href=\"#connections\"><span class=\"chapter-number\">03<\/span><span>Connections<\/span><\/a><a href=\"#assembly\"><span class=\"chapter-number\">04<\/span><span>Byg<\/span><\/a><a href=\"#personalize\"><span class=\"chapter-number\">05<\/span><span>Personalize<\/span><\/a><a href=\"#software\"><span class=\"chapter-number\">06<\/span><span>Software<\/span><\/a><a href=\"#try-device\"><span class=\"chapter-number\">07<\/span><span>Try it<\/span><\/a><a href=\"#connect-sync\"><span class=\"chapter-number\">08<\/span><span>Play & explore<\/span><\/a><a href=\"#profile-sync\"><span class=\"chapter-number\">09<\/span><span>Profile & sync<\/span><\/a><\/div><\/nav><div class=\"chapter-content\">\n<section id=\"about\" class=\"ft-wrap chapter chapter-box\"><div class=\"section-intro\"><p class=\"ft-eyebrow about-label\">01 \/ WHAT IS FIG-TALKS?<\/p><h2>A personalized figure. A familiar voice.<\/h2><\/div>  <div class=\"ft-wrap fig-introduction\" aria-label=\"About Fig-Talks\"><article><p class=\"ft-eyebrow\">A PERSONAL FIGURE<\/p><h3>Their figure. Their voice.<\/h3><p>A personalized physical figure with a removable voice module. Children can record a sound, a word or a message, then play it back as part of a story or a moment of play. Hair, glasses and facial details make the character their own.<\/p><\/article><article><p class=\"ft-eyebrow\">THE ROLE OF FIG-TALKS<\/p><h3>Play at their own pace.<\/h3><p>A tool for play and recorded expression. Listening, exploring and choosing not to record are all valid ways to take part. There is no required speaking goal or expected outcome.<\/p><p class=\"small-note\">Fig-Talks does not diagnose, treat or replace child-specific professional support.<\/p><\/article><\/div>\n<\/section>\n\n<section class=\"ft-wrap ft-section chapter chapter-box\" id=\"explorer\"><div class=\"section-intro\"><p class=\"ft-eyebrow\">02 \/ Parts<\/p><h2>Every part has a place.<\/h2><p>Choose a part to turn it around, see what it does and get its files.<\/p><\/div><div id=\"part-list\" aria-label=\"Choose a part\"><\/div><div class=\"parts-layout\"><div class=\"part-detail\"><div class=\"part-heading\"><div><span id=\"part-category\" class=\"ft-eyebrow\"><\/span><h3 id=\"part-title\"><\/h3><\/div><\/div><p id=\"part-description\"><\/p><div id=\"part-rear-design\" class=\"part-rear-design\" hidden><span class=\"ft-eyebrow\">Rear design<\/span><div class=\"part-rear-options\" role=\"group\" aria-label=\"Rear cover design\"><button type=\"button\" data-rear-option=\"logo\">Mini-Talks logo<\/button><button type=\"button\" data-rear-option=\"name\">Your Name<\/button><button type=\"button\" data-rear-option=\"discs\">Four Studs<\/button><button type=\"button\" data-rear-option=\"plain\">Plain<\/button><\/div><label id=\"part-rear-name-field\" hidden>Write Your Name<input id=\"part-rear-name\" type=\"text\" maxlength=\"24\" autocomplete=\"off\" placeholder=\"Write Your Name\" aria-label=\"Write Your Name\"><\/label><p id=\"part-rear-hint\" class=\"small-note\" hidden>The typed name is a live 3D preview. The Your Name STEP and STL files still contain the placeholder text.<\/p><\/div><div class=\"part-view-mode\"><span id=\"part-view-status\" role=\"status\"><\/span><button id=\"part-locate\" type=\"button\">In Fig-Talks \u2197<\/button><button id=\"part-back\" type=\"button\" hidden>Show selected parts<\/button><\/div><div id=\"part-view\" class=\"model-stage part-stage\"><\/div><div class=\"view-bar\" id=\"part-angles\"><\/div><\/div><aside class=\"part-resources\"><div id=\"part-selected-summary\" hidden><\/div><div id=\"part-files\" class=\"file-links\"><\/div><p id=\"part-file-note\" class=\"small-note\"><\/p><h3>Eight views<\/h3><div id=\"part-gallery\" class=\"eight-views\"><\/div><\/aside><\/div><\/section>\n<section class=\"ft-wrap ft-section chapter chapter-box\" id=\"connections\"><div class=\"section-intro\"><p class=\"ft-eyebrow\">03 \/ Understand the connections<\/p><h2>One core. A complete voice.<\/h2><p>Inspect the wired circuit. Choose a module to see its pins.<\/p><\/div><div class=\"connections-workspace\"><div class=\"circuit-render\"><h3>The complete circuit<\/h3><div class=\"view-bar circuit-layout-switch\" aria-label=\"Circuit layout\"><button data-circuit-layout=\"flat\" aria-pressed=\"true\">Flat layout<\/button><button data-circuit-layout=\"fitted\" aria-pressed=\"false\">Inside device \u00b7 no case<\/button><\/div><label class=\"rear-choice\">Inspect <select id=\"circuit-inspect\"><option value=\"\">Complete circuit<\/option><option value=\"mini-core\">Mini-Core<\/option><option value=\"fig-talks-button\">Button PCB<\/option><option value=\"mini-talks-microphone\">Microphone<\/option><option value=\"speaker\">Speaker<\/option><option value=\"lipo-battery\">Battery<\/option><\/select><\/label><div id=\"circuit-view\" class=\"model-stage circuit-stage\" aria-label=\"Planar 3D circuit with wires connected to actual terminals\"><\/div><div id=\"circuit-fitted-view\" class=\"model-stage circuit-stage\" aria-label=\"Five electronics in their fitted device positions, without enclosure\" hidden><\/div><div class=\"view-bar\"><button data-circuit-angle=\"Back\">Flat \u00b7 solder side<\/button><button data-circuit-angle=\"Front\">Flat \u00b7 component side<\/button><button data-circuit-angle=\"Back angle\">Angle<\/button><button data-circuit-control=\"plus\" aria-label=\"Zoom in circuit\">+<\/button><button data-circuit-control=\"minus\" aria-label=\"Zoom out circuit\">\u2212<\/button><\/div><p class=\"small-note\">Drag to rotate \u00b7 Inspect a part to read its labels.<\/p><\/div><div class=\"connection-layout\"><div class=\"connection-map\" id=\"connection-map\"><button data-net=\"mic\" class=\"map-module map-mic\"><img data-ft-src=\"mini-talks-microphone-top.png\" alt=\"Microphone board\"><strong>Microphone<\/strong><small>Voice in<\/small><\/button><button data-net=\"speaker\" class=\"map-module map-speaker\"><img data-ft-src=\"speaker-angled.png\" alt=\"Speaker\"><strong>Speaker<\/strong><small>Sound out<\/small><\/button><button data-net=\"button\" class=\"map-module map-button\"><img data-ft-src=\"fig-talks-button-top.png\" alt=\"Button PCB\"><strong>Button PCB<\/strong><small>Controls & lights<\/small><\/button><button data-net=\"battery\" class=\"map-module map-battery\"><img data-ft-src=\"lipo-battery-top.png\" alt=\"Bare-lead LiPo battery\"><strong>Battery<\/strong><small>Power<\/small><\/button><\/div><aside class=\"connection-detail\"><span class=\"ft-eyebrow\">Follow a connection<\/span><h3 id=\"net-title\"><\/h3><p id=\"net-copy\"><\/p><table><thead><tr><th>Mini-Core<\/th><th>Module signal<\/th><\/tr><\/thead><tbody id=\"net-pins\"><\/tbody><\/table><p class=\"small-note\">Match the signal labels; wire colours and lengths are illustrative.<\/p><\/aside><\/div><\/div><\/section>\n<section class=\"ft-wrap ft-section chapter chapter-box\" id=\"assembly\"><div class=\"section-intro\"><p class=\"ft-eyebrow\">04 \/ Put it together<\/p><h2>From a voice module<br>to a play companion.<\/h2><p>Follow the five steps. Turn the model to inspect each part\u2019s position.<\/p><\/div><div class=\"build-tabs\" role=\"group\" aria-label=\"Assembly steps\"><button data-build=\"front\"><img data-ft-src=\"build-front.png\" alt=\"\" width=\"56\" height=\"56\"><span>1 \u00b7 Front<\/span><\/button><button data-build=\"rear\"><img data-ft-src=\"build-rear.png\" alt=\"\" width=\"56\" height=\"56\"><span>2 \u00b7 Rear<\/span><\/button><button data-build=\"connect\"><img data-ft-src=\"build-connect.png\" alt=\"\" width=\"56\" height=\"56\"><span>3 \u00b7 Connect<\/span><\/button><button data-build=\"close\"><img data-ft-src=\"build-close.png\" alt=\"\" width=\"56\" height=\"56\"><span>4 \u00b7 Close<\/span><\/button><button data-build=\"figure\"><img data-ft-src=\"build-figure.png\" alt=\"\" width=\"56\" height=\"56\"><span>5 \u00b7 Fig-Talks<\/span><\/button><\/div><div class=\"build-layout\"><div><div id=\"build-view\" class=\"model-stage build-stage\"><\/div><div class=\"view-bar\"><button data-build-angle=\"Angled\">Angle<\/button><button data-build-angle=\"Front\">Front<\/button><button data-build-angle=\"Back\">Back<\/button><button data-build-angle=\"Right\">Side<\/button><\/div><\/div><aside><span id=\"build-count\" class=\"ft-eyebrow\"><\/span><h3 id=\"build-title\"><\/h3><p id=\"build-copy\"><\/p><ol id=\"build-instructions\"><\/ol><label class=\"separation\">Open the layers<input id=\"build-separation\" aria-label=\"Separate assembly layers\" type=\"range\" min=\"0\" max=\"100\" value=\"0\"><\/label><p id=\"build-note\" class=\"small-note\"><\/p><a href=\"#connect-sync\" class=\"ft-link\">Try taking it out and turning it around \u2191<\/a><\/aside><\/div><\/section>\n<section class=\"ft-wrap ft-section chapter chapter-box\" id=\"personalize\"><div class=\"section-intro\"><p class=\"ft-eyebrow\">05 \/ Personalize<\/p><h2>Their look.<br>Their own character.<\/h2><p>See how the recessed head, face details and hair come together.<\/p><\/div><div class=\"personal-steps\" role=\"group\" aria-label=\"Personalization steps\"><button data-person-step=\"0\"><img data-ft-src=\"personal-head.png\" alt=\"\" width=\"56\" height=\"56\"><span>1 \u00b7 Recessed head<\/span><\/button><button data-person-step=\"1\"><img data-ft-src=\"personal-face.png\" alt=\"\" width=\"56\" height=\"56\"><span>2 \u00b7 Face details<\/span><\/button><button data-person-step=\"2\"><img data-ft-src=\"personal-fit.png\" alt=\"\" width=\"56\" height=\"56\"><span>3 \u00b7 Fit the face<\/span><\/button><button data-person-step=\"3\"><img data-ft-src=\"personal-hair.png\" alt=\"\" width=\"56\" height=\"56\"><span>4 \u00b7 Hair pieces<\/span><\/button><button data-person-step=\"4\"><img data-ft-src=\"personal-complete.png\" alt=\"\" width=\"56\" height=\"56\"><span>5 \u00b7 Head with hair<\/span><\/button><\/div><div class=\"personal-layout\"><div><div id=\"personal-view\" class=\"model-stage personal-stage\" aria-label=\"Personalized head, face inserts and hair\"><\/div><div class=\"view-bar\"><button data-person-angle=\"Right\">Face<\/button><button data-person-angle=\"Angled\">Angle<\/button><button data-person-angle=\"Back\">Side<\/button><\/div><\/div><aside><p class=\"ft-eyebrow\">PERSONALIZATION STEP<\/p><h3 id=\"personal-step-title\"><\/h3><p id=\"personal-status\" role=\"status\"><\/p><div class=\"personal-downloads\" aria-label=\"Personalized print files\"><a data-person-download=\"0\" href=\"https:\/\/mini-talks.org\/fig-talks-3d\/downloads\/fig-talks\/recessed-head-print.stl\" download><strong>Recessed head STL \u2193<\/strong><span>Upper &amp; lower head + 4 joining pins<\/span><\/a><a data-person-download=\"1\" href=\"https:\/\/mini-talks.org\/fig-talks-3d\/downloads\/fig-talks\/face-print.stl\" download hidden><strong>Face STL \u2193<\/strong><span>8 separate pieces \u00b7 eyes, brows, mouth, eye highlights &amp; glasses<\/span><\/a><a data-person-download=\"3\" href=\"https:\/\/mini-talks.org\/fig-talks-3d\/downloads\/fig-talks\/hair-print.stl\" download hidden><strong>Hair STL \u2193<\/strong><span>2 separate hair pieces<\/span><\/a><\/div><a class=\"ft-button profile-link\" href=\"https:\/\/mini-talks.org\/da\/mini-community\/mini-forum\/?view=profile#kits\" target=\"_blank\" rel=\"noopener\">Personalize in your profile \u2192<\/a><p class=\"small-note\">Log in first, then open Fig-Talks in My Kits.<\/p><\/aside><\/div><\/section>\n<section class=\"ft-wrap ft-section chapter chapter-box\" id=\"software\"><div class=\"software-panel\"><div><p class=\"ft-eyebrow\">06 \/ Bring the electronics to life<\/p><h2>The software<br>behind the buttons.<\/h2><\/div><div><h3>Explore the firmware.<\/h3><ol><li>Download the existing Arduino sketch.<\/li><li>Read how Mini-Core records, saves and plays audio.<\/li><li>The updated button mapping and upload guide will be added next.<\/li><\/ol><div id=\"software-downloads\"><\/div><p class=\"small-note\" id=\"software-note\" hidden><\/p><\/div><\/div><\/section>\n<section class=\"ft-wrap ft-section chapter chapter-box\" id=\"try-device\"><div class=\"section-intro\"><p class=\"ft-eyebrow\">07 \/ Try Fig-Talks<\/p><h2>A voice is worth trying.<\/h2><p>Press the buttons on the model or use the controls below. Each light matches its button: blue for power, green for recording and yellow for playback.<\/p><\/div><div class=\"try-device-content\"><\/div><\/section>\n<section class=\"ft-wrap ft-section chapter chapter-box\" id=\"connect-sync\"><div class=\"section-intro\"><p class=\"ft-eyebrow\">08 \/ Play & explore<\/p><h2>A play companion. A voice to explore.<\/h2><p>Move the head, arms, hands and legs. Explore the Fig-Module inside, then take it out, turn it around and put it back.<\/p><\/div><div class=\"module-actions\"><button id=\"module-remove\">1 \u00b7 Take out<\/button><button id=\"module-turn\" disabled>2 \u00b7 Turn around<\/button><button id=\"module-insert\" disabled>3 \u00b7 Put back<\/button><\/div><div class=\"sync-layout\"><div class=\"hero-product\"><div id=\"figure-view\" class=\"model-stage hero-stage\" aria-label=\"Interactive complete Fig-Talks figure\"><\/div><\/div><aside><div class=\"view-bar\"><button data-figure-angle=\"Angled\">Angle<\/button><button data-figure-angle=\"Front\">Front<\/button><button data-figure-angle=\"Back\">Back<\/button><button data-figure-angle=\"Right\">Side<\/button><\/div><h3>Pose &amp; explore<\/h3><div id=\"figure-pose-controls\"><\/div><button id=\"inspect-inside\" aria-pressed=\"false\">Look inside Fig-Talks<\/button><p id=\"module-status\" role=\"status\">Buttons forward \u00b7 Ready to record<\/p><label class=\"rear-choice\">Rear design <select id=\"rear-design\"><option value=\"logo\">Mini-Talks logo<\/option><option value=\"name\">Your Name<\/option><option value=\"discs\">Four Studs<\/option><option value=\"plain\">Plain<\/option><\/select><\/label><p class=\"model-hint\">Drag to turn the figure \u00b7 Use the side grips to remove the real module.<\/p><\/aside><\/div><\/section>\n<section class=\"ft-wrap ft-section chapter chapter-box\" id=\"profile-sync\"><div class=\"section-intro\"><p class=\"ft-eyebrow\">09 \/ PROFILE &amp; SYNC<\/p><h2>From figure to your profile.<\/h2><p>Take out the Fig-Module, connect it to your laptop with USB-C, then open your Mini-Talks profile.<\/p><\/div><div class=\"profile-scene-actions\"><button data-sync-step=\"1\">1 \u00b7 Take out Fig-Module<\/button><button data-sync-step=\"2\">2 \u00b7 Connect USB-C<\/button><button data-sync-step=\"0\">3 \u00b7 Start again<\/button><\/div><div class=\"profile-scene-card\"><div class=\"profile-visual\"><div id=\"profile-scene\" class=\"model-stage\" aria-label=\"Fig-Talks, removable Fig-Module, USB-C cable and laptop\"><\/div><\/div><div class=\"profile-guide\"><p id=\"profile-scene-status\" role=\"status\">The Fig-Module is inside your figure.<\/p><div><h3>Charge. Connect. Keep your voice.<\/h3><\/div><div><p class=\"profile-path\">My Kits \u2192 Fig-Talks \u2192 Connect \/ Manage<\/p><a class=\"ft-button profile-link\" href=\"https:\/\/mini-talks.org\/da\/mini-community\/mini-forum\/?view=profile#kits\" target=\"_blank\" rel=\"noopener\">Open your Mini-Talks profile \u2192<\/a><p class=\"small-note\">Log in first to pair your kit and manage recordings.<\/p><\/div><\/div><\/div><\/section>\n  <\/div><\/div>\n<section class=\"ft-closing\" aria-labelledby=\"ft-join\">\n    <div class=\"ft-closing-inner ft-wrap\">\n      <div class=\"ft-closing-copy\"><p class=\"ft-eyebrow\">Fig-Talks \u00b7 Part of Mini-Kits<\/p><h2 id=\"ft-join\">A personal figure.<br><span>En stemme, der er v\u00e6rd at udforske.<\/span><\/h2><p>Interested in Fig-Talks? Connect with Mini-Community to discuss personalization, the project, and what may be possible for your family.<\/p><\/div>\n      <div class=\"ft-actions\"><a class=\"ft-button\" href=\"https:\/\/mini-talks.org\/da\/mini-community\/join-us\/\">Bliv medlem af minif\u00e6llesskabet <span aria-hidden=\"true\">\u2192<\/span><\/a><\/div>\n    <\/div>\n  <\/section>\n<\/main>\n<\/div>\n<script>\ndocument.querySelectorAll('.ft-page img[data-ft-src]').forEach(function(img){img.src=window.FT_MEDIA_BASE+img.getAttribute('data-ft-src');});\n<\/script>\n<script>\n\/* Joint poses affect the live assembly only, never the printable source files. *\/\nwindow.createAssemblyPose=function(host,canvas,redraw){\n const joints={\"Head\": {\"p\": [0, 0, 89.2587341], \"a\": [0, 0, 1]}, \"Left arm\": {\"p\": [36.5867034782122, -1.3964670017685421e-05, 61.397944763489704], \"a\": [-0.9840254344, 0.0, -0.178027931668]}, \"Left hand\": {\"p\": [65.49446383878654, -17.171420469978273, 10.332863753491097], \"a\": [0.2554265698825043, -0.6365436181183205, -0.7277152531250777], \"parent\": \"Left arm\"}, \"Left leg\": {\"p\": [25, 0, -34.12182236], \"a\": [1, 0, 0]}, \"Right arm\": {\"p\": [-36.5867034782122, -1.3964670017685421e-05, 61.397944763489704], \"a\": [-0.9840254344, -0.0, 0.178027931668]}, \"Right hand\": {\"p\": [-65.49446383878654, -17.171420469978273, 10.332863753491097], \"a\": [0.2554265698825043, 0.6365436181183205, 0.7277152531250777], \"parent\": \"Right arm\"}, \"Right leg\": {\"p\": [-25, 0, -34.12182236], \"a\": [1, 0, 0]}};\n const angles=Object.fromEntries(Object.keys(joints).map(k=>[k,0]));let active='',camera,visible=[],moved=false;\n const dot=(a,b)=>a.reduce((s,v,i)=>s+v*b[i],0),sub=(a,b)=>a.map((v,i)=>v-b[i]),cross=(a,b)=>[a[1]*b[2]-a[2]*b[1],a[2]*b[0]-a[0]*b[2],a[0]*b[1]-a[1]*b[0]];\n function rotate(v,a,t){const c=Math.cos(t),s=Math.sin(t),n=Math.hypot(...a);a=a.map(x=>x\/n);const q=cross(a,v),d=dot(a,v);return v.map((x,i)=>x*c+q[i]*s+a[i]*d*(1-c));}\n function transform(name,p,vector=false){const j=joints[name];if(!j)return p;let v=rotate(vector?p:sub(p,j.p),j.a,angles[name]*Math.PI\/180);if(!vector)v=v.map((x,i)=>x+j.p[i]);return j.parent?transform(j.parent,v,vector):v;}\n function matrix(name){const t=transform(name,[0,0,0]),cols=[[1,0,0],[0,1,0],[0,0,1]].map(v=>transform(name,v,true));return new Float32Array([...cols[0],0,...cols[1],0,...cols[2],0,...t,1]);}\n const bar=document.createElement('div');bar.className='assembly-pose-bar';bar.innerHTML='<label>Pose <select aria-label=\"Select movable part\"><option value=\"\">Select a part<\/option>'+Object.keys(joints).map(k=>`<option>${k}<\/option>`).join('')+'<\/select><\/label><label class=\"pose-angle\"><input aria-label=\"Joint angle\" type=\"range\" min=\"-180\" max=\"180\" value=\"0\"><output>0\u00b0<\/output><\/label><label><input type=\"checkbox\"> Move together<\/label><button type=\"button\">Reset pose<\/button>';host.append(bar);\n const select=bar.querySelector('select'),range=bar.querySelector('[type=range]'),out=bar.querySelector('output'),linked=bar.querySelector('[type=checkbox]');\n const gizmo=document.createElement('div');gizmo.className='assembly-pose-gizmo';gizmo.hidden=true;gizmo.innerHTML='<button type=\"button\" aria-label=\"Rotate selected part backward\">\u21b6<\/button><span><\/span><button type=\"button\" aria-label=\"Rotate selected part forward\">\u21b7<\/button>';host.append(gizmo);\n function choose(name){active=name;select.value=name;range.disabled=!name;linked.disabled=!\/^(Left|Right)\/.test(name);sync();redraw();}\n function sync(){range.value=angles[active]||0;out.textContent=(angles[active]||0)+'\u00b0';gizmo.querySelector('span').textContent=active+' \u00b7 '+out.textContent;host.dataset.posePart=active;host.dataset.poseAngles=JSON.stringify(angles);}\n function change(value){if(!active)return;angles[active]=Math.max(-180,Math.min(180,Math.round(value)));if(linked.checked){const pair=active.replace(\/^(Left|Right)\/,s=>s==='Left'?'Right':'Left');if(pair!==active)angles[pair]=angles[active];}sync();redraw();}\n select.onchange=()=>choose(select.value);range.oninput=()=>change(+range.value);bar.querySelector('button').onclick=()=>{Object.keys(angles).forEach(k=>angles[k]=0);sync();redraw();};\n [...gizmo.querySelectorAll('button')].forEach((b,i)=>{let start=null,initial=0,didDrag=false;b.onpointerdown=e=>{e.stopPropagation();b.setPointerCapture(e.pointerId);start=e.clientX;initial=angles[active];didDrag=false;};b.onpointermove=e=>{if(start===null)return;const delta=e.clientX-start;if(Math.abs(delta)>3)didDrag=true;if(didDrag)change(initial+delta);};b.onpointerup=e=>{e.stopPropagation();start=null;};b.onpointercancel=()=>{start=null;};b.onclick=()=>{if(!didDrag)change(angles[active]+(i?5:-5));didDrag=false;};});\n function project(p){const {center,r,u,k}=camera,q=sub(p,center),w=canvas.clientWidth,h=canvas.clientHeight;return [w\/2+dot(q,r)*k*h\/2,h\/2-dot(q,u)*k*h\/2];}\n function frame(c,gs){camera=c;visible=gs;for(const option of select.options)if(option.value)option.disabled=!gs.some(g=>g.name===option.value);gizmo.hidden=!active||!gs.some(g=>g.name===active);if(!gizmo.hidden){let p=joints[active].p;if(joints[active].parent)p=transform(joints[active].parent,p);const g=gs.find(g=>g.name===active);p=p.map((v,i)=>v+g.explode[i]*c.explosion);const xy=project(p);gizmo.style.left=Math.max(100,Math.min(canvas.clientWidth-100,xy[0]))+'px';gizmo.style.top=Math.max(100,Math.min(canvas.clientHeight-65,xy[1]))+'px';}}\n \/\/ Exact triangle hit testing: a torso surface occludes joints behind it.\n function pick(x,y){if(!camera)return;const {center,r,u,f,k,explosion}=camera,h=canvas.clientHeight;const q=center.map((v,i)=>v+r[i]*(x-canvas.clientWidth\/2)*2\/(k*h)+u[i]*(h\/2-y)*2\/(k*h));let best=-Infinity,hit='';\n for(const g of visible){const m=matrix(g.name),off=g.explode.map(v=>v*explosion);const world=(p)=>[0,1,2].map(i=>m[i]*p[0]+m[4+i]*p[1]+m[8+i]*p[2]+m[12+i]+off[i]);const view=g.cpu,idx=g.tri;const vertex=i=>world([0,1,2].map(a=>view.getFloat32(i*32+a*4,true)));for(let n=0;n<idx.length;n+=3){const a=vertex(idx[n]),b=vertex(idx[n+1]),c=vertex(idx[n+2]),e1=sub(b,a),e2=sub(c,a),p=cross(f,e2),det=dot(e1,p);if(Math.abs(det)<1e-9)continue;const t=sub(q,a),v=dot(t,p)\/det;if(v<0||v>1)continue;const z=cross(t,e1),w=dot(f,z)\/det;if(w<0||v+w>1)continue;const depth=dot(e2,z)\/det;if(depth>best){best=depth;hit=g.name;}}}choose(joints[hit]?hit:'');}\n let down=null;canvas.addEventListener('pointerdown',e=>{down=[e.clientX,e.clientY];moved=false;});canvas.addEventListener('pointermove',e=>{if(down&&Math.hypot(e.clientX-down[0],e.clientY-down[1])>4)moved=true;});canvas.addEventListener('pointerup',e=>{if(down&&!moved){const r=canvas.getBoundingClientRect();pick(e.clientX-r.left,e.clientY-r.top);}down=null;});canvas.addEventListener('pointercancel',()=>down=null);\n choose('');return {matrix,frame,selected:name=>name===active,transform,angles};\n};\n\n<\/script>\n<script>\n\/* Perf patch: binary .ftm models + lazy loading near viewport. *\/\nwindow.figUnpack=function(buf){const dv=new DataView(buf),hl=dv.getUint32(0,true),data=JSON.parse(new TextDecoder().decode(new Uint8Array(buf,4,hl))),base=(4+hl+3)&~3,cut=([o,n])=>new Uint8Array(buf.slice(base+o,base+o+n));for(const g of data.groups){g.vertices=cut(g.vertices);g.indices=cut(g.indices);}return data;};\nwindow.figNear=function(host){if(!('IntersectionObserver' in window))return Promise.resolve();return new Promise(ok=>{const io=new IntersectionObserver(es=>{if(es.some(e=>e.isIntersecting)){io.disconnect();ok();}},{rootMargin:'600px 0px'});io.observe(host);});};\n\/* Fig-Talks mechanical assembly: source geometry in a shared millimetre frame. *\/\nwindow.createFigAssembly=function(host){\n const unfocus=document.createElement('button');unfocus.className='assembly-unfocus';unfocus.type='button';unfocus.textContent='\u2190 Show whole device';unfocus.hidden=true;host.append(unfocus);\n const canvas=document.createElement('canvas');canvas.tabIndex=0;canvas.setAttribute('aria-label','Fig-Talks assembled body. Drag to rotate, scroll to zoom.');host.append(canvas);host.classList.add('real-assembly');\n const gl=canvas.getContext('webgl',{alpha:false,antialias:true,preserveDrawingBuffer:true});if(!gl||!gl.getExtension('OES_element_index_uint')){host.textContent='3D assembly requires WebGL.';return null;}\n const vs=`precision highp float;attribute vec3 p,n,c;attribute vec2 uv;varying vec2 texUV;uniform float reverseDevice;uniform mat4 pose;uniform vec3 center,right,up,forward,offset;uniform vec2 scale;varying vec3 normal,color;void main(){vec3 pp=p;vec3 nn=n;if(abs(reverseDevice)>.001){float co=cos(reverseDevice),si=sin(reverseDevice);vec2 t=p.xy-vec2(0.,-8.125);pp.xy=vec2(co*t.x-si*t.y,si*t.x+co*t.y)+vec2(0.,-8.125);nn.xy=vec2(co*n.x-si*n.y,si*n.x+co*n.y);}vec3 q=(pose*vec4(pp,1.)).xyz+offset-center;gl_Position=vec4(dot(q,right)*scale.x,dot(q,up)*scale.y,-dot(q,forward)\/250.,1.);normal=mat3(pose)*nn;color=c;texUV=uv;}`;\n const fs=`precision highp float;varying vec3 normal,color;varying vec2 texUV;uniform sampler2D textureMap;uniform bool textured;uniform vec3 forward;uniform float alpha,highlight;uniform vec3 lamp;uniform float edge;uniform vec2 lensCenter;uniform float lensRadius;void main(){vec3 n=normalize(normal);if(dot(n,forward)<0.)n=-n;vec3 l=normalize(${host.id==='personal-view'?'forward*.9+vec3(0.,-.55,.85)':'vec3(-1.,-1.4,1.8)'});float d=max(0.,dot(n,l));float sp=.12*pow(max(0.,dot(n,normalize(l+forward))),45.);vec4 tx=texture2D(textureMap,texUV);if(textured&&tx.a<.1)discard;vec3 b=pow(textured?tx.rgb:color,vec3(2.2));vec3 rgb=pow(clamp(b*(.43+.58*d)+sp,0.,1.),vec3(1.\/2.2));float a=alpha;if(lensRadius>0. && distance(gl_FragCoord.xy,lensCenter)<lensRadius)a=min(a,.1);rgb*=1.-edge*.4;if(length(lamp)>0.){rgb=lamp;a=1.;}gl_FragColor=vec4(mix(rgb,vec3(1.,.65,.08),highlight*.3),a);}`;\n const program=gl.createProgram();for(const [type,src] of [[gl.VERTEX_SHADER,vs],[gl.FRAGMENT_SHADER,fs]]){const sh=gl.createShader(type);gl.shaderSource(sh,src);gl.compileShader(sh);if(!gl.getShaderParameter(sh,gl.COMPILE_STATUS))throw Error(gl.getShaderInfoLog(sh));gl.attachShader(program,sh);}gl.linkProgram(program);if(!gl.getProgramParameter(program,gl.LINK_STATUS))throw Error(gl.getProgramInfoLog(program));gl.useProgram(program);gl.enable(gl.DEPTH_TEST);gl.depthFunc(gl.LEQUAL);gl.enable(gl.BLEND);gl.blendFunc(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA);gl.clearColor(.978,.982,.987,1);\n const names=['edge','lamp','reverseDevice','textureMap','textured','pose','center','right','up','forward','offset','scale','alpha','highlight','lensCenter','lensRadius'];const U=Object.fromEntries(names.map(n=>[n,gl.getUniformLocation(program,n)]));const attrs=['p','n','c','uv'].map(n=>gl.getAttribLocation(program,n));let withdrawal=0,turnAngle=0,moduleTranslation=[0,0,0];let reversed=false,decoration=\"logo\",customName=\"\";let groups=[],model,az=-1.08,el=.22,zoom=1,spin=false,selected=new Set(),transparent=false,explosion=0,mode='Assembly',wires=false,focus=null,locationFocus=null,lens=false,lensXY=[-1000,-1000],drag=new Map(),pinch=0;\n let lamps={},activation=null,frame=null,frameListener=null;const texMap={};const whiteTex=gl.createTexture();gl.bindTexture(gl.TEXTURE_2D,whiteTex);gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,1,1,0,gl.RGBA,gl.UNSIGNED_BYTE,new Uint8Array([255,255,255,255]));gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);gl.uniform1i(U.textureMap,0);\n const identity=new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);\n const pose=(host.id==='figure-view'&&window.createAssemblyPose)?window.createAssemblyPose(host,canvas,draw):null;\n const decode=s=>s instanceof Uint8Array?s:Uint8Array.from(atob(s),x=>x.charCodeAt(0));\n const nameCanvas=document.createElement('canvas');nameCanvas.width=1024;nameCanvas.height=1024;\n const nameTexture=gl.createTexture();texMap['custom-name']=nameTexture;\n function updateNameTexture(){const ctx=nameCanvas.getContext('2d');ctx.clearRect(0,0,1024,1024);if(customName){ctx.strokeStyle='#681d1b';ctx.lineWidth=11;ctx.beginPath();ctx.roundRect(55,55,914,914,60);ctx.stroke();const face='italic 900 ';const family='\"Arial Rounded MT Bold\", ui-rounded, \"Trebuchet MS\", sans-serif';const targetWidth=838;let low=24,high=760;for(let i=0;i<18;i++){const size=(low+high)\/2;ctx.font=face+size+'px '+family;if(ctx.measureText(customName).width<targetWidth)low=size;else high=size;}const size=low;ctx.font=face+size+'px '+family;const width=ctx.measureText(customName).width;ctx.fillStyle='#681d1b';ctx.strokeStyle='#681d1b';ctx.lineJoin='round';ctx.lineWidth=Math.max(3,size*.025);ctx.textAlign='center';ctx.textBaseline='middle';ctx.save();ctx.translate(512,515);ctx.rotate(Math.PI);ctx.scale(targetWidth\/Math.max(width,1),1);ctx.strokeText(customName,0,0);ctx.fillText(customName,0,0);ctx.restore();}gl.bindTexture(gl.TEXTURE_2D,nameTexture);gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,true);gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE,nameCanvas);gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,false);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE);}\n function addNameGroup(){const raw=new ArrayBuffer(4*32),dv=new DataView(raw),verts=[[-30,12.15,6,0,1],[30,12.15,6,1,1],[30,12.15,67,1,0],[-30,12.15,67,0,0]];verts.forEach((v,j)=>{const k=j*32;for(let a=0;a<3;a++)dv.setFloat32(k+4*a,v[a],true);dv.setInt16(k+12,0,true);dv.setInt16(k+14,32767,true);dv.setInt16(k+16,0,true);dv.setUint8(k+18,255);dv.setUint8(k+19,255);dv.setUint8(k+20,255);dv.setFloat32(k+24,v[3],true);dv.setFloat32(k+28,v[4],true);});const tri=new Uint32Array([0,1,2,0,2,3]),v=gl.createBuffer(),i=gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER,v);gl.bufferData(gl.ARRAY_BUFFER,new Uint8Array(raw),gl.STATIC_DRAW);gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,i);gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,tri,gl.STATIC_DRAW);groups.push({id:'fig-talks-rear-name-text',name:'Custom rear name',category:'printed',device:true,explode:[0,-39,0],texture:'custom-name',v,i,cpu:dv,tri,count:6,bounds:[[-30,12.15,6],[30,12.15,67]]});}\n updateNameTexture();\n const shells=new Set(['fig-talks-torso','fig-talks-front-enclosure','fig-talks-rear-enclosure','fig-talks-button-panel','fig-talks-battery-panel']);\n \/\/ Assembly illustration offsets; physical model coordinates remain unchanged.\n const layerDepth={'fig-talks-cap-blue':-85,'fig-talks-cap-green':-85,'fig-talks-cap-yellow':-85,'fig-talks-light-guides':-85,'fig-talks-front-enclosure':-60,'speaker':-32,'mini-talks-microphone':-32,'fig-talks-button':-12,'fig-talks-button-panel':10,'mini-core':40,'fig-talks-battery-panel':40,'lipo-battery':65,'fig-talks-rear-enclosure':95};\n function offsetFor(g){\n const buildView=host.id==='build-view',completeFigure=buildView&&selected.has('fig-talks-torso');\n let v=buildView?[0,layerDepth[g.id]||0,0]:(g.explode||[0,0,0]);\n \/\/ Keep the exploded figure behind every device layer; retain each limb's own separation.\n if(completeFigure&&!g.device&&g.category!=='wire'){v=[...(g.explode||[0,0,0])];v[1]+=220;}\n return v.map((x,i)=>x*explosion-(g.device&&i===1?withdrawal:0)+(g.device?moduleTranslation[i]:0));\n }\n function isVisible(g){if(g.id==='fig-talks-rear-name-text')return decoration==='name'&&!!customName&&selected.has('fig-talks-rear-enclosure')&&mode!=='Wires';if(g.variant){const customRear=decoration==='name'&&!!customName&&g.id==='fig-talks-rear-enclosure';if(g.variant!==(customRear?'plain':decoration))return false;}if(mode==='Wires')return g.category==='wire'||(g.category==='electronics'&&selected.has(g.id));if(g.category==='wire')return wires&&explosion===0&&mode!=='Enclosure'&&selected.has('mini-core')&&selected.has({'wire-button':'fig-talks-button','wire-mic':'mini-talks-microphone','wire-speaker':'speaker','wire-battery':'lipo-battery'}[g.id]);return selected.has(g.id)&&(mode!=='Electronics'||g.category==='electronics')&&(mode!=='Enclosure'||g.category!=='electronics');}\n function isFaded(g){if(locationFocus)return !locationFocus.has(g.id);return focus?(host.id.startsWith('circuit-')&&g.category==='wire'&&(focus==='mini-core'||g.id===({'speaker':'wire-speaker','lipo-battery':'wire-battery','mini-talks-microphone':'wire-mic','fig-talks-button':'wire-button'}[focus]))?false:g.id!==focus):(mode==='Wires'&&g.category==='electronics'||(transparent||mode==='Wiring')&&shells.has(g.id));}\n function draw(){if(!model)return;const d=(host.id.startsWith('circuit-')||host.id==='personal-view')?Math.min(4,Math.max(2,devicePixelRatio||1),Math.sqrt(16000000\/Math.max(1,canvas.clientWidth*canvas.clientHeight))):Math.min(devicePixelRatio||1,2),w=Math.max(1,Math.round(canvas.clientWidth*d)),h=Math.max(1,Math.round(canvas.clientHeight*d));if(canvas.width!==w||canvas.height!==h){canvas.width=w;canvas.height=h;}gl.viewport(0,0,w,h);gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);gl.useProgram(program);const f=[Math.cos(el)*Math.cos(az),Math.cos(el)*Math.sin(az),Math.sin(el)],r=[-Math.sin(az),Math.cos(az),0],u=[-Math.sin(el)*Math.cos(az),-Math.sin(el)*Math.sin(az),Math.cos(el)];const visibleForBounds=host.id==='personal-view'?groups.filter(g=>g.id!=='hair-one'):(mode==='Electronics'||mode==='Demo'||host.id==='build-view')?groups.filter(isVisible):[];const layerView=host.id==='build-view';const viewBounds=visibleForBounds.length?[0,1,2].map(i=>[Math.min(...visibleForBounds.map(g=>g.bounds[0][i]+(layerView?offsetFor(g)[i]:0))),Math.max(...visibleForBounds.map(g=>g.bounds[1][i]+(layerView?offsetFor(g)[i]:0)))]):null;const span=(viewBounds?viewBounds.map(b=>b[1]-b[0]):model.size).map((x,i)=>x+(layerView?0:explosion*[0,110,0][i]+(i===1?withdrawal:0)));const projectedW=span.reduce((a,x,i)=>a+x*Math.abs(r[i]),0),projectedH=span.reduce((a,x,i)=>a+x*Math.abs(u[i]),0);let center=(viewBounds?viewBounds.map(b=>(b[0]+b[1])\/2):model.center).map((x,i)=>x+(!layerView&&i===1?20*explosion-withdrawal\/2:0)),k=Math.min(1.7\/projectedH,1.7*(w\/h)\/projectedW)*zoom;\n if(focus){const found=groups.filter(g=>g.id===focus);if(found.length){const lo=[0,1,2].map(i=>Math.min(...found.map(g=>g.bounds[0][i]))),hi=[0,1,2].map(i=>Math.max(...found.map(g=>g.bounds[1][i])));center=lo.map((v,i)=>(v+hi[i])\/2);const size=lo.map((v,i)=>hi[i]-v),fw=size.reduce((a,x,i)=>a+x*Math.abs(r[i]),0),fh=size.reduce((a,x,i)=>a+x*Math.abs(u[i]),0);k=Math.min(1.35\/Math.max(fh,60),1.35*(w\/h)\/Math.max(fw,60))*zoom;}}\n host.dataset.focusedPart=focus||'';host.dataset.cameraScale=String(k);host.dataset.cameraAzimuth=String(az);host.dataset.explosion=String(explosion);host.querySelector('.assembly-unfocus').hidden=!focus;\n gl.uniform3fv(U.center,center);gl.uniform3fv(U.right,r);gl.uniform3fv(U.up,u);gl.uniform3fv(U.forward,f);gl.uniform2f(U.scale,k\/(w\/h),k);gl.uniform2f(U.lensCenter,lensXY[0]*d,h-lensXY[1]*d);\n frame={center,r,u,k,aspect:w\/h};host.dataset.ready='true';const visible=groups.filter(isVisible);host.dataset.visibleParts=String(visible.length);host.dataset.view=mode;visible.sort((a,b)=>Number(isFaded(a)||a.id==='fig-talks-light-guides')-Number(isFaded(b)||b.id==='fig-talks-light-guides'));\n if(pose)pose.frame({center,r,u,f,k,explosion},visible);\n for(const g of visible){gl.uniform1f(U.edge,0);gl.uniform3fv(U.lamp,lamps[g.name]||[0,0,0]);gl.uniform1f(U.reverseDevice,g.device?turnAngle:0);gl.uniformMatrix4fv(U.pose,false,pose?pose.matrix(g.name):identity);const faded=isFaded(g);gl.depthMask(!faded&&g.id!=='fig-talks-light-guides');gl.uniform1f(U.alpha,faded?.16:g.id==='fig-talks-light-guides'?.5:1);gl.uniform1f(U.highlight,host.id!=='circuit-view'&&(g.id===focus||pose?.selected(g.name))?1:0);gl.uniform1f(U.lensRadius,lens&&shells.has(g.id)?85*d:0);gl.uniform3fv(U.offset,offsetFor(g));gl.bindBuffer(gl.ARRAY_BUFFER,g.v);for(const [j,size,type,norm,off] of [[0,3,gl.FLOAT,false,0],[1,3,gl.SHORT,true,12],[2,3,gl.UNSIGNED_BYTE,true,18],[3,2,gl.FLOAT,false,24]]){gl.enableVertexAttribArray(attrs[j]);gl.vertexAttribPointer(attrs[j],size,type,norm,32,off);}gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,g.i);if(g.texture){gl.enable(gl.POLYGON_OFFSET_FILL);gl.polygonOffset(-1,-2);}else{gl.disable(gl.POLYGON_OFFSET_FILL);}gl.uniform1i(U.textured,!!g.texture);gl.bindTexture(gl.TEXTURE_2D,texMap[g.texture]||whiteTex);gl.drawElements(gl.TRIANGLES,g.count,gl.UNSIGNED_INT,0);if(g.edges){gl.uniform1f(U.edge,1);gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,g.edges);gl.drawElements(gl.LINES,g.edgeCount,gl.UNSIGNED_INT,0);}}gl.depthMask(true);if(frameListener)frameListener();\n }\n const modelURL=host.dataset.modelScript||'models\/fig-talks-current.ftm';window.figModelPromises=window.figModelPromises||{};\n const ready=window.figNear(host).then(()=>window.figModelPromises[modelURL] ||= fetch(new URL(modelURL,window.FT_BASE)).then(r=>{if(!r.ok)throw Error('Model unavailable');return new Response(r.body.pipeThrough(new DecompressionStream('gzip'))).arrayBuffer();}).then(window.figUnpack)).then(async data=>{await Promise.all(Object.entries(data.textures||{}).map(async([key,src])=>{const im=await new Promise((ok,no)=>{const i=new Image();i.onload=()=>ok(i);i.onerror=no;i.src=new URL(src,window.FT_BASE).href});const t=gl.createTexture();gl.bindTexture(gl.TEXTURE_2D,t);gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE,im);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE);texMap[key]=t;}));model=data;groups=data.groups.map(g=>{const b=decode(g.vertices),v=gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER,v);gl.bufferData(gl.ARRAY_BUFFER,b,gl.STATIC_DRAW);const i=gl.createBuffer();gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,i);gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,decode(g.indices),gl.STATIC_DRAW);const dv=new DataView(b.buffer),lo=[Infinity,Infinity,Infinity],hi=[-Infinity,-Infinity,-Infinity];for(let j=0;j<b.length;j+=32)for(let a=0;a<3;a++){const x=dv.getFloat32(j+a*4,true);lo[a]=Math.min(lo[a],x);hi[a]=Math.max(hi[a],x);}return {...g,v,i,cpu:dv,tri:new Uint32Array(decode(g.indices).buffer),bounds:[lo,hi]};});addNameGroup();for(const g of groups.filter(g=>g.id.startsWith('fig-talks-cap-'))){const edges=new Map(),point=i=>[0,1,2].map(k=>g.cpu.getFloat32(i*32+k*4,true)),key=p=>p.map(v=>v.toFixed(4)).join(',');for(let j=0;j<g.tri.length;j+=3){const ids=[g.tri[j],g.tri[j+1],g.tri[j+2]],p=ids.map(point),a=p[1].map((v,i)=>v-p[0][i]),b=p[2].map((v,i)=>v-p[0][i]),n=[a[1]*b[2]-a[2]*b[1],a[2]*b[0]-a[0]*b[2],a[0]*b[1]-a[1]*b[0]],len=Math.hypot(...n);if(len<1e-8)continue;const normal=n.map(v=>v\/len);for(const [u,v] of [[0,1],[1,2],[2,0]]){const k=[key(p[u]),key(p[v])].sort().join('|');if(!edges.has(k))edges.set(k,{ids:[ids[u],ids[v]],normals:[]});edges.get(k).normals.push(normal);}}const lines=[];for(const e of edges.values())if(e.normals.length===1||e.normals.some(n=>n.reduce((v,x,i)=>v+x*e.normals[0][i],0)<.8))lines.push(...e.ids);g.edges=gl.createBuffer();gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,g.edges);gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,new Uint32Array(lines),gl.STATIC_DRAW);g.edgeCount=lines.length;}draw();return true;}).catch(e=>{host.textContent=e.message;throw e;});\n const presets={Connection:[-1.4,.26],'Back angle':[1.08,.22],Angled:[-1.08,.22],'Hip angled':[-1.08,.22],Top:[-Math.PI\/2,Math.PI\/2],Bottom:[Math.PI\/2,-Math.PI\/2],'Bottom angle':[-1.08,-.5],Front:[-Math.PI\/2,0],Back:[Math.PI\/2,0],Left:[Math.PI,0],Right:[0,0]};\n const api={ready,onFrame(fn){frameListener=fn;draw();},projectPoint(point){if(!frame)return null;const q=point.map((v,i)=>v-frame.center[i]);return {x:(1+q.reduce((v,n,i)=>v+n*frame.r[i],0)*frame.k\/frame.aspect)*canvas.clientWidth\/2,y:(1-q.reduce((v,n,i)=>v+n*frame.u[i],0)*frame.k)*canvas.clientHeight\/2,front:Math.sin(az)<-.15};},lights(value){lamps=value;draw();},onActivate(fn){activation=fn;},orientation(value){reversed=!!value;turnAngle=reversed?Math.PI:0;draw();},moduleOffset(value){moduleTranslation=value;draw();},modulePosition(distance,angle){withdrawal=distance;turnAngle=angle;draw();},decoration(value){decoration=value;draw();},name(value){customName=String(value||'').trim().slice(0,24);updateNameTexture();draw();},update(s){if(focus&&(!s.selected.has(focus)||s.view!==mode)){focus=null;zoom=1;}selected=new Set(s.selected);transparent=s.transparent;explosion=s.exploded?1:(s.explosion||0);mode=s.view;wires=!!s.wires;draw();},preset(name){[az,el]=presets[name]||presets.Angled;focus=null;zoom=1;spin=false;draw();},control(action){if(action==='plus')zoom=Math.min(mode==='Wires'?6:host.id.startsWith('circuit-')?8:4,zoom*1.18);if(action==='minus')zoom=Math.max(.4,zoom\/1.18);if(action==='reset'){api.preset('Angled');}if(action==='rotate')spin=!spin;if(action==='save'){draw();const a=document.createElement('a');a.download='fig-talks-assembly.png';a.href=canvas.toDataURL('image\/png');a.click();}draw();return spin;},explode(value){focus=null;zoom=1;spin=false;if(host.id==='build-view'&&selected.has('fig-talks-torso')&&value>0&&explosion===0&&Math.abs(az+1.08)<.01){az=-.65;el=.22;}if(host.id==='build-view'&&value>0&&explosion===0&&Math.abs(Math.cos(az))<.2){az=Math.sin(az)>0?.65:-.65;el=.25;}explosion=Math.max(0,Math.min(1,value));draw();},focus(id){focus=(!model||groups.some(g=>g.id===id))?id:null;zoom=1;spin=false;explosion=0;draw();},locate(ids){locationFocus=ids?new Set(ids):null;focus=null;zoom=1;draw();},lens(on){lens=on;draw();},get state(){return {ready:!!model,groups:groups.length,visible:groups.filter(isVisible).map(g=>g.name),az,el,zoom,explosion,focus,spin};}};\n let tap=null;canvas.onpointerdown=e=>{tap=[e.clientX,e.clientY];spin=false;canvas.setPointerCapture(e.pointerId);drag.set(e.pointerId,[e.clientX,e.clientY]);pinch=0;};canvas.onpointermove=e=>{const rect=canvas.getBoundingClientRect();lensXY=[e.clientX-rect.left,e.clientY-rect.top];if(drag.has(e.pointerId)){const old=drag.get(e.pointerId);drag.set(e.pointerId,[e.clientX,e.clientY]);if(drag.size===2){const p=[...drag.values()],d=Math.hypot(p[0][0]-p[1][0],p[0][1]-p[1][1]);if(pinch)zoom=Math.max(.4,Math.min(4,zoom*d\/pinch));pinch=d;}else{az-=(e.clientX-old[0])*.008;el=Math.max(-Math.PI\/2,Math.min(Math.PI\/2,el+(e.clientY-old[1])*.008));}}draw();};canvas.addEventListener('pointerup',e=>{if(!activation||!frame||Math.sin(az)>-.1||!tap||Math.hypot(e.clientX-tap[0],e.clientY-tap[1])>6)return;const rect=canvas.getBoundingClientRect(),f=frame;for(const g of groups.filter(g=>isVisible(g)&&g.id.startsWith('fig-talks-cap-'))){const pts=[];for(let x=0;x<2;x++)for(let y=0;y<2;y++)for(let z=0;z<2;z++){const q=[g.bounds[x][0]-f.center[0],g.bounds[y][1]-f.center[1],g.bounds[z][2]-f.center[2]];pts.push([(1+q.reduce((v,n,i)=>v+n*f.r[i],0)*f.k\/f.aspect)*rect.width\/2,(1-q.reduce((v,n,i)=>v+n*f.u[i],0)*f.k)*rect.height\/2]);}const px=e.clientX-rect.left,py=e.clientY-rect.top;if(px>=Math.min(...pts.map(p=>p[0]))&&px<=Math.max(...pts.map(p=>p[0]))&&py>=Math.min(...pts.map(p=>p[1]))&&py<=Math.max(...pts.map(p=>p[1]))){activation(g.id);break;}}});for(const type of ['pointerup','pointercancel','lostpointercapture'])canvas.addEventListener(type,e=>{drag.delete(e.pointerId);pinch=0;});canvas.onwheel=e=>{if(mode==='Demo')return;e.preventDefault();zoom=Math.max(.4,Math.min(4,zoom*Math.exp(-e.deltaY*.001)));draw();};canvas.onkeydown=e=>{if(e.key.startsWith('Arrow')){e.preventDefault();if(e.key==='ArrowLeft')az-=.1;if(e.key==='ArrowRight')az+=.1;if(e.key==='ArrowUp')el=Math.min(Math.PI\/2,el+.1);if(e.key==='ArrowDown')el=Math.max(-Math.PI\/2,el-.1);draw();}if(e.key==='Home'||e.key==='Escape')api.preset('Angled');};\n unfocus.onclick=()=>api.preset('Angled');new ResizeObserver(draw).observe(host);let time=0;function tick(t){if(spin&&!document.hidden){az+=Math.min(t-time,50)*.00025;draw();}time=t;requestAnimationFrame(tick);}requestAnimationFrame(tick);window.FigAssembly=api;return api;\n};\n\n<\/script>\n<script>\n\/* Local microphone demo: audio stays in this browser and is never uploaded. *\/\nwindow.createFigTalksAudio=function(env,onChange){\n let powered=false,phase='off',url=null,recorder=null,stream=null,player=null,generation=0,disposed=false,context=null,decoded=null;\n const release=()=>{if(stream){stream.getTracks().forEach(t=>t.stop());stream=null;}};\n const emit=message=>{if(!disposed)onChange({powered,phase,hasClip:!!url,message});};\n \/\/ Wake the audio device on the power gesture, before the user reaches PLAY.\n function warmAudio(){if(!env.AudioContext)return;try{if(!context)context=new env.AudioContext({latencyHint:'interactive'});if(context.state!=='running')context.resume().catch(()=>{});}catch{\/* Recording still reports unsupported devices normally. *\/}}\n const stopPlayback=()=>{if(player){player.onended=null;player.onerror=null;if(player.stop)player.stop();else player.pause();player=null;}};\n function power(){generation++;if(powered){powered=false;phase='off';stopPlayback();if(recorder&&recorder.state!=='inactive')recorder.stop();recorder=null;release();emit('Device off. Press ON\/OFF to begin.');}else{powered=true;warmAudio();phase='idle';emit(url?'Device on. Play your recording or record a new one.':'Device on. Press RECORD and allow microphone access.');}}\n async function record(){\n  if(!powered||['permission','saving','starting','playing'].includes(phase))return;\n  if(phase==='recording'){phase='saving';emit('Saving your recording\u2026');recorder.stop();return;}\n  warmAudio();\n  const ticket=++generation;phase='permission';emit('Allow microphone access to start recording.');\n  try{\n   if(!env.getUserMedia||!env.MediaRecorder)throw Error('unsupported');\n   const acquired=await env.getUserMedia({audio:true});\n   if(disposed||ticket!==generation||!powered){acquired.getTracks().forEach(t=>t.stop());return;}\n   stream=acquired;const current=new env.MediaRecorder(stream),chunks=[];recorder=current;\n   current.ondataavailable=e=>{if(e.data.size)chunks.push(e.data);};\n   current.onerror=()=>{if(ticket!==generation)return;generation++;release();recorder=null;phase='idle';emit('Recording failed. Press RECORD to try again.');};\n   current.onstop=async()=>{\n    if(ticket!==generation||disposed)return;\n    release();recorder=null;\n    if(chunks.length){const blob=new env.Blob(chunks,{type:current.mimeType||chunks[0].type});phase='saving';emit('Preparing your recording\u2026');let buffer=null;\n     if(context){try{buffer=await context.decodeAudioData(await blob.arrayBuffer());}catch{if(ticket===generation){phase=url?'ready':'idle';emit('This recording could not be prepared. Press RECORD to try again.');}return;}}\n     if(ticket!==generation||disposed)return;if(url)env.revokeURL(url);url=env.createURL(blob);decoded=buffer;phase='ready';emit('Recording saved. Press PLAY to listen.');}\n    else{phase=url?'ready':'idle';emit('No audio was captured. Press RECORD to try again.');}\n   };\n   stream.getTracks().forEach(t=>{t.onended=()=>{if(ticket===generation&&current.state==='recording'){phase='saving';emit('Microphone stopped. Saving your recording\u2026');current.stop();}};});\n   current.start();phase='recording';emit('Speak now. Press RECORD again to save.');\n  }catch(error){if(ticket!==generation||disposed)return;release();recorder=null;phase=url?'ready':'idle';emit(error.name==='NotAllowedError'?'Microphone access was denied. Allow it in your browser, then press RECORD again.':error.name==='NotFoundError'?'No microphone found. Connect one and try again.':error.message==='unsupported'?'Audio recording is not supported in this browser. Open this page in a browser with microphone recording support.':'Microphone unavailable. Check that it is connected and try again.');}\n }\n async function play(){\n  if(!powered||!url||!['ready','idle'].includes(phase))return;\n  const ticket=generation;\n  if(context&&decoded){phase='starting';try{if(context.state!=='running')await context.resume();if(ticket!==generation||disposed||!powered)return;const source=context.createBufferSource();source.buffer=decoded;source.connect(context.destination);source.onended=()=>{if(player!==source||ticket!==generation)return;player=null;source.disconnect();phase='ready';emit('Playback finished. Press PLAY to listen again.');};player=source;source.start();phase='playing';emit('Playing your recording\u2026');}catch{if(ticket===generation&&!disposed){stopPlayback();phase='ready';emit('Playback could not start. Press PLAY to try again.');}}return;}\n  const audio=new env.Audio(url);audio.preload='auto';player=audio;phase='starting';\n  const done=message=>{if(player!==audio||ticket!==generation)return;stopPlayback();phase='ready';emit(message);};\n  audio.onended=()=>done('Playback finished. Press PLAY to listen again.');audio.onerror=()=>done('Playback failed. Try recording again.');\n  try{await audio.play();if(player===audio&&ticket===generation){phase='playing';emit('Playing your recording\u2026');}}catch{done('Playback could not start. Press PLAY to try again.');}\n }\n function dispose(){disposed=true;generation++;stopPlayback();if(recorder&&recorder.state!=='inactive')recorder.stop();release();if(url)env.revokeURL(url);url=null;decoded=null;if(context)context.close().catch(()=>{});}\n emit('Press ON\/OFF to begin.');return {power,record,play,dispose};\n};\nwindow.mountFigTalksDemo=function(root){\n root.id='try-device';root.querySelector('.try-device-content').innerHTML=`<div class=\"ft-demo\"><div class=\"ft-demo-views\" role=\"group\" aria-label=\"Demo view\"><button data-demo-view=\"figure\" aria-pressed=\"true\">Fig-Talks<\/button><button data-demo-view=\"module\" aria-pressed=\"false\">Fig-Module<\/button><\/div><div class=\"ft-demo-model\" aria-label=\"Current Fig-Talks device\"><\/div><div class=\"ft-demo-controls\"><div><button data-demo=\"power\">ON\/OFF<\/button><span class=\"ft-lamp\" data-lamp=\"power\" role=\"img\" aria-label=\"Power light off\"><\/span><\/div><div><button data-demo=\"record\" disabled>RECORD<\/button><span class=\"ft-lamp\" data-lamp=\"record\" role=\"img\" aria-label=\"Recording light off\"><\/span><\/div><div><button data-demo=\"play\" disabled>PLAY<\/button><span class=\"ft-lamp\" data-lamp=\"play\" role=\"img\" aria-label=\"Playback light off\"><\/span><\/div><\/div><p class=\"ft-demo-status\" role=\"status\" aria-live=\"polite\"><\/p><\/div><aside class=\"try-device-scenario\"><h3>Try your Fig-Talks<\/h3><ol><li>Press ON\/OFF. The power light turns on.<\/li><li>Press RECORD and allow microphone access.<\/li><li>Speak while the recording light is on.<\/li><li>Press RECORD again to save. Its light turns off.<\/li><li>Press PLAY. Its light stays on until the recording ends.<\/li><\/ol><p>Your recording stays in this browser. Nothing is uploaded. Reloading the page clears it.<\/p><button class=\"ft-demo-front\">Front view<\/button><\/aside>`;\n const style=document.createElement('style');style.textContent='#ftw .ft-demo{min-width:0;flex:1}#ftw .ft-demo-views{display:flex;justify-content:center;gap:8px;margin-bottom:14px}#ftw .ft-demo-views button{flex:1;max-width:220px}#ftw .ft-demo-model{height:490px;position:relative;overflow:hidden;border-radius:16px;background:#fafbfc}#ftw .ft-demo-model canvas{width:100%;height:100%;display:block;touch-action:none}#ftw .ft-demo-model .assembly-unfocus{display:none}#ftw .ft-demo-controls{display:flex;justify-content:center;gap:22px;padding:18px 8px}#ftw .ft-demo-controls>div{display:flex;flex-direction:column;align-items:center;gap:10px}#ftw .ft-demo-controls button,#ftw .ft-demo-front{padding:12px 18px;border-radius:9px;border:1px solid #d2d8df;font-weight:800;cursor:pointer}#ftw .ft-demo-controls button:disabled{opacity:.45;cursor:default}#ftw [data-demo=power]{background:#205db6;color:white}#ftw [data-demo=record]{background:#21834b;color:white}#ftw [data-demo=play]{background:#f0c629;color:#252c31}#ftw .ft-lamp{display:block;width:36px;height:8px;border-radius:6px;background:#c3c9ce}#ftw .ft-lamp[data-lamp=power][data-on=true]{background:#287bff;box-shadow:0 0 12px #287bff}#ftw .ft-lamp[data-lamp=record][data-on=true]{background:#30e15d;box-shadow:0 0 12px #30e15d}#ftw .ft-lamp[data-lamp=play][data-on=true]{background:#ffe12c;box-shadow:0 0 12px #ffe12c}#ftw .ft-demo-status{min-height:3em;text-align:center;font-weight:600;padding:0 16px}#ftw .ft-demo-model:focus-within{outline:2px solid #1769c0}@media(max-width:700px){#ftw .ft-demo-model{height:420px}#ftw .try-device-content:has(.ft-demo){display:flex;flex-direction:column}#ftw .ft-demo-controls{gap:12px}}';root.append(style);\n const host=root.querySelector('.ft-demo-model');host.dataset.modelScript='models\/fig-talks-finished.ftm';const viewer=createFigAssembly(host);let current=null;\n const waveLayer=document.createElement('div');waveLayer.className='ft-wave-layer';waveLayer.setAttribute('aria-hidden','true');waveLayer.innerHTML='<div class=\"ft-wave ft-wave-mic\" hidden><i><\/i><i><\/i><i><\/i><\/div><div class=\"ft-wave ft-wave-speaker\" hidden><i><\/i><i><\/i><i><\/i><\/div>';host.append(waveLayer);\n const waveStyle=document.createElement('style');waveStyle.textContent='#ftw .ft-wave-layer{position:absolute;inset:0;pointer-events:none;overflow:hidden}#ftw .ft-wave{position:absolute;width:0;height:0;color:#26333c}#ftw .ft-wave[hidden]{display:none}#ftw .ft-wave i{position:absolute;left:0;top:0;width:var(--wave-size);height:var(--wave-size);border:2px solid currentColor;border-radius:50%;transform:translate(-50%,-50%);animation:ft-sound-wave 1.6s ease-out infinite;box-shadow:none;background:none}#ftw .ft-wave i:nth-child(2){animation-delay:-.53s}#ftw .ft-wave i:nth-child(3){animation-delay:-1.06s}#ftw .ft-wave-mic{--wave-size:15px}#ftw .ft-wave-mic i{animation-name:ft-mic-inward}#ftw .ft-wave-speaker{--wave-size:70px}@keyframes ft-mic-inward{0%{transform:translate(-50%,-50%) scale(2.2);opacity:0}25%{opacity:.65}100%{transform:translate(-50%,-50%) scale(.15);opacity:0}}@keyframes ft-sound-wave{0%{transform:translate(-50%,-50%) scale(.8);opacity:.7}100%{transform:translate(-50%,-50%) scale(2.2);opacity:0}}@media(prefers-reduced-motion:reduce){#ftw .ft-wave i{animation:none;opacity:.5}#ftw .ft-wave i:nth-child(2){transform:translate(-50%,-50%) scale(1.4)}#ftw .ft-wave i:nth-child(3){transform:translate(-50%,-50%) scale(1.9)}}';root.append(waveStyle);\n function updateWaves(){for(const [key,point,phase] of [['mic',[23.6,-28.125,58.3],'recording'],['speaker',[0,-28.4,51.8],'playing']]){const el=waveLayer.querySelector('.ft-wave-'+key),p=viewer?.projectPoint(point);el.hidden=!p||!p.front||current?.phase!==phase;if(p){el.style.left=p.x+'px';el.style.top=p.y+'px';const edge=viewer.projectPoint([point[0]+(key==='mic'?2.5:14.5),point[1],point[2]]);el.style.setProperty('--wave-size',Math.max(10,Math.hypot(edge.x-p.x,edge.y-p.y)*2)+'px');}}}\n viewer?.onFrame(updateWaves);\n const lamps={power:'fig_talks_led_light_guide_01_v01',play:'fig_talks_led_light_guide_03_v01',record:'fig_talks_led_light_guide_02_v01'};\n function render(s){current=s;root.dataset.audioState=s.phase;root.querySelector('.ft-demo-status').textContent=s.message;const on={power:s.powered,play:s.phase==='playing',record:s.phase==='recording'};\n  for(const key of Object.keys(on)){const el=root.querySelector('[data-lamp='+key+']');el.dataset.on=String(on[key]);el.setAttribute('aria-label',key+' light '+(on[key]?'on':'off'));root.querySelector('[data-demo='+key+']').setAttribute('aria-pressed',String(on[key]));}\n  root.querySelector('[data-demo=record]').disabled=!s.powered||['permission','saving','starting','playing'].includes(s.phase);root.querySelector('[data-demo=record]').textContent=s.phase==='recording'?'RECORD \u00b7 Stop':'RECORD';root.querySelector('[data-demo=play]').disabled=!s.powered||!s.hasClip||!['ready','idle'].includes(s.phase);\n  updateWaves();viewer?.lights(Object.fromEntries(Object.entries(on).map(([key,value])=>[lamps[key],value?({power:[.08,.35,1],record:[.12,1,.25],play:[1,.85,.05]}[key]):[0,0,0]])));\n }\n const controller=createFigTalksAudio({getUserMedia:navigator.mediaDevices?.getUserMedia.bind(navigator.mediaDevices),MediaRecorder:window.MediaRecorder,AudioContext:window.AudioContext||window.webkitAudioContext,Audio:window.Audio,Blob:window.Blob,createURL:URL.createObjectURL.bind(URL),revokeURL:URL.revokeObjectURL.bind(URL)},render);\n for(const key of ['power','record','play'])root.querySelector('[data-demo='+key+']').onclick=()=>controller[key]();\n const moduleParts=['fig-talks-front-enclosure','fig-talks-rear-enclosure','fig-talks-battery-panel','fig-talks-button-panel','fig-talks-cap-blue','fig-talks-cap-green','fig-talks-cap-yellow','fig-talks-light-guides','mini-core','mini-talks-microphone','fig-talks-button','speaker','lipo-battery'],figureParts=['fig-talks-head','fig-talks-torso','fig-talks-arm-left','fig-talks-arm-right','fig-talks-hand','fig-talks-hip','fig-talks-leg-left','fig-talks-leg-right'];let demoView='figure';\n function showDemoView(value){demoView=value;root.dataset.demoView=value;host.setAttribute('aria-label',value==='figure'?'Fig-Talks complete figure':'Fig-Module voice module');root.querySelectorAll('[data-demo-view]').forEach(b=>b.setAttribute('aria-pressed',String(b.dataset.demoView===value)));viewer?.update({selected:new Set(value==='figure'?[...moduleParts,...figureParts]:moduleParts),view:'Demo',wires:false,transparent:false,explosion:0});viewer?.preset('Front');}\n root.querySelectorAll('[data-demo-view]').forEach(b=>b.onclick=()=>showDemoView(b.dataset.demoView));\n viewer?.ready.then(()=>{showDemoView(demoView);render(current);if(location.hash==='#try-device')root.scrollIntoView({block:'start'});viewer.onActivate(id=>{const key={'fig-talks-cap-blue':'power','fig-talks-cap-green':'record','fig-talks-cap-yellow':'play'}[id];if(key&&!root.querySelector('[data-demo='+key+']').disabled)controller[key]();});}).catch(()=>{root.querySelector('.ft-demo-status').textContent='3D preview unavailable. The audio controls below still work.';});\n root.querySelector('.ft-demo-front').onclick=()=>viewer?.preset('Front');window.addEventListener('pagehide',()=>controller.dispose(),{once:true});\n};\n\n<\/script>\n<script>\n(async()=>{\n'use strict';\nconst assetUrl=name=>window.FT_MEDIA_BASE+name;\nconst $=s=>document.querySelector(s),parts=await fetch(window.FT_BASE+'fig-talks-data.json?asset=a2f25819f5').then(r=>r.json()),all=new Set(parts.map(p=>p.id)),device=new Set(parts.filter(p=>p.category!=='Figure').map(p=>p.id));\nconst pairSpecs=[{id:'fig-talks-buttons',title:'Buttons',description:'Blue power, green record and yellow play buttons.',members:['fig-talks-cap-blue','fig-talks-cap-green','fig-talks-cap-yellow'],files:[{label:'STEP',href:'downloads\/fig-talks\/buttons-set.step',reference:false},{label:'STL',href:'downloads\/fig-talks\/buttons-set.stl',reference:false}]},{id:'fig-talks-arms',title:'Arms',description:'Left and right arms connect to the torso.',members:['fig-talks-arm-left','fig-talks-arm-right']},{id:'fig-talks-legs',title:'Legs',description:'Left and right legs connect to the hip.',members:['fig-talks-leg-left','fig-talks-leg-right']}];\nconst catalogue=[...parts.flatMap(p=>{const pair=pairSpecs.find(g=>g.members.includes(p.id));if(!pair)return [p];if(pair.members[0]!==p.id)return [];return [{...pair,category:p.category,quantity:pair.members.length,files:pair.files||pair.members.flatMap((id,i)=>parts.find(x=>x.id===id).files.map(f=>({...f,label:(pair.labels?pair.labels[i]+' \u00b7 ':(i?'Right \u00b7 ':'Left \u00b7 '))+f.label})))}];}),{id:'fig-talks-wires',title:'Wires',description:'Colour-coded routes connect the five electronic parts to the Mini-Core. Follow the terminal labels in Connections.',category:'Electronics',files:[]}];\nconst views=['Angled','Top','Bottom','Bottom angle','Front','Back','Left','Right'],slugs=['angled','top','bottom','bottom-angled','front','back','left','right'];\nconst partViewPreset=(part,name)=>part?.id==='fig-talks-hip'&&name==='Angled'?'Hip angled':name;\nfunction create(id,selection,mode='Demo',modelScript='models\/fig-talks-current.ftm?usb=1294'){const host=$(id);host.dataset.modelScript=modelScript;const api=createFigAssembly(host);if(!api){host.innerHTML='<p class=\"part-error\">This browser could not start 3D. The part images and downloads remain available below.<\/p>';return null;}api.update({selected:selection,view:mode});return api;}\nconst figure=create('#figure-view',all,'Assembly','models\/fig-talks-finished.ftm');let distance=0,angle=0,busy=false;\nconst poseBar=$('#figure-view .assembly-pose-bar');if(poseBar){const detail=document.createElement('details'),summary=document.createElement('summary');summary.textContent='Pose the figure';detail.className='figure-pose-panel';detail.open=true;detail.append(summary,poseBar);$('#figure-pose-controls').append(detail);}\nconst remove=$('#module-remove'),turn=$('#module-turn'),insert=$('#module-insert'),status=$('#module-status');\nfunction controls(){remove.disabled=busy||distance>0;turn.disabled=busy||distance===0;insert.disabled=busy||distance===0;}\nasync function animate(toDistance,toAngle){if(busy||!figure)return;busy=true;controls();const fromD=distance,fromA=angle,duration=matchMedia('(prefers-reduced-motion: reduce)').matches?0:750;await new Promise(resolve=>{const start=performance.now();function frame(t){const p=duration?Math.min(1,(t-start)\/duration):1,e=p*p*(3-2*p);figure.modulePosition(fromD+(toDistance-fromD)*e,fromA+(toAngle-fromA)*e);if(p<1)requestAnimationFrame(frame);else resolve();}requestAnimationFrame(frame);});distance=toDistance;angle=toAngle;busy=false;controls();}\nremove.onclick=async()=>{await animate(110,angle);status.textContent='Module removed \u00b7 Turn it around, or put it back.';};\nturn.onclick=async()=>{await animate(110,angle===0?Math.PI:0);status.textContent=angle?'Logo side forward \u00b7 Ready to put back.':'Buttons forward \u00b7 Ready to put back.';};\ninsert.onclick=async()=>{await animate(0,angle);status.textContent=angle?'Play mode \u00b7 Buttons protected inside the closed torso.':'Buttons forward \u00b7 Ready to record';};\nif(!figure){remove.disabled=turn.disabled=insert.disabled=true;}\ndocument.querySelectorAll('[data-figure-angle]').forEach(b=>b.onclick=()=>figure?.preset(b.dataset.figureAngle));\n$('#rear-design').onchange=e=>{rearDesign=e.target.value;figure?.decoration(rearDesign);pv?.decoration(rearDesign);applyRearDesign();if(detailPart?.id==='fig-talks-rear-enclosure')showDetails(detailPart.id);if(!distance&&!angle)status.textContent='Rear design selected \u00b7 Take out, turn around and put back to see it on the front.';};\nconst pv=create('#part-view',new Set(['fig-talks-front-enclosure']));\nconst friendlyFile=(part,file)=>{const a=document.createElement('a');a.href=new URL(file.href,window.FT_BASE).href;a.download=file.href.split('\/').pop();a.textContent=file.label;return a;};\nconst selectedParts=new Set();\nlet rearDesign='logo',rearName='';\nconst rearFilePrefix={logo:'Logo',name:'Your Name',discs:'Four Studs',plain:'Plain'};\nfunction applyRearDesign(){pv?.decoration(rearDesign);pv?.name(rearName);figure?.name(rearName);$('#rear-design').value=rearDesign;document.querySelectorAll('[data-rear-option]').forEach(b=>b.setAttribute('aria-pressed',String(b.dataset.rearOption===rearDesign)));$('#part-rear-name-field').hidden=rearDesign!=='name';$('#part-rear-hint').hidden=rearDesign!=='name';}\nfunction setRearDesign(value){rearDesign=value;applyRearDesign();if(detailPart?.id==='fig-talks-rear-enclosure'){showDetails(detailPart.id);renderParts();}}\ndocument.querySelectorAll('[data-rear-option]').forEach(b=>b.onclick=()=>setRearDesign(b.dataset.rearOption));\n$('#part-rear-name').oninput=e=>{rearName=e.target.value.slice(0,24);applyRearDesign();if(detailPart?.id==='fig-talks-rear-enclosure')showDetails(detailPart.id);};\nconst wiringParts=['mini-core','mini-talks-microphone','speaker','fig-talks-button','lipo-battery'];\nlet detailPart=null,locatedPart=null;\nconst partById=id=>catalogue.find(p=>p.id===id||p.members?.includes(id))||catalogue[0];\nconst members=part=>part.members||[part.id];\nfunction renderParts(){\n const status=$('#part-view-status'),back=$('#part-back'),locate=$('#part-locate');\n if(locatedPart){\n  pv?.update({selected:all,view:'Assembly',wires:locatedPart.id==='fig-talks-wires'});\n  pv?.locate(locatedPart.id==='fig-talks-wires'?['wire-button','wire-mic','wire-speaker','wire-battery']:members(locatedPart));\n  pv?.preset(partViewPreset(locatedPart,locatedPart.id==='fig-talks-rear-enclosure'?'Back':'Angled'));\n  status.textContent=locatedPart.title+' inside Fig-Talks';locate.hidden=true;back.hidden=false;\n  return;\n }\n const withWires=selectedParts.has('fig-talks-wires'),onlyWires=withWires&&selectedParts.size===1;\n const ids=new Set();for(const id of selectedParts){const part=partById(id);if(part.id!=='fig-talks-wires')for(const member of members(part))ids.add(member);}\n if(onlyWires)for(const id of wiringParts)ids.add(id);\n else if(withWires&&wiringParts.slice(1).some(id=>ids.has(id)))ids.add('mini-core');\n const shells=new Set(['fig-talks-torso','fig-talks-front-enclosure','fig-talks-rear-enclosure','fig-talks-button-panel','fig-talks-battery-panel']);\n const hasShell=[...ids].some(id=>shells.has(id)),hasElectronics=[...ids].some(id=>parts.find(p=>p.id===id)?.category==='Electronics');\n pv?.locate(null);pv?.update({selected:ids,view:onlyWires?'Wires':'Demo',wires:withWires,transparent:withWires||hasShell&&hasElectronics});pv?.preset(partViewPreset(detailPart,detailPart?.id==='fig-talks-rear-enclosure'?'Back':'Angled'));\n if(onlyWires)for(let k=0;k<7;k++)pv?.control('plus');\n status.textContent=selectedParts.size?selectedParts.size+' '+(selectedParts.size===1?'part':'parts')+' selected':'Tick parts to view them together';locate.hidden=selectedParts.size>1;back.hidden=true;\n}\nfunction showDetails(id){\n const part=partById(id);detailPart=part;\n const multi=selectedParts.size>1;\n const explorer=$('#explorer');explorer.dataset.multi=String(multi);\n const summary=$('#part-selected-summary');summary.hidden=!multi;\n if(multi){\n  const list=document.createElement('ul');list.className='selected-parts-list';\n  for(const chosen of catalogue.filter(item=>selectedParts.has(item.id))){\n   const item=document.createElement('li'),category=document.createElement('span'),title=document.createElement('strong'),description=document.createElement('p');\n   category.className='ft-eyebrow';category.textContent=chosen.category;\n   title.textContent=chosen.title;\n   description.textContent=chosen.id==='fig-talks-wires'?'Shows routes only for the selected electronics.':chosen.description;\n   item.append(category,title,description);list.append(item);\n  }\n  summary.replaceChildren(Object.assign(document.createElement('h3'),{textContent:'Selected parts'}),list);\n }\n $('#part-title').textContent=part.title;$('#part-description').textContent=part.description;$('#part-category').textContent=part.category;\n $('#part-locate').setAttribute('aria-label','See '+part.title+' inside Fig-Talks');\n $('#part-rear-design').hidden=multi||part.id!=='fig-talks-rear-enclosure';\n const files=part.id==='fig-talks-rear-enclosure'?part.files.filter(f=>f.label.startsWith(rearFilePrefix[rearDesign])):part.files;\n $('#part-files').replaceChildren(...(multi?[]:files.map(f=>friendlyFile(part,part.id==='fig-talks-rear-enclosure'&&rearDesign==='name'?{...f,label:f.label.replace('Your Name','Placeholder')}:f))));\n applyRearDesign();\n if(!multi&&part.id==='fig-talks-wires'){const a=document.createElement('a');a.href='#connections';a.textContent='See connections';$('#part-files').append(a);}\n $('#part-file-note').textContent=multi?'':part.id==='fig-talks-wires'?'The wire paths illustrate the routing; match the signal labels when wiring.':part.category==='Electronics'?'Electronic models are for reference and fit checks; use the physical components.':'';\n const showEightViews=part.id!=='fig-talks-wires'&&selectedParts.size<=1;\n $('#part-gallery').replaceChildren(...(showEightViews?views:[]).map((name,i)=>{const card=document.createElement('div');card.className='part-view-card';const groupedViews=['fig-talks-legs','fig-talks-buttons','fig-talks-arms'].includes(part.id);for(const [j,member] of (groupedViews?[part.id]:members(part)).entries()){const a=document.createElement('a');a.href=assetUrl((groupedViews?part.id:member)+'-'+slugs[i]+'.png');a.target='_blank';a.rel='noopener';const im=document.createElement('img');im.src=a.href;im.loading='lazy';const label=(groupedViews?'':part.members?(part.labels?part.labels[j]+' \u00b7 ':(j?'Right \u00b7 ':'Left \u00b7 ')):'')+name;im.alt=part.title+' \u2014 '+label;a.append(im,document.createTextNode(label));card.append(a);}return card;}));\n $('#part-gallery').hidden=!showEightViews;$('#part-gallery').previousElementSibling.hidden=!showEightViews;$('#part-gallery').previousElementSibling.textContent=part.id==='fig-talks-rear-enclosure'?'Eight standard views':'Eight views';\n document.querySelectorAll('.part-choice').forEach(card=>card.dataset.active=String(card.dataset.part===part.id));\n const u=new URL(location.href);u.searchParams.delete('revision');u.searchParams.delete('collection');u.searchParams.set('board',part.id);history.replaceState(null,'',u);\n}\nfunction togglePart(id,checked){if(checked)selectedParts.add(id);else selectedParts.delete(id);locatedPart=null;showDetails(!checked&&selectedParts.size===1?[...selectedParts][0]:id);renderParts();}\nfunction locatePart(id){locatedPart=partById(id);showDetails(id);renderParts();}\nfor(const category of ['Electronics','Voice module','Figure']){\n const group=document.createElement('div');group.className='part-group';const h=document.createElement('h3');h.textContent=category;group.append(h);\n for(const part of catalogue.filter(p=>p.category===category)){\n  const card=document.createElement('div');card.className='part-choice';card.dataset.part=part.id;\n  const label=document.createElement('label');label.className='part-select';\n  const checkbox=document.createElement('input');checkbox.type='checkbox';checkbox.value=part.id;checkbox.setAttribute('aria-label','Show '+part.title+' in the parts view');checkbox.onchange=()=>togglePart(part.id,checkbox.checked);\n  const img=document.createElement('img');img.src=assetUrl(part.id+'-angled.png');img.alt='';img.width=48;img.height=48;img.loading='lazy';\n  const name=document.createElement('span');name.textContent=part.title;label.append(checkbox,img,name);\n  card.append(label);group.append(card);\n }\n $('#part-list').append(group);\n}\n$('#part-back').onclick=()=>{locatedPart=null;renderParts();};\n$('#part-locate').onclick=()=>{if(detailPart)locatePart(detailPart.id);};\nfor(const name of views){const b=document.createElement('button');b.textContent=name;b.onclick=()=>{pv?.preset(partViewPreset(locatedPart||detailPart,name));if(!locatedPart&&selectedParts.size===1&&selectedParts.has('fig-talks-wires'))for(let k=0;k<7;k++)pv?.control('plus');};$('#part-angles').append(b);}\nconst initialPart=partById(new URLSearchParams(location.search).get('board')||'fig-talks-front-enclosure');\nselectedParts.add(initialPart.id);document.querySelector('.part-choice[data-part=\"'+initialPart.id+'\"] input').checked=true;showDetails(initialPart.id);renderParts();\nconst nets={mic:{title:'Microphone \u2192 Mini-Core',copy:'Six connections carry power and the microphone\u2019s digital audio signals.',header:'H3',pins:['3V3','GND','GND \/ L-R','I_WS','I_SD','I_SCK']},speaker:{title:'Mini-Core \u2192 Speaker',copy:'The two speaker leads carry the amplified audio output.',header:'H8',pins:['OP','ON']},button:{title:'Button PCB \u2194 Mini-Core',copy:'Seven connections link the three buttons, three indicators and their common ground.',header:'H6',pins:['BUTON1','BUTON2','BUTON3','LED1','LED2','LED3','GND']},battery:{title:'Battery \u2192 Mini-Core',copy:'The battery connects with two bare leads. Follow the polarity labels.',header:'H2',pins:['VBAT +','VBAT \u2212']}};\nfunction net(key){const n=nets[key];$('#net-title').textContent=n.title;$('#net-copy').textContent=n.copy;$('#net-pins').innerHTML=n.pins.map((p,i)=>'<tr><td>'+n.header+'.'+(i+1)+'<\/td><td>'+p+'<\/td><\/tr>').join('');document.querySelectorAll('[data-net]').forEach(el=>{el.classList.toggle('active',el.dataset.net===key);if(el.tagName==='BUTTON')el.setAttribute('aria-pressed',String(el.dataset.net===key));});}document.querySelectorAll('button[data-net]').forEach(b=>b.onclick=()=>net(b.dataset.net));net('mic');\nconst circuit=create('#circuit-view',new Set(['mini-core','mini-talks-microphone','speaker','fig-talks-button','lipo-battery']),'Demo','models\/fig-talks-planar-circuit.ftm?layout=close');\ncircuit?.update({selected:new Set(['mini-core','mini-talks-microphone','speaker','fig-talks-button','lipo-battery']),view:'Demo',wires:true});circuit?.preset('Front');\nconst circuitLabels=[['Mini-Core',[0,-12,22]],['Speaker',[-43,-12,68]],['Microphone',[55,-12,-22]],['Button PCB',[-40,-12,-67]],['Battery',[52,-12,82]]].map(([text,point])=>{const el=document.createElement('span');el.className='circuit-label';el.textContent=text;$('#circuit-view').append(el);return {el,point};});circuit?.onFrame(()=>{for(const {el,point} of circuitLabels){const p=circuit.projectPoint(point);if(p){el.style.left=p.x+'px';el.style.top=p.y+'px';}}});\nlet fittedCircuit=null,circuitLayout='flat';\nconst activeCircuit=()=>circuitLayout==='fitted'?fittedCircuit:circuit;\nfunction setCircuitLayout(layout){\n circuitLayout=layout;\n $('#circuit-view').hidden=layout!=='flat';$('#circuit-fitted-view').hidden=layout!=='fitted';\n if(layout==='fitted'&&!fittedCircuit){\n  fittedCircuit=create('#circuit-fitted-view',new Set(['mini-core','mini-talks-microphone','speaker','fig-talks-button','lipo-battery']),'Electronics');\n  fittedCircuit?.update({selected:new Set(['mini-core','mini-talks-microphone','speaker','fig-talks-button','lipo-battery']),view:'Electronics',wires:true});\n }\n activeCircuit()?.preset(layout==='fitted'?'Angled':'Front');$('#circuit-inspect').value='';\n document.querySelectorAll('[data-circuit-layout]').forEach(b=>b.setAttribute('aria-pressed',String(b.dataset.circuitLayout===layout)));\n document.querySelectorAll('[data-circuit-angle]').forEach(b=>{const n=b.dataset.circuitAngle;b.textContent=n==='Back'?(layout==='flat'?'Flat \u00b7 solder side':'Back'):n==='Front'?(layout==='flat'?'Flat \u00b7 component side':'Front'):'Angle';});\n}\ndocument.querySelectorAll('[data-circuit-layout]').forEach(b=>b.onclick=()=>setCircuitLayout(b.dataset.circuitLayout));\n$('#circuit-inspect').onchange=e=>{activeCircuit()?.preset(circuitLayout==='fitted'?'Angled':'Front');activeCircuit()?.focus(e.target.value||null);};\ndocument.querySelectorAll('[data-circuit-angle]').forEach(b=>b.onclick=()=>{activeCircuit()?.preset(circuitLayout==='fitted'&&b.dataset.circuitAngle==='Back angle'?'Angled':b.dataset.circuitAngle);$('#circuit-inspect').value='';});\ndocument.querySelectorAll('[data-circuit-control]').forEach(b=>b.onclick=()=>activeCircuit()?.control(b.dataset.circuitControl));\nconst build=create('#build-view',device),steps={front:{number:'1 \/ Front half',title:'Start where the voice comes out.',copy:'Fit the speaker, microphone and button assembly into the front cover.',ids:['fig-talks-front-enclosure','speaker','mini-talks-microphone','fig-talks-button','fig-talks-button-panel','fig-talks-cap-blue','fig-talks-cap-green','fig-talks-cap-yellow','fig-talks-light-guides'],instructions:['Place the speaker in its full side channel.','Seat the microphone behind its opening.','Fit the three caps and light guides, then the PCB and button panel. Secure the panel with its upper two screws.'],note:'The button panel is secured at the top; its lower edge seats in the front cover.'},rear:{number:'2 \/ Rear half',title:'A home for power and control.',copy:'The battery and Mini-Core share the rear panel assembly.',ids:['fig-talks-rear-enclosure','lipo-battery','mini-core','fig-talks-battery-panel'],instructions:['Seat the battery in its pocket without pinching its leads.','Fit Mini-Core into its panel channels.','Engage the panel\u2019s lower edge first, then bring its top into position. Keep USB-C aligned with the opening.'],note:'Mini-Core moves with its panel. Keep the cable channel clear.'},connect:{number:'3 \/ Connections',title:'Bring the two halves together.',copy:'Inspect the established wire routes in their fitted positions.',ids:[...device],instructions:['Follow the connection map above for signal identities.','Route the leads through the intended channels.','Keep wires clear of the mating lips, screw seats and button travel.'],note:'The transparent case lets you see the existing cable paths. Separate the layers to inspect individual components; wires hide during separation.'},close:{number:'4 \/ Finished voice module',title:'Close it. Then make it part of play.',copy:'The complete module sits inside the torso in either direction.',ids:[...device],instructions:['Check that the buttons move freely and USB-C remains accessible.','Join the front and rear covers with the enclosure screws.','Insert the module with buttons facing forward, or remove and reverse it for play.'],note:'The torso\u2019s closed back protects the inward-facing buttons. Physical grip and latch performance still need a print check.'}};let step='front';\nfunction showBuild(key){step=key;const s=steps[key];$('#build-count').textContent=s.number;$('#build-title').textContent=s.title;$('#build-copy').textContent=s.copy;$('#build-instructions').replaceChildren(...s.instructions.map(t=>{const li=document.createElement('li');li.textContent=t;return li;}));$('#build-note').textContent=s.note;$('#build-separation').value=0;$('#build-separation').closest('label').hidden=false;build?.update({selected:new Set(s.ids),view:key==='figure'?'Assembly':'Demo',wires:key==='connect',transparent:key==='connect'});build?.preset(key==='front'?'Back angle':key==='rear'?'Angled':'Angled');steps.figure={number:'5 \/ Complete figure',title:'Give the voice module a character.',copy:'Bring the head, torso, arms, hands, hip and legs together around the voice module.',ids:[...all],instructions:['Connect the legs to the hip and the hip to the torso.','Fit both arms and hands, then seat the head.','Slide the completed voice module into the torso.'],note:'Open the layers: the voice module separates in front, while the head, torso, arms, hands, hip and legs separate behind it.'};\ndocument.querySelectorAll('[data-build]').forEach(b=>b.setAttribute('aria-pressed',String(b.dataset.build===key)));}\ndocument.querySelectorAll('[data-build]').forEach(b=>b.onclick=()=>showBuild(b.dataset.build));document.querySelectorAll('[data-build-angle]').forEach(b=>b.onclick=()=>build?.preset(b.dataset.buildAngle));$('#build-separation').oninput=e=>build?.explode(Number(e.target.value)\/100);showBuild('front');\nconst personal=create('#personal-view',new Set(['head-upper','head-lower','face','glasses','highlights','pins','hair-two']),'Demo','models\/fig-talks-personal.ftm?geometry=original-contour');\nlet personalStep=0;\nconst personalStages=[\n {title:'Recessed head',copy:'See the upper and lower head with the recessed seats and joining pins.',ids:['head-upper','head-lower','pins']},\n {title:'Face details',copy:'Explore the separate eyes, eyebrows, mouth, eye highlights and glasses.',ids:['face','glasses','highlights']},\n {title:'Fit the face',copy:'The face pieces sit in the matching recesses of the head.',ids:['head-upper','head-lower','pins','face','glasses','highlights']},\n {title:'Hair pieces',copy:'See both pieces of the hairstyle before they are fitted.',ids:['hair-two']},\n {title:'Head with hair',copy:'The finished head brings the face details and two-piece hair together.',ids:['head-upper','head-lower','pins','face','glasses','highlights','hair-two']}\n];\nfunction showPersonal(){const stage=personalStages[personalStep];personal?.update({selected:new Set(stage.ids),view:'Demo'});personal?.preset('Right');$('#personal-step-title').textContent=stage.title;$('#personal-status').textContent=stage.copy;document.querySelectorAll('[data-person-step]').forEach(b=>b.setAttribute('aria-pressed',String(+b.dataset.personStep===personalStep)));document.querySelectorAll('[data-person-download]').forEach(a=>a.hidden=+a.dataset.personDownload!==personalStep);}\ndocument.querySelectorAll('[data-person-step]').forEach(b=>b.onclick=()=>{personalStep=+b.dataset.personStep;showPersonal();});document.querySelectorAll('[data-person-angle]').forEach(b=>b.onclick=()=>personal?.preset(b.dataset.personAngle));showPersonal();\nlet inside=false;$('#inspect-inside').onclick=()=>{inside=!inside;figure?.update({selected:all,view:'Assembly',wires:inside,transparent:inside});$('#inspect-inside').setAttribute('aria-pressed',String(inside));$('#inspect-inside').textContent=inside?'Show complete Fig-Talks':'Look inside Fig-Talks';};\nconst syncIds=new Set([...all,'laptop']);const syncViewer=create('#profile-scene',syncIds,'Assembly','models\/fig-talks-profile-scene.ftm');syncViewer?.preset('Connection');let syncPosition=0,syncBusy=false;\nasync function syncStep(step){if(syncBusy||!syncViewer)return;syncBusy=true;const buttons=[...document.querySelectorAll('[data-sync-step]')];buttons.forEach(b=>b.disabled=true);syncIds.delete('usb-cable');syncViewer.update({selected:syncIds,view:'Assembly'});const from=syncPosition,to=step===0?0:1,duration=matchMedia('(prefers-reduced-motion: reduce)').matches?0:1200;await new Promise(resolve=>{const start=performance.now();function frame(t){const p=duration?Math.min(1,(t-start)\/duration):1,e=p*p*(3-2*p),v=from+(to-from)*e;const first=Math.min(1,v*2),second=Math.max(0,v*2-1);syncViewer.moduleOffset([165*second,-95*first,-80*second]);if(p<1)requestAnimationFrame(frame);else resolve();}requestAnimationFrame(frame);});syncPosition=to;if(step===2)syncIds.add('usb-cable');syncViewer.update({selected:syncIds,view:'Assembly'});$('#profile-scene-status').textContent=step===0?'The Fig-Module is inside your figure.':step===1?'Fig-Module removed \u00b7 Ready to connect with USB-C.':'USB-C connected in the preview \u00b7 Open your profile to pair your physical kit.';buttons.forEach(b=>{b.disabled=false;b.setAttribute('aria-pressed',String(+b.dataset.syncStep===step));});syncBusy=false;}\ndocument.querySelectorAll('[data-sync-step]').forEach(b=>b.onclick=()=>syncStep(+b.dataset.syncStep));\n\nmountFigTalksDemo($('#try-device'));\ntry{const s=await fetch(window.FT_BASE+'fig-talks-software.json',{cache:'no-store'}).then(r=>r.json());if(s.status==='ready'&&s.files?.length){$('#software-note').textContent=s.note||'';$('#software-note').hidden=!s.note;const box=$('#software-downloads');box.className='file-links';for(const f of s.files){const a=document.createElement('a');a.href=new URL(f.href,window.FT_BASE).href;a.textContent=f.label;box.append(a);}if(s.source){const detail=document.createElement('details'),summary=document.createElement('summary'),pre=document.createElement('pre');summary.textContent='Read the firmware';pre.className='firmware-source';pre.tabIndex=0;pre.textContent='Loading source\u2026';detail.append(summary,pre);box.after(detail);let loaded=false;detail.addEventListener('toggle',async()=>{if(!detail.open||loaded)return;loaded=true;try{const r=await fetch(new URL(s.source,window.FT_BASE),{cache:'no-store'});if(!r.ok)throw Error();pre.textContent=await r.text();}catch{pre.textContent='Source preview unavailable. Use the firmware download above.';loaded=false;}});}}}catch{}\n})();\n\n\/\/ Keep the rail below the actual responsive header and mark the section in view.\n(()=>{const header=document.querySelector('.mt-header')||document.querySelector('.elementor-location-header')||document.querySelector('header'),page=document.querySelector('main.ft-page'),rail=document.querySelector('.ft-page .chapter-nav'),links=[...document.querySelectorAll('.chapter-nav a')],sections=links.map(a=>document.querySelector(a.getAttribute('href')));let scheduled=false;const hb=()=>header?Math.max(0,header.getBoundingClientRect().bottom):0;function mark(){scheduled=false;const top=hb();document.documentElement.style.setProperty('--site-header-h',top+'px');if(rail){if(getComputedStyle(rail).position==='fixed'){const r=page.getBoundingClientRect();rail.style.top=Math.max(top,r.top)+'px';rail.style.bottom=Math.max(0,innerHeight-r.bottom)+'px';}else{rail.style.top='';rail.style.bottom='';}}const y=top+50;let current=sections[0];for(const section of sections)if(section&&section.getBoundingClientRect().top<=y)current=section;links.forEach(a=>{if(current&&a.hash==='#'+current.id)a.setAttribute('aria-current','location');else a.removeAttribute('aria-current');});}new ResizeObserver(mark).observe(document.documentElement);addEventListener('scroll',()=>{if(!scheduled){scheduled=true;requestAnimationFrame(mark);}},{passive:true});addEventListener('resize',mark);mark();})();\n\n<\/script>\n\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t\t\t\t<\/div>","protected":false},"excerpt":{"rendered":"<p>Fig-Talks Personalize your figure.Record and replay your voice.Speak through your own figure. 01What is Fig-Talks?02Parts03Connections04Build05Personalize06Software07Try it08Play &#038; explore09Profile &#038; sync 01 \/ WHAT IS FIG-TALKS? A personalized figure. A familiar voice. A PERSONAL FIGURE Their figure. Their voice. A personalized physical figure with a removable voice module. Children can record a sound, a word or&hellip; <a class=\"more-link\" href=\"https:\/\/mini-talks.org\/da\/mini-kits\/fig-talks\/\">L\u00e6s mere <span class=\"screen-reader-text\">Fig-Talks<\/span><\/a><\/p>","protected":false},"author":3,"featured_media":0,"parent":13245,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_header_footer","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"class_list":["post-15080","page","type-page","status-publish","hentry","entry"],"_links":{"self":[{"href":"https:\/\/mini-talks.org\/da\/wp-json\/wp\/v2\/pages\/15080","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mini-talks.org\/da\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/mini-talks.org\/da\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/mini-talks.org\/da\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/mini-talks.org\/da\/wp-json\/wp\/v2\/comments?post=15080"}],"version-history":[{"count":16,"href":"https:\/\/mini-talks.org\/da\/wp-json\/wp\/v2\/pages\/15080\/revisions"}],"predecessor-version":[{"id":15301,"href":"https:\/\/mini-talks.org\/da\/wp-json\/wp\/v2\/pages\/15080\/revisions\/15301"}],"up":[{"embeddable":true,"href":"https:\/\/mini-talks.org\/da\/wp-json\/wp\/v2\/pages\/13245"}],"wp:attachment":[{"href":"https:\/\/mini-talks.org\/da\/wp-json\/wp\/v2\/media?parent=15080"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}