All work

Florist website

A storefront for an independent flower shop that makes each bouquet feel special, then sends people to order through a delivery app or WhatsApp.

Role
Design and front-end development
Status
Live
Category
Flower shop storefront
Place and year
Morocco, 2026
Stack
HTML, CSS, JavaScript, Vite, Python
Links
The shop’s name, logo and address are left out to protect the client’s privacy, so the live site isn’t linked. The source code isn’t public.
Florist home page: a bouquet of lilies and roses beside the headline “Des fleurs pour chaque moment précieux.”
Creations gallery.
Ordering section.
Home page on a phone.
Creations on a phone.
prices mirror the delivery app
cut out in Python

PageSpeed Insights, desktop

100Performance
100Accessibility
100Best practices
100SEO

The story

  1. The challenge

    The shop takes orders through a delivery app in its own city and on WhatsApp across Morocco. It needed a website that presents the bouquets with the same care that goes into them, then hands every visitor to the right place to order.

  2. The approach

    A soft, editorial storefront built around the shop’s own photography, in semantic HTML, CSS and a little JavaScript. A Python pipeline cuts out each bouquet for layered compositions, and the parallax runs on CSS scroll-driven animations instead of a JavaScript loop.

  3. The result

    The site is live. PageSpeed Insights scores it 100 for performance, accessibility, best practices and SEO on desktop, and 97 for performance on mobile.

What I built

  • A creations gallery filtered by occasion, with a lightbox and prices that mirror the shop’s delivery-app menu.
  • Ordering that routes to the delivery app locally and to WhatsApp or phone elsewhere in Morocco.
  • Scroll-driven parallax in CSS, with a still composition where browsers don’t support it.
  • Headlines revealed line by line, shown at once when reduced motion is on.
  • A Python pipeline that turns the original photography into WebP and cuts out bouquets.
  • Canonical URLs, Open Graph, JSON-LD, robots.txt, sitemap.xml and llms.txt, generated at build.

Under the hood

real excerpts from the codebase

Parallax without a JavaScript loop

Every drifting element shares one keyframe and reads the scroll position through animation-timeline. Browsers without support, and visitors who prefer reduced motion, get the still layout.

src/style.css

@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    [data-parallax] img,
    .section-index,
    .reviews__ring,
    .why__glow,
    .why::before,
    .botanical--order {
      animation: drift linear both;
      animation-timeline: view();
    }

Cutting out the bouquets

rembg removes the background, a repair pass restores ribbons it loses against dark clothing, and each cut-out is cropped and saved at several widths.

scripts/cut_bouquets.py

def main() -> None:
    session = new_session("isnet-general-use")
    for source, name, widths, erase in CUTS:
        photo = Image.open(SRC / source).convert("RGB")
        cut = remove(photo, session=session)
        if name in RESTORE:
            cut = restore(photo, cut, RESTORE[name])
        cut = clean(cut, erase)
        cut = cut.crop(cut.getchannel("A").getbbox())

Decisions

No framework

A one-page storefront doesn’t need one. Semantic HTML, CSS and a little JavaScript, with self-hosted Cormorant Garamond and Manrope.

One source for prices

Prices come from the shop’s delivery-app menu and live in the markup as data attributes, so keeping them in sync is a single edit.

Brand marks left intact

The delivery app and WhatsApp logos follow each company’s rules, and the word WhatsApp stays written next to its glyph.

Results

Performance, desktop
100
Performance, mobile
97
Accessibility
100
Best practices
100
SEO
100
LCP, desktop
0.6s
CLS
0

PageSpeed Insights on the live site, 1 November 2026. Also checked in Chromium, Firefox and WebKit.

Home page with the bouquet hero.
Home
Home page on a phone, with delivery-app and WhatsApp buttons.
Home on a phone
Creations gallery with red roses and chrysanthemums.
Creations, filtered by occasion
Creations section on a phone.
Creations on a phone
The shop’s story with layered bouquet photography.
The story
Ordering section explaining delivery through a delivery app.
Ordering in three steps

Status

The shop’s name, logo, city, phone number and social accounts are left out of this case study. The screenshots replace them with a neutral wordmark and masked details.