barber-shops-reservations

byKhayredinne Saadi

Build **BarberFlow**, a modern SaaS manager backoffice for barber shops using React, TypeScript, Vite, Tailwind CSS, shadcn/ui, and Lucide React. Create a premium, responsive dashboard with a dark sidebar, clean light interface, and French-language UI. Include Overview, Reservations, Calendar, Customers, Barbers, Services & Pricing, Availability, Reports, and Settings. Prioritize reservation management: display today's appointments, pending confirmations, completed bookings, cancellations, and estimated revenue. Implement searchable and filterable reservations, calendar views, appointment details, and a complete booking flow with customer, service, barber, date, and available time selection. Allow managers to create, edit, confirm, reschedule, cancel, and complete appointments. Manage customers, barbers, services, prices, working hours, breaks, and availability. Prevent overlapping bookings and validate time slots. Use realistic mock data with local persistence, reusable components, strict TypeScript, form validation, and a clean feature-based architecture. Use TND as the default currency. Prepare API services and multi-tenant architecture for future backend integration, a React Native customer app, and a SaaS super-admin dashboard. Make all navigation and main actions functional. Start with the application layout, Overview dashboard, and Reservations page. Build a working application, not just a static

No preview

Comments (0)

No comments yet. Be the first!

System Requirements

System Requirements Document for barber-shops-reservations

1. Introduction

BarberFlow is a modern SaaS manager backoffice for barber shops, delivered as a working application rather than a static mockup. It is built for the owner-manager of a barber shop in Tunisia who stands at the counter between clients, works in French, prices in Tunisian Dinar (TND), and needs to trust the day's numbers in three seconds and act on a booking in two taps.

The product intent is calm, competent, humane order: a booking ledger that reads like a transit timetable. The manager opens the tool at the start of the day, sees today's appointments, pending confirmations, completed bookings, cancellations and estimated revenue, then creates, edits, confirms, reschedules, cancels and completes appointments while keeping customers, barbers, services, prices, working hours, breaks and availability accurate. Overlapping bookings are prevented and time slots are validated so the chair-by-chair schedule stays conflict-free.

The audience is the Barber Shop Manager — the single accepted active human persona for this generation. The interface language is French, the default currency is TND, and the application is prepared for future backend integration, a React Native customer app, and a SaaS super-admin dashboard without building those now.

Page 1 of 56

2. System Overview

BarberFlow is a responsive, French-language dashboard with a dark sidebar (graphite chrome rail) and a clean light working surface. It is a client-side application built with React, TypeScript, Vite, Tailwind CSS, shadcn/ui and Lucide React, using realistic mock data with local persistence so the manager's work survives across sessions.

Current delivery covers the application layout, the Overview dashboard, the Reservations page, the Calendar, appointment details, the complete booking flow, and the administration of customers, barbers, services and prices, working hours, breaks and availability, plus Reports and Settings. All navigation and main actions are functional.

The accepted active human actor is the Barber Shop Manager. The application owns identity: a manager enrolls on first use and verifies on return before reaching protected pages. Local persistence keeps mock data across sessions. Multi-tenancy is prepared architecturally (tenant-scoped data and API service seams) but no super-admin surface, no customer mobile app, and no live backend are part of the current build.

Page 2 of 56

2a. Product Interpretation and Delivery Boundary

BarberFlow is delivered as a first-party web application. The manager's working surfaces — Overview, Reservations, Calendar, appointment details, the booking flow, Customers, Barbers, Services & Pricing, Availability, Reports and Settings — are protected and require the manager to be signed in. Because the manager must privately own and resume durable shop state (appointments, customers, barbers, services, availability, settings) across sessions, the application owns identity: a public Landing explains the product, Sign Up establishes a manager's first-use access, and Login verifies a returning manager. These three entry surfaces are anonymously reachable; everything behind them is not.

The current build is entirely first-party and self-contained: data is realistic mock data persisted locally, and API service modules plus tenant-scoped structures are prepared as seams for a future backend. The React Native customer app and the SaaS super-admin dashboard are explicitly future scope and are not built, routed, or reachable now. No provider-owned or external destination carries accepted manager work in this generation.

2b. Source Content Inventory

Not applicable — no reference directive in this request declares a content_source.

2c. Page Content and Component Coverage

Page 3 of 56

Landing

  • Information/state: Anonymous public entry explaining the BarberFlow manager backoffice before sign-in. Presents the product as a working tool for running a barber shop's day: reservations, calendar, customers, barbers, services and pricing, availability, reports and settings. French-language copy throughout.
  • Primary actions: Go to Sign Up (start using BarberFlow); go to Login (returning manager).
  • Supporting actions: Navigate to the sign-in entry points from any section of the page.
  • Domain entities: Product description content only; no shop data is exposed.
  • Component responsibilities: A ruled panel carrying a single high-contrast black-and-white photograph of a chair and mirror, cropped to the grid and treated as a ruled panel (documentary, not lifestyle); a wordmark in Fira Sans 600 with a signal-red square period; an ALL-CAPS eyebrow, a page title, and a full-width 1px rule; entry controls for Sign Up and Login.
  • States: Loading (hairline skeleton for the panel); empty (not applicable — static entry content); success (entry controls available); error (if the entry route fails to resolve, a plain French message with a retry that returns to the same entry); recovery (retry re-renders the entry without losing the manager's place).
Page 4 of 56

Login

  • Information/state: Returning manager verification for the protected backoffice. French labels and validation messages.
  • Primary actions: Submit credentials to sign in and reach the protected backoffice.
  • Supporting actions: Navigate to Sign Up if the manager has no access yet; return to Landing.
  • Domain entities: Manager identity (email/identifier and secret), session state.
  • Component responsibilities: A form with labeled inputs, inline validation, a submit control, and a link to Sign Up. No protected shop data is rendered here.
  • States: Loading (submit in progress, control disabled); empty (blank form); success (redirect into the protected backoffice); error (invalid credentials or failed verification, shown inline in French, form preserved for correction); recovery (correct and resubmit without re-entering everything).
Page 5 of 56

Sign Up

  • Information/state: Self-service first-use enrollment for a manager starting to use BarberFlow. French labels and validation messages.
  • Primary actions: Submit enrollment details to establish the manager's access.
  • Supporting actions: Navigate to Login if access already exists; return to Landing.
  • Domain entities: Manager identity being established, tenant/shop association for the new manager.
  • Component responsibilities: A form with labeled inputs, inline validation, a submit control, and a link to Login.
  • States: Loading (submit in progress, control disabled); empty (blank form); success (access established and the manager proceeds into the protected backoffice); error (validation failure or enrollment failure, shown inline in French, entered values preserved); recovery (correct the flagged fields and resubmit).
Page 6 of 56

Overview

  • Information/state: The day's control panel. A ruled KPI band with five figures — today's appointments, pending confirmations, completed bookings, cancellations, and estimated revenue in TND — each with a small-caps label above and a signed delta below. A 24-hour appointment density strip beneath the band. A two-column split: today's timeline on the left, next-up queue on the right.
  • Primary actions: Open an appointment from the timeline or the next-up queue to reach Appointment Details; confirm the oldest unconfirmed booking from the rail's persistent action.
  • Supporting actions: Click a density-strip bar to scroll the day timeline to that hour; navigate to Reservations, Calendar, or any other section from the rail.
  • Domain entities: Appointments (time, state, customer, service, barber), estimated revenue in TND, pending count, next appointment time.
  • Component responsibilities: KPI band as a ruled ledger (five oversized tabular figures separated by full-height 1px hairlines, no cards); 24-hour density strip (48 hairline bars, one per 30 minutes, height proportional to bookings, current slot in signal red, doubling as a click target); today's timeline; next-up queue of three appointment rows, each with a 4px state rule, tabular time, client name, service and barber initials; persistent graphite rail footer showing the live pending count, the next appointment countdown in tabular figures, and a signal-red "Confirmer" action.
  • States: Loading (hairline skeletons that pulse opacity, not shimmering blocks); empty (no appointments today — the KPI band shows zeroes and the timeline shows a plain French empty line, not a large illustration); success (figures and timeline rendered); error (if the day's data cannot be read, a plain French message with a retry that reloads the day); recovery (retry restores the band and timeline without leaving Overview).
Page 7 of 56

Reservations

  • Information/state: A dense, searchable and filterable table of reservations. Sticky header, 44px rows, a 4px state rule at the left edge of each row, a right-aligned tabular TND column, and filters as a horizontal chip row above the rule.
  • Primary actions: Search reservations; filter by state and other reservation attributes; open a reservation to reach Appointment Details; start a new appointment.
  • Supporting actions: Sort and scan the table; use the filter chips to narrow the list; clear filters.
  • Domain entities: Appointments with state (en attente, confirmé, terminé, annulé, no-show), customer, service, barber, date and time, price in TND.
  • Component responsibilities: Search input; horizontal filter chip row using the same state hues as the rest of the app; dense table with sticky header and tabular figures; row-level state rule and small-caps state chip; a control to start a new appointment.
  • States: Loading (hairline skeleton rows); empty (no reservations match — a plain French line with a control to clear filters); success (rows rendered with aligned TND amounts); error (if the list cannot be read, a plain French message with a retry that reloads the list); recovery (retry restores the table with the manager's search and filters intact).
Page 8 of 56

Appointment Details

  • Information/state: The focused view of one appointment: customer, service, barber, date, time, price in TND, and current state. This is where the manager edits, confirms, reschedules, cancels or completes the appointment.
  • Primary actions: Confirm the appointment; reschedule it; cancel it; complete it; edit its details.
  • Supporting actions: Return to Reservations or Calendar; open the customer or barber record referenced by the appointment.
  • Domain entities: A single appointment and its references to customer, service, barber, date, time, price and state.
  • Component responsibilities: A detail panel with the appointment's fields; state chip and 4px state rule in the appointment's hue; action controls for confirm, reschedule, cancel, complete and edit; a reschedule control that re-runs available-time selection for the chosen barber and date.
  • States: Loading (hairline skeleton for the detail fields); empty (not applicable — the page always has an appointment in context; if the referenced appointment is missing, a plain French message with a return to Reservations); success (state change reflected immediately, with the state rule wiping from amber to green in 180ms left-to-right once on confirmation); error (if a state change or reschedule fails — for example the chosen slot now overlaps — a plain French message explaining the conflict, with the appointment left in its prior state); recovery (choose another slot or retry the action without losing the appointment context).
Page 9 of 56

New Appointment

  • Information/state: The complete booking flow. The manager selects a customer, a service, a barber, a date, and an available time slot. Available slots are computed from the selected barber's working hours, breaks and existing bookings, and overlapping bookings are prevented.
  • Primary actions: Select customer, service, barber, date and available time; create the appointment.
  • Supporting actions: Change any earlier selection and re-derive available times; cancel the flow and return to Reservations.
  • Domain entities: Customer, service (with price in TND), barber, date, available time slots, the resulting appointment.
  • Component responsibilities: Ordered selection controls for customer, service, barber and date; an available-time selector that only offers valid, non-overlapping slots; inline validation in French; a create control that is enabled only when the selection is complete and valid.
  • States: Loading (hairline skeleton while customers, services, barbers and slots are read); empty (no available slots for the chosen barber and date — a plain French line inviting a different date or barber); success (appointment created and the manager continues to the new appointment's details or back to Reservations); error (validation failure or a slot that became unavailable between selection and creation — a plain French message with the slot list refreshed); recovery (re-select a valid slot and create without re-entering the whole flow).
Page 10 of 56

Calendar

  • Information/state: A day/week column grid with time on the y-axis in 15-minute increments and barber columns across — a timetable, not a card wall. Appointments appear in their barber's column at their time, carrying their state hue.
  • Primary actions: Open an appointment from the grid to reach Appointment Details; switch between day and week views; move the visible date range.
  • Supporting actions: Scan barber columns for gaps and conflicts; use the same state hues as the rest of the app.
  • Domain entities: Appointments positioned by barber, date and time; barber columns; time axis.
  • Component responsibilities: Time axis in 15-minute increments; barber columns; appointment blocks with state hue; day/week view switch; date-range navigation.
  • States: Loading (hairline skeleton grid); empty (no appointments in the visible range — a plain French line, not a large illustration); success (grid rendered with appointments in their columns); error (if the calendar cannot be read, a plain French message with a retry that reloads the visible range); recovery (retry restores the grid at the same date range).
Page 11 of 56

Customers

  • Information/state: The list and records of customers the shop serves, with the fields the manager maintains for each.
  • Primary actions: Create a customer; edit a customer's details.
  • Supporting actions: Search and scan the customer list; open a customer's record.
  • Domain entities: Customer records and their maintained fields.
  • Component responsibilities: Customer list; create and edit forms with inline French validation; search control.
  • States: Loading (hairline skeleton rows); empty (no customers yet — a plain French line with a control to create the first customer); success (customer saved and visible in the list); error (validation or save failure shown inline in French with entered values preserved); recovery (correct the flagged fields and save again).

Barbers

  • Information/state: The list and records of the shop's barbers, with the fields the manager maintains for each.
  • Primary actions: Create a barber; edit a barber's details.
  • Supporting actions: Scan the barber list; open a barber's record.
  • Domain entities: Barber records and their maintained fields.
  • Component responsibilities: Barber list; create and edit forms with inline French validation.
  • States: Loading (hairline skeleton rows); empty (no barbers yet — a plain French line with a control to create the first barber); success (barber saved and visible in the list); error (validation or save failure shown inline in French with entered values preserved); recovery (correct the flagged fields and save again).
Page 12 of 56

Services & Pricing

  • Information/state: The list of services the shop offers and their prices in TND.
  • Primary actions: Create a service; edit a service and its price.
  • Supporting actions: Scan the service list; review prices in tabular TND figures.
  • Domain entities: Services with names, descriptions and prices in TND.
  • Component responsibilities: Service list with right-aligned tabular TND prices; create and edit forms with inline French validation; Lucide pictograms for services (scissors, razor, beard, hair-dryer) at 20px in single-weight line.
  • States: Loading (hairline skeleton rows); empty (no services yet — a plain French line with a control to create the first service); success (service and price saved and visible in the list); error (validation or save failure shown inline in French with entered values preserved); recovery (correct the flagged fields and save again).
Page 13 of 56

Availability

  • Information/state: The availability editor drawn as a timetable diagram rather than a form: a 7-column week grid with working hours as solid graphite bars and breaks as notched gaps, with the resulting slot count printed in tabular figures at the end of each row.
  • Primary actions: Set and adjust working hours; set and adjust breaks; save the resulting availability.
  • Supporting actions: Drag bar edges to change working hours and breaks; read the resulting slot count per row.
  • Domain entities: Working hours per day, breaks per day, derived available slots.
  • Component responsibilities: 7-column week grid; draggable working-hour bars; notched break gaps; per-row tabular slot count; save control with inline French validation.
  • States: Loading (hairline skeleton grid); empty (no working hours set — a plain French line inviting the manager to set the first day's hours); success (availability saved and the derived slot count updated); error (invalid configuration — for example a break outside working hours — shown inline in French); recovery (correct the flagged configuration and save again).
Page 14 of 56

Reports

  • Information/state: Reports over the shop's activity, using the same state hues as the rest of the app so one colour means one thing everywhere.
  • Primary actions: View reports; select the reported period.
  • Supporting actions: Read figures in tabular TND and counts; use the state legend.
  • Domain entities: Aggregated appointment counts by state, revenue in TND, and related activity figures.
  • Component responsibilities: Report figures in tabular numerals; a state legend reusing the appointment state hues; period selection.
  • States: Loading (hairline skeletons that pulse opacity); empty (no data for the selected period — a plain French line); success (reports rendered with aligned tabular figures); error (if reports cannot be read, a plain French message with a retry that reloads the selected period); recovery (retry restores the reports at the same period).
Page 15 of 56

Settings

  • Information/state: The shop's settings, including the TND default currency and the shop's identifying details used across the backoffice.
  • Primary actions: Edit and save settings.
  • Supporting actions: Review current settings values.
  • Domain entities: Shop settings, default currency (TND), tenant/shop identity.
  • Component responsibilities: Settings form with labeled fields and inline French validation; save control.
  • States: Loading (hairline skeleton for the settings fields); empty (not applicable — settings have defaults); success (settings saved and reflected across the backoffice); error (validation or save failure shown inline in French with entered values preserved); recovery (correct the flagged fields and save again).
Page 16 of 56

3. Functional Requirements

FR-01 — Working application with functional navigation and main actions (explicit) As a Barber Shop Manager, I should use BarberFlow as a working application — not a static mockup — where all navigation and main actions are functional, so that every section I open and every action I take actually works.

  • Trigger/input: The manager navigates the rail and uses controls on any page.
  • Observable result: Navigation changes the working surface; main actions produce their stated result.
  • Access state: Protected pages require the manager to be signed in; Landing, Login and Sign Up are anonymously reachable.
  • Failure/recovery: If a route or action fails, a plain French message with a retry that returns the manager to the same context.
  • Continuation: The manager continues in the section they were working in.
  • Provenance: explicit.

FR-02 — Specified technology stack (explicit) As a Barber Shop Manager, I should use a backoffice built with React, TypeScript, Vite, Tailwind CSS, shadcn/ui and Lucide React, so that the tool is fast, consistent and maintainable.

  • Trigger/input: Application build and runtime.
  • Observable result: The application runs on this stack with Lucide icons at 16/18px and 1.5px stroke.
  • Access state: Not applicable.
  • Failure/recovery: Not applicable.
  • Continuation: Not applicable.
  • Provenance: explicit.
Page 17 of 56

FR-03 — Premium responsive dashboard, dark sidebar, light interface, French UI (explicit) As a Barber Shop Manager, I should see a premium, responsive dashboard with a dark sidebar, a clean light interface and a French-language UI, so that the tool reads like signage — legible from across the room and unambiguous.

  • Trigger/input: The manager opens any page at 375px, 768px or 1280px.
  • Observable result: A fixed 248px graphite rail on the left (collapsing to a 64px icon rail at 768px and a bottom sheet drawer at 375px) and a light working surface to its right; all labels, messages and controls in French.
  • Access state: Protected pages require sign-in.
  • Failure/recovery: Not applicable.
  • Continuation: The manager continues working at any viewport.
  • Provenance: explicit.

FR-04 — Required sections (explicit) As a Barber Shop Manager, I should have Overview, Reservations, Calendar, Customers, Barbers, Services & Pricing, Availability, Reports and Settings, so that every part of running the shop's day has a place.

  • Trigger/input: The manager selects a section from the rail.
  • Observable result: The selected section opens on the working surface.
  • Access state: All nine sections require sign-in.
  • Failure/recovery: If a section fails to load, a plain French message with a retry.
  • Continuation: The manager continues in the section they opened.
  • Provenance: explicit.
Page 18 of 56

FR-05 — Reservation management priority: today's appointments, pending confirmations, completed bookings, cancellations, estimated revenue (explicit) As a Barber Shop Manager, I should see today's appointments, pending confirmations, completed bookings, cancellations and estimated revenue, so that I can trust the day's numbers in three seconds.

  • Trigger/input: The manager opens Overview.
  • Observable result: A ruled KPI band with five figures — today's appointments, pending confirmations, completed bookings, cancellations, and estimated revenue in TND — each with a small-caps label above and a signed delta below.
  • Access state: Requires sign-in.
  • Failure/recovery: If the day's data cannot be read, a plain French message with a retry that reloads the day.
  • Continuation: The manager acts on the figures, opening an appointment or confirming the oldest unconfirmed booking.
  • Provenance: explicit.

FR-06 — Searchable and filterable reservations (explicit) As a Barber Shop Manager, I should search and filter reservations, so that I can find the booking I need without scanning the whole day.

  • Trigger/input: The manager types in the search input or selects filter chips on Reservations.
  • Observable result: The dense table narrows to matching reservations, with state rules and tabular TND amounts aligned.
  • Access state: Requires sign-in.
  • Failure/recovery: If the list cannot be read, a plain French message with a retry that reloads the list with search and filters intact.
  • Continuation: The manager opens a matching reservation or clears filters.
  • Provenance: explicit.
Page 19 of 56

FR-07 — Calendar views (explicit) As a Barber Shop Manager, I should view appointments in calendar views, so that I can see the chair-by-chair schedule as a timetable.

  • Trigger/input: The manager opens Calendar and switches between day and week views or moves the date range.
  • Observable result: A day/week column grid with time on the y-axis in 15-minute increments and barber columns across, appointments carrying their state hue.
  • Access state: Requires sign-in.
  • Failure/recovery: If the calendar cannot be read, a plain French message with a retry that reloads the visible range.
  • Continuation: The manager opens an appointment from the grid.
  • Provenance: explicit.

FR-08 — Appointment details (explicit) As a Barber Shop Manager, I should view appointment details, so that I can see the customer, service, barber, date, time, price in TND and current state of one appointment.

  • Trigger/input: The manager opens an appointment from Reservations, Calendar, Overview or the next-up queue.
  • Observable result: Appointment Details shows the appointment's fields with its state chip and 4px state rule.
  • Access state: Requires sign-in.
  • Failure/recovery: If the referenced appointment is missing, a plain French message with a return to Reservations.
  • Continuation: The manager acts on the appointment (edit, confirm, reschedule, cancel, complete).
  • Provenance: explicit.
Page 20 of 56

FR-09 — Complete booking flow with customer, service, barber, date and available time selection (explicit) As a Barber Shop Manager, I should complete a booking flow selecting customer, service, barber, date and an available time, so that a new appointment is created correctly.

  • Trigger/input: The manager starts a new appointment and selects customer, service, barber and date.
  • Observable result: An available-time selector offers only valid, non-overlapping slots derived from the barber's working hours, breaks and existing bookings; creating the appointment produces a new booking.
  • Access state: Requires sign-in.
  • Failure/recovery: If no slots are available, a plain French line invites a different date or barber; if a slot became unavailable between selection and creation, a plain French message with the slot list refreshed.
  • Continuation: The manager continues to the new appointment's details or back to Reservations.
  • Provenance: explicit.

FR-10 — Create appointments (explicit) As a Barber Shop Manager, I should create appointments, so that walk-ins and phone bookings enter the schedule.

  • Trigger/input: The manager completes the booking flow and creates the appointment.
  • Observable result: The appointment exists in the schedule with its state and appears in Reservations, Calendar and Overview.
  • Access state: Requires sign-in.
  • Failure/recovery: Validation failure or slot conflict shown in French with the flow preserved for correction.
  • Continuation: The manager continues to the appointment's details or back to Reservations.
  • Provenance: explicit.
Page 21 of 56

FR-11 — Edit appointments (explicit) As a Barber Shop Manager, I should edit appointments, so that corrected details are reflected in the schedule.

  • Trigger/input: The manager edits an appointment's details from Appointment Details.
  • Observable result: The appointment's fields are updated and reflected wherever the appointment appears.
  • Access state: Requires sign-in.
  • Failure/recovery: Validation failure shown inline in French with entered values preserved.
  • Continuation: The manager returns to the appointment or the list.
  • Provenance: explicit.

FR-12 — Confirm appointments (explicit) As a Barber Shop Manager, I should confirm appointments, so that pending bookings become committed.

  • Trigger/input: The manager confirms an appointment from Appointment Details or the rail's persistent "Confirmer" action.
  • Observable result: The appointment's state changes to confirmé, and its state rule wipes from amber to green in 180ms left-to-right once.
  • Access state: Requires sign-in.
  • Failure/recovery: If the confirmation fails, a plain French message with the appointment left in its prior state and a retry.
  • Continuation: The manager continues with the day's work; the pending count in the rail updates.
  • Provenance: explicit.
Page 22 of 56

FR-13 — Reschedule appointments (explicit) As a Barber Shop Manager, I should reschedule appointments, so that a booking moves to a new valid time.

  • Trigger/input: The manager chooses reschedule on Appointment Details and selects a new date and available time for the barber.
  • Observable result: The appointment moves to the new slot, and the old slot becomes available again.
  • Access state: Requires sign-in.
  • Failure/recovery: If the chosen slot now overlaps, a plain French message explaining the conflict, with the appointment left in its prior state.
  • Continuation: The manager chooses another slot or retries without losing the appointment context.
  • Provenance: explicit.

FR-14 — Cancel appointments (explicit) As a Barber Shop Manager, I should cancel appointments, so that a booking that will not happen leaves the active schedule.

  • Trigger/input: The manager cancels an appointment from Appointment Details.
  • Observable result: The appointment's state changes to annulé and it is reflected in Reservations, Calendar and the day's figures.
  • Access state: Requires sign-in.
  • Failure/recovery: If the cancellation fails, a plain French message with the appointment left in its prior state and a retry.
  • Continuation: The manager continues with the day's work.
  • Provenance: explicit.
Page 23 of 56

FR-15 — Complete appointments (explicit) As a Barber Shop Manager, I should complete appointments, so that finished bookings are recorded as done.

  • Trigger/input: The manager completes an appointment from Appointment Details.
  • Observable result: The appointment's state changes to terminé and it is reflected in Reservations, Calendar and the day's figures.
  • Access state: Requires sign-in.
  • Failure/recovery: If the completion fails, a plain French message with the appointment left in its prior state and a retry.
  • Continuation: The manager continues with the day's work.
  • Provenance: explicit.

FR-16 — Manage customers (explicit) As a Barber Shop Manager, I should manage customers, so that the shop's customer records stay accurate.

  • Trigger/input: The manager creates or edits a customer on Customers.
  • Observable result: The customer record is saved and available for selection in the booking flow.
  • Access state: Requires sign-in.
  • Failure/recovery: Validation or save failure shown inline in French with entered values preserved.
  • Continuation: The manager continues in the customer list or starts a booking for that customer.
  • Provenance: explicit.
Page 24 of 56

FR-17 — Manage barbers (explicit) As a Barber Shop Manager, I should manage barbers, so that the shop's barber records stay accurate.

  • Trigger/input: The manager creates or edits a barber on Barbers.
  • Observable result: The barber record is saved and available as a column in Calendar and as a selection in the booking flow.
  • Access state: Requires sign-in.
  • Failure/recovery: Validation or save failure shown inline in French with entered values preserved.
  • Continuation: The manager continues in the barber list or sets that barber's availability.
  • Provenance: explicit.

FR-18 — Manage services and prices (explicit) As a Barber Shop Manager, I should manage services and prices, so that bookings carry the right service and the right TND price.

  • Trigger/input: The manager creates or edits a service and its price on Services & Pricing.
  • Observable result: The service and its TND price are saved and available in the booking flow, with prices shown in tabular figures.
  • Access state: Requires sign-in.
  • Failure/recovery: Validation or save failure shown inline in French with entered values preserved.
  • Continuation: The manager continues in the service list or starts a booking for that service.
  • Provenance: explicit.
Page 25 of 56

FR-19 — Manage working hours, breaks and availability (explicit) As a Barber Shop Manager, I should manage working hours, breaks and availability, so that the slots offered to bookings match when the shop actually works.

  • Trigger/input: The manager adjusts working-hour bars and break gaps on Availability and saves.
  • Observable result: The week grid reflects the new working hours and breaks, and the derived slot count per row updates in tabular figures.
  • Access state: Requires sign-in.
  • Failure/recovery: Invalid configuration (for example a break outside working hours) shown inline in French.
  • Continuation: The manager continues in Availability or returns to booking, where the new slots are offered.
  • Provenance: explicit.

FR-20 — Prevent overlapping bookings and validate time slots (explicit) As a Barber Shop Manager, I should have overlapping bookings prevented and time slots validated, so that the schedule stays conflict-free.

  • Trigger/input: The manager selects a time slot in the booking flow or reschedules an appointment.
  • Observable result: Only valid, non-overlapping slots are offered; a conflicting selection is refused with a plain French explanation.
  • Access state: Requires sign-in.
  • Failure/recovery: A slot that became unavailable between selection and creation is refused with the slot list refreshed.
  • Continuation: The manager selects a valid slot and continues.
  • Provenance: explicit.
Page 26 of 56

FR-21 — Realistic mock data with local persistence (explicit) As a Barber Shop Manager, I should work with realistic mock data that persists locally, so that my shop's state survives across sessions.

  • Trigger/input: The manager creates or changes data in any section.
  • Observable result: The data is stored locally and is present again when the manager returns.
  • Access state: Requires sign-in; the manager's own shop state is what is restored.
  • Failure/recovery: If local data cannot be read, a plain French message with a retry that reloads the state.
  • Continuation: The manager continues where they left off.
  • Provenance: explicit.

FR-22 — Reusable components, strict TypeScript, form validation, feature-based architecture (explicit) As a Barber Shop Manager, I should use an application built from reusable components with strict TypeScript, form validation and a clean feature-based architecture, so that the tool behaves consistently and reliably.

  • Trigger/input: Application build and use of any form.
  • Observable result: Shared components behave consistently across sections; forms validate input and show French validation messages.
  • Access state: Not applicable.
  • Failure/recovery: Validation failures are shown inline in French with entered values preserved.
  • Continuation: The manager corrects and resubmits.
  • Provenance: explicit.
Page 27 of 56

FR-23 — TND as the default currency (explicit) As a Barber Shop Manager, I should see TND as the default currency, so that every price and revenue figure matches how the shop prices its work.

  • Trigger/input: Any price, revenue or estimated-revenue figure is displayed.
  • Observable result: Amounts are shown in TND with tabular figures so columns align on the decimal.
  • Access state: Requires sign-in for protected figures.
  • Failure/recovery: Not applicable.
  • Continuation: Not applicable.
  • Provenance: explicit.

FR-24 — API services and multi-tenant architecture prepared for future integration (explicit) As a Barber Shop Manager, I should have the application prepared for a future backend, a React Native customer app and a SaaS super-admin dashboard, so that today's tool can grow without being rebuilt.

  • Trigger/input: Application architecture and data access.
  • Observable result: API service modules and tenant-scoped structures exist as seams; the current build remains client-side with local persistence.
  • Access state: Not applicable.
  • Failure/recovery: Not applicable.
  • Continuation: Not applicable.
  • Provenance: explicit.
Page 28 of 56

FR-25 — Start with the application layout, Overview dashboard and Reservations page (explicit) As a Barber Shop Manager, I should have the application layout, Overview dashboard and Reservations page built first, so that the highest-frequency work is available immediately.

  • Trigger/input: The manager signs in and lands in the backoffice.
  • Observable result: The layout, Overview and Reservations are complete and functional, with the remaining sections reachable from the rail.
  • Access state: Requires sign-in.
  • Failure/recovery: If a section is not yet complete, navigation still resolves without breaking the layout.
  • Continuation: The manager continues into the other sections.
  • Provenance: explicit.

FR-26 — Manager self-service enrollment before first use (required_inference) As a Barber Shop Manager, I should establish my own access before first using the protected backoffice, so that the shop state I create belongs to me and can be resumed.

  • Trigger/input: A manager with no access opens Sign Up and submits enrollment details.
  • Observable result: Access is established and the manager proceeds into the protected backoffice.
  • Access state: Sign Up is anonymously reachable; protected pages remain unavailable until access is established.
  • Failure/recovery: Validation or enrollment failure shown inline in French with entered values preserved.
  • Continuation: The manager proceeds into the backoffice, or to Login if access already exists.
  • Provenance: required_inference.
Page 29 of 56

FR-27 — Returning manager verification before accessing protected pages (required_inference) As a Barber Shop Manager, I should verify myself on return before reaching protected pages, so that my shop's state stays private and correctly bound to me.

  • Trigger/input: A returning manager opens Login and submits credentials.
  • Observable result: The manager reaches the protected backoffice with their persisted shop state.
  • Access state: Login is anonymously reachable; protected pages require successful verification.
  • Failure/recovery: Invalid credentials or failed verification shown inline in French with the form preserved for correction.
  • Continuation: The manager continues into the backoffice.
  • Provenance: required_inference.

FR-28 — Local persistence of mock data across sessions (required_inference) As a Barber Shop Manager, I should have my shop's data persist locally across sessions, so that appointments, customers, barbers, services, availability and settings are still there when I return.

  • Trigger/input: The manager changes data and later returns.
  • Observable result: The changed data is present after the session ends and a new session begins.
  • Access state: Requires sign-in; the restored state is the signed-in manager's own.
  • Failure/recovery: If local data cannot be read, a plain French message with a retry that reloads the state.
  • Continuation: The manager continues where they left off.
  • Provenance: required_inference.
Page 30 of 56

4. User Personas

Page 31 of 56

Barber Shop Manager

Product context. The manager runs a barber shop in Tunisia and uses BarberFlow as the shop's backoffice. They work in French, price in TND, and open the tool at the start of the day — often standing at the counter between clients. Their tool must read like signage: legible from across the room, unambiguous, warm inside its rigour. They are the only accepted active human persona for this generation; the shop's customers and barbers are records the manager maintains, not users of this backoffice.

Primary goal. A conflict-free, up-to-date booking schedule: every appointment in the right chair at the right time, with the day's numbers trustworthy at a glance.

Distinct accepted responsibilities.

  • Monitor the day on Overview: today's appointments, pending confirmations, completed bookings, cancellations and estimated revenue in TND.
  • Browse, search and filter reservations, and open any reservation's details.
  • Create, edit, confirm, reschedule, cancel and complete appointments.
  • Run the complete booking flow: customer, service, barber, date and available time.
  • View the schedule as a calendar, in day and week views, with barbers as columns.
  • Maintain customer records and barber records.
  • Maintain services and their prices in TND.
  • Maintain working hours, breaks and availability.
  • Review Reports and maintain Settings.
  • Rely on overlapping bookings being prevented and time slots validated.
Page 32 of 56

Relevant inputs and decisions. Which appointment to act on next; whether a pending booking should be confirmed; whether a booking should be rescheduled, cancelled or completed; which customer, service, barber, date and slot a new booking uses; what the shop charges for each service; when each barber works and when they break; what the shop's settings and default currency are.

Interactions with other accepted participants. The manager is the sole active human actor in this backoffice. The customers and barbers whose records the manager maintains are represented as data, not as users of this application; the React Native customer app and the SaaS super-admin dashboard are future scope and are not participants now.

Observable success. The KPI band shows the day's five figures correctly; a pending booking becomes confirmé with its state rule wiping amber to green; a rescheduled appointment moves to a valid slot and frees its old one; a conflicting slot is refused with a clear French explanation; the calendar shows each barber's column without overlaps; the availability editor's slot count updates after a change; and the manager's data is still there on return.

Source-backed constraints. French-language UI; TND default currency; strict TypeScript; multi-tenant architecture prepared for future backend integration, a React Native customer app and a SaaS super-admin dashboard (future scope, not current build); the build starts with the application layout, Overview dashboard and Reservations page.

5. Core User Flows

Page 33 of 56

Flow 1 — First use: enroll and enter the backoffice

  1. The manager opens BarberFlow and lands on Landing, the anonymous public entry explaining the manager backoffice.
  2. The manager chooses to start using BarberFlow and goes to Sign Up.
  3. On Sign Up, the manager enters their enrollment details. Inline French validation flags any incomplete or invalid field, and the entered values are preserved.
  4. The manager submits. Access is established and the manager proceeds into the protected backoffice.
  5. The manager arrives on Overview, the day's control panel, with the layout, Overview and Reservations ready to use.
  6. Failure/recovery: if enrollment fails, a plain French message appears inline and the manager corrects the flagged fields and resubmits without re-entering everything.
  7. Continuation: the manager begins the day's work on Overview.

Flow 2 — Returning use: verify and resume the shop's state

  1. The returning manager opens Login, the anonymous verification surface.
  2. The manager submits their credentials.
  3. On success, the manager reaches the protected backoffice with their locally persisted shop state — appointments, customers, barbers, services, availability and settings — restored.
  4. Failure/recovery: invalid credentials or a failed verification are shown inline in French with the form preserved; the manager corrects and resubmits. If local data cannot be read, a plain French message offers a retry that reloads the state.
  5. Continuation: the manager continues where they left off, typically on Overview.
Page 34 of 56

Flow 3 — Read the day on Overview

  1. The manager opens Overview.
  2. The manager reads the ruled KPI band: today's appointments, pending confirmations, completed bookings, cancellations, and estimated revenue in TND — each with a small-caps label above and a signed delta below. The pending figure carries a signal-red dot and the revenue figure is set in signal red.
  3. The manager reads the 24-hour density strip beneath the band: 48 hairline bars, one per 30 minutes, height proportional to bookings, the current slot in signal red.
  4. The manager scans today's timeline on the left and the next-up queue on the right — three appointment rows, each with a 4px state rule, tabular time, client name, service and barber initials.
  5. The manager clicks a density-strip bar to scroll the day timeline to that hour.
  6. Failure/recovery: if the day's data cannot be read, a plain French message offers a retry that reloads the day.
  7. Continuation: the manager opens an appointment from the timeline or the next-up queue, or confirms the oldest unconfirmed booking from the rail's persistent action.
Page 35 of 56

Flow 4 — Confirm the oldest pending booking from anywhere

  1. From any screen, the manager uses the persistent graphite rail footer — the day's instrument panel — which shows the live pending count and the next appointment time counting down in tabular figures.
  2. The manager clicks the signal-red Confirmer action, which opens the oldest unconfirmed booking on Appointment Details.
  3. The manager reviews the appointment's customer, service, barber, date, time, price in TND and current state.
  4. The manager confirms the appointment. Its state becomes confirmé, and its state rule wipes from amber to green in 180ms left-to-right once. The pending count in the rail updates.
  5. Failure/recovery: if the confirmation fails, a plain French message appears and the appointment stays in its prior state; the manager retries.
  6. Continuation: the manager returns to the day's work, with one fewer pending booking.
Page 36 of 56

Flow 5 — Find a reservation by search and filters

  1. The manager opens Reservations, the dense table with a sticky header, 44px rows, a 4px state rule at the left edge of each row, a right-aligned tabular TND column, and filters as a horizontal chip row above the rule.
  2. The manager types in the search input and/or selects filter chips. The table narrows to matching reservations, with state rules and tabular TND amounts aligned.
  3. The manager scans the results.
  4. Failure/recovery: if the list cannot be read, a plain French message offers a retry that reloads the list with the manager's search and filters intact. If nothing matches, a plain French line offers a control to clear filters.
  5. Continuation: the manager opens a matching reservation on Appointment Details, or clears filters and continues scanning.
Page 37 of 56

Flow 6 — Create a new appointment through the complete booking flow

  1. The manager starts a new appointment from Reservations and arrives on New Appointment.
  2. The manager selects a customer from the shop's customer records.
  3. The manager selects a service, seeing its price in TND.
  4. The manager selects a barber.
  5. The manager selects a date.
  6. The application derives the available time slots from the selected barber's working hours, breaks and existing bookings, and offers only valid, non-overlapping slots.
  7. The manager selects an available time.
  8. The manager creates the appointment. The new booking appears in Reservations, Calendar and Overview.
  9. Failure/recovery: if no slots are available for the chosen barber and date, a plain French line invites a different date or barber. If the chosen slot became unavailable between selection and creation, a plain French message explains the conflict and the slot list is refreshed; the manager re-selects a valid slot without re-entering the whole flow.
  10. Continuation: the manager continues to the new appointment's details or back to Reservations.
Page 38 of 56

Flow 7 — Reschedule an appointment to a valid slot

  1. The manager opens an appointment on Appointment Details from Reservations, Calendar, Overview or the next-up queue.
  2. The manager chooses to reschedule and selects a new date and an available time for the barber. Only valid, non-overlapping slots are offered.
  3. The manager confirms the reschedule. The appointment moves to the new slot, and the old slot becomes available again.
  4. Failure/recovery: if the chosen slot now overlaps, a plain French message explains the conflict and the appointment stays in its prior state; the manager chooses another slot or retries without losing the appointment context.
  5. Continuation: the manager returns to the schedule, where the appointment now sits at its new time.

Flow 8 — Cancel or complete an appointment

  1. The manager opens an appointment on Appointment Details.
  2. To cancel: the manager cancels the appointment. Its state becomes annulé and it is reflected in Reservations, Calendar and the day's figures.
  3. To complete: the manager completes the appointment. Its state becomes terminé and it is reflected in Reservations, Calendar and the day's figures.
  4. Failure/recovery: if the cancellation or completion fails, a plain French message appears and the appointment stays in its prior state; the manager retries.
  5. Continuation: the manager continues with the day's work, with the day's figures updated.
Page 39 of 56

Flow 9 — Edit an appointment's details

  1. The manager opens an appointment on Appointment Details.
  2. The manager edits the appointment's details.
  3. The manager saves. The updated fields are reflected wherever the appointment appears.
  4. Failure/recovery: validation failures are shown inline in French with entered values preserved; the manager corrects and saves again.
  5. Continuation: the manager returns to the appointment or the list.

Flow 10 — Read the schedule as a timetable on Calendar

  1. The manager opens Calendar.
  2. The manager sees a day/week column grid with time on the y-axis in 15-minute increments and barber columns across, appointments carrying their state hue.
  3. The manager switches between day and week views and moves the visible date range to scan for gaps and conflicts.
  4. Failure/recovery: if the calendar cannot be read, a plain French message offers a retry that reloads the visible range.
  5. Continuation: the manager opens an appointment from the grid on Appointment Details.
Page 40 of 56

Flow 11 — Maintain customer records

  1. The manager opens Customers.
  2. The manager creates a customer or edits an existing one.
  3. The manager saves. The customer record is saved and available for selection in the booking flow.
  4. Failure/recovery: validation or save failures are shown inline in French with entered values preserved; the manager corrects and saves again. If no customers exist yet, a plain French line offers a control to create the first one.
  5. Continuation: the manager continues in the customer list or starts a booking for that customer.

Flow 12 — Maintain barber records

  1. The manager opens Barbers.
  2. The manager creates a barber or edits an existing one.
  3. The manager saves. The barber record is saved and available as a column in Calendar and as a selection in the booking flow.
  4. Failure/recovery: validation or save failures are shown inline in French with entered values preserved; the manager corrects and saves again. If no barbers exist yet, a plain French line offers a control to create the first one.
  5. Continuation: the manager continues in the barber list or sets that barber's availability on Availability.
Page 41 of 56

Flow 13 — Maintain services and prices

  1. The manager opens Services & Pricing.
  2. The manager creates a service or edits an existing service and its price in TND.
  3. The manager saves. The service and its TND price are saved and available in the booking flow, with prices shown in tabular figures.
  4. Failure/recovery: validation or save failures are shown inline in French with entered values preserved; the manager corrects and saves again. If no services exist yet, a plain French line offers a control to create the first one.
  5. Continuation: the manager continues in the service list or starts a booking for that service.

Flow 14 — Set working hours, breaks and availability

  1. The manager opens Availability, the timetable diagram: a 7-column week grid with working hours as solid graphite bars and breaks as notched gaps, with the resulting slot count printed in tabular figures at the end of each row.
  2. The manager drags bar edges to set or adjust working hours and breaks.
  3. The manager saves. The week grid reflects the new working hours and breaks, and the derived slot count per row updates in tabular figures.
  4. Failure/recovery: an invalid configuration — for example a break outside working hours — is shown inline in French; the manager corrects and saves again. If no working hours are set, a plain French line invites the manager to set the first day's hours.
  5. Continuation: the manager continues in Availability or returns to booking, where the new slots are offered.
Page 42 of 56

Flow 15 — Review Reports

  1. The manager opens Reports.
  2. The manager selects the reported period and reads the figures in tabular TND and counts, using the state legend that reuses the appointment state hues.
  3. Failure/recovery: if reports cannot be read, a plain French message offers a retry that reloads the selected period. If there is no data for the period, a plain French line says so.
  4. Continuation: the manager returns to the day's work with the period's picture in mind.

Flow 16 — Maintain Settings

  1. The manager opens Settings.
  2. The manager edits the shop's settings, including the TND default currency and the shop's identifying details used across the backoffice.
  3. The manager saves. The settings are saved and reflected across the backoffice.
  4. Failure/recovery: validation or save failures are shown inline in French with entered values preserved; the manager corrects and saves again.
  5. Continuation: the manager continues with the day's work under the updated settings.
Page 43 of 56

6. Visuals Colors and Theme

Muse and headline. Erik Spiekermann — typographic infrastructure for the barber's day: a booking ledger that reads like a transit timetable. The interface is built from rules, columns and signal colours rather than the generic rounded-card-on-white SaaS shell. The requested dark sidebar and clean light interface are honoured as two fixed grounds; everything else is drawn from Spiekermann's signal-colour logic.

Colour tokens (light mode).

RoleTokenHex
Background (working surface)--bg#F4F1EC
Surface (panels, tables, forms)--surface#FFFFFF
Text (body and data)--text#141414
Primary (chrome rail, section headers)--primary#1F1D1B
Accent (signal red)--accent#D62B1F
Muted (secondary text)--muted#8A8378
Hairline (separation)--hairline#E2DCD2
Chrome rail type--on-primary#F4F1EC

Appointment state hues (used only as a 4px left rule, a 6px dot, or a small-caps label chip — never as a filled card):

Page 44 of 56
StateHex
En attente#E0A100 (amber)
Confirmé#1B6B4A (deep green)
Terminé#3A5A8C (deep blue)
Annulé#8A8378 (grey)
No-show#7A1F1F (oxblood)

Proportion. 70% paper/white, 22% graphite chrome, 6% state hues, 2% signal red. No gradients anywhere; every colour is flat and named.

Typography. One family, many weights — this is the point. Headings and body: Fira Sans. Headings at 600–700 with tight tracking (−0.015em), sentence case for page titles, ALL-CAPS with +0.08em tracking for micro-labels, table headers, section eyebrows and state chips. Numbers are the loudest thing on the page: revenue and counts set at 700 with tabular figures (font-feature-settings: 'tnum' 1), so columns of TND amounts align on the decimal. Secondary weights at 400 for reading, 500 for controls.

Type scale. 1.25 modular on a 16px base — 12 / 13 / 16 / 20 / 25 / 31 / 39 / 49. Page title 31→39 (clamp(1.75rem, 1.2rem + 1.6vw, 2.44rem)), KPI figure 39→49 (clamp(2.44rem, 1.6rem + 3vw, 3.06rem)), section heading 20, table body 13, label 12 caps. Numerals always tabular. Line-height 1.15 for display, 1.5 for body, 1.35 for table rows.

Shape language. Rectilinear and honest. 2px radii on buttons and inputs — enough to feel machined, never pill-shaped. 0px on panels, tables and the sidebar: corners are square because the grid is the shape. Separation comes from 1px hairlines (#E2DCD2) and from weight, not from shadow. The only softness is a 4px left rule on appointment rows and a 6px dot for state. Icons are Lucide at 16/18px with 1.5px stroke, optically aligned to the cap height of adjacent labels. No floating cards, no drop shadows, no glass.

Page 45 of 56

Spacing rhythm. A strict 12-column grid, 24px gutters, 32px page margins at 1280px, 16px at 375px. Every page opens the same way: an ALL-CAPS eyebrow line, a page title, then a full-width horizontal rule — the page behaves like a sign board. Everything aligns to the same left edge; nothing floats.

Imagery style. The interface is the imagery. No photography inside the backoffice — no stock barbers, no mood shots. Visual interest comes from information design: the 24-hour appointment density strip, small schematic diagrams for the availability editor, and a Lucide pictogram set for services (scissors, razor, beard, hair-dryer) at 20px in single-weight line. The one place photography is allowed is the public Landing, where a single high-contrast black-and-white photograph of a chair and mirror is cropped to the grid and treated as a ruled panel — documentary, not lifestyle.

Page 46 of 56

7. Signature Design Concept

The ruled ledger as the first screen. The first screen the manager meets after signing in is not a marketing page — it is Overview, because this is a working tool opened at 8:50am. The composition is a sign board:

  • A 248px graphite rail on the left carrying the BarberFlow wordmark in Fira Sans 600 with a signal-red square period.
  • The working surface opens with an ALL-CAPS eyebrow — MARDI 12 NOVEMBRE — SALON CARTHAGE — in Fira Sans 500 at 12px with +0.08em tracking, then the page title Tableau de bord at clamp(1.75rem, 1.2rem + 1.6vw, 2.44rem), then a full-width 1px rule.
  • Beneath the rule, the dominant element is the KPI band as a ruled ledger: five figures in tabular Fira Sans 700 at clamp(2.44rem, 1.6rem + 3vw, 3.06rem) — 18 rendez-vous, 4 en attente, 11 terminés, 2 annulés, 1 240,000 TND estimé — separated by full-height vertical hairlines, each with a small-caps label above and a signed delta below. The pending figure carries a signal-red dot; the revenue figure is set in signal red. No cards, no icons in circles, no drop shadows.
  • Under the band, the 24-hour density strip runs edge to edge in 1px bars, one per 30 minutes, height proportional to bookings, the current time slot in signal red — and it doubles as a click target that scrolls the day timeline to that hour.
  • The right third of the first screen is the next-up queue: three appointment rows, each with a 4px state rule, time in tabular 700, client name, service and barber initials.
  • The graphite rail footer is the day's instrument panel: the live pending count, the next appointment time counting down in tabular figures, and a signal-red Confirmer action that opens the oldest unconfirmed booking.
Page 47 of 56

There is no centred headline, no subtext, no button in the middle of the screen — the first screen is a control panel and every number on it is live. On mobile the KPI band wraps to two rows of two-and-three with the rules rotating to horizontal, and the rail becomes a bottom sheet drawer.

Page 48 of 56

8. Interaction Model & Motion Direction

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

Landing Hero Motion Brief.

  • Focal subject: the single high-contrast black-and-white photograph of a chair and mirror, cropped to the grid and treated as a ruled panel — documentary, not lifestyle.
  • Input → transformation → outcome thesis: the manager arrives on the anonymous Landing and reads the ruled panel; the entry controls for Sign Up and Login are the only interactive elements, and choosing one carries the manager into the corresponding entry surface. No accepted behaviour is invented — the panel composes accepted entry content only.
  • Motion vocabulary: functional and short — 120–160ms ease-out on hover, focus and state changes; nothing eases longer than 200ms. Page transitions are a 120ms crossfade with a 4px upward settle — no slide, no bounce. Skeleton loaders are hairlines that pulse opacity, not shimmering gradient blocks.
  • Composed first frame: the graphite rail with the BarberFlow wordmark and its signal-red square period; the ruled photographic panel cropped to the grid; an ALL-CAPS eyebrow, a page title, a full-width 1px rule; the Sign Up and Login controls aligned to the same left edge as everything else.
  • Reduced-motion state: under prefers-reduced-motion everything resolves instantly — no wipe, no roll, no crossfade — and the Landing renders as a static ruled composition with the entry controls fully usable.

Signature motion moments (accepted behaviour only). A confirmed booking's state rule wipes from amber to green in 180ms, left to right, once. The live en attente counter in the rail increments with a 90ms number roll. Under prefers-reduced-motion both resolve instantly.

Page 49 of 56

9. Non-Functional Requirements

NFR-01 — French-language UI (explicit) All labels, messages, validation text and empty states are in French. Rationale: the manager works in French and must read the tool without translation.

NFR-02 — TND default currency (explicit) TND is the default currency for every price, revenue and estimated-revenue figure, rendered with tabular figures so columns align on the decimal. Rationale: the shop prices its work in Tunisian Dinar.

NFR-03 — Strict TypeScript (explicit) The codebase is strict TypeScript. Rationale: strict typing keeps the schedule and pricing logic reliable as the application grows.

NFR-04 — Reusable components and feature-based architecture (explicit) Shared components are reused across sections, and the code is organized by feature. Rationale: consistent behaviour across sections and a clean base for future integration.

NFR-05 — Form validation (explicit) Every form validates its input and shows French validation messages inline, preserving entered values on failure. Rationale: the manager must be able to correct and resubmit without re-entering data.

Page 50 of 56

NFR-06 — Responsive at 375px, 768px and 1280px (explicit) The dashboard is responsive: the 248px rail collapses to a 64px icon rail at 768px and a bottom sheet drawer at 375px; the KPI band wraps to two rows with rules rotating to horizontal; page margins are 32px at 1280px and 16px at 375px. Readable text and controls stay whole inside the viewport and their container at every breakpoint. Rationale: the manager uses the tool at the counter, on a tablet and on a phone.

NFR-07 — Local persistence of mock data (explicit) Realistic mock data persists locally across sessions. Rationale: the manager's shop state must survive between sessions without a backend.

NFR-08 — Multi-tenant architecture prepared for future integration (explicit) API service modules and tenant-scoped structures are prepared for a future backend, a React Native customer app and a SaaS super-admin dashboard. Rationale: the tool must be able to grow without being rebuilt.

NFR-09 — Conflict-free scheduling (explicit) Overlapping bookings are prevented and time slots are validated before an appointment is created or rescheduled. Rationale: a barber cannot serve two clients in one chair at one time.

NFR-10 — Motion restraint and reduced-motion support (direction-derived) Transitions are 120–160ms ease-out and never longer than 200ms; no parallax, no scroll-linked animation, no bouncing hovers, no particles. Under prefers-reduced-motion everything resolves instantly. Rationale: motion is functional, not decorative, and must never obstruct the manager's work.

Page 51 of 56

NFR-11 — Accessible contrast and legibility (direction-derived) Body and data text is #141414 on white/paper (contrast ≈15:1); chrome rail type is #F4F1EC on #1F1D1B. State is never encoded by colour alone — every state also carries a small-caps label. Rationale: the tool must be legible from across the room and unambiguous.

10. Tech Stack

  • React — UI library (explicit)
  • TypeScript (strict) — application language (explicit)
  • Vite — build tool and dev server (explicit)
  • Tailwind CSS — styling (explicit)
  • shadcn/ui — component primitives (explicit)
  • Lucide React — icon set, 16/18px at 1.5px stroke (explicit)
  • Fira Sans — headings and body type family (direction-derived)
  • Local persistence — browser-local storage for mock data across sessions (explicit: "realistic mock data with local persistence")
  • API service modules and tenant-scoped structures — prepared seams for future backend integration, a React Native customer app and a SaaS super-admin dashboard; not a live backend in this build (explicit)

No backend service, database, container or orchestration layer is part of the current build; the application is client-side with local persistence and prepared API seams.

Page 52 of 56

11. Assumptions and Constraints

Assumptions.

  • A1 — The manager is the only active human user of this backoffice in the current build; customers and barbers are records the manager maintains, not users of this application. (Source: the accepted persona catalog contains exactly one active human persona.)
  • A2 — The shop's identity used in the Overview eyebrow and Settings is mock data the manager maintains, consistent with the realistic mock data requirement. (Source: explicit mock-data requirement.)
  • A3 — Local persistence is browser-local storage sufficient to restore the manager's shop state across sessions. (Source: explicit "local persistence" requirement; required_inference for cross-session continuity.)
  • A4 — The application owns identity because the manager must privately own and resume durable shop state across sessions; Sign Up establishes first-use access and Login verifies returning access. (Source: required_inference under the actor-continuity rule.)
  • A5 — Multi-tenancy is prepared architecturally (tenant-scoped data and API service seams) without a live backend, a super-admin surface or a customer mobile app. (Source: explicit future-scope constraint.)
Page 53 of 56

Constraints.

  • C1 — UI language is French. (explicit)
  • C2 — Default currency is TND. (explicit)
  • C3 — Strict TypeScript. (explicit)
  • C4 — Multi-tenant architecture is prepared for future backend integration, a React Native customer app and a SaaS super-admin dashboard; these are future scope, not current build. (explicit)
  • C5 — The build starts with the application layout, Overview dashboard and Reservations page. (explicit)
  • C6 — The stack is React, TypeScript, Vite, Tailwind CSS, shadcn/ui and Lucide React. (explicit)
  • C7 — The dashboard has a dark sidebar and a clean light interface. (explicit)
  • C8 — Overlapping bookings are prevented and time slots are validated. (explicit)
  • C9 — The application is a working application, not a static mockup; all navigation and main actions are functional. (explicit)
  • C10 — The React Native customer app and the SaaS super-admin dashboard are not built, routed or reachable in this generation. (explicit future horizon)
Page 54 of 56

12. Glossary

  • BarberFlow — The product name of the manager backoffice for barber shops described in this document.
  • Backoffice — The protected manager-facing application: Overview, Reservations, Calendar, Appointment Details, New Appointment, Customers, Barbers, Services & Pricing, Availability, Reports and Settings.
  • Barber Shop Manager — The single accepted active human persona: the owner-manager who runs the shop's day in this backoffice.
  • Appointment / Réservation — A booking of a service with a barber for a customer at a date and time, carrying a state and a price in TND.
  • Appointment state — One of en attente (amber), confirmé (deep green), terminé (deep blue), annulé (grey), no-show (oxblood); encoded as a 4px left rule, a 6px dot, or a small-caps label chip.
  • KPI band — The ruled ledger at the top of Overview: five oversized tabular figures separated by full-height 1px hairlines, each with a small-caps label above and a signed delta below.
  • Density strip — The 24-hour appointment density strip beneath the Overview KPIs: 48 hairline bars, one per 30 minutes, height proportional to bookings, the current slot in signal red, doubling as a click target.
  • Next-up queue — The three appointment rows on the right of Overview, each with a 4px state rule, tabular time, client name, service and barber initials.
  • Rail — The fixed 248px graphite chrome rail on the left (64px icon rail at 768px, bottom sheet drawer at 375px) carrying navigation and the day's instrument panel footer.
  • Availability editor — The timetable diagram on Availability: a 7-column week grid with working hours as solid graphite bars, breaks as notched gaps, and the derived slot count per row in tabular figures.
Page 55 of 56
  • Slot — A bookable time interval derived from a barber's working hours, breaks and existing bookings; only valid, non-overlapping slots are offered.
  • TND — Tunisian Dinar, the default currency of the application.
  • Tenant — A shop's isolated data scope; multi-tenant structures are prepared for future backend integration.
  • Mock data — Realistic sample data used in place of a live backend, persisted locally across sessions.
Page 56 of 56

No completed page designs yet.

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

Landing: Read product overview
Sign Up: Start enrollment
Sign Up: 1. Submit enrollment details
Sign Up: 2. Correct flagged fields and resubmit
Login: 1. Submit credentials
Login: 2. Correct credentials and resubmit
Overview: 1. Read KPI band and density strip
Overview: 2. Scan timeline and next-up queue
Overview: 3. Click density bar to scroll timeline
Overview: 4. Confirm oldest pending booking
Appointment Details: 5. Review appointment fields
Appointment Details: 6. Confirm appointment
Appointment Details: 7. Retry confirmation
Reservations: 1. Search and filter reservations
Reservations: 2. Clear filters
Reservations: Open reservation
Reservations: 3. Start new appointment
New Appointment: 4. Select customer
New Appointment: 5. Select service
New Appointment: 6. Select barber
New Appointment: 7. Select date
New Appointment: 8. Select available time
New Appointment: 9. Create appointment
New Appointment: 10. Re-select valid slot
Appointment Details: 8. Reschedule appointment
Appointment Details: 9. Choose another slot
Appointment Details: 10. Cancel appointment
Appointment Details: 11. Complete appointment
Appointment Details: 12. Edit appointment details
Appointment Details: 13. Save edited details
Calendar: 14. View day/week grid
Calendar: 15. Switch view and move date range
Calendar: 16. Open appointment from grid
Customers: 1. Create or edit customer
Customers: 2. Save customer record
Barbers: 1. Create or edit barber
Barbers: 2. Save barber record
Services & Pricing: 1. Create or edit service and price
Services & Pricing: 2. Save service and price
Availability: 1. Adjust working hours and breaks
Availability: 2. Save availability
Reports: Select period and view reports
Settings: Edit and save settings

No completed page designs yet.

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

Landing: Read product overview
Sign Up: Start enrollment
Sign Up: 1. Submit enrollment details
Sign Up: 2. Correct flagged fields and resubmit
Login: 1. Submit credentials
Login: 2. Correct credentials and resubmit
Overview: 1. Read KPI band and density strip
Overview: 2. Scan timeline and next-up queue
Overview: 3. Click density bar to scroll timeline
Overview: 4. Confirm oldest pending booking
Appointment Details: 5. Review appointment fields
Appointment Details: 6. Confirm appointment
Appointment Details: 7. Retry confirmation
Reservations: 1. Search and filter reservations
Reservations: 2. Clear filters
Reservations: Open reservation
Reservations: 3. Start new appointment
New Appointment: 4. Select customer
New Appointment: 5. Select service
New Appointment: 6. Select barber
New Appointment: 7. Select date
New Appointment: 8. Select available time
New Appointment: 9. Create appointment
New Appointment: 10. Re-select valid slot
Appointment Details: 8. Reschedule appointment
Appointment Details: 9. Choose another slot
Appointment Details: 10. Cancel appointment
Appointment Details: 11. Complete appointment
Appointment Details: 12. Edit appointment details
Appointment Details: 13. Save edited details
Calendar: 14. View day/week grid
Calendar: 15. Switch view and move date range
Calendar: 16. Open appointment from grid
Customers: 1. Create or edit customer
Customers: 2. Save customer record
Barbers: 1. Create or edit barber
Barbers: 2. Save barber record
Services & Pricing: 1. Create or edit service and price
Services & Pricing: 2. Save service and price
Availability: 1. Adjust working hours and breaks
Availability: 2. Save availability
Reports: Select period and view reports
Settings: Edit and save settings