1<!DOCTYPE html> 2<html lang="cs"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover"> 6 <title>Mushmaster PRO</title> 7 8 <!-- Google tag (gtag.js) -->
vendor: 69 bytes, lines 8-9
8 9 <script async src="https://www.googletagmanager.com/gtag/js?id=
9G-CCSMZQLWNF
vendor: 17 bytes, lines 9-10
9"></script> 10
10<script> 11 window.dataLayer = window.dataLayer || []; 12 function gtag(){dataLayer.push(arguments);} 13 window.gtag = gtag; 14 gtag('js', new Date()); 15 gtag('config', 'G-CCSMZQLWNF'); 16 // GA4 vlastnà události â musà být v klasickém
16<script>, ne ES modulu (spolehlivý pÅÃstup k gtag). 17 window.mmGaEvent = function(eventName, params) { 18 try { 19 if (typeof eventName !== 'string' || !eventName.trim()) return; 20 if (typeof window.gtag !== 'function') return; 21 var p = Object.assign( 22 { send_to: 'G-CCSMZQLWNF' }, 23 params && typeof params === 'object' ? params : {} 24 ); 25 window.gtag('event', eventName, p); 26 } catch (_) {} 27 }; 28 window.mmGaTrackPurchaseSuccess = function() { 29 window.mmGaEvent('purchase', { 30 transaction_id: 'stripe_' + Date.now(), 31 currency: 'CZK', 32 items: [{ item_id: 'pro_subscription', item_name: 'Mushmaster PRO', quantity: 1 }], 33 }); 34 }; 35 </script>
35 36 37 <link rel="manifest" href="/manifest.json"> 38 <link rel="apple-touch-icon" sizes="180x180" href="/icons/apple-touch-icon.png?v=2"> 39 <link rel="icon" type="image/png" sizes="192x192" href="/icons/icon-192.png?v=2"> 40 <link rel="icon" type="image/png" sizes="512x512" href="/icons/icon-512.png?v=2"> 41 42 <meta name="mobile-web-app-capable" content="yes"> 43 <meta name="apple-mobile-web-app-capable" content="yes"> 44 <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> 45 <meta name="apple-mobile-web-app-title" content="Mushmaster"> 46 <meta name="theme-color" content="#3C1A22"> 47 <meta name="msapplication-TileColor" content="#3C1A22"> 48 <meta name="msapplication-TileImage" content="/icons/icon-192.png"> 49 50 <meta name="description" content="Tréninkový denÃk pro mushing a canicross. PlánovánÃ, analýzy, sdÃlenà s trenérem."> 51 <meta property="og:title" content="Mushmaster PRO"> 52 <meta property="og:description" content="Tréninkový denÃk pro mushing a canicross."> 53 <meta property="og:image" content="/icons/icon-512.png"> 54 <meta property="og:type" content="website"> 55 <!-- PÅi vydánà nové verze sjednoÅ¥ s version.json (hlášenà aktualizace PWA) --> 56 <meta name="mm-app-version" content="2.6.1"> 57 58 <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> 59 60 <link rel="stylesheet" href="style.css?v=271"> 61 <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" crossorigin=""/> 62
62<script src="https://unpkg.com/[email protected]/dist/leaflet.js" crossorigin=""></script>
62 63
63<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
63 64</head> 65<body>
66<script> 67 window.__MM_APP_VERSION = '2.4.0'; 68</script>
vendor: 2 bytes, line 68
68
69<script> 70(function () { 71 try { 72 var u = new URL(window.location.href); 73 var ref = u.searchParams.get('ref'); 74 if (ref && /^[a-zA-Z0-9_-]{10,128}$/.test(ref)) { 75 localStorage.setItem('pending_referral', ref); 76 u.searchParams.delete('ref'); 77 var clean = u.pathname + (u.search || '') + (u.hash || ''); 78 window.history.replaceState({}, '', clean); 79 } 80 } catch (e) {} 81})(); 82</script>
vendor: 2 bytes, line 82
82
83<script> 84window.setPlanModuleView = function(id) { 85 if (id !== 'training' && id !== 'gut') id = 'training'; 86 var views = document.querySelectorAll('.plan-main-view'); 87 views.forEach(function(view) { 88 view.style.display = view.id === ('planView-' + id) ? 'block' : 'none'; 89 }); 90 try { localStorage.setItem('plan_active_view', id); } catch (_) {} 91 var tabTraining = document.getElementById('planTab_training'); 92 var tabGut = document.getElementById('planTab_gut'); 93 if (tabTraining) { 94 tabTraining.classList.toggle('planner-tab-active', id === 'training'); 95 tabTraining.setAttribute('aria-selected', id === 'training' ? 'true' : 'false'); 96 } 97 if (tabGut) { 98 tabGut.classList.toggle('planner-tab-active', id === 'gut'); 99 tabGut.setAttribute('aria-selected', id === 'gut' ? 'true' : 'false'); 100 } 101 var layout = document.querySelector('#tab-plan .plan-layout'); 102 if (layout) { 103 layout.classList.toggle('plan-layout--gut-only', id === 'gut'); 104 } 105 var btn = document.getElementById('btnVypocitejTrenink'); 106 if (btn) btn.style.display = (id === 'training') ? 'block' : 'none'; 107}; 108</script>
108 109 110<!-- =Â= GDPR MODAL =Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â= --> 111<div id="gdprModal" class="modal-overlay" style="display:none;z-index:10001;" role="dialog" aria-modal="true" aria-labelledby="gdprModalTitle" onclick="if(event.target===this)window.zavritGdprModal()"> 112 <div class="modal-box gdpr-modal-box" style="max-width:600px;width:100%;padding:0;border-radius:16px;overflow:hidden;box-sizing:border-box;border-top:none;max-height:90vh;display:flex;flex-direction:column;"> 113 <div class="gdpr-modal-head"> 114 <div class="gdpr-modal-head__text"> 115 <div class="gdpr-modal-head__brand">Mushmaster PRO</div> 116 <h2 id="gdprModalTitle" class="gdpr-modal-head__title"> 117 <span data-i18n="gdpr_modal_title"><i data-icon="shield-check" style="color:var(--orange);"></i> Zásady ochrany soukromÃ</span> 118 </h2> 119 </div> 120 <button type="button" class="modal-close gdpr-modal-close" onclick="window.zavritGdprModal()" data-i18n="gdpr_modal_close_aria" data-i18n-attr="aria-label" aria-label="ZavÅÃt"><span class="modal-close__icon" aria-hidden="true"><i data-icon="x-mark"></i></span></button> 121 </div> 122 123 <!-- Scrollovatelný obsah --> 124 <div class="gdpr-modal-body" style="overflow-y:auto;padding:24px;flex:1 1 auto;-webkit-overflow-scrolling:touch;"> 125 126 <p class="gdpr-intro" data-i18n="gdpr_intro">Mushmaster PRO sbÃrá jen ta nejnutnÄjšà data pro pÅesný výpoÄet tréninkových metrik vaÅ¡eho psa. VaÅ¡e soukromà bereme vážnÄ â tato stránka vysvÄtluje co, proÄ a jak dlouho uchováváme.</p> 127 128 <!-- 1 --> 129 <div class="gdpr-section"> 130 <h3 class="gdpr-section__title"><span class="gdpr-num">1</span> <span data-i18n="gdpr_s1_title">Kdo zpracovává vaÅ¡e data?</span></h3> 131 <p data-i18n="gdpr_s1_p1">Správcem vaÅ¡ich osobnÃch údajů je provozovatel aplikace <strong>Mushmaster PRO</strong>.</p> 132 <p data-i18n="gdpr_s1_p2">Kontaktnà e-mail: <a href="mailto:[email protected]" class="gdpr-link">[email protected]</a></p> 133 </div> 134 135 <!-- 2 --> 136 <div class="gdpr-section"> 137 <h3 class="gdpr-section__title"><span class="gdpr-num">2</span> <span data-i18n="gdpr_s2_title">Jaká data sbÃráme a proÄ?</span></h3> 138 <div class="gdpr-item"> 139 <div class="gdpr-item__icon"><i data-icon="user"></i></div> 140 <div> 141 <strong data-i18n="gdpr_s2_account_title">Ãdaje o úÄtu (e-mail, jméno, profilová fotografie)</strong> 142 <p class="gdpr-item__desc" data-i18n="gdpr_s2_account_desc">ZÃskáváme je pÅi registraci pÅes Google nebo magický odkaz. Sloužà k vytvoÅenà profilu, zabezpeÄenà pÅÃstupu a synchronizaci napÅÃÄ zaÅÃzenÃmi.</p> 143 </div> 144 </div> 145 <div class="gdpr-item"> 146 <div class="gdpr-item__icon"><i data-icon="paw"></i></div> 147 <div> 148 <strong data-i18n="gdpr_s2_training_title">Tréninková data a profily psů</strong> 149 <p class="gdpr-item__desc" data-i18n="gdpr_s2_training_desc">Jména psů, délky tréninků, RPE, vzdálenosti, teplota, zdravotnà poznámky a vybavenÃ. Tato data zpracováváme výhradnÄ pro výpoÄet modelů formy (EWMA/CTL/ATL), únavy, teplotnà adaptace a vizualizaci grafů.</p> 150 </div> 151 </div> 152 <div class="gdpr-item"> 153 <div class="gdpr-item__icon"><i data-icon="device-phone-mobile"></i></div> 154 <div> 155 <strong data-i18n="gdpr_s2_tech_title">Technická data (Local Storage, IndexedDB)</strong> 156 <p class="gdpr-item__desc" data-i18n="gdpr_s2_tech_desc">Aplikace ukládá Äást dat pÅÃmo do pamÄti vaÅ¡eho prohlÞeÄe. Zajišťuje to bleskové naÄÃtánà a plnou funkÄnost i offline â napÅÃklad pÅi tréninku v lese bez signálu.</p> 157 </div> 158 </div> 159 </div> 160 161 <!-- 3 --> 162 <div class="gdpr-section"> 163 <h3 class="gdpr-section__title"><span class="gdpr-num">3</span> <span data-i18n="gdpr_s3_title">Komu data pÅedáváme?</span> <span class="gdpr-badge-safe" data-i18n="gdpr_s3_badge">Nikomu je neprodáváme!</span></h3> 164 <p data-i18n="gdpr_s3_p1">VaÅ¡e tréninková data ani osobnà údaje <strong>
164nikdy neprodáváme</strong> tÅetÃm stranám ani je nepoužÃváme pro cÃlenou reklamu.</p> 165 <p data-i18n="gdpr_s3_p2">Pro technický chod využÃváme výhradnÄ <strong>Google Firebase</strong> â zabezpeÄenou cloudovou infrastrukturu. Data jsou uložena v Å¡ifrované podobÄ na serverech Google a podléhajà nejvyššÃm bezpeÄnostnÃm standardům (<a href="https://firebase.google.com/support/privacy" target="_blank" rel="noopener" class="gdpr-link">Firebase Privacy Policy</a>).</p> 166 </div> 167 168 <!-- 4 --> 169 <div class="gdpr-section"> 170 <h3 class="gdpr-section__title"><span class="gdpr-num">4</span> <span data-i18n="gdpr_s4_title">Jak dlouho data uchováváme?</span></h3> 171 <p data-i18n="gdpr_s4_body">VaÅ¡e data uchováváme po celou dobu existence úÄtu, abyste mÄli nepÅetržitý pÅÃstup k historii tréninků. PÅi smazánà úÄtu jsou veÅ¡kerá data (profil, psi, záznamy z denÃku) z našà databáze <strong>nenávratnÄ odstranÄna</strong> â bez výjimky.</p> 172 </div> 173 174 <!-- 5 --> 175 <div class="gdpr-section"> 176 <h3 class="gdpr-section__title"><span class="gdpr-num">5</span> <span data-i18n="gdpr_s5_title">Cookies a sledovacà nástroje</span></h3> 177 <p data-i18n="gdpr_s5_p1">Mushmaster PRO je PWA â Progresivnà webová aplikace. <strong>NevyužÃváme žádné marketingové sledovacà cookies</strong> (Facebook Pixel, Google Analytics apod.). Ukládáme pouze nezbytná technická data pro udrženà pÅihlášenà a plynulý chod aplikace.</p> 178 <p data-i18n="gdpr_s5_p2">Proto vás neobtÄžuje žádná cookie liÅ¡ta.</p> 179 </div> 180 181 <!-- 6 --> 182 <div class="gdpr-section"> 183 <h3 class="gdpr-section__title"><span class="gdpr-num">6</span> <span data-i18n="gdpr_s6_title">VaÅ¡e práva</span></h3> 184 <p data-i18n="gdpr_s6_intro">Máte plnou kontrolu nad svými daty. PÅÃmo v nastavenà aplikace můžete kdykoliv:</p> 185 <div class="gdpr-rights-grid"> 186 <div class="gdpr-right-item"> 187 <i data-icon="arrow-down-tray" style="color:var(--orange);"></i> 188 <div> 189 <strong data-i18n="gdpr_right_export_title">Exportovat svá data</strong> 190 <span data-i18n="gdpr_right_export_desc">StáhnÄte kompletnà historii tréninků a profily psů ve formátu JSON (Právo na pÅenositelnost, Äl. 20 GDPR).</span> 191 </div> 192 </div> 193 <div class="gdpr-right-item"> 194 <i data-icon="trash" style="color:#c62828;"></i> 195 <div> 196 <strong data-i18n="gdpr_right_delete_title">Smazat úÄet</strong> 197 <span data-i18n="gdpr_right_delete_desc">NenávratnÄ smažete profil a veÅ¡kerou historii z naÅ¡ich serverů (Právo být zapomenut, Äl. 17 GDPR).</span> 198 </div> 199 </div> 200 <div class="gdpr-right-item"> 201 <i data-icon="pencil-square" style="color:var(--text-secondary);"></i> 202 <div> 203 <strong data-i18n="gdpr_right_rectify_title">
203Požádat o opravu údajů</strong> 204 <span data-i18n="gdpr_right_rectify_desc">Kontaktujte nás a nesprávná data opravÃme bez zbyteÄného odkladu.</span> 205 </div> 206 </div> 207 <div class="gdpr-right-item"> 208 <i data-icon="hand-raised" style="color:var(--text-secondary);"></i> 209 <div> 210 <strong data-i18n="gdpr_right_complaint_title">Vznést námitku nebo podat stÞnost</strong> 211 <span data-i18n="gdpr_right_complaint_desc">Máte právo obrátit se na <a href="https://www.uoou.cz" target="_blank" rel="noopener" class="gdpr-link">ÃÅad pro ochranu osobnÃch údajů (ÃOOÃ)</a>.</span> 212 </div> 213 </div> 214 </div> 215 <p style="margin-top:14px;" data-i18n="gdpr_s6_contact">V pÅÃpadÄ jakýchkoliv dotazů nás kontaktujte na <a href="mailto:[email protected]" class="gdpr-link">[email protected]</a>.</p> 216 </div> 217 218 <p class="gdpr-footer-note" data-i18n="gdpr_footer_note">Tyto zásady jsou platné od 1. 1. 2025. Mushmaster PRO si vyhrazuje právo je aktualizovat â o zmÄnách vás budeme informovat v aplikaci.</p> 219 220 </div> 221 </div> 222</div> 223<!-- =Â= / GDPR MODAL =Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â= --> 224 225<!-- =Â= UŽIVATELSKà NÃVOD MODAL =Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â= --> 226<div id="userGuideModal" class="modal-overlay" style="display:none;z-index:10001;" role="dialog" aria-modal="true" aria-labelledby="userGuideModalTitle" onclick="if(event.target===this)window.zavritUserGuideModal()"> 227 <div class="modal-box gdpr-modal-box user-guide-modal-box" style="max-width:680px;width:100%;padding:0;border-radius:16px;overflow:hidden;box-sizing:border-box;border-top:none;max-height:90vh;display:flex;flex-direction:column;"> 228 <div class="gdpr-modal-head"> 229 <div class="gdpr-modal-head__text"> 230 <div class="gdpr-modal-head__brand">Mushmaster PRO</div> 231 <h2 id="userGuideModalTitle" class="gdpr-modal-head__title"> 232 <i data-icon="document-text" style="color:var(--orange);"></i> <span data-i18n="settings_user_guide_title">Uživatelský návod</span> 233 </h2> 234 </div> 235 <button type="button" class="modal-close gdpr-modal-close" onclick="window.zavritUserGuideModal()" data-i18n="gdpr_modal_close_aria" data-i18n-attr="aria-label" aria-label="ZavÅÃt"><span class="modal-close__icon" aria-hidden="true"><i data-icon="x-mark"></i></span></button> 236 </div> 237 238 <div id="userGuideModalBody" class="gdpr-modal-body user-guide-body" style="overflow-y:auto;padding:24px;flex:1 1 auto;-webkit-overflow-scrolling:touch;"> 239 <p class="user-guide-loading" data-i18n="settings_user_guide_loading">NaÄÃtám návodâ¦</p> 240 </div> 241 </div> 242</div> 243<!-- =Â= / UŽIVATELSKà NÃVOD MODAL =Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â= --> 244 245<!-- =Â= LOGIN MODAL =Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â= --> 246<div id="loginModal" class="modal-overlay" style="display:none;" role="dialog" aria-modal="true" aria-labelledby="loginModalTitle" onclick="if(event.target===this)window.zavritLoginModal()"> 247 <div class="modal-box" style="max-width:420px;width:100%;padding:0;border-radius:16px;overflow:hidden;box-sizing:border-box;border-top:none;"> 248 <!-- Header --> 249 <div style="background:linear-gradient(135deg,#3C1A22 0%,#5C2A36 100%);padding:28px 28px 22px;text-align:center;position:relative;"> 250 <div style="line-height:1;margin-bottom:10px;color:var(--orange);" role="img" aria-label="Tlapka"><i data-icon="paw" data-icon-size="44"></i></div> 251 <div style="font-size:10px;font-weight:800;color:#D4870A;letter-spacing:2px;text-transform:uppercase;margin-bottom:4px;">Mushmaster PRO</div> 252 <h2 id="loginModalTitle" style="margin:0;font-size:18px;font-weight:900;color:#F8EDE5;line-height:1.3;">PÅihlaste se</h2> 253 <button type="button" onclick="window.zavritLoginModal()" aria-label="ZavÅÃt" 254 style="position:absolute;top:12px;right:14px;background:rgba(255,255,255,0.12);border:1px solid rgba(255,255,255,0.25);border-radius:8px;width:32px;height:32px;display:flex;align-items:center;justify-content:center;cursor:pointer;color:#fff;font-size:16px;line-height:1;padding:0;"> 255 <i data-icon="x-mark"></i> 256 </button> 257 </div> 258 <!-- TÄlo --> 259 <div style="padding:24px;"> 260 <!-- Google --> 261 <button id="loginModalGoogleBtn" type="button" class="login-google-btn" 262 style="width:100%;display:flex;align-items:center;justify-content:center;gap:10px;padding:13px 16px;border-radius:10px;border:2px solid var(--border);background:var(--bg-surface2);color:var(--text-primary);font-size:14px;font-weight:800;cursor:pointer;min-height:48px;box-sizing:border-box;transition:background .15s;" 263 onclick="window.prihlasitSeGoogle()"> 264 <!-- Google "G" logo --> 265 <svg width="20" height="20" viewBox="0 0 48 48" aria-hidden="true" focusable="false"> 266 <path fill="#4285F4" d="M44.5 20H24v8.5h11.8C34.1 33.7 29.6 37 24 37c-7.2 0-13-5.8-13-13s5.8-13 13-13c3.3 0 6.3 1.3 8.6 3.4l6-6C34.9 5.1 29.8 3 24 3 12.4 3 3 12.4 3 24s9.4 21 21 21c10.9 0 20.4-7.9 20.4-21 0-1.4-.1-2.7-.4-4z"/> 267 <path fill="#34A853" d="M6.3 14.7l7 5.1C15 16.2 19.2 13 24 13c3.3 0 6.3 1.3 8.6 3.4l6-6C34.9 5.1 29.8 3 24 3 16 3 9.1 7.9 6.3 14.7z"/> 268 <path fill="#FBBC05" d="M24 45c5.5 0 10.5-1.9 14.4-5.1l-6.7-5.5C29.6 36.2 26.9 37 24 37c-5.6 0-10.1-3.4-11.8-8.1l-6.9 5.3
268C9.1 40.8 16 45 24 45z"/> 269 <path fill="#EA4335" d="M44.5 20H24v8.5h11.8c-.8 2.5-2.5 4.7-4.8 6.2l6.7 5.5C42.5 37 45 31 45 24c0-1.4-.1-2.7-.4-4z"/> 270 </svg> 271 PÅihlásit pÅes Google 272 </button> 273 274 <!-- OddÄlovaÄ --> 275 <div style="display:flex;align-items:center;gap:10px;margin:18px 0 14px;"> 276 <div style="flex:1;height:1px;background:var(--border);"></div> 277 <span style="font-size:11px;font-weight:700;color:var(--text-muted);letter-spacing:.4px;text-transform:uppercase;white-space:nowrap;">nebo e-mailem bez hesla</span> 278 <div style="flex:1;height:1px;background:var(--border);"></div> 279 </div> 280 281 <!-- Magický odkaz --> 282 <div style="display:flex;flex-direction:column;gap:10px;"> 283 <input type="email" id="magic-email-input" autocomplete="email" inputmode="email" 284 placeholder="Váš e-mail" 285 style="width:100%;padding:12px 14px;border:1.5px solid var(--border);border-radius:10px;font-size:16px !important;color:var(--text-primary);background:var(--bg-input,var(--bg-surface));box-sizing:border-box;outline:none;transition:border-color .15s;min-height:48px;" 286 onfocus="this.style.borderColor='var(--orange)'" onblur="this.style.borderColor='var(--border)'" 287 onkeydown="if(event.key==='Enter')window.odeslMagickyOdkaz()"> 288 <button id="btn-magic-login" type="button" class="btn-primary" 289 style="width:100%;min-height:48px;font-size:14px;font-weight:800;border-radius:10px;display:flex;align-items:center;justify-content:center;gap:8px;margin-top:0;" 290 onclick="window.odeslMagickyOdkaz()"> 291 <i data-icon="envelope"></i> Poslat magický odkaz 292 </button> 293 </div> 294 295 <p id="loginMagicHintWeb" style="margin:16px 0 0;font-size:11px;color:var(--text-muted);text-align:center;line-height:1.5;" data-i18n="login_magic_hint"> 296 PoÅ¡leme vám e-mail s odkazem. KliknutÃm na odkaz se pÅihlásÃte â bez hesla. 297 </p> 298 <p id="loginMagicHintPwa" style="display:none;margin:16px 0 0;font-size:11px;color:var(--text-muted);text-align:center;line-height:1.5;" data-i18n="login_magic_hint_pwa"> 299 Na iPhonu odkaz otevÅe Safari. Po pÅihlášenà se vraÅ¥te do aplikace na ploÅ¡e â pÅihlášenà se dokonÄà automaticky. 300 </p> 301 302 <!-- GDPR souhlas --> 303 <p style="margin:14px 0 0;font-size:11px;color:var(--text-muted);text-align:center;line-height:1.6;" data-i18n="auth_gdpr_consent"> 304 PÅihlášenÃm nebo registracà souhlasÃte s naÅ¡imi 305 <a href="#" class="gdpr-link" onclick="event.preventDefault();window.otevritGdprModal()">Zásadami ochrany soukromÃ</a> 306 a zpracovánÃm dat pro úÄely tréninkové analytiky. 307 </p> 308 </div> 309 </div> 310</div> 311<!-- =Â= / LOGIN MODAL =Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â= --> 312 313<!-- =Â= ONBOARDING MODAL =Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â= --> 314<div id="onboarding-modal" class="modal-overlay" style="display:none;" role="dialog" aria-modal="true" aria-labelledby="onboarding-title"> 315 <div class="modal-box" style="max-width:440px;width:100%;padding:0;border-radius:16px;overflow:hidden;box-sizing:border-box;border-top:none;"> 316 <!-- IlustraÄnà header --> 317 <div style="background:linear-gradient(135deg,#3C1A22 0%,#5C2A36 100%);padding:32px 28px 24px;text-align:center;position:relative;"> 318 <div style="line-height:1;margin-bottom:12px;color:var(--orange);" role="img" aria-label="Tlapka"><i data-icon="paw" data-icon-size="56"></i></div> 319 <div style="font-size:10px;font-weight:800;color:#D4870A;letter-spacing:2px;text-transform:uppercase;margin-bottom:6px;">Mushmaster PRO</div> 320 <h2 id="onboarding-title" style="margin:0;font-size:20px;font-weight:900;color:#F8EDE5;line-height:1.3;">VÃtejte! PojÄme zaÄÃt.</h2> 321 </div> 322 <!-- Obsah --> 323 <div style="padding:24px 24px 8px;"> 324 <p style="margin:0 0 16px;font-size:14px;color:var(--text-secondary);line-height:1.6;text-align:center;"> 325 Abychom mohli poÄÃtat <strong>formu, zátÄž a doporuÄenÃ</strong>, potÅebujeme znát vaÅ¡eho prvnÃho parťáka. 326 </p> 327 <!-- 3 ikonkové tipy --> 328 <div style="display:grid;grid-template-columns:1fr 1fr 1fr;gap:10px;margin-bottom:20px;"> 329 <div style="background:var(--bg-surface2);border-radius:10px;padding:10px 8px;text-align:center;"> 330 <div style="color:var(--maroon);"><i data-icon="chart-bar" data-icon-size="22"></i></div> 331 <div style="font-size:10px;color:var(--text-muted);margin-top:4px;font-weight:600;">Forma & zátÄž</div> 332 </div> 333 <div style="background:var(--bg-surface2);border-radius:10px;padding:10px 8px;text-align:center;"> 334 <div style="color:var(--maroon);"><i data-icon="bolt" data-icon-size="22"></i></div> 335 <div style="font-size:10px;color:var(--text-muted);margin-top:4px;font-weight:600;">Tréninkový denÃk</div> 336 </div> 337 <div style="background:var(--bg-surface2);border-radius:10px;padding:10px 8px;text-align:center;"> 338 <div style="color:var(--maroon);"><i data-icon="trophy" data-icon-size="22"></i></div> 339 <div style="font-size:10px;color:var(--text-muted);margin-top:4px;font-weight:600;">Závody & plány</div> 340 </div> 341 </div> 342 </div>
343 <!-- TlaÄÃtka --> 344 <div style="padding:4px 24px 24px;display:flex;flex-direction:column;gap:10px;"> 345 <button id="onboarding-btn-create" class="btn-primary" style="width:100%;min-height:48px;font-size:15px;font-weight:800;border-radius:10px;letter-spacing:.3px;"> 346 <i data-icon="dog"></i> VytvoÅit profil psa 347 </button> 348 <button id="onboarding-btn-later" style="width:100%;min-height:44px;font-size:13px;background:transparent;border:none;color:var(--text-muted);cursor:pointer;border-radius:10px;padding:8px;"> 349 Možná pozdÄji 350 </button> 351 </div> 352 </div> 353</div> 354<!-- =Â= / ONBOARDING MODAL =Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â= --> 355 356<div id="paywallModal" class="modal-overlay" style="display: none;"> 357 <div class="modal-box" style="border-color: #ff8f00; max-width: 420px;"> 358 <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:14px;border-bottom:1px solid var(--border);padding-bottom:10px;"> 359 <h2 style="margin:0;color:#ff8f00;text-align:left;"><i data-icon="crown"></i> Mushmaster PRO</h2> 360 <button type="button" class="modal-close" onclick="window.closeModal('paywallModal')" aria-label="ZavÅÃt"><i data-icon="x-mark"></i></button> 361 </div> 362 <p id="paywallText" style="text-align:center; color:var(--text-secondary); margin-bottom:16px;">OdemknÄte vÅ¡echny pokroÄilé funkce, které posunou pÅÃpravu týmu na vyššà úroveÅ.</p> 363 364 <ul style="font-size:13px; margin-bottom:20px; color:var(--text-secondary); line-height:1.7; padding-left:18px;"> 365 <li><i data-icon="check-circle" data-icon-class="icon-success"></i> Neomezená tréninková historie</li> 366 <li><i data-icon="check-circle" data-icon-class="icon-success"></i> Až 10 psů a plné profily</li> 367 <li><i data-icon="check-circle" data-icon-class="icon-success"></i> GPX/TCX/FIT import z hodinek a automatické vyplnÄnà trasy</li> 368 <li><i data-icon="check-circle" data-icon-class="icon-success"></i> AI PlánovaÄ tréninků</li> 369 <li><i data-icon="check-circle" data-icon-class="icon-success"></i> Správa garáže a sledovánà opotÅebenÃ</li> 370 <li><i data-icon="check-circle" data-icon-class="icon-success"></i> SdÃlenà psa s trenérem + trenérský režim</li> 371 <li><i data-icon="check-circle" data-icon-class="icon-success"></i> OdemÄené dashboardy (vÅ¡echny analýzy, delšà obdobÃ, custom datum)</li> 372 <li><i data-icon="check-circle" data-icon-class="icon-success"></i> Prémiové sdÃlecà karty (barvy, pokroÄilé vzhledy)</li> 373 </ul> 374 375 <div style="display:flex; flex-direction:column; gap:10px; margin-bottom:16px;"> 376 <div style="position:relative; border:2px solid var(--orange); border-radius:10px; padding:14px 16px; background:var(--bg-surface);"> 377 <div style="position:absolute; top:-11px; right:14px; background:var(--orange); color:#fff; font-size:10px; font-weight:900; padding:2px 10px; border-radius:20px; text-transform:uppercase; letter-spacing:0.5px;">NejvýhodnÄjšà â uÅ¡etÅà 298 KÄ</div> 378 <div style="display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:8px;"> 379 <div> 380 <div style="font-weight:900; font-size:15px; color:var(--text-primary);">RoÄnÄ</div> 381 <div style="font-size:12px; color:var(--text-secondary);">1 190 KÄ / rok · <strong style="color:var(--orange);">~99 KÄ / mÄsÃc</strong></div> 382 </div> 383 <button class="btn-accent btn-small" data-price-id="price_1TIpFbGtwYZ0swcsrzpCm8Ey" onclick="window.spustitPlatbu('price_1TIpFbGtwYZ0swcsrzpCm8Ey')" style="margin:0;width:auto;max-width:none;">Vybrat roÄnÃ</button> 384 </div> 385 </div> 386 387 <div style="border:2px solid var(--border-mid); border-radius:10px; padding:14px 16px; background:var(--bg-surface); position:relative;"> 388 <div style="position:absolute; top:-11px; right:14px; background:#455a64; color:#fff; font-size:10px; font-weight:900; padding:2px 10px; border-radius:20px; text-transform:uppercase; letter-spacing:0.5px;">OblÃbené</div> 389 <div style="display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:8px;"> 390 <div> 391 <div style="font-weight:900; font-size:15px;
391 color:var(--text-primary);">PůlroÄnÄ</div> 392 <div style="font-size:12px; color:var(--text-secondary);">749 KÄ / 6 mÄsÃců · <strong>~125 KÄ / mÄsÃc</strong></div> 393 </div> 394 <button class="btn-primary btn-small" data-price-id="price_1TIpEwGtwYZ0swcs4Iov2BWX" onclick="window.spustitPlatbu('price_1TIpEwGtwYZ0swcs4Iov2BWX')" style="margin:0;width:auto;max-width:none;">Vybrat půlroÄnÃ</button> 395 </div> 396 </div> 397 398 <div style="border:1.5px solid var(--border); border-radius:10px; padding:14px 16px; background:var(--bg-surface);"> 399 <div style="display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:8px;"> 400 <div> 401 <div style="font-weight:900; font-size:15px; color:var(--text-primary);">MÄsÃÄnÄ</div> 402 <div style="font-size:12px; color:var(--text-secondary);">149 KÄ / mÄsÃc</div> 403 </div> 404 <button class="btn-outline btn-small" data-price-id="price_1TIpDRGtwYZ0swcspvFvZl8Z" onclick="window.spustitPlatbu('price_1TIpDRGtwYZ0swcspvFvZl8Z')" style="margin:0;width:auto;max-width:none;">Vybrat mÄsÃÄnÃ</button> 405 </div> 406 </div> 407 </div> 408 <p style="font-size:10px; color:var(--text-muted); text-align:center; margin-bottom:14px;">Platba pÅes Stripe · ZruÅ¡enà kdykoliv · Žádné skryté poplatky</p> 409 <button class="btn-cancel" style="display:block;" onclick="window.closeModal('paywallModal')">ZavÅÃt</button> 410 </div> 411</div> 412 413<div id="vybaveniModal" class="modal-overlay" style="display: none;"> 414 <div class="modal-box garage-modal-box" style="border-top-color: #ff8f00;max-width:520px;"> 415 <div style="display:flex;justify-content:space-between;align-items:flex-start;gap:10px;margin-bottom:12px;border-bottom:1px solid var(--border);padding-bottom:10px;"> 416 <div style="min-width:0;"> 417 <h2 style="margin:0;color:#ff8f00;"><span data-i18n="garage_modal_title"><i data-icon="briefcase"></i> Garáž (profil)</span></h2> 418 <p id="garageModalSubtitle" class="garage-modal-subtitle" style="display:none;margin:6px 0 0;font-size:12px;color:var(--text-muted);line-height:1.35;"></p> 419 </div> 420 <button type="button" class="modal-close" onclick="window.closeModal('vybaveniModal')" data-i18n="dog_modal_close_aria" data-i18n-attr="aria-label" aria-label="ZavÅÃt"><i data-icon="x-mark"></i></button> 421 </div> 422 <div style="display:flex;gap:6px;margin-bottom:14px;"> 423 <button id="garageTab_vybaveni" onclick="window.garageTab('vybaveni')" class="garage-tab garage-tab-active" data-i18n="garage_tab_equipment"><i data-icon="wrench-screwdriver"></i> VybavenÃ</button> 424 <button id="garageTab_sety" onclick="window.garageTab('sety')" class="garage-tab" data-i18n="garage_tab_sets"><i data-icon="briefcase"></i> Moje sety</button> 425 </div> 426 <div id="garagePanel_vybaveni"> 427 <p class="settings-hint garage-assign-hint" data-i18n="garage_assign_hint">ZaÅ¡krtnÄte psy u položky â ti mohou ji použÃvat pÅi zápisu (sdÃlenà mezi vÃce psy). Nic nevybráno = dostupné vÅ¡em vlastnÃm psům.</p> 428 <div id="seznamVybaveni" class="garage-eq-scroll"></div> 429 <div style="background:var(--bg-surface2);padding:14px;border:1px solid var(--border);margin-bottom:12px;border-radius:var(--radius-sm);"> 430 <label style="margin-top:0;font-weight:700;" data-i18n="garage_add_section">PÅidat do garáže:</label> 431 <input type="text" id="noveVybaveniNazev" data-i18n="garage_add_name_placeholder" data-i18n-attr="placeholder" placeholder="Název (napÅ. Non-stop Freemotion)"> 432 <select id="noveVybaveniKategorie" aria-label="Kategorie vybavenÃ"></select> 433 <div class="grid-2"> 434 <div><label data-i18n="garage_label_lifespan_km">Životnost (km):</label><input type="number" id="noveVybaveniKm" data-i18n="garage_placeholder_lifespan_km" data-i18n-attr="placeholder" placeholder="NapÅ. 1500"></div> 435 <div><label data-i18n="garage_label_lifespan_hod">Nebo (hodin):</label><input type="number" id="noveVybaveniHod" data-i18n="garage_placeholder_lifespan_hod" data-i18n-attr="placeholder" placeholder="NapÅ. 100"></div> 436 </div> 437 <button class="btn-accent" onclick="window.pridatVybaveni()" style="margin-top:12px;" data-i18n="garage_add_btn">+ PÅIDAT VYBAVENÃ</button> 438 </div> 439 </div> 440 <div id="garagePanel_sety" style="display:none;"> 441 <button class="btn-primary" onclick="window.vytvoritSet()" style="margin-bottom:12px;" data-i18n="garage_create_set_btn">+ VytvoÅit nový set</button> 442 <div id="seznamSetu" class="modal-scroll-region" style="max-height:300px;overflow-y:auto;"></div> 443 </div> 444 <button class="btn-cancel" style="display:block;margin-top:8px;" onclick="window.closeModal('vybaveniModal')" data-i18n="garage_close">ZavÅÃt</button> 445 </div> 446</div> 447 448<div id="setModal" class="modal-overlay" style="display:none;"> 449 <div class="modal-box" style="border-top-color:var(--maroon);max-width:440px;"> 450 <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:14px;border-bottom:1px solid var(--border);padding-bottom:10px;"> 451 <h2 id="setModalTitle" style="margin:0;color:var(--maroon);" data-i18n="garage_set_modal_new">+ Nový set</h2> 452 <button type="button" class="modal-close" onclick="window.closeModal('setModal')" data-i18n="dog_modal_close_aria" data-i18n-attr="aria-label" aria-label="ZavÅÃt"><i data-icon="x-mark"></i></button> 453 </div> 454 <input type="hidden" id="setEditId"> 455 <label style="font-weight:700;margin-bottom:6px;display:block;" data-i18n="garage_set_label_name">Název setu:</label> 456 <input type="text" id="setNazev" placeholder="NapÅ. Závodnà set Kolo" style="margin-bottom:14px;"> 457 <label style="font-weight:700;margin-bottom:8px;display:block;" data-i18n="garage_set_pick_items">Vyberte vybavenà do setu:</label> 458 <div id="setItemList" class="modal-scroll-region" style="max-height:260px;overflow-y:auto;display:flex;flex-direction:column;gap:0;margin-bottom:16px;"></div> 459 <button class="btn-blue" onclick="window.ulozitSet()" style="margin-bottom:8px;" data-i18n="garage_set_save">ULOŽIT SET</button> 460 <button class="btn-cancel" style="display:block;" onclick="window.closeModal('setModal')" data-i18n="btn_zrusit">ZruÅ¡it</button> 461 </div> 462</div> 463 464<div id="selectVybaveniModal" class="modal-overlay" style="display: none;"> 465 <div class="modal-box" style="border-top-color: #ff8f00;max-width:440px;"> 466 <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;border-bottom:1px solid var(--border);padding-bottom:10px;"> 467 <h2 style="margin:0;color:#ff8f00;" data-i18n="garage_select_title"><i data-icon="briefcase"></i> VYBRAT VYBAVENÃ</h2> 468 <button type="button" class="modal-close" onclick="window.closeModal('selectVybaveniModal')" data-i18n="dog_modal_close_aria" data-i18n-attr="aria-label" aria-label="ZavÅÃt"><i data-icon="x-mark"></i></button> 469 </div> 470 <div style="display:flex;gap:6px;margin-bottom:14px;"> 471 <button id="selectTab_sety" onclick="window.selectVybaveniTab('sety')" class="garage-tab garage-tab-active" data-i18n="garage_select_tab_sets"><i data-icon="briefcase"></i> Sety</button> 472 <button id="selectTab_jednotlive" onclick="window.selectVybaveniTab('jednotlive')" class="garage-tab" data-i18n="garage_select_tab_items"><i data-icon="wrench-screwdriver"></i> Jednotlivé</button> 473 </div> 474 <div id="selectPanel_sety"><div id="selectSetyList" class="modal-scroll-region" style="max-height:320px;overflow-y:auto;"></div></div> 475 <div id="selectPanel_jednotlive" style="display:none;"><div id="selectVybaveniList" class="modal-scroll-region" style="max-height:320px;overflow-y:auto;display:flex;flex-direction:column;gap:6px;"></div></div> 476 <button class="btn-blue" style="margin-top:14px;" onclick="window.potvrditVyberVybaveni()" data-i18n="garage_select_confirm">POTVRDIT VÃBÄR</button> 477 <button class="btn-cancel" style="display:block;margin-top:6px;" onclick="window.closeModal('selectVybaveniModal')" data-i18n="btn_zrusit">ZruÅ¡it</button> 478 </div> 479</div> 480 481<div id="vetZaznamModal" class="modal-overlay" style="display:none;" onclick="if(event.target===this)window.closeModal('vetZaznamModal')"> 482 <div class="modal-box" style="border-top-color:#1565c0;max-width:440px;"> 483 <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:18px;"> 484 <h2 id="vetModalTitle" style="margin:0;color:#1565c0;font-size:16px;" data-i18n="dog_vet_modal_title"><i data-icon="syringe"></i> Veterinárnà záznam</h2> 485 <button type="button" class="modal-close" onclick="window.closeModal('vetZaznamModal')" data-i18n="dog_modal_close_aria" data-i18n-attr="aria-label" aria-label="ZavÅÃt"><i data-icon="x-mark"></i></button> 486 </div> 487 <div style="display:flex;flex-direction:column;gap:14px;"> 488 <div> 489 <label style="font-size:11px;font-weight:900;text-transform:uppercase;color:var(--text-muted);letter-spacing:.4px;display:block;margin-bottom:6px;" data-i18n="dog_vet_modal_type">Typ úkonu</label> 490 <select id="typVakciny" style="font-size:16px !important;width:100%;height:44px;padding:0 12px;border:1.5px solid var(--border);border-radius:8px;background:var(--bg-surface);color:var(--text-primary);margin:0;box-sizing:border-box;"></select> 491 </div> 492 <div> 493 <label style="font-size:11px;font-weight:900;text-transform:uppercase;color:var(--text-muted);letter-spacing:.4px;display:block;margin-bottom:6px;"><span data-i18n="dog_vet_modal_date_app">Datum aplikace</span> <span style="color:#d32f2f;">*</span></label> 494 <input type="date" class="dt-input" id="datumOckovani"> 495 </div> 496 <div> 497 <label style="font-size:11px;font-weight:900;text-transform:uppercase;color:var(--text-muted);letter-spacing:.4px;display:block;margin-bottom:6px;">
498 <span data-i18n="dog_vet_modal_date_exp">Datum pÅÃÅ¡tà dávky / expirace</span> 499 <span style="font-weight:400;text-transform:none;font-size:10px;" data-i18n="dog_vet_modal_date_exp_hint"> (volitelné â zobrazà se jako pÅipomÃnka v kalendáÅi)</span> 500 </label> 501 <input type="date" class="dt-input" id="platnostDo"> 502 </div> 503 <div> 504 <label style="font-size:11px;font-weight:900;text-transform:uppercase;color:var(--text-muted);letter-spacing:.4px;display:block;margin-bottom:6px;"> 505 <span data-i18n="dog_vet_modal_note">Poznámka</span> 506 <span style="font-weight:400;text-transform:none;font-size:10px;" data-i18n="dog_vet_modal_note_hint"> (název pÅÃpravku, dávkaâ¦)</span> 507 </label> 508 <input type="text" id="vetPoznamka" data-i18n="dog_vet_modal_note_placeholder" data-i18n-attr="placeholder" placeholder="napÅ. Nobivac Rabies, 1 ml" style="font-size:16px !important;height:44px;width:100%;padding:0 12px;border:1.5px solid var(--border);border-radius:8px;background:var(--bg-surface);color:var(--text-primary);margin:0;box-sizing:border-box;"> 509 </div> 510 <div id="vetModalHint" style="background:#e3f2fd;border:1px solid #90caf9;border-radius:8px;padding:10px 12px;font-size:11px;color:#1565c0;line-height:1.5;" data-i18n="dog_vet_modal_hint"><i data-icon="calendar"></i> Záznam se automaticky zapÃÅ¡e do DenÃku jako veterinárnà událost. Pokud vyplnÃÅ¡ datum expirace, zobrazà se pÅipomÃnka v kalendáÅi.</div> 511 </div> 512 <input type="hidden" id="vetEditId"> 513 <button type="button" id="vetModalSaveBtn" class="btn-primary" onclick="window.ulozVetZaznam()" style="margin-top:18px;" data-i18n="dog_vet_modal_save">Uložit záznam</button> 514 <button type="button" class="btn-cancel btn-small" style="display:block;margin-top:8px;" onclick="window.closeModal('vetZaznamModal')" data-i18n="btn_zrusit">ZruÅ¡it</button> 515 </div> 516</div> 517 518<div id="dogProfileModal" class="modal-overlay" style="display: none;"> 519 <div id="dogProfileModalBox" class="modal-box dog-profile-modal-shell" style="max-width:500px;padding:0;overflow:hidden;"> 520 <div style="padding:18px 20px 12px;border-bottom:1px solid var(--border);display:flex;justify-content:space-between;align-items:center;"> 521 <div style="display:flex;align-items:center;gap:12px;"> 522 <div id="dogAvatarPreview" style="width:52px;height:52px;border-radius:50%;overflow:hidden;background:var(--bg-surface2);border:2px solid var(--border);flex-shrink:0;display:flex;align-items:center;justify-content:center;color:var(--maroon);"><i data-icon="paw" data-icon-size="24"></i></div> 523 <h2 id="dogModalTitle" style="margin:0;font-size:16px;" data-i18n="dog_modal_add">PÅIDAT PSA</h2> 524 </div> 525 <button class="modal-close" onclick="window.closeModal('dogProfileModal')" data-i18n="dog_modal_close_aria" data-i18n-attr="aria-label" aria-label="ZavÅÃt"><i data-icon="x-mark"></i></button> 526 </div> 527 <div class="dog-profile-tabs-scroll" style="border-bottom:2px solid var(--border);background:var(--bg-surface2);"> 528 <button id="dogTab_zakladni" class="dog-profile-tab dog-profile-tab-active" onclick="window.dogProfileTab('zakladni')" data-i18n="dog_tab_basic"><i data-icon="dog"></i> ZákladnÃ</button> 529 <button id="dogTab_sporty" class="dog-profile-tab" onclick="window.dogProfileTab('sporty')" data-i18n="dog_tab_sports"><i data-icon="trophy"></i> Sporty</button> 530 <button id="dogTab_sezona" class="dog-profile-tab" onclick="window.dogProfileTab('sezona')" data-i18n="dog_tab_season"><i data-icon="calendar"></i> Sezóna</button> 531 <button id="dogTab_treneri" class="dog-profile-tab" onclick="window.dogProfileTab('treneri')" data-i18n="dog_tab_trainers"><i data-icon="user-group"></i> TrenéÅi</button> 532 <button id="dogTab_veterina" class="dog-profile-tab" onclick="window.dogProfileTab('veterina')" data-i18n="dog_tab_vet"><i data-icon="heart"></i> Veterina</button> 533 </div> 534 <div class="modal-scroll-region dog-profile-modal-body" style="padding:16px 20px;overflow-y:auto;"> 535 <div id="dogPanel_zakladni"> 536 <div style="margin-bottom:14px;padding-bottom:14px;border-bottom:1px solid var(--border);"> 537 <label style="margin:0 0 8px;display:block;" data-i18n="dog_label_photo">Profilová fotka:</label> 538 <div style="display:flex;align-items:center;gap:14px;"> 539 <div id="dogPhotoCircle" style="width:80px;height:80px;border-radius:50%;overflow:hidden;background:var(--bg-surface2);border:2px dashed var(--border);flex-shrink:0;display:flex;align-items:center;justify-content:center;color:var(--maroon);"><i data-icon="paw" data-icon-size="32"></i></div> 540 <div id="dogPhotoUploadArea"></div> 541 </div> 542 <input type="hidden" id="dogPhotoBase64"> 543 </div> 544 <label data-i18n="dog_label_name">Jméno psa:</label><input type="text" id="dogName" placeholder="Max"> 545 <label data-i18n="dog_label_breed">Plemeno:</label><input type="text" id="dogBreed" data-i18n="dog_placeholder_breed" data-i18n-attr="placeholder" placeholder="NapÅ. Malamut, Husky, Mixbreedâ¦"> 546 <div class="grid-2"> 547 <div><label data-i18n="dog_label_gender">PohlavÃ:</label><select id="dogGender"><option value="pes">Pes</option><option value="fena">Fena</option></select></div> 548 <div><label data-i18n="dog_label_dob">Datum narozenÃ:</label><input type="date" class="date-input" id="dogDob"></div> 549 </div> 550 <div class="grid-2"> 551 <div><label data-i18n="dog_label_weight">Váha (kg):</label><input type="number" id="dogWeight" value="25"></div> 552 <div><label data-i18n="dog_label_height">Výška (cm):</label><input type="number" id="dogHeight" value="55"></div> 553 </div> 554 </div> 555 <div id="dogPanel_sporty" style="display:none;"> 556 <div class="label-with-help"><label style="margin:0;" data-i18n="dog_label_experience">ZkuÅ¡enost psa</label><button type="button" class="help-trigger" data-help-key="dog-ex
556perience" data-i18n="dog_help_aria_experience" data-i18n-attr="aria-label" aria-label="NápovÄda ke zkuÅ¡enosti psa"><i data-icon="information-circle" data-icon-size="16"></i></button></div> 557 <select id="dogExperience"></select> 558 <label style="margin-top:10px;" data-i18n="dog_label_sports_active">Aktivnà sporty a závodnà cÃlový Äas (min):</label> 559 <div class="dog-sport-list"> 560 <div class="dog-sport-row"><label class="dog-sport-label"><input type="checkbox" class="dog-sport-cb" onchange="window.toggleDogSportInput(this)" id="dogSportCC" checked> <span data-i18n="sport_canicross">Canicross</span></label><div class="dog-sport-time-wrap"><input type="number" class="dog-sport-time" id="dogTimeCC" value="25"></div></div> 561 <div class="dog-sport-row"><label class="dog-sport-label"><input type="checkbox" class="dog-sport-cb" onchange="window.toggleDogSportInput(this)" id="dogSportBKJ"> <span data-i18n="sport_bikejoring">Bikejoring</span></label><div class="dog-sport-time-wrap dog-sport-time-wrap--off"><input type="number" class="dog-sport-time" id="dogTimeBKJ" value="15" disabled></div></div> 562 <div class="dog-sport-row"><label class="dog-sport-label"><input type="checkbox" class="dog-sport-cb" onchange="window.toggleDogSportInput(this)" id="dogSportSC"> <span data-i18n="sport_scooterjoring">Scooterjoring</span></label><div class="dog-sport-time-wrap dog-sport-time-wrap--off"><input type="number" class="dog-sport-time" id="dogTimeSC" value="20" disabled></div></div> 563 <div class="dog-sport-row"><label class="dog-sport-label"><input type="checkbox" class="dog-sport-cb" onchange="window.toggleDogSportInput(this)" id="dogSportSKJ"> <span data-i18n="sport_skijoring">Skijoring</span></label><div class="dog-sport-time-wrap dog-sport-time-wrap--off"><input type="number" class="dog-sport-time" id="dogTimeSKJ" value="30" disabled></div></div> 564 <div class="dog-sport-row"><label class="dog-sport-label"><input type="checkbox" class="dog-sport-cb" onchange="window.toggleDogSportInput(this)" id="dogSportDT"> <span data-i18n="sport_dogtrekking">Dogtrekking</span></label><div class="dog-sport-time-wrap dog-sport-time-wrap--off"><input type="number" class="dog-sport-time" id="dogTimeDT" value="60" disabled></div></div> 565 <div class="dog-sport-row"><label class="dog-sport-label"><input type="checkbox" class="dog-sport-cb" onchange="window.toggleDogSportInput(this)" id="dogSportSZ"> <span data-i18n="sport_sprezeni">SpÅeženÃ</span></label><div class="dog-sport-time-wrap dog-sport-time-wrap--off"><input type="number" class="dog-sport-time" id="dogTimeSZ" value="45" disabled></div></div> 566 </div> 567 </div> 568 <div id="dogPanel_sezona" style="display:none;"> 569 <!-- 1. VRCHOL SEZÃNY ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ --> 570 <div class="race-peak-card" id="racePeak1Card" data-race-block="1"> 571 <button type="button" class="race-peak-header" onclick="window.toggleRacePeakCollapse(1)" aria-expanded="true" aria-controls="racePeak1Body"> 572 <span class="race-peak-title" data-i18n="dog_peak_title_1"><i data-icon="trophy"></i> 1. vrchol sezóny</span> 573 <span class="race-peak-summary" id="racePeak1Summary"></span> 574 <span class="race-peak-chevron" aria-hidden="true">?</span> 575 </button> 576 <div class="race-peak-body" id="racePeak1Body"> 577 <div style="margin-bottom:8px;"> 578 <label data-i18n="dog_label_race_discipline">DisciplÃna závodu:</label> 579 <select id="dogRaceSport" onchange="window.toggleRaceTargetInput(); window._updateRacePeakSummary(1);"></select> 580 </div> 581 <div class="grid-2" style="gap:8px;"> 582 <div><label data-i18n="dog_label_race_date">Datum závodu:</label><input type="date" class="date-input" id="dogRaceDate" onchange="window.onRaceDateChange(); window._updateRacePeakSummary(1);" oninput="window.onRaceDateChange(); window._updateRacePeakSummary(1);"></div> 583 <div><label data-i18n="dog_label_race_km">Délka trati (km):</label><input type="number" id="dogRaceKm" data-i18n="dog_placeholder_race_km" data-i18n-attr="placeholder" placeholder="NapÅ. 8" step="0.1" oninput="window._updateRacePeakSummary(1)"></div> 584 </div> 585 <div id="raceTargetPaceGroup" style="margin-top:8px;"> 586 <div class="label-with-help"><label style="margin:0;" data-i18n="dog_label_race_target_pace">CÃlový výkon (tempo min:sec / km)</label><button type="button" class="help-trigger" data-help-key="dog-race-target" data-i18n="dog_help_aria_race_target" data-i18n-attr="aria-label" aria-label="NápovÄda k závodnÃmu cÃli"><i data-icon="information-circle" data-icon-size="16"></i></button></div> 587 <div class="race-target-row"> 588 <input type="number" id="dogRaceTargetMin" class="race-target-input" data-i18n="dog_placeholder_min" data-i18n-attr="placeholder" placeholder="Min" min="0" max="59"><span style="font-size:13px;color:var(--text-muted);">:</span>
588<input type="number" id="dogRaceTargetSec" class="race-target-input" data-i18n="dog_placeholder_sec" data-i18n-attr="placeholder" placeholder="Sec" min="0" max="59"><span style="font-size:11px;color:var(--text-muted);" data-i18n="dog_unit_min_km">min/km</span> 589 </div> 590 </div> 591 <div id="raceTargetSpeedGroup" style="margin-top:8px;display:none;"> 592 <label data-i18n="dog_label_race_target_speed">CÃlová rychlost (km/h):</label> 593 <div class="race-target-row"> 594 <input type="number" id="dogRaceTargetSpeed" class="race-target-speed-input" data-i18n="dog_placeholder_race_speed" data-i18n-attr="placeholder" placeholder="NapÅ. 28" step="0.1" min="1" max="100"><span style="font-size:11px;color:var(--text-muted);" data-i18n="dog_unit_kmh">km/h</span> 595 </div> 596 </div> 597 </div> 598 </div> 599 600 <!-- 2. VRCHOL SEZÃNY (volitelný) ¦¦¦¦¦¦¦¦¦¦¦¦¦¦ --> 601 <div id="addSecondPeakBtnWrap" style="margin:10px 0 14px 0;"> 602 <button type="button" id="btnAddSecondPeak" class="btn-secondary btn-small" onclick="window.toggleSecondPeak(true)" style="width:100%;justify-content:center;display:flex;align-items:center;gap:6px;padding:10px;border:1.5px dashed var(--border-mid);border-radius:8px;background:transparent;color:var(--text-secondary);font-weight:700;cursor:pointer;" data-i18n="dog_peak_add_second"> 603 <i data-icon="plus"></i> PÅidat druhý vrchol sezóny 604 </button> 605 </div> 606 607 <div class="race-peak-card" id="secondPeakBlock" style="display:none;" data-race-block="2"> 608 <button type="button" class="race-peak-header" onclick="window.toggleRacePeakCollapse(2)" aria-expanded="true" aria-controls="racePeak2Body"> 609 <span class="race-peak-title" data-i18n="dog_peak_title_2"><i data-icon="trophy"></i> 2. vrchol sezóny</span> 610 <span class="race-peak-summary" id="racePeak2Summary"></span> 611 <span class="race-peak-remove" onclick="event.stopPropagation(); window.toggleSecondPeak(false);" data-i18n="dog_peak_remove_2_title" data-i18n-attr="title" title="Odebrat 2. vrchol">?</span> 612 <span class="race-peak-chevron" aria-hidden="true">?</span> 613 </button> 614 <div class="race-peak-body" id="racePeak2Body"> 615 <div style="margin-bottom:8px;"> 616 <label data-i18n="dog_label_race_discipline">DisciplÃna závodu:</label> 617 <select id="dogRace2Sport" onchange="window.toggleRaceTargetInput2(); window._updateRacePeakSummary(2);"></select> 618 </div> 619 <div class="grid-2" style="gap:8px;"> 620 <div><label data-i18n="dog_label_race_date">Datum závodu:</label><input type="date" class="date-input" id="dogRace2Date" onchange="window.onRaceDateChange(); window._updateRacePeakSummary(2);" oninput="window.onRaceDateChange(); window._updateRacePeakSummary(2);"></div> 621 <div><label data-i18n="dog_label_race_km">Délka trati (km):</label><input type="number" id="dogRace2Km" data-i18n="dog_placeholder_race_km" data-i18n-attr="placeholder" placeholder="NapÅ. 8" step="0.1" oninput="window._updateRacePeakSummary(2)"></div> 622 </div> 623 <div id="race2TargetPaceGroup" style="margin-top:8px;"> 624 <label style="margin:0;" data-i18n="dog_label_race_target_pace">CÃlový výkon (tempo min:sec / km)</label> 625 <div class="race-target-row"> 626 <input type="number" id="dogRace2TargetMin" class="race-target-input" data-i18n="dog_placeholder_min" data-i18n-attr="placeholder" placeholder="Min" min="0" max="59"><span style="font-size:13px;color:var(--text-muted);">:</span>
626<input type="number" id="dogRace2TargetSec" class="race-target-input" data-i18n="dog_placeholder_sec" data-i18n-attr="placeholder" placeholder="Sec" min="0" max="59"><span style="font-size:11px;color:var(--text-muted);" data-i18n="dog_unit_min_km">min/km</span> 627 </div> 628 </div> 629 <div id="race2TargetSpeedGroup" style="margin-top:8px;display:none;"> 630 <label data-i18n="dog_label_race_target_speed">CÃlová rychlost (km/h):</label> 631 <div class="race-target-row"> 632 <input type="number" id="dogRace2TargetSpeed" class="race-target-speed-input" data-i18n="dog_placeholder_race_speed" data-i18n-attr="placeholder" placeholder="NapÅ. 28" step="0.1" min="1" max="100"><span style="font-size:11px;color:var(--text-muted);" data-i18n="dog_unit_kmh">km/h</span> 633 </div> 634 </div> 635 </div> 636 </div> 637 <div id="periodizaceSection" style="display:none;border-top:1px solid var(--border);padding-top:14px;"> 638 <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:12px;gap:8px;flex-wrap:wrap;"> 639 <div style="font-size:12px;font-weight:900;text-transform:uppercase;letter-spacing:.5px;color:var(--orange);"><i data-icon="calendar"></i> <span data-i18n="dog_section_periodization">Rozloženà fázà sezóny k závodu</span> <button type="button" class="help-trigger" data-help-key="periodization" data-i18n="dog_help_aria_periodization" data-i18n-attr="aria-label" aria-label="NápovÄda k periodizaci"><i data-icon="information-circle" data-icon-size="16"></i></button></div> 640 <button type="button" class="btn-primary btn-small" onclick="window.navrhniPeriodizaci()" data-i18n="dog_phase_auto_suggest"><i data-icon="sparkles"></i> Automatický návrh</button> 641 </div> 642 643 <!-- CYKLUS 1 ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ --> 644 <div id="periodizaceCyklus1" class="periodizace-cyklus"> 645 <div class="periodizace-cyklus-title" id="cyklus1Title" data-i18n="dog_phase_cycle1_default">Cyklus 1 â Vrchol sezóny</div> 646 <div class="phase-block" data-phase="objem" style="border-left:4px solid #2e7d32;background:var(--bg-surface2);border-radius:6px;padding:10px 12px;margin-bottom:8px;"> 647 <div style="display:flex;align-items:center;gap:8px;margin-bottom:6px;"><span style="color:#2e7d32;"><i data-icon="bolt" data-icon-size="14"></i></span><span style="font-size:12px;font-weight:800;color:#2e7d32;">Objemová fáze</span></div> 648 <div class="phase-range-row"><input type="date" id="phaseObjem_od" class="phase-date-input date-input phase-range-input" onchange="window.validujPeriodizaci()"><span style="color:var(--text-muted);font-size:12px;">â</span><input type="date" id="phaseObjem_do" class="phase-date-input date-input phase-range-input" onchange="window.validujPeriodizaci()"></div> 649 </div> 650 <div class="phase-block" data-phase="priprava" style="border-left:4px solid #e65100;background:var(--bg-surface2);border-radius:6px;padding:10px 12px;margin-bottom:8px;"> 651 <div style="display:flex;align-items:center;gap:8px;margin-bottom:6px;"><span style="color:#e65100;"><i data-icon="fire" data-icon-size="14"></i></span><span style="font-size:12px;font-weight:800;color:#e65100;">PÅÃpravná fáze</span></div> 652 <div class="phase-range-row"><input type="date" id="phasePriprava_od" class="phase-date-input date-input phase-range-input" onchange="window.validujPeriodizaci()"><span style="color:var(--text-muted);font-size:12px;">â</span><input type="date" id="phasePriprava_do" class="phase-date-input date-input phase-range-input" onchange="window.validujPeriodizaci()"></div> 653 </div> 654 <div class="phase-block" data-phase="zavodni" style="border-left:4px solid #880e4f;background:var(--bg-surface2);border-radius:6px;padding:10px 12px;margin-bottom:8px;"> 655 <div style="display:flex;align-items:center;gap:8px;margin-bottom:6px;"><span style="color:#880e4f;"><i data-icon="trophy" data-icon-size="14"></i></span><span style="font-size:12px;font-weight:800;color:#880e4f;">Závodnà fáze</span></div> 656 <div class="phase-range-row"><input type="date" id="phaseZavodni_od" class="phase-date-input date-input phase-range-input" onchange="window.validujPeriodizaci()"><span style="color:var(--text-muted);font-size:12px;">â</span><input type="date" id="phaseZavodni_do" class="phase-date-input date-input phase-range-input" onchange="window.validujPeriodizaci()"></div> 657 </div> 658 <div class="phase-block" data-phase="prechodne" style="border-left:4px solid #1565c0;background:var(--bg-surface2);border-radius:6px;padding:10px 12px;margin-bottom:8px;"> 659 <div style="display:flex;align-items:center;gap:8px;margin-bottom:6px;"><span style="color:#1565c0;"><i data-icon="sun" data-icon-size="14"></i></span><span style="font-size:12px;font-weight:800;color:#1565c0;">PÅechodné obdobÃ</span></div> 660 <div class="phase-range-row"><input type="date" id="phasePrechodne_od" class="phase-date-input date-input phase-range-input" onchange="window.validujPeriodizaci()"><span style="color:var(--text-muted);font-size:12px;">â</span><input type="date" id="phasePrechodne_do" class="phase-date-input date-input phase-range-input" onchange="window.validujPeriodizaci()"></div> 661 </div> 662 </div> 663 664 <!-- CYKLUS 2 ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ --> 665 <div id="periodizaceCyklus2" class="periodizace-cyklus" style="display:none;"> 666 <div class="periodizace-cyklus-title" id="cyklus2Title">Cyklus 2 â Vrchol sezóny</div> 667 <div class="phase-block" data-phase="objem" style="border-left:4px solid #2e7d32;background:var(--bg-surface2);border-radius:6px;padding:10px 12px;margin-bottom:8px;"> 668 <div style="display:flex;align-items:center;gap:8px;margin-bottom:6px;"><span style="color:#2e7d32;"><i data-icon="bolt" data-icon-size="14"></i></span><span style="font-size:12px;font-weight:800;color:#2e7d32;">Objemová fáze (2)</span></div> 669 <div class="phase-range-row"><input type="date" id="phaseObjem2_od" class="phase-date-input date-input phase-range-input" onchange="window.validujPeriodizaci()"><span style="color:var(--text-muted);font-size:12px;">â</span><input type="date" id="phaseObjem2_do" class="phase-date-input date-input phase-range-input" onchange="window.validujPeriodizaci()"></div> 670 </div> 671 <div class="phase-block" data-phase="priprava" style="border-left:4px solid #e65100;background:var(--bg-surface2);border-radius:6px;padding:10px 12px;margin-bottom:8px;"> 672 <div style="display:flex;align-items:center;gap:8px;margin-bottom:6px;"><span style="color:#e65100;"><i data-icon="fire" data-icon-size="14"></i></span><span style="font-size:12px;font-weight:800;color:#e65100;">PÅÃpravná fáze (2)</span></div> 673 <div class="phase-range-row"><input type="date" id="phasePriprava2_od" class="phase-date-input date-input phase-range-input" onchange="window.validujPeriodizaci()"><span style="color:var(--text-muted);font-size:12px;">â</span><input type="date" id="phasePriprava2_do" class="phase-date-input date-input phase-range-input" onchange="window.validujPeriodizaci()"></div> 674 </div> 675 <div class="phase-block" data-phase="zavodni" style="border-left:4px solid #880e4f;background:var(--bg-surface2);border-radius:6px;padding:10px 12px;margin-bottom:8px;"> 676 <div style="display:flex;align-items:center;gap:8px;margin-bottom:6px;"><span style="color:#880e4f;"><i data-icon="trophy" data-icon-size="14"></i></span><span style="font-size:12px;font-weight:800;color:#880e4f;">Závodnà fáze (2)</span></div> 677 <div class="phase-range-row"><input type="date" id="phaseZavodni2_od" class="phase-date-input date-input phase-range-input" onchange="window.validujPeriodizaci()"><span style="color:var(--text-muted);font-size:12px;">â</span><input type="date" id="phaseZavodni2_do" class="phase-date-input date-input phase-range-input" onchange="window.validujPeriodizaci()"></div> 678 </div> 679 <div class="phase-block" data-phase="prechodne" style="border-left:4px solid #1565c0;background:var(--bg-surface2);border-radius:6px;padding:10px 12px;margin-bottom:8px;"> 680 <div style="display:flex;align-items:center;gap:8px;margin-bottom:6px;"><span style="color:#1565c0;"><i data-icon="sun" data-icon-size="14"></i></span><span style="font-size:12px;font-weight:800;color:#1565c0;">PÅechodné obdobà (2)</span></div> 681 <div class="phase-range-row"><input type="date" id="phasePrechodne2_od" class="phase-date-input date-input phase-range-input" onchange="window.validujPeriodizaci()"><span style="color:var(--text-muted);font-size:12px;">â</span><input type="date" id="phasePrechodne2_do" class="phase-date-input date-input phase-range-input" onchange="window.validujPeriodizaci()"></div> 682 </div> 683 </div> 684 685 <div id="periodizaceValidace" style="font-size:11px;margin-top:4px;min-height:18px;"></div> 686 </div> 687 </div> 688 <div id="dogPanel_treneri" style="display:none;"> 689 <div style="font-size:12px;font-weight:900;text-transform:uppercase;letter-spacing:.5px;color:var(--orange);margin-bottom:10px;"><i data-icon="user-group"></i> <span data-i18n="dog_section_trainer_share">SdÃlenà s trenérem</span> <button type="button" class="help-trigger" data-help-key="dog-trainer" data-i18n="dog_help_aria_trainer" data-i18n-attr="aria-label" aria-label="NápovÄda ke sdÃlenà s trenérem"><i data-icon="information-circle" data-icon-size="16"></i></button></div> 690 <div style="font-size:12px;color:var(--text-secondary);margin-bottom:14px;line-height:1.5;" data-i18n="dog_trainer_intro">Zadej e-mail svého trenéra. Trenér uvidà profil psa a může zapisovat plánované tréninky. PÅÃstup můžeÅ¡ kdykoliv odebrat.</div> 691 <label data-i18n="dog_label_trainer_email">E-mail trenéra:</label> 692 <div style="display:flex;gap:8px;align-items:flex-start;"> 693 <input type="email" id="trainerEmail" placeholder="trené[email protected]" style="flex:1;"> 694 <button type="button" class="btn-primary btn-small" onclick="window.pridatTrenera()" style="margin-top:6px;" data-i18n="dog_trainer_add_btn">+ PÅidat</button> 695 </div> 696 <div id="trenerList" style="margin-top:14px;display:flex;flex-direction:column;gap:6px;"></div> 697 <div id="trenerMsg" style="font-size:12px;margin-top:8px;min-height:18px;"></div> 698 <button type="button" onclick="window.diagnostikaTrener&&window.diagnostikaTrener()" style="margin-top:10px;background:none;border:1px solid var(--border);color:var(--text-secondary);border-radius:6px;padding:6px 12px;font-size:11px;cursor:pointer;width:auto;min-height:0;" data-i18n="dog_trainer_test_link"><i data-icon="information-circle"></i> Otestovat propojenà s trenérem</button> 699 </div> 700 <div id="dogPanel_veterina" style="display:none;"> 701 702 <!-- ÄÃslo Äipu --> 703 <div style="margin-bottom:20px;"> 704 <label style="font-size:11px;font-weight:900;text-transform:uppercase;color:var(--text-muted);letter-spacing:.4px;display:block;margin-bottom:8px;" data-i18n="dog_vet_chip_section">🔌 ÄÃslo Äipu</label> 705 <div style="display:flex;gap:8px;flex-wrap:wrap;"> 706 <input type="text" id="dogChipNumber" 707 class="vet-chip-input" 708 data-i18n="dog_vet_chip_placeholder" data-i18n-attr="placeholder" 709 placeholder="15mÃstné ÄÃslo Äipu" 710 maxlength="20" 711 inputmode="numeric" 712 style="flex:1 1 160px;"> 713 <button type="button" onclick="window.kopirovatChip('dogChipNumber',this)" class="vet-chip-copy-btn"> 714 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
715 <span data-i18n="dog_vet_chip_copy">KopÃrovat</span> 716 </button> 717 </div> 718 <div style="font-size:11px;color:var(--text-muted);margin-top:6px;" data-i18n="dog_vet_chip_hint">ÄÃslo Äipu se uložà s profilem psa a lze jej kdykoli zkopÃrovat.</div> 719 </div> 720 721 <!-- Veterinárnà záznamy --> 722 <div> 723 <div style="display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:12px;"> 724 <label style="font-size:11px;font-weight:900;text-transform:uppercase;color:var(--text-muted);letter-spacing:.4px;margin:0;" data-i18n="dog_vet_records_section">📒 Veterinárnà záznamy</label> 725 <button type="button" onclick="window.otevritVetModal()" 726 style="background:#1565c0;color:#fff;border:none;border-radius:7px;padding:7px 13px;font-size:12px;font-weight:900;cursor:pointer;margin:0;min-height:0;width:auto;white-space:nowrap;flex-shrink:0;" data-i18n="dog_vet_add_record"> 727 + PÅidat záznam 728 </button> 729 </div> 730 <div id="dogVaxContainer"></div> 731 </div> 732 733 </div> 734 735 </div> 736 <div style="padding:12px 20px;border-top:1px solid var(--border);display:flex;flex-direction:column;gap:8px;"> 737 <button class="btn-blue" onclick="window.ulozitProfilPsa()"><span data-i18n="btn_ulozit_profil">ULOŽIT PROFIL</span></button> 738 <button type="button" id="btnDeleteDog" class="btn-danger" style="display:none;" onclick="window.smazatPsa()" data-i18n="btn_smazat_psa">SMAZAT PSA</button> 739 </div> 740 </div> 741</div> 742 743<!-- Modal: pÅedánà psa novému majiteli --> 744<div id="dogTransferModal" class="modal-overlay" style="display:none;" role="dialog" aria-modal="true" aria-labelledby="dogTransferTitle"> 745 <div class="modal-box" style="max-width:460px;border-top-color:#2e7d32;"> 746 <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:14px;border-bottom:1px solid var(--border);padding-bottom:10px;"> 747 <h2 id="dogTransferTitle" style="margin:0;color:#2e7d32;font-size:16px;" data-i18n="dog_transfer_title"><i data-icon="user-group"></i> PÅedat psa novému majiteli</h2> 748 <button type="button" class="modal-close" onclick="window.closeModal('dogTransferModal')" data-i18n="dog_modal_close_aria" data-i18n-attr="aria-label" aria-label="ZavÅÃt"><i data-icon="x-mark"></i></button> 749 </div> 750 <div style="text-align:center;padding:6px 0 14px;"> 751 <div style="line-height:1;margin-bottom:8px;color:var(--maroon);display:flex;justify-content:center;gap:8px;align-items:center;"><i data-icon="dog" data-icon-size="42"></i><i data-icon="arrows-pointing-out" data-icon-size="24"></i><i data-icon="dog" data-icon-size="42"></i></div> 752 <p id="dogTransferIntro" style="font-size:13px;color:var(--text-primary);margin:0 0 6px;font-weight:700;" data-i18n="dog_transfer_intro"> 753 PÅedat psa <strong id="dogTransferName" style="color:#2e7d32;"></strong> jinému uživateli aplikace 754 </p> 755 <p style="font-size:11px;color:var(--text-secondary);line-height:1.6;margin:0 8px;" data-i18n="dog_transfer_body"> 756 PoÅ¡lete pozvánku e-mailem. Nový majitel ji uvidà po pÅihlášenÃ.<br> 757 Po jeho potvrzenà se vám pes <strong>i s historiÃ, veterinou a vybavenÃm</strong> zmizà ze seznamu. 758 </p> 759 </div> 760 <div style="margin-bottom:14px;"> 761 <label for="dogTransferEmail" style="display:block;font-size:12px;font-weight:700;color:var(--text-secondary);margin-bottom:6px;" data-i18n="dog_transfer_email_label">E-MAIL NOVÃHO MAJITELE:</label> 762 <input type="email" id="dogTransferEmail" class="form-input" data-i18n="dog_transfer_email_placeholder" data-i18n-attr="placeholder" placeholder="[email protected]" autocomplete="off" style="width:100%;font-size:16px;padding:10px;border:1.5px solid var(--border-mid);border-radius:8px;background:var(--bg-input);color:var(--text-primary);"> 763 <div style="font-size:10px;color:var(--text-muted);margin-top:6px;" data-i18n="dog_transfer_warning"> 764 <i data-icon="exclamation-triangle" data-icon-class="icon-warning"></i> PÅedánà nelze vrátit â po pÅijetà jsou vÅ¡echna data nového majitele. 765 </div> 766 </div> 767 <div style="display:flex;gap:8px;"> 768 <button class="btn-cancel" onclick="window.closeModal('dogTransferModal')" style="flex:1;margin:0;" data-i18n="btn_zrusit">ZruÅ¡it</button> 769 <button id="btnDogTransferConfirm" type="button" style="flex:1;margin:0;background:#2e7d32;color:#fff;border:none;padding:12px 14px;border-radius:8px;font-weight:800;font-size:13px;
769cursor:pointer;min-height:44px;" data-i18n="dog_transfer_send"> 770 <i data-icon="paper-airplane"></i> Odeslat pozvánku 771 </button> 772 </div> 773 </div> 774</div> 775 776<!-- Modal: pÅÃjem pozvánky k pÅedánà psa (pro pÅÃjemce) --> 777<div id="dogTransferIncomingModal" class="modal-overlay" style="display:none;" role="dialog" aria-modal="true" aria-labelledby="dogTransferIncomingTitle"> 778 <div class="modal-box" style="max-width:480px;border-top-color:#2e7d32;"> 779 <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:14px;border-bottom:1px solid var(--border);padding-bottom:10px;"> 780 <h2 id="dogTransferIncomingTitle" style="margin:0;color:#2e7d32;font-size:16px;" data-i18n="dog_transfer_incoming_title"><i data-icon="gift"></i> PÅebÃráte psa</h2> 781 <button type="button" class="modal-close" onclick="window.closeModal('dogTransferIncomingModal')" data-i18n="dog_modal_close_aria" data-i18n-attr="aria-label" aria-label="ZavÅÃt"><i data-icon="x-mark"></i></button> 782 </div> 783 <div style="text-align:center;padding:6px 0 14px;"> 784 <div style="line-height:1;margin-bottom:8px;color:var(--maroon);"><i data-icon="dog" data-icon-size="54"></i></div> 785 <p id="dogTransferIncomingIntro" style="font-size:14px;color:var(--text-primary);margin:0 0 8px;font-weight:700;" data-i18n="dog_transfer_incoming_from"> 786 <strong id="dogTransferIncomingFrom" style="color:#2e7d32;"></strong> vám pÅedává psa 787 </p> 788 <p style="font-size:18px;color:var(--text-primary);margin:0 0 12px;font-weight:900;"> 789 <span id="dogTransferIncomingDogName"></span> 790 </p> 791 <p style="font-size:12px;color:var(--text-secondary);line-height:1.6;margin:0 8px;" data-i18n="dog_transfer_incoming_body"> 792 Po pÅijetà zÃskáte: profil psa, kompletnà historii tréninků, veterinárnà záznamy<br> 793 a vÅ¡echno propojené vybavenÃ. 794 </p> 795 <div id="dogTransferIncomingMeta" style="margin:14px 8px 0;font-size:11px;color:var(--text-muted);text-align:left;background:var(--bg-surface);padding:10px;border-radius:8px;line-height:1.5;"></div> 796 </div> 797 <div style="display:flex;gap:8px;"> 798 <button id="btnDogTransferDecline" type="button" style="flex:1;margin:0;background:transparent;color:var(--text-secondary);border:1.5px solid var(--border-mid);padding:12px 14px;border-radius:8px;font-weight:700;font-size:13px;cursor:pointer;min-height:44px;" data-i18n="dog_transfer_decline"> 799 <i data-icon="x-mark"></i> OdmÃtnout 800 </button> 801 <button id="btnDogTransferAccept" type="button" style="flex:1;margin:0;background:#2e7d32;color:#fff;border:none;padding:12px 14px;border-radius:8px;font-weight:800;font-size:13px;cursor:pointer;min-height:44px;" data-i18n="dog_transfer_accept"> 802 <i data-icon="check"></i> PÅijmout psa 803 </button> 804 </div> 805 </div> 806</div> 807 808<!-- Modal: pes zemÅel (datum úmrtÃ) --> 809<div id="dogDeceasedModal" class="modal-overlay" style="display:none;" role="dialog" aria-modal="true" aria-labelledby="dogDeceasedTitle"> 810 <div class="modal-box" style="max-width:440px;border-top-color:#7e57c2;"> 811 <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:14px;border-bottom:1px solid var(--border);padding-bottom:10px;"> 812 <h2 id="dogDeceasedTitle" style="margin:0;color:#7e57c2;font-size:16px;" data-i18n="dog_deceased_title"><i data-icon="rainbow"></i> SÃÅ slávy</h2> 813 <button type="button" class="modal-close" onclick="window.closeModal('dogDeceasedModal')" data-i18n="dog_modal_close_aria" data-i18n-attr="aria-label" aria-label="ZavÅÃt"><i data-icon="x-mark"></i></button> 814 </div> 815 <div style="text-align:center;padding:12px 0 18px;"> 816 <div style="line-height:1;margin-bottom:10px;color:#7e57c2;"><i data-icon="rainbow" data-icon-size="48"></i></div> 817 <p style="font-size:14px;color:var(--text-primary);margin:0 0 8px;font-weight:700;
817" data-i18n="dog_deceased_sympathy"> 818 Mrzà nás vaÅ¡e ztráta. 819 </p> 820 <p id="dogDeceasedBody" style="font-size:12px;color:var(--text-secondary);line-height:1.6;margin:0 8px;" data-i18n="dog_deceased_body"> 821 Pes <strong id="dogDeceasedName" style="color:var(--text-primary);"></strong> bude pÅesunut do SÃnÄ slávy.<br> 822 Profil i historii tréninků zachováme, ale nebude možné pÅidávat nové aktivity ani upravovat profil. 823 </p> 824 </div> 825 <div style="margin-bottom:14px;"> 826 <label for="dogDeceasedDate" style="display:block;font-size:12px;font-weight:700;color:var(--text-secondary);margin-bottom:6px;" data-i18n="dog_deceased_date_label">DATUM ÃMRTÃ:</label> 827 <input type="date" id="dogDeceasedDate" class="date-input" style="width:100%;font-size:16px;"> 828 </div> 829 <div style="display:flex;gap:8px;"> 830 <button class="btn-cancel" onclick="window.closeModal('dogDeceasedModal')" style="flex:1;margin:0;" data-i18n="btn_zrusit">ZruÅ¡it</button> 831 <button id="btnDogDeceasedConfirm" type="button" style="flex:1;margin:0;background:#7e57c2;color:#fff;border:none;padding:12px 14px;border-radius:8px;font-weight:800;font-size:13px;cursor:pointer;min-height:44px;" data-i18n="dog_deceased_confirm"> 832 <i data-icon="rainbow"></i> PÅesunout do SÃnÄ slávy 833 </button> 834 </div> 835 </div> 836</div> 837 838<!-- Modal: výbÄr důvodu mazánà psa --> 839<div id="dogDeleteChoiceModal" class="modal-overlay" style="display:none;" role="dialog" aria-modal="true" aria-labelledby="dogDeleteChoiceTitle"> 840 <div class="modal-box" style="max-width:460px;border-top-color:#b71c1c;"> 841 <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:14px;border-bottom:1px solid var(--border);padding-bottom:10px;"> 842 <h2 id="dogDeleteChoiceTitle" style="margin:0;color:#b71c1c;font-size:16px;"><span data-i18n="dog_delete_choice_title">Smazat psa:</span> <span id="dogDeleteChoiceName" style="color:var(--text-primary);"></span></h2> 843 <button type="button" class="modal-close" onclick="window.closeModal('dogDeleteChoiceModal')" data-i18n="dog_modal_close_aria" data-i18n-attr="aria-label" aria-label="ZavÅÃt"><i data-icon="x-mark"></i></button> 844 </div> 845 <p style="font-size:12px;color:var(--text-secondary);margin:0 0 14px;line-height:1.5;" data-i18n="dog_delete_choice_intro"> 846 Vyberte důvod, proÄ chcete psa odebrat. Každá volba má jiné dopady na vaÅ¡e data. 847 </p> 848 <div style="display:flex;flex-direction:column;gap:10px;"> 849 <button type="button" id="dogDeleteOpt_died" class="dog-delete-opt" style="text-align:left;padding:14px;border:1.5px solid var(--border-mid);background:var(--bg-surface);color:var(--text-primary);border-radius:10px;cursor:pointer;font-size:13px;line-height:1.5;min-height:44px;"> 850 <strong style="display:block;margin-bottom:4px;font-size:14px;" data-i18n="dog_delete_opt_died_title"><i data-icon="rainbow"></i> Pes zemÅel</strong> 851 <span style="color:var(--text-secondary);font-size:12px;" data-i18n="dog_delete_opt_died_desc">PÅesune se do SÃnÄ slávy. Zachová profil, historii i možnost porovnánÃ. NepoÄÃtá se do FREE limitu.</span> 852 </button> 853 <button type="button" id="dogDeleteOpt_mistake" class="dog-delete-opt" style="text-align:left;padding:14px;border:1.5px solid var(--border-mid);background:var(--bg-surface);color:var(--text-primary);border-radius:10px;cursor:pointer;font-size:13px;line-height:1.5;min-height:44px;"> 854 <strong style="display:block;margin-bottom:4px;font-size:14px;" data-i18n="dog_delete_opt_mistake_title"><i data-icon="trash"></i> Omylem založen</strong> 855 <span style="color:var(--text-secondary);font-size:12px;" data-i18n="dog_delete_opt_mistake_desc">Trvale smaže profil, historii tréninků, veterinu a propojenà s vybavenÃm. Nelze vrátit zpÄt.</span> 856 </button> 857 <button type="button" id="dogDeleteOpt_transfer" class="dog-delete-opt" style="text-align:left;padding:14px;border:1.5px solid var(--border-mid);background:var(--bg-surface);color:var(--text-primary);border-radius:10px;cursor:pointer;font-size:13px;line-height:1.5;min-height:44px;"> 858 <strong style="display:block;margin-bottom:4px;font-size:14px;" data-i18n="dog_delete_opt_transfer_title"><i data-icon="user-group"></i> Pes má nového majitele</strong>
859 <span style="color:var(--text-secondary);font-size:12px;" data-i18n="dog_delete_opt_transfer_desc">PÅedá psa vÄetnÄ vÅ¡ech dat jinému uživateli aplikace (pÅes pozvánku e-mailem).</span> 860 </button> 861 </div> 862 <div style="margin-top:14px;display:flex;justify-content:flex-end;"> 863 <button class="btn-cancel" onclick="window.closeModal('dogDeleteChoiceModal')" style="margin:0;" data-i18n="btn_zrusit">ZruÅ¡it</button> 864 </div> 865 </div> 866</div> 867 868<div id="widgetNastaveniModal" class="modal-overlay" style="display: none;"> 869 <div class="modal-box" style="border-top-color: #455a64; max-width: 480px;"> 870 <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:14px;border-bottom:1px solid var(--border);padding-bottom:10px;"> 871 <h2 style="margin:0;color:#455a64;" data-i18n="dashboard_widget_settings_title"><i data-icon="cog-6-tooth"></i> Správa widgetů</h2> 872 <button type="button" class="modal-close" onclick="window.closeModal('widgetNastaveniModal')" aria-label="ZavÅÃt"><i data-icon="x-mark"></i></button> 873 </div> 874 <p style="font-size:12px; color:#757575; margin-bottom:15px;" data-i18n="dashboard_widget_settings_intro">PÅetáhnÄte nebo použijte Å¡ipky pro zmÄnu poÅadÃ. Skryté widgety se neodstraÅujà â data zůstávajÃ.</p> 875 <div id="widgetNastaveniList" class="modal-scroll-region" style="max-height: 420px; overflow-y: auto; display:flex; flex-direction:column; gap:6px;"></div> 876 <div style="margin-top:15px; display:flex; gap:10px;"> 877 <button class="btn-danger btn-small" style="flex:1; margin:0;" onclick="window.resetWidgetConfig()"><span data-i18n="dashboard_widget_settings_reset">? Obnovit výchozÃ</span></button> 878 <button class="btn-cancel" style="display:block; flex:1; margin:0;" onclick="window.closeModal('widgetNastaveniModal')">ZavÅÃt</button> 879 </div> 880 </div> 881</div> 882 883<div class="app-shell"> 884<div class="container" id="mainApp"> 885 <div class="sticky-header"> 886 <div id="authPanel" class="auth-panel"> 887 <span id="userInfo" class="auth-panel__user">ZÃMEK: PÅIHLASTE SE PRO CLOUD</span> 888 <div class="auth-panel__actions"> 889 <span id="appVersionBadge" class="app-version-badge" title="Verze aplikace. Klikni pro changelog a kontrolu aktualizace." onclick="window._mmShowVersionModal && window._mmShowVersionModal()">v2.6.1</span> 890 <button id="helpToggleBtn" type="button" class="help-toggle-btn" onclick="window.toggleHelpMode()" title="NápovÄda zapnuta â klikni pro vypnutÃ" aria-label="PÅepnout interaktivnà nápovÄdu"><i data-icon="question-mark-circle" data-icon-size="16"></i></button> 891 <button id="btnLogin" class="btn-small btn-blue auth-panel__btn" type="button" onclick="window.prihlasitSe()" data-i18n="btn_prihlasit">PÅIHLÃSIT</button> 892 <button id="btnLogout" class="btn-small btn-cancel auth-panel__btn" type="button" style="display: none;" onclick="window.odhlasitSe()" data-i18n="btn_odhlasit">ODHLÃSIT</button> 893 <button type="button" id="btnBugReport" class="auth-panel__bug-btn" onclick="window.openBugReportModal()" title="Nahlásit chybu" aria-label="Nahlásit chybu"><i data-icon="exclamation-triangle" data-icon-size="15"></i> BUG</button> 894 </div> 895 </div> 896 <div class="sticky-header__row"> 897 <label class="label-dog" for="aktivniPes"><span class="label-dog__text" data-i18n="header_active_dog">AKTIVNà PES:</span> <span id="proBadge" class="badge-pro">PRO</span></label> 898 <button type="button" id="btnHeaderDogProfile" class="btn-header-profile" onclick="window.upravitProfilPsa()" aria-labelledby="headerDogProfileSrLabel"> 899 <span id="headerDogProfileSrLabel" class="visually-hidden" data-i18n="header_dog_profile_label">Profil aktivnÃho psa</span> 900 <span class="btn-header-profile-icon" aria-hidden="true"><i data-icon="paw"></i></span> 901 </button> 902 <select id="aktivniPes" class="sticky-header__select" onchange="window.zmenaPsa()"></select> 903 <button type="button" id="btnCreateFirstDog" class="btn-create-first-dog" onclick="window.otevritDogModal(false)" style="display:none;" data-i18n="header_create_first_dog"><i data-icon="plus"></i> VytvoÅit psa</button> 904 </div> 905 </div> 906 907 <div id="appObsah" class="overlay-zamek"> 908 <div id="tab-plan" class="tab-content" style="display: none;"> 909 <div class="plan-layout"> 910 <div class="planner-tabs-header" role="tablist" data-i18n="planner_tabs_aria" data-i18n-attr="aria-label" aria-label="Podsekce plánovaÄe"> 911 <button type="button" id="planTab_training" class="planner-tab planner-tab-active" role="tab" aria-selected="true" onclick="window.setPlanModuleView('training')"><span data-i18n="planner_module_training"><i data-icon="dog"></i> Co dnes trénovat</span></button> 912 <button type="button" id="planTab_gut" class="planner-tab" role="tab" aria-selected="false" onclick="window.setPlanModuleView('gut')"><span data-i18n="planner_module_gut"><i data-icon="droplet"></i> Gut trénink</span></button> 913 </div> 914 915 <!-- =Â= LEVà PANEL: FORMULÃÅ =Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â= --> 916 <div class="plan-form-panel"> 917 <div id="planGlobalHeader" class="plan-global-header"> 918 <div class="plan-global-header__title"><i data-icon="globe-alt"></i> <span data-i18n="planner_global_title">
918Globálnà parametry plánu</span></div> 919 <div class="plan-grid-2 plan-grid-2--dense"> 920 <div class="plan-field-cell"> 921 <label for="planGlobalDate" data-i18n="planner_label_date">Datum:</label> 922 <input type="date" class="date-input date-input--compact planner-field-compact" id="planGlobalDate"> 923 </div> 924 <div class="plan-field-cell"> 925 <label for="planGlobalTime" data-i18n="planner_label_time_short">Äas:</label> 926 <input type="time" class="date-input date-input--compact planner-field-compact" id="planGlobalTime" step="900"> 927 </div> 928 </div> 929 <div class="plan-field-stack plan-field-stack--dense"> 930 <label for="planGlobalPlace" data-i18n="planner_label_place">Tréninkové mÃsto:</label> 931 <div class="plan-place-row"> 932 <select id="planGlobalPlace" class="planner-field-compact"> 933 <option value="">Vyber tréninkové mÃstoâ¦</option> 934 <option value="__create__">+ VytvoÅit nové tréninkové mÃsto</option> 935 </select> 936 <button type="button" id="btnOpenLocationManager" class="plan-place-manage-btn" onclick="window.openManageLocationsModal()" data-i18n="planner_manage_locations_title" data-i18n-attr="title" title="Správa mÃst"><i data-icon="cog-6-tooth"></i></button> 937 </div> 938 </div> 939 <div class="plan-grid-2 plan-grid-2--dense plan-field-stack plan-field-stack--dense"> 940 <div class="plan-field-cell"> 941 <label data-i18n="planner_label_discipline">DisciplÃna:</label> 942 <select id="planSport" class="planner-field-compact" onchange="window.aktualizovatCilovyCas()"></select> 943 </div> 944 <div class="plan-field-cell"> 945 <div class="plan-field-label-row"> 946 <label for="faze" data-i18n="planner_label_season_phase">Fáze sezóny</label> 947 <button type="button" class="help-trigger help-trigger--plan-field" data-help-key="faze" data-i18n="planner_aria_help_phase" data-i18n-attr="aria-label" aria-label="NápovÄda k fázÃm tréninku"><i data-icon="information-circle" data-icon-size="14"></i></button> 948 </div> 949 <select id="faze" class="planner-field-compact" onchange="window._fazeManualOverride=true;window.analyzujAutopilotem();"> 950 <option value="0.2">PÅechodná</option> 951 <option value="0.4">Objemová</option> 952 <option value="0.7">Specifická</option> 953 <option value="1.0">ZávodnÃ</option> 954 </select> 955 </div> 956 </div> 957 <!-- PlánovaÄ generuje pouze 4 kategorie: TAH / OBJEM / VOLNO / KOMPENZACE. 958 Intervaly jsou slouÄeny do TAH (rozhodnutà struktury padá až pÅi zápisu). --> 959 <select id="pozadovanyTypTreninku" style="display:none;"> 960 <option value="Kontinuálnà tah" data-i18n="planner_cat_tah">TAH</option> 961 <option value="Dogtrekking" data-i18n="typ_dogtrekking">Dogtrekking</option> 962 <option value="Trénink na volno - objem" data-i18n="planner_cat_objem">OBJEM</option> 963 <option value="Dogfitness / PlavánÃ" data-i18n="planner_cat_kompenzace">KOMPENZACE</option> 964 </select> 965 <input type="hidden" id="cilovyCas" value="25"> 966 <!-- Aktuálnà poÄasà â primárnÄ auto-fill z forecastu, fallback ruÄnÄ --> 967 <div class="plan-weather-manual"> 968 <div class="plan-weather-manual__head">
969 <span><i data-icon="thermometer" data-icon-size="14"></i> <span data-i18n="planner_weather_current">AKTUÃLNà POÄASÃ</span></span> 970 <span id="plannerWeatherSource" class="plan-weather-manual__source"></span> 971 </div> 972 <div class="plan-grid-2 plan-grid-2--dense plan-weather-manual__grid"> 973 <div class="plan-field-cell"> 974 <label for="teplotaDnes" data-i18n="planner_temp_label">Teplota (°C):</label> 975 <input type="number" class="planner-field-compact" id="teplotaDnes" min="-30" max="40" step="1" data-i18n="planner_placeholder_enter" data-i18n-attr="placeholder" placeholder="Zadatâ¦" oninput="window.analyzujAutopilotem&&window.analyzujAutopilotem()"> 976 </div> 977 <div class="plan-field-cell"> 978 <label for="vlhkostDnes" data-i18n="planner_humidity_label">Vlhkost (%):</label> 979 <input type="number" class="planner-field-compact" id="vlhkostDnes" min="0" max="100" step="5" data-i18n="planner_placeholder_enter" data-i18n-attr="placeholder" placeholder="Zadatâ¦" oninput="window.analyzujAutopilotem&&window.analyzujAutopilotem()"> 980 </div> 981 </div> 982 </div> 983 </div> 984 <!-- CTA TLAÄÃTKO --> 985 <button type="button" id="btnVypocitejTrenink" class="plan-cta-btn" onclick="window.vypocitejVsechny({ interactive: true })" data-i18n="planner_btn_generate"> 986 Navrhni trénink na základÄ vstupnÃch dat 987 </button> 988 </div> 989 990 <!-- =Â= PRAVà PANEL: VÃSLEDKY =Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â=Â= --> 991 <div class="plan-result-panel"> 992 <div id="planView-training" class="plan-main-view" style="display:block;"> 993 <div id="vystupPlanuPrazdny" class="plan-empty-state" style="display:flex;flex-direction:column;align-items:center;justify-content:center;"> 994 <div style="margin-bottom:12px;color:var(--orange);"><i data-icon="compass" data-icon-size="36"></i></div> 995 <div style="font-size:15px;font-weight:700;color:var(--text-primary);margin-bottom:6px;" data-i18n="planner_empty_title">PlánovaÄ tréninku</div> 996 <div style="font-size:13px;color:var(--text-muted);" data-i18n="planner_empty_hint">Nastav zámÄr a podmÃnky vlevo<br>a klikni na <i data-icon="bolt" data-icon-size="14"></i> VYPOÄÃTAT</div> 997 <div id="plannerEmptyHistHint" class="plan-empty-hist-hint" style="display:none;" aria-live="polite"></div> 998 </div> 999 <div id="vystupPlanu" style="display:none;"></div> 1000 </div> 1001 <div id="planView-gut" class="plan-main-view" style="display:none;"> 1002 <div class="plan-section plan-gut-panel"> 1003 <div class="plan-gut-panel__head"> 1004 <span class="plan-gut-panel__title"><i data-icon="droplet" data-icon-size="14"></i> <span data-i18n="planner_gut_section_title">Gut Training (ZavodnÄnÃ)</span></span> 1005 <button type="button" class="help-trigger help-trigger--plan-field" data-help-key="gut" data-i18n="planner_aria_help_gut" data-i18n-attr="aria-label" aria-label="NápovÄda k gut trainingu"><i data-icon="information-circle" data-icon-size="14"></i></button> 1006 </div> 1007 <div class="plan-grid-2 plan-grid-2--dense"> 1008 <div class="plan-field-cell"> 1009 <label for="gutVahaPsa" data-i18n="planner_gut_weight_label">Váha psa (kg):</label> 1010 <input type="number" class="planner-field-compact" id="gutVahaPsa" min="5" max="50" step="0.5" placeholder="kg" oninput="window.gutUlozVahu();window.prepocitejGut()"> 1011 </div> 1012 <div id="gutHaraniNote" class="plan-gut
1012-harani-note" style="display:none;"><i data-icon="droplet" data-icon-class="icon-danger"></i> <span data-i18n="planner_gut_harani_note">Fena v háránà nebo do 60 dnà po háránà â zmÄna hmotnosti je způsobena zadržovánÃm vody. Gut Training plán zachovej beze zmÄny.</span></div> 1013 <div class="plan-field-cell"> 1014 <div class="plan-field-label-row"> 1015 <label for="gutDelkaPlan" data-i18n="planner_gut_plan_length_label">Délka plánu</label> 1016 <button type="button" class="help-trigger help-trigger--plan-field" data-help-key="gut-plan" data-i18n="planner_aria_help_gut_plan" data-i18n-attr="aria-label" aria-label="NápovÄda k délce gut training plánu"><i data-icon="information-circle" data-icon-size="14"></i></button> 1017 </div> 1018 <select id="gutDelkaPlan" class="planner-field-compact" onchange="window.prepocitejGut()"> 1019 <option value="15">15 týdnů â pohodové tempo</option> 1020 <option value="10" selected>10 týdnů â standard</option> 1021 <option value="5">5 týdnů â zrychlený</option> 1022 </select> 1023 </div> 1024 </div> 1025 <div class="plan-grid-2 plan-grid-2--dense plan-field-stack plan-field-stack--dense"> 1026 <div class="plan-field-cell"> 1027 <label for="gutStartDatum" data-i18n="planner_gut_start_label">ZahájenÃ:</label> 1028 <input type="date" class="date-input date-input--compact planner-field-compact" id="gutStartDatum" onchange="window.gutUlozStart(); window.prepocitejGut()"> 1029 </div> 1030 <div class="plan-field-cell"> 1031 <label for="gutCilDatum" data-i18n="planner_gut_race_date_label">Datum závodu:</label> 1032 <input type="date" class="date-input date-input--compact planner-field-compact" id="gutCilDatum" onchange="window.gutUlozCil()"> 1033 </div> 1034 </div> 1035 <label class="plan-gut-checkbox" for="gutManualniRezim"> 1036 <input type="checkbox" id="gutManualniRezim" onchange="window.gutToggleManual()"> 1037 <span data-i18n="planner_gut_manual_checkbox">ZavodÅoval/a jsem pÅed aplikacÃ</span> 1038 </label> 1039 <div id="gutManualniBlok" class="plan-gut-manual-block" style="display:none;"> 1040 <div class="plan-grid-2 plan-grid-2--dense"> 1041 <div class="plan-field-cell"> 1042 <label for="gutManualTahMl" data-i18n="planner_gut_manual_tah_label">Tah â aktuálnà objem (ml):</label> 1043 <input type="number" class="planner-field-compact" id="gutManualTahMl" data-i18n="zapis_placeholder_ml" data-i18n-attr="placeholder" placeholder="ml" oninput="window.gutUlozManual(); window.prepocitejGut()"> 1044 </div> 1045 <div class="plan-field-cell"> 1046 <label for="gutManualObjemMl" data-i18n="planner_gut_manual_objem_label">Objem â aktuálnà objem (ml):</label> 1047 <input type="number" class="planner-field-compact" id="gutManualObjemMl" data-i18n="zapis_placeholder_ml" data-i18n-attr="placeholder" placeholder="ml" oninput="window.gutUlozManual(); window.prepocitejGut()"> 1048 </div> 1049 </div> 1050 </div> 1051 <div id="gutVysledek" class="plan-gut
1051-results" style="display:none;"> 1052 <p class="plan-gut-types-label" data-i18n="planner_gut_types_scroll_label">Dávky podle typu dne â pÅejeÄte prstem</p> 1053 <div id="gutDnesniDavka" class="gut-rec-host"></div> 1054 <button type="button" id="gutPlanToggleBtn" class="plan-inline-toggle" onclick="window.toggleGutPlanDetail()" data-i18n="planner_gut_toggle_show"><i data-icon="clipboard-document"></i> Zobrazit celý plán</button> 1055 <div id="gutPlanDetail" style="overflow-x:auto;display:none;"> 1056 <table id="gutTabulkaPlan" style="width:100%;border-collapse:collapse;font-size:12px;border:1px solid var(--border);border-radius:6px;overflow:hidden;"> 1057 <thead><tr style="background:var(--bg-surface2);"><th style="padding:8px;text-align:left;border-bottom:1px solid var(--border);" data-i18n="planner_gut_table_week">Týden</th><th style="padding:8px;text-align:center;border-bottom:1px solid var(--border);"><i data-icon="bolt"></i> <span data-i18n="planner_gut_table_tah">Tah</span></th><th style="padding:8px;text-align:center;border-bottom:1px solid var(--border);"><i data-icon="map"></i> <span data-i18n="planner_gut_table_objem">Objem</span></th><th style="padding:8px;text-align:center;border-bottom:1px solid var(--border);"><i data-icon="sparkles"></i> <span data-i18n="planner_gut_table_spec">SpeciálnÃ</span></th><th style="padding:8px;text-align:center;border-bottom:1px solid var(--border);"><i data-icon="moon"></i> <span data-i18n="planner_gut_table_volno">Volno</span></th></tr></thead> 1058 <tbody id="gutTabulkaTelo"></tbody> 1059 </table> 1060 </div> 1061 </div> 1062 <div id="gutPrazdny" style="text-align:center;padding:12px;color:var(--text-muted);font-size:12px;" data-i18n="planner_gut_empty_hint">^ Zadej váhu psa pro výpoÄet plánu</div> 1063 </div> 1064 </div> 1065 </div> 1066 1067 </div> 1068 </div> 1069 1070 <div id="fullMapPickerModal" class="modal-overlay" style="display:none; z-index:9999;"> 1071 <div class="modal-box" style="max-width:90%; height:90vh; display:flex; flex-direction:column;"> 1072 <div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:10px;"> 1073 <h3 style="margin:0;" data-i18n="planner_map_title">Zvolit tréninkové mÃsto</h3> 1074 <button onclick="window.closeModal('fullMapPickerModal')" style="min-height:auto; width:auto; padding:5px 10px;"><i data-icon="x-mark"></i></button> 1075 </div> 1076 <div class="map-search-bar" style="position:relative;margin-bottom:10px;"> 1077 <div style="display:flex;gap:8px;"> 1078 <input type="text" id="fullMapSearchInput" class="settings-select" style="flex:1;min-width:0;font-size:16px!important;" data-i18n="planner_map_search_ph" data-i18n-attr="placeholder" placeholder="Hledat mÃsto (napÅ. název obce)â¦" autocomplete="off" onkeydown="if(event.key==='Enter'){event.preventDefault();window.fullMapSearchLocation();}"> 1079 <button type="button" class="btn-base btn-outline btn-small" style="width:auto;padding:0 14px;" onclick="window.fullMapSearchLocation()" data-i18n="planner_map_search_btn" data-i18n-attr="title" title="Hledat"><i data-icon="search"></i></button> 1080 </div> 1081 <div id="fullMapSearchResults" class="map-search-results" style="display:none;"></div> 1082 </div> 1083 <div id="fullMapContainer" class="full-map-picker" style="flex:1; border-radius:10px; border:1px solid var(--border); position:relative;"></div> 1084 <div style="margin-top:15px; display:flex; gap:10px;"> 1085 <button id="btnConfirmLocation" class="btn-primary" style="flex:1;"><i data-icon="check"></i> <span data-i18n="planner_map_confirm">Zvolit toto mÃsto</span></button> 1086 <button onclick="window.ziskatPocasiGPS('','')" style="width:auto; padding:0 15px;" data-i18n="planner_map_gps_title" data-i18n-attr="title" title="Moje poloha"><i data-icon="map-pin"></i></button> 1087 </div> 1088 </div> 1089 </div> 1090 <div id="manageLocationsModal" class="modal-overlay" style="display:none; z-index:9999;"> 1091 <div class="modal-box" style="max-width:520px;width:min(96vw,520px);"> 1092 <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;"> 1093 <h3 style="margin:0;" data-i18n="settings_locations_modal_title">Správa tréninkových mÃst</h3> 1094 <button type="button" onclick="window.closeModal('manageLocationsModal')" style="min-height:auto; width:auto; padding:5px 10px;"><i data-icon="x-mark"></i></button> 1095 </div> 1096 <div id="manageLocationsList" class="modal-scroll-region" style="display:grid;gap:8px;max-height:50vh;overflow:auto;"></div> 1097 </div> 1098 </div> 1099 <div id="tab-zapis" class="tab-content" style="display: none;"> 1100 <div id="modal-zapis" class="sekce zapis-form-compact" style="padding:0;overflow:visible;"> 1101 <div id="realizacePlanBanner" style="display:none;"></div> 1102 <div class="zapis-form-header"> 1103 <h2 id="nadpisFormulare" class="zapis-form-title" data-i18n="title_new_activity">ZAPSAT AKTIVITU</h2> 1104 </div> 1105 <div class="zapis-form-body"> 1106 1107 <!-- KROK 1: KDO & STAV --> 1108 <section class="zapis-step" data-step="1"> 1109 <header class="zapis-step-header">
1110 <span class="zapis-step-num">1</span> 1111 <span class="zapis-step-title" data-i18n="zapis_step1_title">Kdo a stav</span> 1112 </header> 1113 <div class="zapis-sekce-label"><i data-icon="dog"></i> <span data-i18n="zapis_step1_dogs">Psi v tréninku</span></div> 1114 <div id="smeckaPsiCheckboxy" class="zapis-chip-row"></div> 1115 <div id="smeckaRpeBlok"> 1116 <div class="smecka-rpe-header" data-i18n="zapis_step1_rpe_each">RPE pro každého psa:</div> 1117 <div class="smecka-rpe-row" id="smeckaRpeRow"></div> 1118 </div> 1119 <div id="sekceSmecka" style="display:none;"></div> 1120 <div class="zapis-status-toggle"> 1121 <button type="button" id="statusToggleCompleted" onclick="window.setZapisStatus('completed')"><i data-icon="check"></i> <span data-i18n="zapis_status_completed">DokonÄeno</span></button> 1122 <button type="button" id="statusTogglePlanned" onclick="window.setZapisStatus('planned')"><i data-icon="document-text"></i> <span data-i18n="zapis_status_planned">Plánováno</span></button> 1123 </div> 1124 <input type="hidden" id="zapisStatus" value="completed"> 1125 </section> 1126 1127 <!-- KROK 2: CO --> 1128 <section class="zapis-step" data-step="2"> 1129 <header class="zapis-step-header"> 1130 <span class="zapis-step-num">2</span> 1131 <span class="zapis-step-title" data-i18n="zapis_step2_title">Co</span> 1132 </header> 1133 <div class="grid-2 zapis-grid-tight"> 1134 <div id="formGroupSport" class="form-group"><div class="label-with-help"><label style="margin:0;" data-i18n="label_sport">Druh sportu:</label><button type="button" class="help-trigger" data-help-key="sport" data-i18n="zapis_aria_help_sport" data-i18n-attr="aria-label" aria-label="NápovÄda k druhu sportu"><i data-icon="information-circle" data-icon-size="16"></i></button></div><select id="odjetySport"></select></div> 1135 <div> 1136 <div class="label-with-help"><label style="margin:0;" data-i18n="label_typ">Typ aktivity:</label><button type="button" class="help-trigger" data-help-key="activity-type" data-i18n="zapis_aria_help_typ" data-i18n-attr="aria-label" aria-label="NápovÄda k typu aktivity"><i data-icon="information-circle" data-icon-size="16"></i></button></div> 1137 <select id="odjetyTyp"> 1138 <option value="Kontinuálnà tah">ð Kontinuálnà tah</option><option value="Tah v kroku">ð Tah v kroku</option><option value="Intervaly">â±ï¸ Intervaly</option><option value="Intervaly do kopce">ðï¸ Intervaly do kopce</option><option value="Dogtrekking">𥾠Dogtrekking</option><option value="Závod">ð Závod</option><option value="Trénink na volno - objem">ð² Základnà vytrvalost</option><option value="Dogfitness">𤸠Dogfitness</option><option value="PlavánÃ">ð PlavánÃ</option><option value="Aquaterapie">ð¦ Aquaterapie</option><option value="Ostatnà aktivity">ð§© Ostatnà aktivity</option><option value="Poznámka">ðï¸ Poznámka</option><option value="REST DAY">ð¤ REST DAY</option><option value="zdravi">ð¥ ZDRAVà / VETERINA</option> 1139 </select> 1140 </div> 1141 </div> 1142 <div id="formGroupNazevAktivity" class="zapis-field-stack"><label id="labelNazevAktivity" data-i18n="zapis_label_nazev_optional">Název (volitelnÄ):</label><input type="text" id="nazevAktivity" data-i18n="zapis_placeholder_nazev" data-i18n-attr="placeholder" placeholder="NapÅ. Rannà výbÄh, Lesnà trasaâ¦"></div> 1143 <div id="sekceZavod" style="display:none;margin-top:12px;"><label style="margin-top:0;color:#ff8f00;font-size:12px;font-weight:900;text-transform:uppercase;letter-spacing:.4px;"><i data-icon="trophy"></i> Závod</label><input type="text" id="zavodNazev" placeholder="Název závodu"></div> 1144 <div id="sekceZdravi" class="form-group" style="display:none;background:#ffebee;padding:12px;border-left:4px solid #b71c1c;border-radius:0 var(--radius-sm) var(--radius-sm) 0;margin-top:14px;margin-bottom:0;"> 1145 <label style="color:#b71c1c;margin-top:0;font-size:12px;font-weight:900;text-transform:uppercase;letter-spacing:.4px;" data-i18n="zapis_zdravi_cat_label">Kategorie zdravà / péÄe:</label> 1146 <select id="zdraviKategorie" style="border-color:#b71c1c;" onchange="window.toggleKlidDo();window.toggleZdraviPodkategorie()"> 1147 <option value="Nemoc">Nemoc (Viróza, zažÃvánÃ...)</option><option value="Ãraz / ZranÄnÃ">Ãraz / ZranÄnÃ</option><option value="OÄkovánà / OdÄervenÃ">OÄkovánà / OdÄervenÃ</option><option value="Fyzioterapie / Masáž">Fyzioterapie / Masáž</option><option value="HáránÃ">Háránà (pouze feny)</option> 1148 </select> 1149 <div id="sekceZdraviPodkategorie" style="margin-top:8px;display:none;"> 1150 <label style="color:#b71c1c;" data-i18n="zapis_zdravi_vacc_label">Typ oÄkovánà / prevence:</label> 1151 <select id="typVakciny" style="border-color:#b71c1c;"> 1152 <option value="">Vyberte vakcÃnu...</option> 1153 <option value="Vzteklina">Vzteklina</option> 1154 <option value="DHPPi">DHPPi</option> 1155 <option value="L4">L4</option> 1156 <option value="KC">KC</option> 1157 <option value="Borelióza">Borelióza</option> 1158 <option value="Herpes">Herpes</option> 1159 </select> 1160 </div> 1161 <div id="sekcePlatnostDo" style="margin-top:8px;display:none;"> 1162 <label style="color:#b71c1c;" data-i18n="zapis_zdravi_valid_label">Platnost do (datum pÅeoÄkovánÃ):</label> 1163 <input type="date" class="date-input" id="platnostDo" style="border-color:#b71c1c;"> 1164 </div> 1165 <input type="hidden" id="datumOckovani"> 1166 <div id="sekceKlidDo" style="margin-top:8px;display:none;"><label id="klidDoLabel" style="color:#b71c1c;" data-i18n="zapis_zdravi_rest_label">Do kdy je naÅÃzen klid?</label><input type="date" class="date-input" id="zdraviKlidDo" style="border-color:#b71c1c;"></div> 1167 </div> 1168 </section> 1169 1170 <!-- KROK 3: KDE --> 1171 <section class="zapis-step" id="zapisStepKde" data-step="3"> 1172 <header class="zapis-step-header">
1173 <span class="zapis-step-num">3</span> 1174 <span class="zapis-step-title" data-i18n="zapis_step3_title">Kde</span> 1175 </header> 1176 <div id="sekceGpx" style="display:none;"> 1177 <label style="color:var(--orange);margin-top:0;font-size:12px;font-weight:900;text-transform:uppercase;letter-spacing:.4px;display:block;"><i data-icon="signal"></i> <span data-i18n="zapis_gpx_route_label">GPX / TCX / FIT trasa</span></label> 1178 <label id="gpxLabel" class="gpx-upload-zone" style="display:flex;align-items:center;gap:10px;background:var(--bg-surface);border:1.5px dashed var(--border-mid);border-radius:var(--radius-md);padding:10px 14px;cursor:pointer;margin-top:6px;transition:border-color 0.2s;text-transform:none;font-weight:600;font-size:13px;color:var(--text-secondary);"> 1179 <span class="gpx-upload-visual"> 1180 <span style="color:var(--orange);"><i data-icon="map" data-icon-size="20"></i></span><span id="gpxLabelText" data-i18n="zapis_gpx_pick_file">Kliknout a vybrat .gpx / .tcx / .fit soubor</span><span id="gpxLockIcon" class="gpx-lock-icon" style="display:none;"><i data-icon="lock-closed"></i></span> 1181 </span> 1182 <input type="file" id="gpxInput" class="gpx-file-input" accept="*/*" onchange="window.nahratGPX(event)"> 1183 </label> 1184 <div id="gpxStatus" style="margin-top:8px;font-size:12px;font-weight:bold;color:var(--text-muted);display:none;"></div> 1185 </div> 1186 <div id="sekceLokalitaZapis" style="display:none;margin-top:12px;"> 1187 <div class="zapis-sekce-label" style="display:flex;align-items:center;justify-content:space-between;gap:8px;flex-wrap:wrap;"> 1188 <span data-i18n="zapis_saved_location_label">MÃsto (lokalita)</span> 1189 <span id="zapisLocationProBadge" style="font-size:10px;font-weight:900;text-transform:uppercase;letter-spacing:.5px;color:var(--orange);border:1px solid var(--orange);padding:2px 8px;border-radius:6px;">PRO</span> 1190 </div> 1191 <p style="margin:6px 0 0;font-size:11px;color:var(--text-muted);line-height:1.35;" data-i18n="zapis_saved_location_help">Vyber uložené mÃsto, nebo pÅidej nové pÅÃmo tady.</p> 1192 <div class="plan-place-row" style="margin-top:6px;"> 1193 <select id="zapisSavedLocation" class="date-input date-input--compact zapis-field-compact"></select> 1194 <button type="button" id="btnZapisManageLocations" class="plan-place-manage-btn" onclick="window.openManageLocationsModal()" data-i18n="planner_manage_locations_title" data-i18n-attr="title" title="Správa mÃst"><i data-icon="cog-6-tooth"></i></button> 1195 </div> 1196 </div> 1197 </section> 1198 1199 <!-- KROK 4: KDY --> 1200 <section class="zapis-step" id="zapisStepKdy" data-step="4"> 1201 <header class="zapis-step-header"> 1202 <span class="zapis-step-num">4</span> 1203 <span class="zapis-step-title" data-i18n="zapis_step4_title">Kdy</span> 1204 </header> 1205 <div class="grid-2 zapis-grid-tight"> 1206 <div> 1207 <label data-i18n="zapis_label_datum">Datum:</label> 1208 <input type="date" class="date-input date-input--compact" id="odjetyDatum" onchange="window.zkontrolujDatumStatus()"> 1209 </div> 1210 <div id="wrapOdjetyCasSkutecnosti"> 1211 <label data-i18n="zapis_label_cas_treninku">Äas tréninku:</label> 1212 <input type="time" class="dt-input date-input--compact" id="odjetyCasSkutecnosti" step="60"> 1213 </div> 1214 </div> 1215 <div id="sekceDatumDo" class="grid-2 zapis-grid-tight zapis-field-stack" style="display:none;"> 1216 <div> 1217 <label data-i18n="zapis_label_datum_do">Konec (Do):</label> 1218 <input type="date" class="date-input date-input--compact" id="odjetyDatumDo"> 1219 </div> 1220 <div aria-hidden="true"></div> 1221 </div> 1222 </section> 1223 1224 <!-- KROK 5: METRIKY (výkon) --> 1225 <section class="zapis-step zapis-sekce--performance" id="zapisPerformanceBlock" data-step="5"> 1226 <header class="zapis-step-header">
1227 <span class="zapis-step-num">5</span> 1228 <span class="zapis-step-title" data-i18n="zapis_step5_title">Metriky (výkon)</span> 1229 </header> 1230 <p id="casWeatherHint" style="display:none;margin:0 0 10px;font-size:11px;color:#1565c0;font-weight:600;line-height:1.35;" data-i18n="zapis_cas_weather_hint">VyplÅte Äas tréninku u data, aby se poÄasà z mÃsta nahrálo správnÄ.</p> 1231 <div id="sekceVykon" class="zapis-perf-grid"> 1232 <div id="bunkasCas"><label id="labelCasu" style="margin-top:0;display:block;margin-bottom:6px;" data-i18n="zapis_label_cas_trvani">Äas (délka výkonu):</label> 1233 <div class="mm-dur-field"> 1234 <input type="number" class="mm-dur-cell mm-dur-h" min="0" max="99" step="1" inputmode="numeric" placeholder="0" data-i18n="zapis_dur_aria_hours" data-i18n-attr="aria-label" aria-label="Hodiny"> 1235 <span class="mm-dur-sep" data-i18n="duration_picker_hours">h</span> 1236 <input type="number" class="mm-dur-cell mm-dur-m" min="0" max="59" step="1" inputmode="numeric" placeholder="0" data-i18n="zapis_dur_aria_minutes" data-i18n-attr="aria-label" aria-label="Minuty"> 1237 <span class="mm-dur-sep" data-i18n="duration_picker_minutes">m</span> 1238 <input type="number" class="mm-dur-cell mm-dur-s" min="0" max="59" step="1" inputmode="numeric" placeholder="0" data-i18n="zapis_dur_aria_seconds" data-i18n-attr="aria-label" aria-label="Sekundy"> 1239 <span class="mm-dur-sep" data-i18n="duration_picker_seconds">s</span> 1240 <input type="hidden" id="odjetyCas" class="mm-duration-time"> 1241 </div> 1242 </div> 1243 <div id="bunkaVzdalenost"><label style="margin-top:0;display:block;margin-bottom:6px;" data-i18n="zapis_label_delka_km">Délka (km):</label><input type="text" id="odjetaVzdalenost" inputmode="decimal" data-i18n="zapis_placeholder_optional" data-i18n-attr="placeholder" placeholder="VolitelnÄ" oninput="this.value=this.value.replace(',','.')" style="margin-top:0;"></div> 1244 <div id="bunkaRpe"><div class="label-with-help"><label style="margin:0;" data-i18n="zapis_label_rpe">RPE (nároÄnost)</label><button type="button" class="help-trigger" data-help-key="rpe" data-i18n="zapis_aria_help_rpe" data-i18n-attr="aria-label" aria-label="NápovÄda k RPE"><i data-icon="information-circle" data-icon-size="16"></i></button></div><select id="narocnost" style="margin-top:0;"></select><div id="rpeVypocitane" style="display:none;"><div id="rpeVypocitanaHodnota" style="font-size:18px;font-weight:900;color:var(--maroon);line-height:1.2;margin-top:4px;">â</div></div></div> 1245 <div id="bunkaPrevyseni"><label style="margin-top:0;display:block;margin-bottom:6px;" data-i18n="zapis_label_prevyseni">PÅevýšenà (m):</label><input type="text" id="odjetePrevyseni" inputmode="decimal" data-i18n="zapis_placeholder_elevation" data-i18n-attr="placeholder" placeholder="NapÅ. 150" oninput="this.value=this.value.replace(',','.')" style="margin-top:0;"></div> 1246 </div> 1247 <div id="sekceIntervaly" class="sub-sekce" style="display:none;margin-top:12px;"> 1248 <div id="faze1Block" style="background:var(--bg-surface2);border-radius:var(--radius-sm);padding:10px 12px;margin-bottom:8px;border-left:3px solid #2e7d32;"> 1249 <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;"> 1250 <span style="font-size:11px;font-weight:700;color:#2e7d32;text-transform:uppercase;letter-spacing:.4px;display:inline-flex;align-items:center;gap:6px;"><span class="status-dot status-dot--green"></span> <span data-i18n="zapis_interval_phase1">Fáze 1 â Rozklus</span></span> 1251 <button type="button" onclick="window.odebratFazi(1)" style="background:none;border:none;color:var(--text-muted);cursor:pointer;font-size:12px;padding:0;margin:0;width:auto;min-height:0;font-weight:600;"><i data-icon="x-mark"></i> <span data-i18n="zapis_interval_remove">Odebrat</span></button> 1252 </div> 1253 <div style="display:grid;grid-template-columns:1fr 100px;gap:8px;"> 1254 <div><label style="font-size:11px;margin:0 0 2px;display:block;" data-i18n="zapis_interval_warmup_length">Délka rozklusu</label> 1255 <div class="mm-dur-field mm-dur-field--compact" data-mm-dur-oninput="window.prepocitejIntervaly && window.prepocitejIntervaly()"> 1256 <input type="number" class="mm-dur-cell mm-dur-h" min="0" max="99" step="1" inputmode="numeric" placeholder="0" aria-label="Hodiny">
1257 <span class="mm-dur-sep">h</span> 1258 <input type="number" class="mm-dur-cell mm-dur-m" min="0" max="59" step="1" inputmode="numeric" placeholder="0" aria-label="Minuty"> 1259 <span class="mm-dur-sep">m</span> 1260 <input type="number" class="mm-dur-cell mm-dur-s" min="0" max="59" step="1" inputmode="numeric" placeholder="0" aria-label="Sekundy"> 1261 <span class="mm-dur-sep">s</span> 1262 <input type="hidden" id="warmupCas" class="mm-duration-time"> 1263 </div> 1264 </div> 1265 <div><label style="font-size:11px;margin:0 0 2px;display:block;">RPE</label><select id="warmupRpe" class="input-interval-rpe" onchange="window.prepocitejIntervaly()"><option value="1">1</option><option value="2">2</option><option value="3">3</option><option value="4" selected>4</option><option value="5">5</option><option value="6">6</option><option value="7">7</option><option value="8">8</option><option value="9">9</option><option value="10">10</option></select></div> 1266 </div> 1267 </div> 1268 <button id="btnPridatRozklus" type="button" onclick="window.zobrazitFazi(1)" style="display:none;width:100%;margin-bottom:8px;background:var(--bg-surface2);color:#2e7d32;border:1px dashed #2e7d32;border-radius:var(--radius-sm);font-size:12px;font-weight:700;padding:8px;" data-i18n="zapis_interval_add_warmup">+ PÅidat rozklus</button> 1269 <div style="background:var(--bg-surface2);border-radius:var(--radius-sm);padding:10px 12px;margin-bottom:8px;border-left:3px solid #d32f2f;"> 1270 <div style="font-size:11px;font-weight:700;color:#d32f2f;text-transform:uppercase;letter-spacing:.4px;margin-bottom:10px;display:flex;align-items:center;gap:6px;"><span class="status-dot status-dot--red"></span> <span data-i18n="zapis_interval_phase2">Fáze 2 â Hlavnà motiv</span></div> 1271 <div id="intervalBuilder"></div> 1272 <div style="display:flex;gap:8px;margin-top:8px;"> 1273 <button type="button" id="btnPridatUsek" onclick="window.pridatUsek()" class="btn-danger btn-small" style="flex:1;max-width:none;" data-i18n="zapis_interval_add_segment">+ Ãsek</button> 1274 <button type="button" id="btnPridatPauzu" onclick="window.pridatPauzu()" class="btn-outline btn-small" style="flex:1;max-width:none;" data-i18n="zapis_interval_add_rest">+ Pauza</button> 1275 </div> 1276 </div> 1277 <div id="faze3Block" style="background:var(--bg-surface2);border-radius:var(--radius-sm);padding:10px 12px;margin-bottom:8px;border-left:3px solid #1565c0;"> 1278 <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;"> 1279 <span style="font-size:11px;font-weight:700;color:#1565c0;text-transform:uppercase;letter-spacing:.4px;display:inline-flex;align-items:center;gap:6px;"><span class="status-dot status-dot--blue"></span> <span data-i18n="zapis_interval_phase3">Fáze 3 â Výklus</span></span> 1280 <button type="button" onclick="window.odebratFazi(3)" style="background:none;border:none;color:var(--text-muted);cursor:pointer;font-size:12px;padding:0;margin:0;width:auto;min-height:0;font-weight:600;"><i data-icon="x-mark"></i> <span data-i18n="zapis_interval_remove">Odebrat</span></button> 1281 </div> 1282 <div style="display:grid;grid-template-columns:1fr 100px;gap:8px;"> 1283 <div><label style="font-size:11px;margin:0 0 2px;display:block;" data-i18n="zapis_interval_cooldown_length">Délka výklusu</label> 1284 <div class="mm-dur-field mm-dur-field--compact" data-mm-dur-oninput="window.prepocitejIntervaly && window.prepocitejIntervaly()"> 1285 <input type="number" class="mm-dur-cell mm-dur-h" min="0" max="99" step="1" inputmode="numeric" placeholder="0" aria-label="Hodiny">
1286 <span class="mm-dur-sep">h</span> 1287 <input type="number" class="mm-dur-cell mm-dur-m" min="0" max="59" step="1" inputmode="numeric" placeholder="0" aria-label="Minuty"> 1288 <span class="mm-dur-sep">m</span> 1289 <input type="number" class="mm-dur-cell mm-dur-s" min="0" max="59" step="1" inputmode="numeric" placeholder="0" aria-label="Sekundy"> 1290 <span class="mm-dur-sep">s</span> 1291 <input type="hidden" id="cooldownCas" class="mm-duration-time"> 1292 </div> 1293 </div> 1294 <div><label style="font-size:11px;margin:0 0 2px;display:block;">RPE</label><select id="cooldownRpe" class="input-interval-rpe" onchange="window.prepocitejIntervaly()"><option value="1">1</option><option value="2">2</option><option value="3">3</option><option value="4" selected>4</option><option value="5">5</option><option value="6">6</option><option value="7">7</option><option value="8">8</option><option value="9">9</option><option value="10">10</option></select></div> 1295 </div> 1296 </div> 1297 <button id="btnPridatVyklus" type="button" onclick="window.zobrazitFazi(3)" style="display:none;margin-bottom:8px;width:100%;background:var(--bg-surface2);color:#1565c0;border:1px dashed #1565c0;border-radius:var(--radius-sm);font-size:12px;font-weight:700;padding:8px;" data-i18n="zapis_interval_add_cooldown">+ PÅidat výklus</button> 1298 <div id="intervalSouhrn" style="display:none;background:var(--maroon);color:#F8EDE5;border-radius:var(--radius-sm);padding:10px 12px;font-size:12px;"> 1299 <div style="display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:6px;"> 1300 <span><i data-icon="clock"></i> <span data-i18n="zapis_interval_total_time">Celkový Äas:</span> <strong id="intervalSouhrnCas">â</strong></span> 1301 <span><i data-icon="heart" data-icon-class="icon-danger"></i> <span data-i18n="zapis_interval_weighted_rpe">Vážené RPE:</span> <strong id="intervalSouhrnRpe">â</strong></span> 1302 <span id="intervalSouhrnVzdalenost" style="display:none;"><i data-icon="map"></i> <span data-i18n="zapis_interval_segments_distance">Vzdálenost úseků:</span> <strong id="intervalSouhrnVzdalenostHodnota">â</strong></span> 1303 </div> 1304 </div> 1305 <div id="kontejnerIntervalu" style="display:none;"></div> 1306 </div> 1307 </section> 1308 1309 <!-- KROK 6: DOPLÅUJÃCà INFORMACE (harmonika) --> 1310 <details id="zapisAccordionDoplnujici" class="zapis-step zapis-step--accordion zapis-accordion-doplnujici app-disclosure" style="display:none;" open data-step="6"> 1311 <summary class="zapis-accordion-summary"> 1312 <span class="zapis-step-num">6</span> 1313 <span class="zapis-step-title" data-i18n="zapis_step6_title">DoplÅujÃcà informace</span> 1314 <span class="zapis-accordion-summary-hint" data-i18n="zapis_accordion_hint"> â terén, zavodnÄnÃ, poÄasÃ, vybavenÃâ¦</span> 1315 </summary> 1316 <div class="zapis-accordion-body"> 1317 <div id="sekceTeren" style="display:none;"> 1318 <label style="margin-top:0;margin-bottom:4px;display:block;" data-i18n="zapis_label_povrch">Povrch:</label> 1319 <div style="font-size:11px;color:var(--text-muted);margin-bottom:8px;" data-i18n="zapis_teren_hint">Vyberte hlavnà povrch. Chcete-li pÅidat smÃÅ¡ený terén, kliknÄte na â+ PÅidat dalšà povrch" â % hlavnÃho povrchu se odeÄtou automaticky.</div> 1320 <div id="terenBarVizualizace" style="display:none;margin-bottom:10px;"></div> 1321 <div id="terenyKontejner"></div> 1322 <button type="button" class="btn-outline btn-small" style="margin-top:6px;" onclick="window._pridatDalsiPovrch&&window._pridatDalsiPovrch()" data-i18n="zapis_teren_add_surface">+ PÅidat dalšà povrch</button> 1323 </div> 1324 <div class="sub-sekce" id="sekceZavodneni" style="margin-top:12px;"> 1325 <div class="label-with-help" style="font-size:12px;font-weight:900;text-transform:uppercase;letter-spacing:.4px;color:var(--text-secondary);"><span><i data-icon="droplet"></i> <span data-i18n="zapis_hydration_title">ZavodnÄnÃ</span></span><button type="button" class="help-trigger" data-help-key="hydration" data-i18n="zapis_aria_help_hydration" data-i18n-attr="aria-label" aria-label="NápovÄda k zavodnÄnÃ"><i data-icon="information-circle" data-icon-size="16"></i></button></div> 1326 <div class="grid-2 zapis-grid-tight zapis-field-stack--tight"> 1327 <input type="number" id="zavodneniMl" data-i18n="zapis_placeholder_ml" data-i18n-attr="placeholder" placeholder="ml" min="0" oninput="window.gutZapisAktual
1327izujIndikator&&window.gutZapisAktualizujIndikator()"><input type="number" id="zavodneniDavky" data-i18n="zapis_placeholder_doses" data-i18n-attr="placeholder" placeholder="à dávek" min="0"> 1328 </div> 1329 <div id="gutZapisIndikator" style="display:none;margin-top:6px;"></div> 1330 <button type="button" id="gutZapisVlozBtn" onclick="window.gutZapisVlozDoporuceni&&window.gutZapisVlozDoporuceni()" style="display:none;margin-top:8px;width:100%;font-size:11px;background:none;border:1.5px solid #0288d1;color:#0288d1;border-radius:6px;padding:6px 10px;cursor:pointer;font-weight:600;text-align:center;"><i data-icon="droplet"></i> <span id="gutZapisVlozLabel" data-i18n="zapis_gut_insert_default">Vložit doporuÄenà z gut plánu</span></button> 1331 </div> 1332 <div id="sekcePocasiZapis" class="grid-2 zapis-grid-tight zapis-field-stack"> 1333 <div><div class="label-with-help"><label style="margin:0;" data-i18n="zapis_label_temperature">Teplota (°C)</label><button type="button" class="help-trigger" data-help-key="temperature" data-i18n="zapis_aria_help_temp_humidity" data-i18n-attr="aria-label" aria-label="NápovÄda k teplotÄ a vlhkosti"><i data-icon="information-circle" data-icon-size="16"></i></button><span class="label-help-push" style="cursor:pointer;color:#1976d2;font-weight:bold;font-size:11px;" onclick="window.ziskatPocasiGPS('odjetaTeplota','odjetaVlhkost')"><i data-icon="map-pin"></i> <span data-i18n="zapis_link_gps">GPS</span></span></div><input type="number" id="odjetaTeplota"></div> 1334 <div><label style="margin-top:0;" data-i18n="zapis_label_humidity">Vlhkost (%):</label><input type="number" id="odjetaVlhkost"></div> 1335 </div> 1336 <div id="sekceVybaveniZapis" style="display:none;margin-top:12px;padding:12px;background:var(--bg-surface);border-left:3px solid var(--orange);border-radius:0 var(--radius-sm) var(--radius-sm) 0;"> 1337 <label style="color:var(--orange);margin-top:0;font-size:12px;font-weight:900;text-transform:uppercase;letter-spacing:.4px;"><i data-icon="briefcase"></i> <span data-i18n="zapis_equipment_used_label">Použité vybavenÃ</span></label> 1338 <button type="button" class="btn-accent btn-small" style="margin-top:6px;margin-bottom:8px;width:100%;max-width:none;" onclick="window.otevritVyberVybaveni()"><span data-i18n="zapis_equipment_pick_garage">+ VYBRAT Z GARÃŽE</span></button> 1339 <div id="vybraneVybaveniText" data-i18n="zapis_equipment_none_selected" style="font-size:12px;color:var(--text-secondary);font-weight:bold;line-height:1.4;">ZatÃm nevybráno</div> 1340 </div> 1341 </div> 1342 </details> 1343 1344 <!-- KROK 7: POZNÃMKY --> 1345 <section class="zapis-step" id="sekcePoznamkyObecne" data-step="7"> 1346 <header class="zapis-step-header"> 1347 <span class="zapis-step-num">7</span> 1348 <span class="zapis-step-title" data-i18n="zapis_step7_title">Poznámky</span> 1349 </header> 1350 <label style="margin-top:0;" data-i18n="zapis_label_note_custom">Vlastnà poznámka:</label> 1351 <textarea id="poznamka" rows="2" data-i18n="zapis_placeholder_note_custom" data-i18n-attr="placeholder" placeholder="Trasa, pocity, co se povedloâ¦" style="margin-top:4px;"></textarea> 1352 <div id="sekcePoznamkaSpec" style="display:none;margin-top:10px;padding:10px;border:1px dashed var(--border-mid);border-radius:10px;background:var(--bg-surface2);"> 1353 <label style="margin-top:0;" data-i18n="zapis_label_note_title">Název poznámky:</label> 1354 <input type="text" id="poznamkaNazev" data-i18n="zapis_placeholder_note_title" data-i18n-attr="placeholder" placeholder="NapÅ. plán týdne / checklist / poznámky trenéra"> 1355 <label data-i18n="zapis_label_note_text">Text poznámky:</label> 1356 <textarea id="poznamkaText" rows="4" data-i18n="zapis_placeholder_note_text" data-i18n-attr="placeholder" placeholder="Volný text poznámky..."></textarea> 1357 <div style="display:flex;gap:8px;flex-wrap:wrap;margin-top:8px;"> 1358 <button type="button" class="btn-primary btn-small" onclick="window.togglePoznamkaDictation()"><i data-icon="signal"></i> <span data-i18n="zapis_btn_dictate">Diktovat</span></button> 1359 <button type="button" class="btn-primary btn-small" onclick="window.pridatPoznamkaTodoItem()"><i data-icon="plus"></i> <span data-i18n="zapis_btn_add_todo">PÅidat úkol</span></button> 1360 </div> 1361 <div id="poznamkaDictationState" style="display:none;margin-top:8px;font-size:12px;font-weight:700;color:#1565c0;"></div> 1362 <div id="poznamkaTodoStats" style="margin-top:8px;font-size:12px;color:var(--text-secondary);font-weight:700;">ÃkolnÃÄek: 0/0 uzavÅeno</div> 1363 <div id="poznamkaTodoList" style="display:flex;flex-direction:column;gap:6px;margin-top:10px;"></div> 1364 </div> 1365 <label style="margin-top:12px;color:#1565c0;" data-i18n="zapis_label_coach_note">Poznámka trenéra:</label> 1366 <textarea id="poznamkaTrenera" rows="2" data-i18n="zapis_placeholder_coach_note" data-i18n-attr="placeholder" placeholder="Instrukce, zpÄtná vazba, doporuÄenà od trenéraâ¦" style="margin-top:4px;border-color:#90CAF9;background:var(--bg-surface2);"></textarea> 1367 </section> 1368 1369 <!-- AKCE --> 1370 <div class="zapis-actions" style="padding-top:4px;"> 1371 <button type="button" id="btnUlozit" class="btn-secondary" onclick="window.ulozitZapis()"><span data-i18n="btn_ulozit_zaznam">ULOŽIT ZÃZNAM</span></button> 1372 <button type="button" id="btnSmazatZFormulare" class="btn-danger" style="display:none;" onclick="window.smazatZFormulare()"><span data-i18n="btn_smazat_zaznam"><i data-icon="trash"></i> SMAZAT ZÃZNAM</span></button> 1373 <button type="button" id="btnZrusitEdit" class="btn-cancel" style="display:none;" onclick="window.zruseniUpravy()"><span data-i18n="btn_zrusit_upravu">ZRUÅ IT ÃPRAVU</span></button> 1374 </div> 1375 1376 </div> 1377 </div> 1378 </div> 1379 1380 <div id="tab-historie" class="tab-content" style="display: block;"> 1381 <div class="denik-toolbar"> 1382 <select id="hledatTyp" onchange="window.zmenaFiltruHistorie()" style="height:36px;box-sizing:border-box;font-size:12px;font-weight:bold;border-radius:var(--radius-sm);flex:1 1 140px;min-width:0;padding:0 8px;"> 1383 <option value="" data-i18n="denik_filter_all_types">VÅ¡echny typy</option> 1384 </select> 1385 <div class="date-row history-filter-row"> 1386 <div class="date-field flex-fill"> 1387 <label for="hledatMesic" style="margin:0;font-size:10px;line-height:1;color:var(--text-muted);font-weight:700;text-transform:uppercase;letter-spacing:.4px;" data-i18n="denik_filter_month">MÄsÃc</label> 1388 <div class="history-month-row" style="display:flex;align-items:center;gap:6px;flex-wrap:nowrap;width:100%;"> 1389 <button type="button" class="denik-month-nav-btn" onclick="window.k
1389alendarPredchozi()" data-i18n="denik_prev_month" data-i18n-attr="title" title="PÅedchozà mÄsÃc" aria-label="PÅedchozà mÄsÃc">â¹</button> 1390 <div class="history-month-picker flex-fill"> 1391 <span id="hledatMesicLabel" class="history-month-label">â</span> 1392 <input type="month" class="date-input history-month-input-native" id="hledatMesic" onchange="window.zmenaFiltruHistorie()" onclick="window.openNativeDatePicker && window.openNativeDatePicker('hledatMesic')" data-i18n="denik_pick_month_title" data-i18n-attr="title" title="Vyber mÄsÃc a rok" aria-label="Vyber mÄsÃc a rok"> 1393 </div> 1394 <button type="button" class="denik-month-nav-btn" onclick="window.kalendarDalsi()" data-i18n="denik_next_month" data-i18n-attr="title" title="Dalšà mÄsÃc" aria-label="Dalšà mÄsÃc">âº</button> 1395 </div> 1396 </div> 1397 <button type="button" onclick="window.kalendarDnes()" data-i18n="denik_btn_today" style="height:36px;box-sizing:border-box;background:var(--maroon);border:1px solid var(--maroon);border-radius:var(--radius-sm);padding:0 14px;font-size:12px;cursor:pointer;color:#F8EDE5;font-weight:900;letter-spacing:.5px;margin:0;width:auto;min-height:0;white-space:nowrap;">DNES</button> 1398 </div> 1399 </div> 1400 <div id="kalZavodBanner" class="denik-float-ticker" style="display:none;" aria-live="polite"></div> 1401 <div id="mesicniKalendar" style="padding:0;"></div> 1402 1403 <div id="denikTodosInbox" class="denik-todos-inbox" style="display:none;" aria-live="polite"></div> 1404 1405 <section id="denikTodosSection" class="denik-todos-section" style="display:none;" aria-labelledby="denikTodosHeading"> 1406 <div class="denik-todos-header"> 1407 <h3 id="denikTodosHeading" class="denik-todos-title"> 1408 <i data-icon="clipboard-document"></i> 1409 <span data-i18n="denik_todos_title">ÃkolnÃÄek</span> 1410 </h3> 1411 <span id="denikTodosStats" class="denik-todos-stats" data-i18n="denik_todos_stats">0/0 uzavÅeno</span> 1412 </div> 1413 <div class="denik-todos-filters" role="group" data-i18n="denik_todos_filter_aria" data-i18n-attr="aria-label" aria-label="Filtr úkolů"> 1414 <button type="button" class="denik-todos-filter active" data-denik-todos-filter="open" data-i18n="denik_todos_filter_open">OtevÅené</button> 1415 <button type="button" class="denik-todos-filter" data-denik-todos-filter="done" data-i18n="denik_todos_filter_done">SplnÄné</button> 1416 <button type="button" class="denik-todos-filter" data-denik-todos-filter="all" data-i18n="denik_todos_filter_all">VÅ¡e</button> 1417 </div> 1418 <div id="denikTodosPanel" class="denik-todos-panel"></div> 1419 <div id="denikTodosEmptyMonth" class="denik-todos-empty-month" style="display:none;"> 1420 <p class="denik-todos-empty" data-i18n="denik_todos_empty_month">V tomto mÄsÃci nemáte žádné úkoly v poznámkách.</p> 1421 <button type="button" id="denikTodosAddNoteBtn" class="denik-todos-add-btn" data-i18n="denik_todos_add_hint">PÅidat poznámku s úkolnÃÄkem</button> 1422 </div> 1423 </section> 1424 </div> 1425 1426 <div id="tab-dashboard" class="tab-content" style="display: none;"> 1427 <div id="dashTooltip"></div> 1428 1429 <div class="sekce dashboard-sekce"> 1430 <div class="dashboard-toolbar"> 1431 <h2 data-i18n="dashboard_section_title">PRO ANALÃZA</h2> 1432 <div style="display:flex;gap:8px;align-items:center;"> 1433 <button type="button" class="btn-primary btn-small" onclick="window.otevritWidgetNastaveni()"><span data-i18n="dashboard_edit_widgets"><i data-icon="cog-6-tooth"></i> Upravit widgety</span></button> 1434 <button type="button" class="btn-outline btn-small" onclick="try{localStorage.removeItem('mushmaster_dash_order');}catch(e){}window.vykresliDashboard();" data-i18n-attr="title" data-i18n="dashboard_reset_order_title" title="Resetovat poÅadà widgetů"><span data-i18n="dashboard_reset_order">? Reset poÅadÃ</span></button> 1435 </div> 1436 </div> 1437 1438 <div id="widgetContainer"> 1439 1440 <div class="widget-card widget-card--full" data-widget-id="plany" id="widgetCardPlany"> 1441 <div class="widget-header"> 1442 <h3 class="widget-title" data-i18n="dashboard_widget_plany"><i data-icon="document-text"></i> NadcházejÃcà plány</h3>
1443 <span class="widget-period-badge" data-i18n="dashboard_plans_subtitle">pÅÃÅ¡tÃch 30 dnÃ</span> 1444 </div> 1445 <div id="widgetContentPlany"></div> 1446 </div> 1447 1448 <div class="widget-card widget-card--full" data-widget-id="odznaky" id="widgetCardOdznaky"> 1449 <div class="widget-header"> 1450 <h3 class="widget-title" data-i18n="dashboard_widget_odznaky"><i data-icon="trophy"></i> Odznaky</h3> 1451 <span class="widget-period-badge" data-i18n="badge_widget_subtitle">péÄe a pravidelnost</span> 1452 <div class="widget-toolbar"> 1453 <button type="button" id="badgeWidgetToggle" class="widget-icon-btn" onclick="window.toggleBadgeWidget()" data-i18n="badge_widget_toggle" data-i18n-attr="title,aria-label" title="Skrýt odznaky" aria-label="Skrýt odznaky"><i data-icon="chevron-up"></i></button> 1454 </div> 1455 </div> 1456 <div id="widgetContentOdznaky"></div> 1457 </div> 1458 1459 <div class="widget-card widget-card--full" data-widget-id="zavody" id="widgetCardZavody"> 1460 <div class="widget-header"> 1461 <h3 class="widget-title" data-i18n="dashboard_widget_zavody"><i data-icon="trophy"></i> Závody â plán vs. realita</h3> 1462 <div class="widget-toolbar"> 1463 <button type="button" class="widget-icon-btn" onclick="window.dashWidgetInfoModal('zavody')" data-i18n-attr="title" data-i18n="dashboard_widget_help_title" title="Co ukazuje tento widget?" aria-label="NápovÄda"><i data-icon="information-circle"></i></button> 1464 </div> 1465 </div> 1466 <div id="widgetContentZavody"></div> 1467 </div> 1468 1469 <div class="widget-card" data-widget-id="trainingWindow" id="widgetCardTrainingWindow"> 1470 <div class="widget-header"> 1471 <h3 class="widget-title" data-i18n="dashboard_training_window_title"><i data-icon="cloud"></i> Tréninkové okno</h3> 1472 <span class="widget-period-badge" data-i18n="dashboard_training_window_period">následujÃcÃch 24 h od teÄ</span> 1473 <div class="widget-toolbar"> 1474 <button class="widget-icon-btn" onclick="window.wspTogglePanel(this, 'trainingWindow')" data-i18n-attr="title" data-i18n="dashboard_widget_settings_btn_title" title="NastavenÃ"><i data-icon="cog-6-tooth"></i></button> 1475 </div> 1476 <div class="widget-settings-panel" id="wspPanel_trainingWindow"> 1477 <label for="filterTrainingWindowLoc" data-i18n="dashboard_training_window_loc_label">Lokace</label> 1478 <div class="dash-training-window-loc dash-training-window-loc--panel"> 1479 <select id="filterTrainingWindowLoc" class="dash-training-window-loc__select" onchange="window.onDashTrainingWindowLocationChange()"></select> 1480 <button type="button" class="btn-outline btn-small dash-training-window-loc__manage" onclick="typeof window.openManageLocationsModal==='function'&&window.openManageLocationsModal()" data-i18n="dashboard_training_window_manage_locs">MÃstaâ¦</button> 1481 </div> 1482 </div> 1483 </div> 1484 <div id="widgetContentTrainingWindow" data-i18n="msg_nacteni">NaÄÃtám...</div> 1485 </div> 1486 1487 <div class="widget-card" data-widget-id="readiness"> 1488 <div class="widget-header"> 1489 <h3 class="widget-title" data-i18n="dashboard_widget_readiness"><i data-icon="heart"></i> Readiness â Forma psa</h3>
1490 <span class="widget-period-badge" id="filterReadinessBadge">60 dnÃ</span> 1491 <div class="widget-toolbar"> 1492 <button class="widget-icon-btn" onclick="window.wspToggleExpand(this)" data-i18n-attr="title" data-i18n="dashboard_expand_graph_title" title="ZvÄtÅ¡it graf" aria-label="ZvÄtÅ¡it graf"><i data-icon="arrows-pointing-out"></i></button> 1493 <button class="widget-icon-btn" onclick="window.wspTogglePanel(this, 'readiness')" data-i18n-attr="title" data-i18n="dashboard_widget_settings_btn_title" title="NastavenÃ"><i data-icon="cog-6-tooth"></i></button> 1494 </div> 1495 <input type="hidden" id="filterReadiness" value="60"> 1496 <div class="widget-settings-panel" id="wspPanel_readiness"> 1497 <label data-i18n="dashboard_wsp_period_label">ObdobÃ:</label> 1498 <div class="wsp-row" data-wsp-filter="filterReadiness"> 1499 <span class="wsp-chip" data-wsp-value="30" onclick="window.wspSetPeriod('filterReadiness','30',this,window.renderWidgetReadiness)">30 dnÃ</span> 1500 <span class="wsp-chip active" data-wsp-value="60" onclick="window.wspSetPeriod('filterReadiness','60',this,window.renderWidgetReadiness)">60 dnÃ</span> 1501 <span class="wsp-chip" data-wsp-value="90" onclick="window.wspSetPeriod('filterReadiness','90',this,window.renderWidgetReadiness)">90 dnÃ</span> 1502 <span class="wsp-chip" data-wsp-value="365" onclick="window.wspSetPeriod('filterReadiness','365',this,window.renderWidgetReadiness)">Rok</span> 1503 <span class="wsp-chip" data-wsp-value="custom" onclick="window.dashOpenCustomRange('filterReadiness','renderWidgetReadiness')">VlastnÃ</span> 1504 </div> 1505 <hr class="wsp-divider"> 1506 <label data-i18n="dashboard_wsp_compare_period"><i data-icon="scale"></i> Porovnat s obdobÃm:</label> 1507 <div class="wsp-compare-row"> 1508 <input type="date" id="readPorOd" class="date-input--compact filter-date-input" onchange="window.renderWidgetReadiness()"> 1509 <span style="color:var(--text-muted);font-size:11px;">â</span> 1510 <input type="date" id="readPorDo" class="date-input--compact filter-date-input" onchange="window.renderWidgetReadiness()"> 1511 <button class="wf-clear-btn" onclick="window.wfClearPorovnani('readPorOd','readPorDo',window.renderWidgetReadiness)"><i data-icon="x-mark"></i></button> 1512 </div> 1513 </div> 1514 </div> 1515 <p style="font-size:10px; color:#757575; margin-top:-6px; margin-bottom:10px;" data-i18n="dashboard_readiness_subtitle">CTL = fitness (42dennà průmÄr) | ATL = únava (7dennà průmÄr) | TSB = forma.</p> 1516 <div id="widgetContentReadiness" data-i18n="msg_nacteni">NaÄÃtám...</div> 1517 </div> 1518 1519 <div class="widget-card widget-card--full" data-widget-id="report"> 1520 <!-- Klikatelná hlaviÄka â sbalÃ/rozbalà obsah widgetu --> 1521 <div class="widget-header" style="cursor:pointer;" onclick="window.reportToggleCollapse(this)" role="button" aria-expanded="false" aria-controls="widgetContentReport"> 1522 <h3 class="widget-title" data-i18n="dashboard_widget_report"><i data-icon="chart-bar"></i> Analýza obdobÃ</h3> 1523 <span class="widget-period-badge" id="filterReportBadge" style="pointer-events:none;" data-i18n="dashboard_report_collapsed">Sbaleno</span> 1524 <div class="widget-toolbar"> 1525 <button type="button" class="widget-icon-btn" style="pointer-events:auto;" onclick="event.stopPropagation();window.openWidgetFullscreen('report')" data-i18n-attr="title" data-i18n="dashboard_expand_graph_title" title="ZvÄtÅ¡it graf" aria-label="ZvÄtÅ¡it graf"><i data-icon="arrows-pointing-out"></i></button>
1526 <span id="reportCollapseIcon" style="font-size:16px;color:var(--text-muted);line-height:1;user-select:none;pointer-events:none;">â¼</span> 1527 </div> 1528 <!-- Skryté inputy pro filtrovánà (zachovány pro kompatibilitu) --> 1529 <input type="hidden" id="filterReport" value="both"> 1530 </div> 1531 <!-- Obsah â sbalený v defaultu, rozbalà se onclick --> 1532 <div id="widgetContentReport" style="display:none;"></div> 1533 </div> 1534 1535 <div class="widget-card" data-widget-id="top"> 1536 <div class="widget-header"> 1537 <h3 class="widget-title" data-i18n="dashboard_widget_top"><i data-icon="trophy"></i> TOP Výkony a rychlosti</h3> 1538 <span class="widget-period-badge" id="filterTopBadge">90 dnÃ</span> 1539 <div class="widget-toolbar"> 1540 <button class="widget-icon-btn" onclick="window.wspToggleExpand(this)" data-i18n-attr="title" data-i18n="dashboard_expand_graph_title" title="ZvÄtÅ¡it graf" aria-label="ZvÄtÅ¡it graf"><i data-icon="arrows-pointing-out"></i></button> 1541 <button class="widget-icon-btn" onclick="window.wspTogglePanel(this, 'top')" data-i18n-attr="title" data-i18n="dashboard_widget_settings_btn_title" title="NastavenÃ"><i data-icon="cog-6-tooth"></i></button> 1542 </div> 1543 <input type="hidden" id="filterTop" value="90"> 1544 <div class="widget-settings-panel" id="wspPanel_top"> 1545 <label data-i18n="dashboard_wsp_period_label">ObdobÃ:</label> 1546 <div class="wsp-row" data-wsp-filter="filterTop"> 1547 <span class="wsp-chip" data-wsp-value="30" onclick="window.wspSetPeriod('filterTop','30',this,window.renderWidgetTop)">30 dnÃ</span> 1548 <span class="wsp-chip" data-wsp-value="60" onclick="window.wspSetPeriod('filterTop','60',this,window.renderWidgetTop)">60 dnÃ</span> 1549 <span class="wsp-chip active" data-wsp-value="90" onclick="window.wspSetPeriod('filterTop','90',this,window.renderWidgetTop)">90 dnÃ</span> 1550 <span class="wsp-chip" data-wsp-value="365" onclick="window.wspSetPeriod('filterTop','365',this,window.renderWidgetTop)">Rok</span> 1551 <span class="wsp-chip" data-wsp-value="custom" onclick="window.dashOpenCustomRange('filterTop','renderWidgetTop')">VlastnÃ</span> 1552 </div> 1553 </div> 1554 </div> 1555 <div id="widgetContentTop" data-i18n="msg_nacteni">NaÄÃtám...</div> 1556 </div> 1557 1558 <div class="widget-card" data-widget-id="load"> 1559 <div class="widget-header"> 1560 <h3 class="widget-title" data-i18n="dashboard_widget_load"><i data-icon="fire" data-icon-class="icon-warning"></i> Training Load po týdnech</h3> 1561 <span class="widget-period-badge" id="filterLoadBadge">90 dnÃ</span> 1562 <div class="widget-toolbar"> 1563 <button class="widget-icon-btn" onclick="window.wspToggleExpand(this)" data-i18n-attr="title" data-i18n="dashboard_expand_graph_title" title="ZvÄtÅ¡it graf" aria-label="ZvÄtÅ¡it graf"><i data-icon="arrows-pointing-out"></i></button> 1564 <button class="widget-icon-btn" onclick="window.wspTogglePanel(this, 'load')" data-i18n-attr="title" data-i18n="dashboard_widget_settings_btn_title" title="NastavenÃ"><i data-icon="cog-6-tooth"></i></button> 1565 </div> 1566 <input type="hidden" id="filterLoad" value="90"> 1567 <input type="hidden" id="filterLoadAggr" value="weeks"> 1568 <div class="widget-settings-panel" id="wspPanel_load"> 1569 <label data-i18n="dashboard_wsp_period_label">ObdobÃ:</label> 1570 <div class="wsp-row" data-wsp-filter="filterLoad">
1571 <span class="wsp-chip" data-wsp-value="30" onclick="window.wspSetPeriod('filterLoad','30',this,window.renderWidgetLoad)">30 dnÃ</span> 1572 <span class="wsp-chip" data-wsp-value="60" onclick="window.wspSetPeriod('filterLoad','60',this,window.renderWidgetLoad)">60 dnÃ</span> 1573 <span class="wsp-chip active" data-wsp-value="90" onclick="window.wspSetPeriod('filterLoad','90',this,window.renderWidgetLoad)">90 dnÃ</span> 1574 <span class="wsp-chip" data-wsp-value="365" onclick="window.wspSetPeriod('filterLoad','365',this,window.renderWidgetLoad)">Rok</span> 1575 <span class="wsp-chip" data-wsp-value="custom" onclick="window.dashOpenCustomRange('filterLoad','renderWidgetLoad')">VlastnÃ</span> 1576 </div> 1577 <hr class="wsp-divider"> 1578 <label data-i18n="dashboard_wsp_display_label">ZobrazenÃ:</label> 1579 <div class="wsp-row"> 1580 <span class="wsp-chip active" onclick="window.wspSetChip(this,'filterLoadAggr','weeks',window.renderWidgetLoad)">Po týdnech</span> 1581 <span class="wsp-chip" onclick="window.wspSetChip(this,'filterLoadAggr','days',window.renderWidgetLoad)">Po dnech</span> 1582 </div> 1583 <hr class="wsp-divider"> 1584 <label data-i18n="dashboard_wsp_activity_type_label">Typ aktivity:</label> 1585 <div class="wsp-row"> 1586 <select id="filterLoadTyp" class="widget-filter" onchange="window.renderWidgetLoad()"> 1587 <option value="vse" data-i18n="dashboard_filter_all">VÅ¡e</option> 1588 </select> 1589 </div> 1590 <hr class="wsp-divider"> 1591 <label data-i18n="dashboard_wsp_compare_period"><i data-icon="scale"></i> Porovnat s obdobÃm:</label> 1592 <div class="wsp-compare-row"> 1593 <input type="date" id="loadPorovnatOd" class="date-input--compact filter-date-input" onchange="window.renderWidgetLoad()"> 1594 <span style="color:var(--text-muted);font-size:11px;">â</span> 1595 <input type="date" id="loadPorovnatDo" class="date-input--compact filter-date-input" onchange="window.renderWidgetLoad()"> 1596 <button class="wf-clear-btn" onclick="window.wfClearPorovnani('loadPorovnatOd','loadPorovnatDo',window.renderWidgetLoad)"><i data-icon="x-mark"></i></button> 1597 </div> 1598 </div> 1599 </div> 1600 <div id="widgetContentLoad" data-i18n="msg_nacteni">NaÄÃtám...</div> 1601 </div> 1602 1603 <div class="widget-card" data-widget-id="peaksCurve"> 1604 <div class="widget-header"> 1605 <h3 class="widget-title" data-i18n="dashboard_widget_peaksCurve"><i data-icon="bolt"></i> KÅivka rychlosti (PEAKS)</h3> 1606 <span class="widget-period-badge" id="filterPeaksCurveBadge">60 dnÃ</span> 1607 <div class="widget-toolbar"> 1608 <button class="widget-icon-btn" onclick="window.wspToggleExpand(this)" data-i18n-attr="title" data-i18n="dashboard_expand_graph_title" title="ZvÄtÅ¡it graf" aria-label="ZvÄtÅ¡it graf"><i data-icon="arrows-pointing-out"></i></button> 1609 <button class="widget-icon-btn" onclick="window.wspTogglePanel(this, 'peaksCurve')" data-i18n-attr="title" data-i18n="dashboard_widget_settings_btn_title" title="NastavenÃ"><i data-icon="cog-6-tooth"></i></button> 1610 </div> 1611 <input type="hidden" id="filterPeaksCurve" value="60"> 1612 <input type="hidden" id="filterPeaksCurveKind" value="all"> 1613 <div class="widget-settings-panel" id="wspPanel_peaksCurve"> 1614 <label data-i18n="dashboard_wsp_period_label">ObdobÃ:</label> 1615 <div class="wsp-row" data-wsp-filter="filterPeaksCurve">
1616 <span class="wsp-chip" data-wsp-value="30" onclick="window.wspSetPeriod('filterPeaksCurve','30',this,window.renderWidgetPeaksCurve)">30 dnÃ</span> 1617 <span class="wsp-chip active" data-wsp-value="60" onclick="window.wspSetPeriod('filterPeaksCurve','60',this,window.renderWidgetPeaksCurve)">60 dnÃ</span> 1618 <span class="wsp-chip" data-wsp-value="90" onclick="window.wspSetPeriod('filterPeaksCurve','90',this,window.renderWidgetPeaksCurve)">90 dnÃ</span> 1619 <span class="wsp-chip" data-wsp-value="365" onclick="window.wspSetPeriod('filterPeaksCurve','365',this,window.renderWidgetPeaksCurve)">Rok</span> 1620 <span class="wsp-chip" data-wsp-value="custom" onclick="window.dashOpenCustomRange('filterPeaksCurve','renderWidgetPeaksCurve')">VlastnÃ</span> 1621 </div> 1622 <hr class="wsp-divider"> 1623 <label data-i18n="dashboard_peaks_kind_label">Závod / trénink:</label> 1624 <div class="wsp-row" id="wspPeaksKindChips"> 1625 <span class="wsp-chip active" data-i18n="dashboard_peaks_kind_all" onclick="window.wspSetChip(this,'filterPeaksCurveKind','all',window.renderWidgetPeaksCurve)">VÅ¡e</span> 1626 <span class="wsp-chip" data-i18n="dashboard_peaks_kind_race" onclick="window.wspSetChip(this,'filterPeaksCurveKind','race',window.renderWidgetPeaksCurve)">Závod</span> 1627 <span class="wsp-chip" data-i18n="dashboard_peaks_kind_train" onclick="window.wspSetChip(this,'filterPeaksCurveKind','train',window.renderWidgetPeaksCurve)">Trénink</span> 1628 </div> 1629 <p style="font-size:10px;color:var(--text-muted);margin:6px 0 0;line-height:1.35;" data-i18n="dashboard_peaks_kind_all_hint">Režim âVÅ¡eâ zobrazà souÄasnÄ nejlepšà závod a nejlepšà trénink; porovnánà dvou obdobà je v nÄm vypnuté.</p> 1630 <hr class="wsp-divider"> 1631 <label data-i18n="dashboard_wsp_compare_period"><i data-icon="scale"></i> Porovnat s obdobÃm:</label> 1632 <div class="wsp-compare-row"> 1633 <input type="date" id="peaksPorOd" class="date-input--compact filter-date-input" onchange="window.renderWidgetPeaksCurve()"> 1634 <span style="color:var(--text-muted);font-size:11px;">â</span> 1635 <input type="date" id="peaksPorDo" class="date-input--compact filter-date-input" onchange="window.renderWidgetPeaksCurve()"> 1636 <button class="wf-clear-btn" onclick="window.wfClearPorovnani('peaksPorOd','peaksPorDo',window.renderWidgetPeaksCurve)"><i data-icon="x-mark"></i></button> 1637 </div> 1638 </div> 1639 </div> 1640 <p style="font-size:10px; color:#757575; margin-top:-6px; margin-bottom:10px;" data-i18n="dashboard_peaks_curve_hint">Nejvyššà průmÄrná rychlost po Äasových úsecÃch z nahraných tras (FIT/GPX/TCX).</p> 1641 <div id="widgetContentPeaksCurve" data-i18n="msg_nacteni">NaÄÃtám...</div> 1642 </div> 1643 1644 <div class="widget-card" data-widget-id="vybaveni"> 1645 <div class="widget-header"> 1646 <h3 class="widget-title" data-i18n="dashboard_widget_vybaveni"><i data-icon="briefcase"></i> Stav vybavenà (Garáž)</h3> 1647 <div class="widget-toolbar"> 1648 <button class="widget-icon-btn" onclick="window.wspToggleExpand(this)" data-i18n-attr="title" data-i18n="dashboard_expand_graph_title" title="ZvÄtÅ¡it graf" aria-label="ZvÄtÅ¡it graf"><i data-icon="arrows-pointing-out"></i></button> 1649 </div> 1650 </div> 1651 <div id="widgetContentVybaveni" data-i18n="msg_nacteni">NaÄÃtám...</div> 1652 </div> 1653 1654 <div class="widget-card" data-widget-id="objem"> 1655 <div class="widget-header"> 1656 <h3 class="widget-title" data-i18n="dashboard_widget_objem"><i data-icon="clock"></i> Tréninkový objem</h3>
1657 <span class="widget-period-badge" id="filterObjemBadge">60 dnÃ</span> 1658 <div class="widget-toolbar"> 1659 <button class="widget-icon-btn" onclick="window.wspToggleExpand(this)" data-i18n-attr="title" data-i18n="dashboard_expand_graph_title" title="ZvÄtÅ¡it graf" aria-label="ZvÄtÅ¡it graf"><i data-icon="arrows-pointing-out"></i></button> 1660 <button class="widget-icon-btn" onclick="window.wspTogglePanel(this, 'objem')" data-i18n-attr="title" data-i18n="dashboard_widget_settings_btn_title" title="NastavenÃ"><i data-icon="cog-6-tooth"></i></button> 1661 </div> 1662 <input type="hidden" id="filterObjem" value="60"> 1663 <input type="hidden" id="filterObjemAggr" value="weeks"> 1664 <div class="widget-settings-panel" id="wspPanel_objem"> 1665 <label data-i18n="dashboard_wsp_period_label">ObdobÃ:</label> 1666 <div class="wsp-row" data-wsp-filter="filterObjem"> 1667 <span class="wsp-chip" data-wsp-value="30" onclick="window.wspSetPeriod('filterObjem','30',this,window.renderWidgetObjem)">30 dnÃ</span> 1668 <span class="wsp-chip active" data-wsp-value="60" onclick="window.wspSetPeriod('filterObjem','60',this,window.renderWidgetObjem)">60 dnÃ</span> 1669 <span class="wsp-chip" data-wsp-value="90" onclick="window.wspSetPeriod('filterObjem','90',this,window.renderWidgetObjem)">90 dnÃ</span> 1670 <span class="wsp-chip" data-wsp-value="365" onclick="window.wspSetPeriod('filterObjem','365',this,window.renderWidgetObjem)">Rok</span> 1671 <span class="wsp-chip" data-wsp-value="custom" onclick="window.dashOpenCustomRange('filterObjem','renderWidgetObjem')">VlastnÃ</span> 1672 </div> 1673 <hr class="wsp-divider"> 1674 <label data-i18n="dashboard_wsp_display_label">ZobrazenÃ:</label> 1675 <div class="wsp-row"> 1676 <span class="wsp-chip active" onclick="window.wspSetChip(this,'filterObjemAggr','weeks',window.renderWidgetObjem)">Po týdnech</span> 1677 <span class="wsp-chip" onclick="window.wspSetChip(this,'filterObjemAggr','days',window.renderWidgetObjem)">Po dnech</span> 1678 </div> 1679 <hr class="wsp-divider"> 1680 <label data-i18n="dashboard_wsp_activity_type_label">Typ aktivity:</label> 1681 <div class="wsp-row"> 1682 <select id="filterObjemTyp" class="widget-filter" onchange="window.renderWidgetObjem()"> 1683 <option value="vse" data-i18n="dashboard_filter_all">VÅ¡e</option> 1684 </select> 1685 </div> 1686 <hr class="wsp-divider"> 1687 <label data-i18n="dashboard_wsp_compare_period"><i data-icon="scale"></i> Porovnat s obdobÃm:</label> 1688 <div class="wsp-compare-row"> 1689 <input type="date" id="objemPorovnatOd" class="date-input--compact filter-date-input" onchange="window.renderWidgetObjem()"> 1690 <span style="color:var(--text-muted);font-size:11px;">â</span> 1691 <input type="date" id="objemPorovnatDo" class="date-input--compact filter-date-input" onchange="window.renderWidgetObjem()"> 1692 <button class="wf-clear-btn" onclick="window.wfClearPorovnani('objemPorovnatOd','objemPorovnatDo',window.renderWidgetObjem)"><i data-icon="x-mark"></i></button> 1693 </div> 1694 </div> 1695 </div> 1696 <div id="widgetContentObjem" data-i18n="msg_nacteni">NaÄÃtám...</div> 1697 </div> 1698 1699 <div class="widget-card" data-widget-id="teplota"> 1700 <div class="widget-header"> 1701 <h3 class="widget-title" data-i18n="dashboard_widget_teplota"><i data-icon="thermometer"></i> Tepelná adaptace</h3>
1702 <span class="widget-period-badge" id="filterTeplotaBadge">60 dnÃ</span> 1703 <div class="widget-toolbar"> 1704 <button class="widget-icon-btn" onclick="window.wspToggleExpand(this)" data-i18n-attr="title" data-i18n="dashboard_expand_graph_title" title="ZvÄtÅ¡it graf" aria-label="ZvÄtÅ¡it graf"><i data-icon="arrows-pointing-out"></i></button> 1705 <button class="widget-icon-btn" onclick="window.wspTogglePanel(this, 'teplota')" data-i18n-attr="title" data-i18n="dashboard_widget_settings_btn_title" title="NastavenÃ"><i data-icon="cog-6-tooth"></i></button> 1706 </div> 1707 <input type="hidden" id="filterTeplota" value="60"> 1708 <input type="hidden" id="filterTeplotaAggr" value="days"> 1709 <input type="hidden" id="filterTeplotaMA" value="5"> 1710 <div class="widget-settings-panel" id="wspPanel_teplota"> 1711 <label data-i18n="dashboard_wsp_period_graph_label">Obdobà grafu:</label> 1712 <div class="wsp-row" data-wsp-filter="filterTeplota"> 1713 <span class="wsp-chip" data-wsp-value="30" onclick="window.wspSetPeriod('filterTeplota','30',this,window.renderWidgetTeplota)">30 dnÃ</span> 1714 <span class="wsp-chip active" data-wsp-value="60" onclick="window.wspSetPeriod('filterTeplota','60',this,window.renderWidgetTeplota)">60 dnÃ</span> 1715 <span class="wsp-chip" data-wsp-value="90" onclick="window.wspSetPeriod('filterTeplota','90',this,window.renderWidgetTeplota)">90 dnÃ</span> 1716 <span class="wsp-chip" data-wsp-value="365" onclick="window.wspSetPeriod('filterTeplota','365',this,window.renderWidgetTeplota)">Rok</span> 1717 <span class="wsp-chip" data-wsp-value="custom" onclick="window.dashOpenCustomRange('filterTeplota','renderWidgetTeplota')">VlastnÃ</span> 1718 </div> 1719 <hr class="wsp-divider"> 1720 <label data-i18n="dashboard_wsp_display_graph_label">Zobrazenà grafu:</label> 1721 <div class="wsp-row"> 1722 <span class="wsp-chip active" onclick="window.wspSetChip(this,'filterTeplotaAggr','days',window.renderWidgetTeplota)">Po dnech</span> 1723 <span class="wsp-chip" onclick="window.wspSetChip(this,'filterTeplotaAggr','weeks',window.renderWidgetTeplota)">Po týdnech</span> 1724 </div> 1725 <hr class="wsp-divider"> 1726 <label data-i18n="dashboard_temp_activity_primary">Aktivita A:</label> 1727 <div class="wsp-row"> 1728 <select id="filterTeplotaTyp" class="widget-filter" onchange="window.renderWidgetTeplota()"> 1729 <option value="vse" data-i18n="dashboard_filter_all">VÅ¡e</option> 1730 </select> 1731 </div> 1732 <hr class="wsp-divider"> 1733 <label data-i18n="dashboard_temp_activity_secondary">Aktivita B:</label> 1734 <div class="wsp-row"> 1735 <select id="filterTeplotaTyp2" class="widget-filter" onchange="window.renderWidgetTeplota()"> 1736 <option value="none" data-i18n="dashboard_temp_hide_b">Nezobrazovat</option> 1737 </select> 1738 </div> 1739 <hr class="wsp-divider"> 1740 <label data-i18n="dashboard_temp_ma_label">Klouzavý průmÄr:</label> 1741 <div class="wsp-row">
1742 <span class="wsp-chip" onclick="window.wspSetChip(this,'filterTeplotaMA','3',window.renderWidgetTeplota)">3</span> 1743 <span class="wsp-chip active" onclick="window.wspSetChip(this,'filterTeplotaMA','5',window.renderWidgetTeplota)">5</span> 1744 <span class="wsp-chip" onclick="window.wspSetChip(this,'filterTeplotaMA','7',window.renderWidgetTeplota)">7</span> 1745 </div> 1746 <hr class="wsp-divider"> 1747 <p id="dashTeplotaGuideModel" style="font-size:11px;color:var(--text-secondary);line-height:1.6;margin:0 0 8px;"> 1748 <span data-i18n="dashboard_temp_seasonal_title"><strong>Sezónnà základ (60 dnÃ)</strong></span><span data-i18n="dashboard_temp_seasonal_body"> â TWA pocitové teploty ze vÅ¡ech tréninků ve vybrané AktivitÄ A. Odrážà pomalou adaptaci srsti, hustoty Äervených krvinek a metabolismu.</span><br> 1749 <span data-i18n="dashboard_temp_acute_title"><strong>Akutnà zátÄž (14 dnÃ)</strong></span><span data-i18n="dashboard_temp_acute_body"> â totéž s krátkým oknem. Odrážà stav krevnà plazmy a rychlou termoregulaci.</span><br> 1750 <span data-i18n="dashboard_temp_chart_note">ObÄ hodnoty se pÅepoÄÃtajà pÅi zmÄnÄ Aktivity A nÞe. Graf zobrazuje historický průbÄh TI.</span> 1751 </p> 1752 <hr class="wsp-divider"> 1753 <p id="dashTeplotaGuideGap" style="font-size:11px;color:var(--text-secondary);line-height:1.7;margin:0;"> 1754 <span data-i18n="dashboard_temp_gap_title"><strong>Interpretace rozdÃlu (gap = Akutnà - SezónnÃ):</strong></span><br> 1755 <span data-i18n="dashboard_temp_gap_ok"><span style="color:#2e7d32;">? < 3 °C â PlnÄ adaptován</span>: strukturálnà adaptace odpovÃdá klimatu, pes je pÅipraven na plný výkon.</span><br> 1756 <span data-i18n="dashboard_temp_gap_mid"><span style="color:var(--text-secondary);">~ 3â5 °C â MÃrný pÅechod</span>: pes se adaptuje, sledujte kondici, zkraÅ¥te prvnà trénink.</span><br> 1757 <span data-i18n="dashboard_temp_gap_hot"><span style="color:#f57c00;">? > 5 °C â Teplotnà šok</span>: strukturálnà adaptace zaostává, výraznÄ zkraÅ¥te délku a intenzitu.</span><br> 1758 <span data-i18n="dashboard_temp_gap_cool"><span style="color:#1565c0;">Ë < -5 °C â Výrazné ochlazenÃ</span>: pes může mÃt zhorÅ¡ený průtok krve do svalů, prodlužte rozcviÄenÃ.</span> 1759 </p> 1760 </div> 1761 </div> 1762 <div id="widgetContentTeplota" data-i18n="msg_nacteni">NaÄÃtám...</div> 1763 </div> 1764 1765 <div class="widget-card" data-widget-id="voda"> 1766 <div class="widget-header"> 1767 <h3 class="widget-title" data-i18n="dashboard_widget_voda"><i data-icon="droplet"></i> Gut Training (ZavodnÄnÃ)</h3> 1768 <span class="widget-period-badge" id="filterVodaBadge">30 dnÃ</span> 1769 <div class="widget-toolbar"> 1770 <button class="widget-icon-btn" onclick="window.wspToggleExpand(this)" data-i18n-attr="title" data-i18n="dashboard_expand_graph_title" title="ZvÄtÅ¡it graf" aria-label="ZvÄtÅ¡it graf"><i data-icon="arrows-pointing-out"></i></button> 1771 <button class="widget-icon-btn" onclick="window.wspTogglePanel(this, 'voda')" data-i18n-attr="title" data-i18n="dashboard_widget_settings_btn_title" title="NastavenÃ"><i data-icon="cog-6-tooth"></i></button> 1772 </div> 1773 <input type="hidden" id="filterVoda" value="30"> 1774 <input type="hidden" id="filterVodaAggr" value="days"> 1775 <div class="widget-settings-panel" id="wspPanel_voda"> 1776 <label data-i18n="dashboard_wsp_period_label">ObdobÃ:</label> 1777 <div class="wsp-row" data-wsp-filter="filterVoda">
1778 <span class="wsp-chip active" data-wsp-value="30" onclick="window.wspSetPeriod('filterVoda','30',this,window.renderWidgetVoda)">30 dnÃ</span> 1779 <span class="wsp-chip" data-wsp-value="60" onclick="window.wspSetPeriod('filterVoda','60',this,window.renderWidgetVoda)">60 dnÃ</span> 1780 <span class="wsp-chip" data-wsp-value="90" onclick="window.wspSetPeriod('filterVoda','90',this,window.renderWidgetVoda)">90 dnÃ</span> 1781 <span class="wsp-chip" data-wsp-value="365" onclick="window.wspSetPeriod('filterVoda','365',this,window.renderWidgetVoda)">Rok</span> 1782 <span class="wsp-chip" data-wsp-value="custom" onclick="window.dashOpenCustomRange('filterVoda','renderWidgetVoda')">VlastnÃ</span> 1783 </div> 1784 <hr class="wsp-divider"> 1785 <label data-i18n="dashboard_wsp_display_label">ZobrazenÃ:</label> 1786 <div class="wsp-row"> 1787 <span class="wsp-chip active" onclick="window.wspSetChip(this,'filterVodaAggr','days',window.renderWidgetVoda)">Po dnech</span> 1788 <span class="wsp-chip" onclick="window.wspSetChip(this,'filterVodaAggr','weeks',window.renderWidgetVoda)">Po týdnech</span> 1789 </div> 1790 </div> 1791 </div> 1792 <div id="widgetContentVoda" data-i18n="msg_nacteni">NaÄÃtám...</div> 1793 </div> 1794 1795 <div class="widget-card" data-widget-id="rpe"> 1796 <div class="widget-header"> 1797 <h3 class="widget-title" data-i18n="dashboard_widget_rpe"><i data-icon="target"></i> Zóny RPE (Pravidlo 80/20)</h3> 1798 <span class="widget-period-badge" id="filterRpeBadge">60 dnÃ</span> 1799 <div class="widget-toolbar"> 1800 <button class="widget-icon-btn" onclick="window.wspToggleExpand(this)" data-i18n-attr="title" data-i18n="dashboard_expand_graph_title" title="ZvÄtÅ¡it graf" aria-label="ZvÄtÅ¡it graf"><i data-icon="arrows-pointing-out"></i></button> 1801 <button class="widget-icon-btn" onclick="window.wspTogglePanel(this, 'rpe')" data-i18n-attr="title" data-i18n="dashboard_widget_settings_btn_title" title="NastavenÃ"><i data-icon="cog-6-tooth"></i></button> 1802 </div> 1803 <input type="hidden" id="filterRpe" value="60"> 1804 <div class="widget-settings-panel" id="wspPanel_rpe"> 1805 <label data-i18n="dashboard_wsp_period_label">ObdobÃ:</label> 1806 <div class="wsp-row" data-wsp-filter="filterRpe"> 1807 <span class="wsp-chip" data-wsp-value="30" onclick="window.wspSetPeriod('filterRpe','30',this,window.renderWidgetRPE)">30 dnÃ</span> 1808 <span class="wsp-chip active" data-wsp-value="60" onclick="window.wspSetPeriod('filterRpe','60',this,window.renderWidgetRPE)">60 dnÃ</span> 1809 <span class="wsp-chip" data-wsp-value="90" onclick="window.wspSetPeriod('filterRpe','90',this,window.renderWidgetRPE)">90 dnÃ</span> 1810 <span class="wsp-chip" data-wsp-value="365" onclick="window.wspSetPeriod('filterRpe','365',this,window.renderWidgetRPE)">Rok</span> 1811 <span class="wsp-chip" data-wsp-value="custom" onclick="window.dashOpenCustomRange('filterRpe','renderWidgetRPE')">VlastnÃ</span> 1812 </div> 1813 <hr class="wsp-divider"> 1814 <label data-i18n="dashboard_wsp_activity_type_label">Typ aktivity:</label> 1815 <div class="wsp-row"> 1816 <select id="filterRpeTyp" class="widget-filter" onchange="window.renderWidgetRPE()"> 1817 <option value="vse" data-i18n="dashboard_filter_all">VÅ¡e</option> 1818 </select> 1819 </div> 1820 <hr class="wsp-divider"> 1821 <label data-i18n="dashboard_wsp_compare_period"><i data-icon="scale"></i> Porovnat s obdobÃm:</label> 1822 <div class="wsp-compare-row"> 1823 <input type="date" id="rpePorOd" class="date-input--compact filter-date-input" onchange="window.renderWidgetRPE()">
1824 <span style="color:var(--text-muted);font-size:11px;">â</span> 1825 <input type="date" id="rpePorDo" class="date-input--compact filter-date-input" onchange="window.renderWidgetRPE()"> 1826 <button class="wf-clear-btn" onclick="window.wfClearPorovnani('rpePorOd','rpePorDo',window.renderWidgetRPE)"><i data-icon="x-mark"></i></button> 1827 </div> 1828 </div> 1829 </div> 1830 <div id="widgetContentRPE" data-i18n="msg_nacteni">NaÄÃtám...</div> 1831 </div> 1832 1833 <div class="widget-card" data-widget-id="povrch"> 1834 <div class="widget-header"> 1835 <h3 class="widget-title" data-i18n="dashboard_widget_povrch"><i data-icon="paw"></i> ZátÄž pohybového aparátu</h3> 1836 <span class="widget-period-badge" id="filterPovrchBadge">30 dnÃ</span> 1837 <div class="widget-toolbar"> 1838 <button class="widget-icon-btn" onclick="window.wspToggleExpand(this)" data-i18n-attr="title" data-i18n="dashboard_expand_graph_title" title="ZvÄtÅ¡it graf" aria-label="ZvÄtÅ¡it graf"><i data-icon="arrows-pointing-out"></i></button> 1839 <button class="widget-icon-btn" onclick="window.wspTogglePanel(this, 'povrch')" data-i18n-attr="title" data-i18n="dashboard_widget_settings_btn_title" title="NastavenÃ"><i data-icon="cog-6-tooth"></i></button> 1840 </div> 1841 <input type="hidden" id="filterPovrch" value="30"> 1842 <div class="widget-settings-panel" id="wspPanel_povrch"> 1843 <label data-i18n="dashboard_wsp_period_label">ObdobÃ:</label> 1844 <div class="wsp-row" data-wsp-filter="filterPovrch"> 1845 <span class="wsp-chip active" data-wsp-value="30" onclick="window.wspSetPeriod('filterPovrch','30',this,window.renderWidgetPovrch)">30 dnÃ</span> 1846 <span class="wsp-chip" data-wsp-value="60" onclick="window.wspSetPeriod('filterPovrch','60',this,window.renderWidgetPovrch)">60 dnÃ</span> 1847 <span class="wsp-chip" data-wsp-value="90" onclick="window.wspSetPeriod('filterPovrch','90',this,window.renderWidgetPovrch)">90 dnÃ</span> 1848 <span class="wsp-chip" data-wsp-value="365" onclick="window.wspSetPeriod('filterPovrch','365',this,window.renderWidgetPovrch)">Rok</span> 1849 <span class="wsp-chip" data-wsp-value="custom" onclick="window.dashOpenCustomRange('filterPovrch','renderWidgetPovrch')">VlastnÃ</span> 1850 </div> 1851 <hr class="wsp-divider"> 1852 <label data-i18n="dashboard_wsp_compare_period"><i data-icon="scale"></i> Porovnat s obdobÃm:</label> 1853 <div class="wsp-compare-row"> 1854 <input type="date" id="povrchPorOd" class="date-input--compact filter-date-input" onchange="window.renderWidgetPovrch()"> 1855 <span style="color:var(--text-muted);font-size:11px;">â</span> 1856 <input type="date" id="povrchPorDo" class="date-input--compact filter-date-input" onchange="window.renderWidgetPovrch()"> 1857 <button class="wf-clear-btn" onclick="window.wfClearPorovnani('povrchPorOd','povrchPorDo',window.renderWidgetPovrch)"><i data-icon="x-mark"></i></button> 1858 </div> 1859 <hr class="wsp-divider"> 1860 <label data-i18n="dashboard_wsp_activity_type_label">Typ aktivity:</label> 1861 <div class="wsp-row"> 1862 <select id="filterPovrchTyp" class="widget-filter" onchange="window.renderWidgetPovrch()" style="font-size:11px;padding:3px 8px;width:100%;margin:0;"> 1863 <option value="vse" data-i18n="dashboard_filter_all">VÅ¡e</option> 1864 </select> 1865 </div> 1866 </div> 1867 </div> 1868 <div id="widgetContentPovrch" data-i18n="msg_nacteni">NaÄÃtám...</div> 1869 </div> 1870 1871 <div class="widget-card" data-widget-id="lokace"> 1872 <div class="widget-header"> 1873 <h3 class="widget-title" data-i18n="dashboard_widget_lokace"><i data-icon="map-pin"></i> VyužÃvánà lokacÃ</h3>
1874 <span class="widget-period-badge" id="filterLokaceBadge">90 dnÃ</span> 1875 <div class="widget-toolbar"> 1876 <button class="widget-icon-btn" onclick="window.wspToggleExpand(this)" data-i18n-attr="title" data-i18n="dashboard_expand_graph_title" title="ZvÄtÅ¡it graf" aria-label="ZvÄtÅ¡it graf"><i data-icon="arrows-pointing-out"></i></button> 1877 <button class="widget-icon-btn" onclick="window.wspTogglePanel(this, 'lokace')" data-i18n-attr="title" data-i18n="dashboard_widget_settings_btn_title" title="NastavenÃ"><i data-icon="cog-6-tooth"></i></button> 1878 </div> 1879 <input type="hidden" id="filterLokace" value="90"> 1880 <div class="widget-settings-panel" id="wspPanel_lokace"> 1881 <label data-i18n="dashboard_wsp_period_label">ObdobÃ:</label> 1882 <div class="wsp-row" data-wsp-filter="filterLokace"> 1883 <span class="wsp-chip" data-wsp-value="30" onclick="window.wspSetPeriod('filterLokace','30',this,window.renderWidgetLokace)">30 dnÃ</span> 1884 <span class="wsp-chip" data-wsp-value="60" onclick="window.wspSetPeriod('filterLokace','60',this,window.renderWidgetLokace)">60 dnÃ</span> 1885 <span class="wsp-chip active" data-wsp-value="90" onclick="window.wspSetPeriod('filterLokace','90',this,window.renderWidgetLokace)">90 dnÃ</span> 1886 <span class="wsp-chip" data-wsp-value="365" onclick="window.wspSetPeriod('filterLokace','365',this,window.renderWidgetLokace)">Rok</span> 1887 <span class="wsp-chip" data-wsp-value="custom" onclick="window.dashOpenCustomRange('filterLokace','renderWidgetLokace')">VlastnÃ</span> 1888 </div> 1889 <hr class="wsp-divider"> 1890 <label data-i18n="dashboard_wsp_activity_type_label">Typ aktivity:</label> 1891 <div class="wsp-row"> 1892 <select id="filterLokaceTyp" class="widget-filter" onchange="window.renderWidgetLokace()"> 1893 <option value="vse" data-i18n="dashboard_filter_all">VÅ¡e</option> 1894 </select> 1895 </div> 1896 </div> 1897 </div> 1898 <div id="widgetContentLokace" data-i18n="msg_nacteni">NaÄÃtám...</div> 1899 </div> 1900 1901 <div class="widget-card" data-widget-id="porovnani"> 1902 <div class="widget-header"> 1903 <h3 class="widget-title" data-i18n="dashboard_widget_porovnani"><i data-icon="bolt"></i> Porovnánà psů</h3> 1904 <span class="widget-period-badge" id="filterPorovnaniBadge">90 dnÃ</span> 1905 <div class="widget-toolbar"> 1906 <button class="widget-icon-btn" onclick="window.wspToggleExpand(this)" data-i18n-attr="title" data-i18n="dashboard_expand_graph_title" title="ZvÄtÅ¡it graf" aria-label="ZvÄtÅ¡it graf"><i data-icon="arrows-pointing-out"></i></button> 1907 <button class="widget-icon-btn" onclick="window.wspTogglePanel(this, 'porovnani')" data-i18n-attr="title" data-i18n="dashboard_widget_settings_btn_title" title="NastavenÃ"><i data-icon="cog-6-tooth"></i></button> 1908 </div> 1909 <input type="hidden" id="filterPorovnani" value="90"> 1910 <div class="widget-settings-panel" id="wspPanel_porovnani"> 1911 <label data-i18n="dashboard_wsp_period_label">ObdobÃ:</label> 1912 <div class="wsp-row" data-wsp-filter="filterPorovnani">
1913 <span class="wsp-chip" data-wsp-value="30" onclick="window.wspSetPeriod('filterPorovnani','30',this,window.renderWidgetPorovnani)">30 dnÃ</span> 1914 <span class="wsp-chip" data-wsp-value="60" onclick="window.wspSetPeriod('filterPorovnani','60',this,window.renderWidgetPorovnani)">60 dnÃ</span> 1915 <span class="wsp-chip active" data-wsp-value="90" onclick="window.wspSetPeriod('filterPorovnani','90',this,window.renderWidgetPorovnani)">90 dnÃ</span> 1916 <span class="wsp-chip" data-wsp-value="365" onclick="window.wspSetPeriod('filterPorovnani','365',this,window.renderWidgetPorovnani)">Rok</span> 1917 <span class="wsp-chip" data-wsp-value="custom" onclick="window.dashOpenCustomRange('filterPorovnani','renderWidgetPorovnani')">VlastnÃ</span> 1918 </div> 1919 <hr class="wsp-divider"> 1920 <label data-i18n="dashboard_compare_dog_a">Pes A:</label> 1921 <div class="wsp-row"> 1922 <select id="porovnaniPesA" class="widget-filter" onchange="window.renderWidgetPorovnani()"></select> 1923 </div> 1924 <label data-i18n="dashboard_compare_dog_b">Pes B:</label> 1925 <div class="wsp-row"> 1926 <select id="porovnaniPesB" class="widget-filter" onchange="window.renderWidgetPorovnani()"></select> 1927 </div> 1928 <label data-i18n="dashboard_compare_metric">Metrika:</label> 1929 <div class="wsp-row"> 1930 <select id="porovnaniMetrika" class="widget-filter" onchange="window.renderWidgetPorovnani()"> 1931 <option value="load" data-i18n="dashboard_metric_load">Training Load</option> 1932 <option value="objem" data-i18n="dashboard_metric_volume">Objem</option> 1933 <option value="rychlost" data-i18n="dashboard_metric_max_speed">MAX rychlost</option> 1934 <option value="rpe" data-i18n="dashboard_metric_avg_rpe">PrůmÄrné RPE</option> 1935 </select> 1936 </div> 1937 </div> 1938 </div> 1939 <div id="widgetContentPorovnani" data-i18n="msg_nacteni">NaÄÃtám...</div> 1940 </div> 1941 1942 <div class="widget-card" data-widget-id="metriky"> 1943 <div class="widget-header"> 1944 <h3 class="widget-title" data-i18n="dashboard_widget_metriky"><i data-icon="scale"></i> Metriky psa</h3> 1945 <span class="widget-period-badge" id="filterMetrikyBadge">Rok</span> 1946 <div class="widget-toolbar"> 1947 <button class="widget-icon-btn" onclick="window.wspToggleExpand(this)" data-i18n-attr="title" data-i18n="dashboard_expand_graph_title" title="ZvÄtÅ¡it graf" aria-label="ZvÄtÅ¡it graf"><i data-icon="arrows-pointing-out"></i></button> 1948 <button class="widget-icon-btn" onclick="window.wspTogglePanel(this, 'metriky')" data-i18n-attr="title" data-i18n="dashboard_widget_settings_btn_title" title="NastavenÃ"><i data-icon="cog-6-tooth"></i></button> 1949 </div> 1950 <input type="hidden" id="filterMetriky" value="365"> 1951 <div class="widget-settings-panel" id="wspPanel_metriky"> 1952 <label data-i18n="dashboard_wsp_period_label">ObdobÃ:</label> 1953 <div class="wsp-row" data-wsp-filter="filterMetriky"> 1954 <span class="wsp-chip" data-wsp-value="30" onclick="window.wspSetPeriod('filterMetriky','30',this,window.renderWidgetMetriky)">30 dnÃ</span>
1955 <span class="wsp-chip" data-wsp-value="60" onclick="window.wspSetPeriod('filterMetriky','60',this,window.renderWidgetMetriky)">60 dnÃ</span> 1956 <span class="wsp-chip" data-wsp-value="90" onclick="window.wspSetPeriod('filterMetriky','90',this,window.renderWidgetMetriky)">90 dnÃ</span> 1957 <span class="wsp-chip active" data-wsp-value="365" onclick="window.wspSetPeriod('filterMetriky','365',this,window.renderWidgetMetriky)">Rok</span> 1958 <span class="wsp-chip" data-wsp-value="custom" onclick="window.dashOpenCustomRange('filterMetriky','renderWidgetMetriky')">VlastnÃ</span> 1959 </div> 1960 </div> 1961 </div> 1962 <div id="widgetContentMetriky" data-i18n="msg_nacteni">NaÄÃtám...</div> 1963 </div> 1964 1965 </div></div> 1966 </div> 1967 <div id="badgeDetailModal" class="modal-overlay" style="display:none;" role="dialog" aria-modal="true" aria-labelledby="badgeDetailTitle" onclick="if(event.target===this)window.closeModal('badgeDetailModal')"> 1968 <div class="modal-box badge-detail-modal-box"> 1969 <div class="modal-head"> 1970 <h3 id="badgeDetailTitle" data-i18n="badge_detail_title">Detail odznaku</h3> 1971 <button type="button" class="modal-close" onclick="window.closeModal('badgeDetailModal')" data-i18n="dog_modal_close_aria" data-i18n-attr="aria-label" aria-label="ZavÅÃt"><i data-icon="x-mark"></i></button> 1972 </div> 1973 <div id="badgeDetailContent" class="badge-detail-modal-content"></div> 1974 </div> 1975 </div> 1976 <div id="tab-nastaveni" class="tab-content tab-content--settings-hub" style="display:none;"> 1977 <div class="sekce settings-hub-wrap"> 1978 <h2 style="margin-bottom:12px;"><span data-i18n="settings_hub_title">⚙️ NastavenÃ</span></h2> 1979 <p class="settings-hub-intro" data-i18n="settings_hub_autosave">Profil a upozornÄnà se po zmÄnÄ ukládajà automaticky do úÄtu.</p> 1980 1981 <div id="ambassadorPromoBanner" class="ambassador-promo-banner" style="display:none;" role="status"> 1982 <span class="ambassador-promo-banner__text" data-i18n="settings_ambassador_promo">LÃbà se ti Mushmaster? StaÅ se naÅ¡Ãm ambasadorem a zÃskej provizi z doporuÄenÃ.</span> 1983 <a id="ambassadorLearnMoreLink" class="ambassador-promo-banner__link" href="mailto:[email protected]?subject=Ambasador%20Mushmaster%20PRO" rel="noopener" data-i18n="settings_ambassador_more">VÃce informacÃ</a> 1984 </div> 1985 1986 <!-- Ambasador zóna (jen isAmbassador) --> 1987 <details class="settings-section app-disclosure" id="settingsAmbassadorZone" style="display:none;"> 1988 <summary class="settings-section__title"><span data-i18n="settings_ambassador_zone_title">🏆 Ambasador zóna</span></summary> 1989 <p class="settings-hint settings-hint--pad" data-i18n="settings_ambassador_zone_intro">Tvůj slevový kód a odkaz pro doporuÄenÃ. Statistiky pÅicházejà z cloudu (správce je aktualizuje podle plateb).</p> 1990 <div class="ambassador-tools"> 1991 <div class="settings-row settings-row--sub"> 1992 <div class="settings-row__label"> 1993 <span data-i18n="settings_ambassador_code_label">Slevový kód</span> 1994 <small data-i18n="settings_ambassador_code_hint">ZákaznÃci ho zadajà pÅi platbÄ (podle nastavenà Stripe).</small> 1995 </div> 1996 <div class="ambassador-code-row"> 1997 <code id="ambassadorCodeDisplay" class="ambassador-code-pill">â</code> 1998 <button type="button" class="btn-base btn-outline btn-small settings-mini-btn" id="btnCopyAmbassad
1998orCode" onclick="window.copyAmbassadorField('code')" data-i18n="settings_ambassador_copy">KopÃrovat</button> 1999 </div> 2000 </div> 2001 <div class="settings-row settings-row--sub"> 2002 <div class="settings-row__label"> 2003 <span data-i18n="settings_ambassador_link_label">RegistraÄnà odkaz</span> 2004 <small data-i18n="settings_ambassador_link_hint">SdÃlej tento odkaz â pÅi registraci pÅes nÄj se doporuÄenà uložÃ.</small> 2005 </div> 2006 <div class="ambassador-link-row"> 2007 <input type="text" id="ambassadorReferralLinkInput" class="ambassador-link-input" readonly aria-label="RegistraÄnà odkaz s ref"> 2008 <button type="button" class="btn-base btn-outline btn-small settings-mini-btn" onclick="window.copyAmbassadorField('link')" data-i18n="settings_ambassador_copy">KopÃrovat</button> 2009 </div> 2010 </div> 2011 <div class="settings-row settings-row--sub ambassador-card-generator"> 2012 <div class="settings-row__label"> 2013 <span data-i18n="settings_ambassador_cards_title">Promo kartiÄky</span> 2014 <small data-i18n="settings_ambassador_cards_hint">VytvoÅ si kartiÄku pro konkrétnà sport, jazyk a vzhled. QR kód i odkaz automaticky obsahujà tvé doporuÄenÃ.</small> 2015 </div> 2016 <div class="ambassador-generator-tools"> 2017 <input type="text" id="ambassadorCardGeneratorInput" class="ambassador-link-input" readonly aria-label="Osobnà generátor promo kartiÄek"> 2018 <div class="ambassador-generator-actions"> 2019 <a id="ambassadorCardGeneratorLink" class="btn-base btn-primary btn-small settings-mini-btn" href="/promo-karta.html" target="_blank" rel="noopener" data-i18n="settings_ambassador_cards_open">OtevÅÃt generátor</a> 2020 <button type="button" class="btn-base btn-outline btn-small settings-mini-btn" onclick="window.copyAmbassadorField('generator')" data-i18n="settings_ambassador_copy">KopÃrovat</button> 2021 </div> 2022 </div> 2023 </div> 2024 </div> 2025 <div class="ambassador-stats-wrap"> 2026 <table class="ambassador-stats-table" aria-describedby="ambassadorStatsCaption"> 2027 <caption id="ambassadorStatsCaption" class="visually-hidden" data-i18n="settings_ambassador_stats_caption">
2027PÅehled provizà ambasadora</caption> 2028 <thead> 2029 <tr> 2030 <th scope="col" data-i18n="settings_ambassador_stat_paying">PlatÃcà svÄÅenci</th> 2031 <th scope="col" data-i18n="settings_ambassador_stat_unpaid">Nevyplacená provize (5 %)</th> 2032 </tr> 2033 </thead> 2034 <tbody> 2035 <tr> 2036 <td id="ambassadorStatPayingCount">0</td> 2037 <td id="ambassadorStatUnpaidCzk">0 KÄ</td> 2038 </tr> 2039 </tbody> 2040 </table> 2041 <button type="button" class="settings-subscription-btn" id="btnAmbassadorPayout" disabled onclick="window.requestAmbassadorPayout()" data-i18n="settings_ambassador_payout_btn">Požádat o výplatu</button> 2042 <p class="settings-hint" style="margin-top:8px;" data-i18n="settings_ambassador_payout_hint">Výplata je možná od 500 KÄ nevyplacené provize. Žádost se uložà do systému nebo se otevÅe e-mail správci.</p> 2043 </div> 2044 </details> 2045 2046 <!-- Jazyk aplikace (prvnà volba v nastavenÃ) --> 2047 <details class="settings-section app-disclosure"> 2048 <summary class="settings-section__title"><span data-i18n="settings_lang_section_title"><i data-icon="globe-alt"></i> Jazyk aplikace</span></summary> 2049 <div class="settings-row settings-row--theme"> 2050 <div class="settings-row__label"> 2051 <span data-i18n="settings_lang_label">Jazyk aplikace</span> 2052 <small data-i18n="settings_lang_hint">ÄeÅ¡tina · English · Deutsch</small> 2053 </div> 2054 <div class="settings-toggle-group settings-toggle-group--stretch" id="langToggleGroup"> 2055 <button type="button" class="settings-toggle-btn" onclick="window.setLanguage('cs')" data-lang="cs" data-i18n="settings_lang_btn_cs"><span class="settings-lang-flag" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 900 600"><rect width="900" height="600" fill="#d7141a"/><rect width="900" height="300" fill="#fff"/><path fill="#11457e" d="M0 0 450 300 0 600z"/></svg></span><span class="settings-lang-code">CS</span></button> 2056 <button type="button" class="settings-toggle-btn" onclick="window.setLanguage('en')" data-lang="en" data-i18n="settings_lang_btn_en"><span class="settings-lang-flag" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 30"><clipPath id="uk-s"><path d="M0,0 v30 h60 v-30 z"/></clipPath><clipPath id="uk-t"><path d="M30,15 h30 v15 z v-30 z h-30 z h-30 z v15 z v-15 z"/></clipPath><g clip-path="url(#uk-s)"><path fill="#012169" d="M0,0 v30 h60 v-30 z"/><path stroke="#fff" stroke-width="6" d="M0,0 L60,30 M60,0 L0,30"/><path stroke="#C8102E" stroke-width="4" clip-path="url(#uk-t)" d="M0,0 L60,30 M60,0 L0,30"/><path stroke="#fff" stroke-width="10" d="M30,0 v30 M0,15 h60"/><path stroke="#C8102E" stroke-width="6" d="M30,0 v30 M0,15 h60"/></g></svg></span><span class="settings-lang-code">EN</span></button> 2057 <button type="button" class="settings-toggle-btn" onclick="window.setLanguage('de')" data-lang="de" data-i18n="settings_lang_btn_de"><span class="settings-lang-flag" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 5 3"><rect width="5" height="1" fill="#000"/><rect y="1" width="5" height="1" fill="#D00"/><rect y="2" width="5" height="1" fill="#FFCE00"/></svg></span><span class="settings-lang-code">DE</span></button> 2058 </div> 2059 </div> 2060 </details> 2061 2062 <!-- 1. OSOBNà ÃDAJE --> 2063 <details class="settings-section app-disclosure"> 2064 <summary class="settings-section__title"><span data-i18n="settings_personal_title"><i data-icon="user"></i> Osobnà údaje</span></summary> 2065 <div class="settings-form-grid"> 2066 <div> 2067 <label for="userProfileName"><span data-i18n="settings_personal_name_label">Jméno</span></label> 2068 <input type="text" id="userProfileName" data-i18n="settings_personal_name_placeholder" data-i18n-attr="placeholder" placeholder="NapÅ. Jan Novák"> 2069 </div> 2070 <div> 2071 <label for="userProfileEmail"><span data-i18n="settings_personal_email_label">E-mail</span></label> 2072 <input type="email" id="userProfileEmail" data-i18n="settings_personal_email_placeholder" data-i18n-attr="placeholder" placeholder="[email protected]"> 2073 </div> 2074 <div> 2075 <label for="userProfilePhone"><span data-i18n="settings_personal_phone_label">Telefonnà ÄÃslo</span></label> 2076 <input type="tel" id="userProfilePhone" data-i18n="settings_personal_phone_placeholder" data-i18n-attr="placeholder" placeholder="+420 777 123 456"> 2077 </div> 2078 </div> 2079 </details> 2080 2081 <!-- 2. NOTIFIKACE --> 2082 <details class="settings-section app-disclosure"> 2083 <summary class="settings-section__title"><span data-i18n="settings_notif_section_title"><i data-icon="bell"></i> Notifikace</span></summary> 2084 <div class="settings-row"> 2085 <div class="settings-row__label">
2086 <span data-i18n="settings_push_title">Push notifikace</span> 2087 <small id="pushStatusText">Povolte pro pÅipomÃnky a upozornÄnÃ</small> 2088 </div> 2089 <button type="button" class="btn-base btn-primary settings-action-btn btn-inline" id="btnPushToggle" onclick="window.togglePushNotifikace()">Povolit</button> 2090 </div> 2091 <div class="settings-row settings-row--sub settings-row--divider-top"> 2092 <div class="settings-row__label"> 2093 <span data-i18n="settings_notif_preferred_time">Äas zasÃlánà upozornÄnÃ</span> 2094 <small data-i18n="settings_notif_preferred_hint">Preferovaný Äas dennÃho shrnutà (zaÅÃzenà / doruÄenà může mÃrnÄ posunout).</small> 2095 </div> 2096 <input type="time" id="notifPreferredTime" class="settings-time-input" step="300" data-i18n="settings_notif_aria_preferred_time" data-i18n-attr="aria-label" aria-label="Äas upozornÄnÃ"> 2097 </div> 2098 <div class="settings-inline-heading"><span data-i18n="settings_notif_global_title">Globálnà upozornÄnÃ</span></div> 2099 <div class="settings-row settings-row--sub"> 2100 <div class="settings-row__label"><span data-i18n="settings_notif_health_label"><i data-icon="heart"></i> UpozornÄnà na oÄkovánà a zdravÃ</span><small data-i18n="settings_notif_global_hint">Jedno souhrnné upozornÄnà pro vybrané psy</small></div> 2101 <label class="settings-switch"><input type="checkbox" id="notifHealthGlobal" checked><span class="settings-switch__track"></span></label> 2102 </div> 2103 <div class="settings-row settings-row--sub"> 2104 <div class="settings-row__label"><span data-i18n="settings_notif_training_label">📅 UpozornÄnà na trénink</span><small data-i18n="settings_notif_global_hint">Jedno souhrnné upozornÄnà pro vybrané psy</small></div> 2105 <label class="settings-switch"><input type="checkbox" id="notifTrainingGlobal" checked><span class="settings-switch__track"></span></label> 2106 </div> 2107 2108 <div class="settings-row settings-row--sub"> 2109 <div class="settings-row__label"> 2110 <span data-i18n="settings_notif_dogs_label">VýbÄr psů pro upozornÄnÃ</span> 2111 <small data-i18n="settings_notif_dogs_hint">Zvolte, pro které psy chcete dostávat globálnà notifikace.</small> 2112 </div> 2113 </div> 2114 <div id="notifDogList" class="notif-dog-list"></div> 2115 2116 <!-- PÅIPOMÃNKY REPORTU --> 2117 <div class="settings-inline-heading" style="margin-top:12px;"><span data-i18n="settings_notif_report_heading"><i data-icon="envelope"></i> Automatické pÅipomÃnky pÅehledu</span></div> 2118 <div class="settings-row settings-row--sub" style="background:var(--bg-surface2,#f7f1eb);border-radius:8px;padding:10px 14px;margin:4px 0;flex-direction:column;align-items:flex-start;gap:10px;"> 2119 <!-- Týdennà pÅipomÃnka --> 2120 <div style="display:flex;align-items:center;justify-content:space-between;width:100%;gap:10px;"> 2121 <div class="settings-row__label" style="margin:0;"> 2122 <span data-i18n="settings_notif_report_weekly_title"><i data-icon="calendar"></i> Týdennà pÅehled</span> 2123 <small data-i18n="settings_notif_report_weekly_hint">
2123PÅipomene v zvolený den a Äas</small> 2124 </div> 2125 <label class="settings-switch settings-switch--small"> 2126 <input type="checkbox" id="notifReportWeekly" onchange="window._notifReportToggleRow('weekly',this.checked)"> 2127 <span class="settings-switch__track"></span> 2128 </label> 2129 </div> 2130 <div id="notifReportWeeklyRow" style="display:none;width:100%;display:none;flex-wrap:wrap;gap:8px;align-items:center;"> 2131 <select id="notifReportWeeklyDay" style="flex:1;min-width:130px;padding:8px 10px;border:1px solid var(--border);border-radius:8px;font-size:16px !important;background:var(--bg-input,#fff);color:var(--text-primary);"></select> 2132 <input type="time" class="settings-time-input" id="notifReportWeeklyTime" value="08:00" step="300" data-i18n="settings_notif_aria_weekly_time" data-i18n-attr="aria-label" aria-label="Äas týdennà pÅipomÃnky"> 2133 </div> 2134 </div> 2135 <div class="settings-row settings-row--sub" style="background:var(--bg-surface2,#f7f1eb);border-radius:8px;padding:10px 14px;margin:4px 0;flex-direction:column;align-items:flex-start;gap:10px;"> 2136 <!-- MÄsÃÄnà pÅipomÃnka --> 2137 <div style="display:flex;align-items:center;justify-content:space-between;width:100%;gap:10px;"> 2138 <div class="settings-row__label" style="margin:0;"> 2139 <span data-i18n="settings_notif_report_monthly_title"><i data-icon="calendar-days"></i> MÄsÃÄnà pÅehled</span> 2140 <small data-i18n="settings_notif_report_monthly_hint">PÅipomene vybraný den v mÄsÃci</small> 2141 </div> 2142 <label class="settings-switch settings-switch--small"> 2143 <input type="checkbox" id="notifReportMonthly" onchange="window._notifReportToggleRow('monthly',this.checked)"> 2144 <span class="settings-switch__track"></span> 2145 </label> 2146 </div> 2147 <div id="notifReportMonthlyRow" style="display:none;width:100%;flex-wrap:wrap;gap:8px;align-items:center;"> 2148 <select id="notifReportMonthlyDay" style="flex:1;min-width:130px;padding:8px 10px;border:1px solid var(--border);border-radius:8px;font-size:16px !important;background:var(--bg-input,#fff);color:var(--text-primary);"></select> 2149 <input type="time" class="settings-time-input" id="notifReportMonthlyTime" value="
214908:00" step="300" data-i18n="settings_notif_aria_monthly_time" data-i18n-attr="aria-label" aria-label="Äas mÄsÃÄnà pÅipomÃnky"> 2150 </div> 2151 </div> 2152 <div style="padding:4px 14px 8px;font-size:11px;color:var(--text-muted);line-height:1.5;" data-i18n="settings_notif_report_tip"> 2153 <i data-icon="lightbulb" data-icon-class="icon-accent"></i> PÅipomÃnka funguje jako upozornÄnà (notification) v prohlÞeÄi. V den odeslánà se zobrazà i banner pÅÃmo v aplikaci â staÄà kliknout a pÅehled se vygeneruje a odeÅ¡le jednÃm tapem. 2154 </div> 2155 </details> 2156 2157 <!-- 3. VZHLED --> 2158 <details class="settings-section app-disclosure"> 2159 <summary class="settings-section__title"><span data-i18n="settings_appearance_title">🌓 Vzhled (svÄtelný režim)</span></summary> 2160 <div class="settings-row settings-row--theme"> 2161 <div class="settings-row__label"> 2162 <span data-i18n="settings_theme_label">Barevný režim</span> 2163 <small data-i18n="settings_theme_hint">SvÄtlý, tmavý nebo podle systému</small> 2164 </div> 2165 <div class="settings-toggle-group settings-toggle-group--stretch" id="themeToggleGroup"> 2166 <button type="button" class="settings-toggle-btn" onclick="window.setTheme('light')" data-theme="light">☀ <span data-i18n="settings_theme_day">Den</span></button> 2167 <button type="button" class="settings-toggle-btn" onclick="window.setTheme('dark')" data-theme="dark">☾ <span data-i18n="settings_theme_night">Noc</span></button> 2168 <button type="button" class="settings-toggle-btn" onclick="window.setTheme('system')" data-theme="system"><span data-i18n="settings_theme_auto">Automaticky</span></button> 2169 </div> 2170 </div> 2171 </details> 2172 2173 <!-- INSTALACE APLIKACE (PWA) --> 2174 <details class="settings-section app-disclosure" id="settingsPwaInstallSection"> 2175 <summary class="settings-section__title"><span data-i18n="settings_pwa_section_title"><i data-icon="device-phone-mobile"></i> Instalace aplikace</span></summary> 2176 <div class="settings-section__body settings-pwa-body"> 2177 <p class="settings-hint settings-hint--pad" data-i18n="settings_pwa_intro">Mushmaster PRO jde nainstalovat na plochu telefonu nebo do Docku na Macu â funguje jako appka, vÄetnÄ offline režimu a notifikacÃ.</p> 2178 2179 <div id="pwaInstallStatus" class="settings-pwa-status" role="status"></div> 2180 2181 <div class="settings-pwa-actions"> 2182 <button type="button" id="btnPwaInstallNative" class="btn-base btn-primary settings-action-btn settings-action-btn--wide" onclick="window.mmPwaInstall()" style="display:none;"> 2183 <span data-i18n="settings_pwa_btn_install">Instalovat aplikaci</span> 2184 </button> 2185 <button type="button" id="btnPwaInstallGuide" class="btn-base btn-outline settings-action-btn settings-action-btn--wide" onclick="window.mmPwaShowGuideModal()"> 2186 <span data-i18n="settings_pwa_btn_guide">Návod krok za krokem</span> 2187 </button> 2188 </div> 2189 2190 <p class="settings-inline-heading" style="margin-top:16px;"><span data-i18n="settings_pwa_guides_heading">Návody podle zaÅÃzenÃ</span></p> 2191 2192 <details class="settings-pwa-guide-block" id="pwaGuideIos" open> 2193 <summary class="settings-pwa-guide-block__title" data-i18n="settings_pwa_guide_ios_title">iPhone a iPad (Safari)</summary> 2194 <div class="settings-pwa-guide-text" data-i18n="settings_pwa_guide_ios_body"></div> 2195 </details> 2196 <details class="settings-pwa-guide-block" id="pwaGuideMac"> 2197 <summary class="settings-pwa-guide-block__title" data-i18n="settings_pwa_guide_mac_title">MacBook (Safari)</summary> 2198 <div class="settings-pwa-guide-text" data-i18n="settings_pwa_guide_mac_body"></div> 2199 </details> 2200 <details class="settings-pwa-guide-block" id="pwaGuideChrome"> 2201 <summary class="settings-pwa-guide-block__title" data-i18n="settings_pwa_guide_chrome_title">Android, Windows a Chrome na Macu</summary> 2202 <div class="settings-pwa-guide-text" data-i18n="settings_pwa_guide_chrome_body"></div> 2203 </details> 2204 </div> 2205 </details> 2206 2207 <!-- 3b. ANALYTIKA, ZÃTÄŽ A DASHBOARD --> 2208 <details class="settings-section app-disclosure"> 2209 <summary class="settings-section__title"><span data-i18n="settings_smartload_section_title"><i data-icon="chart-bar"></i> Analytika, zátÄž a Dashboard</span></summary> 2210 2211 <div class="settings-row settings-row--sub"> 2212 <div class="settings-row__label"> 2213 <div class="label-with-help" style="margin-bottom:2px;"><span data-i18n="settings_smartload_weather_label">Zohlednit vliv poÄasà na únavu psa</span><button type="button" class="help-trigger" data-help-key="smartload-weather" data-i18n="settings_help_aria_smartload" data-i18n-attr="aria-label" aria-label="NápovÄda k vlivu poÄasÃ"><i data-icon="information-circle" data-icon-size="16"></i></button></div> 2214 <small data-i18n="settings_smartload_weather_hint">ZapnÄte, pokud zadáváte Äisté RPE výkonu a chcete, aby aplikace automaticky pÅiÄetla zátÄž za horko a vlhkost. VypnÄte, pokud si RPE kvůli teplu už sami n
2214avyÅ¡ujete.</small> 2215 </div> 2216 <label class="settings-switch"><input type="checkbox" id="settingsSmartLoadWeather"><span class="settings-switch__track"></span></label> 2217 </div> 2218 2219 <div class="settings-row settings-row--sub"> 2220 <div class="settings-row__label"> 2221 <span data-i18n="settings_help_mode_label"><i data-icon="question-mark-circle"></i> Interaktivnà nápovÄda</span> 2222 <small data-i18n="settings_help_mode_hint">Zobrazuje ? ikonky u metrik s vysvÄtlenÃm. Lze rychle pÅepÃnat tlaÄÃtkem <strong>?</strong> v hlaviÄce.</small> 2223 </div> 2224 <label class="settings-switch"><input type="checkbox" id="helpModeCheckbox" onchange="window.setHelpMode(this.checked)"><span class="settings-switch__track"></span></label> 2225 </div> 2226 2227 <div class="settings-row settings-row--sub"> 2228 <div class="settings-row__label"> 2229 <span data-i18n="settings_marketing_label"><i data-icon="envelope"></i> OdbÄr novinek e-mailem</span> 2230 <small data-i18n="settings_marketing_hint">ZapnÄte, pokud chcete dostávat novinky a tipy e-mailem. Kdykoli lze vypnout zde nebo odkazem v e-mailu.</small> 2231 </div> 2232 <label class="settings-switch"><input type="checkbox" id="settingsMarketingConsent"><span class="settings-switch__track"></span></label> 2233 </div> 2234 2235 <div class="settings-inline-heading"><span data-i18n="settings_dash_prefs_heading">Výchozà nastavenà Dashboardu</span></div> 2236 2237 <div class="settings-row settings-row--sub"> 2238 <div class="settings-row__label"> 2239 <span data-i18n="settings_dash_period_label">Výchozà Äasové rozpÄtà grafů</span> 2240 <small data-i18n="settings_dash_period_hint">Aplikuje se pÅi každém naÄtenà grafů na Dashboardu.</small> 2241 </div> 2242 <select id="settingsDashPeriod" class="settings-select" style="font-size:16px!important;"> 2243 <option value="30">30 dnÃ</option> 2244 <option value="60">60 dnÃ</option> 2245 <option value="90">90 dnÃ</option> 2246 </select> 2247 </div> 2248 2249 <div class="settings-row settings-row--sub"> 2250 <div class="settings-row__label"> 2251 <span data-i18n="settings_dash_grid_label">Rozvrženà pro PC (poÄet sloupců)</span> 2252 <small data-i18n="settings_dash_grid_hint">Platà pro obrazovky Å¡ÃÅky ? 1024 px.</small> 2253 </div> 2254 <select id="settingsDashGrid" class="settings-select" style="font-size:16px!important;"> 2255 <option value="1">1 sloupec (plná Å¡ÃÅka)</option> 2256 <option value="2">2 sloupce</option> 2257 <option value="3">3 sloupce</option> 2258 </select> 2259 </div> 2260 2261 <div class="settings-row settings-row--sub"> 2262 <div class="settings-row__label"> 2263 <span data-i18n="settings_dash_weekstart_label">ZaÄátek týdne</span> 2264 </div> 2265 <select id="settingsDashWeekStart" class="settings-select" style="font-size:16px!important;"> 2266 <option value="monday">PondÄlÃ</option> 2267 <option value="sunday">NedÄle</option> 2268 </select> 2269 </div> 2270 2271 <div class="settings-row settings-row--sub"> 2272 <div class="settings-row__label">
2273 <span data-i18n="settings_dash_empty_days_label">Zobrazovat dny bez záznamu v grafech</span> 2274 <small data-i18n="settings_dash_empty_days_hint">VypnÄte pro kompaktnÄjšà grafy bez prázdných sloupků.</small> 2275 </div> 2276 <label class="settings-switch"><input type="checkbox" id="settingsDashEmptyDays" checked><span class="settings-switch__track"></span></label> 2277 </div> 2278 2279 </details> 2280 2281 <!-- 4. SPRÃVA PSÅ® + GARÃŽ (profilové vybavenÃ) --> 2282 <details class="settings-section app-disclosure"> 2283 <summary class="settings-section__title"><span data-i18n="settings_dogs_section_title"><i data-icon="dog"></i> Správa psů a vybavenÃ</span></summary> 2284 <p class="settings-hint settings-hint--pad" data-i18n="settings_dogs_garage_intro">Garáž patÅà k úÄtu, ne ke každému psovi zvlášť. V garáži u položky zaÅ¡krtnÄte psy, kteÅà ji smà použÃvat â jednu vÄc mohou sdÃlet dva psi. Když nikoho nevyberete, položku může použÃt každý váš vlastnà pes.</p> 2285 <div id="settingsDogList" class="settings-hub-list"></div> 2286 <div class="settings-hub-actions settings-hub-actions--row"> 2287 <button type="button" class="btn-base btn-primary settings-action-btn settings-action-btn--wide" onclick="window.otevritDogModal(false)"><span data-i18n="settings_dogs_add">+ PÅidat nového psa</span></button> 2288 <button type="button" class="btn-base btn-outline settings-action-btn" onclick="window.otevritVybaveni()"><span data-i18n="settings_equipment_open_garage_full"><i data-icon="briefcase"></i> Celá garáž</span></button> 2289 </div> 2290 </details> 2291 2292 <!-- Správa tréninkových mÃst (PRO â sekce viditelná ve FREE, po rozbalenà paywall) --> 2293 <details id="settingsTrainingLocations" class="settings-section app-disclosure"> 2294 <summary class="settings-section__title settings-section__title--with-pro"> 2295 <span data-i18n="settings_locations_section_title"><i data-icon="map-pin"></i> Správa tréninkových mÃst</span> 2296 <span id="settingsLocationsProBadge" class="badge-pro badge-pro--settings-inline">PRO</span> 2297 </summary> 2298 <p class="settings-hint settings-hint--pad" data-i18n="settings_locations_intro">Uložená mÃsta se použÃvajà v PlánovaÄi a pÅi výbÄru lokace. PÅidej mÃsto na mapÄ, uprav název nebo souÅadnice, pÅÃpadnÄ záznam smaž.</p> 2299 <div id="settingsLocationsList" class="settings-locations-list"></div> 2300 <div class="settings-hub-actions settings-hub-actions--row"> 2301 <button type="button" class="btn-base btn-primary settings-action-btn settings-action-btn--wide" onclick="window.openFullMapPickerForNewLocation()"><span data-i18n="settings_locations_add">+ PÅidat tréninkové mÃsto (mapa)</span></button> 2302 </div> 2303 </details> 2304 2305 <!-- 5. PÅEDPLATNà --> 2306 <details class="settings-section app-disclosure"> 2307 <summary class="settings-section__title"><span data-i18n="settings_subscription_title"><i data-icon="currency-dollar"></i> Správa pÅedplatného</span></summary> 2308 <div class="settings-subscription-panel"> 2309 <p class="settings-hint" id="settingsSubscriptionHint" data-i18n="settings_subscription_panel_hint_free">Zvolte mÄsÃÄnÃ, půlroÄnà nebo roÄnà tarif a odemknÄte vÅ¡echny PRO funkce.</p> 2310 <button type="button" class="settings-subscription-btn" id="btnSpravovatPredplatne" onclick="window.spravovatPredplatne()"><span data-i18n="settings_subscription_btn_buy">ZÃskat PRO pÅedplatné</span></button> 2311 </div> 2312 </details> 2313 2314 <!-- 6. ZÃNA NEBEZPEÄNÃCH AKCà --> 2315 <div class="settings-delete-account-zone"> 2316 <details class="settings-section app-disclosure settings-section--danger"> 2317 <summary class="settings-section__title settings-section__title--danger">
2318 <span data-i18n="danger_zone_title"><i data-icon="shield-exclamation"></i> Zóna nebezpeÄných akcÃ</span> 2319 </summary> 2320 <div class="settings-delete-account-body"> 2321 2322 <!-- 1. Export zálohy tréninků --> 2323 <div class="danger-zone-item danger-zone-item--safe"> 2324 <div class="danger-zone-item__header"> 2325 <i data-icon="arrow-up-tray"></i> 2326 <div> 2327 <strong data-i18n="danger_export_backup_title">Export a záloha tréninků</strong> 2328 <span class="settings-hint" style="display:block;margin:2px 0 0;" data-i18n="danger_export_backup_hint">Stáhne tréninky ve formátu CSV/JSON pro zálohu nebo pÅenos.</span> 2329 </div> 2330 </div> 2331 <button type="button" id="btnExport" class="btn-base btn-outline settings-action-btn" onclick="window.showExportModal()" data-i18n="danger_export_backup_btn"> 2332 <i data-icon="arrow-up-tray"></i> Exportovat zálohu tréninků 2333 </button> 2334 </div> 2335 2336 <!-- 2. Export mých dat (GDPR) --> 2337 <div class="danger-zone-item danger-zone-item--safe"> 2338 <div class="danger-zone-item__header"> 2339 <i data-icon="arrow-down-tray"></i> 2340 <div> 2341 <strong data-i18n="danger_gdpr_export_title">Stáhnout vÅ¡echna má data (GDPR)</strong> 2342 <span class="settings-hint" style="display:block;margin:2px 0 0;" data-i18n="danger_gdpr_export_hint">Ãplný export úÄtu, psů, tréninků a nastavenà ve formátu JSON â právo na pÅenositelnost dle GDPR Äl. 20.</span> 2343 </div> 2344 </div> 2345 <button type="button" id="btnExportData" class="btn-base btn-outline settings-action-btn" onclick="window.exportUserData()" data-i18n="danger_gdpr_export_btn"> 2346 <i data-icon="arrow-down-tray"></i> Stáhnout export dat (JSON) 2347 </button> 2348 </div> 2349 2350 <!-- 3. Smazánà tréninků (destruktivnÃ, ale bez smazánà úÄtu) --> 2351 <div class="danger-zone-item danger-zone-item--warn"> 2352 <div class="danger-zone-item__header"> 2353 <i data-icon="exclamation-triangle" style="color:#e65100;"></i> 2354 <div> 2355 <strong style="color:#e65100;" data-i18n="danger_delete_trainings_title">Smazat vÅ¡echna tréninková data v cloudu</strong> 2356 <span class="settings-hint" style="display:block;margin:2px 0 0;" data-i18n="danger_delete_trainings_hint">NevratnÄ odstranà celou historii tréninků. ÃÄet a profily psů zůstanou zachovány.</span> 2357 </div> 2358 </div> 2359 <button type="button" class="btn-base btn-danger settings-action-btn" onclick="window.vymazatHistorii()" data-i18n="danger_delete_trainings_btn"> 2360 <i data-icon="exclamation-triangle"></i> Smazat vÅ¡echna tréninková data 2361 </button> 2362 </div> 2363 2364 <!-- 4. Smazánà celého úÄtu (nejdestruktivnÄjÅ¡Ã) --> 2365 <div class="danger-zone-item danger-zone-item--delete"> 2366 <div class="danger-zone-item__header"> 2367 <i data-icon="trash" style="color:#c62828;"></i> 2368 <div> 2369 <strong style="color:#c62828;" data-i18n="danger_delete_account_title">Smazat celý úÄet a vÅ¡echna data</strong>
2370 <span class="settings-hint" style="display:block;margin:2px 0 0;" data-i18n="danger_delete_account_hint">Trvale odstranà váš profil, vÅ¡echny psy i tréninky ze serverů Mushmaster. <strong>Nelze vzÃt zpÄt.</strong></span> 2371 </div> 2372 </div> 2373 <button type="button" id="btnDeleteAccount" class="btn-base btn-danger settings-action-btn" onclick="window.deleteUserAccount()" data-i18n="danger_delete_account_btn"> 2374 <i data-icon="trash"></i> Smazat úÄet a vÅ¡echna data 2375 </button> 2376 </div> 2377 2378 </div> 2379 </details> 2380 </div> 2381 2382 <!-- PatiÄka nastavenÃ: návod + GDPR, pak uložit --> 2383 <div class="settings-hub-bottom"> 2384 <div class="settings-hub-legal-links"> 2385 <button type="button" class="settings-hub-legal-link" onclick="window.otevritUserGuideModal()"> 2386 <i data-icon="document-text"></i> <span data-i18n="settings_user_guide_btn">Uživatelský návod</span> 2387 </button> 2388 <button type="button" class="settings-hub-legal-link" onclick="window.otevritGdprModal()"> 2389 <i data-icon="shield-check"></i> <span data-i18n="settings_gdpr_btn">Zásady ochrany soukromà (GDPR)</span> 2390 </button> 2391 </div> 2392 <div class="settings-hub-footer"> 2393 <button type="button" class="btn-base btn-outline settings-action-btn settings-action-btn--ghost" onclick="window.ulozNastaveniUzivatele()"><span data-i18n="settings_save_now_btn">Uložit nastavenà teÄ</span></button> 2394 <small class="settings-hub-footer-note" data-i18n="settings_save_now_hint">RuÄnà uloženà â automatické ukládánà už probÄhlo pÅi zmÄnách výše.</small> 2395 </div> 2396 </div> 2397 </div> 2398 </div> 2399 2400 <div id="tab-admin" class="tab-content" style="display:none;"> 2401 <div class="sekce settings-hub-wrap"> 2402 <h2 style="margin-bottom:6px;"><span data-i18n="admin_title">📧 Admin â rozesÃlánÃ</span></h2> 2403 <p class="settings-hub-intro" data-i18n="admin_intro">RozesÃlánà newsletterů a hromadných notifikacà uživatelům aplikace. Viditelné pouze pro administrátora.</p> 2404 2405 <details class="settings-section app-disclosure" open> 2406 <summary class="settings-section__title"><span data-i18n="admin_subscriptions_section"><i data-icon="credit-card"></i> Klienti a pÅedplatné</span></summary> 2407 <div class="settings-section__body" style="padding:10px 4px;"> 2408 <p class="settings-hint" style="margin:0 0 10px;" data-i18n="admin_subscriptions_intro">PÅehled aktivnÃch PRO pÅedplatných. Äástky jsou aktuálnà ceny tarifů; úÄetnÃm zdrojem plateb zůstává Stripe.</p> 2409 <div id="adminSubscriptionsSummary" class="admin-audience-counts" data-i18n="admin_subscriptions_loading">NaÄÃtám pÅehled pÅedplatnýchâ¦</div> 2410 <div style="display:flex;flex-wrap:wrap;gap:8px;margin:12px 0;"> 2411 <input type="search" id="adminSubscriptionSearch" class="settings-select" style="flex:1 1 180px;min-width:0;font-size:16px!important;" data-i18n="admin_subscriptions_search_ph" data-i18n-attr="placeholder" placeholder="Hledat podle e-mailu"> 2412 <select id="adminSubscriptionStatus" class="settings-select" style="flex:0 1 170px;min-width:0;font-size:16px!important;"> 2413 <option value="live" data-i18n="admin_subscriptions_filter_live">Aktivnà a trial</option> 2414 <option value="all" data-i18n="admin_subscriptions_filter_all">VÅ¡echny záznamy</option> 2415 <option value="active" data-i18n="admin_subscriptions_filter_active">Jen platÃcÃ</option> 2416 <option value="trialing" data-i18n="admin_subscriptions_filter_trial">Jen trial</option> 2417 </select> 2418 <button type="button" id="adminSubscriptionsRefreshBtn" class="btn-base btn-outline btn-small" onclick="window.loadAdminSubscriptionsOverview()"><span data-i18n="admin_subscriptions_refresh">Obnovit</span></button> 2419 </div> 2420 <div id="adminSubscriptionsList"></div> 2421 </div> 2422 </details> 2423 2424 <details class="settings-section app-disclosure"> 2425 <summary class="settings-section__title"><span data-i18n="admin_diag_section"><i data-icon="search"></i> Diagnostika uživatele</span></summary> 2426 <div class="settings-section__body" style="padding:10px 4px;"> 2427 <p class="settings-hint" style="margin:0 0 10px;" data-i18n="admin_diag_intro">Zjistà skuteÄný stav konkrétnÃho úÄtu â Firebase Auth, hlavnà dokument i podkolekce (psi, historie) â když se uživateli "ztratÃ" data nebo je vidÄt v platÃcÃch, ale ne mezi uživateli.</p> 2428 <div style="display:flex;flex-wrap:wrap;gap:8px;margin:0 0 12px;"> 2429 <input type="text" id="adminDiagInput" class="settings-select" style="flex:1 1 220px;min-width:0;font-size:16px!important;" data-i18n="admin_diag_input_ph" data-i18n-attr="placeholder" placeholder="UID nebo e-mail uživatele"> 2430 <button type="button" id="adminDiagBtn" class="btn-base btn-primary btn-small" onclick="window.adminLookupUserDiagnostics()"><span data-i18n="admin_diag_search">Vyhledat</span></button> 2431 </div> 2432 <div id="adminDiagResult"></div> 2433 </div> 2434 </details> 2435 2436 <details class="settings-section app-disclosure" open> 2437 <summary class="settings-section__title"><span data-i18n="admin_email_section"><i data-icon="envelope"></i> Newsletter (e-mail)</span></summary> 2438 <div class="settings-section__body" style="padding:10px 4px;"> 2439 <label class="settings-row__label" style="display:block;margin-bottom:4px;" data-i18n="admin_email_subject_label">PÅedmÄt</label> 2440 <input type="text" id="adminEmailSubject" class="settings-select" style="width:100%;font-size:16px!important;margin-bottom:10px;" data-i18n="admin_email_subject_ph" data-i18n-attr="placeholder" placeholder="PÅedmÄt e-mailu"> 2441 2442 <label class="settings-row__label" style="display:block;margin-bottom:4px;" data-i18n="admin_email_body_label">Obsah (HTML povoleno)</label> 2443 <textarea id="adminEmailBody" class="settings-select" style="width:100%;min-height:160px;font-size:16px!important;margin-bottom:10px;resize:vertical;" data-i18n="admin_email_body_ph" data-i18n-attr="placeholder" placeholder="Text e-mailu. Můžete použÃt HTML (napÅ. <b>tuÄnÄ</b>, <a href>odkaz</a>)."></textarea> 2444 2445 <label class="settings-row__label" style="display:block;margin-bottom:4px;" data-i18n="admin_audience_label">PÅÃjemci</label> 2446 <select id="adminEmailAudienceType" class="settings-select" style="width:100%;font-size:16px!important;margin-bottom:8px;"> 2447 <option value="consent" data-i18n="admin_aud_consent">Se souhlasem (newsletter)</option> 2448 <option value="registered" data-i18n="admin_aud_registered">VÅ¡ichni registrovanà (provoznÃ)</option> 2449 <option value="test" data-i18n="admin_audience_test">Jen testovacà (admin)</option> 2450 </select> 2451 <label class="settings-row__label" style="display:block;margin-bottom:4px;" data-i18n="admin_lang_label">Jazyk</label> 2452 <select id="adminEmailLang" class="settings-select" style="width:100%;font-size:16px!important;margin-bottom:8px;"> 2453 <option value="all" data-i18n="admin_lang_all">VÅ¡ichni</option> 2454 <option value="cs" data-i18n="admin_audience_cs">ÄeÅ¡tina</option> 2455 <option value="en" data-i18n="admin_audience_en">English</option> 2456 <option value="de" data-i18n="admin_audience_de">
2456Deutsch</option> 2457 </select> 2458 <div id="adminEmailCountSelected" class="admin-audience-selected" style="display:none;"></div> 2459 <div id="adminEmailCountsPanel" class="settings-hint admin-audience-counts" style="margin-bottom:12px;"> 2460 <div style="display:flex;justify-content:space-between;align-items:center;gap:8px;margin-bottom:6px;"> 2461 <span data-i18n="admin_counts_email_title">PoÄty pÅÃjemců e-mailu</span> 2462 <button type="button" class="btn-base btn-outline btn-small" onclick="window.refreshAdminAudienceCounts()"><span data-i18n="admin_counts_refresh">Obnovit</span></button> 2463 </div> 2464 <div id="adminEmailCountsBody" data-i18n="admin_counts_loading">NaÄÃtámâ¦</div> 2465 </div> 2466 2467 <button type="button" id="adminEmailSendBtn" class="btn-base btn-primary settings-action-btn settings-action-btn--wide" onclick="window.adminSendNewsletter()"><span data-i18n="admin_email_send">Odeslat newsletter</span></button> 2468 <div id="adminEmailResult" style="display:none;font-size:13px;margin-top:10px;font-weight:600;"></div> 2469 </div> 2470 </details> 2471 2472 <details class="settings-section app-disclosure"> 2473 <summary class="settings-section__title"><span data-i18n="admin_push_section"><i data-icon="bell"></i> Hromadná push notifikace</span></summary> 2474 <div class="settings-section__body" style="padding:10px 4px;"> 2475 <label class="settings-row__label" style="display:block;margin-bottom:4px;" data-i18n="admin_push_title_label">Titulek</label> 2476 <input type="text" id="adminPushTitle" class="settings-select" style="width:100%;font-size:16px!important;margin-bottom:10px;" data-i18n="admin_push_title_ph" data-i18n-attr="placeholder" placeholder="Titulek notifikace"> 2477 2478 <label class="settings-row__label" style="display:block;margin-bottom:4px;" data-i18n="admin_push_body_label">Text</label> 2479 <textarea id="adminPushBody" class="settings-select" style="width:100%;min-height:80px;font-size:16px!important;margin-bottom:10px;resize:vertical;" data-i18n="admin_push_body_ph" data-i18n-attr="placeholder" placeholder="Text notifikace"></textarea> 2480 2481 <label class="settings-row__label" style="display:block;margin-bottom:4px;" data-i18n="admin_push_link_label">Odkaz po kliknutà (volitelné)</label> 2482 <input type="text" id="adminPushLink" class="settings-select" style="width:100%;font-size:16px!important;margin-bottom:10px;" placeholder="https://â¦"> 2483 2484 <label class="settings-row__label" style="display:block;margin-bottom:4px;" data-i18n="admin_audience_label">PÅÃjemci</label> 2485 <select id="adminPushAudience" class="settings-select" style="width:100%;font-size:16px!important;margin-bottom:8px;"> 2486 <option value="all" data-i18n="admin_audience_all_push">VÅ¡echna zaÅÃzenÃ</option> 2487 <option value="cs" data-i18n="admin_audience_cs">ÄeÅ¡tina</option> 2488 <option value="en" data-i18n="admin_audience_en">English</option> 2489 <option value="de" data-i18n="admin_audience_de">Deutsch</option> 2490 <option value="test" data-i18n="admin_audience_test">Jen testovacà (admin)</option> 2491 </select> 2492 <div id="adminPushCountSelected" class="admin-audience-selected" style="display:none;"></div> 2493 <div id="adminPushCountsPanel" class="settings-hint admin-audience-counts" style="margin-bottom:12px;"> 2494 <div style="display:flex;justify-content:space-between;align-items:center;gap:8px;margin-bottom:6px;">
2495 <span data-i18n="admin_counts_push_title">PoÄty push zaÅÃzenÃ</span> 2496 <button type="button" class="btn-base btn-outline btn-small" onclick="window.refreshAdminAudienceCounts()"><span data-i18n="admin_counts_refresh">Obnovit</span></button> 2497 </div> 2498 <div id="adminPushCountsBody" data-i18n="admin_counts_loading">NaÄÃtámâ¦</div> 2499 </div> 2500 2501 <button type="button" id="adminPushSendBtn" class="btn-base btn-primary settings-action-btn settings-action-btn--wide" onclick="window.adminSendPush()"><span data-i18n="admin_push_send">Odeslat notifikaci</span></button> 2502 <div id="adminPushResult" style="display:none;font-size:13px;margin-top:10px;font-weight:600;"></div> 2503 </div> 2504 </details> 2505 2506 <details class="settings-section app-disclosure"> 2507 <summary class="settings-section__title"><span data-i18n="admin_history_section"><i data-icon="clock"></i> Historie kampanÃ</span></summary> 2508 <div class="settings-section__body" style="padding:10px 4px;"> 2509 <button type="button" class="btn-base btn-outline btn-small" style="margin-bottom:10px;" onclick="window.loadAdminCampaigns()"><span data-i18n="admin_history_refresh">Obnovit</span></button> 2510 <div id="adminCampaignsList"></div> 2511 </div> 2512 </details> 2513 </div> 2514 </div> 2515 </div><!-- /#appObsah --> 2516 </div><!-- /#mainApp --> 2517</div><!-- /.app-shell --> 2518<nav class="bottom-nav"> 2519 <div class="nav-item active" id="nav-tab-historie" onclick="window.switchTab('tab-historie')"><i data-icon="document-text" data-icon-size="22"></i><span data-i18n="nav_denik">DENÃK</span></div> 2520 <div class="nav-item" id="nav-tab-zapis" onclick="window.switchTab('tab-zapis')"><i data-icon="pencil-square" data-icon-size="22"></i><span data-i18n="nav_zapis">ZÃPIS</span></div> 2521 <div class="nav-item" id="nav-tab-plan" onclick="window.switchTab('tab-plan')"><i data-icon="compass" data-icon-size="22"></i><span data-i18n="nav_planovac">PLÃNOVAÄ</span></div> 2522 <div class="nav-item" id="nav-tab-dashboard" onclick="window.switchTab('tab-dashboard')"><i data-icon="arrow-trending-up" data-icon-size="22"></i><span data-i18n="nav_dashboard">DASHBOARD</span></div> 2523 <div class="nav-item" id="nav-tab-nastaveni" onclick="window.switchTab('tab-nastaveni')"><i data-icon="cog-6-tooth" data-icon-size="22"></i><span data-i18n="nav_nastaveni">NASTAVENÃ</span></div> 2524 <div class="nav-item" id="nav-tab-admin" onclick="window.switchTab('tab-admin')" style="display:none;"><i data-icon="paper-airplane" data-icon-size="22"></i><span data-i18n="nav_admin">ADMIN</span></div> 2525 2526 <div id="sidebarAuth" style="display:none;"> 2527 <button id="sidebarLoginBtn" class="btn-small btn-blue sidebar-auth-btn" onclick="window.prihlasitSe()" style="display:none;" data-i18n="btn_prihlasit" data-i18n-attr="title" title="PÅihlásit"><i data-icon="user" data-icon-size="18"></i><span class="sidebar-auth-btn__label" data-i18n="btn_prihlasit">PÅIHLÃSIT</span></button> 2528 <button id="sidebarLogoutBtn" class="btn-small btn-cancel sidebar-auth-btn" onclick="window.odhlasitSe()" style="display:none;" data-i18n="btn_odhlasit" data-i18n-attr="title" title="Odhlásit"><i data-icon="power" data-icon-size="18"></i><span class="sidebar-auth-btn__label" data-i18n="btn_odhlasit">ODHLÃSIT</span></button> 2529 <button onclick="window.showExportModal()" title="Export tréninků" style="background:none;border:1px solid rgba(255,255,255,0.15);border-radius:6px;color:var(--text-muted);font-size:11px;font-weight:700;cursor:pointer;padding:6px 4px;width:100%;margin:0;min-height:0;"><i data-icon="arrow-up-tray"></i> Export</button> 2530 <button type="button" onclick="window.openBugReportModal()" style="background:var(--orange);color:#fff;border:none;border-radius:6px;display:block;text-align:center;width:100%;cursor:pointer;font-size:12px;font-weight:700;padding:6px 4px;"><i data-icon="exclamation-triangle"></i> BUG</button> 2531 </div> 2532</nav> 2533</div> 2534 2535<!-- ========== BUG REPORT MODAL ========== --> 2536<div id="bugReportModal" class="modal-overlay" style="display:none; z-index:9998; align-items:flex-end; padding:0;"> 2537 <div class="modal-box bug-report-modal-box" style="max-width:480px; width:100%; border-radius:var(--radius-md) var(--radius-md) 0 0; padding:0; max-height:92vh; overflow-y:auto;"> 2538 <div style="display:flex; justify-content:space-between; align-items:center; padding:16px 18px 12px; border-bottom:1px solid var(--border); position:sticky; top:0; background:var(--bg-surface); z-index:1;"> 2539 <div style="display:flex; align-items:center; gap:8px;">
2540 <span style="font-size:20px;">🐛</span> 2541 <h3 style="margin:0; font-size:16px; font-weight:700;" data-i18n="bug_modal_title">Nahlásit chybu</h3> 2542 </div> 2543 <button class="modal-close" onclick="window.closeBugReportModal()" aria-label="ZavÅÃt"><i data-icon="x-mark"></i></button> 2544 </div> 2545 <form id="bugReportForm" onsubmit="return false;" style="padding:16px 18px; display:flex; flex-direction:column; gap:14px;"> 2546 2547 <div> 2548 <label class="settings-row__label" style="display:block; margin-bottom:8px;" data-i18n="bug_category_label">Kategorie problému</label> 2549 <div id="bugCategoryPicker" style="display:grid; grid-template-columns:1fr 1fr; gap:8px;"> 2550 <button type="button" class="bug-cat-btn" data-cat="ui"> 2551 <span class="bug-cat-icon">🖥️</span> 2552 <span data-i18n="bug_cat_ui">Zobrazenà / UI</span> 2553 </button> 2554 <button type="button" class="bug-cat-btn" data-cat="data"> 2555 <span class="bug-cat-icon">📊</span> 2556 <span data-i18n="bug_cat_data">VýpoÄet / data</span> 2557 </button> 2558 <button type="button" class="bug-cat-btn" data-cat="crash"> 2559 <span class="bug-cat-icon">💥</span> 2560 <span data-i18n="bug_cat_crash">Pád / crash</span> 2561 </button> 2562 <button type="button" class="bug-cat-btn" data-cat="idea"> 2563 <span class="bug-cat-icon">💡</span> 2564 <span data-i18n="bug_cat_idea">Návrh na zlepÅ¡enÃ</span> 2565 </button> 2566 </div> 2567 <input type="hidden" id="bugCategoryValue" value=""> 2568 </div> 2569 2570 <div> 2571 <label class="settings-row__label" for="bugDescription" style="display:block; margin-bottom:6px;" data-i18n="bug_desc_label">Popis problému</label> 2572 <textarea id="bugDescription" class="settings-select" style="width:100%; min-height:110px; font-size:16px!important; resize:vertical;" data-i18n="bug_desc_ph" data-i18n-attr="placeholder" placeholder="Co se stalo? Kde? Co jsi oÄekával?"></textarea> 2573 </div> 2574 2575 <div> 2576 <label class="settings-row__label" style="display:block; margin-bottom:6px;" data-i18n="bug_image_label">Screenshot (volitelné)</label> 2577 <div id="bugImageArea" style="display:flex; flex-direction:column; gap:8px;"> 2578 <label for="bugImageInput" class="btn-base btn-outline" style="cursor:pointer; text-align:center; display:block; padding:10px;"> 2579 <i data-icon="camera"></i> <span data-i18n="bug_image_btn">PÅidat obrázek</span> 2580 </label> 2581 <input type="file" id="bugImageInput" accept="image/*" style="display:none;" onchange="window._bugHandleImage(this)"> 2582 <div id="bugImagePreview" style="display:none; position:relative; border-radius:8px; overflow:hidden; max-height:180px;"> 2583 <img id="bugImagePreviewImg" src="" alt="Screenshot" style="width:100%; object-fit:cover; display:block; max-height:180px;"> 2584 <button type="button" onclick="window._bugRemoveImage()" style="position:absolute; top:6px; right:6px; background:rgba(0,0,0,0.6); border:none; border-radius:50%; width:28px; height:28px; color:#fff; cursor:pointer; font-size:14px; display:flex; align-items:center; justify-content:center;"><i data-icon="x-mark"></i></button> 2585 </div> 2586 <div id="bugImageInfo" style="font-size:11px; color:var(--text-muted); display:none;"></div> 2587 </div> 2588 </div> 2589 2590 <div id="bugUserInfo" style="font-size:12px; color:var(--text-muted); background:var(--bg-surface2); border-radius:8px; padding:10px 12px; line-height:1.7;"> 2591 <span data-i18n="bug_account_label">Tvůj úÄet:</span> <strong id="bugUserEmail">â</strong><br> 2592 <span data-i18n="bug_auto_info">UID a informace o zaÅÃzenà budou pÅiloženy automaticky.</span> 2593 </div> 2594 2595 <div id="bugSubmitError" style="display:none; color:#b3261e; font-size:13px; font-weight:600; border-radius:8px; background:rgba(179,38,30,0.1); padding:10px 12px;"></div> 2596 2597 <button type="button" id="bugSubmitBtn" class="btn-base btn-primary settings-action-btn--wide" onclick="window.submitBugReport()" style="font-size:16px; padding:14px;">
2598 <span id="bugSubmitLabel" data-i18n="bug_submit_btn">Odeslat hlášenÃ</span> 2599 </button> 2600 </form> 2601 </div> 2602</div> 2603<!-- ====================================== --> 2604 2605<div id="detailModal" class="modal-overlay" style="display:none; z-index:9997; align-items:flex-start; padding:16px 0 32px; overflow:hidden;"> 2606 <div id="detailModalBox" class="modal-box modal-scroll-region" style="max-width:480px; width:95%; padding:0; overflow-y:auto; border-radius:var(--radius-md); max-height:90vh;"> 2607 <div style="display:flex; justify-content:space-between; align-items:center; padding:14px 18px; border-bottom:1px solid var(--border);"> 2608 <div> 2609 <h3 id="detailModalTitle" style="margin:0; font-size:16px; color:var(--text-primary);" data-i18n="detail_title_default">Detail aktivity</h3> 2610 <div id="detailModalSub" style="font-size:12px; color:var(--text-muted); margin-top:2px;"></div> 2611 </div> 2612 <button class="modal-close" onclick="window.zavritDetailModal()" aria-label="ZavÅÃt"><i data-icon="x-mark"></i></button> 2613 </div> 2614 <div id="detailModalBody" style="padding:16px 18px; display:flex; flex-direction:column; gap:8px;"> 2615 <div id="shareable-activity-card" style="background:var(--bg-surface2);color:var(--text-primary);border-radius:12px;padding:0;"> 2616 <div id="shareCardInner"></div> 2617 <div id="intervalVizual" style="display:none;padding:12px 0 4px;"></div> 2618 </div> 2619 </div> 2620 <div id="detailComplianceNote" style="padding:0 18px 4px;"></div> 2621 <div class="detail-modal-actions" style="padding:12px 18px 16px; border-top:1px solid var(--border);"> 2622 <button class="act-icon-btn act-icon-btn--wide green" id="detailBtnTrasa" data-i18n="detail_btn_track" data-tip-i18n="detail_tip_track" data-tip="Zobrazit trasu" style="display:none;" onclick="window._detailAkce('trasa')"><i data-icon="map"></i> Trasa</button> 2623 <button class="act-icon-btn act-icon-btn--wide purple" id="detailBtnSplits" data-i18n="detail_btn_splits" data-tip-i18n="detail_tip_splits" data-tip="MeziÄasy" style="display:none;" onclick="window._detailAkce('splits')"><i data-icon="chart-bar"></i> Splity</button> 2624 <button class="act-icon-btn act-icon-btn--wide blue" id="detailBtnRealizovat" data-i18n="detail_btn_realize" data-tip-i18n="detail_tip_realize" data-tip="Realizovat plán" style="display:none;" onclick="window._detailAkce('realizovat')"><i data-icon="check-circle"></i> Realizovat</button> 2625 <button class="act-icon-btn act-icon-btn--wide maroon" id="detailBtnShare" data-i18n="detail_btn_share" data-tip-i18n="detail_tip_share" data-tip="SdÃlet aktivitu" onclick="window._detailAkce('share')"><i data-icon="share"></i> SdÃlet</button> 2626 <button class="act-icon-btn act-icon-btn--wide act-icon-btn--outline" id="detailBtnMove" data-i18n="detail_btn_move" data-tip-i18n="detail_tip_move" data-tip="PÅesunout do jiného dne" style="display:none;" onclick="window._detailAkce('move')"><i data-icon="calendar"></i> PÅesunout</button> 2627 <button class="act-icon-btn act-icon-btn--wide act-icon-btn--outline" id="detailBtnEdit" data-i18n="detail_btn_edit" data-tip-i18n="detail_tip_edit" data-tip="Upravit záznam" onclick="window._detailAkce('edit')"><i data-icon="pencil"></i> Upravit</button> 2628 <button class="act-icon-btn act-icon-btn--wide red" id="detailBtnDelete" data-i18n="detail_btn_delete" data-tip-i18n="detail_tip_delete" data-tip="Smazat záznam" onclick="window._detailAkce('delete')"><i data-icon="trash"></i> Smazat</button> 2629 </div> 2630 <div id="detailSplitsContainer" style="padding:0 18px 14px; display:none;"></div> 2631 </div> 2632</div> 2633 2634<!-- VýbÄr jazyka (prvnà spuÅ¡tÄnÃ) â trilingvnÃ, aby ho pochopil každý uživatel --> 2635<div id="languageModal" class="modal-overlay" style="display:none; z-index:9999; align-items:center; padding:16px;"> 2636 <div class="modal-box" style="max-width:380px; width:92%; padding:0; overflow:hidden; border-radius:var(--radius-md);"> 2637 <div style="padding:20px 20px 6px; text-align:center;"> 2638 <div class="lang-modal-flags" aria-hidden="true">
2639 <span class="settings-lang-flag"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 900 600"><rect width="900" height="600" fill="#d7141a"/><rect width="900" height="300" fill="#fff"/><path fill="#11457e" d="M0 0 450 300 0 600z"/></svg></span> 2640 <span class="settings-lang-flag"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 30"><clipPath id="langModalHead-uk-s"><path d="M0,0 v30 h60 v-30 z"/></clipPath><clipPath id="langModalHead-uk-t"><path d="M30,15 h30 v15 z v-30 z h-30 z h-30 z v15 z v-15 z"/></clipPath><g clip-path="url(#langModalHead-uk-s)"><path fill="#012169" d="M0,0 v30 h60 v-30 z"/><path stroke="#fff" stroke-width="6" d="M0,0 L60,30 M60,0 L0,30"/><path stroke="#C8102E" stroke-width="4" clip-path="url(#langModalHead-uk-t)" d="M0,0 L60,30 M60,0 L0,30"/><path stroke="#fff" stroke-width="10" d="M30,0 v30 M0,15 h60"/><path stroke="#C8102E" stroke-width="6" d="M30,0 v30 M0,15 h60"/></g></svg></span> 2641 <span class="settings-lang-flag"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 5 3"><rect width="5" height="1" fill="#000"/><rect y="1" width="5" height="1" fill="#D00"/><rect y="2" width="5" height="1" fill="#FFCE00"/></svg></span> 2642 </div> 2643 <h3 style="margin:8px 0 2px; font-size:17px; color:var(--text-primary);">Vyber jazyk</h3> 2644 <div style="font-size:12px; color:var(--text-muted);">Choose language · Sprache wählen</div> 2645 </div> 2646 <div style="display:flex; flex-direction:column; gap:8px; padding:14px 20px 4px;"> 2647 <button type="button" class="lang-choice-btn" onclick="window.setLanguage('cs',{fromPrompt:true})"><span class="settings-lang-flag" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 900 600"><rect width="900" height="600" fill="#d7141a"/><rect width="900" height="300" fill="#fff"/><path fill="#11457e" d="M0 0 450 300 0 600z"/></svg></span><span>ÄeÅ¡tina</span></button> 2648 <button type="button" class="lang-choice-btn" onclick="window.setLanguage('en',{fromPrompt:true})"><span class="settings-lang-flag" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 30"><clipPath id="langModal-uk-s"><path d="M0,0 v30 h60 v-30 z"/></clipPath><clipPath id="langModal-uk-t"><path d="M30,15 h30 v15 z v-30 z h-30 z h-30 z v15 z v-15 z"/></clipPath><g clip-path="url(#langModal-uk-s)"><path fill="#012169" d="M0,0 v30 h60 v-30 z"/><path stroke="#fff" stroke-width="6" d="M0,0 L60,30 M60,0 L0,30"/><path stroke="#C8102E" stroke-width="4" clip-path="url(#langModal-uk-t)" d="M0,0 L60,30 M60,0 L0,30"/><path stroke="#fff" stroke-width="10" d="M30,0 v30 M0,15 h60"/><path stroke="#C8102E" stroke-width="6" d="M30,0 v30 M0,15 h60"/></g></svg></span><span>English</span></button> 2649 <button type="button" class="lang-choice-btn" onclick="window.setLanguage('de',{fromPrompt:true})"><span class="settings-lang-flag" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 5 3"><rect width="5" height="1" fill="#000"/><rect y="1" width="5" height="1" fill="#D00"/><rect y="2" width="5" height="1" fill="#FFCE00"/></svg></span><span>Deutsch</span></button> 2650 </div> 2651 <label style="display:flex; align-items:center; gap:8px; padding:12px 20px 18px; font-size:12px; color:var(--text-muted); cursor:pointer; line-height:1.35;"> 2652 <input type="checkbox" id="langDontAskAgain" style="width:18px; height:18px; flex:0 0 auto;"> 2653 <span>Nezobrazovat pÅÃÅ¡tÄ · Don't ask again · Nicht mehr fragen</span> 2654 </label> 2655 </div> 2656</div> 2657 2658<div id="shareModal" class="modal-overlay" style="display:none; z-index:9998; align-items:flex-start; padding:12px 0 24px; overflow-y:auto;"> 2659 <div class="modal-box" style="max-width:480px; width:95%; padding:0; overflow:hidden; border-radius:var(--radius-md);"> 2660 <div style="display:flex; justify-content:space-between; align-items:center; padding:14px 18px; border-bottom:1px solid var(--border);"> 2661 <h3 style="margin:0; font-size:16px; color:var(--text-primary);"><i data-icon="share"></i> SdÃlet aktivitu</h3> 2662 <button class="modal-close" onclick="window.zavritShare()" aria-label="ZavÅÃt"><i data-icon="x-mark"></i></button> 2663 </div> 2664 <div style="padding:14px 18px 10px;"> 2665 <div class="share-preview-wrap share-preview-wrap--square" id="sharePreviewWrap">
2666 <canvas id="shareCanvas" width="1080" height="1080"></canvas> 2667 <div id="sharePhotoHint" style="position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;pointer-events:none;"> 2668 <div style="color:var(--text-muted);"><i data-icon="camera" data-icon-size="36"></i></div> 2669 <div style="font-size:12px;color:rgba(255,255,255,.45);font-weight:500;">Vyber pozadà nÞe</div> 2670 </div> 2671 </div> 2672 </div> 2673 <div style="padding:0 14px 16px; display:flex; flex-direction:column; gap:12px;"> 2674 <div class="share-gesture-hint">Å tÃtek můžete pÅesouvat prstem a dvÄma prsty zvÄtÅ¡ovat/zmenÅ¡ovat.</div> 2675 2676 <details class="share-accordion app-disclosure" open> 2677 <summary><i data-icon="photo"></i> Pozadà a Tvar</summary> 2678 <div class="share-accordion__body"> 2679 <div style="display:grid; grid-template-columns:1fr 1fr; gap:8px;" id="shareBgCards"> 2680 <label class="share-bg-card active" id="shareBgPhoto" for="sharePhotoGallery"> 2681 <input type="file" id="sharePhotoGallery" accept="image/*" style="display:none;"> 2682 <div class="share-bg-icon"><i data-icon="photo" data-icon-size="24"></i></div><div class="share-bg-label">Fotka</div><div class="share-bg-sub">z galerie</div> 2683 </label> 2684 <label class="share-bg-card" id="shareBgCamera" for="sharePhotoCamera"> 2685 <input type="file" id="sharePhotoCamera" accept="image/*" capture="environment" style="display:none;"> 2686 <div class="share-bg-icon"><i data-icon="camera" data-icon-size="24"></i></div><div class="share-bg-label">Foťák</div><div class="share-bg-sub">vyfotit teÄ</div> 2687 </label> 2688 <div class="share-bg-card" id="shareBgMap" onclick="window.shareSetBg('map')"> 2689 <div class="share-bg-icon"><i data-icon="map" data-icon-size="24"></i></div><div class="share-bg-label">Mapa</div><div class="share-bg-sub" id="shareBgMapSub">GPX trasa</div> 2690 </div> 2691 <div class="share-bg-card" id="shareBgDark" onclick="window.shareSetBg('dark')"> 2692 <div style="display:flex;align-items:center;gap:10px;width:100%;"> 2693 <div class="share-bg-icon" style="margin-bottom:0;"><i data-icon="moon" data-icon-size="20"></i></div> 2694 <div style="text-align:left;"> 2695 <div class="share-bg-label" style="margin-bottom:0;">Tmavé pozadÃ</div> 2696 <div class="share-bg-sub" style="margin-top:2px;">jen kartiÄka, bez fotky</div> 2697 </div> 2698 </div> 2699 </div> 2700 </div> 2701 <div class="share-section-title" style="margin-top:12px;">Tvar Å¡tÃtku</div> 2702 <div class="share-shape-row share-shape-row--compact" id="shareStickerTypeRow"> 2703 <label class="share-check share-check--compact"><input type="radio" name="shareStickerType" value="classic" checked> Klasický text</label> 2704 <label class="share-check share-check--compact"><input type="radio" name="shareStickerType" value="pill"> Pilulka</label> 2705 <label class="share-check share-check--compact share-check-pro"><input type="radio" name="shareStickerType" value="paw"> <i data-icon="paw"></i> Tlapka</label> 2706 <label class="share-check share-check--compact share-check-pro"><input type="radio" name="shareStickerType" value="heart"> <i data-icon="heart"></i> Srdce</label> 2707 <label class="share-check share-check--compact share-check-pro"><input type="radio" name="shareStickerType" value="mountain"> <i data-icon="flag"></i> Hora</label> 2708 </div> 2709 </div> 2710 </details> 2711 2712 <details class="share-accordion app-disclosure" id="sharePerio
2712dAccordion" open style="display:none;"> 2713 <summary><i data-icon="calendar"></i> <span data-i18n="share_period_panel_title">Obdobà k sdÃlenÃ</span></summary> 2714 <div class="share-accordion__body"> 2715 <div class="share-section-title" data-i18n="share_period_panel_type">Typ pÅehledu</div> 2716 <div class="wsp-row" id="sharePeriodTypeRow"> 2717 <span class="wsp-chip active" data-sp-type="period" onclick="window.spSetSharePeriodType('period', this)"><span data-i18n="share_period_panel_type_period">ObdobÃ</span></span> 2718 <span class="wsp-chip" data-sp-type="season" onclick="window.spSetSharePeriodType('season', this)"><span data-i18n="share_period_label_season">Sezónnà pÅehled</span></span> 2719 </div> 2720 <div id="sharePeriodRangeBlock"> 2721 <div class="share-section-title" data-i18n="dashboard_wsp_period_label">ObdobÃ:</div> 2722 <div class="wsp-row" id="sharePeriodPresetRow"> 2723 <span class="wsp-chip" data-sp-preset="week" onclick="window.spSetSharePeriodPreset('week', this)"><span data-i18n="share_period_label_week">Poslednà týden</span></span> 2724 <span class="wsp-chip active" data-sp-preset="month" onclick="window.spSetSharePeriodPreset('month', this)"><span data-i18n="share_period_label_month">Poslednà mÄsÃc</span></span> 2725 <span class="wsp-chip" data-sp-preset="60" onclick="window.spSetSharePeriodPreset('
272560', this)"><span data-i18n="share_period_preset_60">60 dnÃ</span></span> 2726 <span class="wsp-chip" data-sp-preset="90" onclick="window.spSetSharePeriodPreset('90', this)"><span data-i18n="share_period_preset_90">90 dnÃ</span></span> 2727 <span class="wsp-chip" data-sp-preset="365" onclick="window.spSetSharePeriodPreset('365', this)"><span data-i18n="share_period_preset_year">Rok</span></span> 2728 <span class="wsp-chip" data-sp-preset="custom" onclick="window.spSetSharePeriodPreset('custom', this)"><span data-i18n="share_period_label_custom">Vlastnà obdobÃ</span></span> 2729 </div> 2730 <div id="sharePeriodCustomRow" class="wsp-compare-row" style="display:none;margin-top:8px;"> 2731 <input type="date" id="sharePeriodFrom" class="date-input--compact filter-date-input" onchange="window.refreshSharePeriodFromPanel()"> 2732 <span style="color:var(--text-muted);font-size:11px;">â</span> 2733 <input type="date" id="sharePeriodTo" class="date-input--compact filter-date-input" onchange="window.refreshSharePeriodFromPanel()"> 2734 </div> 2735 </div> 2736 <hr class="wsp-divider"> 2737 <div class="share-section-title" data-i18n="share_period_format_label">Formát exportu</div> 2738 <div class="wsp-row" id="sharePeriodFormatRow"> 2739 <span class="wsp-chip active" data-sp-format="square" onclick="window.spSetSharePeriodFormat('square', this)"><span data-i18n="share_period_format_square">Ätverec 1:1</span></span> 2740 <span class="wsp-chip" data-sp-format="story" onclick="window.spSetSharePeriodFormat('story', this)"><span data-i18n="share_period_format_story">Story 9:16</span></span> 2741 </div> 2742 <hr class="wsp-divider" id="sharePeriodCompareDivider"> 2743 <label class="share-check share-check--compact" id="sharePeriodCompareLabel"> 2744 <input type="checkbox" id="sharePeriodCompareOn" onchange="window.spToggleSharePeriodCompare()"> 2745 <span data-i18n="share_period_panel_compare">Porovnat s jiným obdobÃm</span> 2746 </label> 2747 <div id="sharePeriodCompareRow" class="wsp-compare-row" style="display:none;margin-top:8px;"> 2748 <input type="date" id="sharePeriodCmpFrom" class="date-input--compact filter-date-input" onchange="window.refreshSharePeriodFromPanel()"> 2749 <span style="color:var(--text-muted);font-size:11px;">â</span> 2750 <input type="date" id="sharePeriodCmpTo" class="date-input--compact filter-date-input" onchange="window.refreshSharePeriodFromPanel()"> 2751 </div> 2752 </div> 2753 </details> 2754 2755 <details class="share-accordion app-disclosure"> 2756 <summary><i data-icon="chart-bar"></i> Zobrazené hodnoty</summary> 2757 <div class="share-accordion__body"> 2758 <div class="share-fields-wrap"> 2759 <div class="share-section-title">Zobrazit</div> 2760 <div id="shareFields" class="share-fields-grid"> 2761 <label class="share-check share-check--compact"><input type="checkbox" data-f="name" checked> Jméno psa</label> 2762 <label class="share-check share-check--compact"><input type="checkbox" data-f="sport" checked> Sport / typ</label> 2763 <label class="share-check share-check--compact"><input type="checkbox" data-f="cas" checked> Äas</label> 2764 <label class="share-check share-check--compact"><input type="checkbox" data-f="km" checked> Km</label> 2765 <label class="share-check share-check--compact"><input type="checkbox" data-f="speed"> Rychlost</label> 2766 <label class="share-check share-check--compact"><input type="checkbox" data-f="tempo" checked> Tempo</label> 2767 <label class="share-check share-check--compact"><input type="checkbox" data-f="rpe"> RPE</label> 2768 <label class="share-check share-check--compact"><input type="checkbox" data-f="teplota"> Teplota</label> 2769 <label class="share-check share-check--compact"><input type="checkbox" data-f="datum"> Datum</label> 2770 <label class="share-check share-check--compact"><input type="checkbox" data-f="tag"> Hashtag</label> 2771 <label class="share-check share-check--compact"><input type="checkbox" data-f="logo"> Logo</label> 2772 </div> 2773 </div> 2774 </div> 2775 </details> 2776 2777 <details class="share-accordion app-disclosure"> 2778 <summary><i data-icon="sparkles"></i> Vzhled a Styl</summary> 2779 <div class="share-accordion__body"> 2780 <div class="share-section-title">Barva kartiÄky</div> 2781 <div class="share-color-row"> 2782 <input type="color" id="shareColorPicker" value="#D4870A" oninput="window.shareRedraw()"> 2783 <div id="sharePremiumColors" class="share-premium-row"> 2784 <button type="button" class="share-premium-color" data-c="#C0C0C0" data-label="Silver" onclick="window.shareApplyPremiumColor(this)">Silver</button> 2785 <button type="button" class="share-premium-color" data-c="#D4AF37" data-label="Gold" onclick="window.shareApplyPremiumColor(this)">Gold</button> 2786 <button type="button" class="share-premium-color" data-c="#B76E79" data-label="Rose Gold" onclick="window.shareApplyPremiumColor(this)">Rose</button> 2787 <button type="button" class="share-premium-color" data-c="#4FC3F7" data-label="Neon Blue" onclick="window.shareApplyPremiumColor(this)">Neon</button> 2788 </div> 2789 </div> 2790 <div class="share-style-stack"> 2791 <div> 2792 <div class="share-section-title">
2792Průhlednost</div> 2793 <input type="range" id="shareOpacity" min="50" max="100" step="5" value="92" class="share-range" oninput="window.shareRedraw()"> 2794 <div class="share-section-title share-section-title--tight">ZaoblenÃ</div> 2795 <input type="range" id="shareRadius" min="0" max="80" step="8" value="32" class="share-range" oninput="window.shareRedraw()"> 2796 <div class="share-section-title share-section-title--tight">PÃsmo</div> 2797 <input type="range" id="shareFontScale" min="70" max="130" step="5" value="100" class="share-range" oninput="window.shareRedraw()"> 2798 <div class="share-style-options"> 2799 <label class="share-check share-check--compact"><input type="checkbox" id="shareUppercase" onchange="window.shareRedraw()"> Verzálky</label> 2800 <label class="share-check share-check--compact"><input type="checkbox" id="shareLabels" checked onchange="window.shareRedraw()"> Popisky hodnot</label> 2801 </div> 2802 </div> 2803 </div> 2804 </div> 2805 </details> 2806 <div class="share-action-wrap"> 2807 <button type="button" id="shareDownloadBtn" class="share-action-btn share-action-btn--primary" onclick="window.shareDownload()"><i data-icon="arrow-down-tray"></i> <span data-i18n="share_download_btn">Uložit do telefonu (PNG)</span></button> 2808 <button type="button" id="sharePeriodVideoBtn" class="share-action-btn share-action-btn--accent" style="display:none;" onclick="window.sharePeriodVideoExport()"><i data-icon="video-camera"></i> <span data-i18n="share_period_video_btn">Uložit video (Story)</span></button> 2809 <button id="shareNativeBtn" class="share-action-btn share-action-btn--accent" style="display:none;" onclick="window.shareNativeStory()"><i data-icon="camera"></i> <span data-i18n="share_story_btn">SdÃlet: Instagram / Facebook Story</span></button> 2810 <button type="button" id="shareNativePostBtn" class="share-action-btn share-action-btn--accent" onclick="window.shareNativePost()"><i data-icon="chat-bubble"></i> <span data-i18n="share_post_btn">SdÃlet: Klasický pÅÃspÄvek</span></button> 2811 </div> 2812 </div> 2813 </div> 2814</div> 2815 2816<style> 2817.share-section-title{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;color:var(--text-secondary);margin-bottom:7px;} 2818.share-section-title--tight{margin-top:7px;margin-bottom:4px;} 2819.share-premium-color{margin:0 !important;width:auto !important;min-height:30px !important;padding:4px 8px !important;font-size:10px !important;border-radius:7px;border:1px solid var(--border);background:var(--bg-surface);color:var(--text-primary);cursor:pointer;letter-spacing:.1px !important;font-weight:700 !important;text-transform:none !important;} 2820.share-premium-color.is-locked{position:relative;} 2821.share-premium-color.is-locked::before{content:"";position:absolute;left:6px;top:50%;transform:translateY(-50%);width:10px;height:10px;background:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke-width='2' stroke='%23000'><path stroke-linecap='round' stroke-linejoin='round' d='M16.5 10.5V6.75a4.5 4.5 0 10-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 002.25-2.25v-6.75a2.25 2.25 0 00-2.25-2.25H6.75a2.25 2.25 0 00-2.25 2.25v6.75a2.25 2.25 0 002.25 2.25z'/></svg>") center/contain no-repeat;} 2822.share-shape-row{display:flex;gap:12px;flex-wrap:wrap;} 2823.share-shape-row--compact{gap:6px 10px;} 2824#shareColorPicker{width:44px;height:32px;padding:0;border:none;background:none;cursor:pointer;} 2825.share-bg-card{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:12px 8px;border-radius:10px;cursor:pointer;border:2px solid var(--border);background:var(--bg-surface);transition:border-color .15s, background .15s;text-align:center; min-height:80px;} 2826.share-bg-card{height:102px;} 2827#shareBgCards .share-bg-card{margin-top:0 !important;} 2828.share-bg-card.active{border-color:var(--maroon);background:rgba(60,26,34,0.08);} 2829[data-theme="dark"] .share-bg-card.active{background:rgba(92,44,56,0.25);} 2830.share-bg-icon{font-size:24px;margin-bottom:4px;line-height:1;} 2831.share-bg-label{font-size:12px;font-weight:700;color:var(--text-primary);} 2832.share-bg-sub{font-size:10px;color:var(--text-muted);margin-top:1px;} 2833.share-check{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--text-primary);cursor:pointer;padding:2px 0;} 2834.share-check input{cursor:pointer;width:15px;height:15px;} 2835.share-check--compact{gap:6px;font-size:11px;padding:1px 0;margin:0;line-height:1.2;} 2836.share-check--compact input{width:14px;
2836height:14px;} 2837.share-check-pro{position:relative;} 2838.share-check-pro::after{content:"PRO";font-size:9px;font-weight:900;letter-spacing:.3px;color:#ff8f00;border:1px solid #ff8f00;border-radius:10px;padding:1px 5px;line-height:1;} 2839.share-accordion{border:1px solid var(--border);border-radius:10px;background:var(--bg-surface2);margin:0 4px;} 2840.share-accordion + .share-accordion{margin-top:8px;} 2841.share-accordion summary{cursor:pointer;list-style:none;padding:12px 12px;font-size:13px;font-weight:700;color:var(--text-primary);} 2842.share-accordion summary::-webkit-details-marker{display:none;} 2843.share-accordion__body{padding:0 12px 12px;} 2844.share-fields-wrap{display:flex;flex-direction:column;gap:4px;} 2845.share-fields-grid{display:grid;grid-template-columns:1fr 1fr;gap:4px 10px;} 2846.share-color-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap;} 2847.share-premium-row{display:flex;gap:5px;flex-wrap:wrap;align-items:center;} 2848.share-style-stack{display:grid;grid-template-columns:1fr;gap:6px;margin-top:6px;} 2849.share-range{width:100%;margin-top:2px;} 2850.share-style-options{display:flex;flex-direction:column;gap:4px;margin-top:6px;} 2851.share-gesture-hint{font-size:11px;color:var(--text-muted);background:var(--bg-surface2);border:1px dashed var(--border-mid);border-radius:8px;padding:8px 10px;line-height:1.45;margin:0 4px 2px;} 2852.share-action-wrap{display:flex;flex-direction:column;gap:8px;padding:10px 4px 0;margin-top:2px;border-top:1px solid var(--border);} 2853.share-action-btn{width:100% !important;height:46px !important;min-height:46px !important;border:none !important;border-radius:12px !important;font-size:13px !important;font-weight:700 !important;letter-spacing:.1px !important;font-family:inherit !important;display:flex !important;align-items:center !important;justify-content:center !important;gap:8px !important;cursor:pointer !important;margin:0 !important;margin-top:0 !important;padding:0 14px !important;line-height:1.1 !important;text-transform:none !important;} 2854.share-action-btn--primary{background:var(--maroon);color:#F8EDE5;} 2855.share-action-btn--accent{background:var(--orange);color:#fff;} 2856.share-action-btn:active{transform:translateY(1px);} 2857.share-action-btn:disabled{opacity:.55;cursor:not-allowed;transform:none;} 2858.share-preview-wrap{position:relative;width:100%;margin:0 auto;border-radius:12px;overflow:hidden;background:#111;} 2859.share-preview-wrap--square{aspect-ratio:1/1;max-width:100%;} 2860.share-preview-wrap--story{aspect-ratio:9/16;max-height:min(58vh,480px);} 2861#shareCanvas{display:block;width:100%;height:auto;touch-action:none;-ms-touch-action:none;} 2862</style> 2863 2864<div id="gpxMapModal" class="modal-overlay" style="display:none; z-index:9999;"> 2865 <div class="modal-box" style="max-width:680px; width:95%; padding:0; overflow:hidden; border-radius:var(--radius-md);"> 2866 <div style="display:flex; justify-content:space-between; align-items:center; padding:14px 18px; border-bottom:1px solid var(--border);"> 2867 <div> 2868 <h3 style="margin:0; font-size:16px; color:var(--text-primary);"><i data-icon="map"></i> Trasa aktivity</h3> 2869 <div id="gpxMapSubtitle" style="font-size:12px; color:var(--text-muted); margin-top:2px;"></div> 2870 </div> 2871 <button class="modal-close" onclick="window.zavritGpxMapu()" aria-label="ZavÅÃt"><i data-icon="x-mark"></i></button> 2872 </div> 2873 <div id="gpxMapContainer" style="height:380px; width:100%; background:var(--bg-surface2);"></div> 2874 <div id="gpxMapStats" style="padding:10px 18px; font-size:12px; color:var(--text-secondary); border-top:1px solid var(--border); display:flex; gap:16px; flex-wrap:wrap;"></div> 2875 </div> 2876</div> 2877
2878<script src="icons.js?v=9"></script>
vendor: 2 bytes, line 2878
2878
2879<script> 2880// Firebase Auth ve výchozÃm nastavenà autorizuje localhost, ne 127.0.0.1 (Live Server Äasto otevÅe právÄ IP). 2881(function() { 2882 if (window.location.hostname === '127.0.0.1') { 2883 window.location.replace(window.location.href.replace('//127.0.0.1', '//localhost')); 2884 } 2885})(); 2886</script>
2886 2887
2887<script type="module" src="firebase-db.js?v=150"></script>
2887 2888
2888<script type="module" src="module-i18n.js?v=177"></script>
2888 2889
2889<script type="module" src="app-ui.js?v=73"></script>
2889 2890
2890<script type="module" src="module-dogs.js?v=84"></script>
2890 2891
2891<script type="module" src="module-vybaveni.js?v=24"></script>
vendor: 2 bytes, line 2891
2891
2892<script type="module" src="module-planovac.js?v=219"></script>
2892 2893
2893<script type="module" src="module-zapis.js?v=114"></script>
2893 2894
2894<script type="module" src="module-denik.js?v=109"></script>
2894 2895
2895<script type="module" src="module-share.js?v=21"></script>
2895 2896
2896<script type="module" src="module-share-period.js?v=12"></script>
2896 2897
2897<script type="module" src="module-export.js?v=8"></script>
2897 2898
2898<script type="module" src="module-nastaveni.js?v=44"></script>
2898 2899
2899<script type="module" src="dashboard.js?v=164"></script>
2899 2900
2900<script type="module" src="module-badges.js?v=11"></script>
2900 2901
2901<script type="module" src="module-admin.js?v=7"></script>
2901 2902
2902<script type="module" src="module-bug.js?v=1"></script>
2902 2903
2904<script> 2905(function() { 2906 /* Äas/datum: na laptopu psanà klávesnicà + ikona pro picker; na mobilu klik otevÅe picker. */ 2907 function _isFinePointerDesktop() { 2908 try { 2909 return window.matchMedia('(hover: hover) and (pointer: fine)').matches; 2910 } catch (_) { return false; } 2911 } 2912 function _tryShowPicker(el) { 2913 try { 2914 if (typeof el.showPicker === 'function') { 2915 el.showPicker(); 2916 return true; 2917 } 2918 } catch (_) {} 2919 return false; 2920 } 2921 function _bindNative(el) { 2922 if (!el || el.dataset.dtBound) return; 2923 if (el.classList.contains('mm-duration-time')) return; 2924 if (el.classList.contains('date-input--compact') || 2925 el.classList.contains('filter-date-input') || 2926 el.classList.contains('widget-filter')) return; 2927 el.dataset.dtBound = '1'; 2928 /* Desktop: nevolat showPicker â focus+picker blokoval psanÃ. Picker = ikona vpravo. */ 2929 if (_isFinePointerDesktop()) return; 2930 el.addEventListener('click', function(e) { 2931 if (e.target !== el) return; 2932 _tryShowPicker(el); 2933 }); 2934 } 2935 function _bindAllNativeDT() { 2936 document.querySelectorAll('input[type="time"], input[type="date"]').forEach(_bindNative); 2937 } 2938 document.addEventListener('DOMContentLoaded', _bindAllNativeDT); 2939 if (typeof MutationObserver !== 'undefined') { 2940 try { 2941 new MutationObserver(function(muts) { 2942 for (var i = 0; i < muts.length; i++) { 2943 if (muts[i].addedNodes && muts[i].addedNodes.length) { 2944 _bindAllNativeDT(); 2945 break; 2946 } 2947 } 2948 }).observe(document.body, { childList: true, subtree: true }); 2949 } catch (_) {} 2950 } 2951 window.attachDtInputs = _bindAllNativeDT; 2952})(); 2953</script>
2953 2954
2955<script> 2956function _mmRunningVersion() { 2957 try { 2958 var m = (document.querySelector('meta[name="mm-app-version"]')?.getAttribute('content') || '').trim(); 2959 return m || (typeof window.__MM_APP_VERSION === 'string' ? window.__MM_APP_VERSION.trim() : ''); 2960 } catch (e) { return ''; } 2961} 2962function _mmFetchVersionJson() { 2963 return fetch('/version.json?v=' + Date.now(), { cache: 'no-store' }).then(function(r) { 2964 if (!r.ok) throw new Error('version.json http'); 2965 return r.text(); 2966 }).then(function(txt) { 2967 var body = (txt || '').trim(); 2968 if (!body || body.charAt(0) !== '{') throw new Error('version.json not json body'); 2969 return JSON.parse(body); 2970 }); 2971} 2972 2973// In-memory guard â modal se ukáže max 1à za dobu života stránky (reload ji resetuje) 2974var _mmModalShownThisSession = false; 2975 2976function _mmMaybeShowUpdateModal(v) { 2977 if (!v || !v.version) return; 2978 2979 // Modal byl v téhle JS instanci stránky už jednou zobrazen nebo odmÃtnut 2980 if (_mmModalShownThisSession) return; 2981 2982 var run = _mmRunningVersion(); 2983 2984 // Stejná verze bÄžà ⺠žádná aktualizace, ukliÄ starý klÃÄ 2985 if (run && v.version === run) { 2986 try { localStorage.removeItem('mm_offered_server_version'); } catch (e) {} 2987 return; 2988 } 2989 2990 // Uživatel tuto verzi už odmÃtl ("PÅipomenout pÅÃÅ¡tÄ" nebo "Aktualizovat nynÃ") 2991 // â neotravuj ho znovu dokud neotevÅe novou záložku / nepÅihlásà se znovu 2992 try { 2993 if (localStorage.getItem('mm_offered_server_version') === v.version) return; 2994 } catch (e) {} 2995 2996 // Nastav oba guardy: localStorage (pÅežije reload) + in-memory (rychlá ochrana v rámci záložky) 2997 try { localStorage.setItem('mm_offered_server_version', v.version); } catch (e) {} 2998 _mmModalShownThisSession = true; 2999 _showUpdateModal(v); 3000} 3001 3002function _mmCheckRemoteVersion(delayMs) { 3003 var ms = typeof delayMs === 'number' ? delayMs : 0; 3004 var run = function() { 3005 _mmFetchVersionJson() 3006 .then(function(v) { _mmMaybeShowUpdateModal(v); }) 3007 .catch(function() {}); 3008 }; 3009 if (ms > 0) setTimeout(run, ms); 3010 else run(); 3011} 3012 3013// Detekce dev prostÅedà (VS Code Live Server, lokálnà testovánÃ). 3014// V dev režimu Service Worker NEPOUŽÃVÃME â cachoval by staré verze a Live Server 3015// by nemÄl efekt (zmÄny v JS/CSS by se neprojevily bez tvrdého reloadu). 3016// Také odregistrujeme pÅÃpadného starého SW z pÅedchozà relace. 3017window._mmIsDevHost = (function() { 3018 var h = window.location.hostname; 3019 var p = window.location.port; 3020 return h === 'localhost' || 3021 h === '127.0.0.1' || 3022 h === '0.0.0.0' || 3023 h.endsWith('.local') || 3024 p === '5500' || // VS Code Live Server default 3025 p === '5501' || // Live Server alt port 3026 p === '3000' || // typical dev port 3027 p === '8080'; // typical dev port 3028})(); 3029 3030if ('serviceWorker' in navigator) { 3031 if (window._mmIsDevHost) { 3032 // DEV: odregistruj starý SW + smaž jeho cache (kvůli starým verzÃm firebase-db.js) 3033 navigator.serviceWorker.getRegistrations().then(function(regs) { 3034 regs.forEach(function(reg) { 3035 reg.unregister().then(function(ok) { 3036 if (ok) console.log('[DEV] Service Worker odregistrován pro testovánÃ'); 3037 }); 3038 }); 3039 }).catch(function() {}); 3040 if (window.caches && caches.keys) { 3041 caches.keys().then(function(keys) { 3042 keys.forEach(function(k) { 3043 if (k.indexOf('mushmaster') === 0) caches.delete(k); 3044 }); 3045 }).catch(function() {}); 3046 } 3047 } else { 3048 // PROD: standardnà registrace SW 3049 window.addEventListener('load', function() { 3050 navigator.serviceWorker.register('/sw.js', { updateViaCache: 'none' }).then(function(reg) { 3051 reg.update().catch(function() {}); 3052 reg.addEventListener('updatefound', function() { 3053 var sw = reg.installing; 3054 sw.addEventListener('statechange', function() { 3055 if (sw.state === 'installed' && navigator.serviceWorker.controller) { 3056 _mmFetchVersionJson() 3057 .then(function(v) { _mmMaybeShowUpdateModal(v); }) 3058 .catch(function() {}); 3059 } 3060 }); 3061 }); 3062 }).catch(function() {}); 3063 3064 var refreshing = false; 3065 navigator.serviceWorker.addEventListener('controllerchange', function() { 3066 if (refreshing) return; 3067 refreshing = true; 3068 try { localStorage.removeItem('mm_offered_server_version'); } catch (e) {} 3069 window.location.reload(); 3070 }); 3071 }); 3072 } 3073} 3074 3075function _mmEscHtml(s) { 3076 return String(s == null ? '' : s) 3077 .replace(/&/g, '&') 3078 .replace(/</g, '<') 3079 .replace(/>/g, '>') 3080 .replace(/"/g, '"'); 3081} 3082 3083function _mmTn(key, fallback, vars) { 3084 var text = fallback; 3085 if (typeof window.t === 'function') { 3086 var v = window.t(key); 3087 if (v && v !== key) text = v; 3088 } 3089 if (vars) {
3090 Object.keys(vars).forEach(function(k) { 3091 text = String(text).split('{' + k + '}').join(String(vars[k])); 3092 }); 3093 } 3094 return text; 3095} 3096 3097function _showUpdateModal(versionData) { 3098 if (document.getElementById('mmUpdateModal')) return; 3099 if (!versionData || !versionData.version) return; 3100 var run = _mmRunningVersion(); 3101 if (run && versionData.version === run) return; 3102 3103 const modal = document.createElement('div'); 3104 modal.id = 'mmUpdateModal'; 3105 modal.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,.6);z-index:99999;display:flex;align-items:center;justify-content:center;padding:16px;'; 3106 3107 const version = versionData ? versionData.version : ''; 3108 const dateStr = versionData ? versionData.date : ''; 3109 const highlights = _mmPickVersionHighlights(versionData); 3110 3111 // HTML-escape z version.json, aby znaky <, >, &, " nikdy nerozbily modal 3112 const itemsHtml = highlights.map(function(item) { 3113 return '<div style="display:flex;align-items:flex-start;gap:10px;padding:6px 0;border-bottom:1px solid var(--divider);">' 3114 + '<div style="flex:1;font-size:13px;color:var(--text-primary);line-height:1.5;">' + _mmEscHtml(item) + '</div></div>'; 3115 }).join(''); 3116 3117 modal.innerHTML = '<div style="background:var(--bg-app);border-radius:16px;padding:24px;max-width:420px;width:100%;box-shadow:0 16px 48px rgba(0,0,0,.4);">' 3118 + '<div style="display:flex;align-items:center;gap:12px;margin-bottom:16px;">' 3119 + '<img src="/icons/icon-72.png" style="width:48px;height:48px;border-radius:12px;">' 3120 + '<div><div style="font-size:18px;font-weight:900;color:var(--text-primary);">' + _mmEscHtml(_mmTn('update_modal_title', 'Nová verze')) + '</div>' 3121 + '<div style="font-size:12px;color:var(--text-muted);">Mushmaster PRO' + (version ? ' · v' + version : '') + (dateStr ? ' · ' + dateStr : '') + '</div></div>' 3122 + '</div>' 3123 + (itemsHtml ? '<div style="margin-bottom:18px;">' + itemsHtml + '</div>' : '') 3124 + '<button onclick="window._doUpdate()" style="width:100%;background:var(--maroon);color:#F8EDE5;border:none;border-radius:10px;padding:14px;font-size:14px;font-weight:900;cursor:pointer;margin:0;white-space:nowrap;">' + window.appIcon('bolt') + ' ' + _mmEscHtml(_mmTn('update_modal_update_now', 'Aktualizovat nynÃ')) + '</button>' 3125 + '<button onclick="window._dismissUpdate()" style="width:100%;background:none;border:none;color:var(--text-muted);font-size:12px;cursor:pointer;margin-top:10px;padding:6px;">' + _mmEscHtml(_mmTn('update_modal_remind_later', 'PÅipomenout pÅÃÅ¡tÄ')) + '</button>' 3126 + '</div>'; 3127 3128 document.body.appendChild(modal); 3129} 3130 3131function _showSmallUpdateBanner() { 3132 var b = document.createElement('div'); 3133 b.style.cssText = 'position:fixed;top:max(12px, env(safe-area-inset-top, 0px));left:50%;transform:translateX(-50%);background:#1565c0;color:#fff;border-radius:20px;padding:10px 14px;font-size:12px;font-weight:700;z-index:99999;display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:8px 12px;box-shadow:0 4px 16px rgba(0,0,0,.3);max-width:min(calc(100vw - 24px), 420px);box-sizing:border-box;'; 3134 b.innerHTML = '<span style="white-space:nowrap;line-height:1.3;">\uD83C\uDD95 ' + _mmEscHtml(_mmTn('update_banner_new', 'Nová verze!')) + '</span><button type="button" onclick="location.reload()" style="background:#fff;color:#1565c0;border:none;border-radius:10px;padding:8px 14px;font-weight:700;cursor:pointer;margin:0;min-height:44px;flex-shrink:0;white-space:nowrap;font-size:12px;width:auto;">' + _mmEscHtml(_mmTn('update_banner_btn', 'Aktualizovat')) + '</button>'; 3135 document.body.appendChild(b); 3136} 3137 3138window._doUpdate = function() { 3139 var modal = document.getElementById('mmUpdateModal'); 3140 if (modal) modal.remove(); 3141 _mmModalShownThisSession = true; // zabraÅ opakovanému zobrazenà pÅi controllerchange 3142 // PoÅ¡li SKIP_WAITING ⺠SW se aktivuje ⺠controllerchange ⺠reload 3143 // NEDÄLÃME location.reload() odtud â controllerchange handler to udÄlá za
3143nás. 3144 // Pokud SW nemáme (offline nebo nepodporovaný), udÄláme pÅÃmý reload. 3145 if (navigator.serviceWorker && navigator.serviceWorker.controller) { 3146 navigator.serviceWorker.controller.postMessage({ type: 'SKIP_WAITING' }); 3147 // Záchranný reload pokud controllerchange nepÅijde do 3 s 3148 setTimeout(function() { location.reload(true); }, 3000); 3149 } else { 3150 location.reload(true); 3151 } 3152}; 3153window._dismissUpdate = function() { 3154 var modal = document.getElementById('mmUpdateModal'); 3155 if (modal) modal.remove(); 3156 _mmModalShownThisSession = true; // zabraÅ pÅepnutà záložky ⺠opakovaný modal 3157 // mm_offered_server_version je už nastaven z _mmMaybeShowUpdateModal ⺠modal se neukáže znovu 3158 _showSmallUpdateBanner(); 3159}; 3160 3161// ââ Oznámenà novinek aktuálnà verze (max 3à pÅi otevÅenà appky) ââ 3162var _mmReleaseNotesShownThisSession = false; 3163 3164function _mmPickVersionHighlights(versionData) { 3165 if (!versionData || !versionData.highlights) return []; 3166 var h = versionData.highlights; 3167 if (Array.isArray(h)) return h; 3168 var lang = window._i18nLang || 'cs'; 3169 if (h[lang] && Array.isArray(h[lang])) return h[lang]; 3170 if (h.cs && Array.isArray(h.cs)) return h.cs; 3171 if (h.en && Array.isArray(h.en)) return h.en; 3172 return []; 3173} 3174 3175function _mmReleaseNotesStorageKey(version) { 3176 return 'mm_release_notes_' + String(version || '').replace(/\./g, '_'); 3177} 3178 3179function _mmGetReleaseNotesState(version) { 3180 try { 3181 var raw = localStorage.getItem(_mmReleaseNotesStorageKey(version)); 3182 if (!raw) return { views: 0, dismissed: false }; 3183 var parsed = JSON.parse(raw); 3184 return { 3185 views: Math.max(0, parseInt(parsed.views, 10) || 0), 3186 dismissed: !!parsed.dismissed, 3187 }; 3188 } catch (e) { 3189 return { views: 0, dismissed: false }; 3190 } 3191} 3192 3193function _mmSetReleaseNotesState(version, state) { 3194 try { 3195 localStorage.setItem(_mmReleaseNotesStorageKey(version), JSON.stringify({ 3196 views: Math.max(0, state.views || 0), 3197 dismissed: !!state.dismissed, 3198 })); 3199 } catch (e) {} 3200} 3201 3202function _mmMaybeShowReleaseNotes(v) { 3203 if (!v || !v.version) return; 3204 if (document.getElementById('mmUpdateModal') || document.getElementById('mmReleaseNotesModal')) return; 3205 3206 var run = _mmRunningVersion(); 3207 if (!run || run !== v.version) return; 3208 3209 var state = _mmGetReleaseNotesState(v.version); 3210 if (state.dismissed || state.views >= 3) return; 3211 if (_mmReleaseNotesShownThisSession) return; 3212 3213 _mmReleaseNotesShownThisSession = true; 3214 state.views += 1; 3215 _mmSetReleaseNotesState(v.version, state); 3216 _showReleaseNotesModal(v, state.views); 3217} 3218 3219function _showReleaseNotesModal(versionData, viewCount) { 3220 if (document.getElementById('mmReleaseNotesModal')) return; 3221 if (!versionData || !versionData.version) return; 3222 3223 var version = versionData.version; 3224 var dateStr = versionData.date || ''; 3225 var highlights = _mmPickVersionHighlights(versionData); 3226 3227 var _escRn = function(s) { 3228 return String(s == null ? '' : s) 3229 .replace(/&/g, '&') 3230 .replace(/</g, '<') 3231 .replace(/>/g, '>') 3232 .replace(/"/g, '"'); 3233 }; 3234 3235 var itemsHtml = highlights.map(function(item) { 3236 return '<div style="padding:8px 0;border-bottom:1px solid var(--divider);font-size:13px;color:var(--text-primary);line-height:1.55;">' 3237 + _escRn(item) + '</div>'; 3238 }).join(''); 3239 3240 var remaining = Math.max(0, 3 - (viewCount || 0)); 3241 var hintHtml = remaining > 0 3242 ? '<div style="font-size:11px;color:var(--text-muted);margin-top:10px;text-align:center;">' 3243 + _escRn(_mmTn('release_notes_remaining', 'Zbývá {n} pÅipomenutÃ', { n: remaining })) + '</div>' 3244 : ''; 3245 3246 var modal = document.createElement('div'); 3247 modal.id = 'mmReleaseNotesModal'; 3248 modal.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,.6);z-index:99998;display:flex;align-items:center;justify-content:center;padding:16px;'; 3249 modal.innerHTML = '<div style="background:var(--bg-app);border-radius:16px;padding:24px;max-width:440px;width:100%;max-height:85vh;overflow-y:auto;box-shadow:0 16px 48px rgba(0,0,0,.4);">' 3250 + '<div style="display:flex;align-items:center;gap:12px;margin-bottom:14px;">' 3251 + '<img src="/icons/icon-72.png" style="width:48px;height:48px;border-radius:12px;" alt="">' 3252 + '<div><div style="font-size:18px;font-weight:900;color:var(--text-primary);">' + _escRn(_mmTn('release_notes_title', 'Co je nového')) + '</div>' 3253 + '<div style="font-size:12px;color:var(--text-muted);">Mushmaster PRO · v' + _escRn(version) + (dateStr ? ' · ' + _escRn(dateStr) : '') + '</div></div>' 3254 + '</div>' 3255 + (itemsHtml ? '<div style="margin-bottom:14px;">' + itemsHtml + '</div>' : '') 3256 + '<label style="display:flex;align-items:flex-start;gap:10px;font-size:12px;color:var(--text-secondary);cursor:pointer;margin-bottom:14px;line-height:1.45;">' 3257 + '<input type="checkbox" id="mmReleaseNotesDontAsk" style="width:16px;height:16px;margin-top:2px;flex-shrink:0;">' 3258 + '<span>' + _escRn(_mmTn('release_notes_dont_ask', 'Nezobrazovat pÅÃÅ¡tÄ')) + '</span>' 3259 + '</label>' 3260 + '<button type="button" onclick="window._closeReleaseNotesModal()" style="width:100%;background:var(--maroon);color:#F8EDE5;border:none;border-radius:10px;padding:14px;font-size:14px;font-weight:900;cursor:pointer;margin:0;min-height:44px;">' + _escRn(_mmTn('release_notes_ok', 'RozumÃm')) + '</button>' 3261 + hintHtml 3262 + '</div>'; 3263 document.body.appendChild(modal); 3264} 3265 3266window._closeReleaseNotesModal = function() { 3267 var modal = document.getElementById('mmReleaseNotesModal'); 3268 var dontAsk = document.getElementById('mmReleaseNotesDontAsk'); 3269 var version = _mmRunningVersion(); 3270 if (dontAsk && dontAsk.checked && version) { 3271 _mmSetReleaseNotesState(version, { views: 3, dismissed: true });
3272 } 3273 if (modal) modal.remove(); 3274}; 3275 3276function _mmCheckReleaseNotes(delayMs) { 3277 var ms = typeof delayMs === 'number' ? delayMs : 0; 3278 var run = function() { 3279 _mmFetchVersionJson() 3280 .then(function(v) { _mmMaybeShowReleaseNotes(v); }) 3281 .catch(function() {}); 3282 }; 3283 if (ms > 0) setTimeout(run, ms); 3284 else run(); 3285}; 3286 3287// ¦¦ Kontrola verze: meta / __MM_APP_VERSION vs server ¦¦ 3288window.addEventListener('DOMContentLoaded', function() { 3289 _mmCheckRemoteVersion(2000); 3290 _mmCheckReleaseNotes(2800); 3291 // Aktualizuj badge verze podle skuteÄnÄ naÄteného meta tagu 3292 try { 3293 var badge = document.getElementById('appVersionBadge'); 3294 var run = _mmRunningVersion(); 3295 if (badge && run) badge.textContent = 'v' + run; 3296 } catch (e) {} 3297}); 3298 3299// ¦¦ Tvrdý reset PWA cache + Service Workera ¦¦ 3300window._mmHardRefresh = async function() { 3301 var existing = document.getElementById('mmVersionModal'); 3302 if (existing) existing.remove(); 3303 try { 3304 // 1) Smaž vÅ¡echny CacheStorage cache (PWA i Safari) 3305 if (typeof caches !== 'undefined' && caches.keys) { 3306 var keys = await caches.keys(); 3307 await Promise.all(keys.map(function(k) { return caches.delete(k); })); 3308 } 3309 // 2) Odregistruj vÅ¡echny Service Workery 3310 if ('serviceWorker' in navigator) { 3311 var regs = await navigator.serviceWorker.getRegistrations(); 3312 await Promise.all(regs.map(function(r) { return r.unregister(); })); 3313 } 3314 // 3) VyÄisti localStorage klÃÄe které blokujà re-detekci 3315 try { localStorage.removeItem('mm_offered_server_version'); } catch (e) {} 3316 } catch (e) { 3317 console.warn('[mm] hard refresh cleanup error:', e); 3318 } 3319 // 4) Hard reload â bypass cache (?_= cache-buster aby Å¡lo i pÅi offline) 3320 var sep = window.location.href.indexOf('?') === -1 ? '?' : '&'; 3321 window.location.href = window.location.href.split('#')[0] + sep + '_mm_force=' + Date.now(); 3322}; 3323 3324// ¦¦ Modal po kliknutà na badge verze v hlaviÄce ¦¦ 3325// Zobrazà changelog poslednà verze + status (aktuálnà / nová verze k dispozici). 3326// TlaÄÃtko "Vynutit reset cache" je dostupné vždy (nukleárnà možnost), 3327// "Aktualizovat na vXXX" se objevà jen pokud je server-side novÄjšà verze. 3328window._mmShowVersionModal = async function() { 3329 var existing = document.getElementById('mmVersionModal'); 3330 if (existing) { existing.remove(); return; } 3331 3332 var running = _mmRunningVersion() || '?'; 3333 var modal = document.createElement('div'); 3334 modal.id = 'mmVersionModal'; 3335 modal.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,.6);z-index:99999;display:flex;align-items:center;justify-content:center;padding:16px;'; 3336 modal.addEventListener('click', function(ev) { 3337 if (ev.target === modal) modal.remove(); 3338 }); 3339 3340 // Loading state 3341 modal.innerHTML = '<div style="background:var(--bg-app);border-radius:16px;padding:24px;max-width:480px;width:100%;box-shadow:0 16px 48px rgba(0,0,0,.4);max-height:85vh;overflow-y:auto;">' 3342 + '<div style="display:flex;align-items:center;gap:12px;margin-bottom:14px;">' 3343 + '<img src="/icons/icon-72.png" style="width:44px;height:44px;border-radius:10px;" alt="">' 3344 + '<div style="flex:1;min-width:0;">' 3345 + '<div style="font-size:18px;font-weight:900;color:var(--text-primary);line-height:1.2;">Mushmaster PRO</div>' 3346 + '<div style="font-size:12px;color:var(--text-muted);">' + _mmTn('version_modal_app_version', 'Verze v aplikaci: <strong>v{version}</strong>', { version: _mmEscHtml(running) }) + '</div>' 3347 + '</div>' 3348 + '<button type="button" onclick="document.getElementById(\'mmVersionModal\').remove()" aria-label="' + _mmEscHtml(_mmTn('version_modal_close_aria', 'ZavÅÃt')) + '" style="background:none;border:none;font-size:22px;color:var(--text-muted);cursor:pointer;padding:4px 8px;line-height:1;">Ã</button>' 3349 + '</div>' 3350 + '<div id="mmVersionModalBody" style="padding:16px 0;text-align:center;color:var(--text-muted);font-size:13px;">' + window.appIcon('clock') + ' ' + _mmEscHtml(_mmTn('version_modal_checking', 'Kontroluji verzi na serveruâ¦')) + '</div>' 3351 + '</div>'; 3352 document.body.appendChild(modal); 3353 3354 var serverVersion = null; 3355 var serverData = null; 3356 try { 3357 serverData = await _mmFetchVersionJson(); 3358 serverVersion = serverData && serverData.version ? serverData.version : null; 3359 } catch (e) { 3360 // Offline nebo chyba â zobrazÃme aspoÅ lokálnà highlights pokud je máme 3361 } 3362 3363 var body = document.getElementById('mmVersionModalBody'); 3364 if (!body) return; 3365 3366 var isUpToDate = serverVersion && serverVersion === running; 3367 var hasNewer = serverVersion && serverVersion !== running; 3368 3369 var statusHtml = ''; 3370 if (isUpToDate) { 3371 statusHtml = '<div style="background:#2e7d3215;border:1px solid #2e7d3250;border-radius:10px;padding:10px 14px;margin-bottom:14px;display:flex;align-items:center;gap:10px;">' 3372 + '<div style="color:#2e7d32;">' + window.appIcon('check-circle', { size: 22 }) + '</div>' 3373 + '<div><div style="font-weight:800;color:#2e7d32;font-size:13px;">' + _mmEscHtml(_mmTn('version_modal_status_up_to_date', 'Máš aktuálnà verzi')) + '</div>' 3374 + '<div style="font-size:11px;color:var(--text-muted);">' + _mmEscHtml(_mmTn('version_modal_status_up_to_date_sub', 'Server i aplikace bÄžà na v{version}.', { version: running })) + '</div></div>' 3375 + '</div>'; 3376 } else if (hasNewer) { 3377 statusHtml = '<div style="background:#1565c015;border:1px solid #1565c050;border-radius:10px;padding:10px 14px;margin-bottom:14px;display:flex;align-items:center;gap:10px;">' 3378 + '<div style="font-size:20px;">??</div>' 3379 + '<div><div style="font-weight:800;color:#1565c0;font-size:13px;">' + _mmEscHtml(_mmTn('version_modal_status_newer', 'Nová verze k dis
3379pozici')) + '</div>' 3380 + '<div style="font-size:11px;color:var(--text-muted);">' + _mmEscHtml(_mmTn('version_modal_status_newer_sub', 'Aplikace má v{app} · server nabÃzà v{server}.', { app: running, server: serverVersion })) + '</div></div>' 3381 + '</div>'; 3382 } else { 3383 statusHtml = '<div style="background:#ff9b0015;border:1px solid #ff9b0050;border-radius:10px;padding:10px 14px;margin-bottom:14px;display:flex;align-items:center;gap:10px;">' 3384 + '<div style="color:#e65100;"><i data-icon="exclamation-triangle" data-icon-size="20"></i></div>' 3385 + '<div><div style="font-weight:800;color:#ff9b00;font-size:13px;">' + _mmEscHtml(_mmTn('version_modal_status_unknown', 'Stav serveru se nepodaÅilo zjistit')) + '</div>' 3386 + '<div style="font-size:11px;color:var(--text-muted);">' + _mmEscHtml(_mmTn('version_modal_status_unknown_sub', 'Možná jsi offline. Nainstalovaná verze: v{version}.', { version: running })) + '</div></div>' 3387 + '</div>'; 3388 } 3389 3390 var highlightsHtml = ''; 3391 if (serverData && _mmPickVersionHighlights(serverData).length) { 3392 var dateStr = serverData.date ? ' · ' + _mmEscHtml(serverData.date) : ''; 3393 var headerLabel = hasNewer 3394 ? '<i data-icon="gift"></i> ' + _mmEscHtml(_mmTn('version_modal_changes_new', 'Co je nového ve v{version}', { version: serverVersion })) + dateStr 3395 : '<i data-icon="clipboard-document"></i> ' + _mmEscHtml(_mmTn('version_modal_changes_current', 'ZmÄny v aktuálnà verzi v{version}', { version: serverVersion })) + dateStr; 3396 var items = _mmPickVersionHighlights(serverData).map(function(h) { 3397 return '<div style="padding:8px 0;border-bottom:1px solid var(--divider);font-size:12.5px;color:var(--text-primary);line-height:1.5;">' + _mmEscHtml(h) + '</div>'; 3398 }).join(''); 3399 highlightsHtml = '<div style="font-weight:800;color:var(--text-secondary);font-size:11px;text-transform:uppercase;letter-spacing:.4px;margin-bottom:6px;">' + headerLabel + '</div>' 3400 + '<div style="margin-bottom:14px;">' + items + '</div>'; 3401 } 3402 3403 var actionsHtml = '<div style="display:flex;flex-direction:column;gap:8px;">'; 3404 if (hasNewer) { 3405 actionsHtml += '<button type="button" onclick="window._mmHardRefresh()" style="width:100%;background:#1565c0;color:#fff;border:none;border-radius:10px;padding:12px;font-size:13px;font-weight:900;cursor:pointer;min-height:44px;"><i data-icon="bolt"></i> ' + _mmEscHtml(_mmTn('version_modal_update_btn', 'Aktualizovat na v{version}', { version: serverVersion })) + '</button>'; 3406 } 3407 actionsHtml += '<button type="button" onclick="window._mmHardRefresh()" style="width:100%;background:none;border:1px solid var(--border);color:var(--text-secondary);border-radius:10px;padding:10px;font-size:12px;font-weight:700;cursor:pointer;min-height:44px;"><i data-icon="arrow-path"></i> ' + _mmEscHtml(_mmTn('version_modal_cache_reset', 'Vynutit reset cache (ÅeÅ¡enà starého obsahu)')) + '</button>'; 3408 actionsHtml += '<button type="button" onclick="document.getElementById(\'mmVersionModalBody\').parentElement.parentElement.remove()" style="width:100%;background:none;border:none;color:var(--text-muted);font-size:12px;cursor:pointer;padding:6px;min-height:36px;">' + _mmEscHtml(_mmTn('version_modal_close', 'ZavÅÃt')) + '</button>'; 3409 actionsHtml += '</div>'; 3410 3411 body.style.textAlign = 'left'; 3412 body.style.color = ''; 3413 body.innerHTML = statusHtml + highlightsHtml + actionsHtml; 3414}; 3415document.addEventListener('visibilitychange', function() { 3416 if (document.visibilityState !== 'visible') return; 3417 _mmCheckRemoteVersion(800); 3418 try { 3419 if ('serviceWorker' in navigator) { 3420 navigator.serviceWorker.getRegistration().then(function(reg) { 3421 if (reg) reg.update().catch(function() {}); 3422 }); 3423 } 3424 } catch (e) {} 3425}); 3426window.addEventListener('pageshow', function(ev) { 3427 if (ev.persisted) _mmCheckRemoteVersion(400); 3428}); 3429var _pwaEvent = null; 3430var _isIOS = /iphone|ipad|ipod/i.test(navigator.userAgent); 3431var _isMac = /macintosh|mac os x/i.test(navigator.userAgent) && !_isIOS; 3432var _isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); 3433function _pwaT(key, fb) { return (typeof window.t === 'function') ? window.t(key) : fb; } 3434function _isApp() { return window.matchMedia('(display-mode: standalone)').matches || window.navigator.standalone === true; } 3435window.mmPwaIsInstalled = _isApp; 3436window.mmPwaCanNativeInstall = function() { return !!_pwaEvent; }; 3437window.mmPwaDetectPlatform = function() { 3438 if (_isIOS) return 'ios'; 3439 if (_isMac && _isSafari) return 'macSafari'; 3440 return 'chrome'; 3441}; 3442window.addEventListener('beforeinstallprompt', function(e) { 3443 e.preventDefault(); 3444 _pwaEvent = e; 3445 if (typeof window.refreshPwaInstallSettingsUI === 'function') window.refreshPwaInstallSettingsUI();
3446 setTimeout(_maybePopup, 3000); 3447}); 3448function _maybePopup() { if (_isApp()) return; var d = localStorage.getItem('pwa_ok'); if (d && (Date.now() - Number(d)) < 72 * 3600000) return; _showPopup(); } 3449function _showPopup() { 3450 if (document.getElementById('pwaPopup')) return; 3451 var p = document.createElement('div'); p.id = 'pwaPopup'; 3452 p.style.cssText = 'position:fixed;bottom:80px;left:50%;transform:translateX(-50%);width:calc(100% - 32px);max-width:420px;background:var(--bg-app);border:2px solid var(--orange);border-radius:16px;padding:14px;z-index:9998;box-shadow:0 8px 32px rgba(0,0,0,.35);display:flex;align-items:center;gap:10px;'; 3453 var img = document.createElement('img'); img.src = '/icons/icon-192.png'; img.style.cssText = 'width:42px;height:42px;border-radius:10px;flex-shrink:0;'; img.onerror = function() { this.style.display = 'none'; }; 3454 var info = document.createElement('div'); info.style.cssText = 'flex:1;min-width:0;'; 3455 info.innerHTML = '<div style="font-size:13px;font-weight:900;color:var(--text-primary);">' + _pwaT('pwa_popup_title', 'PÅidat Mushmaster na plochu') + '</div><div style="font-size:11px;color:var(--text-muted);">' + _pwaT('pwa_popup_subtitle', 'Funguje jako appka, i offline') + '</div>'; 3456 var actionBtn = document.createElement('button'); 3457 actionBtn.textContent = _pwaEvent ? ('ð² ' + _pwaT('pwa_popup_install', 'Instalovat')) : (_pwaT('pwa_popup_howto', 'Jak na to â')); 3458 actionBtn.style.cssText = 'background:var(--orange);color:#3C1A22;border:none;border-radius:8px;padding:9px 14px;font-weight:900;font-size:12px;cursor:pointer;margin:0;min-height:0;width:auto;white-space:nowrap;'; 3459 actionBtn.onclick = _pwaEvent ? _pwaDo : function() { window.mmPwaShowGuideModal(); }; 3460 var closeBtn = document.createElement('button'); closeBtn.textContent = '\u2715'; closeBtn.style.cssText = 'background:var(--bg-surface2);color:var(--text-muted);border:none;border-radius:8px;padding:9px 10px;font-size:14px;cursor:pointer;margin:0;min-height:0;width:auto;'; closeBtn.onclick = _pwaDismiss; 3461 var btns = document.createElement('div'); btns.style.cssText = 'display:flex;gap:6px;flex-shrink:0;'; btns.appendChild(actionBtn); btns.appendChild(closeBtn); 3462 p.appendChild(img); p.appendChild(info); p.appendChild(btns); document.body.appendChild(p); 3463} 3464function _pwaDo() { if (!_pwaEvent) return; _pwaEvent.prompt(); _pwaEvent.userChoice.then(function() { _pwaEvent = null; _pwaDismiss(); if (typeof window.refreshPwaInstallSettingsUI === 'function') window.refreshPwaInstallSettingsUI(); }); } 3465window.mmPwaInstall = _pwaDo; 3466function _pwaDismiss() { var el = document.getElementById('pwaPopup'); if (el) el.remove(); localStorage.setItem('pwa_ok', String(Date.now())); } 3467function _pwaBuildGuideModal(titleKey, titleFb, stepsHtml) { 3468 var m = document.createElement('div'); 3469 m.className = 'pwa-guide-modal'; 3470 m.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,.6);z-index:99999;display:flex;align-items:flex-end;justify-content:center;'; 3471 m.onclick = function(ev) { if (ev.target === m) m.remove(); }; 3472 var box = document.createElement('div'); 3473 box.style.cssText = 'background:var(--bg-app);border-radius:16px 16px 0 0;padding:24px 20px calc(24px + env(safe-area-inset-bottom, 0px));max-width:420px;width:100%;max-height:85vh;overflow-y:auto;'; 3474 box.innerHTML = '<div style="text-align:center;margin-bottom:14px;font-size:16px;font-weight:900;">' + _pwaT(titleKey, titleFb) + '</div><div class="settings-pwa-guide-text" style="padding:0;background:var(--bg-surface);border-radius:12px;padding:14px;">' + stepsHtml + '</div>'; 3475 var okBtn = document.createElement('button'); 3476 okBtn.textContent = _pwaT('pwa_modal_ok', 'RozumÃm â'); 3477 okBtn.style.cssText = 'width:100%;margin-top:14px;background:var(--maroon);color:#F8EDE5;border:none;border-radius:10px;padding:14px;font-weight:900;cursor:pointer;display:block;min-height:44px;'; 3478 okBtn.onclick = function() { m.remove(); }; 3479 box.appendChild(okBtn); m.appendChild(box); document.body.appendChild(m); 3480} 3481window.mmPwaShowGuideModal = function() { 3482 _pwaDismiss(); 3483 var platform = window.mmPwaDetectPlatform(); 3484 if (platform === 'ios') { 3485 _pwaBuildGuideModal('pwa_modal_ios_title', 'PÅidat na plochu (iOS)', _pwaT('settings_pwa_guide_ios_body', '')); 3486 } else if (platform === 'macSafari') { 3487 _pwaBuildGuideModal('pwa_modal_mac_title', 'PÅidat do Docku (Mac)', _pwaT('settings_pwa_guide_mac_body', '')); 3488 } else { 3489 _pwaBuildGuideModal('pwa_modal_chrome_title', 'Instalace v Chrome / Edge', _pwaT('settings_pwa_guide_chrome_body', '')); 3490 } 3491}; 3492window.addEventListener('appinstalled', function() { 3493 _pwaDismiss(); 3494 if (typeof window.refreshPwaInstallSettingsUI === 'function') window.refreshPwaInstallSettingsUI();
3495}); 3496// Listen for messages from SW (notifikace click ⺠open tab / open report) 3497navigator.serviceWorker?.addEventListener('message', event => { 3498 if (event.data?.type === 'OPEN_TAB' && typeof window.switchTab === 'function') { 3499 window.switchTab(event.data.tab); 3500 } 3501 if (event.data?.type === 'OPEN_REPORT') { 3502 // OtevÅe sekci pÅehledů v dashboardu 3503 setTimeout(() => { 3504 if (typeof window.switchTab === 'function') window.switchTab('tab-dashboard'); 3505 setTimeout(() => { 3506 const hdr = document.querySelector('[data-widget-id="report"] .widget-header'); 3507 if (hdr && typeof window.reportToggleCollapse === 'function') { 3508 const content = document.getElementById('widgetContentReport'); 3509 if (content && content.style.display === 'none') window.reportToggleCollapse(hdr); 3510 } 3511 // Scrollni na widget 3512 const widget = document.querySelector('[data-widget-id="report"]'); 3513 if (widget) widget.scrollIntoView({ behavior: 'smooth', block: 'start' }); 3514 }, 400); 3515 }, 100); 3516 } 3517}); 3518 3519window.addEventListener('DOMContentLoaded', function() { 3520 var tab = new URLSearchParams(location.search).get('tab'); 3521 if (tab && typeof window.switchTab === 'function') { setTimeout(function() { window.switchTab('tab-' + tab); }, 300); } 3522 if (!_isApp() && !_pwaEvent) { setTimeout(function() { if (!_pwaEvent) _maybePopup(); }, 8000); } 3523 if (_isIOS && _isSafari && !_isApp()) { setTimeout(_maybePopup, 4000); } 3524}); 3525</script>
3525 3526<!-- ¦¦ FAB: Rychlý zápis ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ --> 3527<button id="fabZapis" onclick="window.fabOtevritZapis()" title="Zapsat trénink dnešek" aria-label="Rychlý zápis"> 3528 <span style="font-size:28px;line-height:1;font-weight:300;">+</span> 3529</button> 3530 3531</body> 3532</html> 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.