{"id":2191,"date":"2026-04-21T19:44:29","date_gmt":"2026-04-21T17:44:29","guid":{"rendered":"https:\/\/zulumaps.com\/soundwave\/"},"modified":"2026-04-28T20:17:43","modified_gmt":"2026-04-28T18:17:43","slug":"soundwave","status":"publish","type":"page","link":"https:\/\/zulumaps.com\/de\/soundwave\/","title":{"rendered":"Soundwave"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"2191\" class=\"elementor elementor-2191 elementor-1200\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-db3b44b e-con-full e-flex e-con e-parent\" data-id=\"db3b44b\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-0d8fc1a elementor-widget elementor-widget-html\" data-id=\"0d8fc1a\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!DOCTYPE html>\r\n<html lang=\"de\">\r\n<head>\r\n<meta charset=\"UTF-8\">\r\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n<title>Musicmap Editor<\/title>\r\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=DM+Sans:wght@300;400;500;700&family=Montserrat:wght@400;600;700;800&family=Poppins:wght@400;500;600&display=swap\" rel=\"stylesheet\"\/>\r\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/html2canvas\/1.4.1\/html2canvas.min.js\"><\/script>\r\n<style>\r\n*,*::before,*::after{box-sizing:border-box;margin:0;padding:0;}\r\nhtml,body{overflow-x:hidden;}\r\n.pme{display:flex;width:100vw;height:100%;font-family:'DM Sans',sans-serif;color:#1a1a1a;background:#ffffff;}\r\n.pme-nav{width:64px;min-width:64px;background:#1a1a1a;display:flex;flex-direction:column;align-items:center;padding:12px 0;gap:4px;}\r\n.pme-nav-btn{width:52px;height:56px;background:transparent;border:none;border-radius:8px;cursor:pointer;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;color:#888;font-size:12px;font-family:'DM Sans',sans-serif;transition:all 0.15s;}\r\n.pme-nav-btn:hover{color:#fff;background:rgba(255,255,255,0.08);}\r\n.pme-nav-btn.active{color:#fff;background:rgba(255,255,255,0.12);}\r\n.pme-nav-btn svg{width:20px;height:20px;}\r\n.pme-panel{width:416px;min-width:416px;background:#e7e7e7;border-right:1px solid #e8e8e8;overflow-y:auto;display:flex;flex-direction:column;}\r\n.pme-section{display:none;padding:24px 24px 32px;}\r\n.pme-section.active{display:block;}\r\n.pme-title{font-size:22px;font-weight:600;margin-bottom:6px;}\r\n.pme-desc{font-size:13px;color:#666;margin-bottom:20px;line-height:1.5;}\r\n.pme-lbl{font-size:11px;font-weight:500;letter-spacing:0.08em;text-transform:uppercase;color:#1a1a1a;margin-bottom:10px;margin-top:20px;display:block;}\r\n.pme-field{margin-bottom:14px;}\r\n.pme-field label{display:block;font-size:11px;font-weight:500;text-transform:uppercase;letter-spacing:0.06em;color:#999;margin-bottom:6px;}\r\n.pme-field input{width:100%;border:1.5px solid #e0e0e0;border-radius:8px;padding:10px 12px;font-size:14px;font-family:'DM Sans',sans-serif;outline:none;}\r\n.pme-field input:focus{border-color:#1a1a1a;}\r\n\r\n.pme-search{position:relative;margin-bottom:8px;}\r\n.pme-search input{width:100%;border:1.5px solid #e0e0e0;border-radius:8px;padding:10px 12px 10px 36px;font-size:14px;font-family:'DM Sans',sans-serif;outline:none;background:#fafafa;}\r\n.pme-search input:focus{border-color:#1a1a1a;background:#fff;}\r\n.pme-sic{position:absolute;left:11px;top:50%;transform:translateY(-50%);color:#aaa;pointer-events:none;}\r\n.pme-results{display:none;background:#fff;border:1px solid #e0e0e0;border-radius:8px;margin-top:4px;overflow:hidden;box-shadow:0 4px 16px rgba(0,0,0,0.08);z-index:100;position:absolute;left:0;right:0;max-height:250px;overflow-y:auto;}\r\n.pme-results.show{display:block;}\r\n.pme-ri{padding:10px 14px;font-size:13px;cursor:pointer;border-bottom:1px solid #f0f0f0;}\r\n.pme-ri:last-child{border-bottom:none;}\r\n.pme-ri:hover{background:#f8f8f8;}\r\n.pme-ri strong{display:block;font-weight:500;}\r\n.pme-ri span{color:#888;font-size:12px;}\r\n\r\n.pme-pop-lbl{font-size:11px;font-weight:600;letter-spacing:0.06em;text-transform:uppercase;color:#999;margin:24px 0 10px;}\r\n.pme-pop{list-style:none;}\r\n.pme-pop li{padding:9px 0;font-size:14px;color:#444;cursor:pointer;}\r\n.pme-pop li:hover{color:#1a1a1a;}\r\n\r\n.theme-pins { display: flex; flex-wrap: wrap; gap: 14px; margin-bottom: 24px; justify-content: flex-start; }\r\n.pme-thm { border: none !important; border-radius: 0 !important; padding: 0 !important; cursor: pointer !important; background: transparent !important; display: flex; flex-direction: column; align-items: center; gap: 8px; width: 68px; outline: none !important; box-shadow: none !important;}\r\n.pme-thm-circle { width: 60px; height: 60px; border-radius: 50%; border: 3px solid #e0e0e0; transition: border-color 0.2s; }\r\n.pme-thm:hover .pme-thm-circle { border-color: #a0a0a0; }\r\n.pme-thm.active .pme-thm-circle { border-color: #1a1a1a; }\r\n.pme-thm span { font-size: 11px; color: #1a1a1a; font-weight: 500; font-family:'DM Sans',sans-serif; text-align: center; line-height: 1.2;}\r\n\r\n.shape-pins { display: flex; flex-wrap: wrap; gap: 14px; margin-bottom: 24px; justify-content: flex-start; }\r\n.shape-btn { border: none !important; border-radius: 0 !important; padding: 0 !important; cursor: pointer !important; background: transparent !important; display: flex; flex-direction: column; align-items: center; gap: 8px; width: 68px; outline: none !important; box-shadow: none !important;}\r\n.shape-icon { width: 60px; height: 60px; border-radius: 50%; border: 3px solid #e0e0e0; transition: border-color 0.2s; box-shadow: inset 0 0 0 2px #fff; background: #fafafa; display: flex; align-items: center; justify-content: center; color:#1a1a1a;}\r\n.shape-btn:hover .shape-icon { border-color: #a0a0a0; }\r\n.shape-btn.active .shape-icon { border-color: #1a1a1a; }\r\n.shape-btn span { font-size: 11px; color: #1a1a1a; font-weight: 500; font-family:'DM Sans',sans-serif;}\r\n.shape-icon svg { width: 26px; height: 26px; }\r\n\r\n.pme-frame{border:1.5px solid #d0d0d0;border-radius:8px;padding:12px 4px;text-align:center;font-size:13px;font-weight:500;cursor:pointer;background:#fff;font-family:'DM Sans',sans-serif;color:#1a1a1a;transition:border 0.15s;}\r\n.pme-frame:hover,.pme-frame.active{border:2.5px solid #1a1a1a!important;background:#fff!important;color:#1a1a1a!important;}\r\n.pme-orients{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:14px;}\r\n.pme-or{border:1.5px solid #d0d0d0;border-radius:8px;padding:12px;text-align:center;font-size:13px;font-weight:500;cursor:pointer;background:#fff!important;font-family:'DM Sans',sans-serif;color:#1a1a1a!important;transition:border 0.15s;}\r\n.pme-or:hover,.pme-or.active{border:2.5px solid #1a1a1a!important;background:#fff!important;color:#1a1a1a!important;}\r\n\r\n#size-dropdown,#mat-dropdown{position:relative;margin-bottom:14px;}\r\n.dd-selected{width:100%;border:1.5px solid #e0e0e0;border-radius:8px;padding:10px 12px;font-size:14px;font-family:'DM Sans',sans-serif;background:#fafafa;cursor:pointer;display:flex;justify-content:space-between;align-items:center;user-select:none;}\r\n.dd-options{display:none;position:absolute;top:100%;left:0;right:0;background:#fff;border:1.5px solid #e0e0e0;border-radius:8px;margin-top:4px;z-index:200;overflow:hidden;box-shadow:0 4px 16px rgba(0,0,0,0.08); max-height:250px; overflow-y:auto;}\r\n.size-opt{padding:10px 12px;font-size:14px;font-family:'DM Sans',sans-serif;cursor:pointer;border-bottom:1px solid #f0f0f0;}\r\n.size-opt:hover{background:#f5f5f5;}\r\n\r\n.pme-canvas{flex:1;min-width:0;min-height:0;background:#F9F6F0;display:flex;align-items:center;justify-content:center;position:relative;overflow:hidden;align-self:stretch;}\r\n.pme-outer{position:relative;}\r\n\r\n\/* POSTER DESIGN *\/\r\n.pme-poster{background:#fff;padding:16px;position:relative;display:flex;flex-direction:column;border:1px solid hsl(0,0%,85%);box-shadow:0 6px 40px hsl(0,0%,60%,0.45),0 2px 12px hsl(0,0%,50%,0.25); box-sizing:border-box;}\r\n.pme-poster.is-framed::after{content:'';position:absolute;top:0;left:0;right:0;bottom:0;box-shadow:inset 0 3px 18px rgba(0,0,0,0.25);pointer-events:none;z-index:20;}\r\n.pme-poster-inner{flex:1;background:#000000;display:flex;flex-direction:column;align-items:center;position:relative;width:100%;height:100%;overflow:hidden; transition: background-color 0.3s;}\r\n\r\n.music-visual { flex: 1; width: 100%; position: relative; overflow: hidden; display: flex; align-items: center; justify-content: center; margin-top: 10px; }\r\n.music-visual canvas { display: block; width: 100%; height: 100%; object-fit: contain; }\r\n\r\n.music-footer { width: 100%; text-align: center; padding: 15px 20px 25px; display: flex; flex-direction: column; align-items: center; font-family: 'Montserrat', sans-serif; color: #ffffff; transition: color 0.3s;}\r\n.mf-h1 { font-size: 14px; font-weight: 800; letter-spacing: 0.15em; margin-bottom: 5px; text-transform: uppercase; }\r\n.mf-h2 { font-size: 8px; font-weight: 600; letter-spacing: 0.25em; text-transform: uppercase; margin-bottom: 25px; opacity: 0.9; }\r\n.mf-b1 { font-size: 7px; font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase; margin-bottom: 3px; opacity: 0.9;}\r\n.mf-b2 { font-size: 8px; font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase; }\r\n\r\n.pme-dimr{position:absolute;right:-22px;top:0;bottom:0;display:flex;align-items:center;pointer-events:none;}\r\n.pme-dimr span{writing-mode:vertical-rl;font-size:11px;color:#aaa;white-space:nowrap;}\r\n.pme-dimb{position:absolute;bottom:-22px;left:0;right:0;display:flex;justify-content:center;pointer-events:none;}\r\n.pme-dimb span{font-size:11px;color:#aaa;}\r\n\r\n.pme-bar{background:#1a1a1a;display:flex;align-items:center;padding:16px 24px;gap:12px;margin-top:auto;}\r\n.pme-prices{display:flex;align-items:baseline;gap:6px;}\r\n.pme-old{font-size:12px;color:#888;text-decoration:line-through;}\r\n.pme-new{font-size:17px;font-weight:600;color:#fff;}\r\n.pme-cart{background:#7E5AF0;color:#ffffff;border:none;border-radius:25px;padding:10px 14px;font-size:18px;font-weight:400;font-family:'Poppins',sans-serif;cursor:pointer;flex:1;display:flex;align-items:center;justify-content:center;gap:6px;transition:background 0.15s,color 0.15s;}\r\n.pme-cart:hover{background:#632ED3!important;color:#ffffff!important;border:none!important;}\r\n\r\n@media(max-width:768px){\r\n  .pme{flex-direction:column; height:auto!important; min-height:100vh;}\r\n  .pme-nav{display:none;}\r\n  .pme-panel{width:100%!important; min-width:0!important; border-right:none; border-top:1px solid #e8e8e8; max-height:none!important; height:auto!important; overflow-y:visible!important; order:3;}\r\n  .pme-canvas{order:1; flex:none!important; height:65vh!important; min-height:380px;}\r\n  .pme-mobnav{display:flex!important; order:2; height:71px!important; flex:0 0 71px!important;}\r\n  .pme-section{padding:16px 16px 24px;}\r\n}\r\n\r\n.pme-mobnav{display:none;width:100%;background:#1a1a1a;overflow-x:auto;scrollbar-width:none;}\r\n.pme-mobnav::-webkit-scrollbar{display:none;}\r\n.pme-mobbtn{flex:1;min-width:60px;height:71px;background:transparent;border:none;cursor:pointer;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;color:#888;font-size:14px;font-family:'DM Sans',sans-serif;}\r\n.pme-mobbtn.active{color:#fff;}\r\n.pme-mobbtn svg{width:24px;height:24px;}\r\n<\/style>\r\n<\/head>\r\n<body>\r\n\r\n<div class=\"pme\" id=\"pme-root\">\r\n  <nav class=\"pme-nav\">\r\n    <button class=\"pme-nav-btn active\" data-panel=\"song\">\r\n      <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\"><path d=\"M9 18V5l12-2v13\"\/><circle cx=\"6\" cy=\"18\" r=\"3\"\/><circle cx=\"18\" cy=\"16\" r=\"3\"\/><\/svg>Song\r\n    <\/button>\r\n    <button class=\"pme-nav-btn\" data-panel=\"labels\">\r\n      <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\"><path d=\"M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7\"\/><path d=\"M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z\"\/><\/svg>Texte\r\n    <\/button>\r\n    <button class=\"pme-nav-btn\" data-panel=\"style\">\r\n      <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\"><rect x=\"3\" y=\"3\" width=\"7\" height=\"7\"\/><rect x=\"14\" y=\"3\" width=\"7\" height=\"7\"\/><rect x=\"14\" y=\"14\" width=\"7\" height=\"7\"\/><rect x=\"3\" y=\"14\" width=\"7\" height=\"7\"\/><\/svg>Stil\r\n    <\/button>\r\n    <button class=\"pme-nav-btn\" data-panel=\"size\">\r\n      <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\"><path d=\"M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7\"\/><\/svg>Gr\u00f6\u00dfe\r\n    <\/button>\r\n  <\/nav>\r\n\r\n  <div class=\"pme-mobnav\">\r\n    <button class=\"pme-mobbtn active\" data-panel=\"song\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\"><path d=\"M9 18V5l12-2v13\"\/><circle cx=\"6\" cy=\"18\" r=\"3\"\/><circle cx=\"18\" cy=\"16\" r=\"3\"\/><\/svg>Song<\/button>\r\n    <button class=\"pme-mobbtn\" data-panel=\"labels\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\"><path d=\"M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7\"\/><path d=\"M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z\"\/><\/svg>Texte<\/button>\r\n    <button class=\"pme-mobbtn\" data-panel=\"style\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\"><rect x=\"3\" y=\"3\" width=\"7\" height=\"7\"\/><rect x=\"14\" y=\"3\" width=\"7\" height=\"7\"\/><rect x=\"14\" y=\"14\" width=\"7\" height=\"7\"\/><rect x=\"3\" y=\"14\" width=\"7\" height=\"7\"\/><\/svg>Stil<\/button>\r\n    <button class=\"pme-mobbtn\" data-panel=\"size\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\"><path d=\"M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7\"\/><\/svg>Gr\u00f6\u00dfe<\/button>\r\n  <\/div>\r\n\r\n  <div class=\"pme-panel\">\r\n    \r\n    <div class=\"pme-section active\" id=\"sec-song\">\r\n      <div class=\"pme-title\">Song<\/div>\r\n      <div class=\"pme-desc\">Suche nach deinem Lieblingssong, um seinen einzigartigen visuellen Fingerabdruck zu generieren.<\/div>\r\n      \r\n      <div style=\"position:relative; margin-bottom:14px;\">\r\n        <div class=\"pme-search\" style=\"margin-bottom:0;\">\r\n          <svg class=\"pme-sic\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"11\" cy=\"11\" r=\"8\"\/><path d=\"m21 21-4.35-4.35\"\/><\/svg>\r\n          <input type=\"text\" id=\"inp-search\" value=\"One Love - Bob Marley\" placeholder=\"Suche nach einem Song...\" autocomplete=\"off\"\/>\r\n        <\/div>\r\n        <div class=\"pme-results\" id=\"song-results\"><\/div>\r\n      <\/div>\r\n      \r\n      <div class=\"pme-pop-lbl\">Beliebte Songs<\/div>\r\n      <ul class=\"pme-pop\">\r\n        <li data-name=\"Blinding Lights\" data-artist=\"The Weeknd\" data-album=\"After Hours\" data-year=\"2019\">Blinding Lights - The Weeknd<\/li>\r\n        <li data-name=\"Shape of You\" data-artist=\"Ed Sheeran\" data-album=\"\u00f7 (Divide)\" data-year=\"2017\">Shape of You - Ed Sheeran<\/li>\r\n        <li data-name=\"Someone You Loved\" data-artist=\"Lewis Capaldi\" data-album=\"Divinely Uninspired to a Hellish Extent\" data-year=\"2018\">Someone You Loved - Lewis Capaldi<\/li>\r\n        <li data-name=\"Sunflower\" data-artist=\"Post Malone\" data-album=\"Hollywood's Bleeding\" data-year=\"2018\">Sunflower - Post Malone<\/li>\r\n        <li data-name=\"Starboy\" data-artist=\"The Weeknd\" data-album=\"Starboy\" data-year=\"2016\">Starboy - The Weeknd<\/li>\r\n        <li data-name=\"As It Was\" data-artist=\"Harry Styles\" data-album=\"Harry's House\" data-year=\"2022\">As It Was - Harry Styles<\/li>\r\n        <li data-name=\"Dance Monkey\" data-artist=\"Tones And I\" data-album=\"The Kids Are Coming\" data-year=\"2019\">Dance Monkey - Tones And I<\/li>\r\n      <\/ul>\r\n    <\/div>\r\n\r\n    <div class=\"pme-section\" id=\"sec-labels\">\r\n      <div class=\"pme-title\">Texte<\/div>\r\n      <div class=\"pme-desc\">Passe den Text auf deiner Musikkarte an.<\/div>\r\n      \r\n      <span class=\"pme-lbl\">Titel<\/span>\r\n      <div class=\"pme-field\"><input type=\"text\" id=\"inp-h1\" value=\"One Love\" \/><\/div>\r\n      \r\n      <span class=\"pme-lbl\">Trenntext<\/span>\r\n      <div class=\"pme-field\"><input type=\"text\" id=\"inp-h2\" value=\"Bob Marley\" \/><\/div>\r\n\r\n      <span class=\"pme-lbl\">Zusatztext<\/span>\r\n      <div class=\"pme-field\"><input type=\"text\" id=\"inp-b1\" value=\"Exodus\" \/><\/div>\r\n      \r\n      <span class=\"pme-lbl\">Unterzeile<\/span>\r\n      <div class=\"pme-field\"><input type=\"text\" id=\"inp-b2\" value=\"1977\" \/><\/div>\r\n    <\/div>\r\n\r\n    <div class=\"pme-section\" id=\"sec-style\">\r\n      <div class=\"pme-title\">Stil & Form<\/div>\r\n      <div class=\"pme-desc\">W\u00e4hle, wie die Audiodaten deines Tracks visualisiert werden sollen.<\/div>\r\n      \r\n      <span class=\"pme-lbl\">Form<\/span>\r\n      <div class=\"shape-pins\" id=\"shape-grid\">\r\n        <button class=\"shape-btn\" data-shape=\"0\">\r\n          <div class=\"shape-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#1a1a1a\" stroke-width=\"1.5\"><path d=\"M12 12m-8 0a8 8 0 1 0 16 0a8 8 0 1 0 -16 0 M12 12m-4 0a4 4 0 1 0 8 0a4 4 0 1 0 -8 0\"\/><\/svg><\/div>\r\n          <span>Konzentrisch<\/span>\r\n        <\/button>\r\n        <button class=\"shape-btn active\" data-shape=\"1\">\r\n          <div class=\"shape-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#1a1a1a\" stroke-width=\"1.5\"><path d=\"M12 21a9 9 0 0 0 9-9 9 9 0 0 0-9-9 9 9 0 0 0-9 9c0 4 2.5 7 6 8\"\/><\/svg><\/div>\r\n          <span>Spirale<\/span>\r\n        <\/button>\r\n        <button class=\"shape-btn\" data-shape=\"2\">\r\n          <div class=\"shape-icon\">\r\n            <svg viewBox=\"0 0 24 24\" stroke=\"#1a1a1a\" stroke-width=\"2\" stroke-linecap=\"round\">\r\n              <circle cx=\"12\" cy=\"12\" r=\"5\" fill=\"none\"\/>\r\n              <path d=\"M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41\"\/>\r\n            <\/svg>\r\n          <\/div>\r\n          <span>Radial<\/span>\r\n        <\/button>\r\n        <button class=\"shape-btn\" data-shape=\"3\">\r\n          <div class=\"shape-icon\"><svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M2 12 Q 6 2, 12 12 T 22 12 L 22 13 Q 18 23, 12 13 T 2 13 Z\"\/><\/svg><\/div>\r\n          <span>Soundwave<\/span>\r\n        <\/button>\r\n        <button class=\"shape-btn\" data-shape=\"4\">\r\n          <div class=\"shape-icon\">\r\n            <svg viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n              <rect x=\"3\" y=\"10\" width=\"3\" height=\"4\"\/><rect x=\"8\" y=\"6\" width=\"3\" height=\"12\"\/><rect x=\"13\" y=\"4\" width=\"3\" height=\"16\"\/><rect x=\"18\" y=\"8\" width=\"3\" height=\"8\"\/>\r\n            <\/svg>\r\n          <\/div>\r\n          <span>Bl\u00f6cke<\/span>\r\n        <\/button>\r\n        <button class=\"shape-btn\" data-shape=\"5\">\r\n          <div class=\"shape-icon\">\r\n            <svg viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n              <path d=\"M12 6a6 6 0 1 0 0 12 6 6 0 0 0 0-12zm0 10.5a4.5 4.5 0 1 1 0-9 4.5 4.5 0 0 1 0 9z\"\/>\r\n              <path d=\"M12 2v2M12 20v2M4 12H2M22 12h-2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41\"\/>\r\n            <\/svg>\r\n          <\/div>\r\n          <span>Ring<\/span>\r\n        <\/button>\r\n        <button class=\"shape-btn\" data-shape=\"6\">\r\n          <div class=\"shape-icon\">\r\n            <svg viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n              <path d=\"M12 2l2.4 5.6 6.6 1-4.8 4.8 1.1 6.6L12 17.6l-5.3 2.4 1.1-6.6L3 8.6l6.6-1z\" \/>\r\n              <circle cx=\"12\" cy=\"12\" r=\"4\" fill=\"#fafafa\"\/>\r\n            <\/svg>\r\n          <\/div>\r\n          <span>Nova<\/span>\r\n        <\/button>\r\n        <button class=\"shape-btn\" data-shape=\"7\">\r\n          <div class=\"shape-icon\">\r\n            <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\">\r\n              <circle cx=\"12\" cy=\"12\" r=\"10\" \/>\r\n              <circle cx=\"12\" cy=\"12\" r=\"6\" \/>\r\n              <circle cx=\"12\" cy=\"12\" r=\"2\" fill=\"currentColor\" \/>\r\n            <\/svg>\r\n          <\/div>\r\n          <span>Vinyl<\/span>\r\n        <\/button>\r\n      <\/div>\r\n\r\n      <span class=\"pme-lbl\">Design<\/span>\r\n      <div id=\"theme-pins\" class=\"theme-pins\"><\/div>\r\n    <\/div>\r\n\r\n    <div class=\"pme-section\" id=\"sec-size\">\r\n      <div class=\"pme-title\">Gr\u00f6\u00dfe<\/div>\r\n      <div class=\"pme-desc\">W\u00e4hle Material und Gr\u00f6\u00dfe.<\/div>\r\n      <span class=\"pme-lbl\">Material<\/span>\r\n      \r\n      <div id=\"mat-dropdown\">\r\n        <div class=\"dd-selected\" id=\"mat-selected\"><span id=\"mat-selected-text\">Poster<\/span><svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\"><path d=\"M2 4l4 4 4-4\" stroke=\"#888\" stroke-width=\"1.5\" stroke-linecap=\"round\"\/><\/svg><\/div>\r\n        <div class=\"dd-options\" id=\"mat-options\"><\/div>\r\n      <\/div>\r\n      \r\n      <div id=\"frame-opt-wrap\" style=\"display:none;margin-bottom:14px;\">\r\n        <span class=\"pme-lbl\">Rahmenfarbe<\/span>\r\n        <div style=\"display:grid;grid-template-columns:repeat(3,1fr);gap:6px;\">\r\n          <button class=\"pme-frame active\" data-frame=\"black\">Schwarz<\/button>\r\n          <button class=\"pme-frame\" data-frame=\"white\">Wei\u00df<\/button>\r\n          <button class=\"pme-frame\" data-frame=\"wood\">Holz<\/button>\r\n        <\/div>\r\n      <\/div>\r\n\r\n      <span class=\"pme-lbl\">Gr\u00f6\u00dfe<\/span>\r\n      <div id=\"size-dropdown\">\r\n        <div class=\"dd-selected\" id=\"size-selected\"><span id=\"size-selected-text\">30x40cm<\/span><svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\"><path d=\"M2 4l4 4 4-4\" stroke=\"#888\" stroke-width=\"1.5\" stroke-linecap=\"round\"\/><\/svg><\/div>\r\n        <div class=\"dd-options\" id=\"size-options\"><\/div>\r\n      <\/div>\r\n\r\n      <span class=\"pme-lbl\">Ausrichtung<\/span>\r\n      <div class=\"pme-orients\">\r\n        <button class=\"pme-or active\" data-orient=\"portrait\">Hochformat<\/button>\r\n        <button class=\"pme-or\" data-orient=\"landscape\">Querformat<\/button>\r\n      <\/div>\r\n    <\/div>\r\n\r\n    <div class=\"pme-bar\">\r\n      <div class=\"pme-prices\">\r\n        <span class=\"pme-old\" id=\"p-old\">29,99 \u20ac<\/span>\r\n        <span class=\"pme-new\" id=\"p-new\">14,99 \u20ac<\/span>\r\n      <\/div>\r\n      <button class=\"pme-cart\" id=\"btn-cart\">\r\n        <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"9\" cy=\"21\" r=\"1\"\/><circle cx=\"20\" cy=\"21\" r=\"1\"\/><path d=\"M1 1h4l2.68 13.39a2 2 0 001.99 1.61h9.72a2 2 0 001.99-1.61L23 6H6\"\/><\/svg>\r\n        In den Warenkorb\r\n      <\/button>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <div class=\"pme-canvas\" id=\"pme-canvas\">\r\n    <div class=\"pme-outer\" id=\"pme-outer\">\r\n      <div class=\"pme-poster\" id=\"pme-poster\" style=\"width:360px;height:504px;\">\r\n        <div class=\"pme-poster-inner\" id=\"pme-poster-inner\">\r\n            \r\n          <div class=\"music-visual\">\r\n              <canvas id=\"music-layer\"><\/canvas>\r\n          <\/div>\r\n          \r\n          <div class=\"music-footer\" id=\"music-footer\">\r\n              <div class=\"mf-h1\" id=\"out-h1\">ONE LOVE<\/div>\r\n              <div class=\"mf-h2\" id=\"out-h2\">BOB MARLEY<\/div>\r\n              <div class=\"mf-b1\" id=\"out-b1\">EXODUS<\/div>\r\n              <div class=\"mf-b2\" id=\"out-b2\">1977<\/div>\r\n          <\/div>\r\n\r\n        <\/div>\r\n      <\/div>\r\n      <div class=\"pme-dimr\"><span id=\"dim-h\">40 cm<\/span><\/div>\r\n      <div class=\"pme-dimb\"><span id=\"dim-w\">30 cm<\/span><\/div>\r\n    <\/div>\r\n  <\/div>\r\n<\/div>\r\n\r\n<script>\r\n(function(){\r\n\r\nvar RESOLUTION = 3; \r\n\r\n\/\/ --- THEMES & CONFIG ---\r\nvar THEMES = [\r\n  { id:'Modern',       name:'Modern',       posterBg:'#ffffff', lineCol:'#1a1a1a' },\r\n  { id:'Black',        name:'Black',        posterBg:'#0a0a0a', lineCol:'#ffffff' },\r\n  { id:'Night',        name:'Night',        posterBg:'#1a2a3a', lineCol:'#e0e0e0' },\r\n  { id:'Mint',         name:'Mint',         posterBg:'#8ecdb8', lineCol:'#ffffff' },\r\n  { id:'Sand',         name:'Sand',         posterBg:'#f4efe8', lineCol:'#2c2c2c' },\r\n  { id:'Pink',         name:'Pink',         posterBg:'#edb4c8', lineCol:'#f7285a' },\r\n  { id:'Desert',       name:'Desert',       posterBg:'#e0ceb8', lineCol:'#fcf9e5' },\r\n  { id:'RetroSunset',  name:'Retro Sunset', posterBg:'#f7bf3d', lineCol:'#f7285a' },\r\n];\r\n\r\nvar SIZES = {\r\n  postcard:[{l:'10x15cm',w:10,h:15,p:2.99,orig:4.99}],\r\n  poster:[{l:'13x18cm',w:13,h:18,p:14.99,orig:24.99},{l:'30x40cm',w:30,h:40,p:20.99,orig:34.99},{l:'40x60cm',w:40,h:60,p:26.99,orig:44.99},{l:'50x70cm',w:50,h:70,p:29.99,orig:49.99},{l:'70x100cm',w:70,h:100,p:47.99,orig:79.99}],\r\n  framed:[{l:'13x18cm',w:13,h:18,p:32.99,orig:54.99},{l:'30x40cm',w:30,h:40,p:44.99,orig:74.99},{l:'50x70cm',w:50,h:70,p:89.99,orig:149.99},{l:'70x100cm',w:70,h:100,p:149.99,orig:249.99}],\r\n  canvas:[{l:'30x40cm',w:30,h:40,p:47.99,orig:79.99},{l:'50x70cm',w:50,h:70,p:83.99,orig:139.99},{l:'70x100cm',w:70,h:100,p:113.99,orig:189.99}]\r\n};\r\n\r\nvar MATS = ['postcard','poster','framed','canvas'];\r\nvar MAT_LABELS = {postcard:'Postkarte',poster:'Poster',framed:'Gerahmtes Poster',canvas:'Leinwand'};\r\n\r\nvar audioCache = {};\r\nvar S = { mat: 'poster', sizeIdx: 1, themeId: 'Mint', shape: 1, frame: 'black', orient: 'portrait', seed: 'onelovebobmarley', previewUrl: '' };\r\n\r\nfunction getTheme(){ return THEMES.find(function(t){ return t.id===S.themeId; })||THEMES[0]; }\r\n\r\n\/\/ --- PROCEDURAL GENERATOR (Fallback) ---\r\nfunction getSeed(str) {\r\n    var hash = 0;\r\n    for (var i = 0; i < str.length; i++) { hash = ((hash << 5) - hash) + str.charCodeAt(i); hash |= 0; }\r\n    return hash;\r\n}\r\nfunction mulberry32(a) {\r\n    return function() {\r\n      var t = a += 0x6D2B79F5;\r\n      t = Math.imul(t ^ t >>> 15, t | 1);\r\n      t ^= t + Math.imul(t ^ t >>> 7, t | 61);\r\n      return ((t ^ t >>> 14) >>> 0) \/ 4294967296;\r\n    }\r\n}\r\nfunction smoothNoise(rands, x) {\r\n    var i = Math.floor(x);\r\n    var f = x - i;\r\n    var r1 = rands[i % rands.length];\r\n    var r2 = rands[(i+1) % rands.length];\r\n    var u = f * f * (3.0 - 2.0 * f);\r\n    return r1 * (1 - u) + r2 * u;\r\n}\r\n\r\nfunction getProceduralData(rands, samples) {\r\n    var data = [];\r\n    for (var i = 0; i < samples; i++) {\r\n        var t_ratio = i \/ samples;\r\n        var edgeEnv = Math.pow(Math.sin(t_ratio * Math.PI), 0.8); \r\n        var structure = smoothNoise(rands, t_ratio * 8); \r\n        var detail = (smoothNoise(rands, t_ratio * 80) * 0.4 + smoothNoise(rands, t_ratio * 200) * 0.6);\r\n        var val = edgeEnv * (0.2 + structure * 0.8) * detail * 2.5;\r\n        data.push(Math.min(1, Math.max(0.01, val)));\r\n    }\r\n    return data;\r\n}\r\n\r\nfunction drawLoading(ctx, W, H, t) {\r\n    ctx.fillStyle = t.lineCol;\r\n    ctx.globalAlpha = 0.5;\r\n    ctx.font = '24px \"DM Sans\"';\r\n    ctx.textAlign = 'center';\r\n    ctx.fillText('Generiere echte Soundwave...', W\/2, H\/2);\r\n    ctx.globalAlpha = 1.0;\r\n}\r\n\r\nfunction drawWaveform(ctx, W, H, t, data, shape) {\r\n    var renderData = data;\r\n    \r\n    if (shape === 3 || shape === 4) {\r\n        \/\/ Take the first half of the array (first 15 seconds)\r\n        renderData = data.slice(0, Math.floor(data.length \/ 2));\r\n    }\r\n    \r\n    var marginX = 16 * RESOLUTION;\r\n    var startX = marginX, endX = W - marginX, drawW = endX - startX, cy = H \/ 2;\r\n    var maxAmp = H * 0.35; \r\n    \r\n    \/\/ For circular shapes, calculate max radius fitting into the bounds\r\n    var cx = W \/ 2;\r\n    var rCy = H \/ 2; \r\n    var maxAllowedRadius = Math.min(W \/ 2, H \/ 2) - marginX; \r\n    \r\n    if (shape === 3) {\r\n        \/\/ SOUNDWAVE (Classic Filled, linear)\r\n        var step = drawW \/ (renderData.length - 1);\r\n        ctx.fillStyle = t.lineCol;\r\n        ctx.beginPath();\r\n        ctx.moveTo(startX, cy);\r\n        for(var i=0; i<renderData.length; i++) ctx.lineTo(startX + i*step, cy - renderData[i]*maxAmp);\r\n        for(var i=renderData.length-1; i>=0; i--) ctx.lineTo(startX + i*step, cy + renderData[i]*maxAmp);\r\n        ctx.closePath();\r\n        ctx.fill();\r\n    } \r\n    else if (shape === 4) {\r\n        \/\/ BLOCKS (Distinct bars, linear)\r\n        ctx.fillStyle = t.lineCol;\r\n        var targetBars = 75; \r\n        var stepSize = Math.max(1, Math.floor(renderData.length \/ targetBars));\r\n        var actualBars = Math.floor(renderData.length \/ stepSize);\r\n        var renderStep = drawW \/ actualBars;\r\n        var barW = renderStep * 0.8; \r\n        \r\n        for(var i=0; i<actualBars; i++) {\r\n            var maxD = 0;\r\n            for(var j=0; j<stepSize; j++) {\r\n                if(renderData[i*stepSize + j] > maxD) maxD = renderData[i*stepSize + j];\r\n            }\r\n            var amp = Math.max(H * 0.005, maxD * maxAmp); \r\n            var x = startX + i * renderStep;\r\n            ctx.fillRect(x - barW\/2, cy - amp, barW, amp*2);\r\n        }\r\n    } \r\n    else if (shape === 5) {\r\n        \/\/ RING (Circular Blocks)\r\n        var minR = Math.min(W, H) * 0.22;\r\n        var maxRadialAmp = maxAllowedRadius - minR;\r\n        \r\n        ctx.fillStyle = t.lineCol;\r\n        var targetBars = 160; \r\n        var stepSize = Math.max(1, Math.floor(data.length \/ targetBars));\r\n        var actualBars = Math.floor(data.length \/ stepSize);\r\n        var angleStep = (Math.PI * 2) \/ actualBars;\r\n        var barW = (2 * Math.PI * minR \/ actualBars) * 0.65; \r\n        \r\n        for(var i=0; i<actualBars; i++) {\r\n            var maxD = 0;\r\n            for(var j=0; j<stepSize; j++) {\r\n                if(data[i*stepSize + j] > maxD) maxD = data[i*stepSize + j];\r\n            }\r\n            var amp = Math.max(H * 0.005, maxD * maxRadialAmp); \r\n            var a = i * angleStep - Math.PI\/2; \r\n            \r\n            ctx.save();\r\n            ctx.translate(cx, rCy);\r\n            ctx.rotate(a);\r\n            ctx.fillRect(minR, -barW\/2, amp, barW);\r\n            ctx.restore();\r\n        }\r\n    }\r\n    else if (shape === 6) {\r\n        \/\/ NOVA (Filled Polar Polygon)\r\n        var minR = Math.min(W, H) * 0.22;\r\n        var maxRadialAmp = maxAllowedRadius - minR;\r\n        \r\n        ctx.fillStyle = t.lineCol;\r\n        ctx.beginPath();\r\n        var points = data.length; \r\n        var angleStep = (Math.PI * 2) \/ points;\r\n\r\n        for (var i = 0; i <= points; i++) {\r\n            var idx = i % points;\r\n            var a = idx * angleStep - Math.PI\/2;\r\n            var amp = Math.max(H * 0.005, data[idx] * maxRadialAmp);\r\n            var r = minR + amp;\r\n            ctx.lineTo(cx + r * Math.cos(a), rCy + r * Math.sin(a));\r\n        }\r\n        for (var i = points; i >= 0; i--) {\r\n            var idx = i % points;\r\n            var a = idx * angleStep - Math.PI\/2;\r\n            ctx.lineTo(cx + minR * Math.cos(a), rCy + minR * Math.sin(a));\r\n        }\r\n        ctx.closePath();\r\n        ctx.fill();\r\n    }\r\n    else if (shape === 7) {\r\n        \/\/ VINYL (Continuous modulating spiral)\r\n        var vMinR = Math.min(W, H) * 0.08;\r\n        var vMaxR = maxAllowedRadius;\r\n        var turns = 20;\r\n        var points = data.length * 3; \/\/ Smooth high res curve\r\n        \r\n        ctx.strokeStyle = t.lineCol;\r\n        ctx.lineWidth = Math.max(2, W * 0.0015);\r\n        ctx.lineJoin = 'round';\r\n        ctx.lineCap = 'round';\r\n        ctx.beginPath();\r\n\r\n        for (var i = 0; i <= points; i++) {\r\n            var t_ratio = i \/ points;\r\n            var dataIdx = Math.min(data.length - 1, Math.floor(t_ratio * data.length));\r\n            var a = t_ratio * Math.PI * 2 * turns - Math.PI\/2;\r\n            var baseR = vMinR + t_ratio * (vMaxR - vMinR);\r\n\r\n            var mod = (data[dataIdx] - 0.5) * (vMaxR * 0.05); \r\n            var r = baseR + mod;\r\n            ctx.lineTo(cx + r * Math.cos(a), rCy + r * Math.sin(a));\r\n        }\r\n        ctx.stroke();\r\n\r\n        \/\/ Inner Label\r\n        ctx.fillStyle = t.lineCol;\r\n        ctx.beginPath();\r\n        ctx.arc(cx, rCy, vMinR * 0.7, 0, Math.PI * 2);\r\n        ctx.fill();\r\n    }\r\n}\r\n\r\n\/\/ --- DRAWING ENGINE ---\r\nfunction generateCanvas() {\r\n    var canvas = document.getElementById('music-layer');\r\n    var ctx = canvas.getContext('2d');\r\n    var isL = S.orient === 'landscape';\r\n    \r\n    var vis = document.querySelector('.music-visual');\r\n    var cw = vis.clientWidth;\r\n    var ch = vis.clientHeight;\r\n    \r\n    if (cw < 50) cw = isL ? 504 : 378;\r\n    if (ch < 50) ch = isL ? 250 : 380;\r\n\r\n    var W = canvas.width = cw * RESOLUTION;\r\n    var H = canvas.height = ch * RESOLUTION;\r\n    \r\n    var t = getTheme();\r\n    ctx.fillStyle = t.posterBg;\r\n    ctx.fillRect(0,0,W,H);\r\n    ctx.strokeStyle = t.lineCol;\r\n    ctx.lineJoin = 'round';\r\n    ctx.lineCap = 'round';\r\n\r\n    var seedStr = S.seed || \"onelovebobmarley\";\r\n    var prng = mulberry32(getSeed(seedStr));\r\n    var rands = []; for(var i=0; i<2000; i++) rands.push(prng());\r\n\r\n    if(S.shape === 0) {\r\n        \/\/ CONCENTRIC\r\n        var cx = W\/2, cy = H\/2;\r\n        var maxR = Math.min(W, H)\/2 * 0.85;\r\n        var circles = 22;\r\n        ctx.lineWidth = Math.max(3, W * 0.002);\r\n        for(var c=1; c<=circles; c++) {\r\n            ctx.beginPath();\r\n            var baseR = maxR * (c\/circles);\r\n            for(var a=0; a<=Math.PI*2.01; a+=0.04) {\r\n                var noiseVal = (smoothNoise(rands, c*30 + a*8) - 0.5) * 60 * (c\/circles);\r\n                var r = baseR + noiseVal;\r\n                var x = cx + r * Math.cos(a);\r\n                var y = cy + r * Math.sin(a);\r\n                if(a===0) ctx.moveTo(x, y);\r\n                else ctx.lineTo(x, y);\r\n            }\r\n            ctx.closePath();\r\n            ctx.stroke();\r\n        }\r\n    }\r\n    else if (S.shape === 1) {\r\n        \/\/ SPIRAL\r\n        var cx = W\/2, cy = H\/2;\r\n        var maxR = Math.min(W, H)\/2 * 0.85;\r\n        var turns = 35;\r\n        var steps = turns * 80;\r\n        ctx.lineWidth = Math.max(3, W * 0.002);\r\n        ctx.beginPath();\r\n        for(var i=0; i<=steps; i++) {\r\n            var angle = (i\/80) * Math.PI * 2;\r\n            var baseR = maxR * (i\/steps);\r\n            var env = Math.sin(Math.PI * (i\/steps)); \r\n            var noiseVal = (smoothNoise(rands, i*0.1) - 0.5) * 80 * env;\r\n            var r = baseR + noiseVal;\r\n            var x = cx + r * Math.cos(angle);\r\n            var y = cy + r * Math.sin(angle);\r\n            if(i===0) ctx.moveTo(x, y);\r\n            else ctx.lineTo(x, y);\r\n        }\r\n        ctx.stroke();\r\n    }\r\n    else if (S.shape === 2) {\r\n        \/\/ RADIAL \/ STARBURST (Single Color)\r\n        var cx = W\/2, cy = H\/2;\r\n        var lines = 280;\r\n        var maxR = Math.min(W, H)\/2 * 0.85;\r\n        ctx.strokeStyle = t.lineCol; \r\n        ctx.lineWidth = Math.max(2, W * 0.0015);\r\n        for(var i=0; i<lines; i++) {\r\n            var angle = (i\/lines) * Math.PI * 2;\r\n            var rIdx = Math.floor(rands[i]*1000);\r\n            var r = maxR * (0.15 + 0.85 * rands[rIdx]); \r\n            ctx.beginPath();\r\n            ctx.moveTo(cx + 15*Math.cos(angle), cy + 15*Math.sin(angle));\r\n            ctx.lineTo(cx + r*Math.cos(angle), cy + r*Math.sin(angle));\r\n            ctx.stroke();\r\n        }\r\n    }\r\n    else if (S.shape >= 3 && S.shape <= 7) {\r\n        \/\/ AUDIO SHAPES\r\n        if (S.previewUrl && audioCache[S.previewUrl] && audioCache[S.previewUrl] !== \"error\" && audioCache[S.previewUrl] !== \"loading\") {\r\n            drawWaveform(ctx, W, H, t, audioCache[S.previewUrl], S.shape);\r\n        } \r\n        else if (S.previewUrl && !audioCache[S.previewUrl]) {\r\n            audioCache[S.previewUrl] = \"loading\";\r\n            drawLoading(ctx, W, H, t);\r\n            \r\n            fetch(S.previewUrl)\r\n                .then(function(res) { return res.arrayBuffer(); })\r\n                .then(function(buf) {\r\n                    var actx = new (window.AudioContext || window.webkitAudioContext)();\r\n                    return actx.decodeAudioData(buf);\r\n                })\r\n                .then(function(audioBuf) {\r\n                    var rawDataFull = audioBuf.getChannelData(0);\r\n                    \r\n                    \/\/ ALWAYS use the first 15 seconds (50% of the 30s preview) for all audio shapes\r\n                    var startIdx = 0;\r\n                    var endIdx = Math.floor(rawDataFull.length * 0.50);\r\n                    var rawData = rawDataFull.slice(startIdx, endIdx);\r\n                    \r\n                    var samples = 400; \/\/ Generate high res cache\r\n                    var blockSize = Math.floor(rawData.length \/ samples);\r\n                    var peaks = [];\r\n                    for (var i = 0; i < samples; i++) {\r\n                        var peak = 0;\r\n                        for (var j = 0; j < blockSize; j++) {\r\n                            var val = Math.abs(rawData[blockSize * i + j]);\r\n                            if(val > peak) peak = val;\r\n                        }\r\n                        peaks.push(Math.max(0.01, peak));\r\n                    }\r\n                    \r\n                    var smoothed = [];\r\n                    for(var i=0; i<samples; i++) {\r\n                        var prev = i>0 ? peaks[i-1] : peaks[i];\r\n                        var next = i<samples-1 ? peaks[i+1] : peaks[i];\r\n                        smoothed.push((prev + peaks[i]*2 + next) \/ 4);\r\n                    }\r\n                    \r\n                    var maxVal = Math.max.apply(null, smoothed);\r\n                    if(maxVal === 0) maxVal = 1;\r\n                    audioCache[S.previewUrl] = smoothed.map(function(n) { return Math.pow(n \/ maxVal, 0.8); });\r\n                    updatePosterDesign(); \r\n                })\r\n                .catch(function(err){\r\n                    console.error(\"Audio decoding failed, using fallback.\", err);\r\n                    audioCache[S.previewUrl] = \"error\";\r\n                    updatePosterDesign();\r\n                });\r\n        } \r\n        else if (S.previewUrl && audioCache[S.previewUrl] === \"loading\") {\r\n            drawLoading(ctx, W, H, t);\r\n        } \r\n        else {\r\n            var procData = getProceduralData(rands, 400);\r\n            drawWaveform(ctx, W, H, t, procData, S.shape);\r\n        }\r\n    }\r\n}\r\n\r\n\/\/ --- URL PARAMS ---\r\n(function(){\r\n  var p = new URLSearchParams(window.location.search);\r\n  if(p.get('mat')) S.mat = p.get('mat');\r\n  if(p.get('size')) S.sizeIdx = parseInt(p.get('size'));\r\n  if(p.get('theme')) S.themeId = p.get('theme');\r\n  if(p.get('shape')) {\r\n      var sh = parseInt(p.get('shape'));\r\n      S.shape = (sh >= 0 && sh <= 7) ? sh : 0; \r\n  }\r\n  if(p.get('frame')) S.frame = p.get('frame');\r\n  if(p.get('orient')) S.orient = p.get('orient');\r\n  if(p.get('seed')) S.seed = p.get('seed');\r\n  if(p.get('previewUrl')) S.previewUrl = decodeURIComponent(p.get('previewUrl'));\r\n  \r\n  if(p.get('h1')) document.getElementById('inp-h1').value = decodeURIComponent(p.get('h1'));\r\n  if(p.get('h2')) document.getElementById('inp-h2').value = decodeURIComponent(p.get('h2'));\r\n  if(p.get('b1')) document.getElementById('inp-b1').value = decodeURIComponent(p.get('b1'));\r\n  if(p.get('b2')) document.getElementById('inp-b2').value = decodeURIComponent(p.get('b2'));\r\n})();\r\n\r\nfunction doUpdateUrl(){\r\n  var p = new URLSearchParams();\r\n  p.set('mat', S.mat); p.set('size', S.sizeIdx); p.set('theme', S.themeId); p.set('shape', S.shape);\r\n  p.set('orient', S.orient);\r\n  p.set('seed', S.seed);\r\n  p.set('previewUrl', encodeURIComponent(S.previewUrl));\r\n  if(S.mat === 'framed') p.set('frame', S.frame);\r\n  p.set('h1', encodeURIComponent(document.getElementById('inp-h1').value));\r\n  p.set('h2', encodeURIComponent(document.getElementById('inp-h2').value));\r\n  p.set('b1', encodeURIComponent(document.getElementById('inp-b1').value));\r\n  p.set('b2', encodeURIComponent(document.getElementById('inp-b2').value));\r\n  history.replaceState(null,'','?'+p.toString());\r\n}\r\n\r\nfunction updatePosterDesign(){\r\n  var t = getTheme();\r\n  var inner = document.getElementById('pme-poster-inner');\r\n  inner.style.backgroundColor = t.posterBg;\r\n  document.getElementById('music-footer').style.color = t.lineCol;\r\n  generateCanvas();\r\n}\r\n\r\nfunction updateContent(){\r\n  document.getElementById('out-h1').textContent = document.getElementById('inp-h1').value.toUpperCase();\r\n  document.getElementById('out-h2').textContent = document.getElementById('inp-h2').value.toUpperCase();\r\n  document.getElementById('out-b1').textContent = document.getElementById('inp-b1').value.toUpperCase();\r\n  document.getElementById('out-b2').textContent = document.getElementById('inp-b2').value.toUpperCase();\r\n  \r\n  generateCanvas();\r\n  doUpdateUrl();\r\n}\r\n\r\n\/\/ LIVE SEARCH SONG\r\nvar stimer;\r\ndocument.getElementById('inp-search').addEventListener('input', function(){\r\n  clearTimeout(stimer);\r\n  if(this.value.length < 2) { \r\n      document.getElementById('song-results').classList.remove('show'); \r\n      return; \r\n  }\r\n  stimer = setTimeout(doSongSearch, 500);\r\n});\r\n\r\nfunction doSongSearch(){\r\n  var q = document.getElementById('inp-search').value.trim();\r\n  if(!q) return;\r\n  var box = document.getElementById('song-results');\r\n  \/\/ API Call f\u00fcr deutsche Ergebnisse optimiert\r\n  fetch('https:\/\/itunes.apple.com\/search?term='+encodeURIComponent(q)+'&entity=song&limit=5&country=DE')\r\n    .then(function(r){ return r.json(); })\r\n    .then(function(d){\r\n      if(!d.results||!d.results.length){ box.innerHTML='<div class=\"pme-ri\">Keine Ergebnisse<\/div>'; box.classList.add('show'); return; }\r\n      box.innerHTML = d.results.map(function(t){\r\n        var name=(t.trackName||q).replace(\/\"\/g,'');\r\n        var artist=(t.artistName||'').replace(\/\"\/g,'');\r\n        var album=(t.collectionName||name).replace(\/\"\/g,'');\r\n        var year=t.releaseDate ? t.releaseDate.substring(0,4) : '';\r\n        var preview=t.previewUrl || '';\r\n        return '<div class=\"pme-ri\" data-name=\"'+name+'\" data-artist=\"'+artist+'\" data-album=\"'+album+'\" data-year=\"'+year+'\" data-preview=\"'+preview+'\"><strong>'+name+'<\/strong><span>'+artist+'<\/span><\/div>';\r\n      }).join('');\r\n      box.classList.add('show');\r\n      \r\n      box.querySelectorAll('.pme-ri').forEach(function(item){\r\n        item.addEventListener('click', function(){\r\n          var name=this.getAttribute('data-name');\r\n          var artist=this.getAttribute('data-artist');\r\n          var album=this.getAttribute('data-album');\r\n          var year=this.getAttribute('data-year');\r\n          var preview=this.getAttribute('data-preview');\r\n          \r\n          document.getElementById('inp-search').value=name + ' - ' + artist;\r\n          document.getElementById('inp-h1').value=name;\r\n          document.getElementById('inp-h2').value=artist;\r\n          document.getElementById('inp-b1').value=album;\r\n          document.getElementById('inp-b2').value=year;\r\n          \r\n          S.seed = (name + artist).toLowerCase().replace(\/\\s\/g,'');\r\n          S.previewUrl = preview;\r\n          \r\n          box.classList.remove('show');\r\n          updateContent();\r\n        });\r\n      });\r\n    }).catch(function(){});\r\n}\r\n\r\ndocument.addEventListener('click', function(e){\r\n  if(!e.target.closest('#inp-search')&&!e.target.closest('#song-results')){\r\n      var box = document.getElementById('song-results');\r\n      if(box) box.classList.remove('show');\r\n  }\r\n});\r\n\r\n\/\/ POPULAR SONGS CLICK\r\ndocument.querySelectorAll('.pme-pop li').forEach(function(li){\r\n    li.addEventListener('click', function(){\r\n        var name = this.getAttribute('data-name');\r\n        var artist = this.getAttribute('data-artist');\r\n        var album = this.getAttribute('data-album');\r\n        var year = this.getAttribute('data-year');\r\n        \r\n        document.getElementById('inp-search').value = name + ' - ' + artist;\r\n        document.getElementById('inp-h1').value = name;\r\n        document.getElementById('inp-h2').value = artist;\r\n        document.getElementById('inp-b1').value = album;\r\n        document.getElementById('inp-b2').value = year;\r\n        \r\n        S.seed = (name + artist).toLowerCase().replace(\/\\s\/g,'');\r\n        S.previewUrl = ''; \r\n        updateContent();\r\n        \r\n        fetch('https:\/\/itunes.apple.com\/search?term='+encodeURIComponent(name+' '+artist)+'&entity=song&limit=1&country=DE')\r\n        .then(function(r){ return r.json(); })\r\n        .then(function(d){\r\n            if(d.results && d.results.length > 0) {\r\n                S.previewUrl = d.results[0].previewUrl || '';\r\n                updateContent();\r\n            }\r\n        }).catch(function(){});\r\n    });\r\n});\r\n\r\n['inp-h1', 'inp-h2', 'inp-b1', 'inp-b2'].forEach(function(id){\r\n    document.getElementById(id).addEventListener('input', updateContent);\r\n});\r\n\r\n\/\/ --- PINS (Theme & Shape) ---\r\nfunction renderThemePins(){\r\n  var c = document.getElementById('theme-pins');\r\n  c.innerHTML = THEMES.map(function(t){\r\n    var active = t.id===S.themeId?' active':'';\r\n    return '<button class=\"pme-thm'+active+'\" data-id=\"'+t.id+'\">'\r\n      +'<div class=\"pme-thm-circle\" style=\"background-color:'+t.posterBg+'; border-color: '+ (t.posterBg==='#ffffff' ? '#e0e0e0' : t.posterBg) +'; box-shadow: inset 0 0 0 2px '+t.lineCol+';\"><\/div>'\r\n      +'<span>'+t.name+'<\/span>'\r\n      +'<\/button>';\r\n  }).join('');\r\n  \r\n  c.querySelectorAll('.pme-thm').forEach(function(pin){\r\n    pin.addEventListener('click', function(){\r\n      c.querySelectorAll('.pme-thm').forEach(function(p){ p.classList.remove('active'); });\r\n      this.classList.add('active');\r\n      S.themeId = this.getAttribute('data-id');\r\n      updatePosterDesign(); doUpdateUrl();\r\n    });\r\n  });\r\n}\r\n\r\ndocument.querySelectorAll('.shape-btn').forEach(function(btn) {\r\n    btn.addEventListener('click', function(){\r\n        document.querySelectorAll('.shape-btn').forEach(function(b){ b.classList.remove('active'); });\r\n        this.classList.add('active');\r\n        S.shape = parseInt(this.getAttribute('data-shape'));\r\n        updatePosterDesign(); doUpdateUrl();\r\n    });\r\n});\r\n\r\n\/\/ Sync shape initial state\r\ndocument.querySelectorAll('.shape-btn').forEach(function(b){ b.classList.remove('active'); });\r\nvar actBtn = document.querySelector('.shape-btn[data-shape=\"'+S.shape+'\"]');\r\nif(actBtn) actBtn.classList.add('active');\r\n\r\n\/\/ --- NAV ---\r\ndocument.querySelectorAll('.pme-nav-btn, .pme-mobbtn').forEach(function(btn){\r\n  btn.addEventListener('click', function(){\r\n    var panel = this.getAttribute('data-panel');\r\n    document.querySelectorAll('.pme-section').forEach(function(s){ s.classList.remove('active'); });\r\n    document.querySelectorAll('.pme-nav-btn,.pme-mobbtn').forEach(function(b){ b.classList.remove('active'); });\r\n    document.getElementById('sec-'+panel).classList.add('active');\r\n    document.querySelectorAll('[data-panel=\"'+panel+'\"]').forEach(function(b){ b.classList.add('active'); });\r\n  });\r\n});\r\n\r\ndocument.querySelectorAll('.pme-frame').forEach(function(btn) {\r\n  btn.addEventListener('click', function() {\r\n    document.querySelectorAll('.pme-frame').forEach(function(b) { b.classList.remove('active'); });\r\n    this.classList.add('active');\r\n    S.frame = this.getAttribute('data-frame');\r\n    updateDims();\r\n    doUpdateUrl();\r\n  });\r\n});\r\n\r\ndocument.querySelectorAll('.pme-or').forEach(function(btn) {\r\n  btn.addEventListener('click', function() {\r\n    document.querySelectorAll('.pme-or').forEach(function(b) { b.classList.remove('active'); });\r\n    this.classList.add('active');\r\n    S.orient = this.getAttribute('data-orient');\r\n    updateDims(); doUpdateUrl();\r\n  });\r\n});\r\n\r\nif (S.orient) {\r\n  document.querySelectorAll('.pme-or').forEach(function(btn) {\r\n    btn.classList.toggle('active', btn.getAttribute('data-orient') === S.orient);\r\n  });\r\n}\r\n\r\n\/\/ --- SIZES AND MATS ---\r\nfunction renderMaterials(){\r\n  var optsDiv = document.getElementById('mat-options');\r\n  var selText = document.getElementById('mat-selected-text');\r\n  var selDiv  = document.getElementById('mat-selected');\r\n  function selectMat(mat){\r\n    S.mat=mat;\r\n    var sizes = SIZES[S.mat] || [];\r\n    S.sizeIdx = 0;\r\n    for (var i = 0; i < sizes.length; i++) {\r\n      if (sizes[i].l === '30x40cm') { S.sizeIdx = i; break; }\r\n    }\r\n    selText.textContent = MAT_LABELS[mat];\r\n    optsDiv.style.display='none';\r\n    renderSizes(); doUpdateUrl();\r\n  }\r\n  optsDiv.innerHTML = MATS.map(function(m){\r\n    return '<div class=\"size-opt\" data-mat=\"'+m+'\" style=\"padding:10px 12px;font-size:14px;font-family:\\'DM Sans\\',sans-serif;cursor:pointer;border-bottom:1px solid #f0f0f0;\">'+MAT_LABELS[m]+'<\/div>';\r\n  }).join('');\r\n  optsDiv.querySelectorAll('.size-opt').forEach(function(el){\r\n    el.addEventListener('mouseenter', function() { this.style.background='#f5f5f5'; });\r\n    el.addEventListener('mouseleave', function() { this.style.background=''; });\r\n    el.addEventListener('click',function(){ selectMat(this.getAttribute('data-mat')); });\r\n  });\r\n  selDiv.onclick = function(e){ e.stopPropagation(); optsDiv.style.display=optsDiv.style.display==='none'?'block':'none'; };\r\n  document.addEventListener('click',function(){ optsDiv.style.display='none'; });\r\n  selText.textContent = MAT_LABELS[S.mat];\r\n}\r\n\r\nfunction buildLabel(s){\r\n  return s.l+'\\u00a0\\u00a0<s style=\"color:#999\">'+s.orig.toFixed(2)+'\\u00a0\\u20ac<\/s>\\u00a0\\u00a0<span style=\"color:#e00\">'+s.p.toFixed(2)+'\\u00a0\\u20ac<\/span>';\r\n}\r\n\r\nfunction renderSizes(){\r\n  var sizes=SIZES[S.mat]||[];\r\n  var optsDiv=document.getElementById('size-options');\r\n  var selText=document.getElementById('size-selected-text');\r\n  var selDiv=document.getElementById('size-selected');\r\n  var frameWrap = document.getElementById('frame-opt-wrap');\r\n  \r\n  if (frameWrap) frameWrap.style.display = (S.mat === 'framed') ? 'block' : 'none';\r\n  \r\n  function selectIdx(i){\r\n    S.sizeIdx=i; selText.innerHTML=buildLabel(sizes[i]);\r\n    optsDiv.style.display='none';\r\n    updatePrice(); updateDims(); doUpdateUrl();\r\n  }\r\n  optsDiv.innerHTML=sizes.map(function(s,i){\r\n    return '<div class=\"size-opt\" data-idx=\"'+i+'\" style=\"padding:10px 12px;font-size:14px;font-family:\\'DM Sans\\',sans-serif;cursor:pointer;border-bottom:1px solid #f0f0f0;\">'+buildLabel(s)+'<\/div>';\r\n  }).join('');\r\n  optsDiv.querySelectorAll('.size-opt').forEach(function(el){\r\n    el.addEventListener('mouseenter', function() { this.style.background='#f5f5f5'; });\r\n    el.addEventListener('mouseleave', function() { this.style.background=''; });\r\n    el.addEventListener('click',function(){ selectIdx(parseInt(this.getAttribute('data-idx'))); });\r\n  });\r\n  selDiv.onclick=function(e){ e.stopPropagation(); optsDiv.style.display=optsDiv.style.display==='none'?'block':'none'; };\r\n  document.addEventListener('click',function(){ optsDiv.style.display='none'; });\r\n  selectIdx(S.sizeIdx<sizes.length?S.sizeIdx:0);\r\n}\r\n\r\nfunction updatePrice(){\r\n  var s=(SIZES[S.mat]||[])[S.sizeIdx];\r\n  if(!s) return;\r\n  document.getElementById('p-old').textContent=s.orig.toFixed(2).replace('.',',')+' EUR';\r\n  document.getElementById('p-new').textContent=s.p.toFixed(2).replace('.',',')+' EUR';\r\n}\r\n\r\nfunction updateDims(){\r\n  var s=(SIZES[S.mat]||[])[S.sizeIdx];\r\n  if(!s) return;\r\n  \r\n  var isL = S.orient === 'landscape';\r\n  document.getElementById('dim-w').textContent = (isL ? s.h : s.w) + ' cm';\r\n  document.getElementById('dim-h').textContent = (isL ? s.w : s.h) + ' cm';\r\n  \r\n  var BASE = 504;\r\n  var pw = isL ? s.h : s.w;\r\n  var ph = isL ? s.w : s.h;\r\n  var longer = Math.max(pw,ph), shorter = Math.min(pw,ph);\r\n  \r\n  var baseW = isL ? BASE : Math.round(BASE * shorter \/ longer);\r\n  var baseH = isL ? Math.round(BASE * shorter \/ longer) : BASE;\r\n  var poster = document.getElementById('pme-poster');\r\n\r\n  if (isL) {\r\n    poster.style.width = BASE + 'px';\r\n    poster.style.height = Math.round(BASE * shorter \/ longer) + 'px';\r\n  } else {\r\n    poster.style.width = Math.round(BASE * shorter \/ longer) + 'px';\r\n    poster.style.height = BASE + 'px';\r\n  }\r\n\r\n  if (S.mat === 'framed') {\r\n    var thicknessMm = (s.l === '13x18cm') ? 10 : 14;\r\n    var framePx = thicknessMm * (BASE \/ (longer * 10));\r\n\r\n    poster.style.borderWidth = framePx + 'px';\r\n    poster.style.borderStyle = 'solid';\r\n\r\n    if (S.frame === 'wood') {\r\n      poster.style.borderColor = '#d7c5b3';\r\n      poster.style.borderImage = \"url(\\\"data:image\/svg+xml,%3Csvg xmlns='http:\/\/www.w3.org\/2000\/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.01 0.4' numOctaves='2' result='noise'\/%3E%3CfeColorMatrix type='matrix' values='1 0 0 0 0 0 0.8 0 0 0 0 0.5 0 0 0 0 0 0 0.15 0' in='noise'\/%3E%3C\/filter%3E%3Crect width='100%25' height='100%25' fill='%23d7c5b3'\/%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'\/%3E%3C\/svg%3E\\\") 10 stretch\";\r\n    } else if (S.frame === 'white') {\r\n      poster.style.borderImage = \"\";\r\n      poster.style.borderColor = '#ffffff';\r\n    } else { \/\/ black\r\n      poster.style.borderImage = \"\";\r\n      poster.style.borderColor = '#1a1a1a';\r\n    }\r\n    \r\n    poster.style.width = (baseW + framePx * 2) + 'px';\r\n    poster.style.height = (baseH + framePx * 2) + 'px';\r\n    poster.classList.add('is-framed');\r\n  } else {\r\n    poster.style.border = '';\r\n    poster.style.borderImage = '';\r\n    poster.style.width = baseW + 'px';\r\n    poster.style.height = baseH + 'px';\r\n    poster.classList.remove('is-framed');\r\n  }\r\n\r\n  setTimeout(function(){ fitPoster(); updatePosterDesign(); }, 60);\r\n}\r\n\r\nfunction fitPoster(){\r\n  var outer=document.getElementById('pme-outer');\r\n  var poster=document.getElementById('pme-poster');\r\n  var container = document.getElementById('pme-canvas');\r\n  if(!container||!poster.offsetWidth) return;\r\n  \r\n  var isMob = window.innerWidth <= 768;\r\n  var aH = container.clientHeight - (isMob ? 16 : 60);\r\n  var aW = container.clientWidth - (isMob ? 24 : 80);\r\n  \r\n  var scale = Math.min(aH \/ poster.offsetHeight, aW \/ poster.offsetWidth, isMob ? 2.5 : 1.4);\r\n  outer.style.transform='scale('+scale+')';\r\n  outer.style.transformOrigin='center center';\r\n}\r\n\r\nfunction setHeight(){\r\n  var el=document.getElementById('pme-root');\r\n  if(!el) return;\r\n  var isMob = window.innerWidth <= 768;\r\n  if (isMob) {\r\n    el.style.height = 'auto'; \r\n    if(document.querySelector('.pme-panel')) document.querySelector('.pme-panel').style.height = '';\r\n    if(document.querySelector('.pme-nav')) document.querySelector('.pme-nav').style.height = '';\r\n    if(document.getElementById('pme-canvas')) document.getElementById('pme-canvas').style.height = '';\r\n  } else {\r\n    var r=el.getBoundingClientRect();\r\n    var h=Math.max(window.innerHeight-r.top,500);\r\n    el.style.height=h+'px';\r\n    if(document.querySelector('.pme-panel')) document.querySelector('.pme-panel').style.height=h+'px';\r\n    if(document.querySelector('.pme-nav')) document.querySelector('.pme-nav').style.height=h+'px';\r\n    if(document.getElementById('pme-canvas')) document.getElementById('pme-canvas').style.height=h+'px';\r\n  }\r\n  setTimeout(function(){ fitPoster(); },100);\r\n}\r\n\r\nwindow.addEventListener('load',setHeight);\r\nwindow.addEventListener('resize',function(){ setHeight(); });\r\nsetTimeout(setHeight,300);\r\n\r\n\/\/ --- CART EXPORT ---\r\ndocument.getElementById('btn-cart').addEventListener('click', function() {\r\n  var s = (SIZES[S.mat] || [])[S.sizeIdx] || {};\r\n  \r\n  var cartData = {\r\n    action: 'uwa_add_to_cart',\r\n    \r\n    \/\/ HIER DIE NEUE DEUTSCHE PRODUKT-ID:\r\n    product_id: '2218', \r\n    \r\n    poster_title: document.getElementById('out-h1').textContent,\r\n    poster_subtitle: document.getElementById('out-h2').textContent,\r\n    poster_coordinates: document.getElementById('out-b1').textContent + ' ' + document.getElementById('out-b2').textContent,\r\n    poster_lat: '',\r\n    poster_lng: '',\r\n    poster_zoom: '',\r\n    poster_style: S.themeId,\r\n    poster_shape: S.shape,\r\n    poster_material: S.mat,\r\n    poster_frame: (S.mat === 'framed') ? S.frame : '',\r\n    poster_size: s.l || '',\r\n    poster_orientation: S.orient,\r\n    poster_price: s.p || '',\r\n    poster_original_price: s.orig || ''\r\n  };\r\n\r\n  function buildThumbnail() {\r\n    try {\r\n      var musicCanvas = document.getElementById('music-layer');\r\n      var posterEl = document.getElementById('pme-poster');\r\n      var posterW = posterEl.offsetWidth;\r\n      var posterH = posterEl.offsetHeight;\r\n\r\n      var out = document.createElement('canvas');\r\n      out.width = posterW;\r\n      out.height = posterH;\r\n      var ctx = out.getContext('2d');\r\n\r\n      ctx.fillStyle = '#ffffff';\r\n      ctx.fillRect(0, 0, posterW, posterH);\r\n\r\n      var pad = 16;\r\n      var innerW = posterW - pad * 2;\r\n      var innerH = posterH - pad * 2;\r\n\r\n      var t = getTheme();\r\n      ctx.fillStyle = t.posterBg;\r\n      ctx.fillRect(pad, pad, innerW, innerH);\r\n\r\n      var visEl = document.querySelector('.music-visual');\r\n      var visH = visEl.offsetHeight;\r\n      \r\n      if (musicCanvas && musicCanvas.width > 0) {\r\n        ctx.drawImage(musicCanvas, \r\n          0, 0, musicCanvas.width, musicCanvas.height,\r\n          pad, pad + 10, innerW, visH\r\n        );\r\n      }\r\n\r\n      var h1 = document.getElementById('out-h1').textContent || '';\r\n      var h2 = document.getElementById('out-h2').textContent || '';\r\n      var b1 = document.getElementById('out-b1').textContent || '';\r\n      var b2 = document.getElementById('out-b2').textContent || '';\r\n\r\n      var footerY = pad + 10 + visH;\r\n\r\n      ctx.textAlign = 'center';\r\n      ctx.fillStyle = t.lineCol;\r\n\r\n      ctx.font = 'bold 14px Montserrat, sans-serif';\r\n      ctx.fillText(h1.toUpperCase(), posterW\/2, footerY + 28);\r\n\r\n      ctx.font = 'bold 8px Montserrat, sans-serif';\r\n      ctx.globalAlpha = 0.9;\r\n      ctx.fillText(h2.toUpperCase(), posterW\/2, footerY + 45);\r\n\r\n      ctx.font = 'bold 7px Montserrat, sans-serif';\r\n      ctx.fillText(b1.toUpperCase(), posterW\/2, footerY + 75);\r\n\r\n      ctx.font = 'bold 8px Montserrat, sans-serif';\r\n      ctx.globalAlpha = 1.0;\r\n      ctx.fillText(b2.toUpperCase(), posterW\/2, footerY + 87);\r\n\r\n      return out.toDataURL('image\/jpeg', 0.92);\r\n    } catch(e) {\r\n      console.error(e);\r\n      return null;\r\n    }\r\n  }\r\n\r\n  cartData.poster_thumbnail = buildThumbnail() || '';\r\n\r\n  var body = Object.keys(cartData).map(function(k) {\r\n    return encodeURIComponent(k) + '=' + encodeURIComponent(cartData[k]);\r\n  }).join('&');\r\n\r\n  \/\/ Anfrage an die universelle Root-Ajax Datei\r\n  fetch('https:\/\/zulumaps.com\/wp-admin\/admin-ajax.php', {\r\n    method: 'POST',\r\n    headers: {'Content-Type': 'application\/x-www-form-urlencoded'},\r\n    body: body\r\n  }).then(function(r) { return r.json(); })\r\n  .then(function(res) {\r\n    if (res.success) {\r\n      \/\/ Bei Erfolg an den deutschen Warenkorb leiten\r\n      window.location.href = 'https:\/\/zulumaps.com\/de\/warenkorb\/';\r\n    } else {\r\n      console.error(\"Cart Error:\", res);\r\n      alert(\"Konnte nicht in den Warenkorb gelegt werden. Hast du die richtige deutsche Produkt-ID hinterlegt?\");\r\n    }\r\n  }).catch(function(err) {\r\n    console.error(\"Fetch Error:\", err);\r\n    alert(\"Es gab einen Verbindungsfehler zum Server.\");\r\n  });\r\n});\r\n\r\n\/\/ INIT CALL\r\nfetch('https:\/\/itunes.apple.com\/search?term=One+Love+Bob+Marley&entity=song&limit=1&country=DE')\r\n.then(function(r){ return r.json(); })\r\n.then(function(d){\r\n    if(d.results && d.results.length > 0) {\r\n        S.previewUrl = d.results[0].previewUrl || '';\r\n        updatePosterDesign();\r\n    }\r\n}).catch(function(){});\r\n\r\nrenderThemePins();\r\nrenderMaterials();\r\nrenderSizes();\r\nupdateContent();\r\nupdatePosterDesign();\r\n\r\nif (S.frame) {\r\n  document.querySelectorAll('.pme-frame').forEach(function(btn) {\r\n    btn.classList.toggle('active', btn.getAttribute('data-frame') === S.frame);\r\n  });\r\n}\r\nif (S.mat === 'framed') {\r\n  document.getElementById('pme-poster').classList.add('is-framed');\r\n}\r\n\r\n})();\r\n<\/script>\r\n<\/body>\r\n<\/html>\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>Musicmap Editor Song Texte Stil Gr\u00f6\u00dfe Song Texte Stil Gr\u00f6\u00dfe Song Suche nach deinem Lieblingssong, um seinen einzigartigen visuellen Fingerabdruck zu generieren. Beliebte Songs Blinding Lights &#8211; The Weeknd Shape of You &#8211; Ed Sheeran Someone You Loved &#8211; Lewis Capaldi Sunflower &#8211; Post Malone Starboy &#8211; The Weeknd As It Was &#8211; Harry Styles [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-2191","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/zulumaps.com\/de\/wp-json\/wp\/v2\/pages\/2191","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/zulumaps.com\/de\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/zulumaps.com\/de\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/zulumaps.com\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/zulumaps.com\/de\/wp-json\/wp\/v2\/comments?post=2191"}],"version-history":[{"count":4,"href":"https:\/\/zulumaps.com\/de\/wp-json\/wp\/v2\/pages\/2191\/revisions"}],"predecessor-version":[{"id":2237,"href":"https:\/\/zulumaps.com\/de\/wp-json\/wp\/v2\/pages\/2191\/revisions\/2237"}],"wp:attachment":[{"href":"https:\/\/zulumaps.com\/de\/wp-json\/wp\/v2\/media?parent=2191"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}