Sensory profiles
Up to three taste identities — e.g. Gas / Fuel bombs, Evening knock-out, Sweet tropics — each defined across aroma, flavour, effect, texture, potency and priority weights. A completeness ring unlocks matching at 60%.
Sensory sommelier for cannabis
A private-by-design tasting room. Instead of “indica / sativa / hybrid” reductionism, SŌMA lets a member build a personal sensory profile — aromas, flavours, effects — then scans any dispensary menu and ranks every strain against that taste with a deterministic, fully explainable match engine.
Every dispensary menu sorts flower by legacy taxonomy (indica / sativa / hybrid) and marketing copy (“euphoric, uplifting, creative”) — categories that don’t actually describe what a person’s palate wants tonight.
SŌMA borrows its language from wine and perfumery instead. Members describe how they want a flower to smell, taste and feel, and the app finds the ones that match — on any menu, with a written verdict for every result. Discover, experience, evolve.
Up to three taste identities — e.g. Gas / Fuel bombs, Evening knock-out, Sweet tropics — each defined across aroma, flavour, effect, texture, potency and priority weights. A completeness ring unlocks matching at 60%.
A deterministic scoring engine reading the same sensory vocabulary as the questionnaire, catalog and audit log. No black-box ML — every match ships a per-sense breakdown and a written verdict.
Paste a dispensary menu as text — a deterministic parser pulls out grower, THC, price and weight — and get a ranked #1 / #2 / #3 board plus the full list, each row expandable into the analysis, with a compare-two side-by-side view.
A virtual fourth profile that mixes two or three real ones with a bias slider and a bridge mode (min-across-worlds, so only strains strong in every world survive). Solves “I want both moods tonight.”
An editorial catalog of 895 curated strains — sommelier-style curator notes, lineage, market aliases and a sensory family taxonomy (all in the language the engine reads from), with hand-drawn poster art for the headline strains.
A member’s shelf of tried and wishlisted flowers, plus a two-strain compare view that decomposes match scores by profile and by sense.
A member can answer the questionnaire — or simply describe a flower they loved, or an experience they had, and let the app infer the profile from it. The inference is shown back, with its contradictions named, before it becomes a taste identity.
Eight editorial pieces on how to read a flower — terpenes, sensory families, why potency is the least interesting number on a label — in the same sommelier voice as the verdicts.
“Candied tropical nose over a creamy gelato base; a soft, rounded evening lean. A near-perfect fit for your Sweet tropics profile.”
Engine, questionnaire and strain data all draw from one canonical
vocabulary object (VOCAB_VERSION), so a score is always
reproducible from stored inputs — audit rows survive vocab migrations
by pivoting on the version.
Every visitor gets a signed anonymous UUID cookie; profile, history and audit log accumulate under it. Registering just sets username, email and password hash on the same row, so nothing is lost. HMAC session tokens validate in-process so a DB blip never silently logs a member out. Verification and reset tokens are stored only as hashes, single-use and expiring; deleting an account removes the row.
The whole site sits behind a 21+ acknowledgement that states, before anything else, what SŌMA is and isn’t: an educational sensory resource, not a seller, not affiliated with any dispensary, and it never tells anyone where to buy. The acknowledgement is versioned, so the gate returns if the disclaimer’s substance changes.
First paint started in “did it freeze?” territory. Fix: cache the assembled catalog (hundreds of thousands of comparisons no longer paid per cold start), trim the per-card payload sharply, paginate to 40 cards with IntersectionObserver infinite scroll, and add an instant skeleton.
Every gold surface is pure CSS — no image assets: masked hollow-ring borders, sculpted medallion rings with a debossed cream well, star-shine glints, and a 42% frosted card that lets the embossed leaf backdrop show through. All theme-aware.
Gilded champagne-gold and frosted-cream cards on an embossed cannabis-leaf backdrop. Display in Fraunces (a high-contrast antiqua), UI in Inter. Every microcopy line reads like a sommelier note, not a marketing bullet — sensory-family gradients shift per strain territory (gas-og, garlic-funk, citrus-haze…).
Next.js 15 (App Router · React 19 · Server Components) with TypeScript and Tailwind. Prisma over PostgreSQL (Supabase); custom scrypt + HMAC-cookie auth (no auth library). OpenAI is optional — it only rewrites the written verdicts and infers off-catalog strain names; it never touches the scores. Tested with Node’s built-in test runner plus a stress harness that guards against “the illusion of intelligence.”
Profiles, the match engine, the Blender, Harvest, Collection, Compare, accounts and the audit log all run today, against a catalog of 895 curated strains. What is not settled:
◆ ◆ ◆
SŌMA is live — step into the tasting room.