// stickers.jsx — 30 hand-drawn watercolor SVG stickers for the dream collage
// Each sticker exports { id, name, nameEn, categories, keywords, render() }
// Style: 1.4px ink stroke, soft watercolor wash underneath in palette colors.
const INK = "#2a2018";
const WINE = "#8b3a3a";
const FOREST = "#3a5a4a";
const GOLD = "#c89668";
const ROSE = "#c97b7b";
const DUST = "#6b7a8f";
const NIGHT = "#2a3856";
// Shared filter for watercolor edge wobble
const WC_FILTER = (
);
const wash = (d, color, opacity = 0.32) => (
);
const ink = (d, extra = {}) => (
);
// ============== STICKERS ==============
const STICKERS = [
// --- celestial ---
{
id: "moon-crescent",
name: "三日月",
nameEn: "The Crescent",
categories: ["celestial"],
keywords: ["月", "夜", "眠り", "三日月", "光", "moon", "夢"],
render: () => (
),
},
{
id: "moon-full",
name: "満月",
nameEn: "Full Moon",
categories: ["celestial"],
keywords: ["月", "満月", "夜", "光", "moon", "fullmoon"],
render: () => (
),
},
{
id: "star",
name: "星",
nameEn: "Star",
categories: ["celestial"],
keywords: ["星", "光", "夜", "star", "希望"],
render: () => (
),
},
{
id: "constellation",
name: "星座",
nameEn: "Constellation",
categories: ["celestial"],
keywords: ["星座", "夜空", "占い", "stars"],
render: () => (
),
},
{
id: "cloud",
name: "雲",
nameEn: "Cloud",
categories: ["celestial", "nature"],
keywords: ["雲", "空", "ふわふわ", "cloud"],
render: () => (
),
},
{
id: "comet",
name: "彗星",
nameEn: "Comet",
categories: ["celestial"],
keywords: ["彗星", "流れ星", "comet", "願い"],
render: () => (
),
},
// --- objects ---
{
id: "key",
name: "鍵",
nameEn: "The Key",
categories: ["object"],
keywords: ["鍵", "秘密", "扉", "解く", "key"],
render: () => (
),
},
{
id: "door",
name: "扉",
nameEn: "The Door",
categories: ["object", "architecture"],
keywords: ["扉", "ドア", "出口", "入口", "door", "選択"],
render: () => (
),
},
{
id: "mirror",
name: "鏡",
nameEn: "The Mirror",
categories: ["object"],
keywords: ["鏡", "自分", "影", "mirror", "真実"],
render: () => (
),
},
{
id: "clock",
name: "時計",
nameEn: "The Hour",
categories: ["object"],
keywords: ["時計", "時間", "clock", "刻"],
render: () => (
),
},
{
id: "book",
name: "本",
nameEn: "The Book",
categories: ["object"],
keywords: ["本", "物語", "書物", "book", "記憶"],
render: () => (
),
},
{
id: "candle",
name: "蝋燭",
nameEn: "Candle",
categories: ["object"],
keywords: ["蝋燭", "ろうそく", "炎", "光", "candle"],
render: () => (
),
},
{
id: "staircase",
name: "階段",
nameEn: "Staircase",
categories: ["object", "architecture"],
keywords: ["階段", "登る", "降りる", "stairs"],
render: () => (
),
},
{
id: "window",
name: "窓",
nameEn: "Window",
categories: ["object", "architecture"],
keywords: ["窓", "光", "外", "window"],
render: () => (
),
},
{
id: "ladder",
name: "梯子",
nameEn: "Ladder",
categories: ["object"],
keywords: ["梯子", "登る", "ladder", "天"],
render: () => (
),
},
{
id: "envelope",
name: "手紙",
nameEn: "Letter",
categories: ["object"],
keywords: ["手紙", "便り", "letter", "メッセージ"],
render: () => (
),
},
// --- nature ---
{
id: "tree",
name: "木",
nameEn: "The Tree",
categories: ["nature"],
keywords: ["木", "森", "tree", "成長", "根"],
render: () => (
),
},
{
id: "mountain",
name: "山",
nameEn: "Mountain",
categories: ["nature"],
keywords: ["山", "高い", "mountain", "頂"],
render: () => (
),
},
{
id: "ocean",
name: "海",
nameEn: "The Sea",
categories: ["nature"],
keywords: ["海", "波", "水", "sea", "深い"],
render: () => (
),
},
{
id: "rose",
name: "薔薇",
nameEn: "The Rose",
categories: ["nature", "plant"],
keywords: ["薔薇", "ばら", "rose", "愛", "花"],
render: () => (
),
},
{
id: "leaf",
name: "葉",
nameEn: "Leaf",
categories: ["nature", "plant"],
keywords: ["葉", "leaf", "草"],
render: () => (
),
},
{
id: "feather",
name: "羽根",
nameEn: "Feather",
categories: ["nature"],
keywords: ["羽根", "羽", "feather", "軽い"],
render: () => (
),
},
// --- animals ---
{
id: "butterfly",
name: "蝶",
nameEn: "The Butterfly",
categories: ["animal"],
keywords: ["蝶", "ちょう", "変化", "butterfly", "夢"],
render: () => (
),
},
{
id: "fish",
name: "魚",
nameEn: "The Fish",
categories: ["animal"],
keywords: ["魚", "水", "泳ぐ", "fish"],
render: () => (
),
},
{
id: "bird",
name: "鳥",
nameEn: "The Bird",
categories: ["animal"],
keywords: ["鳥", "とり", "飛ぶ", "bird", "自由"],
render: () => (
),
},
{
id: "cat",
name: "猫",
nameEn: "The Cat",
categories: ["animal"],
keywords: ["猫", "ねこ", "cat"],
render: () => (
),
},
{
id: "snake",
name: "蛇",
nameEn: "The Serpent",
categories: ["animal"],
keywords: ["蛇", "へび", "snake", "変化"],
render: () => (
),
},
{
id: "owl",
name: "梟",
nameEn: "The Owl",
categories: ["animal"],
keywords: ["梟", "ふくろう", "owl", "知恵", "夜"],
render: () => (
),
},
{
id: "deer",
name: "鹿",
nameEn: "The Deer",
categories: ["animal"],
keywords: ["鹿", "しか", "deer", "森"],
render: () => (
),
},
// --- abstract / element ---
{
id: "eye",
name: "目",
nameEn: "The Eye",
categories: ["abstract", "person"],
keywords: ["目", "視る", "見つめる", "eye"],
render: () => (
),
},
{
id: "tear",
name: "涙",
nameEn: "The Tear",
categories: ["abstract"],
keywords: ["涙", "泣く", "tear", "悲しみ", "雨"],
render: () => (
),
},
{
id: "flame",
name: "炎",
nameEn: "The Flame",
categories: ["abstract"],
keywords: ["炎", "火", "情熱", "flame", "fire"],
render: () => (
),
},
{
id: "hand",
name: "手",
nameEn: "The Hand",
categories: ["abstract", "person"],
keywords: ["手", "te", "hand", "つかむ"],
render: () => (
),
},
{
id: "spiral",
name: "渦",
nameEn: "The Spiral",
categories: ["abstract"],
keywords: ["渦", "うず", "spiral", "迷路", "螺旋"],
render: () => (
),
},
{
id: "rain",
name: "雨",
nameEn: "The Rain",
categories: ["nature", "abstract"],
keywords: ["雨", "あめ", "rain", "涙"],
render: () => (
),
},
{
id: "crystal",
name: "結晶",
nameEn: "Crystal",
categories: ["object", "abstract"],
keywords: ["結晶", "宝石", "crystal", "石"],
render: () => (
),
},
{
id: "mushroom",
name: "茸",
nameEn: "Mushroom",
categories: ["plant", "nature"],
keywords: ["茸", "きのこ", "mushroom"],
render: () => (
),
},
];
// recommendation: given a list of keyword strings, return sticker ids in relevance order
function recommendStickers(keywords) {
const kws = keywords.map(k => k.toLowerCase().trim()).filter(Boolean);
if (!kws.length) return STICKERS.map(s => s.id);
const scored = STICKERS.map(s => {
let score = 0;
const haystack = [
s.name, s.nameEn, ...s.keywords, ...s.categories,
].join(" ").toLowerCase();
kws.forEach(kw => {
if (!kw) return;
// exact word match boost
if (s.keywords.some(k => k.toLowerCase() === kw)) score += 5;
// substring match
if (haystack.includes(kw)) score += 2;
// synonym buckets
const syn = SYNONYMS[kw] || [];
syn.forEach(syn => { if (haystack.includes(syn)) score += 1.5; });
});
return { s, score };
});
// Sort: high score first, then alpha
scored.sort((a, b) => b.score - a.score);
return scored.map(x => x.s.id);
}
const SYNONYMS = {
"夜": ["月", "星", "moon", "夜空", "暗い"],
"悲しい": ["涙", "雨", "tear"],
"怖い": ["蛇", "炎", "暗い", "影"],
"嬉しい": ["蝶", "光", "花", "星"],
"海": ["魚", "波", "水"],
"森": ["木", "鹿", "葉"],
"空": ["雲", "鳥", "月", "星"],
"光": ["蝋燭", "月", "炎", "星"],
"迷う": ["扉", "鍵", "渦", "階段"],
"誰か": ["手", "目", "人"],
"変化": ["蝶", "蛇", "月"],
"知る": ["梟", "本", "鏡"],
"愛": ["薔薇", "蝶", "手紙"],
};
window.STICKERS = STICKERS;
window.recommendStickers = recommendStickers;