profitmate

byAbdelkarim Tayane

Act as a senior full-stack developer, UI/UX designer, and product engineer. Build a complete, functional, mobile-first web application called "ProfitMate". IMPORTANT: Do not just create a mockup, static landing page, or visual prototype. Build a genuinely interactive application with working calculations, functional buttons, input validation, and persistent local data storage. 1. APP PURPOSE ProfitMate is a free, easy-to-use business profit calculator for people worldwide, including shop owners, restaurant owners, freelancers, small businesses, and online sellers. The app helps users calculate product costs, selling prices, profits, profit margins, expenses, and break-even points without requiring accounting knowledge. The application must be useful internationally, regardless of the user's country, language, or currency. 2. LANGUAGES Implement a complete language selector with: - English - Arabic - French - Spanish - Portuguese - German Requirements: - Automatically detect the device's preferred language on the first visit when supported. - If the device language is unsupported, default to English. - Allow users to change the language manually at any time. - Translate all interface text, buttons, labels, menus, messages, validation errors, and reports. - Support right-to-left layout for Arabic and left-to-right layout for other languages. - Remember the selected language. 3. UNIVERSAL CURRENCY SYSTEM This is a critical feature. Do NOT hardcode a single currency. Provide two methods for selecting the currency: A. Choose from a comprehensive list of world currencies, including: - USD — US Dollar - EUR — Euro - GBP — British Pound - DZD — Algerian Dinar - CAD — Canadian Dollar - AUD — Australian Dollar - MAD — Moroccan Dirham - SAR — Saudi Riyal - AED — UAE Dirham - EGP — Egyptian Pound - INR — Indian Rupee - JPY — Japanese Yen - CNY — Chinese Yuan - BRL — Brazilian Real - MXN — Mexican Peso - CHF — Swiss Franc - TRY — Turkish Lira - ZAR — South African Rand Include all other commonly used ISO 4217 currencies where practical. B. Allow users to create a custom currency by entering: - Currency name - Currency symbol - Currency code, if available - Number of decimal places, from 0 to 4 Examples of custom currencies: - My Currency - Local Business Credits - A user-defined currency symbol Currency requirements: - Use the selected currency throughout the entire application. - Format numbers according to the selected language and locale. - Support currencies that use zero, two, or three decimal places. - Allow the user to change the currency at any time. - Store the currency preference locally. - Never assume that changing the currency automatically converts monetary values using exchange rates. - Clearly explain that changing the currency changes the display unit and does not convert existing amounts. - Do not require an external currency API or paid service. 4. MAIN DASHBOARD Create a modern, professional dashboard with: - Total sales - Total costs - Gross profit - Net profit estimate - Profit margin - Number of products - Recent calculations Provide date filters where appropriate: - Today - Last 7 days - Last 30 days - All time All dashboard values must be calculated from the user's saved data, not hardcoded demo numbers. Show a helpful empty state when no data exists. 5. PRODUCT PROFIT CALCULATOR Allow users to enter: - Product name - Unit cost - Additional costs per unit - Selling price per unit - Quantity sold Automatically calculate: - Total unit cost - Profit per unit - Total revenue - Total cost - Total profit - Profit margin percentage - Markup percentage Use these formulas: Total unit cost = Unit cost + Additional costs per unit Profit per unit = Selling price - Total unit cost Total revenue = Selling price × Quantity sold Total cost = Total unit cost × Quantity sold Total profit = Total revenue - Total cost Profit margin (%) = Total profit / Total revenue × 100, when revenue is greater than zero. Markup (%) = Profit per unit / Total unit cost × 100, when total unit cost is greater than zero. Handle zero values and invalid inputs safely. Never display NaN or Infinity. 6. SELLING PRICE CALCULATOR Allow users to enter: - Total unit cost - Desired profit margin percentage Calculate the recommended selling price using: Selling price = Total unit cost / (1 - Desired margin / 100) Reject margins below 0% or greater than or equal to 100%. Display the expected profit per unit and profit margin. 7. EXPENSE TRACKER Allow users to: - Add an expense name. - Enter the amount. - Select a category. - Add a date. - Edit and delete expenses. Provide expense summaries by category and date. Do not count the same expense twice in the profit calculation. 8. BREAK-EVEN CALCULATOR Allow users to enter: - Fixed costs - Selling price per unit - Variable cost per unit Calculate: Contribution per unit = Selling price - Variable cost Break-even quantity = Fixed costs / Contribution per unit Break-even revenue = Break-even quantity × Selling price Round the required break-even quantity UP to the next whole unit. If the selling price is less than or equal to the variable cost, explain that break-even cannot be reached under the current assumptions. 9. PRODUCT MANAGEMENT Allow users to: - Add products. - Edit products. - Delete products. - Search products. - Sort products. - View product cost, selling price, and expected profit. Include sample data only in a clearly labeled optional demo mode. Let users start with a completely empty workspace. 10. DATA STORAGE AND PRIVACY The first version must work without: - User registration - Login - Paid APIs - A paid database - A subscription - An external server Use IndexedDB or another appropriate local browser storage solution to save products, expenses, settings, and calculation history. Data must persist after refreshing or reopening the app on the same browser. Include: - Export data to JSON. - Export reports to CSV. - Import a previously exported JSON backup. - Clear all local data after an explicit confirmation. Validate imported data before saving it. Clearly inform users that local data may not automatically synchronize across different devices or browsers. Do not pretend that local browser storage is cloud storage. 11. DESIGN Create a premium-looking interface inspired by high-quality modern SaaS dashboards. Design requirements: - Mobile-first responsive layout. - Works on Android, iPhone, tablets, and desktop browsers. - Clean typography. - Accessible contrast. - Light and dark modes. - Professional dashboard cards. - Simple charts with useful labels. - Attractive empty states. - Clear forms and error messages. - Bottom navigation on mobile and a sidebar on desktop where appropriate. - Smooth but subtle transitions. Avoid excessive animations, unnecessary gradients, clutter, and oversized headings. The app must be usable on small phone screens. 12. INSTALLABLE WEB APP If supported by the environment, make the application a Progressive Web App (PWA). Include: - A web app manifest. - Appropriate app icons. - A service worker for caching the app shell. - An installation prompt or clear installation instructions. - Offline access to the core calculator features after the app has been loaded and cached. Do not claim that offline support works until it has been implemented and tested. 13. TESTING Test all major calculations using known examples. Test case 1: Unit cost = 100 Additional unit cost = 20 Selling price = 200 Quantity = 10 Expected results: Total unit cost = 120 Profit per unit = 80 Total revenue = 2000 Total cost = 1200 Total profit = 800 Profit margin = 40% Markup = 66.6667% approximately Test case 2: Total unit cost = 60 Desired profit margin = 40% Expected selling price = 100 Expected profit per unit = 40 Test case 3: Fixed costs = 1000 Selling price = 100 Variable cost = 60 Expected contribution per unit = 40 Expected break-even quantity = 25 Expected break-even revenue = 2500 Also test: - Zero revenue - Zero cost - Negative input rejection where appropriate - Decimal numbers - Large amounts - Different currency symbols - Arabic right-to-left layout - Language switching - Saving and restoring data - Importing and exporting backups - Mobile responsiveness Fix any errors found during testing. 14. FINAL DELIVERABLE Build the actual working application in the current environment. Do not stop after providing a plan or code snippets. Generate the interface, implement the calculations, connect all buttons, add local storage, and run the available tests. At the end, provide: 1. A working preview. 2. Instructions for testing the app on a phone. 3. Instructions for installing it if PWA support is available. 4. A summary of completed features. 5. Any known limitations. 6. Instructions for exporting the source code and deploying it using a free hosting option. The first version must prioritize reliability, simplicity, privacy, and genuinely working features over unnecessary complexity.

No preview

Comments (0)

No comments yet. Be the first!

System Requirements

System Requirements Document for profitmate

1. Introduction

ProfitMate is a free, easy-to-use business profit calculator for people worldwide — shop owners, restaurant owners, freelancers, small businesses, and online sellers. It helps users calculate product costs, selling prices, profits, profit margins, expenses, and break-even points without requiring accounting knowledge, and it must be useful internationally regardless of the user's country, language, or currency.

This document is the System Requirements Document for the first version of ProfitMate. The first version prioritizes reliability, simplicity, privacy, and genuinely working features over unnecessary complexity. It must be a genuinely interactive application with working calculations, functional buttons, input validation, and persistent local data storage — not a mockup, static landing page, or visual prototype.

The product is delivered as a mobile-first web application that runs entirely in the user's browser, stores all data locally, and requires no registration, login, paid API, paid database, subscription, or external server.

2. System Overview

ProfitMate is a single-page, mobile-first web application. Its working surface is a local workspace: the user's products, expenses, settings, and calculation history live in the browser's local storage (IndexedDB or an equivalent local browser storage solution) and persist after refreshing or reopening the app on the same browser.

The application provides:

Page 1 of 57
  • A Landing entry that explains ProfitMate's purpose, audience, and calculators before the user enters the local workspace.
  • A Dashboard whose totals are computed from the user's saved data, with date filters (Today, Last 7 days, Last 30 days, All time), recent calculations, and a helpful empty state.
  • A Product Profit Calculator that derives total unit cost, profit per unit, total revenue, total cost, total profit, profit margin, and markup from user inputs.
  • A Selling Price Calculator that recommends a selling price from total unit cost and desired margin, rejecting margins below 0% or at or above 100%.
  • An Expense Tracker with add, edit, delete, and category/date summaries, ensuring no expense is counted twice in profit calculations.
  • A Break-Even Calculator computing contribution per unit, break-even quantity (rounded up to the next whole unit), and break-even revenue, with an explanation when break-even cannot be reached.
  • A Products surface for adding, editing, deleting, searching, and sorting products, and viewing cost, selling price, and expected profit.
  • Settings for language (English, Arabic, French, Spanish, Portuguese, German), currency (world list plus custom currency), light/dark mode, and the currency-change explanation.
  • Data & Privacy for JSON export, CSV report export, validated JSON import, confirmed clearing of all local data, and the local-storage privacy notice.

The application is delivered through a React frontend, a shared FastAPI backend process, and a MariaDB database service as provisioned infrastructure. The product's first-version behavior is local-first and requires no external server for its core function; the provisioned backend and database are infrastructure available to the environment and do not introduce registration, login, cloud storage, or any product capability beyond what is specified here.

Page 2 of 57

Removed from scope

  • None. No concept was explicitly removed by the user.
Page 3 of 57

2a. Product Interpretation and Delivery Boundary

ProfitMate is a working instrument, not a brand statement. The user opens it to answer concrete questions — what does this product cost me, what should I charge, what did I spend, when do I break even — and expects the answers to be correct, legible, and available on a cheap phone in bright daylight, in their own language and currency.

Delivery ownership. The first version works without user registration, login, paid APIs, a paid database, a subscription, or an external server. All products, expenses, settings, and calculation history are saved in local browser storage and persist after refreshing or reopening the app on the same browser. There is no application-owned account identity and no cloud synchronization. The app must clearly inform users that local data may not automatically synchronize across different devices or browsers, and must never pretend that local browser storage is cloud storage.

Access. Every page is reachable without identity. The Landing page is the anonymous entry that explains the product before the user enters the local workspace; all working pages are part of that same local workspace.

Currency boundary. Changing the currency changes the display unit only. It never converts existing amounts using exchange rates, and no external currency API or paid service is required.

Offline boundary. Offline access to the core calculator features is claimed only after the service worker and app shell have been implemented and tested. Until then, offline support must not be claimed.

Future boundary. No future-version requirements were stated by the user. Everything in this document is current.

Page 4 of 57

2c. Page Content and Component Coverage

Landing

  • Information/state: ProfitMate's purpose (free business profit calculator for shop owners, restaurant owners, freelancers, small businesses, and online sellers), the calculators and tools it offers (product profit, selling price, expenses, break-even, products, dashboard), the six supported languages, the universal currency capability, and the privacy posture (local-only data, no registration or login). No hardcoded demo numbers presented as the user's data.
  • Primary action: Enter the local workspace (Dashboard).
  • Supporting actions: Language selector; currency selector; theme toggle.
  • Domain entities: None persisted on this page.
  • Component responsibilities: Wordmark and top bar; purpose statement; capability summary; privacy statement; entry control.
  • States: Loading (app shell initializing); empty (no user data yet — the landing itself is the pre-workspace state); success (entry control leads to Dashboard); error (app shell fails to initialize — show a clear message and retry); recovery (retry reloads the shell).
Page 5 of 57

Dashboard

  • Information/state: Total sales, total costs, gross profit, net profit estimate, profit margin, number of products, and recent calculations, all computed from the user's saved data. Active date filter among Today, Last 7 days, Last 30 days, All time. Simple charts with useful labels (sales vs costs vs profit; category breakdown; break-even chart where applicable).
  • Primary action: Change the date filter.
  • Supporting actions: Open a recent calculation; navigate to add a product; navigate to other working pages.
  • Domain entities: Products, expenses, calculation history, settings (currency, language, theme).
  • Component responsibilities: Ruled KPI band; date-filter chips; bar chart; recent-calculations ruled list; empty-state panel.
  • States: Loading (reading local storage); empty (no saved data — helpful empty state with a pictogram, one sentence, and an "Add your first product" button); success (KPIs and charts populated from saved data); error (local storage read failure — clear message, retry); recovery (retry re-reads storage; if storage is unavailable, explain that data cannot be read in this browser).
Page 6 of 57

Product Profit Calculator

  • Information/state: Inputs — product name, unit cost, additional costs per unit, selling price per unit, quantity sold. Derived — total unit cost, profit per unit, total revenue, total cost, total profit, profit margin percentage, markup percentage. All monetary values formatted in the selected currency and locale.
  • Primary action: Calculate (results update automatically as valid inputs are entered).
  • Supporting actions: Save the calculation to history; clear the form; change currency/language from the top bar.
  • Domain entities: Calculation record (inputs and derived results), settings.
  • Component responsibilities: Input form with labels above fields; validation messages directly beneath fields; ruled summary table of computed results; save control.
  • States: Loading (not applicable beyond shell); empty (blank form with zero-safe defaults); success (all seven derived values shown, never NaN or Infinity); error (invalid input — field-level message, e.g., negative values rejected where appropriate; zero revenue or zero cost handled safely with margin/markup omitted or explained rather than shown as NaN/Infinity); recovery (correct the field and results recompute).
Page 7 of 57

Selling Price Calculator

  • Information/state: Inputs — total unit cost, desired profit margin percentage. Derived — recommended selling price, expected profit per unit, profit margin.
  • Primary action: Calculate (results update automatically as valid inputs are entered).
  • Supporting actions: Clear the form; change currency/language from the top bar.
  • Domain entities: Calculation record, settings.
  • Component responsibilities: Input form; validation messages; ruled summary table of results.
  • States: Loading (shell only); empty (blank form); success (selling price, profit per unit, and margin shown); error (margin below 0% or greater than or equal to 100% rejected with a clear message; invalid cost rejected); recovery (correct the input and results recompute).
Page 8 of 57

Expense Tracker

  • Information/state: Expense list with name, amount, category, and date; summaries by category and by date. Amounts formatted in the selected currency and locale.
  • Primary action: Add an expense.
  • Supporting actions: Edit an expense; delete an expense; change summary grouping (category or date).
  • Domain entities: Expense records, settings.
  • Component responsibilities: Expense form; expense list with edit/delete controls; category/date summary views; validation messages.
  • States: Loading (reading local storage); empty (no expenses — helpful empty state with an add control); success (list and summaries populated); error (invalid amount or missing required field — field-level message; storage write failure — clear message); recovery (correct input or retry the write).
Page 9 of 57

Break-Even Calculator

  • Information/state: Inputs — fixed costs, selling price per unit, variable cost per unit. Derived — contribution per unit, break-even quantity (rounded up to the next whole unit), break-even revenue. A break-even chart with a labelled intersection point and a fixed-costs baseline.
  • Primary action: Calculate (results update automatically as valid inputs are entered).
  • Supporting actions: Clear the form; change currency/language from the top bar.
  • Domain entities: Calculation record, settings.
  • Component responsibilities: Input form; validation messages; ruled summary table; break-even chart.
  • States: Loading (shell only); empty (blank form); success (contribution, quantity, and revenue shown); error (selling price less than or equal to variable cost — explain that break-even cannot be reached under the current assumptions; invalid inputs rejected); recovery (correct inputs and results recompute).
Page 10 of 57

Products

  • Information/state: Product list showing product cost, selling price, and expected profit; search query; sort selection.
  • Primary action: Add a product.
  • Supporting actions: Edit a product; delete a product; search products; sort products; optionally enable clearly labeled demo mode with sample data.
  • Domain entities: Product records, settings.
  • Component responsibilities: Product form; search field; sort control; product list with edit/delete controls; demo-mode toggle clearly labeled as optional.
  • States: Loading (reading local storage); empty (completely empty workspace by default — helpful empty state with an add control); success (list populated, search and sort applied); error (invalid product input — field-level message; storage failure — clear message); recovery (correct input or retry).
Page 11 of 57

Settings

  • Information/state: Current language; current currency (world list or custom); theme (light/dark); the currency-change explanation stating that changing the currency changes the display unit and does not convert existing amounts.
  • Primary action: Change language, currency, or theme.
  • Supporting actions: Create a custom currency (name, symbol, optional code, decimal places 0–4); select from the world currency list; toggle light/dark mode.
  • Domain entities: Settings record (language, currency, custom currency definition, theme).
  • Component responsibilities: Language selector; currency selector with world list and custom-currency form; theme toggle; currency-change explanation note.
  • States: Loading (reading settings); empty (defaults: detected or English language, a default currency, light mode); success (preference saved and applied throughout the app); error (invalid custom currency — e.g., decimal places outside 0–4 — field-level message; storage failure — clear message); recovery (correct input or retry).
Page 12 of 57

Data & Privacy

  • Information/state: Explanation that data is stored locally in the browser, may not automatically synchronize across different devices or browsers, and is not cloud storage. Export, import, and clear controls.
  • Primary action: Export data to JSON.
  • Supporting actions: Export reports to CSV; import a previously exported JSON backup; clear all local data after explicit confirmation.
  • Domain entities: All local data (products, expenses, settings, calculation history).
  • Component responsibilities: Privacy notice; JSON export control; CSV report export control; JSON import control with validation feedback; clear-all control with confirmation dialog.
  • States: Loading (reading local storage); empty (no data to export — explain); success (export downloaded, import validated and saved, or data cleared); error (import validation failure — explain what is invalid and do not save; storage failure — clear message); recovery (retry or correct the backup file).
Page 13 of 57

3. Functional Requirements

Each requirement is a distinct story point with provenance, lifecycle facts, and observable acceptance.

FR-01 — Genuinely interactive application (explicit) As a small business owner / seller, I should use a genuinely interactive application with working calculations, functional buttons, input validation, and persistent local data storage, so that ProfitMate is a real tool rather than a mockup, static landing page, or visual prototype.

  • Trigger/input: user interaction with forms, buttons, and navigation.
  • Observable result: calculations update, buttons perform their stated actions, invalid inputs show validation messages, and data persists after refresh.
  • Failure/recovery: any non-working control is a defect to fix during testing.
  • Continuation: user continues working in the local workspace.

FR-02 — Free profit calculator for non-accountants (explicit) As a small business owner / seller, I should calculate product costs, selling prices, profits, profit margins, expenses, and break-even points without accounting knowledge, so that I can understand my business profitability.

  • Trigger/input: the user's business figures entered into the calculators and trackers.
  • Observable result: computed costs, prices, profits, margins, expenses, and break-even points.
  • Failure/recovery: invalid inputs are rejected with clear messages.
  • Continuation: results feed the dashboard and product records.
Page 14 of 57

FR-03 — International usefulness (explicit) As an international user managing language and currency, I should use the app regardless of my country, language, or currency, so that it is useful to me wherever I operate.

  • Trigger/input: language and currency selection.
  • Observable result: interface and monetary formatting match the selected language and currency.
  • Failure/recovery: unsupported device language falls back to English.
  • Continuation: preferences persist locally.

FR-04 — Language selector with six languages (explicit) As an international user managing language and currency, I should select English, Arabic, French, Spanish, Portuguese, or German from a complete language selector, so that I can use the app in my language.

  • Trigger/input: language selection in Settings or the top bar.
  • Observable result: the interface switches to the selected language.
  • Failure/recovery: if a selection cannot be saved, inform the user.
  • Continuation: the selection is remembered.

FR-05 — Device language detection with English fallback (explicit) As an international user managing language and currency, I should have the app automatically detect my device's preferred language on first visit when supported, and default to English when unsupported, so that the app opens in a language I understand.

  • Trigger/input: first visit.
  • Observable result: supported device language is applied; otherwise English.
  • Failure/recovery: detection failure falls back to English.
  • Continuation: the user may change the language manually at any time.
Page 15 of 57

FR-06 — Manual language change and persistence (explicit) As an international user managing language and currency, I should change the language manually at any time and have the selected language remembered, so that my preference persists.

  • Trigger/input: manual language selection.
  • Observable result: interface updates immediately and the selection is stored locally.
  • Failure/recovery: storage failure shows a clear message.
  • Continuation: on reopening, the remembered language is applied.

FR-07 — Full translation coverage (explicit) As an international user managing language and currency, I should see all interface text, buttons, labels, menus, messages, validation errors, and reports translated, so that no untranslated text appears.

  • Trigger/input: any language selection.
  • Observable result: all listed text categories appear in the selected language.
  • Failure/recovery: missing translations are defects to fix.
  • Continuation: reports exported in the selected language.

FR-08 — RTL for Arabic, LTR for others (explicit) As an international user managing language and currency, I should see a right-to-left layout for Arabic and left-to-right layout for other languages, so that the layout matches my reading direction.

  • Trigger/input: language selection.
  • Observable result: layout direction switches accordingly.
  • Failure/recovery: layout defects are fixed during testing.
  • Continuation: direction persists with the language.
Page 16 of 57

FR-09 — World currency list (explicit) As an international user managing language and currency, I should choose from a comprehensive list of world currencies including USD, EUR, GBP, DZD, CAD, AUD, MAD, SAR, AED, EGP, INR, JPY, CNY, BRL, MXN, CHF, TRY, ZAR, and all other commonly used ISO 4217 currencies where practical, so that I can use my own currency.

  • Trigger/input: currency selection from the list.
  • Observable result: the selected currency is applied throughout the app.
  • Failure/recovery: selection failure shows a clear message.
  • Continuation: the preference is stored locally.

FR-10 — Custom currency creation (explicit) As an international user managing language and currency, I should create a custom currency by entering a currency name, currency symbol, optional currency code, and number of decimal places from 0 to 4, so that I can use currencies such as "My Currency", "Local Business Credits", or a user-defined symbol.

  • Trigger/input: custom currency form.
  • Observable result: the custom currency is created and applied throughout the app.
  • Failure/recovery: invalid decimal places (outside 0–4) or missing required fields show field-level messages.
  • Continuation: the custom currency is stored locally and selectable later.
Page 17 of 57

FR-11 — Currency used throughout and locale formatting (explicit) As an international user managing language and currency, I should see the selected currency used throughout the entire application with numbers formatted according to the selected language and locale, so that figures read correctly for me.

  • Trigger/input: any monetary display.
  • Observable result: amounts formatted with the selected currency and locale.
  • Failure/recovery: formatting never produces NaN or Infinity.
  • Continuation: formatting updates when language or currency changes.

FR-12 — Decimal-place support (explicit) As an international user managing language and currency, I should have currencies that use zero, two, or three decimal places supported, so that my currency's precision is respected.

  • Trigger/input: currency selection or custom decimal places.
  • Observable result: amounts display with the configured decimal places.
  • Failure/recovery: invalid decimal settings are rejected.
  • Continuation: precision persists with the currency.

FR-13 — Change currency at any time, stored locally (explicit) As an international user managing language and currency, I should change the currency at any time and have the currency preference stored locally, so that my choice persists.

  • Trigger/input: currency change.
  • Observable result: the new currency applies throughout and is stored.
  • Failure/recovery: storage failure shows a clear message.
  • Continuation: on reopening, the stored currency is applied.
Page 18 of 57

FR-14 — No automatic conversion; clear explanation (explicit) As an international user managing language and currency, I should never have changing the currency automatically convert monetary values using exchange rates, and I should see a clear explanation that changing the currency changes the display unit and does not convert existing amounts, so that I am not misled.

  • Trigger/input: currency change.
  • Observable result: existing amounts are unchanged numerically; the explanation is shown.
  • Failure/recovery: any conversion behavior is a defect.
  • Continuation: the user may change the currency again at any time.

FR-15 — No external currency API (explicit) As a small business owner / seller, I should use the app without an external currency API or paid service, so that the app remains free and self-contained.

  • Trigger/input: any currency operation.
  • Observable result: currency list and custom currencies work without external calls.
  • Failure/recovery: any external dependency is a defect.
  • Continuation: currency operations remain available offline once cached.

FR-16 — Dashboard metrics (explicit) As a small business owner / seller, I should see total sales, total costs, gross profit, net profit estimate, profit margin, number of products, and recent calculations on a modern, professional dashboard, so that I can assess my business at a glance.

  • Trigger/input: opening the Dashboard.
  • Observable result: all listed metrics and recent calculations are shown.
  • Failure/recovery: storage read failure shows a clear message and retry.
  • Continuation: metrics update as saved data changes.
Page 19 of 57

FR-17 — Dashboard date filters (explicit) As a small business owner / seller, I should filter dashboard values by Today, Last 7 days, Last 30 days, and All time, so that I can focus on a period.

  • Trigger/input: date-filter selection.
  • Observable result: dashboard values recompute for the selected period.
  • Failure/recovery: invalid period state falls back to a defined filter.
  • Continuation: the user can switch filters at any time.

FR-18 — Dashboard values from saved data; empty state (explicit) As a small business owner / seller, I should see dashboard values calculated from my saved data, not hardcoded demo numbers, and a helpful empty state when no data exists, so that the dashboard is truthful.

  • Trigger/input: opening the Dashboard with or without saved data.
  • Observable result: computed values when data exists; helpful empty state when none.
  • Failure/recovery: storage failure shows a clear message.
  • Continuation: adding data populates the dashboard.

FR-19 — Product profit calculator inputs (explicit) As a small business owner / seller, I should enter product name, unit cost, additional costs per unit, selling price per unit, and quantity sold, so that I can compute product profitability.

  • Trigger/input: the five listed inputs.
  • Observable result: inputs accepted and validated.
  • Failure/recovery: invalid inputs show field-level messages.
  • Continuation: valid inputs feed the derived calculations.
Page 20 of 57

FR-20 — Product profit calculator derived values (explicit) As a small business owner / seller, I should automatically see total unit cost, profit per unit, total revenue, total cost, total profit, profit margin percentage, and markup percentage, so that I understand the product's economics.

  • Trigger/input: valid inputs from FR-19.
  • Observable result: all seven derived values shown.
  • Failure/recovery: zero or invalid inputs handled safely.
  • Continuation: results can be saved to history.

FR-21 — Product profit formulas (explicit) As a small business owner / seller, I should have the calculations use exactly these formulas: Total unit cost = Unit cost + Additional costs per unit; Profit per unit = Selling price − Total unit cost; Total revenue = Selling price × Quantity sold; Total cost = Total unit cost × Quantity sold; Total profit = Total revenue − Total cost; Profit margin (%) = Total profit / Total revenue × 100 when revenue is greater than zero; Markup (%) = Profit per unit / Total unit cost × 100 when total unit cost is greater than zero, so that results are correct and predictable.

  • Trigger/input: valid inputs.
  • Observable result: results match the formulas exactly.
  • Failure/recovery: division-by-zero conditions suppress the corresponding percentage rather than producing NaN or Infinity.
  • Continuation: results remain visible.
Page 21 of 57

FR-22 — Safe handling of zero and invalid inputs (explicit) As a small business owner / seller, I should have zero values and invalid inputs handled safely, and I should never see NaN or Infinity, so that the app remains trustworthy.

  • Trigger/input: zero, negative, or malformed inputs.
  • Observable result: safe values or clear messages; never NaN or Infinity.
  • Failure/recovery: invalid input rejected with a message.
  • Continuation: correcting input restores valid results.

FR-23 — Selling price calculator inputs and formula (explicit) As a small business owner / seller, I should enter total unit cost and desired profit margin percentage and receive a recommended selling price using Selling price = Total unit cost / (1 − Desired margin / 100), so that I can price products to hit a target margin.

  • Trigger/input: total unit cost and desired margin.
  • Observable result: recommended selling price shown.
  • Failure/recovery: invalid inputs rejected with messages.
  • Continuation: results remain visible and can be adjusted.

FR-24 — Selling price margin rejection (explicit) As a small business owner / seller, I should have margins below 0% or greater than or equal to 100% rejected, so that the calculation stays mathematically valid.

  • Trigger/input: desired margin outside the allowed range.
  • Observable result: rejection with a clear message.
  • Failure/recovery: correcting the margin restores results.
  • Continuation: valid margins compute normally.
Page 22 of 57

FR-25 — Selling price expected profit and margin display (explicit) As a small business owner / seller, I should see the expected profit per unit and profit margin in the selling price calculator, so that I can verify the recommendation.

  • Trigger/input: valid selling price calculation.
  • Observable result: expected profit per unit and profit margin shown.
  • Failure/recovery: invalid inputs show messages instead.
  • Continuation: results update as inputs change.

FR-26 — Expense add/edit/delete (explicit) As a small business owner / seller, I should add an expense name, enter the amount, select a category, add a date, and edit and delete expenses, so that I can track spending.

  • Trigger/input: expense form and list controls.
  • Observable result: expense saved, updated, or removed in local storage.
  • Failure/recovery: invalid amount or missing field shows a message; storage failure shows a message.
  • Continuation: the list and summaries update.

FR-27 — Expense summaries by category and date (explicit) As a small business owner / seller, I should see expense summaries by category and by date, so that I can understand where money goes.

  • Trigger/input: expense data.
  • Observable result: category and date summaries shown.
  • Failure/recovery: no expenses shows an empty state.
  • Continuation: summaries update as expenses change.
Page 23 of 57

FR-28 — No double-counting of expenses (explicit) As a small business owner / seller, I should not have the same expense counted twice in the profit calculation, so that profit figures are accurate.

  • Trigger/input: profit calculation using expenses.
  • Observable result: each expense counted once.
  • Failure/recovery: any double-count is a defect to fix.
  • Continuation: profit figures remain accurate.

FR-29 — Break-even calculator inputs and formulas (explicit) As a small business owner / seller, I should enter fixed costs, selling price per unit, and variable cost per unit and receive Contribution per unit = Selling price − Variable cost, Break-even quantity = Fixed costs / Contribution per unit, and Break-even revenue = Break-even quantity × Selling price, so that I know when I break even.

  • Trigger/input: the three listed inputs.
  • Observable result: contribution, break-even quantity, and break-even revenue shown.
  • Failure/recovery: invalid inputs rejected with messages.
  • Continuation: results remain visible.

FR-30 — Break-even quantity rounded up (explicit) As a small business owner / seller, I should have the required break-even quantity rounded UP to the next whole unit, so that the quantity is achievable.

  • Trigger/input: break-even calculation.
  • Observable result: quantity rounded up to the next whole unit.
  • Failure/recovery: non-finite results suppressed.
  • Continuation: revenue computed from the rounded quantity.
Page 24 of 57

FR-31 — Break-even unreachable explanation (explicit) As a small business owner / seller, I should see an explanation that break-even cannot be reached under the current assumptions when the selling price is less than or equal to the variable cost, so that I understand the limitation.

  • Trigger/input: selling price ≤ variable cost.
  • Observable result: clear explanation shown instead of a break-even figure.
  • Failure/recovery: correcting inputs restores results.
  • Continuation: the user can adjust assumptions.

FR-32 — Product management (explicit) As a small business owner / seller, I should add, edit, delete, search, and sort products, and view product cost, selling price, and expected profit, so that I can manage my catalog.

  • Trigger/input: product form, search field, sort control, list controls.
  • Observable result: product list reflects changes; search and sort applied.
  • Failure/recovery: invalid product input shows a message; storage failure shows a message.
  • Continuation: changes persist locally.

FR-33 — Optional demo mode; empty workspace (explicit) As a small business owner / seller, I should have sample data included only in a clearly labeled optional demo mode and be able to start with a completely empty workspace, so that my data is never confused with samples.

  • Trigger/input: demo-mode toggle.
  • Observable result: sample data appears only when demo mode is enabled and is clearly labeled; default workspace is empty.
  • Failure/recovery: disabling demo mode removes sample data.
  • Continuation: the user's own data is unaffected.
Page 25 of 57

FR-34 — No registration, login, paid APIs, paid database, subscription, or external server (explicit) As a small business owner / seller, I should use the first version without user registration, login, paid APIs, a paid database, a subscription, or an external server, so that the app is free and private.

  • Trigger/input: any use of the app.
  • Observable result: no such requirements are imposed.
  • Failure/recovery: any such requirement is a defect.
  • Continuation: the app works locally.

FR-35 — Local storage persistence (explicit) As a small business owner / seller, I should have products, expenses, settings, and calculation history saved in IndexedDB or another appropriate local browser storage solution, persisting after refreshing or reopening the app on the same browser, so that my work is not lost.

  • Trigger/input: any data change.
  • Observable result: data persists across refresh and reopen on the same browser.
  • Failure/recovery: storage failure shows a clear message.
  • Continuation: data remains available.
Page 26 of 57

FR-36 — JSON export, CSV report export, JSON import, clear all (explicit) As an international user managing language and currency, I should export data to JSON, export reports to CSV, import a previously exported JSON backup, and clear all local data after an explicit confirmation, so that I can back up, move, and reset my data.

  • Trigger/input: export, import, or clear controls.
  • Observable result: file downloaded, backup imported, or data cleared after confirmation.
  • Failure/recovery: import validation failure explains the problem and does not save; clear requires explicit confirmation.
  • Continuation: the user can retry or continue working.

FR-37 — Validate imported data (explicit) As an international user managing language and currency, I should have imported data validated before saving, so that corrupt or invalid backups do not damage my workspace.

  • Trigger/input: JSON import.
  • Observable result: valid data saved; invalid data rejected with explanation.
  • Failure/recovery: rejection leaves existing data intact.
  • Continuation: the user can correct the file and retry.
Page 27 of 57

FR-38 — Local-storage privacy notice (explicit) As an international user managing language and currency, I should be clearly informed that local data may not automatically synchronize across different devices or browsers, and the app must not pretend that local browser storage is cloud storage, so that I understand the limits.

  • Trigger/input: viewing Data & Privacy (and relevant notices).
  • Observable result: the notice is shown.
  • Failure/recovery: any cloud-storage claim is a defect.
  • Continuation: the user can export data to move it.

FR-39 — Premium SaaS-inspired interface (explicit) As a small business owner / seller, I should use a premium-looking interface inspired by high-quality modern SaaS dashboards, so that the app feels professional and trustworthy.

  • Trigger/input: any page.
  • Observable result: the interface meets the design requirements in FR-40.
  • Failure/recovery: design defects fixed during testing.
  • Continuation: consistent across pages.

FR-40 — Design requirements (explicit) As a small business owner / seller, I should have a mobile-first responsive layout that works on Android, iPhone, tablets, and desktop browsers, with clean typography, accessible contrast, light and dark modes, professional dashboard cards, simple charts with useful labels, attractive empty states, clear forms and error messages, bottom navigation on mobile and a sidebar on desktop where appropriate, and smooth but subtle transitions, so that the app is usable and pleasant.

  • Trigger/input: any page at any viewport.
  • Observable result: all listed design properties present.
  • Failure/recovery: defects fixed during testing.
  • Continuation: consistent across pages.
Page 28 of 57

FR-41 — Avoid excess and small-screen usability (explicit) As a small business owner / seller, I should not encounter excessive animations, unnecessary gradients, clutter, or oversized headings, and the app must be usable on small phone screens, so that it stays focused and legible.

  • Trigger/input: any page on a small phone.
  • Observable result: no excessive animation, gradients, clutter, or oversized headings; usable on small screens.
  • Failure/recovery: defects fixed during testing.
  • Continuation: consistent across pages.

FR-42 — PWA if supported (explicit) As a small business owner / seller, I should have the application be a Progressive Web App if supported by the environment, with a web app manifest, appropriate app icons, a service worker for caching the app shell, an installation prompt or clear installation instructions, and offline access to the core calculator features after the app has been loaded and cached, so that I can install and use it offline.

  • Trigger/input: loading the app in a supporting environment.
  • Observable result: manifest, icons, service worker, installation prompt/instructions, and offline access to core calculators after caching.
  • Failure/recovery: unsupported environments show clear installation instructions instead.
  • Continuation: offline use of core calculators.

FR-43 — No premature offline claims (explicit) As a small business owner / seller, I should not be told offline support works until it has been implemented and tested, so that I am not misled.

  • Trigger/input: any offline claim.
  • Observable result: claims appear only after implementation and testing.
  • Failure/recovery: premature claims are defects.
  • Continuation: truthful communication.
Page 29 of 57

FR-44 — Calculation testing with known examples (explicit) As a small business owner / seller, I should have all major calculations tested with known examples — Test case 1 (unit cost 100, additional unit cost 20, selling price 200, quantity 10 → total unit cost 120, profit per unit 80, total revenue 2000, total cost 1200, total profit 800, profit margin 40%, markup ≈66.6667%), Test case 2 (total unit cost 60, desired margin 40% → selling price 100, profit per unit 40), and Test case 3 (fixed costs 1000, selling price 100, variable cost 60 → contribution per unit 40, break-even quantity 25, break-even revenue 2500) — so that the calculations are verified.

  • Trigger/input: running the tests.
  • Observable result: results match the expected values.
  • Failure/recovery: errors found are fixed.
  • Continuation: tests remain part of the build.

FR-45 — Additional testing coverage (explicit) As a small business owner / seller, I should have zero revenue, zero cost, negative input rejection where appropriate, decimal numbers, large amounts, different currency symbols, Arabic right-to-left layout, language switching, saving and restoring data, importing and exporting backups, and mobile responsiveness tested, and any errors found fixed, so that the app is reliable.

  • Trigger/input: running the tests.
  • Observable result: all listed cases tested and passing.
  • Failure/recovery: errors fixed.
  • Continuation: tests remain part of the build.
Page 30 of 57

FR-46 — Build the working application (explicit) As a small business owner / seller, I should receive the actual working application built in the current environment — interface generated, calculations implemented, all buttons connected, local storage added, and available tests run — so that I can use it immediately.

  • Trigger/input: build and run.
  • Observable result: working application with connected controls and local storage.
  • Failure/recovery: build errors fixed.
  • Continuation: the app runs.

FR-47 — Final deliverable documentation (explicit) As a small business owner / seller, I should receive a working preview, instructions for testing the app on a phone, instructions for installing it if PWA support is available, a summary of completed features, any known limitations, and instructions for exporting the source code and deploying it using a free hosting option, so that I can test, install, and deploy it.

  • Trigger/input: completion of the build.
  • Observable result: all six deliverables provided.
  • Failure/recovery: missing items are defects.
  • Continuation: the user can test, install, and deploy.
Page 31 of 57

FR-48 — Prioritize reliability, simplicity, privacy, working features (explicit) As a small business owner / seller, I should have the first version prioritize reliability, simplicity, privacy, and genuinely working features over unnecessary complexity, so that the app is dependable.

  • Trigger/input: any design or implementation decision.
  • Observable result: decisions favor reliability, simplicity, privacy, and working features.
  • Failure/recovery: unnecessary complexity is removed.
  • Continuation: the app remains dependable.

FR-49 — Local storage availability for all data (required_inference) As a small business owner / seller, I should have local browser storage available for products, expenses, settings, and calculation history, so that the accepted persistence journey is executable.

  • Trigger/input: any data change.
  • Observable result: data stored locally.
  • Failure/recovery: storage unavailable shows a clear message.
  • Continuation: data remains available on the same browser.

FR-50 — Device language detection with English fallback on first visit (required_inference) As an international user managing language and currency, I should have device language detection with English fallback on first visit, so that the accepted first-visit journey is executable.

  • Trigger/input: first visit.
  • Observable result: supported language applied; otherwise English.
  • Failure/recovery: detection failure falls back to English.
  • Continuation: the user may change language manually.
Page 32 of 57

FR-51 — Service worker and manifest cached before offline claims (required_inference) As a small business owner / seller, I should have the service worker and manifest cached before offline calculator use is claimed, so that offline claims are truthful.

  • Trigger/input: first load in a supporting environment.
  • Observable result: app shell cached; offline claims only after testing.
  • Failure/recovery: unsupported environments show instructions.
  • Continuation: offline use of core calculators.

4. User Personas

Page 33 of 57

Small business owner / seller

Product context. Shop owners, restaurant owners, freelancers, small businesses, and online sellers use ProfitMate to calculate product costs, selling prices, profits, margins, expenses, and break-even points without accounting knowledge. They work in the local workspace on their own device and browser, often on a phone while counting stock or pricing a product.

Primary goal. Understand business profitability quickly and correctly — what a product costs, what to charge, what was spent, and when the business breaks even — without accounting expertise.

Distinct accepted responsibilities.

  • Add and manage products (add, edit, delete, search, sort) and view cost, selling price, and expected profit.
  • Run the product profit calculator with product name, unit cost, additional costs per unit, selling price per unit, and quantity sold, and read the seven derived values.
  • Run the selling price calculator with total unit cost and desired margin, respecting the margin rejection rule.
  • Track expenses (add, edit, delete) with name, amount, category, and date, and read category and date summaries.
  • Run the break-even calculator with fixed costs, selling price per unit, and variable cost per unit, and understand when break-even cannot be reached.
  • Review the dashboard with date filters and recent calculations, and use the empty state when no data exists.
  • Optionally enable clearly labeled demo mode; otherwise start with a completely empty workspace.
Page 34 of 57

Relevant inputs or decisions. Business figures (costs, prices, quantities, margins, fixed and variable costs, expense amounts, categories, dates); date-filter selection; whether to enable demo mode; whether to save a calculation to history.

Interactions with other accepted participants. Shares the same local workspace and settings with the international user managing language and currency; the currency and language chosen there govern all figures and text this persona sees.

Observable success. Correct, NaN-free calculations; accurate dashboard totals from saved data; expenses counted once; break-even results rounded up and explained when unreachable; data persisting after refresh.

Page 35 of 57

International user managing language and currency

Product context. Users worldwide need the app to work regardless of country, language, or currency. They select or create a custom currency, switch interface language (including Arabic RTL), and manage local data through export, import, and clearing, expecting preferences and data to persist on the same browser.

Primary goal. Use ProfitMate in their own language and currency, with clear understanding of what local storage does and does not do, and the ability to back up, move, and reset their data.

Distinct accepted responsibilities.

  • Select a language from English, Arabic, French, Spanish, Portuguese, and German; rely on device detection with English fallback on first visit; change language manually at any time; have the selection remembered.
  • Select a currency from the world list or create a custom currency (name, symbol, optional code, decimal places 0–4); change currency at any time; have the preference stored locally.
  • Understand that changing the currency changes the display unit and does not convert existing amounts.
  • Export data to JSON, export reports to CSV, import a previously exported JSON backup (validated before saving), and clear all local data after explicit confirmation.
  • Understand that local data may not automatically synchronize across different devices or browsers and is not cloud storage.

Relevant inputs or decisions. Language choice; currency choice or custom currency definition; theme (light/dark); export/import/clear decisions; confirmation of clearing.

Page 36 of 57

Interactions with other accepted participants. Shares the same local workspace and settings with the small business owner / seller; the language and currency chosen here govern all figures and text that persona sees.

Observable success. Interface fully translated with correct RTL/LTR direction; monetary values formatted per language and locale with the correct decimal places; no automatic conversion; validated imports; confirmed clearing; truthful privacy notice.

5. Core User Flows

Flow A — First visit and language setup (International user managing language and currency)

  1. The user opens ProfitMate for the first time on their device.
  2. The app detects the device's preferred language; if supported (English, Arabic, French, Spanish, Portuguese, German), it applies it; otherwise it defaults to English. (Landing)
  3. The user reviews the Landing page's purpose, calculators, languages, currency capability, and privacy posture.
  4. The user opens the language selector and chooses a language; the interface updates immediately, with RTL for Arabic and LTR for others. (Landing / Settings)
  5. The selection is stored locally; on reopening, the remembered language is applied.
  6. Failure/recovery: if the selection cannot be saved, a clear message appears and the user can retry.
  7. Continuation: the user enters the local workspace.
Page 37 of 57

Flow B — Currency selection and custom currency (International user managing language and currency)

  1. The user opens the currency selector. (Settings / top bar)
  2. The user chooses a currency from the world list (including USD, EUR, GBP, DZD, CAD, AUD, MAD, SAR, AED, EGP, INR, JPY, CNY, BRL, MXN, CHF, TRY, ZAR, and other commonly used ISO 4217 currencies where practical) or creates a custom currency by entering name, symbol, optional code, and decimal places 0–4. (Settings)
  3. The app applies the currency throughout the application and formats numbers according to the selected language and locale, supporting zero, two, or three decimal places.
  4. The app shows the explanation that changing the currency changes the display unit and does not convert existing amounts; existing amounts are unchanged numerically.
  5. The preference is stored locally; on reopening, the stored currency is applied.
  6. Failure/recovery: invalid custom currency fields (e.g., decimal places outside 0–4) show field-level messages; the user corrects them.
  7. Continuation: the user proceeds to work with figures in the chosen currency.
Page 38 of 57

Flow C — Product profit calculation (Small business owner / seller)

  1. The user opens the Product Profit Calculator. (Product Profit Calculator)
  2. The user enters product name, unit cost, additional costs per unit, selling price per unit, and quantity sold.
  3. The app validates inputs; invalid inputs show field-level messages and negative values are rejected where appropriate.
  4. The app computes total unit cost, profit per unit, total revenue, total cost, total profit, profit margin percentage, and markup percentage using the exact formulas, suppressing percentages when revenue or total unit cost is zero rather than showing NaN or Infinity.
  5. The user reads the results in the ruled summary table, formatted in the selected currency and locale.
  6. The user optionally saves the calculation to history.
  7. Failure/recovery: zero revenue or zero cost is handled safely; correcting invalid input restores results.
  8. Continuation: the saved calculation appears in the dashboard's recent calculations.
Page 39 of 57

Flow D — Selling price calculation (Small business owner / seller)

  1. The user opens the Selling Price Calculator. (Selling Price Calculator)
  2. The user enters total unit cost and desired profit margin percentage.
  3. The app rejects margins below 0% or greater than or equal to 100% with a clear message.
  4. For valid margins, the app computes the recommended selling price using Selling price = Total unit cost / (1 − Desired margin / 100).
  5. The app displays the expected profit per unit and profit margin.
  6. Failure/recovery: correcting the margin restores results.
  7. Continuation: the user may adjust inputs and compare recommendations.

Flow E — Expense tracking (Small business owner / seller)

  1. The user opens the Expense Tracker. (Expense Tracker)
  2. The user adds an expense name, enters the amount, selects a category, and adds a date.
  3. The app validates the input; invalid amounts or missing fields show messages.
  4. The app saves the expense locally and shows it in the list.
  5. The user edits or deletes expenses as needed; the list and summaries update.
  6. The user reads expense summaries by category and by date.
  7. The app ensures the same expense is not counted twice in the profit calculation.
  8. Failure/recovery: storage failure shows a clear message; the user retries.
  9. Continuation: the dashboard reflects the updated expense data.
Page 40 of 57

Flow F — Break-even calculation (Small business owner / seller)

  1. The user opens the Break-Even Calculator. (Break-Even Calculator)
  2. The user enters fixed costs, selling price per unit, and variable cost per unit.
  3. The app computes contribution per unit = Selling price − Variable cost.
  4. If the selling price is less than or equal to the variable cost, the app explains that break-even cannot be reached under the current assumptions.
  5. Otherwise, the app computes break-even quantity = Fixed costs / Contribution per unit, rounds it UP to the next whole unit, and computes break-even revenue = Break-even quantity × Selling price.
  6. The app displays the results in the ruled summary table and the break-even chart with a labelled intersection point and a fixed-costs baseline.
  7. Failure/recovery: invalid inputs show messages; correcting them restores results.
  8. Continuation: the user may adjust assumptions and recompute.

Flow G — Product management (Small business owner / seller)

  1. The user opens Products. (Products)
  2. The user adds a product; the app validates input and saves it locally.
  3. The user edits or deletes products; the list updates.
  4. The user searches products and sorts them; the list reflects the query and sort.
  5. The user views product cost, selling price, and expected profit.
  6. The user may enable clearly labeled demo mode to see sample data; otherwise the workspace remains completely empty.
  7. Failure/recovery: invalid input shows a message; storage failure shows a message.
  8. Continuation: the dashboard and calculators reflect the updated products.
Page 41 of 57

Flow H — Dashboard review (Small business owner / seller)

  1. The user opens the Dashboard. (Dashboard)
  2. The app reads saved data and computes total sales, total costs, gross profit, net profit estimate, profit margin, number of products, and recent calculations.
  3. The user selects a date filter (Today, Last 7 days, Last 30 days, All time); values recompute for the period.
  4. The user reads the charts with useful labels and the recent-calculations list.
  5. If no data exists, the app shows a helpful empty state with an "Add your first product" button.
  6. Failure/recovery: storage read failure shows a clear message and retry.
  7. Continuation: the user navigates to add data or review other pages.
Page 42 of 57

Flow I — Data export, import, and clearing (International user managing language and currency)

  1. The user opens Data & Privacy. (Data & Privacy)
  2. The app shows the privacy notice that data is stored locally, may not automatically synchronize across different devices or browsers, and is not cloud storage.
  3. The user exports data to JSON or exports reports to CSV; the file downloads.
  4. The user imports a previously exported JSON backup; the app validates the data before saving.
  5. If validation fails, the app explains the problem and does not save; existing data remains intact.
  6. If validation succeeds, the app saves the imported data.
  7. The user clears all local data after an explicit confirmation.
  8. Failure/recovery: storage failure shows a clear message; the user retries.
  9. Continuation: the user continues working with the restored or cleared workspace.
Page 43 of 57

Flow J — PWA installation and offline use (Small business owner / seller)

  1. The user loads the app in a supporting environment. (Landing)
  2. The app registers the service worker and caches the app shell; the manifest and icons are available.
  3. The app shows an installation prompt or clear installation instructions.
  4. After the app has been loaded and cached, the user accesses the core calculator features offline.
  5. Offline support is claimed only after it has been implemented and tested.
  6. Failure/recovery: in unsupported environments, clear installation instructions are shown instead.
  7. Continuation: the user uses the core calculators offline.
Page 44 of 57

6. Visuals Colors and Theme

The creative direction is authoritative: Typographic infrastructure for everyday profit — Fira Sans order with signal-line colour, after Erik Spiekermann. The register is "reliable instrument you can read at a glance" — warm competence, not fintech gloss and not editorial swagger.

Light mode tokens

  • Background (warm paper ground): #F4F1EA
  • Surface (cards): #FFFDF8
  • Hairline: #DED8CB (1px)
  • Text (ink): #1A1A18 (14.5:1 on the ground)
  • Primary / revenue / profit-positive signal: #0F6B4F (5.6:1 on paper)
  • Accent / negative / loss / error / active date-filter underline: #E0531F (never for large fills)
  • Muted (labels, secondary metadata): #6E6A61
  • Transit yellow (4px rule under section headers; break-even chart line only; never behind text): #F2B705

Dark mode tokens

  • Background: #17181A
  • Surface: #202225
  • Text: #F2EFE7
  • Primary: #3FA57F
  • Accent: #FF7A45
  • Hairline, muted, and transit yellow follow the same roles at adjusted lightness.
Page 45 of 57

Typography

  • Headings: Fira Sans 600 for section and page titles, 500 for card labels; tight −0.01em tracking; sentence case; never all-caps for sentences.
  • Numerals: Fira Sans with font-variant-numeric: tabular-nums and 600 weight so columns align like a timetable.
  • Micro-labels (field labels, table headers, date-filter chips): 500 at 12px with 0.06em tracking. True wayfinding labels (section numbers, currency code, nav items) uppercase at 11px/0.12em.
  • Body: Fira Sans.
  • Scale: 1.25 modular on a 4px baseline — 12 / 13 / 15 / 16 / 20 / 25 / 31 / 39.
  • Hero/dashboard headline: clamp(26px, 4vw, 39px). The single largest money figure (net profit): clamp(32px, 6vw, 52px) with tabular numerals. Card values 20–25px. Body 15–16px with 1.55 line-height. Helper/validation text 13px. Nothing above 52px.

Shape language

  • Rectangles with 6px radius on cards, inputs, and buttons; 2px radius on chips. No pills, no blobs, no soft offset shadows.
  • Depth from a single 1px hairline (#DED8CB) plus an optional 0 1px 0 rgba(26,26,24,0.04) edge.
  • Inputs 44px tall with a 1.5px border that turns green on focus and vermilion on error, with the error message directly beneath in 13px.
  • Section headers sit on a 4px transit-yellow rule; tables use ruled rows, not zebra fills.
Page 46 of 57

Layout

  • Mobile-first single column at 375px: sticky top bar (wordmark left; language, currency, and theme controls right; all 44px tap targets), content, and a 5-item bottom navigation (Dashboard, Calculator, Products, Expenses, Break-even) with 11px uppercase labels under 20px line icons.
  • At 768px the bottom nav becomes a left rail of icons + labels 72px wide and cards go two-up.
  • At 1280px a 240px sidebar carries numbered sections (01 Dashboard … 05 Break-even) plus language/currency/theme in its footer; content max-width 1120px in a 12-column grid; dashboard KPIs in a 4-across row with the net-profit card spanning two columns.
  • Every page begins with a left-aligned 31–39px title, a one-line description in muted, and a right-aligned primary action; forms are two-column at 768px with labels above fields and computed results in a ruled summary table, never in floating cards.

Imagery

  • No photography and no illustration for decoration. The visual content is the data itself: a horizontal bar chart of sales vs costs vs profit per date filter, a category breakdown as ruled bars with amounts right-aligned in tabular numerals, and a break-even chart with a labelled intersection point and a fixed-costs baseline.
  • Icons are 1.5px-stroke pictograms in the transit-line style (calculator, box, receipt, chart, scale).
  • Empty states use one large 48px line pictogram, a short sentence, and a single primary button.
Page 47 of 57

Avoid

  • Violet, indigo, or blue-on-white SaaS palette; gradient blobs or glassmorphism panels.
  • Oversized display headlines or marketing-style hero copy above the dashboard — the app opens on working data.
  • Identical hover-lift card grids; use ruled bands and tables instead.
  • Pill-shaped buttons, soft drop shadows, and 20px+ corner radii.
  • Decorative photography, 3D renders, or character illustration.
  • Count-up number animations, parallax, or scroll-jacking.
  • All-caps body text or letterspaced lowercase labels that hurt legibility in Arabic RTL.
  • Hiding computed values behind a "calculate" reveal — results must always be visible and never show NaN or Infinity.

Readable text and controls stay whole at every viewport: headlines, wordmarks, labels, numbers, cards' text, and controls stay entirely inside the viewport and their container at 375px, 768px, and 1280px, wrapping or scaling (e.g., font-size: clamp(...) with its mobile size) to fit, and no other element covers any part of them. Imagery, decoration, and motion may be cropped, bled, rotated, overlapped, or cut as the direction asks, as long as they cover no readable text or control. With prefers-reduced-motion, provide a usable static arrangement.

Page 48 of 57

7. Signature Design Concept

The public entry is the Landing page, and the first working screen is the Dashboard. The signature concept is a ruled instrument panel on warm paper:

  • Warm paper ground #F4F1EA with a sticky top bar carrying the wordmark left and language, currency, and theme controls right, all 44px tap targets.
  • Landing composition: a left-aligned title in Fira Sans 600 at clamp(26px, 4vw, 39px), a one-line muted description of ProfitMate's purpose and audience, a capability summary of the calculators and tools, a privacy statement (local-only, no registration or login), and a single primary entry control into the local workspace. No hardcoded demo numbers are presented as the user's data.
  • Dashboard composition: a left-aligned "Dashboard" title with the date-filter chips (Today / 7 days / 30 days / All time) on the same baseline to the right, underlined in vermilion when active. Directly beneath, a full-width ruled KPI band — four cells separated by vertical hairlines, each with an 11px uppercase tracked label above a 25px tabular figure — where the Net profit cell is the largest (clamp(32px, 6vw, 52px)) and carries a small green or vermilion delta chip. Below it, a two-thirds/one-third split: a flat bar chart of revenue vs cost vs profit with axis labels in 12px muted, and a "Recent calculations" ruled list where each row shows product name, quantity, and a right-aligned profit figure.
  • Empty state: when there is no data, the KPI band collapses into one bordered empty panel with a 48px line pictogram, one sentence, and an "Add your first product" button — the layout never pretends to hold numbers it does not have.
Page 49 of 57
  • Signature moves: the ruled KPI band instead of floating cards; transit-line colour semantics used consistently (green = revenue/profit/positive, vermilion = cost/loss/error, transit yellow = the 4px rule under every section header and the break-even chart line); numbered sidebar wayfinding (01 Dashboard, 02 Calculator, 03 Products, 04 Expenses, 05 Break-even) that becomes a 5-item labelled bottom nav on mobile, with the active item marked by a vermilion 2px top rule rather than a filled pill; calculated results rendered as a ruled summary table directly under the form — label left in muted, value right in 600 tabular numerals, hairline between rows — so profit margin, markup, and totals read like a printed receipt; and a currency/language control pair in the top bar that opens a native-feeling sheet listing currencies by code with their symbol, plus a custom-currency form, with an inline note that the display unit changed and amounts were not converted.
Page 50 of 57

8. Interaction Model & Motion Direction

Interaction Model: Animated Motion Tempo: restrained Hero Dimensionality: flat

Landing Hero Motion Brief

  • Focal subject: the warm paper ground, the Fira Sans wordmark, and the ruled capability summary — the data-as-content instrument, not a marketing hero.
  • Input → transformation → outcome thesis: as the user selects a language or currency from the top bar, the interface text and monetary formatting transform in place (RTL for Arabic, LTR for others; locale-formatted numbers with the configured decimal places), and the outcome is a fully translated, correctly formatted working surface — with an inline note that the display unit changed and amounts were not converted.
  • Motion vocabulary: restrained and mechanical — 120ms ease-out on focus rings, button press, and tab underline; numbers update instantly with no count-up; page transitions are a 160ms opacity fade only; the break-even chart line draws once on first reveal (400ms) and then stays still.
  • Composed first frame: warm paper ground, sticky top bar with wordmark left and language/currency/theme controls right, left-aligned title, one-line muted description, capability summary, privacy statement, and a single primary entry control.
  • Reduced-motion state: prefers-reduced-motion removes the fade and the line draw; all content remains visible and usable in a static arrangement.

No 3D/WebGL scene is required; the direction's hero dimensionality is flat.

Page 51 of 57

9. Non-Functional Requirements

  • NFR-01 — Local-first persistence (explicit): Products, expenses, settings, and calculation history are saved in IndexedDB or another appropriate local browser storage solution and persist after refreshing or reopening the app on the same browser. Rationale: the first version must work without registration, login, paid APIs, a paid database, a subscription, or an external server.
  • NFR-02 — No identity or cloud dependency (explicit): The first version must work without user registration, login, paid APIs, a paid database, a subscription, or an external server. Rationale: privacy and simplicity.
  • NFR-03 — No external currency API (explicit): Currency selection and custom currencies must not require an external currency API or paid service. Rationale: free, self-contained operation.
  • NFR-04 — No automatic conversion (explicit): Changing the currency must never convert monetary values using exchange rates; the app must clearly explain that changing the currency changes the display unit and does not convert existing amounts. Rationale: prevent misleading figures.
  • NFR-05 — Truthful privacy communication (explicit): The app must clearly inform users that local data may not automatically synchronize across different devices or browsers and must not pretend that local browser storage is cloud storage. Rationale: user trust.
  • NFR-06 — Truthful offline claims (explicit): Offline support must not be claimed until it has been implemented and tested. Rationale: user trust.
  • NFR-07 — No NaN or Infinity (explicit): The app must never display NaN or Infinity; zero values and invalid inputs are handled safely. Rationale: trustworthiness of calculations.
  • NFR-08 — Margin rejection (explicit): Margins below 0% or greater than or equal to 100% are rejected in the selling price calculator. Rationale: mathematical validity.
Page 52 of 57
  • NFR-09 — Break-even rounding (explicit): The required break-even quantity is rounded UP to the next whole unit. Rationale: achievable quantity.
  • NFR-10 — Confirmed clearing (explicit): All local data is cleared only after an explicit confirmation. Rationale: prevent accidental data loss.
  • NFR-11 — Import validation (explicit): Imported data is validated before saving. Rationale: protect the workspace from corrupt backups.
  • NFR-12 — No double-counting (explicit): The same expense must not be counted twice in the profit calculation. Rationale: accurate profit figures.
  • NFR-13 — Demo data isolation (explicit): Sample data appears only in a clearly labeled optional demo mode; users can start with a completely empty workspace. Rationale: avoid confusing samples with real data.
  • NFR-14 — Design restraint (explicit): Avoid excessive animations, unnecessary gradients, clutter, and oversized headings; the app must be usable on small phone screens. Rationale: focus and legibility.
  • NFR-15 — Accessibility and responsiveness (explicit): Accessible contrast; mobile-first responsive layout working on Android, iPhone, tablets, and desktop browsers; light and dark modes; bottom navigation on mobile and a sidebar on desktop where appropriate; smooth but subtle transitions. Rationale: usability across devices.
  • NFR-16 — Translation completeness (explicit): All interface text, buttons, labels, menus, messages, validation errors, and reports are translated; RTL for Arabic and LTR for other languages. Rationale: international usefulness.
  • NFR-17 — Reliability and simplicity priority (explicit): The first version prioritizes reliability, simplicity, privacy, and genuinely working features over unnecessary complexity. Rationale: dependable first release.
Page 53 of 57
  • NFR-18 — Testing (explicit): All major calculations are tested with the three known examples and the additional cases (zero revenue, zero cost, negative input rejection where appropriate, decimal numbers, large amounts, different currency symbols, Arabic RTL layout, language switching, saving and restoring data, importing and exporting backups, mobile responsiveness); errors found are fixed. Rationale: verified correctness.

10. Tech Stack

  • Frontend: React application UI (provisioned scaffold), mobile-first, with light/dark modes, RTL/LTR support, and a PWA manifest, icons, and service worker where supported.
  • Backend: shared FastAPI process for application APIs and domain modules (provisioned scaffold). The first-version product behavior is local-first and does not require an external server for its core function; the backend is available infrastructure and does not introduce registration, login, cloud storage, or any product capability beyond this document.
  • Database: MariaDB for application-owned persistent data (provisioned scaffold). The first-version product's user data lives in local browser storage; the provisioned database does not justify domain entities, authentication, or an ER diagram.
  • Local storage: IndexedDB or another appropriate local browser storage solution for products, expenses, settings, and calculation history.
  • PWA: web app manifest, appropriate app icons, and a service worker for caching the app shell, where supported by the environment.
  • Deployment: free hosting option for the built application, with instructions for exporting the source code.
Page 54 of 57

11. Assumptions and Constraints

Assumptions

  • The user's browser supports IndexedDB or an equivalent local browser storage solution; if not, the app shows a clear message and does not claim persistence.
  • The device language is available to the app for first-visit detection; if detection fails, English is used.
  • PWA support depends on the environment; where unsupported, clear installation instructions are shown instead.
  • The provisioned backend and database are infrastructure available to the environment and do not change the product's local-first, no-identity behavior.
Page 55 of 57

Constraints

  • The first version must work without user registration, login, paid APIs, a paid database, a subscription, or an external server.
  • Do not require an external currency API or paid service.
  • Never assume that changing the currency automatically converts monetary values using exchange rates.
  • Do not pretend that local browser storage is cloud storage; clearly inform users that local data may not automatically synchronize across different devices or browsers.
  • Do not claim that offline support works until it has been implemented and tested.
  • Include sample data only in a clearly labeled optional demo mode; users must be able to start with a completely empty workspace.
  • Do not count the same expense twice in the profit calculation.
  • Never display NaN or Infinity.
  • Reject margins below 0% or greater than or equal to 100% in the selling price calculator.
  • Round the required break-even quantity UP to the next whole unit.
  • Clear all local data only after an explicit confirmation.
  • Validate imported data before saving it.
  • Avoid excessive animations, unnecessary gradients, clutter, and oversized headings.
  • The first version must prioritize reliability, simplicity, privacy, and genuinely working features over unnecessary complexity.
  • Do not stop after providing a plan or code snippets; build the actual working application in the current environment.

12. Glossary

Page 56 of 57
  • ProfitMate: The free, mobile-first business profit calculator described in this document.
  • Local workspace: The user's products, expenses, settings, and calculation history stored in the browser's local storage.
  • Local browser storage: IndexedDB or another appropriate local browser storage solution used to persist data on the same browser.
  • Total unit cost: Unit cost + Additional costs per unit.
  • Profit per unit: Selling price − Total unit cost.
  • Total revenue: Selling price × Quantity sold.
  • Total cost: Total unit cost × Quantity sold.
  • Total profit: Total revenue − Total cost.
  • Profit margin (%): Total profit / Total revenue × 100, when revenue is greater than zero.
  • Markup (%): Profit per unit / Total unit cost × 100, when total unit cost is greater than zero.
  • Recommended selling price: Total unit cost / (1 − Desired margin / 100).
  • Contribution per unit: Selling price − Variable cost.
  • Break-even quantity: Fixed costs / Contribution per unit, rounded UP to the next whole unit.
  • Break-even revenue: Break-even quantity × Selling price.
  • Custom currency: A user-defined currency with name, symbol, optional code, and decimal places from 0 to 4.
  • Demo mode: A clearly labeled optional mode that includes sample data; the default workspace is completely empty.
  • PWA (Progressive Web App): An installable web application with a manifest, icons, and a service worker for caching the app shell.
  • RTL / LTR: Right-to-left layout for Arabic; left-to-right layout for other languages.
  • ISO 4217: The international standard for currency codes used in the world currency list.
Page 57 of 57

No completed page designs yet.

Completed design pages will appear here when they are ready to preview.

Landing: Review purpose and privacy
Landing: Open language selector
Landing: Select language
Landing: Open currency selector
Landing: Select currency
Landing: Enter local workspace
Settings: Change language
Settings: Select world currency
Settings: Create custom currency
Settings: Toggle theme
Settings: Read currency-change note
Data & Privacy: Read privacy notice
Data & Privacy: Export data to JSON
Data & Privacy: Export reports to CSV
Data & Privacy: 1. Import JSON backup
Data & Privacy: Confirm clear all data
Data & Privacy: 2. Review import validation error
Data & Privacy: 3. Retry import with corrected file

No completed page designs yet.

Completed design pages will appear here when they are ready to preview.

Landing: Review purpose and privacy
Landing: Open language selector
Landing: Select language
Landing: Open currency selector
Landing: Select currency
Landing: Enter local workspace
Settings: Change language
Settings: Select world currency
Settings: Create custom currency
Settings: Toggle theme
Settings: Read currency-change note
Data & Privacy: Read privacy notice
Data & Privacy: Export data to JSON
Data & Privacy: Export reports to CSV
Data & Privacy: 1. Import JSON backup
Data & Privacy: Confirm clear all data
Data & Privacy: 2. Review import validation error
Data & Privacy: 3. Retry import with corrected file