{"release_id":"01a1c502-4ad1-0000-ec62-adc54d3c69aa","chunk_id":"01a1c502-4bf0-7da2-bf2f-46d0d5696888","file":"CQYERiQZ.mjs","mappings":"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","names":["variant","netScore","$.state","$.proxy","$$props","viewerVote","inFlight","$.user_effect","vote","target","goto","page","next","delta","$.get","prevVote","prevScore","$.set","res","j","div","root_1","button","$.child","span","$.sibling","button_1","$.set_attribute","$0","$.set_class","$1","t","div_1","root_2","button_2","span_1","text_1","$.reset","button_3","$$render","consequent","alternate","POST_BOOST_TOKENS_PER_HOUR","POST_BOOST_MAX_TOKENS","localBoostedUntil","localBoostCount","hoursLeft","$.derived","ms","open","amount","hours","boosting","error","showBuyTokens","nextUrl","dec","inc","openSheet","boost","b","$.delegated","$.append","$$anchor","node_1","span_2","root_3","$.template_effect","$.set_text","span_3","root_4","text_2","consequent_1","alternate_1","root_5","h3","p","strong","span_4","text_5","div_2","div_3","span_5","span_6","text_7","button_4","button_5","text_9","node_3","p_1","root_6","consequent_2","p_2","root_7","consequent_3","$5","$7","consequent_4","BuyTokensModal","node_5","URL_RE","TRAIL_PUNCT","balanceParens","url","trailing","openCount","linkify","text","out","lastIndex","m","matchStart","matchText","trailingPunct","urlPart","balancedUrl","parens","href","linkClass","segments","$.each","node","seg","a","$.clsx","initialComments","$.prop","withInput","replyTarget","comments","fmt","d","date","diffMs","mins","hrs","days","appendComment","c","remove","commentId","canDelete","reportCommentId","canReport","reactionPickerFor","togglingReaction","onDocClick","onKey","e","toggleReaction","comment","emoji","event","applyReactionEvent","startReply","scrollToComment","id","section","$.first_child","fragment","ul","li","getAvatarUrl","DuelAvatar","fragment_1","UserBadge","node_2","ReplyQuote","node_4","video","img","root_8","LinkifiedText","alternate_2","alternate_3","div_4","root_11","ReactionChips","node_9","fragment_4","node_11","div_5","root_13","ALLOWED_REACTIONS","root_14","text_4","scale","quintOut","consequent_5","consequent_7","root_15","d_1","root_16","d_2","ReportContentModal","consequent_10","div_6","root_18","CommentInput","node_16","consequent_11","cls","imgClass","loading","imgEl","loaded","errored","STALL_MS","nudges","timer","settle","el","handleLoad","handleError","trackImageLoadError","retry","root","$$value","$.event","$.replay_events","tributeOpen","tributeBusy","tributeError","buyOpen","buyReason","chatHref","resolve","headParts","portal","sendTribute","kind","message","body","GIFT_PRO_TOKEN_COST","TokenCoin","$2","$3","TRIBUTE_REPLY_RATE_COPY","$$args","msg","TipSheet","$$node","expanded","framed","onModRemove","messageCta","isOwner","chooserOpen","messageCreator","trackPostToChat","openAuthSheet","menuOpen","reportOpen","slideIndex","carouselEl","shareCopied","shareTimer","sharePost","u","title","shareOrCopy","result","trackShare","crossImageFailed","crossImageFailedB","removingTier","removeMeFromTierlist","invalidateAll","videoEl","videoMuted","obs","entries","entry","toggleMute","videoTap","openReport","fmtDate","deletePost","imageResignAttempts","resignPostMedia","profileHref","postHref","cardClick","article","header","a_1","text_3","text_6","a_2","pa","sinceLabel","LOCALE_INFO","locale","div_7","x","$$array_1","sz","svg","$.set_style","div_8","node_7","node_8","div_9","part","i","root_9","div_10","TIERS","div_11","h2","root_12","text_11","consequent_6","div_12","node_10","tier","rowEntries","div_13","div_14","div_15","a_3","node_12","text_12","button_6","text_14","slides","div_16","root_17","div_17","fragment_5","a_4","root_19","ImageWithShimmer","node_15","text_15","div_18","$.index","_","root_20","button_7","root_21","button_8","root_22","a_5","root_23","node_18","consequent_12","div_19","root_24","node_19","root_25","text_16","button_9","node_20","svg_1","root_26","svg_2","root_27","consequent_15","a_6","root_28","node_21","consequent_17","div_20","div_21","root_30","consequent_18","div_22","node_22","root_31","consequent_19","text_18","crossUrl","crossLabel","crossCta","crossIcon","crossImageSrc","crossImageSrcB","a_7","root_32","node_24","div_23","root_33","div_24","video_1","root_34","img_1","root_35","consequent_21","alternate_4","div_25","video_2","root_36","img_2","root_37","consequent_22","alternate_5","div_26","root_38","video_3","fragment_7","node_28","span_7","root_40","text_20","button_10","node_29","svg_3","root_41","svg_4","root_42","consequent_25","alternate_6","img_3","root_43","consequent_26","alternate_7","div_27","root_44","span_8","div_28","span_9","styles","text_21","consequent_23","consequent_27","consequent_28","div_29","div_30","div_31","div_32","div_33","consequent_9","consequent_13","consequent_16","consequent_20","consequent_29","footer","node_6","VoteStack","node_30","a_8","span_10","a_9","fragment_8","span_11","node_32","MessageChooser","consequent_30","div_34","node_31","PostBoostButton","node_33","button_11","node_34","span_12","fragment_9","text_28","span_13","fragment_10","text_29","consequent_31","alternate_8","div_35","root_48","CommentSection","node_36","consequent_32","node_37"],"sources":["../../../../../../src/lib/components/post/VoteStack.svelte","../../../../../../src/lib/post-boost.ts","../../../../../../src/lib/components/post/PostBoostButton.svelte","../../../../../../src/lib/linkify.ts","../../../../../../src/lib/components/post/LinkifiedText.svelte","../../../../../../src/lib/components/post/CommentSection.svelte","../../../../../../src/lib/components/post/ImageWithShimmer.svelte","../../../../../../src/lib/components/MessageChooser.svelte","../../../../../../src/lib/components/post/PostCard.svelte"],"sourcesContent":["<script lang=\"ts\">\n\timport { t } from '$lib/i18n';\n\t/**\n\t * RAT-272 follow-up: reddit-style upvote/downvote stack for PostCard.\n\t *\n\t * Three states: -1 (downvoted), 0 (no vote), 1 (upvoted). Tapping the\n\t * arrow that's already active clears the vote; tapping the opposite\n\t * one switches in a single API call. Optimistic update on the netScore\n\t * + viewerVote so the UI feels instant; failures roll back.\n\t *\n\t * Anonymous viewers see the arrows but get bounced to /auth/sign-in\n\t * with a return path — same friction-low pattern as the niche subscribe\n\t * button.\n\t */\n\n\timport { goto } from '$app/navigation';\n\timport { page } from '$app/state';\n\n\tinterface Props {\n\t\tpostId: string;\n\t\tinitialNetScore: number;\n\t\tinitialViewerVote: -1 | 0 | 1;\n\t\tviewerLoggedIn: boolean;\n\t\t/** 'bar' (default) = the horizontal pill for the feed-card footer.\n\t\t *  'rail' (RAT-446) = a vertical ↑ N ↓ stack for the reels action rail,\n\t\t *  styled to match the rail's translucent circular icons. */\n\t\tvariant?: 'bar' | 'rail';\n\t}\n\n\tlet { postId, initialNetScore, initialViewerVote, viewerLoggedIn, variant = 'bar' }: Props = $props();\n\n\tlet netScore = $state(initialNetScore);\n\tlet viewerVote = $state<-1 | 0 | 1>(initialViewerVote);\n\tlet inFlight = $state(false);\n\n\t// Re-seed when the parent re-renders with new props (e.g. invalidateAll\n\t// after a vote elsewhere). Wrapped in $effect to keep the local state\n\t// trackable + idempotent. RAT-117 anti-pattern guard.\n\t$effect(() => {\n\t\tnetScore = initialNetScore;\n\t});\n\t$effect(() => {\n\t\tviewerVote = initialViewerVote;\n\t});\n\n\tasync function vote(target: -1 | 1) {\n\t\tif (!viewerLoggedIn) {\n\t\t\tgoto(`/auth/sign-in?next=${encodeURIComponent(page.url.pathname + page.url.search)}`);\n\t\t\treturn;\n\t\t}\n\t\tif (inFlight) return;\n\n\t\t// Tapping the active arrow clears; tapping the other switches.\n\t\tconst next: -1 | 0 | 1 = viewerVote === target ? 0 : target;\n\t\tconst delta = next - viewerVote;\n\t\t// Optimistic update — roll back on failure.\n\t\tconst prevVote = viewerVote;\n\t\tconst prevScore = netScore;\n\t\tviewerVote = next;\n\t\tnetScore = netScore + delta;\n\t\tinFlight = true;\n\t\ttry {\n\t\t\tconst res = await fetch(`/api/post/${postId}/vote`, {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders: { 'content-type': 'application/json' },\n\t\t\t\tbody: JSON.stringify({ value: next })\n\t\t\t});\n\t\t\tif (!res.ok) {\n\t\t\t\tviewerVote = prevVote;\n\t\t\t\tnetScore = prevScore;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Reconcile to server truth — covers concurrent votes from other\n\t\t\t// devices, transient drift from the non-transactional delta apply\n\t\t\t// in the API endpoint.\n\t\t\tconst j = (await res.json()) as { netScore: number; viewerVote: -1 | 0 | 1 };\n\t\t\tnetScore = j.netScore;\n\t\t\tviewerVote = j.viewerVote;\n\t\t} catch {\n\t\t\tviewerVote = prevVote;\n\t\t\tnetScore = prevScore;\n\t\t} finally {\n\t\t\tinFlight = false;\n\t\t}\n\t}\n</script>\n\n{#if variant === 'rail'}\n\t<div class=\"flex flex-col items-center gap-0.5 rounded-full border border-white/15 bg-black/45 px-1 py-1.5 drop-shadow\">\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tonclick={() => vote(1)}\n\t\t\tdisabled={inFlight}\n\t\t\taria-label={viewerVote === 1 ? t('remove upvote') : t('upvote')}\n\t\t\taria-pressed={viewerVote === 1}\n\t\t\tclass=\"flex h-6 w-6 items-center justify-center transition-colors {viewerVote === 1 ? 'text-accent' : 'text-white hover:text-accent'}\"\n\t\t>\n\t\t\t<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n\t\t\t\t<path d=\"M12 19V5M5 12l7-7 7 7\" />\n\t\t\t</svg>\n\t\t</button>\n\t\t<span class=\"font-display text-[12px] font-bold leading-none tabular-nums {viewerVote === 1 ? 'text-accent' : viewerVote === -1 ? 'text-coral' : 'text-white'}\">\n\t\t\t{netScore}\n\t\t</span>\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tonclick={() => vote(-1)}\n\t\t\tdisabled={inFlight}\n\t\t\taria-label={viewerVote === -1 ? t('remove downvote') : t('downvote')}\n\t\t\taria-pressed={viewerVote === -1}\n\t\t\tclass=\"flex h-6 w-6 items-center justify-center transition-colors {viewerVote === -1 ? 'text-coral' : 'text-white hover:text-coral'}\"\n\t\t>\n\t\t\t<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n\t\t\t\t<path d=\"M12 5v14M5 12l7 7 7-7\" />\n\t\t\t</svg>\n\t\t</button>\n\t</div>\n{:else}\n<div class=\"inline-flex items-center gap-0.5 rounded-lg border border-border bg-surface/40\">\n\t<button\n\t\ttype=\"button\"\n\t\tonclick={() => vote(1)}\n\t\tdisabled={inFlight}\n\t\taria-label={viewerVote === 1 ? t('remove upvote') : t('upvote')}\n\t\taria-pressed={viewerVote === 1}\n\t\tclass=\"flex h-8 w-8 items-center justify-center rounded-l-lg transition-colors {viewerVote === 1\n\t\t\t? 'text-accent'\n\t\t\t: 'text-muted hover:text-text'}\"\n\t>\n\t\t<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n\t\t\t<path d=\"M12 19V5M5 12l7-7 7 7\" />\n\t\t</svg>\n\t</button>\n\t<span\n\t\tclass=\"min-w-[28px] text-center font-display text-[12px] font-bold tabular-nums {viewerVote === 1\n\t\t\t? 'text-accent'\n\t\t\t: viewerVote === -1\n\t\t\t\t? 'text-coral'\n\t\t\t\t: 'text-text'}\"\n\t>\n\t\t{netScore}\n\t</span>\n\t<button\n\t\ttype=\"button\"\n\t\tonclick={() => vote(-1)}\n\t\tdisabled={inFlight}\n\t\taria-label={viewerVote === -1 ? t('remove downvote') : t('downvote')}\n\t\taria-pressed={viewerVote === -1}\n\t\tclass=\"flex h-8 w-8 items-center justify-center rounded-r-lg transition-colors {viewerVote === -1\n\t\t\t? 'text-coral'\n\t\t\t: 'text-muted hover:text-text'}\"\n\t>\n\t\t<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n\t\t\t<path d=\"M12 5v14M5 12l7 7 7-7\" />\n\t\t</svg>\n\t</button>\n</div>\n{/if}\n","// RAT-424: client-safe constants for the feed post spotlight boost, shared by\n// the PostBoostButton UI and the server (tokens.ts re-exports these, boostPost\n// validates against them). Every POST_BOOST_TOKENS_PER_HOUR buys one hour at the\n// top of the /f For You feed; capped per single boost — stack more by boosting\n// again. Pricier than the beat boost (5 tok/hr) because a boosted post reaches\n// the whole logged-in audience, not just a beat's viewers.\nexport const POST_BOOST_TOKENS_PER_HOUR = 15;\nexport const POST_BOOST_MAX_TOKENS = 90; // 6h in one go\n","<script lang=\"ts\">\n\timport { t } from '$lib/i18n';\n\t/**\n\t * RAT-424: feed post spotlight boost. Self-contained (like VoteStack /\n\t * sharePost) so every PostCard consumer gets it for free — owns its own\n\t * confirm sheet + BuyTokensModal + login redirect. Any logged-in user can\n\t * boost any post: every POST_BOOST_TOKENS_PER_HOUR tokens buys one hour at the\n\t * top of the /f For You feed, seen by the whole logged-in audience. Buys\n\t * EXPOSURE only — the vote tally stays earned.\n\t */\n\timport { goto } from '$app/navigation';\n\timport { page } from '$app/state';\n\timport BuyTokensModal from '$lib/components/BuyTokensModal.svelte';\n\timport { POST_BOOST_TOKENS_PER_HOUR, POST_BOOST_MAX_TOKENS } from '$lib/post-boost';\n\n\tinterface Props {\n\t\tpostId: string;\n\t\t/** current spotlight end (ISO) — drives the \"Nh\" readout; null = not boosted. */\n\t\tboostedUntil: string | null;\n\t\t/** lifetime 🔥 tally on this post. */\n\t\tboostCount: number;\n\t\tviewerLoggedIn: boolean;\n\t\t/** 'bar' (default) = the inline 🔥 boost button for the feed-card footer.\n\t\t *  'rail' (RAT-446) = a circular flame icon for the reels action rail. */\n\t\tvariant?: 'bar' | 'rail';\n\t}\n\tlet { postId, boostedUntil, boostCount, viewerLoggedIn, variant = 'bar' }: Props = $props();\n\n\t// Local mirror so the card reflects a fresh boost without a reload, re-seeded\n\t// from the props whenever the feed reloads (invalidateAll) — the RAT-117\n\t// pattern (literal init + $effect reseed, same as /f's subscribed/onboarding\n\t// state) that avoids frozen local state after a reload.\n\tlet localBoostedUntil = $state<string | null>(null);\n\tlet localBoostCount = $state(0);\n\t$effect(() => {\n\t\tlocalBoostedUntil = boostedUntil;\n\t\tlocalBoostCount = boostCount;\n\t});\n\n\t// whole hours left in the spotlight (0 when not boosted / expired).\n\tconst hoursLeft = $derived.by(() => {\n\t\tif (!localBoostedUntil) return 0;\n\t\tconst ms = new Date(localBoostedUntil).getTime() - Date.now();\n\t\treturn ms > 0 ? Math.ceil(ms / 3_600_000) : 0;\n\t});\n\n\tlet open = $state(false);\n\t// tokens the booster will spend; defaults to one hour.\n\tlet amount = $state(POST_BOOST_TOKENS_PER_HOUR);\n\tconst hours = $derived(amount / POST_BOOST_TOKENS_PER_HOUR);\n\tlet boosting = $state(false);\n\tlet error = $state('');\n\tlet showBuyTokens = $state(false);\n\n\tconst nextUrl = $derived(page.url.pathname + page.url.search);\n\n\tfunction dec() {\n\t\tamount = Math.max(POST_BOOST_TOKENS_PER_HOUR, amount - POST_BOOST_TOKENS_PER_HOUR);\n\t}\n\tfunction inc() {\n\t\tamount = Math.min(POST_BOOST_MAX_TOKENS, amount + POST_BOOST_TOKENS_PER_HOUR);\n\t}\n\n\tfunction openSheet() {\n\t\t// login is the blocker — redirect synchronously (iOS user-activation).\n\t\tif (!viewerLoggedIn) {\n\t\t\tgoto('/auth/sign-in?next=' + encodeURIComponent(nextUrl));\n\t\t\treturn;\n\t\t}\n\t\tamount = POST_BOOST_TOKENS_PER_HOUR;\n\t\terror = '';\n\t\topen = true;\n\t}\n\n\tasync function boost() {\n\t\tif (boosting) return;\n\t\tboosting = true;\n\t\terror = '';\n\t\ttry {\n\t\t\tconst res = await fetch(`/api/post/${postId}/boost`, {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders: { 'content-type': 'application/json' },\n\t\t\t\tbody: JSON.stringify({ tokens: amount })\n\t\t\t});\n\t\t\tif (res.ok) {\n\t\t\t\tconst b = (await res.json()) as {\n\t\t\t\t\tboostedUntil: string;\n\t\t\t\t\tboostCount: number;\n\t\t\t\t\ttokensLeft: number;\n\t\t\t\t};\n\t\t\t\tlocalBoostedUntil = b.boostedUntil;\n\t\t\t\tlocalBoostCount = b.boostCount;\n\t\t\t\topen = false;\n\t\t\t} else if (res.status === 402) {\n\t\t\t\t// not enough tokens — hand off to the buy sheet.\n\t\t\t\topen = false;\n\t\t\t\tshowBuyTokens = true;\n\t\t\t} else if (res.status === 401) {\n\t\t\t\tgoto('/auth/sign-in?next=' + encodeURIComponent(nextUrl));\n\t\t\t} else {\n\t\t\t\terror = t('boost failed — try again');\n\t\t\t}\n\t\t} catch {\n\t\t\terror = t('network error');\n\t\t}\n\t\tboosting = false;\n\t}\n</script>\n\n{#if variant === 'rail'}\n\t<button\n\t\ttype=\"button\"\n\t\tonclick={openSheet}\n\t\tclass=\"flex flex-col items-center gap-0.5 text-white\"\n\t\taria-label={hoursLeft > 0 ? t('boosted — spotlighted {n}h', { n: hoursLeft }) : t('boost this post')}\n\t>\n\t\t<span class=\"flex h-9 w-9 items-center justify-center rounded-full border bg-black/45 text-[17px] leading-none {hoursLeft > 0 ? 'border-yellow/60' : 'border-white/15'}\" aria-hidden=\"true\">🔥</span>\n\t\t<span class=\"text-[10.5px] font-semibold leading-none drop-shadow {hoursLeft > 0 ? 'text-yellow' : ''}\">\n\t\t\t{hoursLeft > 0 ? t('{n}h', { n: hoursLeft }) : t('boost')}\n\t\t</span>\n\t</button>\n{:else}\n<button\n\ttype=\"button\"\n\tonclick={openSheet}\n\tclass=\"inline-flex items-center gap-1.5 text-sm transition-colors {hoursLeft > 0\n\t\t? 'font-semibold text-yellow'\n\t\t: 'text-muted hover:text-text'}\"\n\taria-label={hoursLeft > 0 ? t('boosted — spotlighted {n}h', { n: hoursLeft }) : t('boost this post')}\n>\n\t<span aria-hidden=\"true\">🔥</span>\n\t{#if hoursLeft > 0}\n\t\t<span class=\"tabular-nums\">{t('{n}h', { n: hoursLeft })}</span>\n\t{:else}\n\t\t<span>{t('boost')}</span>\n\t{/if}\n</button>\n{/if}\n\n{#if open}\n\t<div\n\t\tclass=\"fixed inset-0 z-[100] flex items-end justify-center sm:items-center\"\n\t\trole=\"dialog\"\n\t\taria-modal=\"true\"\n\t>\n\t\t<button\n\t\t\tclass=\"absolute inset-0 bg-black/70 backdrop-blur-sm\"\n\t\t\tonclick={() => (open = false)}\n\t\t\taria-label={t('Close')}\n\t\t></button>\n\n\t\t<div\n\t\t\tclass=\"relative w-full max-w-[400px] rounded-t-3xl border border-border bg-bg p-6 sm:mx-4 sm:rounded-3xl\"\n\t\t>\n\t\t\t<div class=\"flex justify-center pb-3 sm:hidden\">\n\t\t\t\t<div class=\"h-1 w-10 rounded-full bg-muted/20\"></div>\n\t\t\t</div>\n\n\t\t\t<h3 class=\"font-display text-2xl font-bold tracking-tight\">{t('🔥 boost this post')}</h3>\n\t\t\t<p class=\"mt-1.5 text-sm text-muted\">\n\t\t\t\t<strong class=\"font-semibold text-text\">{t('10× more eyes.')}</strong> {t('top of the feed — everyone sees it, not just your followers.')}\n\t\t\t\t<span class=\"whitespace-nowrap text-muted/70\">{t('{n} tok = 1h.', { n: POST_BOOST_TOKENS_PER_HOUR })}</span>\n\t\t\t</p>\n\n\t\t\t<div class=\"mt-5 flex justify-center\">\n\t\t\t\t<div class=\"inline-flex items-center rounded-xl border border-border bg-surface p-1\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonclick={dec}\n\t\t\t\t\t\tdisabled={amount <= POST_BOOST_TOKENS_PER_HOUR}\n\t\t\t\t\t\taria-label={t('less time')}\n\t\t\t\t\t\tclass=\"ph-no-rageclick flex h-9 w-9 items-center justify-center rounded-lg font-display text-lg leading-none text-text transition-colors hover:bg-bg disabled:opacity-30\"\n\t\t\t\t\t\t>−</button\n\t\t\t\t\t>\n\t\t\t\t\t<span class=\"px-3 text-center text-sm font-semibold tabular-nums whitespace-nowrap\">\n\t\t\t\t\t\t{amount} <span class=\"font-normal text-muted\">{t('tok · {n}h', { n: hours })}</span>\n\t\t\t\t\t</span>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonclick={inc}\n\t\t\t\t\t\tdisabled={amount >= POST_BOOST_MAX_TOKENS}\n\t\t\t\t\t\taria-label={t('more time')}\n\t\t\t\t\t\tclass=\"ph-no-rageclick flex h-9 w-9 items-center justify-center rounded-lg font-display text-lg leading-none text-text transition-colors hover:bg-bg disabled:opacity-30\"\n\t\t\t\t\t\t>+</button\n\t\t\t\t\t>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tonclick={boost}\n\t\t\t\tdisabled={boosting}\n\t\t\t\tclass=\"mt-5 w-full rounded-xl bg-yellow px-5 py-3 font-display text-[15px] font-bold tracking-tight text-bg transition-transform active:scale-[.99] disabled:opacity-60\"\n\t\t\t>\n\t\t\t\t🔥 {boosting ? t('boosting…') : t('boost for {n} tokens', { n: amount })}\n\t\t\t</button>\n\n\t\t\t{#if hoursLeft > 0}\n\t\t\t\t<p class=\"mt-3 text-center text-xs text-muted\">\n\t\t\t\t\t{localBoostCount > 0\n\t\t\t\t\t\t? t('already spotlighted {n}h · 🔥 {count} — boost again to extend.', { n: hoursLeft, count: localBoostCount })\n\t\t\t\t\t\t: t('already spotlighted {n}h — boost again to extend.', { n: hoursLeft })}\n\t\t\t\t</p>\n\t\t\t{/if}\n\t\t\t{#if error}\n\t\t\t\t<p class=\"mt-2 text-center text-xs text-coral\">{error}</p>\n\t\t\t{/if}\n\t\t</div>\n\t</div>\n{/if}\n\n<BuyTokensModal\n\topen={showBuyTokens}\n\tonclose={() => (showBuyTokens = false)}\n\treason={t('boost this post to the top of the feed')}\n\tsuccessPath={nextUrl}\n\tsource=\"post_boost\"\n/>\n","/** RAT-203: detect URLs inside user-generated text and split it into a list\n *  of plain text + url segments. The Svelte template iterates the segments and\n *  renders <a> for url ones and {text} for plain ones — never `{@html}`, so\n *  there is no XSS surface (URLs themselves are emitted as href + textContent).\n *\n *  Match scheme:\n *    - http(s)://… (must have a host)\n *    - bare www.… (rendered with implicit https://)\n *  Trailing punctuation that is unlikely to be part of the url (.,;!?:) is\n *  stripped back into the trailing text segment so \"see https://x.com.\" won't\n *  swallow the period. Parens are balanced so wikipedia-style links work. */\nexport interface LinkifySegment {\n\ttext: string;\n\thref?: string;\n}\n\nconst URL_RE = /\\b(?:(?:https?:\\/\\/)|(?:www\\.))[^\\s<>\"']+/gi;\nconst TRAIL_PUNCT = /[.,;:!?]+$/;\n\nfunction balanceParens(url: string): { url: string; trailing: string } {\n\tlet trailing = '';\n\tlet openCount = (url.match(/\\(/g) ?? []).length;\n\tconst closeCount = (url.match(/\\)/g) ?? []).length;\n\tif (closeCount > openCount) {\n\t\t// Drop the unmatched closing parens (they're text, not part of the url).\n\t\twhile (openCount < (url.match(/\\)/g) ?? []).length && url.endsWith(')')) {\n\t\t\ttrailing = ')' + trailing;\n\t\t\turl = url.slice(0, -1);\n\t\t\topenCount = (url.match(/\\(/g) ?? []).length;\n\t\t}\n\t}\n\treturn { url, trailing };\n}\n\nexport function linkify(text: string | null | undefined): LinkifySegment[] {\n\tif (!text) return [];\n\tconst out: LinkifySegment[] = [];\n\tlet lastIndex = 0;\n\tfor (const m of text.matchAll(URL_RE)) {\n\t\tconst matchStart = m.index ?? 0;\n\t\tconst matchText = m[0];\n\t\tif (matchStart > lastIndex) {\n\t\t\tout.push({ text: text.slice(lastIndex, matchStart) });\n\t\t}\n\t\t// Strip trailing punctuation + unbalanced parens back into plain text.\n\t\tconst trailingPunct = matchText.match(TRAIL_PUNCT)?.[0] ?? '';\n\t\tlet urlPart = trailingPunct ? matchText.slice(0, -trailingPunct.length) : matchText;\n\t\tconst { url: balancedUrl, trailing: parens } = balanceParens(urlPart);\n\t\turlPart = balancedUrl;\n\t\tconst trailing = parens + trailingPunct;\n\t\tconst href = urlPart.toLowerCase().startsWith('www.') ? `https://${urlPart}` : urlPart;\n\t\tout.push({ text: urlPart, href });\n\t\tif (trailing) out.push({ text: trailing });\n\t\tlastIndex = matchStart + matchText.length;\n\t}\n\tif (lastIndex < text.length) {\n\t\tout.push({ text: text.slice(lastIndex) });\n\t}\n\treturn out;\n}\n","<script lang=\"ts\">\n\timport { linkify } from '$lib/linkify';\n\n\tinterface Props {\n\t\ttext: string | null | undefined;\n\t\t/** Tailwind classes applied to the inline anchor tags. Keep the green\n\t\t *  underlined treatment by default — caller can override if a context\n\t\t *  needs different accent. */\n\t\tlinkClass?: string;\n\t}\n\n\tlet { text, linkClass = 'text-accent underline underline-offset-2 hover:opacity-80' }: Props = $props();\n\n\tconst segments = $derived(linkify(text));\n</script>\n\n{#each segments as seg, i (i)}\n\t{#if seg.href}\n\t\t<a\n\t\t\thref={seg.href}\n\t\t\ttarget=\"_blank\"\n\t\t\trel=\"noopener noreferrer nofollow\"\n\t\t\tclass={linkClass}\n\t\t>{seg.text}</a>\n\t{:else}\n\t\t{seg.text}\n\t{/if}\n{/each}\n","<script lang=\"ts\">\n\timport { t } from '$lib/i18n';\n\timport DuelAvatar from '$lib/components/duel/DuelAvatar.svelte';\n\timport UserBadge from '$lib/components/UserBadge.svelte';\n\timport CommentInput from '$lib/components/post/CommentInput.svelte';\n\timport LinkifiedText from '$lib/components/post/LinkifiedText.svelte';\n\timport ReportContentModal from '$lib/components/ReportContentModal.svelte';\n\timport ReplyQuote from '$lib/components/chat/ReplyQuote.svelte';\n\timport ReactionChips from '$lib/components/chat/ReactionChips.svelte';\n\timport { ALLOWED_REACTIONS, applyReactionEvent } from '$lib/chat/reactions';\n\timport { getAvatarUrl } from '$lib/avatar';\n\timport { scale } from 'svelte/transition';\n\timport { quintOut } from 'svelte/easing';\n\timport type { CommentView } from '$lib/types/post';\n\n\tinterface Props {\n\t\tpostId: string;\n\t\tviewerLoggedIn: boolean;\n\t\tviewerId: string | null;\n\t\t/** id of the post creator — they can delete any comment on their post */\n\t\tpostCreatorId: string;\n\t\t/** Initial comments rendered SSR (typically the first batch from the server load). */\n\t\tinitialComments?: CommentView[];\n\t\t/** Render the comment input inline at the bottom of the section. Set\n\t\t *  false on the desktop detail view where the input is rendered\n\t\t *  separately as a sticky bottom bar. */\n\t\twithInput?: boolean;\n\t\t/** RAT-446: fires after the viewer posts a comment, so a parent showing a\n\t\t *  count (e.g. the reels viewer's header + rail badge) can bump it live. */\n\t\tonadded?: () => void;\n\t\t/** Comments 2.0: reply intent, bindable so a parent that renders its own\n\t\t *  CommentInput (the /post/[id] sticky bar) can hand it to that input. */\n\t\treplyTarget?: CommentView | null;\n\t}\n\n\tlet {\n\t\tpostId,\n\t\tviewerLoggedIn,\n\t\tviewerId,\n\t\tpostCreatorId,\n\t\tinitialComments = [],\n\t\twithInput = true,\n\t\tonadded,\n\t\treplyTarget = $bindable(null)\n\t}: Props = $props();\n\n\t// Always render the (possibly empty) list — the \"load comments →\" button\n\t// + \"no comments yet.\" placeholder were noise on cold posts. Empty state\n\t// reads cleaner with just the input below. SSR loader hands us the full\n\t// thread up front (it's bounded) so the lazy-load fetch is gone too.\n\t// RAT-117 pattern: writable $derived — resyncs when the parent hands us a\n\t// fresh list (the /post/[id] page appends into its own array and passes it\n\t// down live); in-place mutations (delete, reactions) override until then.\n\tlet comments = $derived<CommentView[]>(initialComments);\n\n\tfunction fmt(d: string) {\n\t\tconst date = new Date(d);\n\t\tconst diffMs = Date.now() - date.getTime();\n\t\tconst mins = Math.floor(diffMs / 60000);\n\t\tif (mins < 1) return t('now');\n\t\tif (mins < 60) return t('{n}m', { n: mins });\n\t\tconst hrs = Math.floor(mins / 60);\n\t\tif (hrs < 24) return t('{n}h', { n: hrs });\n\t\tconst days = Math.floor(hrs / 24);\n\t\tif (days < 7) return t('{n}d', { n: days });\n\t\treturn date.toLocaleDateString();\n\t}\n\n\tfunction appendComment(c: CommentView) {\n\t\tcomments = [...comments, c];\n\t\tonadded?.();\n\t}\n\n\tasync function remove(commentId: string) {\n\t\tif (!confirm(t('delete this comment?'))) return;\n\t\tconst res = await fetch(`/api/post/comment/${commentId}`, { method: 'DELETE' });\n\t\tif (res.ok) {\n\t\t\tcomments = comments.map((c) =>\n\t\t\t\tc.id === commentId\n\t\t\t\t\t? { ...c, body: '[deleted]', mediaUrl: null, deletedAt: new Date().toISOString() }\n\t\t\t\t\t: c\n\t\t\t);\n\t\t}\n\t}\n\n\tfunction canDelete(c: CommentView): boolean {\n\t\tif (c.deletedAt) return false;\n\t\tif (!viewerLoggedIn || !viewerId) return false;\n\t\tif (c.author?.id === viewerId) return true;\n\t\tif (postCreatorId === viewerId) return true;\n\t\treturn false;\n\t}\n\n\t// One shared modal for the whole section — holds the reported comment id.\n\tlet reportCommentId = $state<string | null>(null);\n\n\tfunction canReport(c: CommentView): boolean {\n\t\treturn !c.deletedAt && c.author?.id !== viewerId;\n\t}\n\n\t// ── reactions ──\n\t// Which comment's add-reaction popover is open (one at a time).\n\tlet reactionPickerFor = $state<string | null>(null);\n\tlet togglingReaction = $state(false);\n\n\t// Outside click / Escape dismisses the popover. Listeners only live while\n\t// one is open; the trigger button stopPropagations so its own click can't\n\t// re-close what it just opened.\n\t$effect(() => {\n\t\tif (reactionPickerFor === null) return;\n\t\tconst onDocClick = () => (reactionPickerFor = null);\n\t\tconst onKey = (e: KeyboardEvent) => {\n\t\t\tif (e.key === 'Escape') reactionPickerFor = null;\n\t\t};\n\t\tdocument.addEventListener('click', onDocClick);\n\t\tdocument.addEventListener('keydown', onKey);\n\t\treturn () => {\n\t\t\tdocument.removeEventListener('click', onDocClick);\n\t\t\tdocument.removeEventListener('keydown', onKey);\n\t\t};\n\t});\n\n\tasync function toggleReaction(comment: CommentView, emoji: string) {\n\t\tif (!viewerLoggedIn || !viewerId || togglingReaction) return;\n\t\treactionPickerFor = null;\n\t\ttogglingReaction = true;\n\t\ttry {\n\t\t\tconst res = await fetch(`/api/post/comment/${comment.id}/react`, {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders: { 'content-type': 'application/json' },\n\t\t\t\tbody: JSON.stringify({ emoji })\n\t\t\t});\n\t\t\tif (!res.ok) return;\n\t\t\tconst j = (await res.json()) as {\n\t\t\t\taction: 'added' | 'removed' | 'changed';\n\t\t\t\temoji: string;\n\t\t\t\tpreviousEmoji: string | null;\n\t\t\t};\n\t\t\tconst event =\n\t\t\t\tj.action === 'added'\n\t\t\t\t\t? ({ kind: 'add', emoji: j.emoji, userId: viewerId } as const)\n\t\t\t\t\t: j.action === 'removed'\n\t\t\t\t\t\t? ({ kind: 'remove', emoji: j.emoji, userId: viewerId } as const)\n\t\t\t\t\t\t: ({\n\t\t\t\t\t\t\t\tkind: 'change',\n\t\t\t\t\t\t\t\tpreviousEmoji: j.previousEmoji ?? j.emoji,\n\t\t\t\t\t\t\t\temoji: j.emoji,\n\t\t\t\t\t\t\t\tuserId: viewerId\n\t\t\t\t\t\t\t} as const);\n\t\t\tcomments = comments.map((c) =>\n\t\t\t\tc.id === comment.id ? { ...c, reactions: applyReactionEvent(c.reactions, event) } : c\n\t\t\t);\n\t\t} finally {\n\t\t\ttogglingReaction = false;\n\t\t}\n\t}\n\n\tfunction startReply(c: CommentView) {\n\t\treplyTarget = c;\n\t}\n\n\tfunction scrollToComment(id: string) {\n\t\tdocument.getElementById(`post-comment-${id}`)?.scrollIntoView({ behavior: 'smooth', block: 'center' });\n\t}\n</script>\n\n<section class=\"space-y-3\">\n\t<ul class=\"space-y-3\">\n\t\t{#each comments as c (c.id)}\n\t\t\t<li id=\"post-comment-{c.id}\" class=\"group flex items-start gap-2.5\">\n\t\t\t\t<DuelAvatar\n\t\t\t\t\tnickname={c.author?.nickname ?? null}\n\t\t\t\t\tavatarUrl={getAvatarUrl(c.author?.avatarPath)}\n\t\t\t\t\tsize={28}\n\t\t\t\t\thref={c.author?.nickname ? `/u/${c.author.nickname}` : ''}\n\t\t\t\t\tlink={false}\n\t\t\t\t/>\n\t\t\t\t<div class=\"min-w-0 flex-1 text-[13px] leading-snug\">\n\t\t\t\t\t<div class=\"flex items-baseline gap-2\">\n\t\t\t\t\t\t{#if c.author?.nickname}\n\t\t\t\t\t\t\t<a href={`/u/${c.author.nickname}`} class=\"font-semibold text-text hover:text-accent\">\n\t\t\t\t\t\t\t\t@{c.author.nickname}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t<UserBadge rater={c.author.isRater} creator={c.author.isCreator} verified={c.author.isVerified} subscriber={c.author.isSubscriber} size={12} />\n\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t<span class=\"font-semibold text-muted\">{t('[deleted]')}</span>\n\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t<span class=\"text-[11px] text-muted/60\">{fmt(c.createdAt)}</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t{#if c.replyTo}\n\t\t\t\t\t\t<div class=\"mt-1\">\n\t\t\t\t\t\t\t<ReplyQuote\n\t\t\t\t\t\t\t\tvariant=\"bubble\"\n\t\t\t\t\t\t\t\tsenderLabel={c.replyTo.nickname ? `@${c.replyTo.nickname}` : t('a comment')}\n\t\t\t\t\t\t\t\tkind={c.replyTo.kind}\n\t\t\t\t\t\t\t\tbody={c.replyTo.body}\n\t\t\t\t\t\t\t\tmediaMime={null}\n\t\t\t\t\t\t\t\tdeleted={c.replyTo.deleted}\n\t\t\t\t\t\t\t\tonTap={() => scrollToComment(c.replyTo!.id)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t{/if}\n\t\t\t\t\t{#if !c.deletedAt && c.kind === 'gif' && c.mediaUrl}\n\t\t\t\t\t\t<!-- RAT-334 pattern: prefer mp4 (10-30x lighter), muted+looped+\n\t\t\t\t\t\t\t autoplay so it reads as a gif; image/gif fallback. -->\n\t\t\t\t\t\t<div class=\"mt-1 max-w-[240px] overflow-hidden rounded-lg border border-border\">\n\t\t\t\t\t\t\t{#if c.mediaMime === 'video/mp4'}\n\t\t\t\t\t\t\t\t<video\n\t\t\t\t\t\t\t\t\tsrc={c.mediaUrl}\n\t\t\t\t\t\t\t\t\tautoplay\n\t\t\t\t\t\t\t\t\tloop\n\t\t\t\t\t\t\t\t\tmuted\n\t\t\t\t\t\t\t\t\tplaysinline\n\t\t\t\t\t\t\t\t\tpreload=\"metadata\"\n\t\t\t\t\t\t\t\t\taria-label={c.body || 'gif'}\n\t\t\t\t\t\t\t\t\tclass=\"block w-full\"\n\t\t\t\t\t\t\t\t></video>\n\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t<img src={c.mediaUrl} alt={c.body || 'gif'} loading=\"lazy\" draggable=\"false\" class=\"block w-full\" />\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t{:else}\n\t\t\t\t\t\t<p class=\"mt-0.5 break-words text-text {c.deletedAt ? 'italic text-muted' : ''}\">\n\t\t\t\t\t\t\t{#if c.deletedAt}{c.body === '[deleted]' ? t('[deleted]') : c.body}{:else}<LinkifiedText text={c.body} />{/if}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t{/if}\n\t\t\t\t\t{#if !c.deletedAt}\n\t\t\t\t\t\t<div class=\"mt-1 flex flex-wrap items-center gap-2\">\n\t\t\t\t\t\t\t<ReactionChips\n\t\t\t\t\t\t\t\treactions={c.reactions}\n\t\t\t\t\t\t\t\t{viewerId}\n\t\t\t\t\t\t\t\tonToggle={(emoji) => toggleReaction(c, emoji)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t{#if viewerLoggedIn}\n\t\t\t\t\t\t\t\t<span class=\"relative inline-flex\">\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tonclick={(e) => {\n\t\t\t\t\t\t\t\t\t\t\t// stopPropagation: the same click would land on the\n\t\t\t\t\t\t\t\t\t\t\t// document listener below and insta-close the popover.\n\t\t\t\t\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\t\t\t\t\treactionPickerFor = reactionPickerFor === c.id ? null : c.id;\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\tclass=\"inline-flex h-5 w-5 items-center justify-center rounded-full text-muted/50 transition-colors hover:text-text\"\n\t\t\t\t\t\t\t\t\t\taria-label={t('add reaction')}\n\t\t\t\t\t\t\t\t\t\taria-expanded={reactionPickerFor === c.id}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<!-- smiley + plus — the classic add-reaction glyph -->\n\t\t\t\t\t\t\t\t\t\t<svg class=\"h-4 w-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\" stroke-linecap=\"round\">\n\t\t\t\t\t\t\t\t\t\t\t<circle cx=\"11\" cy=\"12\" r=\"8\" />\n\t\t\t\t\t\t\t\t\t\t\t<circle cx=\"8.2\" cy=\"10.4\" r=\"0.4\" fill=\"currentColor\" />\n\t\t\t\t\t\t\t\t\t\t\t<circle cx=\"13.8\" cy=\"10.4\" r=\"0.4\" fill=\"currentColor\" />\n\t\t\t\t\t\t\t\t\t\t\t<path d=\"M7.8 14.4a4.2 4.2 0 0 0 6.4 0\" />\n\t\t\t\t\t\t\t\t\t\t\t<path d=\"M19.5 3.5v5M17 6h5\" />\n\t\t\t\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t{#if reactionPickerFor === c.id}\n\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\ttransition:scale={{ duration: 140, start: 0.88, easing: quintOut }}\n\t\t\t\t\t\t\t\t\t\t\tclass=\"absolute bottom-full left-0 z-20 mb-1.5 flex origin-bottom-left items-center gap-0.5 rounded-full border border-border bg-surface px-1.5 py-1 whitespace-nowrap shadow-lg shadow-black/40\"\n\t\t\t\t\t\t\t\t\t\t\trole=\"menu\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{#each ALLOWED_REACTIONS as emoji (emoji)}\n\t\t\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"rounded px-0.5 text-[16px] leading-none transition-transform hover:scale-125\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tonclick={() => toggleReaction(c, emoji)}\n\t\t\t\t\t\t\t\t\t\t\t\t\taria-label={t('react with {emoji}', { emoji })}\n\t\t\t\t\t\t\t\t\t\t\t\t\trole=\"menuitem\"\n\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{emoji}\n\t\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tonclick={() => startReply(c)}\n\t\t\t\t\t\t\t\t\tclass=\"text-[11px] font-semibold text-muted/50 transition-colors hover:text-text\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{t('reply')}\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t{/if}\n\t\t\t\t</div>\n\t\t\t\t{#if canDelete(c)}\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonclick={() => remove(c.id)}\n\t\t\t\t\t\tclass=\"shrink-0 text-xs text-muted/40 opacity-0 transition-opacity hover:text-accent group-hover:opacity-100\"\n\t\t\t\t\t\taria-label={t('delete comment')}\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{#if canReport(c)}\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonclick={() => (reportCommentId = c.id)}\n\t\t\t\t\t\tclass=\"shrink-0 text-muted/40 opacity-0 transition-opacity hover:text-coral group-hover:opacity-100\"\n\t\t\t\t\t\taria-label={t('report comment')}\n\t\t\t\t\t>\n\t\t\t\t\t\t<svg class=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n\t\t\t\t\t\t\t<path d=\"M5 21V4\" />\n\t\t\t\t\t\t\t<path d=\"M5 4h12l-2.5 3.5L17 11H5\" />\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t</button>\n\t\t\t\t{/if}\n\t\t\t</li>\n\t\t{/each}\n\t</ul>\n</section>\n\n{#if reportCommentId}\n\t<ReportContentModal\n\t\topen={reportCommentId !== null}\n\t\tentityType=\"creator_post_comment\"\n\t\tentityId={reportCommentId}\n\t\tonclose={() => (reportCommentId = null)}\n\t/>\n{/if}\n\n{#if withInput}\n\t<div class=\"-mx-4 mt-3 sm:mx-0\">\n\t\t<CommentInput\n\t\t\t{postId}\n\t\t\t{viewerLoggedIn}\n\t\t\tonposted={appendComment}\n\t\t\treplyTo={replyTarget}\n\t\t\tonclearreply={() => (replyTarget = null)}\n\t\t/>\n\t</div>\n{/if}\n","<script lang=\"ts\">\n\timport { t } from '$lib/i18n';\n\timport { trackImageLoadError, type ImageErrorSurface } from '$lib/analytics';\n\n\tinterface Props {\n\t\tsrc: string;\n\t\talt: string;\n\t\t/** Tailwind classes for the wrapper. Caller controls dimensions. */\n\t\tclass?: string;\n\t\t/** Tailwind classes for the <img> itself (object-fit, position). */\n\t\timgClass?: string;\n\t\tloading?: 'lazy' | 'eager';\n\t\twidth?: number;\n\t\theight?: number;\n\t\t/** Optional onload callback (e.g. for parent to track image readiness). */\n\t\tonload?: () => void;\n\t\t/** Analytics context — where this image renders. Sent on image_load_error. */\n\t\tsurface: ImageErrorSurface;\n\t\t/** Ask the parent to RE-SIGN this image (typically a bounded\n\t\t *  `invalidateAll()`), because the usual cause of a broken tile is an\n\t\t *  expired signed token — re-requesting the same URL would just 403 again.\n\t\t *  Without a handler, retry can only re-mount and hope it was transient. */\n\t\tonretry?: () => void;\n\t}\n\n\tlet {\n\t\tsrc,\n\t\talt,\n\t\tclass: cls = '',\n\t\timgClass = 'h-full w-full object-cover',\n\t\tloading = 'lazy',\n\t\twidth,\n\t\theight,\n\t\tonload,\n\t\tsurface,\n\t\tonretry\n\t}: Props = $props();\n\n\tlet imgEl = $state<HTMLImageElement | undefined>(undefined);\n\tlet loaded = $state(false);\n\t// Before this, a failed load had no onerror → the <img> stayed at opacity-0\n\t// under the pulsing shimmer forever (session replay caught expired signed\n\t// URLs doing exactly this mid-session). Now we surface an explicit,\n\t// retryable fallback and fire one capture so the failure rate is measurable.\n\tlet errored = $state(false);\n\n\t// How long to let a load run before treating silence as a stall. Long enough\n\t// that a slow phone connection finishes normally; short enough that a stuck\n\t// tile self-heals while the user is still looking at it.\n\tconst STALL_MS = 2500;\n\t/** Nudges spent on this src. Two is plenty for a cached byte-stream; more\n\t *  would let a genuinely dead object spin forever. */\n\tlet nudges = 0;\n\n\t// Resync when the parent swaps `src` (e.g. after invalidateAll re-signs the\n\t// media URL) — otherwise a stale error/loaded state would stick to the new\n\t// image. See the RAT-117 note in CLAUDE.md on $state decoupled from props.\n\t$effect(() => {\n\t\tvoid src;\n\t\tloaded = false;\n\t\terrored = false;\n\t\tnudges = 0;\n\n\t\t// `loaded` hangs entirely off the load event, and that event does not\n\t\t// always arrive. Two real cases, both observed on this component:\n\t\t//\n\t\t//  1. The image finished before Svelte attached the handler. On an SSR\n\t\t//     page the browser starts fetching during HTML parse, well ahead of\n\t\t//     hydration, so the event fires into nothing.\n\t\t//  2. The element's own request was aborted mid-flight. The browser fires\n\t\t//     neither load nor error for that — measured on /post: `complete`\n\t\t//     stuck false while a fresh Image() with the SAME url resolved from\n\t\t//     cache in 1ms.\n\t\t//\n\t\t// Either way `loaded` stays false and the img sits at opacity-0 under the\n\t\t// shimmer forever — a black tile over an image the browser already has.\n\t\t// Ask the element directly, then, if it is still silent, re-issue the\n\t\t// request (cache-served, so effectively free).\n\t\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\t\tconst settle = () => {\n\t\t\tconst el = imgEl;\n\t\t\tif (!el || loaded || errored) return;\n\t\t\tif (el.complete) {\n\t\t\t\t// Decoded pixels present = a load we missed. No pixels = a real failure.\n\t\t\t\tif (el.naturalWidth > 0) handleLoad();\n\t\t\t\telse handleError();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (nudges < 2) {\n\t\t\t\tnudges += 1;\n\t\t\t\tconst url = el.src;\n\t\t\t\tel.src = '';\n\t\t\t\tel.src = url;\n\t\t\t\ttimer = setTimeout(settle, STALL_MS);\n\t\t\t}\n\t\t};\n\t\t// Runs after the DOM has the new src, so `imgEl` is the right element.\n\t\ttimer = setTimeout(settle, STALL_MS);\n\t\t// Cheap synchronous pass for case 1 — no need to make a cached image wait.\n\t\tqueueMicrotask(() => {\n\t\t\tif (imgEl?.complete && imgEl.naturalWidth > 0 && !loaded) handleLoad();\n\t\t});\n\t\treturn () => clearTimeout(timer);\n\t});\n\n\tfunction handleLoad() {\n\t\tloaded = true;\n\t\terrored = false;\n\t\tonload?.();\n\t}\n\n\tfunction handleError() {\n\t\tif (!errored) trackImageLoadError(surface);\n\t\terrored = true;\n\t}\n\n\t// ImageWithShimmer is often wrapped in an <a> (the feed card links to the\n\t// post), so the retry tap must not bubble into a navigation.\n\tfunction retry(e: MouseEvent) {\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\t\tloaded = false;\n\t\t// Clearing `errored` swaps the fallback back out for the <img> branch below,\n\t\t// which mounts a BRAND-NEW element — that re-request is the whole retry, and\n\t\t// it deliberately leaves the URL untouched. (The previous version appended\n\t\t// `?_retry=N` to cache-bust; signed delivery URLs carry a token computed over\n\t\t// their query string — see server/cdn-private.ts, where the Bunny token covers\n\t\t// the resize params — so an extra unsigned param turns a maybe-recoverable\n\t\t// image into a guaranteed 403.)\n\t\terrored = false;\n\t\t// Re-requesting only helps if the failure was transient. The common cause is\n\t\t// an expired signed token, which only the parent can fix by re-signing.\n\t\tonretry?.();\n\t}\n</script>\n\n<div class=\"relative {cls}\">\n\t{#if !loaded && !errored}\n\t\t<div class=\"absolute inset-0 animate-pulse bg-white/[0.06]\"></div>\n\t{/if}\n\t{#if errored}\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tonclick={retry}\n\t\t\tclass=\"absolute inset-0 flex flex-col items-center justify-center gap-2 bg-white/[0.03] text-muted transition-colors hover:text-text\"\n\t\t\taria-label={t(\"couldn't load image — tap to retry\")}\n\t\t\tdata-no-card-nav\n\t\t>\n\t\t\t<svg\n\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\tclass=\"h-7 w-7\"\n\t\t\t\tfill=\"none\"\n\t\t\t\tstroke=\"currentColor\"\n\t\t\t\tstroke-width=\"1.6\"\n\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\taria-hidden=\"true\"\n\t\t\t>\n\t\t\t\t<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" />\n\t\t\t\t<circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\" />\n\t\t\t\t<path d=\"M21 15l-5-5L5 21\" />\n\t\t\t</svg>\n\t\t\t<span class=\"text-xs font-medium\">{t('tap to retry')}</span>\n\t\t</button>\n\t{:else}\n\t\t<img\n\t\t\tbind:this={imgEl}\n\t\t\t{src}\n\t\t\t{alt}\n\t\t\t{loading}\n\t\t\t{width}\n\t\t\t{height}\n\t\t\tclass=\"{imgClass} transition-opacity duration-300 {loaded ? 'opacity-100' : 'opacity-0'}\"\n\t\t\tonload={handleLoad}\n\t\t\tonerror={handleError}\n\t\t/>\n\t{/if}\n</div>\n","<script lang=\"ts\">\n\t/**\n\t * RAT-523: the two ways into a creator's DM, from a post or a reel — the same\n\t * choice the profile's message button offers (RAT-462): \"just message\" goes\n\t * straight to the chat; \"message with tokens\" opens the tip sheet with a note,\n\t * sends both, and lands in the conversation it opened. The same chrome as the\n\t * profile's so the two read as one flow.\n\t *\n\t * RAT-549: a centred dialog at every size, with a ✕. As a bottom sheet in the\n\t * feed it came up at the post instead of on screen — out of sight when the\n\t * post sat near the top. The whole flow (chooser, tip sheet, token shop) is\n\t * portalled to <body>, like NichePicker, so no post or feed wrapper can trap\n\t * its fixed layers again. It sits in its own stacking layer above everything,\n\t * because the reels viewer covers the screen at z-100 and the tip sheet's own\n\t * z-index is lower than that.\n\t */\n\timport { goto } from '$app/navigation';\n\timport { resolve } from '$app/paths';\n\timport BuyTokensModal from '$lib/components/BuyTokensModal.svelte';\n\timport TipSheet from '$lib/components/TipSheet.svelte';\n\timport TokenCoin from '$lib/components/TokenCoin.svelte';\n\timport { t } from '$lib/i18n';\n\timport { msg } from '$lib/i18n/mark';\n\timport { GIFT_PRO_TOKEN_COST, TRIBUTE_REPLY_RATE_COPY } from '$lib/token-packages';\n\n\tinterface Props {\n\t\topen: boolean;\n\t\tnickname: string;\n\t\t/** Where the conversation was started from, for `?from=` on the chat. */\n\t\tfrom: 'post' | 'reel';\n\t\tonclose: () => void;\n\t}\n\tlet { open, nickname, from, onclose }: Props = $props();\n\n\tlet tributeOpen = $state(false);\n\tlet tributeBusy = $state(false);\n\tlet tributeError = $state('');\n\tlet buyOpen = $state(false);\n\tlet buyReason = $state<string | null>(null);\n\n\tconst chatHref = $derived(\n\t\t`${resolve('/(chat)/c/[nickname]', { nickname: encodeURIComponent(nickname) })}?from=${from}`\n\t);\n\n\t// One sentence for translators; the handle is set in bold between its halves.\n\tconst headParts = $derived(t('message {name}').split('{name}'));\n\n\tfunction onKey(e: KeyboardEvent) {\n\t\tif (e.key === 'Escape' && open) onclose();\n\t}\n\n\t/** Moves the layer to <body>. It is portalled from inside a wrapper that\n\t *  stays where the component was rendered, so Svelte's teardown of the post\n\t *  never goes looking for a node that has moved. */\n\tfunction portal(node: HTMLElement) {\n\t\tdocument.body.appendChild(node);\n\t\treturn {\n\t\t\tdestroy() {\n\t\t\t\tnode.remove();\n\t\t\t}\n\t\t};\n\t}\n\n\t/** The tribute and the note in one request, as on the profile: a gift with a\n\t *  message gets a reply far more often than a bare one. */\n\tasync function sendTribute(kind: 'tokens' | 'pro', amount: number, message?: string) {\n\t\tif (tributeBusy) return;\n\t\ttributeBusy = true;\n\t\ttributeError = '';\n\t\ttry {\n\t\t\tconst res = await fetch('/api/gift', {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders: { 'Content-Type': 'application/json' },\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tnickname,\n\t\t\t\t\tkind,\n\t\t\t\t\t...(message ? { message } : {}),\n\t\t\t\t\t...(kind === 'tokens' ? { amount, source: 'tip' } : {})\n\t\t\t\t})\n\t\t\t});\n\t\t\tif (res.ok) {\n\t\t\t\ttributeOpen = false;\n\t\t\t\t// The path is resolve()d; the rule can't see it through the query string.\n\t\t\t\t// eslint-disable-next-line svelte/no-navigation-without-resolve\n\t\t\t\tawait goto(chatHref);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst body = await res.json().catch(() => ({}));\n\t\t\tif (res.status === 402 || body?.error === 'insufficient_tokens') {\n\t\t\t\ttributeOpen = false;\n\t\t\t\tbuyReason = t('you need {n} tokens for this', {\n\t\t\t\t\tn: kind === 'pro' ? GIFT_PRO_TOKEN_COST : amount\n\t\t\t\t});\n\t\t\t\tbuyOpen = true;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttributeError =\n\t\t\t\tbody?.error === 'cannot_gift_self' ? t(\"you can't tip yourself\") : t('failed — try again');\n\t\t} catch {\n\t\t\ttributeError = t('network error — try again');\n\t\t} finally {\n\t\t\ttributeBusy = false;\n\t\t}\n\t}\n</script>\n\n<svelte:window onkeydown={onKey} />\n\n<div class=\"msg-host\">\n\t<div class=\"msg-layer\" use:portal>\n\t\t{#if open}\n\t\t\t<button type=\"button\" class=\"msg-backdrop\" aria-label={t('dismiss')} onclick={onclose}\n\t\t\t></button>\n\t\t\t<div\n\t\t\t\tclass=\"msg-sheet\"\n\t\t\t\trole=\"dialog\"\n\t\t\t\taria-modal=\"true\"\n\t\t\t\taria-label={t('message @{name}', { name: nickname })}\n\t\t\t>\n\t\t\t\t<div class=\"msg-top\">\n\t\t\t\t\t<p class=\"msg-head\">{headParts[0]}<strong>@{nickname}</strong>{headParts[1] ?? ''}</p>\n\t\t\t\t\t<button type=\"button\" class=\"msg-close\" aria-label={t('close')} onclick={onclose}>\n\t\t\t\t\t\t<svg\n\t\t\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\t\t\twidth=\"16\"\n\t\t\t\t\t\t\theight=\"16\"\n\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\t\t\tstroke-width=\"2.2\"\n\t\t\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\t\t\taria-hidden=\"true\"><path d=\"M6 6l12 12M18 6L6 18\" /></svg\n\t\t\t\t\t\t>\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\n\t\t\t\t<a\n\t\t\t\t\thref=\"{resolve('/(chat)/c/[nickname]', {\n\t\t\t\t\t\tnickname: encodeURIComponent(nickname)\n\t\t\t\t\t})}?from={from}\"\n\t\t\t\t\tclass=\"msg-opt\"\n\t\t\t\t\tonclick={onclose}\n\t\t\t\t>\n\t\t\t\t\t<span class=\"msg-opt-body\">\n\t\t\t\t\t\t<span class=\"msg-opt-title\">{t('just message')}</span>\n\t\t\t\t\t\t<span class=\"msg-opt-sub\">{t('go straight to the chat')}</span>\n\t\t\t\t\t</span>\n\t\t\t\t\t<span class=\"msg-opt-arrow\" aria-hidden=\"true\">→</span>\n\t\t\t\t</a>\n\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"msg-opt msg-opt--tribute\"\n\t\t\t\t\tonclick={() => {\n\t\t\t\t\t\tonclose();\n\t\t\t\t\t\ttributeOpen = true;\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<span class=\"msg-opt-body\">\n\t\t\t\t\t\t<span class=\"msg-opt-title\">{t('message with tokens')}</span>\n\t\t\t\t\t\t<span class=\"msg-opt-sub\"\n\t\t\t\t\t\t\t>{t(TRIBUTE_REPLY_RATE_COPY)} · {t('every token goes to them')}</span\n\t\t\t\t\t\t>\n\t\t\t\t\t</span>\n\t\t\t\t\t<span class=\"msg-opt-coin\" aria-hidden=\"true\"><TokenCoin size={16} /></span>\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t{/if}\n\n\t\t<TipSheet\n\t\t\topen={tributeOpen}\n\t\t\t{nickname}\n\t\t\tonclose={() => (tributeOpen = false)}\n\t\t\tonpick={sendTribute}\n\t\t\tbusy={tributeBusy}\n\t\t\terror={tributeError}\n\t\t\tcompose\n\t\t\tdesc={msg('they keep every token — the message goes with it')}\n\t\t/>\n\n\t\t<!-- Short on tokens: buy, then land in the chat, where the tip is one tap. -->\n\t\t<BuyTokensModal\n\t\t\topen={buyOpen}\n\t\t\tonclose={() => (buyOpen = false)}\n\t\t\treason={buyReason}\n\t\t\tsuccessPath={chatHref}\n\t\t\tsource={`${from}_message_tip`}\n\t\t/>\n\t</div>\n</div>\n\n<style>\n\t/* Stays in the post's row once the layer has moved out; no box of its own. */\n\t.msg-host {\n\t\tdisplay: contents;\n\t}\n\t/* A zero-size positioned layer: its fixed children paint above the reels\n\t   viewer (z-100) without the layer itself covering anything. */\n\t.msg-layer {\n\t\tposition: relative;\n\t\tz-index: 110;\n\t}\n\t/* Same sheet as the profile's message choice (RAT-462). */\n\t.msg-backdrop {\n\t\tposition: fixed;\n\t\tinset: 0;\n\t\tz-index: 65;\n\t\tbackground: rgba(0, 0, 0, 0.55);\n\t\tbackdrop-filter: blur(4px);\n\t\tborder: none;\n\t\tcursor: default;\n\t}\n\t/* Centred on every screen: wherever the post was, the choice lands where the\n\t   eye already is. */\n\t.msg-sheet {\n\t\tposition: fixed;\n\t\tleft: 50%;\n\t\ttop: 50%;\n\t\ttransform: translate(-50%, -50%);\n\t\tz-index: 66;\n\t\twidth: calc(100% - 32px);\n\t\tmax-width: 400px;\n\t\tbackground: var(--color-bg);\n\t\tborder: 1px solid var(--color-border);\n\t\tborder-radius: 20px;\n\t\tpadding: 16px;\n\t\tbox-shadow: 0 24px 60px -12px rgba(0, 0, 0, 0.7);\n\t\ttext-align: left;\n\t}\n\t.msg-top {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: space-between;\n\t\tgap: 12px;\n\t\tmargin: -4px -4px 12px 4px;\n\t}\n\t.msg-head {\n\t\tfont-size: 14px;\n\t\tcolor: var(--color-muted);\n\t\tmin-width: 0;\n\t\toverflow: hidden;\n\t\ttext-overflow: ellipsis;\n\t\twhite-space: nowrap;\n\t}\n\t.msg-close {\n\t\tdisplay: inline-flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\tflex-shrink: 0;\n\t\twidth: 36px;\n\t\theight: 36px;\n\t\tborder-radius: 999px;\n\t\tborder: none;\n\t\tbackground: var(--color-surface);\n\t\tcolor: var(--color-muted);\n\t\tcursor: pointer;\n\t\ttransition: color 0.15s;\n\t}\n\t.msg-close:hover {\n\t\tcolor: var(--color-text);\n\t}\n\t.msg-sheet > .msg-opt:last-child {\n\t\tmargin-bottom: 0;\n\t}\n\t.msg-head strong {\n\t\tfont-weight: 600;\n\t\tcolor: var(--color-text);\n\t}\n\t.msg-opt {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: space-between;\n\t\tgap: 12px;\n\t\twidth: 100%;\n\t\tpadding: 14px 16px;\n\t\tmargin-bottom: 10px;\n\t\tborder-radius: 14px;\n\t\tborder: 1px solid var(--color-border);\n\t\tbackground: var(--color-surface);\n\t\ttext-align: left;\n\t\ttext-decoration: none;\n\t\tcursor: pointer;\n\t\ttransition: border-color 0.15s;\n\t}\n\t.msg-opt:hover {\n\t\tborder-color: var(--color-accent);\n\t}\n\t.msg-opt--tribute {\n\t\tborder-color: color-mix(in srgb, var(--color-yellow) 40%, var(--color-border));\n\t}\n\t.msg-opt-body {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tgap: 2px;\n\t\tmin-width: 0;\n\t}\n\t.msg-opt-title {\n\t\tfont-family: var(--font-display);\n\t\tfont-size: 14px;\n\t\tfont-weight: 700;\n\t\tcolor: var(--color-text);\n\t}\n\t.msg-opt-sub {\n\t\tfont-size: 12px;\n\t\tcolor: var(--color-muted);\n\t}\n\t.msg-opt-arrow {\n\t\tfont-size: 15px;\n\t\tcolor: var(--color-muted);\n\t\tflex-shrink: 0;\n\t}\n\t.msg-opt-coin {\n\t\tdisplay: inline-flex;\n\t\tflex-shrink: 0;\n\t}\n</style>\n","<script lang=\"ts\">\n\timport { t, locale, LOCALE_INFO } from '$lib/i18n';\n\timport { goto, invalidateAll } from '$app/navigation';\n\timport { resolve } from '$app/paths';\n\timport DuelAvatar from '$lib/components/duel/DuelAvatar.svelte';\n\timport UserBadge from '$lib/components/UserBadge.svelte';\n\timport VoteStack from '$lib/components/post/VoteStack.svelte';\n\timport PostBoostButton from '$lib/components/post/PostBoostButton.svelte';\n\timport CommentSection from '$lib/components/post/CommentSection.svelte';\n\timport LinkifiedText from '$lib/components/post/LinkifiedText.svelte';\n\timport ImageWithShimmer from '$lib/components/post/ImageWithShimmer.svelte';\n\timport ReportContentModal from '$lib/components/ReportContentModal.svelte';\n\timport MessageChooser from '$lib/components/MessageChooser.svelte';\n\timport { getAvatarUrl } from '$lib/avatar';\n\timport { shareOrCopy } from '$lib/share';\n\timport { trackPostToChat, trackShare } from '$lib/analytics';\n\timport { openAuthSheet } from '$lib/stores/authSheet';\n\timport type { PostView, CommentView } from '$lib/types/post';\n\n\tinterface Props {\n\t\tpost: PostView;\n\t\tviewerLoggedIn: boolean;\n\t\tviewerId: string | null;\n\t\t/** When true the comment section + report menu are visible inline (deeplink page).\n\t\t *  In feed mode (false) the post links to /post/[id] for the full thread. */\n\t\texpanded?: boolean;\n\t\t/** Initial comments to render under the card when expanded — saves a roundtrip. */\n\t\tinitialComments?: CommentView[];\n\t\t/** Framed = rounded card on every breakpoint (padded surfaces like the clan\n\t\t *  feed; the /f feed stays edge-to-edge on mobile). */\n\t\tframed?: boolean;\n\t\t/** RAT-446: when provided, video posts get a Reels badge and tapping the\n\t\t *  clip opens the fullscreen reels viewer (instead of toggling mute —\n\t\t *  the corner mute button keeps that job). */\n\t\tonopenreels?: () => void;\n\t\t/** niche staff: soft-remove this post from the niche it's shown in */\n\t\tonModRemove?: ((postId: string) => Promise<void> | void) | null;\n\t\t/** RAT-523: a message button in the footer — the feed shows it. */\n\t\tmessageCta?: boolean;\n\t}\n\n\tlet {\n\t\tpost,\n\t\tviewerLoggedIn,\n\t\tviewerId,\n\t\texpanded = false,\n\t\tinitialComments = [],\n\t\tframed = false,\n\t\tonopenreels,\n\t\tonModRemove = null,\n\t\tmessageCta = false\n\t}: Props = $props();\n\n\tconst isOwner = $derived(viewerLoggedIn && viewerId === post.creator.id);\n\n\t// RAT-523: the creator's DM, offered the way the profile's message button\n\t// offers it — just message, or message with tokens. Signed out, the sign-in\n\t// sheet opens with the DM as next. The link stays a link, so a new tab still\n\t// opens the chat.\n\tlet chooserOpen = $state(false);\n\tfunction messageCreator(e: MouseEvent) {\n\t\tif (!post.creator.nickname) return;\n\t\ttrackPostToChat(post.id);\n\t\te.preventDefault();\n\t\tif (viewerLoggedIn) {\n\t\t\tchooserOpen = true;\n\t\t\treturn;\n\t\t}\n\t\topenAuthSheet(`/c/${encodeURIComponent(post.creator.nickname)}?from=post`, 'post_message');\n\t}\n\n\tlet menuOpen = $state(false);\n\tlet reportOpen = $state(false);\n\t// Multi-pic carousel: index of the snapped slide (drives dots + counter)\n\t// and the container element the desktop arrows scroll.\n\tlet slideIndex = $state(0);\n\tlet carouselEl = $state<HTMLDivElement | null>(null);\n\n\t// RAT-312: native share / clipboard fallback. shareOrCopy MUST be called\n\t// synchronously in the click handler (iOS user-activation), so we build the\n\t// URL up-front and fire without any preceding await.\n\tlet shareCopied = $state(false);\n\tlet shareTimer: ReturnType<typeof setTimeout> | null = null;\n\n\tfunction sharePost() {\n\t\tconst url =\n\t\t\ttypeof window === 'undefined'\n\t\t\t\t? `/post/${post.id}`\n\t\t\t\t: (() => {\n\t\t\t\t\t\tconst u = new URL(`/post/${post.id}`, window.location.origin);\n\t\t\t\t\t\tu.searchParams.set('utm_source', 'post_share');\n\t\t\t\t\t\treturn u.toString();\n\t\t\t\t\t})();\n\t\tconst title =\n\t\t\tpost.kind === 'partnership' && post.partnership\n\t\t\t\t? t('{a} and {b} are officially a thing on ratemyd.', {\n\t\t\t\t\t\ta: post.partnership.a.nickname ?? t('someone'),\n\t\t\t\t\t\tb: post.partnership.b.nickname ?? t('someone')\n\t\t\t\t\t})\n\t\t\t\t: post.creator.nickname\n\t\t\t\t\t? t('@{name} on ratemyd', { name: post.creator.nickname })\n\t\t\t\t\t: 'ratemyd';\n\t\tshareOrCopy({ url, title, text: post.caption ?? undefined }).then((result) => {\n\t\t\tif (result === 'shared') trackShare('native', 'post');\n\t\t\tif (result === 'copied') {\n\t\t\t\ttrackShare('clipboard', 'post');\n\t\t\t\tshareCopied = true;\n\t\t\t\tif (shareTimer) clearTimeout(shareTimer);\n\t\t\t\tshareTimer = setTimeout(() => (shareCopied = false), 2000);\n\t\t\t}\n\t\t});\n\t}\n\n\t// RAT-272 follow-up: cross-content preview images can 404 — e.g. a duel\n\t// shared before /api/duel/[code]/share.png has been hit at least once,\n\t// or a foil-cards / beat-photos signed URL expiring mid-view. Track per-\n\t// image failure so the card silently falls back to the icon-only row\n\t// rather than showing the browser's broken-image glyph.\n\tlet crossImageFailed = $state(false);\n\tlet crossImageFailedB = $state(false);\n\n\t// Tier list \"remove me\": the ranked viewer pulls their own entry. Server\n\t// only ever deletes the caller's row; invalidateAll re-syncs the card.\n\tlet removingTier = $state(false);\n\tasync function removeMeFromTierlist() {\n\t\tif (removingTier) return;\n\t\tremovingTier = true;\n\t\ttry {\n\t\t\tconst res = await fetch(`/api/post/${post.id}/tier-remove`, { method: 'POST' });\n\t\t\tif (res.ok) await invalidateAll();\n\t\t} finally {\n\t\t\tremovingTier = false;\n\t\t}\n\t}\n\n\t// RAT-269: video auto-play muted + IntersectionObserver pause/resume.\n\t// Browser autoplay policy requires muted=true for unattended playback;\n\t// user can tap to unmute. Pause when offscreen to save bandwidth + CPU.\n\tlet videoEl = $state<HTMLVideoElement | null>(null);\n\tlet videoMuted = $state(true);\n\n\t$effect(() => {\n\t\tif (!videoEl) return;\n\t\tconst obs = new IntersectionObserver(\n\t\t\t(entries) => {\n\t\t\t\tfor (const entry of entries) {\n\t\t\t\t\tif (entry.isIntersecting) {\n\t\t\t\t\t\tvideoEl?.play().catch(() => {\n\t\t\t\t\t\t\t// autoplay rejected (rare with muted=true) — leave paused\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvideoEl?.pause();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ threshold: 0.5 }\n\t\t);\n\t\tobs.observe(videoEl);\n\t\treturn () => obs.disconnect();\n\t});\n\n\tfunction toggleMute(e: MouseEvent) {\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\t\tif (!videoEl) return;\n\t\tvideoMuted = !videoMuted;\n\t\tvideoEl.muted = videoMuted;\n\t\t// If user un-mutes while paused, also resume.\n\t\tif (!videoMuted && videoEl.paused) {\n\t\t\tvideoEl.play().catch(() => {});\n\t\t}\n\t}\n\n\t// RAT-446: tap on a video opens the reels viewer when the parent wired it\n\t// up (the /f feed); otherwise falls back to the legacy mute toggle.\n\tfunction videoTap(e: MouseEvent) {\n\t\tif (onopenreels) {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t\tonopenreels();\n\t\t\treturn;\n\t\t}\n\t\ttoggleMute(e);\n\t}\n\n\tfunction openReport() {\n\t\tif (!viewerLoggedIn) {\n\t\t\tgoto(`/auth/sign-in?next=/post/${post.id}`);\n\t\t\treturn;\n\t\t}\n\t\treportOpen = true;\n\t}\n\n\tfunction fmtDate(d: string) {\n\t\tconst date = new Date(d);\n\t\tconst diffMs = Date.now() - date.getTime();\n\t\tconst mins = Math.floor(diffMs / 60000);\n\t\tif (mins < 1) return t('just now');\n\t\tif (mins < 60) return t('{n}m ago', { n: mins });\n\t\tconst hrs = Math.floor(mins / 60);\n\t\tif (hrs < 24) return t('{n}h ago', { n: hrs });\n\t\tconst days = Math.floor(hrs / 24);\n\t\tif (days < 7) return t('{n}d ago', { n: days });\n\t\treturn date.toLocaleDateString();\n\t}\n\n\tasync function deletePost() {\n\t\tif (!confirm(t('delete this post permanently?'))) return;\n\t\tconst res = await fetch(`/api/post/${post.id}`, { method: 'DELETE' });\n\t\tif (res.ok) {\n\t\t\tif (expanded) {\n\t\t\t\tgoto(`/u/${post.creator.nickname ?? ''}`);\n\t\t\t} else {\n\t\t\t\tawait invalidateAll();\n\t\t\t}\n\t\t}\n\t}\n\n\t// The usual cause of a broken post image is an expired signed token, so the\n\t// only recovery that actually works is re-signing: re-run the page load and\n\t// the fresh URL lands back on `post.mediaUrl`. Same shape as the album\n\t// lightbox's auto-recover. Bounded so a genuinely dead object (deleted from\n\t// the bucket) can't turn a tap-to-retry into an invalidateAll loop.\n\tlet imageResignAttempts = 0;\n\tasync function resignPostMedia() {\n\t\tif (imageResignAttempts >= 3) return;\n\t\timageResignAttempts += 1;\n\t\tawait invalidateAll();\n\t}\n\n\tconst profileHref = $derived(post.creator.nickname ? `/u/${post.creator.nickname}` : '#');\n\tconst postHref = $derived(`/post/${post.id}`);\n\n\t// RAT-313: in feed mode the whole card is a tap target that opens the post,\n\t// EXCEPT genuinely interactive children (vote stack, buttons, links, video,\n\t// inputs) which keep their own behavior. closest() lets those clicks through\n\t// untouched; everything else (caption, padding, empty surface) navigates.\n\tfunction cardClick(e: MouseEvent) {\n\t\tif (expanded) return;\n\t\tconst el = e.target as HTMLElement | null;\n\t\tif (el?.closest('a, button, video, input, textarea, label, [data-no-card-nav]')) return;\n\t\tgoto(postHref);\n\t}\n</script>\n\n<!-- svelte-ignore a11y_click_events_have_key_events -->\n<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->\n<article\n\tclass=\"overflow-hidden bg-surface {framed\n\t\t? 'rounded-2xl border border-border'\n\t\t: 'border-b border-border sm:rounded-2xl sm:border'} {expanded ? '' : 'cursor-pointer'}\"\n\tonclick={cardClick}\n>\n\t<header class=\"flex items-center justify-between gap-3 px-4 pt-4\">\n\t\t<div class=\"flex min-w-0 items-center gap-2.5\">\n\t\t\t<DuelAvatar nickname={post.creator.nickname} avatarUrl={getAvatarUrl(post.creator.avatarPath)} size={40} href={profileHref} />\n\t\t\t<div class=\"min-w-0\">\n\t\t\t\t<div class=\"flex items-center gap-1.5\">\n\t\t\t\t\t<a href={profileHref} class=\"truncate text-sm font-semibold text-text hover:text-accent\">\n\t\t\t\t\t\t@{post.creator.nickname ?? t('[deleted]')}\n\t\t\t\t\t</a>\n\t\t\t\t\t<UserBadge rater={post.creator.isRater} creator={post.creator.isCreator} verified={post.creator.isVerified} topRater={post.creator.isTopRater} subscriber={post.creator.isSubscriber} size={13} />\n\t\t\t\t</div>\n\t\t\t\t<a href={postHref} class=\"text-[11px] text-muted hover:text-text\">{fmtDate(post.createdAt)}</a>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<div class=\"relative\">\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tonclick={() => (menuOpen = !menuOpen)}\n\t\t\t\tclass=\"rounded-full p-1.5 text-muted hover:bg-bg hover:text-text\"\n\t\t\t\taria-label={t('more')}\n\t\t\t>\n\t\t\t\t<svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"currentColor\">\n\t\t\t\t\t<circle cx=\"5\" cy=\"12\" r=\"1.5\" /><circle cx=\"12\" cy=\"12\" r=\"1.5\" /><circle cx=\"19\" cy=\"12\" r=\"1.5\" />\n\t\t\t\t</svg>\n\t\t\t</button>\n\t\t\t{#if menuOpen}\n\t\t\t\t<div class=\"absolute right-0 z-10 mt-1 w-40 rounded-xl border border-border bg-bg py-1 text-sm shadow-xl\">\n\t\t\t\t\t{#if isOwner}\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonclick={() => {\n\t\t\t\t\t\t\t\tmenuOpen = false;\n\t\t\t\t\t\t\t\tdeletePost();\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\tclass=\"block w-full px-3 py-2 text-left text-red-400 hover:bg-surface\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{t('delete post')}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t{:else if onModRemove}\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonclick={() => {\n\t\t\t\t\t\t\t\tmenuOpen = false;\n\t\t\t\t\t\t\t\tvoid onModRemove?.(post.id);\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\tclass=\"block w-full px-3 py-2 text-left text-red-400 hover:bg-surface\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{t('remove from niche')}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonclick={() => {\n\t\t\t\t\t\t\t\tmenuOpen = false;\n\t\t\t\t\t\t\t\topenReport();\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\tclass=\"block w-full px-3 py-2 text-left text-text hover:bg-surface\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{t('report')}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t{:else}\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonclick={() => {\n\t\t\t\t\t\t\t\tmenuOpen = false;\n\t\t\t\t\t\t\t\topenReport();\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\tclass=\"block w-full px-3 py-2 text-left text-text hover:bg-surface\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{t('report')}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t{/if}\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonclick={() => {\n\t\t\t\t\t\t\tmenuOpen = false;\n\t\t\t\t\t\t\tsharePost();\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tclass=\"block w-full px-3 py-2 text-left text-text hover:bg-surface\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{shareCopied ? t('link copied ✓') : t('share')}\n\t\t\t\t\t</button>\n\t\t\t\t\t<a href={postHref} class=\"block px-3 py-2 text-left text-text hover:bg-surface\">{t('open post')}</a>\n\t\t\t\t</div>\n\t\t\t{/if}\n\t\t</div>\n\t</header>\n\n\t{#if post.caption}\n\t\t<div class=\"px-4 pt-2 text-sm leading-relaxed text-text\">\n\t\t\t<p class=\"whitespace-pre-wrap break-words\"><LinkifiedText text={post.caption} /></p>\n\t\t</div>\n\t{/if}\n\n\t{#if post.kind === 'partnership' && post.partnership}\n\t\t<!-- Partner feature: the \"officially a thing\" couple card. System-created\n\t\t\t on accept (never via the composer); the post stays as history after a\n\t\t\t split, the sub line just says so. Hearts are SVG, no emoji, no glow. -->\n\t\t{@const pa = post.partnership}\n\t\t{@const sinceLabel = new Date(pa.since)\n\t\t\t.toLocaleDateString(LOCALE_INFO[locale()].hreflang, { month: 'short', day: 'numeric', year: 'numeric' })\n\t\t\t.toLowerCase()}\n\t\t<div class=\"couple\">\n\t\t\t<!-- Floating hearts behind the couple. Pure CSS, transform + opacity\n\t\t\t\t only, so it costs nothing on scroll; off under reduced-motion. -->\n\t\t\t<div class=\"couple-sky\" aria-hidden=\"true\">\n\t\t\t\t{#each [\n\t\t\t\t\t[8, 0, 9, 7.5], [22, 2.1, 6, 8.5], [35, 4.4, 11, 9.5], [48, 1.2, 7, 7],\n\t\t\t\t\t[61, 3.3, 9, 8], [74, 0.6, 6, 9], [87, 2.8, 10, 7.5], [15, 5.6, 5, 10],\n\t\t\t\t\t[68, 6.2, 7, 8.5], [93, 4.9, 5, 9.5]\n\t\t\t\t] as [x, d, sz, t]}\n\t\t\t\t\t<svg\n\t\t\t\t\t\tclass=\"couple-mote\"\n\t\t\t\t\t\tstyle=\"--x:{x}%; --d:{d}s; --s:{sz}px; --t:{t}s\"\n\t\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\t><path d=\"M12 21s-7.5-4.6-9.6-9.2C1 8.3 3.3 4.5 6.9 4.5c2 0 3.5 1.1 4.3 2.4.8-1.3 2.3-2.4 4.3-2.4 3.6 0 5.9 3.8 4.5 7.3C19.5 16.4 12 21 12 21z\" /></svg>\n\t\t\t\t{/each}\n\t\t\t</div>\n\t\t\t<div class=\"couple-avs\">\n\t\t\t\t<span class=\"couple-av couple-av--a\">\n\t\t\t\t\t<DuelAvatar nickname={pa.a.nickname} avatarUrl={getAvatarUrl(pa.a.avatarPath)} size={56} href={pa.a.nickname ? `/u/${pa.a.nickname}` : ''} link={!!pa.a.nickname} />\n\t\t\t\t</span>\n\t\t\t\t<span class=\"couple-heart\" aria-hidden=\"true\">\n\t\t\t\t\t<svg viewBox=\"0 0 24 24\"><path d=\"M12 21s-7.5-4.6-9.6-9.2C1 8.3 3.3 4.5 6.9 4.5c2 0 3.5 1.1 4.3 2.4.8-1.3 2.3-2.4 4.3-2.4 3.6 0 5.9 3.8 4.5 7.3C19.5 16.4 12 21 12 21z\" /></svg>\n\t\t\t\t</span>\n\t\t\t\t<span class=\"couple-av couple-av--b\">\n\t\t\t\t\t<DuelAvatar nickname={pa.b.nickname} avatarUrl={getAvatarUrl(pa.b.avatarPath)} size={56} href={pa.b.nickname ? `/u/${pa.b.nickname}` : ''} link={!!pa.b.nickname} />\n\t\t\t\t</span>\n\t\t\t</div>\n\t\t\t<div class=\"couple-title\">\n\t\t\t\t{#each t('{a} and {b} are <span>officially a thing</span>', {\n\t\t\t\t\ta: pa.a.nickname ?? t('[deleted]'),\n\t\t\t\t\tb: pa.b.nickname ?? t('[deleted]')\n\t\t\t\t}).split(/<span>(.*?)<\\/span>/) as part, i (i)}{#if i % 2}<span>{part}</span>{:else}{part}{/if}{/each}\n\t\t\t</div>\n\t\t\t<div class=\"couple-sub\">{sinceLabel} · {pa.active ? t('both off the market') : t(\"it didn't last\")}</div>\n\t\t</div>\n\t{:else if post.kind === 'tierlist' && post.tierlist}\n\t\t<!-- Tier list: S–D rows of user chips. Chips deep-link to the ranked\n\t\t\t user's profile; empty tiers are skipped to keep feed cards compact.\n\t\t\t Solid tier-color blocks (module tokens), no glow. -->\n\t\t{@const TIERS = [\n\t\t\t{ key: 'S', cls: 'bg-coral' },\n\t\t\t{ key: 'A', cls: 'bg-orange' },\n\t\t\t{ key: 'B', cls: 'bg-yellow' },\n\t\t\t{ key: 'C', cls: 'bg-green' },\n\t\t\t{ key: 'D', cls: 'bg-blue' }\n\t\t]}\n\t\t<div class=\"mx-4 mt-3\">\n\t\t\t{#if post.tierlist.title}\n\t\t\t\t<h2 class=\"font-display text-lg leading-tight font-bold tracking-tight text-text\">\n\t\t\t\t\t{post.tierlist.title}\n\t\t\t\t</h2>\n\t\t\t{/if}\n\t\t\t<div class=\"mt-2 flex flex-col gap-0.5\">\n\t\t\t\t{#each TIERS as tier (tier.key)}\n\t\t\t\t\t{@const rowEntries = post.tierlist.entries.filter((e) => e.tier === tier.key)}\n\t\t\t\t\t{#if rowEntries.length > 0}\n\t\t\t\t\t\t<div class=\"grid grid-cols-[40px_1fr] gap-0.5\">\n\t\t\t\t\t\t\t<div class=\"flex min-h-[64px] items-center justify-center rounded-l-lg {tier.cls} font-display text-lg font-bold text-bg\">\n\t\t\t\t\t\t\t\t{tier.key}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"flex flex-wrap content-start items-center gap-2 rounded-r-lg bg-surface-2 p-2\">\n\t\t\t\t\t\t\t\t{#each rowEntries as e (e.userId)}\n\t\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\t\thref={e.nickname ? `/u/${encodeURIComponent(e.nickname)}` : postHref}\n\t\t\t\t\t\t\t\t\t\tclass=\"flex w-14 flex-col items-center gap-1 no-underline\"\n\t\t\t\t\t\t\t\t\t\ttitle={e.nickname ? `@${e.nickname}` : undefined}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<DuelAvatar nickname={e.nickname} avatarUrl={getAvatarUrl(e.avatarPath)} size={40} href=\"\" link={false} />\n\t\t\t\t\t\t\t\t\t\t<span class=\"w-full truncate text-center text-[9px] font-semibold text-muted\">\n\t\t\t\t\t\t\t\t\t\t\t{e.nickname ?? t('[deleted]')}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t{/if}\n\t\t\t\t{/each}\n\t\t\t</div>\n\t\t\t{#if viewerId && post.tierlist.entries.some((e) => e.userId === viewerId)}\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tonclick={removeMeFromTierlist}\n\t\t\t\t\tdisabled={removingTier}\n\t\t\t\t\tclass=\"mt-2 text-[11px] text-muted underline underline-offset-2 transition-colors hover:text-text disabled:opacity-50\"\n\t\t\t\t>\n\t\t\t\t\t{removingTier ? t('removing…') : t(\"you're on this list — remove me\")}\n\t\t\t\t</button>\n\t\t\t{/if}\n\t\t</div>\n\t{:else if post.kind === 'image' && post.mediaUrl}\n\t\t{@const slides = [\n\t\t\t{ url: post.mediaUrl, width: post.mediaWidth, height: post.mediaHeight },\n\t\t\t...(post.extraMedia ?? [])\n\t\t]}\n\t\t<div class=\"relative mt-3\">\n\t\t\t{#if slides.length > 1}\n\t\t\t\t<!-- Multi-pic carousel: CSS scroll-snap (no JS gesture engine — the\n\t\t\t\t\t horizontal pan is native scroll, so it can't fight vertical feed\n\t\t\t\t\t scrolling), dots + counter track the snapped index. Each slide\n\t\t\t\t\t stays an <a> to the post, same as the single-image card. -->\n\t\t\t\t<div\n\t\t\t\t\tbind:this={carouselEl}\n\t\t\t\t\tclass=\"flex aspect-square snap-x snap-mandatory overflow-x-auto overflow-y-hidden bg-[#0a0a0a] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden\"\n\t\t\t\t\tonscroll={(e) => {\n\t\t\t\t\t\tconst el = e.currentTarget;\n\t\t\t\t\t\tslideIndex = Math.min(\n\t\t\t\t\t\t\tslides.length - 1,\n\t\t\t\t\t\t\tMath.max(0, Math.round(el.scrollLeft / el.clientWidth))\n\t\t\t\t\t\t);\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{#each slides as img, i (i)}\n\t\t\t\t\t\t<a href={postHref} class=\"relative block h-full w-full flex-none snap-center overflow-hidden\">\n\t\t\t\t\t\t\t<ImageWithShimmer\n\t\t\t\t\t\t\t\tsrc={img.url}\n\t\t\t\t\t\t\t\talt={post.caption ?? t('post')}\n\t\t\t\t\t\t\t\tclass=\"relative h-full w-full\"\n\t\t\t\t\t\t\t\timgClass=\"h-full w-full object-contain\"\n\t\t\t\t\t\t\t\twidth={img.width ?? undefined}\n\t\t\t\t\t\t\t\theight={img.height ?? undefined}\n\t\t\t\t\t\t\t\tsurface={expanded ? 'post_detail' : 'post_feed'}\n\t\t\t\t\t\t\t\tonretry={i === 0 ? resignPostMedia : undefined}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</a>\n\t\t\t\t\t{/each}\n\t\t\t\t</div>\n\t\t\t\t<span\n\t\t\t\t\tclass=\"pointer-events-none absolute top-3 left-3 rounded-full bg-bg/60 px-2 py-0.5 font-display text-[11px] font-bold text-white backdrop-blur\"\n\t\t\t\t\t>{slideIndex + 1}/{slides.length}</span\n\t\t\t\t>\n\t\t\t\t<div class=\"pointer-events-none absolute bottom-2 left-1/2 flex -translate-x-1/2 gap-1.5\">\n\t\t\t\t\t{#each slides as _, i (i)}\n\t\t\t\t\t\t<span class=\"h-1.5 w-1.5 rounded-full {i === slideIndex ? 'bg-white' : 'bg-white/35'}\"\n\t\t\t\t\t\t></span>\n\t\t\t\t\t{/each}\n\t\t\t\t</div>\n\t\t\t\t<!-- Desktop paging arrows: mouse users have no horizontal pan, so the\n\t\t\t\t\t snap carousel needs explicit prev/next. hover:hover gates them off\n\t\t\t\t\t touch (where the swipe IS the control). Transparent scrim discs. -->\n\t\t\t\t{#if slideIndex > 0}\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"absolute top-1/2 left-2 hidden h-9 w-9 -translate-y-1/2 items-center justify-center rounded-full bg-black/35 text-white backdrop-blur transition-colors hover:bg-black/60 [@media(hover:hover)]:flex\"\n\t\t\t\t\t\taria-label={t('previous image')}\n\t\t\t\t\t\tonclick={() => carouselEl?.scrollBy({ left: -carouselEl.clientWidth, behavior: 'smooth' })}\n\t\t\t\t\t>\n\t\t\t\t\t\t<svg viewBox=\"0 0 24 24\" class=\"h-5 w-5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"15 18 9 12 15 6\" /></svg>\n\t\t\t\t\t</button>\n\t\t\t\t{/if}\n\t\t\t\t{#if slideIndex < slides.length - 1}\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"absolute top-1/2 right-2 hidden h-9 w-9 -translate-y-1/2 items-center justify-center rounded-full bg-black/35 text-white backdrop-blur transition-colors hover:bg-black/60 [@media(hover:hover)]:flex\"\n\t\t\t\t\t\taria-label={t('next image')}\n\t\t\t\t\t\tonclick={() => carouselEl?.scrollBy({ left: carouselEl.clientWidth, behavior: 'smooth' })}\n\t\t\t\t\t>\n\t\t\t\t\t\t<svg viewBox=\"0 0 24 24\" class=\"h-5 w-5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"9 18 15 12 9 6\" /></svg>\n\t\t\t\t\t</button>\n\t\t\t\t{/if}\n\t\t\t{:else}\n\t\t\t<a href={postHref} class=\"relative block aspect-square overflow-hidden bg-[#0a0a0a]\">\n\t\t\t\t<!-- RAT-212: solid dark bg replaces the blurred-backdrop duplicate\n\t\t\t\t\t <img>. The double-img setup fired two load events on the same src\n\t\t\t\t\t (mobile didn't dedupe perceptually) so the image appeared to flash\n\t\t\t\t\t twice. Single img + solid neutral surface = one load, one paint. -->\n\t\t\t\t<ImageWithShimmer\n\t\t\t\t\tsrc={post.mediaUrl}\n\t\t\t\t\talt={post.caption ?? t('post')}\n\t\t\t\t\tclass=\"relative h-full w-full\"\n\t\t\t\t\timgClass=\"h-full w-full object-contain\"\n\t\t\t\t\twidth={post.mediaWidth ?? undefined}\n\t\t\t\t\theight={post.mediaHeight ?? undefined}\n\t\t\t\t\tsurface={expanded ? 'post_detail' : 'post_feed'}\n\t\t\t\t\tonretry={resignPostMedia}\n\t\t\t\t/>\n\t\t\t</a>\n\t\t\t{/if}\n\t\t</div>\n\t{:else if post.kind === 'video' && post.mediaUrl}\n\t\t<div class=\"relative mt-3 aspect-square overflow-hidden bg-[#0a0a0a]\">\n\t\t\t<!-- RAT-269: muted autoplay + intersection-observer pause/resume.\n\t\t\t\t Tap on video toggles mute. tap on mute-indicator does the same. -->\n\t\t\t<!-- svelte-ignore a11y_media_has_caption -->\n\t\t\t<video\n\t\t\t\tbind:this={videoEl}\n\t\t\t\tsrc={post.mediaUrl}\n\t\t\t\tposter={post.mediaPosterUrl ?? undefined}\n\t\t\t\tpreload=\"metadata\"\n\t\t\t\tautoplay\n\t\t\t\tmuted\n\t\t\t\tloop\n\t\t\t\tplaysinline\n\t\t\t\tonclick={videoTap}\n\t\t\t\tclass=\"relative h-full w-full object-contain cursor-pointer\"\n\t\t\t\twidth={post.mediaWidth ?? undefined}\n\t\t\t\theight={post.mediaHeight ?? undefined}\n\t\t\t></video>\n\t\t\t{#if onopenreels}\n\t\t\t\t<span class=\"pointer-events-none absolute top-3 right-3 flex items-center gap-1 rounded-full bg-pink px-2.5 py-1 font-display text-[11px] font-bold text-white\">\n\t\t\t\t\t<svg viewBox=\"0 0 9 11\" class=\"h-2.5 w-2\" fill=\"currentColor\"><path d=\"M0 0l9 5.5L0 11z\" /></svg>\n\t\t\t\t\t{t('Reels')}\n\t\t\t\t</span>\n\t\t\t{/if}\n\t\t\t<!-- mute / unmute indicator, bottom-right corner -->\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tonclick={toggleMute}\n\t\t\t\tclass=\"absolute bottom-3 right-3 flex h-9 w-9 items-center justify-center rounded-full bg-bg/60 backdrop-blur text-white hover:bg-bg/80 transition-colors\"\n\t\t\t\taria-label={videoMuted ? t('unmute') : t('mute')}\n\t\t\t>\n\t\t\t\t{#if videoMuted}\n\t\t\t\t\t<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n\t\t\t\t\t\t<path d=\"M2.5 6v4h2l3 2.5v-9L4.5 6h-2z\" />\n\t\t\t\t\t\t<path d=\"M11 6l3 3M14 6l-3 3\" />\n\t\t\t\t\t</svg>\n\t\t\t\t{:else}\n\t\t\t\t\t<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n\t\t\t\t\t\t<path d=\"M2.5 6v4h2l3 2.5v-9L4.5 6h-2z\" />\n\t\t\t\t\t\t<path d=\"M10 5.5a3.5 3.5 0 010 5M12 3.5a6 6 0 010 9\" />\n\t\t\t\t\t</svg>\n\t\t\t\t{/if}\n\t\t\t</button>\n\t\t</div>\n\t{:else if post.kind === 'link' && post.linkUrl}\n\t\t<a\n\t\t\thref={post.linkUrl}\n\t\t\ttarget=\"_blank\"\n\t\t\trel=\"noopener noreferrer\"\n\t\t\tclass=\"mx-4 mt-3 flex overflow-hidden rounded-xl border border-border bg-bg transition-colors hover:border-accent/40\"\n\t\t>\n\t\t\t{#if post.linkOgImageUrl}\n\t\t\t\t<ImageWithShimmer\n\t\t\t\t\tsrc={post.linkOgImageUrl}\n\t\t\t\t\talt=\"\"\n\t\t\t\t\tclass=\"h-24 w-24 shrink-0 sm:h-32 sm:w-32\"\n\t\t\t\t\timgClass=\"h-full w-full object-cover\"\n\t\t\t\t\tsurface=\"link_card\"\n\t\t\t\t\tonretry={resignPostMedia}\n\t\t\t\t/>\n\t\t\t{/if}\n\t\t\t<div class=\"min-w-0 flex-1 p-3\">\n\t\t\t\t{#if post.linkOgSiteName}\n\t\t\t\t\t<div class=\"truncate text-[11px] uppercase tracking-wider text-muted/60\">{post.linkOgSiteName}</div>\n\t\t\t\t{/if}\n\t\t\t\t<div class=\"line-clamp-2 text-sm font-semibold text-text\">{post.linkOgTitle ?? post.linkUrl}</div>\n\t\t\t\t{#if post.linkOgDesc}\n\t\t\t\t\t<p class=\"mt-1 line-clamp-2 text-xs text-muted\">{post.linkOgDesc}</p>\n\t\t\t\t{/if}\n\t\t\t</div>\n\t\t</a>\n\t{:else if post.sourceContentId && post.sourceContentType}\n\t\t<!-- RAT-271: cross-content card — routes back to the original duel /\n\t\t\t rate / arena / beat surface, and renders a preview thumbnail\n\t\t\t (crossImageUrl resolved server-side by resolveCrossContentImageUrls).\n\t\t\t Source map:\n\t\t\t   duel        → duel-share-cards (public, pre-warmed on reveal)\n\t\t\t   generation  → foil-cards (signed)\n\t\t\t   arena_subm. → arena-photos (public)\n\t\t\t   beat        → beat-photos mediaA (signed)\n\t\t\t Null = source has no renderable preview (still pending render,\n\t\t\t unrevealed duel, etc.) — falls back to the icon-only card. -->\n\t\t{@const crossUrl =\n\t\t\tpost.sourceContentType === 'duel' ? `/d/${post.sourceContentId}` :\n\t\t\tpost.sourceContentType === 'generation' ? `/rate/result/${post.sourceContentId}` :\n\t\t\tpost.sourceContentType === 'arena_submission' ? `/a/s/${post.sourceContentId}` :\n\t\t\tpost.sourceContentType === 'beat' ? `/b/${post.sourceContentId}` :\n\t\t\tpost.sourceContentType === 'album' ? `/album/${post.sourceContentId}` :\n\t\t\t'#'}\n\t\t{@const crossLabel =\n\t\t\tpost.kind === 'duel_result' ? t('duel result') :\n\t\t\tpost.kind === 'rate_result' ? t('rate result') :\n\t\t\tpost.kind === 'arena_submission' ? t('arena submission') :\n\t\t\tpost.kind === 'beat_me' ? t('beat me') :\n\t\t\tpost.kind === 'album' ? t('paid album') :\n\t\t\tt('post')}\n\t\t{@const crossCta =\n\t\t\tpost.kind === 'duel_result' ? t('see the duel result →') :\n\t\t\tpost.kind === 'rate_result' ? t('see the rate result →') :\n\t\t\tpost.kind === 'arena_submission' ? t('see the arena submission →') :\n\t\t\tpost.kind === 'beat_me' ? t('see the beat me →') :\n\t\t\tpost.kind === 'album' ? t('see the paid album →') :\n\t\t\tt('see the post →')}\n\t\t{@const crossIcon =\n\t\t\tpost.kind === 'duel_result' ? '⚔️' :\n\t\t\tpost.kind === 'rate_result' ? '⭐' :\n\t\t\tpost.kind === 'arena_submission' ? '🎯' :\n\t\t\tpost.kind === 'beat_me' ? '🥊' :\n\t\t\tpost.kind === 'album' ? '⬡' :\n\t\t\t'·'}\n\t\t{@const crossImageSrc = post.crossImageUrl}\n\t\t{@const crossImageSrcB = post.crossImageUrlB}\n\t\t<a\n\t\t\thref={crossUrl}\n\t\t\tclass=\"mx-4 mt-3 block overflow-hidden rounded-xl border border-border bg-surface-2/40 no-underline transition-colors hover:border-border-strong\"\n\t\t>\n\t\t\t{#if post.kind === 'beat_me' && crossImageSrc && !crossImageFailed && crossImageSrcB && !crossImageFailedB}\n\t\t\t\t<!-- 1v1 beat-me split: two photos side-by-side with a hairline\n\t\t\t\t\t divider. Each half can be image OR video (beats accept both)\n\t\t\t\t\t — type swaps <img>↔<video preload=\"metadata\"> per side so an\n\t\t\t\t\t mp4 source actually shows a thumbnail.\n\t\t\t\t\t RAT-294 follow-up: `#t=0.1` URL fragment seeks the video to\n\t\t\t\t\t the 100ms mark, which forces the browser to decode + display\n\t\t\t\t\t the first frame as the static thumbnail. Without it,\n\t\t\t\t\t preload=metadata alone only fetches duration/dimensions and\n\t\t\t\t\t the tile renders as a black square. Fragment is local to\n\t\t\t\t\t the browser, so signed-URL auth is unaffected. -->\n\t\t\t\t<div class=\"relative grid aspect-square grid-cols-2 gap-px overflow-hidden bg-[#0a0a0a]\">\n\t\t\t\t\t<div class=\"relative bg-[#0a0a0a]\">\n\t\t\t\t\t\t{#if post.crossMediaType === 'video'}\n\t\t\t\t\t\t\t<!-- svelte-ignore a11y_media_has_caption -->\n\t\t\t\t\t\t\t<video\n\t\t\t\t\t\t\t\tsrc=\"{crossImageSrc}#t=0.1\"\n\t\t\t\t\t\t\t\tpreload=\"metadata\"\n\t\t\t\t\t\t\t\tmuted\n\t\t\t\t\t\t\t\tplaysinline\n\t\t\t\t\t\t\t\tonerror={() => (crossImageFailed = true)}\n\t\t\t\t\t\t\t\tclass=\"absolute inset-0 h-full w-full object-contain\"\n\t\t\t\t\t\t\t></video>\n\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\tsrc={crossImageSrc}\n\t\t\t\t\t\t\t\talt={t('{label} side A', { label: crossLabel })}\n\t\t\t\t\t\t\t\tloading=\"lazy\"\n\t\t\t\t\t\t\t\tonerror={() => (crossImageFailed = true)}\n\t\t\t\t\t\t\t\tclass=\"absolute inset-0 h-full w-full object-contain\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t{/if}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"relative bg-[#0a0a0a]\">\n\t\t\t\t\t\t{#if post.crossMediaTypeB === 'video'}\n\t\t\t\t\t\t\t<!-- svelte-ignore a11y_media_has_caption -->\n\t\t\t\t\t\t\t<video\n\t\t\t\t\t\t\t\tsrc=\"{crossImageSrcB}#t=0.1\"\n\t\t\t\t\t\t\t\tpreload=\"metadata\"\n\t\t\t\t\t\t\t\tmuted\n\t\t\t\t\t\t\t\tplaysinline\n\t\t\t\t\t\t\t\tonerror={() => (crossImageFailedB = true)}\n\t\t\t\t\t\t\t\tclass=\"absolute inset-0 h-full w-full object-contain\"\n\t\t\t\t\t\t\t></video>\n\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\tsrc={crossImageSrcB}\n\t\t\t\t\t\t\t\talt={t('{label} side B', { label: crossLabel })}\n\t\t\t\t\t\t\t\tloading=\"lazy\"\n\t\t\t\t\t\t\t\tonerror={() => (crossImageFailedB = true)}\n\t\t\t\t\t\t\t\tclass=\"absolute inset-0 h-full w-full object-contain\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t{/if}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t{:else if crossImageSrc && !crossImageFailed}\n\t\t\t\t<!-- Single source preview: image OR video. Same aspect-square dark\n\t\t\t\t\t surface as image posts. -->\n\t\t\t\t<div class=\"relative aspect-square overflow-hidden bg-[#0a0a0a]\">\n\t\t\t\t\t{#if post.crossMediaType === 'video'}\n\t\t\t\t\t\t<!-- RAT-446: cross-content videos (arena) autoplay muted in-viewport\n\t\t\t\t\t\t\t exactly like native video posts — same bound videoEl feeds the\n\t\t\t\t\t\t\t IntersectionObserver above. Poster paints the tile instantly;\n\t\t\t\t\t\t\t legacy rows without one fall back to metadata preload. -->\n\t\t\t\t\t\t<!-- svelte-ignore a11y_media_has_caption -->\n\t\t\t\t\t\t<video\n\t\t\t\t\t\t\tbind:this={videoEl}\n\t\t\t\t\t\t\tsrc={crossImageSrc}\n\t\t\t\t\t\t\tposter={post.crossPosterUrl ?? undefined}\n\t\t\t\t\t\t\tpreload=\"metadata\"\n\t\t\t\t\t\t\tautoplay\n\t\t\t\t\t\t\tmuted\n\t\t\t\t\t\t\tloop\n\t\t\t\t\t\t\tplaysinline\n\t\t\t\t\t\t\tonclick={videoTap}\n\t\t\t\t\t\t\tonerror={() => (crossImageFailed = true)}\n\t\t\t\t\t\t\tclass=\"relative h-full w-full object-contain {onopenreels ? 'cursor-pointer' : ''}\"\n\t\t\t\t\t\t></video>\n\t\t\t\t\t\t{#if onopenreels}\n\t\t\t\t\t\t\t<span class=\"pointer-events-none absolute top-3 right-3 flex items-center gap-1 rounded-full bg-pink px-2.5 py-1 font-display text-[11px] font-bold text-white\">\n\t\t\t\t\t\t\t\t<svg viewBox=\"0 0 9 11\" class=\"h-2.5 w-2\" fill=\"currentColor\"><path d=\"M0 0l9 5.5L0 11z\" /></svg>\n\t\t\t\t\t\t\t\t{t('Reels')}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonclick={toggleMute}\n\t\t\t\t\t\t\tclass=\"absolute bottom-3 right-3 flex h-9 w-9 items-center justify-center rounded-full bg-bg/60 backdrop-blur text-white hover:bg-bg/80 transition-colors\"\n\t\t\t\t\t\t\taria-label={videoMuted ? t('unmute') : t('mute')}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{#if videoMuted}\n\t\t\t\t\t\t\t\t<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n\t\t\t\t\t\t\t\t\t<path d=\"M2.5 6v4h2l3 2.5v-9L4.5 6h-2z\" />\n\t\t\t\t\t\t\t\t\t<path d=\"M11 6l3 3M14 6l-3 3\" />\n\t\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n\t\t\t\t\t\t\t\t\t<path d=\"M2.5 6v4h2l3 2.5v-9L4.5 6h-2z\" />\n\t\t\t\t\t\t\t\t\t<path d=\"M10 5.5a3.5 3.5 0 010 5M12 3.5a6 6 0 010 9\" />\n\t\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t{:else}\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\tsrc={crossImageSrc}\n\t\t\t\t\t\t\talt={t('{label} preview', { label: crossLabel })}\n\t\t\t\t\t\t\tloading=\"lazy\"\n\t\t\t\t\t\t\tonerror={() => (crossImageFailed = true)}\n\t\t\t\t\t\t\tclass=\"relative h-full w-full object-contain\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t{/if}\n\t\t\t\t</div>\n\t\t\t{:else if post.crossFallback?.kind === 'generation_score'}\n\t\t\t\t<!-- RAT-294: orphan rate_result post (foil PNG never rendered + no\n\t\t\t\t\t saved photo). Synthetic score card so the feed tile is never blank. -->\n\t\t\t\t<div\n\t\t\t\t\tclass=\"relative flex aspect-square flex-col items-center justify-center gap-2\"\n\t\t\t\t\tstyle:background={post.crossFallback.mode === 'hype'\n\t\t\t\t\t\t? 'radial-gradient(60% 50% at 50% 35%, var(--color-accent-light), transparent 70%), linear-gradient(160deg, #0c1f12 0%, #0a0a0a 100%)'\n\t\t\t\t\t\t: 'radial-gradient(60% 50% at 50% 35%, rgba(59,130,246,.22), transparent 70%), linear-gradient(160deg, #0c1322 0%, #0a0a0a 100%)'}\n\t\t\t\t>\n\t\t\t\t\t<span class=\"font-mono text-[10px] uppercase tracking-[0.25em] text-muted\">{post.crossFallback.mode}</span>\n\t\t\t\t\t<div class=\"flex items-baseline gap-1\">\n\t\t\t\t\t\t<span class=\"font-display text-7xl font-extrabold leading-none tracking-tighter text-text tabular-nums\">{post.crossFallback.score.toFixed(1)}</span>\n\t\t\t\t\t\t<span class=\"text-lg text-muted\">/10</span>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t{/if}\n\t\t\t<div class=\"flex items-center gap-3 p-4\">\n\t\t\t\t<div class=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-surface-2 text-xl\">{crossIcon}</div>\n\t\t\t\t<div class=\"min-w-0 flex-1\">\n\t\t\t\t\t<div class=\"text-[10px] font-mono uppercase tracking-widest text-muted\">{crossLabel}</div>\n\t\t\t\t\t<div class=\"font-display text-sm font-semibold text-text\">{crossCta}</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</a>\n\t{/if}\n\n\t<footer class=\"flex items-center gap-3 px-4 py-3\">\n\t\t<!-- RAT-272 follow-up: reddit-style vote stack replaces the like\n\t\t\t heart. Likes still live in the DB (notifications + legacy data)\n\t\t\t but the visible engagement signal is the up/down vote. -->\n\t\t<VoteStack\n\t\t\tpostId={post.id}\n\t\t\tinitialNetScore={post.netScore}\n\t\t\tinitialViewerVote={post.viewerVote}\n\t\t\t{viewerLoggedIn}\n\t\t/>\n\t\t<a href={postHref} class=\"inline-flex items-center gap-1.5 text-sm text-muted hover:text-text\">\n\t\t\t<svg viewBox=\"0 0 24 24\" class=\"h-5 w-5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n\t\t\t\t<path d=\"M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z\" />\n\t\t\t</svg>\n\t\t\t<span class=\"tabular-nums\">{post.commentCount}</span>\n\t\t</a>\n\t\t{#if messageCta && post.creator.nickname && post.creator.id !== viewerId}\n\t\t\t<!-- RAT-523: the creator's DM, by the same choice the profile offers.\n\t\t\t\t No data preload: a tap opens the chooser, not the chat, and a preload\n\t\t\t\t would both open the thread before anyone chose to and hand the chat a\n\t\t\t\t stale copy — without the tip and note just sent — when a tip lands\n\t\t\t\t there a moment later. -->\n\t\t\t<a\n\t\t\t\thref=\"{resolve('/(chat)/c/[nickname]', { nickname: post.creator.nickname })}?from=post\"\n\t\t\t\tdata-sveltekit-preload-data=\"off\"\n\t\t\t\tonclick={messageCreator}\n\t\t\t\tclass=\"inline-flex items-center gap-1.5 text-sm text-muted hover:text-text\"\n\t\t\t\taria-label={t('message @{name}', { name: post.creator.nickname })}\n\t\t\t>\n\t\t\t\t<svg viewBox=\"0 0 24 24\" class=\"h-[18px] w-[18px]\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"\n\t\t\t\t\t><path d=\"M22 2L11 13M22 2l-7 20-4-9-9-4 20-7z\" /></svg\n\t\t\t\t>\n\t\t\t\t<span class=\"hidden sm:inline\">{t('message')}</span>\n\t\t\t</a>\n\t\t\t<MessageChooser\n\t\t\t\topen={chooserOpen}\n\t\t\t\tnickname={post.creator.nickname}\n\t\t\t\tfrom=\"post\"\n\t\t\t\tonclose={() => (chooserOpen = false)}\n\t\t\t/>\n\t\t{/if}\n\t\t<!-- RAT-424: token spotlight boost + share, grouped on the right. -->\n\t\t<div class=\"ml-auto flex items-center gap-3\">\n\t\t\t<PostBoostButton\n\t\t\t\tpostId={post.id}\n\t\t\t\tboostedUntil={post.boostedUntil}\n\t\t\t\tboostCount={post.boostCount}\n\t\t\t\t{viewerLoggedIn}\n\t\t\t/>\n\t\t<!-- On mobile the share action lives in the header kebab menu — the\n\t\t\t footer row has no room for it. -->\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tonclick={sharePost}\n\t\t\tclass=\"hidden items-center gap-1.5 text-sm text-muted hover:text-text sm:inline-flex\"\n\t\t\taria-label={t('share post')}\n\t\t>\n\t\t\t{#if shareCopied}\n\t\t\t\t<svg viewBox=\"0 0 24 24\" class=\"h-5 w-5 text-accent\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n\t\t\t\t\t<path d=\"M20 6L9 17l-5-5\" />\n\t\t\t\t</svg>\n\t\t\t\t<span class=\"text-accent\">{t('link copied')}</span>\n\t\t\t{:else}\n\t\t\t\t<svg viewBox=\"0 0 24 24\" class=\"h-5 w-5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n\t\t\t\t\t<circle cx=\"18\" cy=\"5\" r=\"3\" /><circle cx=\"6\" cy=\"12\" r=\"3\" /><circle cx=\"18\" cy=\"19\" r=\"3\" />\n\t\t\t\t\t<line x1=\"8.6\" y1=\"13.5\" x2=\"15.4\" y2=\"17.5\" /><line x1=\"15.4\" y1=\"6.5\" x2=\"8.6\" y2=\"10.5\" />\n\t\t\t\t</svg>\n\t\t\t\t<span>{t('share')}</span>\n\t\t\t{/if}\n\t\t</button>\n\t\t</div>\n\t</footer>\n\n\t{#if expanded}\n\t\t<div class=\"px-4 pb-4\">\n\t\t\t<CommentSection postId={post.id} {viewerLoggedIn} {viewerId} postCreatorId={post.creator.id} initialComments={initialComments} />\n\t\t</div>\n\t{/if}\n</article>\n\n<ReportContentModal\n\tbind:open={reportOpen}\n\tentityType=\"creator_post\"\n\tentityId={post.id}\n\tonclose={() => (reportOpen = false)}\n/>\n\n<style>\n\t/* Partner couple card (kind='partnership') — mirrors the approved mock. */\n\t.couple {\n\t\tposition: relative;\n\t\tisolation: isolate;\n\t\toverflow: hidden;\n\t\tmargin: 12px 16px 4px;\n\t\tborder-radius: 14px;\n\t\t/* Rose ground + a soft warm pool behind the avatars. Neutral edge,\n\t\t   no colored ring — the warmth sits in the middle, not on the border. */\n\t\tbackground:\n\t\t\tradial-gradient(ellipse 70% 55% at 50% 38%, rgba(255, 77, 109, 0.16), transparent 70%),\n\t\t\tlinear-gradient(160deg, #2a1219, #160b0e);\n\t\tborder: 1px solid #3a1a22;\n\t\tpadding: 26px 18px 22px;\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\talign-items: center;\n\t\tgap: 12px;\n\t\ttext-align: center;\n\t}\n\t.couple-sky {\n\t\tposition: absolute;\n\t\tinset: 0;\n\t\tz-index: -1;\n\t\tpointer-events: none;\n\t}\n\t.couple-mote {\n\t\tposition: absolute;\n\t\tleft: var(--x);\n\t\tbottom: -12px;\n\t\twidth: var(--s);\n\t\theight: var(--s);\n\t\tfill: var(--color-coral);\n\t\topacity: 0;\n\t\tanimation: couple-float var(--t) linear var(--d) infinite;\n\t\twill-change: transform, opacity;\n\t}\n\t@keyframes couple-float {\n\t\t0% { transform: translate3d(0, 0, 0) rotate(-8deg); opacity: 0; }\n\t\t12% { opacity: 0.45; }\n\t\t50% { transform: translate3d(6px, -60px, 0) rotate(6deg); }\n\t\t88% { opacity: 0.35; }\n\t\t100% { transform: translate3d(-4px, -150px, 0) rotate(-6deg); opacity: 0; }\n\t}\n\t.couple-avs {\n\t\tposition: relative;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t}\n\t/* Fixed-size grid box so the ring is concentric with the avatar (the\n\t   avatar is an inline-level <a>; a block wrapper adds line-height slack\n\t   under it and the ring drifts down). */\n\t.couple-av {\n\t\tdisplay: grid;\n\t\tplace-items: center;\n\t\twidth: 56px;\n\t\theight: 56px;\n\t\tborder-radius: 50%;\n\t\tline-height: 0;\n\t\tbox-shadow: 0 0 0 3px #160b0e;\n\t\tbackground: #160b0e;\n\t}\n\t.couple-av--b {\n\t\tmargin-left: -14px;\n\t}\n\t.couple-heart {\n\t\tposition: relative;\n\t\tz-index: 1;\n\t\twidth: 28px;\n\t\theight: 28px;\n\t\tmargin: 0 -7px;\n\t\tborder-radius: 50%;\n\t\tbackground: var(--color-coral);\n\t\tdisplay: grid;\n\t\tplace-items: center;\n\t\tbox-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);\n\t\tanimation: couple-pulse 1.8s ease-in-out infinite;\n\t}\n\t@keyframes couple-pulse {\n\t\t0%, 28%, 100% { transform: scale(1); }\n\t\t8% { transform: scale(1.16); }\n\t\t16% { transform: scale(1); }\n\t\t22% { transform: scale(1.1); }\n\t}\n\t@media (prefers-reduced-motion: reduce) {\n\t\t.couple-mote { animation: none; opacity: 0.3; transform: translate3d(0, -60px, 0); }\n\t\t.couple-heart { animation: none; }\n\t}\n\t.couple-heart svg {\n\t\twidth: 13px;\n\t\theight: 13px;\n\t\tfill: #fff;\n\t\tdisplay: block;\n\t}\n\t.couple-title {\n\t\tfont-family: var(--font-display);\n\t\tfont-weight: 700;\n\t\tfont-size: 18px;\n\t\tletter-spacing: -0.01em;\n\t\tcolor: var(--color-text);\n\t\ttext-wrap: balance;\n\t}\n\t.couple-title span {\n\t\tcolor: var(--color-coral);\n\t}\n\t.couple-sub {\n\t\tfont-size: 12px;\n\t\tcolor: var(--color-muted);\n\t}\n</style>\n"],"version":3}