{"release_id":"01a1c502-4ad1-0000-ec62-adc54d3c69aa","chunk_id":"01a1c502-4c13-7fd3-8703-fe0070a81ea0","file":"D0QDrNmr.mjs","mappings":"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","names":["EMOJI_CATEGORIES","msg","c","tab","$.state","activeCategory","recent","$.proxy","gifQuery","gifResults","gifLoading","gifError","gifSearchDebounce","onMount","raw","parsed","$.set","x","pushRecent","emoji","next","$.get","e","handleEmojiTap","handleGifTap","gif","fetchGifs","q","res","t","body","$.user_effect","$$props","onScrimKeydown","jumpToCategory","id","el","button","$.first_child","fragment_1","div","$.sibling","div_1","$.child","button_1","button_2","div_2","fragment_2","button_3","root_3","classes_2","$.set_attribute","$0","$.append","$$anchor","$$render","consequent","$.each","node_3","button_4","root_4","text","$.reset","classes_3","$.set_class","$.set_text","$.delegated","div_3","h3","fragment_3","div_4","button_5","root_6","text_2","$.template_effect","text_1","consequent_1","node_5","h3_1","fragment_4","div_5","button_6","root_8","text_4","div_6","fragment_5","input","$.remove_input_defaults","div_7","p","root_10","p_1","root_11","text_6","p_2","root_12","text_7","div_8","root_13","g","button_7","root_14","img","consequent_3","consequent_4","consequent_5","alternate","$$value","consequent_2","alternate_1","$1","classes","classes_1","$$args"],"sources":["../../../../../../src/lib/data/emojis.ts","../../../../../../src/lib/components/chat/EmojiGifPicker.svelte"],"sourcesContent":["/**\n * RAT-334: curated emoji set for the chat composer picker.\n *\n * Hand-picked subset (~300 emojis) instead of the full unicode catalog\n * (3,800+) because:\n *   • We want a ~5KB import, not a 200KB picker library.\n *   • Most users only need a few dozen emojis — the long tail of flags,\n *     country codes, and obscure object emojis is more noise than help.\n *   • Hand-curating means we can put the actually-popular ones first\n *     (laughing-crying, hearts, fire) without leaning on a frequency\n *     database.\n *\n * \"Recent\" is filled at runtime from localStorage in the picker — no\n * default entries; the user's own picks live there.\n *\n * Each category is a flat array of unicode codepoints. The picker\n * deduplicates if a recent entry already appears in a category.\n */\n\nimport { msg } from '$lib/i18n/mark';\n\nexport type EmojiCategory = {\n\tid: 'recent' | 'smileys' | 'gestures' | 'hearts' | 'animals' | 'food' | 'activities' | 'objects';\n\tlabel: string;\n\t// Single-char icon shown in the category tab strip. We pick one that\n\t// reads at small sizes — flat colour, no skin-tone modifier.\n\ticon: string;\n\temojis: string[];\n};\n\nexport const EMOJI_CATEGORIES: EmojiCategory[] = [\n\t{\n\t\tid: 'smileys',\n\t\tlabel: msg('smileys'),\n\t\ticon: '😊',\n\t\temojis: [\n\t\t\t'😀', '😃', '😄', '😁', '😆', '😅', '🤣', '😂', '🙂', '🙃',\n\t\t\t'😉', '😊', '😇', '🥰', '😍', '🤩', '😘', '😗', '😚', '😋',\n\t\t\t'😛', '😜', '🤪', '😝', '🤑', '🤗', '🤭', '🤫', '🤔', '🤐',\n\t\t\t'🤨', '😐', '😑', '😶', '😏', '😒', '🙄', '😬', '😌', '😔',\n\t\t\t'😪', '🤤', '😴', '😷', '🤒', '🤕', '🤢', '🤮', '🤧', '🥵',\n\t\t\t'🥶', '🥴', '😵', '🤯', '🤠', '🥳', '😎', '🤓', '🧐', '😕',\n\t\t\t'😟', '🙁', '☹️', '😮', '😯', '😲', '😳', '🥺', '😦', '😧',\n\t\t\t'😨', '😰', '😥', '😢', '😭', '😱', '😖', '😣', '😞', '😓',\n\t\t\t'😩', '😫', '🥱', '😤', '😡', '😠', '🤬', '😈', '👿', '💀',\n\t\t\t'☠️', '💩', '🤡', '👹', '👺', '👻', '👽', '👾', '🤖'\n\t\t]\n\t},\n\t{\n\t\tid: 'gestures',\n\t\tlabel: msg('gestures'),\n\t\ticon: '👍',\n\t\temojis: [\n\t\t\t'👍', '👎', '👌', '🤌', '🤏', '✌️', '🤞', '🤟', '🤘', '🤙',\n\t\t\t'👈', '👉', '👆', '👇', '☝️', '✋', '🤚', '🖐️', '🖖', '👋',\n\t\t\t'🤝', '🙏', '✍️', '💅', '🤳', '💪', '🦵', '🦶', '👂', '👃',\n\t\t\t'🧠', '👁️', '👀', '👄', '👅', '💋', '🩸'\n\t\t]\n\t},\n\t{\n\t\tid: 'hearts',\n\t\tlabel: msg('hearts'),\n\t\ticon: '❤️',\n\t\temojis: [\n\t\t\t'❤️', '🧡', '💛', '💚', '💙', '💜', '🖤', '🤍', '🤎', '💔',\n\t\t\t'❣️', '💕', '💞', '💓', '💗', '💖', '💘', '💝', '💟', '♥️',\n\t\t\t'💌', '🌹', '🌷', '💐', '😻', '😽'\n\t\t]\n\t},\n\t{\n\t\tid: 'animals',\n\t\tlabel: msg('animals'),\n\t\ticon: '🐶',\n\t\temojis: [\n\t\t\t'🐶', '🐱', '🐭', '🐹', '🐰', '🦊', '🐻', '🐼', '🐨', '🐯',\n\t\t\t'🦁', '🐮', '🐷', '🐸', '🐵', '🐔', '🐧', '🐦', '🐤', '🦆',\n\t\t\t'🦅', '🦉', '🐺', '🐗', '🐴', '🦄', '🐝', '🐛', '🦋', '🐌',\n\t\t\t'🐞', '🐜', '🪲', '🦗', '🕷️', '🦂', '🐢', '🐍', '🦎', '🐙',\n\t\t\t'🦑', '🦐', '🦀', '🐡', '🐠', '🐟', '🐬', '🐳', '🐋', '🦈'\n\t\t]\n\t},\n\t{\n\t\tid: 'food',\n\t\tlabel: msg('food'),\n\t\ticon: '🍕',\n\t\temojis: [\n\t\t\t'🍎', '🍐', '🍊', '🍋', '🍌', '🍉', '🍇', '🍓', '🫐', '🍈',\n\t\t\t'🍒', '🍑', '🥭', '🍍', '🥥', '🥝', '🍅', '🍆', '🥑', '🥦',\n\t\t\t'🥬', '🥒', '🌶️', '🫑', '🌽', '🥕', '🫒', '🧄', '🧅', '🥔',\n\t\t\t'🍠', '🥐', '🥯', '🍞', '🥖', '🥨', '🧀', '🥚', '🍳', '🧈',\n\t\t\t'🥞', '🧇', '🥓', '🥩', '🍗', '🍖', '🌭', '🍔', '🍟', '🍕',\n\t\t\t'🌮', '🌯', '🥙', '🥗', '🍿', '🧂', '🥫', '🍱', '🍘', '🍙',\n\t\t\t'🍚', '🍛', '🍜', '🍝', '🍢', '🍣', '🍤', '🍥', '🥮',\n\t\t\t'🍡', '🥟', '🥠', '🥡', '🦞', '🍦', '🍧', '🍨', '🍩',\n\t\t\t'🍪', '🎂', '🍰', '🧁', '🥧', '🍫', '🍬', '🍭', '🍮', '🍯',\n\t\t\t'🍼', '🥛', '☕', '🍵', '🍶', '🍾', '🍷', '🍸', '🍹', '🍺',\n\t\t\t'🍻', '🥂', '🥃', '🥤', '🧋', '🧃', '🧉', '🧊'\n\t\t]\n\t},\n\t{\n\t\tid: 'activities',\n\t\tlabel: msg('activities'),\n\t\ticon: '🎉',\n\t\temojis: [\n\t\t\t'🎉', '🎊', '🎈', '🎂', '🎁', '🎀', '🥳', '🎆', '🎇', '🧨',\n\t\t\t'✨', '🎄', '🎃', '🎗️', '🏆', '🥇', '🥈', '🥉', '⚽', '🏀',\n\t\t\t'🏈', '⚾', '🥎', '🎾', '🏐', '🏉', '🥏', '🎱', '🏓', '🏸',\n\t\t\t'🥊', '🥋', '🎯', '⛳', '🪁', '🎣', '🤿', '🎽', '🛹', '🛼',\n\t\t\t'🛷', '⛸️', '🎮', '🕹️', '🎲', '🧩', '🎭', '🎨', '🎬', '🎤',\n\t\t\t'🎧', '🎼', '🎹', '🥁', '🎷', '🎺', '🎸', '🪕', '🎻'\n\t\t]\n\t},\n\t{\n\t\tid: 'objects',\n\t\tlabel: msg('objects'),\n\t\ticon: '💡',\n\t\temojis: [\n\t\t\t'🔥', '💯', '⭐', '🌟', '💫', '⚡', '☄️', '💥', '🌈', '☀️',\n\t\t\t'🌤️', '⛅', '🌧️', '⛈️', '❄️', '☃️', '⛄', '💧', '💦', '☔',\n\t\t\t'💡', '🔦', '🕯️', '💵', '💴', '💶', '💷', '💰', '💳', '💎',\n\t\t\t'⚖️', '🔧', '🔨', '⚙️', '🔗', '🧲', '🔫', '💣', '🧨', '🪓',\n\t\t\t'🔪', '⚔️', '🛡️', '🚬', '⚰️', '🪦', '⚱️', '🏺', '🧭', '🗺️',\n\t\t\t'🪙', '📞', '📱', '💻', '⌨️', '🖥️', '🖨️', '🖱️', '💾', '💿',\n\t\t\t'📀', '📷', '🎞️', '📺', '📻', '⏰', '⏱️', '⏲️', '🕰️', '⌚',\n\t\t\t'📡', '🔋', '🔌', '🪫', '🧱', '🪜', '🛒', '🚀', '🛸', '⛵',\n\t\t\t'🚗', '🚙', '🏎️', '🚕', '🚌', '🚓', '🚑', '🚒', '🛺', '🚲',\n\t\t\t'🛴', '🏍️', '✈️', '🚁', '🚂', '🚆', '🛬', '⛽', '🚦'\n\t\t]\n\t}\n];\n\n/** Convenience flat list for search / dedup helpers. */\nexport const ALL_EMOJIS = EMOJI_CATEGORIES.flatMap((c) => c.emojis);\n","<script lang=\"ts\">\n\t/**\n\t * RAT-334: tabbed emoji + GIF picker for the chat composer.\n\t *\n\t * Bottom sheet on every viewport (Telegram pattern) — not a popover.\n\t * Mobile (`< md`): full-width sheet, hugs viewport bottom + safe-area.\n\t * Desktop (`md+`): centered max-w-md sheet, ~440px tall.\n\t *\n\t * Two tabs (emoji / gif):\n\t *   • Emoji: scrollable grid grouped by category, sticky category\n\t *     strip up top. Tap → onPickEmoji(unicode). Recent emojis are\n\t *     persisted in localStorage and surface as the first row.\n\t *   • GIF: search input + 2-3 col grid. Default = trending. Tap →\n\t *     onPickGif(gif). Lazy: the GIPHY proxy is only hit when the\n\t *     GIF tab opens (cold-start savings on first paint).\n\t *\n\t * Dismiss: Escape, scrim tap, parent calls close(). The parent's\n\t * trigger button needs to stopPropagation on click — without it\n\t * the click bubbles into the newly-mounted scrim in the SAME tick\n\t * Svelte renders, immediately closing the sheet.\n\t *\n\t * Per CLAUDE.md: no neon glow, neutral shadow only.\n\t */\n\n\timport { onMount } from 'svelte';\n\timport { EMOJI_CATEGORIES } from '$lib/data/emojis';\n\timport { t } from '$lib/i18n';\n\timport type { GifSearchResult } from '../../../routes/api/gif/search/+server';\n\n\ttype Tab = 'emoji' | 'gif';\n\n\ttype Props = {\n\t\topen: boolean;\n\t\tonPickEmoji: (emoji: string) => void;\n\t\tonPickGif: (gif: GifSearchResult) => void;\n\t\tonClose: () => void;\n\t};\n\n\tlet { open, onPickEmoji, onPickGif, onClose }: Props = $props();\n\n\tlet tab = $state<Tab>('emoji');\n\tlet activeCategory = $state<string>('smileys');\n\tlet recent = $state<string[]>([]);\n\n\tlet gifQuery = $state('');\n\tlet gifResults = $state<GifSearchResult[]>([]);\n\tlet gifLoading = $state(false);\n\tlet gifError = $state<string | null>(null);\n\tlet gifSearchDebounce: ReturnType<typeof setTimeout> | null = null;\n\n\tonMount(() => {\n\t\ttry {\n\t\t\tconst raw = localStorage.getItem('rat-334-recent-emoji');\n\t\t\tif (raw) {\n\t\t\t\tconst parsed = JSON.parse(raw);\n\t\t\t\tif (Array.isArray(parsed)) {\n\t\t\t\t\trecent = parsed.filter((x): x is string => typeof x === 'string').slice(0, 32);\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// silent\n\t\t}\n\t});\n\n\tfunction pushRecent(emoji: string) {\n\t\tconst next = [emoji, ...recent.filter((e) => e !== emoji)].slice(0, 32);\n\t\trecent = next;\n\t\ttry {\n\t\t\tlocalStorage.setItem('rat-334-recent-emoji', JSON.stringify(next));\n\t\t} catch {\n\t\t\t// silent\n\t\t}\n\t}\n\n\tfunction handleEmojiTap(emoji: string) {\n\t\tpushRecent(emoji);\n\t\tonPickEmoji(emoji);\n\t}\n\n\tfunction handleGifTap(gif: GifSearchResult) {\n\t\tonPickGif(gif);\n\t\tonClose();\n\t}\n\n\tasync function fetchGifs(q: string) {\n\t\tgifLoading = true;\n\t\tgifError = null;\n\t\ttry {\n\t\t\tconst res = await fetch(`/api/gif/search?q=${encodeURIComponent(q)}&limit=24`);\n\t\t\tif (!res.ok) {\n\t\t\t\tgifError = res.status === 503 ? t('gif search not set up yet') : t('something broke');\n\t\t\t\tgifResults = [];\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst body = (await res.json()) as { results: GifSearchResult[] };\n\t\t\tgifResults = body.results;\n\t\t} catch {\n\t\t\tgifError = t('network error');\n\t\t\tgifResults = [];\n\t\t} finally {\n\t\t\tgifLoading = false;\n\t\t}\n\t}\n\n\t$effect(() => {\n\t\tif (!open || tab !== 'gif') return;\n\t\tif (gifSearchDebounce) clearTimeout(gifSearchDebounce);\n\t\tconst q = gifQuery.trim();\n\t\tgifSearchDebounce = setTimeout(() => fetchGifs(q), q ? 250 : 0);\n\t\treturn () => {\n\t\t\tif (gifSearchDebounce) clearTimeout(gifSearchDebounce);\n\t\t};\n\t});\n\n\tfunction onScrimKeydown(e: KeyboardEvent) {\n\t\tif (open && e.key === 'Escape') onClose();\n\t}\n\n\tfunction jumpToCategory(id: string) {\n\t\tactiveCategory = id;\n\t\tconst el = document.getElementById(`emoji-cat-${id}`);\n\t\tif (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });\n\t}\n</script>\n\n<svelte:window onkeydown={onScrimKeydown} />\n\n{#if open}\n\t<!-- Scrim: full-viewport overlay that catches outside taps. Solid\n\t\t black @ 50% on mobile (Telegram look), keeps the focus on the\n\t\t sheet. The button stops propagation on its own onclick so the\n\t\t same tap doesn't fire the trigger button again. -->\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"picker-scrim\"\n\t\taria-label={t('close picker')}\n\t\tonclick={onClose}\n\t></button>\n\n\t<!-- The sheet — bottom-anchored, slides up. -->\n\t<div\n\t\tclass=\"sheet\"\n\t\trole=\"dialog\"\n\t\taria-modal=\"true\"\n\t\taria-label={tab === 'emoji' ? t('emoji picker') : t('gif picker')}\n\t>\n\t\t<!-- Drag handle — visual cue this is a bottom sheet. Not interactive\n\t\t\t (mobile gesture-to-dismiss would be cute but is out of scope). -->\n\t\t<div class=\"sheet-handle\" aria-hidden=\"true\"></div>\n\n\t\t<div class=\"sheet-tabs\">\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"sheet-tab\"\n\t\t\t\tclass:sheet-tab--active={tab === 'emoji'}\n\t\t\t\tonclick={() => (tab = 'emoji')}\n\t\t\t>\n\t\t\t\temoji\n\t\t\t</button>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"sheet-tab\"\n\t\t\t\tclass:sheet-tab--active={tab === 'gif'}\n\t\t\t\tonclick={() => (tab = 'gif')}\n\t\t\t>\n\t\t\t\tgif\n\t\t\t</button>\n\t\t</div>\n\n\t\t{#if tab === 'emoji'}\n\t\t\t<div class=\"cat-strip\">\n\t\t\t\t{#if recent.length > 0}\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"cat-btn\"\n\t\t\t\t\t\tclass:cat-btn--active={activeCategory === 'recent'}\n\t\t\t\t\t\tonclick={() => jumpToCategory('recent')}\n\t\t\t\t\t\taria-label={t('recent')}\n\t\t\t\t\t>\n\t\t\t\t\t\t🕒\n\t\t\t\t\t</button>\n\t\t\t\t{/if}\n\t\t\t\t{#each EMOJI_CATEGORIES as c (c.id)}\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"cat-btn\"\n\t\t\t\t\t\tclass:cat-btn--active={activeCategory === c.id}\n\t\t\t\t\t\tonclick={() => jumpToCategory(c.id)}\n\t\t\t\t\t\taria-label={t(c.label)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{c.icon}\n\t\t\t\t\t</button>\n\t\t\t\t{/each}\n\t\t\t</div>\n\n\t\t\t<div class=\"sheet-body\">\n\t\t\t\t{#if recent.length > 0}\n\t\t\t\t\t<h3 id=\"emoji-cat-recent\" class=\"cat-head\">{t('recent')}</h3>\n\t\t\t\t\t<div class=\"emoji-grid\">\n\t\t\t\t\t\t{#each recent as e (e)}\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"emoji-btn\"\n\t\t\t\t\t\t\t\tonclick={() => handleEmojiTap(e)}\n\t\t\t\t\t\t\t\taria-label={e}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{e}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t{/each}\n\t\t\t\t\t</div>\n\t\t\t\t{/if}\n\t\t\t\t{#each EMOJI_CATEGORIES as c (c.id)}\n\t\t\t\t\t<h3 id=\"emoji-cat-{c.id}\" class=\"cat-head\">{t(c.label)}</h3>\n\t\t\t\t\t<div class=\"emoji-grid\">\n\t\t\t\t\t\t{#each c.emojis as e (c.id + e)}\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"emoji-btn\"\n\t\t\t\t\t\t\t\tonclick={() => handleEmojiTap(e)}\n\t\t\t\t\t\t\t\taria-label={e}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{e}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t{/each}\n\t\t\t\t\t</div>\n\t\t\t\t{/each}\n\t\t\t</div>\n\t\t{:else}\n\t\t\t<div class=\"gif-search\">\n\t\t\t\t<svg\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\tclass=\"gif-search-ico\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t>\n\t\t\t\t\t<circle cx=\"11\" cy=\"11\" r=\"7\" />\n\t\t\t\t\t<path d=\"M21 21l-4.35-4.35\" />\n\t\t\t\t</svg>\n\t\t\t\t<input\n\t\t\t\t\tclass=\"gif-search-input\"\n\t\t\t\t\ttype=\"search\"\n\t\t\t\t\tplaceholder={t('search gifs…')}\n\t\t\t\t\tbind:value={gifQuery}\n\t\t\t\t\tautocomplete=\"off\"\n\t\t\t\t/>\n\t\t\t</div>\n\n\t\t\t<div class=\"sheet-body sheet-body--gif\">\n\t\t\t\t{#if gifError}\n\t\t\t\t\t<p class=\"gif-state\">{gifError}</p>\n\t\t\t\t{:else if gifLoading && gifResults.length === 0}\n\t\t\t\t\t<p class=\"gif-state\">{t('loading…')}</p>\n\t\t\t\t{:else if gifResults.length === 0}\n\t\t\t\t\t<p class=\"gif-state\">{t('no gifs')}</p>\n\t\t\t\t{:else}\n\t\t\t\t\t<div class=\"gif-grid\">\n\t\t\t\t\t\t{#each gifResults as g (g.id)}\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"gif-cell\"\n\t\t\t\t\t\t\t\tonclick={() => handleGifTap(g)}\n\t\t\t\t\t\t\t\taria-label={g.title}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<img src={g.previewUrl} alt={g.title} loading=\"lazy\" />\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t{/each}\n\t\t\t\t\t</div>\n\t\t\t\t{/if}\n\t\t\t</div>\n\t\t{/if}\n\t</div>\n{/if}\n\n<style>\n\t.picker-scrim {\n\t\tposition: fixed;\n\t\tinset: 0;\n\t\tz-index: 70;\n\t\tbackground: rgba(0, 0, 0, 0.55);\n\t\tborder: 0;\n\t\tpadding: 0;\n\t\tcursor: default;\n\t\tanimation: scrim-in 180ms ease-out;\n\t}\n\t@keyframes scrim-in {\n\t\tfrom { opacity: 0; }\n\t\tto { opacity: 1; }\n\t}\n\n\t.sheet {\n\t\tposition: fixed;\n\t\tleft: 0;\n\t\tright: 0;\n\t\tbottom: 0;\n\t\tz-index: 71;\n\t\tmax-height: min(560px, 70dvh);\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tbackground: var(--color-bg);\n\t\tborder-top: 1px solid var(--color-border);\n\t\tborder-radius: 18px 18px 0 0;\n\t\tpadding-bottom: env(safe-area-inset-bottom, 0px);\n\t\tbox-shadow: 0 -12px 30px -10px rgba(0, 0, 0, 0.55);\n\t\tanimation: sheet-up 220ms cubic-bezier(0.16, 1, 0.3, 1);\n\t}\n\t@keyframes sheet-up {\n\t\tfrom { transform: translateY(100%); }\n\t\tto { transform: translateY(0); }\n\t}\n\n\t/* Desktop: centered, narrower. Still bottom-anchored — the trigger\n\t   is in the composer at the bottom, so anchoring there feels right. */\n\t@media (min-width: 768px) {\n\t\t.sheet {\n\t\t\tleft: 50%;\n\t\t\tright: auto;\n\t\t\ttransform: translateX(-50%);\n\t\t\twidth: min(440px, calc(100vw - 32px));\n\t\t\tmax-height: 560px;\n\t\t\tborder-radius: 18px 18px 0 0;\n\t\t}\n\t\t@keyframes sheet-up {\n\t\t\tfrom { transform: translateX(-50%) translateY(100%); }\n\t\t\tto { transform: translateX(-50%) translateY(0); }\n\t\t}\n\t}\n\n\t.sheet-handle {\n\t\twidth: 36px;\n\t\theight: 4px;\n\t\tborder-radius: 2px;\n\t\tbackground: var(--color-border);\n\t\tmargin: 8px auto 4px;\n\t\tflex-shrink: 0;\n\t}\n\n\t.sheet-tabs {\n\t\tdisplay: flex;\n\t\tflex-shrink: 0;\n\t\tborder-bottom: 1px solid var(--color-border);\n\t}\n\t.sheet-tab {\n\t\tflex: 1;\n\t\tpadding: 12px 16px;\n\t\tbackground: none;\n\t\tborder: 0;\n\t\tborder-bottom: 2px solid transparent;\n\t\tcolor: var(--color-muted);\n\t\tfont-family: var(--font-display);\n\t\tfont-size: 12px;\n\t\tfont-weight: 700;\n\t\tletter-spacing: 0.12em;\n\t\ttext-transform: uppercase;\n\t\tcursor: pointer;\n\t\ttransition: color 0.15s ease-out;\n\t}\n\t.sheet-tab:hover {\n\t\tcolor: var(--color-text);\n\t}\n\t.sheet-tab--active {\n\t\tcolor: var(--color-text);\n\t\tborder-bottom-color: var(--color-accent);\n\t}\n\n\t.cat-strip {\n\t\tdisplay: flex;\n\t\tgap: 2px;\n\t\tpadding: 6px 8px;\n\t\tflex-shrink: 0;\n\t\tborder-bottom: 1px solid var(--color-border);\n\t\toverflow-x: auto;\n\t\tscrollbar-width: none;\n\t}\n\t.cat-strip::-webkit-scrollbar { display: none; }\n\t.cat-btn {\n\t\tflex-shrink: 0;\n\t\twidth: 36px;\n\t\theight: 36px;\n\t\tdisplay: inline-flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\tbackground: none;\n\t\tborder: 0;\n\t\tborder-radius: 8px;\n\t\tcursor: pointer;\n\t\tfont-size: 20px;\n\t\tline-height: 1;\n\t\ttransition: background 0.15s ease-out;\n\t}\n\t.cat-btn:hover { background: var(--color-surface); }\n\t.cat-btn--active { background: var(--color-surface); }\n\n\t.sheet-body {\n\t\tflex: 1;\n\t\toverflow-y: auto;\n\t\tpadding: 8px 12px 20px;\n\t\tscrollbar-width: thin;\n\t\tscrollbar-color: var(--color-border) transparent;\n\t}\n\t.sheet-body::-webkit-scrollbar { width: 6px; }\n\t.sheet-body::-webkit-scrollbar-track { background: transparent; }\n\t.sheet-body::-webkit-scrollbar-thumb { background: var(--color-border); border-radius: 3px; }\n\n\t.cat-head {\n\t\tmargin: 12px 4px 6px;\n\t\tfont-family: var(--font-display);\n\t\tfont-size: 10px;\n\t\tfont-weight: 700;\n\t\tletter-spacing: 0.12em;\n\t\ttext-transform: uppercase;\n\t\tcolor: var(--color-muted);\n\t}\n\t.cat-head:first-child { margin-top: 4px; }\n\n\t.emoji-grid {\n\t\tdisplay: grid;\n\t\tgrid-template-columns: repeat(auto-fill, minmax(40px, 1fr));\n\t\tgap: 2px;\n\t}\n\t.emoji-btn {\n\t\tdisplay: inline-flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\twidth: 100%;\n\t\taspect-ratio: 1;\n\t\tbackground: none;\n\t\tborder: 0;\n\t\tborder-radius: 8px;\n\t\tcursor: pointer;\n\t\tfont-size: 24px;\n\t\tline-height: 1;\n\t\tpadding: 0;\n\t\ttransition: background 0.1s ease-out, transform 0.1s ease-out;\n\t}\n\t.emoji-btn:hover { background: var(--color-surface); }\n\t.emoji-btn:active { background: var(--color-surface); transform: scale(0.85); }\n\n\t.gif-search {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tgap: 8px;\n\t\tpadding: 10px 12px;\n\t\tflex-shrink: 0;\n\t\tborder-bottom: 1px solid var(--color-border);\n\t}\n\t.gif-search-ico { width: 16px; height: 16px; color: var(--color-muted); flex-shrink: 0; }\n\t.gif-search-input {\n\t\tflex: 1;\n\t\tmin-width: 0;\n\t\tbackground: none;\n\t\tborder: 0;\n\t\tcolor: var(--color-text);\n\t\tfont: inherit;\n\t\tfont-size: 13px;\n\t\toutline: none;\n\t\t/* Kill the native search input chrome — iOS Safari + Chrome\n\t\t   ship a default cyan focus ring on type=\"search\" that\n\t\t   `outline: none` alone doesn't cover. */\n\t\t-webkit-appearance: none;\n\t\tappearance: none;\n\t\tbox-shadow: none;\n\t}\n\t.gif-search-input:focus,\n\t.gif-search-input:focus-visible {\n\t\toutline: none;\n\t\tbox-shadow: none;\n\t}\n\t.gif-search-input::-webkit-search-cancel-button {\n\t\t-webkit-appearance: none;\n\t\tappearance: none;\n\t}\n\t.gif-search-input::placeholder { color: var(--color-muted); }\n\n\t.sheet-body--gif { padding: 6px; }\n\t.gif-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 4px; }\n\t@media (min-width: 480px) { .gif-grid { grid-template-columns: repeat(3, 1fr); } }\n\t.gif-cell {\n\t\tdisplay: block;\n\t\twidth: 100%;\n\t\taspect-ratio: 1;\n\t\tbackground: var(--color-surface);\n\t\tborder: 0;\n\t\tborder-radius: 8px;\n\t\toverflow: hidden;\n\t\tcursor: pointer;\n\t\tpadding: 0;\n\t\ttransition: transform 0.1s ease-out;\n\t}\n\t.gif-cell:active { transform: scale(0.97); }\n\t.gif-cell img { width: 100%; height: 100%; object-fit: cover; display: block; }\n\n\t.gif-state {\n\t\tmargin: 32px 0;\n\t\ttext-align: center;\n\t\tfont-size: 13px;\n\t\tcolor: var(--color-muted);\n\t}\n</style>\n"],"version":3}