Bengaluru, India
Try it live
Work
/Case study: Khaleel Electricals
Product DesignUXBrand IdentityFull StackAI

Khaleel Electricals: Trust You Can See, Paperwork That Runs Itself

Mohammed Zabeeh·June 18, 2026·33 min read
Khaleel Electricals: Trust You Can See, Paperwork That Runs Itself

A rebrand and two products for a Class-1 electrical contractor: a marketing site that builds its first digital presence, and a Telegram bot and dashboard that run the paperwork themselves.

2
Journeys mapped
2
Products shipped
5
Service categories
Solo
Delivery
Client
Khaleel Electricals, Bengaluru
Role
UX, Brand & Development (solo)
Timeline
2025 to 2026
Type
Site
Tools
Vanilla JS, GSAP / ScrollTrigger, Supabase, Resend +4

The Problem

Decades of serious infrastructure work, and almost no way for a new client to find it. Khaleel Electricals is a electrical contractor in Bengaluru, trusted by names the city knows, from Malabar Gold & Diamonds to St John's. Two everyday gaps were quietly costing the firm work.
  • No digital presence. A prospect who heard the name had nowhere to land. With nothing online, a decades-old Class-1 contractor looked no different from a one-person operation, and enquiries drifted to firms that were simply easier to find.
  • Paperwork that ran on memory. Quotations and invoices were typed in Word or written by hand, then wrestled onto pre-printed letterhead that never quite lined up. Old quotes were near impossible to reuse, payments lived in someone's head, and nobody had a single view of who owed what.
Mapping who the firm actually needed to serve exposed two broken journeys behind those gaps. The prospect arrives on a recommendation and wants one thing fast, proof that this firm can handle serious work. With nothing online, that journey died before it began, so the job was never to build a website. It was to make decades of real capability legible in the few seconds a busy client gives you. The office lives inside the flow of drafting a quotation, winning the job, raising invoices and chasing payments. Every stage leaked time. Walking through how a quote was actually made, typed in Word or written by hand, fought onto letterhead, hunted down whenever it needed reusing, and tracked in someone's memory once it went out, showed those pains were not cosmetic. They were the workflow. Both journeys pointed at one decision: this was one brand doing two jobs, not a website with an admin panel bolted on, and the identity had to come first, because both experiences would be built on top of it.

The Rebrand

An identity that matched the firm's standing came first, a ground-up rebrand of Khaleel Electricals: a new logo, business cards, and a letterhead that carries through to every quotation and invoice the office sends. That one identity is the thread tying everything together. It sets the tone of the marketing site and, crucially, it is the letterhead the invoicing dashboard reproduces. Because the letterhead was designed at the source rather than borrowed, rebuilding it in code to a pixel was a continuation of the same brand work, not a guess at someone else's template. Both products inherit the same visual language, so a client who meets the firm online and a client who receives an invoice are looking at one coherent business.

The Marketing Site

The prospect needs to feel the firm's capability quickly, so the site is a single scrolling story rather than a brochure, moving from a hook, through the firm's promise, into proof. A brochure asks the reader to hunt for the reassuring bits, whereas a paced narrative delivers them in the order a wary client wants them.
The hero pairs a short confident headline with a line illustration of a tower feeding a home.
A short, confident headline sits over the firm's Class-1 licence, paired with a line illustration of a transmission tower feeding a home. The page is bold where it counts and calm where it should be, because the audience wants answers, not decoration. The structure follows the journey a prospect takes rather than a sitemap, so the story is paced and felt instead of dumped in one go:
  • A pinned narrative that advances chapter by chapter, so the firm's story is paced and felt rather than dumped in a wall of text.
  • A services breakdown across five categories that mirror what a Class-1 licence covers, from and to and testing, so a prospect can self-qualify in seconds.
  • Proof that is shown, not claimed.
The services section became the page's centrepiece in a later pass. It holds one screen while a dial of five marks turns beside it, and the illustration for each trade assembles itself from the ground up, plinth then body then the part that energises it, before coming apart and building again. Watching a substation put itself together explains the work faster than a paragraph describing it, which is the whole argument for animating a trade page rather than listing services. Solutions sits on the same idea from the client's side. Building types run down the left, outcomes down the right, and a live current re-routes between whichever pair is lit while the node between them names the trade doing the work. It answers the only question a prospect really has, which is whether this firm has done a job like mine, without asking them to read a case study to find out.
Track-record figures count up over an animated circuit motif as the band scrolls in.
Statistics count up as the band scrolls into view over an animated circuit motif, putting the firm's track record in motion instead of leaving it as a static line.
A wall of flip cards shows named clients like Malabar Gold and St John's.
A client wall of flip cards cycles through named clients and the sectors the firm serves, turning reputation into something a stranger can take in at a glance. Naming real clients does the persuading that an "about us" paragraph never could, because the credibility was already there and only needed showing. Alongside it, a horizontal rail carries fifteen real projects drawn from the founder's own record, named, placed and measured, from a six-lakh-square-foot residency to bank ATM rollouts across three states. Specifics carry weight that adjectives cannot. The phone version keeps the story rather than flattening it. The hero and the risk-to-fix section still turn as you scroll, held with sticky positioning instead of the desktop's scroll pinning, because pinning and touch scrolling fight each other. Where an effect could not survive the smaller screen it degrades to plain stacked content, which is also exactly what a reader with reduced-motion enabled, or no JavaScript at all, receives. A working contact form closes the loop, and knows which service to preselect from the button that sent the visitor there.

The Office Dashboard

The office experience is designed around the quote-to-cash flow, not around screens. Three decisions shaped it.
  • The document is the interface. A live A4 preview reproduces the firm's letterhead as you type, so the thing you edit is the thing you send. That alone ends the text drift, the alignment fights, and the misaligned second pass through the printer that made the old Word-and-letterhead process so slow.
  • Nothing should be entered twice. Past documents are saved, searchable and reusable, so duplicating last month's quotation to tweak a line is a click rather than a file hunt. The client address book builds itself from saved documents, and the revenue overview reads real money in and out. The office maintains nothing by hand, which is the whole point, because anything maintained by hand eventually falls out of date.
  • Status follows the money. A payments ledger on every invoice records date, amount and method, the balance updates live, and the status derives itself from unpaid to partial to paid rather than being flipped by someone who remembered. Payment details, a bank block and a scannable QR code sit on the document so clients can pay the exact balance without a phone call to confirm the number.
It was delivered in phases that each closed one more loop: a local-first editor, then cloud sync, then email and sharing, then the address book, revenue view and payments ledger. Shipping in loops meant the office got a usable tool early and every release removed one more manual step rather than promising a big-bang launch that never quite arrives.

Reading the Business

Once the books were honest, the next question was what they had to say. The dashboard could tell you the balance on any one invoice, but not whether the firm was being paid faster or slower than last quarter, how much quoted work was quietly lapsing, or which client to ring this morning. A contractor does not need a reporting suite; they need the four or five numbers that change what they do today. An Insights page answers that as a set of separate tiles, one idea each, rather than a dense dashboard of everything at once. Money owed and how much of it has gone stale. Work in hand, the accepted quotations not yet invoiced, which is the forward book. Collection speed, measured only on invoices actually settled, because counting the unpaid ones has no end date and would flatter the number. Tax withheld this financial year, ready to reconcile at filing. Then the chase lists: the oldest unpaid invoices with their age, and the quotations about to lapse. The charts were chosen by what each measure is for rather than by what looks impressive. Billing against collections over six months is a trend, so it is an area chart, with cash collected in the brand accent and billing behind it in grey, because the story is how much of what you invoiced turned into money. Two rates are genuine part-of-whole figures, so they are radial meters with the number in the middle. Quotation value by status is a magnitude comparison across five categories, so it is horizontal bars sorted by value, where a pie would have been unreadable at three quotations. Payment methods are also magnitude, not identity, so they share one hue at varying width rather than being handed six competing colours. Colour was the part that needed measuring rather than taste. Won, open and lost want to be green, amber and red, which happens to be the hardest possible triad for colour-vision deficiency: the first set I chose failed outright, with two of the three effectively indistinguishable. Re-stepping them against a contrast and colour-vision check produced a set that passes, and dark mode needed its own steps rather than a lightened flip of the light ones. Every bar also carries its category name and value, so the colour reinforces the reading instead of carrying it. The brand's own orange, it turns out, sits at roughly two-to-one against white, well under the minimum for a mark or a label, so anything that has to read as accented uses a darker step of it. The document lists gained the plumbing that makes a growing archive usable: sortable columns, and a summary of exactly which filters are narrowing the view, each removable on its own, so it is never a mystery why a document is missing from the list.

Into the Field

The dashboard fixed the office but still assumed someone was sitting at it. The raw material of a quote rarely starts at a desk. It starts on site, as a handwritten job sheet or a few lines the contractor reels off between calls, and turning that into a document meant going back to a screen and typing it all in again. So the next step was to meet the work where it happens, on a phone, in a chat. The contractor already lives in messaging all day, so the capture surface is a Telegram assistant rather than one more screen to learn. It did not start as broadly as it ended. The first version was photo-first: snap the handwritten sheet and let the assistant read it. That worked, but it still assumed the job was already written down, and on site the contractor was usually on the move with nothing to photograph. Voice came next and proved the most natural input of all, because dictating a quotation as a few spoken lines needs no camera and no typing, so a photo, a PDF, typed text and a voice note now all arrive at the same place. The flow follows how a contractor thinks, not how a database wants its data.
  • Snap it or say it. Send a photo of the handwritten sheet, a scanned PDF, a typed line, or a voice note describing the job, and the assistant reads the handwriting or the speech and turns it into a draft invoice or quotation.
  • Nothing lands without a nod. Handwriting and speech are fuzzy, so the assistant always shows the parsed job and waits for a tap before anything reaches the books. A misread figure is caught in the preview, never in the accounts.
  • Build it point by point. A job is usually worked out one item at a time, so a draft can be grown the same way: record a point, add another, and submit only once the whole job is in.
  • Repair a point, do not redo the job. If one line comes out wrong, the contractor taps to edit it, picks it from the list, and resends just that item as a fresh photo, voice note, PDF or typed line, and the assistant re-reads it and swaps it in. A saved invoice can be corrected the same way after the fact, with the change showing up live on the dashboard and the total updated. A single misread never means starting over.
  • Dictate a letter, not just a quote. Client letters go the same route: pick the client from the saved list rather than retyping a name, then speak the letter, photograph it or type it, and the assistant turns speech or handwriting into clean prose and shows it back before anything is filed.
  • Close the loop on money. Record a payment, see who owes what and for how long, and send a client their document as a link with a ready WhatsApp message, all without opening a laptop. A weekly summary lists outstanding balances so chasing payments stops depending on memory, which is the same failure the office had before, moved off a desk and onto a phone. The point was never to add a gadget but to let the contractor start and finish a piece of billing from wherever the work is.
Two details from using it in anger turned out to matter more than any feature. The first is that a client's name is never typed the same way twice. "Malabar jewels and gems" and "M/s Malabar Jewels & Gems Pvt Ltd" are the same customer to a human and two different customers to a substring match, and the assistant had been quietly creating the second one. Names are now compared with the noise stripped out, the case, the punctuation, the ampersand against "and", the M/s and Pvt Ltd furniture, and nothing is ever created without being offered back for confirmation first. An address book that silently grows duplicates is worse than one that asks. The second is that a share link on its own says nothing. The assistant used to send "here is your invoice" and a URL; it now sends a message the client can act on without opening anything, naming the document and date, the amount and what is still outstanding, or the total and validity date for a quotation, and the contractor sees the exact wording before it goes. Every draft the assistant creates is written to the same place the dashboard reads from and shows up there live, so the phone and the desk are two windows onto one set of books rather than two copies to reconcile. That single shared source is what stops the field tool becoming a second system to keep in sync, which would have reintroduced exactly the memory-and-reconciliation problem the dashboard set out to kill.

Under the Hood

The engineering is deliberately low-drama, in service of the two experiences above. Both products are vanilla HTML, CSS and JavaScript, with no framework and no build step, so they load instantly and the firm can have the code understood and edited years from now. The dashboard treats the cloud (Supabase Postgres with ) as the source of truth and local storage as an instant cache, so a flaky connection never stops the office billing. The letterhead is rebuilt in code and rendered client-side with html2pdf.js, so the on-screen preview and the emailed PDF are byte-for-byte identical, with measurement-based pagination keeping headers, footers and totals where they belong. Email sends through a via Resend, and several documents for the same client can go out together in one message rather than as a stream of separate emails. The field assistant runs the same way, as a Telegram webhook on a serverless function, with Google's Gemini reading each sheet or voice note into structured fields and the draft written to the same Supabase source of truth the dashboard streams from. The confirm-before-save rule keeps an AI misread out of the books, and the draft appears on the dashboard the moment it is confirmed. For a small business, longevity and load speed beat developer convenience every time, which is why the least fashionable choices here were the deliberate ones. With both products live, the whole codebase went through a senior-level review across architecture, security, data access, performance, accessibility and observability, and the findings were acted on.
  • Security, end to end. Row-level security locks the data to the owner, the service-role key never reaches the browser, and the Telegram assistant is gated by a secret token and an allow-list. Public share links were hardened, the automation and email endpoints scoped to the owner, and the marketing site given a content-security-policy, the usual security headers, and subresource integrity on every third-party script.
  • Accessibility to WCAG 2.2 AA. The marketing site gained keyboard-operable navigation and gallery, proper landmarks and form labels, stronger colour contrast, and animation that steps aside for a reduced-motion preference, so the experience holds up for everyone rather than only a mouse on a fast machine.
  • Resilience and visibility. Every outbound call to Supabase, Gemini, Resend and Telegram now has a timeout and a log, shared money and formatting logic moved into one tested module, and every change shipped through a preview deploy and a smoke test before reaching the live site.
A second review, this time of the field assistant alone once it had been handling real money for a while, found the class of fault that only shows up in something already in production. Its authentication failed open rather than closed: with one environment variable missing, a comparison of nothing against nothing succeeded and every request authenticated. Telegram redelivers a message it thinks went unanswered, and reading a job sheet can take the best part of a minute, which meant a single slow request could record a payment twice. Two writers, the phone and the desk, could each read a document, change it and save it back, with whoever finished last silently erasing the other. And re-sharing a document minted a fresh link while leaving every previous one alive, each a public snapshot carrying the firm's bank details. None of these were visible in normal use, which is the point: a bot that works every time you try it can still be one redelivery away from a duplicated payment. Each was closed at the mechanism rather than patched at the symptom, with the database's own uniqueness constraint used as the lock against replays, and every edit made conditional on the document not having changed since it was read, so a clash is reported rather than resolved by silently overwriting. A later pass addressed being found at all. Alongside the usual canonical tags, sitemap and structured data describing the firm as a licensed electrical contractor with its five services, the site publishes an llms.txt: a plain-text brief of what the firm does, where it works and the questions people actually ask, written for answer engines rather than browsers. More prospects now begin with a question typed into an assistant than with a search box, and a page built only for a crawler quietly loses those. The one thing deliberately left out was FAQ markup, because schema describing questions that do not appear on the page is precisely what search engines penalise. The answers exist; the section to hold them comes first. A later handover moved the firm's own infrastructure into the firm's own hands. The domain and the email sending account had both been sitting in mine, convenient while building and wrong to leave there: a business should hold the keys to its own name and its own post. Moving them turned up the sort of thing nobody looks for until they do. The transfer quietly dropped the domain's lock against being moved again. A renewal the reseller's panel reported as done had not yet reached the registry that actually decides. And www had been serving a browser security warning since the day the certificate was issued, because the address resolved correctly but had never been added to the host, and nobody had thought to type it. Sending moved onto the firm's own verified domain at the same time, so invoices now arrive from the firm's own address rather than a shared one belonging to the email provider. Then a third review asked a blunter question than the first two: the dashboard is a public address, so what does a stranger who opens it actually get? The honest answer is the entire application, because a page like this ships its own source, including the key it uses to reach the database. That is not a flaw, it is how the model works, and it means the login panel is a curtain rather than a wall. The wall is row-level security. What the review found was that account signups on the database project had been left open, so anyone at all could hold a genuine signed-in token. Correct policies made that harmless, and it was still a standing invitation to the first policy written slightly wrong; one setting closed it. Adding an authenticator code to the sign-in then exposed the trap in the obvious way of doing it. A password on its own already earns a valid session; the code only raises that session's assurance. So a page that demands the code while the database does not is decoration, because anyone holding the password can skip the page and talk to the database directly with the key printed in it. The requirement therefore lives in the security policies themselves: a session that has not passed the code is refused by the database, whatever is asking, and the email endpoint refuses it too so a half-authenticated session cannot send invoices from the firm's own address. The last finding was the least obvious and the most interesting. The public contact form spent the same email allowance the invoices did. A script left running on that form could exhaust the day's quota and stop the office billing altogether: a denial of the product's core function through its most open door, with a busy inbox as the only visible symptom. Limiting each visitor would not have held, since anyone with a pool of addresses walks straight past that; the cap that matters is the total one, set to leave the bulk of each day's allowance for the invoices that pay for the thing.

Platform Evolution

Nov 2025
Rebrand and identity
A ground-up rebrand: new logo, business cards, and a letterhead that becomes the master template for every quotation and invoice the firm sends.
Mar 2026
Marketing site
A scroll-driven single-page site with pinned storytelling, a horizontal project showcase, an animated stats band, and a client flip wall, all built on GSAP and ScrollTrigger.
Apr 2026
Invoicing editor (local-first)
A single-file quotation and invoice builder with a live A4 preview replicating the firm's letterhead, measurement-based pagination, and client-side PDF export.
Apr 2026
Cloud auth and database
Supabase Postgres with row-level security behind a password gate, local storage kept as an instant cache so the office can work from any device.
May 2026
Email, address book and revenue
Serverless email sends invoices as PDF attachments via Resend, a self-building client address book, and a revenue overview with per-month cash flow.
Jun 2026
Payments ledger
A per-invoice ledger that records date, amount and method, updates the balance live, and derives status (unpaid, partial, paid) plus a bank block and UPI QR on the document itself.
Jun 2026
Telegram field assistant
A chat assistant that turns a photographed job sheet, a PDF, a typed line or a spoken voice note into a draft invoice or quotation the office confirms, with point-level repair for any misread line in a draft or a saved document, then records payments, reports outstanding balances, shares documents and sends a weekly reminder, all from a phone.
Jun 2026
Audit and hardening
A senior-level pass across security, accessibility and observability: row-level security, a content-security-policy and subresource integrity, WCAG 2.2 AA on the marketing site, and timeouts and logging on every outbound call, with shared logic pulled into one tested module.
Aug 2026
Site rework and reach
The services section rebuilt as a turning dial with illustrations that assemble themselves, solutions merged into one panel with a routed live current, a fifteen-project rail from the founder's own record, and a client wall that flips. Tablet and phone kept the scroll narratives via sticky positioning, and the site gained structured data, a sitemap and an llms.txt for answer engines.
Aug 2026
Insights and a second hardening pass
An Insights page of thirteen single-idea tiles covering cash owed, collection speed, debtor ageing, the quotation pipeline and who to chase, with chart colours measured against colour-vision and contrast checks rather than chosen by eye. Alongside it, a review of the field assistant closed an authentication that failed open, a replay path that could record a payment twice, and concurrent edits that silently overwrote each other.
Aug 2026
Letters and client matching in the field
Letters became a first-class flow on the phone: pick a saved client, then speak, photograph or type the letter and confirm the transcription. Client names are now matched with punctuation and company furniture stripped out, so a loosely typed name finds the existing customer instead of quietly creating a duplicate, and share links go out as a message the client can act on.
Aug 2026
Handover and a third hardening pass
The domain and the email account moved into the firm's own hands, with invoices now sent from its own verified address. A review of what a stranger opening the dashboard address actually gets closed open signups, added an authenticator code enforced by the database rather than by the page, and capped the public contact form so it can no longer burn the allowance the invoices depend on.
Next
Owner-led content updates
A lightweight way for the office to refresh projects and client logos on the marketing site without touching code.

Lessons

  1. Map the journey before the feature Walking the office through how a quote was actually made, reused and chased told me what to build far better than any feature list would have. The dashboard solves a workflow, not a wishlist.
  2. Trust is a design problem, not a copy problem The firm's credibility was already real, it just was not legible online. Animated proof, counting statistics and a named client wall did more for perceived capability than any amount of "about us" prose.
  3. Derive state, do not set it Letting invoice status fall out of the payments ledger, and letting the address book and revenue build themselves from saved work, removed an entire class of human error. The books stay honest because nobody has to remember to update them.
  4. Show the work, do not describe it A page that lists five services asks the reader to picture what each one means. Letting each illustration assemble itself, and letting a live current route between a building type and its outcome, does that picturing for them. For a trade whose competence is invisible until something fails, motion is not decoration, it is the demonstration.
  5. Automate the typing, not the judgement The field assistant reads a sheet or a spoken note in seconds, but it never commits anything by itself. The person still approves every draft and every figure. Handing the machine the tedious part while keeping a human on the decision is what makes an AI feature safe enough to sit next to someone's accounts.
  6. Fail closed, and let the database hold the lock The faults worth finding in something already live were all invisible in normal use: an authentication that passed when its secret was missing, a retry that could bill a client twice, two screens overwriting each other's edits. Each was fixed at the mechanism rather than the symptom, using a uniqueness constraint as the lock and making every edit conditional on nothing having changed underneath it. A feature that works every time you try it can still be one retry away from a duplicated payment.
  7. Put the check where the data is, not where the button is Adding a second factor to the sign-in screen felt like the whole job, and on its own it would have been worth almost nothing. A page like this hands every visitor its own source code, including the key it uses to reach the database, so anyone with the password could have ignored the screen entirely. The rule only became real when the database itself started refusing sessions that had not passed the code. The same thinking applies to the small print of ownership: the domain and the sending account belong in the client's hands, not in the builder's, however convenient that was while building.
  8. Measure colour, do not judge it Green, amber and red for won, open and lost is the obvious palette and very nearly the worst one, because it is the hardest combination for colour-vision deficiency. My first set failed a contrast and colour-vision check outright, with two of the three effectively identical to a large minority of readers. Running the numbers took a minute and would never have been caught by looking. The brand's own orange turned out to be too pale to carry a label at all.

FAQ

By mapping two journeys first: the prospect who needed to gauge the firm's credibility in seconds, and the office stuck in a slow quote-to-cash flow. Those maps, not a feature wishlist, set the scope. The website answers the trust problem and the dashboard answers the paperwork problem, and a single rebrand ties them together.

The audience is busy clients who want answers fast. A single narrative page guides them from a hook to the firm's promise to proof, with pinned storytelling, a services dial whose illustrations assemble themselves, and a horizontal rail of fifteen real projects. On a phone the same narratives hold with sticky positioning rather than scroll pinning, since pinning and touch scrolling work against each other, and every effect degrades to plain stacked content under a reduced-motion preference or if the animation library never loads.

The site carries the usual foundations, canonical tags, a sitemap and structured data describing the firm as a licensed electrical contractor with its five services, and adds an llms.txt: a plain-text brief of what the firm does, where it works and the questions people actually ask, written for answer engines rather than browsers. FAQ schema was deliberately left out until a visible FAQ section exists, because marking up questions that are not on the page is what search engines penalise.

It is derived, not set. Each payment on the ledger records its date, amount and method, the balance updates live, and the status moves itself from unpaid to partial to paid. The revenue overview then reflects real money received and outstanding rather than figures someone remembered to mark off.

The document is rebuilt in HTML and CSS to mirror the firm's printed identity, then rendered client-side with html2pdf.js. The on-screen A4 preview and the emailed PDF come from the same markup, so they are byte-for-byte identical, with measurement-based pagination that keeps headers, footers and totals where they belong.

Both are vanilla HTML, CSS and JavaScript on purpose. The site loads instantly with no build step, and a small business can have the code understood and edited years from now without chasing a dependency tree. For this client, longevity and load speed mattered more than developer convenience.

It is a capture surface for the field, not a separate app. A photo, PDF, typed line or voice note is read into a draft invoice or quotation, the contractor confirms it, and it lands in the same Supabase source of truth the dashboard uses, appearing there live. The phone and the desk are two windows onto one set of books.

Nothing is saved without a human tap. The assistant shows the parsed job and waits for confirmation, so a misread figure is caught in the preview rather than in the accounts. The model handles the typing while the person keeps the judgement.

Only that line is redone, never the whole job. The contractor taps to edit the point, picks it from the list, and resends just that item as a photo, voice note, PDF or typed line, and the assistant re-reads it and swaps it in. It works on a saved document too, with the change appearing live on the dashboard and the total updated. Point-level repair is what makes the assistant trustworthy enough for real billing.

Row-level security locks the data to the owner and the service-role key never reaches the browser. Signing in takes a password and an authenticator code, and the code requirement is enforced by the database rather than by the page, so it cannot be stepped around. The Telegram assistant is gated by a secret token and an allow-list, the share links are hardened, and the marketing site runs a content-security-policy with subresource integrity on third-party scripts. Every outbound call has a timeout and a log, and changes ship through a preview deploy and a smoke test.

No, and it is worth being precise about why. A page like this ships its own source to whoever asks, including the key it uses to reach the database, so the login panel is a curtain rather than a wall. The wall is row-level security: without a signed-in session that has also passed the authenticator code, the database returns nothing, whatever is asking. That is also why the second factor is enforced there and not in the page, since anything the page checks can simply be skipped.

Not the one you would expect. The form sent through the same email allowance as the invoices, so a script left running on it could exhaust the day's quota and stop the office billing, with a full inbox as the only visible symptom. Limiting each visitor would not have held, because anyone with a pool of addresses walks past that, so the cap that matters is the total per day, set to leave the bulk of the allowance for the invoices that pay for the system.

The handful of numbers that change what they do today, one idea per tile: how much is owed and how much of it has aged past sixty days, the accepted quotations not yet invoiced, how long clients actually take to settle, tax withheld this financial year, the oldest unpaid invoices to chase, and the quotations about to lapse. Collection speed is measured only on invoices that were actually settled, because including the unpaid ones has no end date and would flatter the figure.

By measurement, not by eye. Won, amber and lost is the hardest combination for colour-vision deficiency, and the first set I picked failed a contrast and colour-vision check outright. The palette was re-stepped until it passed, dark mode was given its own steps rather than a lightened flip, and every bar carries its category name and value so colour reinforces the reading instead of carrying it. Each chart type follows what the measure is for: a trend is an area chart, a part-of-whole is a radial meter, a magnitude comparison is bars, never a pie.

The faults that only appear in production. Its authentication failed open, so with one environment variable missing every request would have authenticated. Telegram redelivers a message it thinks went unanswered, and reading a job sheet takes close to a minute, so one slow request could record a payment twice. The phone and the desk could each read a document, edit it and save it back, with the later save silently erasing the earlier one. Every one was fixed at the mechanism, using the database's own uniqueness constraint as the lock and making each edit conditional on nothing having changed underneath it.

Design Skills

UX ResearchService DesignInformation ArchitectureInteraction DesignProduct DesignBrand IdentityLogo DesignPrint & StationeryMotion DesignConversational DesignFull-Stack Development

Tech Stack

Vanilla JSGSAP / ScrollTriggerSupabaseResendhtml2pdf.jsTelegram Bot APIGemini (Google AI)Vercel