PRAYOMSH CARPOOL is a production-ready, real-time carpooling web application. Its tagline is “Share the Ride. Split the Cost. Travel Smarter.” and its footer reads © 2026 PRAYOMSH. All rights reserved.
The product exists so that everyday commuters can find and share car journeys: a Driver offers available car seats on a published route, and a Passenger searches matching rides and requests a seat. The whole promise of the product is that a number — seats available — is always true, and that a stranger is verified. The system must be a real functional product, not a static or demo website: it uses a real database, a secure backend, authentication, realtime updates, and a responsive premium UI, with no fake hardcoded production data.
The audience is everyday Indian commuters on mobile plus drivers managing seat inventory — practical, price-aware, and slightly anxious about safety and reliability. The interface must therefore read as trustworthy, fast, and warm rather than corporate-neutral.
PRAYOMSH CARPOOL is a web application with three active human roles — Driver, Passenger, and Admin — where one user can be both Driver and Passenger. Drivers publish rides with pickup, drop, date, time, car model/type, and available passenger seats. Passengers search for rides by from, to, date, time, and seats required, apply filters and sorting, and request a seat. The backend owns the seat count absolutely: seat allocation happens inside an atomic database transaction with locking, so that when only one seat remains and two passengers book simultaneously, only one succeeds.
Rides carry the statuses ACTIVE / FULL / CANCELLED / COMPLETED / EXPIRED. When seats reach 0 the ride automatically becomes FULL, disappears from passenger search, disables booking, and remains in the database with its history preserved. Past rides expire automatically. Seat availability updates without refresh over WebSockets/Supabase Realtime — never faked with timers.
The product also covers authentication and profile (registration, login/logout, password reset, email verification, mobile/OTP verification), privacy (driver phone numbers never publicly exposed; contact details revealed only after approval, masked where required), notifications (in-app required; Email/WhatsApp/SMS optional), ratings and reviews after completed rides, search filters and sorting, safety (report, block, help/emergency), and a secure RBAC admin panel with platform statistics.
Current delivery. Everything described in this document is current: the public landing entry, self-service enrollment and returning verification, driver ride publishing, passenger search and booking, both dashboards, profile, reviews, safety, and the RBAC admin panel. All of it is first-party application surface backed by a first-party secure backend and a PostgreSQL + PostGIS database.
Identity and access ownership. The application owns identity. Drivers, Passengers, and Admins establish their own accounts through self-service enrollment, then verify themselves on return. Protected ride, booking, profile, review, safety, and administrative work is reachable only after identity is established; the anonymous entry surfaces (Landing, Sign Up, Login, Account Recovery) are reachable without identity. Administrative capability is governed by RBAC, provisioned rather than self-selected.
Provider and external ownership. Map rendering and location autocomplete are owned by the chosen map provider (Google Maps, Mapbox, or OpenStreetMap) and are embedded, not reimplemented. Email, WhatsApp, and SMS notification delivery are optional external channels; in-app notification is the required channel and is application-owned. Realtime transport is provided by WebSockets or Supabase Realtime; the authoritative seat state remains application-owned in PostgreSQL.
Explicit exclusions and non-current items. No fake hardcoded production data. No timer-based fake realtime. No public exposure of driver personal phone numbers or of passwords, tokens, hashes, or private contact information through public APIs. No blue or indigo anywhere in the interface. No stock photography of people, no decorative illustration, no gradient-blob or glassmorphism treatment. Nothing in this document is deferred to a future horizon; there is no accepted future-phase requirement in the source.
Not applicable — no reference directive in this project declares a content_source.
Each requirement is a distinct story point with provenance, lifecycle facts, and observable acceptance.
FR-1 — Product identity and footer. As a visitor I should see the product named PRAYOMSH CARPOOL with the tagline “Share the Ride. Split the Cost. Travel Smarter.” and the footer © 2026 PRAYOMSH. All rights reserved., so that I know what the product is and who owns it. Provenance: explicit. Trigger: any page render. Observable result: the wordmark, tagline, and footer text are present. Failure/recovery: none material. Continuation: the visitor proceeds to Find a Ride or Offer a Ride.
FR-2 — Real functional product. As a user I should use a real product backed by a real database, secure backend, authentication, realtime updates, and a responsive premium UI, so that my rides and bookings are real. Provenance: explicit. Constraint: no fake hardcoded production data. Observable result: all ride, booking, review, and user data is persisted and retrieved from the database. Failure/recovery: database unavailability surfaces an error rather than fabricated data.
FR-3 — Dual roles. As a user I should act as a Driver who offers available car seats and as a Passenger who searches and requests rides, so that one account can do both. Provenance: explicit. Observable result: the same account can publish rides and request seats on other rides. Constraint: a passenger must not be the driver on their own booking.
FR-4 — Offer a Ride. As a Driver I should create an Offer a Ride with Name, Mobile, Email, Pickup, Drop, Date, Time, Car model/type, and Available passenger seats, so that passengers can find my journey. Provenance: explicit. Trigger: driver opens Offer a Ride. Observable result: the ride is published with status ACTIVE. Failure/recovery: invalid date, invalid location, or invalid seats produce accessible errors and no ride is created. Continuation: the ride appears in the Driver Dashboard.
FR-5 — Seat selector. As a Driver I should set available passenger seats with a − 1 + control, so that the offered seat count is exact. Provenance: explicit. Example: 4 seats → booking → 3 → 2 → 1 → 0. Observable result: the stepper value is the ride's total seat count at publish time.
FR-6 — Automatic FULL at zero. As the system I should automatically set a ride to FULL when seats reach 0, so that no further booking is possible. Provenance: explicit. Observable result: status becomes FULL. Constraint: FULL rides must disappear from passenger search but remain in the database.
FR-7 — Ride statuses and expiry. As the system I should maintain ride statuses ACTIVE / FULL / CANCELLED / COMPLETED / EXPIRED and automatically expire past rides, so that stale rides never appear as available. Provenance: explicit. Observable result: a ride whose date/time has passed becomes EXPIRED without manual action.
FR-8 — Find a Ride search. As a Passenger I should search Find a Ride by From, To, Date, Time, and Seats required, so that I find a matching journey. Provenance: explicit. Example: Ahmedabad → Sankheda. Observable result: matching rides are listed.
FR-9 — Search result eligibility. As a Passenger I should see only rides that are active, match route/date/time, and have enough seats, so that every listed ride is bookable. Provenance: explicit. Constraint: never show FULL rides in available search.
FR-10 — Location autocomplete and coordinates. As a Driver or Passenger I should use location autocomplete for city, area, landmark, airport, railway station, and map locations, so that I can specify real places. Provenance: explicit. Observable result: latitude/longitude are stored for pickup and drop.
FR-11 — Nearby matching with configurable radius. As a Passenger I should match nearby rides within a configurable radius of 5 / 10 / 25 km, so that I can widen or narrow my search. Provenance: explicit. Observable result: results respect the selected radius.
FR-12 — Map provider. As a user I should see map and location services from Google Maps, Mapbox, or OpenStreetMap, so that routes and places are visualized. Provenance: explicit. Constraint: PostgreSQL + PostGIS is the recommended spatial store.
FR-13 — Ride card. As a Passenger I should see a premium ride card showing route, date and time, driver name, car model, rating, and seats available with a Request Seat button, so that I can evaluate and act on a ride. Provenance: explicit. Example content: Ahmedabad → Sankheda,\x20\xf0\x9f\x93\x85 10 Oct 2026 |\x20\xf0\x9f\x95\x90 10:00 AM,\x20\xf0\x9f\x91\xa4 Driver Name |\x20\xf0\x9f\x9a\x97 Car Model,\x20\xe2\xad\x90 4.8 |\x20\xf0\x9f\x92\xba 2 Seats Available. Full ride shows FULL / No Seats Available.
FR-14 — Backend-owned seat count. As the system I should control seat count in the backend, so that the displayed number is always true. Provenance: explicit. Constraint: never trust frontend seat count.
FR-15 — Zero-seat consequences. As the system I should, at 0 seats, set status = FULL, hide the ride from search, disable booking, and preserve history, so that the ride is closed but auditable. Provenance: explicit.
FR-16 — Atomic overbooking prevention. As the system I should prevent overbooking using an atomic database transaction/locking, so that if only one seat remains and two passengers book simultaneously, only one succeeds. Provenance: explicit. Observable result: exactly one booking succeeds; the other receives the last-seat message.
FR-17 — Last-seat message. As a Passenger I should see “Sorry, this ride is no longer available. The last seat was just booked.” when the last seat is taken, so that I understand why my request failed. Provenance: explicit.
FR-18 — Request Seat validation. As a Passenger I should click Request Seat and have the system validate logged-in user, ride exists, ride ACTIVE, valid date, seats available, passenger ≠ driver, and no duplicate booking, so that only valid requests are created. Provenance: explicit. Failure/recovery: each failed validation produces an accessible explanation and no booking is created.
FR-19 — Booking statuses and driver decision. As a Driver I should accept or reject a request, and bookings should carry statuses PENDING / ACCEPTED / REJECTED / CANCELLED / COMPLETED, so that both parties know where the booking stands. Provenance: explicit.
FR-20 — Atomic seat update on acceptance. As the system I should update seats atomically when a booking is accepted, so that the seat count never drifts. Provenance: explicit.
FR-21 — Passenger cancellation returns seats. As a Passenger I should cancel a booking and have the seats returned, so that the seat becomes available again. Provenance: explicit. Observable result: available seats increase and the ride may return from FULL to ACTIVE when seats become available.
FR-22 — Driver cancellation notifies passengers. As a Driver I should cancel a ride and have passengers notified, so that nobody is left waiting. Provenance: explicit. Observable result: the ride becomes CANCELLED and each affected passenger receives a notification.
FR-23 — Phone privacy. As a Driver I should never have my personal phone number publicly exposed, so that my privacy is protected. Provenance: explicit. Constraint: never expose private data through public APIs.
FR-24 — Pre-approval and post-approval contact. As a Passenger I should see Request Seat / Contact Driver before approval and have appropriate contact details revealed after approval, so that contact happens only when the driver has accepted. Provenance: explicit. Constraint: use masked numbers where required.
FR-25 — Authentication. As a user I should register, log in, log out, reset my password, verify my email, and verify my mobile by OTP, so that my account is real and recoverable. Provenance: explicit.
FR-26 — Profile. As a user I should see Name, photo, verified mobile/email, rating, and completed rides, displayed as ✓ Mobile Verified | ✓ Email Verified, so that I can judge and be judged on trust. Provenance: explicit.
FR-27 — Driver Dashboard. As a Driver I should see my rides, route, date/time, car, total/booked/available seats, status, and passenger requests, so that I can run my seat inventory. Provenance: explicit.
FR-28 — Passenger Dashboard. As a Passenger I should see requested, accepted, rejected, cancelled, and completed rides with booking status, so that I can track every request. Provenance: explicit.
FR-29 — Realtime seat availability. As a user I should see seat availability update without refresh, so that I never act on a stale number. Provenance: explicit. Example: User A sees 1 Seat Available; User B books the final seat; User A automatically sees FULL. Constraint: use WebSockets, Supabase Realtime, or Firebase Realtime; do not fake realtime with timers.
FR-30 — Driver notifications. As a Driver I should receive notifications for new request, accepted/rejected request, passenger cancellation, ride reminder, and ride cancellation, so that I can respond in time. Provenance: explicit.
FR-31 — Passenger notifications. As a Passenger I should receive notifications for request confirmation, accepted/rejected, driver cancellation, ride changes, and reminder, so that I know the state of my journey. Provenance: explicit.
FR-32 — Notification channels. As a user I should receive in-app notifications and optionally Email/WhatsApp/SMS, so that I am reachable on the channel I prefer. Provenance: explicit. Constraint: in-app is required; Email/WhatsApp/SMS are optional.
FR-33 — Ratings and reviews. As a Driver or Passenger I should rate the other party 1–5 stars with an optional review after a completed ride, so that trust accumulates. Provenance: explicit. Constraint: prevent duplicate reviews. Observable result: average rating and completed rides are displayed.
FR-34 — Search filters. As a Passenger I should filter by date, time, seats, vehicle, pickup radius, and driver rating, so that I narrow results to what I need. Provenance: explicit.
FR-35 — Sort options. As a Passenger I should sort by Recommended / Earliest / Nearest / Most Seats / Highest Rated, so that the best ride for me comes first. Provenance: explicit.
FR-36 — Safety features. As a user I should have mobile/email verification, report user/ride, block user, and a help/emergency option, so that I can protect myself. Provenance: explicit. Report categories: fake profile, fraud, harassment, unsafe behaviour, incorrect ride.
FR-37 — Admin panel with RBAC. As an Admin I should use a secure admin dashboard with RBAC to view/search users, suspend users, manage rides, cancel rides, view bookings, handle reports/reviews, and view statistics, so that platform integrity is maintained. Provenance: explicit.
FR-38 — Admin statistics. As an Admin I should see statistics for users, active rides, full rides, completed/cancelled rides, bookings, and available seats, so that I can judge platform health. Provenance: explicit.
FR-39 — Database schema. As the system I should store data in PostgreSQL + PostGIS with the tables users (id, name, email, phone, password_hash, photo, verification status, rating, timestamps), rides (id, driver_id, pickup/drop + coordinates, date, time, car, total_seats, available_seats, status, timestamps), bookings (id, ride_id, passenger_id, seats_requested, status, timestamps), and reviews (id, ride_id, reviewer_id, reviewee_id, rating, comment, timestamp), so that all product state is durable and spatially queryable. Provenance: explicit.
FR-40 — Security controls. As the system I should implement server-side validation, secure password hashing, authentication/authorization, RBAC, rate limiting, CORS, XSS/SQL injection protection, secure headers, error handling, and logging, so that the platform is safe. Provenance: explicit. Constraint: never expose passwords, tokens, hashes, or private contact information.
FR-41 — Premium responsive UI. As a user I should use a premium, modern, minimal, trustworthy mobility-startup interface with clean typography, premium cards, rounded components, subtle shadows, modern icons, map UI, smooth micro-interactions, and strong CTAs, fully responsive for desktop, tablet, and mobile, so that the product feels dependable. Provenance: explicit.
FR-42 — Hero. As a visitor I should see the hero PRAYOMSH CARPOOL with the tagline “Share the Ride. Split the Cost. Travel Smarter.”, the line “Find available rides, share your journey and connect with drivers and passengers.”, and the buttons Find a Ride | Offer a Ride, so that I can start immediately. Provenance: explicit.
FR-43 — SEO and accessibility. As a visitor I should get SEO title/meta, Open Graph, sitemap, robots.txt, semantic HTML, and structured data where useful, with title “PRAYOMSH Carpool — Find & Share Rides” and description “Find and share available carpool rides with PRAYOMSH. Search routes, request seats and travel smarter.”, and WCAG-following keyboard navigation, labels, accessible forms/errors, screen-reader support, and good contrast, so that the product is findable and usable by everyone. Provenance: explicit.
FR-44 — Edge cases. As the system I should handle driver/passenger cancellation, duplicate booking, final-seat race condition, full/expired ride, invalid date/location/seats, unauthorized access, network failure, duplicate API requests, and route/time changes, so that the product stays correct under stress. Provenance: explicit.
FR-45 — Testing. As the team I should test authentication, ride creation, search, booking, concurrency, realtime updates, and security, so that the product is verifiably production-ready. Provenance: explicit.
FR-46 — Final acceptance test. As the team I should verify: Driver login → Offer Ride → Ahmedabad → Sankheda → Date/Time → Car → 4 seats → Publish; Passenger login → Find Ride → Ahmedabad → Sankheda → Search → ride appears; bookings 4 → 3 → 2 → 1 → 0; at 0 ACTIVE → FULL; the ride immediately disappears from available search and booking is disabled; concurrent final-seat requests allow only one successful booking. Provenance: explicit.
FR-47 — Production readiness. As the team I should deliver a fully functional, secure, realtime, responsive, scalable, and production-ready product with no fake hardcoded production data. Provenance: explicit.
FR-48 — Self-service enrollment. As a Driver or Passenger I should be able to start independently by creating my own account, so that I can use the product without an invitation. Provenance: required_inference. Trigger: anonymous visitor chooses to start. Observable result: an account exists and verification can begin. Continuation: verification, then protected work.
FR-49 — Returning verification. As a returning Driver, Passenger, or Admin I should verify myself before protected ride, booking, profile, review, safety, or administrative work, so that my durable state stays bound to me. Provenance: required_inference. Observable result: a session is established and the user reaches the destination they were seeking. Failure/recovery: invalid credentials produce an accessible error and the user can retry or recover the account.
FR-50 — Verification completion. As a user I should complete password recovery, email verification, and mobile OTP verification, so that my account is recoverable and my trust signals are real. Provenance: required_inference. Observable result: the profile shows ✓ Mobile Verified | ✓ Email Verified.
FR-51 — RBAC provisioning. As the system I should provision and enforce role-based access for Admin responsibilities, so that administrative capability is not self-selected. Provenance: required_inference. Observable result: only an Admin reaches the Admin Panel; other roles are refused with an accessible explanation.
FR-52 — Transactional seat allocation. As the system I should perform seat allocation and duplicate-booking prevention inside a backend transaction with locking, so that concurrent requests cannot both succeed. Provenance: required_inference. Observable result: exactly one of two simultaneous final-seat requests succeeds.
FR-53 — Realtime backend updates. As the system I should push availability and ride-status changes from the backend, so that every connected client converges on the same confirmed state. Provenance: required_inference. Observable result: the seat numeral and status change on all affected surfaces without refresh.
FR-54 — Automatic expiry processing. As the system I should process past rides automatically, so that EXPIRED rides never appear as available. Provenance: required_inference. Observable result: a ride past its date/time becomes EXPIRED without manual action.
FR-55 — Approved booking state gates contact. As the system I should require an approved booking state before revealing appropriate driver contact details, so that contact is never exposed before approval. Provenance: required_inference. Observable result: before approval the passenger sees Request Seat / Contact Driver; after approval the appropriate details are revealed, masked where required.
Product context. The Driver offers available car seats. They publish a journey they are already making and manage the seat inventory on it. They are practical and price-aware: the point of offering seats is to split the cost of a trip they are taking anyway.
Primary goal. Fill the offered seats correctly — without overbooking, without a stale seat number, and without being contacted by strangers before they have accepted a request.
Distinct accepted responsibilities. Publishing a ride through Offer a Ride with Name, Mobile, Email, Pickup, Drop, Date, Time, Car model/type, and Available passenger seats, using the − 1 + seat selector. Managing that ride's seat count and status across ACTIVE / FULL / CANCELLED / COMPLETED / EXPIRED. Accepting or rejecting passenger requests. Cancelling a ride when plans change. Marking a ride completed. Rating the passenger after a completed ride.
Relevant inputs and decisions. Pickup and drop chosen through location autocomplete; date and time; car model/type; the number of seats to offer; which requests to accept when seats are scarce; whether to cancel.
Interactions with other accepted participants. With Passengers, whose requests the Driver accepts or rejects and whose cancellations return seats to the ride. With the system, which owns the seat count and flips the ride to FULL at zero. With the Admin, who can manage or cancel rides and suspend users.
Observable success. Seats are filled correctly with no overbooking; the available-seat figure is always the server-confirmed integer; past rides expire automatically; the Driver Dashboard shows my rides, route, date/time, car, total/booked/available seats, status, and passenger requests; the Driver is notified of new requests, cancellations, reminders, and ride changes; and completed rides can be rated.
Source-backed constraints. The Driver's personal phone number is never publicly exposed; contact details are revealed only after approval, masked where required. The Driver cannot be the passenger on their own ride.
Product context. The Passenger searches for a ride that matches a journey they need to make and requests a seat on it. They are slightly anxious about safety and reliability: they want to know the ride is real, the driver is verified, and the seat they are requesting actually exists.
Primary goal. Secure a seat on a matching ride, know exactly where the request stands, and reach the driver only once the request has been approved.
Distinct accepted responsibilities. Searching Find a Ride by From, To, Date, Time, and Seats required. Applying filters for date, time, seats, vehicle, pickup radius, and driver rating, and sorting by Recommended / Earliest / Nearest / Most Seats / Highest Rated. Reading ride cards and clicking Request Seat. Tracking requested, accepted, rejected, cancelled, and completed rides with booking status in the Passenger Dashboard. Cancelling a booking, which returns seats. Rating the driver after a completed ride. Reporting or blocking a user or ride, and using the help/emergency option.
Relevant inputs and decisions. From and To chosen through location autocomplete; date and time; seats required; pickup radius of 5 / 10 / 25 km; which ride to request; whether to cancel.
Interactions with other accepted participants. With the Driver, who accepts or rejects the request and whose contact details are revealed only after approval. With the system, which validates the request and owns the seat count. With the Admin, who handles reports and reviews.
Observable success. A seat is secured on a matching ride; the seat count the Passenger saw was true at the moment of booking; FULL rides never appeared in search; contact details were revealed only after approval; the Passenger is notified of request confirmation, accept/reject outcomes, driver cancellations, ride changes, and reminders; and the completed ride can be rated.
Source-backed constraints. The Passenger must be logged in to request a seat, must not be the driver of the ride, and cannot create a duplicate booking.
Product context. The Admin operates the secure admin dashboard with RBAC. Their work is governance rather than travel: they keep the marketplace honest so that Drivers and Passengers can trust each other.
Primary goal. Maintain platform safety and integrity through moderation of users, rides, reports, and reviews.
Distinct accepted responsibilities. Viewing and searching users. Suspending users. Managing rides and cancelling rides. Viewing bookings. Handling reports and reviews. Viewing statistics for users, active rides, full rides, completed/cancelled rides, bookings, and available seats.
Relevant inputs and decisions. Which users to suspend; which rides to cancel; how to resolve a report in the categories fake profile, fraud, harassment, unsafe behaviour, or incorrect ride; which reviews require action.
Interactions with other accepted participants. With Drivers and Passengers, whose accounts, rides, bookings, reports, and reviews the Admin moderates. With the system, which enforces RBAC and supplies the statistics.
Observable success. Reports and reviews are handled, abusive or fraudulent accounts are suspended, problematic rides are cancelled, and the statistics band reflects the true state of the platform.
Source-backed constraints. Administrative capability is governed by RBAC and is not self-selected. The Admin never sees passwords, tokens, hashes, or private contact information.
The creative direction is authoritative for this section. The muse is Rasmus Andersson: systematic product craft with a warm ground and one hot signal, ride data rendered as editorial numerals. The headline idea is that the core UI object is a live integer — seats available — that must never be misread and must update instantly, so the interface is a seat-count instrument rather than a SaaS landing page.
Palette — light mode.
| Role | Token | Value |
|---|---|---|
| Background (warm paper ground) | --bg | #F6F3EE |
| Surface (cards, form panels) | --surface | #FFFFFF |
| Text / primary action (ink) | --ink | #141517 |
| Accent (single hot signal) | --accent | #E4572E |
| Muted (metadata, timestamps, helper text) | --muted | #8A8578 |
| Hairline border | --hairline | #E3DED4 |
Status set (text + 6px dot, never a coloured pill background).
| Status | Value |
|---|---|
| ACTIVE | #2F7A5F (deep green) |
| FULL | #E4572E |
| CANCELLED | #8A8578 |
| COMPLETED | #141517 at 60% |
| EXPIRED | #8A8578 at 40% |
Tangerine #E4572E is reserved for the Request Seat CTA hover state, live seat-count numerals, the FULL badge, focus rings, active filter chips, and the seat-stepper minus/plus glyphs. The primary action is ink black, not blue. Links are ink with a 1px underline offset 3px. Blue and indigo are forbidden anywhere — no #2563EB, #4F46E5, or #6366F1 buttons, links, focus rings, or map pins.
Typography.
font-variant-numeric: tabular-nums, so seat counts never jitter when they tick 4→3→2→1→0.clamp(40px, 9vw, 96px) mobile→desktop; section headings clamp(24px, 4vw, 40px); ride-card route line 20–25px; body 16px with 1.55 line-height; micro-labels 12px uppercase 0.08em tracking in Space Grotesk 500; monospace numerals 14–20px.Shape language. Compact and precise: 8px radius on inputs, buttons, and chips; 12px on ride cards; 16px on dashboard panels; 999px only on the seat stepper's − and + circular buttons and status dots. Hairline 1px borders in #E3DED4 do the structural work instead of shadows. Buttons are rectangles with a 1px ink border and a 2px hard offset shadow on hover (no soft blur), which reads as a physical key press. Dividers are full-bleed 1px rules that align to the grid. No blobs, no pills-everywhere, no glass.
Spacing rhythm. 4/8-pt scale throughout; 24px gutters; max content 1200px at a visible 12-column grid at 1280px, collapsing to 8 columns at 768px and 4 columns at 375px, with a persistent left rule at column 1 on desktop so the grid is legible.
Imagery style. The interface is the imagery: a real OpenStreetMap/Mapbox vector map panel with ink route polylines, a tangerine pickup pin, a black drop pin, and muted grey map tiles (never default Google blue). Supporting graphics are schematic — a ruled seat-occupancy diagram of four filled/empty seat squares that fill left-to-right as bookings land, thin topographic-style route lines as section dividers, and monospace code-like ride ID labels (e.g. RIDE-2026-00418). No stock photography of people, no 3D blobs, no illustration. Driver avatars are initials in a 1px-bordered square, not a circle.
Readable text and controls stay whole at 375px, 768px, and 1280px: headlines, wordmarks, labels, numbers, card text, and controls stay entirely inside the viewport and their container, wrapping or scaling (for example font-size: clamp(...) with its mobile size) to fit, and no other element covers any part of them. Imagery and decoration may be cropped, bled, rotated, or overlapped as the direction asks, as long as they cover no readable text or control.
The public entry is a seat-count instrument, not a landing page. It is a split hero on warm paper #F6F3EE, nothing centred, nothing floating on a gradient.
Left 7 columns. PRAYOMSH set in Space Grotesk 600 at clamp(40px, 9vw, 96px) with tight tracking, and CARPOOL on the next line indented by exactly one grid column so the two words step down the page. Beneath it the tagline “Share the Ride. Split the Cost. Travel Smarter.” at 20–25px in ink, then the supporting line “Find available rides, share your journey and connect with drivers and passengers.” in muted #8A8578, then two buttons on one baseline — Find a Ride as a solid ink block with white text and Offer a Ride as a 1px ink outline block, both 8px radius with a 2px hard offset shadow on hover.
Right 5 columns. A live “Right now” panel: a white surface with a 1px hairline border containing three real rides as ruled rows — route in ink, date/time in muted, available seats as a large tangerine tabular numeral on the right — headed by a small uppercase Space Grotesk label with a pulsing 6px green dot. The panel shows the last server-confirmed values with a timestamp; it never hides the seat truth behind a skeleton after first paint.
Directly under the hero. A full-bleed 1px rule spans the viewport and the seat-logic strip sits on it: 4 → 3 → 2 → 1 → 0 rendered as five monospace digit blocks separated by arrows, with the 0 block outlined in tangerine and labelled FULL. This is the product's core mechanic stated as the hero's baseline — the app's atomic booking logic rendered as its most prominent graphic element.
The concept recomposes only accepted content, states, and controls: the wordmark, tagline, supporting line, the two entry buttons, real ride data, and the seat-count mechanic. It introduces no new behaviour, page, or destination.
Interaction Model: Static Motion Tempo: restrained Hero Dimensionality: flat
Landing Hero Motion Brief.
cubic-bezier(0.2, 0, 0, 1). The monospace digit flip (old digit slides up out, new digit slides in) over 160ms is the only ornamental motion in the product and it exists to make realtime legible. Realtime updates arrive with a 1px tangerine border flash on the affected card for 400ms, then settle. Ride cards enter with a 120ms 4px upward fade staggered 30ms per row, capped at the first 8 rows. Hover on a ride card shifts the route arrow 4px right. No bounce, no parallax, no animated gradients.prefers-reduced-motion the digit flip and the border flash are removed, leaving instant value swaps; staggered card entry and the hover arrow shift are removed; the seat-logic rail renders as five static digit blocks with the tangerine-outlined 0 tagged FULL.NFR-1 — Backend authority over seat count. Seat count is controlled by the backend and the frontend seat count is never trusted. Provenance: explicit. Rationale: the product's core promise is that the displayed seat number is always true.
NFR-2 — Atomic concurrency safety. Overbooking is prevented with an atomic database transaction/locking; if only one seat remains and two passengers book simultaneously, only one succeeds. Provenance: explicit. Rationale: the final-seat race condition is the defining correctness test of the product.
NFR-3 — FULL-ride visibility rule. FULL rides disappear from passenger search but remain in the database; FULL rides are never shown in available search. Provenance: explicit.
NFR-4 — Zero-seat consequences. At 0 seats: status = FULL, hide from search, disable booking, preserve history. Provenance: explicit.
NFR-5 — Phone privacy. The driver's personal phone number is never publicly exposed, and private data is never exposed through public APIs. Provenance: explicit.
NFR-6 — Secret non-exposure. Passwords, tokens, hashes, and private contact information are never exposed. Provenance: explicit.
NFR-7 — Genuine realtime. Realtime is delivered over WebSockets, Supabase Realtime, or Firebase Realtime; realtime is never faked with timers. Provenance: explicit.
NFR-8 — Secrets in environment variables. API keys and secrets are kept in environment variables. Provenance: explicit.
NFR-9 — No fake production data. The final product contains no fake hardcoded production data. Provenance: explicit.
NFR-10 — Booking integrity rules. A passenger must not be the driver on a booking, and duplicate bookings are not allowed. Provenance: explicit.
NFR-11 — Notification channel obligation. In-app notifications are required; Email/WhatsApp/SMS are optional. Provenance: explicit.
NFR-12 — Security controls. Server-side validation, secure password hashing, authentication/authorization, RBAC, rate limiting, CORS, XSS/SQL injection protection, secure headers, error handling, and logging. Provenance: explicit.
NFR-13 — Responsiveness. Fully responsive for desktop, tablet, and mobile. Provenance: explicit.
NFR-14 — Accessibility. WCAG-following keyboard navigation, labels, accessible forms and errors, screen-reader support, and good contrast. Provenance: explicit.
NFR-15 — SEO. SEO title/meta, Open Graph, sitemap, robots.txt, semantic HTML, and structured data where useful. Provenance: explicit.
NFR-16 — Scalability and production readiness. The product must be fully functional, secure, realtime, responsive, scalable, and production-ready. Provenance: explicit.
NFR-17 — Spatial capability. PostgreSQL + PostGIS supports coordinate storage and nearby matching at 5 / 10 / 25 km. Provenance: explicit.
NFR-18 — Test coverage. Authentication, ride creation, search, booking, concurrency, realtime updates, and security are tested. Provenance: explicit.
NFR-19 — Edge-case handling. Driver/passenger cancellation, duplicate booking, final-seat race condition, full/expired ride, invalid date/location/seats, unauthorized access, network failure, duplicate API requests, and route/time changes are handled. Provenance: explicit.
NFR-20 — Readable content containment. Readable text and controls stay whole at 375px, 768px, and 1280px, inside the viewport and their container, with no other element covering them. Provenance: explicit (creative direction).
Source choices are preserved exactly; nothing is substituted.
Assumptions.
Constraints.
#E4572E.PRAYOMSH CARPOOL © 2026 PRAYOMSH. All rights reserved.
No completed page designs yet.
Completed design pages will appear here when they are ready to preview.
No completed page designs yet.
Completed design pages will appear here when they are ready to preview.
No comments yet. Be the first!