{"id":23242,"date":"2026-05-29T08:24:07","date_gmt":"2026-05-29T06:24:07","guid":{"rendered":"https:\/\/limainvestimmobilien.de\/?page_id=23242"},"modified":"2026-06-05T11:56:35","modified_gmt":"2026-06-05T09:56:35","slug":"ad-content-generator","status":"publish","type":"page","link":"https:\/\/limainvestimmobilien.de\/en\/ad-content-generator\/","title":{"rendered":"AD-Content-Generator"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"23242\" class=\"elementor elementor-23242\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-0f9f644 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"0f9f644\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-e2720b2\" data-id=\"e2720b2\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-a3532bb elementor-widget elementor-widget-html\" data-id=\"a3532bb\" 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<!DOCTYPE html>\n<html lang=\"de\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>Lima Invest \u00b7 Ad Generator Pro<\/title>\n<style>@import url('https:\/\/fonts.googleapis.com\/css2?family=Cormorant+Garamond:ital,wght@0,300;0,400;0,600;1,300;1,400&family=Poppins:wght@300;400;500;600&display=swap');#lima-ad-gen{position:relative;overflow:clip;}:root{--gold:#bb9e1c;--gold-light:#d4b84a;--gold-dim:rgba(187,158,28,0.14);--gold-border:rgba(187,158,28,0.25);--dark:#f5f3ee;--dark2:#ffffff;--dark3:#f0ede6;--dark4:#e8e4da;--dark5:#ddd9cf;--text:#1a1a1a;--text-muted:#7a7060;--text-sub:#5a5040;--border:rgba(187,158,28,0.35);--border-soft:rgba(0,0,0,0.07);--success:#3d9970;--error:#c0392b;}#lima-ad-gen *{margin:0;padding:0;box-sizing:border-box;}#lima-ad-gen{scroll-behavior:smooth;}#lima-ad-gen{background:var(--dark);color:var(--text);font-family:'Poppins',sans-serif;min-height:100vh;overflow-x:hidden;}#lima-ad-gen::before{content:'';position:absolute;top:0;left:50%;transform:translateX(-50%);width:900px;height:500px;background:radial-gradient(ellipse,rgba(187,158,28,0.10) 0%,transparent 65%);pointer-events:none;z-index:0;}#lima-ad-gen .app{position:relative;z-index:1;max-width:1160px;margin:0 auto;padding:0 28px 100px;}#lima-ad-gen header{position:relative;display:block;padding:0;border-bottom:1px solid var(--border);margin-bottom:20px;overflow:hidden;line-height:0;}#lima-ad-gen .logo{display:flex;align-items:center;gap:14px;}#lima-ad-gen .header-right{display:flex;align-items:center;gap:12px;position:absolute;right:24px;bottom:14px;}#lima-ad-gen .version-tag{background:rgba(245,243,238,0.88);backdrop-filter:blur(8px);border-color:var(--border);}#lima-ad-gen .version-tag{font-size:9px;letter-spacing:3px;text-transform:uppercase;color:var(--text-muted);padding:5px 12px;border:1px solid var(--border-soft);}#lima-ad-gen .page-title{margin-bottom:24px;padding:28px 0 28px;position:relative;overflow:hidden;}#lima-ad-gen .page-title::before{content:'';position:absolute;inset:0;background:radial-gradient(ellipse 70% 80% at 50% 50%,rgba(187,158,28,0.08) 0%,transparent 70%);pointer-events:none;}#lima-ad-gen .page-title::after{content:'';position:absolute;top:0;left:0;width:64px;height:1px;background:var(--gold);}#lima-ad-gen .page-title-eyebrow{font-size:9px;letter-spacing:5px;text-transform:uppercase;color:var(--gold);margin-bottom:12px;display:flex;align-items:center;gap:14px;animation:eyebrowIn 0.7s cubic-bezier(0.22,1,0.36,1) 0.1s both;}#lima-ad-gen .page-title-eyebrow::before{content:'';width:32px;height:1px;background:var(--gold);flex-shrink:0;}@keyframes eyebrowIn{from{opacity:0;transform:translateX(-16px);}to{opacity:1;transform:translateX(0);}}#lima-ad-gen .page-title h1{font-family:'Cormorant Garamond',serif;font-size:clamp(36px,5vw,68px);font-weight:300;line-height:1.0;letter-spacing:-0.5px;position:relative;}#lima-ad-gen .page-title h1 .line1{display:block;color:var(--text);animation:line1In 0.8s cubic-bezier(0.22,1,0.36,1) 0.2s both;}@keyframes line1In{from{opacity:0;transform:translateY(30px) skewX(-2deg);}to{opacity:1;transform:translateY(0) skewX(0deg);}}#lima-ad-gen .page-title h1 .line2{display:block;font-style:italic;color:var(--gold);position:relative;animation:line2In 0.8s cubic-bezier(0.22,1,0.36,1) 0.35s both;}@keyframes line2In{from{opacity:0;transform:translateY(30px) skewX(-2deg);}to{opacity:1;transform:translateY(0) skewX(0deg);}}#lima-ad-gen .page-title h1 .line2::after{content:'';position:absolute;bottom:-4px;left:0;height:1px;background:var(--gold);width:0;animation:underlineGrow 0.9s cubic-bezier(0.22,1,0.36,1) 0.9s forwards;}@keyframes underlineGrow{from{width:0;opacity:0;}to{width:100%;opacity:0.6;}}#lima-ad-gen .page-title h1 .line3{display:block;color:var(--text);animation:line3In 0.8s cubic-bezier(0.22,1,0.36,1) 0.5s both;}@keyframes line3In{from{opacity:0;transform:translateY(30px) skewX(-2deg);}to{opacity:1;transform:translateY(0) skewX(0deg);}}#lima-ad-gen .page-title p{margin-top:16px;font-size:13px;color:var(--text-muted);letter-spacing:0.3px;max-width:480px;line-height:1.8;animation:subtitleIn 0.8s cubic-bezier(0.22,1,0.36,1) 0.65s both;}@keyframes subtitleIn{from{opacity:0;transform:translateY(14px);}to{opacity:1;transform:translateY(0);}}#lima-ad-gen .page-title-stats{display:flex;gap:32px;margin-top:32px;animation:statsIn 0.8s cubic-bezier(0.22,1,0.36,1) 0.8s both;}@keyframes statsIn{from{opacity:0;transform:translateY(10px);}to{opacity:1;transform:translateY(0);}}#lima-ad-gen .pt-stat{display:flex;flex-direction:column;gap:4px;}#lima-ad-gen .pt-stat-num{font-family:'Cormorant Garamond',serif;font-size:28px;font-weight:400;color:var(--gold);line-height:1;}#lima-ad-gen .pt-stat-label{font-size:9px;letter-spacing:2px;text-transform:uppercase;color:var(--text-muted);}#lima-ad-gen .pt-stat-divider{width:1px;background:var(--border);align-self:stretch;}#lima-ad-gen .progress-bar{display:flex;gap:0;border:1px solid var(--border);margin-bottom:20px;overflow:hidden;}#lima-ad-gen .pb-step{flex:1;padding:10px 14px;display:flex;align-items:center;gap:10px;border-right:1px solid var(--border);opacity:0.35;transition:all 0.3s;}#lima-ad-gen .pb-step:last-child{border-right:none;}#lima-ad-gen .pb-step.active{opacity:1;background:var(--gold-dim);}#lima-ad-gen .pb-step.done{opacity:0.65;}#lima-ad-gen .pb-num{width:22px;height:22px;border:1px solid var(--gold);display:flex;align-items:center;justify-content:center;font-size:10px;color:var(--gold);flex-shrink:0;}#lima-ad-gen .pb-step.done .pb-num{background:var(--gold);color:#1a1a1a;border-color:var(--gold);}#lima-ad-gen .pb-step.done .pb-num::after{content:'\u2713';}#lima-ad-gen .pb-step.done .pb-num span{display:none;}#lima-ad-gen .pb-label{font-size:10px;letter-spacing:1.5px;text-transform:uppercase;color:var(--text-muted);}#lima-ad-gen .pb-step.active .pb-label{color:var(--text);}#lima-ad-gen .card{background:var(--dark2);border:1px solid var(--border);padding:20px;margin-bottom:12px;}#lima-ad-gen .card-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px;padding-bottom:12px;border-bottom:1px solid var(--border-soft);}#lima-ad-gen .card-title{font-size:9px;letter-spacing:3px;text-transform:uppercase;color:var(--gold);display:flex;align-items:center;gap:8px;}#lima-ad-gen .input-mode-tabs{display:flex;gap:0;border:1px solid var(--border);margin-bottom:20px;}#lima-ad-gen .im-tab{flex:1;padding:14px 20px;display:flex;align-items:center;justify-content:center;gap:10px;font-size:11px;letter-spacing:2px;text-transform:uppercase;color:var(--text-muted);cursor:pointer;border-right:1px solid var(--border);background:var(--dark2);transition:all 0.2s;}#lima-ad-gen .im-tab:last-child{border-right:none;}#lima-ad-gen .im-tab.active{background:var(--dark3);color:var(--gold);}#lima-ad-gen .im-tab:hover:not(.active){color:var(--text-sub);background:var(--dark3);}#lima-ad-gen .im-tab-icon{font-size:16px;}#lima-ad-gen .upload-zone{border:1px dashed var(--border);background:var(--dark3);padding:52px 32px;text-align:center;cursor:pointer;transition:all 0.3s;position:relative;overflow:hidden;}#lima-ad-gen .upload-zone::before{content:'';position:absolute;inset:0;background:var(--gold-dim);opacity:0;transition:0.3s;pointer-events:none;}#lima-ad-gen .upload-zone:hover::before,#lima-ad-gen .upload-zone.drag-over::before{opacity:1;}#lima-ad-gen .upload-zone:hover,#lima-ad-gen .upload-zone.drag-over{border-color:var(--gold);border-style:solid;}#lima-ad-gen .upload-icon{font-size:36px;margin-bottom:14px;opacity:0.5;}#lima-ad-gen .upload-zone h3{font-family:'Cormorant Garamond',serif;font-size:22px;font-weight:300;letter-spacing:2px;margin-bottom:6px;}#lima-ad-gen .upload-zone p{font-size:11px;color:var(--text-muted);letter-spacing:1px;}#lima-ad-gen .upload-file-info{margin-top:12px;font-size:12px;color:var(--gold);font-weight:500;display:none;}#lima-ad-gen #file-input{display:none;}#lima-ad-gen .url-input-wrap{display:none;flex-direction:column;gap:12px;}#lima-ad-gen .url-field{width:100%;padding:14px 18px;background:var(--dark3);border:1px solid rgba(0,0,0,0.1);color:var(--text);font-family:'Poppins',sans-serif;font-size:13px;outline:none;transition:border-color 0.2s;letter-spacing:0.3px;}#lima-ad-gen .url-field:focus{border-color:var(--gold);}#lima-ad-gen .url-field::placeholder{color:var(--text-muted);}#lima-ad-gen .url-hint{font-size:11px;color:var(--text-muted);letter-spacing:0.5px;line-height:1.6;}#lima-ad-gen .url-hint span{color:var(--gold);}#lima-ad-gen .settings-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:12px;}#lima-ad-gen .sg-group{background:var(--dark3);border:1px solid var(--border-soft);padding:14px;}#lima-ad-gen .sg-label{font-size:9px;letter-spacing:2.5px;text-transform:uppercase;color:var(--gold);margin-bottom:12px;display:block;}#lima-ad-gen .toggles{display:flex;flex-wrap:wrap;gap:7px;}#lima-ad-gen .tgl input{display:none;}#lima-ad-gen .tgl-pill{padding:6px 13px;font-size:10px;letter-spacing:1px;border:1px solid rgba(0,0,0,0.12);color:var(--text-muted);cursor:pointer;transition:all 0.2s;display:block;user-select:none;}#lima-ad-gen .tgl input:checked+.tgl-pill{border-color:var(--gold);color:var(--gold);background:var(--gold-dim);}#lima-ad-gen .tgl-pill:hover{border-color:rgba(255,255,255,0.25);color:var(--text-sub);}#lima-ad-gen select.sg-select{width:100%;background:var(--dark4);border:1px solid rgba(0,0,0,0.1);color:var(--text);padding:10px 14px;font-family:'Poppins',sans-serif;font-size:12px;cursor:pointer;outline:none;appearance:none;}#lima-ad-gen select.sg-select:focus{border-color:var(--gold);}#lima-ad-gen .btn-generate{width:100%;margin-top:14px;padding:16px 32px;background:var(--gold);color:#1a1a1a;font-family:'Poppins',sans-serif;font-size:11px;font-weight:600;letter-spacing:3px;text-transform:uppercase;cursor:pointer;border:none;transition:all 0.2s;display:flex;align-items:center;justify-content:center;gap:10px;}#lima-ad-gen .btn-generate:hover{background:var(--gold-light);}#lima-ad-gen .btn-generate:disabled{opacity:0.4;cursor:not-allowed;}#lima-ad-gen #processing-section{display:none;text-align:center;padding:80px 40px;}#lima-ad-gen .spin-ring{width:56px;height:56px;border:1px solid var(--border);border-top-color:var(--gold);border-radius:50%;animation:spin 0.9s linear infinite;margin:0 auto 24px;}@keyframes spin{to{transform:rotate(360deg);}}#lima-ad-gen .proc-label{font-family:'Cormorant Garamond',serif;font-size:22px;font-weight:300;letter-spacing:3px;color:var(--text-muted);}#lima-ad-gen .proc-step{margin-top:10px;font-size:10px;letter-spacing:2px;text-transform:uppercase;color:var(--gold);min-height:18px;}#lima-ad-gen #results-section{display:none;animation:fadeUp 0.5s ease forwards;}@keyframes fadeUp{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:translateY(0)}}#lima-ad-gen .prop-headline{font-family:'Cormorant Garamond',serif;font-size:26px;font-weight:300;letter-spacing:1px;margin-bottom:4px;}#lima-ad-gen .prop-sub{font-size:11px;color:var(--text-muted);letter-spacing:1px;}#lima-ad-gen .data-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px;margin-top:20px;}#lima-ad-gen .di{padding:12px;background:var(--dark3);border-left:2px solid var(--gold);}#lima-ad-gen .di-label{font-size:8px;letter-spacing:2px;text-transform:uppercase;color:var(--text-muted);margin-bottom:4px;}#lima-ad-gen .di-val{font-size:13px;font-weight:500;color:var(--gold-light);}#lima-ad-gen .features-row{grid-column:1\/-1;display:flex;flex-wrap:wrap;gap:7px;margin-top:4px;}#lima-ad-gen .feat-tag{font-size:10px;padding:4px 10px;border:1px solid var(--border);color:var(--text-muted);}#lima-ad-gen .plat-tabs{display:flex;overflow-x:auto;border:1px solid var(--border);border-bottom:none;}#lima-ad-gen .pt{padding:13px 22px;font-size:10px;letter-spacing:2px;text-transform:uppercase;cursor:pointer;border-right:1px solid var(--border);color:var(--text-muted);background:var(--dark2);transition:all 0.2s;white-space:nowrap;flex-shrink:0;display:flex;align-items:center;gap:7px;}#lima-ad-gen .pt:last-child{border-right:none;}#lima-ad-gen .pt.active{background:var(--dark3);color:var(--gold);}#lima-ad-gen .pt:hover:not(.active){color:var(--text-sub);background:var(--dark3);}#lima-ad-gen .pt-dot{width:6px;height:6px;border-radius:50%;background:var(--text-muted);flex-shrink:0;}#lima-ad-gen .pt.active .pt-dot{background:var(--gold);}#lima-ad-gen .pt.connected .pt-dot{background:var(--success);}#lima-ad-gen .ads-box{border:1px solid var(--border);background:var(--dark2);}#lima-ad-gen .plat-content{display:none;padding:28px;animation:fadeIn 0.25s;}#lima-ad-gen .plat-content.active{display:block;}@keyframes fadeIn{from{opacity:0}to{opacity:1}}#lima-ad-gen .plat-meta{display:flex;align-items:center;gap:16px;margin-bottom:24px;padding-bottom:20px;border-bottom:1px solid var(--border-soft);}#lima-ad-gen .plat-icon-lg{font-size:26px;}#lima-ad-gen .plat-info h3{font-family:'Cormorant Garamond',serif;font-size:20px;font-weight:400;}#lima-ad-gen .plat-info p{font-size:10px;color:var(--text-muted);letter-spacing:1px;margin-top:2px;}#lima-ad-gen .ad-variants{display:grid;gap:16px;}#lima-ad-gen .av{background:var(--dark3);border:1px solid var(--border-soft);position:relative;transition:border-color 0.2s;}#lima-ad-gen .av:hover{border-color:var(--border);}#lima-ad-gen .av-head{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;border-bottom:1px solid rgba(0,0,0,0.04);}#lima-ad-gen .av-label{font-size:8px;letter-spacing:2px;text-transform:uppercase;color:var(--text-muted);}#lima-ad-gen .av-tag{font-size:8px;letter-spacing:1px;padding:2px 8px;text-transform:uppercase;background:var(--gold-dim);color:var(--gold);}#lima-ad-gen .av-body{padding:14px 14px 14px;}#lima-ad-gen .ad-txt{font-size:12px;line-height:1.8;color:var(--text);white-space:pre-wrap;word-break:break-word;}#lima-ad-gen .copy-btn{position:absolute;top:8px;right:8px;background:none;border:1px solid var(--border-soft);color:var(--text-muted);padding:4px 9px;font-size:8px;letter-spacing:1px;text-transform:uppercase;cursor:pointer;transition:all 0.2s;opacity:0;font-family:'Poppins',sans-serif;}#lima-ad-gen .av:hover .copy-btn{opacity:1;}#lima-ad-gen .copy-btn:hover{border-color:var(--gold);color:var(--gold);}#lima-ad-gen .copy-btn.copied{color:var(--success);border-color:var(--success);}#lima-ad-gen .ht-block{margin-top:14px;padding:10px 14px;background:var(--dark4);border-left:2px solid var(--gold);}#lima-ad-gen .ht-label{font-size:8px;letter-spacing:2px;text-transform:uppercase;color:var(--text-muted);margin-bottom:5px;}#lima-ad-gen .ht-txt{font-size:10px;color:var(--gold-light);line-height:1.8;word-break:break-word;}#lima-ad-gen .posting-panel{margin-top:0;padding:14px 28px;background:var(--dark3);border:1px solid var(--border-soft);border-top:none;}#lima-ad-gen .pp-title{font-size:9px;letter-spacing:2.5px;text-transform:uppercase;color:var(--gold);margin-bottom:14px;}#lima-ad-gen .post-actions{display:flex;flex-wrap:wrap;gap:10px;align-items:center;}#lima-ad-gen .post-btn{display:inline-flex;align-items:center;gap:8px;padding:9px 18px;font-family:'Poppins',sans-serif;font-size:10px;letter-spacing:1.5px;text-transform:uppercase;cursor:pointer;transition:all 0.2s;border:none;}#lima-ad-gen .post-btn-direct{background:var(--gold);color:#1a1a1a;font-weight:600;}#lima-ad-gen .post-btn-direct:hover{background:var(--gold-light);}#lima-ad-gen .post-btn-copy{background:transparent;border:1px solid var(--border);color:var(--text-muted);}#lima-ad-gen .post-btn-copy:hover{border-color:var(--gold);color:var(--gold);}#lima-ad-gen .post-btn-whatsapp{background:#25d366;color:#fff;}#lima-ad-gen .post-btn-whatsapp:hover{background:#20b558;}#lima-ad-gen .post-btn-google{background:#4285f4;color:#fff;}#lima-ad-gen .post-btn-google:hover{background:#3574df;}#lima-ad-gen .post-status{font-size:10px;letter-spacing:1px;padding:6px 12px;border:1px solid rgba(0,0,0,0.08);color:var(--text-muted);display:none;}#lima-ad-gen .post-status.connected{color:var(--success);border-color:rgba(61,153,112,0.3);display:inline-flex;align-items:center;gap:6px;}#lima-ad-gen .post-status.connected::before{content:'\u25cf';}#lima-ad-gen .connect-section{margin-top:20px;}#lima-ad-gen .connect-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px;}#lima-ad-gen .connect-title{font-size:9px;letter-spacing:3px;text-transform:uppercase;color:var(--gold);}#lima-ad-gen .connect-sub{font-size:11px;color:var(--text-muted);margin-top:4px;letter-spacing:0.3px;}#lima-ad-gen .accounts-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:10px;}#lima-ad-gen .account-card{background:var(--dark3);border:1px solid var(--border-soft);padding:16px;transition:border-color 0.2s;display:flex;flex-direction:column;gap:12px;}#lima-ad-gen .account-card:hover{border-color:var(--border);}#lima-ad-gen .account-card.connected{border-color:rgba(61,153,112,0.35);background:rgba(61,153,112,0.04);}#lima-ad-gen .ac-top{display:flex;align-items:center;gap:10px;}#lima-ad-gen .ac-icon{font-size:22px;}#lima-ad-gen .ac-name{font-size:12px;font-weight:500;}#lima-ad-gen .ac-handle{font-size:10px;color:var(--text-muted);margin-top:1px;}#lima-ad-gen .ac-status{font-size:9px;letter-spacing:1.5px;text-transform:uppercase;display:flex;align-items:center;gap:5px;}#lima-ad-gen .ac-status.connected{color:var(--success);}#lima-ad-gen .ac-status.disconnected{color:var(--text-muted);}#lima-ad-gen .ac-status .dot{width:5px;height:5px;border-radius:50%;background:currentColor;}#lima-ad-gen .ac-btn{width:100%;padding:8px;font-family:'Poppins',sans-serif;font-size:9px;letter-spacing:2px;text-transform:uppercase;cursor:pointer;border:1px solid var(--border);background:transparent;color:var(--text-muted);transition:all 0.2s;}#lima-ad-gen .ac-btn:hover{border-color:var(--gold);color:var(--gold);}#lima-ad-gen .ac-btn.connected-btn{border-color:var(--success);color:var(--success);}#lima-ad-gen .ac-btn.connected-btn:hover{background:rgba(61,153,112,0.1);}#lima-ad-gen .modal-overlay{position:fixed;inset:0;background:rgba(200,193,178,0.75);z-index:100;display:none;align-items:center;justify-content:center;backdrop-filter:blur(4px);}#lima-ad-gen .modal-overlay.show{display:flex;}#lima-ad-gen .modal{background:var(--dark2);border:1px solid var(--border);width:min(480px,90vw);padding:32px;animation:fadeUp 0.3s ease;}#lima-ad-gen .modal-title{font-family:'Cormorant Garamond',serif;font-size:22px;font-weight:300;letter-spacing:1px;margin-bottom:6px;}#lima-ad-gen .modal-sub{font-size:11px;color:var(--text-muted);letter-spacing:0.5px;margin-bottom:24px;line-height:1.6;}#lima-ad-gen .modal-field{margin-bottom:14px;}#lima-ad-gen .modal-field label{display:block;font-size:9px;letter-spacing:2px;text-transform:uppercase;color:var(--text-muted);margin-bottom:7px;}#lima-ad-gen .modal-input{width:100%;padding:11px 14px;background:var(--dark3);border:1px solid rgba(0,0,0,0.1);color:var(--text);font-family:'Poppins',sans-serif;font-size:12px;outline:none;}#lima-ad-gen .modal-input:focus{border-color:var(--gold);}#lima-ad-gen .modal-info{padding:12px;background:var(--dark4);color:var(--text);border-left:2px solid var(--gold);font-size:10px;color:var(--text-muted);line-height:1.7;margin-bottom:20px;}#lima-ad-gen .modal-info strong{color:var(--gold);}#lima-ad-gen .modal-actions{display:flex;gap:10px;margin-top:20px;}#lima-ad-gen .modal-btn-primary{flex:1;padding:12px;background:var(--gold);color:#1a1a1a;font-family:'Poppins',sans-serif;font-size:10px;font-weight:600;letter-spacing:2px;text-transform:uppercase;cursor:pointer;border:none;transition:all 0.2s;}#lima-ad-gen .modal-btn-primary:hover{background:var(--gold-light);}#lima-ad-gen .modal-btn-secondary{padding:12px 20px;background:transparent;color:var(--text-muted);font-family:'Poppins',sans-serif;font-size:10px;letter-spacing:2px;text-transform:uppercase;cursor:pointer;border:1px solid var(--border);transition:all 0.2s;}#lima-ad-gen .modal-btn-secondary:hover{border-color:var(--border);color:var(--text);}#lima-ad-gen .modal-platform-icon{font-size:32px;margin-bottom:14px;}#lima-ad-gen .modal-note{font-size:9px;color:var(--text-muted);letter-spacing:0.5px;margin-top:12px;line-height:1.6;text-align:center;}#lima-ad-gen .action-bar{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-top:20px;padding-top:16px;border-top:1px solid var(--border-soft);}#lima-ad-gen .btn-primary{display:inline-flex;align-items:center;gap:8px;padding:12px 28px;background:var(--gold);color:#1a1a1a;font-family:'Poppins',sans-serif;font-size:10px;font-weight:600;letter-spacing:2px;text-transform:uppercase;cursor:pointer;border:none;transition:all 0.2s;}#lima-ad-gen .btn-primary:hover{background:var(--gold-light);}#lima-ad-gen .btn-sec{display:inline-flex;align-items:center;gap:8px;padding:11px 22px;background:transparent;color:var(--text-muted);font-family:'Poppins',sans-serif;font-size:10px;letter-spacing:2px;text-transform:uppercase;cursor:pointer;border:1px solid rgba(0,0,0,0.1);transition:all 0.2s;}#lima-ad-gen .btn-sec:hover{border-color:var(--gold);color:var(--gold);}#lima-ad-gen .toast{position:fixed;bottom:28px;right:28px;background:#fff;border:1px solid var(--gold);color:var(--text);padding:11px 18px;font-size:11px;letter-spacing:1px;z-index:200;opacity:0;transform:translateY(8px);transition:all 0.3s;max-width:300px;}#lima-ad-gen .toast.show{opacity:1;transform:translateY(0);}#lima-ad-gen .toast.success{border-color:var(--success);}#lima-ad-gen .toast.err{border-color:var(--error);}#lima-ad-gen .err-box{background:rgba(192,57,43,0.08);border:1px solid rgba(192,57,43,0.3);padding:16px 20px;margin-bottom:20px;font-size:12px;color:#ff9090;line-height:1.6;}#lima-ad-gen .section-divider{display:flex;align-items:center;gap:16px;margin:20px 0 16px;}#lima-ad-gen .section-divider span{font-size:9px;letter-spacing:3px;text-transform:uppercase;color:var(--gold);white-space:nowrap;}#lima-ad-gen .section-divider::before,#lima-ad-gen .section-divider::after{content:'';flex:1;height:1px;background:var(--border);}@media(max-width:640px){#lima-ad-gen .settings-grid{grid-template-columns:1fr;}#lima-ad-gen .progress-bar{display:none;}#lima-ad-gen .accounts-grid{grid-template-columns:1fr 1fr;}#lima-ad-gen header{padding:18px 0 24px;}#lima-ad-gen .app{padding:0 16px 80px;}}#lima-ad-gen .app>*{animation:sectionReveal 0.7s cubic-bezier(0.22,1,0.36,1) both;}#lima-ad-gen .app>*:nth-child(1){animation-delay:0.05s;}#lima-ad-gen .app>*:nth-child(2){animation-delay:0.15s;}#lima-ad-gen .app>*:nth-child(3){animation-delay:0.25s;}#lima-ad-gen .app>*:nth-child(4){animation-delay:0.35s;}#lima-ad-gen .app>*:nth-child(5){animation-delay:0.45s;}@keyframes sectionReveal{from{opacity:0;transform:translateY(24px);}to{opacity:1;transform:translateY(0);}}#lima-ad-gen header img{animation:kenBurns 18s ease-in-out infinite alternate;transform-origin:center center;}@keyframes kenBurns{0%{transform:scale(1) translateX(0px);}50%{transform:scale(1.04) translateX(-12px);}100%{transform:scale(1.02) translateX(8px);}}#lima-ad-gen header::after{content:'';position:absolute;bottom:0;left:-100%;width:60%;height:2px;background:linear-gradient(90deg,transparent,rgba(187,158,28,0.7),transparent);animation:shimmerLine 3.5s ease-in-out infinite;}@keyframes shimmerLine{0%{left:-60%;}100%{left:110%;}}#lima-ad-gen::before{animation:orbPulse 6s ease-in-out infinite alternate;}@keyframes orbPulse{0%{opacity:0.6;transform:translateX(-50%) scale(1);}100%{opacity:1;transform:translateX(-50%) scale(1.15);}}#lima-ad-gen .pb-step.active{animation:stepGlow 2s ease-in-out infinite alternate;}@keyframes stepGlow{from{box-shadow:inset 0 0 0 0 transparent;}to{box-shadow:inset 0 0 20px rgba(187,158,28,0.08);}}#lima-ad-gen .pb-step.done .pb-num{animation:checkPop 0.4s cubic-bezier(0.34,1.56,0.64,1) both;}@keyframes checkPop{from{transform:scale(0.4) rotate(-30deg);opacity:0;}to{transform:scale(1) rotate(0deg);opacity:1;}}#lima-ad-gen .card,#lima-ad-gen .av,#lima-ad-gen .account-card,#lima-ad-gen .di{transition:transform 0.25s cubic-bezier(0.22,1,0.36,1),box-shadow 0.25s ease,border-color 0.25s ease;}#lima-ad-gen .card:hover{transform:translateY(-2px);box-shadow:0 12px 40px rgba(0,0,0,0.35);}#lima-ad-gen .av:hover{transform:translateY(-1px);box-shadow:0 8px 24px rgba(0,0,0,0.3);}#lima-ad-gen .account-card:hover{transform:translateY(-2px);box-shadow:0 10px 30px rgba(0,0,0,0.3);}#lima-ad-gen .upload-zone{animation:borderPulse 3s ease-in-out infinite;}#lima-ad-gen .upload-zone:hover,#lima-ad-gen .upload-zone.drag-over{animation:none;}@keyframes borderPulse{0%,100%{border-color:rgba(187,158,28,0.18);}50%{border-color:rgba(187,158,28,0.42);}}#lima-ad-gen .upload-icon{display:inline-block;animation:floatIcon 3s ease-in-out infinite;}@keyframes floatIcon{0%,100%{transform:translateY(0);}50%{transform:translateY(-7px);}}#lima-ad-gen .btn-generate{position:relative;overflow:hidden;}#lima-ad-gen .btn-generate::after{content:'';position:absolute;top:0;left:-100%;width:60%;height:100%;background:linear-gradient(90deg,transparent,rgba(255,255,255,0.18),transparent);animation:btnShimmer 2.8s ease-in-out infinite;}@keyframes btnShimmer{0%{left:-60%;}60%{left:110%;}100%{left:110%;}}#lima-ad-gen .spin-ring{box-shadow:0 0 16px rgba(187,158,28,0.25);animation:spin 0.9s linear infinite,ringGlow 1.8s ease-in-out infinite alternate;}@keyframes ringGlow{from{box-shadow:0 0 8px rgba(187,158,28,0.15);}to{box-shadow:0 0 28px rgba(187,158,28,0.45);}}#lima-ad-gen .proc-step::after{content:'\u258b';animation:blink 1s step-end infinite;margin-left:3px;color:var(--gold);}@keyframes blink{0%,100%{opacity:1;}50%{opacity:0;}}#lima-ad-gen #results-section{animation:resultsEntry 0.65s cubic-bezier(0.22,1,0.36,1) both;}@keyframes resultsEntry{from{opacity:0;transform:translateY(30px);}to{opacity:1;transform:translateY(0);}}#lima-ad-gen .di{animation:diSlide 0.5s cubic-bezier(0.22,1,0.36,1) both;}#lima-ad-gen .di:nth-child(1){animation-delay:0.05s;}#lima-ad-gen .di:nth-child(2){animation-delay:0.10s;}#lima-ad-gen .di:nth-child(3){animation-delay:0.15s;}#lima-ad-gen .di:nth-child(4){animation-delay:0.20s;}#lima-ad-gen .di:nth-child(5){animation-delay:0.25s;}#lima-ad-gen .di:nth-child(6){animation-delay:0.30s;}#lima-ad-gen .di:nth-child(7){animation-delay:0.35s;}#lima-ad-gen .di:nth-child(8){animation-delay:0.40s;}@keyframes diSlide{from{opacity:0;transform:translateX(-12px);}to{opacity:1;transform:translateX(0);}}#lima-ad-gen .pt{position:relative;overflow:hidden;}#lima-ad-gen .pt::after{content:'';position:absolute;bottom:0;left:50%;width:0;height:2px;background:var(--gold);transform:translateX(-50%);transition:width 0.3s cubic-bezier(0.22,1,0.36,1);}#lima-ad-gen .pt.active::after{width:100%;}#lima-ad-gen .av{animation:avAppear 0.45s cubic-bezier(0.22,1,0.36,1) both;}#lima-ad-gen .av:nth-child(1){animation-delay:0.1s;}#lima-ad-gen .av:nth-child(2){animation-delay:0.22s;}@keyframes avAppear{from{opacity:0;transform:translateY(16px);}to{opacity:1;transform:translateY(0);}}#lima-ad-gen .toast{transition:opacity 0.3s ease,transform 0.35s cubic-bezier(0.34,1.56,0.64,1);}#lima-ad-gen .toast.show{animation:toastIn 0.35s cubic-bezier(0.34,1.56,0.64,1) forwards;}@keyframes toastIn{from{opacity:0;transform:translateX(20px) translateY(0);}to{opacity:1;transform:translateX(0) translateY(0);}}#lima-ad-gen .account-card{animation:acardIn 0.5s cubic-bezier(0.22,1,0.36,1) both;}#lima-ad-gen .account-card:nth-child(1){animation-delay:0.05s;}#lima-ad-gen .account-card:nth-child(2){animation-delay:0.12s;}#lima-ad-gen .account-card:nth-child(3){animation-delay:0.19s;}#lima-ad-gen .account-card:nth-child(4){animation-delay:0.26s;}#lima-ad-gen .account-card:nth-child(5){animation-delay:0.33s;}#lima-ad-gen .account-card:nth-child(6){animation-delay:0.40s;}#lima-ad-gen .account-card:nth-child(7){animation-delay:0.47s;}#lima-ad-gen .account-card:nth-child(8){animation-delay:0.54s;}@keyframes acardIn{from{opacity:0;transform:scale(0.93) translateY(10px);}to{opacity:1;transform:scale(1) translateY(0);}}#lima-ad-gen .account-card.connected{animation:connectedPulse 3s ease-in-out infinite alternate;}@keyframes connectedPulse{from{border-color:rgba(61,153,112,0.25);box-shadow:0 0 0 rgba(61,153,112,0);}to{border-color:rgba(61,153,112,0.6);box-shadow:0 0 16px rgba(61,153,112,0.12);}}#lima-ad-gen .section-divider::before,#lima-ad-gen .section-divider::after{background:linear-gradient(90deg,transparent,var(--gold),transparent);background-size:200% 1px;animation:dividerShimmer 3s linear infinite;}@keyframes dividerShimmer{from{background-position:200% center;}to{background-position:-200% center;}}#lima-ad-gen .modal{animation:modalIn 0.35s cubic-bezier(0.34,1.56,0.64,1) both;}@keyframes modalIn{from{opacity:0;transform:scale(0.88) translateY(20px);}to{opacity:1;transform:scale(1) translateY(0);}}#lima-ad-gen .im-tab{position:relative;}#lima-ad-gen .im-tab::after{content:'';position:absolute;bottom:0;left:0;width:0;height:2px;background:var(--gold);transition:width 0.3s ease;}#lima-ad-gen .im-tab.active::after{width:100%;}#lima-ad-gen .btn-primary,#lima-ad-gen .modal-btn-primary,#lima-ad-gen .post-btn-direct{transition:transform 0.12s ease,background 0.2s ease,box-shadow 0.2s ease;}#lima-ad-gen .btn-primary:active,#lima-ad-gen .modal-btn-primary:active,#lima-ad-gen .post-btn-direct:active{transform:scale(0.97);}#lima-ad-gen .tgl input:checked+.tgl-pill{animation:pillBounce 0.3s cubic-bezier(0.34,1.56,0.64,1);}@keyframes pillBounce{from{transform:scale(0.88);}to{transform:scale(1);}}#lima-ad-gen .version-tag{animation:tagPulse 4s ease-in-out infinite alternate;}@keyframes tagPulse{from{box-shadow:0 0 0 rgba(187,158,28,0);}to{box-shadow:0 0 12px rgba(187,158,28,0.2);}}#lima-ad-gen .api-connector{position:relative;top:auto;left:auto;right:auto;z-index:auto;background:#fff8f0;border-bottom:2px solid var(--gold);padding:0;font-family:'Poppins',sans-serif;box-shadow:0 4px 24px rgba(187,158,28,0.15);transition:transform 0.4s cubic-bezier(0.22,1,0.36,1);}#lima-ad-gen .api-connector.hidden{display:none;}#lima-ad-gen .api-bar{display:flex;align-items:center;gap:14px 18px;padding:12px 28px;flex-wrap:wrap;row-gap:10px;}#lima-ad-gen .api-bar-status{display:flex;align-items:center;gap:8px;font-size:11px;letter-spacing:1.5px;text-transform:uppercase;color:var(--text-muted);white-space:nowrap;}#lima-ad-gen .api-status-dot{width:7px;height:7px;border-radius:50%;background:#e0c060;flex-shrink:0;animation:dotBlink 2s ease-in-out infinite;}#lima-ad-gen .api-status-dot.connected{background:var(--success);animation:none;}@keyframes dotBlink{0%,100%{opacity:1}50%{opacity:0.3}}#lima-ad-gen .api-provider-tabs{display:flex;gap:4px;flex-shrink:0;}#lima-ad-gen .api-ptab{padding:6px 14px;font-size:10px;letter-spacing:1.5px;text-transform:uppercase;cursor:pointer;border:1px solid var(--border);color:var(--text-muted);background:transparent;font-family:'Poppins',sans-serif;transition:all 0.2s;}#lima-ad-gen .api-ptab.active{border-color:var(--gold);color:var(--gold);background:var(--gold-dim);}#lima-ad-gen .api-key-wrap{flex:1;display:flex;gap:8px;min-width:260px;}#lima-ad-gen .api-key-input{flex:1;padding:8px 14px;background:#f5f3ee;border:1px solid var(--border);color:#1a1a1a;font-family:'Poppins',sans-serif;font-size:12px;outline:none;letter-spacing:0.5px;transition:border-color 0.2s;}#lima-ad-gen .api-key-input:focus{border-color:var(--gold);}#lima-ad-gen .api-key-input::placeholder{color:#b0a898;}#lima-ad-gen .api-save-btn{padding:8px 20px;background:var(--gold);color:#1a1a1a;border:none;font-family:'Poppins',sans-serif;font-size:10px;font-weight:600;letter-spacing:2px;text-transform:uppercase;cursor:pointer;transition:all 0.2s;white-space:nowrap;}#lima-ad-gen .api-save-btn:hover{background:var(--gold-light);}#lima-ad-gen .api-clear-btn{padding:8px 14px;background:transparent;border:1px solid rgba(0,0,0,0.12);color:var(--text-muted);font-family:'Poppins',sans-serif;font-size:10px;letter-spacing:1px;text-transform:uppercase;cursor:pointer;transition:all 0.2s;white-space:nowrap;}#lima-ad-gen .api-clear-btn:hover{border-color:#c0392b;color:#c0392b;}#lima-ad-gen .api-info-text{font-size:10px;color:var(--text-muted);letter-spacing:0.3px;white-space:nowrap;}#lima-ad-gen .api-info-text a{color:var(--gold);text-decoration:none;}#lima-ad-gen .api-info-text a:hover{text-decoration:underline;}#lima-ad-gen .api-connected-bar{display:none;align-items:center;gap:12px;padding:8px 28px;background:rgba(61,153,112,0.06);border-top:1px solid rgba(61,153,112,0.2);font-size:10px;letter-spacing:1.5px;text-transform:uppercase;}#lima-ad-gen .api-connected-bar.show{display:flex;}#lima-ad-gen .api-connected-badge{display:flex;align-items:center;gap:6px;color:var(--success);font-weight:500;}#lima-ad-gen .api-connected-badge::before{content:'\u25cf';font-size:8px;}#lima-ad-gen .app{}#lima-ad-gen .btn-generate.locked{background:#ccc;cursor:not-allowed;color:#888;}#lima-ad-gen .btn-generate.locked::after{display:none;}#lima-ad-gen .key-hint{text-align:center;font-size:11px;color:#c0392b;margin-top:8px;letter-spacing:0.5px;display:none;}#lima-ad-gen .key-hint.show{display:block;}#lima-ad-gen .api-help-section{background:#fffdf5;border-top:1px solid rgba(187,158,28,0.2);padding:0 28px;}#lima-ad-gen .api-help-accordions{display:flex;flex-direction:column;gap:0;}#lima-ad-gen .api-accordion{border-bottom:1px solid rgba(187,158,28,0.15);}#lima-ad-gen .api-accordion:last-child{border-bottom:none;}#lima-ad-gen .api-accordion-trigger{display:flex;align-items:center;justify-content:space-between;padding:11px 0;cursor:pointer;user-select:none;gap:12px;background:none;border:none;width:100%;text-align:left;font-family:'Poppins',sans-serif;}#lima-ad-gen .api-accordion-trigger:hover .api-acc-title{color:#1a1a1a;}#lima-ad-gen .api-acc-left{display:flex;align-items:center;gap:10px;}#lima-ad-gen .api-acc-icon{font-size:14px;flex-shrink:0;}#lima-ad-gen .api-acc-title{font-size:10px;letter-spacing:2px;text-transform:uppercase;color:var(--text-muted);transition:color 0.2s;}#lima-ad-gen .api-acc-badge{font-size:8px;letter-spacing:1px;padding:2px 7px;border:1px solid var(--border);color:var(--gold);text-transform:uppercase;}#lima-ad-gen .api-acc-arrow{font-size:10px;color:var(--gold);transition:transform 0.3s cubic-bezier(0.22,1,0.36,1);flex-shrink:0;}#lima-ad-gen .api-accordion.open .api-acc-arrow{transform:rotate(180deg);}#lima-ad-gen .api-accordion-body{display:none;padding:0 0 16px 0;}#lima-ad-gen .api-accordion.open .api-accordion-body{display:block;}#lima-ad-gen .api-steps{display:flex;flex-direction:column;gap:6px;margin-bottom:12px;}#lima-ad-gen .api-step{display:flex;align-items:flex-start;gap:10px;font-size:11px;color:#3a3530;line-height:1.6;}#lima-ad-gen .api-step-num{width:18px;height:18px;border-radius:50%;background:var(--gold);color:#fff;font-size:9px;font-weight:600;display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-top:1px;}#lima-ad-gen .api-step a{color:var(--gold);text-decoration:none;font-weight:500;}#lima-ad-gen .api-step a:hover{text-decoration:underline;}#lima-ad-gen .api-note{font-size:10px;color:#7a6a50;padding:8px 12px;background:rgba(187,158,28,0.07);border-left:2px solid var(--gold);line-height:1.6;margin-top:4px;}#lima-ad-gen .api-note strong{color:var(--gold);}#lima-ad-gen .api-warning{font-size:10px;color:#8b4513;padding:10px 14px;background:rgba(255,100,0,0.06);border-left:2px solid #e07030;line-height:1.6;margin-top:10px;}#lima-ad-gen .api-warning strong{color:#c0501a;}#lima-ad-gen .api-warning a{color:#c0501a;}#lima-ad-gen .api-two-col{display:grid;grid-template-columns:1fr 1fr;gap:16px;}@media(max-width:640px){#lima-ad-gen .api-two-col{grid-template-columns:1fr;}}#lima-ad-gen .api-help-toggle{display:flex;align-items:center;gap:6px;font-size:9px;letter-spacing:2px;text-transform:uppercase;color:var(--text-muted);cursor:pointer;padding:8px 0;border:none;background:none;font-family:'Poppins',sans-serif;transition:color 0.2s;white-space:nowrap;}#lima-ad-gen .api-help-toggle:hover{color:var(--gold);}#lima-ad-gen .api-help-toggle .toggle-arrow{font-size:9px;transition:transform 0.3s;color:var(--gold);}#lima-ad-gen .api-help-section.collapsed{display:none;}#lima-ad-gen .transform-btn{padding:7px 13px;font-family:'Poppins',sans-serif;font-size:10px;letter-spacing:1px;border:1px solid var(--border);background:#fff;color:var(--text-muted);cursor:pointer;transition:all 0.2s;white-space:nowrap;}#lima-ad-gen .transform-btn:hover{border-color:var(--gold);color:var(--gold);}#lima-ad-gen .transform-btn.active{border-color:var(--gold);background:var(--gold-dim);color:var(--gold);font-weight:600;}#lima-ad-gen .transform-btn:disabled{opacity:0.4;cursor:wait;}#lima-ad-gen .transform-spinner{display:inline-block;width:10px;height:10px;border:1.5px solid rgba(187,158,28,0.3);border-top-color:var(--gold);border-radius:50%;animation:spin 0.7s linear infinite;margin-right:4px;vertical-align:middle;}#lima-ad-gen .imggen-section{margin-top:20px;background:#fff;border:1px solid var(--border);padding:20px;}#lima-ad-gen .imggen-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px;padding-bottom:12px;border-bottom:1px solid rgba(187,158,28,0.15);}#lima-ad-gen .imggen-title{font-size:9px;letter-spacing:3px;text-transform:uppercase;color:var(--gold);display:flex;align-items:center;gap:8px;}#lima-ad-gen .imggen-controls{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:16px;}#lima-ad-gen .imggen-field label{display:block;font-size:9px;letter-spacing:1.5px;text-transform:uppercase;color:var(--text-muted);margin-bottom:5px;}#lima-ad-gen .imggen-input{width:100%;padding:8px 12px;background:#f5f3ee;border:1px solid rgba(187,158,28,0.2);color:#1a1a1a;font-family:'Poppins',sans-serif;font-size:11px;outline:none;transition:border-color 0.2s;}#lima-ad-gen .imggen-input:focus{border-color:var(--gold);}#lima-ad-gen .imggen-row{display:flex;gap:10px;flex-wrap:wrap;align-items:flex-end;margin-bottom:16px;}#lima-ad-gen .imggen-select{padding:8px 12px;background:#f5f3ee;border:1px solid rgba(187,158,28,0.2);color:#1a1a1a;font-family:'Poppins',sans-serif;font-size:11px;outline:none;cursor:pointer;}#lima-ad-gen .imggen-select:focus{border-color:var(--gold);}#lima-ad-gen .imggen-color-wrap{display:flex;align-items:center;gap:8px;}#lima-ad-gen .imggen-color{width:36px;height:36px;border:1px solid var(--border);cursor:pointer;padding:2px;background:none;}#lima-ad-gen .imggen-btn{padding:9px 20px;background:var(--gold);color:#1a1a1a;border:none;font-family:'Poppins',sans-serif;font-size:10px;font-weight:600;letter-spacing:2px;text-transform:uppercase;cursor:pointer;transition:all 0.2s;white-space:nowrap;}#lima-ad-gen .imggen-btn:hover{background:var(--gold-light);}#lima-ad-gen .imggen-btn:disabled{opacity:0.4;cursor:wait;}#lima-ad-gen .imggen-btn-sec{padding:9px 16px;background:transparent;border:1px solid var(--border);color:var(--text-muted);font-family:'Poppins',sans-serif;font-size:10px;letter-spacing:1.5px;text-transform:uppercase;cursor:pointer;transition:all 0.2s;}#lima-ad-gen .imggen-btn-sec:hover{border-color:var(--gold);color:var(--gold);}#lima-ad-gen .imggen-btn-sec:disabled{opacity:0.4;cursor:wait;}#lima-ad-gen .imggen-images{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-top:16px;}#lima-ad-gen .imggen-img-wrap{position:relative;border:1px solid rgba(187,158,28,0.2);overflow:hidden;background:#f5f3ee;aspect-ratio:1\/1;}#lima-ad-gen .imggen-img-wrap img{width:100%;height:100%;object-fit:cover;display:block;transition:opacity 0.4s;}#lima-ad-gen .imggen-img-label{position:absolute;bottom:0;left:0;right:0;background:rgba(0,0,0,0.55);color:#fff;font-size:9px;letter-spacing:1.5px;text-transform:uppercase;padding:6px 10px;}#lima-ad-gen .imggen-img-actions{position:absolute;top:8px;right:8px;display:flex;gap:6px;opacity:0;transition:opacity 0.2s;}#lima-ad-gen .imggen-img-wrap:hover .imggen-img-actions{opacity:1;}#lima-ad-gen .imggen-img-btn{background:rgba(0,0,0,0.6);color:#fff;border:none;padding:5px 9px;font-size:9px;letter-spacing:1px;text-transform:uppercase;cursor:pointer;font-family:'Poppins',sans-serif;}#lima-ad-gen .imggen-img-btn:hover{background:rgba(187,158,28,0.8);}#lima-ad-gen .imggen-placeholder{display:flex;align-items:center;justify-content:center;height:100%;flex-direction:column;gap:8px;color:var(--text-muted);}#lima-ad-gen .imggen-placeholder-icon{font-size:28px;opacity:0.4;}#lima-ad-gen .imggen-placeholder-text{font-size:9px;letter-spacing:1.5px;text-transform:uppercase;opacity:0.6;}#lima-ad-gen .imggen-loading{display:flex;align-items:center;justify-content:center;height:100%;flex-direction:column;gap:12px;}#lima-ad-gen .imggen-spin{width:32px;height:32px;border:2px solid rgba(187,158,28,0.2);border-top-color:var(--gold);border-radius:50%;animation:spin 0.8s linear infinite;}#lima-ad-gen .imggen-error{padding:12px;background:rgba(192,57,43,0.06);border-left:2px solid #c0392b;font-size:11px;color:#8b2008;margin-top:8px;}@media(max-width:600px){#lima-ad-gen .imggen-images{grid-template-columns:1fr;}#lima-ad-gen .imggen-controls{grid-template-columns:1fr;}}\n#lima-ad-gen .api-bar{display:flex;flex-direction:column;gap:10px;padding:12px 28px;}\n#lima-ad-gen .api-bar-row{display:flex;align-items:center;gap:14px;flex-wrap:wrap;width:100%;}\n#lima-ad-gen .api-bar-row-top{justify-content:flex-start;}\n#lima-ad-gen .api-bar-row-bottom{gap:12px;}\n#lima-ad-gen .api-bar-row-top .api-help-toggle{margin-left:auto;}\n#lima-ad-gen .api-info-text{flex-shrink:0;white-space:nowrap;}\n@media(max-width:640px){#lima-ad-gen .api-info-text{white-space:normal;}#lima-ad-gen .api-key-wrap{min-width:100%;}}\n\n\/* Codex fix: prevent variant\/copy overlap and move transform controls into posting options *\/\n#lima-ad-gen .av-head{gap:10px;align-items:flex-start;justify-content:flex-start;flex-wrap:wrap;}\n#lima-ad-gen .av-label{flex-shrink:0;line-height:1.6;}\n#lima-ad-gen .av-tag{margin-left:auto;max-width:min(420px,55%);white-space:normal;line-height:1.45;text-align:right;}\n#lima-ad-gen .copy-btn{position:static;top:auto;right:auto;opacity:1;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;min-height:24px;background:#fff;}\n#lima-ad-gen .av:hover .copy-btn{opacity:1;}\n#lima-ad-gen .pp-top{display:flex;align-items:center;justify-content:space-between;gap:12px 18px;flex-wrap:wrap;margin-bottom:14px;}\n#lima-ad-gen .pp-top .pp-title{margin-bottom:0;flex-shrink:0;}\n#lima-ad-gen .transform-controls{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-left:auto;}\n#lima-ad-gen .transform-label{font-size:9px;letter-spacing:2px;text-transform:uppercase;color:var(--text-muted);white-space:nowrap;}\n#lima-ad-gen .transform-btn-group{display:flex;gap:6px;flex-wrap:wrap;}\n#lima-ad-gen .action-bar{justify-content:flex-start;}\n#lima-ad-gen .post-btn-instagram{background:#e4405f;color:#fff;}\n#lima-ad-gen .post-btn-tiktok{background:#111;color:#fff;}\n#lima-ad-gen .post-btn-facebook{background:#1877f2;color:#fff;}\n#lima-ad-gen .post-btn-linkedin{background:#0a66c2;color:#fff;}\n#lima-ad-gen .post-btn-xtwitter{background:#111;color:#fff;}\n#lima-ad-gen .post-btn-telegram{background:#2ca5e0;color:#fff;}\n@media(max-width:760px){\n  #lima-ad-gen .av-tag{margin-left:0;max-width:100%;text-align:left;}\n  #lima-ad-gen .copy-btn{margin-left:auto;}\n  #lima-ad-gen .transform-controls{width:100%;margin-left:0;}\n}\n\n\n\/* Codex fix: compact looping hero video for real estate ad generation *\/\n#lima-ad-gen header.hero-video-header{height:clamp(168px,20vw,248px);min-height:168px;padding:0;line-height:normal;background:#111;margin-bottom:18px;}\n#lima-ad-gen .hero-video-wrap{position:absolute;inset:0;overflow:hidden;background:#111;}\n#lima-ad-gen .hero-video{width:100%;height:100%;display:block;object-fit:cover;object-position:center 48%;filter:saturate(0.86) contrast(1.05) brightness(0.98);}\n#lima-ad-gen .hero-video-overlay{position:absolute;inset:0;pointer-events:none;background:linear-gradient(90deg,rgba(245,243,238,0.94) 0%,rgba(245,243,238,0.76) 35%,rgba(245,243,238,0.30) 66%,rgba(26,26,26,0.18) 100%),linear-gradient(0deg,rgba(26,26,26,0.22),rgba(245,243,238,0.00) 58%);}\n#lima-ad-gen .hero-video-content{position:absolute;z-index:2;left:28px;top:50%;transform:translateY(-50%);width:min(690px,calc(100% - 265px));color:var(--text);pointer-events:none;}\n#lima-ad-gen .hero-kicker{display:inline-flex;align-items:center;gap:8px;font-size:9px;letter-spacing:0;text-transform:uppercase;color:var(--gold);padding:5px 10px;background:rgba(255,255,255,0.74);border:1px solid rgba(187,158,28,0.28);backdrop-filter:blur(8px);}\n#lima-ad-gen .hero-kicker::before{content:'';width:7px;height:7px;border-radius:50%;background:var(--gold);box-shadow:0 0 0 5px rgba(187,158,28,0.12);}\n#lima-ad-gen .hero-title{margin-top:10px;max-width:690px;font-family:'Cormorant Garamond',serif;font-size:clamp(26px,3.2vw,44px);font-weight:300;line-height:0.98;letter-spacing:0;color:var(--text);}\n#lima-ad-gen .hero-title span{font-style:italic;color:var(--gold);}\n#lima-ad-gen .hero-sub{margin-top:9px;max-width:590px;font-size:12px;line-height:1.55;letter-spacing:0;color:var(--text-sub);}\n#lima-ad-gen .hero-flow{display:flex;align-items:center;gap:7px;margin-top:12px;flex-wrap:wrap;}\n#lima-ad-gen .hero-flow span{font-size:9px;letter-spacing:0;text-transform:uppercase;color:#1a1a1a;background:rgba(255,255,255,0.80);border:1px solid rgba(187,158,28,0.24);padding:6px 10px;backdrop-filter:blur(8px);}\n#lima-ad-gen .hero-flow i{font-style:normal;color:var(--gold);font-size:13px;}\n#lima-ad-gen .hero-social-preview{position:absolute;z-index:2;right:28px;top:48%;transform:translateY(-50%);width:178px;display:grid;gap:7px;pointer-events:none;}\n#lima-ad-gen .hero-preview-card{padding:8px 10px;background:rgba(255,255,255,0.82);border:1px solid rgba(187,158,28,0.30);box-shadow:0 14px 34px rgba(0,0,0,0.10);backdrop-filter:blur(10px);animation:heroPreviewPulse 5.6s ease-in-out infinite;}\n#lima-ad-gen .hero-preview-card:nth-child(2){animation-delay:0.9s;}\n#lima-ad-gen .hero-preview-card:nth-child(3){animation-delay:1.8s;}\n#lima-ad-gen .hero-preview-card strong{display:block;font-size:9px;letter-spacing:0;text-transform:uppercase;color:var(--gold);margin-bottom:3px;}\n#lima-ad-gen .hero-preview-card span{display:block;font-size:10px;line-height:1.35;letter-spacing:0;color:var(--text-sub);}\n@keyframes heroPreviewPulse{0%,100%{opacity:0.78;transform:translateX(0);}50%{opacity:1;transform:translateX(-6px);}}\n#lima-ad-gen header.hero-video-header .header-right{z-index:3;}\n@media(max-width:900px){#lima-ad-gen .hero-video-content{top:52%;width:calc(100% - 56px);}#lima-ad-gen .hero-title{max-width:520px;font-size:clamp(28px,4vw,34px);line-height:1.02;}#lima-ad-gen .hero-sub{display:none;}#lima-ad-gen .hero-social-preview,#lima-ad-gen header.hero-video-header .header-right{display:none;}}\n@media(max-width:640px){#lima-ad-gen header.hero-video-header{height:158px;min-height:158px;padding:0;}#lima-ad-gen header.hero-video-header .header-right{right:12px!important;top:10px;bottom:auto;}#lima-ad-gen .hero-video-content{left:16px;right:16px;top:56%;width:auto;}#lima-ad-gen .hero-kicker{font-size:8px;padding:4px 8px;}#lima-ad-gen .hero-title{font-size:26px;max-width:76%;}#lima-ad-gen .hero-sub{display:none;}#lima-ad-gen .hero-flow{margin-top:8px;gap:5px;}#lima-ad-gen .hero-flow span{font-size:8px;padding:5px 7px;}#lima-ad-gen .hero-flow i{font-size:10px;}}\n@media(max-width:420px){#lima-ad-gen .hero-flow span:nth-of-type(2),#lima-ad-gen .hero-flow i:nth-of-type(2){display:none;}#lima-ad-gen .hero-title{max-width:100%;font-size:24px;}}\n@media(prefers-reduced-motion:reduce){#lima-ad-gen .hero-preview-card{animation:none;}}\n\n\/* Codex fix: real estate photo edit upload + enhancement sliders *\/\n#lima-ad-gen .imgedit-panel{margin:0 0 16px;border:1px solid rgba(187,158,28,0.2);background:#fffdf8;}\n#lima-ad-gen .imgedit-drop{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:14px;padding:16px;background:#f5f3ee;border-bottom:1px dashed rgba(187,158,28,0.35);cursor:pointer;transition:background 0.2s,border-color 0.2s;}\n#lima-ad-gen .imgedit-drop:hover,#lima-ad-gen .imgedit-drop.drag-over{background:rgba(187,158,28,0.10);border-color:var(--gold);}\n#lima-ad-gen .imgedit-drop-icon{width:36px;height:36px;display:flex;align-items:center;justify-content:center;border:1px solid var(--border);color:var(--gold);font-size:18px;background:#fff;}\n#lima-ad-gen .imgedit-drop-title{font-size:11px;font-weight:600;letter-spacing:1.7px;text-transform:uppercase;color:var(--text);}\n#lima-ad-gen .imgedit-drop-sub{font-size:10px;color:var(--text-muted);letter-spacing:0.5px;margin-top:3px;line-height:1.5;}\n#lima-ad-gen .imgedit-preview{display:none;grid-template-columns:82px 1fr auto;align-items:center;gap:14px;padding:12px 16px;border-bottom:1px solid rgba(187,158,28,0.15);background:#fff;}\n#lima-ad-gen .imgedit-preview img{width:82px;height:62px;object-fit:cover;border:1px solid rgba(187,158,28,0.22);display:block;}\n#lima-ad-gen .imgedit-preview-name{font-size:11px;font-weight:500;color:var(--text);word-break:break-word;}\n#lima-ad-gen .imgedit-preview-meta{font-size:9px;letter-spacing:1.2px;text-transform:uppercase;color:var(--text-muted);margin-top:3px;}\n#lima-ad-gen .imgedit-sliders{padding:14px 16px;}\n#lima-ad-gen .imgedit-slider-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:12px;}\n#lima-ad-gen .imgedit-slider-head span{font-size:9px;letter-spacing:2.5px;text-transform:uppercase;color:var(--gold);}\n#lima-ad-gen .imgedit-reset{padding:6px 10px;font-size:8px;}\n#lima-ad-gen .imgedit-slider-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px 12px;}\n#lima-ad-gen .imgedit-toggle{display:grid;grid-template-columns:minmax(0,1fr) 74px;align-items:center;gap:12px;padding:10px 12px;background:#f8f6ef;border:1px solid rgba(0,0,0,0.04);cursor:pointer;transition:border-color 0.2s,background 0.2s;}\n#lima-ad-gen .imgedit-toggle.active{border-color:rgba(187,158,28,0.45);background:rgba(187,158,28,0.10);}\n#lima-ad-gen .imgedit-toggle span{font-size:10px;color:var(--text-sub);line-height:1.35;}\n#lima-ad-gen .imgedit-toggle input{display:none;}\n#lima-ad-gen .imgedit-value{position:relative;min-width:74px;height:30px;border-radius:999px;padding:0 11px;border:1px solid rgba(0,0,0,0.12);background:#fff;color:var(--text-muted);font-size:9px;font-style:normal;letter-spacing:1px;text-transform:uppercase;display:flex;align-items:center;justify-content:flex-end;transition:background 0.2s,border-color 0.2s,color 0.2s;}\n#lima-ad-gen .imgedit-value::before{content:'';position:absolute;left:3px;top:2px;width:24px;height:24px;border-radius:50%;background:#c9c2b3;box-shadow:0 2px 7px rgba(0,0,0,0.18);transition:left 0.22s cubic-bezier(0.22,1,0.36,1),background 0.2s;}\n#lima-ad-gen .imgedit-toggle.active .imgedit-value{justify-content:flex-start;border-color:var(--gold);background:var(--gold);color:#1a1a1a;font-weight:600;}\n#lima-ad-gen .imgedit-toggle.active .imgedit-value::before{left:calc(100% - 27px);background:#fff;}\n@media(max-width:760px){#lima-ad-gen .imgedit-drop{grid-template-columns:auto 1fr;}#lima-ad-gen .imgedit-drop .imggen-btn-sec{grid-column:1\/-1;width:100%;}#lima-ad-gen .imgedit-preview{grid-template-columns:72px 1fr;}#lima-ad-gen .imgedit-preview .imggen-btn-sec{grid-column:1\/-1;}#lima-ad-gen .imgedit-slider-grid{grid-template-columns:1fr;}}\n#lima-ad-gen .imglogo-panel{margin-top:14px;padding:14px;background:#fffdf8;border:1px solid rgba(187,158,28,0.2);}\n#lima-ad-gen .imglogo-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:12px;flex-wrap:wrap;}\n#lima-ad-gen .imglogo-title{font-size:9px;letter-spacing:2.5px;text-transform:uppercase;color:var(--gold);}\n#lima-ad-gen .imglogo-preview{display:none;align-items:center;gap:10px;margin:8px 0 12px;padding:8px;background:#fff;border:1px solid rgba(187,158,28,0.16);}\n#lima-ad-gen .imglogo-preview img{width:54px;height:38px;object-fit:contain;background:#f5f3ee;border:1px solid rgba(0,0,0,0.06);}\n#lima-ad-gen .imglogo-name{font-size:10px;color:var(--text);word-break:break-word;}\n#lima-ad-gen .imglogo-controls{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;}\n#lima-ad-gen .imglogo-range{display:flex;align-items:center;gap:8px;}\n#lima-ad-gen .imglogo-range input{flex:1;accent-color:var(--gold);}\n#lima-ad-gen .imglogo-value{font-size:9px;color:var(--gold);min-width:38px;text-align:right;}\n@media(max-width:760px){#lima-ad-gen .imglogo-controls{grid-template-columns:1fr;}}\n\n<\/style>\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/pdf.js\/3.11.174\/pdf.min.js\"><\/script>\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\"><link href=\"https:\/\/fonts.googleapis.com\/css2?family=Playfair+Display:wght@400;600;700&family=Montserrat:wght@400;600;700&family=Bebas+Neue&family=Oswald:wght@400;600&display=swap\" rel=\"stylesheet\">\n<\/head>\n<body>\n<div id=\"lima-ad-gen\">\n\n\n<!-- ===== API KEY CONNECTOR ===== -->\n<div class=\"api-connector\" id=\"api-connector\">\n  <div class=\"api-bar\">\n    <div class=\"api-bar-row api-bar-row-top\">\n      <div class=\"api-bar-status\">\n        <span class=\"api-status-dot\" id=\"api-dot\"><\/span>\n        <span id=\"api-status-label\">KI nicht verbunden<\/span>\n      <\/div>\n      <div class=\"api-provider-tabs\">\n        <button class=\"api-ptab active\" onclick=\"selectProvider('anthropic')\" id=\"tab-anthropic\">\ud83e\udd16 Claude<\/button>\n        <button class=\"api-ptab\" onclick=\"selectProvider('openai')\" id=\"tab-openai\">\u2726 ChatGPT<\/button>\n      <\/div>\n      <button class=\"api-help-toggle\" onclick=\"toggleApiHelp()\" id=\"api-help-toggle-btn\">\n        <span>Anleitung<\/span>\n        <span class=\"toggle-arrow\" id=\"api-help-arrow\">\u25be<\/span>\n      <\/button>\n    <\/div>\n    <div class=\"api-bar-row api-bar-row-bottom\">\n      <div class=\"api-key-wrap\">\n        <input\n          type=\"password\"\n          id=\"api-key-input\"\n          class=\"api-key-input\"\n          placeholder=\"sk-ant-... API-Key eingeben\"\n          autocomplete=\"off\"\n          spellcheck=\"false\"\n        \/>\n        <button class=\"api-save-btn\" onclick=\"saveApiKey()\">Verbinden<\/button>\n        <button class=\"api-clear-btn\" onclick=\"clearApiKey()\" id=\"clear-btn\" style=\"display:none;\">Trennen<\/button>\n      <\/div>\n      <div class=\"api-info-text\" id=\"api-info-text\">\n        Claude Key: <a href=\"https:\/\/console.anthropic.com\/settings\/keys\" target=\"_blank\" rel=\"noopener\">console.anthropic.com<\/a>\n      <\/div>\n    <\/div>\n  <\/div>\n\n  <!-- API KEY HELP SECTION -->\n  <div class=\"api-help-section collapsed\" id=\"api-help-section\">\n    <div class=\"api-two-col\" style=\"padding:14px 0;\">\n\n      <!-- OpenAI -->\n      <div class=\"api-accordion\" id=\"acc-openai\">\n        <button class=\"api-accordion-trigger\" onclick=\"toggleAcc('acc-openai')\">\n          <div class=\"api-acc-left\">\n            <span class=\"api-acc-icon\">\u2726<\/span>\n            <span class=\"api-acc-title\">ChatGPT \/ OpenAI API Key<\/span>\n          <\/div>\n          <span class=\"api-acc-arrow\">\u25be<\/span>\n        <\/button>\n        <div class=\"api-accordion-body\">\n          <div class=\"api-steps\">\n            <div class=\"api-step\"><span class=\"api-step-num\">1<\/span><span>Gehe auf <a href=\"https:\/\/platform.openai.com\" target=\"_blank\" rel=\"noopener\">platform.openai.com<\/a><\/span><\/div>\n            <div class=\"api-step\"><span class=\"api-step-num\">2<\/span><span>Mit deinem OpenAI\/ChatGPT-Konto einloggen<\/span><\/div>\n            <div class=\"api-step\"><span class=\"api-step-num\">3<\/span><span>Bereich <strong>API Keys<\/strong> \u00f6ffnen<\/span><\/div>\n            <div class=\"api-step\"><span class=\"api-step-num\">4<\/span><span>Auf <strong>Create new secret key<\/strong> klicken<\/span><\/div>\n            <div class=\"api-step\"><span class=\"api-step-num\">5<\/span><span>Key sofort kopieren und sicher abspeichern<\/span><\/div>\n          <\/div>\n          <div class=\"api-note\">\n            \u26a0 <strong>Wichtig:<\/strong> Der Key wird nur einmal angezeigt. Verlierst du ihn, musst du einen neuen erstellen.\n            OpenAI empfiehlt projektbezogene Keys mit eingeschr\u00e4nkten Berechtigungen.\n          <\/div>\n        <\/div>\n      <\/div>\n\n      <!-- Claude -->\n      <div class=\"api-accordion\" id=\"acc-claude\">\n        <button class=\"api-accordion-trigger\" onclick=\"toggleAcc('acc-claude')\">\n          <div class=\"api-acc-left\">\n            <span class=\"api-acc-icon\">\ud83e\udd16<\/span>\n            <span class=\"api-acc-title\">Claude \/ Anthropic API Key<\/span>\n          <\/div>\n          <span class=\"api-acc-arrow\">\u25be<\/span>\n        <\/button>\n        <div class=\"api-accordion-body\">\n          <div class=\"api-steps\">\n            <div class=\"api-step\"><span class=\"api-step-num\">1<\/span><span>Gehe auf <a href=\"https:\/\/console.anthropic.com\" target=\"_blank\" rel=\"noopener\">console.anthropic.com<\/a><\/span><\/div>\n            <div class=\"api-step\"><span class=\"api-step-num\">2<\/span><span>Einloggen oder Anthropic-Konto erstellen<\/span><\/div>\n            <div class=\"api-step\"><span class=\"api-step-num\">3<\/span><span><strong>Account Settings<\/strong> \u00f6ffnen<\/span><\/div>\n            <div class=\"api-step\"><span class=\"api-step-num\">4<\/span><span>Zu <strong>API Keys<\/strong> navigieren<\/span><\/div>\n            <div class=\"api-step\"><span class=\"api-step-num\">5<\/span><span>Neuen Key erstellen, kopieren und sicher speichern<\/span><\/div>\n          <\/div>\n          <div class=\"api-note\">\n            Keys werden \u00fcber die Claude Console erzeugt und erm\u00f6glichen direkten API-Zugriff.\n            <a href=\"https:\/\/docs.anthropic.com\/en\/api\/overview\" target=\"_blank\" rel=\"noopener\">Claude API Docs \u2192<\/a>\n          <\/div>\n        <\/div>\n      <\/div>\n\n    <\/div>\n\n    <!-- Security warning as accordion -->\n    <div class=\"api-accordion\" id=\"acc-security\" style=\"border-top:1px solid rgba(187,158,28,0.15);margin-bottom:4px;\">\n      <button class=\"api-accordion-trigger\" onclick=\"toggleAcc('acc-security')\">\n        <div class=\"api-acc-left\">\n          <span class=\"api-acc-icon\">\ud83d\udd12<\/span>\n          <span class=\"api-acc-title\">Sicherheitshinweise<\/span>\n          <span class=\"api-acc-badge\">Wichtig<\/span>\n        <\/div>\n        <span class=\"api-acc-arrow\">\u25be<\/span>\n      <\/button>\n      <div class=\"api-accordion-body\">\n        <div class=\"api-warning\" style=\"margin-bottom:10px;\">\n          Teile deinen API Key niemals \u00f6ffentlich \u2014 nicht in Screenshots, WhatsApp, GitHub oder direkt im Website-Code.\n          F\u00fcr produktive Websites empfehlen wir eine Backend-L\u00f6sung via Node.js, PHP, Make oder Zapier, damit der Key nicht ausgelesen werden kann.\n          <br><a href=\"https:\/\/help.openai.com\/en\/articles\/5112595-best-practices-for-api-key-safety\" target=\"_blank\" rel=\"noopener\">Best Practices \u2192<\/a>\n        <\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n\n  <div class=\"api-connected-bar\" id=\"api-connected-bar\">\n    <div class=\"api-connected-badge\" id=\"connected-badge\">Claude API verbunden<\/div>\n    <span style=\"color:var(--text-muted);\">\u00b7<\/span>\n    <span style=\"color:var(--text-muted);font-size:10px;letter-spacing:1px;\">Key wird lokal gespeichert \u00b7 kein Server<\/span>\n  <\/div>\n<\/div>\n\n<div class=\"app\">\n\n<!-- HEADER -->\n<header class=\"hero-video-header\">\n  <div class=\"hero-video-wrap\" aria-hidden=\"true\">\n    <video class=\"hero-video\" autoplay muted loop playsinline preload=\"auto\">\n      <source src=\"https:\/\/videos.pexels.com\/video-files\/7966582\/7966582-hd_1920_1080_25fps.mp4\" type=\"video\/mp4\">\n      Ihr Browser kann das Hero-Video nicht abspielen.\n    <\/video>\n    <div class=\"hero-video-overlay\"><\/div>\n  <\/div>\n  <div class=\"hero-video-content\">\n    <div class=\"hero-kicker\">Kostenloses Ad-Content-Tool<\/div>\n    <div class=\"hero-title\">Aus Expos\u00e9 wird <span>viraler Immobiliencontent<\/span>.<\/div>\n    <div class=\"hero-sub\">PDF hochladen oder Objekt-URL einf\u00fcgen. Die KI erstellt Social-Media-Beitr\u00e4ge, Werbetexte, Hooks und plattformoptimierte Ads in Sekunden.<\/div>\n    <div class=\"hero-flow\">\n      <span>PDF \/ URL<\/span>\n      <i>\u2192<\/i>\n      <span>KI erkennt Objektdaten<\/span>\n      <i>\u2192<\/i>\n      <span>Direkt posten<\/span>\n    <\/div>\n  <\/div>\n  <div class=\"hero-social-preview\" aria-hidden=\"true\">\n    <div class=\"hero-preview-card\">\n      <strong>Instagram Ad<\/strong>\n      <span>Hook, Caption und Hashtags bereit<\/span>\n    <\/div>\n    <div class=\"hero-preview-card\">\n      <strong>LinkedIn Beitrag<\/strong>\n      <span>Professionell f\u00fcr Makler und Bautr\u00e4ger<\/span>\n    <\/div>\n    <div class=\"hero-preview-card\">\n      <strong>WhatsApp Text<\/strong>\n      <span>Objekt-Update direkt teilbar<\/span>\n    <\/div>\n  <\/div>\n  <div class=\"header-right\" style=\"position:absolute;right:28px;\">\n    <div class=\"version-tag\">Ad Generator Pro \u00b7 v2<\/div>\n  <\/div>\n<\/header>\n\n<!-- TITLE -->\n<div class=\"page-title\">\n  <div class=\"page-title-eyebrow\">Lima Invest \u00b7 KI-gest\u00fctztes Marketing<\/div>\n  <h1>\n    <span class=\"line1\">Expos\u00e9 zu<\/span>\n    <span class=\"line2\">viralen Ads<\/span>\n    <span class=\"line3\">in Sekunden.<\/span>\n  <\/h1>\n  <p>PDF hochladen oder URL einf\u00fcgen. Die KI extrahiert alle Objektdaten und generiert plattformoptimierte Werbetexte f\u00fcr alle Kan\u00e4le \u2014 direkt postbar.<\/p>\n\n<\/div>\n\n<!-- PROGRESS -->\n<div class=\"progress-bar\" id=\"progress-bar\">\n  <div class=\"pb-step active\" id=\"pb1\">\n    <div class=\"pb-num\"><span>1<\/span><\/div>\n    <div class=\"pb-label\">Quelle w\u00e4hlen<\/div>\n  <\/div>\n  <div class=\"pb-step\" id=\"pb2\">\n    <div class=\"pb-num\"><span>2<\/span><\/div>\n    <div class=\"pb-label\">Analysieren<\/div>\n  <\/div>\n  <div class=\"pb-step\" id=\"pb3\">\n    <div class=\"pb-num\"><span>3<\/span><\/div>\n    <div class=\"pb-label\">Ads generieren<\/div>\n  <\/div>\n  <div class=\"pb-step\" id=\"pb4\">\n    <div class=\"pb-num\"><span>4<\/span><\/div>\n    <div class=\"pb-label\">Posten<\/div>\n  <\/div>\n<\/div>\n\n<!-- ===== INPUT SECTION ===== -->\n<div id=\"input-section\">\n\n  <div class=\"card\">\n    <div class=\"card-header\">\n      <div class=\"card-title\">\u2726 Quelle ausw\u00e4hlen<\/div>\n    <\/div>\n\n    <!-- Mode Tabs -->\n    <div class=\"input-mode-tabs\">\n      <div class=\"im-tab active\" onclick=\"switchMode('pdf')\" id=\"tab-pdf\">\n        <span class=\"im-tab-icon\">\ud83d\udcc4<\/span> PDF Expos\u00e9\n      <\/div>\n      <div class=\"im-tab\" onclick=\"switchMode('url')\" id=\"tab-url\">\n        <span class=\"im-tab-icon\">\ud83c\udf10<\/span> Website \/ URL\n      <\/div>\n    <\/div>\n\n    <!-- PDF MODE -->\n    <div id=\"pdf-mode\">\n      <div class=\"upload-zone\" id=\"drop-zone\">\n        <div class=\"upload-icon\">\ud83d\udccb<\/div>\n        <h3>Expos\u00e9 hier ablegen<\/h3>\n        <p>PDF-Datei \u00b7 max. 20 MB \u00b7 Drag & Drop oder klicken<\/p>\n        <div class=\"upload-file-info\" id=\"file-info\"><\/div>\n        <button style=\"margin-top:20px;padding:11px 24px;background:var(--gold);color:#1a1a1a;font-family:'Poppins',sans-serif;font-size:10px;font-weight:600;letter-spacing:2px;text-transform:uppercase;cursor:pointer;border:none;\" onclick=\"document.getElementById('file-input').click()\">\n          \u2191 &nbsp; PDF ausw\u00e4hlen\n        <\/button>\n        <input type=\"file\" id=\"file-input\" accept=\".pdf\">\n      <\/div>\n    <\/div>\n\n    <!-- URL MODE -->\n    <div id=\"url-mode\" class=\"url-input-wrap\">\n      <input\n        type=\"url\"\n        id=\"url-field\"\n        class=\"url-field\"\n        placeholder=\"https:\/\/www.immobilienscout24.de\/expose\/...\"\n        spellcheck=\"false\"\n      \/>\n      <div class=\"url-hint\">\n        Unterst\u00fctzt: <span>ImmobilienScout24, Immowelt, Immonet, Engel & V\u00f6lkers, JLL<\/span> und alle anderen Makler-Websites.<br>\n        Die KI liest den Seiteninhalt und extrahiert alle Objektdaten.\n      <\/div>\n    <\/div>\n  <\/div>\n\n  <!-- Settings -->\n  <div class=\"card\">\n    <div class=\"card-header\">\n      <div class=\"card-title\">\u2726 Einstellungen<\/div>\n    <\/div>\n\n    <div class=\"settings-grid\">\n      <div class=\"sg-group\">\n        <label class=\"sg-label\">Plattformen<\/label>\n        <div class=\"toggles\" id=\"platform-toggles\">\n          <label class=\"tgl\"><input type=\"checkbox\" value=\"instagram\" checked><span class=\"tgl-pill\">\ud83d\udcf8 Instagram<\/span><\/label>\n          <label class=\"tgl\"><input type=\"checkbox\" value=\"tiktok\" checked><span class=\"tgl-pill\">\ud83c\udfb5 TikTok<\/span><\/label>\n          <label class=\"tgl\"><input type=\"checkbox\" value=\"facebook\" checked><span class=\"tgl-pill\">\ud83d\udcd8 Facebook<\/span><\/label>\n          <label class=\"tgl\"><input type=\"checkbox\" value=\"linkedin\" checked><span class=\"tgl-pill\">\ud83d\udcbc LinkedIn<\/span><\/label>\n          <label class=\"tgl\"><input type=\"checkbox\" value=\"whatsapp\"><span class=\"tgl-pill\">\ud83d\udcac WhatsApp<\/span><\/label>\n          <label class=\"tgl\"><input type=\"checkbox\" value=\"google\"><span class=\"tgl-pill\">\ud83d\udd0d Google Business<\/span><\/label>\n          <label class=\"tgl\"><input type=\"checkbox\" value=\"xtwitter\"><span class=\"tgl-pill\">\ud835\udd4f X\/Twitter<\/span><\/label>\n          <label class=\"tgl\"><input type=\"checkbox\" value=\"telegram\"><span class=\"tgl-pill\">\u2708\ufe0f Telegram<\/span><\/label>\n        <\/div>\n      <\/div>\n      <div class=\"sg-group\">\n        <label class=\"sg-label\">Ad-Stil<\/label>\n        <select class=\"sg-select\" id=\"ad-style\">\n          <option value=\"viral\">\ud83d\udd25 Viral & emotional (Hooks, FOMO)<\/option>\n          <option value=\"luxury\">\u2728 Luxury & exklusiv (Premium-Ton)<\/option>\n          <option value=\"investment\">\ud83d\udcca Investment-fokussiert (Rendite, Zahlen)<\/option>\n          <option value=\"storytelling\">\ud83d\udcd6 Storytelling (narrative Ads)<\/option>\n        <\/select>\n        <div style=\"height:12px;\"><\/div>\n        <label class=\"sg-label\">Zielgruppe<\/label>\n        <select class=\"sg-select\" id=\"target-audience\">\n          <option value=\"investors\">Kapitalanleger \/ Investoren<\/option>\n          <option value=\"buyers\">K\u00e4ufer \/ Eigennutzer<\/option>\n          <option value=\"brokers\">Makler \/ Fachpublikum<\/option>\n          <option value=\"all\">Gemischte Zielgruppe<\/option>\n        <\/select>\n      <\/div>\n    <\/div>\n\n    <button class=\"btn-generate\" id=\"generate-btn\" onclick=\"startGeneration()\">\n      \u26a1 &nbsp; Ads jetzt generieren\n    <\/button>\n    <div class=\"key-hint\" id=\"key-hint\">\u26a0 Bitte zuerst KI-API-Key oben verbinden<\/div>\n  <\/div>\n\n  <!-- CONNECT SECTION (always visible) -->\n  <div class=\"connect-section\">\n    <div class=\"section-divider\"><span>\u2726 Social Media Verbinden<\/span><\/div>\n    <div class=\"connect-sub\" style=\"font-size:11px;color:var(--text-muted);margin-bottom:10px;line-height:1.7;\">\n      Verbinde deine Konten einmalig \u2014 danach kannst du Ads mit einem Klick direkt posten.\n    <\/div>\n    <div class=\"accounts-grid\" id=\"accounts-grid\"><\/div>\n  <\/div>\n\n<\/div><!-- end input-section -->\n\n<!-- ===== PROCESSING ===== -->\n<div id=\"processing-section\">\n  <div class=\"spin-ring\"><\/div>\n  <div class=\"proc-label\">Verarbeitung l\u00e4uft<\/div>\n  <div class=\"proc-step\" id=\"proc-status\">Objekt wird analysiert...<\/div>\n<\/div>\n\n<!-- ===== RESULTS ===== -->\n<div id=\"results-section\">\n\n  <!-- Extracted data -->\n<!-- data card removed -->\n\n  <!-- Platform tabs -->\n  <div class=\"plat-tabs\" id=\"plat-tabs\"><\/div>\n  <div class=\"ads-box\" id=\"ads-box\"><\/div>\n\n  <!-- Action bar -->\n  <!-- IMAGE GENERATION SECTION -->\n  <div class=\"imggen-section\" id=\"imggen-section\">\n    <div class=\"imggen-header\">\n      <div class=\"imggen-title\">\ud83c\udfa8 Ad-Bilder generieren <span style=\"font-size:8px;padding:2px 7px;border:1px solid var(--border);color:var(--text-muted);letter-spacing:1px;\">KI-Bildgenerator<\/span><\/div>\n      <button class=\"imggen-btn-sec\" onclick=\"toggleImgSettings()\" id=\"imggen-settings-toggle\">\u2699 Einstellungen<\/button>\n    <\/div>\n\n    <!-- Settings (collapsible) -->\n    <div id=\"imggen-settings\" style=\"display:none;margin-bottom:16px;\">\n      <div class=\"imggen-controls\">\n        <div class=\"imggen-field\">\n          <label>Text auf dem Bild<\/label>\n          <input class=\"imggen-input\" id=\"img-overlay-text\" placeholder=\"z.B. 7,5% Rendite \u00b7 Hamburg\" \/>\n        <\/div>\n        <div class=\"imggen-field\">\n          <label>Bildstil<\/label>\n          <select class=\"imggen-select\" id=\"img-style-select\" style=\"width:100%;\">\n            <option value=\"luxury real estate photography, golden hour\">Luxury \u00b7 Golden Hour<\/option>\n            <option value=\"cinematic aerial real estate shot, modern architecture\">Cinematic \u00b7 Aerial<\/option>\n            <option value=\"minimalist editorial real estate, white and gold tones\">Minimalist \u00b7 Editorial<\/option>\n            <option value=\"dramatic moody real estate, dark premium aesthetic\">Dramatic \u00b7 Dark Premium<\/option>\n            <option value=\"bright modern interior real estate photography\">Interior \u00b7 Modern Bright<\/option>\n          <\/select>\n        <\/div>\n      <\/div>\n      <div class=\"imggen-row\">\n        <div class=\"imggen-field\">\n          <label>Schriftart<\/label>\n          <select class=\"imggen-select\" id=\"img-font-select\">\n            <optgroup label=\"Serif \/ Elegant\">\n            <option value=\"Cormorant Garamond, serif\">Cormorant Garamond<\/option>\n            <option value=\"Georgia, serif\">Georgia (Classic)<\/option>\n            <option value=\"'Times New Roman', serif\">Times New Roman<\/option>\n            <option value=\"'Playfair Display', Georgia, serif\">Playfair Display<\/option>\n            <option value=\"Garamond, serif\">Garamond<\/option>\n            <option value=\"'Didot', Georgia, serif\">Didot (Luxus)<\/option>\n            <option value=\"'Baskerville', Georgia, serif\">Baskerville<\/option>\n            <\/optgroup>\n            <optgroup label=\"Sans-Serif \/ Modern\">\n            <option value=\"Poppins, sans-serif\">Poppins (Modern)<\/option>\n            <option value=\"Helvetica, Arial, sans-serif\">Helvetica (Clean)<\/option>\n            <option value=\"'Montserrat', sans-serif\">Montserrat<\/option>\n            <option value=\"'Futura', sans-serif\">Futura<\/option>\n            <option value=\"'Avenir', sans-serif\">Avenir<\/option>\n            <option value=\"Verdana, sans-serif\">Verdana<\/option>\n            <option value=\"'Trebuchet MS', sans-serif\">Trebuchet<\/option>\n            <\/optgroup>\n            <optgroup label=\"Display \/ Bold\">\n            <option value=\"'Bebas Neue', Impact, sans-serif\">Bebas Neue<\/option>\n            <option value=\"Impact, sans-serif\">Impact<\/option>\n            <option value=\"'Oswald', sans-serif\">Oswald<\/option>\n            <\/optgroup>\n          <\/select>\n        <\/div>\n\t        <div class=\"imggen-field\">\n\t          <label>Textgr\u00f6\u00dfe<\/label>\n\t          <select class=\"imggen-select\" id=\"img-fontsize-select\">\n\t            <option value=\"small\">Klein<\/option>\n\t            <option value=\"medium\" selected>Mittel<\/option>\n\t            <option value=\"large\">Gro\u00df<\/option>\n\t          <\/select>\n\t        <\/div>\n\t        <div class=\"imggen-field\">\n\t          <label>Textposition<\/label>\n\t          <select class=\"imggen-select\" id=\"img-text-position-select\">\n\t            <option value=\"top\">Oben<\/option>\n\t            <option value=\"middle\" selected>Mittig<\/option>\n\t            <option value=\"bottom\">Unten<\/option>\n\t          <\/select>\n\t        <\/div>\n\t        <div class=\"imggen-field\">\n\t          <label>Textfarbe<\/label>\n\t          <div class=\"imggen-color-wrap\">\n\t            <input type=\"color\" class=\"imggen-color\" id=\"img-text-color\" value=\"#bb9e1c\" \/>\n\t            <span style=\"font-size:10px;color:var(--text-muted);\" id=\"color-label\">#bb9e1c<\/span>\n\t          <\/div>\n\t        <\/div>\n\t      <\/div>\n\t      <div class=\"imglogo-panel\">\n\t        <input type=\"file\" id=\"img-logo-input\" accept=\"image\/png,image\/jpeg,image\/webp\" style=\"display:none;\">\n\t        <div class=\"imglogo-head\">\n\t          <div class=\"imglogo-title\">Logo einf\u00fcgen<\/div>\n\t          <button type=\"button\" class=\"imggen-btn-sec\" onclick=\"document.getElementById('img-logo-input').click()\">Logo hochladen<\/button>\n\t        <\/div>\n\t        <div class=\"imglogo-preview\" id=\"img-logo-preview\"><\/div>\n\t        <div class=\"imglogo-controls\">\n\t          <div class=\"imggen-field\">\n\t            <label>Deckkraft \u00b7 Empfehlung 80%<\/label>\n\t            <div class=\"imglogo-range\"><input type=\"range\" min=\"10\" max=\"100\" step=\"5\" value=\"80\" id=\"img-logo-opacity\"><span class=\"imglogo-value\" id=\"img-logo-opacity-label\">80%<\/span><\/div>\n\t          <\/div>\n\t          <div class=\"imggen-field\">\n\t            <label>Logo-Gr\u00f6\u00dfe \u00b7 Empfehlung 14%<\/label>\n\t            <div class=\"imglogo-range\"><input type=\"range\" min=\"6\" max=\"36\" step=\"1\" value=\"14\" id=\"img-logo-size\"><span class=\"imglogo-value\" id=\"img-logo-size-label\">14%<\/span><\/div>\n\t          <\/div>\n\t          <div class=\"imggen-field\">\n\t            <label>Logo-Position<\/label>\n\t            <select class=\"imggen-select\" id=\"img-logo-position\">\n\t              <option value=\"top-left\">Oben links<\/option>\n\t              <option value=\"top-center\">Oben mittig<\/option>\n\t              <option value=\"top-right\" selected>Oben rechts<\/option>\n\t              <option value=\"center\">Mittig<\/option>\n\t              <option value=\"bottom-left\">Unten links<\/option>\n\t              <option value=\"bottom-center\">Unten mittig<\/option>\n\t              <option value=\"bottom-right\">Unten rechts<\/option>\n\t            <\/select>\n\t          <\/div>\n\t        <\/div>\n\t      <\/div>\n\t\t    <\/div>\n\n\t    <div class=\"imgedit-panel\" id=\"imgedit-panel\">\n\t      <input type=\"file\" id=\"imgedit-file-input\" accept=\"image\/png,image\/jpeg,image\/webp\" style=\"display:none;\">\n\t      <div class=\"imgedit-drop\" id=\"imgedit-drop-zone\" onclick=\"document.getElementById('imgedit-file-input').click()\">\n\t        <div class=\"imgedit-drop-icon\">\u21ea<\/div>\n\t        <div>\n\t          <div class=\"imgedit-drop-title\">Immobilienfoto \u00fcberarbeiten<\/div>\n\t          <div class=\"imgedit-drop-sub\">JPG, PNG oder WebP hier ablegen oder ausw\u00e4hlen \u00b7 max. 50 MB<\/div>\n\t        <\/div>\n\t        <button type=\"button\" class=\"imggen-btn-sec\">Foto ausw\u00e4hlen<\/button>\n\t      <\/div>\n\t      <div class=\"imgedit-preview\" id=\"imgedit-preview\"><\/div>\n\t      <div class=\"imgedit-source-gallery\" id=\"imgedit-source-gallery\" style=\"display:none;\"><\/div>\n\t      <div class=\"imgedit-sliders\" id=\"imgedit-sliders\">\n\t        <div class=\"imgedit-slider-head\">\n\t          <span>Ausspielung \/ Bearbeitung<\/span>\n\t          <button type=\"button\" class=\"imggen-btn-sec imgedit-reset\" onclick=\"resetImageEditSliders()\">Schalter zur\u00fccksetzen<\/button>\n\t        <\/div>\n\t        <div class=\"imgedit-slider-grid\">\n\t          <label class=\"imgedit-toggle\"><span>Au\u00dfenbereich aufr\u00e4umen<\/span><input type=\"checkbox\" data-edit-key=\"cleanup\"><em class=\"imgedit-value\">Nein<\/em><\/label>\n\t          <label class=\"imgedit-toggle\"><span>Au\u00dfenfl\u00e4chen reinigen<\/span><input type=\"checkbox\" data-edit-key=\"surfaces\"><em class=\"imgedit-value\">Nein<\/em><\/label>\n\t          <label class=\"imgedit-toggle\"><span>Belichtung und Himmel optimieren<\/span><input type=\"checkbox\" data-edit-key=\"sky\"><em class=\"imgedit-value\">Nein<\/em><\/label>\n\t          <label class=\"imgedit-toggle\"><span>Fahrzeuge entfernen<\/span><input type=\"checkbox\" data-edit-key=\"vehicles\"><em class=\"imgedit-value\">Nein<\/em><\/label>\n\t          <label class=\"imgedit-toggle\"><span>Hausnummer entfernen<\/span><input type=\"checkbox\" data-edit-key=\"houseNumber\"><em class=\"imgedit-value\">Nein<\/em><\/label>\n\t          <label class=\"imgedit-toggle\"><span>Kennzeichen unkenntlich machen<\/span><input type=\"checkbox\" data-edit-key=\"plates\"><em class=\"imgedit-value\">Nein<\/em><\/label>\n\t          <label class=\"imgedit-toggle\"><span>Personen entfernen<\/span><input type=\"checkbox\" data-edit-key=\"people\"><em class=\"imgedit-value\">Nein<\/em><\/label>\n\t          <label class=\"imgedit-toggle\"><span>Perspektive optimieren<\/span><input type=\"checkbox\" data-edit-key=\"perspective\"><em class=\"imgedit-value\">Nein<\/em><\/label>\n\t          <label class=\"imgedit-toggle\"><span>Saisonale Optimierung (Sommer-Vegetation)<\/span><input type=\"checkbox\" data-edit-key=\"summer\"><em class=\"imgedit-value\">Nein<\/em><\/label>\n\t          <label class=\"imgedit-toggle\"><span>Umgebung unkenntlich machen (verpixeln)<\/span><input type=\"checkbox\" data-edit-key=\"pixelateSurroundings\"><em class=\"imgedit-value\">Nein<\/em><\/label>\n\t        <\/div>\n\t      <\/div>\n\t    <\/div>\n\n\t    <div style=\"display:flex;gap:10px;flex-wrap:wrap;margin-bottom:4px;\">\n\t      <button class=\"imggen-btn\" onclick=\"generateImages()\" id=\"imggen-generate-btn\">\ud83c\udfa8 Bilder generieren<\/button>\n\t      <button class=\"imggen-btn-sec\" onclick=\"regenerateImages()\" id=\"imggen-regen-btn\" style=\"display:none;\">\u21ba Neue Variation<\/button>\n    <\/div>\n\n    <!-- Image grid -->\n    <div class=\"imggen-images\" id=\"imggen-grid\">\n      <div class=\"imggen-img-wrap\">\n        <div class=\"imggen-placeholder\"><div class=\"imggen-placeholder-icon\">\ud83d\uddbc<\/div><div class=\"imggen-placeholder-text\">Bild 1<\/div><\/div>\n      <\/div>\n      <div class=\"imggen-img-wrap\">\n        <div class=\"imggen-placeholder\"><div class=\"imggen-placeholder-icon\">\ud83d\uddbc<\/div><div class=\"imggen-placeholder-text\">Bild 2<\/div><\/div>\n      <\/div>\n    <\/div>\n    <div class=\"imggen-error\" id=\"imggen-error\" style=\"display:none;\"><\/div>\n    <div class=\"posting-panel\" id=\"img-posting-panel\" style=\"display:none;margin-top:12px;\">\n      <div class=\"pp-title\">\ud83d\udce4 Posting-Optionen (unter den Bildern)<\/div>\n      <div id=\"img-posting-meta\"><\/div>\n      <div class=\"post-actions\" id=\"img-posting-actions\"><\/div>\n    <\/div>\n  <\/div>\n\n  <div class=\"action-bar\">\n    <button class=\"btn-primary\" onclick=\"downloadAdsPdf()\">\u2193 Alle Ads als PDF<\/button>\n    <button class=\"btn-sec\" onclick=\"downloadGeneratedImages()\">\u2193 Beide Bilder<\/button>\n    <button class=\"btn-sec\" onclick=\"downloadAds()\">\u2913 TXT Export<\/button>\n    <button class=\"btn-sec\" onclick=\"resetApp()\">\u21ba Neues Expos\u00e9<\/button>\n  <\/div>\n\n<\/div>\n\n<\/div><!-- end .app -->\n\n<!-- OAUTH MODAL -->\n<div class=\"modal-overlay\" id=\"oauth-modal\">\n  <div class=\"modal\" id=\"modal-content\">\n    <!-- filled by JS -->\n  <\/div>\n<\/div>\n\n<!-- TOAST -->\n<div class=\"toast\" id=\"toast\"><\/div>\n\n<\/div><!-- \/#lima-ad-gen -->\n\n<script>\n\/\/ ============================================================\n\/\/ STATE & CONFIG\n\/\/ ============================================================\nconst POSTING_SHARE_URL='https:\/\/limainvestimmobilien.de\/ad-content-generator\/';\nconst SOCIAL_API_BASE_KEY='li_social_api_base';\nconst DEFAULT_SOCIAL_API_BASE='http:\/\/localhost:8787';\nconst PLATFORMS={\ninstagram:{icon:'\ud83d\udcf8',name:'Instagram',format:'Feed Post \/ Reels Caption',timing:'Di\u2013Fr \u00b7 11\u201313 Uhr oder 19\u201321 Uhr',deepLink:()=>`https:\/\/www.instagram.com\/`},\ntiktok:{icon:'\ud83c\udfb5',name:'TikTok',format:'Video Script \/ Caption',timing:'Mo\u2013Do \u00b7 7\u20139 Uhr oder 19\u201323 Uhr',deepLink:()=>`https:\/\/www.tiktok.com\/upload`},\nfacebook:{icon:'\ud83d\udcd8',name:'Facebook',format:'Post + optional Karussell',timing:'Mi\u2013Fr \u00b7 13\u201316 Uhr',deepLink:(t)=>`https:\/\/www.facebook.com\/sharer\/sharer.php?u=${encodeURIComponent(POSTING_SHARE_URL)}&quote=${encodeURIComponent(unicodeSafeLimit(t,600))}`},\nlinkedin:{icon:'\ud83d\udcbc',name:'LinkedIn',format:'Status Update \/ Artikel',timing:'Di\u2013Do \u00b7 8\u201310 Uhr oder 17\u201318 Uhr',deepLink:()=>`https:\/\/www.linkedin.com\/feed\/?shareActive=true`},\nwhatsapp:{icon:'\ud83d\udcac',name:'WhatsApp',format:'Status \/ Broadcast-Nachricht',timing:'Mo\u2013Sa \u00b7 9\u201312 Uhr oder 18\u201320 Uhr',deepLink:(t)=>`https:\/\/api.whatsapp.com\/send?text=${encodeWhatsAppText(t,1400)}`},\ngoogle:{icon:'\ud83d\udd0d',name:'Google Business',format:'Beitrag \/ Angebot',timing:'Di\u2013Do \u00b7 10\u201314 Uhr',deepLink:()=>`https:\/\/business.google.com\/posts`},\nxtwitter:{icon:'\ud835\udd4f',name:'X \/ Twitter',format:'Tweet \/ Thread',timing:'Mo\u2013Fr \u00b7 9 Uhr oder 17\u201318 Uhr',deepLink:(t)=>`https:\/\/twitter.com\/intent\/tweet?text=${encodeURIComponent(unicodeSafeLimit(t,270))}`},\ntelegram:{icon:'\u2708\ufe0f',name:'Telegram',format:'Kanal-Nachricht',timing:'Mo\u2013Fr \u00b7 8\u201310 Uhr oder 20\u201322 Uhr',deepLink:(t)=>`https:\/\/t.me\/share\/url?url=${encodeURIComponent(POSTING_SHARE_URL)}&text=${encodeURIComponent(unicodeSafeLimit(t,500))}`}\n};\nconst PLATFORM_CAPABILITIES={\ninstagram:{oauth:true,directPost:true},\ntiktok:{oauth:false,directPost:false},\nfacebook:{oauth:true,directPost:true},\nlinkedin:{oauth:true,directPost:true},\nwhatsapp:{oauth:false,directPost:false},\ngoogle:{oauth:true,directPost:true},\nxtwitter:{oauth:false,directPost:false},\ntelegram:{oauth:false,directPost:false}\n};\n\nlet connectedAccounts=JSON.parse(localStorage.getItem('li_connected_accounts')||'{}');\nlet extractedData=null;\nlet generatedAds=null;\nlet currentMode='pdf';\nlet selectedFile=null;\nlet currentProvider='anthropic';\nlet apiKey='';\nlet currentAnrede=null;\nlet generatedImageUrls=[];\nlet imgSettingsOpen=false;\nlet imageEditFile=null;\nlet imageEditDataUrl='';\nlet listingImageAssets=[];\nlet logoFile=null;\nlet logoDataUrl='';\nconst IMGGEN_SETTINGS_KEY='li_imggen_settings_v2';\n\nconst IMAGE_EDIT_CONTROLS={\ncleanup:{label:'Au\u00dfenbereich aufr\u00e4umen',prompt:'remove visual clutter from the exterior area such as bins, debris, loose cables, toys, tools, garden clutter, temporary objects and distracting small items while preserving permanent property features'},\nsurfaces:{label:'Au\u00dfenfl\u00e4chen reinigen',prompt:'make exterior surfaces look freshly cleaned, including facade, paving, terrace, windows, paths and entrance areas; keep materials realistic and do not change the building architecture'},\nsky:{label:'Belichtung und Himmel optimieren',prompt:'improve exposure, dynamic range, contrast and sky in a natural premium real estate photography style; keep weather believable and avoid artificial HDR'},\nvehicles:{label:'Fahrzeuge entfernen',prompt:'remove visible cars, vans, bikes or parked vehicles where possible and reconstruct the background naturally; if removal is not plausible, reduce their visual presence'},\nhouseNumber:{label:'Hausnummer entfernen',prompt:'remove visible house numbers, door numbers and address identifiers cleanly while preserving the facade and entrance'},\nplates:{label:'Kennzeichen unkenntlich machen',prompt:'blur or remove all visible license plates and vehicle registration identifiers'},\npeople:{label:'Personen entfernen',prompt:'remove visible people, faces and body silhouettes and reconstruct the surrounding background naturally'},\nperspective:{label:'Perspektive optimieren',prompt:'correct perspective, vertical lines, lens distortion and framing for a professional architectural real estate look'},\nsummer:{label:'Saisonale Optimierung (Sommer-Vegetation)',prompt:'add tasteful summer vegetation, greener lawn, fuller plants and warm seasonal freshness without hiding the property or changing its structure'},\npixelateSurroundings:{label:'Umgebung unkenntlich machen (verpixeln)',prompt:'pixelate or softly blur neighbouring properties, background windows, sensitive surroundings and non-essential private areas while keeping the main property sharp and marketable'}\n};\n\nconst PROVIDER_INFO={\nanthropic:{placeholder:'sk-ant-api03-... API-Key eingeben',info:'Claude Key: <a href=\"https:\/\/console.anthropic.com\/settings\/keys\" target=\"_blank\" rel=\"noopener\">console.anthropic.com<\/a>',badge:'\ud83e\udd16 Claude API verbunden',storageKey:'li_anthropic_key'},\nopenai:{placeholder:'sk-proj-... API-Key eingeben',info:'ChatGPT Key: <a href=\"https:\/\/platform.openai.com\/api-keys\" target=\"_blank\">platform.openai.com<\/a>',badge:'\u2726 OpenAI API verbunden',storageKey:'li_openai_key'}\n};\n\nconst CONNECT_INFO={\ninstagram:{title:'Instagram verbinden',note:'Echte OAuth-Verbindung via Backend. F\u00fcr Direkt-Posting ist ein Instagram Business\/Creator Konto n\u00f6tig.'},\ntiktok:{title:'TikTok verbinden',note:'Aktuell Deep-Link Workflow. F\u00fcr echte API-Verbindung sp\u00e4ter TikTok Content Posting API anbinden.'},\nfacebook:{title:'Facebook verbinden',note:'Echte OAuth-Verbindung via Backend. Gepostet wird auf die verbundene Facebook-Seite.'},\nlinkedin:{title:'LinkedIn verbinden',note:'Echte OAuth-Verbindung via Backend. Danach kann direkt aus dem Tool ver\u00f6ffentlicht werden.'},\nwhatsapp:{title:'WhatsApp Business',note:'Direktes Status-Posting ist nicht als Standard-OAuth-Flow verf\u00fcgbar. Nutze aktuell Deep-Link\/Copy.'},\ngoogle:{title:'Google Business verbinden',note:'Echte OAuth-Verbindung via Backend. Danach Direkt-Posts auf Google Business Profile.'},\nxtwitter:{title:'X \/ Twitter verbinden',note:'Aktuell Deep-Link Workflow. F\u00fcr echte API-Verbindung kann OAuth2\/PKCE im Backend erg\u00e4nzt werden.'},\ntelegram:{title:'Telegram verbinden',note:'Aktuell Deep-Link Workflow. F\u00fcr echte Bot-Posts kann ein Telegram-Bot im Backend erg\u00e4nzt werden.'}\n};\n\n\/\/ ============================================================\n\/\/ HELPERS\n\/\/ ============================================================\nfunction show(id){const e=document.getElementById(id);if(e)e.style.display='block';}\nfunction hide(id){const e=document.getElementById(id);if(e)e.style.display='none';}\nfunction escHtml(s){if(!s)return '';return String(s).replace(\/&\/g,'&amp;').replace(\/<\/g,'&lt;').replace(\/>\/g,'&gt;');}\nfunction escAttr(s){return escHtml(s).replace(\/\"\/g,'&quot;').replace(\/'\/g,'&#39;');}\nfunction getSelectedPlatforms(){return Array.from(document.querySelectorAll('#platform-toggles input:checked')).map(i=>i.value);}\nfunction fileToBase64(file){return new Promise((res,rej)=>{const r=new FileReader();r.onload=()=>res(r.result.split(',')[1]);r.onerror=rej;r.readAsDataURL(file);});}\nfunction fileToDataUrl(file){return new Promise((res,rej)=>{const r=new FileReader();r.onload=()=>res(r.result);r.onerror=rej;r.readAsDataURL(file);});}\nfunction setStep(n){for(let i=1;i<=4;i++){const el=document.getElementById('pb'+i);if(!el)continue;el.classList.remove('active','done');if(i<n)el.classList.add('done');else if(i===n)el.classList.add('active');}}\nfunction setStatus(msg){const e=document.getElementById('proc-status');if(e)e.textContent=msg;}\nfunction showToast(msg,type){const t=document.getElementById('toast');if(!t)return;t.textContent=msg;t.className='toast show'+(type?' '+type:'');clearTimeout(t._timer);t._timer=setTimeout(()=>t.classList.remove('show'),3200);}\nfunction showError(msg){document.querySelectorAll('.err-box').forEach(e=>e.remove());const box=document.createElement('div');box.className='err-box';box.innerHTML='\u26a0 '+escHtml(msg);const sec=document.getElementById('input-section');if(sec)sec.prepend(box);showToast(msg,'err');}\nfunction sleep(ms){return new Promise(resolve=>setTimeout(resolve,ms));}\nfunction persistConnectedAccounts(){localStorage.setItem('li_connected_accounts',JSON.stringify(connectedAccounts));}\nfunction normalizeApiBase(base){\nconst raw=String(base||'').trim();\nif(!raw)return DEFAULT_SOCIAL_API_BASE;\nreturn raw.replace(\/\\\/+$\/,'');\n}\nfunction getSocialApiBase(){\nconst saved=localStorage.getItem(SOCIAL_API_BASE_KEY)||DEFAULT_SOCIAL_API_BASE;\nreturn normalizeApiBase(saved);\n}\nfunction setSocialApiBase(base){\nconst clean=normalizeApiBase(base);\nlocalStorage.setItem(SOCIAL_API_BASE_KEY,clean);\nreturn clean;\n}\nfunction socialApiUrl(path){\nconst base=getSocialApiBase();\nconst suffix=String(path||'').startsWith('\/')?path:'\/'+path;\nreturn base+suffix;\n}\nasync function socialRequest(path,opts){\nconst options=opts||{};\nconst method=options.method||'GET';\nconst headers=Object.assign({'Accept':'application\/json'},options.headers||{});\nconst init={method:method,headers:headers};\nif(options.body!==undefined){headers['Content-Type']='application\/json';init.body=JSON.stringify(options.body);}\nconst ctrl=new AbortController();\nconst timeout=typeof options.timeoutMs==='number'?options.timeoutMs:20000;\nconst t=setTimeout(()=>ctrl.abort(),timeout);\nlet res;\ntry{\nres=await fetch(socialApiUrl(path),Object.assign(init,{signal:ctrl.signal}));\n}catch(e){\nif(e&&e.name==='AbortError')throw new Error('Social API Timeout. Bitte Backend pr\u00fcfen.');\nthrow new Error('Social API nicht erreichbar. L\u00e4uft dein Backend unter '+getSocialApiBase()+'?');\n}finally{\nclearTimeout(t);\n}\nlet payload=null;\ntry{payload=await res.json();}catch(e){payload=null;}\nif(!res.ok){\nconst msg=(payload&&payload.error)||(payload&&payload.message)||('Fehler '+res.status);\nthrow new Error(msg);\n}\nreturn payload||{};\n}\nfunction platformSupportsOAuth(platform){\nreturn !!(PLATFORM_CAPABILITIES[platform]&&PLATFORM_CAPABILITIES[platform].oauth);\n}\nfunction platformSupportsDirectPost(platform){\nreturn !!(PLATFORM_CAPABILITIES[platform]&&PLATFORM_CAPABILITIES[platform].directPost);\n}\nfunction mapServerConnection(conn){\nif(!conn||!conn.platform)return null;\nreturn{\nplatform:conn.platform,\nsource:'oauth',\nhandle:conn.handle||conn.username||conn.displayName||'Verbunden',\ndisplayName:conn.displayName||conn.handle||conn.username||'Verbunden',\nconnectedAt:conn.connectedAt||new Date().toISOString(),\nexpiresAt:conn.expiresAt||null,\naccountId:conn.accountId||null,\nmeta:conn\n};\n}\nfunction isOAuthConnected(platform){\nconst c=connectedAccounts[platform];\nreturn !!(c&&c.source==='oauth');\n}\nasync function syncConnectionsFromServer(silent){\ntry{\nconst data=await socialRequest('\/v1\/social\/connections');\nconst list=Array.isArray(data.connections)?data.connections:[];\nconst next={};\nlist.forEach(conn=>{const mapped=mapServerConnection(conn);if(mapped)next[mapped.platform]=mapped;});\nObject.keys(connectedAccounts).forEach(p=>{if(connectedAccounts[p]&&connectedAccounts[p].source!=='oauth')next[p]=connectedAccounts[p];});\nconnectedAccounts=next;\npersistConnectedAccounts();\nif(generatedAds)renderAds(generatedAds,getSelectedPlatforms());\nrenderAccountsGrid();\nreturn true;\n}catch(err){\nif(!silent)showToast('Social Backend nicht synchronisiert: '+err.message,'err');\nreturn false;\n}\n}\nasync function waitForConnectResult(platform,state){\nconst started=Date.now();\nconst timeoutMs=120000;\nwhile(Date.now()-started<timeoutMs){\nconst q='\/v1\/social\/connect\/status?platform='+encodeURIComponent(platform)+'&state='+encodeURIComponent(state);\nconst result=await socialRequest(q,{timeoutMs:12000});\nif(result.status==='connected')return result;\nif(result.status==='error')throw new Error(result.message||'OAuth-Verbindung fehlgeschlagen.');\nawait sleep(1800);\n}\nthrow new Error('OAuth Zeit\u00fcberschreitung. Bitte erneut versuchen.');\n}\n\nfunction safeJsonParse(txt){\ntry{return JSON.parse(txt);}catch(e){}\nconst m=txt.match(\/\\{[\\s\\S]*\\}\/);\nif(m){try{return JSON.parse(m[0]);}catch(e){}}\nlet s=m?m[0]:txt;\nlet depth=0,lastValid=-1,inStr=false,esc=false;\nfor(let i=0;i<s.length;i++){const c=s[i];if(esc){esc=false;continue;}if(c==='\\\\'){esc=true;continue;}if(c==='\"')inStr=!inStr;if(!inStr){if(c==='{')depth++;else if(c==='}'){depth--;if(depth===0)lastValid=i;}}}\nif(lastValid>0){try{return JSON.parse(s.substring(0,lastValid+1));}catch(e){}}\nif(inStr)s+='\"';while(depth-->0)s+='}';\ntry{return JSON.parse(s);}catch(e){throw new Error('Die KI-Antwort war unvollst\u00e4ndig. Bitte mit weniger Plattformen erneut versuchen.');}\n}\n\nfunction cleanAdText(text){\nreturn String(text||'').replace(\/\\*\/g,'').replace(\/[ \\t]+\\n\/g,'\\n').replace(\/\\n{3,}\/g,'\\n\\n').trim();\n}\n\nfunction makeHashtag(value){\nconst raw=String(value||'').trim();\nif(!raw)return '';\nconst cleaned=raw.replace(\/^#+\/,'').normalize('NFKD').replace(\/[\\u0300-\\u036f]\/g,'').replace(\/&\/g,'und').replace(\/[^A-Za-z0-9\u00c4\u00d6\u00dc\u00e4\u00f6\u00fc\u00df]+\/g,'');\nreturn cleaned?'#'+cleaned:'';\n}\n\nfunction extractHashtags(text){\nreturn Array.from(String(text||'').matchAll(\/#[A-Za-z0-9\u00c4\u00d6\u00dc\u00e4\u00f6\u00fc\u00df_]+\/g)).map(m=>m[0]);\n}\n\nfunction uniqueHashtags(tags){\nconst seen=new Set();\nreturn tags.map(makeHashtag).filter(Boolean).filter(tag=>{const key=tag.toLowerCase();if(seen.has(key))return false;seen.add(key);return true;});\n}\n\nfunction normalizeHashtags(raw,data){\nconst obj=data||extractedData||{};\nconst fromRaw=extractHashtags(raw);\nconst contextual=[\nobj.standort,\nobj.bundesland,\nobj.art,\n'Immobilieninvestment',\n'Kapitalanlage',\n'Renditeobjekt',\n'Investmentimmobilie',\n'LimaInvest',\n'Immobilien'\n];\nreturn uniqueHashtags(fromRaw.concat(contextual)).slice(0,9);\n}\n\nfunction appendHashtagsToText(text,hashtags,data){\nconst clean=cleanAdText(text);\nif(extractHashtags(clean).length>=5)return clean;\nconst tags=normalizeHashtags(hashtags,data);\nif(!tags.length)return clean;\nreturn (clean+'\\n\\n'+tags.slice(0,Math.max(5,Math.min(tags.length,9))).join(' ')).trim();\n}\n\nfunction normalizeGeneratedAds(ads){\nif(!ads||typeof ads!=='object')return ads;\nObject.keys(ads).forEach(p=>{\nconst platAds=ads[p];\nif(!platAds||typeof platAds!=='object')return;\nplatAds.hashtags=normalizeHashtags(platAds.hashtags,extractedData).join(' ');\n['a','b'].forEach(v=>{\nif(!platAds[v])return;\nplatAds[v].tag=cleanAdText(platAds[v].tag||'');\nplatAds[v].text=appendHashtagsToText(platAds[v].text||'',platAds.hashtags,extractedData);\n});\n});\nreturn ads;\n}\n\n\/\/ ============================================================\n\/\/ MODE & DROP ZONE\n\/\/ ============================================================\nfunction switchMode(mode){\ncurrentMode=mode;\ndocument.getElementById('pdf-mode').style.display=mode==='pdf'?'block':'none';\ndocument.getElementById('url-mode').style.display=mode==='url'?'flex':'none';\ndocument.getElementById('tab-pdf').classList.toggle('active',mode==='pdf');\ndocument.getElementById('tab-url').classList.toggle('active',mode==='url');\n}\n\nfunction setupDropZone(){\nconst dz=document.getElementById('drop-zone');\nconst fi=document.getElementById('file-input');\nif(!dz||!fi){console.warn('DropZone missing');return;}\n['dragover','dragenter'].forEach(ev=>dz.addEventListener(ev,e=>{e.preventDefault();e.stopPropagation();dz.classList.add('drag-over');}));\n['dragleave','dragend'].forEach(ev=>dz.addEventListener(ev,e=>{e.stopPropagation();dz.classList.remove('drag-over');}));\ndz.addEventListener('drop',e=>{e.preventDefault();e.stopPropagation();dz.classList.remove('drag-over');const f=e.dataTransfer.files[0];if(f&&f.type==='application\/pdf')setFile(f);else showToast('Nur PDF-Dateien erlaubt.','err');});\nfi.addEventListener('change',e=>{if(e.target.files[0])setFile(e.target.files[0]);});\ndz.addEventListener('click',e=>{if(e.target.tagName!=='BUTTON')fi.click();});\n}\n\nfunction setFile(f){\nselectedFile=f;\nconst info=document.getElementById('file-info');\nif(info){info.style.display='block';info.textContent='\u2713 '+f.name+' \u00b7 '+(f.size\/1024\/1024).toFixed(1)+' MB';}\n}\n\n\/\/ ============================================================\n\/\/ GENERATION FLOW\n\/\/ ============================================================\nasync function startGeneration(){\nconst key=getApiKey();\nif(!key){const hint=document.getElementById('key-hint');if(hint)hint.classList.add('show');showToast('Bitte zuerst KI-API-Key verbinden.','err');const ki=document.getElementById('api-key-input');if(ki)ki.focus();window.scrollTo({top:0,behavior:'smooth'});return;}\nconst platforms=getSelectedPlatforms();\nif(!platforms.length){showToast('Mindestens eine Plattform ausw\u00e4hlen.','err');return;}\nif(currentMode==='pdf'&&!selectedFile){showToast('Bitte zuerst ein PDF hochladen.','err');return;}\nif(currentMode==='url'&&!document.getElementById('url-field').value.trim()){showToast('Bitte eine URL eingeben.','err');return;}\nhide('input-section');show('processing-section');setStep(2);\ntry{\nlet exposeData;\nconst sourceUrl=currentMode==='url'?document.getElementById('url-field').value.trim():'';\nif(currentMode==='pdf'){clearListingImageAssets();setStatus('PDF wird analysiert...');const b64=await fileToBase64(selectedFile);exposeData=await extractFromPDF(b64);}\nelse{setStatus('Website wird gelesen...');exposeData=await extractFromURL(sourceUrl);}\nextractedData=exposeData;\napplyAutoOverlayText(exposeData,sourceUrl);\nif(sourceUrl){\nhydrateListingImagesFromUrl(sourceUrl).then(()=>{\nif(getAutoListingEditFiles().length)showToast('Anzeigenbilder automatisch in den Bildgenerator \u00fcbernommen.','success');\n}).catch(()=>{});\n}\nsetStep(3);setStatus('Virale Ads werden generiert...');\nconst style=document.getElementById('ad-style').value;\nconst audience=document.getElementById('target-audience').value;\ngeneratedAds=normalizeGeneratedAds(await generateAds(exposeData,platforms,style,audience));\nhide('processing-section');show('results-section');setStep(4);\nrenderAds(generatedAds,platforms);\n}catch(err){hide('processing-section');show('input-section');setStep(1);showError(err.message||'Fehler. Bitte erneut versuchen.');console.error(err);}\n}\n\n\/\/ ============================================================\n\/\/ EXTRACTION \u2014 Anthropic\n\/\/ ============================================================\nasync function extractFromPDF(base64){\nconst key=getApiKey();\nif(!key)throw new Error('Kein API-Key. Bitte oben verbinden.');\nif(currentProvider==='openai')return await extractFromPDFOpenAI(base64,key);\nconst res=await fetch('https:\/\/api.anthropic.com\/v1\/messages',{\nmethod:'POST',\nheaders:{'Content-Type':'application\/json','x-api-key':key,'anthropic-version':'2023-06-01','anthropic-dangerous-direct-browser-access':'true'},\nbody:JSON.stringify({model:'claude-sonnet-4-20250514',max_tokens:2000,\nsystem:'Du bist ein Immobilienexperte. Extrahiere alle Daten aus dem Expos\u00e9. Antworte NUR mit validem JSON ohne Markdown: {\"titel\":\"...\",\"art\":\"...\",\"standort\":\"...\",\"bundesland\":\"...\",\"kaufpreis\":\"...\",\"flaeche\":\"...\",\"zimmer\":\"...\",\"baujahr\":\"...\",\"zustand\":\"...\",\"rendite\":null,\"jnkm\":null,\"faktor\":null,\"besonderheiten\":[\"...\"],\"beschreibung\":\"2-3 S\u00e4tze\"}',\nmessages:[{role:'user',content:[{type:'document',source:{type:'base64',media_type:'application\/pdf',data:base64}},{type:'text',text:'Extrahiere alle Daten aus diesem Immobilien-Expos\u00e9 als JSON.'}]}]})});\nif(!res.ok){const e=await res.text();throw new Error('API '+res.status+': '+e);}\nconst d=await res.json();\nconst txt=d.content.filter(b=>b.type==='text').map(b=>b.text).join('').replace(\/```json|```\/g,'').trim();\nreturn safeJsonParse(txt);\n}\n\nfunction normalizeInputUrl(raw){\nlet url=String(raw||'').trim();\nif(!url)throw new Error('Bitte eine URL eingeben.');\nif(!\/^https?:\\\/\\\/\/i.test(url))url='https:\/\/'+url;\ntry{return new URL(url).href;}catch(e){throw new Error('Bitte eine g\u00fcltige Website-URL eingeben.');}\n}\n\nfunction buildUrlReaders(url){\nconst encoded=encodeURIComponent(url);\nreturn[\n{name:'Jina Reader',url:'https:\/\/r.jina.ai\/'+url,plain:true},\n{name:'Direkt',url:url},\n{name:'AllOrigins Raw',url:'https:\/\/api.allorigins.win\/raw?url='+encoded},\n{name:'AllOrigins JSON',url:'https:\/\/api.allorigins.win\/get?url='+encoded,json:'contents'},\n{name:'CodeTabs',url:'https:\/\/api.codetabs.com\/v1\/proxy?quest='+encoded},\n{name:'CorsProxy',url:'https:\/\/corsproxy.io\/?'+encoded},\n{name:'ThingProxy',url:'https:\/\/thingproxy.freeboard.io\/fetch\/'+url}\n];\n}\n\nfunction normalizeCandidateImageUrl(raw,baseUrl){\nconst val=String(raw||'').trim().replace(\/^['\"]|['\"]$\/g,'');\nif(!val||val.startsWith('data:')||val.startsWith('blob:'))return null;\nif(\/^javascript:\/i.test(val))return null;\ntry{\nconst abs=new URL(val,baseUrl).href;\nif(!\/^https?:\\\/\\\/\/i.test(abs))return null;\nreturn abs;\n}catch(e){\nreturn null;\n}\n}\n\nfunction isLikelyListingImageUrl(url){\nconst low=String(url||'').toLowerCase();\nif(!low)return false;\nif(\/(logo|favicon|icon|sprite|avatar|tracking|pixel|analytics|doubleclick|googleads|badge|placeholder|mapbox|staticmap)\/.test(low))return false;\nif(\/\\.(svg)(\\?|#|$)\/.test(low))return false;\nif(\/\\.(jpe?g|png|webp|avif)(\\?|#|$)\/.test(low))return true;\nreturn \/(image|img|photo|foto|gallery|listing|immobil|property|uploads|media|expose)\/.test(low);\n}\n\nfunction extractListingImageUrls(rawBody,baseUrl,maxCount){\nconst limit=Math.max(1,Number(maxCount)||2);\nconst out=[];\nconst seen=new Set();\nconst pushUrl=(candidate)=>{\nconst abs=normalizeCandidateImageUrl(candidate,baseUrl);\nif(!abs||!isLikelyListingImageUrl(abs))return;\nconst key=abs.replace(\/[?#].*$\/,'').toLowerCase();\nif(seen.has(key))return;\nseen.add(key);\nout.push(abs);\n};\nconst body=String(rawBody||'');\nconst patterns=[\n\/<meta[^>]+(?:property|name)=[\"'](?:og:image|twitter:image)[\"'][^>]+content=[\"']([^\"']+)[\"'][^>]*>\/gi,\n\/<img[^>]+src=[\"']([^\"']+)[\"'][^>]*>\/gi,\n\/\\bsrcset=[\"']([^\"']+)[\"']\/gi,\n\/!\\[[^\\]]*\\]\\((https?:\\\/\\\/[^)\\s]+)\\)\/gi,\n\/https?:\\\/\\\/[^\\s\"'<>]+?\\.(?:jpe?g|png|webp|avif)(?:\\?[^\\s\"'<>]*)?\/gi\n];\npatterns.forEach(rx=>{\nlet m;\nwhile((m=rx.exec(body))!==null){\nif(rx.source.indexOf('srcset')>-1){\nString(m[1]||'').split(',').forEach(part=>pushUrl(String(part).trim().split(\/\\s+\/)[0]));\n}else{\npushUrl(m[1]||m[0]);\n}\nif(out.length>=limit)return;\n}\n});\nreturn out.slice(0,limit);\n}\n\nfunction htmlToPlainText(html){\nreturn String(html||'')\n.replace(\/<script[\\s\\S]*?<\\\/script>\/gi,' ')\n.replace(\/<style[\\s\\S]*?<\\\/style>\/gi,' ')\n.replace(\/<noscript[\\s\\S]*?<\\\/noscript>\/gi,' ')\n.replace(\/<br\\s*\\\/?>\/gi,'\\n')\n.replace(\/<\\\/p>\/gi,'\\n')\n.replace(\/<[^>]+>\/g,' ')\n.replace(\/&nbsp;\/g,' ')\n.replace(\/&amp;\/g,'&')\n.replace(\/&quot;\/g,'\"')\n.replace(\/&#39;\/g,\"'\")\n.replace(\/&uuml;\/g,'\u00fc').replace(\/&Uuml;\/g,'\u00dc')\n.replace(\/&ouml;\/g,'\u00f6').replace(\/&Ouml;\/g,'\u00d6')\n.replace(\/&auml;\/g,'\u00e4').replace(\/&Auml;\/g,'\u00c4')\n.replace(\/&szlig;\/g,'\u00df')\n.replace(\/\\s+\/g,' ')\n.trim();\n}\n\nasync function fetchPageText(rawUrl){\nconst url=normalizeInputUrl(rawUrl);\nconst readers=buildUrlReaders(url);\nconst errors=[];\nfor(const reader of readers){\ntry{\nsetStatus('Website wird gelesen: '+reader.name+'...');\nconst r=await fetch(reader.url,{headers:{'Accept':'text\/plain,text\/html,application\/json,*\/*'}});\nif(!r.ok){errors.push(reader.name+' '+r.status);continue;}\nlet body=await r.text();\nif(reader.json){try{const parsed=JSON.parse(body);body=parsed[reader.json]||body;}catch(e){}}\nconst text=reader.plain?body.trim():htmlToPlainText(body);\nif(text&&text.length>200)return text.substring(0,16000);\nerrors.push(reader.name+' ohne verwertbaren Text');\n}catch(e){errors.push(reader.name+' blockiert');}\n}\nthrow new Error('Website\/URL konnte nicht geladen werden. Bitte URL pr\u00fcfen oder PDF nutzen, falls die Seite Login-, Cookie- oder Bot-Schutz hat. Details: '+errors.slice(0,3).join(', '));\n}\n\nasync function findListingImageUrls(rawUrl,maxCount){\nconst url=normalizeInputUrl(rawUrl);\nconst readers=buildUrlReaders(url);\nconst limit=Math.max(1,Number(maxCount)||2);\nconst out=[];\nconst seen=new Set();\nfor(const reader of readers){\ntry{\nconst r=await fetch(reader.url,{headers:{'Accept':'text\/plain,text\/html,application\/json,*\/*'}});\nif(!r.ok)continue;\nlet body=await r.text();\nif(reader.json){try{const parsed=JSON.parse(body);body=parsed[reader.json]||body;}catch(e){}}\nextractListingImageUrls(body,url,limit).forEach(img=>{\nconst key=img.replace(\/[?#].*$\/,'').toLowerCase();\nif(seen.has(key))return;\nseen.add(key);\nout.push(img);\n});\nif(out.length>=limit)break;\n}catch(e){}\n}\nreturn out.slice(0,limit);\n}\n\nasync function extractFromURL(url){\nconst key=getApiKey();\nif(!key)throw new Error('Kein API-Key. Bitte oben verbinden.');\nsetStatus('Seiteninhalt wird geladen...');\nconst pageText=await fetchPageText(url);\nsetStatus('Objektdaten werden extrahiert...');\nconst sys='Du bist ein Immobilienexperte. Extrahiere aus dem folgenden Webseiten-Text alle Immobiliendaten. Antworte NUR mit validem JSON ohne Markdown: {\"titel\":\"...\",\"art\":\"...\",\"standort\":\"...\",\"bundesland\":\"...\",\"kaufpreis\":\"...\",\"flaeche\":\"...\",\"zimmer\":\"...\",\"baujahr\":\"...\",\"zustand\":\"...\",\"rendite\":null,\"jnkm\":null,\"faktor\":null,\"besonderheiten\":[\"...\"],\"beschreibung\":\"2-3 Saetze\"}';\nif(currentProvider==='openai'){\nconst res=await fetch('https:\/\/api.openai.com\/v1\/chat\/completions',{method:'POST',headers:{'Content-Type':'application\/json','Authorization':'Bearer '+key},body:JSON.stringify({model:'gpt-4o',max_tokens:2000,messages:[{role:'system',content:sys},{role:'user',content:'Webseiten-Text:\\n'+pageText}]})});\nif(!res.ok){const e=await res.text();throw new Error('OpenAI API '+res.status+': '+e);}\nconst d=await res.json();return safeJsonParse(d.choices[0].message.content.replace(\/```json|```\/g,'').trim());\n}else{\nconst res=await fetch('https:\/\/api.anthropic.com\/v1\/messages',{method:'POST',headers:{'Content-Type':'application\/json','x-api-key':key,'anthropic-version':'2023-06-01','anthropic-dangerous-direct-browser-access':'true'},body:JSON.stringify({model:'claude-sonnet-4-20250514',max_tokens:2000,system:sys,messages:[{role:'user',content:'Webseiten-Text:\\n'+pageText}]})});\nif(!res.ok){const e=await res.text();throw new Error('API '+res.status+': '+e);}\nconst d=await res.json();return safeJsonParse(d.content.filter(b=>b.type==='text').map(b=>b.text).join('').replace(\/```json|```\/g,'').trim());\n}\n}\n\nfunction formatTitleFromUrl(rawUrl){\nlet normalized='';\ntry{normalized=normalizeInputUrl(rawUrl);}catch(e){return '';}\ntry{\nconst u=new URL(normalized);\nconst parts=u.pathname.split('\/').filter(Boolean).reverse();\nfor(const part of parts){\nif(part.length<4)continue;\nconst clean=decodeURIComponent(part).replace(\/\\.[a-z0-9]{2,5}$\/i,'').replace(\/[-_]+\/g,' ').replace(\/\\s+\/g,' ').trim();\nif(!clean)continue;\nif(\/^(expose|immobilie|objekt|details|listing|angebote)$\/i.test(clean))continue;\nreturn clean.replace(\/\\b\\w\/g,ch=>ch.toUpperCase());\n}\n}catch(e){}\nreturn '';\n}\n\nfunction buildAutoOverlayText(data,sourceUrl){\nconst obj=data||{};\nconst title=cleanAdText(obj.titel||'').replace(\/\\s+\/g,' ').trim();\nconst fallbackTitle=title||formatTitleFromUrl(sourceUrl)||cleanAdText(obj.art||'').trim();\nconst location=cleanAdText(obj.standort||'').trim();\nif(fallbackTitle&&location&&!fallbackTitle.toLowerCase().includes(location.toLowerCase()))return fallbackTitle+' \u00b7 '+location;\nreturn fallbackTitle||location||'';\n}\n\nfunction applyAutoOverlayText(data,sourceUrl){\nconst input=document.getElementById('img-overlay-text');\nif(!input)return;\nconst suggestion=buildAutoOverlayText(data,sourceUrl);\nif(!suggestion)return;\nconst current=String(input.value||'').trim();\nconst prevAuto=String(input.dataset.autoFillValue||'').trim();\nif(!current||current===prevAuto){\ninput.value=suggestion;\ninput.dataset.autoFillValue=suggestion;\nsaveImageGenSettings(true);\n}\n}\n\nfunction inferImageExtension(type,url){\nconst t=String(type||'').toLowerCase();\nif(t.indexOf('png')>-1)return 'png';\nif(t.indexOf('webp')>-1)return 'webp';\nif(t.indexOf('avif')>-1)return 'avif';\nif(t.indexOf('jpeg')>-1||t.indexOf('jpg')>-1)return 'jpg';\nconst fromUrl=(String(url||'').match(\/\\.([a-z0-9]{3,4})(?:[?#]|$)\/i)||[])[1];\nif(fromUrl&&\/^(png|jpe?g|webp|avif)$\/i.test(fromUrl))return fromUrl.toLowerCase()==='jpeg'?'jpg':fromUrl.toLowerCase();\nreturn 'jpg';\n}\n\nasync function fetchListingImageAsFile(url,index){\nconst candidates=[\nurl,\n'https:\/\/corsproxy.io\/?'+encodeURIComponent(url),\n'https:\/\/api.allorigins.win\/raw?url='+encodeURIComponent(url)\n];\nlet lastErr='Bild konnte nicht geladen werden.';\nfor(const src of candidates){\ntry{\nconst res=await fetch(src,{headers:{'Accept':'image\/*,*\/*;q=0.8'}});\nif(!res.ok){lastErr='Fehler '+res.status;continue;}\nconst blob=await res.blob();\nif(!blob||blob.size<1024){lastErr='Leere Bildantwort.';continue;}\nconst type=blob.type||'';\nif(type&&!\/^image\\\/\/i.test(type)){lastErr='Kein g\u00fcltiges Bildformat.';continue;}\nconst ext=inferImageExtension(type,url);\nconst fileType=type&&\/^image\\\/\/i.test(type)?type:('image\/'+(ext==='jpg'?'jpeg':ext));\nconst fileName='anzeige-bild-'+(index+1)+'.'+ext;\nreturn new File([blob],fileName,{type:fileType});\n}catch(e){\nlastErr=e&&e.message?e.message:lastErr;\n}\n}\nthrow new Error(lastErr);\n}\n\nfunction clearListingImageAssets(){\nif(Array.isArray(listingImageAssets)){\nlistingImageAssets.forEach(item=>{if(item&&item.previewUrl&&item.previewUrl.indexOf('blob:')===0){try{URL.revokeObjectURL(item.previewUrl);}catch(e){}}});\n}\nlistingImageAssets=[];\nconst wrap=document.getElementById('imgedit-source-gallery');\nif(wrap){wrap.style.display='none';wrap.innerHTML='';}\n}\n\nfunction getAutoListingEditFiles(){\nreturn listingImageAssets.map(item=>item&&item.file).filter(Boolean).slice(0,2);\n}\n\nfunction renderListingImageGallery(){\nconst wrap=document.getElementById('imgedit-source-gallery');\nif(!wrap)return;\nif(!listingImageAssets.length){\nwrap.style.display='none';\nwrap.innerHTML='';\nreturn;\n}\nconst usable=getAutoListingEditFiles().length;\nwrap.style.display='block';\nwrap.innerHTML='<div style=\"font-size:10px;letter-spacing:1.2px;text-transform:uppercase;color:var(--gold);margin:6px 0 10px;\">Anzeigebilder erkannt \u00b7 '+usable+'\/'+listingImageAssets.length+' nutzbar<\/div><div style=\"display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:10px;\">'+listingImageAssets.map((item,idx)=>'<div style=\"border:1px solid var(--border-soft);background:var(--dark4);padding:8px;display:flex;flex-direction:column;gap:7px;\"><img decoding=\"async\" src=\"'+escAttr(item.previewUrl||item.sourceUrl||'')+'\" alt=\"Anzeigebild '+(idx+1)+'\" style=\"width:100%;height:100px;object-fit:cover;border:1px solid rgba(0,0,0,0.08);background:#fff;\">'+(item.file?'<button type=\"button\" class=\"imggen-btn-sec\" onclick=\"useListingImageAsPrimary('+idx+')\">Als Hauptfoto nutzen<\/button>':'<div style=\"font-size:10px;color:#c0392b;line-height:1.4;\">Laden blockiert. Bitte Bild manuell hochladen.<\/div>')+'<\/div>').join('')+'<\/div>'+(imageEditFile?'<div style=\"margin-top:10px;\"><button type=\"button\" class=\"imggen-btn-sec\" onclick=\"useAutoListingImages()\">Anzeigebilder automatisch verwenden<\/button><\/div>':'');\n}\n\nfunction useListingImageAsPrimary(index){\nconst item=listingImageAssets[index];\nif(!item||!item.file){showToast('Dieses Bild konnte nicht geladen werden.','err');return;}\nimageEditFile=item.file;\nimageEditDataUrl=item.previewUrl||'';\nrenderImageEditPreview(item.file,item.previewUrl||'');\nupdateImageGenButtonMode();\nshowToast('Anzeigebild '+(index+1)+' als Hauptfoto gesetzt.','success');\n}\n\nfunction useAutoListingImages(){\nremoveImageEditFile(true);\nrenderListingImageGallery();\nupdateImageGenButtonMode();\nshowToast('Automatik mit Anzeigebildern aktiv.','success');\n}\n\nasync function hydrateListingImagesFromUrl(rawUrl){\nclearListingImageAssets();\nlet urls=[];\ntry{urls=await findListingImageUrls(rawUrl,2);}catch(e){urls=[];}\nif(!urls.length){renderListingImageGallery();updateImageGenButtonMode();return;}\nconst assets=await Promise.all(urls.map(async (url,idx)=>{\ntry{\nconst file=await fetchListingImageAsFile(url,idx);\nreturn{sourceUrl:url,file:file,previewUrl:URL.createObjectURL(file)};\n}catch(e){\nreturn{sourceUrl:url,file:null,previewUrl:url,error:e&&e.message?e.message:'Laden blockiert'};\n}\n}));\nlistingImageAssets=assets.slice(0,2);\nrenderListingImageGallery();\nupdateImageGenButtonMode();\n}\n\n\/\/ ============================================================\n\/\/ EXTRACTION \u2014 OpenAI (PDF -> images via PDF.js)\n\/\/ ============================================================\nasync function pdfToImages(base64,maxPages){\nconst lib=window.pdfjsLib;\nif(!lib)throw new Error('PDF-Bibliothek nicht geladen. Bitte Seite neu laden.');\nlib.GlobalWorkerOptions.workerSrc='https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/pdf.js\/3.11.174\/pdf.worker.min.js';\nconst raw=atob(base64);const arr=new Uint8Array(raw.length);\nfor(let i=0;i<raw.length;i++)arr[i]=raw.charCodeAt(i);\nconst pdf=await lib.getDocument({data:arr}).promise;\nconst n=Math.min(pdf.numPages,maxPages||3);\nconst images=[];\nfor(let p=1;p<=n;p++){\nconst page=await pdf.getPage(p);\nconst viewport=page.getViewport({scale:1.5});\nconst canvas=document.createElement('canvas');\ncanvas.width=viewport.width;canvas.height=viewport.height;\nconst ctx=canvas.getContext('2d');\nawait page.render({canvasContext:ctx,viewport:viewport}).promise;\nimages.push(canvas.toDataURL('image\/jpeg',0.8));\n}\nreturn images;\n}\n\nasync function extractFromPDFOpenAI(base64,key){\nsetStatus('PDF wird in Bilder umgewandelt...');\nlet images;\ntry{images=await pdfToImages(base64,3);}catch(e){throw new Error('PDF-Konvertierung fehlgeschlagen: '+e.message);}\nsetStatus('Bilder werden analysiert...');\nconst imageContent=images.map(url=>({type:'image_url',image_url:{url:url}}));\nconst res=await fetch('https:\/\/api.openai.com\/v1\/chat\/completions',{\nmethod:'POST',\nheaders:{'Content-Type':'application\/json','Authorization':'Bearer '+key},\nbody:JSON.stringify({model:'gpt-4o',max_tokens:2000,\nmessages:[{role:'user',content:[{type:'text',text:'Extrahiere alle Daten aus diesem Immobilien-Expos\u00e9 als JSON. Antworte NUR mit validem JSON ohne Markdown: {\"titel\":\"...\",\"art\":\"...\",\"standort\":\"...\",\"bundesland\":\"...\",\"kaufpreis\":\"...\",\"flaeche\":\"...\",\"zimmer\":\"...\",\"baujahr\":\"...\",\"zustand\":\"...\",\"rendite\":null,\"jnkm\":null,\"faktor\":null,\"besonderheiten\":[\"...\"],\"beschreibung\":\"2-3 Saetze\"}'},...imageContent]}]})});\nif(!res.ok){const e=await res.text();throw new Error('OpenAI API '+res.status+': '+e);}\nconst d=await res.json();\nconst txt=d.choices[0].message.content.replace(\/```json|```\/g,'').trim();\nreturn safeJsonParse(txt);\n}\n\n\n\/\/ ============================================================\n\/\/ AD GENERATION\n\/\/ ============================================================\nfunction buildAdPrompt(data,platforms,style,audience){\nconst styleInstructions={\nviral:'STIL: Viral und emotional. Nutze starke Hooks, erzeuge FOMO, kurze kraftvolle Saetze, Neugier wecken, emotionale Trigger setzen.',\nluxury:'STIL: Exklusiv und luxurioes. Raffinierter Premium-Ton, Prestige und Exklusivitaet betonen, gehobene Sprache, keine reisserischen Versprechen.',\ninvestment:'STIL: Investment-fokussiert. Zahlen, Rendite, Fakten im Vordergrund. Sachlich, professionell.',\nstorytelling:'STIL: Storytelling. Erzaehle eine Geschichte rund um das Objekt. Emotional, bildreich, persoenlich.'\n};\nconst audienceInstructions={\ninvestors:'ZIELGRUPPE: Kapitalanleger, Family Offices, Bestandshalter, Projektentwickler, semi-professionelle und institutionelle Immobilieninvestoren.',\nbuyers:'ZIELGRUPPE: Kaufinteressenten und Eigennutzer.',\nbrokers:'ZIELGRUPPE: Makler, Vertriebspartner und Fachpublikum.',\nall:'ZIELGRUPPE: Gemischte Zielgruppe aus Investoren, Eigennutzern und Fachpublikum.'\n};\nconst platInstructions={\ninstagram:'Instagram-Post: vollstaendiges Paket. Max. 2200 Zeichen.',\ntiktok:'TikTok-Script: Hook in 3 Sek., dynamisch, CTA. Max. 150 Woerter.',\nfacebook:'Facebook-Post: Storytelling, vollstaendiges Paket, CTAs.',\nlinkedin:'LinkedIn-Post: Professionell, Thought-Leadership. Max. 1300 Zeichen.',\nwhatsapp:'WhatsApp: Kurz, praegnant, Highlights als Stichpunkte, CTA. Max. 600 Zeichen.',\ngoogle:'Google Business: Lokal SEO-optimiert, Daten, CTA. Max. 1500 Zeichen.',\nxtwitter:'X\/Twitter: Kompakt, Kernfakt, CTA. Max. 280 Zeichen.',\ntelegram:'Telegram: Strukturiert mit Emojis, Daten, CTA, Kontakt.'\n};\nconst obj='Objektart: '+(data.art||'-')+'\\nLage\/Bundesland: '+(data.standort||'-')+(data.bundesland?', '+data.bundesland:'')+'\\nFlaeche: '+(data.flaeche||'-')+'\\nKaufpreis: '+(data.kaufpreis||'-')+'\\nFaktor\/Rendite: '+([data.faktor,data.rendite].filter(Boolean).join(' \/ ')||'-')+'\\nMieteinnahmen\/JNKM: '+(data.jnkm||'-')+'\\nZustand: '+(data.zustand||'-')+'\\nBaujahr: '+(data.baujahr||'-')+'\\nEinheiten\/Zimmer: '+(data.zimmer||'-')+'\\nBesonderheiten: '+((data.besonderheiten||[]).join(', ')||'-')+'\\nBeschreibung: '+(data.beschreibung||'-')+'\\nKontakt: Lima Invest Immobilien | anfrage@limaimmobilien.com | limainvestimmobilien.de';\nconst platList=platforms.map(p=>(p.toUpperCase()+': '+(platInstructions[p]||p))).join('\\n\\n');\nreturn 'Du bist professioneller Immobilien-Marketing-Texter fuer Lima Invest Immobilien.\\n\\n'+styleInstructions[style]+'\\n\\n'+audienceInstructions[audience]+'\\n\\nOBJEKTDATEN:\\n'+obj+'\\n\\nAUFGABE: Erstelle fuer jede angeforderte Plattform exakt 2 vollstaendige Posting-Pakete (Variante a und b) mit unterschiedlichen Winkeln\/Hooks.\\n\\nJede Variante (der \"text\") MUSS als zusammenhaengender, sofort postbarer Beitrag enthalten:\\n1. Starke Headline mit direktem Investmentbezug\\n2. Kurzer Ad-Text fuers Bildmotiv (1 Satz)\\n3. Fertiger Social-Media-Beitrag (Einleitung zum Objekt)\\n4. Wichtigste Investmentdaten kompakt (Lage, Flaeche, Kaufpreis, Faktor\/Rendite, Vermietungsstand, Einheiten)\\n5. Drei verkaufsstarke Highlights mit kurzer Erklaerung\\n6. Zwei bis drei Call-to-Action-Varianten\\n7. Kontakt: Lima Invest Immobilien, anfrage@limaimmobilien.com, limainvestimmobilien.de\\n\\nTon: hochwertig, serioes, klar, investorenorientiert und verkaufsstark. KEINE uebertriebenen Versprechen, KEINE garantierten Rendite-Aussagen.\\nPasse Laenge und Format an die jeweilige Plattform an. Verwende keine Sternchen (*) und keine Markdown-Fettungen. Jede Variante muss am Ende mindestens 5 kontextpassende Hashtags direkt im Text enthalten. Gib dieselben Hashtags zusaetzlich im hashtags-Feld aus.\\n\\nPLATTFORMEN:\\n'+platList+'\\n\\nAntworte NUR mit validem JSON (kein Markdown, keine Backticks):\\n{\"instagram\":{\"a\":{\"tag\":\"Variantenname\",\"text\":\"vollstaendiger Beitrag\"},\"b\":{\"tag\":\"Variantenname\",\"text\":\"...\"},\"hashtags\":\"#...\"}}\\nNur die angeforderten Plattformen einbeziehen.';\n}\n\nasync function generateAds(data,platforms,style,audience){\nconst key=getApiKey();\nif(!key)throw new Error('Kein API-Key. Bitte oben verbinden.');\nif(currentProvider==='openai')return await generateAdsOpenAI(data,platforms,style,audience,key);\nconst prompt=buildAdPrompt(data,platforms,style,audience);\nconst res=await fetch('https:\/\/api.anthropic.com\/v1\/messages',{\nmethod:'POST',\nheaders:{'Content-Type':'application\/json','x-api-key':key,'anthropic-version':'2023-06-01','anthropic-dangerous-direct-browser-access':'true'},\nbody:JSON.stringify({model:'claude-sonnet-4-20250514',max_tokens:8000,system:'Antworte ausschliesslich mit validem JSON ohne Markdown.',messages:[{role:'user',content:prompt}]})});\nif(!res.ok){const e=await res.text();throw new Error('API '+res.status+': '+e);}\nconst d=await res.json();\nconst txt=d.content.filter(b=>b.type==='text').map(b=>b.text).join('').replace(\/```json|```\/g,'').trim();\nreturn safeJsonParse(txt);\n}\n\nasync function generateAdsOpenAI(data,platforms,style,audience,key){\nconst prompt=buildAdPrompt(data,platforms,style,audience);\nconst res=await fetch('https:\/\/api.openai.com\/v1\/chat\/completions',{\nmethod:'POST',\nheaders:{'Content-Type':'application\/json','Authorization':'Bearer '+key},\nbody:JSON.stringify({model:'gpt-4o',max_tokens:8000,messages:[{role:'system',content:'Antworte ausschliesslich mit validem JSON ohne Markdown.'},{role:'user',content:prompt}]})});\nif(!res.ok){const e=await res.text();throw new Error('OpenAI API '+res.status+': '+e);}\nconst d=await res.json();\nconst txt=d.choices[0].message.content.replace(\/```json|```\/g,'').trim();\nreturn safeJsonParse(txt);\n}\n\n\/\/ ============================================================\n\/\/ RENDER ADS\n\/\/ ============================================================\nfunction renderAds(ads,platforms){\nads=normalizeGeneratedAds(ads);\nconst tabsEl=document.getElementById('plat-tabs');\nconst boxEl=document.getElementById('ads-box');\nif(!tabsEl||!boxEl)return;\ntabsEl.innerHTML='';boxEl.innerHTML='';\nconst visible=platforms.filter(p=>ads[p]);\nvisible.forEach((p,i)=>{\nconst cfg=PLATFORMS[p]||{icon:'',name:p,format:'',timing:''};\nconst isConn=!!connectedAccounts[p];\nconst tab=document.createElement('div');\ntab.className='pt'+(i===0?' active':'')+(isConn?' connected':'');\ntab.innerHTML='<span class=\"pt-dot\"><\/span><span>'+cfg.icon+'<\/span><span>'+cfg.name+'<\/span>';\ntab.dataset.p=p;tab.onclick=()=>switchPlatformTab(p);\ntabsEl.appendChild(tab);\nconst content=document.createElement('div');\ncontent.className='plat-content'+(i===0?' active':'');content.id='pc-'+p;\nconst platAds=ads[p];const variants=['a','b'].filter(v=>platAds[v]);\ncontent.innerHTML='<div class=\"plat-meta\"><div class=\"plat-icon-lg\">'+cfg.icon+'<\/div><div class=\"plat-info\"><h3>'+cfg.name+'<\/h3><p>'+cfg.format+' \u00b7 \u23f0 '+cfg.timing+'<\/p><\/div>'+(isConn?'<div class=\"post-status connected\" style=\"margin-left:auto;\">Verbunden<\/div>':'')+'<\/div><div class=\"ad-variants\">'+variants.map((v,vi)=>'<div class=\"av\" id=\"av-'+p+'-'+v+'\"><div class=\"av-head\"><span class=\"av-label\">Variante '+(vi===0?'A':'B')+'<\/span><span class=\"av-tag\">'+escHtml(platAds[v].tag||'')+'<\/span><button class=\"copy-btn\" onclick=\"copyTxt(\\'txt-'+p+'-'+v+'\\',this)\">Kopieren<\/button><\/div><div class=\"av-body\"><div class=\"ad-txt\" id=\"txt-'+p+'-'+v+'\">'+escHtml(platAds[v].text||'')+'<\/div><\/div><\/div>').join('')+'<\/div>'+(platAds.hashtags?'<div class=\"ht-block\"><div class=\"ht-label\">Hashtags<\/div><div class=\"ht-txt\" id=\"ht-'+p+'\">'+escHtml(platAds.hashtags)+'<\/div><\/div>':'');\nboxEl.appendChild(content);\nconst pp=document.createElement('div');\npp.className='posting-panel';pp.id='pp-'+p;pp.style.display=i===0?'block':'none';\npp.innerHTML=buildPostingPanel(p,platAds,isConn);\nboxEl.appendChild(pp);\n});\nrenderImagePostingPanel(visible[0]||null);\n}\n\nfunction buildTransformControls(){\nreturn '<div class=\"transform-controls\"><span class=\"transform-label\">Umwandeln:<\/span><div class=\"transform-btn-group\"><button class=\"transform-btn\" data-transform-anrede=\"du\" onclick=\"setAnrede(\\'du\\')\" title=\"Alle Ads in Du-Form\">\ud83d\udc64 Duzen<\/button><button class=\"transform-btn\" data-transform-anrede=\"sie\" onclick=\"setAnrede(\\'sie\\')\" title=\"Alle Ads in Sie-Form\">\ud83e\udd1d Siezen<\/button><\/div><div class=\"transform-btn-group\"><button class=\"transform-btn\" data-transform-emoji=\"more\" onclick=\"transformEmoji(\\'more\\')\" title=\"Mehr Emojis hinzuf\u00fcgen\">\ud83d\ude0a+ Mehr Emojis<\/button><button class=\"transform-btn\" data-transform-emoji=\"less\" onclick=\"transformEmoji(\\'less\\')\" title=\"Emojis reduzieren\">\ud83d\udeab Weniger Emojis<\/button><\/div><\/div>';\n}\n\nfunction buildPostingPanel(p,platAds,isConn){\nconst cfg=PLATFORMS[p]||{};\nconst connectedLabel=isOAuthConnected(p)?'\u2713 Konto verwalten':'\u26a1 Konto verbinden';\nconst buttons='<button class=\"post-btn post-btn-copy\" onclick=\"copyPlatformText(\\''+p+'\\')\">\ud83d\udccb Text kopieren<\/button><button class=\"post-btn '+postingButtonClass(p)+'\" onclick=\"openPostingApp(\\''+p+'\\')\">'+(cfg.icon||'\u2197')+' '+postingButtonLabel(p)+'<\/button><button class=\"post-btn\" style=\"background:transparent;border:1px solid var(--gold-border);color:var(--gold);\" onclick=\"openConnectModal(\\''+p+'\\')\">'+connectedLabel+'<\/button>';\nreturn '<div class=\"pp-top\"><div class=\"pp-title\">\ud83d\udce4 Posting-Optionen<\/div>'+buildTransformControls()+'<\/div><div class=\"post-actions\">'+buttons+'<\/div>';\n}\n\nfunction postingButtonClass(p){\nreturn 'post-btn-'+(p==='xtwitter'?'xtwitter':p);\n}\n\nfunction postingButtonLabel(p){\nif(isOAuthConnected(p)&&platformSupportsDirectPost(p))return 'Direkt posten';\nconst labels={instagram:'Instagram \u00f6ffnen',tiktok:'TikTok Upload \u00f6ffnen',facebook:'Facebook \u00f6ffnen',linkedin:'LinkedIn \u00f6ffnen',whatsapp:'WhatsApp \u00f6ffnen',google:'Google Business \u00f6ffnen',xtwitter:'X \u00f6ffnen',telegram:'Telegram \u00f6ffnen'};\nreturn labels[p]||'App \u00f6ffnen';\n}\n\nfunction getPostingText(p){\nif(!generatedAds||!generatedAds[p])return '';\nconst ads=generatedAds[p];\nreturn appendHashtagsToText(((ads['a']&&ads['a'].text)||(ads['b']&&ads['b'].text)||''),ads.hashtags,extractedData);\n}\n\nfunction shortPreview(text,maxChars){\nconst chars=Array.from(String(text||''));\nif(chars.length<=maxChars)return chars.join('');\nreturn chars.slice(0,maxChars).join('')+' ...';\n}\n\nfunction setImagePostingPlatform(platform){\nrenderImagePostingPanel(platform);\n}\n\nfunction renderImagePostingPanel(activePlatform){\nconst panel=document.getElementById('img-posting-panel');\nconst meta=document.getElementById('img-posting-meta');\nconst actions=document.getElementById('img-posting-actions');\nif(!panel||!meta||!actions)return;\nif(!generatedAds){panel.style.display='none';meta.innerHTML='';actions.innerHTML='';return;}\nconst platforms=getSelectedPlatforms().filter(p=>generatedAds&&generatedAds[p]);\nif(!platforms.length){panel.style.display='none';meta.innerHTML='';actions.innerHTML='';return;}\nconst tabPlatform=(document.querySelector('.pt.active')||{}).dataset?document.querySelector('.pt.active').dataset.p:null;\nconst selected=platforms.includes(activePlatform)?activePlatform:(platforms.includes(tabPlatform)?tabPlatform:platforms[0]);\nconst cfg=PLATFORMS[selected]||{name:selected,icon:'\ud83d\udce4'};\nconst preview=shortPreview(getPostingText(selected),360);\nmeta.innerHTML='<div style=\"font-size:10px;color:var(--text-muted);margin-bottom:8px;\">'+cfg.icon+' '+escHtml(cfg.name)+' \u00b7 Verwendet den oberen Ad-Text (Variante A\/B).<\/div><div style=\"background:var(--dark4);border-left:2px solid var(--gold);padding:10px;font-size:11px;line-height:1.7;color:var(--text-sub);max-height:126px;overflow:auto;margin-bottom:10px;\">'+escHtml(preview||'Kein Text verf\u00fcgbar.')+'<\/div>';\nactions.innerHTML=platforms.map(p=>{const pcfg=PLATFORMS[p]||{name:p,icon:'\ud83d\udccc'};const active=p===selected;return '<button class=\"post-btn post-btn-copy\" style=\"'+(active?'border-color:var(--gold);color:var(--gold);':'')+'\" onclick=\"setImagePostingPlatform(\\''+p+'\\')\">'+pcfg.icon+' '+escHtml(pcfg.name)+'<\/button>';}).join('')+'<button class=\"post-btn post-btn-copy\" onclick=\"copyPlatformText(\\''+selected+'\\')\">\ud83d\udccb Text kopieren<\/button><button class=\"post-btn post-btn-direct\" onclick=\"openPostingApp(\\''+selected+'\\')\">\ud83d\ude80 Posten<\/button>';\npanel.style.display='block';\n}\n\nfunction getPostingUrl(p,text){\nconst cfg=PLATFORMS[p]||{};\nif(typeof cfg.deepLink==='function')return cfg.deepLink(text||'');\nreturn POSTING_SHARE_URL;\n}\n\nasync function publishPostDirectly(p,text){\nconst hashtags=generatedAds&&generatedAds[p]?generatedAds[p].hashtags:'';\nconst payload={\nplatform:p,\ntext:text,\nhashtags:hashtags||'',\nmediaUrl:(generatedImageUrls&&generatedImageUrls[0]&&generatedImageUrls[0].startsWith('http'))?generatedImageUrls[0]:null,\nmeta:{\nsource:'lima-ad-generator',\ncreatedAt:new Date().toISOString(),\nobjectTitle:(extractedData&&(extractedData.titel||extractedData.art))||null,\nlocation:(extractedData&&extractedData.standort)||null\n}\n};\nconst res=await socialRequest('\/v1\/social\/post',{method:'POST',body:payload,timeoutMs:45000});\nif(res&&res.url){try{window.open(res.url,'_blank','noopener');}catch(e){}}\nshowToast((PLATFORMS[p]&&PLATFORMS[p].name?PLATFORMS[p].name:'Plattform')+' direkt gepostet \u2713','success');\n}\n\nasync function openPostingApp(p){\nconst cfg=PLATFORMS[p]||{name:p};\nconst text=getPostingText(p);\nif(isOAuthConnected(p)&&platformSupportsDirectPost(p)){\ntry{await publishPostDirectly(p,text);return;}catch(e){showToast('Direkt-Posting fehlgeschlagen: '+e.message,'err');}\n}\nconst url=getPostingUrl(p,text);\nconst win=window.open(url,'_blank','noopener');\nif(text&&navigator.clipboard&&navigator.clipboard.writeText){\nnavigator.clipboard.writeText(text).catch(()=>{});\n}\nif(!win)showToast((cfg.name||'App')+' wurde blockiert. Bitte Pop-ups erlauben.','err');\nelse showToast((cfg.name||'App')+' ge\u00f6ffnet \u00b7 Text wurde kopiert.','success');\n}\n\nfunction unicodeSafeLimit(text,maxChars){\nreturn Array.from(String(text||'')).slice(0,maxChars).join('');\n}\n\nfunction encodeWhatsAppText(text,maxChars){\nconst safe=unicodeSafeLimit(cleanAdText(text).normalize('NFC'),maxChars);\ntry{return encodeURIComponent(safe);}catch(e){return encodeURIComponent(safe.replace(\/[\\uD800-\\uDFFF]\/g,''));}\n}\n\nfunction switchPlatformTab(p){\ndocument.querySelectorAll('.pt').forEach(t=>t.classList.toggle('active',t.dataset.p===p));\ndocument.querySelectorAll('.plat-content').forEach(c=>c.classList.toggle('active',c.id==='pc-'+p));\ndocument.querySelectorAll('.posting-panel').forEach(pp=>pp.style.display=pp.id==='pp-'+p?'block':'none');\nrenderImagePostingPanel(p);\n}\n\n\/\/ ============================================================\n\/\/ COPY & EXPORT\n\/\/ ============================================================\nfunction copyTxt(id,btn){const el=document.getElementById(id);if(!el)return;navigator.clipboard.writeText(cleanAdText(el.textContent)).then(()=>{if(btn){btn.textContent='\u2713 Kopiert';btn.classList.add('copied');setTimeout(()=>{btn.textContent='Kopieren';btn.classList.remove('copied');},2000);}showToast('Kopiert!','success');});}\nfunction copyPlatformText(p){if(!generatedAds||!generatedAds[p])return;const ads=generatedAds[p];const text=appendHashtagsToText(((ads['a']&&ads['a'].text)||(ads['b']&&ads['b'].text)||''),ads.hashtags,extractedData);navigator.clipboard.writeText(text).then(()=>showToast((PLATFORMS[p].name||'')+' Text kopiert!','success'));}\nfunction buildAdsExportText(){\nif(!generatedAds)return '';\nnormalizeGeneratedAds(generatedAds);\nlet out='LIMA INVEST \u00b7 AD GENERATOR\\nObjekt: '+((extractedData&& (extractedData.titel||extractedData.art))||'-')+'\\nGeneriert: '+new Date().toLocaleDateString('de-DE')+'\\n\\n';\ngetSelectedPlatforms().forEach(p=>{if(!generatedAds[p])return;const cfg=PLATFORMS[p]||{name:p,icon:''};out+='\\n'+'='.repeat(60)+'\\n'+cfg.icon+' '+String(cfg.name||p).toUpperCase()+'\\n'+'='.repeat(60)+'\\n\\n';['a','b'].forEach((v,i)=>{if(generatedAds[p][v])out+='VARIANTE '+(i===0?'A':'B')+': '+(generatedAds[p][v].tag||'')+'\\n'+'-'.repeat(40)+'\\n'+(generatedAds[p][v].text||'')+'\\n\\n';});});\nreturn cleanAdText(out);\n}\nfunction copyAllAds(){if(!generatedAds){showToast('Noch keine Ads generiert.','err');return;}normalizeGeneratedAds(generatedAds);let out='LIMA INVEST \u00b7 AD GENERATOR\\n'+new Date().toLocaleDateString('de-DE')+'\\n\\n';getSelectedPlatforms().forEach(p=>{if(!generatedAds[p])return;const cfg=PLATFORMS[p];out+='\u2550'.repeat(50)+'\\n'+cfg.icon+' '+cfg.name.toUpperCase()+'\\n'+'\u2550'.repeat(50)+'\\n\\n';['a','b'].forEach((v,i)=>{if(generatedAds[p][v])out+='\u2014 Variante '+(i===0?'A':'B')+' ('+generatedAds[p][v].tag+') \u2014\\n\\n'+generatedAds[p][v].text+'\\n\\n';});});navigator.clipboard.writeText(cleanAdText(out.trim())).then(()=>showToast('Alle Ads kopiert!','success'));}\nfunction downloadAds(){if(!generatedAds||!extractedData){showToast('Noch keine Ads generiert.','err');return;}normalizeGeneratedAds(generatedAds);let out='LIMA INVEST \u00b7 AD GENERATOR\\nObjekt: '+(extractedData.titel||extractedData.art||'-')+'\\nGeneriert: '+new Date().toLocaleDateString('de-DE')+'\\n\\n';getSelectedPlatforms().forEach(p=>{if(!generatedAds[p])return;const cfg=PLATFORMS[p];out+='\\n'+'\u2550'.repeat(60)+'\\n'+cfg.icon+' '+cfg.name.toUpperCase()+'\\n'+'\u2550'.repeat(60)+'\\n\\n';['a','b'].forEach((v,i)=>{if(generatedAds[p][v])out+='VARIANTE '+(i===0?'A':'B')+': '+generatedAds[p][v].tag+'\\n'+'\u2500'.repeat(40)+'\\n'+generatedAds[p][v].text+'\\n\\n';});});const blob=new Blob([cleanAdText(out)],{type:'text\/plain;charset=utf-8'});const a=document.createElement('a');a.href=URL.createObjectURL(blob);a.download='lima-ads-'+((extractedData.standort||'objekt').replace(\/[^a-z0-9]\/gi,'-'))+'-'+Date.now()+'.txt';a.click();URL.revokeObjectURL(a.href);showToast('Export gestartet.');}\nfunction pdfSafeText(text){return cleanAdText(text).replace(\/[\\u{1F000}-\\u{1FAFF}\\u{2600}-\\u{27BF}]\/gu,'').replace(\/[\u2550\u2500\u2014\u2013]\/g,'-').replace(\/[\u201c\u201d]\/g,'\"').replace(\/[\u2018\u2019]\/g,\"'\");}\nfunction ensureJsPdf(){\nif(window.jspdf&&window.jspdf.jsPDF)return Promise.resolve(window.jspdf.jsPDF);\nreturn new Promise((resolve,reject)=>{const existing=document.querySelector('script[data-jspdf-loader]');if(existing){existing.addEventListener('load',()=>resolve(window.jspdf.jsPDF));existing.addEventListener('error',reject);return;}const s=document.createElement('script');s.src='https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/jspdf\/2.5.1\/jspdf.umd.min.js';s.dataset.jspdfLoader='1';s.onload=()=>window.jspdf&&window.jspdf.jsPDF?resolve(window.jspdf.jsPDF):reject(new Error('PDF-Bibliothek nicht verf\u00fcgbar.'));s.onerror=()=>reject(new Error('PDF-Bibliothek konnte nicht geladen werden.'));document.head.appendChild(s);});\n}\nasync function downloadAdsPdf(){\nif(!generatedAds||!extractedData){showToast('Noch keine Ads generiert.','err');return;}\ntry{\nconst jsPDF=await ensureJsPdf();\nconst doc=new jsPDF({unit:'pt',format:'a4'});\nconst margin=46,pageW=doc.internal.pageSize.getWidth(),pageH=doc.internal.pageSize.getHeight(),maxW=pageW-margin*2;\nlet y=54;const lineH=14;\ndoc.setFont('helvetica','bold');doc.setFontSize(17);doc.text('LIMA INVEST \u00b7 AD GENERATOR',margin,y);y+=24;\ndoc.setFont('helvetica','normal');doc.setFontSize(10);doc.text('Objekt: '+pdfSafeText((extractedData.titel||extractedData.art||'-')),margin,y);y+=16;doc.text('Generiert: '+new Date().toLocaleDateString('de-DE'),margin,y);y+=28;\nconst exportText=buildAdsExportText();const bodyText=exportText.split('\\n\\n').slice(1).join('\\n\\n')||exportText;\nconst paragraphs=pdfSafeText(bodyText).split(\/\\n\/);\nfor(const para of paragraphs){const text=para.trim();if(!text){y+=8;continue;}if(y>pageH-56){doc.addPage();y=54;}const isHead=\/^[A-Z0-9 \/]+$\/.test(text)&&text.length<70;doc.setFont('helvetica',isHead?'bold':'normal');doc.setFontSize(isHead?12:10);const lines=doc.splitTextToSize(text,maxW);for(const line of lines){if(y>pageH-44){doc.addPage();y=54;}doc.text(line,margin,y);y+=isHead?16:lineH;}if(isHead)y+=4;}\nconst pages=doc.internal.getNumberOfPages();for(let i=1;i<=pages;i++){doc.setPage(i);doc.setFont('helvetica','normal');doc.setFontSize(8);doc.text('Seite '+i+' \/ '+pages,pageW-margin,pageH-24,{align:'right'});}\ndoc.save('lima-ads-'+((extractedData.standort||'objekt').replace(\/[^a-z0-9]\/gi,'-'))+'-'+Date.now()+'.pdf');\nshowToast('PDF Export gestartet.','success');\n}catch(e){showToast('PDF konnte nicht erstellt werden: '+e.message,'err');}\n}\nfunction resetApp(){\nextractedData=null;\ngeneratedAds=null;\nselectedFile=null;\ngeneratedImageUrls=[];\nclearListingImageAssets();\nremoveImageEditFile(true);\nhide('results-section');\nshow('input-section');\nsetStep(1);\nconst fi=document.getElementById('file-input');if(fi)fi.value='';\nconst info=document.getElementById('file-info');if(info)info.style.display='none';\nconst url=document.getElementById('url-field');if(url)url.value='';\nconst overlay=document.getElementById('img-overlay-text');if(overlay){overlay.value='';overlay.dataset.autoFillValue='';}\nconst imgPost=document.getElementById('img-posting-panel');if(imgPost)imgPost.style.display='none';\nconst imgMeta=document.getElementById('img-posting-meta');if(imgMeta)imgMeta.innerHTML='';\nconst imgActions=document.getElementById('img-posting-actions');if(imgActions)imgActions.innerHTML='';\ndocument.querySelectorAll('.err-box').forEach(e=>e.remove());\n}\n\n\/\/ ============================================================\n\/\/ TRANSFORM: Duzen \/ Siezen \/ Emojis\n\/\/ ============================================================\nasync function setAnrede(mode){\nconst key=getApiKey();if(!key){showToast('Bitte zuerst API-Key verbinden.','err');return;}\nif(!generatedAds){showToast('Zuerst Ads generieren.','err');return;}\ncurrentAnrede=mode;\ndocument.querySelectorAll('[data-transform-anrede=\"du\"]').forEach(b=>b.classList.toggle('active',mode==='du'));\ndocument.querySelectorAll('[data-transform-anrede=\"sie\"]').forEach(b=>b.classList.toggle('active',mode==='sie'));\nsetTransformLoading(true);\ntry{\nfor(const p of Object.keys(generatedAds)){const ads=generatedAds[p];for(const v of ['a','b']){if(!ads[v])continue;const el=document.getElementById('txt-'+p+'-'+v);if(!el)continue;el.style.opacity='0.4';const t=await transformText(ads[v].text,'Wandle den folgenden Text komplett in die '+(mode==='du'?'Du-Form (duzen)':'Sie-Form (siezen)')+' um. Behalte Ton, Stil, Struktur, alle Daten und die Hashtags exakt bei. Verwende keine Sternchen (*) und kein Markdown. Gib nur den umgewandelten Text zurueck.',key);ads[v].text=appendHashtagsToText(t,ads.hashtags,extractedData);el.textContent=ads[v].text;el.style.opacity='1';}}\nshowToast('Alle Ads in '+(mode==='du'?'Du':'Sie')+'-Form umgewandelt \u2713','success');\n}catch(e){showToast('Fehler: '+e.message,'err');}\nsetTransformLoading(false);\n}\n\nasync function transformEmoji(direction){\nconst key=getApiKey();if(!key){showToast('Bitte zuerst API-Key verbinden.','err');return;}\nif(!generatedAds){showToast('Zuerst Ads generieren.','err');return;}\ndocument.querySelectorAll('[data-transform-emoji=\"more\"]').forEach(b=>b.classList.toggle('active',direction==='more'));\ndocument.querySelectorAll('[data-transform-emoji=\"less\"]').forEach(b=>b.classList.toggle('active',direction==='less'));\nsetTransformLoading(true);\nconst instruction=direction==='more'?'Fuege passende Emojis in den Text ein, die den Inhalt visuell unterstuetzen. Behalte alle Inhalte, Daten und Hashtags exakt bei. Verwende keine Sternchen (*) und kein Markdown. Gib nur den Text zurueck.':'Entferne alle oder fast alle Emojis aus dem Text. Behalte alle Inhalte, Daten und Hashtags exakt bei. Verwende keine Sternchen (*) und kein Markdown. Gib nur den Text zurueck.';\ntry{\nfor(const p of Object.keys(generatedAds)){const ads=generatedAds[p];for(const v of ['a','b']){if(!ads[v])continue;const el=document.getElementById('txt-'+p+'-'+v);if(!el)continue;el.style.opacity='0.4';const t=await transformText(ads[v].text,instruction,key);ads[v].text=appendHashtagsToText(t,ads.hashtags,extractedData);el.textContent=ads[v].text;el.style.opacity='1';}}\nshowToast(direction==='more'?'Mehr Emojis hinzugefuegt \u2713':'Emojis reduziert \u2713','success');\n}catch(e){showToast('Fehler: '+e.message,'err');}\nsetTransformLoading(false);\n}\n\nasync function transformText(text,instruction,key){\nif(currentProvider==='openai'){\nconst res=await fetch('https:\/\/api.openai.com\/v1\/chat\/completions',{method:'POST',headers:{'Content-Type':'application\/json','Authorization':'Bearer '+key},body:JSON.stringify({model:'gpt-4o',max_tokens:2000,messages:[{role:'user',content:instruction+'\\n\\nText:\\n'+text}]})});\nconst d=await res.json();return d.choices[0].message.content.trim();\n}else{\nconst res=await fetch('https:\/\/api.anthropic.com\/v1\/messages',{method:'POST',headers:{'Content-Type':'application\/json','x-api-key':key,'anthropic-version':'2023-06-01','anthropic-dangerous-direct-browser-access':'true'},body:JSON.stringify({model:'claude-sonnet-4-20250514',max_tokens:2000,messages:[{role:'user',content:instruction+'\\n\\nText:\\n'+text}]})});\nconst d=await res.json();return d.content.filter(b=>b.type==='text').map(b=>b.text).join('').trim();\n}\n}\n\nfunction setTransformLoading(loading){document.querySelectorAll('.transform-btn').forEach(b=>b.disabled=loading);}\n\n\/\/ ============================================================\n\/\/ IMAGE GENERATION\n\/\/ ============================================================\nfunction toggleImgSettings(){imgSettingsOpen=!imgSettingsOpen;document.getElementById('imggen-settings').style.display=imgSettingsOpen?'block':'none';document.getElementById('imggen-settings-toggle').textContent=imgSettingsOpen?'\u2715 Schlie\u00dfen':'\u2699 Einstellungen';}\n\nfunction readImageGenSettings(){\ntry{return JSON.parse(localStorage.getItem(IMGGEN_SETTINGS_KEY)||'{}')||{};}catch(e){return {};}\n}\n\nfunction setControlValue(id,value){\nif(value===undefined||value===null)return;\nconst el=document.getElementById(id);if(!el)return;\nif(el.tagName==='SELECT'&&!Array.from(el.options).some(o=>o.value===String(value)))return;\nel.value=value;\n}\n\nfunction getImageEditToggleState(){\nconst state={};\ndocument.querySelectorAll('#imgedit-sliders input[type=\"checkbox\"]').forEach(input=>{state[input.dataset.editKey]=!!input.checked;});\nreturn state;\n}\n\nfunction saveImageGenSettings(silent){\nconst settings={\noverlayText:document.getElementById('img-overlay-text')?.value||'',\nstyle:document.getElementById('img-style-select')?.value||'',\nfont:document.getElementById('img-font-select')?.value||'',\nfontSize:document.getElementById('img-fontsize-select')?.value||'medium',\ntextPosition:document.getElementById('img-text-position-select')?.value||'middle',\ntextColor:document.getElementById('img-text-color')?.value||'#bb9e1c',\nlogoOpacity:document.getElementById('img-logo-opacity')?.value||'80',\nlogoSize:document.getElementById('img-logo-size')?.value||'14',\nlogoPosition:document.getElementById('img-logo-position')?.value||'top-right',\neditToggles:getImageEditToggleState(),\nlogo:logoDataUrl?{dataUrl:logoDataUrl,name:(logoFile&&logoFile.name)||'Gespeichertes Logo'}:null\n};\ntry{localStorage.setItem(IMGGEN_SETTINGS_KEY,JSON.stringify(settings));return true;}\ncatch(e){if(!silent)showToast('Logo ist zu gro\u00df zum dauerhaften Speichern. Einstellungen bleiben f\u00fcr diese Sitzung aktiv.','err');return false;}\n}\n\nfunction restoreImageGenSettings(){\nconst s=readImageGenSettings();\nsetControlValue('img-overlay-text',s.overlayText);\nsetControlValue('img-style-select',s.style);\nsetControlValue('img-font-select',s.font);\nsetControlValue('img-fontsize-select',s.fontSize);\nsetControlValue('img-text-position-select',s.textPosition);\nsetControlValue('img-text-color',s.textColor);\nsetControlValue('img-logo-opacity',s.logoOpacity);\nsetControlValue('img-logo-size',s.logoSize);\nsetControlValue('img-logo-position',s.logoPosition);\nif(s.editToggles&&typeof s.editToggles==='object'){\ndocument.querySelectorAll('#imgedit-sliders input[type=\"checkbox\"]').forEach(input=>{input.checked=!!s.editToggles[input.dataset.editKey];updateImageEditSlider(input);});\n}\nif(s.logo&&s.logo.dataUrl){\nlogoFile={name:s.logo.name||'Gespeichertes Logo'};\nlogoDataUrl=s.logo.dataUrl;\nrenderLogoPreview(logoFile,logoDataUrl);\n}\nupdateLogoRangeLabels();\nconst color=document.getElementById('img-text-color');const lbl=document.getElementById('color-label');if(color&&lbl)lbl.textContent=color.value;\n}\n\nfunction initImageGenSettingsPersistence(){\n['img-overlay-text','img-style-select','img-font-select','img-fontsize-select','img-text-position-select','img-text-color','img-logo-position'].forEach(id=>{\nconst el=document.getElementById(id);if(!el||el.dataset.persistBound)return;el.dataset.persistBound='1';\nel.addEventListener('change',()=>saveImageGenSettings(true));\nel.addEventListener('input',()=>{if(id==='img-text-color'){const lbl=document.getElementById('color-label');if(lbl)lbl.textContent=el.value;}saveImageGenSettings(true);});\n});\n['img-logo-opacity','img-logo-size'].forEach(id=>{\nconst el=document.getElementById(id);if(!el||el.dataset.persistBound)return;el.dataset.persistBound='1';\nel.addEventListener('input',()=>{updateLogoRangeLabels();saveImageGenSettings(true);});\nel.addEventListener('change',()=>saveImageGenSettings(true));\n});\ndocument.querySelectorAll('#imgedit-sliders input[type=\"checkbox\"]').forEach(input=>{\nif(input.dataset.persistBound)return;input.dataset.persistBound='1';\ninput.addEventListener('change',()=>saveImageGenSettings(true));\n});\n}\n\nfunction initImageEditUpload(){\nconst drop=document.getElementById('imgedit-drop-zone');const input=document.getElementById('imgedit-file-input');\nif(!drop||!input||drop.dataset.bound)return;\ndrop.dataset.bound='1';\ninput.addEventListener('change',e=>handleImageEditFile(e.target.files&&e.target.files[0]));\n['dragenter','dragover'].forEach(ev=>drop.addEventListener(ev,e=>{e.preventDefault();e.stopPropagation();drop.classList.add('drag-over');}));\n['dragleave','drop'].forEach(ev=>drop.addEventListener(ev,e=>{e.preventDefault();e.stopPropagation();drop.classList.remove('drag-over');}));\ndrop.addEventListener('drop',e=>handleImageEditFile(e.dataTransfer&&e.dataTransfer.files&&e.dataTransfer.files[0]));\ninitImageEditSliders();\nupdateImageGenButtonMode();\n}\n\nfunction initImageEditSliders(){\ndocument.querySelectorAll('#imgedit-sliders input[type=\"checkbox\"]').forEach(input=>{\nif(input.dataset.bound)return;input.dataset.bound='1';\ninput.addEventListener('change',()=>updateImageEditSlider(input));\nupdateImageEditSlider(input);\n});\n}\n\nfunction updateImageEditSlider(input){\nconst wrap=input.closest('.imgedit-toggle');const val=wrap?wrap.querySelector('.imgedit-value'):null;\nif(val)val.textContent=input.checked?'Ja':'Nein';\nif(wrap)wrap.classList.toggle('active',!!input.checked);\n}\n\nfunction resetImageEditSliders(){\ndocument.querySelectorAll('#imgedit-sliders input[type=\"checkbox\"]').forEach(input=>{input.checked=false;updateImageEditSlider(input);});\nsaveImageGenSettings(true);\nshowToast('Schalter zur\u00fcckgesetzt.');\n}\n\nasync function handleImageEditFile(file){\nif(!file)return;\nif(!\/^image\\\/(png|jpe?g|webp)$\/i.test(file.type||'')){showToast('Bitte JPG, PNG oder WebP hochladen.','err');return;}\nif(file.size>50*1024*1024){showToast('Bild ist gr\u00f6\u00dfer als 50 MB.','err');return;}\nimageEditFile=file;\ntry{imageEditDataUrl=await fileToDataUrl(file);renderImageEditPreview(file,imageEditDataUrl);showToast('Immobilienfoto geladen \u2713','success');}\ncatch(e){imageEditFile=null;imageEditDataUrl='';showToast('Bild konnte nicht gelesen werden.','err');}\nrenderListingImageGallery();\nupdateImageGenButtonMode();\n}\n\nfunction renderImageEditPreview(file,url){\nconst preview=document.getElementById('imgedit-preview');if(!preview)return;\nconst mb=(file.size\/1024\/1024).toFixed(1).replace('.',',');\npreview.style.display='grid';\npreview.innerHTML='<img decoding=\"async\" src=\"'+url+'\" alt=\"\"><div><div class=\"imgedit-preview-name\">'+escHtml(file.name||'Immobilienfoto')+'<\/div><div class=\"imgedit-preview-meta\">'+escHtml((file.type||'Bild').replace('image\/','').toUpperCase())+' \u00b7 '+mb+' MB \u00b7 Foto\u00fcberarbeitung aktiv<\/div><\/div><button type=\"button\" class=\"imggen-btn-sec\" onclick=\"removeImageEditFile()\">Entfernen<\/button>';\n}\n\nfunction removeImageEditFile(silent){\nimageEditFile=null;imageEditDataUrl='';\nconst input=document.getElementById('imgedit-file-input');if(input)input.value='';\nconst preview=document.getElementById('imgedit-preview');if(preview){preview.style.display='none';preview.innerHTML='';}\nrenderListingImageGallery();\nupdateImageGenButtonMode();\nif(!silent)showToast('Foto entfernt.');\n}\n\nfunction updateImageGenButtonMode(){\nconst btn=document.getElementById('imggen-generate-btn');if(!btn)return;\nif(imageEditFile)btn.textContent='\u2728 Foto \u00fcberarbeiten';\nelse if(getAutoListingEditFiles().length)btn.textContent='\u2728 Anzeigebilder \u00fcberarbeiten';\nelse btn.textContent='\ud83c\udfa8 Bilder generieren';\n}\n\nfunction initLogoUpload(){\nconst input=document.getElementById('img-logo-input');if(!input||input.dataset.bound)return;\ninput.dataset.bound='1';\ninput.addEventListener('change',e=>handleLogoFile(e.target.files&&e.target.files[0]));\nconst opacity=document.getElementById('img-logo-opacity');const size=document.getElementById('img-logo-size');\nif(opacity&&!opacity.dataset.bound){opacity.dataset.bound='1';opacity.addEventListener('input',()=>updateLogoRangeLabels());}\nif(size&&!size.dataset.bound){size.dataset.bound='1';size.addEventListener('input',()=>updateLogoRangeLabels());}\nupdateLogoRangeLabels();\n}\n\nasync function handleLogoFile(file){\nif(!file)return;\nif(!\/^image\\\/(png|jpe?g|webp)$\/i.test(file.type||'')){showToast('Bitte Logo als PNG, JPG oder WebP hochladen.','err');return;}\nif(file.size>10*1024*1024){showToast('Logo ist gr\u00f6\u00dfer als 10 MB.','err');return;}\nlogoFile=file;\ntry{logoDataUrl=await fileToDataUrl(file);renderLogoPreview(file,logoDataUrl);const saved=saveImageGenSettings(false);if(saved)showToast('Logo geladen und gespeichert \u2713','success');}\ncatch(e){logoFile=null;logoDataUrl='';showToast('Logo konnte nicht gelesen werden.','err');}\n}\n\nfunction renderLogoPreview(file,url){\nconst preview=document.getElementById('img-logo-preview');if(!preview)return;\npreview.style.display='flex';\npreview.innerHTML='<img decoding=\"async\" src=\"'+url+'\" alt=\"\"><div style=\"flex:1;\"><div class=\"imglogo-name\">'+escHtml(file.name||'Logo')+'<\/div><div class=\"imgedit-preview-meta\">Logo wird in neue Bilder eingezeichnet<\/div><\/div><button type=\"button\" class=\"imggen-btn-sec\" onclick=\"removeLogoFile()\">Entfernen<\/button>';\n}\n\nfunction removeLogoFile(){\nlogoFile=null;logoDataUrl='';\nconst input=document.getElementById('img-logo-input');if(input)input.value='';\nconst preview=document.getElementById('img-logo-preview');if(preview){preview.style.display='none';preview.innerHTML='';}\nsaveImageGenSettings(true);\nshowToast('Logo entfernt.');\n}\n\nfunction updateLogoRangeLabels(){\nconst opacity=document.getElementById('img-logo-opacity');const size=document.getElementById('img-logo-size');\nconst ol=document.getElementById('img-logo-opacity-label');const sl=document.getElementById('img-logo-size-label');\nif(opacity&&ol)ol.textContent=opacity.value+'%';\nif(size&&sl)sl.textContent=size.value+'%';\n}\n\nfunction getLogoOverlaySettings(){\nif(!logoDataUrl)return null;\nconst opacity=document.getElementById('img-logo-opacity');const size=document.getElementById('img-logo-size');const pos=document.getElementById('img-logo-position');\nreturn{url:logoDataUrl,opacity:Math.max(0.1,Math.min(1,Number(opacity?opacity.value:80)\/100)),size:Math.max(0.06,Math.min(0.36,Number(size?size.value:14)\/100)),position:pos?pos.value:'top-right'};\n}\n\nfunction getImageEditDirectives(){\nreturn Array.from(document.querySelectorAll('#imgedit-sliders input[type=\"checkbox\"]')).map(input=>{\nconst cfg=IMAGE_EDIT_CONTROLS[input.dataset.editKey]||{};\nreturn{key:input.dataset.editKey,label:cfg.label||input.dataset.editKey,prompt:cfg.prompt||'',enabled:!!input.checked,strength:input.checked?100:0};\n}).filter(item=>item.enabled);\n}\n\nfunction showImgGenError(msg){\nconst errEl=document.getElementById('imggen-error');\nif(errEl){errEl.textContent=msg;errEl.style.display='block';}\nshowToast(msg,'err');\n}\n\nasync function generateImages(isRegen){\nconst oaiKey=localStorage.getItem('li_openai_key');\nif(!oaiKey){showImgGenError('Bildgenerierung ben\u00f6tigt einen OpenAI API-Key mit Zugriff auf GPT Image. Bitte oben unter ChatGPT verbinden.');return;}\nif(!extractedData){showToast('Zuerst Expos\u00e9 analysieren.','err');return;}\nsaveImageGenSettings(true);\nconst genBtn=document.getElementById('imggen-generate-btn');\nconst regenBtn=document.getElementById('imggen-regen-btn');\nconst grid=document.getElementById('imggen-grid');\nconst errEl=document.getElementById('imggen-error');\nconst autoEditFiles=getAutoListingEditFiles();\nconst editFiles=imageEditFile?[imageEditFile]:autoEditFiles;\nconst editMode=editFiles.length>0;\nconst editDirectives=getImageEditDirectives();\nif(errEl)errEl.style.display='none';\ngenBtn.disabled=true;genBtn.textContent=editMode?'\u23f3 \u00dcberarbeite...':'\u23f3 Generiere...';\ngrid.innerHTML='<div class=\"imggen-img-wrap\"><div class=\"imggen-loading\"><div class=\"imggen-spin\"><\/div><div style=\"font-size:9px;letter-spacing:1px;text-transform:uppercase;color:var(--text-muted);\">'+(editMode?'Foto-Variante 1...':'Bild 1...')+'<\/div><\/div><\/div><div class=\"imggen-img-wrap\"><div class=\"imggen-loading\"><div class=\"imggen-spin\"><\/div><div style=\"font-size:9px;letter-spacing:1px;text-transform:uppercase;color:var(--text-muted);\">'+(editMode?'Foto-Variante 2...':'Bild 2...')+'<\/div><\/div><\/div>';\nconst style=document.getElementById('img-style-select')?document.getElementById('img-style-select').value:'luxury real estate photography, golden hour';\nconst overlayText=document.getElementById('img-overlay-text')?document.getElementById('img-overlay-text').value:'';\nconst fontFamily=document.getElementById('img-font-select')?document.getElementById('img-font-select').value:'Cormorant Garamond, serif';\nconst fontSize=document.getElementById('img-fontsize-select')?document.getElementById('img-fontsize-select').value:'medium';\nconst textPosition=document.getElementById('img-text-position-select')?document.getElementById('img-text-position-select').value:'middle';\nconst textColor=document.getElementById('img-text-color')?document.getElementById('img-text-color').value:'#bb9e1c';\nconst logoSettings=getLogoOverlaySettings();\nconst obj=extractedData;\nconst variation=isRegen?('Variation '+Math.floor(Math.random()*1000)+'. '):'';\nconst prompts=editMode?[\nbuildImageEditPrompt('Variante 1',style,editDirectives,variation),\nbuildImageEditPrompt('Variante 2',style,editDirectives,variation)\n]:[\nvariation+'Professional real estate investment advertisement image. '+style+'. Property: '+(obj.art||'building')+' in '+(obj.standort||'Germany')+'. Premium luxury brand photography, cinematic composition, dramatic lighting. Gold and white color palette. No text, no watermarks, photorealistic, high-end marketing visual.',\nvariation+'Aerial or architectural showcase of '+(obj.art||'real estate')+' investment property. '+style+'. Location: '+(obj.standort||'Germany')+'. Modern premium real estate marketing visual, wide angle, golden hour light, sophisticated aesthetic. Gold and neutral tones. No text, photorealistic.'\n];\ngeneratedImageUrls=[];\nconst results=await Promise.all(prompts.map((pr,i)=>{\nif(!editMode)return generateSingleImage(pr,i,oaiKey);\nconst baseFile=editFiles[i]||editFiles[0];\nreturn editSingleImage(baseFile,pr,i,oaiKey);\n}));\ngrid.innerHTML=results.map((result,i)=>{\nif(result.error)return '<div class=\"imggen-img-wrap\"><div class=\"imggen-placeholder\"><div style=\"font-size:11px;color:#c0392b;padding:12px;text-align:center;\">'+escHtml(result.error)+'<\/div><\/div><\/div>';\nreturn '<div class=\"imggen-img-wrap\" id=\"img-wrap-'+i+'\"><canvas id=\"canvas-'+i+'\" style=\"width:100%;height:100%;display:block;cursor:pointer;\" onclick=\"downloadCanvas('+i+')\"><\/canvas><div class=\"imggen-img-label\">'+(editMode?'Bearbeitung ':'Variante ')+(i+1)+' \u00b7 Klicken zum Herunterladen<\/div><div class=\"imggen-img-actions\"><button class=\"imggen-img-btn\" onclick=\"downloadCanvas('+i+')\">\u2193 Download<\/button><button class=\"imggen-img-btn\" onclick=\"copyImageToClipboard('+i+')\">\ud83d\udccb Kopieren<\/button><\/div><\/div>';\n}).join('');\nresults.forEach((result,i)=>{if(result.error)return;let src=null;if(result.b64)src='data:image\/png;base64,'+result.b64;else if(result.url)src=result.url;if(src){generatedImageUrls[i]=src;drawImageWithOverlay(i,src,overlayText,fontFamily,fontSize,textColor,textPosition,logoSettings);}});\ngenBtn.disabled=false;updateImageGenButtonMode();regenBtn.style.display='inline-flex';\n}\n\nfunction buildImageEditPrompt(variant,style,directives,variation){\nconst obj=extractedData||{};\nconst directiveText=directives.length?directives.map(d=>'- '+d.label+': JA. '+d.prompt+'.').join('\\n'):'- Keine Zusatz-Bearbeitung aktiviert: optimiere das Foto nur dezent fuer eine hochwertige Immobilienanzeige, mit natuerlicher Belichtung, sauberer Komposition und realistischem Premium-Look. Veraendere keine sensiblen Details gezielt.';\nconst variantTone=variant==='Variante 2'?'Create a second, slightly more polished premium advertising interpretation while keeping the photo realistic and the same property recognizable.':'Create a clean, realistic real estate marketing edit that stays close to the original photo.';\nreturn variation+\n'Edit the provided real estate photo for a premium Lima Invest Immobilien advertisement.\\n'+\n'Preserve the real property, architecture, room or facade layout, window and door positions, materials, proportions and spatial truth. Do not invent renovations, extra floors, different buildings or unrealistic luxury elements.\\n'+\n'Requested editing controls:\\n'+directiveText+'\\n'+\nvariantTone+'\\n'+\n'Style direction: '+style+'. Photorealistic, high-end real estate photography, natural colors, clean composition, no text, no watermarks, no added logos, no fake signs.\\n'+\n'Property context: '+(obj.art||'real estate property')+' in '+(obj.standort||'Germany')+'. '+(obj.beschreibung||'')+'\\n'+\n'If a requested item is not visible, do not add it. Leave the image natural and coherent.';\n}\n\nasync function editSingleImage(file,prompt,index,key){\nconst imageModels=['gpt-image-1.5','gpt-image-1','gpt-image-1-mini'];\nlet lastError='Foto konnte nicht \u00fcberarbeitet werden.';\nfor(const model of imageModels){\ntry{\nconst form=new FormData();\nform.append('model',model);\nform.append('image',file,file.name||'immobilienfoto.png');\nform.append('prompt',prompt);\nform.append('n','1');\nform.append('size','1024x1024');\nform.append('quality','medium');\nform.append('output_format','png');\nform.append('input_fidelity','high');\nconst res=await fetch('https:\/\/api.openai.com\/v1\/images\/edits',{method:'POST',headers:{'Authorization':'Bearer '+key},body:form});\nif(!res.ok){\nlet msg='Fehler '+res.status;\ntry{const err=await res.json();if(err.error){if(err.error.code==='invalid_api_key')return{error:'OpenAI API-Key ung\u00fcltig oder ohne Bild-Berechtigung.'};msg=err.error.message||msg;}}catch(e){}\nlastError=msg;\nif(\/does not exist|model_not_found|not found|unsupported\/i.test(msg))continue;\nif(\/input_fidelity|unknown parameter\/i.test(msg))return await editSingleImageWithoutFidelity(file,prompt,key,model);\nreturn{error:msg};\n}\nconst d=await res.json();\nconst item=d.data&&d.data[0];\nif(!item)return{error:'Keine Bilddaten erhalten.'};\nif(item.b64_json)return{b64:item.b64_json};\nif(item.url)return{url:item.url};\nreturn{error:'Unbekanntes Bildformat.'};\n}catch(e){\nlastError='Netzwerkfehler bei der Foto\u00fcberarbeitung. Bitte API-Key und Verbindung pr\u00fcfen.';\n}\n}\nreturn{error:lastError};\n}\n\nasync function editSingleImageWithoutFidelity(file,prompt,key,model){\nconst form=new FormData();\nform.append('model',model);\nform.append('image',file,file.name||'immobilienfoto.png');\nform.append('prompt',prompt);\nform.append('n','1');\nform.append('size','1024x1024');\nform.append('quality','medium');\nform.append('output_format','png');\nconst res=await fetch('https:\/\/api.openai.com\/v1\/images\/edits',{method:'POST',headers:{'Authorization':'Bearer '+key},body:form});\nif(!res.ok){let msg='Fehler '+res.status;try{const err=await res.json();if(err.error)msg=err.error.message||msg;}catch(e){}return{error:msg};}\nconst d=await res.json();const item=d.data&&d.data[0];\nif(!item)return{error:'Keine Bilddaten erhalten.'};\nif(item.b64_json)return{b64:item.b64_json};\nif(item.url)return{url:item.url};\nreturn{error:'Unbekanntes Bildformat.'};\n}\n\nasync function generateSingleImage(prompt,index,key){\nconst imageModels=['gpt-image-1.5','gpt-image-1','gpt-image-1-mini'];\nlet lastError='Bild konnte nicht generiert werden.';\nfor(const model of imageModels){\ntry{\nconst res=await fetch('https:\/\/api.openai.com\/v1\/images\/generations',{\nmethod:'POST',\nheaders:{'Content-Type':'application\/json','Authorization':'Bearer '+key},\nbody:JSON.stringify({model:model,prompt:prompt,n:1,size:'1024x1024',quality:'medium',output_format:'png'})\n});\nif(!res.ok){\nlet msg='Fehler '+res.status;\ntry{const err=await res.json();if(err.error){if(err.error.code==='invalid_api_key')return{error:'OpenAI API-Key ung\u00fcltig oder ohne Bild-Berechtigung.'};msg=err.error.message||msg;}}catch(e){}\nlastError=msg;\nif(\/does not exist|model_not_found|not found|unsupported\/i.test(msg))continue;\nreturn{error:msg};\n}\nconst d=await res.json();\nconst item=d.data&&d.data[0];\nif(!item)return{error:'Keine Bilddaten erhalten.'};\nif(item.b64_json)return{b64:item.b64_json};\nif(item.url)return{url:item.url};\nreturn{error:'Unbekanntes Bildformat.'};\n}catch(e){\nlastError='Netzwerkfehler bei der Bildgenerierung. Bitte API-Key und Verbindung pr\u00fcfen.';\n}\n}\nreturn{error:lastError};\n}\n\nfunction drawImageWithOverlay(index,imageUrl,overlayText,fontFamily,fontSize,textColor,textPosition,logoSettings){\nconst canvas=document.getElementById('canvas-'+index);if(!canvas)return;\nconst ctx=canvas.getContext('2d');const img=new Image();\nif(imageUrl.indexOf('http')===0)img.crossOrigin='anonymous';\nimg.onload=()=>{\ncanvas.width=img.width;canvas.height=img.height;ctx.drawImage(img,0,0);\ndrawTextOverlay(ctx,img,overlayText,fontFamily,fontSize,textColor,textPosition||'bottom');\nif(logoSettings&&logoSettings.url)drawLogoOverlay(ctx,img,logoSettings);\n};\nimg.onerror=()=>{canvas.parentElement.innerHTML='<div class=\"imggen-placeholder\"><div style=\"font-size:10px;color:var(--text-muted);padding:12px;\">Bild konnte nicht gerendert werden.<\/div><\/div>';};\nimg.src=imageUrl;\n}\n\nfunction wrapCanvasText(ctx,text,maxWidth){\nconst words=String(text||'').split(\/\\s+\/).filter(Boolean);const lines=[];let line='';\nwords.forEach(word=>{const test=line?line+' '+word:word;if(ctx.measureText(test).width<=maxWidth)line=test;else{if(line)lines.push(line);line=word;}});\nif(line)lines.push(line);return lines.length?lines:[''];\n}\n\nfunction drawTextOverlay(ctx,img,overlayText,fontFamily,fontSize,textColor,textPosition){\nif(overlayText&&overlayText.trim()){\nconst sizeMap={small:Math.round(img.width*0.04),medium:Math.round(img.width*0.055),large:Math.round(img.width*0.075)};\nconst fs=sizeMap[fontSize]||sizeMap.medium;const brandFs=Math.round(fs*0.48);const pad=Math.round(img.width*0.04);\nctx.font='600 '+fs+'px '+fontFamily;const lines=wrapCanvasText(ctx,overlayText,img.width-pad*2).slice(0,3);\nconst textH=lines.length*fs*1.15;const blockH=brandFs*1.3+textH+pad*0.9;\nlet y=textPosition==='top'?pad:(textPosition==='middle'?Math.round((img.height-blockH)\/2):img.height-blockH-pad);\ny=Math.max(pad,Math.min(y,img.height-blockH-pad));\nctx.fillStyle='rgba(0,0,0,0.45)';ctx.fillRect(0,y-pad*0.45,img.width,blockH+pad*0.9);\nctx.textAlign='center';ctx.textBaseline='alphabetic';\nctx.font='300 '+brandFs+'px '+fontFamily;ctx.fillStyle='rgba(255,255,255,0.72)';ctx.fillText('LIMA INVEST IMMOBILIEN',img.width\/2,y+brandFs);\nctx.font='600 '+fs+'px '+fontFamily;ctx.fillStyle=textColor;\nlines.forEach((line,i)=>ctx.fillText(line,img.width\/2,y+brandFs+fs*1.18+(i*fs*1.15)));\nctx.textAlign='start';\n}else{\nconst fs=Math.round(img.width*0.032);ctx.fillStyle='rgba(0,0,0,0.4)';ctx.fillRect(0,img.height-fs*2.5,img.width,fs*2.5);\nctx.textAlign='center';ctx.font='300 '+fs+'px '+fontFamily;ctx.fillStyle='rgba(255,255,255,0.75)';ctx.fillText('LIMA INVEST IMMOBILIEN',img.width\/2,img.height-fs*0.7);ctx.textAlign='start';\n}\n}\n\nfunction drawLogoOverlay(ctx,img,settings){\nconst logo=new Image();\nlogo.onload=()=>{\nconst margin=Math.round(img.width*0.035);const targetW=Math.round(img.width*settings.size);const targetH=Math.round(targetW*(logo.height\/logo.width));let x=margin,y=margin;\nif(settings.position.indexOf('right')>-1)x=img.width-targetW-margin;else if(settings.position.indexOf('center')>-1)x=Math.round((img.width-targetW)\/2);\nif(settings.position.indexOf('bottom')>-1)y=img.height-targetH-margin;else if(settings.position==='center')y=Math.round((img.height-targetH)\/2);\nctx.save();ctx.globalAlpha=settings.opacity;ctx.drawImage(logo,x,y,targetW,targetH);ctx.restore();\n};\nlogo.src=settings.url;\n}\n\nfunction downloadCanvas(index){const canvas=document.getElementById('canvas-'+index);if(canvas){try{const link=document.createElement('a');link.download='lima-invest-ad-'+(index+1)+'.jpg';link.href=canvas.toDataURL('image\/jpeg',0.95);link.click();}catch(e){if(generatedImageUrls[index])window.open(generatedImageUrls[index],'_blank');}}else if(generatedImageUrls[index])window.open(generatedImageUrls[index],'_blank');}\nfunction downloadGeneratedImages(){\nconst indexes=[0,1].filter(i=>document.getElementById('canvas-'+i)||generatedImageUrls[i]);\nif(!indexes.length){showToast('Noch keine Bilder generiert.','err');return;}\nindexes.forEach((i,pos)=>setTimeout(()=>downloadCanvas(i),pos*280));\nshowToast(indexes.length>1?'Beide Bilder werden heruntergeladen.':'Bild wird heruntergeladen.','success');\n}\nasync function copyImageToClipboard(index){const canvas=document.getElementById('canvas-'+index);if(!canvas)return;try{canvas.toBlob(async blob=>{await navigator.clipboard.write([new ClipboardItem({'image\/png':blob})]);showToast('Bild kopiert \u2713','success');});}catch(e){showToast('Kopieren nicht unterst\u00fctzt. Bitte Download nutzen.');}}\nfunction regenerateImages(){generateImages(true);}\n\n\/\/ ============================================================\n\/\/ API KEY MANAGER\n\/\/ ============================================================\nfunction selectProvider(provider){\ncurrentProvider=provider;\ndocument.querySelectorAll('.api-ptab').forEach(t=>t.classList.remove('active'));\ndocument.getElementById('tab-'+provider).classList.add('active');\nconst info=PROVIDER_INFO[provider];\ndocument.getElementById('api-key-input').placeholder=info.placeholder;\ndocument.getElementById('api-info-text').innerHTML=info.info;\nconst saved=localStorage.getItem(info.storageKey);\nif(saved){apiKey=saved;setConnectedUI(true);}else{apiKey='';setConnectedUI(false);}\n}\nfunction saveApiKey(){\nconst val=document.getElementById('api-key-input').value.trim();\nif(!val){showToast('Bitte einen API-Key eingeben.','err');return;}\nif(currentProvider==='anthropic'&&!val.startsWith('sk-ant')){showToast('Claude Keys beginnen mit sk-ant-...','err');return;}\nif(currentProvider==='openai'&&!val.startsWith('sk-')){showToast('OpenAI Keys beginnen mit sk-...','err');return;}\napiKey=val;localStorage.setItem(PROVIDER_INFO[currentProvider].storageKey,val);\ndocument.getElementById('api-key-input').value='';setConnectedUI(true);\nshowToast('API-Key gespeichert \u2713','success');\n}\nfunction clearApiKey(){apiKey='';localStorage.removeItem(PROVIDER_INFO[currentProvider].storageKey);setConnectedUI(false);showToast('API-Key entfernt.');}\nfunction setConnectedUI(connected){\nconst dot=document.getElementById('api-dot');const label=document.getElementById('api-status-label');\nconst connBar=document.getElementById('api-connected-bar');const badge=document.getElementById('connected-badge');\nconst clearBtn=document.getElementById('clear-btn');const genBtn=document.getElementById('generate-btn');const keyHint=document.getElementById('key-hint');\nif(connected){if(dot)dot.classList.add('connected');if(label)label.textContent='KI verbunden';if(connBar)connBar.classList.add('show');if(badge)badge.textContent=PROVIDER_INFO[currentProvider].badge;if(clearBtn)clearBtn.style.display='block';if(genBtn)genBtn.classList.remove('locked');if(keyHint)keyHint.classList.remove('show');}\nelse{if(dot)dot.classList.remove('connected');if(label)label.textContent='KI nicht verbunden';if(connBar)connBar.classList.remove('show');if(clearBtn)clearBtn.style.display='none';if(genBtn)genBtn.classList.add('locked');}\n}\nfunction getApiKey(){if(apiKey)return apiKey;const ant=localStorage.getItem('li_anthropic_key');if(ant){currentProvider='anthropic';return ant;}const oai=localStorage.getItem('li_openai_key');if(oai){currentProvider='openai';return oai;}return null;}\n\n\/\/ ============================================================\n\/\/ HELP ACCORDIONS\n\/\/ ============================================================\nfunction toggleApiHelp(){const sec=document.getElementById('api-help-section');const arrow=document.getElementById('api-help-arrow');const open=sec.classList.contains('collapsed');sec.classList.toggle('collapsed',!open);if(arrow)arrow.style.transform=open?'rotate(180deg)':'rotate(0deg)';}\nfunction toggleAcc(id){const el=document.getElementById(id);if(el)el.classList.toggle('open');}\n\n\/\/ ============================================================\n\/\/ ACCOUNTS GRID + CONNECT MODAL\n\/\/ ============================================================\nfunction renderAccountsGrid(){\nconst grid=document.getElementById('accounts-grid');if(!grid)return;\nconst order=['instagram','tiktok','facebook','linkedin','whatsapp','google','xtwitter','telegram'];\ngrid.innerHTML=order.map(p=>{\nconst cfg=PLATFORMS[p];\nif(!cfg)return '';\nconst conn=connectedAccounts[p];\nconst isConn=!!conn;\nconst isOAuth=!!(conn&&conn.source==='oauth');\nconst label=isConn?(conn.displayName||conn.handle||'Verbunden'):'Nicht verbunden';\nconst status=isConn?(isOAuth?'OAuth aktiv':'Lokal gespeichert'):'Getrennt';\nconst connectLabel=isConn?'\u2713 Verbunden \u00b7 Trennen':(platformSupportsOAuth(p)?'\u26a1 OAuth verbinden':'+ Verbinden');\nreturn '<div class=\"account-card '+(isConn?'connected':'')+'\" id=\"ac-'+p+'\"><div class=\"ac-top\"><div class=\"ac-icon\">'+cfg.icon+'<\/div><div><div class=\"ac-name\">'+cfg.name+'<\/div><div class=\"ac-handle\">'+escHtml(label)+'<\/div><\/div><\/div><div class=\"ac-status '+(isConn?'connected':'disconnected')+'\"><span class=\"dot\"><\/span><span>'+status+'<\/span><\/div><button class=\"ac-btn '+(isConn?'connected-btn':'')+'\" onclick=\"'+(isConn?'disconnectAccount(\\''+p+'\\')':'openConnectModal(\\''+p+'\\')')+'\">'+connectLabel+'<\/button><\/div>';\n}).join('');\n}\nfunction openConnectModal(platform){\nconst cfg=PLATFORMS[platform];const info=CONNECT_INFO[platform]||{title:cfg.name+' verbinden',note:''};\nconst modal=document.getElementById('modal-content');if(!modal)return;\nconst base=getSocialApiBase();\nconst oauthBlock=platformSupportsOAuth(platform)?'<div class=\"modal-info\"><strong>Echt-Verbindung:<\/strong> OAuth l\u00e4uft \u00fcber dein Backend. Danach sind Direkt-Posts aus dem Tool m\u00f6glich.<\/div><div class=\"modal-field\"><label>Social Backend URL<\/label><input class=\"modal-input\" id=\"social-api-base-input\" value=\"'+escAttr(base)+'\" placeholder=\"http:\/\/localhost:8787\" autocomplete=\"off\"><\/div><div class=\"modal-actions\"><button class=\"modal-btn-primary\" onclick=\"startOAuthConnection(\\''+platform+'\\')\">OAuth starten<\/button><button class=\"modal-btn-secondary\" onclick=\"closeModal()\">Abbrechen<\/button><\/div>':'';\nconst manualBlock='<div class=\"modal-info\"><strong>Fallback:<\/strong> Nur lokale Markierung ohne API-Verbindung.<\/div><div class=\"modal-field\"><label>Handle \/ Benutzername<\/label><input class=\"modal-input\" id=\"modal-handle\" placeholder=\"@deinname\" autocomplete=\"off\"><\/div><div class=\"modal-actions\"><button class=\"modal-btn-secondary\" onclick=\"saveConnection(\\''+platform+'\\')\">Nur lokal speichern<\/button><\/div>';\nmodal.innerHTML='<div class=\"modal-platform-icon\">'+cfg.icon+'<\/div><div class=\"modal-title\">'+info.title+'<\/div><div class=\"modal-sub\">'+info.note+'<\/div>'+oauthBlock+manualBlock;\ndocument.getElementById('oauth-modal').classList.add('show');\nsetTimeout(()=>{const m=document.querySelector('.modal-input');if(m)m.focus();},100);\n}\nasync function startOAuthConnection(platform){\ntry{\nconst input=document.getElementById('social-api-base-input');\nif(input&&input.value)setSocialApiBase(input.value);\nconst resp=await socialRequest('\/v1\/social\/connect\/start',{method:'POST',body:{platform:platform}});\nif(!resp.authorizationUrl||!resp.state)throw new Error('Ung\u00fcltige OAuth-Startantwort vom Backend.');\nconst popup=window.open(resp.authorizationUrl,'oauth_'+platform,'width=640,height=780,noopener');\nif(!popup)showToast('Popup blockiert. Bitte Popups erlauben.','err');\nshowToast('OAuth gestartet: '+(PLATFORMS[platform]&&PLATFORMS[platform].name?PLATFORMS[platform].name:platform),'success');\nawait waitForConnectResult(platform,resp.state);\nawait syncConnectionsFromServer(true);\ncloseModal();\nif(generatedAds)renderAds(generatedAds,getSelectedPlatforms());\nshowToast(PLATFORMS[platform].name+' verbunden \u2713','success');\ntry{if(popup&&!popup.closed)popup.close();}catch(e){}\n}catch(err){\nshowToast('Verbindung fehlgeschlagen: '+err.message,'err');\n}\n}\nfunction saveConnection(platform){\nconst handleEl=document.getElementById('modal-handle');\nconst handle=handleEl?handleEl.value.trim():'';\nif(!handle){showToast('Bitte ein Handle eingeben.','err');return;}\nconnectedAccounts[platform]={handle:handle,displayName:handle,source:'manual',connectedAt:new Date().toISOString()};\npersistConnectedAccounts();\ncloseModal();\nrenderAccountsGrid();\nshowToast(PLATFORMS[platform].name+' lokal gespeichert.','success');\nif(generatedAds)renderAds(generatedAds,getSelectedPlatforms());\n}\nasync function disconnectAccount(platform){\ntry{\nif(isOAuthConnected(platform)){\nawait socialRequest('\/v1\/social\/connect\/disconnect',{method:'POST',body:{platform:platform}});\n}\ndelete connectedAccounts[platform];\npersistConnectedAccounts();\nrenderAccountsGrid();\nshowToast(PLATFORMS[platform].name+' getrennt.','success');\nif(generatedAds)renderAds(generatedAds,getSelectedPlatforms());\n}catch(err){\nshowToast('Trennen fehlgeschlagen: '+err.message,'err');\n}\n}\nfunction closeModal(){const m=document.getElementById('oauth-modal');if(m)m.classList.remove('show');}\nfunction postToLinkedIn(p){openPostingApp(p||'linkedin');}\nfunction postToGoogle(p){openPostingApp(p||'google');}\n\n\/\/ ============================================================\n\/\/ INIT\n\/\/ ============================================================\nfunction initHeroVideo(){\nconst video=document.querySelector('#lima-ad-gen .hero-video');if(!video)return;\nvideo.muted=true;video.loop=true;video.playsInline=true;\nconst start=()=>{const p=video.play();if(p&&typeof p.catch==='function')p.catch(()=>{});};\nif(video.readyState>=2)start();else video.addEventListener('loadeddata',start,{once:true});\ndocument.addEventListener('visibilitychange',()=>{if(!document.hidden&&video.paused)start();});\n}\nfunction limaInit(){\ntry{initHeroVideo();}catch(e){console.warn('initHeroVideo',e);}\ntry{initImageEditUpload();}catch(e){console.warn('initImageEditUpload',e);}\ntry{initLogoUpload();}catch(e){console.warn('initLogoUpload',e);}\ntry{restoreImageGenSettings();initImageGenSettingsPersistence();}catch(e){console.warn('restoreImageGenSettings',e);}\ntry{renderAccountsGrid();}catch(e){console.warn('renderAccountsGrid',e);}\ntry{syncConnectionsFromServer(true);}catch(e){console.warn('syncConnectionsFromServer',e);}\ntry{setupDropZone();}catch(e){console.warn('setupDropZone',e);}\nconst antKey=localStorage.getItem('li_anthropic_key');const oaiKey=localStorage.getItem('li_openai_key');\nif(antKey){currentProvider='anthropic';apiKey=antKey;setConnectedUI(true);}\nelse if(oaiKey){currentProvider='openai';apiKey=oaiKey;const to=document.getElementById('tab-openai');const ta=document.getElementById('tab-anthropic');if(to)to.classList.add('active');if(ta)ta.classList.remove('active');setConnectedUI(true);}\nelse setConnectedUI(false);\nconst ki=document.getElementById('api-key-input');if(ki)ki.addEventListener('keydown',e=>{if(e.key==='Enter')saveApiKey();});\nconst ov=document.getElementById('oauth-modal');if(ov)ov.addEventListener('click',function(e){if(e.target===this)closeModal();});\nconst cp=document.getElementById('img-text-color');if(cp)cp.addEventListener('input',e=>{const lbl=document.getElementById('color-label');if(lbl)lbl.textContent=e.target.value;});\n}\nif(document.readyState==='loading'){document.addEventListener('DOMContentLoaded',limaInit);}else{limaInit();}\n\n<\/script>\n<\/body>\n<\/html>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-dab8fbe elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"dab8fbe\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-c5826f9\" data-id=\"c5826f9\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-13e2ace elementor-widget elementor-widget-html\" data-id=\"13e2ace\" 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     Lima Invest \u2013 White-Label CTA Banner (Variante 3)\n     Breit, minimale H\u00f6he, w\u00e4rmerer Hintergrund mit verblasster\n     Skyline-Silhouette (eingebettetes SVG, keine externen Bilder).\n     Kopieren und unterhalb des Tools einf\u00fcgen (WordPress \"Custom HTML\"-Block).\n     Styles sind gescopt (.li-cta3), kollidiert nicht mit dem Theme.\n============================================================ -->\n\n<div class=\"li-cta3\">\n  <style>\n    @import url('https:\/\/fonts.googleapis.com\/css2?family=Cormorant+Garamond:wght@500;600;700&family=Poppins:wght@300;400;500;600&display=swap');\n\n    .li-cta3 * { margin: 0; padding: 0; box-sizing: border-box; }\n\n    .li-cta3 {\n      --gold: #bb9e1c;\n      --gold-light: #e6c83a;\n      container-type: inline-size;\n      font-family: 'Poppins', system-ui, -apple-system, sans-serif;\n      max-width: 1180px;          \/* breit *\/\n      margin: 32px auto;\n    }\n\n    .li-cta3__card {\n      position: relative;\n      display: flex;\n      align-items: center;\n      justify-content: space-between;\n      gap: 28px;\n      padding: 18px 34px;          \/* minimale H\u00f6he *\/\n      border-radius: 14px;\n      border: 1px solid rgba(187,158,28,0.30);\n      overflow: hidden;\n      \/* w\u00e4rmerer Hintergrund + goldener \"Dusk\"-Schimmer am unteren Rand *\/\n      background:\n        radial-gradient(90% 160% at 50% 130%, rgba(187,158,28,0.22) 0%, rgba(187,158,28,0) 55%),\n        linear-gradient(135deg, #1c1813 0%, #262129 55%, #1a1d24 100%);\n      box-shadow: 0 18px 44px -24px rgba(0,0,0,0.6);\n    }\n\n    \/* verblasste Skyline-Silhouette, am unteren Rand verankert *\/\n    .li-cta3__card::before {\n      content: \"\";\n      position: absolute;\n      left: 0; right: 0; bottom: 0;\n      height: 100%;\n      background-image: url(\"data:image\/svg+xml,%3Csvg%20xmlns='http:\/\/www.w3.org\/2000\/svg'%20width='1440'%20height='220'%20viewBox='0%200%201440%20220'%3E%3Cg%20fill='%23bb9e1c'%3E%3Crect%20x='0'%20y='100'%20width='90'%20height='120'\/%3E%3Crect%20x='90'%20y='50'%20width='70'%20height='170'\/%3E%3Crect%20x='160'%20y='125'%20width='110'%20height='95'\/%3E%3Crect%20x='270'%20y='20'%20width='80'%20height='200'\/%3E%3Crect%20x='350'%20y='80'%20width='95'%20height='140'\/%3E%3Crect%20x='445'%20y='35'%20width='120'%20height='185'\/%3E%3Crect%20x='565'%20y='110'%20width='85'%20height='110'\/%3E%3Crect%20x='650'%20y='15'%20width='130'%20height='205'\/%3E%3Crect%20x='780'%20y='70'%20width='90'%20height='150'\/%3E%3Crect%20x='870'%20y='30'%20width='110'%20height='190'\/%3E%3Crect%20x='980'%20y='95'%20width='95'%20height='125'\/%3E%3Crect%20x='1075'%20y='20'%20width='125'%20height='200'\/%3E%3Crect%20x='1200'%20y='60'%20width='90'%20height='160'\/%3E%3Crect%20x='1290'%20y='25'%20width='150'%20height='195'\/%3E%3C\/g%3E%3C\/svg%3E\");\n      background-repeat: no-repeat;\n      background-position: bottom center;\n      background-size: 100% auto;\n      opacity: 0.14;\n      \/* nach oben hin sanft ausblenden *\/\n      -webkit-mask-image: linear-gradient(to top, #000 0%, rgba(0,0,0,0.4) 55%, transparent 100%);\n              mask-image: linear-gradient(to top, #000 0%, rgba(0,0,0,0.4) 55%, transparent 100%);\n      pointer-events: none;\n    }\n\n    .li-cta3__text { position: relative; z-index: 1; }\n\n    .li-cta3__eyebrow {\n      display: block;\n      font-size: 11px;\n      font-weight: 500;\n      letter-spacing: 0.2em;\n      text-transform: uppercase;\n      color: var(--gold);\n      margin-bottom: 5px;\n    }\n\n    .li-cta3__title {\n      font-family: 'Cormorant Garamond', Georgia, serif;\n      font-weight: 600;\n      font-size: 24px;\n      line-height: 1.15;\n      color: #ffffff;\n    }\n    .li-cta3__title span { color: var(--gold); }\n\n    .li-cta3__btn {\n      position: relative;\n      z-index: 1;\n      flex-shrink: 0;\n      display: inline-flex;\n      align-items: center;\n      gap: 10px;\n      padding: 13px 28px;\n      border-radius: 9px;\n      background: var(--gold);\n      color: #1c1813;\n      font-family: 'Poppins', sans-serif;\n      font-size: 14px;\n      font-weight: 600;\n      text-decoration: none;\n      white-space: nowrap;\n      transition: transform 0.25s ease, background 0.25s ease, box-shadow 0.25s ease;\n      box-shadow: 0 10px 24px -12px rgba(187,158,28,0.6);\n    }\n    .li-cta3__btn svg {\n      width: 16px; height: 16px;\n      transition: transform 0.25s ease;\n    }\n    .li-cta3__btn:hover {\n      background: var(--gold-light);\n      transform: translateY(-2px);\n      box-shadow: 0 16px 30px -12px rgba(187,158,28,0.75);\n    }\n    .li-cta3__btn:hover svg { transform: translateX(4px); }\n\n    \/* schmale Container (Elementor-Spalten): sauber stapeln *\/\n    @container (max-width: 640px) {\n      .li-cta3__card {\n        flex-direction: column;\n        align-items: flex-start;\n        text-align: left;\n        gap: 16px;\n        padding: 22px 24px;\n      }\n      .li-cta3__btn { width: 100%; justify-content: center; }\n    }\n  <\/style>\n\n  <div class=\"li-cta3__card\">\n    <div class=\"li-cta3__text\">\n      <span class=\"li-cta3__eyebrow\">White-Label f\u00fcr Ihr Unternehmen<\/span>\n      <h3 class=\"li-cta3__title\">Dieses Tool mit <span>Ihrer eigenen Marke<\/span><\/h3>\n    <\/div>\n\n    <a class=\"li-cta3__btn\" href=\"https:\/\/limainvestimmobilien.de\/shop-fuer-immobilienmakler-immobilienakteure-leadgeneratoren\/\" target=\"_blank\" rel=\"noopener\">\n      Zum Shop\n      <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\"\n           stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n        <path d=\"M5 12h14M13 6l6 6-6 6\"\/>\n      <\/svg>\n    <\/a>\n  <\/div>\n<\/div>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Lima Invest \u00b7 Ad Generator Pro KI nicht verbunden \ud83e\udd16 Claude \u2726 ChatGPT Anleitung \u25be Verbinden Trennen Claude Key: console.anthropic.com \u2726 ChatGPT \/ OpenAI API Key \u25be 1Gehe auf platform.openai.com 2Mit deinem OpenAI\/ChatGPT-Konto einloggen 3Bereich API Keys \u00f6ffnen 4Auf Create new secret key klicken 5Key sofort kopieren und sicher abspeichern \u26a0 Wichtig: Der Key wird&#8230;<\/p>","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_kad_post_transparent":"","_kad_post_title":"hide","_kad_post_layout":"fullwidth","_kad_post_sidebar_id":"","_kad_post_content_style":"unboxed","_kad_post_vertical_padding":"hide","_kad_post_feature":"hide","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","footnotes":""},"class_list":["post-23242","page","type-page","status-publish","hentry"],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/limainvestimmobilien.de\/en\/wp-json\/wp\/v2\/pages\/23242","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/limainvestimmobilien.de\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/limainvestimmobilien.de\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/limainvestimmobilien.de\/en\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/limainvestimmobilien.de\/en\/wp-json\/wp\/v2\/comments?post=23242"}],"version-history":[{"count":10,"href":"https:\/\/limainvestimmobilien.de\/en\/wp-json\/wp\/v2\/pages\/23242\/revisions"}],"predecessor-version":[{"id":23413,"href":"https:\/\/limainvestimmobilien.de\/en\/wp-json\/wp\/v2\/pages\/23242\/revisions\/23413"}],"wp:attachment":[{"href":"https:\/\/limainvestimmobilien.de\/en\/wp-json\/wp\/v2\/media?parent=23242"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}