Add pricing page and update meal card interactions
- Introduced a new pricing page with mode-specific pricing options. - Updated meal card data attributes and descriptions for clarity. - Enhanced meal card interactions to navigate to the pricing page. - Removed toast notifications for a cleaner user experience. - Added pricing styles for better layout and responsiveness.
This commit is contained in:
parent
3f6d7bd638
commit
6c756ac7ba
6 changed files with 130 additions and 20 deletions
12
README.md
12
README.md
|
|
@ -5,7 +5,7 @@ Hyper-futuristic landing page for a goal-oriented food and tiffin service.
|
|||
The Tiffin Food helps people choose meals based on the body and lifestyle they are working toward:
|
||||
|
||||
- **Lean mode** — minimal-fat meals for a lighter, sharper routine
|
||||
- **Muscle mode** — protein-focused meals to support strength and training
|
||||
- **Protein mode** — protein-focused meals to support strength and training
|
||||
- **Bulk mode** — carbohydrate and protein-focused meals for intentional gains
|
||||
- **Balanced mode** — a balanced mix of nutrients for sustainable everyday eating
|
||||
|
||||
|
|
@ -16,9 +16,10 @@ The page combines a dark editorial interface with neon lime accents, orbital mot
|
|||
- Hero section with an orbital meal visual
|
||||
- Responsive navigation and calls to action
|
||||
- Animated principles marquee
|
||||
- Four interactive meal goal cards
|
||||
- Four interactive meal goal cards that open a mode-specific pricing page
|
||||
- Monthly pricing for breakfast/lunch/dinner, lunch/dinner, and dinner plans
|
||||
- Hover and keyboard focus states for meal cards
|
||||
- Accessible selection feedback through a live toast message
|
||||
- Accessible keyboard and click navigation from each meal goal card
|
||||
- “The Tiffin Protocol” section explaining the ordering flow
|
||||
- Responsive layouts for desktop, tablet, and mobile screens
|
||||
|
||||
|
|
@ -28,7 +29,10 @@ The page combines a dark editorial interface with neon lime accents, orbital mot
|
|||
.
|
||||
├── index.html # Page structure and content
|
||||
├── styles.css # Visual system, responsive layout, and image treatment
|
||||
├── script.js # Meal card interactions and toast feedback
|
||||
├── script.js # Meal card navigation
|
||||
├── pricing.html # Mode-specific pricing page
|
||||
├── pricing.css # Pricing page layout and responsive styles
|
||||
├── pricing.js # Pricing data and plan rendering
|
||||
└── README.md # Project documentation
|
||||
```
|
||||
|
||||
|
|
|
|||
11
index.html
11
index.html
|
|
@ -62,22 +62,22 @@
|
|||
<p>Every body has a different brief. Pick the one that sounds like your next chapter.</p>
|
||||
</div>
|
||||
<div class="meal-grid">
|
||||
<article class="meal-card card-lime" data-goal="Lean" tabindex="0">
|
||||
<article class="meal-card card-lime" data-goal="Lean" data-mode="lean" tabindex="0">
|
||||
<div class="card-number">01</div>
|
||||
<div class="food-orb orb-lime"><img src="https://images.unsplash.com/photo-1512621776951-a57141f2eefd?auto=format&fit=crop&w=700&q=88" alt="Fresh salad bowl with vegetables and grains" /><span>LOW<br />FAT</span></div>
|
||||
<div class="card-content"><p class="card-tag">The cut</p><h3>Lean<br />mode</h3><p>Minimal fats. Maximum clarity. Light, clean meals to help you move sharper.</p><button class="card-action" type="button">Explore meal <span>↗</span></button></div>
|
||||
</article>
|
||||
<article class="meal-card card-orange" data-goal="Muscle" tabindex="0">
|
||||
<article class="meal-card card-orange" data-goal="Protein" data-mode="protein" tabindex="0">
|
||||
<div class="card-number">02</div>
|
||||
<div class="food-orb orb-orange"><img src="https://images.unsplash.com/photo-1532550907401-a500c9a57435?auto=format&fit=crop&w=700&q=88" alt="High protein chicken and vegetables meal" /><span>HIGH<br />PROTEIN</span></div>
|
||||
<div class="card-content"><p class="card-tag">The build</p><h3>Muscle<br />mode</h3><p>Pure protein power for the work you put in, from first rep to last.</p><button class="card-action" type="button">Explore meal <span>↗</span></button></div>
|
||||
<div class="card-content"><p class="card-tag">The build</p><h3>Protein<br />mode</h3><p>Pure protein power for the work you put in, from first rep to last.</p><button class="card-action" type="button">Explore meal <span>↗</span></button></div>
|
||||
</article>
|
||||
<article class="meal-card card-violet" data-goal="Bulk" tabindex="0">
|
||||
<article class="meal-card card-violet" data-goal="Bulk" data-mode="bulk" tabindex="0">
|
||||
<div class="card-number">03</div>
|
||||
<div class="food-orb orb-violet"><img src="https://images.unsplash.com/photo-1515003197210-e0cd71810b5f?auto=format&fit=crop&w=700&q=88" alt="Colorful rice, vegetables and protein meal" /><span>CARBS +<br />PROTEIN</span></div>
|
||||
<div class="card-content"><p class="card-tag">The gain</p><h3>Bulk<br />mode</h3><p>Intentional calories, complex carbs and protein in a bigger, bolder box.</p><button class="card-action" type="button">Explore meal <span>↗</span></button></div>
|
||||
</article>
|
||||
<article class="meal-card card-blue" data-goal="Balance" tabindex="0">
|
||||
<article class="meal-card card-blue" data-goal="Balanced" data-mode="balanced" tabindex="0">
|
||||
<div class="card-number">04</div>
|
||||
<div class="food-orb orb-blue"><img src="https://images.unsplash.com/photo-1543352634-a1c51d9f1fa7?auto=format&fit=crop&w=700&q=88" alt="Balanced meal with vegetables, grains and protein" /><span>ALL-ROUND<br />GOOD</span></div>
|
||||
<div class="card-content"><p class="card-tag">The flow</p><h3>Balanced<br />mode</h3><p>A little bit of everything, dialed into a rhythm you can actually keep.</p><button class="card-action" type="button">Explore meal <span>↗</span></button></div>
|
||||
|
|
@ -99,7 +99,6 @@
|
|||
</main>
|
||||
|
||||
<footer><a class="brand" href="#"><span class="brand-mark"><i></i><i></i><i></i></span><span>THE TIFFIN<br /><b>FOOD</b></span></a><p>© 2024 The Tiffin Food / Made for your next.</p></footer>
|
||||
<div class="toast" role="status" aria-live="polite"></div>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
17
pricing.css
Normal file
17
pricing.css
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
.pricing-page{max-width:1180px;margin:0 auto;padding:54px 50px 120px}
|
||||
.back-link{color:var(--muted);font:500 11px "DM Mono",monospace;letter-spacing:.08em;text-transform:uppercase}
|
||||
.back-link:hover{color:var(--lime)}
|
||||
.pricing-intro{padding:90px 0 70px;max-width:700px}
|
||||
.pricing-intro h1{font-size:clamp(64px,10vw,140px);line-height:.88;letter-spacing:-.08em;margin:18px 0 28px}
|
||||
.pricing-intro>p:last-child{color:var(--muted);font-size:18px;max-width:460px}
|
||||
.pricing-grid h2{font:500 12px "DM Mono",monospace;letter-spacing:.12em;text-transform:uppercase;border-bottom:1px solid var(--line);padding-bottom:18px}
|
||||
.pricing-options{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-top:18px}
|
||||
.price-card{min-height:310px;border:1px solid var(--line);padding:26px;display:flex;flex-direction:column;justify-content:space-between;transition:border-color .25s,transform .25s}
|
||||
.price-card:hover{border-color:var(--lime);transform:translateY(-5px)}
|
||||
.price-index{color:var(--lime);font:500 11px "DM Mono",monospace}
|
||||
.price-card h3{font-size:25px;line-height:1.05;max-width:180px;margin:28px 0 8px}
|
||||
.price-card p:last-child{color:var(--muted);font:12px "DM Mono",monospace}
|
||||
.price-card strong{font-size:40px;letter-spacing:-.05em;margin:28px 0}
|
||||
.price-card strong span{color:var(--muted);font:12px "DM Mono",monospace;letter-spacing:0;margin-left:8px}
|
||||
.price-card .button{align-self:flex-start}
|
||||
@media(max-width:760px){.pricing-page{padding:38px 20px 80px}.pricing-intro{padding:70px 0 52px}.pricing-options{grid-template-columns:1fr}.price-card{min-height:260px}}
|
||||
41
pricing.html
Normal file
41
pricing.html
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="theme-color" content="#090b12" />
|
||||
<title>Choose your rhythm — The Tiffin Food</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=DM+Mono:wght@400;500&family=Space+Grotesk:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
<link rel="stylesheet" href="pricing.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="noise"></div>
|
||||
<header class="site-header">
|
||||
<a class="brand" href="index.html" aria-label="The Tiffin Food home">
|
||||
<span class="brand-mark"><i></i><i></i><i></i></span>
|
||||
<span>THE TIFFIN<br /><b>FOOD</b></span>
|
||||
</a>
|
||||
<a class="header-cta" href="index.html#menu">Change your goal <span>↗</span></a>
|
||||
</header>
|
||||
|
||||
<main class="pricing-page">
|
||||
<a class="back-link" href="index.html#menu">← Back to directions</a>
|
||||
<section class="pricing-intro">
|
||||
<p class="eyebrow">05 / Set your frequency</p>
|
||||
<h1><span id="mode-title">Your</span><br /><em>rhythm.</em></h1>
|
||||
<p id="mode-description">Fresh meals, prepared around the way you want to show up.</p>
|
||||
</section>
|
||||
|
||||
<section class="pricing-grid" aria-labelledby="pricing-heading">
|
||||
<h2 id="pricing-heading">Choose your box</h2>
|
||||
<div id="pricing-options" class="pricing-options"></div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer><a class="brand" href="index.html"><span class="brand-mark"><i></i><i></i><i></i></span><span>THE TIFFIN<br /><b>FOOD</b></span></a><p>© 2024 The Tiffin Food / Made for your next.</p></footer>
|
||||
<script src="pricing.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
48
pricing.js
Normal file
48
pricing.js
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
const pricing = {
|
||||
balanced: {
|
||||
name: "Balanced",
|
||||
description: "A little bit of everything, dialed into a rhythm you can actually keep.",
|
||||
prices: [5000, 4000, 2000],
|
||||
},
|
||||
bulk: {
|
||||
name: "Bulk",
|
||||
description: "Intentional calories, complex carbs and protein in a bigger, bolder box.",
|
||||
prices: [6000, 5000, 2500],
|
||||
},
|
||||
protein: {
|
||||
name: "Protein",
|
||||
description: "Pure protein power for the work you put in, from first rep to last.",
|
||||
prices: [6500, 5500, 3000],
|
||||
},
|
||||
lean: {
|
||||
name: "Lean",
|
||||
description: "Minimal fats. Maximum clarity. Light, clean meals to help you move sharper.",
|
||||
prices: [7000, 6000, 3500],
|
||||
},
|
||||
};
|
||||
|
||||
const options = [
|
||||
{ label: "Breakfast, lunch & dinner", detail: "3 meals a day" },
|
||||
{ label: "Lunch & dinner", detail: "2 meals a day" },
|
||||
{ label: "Dinner", detail: "1 meal a day" },
|
||||
];
|
||||
|
||||
const mode = new URLSearchParams(window.location.search).get("mode") || "balanced";
|
||||
const selected = pricing[mode] || pricing.balanced;
|
||||
|
||||
document.title = `${selected.name} mode pricing — The Tiffin Food`;
|
||||
document.querySelector("#mode-title").textContent = `${selected.name} mode`;
|
||||
document.querySelector("#mode-description").textContent = selected.description;
|
||||
document.querySelector("#pricing-options").innerHTML = options
|
||||
.map((option, index) => `
|
||||
<article class="price-card">
|
||||
<div>
|
||||
<p class="price-index">0${index + 1}</p>
|
||||
<h3>${option.label}</h3>
|
||||
<p>${option.detail}</p>
|
||||
</div>
|
||||
<strong>₹${selected.prices[index].toLocaleString("en-IN")}<span>/ month</span></strong>
|
||||
<a class="button button-primary" href="mailto:hello@thetiffinfood.com?subject=${encodeURIComponent(`${selected.name} mode — ${option.label}`)}">Choose this box <span>↗</span></a>
|
||||
</article>
|
||||
`)
|
||||
.join("");
|
||||
21
script.js
21
script.js
|
|
@ -1,17 +1,18 @@
|
|||
const toast = document.querySelector(".toast");
|
||||
const showToast = (goal) => {
|
||||
toast.textContent = `${goal} mode selected — your box is almost ready.`;
|
||||
toast.classList.add("show");
|
||||
window.setTimeout(() => toast.classList.remove("show"), 3200);
|
||||
};
|
||||
|
||||
document.querySelectorAll(".meal-card").forEach((card) => {
|
||||
const action = card.querySelector(".card-action");
|
||||
action.addEventListener("click", () => showToast(card.dataset.goal));
|
||||
const openPricing = () => {
|
||||
window.location.href = `pricing.html?mode=${encodeURIComponent(card.dataset.mode)}`;
|
||||
};
|
||||
|
||||
card.querySelector(".card-action").addEventListener("click", openPricing);
|
||||
card.addEventListener("click", (event) => {
|
||||
if (event.target.closest(".card-action")) return;
|
||||
openPricing();
|
||||
});
|
||||
|
||||
card.addEventListener("keydown", (event) => {
|
||||
if ((event.key === "Enter" || event.key === " ") && event.target === card) {
|
||||
event.preventDefault();
|
||||
showToast(card.dataset.goal);
|
||||
openPricing();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue