{"release_id":"01a1c502-4ad1-0000-ec62-adc54d3c69aa","chunk_id":"01a1c502-4c55-7d40-9637-5f972e79b39d","file":"q8wKYrc_.mjs","mappings":"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","names":["TIERS","tierCls","tier","t","title","$.state","caption","candidates","$.proxy","loading","loadError","placed","posting","error","pickerSelection","sheetTier","search","captionEl","mentionOpen","mentionQuery","mentionCandidates","mentionLoadKicked","byId","$.derived","$.get","c","tierByUserId","p","filtered","hasNiche","submittable","onMount","cancelled","res","j","$.set","openSheet","closeSheet","toggleInTier","userId","current","removePlaced","refreshMentionState","q","mentionQueryAtCaret","loadMentionCandidates","pickMention","nickname","r","spliceMention","tick","entriesForTier","submit","positionByTier","entries","position","body","$$props","handleBackdrop","e","handleKey","div","root","div_1","$.child","header","h3","text","$.reset","button","$.sibling","input","$.remove_input_defaults","node","p_1","root_1","p_2","root_2","$$render","consequent_1","div_2","$$anchor","rowEntries","div_3","root_3","div_4","text_3","button_1","node_1","$.each","span","root_5","node_3","getAvatarUrl","DuelAvatar","span_1","$.set_attribute","$0","$.set_text","text_4","$.delegated","$.append","consequent_2","span_2","root_6","$.template_effect","text_5","consequent_3","textarea","$.remove_textarea_child","$$value","p_3","div_5","NichePicker","n","span_3","root_8","button_2","node_5","text_7","p_4","root_9","consequent_5","node_7","MentionAutocomplete","currentTier","div_6","root_10","div_7","header_1","span_4","text_9","h4","button_3","div_8","input_1","div_9","p_5","root_11","text_11","p_6","root_12","node_10","placedTier","button_4","root_14","node_11","span_5","span_6","root_15","span_7","root_16","text_14","$.set_class","$1","span_8","root_17","consequent_8","consequent_9","alternate_1","text_13","consequent_6","consequent_7","alternate_2","$3","$4","$.transition","fly","consequent_10","$2","$5","$6","$$args","autofocus","framed","extraSelection1","extraSelection2","pickExtra","slot","linkUrl","linkOpen","file","filePreviewUrl","extraFiles","MAX_IMAGES","dragOver","uploading","progress","nudgeOpen","nudgeCode","tierlistOpen","textareaEl","ACCEPT_IMAGE","ACCEPT_IMAGE_PICKER","ACCEPT_VIDEO","MAX_IMAGE","MAX_VIDEO","MAX_VIDEO_DUR","imageInput","videoInput","fileKind","hasContent","viewerNickname","page","viewerAvatarPath","reset","clearFile","autosize","x","removeExtra","i","_","idx","autofocusFired","$.user_effect","handleFile","f","detachIfImage","isHeic","heicToJpeg","fail","pickFailure","analytics.trackUploadFail","isImage","isVideo","pickImage","pickVideo","toggleLink","onDrop","readImageDimensions","resolve","url","img","readVideoMeta","v","canvas","ctx","b","uploadToSigned","mimeType","size","purpose","bytes","urlRes","path","signedUrl","putRes","sharedCode","extractDuelCode","clean","stripExifClient","dims","extraMedia","cleanX","dimsX","pathX","meta","mediaPath","posterPath","extraIds","invalidateAll","stale","isStaleFileError","section","$.first_child","fragment","fragment_1","img_1","video","consequent","alternate","node_2","root_4","node_4","img_2","root_7","consequent_4","input_2","button_5","button_6","button_7","text_2","root_13","node_13","DuelFeatureNudge","consequent_11","node_14","TierListComposerDialog","consequent_12","$7","$8","$.event"],"sources":["../../../../../../src/lib/components/post/TierListComposerDialog.svelte","../../../../../../src/lib/components/post/PostComposer.svelte"],"sourcesContent":["<script lang=\"ts\">\n\timport { t } from '$lib/i18n';\n\t// Tier list composer: rank people you follow into S–D tiers, post to feed.\n\t// Opened from PostComposer's \"tier list\" action. Interaction: tap a tier ROW\n\t// → a bottom sheet slides up with search + the people you follow; tapping a\n\t// person toggles them into that tier (tapping someone already placed\n\t// elsewhere moves them). Tap a placed chip in a row to remove directly.\n\timport { onMount, tick } from 'svelte';\n\timport { fly } from 'svelte/transition';\n\timport DuelAvatar from '$lib/components/duel/DuelAvatar.svelte';\n\timport MentionAutocomplete from '$lib/components/chat/MentionAutocomplete.svelte';\n\timport NichePicker from '$lib/components/post/NichePicker.svelte';\n\timport { getAvatarUrl } from '$lib/avatar';\n\timport {\n\t\tmentionQueryAtCaret,\n\t\tspliceMention,\n\t\tloadMentionCandidates,\n\t\ttype MentionCandidate\n\t} from '$lib/mention-typeahead';\n\timport type { NicheOption } from '$lib/types/niche';\n\n\ttype Tier = 'S' | 'A' | 'B' | 'C' | 'D';\n\ttype Candidate = { userId: string; nickname: string; avatarPath: string | null };\n\n\tinterface Props {\n\t\tnicheContext?: { id: string; slug: string; name: string };\n\t\tclanContext?: { id: string; tag: string; name: string };\n\t\tonclose: () => void;\n\t\t/** Fired after a successful post — parent refreshes the feed + closes. */\n\t\tonposted: () => void;\n\t}\n\tlet { nicheContext, clanContext, onclose, onposted }: Props = $props();\n\n\tconst TIERS: { key: Tier; cls: string }[] = [\n\t\t{ key: 'S', cls: 'bg-coral' },\n\t\t{ key: 'A', cls: 'bg-orange' },\n\t\t{ key: 'B', cls: 'bg-yellow' },\n\t\t{ key: 'C', cls: 'bg-green' },\n\t\t{ key: 'D', cls: 'bg-blue' }\n\t];\n\tconst tierCls = (tier: Tier) => TIERS.find((t) => t.key === tier)?.cls ?? 'bg-surface-2';\n\n\tlet title = $state('');\n\tlet caption = $state('');\n\tlet candidates = $state<Candidate[]>([]);\n\tlet loading = $state(true);\n\tlet loadError = $state('');\n\tlet placed = $state<{ userId: string; tier: Tier }[]>([]);\n\tlet posting = $state(false);\n\tlet error = $state('');\n\tlet pickerSelection = $state<NicheOption | null>(null);\n\t// Which tier's picker sheet is open (null = closed).\n\tlet sheetTier = $state<Tier | null>(null);\n\tlet search = $state('');\n\t// @-mention typeahead on the caption. Candidates = viewer's followers\n\t// (that's who a mention notifies), NOT the tier candidates (following).\n\tlet captionEl = $state<HTMLTextAreaElement | null>(null);\n\tlet mentionOpen = $state(false);\n\tlet mentionQuery = $state('');\n\tlet mentionCandidates = $state<MentionCandidate[]>([]);\n\tlet mentionLoadKicked = false;\n\n\tconst byId = $derived(new Map(candidates.map((c) => [c.userId, c])));\n\tconst tierByUserId = $derived(new Map(placed.map((p) => [p.userId, p.tier])));\n\tconst filtered = $derived(\n\t\tcandidates.filter((c) => c.nickname.toLowerCase().includes(search.trim().toLowerCase()))\n\t);\n\tconst hasNiche = $derived(!!nicheContext || !!clanContext || !!pickerSelection);\n\tconst submittable = $derived(\n\t\t!posting && title.trim().length > 0 && placed.length > 0 && hasNiche\n\t);\n\n\tonMount(() => {\n\t\tlet cancelled = false;\n\t\t(async () => {\n\t\t\ttry {\n\t\t\t\tconst res = await fetch('/api/post/tier-candidates');\n\t\t\t\tif (!res.ok) throw new Error('failed');\n\t\t\t\tconst j = (await res.json()) as { candidates: Candidate[] };\n\t\t\t\tif (!cancelled) candidates = j.candidates;\n\t\t\t} catch {\n\t\t\t\tif (!cancelled) loadError = t('could not load the people you follow — try again');\n\t\t\t} finally {\n\t\t\t\tif (!cancelled) loading = false;\n\t\t\t}\n\t\t})();\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t});\n\n\tfunction openSheet(tier: Tier) {\n\t\tsheetTier = tier;\n\t\tsearch = '';\n\t}\n\tfunction closeSheet() {\n\t\tsheetTier = null;\n\t}\n\n\t/** Sheet tap: toggle membership in the sheet's tier. Someone placed in\n\t *  another tier gets MOVED here (their old row entry is replaced). */\n\tfunction toggleInTier(userId: string, tier: Tier) {\n\t\tconst current = tierByUserId.get(userId);\n\t\tif (current === tier) {\n\t\t\tplaced = placed.filter((p) => p.userId !== userId);\n\t\t} else if (current) {\n\t\t\tplaced = placed.map((p) => (p.userId === userId ? { ...p, tier } : p));\n\t\t} else {\n\t\t\tplaced = [...placed, { userId, tier }];\n\t\t}\n\t}\n\n\tfunction removePlaced(userId: string) {\n\t\tplaced = placed.filter((p) => p.userId !== userId);\n\t}\n\n\tfunction refreshMentionState() {\n\t\tconst q = mentionQueryAtCaret(caption, captionEl);\n\t\tif (q === null) {\n\t\t\tmentionOpen = false;\n\t\t\treturn;\n\t\t}\n\t\tmentionQuery = q;\n\t\tmentionOpen = true;\n\t\tif (!mentionLoadKicked) {\n\t\t\tmentionLoadKicked = true;\n\t\t\tloadMentionCandidates().then((c) => (mentionCandidates = c));\n\t\t}\n\t}\n\n\tfunction pickMention(nickname: string) {\n\t\tconst r = spliceMention(caption, captionEl, nickname);\n\t\tcaption = r.text;\n\t\tmentionOpen = false;\n\t\ttick().then(() => {\n\t\t\tcaptionEl?.focus();\n\t\t\tcaptionEl?.setSelectionRange(r.caret, r.caret);\n\t\t});\n\t}\n\n\tfunction entriesForTier(tier: Tier) {\n\t\treturn placed.filter((p) => p.tier === tier);\n\t}\n\n\tasync function submit() {\n\t\tif (!hasNiche && title.trim() && placed.length > 0) {\n\t\t\terror = t('pick a niche first');\n\t\t\treturn;\n\t\t}\n\t\tif (!submittable) return;\n\t\tposting = true;\n\t\terror = '';\n\t\ttry {\n\t\t\tconst positionByTier: Record<string, number> = {};\n\t\t\tconst entries = placed.map((p) => {\n\t\t\t\tconst position = positionByTier[p.tier] ?? 0;\n\t\t\t\tpositionByTier[p.tier] = position + 1;\n\t\t\t\treturn { userId: p.userId, tier: p.tier, position };\n\t\t\t});\n\t\t\tconst body: Record<string, unknown> = {\n\t\t\t\tkind: 'tierlist',\n\t\t\t\ttitle: title.trim(),\n\t\t\t\tcaption: caption.trim() || null,\n\t\t\t\tentries\n\t\t\t};\n\t\t\tif (nicheContext) body.nicheId = nicheContext.id;\n\t\t\telse if (pickerSelection) body.nicheId = pickerSelection.id;\n\t\t\tif (clanContext) body.clanId = clanContext.id;\n\t\t\tconst res = await fetch('/api/post/create', {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders: { 'content-type': 'application/json' },\n\t\t\t\tbody: JSON.stringify(body)\n\t\t\t});\n\t\t\tconst j = await res.json();\n\t\t\tif (!res.ok) {\n\t\t\t\terror = j.error ?? t('failed to post');\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tonposted();\n\t\t} catch {\n\t\t\terror = t('something broke — try again');\n\t\t} finally {\n\t\t\tposting = false;\n\t\t}\n\t}\n\n\tfunction handleBackdrop(e: MouseEvent) {\n\t\tif (e.target === e.currentTarget) onclose();\n\t}\n\tfunction handleKey(e: KeyboardEvent) {\n\t\tif (e.key === 'Escape') {\n\t\t\tif (mentionOpen) mentionOpen = false;\n\t\t\telse if (sheetTier) closeSheet();\n\t\t\telse onclose();\n\t\t}\n\t}\n</script>\n\n<!-- Full-screen takeover on mobile (the centered card squished between the\n\t banner + bottom nav); centered card from sm up. z-[215]: above all site\n\t chrome (nav band is 90–110, PostToFeedCta 210) but BELOW NichePicker's\n\t fullscreen sheet (220) — the picker opens from inside this dialog and has\n\t to land on top of it. MentionAutocomplete (250) also clears us. -->\n<div\n\tclass=\"fixed inset-0 z-[215] flex items-stretch justify-center bg-black/60 sm:items-center sm:p-4 sm:pb-[calc(1rem+env(safe-area-inset-bottom,0px))]\"\n\trole=\"dialog\"\n\taria-modal=\"true\"\n\taria-labelledby=\"tierlist-title\"\n\ttabindex=\"-1\"\n\tonclick={handleBackdrop}\n\tonkeydown={handleKey}\n>\n\t<div\n\t\tclass=\"h-full w-full overflow-y-auto bg-bg p-5 pb-[calc(1.25rem+env(safe-area-inset-bottom,0px))] shadow-2xl sm:h-auto sm:max-h-[calc(100dvh-2rem)] sm:max-w-md sm:rounded-2xl sm:border sm:border-border sm:pb-5\"\n\t>\n\t\t<header class=\"flex items-center justify-between\">\n\t\t\t<h3\n\t\t\t\tid=\"tierlist-title\"\n\t\t\t\tclass=\"font-display text-[17px] font-semibold tracking-tight text-text\"\n\t\t\t>\n\t\t\t\t{t('New tier list')}\n\t\t\t</h3>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"rounded-lg px-1.5 text-2xl leading-none text-muted transition-colors hover:bg-surface hover:text-text\"\n\t\t\t\taria-label={t('close')}\n\t\t\t\tonclick={onclose}\n\t\t\t>\n\t\t\t\t×\n\t\t\t</button>\n\t\t</header>\n\n\t\t<input\n\t\t\ttype=\"text\"\n\t\t\tbind:value={title}\n\t\t\tmaxlength=\"80\"\n\t\t\tplaceholder={t('Name your list')}\n\t\t\tdisabled={posting}\n\t\t\tclass=\"mt-3 block w-full border-0 border-b border-border bg-transparent px-0 pb-2 font-display text-lg font-bold tracking-tight text-text placeholder:text-muted/40 focus:border-accent focus:ring-0 focus:outline-none disabled:opacity-50\"\n\t\t/>\n\n\t\t{#if loadError}\n\t\t\t<p class=\"mt-3 text-xs text-red-400\">{loadError}</p>\n\t\t{:else if !loading && candidates.length === 0}\n\t\t\t<p class=\"mt-3 text-xs text-muted\">{t(\"you don't follow anyone yet — follow people to rank them.\")}</p>\n\t\t{/if}\n\n\t\t<div class=\"mt-3 flex flex-col gap-0.5\">\n\t\t\t{#each TIERS as tier (tier.key)}\n\t\t\t\t{@const rowEntries = entriesForTier(tier.key)}\n\t\t\t\t<div class=\"grid grid-cols-[40px_1fr] gap-0.5\">\n\t\t\t\t\t<div\n\t\t\t\t\t\tclass=\"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>\n\t\t\t\t\t\t{tier.key}\n\t\t\t\t\t</div>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"flex flex-wrap content-center items-center gap-2 rounded-r-lg bg-surface-2 p-2 text-left transition-colors hover:bg-surface\"\n\t\t\t\t\t\taria-label={t('add people to {tier} tier', { tier: tier.key })}\n\t\t\t\t\t\tonclick={() => openSheet(tier.key)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{#each rowEntries as p (p.userId)}\n\t\t\t\t\t\t\t{@const c = byId.get(p.userId)}\n\t\t\t\t\t\t\t{#if c}\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tclass=\"flex w-14 flex-col items-center gap-1\"\n\t\t\t\t\t\t\t\t\trole=\"button\"\n\t\t\t\t\t\t\t\t\ttabindex=\"0\"\n\t\t\t\t\t\t\t\t\ttitle={t('remove @{name}', { name: c.nickname })}\n\t\t\t\t\t\t\t\t\tonclick={(e) => {\n\t\t\t\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\t\t\t\tremovePlaced(p.userId);\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\tonkeydown={(e) => {\n\t\t\t\t\t\t\t\t\t\tif (e.key === 'Enter' || e.key === ' ') {\n\t\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\t\t\t\t\tremovePlaced(p.userId);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<DuelAvatar\n\t\t\t\t\t\t\t\t\t\tnickname={c.nickname}\n\t\t\t\t\t\t\t\t\t\tavatarUrl={getAvatarUrl(c.avatarPath)}\n\t\t\t\t\t\t\t\t\t\tsize={40}\n\t\t\t\t\t\t\t\t\t\thref=\"\"\n\t\t\t\t\t\t\t\t\t\tlink={false}\n\t\t\t\t\t\t\t\t\t/>\n\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>{c.nickname}</span\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t<span\n\t\t\t\t\t\t\tclass=\"flex h-10 w-10 items-center justify-center rounded-full border border-dashed border-border text-lg text-muted/60\"\n\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t+\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t{#if rowEntries.length === 0}\n\t\t\t\t\t\t\t<span class=\"text-[11px] text-muted/50 select-none\">{t('tap to add people')}</span>\n\t\t\t\t\t\t{/if}\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t{/each}\n\t\t</div>\n\n\t\t<textarea\n\t\t\tbind:this={captionEl}\n\t\t\tbind:value={caption}\n\t\t\trows=\"2\"\n\t\t\tmaxlength=\"2000\"\n\t\t\tplaceholder={t('say something about it… (optional)')}\n\t\t\tdisabled={posting}\n\t\t\toninput={refreshMentionState}\n\t\t\tonkeyup={refreshMentionState}\n\t\t\tonclick={refreshMentionState}\n\t\t\tclass=\"mt-4 block w-full resize-none rounded-lg border border-border bg-surface px-3 py-2 text-sm text-text placeholder:text-muted/40 focus:border-accent focus:ring-0 focus:outline-none disabled:opacity-50\"\n\t\t></textarea>\n\n\t\t<p class=\"mt-2 text-[11px] text-muted/70\">\n\t\t\t{placed.length > 0\n\t\t\t\t? placed.length === 1\n\t\t\t\t\t? t('you can only rank people you follow. 1 person will get notified.')\n\t\t\t\t\t: t('you can only rank people you follow. {n} people will get notified.', { n: placed.length })\n\t\t\t\t: t('you can only rank people you follow. everyone you rank gets notified.')}\n\t\t</p>\n\n\t\t<div class=\"mt-3 flex items-center justify-between gap-2\">\n\t\t\t{#if !nicheContext && !clanContext}\n\t\t\t\t<NichePicker\n\t\t\t\t\tbind:selected={pickerSelection}\n\t\t\t\t\tonSelect={(n) => {\n\t\t\t\t\t\tpickerSelection = n;\n\t\t\t\t\t\tif (n) error = '';\n\t\t\t\t\t}}\n\t\t\t\t\tallowSkip={false}\n\t\t\t\t/>\n\t\t\t{:else}\n\t\t\t\t<span></span>\n\t\t\t{/if}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tonclick={submit}\n\t\t\t\tdisabled={posting || title.trim().length === 0 || placed.length === 0}\n\t\t\t\tclass=\"rounded-full bg-accent px-4 py-1.5 text-[13px] font-semibold text-bg transition-colors hover:bg-accent/85 disabled:cursor-not-allowed disabled:opacity-40 {title.trim() &&\n\t\t\t\tplaced.length > 0 &&\n\t\t\t\t!hasNiche\n\t\t\t\t\t? 'opacity-60'\n\t\t\t\t\t: ''}\"\n\t\t\t>\n\t\t\t\t{posting ? t('posting…') : t('post')}\n\t\t\t</button>\n\t\t</div>\n\t\t{#if error}\n\t\t\t<p class=\"mt-2 text-xs text-red-400\">{error}</p>\n\t\t{/if}\n\t</div>\n\n\t<MentionAutocomplete\n\t\topen={mentionOpen}\n\t\tquery={mentionQuery}\n\t\tcandidates={mentionCandidates}\n\t\tanchor={captionEl}\n\t\tonPick={pickMention}\n\t\tonClose={() => (mentionOpen = false)}\n\t/>\n\n\t{#if sheetTier}\n\t\t{@const currentTier = sheetTier}\n\t\t<!-- svelte-ignore a11y_no_static_element_interactions -->\n\t\t<div\n\t\t\tclass=\"absolute inset-0 z-10 flex items-end justify-center bg-black/50\"\n\t\t\tonclick={(e) => {\n\t\t\t\tif (e.target === e.currentTarget) closeSheet();\n\t\t\t}}\n\t\t\tonkeydown={(e) => {\n\t\t\t\tif (e.key === 'Escape') closeSheet();\n\t\t\t}}\n\t\t>\n\t\t\t<div\n\t\t\t\tclass=\"flex max-h-[70dvh] w-full max-w-md flex-col rounded-t-2xl border-x border-t border-border bg-bg shadow-2xl\"\n\t\t\t\ttransition:fly={{ y: 240, duration: 220 }}\n\t\t\t\trole=\"dialog\"\n\t\t\t\taria-label={t('add people to {tier} tier', { tier: currentTier })}\n\t\t\t>\n\t\t\t\t<header class=\"flex items-center gap-2.5 px-4 pt-4 pb-2\">\n\t\t\t\t\t<span\n\t\t\t\t\t\tclass=\"flex h-7 w-7 items-center justify-center rounded-md {tierCls(currentTier)} font-display text-sm font-bold text-bg\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{currentTier}\n\t\t\t\t\t</span>\n\t\t\t\t\t<h4 class=\"font-display text-[15px] font-semibold tracking-tight text-text\">\n\t\t\t\t\t\t{t('Add to {tier} tier', { tier: currentTier })}\n\t\t\t\t\t</h4>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"ml-auto rounded-lg px-1.5 text-2xl leading-none text-muted transition-colors hover:bg-surface hover:text-text\"\n\t\t\t\t\t\taria-label={t('done')}\n\t\t\t\t\t\tonclick={closeSheet}\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</header>\n\n\t\t\t\t<div class=\"px-4 pb-2\">\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"search\"\n\t\t\t\t\t\tbind:value={search}\n\t\t\t\t\t\tplaceholder={t('search people you follow…')}\n\t\t\t\t\t\tclass=\"block w-full rounded-lg border border-border bg-surface px-3 py-2 text-sm text-text placeholder:text-muted/40 focus:border-accent focus:ring-0 focus:outline-none\"\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"min-h-0 flex-1 overflow-y-auto px-2 pb-[calc(0.75rem+env(safe-area-inset-bottom,0px))]\">\n\t\t\t\t\t{#if loading}\n\t\t\t\t\t\t<p class=\"px-2 py-3 text-xs text-muted\">{t('loading…')}</p>\n\t\t\t\t\t{:else if filtered.length === 0}\n\t\t\t\t\t\t<p class=\"px-2 py-3 text-xs text-muted\">\n\t\t\t\t\t\t\t{candidates.length === 0\n\t\t\t\t\t\t\t\t? t(\"you don't follow anyone yet.\")\n\t\t\t\t\t\t\t\t: t('nobody matches that search.')}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t{:else}\n\t\t\t\t\t\t{#each filtered as c (c.userId)}\n\t\t\t\t\t\t\t{@const placedTier = tierByUserId.get(c.userId)}\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"flex w-full items-center gap-3 rounded-xl px-2 py-2 text-left transition-colors hover:bg-surface\"\n\t\t\t\t\t\t\t\tonclick={() => toggleInTier(c.userId, currentTier)}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<DuelAvatar\n\t\t\t\t\t\t\t\t\tnickname={c.nickname}\n\t\t\t\t\t\t\t\t\tavatarUrl={getAvatarUrl(c.avatarPath)}\n\t\t\t\t\t\t\t\t\tsize={36}\n\t\t\t\t\t\t\t\t\thref=\"\"\n\t\t\t\t\t\t\t\t\tlink={false}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t<span class=\"min-w-0 flex-1 truncate text-sm font-semibold text-text\"\n\t\t\t\t\t\t\t\t\t>{c.nickname}</span\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{#if placedTier === currentTier}\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"flex h-6 w-6 items-center justify-center rounded-full bg-accent text-bg\"\n\t\t\t\t\t\t\t\t\t\taria-label={t('in this tier — tap to remove')}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<svg viewBox=\"0 0 24 24\" class=\"h-3.5 w-3.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n\t\t\t\t\t\t\t\t\t\t\t<path d=\"M5 13l4 4L19 7\" />\n\t\t\t\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t{:else if placedTier}\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"flex h-6 w-6 items-center justify-center rounded-md {tierCls(placedTier)} font-display text-xs font-bold text-bg\"\n\t\t\t\t\t\t\t\t\t\taria-label={t('currently in {tier} tier — tap to move here', { tier: placedTier })}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{placedTier}\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"flex h-6 w-6 items-center justify-center rounded-full border border-border text-muted/60\"\n\t\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t+\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t{/each}\n\t\t\t\t\t{/if}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t{/if}\n</div>\n","<script lang=\"ts\">\n\timport { t } from '$lib/i18n';\n\timport { tick } from 'svelte';\n\timport { invalidateAll } from '$app/navigation';\n\timport { page } from '$app/state';\n\timport DuelAvatar from '$lib/components/duel/DuelAvatar.svelte';\n\timport MentionAutocomplete from '$lib/components/chat/MentionAutocomplete.svelte';\n\timport {\n\t\tmentionQueryAtCaret,\n\t\tspliceMention,\n\t\tloadMentionCandidates,\n\t\ttype MentionCandidate\n\t} from '$lib/mention-typeahead';\n\timport { getAvatarUrl } from '$lib/avatar';\n\timport { stripExifClient } from '$lib/utils/strip-exif-client';\n\timport { heicToJpeg, isHeic } from '$lib/utils/heic-to-jpeg';\n\timport { detachIfImage, isStaleFileError, pickFailure } from '$lib/utils/stale-file';\n\timport * as analytics from '$lib/analytics';\n\timport NichePicker from '$lib/components/post/NichePicker.svelte';\n\timport TierListComposerDialog from '$lib/components/post/TierListComposerDialog.svelte';\n\timport DuelFeatureNudge from '$lib/components/duel/DuelFeatureNudge.svelte';\n\timport { extractDuelCode } from '$lib/duel-feature';\n\timport type { NicheOption } from '$lib/types/niche';\n\n\t// RAT-269: optional niche context — when rendered on /n/[slug], the niche\n\t// id auto-tags the post so it surfaces in that niche's feed. When NOT set\n\t// (i.e. on /f home), the NichePicker lets the user pick per-post.\n\tinterface Props {\n\t\tnicheContext?: { id: string; slug: string; name: string };\n\t\t/** Clan mode: when set, the post is tagged to this clan (no niche picker). */\n\t\tclanContext?: { id: string; tag: string; name: string };\n\t\t/** Framed = rounded card on every breakpoint (the /f feed is edge-to-edge\n\t\t *  on mobile; padded surfaces like the clan feed want a rounded box). */\n\t\tframed?: boolean;\n\t\t/** RAT-272: deeplink intent. /f?compose=1 (driven by the bottom-nav\n\t\t *  + picker's \"post to feed\" entry) sets this true so the composer\n\t\t *  scrolls into view + focuses its textarea on mount. iOS Safari\n\t\t *  won't pop the on-screen keyboard from a programmatic focus that\n\t\t *  happens after a navigation (user activation is lost across the\n\t\t *  hop), but the scroll-and-cursor-ready state still saves the user\n\t\t *  one tap. */\n\t\tautofocus?: boolean;\n\t}\n\tlet { nicheContext, clanContext, autofocus = false, framed = false }: Props = $props();\n\n\t// RAT-270: NichePicker selection state — only used on /f home (when\n\t// nicheContext is not supplied). The pill renders in the bottom button row.\n\tlet pickerSelection = $state<NicheOption | null>(null);\n\t// Multi-niche: up to 2 extra tags beyond the primary. Two explicit slots\n\t// rather than an array — each renders its own bindable NichePicker pill,\n\t// and the second only appears once the first is filled.\n\tlet extraSelection1 = $state<NicheOption | null>(null);\n\tlet extraSelection2 = $state<NicheOption | null>(null);\n\n\tfunction pickExtra(slot: 1 | 2, n: NicheOption | null) {\n\t\tif (n) {\n\t\t\tconst chosen = [\n\t\t\t\tnicheContext?.id,\n\t\t\t\tpickerSelection?.id,\n\t\t\t\tslot === 1 ? extraSelection2?.id : extraSelection1?.id\n\t\t\t];\n\t\t\tif (chosen.includes(n.id)) {\n\t\t\t\t// bind:selected already wrote the dup into the slot — undo it.\n\t\t\t\tif (slot === 1) extraSelection1 = null;\n\t\t\t\telse extraSelection2 = null;\n\t\t\t\terror = t('already tagged in that niche');\n\t\t\t\treturn;\n\t\t\t}\n\t\t\terror = '';\n\t\t}\n\t\tif (slot === 1) extraSelection1 = n;\n\t\telse extraSelection2 = n;\n\t}\n\n\tlet caption = $state('');\n\tlet linkUrl = $state('');\n\tlet linkOpen = $state(false);\n\tlet file = $state<File | null>(null);\n\tlet filePreviewUrl = $state<string | null>(null);\n\t// Multi-pic: up to 3 extra photos beyond the cover (`file`). Images only —\n\t// picking a video replaces the whole selection.\n\tlet extraFiles = $state<{ file: File; previewUrl: string }[]>([]);\n\tconst MAX_IMAGES = 4;\n\tlet dragOver = $state(false);\n\tlet uploading = $state(false);\n\tlet progress = $state<string>('');\n\tlet error = $state('');\n\t// Duel-link nudge: a duel link in a post is redirected to the board (or reddit)\n\t// instead of being posted — same anti-spam intercept as the group chat.\n\tlet nudgeOpen = $state(false);\n\tlet nudgeCode = $state('');\n\t// Tier list composer dialog — separate posting path from the inline flow.\n\tlet tierlistOpen = $state(false);\n\tlet textareaEl: HTMLTextAreaElement | null = $state(null);\n\n\tconst ACCEPT_IMAGE = 'image/jpeg,image/png,image/webp';\n\tconst ACCEPT_IMAGE_PICKER = 'image/jpeg,image/png,image/webp,image/heic,image/heif,.heic,.heif';\n\t// RAT-269: include video/quicktime (.mov) for iPhone uploads.\n\tconst ACCEPT_VIDEO = 'video/mp4,video/webm,video/quicktime';\n\tconst MAX_IMAGE = 10 * 1024 * 1024;\n\tconst MAX_VIDEO = 200 * 1024 * 1024;\n\tconst MAX_VIDEO_DUR = 300;\n\n\tlet imageInput: HTMLInputElement | null = $state(null);\n\tlet videoInput: HTMLInputElement | null = $state(null);\n\n\tconst fileKind = $derived(file ? (file.type.startsWith('video/') ? 'video' : 'image') : null);\n\t// A niche is REQUIRED for feed posts (product call: every post should land\n\t// in a niche feed so it actually reaches people — most posters have thin\n\t// follower graphs, an untagged post is near-invisible). The old dead-end\n\t// (picker offered \"skip\" while this gate refused it) is fixed the other way\n\t// around: the composer's picker hides the skip affordance (allowSkip=false).\n\t// Clan posts are exempt — the clan is their posting context.\n\tconst hasContent = $derived(\n\t\t!!file || (linkOpen && linkUrl.trim().length > 0) || caption.trim().length > 0\n\t);\n\tconst hasNiche = $derived(!!nicheContext || !!pickerSelection || !!clanContext);\n\tconst submittable = $derived(!uploading && hasContent && hasNiche);\n\n\t// /f supplies viewerNickname/viewerAvatarPath; elsewhere (e.g. the clan feed)\n\t// fall back to the root layout's nickname/avatarPath so the avatar still shows.\n\tconst viewerNickname = $derived(\n\t\t(page.data.viewerNickname as string | null) ?? (page.data.nickname as string | null) ?? null\n\t);\n\tconst viewerAvatarPath = $derived(\n\t\t(page.data.viewerAvatarPath as string | null) ?? (page.data.avatarPath as string | null) ?? null\n\t);\n\n\tfunction reset() {\n\t\tcaption = '';\n\t\tlinkUrl = '';\n\t\tlinkOpen = false;\n\t\tclearFile();\n\t\tprogress = '';\n\t\terror = '';\n\t\t// RAT-270: clear niche pick on /f home reset (no-op on niche page,\n\t\t// where nicheContext is the locked source of truth).\n\t\tif (!nicheContext) pickerSelection = null;\n\t\textraSelection1 = null;\n\t\textraSelection2 = null;\n\t\tautosize();\n\t}\n\n\tfunction clearFile() {\n\t\tif (filePreviewUrl) URL.revokeObjectURL(filePreviewUrl);\n\t\tfilePreviewUrl = null;\n\t\tfile = null;\n\t\tfor (const x of extraFiles) URL.revokeObjectURL(x.previewUrl);\n\t\textraFiles = [];\n\t\tif (imageInput) imageInput.value = '';\n\t\tif (videoInput) videoInput.value = '';\n\t}\n\n\tfunction removeExtra(i: number) {\n\t\tURL.revokeObjectURL(extraFiles[i].previewUrl);\n\t\textraFiles = extraFiles.filter((_, idx) => idx !== i);\n\t}\n\n\t// RAT-272 / RAT-294 follow-up: when the composer is asked to grab focus\n\t// (autofocus=true, triggered by /f?compose=1 from the bottom-nav +\n\t// picker), focus the textarea once it's mounted. The feed page owns the\n\t// scroll-to-top — focusing here with preventScroll:true keeps the parent\n\t// in control instead of fighting it with our own scrollIntoView (which\n\t// previously parked the composer at the top and pushed live raters +\n\t// stories off-screen). Wrapped in a one-shot guard so SvelteKit re-\n\t// running this effect on invalidate doesn't re-focus mid-feed.\n\tlet autofocusFired = false;\n\t$effect(() => {\n\t\tif (!autofocus || autofocusFired || !textareaEl) return;\n\t\tautofocusFired = true;\n\t\t// rAF gives the layout a tick to settle (the StoryRail + recommended\n\t\t// rail may still be mounting) before the focus lands.\n\t\trequestAnimationFrame(() => {\n\t\t\ttextareaEl?.focus({ preventScroll: true });\n\t\t});\n\t});\n\n\tfunction autosize() {\n\t\tif (!textareaEl) return;\n\t\ttextareaEl.style.height = 'auto';\n\t\ttextareaEl.style.height = textareaEl.scrollHeight + 'px';\n\t}\n\n\t// @-mention typeahead on the caption (Telegram-style). Candidates =\n\t// viewer's followers, lazily loaded on the first `@`, cached page-wide.\n\tlet mentionOpen = $state(false);\n\tlet mentionQuery = $state('');\n\tlet mentionCandidates = $state<MentionCandidate[]>([]);\n\tlet mentionLoadKicked = false;\n\n\tfunction refreshMentionState() {\n\t\tconst q = mentionQueryAtCaret(caption, textareaEl);\n\t\tif (q === null) {\n\t\t\tmentionOpen = false;\n\t\t\treturn;\n\t\t}\n\t\tmentionQuery = q;\n\t\tmentionOpen = true;\n\t\tif (!mentionLoadKicked) {\n\t\t\tmentionLoadKicked = true;\n\t\t\tloadMentionCandidates().then((c) => (mentionCandidates = c));\n\t\t}\n\t}\n\n\tfunction pickMention(nickname: string) {\n\t\tconst r = spliceMention(caption, textareaEl, nickname);\n\t\tcaption = r.text;\n\t\tmentionOpen = false;\n\t\tautosize();\n\t\ttick().then(() => {\n\t\t\ttextareaEl?.focus();\n\t\t\ttextareaEl?.setSelectionRange(r.caret, r.caret);\n\t\t});\n\t}\n\n\tasync function handleFile(f: File) {\n\t\terror = '';\n\t\t// Read the bytes at pick time so the OS handle can't die while the user is\n\t\t// off in the login flow — photos only. This composer accepts video up to\n\t\t// 200 MB and any file at all reaches here before the allowlist below runs,\n\t\t// so an unguarded read would pull a mislabelled 2 GB file into memory just\n\t\t// to then reject it (see $lib/utils/stale-file). A file that can't be read\n\t\t// at all throws in these reads — said, not dropped (see pickFailure).\n\t\ttry {\n\t\t\tf = await detachIfImage(f);\n\t\t\t// HEIC pre-pass — convert before MIME validation so iPhone uploads land\n\t\t\t// as JPEG and the strict allowlist below stays narrow.\n\t\t\tif (await isHeic(f)) {\n\t\t\t\terror = t('converting heic photo…');\n\t\t\t\tf = await heicToJpeg(f);\n\t\t\t\terror = '';\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tconst fail = pickFailure(e);\n\t\t\tanalytics.trackUploadFail({ error: fail.error, context: 'feed_pick', stale: fail.stale });\n\t\t\terror = fail.message;\n\t\t\treturn;\n\t\t}\n\t\tconst isImage = ACCEPT_IMAGE.split(',').includes(f.type);\n\t\tconst isVideo = ACCEPT_VIDEO.split(',').includes(f.type);\n\t\tif (!isImage && !isVideo) {\n\t\t\terror = t('use jpeg/png/webp or mp4/webm');\n\t\t\treturn;\n\t\t}\n\t\tif (isImage && f.size > MAX_IMAGE) {\n\t\t\terror = t('image too large (10MB max)');\n\t\t\treturn;\n\t\t}\n\t\tif (isVideo && f.size > MAX_VIDEO) {\n\t\t\terror = t('video too large (200MB max)');\n\t\t\treturn;\n\t\t}\n\t\t// Multi-pic: an image picked while an image cover already exists appends\n\t\t// as an extra instead of replacing — up to 4 photos total. A video pick\n\t\t// still replaces the whole selection below.\n\t\tif (isImage && file && fileKind === 'image') {\n\t\t\tif (1 + extraFiles.length >= MAX_IMAGES) {\n\t\t\t\terror = t('up to {n} photos per post', { n: MAX_IMAGES });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\textraFiles = [...extraFiles, { file: f, previewUrl: URL.createObjectURL(f) }];\n\t\t\treturn;\n\t\t}\n\t\tlinkOpen = false;\n\t\tlinkUrl = '';\n\t\tclearFile();\n\t\tfile = f;\n\t\tfilePreviewUrl = URL.createObjectURL(f);\n\t}\n\n\tfunction pickImage() {\n\t\timageInput?.click();\n\t}\n\tfunction pickVideo() {\n\t\tvideoInput?.click();\n\t}\n\tfunction toggleLink() {\n\t\tif (file) clearFile();\n\t\tlinkOpen = !linkOpen;\n\t\tif (!linkOpen) linkUrl = '';\n\t}\n\n\tasync function onDrop(e: DragEvent) {\n\t\te.preventDefault();\n\t\tdragOver = false;\n\t\t// Sequential so the first file becomes the cover and the rest append.\n\t\tfor (const f of Array.from(e.dataTransfer?.files ?? [])) await handleFile(f);\n\t}\n\n\tasync function readImageDimensions(f: File): Promise<{ width: number; height: number } | null> {\n\t\treturn new Promise((resolve) => {\n\t\t\tconst url = URL.createObjectURL(f);\n\t\t\tconst img = new Image();\n\t\t\timg.onload = () => {\n\t\t\t\tURL.revokeObjectURL(url);\n\t\t\t\tresolve({ width: img.naturalWidth, height: img.naturalHeight });\n\t\t\t};\n\t\t\timg.onerror = () => {\n\t\t\t\tURL.revokeObjectURL(url);\n\t\t\t\tresolve(null);\n\t\t\t};\n\t\t\timg.src = url;\n\t\t});\n\t}\n\n\tasync function readVideoMeta(\n\t\tf: File\n\t): Promise<{ width: number; height: number; durationSec: number; posterBlob: Blob | null } | null> {\n\t\treturn new Promise((resolve) => {\n\t\t\tconst url = URL.createObjectURL(f);\n\t\t\tconst v = document.createElement('video');\n\t\t\tv.preload = 'metadata';\n\t\t\tv.muted = true;\n\t\t\tv.playsInline = true;\n\t\t\tv.src = url;\n\t\t\tv.onloadedmetadata = () => {\n\t\t\t\tv.currentTime = Math.min(0.1, v.duration / 2 || 0);\n\t\t\t};\n\t\t\tv.onseeked = () => {\n\t\t\t\tconst canvas = document.createElement('canvas');\n\t\t\t\tcanvas.width = v.videoWidth;\n\t\t\t\tcanvas.height = v.videoHeight;\n\t\t\t\tconst ctx = canvas.getContext('2d');\n\t\t\t\tif (ctx) ctx.drawImage(v, 0, 0, canvas.width, canvas.height);\n\t\t\t\tcanvas.toBlob(\n\t\t\t\t\t(b) => {\n\t\t\t\t\t\tURL.revokeObjectURL(url);\n\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\twidth: v.videoWidth,\n\t\t\t\t\t\t\theight: v.videoHeight,\n\t\t\t\t\t\t\tdurationSec: Math.round(v.duration),\n\t\t\t\t\t\t\tposterBlob: b\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t\t'image/webp',\n\t\t\t\t\t0.85\n\t\t\t\t);\n\t\t\t};\n\t\t\tv.onerror = () => {\n\t\t\t\tURL.revokeObjectURL(url);\n\t\t\t\tresolve(null);\n\t\t\t};\n\t\t});\n\t}\n\n\tasync function uploadToSigned(\n\t\tmimeType: string,\n\t\tsize: number,\n\t\tpurpose: 'media' | 'poster',\n\t\tbytes: Blob\n\t): Promise<string | null> {\n\t\tconst urlRes = await fetch('/api/post/upload-url', {\n\t\t\tmethod: 'POST',\n\t\t\theaders: { 'content-type': 'application/json' },\n\t\t\tbody: JSON.stringify({ mimeType, size, purpose })\n\t\t});\n\t\tif (!urlRes.ok) {\n\t\t\tconst j = await urlRes.json().catch(() => ({}));\n\t\t\terror = j.error ?? t('upload init failed');\n\t\t\tanalytics.trackUploadFail({\n\t\t\t\terror: j.error || `upload-url ${urlRes.status}`,\n\t\t\t\tcontext: 'feed',\n\t\t\t\tstale: false\n\t\t\t});\n\t\t\treturn null;\n\t\t}\n\t\tconst { path, signedUrl } = await urlRes.json();\n\t\tconst putRes = await fetch(signedUrl, {\n\t\t\tmethod: 'PUT',\n\t\t\theaders: { 'content-type': mimeType },\n\t\t\tbody: bytes\n\t\t});\n\t\tif (!putRes.ok) {\n\t\t\terror = t('upload failed');\n\t\t\tanalytics.trackUploadFail({ error: `put ${putRes.status}`, context: 'feed', stale: false });\n\t\t\treturn null;\n\t\t}\n\t\treturn path;\n\t}\n\n\tasync function submit() {\n\t\terror = '';\n\t\t// Duel link in the caption or the link field → intercept: pop the board\n\t\t// nudge, don't post it. Sharing duel links in the feed is the same\n\t\t// opponent-hunting spam we redirect onto the board.\n\t\tconst sharedCode = extractDuelCode(`${caption} ${linkOpen ? linkUrl : ''}`);\n\t\tif (sharedCode) {\n\t\t\tnudgeCode = sharedCode;\n\t\t\tnudgeOpen = true;\n\t\t\treturn;\n\t\t}\n\t\t// Concrete reason when only the niche is missing — the disabled button\n\t\t// gives no feedback on its own.\n\t\tif (!hasNiche && hasContent && !uploading) {\n\t\t\terror = t('pick a niche first');\n\t\t\treturn;\n\t\t}\n\t\tif (!submittable) return;\n\t\tuploading = true;\n\t\ttry {\n\t\t\tlet body: Record<string, unknown>;\n\t\t\tif (file && fileKind === 'image') {\n\t\t\t\tprogress = t('uploading image…');\n\t\t\t\tconst clean = await stripExifClient(file);\n\t\t\t\tconst dims = await readImageDimensions(clean);\n\t\t\t\tconst path = await uploadToSigned(clean.type, clean.size, 'media', clean);\n\t\t\t\tif (!path) return;\n\t\t\t\t// Multi-pic extras: same strip-exif + upload pipeline per photo.\n\t\t\t\tconst extraMedia: Record<string, unknown>[] = [];\n\t\t\t\tfor (let i = 0; i < extraFiles.length; i++) {\n\t\t\t\t\tprogress = t('uploading image {i}/{n}…', { i: i + 2, n: extraFiles.length + 1 });\n\t\t\t\t\tconst cleanX = await stripExifClient(extraFiles[i].file);\n\t\t\t\t\tconst dimsX = await readImageDimensions(cleanX);\n\t\t\t\t\tconst pathX = await uploadToSigned(cleanX.type, cleanX.size, 'media', cleanX);\n\t\t\t\t\tif (!pathX) return;\n\t\t\t\t\textraMedia.push({\n\t\t\t\t\t\tmediaPath: pathX,\n\t\t\t\t\t\tmediaMime: cleanX.type,\n\t\t\t\t\t\tmediaWidth: dimsX?.width,\n\t\t\t\t\t\tmediaHeight: dimsX?.height\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbody = {\n\t\t\t\t\tkind: 'image',\n\t\t\t\t\tmediaPath: path,\n\t\t\t\t\tmediaMime: clean.type,\n\t\t\t\t\tmediaWidth: dims?.width,\n\t\t\t\t\tmediaHeight: dims?.height,\n\t\t\t\t\tcaption,\n\t\t\t\t\t...(extraMedia.length > 0 ? { extraMedia } : {})\n\t\t\t\t};\n\t\t\t} else if (file && fileKind === 'video') {\n\t\t\t\tprogress = t('reading video…');\n\t\t\t\tconst meta = await readVideoMeta(file);\n\t\t\t\tif (meta && meta.durationSec > MAX_VIDEO_DUR) {\n\t\t\t\t\terror = t('video too long (5 min max)');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tprogress = t('uploading video…');\n\t\t\t\tconst mediaPath = await uploadToSigned(file.type, file.size, 'media', file);\n\t\t\t\tif (!mediaPath) return;\n\t\t\t\tlet posterPath: string | undefined;\n\t\t\t\tif (meta?.posterBlob) {\n\t\t\t\t\tprogress = t('uploading thumbnail…');\n\t\t\t\t\tconst p = await uploadToSigned('image/webp', meta.posterBlob.size, 'poster', meta.posterBlob);\n\t\t\t\t\tif (p) posterPath = p;\n\t\t\t\t}\n\t\t\t\tbody = {\n\t\t\t\t\tkind: 'video',\n\t\t\t\t\tmediaPath,\n\t\t\t\t\tmediaMime: file.type,\n\t\t\t\t\tmediaWidth: meta?.width,\n\t\t\t\t\tmediaHeight: meta?.height,\n\t\t\t\t\tdurationSec: meta?.durationSec,\n\t\t\t\t\tposterPath,\n\t\t\t\t\tcaption\n\t\t\t\t};\n\t\t\t} else if (linkOpen && linkUrl.trim()) {\n\t\t\t\tprogress = t('fetching link preview…');\n\t\t\t\tbody = { kind: 'link', url: linkUrl, caption };\n\t\t\t} else if (caption.trim()) {\n\t\t\t\tprogress = t('posting…');\n\t\t\t\tbody = { kind: 'text', caption };\n\t\t\t} else {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tprogress = progress || t('posting…');\n\t\t\t// RAT-269/270: niche tag — locked context (niche page) takes\n\t\t\t// priority; otherwise use the picker selection from /f home.\n\t\t\tif (nicheContext) body.nicheId = nicheContext.id;\n\t\t\telse if (pickerSelection) body.nicheId = pickerSelection.id;\n\t\t\t// Multi-niche extras ride alongside the primary; the server enforces\n\t\t\t// the 3-total cap + validates each id.\n\t\t\tconst extraIds = [extraSelection1, extraSelection2]\n\t\t\t\t.filter((n): n is NicheOption => !!n)\n\t\t\t\t.map((n) => n.id);\n\t\t\tif (extraIds.length > 0) body.extraNicheIds = extraIds;\n\t\t\tif (clanContext) body.clanId = clanContext.id;\n\t\t\tconst res = await fetch('/api/post/create', {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders: { 'content-type': 'application/json' },\n\t\t\t\tbody: JSON.stringify(body)\n\t\t\t});\n\t\t\tconst j = await res.json();\n\t\t\tif (!res.ok) {\n\t\t\t\terror = j.error ?? t('failed');\n\t\t\t\treturn;\n\t\t\t}\n\t\t\treset();\n\t\t\tawait invalidateAll();\n\t\t} catch (e) {\n\t\t\t// A thrown failure here is almost always a dead File handle surfacing\n\t\t\t// from stripExifClient / the media readers (detachFile makes this\n\t\t\t// near-impossible now, but keep it measurable + recoverable).\n\t\t\tconst stale = isStaleFileError(e);\n\t\t\tanalytics.trackUploadFail({\n\t\t\t\terror: e instanceof Error ? `${e.name}: ${e.message}` : String(e),\n\t\t\t\tcontext: 'feed',\n\t\t\t\tstale\n\t\t\t});\n\t\t\terror = stale ? t('that photo went stale — pick it again') : t('something broke — try again');\n\t\t} finally {\n\t\t\tuploading = false;\n\t\t\tprogress = '';\n\t\t}\n\t}\n</script>\n\n<!-- svelte-ignore a11y_no_static_element_interactions -->\n<section\n\tclass=\"overflow-hidden bg-surface transition-colors {framed\n\t\t? 'rounded-2xl border border-border'\n\t\t: 'border-b border-border sm:rounded-2xl sm:border'} {dragOver ? 'border-accent' : ''}\"\n\tondragover={(e) => {\n\t\te.preventDefault();\n\t\tdragOver = true;\n\t}}\n\tondragleave={() => (dragOver = false)}\n\tondrop={onDrop}\n>\n\t<div class=\"flex gap-3 px-4 pt-3.5 pb-2\">\n\t\t<div class=\"shrink-0\">\n\t\t\t<DuelAvatar\n\t\t\tnickname={viewerNickname}\n\t\t\tavatarUrl={getAvatarUrl(viewerAvatarPath)}\n\t\t\tsize={36}\n\t\t\thref=\"\"\n\t\t\tlink={false}\n\t\t\tvariant={viewerAvatarPath ? 'auto' : 'accent'}\n\t\t/>\n\t\t</div>\n\t\t<div class=\"min-w-0 flex-1\">\n\t\t\t<textarea\n\t\t\t\tbind:this={textareaEl}\n\t\t\t\tbind:value={caption}\n\t\t\t\toninput={() => {\n\t\t\t\t\tautosize();\n\t\t\t\t\trefreshMentionState();\n\t\t\t\t}}\n\t\t\t\tonkeyup={refreshMentionState}\n\t\t\t\tonclick={refreshMentionState}\n\t\t\t\tplaceholder={clanContext\n\t\t\t\t\t? t('post to {name}…', { name: clanContext.name })\n\t\t\t\t\t: nicheContext\n\t\t\t\t\t\t? t('post to /n/{slug}…', { slug: nicheContext.slug })\n\t\t\t\t\t\t: t(\"what's on your mind?\")}\n\t\t\t\trows=\"1\"\n\t\t\t\tmaxlength=\"2000\"\n\t\t\t\tdisabled={uploading}\n\t\t\t\tclass=\"block w-full resize-none border-0 bg-transparent p-0 text-[15px] leading-snug text-text shadow-none ring-0 outline-none placeholder:text-muted/60 focus:border-0 focus:ring-0 focus:outline-none disabled:opacity-50\"\n\t\t\t></textarea>\n\n\t\t\t{#if file && filePreviewUrl}\n\t\t\t\t<div class=\"relative mt-2 overflow-hidden rounded-xl border border-border bg-bg\">\n\t\t\t\t\t{#if fileKind === 'image'}\n\t\t\t\t\t\t<img src={filePreviewUrl} alt=\"\" class=\"block max-h-72 w-full object-contain\" />\n\t\t\t\t\t{:else}\n\t\t\t\t\t\t<!-- svelte-ignore a11y_media_has_caption -->\n\t\t\t\t\t\t<video src={filePreviewUrl} controls class=\"block max-h-72 w-full\"></video>\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={clearFile}\n\t\t\t\t\t\tclass=\"absolute top-2 right-2 rounded-full bg-black/70 px-2 py-0.5 text-xs font-semibold text-white hover:bg-black/90\"\n\t\t\t\t\t\taria-label={t('remove file')}\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</div>\n\t\t\t\t{#if fileKind === 'image' && extraFiles.length > 0}\n\t\t\t\t\t<!-- Multi-pic: extra photo thumbs, each removable. The image button\n\t\t\t\t\t\t (or another pick from the same multi-select) appends more. -->\n\t\t\t\t\t<div class=\"mt-2 flex flex-wrap items-center gap-2\">\n\t\t\t\t\t\t{#each extraFiles as x, i (x.previewUrl)}\n\t\t\t\t\t\t\t<div class=\"relative\">\n\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\tsrc={x.previewUrl}\n\t\t\t\t\t\t\t\t\talt=\"\"\n\t\t\t\t\t\t\t\t\tclass=\"h-16 w-16 rounded-lg border border-border object-cover\"\n\t\t\t\t\t\t\t\t/>\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={() => removeExtra(i)}\n\t\t\t\t\t\t\t\t\tclass=\"absolute -top-1.5 -right-1.5 flex h-5 w-5 items-center justify-center rounded-full bg-black/80 text-[11px] font-semibold text-white hover:bg-black\"\n\t\t\t\t\t\t\t\t\taria-label={t('remove photo')}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t×\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t{#if 1 + extraFiles.length < MAX_IMAGES}\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tonclick={pickImage}\n\t\t\t\t\t\t\t\tdisabled={uploading}\n\t\t\t\t\t\t\t\tclass=\"flex h-16 w-16 items-center justify-center rounded-lg border border-dashed border-border text-lg text-muted transition-colors hover:border-border-strong hover:text-text disabled:opacity-40\"\n\t\t\t\t\t\t\t\taria-label={t('add another photo')}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t+\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t{/if}\n\t\t\t\t\t</div>\n\t\t\t\t{/if}\n\t\t\t{/if}\n\n\t\t\t{#if linkOpen}\n\t\t\t\t<input\n\t\t\t\t\ttype=\"url\"\n\t\t\t\t\tbind:value={linkUrl}\n\t\t\t\t\tplaceholder={t('paste a url…')}\n\t\t\t\t\tdisabled={uploading}\n\t\t\t\t\tclass=\"mt-2 block w-full rounded-lg border border-border bg-bg px-3 py-1.5 text-sm text-text placeholder:text-muted/40 focus:border-accent focus:ring-0 focus:outline-none disabled:opacity-50\"\n\t\t\t\t/>\n\t\t\t{/if}\n\n\t\t</div>\n\t</div>\n\n\t<input\n\t\tbind:this={imageInput}\n\t\ttype=\"file\"\n\t\taccept={ACCEPT_IMAGE_PICKER}\n\t\tmultiple\n\t\tonchange={async (e) => {\n\t\t\t// Sequential so the first file becomes the cover and the rest append\n\t\t\t// as extras (handleFile caps at 4 total).\n\t\t\tfor (const f of Array.from(e.currentTarget.files ?? [])) await handleFile(f);\n\t\t}}\n\t\tclass=\"hidden\"\n\t/>\n\t<input\n\t\tbind:this={videoInput}\n\t\ttype=\"file\"\n\t\taccept={ACCEPT_VIDEO}\n\t\tonchange={(e) => {\n\t\t\tconst f = e.currentTarget.files?.[0];\n\t\t\tif (f) handleFile(f);\n\t\t}}\n\t\tclass=\"hidden\"\n\t/>\n\n\t<div class=\"flex flex-wrap items-center justify-between gap-2 border-border/60 px-3 py-2 sm:border-t\">\n\t\t<div class=\"flex flex-wrap items-center gap-1\">\n\t\t\t<!-- RAT-270: niche picker pill (only on /f home, not /n/[slug] where\n\t\t\t\t the niche is locked via nicheContext). Multi-niche: once a primary\n\t\t\t\t exists (picked here or locked via nicheContext), up to two \"+ add\"\n\t\t\t\t slots let the post reach 2-3 niche feeds at once. -->\n\t\t\t{#if !clanContext}\n\t\t\t\t{#if !nicheContext}\n\t\t\t\t\t<NichePicker\n\t\t\t\t\t\tbind:selected={pickerSelection}\n\t\t\t\t\t\tonSelect={(n) => {\n\t\t\t\t\t\t\tpickerSelection = n;\n\t\t\t\t\t\t\tif (n) error = '';\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tallowSkip={false}\n\t\t\t\t\t/>\n\t\t\t\t{/if}\n\t\t\t\t{#if nicheContext || pickerSelection}\n\t\t\t\t\t<NichePicker\n\t\t\t\t\t\tbind:selected={extraSelection1}\n\t\t\t\t\t\tonSelect={(n) => pickExtra(1, n)}\n\t\t\t\t\t\tallowSkip={false}\n\t\t\t\t\t\tplaceholder={t('+ add a niche')}\n\t\t\t\t\t/>\n\t\t\t\t{/if}\n\t\t\t\t{#if extraSelection1}\n\t\t\t\t\t<NichePicker\n\t\t\t\t\t\tbind:selected={extraSelection2}\n\t\t\t\t\t\tonSelect={(n) => pickExtra(2, n)}\n\t\t\t\t\t\tallowSkip={false}\n\t\t\t\t\t\tplaceholder={t('+ add a niche')}\n\t\t\t\t\t/>\n\t\t\t\t{/if}\n\t\t\t\t<span class=\"mx-1 h-4 w-px bg-border\"></span>\n\t\t\t{/if}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tonclick={pickImage}\n\t\t\t\tdisabled={uploading}\n\t\t\t\tclass=\"rounded-full p-1.5 text-muted transition-colors hover:bg-bg hover:text-accent disabled:opacity-40\"\n\t\t\t\taria-label={t('add image')}\n\t\t\t\ttitle={t('add image')}\n\t\t\t>\n\t\t\t\t<svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n\t\t\t\t\t<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" />\n\t\t\t\t\t<circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\" />\n\t\t\t\t\t<polyline points=\"21 15 16 10 5 21\" />\n\t\t\t\t</svg>\n\t\t\t</button>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tonclick={pickVideo}\n\t\t\t\tdisabled={uploading}\n\t\t\t\tclass=\"rounded-full p-1.5 text-muted transition-colors hover:bg-bg hover:text-accent disabled:opacity-40\"\n\t\t\t\taria-label={t('add video')}\n\t\t\t\ttitle={t('add video')}\n\t\t\t>\n\t\t\t\t<svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n\t\t\t\t\t<polygon points=\"23 7 16 12 23 17 23 7\" />\n\t\t\t\t\t<rect x=\"1\" y=\"5\" width=\"15\" height=\"14\" rx=\"2\" ry=\"2\" />\n\t\t\t\t</svg>\n\t\t\t</button>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tonclick={toggleLink}\n\t\t\t\tdisabled={uploading}\n\t\t\t\tclass=\"rounded-full p-1.5 transition-colors hover:bg-bg disabled:opacity-40 {linkOpen ? 'text-accent' : 'text-muted hover:text-accent'}\"\n\t\t\t\taria-label={t('add link')}\n\t\t\t\ttitle={t('add link')}\n\t\t\t>\n\t\t\t\t<svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n\t\t\t\t\t<path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\" />\n\t\t\t\t\t<path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\" />\n\t\t\t\t</svg>\n\t\t\t</button>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tonclick={() => (tierlistOpen = true)}\n\t\t\t\tdisabled={uploading}\n\t\t\t\tclass=\"relative rounded-full p-1.5 text-muted transition-colors hover:bg-bg hover:text-accent disabled:opacity-40\"\n\t\t\t\taria-label={t('create tier list')}\n\t\t\t\ttitle={t('create tier list')}\n\t\t\t>\n\t\t\t\t<svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n\t\t\t\t\t<rect x=\"3\" y=\"4\" width=\"4\" height=\"4\" rx=\"1\" />\n\t\t\t\t\t<path d=\"M11 6h10\" />\n\t\t\t\t\t<rect x=\"3\" y=\"14\" width=\"4\" height=\"4\" rx=\"1\" />\n\t\t\t\t\t<path d=\"M11 16h10\" />\n\t\t\t\t</svg>\n\t\t\t\t<span class=\"new-badge\" aria-hidden=\"true\">{t('NEW')}</span>\n\t\t\t</button>\n\t\t</div>\n\t\t<div class=\"flex items-center gap-3\">\n\t\t\t{#if progress}\n\t\t\t\t<span class=\"text-[11px] text-muted\">{progress}</span>\n\t\t\t{/if}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tonclick={submit}\n\t\t\t\tdisabled={uploading || !hasContent}\n\t\t\t\tclass=\"rounded-full bg-accent px-4 py-1 text-[13px] font-semibold text-bg transition-colors hover:bg-accent/85 disabled:cursor-not-allowed disabled:opacity-40 {hasContent && !hasNiche ? 'opacity-60' : ''}\"\n\t\t\t>\n\t\t\t\t{t('post')}\n\t\t\t</button>\n\t\t</div>\n\t</div>\n\t{#if error}\n\t\t<!-- Under the niche pill row: the \"pick a niche first\" guard (and any\n\t\t\t upload error) lands next to the control that fixes it. -->\n\t\t<p class=\"px-3 pb-2 text-xs text-red-400\">{error}</p>\n\t{/if}\n</section>\n\n{#if nudgeOpen}\n\t<DuelFeatureNudge code={nudgeCode} onclose={() => (nudgeOpen = false)} />\n{/if}\n\n<MentionAutocomplete\n\topen={mentionOpen}\n\tquery={mentionQuery}\n\tcandidates={mentionCandidates}\n\tanchor={textareaEl}\n\tonPick={pickMention}\n\tonClose={() => (mentionOpen = false)}\n/>\n\n{#if tierlistOpen}\n\t<TierListComposerDialog\n\t\t{nicheContext}\n\t\t{clanContext}\n\t\tonclose={() => (tierlistOpen = false)}\n\t\tonposted={async () => {\n\t\t\ttierlistOpen = false;\n\t\t\tawait invalidateAll();\n\t\t}}\n\t/>\n{/if}\n\n<style>\n\t/* Shimmering NEW badge on the tier list action. A moving highlight over a\n\t   solid accent pill — a filled block, not a glow (design rules: no neon). */\n\t.new-badge {\n\t\tposition: absolute;\n\t\ttop: -5px;\n\t\tright: -8px;\n\t\toverflow: hidden;\n\t\tborder-radius: 999px;\n\t\tbackground: var(--color-accent);\n\t\tpadding: 1px 5px;\n\t\tfont-size: 8px;\n\t\tfont-weight: 700;\n\t\tletter-spacing: 0.08em;\n\t\tcolor: white;\n\t\tpointer-events: none;\n\t}\n\t.new-badge::after {\n\t\tcontent: '';\n\t\tposition: absolute;\n\t\tinset: 0;\n\t\tbackground: linear-gradient(\n\t\t\t105deg,\n\t\t\ttransparent 30%,\n\t\t\trgba(255, 255, 255, 0.55) 50%,\n\t\t\ttransparent 70%\n\t\t);\n\t\ttransform: translateX(-100%);\n\t\tanimation: new-badge-shimmer 2.6s var(--ease-out-quart) infinite;\n\t}\n\t@keyframes new-badge-shimmer {\n\t\tto {\n\t\t\ttransform: translateX(100%);\n\t\t}\n\t}\n\t@media (prefers-reduced-motion: reduce) {\n\t\t.new-badge::after {\n\t\t\tanimation: none;\n\t\t}\n\t}\n</style>\n"],"version":3}