Back to projects No. 002 · E-commerce

ALCOBA

I build complete shopping flows: filters, a persistent cart and a validated checkout in vanilla JavaScript, with a magazine aesthetic.

Full ALCOBA home page: hero, collections, categories, journal and newsletter
Year
2026
Type
Editorial e-commerce · 7 pages
Role
Front-end design and development
Stack
HTML5 · SCSS · Bootstrap 5 · JavaScript · AOS

Challenge, solution and result

The challenge

A magazine that also sells

Capturing the tone of a fashion magazine without losing what a store needs: finding products, saving them and paying.

The solution

Editorial design, custom logic

Layered SCSS styles on top of the Bootstrap grid; filters, cart, checkout and payment written in vanilla JavaScript.

The result

A complete shopping flow

From collection to order confirmation, with the cart saved across pages and a demo payment that validates like a real one.

Highlights

A store from start to finish

01

Store filters and search

Filter by category, color and size, sort by price and search regardless of accents or capitalization. If nothing matches, a message says so and offers to clear the filters.

ALCOBA store with sidebar filters and the product grid
02

A cart that doesn't get lost

It's saved in localStorage, validates each product when reading it and keeps working even if storage is unavailable.

03

Complete checkout

An order summary with free shipping from $300 USD, form validation, focus on the first error and an order number on confirmation.

A technical decision

A card that validates like the real thing

The payment is a demo: card details are never stored or sent.

Even so, the form detects the brand (Visa, Mastercard or AMEX), formats the number as you type and validates it with the Luhn algorithm, the same one real cards use.

scripts/card-payment.js · simplified
const BRANDS = [
  { label: "AMEX", pattern: /^3[47]/, length: 15 },
  { label: "VISA", pattern: /^4/, length: 16 },
  { label: "Mastercard", pattern: /^(5[1-5]|2[2-7])/, length: 16 },
];

// Luhn checksum: used by all real cards.
const passesLuhn = (digits) => {
  let sum = 0;
  digits.split("").reverse().forEach((char, index) => {
    let digit = Number(char);
    if (index % 2 === 1) {
      digit *= 2;
      if (digit > 9) digit -= 9;
    }
    sum += digit;
  });
  return sum % 10 === 0;
};
The collections
Next project Huellitas