feat(legal): add /policies, /contact, /promotions pages for Stripe verification #165

Merged
chihlasm merged 2 commits from feat/stripe-legal-pages into main 2026-05-12 05:23:44 +00:00
10 changed files with 382 additions and 25 deletions

View File

@@ -0,0 +1,35 @@
import { Link } from 'react-router-dom'
// Styles live in src/styles/landing.css under `.landing-footer*`. The component
// must be rendered inside a `.landing-page` wrapper so the `--lp-*` CSS
// variables resolve. All current marketing surfaces (LandingPage,
// PricingPage, ContactSalesPage) already provide that wrapper.
export function MarketingFooter() {
return (
<footer className="landing-footer">
<div className="landing-footer-inner">
<div className="landing-footer-left">
<div className="landing-nav-logo-icon" style={{ width: 24, height: 24, borderRadius: 6 }}>
<svg viewBox="0 0 24 24" fill="none" stroke="#000" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" style={{ width: 14, height: 14 }}>
<circle cx="12" cy="5" r="2" />
<line x1="12" y1="7" x2="12" y2="11" />
<circle cx="6" cy="15" r="2" />
<circle cx="18" cy="15" r="2" />
<line x1="12" y1="11" x2="6" y2="13" />
<line x1="12" y1="11" x2="18" y2="13" />
</svg>
</div>
<span className="landing-footer-copy">&copy; 2026 ResolutionFlow</span>
</div>
<ul className="landing-footer-links">
<li><Link to="/privacy">Privacy</Link></li>
<li><Link to="/terms">Terms</Link></li>
<li><Link to="/policies">Policies</Link></li>
<li><Link to="/contact">Contact</Link></li>
</ul>
</div>
</footer>
)
}
export default MarketingFooter

View File

@@ -0,0 +1,88 @@
import { Link } from 'react-router-dom'
import { PageMeta } from '@/components/common/PageMeta'
export default function ContactPage() {
return (
<>
<PageMeta title="Contact" description="Contact ResolutionFlow customer service, sales, billing, or security." />
<div className="min-h-screen bg-background text-foreground">
<div className="mx-auto max-w-3xl px-6 py-16">
<Link to="/landing" className="text-sm text-muted-foreground hover:text-foreground mb-8 inline-block">&larr; Back to home</Link>
<h1 className="text-3xl font-bold font-heading mb-4">Contact ResolutionFlow</h1>
<p className="text-muted-foreground mb-10">
We respond to customer inquiries Monday through Friday during U.S. business hours, excluding federal holidays. Email is the fastest path to a response.
</p>
<div className="space-y-8 text-muted-foreground leading-relaxed">
<section>
<h2 className="text-xl font-semibold text-foreground mb-3">Phone</h2>
<p>
<a href="tel:+14709494131" className="text-primary hover:underline">(470) 949-4131</a>
</p>
<p className="text-sm mt-1">Monday&ndash;Friday, 9:00 AM&ndash;5:00 PM ET, excluding U.S. federal holidays.</p>
</section>
<section>
<h2 className="text-xl font-semibold text-foreground mb-3">Email</h2>
<ul className="space-y-2">
<li>
<strong className="text-foreground">General support:</strong>{' '}
<a href="mailto:support@resolutionflow.com" className="text-primary hover:underline">support@resolutionflow.com</a>
</li>
<li>
<strong className="text-foreground">Sales and Enterprise:</strong>{' '}
<a href="mailto:sales@resolutionflow.com" className="text-primary hover:underline">sales@resolutionflow.com</a>
</li>
<li>
<strong className="text-foreground">Billing and account:</strong>{' '}
<a href="mailto:billing@resolutionflow.com" className="text-primary hover:underline">billing@resolutionflow.com</a>
</li>
<li>
<strong className="text-foreground">Security and privacy:</strong>{' '}
<a href="mailto:security@resolutionflow.com" className="text-primary hover:underline">security@resolutionflow.com</a>
</li>
</ul>
</section>
<section>
<h2 className="text-xl font-semibold text-foreground mb-3">Response times</h2>
<ul className="list-disc list-inside space-y-1">
<li>General support: within one (1) business day</li>
<li>Billing or account access: within one (1) business day</li>
<li>Security disclosures: within twenty-four (24) hours, including weekends</li>
</ul>
</section>
<section>
<h2 className="text-xl font-semibold text-foreground mb-3">Mailing address</h2>
{/* TODO: replace with full mailing address once P.O. Box is set up. */}
<p>
Available on request. Email{' '}
<a href="mailto:support@resolutionflow.com" className="text-primary hover:underline">support@resolutionflow.com</a>{' '}
and we will provide our current mailing address.
</p>
</section>
<section>
<h2 className="text-xl font-semibold text-foreground mb-3">Sales and demos</h2>
<p>
Interested in a guided demo or Enterprise pricing? Use our{' '}
<Link to="/contact-sales" className="text-primary hover:underline">sales contact form</Link>{' '}
to book a time directly.
</p>
</section>
<section>
<h2 className="text-xl font-semibold text-foreground mb-3">Related</h2>
<ul className="list-disc list-inside space-y-1">
<li><Link to="/policies" className="text-primary hover:underline">Customer Policies</Link> &mdash; billing, refunds, cancellation, and promotions</li>
<li><Link to="/terms" className="text-primary hover:underline">Terms of Service</Link></li>
<li><Link to="/privacy" className="text-primary hover:underline">Privacy Policy</Link></li>
</ul>
</section>
</div>
</div>
</div>
</>
)
}

View File

@@ -3,6 +3,7 @@ import { Link } from 'react-router-dom'
import { salesApi, type SalesLeadSource } from '@/api/sales'
import { PageMeta } from '@/components/common/PageMeta'
import { MarketingFooter } from '@/components/common/MarketingFooter'
import { useAppConfig } from '@/hooks/useAppConfig'
import '@/styles/landing.css'
@@ -342,6 +343,8 @@ export function ContactSalesPage() {
</form>
)}
</section>
<MarketingFooter />
</main>
</div>
)

View File

@@ -2,6 +2,7 @@ import { useState, useEffect, useRef } from 'react'
import { Link } from 'react-router-dom'
import { PageMeta } from '@/components/common/PageMeta'
import { useAppConfig } from '@/hooks/useAppConfig'
import { MarketingFooter } from '@/components/common/MarketingFooter'
import '@/styles/landing.css'
const FAQ_ITEMS = [
@@ -410,29 +411,7 @@ export default function LandingPage() {
</div>
</section>
{/* Footer */}
<footer className="landing-footer">
<div className="landing-footer-inner">
<div className="landing-footer-left">
<div className="landing-nav-logo-icon" style={{ width: 24, height: 24, borderRadius: 6 }}>
<svg viewBox="0 0 24 24" fill="none" stroke="#000" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" style={{ width: 14, height: 14 }}>
<circle cx="12" cy="5" r="2" />
<line x1="12" y1="7" x2="12" y2="11" />
<circle cx="6" cy="15" r="2" />
<circle cx="18" cy="15" r="2" />
<line x1="12" y1="11" x2="6" y2="13" />
<line x1="12" y1="11" x2="18" y2="13" />
</svg>
</div>
<span className="landing-footer-copy">&copy; 2026 ResolutionFlow</span>
</div>
<ul className="landing-footer-links">
<li><Link to="/privacy">Privacy</Link></li>
<li><Link to="/terms">Terms</Link></li>
<li><a href="mailto:hello@resolutionflow.com">Contact</a></li>
</ul>
</div>
</footer>
<MarketingFooter />
</main>
</div>
</>

View File

@@ -0,0 +1,194 @@
import { Link } from 'react-router-dom'
import { PageMeta } from '@/components/common/PageMeta'
export default function PoliciesPage() {
return (
<>
<PageMeta title="Customer Policies" description="ResolutionFlow customer service, billing, refunds, cancellation, legal restrictions, and promotional terms." />
<div className="min-h-screen bg-background text-foreground">
<div className="mx-auto max-w-3xl px-6 py-16">
<Link to="/landing" className="text-sm text-muted-foreground hover:text-foreground mb-8 inline-block">&larr; Back to home</Link>
<h1 className="text-3xl font-bold font-heading mb-4">Customer Policies</h1>
<p className="text-muted-foreground mb-2">Last updated: May 7, 2026</p>
<p className="text-muted-foreground mb-2"><strong className="text-foreground">Operator:</strong> ResolutionFlow, LLC (the &ldquo;Company&rdquo;), operator of ResolutionFlow (&ldquo;Service&rdquo;).</p>
<p className="text-muted-foreground mb-8"><strong className="text-foreground">Product:</strong> ResolutionFlow &mdash; a software-as-a-service troubleshooting platform for Managed Service Providers (MSPs).</p>
<p className="text-muted-foreground mb-6 leading-relaxed">
This document consolidates the policies that govern your use of ResolutionFlow, including how to contact us, how billing works, how to cancel, how refunds and disputes are handled, the legal restrictions that apply, and the terms of any promotional offers. It is intended to satisfy the disclosure requirements of our payment processors (including Stripe) and to give customers clear, accessible answers to common billing and account questions.
</p>
<p className="text-muted-foreground mb-10 leading-relaxed">
ResolutionFlow is a digital subscription service. We do not sell or ship physical goods, so a return policy does not apply; the section on refunds below covers all circumstances in which money may be returned.
</p>
<hr className="border-border mb-10" />
<div className="space-y-10 text-muted-foreground leading-relaxed">
{/* Section 1 */}
<section id="contact">
<h2 className="text-xl font-semibold text-foreground mb-3">1. Customer Service Contact</h2>
<p>We respond to customer inquiries during standard business hours, Monday through Friday, excluding U.S. federal holidays. The fastest path to a response is email.</p>
<ul className="mt-3 space-y-1">
<li><strong className="text-foreground">Phone:</strong> <a href="tel:+14709494131" className="text-primary hover:underline">(470) 949-4131</a></li>
<li><strong className="text-foreground">Email (primary channel):</strong> <a href="mailto:support@resolutionflow.com" className="text-primary hover:underline">support@resolutionflow.com</a></li>
<li><strong className="text-foreground">Sales and Enterprise inquiries:</strong> <a href="mailto:sales@resolutionflow.com" className="text-primary hover:underline">sales@resolutionflow.com</a></li>
<li><strong className="text-foreground">Billing and account inquiries:</strong> <a href="mailto:billing@resolutionflow.com" className="text-primary hover:underline">billing@resolutionflow.com</a></li>
<li><strong className="text-foreground">Security and privacy inquiries:</strong> <a href="mailto:security@resolutionflow.com" className="text-primary hover:underline">security@resolutionflow.com</a></li>
</ul>
{/* TODO: replace with full mailing address once P.O. Box is set up. */}
<p className="mt-4"><strong className="text-foreground">Mailing address:</strong> available on request &mdash; email <a href="mailto:support@resolutionflow.com" className="text-primary hover:underline">support@resolutionflow.com</a>.</p>
<p className="mt-2"><strong className="text-foreground">Web contact form:</strong> <Link to="/contact" className="text-primary hover:underline">resolutionflow.com/contact</Link></p>
<p className="mt-4"><strong className="text-foreground">Target response times:</strong></p>
<ul className="list-disc list-inside space-y-1 mt-1">
<li>General support: within one (1) business day</li>
<li>Billing or account access issues: within one (1) business day</li>
<li>Security disclosures: within twenty-four (24) hours, including weekends</li>
</ul>
<p className="mt-3">Customers on the Enterprise plan have additional contact channels and service levels defined in their order form.</p>
</section>
{/* Section 2 */}
<section id="returns">
<h2 className="text-xl font-semibold text-foreground mb-3">2. Return Policy</h2>
<p>ResolutionFlow is a software-as-a-service product delivered electronically. Because no physical goods are sold or shipped, no return policy applies. All refund-related questions are governed by Section 3 (Refund and Dispute Policy) below.</p>
</section>
{/* Section 3 */}
<section id="refunds">
<h2 className="text-xl font-semibold text-foreground mb-3">3. Refund and Dispute Policy</h2>
<h3 className="text-base font-semibold text-foreground mt-4 mb-2">3.1 Subscription model</h3>
<p>ResolutionFlow is sold as a recurring monthly subscription. The Service is billed in advance: the first charge occurs at the end of any free trial period (or immediately if no trial applies), and subsequent charges occur on the same day each month until the subscription is cancelled. There are currently no annual subscription terms; if and when annual terms become available, refund handling for those terms will be specified at the point of sale.</p>
<h3 className="text-base font-semibold text-foreground mt-4 mb-2">3.2 Free trial</h3>
<p>New customers receive a 14-day free trial of the Pro plan. No charge is made during the trial. If the customer does not cancel before the trial ends, the subscription converts automatically to a paid plan at the price disclosed at signup. Cancelling before the trial ends prevents any charge. The trial is intended to be the customer&rsquo;s primary opportunity to evaluate the Service before paying.</p>
<h3 className="text-base font-semibold text-foreground mt-4 mb-2">3.3 Refund policy</h3>
<p><strong className="text-foreground">Monthly subscriptions are non-refundable.</strong> Because the customer can cancel at any time and is never billed for a future period after cancellation, we do not issue refunds for partial months, unused features, or change-of-mind cancellations made after the billing date. This is the standard model for B2B SaaS and is consistent with how the Service is priced and delivered.</p>
<p className="mt-3">We will issue a refund or credit at our discretion in the following circumstances:</p>
<ul className="list-disc list-inside space-y-2 mt-2">
<li><strong className="text-foreground">Duplicate or accidental charge.</strong> If a customer is charged twice for the same billing period, or charged after a verifiable cancellation that we failed to process, we refund the erroneous charge in full.</li>
<li><strong className="text-foreground">Fraudulent charge.</strong> If a customer demonstrates that their payment method was used without authorization, we cooperate with the cardholder and the issuing bank to resolve the dispute and refund or reverse the charge as appropriate.</li>
<li><strong className="text-foreground">Material Service failure.</strong> If the Service is materially unavailable for an extended period due to our fault, we may issue a service credit applied to the next billing cycle. Credits are not paid as cash refunds.</li>
<li><strong className="text-foreground">Annual prepayments (when offered).</strong> If annual prepayment becomes available in the future, the refund terms for those subscriptions will be disclosed at the point of sale.</li>
</ul>
<p className="mt-3">Refunds, where issued, are returned to the original payment method used for the charge. Refund processing typically completes within five (5) to ten (10) business days, depending on the customer&rsquo;s bank or card issuer.</p>
<h3 className="text-base font-semibold text-foreground mt-4 mb-2">3.4 Disputes and chargebacks</h3>
<p>If you believe a charge is incorrect, please contact <a href="mailto:billing@resolutionflow.com" className="text-primary hover:underline">billing@resolutionflow.com</a> <strong className="text-foreground">before</strong> initiating a chargeback with your bank or card issuer. We can almost always resolve billing questions faster than the dispute process and without affecting your account standing.</p>
<p className="mt-3">If a chargeback is filed against an active subscription, the associated account may be suspended pending resolution to prevent further charges. We respond to chargeback inquiries from card networks with the records we maintain, including signup records, billing history, login activity, and product usage. We do not retaliate against customers for filing legitimate disputes; suspensions during a dispute are operational, not punitive.</p>
<p className="mt-3">Customers who repeatedly file chargebacks for charges that they previously authorized and used may be permanently banned from the Service.</p>
<h3 className="text-base font-semibold text-foreground mt-4 mb-2">3.5 Enterprise refunds</h3>
<p>Customers on the Enterprise plan are governed by the refund and dispute terms in their executed order form or master services agreement. Where those terms conflict with this section, the order form or MSA controls.</p>
</section>
{/* Section 4 */}
<section id="cancellation">
<h2 className="text-xl font-semibold text-foreground mb-3">4. Cancellation Policy</h2>
<h3 className="text-base font-semibold text-foreground mt-4 mb-2">4.1 How to cancel</h3>
<p>Customers can cancel their subscription at any time, without contacting support, through one of the following routes:</p>
<ol className="list-decimal list-inside space-y-2 mt-2">
<li><strong className="text-foreground">Account settings &rarr; Billing &rarr; Manage subscription</strong>, which opens the Stripe Customer Portal and allows the customer to cancel directly.</li>
<li><strong className="text-foreground">Email <a href="mailto:billing@resolutionflow.com" className="text-primary hover:underline">billing@resolutionflow.com</a></strong> from the email address on file. We will process the cancellation within one (1) business day and confirm by reply.</li>
</ol>
<p className="mt-3">Customers on the Enterprise plan should follow the cancellation procedure specified in their order form or MSA.</p>
<h3 className="text-base font-semibold text-foreground mt-4 mb-2">4.2 What happens when you cancel</h3>
<ul className="list-disc list-inside space-y-2">
<li><strong className="text-foreground">No future charges.</strong> Your subscription will not renew. The card on file will not be charged again.</li>
<li><strong className="text-foreground">Access continues until the end of the current billing period.</strong> If you cancel mid-month, you retain full access to the Service until the end of the period you have already paid for. We do not lock you out early.</li>
<li><strong className="text-foreground">Trial cancellations.</strong> Cancelling during a free trial ends the trial immediately. No charge is made.</li>
<li><strong className="text-foreground">No partial refunds.</strong> Per Section 3.3, the unused portion of the current billing period is not refunded.</li>
</ul>
<h3 className="text-base font-semibold text-foreground mt-4 mb-2">4.3 What happens to your data</h3>
<p>For a period of thirty (30) days after the end of the current billing period, your account is retained in a read-only state. During this window you can:</p>
<ul className="list-disc list-inside space-y-2 mt-2">
<li>Reactivate the subscription and resume work without any data loss.</li>
<li>Export your sessions, flows, and documentation in any of the supported export formats (Markdown, plain text, HTML, PDF, or PSA-formatted notes).</li>
<li>Request a copy of your data by emailing <a href="mailto:security@resolutionflow.com" className="text-primary hover:underline">security@resolutionflow.com</a>.</li>
</ul>
<p className="mt-3">After thirty (30) days, all customer-generated content is permanently deleted from production systems. Backups are purged within ninety (90) days. Some metadata may be retained as required for tax, legal, or fraud-prevention obligations.</p>
<h3 className="text-base font-semibold text-foreground mt-4 mb-2">4.4 Reactivation</h3>
<p>A cancelled account can be reactivated within the thirty (30) day retention window by signing in and re-subscribing. Beyond that window, the customer can sign up again, but prior data will not be available.</p>
</section>
{/* Section 5 */}
<section id="legal">
<h2 className="text-xl font-semibold text-foreground mb-3">5. Legal and Export Restrictions</h2>
<p>ResolutionFlow is operated from the United States and is subject to U.S. law, including export control and economic sanctions regulations administered by the U.S. Department of the Treasury Office of Foreign Assets Control (&ldquo;OFAC&rdquo;) and the U.S. Department of Commerce Bureau of Industry and Security (&ldquo;BIS&rdquo;).</p>
<h3 className="text-base font-semibold text-foreground mt-4 mb-2">5.1 Eligibility</h3>
<p>By subscribing to or using the Service, you represent and warrant that:</p>
<ul className="list-disc list-inside space-y-2 mt-2">
<li>You are not located in, ordinarily resident in, or organized under the laws of a country or region subject to comprehensive U.S. sanctions (including, as of this date, Cuba, Iran, North Korea, Syria, and the so-called Crimea, Donetsk, and Luhansk regions of Ukraine).</li>
<li>You are not identified on the U.S. Treasury Department&rsquo;s List of Specially Designated Nationals and Blocked Persons (SDN List), the U.S. Commerce Department&rsquo;s Denied Persons List or Entity List, or any other restricted-party list maintained by the U.S. government, the United Nations Security Council, the European Union, or the United Kingdom.</li>
<li>You will not use the Service in violation of any applicable U.S. or foreign export control or sanctions law.</li>
</ul>
<h3 className="text-base font-semibold text-foreground mt-4 mb-2">5.2 Use restrictions</h3>
<p>The Service is intended for general business use by Managed Service Providers and similar IT services organizations. The Service may not be used in connection with:</p>
<ul className="list-disc list-inside space-y-2 mt-2">
<li>The design, development, production, or use of nuclear, chemical, or biological weapons, or missile systems capable of delivering such weapons.</li>
<li>Any application where failure of the Service could reasonably be expected to cause death, personal injury, or severe physical or environmental damage (including life-support systems, primary medical diagnostic systems, nuclear facilities, or air traffic control).</li>
</ul>
<h3 className="text-base font-semibold text-foreground mt-4 mb-2">5.3 Right to refuse service</h3>
<p>We reserve the right to refuse, suspend, or terminate service to any customer where we have a reasonable belief, based on the information available to us, that providing the Service would violate applicable law, sanctions, or our policies. Where service is terminated for compliance reasons, any prepaid amounts are refunded to the extent permitted by law.</p>
<h3 className="text-base font-semibold text-foreground mt-4 mb-2">5.4 Governing law and venue</h3>
<p>These policies are governed by the laws of the State of Georgia, without regard to its conflict-of-laws principles. Any dispute arising out of these policies or your use of the Service will be brought in the state or federal courts located in Cherokee County, Georgia, and you consent to the personal jurisdiction of those courts. This venue clause does not apply where prohibited by mandatory consumer protection law in your jurisdiction.</p>
</section>
{/* Section 6 */}
<section id="promotions">
<h2 className="text-xl font-semibold text-foreground mb-3">6. Promotions: Terms and Conditions</h2>
<p>From time to time we may offer promotional pricing, extended trials, referral credits, free upgrades, or other promotional benefits (&ldquo;Promotions&rdquo;). The following general terms apply to all Promotions, in addition to any specific terms disclosed at the time the Promotion is offered:</p>
<h3 className="text-base font-semibold text-foreground mt-4 mb-2">6.1 General terms</h3>
<ul className="list-disc list-inside space-y-2">
<li>Promotions apply only to the specific accounts, plans, and billing periods identified at the time of the offer.</li>
<li>Promotions cannot be combined with other Promotions unless we expressly state otherwise.</li>
<li>Promotional pricing applies for the period stated in the offer. After that period, the subscription renews at the then-current standard price for the applicable plan unless cancelled.</li>
<li>Promotional credits and discounts have no cash value and are not transferable, refundable, or redeemable for currency.</li>
<li>Customers must be in good standing (no overdue balances, no active chargebacks, no policy violations) to receive or continue receiving a Promotion.</li>
<li>We may modify or discontinue a Promotion at any time, except where doing so would be inconsistent with the terms disclosed at the time the customer accepted the Promotion.</li>
<li>We reserve the right to revoke a Promotion and recover its value if we determine, in good faith, that the customer obtained the Promotion through fraud, duplicate accounts, abuse, or violation of these terms.</li>
</ul>
<h3 className="text-base font-semibold text-foreground mt-4 mb-2">6.2 Active promotions</h3>
<p>A current list of active Promotions, along with their specific terms, is published at <Link to="/promotions" className="text-primary hover:underline">resolutionflow.com/promotions</Link>. Where there is any inconsistency between the general terms above and the specific terms of an individual Promotion, the specific terms control for that Promotion only.</p>
<p className="mt-3">If no Promotions are active, that page will state so.</p>
</section>
{/* Section 7 */}
<section id="changes">
<h2 className="text-xl font-semibold text-foreground mb-3">7. Changes to These Policies</h2>
<p>We may update these policies from time to time. Material changes will be announced by email to the address on file for the account at least fifteen (15) days before they take effect, and the &ldquo;Last updated&rdquo; date at the top of this document will be revised. Continued use of the Service after the effective date of a change constitutes acceptance of the updated policies. Customers who do not accept a material change may cancel under Section 4 before the effective date.</p>
</section>
{/* Section 8 */}
<section id="agreements">
<h2 className="text-xl font-semibold text-foreground mb-3">8. Relationship to Other Agreements</h2>
<p>These policies are part of, and incorporated into, the ResolutionFlow <Link to="/terms" className="text-primary hover:underline">Terms of Service</Link> and the <Link to="/privacy" className="text-primary hover:underline">Privacy Policy</Link>. Where these policies conflict with the Terms of Service or Privacy Policy, the Terms of Service control for matters of contract formation, liability, warranties, and dispute resolution; the Privacy Policy controls for matters of personal data handling; and these policies control for matters of billing, refunds, cancellation, customer service contact, legal restrictions, and Promotions.</p>
<p className="mt-3">For Enterprise customers operating under an executed order form or master services agreement, that agreement controls in the event of any conflict with these policies.</p>
</section>
<hr className="border-border" />
<p className="text-sm italic">
Questions about these policies? Email{' '}
<a href="mailto:billing@resolutionflow.com" className="text-primary hover:underline">billing@resolutionflow.com</a>{' '}
or use the contact form at{' '}
<Link to="/contact" className="text-primary hover:underline">resolutionflow.com/contact</Link>.
</p>
</div>
</div>
</div>
</>
)
}

View File

@@ -3,6 +3,7 @@ import { Link } from 'react-router-dom'
import { plansApi, type PublicPlanResponse } from '@/api/plans'
import { PageMeta } from '@/components/common/PageMeta'
import { MarketingFooter } from '@/components/common/MarketingFooter'
import { useAppConfig } from '@/hooks/useAppConfig'
import '@/styles/landing.css'
@@ -431,6 +432,8 @@ export function PricingPage() {
>
Built on Stripe + AWS · Encrypted in transit and at rest
</section>
<MarketingFooter />
</main>
</div>
)

View File

@@ -34,7 +34,7 @@ export default function PrivacyPage() {
<section>
<h2 className="text-xl font-semibold text-foreground mb-3">5. Contact</h2>
<p>Questions about this policy? Email us at <a href="mailto:hello@resolutionflow.com" className="text-primary hover:underline">hello@resolutionflow.com</a>.</p>
<p>Questions about this policy? Email <a href="mailto:security@resolutionflow.com" className="text-primary hover:underline">security@resolutionflow.com</a> or visit our <Link to="/contact" className="text-primary hover:underline">contact page</Link>. Billing, cancellation, refund, and promotional terms are governed by our <Link to="/policies" className="text-primary hover:underline">Customer Policies</Link>.</p>
</section>
</div>
</div>

View File

@@ -0,0 +1,37 @@
import { Link } from 'react-router-dom'
import { PageMeta } from '@/components/common/PageMeta'
export default function PromotionsPage() {
return (
<>
<PageMeta title="Promotions" description="Active ResolutionFlow promotional offers and their terms." />
<div className="min-h-screen bg-background text-foreground">
<div className="mx-auto max-w-3xl px-6 py-16">
<Link to="/landing" className="text-sm text-muted-foreground hover:text-foreground mb-8 inline-block">&larr; Back to home</Link>
<h1 className="text-3xl font-bold font-heading mb-4">Promotions</h1>
<p className="text-muted-foreground mb-10">Last updated: May 7, 2026</p>
<div className="space-y-6 text-muted-foreground leading-relaxed">
<section>
<h2 className="text-xl font-semibold text-foreground mb-3">Current promotions</h2>
<p>No promotions are currently active.</p>
<p className="mt-3">
Promotional offers, when running, will be listed on this page with their specific terms (eligible plans, duration, redemption rules, expiration). The general terms that apply to all promotions are described in{' '}
<Link to="/policies" className="text-primary hover:underline">Section 6 of our Customer Policies</Link>.
</p>
</section>
<section>
<h2 className="text-xl font-semibold text-foreground mb-3">Questions</h2>
<p>
Email{' '}
<a href="mailto:billing@resolutionflow.com" className="text-primary hover:underline">billing@resolutionflow.com</a>{' '}
for questions about a promotion you received by email, or to ask about upcoming offers.
</p>
</section>
</div>
</div>
</div>
</>
)
}

View File

@@ -39,7 +39,7 @@ export default function TermsPage() {
<section>
<h2 className="text-xl font-semibold text-foreground mb-3">6. Contact</h2>
<p>Questions about these terms? Email us at <a href="mailto:hello@resolutionflow.com" className="text-primary hover:underline">hello@resolutionflow.com</a>.</p>
<p>Questions about these terms? Email <a href="mailto:support@resolutionflow.com" className="text-primary hover:underline">support@resolutionflow.com</a> or visit our <Link to="/contact" className="text-primary hover:underline">contact page</Link>. Billing, cancellation, refund, and promotional terms are governed by our <Link to="/policies" className="text-primary hover:underline">Customer Policies</Link>.</p>
</section>
</div>
</div>

View File

@@ -24,6 +24,9 @@ const PrivacyPage = lazyWithRetry(() => import('@/pages/PrivacyPage'))
const TermsPage = lazyWithRetry(() => import('@/pages/TermsPage'))
const PricingPage = lazyWithRetry(() => import('@/pages/PricingPage'))
const ContactSalesPage = lazyWithRetry(() => import('@/pages/ContactSalesPage'))
const ContactPage = lazyWithRetry(() => import('@/pages/ContactPage'))
const PoliciesPage = lazyWithRetry(() => import('@/pages/PoliciesPage'))
const PromotionsPage = lazyWithRetry(() => import('@/pages/PromotionsPage'))
// Standalone auth pages
const VerifyEmailPage = lazyWithRetry(() => import('@/pages/VerifyEmailPage'))
@@ -145,6 +148,21 @@ export const router = sentryCreateBrowserRouter([
element: page(ContactSalesPage),
errorElement: <RouteError />,
},
{
path: '/contact',
element: page(ContactPage),
errorElement: <RouteError />,
},
{
path: '/policies',
element: page(PoliciesPage),
errorElement: <RouteError />,
},
{
path: '/promotions',
element: page(PromotionsPage),
errorElement: <RouteError />,
},
{
path: '/login',
element: <LoginPage />,