Compare commits

..

No commits in common. "79c29e6c8e6c14124fd9d1b2585c75467a9c8649" and "e3c005aa92ecf41aab5e55431972af36e652ec70" have entirely different histories.

10 changed files with 1483 additions and 1161 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 11 KiB

View file

@ -0,0 +1,825 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--primary: #1e4e9c;
--secondary: #337cf2;
--accent: #00d4ff;
--text-dark: #1a1a1a;
--text-light: #6b7280;
--bg-light: #f8fafc;
--white: #ffffff;
--gradient: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 50%, var(--accent) 100%);
--shadow: 0 10px 30px rgba(30, 78, 156, 0.1);
--shadow-hover: 0 20px 40px rgba(30, 78, 156, 0.15);
--border-radius: 20px;
}
html {
scroll-behavior: smooth;
}
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
line-height: 1.7;
color: var(--text-dark);
background: var(--bg-light);
min-height: 100vh;
display: flex;
flex-direction: column;
}
/* Navigation */
.navbar {
position: sticky;
top: 0;
background: rgba(255, 255, 255, 0.98);
backdrop-filter: blur(20px);
z-index: 1000;
padding: 1rem 0;
box-shadow: 0 2px 20px rgba(0, 0, 0, 0.05);
}
.nav-container {
max-width: 1200px;
margin: 0 auto;
padding: 0 2rem;
display: flex;
justify-content: space-between;
align-items: center;
}
.logo {
font-size: 1.5rem;
font-weight: 700;
color: var(--text-dark);
text-decoration: none;
transition: transform 0.3s ease;
}
.logo:hover {
transform: scale(1.05);
}
.logo-accent {
color: var(--primary);
}
.nav-links {
display: flex;
gap: 2rem;
list-style: none;
align-items: center;
}
.nav-links a {
text-decoration: none;
color: var(--text-dark);
font-weight: 500;
transition: all 0.3s ease;
position: relative;
padding: 0.5rem 1rem;
border-radius: 25px;
}
.nav-links a.active {
background: var(--gradient);
color: white;
transform: translateY(-2px);
}
.nav-links a:not(.active)::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 0;
height: 2px;
background: var(--gradient);
transition: width 0.3s ease;
}
.nav-links a:not(.active):hover::after {
width: 80%;
}
/* Header Section */
.page-header {
background: var(--gradient);
padding: 4rem 0 2rem;
text-align: center;
position: relative;
overflow: hidden;
}
.page-header::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="dots" width="20" height="20" patternUnits="userSpaceOnUse"><circle cx="10" cy="10" r="1" fill="rgba(255,255,255,0.1)"/></pattern></defs><rect width="100%" height="100%" fill="url(%23dots)"/></svg>');
opacity: 0.3;
}
.page-header-content {
max-width: 1200px;
margin: 0 auto;
padding: 0 2rem;
position: relative;
z-index: 1;
}
.page-header h1 {
font-size: clamp(2.5rem, 5vw, 3.5rem);
font-weight: 800;
color: white;
margin-bottom: 1rem;
text-shadow: 0 2px 20px rgba(0, 0, 0, 0.1);
}
.page-header p {
font-size: 1.25rem;
color: rgba(255, 255, 255, 0.9);
max-width: 600px;
margin: 0 auto;
font-weight: 300;
}
.header-icon {
display: inline-block;
font-size: 3rem;
margin-bottom: 1rem;
color: rgba(255, 255, 255, 0.8);
}
/* Main Content (List page) */
.main-content {
flex: 1;
max-width: 1200px;
margin: 0 auto;
padding: 3rem 2rem;
width: 100%;
}
/* Newsletter Grid */
.newsletters-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
gap: 2rem;
margin-top: 2rem;
}
.newsletter-card {
background: white;
border-radius: var(--border-radius);
padding: 2rem;
box-shadow: var(--shadow);
border: 1px solid rgba(30, 78, 156, 0.05);
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.newsletter-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 4px;
background: var(--gradient);
}
.newsletter-card:hover {
transform: translateY(-8px);
box-shadow: var(--shadow-hover);
}
.newsletter-header {
display: flex;
align-items: flex-start;
gap: 1rem;
margin-bottom: 1rem;
}
.newsletter-icon {
width: 50px;
height: 50px;
background: var(--gradient);
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 1.25rem;
flex-shrink: 0;
}
.newsletter-info h2 {
font-size: 1.375rem;
font-weight: 600;
color: var(--text-dark);
margin-bottom: 0.5rem;
line-height: 1.4;
}
.newsletter-info h2 a {
color: inherit;
text-decoration: none;
transition: color 0.3s ease;
}
.newsletter-info h2 a:hover {
background: var(--gradient);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.newsletter-date {
color: var(--text-light);
font-size: 0.875rem;
display: flex;
align-items: center;
gap: 0.5rem;
margin-bottom: 1rem;
}
.newsletter-excerpt {
color: var(--text-light);
margin-bottom: 1.5rem;
font-size: 0.95rem;
line-height: 1.6;
}
.read-more-btn {
display: inline-flex;
align-items: center;
gap: 0.5rem;
background: var(--gradient);
color: white;
text-decoration: none;
padding: 0.75rem 1.5rem;
border-radius: 25px;
font-weight: 500;
transition: all 0.3s ease;
font-size: 0.875rem;
}
.read-more-btn:hover {
transform: translateX(5px);
box-shadow: 0 5px 15px rgba(30, 78, 156, 0.3);
}
/* Empty State */
.empty-state {
text-align: center;
padding: 4rem 2rem;
background: white;
border-radius: var(--border-radius);
box-shadow: var(--shadow);
border: 1px solid rgba(30, 78, 156, 0.05);
}
.empty-icon {
font-size: 4rem;
color: var(--text-light);
margin-bottom: 1.5rem;
opacity: 0.5;
}
.empty-state h3 {
font-size: 1.5rem;
color: var(--text-dark);
margin-bottom: 1rem;
}
.empty-state p {
color: var(--text-light);
font-size: 1.125rem;
max-width: 400px;
margin: 0 auto 2rem;
}
.subscribe-prompt {
background: var(--gradient);
color: white;
text-decoration: none;
padding: 1rem 2rem;
border-radius: 25px;
font-weight: 600;
display: inline-flex;
align-items: center;
gap: 0.75rem;
transition: all 0.3s ease;
}
.subscribe-prompt:hover {
transform: translateY(-3px);
box-shadow: var(--shadow-hover);
}
/* Footer (list page) */
.footer {
background: var(--text-dark);
color: white;
text-align: center;
padding: 2rem 0;
margin-top: auto;
}
.footer p {
opacity: 0.8;
}
/* Mobile Styles (list page) */
@media (max-width: 768px) {
.nav-container {
padding: 0 1rem;
}
.nav-links {
gap: 1rem;
}
.nav-links a {
padding: 0.5rem 0.75rem;
font-size: 0.875rem;
}
.page-header {
padding: 3rem 0 1.5rem;
}
.main-content {
padding: 2rem 1rem;
}
.newsletters-grid {
grid-template-columns: 1fr;
gap: 1.5rem;
}
.newsletter-card {
padding: 1.5rem;
}
.newsletter-header {
flex-direction: column;
align-items: center;
text-align: center;
gap: 1rem;
}
.empty-state {
padding: 3rem 1.5rem;
}
}
/* Loading Animation (list page cards) */
@keyframes fadeInUp {
from { opacity: 0; transform: translateY(30px); }
to { opacity: 1; transform: translateY(0); }
}
.newsletter-card {
animation: fadeInUp 0.6s ease forwards;
}
.newsletter-card:nth-child(2) { animation-delay: 0.1s; }
.newsletter-card:nth-child(3) { animation-delay: 0.2s; }
.newsletter-card:nth-child(4) { animation-delay: 0.3s; }
/* ----------------------------- */
/* Detail Page Additions (unique) */
/* ----------------------------- */
/* Back Button */
.back-navigation {
max-width: 1200px;
margin: 0 auto;
padding: 2rem 2rem 0;
}
.back-link {
display: inline-flex;
align-items: center;
gap: 0.75rem;
color: var(--text-light);
text-decoration: none;
font-weight: 500;
transition: all 0.3s ease;
padding: 0.75rem 1rem;
border-radius: 25px;
background: white;
box-shadow: var(--shadow);
border: 1px solid rgba(30, 78, 156, 0.05);
}
.back-link:hover {
color: var(--primary);
transform: translateX(-5px);
box-shadow: var(--shadow-hover);
}
.back-link i {
transition: transform 0.3s ease;
}
.back-link:hover i {
transform: translateX(-3px);
}
/* Main Content (detail page override) */
.main-content {
flex: 1;
max-width: 900px;
margin: 0 auto;
padding: 2rem;
width: 100%;
}
/* Newsletter Header (detail) */
.newsletter-header {
background: white;
padding: 3rem;
border-radius: var(--border-radius);
box-shadow: var(--shadow);
margin-bottom: 2rem;
text-align: center;
position: relative;
overflow: hidden;
border: 1px solid rgba(30, 78, 156, 0.05);
}
.newsletter-header::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 4px;
background: var(--gradient);
}
.newsletter-icon {
width: 80px;
height: 80px;
background: var(--gradient);
border-radius: 20px;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 2rem;
margin: 0 auto 1.5rem;
box-shadow: 0 10px 20px rgba(30, 78, 156, 0.2);
}
.newsletter-header h1 {
font-size: clamp(1.75rem, 4vw, 2.5rem);
font-weight: 700;
color: var(--text-dark);
margin-bottom: 1rem;
line-height: 1.3;
}
.newsletter-meta {
display: flex;
justify-content: center;
align-items: center;
gap: 2rem;
color: var(--text-light);
font-size: 0.95rem;
margin-bottom: 1.5rem;
}
.meta-item {
display: flex;
align-items: center;
gap: 0.5rem;
}
.newsletter-tags {
display: flex;
gap: 0.75rem;
justify-content: center;
flex-wrap: wrap;
}
.tag {
background: rgba(30, 78, 156, 0.1);
color: var(--primary);
padding: 0.5rem 1rem;
border-radius: 20px;
font-size: 0.875rem;
font-weight: 500;
}
/* Newsletter Content (detail) */
.newsletter-content {
background: white;
padding: 3rem;
border-radius: var(--border-radius);
box-shadow: var(--shadow);
border: 1px solid rgba(30, 78, 156, 0.05);
position: relative;
}
.newsletter-content::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 4px;
background: var(--gradient);
}
/* Typography */
.newsletter-content h1,
.newsletter-content h2,
.newsletter-content h3,
.newsletter-content h4,
.newsletter-content h5,
.newsletter-content h6 {
color: var(--text-dark);
font-weight: 600;
margin-top: 2rem;
margin-bottom: 1rem;
line-height: 1.3;
}
.newsletter-content h1 {
font-size: 2.25rem;
font-weight: 700;
background: var(--gradient);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.newsletter-content h2 {
font-size: 1.875rem;
border-bottom: 2px solid rgba(30, 78, 156, 0.1);
padding-bottom: 0.5rem;
}
.newsletter-content h3 {
font-size: 1.5rem;
color: var(--primary);
}
.newsletter-content h4 {
font-size: 1.25rem;
}
.newsletter-content p {
margin-bottom: 1.5rem;
font-size: 1.0625rem;
line-height: 1.8;
color: var(--text-dark);
}
.newsletter-content ul,
.newsletter-content ol {
margin-bottom: 1.5rem;
padding-left: 2rem;
}
.newsletter-content li {
margin-bottom: 0.75rem;
color: var(--text-dark);
line-height: 1.7;
}
.newsletter-content blockquote {
background: rgba(30, 78, 156, 0.05);
border-left: 4px solid var(--primary);
padding: 1.5rem 2rem;
margin: 2rem 0;
border-radius: 0 15px 15px 0;
font-style: italic;
color: var(--text-light);
position: relative;
}
.newsletter-content blockquote::before {
content: '"';
font-size: 3rem;
color: var(--primary);
position: absolute;
top: 0.5rem;
left: 1rem;
opacity: 0.3;
}
.newsletter-content a {
color: var(--primary);
text-decoration: none;
font-weight: 500;
border-bottom: 1px solid transparent;
transition: all 0.3s ease;
}
.newsletter-content a:hover {
border-bottom-color: var(--primary);
color: var(--secondary);
}
.newsletter-content img {
max-width: 100%;
height: auto;
border-radius: 15px;
margin: 2rem 0;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
}
.newsletter-content pre {
background: #f8fafc;
border: 1px solid #e5e7eb;
border-radius: 10px;
padding: 1.5rem;
overflow-x: auto;
margin: 2rem 0;
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
}
.newsletter-content code {
background: rgba(30, 78, 156, 0.1);
color: var(--primary);
padding: 0.25rem 0.5rem;
border-radius: 5px;
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
font-size: 0.9em;
}
.newsletter-content table {
width: 100%;
border-collapse: collapse;
margin: 2rem 0;
border-radius: 10px;
overflow: hidden;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
}
.newsletter-content th,
.newsletter-content td {
padding: 1rem 1.5rem;
text-align: left;
border-bottom: 1px solid rgba(30, 78, 156, 0.1);
}
.newsletter-content th {
background: var(--gradient);
color: white;
font-weight: 600;
}
/* Action Buttons */
.newsletter-actions {
display: flex;
gap: 1rem;
justify-content: center;
margin: 3rem 0 2rem;
flex-wrap: wrap;
}
.action-btn {
display: inline-flex;
align-items: center;
gap: 0.75rem;
padding: 1rem 2rem;
border: none;
border-radius: 25px;
font-weight: 600;
text-decoration: none;
cursor: pointer;
transition: all 0.3s ease;
font-size: 1rem;
}
.action-btn.primary {
background: var(--gradient);
color: white;
}
.action-btn.secondary {
background: white;
color: var(--primary);
border: 2px solid var(--primary);
}
.action-btn:hover {
transform: translateY(-3px);
box-shadow: var(--shadow-hover);
}
/* Footer (detail page override) */
.footer {
background: var(--text-dark);
color: white;
text-align: center;
padding: 2rem 0;
margin-top: 2rem;
}
/* Mobile (detail page) */
@media (max-width: 768px) {
.back-navigation {
padding: 1.5rem 1rem 0;
}
.main-content {
padding: 1rem;
}
.newsletter-header {
padding: 2rem 1.5rem;
}
.newsletter-meta {
flex-direction: column;
gap: 1rem;
}
.newsletter-content {
padding: 2rem 1.5rem;
}
.newsletter-content h1 { font-size: 1.75rem; }
.newsletter-content h2 { font-size: 1.5rem; }
.newsletter-content h3 { font-size: 1.25rem; }
.newsletter-actions {
flex-direction: column;
align-items: center;
}
.action-btn {
width: 100%;
max-width: 300px;
justify-content: center;
}
.newsletter-content pre {
padding: 1rem;
font-size: 0.875rem;
}
.newsletter-content th,
.newsletter-content td {
padding: 0.75rem 1rem;
font-size: 0.875rem;
}
}
@media (max-width: 480px) {
.newsletter-header {
padding: 1.5rem 1rem;
}
.newsletter-content {
padding: 1.5rem 1rem;
}
.newsletter-icon {
width: 60px;
height: 60px;
font-size: 1.5rem;
}
}
/* Print Styles */
@media print {
.navbar,
.back-navigation,
.newsletter-actions,
.footer {
display: none;
}
.newsletter-header,
.newsletter-content {
box-shadow: none;
border: 1px solid #ddd;
}
.newsletter-content {
page-break-inside: avoid;
}
}
/* Animation (detail page elements) */
.newsletter-header,
.newsletter-content {
animation: fadeInUp 0.6s ease forwards;
}
.newsletter-content {
animation-delay: 0.2s;
}

View file

@ -1,6 +1,3 @@
/* =======================
Global Reset & Variables
======================= */
* { * {
margin: 0; margin: 0;
padding: 0; padding: 0;
@ -15,12 +12,7 @@
--text-light: #6b7280; --text-light: #6b7280;
--bg-light: #f8fafc; --bg-light: #f8fafc;
--white: #ffffff; --white: #ffffff;
--gradient: linear-gradient( --gradient: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 50%, var(--accent) 100%);
135deg,
var(--primary) 0%,
var(--secondary) 50%,
var(--accent) 100%
);
--shadow: 0 10px 30px rgba(30, 78, 156, 0.1); --shadow: 0 10px 30px rgba(30, 78, 156, 0.1);
--shadow-hover: 0 20px 40px rgba(30, 78, 156, 0.15); --shadow-hover: 0 20px 40px rgba(30, 78, 156, 0.15);
} }
@ -34,12 +26,9 @@ body {
line-height: 1.7; line-height: 1.7;
color: var(--text-dark); color: var(--text-dark);
overflow-x: hidden; overflow-x: hidden;
background: #fff;
} }
/* ======================= /* Navigation */
Navigation
======================= */
.navbar { .navbar {
position: fixed; position: fixed;
top: 0; top: 0;
@ -50,12 +39,6 @@ body {
z-index: 1000; z-index: 1000;
padding: 1rem 0; padding: 1rem 0;
transition: all 0.3s ease; transition: all 0.3s ease;
border-bottom: 1px solid rgba(2, 6, 23, 0.04);
/* Lock navbar typography (prevents subtle shifts) */
font-size: 1rem; /* 16px baseline */
line-height: 1.2;
letter-spacing: 0;
} }
.nav-container { .nav-container {
@ -68,13 +51,11 @@ body {
} }
.logo { .logo {
font-size: 1.5rem; /* consistent logo size */ font-size: 1.5rem;
font-weight: 700; font-weight: 700;
color: var(--text-dark); color: var(--text-dark);
text-decoration: none; text-decoration: none;
transition: transform 0.3s ease; transition: transform 0.3s ease;
letter-spacing: 0.2px;
font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
} }
.logo:hover { .logo:hover {
@ -82,7 +63,7 @@ body {
} }
.logo-accent { .logo-accent {
color: var(--accent); color: var(--primary);
} }
.nav-links { .nav-links {
@ -110,14 +91,11 @@ body {
transition: width 0.3s ease; transition: width 0.3s ease;
} }
.nav-links a:hover::after, .nav-links a:hover::after {
.nav-links a.active::after {
width: 100%; width: 100%;
} }
/* ======================= /* Hero Section */
Hero Section (Landing)
======================= */
.hero { .hero {
min-height: 100vh; min-height: 100vh;
background: var(--gradient); background: var(--gradient);
@ -130,7 +108,10 @@ body {
.hero::before { .hero::before {
content: ''; content: '';
position: absolute; position: absolute;
inset: 0; top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="grain" width="100" height="100" patternUnits="userSpaceOnUse"><circle cx="20" cy="20" r="1" fill="rgba(255,255,255,0.1)"/><circle cx="80" cy="40" r="1" fill="rgba(255,255,255,0.05)"/><circle cx="40" cy="80" r="1" fill="rgba(255,255,255,0.1)"/></pattern></defs><rect width="100%" height="100%" fill="url(%23grain)"/></svg>'); background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="grain" width="100" height="100" patternUnits="userSpaceOnUse"><circle cx="20" cy="20" r="1" fill="rgba(255,255,255,0.1)"/><circle cx="80" cy="40" r="1" fill="rgba(255,255,255,0.05)"/><circle cx="40" cy="80" r="1" fill="rgba(255,255,255,0.1)"/></pattern></defs><rect width="100%" height="100%" fill="url(%23grain)"/></svg>');
opacity: 0.3; opacity: 0.3;
} }
@ -150,7 +131,7 @@ body {
.hero-content h1 { .hero-content h1 {
font-size: clamp(2.5rem, 5vw, 4rem); font-size: clamp(2.5rem, 5vw, 4rem);
font-weight: 800; font-weight: 800;
color: #fff; color: white;
margin-bottom: 1.5rem; margin-bottom: 1.5rem;
line-height: 1.2; line-height: 1.2;
text-shadow: 0 2px 20px rgba(0, 0, 0, 0.1); text-shadow: 0 2px 20px rgba(0, 0, 0, 0.1);
@ -172,7 +153,7 @@ body {
} }
.cta-section h3 { .cta-section h3 {
color: #fff; color: white;
font-size: 1.5rem; font-size: 1.5rem;
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
font-weight: 600; font-weight: 600;
@ -202,7 +183,7 @@ body {
} }
.email-input:focus { .email-input:focus {
background: #fff; background: white;
box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.3); box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.3);
} }
@ -223,7 +204,7 @@ body {
box-shadow: var(--shadow-hover); box-shadow: var(--shadow-hover);
} }
/* Countdown (if used) */ /* Countdown Timer */
.countdown { .countdown {
display: grid; display: grid;
grid-template-columns: repeat(4, 1fr); grid-template-columns: repeat(4, 1fr);
@ -233,7 +214,7 @@ body {
.countdown-item { .countdown-item {
text-align: center; text-align: center;
color: #fff; color: white;
} }
.countdown-number { .countdown-number {
@ -249,7 +230,6 @@ body {
letter-spacing: 1px; letter-spacing: 1px;
} }
/* Phone mockup */
.hero-visual { .hero-visual {
position: relative; position: relative;
height: 500px; height: 500px;
@ -271,13 +251,8 @@ body {
} }
@keyframes float { @keyframes float {
0%, 0%, 100% { transform: rotate(-5deg) translateY(0px); }
100% { 50% { transform: rotate(-5deg) translateY(-20px); }
transform: rotate(-5deg) translateY(0);
}
50% {
transform: rotate(-5deg) translateY(-20px);
}
} }
.screen { .screen {
@ -293,7 +268,7 @@ body {
} }
.app-interface { .app-interface {
color: #fff; color: white;
text-align: center; text-align: center;
} }
@ -327,9 +302,7 @@ body {
opacity: 0.8; opacity: 0.8;
} }
/* ======================= /* Features Section */
Features Section
======================= */
.features { .features {
padding: 6rem 0; padding: 6rem 0;
background: var(--bg-light); background: var(--bg-light);
@ -350,8 +323,6 @@ body {
background: var(--gradient); background: var(--gradient);
-webkit-background-clip: text; -webkit-background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
background-clip: text;
color: transparent;
} }
.section-header p { .section-header p {
@ -372,7 +343,7 @@ body {
} }
.feature-card { .feature-card {
background: #fff; background: white;
padding: 2.5rem; padding: 2.5rem;
border-radius: 20px; border-radius: 20px;
box-shadow: var(--shadow); box-shadow: var(--shadow);
@ -406,7 +377,7 @@ body {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
margin-bottom: 1.5rem; margin-bottom: 1.5rem;
color: #fff; color: white;
font-size: 1.5rem; font-size: 1.5rem;
} }
@ -440,274 +411,15 @@ body {
color: var(--text-dark); color: var(--text-dark);
} }
/* ======================= /* Footer */
Newsletter Pages (List & Detail)
======================= */
/* Page header banner */
.page-header {
background: linear-gradient(
180deg,
rgba(30, 78, 156, 0.06),
rgba(0, 212, 255, 0.06)
);
padding: 8rem 0 3rem; /* account for fixed navbar */
border-bottom: 1px solid rgba(30, 78, 156, 0.08);
}
.page-header-content {
max-width: 1000px;
margin: 0 auto;
padding: 0 2rem;
text-align: center;
}
.page-header .header-icon {
width: 64px;
height: 64px;
margin: 0 auto 1rem;
border-radius: 16px;
background: var(--gradient);
color: #fff;
display: flex;
align-items: center;
justify-content: center;
box-shadow: var(--shadow);
font-size: 1.5rem;
}
.page-header h1 {
font-size: clamp(2rem, 4vw, 2.5rem);
font-weight: 700;
color: var(--text-dark);
margin-bottom: 0.5rem;
}
.page-header p {
color: var(--text-light);
font-size: 1.05rem;
}
/* Main content container */
.main-content {
max-width: 1100px;
margin: 0 auto;
padding: 2rem 2rem 4rem;
}
/* Grid of newsletter cards */
.newsletters-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
gap: 1.5rem;
}
/* Individual card */
.newsletter-card {
background: #fff;
border: 1px solid rgba(30, 78, 156, 0.08);
border-radius: 16px;
padding: 1.25rem 1.25rem 1rem;
box-shadow: var(--shadow);
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.newsletter-card:hover {
transform: translateY(-4px);
box-shadow: var(--shadow-hover);
}
.newsletter-header {
display: flex;
align-items: center;
gap: 0.75rem;
margin-bottom: 0.75rem;
}
.newsletter-icon {
width: 44px;
height: 44px;
border-radius: 12px;
background: var(--gradient);
color: #fff;
display: flex;
align-items: center;
justify-content: center;
flex: 0 0 44px;
}
.newsletter-info h2 {
font-size: 1.1rem;
margin: 0;
}
.newsletter-info a {
color: var(--text-dark);
text-decoration: none;
}
.newsletter-info a:hover {
color: var(--secondary);
}
/* Meta/date and excerpt */
.newsletter-date {
display: flex;
align-items: center;
gap: 0.5rem;
color: var(--text-light);
font-size: 0.9rem;
margin-bottom: 0.5rem;
}
.newsletter-excerpt {
color: var(--text-dark);
opacity: 0.9;
margin-bottom: 0.75rem;
}
/* Read more button */
.read-more-btn {
display: inline-flex;
align-items: center;
gap: 0.5rem;
color: #fff;
background: var(--gradient);
padding: 0.55rem 0.9rem;
border-radius: 999px;
text-decoration: none;
font-weight: 600;
}
/* Detail page nav back link */
.back-navigation {
max-width: 1100px;
margin: 6rem auto 0; /* space for fixed navbar */
padding: 0 2rem;
}
.back-link {
color: var(--secondary);
text-decoration: none;
font-weight: 600;
}
.back-link:hover {
text-decoration: underline;
}
/* Detail header, meta, tags */
.newsletter-header h1 {
margin-top: 0.5rem;
}
.newsletter-meta {
display: flex;
flex-wrap: wrap;
gap: 0.75rem 1.25rem;
margin-top: 0.5rem;
color: var(--text-light);
}
.newsletter-meta .meta-item {
display: inline-flex;
align-items: center;
gap: 0.4rem;
}
.newsletter-tags {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
margin-top: 0.75rem;
}
.newsletter-tags .tag {
font-size: 0.85rem;
padding: 0.3rem 0.6rem;
background: rgba(51, 124, 242, 0.1);
color: var(--secondary);
border: 1px solid rgba(51, 124, 242, 0.2);
border-radius: 999px;
}
/* Detail content */
.newsletter-content {
margin-top: 1.25rem;
background: #fff;
border: 1px solid rgba(30, 78, 156, 0.08);
border-radius: 16px;
padding: 1.5rem;
box-shadow: var(--shadow);
}
.newsletter-content h2,
.newsletter-content h3 {
margin-top: 1rem;
margin-bottom: 0.5rem;
}
.newsletter-content p,
.newsletter-content li {
color: var(--text-dark);
}
.newsletter-content ul {
padding-left: 1.25rem;
}
.newsletter-content blockquote {
margin: 1rem 0;
padding: 1rem 1.25rem;
background: rgba(0, 212, 255, 0.08);
border-left: 4px solid var(--accent);
border-radius: 8px;
color: var(--text-dark);
}
/* Actions */
.newsletter-actions {
display: flex;
flex-wrap: wrap;
gap: 0.75rem;
margin-top: 1rem;
}
.action-btn {
display: inline-flex;
align-items: center;
gap: 0.5rem;
border-radius: 10px;
padding: 0.6rem 1rem;
cursor: pointer;
border: none;
text-decoration: none;
font-weight: 600;
}
.action-btn.primary {
background: var(--gradient);
color: #fff;
}
.action-btn.secondary {
background: #f1f5f9;
color: var(--text-dark);
}
/* =======================
Footer
======================= */
.footer { .footer {
background: var(--text-dark); background: var(--text-dark);
color: #fff; color: white;
text-align: center; text-align: center;
padding: 2rem 0; padding: 2rem 0;
} }
/* ======================= /* Mobile Styles */
Responsive
======================= */
@media (max-width: 768px) { @media (max-width: 768px) {
.nav-container { .nav-container {
padding: 0 1rem; padding: 0 1rem;
@ -750,15 +462,6 @@ body {
.feature-card { .feature-card {
padding: 2rem; padding: 2rem;
} }
/* Newsletter pages */
.page-header {
padding: 7rem 0 2rem;
}
.main-content {
padding: 1.25rem 1rem 3rem;
}
} }
@media (max-width: 480px) { @media (max-width: 480px) {
@ -771,132 +474,3 @@ body {
padding: 0 1rem; padding: 0 1rem;
} }
} }
/* =======================
Hard Guards for Navbar
======================= */
/* Ensure navbar logo colors are always visible on white background */
.navbar .logo {
color: var(--text-dark) !important;
}
.navbar .logo .logo-accent {
color: var(--accent) !important;
}
/* Prevent content typography from leaking into the navbar */
.navbar,
.navbar * {
text-transform: none;
letter-spacing: normal;
line-height: normal;
font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif !important;
}
/* Article layout for newsletter detail */
.article-wrap {
max-width: 1200px;
margin: 6rem auto 3rem;
padding: 0 2rem;
display: grid;
grid-template-columns: 280px 1fr;
gap: 2rem;
}
.article-aside {
position: sticky;
top: 84px; /* below fixed navbar */
align-self: start;
}
.article-meta {
background: #fff;
border: 1px solid rgba(30, 78, 156, 0.08);
border-radius: 16px;
padding: 1rem;
box-shadow: var(--shadow);
margin-top: 0.75rem;
}
.article-title {
font-size: 1.1rem;
margin: 0 0 0.5rem 0;
}
.meta-row {
display: flex;
align-items: center;
gap: 0.5rem;
color: var(--text-light);
font-size: 0.95rem;
margin: 0.25rem 0;
}
.article-tags {
display: flex;
flex-wrap: wrap;
gap: 0.4rem;
margin-top: 0.5rem;
}
.article-tags .tag {
font-size: 0.8rem;
padding: 0.25rem 0.5rem;
background: rgba(51, 124, 242, 0.08);
color: var(--secondary);
border: 1px solid rgba(51, 124, 242, 0.2);
border-radius: 999px;
}
.toc {
margin-top: 1rem;
background: #fff;
border: 1px solid rgba(30, 78, 156, 0.08);
border-radius: 16px;
padding: 0.75rem 0.75rem 0.75rem 1rem;
box-shadow: var(--shadow);
}
.toc-title {
font-weight: 700;
margin-bottom: 0.5rem;
color: var(--text-dark);
}
#toc-list {
list-style: none;
padding-left: 0;
}
#toc-list li {
margin: 0.25rem 0;
}
#toc-list a {
text-decoration: none;
color: var(--text-dark);
font-size: 0.95rem;
}
#toc-list a:hover { color: var(--secondary); }
.toc-h3 { margin-left: 0.75rem; opacity: 0.9; }
.article-main .article-hero {
display: flex;
align-items: center;
gap: 0.75rem;
margin-bottom: 0.75rem;
}
.article-hero .newsletter-icon {
width: 44px;
height: 44px;
border-radius: 12px;
background: var(--gradient);
color: #fff;
display: inline-flex;
align-items: center;
justify-content: center;
}
@media (max-width: 992px) {
.article-wrap {
grid-template-columns: 1fr;
}
.article-aside {
position: static;
}
}

View file

@ -1,69 +0,0 @@
<!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>
<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') }}"
/>
<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 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">
<li><a href="#features">Features</a></li>
<li><a href="/newsletters">Newsletters</a></li>
</ul>
</div>
</nav>
{% block content %}{% endblock %}
<footer class="footer">
<p>&copy; 2025 RideAware. All rights reserved.</p>
</footer>
<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>

View file

@ -1,31 +1,39 @@
<!-- templates/index.html --> <!DOCTYPE html>
{% extends "base.html" %} <html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>RideAware - Smart Cycling Training Platform</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://cdn.statically.io" crossorigin>
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
{% block title %}RideAware - Smart Cycling Training Platform{% endblock %} </head>
<body>
<!-- Navigation -->
<nav class="navbar">
<div class="nav-container">
<a href="#" class="logo">Ride<span class="logo-accent">Aware</span></a>
<ul class="nav-links">
<li><a href="#features">Features</a></li>
<li><a href="/newsletters">Newsletters</a></li>
</ul>
</div>
</nav>
{% block content %}
<!-- Hero Section --> <!-- Hero Section -->
<section class="hero"> <section class="hero">
<div class="hero-container"> <div class="hero-container">
<div class="hero-content"> <div class="hero-content">
<h1>Elevate Your Cycling Journey</h1> <h1>Elevate Your Cycling Journey</h1>
<p class="subtitle"> <p class="subtitle">The ultimate smart training platform for cyclists who demand excellence in every ride.</p>
The ultimate smart training platform for cyclists who demand excellence
in every ride.
</p>
<div class="cta-section"> <div class="cta-section">
<h3>Coming soon!</h3> <h3>Coming soon!</h3>
<p>Join us while waiting for launch</p> <p>Join us while waiting for launch</p>
<div class="email-form"> <div class="email-form">
<input <input type="email" class="email-input" id="email-input" placeholder="Enter your email address" required>
type="email"
class="email-input"
id="email-input"
placeholder="Enter your email address"
required
/>
<button class="notify-btn" id="notify-button">Notify Me</button> <button class="notify-btn" id="notify-button">Notify Me</button>
</div> </div>
</div> </div>
@ -65,10 +73,7 @@
<section class="features" id="features"> <section class="features" id="features">
<div class="section-header"> <div class="section-header">
<h2>Powerful Features for Every Cyclist</h2> <h2>Powerful Features for Every Cyclist</h2>
<p> <p>From beginners to professionals, RideAware provides comprehensive tools to optimize your training and performance.</p>
From beginners to professionals, RideAware provides comprehensive tools
to optimize your training and performance.
</p>
</div> </div>
<div class="features-container"> <div class="features-container">
@ -79,18 +84,9 @@
</div> </div>
<h3>Smart Training Plans</h3> <h3>Smart Training Plans</h3>
<ul class="feature-list"> <ul class="feature-list">
<li> <li><strong>AI-Powered Planning:</strong> Customized training plans based on your goals and fitness level</li>
<strong>AI-Powered Planning:</strong> Customized training plans <li><strong>Adaptive Scheduling:</strong> Smart workout scheduling with automated reminders</li>
based on your goals and fitness level <li><strong>Goal Tracking:</strong> Set and monitor your cycling objectives in real-time</li>
</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> </ul>
</div> </div>
@ -100,18 +96,9 @@
</div> </div>
<h3>Advanced Analytics</h3> <h3>Advanced Analytics</h3>
<ul class="feature-list"> <ul class="feature-list">
<li> <li><strong>Detailed Logging:</strong> Track exercises, sets, reps, and performance metrics</li>
<strong>Detailed Logging:</strong> Track exercises, sets, reps, <li><strong>Data Visualization:</strong> Interactive charts, graphs, and progress statistics</li>
and performance metrics <li><strong>Progress Insights:</strong> Monitor your improvement over time with AI analysis</li>
</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> </ul>
</div> </div>
@ -121,18 +108,9 @@
</div> </div>
<h3>Virtual Training</h3> <h3>Virtual Training</h3>
<ul class="feature-list"> <ul class="feature-list">
<li> <li><strong>Expert Coaching:</strong> Professional guidance to achieve your cycling goals</li>
<strong>Expert Coaching:</strong> Professional guidance to achieve <li><strong>Immersive Rides:</strong> Virtual training experiences to boost performance</li>
your cycling goals <li><strong>Structured Workouts:</strong> Designed programs for fitness and performance gains</li>
</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> </ul>
</div> </div>
@ -142,18 +120,9 @@
</div> </div>
<h3>Health & Recovery</h3> <h3>Health & Recovery</h3>
<ul class="feature-list"> <ul class="feature-list">
<li> <li><strong>Nutrition Tracking:</strong> Plan and monitor your dietary intake for optimal performance</li>
<strong>Nutrition Tracking:</strong> Plan and monitor your dietary <li><strong>Recovery Optimization:</strong> Tools and resources for effective rest and recovery</li>
intake for optimal performance <li><strong>Injury Prevention:</strong> Proactive measures to prevent and manage injuries</li>
</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> </ul>
</div> </div>
@ -163,18 +132,9 @@
</div> </div>
<h3>Community & Social</h3> <h3>Community & Social</h3>
<ul class="feature-list"> <ul class="feature-list">
<li> <li><strong>Social Sharing:</strong> Share achievements and progress on social platforms</li>
<strong>Social Sharing:</strong> Share achievements and progress <li><strong>Active Community:</strong> Connect with fellow cyclists and share experiences</li>
on social platforms <li><strong>Competitive Leaderboards:</strong> Challenge yourself against the community</li>
</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> </ul>
</div> </div>
@ -184,21 +144,21 @@
</div> </div>
<h3>Smart Integration</h3> <h3>Smart Integration</h3>
<ul class="feature-list"> <ul class="feature-list">
<li> <li><strong>Wearable Sync:</strong> Connect with fitness trackers and smart devices</li>
<strong>Wearable Sync:</strong> Connect with fitness trackers and <li><strong>Music Integration:</strong> Seamlessly sync with your favorite music services</li>
smart devices <li><strong>Data Portability:</strong> Easy import/export to other cycling platforms</li>
</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> </ul>
</div> </div>
</div> </div>
</div> </div>
</section> </section>
{% endblock %}
<!-- Footer -->
<footer class="footer">
<p>&copy; 2025 RideAware. All rights reserved.</p>
</footer>
<script defer
src="https://cdn.statically.io/gl/rideaware/landing/06d19988c7df53636277f945f9ed853bda76471b/static/js/main.min.js"
crossorigin="anonymous"></script>
</body>
</html>

View file

@ -1,66 +1,103 @@
{% extends "base.html" %} <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>RideAware - {{ newsletter.subject if newsletter else 'Newsletter Detail' }}</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://cdn.statically.io" crossorigin>
{% block title %} <link rel="stylesheet" href="{{ url_for('static', filename='css/newsletter_styles.css') }}">
RideAware - {{ newsletter.subject if newsletter else 'Newsletter Detail' }}
{% endblock %}
{% block content %} </head>
<div class="article-wrap"> <body>
<aside class="article-aside"> <!-- Navigation -->
<nav class="navbar">
<div class="nav-container">
<a href="/" class="logo">Ride<span class="logo-accent">Aware</span></a>
<ul class="nav-links">
<li><a href="/">Home</a></li>
<li><a href="/newsletters">Newsletters</a></li>
</ul>
</div>
</nav>
<!-- Back Navigation -->
<div class="back-navigation">
<a href="/newsletters" class="back-link"> <a href="/newsletters" class="back-link">
<i class="fas fa-arrow-left"></i> <i class="fas fa-arrow-left"></i>
Back to Newsletters Back to Newsletters
</a> </a>
</div>
<div class="article-meta"> <!-- Main Content -->
<h2 class="article-title">{{ newsletter.subject if newsletter else 'Newsletter Title' }}</h2> <main class="main-content">
<div class="meta-row"> <!-- Newsletter Header -->
<div class="newsletter-header">
<div class="newsletter-icon">
<i class="fas fa-envelope-open-text"></i>
</div>
<h1>{{ newsletter.subject if newsletter else 'Newsletter Title' }}</h1>
<div class="newsletter-meta">
<div class="meta-item">
<i class="fas fa-calendar-alt"></i> <i class="fas fa-calendar-alt"></i>
<span>{{ newsletter.sent_at if newsletter else 'Published Date' }}</span> <span>{{ newsletter.sent_at if newsletter else 'Published Date' }}</span>
</div> </div>
{% if newsletter and newsletter.get('reading_time') %} {% if newsletter and newsletter.get('reading_time') %}
<div class="meta-row"> <div class="meta-item">
<i class="fas fa-clock"></i> <i class="fas fa-clock"></i>
<span>{{ newsletter.reading_time }} min read</span> <span>{{ newsletter.reading_time }} min read</span>
</div> </div>
{% endif %} {% endif %}
{% if newsletter and newsletter.get('author') %} {% if newsletter and newsletter.get('author') %}
<div class="meta-row"> <div class="meta-item">
<i class="fas fa-user"></i> <i class="fas fa-user"></i>
<span>{{ newsletter.author }}</span> <span>{{ newsletter.author }}</span>
</div> </div>
{% endif %} {% endif %}
</div>
{% if newsletter and newsletter.get('tags') %} {% if newsletter and newsletter.get('tags') %}
<div class="article-tags"> <div class="newsletter-tags">
{% for tag in newsletter.tags %} {% for tag in newsletter.tags %}
<span class="tag">{{ tag }}</span> <span class="tag">{{ tag }}</span>
{% endfor %} {% endfor %}
</div> </div>
{% else %}
<div class="newsletter-tags">
<span class="tag">Cycling Tips</span>
<span class="tag">Training</span>
<span class="tag">Performance</span>
</div>
{% endif %} {% endif %}
</div> </div>
<nav class="toc"> <!-- Newsletter Content -->
<div class="toc-title">On this page</div> <article class="newsletter-content">
<ol id="toc-list"></ol>
</nav>
</aside>
<main class="article-main">
<header class="article-hero">
<div class="newsletter-icon"><i class="fas fa-envelope-open-text"></i></div>
<h1>{{ newsletter.subject if newsletter else 'Newsletter Title' }}</h1>
</header>
<article class="newsletter-content" id="article">
{% if newsletter %} {% if newsletter %}
{{ newsletter.body | safe }} {{ newsletter.body | safe }}
{% else %} {% else %}
<h2>Welcome to RideAware Newsletter</h2> <h2>Welcome to RideAware Newsletter</h2>
<p>Sample content…</p> <p>This is a sample newsletter content that demonstrates the modern, clean design of our newsletter system. The content would typically include cycling tips, training advice, and product updates.</p>
<h3>This Week's Highlights</h3>
<ul>
<li>New training features released</li>
<li>Community spotlight on top performers</li>
<li>Upcoming events and challenges</li>
<li>Expert tips from professional cyclists</li>
</ul>
<blockquote>
"The bicycle is a curious vehicle. Its passenger is its engine." - John Howard
</blockquote>
<p>Stay tuned for more exciting content and updates from the RideAware team. We're committed to helping you achieve your cycling goals with the best tools and community support.</p>
{% endif %} {% endif %}
</article> </article>
<!-- Action Buttons -->
<div class="newsletter-actions"> <div class="newsletter-actions">
<a href="/newsletters" class="action-btn primary"> <a href="/newsletters" class="action-btn primary">
<i class="fas fa-list"></i> <i class="fas fa-list"></i>
@ -68,7 +105,7 @@
</a> </a>
<button onclick="window.print()" class="action-btn secondary"> <button onclick="window.print()" class="action-btn secondary">
<i class="fas fa-print"></i> <i class="fas fa-print"></i>
Print Print Newsletter
</button> </button>
<button onclick="shareNewsletter()" class="action-btn secondary"> <button onclick="shareNewsletter()" class="action-btn secondary">
<i class="fas fa-share-alt"></i> <i class="fas fa-share-alt"></i>
@ -76,39 +113,13 @@
</button> </button>
</div> </div>
</main> </main>
</div>
{% endblock %}
{% block extra_scripts %} <!-- Footer -->
<script> <footer class="footer">
function shareNewsletter() { <p>&copy; 2025 RideAware. All rights reserved.</p>
if (navigator.share) { </footer>
navigator.share({ title: document.title, url: location.href }).catch(() => {}); <script defer
} else { src="https://cdn.statically.io/gl/rideaware/landing/06d19988c7df53636277f945f9ed853bda76471b/static/js/main.min.js"
navigator.clipboard.writeText(location.href); crossorigin="anonymous"></script>
alert('Link copied to clipboard!'); </body>
} </html>
}
// 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;
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 %}

View file

@ -1,8 +1,25 @@
{% extends "base.html" %} <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>RideAware - Newsletters</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<link rel="stylesheet" href="{{ url_for('static', filename='css/newsletter_styles.css') }}">
{% block title %}RideAware - Newsletters{% endblock %} </head>
<body>
<!-- Navigation -->
<nav class="navbar">
<div class="nav-container">
<a href="/" class="logo">Ride<span class="logo-accent">Aware</span></a>
<ul class="nav-links">
<li><a href="/">Home</a></li>
<li><a href="/newsletters" class="active">Newsletters</a></li>
</ul>
</div>
</nav>
{% block content %}
<!-- Page Header --> <!-- Page Header -->
<section class="page-header"> <section class="page-header">
<div class="page-header-content"> <div class="page-header-content">
@ -10,10 +27,7 @@
<i class="fas fa-newspaper"></i> <i class="fas fa-newspaper"></i>
</div> </div>
<h1>RideAware Newsletters</h1> <h1>RideAware Newsletters</h1>
<p> <p>Stay updated with the latest cycling tips, training insights, and product updates from our team.</p>
Stay updated with the latest cycling tips, training insights, and
product updates from our team.
</p>
</div> </div>
</section> </section>
@ -43,8 +57,7 @@
{% if nl.get('preview') %} {% if nl.get('preview') %}
{{ nl['preview'][:150] }}... {{ nl['preview'][:150] }}...
{% else %} {% else %}
Get the latest updates on cycling training, performance tips, and Get the latest updates on cycling training, performance tips, and RideAware features in this newsletter edition.
RideAware features in this newsletter edition.
{% endif %} {% endif %}
</div> </div>
@ -61,10 +74,7 @@
<i class="fas fa-inbox"></i> <i class="fas fa-inbox"></i>
</div> </div>
<h3>No Newsletters Yet</h3> <h3>No Newsletters Yet</h3>
<p> <p>We're working on some amazing content for you. Subscribe to be the first to know when we publish our newsletters!</p>
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="/" class="subscribe-prompt">
<i class="fas fa-bell"></i> <i class="fas fa-bell"></i>
Subscribe for Updates Subscribe for Updates
@ -72,4 +82,13 @@
</div> </div>
{% endif %} {% endif %}
</main> </main>
{% endblock %}
<!-- Footer -->
<footer class="footer">
<p>&copy; 2025 RideAware. All rights reserved.</p>
</footer>
<script defer
src="https://cdn.statically.io/gl/rideaware/landing/06d19988c7df53636277f945f9ed853bda76471b/static/js/main.min.js"
crossorigin="anonymous"></script>
</body>
</html>