{"release_id":"01a1c502-4ad1-0000-ec62-adc54d3c69aa","chunk_id":"01a1c502-4c44-76d1-bb96-8fddbd6ce5d8","file":"JG46b6Vr.mjs","mappings":"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","names":["busy","error","desc","$.prop","$$props","msg","compose","picked","$.state","message","tipTitle","t","canSend","$.derived","$.get","dismiss","$.set","choose","kind","amount","send","button","$.first_child","fragment_1","div","div_1","p","strong","$.sibling","text","p_1","div_2","$.each","TIP_PRESETS","amt","button_1","root_2","span","$.child","span_1","TokenCoin","$.reset","classes","$.set_class","$.set_attribute","$.delegated","$.append","$$anchor","button_2","span_2","span_3","node_3","textarea","fragment_2","$.remove_textarea_child","button_3","$.template_effect","$0","$.set_text","text_8","text_9","text_10","d","text_11","$$render","consequent_2","alternate","consequent_1","$$value","consequent_3","div_3","root_8","consequent_4","button_4","node_5","classes_1","GIFT_PRO_TOKEN_COST"],"sources":["../../../../../../src/lib/components/TipSheet.svelte"],"sourcesContent":["<script lang=\"ts\">\n\t/**\n\t * RAT-462: the tip / gift-Pro picker, lifted out of the chat page so the two\n\t * surfaces that offer it — the open conversation and the profile's message\n\t * button — can never drift apart.\n\t *\n\t * The sheet owns the presentation and the choice; it does NOT own what happens\n\t * next. The chat inserts an optimistic gift card, the profile navigates into\n\t * the conversation the tribute just opened. Both hand that back through\n\t * `onpick`, and both keep their own busy/error state so the sheet stays\n\t * stateless (and testable) on its own.\n\t */\n\timport TokenCoin from '$lib/components/TokenCoin.svelte';\n\timport { t } from '$lib/i18n';\n\timport { msg } from '$lib/i18n/mark';\n\timport { TIP_PRESETS, GIFT_PRO_TOKEN_COST } from '$lib/token-packages';\n\n\tinterface Props {\n\t\topen: boolean;\n\t\t/** Recipient handle, rendered in the header. */\n\t\tnickname: string;\n\t\tonclose: () => void;\n\t\t/** Called with the chosen gift. `amount` is 0 for the Pro gift; `message`\n\t\t *  is only ever set in compose mode. */\n\t\tonpick: (kind: 'tokens' | 'pro', amount: number, message?: string) => void;\n\t\tbusy?: boolean;\n\t\terror?: string;\n\t\t/** Optional line under the title — the profile entry uses it for the\n\t\t *  reply-rate note; the in-chat sheet leaves it at the default. */\n\t\tdesc?: string;\n\t\t/** Compose mode (RAT-462, profile entry): picking an amount SELECTS it\n\t\t *  instead of firing, and a message field appears so the tribute and the\n\t\t *  words leave together.\n\t\t *\n\t\t *  This exists because the message is the part that works: a gift sent\n\t\t *  with a message gets a reply 94.2% of the time (n=206) against 30.0%\n\t\t *  for a bare one (n=40). Inside an open conversation there's already\n\t\t *  context, so the chat keeps the plain one-tap behaviour. */\n\t\tcompose?: boolean;\n\t}\n\n\tlet {\n\t\topen,\n\t\tnickname,\n\t\tonclose,\n\t\tonpick,\n\t\tbusy = false,\n\t\terror = '',\n\t\tdesc = msg('drop tokens, or gift them a month of Pro'),\n\t\tcompose = false\n\t}: Props = $props();\n\n\tlet picked = $state<{ kind: 'tokens' | 'pro'; amount: number } | null>(null);\n\tlet message = $state('');\n\n\t// One sentence for translators; the handle is set in bold between its halves.\n\tconst tipTitle = $derived(t('send {name} a tip').split('{name}'));\n\tconst canSend = $derived(!!picked && message.trim().length > 0 && !busy);\n\n\t/** Cancel/backdrop only — a deliberate abandon clears the draft.\n\t *\n\t *  A programmatic close does NOT: running out of tokens closes this to open\n\t *  the top-up modal, and losing what they'd already typed on the way to\n\t *  paying would be its own small betrayal. A successful send navigates away,\n\t *  so leftover state there is moot. */\n\tfunction dismiss() {\n\t\tpicked = null;\n\t\tmessage = '';\n\t\tonclose();\n\t}\n\n\tfunction choose(kind: 'tokens' | 'pro', amount: number) {\n\t\tif (!compose) {\n\t\t\tonpick(kind, amount);\n\t\t\treturn;\n\t\t}\n\t\tpicked = { kind, amount };\n\t}\n\n\tfunction send() {\n\t\tif (!picked || !canSend) return;\n\t\tonpick(picked.kind, picked.amount, message.trim());\n\t}\n</script>\n\n{#if open}\n\t<button type=\"button\" class=\"tip-backdrop\" aria-label={t('close')} onclick={dismiss}></button>\n\t<div class=\"tip-sheet\" role=\"dialog\" aria-modal=\"true\">\n\t\t<div class=\"tip-head\">\n\t\t\t<p class=\"tip-title\">{tipTitle[0]}<strong>@{nickname}</strong>{tipTitle[1] ?? ''}</p>\n\t\t\t<p class=\"tip-desc\">{t(desc)}</p>\n\t\t</div>\n\t\t<div class=\"tip-grid\">\n\t\t\t{#each TIP_PRESETS as amt (amt)}\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tdisabled={busy}\n\t\t\t\t\tonclick={() => choose('tokens', amt)}\n\t\t\t\t\tclass=\"tip-card\"\n\t\t\t\t\tclass:is-picked={picked?.kind === 'tokens' && picked.amount === amt}\n\t\t\t\t\taria-pressed={compose ? picked?.kind === 'tokens' && picked.amount === amt : undefined}\n\t\t\t\t>\n\t\t\t\t\t<span class=\"tip-amt\">{amt}</span>\n\t\t\t\t\t<span class=\"tip-lbl\"><TokenCoin size={11} /> {t('tokens')}</span>\n\t\t\t\t</button>\n\t\t\t{/each}\n\t\t</div>\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdisabled={busy}\n\t\t\tonclick={() => choose('pro', 0)}\n\t\t\tclass=\"gift-pro\"\n\t\t\tclass:is-picked={picked?.kind === 'pro'}\n\t\t\taria-pressed={compose ? picked?.kind === 'pro' : undefined}\n\t\t>\n\t\t\t<span class=\"gift-pro-left\"><span class=\"pro-chip\">pro</span> {t('gift 30 days')}</span>\n\t\t\t<span class=\"gift-pro-cost\">{GIFT_PRO_TOKEN_COST} <TokenCoin size={14} /></span>\n\t\t</button>\n\n\t\t{#if compose}\n\t\t\t<textarea\n\t\t\t\tclass=\"tip-msg\"\n\t\t\t\tbind:value={message}\n\t\t\t\tdisabled={busy}\n\t\t\t\tmaxlength=\"1000\"\n\t\t\t\trows=\"3\"\n\t\t\t\tplaceholder={t('say something — this is the part that gets a reply')}\n\t\t\t></textarea>\n\t\t\t<button type=\"button\" class=\"tip-send\" disabled={!canSend} onclick={send}>\n\t\t\t\t{#if busy}\n\t\t\t\t\t{t('sending…')}\n\t\t\t\t{:else if !picked}\n\t\t\t\t\t{t('pick an amount')}\n\t\t\t\t{:else if !message.trim()}\n\t\t\t\t\t{t('write a message')}\n\t\t\t\t{:else}\n\t\t\t\t\t{t('send')}\n\t\t\t\t{/if}\n\t\t\t</button>\n\t\t{/if}\n\n\t\t{#if error}<div class=\"tip-err\">{error}</div>{/if}\n\t\t<button type=\"button\" onclick={dismiss} class=\"tip-cancel\">{t('cancel')}</button>\n\t</div>\n{/if}\n\n<style>\n\t.tip-backdrop { position: fixed; inset: 0; z-index: 65; background: rgba(0, 0, 0, 0.55); backdrop-filter: blur(4px); border: none; cursor: default; }\n\t.tip-sheet {\n\t\tposition: fixed; left: 50%; bottom: 0; transform: translateX(-50%); z-index: 66;\n\t\twidth: 100%; max-width: 440px;\n\t\tbackground: var(--color-bg); border: 1px solid var(--color-border); border-bottom: none;\n\t\tborder-radius: 20px 20px 0 0;\n\t\tpadding: 20px 20px calc(22px + env(safe-area-inset-bottom, 0px));\n\t\tbox-shadow: 0 -16px 40px -10px rgba(0, 0, 0, 0.6);\n\t}\n\t@media (min-width: 480px) {\n\t\t.tip-sheet { bottom: auto; top: 50%; transform: translate(-50%, -50%); border-radius: 20px; border-bottom: 1px solid var(--color-border); }\n\t}\n\t.tip-head { margin-bottom: 14px; }\n\t.tip-title { font-size: 14px; color: var(--color-muted); }\n\t.tip-title strong { font-weight: 600; color: var(--color-text); }\n\t.tip-desc { font-size: 12px; color: color-mix(in srgb, var(--color-muted) 65%, transparent); margin-top: 2px; }\n\t.tip-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }\n\t.tip-card { display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 12px 0; border-radius: 14px; border: 1px solid var(--color-border); background: var(--color-surface); cursor: pointer; transition: border-color 0.15s, background 0.15s, transform 0.1s; }\n\t.tip-card:hover:not(:disabled) { border-color: var(--color-accent); background: var(--color-accent-light); }\n\t.tip-card:active:not(:disabled) { transform: scale(0.96); }\n\t.tip-card:disabled { opacity: 0.5; cursor: default; }\n\t.tip-amt { font-family: var(--font-display); font-size: 18px; font-weight: 800; letter-spacing: -0.02em; color: var(--color-text); }\n\t.tip-lbl { display: inline-flex; align-items: center; gap: 3px; font-size: 11px; color: var(--color-muted); }\n\t.gift-pro { display: flex; align-items: center; justify-content: space-between; width: 100%; margin-top: 10px; padding: 13px 16px; border-radius: 14px; border: 1px solid var(--color-border); background: var(--color-surface); cursor: pointer; transition: border-color 0.15s; }\n\t.gift-pro:hover:not(:disabled) { border-color: var(--color-accent); }\n\t.gift-pro:disabled { opacity: 0.5; cursor: default; }\n\t.gift-pro-left { display: inline-flex; align-items: center; gap: 8px; font-family: var(--font-display); font-size: 14px; font-weight: 700; color: var(--color-text); }\n\t.pro-chip { font-family: var(--font-display); font-size: 9px; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; padding: 2px 6px; border-radius: 5px; background: var(--color-accent); color: var(--color-bg); }\n\t.gift-pro-cost { display: inline-flex; align-items: center; gap: 4px; font-family: var(--font-display); font-size: 14px; font-weight: 700; color: var(--color-text); }\n\t.tip-card.is-picked, .gift-pro.is-picked { border-color: var(--color-accent); background: var(--color-accent-light); }\n\t.tip-msg {\n\t\twidth: 100%; margin-top: 12px; padding: 11px 13px;\n\t\tborder-radius: 14px; border: 1px solid var(--color-border);\n\t\tbackground: var(--color-surface); color: var(--color-text);\n\t\tfont-family: inherit; font-size: 14px; line-height: 1.45;\n\t\tresize: none;\n\t}\n\t.tip-msg::placeholder { color: color-mix(in srgb, var(--color-muted) 70%, transparent); }\n\t.tip-msg:focus { outline: none; border-color: var(--color-accent); }\n\t.tip-send {\n\t\twidth: 100%; margin-top: 10px; padding: 13px 0;\n\t\tborder-radius: 14px; border: none;\n\t\tbackground: var(--color-accent); color: #fff;\n\t\tfont-family: var(--font-display); font-size: 14px; font-weight: 700;\n\t\tcursor: pointer; transition: opacity 0.15s;\n\t}\n\t.tip-send:disabled { opacity: 0.4; cursor: default; }\n\t.tip-err { margin-top: 10px; font-size: 13px; color: var(--color-coral); }\n\t.tip-cancel { width: 100%; margin-top: 14px; padding: 6px 0; text-align: center; font-size: 13px; color: color-mix(in srgb, var(--color-muted) 60%, transparent); background: none; border: none; cursor: pointer; }\n\t.tip-cancel:hover { color: var(--color-muted); }\n</style>\n"],"version":3}