Files
jzzliu 73fcc0548c Rework storefront into modules and tokenised styles
Split the 100-line script into catalog, cart, format, dom and main modules.
Money is integer cents, the bag is capped and sanitised and syncs across
tabs, and the view (category, sort) lives in the URL. Templates escape every
interpolation.

Rewrite the minified stylesheet as cascade layers on design tokens. Fixes
heading tracking that collapsed word gaps, a 2.6:1 focus ring on the hero,
1.3:1 control borders, misaligned cart quantities, uneven product cards and
undersized touch targets. Adds a favicon and a resolvable dialog label.
2026-11-07 21:18:38 -07:00

21 lines
736 B
JavaScript

/** Formatting helpers. Money is always handled as integer cents to avoid float drift. */
// Intl formatters are comparatively expensive to build, so create each one once.
const whole = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
minimumFractionDigits: 0,
maximumFractionDigits: 0,
});
const exact = new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" });
/** 8600 -> "$86", 8650 -> "$86.50" */
export function money(cents) {
return (cents % 100 === 0 ? whole : exact).format(cents / 100);
}
/** plural(1, "item") -> "1 item", plural(3, "item") -> "3 items" */
export function plural(count, noun, pluralNoun = `${noun}s`) {
return `${count} ${count === 1 ? noun : pluralNoun}`;
}