chore(ui): Formatted and cleaned up the code
This commit is contained in:
		
							parent
							
								
									ffdc4cde38
								
							
						
					
					
						commit
						46093d2b56
					
				
					 5 changed files with 638 additions and 611 deletions
				
			
		|  | @ -1,72 +1,94 @@ | |||
| {% set is_home = is_home | default(false) %} | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| <head> | ||||
|   <meta charset="UTF-8" /> | ||||
|   <meta | ||||
|     name="viewport" | ||||
|     content="width=device-width, initial-scale=1, viewport-fit=cover" | ||||
|   /> | ||||
|   <title>{% block title %}RideAware{% endblock %}</title> | ||||
|   <head> | ||||
|     <meta charset="UTF-8" /> | ||||
|     <meta | ||||
|       name="viewport" | ||||
|       content="width=device-width, initial-scale=1, viewport-fit=cover" | ||||
|     /> | ||||
|     <title>{% block title %}RideAware{% endblock %}</title> | ||||
| 
 | ||||
|   <link | ||||
|     href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" | ||||
|     rel="stylesheet" | ||||
|   /> | ||||
|   <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | ||||
|   <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet"> | ||||
|   <link | ||||
|     rel="stylesheet" | ||||
|     href="{{ url_for('static', filename='css/styles.css') }}" | ||||
|   /> | ||||
|     <!-- Icons/Fonts --> | ||||
|     <link | ||||
|       href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" | ||||
|       rel="stylesheet" | ||||
|     /> | ||||
|     <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> | ||||
|     <link | ||||
|       href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" | ||||
|       rel="stylesheet" | ||||
|     /> | ||||
| 
 | ||||
|   <link | ||||
|     rel="alternate icon" | ||||
|     type="image/png" | ||||
|     sizes="32x32" | ||||
|     href="{{ url_for('static', filename='assets/32x32.png') }}" | ||||
|   /> | ||||
|   <link | ||||
|     rel="apple-touch-icon" | ||||
|     sizes="180x180" | ||||
|     href="{{ url_for('static', filename='assets/apple-touch-icon.png') }}" | ||||
|   /> | ||||
|   <link | ||||
|     rel="manifest" | ||||
|     href="{{ url_for('static', filename='assets/site.webmanifest') }}" | ||||
|   /> | ||||
|   <meta | ||||
|     name="theme-color" | ||||
|     content="#0f172a" | ||||
|   /> | ||||
|     <!-- Core CSS --> | ||||
|     <link | ||||
|       rel="stylesheet" | ||||
|       href="{{ url_for('static', filename='css/styles.css') }}" | ||||
|     /> | ||||
| 
 | ||||
|   {% block extra_head %}{% endblock %} | ||||
| </head> | ||||
| <body> | ||||
| <nav class="navbar"> | ||||
|   <div class="nav-container"> | ||||
|     <a href="/" class="logo">Ride<span class="logo-accent">Aware</span></a> | ||||
|     <ul class="nav-links"> | ||||
|     {% if is_home %} | ||||
|         <li><a href="#features">Features</a></li> | ||||
|     {% endif %} | ||||
|     <li><a href="/newsletters">Newsletters</a></li> | ||||
|     </ul> | ||||
|   </div> | ||||
| </nav> | ||||
|     <!-- Favicons --> | ||||
|     <link | ||||
|       rel="icon" | ||||
|       type="image/png" | ||||
|       sizes="32x32" | ||||
|       href="{{ url_for('static', filename='assets/32x32.png') }}" | ||||
|     /> | ||||
|     <link | ||||
|       rel="alternate icon" | ||||
|       type="image/png" | ||||
|       sizes="32x32" | ||||
|       href="{{ url_for('static', filename='assets/32x32.png') }}" | ||||
|     /> | ||||
|     <link | ||||
|       rel="apple-touch-icon" | ||||
|       sizes="180x180" | ||||
|       href="{{ url_for('static', filename='assets/apple-touch-icon.png') }}" | ||||
|     /> | ||||
|     <link | ||||
|       rel="manifest" | ||||
|       href="{{ url_for('static', filename='assets/site.webmanifest') }}" | ||||
|     /> | ||||
|     <meta name="theme-color" content="#0f172a" /> | ||||
| 
 | ||||
|   {% block content %}{% endblock %} | ||||
|     {% block extra_head %}{% endblock %} | ||||
|   </head> | ||||
|   <body> | ||||
|     {% set is_home = is_home | default(false) %} | ||||
| 
 | ||||
|   <footer class="footer"> | ||||
|     <p>© 2025 RideAware. All rights reserved.</p> | ||||
|   </footer> | ||||
|     <nav class="navbar"> | ||||
|       <div class="nav-container"> | ||||
|         <a href="{{ url_for('index') }}" class="logo" aria-label="RideAware home"> | ||||
|           <img | ||||
|             src="{{ url_for('static', filename='assets/logo.png') }}" | ||||
|             alt="RideAware" | ||||
|             class="logo-img" | ||||
|             width="140" | ||||
|             height="28" | ||||
|             decoding="async" | ||||
|             fetchpriority="high" | ||||
|           /> | ||||
|         </a> | ||||
|         <ul class="nav-links"> | ||||
|           {% if is_home %} | ||||
|             <li><a href="#features">Features</a></li> | ||||
|           {% endif %} | ||||
|           <li><a href="{{ url_for('newsletters') }}">Newsletters</a></li> | ||||
|         </ul> | ||||
|       </div> | ||||
|     </nav> | ||||
| 
 | ||||
|   <script | ||||
|     defer | ||||
|     src="https://cdn.statically.io/gl/rideaware/landing/06d19988c7df53636277f945f9ed853bda76471b/static/js/main.min.js" | ||||
|     crossorigin="anonymous" | ||||
|   ></script> | ||||
|     {% block content %}{% endblock %} | ||||
| 
 | ||||
|   {% block extra_scripts %}{% endblock %} | ||||
| </body> | ||||
|     <footer class="footer"> | ||||
|       <p>© 2025 RideAware. All rights reserved.</p> | ||||
|     </footer> | ||||
| 
 | ||||
|     <!-- Core JS --> | ||||
|     <script | ||||
|       defer | ||||
|       src="https://cdn.statically.io/gl/rideaware/landing/06d19988c7df53636277f945f9ed853bda76471b/static/js/main.min.js" | ||||
|       crossorigin="anonymous" | ||||
|     ></script> | ||||
| 
 | ||||
|     {% block extra_scripts %}{% endblock %} | ||||
|   </body> | ||||
| </html> | ||||
|  | @ -1,392 +1,367 @@ | |||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| <head> | ||||
|     <meta charset="UTF-8"> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||
|     <title>Welcome to RideAware!</title> | ||||
|   <head> | ||||
|     <meta charset="UTF-8" /> | ||||
|     <meta http-equiv="X-UA-Compatible" content="IE=edge" /> | ||||
|     <meta | ||||
|       name="viewport" | ||||
|       content="width=device-width, initial-scale=1.0" | ||||
|     /> | ||||
|     <!--[if mso]> | ||||
|     <noscript> | ||||
|       <noscript> | ||||
|         <xml> | ||||
|             <o:OfficeDocumentSettings> | ||||
|                 <o:PixelsPerInch>96</o:PixelsPerInch> | ||||
|             </o:OfficeDocumentSettings> | ||||
|           <o:OfficeDocumentSettings> | ||||
|             <o:PixelsPerInch>96</o:PixelsPerInch> | ||||
|             <o:AllowPNG/> | ||||
|           </o:OfficeDocumentSettings> | ||||
|         </xml> | ||||
|     </noscript> | ||||
|       </noscript> | ||||
|     <![endif]--> | ||||
|     <meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||||
|     <title>Welcome to RideAware!</title> | ||||
|     <style> | ||||
|         /* Reset and base styles */ | ||||
|         * { | ||||
|             margin: 0; | ||||
|             padding: 0; | ||||
|             box-sizing: border-box; | ||||
|         } | ||||
| 
 | ||||
|         body { | ||||
|             margin: 0; | ||||
|             padding: 0; | ||||
|             font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; | ||||
|             line-height: 1.6; | ||||
|             color: #1a1a1a; | ||||
|             background-color: #f8fafc; | ||||
|             -webkit-text-size-adjust: 100%; | ||||
|             -ms-text-size-adjust: 100%; | ||||
|         } | ||||
| 
 | ||||
|         table { | ||||
|             border-collapse: collapse; | ||||
|             mso-table-lspace: 0pt; | ||||
|             mso-table-rspace: 0pt; | ||||
|         } | ||||
| 
 | ||||
|         img { | ||||
|             border: 0; | ||||
|             max-width: 100%; | ||||
|             height: auto; | ||||
|             line-height: 100%; | ||||
|             outline: none; | ||||
|             text-decoration: none; | ||||
|         } | ||||
| 
 | ||||
|         /* Email container */ | ||||
|         .email-wrapper { | ||||
|             max-width: 600px; | ||||
|             margin: 0 auto; | ||||
|             background-color: #ffffff; | ||||
|         } | ||||
| 
 | ||||
|         /* Header styles */ | ||||
|       /* Basic resets (email-safe) */ | ||||
|       html, | ||||
|       body { | ||||
|         margin: 0 !important; | ||||
|         padding: 0 !important; | ||||
|         height: 100% !important; | ||||
|         width: 100% !important; | ||||
|       } | ||||
|       * { | ||||
|         -ms-text-size-adjust: 100%; | ||||
|         -webkit-text-size-adjust: 100%; | ||||
|       } | ||||
|       table, | ||||
|       td { | ||||
|         mso-table-lspace: 0pt !important; | ||||
|         mso-table-rspace: 0pt !important; | ||||
|       } | ||||
|       img { | ||||
|         -ms-interpolation-mode: bicubic; | ||||
|         border: 0; | ||||
|         outline: none; | ||||
|         text-decoration: none; | ||||
|         display: block; | ||||
|         height: auto; | ||||
|         max-width: 100%; | ||||
|       } | ||||
|       /* Wrapper/background */ | ||||
|       .bg { | ||||
|         background-color: #f8fafc; | ||||
|       } | ||||
|       /* Container */ | ||||
|       .container { | ||||
|         width: 100%; | ||||
|         max-width: 600px; | ||||
|         margin: 0 auto; | ||||
|         background-color: #ffffff; | ||||
|       } | ||||
|       /* Header */ | ||||
|       .header { | ||||
|         background: #1e4e9c; | ||||
|         background-image: linear-gradient(135deg, #1e4e9c 0%, #337cf2 100%); | ||||
|         padding: 40px 24px; | ||||
|         text-align: center; | ||||
|         color: #ffffff; | ||||
|       } | ||||
|       .logo-text { | ||||
|         font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, | ||||
|           Helvetica, Arial, sans-serif; | ||||
|         font-weight: 800; | ||||
|         font-size: 24px; | ||||
|         line-height: 1.2; | ||||
|         color: #ffffff; | ||||
|         margin: 0 0 8px 0; | ||||
|       } | ||||
|       .logo-accent { | ||||
|         color: #00d4ff; | ||||
|       } | ||||
|       .header-title { | ||||
|         font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, | ||||
|           Helvetica, Arial, sans-serif; | ||||
|         font-size: 26px; | ||||
|         font-weight: 800; | ||||
|         margin: 6px 0 6px 0; | ||||
|         color: #ffffff; | ||||
|       } | ||||
|       .subtitle { | ||||
|         font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, | ||||
|           Helvetica, Arial, sans-serif; | ||||
|         font-size: 15px; | ||||
|         color: rgba(255, 255, 255, 0.92); | ||||
|         margin: 0; | ||||
|       } | ||||
|       /* Content */ | ||||
|       .content { | ||||
|         padding: 32px 24px; | ||||
|         text-align: center; | ||||
|       } | ||||
|       .main-message { | ||||
|         font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, | ||||
|           Helvetica, Arial, sans-serif; | ||||
|         font-size: 18px; | ||||
|         color: #1a1a1a; | ||||
|         font-weight: 600; | ||||
|         margin: 0 0 16px 0; | ||||
|       } | ||||
|       .description { | ||||
|         font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, | ||||
|           Helvetica, Arial, sans-serif; | ||||
|         font-size: 15px; | ||||
|         color: #6b7280; | ||||
|         line-height: 1.6; | ||||
|         margin: 0 0 24px 0; | ||||
|       } | ||||
|       /* Feature block */ | ||||
|       .features-wrap { | ||||
|         padding: 0 24px 24px 24px; | ||||
|       } | ||||
|       .features { | ||||
|         border: 1px solid rgba(30, 78, 156, 0.12); | ||||
|         border-radius: 12px; | ||||
|         background-color: #ffffff; | ||||
|         padding: 20px; | ||||
|       } | ||||
|       .features-title { | ||||
|         font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, | ||||
|           Helvetica, Arial, sans-serif; | ||||
|         color: #1e4e9c; | ||||
|         font-size: 18px; | ||||
|         font-weight: 700; | ||||
|         margin: 0 0 12px 0; | ||||
|         text-align: center; | ||||
|       } | ||||
|       .feature-item { | ||||
|         width: 100%; | ||||
|         text-align: left; | ||||
|         padding: 10px 12px; | ||||
|         border-radius: 10px; | ||||
|         background: #ffffff; | ||||
|         border: 1px solid rgba(2, 6, 23, 0.05); | ||||
|         margin-bottom: 10px; | ||||
|       } | ||||
|       .feature-title { | ||||
|         font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, | ||||
|           Helvetica, Arial, sans-serif; | ||||
|         font-size: 14px; | ||||
|         font-weight: 600; | ||||
|         color: #1a1a1a; | ||||
|         margin: 0 0 4px 0; | ||||
|       } | ||||
|       .feature-desc { | ||||
|         font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, | ||||
|           Helvetica, Arial, sans-serif; | ||||
|         font-size: 13px; | ||||
|         color: #6b7280; | ||||
|         margin: 0; | ||||
|       } | ||||
|       /* CTA */ | ||||
|       .cta { | ||||
|         padding: 8px 24px 32px 24px; | ||||
|         text-align: center; | ||||
|       } | ||||
|       .cta-btn { | ||||
|         font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, | ||||
|           Helvetica, Arial, sans-serif; | ||||
|         display: inline-block; | ||||
|         background: #1e4e9c; | ||||
|         background-image: linear-gradient(135deg, #1e4e9c 0%, #337cf2 100%); | ||||
|         color: #ffffff !important; | ||||
|         text-decoration: none; | ||||
|         padding: 14px 28px; | ||||
|         border-radius: 999px; | ||||
|         font-weight: 700; | ||||
|         font-size: 16px; | ||||
|       } | ||||
|       /* Social */ | ||||
|       .social { | ||||
|         background-color: #f8fafc; | ||||
|         padding: 20px 24px; | ||||
|         text-align: center; | ||||
|         border-radius: 12px; | ||||
|         margin: 0 24px 24px 24px; | ||||
|       } | ||||
|       .social-title { | ||||
|         font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, | ||||
|           Helvetica, Arial, sans-serif; | ||||
|         font-size: 15px; | ||||
|         font-weight: 700; | ||||
|         margin: 0 0 10px 0; | ||||
|         color: #1a1a1a; | ||||
|       } | ||||
|       .social-link { | ||||
|         display: inline-block; | ||||
|         width: 40px; | ||||
|         height: 40px; | ||||
|         text-decoration: none; | ||||
|         color: #ffffff !important; | ||||
|         border-radius: 50%; | ||||
|         line-height: 40px; | ||||
|         text-align: center; | ||||
|         margin: 0 6px; | ||||
|         background-image: linear-gradient(135deg, #1e4e9c 0%, #337cf2 100%); | ||||
|       } | ||||
|       /* Footer */ | ||||
|       .footer { | ||||
|         background: #1a1a1a; | ||||
|         color: #ffffff; | ||||
|         text-align: center; | ||||
|         padding: 24px; | ||||
|       } | ||||
|       .footer p { | ||||
|         margin: 6px 0; | ||||
|         font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, | ||||
|           Helvetica, Arial, sans-serif; | ||||
|         font-size: 13px; | ||||
|       } | ||||
|       .unsubscribe { | ||||
|         border-top: 1px solid rgba(255, 255, 255, 0.12); | ||||
|         margin-top: 14px; | ||||
|         padding-top: 14px; | ||||
|       } | ||||
|       .unsubscribe a { | ||||
|         color: #9ca3af !important; | ||||
|         text-decoration: none; | ||||
|         font-size: 13px; | ||||
|       } | ||||
|       .unsubscribe a:hover { | ||||
|         color: #00d4ff !important; | ||||
|         text-decoration: underline; | ||||
|       } | ||||
|       /* Mobile */ | ||||
|       @media only screen and (max-width: 600px) { | ||||
|         .header { | ||||
|             background: linear-gradient(135deg, #1e4e9c 0%, #337cf2 100%); | ||||
|             background-color: #1e4e9c; /* Fallback */ | ||||
|             padding: 50px 30px; | ||||
|             text-align: center; | ||||
|             color: white; | ||||
|           padding: 32px 18px !important; | ||||
|         } | ||||
| 
 | ||||
|         .welcome-icon { | ||||
|             font-size: 3rem; | ||||
|             margin-bottom: 20px; | ||||
|             display: block; | ||||
|         } | ||||
| 
 | ||||
|         .logo { | ||||
|             font-size: 24px; | ||||
|             font-weight: 700; | ||||
|             color: white; | ||||
|             margin-bottom: 15px; | ||||
|             display: block; | ||||
|         } | ||||
| 
 | ||||
|         .logo-accent { | ||||
|             color: #00d4ff; | ||||
|         } | ||||
| 
 | ||||
|         .header h1 { | ||||
|             color: white; | ||||
|             font-size: 28px; | ||||
|             font-weight: 800; | ||||
|             margin: 0 0 10px; | ||||
|         } | ||||
| 
 | ||||
|         .subtitle { | ||||
|             color: rgba(255, 255, 255, 0.9); | ||||
|             font-size: 16px; | ||||
|             font-weight: 300; | ||||
|             margin: 0; | ||||
|         } | ||||
| 
 | ||||
|         /* Content styles */ | ||||
|         .content { | ||||
|             padding: 40px 30px; | ||||
|             text-align: center; | ||||
|           padding: 24px 18px !important; | ||||
|         } | ||||
| 
 | ||||
|         .main-message { | ||||
|             font-size: 18px; | ||||
|             color: #1a1a1a; | ||||
|             margin-bottom: 25px; | ||||
|             font-weight: 500; | ||||
|         } | ||||
| 
 | ||||
|         .description { | ||||
|             font-size: 16px; | ||||
|             color: #6b7280; | ||||
|             margin-bottom: 35px; | ||||
|             line-height: 1.7; | ||||
|         } | ||||
| 
 | ||||
|         /* Feature highlights */ | ||||
|         .features { | ||||
|             background: linear-gradient(135deg, rgba(30, 78, 156, 0.05) 0%, rgba(0, 212, 255, 0.05) 100%); | ||||
|             background-color: #f8fafc; /* Fallback */ | ||||
|             border-radius: 12px; | ||||
|             padding: 30px 25px; | ||||
|             margin: 30px 0; | ||||
|             border: 1px solid rgba(30, 78, 156, 0.1); | ||||
|         } | ||||
| 
 | ||||
|         .features h3 { | ||||
|             color: #1e4e9c; | ||||
|             font-size: 20px; | ||||
|             font-weight: 700; | ||||
|             margin-bottom: 20px; | ||||
|         } | ||||
| 
 | ||||
|         .feature-grid { | ||||
|             width: 100%; | ||||
|         } | ||||
| 
 | ||||
|         .feature-item { | ||||
|             text-align: center; | ||||
|             padding: 15px; | ||||
|             background: white; | ||||
|             border-radius: 10px; | ||||
|             margin-bottom: 15px; | ||||
|             box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); | ||||
|         } | ||||
| 
 | ||||
|         .feature-icon { | ||||
|             font-size: 2rem; | ||||
|             margin-bottom: 8px; | ||||
|             display: block; | ||||
|         } | ||||
| 
 | ||||
|         .feature-title { | ||||
|             font-size: 14px; | ||||
|             font-weight: 600; | ||||
|             color: #1a1a1a; | ||||
|             margin-bottom: 5px; | ||||
|         } | ||||
| 
 | ||||
|         .feature-desc { | ||||
|             font-size: 12px; | ||||
|             color: #6b7280; | ||||
|             line-height: 1.4; | ||||
|         } | ||||
| 
 | ||||
|         /* CTA styles */ | ||||
|         .cta-section { | ||||
|             margin: 35px 0; | ||||
|             padding: 25px; | ||||
|         } | ||||
| 
 | ||||
|         .cta-button { | ||||
|             display: inline-block; | ||||
|             background: linear-gradient(135deg, #1e4e9c 0%, #337cf2 100%); | ||||
|             background-color: #1e4e9c; /* Fallback */ | ||||
|             color: white !important; | ||||
|             text-decoration: none; | ||||
|             padding: 15px 35px; | ||||
|             border-radius: 25px; | ||||
|             font-weight: 600; | ||||
|             font-size: 16px; | ||||
|             box-shadow: 0 5px 15px rgba(30, 78, 156, 0.3); | ||||
|         } | ||||
| 
 | ||||
|         .cta-button:hover { | ||||
|             background-color: #337cf2; | ||||
|             text-decoration: none; | ||||
|         } | ||||
| 
 | ||||
|         /* Social section */ | ||||
|         .social-section { | ||||
|             margin: 30px 0; | ||||
|             padding: 25px; | ||||
|             background: #f8fafc; | ||||
|             border-radius: 12px; | ||||
|         } | ||||
| 
 | ||||
|         .social-section h4 { | ||||
|             color: #1a1a1a; | ||||
|             font-size: 16px; | ||||
|             font-weight: 600; | ||||
|             margin-bottom: 15px; | ||||
|         } | ||||
| 
 | ||||
|         .social-links { | ||||
|             text-align: center; | ||||
|         } | ||||
| 
 | ||||
|         .social-link { | ||||
|             display: inline-block; | ||||
|             width: 40px; | ||||
|             height: 40px; | ||||
|             background: linear-gradient(135deg, #1e4e9c 0%, #337cf2 100%); | ||||
|             background-color: #1e4e9c; /* Fallback */ | ||||
|             color: white; | ||||
|             text-decoration: none; | ||||
|             border-radius: 50%; | ||||
|             line-height: 40px; | ||||
|             font-size: 16px; | ||||
|             margin: 0 7px; | ||||
|             text-align: center; | ||||
|         } | ||||
| 
 | ||||
|         .social-link:hover { | ||||
|             background-color: #337cf2; | ||||
|         } | ||||
| 
 | ||||
|         /* Footer styles */ | ||||
|         .footer { | ||||
|             background: #1a1a1a; | ||||
|             color: white; | ||||
|             padding: 30px; | ||||
|             text-align: center; | ||||
|         } | ||||
| 
 | ||||
|         .footer-content { | ||||
|             margin-bottom: 20px; | ||||
|         } | ||||
| 
 | ||||
|         .footer-content p { | ||||
|             margin: 5px 0; | ||||
|             font-size: 14px; | ||||
|         } | ||||
| 
 | ||||
|         .unsubscribe { | ||||
|             margin-top: 20px; | ||||
|             padding-top: 20px; | ||||
|             border-top: 1px solid rgba(255, 255, 255, 0.1); | ||||
|         } | ||||
| 
 | ||||
|         .unsubscribe a { | ||||
|             color: #9ca3af; | ||||
|             text-decoration: none; | ||||
|             font-size: 13px; | ||||
|         } | ||||
| 
 | ||||
|         .unsubscribe a:hover { | ||||
|             color: #00d4ff; | ||||
|             text-decoration: underline; | ||||
|         } | ||||
| 
 | ||||
|         /* Mobile responsive */ | ||||
|         @media only screen and (max-width: 600px) { | ||||
|             .email-wrapper { | ||||
|                 width: 100% !important; | ||||
|             } | ||||
|              | ||||
|             .header { | ||||
|                 padding: 40px 20px !important; | ||||
|             } | ||||
|              | ||||
|             .header h1 { | ||||
|                 font-size: 24px !important; | ||||
|             } | ||||
|              | ||||
|             .content { | ||||
|                 padding: 30px 20px !important; | ||||
|             } | ||||
|              | ||||
|             .features { | ||||
|                 padding: 25px 20px !important; | ||||
|             } | ||||
|              | ||||
|             .feature-item { | ||||
|                 margin-bottom: 10px !important; | ||||
|             } | ||||
|              | ||||
|             .social-link { | ||||
|                 margin: 0 5px !important; | ||||
|             } | ||||
|           padding: 16px !important; | ||||
|         } | ||||
|       } | ||||
|     </style> | ||||
| </head> | ||||
| <body> | ||||
|     <table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="background-color: #f8fafc;"> | ||||
|   </head> | ||||
|   <body class="bg"> | ||||
|     <center role="article" aria-roledescription="email"> | ||||
|       <table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0"> | ||||
|         <tr> | ||||
|             <td align="center"> | ||||
|                 <div class="email-wrapper"> | ||||
|                     <!-- Header --> | ||||
|                     <div class="header"> | ||||
|                         <div class="welcome-icon">🎉</div> | ||||
|                         <div class="logo">Ride<span class="logo-accent">Aware</span></div> | ||||
|                         <h1>Welcome Aboard!</h1> | ||||
|                         <p class="subtitle">You're now part of the RideAware community</p> | ||||
|                     </div> | ||||
|           <td align="center"> | ||||
|             <table role="presentation" class="container" width="600" cellspacing="0" cellpadding="0" border="0"> | ||||
|               <!-- Header --> | ||||
|               <tr> | ||||
|                 <td class="header"> | ||||
|                   <!-- Optional image logo: replace src if you prefer image instead of text --> | ||||
|                   <!-- | ||||
|                   <img src="https://your-cdn/rideaware-logo.png" alt="RideAware" width="140" height="28" /> | ||||
|                   --> | ||||
|                   <div class="logo-text">Ride<span class="logo-accent">Aware</span></div> | ||||
|                   <div style="font-size: 36px; line-height: 1; margin-bottom: 10px;" aria-hidden="true">🎉</div> | ||||
|                   <div class="header-title">Welcome Aboard!</div> | ||||
|                   <div class="subtitle">You're now part of the RideAware community</div> | ||||
|                 </td> | ||||
|               </tr> | ||||
| 
 | ||||
|                     <!-- Content --> | ||||
|                     <div class="content"> | ||||
|                         <p class="main-message">Thanks for subscribing to RideAware newsletter!</p> | ||||
|                          | ||||
|                         <p class="description"> | ||||
|                             We're absolutely thrilled to have you join our community of passionate cyclists. Get ready for exclusive insights, training tips, feature updates, and much more delivered straight to your inbox. | ||||
|                         </p> | ||||
|               <!-- Body --> | ||||
|               <tr> | ||||
|                 <td class="content"> | ||||
|                   <p class="main-message">Thanks for subscribing to the RideAware newsletter!</p> | ||||
|                   <p class="description"> | ||||
|                     We’re thrilled to have you with us. Expect training tips, performance insights, | ||||
|                     product news, and community highlights—delivered straight to your inbox. | ||||
|                   </p> | ||||
|                 </td> | ||||
|               </tr> | ||||
| 
 | ||||
|                         <!-- Features --> | ||||
|                         <div class="features"> | ||||
|                             <h3>What to expect from us:</h3> | ||||
|                             <div class="feature-grid"> | ||||
|                                 <div class="feature-item"> | ||||
|                                     <span class="feature-icon">🚴♂️</span> | ||||
|                                     <div class="feature-title">Training Tips</div> | ||||
|                                     <div class="feature-desc">Expert advice to improve your performance</div> | ||||
|                                 </div> | ||||
|                                 <div class="feature-item"> | ||||
|                                     <span class="feature-icon">📊</span> | ||||
|                                     <div class="feature-title">Performance Insights</div> | ||||
|                                     <div class="feature-desc">Data-driven analysis for better rides</div> | ||||
|                                 </div> | ||||
|                                 <div class="feature-item"> | ||||
|                                     <span class="feature-icon">🆕</span> | ||||
|                                     <div class="feature-title">Feature Updates</div> | ||||
|                                     <div class="feature-desc">Be first to know about new releases</div> | ||||
|                                 </div> | ||||
|                                 <div class="feature-item"> | ||||
|                                     <span class="feature-icon">👥</span> | ||||
|                                     <div class="feature-title">Community Stories</div> | ||||
|                                     <div class="feature-desc">Inspiring journeys from fellow cyclists</div> | ||||
|                                 </div> | ||||
|                             </div> | ||||
|                         </div> | ||||
|               <!-- Features --> | ||||
|               <tr> | ||||
|                 <td class="features-wrap"> | ||||
|                   <table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0" class="features"> | ||||
|                     <tr> | ||||
|                       <td align="center" style="padding-bottom: 10px;"> | ||||
|                         <div class="features-title">What to expect from us</div> | ||||
|                       </td> | ||||
|                     </tr> | ||||
|                     <tr> | ||||
|                       <td> | ||||
|                         <table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0"> | ||||
|                           <tr> | ||||
|                             <td class="feature-item"> | ||||
|                               <div class="feature-title">Training Tips</div> | ||||
|                               <div class="feature-desc">Actionable advice to improve your performance.</div> | ||||
|                             </td> | ||||
|                           </tr> | ||||
|                           <tr> | ||||
|                             <td class="feature-item"> | ||||
|                               <div class="feature-title">Performance Insights</div> | ||||
|                               <div class="feature-desc">Data-driven analysis for smarter rides.</div> | ||||
|                             </td> | ||||
|                           </tr> | ||||
|                           <tr> | ||||
|                             <td class="feature-item"> | ||||
|                               <div class="feature-title">Feature Updates</div> | ||||
|                               <div class="feature-desc">Be first to know about new releases.</div> | ||||
|                             </td> | ||||
|                           </tr> | ||||
|                           <tr> | ||||
|                             <td class="feature-item" style="margin-bottom: 0;"> | ||||
|                               <div class="feature-title">Community Stories</div> | ||||
|                               <div class="feature-desc">Inspiring journeys from fellow cyclists.</div> | ||||
|                             </td> | ||||
|                           </tr> | ||||
|                         </table> | ||||
|                       </td> | ||||
|                     </tr> | ||||
|                   </table> | ||||
|                 </td> | ||||
|               </tr> | ||||
| 
 | ||||
|                         <!-- CTA --> | ||||
|                         <div class="cta-section"> | ||||
|                             <p style="margin-bottom: 20px;">Ready to start your journey with RideAware?</p> | ||||
|                             <a href="https://rideaware.com" target="_blank" class="cta-button"> | ||||
|                                 Explore RideAware → | ||||
|                             </a> | ||||
|                         </div> | ||||
|               <!-- CTA --> | ||||
|               <tr> | ||||
|                 <td class="cta" align="center"> | ||||
|                   <p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; color:#1a1a1a; font-size:15px; margin: 0 0 12px 0;"> | ||||
|                     Ready to start your journey with RideAware? | ||||
|                   </p> | ||||
|                   <a href="https://rideaware.org" target="_blank" class="cta-btn">Explore RideAware →</a> | ||||
|                 </td> | ||||
|               </tr> | ||||
| 
 | ||||
|                         <!-- Social section --> | ||||
|                         <div class="social-section"> | ||||
|                             <h4>Stay Connected</h4> | ||||
|                             <div class="social-links"> | ||||
|                                 <a href="#" class="social-link" title="Follow us on Twitter">🐦</a> | ||||
|                                 <a href="#" class="social-link" title="Like us on Facebook">📘</a> | ||||
|                                 <a href="#" class="social-link" title="Follow us on Instagram">📷</a> | ||||
|                             </div> | ||||
|                         </div> | ||||
|               <!-- Social --> | ||||
|               <tr> | ||||
|                 <td> | ||||
|                   <div class="social"> | ||||
|                     <div class="social-title">Stay Connected</div> | ||||
|                     <a href="https://twitter.com" class="social-link" title="Twitter" aria-label="Twitter">T</a> | ||||
|                     <a href="https://facebook.com" class="social-link" title="Facebook" aria-label="Facebook">f</a> | ||||
|                     <a href="https://instagram.com" class="social-link" title="Instagram" aria-label="Instagram">IG</a> | ||||
|                   </div> | ||||
|                 </td> | ||||
|               </tr> | ||||
| 
 | ||||
|                         <p style="color: #6b7280; font-size: 14px; margin-top: 30px;"> | ||||
|                             We're excited to share our journey with you and help you achieve your cycling goals. Welcome to the RideAware family! 🚴♀️ | ||||
|                         </p> | ||||
|                     </div> | ||||
| 
 | ||||
|                     <!-- Footer --> | ||||
|                     <div class="footer"> | ||||
|                         <div class="footer-content"> | ||||
|                             <p><strong>RideAware Team</strong></p> | ||||
|                             <p>Empowering cyclists, one ride at a time</p> | ||||
|                         </div> | ||||
|                          | ||||
|                         <div class="unsubscribe"> | ||||
|                             <p> | ||||
|                                 <a href="{{ unsubscribe_link }}">Unsubscribe</a> |  | ||||
|                                 <a href="mailto:support@rideaware.com">Contact Support</a> | ||||
|                             </p> | ||||
|                             <p style="font-size: 12px; color: #6b7280; margin-top: 10px;"> | ||||
|                                 © 2025 RideAware. All rights reserved. | ||||
|                             </p> | ||||
|                             <p style="font-size: 11px; color: #9ca3af; margin-top: 8px;"> | ||||
|                                 This email was sent to you because you subscribed to RideAware updates. | ||||
|                             </p> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </td> | ||||
|               <!-- Footer --> | ||||
|               <tr> | ||||
|                 <td class="footer"> | ||||
|                   <p><strong>RideAware Team</strong></p> | ||||
|                   <p>Empowering cyclists, one ride at a time</p> | ||||
|                   <div class="unsubscribe"> | ||||
|                     <p style="margin: 0;"> | ||||
|                       <a href="{{ unsubscribe_link }}">Unsubscribe</a> | ||||
|                        |  | ||||
|                       <a href="mailto:support@rideaware.com">Contact Support</a> | ||||
|                     </p> | ||||
|                     <p style="font-size: 12px; color: #9ca3af;"> | ||||
|                       © 2025 RideAware. All rights reserved. | ||||
|                     </p> | ||||
|                     <p style="font-size: 11px; color: #9ca3af;"> | ||||
|                       You received this email because you subscribed to RideAware updates. | ||||
|                     </p> | ||||
|                   </div> | ||||
|                 </td> | ||||
|               </tr> | ||||
|             </table> | ||||
|           </td> | ||||
|         </tr> | ||||
|     </table> | ||||
| </body> | ||||
|       </table> | ||||
|     </center> | ||||
|   </body> | ||||
| </html> | ||||
|  | @ -1,4 +1,3 @@ | |||
| <!-- templates/index.html --> | ||||
| {% extends "base.html" %} | ||||
| 
 | ||||
| {% block title %}RideAware - Smart Cycling Training Platform{% endblock %} | ||||
|  | @ -10,8 +9,8 @@ | |||
|       <div class="hero-content"> | ||||
|         <h1>Elevate Your Cycling Journey</h1> | ||||
|         <p class="subtitle"> | ||||
|           The ultimate smart training platform for cyclists who demand excellence | ||||
|           in every ride. | ||||
|           The ultimate smart training platform for cyclists who demand | ||||
|           excellence in every ride. | ||||
|         </p> | ||||
| 
 | ||||
|         <div class="cta-section"> | ||||
|  | @ -35,7 +34,18 @@ | |||
|         <div class="phone-mockup"> | ||||
|           <div class="screen"> | ||||
|             <div class="app-interface"> | ||||
|               <div class="app-logo">RideAware</div> | ||||
|               <div class="app-brand"> | ||||
|                 <img | ||||
|                   src="{{ url_for('static', filename='assets/32x32.png') }}" | ||||
|                   alt="RideAware icon" | ||||
|                   class="app-brand-icon" | ||||
|                   width="32" | ||||
|                   height="32" | ||||
|                   decoding="async" | ||||
|                 /> | ||||
|                 <div class="app-logo">RideAware</div> | ||||
|               </div> | ||||
| 
 | ||||
|               <div class="stats-grid"> | ||||
|                 <div class="stat-card"> | ||||
|                   <div class="stat-number">24.5</div> | ||||
|  | @ -62,143 +72,145 @@ | |||
|   </section> | ||||
| 
 | ||||
|   <!-- Features Section --> | ||||
|   <section class="features" id="features"> | ||||
|     <div class="section-header"> | ||||
|       <h2>Powerful Features for Every Cyclist</h2> | ||||
|       <p> | ||||
|         From beginners to professionals, RideAware provides comprehensive tools | ||||
|         to optimize your training and performance. | ||||
|       </p> | ||||
|     </div> | ||||
|   {% if is_home %} | ||||
|     <section class="features" id="features"> | ||||
|       <div class="section-header"> | ||||
|         <h2>Powerful Features for Every Cyclist</h2> | ||||
|         <p> | ||||
|           From beginners to professionals, RideAware provides comprehensive | ||||
|           tools to optimize your training and performance. | ||||
|         </p> | ||||
|       </div> | ||||
| 
 | ||||
|     <div class="features-container"> | ||||
|       <div class="features-grid"> | ||||
|         <div class="feature-card"> | ||||
|           <div class="feature-icon"> | ||||
|             <i class="fas fa-calendar-alt"></i> | ||||
|       <div class="features-container"> | ||||
|         <div class="features-grid"> | ||||
|           <div class="feature-card"> | ||||
|             <div class="feature-icon"> | ||||
|               <i class="fas fa-calendar-alt"></i> | ||||
|             </div> | ||||
|             <h3>Smart Training Plans</h3> | ||||
|             <ul class="feature-list"> | ||||
|               <li> | ||||
|                 <strong>AI-Powered Planning:</strong> Customized training plans | ||||
|                 based on your goals and fitness level | ||||
|               </li> | ||||
|               <li> | ||||
|                 <strong>Adaptive Scheduling:</strong> Smart workout scheduling | ||||
|                 with automated reminders | ||||
|               </li> | ||||
|               <li> | ||||
|                 <strong>Goal Tracking:</strong> Set and monitor your cycling | ||||
|                 objectives in real-time | ||||
|               </li> | ||||
|             </ul> | ||||
|           </div> | ||||
|           <h3>Smart Training Plans</h3> | ||||
|           <ul class="feature-list"> | ||||
|             <li> | ||||
|               <strong>AI-Powered Planning:</strong> Customized training plans | ||||
|               based on your goals and fitness level | ||||
|             </li> | ||||
|             <li> | ||||
|               <strong>Adaptive Scheduling:</strong> Smart workout scheduling | ||||
|               with automated reminders | ||||
|             </li> | ||||
|             <li> | ||||
|               <strong>Goal Tracking:</strong> Set and monitor your cycling | ||||
|               objectives in real-time | ||||
|             </li> | ||||
|           </ul> | ||||
|         </div> | ||||
| 
 | ||||
|         <div class="feature-card"> | ||||
|           <div class="feature-icon"> | ||||
|             <i class="fas fa-chart-line"></i> | ||||
|           <div class="feature-card"> | ||||
|             <div class="feature-icon"> | ||||
|               <i class="fas fa-chart-line"></i> | ||||
|             </div> | ||||
|             <h3>Advanced Analytics</h3> | ||||
|             <ul class="feature-list"> | ||||
|               <li> | ||||
|                 <strong>Detailed Logging:</strong> Track exercises, sets, reps, | ||||
|                 and performance metrics | ||||
|               </li> | ||||
|               <li> | ||||
|                 <strong>Data Visualization:</strong> Interactive charts, graphs, | ||||
|                 and progress statistics | ||||
|               </li> | ||||
|               <li> | ||||
|                 <strong>Progress Insights:</strong> Monitor your improvement | ||||
|                 over time with AI analysis | ||||
|               </li> | ||||
|             </ul> | ||||
|           </div> | ||||
|           <h3>Advanced Analytics</h3> | ||||
|           <ul class="feature-list"> | ||||
|             <li> | ||||
|               <strong>Detailed Logging:</strong> Track exercises, sets, reps, | ||||
|               and performance metrics | ||||
|             </li> | ||||
|             <li> | ||||
|               <strong>Data Visualization:</strong> Interactive charts, graphs, | ||||
|               and progress statistics | ||||
|             </li> | ||||
|             <li> | ||||
|               <strong>Progress Insights:</strong> Monitor your improvement over | ||||
|               time with AI analysis | ||||
|             </li> | ||||
|           </ul> | ||||
|         </div> | ||||
| 
 | ||||
|         <div class="feature-card"> | ||||
|           <div class="feature-icon"> | ||||
|             <i class="fas fa-bicycle"></i> | ||||
|           <div class="feature-card"> | ||||
|             <div class="feature-icon"> | ||||
|               <i class="fas fa-bicycle"></i> | ||||
|             </div> | ||||
|             <h3>Virtual Training</h3> | ||||
|             <ul class="feature-list"> | ||||
|               <li> | ||||
|                 <strong>Expert Coaching:</strong> Professional guidance to | ||||
|                 achieve your cycling goals | ||||
|               </li> | ||||
|               <li> | ||||
|                 <strong>Immersive Rides:</strong> Virtual training experiences | ||||
|                 to boost performance | ||||
|               </li> | ||||
|               <li> | ||||
|                 <strong>Structured Workouts:</strong> Designed programs for | ||||
|                 fitness and performance gains | ||||
|               </li> | ||||
|             </ul> | ||||
|           </div> | ||||
|           <h3>Virtual Training</h3> | ||||
|           <ul class="feature-list"> | ||||
|             <li> | ||||
|               <strong>Expert Coaching:</strong> Professional guidance to achieve | ||||
|               your cycling goals | ||||
|             </li> | ||||
|             <li> | ||||
|               <strong>Immersive Rides:</strong> Virtual training experiences to | ||||
|               boost performance | ||||
|             </li> | ||||
|             <li> | ||||
|               <strong>Structured Workouts:</strong> Designed programs for | ||||
|               fitness and performance gains | ||||
|             </li> | ||||
|           </ul> | ||||
|         </div> | ||||
| 
 | ||||
|         <div class="feature-card"> | ||||
|           <div class="feature-icon"> | ||||
|             <i class="fas fa-heart"></i> | ||||
|           <div class="feature-card"> | ||||
|             <div class="feature-icon"> | ||||
|               <i class="fas fa-heart"></i> | ||||
|             </div> | ||||
|             <h3>Health & Recovery</h3> | ||||
|             <ul class="feature-list"> | ||||
|               <li> | ||||
|                 <strong>Nutrition Tracking:</strong> Plan and monitor your | ||||
|                 dietary intake for optimal performance | ||||
|               </li> | ||||
|               <li> | ||||
|                 <strong>Recovery Optimization:</strong> Tools and resources for | ||||
|                 effective rest and recovery | ||||
|               </li> | ||||
|               <li> | ||||
|                 <strong>Injury Prevention:</strong> Proactive measures to | ||||
|                 prevent and manage injuries | ||||
|               </li> | ||||
|             </ul> | ||||
|           </div> | ||||
|           <h3>Health & Recovery</h3> | ||||
|           <ul class="feature-list"> | ||||
|             <li> | ||||
|               <strong>Nutrition Tracking:</strong> Plan and monitor your dietary | ||||
|               intake for optimal performance | ||||
|             </li> | ||||
|             <li> | ||||
|               <strong>Recovery Optimization:</strong> Tools and resources for | ||||
|               effective rest and recovery | ||||
|             </li> | ||||
|             <li> | ||||
|               <strong>Injury Prevention:</strong> Proactive measures to prevent | ||||
|               and manage injuries | ||||
|             </li> | ||||
|           </ul> | ||||
|         </div> | ||||
| 
 | ||||
|         <div class="feature-card"> | ||||
|           <div class="feature-icon"> | ||||
|             <i class="fas fa-users"></i> | ||||
|           <div class="feature-card"> | ||||
|             <div class="feature-icon"> | ||||
|               <i class="fas fa-users"></i> | ||||
|             </div> | ||||
|             <h3>Community & Social</h3> | ||||
|             <ul class="feature-list"> | ||||
|               <li> | ||||
|                 <strong>Social Sharing:</strong> Share achievements and progress | ||||
|                 on social platforms | ||||
|               </li> | ||||
|               <li> | ||||
|                 <strong>Active Community:</strong> Connect with fellow cyclists | ||||
|                 and share experiences | ||||
|               </li> | ||||
|               <li> | ||||
|                 <strong>Competitive Leaderboards:</strong> Challenge yourself | ||||
|                 against the community | ||||
|               </li> | ||||
|             </ul> | ||||
|           </div> | ||||
|           <h3>Community & Social</h3> | ||||
|           <ul class="feature-list"> | ||||
|             <li> | ||||
|               <strong>Social Sharing:</strong> Share achievements and progress | ||||
|               on social platforms | ||||
|             </li> | ||||
|             <li> | ||||
|               <strong>Active Community:</strong> Connect with fellow cyclists | ||||
|               and share experiences | ||||
|             </li> | ||||
|             <li> | ||||
|               <strong>Competitive Leaderboards:</strong> Challenge yourself | ||||
|               against the community | ||||
|             </li> | ||||
|           </ul> | ||||
|         </div> | ||||
| 
 | ||||
|         <div class="feature-card"> | ||||
|           <div class="feature-icon"> | ||||
|             <i class="fas fa-sync-alt"></i> | ||||
|           <div class="feature-card"> | ||||
|             <div class="feature-icon"> | ||||
|               <i class="fas fa-sync-alt"></i> | ||||
|             </div> | ||||
|             <h3>Smart Integration</h3> | ||||
|             <ul class="feature-list"> | ||||
|               <li> | ||||
|                 <strong>Wearable Sync:</strong> Connect with fitness trackers | ||||
|                 and smart devices | ||||
|               </li> | ||||
|               <li> | ||||
|                 <strong>Music Integration:</strong> Seamlessly sync with your | ||||
|                 favorite music services | ||||
|               </li> | ||||
|               <li> | ||||
|                 <strong>Data Portability:</strong> Easy import/export to other | ||||
|                 cycling platforms | ||||
|               </li> | ||||
|             </ul> | ||||
|           </div> | ||||
|           <h3>Smart Integration</h3> | ||||
|           <ul class="feature-list"> | ||||
|             <li> | ||||
|               <strong>Wearable Sync:</strong> Connect with fitness trackers and | ||||
|               smart devices | ||||
|             </li> | ||||
|             <li> | ||||
|               <strong>Music Integration:</strong> Seamlessly sync with your | ||||
|               favorite music services | ||||
|             </li> | ||||
|             <li> | ||||
|               <strong>Data Portability:</strong> Easy import/export to other | ||||
|               cycling platforms | ||||
|             </li> | ||||
|           </ul> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </section> | ||||
|     </section> | ||||
|   {% endif %} | ||||
| {% endblock %} | ||||
|  | @ -7,36 +7,41 @@ | |||
| {% block content %} | ||||
|   <div class="article-wrap"> | ||||
|     <aside class="article-aside"> | ||||
|       <a href="/newsletters" class="back-link"> | ||||
|       <a href="{{ url_for('newsletters') }}" class="back-link"> | ||||
|         <i class="fas fa-arrow-left"></i> | ||||
|         Back to Newsletters | ||||
|       </a> | ||||
| 
 | ||||
|       <div class="article-meta"> | ||||
|         <h2 class="article-title">{{ newsletter.subject if newsletter else 'Newsletter Title' }}</h2> | ||||
|         <h2 class="article-title"> | ||||
|           {{ newsletter.subject if newsletter else 'Newsletter Title' }} | ||||
|         </h2> | ||||
| 
 | ||||
|         <div class="meta-row"> | ||||
|           <i class="fas fa-calendar-alt"></i> | ||||
|           <span>{{ newsletter.sent_at if newsletter else 'Published Date' }}</span> | ||||
|         </div> | ||||
| 
 | ||||
|         {% if newsletter and newsletter.get('reading_time') %} | ||||
|         <div class="meta-row"> | ||||
|           <i class="fas fa-clock"></i> | ||||
|           <span>{{ newsletter.reading_time }} min read</span> | ||||
|         </div> | ||||
|           <div class="meta-row"> | ||||
|             <i class="fas fa-clock"></i> | ||||
|             <span>{{ newsletter.reading_time }} min read</span> | ||||
|           </div> | ||||
|         {% endif %} | ||||
| 
 | ||||
|         {% if newsletter and newsletter.get('author') %} | ||||
|         <div class="meta-row"> | ||||
|           <i class="fas fa-user"></i> | ||||
|           <span>{{ newsletter.author }}</span> | ||||
|         </div> | ||||
|           <div class="meta-row"> | ||||
|             <i class="fas fa-user"></i> | ||||
|             <span>{{ newsletter.author }}</span> | ||||
|           </div> | ||||
|         {% endif %} | ||||
| 
 | ||||
|         {% if newsletter and newsletter.get('tags') %} | ||||
|         <div class="article-tags"> | ||||
|           {% for tag in newsletter.tags %} | ||||
|           <span class="tag">{{ tag }}</span> | ||||
|           {% endfor %} | ||||
|         </div> | ||||
|           <div class="article-tags"> | ||||
|             {% for tag in newsletter.tags %} | ||||
|               <span class="tag">{{ tag }}</span> | ||||
|             {% endfor %} | ||||
|           </div> | ||||
|         {% endif %} | ||||
|       </div> | ||||
| 
 | ||||
|  | @ -48,7 +53,9 @@ | |||
| 
 | ||||
|     <main class="article-main"> | ||||
|       <header class="article-hero"> | ||||
|         <div class="newsletter-icon"><i class="fas fa-envelope-open-text"></i></div> | ||||
|         <div class="newsletter-icon"> | ||||
|           <i class="fas fa-envelope-open-text"></i> | ||||
|         </div> | ||||
|         <h1>{{ newsletter.subject if newsletter else 'Newsletter Title' }}</h1> | ||||
|       </header> | ||||
| 
 | ||||
|  | @ -62,7 +69,7 @@ | |||
|       </article> | ||||
| 
 | ||||
|       <div class="newsletter-actions"> | ||||
|         <a href="/newsletters" class="action-btn primary"> | ||||
|         <a href="{{ url_for('newsletters') }}" class="action-btn primary"> | ||||
|           <i class="fas fa-list"></i> | ||||
|           View All Newsletters | ||||
|         </a> | ||||
|  | @ -80,35 +87,41 @@ | |||
| {% endblock %} | ||||
| 
 | ||||
| {% block extra_scripts %} | ||||
| <script> | ||||
|   function shareNewsletter() { | ||||
|     if (navigator.share) { | ||||
|       navigator.share({ title: document.title, url: location.href }).catch(() => {}); | ||||
|     } else { | ||||
|       navigator.clipboard.writeText(location.href); | ||||
|       alert('Link copied to clipboard!'); | ||||
|   <script> | ||||
|     function shareNewsletter() { | ||||
|       if (navigator.share) { | ||||
|         navigator | ||||
|           .share({ title: document.title, url: location.href }) | ||||
|           .catch(() => {}); | ||||
|       } else { | ||||
|         navigator.clipboard.writeText(location.href); | ||||
|         alert('Link copied to clipboard!'); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // Build TOC from h2/h3 inside the article | ||||
|   (function buildTOC() { | ||||
|     const article = document.getElementById('article'); | ||||
|     if (!article) return; | ||||
|     const headings = article.querySelectorAll('h2, h3'); | ||||
|     const list = document.getElementById('toc-list'); | ||||
|     if (!headings.length || !list) return; | ||||
|     // Build TOC from h2/h3 inside the article | ||||
|     (function buildTOC() { | ||||
|       const article = document.getElementById('article'); | ||||
|       if (!article) return; | ||||
| 
 | ||||
|     headings.forEach((h, idx) => { | ||||
|       const id = h.id || `h-${idx}`; | ||||
|       h.id = id; | ||||
|       const li = document.createElement('li'); | ||||
|       li.className = h.tagName === 'H2' ? 'toc-h2' : 'toc-h3'; | ||||
|       const a = document.createElement('a'); | ||||
|       a.href = `#${id}`; | ||||
|       a.textContent = h.textContent; | ||||
|       li.appendChild(a); | ||||
|       list.appendChild(li); | ||||
|     }); | ||||
|   })(); | ||||
| </script> | ||||
|       const headings = article.querySelectorAll('h2, h3'); | ||||
|       const list = document.getElementById('toc-list'); | ||||
|       if (!headings.length || !list) return; | ||||
| 
 | ||||
|       headings.forEach((h, idx) => { | ||||
|         const id = h.id || `h-${idx}`; | ||||
|         h.id = id; | ||||
| 
 | ||||
|         const li = document.createElement('li'); | ||||
|         li.className = h.tagName === 'H2' ? 'toc-h2' : 'toc-h3'; | ||||
| 
 | ||||
|         const a = document.createElement('a'); | ||||
|         a.href = `#${id}`; | ||||
|         a.textContent = h.textContent; | ||||
| 
 | ||||
|         li.appendChild(a); | ||||
|         list.appendChild(li); | ||||
|       }); | ||||
|     })(); | ||||
|   </script> | ||||
| {% endblock %} | ||||
|  | @ -29,7 +29,9 @@ | |||
|               </div> | ||||
|               <div class="newsletter-info"> | ||||
|                 <h2> | ||||
|                   <a href="/newsletter/{{ nl['id'] }}">{{ nl['subject'] }}</a> | ||||
|                   <a href="{{ url_for('newsletter_detail', newsletter_id=nl['id']) }}"> | ||||
|                     {{ nl['subject'] }} | ||||
|                   </a> | ||||
|                 </h2> | ||||
|               </div> | ||||
|             </div> | ||||
|  | @ -43,12 +45,15 @@ | |||
|               {% if nl.get('preview') %} | ||||
|                 {{ nl['preview'][:150] }}... | ||||
|               {% else %} | ||||
|                 Get the latest updates on cycling training, performance tips, and | ||||
|                 RideAware features in this newsletter edition. | ||||
|                 Get the latest updates on cycling training, performance tips, | ||||
|                 and RideAware features in this newsletter edition. | ||||
|               {% endif %} | ||||
|             </div> | ||||
| 
 | ||||
|             <a href="/newsletter/{{ nl['id'] }}" class="read-more-btn"> | ||||
|             <a | ||||
|               href="{{ url_for('newsletter_detail', newsletter_id=nl['id']) }}" | ||||
|               class="read-more-btn" | ||||
|             > | ||||
|               Read Full Newsletter | ||||
|               <i class="fas fa-arrow-right"></i> | ||||
|             </a> | ||||
|  | @ -65,7 +70,7 @@ | |||
|           We're working on some amazing content for you. Subscribe to be the | ||||
|           first to know when we publish our newsletters! | ||||
|         </p> | ||||
|         <a href="/" class="subscribe-prompt"> | ||||
|         <a href="{{ url_for('index') }}" class="subscribe-prompt"> | ||||
|           <i class="fas fa-bell"></i> | ||||
|           Subscribe for Updates | ||||
|         </a> | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Cipher Vance
						Cipher Vance