Add legal and onboarding pages
- Add /sms-onboarding page for text message consent signup with FAQ, consent checkbox, and feature grid - Add /privacy-policy page with comprehensive sections covering data collection, SMS communications, and user rights - Add /terms page with full terms of use including SMS service terms, intellectual property, and disclaimers All pages use BaseLayout and site-context for dynamic branding. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
245
src/pages/privacy-policy.astro
Normal file
245
src/pages/privacy-policy.astro
Normal file
@@ -0,0 +1,245 @@
|
|||||||
|
---
|
||||||
|
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||||
|
import { loadSiteData } from '../lib/site-data.ts';
|
||||||
|
|
||||||
|
const { siteContext } = loadSiteData();
|
||||||
|
---
|
||||||
|
<BaseLayout title={`Privacy Policy — ${siteContext.businessName}`} primaryColor={siteContext.primaryColor}>
|
||||||
|
<Fragment slot="logo">{siteContext.businessName}</Fragment>
|
||||||
|
<Fragment slot="tagline">Your Privacy Matters</Fragment>
|
||||||
|
|
||||||
|
<section class="legal-page">
|
||||||
|
<div class="container">
|
||||||
|
<h1>Privacy Policy</h1>
|
||||||
|
<p class="effective-date">Effective Date: April 26, 2026</p>
|
||||||
|
|
||||||
|
<div class="legal-content">
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>1. Introduction</h2>
|
||||||
|
<p>
|
||||||
|
{siteContext.businessName} ("we," "us," or "our") respects your privacy and is committed to protecting your personal information.
|
||||||
|
This Privacy Policy explains how we collect, use, store, and safeguard your information when you visit our website,
|
||||||
|
use our services, or subscribe to our text message updates.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>2. Information We Collect</h2>
|
||||||
|
<h3>2.1 Information You Provide Directly</h3>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Contact Information:</strong> Name, phone number, and email address when you sign up for text notifications or contact us.</li>
|
||||||
|
<li><strong>Communication Preferences:</strong> Your opt-in consent for receiving text messages and marketing communications.</li>
|
||||||
|
<li><strong>Feedback:</strong> Any comments, reviews, or messages you send us.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h3>2.2 Information Collected Automatically</h3>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Usage Data:</strong> Pages visited, time spent on site, clicks, and interactions.</li>
|
||||||
|
<li><strong>Device Information:</strong> Browser type, operating system, IP address, and device identifiers.</li>
|
||||||
|
<li><strong>Cookies:</strong> Small data files stored on your device to improve your browsing experience.</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>3. How We Use Your Information</h2>
|
||||||
|
<p>We use the information we collect for the following purposes:</p>
|
||||||
|
<ul>
|
||||||
|
<li>To send you text message updates about our website, events, and offerings (with your explicit consent).</li>
|
||||||
|
<li>To respond to your inquiries and provide customer support.</li>
|
||||||
|
<li>To improve our website, services, and user experience.</li>
|
||||||
|
<li>To comply with legal obligations and enforce our terms.</li>
|
||||||
|
<li>To detect and prevent fraud, abuse, and security incidents.</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>4. Text Message Communications (SMS)</h2>
|
||||||
|
<p>
|
||||||
|
When you subscribe to our text message updates, you provide explicit consent to receive SMS messages
|
||||||
|
from {siteContext.businessName} at the phone number you provide.
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Message Frequency:</strong> Message frequency varies, typically 2–4 messages per month.</li>
|
||||||
|
<li><strong>Message and Data Rates:</strong> Standard message and data rates may apply based on your wireless carrier plan.</li>
|
||||||
|
<li><strong>Opt-Out:</strong> You may opt out at any time by replying <strong>STOP</strong> to any message.</li>
|
||||||
|
<li><strong>Help:</strong> Reply <strong>HELP</strong> for assistance or contact us directly.</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
We use third-party SMS providers to deliver messages. Your phone number is shared with these providers
|
||||||
|
solely for the purpose of message delivery and is not used for any other marketing without your additional consent.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>5. How We Share Your Information</h2>
|
||||||
|
<p>We do not sell your personal information. We may share your information in the following limited circumstances:</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Service Providers:</strong> With trusted third-party vendors who help us operate our website and deliver services (e.g., SMS providers, hosting, analytics).</li>
|
||||||
|
<li><strong>Legal Compliance:</strong> When required by law, subpoena, or legal process.</li>
|
||||||
|
<li><strong>Business Transfers:</strong> In connection with a merger, acquisition, or sale of assets, with notice to you.</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>6. Data Security</h2>
|
||||||
|
<p>
|
||||||
|
We implement reasonable technical and organizational measures to protect your personal information
|
||||||
|
against unauthorized access, alteration, disclosure, or destruction. However, no method of transmission
|
||||||
|
over the internet or electronic storage is 100% secure, and we cannot guarantee absolute security.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>7. Data Retention</h2>
|
||||||
|
<p>
|
||||||
|
We retain your personal information for as long as necessary to fulfill the purposes outlined in this policy,
|
||||||
|
unless a longer retention period is required or permitted by law. If you opt out of SMS messages,
|
||||||
|
we retain your phone number in a suppression list to honor your opt-out preference.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>8. Your Rights</h2>
|
||||||
|
<p>Depending on your location, you may have the following rights regarding your personal information:</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Access:</strong> Request a copy of the personal information we hold about you.</li>
|
||||||
|
<li><strong>Correction:</strong> Request that we correct inaccurate or incomplete information.</li>
|
||||||
|
<li><strong>Deletion:</strong> Request that we delete your personal information, subject to legal obligations.</li>
|
||||||
|
<li><strong>Opt-Out:</strong> Unsubscribe from marketing communications at any time.</li>
|
||||||
|
<li><strong>Portability:</strong> Request a copy of your data in a portable format.</li>
|
||||||
|
</ul>
|
||||||
|
<p>To exercise any of these rights, please contact us using the information below.</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>9. Cookies and Tracking Technologies</h2>
|
||||||
|
<p>
|
||||||
|
We use cookies and similar technologies to enhance your experience on our website.
|
||||||
|
You can manage your cookie preferences through your browser settings.
|
||||||
|
Disabling cookies may affect the functionality of certain features on our site.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>10. Third-Party Links</h2>
|
||||||
|
<p>
|
||||||
|
Our website may contain links to third-party websites. We are not responsible for the privacy practices
|
||||||
|
or content of those sites. We encourage you to review the privacy policies of any third-party sites you visit.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>11. Children's Privacy</h2>
|
||||||
|
<p>
|
||||||
|
Our services are not directed to individuals under the age of 13.
|
||||||
|
We do not knowingly collect personal information from children under 13.
|
||||||
|
If we become aware that we have collected such information, we will take steps to delete it promptly.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>12. Changes to This Policy</h2>
|
||||||
|
<p>
|
||||||
|
We may update this Privacy Policy from time to time. Changes will be posted on this page with an updated
|
||||||
|
effective date. We encourage you to review this policy periodically. Significant changes may be communicated
|
||||||
|
via text message if you are subscribed to our updates.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>13. Contact Us</h2>
|
||||||
|
<p>
|
||||||
|
If you have any questions, concerns, or requests regarding this Privacy Policy or our data practices,
|
||||||
|
please contact us:
|
||||||
|
</p>
|
||||||
|
<ul class="contact-list">
|
||||||
|
{siteContext.contactEmail && <li><strong>Email:</strong> <a href={`mailto:${siteContext.contactEmail}`}>{siteContext.contactEmail}</a></li>}
|
||||||
|
{siteContext.contactPhone && <li><strong>Phone:</strong> {siteContext.contactPhone}</li>}
|
||||||
|
{siteContext.address && <li><strong>Address:</strong> {siteContext.address}</li>}
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<Fragment slot="footer">
|
||||||
|
© {new Date().getFullYear()} {siteContext.businessName} ·
|
||||||
|
<a href="/privacy-policy">Privacy Policy</a> ·
|
||||||
|
<a href="/terms">Terms of Use</a>
|
||||||
|
</Fragment>
|
||||||
|
</BaseLayout>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.legal-page {
|
||||||
|
padding: 3rem 1.5rem 4rem;
|
||||||
|
}
|
||||||
|
.legal-page h1 {
|
||||||
|
font-family: var(--font-display);
|
||||||
|
font-size: 2rem;
|
||||||
|
color: var(--color-primary-dark);
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
.effective-date {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: var(--color-text-muted);
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legal-content {
|
||||||
|
max-width: 720px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.legal-section {
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
.legal-section h2 {
|
||||||
|
font-family: var(--font-display);
|
||||||
|
font-size: 1.2rem;
|
||||||
|
color: var(--color-primary-dark);
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
padding-bottom: 0.35rem;
|
||||||
|
border-bottom: 1px solid var(--color-border);
|
||||||
|
}
|
||||||
|
.legal-section h3 {
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-text);
|
||||||
|
margin: 1rem 0 0.5rem;
|
||||||
|
}
|
||||||
|
.legal-section p {
|
||||||
|
font-size: 0.95rem;
|
||||||
|
color: var(--color-text);
|
||||||
|
line-height: 1.7;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
.legal-section ul {
|
||||||
|
margin-left: 1.25rem;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
.legal-section li {
|
||||||
|
font-size: 0.95rem;
|
||||||
|
color: var(--color-text);
|
||||||
|
line-height: 1.7;
|
||||||
|
margin-bottom: 0.4rem;
|
||||||
|
}
|
||||||
|
.legal-section li strong {
|
||||||
|
color: var(--color-primary-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
.contact-list {
|
||||||
|
list-style: none;
|
||||||
|
margin-left: 0;
|
||||||
|
padding: 0.75rem;
|
||||||
|
background: color-mix(in srgb, var(--color-primary), white 95%);
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
}
|
||||||
|
.contact-list li {
|
||||||
|
margin-bottom: 0.35rem;
|
||||||
|
}
|
||||||
|
.contact-list a {
|
||||||
|
color: var(--color-primary);
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
421
src/pages/sms-onboarding.astro
Normal file
421
src/pages/sms-onboarding.astro
Normal file
@@ -0,0 +1,421 @@
|
|||||||
|
---
|
||||||
|
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||||
|
import { loadSiteData } from '../lib/site-data.ts';
|
||||||
|
|
||||||
|
const { siteContext } = loadSiteData();
|
||||||
|
|
||||||
|
// In a real implementation, this would connect to an API endpoint
|
||||||
|
// that stores the phone number and sends a confirmation SMS
|
||||||
|
---
|
||||||
|
<BaseLayout title={`Text Message Updates — ${siteContext.businessName}`} primaryColor={siteContext.primaryColor}>
|
||||||
|
<Fragment slot="logo">{siteContext.businessName}</Fragment>
|
||||||
|
<Fragment slot="tagline">Stay Connected</Fragment>
|
||||||
|
|
||||||
|
<section class="onboarding-hero">
|
||||||
|
<div class="container">
|
||||||
|
<h1>Get Website Updates by Text</h1>
|
||||||
|
<p class="lead">
|
||||||
|
Sign up to receive text message notifications whenever we update our website
|
||||||
|
with new events, menu items, or announcements.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="onboarding-form">
|
||||||
|
<div class="container">
|
||||||
|
<div class="form-card">
|
||||||
|
<h2>Sign Up for Text Notifications</h2>
|
||||||
|
<form id="sms-signup-form" method="POST" action="/api/sms/subscribe">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="phone">Phone Number</label>
|
||||||
|
<input
|
||||||
|
type="tel"
|
||||||
|
id="phone"
|
||||||
|
name="phone"
|
||||||
|
placeholder="(503) 555-0142"
|
||||||
|
required
|
||||||
|
pattern="[\d\s\-\+\(\)]{10,}"
|
||||||
|
/>
|
||||||
|
<span class="hint">We'll send a confirmation text to verify your number.</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="name">Your Name (optional)</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="name"
|
||||||
|
name="name"
|
||||||
|
placeholder="First name"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="consent-box">
|
||||||
|
<label class="checkbox-label">
|
||||||
|
<input type="checkbox" name="consent" required />
|
||||||
|
<span class="checkmark"></span>
|
||||||
|
<span class="label-text">
|
||||||
|
I consent to receive text messages from <strong>{siteContext.businessName}</strong>
|
||||||
|
about website updates, events, and announcements.
|
||||||
|
Message frequency varies. Message and data rates may apply.
|
||||||
|
Reply STOP to opt out at any time.
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="submit-btn">Subscribe</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div id="form-success" class="form-message success" style="display: none;">
|
||||||
|
<h3>You're all set!</h3>
|
||||||
|
<p>Check your phone for a confirmation message. Reply YES to complete your signup.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="form-error" class="form-message error" style="display: none;">
|
||||||
|
<h3>Something went wrong</h3>
|
||||||
|
<p>Please try again or contact us directly.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="what-to-expect">
|
||||||
|
<div class="container">
|
||||||
|
<h2>What You'll Receive</h2>
|
||||||
|
<div class="feature-grid">
|
||||||
|
<div class="feature">
|
||||||
|
<span class="feature-icon">📅</span>
|
||||||
|
<h3>New Events</h3>
|
||||||
|
<p>Be the first to know about upcoming community events, tastings, and workshops.</p>
|
||||||
|
</div>
|
||||||
|
<div class="feature">
|
||||||
|
<span class="feature-icon">☕</span>
|
||||||
|
<h3>Menu Updates</h3>
|
||||||
|
<p>Get notified when we add new seasonal drinks or specialty items to the menu.</p>
|
||||||
|
</div>
|
||||||
|
<div class="feature">
|
||||||
|
<span class="feature-icon">🏷️</span>
|
||||||
|
<h3>Special Offers</h3>
|
||||||
|
<p>Receive exclusive promotions and limited-time offers for subscribers.</p>
|
||||||
|
</div>
|
||||||
|
<div class="feature">
|
||||||
|
<span class="feature-icon">🔔</span>
|
||||||
|
<h3>Website Changes</h3>
|
||||||
|
<p>Stay informed when we update our hours, location details, or services.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="faq-section">
|
||||||
|
<div class="container">
|
||||||
|
<h2>Common Questions</h2>
|
||||||
|
<div class="faq-list">
|
||||||
|
<details class="faq-item">
|
||||||
|
<summary>How often will I receive messages?</summary>
|
||||||
|
<p>
|
||||||
|
Message frequency varies based on website updates and events — typically 2-4 messages per month.
|
||||||
|
We respect your time and only send messages that matter.
|
||||||
|
</p>
|
||||||
|
</details>
|
||||||
|
<details class="faq-item">
|
||||||
|
<summary>Is there a cost?</summary>
|
||||||
|
<p>
|
||||||
|
Message and data rates may apply depending on your wireless carrier plan.
|
||||||
|
Standard text messaging rates from your provider will apply.
|
||||||
|
</p>
|
||||||
|
</details>
|
||||||
|
<details class="faq-item">
|
||||||
|
<summary>How do I stop receiving messages?</summary>
|
||||||
|
<p>
|
||||||
|
Reply <strong>STOP</strong> to any message at any time to opt out.
|
||||||
|
You'll receive a confirmation, and no further messages will be sent.
|
||||||
|
Reply <strong>START</strong> to resubscribe.
|
||||||
|
</p>
|
||||||
|
</details>
|
||||||
|
<details class="faq-item">
|
||||||
|
<summary>Is my phone number shared?</summary>
|
||||||
|
<p>
|
||||||
|
No. Your phone number is used solely by {siteContext.businessName} for the purposes
|
||||||
|
you consented to. We do not sell or share your information with third parties.
|
||||||
|
See our <a href="/privacy-policy">Privacy Policy</a> for full details.
|
||||||
|
</p>
|
||||||
|
</details>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<Fragment slot="footer">
|
||||||
|
© {new Date().getFullYear()} {siteContext.businessName} ·
|
||||||
|
<a href="/privacy-policy">Privacy Policy</a> ·
|
||||||
|
<a href="/terms">Terms of Use</a>
|
||||||
|
</Fragment>
|
||||||
|
</BaseLayout>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.onboarding-hero {
|
||||||
|
text-align: center;
|
||||||
|
padding: 4rem 1.5rem 2.5rem;
|
||||||
|
background: linear-gradient(180deg, color-mix(in srgb, var(--color-primary), white 92%) 0%, var(--color-bg) 100%);
|
||||||
|
}
|
||||||
|
.onboarding-hero h1 {
|
||||||
|
font-family: var(--font-display);
|
||||||
|
font-size: 2.25rem;
|
||||||
|
color: var(--color-primary-dark);
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
.onboarding-hero .lead {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: var(--color-text-muted);
|
||||||
|
max-width: 560px;
|
||||||
|
margin: 0 auto;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.onboarding-form {
|
||||||
|
padding: 1.5rem 1.5rem 3rem;
|
||||||
|
}
|
||||||
|
.form-card {
|
||||||
|
max-width: 520px;
|
||||||
|
margin: 0 auto;
|
||||||
|
background: white;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
.form-card h2 {
|
||||||
|
font-family: var(--font-display);
|
||||||
|
font-size: 1.3rem;
|
||||||
|
color: var(--color-primary-dark);
|
||||||
|
margin-bottom: 1.25rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group {
|
||||||
|
margin-bottom: 1.25rem;
|
||||||
|
}
|
||||||
|
.form-group label {
|
||||||
|
display: block;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--color-text);
|
||||||
|
margin-bottom: 0.35rem;
|
||||||
|
}
|
||||||
|
.form-group input {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.65rem 0.85rem;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-family: var(--font-body);
|
||||||
|
transition: border-color 0.2s;
|
||||||
|
}
|
||||||
|
.form-group input:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: var(--color-primary);
|
||||||
|
}
|
||||||
|
.form-group .hint {
|
||||||
|
display: block;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: var(--color-text-muted);
|
||||||
|
margin-top: 0.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.consent-box {
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
.checkbox-label {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 0.6rem;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: var(--color-text);
|
||||||
|
}
|
||||||
|
.checkbox-label input[type="checkbox"] {
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
margin-top: 0.15rem;
|
||||||
|
accent-color: var(--color-primary);
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.label-text strong {
|
||||||
|
color: var(--color-primary-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-btn {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.8rem;
|
||||||
|
background: var(--color-primary);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: var(--font-body);
|
||||||
|
transition: background 0.2s;
|
||||||
|
}
|
||||||
|
.submit-btn:hover {
|
||||||
|
background: var(--color-primary-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-message {
|
||||||
|
text-align: center;
|
||||||
|
padding: 1.5rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
.form-message h3 {
|
||||||
|
font-family: var(--font-display);
|
||||||
|
font-size: 1.15rem;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
.form-message.success {
|
||||||
|
background: color-mix(in srgb, #22c55e, white 88%);
|
||||||
|
color: #166534;
|
||||||
|
}
|
||||||
|
.form-message.error {
|
||||||
|
background: color-mix(in srgb, #ef4444, white 88%);
|
||||||
|
color: #991b1b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.what-to-expect {
|
||||||
|
padding: 3rem 1.5rem;
|
||||||
|
background: color-mix(in srgb, var(--color-primary), white 96%);
|
||||||
|
border-top: 1px solid var(--color-border);
|
||||||
|
}
|
||||||
|
.what-to-expect h2 {
|
||||||
|
font-family: var(--font-display);
|
||||||
|
font-size: 1.6rem;
|
||||||
|
color: var(--color-primary-dark);
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
.feature-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
gap: 1.5rem;
|
||||||
|
max-width: 720px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.feature-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.feature {
|
||||||
|
text-align: center;
|
||||||
|
padding: 1.25rem;
|
||||||
|
background: white;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
.feature-icon {
|
||||||
|
font-size: 1.75rem;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
.feature h3 {
|
||||||
|
font-family: var(--font-display);
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: var(--color-primary-dark);
|
||||||
|
margin-bottom: 0.4rem;
|
||||||
|
}
|
||||||
|
.feature p {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: var(--color-text-muted);
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-section {
|
||||||
|
padding: 3rem 1.5rem;
|
||||||
|
}
|
||||||
|
.faq-section h2 {
|
||||||
|
font-family: var(--font-display);
|
||||||
|
font-size: 1.6rem;
|
||||||
|
color: var(--color-primary-dark);
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
.faq-list {
|
||||||
|
max-width: 680px;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
.faq-item {
|
||||||
|
background: white;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.faq-item summary {
|
||||||
|
padding: 1rem 1.25rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--color-text);
|
||||||
|
cursor: pointer;
|
||||||
|
list-style: none;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.faq-item summary::-webkit-details-marker {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.faq-item summary::after {
|
||||||
|
content: '+';
|
||||||
|
font-size: 1.25rem;
|
||||||
|
color: var(--color-primary);
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
.faq-item[open] summary::after {
|
||||||
|
content: '−';
|
||||||
|
}
|
||||||
|
.faq-item p {
|
||||||
|
padding: 0 1.25rem 1rem;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: var(--color-text-muted);
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
.faq-item p a {
|
||||||
|
color: var(--color-primary);
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const form = document.getElementById('sms-signup-form');
|
||||||
|
const successMsg = document.getElementById('form-success');
|
||||||
|
const errorMsg = document.getElementById('form-error');
|
||||||
|
|
||||||
|
if (form) {
|
||||||
|
form.addEventListener('submit', async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const formData = new FormData(form);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/sms/subscribe', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({
|
||||||
|
phone: formData.get('phone'),
|
||||||
|
name: formData.get('name'),
|
||||||
|
consent: formData.get('consent') === 'on',
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
form.style.display = 'none';
|
||||||
|
successMsg.style.display = 'block';
|
||||||
|
} else {
|
||||||
|
throw new Error('Subscription failed');
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
errorMsg.style.display = 'block';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
290
src/pages/terms.astro
Normal file
290
src/pages/terms.astro
Normal file
@@ -0,0 +1,290 @@
|
|||||||
|
---
|
||||||
|
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||||
|
import { loadSiteData } from '../lib/site-data.ts';
|
||||||
|
|
||||||
|
const { siteContext } = loadSiteData();
|
||||||
|
---
|
||||||
|
<BaseLayout title={`Terms of Use — ${siteContext.businessName}`} primaryColor={siteContext.primaryColor}>
|
||||||
|
<Fragment slot="logo">{siteContext.businessName}</Fragment>
|
||||||
|
<Fragment slot="tagline">Terms and Conditions</Fragment>
|
||||||
|
|
||||||
|
<section class="legal-page">
|
||||||
|
<div class="container">
|
||||||
|
<h1>Terms of Use</h1>
|
||||||
|
<p class="effective-date">Effective Date: April 26, 2026</p>
|
||||||
|
|
||||||
|
<div class="legal-content">
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>1. Acceptance of Terms</h2>
|
||||||
|
<p>
|
||||||
|
By accessing or using the website and services of {siteContext.businessName} ("we," "us," or "our"),
|
||||||
|
you agree to be bound by these Terms of Use. If you do not agree to all of these terms, you may not
|
||||||
|
access or use our website or services. These terms apply to all visitors, users, and others who access
|
||||||
|
or use the service.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>2. Changes to Terms</h2>
|
||||||
|
<p>
|
||||||
|
We reserve the right to modify or replace these Terms of Use at any time at our sole discretion.
|
||||||
|
Changes will be effective immediately upon posting to this page. Your continued use of the website
|
||||||
|
after any changes constitutes acceptance of the new terms. We encourage you to review these terms
|
||||||
|
periodically.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>3. Use of the Website</h2>
|
||||||
|
<p>You agree to use our website only for lawful purposes and in a manner that does not infringe the rights of,
|
||||||
|
restrict, or inhibit anyone else's use and enjoyment of the website. Prohibited behavior includes:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Using the website in any way that breaches any applicable local, national, or international law.</li>
|
||||||
|
<li>Transmitting or procuring the sending of any unsolicited or unauthorized advertising or promotional material.</li>
|
||||||
|
<li>Knowingly transmitting any data or sending any material that contains viruses, malware, or other harmful code.</li>
|
||||||
|
<li>Attempting to gain unauthorized access to our website, server, or any related systems.</li>
|
||||||
|
<li>Engaging in any activity that disrupts or interferes with the website's functionality.</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>4. Intellectual Property</h2>
|
||||||
|
<p>
|
||||||
|
All content on this website, including but not limited to text, graphics, logos, images, audio clips,
|
||||||
|
digital downloads, data compilations, and software, is the property of {siteContext.businessName}
|
||||||
|
or its content suppliers and is protected by copyright, trademark, and other intellectual property laws.
|
||||||
|
</p>
|
||||||
|
<p>You may not:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Reproduce, duplicate, copy, sell, resell, or exploit any portion of the website without express written permission.</li>
|
||||||
|
<li>Use our trademarks, service marks, or logos without prior written consent.</li>
|
||||||
|
<li>Modify, adapt, translate, or create derivative works based on the website or its content.</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>5. User Contributions</h2>
|
||||||
|
<p>
|
||||||
|
If you submit any content to us — including feedback, suggestions, reviews, or other materials — you grant us
|
||||||
|
a non-exclusive, royalty-free, perpetual, irrevocable, and fully sublicensable right to use, reproduce,
|
||||||
|
modify, adapt, publish, translate, create derivative works from, distribute, and display such content
|
||||||
|
throughout the world in any media.
|
||||||
|
</p>
|
||||||
|
<p>You represent and warrant that:</p>
|
||||||
|
<ul>
|
||||||
|
<li>You own or have the necessary rights to the content you submit.</li>
|
||||||
|
<li>The content does not violate the rights of any third party, including copyright, privacy, or publicity rights.</li>
|
||||||
|
<li>The content is not unlawful, defamatory, obscene, or otherwise objectionable.</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>6. Text Message Service (SMS)</h2>
|
||||||
|
<p>
|
||||||
|
By subscribing to our text message updates, you agree to the following terms in addition to these Terms of Use:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Eligibility:</strong> You must be at least 18 years old or have parental consent to subscribe.</li>
|
||||||
|
<li><strong>Consent:</strong> You provide express written consent to receive automated marketing and informational text messages.</li>
|
||||||
|
<li><strong>Frequency:</strong> Message frequency varies, typically 2–4 messages per month.</li>
|
||||||
|
<li><strong>Rates:</strong> Message and data rates may apply based on your wireless carrier plan.</li>
|
||||||
|
<li><strong>Opt-Out:</strong> You may cancel at any time by replying <strong>STOP</strong> to any message.</li>
|
||||||
|
<li><strong>Help:</strong> Reply <strong>HELP</strong> for assistance or contact us directly.</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
We are not liable for delayed or undelivered messages. Delivery is subject to your wireless carrier's
|
||||||
|
service and network availability. We reserve the right to discontinue the SMS service at any time.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>7. Third-Party Links and Services</h2>
|
||||||
|
<p>
|
||||||
|
Our website may contain links to third-party websites or services that are not owned or controlled by
|
||||||
|
{siteContext.businessName}. We have no control over and assume no responsibility for the content,
|
||||||
|
privacy policies, or practices of any third-party websites or services. You acknowledge and agree that we
|
||||||
|
shall not be responsible or liable, directly or indirectly, for any damage or loss caused or alleged to
|
||||||
|
be caused by or in connection with the use of or reliance on any such content, goods, or services
|
||||||
|
available on or through any such websites or services.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>8. Disclaimer of Warranties</h2>
|
||||||
|
<p>
|
||||||
|
Our website and services are provided on an <strong>"as is" and "as available"</strong> basis.
|
||||||
|
We make no warranties, expressed or implied, regarding the operation of the website, the accuracy,
|
||||||
|
completeness, or reliability of any content, or that the website will be uninterrupted, timely, secure,
|
||||||
|
or error-free.
|
||||||
|
</p>
|
||||||
|
<p>To the fullest extent permitted by applicable law, we disclaim all warranties, express or implied,
|
||||||
|
including but not limited to implied warranties of merchantability, fitness for a particular purpose,
|
||||||
|
and non-infringement.</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>9. Limitation of Liability</h2>
|
||||||
|
<p>
|
||||||
|
To the fullest extent permitted by applicable law, {siteContext.businessName} and its officers,
|
||||||
|
directors, employees, agents, and affiliates shall not be liable for any indirect, incidental, special,
|
||||||
|
consequential, or punitive damages, including but not limited to loss of profits, data, use, goodwill,
|
||||||
|
or other intangible losses, resulting from:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>Your access to or use of, or inability to access or use, the website.</li>
|
||||||
|
<li>Any conduct or content of any third party on the website.</li>
|
||||||
|
<li>Any content obtained from the website.</li>
|
||||||
|
<li>Unauthorized access, use, or alteration of your transmissions or content.</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>10. Indemnification</h2>
|
||||||
|
<p>
|
||||||
|
You agree to defend, indemnify, and hold harmless {siteContext.businessName} and its affiliates,
|
||||||
|
officers, directors, employees, and agents from and against any and all claims, damages, obligations,
|
||||||
|
losses, liabilities, costs, or debt, and expenses (including but not limited to attorney's fees)
|
||||||
|
arising from your use of and access to the website, your violation of any term of these Terms of Use,
|
||||||
|
or your violation of any third-party right, including without limitation any copyright, property,
|
||||||
|
or privacy right.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>11. Termination</h2>
|
||||||
|
<p>
|
||||||
|
We may terminate or suspend your access to the website immediately, without prior notice or liability,
|
||||||
|
for any reason whatsoever, including without limitation if you breach these Terms of Use.
|
||||||
|
Upon termination, your right to use the website will immediately cease. All provisions of these terms
|
||||||
|
which by their nature should survive termination shall survive, including ownership provisions,
|
||||||
|
warranty disclaimers, indemnity, and limitations of liability.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>12. Governing Law</h2>
|
||||||
|
<p>
|
||||||
|
These Terms of Use shall be governed by and construed in accordance with the laws of the State of Texas,
|
||||||
|
without regard to its conflict of law provisions. Any dispute arising from or relating to these terms
|
||||||
|
shall be subject to the exclusive jurisdiction of the courts located in Houston, Texas.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>13. Dispute Resolution</h2>
|
||||||
|
<p>
|
||||||
|
Any dispute, controversy, or claim arising out of or relating to these Terms of Use, including the
|
||||||
|
formation, interpretation, breach, termination, or validity thereof, shall first be attempted to be
|
||||||
|
resolved through good-faith negotiation. If the dispute cannot be resolved through negotiation within
|
||||||
|
thirty (30) days, either party may pursue legal remedies in accordance with the Governing Law section above.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>14. Severability</h2>
|
||||||
|
<p>
|
||||||
|
If any provision of these Terms of Use is found to be invalid, illegal, or unenforceable by a court of
|
||||||
|
competent jurisdiction, such provision shall be severed from these terms, and the remaining provisions
|
||||||
|
shall continue in full force and effect.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>15. Entire Agreement</h2>
|
||||||
|
<p>
|
||||||
|
These Terms of Use, together with our <a href="/privacy-policy">Privacy Policy</a>, constitute the
|
||||||
|
entire agreement between you and {siteContext.businessName} regarding the use of our website and services,
|
||||||
|
superseding any prior agreements, communications, and proposals, whether oral or written.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>16. Contact Us</h2>
|
||||||
|
<p>
|
||||||
|
If you have any questions about these Terms of Use, please contact us:
|
||||||
|
</p>
|
||||||
|
<ul class="contact-list">
|
||||||
|
{siteContext.contactEmail && <li><strong>Email:</strong> <a href={`mailto:${siteContext.contactEmail}`}>{siteContext.contactEmail}</a></li>}
|
||||||
|
{siteContext.contactPhone && <li><strong>Phone:</strong> {siteContext.contactPhone}</li>}
|
||||||
|
{siteContext.address && <li><strong>Address:</strong> {siteContext.address}</li>}
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<Fragment slot="footer">
|
||||||
|
© {new Date().getFullYear()} {siteContext.businessName} ·
|
||||||
|
<a href="/privacy-policy">Privacy Policy</a> ·
|
||||||
|
<a href="/terms">Terms of Use</a>
|
||||||
|
</Fragment>
|
||||||
|
</BaseLayout>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.legal-page {
|
||||||
|
padding: 3rem 1.5rem 4rem;
|
||||||
|
}
|
||||||
|
.legal-page h1 {
|
||||||
|
font-family: var(--font-display);
|
||||||
|
font-size: 2rem;
|
||||||
|
color: var(--color-primary-dark);
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
.effective-date {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: var(--color-text-muted);
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legal-content {
|
||||||
|
max-width: 720px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.legal-section {
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
.legal-section h2 {
|
||||||
|
font-family: var(--font-display);
|
||||||
|
font-size: 1.2rem;
|
||||||
|
color: var(--color-primary-dark);
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
padding-bottom: 0.35rem;
|
||||||
|
border-bottom: 1px solid var(--color-border);
|
||||||
|
}
|
||||||
|
.legal-section p {
|
||||||
|
font-size: 0.95rem;
|
||||||
|
color: var(--color-text);
|
||||||
|
line-height: 1.7;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
.legal-section ul {
|
||||||
|
margin-left: 1.25rem;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
.legal-section li {
|
||||||
|
font-size: 0.95rem;
|
||||||
|
color: var(--color-text);
|
||||||
|
line-height: 1.7;
|
||||||
|
margin-bottom: 0.4rem;
|
||||||
|
}
|
||||||
|
.legal-section li strong {
|
||||||
|
color: var(--color-primary-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
.contact-list {
|
||||||
|
list-style: none;
|
||||||
|
margin-left: 0;
|
||||||
|
padding: 0.75rem;
|
||||||
|
background: color-mix(in srgb, var(--color-primary), white 95%);
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
}
|
||||||
|
.contact-list li {
|
||||||
|
margin-bottom: 0.35rem;
|
||||||
|
}
|
||||||
|
.contact-list a {
|
||||||
|
color: var(--color-primary);
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user