Introduction
Hi, I'm Awoyemi Abiola, and this is my case study for the week 5 task of the Rise Academy Frontend track project - LovedIn, In this Case study, we'll cover what love challenges this project solves, who it solves it for, solution and UI design, technical structure and architecture of the project with HTML and CSS, and finally an overall reflection on collaboration and areas to improve. Let's dive in.
Problem Statement
In today's fast-paced digital world, expressing romantic interest has become increasingly complex and anxiety-inducing. Many individuals struggle with:
- Finding the right words: The pressure of crafting the perfect romantic proposal or expression of interest often leads to missed opportunities or awkward encounters. People spend hours overthinking what to say, how to say it, and when to say it, which can result in never saying anything at all.
- Personalization challenges: Generic romantic gestures often fail to capture the unique connection between two people, making them feel impersonal or insincere. A simple "Will you be my girlfriend/boyfriend?" text message doesn't convey the depth of thought and care that went into the decision.
- Lack of memorable format: Traditional text messages or social media DMs lack the special, memorable quality that important relationship milestones deserve. These moments should be cherished and remembered, not lost in a sea of chat history.
- LovedIn addresses these challenges by providing a structured, thoughtful, and personalized platform that takes the stress out of romantic proposals while maintaining authenticity and sincerity. It gives users the tools to express their feelings in a beautiful, memorable way.
The Primary target audience for LovedIn is a demographic of tech-comfortable young adults (18-35 years old) familiar with online dating culture and value creative and thoughtful expressions of affection.
Solution Design
To solve this problem, we designed a multi-page proposal website with:
- Interactive Landing Page Experience
- Personalized Information Collection via a form
- An auto-generated and customized Proposal page
This flow was chosen to maintain a sense of emotional connection throughout the proposal creation process. Our users would not just be filling a form and getting a link but be crafting a thoughtful and romantic experience for their prospective partners.
UI Design System
Colors
The colour palette leans into romantic and affectionate tones. We aimed to create a visual mood that feels warm, gentle, and emotionally inviting. These colours were chosen to reflect love, softness, and intimacy without feeling loud or overwhelming.
- Primary: #E22B3B [Scarlet Blush]
- Secondary: #ED4779 [Wild Strawberry]
- Accent: #FA88BB [Petal Frost]
- Background: #F0D1D7 [Pink Carnation]
- Support: #D86A77 [Blush Rose]
Typography
For fonts we sought after a font that was both expressive and somewhat simple, to balance romance with clarity and ensure emotional expression without sacrificing readability. After deliberation, we decided on Playfair Display for headings and Inter for body text.
HTML & Structural Approach
The website was built using semantic HTML to improve accessibility and SEO.
Key Semantic Elements Used
-
<header>for navigation and hero section -
<main>for primary content -
<section>for logical grouping -
<footer>for closing content -
<aside>for separate content
CSS Architecture
CSS Variables
To ensure consistency, I used CSS custom properties for colors, fonts, spacing values and transitions in a base css file shared across all pages in the application:
:root {
/* ========== COLORS ========== */
/* Primary Colors */
--color-primary: #e22b3b;
--color-primary-bg: #f0d1d7;
/* Secondary Colors */
--color-secondary: #ed4779;
--color-secondary-bg: #fff6f8;
/* Accent Colors */
--color-accent: #fa88bb;
/* Support Colors */
--color-support: #d86a77;
/* Neutral Colors */
--color-white: #ffffff;
--color-gray-50: #f9fafb;
--color-gray-100: #f3f4f6;
--color-gray-200: #e5e7eb;
--color-gray-300: #d1d5db;
--color-gray-400: #9ca3af;
--color-gray-500: #6b7280;
--color-gray-600: #4b5563;
--color-gray-700: #374151;
--color-gray-800: #1f2937;
--color-gray-900: #111827;
--color-black: #000000;
/* ========== TYPOGRAPHY ========== */
/* Font Families */
--font-display: "Playfair Display", serif;
--font-body: "Inter", sans-serif;
/* Base Font Size */
--font-size-base: 16px;
/* Font Sizes - Type Scale */
--font-size-xs: 0.75rem; /* 12px */
--font-size-sm: 0.875rem; /* 14px */
--font-size-md: 1rem; /* 16px */
--font-size-lg: 1.125rem; /* 18px */
--font-size-xl: 1.25rem; /* 20px */
--font-size-2xl: 1.5rem; /* 24px */
--font-size-3xl: 1.875rem; /* 30px */
--font-size-4xl: 2.25rem; /* 36px */
--font-size-5xl: 3rem; /* 48px */
--font-size-6xl: 3.75rem; /* 60px */
--font-size-7xl: 4.5rem; /* 72px */
/* Heading Scales */
--heading-h1: var(--font-size-5xl);
--heading-h2: var(--font-size-4xl);
--heading-h3: var(--font-size-3xl);
--heading-h4: var(--font-size-2xl);
--heading-h5: var(--font-size-xl);
--heading-h6: var(--font-size-lg);
/* Font Weights */
--font-weight-normal: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
--font-weight-extrabold: 800;
/* Line Heights */
--line-height-tight: 1.25;
--line-height-normal: 1.5;
--line-height-relaxed: 1.75;
/* ========== SPACING & SHAPES ========== */
/* Spacing Scale - Padding/Margin */
--spacing-xs: 0.25rem; /* 4px */
--spacing-sm: 0.5rem; /* 8px */
--spacing-md: 1rem; /* 16px */
--spacing-lg: 1.5rem; /* 24px */
--spacing-xl: 2rem; /* 32px */
--spacing-2xl: 2.5rem; /* 40px */
--spacing-3xl: 3rem; /* 48px */
--spacing-4xl: 4rem; /* 64px */
--spacing-5xl: 5rem; /* 80px */
--spacing-6xl: 6rem; /* 96px */
/* Border Radius */
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 12px;
--radius-xl: 16px;
--radius-2xl: 20px;
--radius-full: 9999px;
/* Border Widths */
--border-width-thin: 1px;
--border-width-medium: 2px;
--border-width-thick: 4px;
/* ========== SHADOWS ========== */
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
--shadow-2xl: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
--shadow-colored: 0 6px 20px rgba(226, 43, 59, 0.25);
--shadow-subtle: 0 0 0 3px rgba(226, 43, 59, 0.15);
/* ========== TRANSITIONS ========== */
--transition-fast: 150ms ease-in-out;
--transition-base: 250ms ease-in-out;
--transition-slow: 350ms ease-in-out;
/* ========== LINEAR GRADIENTS ========== */
--gradient-primary: linear-gradient(
135deg,
var(--color-primary-bg),
var(--color-secondary-bg)
);
--gradient-secondary: linear-gradient(
135deg,
var(--color-secondary-bg),
var(--color-primary-bg)
);
--gradient-transparent: linear-gradient(
rgba(255, 192, 203, 0.6),
rgba(255, 182, 193, 0.6)
);
}
This approach ensured consistency and cohesiveness for shared elements on the website, reducing repetition as much as possible.
Flex display was used across the application for a consistent layout and seamless responsiveness
display: flex;
align-items: center;
justify-content: space-between;
A particularly challenging component was the navigation bar. My initial implementation for the navbar was not in tune with semantic standards, or a non-repetitive HTML structure. This was fixed and improved to take all these into consideration, keeping all links as direct descendants of the nav element.
<div class="navigation">
<a href="index.html" class="logo">
<img src="assets/images/logo.png" alt="LovedIn logo" width="200" />
</a>
<nav id="nav-links-container" aria-label="Main navigation">
<a href="#features" class="navlink">Features</a>
<a href="stories.html" class="navlink">Stories</a>
<a href="login.html" class="btn btn-primary auth-btn navlink"
>Sign In</a
>
<a href="index.html#get-started" class="btn btn-primary navlink"
>Get Started</a
>
</nav>
</div>
.navigation {
max-width: 1144px;
margin: 0 auto var(--spacing-3xl);
background: var(--color-secondary-bg);
border-radius: var(--radius-full);
padding: var(--spacing-md) var(--spacing-lg);
display: flex;
align-items: center;
justify-content: space-between;
box-shadow: var(--shadow-md);
}
#nav-links-container {
display: flex;
align-items: center;
gap: var(--spacing-3xl);
}
Visuals
Responsiveness
JavaScript Implementation
Our application's interactivity is powered by three vanilla ES6+ JavaScript files app.js, proposal.js, and stories.js each scoped to a specific page with no external libraries or frameworks.
app.js Home Page Logic
Handles the landing page's proposal form and hamburger navigation menu.
Proposal Form Submission
Captures the partner's name and relationship type, validates both fields, then redirects to proposal.html with the values encoded as URL query parameters. Incomplete submissions trigger an alert.
Modal & Sharing
After a valid URL is generated, a modal offers two options: share via the Web Share API (with a clipboard fallback) or preview the proposal. The modal can be closed by clicking outside it, pressing Escape, or using the close button.
Hamburger Menu
Toggles an active class on the nav container to show/hide links on mobile. Updates aria-expanded for accessibility. The menu closes automatically when a link is clicked or the user taps outside the nav.
proposal.js Proposal Page Logic
Powers the interactive experience recipients see when they open a shared proposal link.
URL Parameter Parsing
Reads name and type query parameters via URLSearchParams and dynamically updates the proposal heading (e.g. "Will you be my girlfriend, Sarah") if both values are present.
Yes / No Interaction
- Yes hides the proposal state and reveals a celebratory success message.
-
No deliberately unclikable; moves to a random screen position on
mouseenterortouchstart, making it playfully impossible to select.
Keyboard & Navigation
Escape navigates back to the previous page. A Back Home button in the success state redirects to the landing page.
stories.js Stories Page Logic
Dynamically renders the stories page from a local data array, simulating a backend data layer.
Mock Data
Stories are stored as an array of objects, each containing couple names, location, image URL, alt text, a quote, and a date.
DOM Rendering
On page load, the script iterates over the stories array and creates an <article> element for each entry using template literals, then appends it to the stories grid. No story content is hardcoded in the HTML.
Logic Flow
| Journey | Steps |
|---|---|
| Proposal Creation | User fills form, app.js validates builds URL with query params, modal opens, user shares or previews |
| Proposal Experience | Recipient opens link, proposal.js parses params, heading personalised Yes reveals success state; No escapes cursor |
| Stories Page | Page loads,stories.js reads local array iterates stories, injects article cards into DOM |
Edge Case Handling
| Edge Case | Handling |
|---|---|
| Empty form submission | Alert shown; form not submitted |
| Missing URL parameters | Heading update skipped; default placeholder shown |
| Web Share API unavailable | Falls back to clipboard copy; uses native prompt as last resort |
| Modal elements not present | All modal logic guarded with null checks |
| Stories grid not found | Checks for grid container before populating |
| No button on touch devices | Evasion triggered on both mouseenter and touchstart
|
Reflection
Overall, this was a very interesting project for me, I learnt a lot about collaboration with Git and Github, and even more about standards for writing semantic HTML, and structured design systems with CSS.
That said, collaboration did not come without its challenges, particularly around maintaining a standardized approach to implementing features and pages on the application due to differing perspectives for each collaborator, we were able to overcome this via clear and concise discussions and meetings before and throughout the task delivery processes, where I properly communicated to my partner, and her to me, clear and concise requirements for each week's task.
In a version 2.0, I would work towards improving semantics and optimizing SEO and accessibility for the project to near perfection, as these are the areas we received feedback for improvement.
Contributors
This project was developed collaboratively with;
- Oluchi Okwuosa – GitHub
You can view their version of this case study here
Special thanks to Sophia Ahuoyiza - Github for issue submissions and feedback which helped greatly improve this project.










Top comments (0)