{"id":14980,"date":"2026-10-24T03:46:47","date_gmt":"2026-10-24T01:46:47","guid":{"rendered":"https:\/\/pappcseperke.hu\/?page_id=14980"},"modified":"2026-11-13T07:02:14","modified_gmt":"2026-11-13T06:02:14","slug":"digital-equilibrist","status":"publish","type":"page","link":"https:\/\/pappcseperke.hu\/hu\/digital-equilibrist\/","title":{"rendered":"The Equilibrist&#8217;s Lab"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"14980\" class=\"elementor elementor-14980\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-b4a30b6 e-flex e-con-boxed e-con e-parent\" data-id=\"b4a30b6\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;jet_parallax_layout_list&quot;:[],&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-653ba04 elementor-widget elementor-widget-menu-anchor\" data-id=\"653ba04\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"menu-anchor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-menu-anchor\" id=\"projects\"><\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-08132cd animated-slow elementor-invisible elementor-widget elementor-widget-heading\" data-id=\"08132cd\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;_animation&quot;:&quot;fadeIn&quot;}\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h4 class=\"elementor-heading-title elementor-size-default\">the laboratory<\/h4>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7d84894 elementor-widget elementor-widget-heading\" data-id=\"7d84894\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Digital Experiments\n<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-31af086 elementor-widget elementor-widget-text-editor\" data-id=\"31af086\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>The common thread is visualization \u2014 systems made visible. Typographic engines, manuscript-flavored interfaces, motion tools, timelines, breathing worlds: different shapes of an inspired craft.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-aa3e90e e-grid e-con-full e-con e-child\" data-id=\"aa3e90e\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;jet_parallax_layout_list&quot;:[],&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t<div class=\"elementor-element elementor-element-a7c873c elementor-flip-box--effect-flip elementor-flip-box--direction-up elementor-widget elementor-widget-flip-box\" data-id=\"a7c873c\" data-element_type=\"widget\" data-e-type=\"widget\" data-anchor-link=\"#systems\" data-widget_type=\"flip-box.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-flip-box\" tabindex=\"0\">\n\t\t\t<div class=\"elementor-flip-box__layer elementor-flip-box__front\">\n\t\t\t\t<div class=\"elementor-flip-box__layer__overlay\">\n\t\t\t\t\t<div class=\"elementor-flip-box__layer__inner\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"elementor-icon-wrapper elementor-view-default\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-icon\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t<h3 class=\"elementor-flip-box__layer__title\">\n\t\t\t\t\t\t\t\tDecision Themes\t\t\t\t\t\t\t<\/h3>\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"elementor-flip-box__layer__description\">\n\t\t\t\t\t\t\t\tA design system generator that shows its math \u2014 whole visual systems derived from a handful of decisions. \t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t\t<a class=\"elementor-flip-box__layer elementor-flip-box__back\" href=\"http:\/\/studio.decisionthemes.com\/\">\n\t\t\t<div class=\"elementor-flip-box__layer__overlay\">\n\t\t\t\t<div class=\"elementor-flip-box__layer__inner\">\n\t\t\t\t\t\t\t\t\t\t\t<h3 class=\"elementor-flip-box__layer__title\">\n\t\t\t\t\t\t\tstudio DTS\t\t\t\t\t\t<\/h3>\n\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"elementor-flip-box__layer__description\">\n\t\t\t\t\t\t\tExperience the system\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-flip-box__button elementor-button elementor-size-sm\">\n\t\t\t\t\t\t\tDTS Studio\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t<\/a>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-6d7b13f elementor-flip-box--effect-flip elementor-flip-box--direction-up elementor-widget elementor-widget-flip-box\" data-id=\"6d7b13f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"flip-box.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-flip-box\" tabindex=\"0\">\n\t\t\t<div class=\"elementor-flip-box__layer elementor-flip-box__front\">\n\t\t\t\t<div class=\"elementor-flip-box__layer__overlay\">\n\t\t\t\t\t<div class=\"elementor-flip-box__layer__inner\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"elementor-icon-wrapper elementor-view-default\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-icon\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t<h3 class=\"elementor-flip-box__layer__title\">\n\t\t\t\t\t\t\t\tVisualization experiments\t\t\t\t\t\t\t<\/h3>\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"elementor-flip-box__layer__description\">\n\t\t\t\t\t\t\t\tTimelines, diagrams, motion studies \u2014 the mathematics of rhythm and movement, tested in public. The lab notebook, left open.\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t\t<a class=\"elementor-flip-box__layer elementor-flip-box__back\" href=\"http:\/\/github.com\/CseperkePapp\/Visualizations\">\n\t\t\t<div class=\"elementor-flip-box__layer__overlay\">\n\t\t\t\t<div class=\"elementor-flip-box__layer__inner\">\n\t\t\t\t\t\t\t\t\t\t\t<h3 class=\"elementor-flip-box__layer__title\">\n\t\t\t\t\t\t\tVISUALIZATION SYSTEMS\t\t\t\t\t\t<\/h3>\n\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"elementor-flip-box__layer__description\">\n\t\t\t\t\t\t\tOpen source, free\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-flip-box__button elementor-button elementor-size-sm\">\n\t\t\t\t\t\t\tmy GIT HUB\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t<\/a>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-e505830 elementor-flip-box--effect-flip elementor-flip-box--direction-up elementor-widget elementor-widget-flip-box\" data-id=\"e505830\" data-element_type=\"widget\" data-e-type=\"widget\" data-anchor-link=\"#patterns\" data-widget_type=\"flip-box.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-flip-box\" tabindex=\"0\">\n\t\t\t<div class=\"elementor-flip-box__layer elementor-flip-box__front\">\n\t\t\t\t<div class=\"elementor-flip-box__layer__overlay\">\n\t\t\t\t\t<div class=\"elementor-flip-box__layer__inner\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"elementor-icon-wrapper elementor-view-default\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-icon\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t<h3 class=\"elementor-flip-box__layer__title\">\n\t\t\t\t\t\t\t\tWe Are Patterns\t\t\t\t\t\t\t<\/h3>\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"elementor-flip-box__layer__description\">\n\t\t\t\t\t\t\t\tA book about how to look at the world through the pattern view and how the change in eprception changes our attitude, and our experience.\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t\t<a class=\"elementor-flip-box__layer elementor-flip-box__back\" href=\"https:\/\/docs.google.com\/document\/d\/1hoxPs6x9L3_v7N3EXqfDmNgXmTR2VbZakP8pg6ZRu78\/edit?usp=sharing\">\n\t\t\t<div class=\"elementor-flip-box__layer__overlay\">\n\t\t\t\t<div class=\"elementor-flip-box__layer__inner\">\n\t\t\t\t\t\t\t\t\t\t\t<h3 class=\"elementor-flip-box__layer__title\">\n\t\t\t\t\t\t\tWhere patterns meet\t\t\t\t\t\t<\/h3>\n\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"elementor-flip-box__layer__description\">\n\t\t\t\t\t\t\tGet a taste of the first few pages\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-flip-box__button elementor-button elementor-size-sm\">\n\t\t\t\t\t\t\tChapter 1\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t<\/a>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-b52d6e1 e-flex e-con-boxed e-con e-parent\" data-id=\"b52d6e1\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;jet_parallax_layout_list&quot;:[]}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-453899e animated-slow e-con-full e-flex elementor-invisible e-con e-child\" data-id=\"453899e\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;jet_parallax_layout_list&quot;:[],&quot;animation&quot;:&quot;fadeInUp&quot;,&quot;animation_mobile&quot;:&quot;none&quot;}\">\n\t\t\t\t<div class=\"elementor-element elementor-element-b979cc5 elementor-widget elementor-widget-html\" data-id=\"b979cc5\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<script>\ndocument.addEventListener('DOMContentLoaded', function() {\n    if (window.innerWidth > 767) return;\n\n    const posts = document.querySelectorAll('article.elementor-post');\n    const centralZoneHeight = 100;\n\n    function handleScrollAnimations() {\n        const windowHeight = window.innerHeight;\n        const viewportCenter = windowHeight \/ 2;\n        const zoneTop = viewportCenter - (centralZoneHeight \/ 2);\n        const zoneBottom = viewportCenter + (centralZoneHeight \/ 2);\n\n        posts.forEach(post => {\n            const rect = post.getBoundingClientRect();\n            const excerpt = post.querySelector('.elementor-post__excerpt');\n            if (!excerpt) return;\n\n            const elementCenter = rect.top + rect.height \/ 2;\n            let proximity;\n\n            if (elementCenter > zoneTop && elementCenter < zoneBottom) {\n                proximity = 1;\n            } else {\n                let distanceFromZoneEdge;\n                if (elementCenter <= zoneTop) {\n                    distanceFromZoneEdge = zoneTop - elementCenter;\n                } else {\n                    distanceFromZoneEdge = elementCenter - zoneBottom;\n                }\n                const maxDistance = viewportCenter - (centralZoneHeight \/ 2) + (rect.height \/ 2);\n                proximity = 1 - (distanceFromZoneEdge \/ maxDistance);\n                proximity = Math.max(0, Math.min(1, proximity));\n            }\n\n            const maxRotation = 60;\n            let rotation = maxRotation * (1 - proximity);\n\n            if (elementCenter < viewportCenter) {\n                post.style.transformOrigin = 'bottom';\n            } else {\n                post.style.transformOrigin = 'top';\n                rotation = -rotation;\n            }\n            post.style.opacity = proximity;\n            \/\/ UPDATED LINE: Added perspective directly to the transform\n            post.style.transform = `perspective(1000px) rotateX(${rotation}deg)`;\n\n            const currentState = excerpt.dataset.state || 'hidden';\n            const triggerThreshold = 0.8;\n\n            if (proximity > triggerThreshold && currentState === 'hidden') {\n                excerpt.dataset.state = 'visible';\n                excerpt.classList.add('fade-in-timed');\n                excerpt.classList.remove('fade-out-top', 'fade-out-bottom');\n            } else if (proximity <= triggerThreshold && currentState === 'visible') {\n                excerpt.dataset.state = 'hidden';\n                if (elementCenter > viewportCenter) {\n                    excerpt.classList.add('fade-out-bottom');\n                } else {\n                    excerpt.classList.add('fade-out-top');\n                }\n                excerpt.classList.remove('fade-in-timed');\n            }\n        });\n    }\n\n    window.addEventListener('scroll', handleScrollAnimations, { passive: true });\n    handleScrollAnimations();\n});\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-6d67b89 e-flex e-con-boxed e-con e-parent\" data-id=\"6d67b89\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;jet_parallax_layout_list&quot;:[]}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-ad27303 elementor-widget elementor-widget-menu-anchor\" data-id=\"ad27303\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"menu-anchor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-menu-anchor\" id=\"systems\"><\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-723da66 animated-slow elementor-invisible elementor-widget elementor-widget-heading\" data-id=\"723da66\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;_animation&quot;:&quot;fadeIn&quot;}\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h4 class=\"elementor-heading-title elementor-size-default\">The mad project<\/h4>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-be6cc14 elementor-widget elementor-widget-heading\" data-id=\"be6cc14\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">DTS: A Design Decision System<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-94c282d elementor-widget elementor-widget-html\" data-id=\"94c282d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!-- ============================================================\n     THE THREE-DECISION PLAYGROUND \u2014 standalone Elementor HTML widget\n     2026-07-18 \u00b7 from home-v3-juggler (IIIA)\n\n     WHAT IT DOES\n     A live, tiny demo of the Decision Themes engine: three sliders \u2014\n     base size, ratio, hue \u2014 and everything on the right (headline size,\n     subhead, body copy, swatches, spacing bars, a readout of the raw\n     numbers) is a pure derivation of those three inputs. Drag a slider,\n     watch the whole specimen recompute in real time. The argument the\n     rest of the page makes in words, running live in one box.\n\n     HOW TO INSTALL\n     1. Elementor \u2192 add an HTML widget where the playground should sit.\n     2. Paste this entire file into the widget. Done.\n     3. Reuse anywhere: about page, Decision Themes landing page, a blog\n        post explaining the engine \u2014 it's fully self-contained.\n\n     NOTES\n     \u00b7 No dependencies beyond Google Fonts (Cormorant + Overlock) \u2014\n       no GSAP, no jQuery.\n     \u00b7 Everything is scoped under #cspPlayground \/ csp- prefixed classes\n       and ids; nothing leaks into your theme, and your theme can't\n       break it. Its own color\/font variables are local, not inherited\n       from the main site.\n     \u00b7 Fully keyboard accessible: three real <input type=range> elements.\n     ============================================================ -->\n\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n<link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Cormorant+Unicase:wght@600&family=Cormorant+SC:wght@600&family=Overlock:wght@400;700&display=swap\" rel=\"stylesheet\">\n\n<div id=\"cspPlayground\" class=\"csp-pg\">\n  <div class=\"csp-pg-decisions\">\n    <span class=\"csp-pg-title\">three decisions<\/span>\n    <label for=\"cspPgBase\">base size \u2014 <b id=\"cspPgBv\">18px<\/b>\n      <input type=\"range\" id=\"cspPgBase\" min=\"14\" max=\"22\" step=\"1\" value=\"18\"><\/label>\n    <label for=\"cspPgRatio\">ratio \u2014 <b id=\"cspPgRv\">1.333<\/b>\n      <input type=\"range\" id=\"cspPgRatio\" min=\"1150\" max=\"1500\" step=\"1\" value=\"1333\"><\/label>\n    <label for=\"cspPgHue\">hue \u2014 <b id=\"cspPgHv\">183\u00b0<\/b>\n      <input type=\"range\" id=\"cspPgHue\" min=\"0\" max=\"360\" step=\"1\" value=\"183\"><\/label>\n    <p class=\"csp-pg-note\">Three decisions. Everything on the right is consequences.<\/p>\n  <\/div>\n  <div class=\"csp-pg-specimen\">\n    <div class=\"csp-pg-h\" id=\"cspPgH\">Digital Equilibrist<\/div>\n    <div class=\"csp-pg-sub\" id=\"cspPgSub\">order where it matters<\/div>\n    <p class=\"csp-pg-body\" id=\"cspPgBody\">Play whenever you can. The scale, the swatches and the spacing\n      below all derive from the three decisions on the left \u2014 the same way a whole site can.<\/p>\n    <div class=\"csp-pg-swatches\" id=\"cspPgSwatches\" aria-hidden=\"true\"><\/div>\n    <div class=\"csp-pg-bars\" id=\"cspPgBars\" aria-hidden=\"true\"><\/div>\n    <div class=\"csp-pg-readout\" id=\"cspPgReadout\" aria-hidden=\"true\"><\/div>\n  <\/div>\n<\/div>\n\n<style>\n#cspPlayground{\n  \/* the kit, locally scoped \u2014 change these to retheme it *\/\n  --csp-bg:        #1C1C1C;\n  --csp-sage:      #C0D8D5;\n  --csp-grey:      #CCCDD1;\n  --csp-teal:      #6EB4BA;\n  --csp-neutral:   #939498;\n  --csp-parchment: #EBDCC5;\n  --csp-parchment2:#D2C2AA;\n  --csp-deepteal:  #213333;\n\n  --csp-f-display: 'Cormorant Unicase', serif;\n  --csp-f-caps:    'Cormorant SC', serif;\n  --csp-f-body:    'Overlock', sans-serif;\n\n  max-width: 720px;\n  border:1px solid color-mix(in oklab, var(--csp-neutral) 30%, transparent);\n  background: color-mix(in oklab, var(--csp-deepteal) 20%, var(--csp-bg));\n  display:grid; grid-template-columns: 240px 1fr;\n  font-family: var(--csp-f-body); color: var(--csp-grey);\n  box-sizing: border-box;\n  transition: border-color .3s ease;\n}\n#cspPlayground *{ box-sizing:border-box; }\n@media (max-width:640px){ #cspPlayground{ grid-template-columns:1fr; } }\n\n#cspPlayground .csp-pg-decisions{\n  padding: 1.5rem;\n  border-right:1px dashed color-mix(in oklab, var(--csp-neutral) 30%, transparent);\n  display:flex; flex-direction:column; gap: 1rem;\n}\n@media (max-width:640px){\n  #cspPlayground .csp-pg-decisions{\n    border-right:none;\n    border-bottom:1px dashed color-mix(in oklab, var(--csp-neutral) 30%, transparent);\n  }\n}\n#cspPlayground .csp-pg-title{\n  font-family: var(--csp-f-caps); font-variant: small-caps; text-transform: lowercase;\n  letter-spacing:0.18em; color: var(--csp-parchment2); font-size: 0.85rem;\n}\n#cspPlayground label{\n  font-family: var(--csp-f-caps); font-variant: small-caps; text-transform: lowercase;\n  letter-spacing:0.12em; color: var(--csp-neutral); font-size: 0.85rem; display:block;\n}\n#cspPlayground label b{ color: var(--csp-sage); font-weight:600; }\n#cspPlayground input[type=range]{ width:100%; accent-color: var(--csp-teal); margin-top:4px; }\n#cspPlayground .csp-pg-note{\n  margin-top:auto; font-family: var(--csp-f-body); font-style:italic;\n  color: var(--csp-parchment2); font-size: 0.94rem; line-height:1.45;\n}\n#cspPlayground .csp-pg-specimen{ padding: 1.5rem; min-width:0; }\n#cspPlayground .csp-pg-h{\n  font-family: var(--csp-f-display); font-weight:600; color: var(--csp-sage);\n  line-height:1.1; transition: color .3s ease;\n}\n#cspPlayground .csp-pg-sub{\n  font-family: var(--csp-f-caps); font-variant: small-caps; text-transform: lowercase;\n  color: var(--csp-parchment2); margin-top:2px;\n}\n#cspPlayground .csp-pg-body{ margin-top: 0.5rem; max-width:44ch; line-height:1.5; }\n#cspPlayground .csp-pg-swatches{ display:flex; gap:0.5rem; margin-top: 0.75rem; }\n#cspPlayground .csp-pg-swatches div{ width:34px; height:34px; }\n#cspPlayground .csp-pg-bars{ display:flex; align-items:flex-end; gap:6px; margin-top: 0.75rem; }\n#cspPlayground .csp-pg-bars div{ height:8px; background: var(--csp-parchment2); opacity:.8; }\n#cspPlayground .csp-pg-readout{\n  margin-top: 0.75rem; font-family: ui-monospace, 'Cascadia Code', Consolas, monospace;\n  font-size: 0.85rem; color: var(--csp-neutral); line-height:1.7;\n}\n#cspPlayground .csp-pg-readout b{ color: var(--csp-grey); font-weight:400; }\n\n@media (prefers-reduced-motion: reduce){\n  #cspPlayground{ transition:none; }\n  #cspPlayground .csp-pg-h{ transition:none; }\n}\n<\/style>\n\n<script>\n\/* The engine, running in a box. Deterministic, dependency-free. *\/\n(function () {\n  'use strict';\n\n  var root = document.getElementById('cspPlayground');\n  if (!root) { return; }\n  function $(id){ return document.getElementById(id); }\n\n  var base = $('cspPgBase'), ratio = $('cspPgRatio'), hue = $('cspPgHue');\n  if (!base || !ratio || !hue) { return; }\n\n  var titleEl = root.querySelector('.csp-pg-title');\n\n  function derive(){\n    var b = +base.value, r = +ratio.value \/ 1000, h = +hue.value;\n    $('cspPgBv').textContent = b + 'px';\n    $('cspPgRv').textContent = r.toFixed(3);\n    $('cspPgHv').textContent = h + '\u00b0';\n\n    var ink = 'hsl(' + h + ',35%,58%)';\n    var s1 = b * r, s2 = s1 * r, s3 = s2 * r;\n    $('cspPgH').style.fontSize = Math.min(s2 * 1.15, 52) + 'px';\n    $('cspPgH').style.color = 'hsl(' + h + ',30%,80%)';\n    $('cspPgSub').style.fontSize = s1 * 0.85 + 'px';\n    $('cspPgSub').style.color = 'hsl(' + h + ',32%,64%)';\n    $('cspPgBody').style.fontSize = b * 0.85 + 'px';\n    root.style.borderColor = 'hsl(' + h + ',25%,32%)';\n\n    \/* the decisions column is derived too: sliders, values, title *\/\n    [base, ratio, hue].forEach(function (i) { i.style.accentColor = ink; });\n    if (titleEl) { titleEl.style.color = 'hsl(' + h + ',28%,72%)'; }\n    ['cspPgBv', 'cspPgRv', 'cspPgHv'].forEach(function (id) {\n      $(id).style.color = 'hsl(' + h + ',30%,74%)';\n    });\n\n    var cols = [\n      'hsl(' + h + ',35%,58%)', 'hsl(' + h + ',30%,38%)',\n      'hsl(' + h + ',25%,16%)', 'hsl(' + ((h + 200) % 360) + ',92%,60%)'\n    ];\n    $('cspPgSwatches').innerHTML = cols.map(function (c) {\n      return '<div style=\"background:' + c + '\"><\/div>';\n    }).join('');\n\n    var bars = '', k;\n    for (k = 0; k < 5; k++) {\n      bars += '<div style=\"width:' + (b * 0.5 * Math.pow(r, k)).toFixed(1) + 'px\"><\/div>';\n    }\n    $('cspPgBars').innerHTML = bars;\n\n    $('cspPgReadout').innerHTML =\n      'scale \u2192 <b>' + [b, s1, s2, s3].map(function (v) { return Math.round(v); }).join(' \u00b7 ') + '<\/b><br>' +\n      'spacing \u2192 <b>' + [1, 2, 3, 4].map(function (m) { return Math.round(b * 0.5 * m * r); }).join(' \u00b7 ') + '<\/b> &nbsp;\u00b7&nbsp; ' +\n      'ink \u2192 <b>hsl(' + h + ' 35% 58%)<\/b>';\n  }\n\n  [base, ratio, hue].forEach(function (i) { i.addEventListener('input', derive); });\n  derive();\n}());\n<\/script>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3262724 elementor-widget elementor-widget-text-editor\" data-id=\"3262724\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Decision Themes, my design system generator, turns a few base decisions \u2014 size, rhythm, color \u2014 into a complete, coherent design system, derived by rule. The math underneath is public: on GitHub and npm, with a live playground at <a href=\"https:\/\/decisionthemes.com\/\" target=\"_blank\" rel=\"noopener\">decisionthemes.com<\/a>.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-8c747ee e-flex e-con-boxed e-con e-parent\" data-id=\"8c747ee\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;jet_parallax_layout_list&quot;:[]}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-2c8fe9d elementor-widget elementor-widget-menu-anchor\" data-id=\"2c8fe9d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"menu-anchor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-menu-anchor\" id=\"patterns\"><\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-fd03a3a animated-slow elementor-invisible elementor-widget elementor-widget-heading\" data-id=\"fd03a3a\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;_animation&quot;:&quot;fadeIn&quot;}\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">How looking ourselves as interacting patterns changes the perspective<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-ba0d853 elementor-widget elementor-widget-heading\" data-id=\"ba0d853\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">We are patterns<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-5a7a3b9 elementor-widget elementor-widget-text-editor\" data-id=\"5a7a3b9\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Taking an attempt at writing a book about how looking at life as an infinite generation and interference of patterns affects our thinking about the world, life, death, and relationships. It is a meditation, an observation through a unique lense.<\/p><p>Right now it is too dense, but a great project I am happy to share chapter by chapter (unedited, work in progress) &#8211; hopefully one day I even finish.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-86100c3 elementor-tablet-align-right elementor-widget elementor-widget-button\" data-id=\"86100c3\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"button.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<div class=\"elementor-button-wrapper\">\n\t\t\t\t\t<a class=\"elementor-button elementor-button-link elementor-size-sm\" href=\"https:\/\/pappcseperke.hu\/we-are-patterns-chapter-1\/\" target=\"_blank\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\">Chapter 1<\/span>\n\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/a>\n\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-2954f57 e-flex e-con-boxed e-con e-parent\" data-id=\"2954f57\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;jet_parallax_layout_list&quot;:[]}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-f2568e2 elementor-widget elementor-widget-menu-anchor\" data-id=\"f2568e2\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"menu-anchor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-menu-anchor\" id=\"commissions\"><\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-0412f7b animated-slow elementor-invisible elementor-widget elementor-widget-heading\" data-id=\"0412f7b\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;_animation&quot;:&quot;fadeIn&quot;}\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h4 class=\"elementor-heading-title elementor-size-default\">fund the lab<\/h4>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-df53fc7 elementor-widget elementor-widget-heading\" data-id=\"df53fc7\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Every experiment needs funding.<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-be7c75f elementor-widget elementor-widget-heading\" data-id=\"be7c75f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h3 class=\"elementor-heading-title elementor-size-default\">If you enjoy my work and have the means to support me, I opened three channels for it, or you can always hire my skills for commissions.<\/h3>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-1e98b5e elementor-widget elementor-widget-html\" data-id=\"1e98b5e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<ul class=\"funding\">\r\n  <li><span class=\"n\">1<\/span>\r\n    <span><strong>Buy me a cappucino.<\/strong> Small fuel, gratefully burned. Lactose free. \u2014\r\n    <a href=\"#\">buymeacoffee<\/a>.<\/span><\/li>\r\n  <li><span class=\"n\">2<\/span>\r\n    <span><strong>Sponsor the experiments.<\/strong> The goal is to create open source applications. Every sponsored hour is an hour the lab spends experimenting\r\n    instead of invoicing \u2014 <a href=\"https:\/\/cseperkepapp.github.io\/\">GitHub Sponsors<\/a>.<\/span><\/li>\r\n  <li><span class=\"n\">3<\/span>\r\n    <span><strong>Commission the lab.<\/strong> How it runs today: a limited number of client\r\n    projects a year, chosen for fit. The biggest single way to fund the work, it just borrows the scientist while it does \u2014  <a href=\"#\">Digital Presence<\/a><\/span><\/li>\r\n<\/ul>\r\n\r\n<style>\r\n.funding{ list-style:none; margin:0; padding:0; max-width:46rem; }\r\n.funding li{\r\n  display:grid; grid-template-columns:auto 1fr; gap:1.5rem; align-items:baseline;\r\n  padding:1.5rem 0;\r\n  border-bottom:1px solid rgba(147,148,152,.25);   \/* your neutral #939498 at 25% *\/\r\n}\r\n.funding .n{\r\n  font-family:'Cormorant Unicase', serif; font-size:2rem; line-height:1;\r\n  color:var(--e-global-color-457a0a7);              \/* your kit #D2C2AA *\/\r\n}\r\n.funding strong{ color:var(--e-global-color-primary); }  \/* #C0D8D5 *\/\r\n.funding a{ color:var(--e-global-color-accent); text-decoration:none; }  \/* #6EB4BA *\/\r\n.funding a:hover{ color:var(--e-global-color-primary); }\r\n<\/style>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-0030361 e-flex e-con-boxed e-con e-parent\" data-id=\"0030361\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;jet_parallax_layout_list&quot;:[]}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-e2f3530 elementor-widget elementor-widget-html\" data-id=\"e2f3530\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!-- ============================================================\n     THE TIGHTROPE WALKER \u2014 full-width variant, standalone Elementor HTML widget\n     2026-07-18 \u00b7 from home-v3-juggler\n\n     WHAT IT DOES\n     Same as elementor-ropewalker-widget.html, except the rope spans\n     the full viewport width edge-to-edge instead of being capped to\n     the site's 1120px content column. Use this version if the widget\n     sits in a full-width Elementor section, or if you just want the\n     rope to run all the way to both screen edges regardless of layout.\n\n     HOW TO INSTALL\n     1. Elementor \u2192 add an HTML widget anywhere on the page\n        (bottom of the page is tidy, but position doesn't matter \u2014\n        the walker fixes itself to the viewport bottom).\n     2. Paste this entire file into the widget. Done.\n     3. Site-wide: put the widget in your Elementor footer template.\n\n     NOTES\n     \u00b7 No dependencies. No GSAP, no jQuery \u2014 self-contained.\n     \u00b7 Everything is scoped under #cspRopeWalk; nothing leaks into\n       your theme, and your theme can't break it.\n     \u00b7 One caveat: the parent Elementor section must NOT have Motion\n       Effects \/ CSS transforms \u2014 transforms trap position:fixed.\n       A plain section is fine.\n     \u00b7 pointer-events: none \u2014 it never blocks clicks.\n     \u00b7 prefers-reduced-motion: she stands still, no spring, no act.\n     \u00b7 Only diff from the capped version: the svg rule below drops\n       max-width\/margin:auto and uses a small fixed side inset instead\n       of the site's clamp() gutter, so the rope reaches both edges.\n     ============================================================ -->\n\n<div id=\"cspRopeWalk\" aria-hidden=\"true\">\n  <svg viewBox=\"0 0 1000 56\" preserveAspectRatio=\"none\">\n    <path class=\"csp-rope\" id=\"cspRopePath\" d=\"M0,20 Q500,44 1000,20\"\/>\n    <g class=\"csp-end\" id=\"cspEndL\" transform=\"translate(0,20)\"><circle r=\"2.6\"\/><\/g>\n    <g class=\"csp-end\" id=\"cspEndR\" transform=\"translate(1000,20)\"><circle r=\"2.6\"\/><\/g>\n    <g id=\"cspWalker\">\n      <g class=\"csp-poise\">\n        <g class=\"csp-body\">\n          <g id=\"cspLegF\" transform=\"translate(0,-10) rotate(10)\"><path d=\"M0,0 L1.2,5.4 L1.6,9.7\"\/><\/g>\n          <g id=\"cspLegB\" transform=\"translate(0,-10) rotate(-10)\"><path d=\"M0,0 L-0.5,5.3 L-1.1,9.6\"\/><\/g>\n        <\/g>\n        <g id=\"cspBob\">\n          <path class=\"csp-pole\" id=\"cspPole\" d=\"M-34,-10.5 Q0,-17.5 34,-10.5\"\/>\n          <g class=\"csp-body\">\n            <line x1=\"0\" y1=\"-10\" x2=\"0\" y2=\"-16.4\"\/>\n            <path id=\"cspArms\" d=\"M-0.2,-15.8 L-7,-14.4 M0.2,-15.8 L7,-14.4\"\/>\n          <\/g>\n          <circle class=\"csp-head\" cx=\"0\" cy=\"-20.4\" r=\"3\"\/>\n          <g id=\"cspCap\">\n            <path class=\"csp-caph\" d=\"M-3.1,-21.2 Q0,-23.8 3.1,-21.2\"\/>\n            <g transform=\"translate(-1.7,-22.4)\">\n              <g id=\"cspHornL\"><path class=\"csp-caph\" d=\"M0,0 Q-2.8,-3.4 -5.4,-2\"\/>\n                <circle class=\"csp-bell\" cx=\"-5.7\" cy=\"-1.8\" r=\"0.95\"\/><\/g>\n            <\/g>\n            <g transform=\"translate(1.5,-22.7)\">\n              <g id=\"cspHornR\"><path class=\"csp-caph\" d=\"M0,0 Q1.3,-4.6 4,-3.4\"\/>\n                <circle class=\"csp-bell\" cx=\"4.3\" cy=\"-3.3\" r=\"0.95\"\/><\/g>\n            <\/g>\n          <\/g>\n          <g id=\"cspBalls\" opacity=\"0\">\n            <circle r=\"1.8\" class=\"csp-b1\" cx=\"-3.5\" cy=\"-12.7\"\/>\n            <circle r=\"1.8\" class=\"csp-b2\" cx=\"0\" cy=\"-27\"\/>\n            <circle r=\"1.8\" class=\"csp-b3\" cx=\"3.5\" cy=\"-12.7\"\/>\n          <\/g>\n        <\/g>\n      <\/g>\n    <\/g>\n  <\/svg>\n<\/div>\n\n<style>\n#cspRopeWalk{\n  \/* the kit, locally scoped \u2014 change these four to retheme her *\/\n  --csp-teal:  #6EB4BA;\n  --csp-parch: #D2C2AA;\n  --csp-spark: #FD6B34;\n  --csp-bg:    #1C1C1C;\n\n  position: fixed; left:0; right:0; bottom:0;\n  height:56px; z-index:90;\n  pointer-events:none;\n}\n#cspRopeWalk::before{\n  content:\"\"; position:absolute; inset:-22px 0 0; z-index:-1;\n  background: linear-gradient(to top,\n    var(--csp-bg) 0%,\n    color-mix(in oklab, var(--csp-bg) 86%, transparent) 55%,\n    transparent 100%);\n  backdrop-filter: blur(4px);\n}\n\/* full-width: no max-width cap, no centering \u2014 edge to edge, with a\n   small fixed inset so the rope-end circles aren't flush against the\n   literal screen edge. *\/\n#cspRopeWalk svg{\n  width:100%; height:100%; display:block; overflow:visible;\n  padding:0 clamp(0.5rem, 2vw, 1.5rem);\n  box-sizing:border-box;\n}\n#cspRopeWalk .csp-rope{ stroke:#939498; stroke-width:1.5; fill:none; opacity:.8; }\n#cspRopeWalk .csp-end circle{ fill: var(--csp-teal); }\n#cspRopeWalk .csp-pole{ stroke: var(--csp-parch); stroke-width:1.2; fill:none; stroke-linecap:round; }\n#cspRopeWalk .csp-body path, #cspRopeWalk .csp-body line{\n  stroke: var(--csp-teal); stroke-width:1.4; fill:none;\n  stroke-linecap:round; stroke-linejoin:round;\n}\n#cspRopeWalk .csp-head{ fill: var(--csp-spark); }\n#cspRopeWalk .csp-caph{ stroke: var(--csp-parch); stroke-width:1.2; fill:none; stroke-linecap:round; }\n#cspRopeWalk .csp-bell{ fill: var(--csp-spark); }\n#cspRopeWalk .csp-b1{ fill: var(--csp-teal); }\n#cspRopeWalk .csp-b2{ fill: var(--csp-parch); }\n#cspRopeWalk .csp-b3{ fill: var(--csp-spark); }\n#cspRopeWalk .csp-poise{\n  transform-box: fill-box; transform-origin: 50% 100%;\n  animation: cspPoise 7s ease-in-out infinite;\n}\n@keyframes cspPoise{\n  0%{ transform: rotate(0deg); } 30%{ transform: rotate(2.4deg); }\n  55%{ transform: rotate(-2.8deg); } 70%{ transform: rotate(1.2deg); }\n  85%{ transform: rotate(-1.6deg); } 100%{ transform: rotate(0deg); }\n}\n@media (prefers-reduced-motion: reduce){\n  #cspRopeWalk .csp-poise{ animation:none; }\n}\n<\/style>\n\n<script>\n\/* The equilibrist. Deterministic, dependency-free, boring on purpose. *\/\n(function () {\n  'use strict';\n\n  var root = document.getElementById('cspRopeWalk');\n  if (!root) { return; }\n  var reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n  function $(id){ return document.getElementById(id); }\n\n  var svg = root.querySelector('svg');\n  var rope = $('cspRopePath'), walker = $('cspWalker');\n  var legF = $('cspLegF'), legB = $('cspLegB'), pole = $('cspPole'), bob = $('cspBob');\n  var hornL = $('cspHornL'), hornR = $('cspHornR');\n  var armsEl = $('cspArms'), ballsG = $('cspBalls');\n  var balls = ballsG ? Array.prototype.slice.call(ballsG.querySelectorAll('circle')) : [];\n  if (!rope || !walker) { return; }\n\n  \/* ---------- geometry ---------- *\/\n  var len = rope.getTotalLength(), sx = 1;\n  function measure(){\n    var w = svg.getBoundingClientRect().width;\n    sx = w > 0 ? 1000 \/ w : 1;\n    var eL = $('cspEndL'), eR = $('cspEndR');\n    if (eL) { eL.setAttribute('transform', 'translate(0,20) scale(' + sx.toFixed(4) + ',1)'); }\n    if (eR) { eR.setAttribute('transform', 'translate(1000,20) scale(' + sx.toFixed(4) + ',1)'); }\n  }\n  function renderRope(){\n    var cx = 200 + 600 * lastU;\n    var cy = 20 + 96 * lastU * (1 - lastU) + dyn;\n    rope.setAttribute('d', 'M0,20 Q' + cx.toFixed(1) + ',' + cy.toFixed(2) + ' 1000,20');\n    len = rope.getTotalLength();\n  }\n  function placeWalker(u){\n    var p = rope.getPointAtLength(u * len);\n    var p2 = rope.getPointAtLength(Math.min(1, u + 0.01) * len);\n    var angle = Math.atan2(p2.y - p.y, p2.x - p.x) * 180 \/ Math.PI;\n    walker.setAttribute('transform',\n      'translate(' + p.x + ',' + (p.y - 0.5) + ') rotate(' + angle.toFixed(2) +\n      ') scale(' + sx.toFixed(4) + ',1)');\n  }\n  function progress(){\n    var doc = document.documentElement;\n    var max = doc.scrollHeight - window.innerHeight;\n    return max > 0 ? Math.max(0, Math.min(1, window.scrollY \/ max)) : 0;\n  }\n\n  \/* ---------- the fool's cap: horns on a lagging spring ---------- *\/\n  var capA = 0, capPose = 0, capSpring = 0;\n  function applyCap(){\n    if (!hornL) { return; }\n    var target = Math.max(-38, Math.min(38, capPose + capSpring));\n    capA += (target - capA) * 0.16;\n    hornL.setAttribute('transform', 'rotate(' + capA.toFixed(1) + ')');\n    hornR.setAttribute('transform', 'rotate(' + (capA * 0.7 - 3).toFixed(1) + ')');\n  }\n\n  \/* ---------- the walk cycle ---------- *\/\n  var STRIDE = 18, curSwing = 10;\n  function applyPose(swing){\n    if (!legF) { return; }\n    if (!reduced && ((swing < 0) !== (curSwing < 0)) && Math.abs(swing - curSwing) < 30) {\n      kick(3);   \/* footfall *\/\n    }\n    capPose = (curSwing - swing) * 2.4;\n    curSwing = swing;\n    legF.setAttribute('transform', 'translate(0,-10) rotate(' + swing.toFixed(1) + ')');\n    legB.setAttribute('transform', 'translate(0,-10) rotate(' + (-swing).toFixed(1) + ')');\n    if (jugState === 'none') {\n      pole.setAttribute('transform', 'rotate(' + (-swing * 0.14).toFixed(2) + ')');\n    }\n    bob.setAttribute('transform', 'translate(0,' +\n      (-0.8 * (1 - Math.abs(swing) \/ 24)).toFixed(2) + ')');\n    applyCap();\n  }\n\n  \/* ---------- the rope spring ---------- *\/\n  var dyn = 0, dynV = 0;\n  function kick(v){\n    if (reduced) { return; }\n    dynV = Math.max(-46, Math.min(46, dynV + v));\n  }\n\n  \/* ---------- the intermission: juggling ---------- *\/\n  var ARMS_HOLD = 'M-0.2,-15.8 L-7,-14.4 M0.2,-15.8 L7,-14.4';\n  var ARMS_JUG  = 'M-0.2,-15.8 L-5,-13.4 L-4,-11.9 M0.2,-15.8 L5,-13.4 L4,-11.9';\n  var jugState = 'none', jugStart = 0, jugT0 = 0, armsSwapped = false;\n  var prevP = [0, 0, 0];\n  function ballPos(p){\n    var a = p * Math.PI * 2;\n    var cy = -15.5, rx = 8;\n    var vert = -Math.cos(a);\n    var ry = vert > 0 ? 12 : 6;\n    return [rx * Math.sin(a), cy - vert * ry];\n  }\n  function startJuggle(now){\n    if (reduced || !armsEl || !balls.length) { return; }\n    jugState = 'drop'; jugStart = now; armsSwapped = false;\n  }\n  function stopJuggle(){\n    if (jugState === 'none') { return; }\n    jugState = 'none';\n    ballsG.setAttribute('opacity', '0');\n    armsEl.setAttribute('d', ARMS_HOLD);\n    pole.removeAttribute('transform');\n  }\n  function juggleFrame(now){\n    if (jugState === 'drop') {\n      var k = Math.min(1, (now - jugStart) \/ 550);\n      var e = k * k * (3 - 2 * k);\n      pole.setAttribute('transform', 'translate(' + (-11 * e).toFixed(2) + ',' +\n        (13.4 * e).toFixed(2) + ') rotate(' + (9 * e).toFixed(2) + ')');\n      if (!armsSwapped && k > 0.55) { armsSwapped = true; armsEl.setAttribute('d', ARMS_JUG); }\n      if (k >= 1) {\n        jugState = 'juggling'; jugT0 = now; prevP = [0, 1 \/ 3, 2 \/ 3];\n        ballsG.setAttribute('opacity', '1');\n      }\n      return;\n    }\n    var tt = (now - jugT0) \/ 1000 * 0.55;\n    for (var i = 0; i < 3; i++) {\n      var p = (tt + i \/ 3) % 1;\n      var pos = ballPos(p);\n      balls[i].setAttribute('cx', pos[0].toFixed(2));\n      balls[i].setAttribute('cy', pos[1].toFixed(2));\n      if (prevP[i] > p) { kick(0.9); }\n      prevP[i] = p;\n    }\n    bob.setAttribute('transform', 'translate(0,' +\n      (0.4 * Math.sin(tt * Math.PI * 6)).toFixed(2) + ')');\n    applyCap();\n  }\n\n  \/* ---------- the main loop ---------- *\/\n  var lastU = 0.045, uAtRest = 0.045, dispT = -0.045, prevTs = null;\n  var resting = true, restSince = 0, movedSince = 0, everMoved = false;\n\n  function frame(ts){\n    window.requestAnimationFrame(frame);\n    if (document.hidden) { prevTs = null; return; }\n    if (prevTs === null) { prevTs = ts; }\n    var dt = Math.min(0.05, (ts - prevTs) \/ 1000);\n    prevTs = ts;\n\n    \/* smoothing: she trails the scroll like a walker, not a scrollbar *\/\n    var target = progress();\n    if (reduced) { dispT = target; }\n    else { dispT += (target - dispT) * Math.min(1, dt * 3.4); }\n\n    var u = 0.045 + dispT * 0.94;\n    var moving = Math.abs(u - lastU) > 0.00035;\n\n    if (moving) {\n      movedSince = ts; everMoved = true;\n      stopJuggle();\n      if (resting) {\n        resting = false;\n        kick(22);            \/* push-off *\/\n      }\n    } else if (!resting && ts - movedSince > 420) {\n      resting = true; restSince = ts;\n      if (Math.abs(u - uAtRest) > 0.015) { kick(13); }   \/* landing *\/\n      uAtRest = u;\n    }\n\n    \/* legs: walking, or easing into a stand *\/\n    if (!reduced) {\n      if (moving) {\n        var phase = (u * len \/ STRIDE) * Math.PI;\n        applyPose(24 * Math.sin(phase));\n      } else if (Math.abs(curSwing) > 10.5 || (curSwing !== 10 && curSwing !== -10)) {\n        var st = curSwing >= 0 ? 10 : -10;\n        var d = st - curSwing;\n        if (Math.abs(d) < 0.4) { applyPose(st); }\n        else { applyPose(curSwing + d * 0.14); }\n      }\n    }\n\n    \/* the act, one second after she has settled *\/\n    if (!reduced && resting && everMoved && jugState === 'none' &&\n        ts - restSince > 1000) {\n      startJuggle(ts);\n    }\n    if (jugState !== 'none') { juggleFrame(ts); }\n\n    \/* the spring *\/\n    if (!reduced && (Math.abs(dyn) > 0.02 || Math.abs(dynV) > 0.02)) {\n      dynV += (-88 * dyn - 5 * dynV) * dt;\n      dyn += dynV * dt;\n      capSpring = -dynV * 0.55;\n      applyCap();\n    } else { dyn = 0; dynV = 0; capSpring = 0; }\n\n    lastU = u;\n    renderRope();\n    placeWalker(u);\n  }\n  measure();\n  window.addEventListener('resize', measure, { passive: true });\n  renderRope();\n  placeWalker(0.045 + dispT * 0.94);\n  window.requestAnimationFrame(frame);\n}());\n<\/script>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>the laboratory Digital Experiments The common thread is visualization \u2014 systems made visible. Typographic engines, manuscript-flavored interfaces, motion tools, timelines, breathing worlds: different shapes of an inspired craft. Decision Themes A design system generator that shows its math \u2014 whole visual systems derived from a handful of decisions. studio DTS Experience the system DTS Studio [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_header_footer","meta":{"footnotes":""},"class_list":["post-14980","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/pappcseperke.hu\/hu\/wp-json\/wp\/v2\/pages\/14980","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pappcseperke.hu\/hu\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/pappcseperke.hu\/hu\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/pappcseperke.hu\/hu\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/pappcseperke.hu\/hu\/wp-json\/wp\/v2\/comments?post=14980"}],"version-history":[{"count":67,"href":"https:\/\/pappcseperke.hu\/hu\/wp-json\/wp\/v2\/pages\/14980\/revisions"}],"predecessor-version":[{"id":16014,"href":"https:\/\/pappcseperke.hu\/hu\/wp-json\/wp\/v2\/pages\/14980\/revisions\/16014"}],"wp:attachment":[{"href":"https:\/\/pappcseperke.hu\/hu\/wp-json\/wp\/v2\/media?parent=14980"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}