{"id":4842,"date":"2026-04-27T13:09:13","date_gmt":"2026-04-27T13:09:13","guid":{"rendered":"https:\/\/sofapiano.com\/membership-login\/"},"modified":"2026-11-05T01:24:50","modified_gmt":"2026-11-05T01:24:50","slug":"membership-login","status":"publish","type":"page","link":"https:\/\/sofapiano.com\/es\/membership-login\/","title":{"rendered":"MyLogIn"},"content":{"rendered":"\n<span hidden data-spx-mark=\"head-start\"><\/span>\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n<link rel=\"stylesheet\" href=\"https:\/\/fonts.googleapis.com\/css2?family=Fraunces:ital,opsz,wght@0,9..144,400;0,9..144,600;1,9..144,400;1,9..144,500&#038;family=Inter:wght@400;500;600;700;800&#038;display=swap\">\n<style>\n\/* ===== SPX Design: Grundlagen (gilt f\u00fcr alle neuen Seiten) ===== *\/\n#masthead,#colophon,.elementor-location-header,.elementor-location-footer,.page-header,.entry-title{display:none!important}\n\/* Wei\u00dfe Theme-Fu\u00dfzeile (Hello: Footer-Men\u00fc + \u201eAlle Rechte vorbehalten\u201c) ausblenden \u2013 die Legal-Zeile steht schon im Petrol-Footer *\/\n#site-footer:not(:has(.spx-foot)),footer.site-footer:not(.spx-foot):not(:has(.spx-foot)){display:none!important}\n\/* Theme-Kopf (Logo + Seitentitel + Untertitel) ausblenden \u2013 das SPX-Men\u00fc steht schon oben *\/\n#site-header:not(:has(.spx-top)),header.site-header:not(:has(.spx-top)),.site-header .site-branding{display:none!important}\n.site-main,.page-content,main#content{padding:0!important;margin:0!important;max-width:none!important;width:auto!important}\nbody{background:#FBF8F2}\n.spx-page,.spx-foot{--ink:#1D2427;--dark:#0E1A20;--teal:#14708C;--sky:#6EC1E4;--sun:#FFCF33;--paper:#FBF8F2;--muted:#4B565A;--line:#EFEAE0;width:100vw;margin-left:calc(50% - 50vw);font-family:'Inter','Segoe UI',Roboto,Arial,sans-serif;font-size:16px;line-height:1.6;-webkit-font-smoothing:antialiased}\n.spx-page{background:var(--paper);color:var(--ink);min-height:60vh}\n.spx{--ink:#1D2427;--dark:#0E1A20;--teal:#14708C;--sky:#6EC1E4;--sun:#FFCF33;--paper:#FBF8F2;--muted:#4B565A;--line:#EFEAE0;font-family:'Inter','Segoe UI',Roboto,Arial,sans-serif}\n.spx *,.spx-page .pg *{box-sizing:border-box}\n.spx h1,.spx h2,.spx h3,.spx p,.spx ul,.spx ol{margin:0;padding:0}\n.spx ul,.spx ol{list-style:none}\n.spx a{color:var(--teal);text-decoration:none}\n.spx a:hover{color:#0E5367}\n.spx em{font-style:italic}\n.spx .wrap{max-width:1120px;margin:0 auto;padding:0 24px}\n.spx .btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;min-height:52px;padding:0 26px;border-radius:999px;font-weight:700;font-size:16px;border:none;cursor:pointer;font-family:inherit;text-decoration:none}\n.spx .b-teal{background:var(--teal);color:#fff}.spx .b-teal:hover{color:#fff;background:#0E5367}\n.spx .b-sun{background:var(--sun);color:var(--dark)}.spx .b-sun:hover{color:var(--dark);background:#FFD94F}\n.spx .b-ghost{background:#fff;color:var(--ink);box-shadow:inset 0 0 0 1.5px #D9D2C4}.spx .b-ghost:hover{color:var(--ink);box-shadow:inset 0 0 0 1.5px var(--ink)}\n\/* Seitenkopf *\/\n.spx .a1-head,.spx .pg-head{padding:116px 0 20px;text-align:center}\n.spx .pg-head{padding-bottom:34px}\n.spx .kicker{font-family:'Fraunces',Georgia,serif;font-style:italic;font-size:19px;color:var(--teal);margin-bottom:8px}\n.spx h1{font-family:'Fraunces',Georgia,serif;font-weight:600;font-size:clamp(1.9rem,3.6vw,2.9rem);line-height:1.1;letter-spacing:-1px;color:var(--ink);margin-bottom:14px}\n.spx .a1-head h1{font-size:clamp(1.7rem,3.2vw,2.5rem);margin-bottom:16px}\n.spx h1 em,.spx h2 em{font-weight:500;color:var(--teal)}\n.spx .a1-sub,.spx .sub{font-size:16.5px;line-height:1.55;color:var(--muted);max-width:620px;margin:-4px auto 6px}\n.spx .a1-sub{font-size:16px;max-width:560px;margin:-6px auto 6px}\n\/* \u00dcbungs-\/Tool-B\u00fchne *\/\n.a1-stage,.tool-stage{padding:6px 16px 80px;min-height:60vh}\n.tool-stage{max-width:1100px;margin:0 auto}\n\/* Inhaltsbereiche *\/\n.spx .sec{padding:56px 0}\n.spx .sec+.sec{border-top:1px solid var(--line)}\n.spx .sec-head{text-align:center;max-width:720px;margin:0 auto 32px}\n.spx h2{font-family:'Fraunces',Georgia,serif;font-weight:600;font-size:clamp(1.6rem,2.8vw,2.2rem);line-height:1.12;letter-spacing:-.6px;color:var(--ink);margin-bottom:10px}\n.spx h3{font-size:18px;font-weight:800;color:var(--ink);margin-bottom:6px;line-height:1.3}\n.spx .txt{font-size:16.5px;color:var(--muted)}\n.spx .cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:16px}\n.spx .card{display:flex;flex-direction:column;gap:6px;background:#fff;border-radius:22px;padding:24px;color:var(--ink);box-shadow:0 1px 2px rgba(29,36,39,.04),0 10px 26px rgba(29,36,39,.05)}\na.card:hover{color:var(--ink);box-shadow:inset 0 0 0 1.5px var(--teal),0 10px 26px rgba(29,36,39,.06)}\n.spx .card p{font-size:15px;color:var(--muted)}\n.spx .card .ic{display:flex;width:44px;height:44px;border-radius:13px;align-items:center;justify-content:center;color:var(--dark);margin-bottom:8px;font-size:20px}\n.spx .card .go{margin-top:auto;padding-top:8px;font-weight:700;font-size:14.5px;color:var(--teal)}\n.spx .tag{display:inline-block;font-size:11.5px;font-weight:800;letter-spacing:1.1px;color:var(--teal);text-transform:uppercase}\n\/* Flie\u00dftext (z.B. Rechtliches, Story) *\/\n.spx .prose{max-width:780px;margin:0 auto;background:#fff;border-radius:26px;padding:40px clamp(22px,5vw,56px);font-size:16px;line-height:1.75;color:#33403F;box-shadow:0 1px 2px rgba(29,36,39,.04),0 10px 26px rgba(29,36,39,.05)}\n.spx .prose h2{font-size:clamp(1.35rem,2.2vw,1.65rem);margin:34px 0 10px}\n.spx .prose h3{font-size:17px;margin:24px 0 6px}\n.spx .prose h4{font-size:15.5px;font-weight:800;margin:18px 0 4px}\n.spx .prose h2:first-child,.spx .prose h3:first-child{margin-top:0}\n.spx .prose p{margin:0 0 14px}\n.spx .prose ul,.spx .prose ol{margin:0 0 16px 22px;padding:0}\n.spx .prose ul{list-style:disc}.spx .prose ol{list-style:decimal}\n.spx .prose li{margin:0 0 6px}\n.spx .prose a{text-decoration:underline;text-underline-offset:2px}\n.spx .prose table{width:100%;border-collapse:collapse;margin:0 0 18px;font-size:14.5px}\n.spx .prose th,.spx .prose td{border:1px solid var(--line);padding:8px 10px;text-align:left;vertical-align:top}\n.spx .prose img{max-width:100%;height:auto;border-radius:16px}\n\/* FAQ *\/\n.spx .faq{max-width:780px;margin:0 auto;background:#fff;border-radius:24px;padding:6px 26px;box-shadow:0 1px 2px rgba(29,36,39,.04),0 10px 26px rgba(29,36,39,.05)}\n.spx .faq details{border-bottom:1px solid var(--line)}\n.spx .faq details:last-child{border-bottom:0}\n.spx .faq summary{display:flex;justify-content:space-between;align-items:center;gap:16px;padding:20px 0;cursor:pointer;list-style:none;font-size:17px;font-weight:700;color:var(--ink)}\n.spx .faq summary::-webkit-details-marker{display:none}\n.spx .faq summary::after{content:\"+\";flex-shrink:0;font-size:24px;font-weight:400;color:var(--teal);transition:transform .2s}\n.spx .faq details[open] summary::after{transform:rotate(45deg)}\n.spx .faq .a{padding:0 0 20px;font-size:15.5px;color:var(--muted);line-height:1.7}\n.spx .faq .a p{margin:0 0 10px}\n.spx .faq .a ul{list-style:disc;margin:0 0 10px 20px}\n\/* Anleitung \/ Info (ersetzt die alten Info-Popups) *\/\n.spx .howto{max-width:680px;margin:22px auto 0;background:#fff;border-radius:20px;padding:2px 22px;box-shadow:0 1px 2px rgba(29,36,39,.04),0 10px 26px rgba(29,36,39,.05)}\n.spx .howto summary{display:flex;align-items:center;gap:10px;padding:16px 0;cursor:pointer;list-style:none;font-size:15.5px;font-weight:700;color:var(--ink)}\n.spx .howto summary::-webkit-details-marker{display:none}\n.spx .howto summary::before{content:\"i\";display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:50%;background:var(--sky);color:var(--dark);font-family:'Fraunces',Georgia,serif;font-style:italic;font-weight:600;font-size:14px;flex-shrink:0}\n.spx .howto summary::after{content:\"+\";margin-left:auto;font-size:22px;font-weight:400;color:var(--teal);transition:transform .2s}\n.spx .howto[open] summary::after{transform:rotate(45deg)}\n.spx .howto .a{padding:0 0 18px;font-size:15px;line-height:1.7;color:var(--muted)}\n.spx .howto .a h3{font-size:16px;margin:4px 0 8px}\n.spx .howto .a p{margin:0 0 10px}\n.spx .howto .a ul,.spx .howto .a ol{margin:0 0 10px 20px}\n.spx .howto .a ul{list-style:disc}.spx .howto .a ol{list-style:decimal}\n.spx .howto .a li{margin:0 0 5px}\n.spx .howto .a li p{margin:0}\n\/* Preis-\/Mitgliedschaftskarte *\/\n.spx .plans{display:flex;flex-wrap:wrap;justify-content:center;gap:18px}\n.spx .plan{position:relative;width:100%;max-width:380px;background:#fff;border-radius:26px;padding:30px 28px;box-shadow:0 1px 2px rgba(29,36,39,.04),0 14px 34px rgba(29,36,39,.07);text-align:left}\n.spx .plan.hot{background:var(--dark);color:#DCE6E9}\n.spx .plan .pname{font-family:'Fraunces',Georgia,serif;font-size:28px;font-weight:600;color:var(--ink);margin:0 0 4px}\n.spx .plan.hot .pname{color:#fff}\n.spx .plan .price{font-size:20px;font-weight:800;color:var(--teal);margin:0 0 16px}\n.spx .plan.hot .price{color:var(--sun)}\n.spx .plan .note{font-size:13px;color:var(--muted);margin:10px 0 0}\n.spx .plan.hot .note{color:#9FB2BA}\n.spx .plan ul.feat{list-style:none;margin:18px 0 0;padding:16px 0 0;border-top:1px solid var(--line)}\n.spx .plan.hot ul.feat{border-top-color:#22363F}\n.spx .plan ul.feat li{position:relative;padding:0 0 0 28px;margin:0 0 10px;font-size:15.5px}\n.spx .plan ul.feat li::before{content:\"\u2713\";position:absolute;left:0;top:0;width:20px;height:20px;border-radius:50%;background:#E3F5FC;color:var(--teal);font-size:12px;font-weight:800;display:flex;align-items:center;justify-content:center}\n.spx .plan.hot ul.feat li::before{background:rgba(255,207,51,.18);color:var(--sun)}\n.spx .plan .buy input[type=submit],.spx .plan .buy button,.spx .plan .buy .swpm-payment-button input{display:inline-flex;align-items:center;justify-content:center;min-height:50px;padding:0 28px;border-radius:999px;border:0;background:var(--sun);color:var(--dark);font:inherit;font-weight:800;cursor:pointer}\n\/* Sprach-Tabs (Rechtstexte) *\/\n.spx .ltabs{max-width:780px;margin:0 auto}\n.spx .ltabs>input{position:absolute;opacity:0;pointer-events:none}\n.spx .ltabs .lt-bar{display:inline-flex;gap:4px;background:#fff;border-radius:999px;padding:5px;box-shadow:inset 0 0 0 1px #E5E0D6;margin:0 0 18px}\n.spx .ltabs .lt-bar label{cursor:pointer;padding:9px 18px;border-radius:999px;font-size:14px;font-weight:700;color:var(--muted)}\n.spx .ltabs .lt-p{display:none}\n.spx .ltabs #lt-en:checked~.lt-bar label[for=lt-en],.spx .ltabs #lt-de:checked~.lt-bar label[for=lt-de],.spx .ltabs #lt-es:checked~.lt-bar label[for=lt-es]{background:var(--dark);color:#fff}\n.spx .ltabs #lt-en:checked~.lt-panels .p-en,.spx .ltabs #lt-de:checked~.lt-panels .p-de,.spx .ltabs #lt-es:checked~.lt-panels .p-es{display:block}\n.spx .prose h1{font-family:'Fraunces',Georgia,serif;font-size:clamp(1.6rem,2.6vw,2rem);font-weight:600;margin:0 0 16px;letter-spacing:-.5px}\n.spx .prose hr{border:0;border-top:1px solid var(--line);margin:22px 0}\n\/* Formular-H\u00fclle f\u00fcr Plugins (Login, Registrierung, Kontakt) *\/\n.spx .form-card{max-width:560px;margin:0 auto;background:#fff;border-radius:26px;padding:34px clamp(20px,5vw,40px);box-shadow:0 1px 2px rgba(29,36,39,.04),0 10px 26px rgba(29,36,39,.05)}\n.spx .form-card input[type=text],.spx .form-card input[type=email],.spx .form-card input[type=password],.spx .form-card input[type=tel],.spx .form-card input[type=url],.spx .form-card textarea,.spx .form-card select{width:100%;min-height:48px;padding:10px 14px;border-radius:12px;border:1px solid #DDD6C9;background:#FBF8F2;font:inherit;color:var(--ink)}\n.spx .form-card textarea{min-height:130px}\n.spx .form-card input:focus,.spx .form-card textarea:focus,.spx .form-card select:focus{outline:none;border-color:var(--teal);background:#fff;box-shadow:0 0 0 3px rgba(20,112,140,.15)}\n.spx .form-card label{font-size:14px;font-weight:700;color:var(--ink)}\n.spx .form-card input[type=submit],.spx .form-card button[type=submit],.spx .form-card .swpm-login-form-submit{display:inline-flex;align-items:center;justify-content:center;min-height:50px;padding:0 28px;border-radius:999px;border:0;background:var(--teal);color:#fff;font:inherit;font-weight:700;cursor:pointer}\n.spx .form-card input[type=submit]:hover,.spx .form-card button[type=submit]:hover{background:#0E5367}\n\/* Footer *\/\n.spx-foot{background:var(--dark);color:#C9D6DB;margin-top:0}\n.spx-foot .fi{max-width:1120px;margin:0 auto;padding:56px 24px 28px;display:grid;grid-template-columns:1.4fr repeat(3,1fr);gap:32px}\n.spx-foot .logo{display:flex;align-items:center;gap:16px;font-family:'Fraunces',Georgia,serif;font-size:24px;font-weight:600;color:#fff;letter-spacing:-.3px;text-decoration:none;margin-bottom:12px}\n.spx-foot .logo-dot{width:11px;height:11px;border-radius:50%;background:var(--sun);box-shadow:7px 0 0 var(--sky)}\n.spx-foot .claim{font-size:15px;max-width:300px;color:#9FB2BA}\n.spx-foot .claim em{font-family:'Fraunces',Georgia,serif;color:#fff}\n.spx-foot h4{font-size:12px;font-weight:800;letter-spacing:1.4px;color:#6EC1E4;margin:0 0 14px;text-transform:uppercase}\n.spx-foot ul{list-style:none;margin:0;padding:0}\n.spx-foot li{margin:0 0 9px}\n.spx-foot a{color:#DCE6E9;text-decoration:none;font-size:15px}\n.spx-foot a:hover{color:#fff;text-decoration:underline}\n.spx-foot .fb{max-width:1120px;margin:0 auto;padding:18px 24px 30px;border-top:1px solid #22363F;display:flex;flex-wrap:wrap;justify-content:space-between;gap:10px;font-size:13.5px;color:#7F949C}\n.spx-foot .fb a{font-size:13.5px;color:#9FB2BA}\n@media (max-width:860px){.spx-foot .fi{grid-template-columns:1fr 1fr}.spx-foot .fi>div:first-child{grid-column:1\/-1}}\n@media (max-width:520px){.spx .sec{padding:40px 0}.spx .prose{border-radius:20px}}\n\/* ===== Men\u00fc: Inseln (aktiv) ===== *\/\n.spx .sr{position:absolute;width:1px;height:1px;opacity:0;margin:0;pointer-events:none}\nhtml:not(.spx-member) .spx .mb-only{display:none!important}\nhtml.spx-member .spx .g-only{display:none!important}\nhtml.spx-plus .spx .free-only{display:none!important}\n.spx .a1-head,.spx .pg-head{padding-top:132px}\n.spx .nav{position:fixed;top:18px;left:0;right:0;z-index:999;padding:0 16px}\n.admin-bar .spx .nav{top:50px}\n.spx .nav-in{position:relative;max-width:1200px;margin:0 auto;display:flex;align-items:center;gap:16px}\n.spx .isl{display:flex;align-items:center;gap:4px;height:60px;padding:0 8px;border-radius:999px;background:rgba(14,26,32,.8);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);box-shadow:0 10px 30px rgba(0,0,0,.18),inset 0 0 0 1px rgba(255,255,255,.12);color:#fff}\n.spx .logo{gap:16px;padding:0 26px;font-family:'Fraunces',Georgia,serif;font-size:22px;font-weight:600;letter-spacing:-.3px;color:#fff;white-space:nowrap}\n.spx .logo:hover{color:#fff}\n.spx .logo-dot{display:block;width:11px;height:11px;border-radius:50%;background:var(--sun);box-shadow:7px 0 0 var(--sky)}\n.spx .isl-nav{margin:0 auto}\n.spx .nl{display:inline-flex;align-items:center;gap:8px;height:44px;padding:0 18px;border-radius:999px;font-size:15.5px;font-weight:600;color:#E6F3F7;white-space:nowrap}\n.spx .nl:hover,.spx .dd:hover>.nl,.spx .dd:focus-within>.nl{background:rgba(255,255,255,.12);color:#fff}\n.spx .nl svg{transition:transform .2s}\n.spx .dd{position:relative}\n.spx .dd:hover>.nl svg,.spx .dd:focus-within>.nl svg{transform:rotate(180deg)}\n.spx .nav-in a:focus-visible,.spx .nav-in button:focus-visible,.spx .nav-in summary:focus-visible{outline:2px solid #fff;outline-offset:2px}\n.spx .panel{position:absolute;top:calc(100% + 18px);left:50%;transform:translate(-50%,8px);opacity:0;visibility:hidden;transition:opacity .18s,transform .18s,visibility .18s;background:#fff;color:var(--ink);border-radius:24px;padding:20px;box-shadow:0 24px 60px rgba(14,26,32,.28);z-index:5}\n.spx .panel::before{content:\"\";position:absolute;left:0;right:0;top:-22px;height:22px}\n.spx .dd:hover>.panel,.spx .dd:focus-within>.panel{opacity:1;visibility:visible;transform:translate(-50%,0)}\n.spx .mega{width:580px}\n.spx .pt{margin:0 0 12px;font-size:12px;font-weight:800;letter-spacing:1.3px;color:#6A7477}\n.spx .lvl-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px}\n.spx .lvl{display:flex;flex-direction:column;gap:2px;padding:14px;border-radius:16px;background:var(--c);color:var(--f,#0E1A20)}\n.spx .lvl b{font-family:'Fraunces',Georgia,serif;font-size:30px;font-weight:600;line-height:1}\n.spx .lvl small{margin-bottom:10px;font-size:12px;opacity:.85}\n.spx .lvl a{padding:3px 0;font-size:13px;font-weight:700;color:inherit}\n.spx .lvl a:hover{color:inherit;text-decoration:underline}\n.spx .panel-foot{display:flex;flex-wrap:wrap;justify-content:space-between;gap:8px 16px;margin-top:14px;padding-top:12px;border-top:1px solid var(--line);font-size:14px;font-weight:700}\n.spx .prac{width:420px}\n.spx .prac-row{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}\n.spx .prac-a{display:flex;flex-direction:column;gap:4px;padding:16px;border-radius:16px;background:#E3F5FC;color:var(--dark);font-weight:700}\n.spx .prac-a.g{background:var(--teal);color:#fff}\n.spx .prac-a:hover{color:inherit;opacity:.9}\n.spx .prac-a.g:hover{color:#fff}\n.spx .prac-a small{font-size:12.5px;font-weight:500;opacity:.85}\n.spx .tools-p{width:540px;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:4px}\n.spx .tl{display:grid;grid-template-columns:38px 1fr;column-gap:12px;align-items:center;padding:10px;border-radius:14px;color:var(--ink)}\n.spx .tl:hover{background:#F4F1EA;color:var(--ink)}\n.spx .tl i{grid-row:1 \/ span 2;display:flex;align-items:center;justify-content:center;width:38px;height:38px;border-radius:12px;background:var(--c);color:var(--dark)}\n.spx .tl b{display:block;font-size:14.5px;line-height:1.25}\n.spx .tl small{display:block;font-size:12.5px;color:#6A7477}\n.spx .m-only{display:none}\n.spx button.nl{background:none;border:0;margin:0;font-family:inherit;cursor:pointer}\n.spx .tl i{color:var(--f,#0E1A20);font-style:normal}\n.spx .tl i.lv{font-family:'Fraunces',Georgia,serif;font-size:15px;font-weight:600}\n.spx .tl .dk-tag{font-weight:700}\n.spx .ac-l{padding:8px 10px}\n.spx .ac-l svg{width:38px;height:38px;padding:10px;box-sizing:border-box;border-radius:12px;background:#E3F5FC;color:var(--dark)}\n.spx .ac-l.out svg{background:#F4F1EA;color:var(--muted)}\n.spx .more-p{width:280px;display:flex;flex-direction:column;gap:2px;padding:10px}\n.spx .mo{display:flex;flex-direction:column;gap:1px;padding:11px 14px;border-radius:14px;color:var(--ink)}\n.spx .mo:hover{background:#F4F1EA;color:var(--ink)}\n.spx .mo b{font-size:15px;font-weight:700}\n.spx .mo small{font-size:12.5px;color:#6A7477}\n.spx .isl-act{gap:6px;padding:0 8px 0 14px;flex-shrink:0}\n.spx .lang{padding:8px;font-size:13px;font-weight:700;color:#CFEFFB}\n.spx .lang:hover{color:#fff}\n.spx .login{display:inline-flex;align-items:center;height:44px;padding:0 14px;font-size:15.5px;font-weight:600;color:#fff;white-space:nowrap}\n.spx .login:hover{color:#fff}\n.spx .cta{display:inline-flex;align-items:center;height:44px;padding:0 22px;border-radius:999px;background:var(--sun);color:var(--dark);font-size:15.5px;font-weight:700;white-space:nowrap}\n.spx .cta:hover{background:#FFD94F;color:var(--dark)}\n.spx .lvp{position:relative}\n.spx .lvp>summary{display:flex;align-items:center;gap:8px;height:44px;padding:0 14px 0 16px;border-radius:999px;background:var(--sky);color:var(--dark);font-size:15px;font-weight:700;cursor:pointer;list-style:none;white-space:nowrap}\n.spx .lvp>summary::-webkit-details-marker{display:none}\n.spx .lvp>summary svg{transition:transform .2s}\n.spx .lvp[open]>summary svg{transform:rotate(180deg)}\n.spx .lvp .dk-tag:empty::after{content:\"?\"}\n.spx .lvp-p{position:absolute;right:0;top:calc(100% + 18px);z-index:6;width:310px;max-width:calc(100vw - 32px);padding:10px;border-radius:22px;background:#fff;color:var(--ink);box-shadow:0 24px 60px rgba(14,26,32,.3)}\n.spx .lvp-p .pt{padding:6px 12px 0}\n.spx .lvp-p button{all:unset;box-sizing:border-box;cursor:pointer;display:flex;align-items:center;gap:14px;width:100%;padding:10px 12px;border-radius:14px;font-family:inherit}\n.spx .lvp-p button:hover{background:#F7F4EE}\n.spx .lvp-p button[aria-pressed=true]{background:#F4F1EA;box-shadow:inset 0 0 0 1.5px var(--teal)}\n.spx .lv-ic{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:38px;height:38px;border-radius:12px;background:var(--c);color:var(--f,#0E1A20);font-family:'Fraunces',Georgia,serif;font-size:16px;font-weight:600}\n.spx .lv-t b{display:block;font-size:15px}\n.spx .lv-t small{display:block;font-size:13px;color:var(--muted)}\n.spx .lvp-p a{display:block;margin-top:6px;padding:12px;border-top:1px solid var(--line);font-size:14px;font-weight:700}\n.spx .gp{display:flex;align-items:center;gap:10px;height:44px;padding:0 14px 0 4px;border-radius:999px;color:#fff;--p:0;white-space:nowrap}\n.spx .gp:hover{background:rgba(255,255,255,.1);color:#fff}\n.spx .gp-ring{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:38px;height:38px;border-radius:50%;background:conic-gradient(var(--sun) calc(var(--p) * 1%),rgba(255,255,255,.2) 0)}\n.spx .gp-in{display:flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:50%;background:#1F3A44;font-size:12px;font-weight:800}\n.spx .gp-txt{display:flex;flex-direction:column;line-height:1.15}\n.spx .gp-top{font-size:13.5px;font-weight:700}\n.spx .gp-bot{font-size:12px;color:#C9D6DB}\n.spx .gp.done .gp-in{background:var(--sun);color:var(--dark)}\n.spx .acct{position:relative}\n.spx .acct>summary{display:flex;align-items:center;justify-content:center;width:44px;height:44px;border-radius:50%;background:#fff;cursor:pointer;list-style:none}\n.spx .acct>summary::-webkit-details-marker{display:none}\n.spx .av{display:flex;align-items:center;justify-content:center;width:44px;height:44px;border-radius:50%;background:#fff;color:var(--teal);font-size:16px;font-weight:800}\n.spx .acct-p{position:absolute;right:0;top:calc(100% + 18px);z-index:6;display:flex;flex-direction:column;gap:2px;width:320px;max-width:calc(100vw - 32px);padding:10px;border-radius:22px;background:#fff;box-shadow:0 24px 60px rgba(14,26,32,.28)}\n.spx .ac-card{display:flex;flex-direction:column;gap:10px;margin-bottom:4px;padding:14px;border-radius:16px;background:var(--dark);color:#fff}\n.spx .ac-top{display:flex;justify-content:space-between;align-items:center;gap:10px;font-weight:700}\n.spx .ac-badge{padding:3px 10px;border-radius:999px;background:var(--sun);color:var(--dark);font-size:11px;font-weight:800;letter-spacing:.5px}\n.spx .ac-badge.free{background:#2A3A41;color:#C9D3D6}\n.spx .ac-row{display:flex;justify-content:space-between;font-size:13px;color:#C9D3D6}\n.spx .ac-row b{color:#fff}\n.spx .ac-bar{height:8px;border-radius:999px;background:#2A3A41;overflow:hidden}\n.spx .ac-bar i{display:block;height:100%;width:0;background:var(--sun);border-radius:999px;transition:width .3s}\n.spx .ac-note{font-size:12px;color:#C9D3D6}\n.spx .ac-go{display:block;padding:11px;border-radius:12px;background:var(--sky);color:var(--dark);text-align:center;font-size:14px;font-weight:700}\n.spx .ac-go:hover{background:#8DD0EC;color:var(--dark)}\n.spx .ac-l{display:flex;align-items:center;gap:12px;padding:11px 12px;border-radius:12px;color:var(--ink);font-size:14px;font-weight:600}\n.spx .ac-l:hover{background:#F3EFE6;color:var(--ink)}\n.spx .ac-l svg{flex-shrink:0;color:var(--teal)}\n.spx .ac-l.out{color:var(--muted)}.spx .ac-l.out svg{color:var(--muted)}\n.spx .ac-hr{height:1px;margin:4px 8px;background:var(--line)}\n.spx .burger{display:none;flex-direction:column;align-items:center;justify-content:center;gap:5px;width:44px;height:44px;border-radius:50%;background:rgba(255,255,255,.12);cursor:pointer}\n.spx .burger span{display:block;width:18px;height:2px;border-radius:2px;background:#fff;transition:transform .2s}\n.spx .nav-toggle:focus-visible ~ .nav .burger{outline:2px solid #fff;outline-offset:2px}\n@media (max-width:1140px){.spx .nl{padding:0 13px}.spx .logo{padding:0 20px}.spx .nav-in{gap:10px}}\n@media (max-width:1020px){\n .spx .nav-in{justify-content:space-between}\n .spx .burger{display:flex}\n .spx .gp-txt{display:none}\n .spx .gp{padding:0 4px}\n .spx .isl-nav{display:none;position:absolute;top:calc(100% + 12px);left:0;right:0;height:auto;margin:0;flex-direction:column;align-items:stretch;gap:4px;max-height:calc(100vh - 110px);overflow:auto;padding:14px;border-radius:24px;background:#0E1A20}\n .spx .nav-toggle:checked ~ .nav .isl-nav{display:flex}\n .spx .nav-toggle:checked ~ .nav .burger span:first-child{transform:translateY(3.5px) rotate(45deg)}\n .spx .nav-toggle:checked ~ .nav .burger span:last-child{transform:translateY(-3.5px) rotate(-45deg)}\n .spx .isl-nav .nl{display:flex;justify-content:space-between;height:auto;padding:12px 14px;font-size:17px}\n .spx .isl-nav .nl svg{display:none}\n .spx .panel{position:static;opacity:1;visibility:visible;transform:none;width:auto;margin:2px 0 10px;padding:14px;border-radius:18px;box-shadow:none}\n .spx .panel::before{display:none}\n .spx .dd:hover>.panel,.spx .dd:focus-within>.panel{transform:none}\n .spx .mega,.spx .tools-p,.spx .prac{width:auto}\n .spx .lvl-grid{grid-template-columns:repeat(2,minmax(0,1fr))}\n .spx .tools-p{grid-template-columns:minmax(0,1fr)}\n .spx .m-only{display:block;margin-top:6px;padding-top:6px;border-top:1px solid #24404C}\n}\n@media (max-width:640px){\n .spx .login,.spx .lang,.spx .lvp-w{display:none}\n .spx .logo,.spx .isl-act{height:54px}\n .spx .logo{padding:0 18px;font-size:20px;gap:14px}\n .spx .isl-act{padding:0 5px;gap:4px}\n .spx .lvp>summary{padding:0 12px}\n .spx .cta{padding:0 16px;font-size:14.5px}\n .spx .nav-in{gap:8px}\n}\n@media (max-width:400px){.spx .logo{padding:0 14px;font-size:18px}.spx .gp{display:none}}\n\/* ===== Header A: Logo frei links oben, Men\u00fc + Konto in einer Insel ===== *\/\n.spx-top{position:relative}\n.spx .logo-free{position:absolute;top:24px;left:36px;z-index:998;display:flex;align-items:center;gap:24px;height:60px;font-family:'Fraunces',Georgia,serif;font-size:28px;font-weight:600;letter-spacing:-.5px;line-height:1;color:var(--ink);white-space:nowrap;text-decoration:none}\n.spx .logo-free:hover{color:var(--ink)}\n\n.spx .logo-free .logo-dot{display:block;width:15px;height:15px;border-radius:50%;background:var(--sun);box-shadow:10px 0 0 var(--sky)}\n.admin-bar .spx .logo-free{top:24px}\n.spx .nav{pointer-events:none}\n.spx .nav-in>*{pointer-events:auto}\n.spx .logo-free{z-index:1000;cursor:pointer}\n.spx .nav{padding:0 28px}\n.spx .nav-in{justify-content:flex-end;max-width:none}\n.spx .isl-grp{margin:0 0 0 auto;display:flex;align-items:center;gap:2px;height:60px;padding:0 8px;border-radius:999px;background:rgba(15,92,115,.92);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);box-shadow:0 10px 30px rgba(14,26,32,.18),inset 0 0 0 1px rgba(255,255,255,.16);color:#fff}\n.spx .isl-grp .isl{height:auto;padding:0;background:none;box-shadow:none;backdrop-filter:none;-webkit-backdrop-filter:none;border-radius:0}\n.spx .isl-grp .isl-nav{margin:0}\n.spx .isl-grp .isl-act{gap:6px;margin-left:8px;padding-left:14px;border-left:1px solid rgba(255,255,255,.2)}\n.spx .isl-grp .nl{color:#F0F8FB}\n.spx .isl-grp .gp-in{background:#0B4A5C}\n.spx .isl-grp .burger{background:rgba(255,255,255,.14)}\n@media (max-width:1140px){.spx .isl-grp .nl{padding:0 13px}}\n@media (max-width:1020px){\n .spx .nav-in{justify-content:flex-end}\n .spx .isl-grp{margin:0 0 0 auto;padding:0 6px;background:#0F5C73;backdrop-filter:none;-webkit-backdrop-filter:none}\n .spx .isl-grp .isl-nav{position:absolute;top:calc(100% + 12px);left:0;right:0;padding:14px;border-radius:24px;background:#0F5C73;box-shadow:0 24px 60px rgba(14,26,32,.3)}\n .spx .isl-grp .isl-act{margin-left:0;padding-left:0;border-left:0}\n .spx .isl-grp .m-only{border-top-color:rgba(255,255,255,.2)}\n}\n@media (max-width:640px){\n .spx .nav{padding:0 16px}\n .spx .logo-free{top:18px;left:18px;height:54px;gap:18px;font-size:21px}\n .spx .logo-free .logo-dot{width:12px;height:12px;box-shadow:8px 0 0 var(--sky)}\n .spx .isl-grp{height:54px}\n .spx .isl-grp .gp{display:none}\n}\n@media (max-width:360px){.spx .logo-free{font-size:18px;gap:16px}}\n<\/style>\n<style media=\"not all\">\n\/* ===== Level Dock (deaktiviert, bleibt als Sicherung) ===== *\/\n.spx .sr{position:absolute;width:1px;height:1px;opacity:0;margin:0;pointer-events:none}\nhtml:not(.spx-member) .spx .mb-only{display:none!important}\nhtml.spx-member .spx .g-only{display:none!important}\nhtml.spx-plus .spx .free-only{display:none!important}\n.spx .a1-head,.spx .pg-head{padding-top:142px}\n.spx .nav{position:fixed;top:12px;left:0;right:0;z-index:999;padding:0 16px}\n.admin-bar .spx .nav{top:44px}\n.spx .nav-in{position:relative;max-width:1200px;margin:0 auto;border-radius:26px;background:rgba(14,26,32,.82);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);box-shadow:0 12px 34px rgba(0,0,0,.25),inset 0 0 0 1px rgba(255,255,255,.09);color:#fff}\n.spx .dk-row1{display:flex;align-items:center;gap:16px;min-height:58px;padding:7px 8px 7px 22px;border-bottom:1px solid rgba(255,255,255,.08)}\n.spx .dk-row2{display:flex;align-items:center;gap:2px;min-height:44px;padding:3px 10px}\n.spx .logo{display:flex;align-items:center;gap:16px;font-family:'Fraunces',Georgia,serif;font-size:22px;font-weight:600;letter-spacing:-.3px;color:#fff;white-space:nowrap}\n.spx .logo:hover{color:#fff}\n.spx .logo-mark{display:block;width:11px;height:11px;border-radius:50%;background:var(--sun);box-shadow:7px 0 0 var(--sky);font-size:0;line-height:0;overflow:hidden}\n.spx .dk-lv{display:flex;align-items:center;gap:2px;padding:4px;border-radius:999px;background:rgba(255,255,255,.07);box-shadow:inset 0 0 0 1px rgba(255,255,255,.08)}\n.spx .dk-lv-l{padding:0 8px 0 10px;font-size:12px;font-weight:600;color:#9FB2BA;white-space:nowrap}\n.spx .dk-lv button{all:unset;box-sizing:border-box;cursor:pointer;min-width:42px;height:34px;padding:0 10px;border-radius:999px;text-align:center;line-height:34px;font-family:'Inter','Segoe UI',Roboto,Arial,sans-serif;font-size:14px;font-weight:700;color:#D6E2E6;transition:background .15s,color .15s}\n.spx .dk-lv button:hover{background:rgba(255,255,255,.1);color:#fff}\n.spx .dk-lv button[aria-pressed=true]{background:var(--sky);color:var(--dark)}\n.spx .nav-in button:focus-visible,.spx .nav-in a:focus-visible,.spx .nav-in summary:focus-visible{outline:2px solid #fff;outline-offset:2px}\n.spx .dk-lv-m{display:none}\n.spx .nav-right{display:flex;align-items:center;gap:6px;margin-left:auto;flex-shrink:0}\n.spx .lang{padding:8px 10px;border-radius:999px;font-size:13px;font-weight:700;color:#D6E2E6;box-shadow:inset 0 0 0 1px rgba(255,255,255,.2);white-space:nowrap}\n.spx .login{padding:10px 12px;font-size:15px;font-weight:600;color:#fff;white-space:nowrap}\n.spx .lang:hover,.spx .login:hover{color:#fff}\n.spx .cta{padding:12px 20px;border-radius:999px;background:var(--sun);color:var(--dark);font-size:15px;font-weight:700;white-space:nowrap}\n.spx .cta:hover{background:#FFD94F;color:var(--dark)}\n.spx .nl{display:inline-flex;align-items:center;gap:7px;padding:9px 14px;border-radius:999px;font-size:15px;font-weight:600;color:#D6E2E6;white-space:nowrap}\n.spx .nl:hover,.spx .dd:hover>.nl,.spx .dd:focus-within>.nl{background:rgba(255,255,255,.09);color:#fff}\n.spx .nl.hl{background:rgba(110,193,228,.16);color:#fff}\n.spx .nl.hl:hover{background:rgba(110,193,228,.26);color:#fff}\n.spx .dk-tag{display:inline-block;padding:2px 7px;border-radius:999px;background:var(--sky);color:var(--dark);font-size:11.5px;font-weight:800;letter-spacing:.3px}\n.spx .dk-tag:empty{display:none}\n.spx .nl svg{transition:transform .2s}\n.spx .dd{position:relative}\n.spx .dd:hover>.nl svg,.spx .dd:focus-within>.nl svg{transform:rotate(180deg)}\n.spx .panel{position:absolute;top:calc(100% + 12px);left:0;opacity:0;visibility:hidden;transform:translateY(8px);transition:opacity .18s,transform .18s,visibility .18s;background:#fff;color:var(--ink);border-radius:24px;padding:20px;box-shadow:0 24px 60px rgba(14,26,32,.28);z-index:5}\n.spx .panel::before{content:\"\";position:absolute;left:0;right:0;top:-16px;height:16px}\n.spx .dd:hover>.panel,.spx .dd:focus-within>.panel{opacity:1;visibility:visible;transform:none}\n.spx .mega{width:580px}\n.spx .pt{margin:0 0 12px;font-size:12px;font-weight:800;letter-spacing:1.3px;color:#8E979A}\n.spx .lvl-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px}\n.spx .lvl{display:flex;flex-direction:column;gap:2px;padding:14px;border-radius:16px;background:var(--c);color:var(--f,#0E1A20)}\n.spx .lvl b{font-family:'Fraunces',Georgia,serif;font-size:30px;font-weight:600;line-height:1}\n.spx .lvl small{margin-bottom:10px;font-size:12px;opacity:.8}\n.spx .lvl a{padding:3px 0;font-size:13px;font-weight:700;color:inherit}\n.spx .lvl a:hover{color:inherit;text-decoration:underline}\n.spx .panel-foot{display:flex;flex-wrap:wrap;justify-content:space-between;gap:8px 16px;margin-top:14px;padding-top:12px;border-top:1px solid var(--line);font-size:14px;font-weight:700}\n.spx .tools-p{width:540px;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:4px}\n.spx .tl{display:grid;grid-template-columns:38px 1fr;column-gap:12px;align-items:center;padding:10px;border-radius:14px;color:var(--ink)}\n.spx .tl:hover{background:#F4F1EA;color:var(--ink)}\n.spx .tl i{grid-row:1 \/ span 2;display:flex;align-items:center;justify-content:center;width:38px;height:38px;border-radius:12px;background:var(--c);color:var(--dark)}\n.spx .tl i svg{width:18px;height:18px}\n.spx .tl b{display:block;font-size:14.5px;line-height:1.25}\n.spx .tl small{display:block;font-size:12.5px;color:#6A7477}\n.spx .dk-r2r{display:flex;align-items:center;gap:8px;margin-left:auto}\n.spx .dk-note{font-size:13px;color:#9FB2BA;white-space:nowrap}\n.spx .dk-upg{padding:7px 14px;border-radius:999px;background:var(--sun);color:var(--dark);font-size:13px;font-weight:700;white-space:nowrap}\n.spx .dk-upg:hover{background:#FFD94F;color:var(--dark)}\n.spx .dk-dash{padding:8px 12px;font-size:14px;font-weight:600;color:#C9D6DB;white-space:nowrap}\n.spx .dk-dash:hover{color:#fff}\n.spx .m-only{display:none}\n.spx .gp{display:flex;align-items:center;gap:10px;padding:5px 14px 5px 5px;border-radius:999px;background:rgba(255,255,255,.1);color:#fff;--p:0;white-space:nowrap}\n.spx .gp:hover{color:#fff;background:rgba(255,255,255,.16)}\n.spx .gp-ring{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:34px;height:34px;border-radius:50%;background:conic-gradient(var(--sun) calc(var(--p) * 1%),#4B5A5F 0)}\n.spx .gp-in{display:flex;align-items:center;justify-content:center;width:26px;height:26px;border-radius:50%;background:#26343A;font-size:11px;font-weight:700}\n.spx .gp-txt{display:flex;flex-direction:column;line-height:1.15}\n.spx .gp-main{font-size:13px;font-weight:700}\n.spx .gp-sub{font-size:11px;color:#C9D3D6}\n.spx .gp-sep{width:1px;height:24px;background:rgba(255,255,255,.2)}\n.spx .gp-streak{display:flex;align-items:center;gap:4px;font-size:13px;font-weight:700;color:var(--sun)}\n.spx .gp.done{background:var(--sun);color:var(--dark)}\n.spx .gp.done:hover{background:#FFD94F;color:var(--dark)}\n.spx .gp.done .gp-ring{background:var(--dark)}\n.spx .gp.done .gp-in{background:var(--dark);color:var(--sun)}\n.spx .gp.done .gp-sub,.spx .gp.done .gp-streak{color:var(--dark)}\n.spx .gp.done .gp-sep{background:rgba(14,26,32,.25)}\n.spx .acct{position:relative}\n.spx .acct>summary{display:flex;align-items:center;gap:8px;padding:4px 12px 4px 4px;border-radius:999px;background:#fff;color:var(--ink);font-size:14px;font-weight:600;cursor:pointer;list-style:none;white-space:nowrap}\n.spx .acct>summary::-webkit-details-marker{display:none}\n.spx .acct>summary svg{transition:transform .2s}\n.spx .acct[open]>summary svg{transform:rotate(180deg)}\n.spx .av{display:flex;align-items:center;justify-content:center;width:34px;height:34px;border-radius:50%;background:var(--teal);color:#fff;font-size:15px;font-weight:700}\n.spx .acct-p{position:absolute;right:0;top:calc(100% + 16px);z-index:6;display:flex;flex-direction:column;gap:2px;width:320px;max-width:calc(100vw - 32px);padding:10px;border-radius:22px;background:#fff;box-shadow:0 24px 60px rgba(14,26,32,.28)}\n.spx .ac-card{display:flex;flex-direction:column;gap:10px;margin-bottom:4px;padding:14px;border-radius:16px;background:var(--dark);color:#fff}\n.spx .ac-top{display:flex;justify-content:space-between;align-items:center;gap:10px;font-weight:700}\n.spx .ac-badge{padding:3px 10px;border-radius:999px;background:var(--sun);color:var(--dark);font-size:11px;font-weight:800;letter-spacing:.5px}\n.spx .ac-badge.free{background:#2A3A41;color:#C9D3D6}\n.spx .ac-row{display:flex;justify-content:space-between;font-size:13px;color:#C9D3D6}\n.spx .ac-row b{color:#fff}\n.spx .ac-bar{height:8px;border-radius:999px;background:#2A3A41;overflow:hidden}\n.spx .ac-bar i{display:block;height:100%;width:0;background:var(--sun);border-radius:999px;transition:width .3s}\n.spx .ac-note{font-size:12px;color:#C9D3D6}\n.spx .ac-go{display:block;padding:11px;border-radius:12px;background:var(--sky);color:var(--dark);text-align:center;font-size:14px;font-weight:700}\n.spx .ac-go:hover{background:#8DD0EC;color:var(--dark)}\n.spx .ac-l{display:flex;align-items:center;gap:12px;padding:11px 12px;border-radius:12px;color:var(--ink);font-size:14px;font-weight:600}\n.spx .ac-l:hover{background:#F3EFE6;color:var(--ink)}\n.spx .ac-l svg{flex-shrink:0;color:var(--teal)}\n.spx .ac-l.out{color:var(--muted)}.spx .ac-l.out svg{color:var(--muted)}\n.spx .ac-hr{height:1px;margin:4px 8px;background:var(--line)}\n.spx .burger{display:none;flex-direction:column;align-items:center;justify-content:center;gap:5px;width:44px;height:44px;border-radius:50%;background:rgba(255,255,255,.1);cursor:pointer}\n.spx .burger span{display:block;width:18px;height:2px;border-radius:2px;background:#fff;transition:transform .2s}\n.spx .nav-toggle:focus-visible ~ .nav .burger{outline:2px solid #fff;outline-offset:2px}\n@media (max-width:1100px){.spx .dk-lv-l,.spx .dk-note{display:none}}\n@media (max-width:1020px){\n .spx .burger{display:flex}\n .spx .nav-in{border-radius:999px}\n .spx .dk-row1{border-bottom:0;padding-left:18px}\n .spx .login,.spx .lang,.spx .dk-r2r .dk-dash{display:none}\n .spx .dk-row2{display:none;position:absolute;top:calc(100% + 10px);left:0;right:0;flex-direction:column;align-items:stretch;gap:4px;max-height:calc(100vh - 110px);overflow:auto;padding:14px;border-radius:24px;background:#0E1A20;box-shadow:0 24px 60px rgba(0,0,0,.35)}\n .spx .nav-toggle:checked ~ .nav .dk-row2{display:flex}\n .spx .nav-toggle:checked ~ .nav .burger span:first-child{transform:translateY(3.5px) rotate(45deg)}\n .spx .nav-toggle:checked ~ .nav .burger span:last-child{transform:translateY(-3.5px) rotate(-45deg)}\n .spx .nl{display:flex;justify-content:space-between;padding:12px 14px;font-size:17px}\n .spx .nl svg{display:none}\n .spx .panel{position:static;opacity:1;visibility:visible;transform:none;width:auto;margin:2px 0 10px;padding:14px;border-radius:18px;box-shadow:none}\n .spx .panel::before{display:none}\n .spx .mega,.spx .tools-p{width:auto}\n .spx .lvl-grid{grid-template-columns:repeat(2,minmax(0,1fr))}\n .spx .tools-p{grid-template-columns:minmax(0,1fr)}\n .spx .dk-r2r{margin:6px 0 0;flex-wrap:wrap}\n .spx .m-only{display:block;margin-top:6px;padding-top:6px;border-top:1px solid #24404C}\n .spx .gp-txt,.spx .gp-sep,.spx .acct-name,.spx .acct>summary svg{display:none}\n .spx .gp{padding:4px 10px 4px 4px;gap:6px}\n .spx .acct>summary{padding:4px}\n}\n@media (max-width:680px){\n .spx .dk-lv-d{display:none}\n .spx .dk-lv-m{display:flex;margin-bottom:8px}\n .spx .dk-lv-m button{flex:1}\n .spx .dk-lv-m .dk-lv-l{display:block}\n}\n@media (max-width:420px){.spx .gp-streak{display:none}.spx .gp{padding:4px}.spx .cta{padding:10px 14px;font-size:14px}.spx .logo{font-size:20px;gap:14px}.spx .dk-row1{gap:10px;padding-left:16px}}\n<\/style>\n<style media=\"not all\">\n\/* ===== Altes Men\u00fc (deaktiviert, bleibt als Sicherung) ===== *\/\n.spx .sr{position:absolute;width:1px;height:1px;opacity:0;margin:0;pointer-events:none}\n.spx .nav{position:fixed;top:14px;left:0;right:0;z-index:999;padding:0 16px}\n.admin-bar .spx .nav{top:46px}\n.spx .nav-in{position:relative;max-width:1200px;margin:0 auto;display:flex;align-items:center;gap:18px;padding:8px 8px 8px 22px;border-radius:999px;background:rgba(14,26,32,.8);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);box-shadow:0 12px 34px rgba(0,0,0,.25),inset 0 0 0 1px rgba(255,255,255,.09)}\n.spx .logo{display:flex;align-items:center;gap:16px;font-family:'Fraunces',Georgia,serif;font-size:22px;font-weight:600;color:#fff;letter-spacing:-.3px}\n.spx .logo:hover{color:#fff}\n.spx .logo-dot{width:11px;height:11px;border-radius:50%;background:var(--sun);box-shadow:7px 0 0 var(--sky)}\n.spx .nav-links{display:flex;align-items:center;gap:2px;margin:0 auto}\n.spx .nl{display:inline-flex;align-items:center;gap:6px;padding:10px 14px;border-radius:999px;font-size:15px;font-weight:600;color:#D6E2E6;white-space:nowrap}\n.spx .nl:hover,.spx .dd:hover>.nl,.spx .dd:focus-within>.nl{background:rgba(255,255,255,.09);color:#fff}\n.spx .nl svg{transition:transform .2s}\n.spx .dd{position:relative}\n.spx .dd:hover>.nl svg,.spx .dd:focus-within>.nl svg{transform:rotate(180deg)}\n.spx .panel{position:absolute;top:calc(100% + 14px);left:50%;transform:translate(-50%,8px);opacity:0;visibility:hidden;transition:opacity .18s,transform .18s,visibility .18s;background:#fff;color:var(--ink);border-radius:24px;padding:20px;box-shadow:0 24px 60px rgba(14,26,32,.28)}\n.spx .panel::before{content:\"\";position:absolute;left:0;right:0;top:-16px;height:16px}\n.spx .dd:hover>.panel,.spx .dd:focus-within>.panel{opacity:1;visibility:visible;transform:translate(-50%,0)}\n.spx .mega{width:580px}\n.spx .pt{font-size:12px;font-weight:800;letter-spacing:1.3px;color:#8E979A;margin-bottom:12px}\n.spx .lvl-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px}\n.spx .lvl{background:var(--c);color:var(--f);border-radius:16px;padding:14px;display:flex;flex-direction:column;gap:2px}\n.spx .lvl b{font-family:'Fraunces',Georgia,serif;font-size:30px;font-weight:600;line-height:1}\n.spx .lvl small{font-size:12px;opacity:.8;margin-bottom:10px}\n.spx .lvl a{font-size:13px;font-weight:700;color:inherit;padding:3px 0}\n.spx .lvl a:hover{color:inherit;text-decoration:underline}\n.spx .panel-foot{display:flex;flex-wrap:wrap;justify-content:space-between;gap:8px 16px;margin-top:14px;padding-top:12px;border-top:1px solid var(--line);font-size:14px;font-weight:700}\n.spx .tools-p{width:540px;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:4px}\n.spx .tl{display:flex;gap:12px;align-items:center;padding:10px;border-radius:14px;color:var(--ink)}\n.spx .tl:hover{background:#F4F1EA;color:var(--ink)}\n.spx .tl i{flex-shrink:0;width:38px;height:38px;border-radius:12px;display:flex;align-items:center;justify-content:center;color:var(--dark)}\n.spx .tl b{display:block;font-size:14.5px}\n.spx .tl small{display:block;font-size:12.5px;color:#6A7477}\n.spx .nav-right{display:flex;align-items:center;gap:6px;flex-shrink:0;margin-left:auto}\n.spx .lang{font-size:13px;font-weight:700;color:#D6E2E6;padding:8px 10px;border-radius:999px;box-shadow:inset 0 0 0 1px rgba(255,255,255,.2)}\n.spx .login{font-size:15px;font-weight:600;color:#fff;padding:10px 12px}\n.spx .lang:hover,.spx .login:hover{color:#fff}\n.spx .cta{font-size:15px;font-weight:700;color:var(--dark);background:var(--sun);padding:12px 20px;border-radius:999px}\n.spx .cta:hover{color:var(--dark);background:#FFD94F}\n.spx .burger{display:none;width:44px;height:44px;border-radius:50%;background:rgba(255,255,255,.1);cursor:pointer;flex-direction:column;align-items:center;justify-content:center;gap:5px}\n.spx .burger span{display:block;width:18px;height:2px;background:#fff;border-radius:2px;transition:transform .2s}\n.spx .nav-toggle:focus-visible ~ .nav .burger{outline:2px solid #fff;outline-offset:2px}\n.spx .m-only{display:none}\n@media (max-width:1020px){\n .spx .burger{display:flex}\n .spx .login,.spx .lang{display:none}\n .spx .nav-links{display:none;position:absolute;top:calc(100% + 10px);left:0;right:0;max-height:calc(100vh - 110px);overflow:auto;flex-direction:column;align-items:stretch;gap:4px;background:#0E1A20;border-radius:24px;padding:14px;box-shadow:0 24px 60px rgba(0,0,0,.35)}\n .spx .nav-toggle:checked ~ .nav .nav-links{display:flex}\n .spx .nav-toggle:checked ~ .nav .burger span:first-child{transform:translateY(3.5px) rotate(45deg)}\n .spx .nav-toggle:checked ~ .nav .burger span:last-child{transform:translateY(-3.5px) rotate(-45deg)}\n .spx .nl{display:flex;justify-content:space-between;padding:12px 14px;font-size:17px}\n .spx .nl svg{display:none}\n .spx .panel{position:static;transform:none;opacity:1;visibility:visible;width:auto;box-shadow:none;margin:2px 0 10px;padding:14px;border-radius:18px}\n .spx .panel::before{display:none}\n .spx .dd:hover>.panel,.spx .dd:focus-within>.panel{transform:none}\n .spx .mega,.spx .tools-p{width:auto}\n .spx .lvl-grid{grid-template-columns:repeat(2,minmax(0,1fr))}\n .spx .tools-p{grid-template-columns:minmax(0,1fr)}\n .spx .m-only{display:block;border-top:1px solid #24404C;margin-top:6px;padding-top:6px}\n .spx .nav-in{padding-left:18px}\n}\n\/* ===== Mitglieder-Men\u00fc ===== *\/\nhtml:not(.spx-member) .spx .mb-only{display:none!important}\nhtml.spx-member .spx .g-only{display:none!important}\n.spx .gp{display:flex;align-items:center;gap:10px;padding:5px 14px 5px 5px;border-radius:999px;background:rgba(255,255,255,.1);color:#fff;--p:0;white-space:nowrap}\n.spx .gp:hover{color:#fff;background:rgba(255,255,255,.16)}\n.spx .gp-ring{width:34px;height:34px;border-radius:50%;background:conic-gradient(var(--sun) calc(var(--p) * 1%),#4B5A5F 0);display:flex;align-items:center;justify-content:center;flex-shrink:0}\n.spx .gp-in{width:26px;height:26px;border-radius:50%;background:#26343A;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:700}\n.spx .gp-txt{display:flex;flex-direction:column;line-height:1.15}\n.spx .gp-main{font-size:13px;font-weight:700}\n.spx .gp-sub{font-size:11px;color:#C9D3D6}\n.spx .gp-sep{width:1px;height:24px;background:rgba(255,255,255,.2)}\n.spx .gp-streak{display:flex;align-items:center;gap:4px;font-size:13px;font-weight:700;color:var(--sun)}\n.spx .gp.done{background:var(--sun);color:var(--dark)}\n.spx .gp.done:hover{background:#FFD94F;color:var(--dark)}\n.spx .gp.done .gp-ring{background:var(--dark)}\n.spx .gp.done .gp-in{background:var(--dark);color:var(--sun)}\n.spx .gp.done .gp-sub,.spx .gp.done .gp-streak{color:var(--dark)}\n.spx .gp.done .gp-sep{background:rgba(14,26,32,.25)}\n.spx .acct{position:relative}\n.spx .acct>summary{list-style:none;display:flex;align-items:center;gap:8px;padding:4px 12px 4px 4px;border-radius:999px;background:#fff;color:var(--ink);font-weight:600;font-size:14px;cursor:pointer;white-space:nowrap}\n.spx .acct>summary::-webkit-details-marker{display:none}\n.spx .acct>summary svg{transition:transform .2s}\n.spx .acct[open]>summary svg{transform:rotate(180deg)}\n.spx .av{width:34px;height:34px;border-radius:50%;background:var(--teal);color:#fff;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:15px}\n.spx .acct-p{position:absolute;right:0;top:calc(100% + 16px);width:320px;max-width:calc(100vw - 32px);background:#fff;border-radius:22px;box-shadow:0 24px 60px rgba(14,26,32,.28);padding:10px;display:flex;flex-direction:column;gap:2px;z-index:5}\n.spx .ac-card{background:var(--dark);color:#fff;border-radius:16px;padding:14px;display:flex;flex-direction:column;gap:10px;margin-bottom:4px}\n.spx .ac-top{display:flex;justify-content:space-between;align-items:center;gap:10px;font-weight:700}\n.spx .ac-badge{padding:3px 10px;border-radius:999px;background:var(--sun);color:var(--dark);font-size:11px;font-weight:800;letter-spacing:.5px}\n.spx .ac-badge.free{background:#2A3A41;color:#C9D3D6}\n.spx .ac-row{display:flex;justify-content:space-between;font-size:13px;color:#C9D3D6}\n.spx .ac-row b{color:#fff}\n.spx .ac-bar{height:8px;border-radius:999px;background:#2A3A41;overflow:hidden}\n.spx .ac-bar i{display:block;height:100%;width:0;background:var(--sun);border-radius:999px;transition:width .3s}\n.spx .ac-note{font-size:12px;color:#C9D3D6}\n.spx .ac-go{display:block;text-align:center;padding:11px;border-radius:12px;background:var(--sky);color:var(--dark);font-weight:700;font-size:14px}\n.spx .ac-go:hover{background:#8DD0EC;color:var(--dark)}\n.spx .ac-l{display:flex;align-items:center;gap:12px;padding:11px 12px;border-radius:12px;color:var(--ink);font-size:14px;font-weight:600}\n.spx .ac-l:hover{background:#F3EFE6;color:var(--ink)}\n.spx .ac-l svg{color:var(--teal);flex-shrink:0}\n.spx .ac-l.out{color:var(--muted)}.spx .ac-l.out svg{color:var(--muted)}\n.spx .ac-hr{height:1px;background:var(--line);margin:4px 8px}\n@media (max-width:1020px){.spx .gp-txt,.spx .gp-sep,.spx .acct-name,.spx .acct>summary svg{display:none}.spx .gp{padding:4px 10px 4px 4px;gap:6px}.spx .acct>summary{padding:4px}}\n@media (max-width:400px){.spx .gp-streak{display:none}.spx .gp{padding:4px}}\n<\/style>\n<script>(function(){var u=window.wpTrainerUserInfo;if(u){var h=document.documentElement;h.classList.add('spx-member');if((parseInt(u.level,10)||1)>=3){h.classList.add('spx-plus');}}})();<\/script>\n<style id=\"spx-kopf-d\">\n\/* ===== Seitenkopf \"Kopf D\" + Men\u00fc (global, 29.10.) =====\n   Kopf: kompakt, linksb\u00fcndig auf 780px, kleine Kapitelzeile, feine Verlaufslinie, heller Schein oben rechts.\n   Men\u00fc: Petrol-Pille leicht transparent, aufklappende K\u00e4sten in derselben Farbe. *\/\nhtml body:not(.home) .spx-page{background:radial-gradient(ellipse 62% 460px at 85% 0%,#CBE8F4 0%,rgba(203,232,244,.6) 45%,rgba(251,248,242,0) 100%),radial-gradient(ellipse 40% 300px at 100% 0%,rgba(255,207,51,.16) 0%,rgba(255,207,51,0) 100%),#FBF8F2 !important}\nhtml body .spx .pg-head,html body .spx .a1-head{text-align:left!important;padding-top:124px!important;padding-bottom:0!important;margin-bottom:30px!important}\nhtml body .spx .a1-head{margin-bottom:0!important}\nhtml body .spx-page .a1-stage{padding-top:30px}\n\/* Einheitlicher Abstand Titel-Linie -> Inhalt auf allen Unterseiten *\/\nhtml body .spx-page .spx .pg-head,html body .spx-page .spx .a1-head{margin-bottom:0!important}\nhtml body .spx-page .pg-head + section,html body .spx-page .a1-head + section,html body .spx-page .spx:has(> .pg-head:last-child) + *,html body .spx-page .spx:has(> .a1-head:last-child) + *,html body .spx-page .a1-stage,html body .spx-page .tool-stage{padding-top:48px!important;margin-top:0!important}\n@media (max-width:840px){html body .spx-page .pg-head + section,html body .spx-page .a1-head + section,html body .spx-page .spx:has(> .pg-head:last-child) + *,html body .spx-page .spx:has(> .a1-head:last-child) + *,html body .spx-page .a1-stage,html body .spx-page .tool-stage{padding-top:36px!important}}\nhtml body .spx .pg-head .wrap,html body .spx .a1-head .wrap{max-width:780px!important;width:auto!important;margin:0 auto!important;padding:0 0 22px!important;position:relative;box-sizing:border-box}\nhtml body .spx .pg-head .wrap::after,html body .spx .a1-head .wrap::after{content:\"\";position:absolute;left:0;right:0;bottom:0;height:1px;background:linear-gradient(to right,#0F5C73 0%,#6EC1E4 45%,rgba(110,193,228,0) 100%)}\nhtml body .spx .pg-head .kicker,html body .spx .a1-head .kicker{margin:0 0 8px!important;font-family:'Inter','Segoe UI',Arial,sans-serif!important;font-style:normal!important;font-size:12px!important;font-weight:700!important;line-height:1.4!important;letter-spacing:1.4px!important;text-transform:uppercase!important;color:#5E686B!important;text-align:left!important}\nhtml body .spx .pg-head h1,html body .spx .a1-head h1{font-size:34px!important;line-height:1.15!important;letter-spacing:-.5px!important;margin:0 0 8px!important;text-align:left!important}\nhtml body .spx .pg-head .sub,html body .spx .a1-head .a1-sub{margin:0!important;max-width:600px!important;font-size:16px!important;line-height:1.55!important;color:#5E686B!important;text-align:left!important}\n@media (max-width:840px){\n html body .spx .pg-head .wrap,html body .spx .a1-head .wrap{margin:0 16px!important}\n html body .spx .pg-head h1,html body .spx .a1-head h1{font-size:28px!important}\n html body .spx .pg-head,html body .spx .a1-head{padding-top:108px!important}\n}\n\/* Startseite: dezente Farbverl\u00e4ufe im Stil der Unterseiten *\/\nhtml body.home #spx .hero{background-color:#14708C!important;background-image:radial-gradient(ellipse 55% 75% at 88% 0%,rgba(110,193,228,.38) 0%,rgba(110,193,228,0) 70%),radial-gradient(ellipse 45% 55% at 100% 100%,rgba(255,207,51,.12) 0%,rgba(255,207,51,0) 70%),radial-gradient(ellipse 55% 70% at 0% 100%,rgba(14,83,103,.75) 0%,rgba(14,83,103,0) 70%)!important}\n\/* Verl\u00e4ufe als weiche Farbschicht \u00fcber den R\u00e4ndern (multiply), damit K\u00e4sten mit eigenem Hintergrund keine Kanten bilden *\/\nhtml body.home #spx section.ch2::after,html body.home #spx section.ch3::after,html body.home #spx section#pricing::after,html body.home #spx section.ch:last-of-type::after{content:\"\";position:absolute;top:0;bottom:0;left:50%;width:100vw;margin-left:-50vw;z-index:60;pointer-events:none;mix-blend-mode:multiply}\nhtml body.home #spx section.ch2::after{background:radial-gradient(ellipse 34% 42% at 0% 50%,#D3ECF6 0%,rgba(255,255,255,0) 100%)}\nhtml body.home #spx section.ch3::after{background:radial-gradient(ellipse 34% 42% at 100% 50%,#D3ECF6 0%,rgba(255,255,255,0) 100%)}\nhtml body.home #spx section#pricing::after{background:radial-gradient(ellipse 30% 40% at 0% 45%,#D6EEF7 0%,rgba(255,255,255,0) 100%),radial-gradient(ellipse 26% 36% at 100% 60%,#FFF3C9 0%,rgba(255,255,255,0) 100%)}\nhtml body.home #spx section.ch:last-of-type::after{background:radial-gradient(ellipse 34% 40% at 100% 50%,#D6EEF7 0%,rgba(255,255,255,0) 100%)}\n\/* Men\u00fc-Pille: gleich wie bisher, nur leicht transparent *\/\nhtml body .spx .isl-grp{background:rgba(15,92,115,.8)!important;-webkit-backdrop-filter:blur(14px) saturate(140%)!important;backdrop-filter:blur(14px) saturate(140%)!important;box-shadow:0 8px 24px rgba(14,26,32,.12),inset 0 0 0 1px rgba(255,255,255,.2)!important}\n\/* Aufklappende K\u00e4sten in derselben Farbe *\/\nhtml body .spx .lvp-p,html body .spx .acct-p{background:rgba(15,92,115,.92)!important;-webkit-backdrop-filter:blur(18px)!important;backdrop-filter:blur(18px)!important;color:#fff!important;box-shadow:0 24px 60px rgba(14,26,32,.22),inset 0 0 0 1px rgba(255,255,255,.18)!important}\n@media (min-width:901px){\n html body .spx .panel{background:rgba(15,92,115,.92)!important;-webkit-backdrop-filter:blur(18px)!important;backdrop-filter:blur(18px)!important;color:#fff!important;box-shadow:0 24px 60px rgba(14,26,32,.22),inset 0 0 0 1px rgba(255,255,255,.18)!important}\n}\n@media (max-width:900px){\n html body .spx .isl-grp{-webkit-backdrop-filter:none!important;backdrop-filter:none!important;background:rgba(15,92,115,.88)!important}\n html body .spx .isl-nav{background:rgba(15,92,115,.94)!important;-webkit-backdrop-filter:blur(18px)!important;backdrop-filter:blur(18px)!important}\n html body .spx .panel{background:rgba(255,255,255,.07)!important;color:#fff!important}\n}\nhtml body .spx .tl,html body .spx .tl b{color:#fff!important}\nhtml body .spx .tl:hover{background:rgba(255,255,255,.1)!important;color:#fff!important}\nhtml body .spx .tl small{color:#CFE3EA!important}\nhtml body .spx .lvl{box-shadow:inset 0 0 0 1px rgba(255,255,255,.14)}\nhtml body .spx .panel-foot{border-top-color:rgba(255,255,255,.2)!important}\nhtml body .spx .panel-foot a{color:#fff!important}\nhtml body .spx .panel-foot a:hover{color:#CFEFFB!important}\nhtml body .spx .lvp-p .pt{color:#CFE3EA!important}\nhtml body .spx .lvp-p button{color:#fff!important}\nhtml body .spx .lvp-p button:hover{background:rgba(255,255,255,.1)!important}\nhtml body .spx .lvp-p button[aria-pressed=true]{background:rgba(255,255,255,.14)!important;box-shadow:inset 0 0 0 1.5px #6EC1E4!important}\nhtml body .spx .lv-t small{color:#CFE3EA!important}\nhtml body .spx .lvp-p a{color:#fff!important;border-top-color:rgba(255,255,255,.2)!important}\n\/* Konto-Kasten: nur Name und Mitgliedschaft, kein dunkler Block mit Tagesziel\/Button *\/\nhtml body .spx .ac-card{background:transparent!important;color:#fff!important;padding:10px 12px 12px!important;margin:0 0 4px!important;border-radius:0!important;border-bottom:1px solid rgba(255,255,255,.2)!important;gap:0!important}\nhtml body .spx .ac-card .ac-row,html body .spx .ac-card .ac-bar,html body .spx .ac-card .ac-note,html body .spx .ac-card .ac-go{display:none!important}\nhtml body .spx .ac-card .ac-nm{font-family:'Fraunces',Georgia,serif;font-size:18px;font-weight:600;color:#fff}\nhtml body .spx .ac-l{color:#fff!important}\nhtml body .spx .ac-l:hover{background:rgba(255,255,255,.1)!important;color:#fff!important}\nhtml body .spx .ac-l svg{background:rgba(255,255,255,.12)!important;color:#9ADCF5!important}\nhtml body .spx .ac-l.out,html body .spx .ac-l.out svg{color:#CFE3EA!important}\nhtml body .spx .ac-hr{background:rgba(255,255,255,.2)!important}\n\/* ===== Men\u00fc in Beige (29.10., \u00fcberschreibt die Petrol-Variante oben) ===== *\/\nhtml body .spx .isl-grp{background:rgba(246,250,251,.62)!important;box-shadow:0 6px 20px rgba(14,26,32,.06),inset 0 0 0 1px rgba(20,112,140,.14)!important;color:#1D2427!important}\nhtml body .spx .isl-grp .nl,html body .spx .nl{color:#1D2427!important}\nhtml body .spx .nl:hover,html body .spx .dd:hover>.nl,html body .spx .dd:focus-within>.nl{background:rgba(20,112,140,.08)!important;color:#0F5C73!important}\nhtml body .spx .isl-grp .login,html body .spx .isl-grp .login:hover{color:#1D2427!important}\nhtml body .spx .isl-grp .lang{color:#4B565A!important;box-shadow:inset 0 0 0 1px rgba(29,36,39,.16)!important}\nhtml body .spx .isl-grp .gp{color:#1D2427!important;background:rgba(29,36,39,.05)!important}\nhtml body .spx .isl-grp .gp-bot,html body .spx .isl-grp .gp-sub{color:#5E686B!important}\nhtml body .spx .isl-grp .gp-in{background:#FBF8F2!important;color:#1D2427!important}\nhtml body .spx .isl-grp .gp-sep{background:rgba(29,36,39,.15)!important}\nhtml body .spx .isl-grp .burger{background:rgba(29,36,39,.07)!important}\nhtml body .spx .isl-grp .burger span{background:#1D2427!important}\nhtml body .spx .lvp-p,html body .spx .acct-p{background:rgba(247,251,252,.94)!important;color:#1D2427!important;box-shadow:0 24px 60px rgba(14,26,32,.12),inset 0 0 0 1px rgba(20,112,140,.14)!important}\n@media (min-width:901px){\n html body .spx .panel{background:rgba(247,251,252,.94)!important;color:#1D2427!important;box-shadow:0 24px 60px rgba(14,26,32,.12),inset 0 0 0 1px rgba(20,112,140,.14)!important}\n}\n@media (max-width:900px){\n html body .spx .isl-grp{background:rgba(246,250,251,.82)!important}\n html body .spx .isl-nav{background:rgba(247,251,252,.96)!important;box-shadow:0 24px 60px rgba(14,26,32,.14),inset 0 0 0 1px rgba(20,112,140,.14)!important}\n html body .spx .panel{background:rgba(20,112,140,.05)!important;color:#1D2427!important}\n}\nhtml body .spx .tl,html body .spx .tl b{color:#1D2427!important}\nhtml body .spx .tl:hover{background:rgba(20,112,140,.07)!important;color:#1D2427!important}\nhtml body .spx .tl small{color:#5E686B!important}\nhtml body .spx .lvl{box-shadow:none}\nhtml body .spx .panel-foot{border-top-color:#E6DFD1!important}\nhtml body .spx .panel-foot a{color:#14708C!important}\nhtml body .spx .panel-foot a:hover{color:#0E5367!important}\nhtml body .spx .lvp-p .pt{color:#5E686B!important}\nhtml body .spx .lvp-p button{color:#1D2427!important}\nhtml body .spx .lvp-p button:hover{background:rgba(20,112,140,.07)!important}\nhtml body .spx .lvp-p button[aria-pressed=true]{background:rgba(20,112,140,.1)!important;box-shadow:inset 0 0 0 1.5px #14708C!important}\nhtml body .spx .lv-t small{color:#5E686B!important}\nhtml body .spx .lvp-p a{color:#14708C!important;border-top-color:#E6DFD1!important}\nhtml body .spx .ac-card{color:#1D2427!important;border-bottom-color:#E6DFD1!important}\nhtml body .spx .ac-card .ac-nm{color:#1D2427!important}\nhtml body .spx .ac-l{color:#1D2427!important}\nhtml body .spx .ac-l:hover{background:rgba(20,112,140,.07)!important;color:#1D2427!important}\nhtml body .spx .ac-l svg{background:#E3F5FC!important;color:#14708C!important}\nhtml body .spx .ac-l.out,html body .spx .ac-l.out svg{color:#5E686B!important}\nhtml body .spx .ac-l.out svg{background:#F4F1EA!important}\nhtml body .spx .ac-hr{background:#E6DFD1!important}\n\/* ===== Mitglieder-Men\u00fc wie das Original + eigener Bereich f\u00fcr Level\/Streak\/Konto (03.11.) ===== *\/\nhtml.spx-member .spx .isl-nav>.dd.g-only{display:block!important}\nhtml.spx-member .spx .isl-nav>.dd.mb-only{display:none!important}\n@media (min-width:901px){\n html.spx-member body .spx .isl-grp{background:transparent!important;box-shadow:none!important;-webkit-backdrop-filter:none!important;backdrop-filter:none!important;padding:0!important;gap:18px!important}\n html.spx-member body .spx .isl-grp .isl-nav,html.spx-member body .spx .isl-grp .isl-act{height:60px!important;padding:0 8px!important;border-radius:999px!important;background:rgba(246,250,251,.62)!important;-webkit-backdrop-filter:blur(14px) saturate(140%)!important;backdrop-filter:blur(14px) saturate(140%)!important;box-shadow:0 6px 20px rgba(14,26,32,.06),inset 0 0 0 1px rgba(20,112,140,.14)!important}\n html.spx-member body .spx .isl-grp .isl-act{margin-left:0!important;border-left:0!important;gap:10px!important}\n html.spx-member body .spx .isl-grp .isl-act .gp{background:#fff!important;box-shadow:inset 0 0 0 1px rgba(20,112,140,.14)!important}\n}\n<\/style>\n<style id=\"spx-kopf-act-0311b\">\n\/* ===== Level \/ Streak \/ Konto: aufger\u00e4umt, mehr Abstand, Profil klar klickbar (03.11. b) ===== *\/\n.spx .ia-sep{display:none}\n.spx .isl-act .gp-ring{display:none!important}\n\/* Level: dezent statt Farbfl\u00e4che *\/\nhtml body .spx .isl-act .lvp>summary{height:40px!important;padding:0 10px 0 12px!important;gap:7px!important;border-radius:12px!important;background:transparent!important;box-shadow:none!important;color:#6A7477!important;font-size:13px!important;font-weight:500!important;transition:background .15s!important}\nhtml body .spx .isl-act .lvp>summary:hover,html body .spx .isl-act .lvp[open]>summary{background:rgba(20,112,140,.07)!important}\nhtml body .spx .isl-act .lvp .dk-tag{display:inline-flex;align-items:center;height:22px;padding:0 7px;border-radius:7px;background:#EEF5F7;color:#14708C;font-size:12.5px;font-weight:700;letter-spacing:.2px}\nhtml body .spx .isl-act .lvp>summary svg{width:10px!important;height:10px!important;opacity:.5}\n\/* Account: Avatar + Name + Pfeil, deutlich als Button *\/\nhtml body .spx .isl-act .acct>summary{display:flex!important;align-items:center!important;gap:8px!important;width:auto!important;height:44px!important;padding:0 12px 0 4px!important;border-radius:999px!important;background:#fff!important;color:#1D2427!important;box-shadow:inset 0 0 0 1px rgba(20,112,140,.25),0 1px 3px rgba(14,26,32,.08)!important;cursor:pointer!important;transition:box-shadow .15s,transform .15s!important}\nhtml body .spx .isl-act .acct>summary:hover,html body .spx .isl-act .acct[open]>summary{box-shadow:inset 0 0 0 1.5px #14708C,0 6px 16px rgba(20,112,140,.18)!important;transform:translateY(-1px)}\nhtml body .spx .isl-act .acct>summary:focus-visible{outline:2px solid #14708C!important;outline-offset:2px!important}\nhtml body .spx .isl-act .acct .av{width:36px!important;height:36px!important;background:#14708C!important;color:#fff!important;font-size:15px!important;font-weight:700!important}\nhtml body .spx .isl-act .acct-name{display:block!important;max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:14px;font-weight:600;color:#1D2427}\nhtml body .spx .isl-act .acct-chev{display:block!important;flex-shrink:0;color:#14708C;transition:transform .2s}\nhtml body .spx .isl-act .acct[open] .acct-chev{transform:rotate(180deg)}\n@media (min-width:641px){\n \/* Streak: ohne runde Zahl, Flamme + zwei Zeilen *\/\n html.spx-member body .spx .isl-grp .isl-act .gp{display:flex!important;align-items:center!important;gap:9px!important;height:40px!important;padding:0 12px 0 10px!important;border-radius:12px!important;background:transparent!important;box-shadow:none!important;color:#1D2427!important;text-decoration:none!important;transition:background .15s!important}\n html.spx-member body .spx .isl-grp .isl-act .gp:hover{background:rgba(20,112,140,.07)!important}\n html body .spx .isl-act .gp-fl{flex-shrink:0;color:#E89A00}\n html body .spx .isl-act .gp.done .gp-fl{fill:#FFCF33}\n html body .spx .isl-act .gp-txt{display:flex!important;flex-direction:column;line-height:1.2}\n html body .spx .isl-act .gp-top{font-size:13.5px;font-weight:700;color:#1D2427!important}\n html body .spx .isl-act .gp-bot{font-size:12px;font-weight:500;color:#6A7477!important}\n html body .spx .isl-act .gp-bot .ac-val{font-weight:700;color:#14708C}\n}\n@media (min-width:901px){\n html.spx-member body .spx .isl-grp{gap:44px!important}\n html.spx-member body .spx .isl-grp .isl-act{gap:8px!important;padding:0 8px 0 10px!important;background:rgba(255,255,255,.86)!important}\n html.spx-member body .spx .isl-grp .isl-nav{background:rgba(255,255,255,.86)!important}\n html.spx-member .spx .ia-sep{display:block;flex-shrink:0;width:1px;height:26px;background:rgba(20,112,140,.16)}\n}\n@media (max-width:1020px){\n html body .spx .isl-act .gp-bot{display:none}\n html body .spx .isl-act .acct-name{display:none!important}\n html body .spx .isl-act .acct>summary{padding:0 10px 0 4px!important}\n}\n<\/style>\n<div class=\"spx spx-top\">\n<style>html body.home .spx a.logo-free,html body.home .spx a.logo-free:hover{filter:none!important}html body.home .spx a.logo-free{width:130px!important;height:90px!important}@media (max-width:767px){html body.home .spx a.logo-free{width:96px!important;height:66px!important}}<\/style><input type=\"checkbox\" id=\"spx-isl\" class=\"nav-toggle sr\" aria-label=\"Toggle menu\">\n<a class=\"logo-free\" href=\"https:\/\/sofapiano.com\/\"><span class=\"logo-dot\" aria-hidden=\"true\"><\/span>sofapiano<\/a>\n<header class=\"nav\"><div class=\"nav-in\">\n <div class=\"isl-grp\">\n <nav class=\"isl isl-nav\" aria-label=\"Main\">\n  <div class=\"dd g-only\">\n   <a class=\"nl\" href=\"https:\/\/sofapiano.com\/exercises\/\">Exercises <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"m6 9 6 6 6-6\"\/><\/svg><\/a>\n   <div class=\"panel tools-p ex-p\">\n    <a class=\"tl ex-mine\" style=\"--c:#6EC1E4\" data-lvl-link=\"sentences\" href=\"https:\/\/sofapiano.com\/exercises\/\"><i class=\"lv ex-lvt\"><\/i><b>Mixed Translations<\/b><small>Sentences from daily life<\/small><\/a>\n    <a class=\"tl ex-mine\" style=\"--c:#FFCF33\" data-lvl-link=\"grammar\" href=\"https:\/\/sofapiano.com\/exercises\/\"><i class=\"lv ex-lvt\"><\/i><b>Grammar-Specific Translations<\/b><small>Target your weak spot<\/small><\/a>\n    <div class=\"ex-col\">\n     <div class=\"ex-hd\"><span><b>Mixed Translations<\/b><small>Sentences from daily life<\/small><\/span><\/div>\n     <div class=\"ex-lv\"><a class=\"ex-t\" style=\"--c:#E3F5FC\" href=\"https:\/\/sofapiano.com\/a1-mixed-translations\/\">A1<\/a><a class=\"ex-t\" style=\"--c:#6EC1E4\" href=\"https:\/\/sofapiano.com\/a2-mixed-translations\/\">A2<\/a><a class=\"ex-t\" style=\"--c:#14708C;--f:#FFFFFF\" href=\"https:\/\/sofapiano.com\/b1-mixed-translations\/\">B1<\/a><a class=\"ex-t\" style=\"--c:#FFCF33\" href=\"https:\/\/sofapiano.com\/b2-mixed-translations\/\">B2<\/a><\/div>\n    <\/div>\n    <div class=\"ex-col\">\n     <div class=\"ex-hd\"><span><b>Grammar-Specific Translations<\/b><small>Target your weak spot<\/small><\/span><\/div>\n     <div class=\"ex-lv\"><a class=\"ex-t\" style=\"--c:#E3F5FC\" href=\"https:\/\/sofapiano.com\/a1-grammar-specific-translations\/\">A1<\/a><a class=\"ex-t\" style=\"--c:#6EC1E4\" href=\"https:\/\/sofapiano.com\/a2-grammar-specific-translations\/\">A2<\/a><a class=\"ex-t\" style=\"--c:#14708C;--f:#FFFFFF\" href=\"https:\/\/sofapiano.com\/b1-grammar-specific-translations\/\">B1<\/a><a class=\"ex-t\" style=\"--c:#FFCF33\" href=\"https:\/\/sofapiano.com\/b2-grammar-specific-translations\/\">B2<\/a><\/div>\n    <\/div>\n    <div class=\"panel-foot\"><a href=\"https:\/\/sofapiano.com\/level-test\/\">Not sure? Find your level \u2192<\/a><\/div>\n   <\/div>\n  <\/div>\n  <div class=\"dd mb-only\">\n   <a class=\"nl\" data-lvl-link=\"sentences\" href=\"https:\/\/sofapiano.com\/exercises\/\">Practise <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"m6 9 6 6 6-6\"\/><\/svg><\/a>\n   <div class=\"panel tools-p\">\n    <a class=\"tl\" style=\"--c:#6EC1E4\" data-lvl-link=\"sentences\" href=\"https:\/\/sofapiano.com\/exercises\/\"><i><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 12a8 8 0 0 1-11.6 7.1L4 20l1-4.6A8 8 0 1 1 21 12z\"\/><\/svg><\/i><b>Mixed Translations<\/b><small>Your level <span class=\"dk-tag\"><\/span><\/small><\/a>\n    <a class=\"tl\" style=\"--c:#14708C;--f:#FFFFFF\" data-lvl-link=\"grammar\" href=\"https:\/\/sofapiano.com\/exercises\/\"><i><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M4 19V5a2 2 0 0 1 2-2h12v18H6a2 2 0 0 1-2-2zM8 7h6\"\/><\/svg><\/i><b>Grammar-Specific Translations<\/b><small>Your level <span class=\"dk-tag\"><\/span><\/small><\/a>\n   <\/div>\n  <\/div>\n  <div class=\"dd\">\n   <a class=\"nl\" href=\"https:\/\/sofapiano.com\/learning-tools\/\">Tools <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"m6 9 6 6 6-6\"\/><\/svg><\/a>\n   <div class=\"panel tools-p\">\n    <a class=\"tl\" style=\"--c:#6EC1E4\" href=\"https:\/\/sofapiano.com\/listening-trainer\/\"><i><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 14v-2a9 9 0 0 1 18 0v2M3 14h3v6H3zM18 14h3v6h-3z\"\/><\/svg><\/i><b>Listening Trainer<\/b><small>Train your ear<\/small><\/a>\n    <a class=\"tl\" style=\"--c:#FFCF33\" href=\"https:\/\/sofapiano.com\/word-context-search\/\"><i><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M11 4a7 7 0 1 0 0 14 7 7 0 0 0 0-14zM21 21l-5-5\"\/><\/svg><\/i><b>Word Context Search<\/b><small>Words in real sentences<\/small><\/a>\n    <a class=\"tl\" style=\"--c:#F3A08C\" href=\"https:\/\/sofapiano.com\/word-video-search\/\"><i><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 6h12v12H3zM15 10l6-3v10l-6-3\"\/><\/svg><\/i><b>Word Video Search<\/b><small>Hear it from natives<\/small><\/a>\n    <a class=\"tl\" style=\"--c:#9BE38A\" href=\"https:\/\/sofapiano.com\/synonym-finder\/\"><i><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M7 7h10M7 7l3-3M7 7l3 3M17 17H7M17 17l-3-3M17 17l-3 3\"\/><\/svg><\/i><b>Synonym Finder<\/b><small>Natural alternatives<\/small><\/a>\n    <a class=\"tl\" style=\"--c:#14708C;--f:#FFFFFF\" href=\"https:\/\/sofapiano.com\/level-test\/\"><i><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M9 11l3 3 8-8M20 12v7a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h9\"\/><\/svg><\/i><b>Level test<\/b><small>A1 to B2 in a few minutes<\/small><\/a>\n    <a class=\"tl\" style=\"--c:#C9B6F2\" href=\"https:\/\/sofapiano.com\/workbook\/\"><i><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M4 5a2 2 0 0 1 2-2h13v16H6a2 2 0 0 0-2 2zM4 19V5M8 7h7\"\/><\/svg><\/i><b>Workbook<\/b><small>Practise by hand<\/small><\/a>\n    <a class=\"tl mb-only\" style=\"--c:#E3F5FC\" href=\"https:\/\/sofapiano.com\/my-sentences\/\"><i><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M6 3h12v18l-6-4-6 4z\"\/><\/svg><\/i><b>Saved Sentences<\/b><small>Your personal list<\/small><\/a>\n   <\/div>\n  <\/div>\n  <div class=\"dd g-only\">\n   <button type=\"button\" class=\"nl\">About <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"m6 9 6 6 6-6\"\/><\/svg><\/button>\n   <div class=\"panel tools-p\">\n    <a class=\"tl\" style=\"--c:#FFCF33\" href=\"https:\/\/sofapiano.com\/membership-join\/\"><i><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M12 3l2.6 5.6 6.1.7-4.5 4.2 1.2 6L12 16.6 6.6 19.5l1.2-6L3.3 9.3l6.1-.7z\"\/><\/svg><\/i><b>Membership<\/b><small>Free and Plus compared<\/small><\/a>\n    <a class=\"tl\" style=\"--c:#9BE38A\" href=\"https:\/\/sofapiano.com\/faq\/\"><i><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M9.1 9a3 3 0 0 1 5.8 1c0 2-3 3-3 3M12 17h.01M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20z\"\/><\/svg><\/i><b>FAQ<\/b><small>Questions and answers<\/small><\/a>\n    <a class=\"tl\" style=\"--c:#E3F5FC\" href=\"https:\/\/sofapiano.com\/contact\/\"><i><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M4 5h16v14H4zM4 6l8 7 8-7\"\/><\/svg><\/i><b>Contact<\/b><small>Write to us<\/small><\/a>\n    <a class=\"tl\" style=\"--c:#6EC1E4\" href=\"https:\/\/sofapiano.com\/blog\/\"><i><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M4 20h4L19 9l-4-4L4 16zM13 7l4 4\"\/><\/svg><\/i><b>Blog<\/b><small>Tips and real German<\/small><\/a>\n   <\/div>\n  <\/div>\n  <div class=\"dd mb-only\">\n   <button type=\"button\" class=\"nl\">About <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"m6 9 6 6 6-6\"\/><\/svg><\/button>\n   <div class=\"panel tools-p\">\n    <a class=\"tl\" style=\"--c:#9BE38A\" href=\"https:\/\/sofapiano.com\/quiz\/\"><i><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M9.1 9a3 3 0 0 1 5.8 1c0 2-3 3-3 3M12 17h.01M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20z\"\/><\/svg><\/i><b>Quiz<\/b><small>Test what you know<\/small><\/a>\n    <a class=\"tl\" style=\"--c:#6EC1E4\" href=\"https:\/\/sofapiano.com\/blog\/\"><i><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M4 20h4L19 9l-4-4L4 16zM13 7l4 4\"\/><\/svg><\/i><b>Blog<\/b><small>Tips and real German<\/small><\/a>\n    <a class=\"tl\" style=\"--c:#F3A08C\" href=\"https:\/\/sofapiano.com\/level-test\/\"><i><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M9 11l3 3 8-8M20 12v7a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h9\"\/><\/svg><\/i><b>Level test<\/b><small>Check your level again<\/small><\/a>\n   <\/div>\n  <\/div>\n  <div class=\"m-only\">\n   <a class=\"nl g-only\" href=\"https:\/\/sofapiano.com\/membership-login\/\">Log in<\/a>\n   <a class=\"nl mb-only\" href=\"https:\/\/sofapiano.com\/membership-login\/#dt-1\">My dashboard<\/a>\n   <a class=\"nl mb-only free-only\" href=\"https:\/\/sofapiano.com\/membership-join\/\">Upgrade to Plus<\/a>\n   <a class=\"nl mb-only\" href=\"https:\/\/sofapiano.com\/?swpm-logout=true\">Log out<\/a>\n   <a class=\"nl\" href=\"https:\/\/sofapiano.com\/es\/\">Espa\u00f1ol<\/a>\n  <\/div>\n <\/nav>\n <div class=\"isl isl-act\">\n  <a class=\"lang g-only\" href=\"https:\/\/sofapiano.com\/es\/\" aria-label=\"Espa\u00f1ol\">ES<\/a>\n  <a class=\"login g-only\" href=\"https:\/\/sofapiano.com\/membership-login\/\">Log in<\/a>\n  <a class=\"cta g-only\" href=\"https:\/\/sofapiano.com\/membership-join\/\">Create free account<\/a>\n  <details class=\"lvp mb-only\">\n   <summary aria-label=\"Your level\"><span class=\"lvp-w\">Level <\/span><span class=\"dk-tag\"><\/span><svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"m6 9 6 6 6-6\"\/><\/svg><\/summary>\n   <div class=\"lvp-p\">\n    <p class=\"pt\">YOUR LEVEL<\/p>\n    <button type=\"button\" data-lv=\"A1\" aria-pressed=\"false\"><span class=\"lv-ic\" style=\"--c:#E3F5FC\">A1<\/span><span class=\"lv-t\"><b>Beginner<\/b><small>Order food, ask questions<\/small><\/span><\/button>\n    <button type=\"button\" data-lv=\"A2\" aria-pressed=\"false\"><span class=\"lv-ic\" style=\"--c:#6EC1E4\">A2<\/span><span class=\"lv-t\"><b>Elementary<\/b><small>Your day, past and plans<\/small><\/span><\/button>\n    <button type=\"button\" data-lv=\"B1\" aria-pressed=\"false\"><span class=\"lv-ic\" style=\"--c:#14708C;--f:#FFFFFF\">B1<\/span><span class=\"lv-t\"><b>Intermediate<\/b><small>Reasons, stories, opinions<\/small><\/span><\/button>\n    <button type=\"button\" data-lv=\"B2\" aria-pressed=\"false\"><span class=\"lv-ic\" style=\"--c:#0E1A20;--f:#FFFFFF\">B2<\/span><span class=\"lv-t\"><b>Upper intermediate<\/b><small>Complex topics, fluently<\/small><\/span><\/button>\n    <a href=\"https:\/\/sofapiano.com\/level-test\/\">Not sure? Take the level test \u2192<\/a>\n   <\/div>\n  <\/details>\n  <span class=\"ia-sep mb-only\" aria-hidden=\"true\"><\/span>\n  <a class=\"gp mb-only spx-goal\" href=\"https:\/\/sofapiano.com\/membership-login\/#dt-1\" aria-label=\"Daily goal\">\n   <svg class=\"gp-fl\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M12 22c4 0 7-3 7-7 0-4-3-6-4-10-2 2-3 4-3 6-1-1-2-2-2-4-2 2-5 5-5 8 0 4 3 7 7 7z\"\/><\/svg>\n   <span class=\"gp-txt\"><span class=\"gp-top\"><span class=\"gp-s\">0<\/span>-day streak<\/span><span class=\"gp-bot\"><span class=\"gp-gl\">Daily goal<\/span> <span class=\"ac-val\">0 \/ 10<\/span><\/span><\/span>\n  <\/a>\n  <span class=\"ia-sep mb-only\" aria-hidden=\"true\"><\/span>\n  <details class=\"acct mb-only\">\n   <summary aria-label=\"Account menu\" title=\"Open account menu\"><span class=\"av ac-init\">S<\/span><span class=\"acct-name ac-nm\">Account<\/span><svg class=\"acct-chev\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"m6 9 6 6 6-6\"\/><\/svg><\/summary>\n   <div class=\"acct-p\">\n    <div class=\"ac-card\">\n     <div class=\"ac-top\"><span class=\"ac-nm\">Account<\/span><span class=\"ac-badge\">PLUS<\/span><\/div>\n     <div class=\"ac-row\"><span>Daily goal<\/span><b class=\"ac-val\">0 \/ 10<\/b><\/div>\n     <div class=\"ac-bar\"><i><\/i><\/div>\n     <div class=\"ac-note\">Loading your progress \u2026<\/div>\n     <a class=\"ac-go\" href=\"https:\/\/sofapiano.com\/membership-login\/#dt-2\">Continue practising<\/a>\n    <\/div>\n    <a class=\"ac-l\" href=\"https:\/\/sofapiano.com\/membership-login\/#dt-1\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 3h7v9H3zM14 3h7v5h-7zM14 12h7v9h-7zM3 16h7v5H3z\"\/><\/svg>My dashboard<\/a>\n    <a class=\"ac-l\" href=\"https:\/\/sofapiano.com\/membership-login\/#dt-3\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M6 3h12v18l-6-4-6 4z\"\/><\/svg>Saved Sentences<\/a>\n    <a class=\"ac-l\" href=\"https:\/\/sofapiano.com\/membership-login\/#dt-4\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M4 19V5a2 2 0 0 1 2-2h12v18H6a2 2 0 0 1-2-2zM8 7h6\"\/><\/svg>Grammar tracker<\/a>\n    <a class=\"ac-l\" href=\"https:\/\/sofapiano.com\/membership-login\/#dt-5\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M9 11l3 3 8-8M20 12v7a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h9\"\/><\/svg>Test results<\/a>\n    <a class=\"ac-l\" href=\"https:\/\/sofapiano.com\/membership-login\/#dt-8\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M4 20V10M10 20V4M16 20v-8M22 20H2\"\/><\/svg>Statistics<\/a>\n    <a class=\"ac-l\" href=\"https:\/\/sofapiano.com\/membership-login\/#dt-9\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM4 21a8 8 0 0 1 16 0\"\/><\/svg>Account &amp; membership<\/a>\n    <a class=\"ac-l free-only\" href=\"https:\/\/sofapiano.com\/membership-join\/\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M12 3l2.6 5.6 6.1.7-4.5 4.2 1.2 6L12 16.6 6.6 19.5l1.2-6L3.3 9.3l6.1-.7z\"\/><\/svg>Upgrade to Plus<\/a>\n    <div class=\"ac-hr\"><\/div>\n    <a class=\"ac-l out\" href=\"https:\/\/sofapiano.com\/?swpm-logout=true\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4M10 17l-5-5 5-5M5 12h11\"\/><\/svg>Log out<\/a>\n   <\/div>\n  <\/details>\n  <label for=\"spx-isl\" class=\"burger\" aria-hidden=\"true\"><span><\/span><span><\/span><\/label>\n <\/div>\n <\/div>\n<\/div>\n<\/header>\n<\/div>\n<script>\n(function(){\n document.addEventListener('click', function (e) {\n  var d = document.querySelector('.spx-top .lvp[open]');\n  if (!d) return;\n  if (e.target.closest('[data-lv]')) { d.removeAttribute('open'); return; }\n  if (!d.contains(e.target)) d.removeAttribute('open');\n });\n})();\n<\/script>\n<style>\n\/* ===== Update 28.10.: \u00dcbungs-Men\u00fc mit vier gro\u00dfen Level-K\u00e4sten, helleres Konto-Men\u00fc ===== *\/\n.spx .lv-panel{width:680px;padding:14px}\n.spx .lv-big{gap:10px}\n.spx .lv-big .lvl{min-height:180px;padding:18px 16px 14px;gap:2px;border-radius:18px}\n.spx .lv-big .lvl b{font-size:42px;letter-spacing:-1px}\n.spx .lv-big .lvl small{margin-bottom:auto;padding-bottom:16px;font-size:12.5px;font-weight:600}\n.spx .lv-big .lvl a{display:flex;justify-content:space-between;align-items:center;padding:8px 0;font-size:13.5px;font-weight:700;border-top:1px solid rgba(14,26,32,.12)}\n.spx .lv-big .lvl a::after{content:\"\u2192\";font-weight:700}\n.spx .lv-big .lvl[style*=\"#14708C\"] a{border-top-color:rgba(255,255,255,.25)}\n.spx .lv-big .lvl a:hover{text-decoration:none;opacity:.75}\n.spx .ac-card{background:#E2F0F4;color:var(--ink)}\n.spx .ac-card .ac-badge{background:#14708C;color:#fff}\n.spx .ac-card .ac-bar{background:rgba(20,112,140,.15)}\n.spx .ac-card .ac-bar i{background:#14708C}\n.spx .ac-card .ac-note{color:var(--muted)}\n.spx .acct-p{gap:0;padding:8px}\n.spx .acct-p .ac-l{padding:6px 10px;gap:10px;font-size:13.5px}\n.spx .acct-p .ac-l svg{width:32px;height:32px;padding:8px;border-radius:10px}\n.spx .acct-p .ac-hr{margin:3px 8px}\n@media (max-width:1020px){.spx .lv-panel{width:auto}.spx .lv-big .lvl{min-height:0}}\n\/* ===== Update 03.11.: \u00dcbungs-Men\u00fc im Stil von Tools\/About, Workbook unter Tools ===== *\/\n.spx .ex-p{width:660px}\n.spx .ex-p .tl.ex{grid-template-columns:38px 1fr;align-items:center}\n.spx .ex-p .tl.ex i{grid-row:auto}\n.spx .ex-p .tl.ex b{padding-top:1px}\n.spx .ex-p .ex-l{display:flex;flex-direction:column;gap:7px;margin-top:0}\n.spx .ex-p .tl.ex{padding:14px 10px!important}\n.spx .ex-p .tl.ex i.lv{font-size:19px!important}\nhtml body .spx .ex-p .ex-l a{display:inline-flex;align-items:center;gap:6px;width:fit-content;padding:2px 0;font-size:13.5px;font-weight:500;line-height:1.3;white-space:nowrap;color:#1D2427!important}\n.spx .ex-p .ex-l a::after{content:\"\u2192\";font-weight:700;transition:transform .15s}\nhtml body .spx .ex-p .ex-l a:hover{color:#1D2427!important;text-decoration:underline;text-underline-offset:3px}\n.spx .ex-p .ex-l a:hover::after{transform:translateX(3px)}\n.spx .ex-p .panel-foot{grid-column:1 \/ -1;margin-top:6px}\n@media (max-width:900px){.spx .ex-p{width:auto}}\n.spx .ex-p .ex-mine{display:none}\n.spx .ex-p.ex-one{width:620px}\n.spx .ex-p .ex-mine b{white-space:nowrap}\n.spx .ex-p.ex-one .ex-mine{display:grid}\n.spx .ex-p.ex-one .tl.ex,.spx .ex-p.ex-one .panel-foot{display:none!important}\n@media (max-width:900px){.spx .ex-p.ex-one{width:auto}}\n\/* ===== Update 03.11. (2): \u00dcbungs-Men\u00fc f\u00fcr G\u00e4ste \u2013 oben zwei K\u00e4sten Mixed \/ Grammar, darunter je A1\u2013B2 zum Anklicken ===== *\/\n.spx .ex-p{width:600px;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}\n.spx .ex-col{display:flex;flex-direction:column;gap:12px;padding:12px;border-radius:18px;background:#F4F8FA;box-shadow:inset 0 0 0 1px rgba(20,112,140,.10)}\n.spx .ex-hd{flex:1;display:flex;align-items:center;gap:12px;padding:0 2px 12px;border-bottom:1px solid rgba(20,112,140,.12)}\n.spx .ex-hd i{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:38px;height:38px;border-radius:12px;background:var(--c);color:var(--f,#0E1A20);font-style:normal}\n.spx .ex-hd span{min-width:0}\nhtml body .spx .ex-hd b{display:block;font-size:14.5px;line-height:1.25;color:#1D2427!important}\nhtml body .spx .ex-hd small{display:block;margin-top:1px;font-size:12.5px;line-height:1.3;color:#6A7477!important}\n.spx .ex-lv{display:flex;flex-wrap:wrap;gap:8px;padding:0 2px}\nhtml body .spx .ex-lv a.ex-t{display:flex;align-items:center;justify-content:center;width:38px;height:38px;border-radius:12px;background:var(--c);color:var(--f,#0E1A20)!important;font-family:'Fraunces',Georgia,serif;font-size:15px;font-weight:600;line-height:1;text-decoration:none!important;box-shadow:0 1px 4px rgba(14,26,32,.12);transition:transform .15s,box-shadow .15s}\nhtml body .spx .ex-lv a.ex-t:hover,html body .spx .ex-lv a.ex-t:focus-visible{transform:translateY(-2px);box-shadow:0 8px 18px rgba(14,26,32,.26);color:var(--f,#0E1A20)!important}\n.spx .ex-p.ex-one .ex-col{display:none!important}\n@media (max-width:900px){\n .spx .ex-p{width:auto;grid-template-columns:minmax(0,1fr)}\n}\n<\/style>\n<script id=\"spx-i18n\">\n\/* SPX: Sprach-Korrekturen. 1) Cookie-Banner in Seitensprache (EN\/ES) statt Deutsch.\n   2) Kontaktformular-Beschriftungen. 3) Spanische Texte f\u00fcr Men\u00fc, Footer und Hauptseiten,\n   solange sie in TranslatePress noch nicht \u00fcbersetzt sind (bereits \u00fcbersetzte Texte bleiben unber\u00fchrt). *\/\n(function () {\n  var p = location.pathname, ES = (p === '\/es' || p.indexOf('\/es\/') === 0);\n\n  var BANNER = ES ? {\n    '.cmplz-title': 'Gestionar el consentimiento',\n    '.cmplz-message': 'Para ofrecerte la mejor experiencia usamos tecnolog\u00edas como las cookies para almacenar y\/o acceder a informaci\u00f3n del dispositivo. Si aceptas, podremos procesar datos como el comportamiento de navegaci\u00f3n o identificadores \u00fanicos en este sitio. Si no aceptas o retiras tu consentimiento, algunas funciones pueden verse afectadas.',\n    '.cmplz-always-active': 'Siempre activas',\n    '.cmplz-description-functional': 'El almacenamiento o acceso t\u00e9cnico es estrictamente necesario para el fin leg\u00edtimo de permitir el uso de un servicio solicitado expresamente por el usuario, o con el \u00fanico fin de transmitir una comunicaci\u00f3n a trav\u00e9s de una red.',\n    '.cmplz-description-preferences': 'El almacenamiento o acceso t\u00e9cnico es necesario para guardar preferencias que no ha solicitado el usuario.',\n    '.cmplz-description-statistics': 'El almacenamiento o acceso t\u00e9cnico que se utiliza exclusivamente con fines estad\u00edsticos.',\n    '.cmplz-description-statistics-anonymous': 'El almacenamiento o acceso t\u00e9cnico que se utiliza exclusivamente con fines estad\u00edsticos an\u00f3nimos.',\n    '.cmplz-description-marketing': 'El almacenamiento o acceso t\u00e9cnico es necesario para crear perfiles de usuario, enviar publicidad o rastrear al usuario en uno o varios sitios web con fines de marketing similares.',\n    '.cmplz-manage-options': 'Gestionar opciones',\n    '.cmplz-manage-third-parties': 'Gestionar servicios',\n    '.cmplz-accept': 'Aceptar',\n    '.cmplz-deny': 'Rechazar',\n    '.cmplz-view-preferences': 'Ver preferencias',\n    '.cmplz-save-preferences': 'Guardar preferencias'\n  } : {\n    '.cmplz-title': 'Manage consent',\n    '.cmplz-message': 'To give you the best experience, we use technologies like cookies to store and\/or access device information. Consenting allows us to process data such as browsing behaviour or unique IDs on this site. Not consenting or withdrawing consent may affect certain features and functions.',\n    '.cmplz-always-active': 'Always active',\n    '.cmplz-description-functional': 'The technical storage or access is strictly necessary for the legitimate purpose of enabling the use of a specific service explicitly requested by the user, or for the sole purpose of carrying out the transmission of a communication over an electronic network.',\n    '.cmplz-description-preferences': 'The technical storage or access is necessary for the legitimate purpose of storing preferences that are not requested by the user.',\n    '.cmplz-description-statistics': 'The technical storage or access that is used exclusively for statistical purposes.',\n    '.cmplz-description-statistics-anonymous': 'The technical storage or access that is used exclusively for anonymous statistical purposes.',\n    '.cmplz-description-marketing': 'The technical storage or access is required to create user profiles to send advertising, or to track the user on a website or across several websites for similar marketing purposes.',\n    '.cmplz-manage-options': 'Manage options',\n    '.cmplz-manage-third-parties': 'Manage services',\n    '.cmplz-accept': 'Accept',\n    '.cmplz-deny': 'Deny',\n    '.cmplz-view-preferences': 'View preferences',\n    '.cmplz-save-preferences': 'Save preferences'\n  };\n  var CATS = ES\n    ? { 'Funktional': 'Funcionales', 'Pr\u00e4ferenzen': 'Preferencias', 'Statistiken': 'Estad\u00edsticas', 'Marketing': 'Marketing' }\n    : { 'Funktional': 'Functional', 'Pr\u00e4ferenzen': 'Preferences', 'Statistiken': 'Statistics', 'Marketing': 'Marketing' };\n\n  var FORM = ES\n    ? { 'your-name': 'Nombre', 'your-email': 'Correo electr\u00f3nico', 'your-subject': 'Asunto', 'your-message': 'Mensaje' }\n    : { 'your-name': 'Name', 'your-email': 'Email address', 'your-subject': 'Subject', 'your-message': 'Message' };\n\n  var D = {\n    'Beginner': 'Principiante', 'Elementary': 'Elemental', 'Intermediate': 'Intermedio', 'Upper intermediate': 'Intermedio alto',\n    'Everyday sentences': 'Frases cotidianas', 'Everyday Sentences': 'Frases cotidianas', 'Mixed Translations': 'Traducciones mixtas', 'Mixed translations': 'Traducciones mixtas', 'Grammar-Specific Translations': 'Traducciones gramaticales', 'Grammar-specific translations': 'Traducciones gramaticales',\n    'Grammar in context': 'Gram\u00e1tica en contexto', 'Grammar in Context': 'Gram\u00e1tica en contexto',\n    'Exercises': 'Ejercicios', 'Practise': 'Practicar', 'PRACTISE': 'PRACTICAR', 'Your level': 'Tu nivel', 'YOUR LEVEL': 'TU NIVEL', 'Level': 'Nivel',\n    'Tools': 'Herramientas', 'TOOLS': 'HERRAMIENTAS', 'Train your ear': 'Entrena tu o\u00eddo', 'Words in real sentences': 'Palabras en frases reales',\n    'Hear it from natives': 'Esc\u00fachalo de nativos', 'Synonym Finder': 'Buscador de sin\u00f3nimos', 'Natural alternatives': 'Alternativas naturales',\n    'Workbooks': 'Cuadernos', 'Workbook': 'Cuaderno', 'Practise by hand': 'Practica a mano', 'Saved Sentences': 'Frases guardadas', 'Your personal list': 'Tu lista personal',\n    'More': 'M\u00e1s', 'About': 'Sobre nosotros', 'All topics mixed': 'Todos los temas mezclados', 'Sentences from daily life': 'Frases del d\u00eda a d\u00eda', 'Target your weak spot': 'Trabaja tu punto d\u00e9bil', 'One grammar topic at a time': 'Un tema de gram\u00e1tica a la vez', 'Pricing': 'Precios', 'Memberships': 'Suscripciones', 'Free and Plus compared': 'Free y Plus comparados', 'Tips and real German': 'Consejos y alem\u00e1n real',\n    'Find my level': 'Descubrir mi nivel', 'A1 to B2 in a few minutes': 'De A1 a B2 en pocos minutos', 'Questions and answers': 'Preguntas y respuestas',\n    'Write to us': 'Escr\u00edbenos', 'Test what you know': 'Pon a prueba lo que sabes', 'Level test': 'Test de nivel', 'Check your level again': 'Vuelve a comprobar tu nivel',\n    'Log in': 'Iniciar sesi\u00f3n', 'My dashboard': 'Mi panel', 'Upgrade to Plus': 'Pasar a Plus', 'Log out': 'Cerrar sesi\u00f3n', 'Start free': 'Empieza gratis', 'Create free account': 'Crear cuenta gratis',\n    'Order food, ask questions': 'Pedir comida, hacer preguntas', 'Your day, past and plans': 'Tu d\u00eda, el pasado y tus planes',\n    'Reasons, stories, opinions': 'Razones, historias, opiniones', 'Complex topics, fluently': 'Temas complejos, con fluidez',\n    'Not sure? Take the level test \u2192': '\u00bfNo est\u00e1s seguro? Haz el test de nivel \u2192', 'Not sure? Find your level \u2192': '\u00bfNo est\u00e1s seguro? Descubre tu nivel \u2192',\n    'All exercises \u2192': 'Todos los ejercicios \u2192', '-day streak': ' d\u00edas seguidos', 'Account': 'Cuenta', 'Daily goal': 'Objetivo diario',\n    'Loading your progress \u2026': 'Cargando tu progreso \u2026', 'Continue practising': 'Seguir practicando', 'Grammar tracker': 'Progreso gramatical',\n    'Test results': 'Resultados de tests', 'Account \\\\u0026 membership': 'Cuenta y suscripci\u00f3n',\n    'You know the words. So why won\u2019t the sentence come?': 'Conoces las palabras. \u00bfPor qu\u00e9 no sale la frase?',\n    'Learn German': 'Aprende alem\u00e1n', 'through translation.': 'traduciendo.', 'through translation': 'traduciendo',\n    'Translate real everyday sentences, get instant feedback on every word and learn German the way native speakers actually speak \u2014 from A1 to B2. Try it right now.': 'Traduce frases reales del d\u00eda a d\u00eda, recibe feedback al instante sobre cada palabra y aprende el alem\u00e1n que hablan los nativos, de A1 a B2. Pru\u00e9balo ahora mismo.',\n    'Start practising free': 'Empieza a practicar gratis', 'Create free account': 'Crear cuenta gratis', 'Try it \u2014 it\u2019s live': 'Pru\u00e9balo, \u00a1es en vivo!',\n    'What makes sofapiano different?': '\u00bfQu\u00e9 hace diferente a sofapiano?', 'phrases from real conversations.': 'frases de conversaciones reales.',\n    'authentic German.': 'alem\u00e1n aut\u00e9ntico.', 'grammar topics,': 'temas de gram\u00e1tica,', 'taught naturally.': 'ense\u00f1ados de forma natural.',\n    'Every sentence written and checked by native speakers.': 'Cada frase est\u00e1 escrita y revisada por hablantes nativos.',\n    'No textbook German': 'Nada de alem\u00e1n de libro', 'Phrases people actually use in everyday life.': 'Frases que la gente usa de verdad en su d\u00eda a d\u00eda.',\n    'No dry drills': 'Nada de ejercicios aburridos', 'Grammar sinks in through context, not rule tables.': 'La gram\u00e1tica se aprende con el contexto, no con tablas de reglas.',\n    'The moment every German learner knows': 'El momento que conoce todo estudiante de alem\u00e1n',\n    'You learned German. Then Germans started talking.': 'Aprendiste alem\u00e1n. Luego los alemanes empezaron a hablar.',\n    'Vocabulary lists, grammar tables, perfect textbook sentences \u2014 and still you freeze when a real conversation starts.': 'Listas de vocabulario, tablas de gram\u00e1tica, frases perfectas de libro\u2026 y aun as\u00ed te bloqueas cuando empieza una conversaci\u00f3n real.',\n    'That\u2019s because people don\u2019t talk like textbooks. sofapiano teaches you the German they actually use.': 'Porque la gente no habla como los libros. sofapiano te ense\u00f1a el alem\u00e1n que se usa de verdad.',\n    'Go to the exercises': 'Ir a los ejercicios', 'Textbook:': 'Libro de texto:', 'Then something changes': 'Entonces algo cambia',\n    'One sentence.': 'Una frase.', 'Five lessons at once.': 'Cinco lecciones a la vez.',\n    'When you translate a real sentence, you don\u2019t practise one rule in isolation. Vocabulary, word order, tenses and fixed phrases all come together \u2014 exactly like when you speak.': 'Cuando traduces una frase real no practicas una regla aislada. Vocabulario, orden de las palabras, tiempos verbales y expresiones fijas se juntan, igual que cuando hablas.',\n    'That\u2019s why the translation method works so well.': 'Por eso el m\u00e9todo de traducci\u00f3n funciona tan bien.',\n    'TENSE': 'TIEMPO VERBAL', 'Perfect with \u201esein\u201c': 'Perfecto con \u201esein\u201c', 'PHRASE': 'EXPRESI\u00d3N', 'A fixed expression': 'Una expresi\u00f3n fija',\n    'VERB FORM': 'FORMA VERBAL', 'Irregular participle': 'Participio irregular', 'CONNECTOR': 'CONECTOR', 'Gives a reason': 'Da una raz\u00f3n',\n    'WORD ORDER': 'ORDEN DE PALABRAS', 'Verb goes to the end': 'El verbo va al final', 'Start an exercise': 'Empezar un ejercicio',\n    'Step by step': 'Paso a paso', 'Sentence by sentence, you climb from A1 to B2.': 'Frase a frase, subes de A1 a B2.',\n    'German exercises for every level \u2014 start where you are and go up one step at a time.': 'Ejercicios de alem\u00e1n para cada nivel: empieza donde est\u00e1s y sube paso a paso.',\n    'Introduce yourself, order food, ask simple questions.': 'Pres\u00e9ntate, pide comida, haz preguntas sencillas.',\n    'Talk about your day, the past and your plans.': 'Habla de tu d\u00eda, del pasado y de tus planes.',\n    'Give reasons, tell stories, share opinions.': 'Da razones, cuenta historias, comparte opiniones.',\n    'Discuss complex topics fluently and naturally.': 'Habla de temas complejos con fluidez y naturalidad.',\n    'You\u2019re not alone': 'No est\u00e1s solo', 'Along the way, the right tools have your back.': 'Por el camino, las herramientas adecuadas te acompa\u00f1an.',\n    'Learning tools for German \u2014 for the moments when a sentence isn\u2019t enough.': 'Herramientas para aprender alem\u00e1n, para cuando una frase no basta.',\n    'Explore all tools': 'Ver todas las herramientas', 'Get the workbook': 'Conseguir el cuaderno',\n    'When you can\u2019t understand spoken German': 'Cuando no entiendes el alem\u00e1n hablado', 'Train your ear with sentences read by natural voices.': 'Entrena tu o\u00eddo con frases le\u00eddas por voces naturales.',\n    'When a word means five things': 'Cuando una palabra significa cinco cosas', 'See how a German word is really used in full sentences.': 'Mira c\u00f3mo se usa de verdad una palabra alemana en frases completas.',\n    'When you want to hear it from a native': 'Cuando quieres o\u00edrlo de un nativo', 'Hear a word spoken in real video clips.': 'Escucha una palabra en v\u00eddeos reales.',\n    'When you keep using the same word': 'Cuando siempre usas la misma palabra', 'Expand your vocabulary with natural alternatives.': 'Ampl\u00eda tu vocabulario con alternativas naturales.',\n    'When you want it to really stick': 'Cuando quieres que se te quede', 'Handwriting Workbooks': 'Cuadernos para escribir a mano',\n    'PDF workbooks \u2014 writing by hand deepens memory.': 'Cuadernos en PDF: escribir a mano refuerza la memoria.',\n    'When you\u2019re not sure where you stand': 'Cuando no sabes qu\u00e9 nivel tienes', 'German Level Test': 'Test de nivel de alem\u00e1n',\n    'Find your level objectively in a few minutes.': 'Descubre tu nivel de forma objetiva en pocos minutos.',\n    'Your choice': 'T\u00fa eliges', 'How far you go is up to you.': 'Hasta d\u00f3nde llegas depende de ti.', 'No credit card to get started.': 'Sin tarjeta de cr\u00e9dito para empezar.',\n    'Exercises A1\u2013B2, no account needed': 'Ejercicios A1\u2013B2, sin necesidad de cuenta',\n    'More grammar topics and audio with a free account': 'M\u00e1s temas de gram\u00e1tica y audio con una cuenta gratuita',\n    'Progress tracking, reminder emails, level test and all tools': 'Seguimiento del progreso, recordatorios por email, test de nivel y todas las herramientas',\n    'Cancel anytime': 'Cancela cuando quieras', 'All 80+ grammar topics and the grammar quick guide': 'Los m\u00e1s de 80 temas de gram\u00e1tica y la gu\u00eda r\u00e1pida de gram\u00e1tica',\n    'Save sentences and add your own': 'Guarda frases y a\u00f1ade las tuyas', 'Statistics dashboard and grammar tracker': 'Panel de estad\u00edsticas y progreso gramatical',\n    'A new handwriting workbook every month': 'Un cuaderno nuevo para escribir a mano cada mes', 'Get Plus': 'Conseguir Plus', 'Compare all features': 'Comparar todas las funciones',\n    'Before you set off': 'Antes de empezar', 'A few questions about learning German with sofapiano': 'Algunas preguntas sobre aprender alem\u00e1n con sofapiano',\n    'What is sofapiano?': '\u00bfQu\u00e9 es sofapiano?',\n    'sofapiano is a German learning platform based on the translation method. You translate real everyday sentences and train grammar naturally in context instead of memorising isolated rules.': 'sofapiano es una plataforma para aprender alem\u00e1n basada en el m\u00e9todo de traducci\u00f3n. Traduces frases reales del d\u00eda a d\u00eda y entrenas la gram\u00e1tica de forma natural en contexto, en lugar de memorizar reglas aisladas.',\n    'How does the translation method work?': '\u00bfC\u00f3mo funciona el m\u00e9todo de traducci\u00f3n?',\n    'You see a sentence in English or Spanish and translate it into German. Instant feedback shows which words are right, close or missing, so you understand grammar, vocabulary and sentence structure in context.': 'Ves una frase en ingl\u00e9s o en espa\u00f1ol y la traduces al alem\u00e1n. El feedback inmediato muestra qu\u00e9 palabras est\u00e1n bien, casi bien o faltan, para que entiendas la gram\u00e1tica, el vocabulario y la estructura en contexto.',\n    'Is sofapiano suitable for beginners?': '\u00bfEs sofapiano adecuado para principiantes?',\n    'Yes. Exercises start at A1 and grammar is explained step by step. Advanced learners at B1 and B2 improve fluency, sentence structure and natural everyday expressions.': 'S\u00ed. Los ejercicios empiezan en A1 y la gram\u00e1tica se explica paso a paso. En B1 y B2 mejoras la fluidez, la estructura de las frases y las expresiones naturales del d\u00eda a d\u00eda.',\n    'How much does it cost?': '\u00bfCu\u00e1nto cuesta?',\n    'You can practise for free without an account and register for free to unlock more. Plus costs \u20ac4 per month and gives you full access to all grammar topics, saved sentences, statistics and workbooks.': 'Puedes practicar gratis sin cuenta y registrarte gratis para desbloquear m\u00e1s. Plus cuesta 4 \u20ac al mes y te da acceso completo a todos los temas de gram\u00e1tica, frases guardadas, estad\u00edsticas y cuadernos.',\n    'How can I cancel my membership?': '\u00bfC\u00f3mo puedo cancelar mi suscripci\u00f3n?',\n    'You can cancel at any time with the cancellation button in your profile settings or by contacting our support.': 'Puedes cancelarla en cualquier momento con el bot\u00f3n de cancelaci\u00f3n en tu perfil o contactando con nosotros.',\n    'What makes sofapiano different from other language apps?': '\u00bfQu\u00e9 diferencia a sofapiano de otras apps de idiomas?',\n    'sofapiano focuses on real language use instead of random vocabulary. All 30,000+ sentences are written and reviewed by native speakers \u2014 no AI-generated filler.': 'sofapiano se centra en el uso real del idioma en lugar de vocabulario suelto. Las m\u00e1s de 30.000 frases est\u00e1n escritas y revisadas por nativos, sin relleno generado por IA.',\n    'All FAQs': 'Todas las preguntas', 'Contact us': 'Cont\u00e1ctanos',\n    '\u2014 with real sentences native speakers use every day.': ', con frases reales que los nativos usan cada d\u00eda.',\n    'Learning tools': 'Herramientas', 'Our story': 'Nuestra historia', 'Terms \\\\u0026 Conditions': 'T\u00e9rminos y condiciones', 'Terms of Use': 'Condiciones de uso',\n    'Exercises \u00b7 A1\u2013B2': 'Ejercicios \u00b7 A1\u2013B2', 'Choose your': 'Elige tu', 'exercise': 'ejercicio', 'Pick your level, then a format:': 'Elige tu nivel y luego un formato:',\n    'train the phrases native speakers use every day,': 'entrenan las frases que los nativos usan cada d\u00eda,',\n    'lets you choose a grammar topic and apply it in real sentences.': 'te permite elegir un tema de gram\u00e1tica y aplicarlo en frases reales.',\n    'German A1 \u00b7 Beginner': 'Alem\u00e1n A1 \u00b7 Principiante', 'German A2 \u00b7 Elementary': 'Alem\u00e1n A2 \u00b7 Elemental', 'German B1 \u00b7 Intermediate': 'Alem\u00e1n B1 \u00b7 Intermedio', 'German B2 \u00b7 Upper intermediate': 'Alem\u00e1n B2 \u00b7 Intermedio alto',\n    'membership': 'suscripci\u00f3n', 'Start with Free \u2014 upgrade to Plus whenever you want the full learning experience. No credit card to get started.': 'Empieza con Free y pasa a Plus cuando quieras la experiencia completa. Sin tarjeta de cr\u00e9dito para empezar.',\n    'Your membership': 'Tu suscripci\u00f3n', 'Progress tracking and a personal profile': 'Seguimiento del progreso y perfil personal', 'Reminder emails': 'Recordatorios por email',\n    'Level test and all learning tools': 'Test de nivel y todas las herramientas', 'Everything in Free': 'Todo lo de Free', 'Saved test results to track your progress': 'Resultados de tests guardados para seguir tu progreso',\n    '\u20ac4 \/ month': '4 \u20ac \/ mes', '\/ month': '\/ mes', 'You are a member \ud83d\ude0a': 'Ya eres miembro \ud83d\ude0a',\n    'Get in touch': 'Escr\u00edbenos', 'us': 'nosotros', 'Questions, feedback, a request for the workbook or an idea for a new exercise? Write us a message.': '\u00bfPreguntas, comentarios, quieres el cuaderno o tienes una idea para un ejercicio nuevo? Escr\u00edbenos un mensaje.',\n    'Send a message': 'Env\u00eda un mensaje', 'We read every message personally.': 'Leemos cada mensaje personalmente.', 'Maybe you\u2019ll find the': 'Quiz\u00e1 encuentres la',\n    'answer': 'respuesta', 'here': 'aqu\u00ed', 'Many questions are already answered \u2014 have a quick look before you write.': 'Muchas preguntas ya tienen respuesta: \u00e9chales un vistazo antes de escribir.',\n    'Answers sorted by topic': 'Respuestas ordenadas por tema', 'Practise German by hand': 'Practica alem\u00e1n a mano', 'Free vs. Plus': 'Free vs. Plus', 'Membership': 'Suscripci\u00f3n',\n    'Send': 'Enviar', 'Account and membership': 'Cuenta y suscripci\u00f3n', 'Terms and Conditions': 'T\u00e9rminos y condiciones',\n    'Error 404': 'Error 404'\n  };\n\n  function setText(el, t) { if (el && el.textContent.trim() !== t) el.textContent = t; }\n\n  function banner() {\n    var b = document.querySelector('.cmplz-cookiebanner'); if (!b) return;\n    Object.keys(BANNER).forEach(function (s) { b.querySelectorAll(s).forEach(function (el) { if (!el.children.length || \/cmplz-message|cmplz-title\/.test(s)) setText(el, BANNER[s]); }); });\n    b.querySelectorAll('.cmplz-category-title, .screen-reader-text').forEach(function (el) { var t = el.textContent.trim(); if (CATS[t]) el.textContent = CATS[t]; });\n  }\n\n  function form() {\n    Object.keys(FORM).forEach(function (n) {\n      var f = document.querySelector('.wpcf7 [name=\"' + n + '\"]'); if (!f) return;\n      var lab = f.closest('label'); if (!lab) return;\n      for (var i = 0; i < lab.childNodes.length; i++) { var c = lab.childNodes[i]; if (c.nodeType === 3) { if (c.textContent.trim()) { c.textContent = FORM[n] + ' '; break; } } }\n    });\n    if (ES) { var s = document.querySelector('.wpcf7 input[type=submit]'); if (s) { if (s.value === 'Send') s.value = 'Enviar'; } }\n  }\n\n  function spanish(root) {\n    if (!ES) return;\n    var w = document.createTreeWalker(root || document.body, NodeFilter.SHOW_TEXT, {\n      acceptNode: function (n) { var p = n.parentNode; if (!p || \/^(SCRIPT|STYLE|TEXTAREA|NOSCRIPT)$\/.test(p.nodeName)) return 2; if (p.closest) { if (p.closest('#trainer-container, #trainer-home, .cmplz-cookiebanner')) return 2; } return 1; }\n    });\n    var n, list = [];\n    while ((n = w.nextNode())) list.push(n);\n    list.forEach(function (n) {\n      var raw = n.textContent, t = raw.replace(\/\\s+\/g, ' ').trim().split(String.fromCharCode(38)).join('and');\n      if (t) { if (D.hasOwnProperty(t)) n.textContent = raw.replace(raw.trim(), D[t]); }\n    });\n  }\n\n  function lang() {\n    if (ES) { var lt = document.getElementById('lt-es'); if (lt) { if (!window.__spxLt) { window.__spxLt = 1; lt.checked = true; } } }\n    var here = location.pathname.replace(\/^\\\/es(\\\/|$)\/, '\/');\n    document.querySelectorAll('a[href=\"https:\/\/sofapiano.com\/es\/\"], a[href=\"\/es\/\"], a.spx-lang-sw').forEach(function (a) {\n      if (a.closest('.trp-language-switcher, .cmplz-cookiebanner')) return;\n      if (!\/^(ES|EN|Espa\u00f1ol|English)$\/.test(a.textContent.trim())) return;\n      a.classList.add('spx-lang-sw');\n      if (ES) {\n        a.href = here + location.search;\n        a.setAttribute('aria-label', 'English');\n        if (a.textContent.trim().length <= 3) a.textContent = 'EN'; else a.textContent = 'English';\n      } else {\n        a.href = '\/es' + here + location.search;\n      }\n    });\n  }\n\n  function run() { try { banner(); form(); spanish(); lang(); } catch (e) {} }\n  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', run); else run();\n  window.addEventListener('load', function () { run(); setTimeout(run, 800); });\n})();\n<\/script>\n<style id=\"spx-shell-css\">\n\/* Blogartikel, Archive, 404 (Men\u00fc wird dort per Loader aus dem alten Header-Template eingesetzt) *\/\nbody.spx-shell{background:#FBF8F2 radial-gradient(ellipse 80% 60% at 50% 0%,#FFFFFF 0%,#FBF8F2 55%,#F0EADE 100%) no-repeat!important;background-size:100% 1400px!important}\nbody.spx-shell #content,body.spx-shell main.site-main{box-sizing:border-box;width:100%!important;max-width:780px!important;margin:0 auto!important;padding:130px 20px 90px!important}\nbody.spx-shell .page-header{display:block!important;margin:0 0 22px!important;padding:0!important}\nbody.spx-shell .entry-title{display:block!important;margin:0!important;font-family:'Fraunces',Georgia,serif!important;font-size:clamp(30px,4.6vw,46px)!important;font-weight:600!important;line-height:1.12!important;letter-spacing:-.6px;color:#1D2427!important}\nbody.spx-shell .page-content,body.spx-shell .entry-content{font-family:'Inter','Segoe UI',Arial,sans-serif;font-size:17px;line-height:1.7;color:#1D2427}\nbody.spx-shell .page-content h2,body.spx-shell .entry-content h2{font-family:'Fraunces',Georgia,serif;font-weight:600;font-size:28px;line-height:1.2;letter-spacing:-.3px;margin:38px 0 12px;color:#1D2427}\nbody.spx-shell .page-content h3,body.spx-shell .entry-content h3{font-size:20px;font-weight:700;margin:28px 0 8px;color:#1D2427}\nbody.spx-shell .page-content a:not(.btn):not([class*=button]),body.spx-shell .entry-content a:not(.btn):not([class*=button]){color:#14708C;font-weight:600}\nbody.spx-shell .page-content img,body.spx-shell .entry-content img{max-width:100%;height:auto;border-radius:18px}\nbody.spx-shell .post-tags,body.spx-shell .comments-area{max-width:780px;margin-left:auto;margin-right:auto}\n.spx-404{text-align:center;padding:20px 0 40px}\n.spx-404 .k{margin:0 0 8px;font-family:'Fraunces',Georgia,serif;font-style:italic;font-size:18px;color:#14708C}\n.spx-404 h1{margin:0 0 14px;font-family:'Fraunces',Georgia,serif;font-size:clamp(34px,5vw,52px);font-weight:600;line-height:1.08;letter-spacing:-1px;color:#1D2427}\n.spx-404 h1 em{font-style:italic;font-weight:500;color:#14708C}\n.spx-404 .t{max-width:480px;margin:0 auto 24px;font-size:17px;line-height:1.6;color:#4B565A}\n.spx-404 .btns{display:flex;flex-wrap:wrap;justify-content:center;gap:10px}\n.spx-404 .btn{display:inline-flex;align-items:center;justify-content:center;min-height:50px;padding:0 24px;border-radius:999px;font:700 15px 'Inter',sans-serif;text-decoration:none}\n.spx-404 .b-teal{background:#14708C;color:#fff}.spx-404 .b-teal:hover{background:#0E5367;color:#fff}\n.spx-404 .b-ghost{background:#fff;color:#1D2427;border:1.5px solid #E5E0D6}.spx-404 .b-ghost:hover{border-color:#14708C;color:#14708C}\n@media (max-width:640px){body.spx-shell #content,body.spx-shell main.site-main{padding:110px 18px 70px!important}}\n<\/style>\n<style id=\"spx-page-bg\">\n\/* Einheitlicher Seitenhintergrund wie auf den Practice-Seiten (alle Seiten au\u00dfer Startseite) *\/\nbody:not(.home) .spx-page{background:radial-gradient(ellipse 80% 75% at 50% 0%,#FFFFFF 0%,#FBF8F2 50%,#F0EADE 100%)!important;min-height:60vh}\nbody:not(.home) .spx-page .spx,body:not(.home) .spx-page .spx .sec,body:not(.home) .spx-page .pg-head{background:transparent!important}\nbody:not(.home) .spx-page>.spx:last-child{padding-bottom:90px}\n<\/style>\n<template class=\"spx-dock-old\"><div class=\"spx spx-top\">\n<input type=\"checkbox\" id=\"spx-dock\" class=\"nav-toggle sr\" aria-label=\"Toggle menu\">\n<header class=\"nav\"><div class=\"nav-in\">\n <div class=\"dk-row1\">\n  <a class=\"logo\" href=\"https:\/\/sofapiano.com\/\"><span class=\"logo-mark\" aria-hidden=\"true\">s<\/span>sofapiano<\/a>\n  <div class=\"dk-lv dk-lv-d\" role=\"group\" aria-label=\"Your level\"><span class=\"dk-lv-l\">Your level<\/span><button type=\"button\" data-lv=\"A1\" aria-pressed=\"false\">A1<\/button><button type=\"button\" data-lv=\"A2\" aria-pressed=\"false\">A2<\/button><button type=\"button\" data-lv=\"B1\" aria-pressed=\"false\">B1<\/button><button type=\"button\" data-lv=\"B2\" aria-pressed=\"false\">B2<\/button><\/div>\n  <div class=\"nav-right\">\n   <a class=\"lang g-only\" href=\"https:\/\/sofapiano.com\/es\/\" aria-label=\"Espa\u00f1ol\">ES<\/a>\n   <a class=\"login g-only\" href=\"https:\/\/sofapiano.com\/membership-login\/\">Log in<\/a>\n   <a class=\"cta g-only\" href=\"https:\/\/sofapiano.com\/membership-join\/\">Start free<\/a>\n   <a class=\"gp mb-only spx-goal\" href=\"https:\/\/sofapiano.com\/membership-login\/#dt-1\" aria-label=\"Daily goal\">\n    <span class=\"gp-ring\"><span class=\"gp-in gp-n\">0<\/span><\/span>\n    <span class=\"gp-txt\"><span class=\"gp-main\">Daily goal<\/span><span class=\"gp-sub\">0 \/ 10<\/span><\/span>\n    <span class=\"gp-sep\" aria-hidden=\"true\"><\/span>\n    <span class=\"gp-streak\"><svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M12 22c4 0 7-3 7-7 0-4-3-6-4-10-2 2-3 4-3 6-1-1-2-2-2-4-2 2-5 5-5 8 0 4 3 7 7 7z\"\/><\/svg><span class=\"gp-s\">0<\/span><\/span>\n   <\/a>\n   <details class=\"acct mb-only\">\n    <summary aria-label=\"Account menu\"><span class=\"av ac-init\">S<\/span><span class=\"acct-name ac-nm\">Account<\/span><svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"m6 9 6 6 6-6\"\/><\/svg><\/summary>\n    <div class=\"acct-p\">\n     <div class=\"ac-card\">\n      <div class=\"ac-top\"><span class=\"ac-nm\">Account<\/span><span class=\"ac-badge\">PLUS<\/span><\/div>\n      <div class=\"ac-row\"><span>Daily goal<\/span><b class=\"ac-val\">0 \/ 10<\/b><\/div>\n      <div class=\"ac-bar\"><i><\/i><\/div>\n      <div class=\"ac-note\">Loading your progress \u2026<\/div>\n      <a class=\"ac-go\" href=\"https:\/\/sofapiano.com\/membership-login\/#dt-2\">Continue practising<\/a>\n     <\/div>\n     <a class=\"ac-l\" href=\"https:\/\/sofapiano.com\/membership-login\/#dt-1\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 3h7v9H3zM14 3h7v5h-7zM14 12h7v9h-7zM3 16h7v5H3z\"\/><\/svg>My dashboard<\/a>\n     <a class=\"ac-l\" href=\"https:\/\/sofapiano.com\/membership-login\/#dt-3\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M6 3h12v18l-6-4-6 4z\"\/><\/svg>Saved Sentences<\/a>\n     <a class=\"ac-l\" href=\"https:\/\/sofapiano.com\/membership-login\/#dt-4\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M4 19V5a2 2 0 0 1 2-2h12v18H6a2 2 0 0 1-2-2zM8 7h6\"\/><\/svg>Grammar tracker<\/a>\n     <a class=\"ac-l\" href=\"https:\/\/sofapiano.com\/membership-login\/#dt-5\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M9 11l3 3 8-8M20 12v7a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h9\"\/><\/svg>Test results<\/a>\n     <a class=\"ac-l\" href=\"https:\/\/sofapiano.com\/membership-login\/#dt-8\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M4 20V10M10 20V4M16 20v-8M22 20H2\"\/><\/svg>Statistics<\/a>\n     <a class=\"ac-l\" href=\"https:\/\/sofapiano.com\/membership-login\/#dt-9\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM4 21a8 8 0 0 1 16 0\"\/><\/svg>Account &amp; membership<\/a>\n     <div class=\"ac-hr\"><\/div>\n     <a class=\"ac-l out\" href=\"https:\/\/sofapiano.com\/?swpm-logout=true\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4M10 17l-5-5 5-5M5 12h11\"\/><\/svg>Log out<\/a>\n    <\/div>\n   <\/details>\n   <label for=\"spx-dock\" class=\"burger\" aria-hidden=\"true\"><span><\/span><span><\/span><\/label>\n  <\/div>\n <\/div>\n <nav class=\"dk-row2\" aria-label=\"Main\">\n  <div class=\"dk-lv dk-lv-m\" role=\"group\" aria-label=\"Your level\"><span class=\"dk-lv-l\">Level<\/span><button type=\"button\" data-lv=\"A1\" aria-pressed=\"false\">A1<\/button><button type=\"button\" data-lv=\"A2\" aria-pressed=\"false\">A2<\/button><button type=\"button\" data-lv=\"B1\" aria-pressed=\"false\">B1<\/button><button type=\"button\" data-lv=\"B2\" aria-pressed=\"false\">B2<\/button><\/div>\n  <div class=\"dd g-only\">\n   <a class=\"nl\" href=\"https:\/\/sofapiano.com\/exercises\/\">Exercises <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"m6 9 6 6 6-6\"\/><\/svg><\/a>\n   <div class=\"panel mega\">\n    <p class=\"pt\">CHOOSE YOUR LEVEL<\/p>\n    <div class=\"lvl-grid\">\n     <div class=\"lvl\" style=\"--c:#E3F5FC;--f:#0E1A20\"><b>A1<\/b><small>Beginner<\/small><a href=\"https:\/\/sofapiano.com\/a1-mixed-translations\/\">Sentences \u2192<\/a><a href=\"https:\/\/sofapiano.com\/a1-grammar-specific-translations\/\">Grammar \u2192<\/a><\/div>\n     <div class=\"lvl\" style=\"--c:#6EC1E4;--f:#0E1A20\"><b>A2<\/b><small>Elementary<\/small><a href=\"https:\/\/sofapiano.com\/a2-mixed-translations\/\">Sentences \u2192<\/a><a href=\"https:\/\/sofapiano.com\/a2-grammar-specific-translations\/\">Grammar \u2192<\/a><\/div>\n     <div class=\"lvl\" style=\"--c:#14708C;--f:#FFFFFF\"><b>B1<\/b><small>Intermediate<\/small><a href=\"https:\/\/sofapiano.com\/b1-mixed-translations\/\">Sentences \u2192<\/a><a href=\"https:\/\/sofapiano.com\/b1-grammar-specific-translations\/\">Grammar \u2192<\/a><\/div>\n     <div class=\"lvl\" style=\"--c:#0E1A20;--f:#FFFFFF\"><b>B2<\/b><small>Upper int.<\/small><a href=\"https:\/\/sofapiano.com\/b2-mixed-translations\/\">Sentences \u2192<\/a><a href=\"https:\/\/sofapiano.com\/b2-grammar-specific-translations\/\">Grammar \u2192<\/a><\/div>\n    <\/div>\n    <div class=\"panel-foot\"><a href=\"https:\/\/sofapiano.com\/exercises\/\">All exercises \u2192<\/a><a href=\"https:\/\/sofapiano.com\/quiz\/\">Quiz \u2192<\/a><a href=\"https:\/\/sofapiano.com\/level-test\/\">Not sure? Level test \u2192<\/a><\/div>\n   <\/div>\n  <\/div>\n  <a class=\"nl hl mb-only\" data-lvl-link=\"sentences\" href=\"https:\/\/sofapiano.com\/exercises\/\"><span class=\"dk-tag\"><\/span>Sentences<\/a>\n  <a class=\"nl mb-only\" data-lvl-link=\"grammar\" href=\"https:\/\/sofapiano.com\/exercises\/\"><span class=\"dk-tag\"><\/span>Grammar<\/a>\n  <a class=\"nl mb-only\" href=\"https:\/\/sofapiano.com\/quiz\/\">Quiz<\/a>\n  <div class=\"dd\">\n   <a class=\"nl\" href=\"https:\/\/sofapiano.com\/learning-tools\/\">Tools <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"m6 9 6 6 6-6\"\/><\/svg><\/a>\n   <div class=\"panel tools-p\">\n    <a class=\"tl\" style=\"--c:#6EC1E4\" href=\"https:\/\/sofapiano.com\/listening-trainer\/\"><i><svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 14v-2a9 9 0 0 1 18 0v2M3 14h3v6H3zM18 14h3v6h-3z\"\/><\/svg><\/i><b>Listening Trainer<\/b><small>Train your ear<\/small><\/a>\n    <a class=\"tl\" style=\"--c:#FFCF33\" href=\"https:\/\/sofapiano.com\/word-context-search\/\"><i><svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M11 4a7 7 0 1 0 0 14 7 7 0 0 0 0-14zM21 21l-5-5\"\/><\/svg><\/i><b>Word Context Search<\/b><small>Words in real sentences<\/small><\/a>\n    <a class=\"tl\" style=\"--c:#F3A08C\" href=\"https:\/\/sofapiano.com\/word-video-search\/\"><i><svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 6h12v12H3zM15 10l6-3v10l-6-3\"\/><\/svg><\/i><b>Word Video Search<\/b><small>Hear it from natives<\/small><\/a>\n    <a class=\"tl\" style=\"--c:#9BE38A\" href=\"https:\/\/sofapiano.com\/synonym-finder\/\"><i><svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M7 7h10M7 7l3-3M7 7l3 3M17 17H7M17 17l-3-3M17 17l-3 3\"\/><\/svg><\/i><b>Synonym Finder<\/b><small>Natural alternatives<\/small><\/a>\n    <a class=\"tl\" style=\"--c:#FFCF33\" href=\"https:\/\/sofapiano.com\/workbook\/\"><i><svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M4 20h4L19 9l-4-4L4 16zM13 7l4 4\"\/><\/svg><\/i><b>Workbooks<\/b><small>Practise by hand<\/small><\/a>\n    <a class=\"tl mb-only\" style=\"--c:#6EC1E4\" href=\"https:\/\/sofapiano.com\/my-sentences\/\"><i><svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M6 3h12v18l-6-4-6 4z\"\/><\/svg><\/i><b>Saved Sentences<\/b><small>Your personal list<\/small><\/a>\n   <\/div>\n  <\/div>\n  <a class=\"nl g-only\" href=\"https:\/\/sofapiano.com\/level-test\/\">Level test<\/a>\n  <a class=\"nl g-only\" href=\"https:\/\/sofapiano.com\/membership-join\/\">Pricing<\/a>\n  <a class=\"nl g-only\" href=\"https:\/\/sofapiano.com\/blog\/\">Blog<\/a>\n  <a class=\"nl mb-only\" href=\"https:\/\/sofapiano.com\/my-sentences\/\">Saved Sentences<\/a>\n  <div class=\"dk-r2r\">\n   <span class=\"dk-note g-only\">Free to start \u00b7 no credit card<\/span>\n   <a class=\"dk-upg mb-only free-only\" href=\"https:\/\/sofapiano.com\/membership-join\/\">Upgrade to Plus<\/a>\n   <a class=\"dk-dash mb-only\" href=\"https:\/\/sofapiano.com\/membership-login\/#dt-1\">My dashboard \u2192<\/a>\n  <\/div>\n  <div class=\"m-only\">\n   <a class=\"nl g-only\" href=\"https:\/\/sofapiano.com\/membership-login\/\">Log in<\/a>\n   <a class=\"nl mb-only\" href=\"https:\/\/sofapiano.com\/membership-login\/#dt-1\">My dashboard<\/a>\n   <a class=\"nl mb-only\" href=\"https:\/\/sofapiano.com\/?swpm-logout=true\">Log out<\/a>\n   <a class=\"nl\" href=\"https:\/\/sofapiano.com\/es\/\">Espa\u00f1ol<\/a>\n  <\/div>\n <\/nav>\n<\/div><\/header><\/div><\/template>\n<template class=\"spx-old-menu\"><div class=\"spx\">\n<input type=\"checkbox\" id=\"spx-menu\" class=\"nav-toggle sr\" aria-label=\"Toggle menu\">\n<header class=\"nav\">\n <div class=\"nav-in\">\n  <a class=\"logo\" href=\"https:\/\/sofapiano.com\/\"><span class=\"logo-dot\" aria-hidden=\"true\"><\/span>sofapiano<\/a>\n  <nav class=\"nav-links\" aria-label=\"Main\">\n   <div class=\"dd\">\n    <a class=\"nl\" href=\"https:\/\/sofapiano.com\/exercises\/\">Exercises <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"m6 9 6 6 6-6\"\/><\/svg><\/a>\n    <div class=\"panel mega\">\n     <p class=\"pt\">CHOOSE YOUR LEVEL<\/p>\n     <div class=\"lvl-grid\">\n       <div class=\"lvl\" style=\"--c:#E3F5FC;--f:#0E1A20\"><b>A1<\/b><small>Beginner<\/small><a href=\"https:\/\/sofapiano.com\/a1-mixed-translations\/\">Sentences \u2192<\/a><a href=\"https:\/\/sofapiano.com\/a1-grammar-specific-translations\/\">Grammar \u2192<\/a><\/div>\n       <div class=\"lvl\" style=\"--c:#6EC1E4;--f:#0E1A20\"><b>A2<\/b><small>Elementary<\/small><a href=\"https:\/\/sofapiano.com\/a2-mixed-translations\/\">Sentences \u2192<\/a><a href=\"https:\/\/sofapiano.com\/a2-grammar-specific-translations\/\">Grammar \u2192<\/a><\/div>\n       <div class=\"lvl\" style=\"--c:#14708C;--f:#FFFFFF\"><b>B1<\/b><small>Intermediate<\/small><a href=\"https:\/\/sofapiano.com\/b1-mixed-translations\/\">Sentences \u2192<\/a><a href=\"https:\/\/sofapiano.com\/b1-grammar-specific-translations\/\">Grammar \u2192<\/a><\/div>\n       <div class=\"lvl\" style=\"--c:#0E1A20;--f:#FFFFFF\"><b>B2<\/b><small>Upper int.<\/small><a href=\"https:\/\/sofapiano.com\/b2-mixed-translations\/\">Sentences \u2192<\/a><a href=\"https:\/\/sofapiano.com\/b2-grammar-specific-translations\/\">Grammar \u2192<\/a><\/div>\n     <\/div>\n     <div class=\"panel-foot\"><a href=\"https:\/\/sofapiano.com\/exercises\/\">All exercises \u2192<\/a><a href=\"https:\/\/sofapiano.com\/quiz\/\">Quiz \u2192<\/a><a href=\"https:\/\/sofapiano.com\/level-test\/\">Not sure? Level test \u2192<\/a><\/div>\n    <\/div>\n   <\/div>\n   <div class=\"dd\">\n    <a class=\"nl\" href=\"https:\/\/sofapiano.com\/learning-tools\/\">Tools <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"m6 9 6 6 6-6\"\/><\/svg><\/a>\n    <div class=\"panel tools-p\">\n      <a class=\"tl\" href=\"https:\/\/sofapiano.com\/listening-trainer\/\"><i style=\"background:#6EC1E4\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 14v-2a9 9 0 0 1 18 0v2M3 14h3v6H3zM18 14h3v6h-3z\"\/><\/svg><\/i><span><b>Listening Trainer<\/b><small>Train your ear<\/small><\/span><\/a>\n      <a class=\"tl\" href=\"https:\/\/sofapiano.com\/word-context-search\/\"><i style=\"background:#FFCF33\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M11 4a7 7 0 1 0 0 14 7 7 0 0 0 0-14zM21 21l-5-5\"\/><\/svg><\/i><span><b>Word Context Search<\/b><small>Words in real sentences<\/small><\/span><\/a>\n      <a class=\"tl\" href=\"https:\/\/sofapiano.com\/word-video-search\/\"><i style=\"background:#F3A08C\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 6h12v12H3zM15 10l6-3v10l-6-3\"\/><\/svg><\/i><span><b>Word Video Search<\/b><small>Hear it from natives<\/small><\/span><\/a>\n      <a class=\"tl\" href=\"https:\/\/sofapiano.com\/synonym-finder\/\"><i style=\"background:#9BE38A\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M7 7h10M7 7l3-3M7 7l3 3M17 17H7M17 17l-3-3M17 17l-3 3\"\/><\/svg><\/i><span><b>Synonym Finder<\/b><small>Natural alternatives<\/small><\/span><\/a>\n      <a class=\"tl\" href=\"https:\/\/sofapiano.com\/workbook\/\"><i style=\"background:#FFCF33\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M4 20h4L19 9l-4-4L4 16zM13 7l4 4\"\/><\/svg><\/i><span><b>Workbooks<\/b><small>Practise by hand<\/small><\/span><\/a>\n      <a class=\"tl\" href=\"https:\/\/sofapiano.com\/my-sentences\/\"><i style=\"background:#6EC1E4\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M6 3h12v18l-6-4-6 4z\"\/><\/svg><\/i><span><b>Saved Sentences<\/b><small>Your personal list<\/small><\/span><\/a>\n    <\/div>\n   <\/div>\n   <a class=\"nl g-only\" href=\"https:\/\/sofapiano.com\/level-test\/\">Level test<\/a>\n   <a class=\"nl g-only\" href=\"https:\/\/sofapiano.com\/membership-join\/\">Pricing<\/a>\n   <a class=\"nl g-only\" href=\"https:\/\/sofapiano.com\/blog\/\">Blog<\/a>\n   <a class=\"nl mb-only\" href=\"https:\/\/sofapiano.com\/quiz\/\">Quiz<\/a>\n   <a class=\"nl mb-only\" href=\"https:\/\/sofapiano.com\/membership-login\/#dt-1\">My dashboard<\/a>\n   <div class=\"m-only\">\n    <a class=\"nl g-only\" href=\"https:\/\/sofapiano.com\/membership-login\/\">Log in<\/a>\n    <a class=\"nl mb-only\" href=\"https:\/\/sofapiano.com\/?swpm-logout=true\">Log out<\/a>\n    <a class=\"nl\" href=\"https:\/\/sofapiano.com\/es\/\">Espa\u00f1ol<\/a>\n   <\/div>\n  <\/nav>\n  <div class=\"nav-right\">\n   <a class=\"lang g-only\" href=\"https:\/\/sofapiano.com\/es\/\" aria-label=\"Espa\u00f1ol\">ES<\/a>\n   <a class=\"login g-only\" href=\"https:\/\/sofapiano.com\/membership-login\/\">Log in<\/a>\n   <a class=\"cta g-only\" href=\"https:\/\/sofapiano.com\/membership-join\/\">Start free<\/a>\n   <a class=\"gp mb-only spx-goal\" href=\"https:\/\/sofapiano.com\/membership-login\/#dt-1\" aria-label=\"Daily goal\">\n    <span class=\"gp-ring\"><span class=\"gp-in gp-n\">0<\/span><\/span>\n    <span class=\"gp-txt\"><span class=\"gp-main\">Daily goal<\/span><span class=\"gp-sub\">0 \/ 10<\/span><\/span>\n    <span class=\"gp-sep\" aria-hidden=\"true\"><\/span>\n    <span class=\"gp-streak\"><svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M12 22c4 0 7-3 7-7 0-4-3-6-4-10-2 2-3 4-3 6-1-1-2-2-2-4-2 2-5 5-5 8 0 4 3 7 7 7z\"\/><\/svg><span class=\"gp-s\">0<\/span><\/span>\n   <\/a>\n   <details class=\"acct mb-only\">\n    <summary aria-label=\"Account menu\"><span class=\"av ac-init\">S<\/span><span class=\"acct-name ac-nm\">Account<\/span><svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"m6 9 6 6 6-6\"\/><\/svg><\/summary>\n    <div class=\"acct-p\">\n     <div class=\"ac-card\">\n      <div class=\"ac-top\"><span class=\"ac-nm\">Account<\/span><span class=\"ac-badge\">PLUS<\/span><\/div>\n      <div class=\"ac-row\"><span>Daily goal<\/span><b class=\"ac-val\">0 \/ 10<\/b><\/div>\n      <div class=\"ac-bar\"><i><\/i><\/div>\n      <div class=\"ac-note\">Loading your progress \u2026<\/div>\n      <a class=\"ac-go\" href=\"https:\/\/sofapiano.com\/membership-login\/#dt-2\">Continue practising<\/a>\n     <\/div>\n     <a class=\"ac-l\" href=\"https:\/\/sofapiano.com\/membership-login\/#dt-1\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 3h7v9H3zM14 3h7v5h-7zM14 12h7v9h-7zM3 16h7v5H3z\"\/><\/svg>My dashboard<\/a>\n     <a class=\"ac-l\" href=\"https:\/\/sofapiano.com\/membership-login\/#dt-3\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M6 3h12v18l-6-4-6 4z\"\/><\/svg>Saved Sentences<\/a>\n     <a class=\"ac-l\" href=\"https:\/\/sofapiano.com\/membership-login\/#dt-4\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M4 19V5a2 2 0 0 1 2-2h12v18H6a2 2 0 0 1-2-2zM8 7h6\"\/><\/svg>Grammar tracker<\/a>\n     <a class=\"ac-l\" href=\"https:\/\/sofapiano.com\/membership-login\/#dt-5\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M9 11l3 3 8-8M20 12v7a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h9\"\/><\/svg>Test results<\/a>\n     <a class=\"ac-l\" href=\"https:\/\/sofapiano.com\/membership-login\/#dt-8\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M4 20V10M10 20V4M16 20v-8M22 20H2\"\/><\/svg>Statistics<\/a>\n     <a class=\"ac-l\" href=\"https:\/\/sofapiano.com\/membership-login\/#dt-9\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM4 21a8 8 0 0 1 16 0\"\/><\/svg>Account &amp; membership<\/a>\n     <div class=\"ac-hr\"><\/div>\n     <a class=\"ac-l out\" href=\"https:\/\/sofapiano.com\/?swpm-logout=true\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4M10 17l-5-5 5-5M5 12h11\"\/><\/svg>Log out<\/a>\n    <\/div>\n   <\/details>\n   <label for=\"spx-menu\" class=\"burger\" aria-hidden=\"true\"><span><\/span><span><\/span><\/label>\n  <\/div>\n <\/div>\n<\/header>\n<\/div><\/template>\n<script>\n(function(){\n var CSV = 'https:\/\/docs.google.com\/spreadsheets\/d\/1pGfdVy3yDtzS56FIxiP4KsHHYuKUqPWVG18ULv9wxi4\/export?format=csv&gid=588315623';\n var TTL = 120000;\n var st = { counts: {}, target: 10, ready: false };\n var started = false;\n\n function info() { return window.wpTrainerUserInfo || null; }\n function markMember() { if (info()) document.documentElement.classList.add('spx-member'); }\n markMember();\n\n function hashTab() {\n  var h = (location.hash || '').replace('#', '');\n  if (!\/^dt-[1-9]$\/.test(h)) return;\n  var r = document.getElementById(h);\n  if (!r) return;\n  r.checked = true;\n  try { r.dispatchEvent(new Event('change', { bubbles: true })); } catch (e) {}\n  var acct = document.querySelector('.spx-top .acct');\n  if (acct) acct.removeAttribute('open');\n }\n window.addEventListener('hashchange', hashTab);\n\n function dkey(d) { return d.toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' }); }\n function norm(s) {\n  if (!s) return '';\n  var p = String(s).trim().split(' ')[0];\n  if (p.indexOf('.') !== -1) return p;\n  if (p.indexOf('-') !== -1) { var a = p.split('-'); if (a[0].length === 4) return a[2] + '.' + a[1] + '.' + a[0]; }\n  return p;\n }\n function parseLine(t) {\n  var r = [], p = '', q = false;\n  for (var i = 0; t.length > i; i++) {\n   var c = t[i];\n   if (c === '\"') { q = !q; }\n   else if (c === ',') { if (q) { p += c; } else { r.push(p.trim()); p = ''; } }\n   else if (c === '\\r' || c === '\\n') { if (q) p += c; }\n   else { p += c; }\n  }\n  r.push(p.trim());\n  return r;\n }\n function calc(txt, u) {\n  var id = String(u.id || '').trim().toLowerCase();\n  var nm = String(u.name || '').trim().toLowerCase();\n  var lines = txt.split(\/\\r?\\n\/), counts = {}, exp = null, leg = null;\n  for (var i = 1; lines.length > i; i++) {\n   if (!lines[i].trim()) continue;\n   var c = parseLine(lines[i]);\n   if (3 > c.length) continue;\n   var uid = (c[1] || '').toLowerCase(), un = (c[2] || '').toLowerCase();\n   var match = false;\n   if (uid) { if (uid === id) match = true; }\n   if (!match) { if (un) { if (un === nm) match = true; } }\n   if (!match) continue;\n   var dk = norm(c[0]);\n   counts[dk] = (counts[dk] || 0) + 1;\n   var n = parseInt(c[10] || c[3], 10);\n   if (n > 0) { if ((c[8] || '').toLowerCase() === 'tagesziel_geandert') { exp = n; } else { leg = n; } }\n  }\n  return { counts: counts, target: exp || leg || 10 };\n }\n function streak() {\n  var s = 0, d = new Date();\n  for (var i = 0; 365 > i; i++) {\n   var v = st.counts[dkey(d)] || 0;\n   if (v >= st.target) { s++; } else if (i !== 0) { break; }\n   d.setDate(d.getDate() - 1);\n  }\n  return s;\n }\n function setText(sel, val) { document.querySelectorAll('.spx-top ' + sel).forEach(function (el) { el.textContent = val; }); }\n\n function render() {\n  var u = info();\n  if (!u) return;\n  var name = String(u.name || 'Account').trim() || 'Account';\n  setText('.ac-nm', name);\n  setText('.ac-init', name.charAt(0).toUpperCase());\n  var lvl = parseInt(u.level, 10) || 1;\n  document.querySelectorAll('.spx-top .ac-badge').forEach(function (b) {\n   b.textContent = lvl >= 3 ? 'PLUS' : 'FREE';\n   b.classList.toggle('free', !(lvl >= 3));\n  });\n  if (!st.ready) return;\n  var t = st.target, today = st.counts[dkey(new Date())] || 0;\n  var pct = Math.min(100, Math.round(today * 100 \/ t));\n  var done = today >= t, s = streak();\n  var main, sub;\n  if (done) { main = 'Goal reached!'; sub = today + ' \/ ' + t; }\n  else if (today === 0) { main = 'Start today\u2019s goal'; sub = '0 \/ ' + t; }\n  else { main = today + ' \/ ' + t + ' today'; sub = (t - today) + ' to go'; }\n  document.querySelectorAll('.spx-top .spx-goal').forEach(function (el) {\n   el.style.setProperty('--p', pct);\n   el.classList.toggle('done', done);\n   el.setAttribute('aria-label', 'Daily goal: ' + today + ' of ' + t + ' sentences today, ' + s + ' day streak');\n  });\n  setText('.gp-n', done ? '\u2713' : String(today));\n  setText('.gp-main', main);\n  setText('.gp-sub', sub);\n  setText('.gp-s', String(s));\n  setText('.ac-val', today + ' \/ ' + t);\n  document.querySelectorAll('.spx-top .ac-bar i').forEach(function (b) { b.style.width = pct + '%'; });\n  var left = t - today;\n  setText('.ac-note', (done ? 'Daily goal reached' : left + (left === 1 ? ' sentence' : ' sentences') + ' to go') + ' \u00b7 ' + s + ' day streak');\n }\n\n function cacheKey(u) { return 'spxGoal_' + String(u.id || u.name || ''); }\n function save(u) { try { sessionStorage.setItem(cacheKey(u), JSON.stringify({ at: Date.now(), counts: st.counts, target: st.target })); } catch (e) {} }\n\n function load() {\n  var u = info();\n  if (!u || started) return;\n  started = true;\n  markMember();\n  render();\n  try {\n   var c = JSON.parse(sessionStorage.getItem(cacheKey(u)) || 'null');\n   if (c) { if (TTL > Date.now() - c.at) { st.counts = c.counts || {}; st.target = c.target || 10; st.ready = true; render(); return; } }\n  } catch (e) {}\n  fetch(CSV + '&_cb=' + Date.now())\n   .then(function (r) { return r.text(); })\n   .then(function (txt) { var res = calc(txt, u); st.counts = res.counts; st.target = res.target; st.ready = true; save(u); render(); })\n   .catch(function () { st.ready = true; render(); });\n }\n\n window.addEventListener('tm-satz-bestaetigt', function () {\n  var u = info();\n  if (!u) return;\n  var k = dkey(new Date());\n  st.counts[k] = (st.counts[k] || 0) + 1;\n  st.ready = true;\n  save(u);\n  render();\n });\n\n document.addEventListener('click', function (e) {\n  document.querySelectorAll('.spx-top .acct[open]').forEach(function (a) { if (!a.contains(e.target)) a.removeAttribute('open'); });\n });\n\n function boot() { load(); hashTab(); if (!started) setTimeout(load, 800); }\n if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', boot); } else { boot(); }\n})();\n<\/script>\n<script>\n\/* ===== Level Dock: Level-Wahl + Gast\/Mitglied ===== *\/\n(function(){\n var LV = ['A1','A2','B1','B2'];\n function info(){ return window.wpTrainerUserInfo || null; }\n function mark(){\n  var u = info(), h = document.documentElement;\n  if (!u) return;\n  h.classList.add('spx-member');\n  h.classList.toggle('spx-plus', (parseInt(u.level, 10) || 1) >= 3);\n }\n function urlFor(l, kind){\n  if (!l) return 'https:\/\/sofapiano.com\/exercises\/';\n  var s = l.toLowerCase();\n  return kind === 'grammar' ? 'https:\/\/sofapiano.com\/' + s + '-grammar-specific-translations\/' : 'https:\/\/sofapiano.com\/' + s + '-mixed-translations\/';\n }\n function current(){\n  var m = location.pathname.match(\/\\\/(a1|a2|b1|b2)-\/i);\n  if (m) { var p = m[1].toUpperCase(); try { localStorage.setItem('spxLevel', p); } catch (e) {} return p; }\n  try { var s = localStorage.getItem('spxLevel'); if (LV.indexOf(s) > -1) return s; } catch (e) {}\n  return '';\n }\n function paint(l){\n  document.querySelectorAll('.spx-top [data-lv]').forEach(function (b) { b.setAttribute('aria-pressed', b.getAttribute('data-lv') === l ? 'true' : 'false'); });\n  document.querySelectorAll('.spx-top [data-lvl-link]').forEach(function (a) { a.href = urlFor(l, a.getAttribute('data-lvl-link')); });\n  document.querySelectorAll('.spx-top .dk-tag, .spx-top .ex-lvt').forEach(function (t) { t.textContent = l; });\n  \/* Eingeloggt + Level gew\u00e4hlt: im \u00dcbungs-Men\u00fc nur die \u00dcbungen dieses Levels zeigen *\/\n  var only = !!(info() && l);\n  document.querySelectorAll('.spx-top .ex-p').forEach(function (p) {\n   p.classList.toggle('ex-one', only);\n   p.querySelectorAll('.tl.ex').forEach(function (r) {\n    var t = r.querySelector('i.lv');\n    r.style.display = (only && t && t.textContent.trim() !== l) ? 'none' : '';\n   });\n  });\n }\n function boot(){\n  mark();\n  paint(current());\n  document.querySelectorAll('.spx-top [data-lv]').forEach(function (b) {\n   b.addEventListener('click', function () {\n    var l = b.getAttribute('data-lv');\n    try { localStorage.setItem('spxLevel', l); } catch (e) {}\n    paint(l);\n    if (!info()) location.href = urlFor(l, 'sentences');\n   });\n  });\n  setTimeout(mark, 900);\n }\n if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', boot); } else { boot(); }\n})();\n<\/script>\n<span hidden data-spx-mark=\"head-end\"><\/span>\n\n\n\n<style>\n.spx-role{display:none!important}.spx-role.on{display:block!important}\n\/* Free: Saved Sentences, Grammar tracker und Test results sichtbar, aber schraffiert und gesperrt *\/\n.dash-p.spx-locked{position:relative;min-height:520px;overflow:hidden;border-radius:18px}.dash-p.spx-locked::after{content:\"\";position:absolute;inset:0;z-index:5;background:repeating-linear-gradient(135deg,rgba(20,112,140,.10) 0 6px,rgba(255,255,255,.22) 6px 14px)}.dash-p.spx-locked>*:not(.spx-role){opacity:.9;user-select:none}.dash-p.spx-locked>.spx-role{position:absolute;z-index:6;top:170px;left:16px;right:16px}.dash-p.spx-locked .lock{margin:0 auto;padding:20px 24px;box-shadow:0 12px 34px rgba(14,26,32,.16)}.dash-p.spx-locked .lock .lk{width:40px;height:40px;margin-bottom:8px}.dash .lock .btn{display:inline-block;padding:11px 24px;border-radius:999px;background:#14708C;color:#fff!important;font-weight:700;text-decoration:none!important}\n.dash{max-width:1100px;margin:0 auto;padding:0 16px 72px}\n.dash>input{position:absolute;opacity:0;pointer-events:none}\n.dash-bar{display:flex;flex-wrap:wrap;gap:8px;justify-content:center;margin:0 auto 30px;max-width:900px}\n.dash-bar label{cursor:pointer;padding:10px 16px;border-radius:999px;background:#fff;border:1px solid var(--line);font:600 14px\/1.2 'Inter',sans-serif;color:var(--ink);white-space:nowrap;transition:background .15s,border-color .15s,color .15s}\n.dash-bar label:hover{border-color:var(--teal);color:var(--teal)}\n#dt-1:checked~.dash-bar label[for=dt-1],#dt-2:checked~.dash-bar label[for=dt-2],#dt-3:checked~.dash-bar label[for=dt-3],#dt-4:checked~.dash-bar label[for=dt-4],#dt-5:checked~.dash-bar label[for=dt-5],#dt-6:checked~.dash-bar label[for=dt-6],#dt-7:checked~.dash-bar label[for=dt-7],#dt-8:checked~.dash-bar label[for=dt-8],#dt-9:checked~.dash-bar label[for=dt-9]{background:var(--teal);border-color:var(--teal);color:#fff}\n.dash-p{display:none}\n#dt-1:checked~.dash-panels .p1,#dt-2:checked~.dash-panels .p2,#dt-3:checked~.dash-panels .p3,#dt-4:checked~.dash-panels .p4,#dt-5:checked~.dash-panels .p5,#dt-6:checked~.dash-panels .p6,#dt-7:checked~.dash-panels .p7,#dt-8:checked~.dash-panels .p8,#dt-9:checked~.dash-panels .p9{display:block}\n.dash-p .gap{height:28px}\n.dash .lock{max-width:640px;margin:26px auto 0;text-align:center;background:#fff;border:1px solid var(--line);border-radius:24px;padding:30px 22px;box-shadow:0 10px 30px rgba(14,26,32,.06)}\n.dash .lock .lk{width:52px;height:52px;margin:0 auto 12px;border-radius:50%;background:var(--sun);display:flex;align-items:center;justify-content:center}\n.dash .lock h3{font-family:'Fraunces',Georgia,serif;font-size:22px;margin:0 0 6px;color:var(--ink)}\n.dash .lock p{margin:0 0 16px;color:var(--muted)}\n.dash .acc-extra{max-width:640px;margin:26px auto 0}\n.dash .acc-extra .plans{grid-template-columns:1fr;margin:0 auto;max-width:420px}\n.dash .acc-extra .contact{text-align:center;margin-top:22px}\n.dash .p7 #millionaer-game-wrapper{width:fit-content!important;max-width:100%!important;margin:0 auto!important}\n@media (max-width:700px){.dash-bar{flex-wrap:nowrap;overflow-x:auto;justify-content:flex-start;padding-bottom:8px;-webkit-overflow-scrolling:touch}}\n\/* ===== Dashboard: schlichtes, modernes Layout ===== *\/\n.spx .dh{padding:128px 0 30px}\n.spx .dh-in{max-width:1180px;margin:0 auto;padding:0 24px;display:flex;flex-wrap:wrap;justify-content:space-between;align-items:flex-end;gap:16px 32px}\n.spx .dh-k{margin:0 0 6px;font-size:14px;font-weight:600;color:var(--teal)}\n.spx .dh h1{margin:0 0 8px;text-align:left;font-size:clamp(2rem,3.4vw,2.8rem)}\n.spx .dh-sub{margin:0;max-width:560px;font-size:16px;color:var(--muted)}\n.spx .dh-act .btn{min-height:48px}\n\/* --- Profil: Kasten links (blauer Kopf, Zeitstrahl, Liste) + Inhalt rechts --- *\/\n.dash{max-width:1180px;display:grid;grid-template-columns:290px minmax(0,1fr);column-gap:28px;row-gap:16px;align-items:start;padding:0 24px 88px}\n.dash-bar{position:sticky;top:96px;display:block;margin:0;max-width:none;padding:0;background:#fff;border-radius:24px;box-shadow:0 0 0 1px var(--line),0 10px 26px rgba(29,36,39,.05);overflow:hidden}\nhtml.spx-member .spx .dh-in{display:none}\n@media (max-height:900px){.dash-bar{position:relative;top:0}}\nhtml.spx-member .spx .dh{padding:118px 0 0}\n.pc{padding:22px 22px 20px;background:var(--teal);color:#fff}\n.pc-k{margin:0;font-size:13px;font-weight:600;color:#CFEFFB}\n.pc-title{margin:0 0 18px!important;font-family:'Fraunces',Georgia,serif!important;font-size:30px!important;font-weight:600!important;line-height:1.1!important;letter-spacing:-.5px;color:#fff!important;text-align:left!important}\n.pc-title em{font-style:italic;font-weight:500;color:var(--sun)!important;background:none!important;padding:0!important}\n.pc-top{display:flex;align-items:center;gap:12px}\n.pc-av{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:46px;height:46px;border-radius:50%;background:#fff;color:var(--teal);font-size:18px;font-weight:800}\n.pc-top b{display:block;font-size:16px;line-height:1.2}\n.pc-tags{display:inline-flex;gap:6px;margin-top:5px}\n.pc-badge{padding:2px 8px;border-radius:999px;background:var(--sun);color:var(--dark);font-size:11px;font-weight:800;letter-spacing:.4px}\n.pc-badge.free{background:rgba(255,255,255,.2);color:#fff}\n.pc-tag{padding:2px 8px;border-radius:999px;background:rgba(255,255,255,.18);color:#fff;font-size:11px;font-weight:800}\n.pc-row{display:flex;justify-content:space-between;gap:10px;margin-top:18px;font-size:13px;color:#E6F3F7}\n.pc-row b{color:var(--sun)}\n.pc-track{height:7px;margin-top:8px;border-radius:999px;background:rgba(255,255,255,.2);overflow:hidden}\n.pc-track i{display:block;width:0;height:100%;border-radius:999px;background:var(--sun);transition:width .4s}\n.pc-h{margin:22px 0 10px;font-size:11px;font-weight:800;letter-spacing:1.3px;text-transform:uppercase;color:#CFEFFB}\n.pc-lvs{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:6px}\n.dash-bar a.pc-lv{display:flex;flex-direction:column;align-items:center;gap:6px;color:#fff;text-decoration:none!important;--p:0}\n.dash-bar a.pc-lv *{text-decoration:none!important}\n.dash-bar a.pc-lv:hover{color:#fff}\n.pc-ring{display:flex;align-items:center;justify-content:center;width:50px;height:50px;border-radius:50%;background:conic-gradient(var(--sun) calc(var(--p) * 1%),rgba(255,255,255,.2) 0);transition:transform .15s}\n.dash-bar a.pc-lv:hover .pc-ring{transform:scale(1.06)}\n.pc-in{display:flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:50%;background:var(--teal);color:#fff;font-family:'Fraunces',Georgia,serif;font-size:15px;font-weight:600}\n.pc-lv.cur .pc-in{background:var(--sun);color:var(--dark)}\n.pc-pct{font-size:12px;font-weight:700;color:#E6F3F7}\n.db-list{display:flex;flex-direction:column;gap:2px;margin:0;padding:10px}\n.db-list label{display:block;padding:10px 12px;border:0;border-radius:12px;background:transparent;font:600 14.5px\/1.3 'Inter',sans-serif;color:var(--ink);white-space:nowrap;cursor:pointer;transition:background .15s}\n.db-list label:hover{background:#F4F1EA;border-color:transparent;color:var(--ink)}\n.db-list .db-acc{color:var(--muted)}\n.db-sep{display:block;height:1px;margin:6px 10px;background:var(--line)}\n#dt-1:checked~.dash-bar label[for=dt-1],#dt-2:checked~.dash-bar label[for=dt-2],#dt-3:checked~.dash-bar label[for=dt-3],#dt-4:checked~.dash-bar label[for=dt-4],#dt-5:checked~.dash-bar label[for=dt-5],#dt-6:checked~.dash-bar label[for=dt-6],#dt-7:checked~.dash-bar label[for=dt-7],#dt-8:checked~.dash-bar label[for=dt-8],#dt-9:checked~.dash-bar label[for=dt-9]{background:#E3F5FC;color:#0E1A20;font-weight:700;box-shadow:inset 3px 0 0 var(--teal)}\n.dash-panels{min-width:0}\n.dash-panels .tm-card{max-width:none!important;margin-left:0!important;margin-right:0!important}\n.dash-p>.gap{height:24px}\n@media (max-width:900px){\n .dash{grid-template-columns:minmax(0,1fr);row-gap:16px;padding:0 16px 72px}\n .dash-bar{position:relative;top:0}\n .db-list{flex-direction:row;overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none;gap:4px;padding:8px}\n .db-list::-webkit-scrollbar{display:none}\n .db-sep{display:none}\n .spx .dh{padding:112px 0 22px}\n .spx .dh-in{padding:0 16px}\n html.spx-member .spx .dh{padding:96px 0 0}\n}\n<\/style>\n<script>\ndocument.addEventListener('DOMContentLoaded', function () {\n  var info = window.wpTrainerUserInfo;\n  var lvl = info ? parseInt(info.level, 10) || 1 : 0;\n  var role = !info ? 'guest' : (lvl >= 3 ? 'paid' : 'free');\n  document.querySelectorAll('.spx-role[data-role~=\"' + role + '\"]').forEach(function (el) { el.classList.add('on'); });\n  if (role === 'free') {\n    document.querySelectorAll('.dash-p.p3,.dash-p.p4,.dash-p.p5').forEach(function (p) {\n      p.classList.add('spx-locked');\n      Array.prototype.forEach.call(p.children, function (c) { if (!c.classList.contains('spx-role')) c.inert = true; });\n    });\n  }\n  var key = 'spxDashTab', want = (location.hash || '').replace('#', '');\n  if (!\/^dt-[1-9]$\/.test(want)) { try { want = localStorage.getItem(key) || ''; } catch (e) { want = ''; } }\n  var r = want ? document.getElementById(want) : null;\n  if (r) r.checked = true;\n  document.querySelectorAll('.dash > input[name=\"dt\"]').forEach(function (inp) {\n    inp.addEventListener('change', function () { try { localStorage.setItem(key, inp.id); } catch (e) {} window.dispatchEvent(new Event('resize')); });\n  });\n});\n<\/script>\n<div class=\"spx-page\">\n<div class=\"spx\"><section class=\"dh\" aria-labelledby=\"pg-h1\"><div class=\"dh-in\">\n<div>\n<p class=\"dh-k\" id=\"dh-greet\">Members area<\/p>\n<h1 id=\"pg-h1\">Log in to your <em>dashboard<\/em><\/h1>\n<p class=\"dh-sub\">Pick up where you left off: your statistics, saved sentences, grammar tracker and test results in one place.<\/p>\n<\/div>\n<\/div><\/section><\/div>\n<script>\ndocument.addEventListener('DOMContentLoaded', function () {\n  var u = window.wpTrainerUserInfo;\n  var el = document.getElementById('dh-greet');\n  if (!u) return;\n  if (u.name) el.textContent = 'Welcome back, ' + u.name;\n});\n<\/script>\n\n<div class=\"spx-role\" data-role=\"guest\"><div class=\"tool-stage\">\n<style id=\"lg2e-style\">\n\/* ===== Login f\u00fcr nicht eingeloggte Besucher im Design \u201eIdee 2E \u2013 Verlaufsrahmen\u201c (04.11.2026) =====\n   Seitenkopf wie auf den \u00dcbungs-\/Tool-Seiten (780px, Kapitelzeile, H1, Einleitung, Verlaufslinie),\n   darunter der Login-Kasten mit Farbverlauf-Rahmen, hellem Kopfstreifen und Petrol-Pille. *\/\nhtml:not(.spx-member) body .spx .dh{padding:124px 0 0!important;background:transparent!important}\nhtml:not(.spx-member) body .spx .dh-in{display:block!important;position:relative!important;box-sizing:border-box!important;max-width:780px!important;margin:0 auto!important;padding:0 0 22px!important}\nhtml:not(.spx-member) body .spx .dh-in::after{content:\"\"!important;position:absolute!important;left:0!important;right:0!important;bottom:0!important;height:1px!important;background:linear-gradient(to right,#0F5C73 0%,#6EC1E4 45%,rgba(110,193,228,0) 100%)!important}\nhtml:not(.spx-member) body .spx .dh-k{margin:0 0 8px!important;font-family:'Inter','Segoe UI',Arial,sans-serif!important;font-size:12px!important;font-weight:700!important;line-height:1.4!important;letter-spacing:1.4px!important;text-transform:uppercase!important;color:#5E686B!important;text-align:left!important}\nhtml:not(.spx-member) body .spx .dh h1{margin:0 0 8px!important;font-family:'Fraunces',Georgia,serif!important;font-size:34px!important;font-weight:600!important;line-height:1.15!important;letter-spacing:-.5px!important;color:#1D2427!important;text-align:left!important}\nhtml:not(.spx-member) body .spx .dh-sub{margin:0!important;max-width:600px!important;font-family:'Inter','Segoe UI',Arial,sans-serif!important;font-size:16px!important;line-height:1.55!important;color:#5E686B!important;text-align:left!important}\nhtml body .spx-page .spx-role[data-role=\"guest\"] .tool-stage{padding:48px 16px 150px!important;max-width:none!important}\n@media (max-width:840px){\n html:not(.spx-member) body .spx .dh{padding-top:108px!important}\n html:not(.spx-member) body .spx .dh-in{margin:0 16px!important}\n html:not(.spx-member) body .spx .dh h1{font-size:28px!important}\n html body .spx-page .spx-role[data-role=\"guest\"] .tool-stage{padding:36px 16px 110px!important}\n}\n\n.lg2e{--ink:#1D2427;--muted:#5E686B;--faint:#8E979A;--line:#E6DFD1;--teal:#14708C;--teal-dark:#0E5367;--teal-soft:#E2F0F4;--teal-line:#C7DDE5;\n box-sizing:border-box!important;max-width:780px!important;width:100%!important;margin:0 auto!important;padding:0!important;text-align:left!important;\n font-family:'Inter','Segoe UI',Roboto,Helvetica,Arial,sans-serif!important;font-size:15px!important;line-height:1.45!important;color:var(--ink)!important;\n border:1.5px solid transparent!important;border-radius:16px!important;\n background:linear-gradient(#FFFFFF,#FFFFFF) padding-box,linear-gradient(90deg,#14708C 0%,#7FB9CC 18%,#D9E7EC 45%,#E8E3D9 100%) border-box!important;\n box-shadow:0 6px 20px rgba(20,112,140,0.06)!important}\n.lg2e *,.lg2e *::before,.lg2e *::after{box-sizing:border-box!important}\n.lg2e .lg-head{display:flex!important;align-items:center!important;justify-content:space-between!important;gap:10px!important;min-height:60px!important;padding:8px 10px 8px 16px!important;background:#F2F8FA!important;border-bottom:1px solid #E2EEF2!important;border-radius:14.5px 14.5px 0 0!important}\n.lg2e .lg-title{display:flex!important;align-items:center!important;margin:0!important;font-family:'Fraunces',Georgia,serif!important;font-size:17px!important;font-weight:500!important;color:var(--teal-dark)!important;line-height:1.3!important}\n.lg2e .lg-badge{display:inline-flex!important;align-items:center!important;justify-content:center!important;width:30px!important;height:26px!important;margin-right:10px!important;border-radius:7px!important;background:var(--teal)!important;color:#fff!important}\n.lg2e .lg-badge svg{display:block!important}\n.lg2e .lg-join{display:inline-flex!important;align-items:center!important;height:30px!important;padding:0 12px!important;border-radius:999px!important;box-shadow:inset 0 0 0 1px var(--teal-line)!important;color:var(--teal)!important;font-family:'Inter','Segoe UI',Arial,sans-serif!important;font-size:12px!important;font-weight:700!important;text-decoration:none!important;white-space:nowrap!important;transition:background .15s,box-shadow .15s!important}\n.lg2e .lg-join:hover{background:var(--teal-soft)!important;box-shadow:inset 0 0 0 1px var(--teal)!important;color:var(--teal)!important}\n\n.lg2e .lg-body{display:grid!important;grid-template-columns:minmax(0,1fr) 250px!important;gap:32px!important;padding:30px 32px 28px!important;background:#fff!important;border-radius:0 0 14.5px 14.5px!important}\n\n\/* Formular (Simple Membership) *\/\n.lg2e .lg-form form,.lg2e .lg-form .swpm-login-widget-form{margin:0!important;padding:0!important}\n.lg2e .lg-form .swpm-login-form-inner{display:flex!important;flex-wrap:wrap!important;align-items:center!important;gap:0 12px!important}\n.lg2e .lg-form .swpm-login-form-inner > div{width:100%!important;margin:0!important;padding:0!important}\n.lg2e .lg-form .swpm-username-label,.lg2e .lg-form .swpm-password-label{order:1}\n.lg2e .lg-form .swpm-username-label{order:1}.lg2e .lg-form .swpm-username-input{order:2}\n.lg2e .lg-form .swpm-password-label{order:3}.lg2e .lg-form .swpm-password-input{order:4}\n.lg2e .lg-form .swpm-login-form-inner > .swpm-remember-me{order:5;width:auto!important;flex:1 1 auto!important;margin:0 0 18px 4px!important}\n.lg2e .lg-form .swpm-login-form-inner > .swpm-forgot-pass-link{order:6;width:auto!important;flex:0 0 auto!important;margin:0 4px 18px auto!important}\n.lg2e .lg-form .swpm-before-login-submit-section{order:7}\n.lg2e .lg-form .swpm-login-submit{order:8}\n.lg2e .lg-form .swpm-join-us-link{order:9}\n.lg2e .lg-form .swpm-login-action-msg{order:10}\n.lg2e .lg-form label,.lg2e .lg-form .swpm-label{display:block!important;margin:0 0 6px 4px!important;padding:0!important;font-family:'Inter','Segoe UI',Arial,sans-serif!important;font-size:12px!important;font-weight:700!important;letter-spacing:.3px!important;text-transform:none!important;color:var(--muted)!important}\n.lg2e .lg-form input[type=\"text\"],.lg2e .lg-form input[type=\"email\"],.lg2e .lg-form input[type=\"password\"]{\n display:block!important;width:100%!important;height:50px!important;margin:0 0 16px!important;padding:0 20px!important;\n border:1px solid var(--teal-line)!important;border-radius:25px!important;background:#fff!important;box-shadow:none!important;\n font-family:'Inter','Segoe UI',Arial,sans-serif!important;font-size:16px!important;font-weight:400!important;color:var(--ink)!important;transition:border-color .2s,box-shadow .2s!important}\n.lg2e .lg-form input[type=\"text\"]:focus,.lg2e .lg-form input[type=\"email\"]:focus,.lg2e .lg-form input[type=\"password\"]:focus{outline:none!important;border-color:var(--teal)!important;box-shadow:0 0 0 3px var(--teal-soft)!important}\n.lg2e .lg-form .swpm-password-input{position:relative!important}\n.lg2e .lg-form .swpm-remember-me,.lg2e .lg-form .swpm-remember-me *{font-size:13px!important;color:var(--muted)!important;text-transform:none!important;font-weight:500!important}\n.lg2e .lg-form .swpm-remember-me{display:flex!important;align-items:center!important;gap:6px!important;margin:0 0 18px 4px!important}\n.lg2e .lg-form .swpm-remember-me label{display:inline!important;margin:0!important}\n.lg2e .lg-form input[type=\"checkbox\"]{width:16px!important;height:16px!important;margin:0 4px 0 0!important;accent-color:var(--teal)!important;vertical-align:middle!important}\n.lg2e .lg-form .swpm-forgot-pass-link{margin-bottom:18px!important}\n.lg2e .lg-form .swpm-forgot-pass-link a{font-size:13px!important;font-weight:600!important;color:var(--teal)!important;text-decoration:none!important}\n.lg2e .lg-form .swpm-forgot-pass-link a:hover{text-decoration:underline!important;text-underline-offset:3px!important}\n.lg2e .lg-form input[type=\"submit\"],.lg2e .lg-form .swpm-login-form-submit{\n -webkit-appearance:none!important;appearance:none!important;display:block!important;width:100%!important;height:48px!important;margin:0!important;padding:0 24px!important;\n border:0!important;border-radius:999px!important;background:var(--teal)!important;color:#fff!important;box-shadow:none!important;cursor:pointer!important;\n font-family:'Inter','Segoe UI',Arial,sans-serif!important;font-size:15px!important;font-weight:700!important;letter-spacing:.2px!important;text-transform:none!important;transition:background .15s,transform .12s!important}\n.lg2e .lg-form input[type=\"submit\"]:hover,.lg2e .lg-form .swpm-login-form-submit:hover{background:var(--teal-dark)!important}\n.lg2e .lg-form input[type=\"submit\"]:active{transform:scale(.98)!important}\n.lg2e .lg-form .swpm-join-us-link{display:none!important}\n.lg2e .lg-form .swpm-login-action-msg{display:none!important}\n\n\/* Rechte Spalte: Vorteile *\/\n.lg2e .lg-side{padding:2px 0 0 28px!important;border-left:1px dashed var(--line)!important}\n.lg2e .lg-side-h{margin:0 0 12px!important;font-family:'Inter','Segoe UI',Arial,sans-serif!important;font-size:11px!important;font-weight:800!important;letter-spacing:1.3px!important;text-transform:uppercase!important;color:var(--teal)!important}\n.lg2e .lg-list{list-style:none!important;margin:0 0 20px!important;padding:0!important}\n.lg2e .lg-list li{display:flex!important;align-items:flex-start!important;gap:10px!important;margin:0 0 10px!important;padding:0!important;font-size:14px!important;line-height:1.45!important;color:var(--ink)!important}\n.lg2e .lg-list li::before{content:\"\"!important;flex:0 0 18px!important;width:18px!important;height:18px!important;margin-top:1px!important;border-radius:50%!important;background:var(--teal-soft) url(\"data:image\/svg+xml,%3Csvg xmlns='http:\/\/www.w3.org\/2000\/svg' viewBox='0 0 24 24' fill='none' stroke='%2314708C' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12 5 5 9-10'\/%3E%3C\/svg%3E\") center\/11px no-repeat!important}\n.lg2e .lg-new{margin:0!important;padding:14px 0 0!important;border-top:1px dashed var(--line)!important;font-size:13.5px!important;line-height:1.5!important;color:var(--muted)!important}\n.lg2e .lg-new a{display:inline-flex!important;align-items:center!important;margin-top:8px!important;height:40px!important;padding:0 16px!important;border-radius:999px!important;box-shadow:inset 0 0 0 1px var(--teal-line)!important;color:var(--teal)!important;font-weight:700!important;font-size:13.5px!important;text-decoration:none!important;transition:background .15s!important}\n.lg2e .lg-new a:hover{background:var(--teal-soft)!important}\n\n@media (max-width:800px){\n .lg2e .lg-head{padding:6px 6px 6px 12px!important}\n .lg2e .lg-title{font-size:15px!important}\n .lg2e .lg-body{grid-template-columns:minmax(0,1fr)!important;gap:22px!important;padding:22px 16px 20px!important}\n .lg2e .lg-side{padding:20px 0 0!important;border-left:0!important;border-top:1px dashed var(--line)!important}\n}\n@media (max-width:800px){.lg2e .lg-join{display:none!important}}\n<\/style>\n\n<div class=\"lg2e\">\n  <div class=\"lg-head\">\n    <p class=\"lg-title\"><span class=\"lg-badge\" aria-hidden=\"true\"><svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4\"\/><polyline points=\"10 17 15 12 10 7\"\/><line x1=\"15\" y1=\"12\" x2=\"3\" y2=\"12\"\/><\/svg><\/span>Member login<\/p>\n    <a class=\"lg-join\" href=\"https:\/\/sofapiano.com\/membership-join\/\">Create free account<\/a>\n  <\/div>\n  <div class=\"lg-body\">\n    <div class=\"lg-form\">\n<div class=\"swpm-login-widget-form\">\n    <form id=\"swpm-login-form\" name=\"swpm-login-form\" method=\"post\" action=\"\">\n        <input type=\"hidden\" name=\"swpm_login_origination_flag\" value=\"1\" \/>\n        <div class=\"swpm-login-form-inner\">\n            <div class=\"swpm-username-label\">\n                <label for=\"swpm_user_name\" class=\"swpm-label\">Nombre de usuario o correo electr\u00f3nico<\/label>\n            <\/div>\n            <div class=\"swpm-username-input\">\n                <input type=\"text\" class=\"swpm-text-field swpm-username-field\" id=\"swpm_user_name\" value=\"\" size=\"25\" name=\"swpm_user_name\" \/>\n            <\/div>\n            <div class=\"swpm-password-label\">\n                <label for=\"swpm_password\" class=\"swpm-label\">Contrase\u00f1a<\/label>\n            <\/div>\n            <div class=\"swpm-password-input\">                \n                <input type=\"password\" class=\"swpm-text-field swpm-password-field\" id=\"swpm_password\" value=\"\" size=\"25\" name=\"swpm_password\" \/>                \n            <\/div>\n                        <div class=\"swpm-remember-me\">\n                <span class=\"swpm-remember-checkbox\"><input type=\"checkbox\" name=\"rememberme\" id=\"swpm-rememberme\"><\/span>\n                <label for=\"swpm-rememberme\" class=\"swpm-rememberme-label\">\n                    <span class=\"swpm-rember-label\"> Recu\u00e9rdame<\/span>\n                <\/label>\n            <\/div>\n\n            <div class=\"swpm-before-login-submit-section\"><div class=\"swpm-recaptcha-section\" style=\"margin-bottom: 15px;\"><style type=\"text\/css\">@media screen and (max-width: 375px) {\n            .swpm_g_captcha{transform:scale(0.77);transform-origin:0;-webkit-transform:scale(0.77);-webkit-transform-origin:0 0;}\n        }<\/style><script src=\"https:\/\/www.google.com\/recaptcha\/api.js\" async defer><\/script><div class=\"swpm_g_captcha\"><div class=\"g-recaptcha\" data-sitekey=\"6Lc2pqstAAAAAIx14fGoEgptXyxJGNeaNFUgDEhZ\" data-theme=\"light\" data-size=\"normal\"><\/div><\/div><\/div><\/div>\n\n            <div class=\"swpm-login-submit\">\n                <input type=\"submit\" class=\"swpm-login-form-submit\" name=\"swpm-login\" value=\"Acceder\"\/>\n            <\/div>\n            <div class=\"swpm-forgot-pass-link\">\n                <a id=\"forgot_pass\" class=\"swpm-login-form-pw-reset-link\"  href=\"https:\/\/sofapiano.com\/membership-login\/password-reset\/\">\u00bfHas olvidado tu contrase\u00f1a?<\/a>\n            <\/div>\n                        <div class=\"swpm-join-us-link\">\n                <a id=\"register\" class=\"swpm-login-form-register-link\" href=\"https:\/\/sofapiano.com\/membership-join\/\">\u00danete a nosotros<\/a>\n            <\/div>\n                        <div class=\"swpm-login-action-msg\">\n                <span class=\"swpm-login-widget-action-msg\"><\/span>\n            <\/div>\n        <\/div>\n    <\/form>\n\n    <\/div>\n\n    <\/div>\n    <div class=\"lg-side\">\n      <p class=\"lg-side-h\">Your dashboard<\/p>\n      <ul class=\"lg-list\">\n        <li>Statistics and daily streak<\/li>\n        <li>Saved Sentences<\/li>\n        <li>Grammar tracker A1\u2013B2<\/li>\n        <li>Your level test results<\/li>\n      <\/ul>\n      <p class=\"lg-new\">New to sofapiano?<br><a href=\"https:\/\/sofapiano.com\/membership-join\/\">Create a free account<\/a><\/p>\n    <\/div>\n  <\/div>\n<\/div>\n<\/div><\/div>\n\n<div class=\"spx-role\" data-role=\"free paid\"><div class=\"dash\">\n<input type=\"radio\" name=\"dt\" id=\"dt-2\"><input type=\"radio\" name=\"dt\" id=\"dt-3\"><input type=\"radio\" name=\"dt\" id=\"dt-4\"><input type=\"radio\" name=\"dt\" id=\"dt-5\"><input type=\"radio\" name=\"dt\" id=\"dt-6\"><input type=\"radio\" name=\"dt\" id=\"dt-7\"><input type=\"radio\" name=\"dt\" id=\"dt-8\" checked><input type=\"radio\" name=\"dt\" id=\"dt-9\">\n<div class=\"dash-bar\">\n<div class=\"pc\">\n <h2 class=\"pc-title\">My <em>dashboard<\/em><\/h2>\n <div class=\"pc-top\"><span class=\"pc-av\" id=\"pc-init\" aria-hidden=\"true\">\u00b7<\/span><span><b id=\"pc-name\">Account<\/b><span class=\"pc-tags\"><span class=\"pc-badge\" id=\"pc-badge\">PLUS<\/span><span class=\"pc-tag\" id=\"pc-level\">Level ?<\/span><\/span><\/span><\/div>\n <div class=\"pc-row\"><span class=\"pc-today-wrap\"><span id=\"pc-today\">0 \/ 10 today<\/span><button type=\"button\" class=\"pc-edit\" id=\"pc-goal-btn\" aria-expanded=\"false\" aria-controls=\"pc-goal-form\"><span aria-hidden=\"true\">\u270e<\/span> Edit<\/button><\/span><b id=\"pc-streak\">0-day streak<\/b><div class=\"pc-goal-form\" id=\"pc-goal-form\"><label for=\"pc-goal-input\">Daily goal<\/label><input type=\"number\" id=\"pc-goal-input\" min=\"1\" max=\"500\" inputmode=\"numeric\" autocomplete=\"off\"><button type=\"button\" id=\"pc-goal-save\">Save<\/button><\/div><\/div>\n <div class=\"pc-track\"><i id=\"pc-bar\"><\/i><\/div>\n <p class=\"pc-h\">Progress per level<\/p>\n <div class=\"pc-lvs pc-tl\">\n  <a class=\"pc-lv\" data-l=\"A1\" href=\"https:\/\/sofapiano.com\/a1-grammar-in-context\/\"><span class=\"pc-node\"><span class=\"pc-in\">A1<\/span><span class=\"pc-seg\"><i><\/i><\/span><\/span><span class=\"pc-pct\">\u2013<\/span><\/a>\n  <a class=\"pc-lv\" data-l=\"A2\" href=\"https:\/\/sofapiano.com\/a2-grammar-in-context\/\"><span class=\"pc-node\"><span class=\"pc-in\">A2<\/span><span class=\"pc-seg\"><i><\/i><\/span><\/span><span class=\"pc-pct\">\u2013<\/span><\/a>\n  <a class=\"pc-lv\" data-l=\"B1\" href=\"https:\/\/sofapiano.com\/b1-grammar-in-context\/\"><span class=\"pc-node\"><span class=\"pc-in\">B1<\/span><span class=\"pc-seg\"><i><\/i><\/span><\/span><span class=\"pc-pct\">\u2013<\/span><\/a>\n  <a class=\"pc-lv\" data-l=\"B2\" href=\"https:\/\/sofapiano.com\/b2-grammar-in-context\/\"><span class=\"pc-node\"><span class=\"pc-in\">B2<\/span><span class=\"pc-seg\"><i><\/i><\/span><\/span><span class=\"pc-pct\">\u2013<\/span><\/a>\n <\/div>\n<style id=\"dash-timeline\">\n.dash .pc .pc-lvs.pc-tl{display:grid!important;grid-template-columns:repeat(4,minmax(0,1fr))!important;gap:0!important;justify-content:stretch!important}\n.dash-bar .pc-tl a.pc-lv{align-items:flex-start!important;gap:7px!important;min-width:0}\n.pc-tl .pc-node{display:flex;align-items:center;width:100%}\n.pc-tl .pc-in{flex-shrink:0;width:34px!important;height:34px!important;font-size:13px!important;background:#fff!important;color:#0E5367!important;box-shadow:inset 0 0 0 2px #14708C;transition:transform .15s}\n.pc-tl .pc-lv.done .pc-in{background:#14708C!important;color:#fff!important}\n.pc-tl .pc-lv.cur .pc-in{background:#14708C!important;color:#fff!important;box-shadow:0 0 0 3px #FFCF33}\n.pc-tl a.pc-lv:hover .pc-in{transform:scale(1.08)}\n.pc-tl .pc-seg{flex:1;height:6px;margin:0 6px;border-radius:999px;background:#fff;overflow:hidden}\n.pc-tl .pc-seg i{display:block;height:100%;width:calc(var(--p) * 1%);background:#14708C;border-radius:999px;transition:width .5s}\n.pc-tl .pc-pct{padding-left:3px;font-size:12px}\n@media (min-width:901px){.dash .pc::before,.dash .pc::after{content:\"\";grid-row:1 \/ 3;justify-self:start;align-self:stretch;width:1px;margin-left:-20px;background:#C7DDE4;pointer-events:none}.dash .pc::before{grid-column:2}.dash .pc::after{grid-column:3}}\n.dash .pc .pc-row{flex-wrap:wrap;align-items:center}\n.pc-today-wrap{display:inline-flex;align-items:center;gap:8px}\n.pc-edit{all:unset;box-sizing:border-box;cursor:pointer;display:inline-flex;align-items:center;gap:4px;padding:3px 9px;border-radius:999px;background:#fff;border:1px solid #14708C;color:#14708C;font:700 11px\/1.2 'Inter',sans-serif;transition:background .15s,color .15s}\n.dash .pc .pc-edit:hover,.dash .pc .pc-edit.active,.dash .pc .pc-edit:focus{background:#14708C!important;color:#fff!important;opacity:1!important}\n.pc-goal-form{display:none;width:100%;align-items:center;gap:6px;margin-top:10px}\n.pc-goal-form.open{display:flex}\n.dash-bar .pc-goal-form label{all:unset!important;margin-right:2px!important;font:700 11px\/1.2 'Inter',sans-serif!important;color:#4B565A!important;cursor:default!important}\n.pc-goal-form input{width:64px!important;min-height:0!important;height:auto!important;padding:5px 8px!important;border:1px solid #C7DDE4!important;border-radius:8px!important;background:#fff!important;color:#1D2427!important;font:600 13px 'Inter',sans-serif!important}\n.pc-goal-form button{all:unset;cursor:pointer;padding:6px 12px;border-radius:8px;background:#14708C;color:#fff;font:700 12px 'Inter',sans-serif}\n.pc-goal-form button:hover{background:#0E5367}\n@media (min-width:901px){.dash.dash .pc{grid-template-columns:220px 290px minmax(0,1fr)!important}}\n@media (max-width:900px){.dash .pc .pc-row{margin-top:18px;padding-top:16px;border-top:1px solid #C7DDE4}.dash .pc .pc-h{margin-top:20px;padding-top:16px;border-top:1px solid #C7DDE4}}\n<\/style>\n<\/div>\n<style id=\"dash-a2\">@media (min-width:901px){.dash.dash{grid-template-columns:250px minmax(0,1fr)!important;column-gap:24px!important;row-gap:0!important}.dash .dash-bar{display:contents!important}.dash .pc{grid-column:1 \/ -1!important;grid-row:1!important;display:grid!important;grid-template-columns:220px 230px minmax(0,1fr)!important;grid-template-rows:auto auto!important;column-gap:40px!important;align-items:center!important;padding:22px 28px!important;border-radius:22px 22px 22px 0!important}.dash .pc-title{grid-column:1!important;grid-row:1!important;margin:0 0 14px!important}.dash .pc-top{grid-column:1!important;grid-row:2!important}.dash .pc-row{grid-column:2!important;grid-row:1!important;align-self:end!important;margin:0 0 10px!important}.dash .pc-track{grid-column:2!important;grid-row:2!important;align-self:start!important;margin:0!important}.dash .pc-h{grid-column:3!important;grid-row:1!important;align-self:end!important;margin:0 0 10px!important}.dash .pc-lvs{grid-column:3!important;grid-row:2!important;grid-template-columns:repeat(4,56px)!important;justify-content:start!important;gap:14px!important}.dash .db-list{grid-column:1!important;grid-row:2!important;align-self:start!important;background:#E2F0F4!important;border-top:1px solid #C7DDE4!important;border-radius:0 0 22px 22px!important;padding:8px 12px 14px!important}.dash .db-list label:hover{background:rgba(255,255,255,.6)!important}.dash .db-sep{background:#C7DDE4!important}.dash #dt-1:checked~.dash-bar label[for=dt-1],.dash #dt-2:checked~.dash-bar label[for=dt-2],.dash #dt-3:checked~.dash-bar label[for=dt-3],.dash #dt-4:checked~.dash-bar label[for=dt-4],.dash #dt-5:checked~.dash-bar label[for=dt-5],.dash #dt-6:checked~.dash-bar label[for=dt-6],.dash #dt-7:checked~.dash-bar label[for=dt-7],.dash #dt-8:checked~.dash-bar label[for=dt-8],.dash #dt-9:checked~.dash-bar label[for=dt-9]{background:#FFFFFF!important;color:#0E5367!important;box-shadow:inset 3px 0 0 #6EC1E4,0 2px 6px rgba(29,36,39,.06)!important}.dash .dash-panels{grid-column:2!important;grid-row:2!important;padding-top:24px!important}}<\/style><style id=\"dash-soft\">\n\/* Dashboard: ruhigeres Men\u00fc links, mehr Abstand nach oben, gr\u00f6\u00dfere Abst\u00e4nde oben *\/\n.dash{padding-top:48px!important}\n.dash-bar{box-shadow:0 0 0 1px #EFEAE0,0 10px 26px rgba(29,36,39,.04)!important}\n.pc{background:#E2F0F4!important;color:#1D2427!important}\n.pc-k,.pc-h{color:#4B565A!important}\n.pc-title{color:#1D2427!important}\n.pc-title em{color:#14708C!important}\n.pc-av{background:#14708C!important;color:#fff!important}\n.pc-top b{color:#1D2427}\n.pc-badge{background:#FFCF33!important;color:#0E1A20!important}\n.pc-badge.free{background:#fff!important;color:#14708C!important}\n.pc-tag{background:#fff!important;color:#14708C!important}\n.pc-row{color:#4B565A!important}\n.pc-row b{color:#0E5367!important}\n.pc-track{background:#fff!important}\n.pc-track i{background:#14708C!important}\n.dash-bar a.pc-lv,.dash-bar a.pc-lv:hover{color:#1D2427!important}\n.pc-ring{background:conic-gradient(#14708C calc(var(--p) * 1%),#fff 0)!important}\n.pc-in{background:#E2F0F4!important;color:#0E5367!important}\n.pc-lv.cur .pc-in{background:#14708C!important;color:#fff!important}\n.pc-pct{color:#4B565A!important}\n.db-list label{color:#1D2427}\n#dt-1:checked~.dash-bar label[for=dt-1],#dt-3:checked~.dash-bar label[for=dt-3],#dt-4:checked~.dash-bar label[for=dt-4],#dt-5:checked~.dash-bar label[for=dt-5],#dt-8:checked~.dash-bar label[for=dt-8],#dt-9:checked~.dash-bar label[for=dt-9]{background:#F2F8FA!important;color:#0E5367!important;box-shadow:inset 3px 0 0 #6EC1E4!important}\n.db-sep+.db-sep{display:none!important}\n.dash .tm-stat-row{margin-bottom:20px!important}\n.dash .tm-target-drawer.open{margin-bottom:20px!important}\n.dash .tm-history-card{margin-top:4px!important}\n.dash .tm-stats-grid{gap:20px!important;margin-bottom:24px!important}\n@media (max-width:900px){.dash{padding-top:28px!important}.dash .tm-stat-row{margin-bottom:14px!important}.dash .tm-stats-grid{gap:12px!important}}\n<\/style>\n<style id=\"dash-white\">\n\/* Dashboard: wei\u00dfer Hintergrund statt Hellblau, Farben angepasst *\/\n.pc{background:#fff!important}\n.pc-track{background:#EDF3F5!important}\n.pc-tl .pc-seg{background:#EDF3F5!important}\n.pc-tag,.pc-badge.free{background:#E2F0F4!important;color:#0E5367!important}\n.pc-tl .pc-in{background:#fff!important}\n.pc-tl .pc-lv.done .pc-in,.pc-tl .pc-lv.cur .pc-in{background:#14708C!important;color:#fff!important}\n.dash .db-sep{background:#ECE8E0!important}\n.dash .db-list label:hover{background:#F5F9FA!important}\n.dash #dt-3:checked~.dash-bar label[for=dt-3],.dash #dt-4:checked~.dash-bar label[for=dt-4],.dash #dt-5:checked~.dash-bar label[for=dt-5],.dash #dt-8:checked~.dash-bar label[for=dt-8],.dash #dt-9:checked~.dash-bar label[for=dt-9]{background:#E2F0F4!important;color:#0E5367!important;box-shadow:inset 3px 0 0 #14708C!important}\n.dash.dash .p8 .tm-stat-box:first-child{background:#fff!important;border-color:#E7E2D8!important}\n@media (min-width:901px){\n.dash .pc{box-shadow:0 0 0 1px #E7E2D8,0 10px 26px rgba(29,36,39,.05)!important}\n.dash .db-list{background:#fff!important;border-top:1px solid #ECE8E0!important;box-shadow:1px 0 0 #E7E2D8,-1px 0 0 #E7E2D8,0 1px 0 #E7E2D8,0 12px 24px -12px rgba(29,36,39,.10)!important}\n.dash .pc::before,.dash .pc::after{background:#ECE8E0!important}\n}\n@media (max-width:900px){\n.dash .db-list{background:#fff!important;border-top:1px solid #ECE8E0!important}\n.dash .pc .pc-row,.dash .pc .pc-h{border-top-color:#ECE8E0!important}\n}\n<\/style>\n<div class=\"db-list\" role=\"tablist\" aria-label=\"Dashboard sections\">\n<label for=\"dt-8\">Statistics<\/label>\n<span class=\"db-sep\" aria-hidden=\"true\"><\/span>\n\n<label for=\"dt-3\">Saved Sentences<\/label>\n<label for=\"dt-4\">Grammar tracker<\/label>\n<label for=\"dt-5\">Test results<\/label>\n<span class=\"db-sep\" aria-hidden=\"true\"><\/span>\n\n\n<span class=\"db-sep\" aria-hidden=\"true\"><\/span>\n<label for=\"dt-9\" class=\"db-acc\">Account &amp; membership<\/label>\n<\/div>\n<\/div>\n<script>\n(function () {\n var LOG = 'https:\/\/docs.google.com\/spreadsheets\/d\/1pGfdVy3yDtzS56FIxiP4KsHHYuKUqPWVG18ULv9wxi4\/export?format=csv&gid=588315623';\n var TOP = 'https:\/\/docs.google.com\/spreadsheets\/d\/1pGfdVy3yDtzS56FIxiP4KsHHYuKUqPWVG18ULv9wxi4\/export?format=csv&gid=368365373';\n var LV = ['A1', 'A2', 'B1', 'B2'];\n function setText(id, v) { var e = document.getElementById(id); if (e) e.textContent = v; }\n function parseLine(t) {\n  var r = [], p = '', q = false;\n  for (var i = 0; t.length > i; i++) {\n   var c = t[i];\n   if (c === '\"') { q = !q; }\n   else if (c === ',') { if (q) { p += c; } else { r.push(p.trim()); p = ''; } }\n   else if (c === '\\r' || c === '\\n') { if (q) p += c; }\n   else { p += c; }\n  }\n  r.push(p.trim());\n  return r;\n }\n function dkey(d) { return d.toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' }); }\n function norm(s) {\n  if (!s) return '';\n  var p = String(s).trim().split(' ')[0];\n  if (p.indexOf('.') !== -1) return p;\n  if (p.indexOf('-') !== -1) { var a = p.split('-'); if (a[0].length === 4) return a[2] + '.' + a[1] + '.' + a[0]; }\n  return p;\n }\n function curLevel() { try { var s = localStorage.getItem('spxLevel'); if (LV.indexOf(s) > -1) return s; } catch (e) {} return ''; }\n function basics(u) {\n  var name = String(u.name || 'Account').trim() || 'Account';\n  setText('pc-name', name);\n  setText('pc-greet', 'Welcome back, ' + name.split(' ')[0]);\n  setText('pc-init', name.charAt(0).toUpperCase());\n  var lvl = parseInt(u.level, 10) || 1;\n  var b = document.getElementById('pc-badge');\n  if (b) { b.textContent = lvl >= 3 ? 'PLUS' : 'FREE'; b.classList.toggle('free', !(lvl >= 3)); }\n  var cl = curLevel();\n  setText('pc-level', cl ? cl : 'Level ?');\n  document.querySelectorAll('.pc-lv').forEach(function (el) { el.classList.toggle('cur', el.getAttribute('data-l') === cl); });\n }\n function render(u, logTxt, topTxt) {\n  var id = String(u.id || '').trim().toLowerCase(), nm = String(u.name || '').trim().toLowerCase();\n  var total = { A1: 0, A2: 0, B1: 0, B2: 0 }, topicLevel = {};\n  var tl = topTxt.split(\/\\r?\\n\/);\n  for (var i = 1; tl.length > i; i++) {\n   if (!tl[i].trim()) continue;\n   var c = parseLine(tl[i]);\n   var L = (c[0] || '').toUpperCase(), T = c[1] || '';\n   if (LV.indexOf(L) === -1) continue;\n   if (!T) continue;\n   if (topicLevel[L + '|' + T]) continue;\n   topicLevel[L + '|' + T] = L; total[L]++;\n  }\n  var done = { A1: {}, A2: {}, B1: {}, B2: {} }, counts = {}, exp = null, leg = null;\n  var ll = logTxt.split(\/\\r?\\n\/);\n  for (var j = 1; ll.length > j; j++) {\n   if (!ll[j].trim()) continue;\n   var r = parseLine(ll[j]);\n   if (3 > r.length) continue;\n   var uid = (r[1] || '').toLowerCase(), un = (r[2] || '').toLowerCase(), m = false;\n   if (uid) { if (uid === id) m = true; }\n   if (!m) { if (un) { if (un === nm) m = true; } }\n   if (!m) continue;\n   var dk = norm(r[0]);\n   counts[dk] = (counts[dk] || 0) + 1;\n   var n = parseInt(r[10] || r[3], 10);\n   if (n > 0) { if ((r[8] || '').toLowerCase() === 'tagesziel_geandert') { exp = n; } else { leg = n; } }\n   if ((r[9] || '') === 'Richtig') { var t = (r[4] || '').toUpperCase() + '|' + (r[5] || ''); var tlv = topicLevel[t]; if (tlv) done[tlv][t] = 1; }\n  }\n  pcCounts = counts; pcTarget = exp || leg || 10;\n  paintGoal();\n  LV.forEach(function (L2) {\n   var el = document.querySelector('.pc-lv[data-l=\"' + L2 + '\"]');\n   if (!el) return;\n   var tot = total[L2], dn = Object.keys(done[L2]).length;\n   var pct = tot ? Math.min(100, Math.round(dn * 100 \/ tot)) : 0;\n   el.style.setProperty('--p', pct);\n   el.classList.toggle('done', pct >= 100);\n   el.querySelector('.pc-pct').textContent = pct >= 100 ? '\u2713 100%' : pct + '%';\n   el.setAttribute('aria-label', L2 + ': ' + dn + ' of ' + tot + ' grammar topics practised correctly');\n  });\n }\n var pcCounts = {}, pcTarget = 10;\n var SAVE_URL = 'https:\/\/script.google.com\/macros\/s\/AKfycbz7ViqxDaSi1l2M0o4rsPHqS09qmgosQy34eIJmBhfd1hs2SBbRAuc3nrJC4D4KfBoPPQ\/exec';\n function paintGoal() {\n  var target = pcTarget, today = pcCounts[dkey(new Date())] || 0;\n  var s = 0, d = new Date();\n  for (var k = 0; 365 > k; k++) {\n   var v = pcCounts[dkey(d)] || 0;\n   if (v >= target) { s++; } else if (k !== 0) { break; }\n   d.setDate(d.getDate() - 1);\n  }\n  setText('pc-today', today + ' \/ ' + target + ' today');\n  setText('pc-streak', s + '-day streak');\n  var bar = document.getElementById('pc-bar');\n  if (bar) bar.style.width = Math.min(100, Math.round(today * 100 \/ target)) + '%';\n  var gi = document.getElementById('pc-goal-input');\n  if (gi && document.activeElement !== gi) gi.value = target;\n }\n function toggleGoal(open) {\n  var f = document.getElementById('pc-goal-form'), b = document.getElementById('pc-goal-btn');\n  if (!f) return;\n  f.classList.toggle('open', open);\n  if (b) { b.classList.toggle('active', open); b.setAttribute('aria-expanded', String(open)); }\n  if (open) { var gi = document.getElementById('pc-goal-input'); if (gi) { gi.value = pcTarget; gi.focus(); gi.select(); } }\n }\n function saveGoal() {\n  var gi = document.getElementById('pc-goal-input');\n  var n = parseInt(gi && gi.value, 10);\n  if (!(n > 0)) return;\n  pcTarget = n; toggleGoal(false); paintGoal();\n  var ti = document.getElementById('tm-target-input'), tb = document.getElementById('tm-target-save-btn');\n  if (ti && tb) { ti.value = n; tb.click(); return; }\n  var u = window.wpTrainerUserInfo || {};\n  fetch(SAVE_URL, { method: 'POST', mode: 'no-cors', headers: { 'Content-Type': 'application\/json' }, body: JSON.stringify({\n   user_id: String(u.id || ''), user_name: String(u.name || ''), target: n, tagesziel: n, col4: n, column4: n, col11: n, column11: n,\n   action: 'tagesziel_geandert', status: 'tagesziel_geandert', user_input: String(n) }) }).catch(function () {});\n }\n (function () {\n  var gb = document.getElementById('pc-goal-btn'), gs = document.getElementById('pc-goal-save'), gi = document.getElementById('pc-goal-input');\n  if (gb) gb.addEventListener('click', function () { toggleGoal(!document.getElementById('pc-goal-form').classList.contains('open')); });\n  if (gs) gs.addEventListener('click', saveGoal);\n  if (gi) gi.addEventListener('keydown', function (e) { if (e.key === 'Enter') { e.preventDefault(); saveGoal(); } if (e.key === 'Escape') toggleGoal(false); });\n  document.addEventListener('click', function (e) {\n   if (!e.target || e.target.id !== 'tm-target-save-btn') return;\n   var ti = document.getElementById('tm-target-input'), n = parseInt(ti && ti.value, 10);\n   if (n > 0) { pcTarget = n; paintGoal(); }\n  });\n  window.addEventListener('tm-satz-bestaetigt', function () { var k = dkey(new Date()); pcCounts[k] = (pcCounts[k] || 0) + 1; paintGoal(); });\n })();\n function load() {\n  var u = window.wpTrainerUserInfo;\n  if (!u) return;\n  basics(u);\n  Promise.all([\n   fetch(LOG + '&_cb=' + Date.now()).then(function (x) { return x.text(); }),\n   fetch(TOP).then(function (x) { return x.text(); })\n  ]).then(function (a) { render(u, a[0], a[1]); }).catch(function () {});\n }\n function syncCur() {\n  var r = document.querySelector('.dash > input[name=\"dt\"]:checked');\n  if (!r) return;\n  var lab = document.querySelector('.db-list label[for=\"' + r.id + '\"]');\n  if (lab) setText('db-cur', lab.textContent);\n }\n document.addEventListener('DOMContentLoaded', function () {\n  load();\n  setTimeout(syncCur, 0);\n  document.querySelectorAll('.dash > input[name=\"dt\"]').forEach(function (inp) {\n   inp.addEventListener('change', function () { syncCur(); var o = document.getElementById('db-open'); if (o) o.checked = false; });\n  });\n });\n window.addEventListener('tm-user-switched', load);\n})();\n<\/script>\n<div class=\"dash-panels\">\n\n<div class=\"dash-p p2\"><div class=\"a1-stage\">\n<script>window.__spxLevel = \"B1\"; window.__spxGrammar = true;<\/script>\n\n\n\n<div id=\"trainer-container\" class=\"trainer-app\">\n<style>\n@import url('https:\/\/fonts.googleapis.com\/css2?family=Fraunces:opsz,wght@9..144,500;9..144,600&family=Inter:wght@500;600;700&display=swap');\n\nhtml, body { max-width: 100% !important; overflow-x: hidden !important; width: 100% !important; position: relative !important; }\n\n\/* ============ DESIGN TOKENS ============\n   Konzept: \"Fokus-Modus\" \u2014 ein Satz, viel Ruhe, ein W\u00f6rterbuch-Akzent (Bernstein),\n   Serifenschrift f\u00fcr den deutschen Satz, klare Grotesk f\u00fcr die Bedienung. *\/\n#trainer-container.trainer-app {\n  display: block !important;\n  max-width: 640px !important;\n  margin: 0px auto !important;\n  font-family: 'Inter', 'Segoe UI', Roboto, Helvetica, Arial, sans-serif !important;\n  --font-serif: 'Fraunces', Georgia, 'Times New Roman', serif;\n  --ink: #1E293B;\n  --muted: #7B8799;\n  --paper: #F4F8FC;\n  --card: #FFFFFF;\n  --line: #E0E6EE;\n\n  --accent: #475569;\n  --accent-rgb: 71, 85, 105;\n  --accent-soft: #E8EEF5;\n  --accent-ink: #475569;\n  --accent-solid: #475569;\n  --accent-solid-rgb: 71, 85, 105;\n\n  --sound: #475569;\n  --sound-soft: #E8EEF5;\n\n  --correct: #DDF2E9; --correct-ink: #0E7A59; --correct-border: #9BDBC2;\n  --tip: #FBEECB; --tip-ink: #8A5A00; --tip-border: #E9C46A;\n  --missing: #FAE1E7; --missing-ink: #A63150; --missing-border: #EBA5B7;\n\n  --source-size: 26px;\n  --input-size: 17px;\n  --feedback-size: 21px;\n  --alt-size: 19px;\n  --input-width: 92%;\n  color: var(--ink) !important;\n}\n#trainer-container.trainer-app *, #trainer-container.trainer-app *::before, #trainer-container.trainer-app *::after {\n  box-sizing: border-box !important;\n}\n#trainer-container button:focus-visible, #trainer-container [tabindex]:focus-visible,\n#trainer-container textarea:focus-visible, #trainer-container input:focus-visible {\n  outline: 2px solid var(--accent) !important; outline-offset: 2px !important;\n}\n#trainer-container [data-tooltip] { position: relative !important; }\n\n\/* ---- Top-Leiste: pr\u00e4gnante Themen-Auswahlkarte + Fortschrittspunkte ---- *\/\n#trainer-container .top-bar {\n  display: flex !important; flex-direction: column !important; align-items: center !important;\n  gap: 10px !important; margin-bottom: 18px !important;\n}\n\n#trainer-container .filter-toggle-btn {\n  all: unset !important; box-sizing: border-box !important; cursor: pointer !important; position: relative !important;\n  display: flex !important; align-items: center !important; gap: 12px !important; width: 100% !important;\n  background: var(--card) !important;\n  border: 1px solid var(--line) !important; border-radius: 20px !important;\n  padding: 20px 16px 20px 16px !important; font-family: inherit !important;\n  box-shadow: 0 1px 2px rgba(28,27,26,0.03), 0 16px 32px rgba(28,27,26,0.05) !important;\n  transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease !important;\n}\n#trainer-container .filter-toggle-btn:hover {\n  transform: translateY(-2px) !important;\n  border-color: var(--accent) !important;\n  box-shadow: 0 2px 6px rgba(28,27,26,0.06), 0 16px 28px rgba(28,27,26,0.08) !important;\n}\n#trainer-container .filter-toggle-btn:active { transform: translateY(0) scale(0.99) !important; }\n#trainer-container .fc-icon {\n  flex-shrink: 0 !important; display: flex !important; align-items: center !important; justify-content: center !important;\n  width: 40px !important; height: 40px !important; border-radius: 12px !important; background: var(--accent-solid) !important;\n  color: var(--paper) !important; font-weight: 800 !important; font-size: 14px !important; letter-spacing: 0.2px !important;\n}\n#trainer-container .fc-text { flex-grow: 1 !important; text-align: left !important; min-width: 0 !important; display: flex !important; flex-direction: column !important; justify-content: center !important; gap: 2px !important; }\n#trainer-container .fc-eyebrow {\n  position: absolute !important; top: 7px !important; left: 50% !important; transform: translateX(-50%) !important;\n  display: block !important; font-size: 9px !important; font-weight: 600 !important; color: var(--accent-ink) !important;\n  opacity: 0.7 !important; line-height: 1 !important; white-space: nowrap !important; max-width: 80% !important;\n  overflow: hidden !important; text-overflow: ellipsis !important;\n}\n#trainer-container .fc-topic-name {\n  display: block !important; font-family: var(--font-serif) !important; font-size: 21px !important; font-weight: 600 !important;\n  color: var(--ink) !important; line-height: 1.25 !important; overflow: hidden !important; text-overflow: ellipsis !important;\n  white-space: nowrap !important; width: 100% !important;\n}\n@media (max-width: 800px) {\n  #trainer-container .fc-topic-name {\n    display: -webkit-box !important; -webkit-box-orient: vertical !important; -webkit-line-clamp: 2 !important;\n    white-space: normal !important; overflow-wrap: break-word !important;\n  }\n}\n#trainer-container .fc-caret {\n  flex-shrink: 0 !important; display: flex !important; align-items: center !important; gap: 3px !important;\n  font-size: 20px !important; color: var(--accent) !important; font-weight: 700 !important;\n}\n\n#trainer-container .mobile-full-toggle {\n  all: unset !important; box-sizing: border-box !important; cursor: pointer !important;\n  display: flex !important; align-items: center !important; justify-content: center !important;\n  gap: 5px !important; width: 100% !important; margin-top: 14px !important;\n  font-family: inherit !important; font-size: 12px !important; font-weight: 600 !important;\n  padding: 4px 0 !important; color: var(--muted) !important; opacity: 0.75 !important;\n  transition: opacity 0.15s ease, color 0.15s ease !important;\n}\n#trainer-container .mobile-full-toggle:hover { opacity: 1 !important; color: var(--accent-ink) !important; }\n#trainer-container .mobile-full-toggle.active { color: var(--accent-ink) !important; opacity: 1 !important; }\n#trainer-container .mft-icon { font-size: 13px !important; }\n#trainer-container .mft-label { text-decoration: underline !important; text-decoration-color: currentColor !important; text-underline-offset: 2px !important; }\n\n\/* ---- Satzkarte ---- *\/\n#trainer-container .sentence-block {\n  position: relative !important; padding: 34px 26px 24px 26px !important;\n  border: 1px solid var(--line) !important; border-radius: 20px !important; background-color: var(--card) !important;\n  text-align: center !important; font-family: inherit !important; box-sizing: border-box !important;\n  box-shadow: 0 1px 2px rgba(28,27,26,0.03), 0 16px 32px rgba(28,27,26,0.05) !important;\n  animation: cardIn 0.35s ease both !important;\n}\n@keyframes cardIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }\n#trainer-container .source {\n  display: block !important; font-family: var(--font-serif) !important; font-size: var(--source-size) !important;\n  font-weight: 600 !important; font-optical-sizing: auto !important; color: var(--ink) !important;\n  margin-bottom: 22px !important; padding: 0 38px !important; line-height: 1.35 !important;\n}\n\n#trainer-container .input-wrapper { position: relative !important; width: var(--input-width) !important; margin: 0 auto !important; }\n@keyframes input-mic-blink-intense {\n  0% { background-color: #ffffff; border-color: var(--line); }\n  50% { background-color: var(--tip); border-color: var(--tip-border); box-shadow: 0 0 12px rgba(227,197,131,0.5); }\n  100% { background-color: #ffffff; border-color: var(--line); }\n}\n@keyframes mic-icon-blink-intense {\n  0% { transform: scale(1); color: var(--ink); opacity: 0.4; }\n  50% { transform: scale(1.3); color: var(--missing-ink); opacity: 1; }\n  100% { transform: scale(1); color: var(--ink); opacity: 0.4; }\n}\n#trainer-container textarea.recording-active { animation: input-mic-blink-intense 0.7s infinite ease-in-out !important; border: 1px solid var(--tip-border) !important; }\n#trainer-container .mic-in-input.recording-active { animation: mic-icon-blink-intense 0.7s infinite ease-in-out !important; opacity: 1 !important; }\n\n#trainer-container textarea {\n  display: block !important; width: 100% !important; min-height: 46px !important; height: 46px;\n  font-size: var(--input-size) !important; padding: 11px 45px 11px 14px !important; border-radius: 12px !important;\n  border: 1px solid var(--line) !important; resize: none !important; text-align: center !important;\n  box-sizing: border-box !important; font-family: inherit !important; color: var(--ink) !important; background: var(--paper) !important;\n  overflow-y: hidden !important; line-height: 1.4 !important; transition: border-color 0.2s, box-shadow 0.2s, background 0.2s !important;\n}\n#trainer-container textarea:focus { outline: none !important; border-color: var(--accent) !important; background: var(--card) !important; box-shadow: 0 0 0 3px var(--accent-soft) !important; }\n#trainer-container .mic-in-input {\n  position: absolute !important; right: 4px !important; top: 4px !important; background: none !important; border: none !important;\n  cursor: pointer !important; font-size: 18px !important; opacity: 0.45 !important; transition: opacity 0.15s, transform 0.15s !important;\n}\n#trainer-container .mic-in-input:hover { opacity: 0.9 !important; transform: scale(1.08) !important; }\n\n#trainer-container .lang-indicator {\n  position: absolute !important; bottom: 4px !important; right: 4px !important; background: none !important; border: none !important; cursor: pointer !important;\n  transition: transform 0.15s ease, opacity 0.15s ease !important; font-size: 13px !important; opacity: 0.55 !important;\n}\n#trainer-container .lang-indicator:hover { transform: scale(1.12) !important; opacity: 1 !important; }\n\n#trainer-container .save-btn {\n  all: unset !important; box-sizing: border-box !important; position: absolute !important; top: 6px !important; left: 6px !important;\n  display: flex !important; align-items: center !important; justify-content: center !important;\n  width: 32px !important; height: 32px !important; border-radius: 50% !important;\n  background: var(--paper) !important; border: 1.5px solid var(--line) !important; color: var(--muted) !important;\n  font-size: 17px !important; cursor: pointer !important; line-height: 1 !important;\n  transition: transform 0.15s ease, background 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease !important;\n}\n#trainer-container .save-btn:hover { transform: scale(1.12) !important; border-color: var(--accent) !important; color: var(--accent-ink) !important; }\n#trainer-container .save-btn.saved {\n  color: var(--accent) !important; background: var(--accent-soft) !important; border-color: var(--accent) !important;\n  box-shadow: 0 3px 8px rgba(var(--accent-rgb), 0.35) !important;\n}\n\n#trainer-container .save-btn.is-locked,\n#trainer-container .btn-icon.is-locked {\n  opacity: 0.35 !important; cursor: not-allowed !important; color: var(--muted) !important;\n  background: var(--paper) !important; box-shadow: none !important;\n}\n#trainer-container .save-btn.is-locked:hover,\n#trainer-container .btn-icon.is-locked:hover {\n  transform: none !important; box-shadow: none !important; border-color: var(--line) !important; color: var(--muted) !important;\n}\n\n#trainer-container .tt-bubble {\n  position: absolute !important; z-index: 30 !important;\n  background: var(--ink) !important; color: var(--paper) !important; font-size: 11.5px !important; font-weight: 600 !important;\n  padding: 6px 10px !important; border-radius: 8px !important; line-height: 1.35 !important;\n  text-align: center !important; white-space: normal !important;\n  width: max-content !important; max-width: calc(100% - 16px) !important;\n  pointer-events: none !important; box-shadow: 0 6px 16px rgba(0,0,0,0.22) !important;\n  animation: ttBubbleIn 0.12s ease both !important;\n}\n@keyframes ttBubbleIn { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: translateY(0); } }\n#trainer-container .tt-bubble::after {\n  content: \"\" !important; position: absolute !important; left: var(--tt-arrow-left, 50%) !important;\n  transform: translateX(-50%) !important; width: 0 !important; height: 0 !important;\n  border-left: 5px solid transparent !important; border-right: 5px solid transparent !important;\n}\n#trainer-container .tt-bubble.tt-arrow-bottom::after { bottom: -5px !important; border-top: 5px solid var(--ink) !important; }\n#trainer-container .tt-bubble.tt-arrow-top::after { top: -5px !important; border-bottom: 5px solid var(--ink) !important; }\n\n#trainer-container .save-toast {\n  position: absolute !important; inset: 0 !important;\n  display: flex !important; align-items: center !important; justify-content: center !important;\n  background: rgba(0,0,0,0.8) !important; color: var(--paper) !important; font-size: 18px !important; font-weight: 700 !important;\n  border-radius: 20px !important; text-align: center !important; padding: 20px !important;\n  opacity: 0 !important; pointer-events: none !important; z-index: 25 !important;\n}\n#trainer-container .save-toast.show {\n  opacity: 1 !important;\n  transition: opacity 0.15s ease !important;\n}\n#trainer-container .save-toast.hide {\n  opacity: 0 !important;\n  transition: opacity 2.2s ease !important;\n}\n\n#trainer-container .fullscreen-toggle-btn {\n  all: unset !important; box-sizing: border-box !important; position: absolute !important;\n  top: 6px !important; right: 6px !important; display: flex !important;\n  align-items: center !important; justify-content: center !important;\n  width: 32px !important; height: 32px !important; border-radius: 50% !important;\n  background: var(--paper) !important; border: 1.5px solid var(--line) !important; color: var(--muted) !important;\n  font-size: 15px !important; cursor: pointer !important; line-height: 1 !important;\n  transition: transform 0.15s ease, background 0.2s ease, border-color 0.2s ease, color 0.2s ease !important;\n}\n#trainer-container .fullscreen-toggle-btn:hover { transform: scale(1.12) !important; border-color: var(--accent) !important; color: var(--accent-ink) !important; }\n\n#trainer-container.trainer-app:fullscreen,\n#trainer-container.trainer-app:-webkit-full-screen,\n#trainer-container.trainer-app.pseudo-fullscreen {\n  --source-size: 32px; --input-size: 19px; --feedback-size: 25px; --alt-size: 21px;\n  max-width: 100% !important; width: 100% !important; height: 100% !important;\n  margin: 0 !important; background: #000 !important; background-color: #000 !important;\n  display: flex !important; flex-direction: column !important; justify-content: center !important; align-items: center !important;\n  padding: 24px 16px !important; box-sizing: border-box !important; overflow-y: auto !important;\n}\n#trainer-container.trainer-app:fullscreen .top-bar,\n#trainer-container.trainer-app:-webkit-full-screen .top-bar,\n#trainer-container.trainer-app.pseudo-fullscreen .top-bar,\n#trainer-container.trainer-app.pseudo-fullscreen .mobile-full-toggle { display: none !important; }\n#trainer-container.trainer-app:fullscreen #sentenceArea,\n#trainer-container.trainer-app:-webkit-full-screen #sentenceArea,\n#trainer-container.trainer-app.pseudo-fullscreen #sentenceArea {\n  width: 100% !important; max-width: 640px !important;\n}\n\n#trainer-container.trainer-app.pseudo-fullscreen {\n  position: fixed !important; inset: 0 !important; z-index: 2147483647 !important;\n}\n\n#trainer-container .feedback-wrapper { display: block !important; margin-top: 10px !important; position: relative !important; }\n#trainer-container .feedback {\n  display: block !important; font-family: var(--font-serif) !important; font-size: var(--feedback-size) !important;\n  line-height: 1.6em !important; word-spacing: normal !important; user-select: text !important; cursor: text !important;\n}\n#trainer-container .solution-text {\n  display: block !important; font-size: var(--alt-size) !important; color: var(--muted) !important; font-weight: 500 !important;\n  margin-top: 10px !important; padding-top: 10px !important; border-top: 1px dashed var(--line) !important; line-height: 1.4em !important;\n}\n\n#trainer-container .sentence-controls { display: flex !important; justify-content: center !important; align-items: flex-end !important; gap: 12px !important; margin-top: 22px !important; }\n#trainer-container .btn-icon {\n  all: unset !important; display: inline-flex !important; justify-content: center !important; align-items: center !important;\n  border-radius: 50% !important; border: 1px solid var(--line) !important; background: var(--paper) !important;\n  cursor: pointer !important; width: 48px !important; height: 48px !important; font-size: 19px !important; font-weight: 700 !important;\n  box-shadow: 0 1px 2px rgba(28,27,26,0.04) !important;\n  transition: transform 0.12s ease, border-color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease !important;\n}\n#trainer-container .btn-icon:hover { transform: translateY(-2px) !important; box-shadow: 0 4px 10px rgba(28,27,26,0.10) !important; }\n#trainer-container .btn-icon:active { transform: translateY(0) scale(0.96) !important; }\n#trainer-container .control-item:nth-child(1) .btn-icon:hover { border-color: var(--tip-border) !important; background: var(--tip) !important; }\n#trainer-container .control-item:nth-child(2) .btn-icon:hover { border-color: var(--sound) !important; background: var(--sound-soft) !important; }\n#trainer-container .control-item:nth-child(3) .btn-icon {\n  background: var(--accent-soft) !important; border-color: var(--accent) !important; color: var(--accent-ink) !important;\n}\n#trainer-container .control-item:nth-child(3) .btn-icon:hover { transform: translateY(-2px) scale(1.03) !important; box-shadow: 0 4px 10px rgba(var(--accent-rgb),0.18) !important; }\n#trainer-container .control-item:nth-child(4) .btn-icon { color: var(--muted) !important; }\n#trainer-container .control-item:nth-child(4) .btn-icon:hover { border-color: var(--accent) !important; background: var(--accent-soft) !important; }\n#trainer-container .control-item:nth-child(4) .btn-icon.is-disabled { opacity: 0.3 !important; pointer-events: none !important; box-shadow: none !important; transform: none !important; }\n#trainer-container .control-item:nth-child(5) .btn-icon { color: var(--accent-ink) !important; font-weight: 800 !important; }\n#trainer-container .control-item:nth-child(5) .btn-icon:hover { border-color: var(--accent) !important; background: var(--accent-soft) !important; }\n#trainer-container .btn-label { font-size: 10.5px !important; font-weight: 600 !important; color: var(--muted) !important; margin-top: 6px !important; }\n\n#trainer-container .daily-goal {\n  margin-top: 14px !important; padding: 10px 52px 0 52px !important; border-top: 1px dashed var(--line) !important;\n  cursor: default !important;\n}\n#trainer-container .dg-top {\n  display: flex !important; justify-content: space-between !important; align-items: baseline !important;\n  margin-bottom: 6px !important;\n}\n#trainer-container .dg-label { font-size: 11px !important; font-weight: 600 !important; color: var(--muted) !important; }\n#trainer-container .dg-count {\n  font-size: 11px !important; font-weight: 600 !important; color: var(--muted) !important; font-variant-numeric: tabular-nums !important;\n  cursor: pointer !important; text-decoration: underline dotted !important; text-underline-offset: 2px !important;\n}\n#trainer-container .dg-track {\n  height: 9px !important; border-radius: 5px !important; background: var(--paper) !important;\n  border: 1px solid var(--line) !important; overflow: hidden !important;\n}\n#trainer-container .dg-fill {\n  height: 100% !important; width: 0%; border-radius: 5px !important; background: var(--accent-ink) !important;\n  opacity: 0.7 !important; transition: width 0.5s cubic-bezier(.25,.8,.25,1) !important;\n}\n#trainer-container .daily-goal.reached .dg-fill { background: var(--accent) !important; opacity: 1 !important; }\n\n#trainer-container .correct { color: var(--correct-ink) !important; font-weight: 600 !important; padding: 1px 4px !important; margin: 0 1px !important; border-radius: 5px !important; background: var(--correct) !important; border-bottom: 2px solid var(--correct-border) !important; }\n#trainer-container .tip { color: var(--tip-ink) !important; font-weight: 600 !important; padding: 1px 4px !important; margin: 0 1px !important; border-radius: 5px !important; background: var(--tip) !important; border-bottom: 2px solid var(--tip-border) !important; }\n#trainer-container .missing { color: var(--missing-ink) !important; font-weight: 600 !important; padding: 1px 4px !important; margin: 0 1px !important; border-radius: 5px !important; background: var(--missing) !important; border-bottom: 2px solid var(--missing-border) !important; }\n\n#trainer-container .empty-state { padding: 50px 20px !important; text-align: center !important; color: var(--muted) !important; font-size: 14px !important; }\n\n\/* ---- Mobile L\u00f6sungs-Aufdeck-Mechanik ---- *\/\n#trainer-container .reveal-wrapper, #trainer-container .reveal-alt-holder { display: none; }\n#trainer-container .reveal-wrapper { flex-wrap: wrap !important; justify-content: center !important; gap: 7px !important; }\n#trainer-container .reveal-word {\n  display: inline-block !important; padding: 8px 13px !important; border-radius: 10px !important; background: var(--paper) !important;\n  color: var(--ink) !important; font-family: var(--font-serif) !important; filter: blur(5.5px) !important; -webkit-filter: blur(5.5px) !important;\n  user-select: none !important; -webkit-user-select: none !important; -webkit-touch-callout: none !important; touch-action: pan-y !important;\n  cursor: pointer !important; font-size: 18px !important; font-weight: 700 !important; border: 1.5px solid var(--line) !important;\n  transition: background 0.25s, filter 0.15s, transform 0.1s, border-color 0.25s !important;\n}\n#trainer-container .reveal-word.dragging { transform: scale(1.07) !important; }\n#trainer-container .reveal-word.revealed { filter: none !important; -webkit-filter: none !important; cursor: default !important; }\n#trainer-container .reveal-word.revealed.correct-word { background: var(--correct) !important; color: var(--correct-ink) !important; border-color: var(--correct-border) !important; }\n#trainer-container .reveal-word.revealed.wrong-word { background: var(--missing) !important; color: var(--missing-ink) !important; border-color: var(--missing-border) !important; }\n\n@media (max-width: 800px) {\n  #trainer-container textarea { font-size: 16px !important; min-height: 30px !important; }\n  #trainer-container .source { font-size: 21px !important; padding: 0 26px !important; }\n  #trainer-container .feedback { font-size: 17px !important; }\n  #trainer-container .solution-text { font-size: 14px !important; }\n  #trainer-container .input-wrapper { display: none !important; }\n  #trainer-container .reveal-wrapper { display: flex !important; width: var(--input-width) !important; margin: 0 auto !important; }\n  #trainer-container .reveal-alt-holder { display: block !important; }\n  #trainer-container .sentence-controls { gap: 8px !important; }\n  #trainer-container .btn-icon { width: 44px !important; height: 44px !important; font-size: 17px !important; }\n  #trainer-container .lang-indicator { bottom: 0 !important; right: 0 !important; font-size: 12px !important; }\n\n  #trainer-container.full-input-mode .input-wrapper { display: block !important; }\n  #trainer-container.full-input-mode .reveal-wrapper { display: none !important; }\n  #trainer-container.full-input-mode .reveal-alt-holder { display: none !important; }\n}\n\n@media (min-width: 801px) {\n  #trainer-container.full-input-mode .input-wrapper { display: none !important; }\n  #trainer-container.full-input-mode .reveal-wrapper {\n    display: flex !important; flex-wrap: wrap !important; justify-content: center !important; gap: 7px !important;\n    width: var(--input-width) !important; margin: 0 auto !important;\n  }\n  #trainer-container.full-input-mode .reveal-alt-holder { display: block !important; }\n}\n\n\/* ---- Themen-Schublade (Level + Suche + Liste) ---- *\/\n.tm-drawer-root {\n  --ink: #1E293B; --muted: #7B8799; --paper: #F4F8FC; --card: #FFFFFF; --line: #E0E6EE;\n  --accent: #475569; --accent-rgb: 71, 85, 105; --accent-soft: #E8EEF5; --accent-ink: #475569;\n  --accent-solid: #475569; --accent-solid-rgb: 71, 85, 105;\n  display: none !important; position: fixed !important; z-index: 2147483647 !important; inset: 0 !important;\n  background: rgba(20,19,18,0.6) !important; backdrop-filter: blur(5px) !important; -webkit-backdrop-filter: blur(5px) !important;\n  font-family: 'Inter', 'Segoe UI', Roboto, Helvetica, Arial, sans-serif !important;\n}\n.tm-drawer-root.open { display: block !important; }\n.tm-drawer-root .filter-panel {\n  position: fixed !important; top: 0 !important; right: 0 !important; height: 100% !important; width: min(398px, 92vw) !important;\n  z-index: 2147483647 !important;\n  background: var(--paper) !important; box-shadow: -20px 0 40px rgba(28,27,26,0.15) !important; padding: 20px 16px !important;\n  display: flex !important; flex-direction: column !important; box-sizing: border-box !important;\n  animation: panelSlideIn 0.28s cubic-bezier(.2,.8,.2,1) both !important;\n}\n@media (max-width: 800px) {\n  .tm-drawer-root .filter-panel { width: 80vw !important; }\n}\n@keyframes panelSlideIn { from { transform: translateX(100%); } to { transform: translateX(0); } }\n.tm-drawer-root .filter-panel-header { display: flex !important; align-items: center !important; justify-content: space-between !important; margin-bottom: 12px !important; }\n.tm-drawer-root .filter-panel-header h3 { margin: 0 !important; font-size: 15px !important; font-weight: 700 !important; color: var(--ink) !important; }\n.tm-drawer-root .filter-close-btn {\n  all: unset !important; cursor: pointer !important; width: 30px !important; height: 30px !important; border-radius: 50% !important;\n  display: flex !important; align-items: center !important; justify-content: center !important; font-size: 20px !important; color: var(--muted) !important;\n  transition: background 0.15s !important;\n}\n.tm-drawer-root .filter-close-btn:hover { background: var(--line) !important; }\n.tm-drawer-root .level-buttons { display: flex !important; justify-content: center !important; gap: 5px !important; margin-bottom: 12px !important; }\n.tm-drawer-root .level-btn {\n  all: unset !important; box-sizing: border-box !important; flex: 1 !important; padding: 9px 0 !important;\n  border: 1px solid var(--line) !important; background: var(--card) !important; border-radius: 11px !important;\n  cursor: pointer !important; font-weight: 700 !important; font-size: 12px !important; text-align: center !important;\n  font-family: inherit !important; color: var(--ink) !important;\n  transition: flex 0.25s ease, background 0.25s ease, opacity 0.25s ease, color 0.25s ease, border-color 0.25s ease !important;\n}\n.tm-drawer-root .level-btn.active { flex: 2.3 !important; background: var(--accent-solid) !important; color: var(--paper) !important; border-color: var(--accent-solid) !important; box-shadow: 0 4px 10px rgba(var(--accent-solid-rgb), 0.35) !important; z-index: 2 !important; position: relative !important; }\n.tm-drawer-root .level-btn:not(.active) { background: transparent !important; border-color: transparent !important; color: var(--muted) !important; opacity: 0.7 !important; }\n.tm-drawer-root .level-btn:not(.active):hover { opacity: 1 !important; background: var(--card) !important; }\n\n.tm-drawer-root .all-topics-btn {\n  all: unset !important; box-sizing: border-box !important; display: block !important; width: 100% !important;\n  text-align: center !important; cursor: pointer !important; font-family: inherit !important;\n  padding: 13px 0 !important; margin-bottom: 10px !important; border-radius: 13px !important;\n  border: 1.5px solid var(--line) !important; background: var(--card) !important;\n  font-size: 15px !important; font-weight: 700 !important; color: var(--ink) !important;\n  transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease, transform 0.12s ease !important;\n}\n.tm-drawer-root .all-topics-btn:hover { border-color: var(--accent) !important; transform: translateY(-1px) !important; }\n.tm-drawer-root .all-topics-btn.active {\n  background: var(--accent-solid) !important; border-color: var(--accent-solid) !important; color: var(--paper) !important;\n  box-shadow: 0 4px 12px rgba(var(--accent-solid-rgb), 0.3) !important;\n}\n\n.tm-drawer-root .search-wrapper { position: relative !important; margin: 0 0 12px 0 !important; }\n.tm-drawer-root .search-icon {\n  position: absolute !important; left: 11px !important; top: 50% !important;\n  width: 13px !important; height: 13px !important; transform: translateY(-52%) !important;\n  pointer-events: none !important;\n}\n.tm-drawer-root .search-icon::before {\n  content: \"\" !important; position: absolute !important; top: 0 !important; left: 0 !important;\n  width: 9px !important; height: 9px !important; border: 1.6px solid var(--muted) !important;\n  border-radius: 50% !important; box-sizing: border-box !important;\n}\n.tm-drawer-root .search-icon::after {\n  content: \"\" !important; position: absolute !important; width: 5px !important; height: 1.6px !important;\n  background: var(--muted) !important; border-radius: 1px !important;\n  left: 7.3px !important; top: 7.8px !important; transform: rotate(45deg) !important; transform-origin: left center !important;\n}\n.tm-drawer-root #topicSearch {\n  width: 100% !important; box-sizing: border-box !important; padding: 9px 10px 9px 30px !important; border-radius: 11px !important;\n  border: 1px solid var(--line) !important; font-family: inherit !important; font-size: 13px !important; color: var(--ink) !important;\n  background: var(--card) !important; transition: border-color 0.2s, box-shadow 0.2s !important;\n}\n.tm-drawer-root #topicSearch::placeholder { color: var(--muted) !important; }\n.tm-drawer-root #topicSearch:focus { outline: none !important; border-color: var(--accent) !important; box-shadow: 0 0 0 3px var(--accent-soft) !important; }\n\n.tm-drawer-root .topic-list { list-style: none !important; padding: 0 !important; margin: 0 !important; flex-grow: 1 !important; overflow-y: auto !important; text-align: left !important; }\n.tm-drawer-root .topic-item {\n  position: relative !important; background: var(--card) !important; border: 1px solid var(--line) !important;\n  border-radius: 13px !important; margin-bottom: 7px !important; overflow: hidden !important;\n  transition: border-color 0.15s ease, background 0.15s ease !important; line-height: 1.3 !important;\n}\n.tm-drawer-root .topic-item:hover { border-color: var(--accent) !important; }\n.tm-drawer-root .topic-item.active {\n  border-color: var(--accent) !important; background: var(--accent-soft) !important;\n}\n.tm-drawer-root .topic-item.locked { opacity: 0.65 !important; }\n.tm-drawer-root .topic-row {\n  position: relative !important; display: flex !important; align-items: flex-start !important; gap: 10px !important;\n  padding: 11px 46px 11px 11px !important; cursor: pointer !important; font-size: 14px !important;\n}\n.tm-drawer-root .topic-item.locked .topic-row { cursor: not-allowed !important; }\n.tm-drawer-root .topic-item.locked:hover { border-color: var(--line) !important; }\n\n.tm-drawer-root .topic-id-big {\n  flex: 0 0 auto !important; display: inline-flex !important; align-items: center !important; justify-content: center !important;\n  font-size: 11.5px !important; font-weight: 800 !important; color: var(--accent-ink) !important;\n  background: var(--accent-soft) !important; padding: 3px 7px !important; border-radius: 7px !important; line-height: 1.3 !important;\n}\n.tm-drawer-root .topic-text-wrapper { flex: 1 1 auto !important; min-width: 0 !important; display: block !important; overflow: hidden !important; }\n.tm-drawer-root .topic-title-text {\n  display: block !important; font-size: 14px !important; font-weight: 700 !important; color: var(--ink) !important;\n  line-height: 1.3 !important; white-space: normal !important; overflow-wrap: break-word !important; word-break: break-word !important;\n}\n.tm-drawer-root .topic-name-row { font-size: 12.5px !important; font-weight: 500 !important; color: var(--muted) !important; margin-top: 3px !important; line-height: 1.35 !important; white-space: normal !important; }\n.tm-drawer-root .topic-level-badge { display: inline-block !important; font-size: 10px !important; font-weight: 700 !important; color: var(--muted) !important; border: 1px solid var(--line) !important; border-radius: 5px !important; padding: 1px 5px !important; margin-left: 6px !important; vertical-align: middle !important; }\n.tm-drawer-root .topic-lock-badge {\n  font-size: 11px !important; font-weight: 700 !important; color: var(--muted) !important; margin-top: 5px !important; display: inline-block !important;\n}\n\n.tm-drawer-root .topic-expand-btn {\n  position: absolute !important; right: 8px !important; top: 50% !important; transform: translateY(-50%) !important; background: transparent !important;\n  border: none !important; cursor: pointer !important; display: flex !important; align-items: center !important;\n  width: 34px !important; height: 34px !important; border-radius: 50% !important; justify-content: center !important; font-size: 17px !important;\n  color: var(--muted) !important; opacity: 0.85 !important;\n  transition: opacity 0.2s, transform 0.2s, background 0.2s, color 0.2s !important;\n}\n.tm-drawer-root .topic-expand-btn:hover { opacity: 1 !important; background: var(--accent-soft) !important; color: var(--accent-ink) !important; }\n.tm-drawer-root .topic-expand-btn.open { transform: translateY(-50%) rotate(180deg) !important; }\n\n.tm-drawer-root .topic-info-panel {\n  max-height: 0 !important; overflow: hidden !important;\n  transition: max-height 0.28s ease, padding 0.28s ease !important;\n  padding: 0 14px !important; font-size: 12.5px !important; line-height: 1.55 !important;\n  color: var(--muted) !important; border-top: 1px solid transparent !important;\n}\n.tm-drawer-root .topic-info-panel.open {\n  max-height: 400px !important; padding: 0 14px 12px 14px !important;\n  border-top-color: var(--line) !important;\n}\n\n#trainer-container .sentence-block.ui-loading { color: var(--muted) !important; font-weight: 600 !important; animation: loadingPulse 1.3s ease-in-out infinite !important; }\n@keyframes loadingPulse { 0%, 100% { opacity: 0.55; } 50% { opacity: 1; } }\n\n@keyframes modalFadeIn { from { opacity: 0; transform: translateY(-20px); } to { opacity: 1; transform: translateY(0); } }\n\n@media (prefers-reduced-motion: reduce) {\n  #trainer-container.trainer-app *, #trainer-container.trainer-app *::before, #trainer-container.trainer-app *::after {\n    animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important;\n  }\n}\n\n\/* ---- Tageslimit-Hinweis ---- *\/\n#trainer-container .daily-limit-notice {\n  margin-top: 14px !important; padding: 12px 16px !important; border-radius: 12px !important;\n  background: var(--tip) !important; border: 1px solid var(--tip-border) !important; color: var(--tip-ink) !important;\n  font-size: 13px !important; line-height: 1.5 !important; text-align: center !important;\n}\n<\/style>\n\n<!-- Themen-Schublade -->\n<div id=\"filter-overlay\" class=\"filter-overlay tm-drawer-root\">\n  <div class=\"filter-panel\">\n    <div class=\"filter-panel-header\">\n      <h3 class=\"ui-topic-title\">Grammar Topic<\/h3>\n      <button id=\"filter-close\" class=\"filter-close-btn\">&times;<\/button>\n    <\/div>\n    <div class=\"level-buttons\" id=\"levelBtnGroup\">\n      <button class=\"level-btn\" data-level=\"A1\">A1<\/button>\n      <button class=\"level-btn\" data-level=\"A2\">A2<\/button>\n      <button class=\"level-btn\" data-level=\"B1\">B1<\/button>\n      <button class=\"level-btn\" data-level=\"B2\">B2<\/button>\n    <\/div>\n    <div class=\"search-wrapper\"><span class=\"search-icon\" aria-hidden=\"true\"><\/span><input type=\"text\" id=\"topicSearch\" placeholder=\"Search...\"><\/div>\n    <button id=\"allTopicsBtn\" class=\"all-topics-btn\">All topics<\/button>\n    <ul class=\"topic-list\" id=\"topicList\"><\/ul>\n  <\/div>\n<\/div>\n\n<!-- SHOW_TOPIC_BAR-Vorbereitung: window.__trainerShowTopicBar bestimmt, ob die\n     obere Auswahl-Leiste sichtbar ist. true = Leiste ausblenden (fest auf\n     MANUAL_LEVEL\/MANUAL_TOPIC_ID), false\/nicht gesetzt = Leiste anzeigen.\n     FIX: setProperty(...,'important') statt .style.display=, da die CSS-Regel\n     #trainer-container .top-bar { display: flex !important; ... } ein normales\n     Inline-display sonst \u00fcberstimmen w\u00fcrde. -->\n<script>window.__trainerShowTopicBar = true;<\/script>\n<div class=\"top-bar\" id=\"topBar\" style=\"display: none;\">\n  <button id=\"filterToggleBtn\" class=\"filter-toggle-btn\">\n    <span class=\"fc-eyebrow\" id=\"fcEyebrow\">...<\/span>\n    <span class=\"fc-icon\" id=\"fcLevelBadge\">...<\/span>\n    <span class=\"fc-text\">\n      <span class=\"fc-topic-name\" id=\"fcTopicName\">...<\/span>\n    <\/span>\n    <span class=\"fc-caret\">\u203a<\/span>\n  <\/button>\n<\/div>\n<script>\n  document.getElementById('topBar').style.setProperty('display', '', 'important');\n<\/script>\n\n<div id=\"sentenceArea\">\n  <div class=\"sentence-block ui-loading\">Loading...<\/div>\n<\/div>\n\n<button id=\"mobileFullToggle\" class=\"mobile-full-toggle\" type=\"button\">\n  <span class=\"mft-icon\">\u2328\ufe0f<\/span><span class=\"mft-label\"><\/span>\n<\/button>\n\n<script>\n(function(container){\n    const MANUAL_LEVEL = window.__spxLevel || \"A1\";\n    const MANUAL_TOPIC_ID = \"\";\n    const MANUAL_TOPIC_AREA = \"Grammar\";\n    const SESSION_SIZE = 8;\n    const SHOW_TOPIC_BAR = window.__spxGrammar ? (window.__trainerShowTopicBar !== false) : (window.__trainerShowTopicBar !== true);\n\n    const DAILY_LIMIT_GUEST  = 10;   \/\/ nicht angemeldete Besucher (G\u00e4ste)\n    const DAILY_LIMIT_MEMBER = 20;  \/\/ angemeldet, aber nicht zahlend (Level 1)\n    const DAILY_LIMIT_PAYER  = 0;   \/\/ zahlende Mitglieder (Level 2\/3) \u2013 0 = unbegrenzt\n\n    const UI_LANGUAGES = {\n        en: {\n            topicTitle: \"Grammar Topic\", loading: \"Loading data...\", placeholder: \"translation...\",\n            saveHint: \"Save Sentence\", langHint: \"Change Language\", micHint: \"Speech to Text\",\n            btnHint: \"Hint\", btnListen: \"Listen\", btnCheck: \"Check\", btnPrev: \"Back\", btnNew: \"Next\",\n            altLabel: \"Alternative: \", noData: \"No sentences for this selection yet.\", allTopics: \"All topics mixed\",\n            searchPlaceholder: \"Search topics...\", topicEyebrow: \"Current topic \u2014 tap to change\",\n            fullModeOn: \"Type your answer\", fullModeOff: \"Switch to puzzle mode\",\n            fullscreenHint: \"Fullscreen\", exitFullscreenHint: \"Exit fullscreen\",\n            savedToast: \"Sentence Saved\", dailyGoalLabel: \"Daily goal\",\n            lockedLogin: \"Log in to unlock this topic.\", lockedPaid: \"This topic is for paying members only.\",\n            lockedLoginList: \"Members only\", lockedPaidList: \"Paying members only\",\n            listenLockedHint: \"Log in to listen\", saveLockedHint: \"Log in to save sentences\",\n            saveUpgradeHint: \"Upgrade membership to save sentence\",\n            dailyGoalAdjustHint: \"Adjust Daily Goal in your Profile\",\n            dailyLimitReachedGuest: \"Daily limit reached. Log in for free to continue.\",\n            dailyLimitReachedMember: \"Daily limit reached. Upgrade your membership to continue.\",\n            dailyLimitReachedTitle: \"Daily limit reached\"\n        },\n        es: {\n            topicTitle: \"Tema de gram\u00e1tica\", loading: \"Cargando datos...\", placeholder: \"traducci\u00f3n...\",\n            saveHint: \"Guardar frase\", langHint: \"Cambiar idioma\", micHint: \"Reconocimiento de voz\",\n            btnHint: \"Pista\", btnListen: \"Escucha\", btnCheck: \"Valida\", btnPrev: \"Atr\u00e1s\", btnNew: \"Siguiente\",\n            altLabel: \"Alternativa: \", noData: \"A\u00fan no hay frases para esta selecci\u00f3n.\", allTopics: \"Todos los temas mezclados\",\n            searchPlaceholder: \"Buscar temas...\", topicEyebrow: \"Tema actual \u2014 toca para cambiar\",\n            fullModeOn: \"Escribir la respuesta\", fullModeOff: \"Cambiar a modo puzzle\",\n            fullscreenHint: \"Pantalla completa\", exitFullscreenHint: \"Salir de pantalla completa\",\n            savedToast: \"Frase guardada\", dailyGoalLabel: \"Objetivo diario\",\n            lockedLogin: \"Inicia sesi\u00f3n para desbloquear este tema.\", lockedPaid: \"Este tema es solo para miembros de pago.\",\n            lockedLoginList: \"Solo miembros\", lockedPaidList: \"Solo miembros de pago\",\n            listenLockedHint: \"Inicia sesi\u00f3n para escuchar\", saveLockedHint: \"Inicia sesi\u00f3n para guardar frases\",\n            saveUpgradeHint: \"Mejora tu membres\u00eda para guardar frases\",\n            dailyGoalAdjustHint: \"Ajusta tu objetivo diario en tu perfil\",\n            dailyLimitReachedGuest: \"L\u00edmite diario alcanzado. Inicia sesi\u00f3n gratis para continuar.\",\n            dailyLimitReachedMember: \"L\u00edmite diario alcanzado. Mejora tu membres\u00eda para continuar.\",\n            dailyLimitReachedTitle: \"L\u00edmite diario alcanzado\"\n        }\n    };\n    \/\/ Das Label vor dem Alternativsatz bleibt immer auf Deutsch, da der\n    \/\/ dahinterstehende Alternativsatz selbst Deutsch ist (unabh\u00e4ngig von der\n    \/\/ gew\u00e4hlten Oberfl\u00e4chensprache en\/es).\n    const ALT_LABEL = \"Alternative: \";\n    const SHEET_ID = '1pGfdVy3yDtzS56FIxiP4KsHHYuKUqPWVG18ULv9wxi4';\n    const URL_S = `https:\/\/docs.google.com\/spreadsheets\/d\/${SHEET_ID}\/export?format=csv&gid=0`;\n    const URL_T = `https:\/\/docs.google.com\/spreadsheets\/d\/${SHEET_ID}\/export?format=csv&gid=368365373`;\n\n    const URL_GOAL = `https:\/\/docs.google.com\/spreadsheets\/d\/${SHEET_ID}\/export?format=csv&gid=588315623`;\n    const DEFAULT_DAILY_TARGET = 10;\n\n    let allData = [];\n    let state_topics = [];\n    let currentLevel = MANUAL_LEVEL;\n    let currentTopicId = MANUAL_TOPIC_ID;\n    let currentLang = detectSiteLanguage();\n    let session = [];\n    let sessionIndex = 0;\n\n    let dgBaseCounts = {};\n    let dgTarget = null;\n    let dgLiveModifier = 0;\n\n    function detectSiteLanguage() {\n        const supported = Object.keys(UI_LANGUAGES);\n        const candidates = [\n            document.documentElement.lang,\n            navigator.language,\n            (navigator.languages && navigator.languages[0])\n        ].filter(Boolean).map(v => v.toLowerCase().split('-')[0]);\n        for (const c of candidates) { if (supported.includes(c)) return c; }\n        return \"en\";\n    }\n\n    \/\/ ============ GAST-ID ============\n    \/\/ Jeder nicht angemeldete Besucher bekommt eine zuf\u00e4llige, aber dauerhafte\n    \/\/ ID (localStorage), damit wiederkehrende G\u00e4ste im Log erkennbar sind und\n    \/\/ das Tageslimit personenbezogen (statt nur pro Browser-Sitzung) gilt.\n    \/\/ Der Name bleibt bewusst immer \"Gast\" \u2014 nur die ID ist individuell.\n    function generateGuestId() {\n        if (window.crypto && typeof window.crypto.randomUUID === 'function') {\n            return 'guest-' + window.crypto.randomUUID();\n        }\n        return 'guest-' + Date.now().toString(36) + '-' + Math.random().toString(36).slice(2, 10);\n    }\n    function getGuestId() {\n        try {\n            let id = window.localStorage.getItem('trainerGuestId');\n            if (!id) {\n                id = generateGuestId();\n                window.localStorage.setItem('trainerGuestId', id);\n            }\n            return id;\n        } catch (e) {\n            \/\/ localStorage nicht verf\u00fcgbar (z.B. privater Modus ohne Speicher) -> pro Ladevorgang neue ID\n            return generateGuestId();\n        }\n    }\n    \/\/ Aktive Nutzer-Info: entweder das echte wpTrainerUserInfo (eingeloggt)\n    \/\/ oder ein Gast-Objekt mit fester, wiederkehrender ID und Name \"Gast\".\n    function getActiveUserInfo() {\n        if (window.wpTrainerUserInfo) return window.wpTrainerUserInfo;\n        return { id: getGuestId(), name: 'Gast', level: 1 };\n    }\n\n    const bookmarksMemory = [];\n    let sessionAnswers = {};\n\n    const filterOverlayEl = container.querySelector('#filter-overlay');\n    const filterPanelEl = filterOverlayEl ? filterOverlayEl.querySelector('.filter-panel') : null;\n    const filterTitleEl = filterPanelEl ? filterPanelEl.querySelector('.ui-topic-title') : null;\n    const filterCloseBtn = filterOverlayEl ? filterOverlayEl.querySelector('#filter-close') : null;\n    const levelBtnGroupEl = filterOverlayEl ? filterOverlayEl.querySelector('#levelBtnGroup') : null;\n    const topicSearchEl = filterOverlayEl ? filterOverlayEl.querySelector('#topicSearch') : null;\n    const allTopicsBtnEl = filterOverlayEl ? filterOverlayEl.querySelector('#allTopicsBtn') : null;\n    const topicListEl = filterOverlayEl ? filterOverlayEl.querySelector('#topicList') : null;\n\n    if (filterOverlayEl && filterOverlayEl.parentNode !== document.body) document.body.appendChild(filterOverlayEl);\n\n    const ua = navigator.userAgent || \"\";\n    const isIOS = \/iPad|iPhone|iPod\/.test(ua) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);\n    const isSafari = \/^((?!chrome|android|crios|fxios|edgios).)*safari\/i.test(ua);\n\n    const fsApiSupported = !!(document.fullscreenEnabled || document.webkitFullscreenEnabled);\n    function isContainerFullscreen() {\n        return document.fullscreenElement === container || document.webkitFullscreenElement === container || container.classList.contains('pseudo-fullscreen');\n    }\n    function updateFsBtnIcon() {\n        const btn = container.querySelector('.fullscreen-toggle-btn');\n        if (!btn) return;\n        const active = isContainerFullscreen();\n        btn.textContent = active ? '\u00d7' : '\u26f6';\n        btn.dataset.tooltip = active\n            ? (UI_LANGUAGES[currentLang].exitFullscreenHint || 'Exit fullscreen')\n            : (UI_LANGUAGES[currentLang].fullscreenHint || 'Fullscreen');\n    }\n    document.addEventListener('fullscreenchange', updateFsBtnIcon);\n    document.addEventListener('webkitfullscreenchange', updateFsBtnIcon);\n\n    const originalParent = container.parentNode;\n    const originalNextSibling = container.nextSibling;\n    function activatePseudoFullscreen() {\n        document.body.appendChild(container);\n        container.classList.add('pseudo-fullscreen');\n        document.body.style.overflow = 'hidden';\n        updateFsBtnIcon();\n    }\n    function deactivatePseudoFullscreen() {\n        if (originalNextSibling && originalNextSibling.parentNode === originalParent) {\n            originalParent.insertBefore(container, originalNextSibling);\n        } else if (originalParent) {\n            originalParent.appendChild(container);\n        }\n        container.classList.remove('pseudo-fullscreen');\n        document.body.style.overflow = '';\n        updateFsBtnIcon();\n    }\n    document.addEventListener('keydown', (e) => {\n        if (e.key === 'Escape' && container.classList.contains('pseudo-fullscreen')) deactivatePseudoFullscreen();\n    });\n\n    const initialBtn = levelBtnGroupEl ? levelBtnGroupEl.querySelector(`.level-btn[data-level=\"${MANUAL_LEVEL}\"]`) : null;\n    if (initialBtn) initialBtn.classList.add('active');\n\n    function getLevenshteinDist(a, b) {\n        const matrix = [];\n        for (let i = 0; i <= b.length; i++) matrix[i] = [i];\n        for (let j = 0; j <= a.length; j++) matrix[0][j] = j;\n        for (let i = 1; i <= b.length; i++) {\n            for (let j = 1; j <= a.length; j++) {\n                if (b.charAt(i - 1) === a.charAt(j - 1)) matrix[i][j] = matrix[i - 1][j - 1];\n                else matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, Math.min(matrix[i][j - 1] + 1, matrix[i - 1][j] + 1));\n            }\n        }\n        return matrix[b.length][a.length];\n    }\n    const normalize = (t) => t ? t.toLowerCase().trim().replace(\/[.,!?]\/g, '').replace(\/\u00e4\/g,'ae').replace(\/\u00f6\/g,'oe').replace(\/\u00fc\/g,'ue').replace(\/\u00df\/g,'ss').replace(\/\\s+\/g, ' ') : \"\";\n\n    function wordsEqualFuzzy(a, b) {\n        if (!a || !b) return false;\n        if (a === b) return true;\n        const maxLen = Math.max(a.length, b.length);\n        const threshold = maxLen <= 4 ? 1 : (maxLen <= 8 ? 2 : 3);\n        return getLevenshteinDist(a, b) <= threshold;\n    }\n    function alignWords(target, user) {\n        const n = target.length, m = user.length;\n        const dp = Array.from({length: n + 1}, () => new Array(m + 1).fill(0));\n        const isMatch = Array.from({length: n + 1}, () => new Array(m + 1).fill(false));\n        for (let i = 1; i <= n; i++) {\n            for (let j = 1; j <= m; j++) {\n                if (wordsEqualFuzzy(target[i - 1], user[j - 1])) { dp[i][j] = dp[i - 1][j - 1] + 1; isMatch[i][j] = true; }\n                else { dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]); }\n            }\n        }\n        let i = n, j = m;\n        const alignment = new Array(n).fill(null);\n        while (i > 0 && j > 0) {\n            if (isMatch[i][j] && dp[i][j] === dp[i - 1][j - 1] + 1) { alignment[i - 1] = j - 1; i--; j--; }\n            else if (dp[i - 1][j] >= dp[i][j - 1]) { i--; } else { j--; }\n        }\n        return alignment;\n    }\n\n    let cachedVoices = [];\n    let voicesReady = false;\n    let speechWarmedUp = false;\n    function loadVoices() {\n        return new Promise((resolve) => {\n            let voices = window.speechSynthesis ? speechSynthesis.getVoices() : [];\n            if (voices.length) { cachedVoices = voices; voicesReady = true; resolve(voices); return; }\n            const handler = () => {\n                voices = speechSynthesis.getVoices();\n                if (voices.length) { cachedVoices = voices; voicesReady = true; speechSynthesis.removeEventListener('voiceschanged', handler); resolve(voices); }\n            };\n            if (window.speechSynthesis) speechSynthesis.addEventListener('voiceschanged', handler);\n            setTimeout(() => { resolve(window.speechSynthesis ? speechSynthesis.getVoices() : []); }, 1200);\n        });\n    }\n    if (window.speechSynthesis) loadVoices();\n\n    function warmUpSpeechOniOS() {\n        if (speechWarmedUp || !isIOS || !('speechSynthesis' in window)) return;\n        speechWarmedUp = true;\n        try {\n            const warmup = new SpeechSynthesisUtterance(' ');\n            warmup.volume = 0;\n            speechSynthesis.speak(warmup);\n        } catch (e) { \/* ignorieren *\/ }\n        loadVoices();\n    }\n    if (isIOS) container.addEventListener('pointerdown', warmUpSpeechOniOS, { once: true, passive: true });\n\n    async function speakText(textToSpeak) {\n        if (!textToSpeak) return;\n        if (!('speechSynthesis' in window)) { alert('Sprachausgabe wird von diesem Browser nicht unterst\u00fctzt.'); return; }\n\n        const doSpeak = (voices) => {\n            speechSynthesis.cancel();\n            const u = new SpeechSynthesisUtterance(textToSpeak);\n            const germanVoices = voices.filter(v => v.lang && v.lang.toLowerCase().startsWith('de'));\n            function scoreVoice(v) {\n                const name = v.name.toLowerCase();\n                let score = 0;\n                if (v.localService === false) score += 4;\n                if (\/neural|natural|enhanced|premium|wavenet|online\/.test(name)) score += 5;\n                if (name.includes('google')) score += 3;\n                if (\/compact\/.test(name)) score -= 2;\n                const goodNames = ['katja', 'vicki', 'conrad', 'daniel', 'markus', 'anna', 'stefan', 'hedda', 'yannick'];\n                if (goodNames.some(n => name.includes(n))) score += 1;\n                return score;\n            }\n            const chosen = germanVoices.slice().sort((a, b) => scoreVoice(b) - scoreVoice(a))[0];\n            if (chosen) u.voice = chosen;\n            u.lang = \"de-DE\"; u.pitch = 1.0; u.rate = 0.96;\n            u.onerror = (e) => { console.error(\"Sprachausgabe-Fehler:\", e); };\n\n            if (!isIOS && !isSafari) {\n                let keepAlive = setInterval(() => {\n                    if (!window.speechSynthesis || !speechSynthesis.speaking) { clearInterval(keepAlive); return; }\n                    speechSynthesis.pause(); speechSynthesis.resume();\n                }, 5000);\n                u.onend = () => clearInterval(keepAlive);\n                u.onerror = () => clearInterval(keepAlive);\n            }\n            speechSynthesis.speak(u);\n        };\n\n        if (isIOS || isSafari) {\n            const voices = voicesReady ? cachedVoices : (window.speechSynthesis.getVoices() || []);\n            doSpeak(voices);\n            if (!voicesReady) loadVoices();\n        } else {\n            speechSynthesis.cancel();\n            await new Promise(r => setTimeout(r, 60));\n            const voices = voicesReady ? cachedVoices : await loadVoices();\n            doSpeak(voices);\n        }\n    }\n\n    let activeTooltipBubble = null;\n    function hideTooltip() {\n        if (activeTooltipBubble && activeTooltipBubble.parentNode) activeTooltipBubble.parentNode.removeChild(activeTooltipBubble);\n        activeTooltipBubble = null;\n    }\n    function clampAndShowTooltip(el, text) {\n        hideTooltip();\n        if (!text) return;\n        const card = el.closest('.sentence-block');\n        if (!card) return;\n        const bubble = document.createElement('div');\n        bubble.className = 'tt-bubble';\n        bubble.textContent = text;\n        bubble._anchorEl = el;\n        card.appendChild(bubble);\n\n        const cardRect = card.getBoundingClientRect();\n        const elRect = el.getBoundingClientRect();\n        const margin = 8;\n        const bw = bubble.offsetWidth;\n        const bh = bubble.offsetHeight;\n\n        let left = (elRect.left - cardRect.left) + (elRect.width \/ 2) - (bw \/ 2);\n        if (left < margin) left = margin;\n        if (left + bw > cardRect.width - margin) left = Math.max(margin, cardRect.width - margin - bw);\n\n        let top = (elRect.top - cardRect.top) - bh - 10;\n        let arrowSide = 'bottom';\n        if (top < margin) {\n            top = (elRect.bottom - cardRect.top) + 10;\n            arrowSide = 'top';\n        }\n\n        bubble.style.left = left + 'px';\n        bubble.style.top = top + 'px';\n        bubble.classList.add('tt-arrow-' + arrowSide);\n\n        const elCenterInCard = (elRect.left - cardRect.left) + elRect.width \/ 2;\n        let arrowLeft = elCenterInCard - left;\n        arrowLeft = Math.max(10, Math.min(bw - 10, arrowLeft));\n        bubble.style.setProperty('--tt-arrow-left', arrowLeft + 'px');\n\n        activeTooltipBubble = bubble;\n    }\n    function attachHoverTooltip(el) {\n        if (!el) return;\n        const show = () => clampAndShowTooltip(el, el.dataset.tooltip);\n        el.addEventListener('mouseenter', show);\n        el.addEventListener('mouseleave', hideTooltip);\n        el.addEventListener('focus', show);\n        el.addEventListener('blur', hideTooltip);\n        el.addEventListener('touchstart', () => { show(); setTimeout(hideTooltip, 2000); }, { passive: true });\n    }\n    function attachClickTooltip(el, textFn) {\n        if (!el) return;\n        el.addEventListener('click', (e) => {\n            e.stopPropagation();\n            clampAndShowTooltip(el, typeof textFn === 'function' ? textFn() : textFn);\n            setTimeout(hideTooltip, 2500);\n        });\n    }\n    document.addEventListener('click', (e) => {\n        if (!activeTooltipBubble) return;\n        const anchor = activeTooltipBubble._anchorEl;\n        if (e.target.closest('.tt-bubble')) return;\n        if (anchor && anchor.contains(e.target)) return;\n        hideTooltip();\n    }, true);\n\n    async function logToGoogle(data) {\n        const userInfo = getActiveUserInfo();\n        data.user_id = userInfo.id; data.user_name = userInfo.name;\n        const LOG_URL = 'https:\/\/script.google.com\/macros\/s\/AKfycbz7ViqxDaSi1l2M0o4rsPHqS09qmgosQy34eIJmBhfd1hs2SBbRAuc3nrJC4D4KfBoPPQ\/exec';\n        try {\n            await fetch(LOG_URL, { method: 'POST', mode: 'no-cors', cache: 'no-cache', headers: { 'Content-Type': 'application\/json' }, body: JSON.stringify(data) });\n        } catch (e) { console.error(\"Logging Fehler:\", e); }\n    }\n\n    function dgNormalizeDate(dateStr) {\n        if (!dateStr) return \"\";\n        let pureDate = dateStr.trim().split(\" \")[0];\n        if (pureDate.includes('.')) return pureDate;\n        if (pureDate.includes('-')) {\n            const parts = pureDate.split('-');\n            if (parts[0].length === 4) return `${parts[2]}.${parts[1]}.${parts[0]}`;\n        }\n        return pureDate;\n    }\n    function dgTodayKey() {\n        return new Date().toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' });\n    }\n    async function loadDailyGoal() {\n        const userInfo = getActiveUserInfo();\n        const userName = String(userInfo.name || \"\").trim().toLowerCase();\n        const userId = String(userInfo.id || \"\").trim().toLowerCase();\n        try {\n            const res = await fetch(`${URL_GOAL}&_cb=${Date.now()}`);\n            const csvText = await res.text();\n            const lines = csvText.split(\/\\r?\\n\/);\n            dgBaseCounts = {}; dgTarget = null;\n            for (let i = 1; i < lines.length; i++) {\n                if (!lines[i]) continue;\n                const cols = lines[i].split(\/,(?=(?:(?:[^\"]*\"){2})*[^\"]*$)\/).map(v => v ? v.trim().replace(\/^\"|\"$\/g, '').replace(\/\"\"\/g, '\"') : \"\");\n                if (!(cols.length >= 3)) continue;\n                const rowUserId = (cols[1] || \"\").toLowerCase();\n                const rowName = (cols[2] || \"\").toLowerCase();\n                \/\/ Bei G\u00e4sten matchen wir bewusst NUR auf die individuelle Gast-ID\n                \/\/ (nicht auf den Namen \"Gast\", da sonst alle G\u00e4ste zusammengez\u00e4hlt w\u00fcrden).\n                const matches = userId.startsWith('guest-')\n                    ? (rowUserId && rowUserId === userId)\n                    : ((rowUserId && rowUserId === userId) || (rowName && rowName === userName));\n                if (matches) {\n                    const rowDate = dgNormalizeDate(cols[0]);\n                    const rowTargetRaw = cols[10] || cols[3];\n                    const rowTarget = parseInt(rowTargetRaw, 10);\n                    if (!isNaN(rowTarget) && rowTarget > 0) dgTarget = rowTarget;\n                    dgBaseCounts[rowDate] = (dgBaseCounts[rowDate] || 0) + 1;\n                }\n            }\n        } catch (e) { console.error(\"Tagesziel-Fehler:\", e); }\n        updateDailyGoalUI(true);\n        applyDailyLimitState();\n    }\n    function updateDailyGoalUI(animateFromZero) {\n        const goalEl = container.querySelector('.daily-goal');\n        const fillEl = container.querySelector('.dg-fill');\n        const countEl = container.querySelector('.dg-count');\n        if (!goalEl || !fillEl || !countEl) return;\n        const target = dgTarget || DEFAULT_DAILY_TARGET;\n        const todayCount = getTodaySentenceCount();\n        const pct = Math.min(Math.round((todayCount \/ target) * 100), 100);\n        countEl.textContent = `${todayCount} \/ ${target}`;\n        goalEl.classList.toggle('reached', todayCount >= target);\n        if (animateFromZero) {\n            fillEl.style.transition = 'none';\n            fillEl.style.width = '0%';\n            void fillEl.offsetWidth;\n            fillEl.style.transition = '';\n            requestAnimationFrame(() => { fillEl.style.width = pct + '%'; });\n        } else {\n            fillEl.style.width = pct + '%';\n        }\n    }\n\n    \/\/ ============ TAGESLIMIT-LOGIK ============\n    \/\/ Nutzt denselben Z\u00e4hler wie das Daily-Goal (heutige Check-Aktionen dieser\n    \/\/ Person), vergleicht ihn aber gegen ein hartes Limit je Nutzergruppe.\n    function getTodaySentenceCount() {\n        return (dgBaseCounts[dgTodayKey()] || 0) + dgLiveModifier;\n    }\n    function getCurrentDailyLimit() {\n        if (!window.wpTrainerUserInfo) return DAILY_LIMIT_GUEST;\n        const lvl = getUserAccessLevel();\n        return (lvl >= 2) ? DAILY_LIMIT_PAYER : DAILY_LIMIT_MEMBER;\n    }\n    function isDailyLimitReached() {\n        const limit = getCurrentDailyLimit();\n        if (!limit || limit <= 0) return false; \/\/ 0 = unbegrenzt\n        return getTodaySentenceCount() >= limit;\n    }\n    \/\/ Sperrt\/entsperrt die Check-\/Eingabe-Steuerung der aktuell sichtbaren\n    \/\/ Satzkarte, wenn das Tageslimit erreicht ist. Wird nach jedem Laden des\n    \/\/ Tagesziels und nach jeder best\u00e4tigten Antwort aufgerufen.\n    function applyDailyLimitState() {\n        const area = container.querySelector('#sentenceArea');\n        const block = area ? area.querySelector('.sentence-block') : null;\n        if (!block) return;\n        const limitReached = isDailyLimitReached();\n        block.classList.toggle('daily-limit-reached', limitReached);\n\n        const input = block.querySelector('textarea');\n        const revealWords = block.querySelectorAll('.reveal-word');\n        const checkBtn = block.querySelector('.control-item:nth-child(3) .btn-icon');\n        const hintBtn = block.querySelector('.control-item:nth-child(1) .btn-icon');\n        const micBtn = block.querySelector('.mic-in-input');\n\n        if (input) input.disabled = limitReached;\n        revealWords.forEach(w => { if (!w.classList.contains('revealed')) w.style.pointerEvents = limitReached ? 'none' : ''; });\n        if (checkBtn) checkBtn.classList.toggle('is-locked', limitReached);\n        if (hintBtn) hintBtn.classList.toggle('is-locked', limitReached);\n        if (micBtn) micBtn.style.pointerEvents = limitReached ? 'none' : '';\n\n        let noticeEl = block.querySelector('.daily-limit-notice');\n        if (limitReached) {\n            if (!noticeEl) {\n                noticeEl = document.createElement('div');\n                noticeEl.className = 'daily-limit-notice';\n                const feedbackWrapper = block.querySelector('.feedback-wrapper');\n                if (feedbackWrapper) feedbackWrapper.insertAdjacentElement('afterend', noticeEl);\n            }\n            const isGuest = !window.wpTrainerUserInfo;\n            noticeEl.innerHTML = `<strong>${UI_LANGUAGES[currentLang].dailyLimitReachedTitle}<\/strong><br>${isGuest ? UI_LANGUAGES[currentLang].dailyLimitReachedGuest : UI_LANGUAGES[currentLang].dailyLimitReachedMember}`;\n        } else if (noticeEl) {\n            noticeEl.remove();\n        }\n    }\n    window.addEventListener('tm-satz-bestaetigt', () => { dgLiveModifier++; updateDailyGoalUI(false); applyDailyLimitState(); });\n    window.addEventListener('tm-user-switched', () => {\n        dgLiveModifier = 0; loadDailyGoal();\n        if (state_topics.length) { renderTopics(); buildSession(); }\n    });\n\n    function shuffleCopy(arr) {\n        const a = arr.slice();\n        for (let i = a.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [a[i], a[j]] = [a[j], a[i]]; }\n        return a;\n    }\n\n    function getUserAccessLevel() {\n        const info = window.wpTrainerUserInfo;\n        const lvl = info && info.level != null ? parseInt(info.level, 10) : 1;\n        return (lvl === 2 || lvl === 3) ? lvl : 1;\n    }\n    function getTopicAccessLevel(topicId) {\n        if (!topicId) return 1;\n        const t = state_topics.find(t2 => t2.id === topicId);\n        return t ? (t.accessLevel || 1) : 1;\n    }\n    function isTopicUnlocked(topicId) {\n        return getTopicAccessLevel(topicId) <= getUserAccessLevel();\n    }\n\n    async function loadData() {\n        try {\n            const [csvS, csvT] = await Promise.all([fetch(URL_S).then(r => r.text()), fetch(URL_T).then(r => r.text())]);\n            const rowsS = csvS.split(\/\\r?\\n\/).slice(1);\n            allData = rowsS.map(row => {\n                const cols = row.split(\/,(?=(?:(?:[^\"]*\"){2})*[^\"]*$)\/);\n                const clean = (v) => v ? v.trim().replace(\/^\"|\"$\/g, '').replace(\/\"\"\/g, '\"') : \"\";\n                return { id: clean(cols[0]), level: clean(cols[1]), topicId: clean(cols[2]), de: clean(cols[4]), en: clean(cols[5]), es: clean(cols[6]), alt: clean(cols[7]) };\n            }).filter(r => r.de);\n\n            const rowsT = csvT.split(\/\\r?\\n\/).slice(1);\n            state_topics = rowsT.map(row => {\n                const cols = row.split(\/,(?=(?:(?:[^\"]*\"){2})*[^\"]*$)\/);\n                const clean = (v) => v ? v.trim().replace(\/^\"|\"$\/g, '').replace(\/\"\"\/g, '\"') : \"\";\n                const accessRaw = parseInt(clean(cols[10]), 10);\n                const accessLevel = (accessRaw === 2 || accessRaw === 3) ? accessRaw : 1;\n                return {\n                    level: clean(cols[0]),\n                    id: clean(cols[1]),\n                    topicTitle: clean(cols[2]),\n                    area: clean(cols[3]),\n                    name: clean(cols[4]),\n                    nameEn: clean(cols[5]),\n                    nameEs: clean(cols[6]),\n                    infoDe: clean(cols[7]),\n                    infoEn: clean(cols[8]),\n                    infoEs: clean(cols[9]),\n                    accessLevel: accessLevel\n                };\n            });\n            updateInterfaceStrings();\n            renderTopics();\n            buildSession();\n        } catch (e) { console.error(\"Fehler beim Laden:\", e); }\n    }\n\n    function updateInterfaceStrings() {\n        if (filterTitleEl) filterTitleEl.textContent = UI_LANGUAGES[currentLang].topicTitle;\n        if (topicSearchEl) topicSearchEl.placeholder = UI_LANGUAGES[currentLang].searchPlaceholder;\n        updateFilterToggleLabel();\n        updateMobileFullToggleUI();\n    }\n\n    function updateFilterToggleLabel() {\n        const levelBadge = container.querySelector('#fcLevelBadge');\n        const eyebrow = container.querySelector('#fcEyebrow');\n        const topicName = container.querySelector('#fcTopicName');\n        if (!levelBadge || !topicName) return;\n\n        if (eyebrow) eyebrow.textContent = UI_LANGUAGES[currentLang].topicEyebrow;\n        levelBadge.textContent = currentLevel;\n\n        if (!currentTopicId) {\n            topicName.textContent = UI_LANGUAGES[currentLang].allTopics;\n            return;\n        }\n        const t = state_topics.find(t2 => t2.id === currentTopicId);\n        if (t) {\n            topicName.textContent = t.topicTitle || t.name || t.id;\n        } else {\n            topicName.textContent = currentTopicId;\n        }\n    }\n\n    function updateMobileFullToggleUI() {\n        const btn = container.querySelector('#mobileFullToggle');\n        if (!btn) return;\n        const toggled = container.classList.contains('full-input-mode');\n        const isMobileWidth = window.matchMedia('(max-width: 800px)').matches;\n        const defaultIsPuzzle = isMobileWidth;\n        const puzzleShowing = defaultIsPuzzle !== toggled;\n        btn.classList.toggle('active', !puzzleShowing);\n        const icon = btn.querySelector('.mft-icon');\n        const label = btn.querySelector('.mft-label');\n        if (icon) icon.textContent = puzzleShowing ? '\u2328\ufe0f' : '\ud83e\udde9';\n        if (label) label.textContent = puzzleShowing ? UI_LANGUAGES[currentLang].fullModeOn : UI_LANGUAGES[currentLang].fullModeOff;\n    }\n\n    function updateAllTopicsBtnState() {\n        const btn = allTopicsBtnEl;\n        if (!btn) return;\n        btn.textContent = UI_LANGUAGES[currentLang].allTopics;\n        btn.classList.toggle('active', !currentTopicId);\n    }\n\n    function renderTopics() {\n        const list = topicListEl;\n        const searchInput = topicSearchEl;\n        if (!list) return;\n        list.innerHTML = \"\";\n        updateAllTopicsBtnState();\n\n        const term = searchInput ? searchInput.value.toLowerCase().trim() : \"\";\n        let filtered;\n        let crossLevelSearch = false;\n        const areaPool = MANUAL_TOPIC_AREA ? state_topics.filter(t => t.area === MANUAL_TOPIC_AREA) : state_topics;\n        if (term) {\n            crossLevelSearch = true;\n            filtered = areaPool.filter(t => {\n                const haystacks = [t.name, t.nameEn, t.nameEs, t.topicTitle, t.id].map(v => (v || \"\").toLowerCase());\n                return haystacks.some(h => h.includes(term));\n            });\n        } else {\n            filtered = areaPool.filter(t => t.level === currentLevel);\n        }\n\n        const userLevel = getUserAccessLevel();\n        filtered.forEach(t => {\n            const topicName = (currentLang === 'en' ? t.nameEn : t.nameEs) || t.name;\n            let activeInfo = t.infoDe;\n            if (currentLang === 'en') activeInfo = t.infoEn || t.infoDe;\n            if (currentLang === 'es') activeInfo = t.infoEs || t.infoDe;\n            const levelBadge = crossLevelSearch ? `<span class=\"topic-level-badge\">${t.level}<\/span>` : '';\n            const infoText = (activeInfo || \"\").replace(\/\\n\/g, '<br>');\n\n            const topicAccess = t.accessLevel || 1;\n            const isLocked = topicAccess > userLevel;\n            const lockLabel = topicAccess >= 3 ? UI_LANGUAGES[currentLang].lockedPaidList : UI_LANGUAGES[currentLang].lockedLoginList;\n            const lockBadge = isLocked ? `<span class=\"topic-lock-badge\">\ud83d\udd12 ${lockLabel}<\/span>` : '';\n\n            const li = document.createElement('li');\n            li.className = \"topic-item\" + (currentTopicId === t.id ? \" active\" : \"\") + (isLocked ? \" locked\" : \"\");\n            li.innerHTML = `\n                <div class=\"topic-row\">\n                    <span class=\"topic-id-big\">${t.id}<\/span>\n                    <div class=\"topic-text-wrapper\">\n                        <div class=\"topic-title-text\">${t.topicTitle || \"\"}<\/div>\n                        <div class=\"topic-name-row\">${topicName}${levelBadge}<\/div>\n                        ${lockBadge}\n                    <\/div>\n                    <button class=\"topic-expand-btn\" type=\"button\" aria-expanded=\"false\">\u25be<\/button>\n                <\/div>\n                <div class=\"topic-info-panel\">${infoText || \"\"}<\/div>`;\n\n            const row = li.querySelector('.topic-row');\n            const expandBtn = li.querySelector('.topic-expand-btn');\n            const infoPanel = li.querySelector('.topic-info-panel');\n\n            row.onclick = (e) => {\n                if (e.target.closest('.topic-expand-btn')) return;\n                if (isLocked) {\n                    infoPanel.innerHTML = `<strong>${topicAccess >= 3 ? UI_LANGUAGES[currentLang].lockedPaid : UI_LANGUAGES[currentLang].lockedLogin}<\/strong>`;\n                    infoPanel.classList.add('open');\n                    expandBtn.classList.add('open');\n                    expandBtn.setAttribute('aria-expanded', 'true');\n                    return;\n                }\n                currentTopicId = t.id;\n                if (t.level !== currentLevel) {\n                    currentLevel = t.level;\n                    if (levelBtnGroupEl) levelBtnGroupEl.querySelectorAll('.level-btn').forEach(b => b.classList.toggle('active', b.dataset.level === currentLevel));\n                }\n                closeFilterDrawer();\n                renderTopics();\n                buildSession();\n            };\n            expandBtn.onclick = (e) => {\n                e.stopPropagation();\n                const willOpen = !infoPanel.classList.contains('open');\n                if (willOpen && isLocked) infoPanel.innerHTML = `<strong>${topicAccess >= 3 ? UI_LANGUAGES[currentLang].lockedPaid : UI_LANGUAGES[currentLang].lockedLogin}<\/strong>`;\n                else if (willOpen) infoPanel.innerHTML = infoText || \"\";\n                infoPanel.classList.toggle('open', willOpen);\n                expandBtn.classList.toggle('open', willOpen);\n                expandBtn.setAttribute('aria-expanded', String(willOpen));\n            };\n            list.appendChild(li);\n        });\n        updateFilterToggleLabel();\n    }\n\n    function captureCurrentAnswer() {\n        const area = container.querySelector('#sentenceArea');\n        const ta = area ? area.querySelector('textarea') : null;\n        if (ta) sessionAnswers[sessionIndex] = ta.value;\n    }\n    function buildSession() {\n        let poolAll = allData.filter(d => d.level === currentLevel);\n        if (MANUAL_TOPIC_AREA) {\n            poolAll = poolAll.filter(d => {\n                const t = state_topics.find(t2 => t2.id === d.topicId);\n                return t && t.area === MANUAL_TOPIC_AREA;\n            });\n        }\n        if (currentTopicId) poolAll = poolAll.filter(d => d.topicId === currentTopicId);\n        const pool = currentTopicId ? poolAll.filter(d => isTopicUnlocked(d.topicId)) : poolAll;\n        sessionAnswers = {};\n        if (pool.length === 0) {\n            session = [];\n            if (poolAll.length > 0) {\n                const requiredLevel = Math.min(...poolAll.map(d => getTopicAccessLevel(d.topicId)));\n                renderLockedState(requiredLevel);\n            } else {\n                renderEmptyState();\n            }\n            return;\n        }\n        const ordered = shuffleCopy(pool);\n        session = ordered.slice(0, Math.min(SESSION_SIZE, ordered.length));\n        sessionIndex = 0;\n        renderCurrentSentence();\n    }\n    function goToNext() {\n        captureCurrentAnswer();\n        sessionIndex++;\n        if (sessionIndex >= session.length) { buildSession(); return; }\n        renderCurrentSentence();\n    }\n    function goToPrevious() {\n        if (sessionIndex <= 0) return;\n        captureCurrentAnswer();\n        sessionIndex--;\n        renderCurrentSentence();\n    }\n    function renderEmptyState() {\n        const area = container.querySelector('#sentenceArea');\n        area.innerHTML = `<div class=\"sentence-block empty-state\">${UI_LANGUAGES[currentLang].noData}<\/div>`;\n    }\n    function renderLockedState(requiredLevel) {\n        const area = container.querySelector('#sentenceArea');\n        const msg = requiredLevel >= 3 ? UI_LANGUAGES[currentLang].lockedPaid : UI_LANGUAGES[currentLang].lockedLogin;\n        area.innerHTML = `<div class=\"sentence-block empty-state\">\ud83d\udd12 ${msg}<\/div>`;\n    }\n    function renderCurrentSentence() {\n        const area = container.querySelector('#sentenceArea');\n        area.innerHTML = \"\";\n        if (session.length === 0) { renderEmptyState(); return; }\n        area.appendChild(createSentenceBlock(session[sessionIndex]));\n        updateDailyGoalUI(true);\n        applyDailyLimitState();\n    }\n\n    function isBookmarked(s) { return bookmarksMemory.some(b => b.de === s.de); }\n\n    function createSentenceBlock(initialS) {\n        const block = document.createElement(\"div\");\n        block.className = \"sentence-block\";\n        block.dataset.sentence = JSON.stringify(initialS);\n        block.dataset.tipLevel = 0;\n        const isB = isBookmarked(initialS);\n\n        const userLevel = getUserAccessLevel();\n        const canListen = userLevel >= 2;\n        const canSave = userLevel >= 3;\n        const saveTooltip = canSave\n            ? UI_LANGUAGES[currentLang].saveHint\n            : (userLevel >= 2 ? UI_LANGUAGES[currentLang].saveUpgradeHint : UI_LANGUAGES[currentLang].saveLockedHint);\n\n        block.innerHTML = `\n            <button class=\"save-btn ${isB ? 'saved' : ''} ${canSave ? '' : 'is-locked'}\" data-tooltip=\"${saveTooltip}\">${isB ? '\u2b50' : '\u2606'}<\/button>\n            <span class=\"save-toast\"><\/span>\n            <button class=\"lang-indicator\" data-tooltip=\"${UI_LANGUAGES[currentLang].langHint}\">${currentLang === 'en' ? '\ud83c\uddfa\ud83c\uddf8' : '\ud83c\uddea\ud83c\uddf8'}<\/button>\n            <button class=\"fullscreen-toggle-btn\" data-tooltip=\"${UI_LANGUAGES[currentLang].fullscreenHint || 'Fullscreen'}\">\u26f6<\/button>\n            <div class=\"source\">${initialS[currentLang]}<\/div>\n            <div class=\"input-wrapper\">\n                <textarea placeholder=\"${UI_LANGUAGES[currentLang].placeholder}\"><\/textarea>\n                <button class=\"mic-in-input\" data-tooltip=\"${UI_LANGUAGES[currentLang].micHint}\">\ud83c\udfa4<\/button>\n            <\/div>\n            <div class=\"reveal-wrapper\"><\/div>\n            <div class=\"reveal-alt-holder\"><\/div>\n            <div class=\"feedback-wrapper\"><div class=\"feedback\"><\/div><\/div>\n            <div class=\"sentence-controls\"><\/div>\n            <div class=\"daily-goal\">\n                <div class=\"dg-top\">\n                    <span class=\"dg-label\">${UI_LANGUAGES[currentLang].dailyGoalLabel}<\/span>\n                    <span class=\"dg-count\">0 \/ ${dgTarget || DEFAULT_DAILY_TARGET}<\/span>\n                <\/div>\n                <div class=\"dg-track\"><div class=\"dg-fill\"><\/div><\/div>\n            <\/div>\n        `;\n        const input = block.querySelector(\"textarea\");\n        const micBtn = block.querySelector(\".mic-in-input\");\n        const fb = block.querySelector(\".feedback\");\n        const fbWrapper = block.querySelector(\".feedback-wrapper\");\n        const saveBtn = block.querySelector(\".save-btn\");\n        const saveToast = block.querySelector(\".save-toast\");\n        const langInd = block.querySelector(\".lang-indicator\");\n        const fsBtn = block.querySelector(\".fullscreen-toggle-btn\");\n        const ctrlArea = block.querySelector(\".sentence-controls\");\n        const revealWrapper = block.querySelector(\".reveal-wrapper\");\n        const revealAltHolder = block.querySelector(\".reveal-alt-holder\");\n        const dgCountEl = block.querySelector(\".dg-count\");\n\n        attachHoverTooltip(saveBtn);\n        attachHoverTooltip(langInd);\n        attachHoverTooltip(fsBtn);\n        attachHoverTooltip(micBtn);\n        attachHoverTooltip(fbWrapper);\n        attachClickTooltip(dgCountEl, () => UI_LANGUAGES[currentLang].dailyGoalAdjustHint);\n\n        saveBtn.onclick = () => {\n            if (!canSave) return;\n            const s = JSON.parse(block.dataset.sentence);\n            const idx = bookmarksMemory.findIndex(b => b.de === s.de);\n            let actionType = \"\";\n            if (idx > -1) { bookmarksMemory.splice(idx, 1); saveBtn.classList.remove('saved'); saveBtn.textContent = '\u2606'; actionType = \"Bookmark entfernt\"; }\n            else {\n                bookmarksMemory.push(s); saveBtn.classList.add('saved'); saveBtn.textContent = '\u2b50'; actionType = \"Bookmark gesetzt\";\n                if (saveToast) {\n                    saveToast.textContent = UI_LANGUAGES[currentLang].savedToast;\n                    clearTimeout(saveToast._hideTimer);\n                    clearTimeout(saveToast._resetTimer);\n                    saveToast.classList.remove('hide');\n                    void saveToast.offsetWidth;\n                    saveToast.classList.add('show');\n                    saveToast._hideTimer = setTimeout(() => {\n                        saveToast.classList.remove('show');\n                        saveToast.classList.add('hide');\n                        saveToast._resetTimer = setTimeout(() => saveToast.classList.remove('hide'), 2300);\n                    }, 700);\n                }\n            }\n            logToGoogle({ sentence_id: s.id, level: currentLevel, topic: s.topicId || \"Mix\", german: s.de, translation: s[currentLang], action: actionType, status: \"-\", user_input: \"\" });\n        };\n\n        if (fsBtn) {\n            fsBtn.onclick = () => {\n                if (fsApiSupported) {\n                    if (!isContainerFullscreen()) {\n                        const reqFs = container.requestFullscreen || container.webkitRequestFullscreen;\n                        if (reqFs) reqFs.call(container);\n                    } else {\n                        const exitFs = document.exitFullscreen || document.webkitExitFullscreen;\n                        if (exitFs) exitFs.call(document);\n                    }\n                } else {\n                    if (container.classList.contains('pseudo-fullscreen')) deactivatePseudoFullscreen();\n                    else activatePseudoFullscreen();\n                }\n            };\n            updateFsBtnIcon();\n        }\n\n        langInd.onclick = () => {\n            currentLang = (currentLang === 'en' ? 'es' : 'en');\n            updateInterfaceStrings();\n            renderTopics();\n            const data = JSON.parse(block.dataset.sentence);\n            block.querySelector('.source').textContent = data[currentLang];\n            langInd.textContent = (currentLang === 'en' ? '\ud83c\uddfa\ud83c\uddf8' : '\ud83c\uddea\ud83c\uddf8');\n            langInd.dataset.tooltip = UI_LANGUAGES[currentLang].langHint;\n            saveBtn.dataset.tooltip = canSave\n                ? UI_LANGUAGES[currentLang].saveHint\n                : (userLevel >= 2 ? UI_LANGUAGES[currentLang].saveUpgradeHint : UI_LANGUAGES[currentLang].saveLockedHint);\n            micBtn.dataset.tooltip = UI_LANGUAGES[currentLang].micHint;\n            if (input) input.placeholder = UI_LANGUAGES[currentLang].placeholder;\n            const labels = block.querySelectorAll('.btn-label');\n            if (labels.length >= 5) {\n                labels[0].textContent = UI_LANGUAGES[currentLang].btnHint;\n                labels[1].textContent = UI_LANGUAGES[currentLang].btnListen;\n                labels[2].textContent = UI_LANGUAGES[currentLang].btnCheck;\n                labels[3].textContent = UI_LANGUAGES[currentLang].btnPrev;\n                labels[4].textContent = UI_LANGUAGES[currentLang].btnNew;\n            }\n            const icons = block.querySelectorAll('.control-item .btn-icon');\n            if (icons.length >= 2 && !canListen) icons[1].dataset.tooltip = UI_LANGUAGES[currentLang].listenLockedHint;\n            const altDiv = block.querySelector(\".solution-text\");\n            if (altDiv) altDiv.textContent = ALT_LABEL + data.alt;\n            const dgLabelEl = block.querySelector(\".dg-label\");\n            if (dgLabelEl) dgLabelEl.textContent = UI_LANGUAGES[currentLang].dailyGoalLabel;\n            applyDailyLimitState();\n        };\n\n        function autoResize() { input.style.height = '0px'; input.style.height = Math.max(46, input.scrollHeight) + 'px'; }\n        input.addEventListener('input', autoResize);\n        if (sessionAnswers[sessionIndex]) { input.value = sessionAnswers[sessionIndex]; autoResize(); }\n\n        const check = () => {\n            if (isDailyLimitReached()) { applyDailyLimitState(); return; }\n            const s = JSON.parse(block.dataset.sentence);\n            fb.innerHTML = \"\";\n            const topicInfo = s.topicId ? `Grammer Topic ${s.topicId} (${s.level})` : `no specific grammar topic (${s.level})`;\n            fbWrapper.setAttribute('data-tooltip', topicInfo);\n\n            const targetWordsOriginal = s.de.split(\/\\s+\/).filter(Boolean);\n            const targetNorm = targetWordsOriginal.map(normalize);\n            const userWordsOriginal = input.value.trim().split(\/\\s+\/).filter(Boolean);\n            const userNorm = userWordsOriginal.map(normalize);\n            const alignment = alignWords(targetNorm, userNorm);\n            const usedUserIdx = new Set(alignment.filter(x => x !== null));\n\n            targetWordsOriginal.forEach((word, idx) => {\n                const span = document.createElement(\"span\");\n                span.textContent = word;\n                const uIdx = alignment[idx];\n                if (uIdx !== null) { span.className = (userNorm[uIdx] === targetNorm[idx]) ? \"correct\" : \"tip\"; }\n                else {\n                    const foundElsewhere = userNorm.some((uw, k) => !usedUserIdx.has(k) && wordsEqualFuzzy(uw, targetNorm[idx]));\n                    span.className = foundElsewhere ? \"tip\" : \"missing\";\n                }\n                fb.appendChild(span);\n                fb.appendChild(document.createTextNode(\" \"));\n            });\n            if (s.alt) {\n                const altDiv = document.createElement(\"div\");\n                altDiv.className = \"solution-text\";\n                altDiv.textContent = ALT_LABEL + s.alt;\n                fb.appendChild(altDiv);\n            }\n            const isCorrect = normalize(input.value) === normalize(s.de);\n            window.dispatchEvent(new CustomEvent('tm-satz-bestaetigt'));\n            logToGoogle({ sentence_id: s.id, level: currentLevel, topic: s.topicId || \"Mix\", german: s.de, translation: s[currentLang], action: \"Check\", status: isCorrect ? \"Richtig\" : \"Falsch\", user_input: input.value });\n        };\n\n        if ('webkitSpeechRecognition' in window) {\n            const rec = new webkitSpeechRecognition();\n            rec.continuous = true; rec.interimResults = true; rec.lang = 'de-DE'; rec.maxAlternatives = 1;\n            let isListening = false; let autoStopTimer = null;\n            const resetTimer = () => {\n                if (autoStopTimer) clearTimeout(autoStopTimer);\n                autoStopTimer = setTimeout(() => { if (isListening) rec.stop(); }, 5000);\n            };\n            rec.onstart = () => { isListening = true; input.classList.add(\"recording-active\"); micBtn.classList.add(\"recording-active\"); resetTimer(); };\n            rec.onerror = (event) => { console.error(\"Spracherkennungsfehler:\", event.error); rec.stop(); };\n            rec.onend = () => {\n                isListening = false; input.classList.remove(\"recording-active\"); micBtn.classList.remove(\"recording-active\");\n                if (autoStopTimer) clearTimeout(autoStopTimer);\n                if (input.value) { let text = input.value.trim(); if (text.length > 0) input.value = text.charAt(0).toUpperCase() + text.slice(1); }\n            };\n            rec.onresult = (e) => {\n                let currentTranscript = '';\n                for (let i = 0; i < e.results.length; ++i) {\n                    let word = e.results[i][0].transcript;\n                    currentTranscript += (i > 0 && !word.startsWith(' ')) ? ' ' + word : word;\n                }\n                input.value = currentTranscript.replace(\/\\s\\s+\/g, ' ');\n                autoResize(); resetTimer();\n            };\n            micBtn.onclick = (e) => {\n                e.preventDefault();\n                if (isDailyLimitReached()) return;\n                if (isListening) { rec.stop(); }\n                else { input.value = \"\"; if (window.speechSynthesis.speaking) window.speechSynthesis.cancel(); rec.start(); }\n            };\n        }\n\n        let revealedCount = 0;\n        let revealCorrectCount = 0;\n        function finalizeRevealIfComplete() {\n            if (revealWrapper.children.length === 0 || revealedCount !== revealWrapper.children.length) return;\n            const s2 = JSON.parse(block.dataset.sentence);\n            revealAltHolder.innerHTML = \"\";\n            if (s2.alt) {\n                const altDiv = document.createElement('div');\n                altDiv.className = 'solution-text';\n                altDiv.textContent = ALT_LABEL + s2.alt;\n                revealAltHolder.appendChild(altDiv);\n            }\n            const isCorrect = (revealCorrectCount === revealedCount);\n            window.dispatchEvent(new CustomEvent('tm-satz-bestaetigt'));\n            logToGoogle({ sentence_id: s2.id, level: currentLevel, topic: s2.topicId || \"Mix\", german: s2.de, translation: s2[currentLang], action: \"Mobile Aufdecken\", status: isCorrect ? \"Richtig\" : \"Teilweise\", user_input: `${revealCorrectCount}\/${revealedCount} gewusst` });\n        }\n        function buildRevealWord(word) {\n            const span = document.createElement('span');\n            span.className = 'reveal-word';\n            span.textContent = word;\n            let startX = null; let dragged = false; const threshold = 22;\n            const reveal = (isKnown) => {\n                if (span.classList.contains('revealed')) return;\n                if (isDailyLimitReached()) return;\n                span.classList.add('revealed', isKnown ? 'correct-word' : 'wrong-word');\n                revealedCount++; if (isKnown) revealCorrectCount++;\n                finalizeRevealIfComplete();\n            };\n            span.addEventListener('pointerdown', (e) => { if (span.classList.contains('revealed') || isDailyLimitReached()) return; startX = e.clientX; dragged = false; span.classList.add('dragging'); });\n            span.addEventListener('pointermove', (e) => { if (startX === null) return; if (Math.abs(e.clientX - startX) > 6) dragged = true; });\n            const finish = (e) => {\n                if (startX === null) return;\n                const dx = (e.clientX || 0) - startX;\n                startX = null; span.classList.remove('dragging');\n                if (!dragged) { reveal(true); return; }\n                if (dx <= -threshold) reveal(false); else if (dx >= threshold) reveal(true);\n            };\n            span.addEventListener('pointerup', finish);\n            span.addEventListener('pointercancel', () => { startX = null; span.classList.remove('dragging'); });\n            return span;\n        }\n        function renderRevealWords(sentenceDe) {\n            revealWrapper.innerHTML = \"\"; revealAltHolder.innerHTML = \"\";\n            revealedCount = 0; revealCorrectCount = 0;\n            sentenceDe.split(\/\\s+\/).filter(Boolean).forEach(w => revealWrapper.appendChild(buildRevealWord(w)));\n        }\n        function revealAllRemaining() {\n            let changed = false;\n            Array.from(revealWrapper.children).forEach(span => {\n                if (!span.classList.contains('revealed')) { span.classList.add('revealed', 'wrong-word'); revealedCount++; changed = true; }\n            });\n            if (changed) finalizeRevealIfComplete();\n        }\n        renderRevealWords(initialS.de);\n\n        const createBtn = (icon, labelKey, fn, opts) => {\n            opts = opts || {};\n            const div = document.createElement(\"div\");\n            div.className = \"control-item\";\n            const lockAttrs = opts.locked ? ` data-tooltip=\"${opts.lockedTooltip || ''}\"` : '';\n            div.innerHTML = `<button class=\"btn-icon${opts.locked ? ' is-locked' : ''}\"${lockAttrs}>${icon}<\/button><div class=\"btn-label\">${UI_LANGUAGES[currentLang][labelKey]}<\/div>`;\n            const btnEl = div.querySelector(\"button\");\n            btnEl.onclick = opts.locked ? () => {} : fn;\n            if (opts.locked) attachHoverTooltip(btnEl);\n            return div;\n        };\n        ctrlArea.appendChild(createBtn(\"\ud83d\udca1\", \"btnHint\", () => {\n            if (isDailyLimitReached()) return;\n            const s = JSON.parse(block.dataset.sentence);\n            let tipL = (parseInt(block.dataset.tipLevel) || 0) + 1;\n            block.dataset.tipLevel = tipL;\n            fb.innerHTML = s.de.split(\" \").map(w => `<span class=\"tip\">${w.slice(0, tipL)}${tipL < w.length ? '...' : ''}<\/span> `).join(\"\");\n        }));\n        ctrlArea.appendChild(createBtn(\"\ud83d\udd0a\", \"btnListen\", () => { const s = JSON.parse(block.dataset.sentence); speakText(s.de); }, { locked: !canListen, lockedTooltip: UI_LANGUAGES[currentLang].listenLockedHint }));\n        ctrlArea.appendChild(createBtn(\"\u2713\", \"btnCheck\", () => {\n            if (window.matchMedia('(max-width: 800px)').matches && !container.classList.contains('full-input-mode')) revealAllRemaining(); else check();\n        }));\n        const prevItem = createBtn('<span style=\"display:inline-block;transform:rotate(180deg);\">\u279c<\/span>', \"btnPrev\", () => goToPrevious());\n        if (sessionIndex <= 0) prevItem.querySelector(\".btn-icon\").classList.add(\"is-disabled\");\n        ctrlArea.appendChild(prevItem);\n        ctrlArea.appendChild(createBtn(\"\u279c\", \"btnNew\", goToNext));\n\n        input.onkeydown = (e) => { if (e.key === \"Enter\") { e.preventDefault(); check(); } };\n        applyDailyLimitState();\n        return block;\n    }\n\n    function scrollToActiveTopic() {\n        if (!topicListEl) return;\n        const activeItem = topicListEl.querySelector('.topic-item.active');\n        if (activeItem) {\n            activeItem.scrollIntoView({ block: 'start', behavior: 'auto' });\n        } else {\n            topicListEl.scrollTop = 0;\n        }\n    }\n    function openFilterDrawer() {\n        if (filterOverlayEl) document.body.appendChild(filterOverlayEl);\n        if (filterOverlayEl) filterOverlayEl.classList.add('open');\n        document.body.style.overflow = 'hidden';\n        requestAnimationFrame(() => requestAnimationFrame(scrollToActiveTopic));\n    }\n    function closeFilterDrawer() {\n        if (filterOverlayEl) filterOverlayEl.classList.remove('open');\n        document.body.style.overflow = '';\n    }\n    container.querySelector('#filterToggleBtn').onclick = openFilterDrawer;\n    if (filterCloseBtn) filterCloseBtn.onclick = closeFilterDrawer;\n    if (filterOverlayEl) filterOverlayEl.addEventListener('click', (e) => {\n        if (e.target === filterOverlayEl) closeFilterDrawer();\n    });\n\n    const mobileFullBtn = container.querySelector('#mobileFullToggle');\n    if (mobileFullBtn) {\n        mobileFullBtn.onclick = () => {\n            container.classList.toggle('full-input-mode');\n            updateMobileFullToggleUI();\n        };\n    }\n\n    if (levelBtnGroupEl) {\n        levelBtnGroupEl.querySelectorAll('.level-btn').forEach(btn => {\n            btn.onclick = (e) => {\n                currentLevel = e.target.dataset.level;\n                levelBtnGroupEl.querySelectorAll('.level-btn').forEach(b => b.classList.remove('active'));\n                e.target.classList.add('active');\n                currentTopicId = null;\n                renderTopics();\n                buildSession();\n            };\n        });\n    }\n    if (allTopicsBtnEl) allTopicsBtnEl.onclick = () => { currentTopicId = null; closeFilterDrawer(); renderTopics(); buildSession(); };\n    if (topicSearchEl) topicSearchEl.oninput = () => { renderTopics(); };\n\n    \/\/ Obere Leiste bleibt IMMER sichtbar (dient nur noch als \u00dcberschrift).\n    \/\/ Bei SHOW_TOPIC_BAR = false wird lediglich der Klick deaktiviert und der\n    \/\/ Eyebrow-Text (\"Current topic \u2014 tap to change\") sowie der Pfeil (Caret)\n    \/\/ ausgeblendet, da beide eine Interaktion suggerieren, die nicht mehr\n    \/\/ m\u00f6glich ist. FIX: setProperty(...,'important') statt .style.display=,\n    \/\/ da die zugeh\u00f6rigen CSS-Regeln display mit !important setzen.\n    if (!SHOW_TOPIC_BAR) {\n        const toggleBtn = container.querySelector('#filterToggleBtn');\n        if (toggleBtn) toggleBtn.onclick = null;\n        const eyebrowEl = container.querySelector('#fcEyebrow');\n        const caretEl = container.querySelector('.fc-caret');\n        if (eyebrowEl) eyebrowEl.style.setProperty('display', 'none', 'important');\n        if (caretEl) caretEl.style.setProperty('display', 'none', 'important');\n    }\n\n    updateMobileFullToggleUI();\n    window.addEventListener('resize', updateMobileFullToggleUI);\n    loadData();\n    loadDailyGoal();\n})(document.currentScript.parentElement);\n<\/script><\/div>\n\n\n\n<\/div><\/div>\n\n<div class=\"dash-p p3\">\n<div class=\"spx-role\" data-role=\"free\"><div class=\"lock\"><div class=\"lk\">\ud83d\udd12<\/div><h3>This area is for paying members only<\/h3><p>Upgrade to Plus to save sentences, track them with traffic lights and practise them again.<\/p><a class=\"btn b-teal\" href=\"https:\/\/sofapiano.com\/membership-join\/\">More Info!<\/a><\/div><\/div>\n<style id=\"saved-design\">\n\/* Saved Sentences \u2013 an aktuelles Dashboard-Design angepasst (wei\u00df, Teal, Fraunces\/Inter), volle Breite *\/\n.dash .p3 .tm-bookmark-container{max-width:none!important;width:100%!important;margin:0!important;color:#1D2427!important;font-family:'Inter','Segoe UI',Roboto,sans-serif!important}\n.dash .p3 .tm-bookmark-header{padding:18px 20px!important;margin-bottom:16px!important;background:#fff!important;border:1px solid #E7E2D8!important;border-radius:22px!important;box-shadow:0 10px 26px rgba(29,36,39,.04)!important}\n.dash .p3 .tm-search-box input{height:44px!important;padding:10px 14px 10px 34px!important;background:#F7FAFB!important;border:1px solid #E5EEF1!important;border-radius:12px!important;color:#1D2427!important;font-size:14px!important}\n.dash .p3 .tm-search-box input:focus{background:#fff!important;border-color:#14708C!important;box-shadow:0 0 0 3px #E2F0F4!important}\n.dash .p3 .tm-search-box::before{border-color:#4B565A!important}\n.dash .p3 .tm-search-box::after{background:#4B565A!important}\n.dash .p3 .btn-blur-toggle{background:#fff!important;border:1px solid #E7E2D8!important;color:#0E5367!important;box-shadow:none!important}\n.dash .p3 .btn-blur-toggle:hover{background:#F2F8FA!important;border-color:#14708C!important}\n.dash .p3 .btn-blur-toggle.active,.dash .p3 .btn-add-toggle.active{background:#14708C!important;border-color:#14708C!important;color:#fff!important;box-shadow:0 4px 10px rgba(20,112,140,.25)!important}\n.dash .p3 .tooltip-wrapper::after{background:#1D2427!important}\n.dash .p3 .tooltip-wrapper::before{border-top-color:#1D2427!important}\n.dash .p3 .tm-filter-row{margin-top:14px!important}\n.dash .p3 .tm-filter-btn{height:30px!important;background:#fff!important;border:1px solid #E7E2D8!important;color:#4B565A!important;box-shadow:none!important;font-size:12.5px!important}\n.dash .p3 .tm-filter-btn:hover{border-color:#14708C!important;color:#0E5367!important}\n.dash .p3 .tm-filter-btn.active{background:#14708C!important;border-color:#14708C!important;color:#fff!important;box-shadow:0 4px 10px rgba(20,112,140,.25)!important}\n.dash .p3 .tm-filter-btn.color-btn{width:26px!important;height:26px!important;border:3px solid #fff!important;box-shadow:0 0 0 1px #E7E2D8!important}\n.dash .p3 .tm-filter-btn.color-btn.active{transform:none!important;box-shadow:0 0 0 2px #14708C!important}\n.dash .p3 .tm-filter-btn.color-btn[data-filter=\"gr\u00fcn\"]{background:#3BAA7E!important}\n.dash .p3 .tm-filter-btn.color-btn[data-filter=\"gelb\"]{background:#F2B630!important}\n.dash .p3 .tm-filter-btn.color-btn[data-filter=\"rot\"]{background:#E06A5A!important}\n.dash .p3 .tm-input-box input{background:#F7FAFB!important;border:1px solid #E5EEF1!important;border-radius:12px!important;color:#1D2427!important}\n.dash .p3 .tm-input-box input:focus{background:#fff!important;border-color:#14708C!important;box-shadow:0 0 0 3px #E2F0F4!important}\n.dash .p3 .tm-bookmark-list{gap:10px!important;max-height:640px!important;padding:2px 6px 2px 0!important}\n.dash .p3 .tm-bookmark-list::-webkit-scrollbar-track{background:transparent!important}\n.dash .p3 .tm-bookmark-list::-webkit-scrollbar-thumb{background:#C7DDE4!important}\n.dash .p3 .tm-bookmark-item{padding:16px 18px 18px!important;background:#fff!important;border:1px solid #E7E2D8!important;border-left:4px solid #E7E2D8!important;border-radius:16px!important;box-shadow:0 6px 18px rgba(29,36,39,.03)!important}\n.dash .p3 .tm-bookmark-item:hover{border-color:#C7DDE4!important}\n.dash .p3 .tm-bookmark-item.status-gruen{background:#F4FBF7!important;border-left-color:#3BAA7E!important}\n.dash .p3 .tm-bookmark-item.status-gelb{background:#FFFAEC!important;border-left-color:#F2B630!important}\n.dash .p3 .tm-bookmark-item.status-rot{background:#FDF4F2!important;border-left-color:#E06A5A!important}\n.dash .p3 .tm-bookmark-text-group{gap:5px!important;padding-right:170px!important}\n.dash .p3 .tm-bookmark-de{font-family:'Fraunces',Georgia,serif!important;font-size:17px!important;font-weight:600!important;line-height:1.35!important;color:#1D2427!important}\n.dash .p3 .tm-bookmark-trans{font-size:14px!important;font-style:normal!important;font-weight:500!important;color:#4B565A!important}\n.dash .p3 .tm-bookmark-meta{margin-top:6px!important}\n.dash .p3 .tm-b-badge{padding:3px 9px!important;border-radius:999px!important;font-size:11px!important;font-weight:700!important;border:0!important;opacity:1!important}\n.dash .p3 .tm-b-badge.level{background:#14708C!important;color:#fff!important}\n.dash .p3 .tm-b-badge.custom-level{background:#FFF3C4!important;color:#6B4A00!important}\n.dash .p3 .tm-b-badge.topic{background:#E2F0F4!important;color:#0E5367!important}\n.dash .p3 .tm-control-group{right:14px!important;bottom:14px!important;padding:3px 6px!important;background:#fff!important;border:1px solid #E7E2D8!important;border-radius:999px!important;box-shadow:none!important}\n.dash .p3 .tm-btn-traffic:hover,.dash .p3 .btn-blur-single:hover{background:#F2F8FA!important}\n.dash .p3 .btn-blur-single{border:0!important;box-shadow:none!important;width:26px!important;height:26px!important;border-radius:50%!important;color:inherit!important}\n.dash .p3 .btn-blur-single.active{background:#E2F0F4!important}\n.dash .p3 .tm-bookmark-loading,.dash .p3 .tm-bookmark-empty{color:#4B565A!important;background:#fff!important;border:1px dashed #E7E2D8!important;border-radius:16px!important}\n@media (max-width:600px){.dash .p3 .tm-bookmark-header{padding:14px!important}.dash .p3 .tm-bookmark-text-group{padding-right:0!important;padding-bottom:38px!important}}\n<\/style>\n<style id=\"spx-saved-compact\">\n\/* Saved Sentences kompakt: Kopf in einer Zeile, Deutsch links, Uebersetzung rechts *\/\n#spx-saved .tm-bookmark-header{display:flex!important;flex-wrap:wrap!important;align-items:center!important;column-gap:10px!important;row-gap:0!important;padding:12px 14px!important;margin-bottom:12px!important}\n#spx-saved .tm-search-row{display:contents!important}\n#spx-saved .tm-search-row>:first-child{order:1;flex:none}\n#spx-saved .tm-search-box{order:2;flex:1 1 100px!important;min-width:0!important;margin:0!important}\n#spx-saved .tm-search-box input{height:40px!important}\n#spx-saved .tm-filter-row{order:3;flex:none!important;flex-wrap:nowrap!important;gap:6px!important;margin:0!important}\n#spx-saved .tm-search-row>:last-child{order:4;flex:none}\n#spx-saved .tm-add-sentence-drawer{order:5;flex:0 0 100%!important}\n#spx-saved .tm-bookmark-list{gap:8px!important}\n#spx-saved .tm-bookmark-item{display:grid!important;grid-template-columns:minmax(0,1fr) auto!important;align-items:center!important;gap:14px!important;padding:9px 12px 9px 14px!important}\n#spx-saved .tm-bookmark-text-group{display:grid!important;grid-template-columns:minmax(0,1fr) minmax(0,1fr)!important;column-gap:20px!important;row-gap:3px!important;padding:0!important}\n#spx-saved .tm-bookmark-de{font-size:15px!important;line-height:1.3!important}\n#spx-saved .tm-bookmark-trans{font-size:14px!important;line-height:1.35!important}\n#spx-saved .tm-bookmark-meta{grid-column:1 \/ -1!important;margin:0!important}\n#spx-saved .tm-b-badge{padding:1px 8px!important;font-size:10.5px!important}\n#spx-saved .tm-control-group{position:static!important;flex:none!important}\n\/* Bereiche der Karte trennen: Deutsch | Uebersetzung | Knoepfe, darunter Level und Thema *\/\n#spx-saved .tm-bookmark-text-group{column-gap:0!important;row-gap:0!important}\n#spx-saved .tm-bookmark-de{padding:2px 16px 6px 0!important}\n#spx-saved .tm-bookmark-trans{padding:2px 0 6px 16px!important;border-left:1px solid rgba(29,36,39,.14)!important}\n#spx-saved .tm-bookmark-meta{padding-top:6px!important;border-top:1px solid rgba(29,36,39,.14)!important}\n#spx-saved .tm-control-group{align-self:stretch!important;padding:0 0 0 12px!important;background:transparent!important;border:0!important;border-left:1px solid rgba(29,36,39,.14)!important;border-radius:0!important;box-shadow:none!important}\n@media (max-width:600px){\n#spx-saved .tm-bookmark-header{column-gap:6px!important;padding:10px!important}\n#spx-saved .tm-search-box{flex-basis:60px!important}\n#spx-saved .tm-search-box input{height:36px!important;padding-right:6px!important}\n#spx-saved .tm-bookmark-header .btn-blur-toggle{width:36px!important;height:36px!important}\n#spx-saved .tm-filter-row{gap:4px!important}\n#spx-saved .tm-filter-btn{height:26px!important;padding:0 8px!important}\n#spx-saved .tm-filter-btn.color-btn{width:20px!important;height:20px!important;padding:0!important;border-width:2px!important}\n#spx-saved .tm-bookmark-item{grid-template-columns:minmax(0,1fr)!important;gap:0!important}\n#spx-saved .tm-bookmark-text-group{grid-template-columns:minmax(0,1fr)!important;padding:0!important}\n#spx-saved .tm-bookmark-de{padding:0 0 6px!important}\n#spx-saved .tm-bookmark-trans{padding:6px 0!important;border-left:0!important;border-top:1px solid rgba(29,36,39,.14)!important}\n#spx-saved .tm-bookmark-meta{padding-right:160px!important;min-height:36px!important}\n#spx-saved .tm-control-group{align-self:end!important;justify-self:end!important;height:30px!important;margin-top:-31px!important;padding-left:8px!important}\n}\n<\/style>\n<div class=\"tm-bookmark-container\" id=\"spx-saved\">\n    <div class=\"tm-bookmark-header\">\n        <!-- Suchzeile -->\n        <div class=\"tm-search-row\">\n            <div class=\"tooltip-wrapper\" id=\"tm-add-tooltip-wrapper\" data-tooltip=\"Add new sentence\">\n                <button type=\"button\" class=\"btn-blur-toggle btn-add-toggle\" id=\"tm-bookmark-add-btn\">\u2795<\/button>\n            <\/div>\n            <div class=\"tm-search-box\">\n                <input type=\"text\" id=\"tm-bookmark-search\" placeholder=\"Search...\">\n            <\/div>\n            <div class=\"tooltip-wrapper\" id=\"tm-blur-tooltip-wrapper\" data-tooltip=\"Hide German translation\">\n                <button type=\"button\" class=\"btn-blur-toggle\" id=\"tm-bookmark-blur-btn\">\ud83d\udc41\ufe0f<\/button>\n            <\/div>\n        <\/div>\n\n        <!-- Filter Buttons -->\n        <div class=\"tm-filter-row\" id=\"tm-filter-row\">\n            <button class=\"tm-filter-btn active\" data-filter=\"all\" id=\"tm-filter-all-btn\">All<\/button>\n            <button class=\"tm-filter-btn color-btn\" data-filter=\"gr\u00fcn\" title=\"Gr\u00fcn (Gelernt)\"><\/button>\n            <button class=\"tm-filter-btn color-btn\" data-filter=\"gelb\" title=\"Gelb (Unsicher)\"><\/button>\n            <button class=\"tm-filter-btn color-btn\" data-filter=\"rot\" title=\"Rot (Wiederholen)\"><\/button>\n        <\/div>\n\n        <!-- Eingabefelder -->\n        <div class=\"tm-add-sentence-drawer\" id=\"tm-add-drawer\">\n            <div class=\"tm-add-sentence-row\">\n                <div class=\"tm-input-box\">\n                    <input type=\"text\" id=\"tm-custom-de\" placeholder=\"Deutscher Satz\">\n                <\/div>\n                <div class=\"tm-input-box\">\n                    <input type=\"text\" id=\"tm-custom-trans\" placeholder=\"\u00dcbersetzung\">\n                <\/div>\n                <div class=\"tm-input-box\">\n                    <input type=\"text\" id=\"tm-custom-topic\" placeholder=\"Thema (optional)\">\n                <\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n\n    <!-- Ergebnisliste -->\n    <div id=\"tm-bookmark-list\" class=\"tm-bookmark-list\">\n        <div class=\"tm-bookmark-loading\">Loading...<\/div>\n    <\/div>\n<\/div>\n\n<style>\n@import url('https:\/\/fonts.googleapis.com\/css2?family=Fraunces:opsz,wght@9..144,500;9..144,600&family=Inter:wght@500;600;700&display=swap');\n\n.tm-bookmark-container, .tm-bookmark-container * { box-sizing: border-box !important; }\n\n.tm-bookmark-container {\n    --font-serif: 'Fraunces', Georgia, 'Times New Roman', serif;\n    --ink: #475569;\n    --muted: #7B8799;\n    --paper: #F4F8FC;\n    --card: #FFFFFF;\n    --line: #E0E6EE;\n\n    --accent: #475569;\n    --accent-rgb: 71, 85, 105;\n    --accent-soft: #E8EEF5;\n    --accent-ink: #1E293B;\n    --accent-solid: #475569;\n    --accent-solid-rgb: 71, 85, 105;\n\n    --correct: #DDF2E9; --correct-ink: #0E7A59; --correct-border: #9BDBC2;\n    --tip: #FBEECB; --tip-ink: #8A5A00; --tip-border: #E9C46A;\n    --missing: #FAE1E7; --missing-ink: #A63150; --missing-border: #EBA5B7;\n\n\nmax-width: calc(640px * var(--card-scale, 1));\nwidth: 100%;\nmargin: 0 auto !important;\n\n    font-family: 'Inter', 'Segoe UI', Roboto, Helvetica, Arial, sans-serif !important;\n    color: var(--ink) !important; position: relative !important;\n}\n\n\/* ---- Kopfbereich als Karte ---- *\/\n.tm-bookmark-header {\n    background: var(--card) !important;\n    border: none !important;\n    border-radius: 18px !important;\n    padding: 16px !important;\n    margin-bottom: 15px !important;\n    box-shadow: none !important;\n}\n\n\/* ---- Suchzeile ---- *\/\n.tm-search-row { display: flex !important; align-items: center !important; gap: 10px !important; width: 100% !important; }\n\n.tm-search-box { flex-grow: 1 !important; position: relative !important; }\n.tm-search-box::before {\n    content: \"\" !important; position: absolute !important; left: 13px !important; top: 50% !important;\n    width: 11px !important; height: 11px !important; transform: translateY(-60%) !important;\n    border: 1.5px solid var(--muted) !important; border-radius: 50% !important; box-sizing: border-box !important;\n    pointer-events: none !important; opacity: 0.7 !important;\n}\n.tm-search-box::after {\n    content: \"\" !important; position: absolute !important; width: 5.5px !important; height: 1.5px !important;\n    background: var(--muted) !important; border-radius: 1px !important; opacity: 0.7 !important;\n    left: 21px !important; top: 62% !important; transform: translateY(-50%) rotate(45deg) !important;\n    transform-origin: left center !important; pointer-events: none !important;\n}\n.tm-search-box input {\n    width: 100% !important; padding: 9px 12px 9px 32px !important; border: 1px solid var(--line) !important;\n    border-radius: 10px !important; font-size: 0.85rem !important; font-weight: 500 !important; font-family: inherit !important;\n    background: var(--paper) !important; color: var(--ink) !important;\n    transition: border-color 0.2s, box-shadow 0.2s, background 0.2s !important;\n}\n.tm-search-box input::placeholder { color: var(--muted) !important; opacity: 0.7 !important; }\n.tm-search-box input:focus { outline: none !important; border-color: var(--accent) !important; background: var(--card) !important; box-shadow: 0 0 0 3px var(--accent-soft) !important; }\n\n\/* ---- Filter-Zeile (Pill + Farbpunkte) ---- *\/\n.tm-filter-row { display: flex !important; gap: 8px !important; margin-top: 12px !important; align-items: center !important; flex-wrap: wrap !important; }\n.tm-filter-btn {\n    padding: 5px 14px !important; border: 1px solid var(--line) !important; border-radius: 20px !important;\n    background: var(--card) !important; cursor: pointer !important; font-size: 0.8rem !important; font-weight: 700 !important;\n    color: var(--muted) !important; font-family: inherit !important; transition: all 0.2s ease !important;\n    display: flex !important; align-items: center !important; justify-content: center !important; height: 30px !important;\n    box-shadow: 0 1px 2px rgba(28,27,26,0.04) !important;\n}\n.tm-filter-btn:hover { border-color: var(--accent) !important; transform: translateY(-1px) !important; }\n.tm-filter-btn.active {\n    border-color: var(--accent-solid) !important; color: white !important;\n    background: var(--accent-solid) !important; box-shadow: 0 3px 8px rgba(var(--accent-solid-rgb), 0.35) !important;\n}\n.tm-filter-btn.color-btn { width: 28px !important; padding: 0 !important; border-radius: 50% !important; border: 2px solid var(--card) !important; box-shadow: 0 1px 3px rgba(28,27,26,0.15) !important; }\n.tm-filter-btn.color-btn:hover { border-color: var(--line) !important; transform: scale(1.08) !important; }\n.tm-filter-btn.color-btn.active { border-color: var(--ink) !important; transform: scale(1.15) !important; box-shadow: 0 0 0 3px var(--paper) !important; }\n\n\/* FIX: .tm-filter-btn setzt oben \"background: var(--card) !important\", das war spezifischer\n   als der reine Inline-style=\"background:...\", und hat die Farben daher immer \u00fcberschrieben\n   -> die Kreise blieben wei\u00df. Diese Regeln haben durch die zus\u00e4tzliche Attribut-Selektion\n   eine h\u00f6here Spezifit\u00e4t und setzen die echten Farben zuverl\u00e4ssig. *\/\n.tm-filter-btn.color-btn[data-filter=\"gr\u00fcn\"] { background: #10B981 !important; }\n.tm-filter-btn.color-btn[data-filter=\"gelb\"] { background: #F59E0B !important; }\n.tm-filter-btn.color-btn[data-filter=\"rot\"]  { background: #EF4444 !important; }\n\n\/* ---- Ausklapp-Drawer f\u00fcr neue S\u00e4tze ---- *\/\n.tm-add-sentence-drawer { max-height: 0 !important; overflow: hidden !important; transition: max-height 0.25s ease-out, margin-top 0.25s ease-out !important; margin-top: 0 !important; }\n.tm-add-sentence-drawer.open { max-height: 200px !important; margin-top: 15px !important; }\n\n.tm-add-sentence-row { display: flex !important; align-items: center !important; gap: 10px !important; width: 100% !important; }\n.tm-input-box { flex: 1 !important; }\n.tm-input-box input {\n    width: 100% !important; padding: 12px 14px !important; border: 1px solid var(--line) !important;\n    border-radius: 12px !important; font-size: 0.9rem !important; font-family: inherit !important;\n    background: var(--card) !important; color: var(--ink) !important; transition: border-color 0.2s, box-shadow 0.2s !important;\n}\n.tm-input-box input::placeholder { color: var(--muted) !important; }\n.tm-input-box input:focus { outline: none !important; border-color: var(--correct-ink) !important; box-shadow: 0 0 0 3px var(--correct) !important; }\n\n.tm-bookmark-container .btn-add-toggle.active { background-color: var(--correct-ink) !important; color: white !important; border-color: var(--correct-ink) !important; }\n\n\/* ---- Tooltip ---- *\/\n.tm-bookmark-container .tooltip-wrapper { position: relative !important; display: inline-block !important; }\n.tm-bookmark-container .tooltip-wrapper::after {\n    content: attr(data-tooltip) !important; position: absolute !important; bottom: 125% !important; left: 50% !important;\n    transform: translateX(-50%) scale(0.85) !important; background-color: var(--ink) !important; color: #ffffff !important;\n    padding: 6px 10px !important; border-radius: 8px !important; font-size: 11px !important; font-weight: 600 !important;\n    white-space: nowrap !important; opacity: 0 !important; pointer-events: none !important;\n    transition: all 0.15s ease-in-out !important; z-index: 99999 !important; box-shadow: 0 6px 16px rgba(0,0,0,0.22) !important;\n}\n.tm-bookmark-container .tooltip-wrapper::before {\n    content: \"\" !important; position: absolute !important; bottom: 110% !important; left: 50% !important;\n    transform: translateX(-50%) !important; border-width: 5px !important; border-style: solid !important;\n    border-color: var(--ink) transparent transparent transparent !important; opacity: 0 !important;\n    transition: all 0.15s ease-in-out !important; pointer-events: none !important; z-index: 99999 !important;\n}\n.tm-bookmark-container .tooltip-wrapper:hover::after, .tm-bookmark-container .tooltip-wrapper:hover::before { opacity: 1 !important; transform: translateX(-50%) scale(1) !important; }\n\n\/* ---- Icon-Buttons (\u2795 \/ \ud83d\udc41\ufe0f) ---- *\/\n.tm-bookmark-container .btn-blur-toggle {\n    width: 44px !important; height: 44px !important; border-radius: 12px !important; font-size: 16px !important;\n    cursor: pointer !important; background: var(--card) !important; display: flex !important; align-items: center !important;\n    justify-content: center !important; border: 1.5px solid var(--line) !important; transition: all 0.15s ease !important;\n    color: var(--muted) !important; outline: none !important; box-shadow: 0 1px 2px rgba(28,27,26,0.04) !important;\n    padding: 0 !important; flex-shrink: 0 !important;\n}\n.tm-bookmark-container .btn-blur-toggle:hover { background-color: var(--paper) !important; border-color: var(--accent) !important; color: var(--accent-ink) !important; transform: translateY(-1px) !important; }\n.tm-bookmark-container .btn-blur-toggle:active { transform: scale(0.95) !important; }\n.tm-bookmark-container .btn-blur-toggle.active { background-color: var(--accent-solid) !important; color: white !important; border-color: var(--accent-solid) !important; box-shadow: 0 3px 8px rgba(var(--accent-solid-rgb), 0.35) !important; }\n\n.tm-bookmark-container .btn-blur-single {\n    border: none !important; background: transparent !important; font-size: 0.95rem !important; cursor: pointer !important;\n    padding: 2px !important; border-radius: 6px !important; transition: transform 0.1s, background-color 0.1s !important;\n    display: flex !important; align-items: center !important; justify-content: center !important; width: 26px !important; height: 26px !important;\n}\n.tm-bookmark-container .btn-blur-single:hover { background-color: var(--paper) !important; transform: scale(1.12) !important; }\n.tm-bookmark-container .btn-blur-single.active { background-color: var(--accent-soft) !important; }\n\n\/* ---- Blur-Logik ---- *\/\n.tm-bookmark-de { transition: filter 0.2s ease !important; }\n.tm-bookmark-container.blur-active .tm-bookmark-de { filter: blur(6px) !important; user-select: none !important; }\n.tm-bookmark-container.blur-active .tm-bookmark-item.reveal-active .tm-bookmark-de { filter: none !important; user-select: text !important; }\n.tm-bookmark-container:not(.blur-active) .tm-bookmark-item.blur-single-active .tm-bookmark-de { filter: blur(6px) !important; user-select: none !important; }\n\n\/* ---- Liste + Scrollbar ---- *\/\n.tm-bookmark-list {\n    display: flex !important; flex-direction: column !important; gap: 12px !important; min-height: 100px !important;\n    max-height: 500px !important; overflow-y: auto !important; padding-right: 6px !important;\n}\n.tm-bookmark-list::-webkit-scrollbar { width: 6px !important; }\n.tm-bookmark-list::-webkit-scrollbar-track { background: var(--paper) !important; border-radius: 4px !important; }\n.tm-bookmark-list::-webkit-scrollbar-thumb { background: var(--line) !important; border-radius: 4px !important; }\n.tm-bookmark-list::-webkit-scrollbar-thumb:hover { background: var(--muted) !important; }\n\n\/* ---- Satz-Karten ---- *\/\n.tm-bookmark-item {\n    padding: 16px 16px 20px 16px !important; background: var(--card) !important; border-radius: 18px !important;\n    display: flex !important; justify-content: space-between !important; align-items: flex-start !important; gap: 15px !important;\n    box-shadow: none !important;\n    transition: all 0.2s ease !important; border: none !important; border-left: 6px solid var(--line) !important;\n    position: relative !important;\n}\n.tm-bookmark-item:hover { transform: translateY(-1px) !important; }\n.tm-bookmark-item.status-gruen { border-left-color: #10B981 !important; background-color: var(--correct) !important; }\n.tm-bookmark-item.status-gelb { border-left-color: #F59E0B !important; background-color: var(--tip) !important; }\n.tm-bookmark-item.status-rot { border-left-color: #EF4444 !important; background-color: var(--missing) !important; }\n\n.tm-bookmark-item.updating { opacity: 0.3 !important; pointer-events: none !important; }\n.tm-bookmark-text-group { display: flex !important; flex-direction: column !important; gap: 4px !important; flex-grow: 1 !important; padding-right: 140px !important; }\n.tm-bookmark-de { font-family: var(--font-serif) !important; font-size: 1.02rem !important; font-weight: 600 !important; color: var(--ink) !important; margin: 0 !important; }\n.tm-bookmark-trans { font-size: 0.88rem !important; font-weight: 500 !important; color: var(--muted) !important; font-style: italic !important; margin: 0 !important; }\n\n.tm-bookmark-meta { display: flex !important; gap: 6px !important; flex-wrap: wrap !important; align-items: center !important; margin-top: 4px !important; }\n.tm-b-badge { font-size: 0.65rem !important; font-weight: 700 !important; padding: 2px 7px !important; border-radius: 6px !important; }\n.tm-b-badge.topic { background: var(--accent-soft) !important; color: var(--accent-ink) !important; }\n.tm-b-badge.level { background: var(--paper) !important; color: var(--muted) !important; border: 1px solid var(--line) !important; }\n.tm-b-badge.custom-level { background: var(--accent-soft) !important; color: var(--accent-ink) !important; opacity: 0.85 !important; }\n\n\/* ---- Status-\/Aktions-Buttons ---- *\/\n.tm-control-group {\n    position: absolute !important; right: 12px !important; bottom: 12px !important; display: flex !important; gap: 3px !important;\n    background: var(--card) !important; padding: 3px 5px !important; border-radius: 10px !important; border: 1px solid var(--line) !important;\n    align-items: center !important; box-shadow: 0 1px 2px rgba(28,27,26,0.05) !important;\n}\n.tm-btn-traffic {\n    border: none !important; background: transparent !important; font-size: 0.9rem !important; cursor: pointer !important;\n    padding: 2px !important; border-radius: 6px !important; transition: transform 0.1s, background-color 0.1s !important;\n    display: flex !important; align-items: center !important; justify-content: center !important; width: 26px !important; height: 26px !important;\n}\n.tm-btn-traffic:hover { background-color: var(--paper) !important; transform: scale(1.12) !important; }\n.tm-btn-traffic:active { transform: scale(0.95) !important; }\n.tm-btn-traffic.btn-delete:hover { background-color: var(--missing) !important; }\n\n.tm-bookmark-loading, .tm-bookmark-empty {\n    text-align: center !important; color: var(--muted) !important; font-size: 0.85rem !important; font-weight: 600 !important; padding: 30px 0 !important;\n}\n.tm-bookmark-loading { animation: tmLoadingPulse 1.3s ease-in-out infinite !important; }\n@keyframes tmLoadingPulse { 0%, 100% { opacity: 0.55; } 50% { opacity: 1; } }\n\n@media (max-width: 600px) {\n    .tm-add-sentence-row { flex-direction: column !important; align-items: stretch !important; }\n    .tm-add-sentence-drawer.open { max-height: 300px !important; }\n    .tm-bookmark-text-group { padding-right: 0 !important; padding-bottom: 35px !important; }\n}\n<\/style>\n\n<script>\n(function() {\n    const CONFIG = {\n        csvUrl: \"https:\/\/docs.google.com\/spreadsheets\/d\/1pGfdVy3yDtzS56FIxiP4KsHHYuKUqPWVG18ULv9wxi4\/export?format=csv&gid=588315623\",\n        bookmarkColIndex: 8,\n        scriptUrl: \"https:\/\/script.google.com\/macros\/s\/AKfycbz7ViqxDaSi1l2M0o4rsPHqS09qmgosQy34eIJmBhfd1hs2SBbRAuc3nrJC4D4KfBoPPQ\/exec\"\n    };\n\n    \/\/ ---- i18n: Texte passen sich automatisch an die Sprache der Website an (de \/ en \/ es) ----\n    const I18N = {\n        de: {\n            search_placeholder: \"Suchen...\",\n            tooltip_add: \"Neuen Satz hinzuf\u00fcgen\",\n            tooltip_hide: \"Deutsche \u00dcbersetzung ausblenden\",\n            tooltip_show: \"Deutsche \u00dcbersetzung anzeigen\",\n            filter_all: \"Alle\",\n            filter_gruen: \"Gr\u00fcn (Gelernt)\",\n            filter_gelb: \"Gelb (Unsicher)\",\n            filter_rot: \"Rot (Wiederholen)\",\n            input_de: \"Deutscher Satz\",\n            input_trans: \"\u00dcbersetzung\",\n            input_topic: \"Thema (optional)\",\n            loading: \"Wird geladen...\",\n            empty_filtered: \"Keine passenden S\u00e4tze f\u00fcr diesen Filter gefunden.\",\n            empty_none: \"Du hast aktuell keine markierten S\u00e4tze.\",\n            error_loading: \"Fehler beim Laden der Daten.\",\n            tip_hide_single: \"Satz verbergen\/anzeigen\",\n            tip_delete: \"Aus Liste l\u00f6schen\",\n            default_topic: \"Eigene S\u00e4tze\",\n            default_level: \"Dein Satz\",\n            default_translation: \"Keine \u00dcbersetzung vorhanden\",\n            guest: \"Gast\"\n        },\n        en: {\n            search_placeholder: \"Search...\",\n            tooltip_add: \"Add new sentence\",\n            tooltip_hide: \"Hide German translation\",\n            tooltip_show: \"Show German translation\",\n            filter_all: \"All\",\n            filter_gruen: \"Green (Learned)\",\n            filter_gelb: \"Yellow (Unsure)\",\n            filter_rot: \"Red (Repeat)\",\n            input_de: \"German sentence\",\n            input_trans: \"Translation\",\n            input_topic: \"Topic (optional)\",\n            loading: \"Loading...\",\n            empty_filtered: \"No matching sentences found for this filter.\",\n            empty_none: \"You don't have any bookmarked sentences yet.\",\n            error_loading: \"Error loading data.\",\n            tip_hide_single: \"Hide\/show sentence\",\n            tip_delete: \"Remove from list\",\n            default_topic: \"Custom sentences\",\n            default_level: \"Your sentence\",\n            default_translation: \"No translation available\",\n            guest: \"Guest\"\n        },\n        es: {\n            search_placeholder: \"Buscar...\",\n            tooltip_add: \"A\u00f1adir nueva frase\",\n            tooltip_hide: \"Ocultar traducci\u00f3n al alem\u00e1n\",\n            tooltip_show: \"Mostrar traducci\u00f3n al alem\u00e1n\",\n            filter_all: \"Todo\",\n            filter_gruen: \"Verde (Aprendida)\",\n            filter_gelb: \"Amarillo (Insegura)\",\n            filter_rot: \"Rojo (Repasar)\",\n            input_de: \"Frase en alem\u00e1n\",\n            input_trans: \"Traducci\u00f3n\",\n            input_topic: \"Tema (opcional)\",\n            loading: \"Cargando...\",\n            empty_filtered: \"No se encontraron frases para este filtro.\",\n            empty_none: \"Todav\u00eda no tienes frases guardadas.\",\n            error_loading: \"Error al cargar los datos.\",\n            tip_hide_single: \"Ocultar\/mostrar frase\",\n            tip_delete: \"Eliminar de la lista\",\n            default_topic: \"Frases propias\",\n            default_level: \"Tu frase\",\n            default_translation: \"Sin traducci\u00f3n disponible\",\n            guest: \"Invitado\"\n        }\n    };\n\n    function detectLang() {\n        const raw = (document.documentElement.lang || navigator.language || \"de\").toLowerCase();\n        const short = raw.slice(0, 2);\n        return I18N[short] ? short : \"en\";\n    }\n\n    const LANG = detectLang();\n    const T = I18N[LANG];\n\n    let bookmarkedSentences = [];\n    let globalBlurActive = false;\n    let currentColorFilter = 'all';\n    let loadToken = 0; \/\/ NEU: verhindert, dass veraltete Antworten die Liste \u00fcberschreiben\n\n    function applyStaticTranslations() {\n        const searchInput = document.getElementById('tm-bookmark-search');\n        if (searchInput) searchInput.placeholder = T.search_placeholder;\n\n        const addWrapper = document.getElementById('tm-add-tooltip-wrapper');\n        if (addWrapper) addWrapper.setAttribute('data-tooltip', T.tooltip_add);\n\n        const blurWrapper = document.getElementById('tm-blur-tooltip-wrapper');\n        if (blurWrapper) blurWrapper.setAttribute('data-tooltip', globalBlurActive ? T.tooltip_show : T.tooltip_hide);\n\n        const allBtn = document.getElementById('tm-filter-all-btn');\n        if (allBtn) allBtn.textContent = T.filter_all;\n\n        document.querySelectorAll('.tm-filter-btn.color-btn').forEach(btn => {\n            const key = btn.getAttribute('data-filter');\n            const map = { 'gr\u00fcn': T.filter_gruen, gelb: T.filter_gelb, rot: T.filter_rot };\n            if (map[key]) btn.setAttribute('title', map[key]);\n        });\n\n        const deInput = document.getElementById('tm-custom-de');\n        if (deInput) deInput.placeholder = T.input_de;\n        const transInput = document.getElementById('tm-custom-trans');\n        if (transInput) transInput.placeholder = T.input_trans;\n        const topicInput = document.getElementById('tm-custom-topic');\n        if (topicInput) topicInput.placeholder = T.input_topic;\n\n        const loadingEl = document.querySelector('.tm-bookmark-loading');\n        if (loadingEl) loadingEl.textContent = T.loading;\n    }\n\n    function parseCSV(text) {\n        let r = [];\n        let insideQuote = false;\n        let entry = '';\n        for (let i = 0; text.length > i; i++) {\n            let c = text[i];\n            if (c === '\"') {\n                insideQuote = !insideQuote;\n            } else if (c === ',' && !insideQuote) {\n                r.push(entry);\n                entry = '';\n            } else {\n                entry += c;\n            }\n        }\n        r.push(entry);\n        return r;\n    }\n\n    async function updateTrafficLightInBackend(sentenceObj, newStatus) {\n        const userName = String(window.wpTrainerUserInfo?.name || T.guest).trim();\n        const userId = String(window.wpTrainerUserInfo?.id || T.guest).trim();\n\n        const payload = {\n            user_id: userId,\n            user_name: userName,\n            sentence_id: sentenceObj.satzId,\n            level: sentenceObj.level,\n            topic: sentenceObj.thema,\n            german: sentenceObj.deutsch,\n            translation: sentenceObj.uebersetzung,\n            action: newStatus,\n            status: newStatus,\n            user_input: \"\"\n        };\n\n        try {\n            await fetch(CONFIG.scriptUrl, {\n                method: 'POST',\n                mode: 'no-cors',\n                headers: { 'Content-Type': 'application\/json' },\n                body: JSON.stringify(payload)\n            });\n        } catch(e) {\n            console.error(\"Fehler beim Senden an Google Apps Script:\", e);\n        }\n    }\n\n    async function handleAddToggleClick() {\n        const drawer = document.getElementById('tm-add-drawer');\n        const addBtn = document.getElementById('tm-bookmark-add-btn');\n        const deInput = document.getElementById('tm-custom-de');\n        const transInput = document.getElementById('tm-custom-trans');\n        const topicInput = document.getElementById('tm-custom-topic');\n\n        if (!drawer || !addBtn || !deInput || !transInput || !topicInput) return;\n\n        if (!drawer.classList.contains('open')) {\n            drawer.classList.add('open');\n            addBtn.classList.add('active');\n            deInput.focus();\n            return;\n        }\n\n        const deText = deInput.value.trim();\n        const transText = transInput.value.trim();\n        const topicText = topicInput.value.trim();\n\n        if (!deText) {\n            drawer.classList.remove('open');\n            addBtn.classList.remove('active');\n            return;\n        }\n\n        const userName = String(window.wpTrainerUserInfo?.name || T.guest).trim();\n        const userId = String(window.wpTrainerUserInfo?.id || T.guest).trim();\n        const tempRowId = \"custom-\" + Date.now();\n\n        \/\/ Neue, selbst hinzugef\u00fcgte S\u00e4tze starten direkt auf Rot (statt Grau\/\"bookmark gesetzt\")\n        const newSentence = {\n            rowId: tempRowId,\n            satzId: \"EIGEN-\" + Date.now(),\n            status: \"rot\",\n            level: T.default_level,\n            thema: topicText || T.default_topic,\n            deutsch: deText,\n            uebersetzung: transText || T.default_translation,\n            custom: true \/\/ interner Marker, unabh\u00e4ngig von der Anzeigesprache\n        };\n\n        bookmarkedSentences.unshift(newSentence);\n        const searchInput = document.getElementById('tm-bookmark-search');\n        renderBookmarkList(searchInput ? searchInput.value : \"\");\n\n        deInput.value = \"\";\n        transInput.value = \"\";\n        topicInput.value = \"\";\n        drawer.classList.remove('open');\n        addBtn.classList.remove('active');\n\n        const payload = {\n            user_id: userId,\n            user_name: userName,\n            sentence_id: newSentence.satzId,\n            level: newSentence.level,\n            topic: newSentence.thema,\n            german: newSentence.deutsch,\n            translation: newSentence.uebersetzung,\n            action: \"rot\",\n            status: \"rot\",\n            user_input: \"\"\n        };\n\n        try {\n            await fetch(CONFIG.scriptUrl, {\n                method: 'POST',\n                mode: 'no-cors',\n                headers: { 'Content-Type': 'application\/json' },\n                body: JSON.stringify(payload)\n            });\n        } catch(e) {\n            console.error(\"Fehler beim Speichern:\", e);\n        }\n    }\n\n    function renderBookmarkList(filterText = \"\") {\n        const container = document.getElementById('tm-bookmark-list');\n        if (!container) return;\n\n        const filtered = bookmarkedSentences.filter(s => {\n            let textMatch = true;\n            if (filterText) {\n                const search = filterText.toLowerCase();\n                textMatch = s.deutsch.toLowerCase().includes(search) || s.uebersetzung.toLowerCase().includes(search);\n            }\n\n            let colorMatch = true;\n            if (currentColorFilter !== 'all') {\n                colorMatch = (s.status === currentColorFilter);\n            }\n\n            return textMatch && colorMatch;\n        });\n\n        if (filtered.length === 0) {\n            container.innerHTML = `<div class=\"tm-bookmark-empty\">${filterText || currentColorFilter !== 'all' ? T.empty_filtered : T.empty_none}<\/div>`;\n            return;\n        }\n\n        container.innerHTML = filtered.map(s => {\n            const currentIcon = globalBlurActive ? '\ud83d\ude48' : '\ud83d\udc41\ufe0f';\n\n            let statusClass = '';\n            if (s.status === 'gr\u00fcn') statusClass = 'status-gruen';\n            if (s.status === 'gelb') statusClass = 'status-gelb';\n            if (s.status === 'rot') statusClass = 'status-rot';\n\n            const isCustom = s.custom === true || s.level === \"Deine Notiz\" || s.level === \"Dein Satz\";\n            const levelBadgeClass = isCustom ? \"tm-b-badge custom-level\" : \"tm-b-badge level\";\n            const levelIcon = isCustom ? \"\ud83d\udc64\" : \"\u26a1\";\n\n            return `\n                <div class=\"tm-bookmark-item ${statusClass}\" id=\"tm-bk-${s.rowId}\">\n                    <div class=\"tm-bookmark-text-group\">\n                        <p class=\"tm-bookmark-de\">\ud83c\udde9\ud83c\uddea ${s.deutsch}<\/p>\n                        <p class=\"tm-bookmark-trans\">\ud83d\udde3\ufe0f ${s.uebersetzung}<\/p>\n                        <div class=\"tm-bookmark-meta\">\n                            <span class=\"${levelBadgeClass}\">${levelIcon} ${s.level}<\/span>\n                            <span class=\"tm-b-badge topic\">\ud83d\udcc1 ${s.thema}<\/span>\n                        <\/div>\n                    <\/div>\n\n                    <div class=\"tm-control-group\">\n                        <button type=\"button\" class=\"btn-blur-toggle btn-blur-single\" data-rowid=\"${s.rowId}\" title=\"${T.tip_hide_single}\">${currentIcon}<\/button>\n                        <button class=\"tm-btn-traffic\" data-status=\"gr\u00fcn\" data-rowid=\"${s.rowId}\" title=\"${T.filter_gruen}\">\ud83d\udfe2<\/button>\n                        <button class=\"tm-btn-traffic\" data-status=\"gelb\" data-rowid=\"${s.rowId}\" title=\"${T.filter_gelb}\">\ud83d\udfe1<\/button>\n                        <button class=\"tm-btn-traffic\" data-status=\"rot\" data-rowid=\"${s.rowId}\" title=\"${T.filter_rot}\">\ud83d\udd34<\/button>\n                        <button class=\"tm-btn-traffic btn-delete\" data-status=\"bookmark entfernt\" data-rowid=\"${s.rowId}\" title=\"${T.tip_delete}\">\ud83d\uddd1\ufe0f<\/button>\n                    <\/div>\n                <\/div>\n            `;\n        }).join('');\n\n        container.querySelectorAll('.tm-btn-traffic').forEach(btn => {\n            btn.addEventListener('click', function() {\n                const rowId = this.getAttribute('data-rowid');\n                const newStatus = this.getAttribute('data-status');\n                executeStatusChange(rowId, newStatus);\n            });\n        });\n\n        container.querySelectorAll('.btn-blur-single').forEach(btn => {\n            btn.addEventListener('click', function(e) {\n                e.preventDefault();\n                const rowId = this.getAttribute('data-rowid');\n                const itemEl = document.getElementById(`tm-bk-${rowId}`);\n                if (!itemEl) return;\n\n                if (globalBlurActive) {\n                    const isRevealed = itemEl.classList.toggle('reveal-active');\n                    this.innerText = isRevealed ? '\ud83d\udc41\ufe0f' : '\ud83d\ude48';\n                    if(isRevealed) { this.classList.add('active'); } else { this.classList.remove('active'); }\n                } else {\n                    const isSingleBlurred = itemEl.classList.toggle('blur-single-active');\n                    this.innerText = isSingleBlurred ? '\ud83d\ude48' : '\ud83d\udc41\ufe0f';\n                    if(isSingleBlurred) { this.classList.add('active'); } else { this.classList.remove('active'); }\n                }\n            });\n        });\n    }\n\n    function executeStatusChange(rowId, newStatus) {\n        const itemEl = document.getElementById(`tm-bk-${rowId}`);\n        const sentence = bookmarkedSentences.find(s => String(s.rowId) === String(rowId));\n\n        if (itemEl && sentence) {\n            itemEl.classList.add('updating');\n\n            if (newStatus === 'bookmark entfernt') {\n                setTimeout(() => {\n                    itemEl.style.display = 'none';\n                    bookmarkedSentences = bookmarkedSentences.filter(s => String(s.rowId) !== String(rowId));\n                    const searchInput = document.getElementById('tm-bookmark-search');\n                    renderBookmarkList(searchInput ? searchInput.value : \"\");\n                }, 200);\n            } else {\n                sentence.status = newStatus;\n                setTimeout(() => {\n                    itemEl.classList.remove('updating');\n                    itemEl.classList.remove('status-gruen', 'status-gelb', 'status-rot');\n                    if (newStatus === 'gr\u00fcn') itemEl.classList.add('status-gruen');\n                    if (newStatus === 'gelb') itemEl.classList.add('status-gelb');\n                    if (newStatus === 'rot') itemEl.classList.add('status-rot');\n\n                    if (currentColorFilter !== 'all' && currentColorFilter !== newStatus) {\n                        itemEl.style.display = 'none';\n                    }\n                }, 150);\n            }\n\n            updateTrafficLightInBackend(sentence, newStatus);\n        }\n    }\n\n    async function loadBookmarkData() {\n        if (!window.wpTrainerUserInfo) {\n            setTimeout(loadBookmarkData, 500);\n            return;\n        }\n\n        const myToken = ++loadToken; \/\/ NEU: jede Ladeanfrage bekommt eine eigene Nummer\n        const userName = String(window.wpTrainerUserInfo.name || \"\").trim();\n        const userId = String(window.wpTrainerUserInfo.id || \"\").trim();\n\n        try {\n            const response = await fetch(`${CONFIG.csvUrl}&_cb=${new Date().getTime()}`);\n            const csvText = await response.text();\n\n            \/\/ NEU: Wurde inzwischen ein anderer User gew\u00e4hlt, diese alte Antwort verwerfen\n            if (myToken !== loadToken) return;\n\n            const lines = csvText.split(\/\\r?\\n\/);\n\n            let activeBookmarksMap = {};\n\n            for (let i = 1; lines.length > i; i++) {\n                if (!lines[i]) continue;\n                const cols = parseCSV(lines[i]);\n                if (!(cols.length >= 3)) continue;\n\n                const rowUserId = cols[1]?.trim();\n                const rowName = cols[2]?.trim();\n\n                if ((rowUserId && rowUserId === userId) || (rowName && rowName === userName)) {\n                    const statVal = cols[CONFIG.bookmarkColIndex]?.trim().toLowerCase() || \"\";\n                    const deText = cols[6]?.trim() || \"\";\n\n                    if (!deText) continue;\n\n                    \/\/ S\u00e4tze ohne g\u00fcltige Ampel-Farbe (z.B. altes \"bookmark gesetzt\") werden\n                    \/\/ wie neue S\u00e4tze behandelt und auf Rot normalisiert.\n                    if (statVal === \"gr\u00fcn\" || statVal === \"gelb\" || statVal === \"rot\") {\n                        activeBookmarksMap[deText] = {\n                            rowId: i + 1,\n                            satzId: cols[3]?.trim() || \"\",\n                            status: statVal,\n                            level: cols[4]?.trim() || \"Standard\",\n                            thema: cols[5]?.trim() || \"Allgemein\",\n                            deutsch: deText,\n                            uebersetzung: cols[7]?.trim() || \"\"\n                        };\n                    } else if (statVal === \"bookmark gesetzt\") {\n                        activeBookmarksMap[deText] = {\n                            rowId: i + 1,\n                            satzId: cols[3]?.trim() || \"\",\n                            status: \"rot\",\n                            level: cols[4]?.trim() || \"Standard\",\n                            thema: cols[5]?.trim() || \"Allgemein\",\n                            deutsch: deText,\n                            uebersetzung: cols[7]?.trim() || \"\"\n                        };\n                    } else if (statVal === \"bookmark entfernt\") {\n                        if (activeBookmarksMap[deText]) {\n                            delete activeBookmarksMap[deText];\n                        }\n                    }\n                }\n            }\n\n            bookmarkedSentences = Object.values(activeBookmarksMap);\n            bookmarkedSentences.reverse();\n            const searchInput = document.getElementById('tm-bookmark-search');\n            renderBookmarkList(searchInput ? searchInput.value : \"\");\n\n        } catch (err) {\n            if (myToken !== loadToken) return; \/\/ NEU: Fehler einer veralteten Anfrage ignorieren\n            console.error(\"Fehler beim Verarbeiten der Daten:\", err);\n            const container = document.getElementById('tm-bookmark-list');\n            if (container) container.innerHTML = `<div class=\"tm-bookmark-empty\">${T.error_loading}<\/div>`;\n        }\n    }\n\n    function init() {\n        applyStaticTranslations();\n\n        const addBtn = document.getElementById('tm-bookmark-add-btn');\n        if (addBtn) {\n            addBtn.addEventListener('click', handleAddToggleClick);\n        }\n\n        const inputs = ['tm-custom-de', 'tm-custom-trans', 'tm-custom-topic'];\n        inputs.forEach(id => {\n            const el = document.getElementById(id);\n            if (el) {\n                el.addEventListener('keydown', function(e) {\n                    if (e.key === 'Enter') {\n                        handleAddToggleClick();\n                    }\n                });\n            }\n        });\n\n        const searchInput = document.getElementById('tm-bookmark-search');\n        if (searchInput) {\n            searchInput.addEventListener('input', function() {\n                renderBookmarkList(this.value);\n            });\n        }\n\n        const filterBtns = document.querySelectorAll('.tm-filter-btn');\n        filterBtns.forEach(btn => {\n            btn.addEventListener('click', function() {\n                filterBtns.forEach(b => b.classList.remove('active'));\n                this.classList.add('active');\n\n                currentColorFilter = this.getAttribute('data-filter');\n\n                const currentSearch = searchInput ? searchInput.value : '';\n                renderBookmarkList(currentSearch);\n            });\n        });\n\n        const containerBox = document.querySelector('.tm-bookmark-container');\n        const blurBtn = document.getElementById('tm-bookmark-blur-btn');\n        const blurWrapper = document.getElementById('tm-blur-tooltip-wrapper');\n\n        if (blurBtn && containerBox) {\n            blurBtn.addEventListener('click', function(e) {\n                e.preventDefault();\n                globalBlurActive = !globalBlurActive;\n\n                containerBox.querySelectorAll('.tm-bookmark-item').forEach(el => {\n                    el.classList.remove('reveal-active', 'blur-single-active');\n                });\n\n                if (globalBlurActive) {\n                    containerBox.classList.add('blur-active');\n                    blurBtn.classList.add('active');\n                    blurBtn.innerText = '\ud83d\ude48';\n                } else {\n                    containerBox.classList.remove('blur-active');\n                    blurBtn.classList.remove('active');\n                    blurBtn.innerText = '\ud83d\udc41\ufe0f';\n                }\n\n                if (blurWrapper) blurWrapper.setAttribute('data-tooltip', globalBlurActive ? T.tooltip_show : T.tooltip_hide);\n\n                containerBox.querySelectorAll('.btn-blur-single').forEach(b => {\n                    b.innerText = globalBlurActive ? '\ud83d\ude48' : '\ud83d\udc41\ufe0f';\n                    b.classList.remove('active');\n                });\n            });\n        }\n\n        \/\/ NEU: Beim Wechsel im \"User spiegeln\"-Widget die Liste des gew\u00e4hlten Users laden\n        window.addEventListener('tm-user-switched', function() {\n            bookmarkedSentences = [];\n            const listEl = document.getElementById('tm-bookmark-list');\n            if (listEl) listEl.innerHTML = `<div class=\"tm-bookmark-loading\">${T.loading}<\/div>`;\n            loadBookmarkData();\n        });\n\n        loadBookmarkData();\n    }\n\n    if (document.readyState === 'loading') {\n        document.addEventListener('DOMContentLoaded', init);\n    } else {\n        init();\n    }\n})();\n<\/script>\n<\/div>\n\n<div class=\"dash-p p4\">\n<style id=\"tracker-tests-design\">\n\/* Grammar tracker + Test results \u2013 an aktuelles Dashboard-Design angepasst, volle Breite *\/\n.dash .p4 #el-grammar-app.el-container,.dash .p5 #trainer-history-app{max-width:none!important;width:100%!important;margin:0!important;font-family:'Inter','Segoe UI',Roboto,sans-serif!important;color:#1D2427!important}\n.dash .p4 #el-grammar-app .el-level-row{margin-bottom:14px!important;background:#fff!important;border:1px solid #E7E2D8!important;border-radius:22px!important;box-shadow:0 10px 26px rgba(29,36,39,.04)!important}\n.dash .p4 #el-grammar-app .el-level-head{padding:16px 20px!important}\n.dash .p4 #el-grammar-app .el-level-head:hover{background:#F7FAFB!important}\n.dash .p4 #el-grammar-app .el-level-badge{width:40px!important;height:40px!important;border-radius:12px!important;background:#14708C!important;color:#fff!important;font-size:13px!important}\n.dash .p4 #el-grammar-app .el-level-title{font-family:'Fraunces',Georgia,serif!important;font-size:19px!important;color:#1D2427!important}\n.dash .p4 #el-grammar-app .el-level-caret{color:#14708C!important;transform:rotate(90deg)!important}\n.dash .p4 #el-grammar-app .el-level-row.open .el-level-caret{transform:rotate(-90deg)!important}\n.dash .p4 #el-grammar-app .el-content-inner{padding:0 14px 14px!important}\n.dash .p4 #el-grammar-app .el-item-container{margin-top:8px!important;background:#fff!important;border:1px solid #ECE8E0!important;border-radius:14px!important}\n.dash .p4 #el-grammar-app .el-item-container:hover{border-color:#14708C!important}\n.dash .p4 #el-grammar-app .el-item-row{padding:12px 14px!important}\n.dash .p4 #el-grammar-app .el-nr{padding:3px 9px!important;border-radius:999px!important;background:#E2F0F4!important;color:#0E5367!important}\n.dash .p4 #el-grammar-app .el-title{font-size:15.5px!important;color:#1D2427!important}\n.dash .p4 #el-grammar-app .el-desc{font-size:13px!important;color:#4B565A!important}\n.dash .p4 #el-grammar-app .el-status-btn,.dash .p4 #el-grammar-app .el-expand-btn{width:32px!important;height:32px!important;border-radius:50%!important;background:#fff!important;border:1px solid #E7E2D8!important}\n.dash .p4 #el-grammar-app .el_s1{background:#FDF4F2!important;border-color:#E06A5A!important}\n.dash .p4 #el-grammar-app .el_s2{background:#FFFAEC!important;border-color:#F2B630!important}\n.dash .p4 #el-grammar-app .el_s3{background:#F4FBF7!important;border-color:#3BAA7E!important}\n.dash .p4 #el-grammar-app .el-expand-btn{color:#4B565A!important}\n.dash .p4 #el-grammar-app .el-expand-btn:hover,.dash .p4 #el-grammar-app .el-expand-btn.open{background:#E2F0F4!important;border-color:#14708C!important;color:#0E5367!important}\n.dash .p4 #el-grammar-app .el-menu{border:1px solid #E7E2D8!important;border-radius:14px!important;box-shadow:0 12px 28px rgba(29,36,39,.12)!important}\n.dash .p4 #el-grammar-app .el-opt{color:#1D2427!important}\n.dash .p4 #el-grammar-app .el-opt:hover{background:#F2F8FA!important}\n.dash .p4 #el-grammar-app .el-info-box{color:#4B565A!important;font-size:13px!important}\n.dash .p4 #el-grammar-app .el-info-box.show{border-top-color:#ECE8E0!important;background:#FBFCFC!important;border-radius:0 0 14px 14px!important}\n.dash .p4 #el-grammar-app .el-loading{color:#4B565A!important}\n.dash .p5 .history-white-box{max-width:none!important;padding:20px!important;background:#fff!important;border:1px solid #E7E2D8!important;border-radius:22px!important;box-shadow:0 10px 26px rgba(29,36,39,.04)!important}\n.dash .p5 #history-content{color:#4B565A!important;font-size:14px!important}\n.dash .p5 #history-content>p{margin:0!important;padding:16px 0!important;text-align:center!important}\n.dash .p5 .history-card{margin-bottom:10px!important;background:#fff!important;border:1px solid #ECE8E0!important;border-radius:16px!important;box-shadow:none!important}\n.dash .p5 .history-card:last-child{margin-bottom:0!important}\n.dash .p5 .hist-head{padding:14px 18px!important;background:#fff!important;border-bottom:1px solid transparent!important}\n.dash .p5 .hist-head:hover{background:#F7FAFB!important}\n.dash .p5 .hist-body[style*=\"block\"]{border-top:1px solid #ECE8E0!important}\n.dash .p5 .head-info{color:#1D2427!important;line-height:1.5!important}\n.dash .p5 .head-info strong{font-family:'Fraunces',Georgia,serif!important;font-size:16.5px!important;font-weight:600!important}\n.dash .p5 .head-info small{font-size:12.5px!important;color:#4B565A!important}\n.dash .p5 .click-hint{padding:5px 11px!important;border-radius:999px!important;background:#E2F0F4!important;color:#0E5367!important;font-size:12px!important;font-weight:700!important}\n.dash .p5 .hist-body{padding:6px 18px 12px!important;background:#FBFCFC!important}\n.dash .p5 .hist-row{padding:10px 0!important;border-bottom:1px solid #ECE8E0!important;font-size:14px!important;line-height:1.5!important;color:#1D2427!important}\n.dash .p5 .hist-row strong{display:inline-block;min-width:30px;color:#14708C!important;font-size:12px!important;font-weight:800!important}\n.dash .p5 .hist-row:last-child{border-bottom:0!important}\n<\/style>\n<div id=\"el-grammar-app\" class=\"el-container\">\n    <div id=\"el-list\" class=\"el-loading\">Loading...<\/div>\n<\/div>\n\n<style>\n@import url('https:\/\/fonts.googleapis.com\/css2?family=Fraunces:opsz,wght@9..144,500;9..144,600&family=Inter:wght@500;600;700&display=swap');\n\n#el-grammar-app.el-container {\n    --font-serif: 'Fraunces', Georgia, 'Times New Roman', serif;\n    --ink: #1E293B;\n    --muted: #7B8799;\n    --paper: #F4F8FC;\n    --card: #FFFFFF;\n    --line: #E0E6EE;\n\n    --accent: #475569;\n    --accent-rgb: 71, 85, 105;\n    --accent-soft: #E8EEF5;\n    --accent-ink: #1E293B;\n    --accent-solid: #475569;\n    --accent-solid-rgb: 71, 85, 105;\n\n    --correct: #DDF2E9; --correct-ink: #0E7A59; --correct-border: #9BDBC2;\n    --tip: #FBEECB; --tip-ink: #8A5A00; --tip-border: #E9C46A;\n    --missing: #FAE1E7; --missing-ink: #A63150; --missing-border: #EBA5B7;\n\n    background: transparent !important; max-width: calc(640px * var(--card-scale, 1));\nwidth: 100%;\nmargin: 0 auto !important;\n    font-family: 'Inter', 'Segoe UI', Roboto, Helvetica, Arial, sans-serif !important;\n    box-sizing: border-box !important;\n}\n#el-grammar-app.el-container * { box-sizing: border-box !important; }\n\n#el-grammar-app .el-loading { padding: 40px 0 !important; text-align: center !important; color: var(--muted) !important; font-weight: 600 !important; animation: elLoadingPulse 1.3s ease-in-out infinite !important; }\n@keyframes elLoadingPulse { 0%, 100% { opacity: 0.55; } 50% { opacity: 1; } }\n\n\/* ---- Level-Akkordeon ---- *\/\n#el-grammar-app .el-level-row {\n    background: var(--card) !important; margin-bottom: 12px !important;\n    border: 1px solid var(--line) !important; border-radius: 20px !important;\n    box-shadow: 0 1px 2px rgba(28,27,26,0.03), 0 16px 32px rgba(28,27,26,0.05) !important;\n    overflow: hidden !important; transition: border-color 0.15s ease !important;\n}\n#el-grammar-app .el-level-row.open { overflow: visible !important; }\n\n#el-grammar-app .el-level-head {\n    all: unset !important; box-sizing: border-box !important; cursor: pointer !important;\n    width: 100% !important; padding: 16px 18px !important; background: transparent !important;\n    display: flex !important; align-items: center !important; gap: 12px !important;\n    font-family: inherit !important; transition: background 0.15s ease !important;\n}\n#el-grammar-app .el-level-head:hover { background: var(--paper) !important; }\n#el-grammar-app .el-level-badge {\n    flex-shrink: 0 !important; display: flex !important; align-items: center !important; justify-content: center !important;\n    width: 38px !important; height: 38px !important; border-radius: 11px !important; background: var(--accent-solid) !important;\n    color: var(--paper) !important; font-weight: 800 !important; font-size: 13px !important; letter-spacing: 0.2px !important;\n}\n#el-grammar-app .el-level-title {\n    flex-grow: 1 !important; text-align: left !important; font-family: var(--font-serif) !important;\n    font-size: 18px !important; font-weight: 600 !important; color: var(--ink) !important;\n}\n#el-grammar-app .el-level-caret {\n    flex-shrink: 0 !important; font-size: 18px !important; color: var(--accent) !important; font-weight: 700 !important;\n    transition: transform 0.2s ease !important;\n}\n#el-grammar-app .el-level-row.open .el-level-caret { transform: rotate(180deg) !important; }\n\n#el-grammar-app .el-content {\n    max-height: 0 !important; overflow: hidden !important;\n    transition: max-height 0.3s ease !important;\n}\n#el-grammar-app .el-level-row.open .el-content {\n    max-height: 4000px !important;\n    overflow: visible !important;\n}\n#el-grammar-app .el-content-inner { padding: 0 10px 10px 10px !important; }\n\n\/* ---- Themen-Zeilen ---- *\/\n#el-grammar-app .el-item-container {\n    position: relative !important; background: var(--card) !important; border: 1px solid var(--line) !important;\n    border-radius: 13px !important; margin-top: 7px !important;\n    transition: border-color 0.15s ease, opacity 0.2s ease, z-index 0s !important;\n    z-index: 1 !important;\n}\n#el-grammar-app .el-item-container.el-menu-open { z-index: 50 !important; }\n#el-grammar-app .el-item-container.el-updating { opacity: 0.4 !important; pointer-events: none !important; }\n#el-grammar-app .el-item-container:hover { border-color: var(--accent) !important; }\n\n#el-grammar-app .el-item-row { position: relative !important; display: flex !important; align-items: flex-start !important; gap: 10px !important; padding: 11px 11px 11px 11px !important; }\n\n#el-grammar-app .el-nr {\n    flex: 0 0 auto !important; display: inline-flex !important; align-items: center !important; justify-content: center !important;\n    font-size: 11.5px !important; font-weight: 800 !important; color: var(--accent-ink) !important;\n    background: var(--accent-soft) !important; padding: 3px 7px !important; border-radius: 7px !important;\n    line-height: 1.3 !important; margin-top: 1px !important;\n}\n#el-grammar-app .el-text-col { flex: 1 1 auto !important; min-width: 0 !important; overflow: hidden !important; }\n#el-grammar-app .el-title {\n    display: block !important; font-family: var(--font-serif) !important; font-size: 14.5px !important; font-weight: 600 !important;\n    color: var(--ink) !important; line-height: 1.3 !important; overflow-wrap: break-word !important; word-break: break-word !important;\n}\n#el-grammar-app .el-desc {\n    display: block !important; font-size: 12.5px !important; font-weight: 500 !important; color: var(--muted) !important;\n    margin-top: 3px !important; line-height: 1.35 !important; overflow-wrap: break-word !important;\n}\n\n#el-grammar-app .el-actions { flex: 0 0 auto !important; display: flex !important; align-items: center !important; gap: 8px !important; }\n\n#el-grammar-app .el-status-btn {\n    all: unset !important; box-sizing: border-box !important; width: 30px !important; height: 30px !important;\n    border-radius: 9px !important; border: 1px solid var(--line) !important; background: var(--paper) !important;\n    cursor: pointer !important; display: flex !important; align-items: center !important; justify-content: center !important;\n    font-size: 14px !important; transition: transform 0.12s ease, border-color 0.15s ease !important;\n}\n#el-grammar-app .el-status-btn:hover { transform: translateY(-1px) !important; }\n#el-grammar-app .el_s0 { background: var(--paper) !important; border-color: var(--line) !important; }\n#el-grammar-app .el_s1 { background: var(--missing) !important; border-color: var(--missing-border) !important; }\n#el-grammar-app .el_s2 { background: var(--tip) !important; border-color: var(--tip-border) !important; }\n#el-grammar-app .el_s3 { background: var(--correct) !important; border-color: var(--correct-border) !important; }\n\n#el-grammar-app .el-menu {\n    display: none !important; position: absolute !important; right: 0 !important; top: 36px !important;\n    background: var(--card) !important; border-radius: 12px !important;\n    box-shadow: 0 10px 25px rgba(20,26,34,0.15) !important; border: 1px solid var(--line) !important;\n    z-index: 999999 !important; width: 168px !important; padding: 5px !important;\n}\n#el-grammar-app .el-menu.show { display: flex !important; flex-direction: column !important; }\n#el-grammar-app .el-opt {\n    padding: 8px 10px !important; cursor: pointer !important; font-size: 12.5px !important; font-weight: 600 !important;\n    border-radius: 8px !important; color: var(--ink) !important; text-align: left !important;\n    display: flex !important; align-items: center !important; gap: 8px !important;\n}\n#el-grammar-app .el-opt:hover { background: var(--paper) !important; }\n\n#el-grammar-app .el-expand-btn {\n    all: unset !important; box-sizing: border-box !important; cursor: pointer !important;\n    width: 30px !important; height: 30px !important; border-radius: 9px !important;\n    border: 1px solid var(--line) !important; background: var(--paper) !important; color: var(--muted) !important;\n    display: flex !important; align-items: center !important; justify-content: center !important;\n    font-size: 14px !important; font-weight: 700 !important;\n    transition: transform 0.2s ease, background 0.15s ease, border-color 0.15s ease, color 0.15s ease !important;\n}\n#el-grammar-app .el-expand-btn:hover { border-color: var(--accent) !important; background: var(--accent-soft) !important; color: var(--accent-ink) !important; }\n#el-grammar-app .el-expand-btn.open { transform: rotate(180deg) !important; border-color: var(--accent) !important; color: var(--accent-ink) !important; }\n#el-grammar-app .el-expand-btn.el-disabled { opacity: 0.35 !important; pointer-events: none !important; }\n\n#el-grammar-app .el-info-box {\n    max-height: 0 !important; overflow: hidden !important;\n    transition: max-height 0.28s ease, padding 0.28s ease !important;\n    padding: 0 14px !important; font-size: 12.5px !important; line-height: 1.55 !important;\n    color: var(--muted) !important; border-top: 1px solid transparent !important;\n}\n#el-grammar-app .el-info-box.show {\n    max-height: 400px !important; padding: 10px 14px 12px 14px !important;\n    border-top-color: var(--line) !important;\n}\n<\/style>\n\n<script>\n(function() {\n    const CONFIG = {\n        csvUrl: 'https:\/\/docs.google.com\/spreadsheets\/d\/1pGfdVy3yDtzS56FIxiP4KsHHYuKUqPWVG18ULv9wxi4\/export?format=csv&gid=368365373',\n        logUrl: 'https:\/\/docs.google.com\/spreadsheets\/d\/1pGfdVy3yDtzS56FIxiP4KsHHYuKUqPWVG18ULv9wxi4\/export?format=csv&gid=588315623',\n        scriptUrl: 'https:\/\/script.google.com\/macros\/s\/AKfycbz7ViqxDaSi1l2M0o4rsPHqS09qmgosQy34eIJmBhfd1hs2SBbRAuc3nrJC4D4KfBoPPQ\/exec'\n    };\n\n    const TOPIC_AREA = \"Grammar\";\n\n    function detectSiteLanguage() {\n        const supported = ['de', 'en', 'es'];\n        const candidates = [\n            document.documentElement.lang,\n            navigator.language,\n            (navigator.languages && navigator.languages[0])\n        ].filter(Boolean).map(v => v.toLowerCase().split('-')[0]);\n        for (const c of candidates) { if (supported.includes(c)) return c; }\n        return 'de';\n    }\n\n    const currentLang = detectSiteLanguage();\n    let dataStore = {}, userStates = {};\n    let topicsLoaded = false; \/\/ NEU: Themenliste (\u00e4ndert sich beim User-Wechsel nicht) wird nur einmal geladen\n    let stateToken = 0;       \/\/ NEU: verhindert, dass veraltete Antworten den neuen User \u00fcberschreiben\n    const statusMap = { \"offen\": \"s0\", \"open\": \"s0\", \"abierto\": \"s0\", \"nicht gekonnt\": \"s1\", \"not mastered\": \"s1\", \"no dominado\": \"s1\", \"wiederholen\": \"s2\", \"repeat\": \"s2\", \"repetir\": \"s2\", \"erledigt\": \"s3\", \"done\": \"s3\", \"completado\": \"s3\" };\n    const texts = { de: { s0: \"offen\", s1: \"nicht gekonnt\", s2: \"wiederholen\", s3: \"erledigt\" }, en: { s0: \"open\", s1: \"not mastered\", s2: \"repeat\", s3: \"done\" }, es: { s0: \"abierto\", s1: \"no dominado\", s2: \"repetir\", s3: \"completado\" } };\n    const icons = { s0: '\u26aa', s1: '\ud83d\udd34', s2: '\ud83d\udfe1', s3: '\ud83d\udfe2' };\n\n    function getUid() { return String(window.wpTrainerUserInfo?.id || \"Gast\").trim(); }\n\n    \/\/ NEU: L\u00e4dt die Status des aktuell gew\u00e4hlten Users und zeichnet die Liste neu\n    async function refreshStates() {\n        const myToken = ++stateToken;\n        const uid = getUid();\n        const area = document.getElementById('el-list');\n        if (area && topicsLoaded) area.style.opacity = '0.5';\n\n        let fresh = {};\n        let ok = false;\n        try {\n            const res = await fetch(CONFIG.logUrl + '&_cb=' + Date.now());\n            const text = await res.text();\n            const rows = text.split('\\n').map(r => r.split(','));\n            rows.forEach(r => {\n                if (r.length > 8 && r[1]?.replace(\/\"\/g, '').trim() === uid) {\n                    fresh[r[3]?.replace(\/\"\/g, '').trim()] = statusMap[r[8]?.replace(\/\"\/g, '').trim()] || 's0';\n                }\n            });\n            ok = true;\n        } catch(e) { console.error(e); }\n\n        \/\/ Wurde inzwischen ein anderer User gew\u00e4hlt, diese alte Antwort verwerfen\n        if (myToken !== stateToken) return;\n\n        if (ok) {\n            userStates = fresh;\n            localStorage.setItem('el_grammar_states_' + uid, JSON.stringify(userStates));\n        } else {\n            \/\/ Offline-Fallback: zuletzt gespeicherte Status dieses Users\n            try {\n                const saved = localStorage.getItem('el_grammar_states_' + uid);\n                userStates = saved ? JSON.parse(saved) : {};\n            } catch(e) { userStates = {}; }\n        }\n\n        if (area) area.style.opacity = '';\n        if (topicsLoaded) render();\n    }\n\n    async function loadTopics() {\n        const csvRes = await fetch(CONFIG.csvUrl);\n        const t = await csvRes.text();\n\n        const rows = t.split('\\n').map(r => {\n            let row = [], inQ = false, cur = \"\";\n            for (let c of r) {\n                if (c === '\"') { inQ = !inQ; cur += c; }\n                else if (c === ',' && !inQ) { row.push(cur); cur = \"\"; }\n                else { cur += c; }\n            }\n            row.push(cur); return row;\n        });\n\n        function cleanCSVField(str) {\n            if (!str) return \"\";\n            str = str.trim();\n            if (str.startsWith('\"') && str.endsWith('\"')) str = str.slice(1, -1);\n            return str.replace(\/\"\"\/g, '\"');\n        }\n\n        dataStore = {};\n        rows.slice(1).forEach(c => {\n            if (!c[0]) return;\n            const lvl = cleanCSVField(c[0]);\n            const area = cleanCSVField(c[3]);\n            if (TOPIC_AREA && area !== TOPIC_AREA) return;\n            if (!dataStore[lvl]) dataStore[lvl] = [];\n            dataStore[lvl].push({\n                lvl: lvl,\n                nr: cleanCSVField(c[1]),\n                topicTitle: cleanCSVField(c[2]),\n                area: area,\n                de: cleanCSVField(c[4]),\n                en: cleanCSVField(c[5]),\n                es: cleanCSVField(c[6]),\n                info_de: cleanCSVField(c[7]),\n                info_en: cleanCSVField(c[8]),\n                info_es: cleanCSVField(c[9])\n            });\n        });\n        topicsLoaded = true;\n    }\n\n    async function init() {\n        try { await loadTopics(); } catch(e) { console.error(e); }\n        await refreshStates();\n    }\n\n    window.elUpdate = async function(state, id, lvl, nr) {\n        const uid = getUid();\n        userStates[\"THEMA-\" + id] = state;\n        const btn = document.getElementById('btn-' + id);\n        btn.className = 'el-status-btn el_' + state;\n        btn.innerHTML = icons[state];\n        document.getElementById('m-' + id).classList.remove('show');\n        document.getElementById('item-' + id)?.classList.remove('el-menu-open');\n        localStorage.setItem('el_grammar_states_' + uid, JSON.stringify(userStates));\n\n        try {\n            await fetch(CONFIG.scriptUrl, { method: 'POST', mode: 'no-cors', headers: {'Content-Type': 'application\/json'}, body: JSON.stringify({\n                time: new Date().toISOString(), user_id: uid, sentence_id: \"THEMA-\" + id, level: lvl, topic: nr, action: texts[currentLang][state]\n            })});\n        } catch(e) { console.error(e); }\n    };\n\n    window.elToggleMenu = (id) => {\n        document.querySelectorAll('.el-menu').forEach(m => { if (m.id !== 'm-'+id) m.classList.remove('show'); });\n        document.querySelectorAll('.el-item-container').forEach(c => { if (c.id !== 'item-'+id) c.classList.remove('el-menu-open'); });\n        const menu = document.getElementById('m-'+id);\n        const willOpen = !menu.classList.contains('show');\n        menu.classList.toggle('show', willOpen);\n        document.getElementById('item-'+id)?.classList.toggle('el-menu-open', willOpen);\n    };\n    window.elToggleInfo = (id) => {\n        const panel = document.getElementById('info-' + id);\n        const btn = document.getElementById('exp-' + id);\n        const willOpen = !panel.classList.contains('show');\n        panel.classList.toggle('show', willOpen);\n        if (btn) btn.classList.toggle('open', willOpen);\n    };\n    window.elToggleLevel = (headEl) => { headEl.closest('.el-level-row').classList.toggle('open'); };\n\n    document.addEventListener('click', (e) => {\n        if (!e.target.closest('.el-actions')) {\n            document.querySelectorAll('.el-menu').forEach(m => m.classList.remove('show'));\n            document.querySelectorAll('.el-item-container').forEach(c => c.classList.remove('el-menu-open'));\n        }\n    });\n\n    function render() {\n        const area = document.getElementById('el-list');\n\n        \/\/ NEU: Ge\u00f6ffnete Level merken, damit sie beim Neuzeichnen offen bleiben\n        const openLevels = new Set(\n            Array.from(area.querySelectorAll('.el-level-row.open')).map(el => el.dataset.lvl)\n        );\n\n        area.classList.remove('el-loading');\n        area.innerHTML = '';\n        const levels = Object.keys(dataStore).sort();\n        if (levels.length === 0) { area.innerHTML = ''; return; }\n\n        levels.forEach((lvl, idx) => {\n            const section = document.createElement('div');\n            section.className = 'el-level-row';\n            section.dataset.lvl = lvl;\n            if (openLevels.has(lvl)) section.classList.add('open');\n            const itemsHtml = dataStore[lvl].map(item => {\n                const id = lvl.replace(\/\\s\/g,'-') + '_' + item.nr;\n                const st = userStates[\"THEMA-\" + id] || 's0';\n                const title = item.topicTitle || item.de;\n                const desc = (currentLang === 'en' ? item.en : currentLang === 'es' ? item.es : item.de) || '';\n                const info = (currentLang === 'en' ? (item.info_en || item.info_de) : currentLang === 'es' ? (item.info_es || item.info_de) : item.info_de) || '';\n                const hasInfo = !!info;\n                return `<div class=\"el-item-container\" id=\"item-${id}\">\n                    <div class=\"el-item-row\">\n                        <span class=\"el-nr\">${item.nr}<\/span>\n                        <div class=\"el-text-col\">\n                            <span class=\"el-title\">${title}<\/span>\n                            <span class=\"el-desc\">${desc}<\/span>\n                        <\/div>\n                        <div class=\"el-actions\">\n                            <div style=\"position:relative\">\n                                <button id=\"btn-${id}\" class=\"el-status-btn el_${st}\" onclick=\"elToggleMenu('${id}')\">${icons[st]}<\/button>\n                                <div class=\"el-menu\" id=\"m-${id}\">${['s0','s1','s2','s3'].map(s => `<div class=\"el-opt\" onclick=\"elUpdate('${s}','${id}','${lvl}','${item.nr}')\">${icons[s]} ${texts[currentLang][s]}<\/div>`).join('')}<\/div>\n                            <\/div>\n                            <button id=\"exp-${id}\" class=\"el-expand-btn${hasInfo ? '' : ' el-disabled'}\" onclick=\"elToggleInfo('${id}')\">\u25be<\/button>\n                        <\/div>\n                    <\/div>\n                    <div class=\"el-info-box\" id=\"info-${id}\">${info}<\/div>\n                <\/div>`;\n            }).join('');\n            section.innerHTML = `<button class=\"el-level-head\" onclick=\"elToggleLevel(this)\">\n                    <span class=\"el-level-badge\">${lvl}<\/span>\n                    <span class=\"el-level-title\">Grammar Topics<\/span>\n                    <span class=\"el-level-caret\">\u203a<\/span>\n                <\/button>\n                <div class=\"el-content\"><div class=\"el-content-inner\">${itemsHtml}<\/div><\/div>`;\n            area.appendChild(section);\n        });\n    }\n\n    \/\/ NEU: Beim Wechsel im \"User spiegeln\"-Widget die Status des gew\u00e4hlten Users laden\n    window.addEventListener('tm-user-switched', function() {\n        refreshStates();\n    });\n\n    init();\n})();\n<\/script>\n<div class=\"spx-role\" data-role=\"free\"><div class=\"lock\"><div class=\"lk\">\ud83d\udd12<\/div><h3>This area is for paying members only<\/h3><p>Upgrade to Plus to unlock the grammar tracker.<\/p><a class=\"btn b-teal\" href=\"https:\/\/sofapiano.com\/membership-join\/\">More Info!<\/a><\/div><\/div>\n<\/div>\n\n<div class=\"dash-p p5\">\n<div id=\"trainer-history-app\">\n    <div class=\"history-white-box\">\n        <div id=\"history-content\">Loading...<\/div>\n    <\/div>\n<\/div>\n\n<script>\nlet historyToken = 0; \/\/ NEU: verhindert, dass veraltete Antworten die Liste des neuen Users \u00fcberschreiben\n\n(function checkUser() {\n    if (window.wpTrainerUserInfo && window.wpTrainerUserInfo.id) {\n        loadHistory(window.wpTrainerUserInfo.id);\n    } else {\n        setTimeout(checkUser, 500);\n    }\n})();\n\n\/\/ NEU: Beim Wechsel im \"User spiegeln\"-Widget den Verlauf des gew\u00e4hlten Users laden\nwindow.addEventListener('tm-user-switched', function() {\n    const container = document.getElementById('history-content');\n    if (container) container.innerHTML = 'Loading...';\n    const id = window.wpTrainerUserInfo && window.wpTrainerUserInfo.id;\n    if (id) loadHistory(id);\n});\n\n\/\/ Hilfsfunktion: Konvertiert Google-Datumsformat sicher in Millisekunden\nfunction getTimestamp(dateVal) {\n    if (dateVal instanceof Date) return dateVal.getTime();\n    if (typeof dateVal === 'string' && dateVal.includes('Date')) {\n        const parts = dateVal.match(\/\\d+\/g);\n        return new Date(parts[0], parts[1], parts[2], parts[3], parts[4], parts[5]).getTime();\n    }\n    return new Date(dateVal).getTime();\n}\n\nasync function loadHistory(userId) {\n    const myToken = ++historyToken; \/\/ NEU: jede Ladeanfrage bekommt eine eigene Nummer\n    const sheetId = '1pGfdVy3yDtzS56FIxiP4KsHHYuKUqPWVG18ULv9wxi4';\n    const gid = '588315623';\n    const url = `https:\/\/docs.google.com\/spreadsheets\/d\/${sheetId}\/gviz\/tq?tqx=out:json&gid=${gid}&_cb=${Date.now()}`;\n    const container = document.getElementById('history-content');\n\n    try {\n        const response = await fetch(url);\n        const text = await response.text();\n\n        \/\/ NEU: Wurde inzwischen ein anderer User gew\u00e4hlt, diese alte Antwort verwerfen\n        if (myToken !== historyToken) return;\n\n        const json = JSON.parse(text.substring(47).slice(0, -2));\n        const rows = json.table.rows;\n\n        let sessions = [];\n        let currentSession = null;\n\n        rows.forEach(row => {\n            const c = row.c;\n            if (!c || !c[1]) return;\n            if (String(c[1].v) !== String(userId)) return;\n\n            const action = c[8] ? c[8].v : \"\";\n\n            if (action === \"Test-Start\") {\n                currentSession = { startTs: c[0].v, date: c[0].f, level: \"N\/A\", items: [] };\n            } else if (action === \"Test-Auswertung\" && currentSession) {\n                currentSession.endTs = c[0].v;\n                currentSession.result = c[9] ? c[9].v : \"-\";\n\n                \/\/ Dauer sicher berechnen\n                let diff = Math.round((getTimestamp(currentSession.endTs) - getTimestamp(currentSession.startTs)) \/ 60000);\n                currentSession.duration = diff + \" Min\";\n\n                sessions.push(currentSession);\n                currentSession = null;\n            } else if (currentSession) {\n                \/\/ Level aus Spalte 4 (Index 4)\n                if (c[4] && c[4].v) currentSession.level = c[4].v;\n\n                currentSession.items.push({\n                    deutsch: c[6] ? c[6].v : \"\",\n                    eingabe: c[10] ? c[10].v : \"\",\n                    status: c[9] ? c[9].v : \"\"\n                });\n            }\n        });\n\n        if (sessions.length === 0) {\n            container.innerHTML = '<p>Keine Test-Daten gefunden.<\/p>';\n            return;\n        }\n\n        container.innerHTML = '';\n        sessions.reverse().forEach((s, index) => {\n            const div = document.createElement('div');\n            div.className = 'history-card';\n            div.innerHTML = `\n                <div class=\"hist-head\" onclick=\"toggleH(this)\">\n                    <div class=\"head-info\">\n                        <strong>Test vom ${s.date}<\/strong><br>\n                        <small>Level: ${s.level} | Duration: ${s.duration} | Result: ${s.result}<\/small>\n                    <\/div>\n                    <div class=\"click-hint\">\u25bc Details<\/div>\n                <\/div>\n                <div class=\"hist-body\" style=\"display:none;\">\n                    ${s.items.map(i => `\n                        <div class=\"hist-row\">\n                            <strong>DE:<\/strong> ${i.deutsch}<br>\n                            <strong>DU:<\/strong> ${i.eingabe} (${i.status})\n                        <\/div>\n                    `).join('')}\n                <\/div>\n            `;\n            container.appendChild(div);\n        });\n    } catch (e) {\n        if (myToken !== historyToken) return; \/\/ NEU: Fehler einer veralteten Anfrage ignorieren\n        console.error(e);\n        container.innerHTML = \"Fehler beim Laden der Daten.\";\n    }\n}\n\nfunction toggleH(el) {\n    const body = el.nextElementSibling;\n    const hint = el.querySelector('.click-hint');\n    if (body.style.display === 'none') {\n        body.style.display = 'block';\n        hint.innerText = '\u25b2 Close';\n    } else {\n        body.style.display = 'none';\n        hint.innerText = '\u25bc Details';\n    }\n}\n<\/script>\n\n<style>\n\/* ============ Gemeinsamer Container ============\n   Gleiche Au\u00dfenma\u00dfe\/Position wie die anderen Trainer-Boxen:\n   max-width 640px, keine Au\u00dfenmargin. Gleiches Farbschema. *\/\n#trainer-history-app {\n  display: block !important;\n  max-width: 640px !important;\n  width: 100% !important;\nmargin: 0 auto !important;\n  font-family: 'Inter', 'Segoe UI', Roboto, Helvetica, Arial, sans-serif !important;\n\n  --ink: #1E293B;\n  --muted: #7B8799;\n  --paper: #F4F8FC;\n  --card: #FFFFFF;\n  --line: #E0E6EE;\n  --accent: #475569;\n  --accent-rgb: 71, 85, 105;\n  --accent-soft: #E8EEF5;\n  --accent-ink: #475569;\n  --card-scale: 1;\n\n  color: var(--ink) !important;\n  box-sizing: border-box !important;\n}\n#trainer-history-app *, #trainer-history-app *::before, #trainer-history-app *::after {\n  box-sizing: border-box !important;\n}\n\n\/* ============ Neuer wei\u00dfer Kasten um den Inhalt ============ *\/\n.history-white-box {\n  background: var(--card);\n  border-radius: 20px;\n  padding: 24px;\n  max-width: calc(640px * var(--card-scale));\n  width: 100%;\n  margin: 0 auto !important;\n  box-shadow: 0 1px 2px rgba(28,27,26,0.03), 0 16px 32px rgba(28,27,26,0.05);\n  box-sizing: border-box;\n}\n\n#history-content { color: var(--muted); }\n\n.history-card {\n  border: 1px solid var(--line);\n  margin-bottom: 12px;\n  border-radius: 20px;\n  overflow: hidden;\n  background: var(--card);\n  box-shadow: 0 1px 2px rgba(28,27,26,0.03), 0 16px 32px rgba(28,27,26,0.05);\n}\n.hist-head {\n  background: var(--paper);\n  padding: 15px 20px;\n  cursor: pointer;\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  border-bottom: 1px solid var(--line);\n  transition: background 0.15s ease;\n}\n.hist-head:hover { background: var(--accent-soft); }\n.head-info { line-height: 1.4; color: var(--ink); }\n.click-hint { font-size: 0.75em; color: var(--accent-ink); font-weight: bold; margin-left: 10px; white-space: nowrap; }\n.hist-body { padding: 15px 20px; background: var(--card); }\n.hist-row { padding: 8px 0; border-bottom: 1px solid var(--paper); font-size: 0.9em; color: var(--ink); }\n.hist-row:last-child { border-bottom: none; }\n<\/style>\n<div class=\"spx-role\" data-role=\"free\"><div class=\"lock\"><div class=\"lk\">\ud83d\udd12<\/div><h3>This area is for paying members only<\/h3><p>Upgrade to Plus to save your test results and track your progress.<\/p><a class=\"btn b-teal\" href=\"https:\/\/sofapiano.com\/membership-join\/\">More Info!<\/a><\/div><\/div>\n<\/div>\n\n<div class=\"dash-p p6\">\n<div id=\"trainer-wrapper-fixed\">\n<div id=\"trainer-container-final\" class=\"trainer-app-scoped\">\n\n<style>\n#trainer-wrapper-fixed { all: initial; display: block; width: 100%; clear: both; }\n#trainer-container-final.trainer-app-scoped { display: block !important; text-align: center !important; max-width: calc(640px * var(--card-scale, 1)) !important; width: 100% !important; margin: 0 auto !important; padding: 25px !important; font-family: 'Segoe UI', Roboto, Arial, sans-serif !important; background-color: #ffffff !important; border: 1px solid #E8EEF5 !important; border-radius: 30px !important; box-shadow: 0 10px 30px rgba(0,0,0,0.05) !important; box-sizing: border-box !important; }\n\n\/* Obere Kontrollzeile *\/\n#trainer-container-final .top-row { display: flex !important; gap: 8px !important; align-items: center !important; margin-bottom: 20px !important; width: 100% !important; }\n\n\/* Suchbereich *\/\n#trainer-container-final .search-section-main { display: flex !important; gap: 8px !important; flex-grow: 1 !important; }\n#trainer-container-final .search-wrapper-inner { position: relative !important; flex-grow: 1 !important; }\n#trainer-container-final .input-area { width: 100% !important; height: 50px !important; font-size: 16px !important; padding: 12px 35px 12px 15px !important; border-radius: 16px !important; border: 1px solid #E8EEF5 !important; background: #E8EEF5 !important; text-align: left !important; box-sizing: border-box !important; outline: none !important; transition: border-color 0.2s !important; }\n#trainer-container-final .input-area:focus { border-color: #475569 !important; }\n\n\/* Reset-Button im Suchfeld *\/\n#trainer-container-final .resetBtn-inline { position: absolute !important; right: 12px !important; top: 50% !important; transform: translateY(-50%) !important; background: none !important; border: none !important; cursor: pointer !important; font-size: 14px !important; color: #475569 !important; padding: 0 !important; }\n\n\/* GARANTIERT FUNKTIONIERENDER CSS-TOOLTIP HIER *\/\n#trainer-container-final .tooltip-wrapper {\n  position: relative !important;\n  display: inline-block !important;\n}\n\n\/* Der Tooltip-Kasten (Standardm\u00e4\u00dfig unsichtbar) *\/\n#trainer-container-final .tooltip-wrapper::after {\n  content: attr(data-tooltip) !important;\n  position: absolute !important;\n  bottom: 125% !important;\n  left: 50% !important;\n  transform: translateX(-50%) scale(0.8) !important;\n  background-color: #333333 !important;\n  color: #ffffff !important;\n  padding: 6px 10px !important;\n  border-radius: 8px !important;\n  font-size: 12px !important;\n  font-family: sans-serif !important;\n  white-space: nowrap !important;\n  opacity: 0 !important;\n  pointer-events: none !important;\n  transition: all 0.15s ease-in-out !important;\n  z-index: 99999 !important;\n  box-shadow: 0 4px 10px rgba(0,0,0,0.15) !important;\n}\n\n\/* Kleiner Pfeil unter dem Tooltip *\/\n#trainer-container-final .tooltip-wrapper::before {\n  content: \"\" !important;\n  position: absolute !important;\n  bottom: 110% !important;\n  left: 50% !important;\n  transform: translateX(-50%) !important;\n  border-width: 5px !important;\n  border-style: solid !important;\n  border-color: #333 transparent transparent transparent !important;\n  opacity: 0 !important;\n  transition: all 0.15s ease-in-out !important;\n  pointer-events: none !important;\n  z-index: 99999 !important;\n}\n\n\/* Hover-Effekt: Zeige Tooltip *\/\n#trainer-container-final .tooltip-wrapper:hover::after,\n#trainer-container-final .tooltip-wrapper:hover::before {\n  opacity: 1 !important;\n  transform: translateX(-50%) scale(1) !important;\n}\n\n\/* Einheitlicher Button-Stil *\/\n#trainer-container-final .btn-icon { \n  width: 50px !important; \n  height: 50px !important; \n  border-radius: 16px !important; \n  font-size: 18px !important; \n  cursor: pointer !important; \n  background: #E8EEF5 !important; \n  display: flex !important; \n  align-items: center !important; \n  justify-content: center !important; \n  border: 1px solid #E8EEF5 !important; \n  transition: background-color 0.1s, transform 0.1s, border-color 0.2s !important; \n  color: #475569 !important; \n  outline: none !important; \n  box-shadow: 0 2px 5px rgba(0,0,0,0.03) !important; \n  padding: 0 !important;\n  box-sizing: border-box !important;\n}\n#trainer-container-final .btn-icon:hover { background-color: #d7e1ec !important; border-color: #c3d0e0 !important; }\n#trainer-container-final .btn-icon:active { transform: scale(0.95) !important; }\n\n\/* Spezialzustand f\u00fcr aktiven Blur-Button *\/\n#trainer-container-final .btn-blur-toggle.active { background-color: #ffb300 !important; color: white !important; border-color: #ffb300 !important; }\n#trainer-container-final .btn-blur-toggle.active:hover { background-color: #ffa000 !important; }\n\n\/* Statusmeldung *\/\n#trainer-container-final .status-text-info { font-size: 11px !important; color: #475569 !important; font-weight: bold !important; text-align: left !important; margin-top: -5px !important; margin-bottom: 15px !important; text-transform: uppercase !important; letter-spacing: 0.5px !important; }\n\n\/* S\u00e4tze-Ausgabebereich *\/\n#trainer-container-final .sentenceArea { max-height: 55vh !important; overflow-y: auto !important; margin-top: 10px !important; padding-right: 5px !important; }\n#trainer-container-final .sentence-block { margin-bottom: 12px !important; padding: 18px !important; border: 1px solid #E8EEF5 !important; border-radius: 18px !important; background-color: #E8EEF5 !important; text-align: left !important; box-shadow: 0 3px 8px rgba(0,0,0,0.02) !important; }\n\n\/* Sprachzeilen im Block *\/\n#trainer-container-final .lang-row-main { font-size: 17px !important; font-weight: 600 !important; color: #1E293B !important; margin-bottom: 6px !important; display: flex !important; align-items: flex-start !important; justify-content: space-between !important; }\n#trainer-container-final .lang-row-sub { font-size: 15px !important; color: #475569 !important; display: flex !important; margin-top: 8px !important; border-top: 1px solid #E8EEF5 !important; padding-top: 8px !important; }\n#trainer-container-final .lang-label { min-width: 35px !important; font-weight: bold !important; color: #475569 !important; font-size: 10px !important; margin-top: 4px !important; flex-shrink: 0 !important; text-transform: uppercase !important; }\n#trainer-container-final .txt-content { flex-grow: 1 !important; padding-right: 10px !important; line-height: 1.4 !important; transition: filter 0.2s ease !important; }\n\n\/* Der Blur-Effekt f\u00fcr den deutschen Text *\/\n#trainer-container-final .blur-active .lang-row-main .txt-content {\n    filter: blur(6px) !important;\n    user-select: none !important; \n}\n\n\/* Suchtreffer markieren *\/\n#trainer-container-final mark { \n  background-color: #fff176 !important; \n  color: inherit !important;\n  padding: 0 !important; \n  margin: 0 !important; \n  border-radius: 0 !important; \n  box-shadow: none !important;\n  display: inline !important;\n}\n\n\/* Vorlesebutton *\/\n#trainer-container-final .speak-btn { background: none !important; border: none !important; cursor: pointer !important; font-size: 20px !important; opacity: 0.3 !important; padding: 0 !important; transition: opacity 0.2s !important; }\n#trainer-container-final .speak-btn:hover { opacity: 0.9 !important; }\n\n@media (max-width: 600px) {\n  #trainer-container-final .top-row { flex-wrap: wrap !important; }\n  #trainer-container-final .search-section-main { width: 100% !important; }\n}\n<\/style>\n\n<div class=\"unified-box\">\n  <div class=\"top-row\">\n    <div class=\"search-section-main\">\n      <div class=\"search-wrapper-inner\">\n        <input type=\"text\" id=\"search-input-field\" class=\"input-area\" placeholder=\"Loading...\" disabled>\n        <button class=\"resetBtn-inline\" id=\"clearSearchBtn\" title=\"Clear\">\u2715<\/button>\n      <\/div>\n      <div class=\"tooltip-wrapper\" data-tooltip=\"Search\">\n        <button class=\"btn-icon\" id=\"main-search-btn\" disabled>\ud83d\udd0d<\/button>\n      <\/div>\n    <\/div>\n\n    <div class=\"tooltip-wrapper\" data-tooltip=\"Learn sentences\">\n      <button class=\"btn-icon btn-blur-toggle\" id=\"blur-toggler\">\ud83d\udc41\ufe0f<\/button>\n    <\/div>\n    \n    <div class=\"tooltip-wrapper\" data-tooltip=\"Change language\">\n      <button class=\"btn-icon\" id=\"language-toggler\">\n        <span id=\"toggler-icon\">\ud83c\uddea\ud83c\uddf8<\/span>\n      <\/button>\n    <\/div>\n  <\/div>\n\n  <div id=\"status-msg\" class=\"status-text-info\">Connecting...<\/div>\n\n  <div class=\"sentenceArea\"><\/div>\n<\/div>\n\n<\/div>\n<\/div>\n\n<script>\n(function(){\n    const container = document.getElementById('trainer-container-final');\n    if (!container) return;\n\n    \/\/ Google-Sheet ID\n    const sheetId = '1w0VPGjhREhzB5DEE1C11t3Ys2IuMi8N3G7SGqcZ5ZDQ';\n    \n    \/\/ GIDs der beiden Tabellenbl\u00e4tter\n    const gidEN = '0';            \n    const gidES = '1398568784';   \n\n    let currentMode = 'en'; \n    let allSentences = [];\n    let filtered = [];\n    let isBlurred = false; \n    const MAX_RESULTS = 100; \n\n    \/\/ Mehrsprachige Texte f\u00fcr das Interface\n    const translations = {\n        en: {\n            loadingData: \"Loading language data...\",\n            updating: \"Updating sentences...\",\n            placeholder: \"Search sentence or word...\",\n            ready: \"Ready for search.\",\n            loaded: \" sentences loaded.\",\n            typing: \"Keep typing (at least 3 characters)...\",\n            limitInfo: \" matches. Showing first 100.\",\n            matches: \" matches found.\"\n        },\n        es: {\n            loadingData: \"Cargando datos de idioma...\",\n            updating: \"Actualizando frases...\",\n            placeholder: \"Buscar frase o palabra...\",\n            ready: \"Listo para buscar.\",\n            loaded: \" frases cargadas.\",\n            typing: \"Sigue escribiendo (m\u00ednimo 3 caracteres)...\",\n            limitInfo: \" coincidencias. Mostrando las primeras 100.\",\n            matches: \" coincidencias encontradas.\"\n        }\n    };\n\n    \/\/ Erkennt die Sprache der Website automatisch und liefert 'en' oder 'es' zur\u00fcck\n    function detectSiteLanguage() {\n        try {\n            \/\/ 1) html lang-Attribut (von WordPress\/WPML\/Polylang gesetzt)\n            const htmlLang = (document.documentElement.lang || \"\").toLowerCase();\n            if (htmlLang.startsWith(\"es\")) return \"es\";\n            if (htmlLang.startsWith(\"en\")) return \"en\";\n\n            \/\/ 2) Polylang\/WPML-typische body-Klassen als Fallback (z.B. \"lang-es\", \"polylang-es\")\n            const bodyClasses = document.body ? document.body.className.toLowerCase() : \"\";\n            if (\/\\blang-es\\b|\\bpolylang-es\\b\/.test(bodyClasses)) return \"es\";\n            if (\/\\blang-en\\b|\\bpolylang-en\\b\/.test(bodyClasses)) return \"en\";\n\n            \/\/ 3) Browser-Spracheinstellung als letzter Fallback\n            const browserLang = (navigator.language || navigator.userLanguage || \"\").toLowerCase();\n            if (browserLang.startsWith(\"es\")) return \"es\";\n        } catch (e) {\n            console.warn(\"Spracherkennung fehlgeschlagen, nutze Standard 'en':\", e);\n        }\n        \/\/ Standard, falls nichts erkannt wurde\n        return \"en\";\n    }\n\n    \/\/ Aktualisiert das UI beim Sprachwechsel\n    function updateTogglerUI(mode) {\n        if (mode === 'en') {\n            togglerIcon.innerText = \"\ud83c\uddea\ud83c\uddf8\";\n        } else {\n            togglerIcon.innerText = \"\ud83c\uddec\ud83c\udde7\";\n        }\n    }\n\n    \/\/ L\u00e4dt die Tabellendaten\n    async function loadSheetData(mode) {\n        currentMode = mode;\n        updateTogglerUI(mode);\n        \n        const gid = (mode === 'es') ? gidES : gidEN;\n        const base = `https:\/\/docs.google.com\/spreadsheets\/d\/${sheetId}\/gviz\/tq?tqx=out:csv&gid=${gid}`;\n        \n        const langPack = translations[currentMode];\n\n        input.disabled = true;\n        searchBtn.disabled = true;\n        input.placeholder = langPack.loadingData;\n        statusMsg.innerText = langPack.updating;\n        area.innerHTML = \"\";\n\n        try {\n            const response = await fetch(base);\n            if (!response.ok) throw new Error('Network error');\n            \n            const data = await response.text();\n            const parsedRows = parseCSV(data);\n            \n            const dataRows = parsedRows.slice(1); \n\n            allSentences = dataRows.map(cells => {\n                return {\n                    de: (cells[0] || \"\").trim(),\n                    foreign: (cells[1] || \"\").trim()\n                };\n            }).filter(s => s.de !== \"\" && s.foreign !== \"\"); \n            \n            input.disabled = false;\n            searchBtn.disabled = false;\n            input.placeholder = langPack.placeholder;\n            statusMsg.innerText = `${allSentences.length}${langPack.loaded}`;\n            \n            if (input.value.length >= 3) {\n                performSearch(false);\n            }\n        } catch (error) { \n            console.error(\"Fehler beim Abrufen der Daten:\", error);\n            statusMsg.innerText = \"Error loading data. Please check spreadsheet share settings.\"; \n        }\n    }\n\n    \/\/ Sicherer CSV-Parser\n    function parseCSV(text) {\n        const lines = [];\n        let row = [\"\"];\n        let inQuotes = false;\n\n        for (let i = 0; text.length > i; i++) {\n            const current = text[i];\n            const next = text[i + 1];\n\n            if (current === '\"') {\n                if (inQuotes && next === '\"') {\n                    row[row.length - 1] += '\"';\n                    i++;\n                } else {\n                    inQuotes = !inQuotes;\n                }\n            } else if (current === ',' && !inQuotes) {\n                row.push('');\n            } else if ((current === '\\r' || current === '\\n') && !inQuotes) {\n                if (current === '\\r' && next === '\\n') { i++; }\n                lines.push(row);\n                row = [\"\"];\n            } else {\n                row[row.length - 1] += current;\n            }\n        }\n        if (row.length > 1 || row[0] !== \"\") {\n            lines.push(row);\n        }\n        return lines;\n    }\n\n    \/\/ DOM-Elemente\n    const input = container.querySelector(\"#search-input-field\");\n    const area = container.querySelector(\".sentenceArea\");\n    const statusMsg = container.querySelector(\"#status-msg\");\n    const resetBtn = container.querySelector(\"#clearSearchBtn\");\n    const searchBtn = container.querySelector(\"#main-search-btn\");\n    const languageToggler = container.querySelector(\"#language-toggler\");\n    const togglerIcon = container.querySelector(\"#toggler-icon\");\n    const blurToggler = container.querySelector(\"#blur-toggler\");\n\n    \/\/ Vorlesefunktion\n    function speakText(text) {\n        window.speechSynthesis.cancel();\n        const msg = new SpeechSynthesisUtterance(text);\n        msg.lang = 'de-DE';\n        window.speechSynthesis.speak(msg);\n    }\n\n    \/\/ Suchtreffer markieren\n    function highlight(text, query) {\n        if (!query) return text;\n        const escapedQuery = query.replace(\/[.*+?^${}()|[\\]\\\\]\/g, '\\\\$&');\n        return text.replace(new RegExp(`(${escapedQuery})`, \"gi\"), '<mark>$1<\/mark>');\n    }\n\n    \/\/ Filtersuche ausf\u00fchren\n    function performSearch(force = false) {\n        const query = input.value.toLowerCase(); \n        const langPack = translations[currentMode];\n        \n        if (!force && query.length > 0 && query.length < 3) {\n            area.innerHTML = \"\";\n            statusMsg.innerText = langPack.typing;\n            return;\n        }\n\n        if (query.length === 0) {\n            filtered = [];\n            area.innerHTML = \"\";\n            statusMsg.innerText = langPack.ready;\n            return;\n        }\n        \n        const matches = allSentences.filter(s => \n            s.de.toLowerCase().includes(query) || \n            s.foreign.toLowerCase().includes(query)\n        );\n\n        if (matches.length > MAX_RESULTS) {\n            filtered = matches.slice(0, MAX_RESULTS);\n            statusMsg.innerText = `${matches.length}${langPack.limitInfo}`;\n        } else {\n            filtered = matches;\n            statusMsg.innerText = `${filtered.length}${langPack.matches}`;\n        }\n        \n        render();\n    }\n\n    \/\/ Generiert die S\u00e4tze auf dem Bildschirm\n    function render() {\n        const query = input.value; \n        const secondLangLabel = currentMode.toUpperCase();\n\n        area.innerHTML = \"\";\n        filtered.forEach(s => {\n            const div = document.createElement(\"div\");\n            div.className = \"sentence-block\";\n            div.innerHTML = `\n                <div class=\"lang-row-main\">\n                    <span class=\"lang-label\">DE<\/span>\n                    <div class=\"txt-content\">${highlight(s.de, query)}<\/div>\n                    <button class=\"speak-btn\" data-txt=\"${s.de.replace(\/\"\/g, '&quot;')}\" title=\"Vorlesen\">\ud83d\udd0a<\/button>\n                <\/div>\n                <div class=\"lang-row-sub\">\n                    <span class=\"lang-label\">${secondLangLabel}<\/span>\n                    <div class=\"txt-content\">${highlight(s.foreign, query)}<\/div>\n                <\/div>\n            `;\n            \n            const speakBtn = div.querySelector(\".speak-btn\");\n            if (speakBtn) {\n                speakBtn.onclick = function() {\n                    speakText(this.getAttribute('data-txt'));\n                };\n            }\n\n            area.appendChild(div);\n        });\n    }\n\n    \/\/ Event-Listener f\u00fcr den Blur-Button\n    blurToggler.addEventListener(\"click\", function() {\n        isBlurred = !isBlurred;\n        if (isBlurred) {\n            area.classList.add(\"blur-active\");\n            blurToggler.classList.add(\"active\");\n            blurToggler.innerText = \"\ud83d\ude48\"; \n        } else {\n            area.classList.remove(\"blur-active\");\n            blurToggler.classList.remove(\"active\");\n            blurToggler.innerText = \"\ud83d\udc41\ufe0f\";\n        }\n    });\n\n    \/\/ Sprachumschalter binden (manueller Wechsel bleibt m\u00f6glich, \u00fcberschreibt die Auto-Erkennung)\n    languageToggler.addEventListener(\"click\", function() {\n        const nextMode = (currentMode === 'en') ? 'es' : 'en';\n        loadSheetData(nextMode);\n    });\n\n    \/\/ Suchmasken-Eventlistener\n    input.addEventListener(\"input\", () => performSearch(false));\n    searchBtn.onclick = () => performSearch(true);\n    input.addEventListener(\"keypress\", (e) => { if (e.key === \"Enter\") performSearch(true); });\n\n    resetBtn.onclick = () => { \n        input.value = \"\"; \n        performSearch(false); \n        input.focus(); \n    };\n\n    \/\/ Direkt beim Start starten \u2013 Sprache wird automatisch anhand der Website erkannt\n    loadSheetData(detectSiteLanguage());\n})();\n<\/script>\n<div class=\"gap\"><\/div>\n<div id=\"yt-tracker-wrapper-fixed\">\n    <div id=\"yt-app-container-final\" class=\"yt-app-scoped\">\n\n        <style>\n            #yt-tracker-wrapper-fixed { all: initial; display: block; width: 100%; clear: both; }\n            #yt-app-container-final.yt-app-scoped { \n                display: block !important; \n                width: 100% !important;\n                max-width: calc(640px * var(--card-scale, 1)) !important; \n                margin: 0 auto !important; \n                padding: 15px !important; \n                font-family: 'Segoe UI', Roboto, Arial, sans-serif !important; \n                background-color: #ffffff !important; \n                border: 1px solid #E8EEF5 !important; \n                border-radius: 20px !important; \n                box-shadow: 0 10px 30px rgba(0,0,0,0.05) !important; \n                box-sizing: border-box !important; \n            }\n\n            \/* Search Area - Erzwingt eine Zeile *\/\n            #yt-app-container-final .search-row-unique {\n                display: flex !important;\n                flex-wrap: nowrap !important; \n                gap: 10px !important;\n                margin-bottom: 10px !important;\n                align-items: center !important;\n            }\n\n            #yt-app-container-final .search-input-unique {\n                flex: 1 !important;\n                min-width: 0 !important; \n                padding: 12px 15px !important;\n                border-radius: 12px !important;\n                border: 1px solid #E8EEF5 !important;\n                background: #E8EEF5 !important;\n                box-shadow: 0 4px 6px rgba(0,0,0,0.03) !important;\n                font-size: 16px !important;\n                outline: none !important;\n                height: 45px !important;\n                box-sizing: border-box !important;\n                transition: border-color 0.2s !important;\n            }\n\n            #yt-app-container-final .search-input-unique:focus {\n                border-color: #475569 !important;\n            }\n\n            \/* Quadratischer Button mit Lupe *\/\n            #yt-app-container-final .btn-unique-search { \n                width: 45px !important;\n                height: 45px !important;\n                background-color: #E8EEF5 !important;\n                border: 1px solid #E8EEF5 !important;\n                border-radius: 12px !important;\n                cursor: pointer !important;\n                box-shadow: 0 4px 6px rgba(0,0,0,0.03) !important;\n                display: flex !important;\n                align-items: center !important;\n                justify-content: center !important;\n                padding: 0 !important;\n                transition: all 0.2s ease !important;\n                flex-shrink: 0 !important;\n            }\n\n            #yt-app-container-final .btn-unique-search:hover {\n                background-color: #d7e1ec !important;\n                border-color: #c3d0e0 !important;\n                box-shadow: 0 6px 10px rgba(0,0,0,0.12) !important;\n                transform: translateY(-1px);\n            }\n\n            #yt-app-container-final .search-icon-svg {\n                width: 20px;\n                height: 20px;\n                fill: #475569;\n            }\n\n            \/* Video Player Container - Rund *\/\n            #yt-player-frame-unique { \n                position: relative; \n                padding-bottom: 56.25%; \n                height: 0; \n                overflow: hidden; \n                border-radius: 20px !important; \n                background: #000; \n                margin-bottom: 20px; \n                box-shadow: 0 8px 20px rgba(0,0,0,0.15);\n                -webkit-mask-image: -webkit-radial-gradient(white, black); \n            }\n            #yt-player-frame-unique iframe { position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none; border-radius: 20px; }\n\n            \/* Overlay Styling *\/\n            #no-search-overlay {\n                position: absolute; top: 0; left: 0; width: 100%; height: 100%; \n                background: linear-gradient(135deg, #14708C 0%, #0E1A20 100%); \n                color: #fff; display: flex; flex-direction: column; align-items: center; \n                justify-content: center; z-index:1; text-align: center; padding: 20px; \n                box-sizing: border-box; border-radius: 20px;\n            }\n\n            .play-icon-big {\n                width: 70px; height: 70px; background: rgba(255,255,255,0.15);\n                border-radius: 50%; display: flex; align-items: center; justify-content: center;\n                margin-bottom: 10px; border: 3px solid #fff;\n            }\n\n            \/* Texte wie im Original *\/\n            .overlay-text-main { font-size: 20px; font-weight: 700; margin-bottom: 5px; }\n            .overlay-text-sub { font-size: 15px; opacity: 0.7; }\n\n            \/* Results List *\/\n            #yt-results-list { \n                list-style: none !important; \n                padding: 0 !important; \n                max-height: 400px; \n                overflow-y: auto; \n                background: transparent !important;\n                display: flex !important;\n                flex-direction: column !important;\n                gap: 10px !important;\n            }\n            .result-item-unique { \n                padding: 12px 15px; \n                display: flex; \n                align-items: center; \n                gap: 10px; \n                background: #E8EEF5 !important;\n                border-radius: 14px !important;\n                cursor: pointer !important;\n                transition: background-color 0.15s ease, transform 0.1s ease, box-shadow 0.15s ease !important;\n            }\n            .result-item-unique:hover {\n                background: #d7e1ec !important;\n                transform: translateY(-1px) !important;\n                box-shadow: 0 4px 10px rgba(0,0,0,0.06) !important;\n            }\n            .result-item-unique.empty-state {\n                cursor: default !important;\n            }\n            .result-item-unique.empty-state:hover {\n                background: #E8EEF5 !important;\n                transform: none !important;\n                box-shadow: none !important;\n            }\n            .jump-indicator-unique {\n                color: #475569 !important;\n                font-size: 11px !important;\n                opacity: 0.5 !important;\n                flex-shrink: 0 !important;\n            }\n\n            .time-tag-unique { \n                background: #ffffff; \n                color: #475569; \n                padding: 6px 10px; \n                border-radius: 8px; \n                font-family: monospace; \n                font-weight: bold; \n                font-size: 14px;\n                white-space: nowrap;\n                cursor: pointer !important;\n            }\n            .text-line-unique { flex: 1; color: #1E293B; font-size: 14px; line-height: 1.4; cursor: pointer !important; }\n            \n            .deepl-btn-small { \n                text-decoration: none; \n                background: #002b49; \n                color: white !important; \n                padding: 5px 10px; \n                border-radius: 6px; \n                font-size: 11px; \n                font-weight: bold;\n            }\n\n            \/* MOBIL-OPTIMIERUNG *\/\n            @media (max-width: 600px) {\n                #yt-app-container-final.yt-app-scoped { padding: 12px !important; }\n                .deepl-btn-small { display: none !important; } \n                .text-line-unique { font-size: 13px; }\n                .time-tag-unique { font-size: 12px; padding: 4px 8px; }\n            }\n\n            mark { background-color: #ffeb3b; color: black; border-radius: 2px; }\n            #status-unique { font-size: 10px; color: #475569; text-align: center; margin-top: 10px; letter-spacing: 1px; text-transform: uppercase; }\n        <\/style>\n\n        <div class=\"search-row-unique\">\n            <input type=\"text\" id=\"searchInputUnique\" class=\"search-input-unique\" placeholder=\"Loading...\" onkeyup=\"handleTypingUnique(this.value)\">\n            <button class=\"btn-unique-search\" onclick=\"performSearchUnique()\" title=\"Search\">\n                <svg class=\"search-icon-svg\" viewBox=\"0 0 24 24\">\n                    <path d=\"M15.5 14h-.79l-.28-.27A6.471 6.471 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z\"\/>\n                <\/svg>\n            <\/button>\n        <\/div>\n\n        <div id=\"dynamic-heading-unique\" class=\"dynamic-heading\" style=\"text-align:center; font-weight:700; font-size:20px; margin-bottom:20px; color:#1E293B; min-height: 1.2em;\"><\/div>\n        \n        <div id=\"yt-player-frame-unique\">\n            <div id=\"no-search-overlay\">\n                <div class=\"play-icon-big\">\n                    <div style=\"width: 0; height: 0; border-style: solid; border-width: 10px 0 10px 16px; border-color: transparent transparent transparent #ffffff; margin-left: 4px;\"><\/div>\n                <\/div>\n                <div class=\"overlay-text-main\" id=\"overlay-text-main-unique\"><\/div>\n                <div class=\"overlay-text-sub\" id=\"overlay-text-sub-unique\"><\/div>\n            <\/div>\n            <div id=\"player-unique\"><\/div>\n        <\/div>\n        \n        <ul id=\"yt-results-list\"><\/ul>\n        <div id=\"status-unique\">Loading database...<\/div>\n\n    <\/div>\n\n    <script>\n        (function() {\n            const SHEET_ID = '1TjKM7OsBKykIBEQn6tjnzl4JPlHujaOTvOqngu876ms';\n            const CSV_URL = `https:\/\/docs.google.com\/spreadsheets\/d\/${SHEET_ID}\/export?format=csv`;\n\n            let transcriptDatabase = [];\n            let ytPlayer;\n            let activeVideoId = \"\";\n            let trackingInterval;\n            let debounceTimer;\n            let currentMode = 'en';\n\n            \/\/ Mehrsprachige Texte f\u00fcr das Interface\n            const translations = {\n                en: {\n                    placeholder: \"Search German word...\",\n                    loading: \"Loading database...\",\n                    ready: \"Ready\",\n                    error: \"Error loading data\",\n                    overlayTitle: \"Video Pronunciation Trainer\",\n                    overlaySub: \"Enter a German word above to see how natives pronounce it\",\n                    headingPrefix: 'How to pronounce \"',\n                    headingSuffix: '\"',\n                    noResults: \"No results found.\",\n                    deeplTarget: \"en\"\n                },\n                es: {\n                    placeholder: \"Buscar palabra en alem\u00e1n...\",\n                    loading: \"Cargando base de datos...\",\n                    ready: \"Listo\",\n                    error: \"Error al cargar los datos\",\n                    overlayTitle: \"Entrenador de pronunciaci\u00f3n en v\u00eddeo\",\n                    overlaySub: \"Introduce una palabra alemana arriba para ver c\u00f3mo la pronuncian los nativos\",\n                    headingPrefix: 'C\u00f3mo se pronuncia \"',\n                    headingSuffix: '\"',\n                    noResults: \"No se encontraron resultados.\",\n                    deeplTarget: \"es\"\n                }\n            };\n\n            \/\/ Erkennt die Sprache der Website automatisch und liefert 'en' oder 'es' zur\u00fcck\n            function detectSiteLanguage() {\n                try {\n                    const htmlLang = (document.documentElement.lang || \"\").toLowerCase();\n                    if (htmlLang.startsWith(\"es\")) return \"es\";\n                    if (htmlLang.startsWith(\"en\")) return \"en\";\n\n                    const bodyClasses = document.body ? document.body.className.toLowerCase() : \"\";\n                    if (\/\\blang-es\\b|\\bpolylang-es\\b\/.test(bodyClasses)) return \"es\";\n                    if (\/\\blang-en\\b|\\bpolylang-en\\b\/.test(bodyClasses)) return \"en\";\n\n                    const browserLang = (navigator.language || navigator.userLanguage || \"\").toLowerCase();\n                    if (browserLang.startsWith(\"es\")) return \"es\";\n                } catch (e) {\n                    console.warn(\"Spracherkennung fehlgeschlagen, nutze Standard 'en':\", e);\n                }\n                return \"en\";\n            }\n\n            function applyLanguageUI() {\n                const langPack = translations[currentMode];\n                document.getElementById('searchInputUnique').placeholder = langPack.placeholder;\n                document.getElementById('overlay-text-main-unique').innerText = langPack.overlayTitle;\n                document.getElementById('overlay-text-sub-unique').innerText = langPack.overlaySub;\n                document.getElementById('status-unique').innerText = langPack.loading;\n            }\n\n            function normalizeText(text) { return text ? text.toLowerCase().trim() : \"\"; }\n\n            window.handleTypingUnique = function(val) {\n                const langPack = translations[currentMode];\n                const heading = document.getElementById('dynamic-heading-unique');\n                heading.innerHTML = val.trim() !== \"\" ? `${langPack.headingPrefix}<mark>${val}<\/mark>${langPack.headingSuffix}` : \"\";\n                clearTimeout(debounceTimer);\n                debounceTimer = setTimeout(() => {\n                    if (val.trim().length >= 3) performSearchUnique();\n                }, 400); \n            };\n\n            window.onYouTubeIframeAPIReady = function() {\n                ytPlayer = new YT.Player('player-unique', {\n                    height: '100%', width: '100%', videoId: '',\n                    playerVars: { 'autoplay': 1, 'modestbranding': 1, 'rel': 0, 'playsinline': 1 },\n                    events: { 'onReady': fetchSheetData }\n                });\n            };\n\n            \/\/ Sprache erkennen und UI direkt beim Start anwenden\n            currentMode = detectSiteLanguage();\n            applyLanguageUI();\n\n            if (!window.YT) {\n                var tag = document.createElement('script');\n                tag.src = \"https:\/\/www.youtube.com\/iframe_api\";\n                document.getElementsByTagName('script')[0].parentNode.insertBefore(tag, document.getElementsByTagName('script')[0]);\n            } else { onYouTubeIframeAPIReady(); }\n\n            async function fetchSheetData() {\n                try {\n                    const r = await fetch(CSV_URL);\n                    const txt = await r.text();\n                    parseCSV(txt);\n                    document.getElementById('status-unique').innerText = translations[currentMode].ready;\n                } catch (e) { document.getElementById('status-unique').innerText = translations[currentMode].error; }\n            }\n\n            function parseCSV(csv) {\n                const rows = csv.split(\/\\r?\\n\/).map(row => row.split(\/,(?=(?:(?:[^\"]*\"){2})*[^\"]*$)\/).map(cell => cell.replace(\/^\"|\"$\/g, '').trim()));\n                transcriptDatabase = [];\n                for (let col = 0; (rows[0]?.length || 0) > col; col++) {\n                    let currentVid = \"\", lastTimestamp = null;\n                    for (let row = 0; rows.length > row; row++) {\n                        let cell = rows[row][col];\n                        if (!cell) continue;\n                        if (cell.includes('youtube.com') || cell.includes('youtu.be')) {\n                            currentVid = extractID(cell);\n                        } else if (cell.match(\/^\\d{1,2}:\\d{2}\/)) {\n                            lastTimestamp = cell.split(\/[\\s,]+\/)[0];\n                        } else if (currentVid && lastTimestamp) {\n                            transcriptDatabase.push({\n                                vid: currentVid, timeLabel: lastTimestamp,\n                                seconds: convertToSeconds(lastTimestamp),\n                                content: cell, normalized: normalizeText(cell)\n                            });\n                            lastTimestamp = null;\n                        }\n                    }\n                }\n            }\n\n            window.performSearchUnique = function() {\n                const query = document.getElementById('searchInputUnique').value.trim();\n                const list = document.getElementById('yt-results-list');\n                const langPack = translations[currentMode];\n                if (!query) { list.innerHTML = ''; return; }\n\n                document.getElementById('no-search-overlay').style.display = 'none';\n                list.innerHTML = '';\n                const normQ = normalizeText(query);\n                const regex = new RegExp(`(${query.replace(\/[.*+?^${}()|[\\]\\\\]\/g, '\\\\$&')})`, 'gi');\n\n                const fragment = document.createDocumentFragment();\n\n                \/\/ Treffer nach Video gruppieren, Reihenfolge der ersten Nennung je Video merken\n                const groupedByVid = {};\n                const vidOrder = [];\n                transcriptDatabase.forEach((item) => {\n                    if (!item.normalized.includes(normQ)) return;\n                    if (!groupedByVid[item.vid]) { groupedByVid[item.vid] = []; vidOrder.push(item.vid); }\n                    groupedByVid[item.vid].push(item);\n                });\n\n                \/\/ Round-Robin: Runde 1 = erste Szene jedes Videos, Runde 2 = zweite Szene jedes Videos, usw.\n                const interleaved = [];\n                let round = 0;\n                let hasMore = true;\n                while (hasMore) {\n                    hasMore = false;\n                    for (const vid of vidOrder) {\n                        const item = groupedByVid[vid][round];\n                        if (item) {\n                            interleaved.push(item);\n                            hasMore = true;\n                        }\n                    }\n                    round++;\n                }\n\n                interleaved.forEach((item) => {\n                    const li = document.createElement('li');\n                    li.className = 'result-item-unique';\n                    li.setAttribute('data-seconds', item.seconds);\n                    li.setAttribute('data-vid', item.vid);\n\n                    const highlighted = item.content.replace(regex, '<mark>$1<\/mark>');\n                    li.innerHTML = `\n                        <span class=\"time-tag-unique\" onclick=\"jumpTo('${item.vid}', ${item.seconds})\">${item.timeLabel}<\/span>\n                        <span class=\"text-line-unique\" onclick=\"jumpTo('${item.vid}', ${item.seconds})\">${highlighted}<\/span>\n                        <span class=\"jump-indicator-unique\">\u25b6<\/span>\n                        <a href=\"https:\/\/www.deepl.com\/translator#de\/${langPack.deeplTarget}\/${encodeURIComponent(item.content)}\" target=\"_blank\" class=\"deepl-btn-small\">DeepL<\/a>\n                    `;\n                    fragment.appendChild(li);\n                });\n\n                if (interleaved.length === 0) {\n                    const empty = document.createElement('li');\n                    empty.className = 'result-item-unique empty-state';\n                    empty.innerText = langPack.noResults;\n                    list.appendChild(empty);\n                } else {\n                    list.appendChild(fragment);\n                }\n            };\n\n            window.jumpTo = function(vid, secs) {\n                document.getElementById('no-search-overlay').style.display = 'none';\n                if (activeVideoId !== vid) {\n                    activeVideoId = vid;\n                    ytPlayer.loadVideoById({ videoId: vid, startSeconds: secs });\n                } else {\n                    ytPlayer.seekTo(secs, true);\n                    ytPlayer.playVideo();\n                }\n                clearInterval(trackingInterval);\n                trackingInterval = setInterval(updateHighlight, 500);\n            };\n\n            function updateHighlight() {\n                if (!ytPlayer.getCurrentTime) return;\n                const curr = ytPlayer.getCurrentTime();\n                const items = document.querySelectorAll('.result-item-unique');\n                items.forEach(li => {\n                    const itemSecs = parseInt(li.getAttribute('data-seconds'));\n                    if (li.getAttribute('data-vid') === activeVideoId && curr >= itemSecs && itemSecs > curr - 3) {\n                        items.forEach(el => el.classList.remove('active'));\n                        li.classList.add('active');\n                        li.style.backgroundColor = '#d7e1ec';\n                    } else {\n                        li.style.backgroundColor = 'transparent';\n                    }\n                });\n            }\n\n            function extractID(url) {\n                const m = url.match(\/(?:youtu\\.be\\\/|youtube\\.com\\\/.*v=)([^\\?&\"'\\s]{11})\/);\n                return m ? m[1] : null;\n            }\n\n            function convertToSeconds(s) {\n                const p = s.split(':').map(Number);\n                return p.length === 3 ? p[0]*3600+p[1]*60+p[2] : p[0]*60+p[1];\n            }\n        })();\n    <\/script>\n<\/div>\n<\/div>\n\n<div class=\"dash-p p7\">\n<div id=\"millionaer-game-wrapper\">\n<div id=\"m-game-container\" class=\"m-scoped\">\n\n<style>\n#millionaer-game-wrapper {\n    all: initial;\n    display: block;\n    width: auto;\n    max-width: 100%;\n    clear: both;\n}\n\n#m-game-container.m-scoped {\n    --c-navy: #14708C;       \/* dunkles Blau: Seitenleiste, Rahmen, prim\u00e4re Buttons *\/\n    --c-navy-dark: #0E5367;  \/* noch dunkler: Trennlinie zur Seitenleiste *\/\n    --c-primary: #14708C;\n    --c-bg: #FBF8F2;         \/* helle Fl\u00e4che \/ Schrift auf dunklem Hintergrund *\/\n    --c-bg-alt: #E3F5FC;     \/* helles Blau: Hover-\/Fl\u00e4chenfarbe *\/\n    --c-text: #1D2427;       \/* Schrift auf hellem Hintergrund *\/\n    --c-border: #64748B;     \/* Rand von Antwort-Buttons (ausreichender Kontrast) *\/\n    --c-on-navy: #E6F4F8;    \/* Schrift auf dunkelblauem Hintergrund *\/\n\n    display: flex !important;\n    flex-direction: row !important;\n    text-align: center !important;\n    width: 640px !important;\n    max-width: 640px !important;\n    margin: 0 !important;\n    padding: 0 !important;\n    font-family: 'Segoe UI', Roboto, Arial, sans-serif !important;\n    background-color: var(--c-bg) !important;\n    border: 2px solid var(--c-navy) !important;\n    border-radius: 30px !important;\n    box-shadow: 0 10px 30px rgba(30, 41, 59, 0.12) !important;\n    box-sizing: border-box !important;\n    overflow: hidden !important;\n    min-height: 740px !important;\n    position: relative !important;\n    color: var(--c-text) !important;\n}\n\n\/* ---------- Sidebar (Geldstufen) ---------- *\/\n#m-game-container.m-scoped #m-sidebar {\n    width: 180px !important;\n    background: var(--c-navy) !important;\n    padding: 24px 14px !important;\n    display: flex !important;\n    flex-direction: column-reverse !important;\n    gap: 5px !important;\n    border-right: 2px solid var(--c-navy-dark) !important;\n    box-sizing: border-box !important;\n    flex-shrink: 0 !important;\n}\n\n#m-game-container.m-scoped .m-money-step {\n    padding: 8px 12px !important;\n    color: var(--c-on-navy) !important;\n    border: 1px solid rgba(230, 238, 248, 0.28) !important;\n    font-weight: 600 !important;\n    font-size: 13px !important;\n    display: flex !important;\n    justify-content: space-between !important;\n    border-radius: 10px !important;\n    transition: background 0.2s, color 0.2s !important;\n    box-sizing: border-box !important;\n}\n\n\/* Sicherheitsstufen (5, 10) und Ziel (15): fett, kr\u00e4ftiger Rand *\/\n#m-game-container.m-scoped .m-money-step.m-safe,\n#m-game-container.m-scoped .m-money-step.m-goal {\n    font-weight: 800 !important;\n    border-color: rgba(230, 238, 248, 0.8) !important;\n}\n\n#m-game-container.m-scoped .m-money-step.m-safe {\n    background: rgba(230, 238, 248, 0.14) !important;\n}\n\n\/* Sicherheitsstufe bereits erreicht: gef\u00fcllt + H\u00e4kchen *\/\n#m-game-container.m-scoped .m-money-step.m-secured {\n    background: rgba(230, 238, 248, 0.32) !important;\n}\n\n#m-game-container.m-scoped .m-money-step.m-active {\n    background: var(--c-bg) !important;\n    color: var(--c-navy) !important;\n    border-color: var(--c-bg) !important;\n    font-weight: 800 !important;\n}\n\n\/* ---------- Hauptbereich ---------- *\/\n#m-game-container.m-scoped #m-main-area {\n    flex-grow: 1 !important;\n    padding: 32px !important;\n    display: flex !important;\n    flex-direction: column !important;\n    box-sizing: border-box !important;\n    min-width: 0 !important;\n}\n\n\/* ---------- Moderator + Sprechblase ---------- *\/\n#m-game-container.m-scoped .m-mod-row {\n    display: flex !important;\n    align-items: flex-start !important;\n    gap: 22px !important;\n    margin-bottom: 32px !important;\n    text-align: left !important;\n}\n\n#m-game-container.m-scoped .m-mod-avatar {\n    flex: 0 0 56px !important;\n    width: 56px !important;\n    height: 56px !important;\n    border-radius: 50% !important;\n    border: 2px solid var(--c-navy) !important;\n    background: var(--c-bg-alt) !important;\n    display: flex !important;\n    align-items: flex-end !important;\n    justify-content: center !important;\n    overflow: hidden !important;\n    box-sizing: border-box !important;\n}\n\n#m-game-container.m-scoped .m-mod-bubble {\n    position: relative !important;\n    flex: 1 1 auto !important;\n    background: #FFFFFF !important;\n    color: var(--c-text) !important;\n    border: 2px solid var(--c-navy) !important;\n    border-radius: 16px !important;\n    padding: 16px 20px !important;\n    min-height: 64px !important;\n    display: flex !important;\n    align-items: center !important;\n    font-size: 14px !important;\n    font-weight: 600 !important;\n    line-height: 1.5 !important;\n    text-align: left !important;\n    box-sizing: border-box !important;\n}\n\n\/* Sprechblasen-Zipfel: \u00e4u\u00dferes Dreieck = Rand, inneres = F\u00fcllung *\/\n#m-game-container.m-scoped .m-mod-bubble::before {\n    content: '' !important;\n    position: absolute !important;\n    left: -12px !important;\n    top: 23px !important;\n    width: 0 !important;\n    height: 0 !important;\n    border-style: solid !important;\n    border-width: 9px 12px 9px 0 !important;\n    border-color: transparent var(--c-navy) transparent transparent !important;\n}\n\n#m-game-container.m-scoped .m-mod-bubble::after {\n    content: '' !important;\n    position: absolute !important;\n    left: -8px !important;\n    top: 25px !important;\n    width: 0 !important;\n    height: 0 !important;\n    border-style: solid !important;\n    border-width: 7px 10px 7px 0 !important;\n    border-color: transparent #FFFFFF transparent transparent !important;\n}\n\n#m-game-container.m-scoped .m-mod-bubble.m-pop {\n    animation: m-pop 0.22s ease-out !important;\n}\n@keyframes m-pop {\n    from { transform: scale(0.97); opacity: 0.6; }\n    to   { transform: scale(1);    opacity: 1; }\n}\n\n\/* ---------- Joker ---------- *\/\n#m-game-container.m-scoped .m-joker-container {\n    display: flex !important;\n    justify-content: center !important;\n    gap: 14px !important;\n    margin-bottom: 30px !important;\n}\n\n#m-game-container.m-scoped .m-joker-btn {\n    background: #FFFFFF !important;\n    border: 2px solid var(--c-navy) !important;\n    color: var(--c-navy) !important;\n    width: 110px !important;\n    height: 44px !important;\n    border-radius: 50px !important;\n    cursor: pointer !important;\n    font-weight: 700 !important;\n    font-size: 12px !important;\n    transition: transform 0.2s, background 0.2s, color 0.2s !important;\n}\n\n#m-game-container.m-scoped .m-joker-btn:hover:not(:disabled) {\n    transform: translateY(-2px) !important;\n    background: var(--c-navy) !important;\n    color: var(--c-bg) !important;\n}\n\n#m-game-container.m-scoped .m-joker-btn:disabled {\n    opacity: 0.4 !important;\n    border-style: dashed !important;\n    cursor: not-allowed !important;\n    transform: none !important;\n}\n\n\/* ---------- Frage ---------- *\/\n#m-game-container.m-scoped .m-question-box {\n    background: #FFFFFF !important;\n    border: 2px solid var(--c-navy) !important;\n    color: var(--c-text) !important;\n    padding: 30px 26px !important;\n    font-size: 1.2em !important;\n    font-weight: 700 !important;\n    line-height: 1.4 !important;\n    text-align: center !important;\n    border-radius: 20px !important;\n    margin-bottom: 32px !important;\n    min-height: 110px !important;\n    width: 100% !important;\n    display: flex !important;\n    align-items: center !important;\n    justify-content: center !important;\n    box-sizing: border-box !important;\n}\n\n\/* ---------- Antworten ---------- *\/\n#m-game-container.m-scoped #m-ans-grid {\n    display: grid !important;\n    grid-template-columns: 1fr 1fr !important;\n    gap: 18px !important;\n    width: 100% !important;\n}\n\n#m-game-container.m-scoped .m-answer-btn {\n    background: #FFFFFF !important;\n    border: 2px solid var(--c-border) !important;\n    padding: 18px !important;\n    border-radius: 18px !important;\n    cursor: pointer !important;\n    font-size: 15px !important;\n    min-height: 68px !important;\n    font-weight: 700 !important;\n    color: var(--c-text) !important;\n    transition: all 0.15s !important;\n}\n\n#m-game-container.m-scoped .m-answer-btn:hover {\n    border-color: var(--c-navy) !important;\n    background-color: var(--c-bg-alt) !important;\n}\n\n\/* Antwort-Zust\u00e4nde: \u00fcber Icons\/Muster statt Ampelfarben unterschieden *\/\n#m-game-container.m-scoped .m-selected {\n    background: var(--c-navy) !important;\n    color: var(--c-bg) !important;\n    border-color: var(--c-navy) !important;\n    animation: m-pulse 0.5s infinite !important;\n}\n@keyframes m-pulse {\n    50% { opacity: 0.7; }\n}\n\n#m-game-container.m-scoped .m-correct-anim {\n    background: var(--c-navy) !important;\n    color: var(--c-bg) !important;\n    border-color: var(--c-navy) !important;\n}\n\n#m-game-container.m-scoped .m-wrong-anim {\n    background: var(--c-bg-alt) !important;\n    color: var(--c-text) !important;\n    border: 2px dashed var(--c-navy) !important;\n    opacity: 0.8 !important;\n    text-decoration: line-through !important;\n}\n\n\/* ---------- Screens ---------- *\/\n#m-game-container.m-scoped .m-screen {\n    display: none !important;\n    flex: 1 1 auto !important;\n    flex-direction: column !important;\n    align-items: center !important;\n    justify-content: center !important;\n    width: 100% !important;\n    padding: 14px 0 !important;\n    box-sizing: border-box !important;\n}\n\n#m-game-container.m-scoped #m-quiz-screen {\n    justify-content: flex-start !important;\n}\n\n#m-game-container.m-scoped .m-active-screen {\n    display: flex !important;\n}\n\n\/* ---------- Buttons ---------- *\/\n#m-game-container.m-scoped .m-btn-start,\n#m-game-container.m-scoped .m-btn-next {\n    background: var(--c-navy) !important;\n    color: var(--c-bg) !important;\n    padding: 16px 42px !important;\n    border-radius: 50px !important;\n    cursor: pointer !important;\n    border: 2px solid var(--c-navy) !important;\n    font-weight: 700 !important;\n    font-size: 15px !important;\n    box-shadow: 0 4px 15px rgba(27, 54, 93, 0.25) !important;\n    transition: all 0.2s !important;\n}\n\n#m-game-container.m-scoped .m-btn-start.m-btn-secondary {\n    background: #FFFFFF !important;\n    color: var(--c-navy) !important;\n    box-shadow: none !important;\n}\n\n#m-game-container.m-scoped .m-btn-start:hover,\n#m-game-container.m-scoped .m-btn-next:hover {\n    transform: translateY(-2px) !important;\n    box-shadow: 0 6px 20px rgba(27, 54, 93, 0.3) !important;\n}\n\n#m-game-container.m-scoped .m-btn-start.m-btn-secondary:hover {\n    background: var(--c-bg-alt) !important;\n}\n\n#m-game-container.m-scoped #m-next-container {\n    display: none;\n    width: 100% !important;\n    text-align: center !important;\n    margin-top: 28px !important;\n}\n\n#m-game-container.m-scoped .m-end-info {\n    margin: 16px 0 32px 0 !important;\n    padding: 18px 30px !important;\n    background: #FFFFFF !important;\n    border: 2px solid var(--c-navy) !important;\n    border-radius: 18px !important;\n    font-size: 1.3em !important;\n    font-weight: 700 !important;\n    color: var(--c-navy) !important;\n}\n\n\/* Tastatur-Fokus sichtbar *\/\n#m-game-container.m-scoped button:focus-visible {\n    outline: 3px solid var(--c-navy) !important;\n    outline-offset: 2px !important;\n}\n\n\/* Weniger Bewegung *\/\n@media (prefers-reduced-motion: reduce) {\n    #m-game-container.m-scoped .m-selected,\n    #m-game-container.m-scoped .m-mod-bubble.m-pop {\n        animation: none !important;\n    }\n    #m-game-container.m-scoped * {\n        transition: none !important;\n    }\n}\n\n\/* ---------- Responsive ---------- *\/\n@media (max-width: 680px) {\n    #m-game-container.m-scoped {\n        width: 100% !important;\n        max-width: 100% !important;\n        flex-direction: column-reverse !important;\n        min-height: auto !important;\n    }\n    #m-game-container.m-scoped #m-main-area {\n        padding: 24px !important;\n    }\n    #m-game-container.m-scoped #m-sidebar {\n        width: 100% !important;\n        flex-direction: row !important;\n        flex-wrap: wrap !important;\n        justify-content: center !important;\n        border-right: none !important;\n        border-top: 2px solid var(--c-navy-dark) !important;\n        gap: 6px !important;\n        padding: 18px !important;\n    }\n    #m-game-container.m-scoped .m-money-step {\n        font-size: 11px !important;\n        padding: 5px 9px !important;\n    }\n    #m-game-container.m-scoped .m-mod-row {\n        gap: 20px !important;\n        margin-bottom: 26px !important;\n    }\n    #m-game-container.m-scoped #m-ans-grid {\n        grid-template-columns: 1fr !important;\n        gap: 14px !important;\n    }\n}\n<\/style>\n\n    <div id=\"m-sidebar\"><\/div>\n    <div id=\"m-main-area\">\n\n        <!-- Moderator mit Sprechblase -->\n        <div class=\"m-mod-row\">\n            <div class=\"m-mod-avatar\" aria-hidden=\"true\">\n                <svg viewBox=\"0 0 52 52\" width=\"52\" height=\"52\">\n                    <circle cx=\"26\" cy=\"19\" r=\"8.5\" fill=\"#14708C\"\/>\n                    <rect x=\"22.5\" y=\"25\" width=\"7\" height=\"10\" fill=\"#14708C\"\/>\n                    <path d=\"M7 52C7 41 14 34 26 34C38 34 45 41 45 52Z\" fill=\"#14708C\"\/>\n                    <path d=\"M24.3 39L16.5 35.2V42.8Z\" fill=\"#FBF8F2\"\/>\n                    <path d=\"M27.7 39L35.5 35.2V42.8Z\" fill=\"#FBF8F2\"\/>\n                    <circle cx=\"26\" cy=\"39\" r=\"2\" fill=\"#FBF8F2\"\/>\n                <\/svg>\n            <\/div>\n            <div id=\"m-mod-bubble\" class=\"m-mod-bubble\" role=\"status\" aria-live=\"polite\">\n                <span id=\"m-mod-text\"><\/span>\n            <\/div>\n        <\/div>\n\n        <div id=\"m-start-screen\" class=\"m-screen m-active-screen\">\n            <h2 style=\"color:#14708C !important; margin: 0 0 14px 0; font-weight:800; font-size:2em; font-family:'Fraunces',Georgia,serif;\">DEUTSCH-MILLION\u00c4R<\/h2>\n            <p id=\"m-start-subtitle\" style=\"color:#334155; font-weight:600; margin:0;\"><\/p>\n            <div style=\"display:flex; gap:18px; margin-top: 32px; flex-wrap:wrap; justify-content:center;\">\n                <button id=\"m-btn-level-a1\" class=\"m-btn-start\" onclick=\"startGame('A1')\"><\/button>\n                <button id=\"m-btn-level-b1\" class=\"m-btn-start m-btn-secondary\" onclick=\"startGame('B1')\"><\/button>\n            <\/div>\n        <\/div>\n\n        <div id=\"m-quiz-screen\" class=\"m-screen\">\n            <div class=\"m-joker-container\">\n                <button id=\"joker-5050\" class=\"m-joker-btn\" onclick=\"use5050()\">50:50<\/button>\n                <button id=\"joker-switch\" class=\"m-joker-btn\" onclick=\"useSwitch()\"><\/button>\n                <button id=\"joker-safety\" class=\"m-joker-btn\" onclick=\"useSafety()\"><\/button>\n            <\/div>\n            <div class=\"m-question-box\" id=\"m-q-text\"><\/div>\n            <div id=\"m-ans-grid\"><\/div>\n            <div id=\"m-next-container\">\n                <button class=\"m-btn-next\" onclick=\"proceedToNext()\"><\/button>\n            <\/div>\n        <\/div>\n\n        <div id=\"m-end-screen\" class=\"m-screen\">\n            <h2 id=\"m-end-title\" style=\"color:#14708C !important; font-weight:800; font-size:1.8em; margin:0 0 10px 0;\"><\/h2>\n            <p id=\"m-end-info\" class=\"m-end-info\"><\/p>\n            <button class=\"m-btn-start\" onclick=\"restartGame()\"><\/button>\n        <\/div>\n    <\/div>\n<\/div>\n<\/div>\n\n<script>\n(function(){\n    \/* ---------- \u00dcbersetzungen (Oberfl\u00e4che: en\/es) ---------- *\/\n    const translations = {\n        en: {\n            subtitle: \"Click on a level to start the quiz.\",\n            levelA1: \"Easy German\",\n            levelB1: \"Normal German\",\n            jokerSwitch: \"Swap\",\n            jokerSafety: \"2 tries\",\n            loading: \"Loading question\u2026\",\n            nextBtn: \"Next\",\n            restartBtn: \"Restart\",\n            endTitleLost: \"Game over\",\n            endTitleWon: \"CONGRATULATIONS! MILLIONAIRE!\",\n            wonPrefix: \"You won: \",\n            wonAll: \"CONGRATULATIONS! YOU'RE A MILLIONAIRE!\"\n        },\n        es: {\n            subtitle: \"Haz clic en un nivel para empezar el cuestionario.\",\n            levelA1: \"Alem\u00e1n f\u00e1cil\",\n            levelB1: \"Alem\u00e1n normal\",\n            jokerSwitch: \"Cambiar\",\n            jokerSafety: \"2 intentos\",\n            loading: \"Cargando pregunta\u2026\",\n            nextBtn: \"Siguiente\",\n            restartBtn: \"Reiniciar\",\n            endTitleLost: \"Fin del juego\",\n            endTitleWon: \"\u00a1FELICIDADES! \u00a1MILLONARIO!\",\n            wonPrefix: \"Has ganado: \",\n            wonAll: \"\u00a1FELICIDADES! \u00a1ERES MILLONARIO!\"\n        }\n    };\n\n    \/* ---------- Moderator: immer auf Deutsch (zuf\u00e4llige Auswahl je Situation) ---------- *\/\n    const modSay = {\n        welcome: [\"Willkommen bei Deutsch-Million\u00e4r! W\u00e4hlen Sie Ihr Niveau.\"],\n        start: [\n            \"Gute Wahl! Bei Frage 5 und Frage 10 erreichen Sie eine Sicherheitsstufe. Los geht's mit Frage 1!\",\n            \"Viel Gl\u00fcck! Bei Frage 5 und 10 sind Sie auf der sicheren Seite. Hier ist die erste Frage.\"\n        ],\n        qEarly: [\"Wir fangen ganz leicht an.\", \"Hier kommt die n\u00e4chste Frage.\", \"Lassen Sie sich Zeit. Lesen Sie die Frage in Ruhe.\"],\n        qAfterSafe: [\"Sie haben {safe} sicher. Jetzt spielen wir um {prize}!\", \"{safe} kann Ihnen niemand mehr nehmen. Weiter geht's \u2013 es geht um {prize}!\"],\n        qMid: [\"Jetzt wird es ernst.\", \"Diese Frage ist {prize} wert. Lesen Sie genau!\", \"Noch eine Stufe h\u00f6her. Sie machen das gut!\"],\n        qHigh: [\"Jetzt spielen wir um {prize}. Bleiben Sie konzentriert!\", \"Jetzt wird es schwer.\", \"Das Publikum h\u00e4lt den Atem an \u2026\"],\n        qFinal: [\"Die Millionenfrage! Nehmen Sie sich alle Zeit der Welt.\"],\n        thinking: [\"Ist das Ihre endg\u00fcltige Antwort? Wir pr\u00fcfen \u2026\", \"Sind Sie sicher? \u2026 Schauen wir mal.\", \"Interessante Wahl \u2026 mal sehen.\"],\n        correct: [\"RICHTIG! Sie haben jetzt {prize}.\", \"Ja, das stimmt! {prize} geh\u00f6ren Ihnen.\", \"Ja! Ausgezeichnet \u2013 {prize}.\"],\n        safeReached: [\n            \"RICHTIG! Sicherheitsstufe erreicht: {prize} kann Ihnen jetzt niemand mehr nehmen!\",\n            \"Ja! Sie haben die Sicherheitsstufe geschafft. Diese {prize} sind Ihnen sicher!\"\n        ],\n        wrongWithSafety: [\"Das war falsch. Aber Sie haben noch einen zweiten Versuch!\"],\n        safetyActivated: [\"Joker aktiviert! Sie haben bei dieser Frage zwei Versuche.\"],\n        wrong: [\"Oh nein, das ist leider falsch. Die richtige Antwort ist markiert.\"],\n        joker5050: [\"Zwei falsche Antworten sind weg. Jetzt bleiben nur noch zwei!\"],\n        jokerSwitch: [\"Kein Problem \u2013 hier ist eine neue Frage.\"],\n        endLost: [\"Sie nehmen {prize} mit nach Hause. Gut gespielt!\", \"{prize} sind Ihnen sicher. Das haben Sie gut gemacht!\"],\n        endLostZero: [\"Diesmal gehen Sie ohne Gewinn nach Hause. Versuchen Sie es gleich noch einmal!\"],\n        endWon: [\"Unglaublich! Sie sind Million\u00e4r!\"]\n    };\n\n    function detectLang() {\n        try {\n            const htmlLang = (document.documentElement.lang || '').toLowerCase();\n            if (htmlLang.indexOf('es') === 0) return 'es';\n            if (htmlLang.indexOf('en') === 0) return 'en';\n        } catch (e) {}\n        const nav = ((navigator.language || navigator.userLanguage || 'en') + '').toLowerCase();\n        return nav.indexOf('es') === 0 ? 'es' : 'en';\n    }\n\n    const lang = detectLang();\n    const t = translations[lang];\n    const numberLocale = lang === 'es' ? 'es-ES' : 'en-GB';\n\n    function formatMoney(value) {\n        return value.toLocaleString(numberLocale) + ' \u20ac';\n    }\n\n    \/* Betr\u00e4ge in der Moderator-Sprechblase: deutsche Schreibweise *\/\n    function formatMoneyDe(value) {\n        return value.toLocaleString('de-DE') + ' \u20ac';\n    }\n\n    function pick(list) {\n        return list[Math.floor(Math.random() * list.length)];\n    }\n\n    \/* ---------- Moderator-Sprechblase ---------- *\/\n    const modText = document.getElementById('m-mod-text');\n    const modBubble = document.getElementById('m-mod-bubble');\n\n    function say(key, vars) {\n        let text = pick(modSay[key]);\n        if (vars) {\n            Object.keys(vars).forEach(k => { text = text.split('{' + k + '}').join(vars[k]); });\n        }\n        modText.textContent = text;\n        modBubble.classList.remove('m-pop');\n        void modBubble.offsetWidth; \/\/ Animation neu starten\n        modBubble.classList.add('m-pop');\n    }\n\n    \/* ---------- Sound ---------- *\/\n    const audioCtx = new (window.AudioContext || window.webkitAudioContext)();\n\n    function playSound(type) {\n        const now = audioCtx.currentTime;\n\n        if (type === 'tension') {\n            const osc = audioCtx.createOscillator();\n            const gain = audioCtx.createGain();\n            osc.type = 'sine';\n            osc.frequency.setValueAtTime(110, now);\n            osc.frequency.exponentialRampToValueAtTime(165, now + 7);\n            gain.gain.setValueAtTime(0.1, now);\n            gain.gain.linearRampToValueAtTime(0, now + 7);\n            osc.connect(gain); gain.connect(audioCtx.destination);\n            osc.start(); osc.stop(now + 7);\n        } else if (type === 'correct') {\n            \/* Kurzer Dreiklang (ca. 0,4 s) *\/\n            [523.25, 659.25, 783.99].forEach((freq, i) => {\n                const start = now + i * 0.07;\n                const osc = audioCtx.createOscillator();\n                const gain = audioCtx.createGain();\n                osc.type = 'triangle';\n                osc.frequency.setValueAtTime(freq, start);\n                gain.gain.setValueAtTime(0.12, start);\n                gain.gain.exponentialRampToValueAtTime(0.001, start + 0.22);\n                osc.connect(gain); gain.connect(audioCtx.destination);\n                osc.start(start); osc.stop(start + 0.25);\n            });\n        } else if (type === 'wrong') {\n            const osc = audioCtx.createOscillator();\n            const gain = audioCtx.createGain();\n            osc.type = 'sawtooth';\n            osc.frequency.setValueAtTime(120, now);\n            osc.frequency.linearRampToValueAtTime(80, now + 0.5);\n            gain.gain.setValueAtTime(0.1, now);\n            gain.gain.linearRampToValueAtTime(0, now + 0.5);\n            osc.connect(gain); gain.connect(audioCtx.destination);\n            osc.start(); osc.stop(now + 0.5);\n        }\n    }\n\n    \/* ---------- Statisches UI \u00fcbersetzen ---------- *\/\n    say('welcome');\n    document.getElementById('m-start-subtitle').innerText = t.subtitle;\n    document.getElementById('m-btn-level-a1').innerText = t.levelA1;\n    document.getElementById('m-btn-level-b1').innerText = t.levelB1;\n    document.getElementById('joker-switch').innerText = t.jokerSwitch;\n    document.getElementById('joker-safety').innerText = t.jokerSafety;\n    document.getElementById('m-q-text').innerText = t.loading;\n    document.querySelector('#m-next-container .m-btn-next').innerText = t.nextBtn;\n    document.querySelector('#m-end-screen .m-btn-start').innerText = t.restartBtn;\n    document.getElementById('m-end-title').innerText = t.endTitleLost;\n\n    \/* ---------- Spiellogik ---------- *\/\n    const sheetID = \"1jV4htReTIOu9qlcb_B-E9kDSU6o-igJLvfDfiChBucU\";\n    const sheetName = \"Quizfragen\";\n    let questionsDB = {};\n    let currentStep = 1;\n    let currentLevel = 'A1';\n    let safetyActive = false;\n    let locked = false; \/\/ true, solange eine Antwort gepr\u00fcft wird oder das Ergebnis angezeigt wird\n    let currentQuestionData = null;\n    const moneyScale = [0, 50, 100, 200, 300, 500, 1000, 2000, 4000, 8000, 16000, 32000, 64000, 125000, 500000, 1000000];\n\n    \/* Sicherheitsstufen: Wer diese Frage richtig beantwortet, beh\u00e4lt den Betrag auch bei einer falschen Antwort sp\u00e4ter *\/\n    const safeSteps = [5, 10];\n\n    \/* Gewinn, den man bei einer falschen Antwort auf Frage `step` mitnimmt *\/\n    function securedAmount(step) {\n        let amount = 0;\n        safeSteps.forEach(s => { if (step > s) amount = moneyScale[s]; });\n        return amount;\n    }\n\n    async function fetchSheetData() {\n        try {\n            const url = `https:\/\/docs.google.com\/spreadsheets\/d\/${sheetID}\/gviz\/tq?tqx=out:json&sheet=${sheetName}`;\n            const response = await fetch(url);\n            const text = await response.text();\n            const json = JSON.parse(text.substr(47).slice(0, -2));\n            json.table.rows.forEach(row => {\n                let lvl = row.c[0]?.v; if (!lvl) return;\n                if (!questionsDB[lvl]) questionsDB[lvl] = {};\n                for (let i = 1; i <= 15; i++) {\n                    let cell = row.c[i]?.v;\n                    if (cell) {\n                        let parts = cell.split(';').map(p => p.trim());\n                        if (!questionsDB[lvl][i]) questionsDB[lvl][i] = [];\n                        questionsDB[lvl][i].push({ q: parts[0], a: parts.slice(1) });\n                    }\n                }\n            });\n        } catch (e) {\n            console.error(\"Datenfehler beim Laden der Fragen\", e);\n        }\n    }\n\n    function initSidebar() {\n        const sb = document.getElementById('m-sidebar'); sb.innerHTML = '';\n        for (let i = 1; i < moneyScale.length; i++) {\n            const div = document.createElement('div');\n            div.className = 'm-money-step'\n                + (safeSteps.indexOf(i) !== -1 ? ' m-safe' : '')\n                + (i === 15 ? ' m-goal' : '');\n            div.id = 'm-step-' + i;\n            div.innerHTML = `<span>${i}<\/span> <span>${formatMoney(moneyScale[i])}<\/span>`;\n            sb.appendChild(div);\n        }\n    }\n\n    function markSecured(step) {\n        const el = document.getElementById('m-step-' + step);\n        if (!el) return;\n        el.classList.add('m-secured');\n        el.firstElementChild.textContent = '\u2713 ' + step;\n    }\n\n    window.startGame = function (lvl) {\n        if (audioCtx.state === 'suspended') audioCtx.resume();\n        currentLevel = lvl; currentStep = 1;\n        currentQuestionData = null;\n        initSidebar();\n        document.getElementById('m-start-screen').classList.remove('m-active-screen');\n        document.getElementById('m-quiz-screen').classList.add('m-active-screen');\n        loadQuestion('start');\n    };\n\n    function introKey(step) {\n        if (step === 15) return 'qFinal';\n        if (step >= 11) return 'qHigh';\n        if (step >= 6) return 'qMid';\n        return 'qEarly';\n    }\n\n    \/* mode: 'start' (erste Frage), 'next' (n\u00e4chste Frage), 'switch' (Joker Tauschen) *\/\n    function loadQuestion(mode) {\n        locked = false;\n        document.getElementById('m-next-container').style.display = 'none';\n        document.getElementById('m-ans-grid').style.display = 'grid';\n        document.querySelectorAll('.m-money-step').forEach(el => el.classList.remove('m-active'));\n        const activeStep = document.getElementById('m-step-' + currentStep);\n        if (activeStep) activeStep.classList.add('m-active');\n\n        const pool = questionsDB[currentLevel] && questionsDB[currentLevel][currentStep];\n        if (!pool || !pool.length) {\n            document.getElementById('m-q-text').innerText = t.loading;\n            setTimeout(() => loadQuestion(mode), 500);\n            return;\n        }\n\n        let candidates = pool;\n        if (mode === 'switch' && currentQuestionData && pool.length > 1) {\n            candidates = pool.filter(q => q !== currentQuestionData);\n        }\n        currentQuestionData = pick(candidates);\n        document.getElementById('m-q-text').innerText = currentQuestionData.q;\n\n        const grid = document.getElementById('m-ans-grid'); grid.innerHTML = '';\n        let answers = currentQuestionData.a.map((txt, i) => ({ txt, correct: i === 0 }));\n        answers.sort(() => Math.random() - 0.5);\n\n        answers.forEach(obj => {\n            const b = document.createElement('button');\n            b.className = 'm-answer-btn'; b.innerText = obj.txt;\n            b.dataset.correct = obj.correct;\n            b.onclick = (e) => checkAnswer(obj.correct, e.target);\n            grid.appendChild(b);\n        });\n\n        const prize = formatMoneyDe(moneyScale[currentStep]);\n        if (mode === 'switch') {\n            say('jokerSwitch');\n        } else if (mode === 'start') {\n            say('start');\n        } else if (safeSteps.indexOf(currentStep - 1) !== -1) {\n            say('qAfterSafe', { safe: formatMoneyDe(securedAmount(currentStep)), prize: prize });\n        } else {\n            say(introKey(currentStep), { prize: prize });\n        }\n    }\n\n    function checkAnswer(isCorrect, btn) {\n        if (locked) return;\n        locked = true;\n\n        const allBtns = document.querySelectorAll('.m-answer-btn');\n        allBtns.forEach(b => b.style.pointerEvents = 'none');\n\n        btn.classList.add('m-selected');\n        say('thinking');\n        playSound('tension');\n\n        setTimeout(() => {\n            btn.classList.remove('m-selected');\n            if (isCorrect) {\n                playSound('correct');\n                btn.classList.add('m-correct-anim');\n                btn.innerText = '\u2713 ' + btn.innerText;\n                const prize = formatMoneyDe(moneyScale[currentStep]);\n                if (safeSteps.indexOf(currentStep) !== -1) {\n                    markSecured(currentStep);\n                    say('safeReached', { prize: prize });\n                } else {\n                    say('correct', { prize: prize });\n                }\n                document.getElementById('m-next-container').style.display = 'block';\n            } else {\n                if (safetyActive) {\n                    safetyActive = false;\n                    btn.classList.add('m-wrong-anim');\n                    btn.innerText = '\u2717 ' + btn.innerText;\n                    say('wrongWithSafety');\n                    setTimeout(() => {\n                        btn.style.visibility = 'hidden';\n                        allBtns.forEach(b => { if (b.style.visibility !== 'hidden') b.style.pointerEvents = 'auto'; });\n                        locked = false;\n                    }, 1500);\n                } else {\n                    playSound('wrong');\n                    btn.classList.add('m-wrong-anim');\n                    btn.innerText = '\u2717 ' + btn.innerText;\n                    allBtns.forEach(b => {\n                        if (b.dataset.correct === \"true\") {\n                            b.classList.add('m-correct-anim');\n                            b.innerText = '\u2713 ' + b.innerText;\n                        }\n                    });\n                    say('wrong');\n                    setTimeout(() => endGame(false), 2500);\n                }\n            }\n        }, 7000);\n    }\n\n    window.use5050 = function () {\n        if (locked) return;\n        const btns = Array.from(document.querySelectorAll('.m-answer-btn'))\n            .filter(b => b.dataset.correct === \"false\" && b.style.visibility !== 'hidden');\n        btns.sort(() => Math.random() - 0.5).slice(0, 2).forEach(b => b.style.visibility = 'hidden');\n        document.getElementById('joker-5050').disabled = true;\n        say('joker5050');\n    };\n\n    window.useSwitch = function () {\n        if (locked) return;\n        document.getElementById('joker-switch').disabled = true;\n        loadQuestion('switch');\n    };\n\n    window.useSafety = function () {\n        if (locked) return;\n        safetyActive = true;\n        document.getElementById('joker-safety').disabled = true;\n        say('safetyActivated');\n    };\n\n    window.proceedToNext = function () {\n        if (currentStep === 15) endGame(true);\n        else { currentStep++; loadQuestion('next'); }\n    };\n\n    function endGame(won) {\n        const amount = won ? moneyScale[15] : securedAmount(currentStep);\n        document.getElementById('m-quiz-screen').classList.remove('m-active-screen');\n        document.getElementById('m-end-screen').classList.add('m-active-screen');\n        document.getElementById('m-end-title').innerText = won ? t.endTitleWon : t.endTitleLost;\n        document.getElementById('m-end-info').innerText = won ? t.wonAll : t.wonPrefix + formatMoney(amount);\n        if (won) say('endWon');\n        else if (amount > 0) say('endLost', { prize: formatMoneyDe(amount) });\n        else say('endLostZero');\n    }\n\n    \/* Neustart ohne die Seite neu zu laden: Zustand zur\u00fccksetzen, Fragen bleiben im Speicher *\/\n    window.restartGame = function () {\n        currentStep = 1;\n        safetyActive = false;\n        locked = false;\n        currentQuestionData = null;\n\n        ['joker-5050', 'joker-switch', 'joker-safety'].forEach(id => {\n            document.getElementById(id).disabled = false;\n        });\n\n        document.getElementById('m-ans-grid').innerHTML = '';\n        document.getElementById('m-next-container').style.display = 'none';\n        document.getElementById('m-q-text').innerText = t.loading;\n        document.getElementById('m-sidebar').innerHTML = '';\n\n        document.getElementById('m-end-screen').classList.remove('m-active-screen');\n        document.getElementById('m-quiz-screen').classList.remove('m-active-screen');\n        document.getElementById('m-start-screen').classList.add('m-active-screen');\n        say('welcome');\n    };\n\n    fetchSheetData();\n})();\n<\/script>\n<\/div>\n\n<div class=\"dash-p p8\">\n<style id=\"stats-design\">\n\/* Statistics \u2013 an aktuelles Dashboard-Design angepasst (Teal, Fraunces, Inter) *\/\n.dash .p8 .tm-dashboard-card{font-family:'Inter','Segoe UI',Roboto,sans-serif!important;color:#1D2427!important}\n.dash .p8 .tm-stats-grid{gap:12px!important;margin-bottom:16px!important}\n.dash .p8 .tm-stat-box{align-items:flex-start!important;justify-content:flex-end!important;min-height:0!important;padding:16px 16px 14px!important;background:#fff!important;border:1px solid #E7E2D8!important;border-radius:18px!important;box-shadow:0 10px 26px rgba(29,36,39,.04)!important}\n.dash .p8 .tm-stat-box .tm-stat-icon{display:none!important}\n.dash .p8 .tm-stat-label{order:2;margin:6px 0 0!important;font-size:10.5px!important;font-weight:700!important;letter-spacing:.08em!important;color:#4B565A!important}\n.dash .p8 .tm-stat-value{order:1;font-family:'Fraunces',Georgia,serif!important;font-size:30px!important;font-weight:600!important;line-height:1!important;color:#0E5367!important}\n.dash .p8 .tm-stat-box:first-child{background:#E2F0F4!important;border-color:#C7DDE4!important}\n.dash .p8 .tm-stat-badge{top:10px!important;right:10px!important;padding:3px 8px!important;border-radius:999px!important;background:#FFCF33!important;color:#0E1A20!important;font-size:10px!important;font-weight:800!important}\n.dash .p8 .tm-chart-card,.dash .p8 .tm-section-card{padding:22px!important;margin-bottom:16px!important;background:#fff!important;border:1px solid #E7E2D8!important;border-radius:22px!important;box-shadow:0 10px 26px rgba(29,36,39,.04)!important}\n.dash .p8 .tm-bottom-grid .tm-section-card{margin-bottom:0!important}\n.dash .p8 .tm-chart-title,.dash .p8 .tm-section-title{margin:0 0 18px!important;text-align:left!important;font-family:'Fraunces',Georgia,serif!important;font-size:19px!important;font-weight:600!important;color:#1D2427!important}\n.dash .p8 .tm-bar-chart{gap:10px!important}\n.dash .p8 .tm-bar-val{font-size:11px!important;font-weight:700!important;color:#4B565A!important}\n.dash .p8 .tm-bar-track{max-width:40px!important;background:#F2F8FA!important;border:0!important;border-radius:10px!important}\n.dash .p8 .tm-bar-fill{background:#6EC1E4!important;border-radius:10px!important}\n.dash .p8 .tm-bar-fill.target-reached{background:#14708C!important}\n.dash .p8 .tm-bar-col:last-child .tm-bar-lbl{color:#14708C!important;font-weight:800!important}\n.dash .p8 .tm-bar-lbl{font-size:11px!important;font-weight:600!important;color:#4B565A!important}\n.dash .p8 .tm-line-chart-wrap stop:first-child{stop-color:#14708C!important;stop-opacity:.22!important}\n.dash .p8 .tm-line-chart-wrap stop:last-child{stop-color:#ffffff!important}\n.dash .p8 .tm-line-chart-wrap path[fill=\"none\"]{stroke:#14708C!important;stroke-width:2.5!important}\n.dash .p8 .tm-line-chart-wrap line{stroke:#E0A800!important;stroke-width:1.5!important;opacity:1!important}\n.dash .p8 .tm-line-chart-wrap text{fill:#8A5A00!important;font-family:'Inter',sans-serif!important}\n.dash .p8 .tm-sentence-card,.dash .p8 .tm-topic-row{background:#F7FAFB!important;border:1px solid #E5EEF1!important;border-radius:12px!important}\n.dash .p8 .tm-sentence-card{padding:12px 14px!important}\n.dash .p8 .tm-tag{border-radius:999px!important;padding:2px 8px!important;font-size:10px!important;letter-spacing:.04em!important}\n.dash .p8 .tm-tag-level{background:#14708C!important;color:#fff!important}\n.dash .p8 .tm-tag-topic{background:#E2F0F4!important;color:#0E5367!important}\n.dash .p8 .tm-sentence-de{font-family:'Fraunces',Georgia,serif!important;font-size:15px!important;font-weight:600!important;color:#1D2427!important}\n.dash .p8 .tm-sentence-en{font-size:13px!important;font-weight:500!important;color:#4B565A!important}\n.dash .p8 .tm-topic-row{padding:10px 12px!important;margin-bottom:8px!important}\n.dash .p8 .tm-topic-name{font-size:14px!important;font-weight:700!important;color:#1D2427!important}\n.dash .p8 .tm-topic-date{font-size:12px!important;font-weight:500!important;color:#4B565A!important}\n.dash .p8 .tm-topic-count{background:#E2F0F4!important;color:#0E5367!important;font-size:12px!important;font-weight:700!important;border-radius:999px!important;padding:4px 10px!important}\n.dash .p8 .tm-recent-scroll-box::-webkit-scrollbar-thumb,.dash .p8 .tm-topics-scroll-box::-webkit-scrollbar-thumb{background:#C7DDE4!important}\n.dash .p8 .tm-topic-count{flex-shrink:0!important;white-space:nowrap!important;margin-left:10px!important}\n@media (max-width:768px){.dash .p8 .tm-stat-box{flex:1 1 30%!important}.dash .p8 .tm-stat-value{font-size:24px!important}.dash .p8 .tm-chart-card,.dash .p8 .tm-section-card{padding:16px!important}}\n<\/style>\n<div class=\"tm-card tm-dashboard-card\">\n\n    <!-- 1. Top Cards Grid (Full width + Icons + Dynamic Badge) -->\n    \n    <div class=\"tm-stats-grid\">\n        <div class=\"tm-stat-box\">\n            <span class=\"tm-stat-badge danger\" id=\"tm-stat-danger-badge\" style=\"display: none;\"><\/span>\n            <span class=\"tm-stat-icon\">\ud83d\udd25<\/span>\n            <span class=\"tm-stat-label\" id=\"tm-lbl-streak\"><\/span>\n            <span class=\"tm-stat-value\" id=\"tm-stat-streak\">0<\/span>\n        <\/div>\n        <div class=\"tm-stat-box\">\n            <span class=\"tm-stat-icon\">\ud83c\udfaf<\/span>\n            <span class=\"tm-stat-label\" id=\"tm-lbl-goal\"><\/span>\n            <span class=\"tm-stat-value\" id=\"tm-stat-target\">10<\/span>\n        <\/div>\n        <div class=\"tm-stat-box\">\n            <span class=\"tm-stat-icon\">\ud83d\udcda<\/span>\n            <span class=\"tm-stat-label\" id=\"tm-lbl-total\"><\/span>\n            <span class=\"tm-stat-value\" id=\"tm-stat-total\">0<\/span>\n        <\/div>\n        <div class=\"tm-stat-box\">\n            <span class=\"tm-stat-icon\">\ud83c\udfc6<\/span>\n            <span class=\"tm-stat-label\" id=\"tm-lbl-best\"><\/span>\n            <span class=\"tm-stat-value\" id=\"tm-stat-best\">0<\/span>\n        <\/div>\n        <div class=\"tm-stat-box\">\n            <span class=\"tm-stat-icon\">\u26a1<\/span>\n            <span class=\"tm-stat-label\" id=\"tm-lbl-avg\"><\/span>\n            <span class=\"tm-stat-value\" id=\"tm-stat-avg\">0.0<\/span>\n        <\/div>\n    <\/div>\n    \n\n    <!-- 2. Activity Last 7 Days -->\n    <div class=\"tm-chart-card\">\n        <div class=\"tm-chart-title\"><span id=\"tm-lbl-7d-title\"><\/span> (<span id=\"tm-lbl-total-word\"><\/span>: <span id=\"tm-7d-sum\">0<\/span>)<\/div>\n        <div class=\"tm-bar-chart\" id=\"tm-chart-7d\"><\/div>\n    <\/div>\n\n    <!-- 3. 30-Day Trend & Target Line -->\n    <div class=\"tm-chart-card\">\n        <div class=\"tm-chart-title\" id=\"tm-lbl-30d-title\"><\/div>\n        <div class=\"tm-line-chart-wrap\" id=\"tm-chart-30d-wrap\">\n            <!-- SVG rendered dynamically -->\n        <\/div>\n    <\/div>\n\n    <!-- 4. Bottom Grid: Recently Practiced Sentences & Topics Overview -->\n    <div class=\"tm-bottom-grid\">\n        <div class=\"tm-section-card\">\n            <div class=\"tm-section-title\" id=\"tm-lbl-recent-title\"><\/div>\n            <div class=\"tm-recent-scroll-box\">\n                <div class=\"tm-recent-list\" id=\"tm-recent-sentences\">\n                    <div class=\"tm-recent-loading\" id=\"tm-lbl-loading\"><\/div>\n                <\/div>\n            <\/div>\n        <\/div>\n\n        <div class=\"tm-section-card\">\n            <div class=\"tm-section-title\" id=\"tm-lbl-topics-title\"><\/div>\n            <div class=\"tm-topics-scroll-box\">\n                <div class=\"tm-topics-list\" id=\"tm-topics-list\">\n                    <div class=\"tm-topics-empty\" id=\"tm-lbl-no-topics\"><\/div>\n                <\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n\n<\/div>\n\n<style>\n:root {\n    --dash-scale: 1;\n    --card-scale: 1;\n}\n\n\/* Container: new width + light background, white content boxes *\/\n.elementor-widget-html .tm-dashboard-card,\n.tm-dashboard-card {\n    max-width: calc(640px * var(--card-scale));\n    width: 100%;\n    margin: 0 auto !important;\n    padding: 0 !important;\n    font-family: system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif !important;\n    color: #1E293B;\n    box-sizing: border-box !important;\n}\n\n.tm-dashboard-card * {\n    box-sizing: border-box !important;\n}\n\n\/* 1. Stats Grid *\/\n.tm-stats-grid {\n    display: flex;\n    width: 100%;\n    gap: calc(12px * var(--dash-scale));\n    margin-bottom: calc(16px * var(--dash-scale));\n}\n\n.tm-stat-box {\n    flex: 1;\n    background: #ffffff;\n    border: 1px solid #E8EEF5;\n    border-radius: calc(20px * var(--dash-scale));\n    padding: calc(14px * var(--dash-scale)) calc(8px * var(--dash-scale));\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    justify-content: center;\n    position: relative;\n    box-shadow: 0 4px 12px rgba(15, 23, 42, 0.03);\n    min-height: calc(95px * var(--dash-scale));\n}\n\n.tm-stat-icon {\n    font-size: calc(2rem * var(--dash-scale));\n    margin-bottom: calc(6px * var(--dash-scale));\n    line-height: 1;\n}\n\n.tm-stat-badge {\n    position: absolute;\n    top: 6px;\n    right: 6px;\n    background: #1E293B;\n    color: #ffffff;\n    font-size: calc(0.45rem * var(--dash-scale));\n    font-weight: 700;\n    padding: 1px 5px;\n    border-radius: 8px;\n}\n\n.tm-stat-label {\n    font-size: calc(0.65rem * var(--dash-scale));\n    color: #475569;\n    font-weight: 800;\n    text-transform: uppercase;\n    letter-spacing: 0.04em;\n    margin-bottom: 4px;\n}\n\n.tm-stat-value {\n    font-size: calc(1.5rem * var(--dash-scale)) !important;\n    font-weight: 800 !important;\n    color: #1E293B;\n    line-height: 1 !important;\n}\n\n\/* 2. & 3. Chart Cards *\/\n.tm-chart-card {\n    background: #ffffff;\n    border: 1px solid #E8EEF5;\n    border-radius: calc(20px * var(--dash-scale));\n    padding: calc(20px * var(--dash-scale));\n    margin-bottom: calc(16px * var(--dash-scale));\n    box-shadow: 0 4px 12px rgba(15, 23, 42, 0.03);\n    width: 100%;\n}\n\n.tm-chart-title {\n    font-size: calc(0.95rem * var(--dash-scale));\n    font-weight: 800;\n    color: #1E293B;\n    text-align: center;\n    margin-bottom: calc(16px * var(--dash-scale));\n}\n\n\/* 7-Day Bar Chart *\/\n.tm-bar-chart {\n    display: flex;\n    align-items: flex-end;\n    justify-content: space-between;\n    height: calc(130px * var(--dash-scale));\n    gap: calc(12px * var(--dash-scale));\n}\n\n.tm-bar-col {\n    flex: 1;\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    height: 100%;\n    justify-content: flex-end;\n}\n\n.tm-bar-val {\n    font-size: calc(0.72rem * var(--dash-scale));\n    font-weight: 800;\n    color: #475569;\n    margin-bottom: 4px;\n    white-space: nowrap;\n}\n\n.tm-bar-track {\n    width: 100%;\n    max-width: 48px;\n    height: 70%;\n    display: flex;\n    align-items: flex-end;\n    background: #F4F8FC;\n    border: 1px solid #E8EEF5;\n    border-radius: 8px 8px 0 0;\n    overflow: hidden;\n}\n\n.tm-bar-fill {\n    width: 100%;\n    background: #475569;\n    transition: height 0.5s ease;\n    border-radius: 6px 6px 0 0;\n}\n\n.tm-bar-fill.target-reached {\n    background: #1E293B;\n}\n\n.tm-bar-lbl {\n    font-size: calc(0.72rem * var(--dash-scale));\n    font-weight: 700;\n    color: #475569;\n    margin-top: 8px;\n}\n\n\/* 30-Day Line Chart *\/\n.tm-line-chart-wrap {\n    width: 100%;\n    height: calc(130px * var(--dash-scale));\n    position: relative;\n}\n\n.tm-line-chart-wrap svg {\n    width: 100%;\n    height: 100%;\n    overflow: visible;\n}\n\n\/* 4. Bottom Grid *\/\n.tm-bottom-grid {\n    display: flex;\n    flex-direction: column;\n    width: 100%;\n    gap: calc(16px * var(--dash-scale));\n}\n\n.tm-section-card {\n    background: #ffffff;\n    border: 1px solid #E8EEF5;\n    border-radius: calc(20px * var(--dash-scale));\n    padding: calc(20px * var(--dash-scale));\n    box-shadow: 0 4px 12px rgba(15, 23, 42, 0.03);\n    width: 100%;\n}\n\n.tm-section-title {\n    font-size: calc(0.95rem * var(--dash-scale)) !important;\n    font-weight: 800 !important;\n    color: #1E293B !important;\n    text-align: center;\n    margin-bottom: calc(16px * var(--dash-scale)) !important;\n}\n\n\/* Scrollboxes *\/\n.tm-recent-scroll-box, .tm-topics-scroll-box {\n    max-height: calc(260px * var(--dash-scale));\n    overflow-y: auto;\n    padding-right: 4px;\n}\n\n.tm-recent-scroll-box::-webkit-scrollbar,\n.tm-topics-scroll-box::-webkit-scrollbar {\n    width: 4px;\n}\n.tm-recent-scroll-box::-webkit-scrollbar-thumb,\n.tm-topics-scroll-box::-webkit-scrollbar-thumb {\n    background: #E8EEF5;\n    border-radius: 4px;\n}\n\n\/* Sentence Cards *\/\n.tm-sentence-card {\n    background: #F4F8FC;\n    border: 1px solid #E8EEF5;\n    border-radius: calc(10px * var(--dash-scale));\n    padding: calc(10px * var(--dash-scale));\n    margin-bottom: 8px;\n    display: flex;\n    flex-direction: column;\n    gap: 4px;\n}\n\n.tm-tags-row {\n    display: flex;\n    gap: 6px;\n    margin-bottom: 2px;\n}\n\n.tm-tag {\n    font-size: calc(0.6rem * var(--dash-scale));\n    font-weight: 800;\n    padding: 2px 6px;\n    border-radius: 4px;\n    text-transform: uppercase;\n}\n\n.tm-tag-level {\n    background: #E8EEF5;\n    color: #1E293B;\n}\n\n.tm-tag-topic {\n    background: #E8EEF5;\n    color: #1E293B;\n}\n\n.tm-sentence-de {\n    font-size: calc(0.82rem * var(--dash-scale));\n    font-weight: 700;\n    color: #1E293B;\n}\n\n.tm-sentence-en {\n    font-size: calc(0.78rem * var(--dash-scale));\n    font-weight: 600;\n    color: #475569;\n}\n\n\/* Topic Rows Design *\/\n.tm-topic-row {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    padding: 8px 10px;\n    background: #F4F8FC;\n    border: 1px solid #E8EEF5;\n    border-radius: 8px;\n    margin-bottom: 6px;\n}\n\n.tm-topic-info {\n    display: flex;\n    flex-direction: column;\n}\n\n.tm-topic-name {\n    font-size: calc(0.82rem * var(--dash-scale));\n    font-weight: 700;\n    color: #1E293B;\n}\n\n.tm-topic-date {\n    font-size: calc(0.68rem * var(--dash-scale));\n    font-weight: 600;\n    color: #475569;\n}\n\n.tm-topic-count {\n    font-size: calc(0.75rem * var(--dash-scale));\n    font-weight: 800;\n    background: #E8EEF5;\n    color: #1E293B;\n    padding: 3px 8px;\n    border-radius: 12px;\n}\n\n.tm-recent-loading, .tm-recent-empty, .tm-topics-empty {\n    color: #475569;\n    font-size: calc(0.82rem * var(--dash-scale));\n    padding: 12px 0;\n    text-align: center;\n}\n\n\/* Responsive *\/\n@media (max-width: 768px) {\n    .tm-stats-grid {\n        flex-wrap: wrap;\n    }\n    .tm-stat-box {\n        flex: 1 1 40%;\n    }\n}\n<\/style>\n\n<script>\n(function() {\n    const CONFIG = {\n        csvUrl: \"https:\/\/docs.google.com\/spreadsheets\/d\/1pGfdVy3yDtzS56FIxiP4KsHHYuKUqPWVG18ULv9wxi4\/export?format=csv&gid=588315623\"\n    };\n\n    let localLiveModifier = 0;\n    let baseDateCounts = {};\n    let recentSentencesList = [];\n    let topicsDataMap = {};\n    let targetValue = 10;\n\n    \/\/ --- i18n: automatische Spracherkennung anhand der Website-Sprache ---\n    const I18N = {\n        en: {\n            streak: \"STREAK\",\n            dailyGoal: \"DAILY GOAL\",\n            total: \"TOTAL\",\n            bestDay: \"BEST DAY\",\n            avgDay: \"AVG \/ DAY\",\n            inDanger: \"In Danger\",\n            activity7dTitle: \"Activity Last 7 Days\",\n            totalWord: \"Total\",\n            trend30dTitle: \"30-Day Trend & Target\",\n            recentTitle: \"Recently Practiced Sentences\",\n            topicsTitle: \"Topics Overview\",\n            loading: \"Loading sentence history...\",\n            noActivity: \"No complete activity recorded yet.\",\n            noTopics: \"No topics available\",\n            lastPracticed: \"Last practiced:\",\n            sentencesTotal: \"sentences (total)\",\n            grammarTopic: \"Grammar Topic\",\n            target: \"Target\",\n            today: \"Today\",\n            days: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"]\n        },\n        es: {\n            streak: \"RACHA\",\n            dailyGoal: \"META DIARIA\",\n            total: \"TOTAL\",\n            bestDay: \"MEJOR D\u00cdA\",\n            avgDay: \"PROM. \/ D\u00cdA\",\n            inDanger: \"En riesgo\",\n            activity7dTitle: \"Actividad de los \u00faltimos 7 d\u00edas\",\n            totalWord: \"Total\",\n            trend30dTitle: \"Tendencia de 30 d\u00edas y meta\",\n            recentTitle: \"Frases practicadas recientemente\",\n            topicsTitle: \"Resumen de temas\",\n            loading: \"Cargando historial de frases...\",\n            noActivity: \"A\u00fan no hay actividad registrada.\",\n            noTopics: \"No hay temas disponibles\",\n            lastPracticed: \"\u00daltima pr\u00e1ctica:\",\n            sentencesTotal: \"frases (total)\",\n            grammarTopic: \"Tema gramatical\",\n            target: \"Meta\",\n            today: \"Hoy\",\n            days: [\"dom\", \"lun\", \"mar\", \"mi\u00e9\", \"jue\", \"vie\", \"s\u00e1b\"]\n        }\n    };\n\n    function detectLang() {\n        const raw = (document.documentElement.lang || document.documentElement.getAttribute('lang') || navigator.language || 'en').toLowerCase();\n        return raw.startsWith('es') ? 'es' : 'en';\n    }\n\n    const T = I18N[detectLang()];\n\n    function applyStaticTranslations() {\n        const setText = (id, val) => { const el = document.getElementById(id); if (el) el.innerText = val; };\n        setText('tm-lbl-streak', T.streak);\n        setText('tm-lbl-goal', T.dailyGoal);\n        setText('tm-lbl-total', T.total);\n        setText('tm-lbl-best', T.bestDay);\n        setText('tm-lbl-avg', T.avgDay);\n        setText('tm-stat-danger-badge', T.inDanger);\n        setText('tm-lbl-7d-title', T.activity7dTitle);\n        setText('tm-lbl-total-word', T.totalWord);\n        setText('tm-lbl-30d-title', T.trend30dTitle);\n        setText('tm-lbl-recent-title', T.recentTitle);\n        setText('tm-lbl-topics-title', T.topicsTitle);\n        setText('tm-lbl-loading', T.loading);\n        setText('tm-lbl-no-topics', T.noTopics);\n    }\n\n    function parseCSVLine(text) {\n        let p = '', r = [], q = false;\n        for (let i = 0; text.length > i; i++) {\n            let c = text[i];\n            if (c === '\"') {\n                q = !q;\n            } else if (c === ',' && !q) {\n                r.push(p.trim().replace(\/^\"|\"$\/g, ''));\n                p = '';\n            } else if ((c === '\\r' || c === '\\n') && !q) {\n                continue;\n            } else {\n                p += c;\n            }\n        }\n        r.push(p.trim().replace(\/^\"|\"$\/g, ''));\n        return r;\n    }\n\n    function parseDateObj(dateStr) {\n        if (!dateStr) return null;\n        const parts = dateStr.trim().split(' ')[0].split(\/[\\.-]\/);\n        if (parts.length < 3) return null;\n        \n        if (parts[0].length === 4) {\n            return new Date(parts[0], parts[1] - 1, parts[2]);\n        } else {\n            return new Date(parts[2], parts[1] - 1, parts[0]);\n        }\n    }\n\n    function normalizeDate(dateStr) {\n        const d = parseDateObj(dateStr);\n        if (!d) return \"\";\n        return d.toLocaleDateString('en-US', { month: '2-digit', day: '2-digit', year: 'numeric' });\n    }\n\n    function calculateStreak() {\n        let streak = 0;\n        let d = new Date();\n\n        for (let i = 0; i < 365; i++) {\n            const dKey = d.toLocaleDateString('en-US', { month: '2-digit', day: '2-digit', year: 'numeric' });\n            const val = (baseDateCounts[dKey] || 0) + (i === 0 ? localLiveModifier : 0);\n\n            if (val >= targetValue) {\n                streak++;\n            } else {\n                if (i === 0) {\n                    d.setDate(d.getDate() - 1);\n                    continue;\n                }\n                break;\n            }\n            d.setDate(d.getDate() - 1);\n        }\n        return streak;\n    }\n\n    function calculatePeriodTotal(days) {\n        let total = 0;\n        for (let i = 0; i < days; i++) {\n            const d = new Date();\n            d.setDate(d.getDate() - i);\n            total += baseDateCounts[d.toLocaleDateString('en-US', { month: '2-digit', day: '2-digit', year: 'numeric' })] || 0;\n        }\n\n        return total;\n    }\n\n    function calculateDailyAverage() {\n        const dates = Object.keys(baseDateCounts);\n        if (dates.length === 0) return localLiveModifier > 0 ? (localLiveModifier).toFixed(1) : \"0.0\";\n\n        const totalSentences = Object.values(baseDateCounts).reduce((a, b) => a + b, 0) + localLiveModifier;\n        return (totalSentences \/ dates.length).toFixed(1);\n    }\n\n    function calculateBestDay() {\n        const values = Object.values(baseDateCounts);\n        if (values.length === 0) return localLiveModifier;\n        let max = Math.max(...values);\n        \n        const todayStr = new Date().toLocaleDateString('en-US', { month: '2-digit', day: '2-digit', year: 'numeric' });\n        const todayCount = (baseDateCounts[todayStr] || 0) + localLiveModifier;\n        \n        return Math.max(max, todayCount);\n    }\n\n    function render7DaysBarChart() {\n        const container = document.getElementById('tm-chart-7d');\n        if (!container) return;\n\n        container.innerHTML = '';\n        const dayNames = T.days;\n        let maxVal = targetValue;\n        const chartData = [];\n\n        for (let i = 6; i >= 0; i--) {\n            const d = new Date();\n            d.setDate(d.getDate() - i);\n            const dKey = d.toLocaleDateString('en-US', { month: '2-digit', day: '2-digit', year: 'numeric' });\n            const val = (baseDateCounts[dKey] || 0) + (i === 0 ? localLiveModifier : 0);\n\n            if (val > maxVal) maxVal = val;\n            const label = i === 0 ? T.today : dayNames[d.getDay()];\n\n            chartData.push({ label, val, isTarget: val >= targetValue });\n        }\n\n        chartData.forEach(item => {\n            const heightPercent = maxVal > 0 ? Math.round((item.val \/ maxVal) * 100) : 0;\n            const barCol = document.createElement('div');\n            barCol.className = 'tm-bar-col';\n            \n            barCol.innerHTML = `\n                <span class=\"tm-bar-val\">${item.val}\/${targetValue}<\/span>\n                <div class=\"tm-bar-track\">\n                    <div class=\"tm-bar-fill ${item.isTarget ? 'target-reached' : ''}\" style=\"height: ${heightPercent}%\"><\/div>\n                <\/div>\n                <span class=\"tm-bar-lbl\">${item.label}<\/span>\n            `;\n            container.appendChild(barCol);\n        });\n    }\n\n    \/\/ 30-Day Line Chart with a softer orange Target Line\n    function render30DaysLineChart() {\n        const container = document.getElementById('tm-chart-30d-wrap');\n        if (!container) return;\n\n        const chartData = [];\n        let maxVal = targetValue;\n\n        for (let i = 29; i >= 0; i--) {\n            const d = new Date();\n            d.setDate(d.getDate() - i);\n            const dKey = d.toLocaleDateString('en-US', { month: '2-digit', day: '2-digit', year: 'numeric' });\n            const val = (baseDateCounts[dKey] || 0) + (i === 0 ? localLiveModifier : 0);\n\n            if (val > maxVal) maxVal = val;\n            chartData.push({ dateStr: `${d.getMonth() + 1}\/${d.getDate()}`, val });\n        }\n\n        const width = 600;\n        const height = 130;\n        const padding = 20;\n\n        const points = chartData.map((item, idx) => {\n            const x = padding + (idx \/ (chartData.length - 1)) * (width - 2 * padding);\n            const y = height - padding - (item.val \/ maxVal) * (height - 2 * padding);\n            return { x, y, val: item.val, label: item.dateStr };\n        });\n\n        const targetY = height - padding - (targetValue \/ maxVal) * (height - 2 * padding);\n\n        const pathD = points.reduce((acc, p, i) => i === 0 ? `M ${p.x} ${p.y}` : `${acc} L ${p.x} ${p.y}`, '');\n        const areaD = `${pathD} L ${points[points.length - 1].x} ${height - padding} L ${points[0].x} ${height - padding} Z`;\n\n        container.innerHTML = `\n            <svg viewBox=\"0 0 ${width} ${height}\" preserveAspectRatio=\"none\">\n                <defs>\n                    <linearGradient id=\"tm-line-grad\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n                        <stop offset=\"0%\" stop-color=\"#475569\" stop-opacity=\"0.25\"\/>\n                        <stop offset=\"100%\" stop-color=\"#F4F8FC\" stop-opacity=\"0.0\"\/>\n                    <\/linearGradient>\n                <\/defs>\n                \n                <!-- Target Line -->\n                <line x1=\"${padding}\" y1=\"${targetY}\" x2=\"${width - padding}\" y2=\"${targetY}\" \n                      stroke=\"#1E293B\" stroke-width=\"1.5\" stroke-dasharray=\"3,3\" opacity=\"0.85\"\/>\n                <text x=\"${width - padding - 2}\" y=\"${targetY - 4}\" fill=\"#1E293B\" font-size=\"10\" font-weight=\"700\" text-anchor=\"end\">${T.target} (${targetValue})<\/text>\n\n                <path d=\"${areaD}\" fill=\"url(#tm-line-grad)\" \/>\n                <path d=\"${pathD}\" fill=\"none\" stroke=\"#475569\" stroke-width=\"2.5\" stroke-linejoin=\"round\"\/>\n            <\/svg>\n        `;\n    }\n\n    function updateDashboardUI() {\n        const streakEl = document.getElementById('tm-stat-streak');\n        const totalEl = document.getElementById('tm-stat-total');\n        const avgEl = document.getElementById('tm-stat-avg');\n        const bestEl = document.getElementById('tm-stat-best');\n        const targetEl = document.getElementById('tm-stat-target');\n        const sum7El = document.getElementById('tm-7d-sum');\n        const dangerBadgeEl = document.getElementById('tm-stat-danger-badge');\n\n        const sumTotal = Object.values(baseDateCounts).reduce((a, b) => a + b, 0) + localLiveModifier;\n        const sum7Days = calculatePeriodTotal(7) + localLiveModifier;\n\n        const todayStr = new Date().toLocaleDateString('en-US', { month: '2-digit', day: '2-digit', year: 'numeric' });\n        const todayCount = (baseDateCounts[todayStr] || 0) + localLiveModifier;\n\n        \/\/ \"In Danger\" nur anzeigen, wenn das heutige Ziel noch NICHT erreicht wurde\n        if (dangerBadgeEl) {\n            if (targetValue > todayCount) {\n                dangerBadgeEl.style.display = 'inline-block';\n            } else {\n                dangerBadgeEl.style.display = 'none';\n            }\n        }\n\n        if (streakEl) streakEl.innerText = calculateStreak();\n        if (totalEl) totalEl.innerText = sumTotal;\n        if (avgEl) avgEl.innerText = calculateDailyAverage();\n        if (bestEl) bestEl.innerText = calculateBestDay();\n        if (targetEl) targetEl.innerText = targetValue;\n        if (sum7El) sum7El.innerText = sum7Days;\n\n        render7DaysBarChart();\n        render30DaysLineChart();\n        renderRecentSentences();\n        renderTopics();\n    }\n\n    function renderRecentSentences() {\n        const listEl = document.getElementById('tm-recent-sentences');\n        if (!listEl) return;\n\n        listEl.innerHTML = '';\n\n        if (recentSentencesList.length === 0) {\n            listEl.innerHTML = `<div class=\"tm-recent-empty\">${T.noActivity}<\/div>`;\n            return;\n        }\n\n        recentSentencesList.slice(0, 20).forEach(item => {\n            const card = document.createElement('div');\n            card.className = 'tm-sentence-card';\n            \n            const levelTag = `<span class=\"tm-tag tm-tag-level\">${item.level}<\/span>`;\n            const topicTag = `<span class=\"tm-tag tm-tag-topic\">${T.grammarTopic} ${item.topic}<\/span>`;\n\n            card.innerHTML = `\n                <div class=\"tm-tags-row\">${levelTag}${topicTag}<\/div>\n                <div class=\"tm-sentence-de\">\ud83c\udde9\ud83c\uddea ${item.de}<\/div>\n                <div class=\"tm-sentence-en\">\ud83d\udde3\ufe0f ${item.en}<\/div>\n            `;\n            listEl.appendChild(card);\n        });\n    }\n\n    function renderTopics() {\n        const listEl = document.getElementById('tm-topics-list');\n        if (!listEl) return;\n\n        const topicEntries = Object.entries(topicsDataMap);\n        if (topicEntries.length === 0) {\n            listEl.innerHTML = `<div class=\"tm-topics-empty\">${T.noTopics}<\/div>`;\n            return;\n        }\n\n        topicEntries.sort((a, b) => {\n            const dateA = parseDateObj(a[1].dateStr) || new Date(0);\n            const dateB = parseDateObj(b[1].dateStr) || new Date(0);\n            return dateB - dateA;\n        });\n\n        listEl.innerHTML = '';\n        topicEntries.forEach(([topicName, data]) => {\n            const row = document.createElement('div');\n            row.className = 'tm-topic-row';\n            row.innerHTML = `\n                <div class=\"tm-topic-info\">\n                    <span class=\"tm-topic-name\">${T.grammarTopic} ${topicName}<\/span>\n                    <span class=\"tm-topic-date\">${T.lastPracticed} ${data.displayDate}<\/span>\n                <\/div>\n                <span class=\"tm-topic-count\">${data.count} ${T.sentencesTotal}<\/span>\n            `;\n            listEl.appendChild(row);\n        });\n    }\n\n    async function fetchCSVData() {\n        if (!window.wpTrainerUserInfo) return;\n\n        const userName = String(window.wpTrainerUserInfo.name || \"\").trim().toLowerCase();\n        const userId = String(window.wpTrainerUserInfo.id || \"\").trim().toLowerCase();\n\n        try {\n            const response = await fetch(`${CONFIG.csvUrl}&_cb=${new Date().getTime()}`);\n            const csvText = await response.text();\n            const lines = csvText.split(\/\\r?\\n\/);\n\n            baseDateCounts = {};\n            recentSentencesList = [];\n            topicsDataMap = {};\n            let targetFound = null;\n\n            for (let i = 1; lines.length > i; i++) {\n                if (!lines[i].trim()) continue;\n\n                const cols = parseCSVLine(lines[i]);\n                if (!(cols.length >= 3)) continue;\n\n                const rowDateRaw = cols[0]?.trim();\n                const rowUserId = cols[1]?.trim().toLowerCase();\n                const rowName = cols[2]?.trim().toLowerCase();\n\n                const rowTargetCol11 = cols[10]?.trim();\n                const rowTargetCol4 = cols[3]?.trim();\n                const rowTarget = rowTargetCol11 || rowTargetCol4;\n\n                const level = cols[4]?.trim();\n                const topic = cols[5]?.trim();\n                const textDE = cols[6]?.trim();\n                const textEN = cols[7]?.trim();\n\n                const rowDate = normalizeDate(rowDateRaw);\n                const isMatch = (rowUserId && rowUserId === userId) || (rowName && rowName === userName);\n\n                if (isMatch) {\n                    baseDateCounts[rowDate] = (baseDateCounts[rowDate] || 0) + 1;\n\n                    if (rowTarget && !isNaN(parseInt(rowTarget, 10))) {\n                        targetFound = parseInt(rowTarget, 10);\n                    }\n\n                    if (rowDateRaw && level && topic && textDE && textEN) {\n                        recentSentencesList.unshift({\n                            date: rowDateRaw,\n                            level: level,\n                            topic: topic,\n                            de: textDE,\n                            en: textEN\n                        });\n\n                        if (\/^\\d+$\/.test(topic)) {\n                            if (!topicsDataMap[topic]) {\n                                topicsDataMap[topic] = {\n                                    count: 0,\n                                    dateStr: rowDateRaw,\n                                    displayDate: rowDate || rowDateRaw\n                                };\n                            }\n                            \n                            topicsDataMap[topic].count += 1;\n\n                            const currentDateObj = parseDateObj(rowDateRaw);\n                            const existingDateObj = parseDateObj(topicsDataMap[topic].dateStr);\n                            if (!existingDateObj || (currentDateObj && currentDateObj > existingDateObj)) {\n                                topicsDataMap[topic].dateStr = rowDateRaw;\n                                topicsDataMap[topic].displayDate = rowDate || rowDateRaw;\n                            }\n                        }\n                    }\n                }\n            }\n\n            if (targetFound) {\n                targetValue = targetFound;\n            }\n\n            updateDashboardUI();\n        } catch (err) {\n            console.error(\"Error loading CSV data:\", err);\n            updateDashboardUI();\n        }\n    }\n\n    function setupEventListeners() {\n        window.addEventListener('tm-satz-bestaetigt', function(e) {\n            localLiveModifier++;\n            \n            const level = e.detail && e.detail.level ? e.detail.level : \"\";\n            const topic = e.detail && e.detail.topic ? String(e.detail.topic).trim() : \"\";\n            const deText = e.detail && e.detail.de ? e.detail.de : \"\";\n            const enText = e.detail && e.detail.en ? e.detail.en : \"\";\n            const todayStr = new Date().toLocaleDateString('en-US', { month: '2-digit', day: '2-digit', year: 'numeric' });\n\n            if (level && topic && deText && enText) {\n                recentSentencesList.unshift({\n                    date: todayStr,\n                    level: level,\n                    topic: topic,\n                    de: deText,\n                    en: enText\n                });\n\n                if (\/^\\d+$\/.test(topic)) {\n                    if (!topicsDataMap[topic]) {\n                        topicsDataMap[topic] = { count: 0, dateStr: todayStr, displayDate: todayStr };\n                    }\n                    topicsDataMap[topic].count += 1;\n                    topicsDataMap[topic].dateStr = todayStr;\n                    topicsDataMap[topic].displayDate = todayStr;\n                }\n            }\n\n            updateDashboardUI();\n        });\n\n        window.addEventListener('tm-user-switched', function() {\n            localLiveModifier = 0;\n            fetchCSVData();\n        });\n    }\n\n    function init() {\n        applyStaticTranslations();\n        if (!window.wpTrainerUserInfo) {\n            setTimeout(init, 300);\n            return;\n        }\n        setupEventListeners();\n        fetchCSVData();\n    }\n\n    if (document.readyState === 'loading') {\n        document.addEventListener('DOMContentLoaded', init);\n    } else {\n        init();\n    }\n})();\n<\/script>\n<div class=\"spx-role\" data-role=\"free\"><div class=\"lock\"><div class=\"lk\">\ud83d\udd12<\/div><h3>This area is for paying members only<\/h3><p>Upgrade to Plus to unlock your statistics dashboard.<\/p><a class=\"btn b-teal\" href=\"https:\/\/sofapiano.com\/membership-join\/\">More Info!<\/a><\/div><\/div>\n<\/div>\n\n<div class=\"dash-p p9\">\n<style id=\"account-design\">\n\/* Account & membership \u2013 an aktuelles Dashboard-Design angepasst, volle Breite *\/\n.dash .p9 .login-card-container{max-width:none!important;padding:22px 24px!important;background:#fff!important;border:1px solid #E7E2D8!important;border-radius:22px!important;box-shadow:0 10px 26px rgba(29,36,39,.04)!important;font-family:'Inter','Segoe UI',Roboto,sans-serif!important;color:#1D2427!important}\n.dash .p9 .login-header{margin-bottom:16px!important}\n.dash .p9 .login-title{gap:10px!important;font-family:'Fraunces',Georgia,serif!important;font-size:22px!important;font-weight:600!important;letter-spacing:0!important;text-transform:none!important;color:#1D2427!important}\n.dash .p9 .login-title svg{color:#14708C!important}\n.dash .p9 .swpm-login-widget-logged{display:grid!important;grid-template-columns:repeat(2,minmax(0,1fr))!important;gap:10px!important}\n.dash .p9 .swpm-logged-username,.dash .p9 .swpm-logged-status,.dash .p9 .swpm-logged-membership,.dash .p9 .swpm-logged-expiry{margin:0!important;padding:12px 14px!important;background:#F7FAFB!important;border:1px solid #E5EEF1!important;border-radius:14px!important}\n.dash .p9 .swpm-logged-label{display:block!important;margin:0 0 4px!important;font-size:11px!important;font-weight:700!important;letter-spacing:.08em!important;text-transform:uppercase!important;color:#4B565A!important}\n.dash .p9 .swpm-logged-value{font-size:15px!important;font-weight:700!important;color:#1D2427!important}\n.dash .p9 .swpm-edit-profile-link,.dash .p9 .swpm-logged-logout-link{margin:6px 0 0!important}\n.dash .p9 .swpm-edit-profile-link a,.dash .p9 .swpm-logged-logout-link a{display:flex!important;align-items:center!important;justify-content:center!important;min-height:46px!important;padding:0 20px!important;border-radius:999px!important;font:700 14px\/1 'Inter',sans-serif!important;text-decoration:none!important;transition:background .15s,border-color .15s,color .15s!important}\n.dash .p9 .swpm-edit-profile-link a{background:#14708C!important;color:#fff!important;border:1.5px solid #14708C!important}\n.dash .p9 .swpm-edit-profile-link a:hover{background:#0E5367!important;border-color:#0E5367!important}\n.dash .p9 .swpm-logged-logout-link a{background:#fff!important;color:#1D2427!important;border:1.5px solid #E7E2D8!important}\n.dash .p9 .swpm-logged-logout-link a:hover{border-color:#14708C!important;color:#14708C!important}\n.dash .p9 .acc-extra{max-width:none!important;margin:16px 0 0!important}\n.dash .p9 .howto{max-width:none!important;margin:0!important;padding:2px 24px!important;background:#fff!important;border:1px solid #E7E2D8!important;border-radius:22px!important;box-shadow:0 10px 26px rgba(29,36,39,.04)!important}\n.dash .p9 .howto summary{padding:18px 0!important;font-size:15.5px!important;color:#1D2427!important}\n.dash .p9 .howto summary::before{background:#E2F0F4!important;color:#0E5367!important}\n.dash .p9 .howto summary::after{color:#14708C!important}\n.dash .p9 .howto .a{padding:0 0 22px!important}\n.dash .p9 .plans{max-width:440px!important}\n.dash .p9 .plan.hot{max-width:none!important;padding:26px!important;background:#fff!important;color:#1D2427!important;border:1px solid #E7E2D8!important;border-radius:20px!important;box-shadow:0 10px 26px rgba(29,36,39,.05)!important}\n.dash .p9 .plan.hot .pname{color:#1D2427!important}\n.dash .p9 .plan.hot .price{color:#14708C!important}\n.dash .p9 .plan.hot .note{color:#4B565A!important}\n.dash .p9 .plan.hot ul.feat{border-top-color:#ECE8E0!important}\n.dash .p9 .plan.hot ul.feat li{color:#1D2427!important;font-size:14.5px!important}\n.dash .p9 .plan.hot ul.feat li::before{background:#E2F0F4!important;color:#14708C!important}\n.dash .p9 .contact{margin-top:18px!important}\n@media (max-width:600px){.dash .p9 .swpm-login-widget-logged{grid-template-columns:1fr!important}.dash .p9 .login-card-container{padding:18px!important}.dash .p9 .howto{padding:2px 16px!important}}\n<\/style>\n<div class=\"trainer-dashboard-standalone login-card-container\">\n    <style>\n        .login-card-container {\n            max-width: 640px;\n            width: 100%;\n            margin: 0 auto !important;\n            font-family: 'Inter', sans-serif;\n            background: #ffffff;\n            border-radius: 24px;\n            padding: 20px;\n            box-shadow: 0 10px 30px rgba(14,26,32,0.08);\n            border: 1px solid #f0f2f5;\n            box-sizing: border-box;\n        }\n\n        .login-header {\n            display: flex;\n            align-items: center;\n            margin-bottom: 18px;\n            gap: 10px;\n        }\n\n        .login-title {\n            font-weight: 500;\n            font-size: 25px;\n            color: #1E293B;\n            text-transform: uppercase;\n            letter-spacing: 1px;\n            display: flex;\n            align-items: center;\n            gap: 15px;\n        }\n\n        \/* Labels *\/\n        .login-card-container label {\n            display: block;\n            font-size: 15px;\n            font-weight: 300;\n            color: #1E293B;\n            margin-bottom: 7px;\n            text-transform: uppercase;\n        }\n\n        \/* Eingabefelder *\/\n        .login-card-container input[type=\"text\"],\n        .login-card-container input[type=\"password\"] {\n            width: 100%;\n            background: #f8fafb;\n            border: 2px solid transparent;\n            border-radius: 14px;\n            padding: 13px 15px;\n            font-family: 'Inter', sans-serif;\n            font-size: 14px;\n            margin-bottom: 16px;\n            box-sizing: border-box;\n            transition: all 0.2s ease;\n        }\n\n        \/* Checkbox + Passwort vergessen *\/\n        .swpm-remember-me-section, \n        .swpm-before-login-form-section {\n            display: flex !important;\n            flex-direction: row !important;\n            align-items: center !important;\n            justify-content: flex-start !important;\n            gap: 15px;\n            margin-top: 2px;\n            margin-bottom: 18px;\n            font-size: 12px;\n        }\n\n        \/* Label neben Checkbox *\/\n        .swpm-remember-me-section label {\n            display: inline-flex !important;\n            align-items: center !important;\n            margin-bottom: 0 !important;\n            text-transform: none !important;\n            font-weight: 400;\n            color: #64748b;\n            cursor: pointer;\n            gap: 6px;\n        }\n\n        \/* Passwort vergessen *\/\n        .swpm-login-forgot-pass {\n            margin-left: auto;\n            margin-bottom: 0 !important;\n        }\n\n        .swpm-login-forgot-pass a {\n            color: #64748b;\n            text-decoration: none;\n            font-weight: 700;\n        }\n\n        \/* Login Button *\/\n        .login-card-container input[type=\"submit\"] {\n            width: 100%;\n            background: #14708C;\n            color: white;\n            border: none;\n            padding: 15px;\n            border-radius: 16px;\n            font-weight: 800;\n            font-size: 14px;\n            text-transform: uppercase;\n            cursor: pointer;\n            box-shadow: 0 4px 12px rgba(20, 112, 140, 0.25);\n        }\n\n        \/* Plugin-Text entfernen *\/\n        .swpm-login-action-msg {\n            display: none !important;\n        }\n    <\/style>\n\n    <div class=\"login-header\">\n        <div class=\"login-title\">\n            <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n                <path d=\"M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4\"><\/path>\n                <polyline points=\"10 17 15 12 10 7\"><\/polyline>\n                <line x1=\"15\" y1=\"12\" x2=\"3\" y2=\"12\"><\/line>\n            <\/svg>\n            Account\n        <\/div>\n    <\/div>\n\n    <div class=\"login-form-wrapper\">\n        <div class=\"swpm-login-widget-form\">\n    <form id=\"swpm-login-form\" name=\"swpm-login-form\" method=\"post\" action=\"\">\n        <input type=\"hidden\" name=\"swpm_login_origination_flag\" value=\"1\" \/>\n        <div class=\"swpm-login-form-inner\">\n            <div class=\"swpm-username-label\">\n                <label for=\"swpm_user_name\" class=\"swpm-label\">Nombre de usuario o correo electr\u00f3nico<\/label>\n            <\/div>\n            <div class=\"swpm-username-input\">\n                <input type=\"text\" class=\"swpm-text-field swpm-username-field\" id=\"swpm_user_name\" value=\"\" size=\"25\" name=\"swpm_user_name\" \/>\n            <\/div>\n            <div class=\"swpm-password-label\">\n                <label for=\"swpm_password\" class=\"swpm-label\">Contrase\u00f1a<\/label>\n            <\/div>\n            <div class=\"swpm-password-input\">                \n                <input type=\"password\" class=\"swpm-text-field swpm-password-field\" id=\"swpm_password\" value=\"\" size=\"25\" name=\"swpm_password\" \/>                \n            <\/div>\n                        <div class=\"swpm-remember-me\">\n                <span class=\"swpm-remember-checkbox\"><input type=\"checkbox\" name=\"rememberme\" id=\"swpm-rememberme\"><\/span>\n                <label for=\"swpm-rememberme\" class=\"swpm-rememberme-label\">\n                    <span class=\"swpm-rember-label\"> Recu\u00e9rdame<\/span>\n                <\/label>\n            <\/div>\n\n            <div class=\"swpm-before-login-submit-section\"><div class=\"swpm-recaptcha-section\" style=\"margin-bottom: 15px;\"><style type=\"text\/css\">@media screen and (max-width: 375px) {\n            .swpm_g_captcha{transform:scale(0.77);transform-origin:0;-webkit-transform:scale(0.77);-webkit-transform-origin:0 0;}\n        }<\/style><script src=\"https:\/\/www.google.com\/recaptcha\/api.js\" async defer><\/script><div class=\"swpm_g_captcha\"><div class=\"g-recaptcha\" data-sitekey=\"6Lc2pqstAAAAAIx14fGoEgptXyxJGNeaNFUgDEhZ\" data-theme=\"light\" data-size=\"normal\"><\/div><\/div><\/div><\/div>\n\n            <div class=\"swpm-login-submit\">\n                <input type=\"submit\" class=\"swpm-login-form-submit\" name=\"swpm-login\" value=\"Acceder\"\/>\n            <\/div>\n            <div class=\"swpm-forgot-pass-link\">\n                <a id=\"forgot_pass\" class=\"swpm-login-form-pw-reset-link\"  href=\"https:\/\/sofapiano.com\/membership-login\/password-reset\/\">\u00bfHas olvidado tu contrase\u00f1a?<\/a>\n            <\/div>\n                        <div class=\"swpm-join-us-link\">\n                <a id=\"register\" class=\"swpm-login-form-register-link\" href=\"https:\/\/sofapiano.com\/membership-join\/\">\u00danete a nosotros<\/a>\n            <\/div>\n                        <div class=\"swpm-login-action-msg\">\n                <span class=\"swpm-login-widget-action-msg\"><\/span>\n            <\/div>\n        <\/div>\n    <\/form>\n\n    <\/div>\n\n    <\/div>\n<\/div>\n<div id=\"tm-mirror-slot\" class=\"tm-mirror-slot\"><\/div>\n<div class=\"spx acc-extra\">\n<details class=\"howto\"><summary>Click to Upgrade or Renew Membership here<\/summary><div class=\"a\">\n<div class=\"plans\"><div class=\"plan hot\">\n<p class=\"pname\">Plus<\/p>\n<p class=\"price\">4,00 \u20ac \/ month*<\/p>\n<div class=\"buy spx-role\" data-role=\"free\">\n\n\n<div class=\"swpm-payment-button\">    <div id=\"swpm-button-wrapper-15924\" class=\"swpm-button-wrapper swpm-paypal-subscription-button-wrapper\">\n\n    <!-- PayPal button container where the button will be rendered -->\n    <div id=\"swpm_paypal_button_0\" style=\"width: 200px;\"><\/div>\n    <!-- Some additiona hidden input fields -->\n    <input type=\"hidden\" id=\"swpm_paypal_button_0-custom-field\" name=\"custom\" value=\"subsc_ref=3&amp;user_ip=216.73.217.32\">\n\n    <script type=\"text\/javascript\">\n        document.addEventListener( \"swpm_paypal_sdk_subscriptions_loaded\", function() { \n            \/\/Anything that goes here will only be executed after the PayPal SDK is loaded.\n\n            const paypalSubButtonsComponent = swpm_paypal_subscriptions.Buttons({\n                \/\/ optional styling for buttons\n                \/\/ https:\/\/developer.paypal.com\/docs\/checkout\/standard\/customize\/buttons-style-guide\/\n                style: {\n                    color: 'blue',\n                    shape: 'pill',\n                    height: 35,\n                    label: 'checkout',\n                    layout: 'vertical',\n                },\n    \n                \/\/ Handle the createSubscription call\n                createSubscription: async function(data, actions) {\n                    \/\/ console.log('createSubscription call triggered. Data: ' + JSON.stringify(data));\n\n                    \/\/We will send ajax request that will create the subscription from the server side using PayPal API.\n                    let pp_sub_bn_data = {};\n                    pp_sub_bn_data.button_id = '15924';\n                    pp_sub_bn_data.on_page_button_id = 'swpm_paypal_button_0';\n                    pp_sub_bn_data.item_name = 'Paypal Subscription';\n                    let post_data = 'action=swpm_pp_create_subscription&data=' + JSON.stringify(pp_sub_bn_data) + '&_wpnonce=87be23c65a';\n                    try {\n                        \/\/ Using fetch for AJAX request. This is supported in all modern browsers.\n                        const response = await fetch(\"https:\/\/sofapiano.com\/wp-admin\/admin-ajax.php\", {\n                            method: \"post\",\n                            headers: {\n                                'Content-Type': 'application\/x-www-form-urlencoded'\n                            },\n                            body: post_data\n                        });\n\n                        const response_data = await response.json();\n\n                        if (response_data.subscription_id) {\n                            console.log('Create-subscription API call to PayPal completed successfully.');\n                            \/\/If we need to see the details, uncomment the following line.\n                            \/\/console.log('Order data: ' + JSON.stringify(response_data.sub_data));\n\n                            \/\/Return the subscription ID.\n                            return response_data.subscription_id;\n                        } else {\n                            const error_message = JSON.stringify(response_data);\n                            console.error('Error occurred during the create-subscription API call to PayPal. ' + error_message);\n                            throw new Error(error_message);\n                        }\n                    } catch (error) {\n                        console.error(error);\n                        alert('Could not initiate PayPal subscription...\\n\\n' + JSON.stringify(error));\n                    }\n                },\n    \n                \/\/ Notify the buyer that the subscription is successful\n                onApprove: function(data, actions) {\n                    console.log('Successfully created a subscription.');\n                    \/\/console.log(JSON.stringify(data));\n\n                    \/\/Show the spinner while we process this transaction.\n                    const pp_button_container = document.getElementById('swpm_paypal_button_0');\n                    const pp_button_container_wrapper = document.getElementById('swpm-button-wrapper-15924');\n                    const pp_button_spinner_container = pp_button_container_wrapper.querySelector('.swpm-pp-button-spinner-container');\n                    pp_button_container.style.display = 'none'; \/\/Hide the buttons\n                    pp_button_spinner_container.style.display = 'inline-block'; \/\/Show the spinner.\n\n                    \/\/Get the subscription details and send AJAX request to process the transaction.\n                    actions.subscription.get().then( async function( txn_data ) {\n                        \/\/console.log( 'Subscription details: ' + JSON.stringify( txn_data ) );\n\n                        \/\/Ajax request to process the transaction. This will process it similar to how an IPN request is handled.\n                        const custom = document.getElementById('swpm_paypal_button_0-custom-field').value;\n                        data.custom_field = custom;\n                        data.button_id = '15924';\n                        data.on_page_button_id = 'swpm_paypal_button_0';\n                        data.item_name = 'Paypal Subscription';\n\n                        const post_data = new URLSearchParams({\n                            action: 'swpm_onapprove_process_subscription',\n                            data: JSON.stringify(data),\n                            txn_data: JSON.stringify(txn_data),\n                            _wpnonce: '87be23c65a',\n                        }).toString();\n\n                        try {\n                            const requestUrl = \"https:\/\/sofapiano.com\/wp-admin\/admin-ajax.php\";\n                            const resp = await fetch( requestUrl, {\n                                method: \"post\",\n                                headers: {\n                                    'Content-Type': 'application\/x-www-form-urlencoded'\n                                },\n                                body: post_data\n                            });\n\n                            const response = await resp.json();\n\n                            \/\/console.log( 'Response from the server: ' + JSON.stringify( response ) );\n                            if ( response.success ) {\n\n                                \/\/Redirect to the Thank you page or Registration page URL if it is set.\n                                const return_url = response.redirect_url || '';\n                                if( return_url ){\n                                    \/\/redirect to the URL.\n                                    console.log('Redirecting to the Thank you page URL: ' + return_url);\n                                    window.location.href = return_url;\n                                    return;\n                                }\n\n                                \/\/No return URL is set. Just show a success message.\n                                \/\/Important Note: any alert message will block the normal PayPal popup window flow. So we want to show the message on the page instead of using alert.\n                                txn_success_msg = '\u00a1Transacci\u00f3n completada correctamente!';\n                                const swpm_btn_wrapper_div = document.getElementById('swpm-button-wrapper-15924');\n                                if (swpm_btn_wrapper_div) {\n                                    \/\/ Remove any previous message if it exists\n                                    const old_msg_div = swpm_btn_wrapper_div.querySelector('.swpm-ppcp-txn-success-message');\n                                    if (old_msg_div) old_msg_div.remove();\n\n                                    \/\/ Create new message div\n                                    const new_msg_div = document.createElement('div');\n                                    new_msg_div.className = 'swpm-ppcp-txn-success-message';\n                                    new_msg_div.textContent = txn_success_msg;\n\n                                    \/\/Insert the message div before the button.\n                                    const firstChild = swpm_btn_wrapper_div.firstChild;\n                                    swpm_btn_wrapper_div.insertBefore(new_msg_div, firstChild);\n                                }\n\n                                \/\/ Trigger a event on subscription complete \n                                document.dispatchEvent(new Event('swpm_paypal_subscriptions_complete'));\n                        \n                            } else {\n                                \/\/Error response from the AJAX IPN hanler. Throw error.\n                                throw new Error(response.err_msg);\n                            }\n\n                            \/\/Return the button and the spinner back to their orignal display state.\n                            pp_button_container.style.display = 'block'; \/\/ Show the buttons\n                            pp_button_spinner_container.style.display = 'none'; \/\/ Hide the spinner\n\n                        } catch (error) {\n                            \/\/ Show the error message.\n                            alert(error.message);\n                            console.error( error.message );\n                        }\n                    });\n                },\n    \n                \/\/ handle unrecoverable errors\n                onError: function(err) {\n                    console.error('An error prevented the user from checking out with PayPal. ' + JSON.stringify(err));\n                    alert( 'Ha ocurrido un error durante el proceso de pago de PayPal.\\n\\n' + JSON.stringify(err) );\n                }\n            });\n    \n            paypalSubButtonsComponent\n                .render('#swpm_paypal_button_0')\n                .catch((err) => {\n                    console.error('PayPal Buttons failed to render');\n                });\n        });\n    <\/script>\n    <style>\n        @keyframes swpm-pp-button-spinner {\n            to {transform: rotate(360deg);}\n        }\n        .swpm-pp-button-spinner {\n            margin: 0 auto;\n            text-indent: -9999px;\n            vertical-align: middle;\n            box-sizing: border-box;\n            position: relative;\n            width: 60px;\n            height: 60px;\n            border-radius: 50%;\n            border: 5px solid #ccc;\n            border-top-color: #0070ba;\n            animation: swpm-pp-button-spinner .6s linear infinite;\n        }\n        .swpm-pp-button-spinner-container {\n            width: 100%;\n            text-align: center;\n            margin-top:10px;\n            display: none;\n        }\n    <\/style>\n    <div class=\"swpm-pp-button-spinner-container\">\n        <div class=\"swpm-pp-button-spinner\"><\/div>\n    <\/div>\n    <\/div><!-- end of .swpm-button-wrapper -->\n    <\/div>\n\n\n\n<\/div>\n<div class=\"spx-role\" data-role=\"paid\"><span class=\"btn b-sun\" style=\"width:100%\">You are a member \ud83d\ude0a<\/span><\/div>\n<p class=\"note\">* Cancel anytime.<\/p>\n<ul class=\"feat\"><li>Everything in Free<\/li><li>All 80+ grammar topics and the grammar quick guide<\/li><li>Save sentences and add your own<\/li><li>Statistics dashboard and grammar tracker<\/li><li>Saved test results to track your progress<\/li><li>A new handwriting workbook every month<\/li><\/ul>\n<\/div><\/div>\n<\/div><\/details>\n<p class=\"contact\"><a class=\"btn b-ghost\" href=\"https:\/\/sofapiano.com\/contact\/\">Contact us<\/a><\/p>\n<\/div>\n<\/div>\n\n<\/div>\n<\/div><\/div>\n<\/div>\n\n\n\n<span hidden data-spx-mark=\"foot-start\"><\/span>\n<style>\n\/* ===== Footer: Petrol, klar gegliedert in vier Spalten ===== *\/\nhtml,body{background:#FBF8F2}\n.spx-foot.f2{background:#0F5C73;color:#E6F3F7;margin:0!important;padding:0;line-height:1.5}\n.spx-foot.f2 *{box-sizing:border-box}\n.spx-foot.f2 .f2-in{max-width:1168px;margin:0 auto;padding:44px 24px 0}\n.spx-foot.f2 .f2-top{display:grid;grid-template-columns:minmax(0,1fr) repeat(3,140px);gap:32px 40px;padding-bottom:34px}\n.spx-foot.f2 .f2-logo{display:inline-flex;align-items:center;gap:20px;font-family:'Fraunces',Georgia,serif;font-size:22px;font-weight:600;letter-spacing:-.3px;line-height:1;color:#fff;text-decoration:none}\n.spx-foot.f2 .f2-logo:hover{color:#fff;text-decoration:none}\n.spx-foot.f2 .f2-logo .logo-dot{display:block;width:12px;height:12px;border-radius:50%;background:#FFCF33;box-shadow:8px 0 0 #6EC1E4}\n.spx-foot.f2 .f2-claim{margin:14px 0 18px;max-width:300px;font-size:14px;color:#CFE6EE}\n.spx-foot.f2 .f2-claim em{font-family:'Fraunces',Georgia,serif;font-style:italic;color:#FFCF33}\n.spx-foot.f2 .f2-cta{display:inline-flex;align-items:center;min-height:44px;padding:0 20px;border-radius:999px;background:#FFCF33;color:#0E1A20;font-size:14px;font-weight:700;text-decoration:none}\n.spx-foot.f2 .f2-cta:hover{background:#FFD94F;color:#0E1A20;text-decoration:none}\n.spx-foot.f2 .f2-h{margin:0 0 12px;font-size:11px;font-weight:800;letter-spacing:1.3px;text-transform:uppercase;color:#9FD3E6}\n.spx-foot.f2 ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:8px}\n.spx-foot.f2 li{margin:0}\n.spx-foot.f2 .f2-top a.f2-l{font-size:14.5px;font-weight:500;color:#fff;text-decoration:none}\n.spx-foot.f2 .f2-top a.f2-l:hover{color:#FFCF33;text-decoration:none}\n.spx-foot.f2 .f2-bot{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px 24px;padding:16px 0 20px;border-top:1px solid rgba(255,255,255,.16);font-size:12.5px;color:#B5D6E1}\n.spx-foot.f2 .f2-legal{display:flex;flex-wrap:wrap;gap:4px 18px}\n.spx-foot.f2 .f2-legal a{font-size:12.5px;color:#B5D6E1;text-decoration:none}\n.spx-foot.f2 .f2-legal a:hover{color:#fff;text-decoration:none}\n.spx-foot.f2 a:focus-visible{outline:2px solid #fff;outline-offset:2px;border-radius:6px}\n@media (max-width:900px){\n .spx-foot.f2 .f2-top{grid-template-columns:repeat(3,minmax(0,1fr))}\n .spx-foot.f2 .f2-brand{grid-column:1 \/ -1}\n .spx-foot.f2 .f2-top{gap:32px 40px}\n .spx-foot.f2 .f2-claim{max-width:340px}\n}\n@media (max-width:560px){\n .spx-foot.f2 .f2-in{padding:32px 20px 0}\n .spx-foot.f2 .f2-top{grid-template-columns:repeat(2,minmax(0,1fr));gap:26px 20px}\n}\n<\/style>\n<footer class=\"spx-foot f2\">\n <div class=\"f2-in\">\n  <div class=\"f2-top\">\n   <div class=\"f2-brand\">\n    <a class=\"f2-logo\" href=\"https:\/\/sofapiano.com\/\"><span class=\"logo-dot\" aria-hidden=\"true\"><\/span>sofapiano<\/a>\n    <p class=\"f2-claim\">Learn German <em>through translation<\/em> \u2014 with real sentences native speakers use every day.<\/p>\n    <a class=\"f2-cta\" href=\"https:\/\/sofapiano.com\/exercises\/\">Start practising free<\/a>\n   <\/div>\n   <nav aria-label=\"Practise\">\n    <p class=\"f2-h\">Practise<\/p>\n    <ul>\n     <li><a class=\"f2-l\" href=\"https:\/\/sofapiano.com\/exercises\/\">Exercises<\/a><\/li>\n     <li><a class=\"f2-l\" href=\"https:\/\/sofapiano.com\/level-test\/\">Level test<\/a><\/li>\n     <li><a class=\"f2-l\" href=\"https:\/\/sofapiano.com\/quiz\/\">Quiz<\/a><\/li>\n    <\/ul>\n   <\/nav>\n   <nav aria-label=\"Tools\">\n    <p class=\"f2-h\">Tools<\/p>\n    <ul>\n     <li><a class=\"f2-l\" href=\"https:\/\/sofapiano.com\/learning-tools\/\">Learning tools<\/a><\/li>\n     <li><a class=\"f2-l\" href=\"https:\/\/sofapiano.com\/workbook\/\">Workbook<\/a><\/li>\n     <li><a class=\"f2-l\" href=\"https:\/\/sofapiano.com\/blog\/\">Blog<\/a><\/li>\n    <\/ul>\n   <\/nav>\n   <nav aria-label=\"sofapiano\">\n    <p class=\"f2-h\">sofapiano<\/p>\n    <ul>\n     <li><a class=\"f2-l\" href=\"https:\/\/sofapiano.com\/the-sofapiano-story\/\">Our story<\/a><\/li>\n     <li><a class=\"f2-l\" href=\"https:\/\/sofapiano.com\/membership-join\/\">Membership<\/a><\/li>\n     <li><a class=\"f2-l\" href=\"https:\/\/sofapiano.com\/faq\/\">FAQ<\/a><\/li>\n     <li><a class=\"f2-l\" href=\"https:\/\/sofapiano.com\/contact\/\">Contact<\/a><\/li>\n    <\/ul>\n   <\/nav>\n  <\/div>\n  <div class=\"f2-bot\">\n   <span>\u00a9 2026 sofapiano<\/span>\n   <nav class=\"f2-legal\" aria-label=\"Legal\">\n    <a href=\"https:\/\/sofapiano.com\/privacy-policy\/\">Privacy Policy<\/a>\n    <a href=\"https:\/\/sofapiano.com\/terms-conditions\/\">Terms &amp; Conditions<\/a>\n    <a href=\"https:\/\/sofapiano.com\/terms-of-use\/\">Terms of Use<\/a>\n    <a href=\"https:\/\/sofapiano.com\/cookie-notice\/\">Cookie Notice<\/a>\n    <a href=\"https:\/\/sofapiano.com\/impressum\/\">Impressum<\/a>\n   <\/nav>\n  <\/div>\n <\/div>\n<\/footer>\n<span hidden data-spx-mark=\"foot-end\"><\/span>\n","protected":false},"excerpt":{"rendered":"<p>Members area Log in to your dashboard Pick up where you left off: your statistics, saved sentences, grammar tracker and test results in one place. Member login Create free account Your dashboard Statistics and daily streak Saved Sentences Grammar tracker A1\u2013B2 Your level test results New to sofapiano?Create a free account My dashboard \u00b7AccountPLUSLevel ? [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-4842","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>MyLogIn - sofapiano<\/title>\n<meta name=\"robots\" content=\"noindex, follow\" \/>\n<meta property=\"og:locale\" content=\"es_ES\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"MyLogIn - sofapiano\" \/>\n<meta property=\"og:description\" content=\"Members area Log in to your dashboard Pick up where you left off: your statistics, saved sentences, grammar tracker and test results in one place. Member login Create free account Your dashboard Statistics and daily streak Saved Sentences Grammar tracker A1\u2013B2 Your level test results New to sofapiano?Create a free account My dashboard \u00b7AccountPLUSLevel ? [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/sofapiano.com\/es\/membership-login\/\" \/>\n<meta property=\"og:site_name\" content=\"sofapiano\" \/>\n<meta property=\"article:modified_time\" content=\"2026-11-05T01:24:50+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Tiempo de lectura\" \/>\n\t<meta name=\"twitter:data1\" content=\"274 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/sofapiano.com\\\/membership-login\\\/\",\"url\":\"https:\\\/\\\/sofapiano.com\\\/membership-login\\\/\",\"name\":\"MyLogIn - sofapiano\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/sofapiano.com\\\/#website\"},\"datePublished\":\"2026-04-27T13:09:13+00:00\",\"dateModified\":\"2026-11-05T01:24:50+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/sofapiano.com\\\/membership-login\\\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/sofapiano.com\\\/membership-login\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/sofapiano.com\\\/membership-login\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Start\",\"item\":\"https:\\\/\\\/sofapiano.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"MyLogIn\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/sofapiano.com\\\/#website\",\"url\":\"https:\\\/\\\/sofapiano.com\\\/\",\"name\":\"sofapiano\",\"description\":\"Learn German through translation\",\"publisher\":{\"@id\":\"https:\\\/\\\/sofapiano.com\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/sofapiano.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/sofapiano.com\\\/#organization\",\"name\":\"sofapiano\",\"url\":\"https:\\\/\\\/sofapiano.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/sofapiano.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/sofapiano.com\\\/wp-content\\\/uploads\\\/2026\\\/11\\\/cropped-Gemini_Generated_Image_m1p5p9m1p5p9m1p5-e1793819719304.png\",\"contentUrl\":\"https:\\\/\\\/sofapiano.com\\\/wp-content\\\/uploads\\\/2026\\\/11\\\/cropped-Gemini_Generated_Image_m1p5p9m1p5p9m1p5-e1793819719304.png\",\"width\":1683,\"height\":1156,\"caption\":\"sofapiano\"},\"image\":{\"@id\":\"https:\\\/\\\/sofapiano.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"MyLogIn - sofapiano","robots":{"index":"noindex","follow":"follow"},"og_locale":"es_ES","og_type":"article","og_title":"MyLogIn - sofapiano","og_description":"Members area Log in to your dashboard Pick up where you left off: your statistics, saved sentences, grammar tracker and test results in one place. Member login Create free account Your dashboard Statistics and daily streak Saved Sentences Grammar tracker A1\u2013B2 Your level test results New to sofapiano?Create a free account My dashboard \u00b7AccountPLUSLevel ? [&hellip;]","og_url":"https:\/\/sofapiano.com\/es\/membership-login\/","og_site_name":"sofapiano","article_modified_time":"2026-11-05T01:24:50+00:00","twitter_card":"summary_large_image","twitter_misc":{"Tiempo de lectura":"274 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/sofapiano.com\/membership-login\/","url":"https:\/\/sofapiano.com\/membership-login\/","name":"MyLogIn - sofapiano","isPartOf":{"@id":"https:\/\/sofapiano.com\/#website"},"datePublished":"2026-04-27T13:09:13+00:00","dateModified":"2026-11-05T01:24:50+00:00","breadcrumb":{"@id":"https:\/\/sofapiano.com\/membership-login\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/sofapiano.com\/membership-login\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/sofapiano.com\/membership-login\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Start","item":"https:\/\/sofapiano.com\/"},{"@type":"ListItem","position":2,"name":"MyLogIn"}]},{"@type":"WebSite","@id":"https:\/\/sofapiano.com\/#website","url":"https:\/\/sofapiano.com\/","name":"sofapiano","description":"Aprende alem\u00e1n a trav\u00e9s de la traducci\u00f3n","publisher":{"@id":"https:\/\/sofapiano.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/sofapiano.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":"Organization","@id":"https:\/\/sofapiano.com\/#organization","name":"sofapiano","url":"https:\/\/sofapiano.com\/","logo":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/sofapiano.com\/#\/schema\/logo\/image\/","url":"https:\/\/sofapiano.com\/wp-content\/uploads\/2026\/11\/cropped-Gemini_Generated_Image_m1p5p9m1p5p9m1p5-e1793819719304.png","contentUrl":"https:\/\/sofapiano.com\/wp-content\/uploads\/2026\/11\/cropped-Gemini_Generated_Image_m1p5p9m1p5p9m1p5-e1793819719304.png","width":1683,"height":1156,"caption":"sofapiano"},"image":{"@id":"https:\/\/sofapiano.com\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/sofapiano.com\/es\/wp-json\/wp\/v2\/pages\/4842","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sofapiano.com\/es\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/sofapiano.com\/es\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/sofapiano.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sofapiano.com\/es\/wp-json\/wp\/v2\/comments?post=4842"}],"version-history":[{"count":275,"href":"https:\/\/sofapiano.com\/es\/wp-json\/wp\/v2\/pages\/4842\/revisions"}],"predecessor-version":[{"id":19684,"href":"https:\/\/sofapiano.com\/es\/wp-json\/wp\/v2\/pages\/4842\/revisions\/19684"}],"wp:attachment":[{"href":"https:\/\/sofapiano.com\/es\/wp-json\/wp\/v2\/media?parent=4842"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}