{"release_id":"01a1c502-4ad1-0000-ec62-adc54d3c69aa","chunk_id":"01a1c502-4d0e-74f1-a4f1-4436d76eb216","file":"85.CxThnDuy.mjs","ignoreList":[],"mappings":"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","names":["DUEL_SHARE_TEXTS","pickDuelShareText","format","copied","$.state","copyInFlight","shareInFlight","showFallback","showCommunityModal","CommunityModal","openCommunityModal","$.get","mod","$.set","utmSource","url","hasNativeShare","fallbackText","waUrl","tgUrl","xUrl","copyLink","analytics.trackDuelLinkShared","$$props","shareOther","t","err","div","$.first_child","fragment","button","$.child","span","$.sibling","$.template_effect","$0","$.set_text","text","text_1","$$render","consequent","alternate","$.reset","div_1","button_1","span_1","button_2","span_2","div_2","root_3","a","a_1","a_2","$.set_attribute","$.delegated","consequent_1","CommunityModal_1","$$anchor","consequent_2","winner","$.derived","winnerName","dims","cd","i","ed","cScore","eScore","cDimsWon","d","eDimsWon","cRank","eRank","cPotential","ePotential","cVerdict","eVerdict","cTips","eTips","fragment_1","p","p_1","root_2","p_2","p_3","span_3","root_4","span_4","root_5","text_3","consequent_3","div_3","h2","span_5","text_6","p_4","div_4","dim","div_5","root_6","div_6","div_7","div_8","span_6","span_7","root_7","span_8","root_8","span_9","root_9","text_12","consequent_5","div_9","span_10","div_10","div_11","div_12","span_11","div_13","root_10","p_5","p_6","consequent_6","text_9","consequent_7","div_14","root_11","h2_1","span_12","fragment_2","span_13","text_18","span_14","text_20","consequent_8","alternate_1","p_7","consequent_9","alternate_2","div_15","div_16","root_16","diff","div_17","root_17","div_18","span_15","span_16","root_18","span_17","root_19","span_18","root_20","text_28","consequent_11","alternate_3","p_8","text_25","text_29","consequent_12","div_19","root_21","h2_2","span_19","text_30","p_9","div_20","div_21","root_22","p_10","div_22","sanitizeVerdict","div_23","span_20","root_23","strong","text_34","consequent_14","span_21","root_24","strong_1","text_36","consequent_15","text_33","consequent_16","div_24","root_25","p_11","div_25","div_26","span_22","root_26","strong_2","text_39","consequent_17","span_23","root_27","strong_3","text_41","consequent_18","text_38","consequent_19","consequent_20","div_27","root_28","h2_3","span_24","text_43","p_12","div_28","div_29","root_29","p_13","$.each","node_21","tip","div_30","root_30","span_25","div_31","p_14","p_15","span_26","text_47","text_48","text_49","text_50","consequent_21","div_32","root_31","p_16","node_23","div_33","root_32","span_27","div_34","p_17","p_18","span_28","text_52","text_53","text_54","text_55","consequent_22","consequent_23","fmtSize","bytes","root_1","label","input","e","label_1","input_1","classes","$.set_class","$.event","$.append","challengerOnline","opponentOnline","spectatorCount","challengerLabel","opponentLabel","root","classes_1","challengerAvatarUrl","entryAvatarUrl","bothScored","scoreDiff","animatedC","animatedE","onMount","startAt","rafId","easeOutCubic","tick","ts","eased","cName","eName","broken","SvelteSet","onImgError","article","img","node","DuelAvatar","node_1","node_2","text_5","consequent_4","article_1","img_1","d_1","text_10","node_5","node_6","root_12","root_13","node_7","root_14","alternate_6","alternate_7","node_10","text_17","node_11","part","consequent_10","text_23","alternate_8","emojis","$.prop","chatOpen","emojiOpen","rotatingEmojiIdx","draft","submitting","inlineError","listEl","inputEl","emojiTriggerEl","emojiPopoverEl","reactCooldownUntil","toast","toastTimer","unreadInBg","lastSeenId","pendingSelfSkips","originalTitle","audioCtx","NOTIFY_GRACE_MS","mountedAt","MAX_LEN","MAX_INPUT_HEIGHT","MAX_RECORDING_SEC","recording","recordingStartedAt","recordingDuration","recordingTimer","recorder","recorderStream","recorderChunks","recorderMime","voiceUploading","voiceError","voiceErrorTimer","playingVoiceId","playingProgress","voiceAudioEl","pickRecorderMime","candidates","c","flashVoiceError","msg","teardownRecording","track","startRecording","canRecord","pick","secs","stopAndSend","cancelRecording","dur","r","onStop","blob","succeeded","result","trackDuelChatComment","togglePlayVoice","handleVoiceTimeUpdate","handleVoiceEnded","handleVoicePause","fmtRecDuration","total","m","s","fmtVoiceDuration","canComment","lockedLabel","remaining","overLimit","canSubmit","sendComment","body","sendReact","now","trackDuelChatReact","$.user_effect","handleKey","toggleEmojiPicker","next","trackDuelEmojiPickerOpen","onPointerDown","ev","onKey","fmtTime","iso","layout","id","seed","left","drift","delay","scale","playPing","ctx","osc","gain","flashTitle","count","restoreTitle","startToastDismissTimer","showToast","preview","dismissToast","openFromToast","notifyIncoming","onVisibility","lastCmt","seenIdx","newOnes","l","$.set_style","aside","text_4","node_4","isPlaying","svg","svg_1","text_8","$$value","$1","slide","cubicOut","text_11","node_9","button_3","button_4","$2","fragment_3","button_5","text_14","fade","node_12","button_6","form","textarea","$.remove_textarea_child","node_14","classes_3","button_7","button_8","node_16","svg_2","consequent_13","alternate_4","classes_4","button_9","node_15","node_17","classes_2","classes_5","alternate_5","audio","REACTION_COOLDOWN_MS","createDuelChannel","supabase","code","self","duelId","handlers","channelName","existing","channel","joinedAt","lastReactionAt","subscribed","state","list","key","meta","payload","status","healthy","broadcastReaction","emoji","reaction","broadcastComment","comment","destroy","reportOpen","createSupabaseBrowserClient","activeMode","onDestroy","notFound","corrupted","duel","entries","isChallenger","hasSession","sentTo","$.proxy","sendToChat","threadId","res","claimTried","page","clean","replaceState","invalidateAll","featurePromptOpen","isFeatured","targeting","targeted","viewerBlocked","viewerAmbiguous","firstEntry","challengerProcessing","teamSize","teamA","rows","aEntries","x","y","bySlot","teamB","bEntries","entryId","$.user_pre_effect","joinStep","selectedFile","savePhoto","dragOver","email","emailError","emailSending","otpCode","otpError","otpVerifying","otpCooldown","otpResendCount","cooldownInterval","submitError","uploadedImagePath","oauthResumeIncoming","clearOauthResumeFlag","expiryMs","target","expH","expM","expS","expUrgent","pad","n","lightboxImage","presences","activeReactions","comments","channelHandle","finalizeInFlight","pollInterval","analysisTimedOut","retrying","params","refCode","beacon","k","v","selfRole","selfNickname","cb","fetchAndMergeComments","commentPollInterval","stopStatusPoll","viewPollInterval","server","seen","localOnly","b","submitComment","submitVoice","durationSec","fd","opponentPresenceState","challengerPresenceState","watcherCount","myEntry","view","isLiveView","goBack","goto","CHAT_POST_REVEAL_MS","nowMs","revealedAtMs","chatExpired","showDock","loaderView","html","prevHtml","prevBody","duelFocusMode","terminalViews","shouldPoll","onCountdownComplete","MAX_IMAGE_BYTES","MAX_DIMENSION","startOtpCooldown","seconds","compressImage","file","resolve","w","h","canvas","quality","handleFile","rasterized","heicToJpeg","fail","pickFailure","analytics.trackUploadFail","openJoinPicker","goToEmailStep","openAuthSheet","useSavedPhotoJoin","uploadImage","path","error","uploadSubmissionPhoto","callAction","action","fields","response","deserialize","submitDirectly","imagePath","startProcessing","resumeKey","prepareOAuthRedirect","saveResume","submitEmail","resendOtp","verifyOtp","analytics.trackSignInComplete","ANALYSIS_HARD_TIMEOUT_MS","retryAnalysis","startedAt","hiddenMs","hiddenSince","elapsedVisible","endPoll","ticks","consecutiveFailures","analytics.trackAnalysisFail","sessionKey","isFirstVisit","analytics.trackDuelLinkVisited","resume","consumeResume","fo","analytics.trackPostDuelFollowCtaShown","waitlistEmail","waitlistSubmitting","waitlistDone","waitlistError","submitWaitlist","resultShareCopied","copyResultLink","shareImageInFlight","shareImageStatus","shareImageUrl","prewarmFired","showResultCommunityModal","ResultCommunityModal","openResultCommunityModal","analytics.trackDuelCommunityModalOpen","resultShareUrl","resultPostTitle","teamAScores","teamBScores","aAvg","bAvg","shouldTryNativeFileShare","shareImage","filename","analytics.trackDuelImageShared","objUrl","main","_","angle","dist","text_2","h1","h1_1","node_3","h1_2","roster","ul","li","getAvatarUrl","text_15","text_16","UserBadge","node_8","a_3","root_15","AnalyzingProgress","fragment_5","PresenceBar","node_13","h1_3","fragment_11","text_27","text_31","text_32","a_4","text_35","st","root_33","root_34","h1_4","fragment_12","text_40","h1_5","fragment_13","h1_6","fragment_14","text_46","consequent_25","node_26","root_40","p_19","root_41","consequent_26","p_20","root_42","a_5","p_21","root_43","consequent_27","consequent_28","consequent_24","p_22","root_44","text_56","consequent_29","ShareLink","node_30","root_45","text_57","consequent_30","root_46","node_33","a_6","root_47","text_58","p_23","root_48","text_59","consequent_31","node_35","p_24","a_7","root_49","text_61","p_25","root_50","text_62","p_26","root_51","text_63","consequent_32","consequent_33","consequent_34","p_27","text_64","text_65","text_66","text_67","consequent_35","consequent_36","consequent_37","alternate_9","node_39","text_60","root_57","div_35","node_40","row","div_36","root_59","node_42","div_37","a_8","root_60","text_69","p_28","root_61","text_70","consequent_39","alternate_10","p_29","node_43","text_71","div_38","root_62","node_44","div_39","a_9","root_63","p_30","root_64","text_73","consequent_41","alternate_11","p_31","node_45","text_74","text_75","text_76","text_77","consequent_42","consequent_43","consequent_44","alternate_12","div_40","root_69","node_47","div_41","p_32","p_33","consequent_45","alternate_13","div_42","node_48","div_43","root_71","div_44","a_10","root_72","p_34","root_73","text_82","consequent_46","alternate_14","p_35","node_50","text_83","text_84","text_85","text_86","consequent_47","consequent_48","consequent_49","alternate_15","node_52","div_45","root_78","div_46","p_36","p_37","node_53","consequent_50","alternate_16","consequent_38","alternate_17","div_47","fragment_32","div_48","div_49","node_54","div_50","p_38","a_11","root_80","text_90","p_39","root_81","text_91","consequent_52","alternate_18","root_82","text_92","consequent_53","h1_7","text_93","text_95","text_97","consequent_55","alternate_19","div_51","root_86","div_52","p_40","root_87","$.index","root_89","text_100","consequent_56","p_41","root_90","span_29","root_92","text_102","consequent_58","p_42","root_93","span_30","root_95","text_104","consequent_60","consequent_59","alternate_20","p_43","root_96","span_31","root_98","text_106","consequent_62","consequent_61","alternate_21","div_53","root_99","div_54","span_32","span_33","text_108","consequent_63","div_55","root_100","div_56","span_34","text_110","consequent_64","div_57","div_58","root_101","a_12","text_111","a_13","text_112","div_59","fragment_40","duelJoinUpload","DuelUploadZone","ReusePhoto","node_67","div_60","root_104","root_105","text_113","root_106","text_114","consequent_66","alternate_22","consequent_67","p_44","root_107","consequent_68","consequent_65","alternate_23","div_61","span_35","span_36","text_116","div_62","root_108","span_37","text_118","p_45","div_63","OAuthButtonRow","node_71","div_64","$.remove_input_defaults","node_72","p_46","root_109","p_47","root_110","text_122","consequent_70","alternate_24","div_65","root_111","text_124","consequent_71","div_66","root_112","p_48","text_126","div_67","node_74","p_49","root_113","p_50","root_114","p_51","root_115","text_130","consequent_74","alternate_25","div_68","text_131","text_132","text_133","consequent_76","alternate_26","div_69","span_38","root_119","text_134","root_120","text_135","consequent_77","alternate_27","node_76","div_70","root_121","div_71","p_52","div_72","root_122","h2_4","span_39","text_139","p_53","consequent_80","alternate_28","button_10","text_143","button_11","text_144","div_73","root_125","div_74","node_79","div_75","SyncCountdown","node_80","p_54","span_40","text_145","text_146","cScoreNum","DuelFightArena","node_82","div_76","root_128","div_77","span_41","p_55","span_42","text_150","consequent_83","opponent","opponentAvatarPath","opponentHref","div_78","root_129","span_43","div_79","node_85","a_14","root_130","text_152","span_44","root_131","text_153","consequent_84","alternate_29","FollowButton","node_87","text_151","consequent_85","teamAEntries","teamBEntries","teamAAvg","teamBAvg","showPhotos","teamAMembersUI","teamBMembersUI","div_80","root_132","div_81","div_82","span_45","span_46","root_133","text_155","span_47","root_134","text_156","span_48","root_135","text_157","consequent_87","consequent_88","alternate_30","div_83","span_49","span_50","div_84","root_136","href","figure","root_137","button_12","root_138","div_85","root_139","node_91","consequent_89","alternate_31","figcaption","node_90","a_15","root_140","text_160","span_51","root_141","text_161","consequent_90","alternate_32","span_52","node_92","text_162","ul_1","root_142","li_1","root_143","node_93","a_16","root_144","text_163","span_53","root_145","text_164","consequent_92","alternate_33","span_54","node_94","text_165","consequent_91","alternate_34","div_86","div_87","span_55","span_56","root_146","text_167","span_57","root_147","text_168","span_58","root_148","text_169","consequent_93","consequent_94","alternate_35","div_88","span_59","span_60","div_89","root_149","figure_1","root_150","button_13","root_151","img_2","div_90","root_152","node_98","consequent_95","alternate_36","figcaption_1","node_97","a_17","root_153","text_172","span_61","root_154","text_173","consequent_96","alternate_37","span_62","node_99","text_174","ul_2","root_155","li_2","root_156","node_100","a_18","root_157","text_175","span_63","root_158","text_176","consequent_98","alternate_38","span_64","node_101","text_177","consequent_97","alternate_39","consequent_86","alternate_40","div_91","node_81","p_56","div_92","button_14","span_65","text_179","text_180","text_181","text_182","text_183","consequent_99","consequent_100","consequent_101","consequent_102","alternate_41","button_15","span_66","button_16","node_103","text_185","text_186","consequent_103","alternate_42","node_104","div_93","root_166","PostToFeedCta","node_105","consequent_104","div_94","root_167","p_57","a_19","div_95","p_58","p_59","a_20","text_190","analytics.trackCtaClick","consequent_105","div_96","root_168","p_60","div_97","root_169","div_98","p_61","p_62","button_17","text_194","a_21","root_170","text_195","consequent_106","consequent_107","a_22","node_108","div_99","p_63","p_64","div_100","a_23","a_24","consequent_108","div_101","root_171","h3","div_102","div_103","root_172","node_110","div_104","p_65","p_66","span_67","text_203","text_200","consequent_109","div_105","root_173","DuelResults","node_112","teamWinner","teamAMembers","teamBMembers","dimensionNames","teamADims","name","cDim","memberDims","allScores","avg","teamBDims","teamADimsWon","teamBDimsWon","teamADimFeedback","all","best","teamBDimFeedback","div_106","fragment_57","div_107","p_67","p_68","span_68","span_69","div_108","p_69","p_70","span_70","span_71","div_109","h2_5","span_72","text_210","p_71","div_110","aDim","bDim","dimWinner","aFb","bFb","div_111","root_176","div_112","div_113","div_114","span_73","span_74","root_177","text_214","span_75","root_178","text_215","span_76","root_179","text_216","consequent_111","consequent_112","alternate_43","div_115","span_77","div_116","div_117","div_118","span_78","div_119","root_180","div_120","p_72","root_181","text_219","consequent_113","p_73","node_116","div_121","p_74","root_182","text_221","consequent_114","p_75","node_117","text_220","text_222","consequent_115","text_213","consequent_116","div_122","root_183","h2_6","span_79","fragment_58","span_80","text_224","span_81","fragment_59","span_82","text_227","span_83","text_229","consequent_117","consequent_118","alternate_44","p_76","consequent_119","alternate_45","div_123","div_124","root_189","div_125","root_190","div_126","span_84","span_85","root_191","text_235","span_86","root_192","text_236","span_87","root_193","text_237","consequent_121","alternate_46","p_77","text_234","text_238","consequent_122","consequent_123","div_127","root_194","h2_7","span_88","text_239","p_78","div_128","div_129","p_79","div_130","div_131","root_196","div_132","p_80","span_89","div_133","$.html","div_134","span_90","root_197","text_245","consequent_124","span_91","root_198","text_247","consequent_125","text_243","consequent_126","div_135","p_81","div_136","div_137","root_200","div_138","p_82","span_92","div_139","div_140","span_93","root_201","text_252","consequent_127","span_94","root_202","strong_4","text_254","consequent_128","text_250","consequent_129","div_141","root_203","h2_8","span_95","text_256","p_83","div_142","div_143","p_84","div_144","div_145","root_205","p_85","div_146","root_206","span_96","div_147","p_86","p_87","span_97","text_261","text_262","text_263","text_264","text_260","consequent_131","div_148","p_88","div_149","div_150","root_208","p_89","div_151","root_209","span_98","div_152","p_90","p_91","span_99","text_267","text_268","text_269","text_270","text_266","consequent_132","consequent_110","consequent_134","div_153","root_210","p_92","div_154","a_25","text_272","a_26","text_273","div_155","root_211","p_93","a_27","div_156","p_94","p_95","div_157","a_28","a_29","consequent_135","alternate_47","div_158","root_212","h1_8","span_100","text_279","p_96","div_159","button_18","a_30","consequent_51","consequent_69","consequent_72","consequent_78","consequent_79","consequent_81","consequent_82","consequent_136","alternate_48","section","root_213","h2_9","span_101","text_284","p_97","div_160","root_214","text_287","div_161","fragment_67","input_2","button_19","text_288","p_98","root_216","consequent_138","consequent_137","alternate_49","consequent_139","div_162","root_217","button_20","text_290","consequent_140","ReportContentModal","consequent_141","button_21","root_219","img_3","consequent_142","DuelDock","consequent_143","DuelFeatureNudge","consequent_144","ResultCommunityModal_1","consequent_145"],"sources":["../../../../../../src/lib/duel-share-text.ts","../../../../../../src/lib/components/duel/ShareLink.svelte","../../../../../../src/lib/components/duel/DuelResults.svelte","../../../../../../src/lib/components/duel/DuelUploadZone.svelte","../../../../../../src/lib/components/duel/PresenceBar.svelte","../../../../../../src/lib/components/duel/DuelFightArena.svelte","../../../../../../src/lib/components/duel/DuelDock.svelte","../../../../../../src/lib/duelRealtime.ts","../../../../../../src/routes/d/[code]/+page.svelte"],"sourcesContent":["/**\n * Random share-message rotation for duel links.\n * Used by both `<ShareLink>` (form CTA) and `<DuelDock>` (floating peek).\n *\n * Voice: lowercase, punchy, dark-humor, gen-z. Each line is meant to be the\n * full message body sent to the recipient via navigator.share / clipboard.\n * Keep them short — most messaging apps clip preview around 60-100 chars.\n */\nexport const DUEL_SHARE_TEXTS: readonly string[] = [\n\t\"i went first. let's see what you've got.\",\n\t'AI ranked me. show me yours, see who scores higher.',\n\t\"made my move. your turn — let's settle this.\",\n\t\"i sealed mine. think you can top it? prove it.\",\n\t\"come show what you're working with. AI judges both.\",\n\t\"step up. one upload, ai decides who wins.\",\n\t\"i'm waiting. show up and we'll see who scores higher.\",\n\t\"settle the debate once and for all. AI ranks both.\",\n\t\"my score is locked in. yours next. let's go.\",\n\t\"come prove me wrong. ratemyd. is the judge.\",\n\t\"i went and got rated. now you. let's compare.\",\n\t'just got my score. wanna see how you stack up?',\n\t\"i did it. you up for it? AI scores both at once.\",\n\t\"locked in my rating. now show me yours.\"\n];\n\nexport function pickDuelShareText(): string {\n\treturn DUEL_SHARE_TEXTS[Math.floor(Math.random() * DUEL_SHARE_TEXTS.length)];\n}\n","<script lang=\"ts\">\n\timport { t } from '$lib/i18n';\n\timport * as analytics from '$lib/analytics';\n\timport { pickDuelShareText } from '$lib/duel-share-text';\n\n\tinterface Props {\n\t\tcode: string;\n\t\tisInviter: boolean;\n\t\tsharePosition: 'post_create' | 'duel_page' | 'result_page';\n\t\tformat?: '1v1' | '2v2' | '4v4';\n\t}\n\n\tlet { code, isInviter, sharePosition, format = '1v1' }: Props = $props();\n\n\tlet copied = $state(false);\n\tlet copyInFlight = $state(false);\n\tlet shareInFlight = $state(false);\n\tlet showFallback = $state(false);\n\tlet showCommunityModal = $state(false);\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tlet CommunityModal = $state<any>(null);\n\n\tasync function openCommunityModal() {\n\t\tif (!CommunityModal) {\n\t\t\tconst mod = await import('./ShareCommunityModal.svelte');\n\t\t\tCommunityModal = mod.default;\n\t\t}\n\t\tshowCommunityModal = true;\n\t}\n\n\t// Differentiate share source by format so PostHog can split inbound traffic\n\t// by 1v1 / 2v2 / 4v4 without joining back to the duel row.\n\tconst utmSource = $derived(format === '1v1' ? 'duel_share' : `duel_share_${format}`);\n\t// Use www host directly — apex (ratemyd.app) 307-redirects to www in prod, costing\n\t// every share open ~80–150ms. Tracking unaffected: query string + path identical.\n\tconst url = $derived(`https://www.ratemyd.app/d/${code}?utm_source=${utmSource}`);\n\tconst hasNativeShare = typeof navigator !== 'undefined' && typeof navigator.share === 'function';\n\n\tlet fallbackText = $state('');\n\tconst waUrl = $derived(`https://wa.me/?text=${encodeURIComponent(fallbackText + ' ' + url)}`);\n\tconst tgUrl = $derived(`https://t.me/share/url?url=${encodeURIComponent(url)}&text=${encodeURIComponent(fallbackText)}`);\n\tconst xUrl = $derived(`https://x.com/intent/tweet?text=${encodeURIComponent(fallbackText)}&url=${encodeURIComponent(url)}`);\n\n\tasync function copyLink() {\n\t\tif (copyInFlight) return;\n\t\tcopyInFlight = true;\n\t\ttry {\n\t\t\tawait navigator.clipboard.writeText(url);\n\t\t\tcopied = true;\n\t\t\tanalytics.trackDuelLinkShared(code, 'copy_link', isInviter, sharePosition);\n\t\t\tsetTimeout(() => (copied = false), 3000);\n\t\t} finally {\n\t\t\tcopyInFlight = false;\n\t\t}\n\t}\n\n\tasync function shareOther() {\n\t\tif (shareInFlight) return;\n\t\tshareInFlight = true;\n\t\ttry {\n\t\t\tif (hasNativeShare) {\n\t\t\t\ttry {\n\t\t\t\t\tawait navigator.share({ title: t('d*ck duel'), text: pickDuelShareText(), url });\n\t\t\t\t\tanalytics.trackDuelLinkShared(code, 'native_share', isInviter, sharePosition);\n\t\t\t\t\treturn;\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (err instanceof DOMException && err.name === 'AbortError') return;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!showFallback) fallbackText = pickDuelShareText();\n\t\t\tshowFallback = !showFallback;\n\t\t} finally {\n\t\t\tshareInFlight = false;\n\t\t}\n\t}\n</script>\n\n<div class=\"flex flex-col gap-2.5\">\n\t<!-- Primary CTA: copy link, dominant blue, full width above the secondaries. -->\n\t<button\n\t\tonclick={copyLink}\n\t\tdisabled={copyInFlight}\n\t\tclass=\"group relative w-full overflow-hidden rounded-xl bg-blue py-4 font-display text-base font-bold text-white transition-all hover:bg-blue/90 disabled:opacity-60\"\n\t>\n\t\t<span class=\"pointer-events-none absolute inset-0 -translate-x-full bg-gradient-to-r from-transparent via-white/20 to-transparent transition-transform duration-700 group-hover:translate-x-full\"></span>\n\t\t<span class=\"relative flex items-center justify-center gap-2.5\">\n\t\t\t{#if copied}\n\t\t\t\t<svg class=\"h-4 w-4 shrink-0\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2.5\"><polyline points=\"20 6 9 17 4 12\"/></svg>\n\t\t\t\t{t('copied — paste it now')}\n\t\t\t{:else}\n\t\t\t\t<svg class=\"h-4 w-4 shrink-0\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\"/><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"/></svg>\n\t\t\t\t{t('copy link')}\n\t\t\t{/if}\n\t\t</span>\n\t</button>\n\n\t<!-- Secondaries: where-to-post + share-other side-by-side, equal weight. -->\n\t<div class=\"grid grid-cols-2 gap-2\">\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tonclick={openCommunityModal}\n\t\t\tclass=\"rounded-xl border border-border px-3 py-3 font-display text-sm font-semibold text-text transition-all hover:border-muted hover:bg-white/[.03]\"\n\t\t>\n\t\t\t<span class=\"flex items-center justify-center gap-2\">\n\t\t\t\t<svg class=\"h-4 w-4 shrink-0\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 11l18-8-8 18-2-8-8-2z\"/></svg>\n\t\t\t\t{t('where to post')}\n\t\t\t</span>\n\t\t</button>\n\t\t<button\n\t\t\tonclick={shareOther}\n\t\t\tdisabled={shareInFlight}\n\t\t\tclass=\"rounded-xl border border-border px-3 py-3 font-display text-sm font-semibold text-text transition-all hover:border-muted hover:bg-white/[.03] disabled:opacity-60\"\n\t\t>\n\t\t\t<span class=\"flex items-center justify-center gap-2\">\n\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\"><circle cx=\"18\" cy=\"5\" r=\"3\"/><circle cx=\"6\" cy=\"12\" r=\"3\"/><circle cx=\"18\" cy=\"19\" r=\"3\"/><line x1=\"8.59\" y1=\"13.51\" x2=\"15.42\" y2=\"17.49\"/><line x1=\"15.41\" y1=\"6.51\" x2=\"8.59\" y2=\"10.49\"/></svg>\n\t\t\t\t{t('share other')}\n\t\t\t</span>\n\t\t</button>\n\t</div>\n\n\t{#if showFallback}\n\t\t<div class=\"flex gap-2\">\n\t\t\t<a href={waUrl} target=\"_blank\" rel=\"noopener noreferrer\"\n\t\t\t\tclass=\"flex-1 rounded-lg border border-border py-2.5 text-center font-display text-xs font-bold text-muted no-underline transition-all hover:border-muted hover:text-text\"\n\t\t\t\tonclick={() => analytics.trackDuelLinkShared(code, 'whatsapp', isInviter, sharePosition)}\n\t\t\t>WhatsApp</a>\n\t\t\t<a href={tgUrl} target=\"_blank\" rel=\"noopener noreferrer\"\n\t\t\t\tclass=\"flex-1 rounded-lg border border-border py-2.5 text-center font-display text-xs font-bold text-muted no-underline transition-all hover:border-muted hover:text-text\"\n\t\t\t\tonclick={() => analytics.trackDuelLinkShared(code, 'telegram', isInviter, sharePosition)}\n\t\t\t>Telegram</a>\n\t\t\t<a href={xUrl} target=\"_blank\" rel=\"noopener noreferrer\"\n\t\t\t\tclass=\"flex-1 rounded-lg border border-border py-2.5 text-center font-display text-xs font-bold text-muted no-underline transition-all hover:border-muted hover:text-text\"\n\t\t\t\tonclick={() => analytics.trackDuelLinkShared(code, 'x', isInviter, sharePosition)}\n\t\t\t>X</a>\n\t\t</div>\n\t{/if}\n</div>\n\n{#if showCommunityModal && CommunityModal}\n\t<CommunityModal\n\t\t{code}\n\t\t{url}\n\t\t{isInviter}\n\t\t{sharePosition}\n\t\tonclose={() => (showCommunityModal = false)}\n\t/>\n{/if}\n","<script lang=\"ts\">\n\timport { t } from '$lib/i18n';\n\timport type { AnalysisResults } from '$lib/types/generation';\n\timport type { DuelComparison } from '$lib/types/duel';\n\timport { sanitizeVerdict } from '$lib/utils/sanitize-verdict';\n\n\tinterface Props {\n\t\tchallengerScore: number;\n\t\tchallengerResults: AnalysisResults;\n\t\tchallengerNickname: string | null;\n\t\tentryScore: number;\n\t\tentryResults: AnalysisResults | null;\n\t\tentryNickname: string | null;\n\t\tmode: 'roast' | 'hype';\n\t\tcomparison: DuelComparison | null;\n\t}\n\n\tlet {\n\t\tchallengerScore, challengerResults, challengerNickname,\n\t\tentryScore, entryResults, entryNickname, mode, comparison\n\t}: Props = $props();\n\n\tconst winner = $derived<'challenger' | 'entry' | 'tie'>(\n\t\tchallengerScore > entryScore ? 'challenger' : entryScore > challengerScore ? 'entry' : 'tie'\n\t);\n\tconst scoreDiff = $derived(Math.abs(challengerScore - entryScore).toFixed(1));\n\tconst winnerName = $derived(\n\t\twinner === 'challenger' ? (challengerNickname || t('challenger'))\n\t\t\t: winner === 'entry' ? (entryNickname || t('contender'))\n\t\t\t: null\n\t);\n\n\tconst dims = $derived(\n\t\t(challengerResults?.dimensions ?? []).map((cd, i) => {\n\t\t\tconst ed = entryResults?.dimensions?.[i];\n\t\t\tconst cScore = cd.score;\n\t\t\tconst eScore = ed?.score ?? 0;\n\t\t\treturn {\n\t\t\t\tname: cd.name, color: cd.color,\n\t\t\t\tchallenger: { score: cScore, feedback: cd.feedback ?? '' },\n\t\t\t\tentry: { score: eScore, feedback: ed?.feedback ?? '' },\n\t\t\t\tdimWinner: cScore > eScore ? 'challenger' as const : eScore > cScore ? 'entry' as const : 'tie' as const,\n\t\t\t\tdiff: +(Math.abs(cScore - eScore).toFixed(1))\n\t\t\t};\n\t\t})\n\t);\n\n\tconst cDimsWon = $derived(dims.filter(d => d.dimWinner === 'challenger').length);\n\tconst eDimsWon = $derived(dims.filter(d => d.dimWinner === 'entry').length);\n\tconst cRank = $derived(challengerResults?.rank ?? '');\n\tconst eRank = $derived(entryResults?.rank ?? '');\n\tconst cPotential = $derived(challengerResults?.potential ?? 0);\n\tconst ePotential = $derived(entryResults?.potential ?? 0);\n\tconst cVerdict = $derived(challengerResults?.verdict ?? '');\n\tconst eVerdict = $derived(entryResults?.verdict ?? '');\n\tconst cTips = $derived(challengerResults?.tips ?? []);\n\tconst eTips = $derived(entryResults?.tips ?? []);\n</script>\n\n<!-- DIMENSION BREAKDOWN — same style as rate/result -->\n{#if dims.length > 0}\n\t<!-- dims-won strip sits just above the breakdown -->\n\t<div class=\"mb-10 flex flex-wrap items-center gap-8 border-b border-border pb-6\">\n\t\t<div>\n\t\t\t<p class=\"text-[10px] font-bold uppercase tracking-[0.2em] text-muted\">{t('dimensions won')}</p>\n\t\t\t<p class=\"mt-1 font-display text-2xl font-extrabold tabular-nums\">\n\t\t\t\t<span class=\"text-blue\">{cDimsWon}</span>\n\t\t\t\t<span class=\"text-muted/30 mx-1\">vs</span>\n\t\t\t\t<span class=\"text-coral\">{eDimsWon}</span>\n\t\t\t</p>\n\t\t</div>\n\t\t{#if cRank || eRank}\n\t\t\t<div>\n\t\t\t\t<p class=\"text-[10px] font-bold uppercase tracking-[0.2em] text-muted\">{t('ranks')}</p>\n\t\t\t\t<p class=\"mt-1 font-display text-sm font-bold\">\n\t\t\t\t\t{#if cRank}<span class=\"text-accent/80\">{cRank}</span>{/if}\n\t\t\t\t\t{#if cRank && eRank}<span class=\"text-muted/30 mx-1\">·</span>{/if}\n\t\t\t\t\t{#if eRank}<span class=\"text-accent/80\">{eRank}</span>{/if}\n\t\t\t\t</p>\n\t\t\t</div>\n\t\t{/if}\n\t</div>\n\n\t<div>\n\t\t<h2 class=\"font-display text-[clamp(1.8rem,5vw,3rem)] font-bold leading-[0.95] tracking-tighter\">\n\t\t\t{t('the full breakdown.')}<br /><span class=\"text-muted\">{t('{n} dimensions. head to head.', { n: dims.length })}</span>\n\t\t</h2>\n\t\t<p class=\"mt-3 mb-8 text-sm text-muted\">{t('every dimension compared. who won what.')}</p>\n\n\t\t<div class=\"flex flex-col\">\n\t\t\t{#each dims as dim (dim.name)}\n\t\t\t\t<div class=\"border-b border-border py-5 last:border-b-0\">\n\t\t\t\t\t<div class=\"mb-3 flex items-center justify-between\">\n\t\t\t\t\t\t<div class=\"flex items-center gap-2.5\">\n\t\t\t\t\t\t\t<div class=\"h-2.5 w-2.5 rounded-full\" style=\"background: {dim.color}\"></div>\n\t\t\t\t\t\t\t<span class=\"font-display text-sm font-semibold\">{dim.name}</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{#if dim.dimWinner === 'challenger'}\n\t\t\t\t\t\t\t<span class=\"text-[9px] font-bold uppercase text-muted/30\">{challengerNickname || t('challenger')} +{dim.diff.toFixed(1)}</span>\n\t\t\t\t\t\t{:else if dim.dimWinner === 'entry'}\n\t\t\t\t\t\t\t<span class=\"text-[9px] font-bold uppercase text-muted/30\">{entryNickname || t('contender')} +{dim.diff.toFixed(1)}</span>\n\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t<span class=\"text-[9px] font-bold uppercase text-muted/20\">{t('tied')}</span>\n\t\t\t\t\t\t{/if}\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"flex items-center gap-3\">\n\t\t\t\t\t\t<span class=\"w-8 text-right font-display text-sm font-bold tabular-nums\" style=\"color: {dim.color}\">{dim.challenger.score.toFixed(1)}</span>\n\t\t\t\t\t\t<div class=\"flex h-1.5 flex-1 gap-0.5 overflow-hidden rounded-full bg-border/30\">\n\t\t\t\t\t\t\t<div class=\"rounded-l-full transition-all duration-[1.5s]\" style=\"width: {dim.challenger.score * 10}%; background: {dim.color}; opacity: 0.5;\"></div>\n\t\t\t\t\t\t\t<div class=\"ml-auto rounded-r-full transition-all duration-[1.5s]\" style=\"width: {dim.entry.score * 10}%; background: {dim.color}; opacity: 0.3;\"></div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<span class=\"w-8 font-display text-sm font-bold tabular-nums\" style=\"color: {dim.color}; opacity: 0.6;\">{dim.entry.score.toFixed(1)}</span>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t{#if dim.challenger.feedback || dim.entry.feedback}\n\t\t\t\t\t\t<div class=\"mt-2 flex items-start justify-between gap-6\">\n\t\t\t\t\t\t\t<p class=\"max-w-[45%] text-[11px] leading-relaxed text-muted/40\">{dim.challenger.feedback}</p>\n\t\t\t\t\t\t\t<p class=\"max-w-[45%] text-right text-[11px] leading-relaxed text-muted/40\">{dim.entry.feedback}</p>\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{/each}\n\t\t</div>\n\t</div>\n{/if}\n\n<!-- WHY THE WINNER WON — AI head-to-head verdict (RAT-5) -->\n{#if comparison}\n\t<div class=\"mt-10\">\n\t\t<h2 class=\"font-display text-[clamp(1.8rem,5vw,3rem)] font-bold leading-[0.95] tracking-tighter\">\n\t\t\t{#if winnerName}\n\t\t\t\t<span class=\"text-coral\">{winnerName}</span> {t('ran the table.')}<br /><span class=\"text-muted\">{mode === 'roast' ? t('the autopsy.') : t('the play-by-play.')}</span>\n\t\t\t{:else}\n\t\t\t\t{t('the deadlock.')}<br /><span class=\"text-muted\">{t('nobody flinched.')}</span>\n\t\t\t{/if}\n\t\t</h2>\n\t\t<p class=\"mt-3 mb-8 text-sm text-muted\">\n\t\t\t{#if winnerName}\n\t\t\t\t{t('both photos. one frame. ai picked sides — no diplomacy.')}\n\t\t\t{:else}\n\t\t\t\t{t(\"ai studied both. couldn't pick. genuinely impressive.\")}\n\t\t\t{/if}\n\t\t</p>\n\n\t\t<div class=\"verdict-text text-[14px] leading-[1.8] text-text/70\" style=\"text-align: justify;\">{comparison.verdict}</div>\n\n\t\t{#if comparison.keyDifferences.length > 0}\n\t\t\t<div class=\"mt-8 flex flex-col\">\n\t\t\t\t{#each comparison.keyDifferences as diff (diff.dimension)}\n\t\t\t\t\t<div class=\"border-b border-border/40 py-4 last:border-b-0\">\n\t\t\t\t\t\t<div class=\"mb-1.5 flex items-center justify-between\">\n\t\t\t\t\t\t\t<span class=\"font-display text-sm font-semibold lowercase\">{diff.dimension}</span>\n\t\t\t\t\t\t\t{#if diff.favors === 'challenger'}\n\t\t\t\t\t\t\t\t<span class=\"text-[9px] font-bold uppercase tracking-[0.15em] text-blue/70\">{t('{name} edge', { name: challengerNickname || t('challenger') })}</span>\n\t\t\t\t\t\t\t{:else if diff.favors === 'entry'}\n\t\t\t\t\t\t\t\t<span class=\"text-[9px] font-bold uppercase tracking-[0.15em] text-coral/70\">{t('{name} edge', { name: entryNickname || t('contender') })}</span>\n\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t<span class=\"text-[9px] font-bold uppercase tracking-[0.15em] text-muted/40\">{t('tied')}</span>\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<p class=\"text-[12px] leading-relaxed text-muted/60\">{diff.reasoning}</p>\n\t\t\t\t\t</div>\n\t\t\t\t{/each}\n\t\t\t</div>\n\t\t{/if}\n\t</div>\n{/if}\n\n<!-- Post-duel follow CTA (RAT-27): moved to /d/[code]/+page.svelte right\n\t under the matchup so users actually see it. Was here under RAT-14 but\n\t buried below the dim breakdown — too far down to surface follow opportunity. -->\n\n<!-- VERDICTS — side by side, no card borders -->\n{#if cVerdict || eVerdict}\n\t<div class=\"mt-10\">\n\t\t<h2 class=\"font-display text-[clamp(1.8rem,5vw,3rem)] font-bold leading-[0.95] tracking-tighter\">\n\t\t\t{t('what the AI thinks.')}<br /><span class=\"text-muted\">{t('both sides.')}</span>\n\t\t</h2>\n\t\t<p class=\"mt-3 mb-8 text-sm text-muted\">{t('the unfiltered AI verdicts.')}</p>\n\n\t\t<div class=\"grid gap-10 md:grid-cols-2\">\n\t\t\t{#if cVerdict}\n\t\t\t\t<div>\n\t\t\t\t\t<p class=\"mb-3 text-[10px] font-semibold uppercase tracking-[0.15em] text-muted/30\">{challengerNickname || t('challenger')}</p>\n\t\t\t\t\t<div class=\"verdict-text text-[13px] leading-[1.8] text-text/60\" style=\"text-align: justify;\">{@html sanitizeVerdict(cVerdict)}</div>\n\t\t\t\t\t<div class=\"mt-4 flex flex-wrap items-center gap-4 border-t border-border/30 pt-3\">\n\t\t\t\t\t\t{#if cRank}<span class=\"text-[11px] text-muted/30\">{t('rank:')} <strong class=\"text-accent/50\">{cRank}</strong></span>{/if}\n\t\t\t\t\t\t{#if cPotential > challengerScore}<span class=\"text-[11px] text-muted/30\">{t('potential:')} <strong class=\"text-text/50\">{cPotential.toFixed(1)}</strong></span>{/if}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t{/if}\n\t\t\t{#if eVerdict}\n\t\t\t\t<div>\n\t\t\t\t\t<p class=\"mb-3 text-[10px] font-semibold uppercase tracking-[0.15em] text-muted/30\">{entryNickname || t('contender')}</p>\n\t\t\t\t\t<div class=\"verdict-text text-[13px] leading-[1.8] text-text/60\" style=\"text-align: justify;\">{@html sanitizeVerdict(eVerdict)}</div>\n\t\t\t\t\t<div class=\"mt-4 flex flex-wrap items-center gap-4 border-t border-border/30 pt-3\">\n\t\t\t\t\t\t{#if eRank}<span class=\"text-[11px] text-muted/30\">{t('rank:')} <strong class=\"text-accent/50\">{eRank}</strong></span>{/if}\n\t\t\t\t\t\t{#if ePotential > entryScore}<span class=\"text-[11px] text-muted/30\">{t('potential:')} <strong class=\"text-text/50\">{ePotential.toFixed(1)}</strong></span>{/if}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t{/if}\n\t\t</div>\n\t</div>\n{/if}\n\n<!-- TIPS -->\n{#if cTips.length > 0 || eTips.length > 0}\n\t<div class=\"mt-10\">\n\t\t<h2 class=\"font-display text-[clamp(1.8rem,5vw,3rem)] font-bold leading-[0.95] tracking-tighter\">\n\t\t\t{t('room for improvement.')}<br /><span class=\"text-muted\">{t('for both of you.')}</span>\n\t\t</h2>\n\t\t<p class=\"mt-3 mb-8 text-sm text-muted\">{t(\"the AI's recommendations.\")}</p>\n\n\t\t<div class=\"grid gap-10 md:grid-cols-2\">\n\t\t\t{#if cTips.length > 0}\n\t\t\t\t<div>\n\t\t\t\t\t<p class=\"mb-4 text-[10px] font-semibold uppercase tracking-[0.15em] text-muted/30\">{t(\"{name}'s tips\", { name: challengerNickname || t('challenger') })}</p>\n\t\t\t\t\t{#each cTips as tip (tip.num)}\n\t\t\t\t\t\t<div class=\"flex gap-3 border-b border-border/30 py-3 last:border-b-0\">\n\t\t\t\t\t\t\t<span class=\"shrink-0 pt-0.5 font-display text-[10px] font-bold text-muted/20\">{tip.num}</span>\n\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t<p class=\"text-[12px] font-semibold text-text/70\">{tip.title}</p>\n\t\t\t\t\t\t\t\t<p class=\"mt-0.5 text-[11px] leading-relaxed text-muted/40\">{tip.desc}</p>\n\t\t\t\t\t\t\t\t<span class=\"mt-1 inline-flex items-center gap-1 rounded bg-accent/[.08] px-1.5 py-0.5 text-[10px] font-semibold text-accent\">\n\t\t\t\t\t\t\t\t\t<svg class=\"h-2.5 w-2.5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"><polyline points=\"23,6 13.5,15.5 8.5,10.5 1,18\"/><polyline points=\"17,6 23,6 23,12\"/></svg>\n\t\t\t\t\t\t\t\t\t{tip.impact}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t{/each}\n\t\t\t\t</div>\n\t\t\t{/if}\n\t\t\t{#if eTips.length > 0}\n\t\t\t\t<div>\n\t\t\t\t\t<p class=\"mb-4 text-[10px] font-semibold uppercase tracking-[0.15em] text-muted/30\">{t(\"{name}'s tips\", { name: entryNickname || t('contender') })}</p>\n\t\t\t\t\t{#each eTips as tip (tip.num)}\n\t\t\t\t\t\t<div class=\"flex gap-3 border-b border-border/30 py-3 last:border-b-0\">\n\t\t\t\t\t\t\t<span class=\"shrink-0 pt-0.5 font-display text-[10px] font-bold text-muted/20\">{tip.num}</span>\n\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t<p class=\"text-[12px] font-semibold text-text/70\">{tip.title}</p>\n\t\t\t\t\t\t\t\t<p class=\"mt-0.5 text-[11px] leading-relaxed text-muted/40\">{tip.desc}</p>\n\t\t\t\t\t\t\t\t<span class=\"mt-1 inline-flex items-center gap-1 rounded bg-accent/[.08] px-1.5 py-0.5 text-[10px] font-semibold text-accent\">\n\t\t\t\t\t\t\t\t\t<svg class=\"h-2.5 w-2.5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"><polyline points=\"23,6 13.5,15.5 8.5,10.5 1,18\"/><polyline points=\"17,6 23,6 23,12\"/></svg>\n\t\t\t\t\t\t\t\t\t{tip.impact}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t{/each}\n\t\t\t\t</div>\n\t\t\t{/if}\n\t\t</div>\n\t</div>\n{/if}\n\n<style>\n\t.vs-glitch {\n\t\tposition: relative; display: inline-block;\n\t\tfont-weight: 900; letter-spacing: 0.1em; color: rgba(255,255,255,0.15);\n\t}\n\t.vs-glitch::before, .vs-glitch::after {\n\t\tcontent: attr(data-text); position: absolute; top: 0; left: 0; right: 0;\n\t\ttext-align: center; pointer-events: none;\n\t}\n\t.vs-glitch::before {\n\t\tcolor: var(--color-coral); opacity: 0;\n\t\tanimation: g1 3s ease-in-out infinite;\n\t\tclip-path: polygon(0 0, 100% 0, 100% 45%, 0 45%);\n\t}\n\t.vs-glitch::after {\n\t\tcolor: var(--color-blue); opacity: 0;\n\t\tanimation: g2 2.8s ease-in-out infinite;\n\t\tclip-path: polygon(0 55%, 100% 55%, 100% 100%, 0 100%);\n\t}\n\t@keyframes g1 {\n\t\t0%, 72%, 80%, 100% { transform: translate(0); opacity: 0; }\n\t\t74% { transform: translate(-3px, -1px); opacity: 0.8; }\n\t\t76% { transform: translate(2px, 1px); opacity: 0.9; }\n\t\t78% { transform: translate(-1px, 0); opacity: 0.6; }\n\t}\n\t@keyframes g2 {\n\t\t0%, 68%, 76%, 100% { transform: translate(0); opacity: 0; }\n\t\t70% { transform: translate(2px, 1px); opacity: 0.8; }\n\t\t72% { transform: translate(-2px, -1px); opacity: 0.9; }\n\t\t74% { transform: translate(1px, 0); opacity: 0.6; }\n\t}\n\n\t.verdict-text :global(strong) {\n\t\tcolor: var(--color-coral); font-weight: 600; position: relative; display: inline;\n\t\tbackground-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 12' preserveAspectRatio='none'%3E%3Cpath d='M1 8.5C30 4 60 6 100 5.5c40-.5 70 2.5 99 3' stroke='%23FF4D6D' stroke-width='3' fill='none' stroke-linecap='round' opacity='0.35'/%3E%3C/svg%3E\");\n\t\tbackground-repeat: no-repeat; background-size: 100% 0.35em; background-position: 0 88%; padding-bottom: 2px;\n\t}\n\t.verdict-text :global(.hype-strong) {\n\t\tcolor: var(--color-yellow); font-weight: 600; position: relative; display: inline;\n\t\tbackground-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 12' preserveAspectRatio='none'%3E%3Cpath d='M1 8.5C30 4 60 6 100 5.5c40-.5 70 2.5 99 3' stroke='%23FFE500' stroke-width='3' fill='none' stroke-linecap='round' opacity='0.35'/%3E%3C/svg%3E\");\n\t\tbackground-repeat: no-repeat; background-size: 100% 0.35em; background-position: 0 88%; padding-bottom: 2px;\n\t}\n</style>\n","<script lang=\"ts\">\n\timport { t } from '$lib/i18n';\n\tinterface Props {\n\t\tselectedFile: File | null;\n\t\tdragOver: boolean;\n\t\tonfile: (file: File | undefined) => void;\n\t\tonremove: () => void;\n\t}\n\n\tlet { selectedFile, dragOver, onfile, onremove }: Props = $props();\n\n\tfunction fmtSize(bytes: number): string {\n\t\tif (bytes < 1024) return `${bytes} B`;\n\t\tif (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)} KB`;\n\t\treturn `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n\t}\n</script>\n\n{#if selectedFile}\n\t<div class=\"selected\">\n\t\t<div class=\"left\">\n\t\t\t<span class=\"check\" aria-hidden=\"true\">\n\t\t\t\t<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.6\" 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</span>\n\t\t\t<div class=\"meta\">\n\t\t\t\t<p class=\"status\">{t('photo ready')}</p>\n\t\t\t\t<p class=\"filename\">{selectedFile.name}</p>\n\t\t\t\t<p class=\"size\">{t('{size} · ai-encrypted on upload', { size: fmtSize(selectedFile.size) })}</p>\n\t\t\t</div>\n\t\t</div>\n\t\t<label class=\"change\">\n\t\t\t<span>{t('change')}</span>\n\t\t\t<input\n\t\t\t\ttype=\"file\"\n\t\t\t\taccept=\"image/*\"\n\t\t\t\tclass=\"hidden\"\n\t\t\t\tonchange={(e) => { onremove(); onfile((e.target as HTMLInputElement).files?.[0]); }}\n\t\t\t/>\n\t\t</label>\n\t</div>\n{:else}\n\t<label\n\t\tclass=\"drop\"\n\t\tclass:drop--over={dragOver}\n\t\tondrop={(e) => { e.preventDefault(); onfile(e.dataTransfer?.files[0]); }}\n\t\tondragover={(e) => e.preventDefault()}\n\t\tondragenter={(e) => e.preventDefault()}\n\t>\n\t\t<!-- dashed-zone visual is desktop-only — drag & drop is a pointer paradigm.\n\t\t     on mobile the filled CTA button below is the whole affordance. -->\n\t\t<span class=\"zone-visual\">\n\t\t\t<span class=\"icon\" aria-hidden=\"true\">\n\t\t\t\t<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5\"/></svg>\n\t\t\t</span>\n\t\t\t<p class=\"drop-head\">{t('drag & drop your photo')}</p>\n\t\t</span>\n\t\t<span class=\"cta\">\n\t\t\t<svg class=\"cta-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n\t\t\t\t<path d=\"M12 16V4M6 10l6-6 6 6\"/>\n\t\t\t\t<path d=\"M4 16v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2\"/>\n\t\t\t</svg>\n\t\t\t{t('upload your photo')}\n\t\t</span>\n\t\t<p class=\"drop-sub\">{t('free · no signup to upload · jpg, png, webp · max 5mb')}</p>\n\t\t<input\n\t\t\ttype=\"file\"\n\t\t\taccept=\"image/*\"\n\t\t\tclass=\"hidden\"\n\t\t\tonchange={(e) => onfile((e.target as HTMLInputElement).files?.[0])}\n\t\t/>\n\t</label>\n{/if}\n\n<style>\n\t/* ─── drop target (empty state) ─── */\n\t.drop {\n\t\tposition: relative;\n\t\tdisplay: flex; flex-direction: column; align-items: center;\n\t\tcursor: pointer; text-align: center;\n\t}\n\t/* desktop-only dashed-zone visual */\n\t.zone-visual { display: none; }\n\t.drop .icon {\n\t\tdisplay: inline-flex; align-items: center; justify-content: center;\n\t\twidth: 44px; height: 44px; border-radius: 50%;\n\t\tbackground: rgba(59,130,246,0.08);\n\t\tcolor: var(--color-blue);\n\t\tmargin-bottom: 14px;\n\t}\n\t.drop .icon svg { width: 20px; height: 20px; }\n\t.drop-head {\n\t\tfont-family: var(--font-display); font-size: 15px; font-weight: 700;\n\t\tcolor: var(--color-text);\n\t}\n\t/* the filled CTA — the dominant affordance, the loudest thing on the page */\n\t.cta {\n\t\tdisplay: inline-flex; align-items: center; justify-content: center; gap: 9px;\n\t\twidth: 100%;\n\t\tpadding: 17px 26px;\n\t\tborder-radius: 16px;\n\t\tbackground: var(--color-blue);\n\t\tcolor: #fff;\n\t\tfont-family: var(--font-display);\n\t\tfont-size: 16px; font-weight: 700;\n\t\tbox-shadow: 0 8px 22px -6px rgba(0,0,0,0.5);\n\t\ttransition: background 0.18s, transform 0.06s;\n\t}\n\t.drop:hover .cta { background: #2563eb; }\n\t.drop:active .cta { transform: scale(0.99); }\n\t.cta-icon { width: 18px; height: 18px; }\n\t.drop-sub {\n\t\tmargin-top: 10px; font-size: 11px; color: var(--color-muted);\n\t}\n\n\t@media (min-width: 640px) {\n\t\t.drop {\n\t\t\tpadding: 40px 24px;\n\t\t\tborder: 1px dashed var(--color-border);\n\t\t\tborder-radius: 20px;\n\t\t\tbackground: linear-gradient(180deg, rgba(255,255,255,0.01), rgba(255,255,255,0));\n\t\t\ttransition: border-color 0.2s, background 0.2s;\n\t\t}\n\t\t.drop:hover {\n\t\t\tborder-color: rgba(255,255,255,0.15);\n\t\t\tbackground: linear-gradient(180deg, rgba(59,130,246,0.02), rgba(255,255,255,0));\n\t\t}\n\t\t.drop--over {\n\t\t\tborder-color: rgba(59,130,246,0.5);\n\t\t\tbackground: linear-gradient(180deg, rgba(59,130,246,0.05), rgba(59,130,246,0.01));\n\t\t}\n\t\t.zone-visual {\n\t\t\tdisplay: flex; flex-direction: column; align-items: center;\n\t\t\tmargin-bottom: 18px;\n\t\t}\n\t\t.cta { width: auto; }\n\t}\n\n\t/* ─── selected state (file chosen) ─── */\n\t.selected {\n\t\tdisplay: flex; align-items: center; justify-content: space-between;\n\t\tgap: 16px; padding: 16px 18px 16px 16px;\n\t\tborder: 1px solid rgba(59,130,246,0.3);\n\t\tborder-radius: 16px;\n\t\tbackground:\n\t\t\tlinear-gradient(135deg, rgba(59,130,246,0.08) 0%, rgba(59,130,246,0.02) 50%, transparent 100%),\n\t\t\trgba(255,255,255,0.01);\n\t\tbox-shadow:\n\t\t\t0 10px 30px -10px rgba(59,130,246,0.3),\n\t\t\t0 1px 0 rgba(255,255,255,0.04) inset;\n\t\tposition: relative; overflow: hidden;\n\t}\n\t.selected::before {\n\t\tcontent: '';\n\t\tposition: absolute; inset: 0; pointer-events: none;\n\t\tbackground: radial-gradient(ellipse 40% 100% at 0% 50%, rgba(59,130,246,0.15), transparent 70%);\n\t}\n\t.left {\n\t\tdisplay: flex; align-items: center; gap: 14px;\n\t\tmin-width: 0; position: relative; z-index: 1;\n\t}\n\t.check {\n\t\tdisplay: inline-flex; align-items: center; justify-content: center;\n\t\tflex-shrink: 0;\n\t\twidth: 40px; height: 40px; border-radius: 12px;\n\t\tbackground: linear-gradient(135deg, rgba(59,130,246,0.25), rgba(59,130,246,0.12));\n\t\tborder: 1px solid rgba(59,130,246,0.35);\n\t\tcolor: var(--color-blue);\n\t\tanimation: check-pop 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);\n\t}\n\t.check svg { width: 20px; height: 20px; }\n\t@keyframes check-pop {\n\t\t0% { transform: scale(0); opacity: 0; }\n\t\t60% { transform: scale(1.2); opacity: 1; }\n\t\t100% { transform: scale(1); opacity: 1; }\n\t}\n\t.meta { min-width: 0; }\n\t.status {\n\t\tfont-family: var(--font-display);\n\t\tfont-size: 10px; font-weight: 700;\n\t\ttext-transform: uppercase; letter-spacing: 0.22em;\n\t\tcolor: var(--color-blue);\n\t}\n\t.filename {\n\t\tmargin-top: 3px;\n\t\tfont-family: var(--font-display);\n\t\tfont-size: 14px; font-weight: 700;\n\t\tcolor: var(--color-text);\n\t\toverflow: hidden; text-overflow: ellipsis; white-space: nowrap;\n\t\tmax-width: 100%;\n\t}\n\t.size {\n\t\tmargin-top: 2px;\n\t\tfont-size: 11px; color: var(--color-muted); opacity: 0.7;\n\t}\n\t.change {\n\t\tposition: relative; z-index: 1;\n\t\tdisplay: inline-flex; align-items: center; gap: 6px;\n\t\tpadding: 9px 14px; border-radius: 10px;\n\t\tbackground: rgba(255,255,255,0.04);\n\t\tborder: 1px solid var(--color-border);\n\t\tcolor: var(--color-text);\n\t\tfont-family: var(--font-display);\n\t\tfont-size: 11px; font-weight: 700;\n\t\ttext-transform: uppercase; letter-spacing: 0.18em;\n\t\tcursor: pointer;\n\t\ttransition: background 0.2s, border-color 0.2s;\n\t\tflex-shrink: 0;\n\t}\n\t.change:hover {\n\t\tbackground: rgba(255,255,255,0.08);\n\t\tborder-color: rgba(255,255,255,0.15);\n\t}\n\t.change input { display: none; }\n\t.hidden { display: none; }\n</style>\n","<script lang=\"ts\">\n\timport { t } from '$lib/i18n';\n\timport type { DuelPresence } from '$lib/types/duel';\n\n\tinterface Props {\n\t\tpresences: DuelPresence[];\n\t\tchallengerNickname: string | null;\n\t\topponentNickname?: string | null;\n\t\tchallengerState: 'locked' | 'rating' | 'waiting';\n\t\topponentState: 'absent' | 'joined' | 'uploading' | 'rating' | 'ready';\n\t}\n\n\tlet { presences, challengerNickname, opponentNickname, challengerState, opponentState }: Props = $props();\n\n\tconst challengerOnline = $derived(presences.some((p) => p.role === 'challenger'));\n\tconst opponentOnline = $derived(presences.some((p) => p.role === 'opponent'));\n\tconst spectatorCount = $derived(presences.filter((p) => p.role === 'spectator').length);\n\n\tconst challengerLabel = $derived.by(() => {\n\t\tswitch (challengerState) {\n\t\t\tcase 'locked': return t('locked in');\n\t\t\tcase 'rating': return t('rating…');\n\t\t\tcase 'waiting': return t('waiting');\n\t\t}\n\t});\n\n\tconst opponentLabel = $derived.by(() => {\n\t\tswitch (opponentState) {\n\t\t\tcase 'absent': return t('not joined');\n\t\t\tcase 'joined': return t('joined');\n\t\t\tcase 'uploading': return t('uploading…');\n\t\t\tcase 'rating': return t('rating…');\n\t\t\tcase 'ready': return t('locked in');\n\t\t}\n\t});\n</script>\n\n<div class=\"presence-row\">\n\t<span class=\"presence\">\n\t\t<span class=\"live-dot\" class:live-dot--blue={challengerOnline} class:live-dot--muted={!challengerOnline}></span>\n\t\t<span class=\"text-text\">{challengerNickname ?? t('challenger')}</span>\n\t\t<span class=\"sep\">·</span>\n\t\t<span class=\"presence-state\">{challengerLabel}</span>\n\t</span>\n\t<span class=\"presence\">\n\t\t<span\n\t\t\tclass=\"live-dot\"\n\t\t\tclass:live-dot--coral={opponentOnline && opponentState !== 'absent'}\n\t\t\tclass:live-dot--muted={!opponentOnline || opponentState === 'absent'}\n\t\t></span>\n\t\t<span class=\"text-text\">{opponentNickname ?? t('opponent')}</span>\n\t\t<span class=\"sep\">·</span>\n\t\t<span class=\"presence-state\">{opponentLabel}</span>\n\t</span>\n\t<span class=\"presence presence--watching\">\n\t\t<span class=\"live-dot\"></span>\n\t\t<span>{t('{n} watching', { n: spectatorCount })}</span>\n\t</span>\n</div>\n\n<style>\n\t.presence-row {\n\t\tdisplay: flex; align-items: center; flex-wrap: nowrap;\n\t\tgap: 5px;\n\t}\n\t@media (min-width: 768px) {\n\t\t.presence-row { flex-wrap: wrap; gap: 12px 16px; }\n\t}\n\t.presence {\n\t\tdisplay: inline-flex; align-items: center; gap: 5px;\n\t\tpadding: 4px 9px; border-radius: 999px;\n\t\tborder: 1px solid var(--color-border);\n\t\tbackground: rgba(255,255,255,0.015);\n\t\tfont-size: 10px; font-weight: 600; letter-spacing: 0.01em;\n\t\tcolor: var(--color-text);\n\t\twhite-space: nowrap;\n\t}\n\t@media (min-width: 768px) {\n\t\t.presence {\n\t\t\tpadding: 7px 14px; gap: 10px;\n\t\t\tfont-size: 11px; letter-spacing: 0.02em;\n\t\t}\n\t}\n\t/* push watching to right edge on desktop, keep inline on mobile */\n\t@media (min-width: 640px) {\n\t\t.presence--watching { margin-left: auto; }\n\t}\n\t.presence-state {\n\t\tfont-family: var(--font-display);\n\t\ttext-transform: uppercase; letter-spacing: 0.08em;\n\t\tfont-size: 9px; color: var(--color-muted);\n\t}\n\t@media (min-width: 768px) {\n\t\t.presence-state { letter-spacing: 0.15em; font-size: 10px; }\n\t}\n\t.sep { color: var(--color-muted); opacity: 0.5; }\n\n\t.live-dot {\n\t\tdisplay: inline-block; width: 6px; height: 6px; border-radius: 50%;\n\t\tbackground: var(--color-green); box-shadow: 0 0 8px rgba(34,197,94,0.5);\n\t\tanimation: pulse-green 2.5s ease-in-out infinite;\n\t}\n\t.live-dot--blue {\n\t\tbackground: var(--color-blue); box-shadow: 0 0 8px rgba(59,130,246,0.5);\n\t\tanimation: pulse-blue 2.5s ease-in-out infinite;\n\t}\n\t.live-dot--coral {\n\t\tbackground: var(--color-coral); box-shadow: 0 0 8px rgba(255,77,109,0.5);\n\t\tanimation: pulse-coral 2.5s ease-in-out infinite;\n\t}\n\t.live-dot--muted { background: var(--color-muted); box-shadow: none; animation: none; opacity: 0.4; }\n\n\t@keyframes pulse-green { 0%,100% { opacity: 1; } 50% { opacity: 0.35; } }\n\t@keyframes pulse-blue  { 0%,100% { opacity: 1; } 50% { opacity: 0.35; } }\n\t@keyframes pulse-coral { 0%,100% { opacity: 1; } 50% { opacity: 0.35; } }\n</style>\n","<script lang=\"ts\">\n\timport { t } from '$lib/i18n';\n\timport { onMount } from 'svelte';\n\timport { SvelteSet } from 'svelte/reactivity';\n\timport DuelAvatar from './DuelAvatar.svelte';\n\n\tinterface Props {\n\t\t/** Null when this side has no score to show — its analysis failed or never\n\t\t *  ran. Distinct from 0, which is a real (terrible) rating. The server\n\t\t *  coerces a missing challenger score to 0, so the caller is responsible\n\t\t *  for passing null instead when the generation didn't complete. */\n\t\tchallengerScore: number | null;\n\t\tchallengerNickname: string | null;\n\t\tchallengerAvatarUrl?: string | null;\n\t\tchallengerImageUrl: string | null;\n\t\tentryScore: number | null;\n\t\tentryNickname: string | null;\n\t\tentryAvatarUrl?: string | null;\n\t\tentryImageUrl: string | null;\n\t}\n\n\tlet {\n\t\tchallengerScore,\n\t\tchallengerNickname,\n\t\tchallengerAvatarUrl = null,\n\t\tchallengerImageUrl,\n\t\tentryScore,\n\t\tentryNickname,\n\t\tentryAvatarUrl = null,\n\t\tentryImageUrl\n\t}: Props = $props();\n\n\t// A missing score can't win, lose or draw — with only one number there is no\n\t// comparison to make. Declaring a winner off a stand-in 0 crowned whoever\n\t// simply managed to get analysed, which is the opposite of what this screen\n\t// is for.\n\tconst bothScored = $derived(challengerScore !== null && entryScore !== null);\n\tconst winner = $derived<'challenger' | 'entry' | 'tie' | 'unknown'>(\n\t\t!bothScored\n\t\t\t? 'unknown'\n\t\t\t: (challengerScore as number) > (entryScore as number)\n\t\t\t\t? 'challenger'\n\t\t\t\t: (entryScore as number) > (challengerScore as number)\n\t\t\t\t\t? 'entry'\n\t\t\t\t\t: 'tie'\n\t);\n\tconst scoreDiff = $derived(\n\t\tbothScored ? Math.abs((challengerScore as number) - (entryScore as number)).toFixed(1) : null\n\t);\n\n\tlet animatedC = $state(0);\n\tlet animatedE = $state(0);\n\n\tonMount(() => {\n\t\tconst duration = 1400;\n\t\tconst startAt = performance.now();\n\t\tlet rafId = 0;\n\t\tconst easeOutCubic = (t: number) => 1 - Math.pow(1 - t, 3);\n\n\t\tfunction tick(ts: number) {\n\t\t\tconst t = Math.min(1, (ts - startAt) / duration);\n\t\t\tconst eased = easeOutCubic(t);\n\t\t\tanimatedC = +((challengerScore ?? 0) * eased).toFixed(1);\n\t\t\tanimatedE = +((entryScore ?? 0) * eased).toFixed(1);\n\t\t\tif (t < 1) rafId = requestAnimationFrame(tick);\n\t\t}\n\t\trafId = requestAnimationFrame(tick);\n\t\treturn () => cancelAnimationFrame(rafId);\n\t});\n\n\tconst cName = $derived(challengerNickname ?? t('challenger'));\n\tconst eName = $derived(entryNickname ?? t('contender'));\n\n\t// A signed URL can point at an object that no longer exists — most often an\n\t// expired duel whose photos the expire-duels cron already deleted. signedCdnUrl\n\t// signs locally with no existence check, so the URL looks valid but 404s at the\n\t// edge. Without this the {#if url} guard sails past and renders a torn-image\n\t// icon; instead we drop to the same \"private\" lock placeholder the no-photo case\n\t// already uses. Keyed by URL so it resets when a fresh signed URL arrives after\n\t// invalidateAll (same rationale as BeatLiveCard's onImgError).\n\tconst broken = new SvelteSet<string>();\n\tfunction onImgError(url: string | null) {\n\t\tif (url) broken.add(url);\n\t}\n</script>\n\n<div class=\"arena\">\n\t<div class=\"bracket\">\n\t\t<!-- LEFT: challenger -->\n\t\t<article\n\t\t\tclass=\"fighter fighter--blue\"\n\t\t\tclass:is-winner={winner === 'challenger'}\n\t\t\tclass:is-loser={winner === 'entry'}\n\t\t\tclass:is-tie={winner === 'tie'}\n\t\t>\n\t\t\t<div class=\"photo-card\">\n\t\t\t\t{#if challengerImageUrl && !broken.has(challengerImageUrl)}\n\t\t\t\t\t<img class=\"photo\" src={challengerImageUrl} alt=\"\" loading=\"eager\" decoding=\"async\" onerror={() => onImgError(challengerImageUrl)} />\n\t\t\t\t{:else}\n\t\t\t\t\t<div class=\"photo photo--hidden\">\n\t\t\t\t\t\t<svg class=\"lock-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t<rect x=\"5\" y=\"11\" width=\"14\" height=\"9\" rx=\"2\" />\n\t\t\t\t\t\t\t<path d=\"M8 11V7a4 4 0 0 1 8 0v4\" />\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t<span class=\"hidden-label\">{t('private')}</span>\n\t\t\t\t\t</div>\n\t\t\t\t{/if}\n\n\t\t\t\t<!-- top: nick + role -->\n\t\t\t\t<div class=\"card-top\">\n\t\t\t\t\t<DuelAvatar nickname={challengerNickname} avatarUrl={challengerAvatarUrl} size={28} variant=\"blue\" />\n\t\t\t\t\t<div class=\"meta-text\">\n\t\t\t\t\t\t{#if challengerNickname}\n\t\t\t\t\t\t\t<a class=\"nick text-blue\" href=\"/u/{encodeURIComponent(challengerNickname)}\">{cName}</a>\n\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t<span class=\"nick text-blue\">{cName}</span>\n\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t<span class=\"role\">{t('challenger')}</span>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<!-- bottom: score -->\n\t\t\t\t<div class=\"card-bottom\">\n\t\t\t\t\t{#if challengerScore === null}\n\t\t\t\t\t\t<span class=\"score score-none\">—</span>\n\t\t\t\t\t{:else}\n\t\t\t\t\t\t<span class=\"score\">{animatedC.toFixed(1)}</span>\n\t\t\t\t\t\t<span class=\"score-sub\">/10</span>\n\t\t\t\t\t{/if}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</article>\n\n\t\t<!-- CENTER: VS -->\n\t\t<div class=\"vs-block\" aria-hidden=\"true\">\n\t\t\t<span class=\"vs-glitch\" data-text=\"VS\">VS</span>\n\t\t\t{#if winner === 'unknown'}\n\t\t\t\t<div class=\"delta\">\n\t\t\t\t\t<span class=\"delta-label\">{t('result')}</span>\n\t\t\t\t\t<span class=\"delta-num text-muted\">n/a</span>\n\t\t\t\t</div>\n\t\t\t{:else if winner === 'tie'}\n\t\t\t\t<div class=\"delta\">\n\t\t\t\t\t<span class=\"delta-label\">{t('verdict')}</span>\n\t\t\t\t\t<span class=\"delta-num text-yellow\">{t('tie')}</span>\n\t\t\t\t</div>\n\t\t\t{:else}\n\t\t\t\t<div class=\"delta\">\n\t\t\t\t\t<span class=\"delta-label\">{t('decided by')}</span>\n\t\t\t\t\t<span class=\"delta-num\">{scoreDiff}</span>\n\t\t\t\t</div>\n\t\t\t{/if}\n\t\t</div>\n\n\t\t<!-- RIGHT: opponent -->\n\t\t<article\n\t\t\tclass=\"fighter fighter--coral fighter--right\"\n\t\t\tclass:is-winner={winner === 'entry'}\n\t\t\tclass:is-loser={winner === 'challenger'}\n\t\t\tclass:is-tie={winner === 'tie'}\n\t\t>\n\t\t\t<div class=\"photo-card\">\n\t\t\t\t{#if entryImageUrl && !broken.has(entryImageUrl)}\n\t\t\t\t\t<img class=\"photo\" src={entryImageUrl} alt=\"\" loading=\"eager\" decoding=\"async\" onerror={() => onImgError(entryImageUrl)} />\n\t\t\t\t{:else}\n\t\t\t\t\t<div class=\"photo photo--hidden\">\n\t\t\t\t\t\t<svg class=\"lock-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t<rect x=\"5\" y=\"11\" width=\"14\" height=\"9\" rx=\"2\" />\n\t\t\t\t\t\t\t<path d=\"M8 11V7a4 4 0 0 1 8 0v4\" />\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t<span class=\"hidden-label\">{t('private')}</span>\n\t\t\t\t\t</div>\n\t\t\t\t{/if}\n\n\t\t\t\t<div class=\"card-top\">\n\t\t\t\t\t<DuelAvatar nickname={entryNickname} avatarUrl={entryAvatarUrl} size={28} variant=\"coral\" />\n\t\t\t\t\t<div class=\"meta-text\">\n\t\t\t\t\t\t{#if entryNickname}\n\t\t\t\t\t\t\t<a class=\"nick text-coral\" href=\"/u/{encodeURIComponent(entryNickname)}\">{eName}</a>\n\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t<span class=\"nick text-coral\">{eName}</span>\n\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t<span class=\"role\">{t('contender')}</span>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"card-bottom\">\n\t\t\t\t\t{#if entryScore === null}\n\t\t\t\t\t\t<span class=\"score score-none\">—</span>\n\t\t\t\t\t{:else}\n\t\t\t\t\t\t<span class=\"score\">{animatedE.toFixed(1)}</span>\n\t\t\t\t\t\t<span class=\"score-sub\">/10</span>\n\t\t\t\t\t{/if}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</article>\n\t</div>\n\n\t<h2 class=\"verdict-headline\">\n\t\t{#if winner === 'unknown'}\n\t\t\t{#if challengerScore === null}{cName}{:else}{eName}{/if}\n\t\t\t<span class=\"text-muted\">{t('never got scored.')}</span>\n\t\t{:else if winner === 'tie'}\n\t\t\t{#each t('dead {tie} both at {score}.', { score: animatedC.toFixed(1) }).split('{tie}') as part, i (i)}{#if i}<span class=\"text-yellow\">{t('tie.')}</span>{/if}{part}{/each}\n\t\t{:else if winner === 'challenger'}\n\t\t\t{cName} <span class=\"text-blue\">{t('destroyed')}</span> {eName}.\n\t\t{:else}\n\t\t\t{eName} <span class=\"text-coral\">{t('destroyed')}</span> {cName}.\n\t\t{/if}\n\t</h2>\n</div>\n\n<style>\n\t.arena {\n\t\tposition: relative;\n\t}\n\n\t/* ─── bracket ─── */\n\t.bracket {\n\t\tdisplay: grid;\n\t\tgrid-template-columns: 1fr;\n\t\tgap: 28px;\n\t\talign-items: center; /* VS centers vertically with the cards */\n\t}\n\t@media (min-width: 768px) {\n\t\t.bracket {\n\t\t\tgrid-template-columns: 1fr auto 1fr;\n\t\t\tgap: clamp(1rem, 4vw, 3rem);\n\t\t}\n\t}\n\n\t/* ─── fighter ─── */\n\t.fighter {\n\t\tposition: relative;\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tmin-width: 0;\n\t}\n\n\t/* photo card — faint white border, faded on loser */\n\t.photo-card {\n\t\tposition: relative;\n\t\taspect-ratio: 3 / 4;\n\t\tborder-radius: 14px;\n\t\toverflow: hidden;\n\t\tbackground: var(--color-surface);\n\t\tborder: 1px solid rgba(255, 255, 255, 0.08);\n\t\ttransition: filter 600ms ease;\n\t}\n\t.is-loser .photo-card {\n\t\tfilter: saturate(0.4) brightness(0.65);\n\t}\n\n\t.photo {\n\t\twidth: 100%;\n\t\theight: 100%;\n\t\tobject-fit: cover;\n\t\tdisplay: block;\n\t}\n\t.photo--hidden {\n\t\tposition: relative;\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\tgap: 16px;\n\t\tcolor: var(--color-muted);\n\t\tbackground:\n\t\t\tlinear-gradient(rgba(255, 255, 255, 0.012) 1px, transparent 1px) 0 0 / 28px 28px,\n\t\t\tlinear-gradient(90deg, rgba(255, 255, 255, 0.012) 1px, transparent 1px) 0 0 / 28px 28px,\n\t\t\tvar(--color-surface);\n\t}\n\t.photo--hidden::before {\n\t\tcontent: '';\n\t\tposition: absolute;\n\t\tinset: 0;\n\t\tbackground: radial-gradient(\n\t\t\tellipse at 50% 45%,\n\t\t\trgba(255, 255, 255, 0.02) 0%,\n\t\t\trgba(0, 0, 0, 0.3) 85%\n\t\t);\n\t\tpointer-events: none;\n\t}\n\t.lock-icon {\n\t\twidth: 30px;\n\t\theight: 30px;\n\t\tcolor: rgba(255, 255, 255, 0.32);\n\t\tposition: relative;\n\t\tz-index: 1;\n\t}\n\t.hidden-label {\n\t\tfont-family: var(--font-display);\n\t\tfont-size: 9px;\n\t\tfont-weight: 700;\n\t\ttext-transform: uppercase;\n\t\tletter-spacing: 0.32em;\n\t\tcolor: rgba(255, 255, 255, 0.4);\n\t\tposition: relative;\n\t\tz-index: 1;\n\t}\n\n\t/* ─── top overlay: nick + role ─── */\n\t.card-top {\n\t\tposition: absolute;\n\t\ttop: 0;\n\t\tleft: 0;\n\t\tright: 0;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tgap: 10px;\n\t\tpadding: 14px 16px 28px;\n\t\tbackground: linear-gradient(180deg, rgba(0, 0, 0, 0.7) 0%, transparent 100%);\n\t\tz-index: 2;\n\t}\n\t.fighter--right .card-top {\n\t\tflex-direction: row-reverse;\n\t}\n\t.meta-text {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tmin-width: 0;\n\t\tline-height: 1.15;\n\t}\n\t.fighter--right .meta-text {\n\t\ttext-align: right;\n\t}\n\t.nick {\n\t\tfont-family: var(--font-display);\n\t\tfont-size: 13px;\n\t\tfont-weight: 800;\n\t\tletter-spacing: -0.005em;\n\t\ttext-decoration: none;\n\t\toverflow: hidden;\n\t\ttext-overflow: ellipsis;\n\t\twhite-space: nowrap;\n\t\tmax-width: 200px;\n\t\ttext-shadow: 0 1px 4px rgba(0, 0, 0, 0.7);\n\t\ttransition: opacity 0.15s;\n\t}\n\ta.nick:hover {\n\t\topacity: 0.75;\n\t\ttext-decoration: underline;\n\t\ttext-underline-offset: 3px;\n\t}\n\t.role {\n\t\tfont-family: var(--font-display);\n\t\tfont-size: 9px;\n\t\tfont-weight: 700;\n\t\ttext-transform: uppercase;\n\t\tletter-spacing: 0.25em;\n\t\tcolor: var(--color-muted);\n\t\tmargin-top: 2px;\n\t\ttext-shadow: 0 1px 3px rgba(0, 0, 0, 0.7);\n\t}\n\n\t/* ─── bottom overlay: score ─── */\n\t.card-bottom {\n\t\tposition: absolute;\n\t\tleft: 0;\n\t\tright: 0;\n\t\tbottom: 0;\n\t\tdisplay: flex;\n\t\talign-items: baseline;\n\t\tgap: 6px;\n\t\tpadding: 56px 18px 16px;\n\t\tbackground: linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.85) 100%);\n\t\tz-index: 2;\n\t}\n\t.fighter--right .card-bottom {\n\t\tjustify-content: flex-end;\n\t}\n\t/* No score to show. Muted so it reads as absence rather than as a result. */\n\t.score-none {\n\t\tcolor: rgba(255, 255, 255, 0.28);\n\t}\n\n\t.score {\n\t\tfont-family: var(--font-display);\n\t\tfont-weight: 900;\n\t\tfont-size: clamp(3rem, 9vw, 5.5rem);\n\t\tline-height: 0.85;\n\t\tletter-spacing: -0.04em;\n\t\tfont-variant-numeric: tabular-nums;\n\t\tcolor: rgba(255, 255, 255, 0.65);\n\t\ttext-shadow: 0 2px 12px rgba(0, 0, 0, 0.7);\n\t\ttransition: color 600ms ease;\n\t}\n\t.fighter--blue.is-winner .score {\n\t\tcolor: var(--color-blue);\n\t}\n\t.fighter--coral.is-winner .score {\n\t\tcolor: var(--color-coral);\n\t}\n\t.is-tie .score {\n\t\tcolor: rgba(255, 255, 255, 0.6);\n\t}\n\t.is-loser .score {\n\t\tcolor: rgba(255, 255, 255, 0.35);\n\t}\n\t.score-sub {\n\t\tfont-family: var(--font-display);\n\t\tfont-size: 11px;\n\t\tfont-weight: 700;\n\t\tcolor: rgba(255, 255, 255, 0.45);\n\t\ttext-shadow: 0 1px 3px rgba(0, 0, 0, 0.7);\n\t}\n\n\t/* ─── VS divider ─── */\n\t.vs-block {\n\t\tposition: relative;\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\talign-items: center;\n\t\tgap: 12px;\n\t\tpadding: 8px 0;\n\t}\n\t.vs-glitch {\n\t\tposition: relative;\n\t\tfont-family: var(--font-display);\n\t\tfont-weight: 900;\n\t\tletter-spacing: 0.08em;\n\t\tcolor: rgba(255, 255, 255, 0.1);\n\t\tfont-size: clamp(2rem, 7vw, 5rem);\n\t\tline-height: 1;\n\t}\n\t.vs-glitch::before,\n\t.vs-glitch::after {\n\t\tcontent: attr(data-text);\n\t\tposition: absolute;\n\t\ttop: 0;\n\t\tleft: 0;\n\t\tright: 0;\n\t\ttext-align: center;\n\t\tpointer-events: none;\n\t}\n\t.vs-glitch::before {\n\t\tcolor: var(--color-coral);\n\t\topacity: 0;\n\t\tclip-path: polygon(0 0, 100% 0, 100% 45%, 0 45%);\n\t\tanimation: glitch-a 3s ease-in-out infinite;\n\t}\n\t.vs-glitch::after {\n\t\tcolor: var(--color-blue);\n\t\topacity: 0;\n\t\tclip-path: polygon(0 55%, 100% 55%, 100% 100%, 0 100%);\n\t\tanimation: glitch-b 2.8s ease-in-out infinite;\n\t}\n\t@keyframes glitch-a {\n\t\t0%, 72%, 80%, 100% { transform: translate(0); opacity: 0; }\n\t\t74% { transform: translate(-3px, -1px); opacity: 0.85; }\n\t\t76% { transform: translate(2px, 1px); opacity: 1; }\n\t\t78% { transform: translate(-1px, 0); opacity: 0.6; }\n\t}\n\t@keyframes glitch-b {\n\t\t0%, 68%, 76%, 100% { transform: translate(0); opacity: 0; }\n\t\t70% { transform: translate(2px, 1px); opacity: 0.85; }\n\t\t72% { transform: translate(-2px, -1px); opacity: 1; }\n\t\t74% { transform: translate(1px, 0); opacity: 0.6; }\n\t}\n\n\t.delta {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\talign-items: center;\n\t\tgap: 2px;\n\t}\n\t.delta-label {\n\t\tfont-family: var(--font-display);\n\t\tfont-size: 9px;\n\t\tfont-weight: 700;\n\t\ttext-transform: uppercase;\n\t\tletter-spacing: 0.3em;\n\t\tcolor: var(--color-muted);\n\t}\n\t.delta-num {\n\t\tfont-family: var(--font-display);\n\t\tfont-size: 18px;\n\t\tfont-weight: 900;\n\t\tcolor: var(--color-text);\n\t\tfont-variant-numeric: tabular-nums;\n\t}\n\n\t/* ─── verdict headline ─── */\n\t.verdict-headline {\n\t\tmargin-top: 56px;\n\t\tfont-family: var(--font-display);\n\t\tfont-size: clamp(2rem, 7vw, 5rem);\n\t\tfont-weight: 700;\n\t\tline-height: 0.9;\n\t\tletter-spacing: -0.04em;\n\t\tcolor: var(--color-text);\n\t}\n\n\t@media (prefers-reduced-motion: reduce) {\n\t\t.vs-glitch::before,\n\t\t.vs-glitch::after {\n\t\t\tanimation: none;\n\t\t\topacity: 0;\n\t\t}\n\t}\n</style>\n","<script lang=\"ts\">\n\timport { t } from '$lib/i18n';\n\timport { slide, fade } from 'svelte/transition';\n\timport { cubicOut } from 'svelte/easing';\n\timport { pickDuelShareText } from '$lib/duel-share-text';\n\timport {\n\t\ttrackDuelChatComment,\n\t\ttrackDuelChatReact,\n\t\ttrackDuelEmojiPickerOpen\n\t} from '$lib/analytics';\n\timport type { DuelCommentData, DuelReaction, CommentsPermission } from '$lib/types/duel';\n\n\tinterface Props {\n\t\tcode: string;\n\t\treactions: DuelReaction[];\n\t\tcomments: DuelCommentData[];\n\t\tpermission: CommentsPermission;\n\t\thasSession: boolean;\n\t\temojis?: string[];\n\t\t/** RAT-277: when true, the dock anchors high enough to clear the\n\t\t *  mobile BottomNav (revealed / result view + countdown). When\n\t\t *  false, it hugs the bottom edge (focus-mode views — lobby/fomo\n\t\t *  where the nav is hidden). Prop-driven instead of a body-class\n\t\t *  trick so the positioning is deterministic per render. */\n\t\tliftAboveNav: boolean;\n\t\tonreact?: (emoji: string) => void;\n\t\toncomment?: (body: string) => Promise<{ ok: boolean; error?: string }>;\n\t\tonvoice?: (audio: Blob, durationSec: number) => Promise<{ ok: boolean; error?: string }>;\n\t}\n\n\tlet {\n\t\tcode,\n\t\treactions,\n\t\tcomments,\n\t\tpermission,\n\t\thasSession,\n\t\temojis = ['🔥', '💀', '👑', '😂', '😬', '🤯', '👀', '🫡'],\n\t\tliftAboveNav,\n\t\tonreact,\n\t\toncomment,\n\t\tonvoice\n\t}: Props = $props();\n\n\tlet chatOpen = $state(false);\n\tlet emojiOpen = $state(false);\n\tlet rotatingEmojiIdx = $state(0);\n\tlet draft = $state('');\n\tlet submitting = $state(false);\n\tlet inlineError = $state('');\n\tlet listEl: HTMLDivElement | undefined = $state();\n\tlet inputEl: HTMLTextAreaElement | undefined = $state();\n\tlet emojiTriggerEl: HTMLButtonElement | undefined = $state();\n\tlet emojiPopoverEl: HTMLDivElement | undefined = $state();\n\tlet reactCooldownUntil = $state(0);\n\n\t// ─── notifications: toast / title-flash / audio ping / toggle-pulse ───\n\tlet toast = $state<{ id: string; nickname: string; preview: string } | null>(null);\n\tlet toastTimer: ReturnType<typeof setTimeout> | null = null;\n\tlet unreadInBg = $state(0);\n\tlet lastSeenId: string | null = null;\n\tlet pendingSelfSkips = 0;\n\tlet originalTitle = '';\n\tlet audioCtx: AudioContext | null = null;\n\tconst NOTIFY_GRACE_MS = 2000; // skip notifications for the first batch after mount\n\tconst mountedAt = Date.now();\n\n\tconst MAX_LEN = 280;\n\t// Roughly 4 lines at 13px/1.4 line-height + 16px vertical padding.\n\tconst MAX_INPUT_HEIGHT = 88;\n\tconst MAX_RECORDING_SEC = 30;\n\n\t// ─── voice recording / playback state ─────────────────────────────────\n\tlet recording = $state(false);\n\tlet recordingStartedAt = 0;\n\tlet recordingDuration = $state(0);\n\tlet recordingTimer: ReturnType<typeof setInterval> | null = null;\n\tlet recorder: MediaRecorder | null = null;\n\tlet recorderStream: MediaStream | null = null;\n\tlet recorderChunks: Blob[] = [];\n\tlet recorderMime = '';\n\tlet voiceUploading = $state(false);\n\tlet voiceError = $state(''); // shown briefly above the bar\n\tlet voiceErrorTimer: ReturnType<typeof setTimeout> | null = null;\n\tlet playingVoiceId = $state<string | null>(null);\n\tlet playingProgress = $state(0); // 0..1 progress of current playback\n\tlet voiceAudioEl: HTMLAudioElement | undefined = $state();\n\t// `canRecord` derived is defined later — placed after `canComment` so the dep\n\t// reference order is valid.\n\n\tfunction pickRecorderMime(): { mime: string; ext: string } {\n\t\tif (typeof MediaRecorder === 'undefined') return { mime: '', ext: 'webm' };\n\t\tconst candidates: Array<{ mime: string; ext: string }> = [\n\t\t\t{ mime: 'audio/webm;codecs=opus', ext: 'webm' },\n\t\t\t{ mime: 'audio/webm', ext: 'webm' },\n\t\t\t{ mime: 'audio/ogg;codecs=opus', ext: 'ogg' },\n\t\t\t{ mime: 'audio/mp4', ext: 'm4a' }\n\t\t];\n\t\tfor (const c of candidates) {\n\t\t\tif (MediaRecorder.isTypeSupported(c.mime)) return c;\n\t\t}\n\t\treturn { mime: '', ext: 'webm' };\n\t}\n\n\tfunction flashVoiceError(msg: string) {\n\t\tvoiceError = msg;\n\t\tif (voiceErrorTimer) clearTimeout(voiceErrorTimer);\n\t\tvoiceErrorTimer = setTimeout(() => {\n\t\t\tvoiceError = '';\n\t\t\tvoiceErrorTimer = null;\n\t\t}, 3500);\n\t}\n\n\tfunction teardownRecording() {\n\t\tif (recordingTimer) {\n\t\t\tclearInterval(recordingTimer);\n\t\t\trecordingTimer = null;\n\t\t}\n\t\trecorder = null;\n\t\trecorderChunks = [];\n\t\tif (recorderStream) {\n\t\t\tfor (const track of recorderStream.getTracks()) track.stop();\n\t\t\trecorderStream = null;\n\t\t}\n\t\trecording = false;\n\t\trecordingDuration = 0;\n\t}\n\n\tasync function startRecording() {\n\t\tif (recording || voiceUploading) return;\n\t\tif (!canRecord) return;\n\t\tconst pick = pickRecorderMime();\n\t\tif (typeof navigator === 'undefined' || !navigator.mediaDevices?.getUserMedia) {\n\t\t\tflashVoiceError(t('voice not supported in this browser'));\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\trecorderStream = await navigator.mediaDevices.getUserMedia({ audio: true });\n\t\t} catch {\n\t\t\tflashVoiceError(t('mic blocked. enable in browser settings.'));\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\trecorder = pick.mime\n\t\t\t\t? new MediaRecorder(recorderStream, { mimeType: pick.mime })\n\t\t\t\t: new MediaRecorder(recorderStream);\n\t\t} catch {\n\t\t\tflashVoiceError(t('voice not supported in this browser'));\n\t\t\tteardownRecording();\n\t\t\treturn;\n\t\t}\n\t\trecorderMime = recorder.mimeType || pick.mime;\n\t\trecorderChunks = [];\n\t\trecorder.ondataavailable = (e) => {\n\t\t\tif (e.data && e.data.size > 0) recorderChunks.push(e.data);\n\t\t};\n\t\trecorder.onerror = () => {\n\t\t\tflashVoiceError(t('recording failed'));\n\t\t\tteardownRecording();\n\t\t};\n\t\trecorder.start();\n\t\trecordingStartedAt = Date.now();\n\t\trecording = true;\n\t\trecordingDuration = 0;\n\t\trecordingTimer = setInterval(() => {\n\t\t\tconst secs = (Date.now() - recordingStartedAt) / 1000;\n\t\t\trecordingDuration = secs;\n\t\t\tif (secs >= MAX_RECORDING_SEC) {\n\t\t\t\t// Hard cap: auto-send.\n\t\t\t\tstopAndSend();\n\t\t\t}\n\t\t}, 250);\n\t}\n\n\tfunction cancelRecording() {\n\t\tif (!recording) return;\n\t\ttry {\n\t\t\trecorder?.stop();\n\t\t} catch {\n\t\t\t/* already stopped */\n\t\t}\n\t\tteardownRecording();\n\t}\n\n\tfunction stopAndSend() {\n\t\tif (!recording || !recorder) return;\n\t\tconst dur = (Date.now() - recordingStartedAt) / 1000;\n\t\t// Capture stream + recorder in closure so teardownRecording() can run after onstop.\n\t\tconst r = recorder;\n\t\tconst onStop = async () => {\n\t\t\tr.removeEventListener('stop', onStop);\n\t\t\tconst blob = new Blob(recorderChunks, { type: recorderMime || 'audio/webm' });\n\t\t\tteardownRecording();\n\t\t\tif (blob.size === 0 || dur < 0.5) {\n\t\t\t\tflashVoiceError(t('too short'));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvoiceUploading = true;\n\t\t\tpendingSelfSkips++;\n\t\t\tlet succeeded = false;\n\t\t\ttry {\n\t\t\t\tconst result = await onvoice?.(blob, Math.round(dur));\n\t\t\t\tif (result?.ok) {\n\t\t\t\t\tsucceeded = true;\n\t\t\t\t\ttrackDuelChatComment(code, 0); // reuse text-comment metric for now\n\t\t\t\t} else {\n\t\t\t\t\tconst err = result?.error ?? 'failed';\n\t\t\t\t\tflashVoiceError(\n\t\t\t\t\t\terr === 'cooldown' ? t('easy, tiger') :\n\t\t\t\t\t\terr === 'too_large' ? t('too long') :\n\t\t\t\t\t\terr === 'login_required' ? t('log in to send voice') :\n\t\t\t\t\t\terr === 'comments_disabled' ? t('comments off') :\n\t\t\t\t\t\tt('send failed')\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tif (!succeeded) pendingSelfSkips = Math.max(0, pendingSelfSkips - 1);\n\t\t\t\tvoiceUploading = false;\n\t\t\t}\n\t\t};\n\t\tr.addEventListener('stop', onStop);\n\t\ttry {\n\t\t\tr.stop();\n\t\t} catch {\n\t\t\tr.removeEventListener('stop', onStop);\n\t\t\tteardownRecording();\n\t\t}\n\t}\n\n\tfunction togglePlayVoice(c: DuelCommentData) {\n\t\tif (!c.voiceUrl || !voiceAudioEl) return;\n\t\tif (playingVoiceId === c.id) {\n\t\t\tvoiceAudioEl.pause();\n\t\t\treturn;\n\t\t}\n\t\t// Switching: stop current, start the new one\n\t\tvoiceAudioEl.pause();\n\t\tvoiceAudioEl.src = c.voiceUrl;\n\t\tvoiceAudioEl.currentTime = 0;\n\t\tplayingProgress = 0;\n\t\tplayingVoiceId = c.id;\n\t\tvoiceAudioEl.play().catch(() => {\n\t\t\t// Autoplay rare-edge — silent fail, user can tap again\n\t\t\tplayingVoiceId = null;\n\t\t});\n\t}\n\n\tfunction handleVoiceTimeUpdate() {\n\t\tif (!voiceAudioEl) return;\n\t\tconst dur = voiceAudioEl.duration;\n\t\tif (Number.isFinite(dur) && dur > 0) {\n\t\t\tplayingProgress = voiceAudioEl.currentTime / dur;\n\t\t}\n\t}\n\n\tfunction handleVoiceEnded() {\n\t\tplayingVoiceId = null;\n\t\tplayingProgress = 0;\n\t}\n\n\tfunction handleVoicePause() {\n\t\t// Pausing keeps playingVoiceId so the play icon stays \"this is the active one\"\n\t\t// only if we're paused mid-track. If at the end, ended fires separately.\n\t\t// Treat manual pause as \"stop\": clear the active marker.\n\t\tif (voiceAudioEl && voiceAudioEl.ended) return;\n\t\t// Only clear if user paused but there's no further play in progress.\n\t\t// We delay slightly so a quick re-play (toggle) doesn't flicker.\n\t\tif (voiceAudioEl && voiceAudioEl.paused && voiceAudioEl.currentTime < voiceAudioEl.duration) {\n\t\t\tplayingVoiceId = null;\n\t\t}\n\t}\n\n\tfunction fmtRecDuration(secs: number): string {\n\t\tconst total = Math.floor(secs);\n\t\tconst m = Math.floor(total / 60);\n\t\tconst s = total % 60;\n\t\treturn `${m}:${String(s).padStart(2, '0')}`;\n\t}\n\n\tfunction fmtVoiceDuration(secs: number | null | undefined): string {\n\t\tconst total = Math.max(0, Math.round(secs ?? 0));\n\t\tconst m = Math.floor(total / 60);\n\t\tconst s = total % 60;\n\t\treturn `${m}:${String(s).padStart(2, '0')}`;\n\t}\n\tconst canComment = $derived(permission !== 'none' && (permission === 'all' || hasSession));\n\tconst lockedLabel = $derived(\n\t\tpermission === 'none'\n\t\t\t? t('comments off')\n\t\t\t: !hasSession\n\t\t\t? t('log in to talk sh*t')\n\t\t\t: ''\n\t);\n\tconst remaining = $derived(MAX_LEN - draft.length);\n\tconst overLimit = $derived(remaining < 0);\n\tconst canSubmit = $derived(canComment && !submitting && draft.trim().length > 0 && !overLimit);\n\tconst canRecord = $derived(canComment && !!onvoice);\n\n\tasync function sendComment() {\n\t\tif (!canSubmit) return;\n\t\tinlineError = '';\n\t\tconst body = draft.trim();\n\t\tsubmitting = true;\n\t\t// Increment BEFORE await so the local-optimistic comment add (in +page.svelte's\n\t\t// submitComment, which runs synchronously after this resolves) is skipped from\n\t\t// the notification flow. Decremented in `finally` if the send didn't actually\n\t\t// produce a comment.\n\t\tpendingSelfSkips++;\n\t\tlet succeeded = false;\n\t\ttry {\n\t\t\tconst result = await oncomment?.(body);\n\t\t\tif (result?.ok) {\n\t\t\t\tsucceeded = true;\n\t\t\t\tdraft = '';\n\t\t\t\ttrackDuelChatComment(code, body.length);\n\t\t\t} else if (result?.error) {\n\t\t\t\tinlineError =\n\t\t\t\t\tresult.error === 'cooldown' ? t('easy, tiger') :\n\t\t\t\t\tresult.error === 'login_required' ? t('log in') :\n\t\t\t\t\tresult.error === 'comments_disabled' ? t('comments off') :\n\t\t\t\t\tt('failed');\n\t\t\t}\n\t\t} finally {\n\t\t\tif (!succeeded) pendingSelfSkips = Math.max(0, pendingSelfSkips - 1);\n\t\t\tsubmitting = false;\n\t\t}\n\t}\n\n\tfunction sendReact(e: string) {\n\t\tconst now = Date.now();\n\t\tif (now < reactCooldownUntil) return;\n\t\treactCooldownUntil = now + 1200;\n\t\tonreact?.(e);\n\t\ttrackDuelChatReact(code, e);\n\t\temojiOpen = false;\n\t}\n\n\t// Auto-grow textarea up to MAX_INPUT_HEIGHT, then scroll inside.\n\t$effect(() => {\n\t\tvoid draft;\n\t\tif (!inputEl) return;\n\t\tinputEl.style.height = 'auto';\n\t\tinputEl.style.height = Math.min(inputEl.scrollHeight, MAX_INPUT_HEIGHT) + 'px';\n\t});\n\n\tfunction handleKey(e: KeyboardEvent) {\n\t\t// Enter sends, Shift+Enter inserts a newline. Mobile users tap the send button.\n\t\tif (e.key === 'Enter' && !e.shiftKey && !e.isComposing) {\n\t\t\te.preventDefault();\n\t\t\tsendComment();\n\t\t}\n\t}\n\n\tfunction toggleEmojiPicker() {\n\t\tconst next = !emojiOpen;\n\t\temojiOpen = next;\n\t\tif (next) {\n\t\t\t// Emoji popover sits right above the bar — collapsing the chat panel\n\t\t\t// keeps the popover the only thing competing for attention.\n\t\t\tchatOpen = false;\n\t\t\ttrackDuelEmojiPickerOpen(code);\n\t\t}\n\t}\n\n\t// Close popover on Escape or outside-click while open. Listeners are attached\n\t// only while open so there's zero idle cost when the popover is closed.\n\t$effect(() => {\n\t\tif (!emojiOpen) return;\n\t\tfunction onPointerDown(ev: PointerEvent) {\n\t\t\tconst t = ev.target as Node | null;\n\t\t\tif (!t) return;\n\t\t\tif (emojiPopoverEl?.contains(t)) return;\n\t\t\tif (emojiTriggerEl?.contains(t)) return;\n\t\t\temojiOpen = false;\n\t\t}\n\t\tfunction onKey(ev: KeyboardEvent) {\n\t\t\tif (ev.key === 'Escape') {\n\t\t\t\temojiOpen = false;\n\t\t\t\temojiTriggerEl?.focus();\n\t\t\t}\n\t\t}\n\t\tdocument.addEventListener('pointerdown', onPointerDown);\n\t\tdocument.addEventListener('keydown', onKey);\n\t\treturn () => {\n\t\t\tdocument.removeEventListener('pointerdown', onPointerDown);\n\t\t\tdocument.removeEventListener('keydown', onKey);\n\t\t};\n\t});\n\n\tfunction fmtTime(iso: string): string {\n\t\tconst d = Date.now() - new Date(iso).getTime();\n\t\tif (d < 10_000) return t('now');\n\t\tif (d < 60_000) return `${Math.floor(d / 1000)}s`;\n\t\tif (d < 3_600_000) return `${Math.floor(d / 60_000)}m`;\n\t\treturn `${Math.floor(d / 3_600_000)}h`;\n\t}\n\n\tfunction layout(id: string) {\n\t\tlet seed = 0;\n\t\tfor (let i = 0; i < id.length; i++) seed = (seed * 31 + id.charCodeAt(i)) >>> 0;\n\t\tconst left = 20 + (seed % 60);\n\t\tconst drift = -30 + ((seed >> 6) % 60);\n\t\tconst delay = (seed >> 3) % 200;\n\t\tconst scale = 0.9 + ((seed >> 9) % 40) / 100;\n\t\treturn { left, drift, delay, scale };\n\t}\n\n\t// ─── notification helpers ─────────────────────────────────────────────\n\n\tfunction playPing() {\n\t\tif (typeof window === 'undefined') return;\n\t\ttry {\n\t\t\taudioCtx ??= new (window.AudioContext ||\n\t\t\t\t(window as unknown as { webkitAudioContext: typeof AudioContext }).webkitAudioContext)();\n\t\t\tif (audioCtx.state === 'suspended') void audioCtx.resume();\n\t\t\tconst ctx = audioCtx;\n\t\t\tconst t = ctx.currentTime;\n\t\t\tconst osc = ctx.createOscillator();\n\t\t\tconst gain = ctx.createGain();\n\t\t\tosc.connect(gain);\n\t\t\tgain.connect(ctx.destination);\n\t\t\tosc.type = 'sine';\n\t\t\tosc.frequency.setValueAtTime(880, t);\n\t\t\tosc.frequency.exponentialRampToValueAtTime(660, t + 0.18);\n\t\t\tgain.gain.setValueAtTime(0, t);\n\t\t\tgain.gain.linearRampToValueAtTime(0.15, t + 0.01);\n\t\t\tgain.gain.exponentialRampToValueAtTime(0.001, t + 0.18);\n\t\t\tosc.start(t);\n\t\t\tosc.stop(t + 0.2);\n\t\t} catch {\n\t\t\t// Autoplay policy / unsupported — silent fail, the toast still shows.\n\t\t}\n\t}\n\n\tfunction flashTitle(count: number) {\n\t\tif (typeof document === 'undefined') return;\n\t\tif (!originalTitle) originalTitle = document.title;\n\t\tdocument.title = `(${count}) ${originalTitle}`;\n\t}\n\n\tfunction restoreTitle() {\n\t\tif (typeof document === 'undefined' || !originalTitle) return;\n\t\tdocument.title = originalTitle;\n\t}\n\n\tfunction startToastDismissTimer() {\n\t\tif (toastTimer) clearTimeout(toastTimer);\n\t\ttoastTimer = setTimeout(() => {\n\t\t\ttoast = null;\n\t\t\ttoastTimer = null;\n\t\t}, 4000);\n\t}\n\n\tfunction showToast(c: DuelCommentData) {\n\t\tconst preview = c.type === 'voice'\n\t\t\t? t('🎤 voice ({duration})', { duration: fmtVoiceDuration(c.voiceDurationSec) })\n\t\t\t: (c.body.length > 40 ? c.body.slice(0, 40) + '…' : c.body);\n\t\ttoast = { id: c.id, nickname: c.nickname ?? t('anon'), preview };\n\t\tif (toastTimer) {\n\t\t\tclearTimeout(toastTimer);\n\t\t\ttoastTimer = null;\n\t\t}\n\t\t// Don't start the dismiss timer while the tab is hidden — the user can't\n\t\t// see the toast yet. We'll start it on visibilitychange when they return.\n\t\tif (typeof document === 'undefined' || !document.hidden) {\n\t\t\tstartToastDismissTimer();\n\t\t}\n\t}\n\n\tfunction dismissToast() {\n\t\ttoast = null;\n\t\tif (toastTimer) {\n\t\t\tclearTimeout(toastTimer);\n\t\t\ttoastTimer = null;\n\t\t}\n\t}\n\n\tfunction openFromToast() {\n\t\tdismissToast();\n\t\tchatOpen = true;\n\t}\n\n\tfunction notifyIncoming(c: DuelCommentData) {\n\t\t// Audio ping — passive heads-up regardless of focus / panel state.\n\t\tplayPing();\n\t\t// Tab-title flash only if tab not visible (toast covers the focused case).\n\t\tif (typeof document !== 'undefined' && document.hidden) {\n\t\t\tunreadInBg++;\n\t\t\tflashTitle(unreadInBg);\n\t\t}\n\t\tshowToast(c);\n\t}\n\n\t// Visibility listener: clear unread + restore title when user returns to the tab.\n\t$effect(() => {\n\t\tif (typeof document === 'undefined') return;\n\t\tfunction onVisibility() {\n\t\t\tif (!document.hidden) {\n\t\t\t\tif (unreadInBg > 0) {\n\t\t\t\t\tunreadInBg = 0;\n\t\t\t\t\trestoreTitle();\n\t\t\t\t}\n\t\t\t\t// If a toast was rendered while we were hidden, kick off its dismiss\n\t\t\t\t// timer now so the user actually has 4s to see it.\n\t\t\t\tif (toast && !toastTimer) {\n\t\t\t\t\tstartToastDismissTimer();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tdocument.addEventListener('visibilitychange', onVisibility);\n\t\treturn () => {\n\t\t\tdocument.removeEventListener('visibilitychange', onVisibility);\n\t\t\trestoreTitle();\n\t\t\tif (toastTimer) clearTimeout(toastTimer);\n\t\t};\n\t});\n\n\t// Comments effect: handles both autoscroll AND incoming-message notifications.\n\t// Skips notifications during a 2s grace window after mount so historical messages\n\t// loaded by the initial fetch don't trigger a flood of pings.\n\t$effect(() => {\n\t\tvoid comments.length;\n\t\tif (!comments.length) return;\n\t\tconst lastCmt = comments[comments.length - 1];\n\n\t\tconst inGrace = Date.now() - mountedAt < NOTIFY_GRACE_MS;\n\t\tif (inGrace || !lastSeenId) {\n\t\t\tlastSeenId = lastCmt.id;\n\t\t\tif (listEl && chatOpen) listEl.scrollTo({ top: listEl.scrollHeight, behavior: 'smooth' });\n\t\t\treturn;\n\t\t}\n\n\t\tconst seenIdx = comments.findIndex((c) => c.id === lastSeenId);\n\t\tconst newOnes = seenIdx >= 0 ? comments.slice(seenIdx + 1) : [];\n\t\tfor (const c of newOnes) {\n\t\t\tif (pendingSelfSkips > 0) {\n\t\t\t\tpendingSelfSkips--;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tnotifyIncoming(c);\n\t\t}\n\t\tlastSeenId = lastCmt.id;\n\n\t\tif (listEl && chatOpen) listEl.scrollTo({ top: listEl.scrollHeight, behavior: 'smooth' });\n\t});\n\n\t// Opening the chat panel = \"I've seen new messages now\": clear toast + bg unread.\n\t$effect(() => {\n\t\tif (chatOpen) {\n\t\t\tdismissToast();\n\t\t\tif (unreadInBg > 0) {\n\t\t\t\tunreadInBg = 0;\n\t\t\t\trestoreTitle();\n\t\t\t}\n\t\t}\n\t});\n\n\t// Cycle the emoji-trigger glyph through the available reactions so the\n\t// button visibly invites a tap. Pauses when the popover is open.\n\t$effect(() => {\n\t\tif (emojiOpen) return;\n\t\tconst id = setInterval(() => {\n\t\t\trotatingEmojiIdx = (rotatingEmojiIdx + 1) % emojis.length;\n\t\t}, 1800);\n\t\treturn () => clearInterval(id);\n\t});\n</script>\n\n<!-- floating emoji rise overlay (full-screen, non-interactive) -->\n<div class=\"rise-layer\" aria-hidden=\"true\">\n\t{#each reactions as r (r.id)}\n\t\t{@const l = layout(r.id)}\n\t\t<span\n\t\t\tclass=\"rise-emoji\"\n\t\t\tstyle=\"--left: {l.left}%; --drift: {l.drift}px; --delay: {l.delay}ms; --scale: {l.scale};\"\n\t\t>\n\t\t\t{r.emoji}\n\t\t\t{#if r.nickname}<span class=\"rise-who\">{r.nickname}</span>{/if}\n\t\t</span>\n\t{/each}\n</div>\n\n<aside class=\"dock\" class:dock--open={chatOpen} class:dock--lifted={liftAboveNav} class:dock--floor={!liftAboveNav}>\n\t<!-- chat panel (grows upward, animated) -->\n\t{#if chatOpen}\n\t\t<div\n\t\t\tclass=\"panel\"\n\t\t\ttransition:slide={{ duration: 260, easing: cubicOut, axis: 'y' }}\n\t\t>\n\t\t\t<div class=\"panel-head\">\n\t\t\t\t<span class=\"head-dot\"></span>\n\t\t\t\t<span class=\"head-label\">{t('live chat')}</span>\n\t\t\t\t{#if comments.length > 0}\n\t\t\t\t\t<span class=\"head-count\">{comments.length}</span>\n\t\t\t\t{/if}\n\t\t\t\t<button class=\"head-close\" type=\"button\" onclick={() => (chatOpen = false)} aria-label={t('close chat')}>\n\t\t\t\t\t<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M18 6L6 18M6 6l12 12\"/></svg>\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t\t<div class=\"list\" bind:this={listEl}>\n\t\t\t\t{#if comments.length === 0}\n\t\t\t\t\t<p class=\"empty\">{t('crickets. someone has to start.')}</p>\n\t\t\t\t{:else}\n\t\t\t\t\t{#each comments as c (c.id)}\n\t\t\t\t\t\t<div class=\"msg\">\n\t\t\t\t\t\t\t<span class=\"msg-head\">\n\t\t\t\t\t\t\t\t<span class=\"msg-who\">{c.nickname ?? t('anon')}</span>\n\t\t\t\t\t\t\t\t<span class=\"msg-time\">{fmtTime(c.createdAt)}</span>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t{#if c.type === 'voice' && c.voiceUrl}\n\t\t\t\t\t\t\t\t{@const isPlaying = playingVoiceId === c.id}\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\tclass=\"voice-bubble\"\n\t\t\t\t\t\t\t\t\tclass:voice-bubble--playing={isPlaying}\n\t\t\t\t\t\t\t\t\tonclick={() => togglePlayVoice(c)}\n\t\t\t\t\t\t\t\t\taria-label={isPlaying ? t('pause voice message') : t('play voice message')}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<span class=\"voice-play-icon\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t\t\t{#if isPlaying}\n\t\t\t\t\t\t\t\t\t\t\t<svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><rect x=\"6\" y=\"5\" width=\"4\" height=\"14\"/><rect x=\"14\" y=\"5\" width=\"4\" height=\"14\"/></svg>\n\t\t\t\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t\t\t\t<svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M8 5v14l11-7z\"/></svg>\n\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t<span class=\"voice-progress\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t\t\t<span class=\"voice-progress-fill\" style=\"width: {(isPlaying ? playingProgress : 0) * 100}%\"></span>\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t<span class=\"voice-duration\">{fmtVoiceDuration(c.voiceDurationSec)}</span>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t<p class=\"msg-body\">{c.body}</p>\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t{/each}\n\t\t\t\t{/if}\n\t\t\t</div>\n\t\t</div>\n\t{/if}\n\n\t{#if inlineError}<p class=\"err\">{inlineError}</p>{/if}\n\n\t{#if toast && !chatOpen}\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"toast\"\n\t\t\taria-live=\"polite\"\n\t\t\taria-label={t('open chat')}\n\t\t\tonclick={openFromToast}\n\t\t\ttransition:slide={{ duration: 180, easing: cubicOut, axis: 'y' }}\n\t\t>\n\t\t\t<span class=\"toast-icon\" aria-hidden=\"true\">💬</span>\n\t\t\t<span class=\"toast-text\">\n\t\t\t\t<span class=\"toast-who\">{toast.nickname}</span>\n\t\t\t\t<span class=\"toast-body\">{toast.preview}</span>\n\t\t\t</span>\n\t\t</button>\n\t{/if}\n\n\t{#if voiceError}\n\t\t<p class=\"err\">{voiceError}</p>\n\t{/if}\n\n\t<div class=\"bar-wrapper\">\n\t\t<!-- dock bar — input dominant, emoji popover, mic, chat toggle -->\n\t\t<div class=\"bar\">\n\t\t\t{#if recording}\n\t\t\t\t<span class=\"rec-dot\" aria-hidden=\"true\"></span>\n\t\t\t\t<span class=\"rec-timer\">{fmtRecDuration(recordingDuration)}</span>\n\t\t\t\t<span class=\"rec-spacer\"></span>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"rec-cancel\"\n\t\t\t\t\tonclick={cancelRecording}\n\t\t\t\t\taria-label={t('cancel recording')}\n\t\t\t\t>\n\t\t\t\t\t<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n\t\t\t\t\t\t<path d=\"M18 6L6 18M6 6l12 12\"/>\n\t\t\t\t\t</svg>\n\t\t\t\t</button>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"rec-send\"\n\t\t\t\t\tonclick={stopAndSend}\n\t\t\t\t\tdisabled={voiceUploading}\n\t\t\t\t\taria-label={t('send voice message')}\n\t\t\t\t>\n\t\t\t\t\t<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n\t\t\t\t\t\t<path d=\"M22 2L11 13\"/><path d=\"M22 2l-7 20-4-9-9-4z\"/>\n\t\t\t\t\t</svg>\n\t\t\t\t</button>\n\t\t\t{:else}\n\t\t\t\t<div class=\"emoji-trigger-wrap\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"emoji-trigger\"\n\t\t\t\t\t\tclass:emoji-trigger--open={emojiOpen}\n\t\t\t\t\t\tonclick={toggleEmojiPicker}\n\t\t\t\t\t\tbind:this={emojiTriggerEl}\n\t\t\t\t\t\taria-haspopup=\"true\"\n\t\t\t\t\t\taria-expanded={emojiOpen}\n\t\t\t\t\t\taria-label={t('reactions')}\n\t\t\t\t\t>\n\t\t\t\t\t\t{#key rotatingEmojiIdx}\n\t\t\t\t\t\t\t<span class=\"rotating-glyph\" in:fade={{ duration: 220 }}>\n\t\t\t\t\t\t\t\t{emojis[rotatingEmojiIdx % emojis.length]}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t{/key}\n\t\t\t\t\t</button>\n\t\t\t\t\t{#if emojiOpen}\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclass=\"emoji-popover\"\n\t\t\t\t\t\t\trole=\"menu\"\n\t\t\t\t\t\t\tbind:this={emojiPopoverEl}\n\t\t\t\t\t\t\ttransition:slide={{ duration: 140, easing: cubicOut, axis: 'y' }}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{#each emojis as e (e)}\n\t\t\t\t\t\t\t\t<button type=\"button\" class=\"e-btn\" onclick={() => sendReact(e)} aria-label={t('react with {emoji}', { emoji: e })}>\n\t\t\t\t\t\t\t\t\t{e}\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t{/if}\n\t\t\t\t</div>\n\n\t\t\t\t{#if canComment}\n\t\t\t\t\t<form\n\t\t\t\t\t\tclass=\"bar-form\"\n\t\t\t\t\t\tonsubmit={(e) => { e.preventDefault(); sendComment(); }}\n\t\t\t\t\t>\n\t\t\t\t\t\t<textarea\n\t\t\t\t\t\t\trows=\"1\"\n\t\t\t\t\t\t\tplaceholder={t('talk sh*t…')}\n\t\t\t\t\t\t\tbind:value={draft}\n\t\t\t\t\t\t\tbind:this={inputEl}\n\t\t\t\t\t\t\tmaxlength={MAX_LEN + 20}\n\t\t\t\t\t\t\tonkeydown={handleKey}\n\t\t\t\t\t\t\tonfocus={() => (chatOpen = true)}\n\t\t\t\t\t\t\tenterkeyhint=\"send\"\n\t\t\t\t\t\t></textarea>\n\t\t\t\t\t\t{#if draft.length > 0}\n\t\t\t\t\t\t\t<span class=\"count\" class:count--over={overLimit}>{remaining}</span>\n\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t<button type=\"submit\" class=\"bar-send\" disabled={!canSubmit} aria-label={t('send comment')}>\n\t\t\t\t\t\t\t<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n\t\t\t\t\t\t\t\t<path d=\"M22 2L11 13\"/><path d=\"M22 2l-7 20-4-9-9-4z\"/>\n\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</form>\n\t\t\t\t{:else}\n\t\t\t\t\t<p class=\"bar-locked\">{lockedLabel}</p>\n\t\t\t\t{/if}\n\n\t\t\t\t{#if canRecord}\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"mic-trigger\"\n\t\t\t\t\t\tclass:mic-trigger--uploading={voiceUploading}\n\t\t\t\t\t\tonclick={startRecording}\n\t\t\t\t\t\tdisabled={voiceUploading}\n\t\t\t\t\t\taria-label={voiceUploading ? t('sending voice') : t('record voice message')}\n\t\t\t\t\t>\n\t\t\t\t\t\t{#if voiceUploading}\n\t\t\t\t\t\t\t<span class=\"mic-spinner\" aria-hidden=\"true\"></span>\n\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n\t\t\t\t\t\t\t\t<path d=\"M12 2a3 3 0 0 0-3 3v6a3 3 0 1 0 6 0V5a3 3 0 0 0-3-3z\"/>\n\t\t\t\t\t\t\t\t<path d=\"M19 10v1a7 7 0 0 1-14 0v-1\"/>\n\t\t\t\t\t\t\t\t<line x1=\"12\" y1=\"18\" x2=\"12\" y2=\"22\"/>\n\t\t\t\t\t\t\t\t<line x1=\"8\" y1=\"22\" x2=\"16\" y2=\"22\"/>\n\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t{/if}\n\t\t\t\t\t</button>\n\t\t\t\t{/if}\n\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"chat-toggle chat-toggle--icon\"\n\t\t\t\t\tclass:active={chatOpen}\n\t\t\t\t\tonclick={() => (chatOpen = !chatOpen)}\n\t\t\t\t\taria-label={t('toggle chat panel')}\n\t\t\t\t>\n\t\t\t\t\t<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n\t\t\t\t\t\t<path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"/>\n\t\t\t\t\t</svg>\n\t\t\t\t\t{#if comments.length > 0 && !chatOpen}\n\t\t\t\t\t\t<span class=\"badge\">{comments.length > 99 ? '99+' : comments.length}</span>\n\t\t\t\t\t{/if}\n\t\t\t\t</button>\n\t\t\t{/if}\n\t\t</div>\n\t</div>\n\n\t<!-- Single hidden audio element shared by all voice messages — playing one\n\t     stops the previous automatically. -->\n\t<audio\n\t\tbind:this={voiceAudioEl}\n\t\tontimeupdate={handleVoiceTimeUpdate}\n\t\tonended={handleVoiceEnded}\n\t\tonpause={handleVoicePause}\n\t\tpreload=\"none\"\n\t></audio>\n</aside>\n\n<style>\n\t/* ─── TikTok-style reaction pops ─── */\n\t.rise-layer {\n\t\tposition: fixed; inset: 0; pointer-events: none; z-index: 40;\n\t\toverflow: hidden;\n\t}\n\t.rise-emoji {\n\t\tposition: absolute; bottom: 86px; left: var(--left);\n\t\ttransform: translate(-50%, 0) scale(0);\n\t\tfont-size: 2.6rem; line-height: 1;\n\t\tanimation: pop-rise 1.4s cubic-bezier(0.34, 1.56, 0.64, 1) var(--delay) forwards;\n\t\tdisplay: inline-flex; flex-direction: column; align-items: center; gap: 3px;\n\t\tfilter: drop-shadow(0 6px 14px rgba(0,0,0,0.5));\n\t\twill-change: transform, opacity;\n\t}\n\t.rise-who {\n\t\tfont-family: var(--font-display); font-size: 10px; font-weight: 700;\n\t\tcolor: var(--color-text); opacity: 0.7;\n\t\tbackground: rgba(0,0,0,0.45); padding: 2px 6px; border-radius: 4px;\n\t\tbackdrop-filter: blur(6px);\n\t}\n\t/* Quick pop on spawn (bouncy scale), then drift up + fade */\n\t@keyframes pop-rise {\n\t\t0%   { transform: translate(-50%, 0) scale(0); opacity: 0; }\n\t\t20%  { transform: translate(-50%, -30px) scale(calc(var(--scale) * 1.3)); opacity: 1; }\n\t\t35%  { transform: translate(calc(-50% + var(--drift) * 0.3), -80px) scale(var(--scale)); opacity: 1; }\n\t\t100% { transform: translate(calc(-50% + var(--drift)), -260px) scale(calc(var(--scale) * 0.75)); opacity: 0; }\n\t}\n\n\t/* (button press transform is defined further below with other .e-btn styles) */\n\n\t/* ─── dock ─── */\n\t.dock {\n\t\tposition: fixed; left: 50%; transform: translateX(-50%);\n\t\tz-index: 55;\n\t\tdisplay: flex; flex-direction: column; gap: 8px;\n\t\t/* Desktop caps at 440px; on mobile match the page's px-5 content padding\n\t\t   (20px each side) so the bar lines up with the share-link / copy-link button. */\n\t\twidth: min(440px, calc(100vw - 40px));\n\t}\n\n\t/* RAT-277: prop-driven positioning. Two distinct modes via parent-set\n\t   class — no body-global hack, no Svelte $effect timing games. The\n\t   parent passes `liftAboveNav={view !== 'lobby' && view !== 'fomo'}`\n\t   and the class swap is synchronous with the render. */\n\n\t/* dock--lifted: revealed view only (loader views moved to focus mode\n\t   in RAT-280 — their nav hides, dock floors). BottomNav is visible\n\t   (fixed bottom-0, ~68px body + env safe-area), a flat 7-slot grid with\n\t   no raised FAB. The dock had a 130px bottom (≈52px clearance) which\n\t   read as a big empty gap above the nav. Dropped to ~84px so the dock\n\t   sits ~16px above the nav's top edge — a small breath, not a void. */\n\t.dock--lifted {\n\t\tbottom: calc(env(safe-area-inset-bottom, 0px) + 84px);\n\t}\n\n\t/* dock--floor: focus-mode views (lobby / fomo). Nav is hidden via\n\t   body.duel-focus-mode (BottomNav.svelte + layout.css consume that\n\t   class). Dock hugs the bottom edge with a 12px breath above the\n\t   safe-area zone. */\n\t.dock--floor {\n\t\tbottom: calc(env(safe-area-inset-bottom, 0px) + 12px);\n\t}\n\n\t@media (min-width: 768px) {\n\t\t/* Desktop has no bottom nav, both modes collapse to the same floor. */\n\t\t.dock--lifted,\n\t\t.dock--floor { bottom: 18px; }\n\t}\n\n\t.bar-wrapper {\n\t\tdisplay: flex;\n\t\tjustify-content: center;\n\t}\n\n\t/* chat panel above bar */\n\t.panel {\n\t\tbackground: rgba(15,15,15,0.85);\n\t\tbackdrop-filter: blur(28px) saturate(1.5);\n\t\t-webkit-backdrop-filter: blur(28px) saturate(1.5);\n\t\tborder: 1px solid var(--color-border);\n\t\tborder-radius: 16px;\n\t\toverflow: hidden;\n\t\tbox-shadow: 0 30px 60px -10px rgba(0,0,0,0.6);\n\t\tdisplay: flex; flex-direction: column;\n\t\tmax-height: 320px;\n\t}\n\t.panel-head {\n\t\tdisplay: inline-flex; align-items: center; gap: 10px;\n\t\tpadding: 12px 14px;\n\t\tborder-bottom: 1px solid var(--color-border);\n\t}\n\t.head-dot {\n\t\twidth: 6px; height: 6px; border-radius: 50%;\n\t\tbackground: var(--color-blue); box-shadow: 0 0 8px rgba(59,130,246,0.5);\n\t\tanimation: pulse 2.5s ease-in-out infinite;\n\t}\n\t@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.35; } }\n\t.head-label {\n\t\tfont-family: var(--font-display); font-size: 11px; font-weight: 700;\n\t\tletter-spacing: 0.2em; text-transform: uppercase; color: var(--color-text);\n\t}\n\t.head-count {\n\t\tmargin-left: auto;\n\t\tpadding: 2px 8px; border-radius: 999px;\n\t\tbackground: rgba(59,130,246,0.15); color: var(--color-blue);\n\t\tfont-size: 10px; font-weight: 700;\n\t}\n\t.head-close {\n\t\twidth: 24px; height: 24px; border: 0; background: transparent;\n\t\tcolor: var(--color-muted); cursor: pointer; display: inline-flex;\n\t\talign-items: center; justify-content: center; border-radius: 6px;\n\t}\n\t.head-close:hover { background: rgba(255,255,255,0.05); color: var(--color-text); }\n\t.head-close svg { width: 14px; height: 14px; }\n\n\t.list {\n\t\tpadding: 10px 14px; overflow-y: auto;\n\t\tdisplay: flex; flex-direction: column; gap: 10px;\n\t\tscrollbar-width: thin; scrollbar-color: var(--color-border) transparent;\n\t}\n\t.list::-webkit-scrollbar { width: 4px; }\n\t.list::-webkit-scrollbar-thumb { background: var(--color-border); border-radius: 2px; }\n\t.empty {\n\t\ttext-align: center; padding: 20px 0;\n\t\tfont-size: 11px; color: var(--color-muted); opacity: 0.5;\n\t\tfont-style: italic;\n\t}\n\t.msg { display: flex; flex-direction: column; gap: 2px; }\n\t.msg-head { display: flex; align-items: baseline; gap: 8px; }\n\t.msg-who { font-family: var(--font-display); font-size: 11px; font-weight: 700; color: var(--color-blue); }\n\t.msg-time { font-size: 10px; color: var(--color-muted); opacity: 0.5; }\n\t.msg-body { font-size: 13px; line-height: 1.5; color: var(--color-text); word-wrap: break-word; }\n\n\t/* ─── bar ─── */\n\t.bar {\n\t\tposition: relative;\n\t\tflex: 1;\n\t\tdisplay: flex; align-items: center; gap: 6px;\n\t\tpadding: 6px 8px 6px 10px;\n\t\tbackground: rgba(18,18,18,0.85);\n\t\tbackdrop-filter: blur(24px) saturate(1.5);\n\t\t-webkit-backdrop-filter: blur(24px) saturate(1.5);\n\t\tborder: 1px solid var(--color-border);\n\t\tborder-radius: 999px;\n\t\tbox-shadow: 0 20px 40px -10px rgba(0,0,0,0.7);\n\t}\n\n\t.e-btn {\n\t\tdisplay: inline-flex; align-items: center; justify-content: center;\n\t\twidth: 36px; height: 36px; padding: 0; border: 0; background: transparent;\n\t\tfont-size: 18px; line-height: 1; cursor: pointer; border-radius: 50%;\n\t\ttransition: transform 0.15s, background 0.2s;\n\t\tflex-shrink: 0;\n\t}\n\t.e-btn:hover { background: rgba(255,255,255,0.1); transform: scale(1.2); }\n\t.e-btn:active { transform: scale(0.82); transition-duration: 60ms; }\n\n\t/* ─── input dominant bar-form ─── */\n\t.bar-form {\n\t\tdisplay: flex; align-items: flex-end; gap: 6px;\n\t\tflex: 1; min-width: 0;\n\t}\n\t.bar-form textarea {\n\t\tflex: 1; min-width: 0;\n\t\tmin-height: 34px; max-height: 88px;\n\t\tpadding: 8px 14px;\n\t\tborder: 0; background: transparent;\n\t\tcolor: var(--color-text); font-family: var(--font-body); font-size: 13px;\n\t\tline-height: 1.4;\n\t\toutline: 0; resize: none; overflow-y: auto;\n\t\tscrollbar-width: thin; scrollbar-color: var(--color-border) transparent;\n\t\tbox-shadow: none;\n\t}\n\t/* Kill the @tailwindcss/forms default focus ring (box-shadow based, not outline). */\n\t.bar-form textarea:focus,\n\t.bar-form textarea:focus-visible {\n\t\toutline: 0;\n\t\tbox-shadow: none;\n\t\t--tw-ring-shadow: 0 0 #0000;\n\t\t--tw-ring-color: transparent;\n\t}\n\t.bar-form textarea::placeholder { color: rgba(115,115,115,0.6); }\n\t.bar-form textarea::-webkit-scrollbar { width: 4px; }\n\t.bar-form textarea::-webkit-scrollbar-thumb { background: var(--color-border); border-radius: 2px; }\n\t.bar-send {\n\t\tdisplay: inline-flex; align-items: center; justify-content: center;\n\t\twidth: 36px; height: 36px; border: 0; border-radius: 50%;\n\t\tbackground: var(--color-blue); color: white; cursor: pointer;\n\t\ttransition: transform 0.15s, background 0.2s;\n\t\tflex-shrink: 0;\n\t}\n\t.bar-send:hover:not(:disabled) { background: #2563eb; }\n\t.bar-send:active:not(:disabled) { transform: scale(0.92); }\n\t.bar-send:disabled { opacity: 0.35; cursor: not-allowed; }\n\t.bar-send svg { width: 14px; height: 14px; }\n\t.bar-locked {\n\t\tflex: 1; min-width: 0;\n\t\tfont-family: var(--font-display); font-size: 10px;\n\t\ttext-transform: uppercase; letter-spacing: 0.2em;\n\t\tcolor: var(--color-muted); padding: 0 12px; text-align: center;\n\t}\n\n\t/* ─── emoji popover trigger ─── */\n\t.emoji-trigger-wrap {\n\t\tflex-shrink: 0;\n\t}\n\t.emoji-trigger {\n\t\tposition: relative;\n\t\tdisplay: inline-flex; align-items: center; justify-content: center;\n\t\twidth: 36px; height: 36px; padding: 0; border: 0; background: transparent;\n\t\tfont-size: 19px; line-height: 1; cursor: pointer; border-radius: 50%;\n\t\ttransition: background 0.2s, transform 0.15s;\n\t}\n\t.rotating-glyph {\n\t\tposition: absolute; top: 50%; left: 50%;\n\t\ttransform: translate(-50%, -50%);\n\t\tfont-size: 19px; line-height: 1;\n\t\tpointer-events: none;\n\t}\n\t@media (prefers-reduced-motion: reduce) {\n\t\t.rotating-glyph { transition: none !important; }\n\t}\n\t.emoji-trigger:hover { background: rgba(255,255,255,0.08); }\n\t.emoji-trigger:active { transform: scale(0.92); transition-duration: 60ms; }\n\t.emoji-trigger--open { background: rgba(255,255,255,0.1); }\n\n\t.emoji-popover {\n\t\tposition: absolute;\n\t\tbottom: calc(100% + 10px);\n\t\tleft: 50%;\n\t\ttransform: translateX(-50%);\n\t\tdisplay: inline-flex; gap: 2px;\n\t\tpadding: 6px 8px;\n\t\tbackground: rgba(18,18,18,0.92);\n\t\tbackdrop-filter: blur(24px) saturate(1.5);\n\t\t-webkit-backdrop-filter: blur(24px) saturate(1.5);\n\t\tborder: 1px solid var(--color-border);\n\t\tborder-radius: 999px;\n\t\tbox-shadow: 0 16px 30px -8px rgba(0,0,0,0.7);\n\t\tz-index: 1;\n\t\twhite-space: nowrap;\n\t}\n\n\t.chat-toggle {\n\t\tposition: relative;\n\t\tdisplay: inline-flex; align-items: center; gap: 7px;\n\t\theight: 36px; padding: 0 14px 0 12px;\n\t\tborder: 0; border-radius: 999px;\n\t\tbackground: transparent; color: var(--color-muted); cursor: pointer;\n\t\tfont-family: var(--font-display); font-size: 11px; font-weight: 700;\n\t\ttext-transform: uppercase; letter-spacing: 0.15em;\n\t\ttransition: background 0.2s, color 0.2s;\n\t\tflex-shrink: 0;\n\t}\n\t.chat-toggle:hover { background: rgba(255,255,255,0.06); color: var(--color-text); }\n\t.chat-toggle.active {\n\t\tcolor: var(--color-text);\n\t\tbackground: rgba(255,255,255,0.08);\n\t}\n\t.chat-toggle--icon {\n\t\twidth: 36px; padding: 0;\n\t\tjustify-content: center;\n\t}\n\t.chat-toggle svg { width: 16px; height: 16px; }\n\t.badge {\n\t\tposition: absolute; top: -2px; right: -2px;\n\t\tmin-width: 16px; height: 16px; padding: 0 4px;\n\t\tborder-radius: 999px;\n\t\tbackground: var(--color-coral); color: white;\n\t\tfont-family: var(--font-display); font-size: 9px; font-weight: 800;\n\t\tdisplay: inline-flex; align-items: center; justify-content: center;\n\t\tfont-variant-numeric: tabular-nums;\n\t}\n\n\t.count {\n\t\tfont-family: var(--font-display); font-size: 10px;\n\t\tcolor: var(--color-muted); opacity: 0.6;\n\t\tfont-variant-numeric: tabular-nums;\n\t\tflex-shrink: 0;\n\t}\n\t.count--over { color: var(--color-coral); opacity: 1; }\n\n\t.err {\n\t\talign-self: center;\n\t\tmargin: 0;\n\t\tpadding: 4px 12px;\n\t\tbackground: rgba(255,77,109,0.12);\n\t\tborder: 1px solid rgba(255,77,109,0.3);\n\t\tborder-radius: 999px;\n\t\ttext-align: center; font-size: 10px; color: var(--color-coral);\n\t\tfont-family: var(--font-display); font-weight: 700;\n\t\ttext-transform: lowercase; letter-spacing: 0.05em;\n\t}\n\n\t/* ─── incoming-message toast ─── */\n\t.toast {\n\t\talign-self: center;\n\t\tdisplay: inline-flex; align-items: center; gap: 8px;\n\t\tmax-width: 100%; min-width: 0;\n\t\tpadding: 8px 14px;\n\t\tbackground: rgba(18,18,18,0.92);\n\t\tbackdrop-filter: blur(20px) saturate(1.5);\n\t\t-webkit-backdrop-filter: blur(20px) saturate(1.5);\n\t\tborder: 1px solid var(--color-border);\n\t\tborder-radius: 999px;\n\t\tbox-shadow: 0 10px 24px -8px rgba(0,0,0,0.6);\n\t\tcolor: var(--color-text);\n\t\tfont-family: var(--font-body); font-size: 12px;\n\t\tcursor: pointer;\n\t\ttext-align: left;\n\t}\n\t.toast:hover { background: rgba(28,28,28,0.95); border-color: rgba(255,255,255,0.18); }\n\t.toast-icon { font-size: 13px; line-height: 1; flex-shrink: 0; }\n\t.toast-text {\n\t\tdisplay: inline-flex; align-items: baseline; gap: 6px;\n\t\tmin-width: 0;\n\t\toverflow: hidden;\n\t}\n\t.toast-who {\n\t\tfont-family: var(--font-display); font-weight: 700; font-size: 11px;\n\t\tcolor: var(--color-blue);\n\t\tflex-shrink: 0;\n\t}\n\t.toast-body {\n\t\tcolor: var(--color-text); opacity: 0.9;\n\t\twhite-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n\t\tmin-width: 0;\n\t}\n\n\t/* ─── mic trigger (record voice message) ─── */\n\t.mic-trigger {\n\t\tdisplay: inline-flex; align-items: center; justify-content: center;\n\t\twidth: 36px; height: 36px; padding: 0; border: 0; background: transparent;\n\t\tcolor: var(--color-muted); cursor: pointer; border-radius: 50%;\n\t\ttransition: background 0.2s, color 0.2s, transform 0.15s;\n\t\tflex-shrink: 0;\n\t}\n\t.mic-trigger:hover { background: rgba(255,255,255,0.08); color: var(--color-text); }\n\t.mic-trigger:active:not(:disabled) { transform: scale(0.92); transition-duration: 60ms; }\n\t.mic-trigger:disabled { cursor: not-allowed; opacity: 0.6; }\n\t.mic-trigger svg { width: 16px; height: 16px; }\n\t.mic-spinner {\n\t\twidth: 14px; height: 14px;\n\t\tborder: 2px solid rgba(59,130,246,0.25);\n\t\tborder-top-color: var(--color-blue);\n\t\tborder-radius: 50%;\n\t\tanimation: mic-spin 0.7s linear infinite;\n\t}\n\t@keyframes mic-spin { to { transform: rotate(360deg); } }\n\n\t/* ─── recording state (replaces normal bar contents) ─── */\n\t.rec-dot {\n\t\twidth: 10px; height: 10px; border-radius: 50%;\n\t\tbackground: var(--color-coral);\n\t\tbox-shadow: 0 0 10px rgba(255,77,109,0.6);\n\t\tanimation: pulse 1s ease-in-out infinite;\n\t\tmargin-left: 4px;\n\t\tflex-shrink: 0;\n\t}\n\t.rec-timer {\n\t\tfont-family: var(--font-display); font-weight: 700;\n\t\tfont-size: 13px; color: var(--color-text);\n\t\tfont-variant-numeric: tabular-nums;\n\t\tflex-shrink: 0;\n\t}\n\t.rec-spacer { flex: 1; min-width: 0; }\n\t.rec-cancel {\n\t\tdisplay: inline-flex; align-items: center; justify-content: center;\n\t\twidth: 32px; height: 32px; border: 0; border-radius: 50%;\n\t\tbackground: rgba(255,77,109,0.15); color: var(--color-coral); cursor: pointer;\n\t\ttransition: background 0.2s, transform 0.15s;\n\t\tflex-shrink: 0;\n\t}\n\t.rec-cancel:hover { background: rgba(255,77,109,0.25); }\n\t.rec-cancel:active { transform: scale(0.92); transition-duration: 60ms; }\n\t.rec-cancel svg { width: 14px; height: 14px; }\n\t.rec-send {\n\t\tdisplay: inline-flex; align-items: center; justify-content: center;\n\t\twidth: 36px; height: 36px; border: 0; border-radius: 50%;\n\t\tbackground: var(--color-blue); color: white; cursor: pointer;\n\t\ttransition: background 0.2s, transform 0.15s;\n\t\tflex-shrink: 0;\n\t}\n\t.rec-send:hover:not(:disabled) { background: #2563eb; }\n\t.rec-send:active:not(:disabled) { transform: scale(0.92); transition-duration: 60ms; }\n\t.rec-send:disabled { opacity: 0.5; cursor: not-allowed; }\n\t.rec-send svg { width: 14px; height: 14px; }\n\n\t/* ─── voice message bubble in chat list ─── */\n\t.voice-bubble {\n\t\tdisplay: inline-flex; align-items: center; gap: 10px;\n\t\tmax-width: 240px; min-width: 180px;\n\t\tpadding: 8px 12px;\n\t\tbackground: rgba(59,130,246,0.10);\n\t\tborder: 1px solid rgba(59,130,246,0.25);\n\t\tborder-radius: 999px;\n\t\tcolor: var(--color-text);\n\t\tcursor: pointer;\n\t\ttransition: background 0.15s, border-color 0.15s;\n\t}\n\t.voice-bubble:hover { background: rgba(59,130,246,0.15); border-color: rgba(59,130,246,0.4); }\n\t.voice-bubble--playing { background: rgba(59,130,246,0.18); border-color: rgba(59,130,246,0.5); }\n\t.voice-play-icon {\n\t\tdisplay: inline-flex; align-items: center; justify-content: center;\n\t\twidth: 24px; height: 24px;\n\t\tbackground: var(--color-blue); color: white;\n\t\tborder-radius: 50%;\n\t\tflex-shrink: 0;\n\t}\n\t.voice-play-icon svg { width: 12px; height: 12px; }\n\t.voice-progress {\n\t\tflex: 1; min-width: 0;\n\t\theight: 3px;\n\t\tbackground: rgba(255,255,255,0.10);\n\t\tborder-radius: 999px;\n\t\toverflow: hidden;\n\t}\n\t.voice-progress-fill {\n\t\tdisplay: block;\n\t\theight: 100%;\n\t\tbackground: var(--color-blue);\n\t\ttransition: width 0.12s linear;\n\t}\n\t.voice-duration {\n\t\tfont-family: var(--font-display); font-weight: 700;\n\t\tfont-size: 11px; color: var(--color-blue);\n\t\tfont-variant-numeric: tabular-nums;\n\t\tflex-shrink: 0;\n\t}\n\n\t@media (max-width: 520px) {\n\t\t/* No `.dock { bottom }` here — that overrode .dock--lifted by source order, killing the mobile nav clearance. */\n\t\t.bar { gap: 4px; padding: 5px 6px 5px 8px; }\n\t\t.e-btn { width: 32px; height: 32px; font-size: 16px; }\n\t\t.emoji-trigger { width: 32px; height: 32px; font-size: 17px; }\n\t\t.mic-trigger { width: 32px; height: 32px; }\n\t\t.mic-trigger svg { width: 14px; height: 14px; }\n\t\t.bar-send { width: 32px; height: 32px; }\n\t\t.chat-toggle { height: 32px; font-size: 10px; }\n\t\t.chat-toggle--icon { width: 32px; padding: 0; }\n\t}\n\n\t@media (prefers-reduced-motion: reduce) {\n\t\t.rise-emoji { animation-duration: 0.4s; }\n\t\t.rec-dot { animation: none; }\n\t\t.mic-spinner { animation-duration: 1.4s; }\n\t}\n</style>\n","import type { SupabaseClient, RealtimeChannel } from '@supabase/supabase-js';\nimport type { DuelPresence, DuelReaction, DuelCommentData } from '$lib/types/duel';\n\nexport interface DuelChannelSelf {\n\tuserId: string | null;\n\tnickname: string | null;\n\trole: 'challenger' | 'opponent' | 'spectator';\n}\n\nexport interface DuelChannelHandlers {\n\tonPresence?: (presences: DuelPresence[]) => void;\n\tonReaction?: (reaction: DuelReaction) => void;\n\tonComment?: (comment: DuelCommentData) => void;\n\t/** Fires when any column on the `duel` row changes (e.g. countdownStartedAt set). */\n\tonDuelUpdate?: () => void;\n\t/** Fires when the duel_entry rows change (new entry, status flip). */\n\tonEntryUpdate?: () => void;\n\t/** Fires when subscription state flips. Lets the page skip fallback polling while healthy. */\n\tonSubscriptionChange?: (healthy: boolean) => void;\n}\n\nconst REACTION_COOLDOWN_MS = 1500;\n\nexport function createDuelChannel(\n\tsupabase: SupabaseClient,\n\tcode: string,\n\tself: DuelChannelSelf,\n\tduelId: string,\n\thandlers: DuelChannelHandlers = {}\n) {\n\tconst channelName = `duel:${code.toUpperCase()}`;\n\t// Defensive: Svelte 5 dev double-invokes $effect, and remounts / realtime\n\t// reconnects can re-run this. supabase.channel() returns the *cached* channel\n\t// for a name that already exists — calling .on() on an already-subscribed\n\t// channel throws \"cannot add presence callbacks ... after subscribe()\" and\n\t// aborts hydration. Drop any stale channel for this name first.\n\t// (Same guard NotificationBell.svelte uses.)\n\tconst existing = supabase.getChannels().find((c) => c.topic === `realtime:${channelName}`);\n\tif (existing) supabase.removeChannel(existing);\n\tconst channel: RealtimeChannel = supabase.channel(channelName, {\n\t\tconfig: { presence: { key: self.userId ?? `anon-${crypto.randomUUID().slice(0, 8)}` } }\n\t});\n\n\tconst joinedAt = new Date().toISOString();\n\tlet lastReactionAt = 0;\n\tlet subscribed = false;\n\n\tchannel\n\t\t.on('presence', { event: 'sync' }, () => {\n\t\t\tconst state = channel.presenceState<DuelPresence>();\n\t\t\tconst list: DuelPresence[] = [];\n\t\t\tfor (const key of Object.keys(state)) {\n\t\t\t\tconst meta = state[key][0];\n\t\t\t\tif (meta) list.push(meta);\n\t\t\t}\n\t\t\thandlers.onPresence?.(list);\n\t\t})\n\t\t.on('broadcast', { event: 'reaction' }, (payload) => {\n\t\t\tconst r = payload.payload as DuelReaction | undefined;\n\t\t\tif (r && typeof r.emoji === 'string') handlers.onReaction?.(r);\n\t\t})\n\t\t.on('broadcast', { event: 'comment' }, (payload) => {\n\t\t\tconst c = payload.payload as DuelCommentData | undefined;\n\t\t\tif (c && typeof c.body === 'string') handlers.onComment?.(c);\n\t\t})\n\t\t.on(\n\t\t\t'postgres_changes',\n\t\t\t{ event: 'UPDATE', schema: 'public', table: 'duel', filter: `id=eq.${duelId}` },\n\t\t\t() => handlers.onDuelUpdate?.()\n\t\t)\n\t\t.on(\n\t\t\t'postgres_changes',\n\t\t\t{ event: '*', schema: 'public', table: 'duel_entry', filter: `duel_id=eq.${duelId}` },\n\t\t\t() => handlers.onEntryUpdate?.()\n\t\t);\n\n\tchannel.subscribe(async (status) => {\n\t\tconst healthy = status === 'SUBSCRIBED';\n\t\tif (healthy && !subscribed) {\n\t\t\tsubscribed = true;\n\t\t\tawait channel.track({\n\t\t\t\tuserId: self.userId,\n\t\t\t\tnickname: self.nickname,\n\t\t\t\trole: self.role,\n\t\t\t\tjoinedAt\n\t\t\t} satisfies DuelPresence);\n\t\t} else if (!healthy && subscribed) {\n\t\t\tsubscribed = false;\n\t\t}\n\t\t// Always notify — covers initial SUBSCRIBED, drops (CHANNEL_ERROR, TIMED_OUT, CLOSED),\n\t\t// and reconnects. Page uses this to gate fallback polling.\n\t\thandlers.onSubscriptionChange?.(healthy);\n\t});\n\n\tfunction broadcastReaction(emoji: string) {\n\t\tconst now = Date.now();\n\t\tif (now - lastReactionAt < REACTION_COOLDOWN_MS) return false;\n\t\tlastReactionAt = now;\n\t\tconst reaction: DuelReaction = {\n\t\t\tid: crypto.randomUUID(),\n\t\t\temoji,\n\t\t\tnickname: self.nickname,\n\t\t\tuserId: self.userId,\n\t\t\tat: now\n\t\t};\n\t\tchannel.send({ type: 'broadcast', event: 'reaction', payload: reaction });\n\t\t// Also surface our own reaction locally so the sender sees it.\n\t\thandlers.onReaction?.(reaction);\n\t\treturn true;\n\t}\n\n\tfunction broadcastComment(comment: DuelCommentData) {\n\t\tchannel.send({ type: 'broadcast', event: 'comment', payload: comment });\n\t}\n\n\tfunction destroy() {\n\t\tchannel.unsubscribe();\n\t\tsupabase.removeChannel(channel);\n\t}\n\n\treturn { broadcastReaction, broadcastComment, destroy };\n}\n","<script lang=\"ts\">\n\timport { t } from '$lib/i18n';\n\timport { invalidateAll, replaceState, goto } from '$app/navigation';\n\timport { page } from '$app/state';\n\timport { deserialize } from '$app/forms';\n\timport { onDestroy, onMount } from 'svelte';\n\timport ShareLink from '$lib/components/duel/ShareLink.svelte';\n\timport DuelFeatureNudge from '$lib/components/duel/DuelFeatureNudge.svelte';\n\timport PostToFeedCta from '$lib/components/post/PostToFeedCta.svelte';\n\timport DuelResults from '$lib/components/duel/DuelResults.svelte';\n\timport DuelUploadZone from '$lib/components/duel/DuelUploadZone.svelte';\n\timport ReusePhoto from '$lib/components/ReusePhoto.svelte';\n\timport PresenceBar from '$lib/components/duel/PresenceBar.svelte';\n\timport SyncCountdown from '$lib/components/duel/SyncCountdown.svelte';\n\timport AnalyzingProgress from '$lib/components/AnalyzingProgress.svelte';\n\timport OAuthButtonRow from '$lib/components/auth/OAuthButtonRow.svelte';\n\timport DuelFightArena from '$lib/components/duel/DuelFightArena.svelte';\n\timport { browser } from '$app/environment';\n\timport { resolve } from '$app/paths';\n\timport { saveResume, consumeResume } from '$lib/oauth-resume';\n\timport { heicToJpeg } from '$lib/utils/heic-to-jpeg';\n\timport { pickFailure } from '$lib/utils/stale-file';\n\n\ttype DuelCodeResume = { imagePath: string };\n\timport DuelDock from '$lib/components/duel/DuelDock.svelte';\n\timport DuelAvatar from '$lib/components/duel/DuelAvatar.svelte';\n\timport UserBadge from '$lib/components/UserBadge.svelte';\n\timport FollowButton from '$lib/components/profile/FollowButton.svelte';\n\timport { getAvatarUrl } from '$lib/avatar';\n\timport { activeMode } from '$lib/stores/activeMode';\n\timport { openAuthSheet } from '$lib/stores/authSheet';\n\timport { createSupabaseBrowserClient } from '$lib/supabase';\n\timport { uploadSubmissionPhoto } from '$lib/submission-upload';\n\timport { createDuelChannel } from '$lib/duelRealtime';\n\timport * as analytics from '$lib/analytics';\n\timport type { AnalysisResults } from '$lib/types/generation';\n\timport type { DuelPresence, DuelReaction, DuelCommentData } from '$lib/types/duel';\n\timport ReportContentModal from '$lib/components/ReportContentModal.svelte';\n\timport { sanitizeVerdict } from '$lib/utils/sanitize-verdict';\n\n\tlet reportOpen = $state(false);\n\n\tlet { data } = $props();\n\tconst supabase = createSupabaseBrowserClient();\n\n\tactiveMode.set('duel');\n\tonDestroy(() => activeMode.set(null));\n\n\t// ─── Load-derived base state ──────────────────────────────────────────\n\tconst notFound = $derived(data.notFound);\n\tconst corrupted = $derived(data.notFound && data.corrupted === true);\n\tconst duel = $derived(data.notFound ? null : data.duel);\n\tconst entries = $derived(data.notFound ? [] : data.entries);\n\tconst isChallenger = $derived(!data.notFound && data.isChallenger);\n\tconst hasSession = $derived(!data.notFound && !!data.session);\n\n\t// RAT-529: duels and chat — send to a chat, rematch, keep the score.\n\tlet sentTo = $state<Record<string, 'sending' | 'sent' | 'failed'>>({});\n\tasync function sendToChat(threadId: string) {\n\t\tif (!duel || sentTo[threadId]) return;\n\t\tsentTo = { ...sentTo, [threadId]: 'sending' };\n\t\ttry {\n\t\t\tconst res = await fetch(`/api/duel/${duel.code}/send-to-chat`, {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders: { 'content-type': 'application/json' },\n\t\t\t\tbody: JSON.stringify({ threadId })\n\t\t\t});\n\t\t\tsentTo = { ...sentTo, [threadId]: res.ok ? 'sent' : 'failed' };\n\t\t} catch {\n\t\t\tsentTo = { ...sentTo, [threadId]: 'failed' };\n\t\t}\n\t}\n\t// Back from signing in at the reveal: the entry made signed-out becomes theirs.\n\tlet claimTried = false;\n\t$effect(() => {\n\t\tif (claimTried || !hasSession || !duel) return;\n\t\tif (page.url.searchParams.get('claim') !== '1') return;\n\t\tclaimTried = true;\n\t\tconst code = duel.code;\n\t\tconst clean = new URL(page.url);\n\t\tclean.searchParams.delete('claim');\n\t\t// The page's own address minus one parameter: nothing to resolve.\n\t\t// eslint-disable-next-line svelte/no-navigation-without-resolve\n\t\treplaceState(clean, {});\n\t\tvoid fetch(`/api/duel/${code}/claim-entry`, { method: 'POST' }).then(() => invalidateAll());\n\t});\n\n\t// Featured-board prompt: shown to the challenger while they wait with no\n\t// opponent and the duel isn't already on the board.\n\tlet featurePromptOpen = $state(false);\n\tconst isFeatured = $derived(\n\t\t!!duel?.featuredUntil && new Date(duel.featuredUntil).getTime() > Date.now()\n\t);\n\n\t// RAT-88: targeting info for private duels. `targeted` = true when the\n\t// challenger restricted who can accept; `viewerBlocked` = true only when\n\t// we can prove the viewer is the wrong person (logged in, doesn't match).\n\t// `viewerAmbiguous` covers the anon case — we don't know yet, so we show\n\t// a softer \"log in to confirm\" hint instead of a hard block.\n\tconst targeting = $derived(data.notFound ? null : data.targeting);\n\tconst targeted = $derived(targeting?.type !== null && targeting?.type !== undefined);\n\tconst viewerBlocked = $derived(targeted && targeting?.viewerEligible === false);\n\tconst viewerAmbiguous = $derived(targeted && targeting?.viewerEligible === null);\n\n\tconst firstEntry = $derived(entries[0] ?? null);\n\tconst challengerProcessing = $derived(\n\t\tduel?.challengerGenerationStatus === 'pending' || duel?.challengerGenerationStatus === 'processing'\n\t);\n\n\t// Team-mode layout helpers — derive the per-side roster ahead of render so the\n\t// matchup card can iterate slot 0..teamSize-1 with both filled and open slots.\n\tconst teamSize = $derived(\n\t\tduel?.format === '4v4' ? 4 : duel?.format === '2v2' ? 2 : 1\n\t);\n\ttype SlotRow =\n\t\t| { kind: 'challenger'; nickname: string | null }\n\t\t| { kind: 'entry'; entry: (typeof entries)[number] }\n\t\t| { kind: 'open' };\n\tconst teamA = $derived.by<SlotRow[]>(() => {\n\t\tconst rows: SlotRow[] = [{ kind: 'challenger', nickname: duel?.challengerNickname ?? null }];\n\t\tconst aEntries = entries\n\t\t\t.filter((e) => e.teamPosition === 'A')\n\t\t\t.sort((x, y) => x.slotIndex - y.slotIndex);\n\t\tconst bySlot = new Map(aEntries.map((e) => [e.slotIndex, e]));\n\t\tfor (let s = 1; s < teamSize; s++) {\n\t\t\tconst e = bySlot.get(s);\n\t\t\trows.push(e ? { kind: 'entry', entry: e } : { kind: 'open' });\n\t\t}\n\t\treturn rows;\n\t});\n\tconst teamB = $derived.by<SlotRow[]>(() => {\n\t\tconst bEntries = entries\n\t\t\t.filter((e) => e.teamPosition === 'B')\n\t\t\t.sort((x, y) => x.slotIndex - y.slotIndex);\n\t\tconst bySlot = new Map(bEntries.map((e) => [e.slotIndex, e]));\n\t\tconst rows: SlotRow[] = [];\n\t\tfor (let s = 0; s < teamSize; s++) {\n\t\t\tconst e = bySlot.get(s);\n\t\t\trows.push(e ? { kind: 'entry', entry: e } : { kind: 'open' });\n\t\t}\n\t\treturn rows;\n\t});\n\n\tlet entryId = $state<string | null>(null);\n\t$effect.pre(() => {\n\t\tif (entryId === null && !data.notFound && data.entryId) entryId = data.entryId;\n\t});\n\n\t// ─── Join flow state ──────────────────────────────────────────────────\n\ttype JoinStep = 'fomo' | 'email' | 'otp';\n\tlet joinStep = $state<JoinStep>('fomo');\n\tlet selectedFile = $state<File | null>(null);\n\tlet savePhoto = $state(true);\n\tlet dragOver = $state(false);\n\tlet email = $state('');\n\tlet emailError = $state('');\n\tlet emailSending = $state(false);\n\tlet otpCode = $state('');\n\tlet otpError = $state('');\n\tlet otpVerifying = $state(false);\n\tlet otpCooldown = $state(0);\n\tlet otpResendCount = $state(0);\n\tlet cooldownInterval: ReturnType<typeof setInterval> | null = null;\n\tlet submitting = $state(false);\n\tlet submitError = $state('');\n\tlet uploadedImagePath = $state<string | null>(null);\n\n\t// RAT-165: server-aware OAuth resume probe via URL flag. SSR sees\n\t// `?oauth_resume=1` and renders the bridge loader from the first frame.\n\tlet oauthResumeIncoming = $state(page.url.searchParams.get('oauth_resume') === '1');\n\tfunction clearOauthResumeFlag() {\n\t\tif (!browser) return;\n\t\tconst url = new URL(page.url);\n\t\tif (!url.searchParams.has('oauth_resume')) return;\n\t\turl.searchParams.delete('oauth_resume');\n\t\treplaceState(url, {});\n\t}\n\n\t// ─── Countdown display for expiry (top-right clock) ──────────────────\n\t// RAT-529: seeded from the server's clock, so the first frame (SSR and\n\t// hydration alike) shows the real time left instead of 00:00:00; the effect\n\t// then ticks it on the client's clock.\n\tlet expiryMs = $derived(\n\t\t!data.notFound && data.duel\n\t\t\t? Math.max(0, new Date(data.duel.expiresAt).getTime() - data.serverNow)\n\t\t\t: 0\n\t);\n\t$effect(() => {\n\t\tif (!duel) return;\n\t\tconst target = new Date(duel.expiresAt).getTime();\n\t\tconst tick = () => { expiryMs = Math.max(0, target - Date.now()); };\n\t\ttick();\n\t\tconst id = setInterval(tick, 1000);\n\t\treturn () => clearInterval(id);\n\t});\n\tconst expH = $derived(Math.floor(expiryMs / 3_600_000));\n\tconst expM = $derived(Math.floor((expiryMs % 3_600_000) / 60_000));\n\tconst expS = $derived(Math.floor((expiryMs % 60_000) / 1000));\n\tconst expUrgent = $derived(expiryMs > 0 && expiryMs < 3_600_000);\n\tconst pad = (n: number) => String(n).padStart(2, '0');\n\n\t// Lightbox for tapping a team-mode member photo (full-size view).\n\tlet lightboxImage = $state<string | null>(null);\n\n\t// ─── Realtime channel ────────────────────────────────────────────────\n\tlet presences = $state<DuelPresence[]>([]);\n\tlet activeReactions = $state<DuelReaction[]>([]);\n\tlet comments = $state<DuelCommentData[]>([]);\n\tlet channelHandle: ReturnType<typeof createDuelChannel> | null = null;\n\tlet finalizeInFlight = false;\n\tlet pollInterval: ReturnType<typeof setInterval> | null = null;\n\t// Escape hatch for a stuck analysis. `analysisTimedOut` flips true when the\n\t// status poll runs past its hard ceiling without ever seeing completed/failed\n\t// (the server hung, or its function died before it could mark the row failed) —\n\t// it routes the joiner to the failure/retry view instead of parking the loader\n\t// at 92% forever. `retrying` holds the processing view while a re-run is kicked.\n\tlet analysisTimedOut = $state(false);\n\tlet retrying = $state(false);\n\tonMount(() => {\n\t\tif (notFound || !duel) return;\n\n\t\t// Attribution beacon — the server hook skips utm/ref cookie-setting on /d/*\n\t\t// GETs so the response stays edge-cacheable. Replay it client-side: fire-and-forget\n\t\t// POST to /api/attribute that sets the same cookies + logs the click.\n\t\tconst params = new URLSearchParams(window.location.search);\n\t\tconst utmSource = params.get('utm_source');\n\t\tconst refCode = params.get('ref');\n\t\tif (utmSource || refCode) {\n\t\t\tconst beacon = new FormData();\n\t\t\tif (utmSource) {\n\t\t\t\tbeacon.set('utm_source', utmSource);\n\t\t\t\tfor (const k of ['utm_medium', 'utm_campaign', 'utm_content', 'utm_term']) {\n\t\t\t\t\tconst v = params.get(k);\n\t\t\t\t\tif (v) beacon.set(k, v);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (refCode) beacon.set('ref', refCode);\n\t\t\tfetch('/api/attribute', { method: 'POST', body: beacon, keepalive: true }).catch(() => {});\n\t\t}\n\n\t\tconst selfRole: DuelPresence['role'] = isChallenger\n\t\t\t? 'challenger'\n\t\t\t: entryId\n\t\t\t? 'opponent'\n\t\t\t: 'spectator';\n\t\tconst selfNickname = isChallenger ? duel.challengerNickname : firstEntry?.nickname ?? data.userNickname ?? null;\n\n\t\t// Defer realtime + initial comments fetch until the browser is idle. The\n\t\t// WebSocket handshake + presence join previously fired immediately on mount\n\t\t// and blocked first interaction on slow networks. Polling already covers\n\t\t// correctness, so a few hundred ms of \"no realtime yet\" is invisible.\n\t\tconst ric: (cb: () => void) => number =\n\t\t\t(typeof window !== 'undefined' && (window as Window & { requestIdleCallback?: (cb: () => void) => number }).requestIdleCallback) ||\n\t\t\t((cb: () => void) => window.setTimeout(cb, 0));\n\n\t\tric(async () => {\n\t\t\tif (!duel) return;\n\t\t\tchannelHandle = createDuelChannel(\n\t\t\t\tsupabase,\n\t\t\t\tduel.code,\n\t\t\t\t{\n\t\t\t\t\tuserId: data.session?.user?.id ?? null,\n\t\t\t\t\tnickname: selfNickname,\n\t\t\t\t\trole: selfRole\n\t\t\t\t},\n\t\t\t\tduel.id,\n\t\t\t\t{\n\t\t\t\t\tonPresence: (list) => { presences = list; },\n\t\t\t\t\tonReaction: (r) => {\n\t\t\t\t\t\tactiveReactions = [...activeReactions, r];\n\t\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\t\tactiveReactions = activeReactions.filter((x) => x.id !== r.id);\n\t\t\t\t\t\t}, 3200);\n\t\t\t\t\t},\n\t\t\t\t\tonComment: (c) => {\n\t\t\t\t\t\tif (!comments.some((x) => x.id === c.id)) {\n\t\t\t\t\t\t\tcomments = [...comments, c];\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tonDuelUpdate: () => invalidateAll(),\n\t\t\t\t\tonEntryUpdate: () => invalidateAll()\n\t\t\t\t}\n\t\t\t);\n\n\t\t\tawait fetchAndMergeComments(duel.code);\n\t\t});\n\t});\n\n\tlet commentPollInterval: ReturnType<typeof setInterval> | null = null;\n\n\t// Set by startProcessing so teardown can drop its visibilitychange listener\n\t// too — the poll owns it, but onDestroy is the only place that sees unmount.\n\tlet stopStatusPoll: (() => void) | null = null;\n\n\tonDestroy(() => {\n\t\tchannelHandle?.destroy();\n\t\tif (cooldownInterval) clearInterval(cooldownInterval);\n\t\tstopStatusPoll?.();\n\t\tif (pollInterval) clearInterval(pollInterval);\n\t\tif (viewPollInterval) clearInterval(viewPollInterval);\n\t\tif (commentPollInterval) clearInterval(commentPollInterval);\n\t});\n\n\t// Comment polling fallback. Realtime broadcast is the primary path, but iOS\n\t// Safari mobile has been observed to silently drop the WS subscription on\n\t// flaky networks / backgrounded tabs — leaving the receiver permanently\n\t// missing the other party's messages until they refresh. Refetch + merge\n\t// closes the worst-case window. Server is the source of truth for committed\n\t// comments; local-only items (broadcast arrived before DB visibility) are\n\t// preserved.\n\tasync function fetchAndMergeComments(code: string) {\n\t\ttry {\n\t\t\tconst res = await fetch(`/api/duel/comment/${code}`);\n\t\t\tif (!res.ok) return;\n\t\t\tconst body = (await res.json()) as { comments: DuelCommentData[] };\n\t\t\tconst server = body.comments ?? [];\n\t\t\tconst seen = new Set(server.map((c) => c.id));\n\t\t\tconst localOnly = comments.filter((c) => !seen.has(c.id));\n\t\t\tcomments = [...server, ...localOnly].sort((a, b) =>\n\t\t\t\ta.createdAt.localeCompare(b.createdAt)\n\t\t\t);\n\t\t} catch {\n\t\t\t// transient — next poll tick recovers\n\t\t}\n\t}\n\n\tfunction broadcastReaction(emoji: string) {\n\t\tchannelHandle?.broadcastReaction(emoji);\n\t}\n\n\tasync function submitComment(body: string): Promise<{ ok: boolean; error?: string }> {\n\t\tif (!duel) return { ok: false, error: 'no_duel' };\n\t\tconst res = await fetch(`/api/duel/comment/${duel.code}`, {\n\t\t\tmethod: 'POST',\n\t\t\theaders: { 'Content-Type': 'application/json' },\n\t\t\tbody: JSON.stringify({ body })\n\t\t});\n\t\tif (res.ok) {\n\t\t\tconst d = (await res.json()) as { comment: DuelCommentData };\n\t\t\tchannelHandle?.broadcastComment(d.comment);\n\t\t\tcomments = [...comments, d.comment];\n\t\t\treturn { ok: true };\n\t\t}\n\t\tconst err = await res.json().catch(() => ({}));\n\t\treturn { ok: false, error: err?.error ?? 'failed' };\n\t}\n\n\tasync function submitVoice(audio: Blob, durationSec: number): Promise<{ ok: boolean; error?: string }> {\n\t\tif (!duel) return { ok: false, error: 'no_duel' };\n\t\tconst fd = new FormData();\n\t\tfd.append('audio', audio);\n\t\tfd.append('durationSec', String(durationSec));\n\t\tconst res = await fetch(`/api/duel/voice/${duel.code}`, { method: 'POST', body: fd });\n\t\tif (res.ok) {\n\t\t\tconst d = (await res.json()) as { comment: DuelCommentData };\n\t\t\tchannelHandle?.broadcastComment(d.comment);\n\t\t\tcomments = [...comments, d.comment];\n\t\t\treturn { ok: true };\n\t\t}\n\t\tconst err = await res.json().catch(() => ({}));\n\t\treturn { ok: false, error: err?.error ?? 'failed' };\n\t}\n\n\t// ─── Derived presence states for the PresenceBar ─────────────────────\n\tconst opponentPresenceState = $derived.by<'absent' | 'joined' | 'uploading' | 'rating' | 'ready'>(() => {\n\t\tif (!firstEntry) return 'absent';\n\t\tif (firstEntry.status === 'pending') return 'uploading';\n\t\tif (firstEntry.status === 'processing') return 'rating';\n\t\tif (firstEntry.status === 'completed') return 'ready';\n\t\treturn 'joined';\n\t});\n\tconst challengerPresenceState = $derived.by<'locked' | 'rating' | 'waiting'>(() => {\n\t\tif (challengerProcessing) return 'rating';\n\t\treturn 'locked';\n\t});\n\tconst watcherCount = $derived(presences.filter((p) => p.role === 'spectator').length);\n\n\t// ─── Main state machine (view router) ────────────────────────────────\n\tconst myEntry = $derived(entryId ? entries.find((e) => e.id === entryId) : null);\n\n\ttype View =\n\t\t| 'not-found'\n\t\t| 'expired'\n\t\t| 'challenger-processing'\n\t\t| 'lobby'\n\t\t| 'fomo'\n\t\t| 'auth-email'\n\t\t| 'auth-otp'\n\t\t| 'opponent-processing'\n\t\t| 'opponent-failed'\n\t\t| 'countdown'\n\t\t| 'revealed';\n\n\tconst view = $derived.by<View>(() => {\n\t\tif (notFound || !duel) return 'not-found';\n\t\t// `revealed=true` without a completed first entry means the duel is in\n\t\t// an inconsistent state (challenger pressed reveal before anyone joined,\n\t\t// or a stale row from an old flow). Fall through to lobby/fomo so the\n\t\t// page renders something useful instead of a blank stage.\n\t\tif (duel.revealed && firstEntry?.status === 'completed') return 'revealed';\n\t\tif (duel.status === 'expired' || duel.status === 'closed') return 'expired';\n\t\t// Both rated + countdown armed → synchronized countdown\n\t\tif (duel.countdownStartedAt && firstEntry?.status === 'completed' && !challengerProcessing) {\n\t\t\treturn 'countdown';\n\t\t}\n\t\t// Challenger side — always show lobby so share CTA is immediately available\n\t\tif (isChallenger) {\n\t\t\treturn 'lobby';\n\t\t}\n\t\t// Opponent with existing entry\n\t\tif (myEntry) {\n\t\t\t// A re-run is in flight — hold the analyzing view over the failure screen.\n\t\t\tif (retrying) return 'opponent-processing';\n\t\t\t// Server-marked failure, or the client-side poll timed out on a hang.\n\t\t\tif (myEntry.status === 'failed' || analysisTimedOut) return 'opponent-failed';\n\t\t\t// Team modes: drop joiners straight into the lobby as soon as their\n\t\t\t// entry exists, even while analysis is still running. The team roster\n\t\t\t// surfaces their card with `rating…` status and they can watch the\n\t\t\t// squad fill or share the link instead of staring at a loader. Their\n\t\t\t// analysis runs in the background and updates the card to `locked in`\n\t\t\t// when done — much better than blocking on a 30s Claude call.\n\t\t\tif (duel.format !== '1v1') return 'lobby';\n\t\t\t// 1v1: hold on the processing view until the countdown is armed. The\n\t\t\t// gap between \"entry done\" and \"countdown armed\" is ~seconds (just the\n\t\t\t// AI head-to-head call), so bouncing through lobby is jarring.\n\t\t\tif (myEntry.status === 'completed' && duel.countdownStartedAt) return 'lobby';\n\t\t\treturn 'opponent-processing';\n\t\t}\n\t\t// Opponent-new\n\t\tif (joinStep === 'email') return 'auth-email';\n\t\tif (joinStep === 'otp') return 'auth-otp';\n\t\treturn 'fomo';\n\t});\n\n\tconst isLiveView = $derived(\n\t\tview === 'lobby' || view === 'fomo' || view === 'countdown' ||\n\t\tview === 'opponent-processing' || view === 'revealed' || view === 'challenger-processing'\n\t);\n\n\t// Real back-navigation for terminal states (expired / fallback). Most visitors\n\t// to a past duel arrive from somewhere on-site — their own profile activity\n\t// feed, another user's profile, or a challenge notification — so returning\n\t// them there beats a dead-end \"start your own\". history.back() lands on that\n\t// origin; fall back to the duel hub when there's no in-app history (cold link).\n\tfunction goBack() {\n\t\tif (browser && window.history.length > 1) {\n\t\t\twindow.history.back();\n\t\t} else {\n\t\t\tgoto('/d');\n\t\t}\n\t}\n\n\t// ─── 10-minute post-reveal chat window ──────────────────────────────\n\tconst CHAT_POST_REVEAL_MS = 10 * 60 * 1000;\n\tlet nowMs = $state(Date.now());\n\t$effect(() => {\n\t\tconst id = setInterval(() => { nowMs = Date.now(); }, 30_000);\n\t\treturn () => clearInterval(id);\n\t});\n\t// Reveal happens ~3s after countdownStartedAt (the countdown duration)\n\tconst revealedAtMs = $derived.by(() => {\n\t\tif (!duel?.countdownStartedAt) return null;\n\t\treturn new Date(duel.countdownStartedAt).getTime() + 3000;\n\t});\n\tconst chatExpired = $derived(\n\t\t!!duel?.revealed && !!revealedAtMs && (nowMs - revealedAtMs) > CHAT_POST_REVEAL_MS\n\t);\n\t// Dock (chat / talk-sh*t bar) stays hidden in the pre-join `fomo` state — it\n\t// pre-primes login and competes with the upload CTA. Chat earns its place\n\t// once the viewer has joined / while the result loader spins.\n\tconst showDock = $derived(isLiveView && view !== 'fomo' && !chatExpired);\n\n\t// The short loader views (synced countdown + the \"analyzing…\" spinners) fit\n\t// the viewport with room to spare. Lock document scroll while they're on\n\t// screen so focusing the chat dock's input (mobile keyboard) can't drag the\n\t// loader up the page — `min-h-screen` on <main> otherwise leaves iOS just\n\t// enough scrollable slack to yank it.\n\tconst loaderView = $derived(\n\t\tview === 'countdown' || view === 'opponent-processing' || view === 'challenger-processing'\n\t);\n\t$effect(() => {\n\t\tif (!loaderView) return;\n\t\tconst html = document.documentElement;\n\t\tconst prevHtml = html.style.overflow;\n\t\tconst prevBody = document.body.style.overflow;\n\t\thtml.style.overflow = 'hidden';\n\t\tdocument.body.style.overflow = 'hidden';\n\t\treturn () => {\n\t\t\thtml.style.overflow = prevHtml;\n\t\t\tdocument.body.style.overflow = prevBody;\n\t\t};\n\t});\n\n\t// Batch 23: focus-mode (lobby = \"created/share\" screen + fomo = invitee\n\t// landing) hides the bottom nav so the chat dock is the only bottom\n\t// chrome. Result view (revealed) intentionally does NOT enter focus\n\t// mode — the user needs the nav back to leave the page. BottomNav.svelte\n\t// + layout.css both react to the body class.\n\t//\n\t// RAT-280: also enter focus mode on the loader views (countdown,\n\t// opponent-processing, challenger-processing). These are short\n\t// \"analyzing…\" screens where the nav is just noise — the chat dock\n\t// already provides the only meaningful action surface.\n\tconst duelFocusMode = $derived(\n\t\tview === 'lobby' || view === 'fomo' ||\n\t\tview === 'countdown' || view === 'opponent-processing' || view === 'challenger-processing'\n\t);\n\t$effect(() => {\n\t\tdocument.body.classList.toggle('duel-focus-mode', duelFocusMode);\n\t\treturn () => document.body.classList.remove('duel-focus-mode');\n\t});\n\n\t// ─── Fallback poll — runs alongside realtime as a correctness safety net.\n\t// Earlier this was gated on `realtimeHealthy` to skip when the WS subscribed,\n\t// but \"subscribed\" doesn't guarantee that postgres_changes events actually\n\t// deliver (publication misconfig, transient drops, table-level filters).\n\t// When that happened the joiner would sit on \"analyzing\" while the duel had\n\t// already revealed in the DB. So we always poll at 5s in non-terminal views;\n\t// realtime still drives sub-second updates when it works, but polling closes\n\t// the worst-case stuck-state window.\n\tlet viewPollInterval: ReturnType<typeof setInterval> | null = null;\n\t$effect(() => {\n\t\tconst terminalViews = ['revealed', 'expired', 'not-found', 'opponent-failed', 'auth-email', 'auth-otp', 'fomo'];\n\t\tconst shouldPoll = !!duel && !duel.revealed && !terminalViews.includes(view);\n\t\tif (shouldPoll && !viewPollInterval) {\n\t\t\tviewPollInterval = setInterval(() => invalidateAll(), 10000);\n\t\t}\n\t\tif (!shouldPoll && viewPollInterval) {\n\t\t\tclearInterval(viewPollInterval);\n\t\t\tviewPollInterval = null;\n\t\t}\n\t});\n\n\t// Mirrors the duel-state poll above but for the chat. Lives separately\n\t// because the chat survives reveal (10-min post-reveal window) while the\n\t// duel-state poll stops at terminal views. Skips when the tab is hidden.\n\t$effect(() => {\n\t\tif (!duel || !showDock) {\n\t\t\tif (commentPollInterval) {\n\t\t\t\tclearInterval(commentPollInterval);\n\t\t\t\tcommentPollInterval = null;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (commentPollInterval) return;\n\t\tcommentPollInterval = setInterval(() => {\n\t\t\tif (typeof document !== 'undefined' && document.hidden) return;\n\t\t\tif (duel) fetchAndMergeComments(duel.code);\n\t\t}, 6000);\n\t});\n\n\t// ─── Countdown → reveal trigger ─────────────────────────────────────\n\tasync function onCountdownComplete() {\n\t\tif (!duel || finalizeInFlight) return;\n\t\tfinalizeInFlight = true;\n\t\ttry {\n\t\t\tawait fetch(`/api/duel/reveal/${duel.code}`, { method: 'POST' });\n\t\t\tawait invalidateAll();\n\t\t} finally {\n\t\t\tfinalizeInFlight = false;\n\t\t}\n\t}\n\n\t// ─── Image / auth / submit helpers ───────────────────────────────────\n\tconst MAX_IMAGE_BYTES = 4 * 1024 * 1024;\n\tconst MAX_DIMENSION = 4000;\n\n\tfunction startOtpCooldown() {\n\t\tconst seconds = 60 + Math.min(otpResendCount, 3) * 30;\n\t\totpCooldown = seconds;\n\t\tif (cooldownInterval) clearInterval(cooldownInterval);\n\t\tcooldownInterval = setInterval(() => {\n\t\t\totpCooldown--;\n\t\t\tif (otpCooldown <= 0) {\n\t\t\t\totpCooldown = 0;\n\t\t\t\tif (cooldownInterval) { clearInterval(cooldownInterval); cooldownInterval = null; }\n\t\t\t}\n\t\t}, 1000);\n\t}\n\n\tasync function compressImage(file: File): Promise<File> {\n\t\treturn new Promise((resolve) => {\n\t\t\tconst img = new Image();\n\t\t\tconst url = URL.createObjectURL(file);\n\t\t\timg.onload = async () => {\n\t\t\t\tURL.revokeObjectURL(url);\n\t\t\t\tlet { naturalWidth: w, naturalHeight: h } = img;\n\t\t\t\tif (w > MAX_DIMENSION || h > MAX_DIMENSION) {\n\t\t\t\t\tconst s = MAX_DIMENSION / Math.max(w, h);\n\t\t\t\t\tw = Math.round(w * s); h = Math.round(h * s);\n\t\t\t\t}\n\t\t\t\tconst canvas = document.createElement('canvas');\n\t\t\t\tcanvas.width = w; canvas.height = h;\n\t\t\t\tcanvas.getContext('2d')!.drawImage(img, 0, 0, w, h);\n\t\t\t\tlet quality = 0.85;\n\t\t\t\tlet blob: Blob | null = null;\n\t\t\t\twhile (quality > 0.3) {\n\t\t\t\t\tblob = await new Promise<Blob | null>((r) => canvas.toBlob(r, 'image/jpeg', quality));\n\t\t\t\t\tif (blob && blob.size <= MAX_IMAGE_BYTES) break;\n\t\t\t\t\tquality -= 0.1;\n\t\t\t\t}\n\t\t\t\tif (blob) resolve(new File([blob], file.name.replace(/\\.[^.]+$/, '.jpg'), { type: 'image/jpeg' }));\n\t\t\t\telse resolve(file);\n\t\t\t};\n\t\t\timg.onerror = () => { URL.revokeObjectURL(url); resolve(file); };\n\t\t\timg.src = url;\n\t\t});\n\t}\n\n\tasync function handleFile(file: File | undefined) {\n\t\tif (!file) return;\n\t\tsubmitError = '';\n\t\t// The HEIC sniff reads the file, and a file that can't be read at all\n\t\t// throws there — said under the picker instead of dropped (see pickFailure).\n\t\tlet rasterized: File;\n\t\ttry {\n\t\t\trasterized = await heicToJpeg(file);\n\t\t} catch (err) {\n\t\t\tconst fail = pickFailure(err);\n\t\t\tanalytics.trackUploadFail({ error: fail.error, context: 'duel_join_pick', stale: fail.stale });\n\t\t\tsubmitError = fail.message;\n\t\t\treturn;\n\t\t}\n\t\tselectedFile = await compressImage(rasterized);\n\t}\n\n\t// Logged-out signup hook: the row is labelled \"Sign up\", so it must actually\n\t// start account creation — raise the in-place AuthSheet (next = this duel so\n\t// they land back here to accept), not the file picker (RAT: signup affordance).\n\t// One exception: once a file is staged the sheet would drop it. Its Google\n\t// button full-page redirects without writing this duel's resume entry, so the\n\t// user returns to `?oauth_resume=1` with consumeResume() -> null and an empty\n\t// upload zone. Keep the page's own resume-backed email step in that case —\n\t// its OAuthButtonRow runs prepareOAuthRedirect, which uploads + saves first.\n\tfunction openJoinPicker() {\n\t\tif (selectedFile) {\n\t\t\tgoToEmailStep();\n\t\t\treturn;\n\t\t}\n\t\topenAuthSheet(duel ? `/d/${duel.code}` : undefined, 'duel_join_reuse');\n\t}\n\n\t// Photo reuse: pull the saved photo down as a File so the joiner can accept\n\t// the duel with it. No auto-submit — \"accept the challenge\" stays the step.\n\tasync function useSavedPhotoJoin() {\n\t\tif (data.notFound || !data.lastPhotoUrl) return;\n\t\ttry {\n\t\t\tconst res = await fetch(data.lastPhotoUrl);\n\t\t\tconst blob = await res.blob();\n\t\t\tselectedFile = new File([blob], 'reused.jpg', { type: blob.type || 'image/jpeg' });\n\t\t} catch {\n\t\t\tsubmitError = t('could not load your saved photo — upload a new one.');\n\t\t}\n\t}\n\n\tasync function uploadImage(): Promise<string | null> {\n\t\tif (!selectedFile) return null;\n\t\ttry {\n\t\t\t// Signed upload: the server names the path (owner folder).\n\t\t\tconst { path, error } = await uploadSubmissionPhoto(supabase, selectedFile, 'duel');\n\t\t\tif (error) console.error('Upload failed:', error.message);\n\t\t\treturn path;\n\t\t} catch (err) {\n\t\t\tconsole.error('Upload threw:', err);\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tasync function callAction(action: string, fields: Record<string, string>) {\n\t\tconst fd = new FormData();\n\t\tfor (const [k, v] of Object.entries(fields)) fd.append(k, v);\n\t\tconst code = data.notFound ? '' : data.duel.code;\n\t\tconst response = await fetch(`/d/${code}?/${action}`, { method: 'POST', body: fd });\n\t\treturn deserialize(await response.text());\n\t}\n\n\n\tasync function submitDirectly() {\n\t\tif (!selectedFile) return;\n\t\tsubmitting = true; submitError = '';\n\t\tconst imagePath = await uploadImage();\n\t\tif (!imagePath) { submitError = t('image upload failed. try a different photo.'); submitting = false; return; }\n\t\tconst result = await callAction('submitEntry', {\n\t\t\timagePath,\n\t\t\tsavePhoto: savePhoto ? 'true' : 'false',\n\t\t\treferrer: document.referrer,\n\t\t\tutm_source: new URLSearchParams(window.location.search).get('utm_source') ?? '',\n\t\t\tsrc: new URLSearchParams(window.location.search).get('src') ?? ''\n\t\t});\n\t\tsubmitting = false;\n\t\tif (result.type === 'success') {\n\t\t\tconst d = result.data as Record<string, unknown>;\n\t\t\tentryId = (d?.entryId as string) || null;\n\t\t\tif (entryId) {\n\t\t\t\tstartProcessing(entryId);\n\t\t\t\tawait invalidateAll();\n\t\t\t}\n\t\t} else if (result.type === 'failure') {\n\t\t\tsubmitError = ((result.data as Record<string, unknown> | undefined)?.error as string) || t('something went wrong');\n\t\t} else if (result.type === 'error') {\n\t\t\tsubmitError = t('server error ({status})', { status: result.status ?? 500 });\n\t\t}\n\t}\n\n\tfunction goToEmailStep() {\n\t\tif (!selectedFile) return;\n\t\twindow.scrollTo({ top: 0, behavior: 'smooth' });\n\t\tsetTimeout(() => { joinStep = 'email'; }, 250);\n\t}\n\n\t// RAT-165: OAuth resume for duel-join. Pre-redirect: upload image +\n\t// stash path under a code-scoped key so duel A's resume can't pollute\n\t// duel B if the user opens both. Post-redirect: if there's a session\n\t// and a resume entry for THIS duel code, run the same code path that\n\t// submitDirectly uses (logged-in submit).\n\tfunction resumeKey(code: string): string {\n\t\treturn `duel-code-${code}`;\n\t}\n\tasync function prepareOAuthRedirect(): Promise<boolean> {\n\t\tif (!duel) return false;\n\t\tif (!selectedFile) {\n\t\t\tjoinStep = 'fomo';\n\t\t\treturn false;\n\t\t}\n\t\tsubmitError = '';\n\t\tconst path = uploadedImagePath ?? (await uploadImage());\n\t\tif (!path) {\n\t\t\tsubmitError = t('image upload failed. try a different photo.');\n\t\t\treturn false;\n\t\t}\n\t\tuploadedImagePath = path;\n\t\treturn saveResume<DuelCodeResume>(resumeKey(duel.code), { imagePath: path });\n\t}\n\n\tasync function submitEmail() {\n\t\temailError = '';\n\t\tif (!email || !email.includes('@')) { emailError = t('please enter a valid email address.'); return; }\n\t\temailSending = true;\n\t\tif (!uploadedImagePath) {\n\t\t\tconst path = await uploadImage();\n\t\t\tif (!path) { emailError = t('image upload failed.'); emailSending = false; return; }\n\t\t\tuploadedImagePath = path;\n\t\t}\n\t\tconst result = await callAction('sendOtp', { email });\n\t\temailSending = false;\n\t\tif (result.type === 'success') {\n\t\t\tstartOtpCooldown();\n\t\t\twindow.scrollTo({ top: 0, behavior: 'smooth' });\n\t\t\tjoinStep = 'otp';\n\t\t} else if (result.type === 'failure') {\n\t\t\temailError = ((result.data as Record<string, unknown> | undefined)?.error as string) || t('something went wrong.');\n\t\t}\n\t}\n\n\tasync function resendOtp() {\n\t\totpError = '';\n\t\tconst result = await callAction('resendOtp', { email });\n\t\tif (result.type === 'success') { otpResendCount++; startOtpCooldown(); }\n\t\telse if (result.type === 'failure') {\n\t\t\totpError = ((result.data as Record<string, unknown> | undefined)?.error as string) || t('failed to resend.');\n\t\t}\n\t}\n\n\tasync function verifyOtp() {\n\t\totpError = '';\n\t\tif (!otpCode || otpCode.length < 6) { otpError = t('enter the 6-digit code from your email.'); return; }\n\t\totpVerifying = true;\n\t\tconst { error } = await supabase.auth.verifyOtp({ email, token: otpCode, type: 'email' });\n\t\totpVerifying = false;\n\t\tif (error) { otpError = t('invalid or expired code.'); return; }\n\t\tanalytics.trackSignInComplete();\n\t\tsubmitting = true; submitError = '';\n\t\tconst result = await callAction('submitEntry', {\n\t\t\timagePath: uploadedImagePath || '',\n\t\t\treferrer: document.referrer,\n\t\t\tutm_source: new URLSearchParams(window.location.search).get('utm_source') ?? '',\n\t\t\tsrc: new URLSearchParams(window.location.search).get('src') ?? ''\n\t\t});\n\t\tsubmitting = false;\n\t\tif (result.type === 'success') {\n\t\t\tconst d = result.data as Record<string, unknown>;\n\t\t\tentryId = (d?.entryId as string) || null;\n\t\t\tif (entryId) {\n\t\t\t\tstartProcessing(entryId);\n\t\t\t\tawait invalidateAll();\n\t\t\t}\n\t\t} else if (result.type === 'failure') {\n\t\t\tsubmitError = ((result.data as Record<string, unknown> | undefined)?.error as string) || t('something went wrong');\n\t\t} else if (result.type === 'error') {\n\t\t\tsubmitError = t('server error ({status}). check console.', { status: result.status ?? 500 });\n\t\t\tconsole.error('[duel submitEntry via OTP] server error:', result);\n\t\t}\n\t}\n\n\t// Client backstop for a hung analysis. The server bounds its vision call at 45s;\n\t// this sits above that (server-marked failures surface first, with their real\n\t// message) and only trips when the server function died outright.\n\tconst ANALYSIS_HARD_TIMEOUT_MS = 75_000;\n\n\t// Retry a failed entry in place. The server keeps the source photo on failure now,\n\t// so a re-run re-downloads it — no re-upload, no brand-new duel. `startProcessing`\n\t// re-POSTs to kick the analysis (the endpoint re-runs a failed+retryable entry) and\n\t// restarts the poll; `retrying` holds the analyzing view over the failure screen for\n\t// the whole re-run and is cleared by the poll once it reaches a terminal state.\n\tfunction retryAnalysis() {\n\t\tif (!entryId) return;\n\t\tanalysisTimedOut = false;\n\t\tsubmitError = '';\n\t\tretrying = true;\n\t\tstartProcessing(entryId);\n\t}\n\n\tfunction startProcessing(id: string) {\n\t\t// Kick off the analysis. A transient network failure here must not surface\n\t\t// as an uncaught rejection — the poll below is the safety net that drives\n\t\t// the screen forward regardless.\n\t\t//\n\t\t// One response we do read: `retryable: false` means this entry can never be\n\t\t// re-run in place (its photo is gone, or the caller doesn't own it). Every\n\t\t// `failed` row written before the photo-retention fix is in that state, so\n\t\t// without this the \"try again\" button spins for one poll and lands back on\n\t\t// the same failure screen, forever. Say so and point at the path that works.\n\t\tfetch(`/api/duel/entry/${id}`, { method: 'POST' })\n\t\t\t.then(async (res) => {\n\t\t\t\tif (res.ok) return;\n\t\t\t\tconst body = await res.json().catch(() => null);\n\t\t\t\tif (body?.retryable === false) {\n\t\t\t\t\tif (pollInterval) {\n\t\t\t\t\t\tclearInterval(pollInterval);\n\t\t\t\t\t\tpollInterval = null;\n\t\t\t\t\t}\n\t\t\t\t\tretrying = false;\n\t\t\t\t\tanalysisTimedOut = false;\n\t\t\t\t\tsubmitError =\n\t\t\t\t\t\tbody.error === 'retry_not_permitted'\n\t\t\t\t\t\t\t? t(\"this attempt can't be re-run here — upload a different photo to try again.\")\n\t\t\t\t\t\t\t: t(\"this attempt can't be re-run — upload a different photo to try again.\");\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch(() => {});\n\t\t// Poll entry status as a correctness safety net — realtime is best-effort.\n\t\t// Earlier we gated on `realtimeHealthy` here too, which led to the joiner\n\t\t// being stuck on the analyzing screen forever when realtime \"subscribed\"\n\t\t// but never delivered the postgres_changes event. Always polling at 3s costs\n\t\t// at most ~2-3 HTTP roundtrips per analysis (which now finishes in ~7s).\n\t\tif (pollInterval) clearInterval(pollInterval);\n\t\tanalysisTimedOut = false;\n\t\tconst startedAt = Date.now();\n\t\t// Only foreground time counts toward the ceiling. Switching apps during a\n\t\t// ~7s analysis is routine on a phone, and a backgrounded tab throttles this\n\t\t// interval to roughly one tick a minute — so a plain wall clock hands the\n\t\t// returning user a timeout screen over an analysis that finished fine.\n\t\tlet hiddenMs = 0;\n\t\tlet hiddenSince = 0;\n\t\tconst onVisibility = () => {\n\t\t\tif (document.hidden) hiddenSince = Date.now();\n\t\t\telse if (hiddenSince) {\n\t\t\t\thiddenMs += Date.now() - hiddenSince;\n\t\t\t\thiddenSince = 0;\n\t\t\t}\n\t\t};\n\t\tdocument.addEventListener('visibilitychange', onVisibility);\n\t\tconst elapsedVisible = () =>\n\t\t\tDate.now() - startedAt - hiddenMs - (hiddenSince ? Date.now() - hiddenSince : 0);\n\t\tconst endPoll = () => {\n\t\t\tif (pollInterval) {\n\t\t\t\tclearInterval(pollInterval);\n\t\t\t\tpollInterval = null;\n\t\t\t}\n\t\t\tdocument.removeEventListener('visibilitychange', onVisibility);\n\t\t\tstopStatusPoll = null;\n\t\t};\n\t\tstopStatusPoll?.();\n\t\tstopStatusPoll = endPoll;\n\t\tlet ticks = 0;\n\t\tlet consecutiveFailures = 0;\n\t\tpollInterval = setInterval(async () => {\n\t\t\tticks++;\n\t\t\t// A network blip mid-poll rejects the fetch. Because this runs inside an\n\t\t\t// async setInterval callback, an unguarded rejection surfaces as an\n\t\t\t// uncaught `TypeError: Failed to fetch` and silently kills the poll,\n\t\t\t// stranding the joiner on the analyzing screen. Swallow it and let the\n\t\t\t// next 3s tick retry.\n\t\t\ttry {\n\t\t\t\tconst res = await fetch(`/api/duel/entry/${id}`);\n\t\t\t\t// The request itself completed, so the network is healthy — reset the\n\t\t\t\t// streak even on a non-2xx (that's a server problem, not a network one).\n\t\t\t\tconsecutiveFailures = 0;\n\t\t\t\tif (!res.ok) return;\n\t\t\t\tconst d = (await res.json()) as { status: string; errorMessage?: string | null };\n\t\t\t\t// Hard ceiling on the wait, evaluated only against a status we just\n\t\t\t\t// read. The server bounds its own analyze call below maxDuration and\n\t\t\t\t// marks the row `failed` on a hang, so this only fires in the residual\n\t\t\t\t// case where the whole function died before it could — but without it\n\t\t\t\t// the loader would ease to 92% and spin there indefinitely.\n\t\t\t\tif (\n\t\t\t\t\td.status !== 'completed' &&\n\t\t\t\t\td.status !== 'failed' &&\n\t\t\t\t\telapsedVisible() > ANALYSIS_HARD_TIMEOUT_MS\n\t\t\t\t) {\n\t\t\t\t\tendPoll();\n\t\t\t\t\tretrying = false;\n\t\t\t\t\tanalysisTimedOut = true;\n\t\t\t\t\tanalytics.trackAnalysisFail('duel_timeout', 'duel');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (d.status === 'completed' || d.status === 'failed') {\n\t\t\t\t\tendPoll();\n\t\t\t\t\t// The duel failure path used to emit nothing to PostHog (only a\n\t\t\t\t\t// server-side logError), so every duel analysis failure was invisible\n\t\t\t\t\t// in analytics — `analysis_fail` carried `flow: 'rate'` almost\n\t\t\t\t\t// exclusively. Emit it here with `flow: 'duel'` so these are visible.\n\t\t\t\t\tif (d.status === 'failed') {\n\t\t\t\t\t\tanalytics.trackAnalysisFail(d.errorMessage || 'unknown', 'duel');\n\t\t\t\t\t}\n\t\t\t\t\tawait invalidateAll();\n\t\t\t\t\t// Release the retry hold only after fresh data lands, so the view\n\t\t\t\t\t// derives the real terminal state (completed → lobby, failed → retry)\n\t\t\t\t\t// instead of flickering off the analyzing screen mid-reload.\n\t\t\t\t\tretrying = false;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// The POST kick above is the ONLY thing that moves an entry out of\n\t\t\t\t// `pending` — no cron sweeps stale pending duel entries, and the\n\t\t\t\t// $effect that would re-kick is gated on `!pollInterval`, which this\n\t\t\t\t// very function has already set. So a dropped kick strands the entry\n\t\t\t\t// as `pending` forever. Re-kick every 4th tick (~12s); the endpoint\n\t\t\t\t// 400s with `already started` unless the status is still `pending`,\n\t\t\t\t// so this is a harmless no-op once analysis is actually running.\n\t\t\t\tif (d.status === 'pending' && ticks % 4 === 0) {\n\t\t\t\t\tfetch(`/api/duel/entry/${id}`, { method: 'POST' }).catch(() => {});\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Transient — the next 3s tick retries. But a *permanently* failing\n\t\t\t\t// poll would otherwise spin every 3s in total silence, since PostHog's\n\t\t\t\t// capture_exceptions only sees UNCAUGHT rejections. Emit exactly one\n\t\t\t\t// signal per failure episode (~15s in); a success resets the streak.\n\t\t\t\tconsecutiveFailures++;\n\t\t\t\tif (consecutiveFailures === 5) {\n\t\t\t\t\tconsole.warn(`[duel] status poll for entry ${id} failed 5x in a row (~15s) — network down?`);\n\t\t\t\t\tanalytics.trackAnalysisFail('duel_poll_network', 'duel');\n\t\t\t\t}\n\t\t\t}\n\t\t}, 3000);\n\t}\n\n\t// Re-kick the poll when a fresh load shows the entry still in flight. Gated on\n\t// `analysisTimedOut` because the row stays `processing` after we give up on\n\t// it: without the gate, any later invalidateAll (a realtime duel/entry update,\n\t// e.g. the challenger commenting) re-enters this branch, and startProcessing\n\t// resets the flag — snapping the user off the escape-hatch screen back onto\n\t// the 92% ring, to time out again 75s later, in a loop. Only an explicit\n\t// retryAnalysis() clears the flag.\n\t$effect(() => {\n\t\tif (entryId && !pollInterval && !data.notFound && !analysisTimedOut) {\n\t\t\tconst existing = data.entries.find((e) => e.id === entryId);\n\t\t\tif (existing && (existing.status === 'pending' || existing.status === 'processing')) {\n\t\t\t\tstartProcessing(entryId);\n\t\t\t}\n\t\t}\n\t});\n\n\tonMount(() => {\n\t\tif (data.notFound) return;\n\t\tconst code = data.duel.code;\n\t\tconst sessionKey = `ph_duel_visited_${code}`;\n\t\tconst isFirstVisit = !sessionStorage.getItem(sessionKey);\n\t\tsessionStorage.setItem(sessionKey, '1');\n\t\tconst utmSource = new URLSearchParams(window.location.search).get('utm_source');\n\t\tanalytics.trackDuelLinkVisited(\n\t\t\tcode,\n\t\t\tdata.duel.challengerId,\n\t\t\tdocument.referrer || null,\n\t\t\tutmSource,\n\t\t\tisFirstVisit,\n\t\t\t!!data.session\n\t\t);\n\n\t\t// RAT-165: OAuth resume for joining this duel. Mirrors submitDirectly's\n\t\t// happy path. We deliberately await callAction inside an async IIFE so\n\t\t// the synchronous analytics call above isn't held back.\n\t\tif (data.session && !data.notFound) {\n\t\t\tconst resume = consumeResume<DuelCodeResume>(resumeKey(code));\n\t\t\tif (resume) {\n\t\t\t\tsubmitting = true;\n\t\t\t\tsubmitError = '';\n\t\t\t\t(async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await callAction('submitEntry', {\n\t\t\t\t\t\t\timagePath: resume.imagePath,\n\t\t\t\t\t\t\treferrer: document.referrer,\n\t\t\t\t\t\t\tutm_source: utmSource ?? '',\n\t\t\t\t\t\t\tsrc: new URLSearchParams(window.location.search).get('src') ?? ''\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (result.type === 'success') {\n\t\t\t\t\t\t\tconst d = result.data as Record<string, unknown>;\n\t\t\t\t\t\t\tentryId = (d?.entryId as string) || null;\n\t\t\t\t\t\t\tif (entryId) {\n\t\t\t\t\t\t\t\tstartProcessing(entryId);\n\t\t\t\t\t\t\t\tawait invalidateAll();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// invalidateAll triggers a re-derive of `view` to\n\t\t\t\t\t\t\t// 'opponent-processing' — drop the bridge here.\n\t\t\t\t\t\t\toauthResumeIncoming = false;\n\t\t\t\t\t\t\tclearOauthResumeFlag();\n\t\t\t\t\t\t} else if (result.type === 'failure') {\n\t\t\t\t\t\t\tsubmitError = ((result.data as Record<string, unknown> | undefined)?.error as string) || t('something went wrong picking up where you left off.');\n\t\t\t\t\t\t\toauthResumeIncoming = false;\n\t\t\t\t\t\t\tclearOauthResumeFlag();\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tconsole.error('OAuth resume failed (duel/[code]):', err);\n\t\t\t\t\t\tsubmitError = t('something went wrong picking up where you left off.');\n\t\t\t\t\t\toauthResumeIncoming = false;\n\t\t\t\t\t\tclearOauthResumeFlag();\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tsubmitting = false;\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t} else {\n\t\t\t\toauthResumeIncoming = false;\n\t\t\t\tclearOauthResumeFlag();\n\t\t\t}\n\t\t} else {\n\t\t\toauthResumeIncoming = false;\n\t\t\tclearOauthResumeFlag();\n\t\t}\n\t});\n\n\t// RAT-27: post-duel follow CTA shown event. Fires once per\n\t// (duel, opponent) for the inline CTA right under the matchup. The CTA\n\t// only renders for revealed 1v1s where the viewer is a participant whose\n\t// opponent has a registered account they don't already follow — same data\n\t// the server pre-computed into data.followOpponent.\n\t$effect(() => {\n\t\tif (view !== 'revealed') return;\n\t\tif (!duel || duel.format !== '1v1') return;\n\t\tconst fo = data.followOpponent;\n\t\tif (!fo || fo.viewerFollows) return;\n\t\tconst key = `ph_post_duel_cta_${duel.code}_${fo.userId}`;\n\t\ttry {\n\t\t\tif (sessionStorage.getItem(key)) return;\n\t\t\tsessionStorage.setItem(key, '1');\n\t\t} catch {\n\t\t\t// privacy mode — fire anyway, accept duplicates\n\t\t}\n\t\tanalytics.trackPostDuelFollowCtaShown({\n\t\t\tduelCode: duel.code,\n\t\t\topponentUserId: fo.userId\n\t\t});\n\t});\n\n\t// ─── Waitlist (spectators) ──────────────────────────────────────────\n\tlet waitlistEmail = $state('');\n\tlet waitlistSubmitting = $state(false);\n\tlet waitlistDone = $state(false);\n\tlet waitlistError = $state('');\n\tasync function submitWaitlist() {\n\t\tif (!waitlistEmail.includes('@') || !duel) return;\n\t\twaitlistSubmitting = true; waitlistError = '';\n\t\ttry {\n\t\t\tconst res = await fetch('/api/duel/waitlist', {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders: { 'Content-Type': 'application/json' },\n\t\t\t\tbody: JSON.stringify({ email: waitlistEmail, code: duel.code })\n\t\t\t});\n\t\t\tif (res.ok) { waitlistDone = true; }\n\t\t\telse { const d = await res.json(); waitlistError = d.error || t('something went wrong'); }\n\t\t} catch { waitlistError = t('network error'); }\n\t\twaitlistSubmitting = false;\n\t}\n\n\t// ─── Derived reveal values ──────────────────────────────────────────\n\tconst myScore = $derived(myEntry?.score ?? 0);\n\tconst myResults = $derived(myEntry?.results as AnalysisResults | null);\n\n\t// ─── Result page tertiary share ──────────────────────────────────────\n\tlet resultShareCopied = $state(false);\n\tasync function copyResultLink() {\n\t\tif (!duel) return;\n\t\tconst utmSource = duel.format === '1v1' ? 'duel_share' : `duel_share_${duel.format}`;\n\t\t// www host directly — skips the apex→www 307 redirect on share opens.\n\t\tconst url = `https://www.ratemyd.app/d/${duel.code}?utm_source=${utmSource}`;\n\t\ttry {\n\t\t\tawait navigator.clipboard.writeText(url);\n\t\t\tresultShareCopied = true;\n\t\t\tanalytics.trackDuelLinkShared(duel.code, 'copy_link', isChallenger, 'result_page');\n\t\t\tsetTimeout(() => (resultShareCopied = false), 2000);\n\t\t} catch { /* ignore */ }\n\t}\n\n\t// ─── Result page share-image (RAT-67) ────────────────────────────────\n\t// Pulls the server-rendered 1080x1350 PNG and either hands it to the native\n\t// share sheet (mobile → Reddit/Discord/IG/X in one tap) or triggers a blob\n\t// download on desktop. The endpoint caches PNGs in Supabase Storage so the\n\t// chromium cold start only hits the first sharer.\n\tlet shareImageInFlight = $state(false);\n\tlet shareImageStatus = $state<'idle' | 'shared' | 'downloaded' | 'error'>('idle');\n\tconst shareImageUrl = $derived(duel ? `/api/duel/${duel.code}/share.png?v=3` : '');\n\n\t// Perf: fire a single fetch to the share-card endpoint as soon as the page\n\t// reaches the revealed state. Server-side this triggers chromium render +\n\t// supabase storage upload (~3-5s cold start), so by the time the user\n\t// reads the matchup and reaches for the \"download the matchup\" button, the\n\t// PNG is already in storage cache and the click resolves in <100ms.\n\t// Browser also caches the response (Cache-Control immutable) so the\n\t// subsequent fetch from `shareImage()` doesn't even hit the network.\n\tlet prewarmFired = $state(false);\n\t$effect(() => {\n\t\tif (!duel?.revealed || !duel.code || prewarmFired || typeof window === 'undefined') return;\n\t\tprewarmFired = true;\n\t\t// fire-and-forget; failure is harmless (the click path will retry).\n\t\tfetch(`/api/duel/${duel.code}/share.png?v=3`, { mode: 'same-origin', credentials: 'omit' }).catch(() => {});\n\t});\n\n\t// \"where to post\" modal — same component used by the lobby ShareLink, but\n\t// here we open it directly from the revealed view with the save-image step\n\t// turned on so the Reddit-attach flow is one tap shorter.\n\tlet showResultCommunityModal = $state(false);\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tlet ResultCommunityModal = $state<any>(null);\n\tasync function openResultCommunityModal() {\n\t\tif (!duel) return;\n\t\tif (!ResultCommunityModal) {\n\t\t\tconst mod = await import('$lib/components/duel/ShareCommunityModal.svelte');\n\t\t\tResultCommunityModal = mod.default;\n\t\t}\n\t\tshowResultCommunityModal = true;\n\t\tanalytics.trackDuelCommunityModalOpen(duel.code, isChallenger, 'result_page');\n\t}\n\tconst resultShareUrl = $derived.by(() => {\n\t\tif (!duel) return '';\n\t\tconst utmSource = duel.format === '1v1' ? 'duel_share' : `duel_share_${duel.format}`;\n\t\treturn `https://www.ratemyd.app/d/${duel.code}?utm_source=${utmSource}`;\n\t});\n\n\t// Reddit honors ?title= on /r/{sub}/submit for any sub. Mirrors the\n\t// destroyed-headline so the post lands with the punchline already typed.\n\t// The \"ratemyd.app\" tail is non-clickable text on reddit, but it surfaces\n\t// the brand for users glancing at the title — and complements the watermark\n\t// + duel-code footer baked into the share card itself.\n\tconst resultPostTitle = $derived.by(() => {\n\t\tif (!duel || view !== 'revealed' || !firstEntry) return undefined;\n\t\tconst cName = duel.challengerNickname?.trim() || 'challenger';\n\t\tif (duel.format === '1v1') {\n\t\t\tconst eName = firstEntry.nickname?.trim() || 'contender';\n\t\t\tconst cScore = duel.challengerScore;\n\t\t\tconst eScore = Number(firstEntry.score) || 0;\n\t\t\tif (cScore > eScore) return `${cName} destroyed ${eName} — AI judged our duel @ ratemyd.app`;\n\t\t\tif (eScore > cScore) return `${eName} destroyed ${cName} — AI judged our duel @ ratemyd.app`;\n\t\t\treturn `dead tie at ${cScore.toFixed(1)}/10 — even the AI couldn't pick @ ratemyd.app`;\n\t\t}\n\t\t// team modes: challenger always sits on team A. compute from entries.\n\t\tconst teamAScores = [\n\t\t\tduel.challengerScore,\n\t\t\t...entries.filter((e) => e.teamPosition === 'A').map((e) => Number(e.score) || 0)\n\t\t];\n\t\tconst teamBScores = entries\n\t\t\t.filter((e) => e.teamPosition === 'B')\n\t\t\t.map((e) => Number(e.score) || 0);\n\t\tconst aAvg = teamAScores.reduce((s, x) => s + x, 0) / Math.max(teamAScores.length, 1);\n\t\tconst bAvg = teamBScores.reduce((s, x) => s + x, 0) / Math.max(teamBScores.length, 1);\n\t\tif (aAvg > bAvg) return `team a destroyed team b — AI judged our duel @ ratemyd.app`;\n\t\tif (bAvg > aAvg) return `team b destroyed team a — AI judged our duel @ ratemyd.app`;\n\t\treturn `dead tie at ${aAvg.toFixed(1)}/10 — even the AI couldn't pick @ ratemyd.app`;\n\t});\n\n\n\t// Touch-first heuristic: only attempt navigator.share on devices with a\n\t// touch surface and where canShare confirms file support. On desktop Chrome\n\t// canShare({files:…}) returns true but the macOS share sheet often opens\n\t// hidden behind the window — share() then never resolves and the button\n\t// hangs in \"preparing card…\". Restricting to touch devices avoids that.\n\tfunction shouldTryNativeFileShare(file: File): boolean {\n\t\tif (typeof navigator === 'undefined') return false;\n\t\tif (typeof navigator.canShare !== 'function') return false;\n\t\tconst isTouch = navigator.maxTouchPoints > 0 || 'ontouchstart' in window;\n\t\tif (!isTouch) return false;\n\t\ttry {\n\t\t\treturn navigator.canShare({ files: [file] });\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tasync function shareImage() {\n\t\tif (!duel || shareImageInFlight) return;\n\t\tshareImageInFlight = true;\n\t\tshareImageStatus = 'idle';\n\t\tconst filename = `ratemyd-duel-${duel.code}.png`;\n\t\ttry {\n\t\t\t// Fetch the rendered card bytes once (prewarmed on reveal → usually\n\t\t\t// instant from cache). Reused for BOTH the mobile share sheet and the\n\t\t\t// desktop download, so desktop no longer fires a wasted second request.\n\t\t\tlet blob: Blob | null = null;\n\t\t\ttry {\n\t\t\t\tconst res = await fetch(shareImageUrl);\n\t\t\t\tif (res.ok) blob = await res.blob();\n\t\t\t} catch {\n\t\t\t\t// network blip — fall back to the URL-based download below\n\t\t\t}\n\n\t\t\t// Mobile path: hand the file to the native share sheet — one tap from\n\t\t\t// posting, and \"Save Image\" / \"Add to Photos\" saves it to the gallery.\n\t\t\t// (iOS Safari can't reliably auto-download to Photos, so the share\n\t\t\t// sheet is the canonical save path there.) Touch + file-share only.\n\t\t\tif (blob && typeof navigator !== 'undefined' && typeof navigator.canShare === 'function') {\n\t\t\t\tconst file = new File([blob], filename, { type: 'image/png' });\n\t\t\t\tif (shouldTryNativeFileShare(file)) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait navigator.share({\n\t\t\t\t\t\t\tfiles: [file],\n\t\t\t\t\t\t\ttitle: 'd*ck duel',\n\t\t\t\t\t\t\ttext: 'ai picked sides. accept the duel ↗'\n\t\t\t\t\t\t});\n\t\t\t\t\t\tshareImageStatus = 'shared';\n\t\t\t\t\t\tanalytics.trackDuelImageShared(duel.code, 'native_share', isChallenger, 'result_page');\n\t\t\t\t\t\treturn;\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tif (err instanceof DOMException && err.name === 'AbortError') {\n\t\t\t\t\t\t\tshareImageStatus = 'idle';\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// share dismissed/failed → fall through to download\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Desktop / non-share fallback: trigger a real file download. Prefer an\n\t\t\t// <a download> on a blob URL (reuses the fetched bytes, no blank tab,\n\t\t\t// not popup-blocked). If the fetch failed, navigate to the attachment\n\t\t\t// URL — shareImageUrl already carries ?v=, so the param MUST be appended\n\t\t\t// with & (the old `?download=1` produced `...share.png?v=3?download=1`,\n\t\t\t// which the server parsed as v=\"3?download=1\" with NO download flag, so\n\t\t\t// it served the PNG inline and \"download\" just opened it in a tab).\n\t\t\tif (blob) {\n\t\t\t\tconst objUrl = URL.createObjectURL(blob);\n\t\t\t\tconst a = document.createElement('a');\n\t\t\t\ta.href = objUrl;\n\t\t\t\ta.download = filename;\n\t\t\t\tdocument.body.appendChild(a);\n\t\t\t\ta.click();\n\t\t\t\ta.remove();\n\t\t\t\tsetTimeout(() => URL.revokeObjectURL(objUrl), 10_000);\n\t\t\t} else {\n\t\t\t\twindow.open(`${shareImageUrl}&download=1`, '_blank', 'noopener,noreferrer');\n\t\t\t}\n\t\t\tshareImageStatus = 'downloaded';\n\t\t\tanalytics.trackDuelImageShared(duel.code, 'download', isChallenger, 'result_page');\n\t\t} catch (err) {\n\t\t\tconsole.error('shareImage failed:', err);\n\t\t\tshareImageStatus = 'error';\n\t\t} finally {\n\t\t\tshareImageInFlight = false;\n\t\t\tsetTimeout(() => {\n\t\t\t\tshareImageStatus = 'idle';\n\t\t\t}, 2500);\n\t\t}\n\t}\n</script>\n\n<!-- RAT-272 follow-up: bottom padding sized to clear the chat dock +\n\t the BottomNav stack. Dock now sits at bottom: 104-118px (Batch\n\t 14b, accounting for + slot lift) and is ~80px tall when collapsed,\n\t so its top edge sits ~184-198px from viewport bottom. pb-60 =\n\t 240px keeps the post-to-feed CTA + share row visible above the\n\t dock in the closed-chat state. With the chat panel expanded the\n\t dock grows up to ~350px — user scrolls past in that case. Desktop\n\t keeps pb-32 (no bottom nav, no dock collision).\n\t Batch 23: focus-mode views (lobby + fomo, body.duel-focus-mode)\n\t trim the bottom padding because the nav is hidden and the dock\n\t drops to env+12 — only ~100px of clearance needed for the dock's\n\t collapsed height. CSS override below the main element. -->\n<main class=\"duel-main relative min-h-screen overflow-hidden px-5 pt-28 pb-60 md:pt-32 md:pb-32\">\n\t<!-- shared atmosphere -->\n\t<div class=\"pointer-events-none absolute inset-0 bg-[linear-gradient(rgba(255,255,255,.006)_1px,transparent_1px),linear-gradient(90deg,rgba(255,255,255,.006)_1px,transparent_1px)] bg-[size:60px_60px]\"></div>\n\t<div class=\"pointer-events-none absolute top-1/3 left-1/2 hidden h-[800px] w-[800px] -translate-x-1/2 -translate-y-1/2 rounded-full bg-blue/[.05] blur-[200px] md:block\"></div>\n\n\t{#if view === 'countdown' || view === 'revealed'}\n\t\t<div class=\"warp-field\">\n\t\t\t{#each Array(28) as _, i}\n\t\t\t\t{@const angle = (i / 28) * 360 + Math.random() * 9}\n\t\t\t\t{@const dist = 18 + Math.random() * 30}\n\t\t\t\t<div class=\"warp-streak\" style=\"--angle: {angle}deg; --dist: {dist}%; --len: {100 + Math.random() * 120}px; --o: {0.05 + Math.random() * 0.06}; --dur: {2.4 + Math.random() * 2}s; --del: {-Math.random() * 5}s;\"></div>\n\t\t\t{/each}\n\t\t</div>\n\t{/if}\n\n\t<div class=\"relative z-10 mx-auto max-w-5xl\">\n\n\t\t<!-- custom duel: the creator set their own judging rubric. Surfaced so\n\t\t     everyone knows the photos were scored by these rules, not the default. -->\n\t\t{#if duel?.customJudgePrompt && (view === 'lobby' || view === 'fomo')}\n\t\t\t<div\n\t\t\t\tclass=\"mb-5 rounded-xl border border-blue/25 bg-blue/[.06] px-4 py-3 {duelFocusMode\n\t\t\t\t\t? 'max-md:mt-12'\n\t\t\t\t\t: ''}\"\n\t\t\t>\n\t\t\t\t<div class=\"flex items-center gap-2\">\n\t\t\t\t\t<svg class=\"h-3.5 w-3.5 text-blue\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M12 1a5 5 0 0 0-5 5v3H6a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-9a2 2 0 0 0-2-2h-1V6a5 5 0 0 0-5-5zm3 8H9V6a3 3 0 0 1 6 0v3z\"/></svg>\n\t\t\t\t\t<span class=\"font-display text-[11px] font-bold uppercase tracking-[0.18em] text-blue\">{t('custom duel')}</span>\n\t\t\t\t</div>\n\t\t\t\t<p class=\"mt-1.5 text-[13px] leading-relaxed text-text\">\n\t\t\t\t\t<span class=\"text-muted\">{t('judged on:')}</span> {duel.customJudgePrompt}\n\t\t\t\t</p>\n\t\t\t</div>\n\t\t{/if}\n\n\t\t<!-- OAuth resume bridge — same purpose as in /rate. Shadows whichever\n\t\t     view would have been computed; cleared in onMount once submitEntry\n\t\t     succeeds (or fails). -->\n\t\t{#if oauthResumeIncoming}\n\t\t\t<div class=\"flex min-h-[60vh] flex-col items-center justify-center text-center\">\n\t\t\t\t<div class=\"mx-auto h-12 w-12 animate-spin rounded-full border-4 border-border border-t-blue\"></div>\n\t\t\t\t<p class=\"mt-6 font-display text-sm tracking-wider uppercase text-muted\">{t('accepting the challenge…')}</p>\n\t\t\t</div>\n\n\t\t<!-- ─── NOT FOUND ──────────────────────────────────────────────────── -->\n\t\t{:else if view === 'not-found'}\n\t\t\t<div class=\"flex min-h-[60vh] flex-col items-center justify-center text-center\">\n\t\t\t\t{#if corrupted}\n\t\t\t\t\t<h1 class=\"font-display text-[clamp(2.5rem,8vw,5rem)] font-bold tracking-tighter\">\n\t\t\t\t\t\t{t('this duel')}<br /><span class=\"text-muted/40\">{t('went sideways.')}</span>\n\t\t\t\t\t</h1>\n\t\t\t\t\t<p class=\"mt-4 max-w-md text-sm text-muted\">\n\t\t\t\t\t\t{t(\"something on our end couldn't load this duel. it'll either fix itself, or it won't — we already got the heads-up.\")}\n\t\t\t\t\t</p>\n\t\t\t\t{:else}\n\t\t\t\t\t<h1 class=\"font-display text-[clamp(2.5rem,8vw,5rem)] font-bold tracking-tighter\">{t('duel not found')}</h1>\n\t\t\t\t\t<p class=\"mt-4 text-sm text-muted\">{t(\"this code doesn't exist or has been deleted.\")}</p>\n\t\t\t\t{/if}\n\t\t\t\t<a href=\"/d\" class=\"mt-8 inline-flex rounded-xl bg-blue px-7 py-3.5 font-display text-sm font-semibold text-white no-underline hover:bg-blue/80\">{t('start your own')}</a>\n\t\t\t</div>\n\n\t\t<!-- ─── EXPIRED ──────────────────────────────────────────────────── -->\n\t\t{:else if view === 'expired' && duel}\n\t\t\t<div class=\"mx-auto max-w-lg py-10\">\n\t\t\t\t<div class=\"text-center\">\n\t\t\t\t\t<h1 class=\"font-display text-[clamp(2.2rem,7vw,4rem)] font-bold leading-[0.9] tracking-tighter\">{t('this duel')}<br /><span class=\"text-muted/30\">{t('has ended.')}</span></h1>\n\t\t\t\t\t<p class=\"mt-4 text-sm text-muted\">\n\t\t\t\t\t\t{#if entries.length > 0}\n\t\t\t\t\t\t\t{t(\"the 48-hour window closed. here's how it finished.\")}\n\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t{t('the 48-hour window closed before anyone stepped up.')}\n\t\t\t\t\t\t{/if}\n\t\t\t\t\t</p>\n\t\t\t\t</div>\n\n\t\t\t\t<!-- Final read-back: challenger + everyone who joined, ranked by score.\n\t\t\t\t     Beats the old terminal wall — a visitor arriving from a feed or\n\t\t\t\t     notification at least sees the outcome. Entries with no score\n\t\t\t\t     (never analyzed before expiry) show a dash rather than a fake 0. -->\n\t\t\t\t{#if entries.length > 0}\n\t\t\t\t\t<!-- The challenger's score is coerced to 0 server-side (`Number(...) || 0`),\n\t\t\t\t\t     so an unscored challenger reads as a real 0.0 and, sorting above the\n\t\t\t\t\t     `null` entries, lands at #1 looking like the winner. Only trust it\n\t\t\t\t\t     once their generation actually completed. -->\n\t\t\t\t\t{@const roster = [\n\t\t\t\t\t\t{ id: 'challenger', nickname: duel.challengerNickname, avatarPath: duel.challengerAvatarPath, score: duel.challengerGenerationStatus === 'completed' ? duel.challengerScore : null, isRater: duel.challengerIsRater, isSubscriber: duel.challengerIsSubscriber, isVerified: duel.challengerIsVerified },\n\t\t\t\t\t\t...entries.map((e) => ({ id: e.id, nickname: e.nickname, avatarPath: e.avatarPath, score: e.status === 'completed' ? e.score : null, isRater: e.isRater, isSubscriber: e.isSubscriber, isVerified: e.isVerified }))\n\t\t\t\t\t].sort((a, b) => (b.score ?? -1) - (a.score ?? -1))}\n\t\t\t\t\t<ul class=\"mt-8 divide-y divide-border overflow-hidden rounded-2xl border border-border bg-surface\">\n\t\t\t\t\t\t{#each roster as m, i (m.id)}\n\t\t\t\t\t\t\t<li class=\"flex items-center gap-3 px-4 py-3.5\">\n\t\t\t\t\t\t\t\t<span class=\"w-5 shrink-0 text-center font-display text-sm font-bold tabular-nums text-muted/40\">{i + 1}</span>\n\t\t\t\t\t\t\t\t<DuelAvatar nickname={m.nickname} avatarUrl={getAvatarUrl(m.avatarPath)} size={40} />\n\t\t\t\t\t\t\t\t<div class=\"flex min-w-0 flex-1 items-center gap-1.5\">\n\t\t\t\t\t\t\t\t\t{#if m.nickname}\n\t\t\t\t\t\t\t\t\t\t<a href=\"/u/{encodeURIComponent(m.nickname)}\" class=\"truncate font-display text-sm font-semibold text-text no-underline hover:underline\">{m.nickname}</a>\n\t\t\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t\t\t<span class=\"truncate font-display text-sm font-semibold text-text\">{t('anon')}</span>\n\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t<UserBadge rater={m.isRater} subscriber={m.isSubscriber} verified={m.isVerified} size={13} />\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<span class=\"font-display text-sm font-bold tabular-nums {i === 0 ? 'text-blue' : 'text-muted'}\">\n\t\t\t\t\t\t\t\t\t{m.score != null ? m.score.toFixed(1) : '—'}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t{/each}\n\t\t\t\t\t</ul>\n\t\t\t\t{/if}\n\n\t\t\t\t<div class=\"mt-8 flex flex-col gap-2 sm:flex-row sm:justify-center\">\n\t\t\t\t\t<button type=\"button\" onclick={goBack} class=\"inline-flex items-center justify-center gap-2 rounded-xl border border-border px-6 py-3.5 font-display text-sm font-semibold text-text transition-all hover:border-muted hover:bg-white/[.03]\">\n\t\t\t\t\t\t<svg class=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M19 12H5M12 19l-7-7 7-7\"/></svg>\n\t\t\t\t\t\t{t('go back')}\n\t\t\t\t\t</button>\n\t\t\t\t\t<a href=\"/d\" class=\"inline-flex items-center justify-center rounded-xl bg-blue px-6 py-3.5 font-display text-sm font-semibold text-white no-underline hover:bg-blue/80\">{t('start your own')}</a>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t<!-- ─── CHALLENGER PROCESSING ─────────────────────────────────────── -->\n\t\t{:else if view === 'challenger-processing'}\n\t\t\t<div class=\"loader-shell\">\n\t\t\t\t<div class=\"mx-auto w-fit\"><AnalyzingProgress colorClass=\"text-blue\" size={72} /></div>\n\t\t\t\t<h2 class=\"mt-8 font-display text-[clamp(1.6rem,5vw,2.5rem)] font-bold tracking-tighter\">\n\t\t\t\t\t{t('analyzing your d*ck')}<span class=\"text-blue\">…</span>\n\t\t\t\t</h2>\n\t\t\t\t<p class=\"mt-4 text-sm text-muted\">{t('the AI is rating your photo. your duel lobby will be ready in seconds.')}</p>\n\t\t\t</div>\n\n\t\t<!-- ─── LOBBY (challenger waiting / spectator / both-uploaded) ────── -->\n\t\t{:else if view === 'lobby' && duel}\n\t\t\t<div class=\"mb-10\">\n\t\t\t\t<PresenceBar\n\t\t\t\t\tpresences={presences}\n\t\t\t\t\tchallengerNickname={duel.challengerNickname}\n\t\t\t\t\topponentNickname={firstEntry?.nickname ?? null}\n\t\t\t\t\tchallengerState={challengerPresenceState}\n\t\t\t\t\topponentState={opponentPresenceState}\n\t\t\t\t/>\n\t\t\t</div>\n\n\t\t\t<!-- RAT-88: private-duel pill — same shape as the fomo view's notice\n\t\t\t     so the challenger sees a confirmation of who they targeted, and\n\t\t\t     any spectator with the link knows the duel is locked. Suppressed\n\t\t\t     once a joiner has locked in (firstEntry exists) — at that point\n\t\t\t     the targeting decision is moot, both photos are in. -->\n\t\t\t{#if targeted && !firstEntry}\n\t\t\t\t<div class=\"mb-8\">\n\t\t\t\t\t<div class=\"inline-flex items-center gap-2 rounded-full border border-coral/30 bg-coral/[.08] px-3 py-1.5\">\n\t\t\t\t\t\t<svg class=\"h-3 w-3 text-coral\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n\t\t\t\t\t\t\t<rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" />\n\t\t\t\t\t\t\t<path d=\"M7 11V7a5 5 0 0 1 10 0v4\" />\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t<span class=\"font-display text-[10px] font-bold uppercase tracking-[0.2em] text-coral\">\n\t\t\t\t\t\t\t{t('private duel · for {name}', { name: targeting?.label ?? '' })}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t<p class=\"mt-3 max-w-lg text-[13px] leading-relaxed text-muted\">\n\t\t\t\t\t\t{#if isChallenger}\n\t\t\t\t\t\t\t{#each t('only {name} can accept this — anyone else with the link is bounced.').split('{name}') as part, i (i)}{#if i}<span class=\"text-text\">{targeting?.label}</span>{/if}{part}{/each}\n\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t{#each t('the challenger called {name} directly. only they can accept this duel.').split('{name}') as part, i (i)}{#if i}<span class=\"text-text\">{targeting?.label}</span>{/if}{part}{/each}\n\t\t\t\t\t\t{/if}\n\t\t\t\t\t</p>\n\t\t\t\t</div>\n\t\t\t{/if}\n\n\t\t\t{#if duel.format === '1v1'}\n\t\t\t\t{#if isChallenger}\n\t\t\t\t\t<h1 class=\"font-display text-[clamp(2.8rem,9vw,6.5rem)] font-bold leading-[0.85] tracking-tighter\">\n\t\t\t\t\t\t{t('your d*ck')}<br /><span class=\"text-blue\">{t('is sealed.')}</span>\n\t\t\t\t\t</h1>\n\t\t\t\t\t<p class=\"mt-6 font-display text-lg font-bold tracking-tight text-text md:text-xl\">\n\t\t\t\t\t\t<span aria-hidden=\"true\" class=\"mr-1.5 text-blue\">→</span>{t('share the link.')}\n\t\t\t\t\t</p>\n\t\t\t\t\t<p class=\"mt-1 max-w-md text-[13px] leading-snug text-muted\">\n\t\t\t\t\t\t{t('both scores drop the instant they accept.')}\n\t\t\t\t\t</p>\n\n\t\t\t\t\t<!-- compact status row: continuous slim bar fills the space between\n\t\t\t\t\t     the label and the timer chip; copy-link CTA sits just below. -->\n\t\t\t\t\t<div class=\"mt-7 max-w-md\">\n\t\t\t\t\t\t<div class=\"flex items-center gap-3\">\n\t\t\t\t\t\t\t<div class=\"h-1.5 min-w-[40px] flex-1 overflow-hidden rounded-full bg-border\">\n\t\t\t\t\t\t\t\t<div class=\"h-full rounded-full bg-blue transition-all duration-300 {opponentPresenceState !== 'absent' ? 'w-full' : 'w-1/2'}\"></div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t{#if opponentPresenceState === 'uploading'}\n\t\t\t\t\t\t\t\t<p class=\"shrink-0 whitespace-nowrap text-[11px] font-semibold text-muted\">{t('opponent uploading…')}</p>\n\t\t\t\t\t\t\t{:else if opponentPresenceState === 'rating'}\n\t\t\t\t\t\t\t\t<p class=\"shrink-0 whitespace-nowrap text-[11px] font-semibold text-muted\">{t('ai rating opponent…')}</p>\n\t\t\t\t\t\t\t{:else if opponentPresenceState !== 'absent'}\n\t\t\t\t\t\t\t\t<p class=\"shrink-0 whitespace-nowrap text-[11px] font-semibold text-muted\">{t('dropping soon')}</p>\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t{#if opponentPresenceState === 'absent'}\n\t\t\t\t\t\t\t\t<span class=\"flex shrink-0 items-center gap-1.5 whitespace-nowrap rounded-full border border-border bg-white/[0.03] px-2.5 py-1 text-[11px] font-semibold tabular-nums {expUrgent ? 'text-coral' : 'text-text'}\">\n\t\t\t\t\t\t\t\t\t<svg class=\"h-3 w-3 shrink-0 opacity-70\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><polyline points=\"12 6 12 12 16 14\"/></svg>\n\t\t\t\t\t\t\t\t\t{pad(expH)}h {pad(expM)}m\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</div>\n\n\t\t\t\t\t\t{#if duel.challengerGenerationStatus === 'failed'}\n\t\t\t\t\t\t\t<p class=\"mt-3 flex items-center gap-1.5 text-xs text-coral\">\n\t\t\t\t\t\t\t\t<svg class=\"h-3.5 w-3.5 shrink-0\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\"/><line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\"/></svg>\n\t\t\t\t\t\t\t{t('analysis failed —')} <a href=\"/d\" class=\"underline underline-offset-2\">{t('start a new duel')}</a>\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t{:else if challengerProcessing}\n\t\t\t\t\t\t\t<p class=\"mt-3 flex items-center gap-1.5 text-xs text-muted/60\">\n\t\t\t\t\t\t\t\t<span class=\"inline-block h-2 w-2 animate-pulse rounded-full bg-blue/60\"></span>\n\t\t\t\t\t\t\t\t{t('ai is rating your photo in the background — share away.')}\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t{/if}\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<!-- RAT-529: the people they already talk to, one tap each — the\n\t\t\t\t\t\t existing duel invite card lands in that chat. -->\n\t\t\t\t\t{#if !data.notFound && data.chatPartners.length > 0}\n\t\t\t\t\t\t<div class=\"mt-7 max-w-md\">\n\t\t\t\t\t\t\t<p class=\"text-[10px] font-bold uppercase tracking-[0.2em] text-muted\">{t('send to a chat')}</p>\n\t\t\t\t\t\t\t<div class=\"mt-3 flex gap-4 overflow-x-auto pb-1\">\n\t\t\t\t\t\t\t\t{#each data.chatPartners as p (p.threadId)}\n\t\t\t\t\t\t\t\t\t{@const st = sentTo[p.threadId]}\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\tclass=\"flex w-16 shrink-0 flex-col items-center gap-1.5 disabled:opacity-60\"\n\t\t\t\t\t\t\t\t\t\tdisabled={!!st && st !== 'failed'}\n\t\t\t\t\t\t\t\t\t\tonclick={() => sendToChat(p.threadId)}\n\t\t\t\t\t\t\t\t\t\taria-label={t('send the duel to @{name}', { name: p.nickname })}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<span class=\"relative\">\n\t\t\t\t\t\t\t\t\t\t\t<DuelAvatar nickname={p.nickname} avatarUrl={getAvatarUrl(p.avatarPath)} size={48} link={false} />\n\t\t\t\t\t\t\t\t\t\t\t{#if st === 'sent'}\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"absolute -right-1 -bottom-1 flex h-5 w-5 items-center justify-center rounded-full bg-green text-[11px] font-bold text-bg\">✓</span>\n\t\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t<span class=\"w-full truncate text-center text-[11px] {st === 'sent' ? 'text-green' : st === 'failed' ? 'text-coral' : 'text-muted-2'}\">\n\t\t\t\t\t\t\t\t\t\t\t{st === 'sent' ? t('sent') : st === 'sending' ? '…' : st === 'failed' ? t('retry') : p.nickname}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t</button>\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{:else if firstEntry?.status === 'completed'}\n\t\t\t\t\t<h1 class=\"font-display text-[clamp(2.8rem,9vw,6.5rem)] font-bold leading-[0.85] tracking-tighter\">\n\t\t\t\t\t\t{t('both are in.')}<br /><span class=\"text-blue\">{t('scores sealed.')}</span>\n\t\t\t\t\t</h1>\n\t\t\t\t\t<p class=\"mt-6 max-w-xl text-sm leading-relaxed text-muted md:text-base\">\n\t\t\t\t\t\t{t('the ai has judged both sides. the synchronized countdown starts any second now.')}\n\t\t\t\t\t</p>\n\t\t\t\t{:else}\n\t\t\t\t\t<h1 class=\"font-display text-[clamp(2.8rem,9vw,6.5rem)] font-bold leading-[0.85] tracking-tighter\">\n\t\t\t\t\t\t{t('duel live.')}<br /><span class=\"text-muted\">{t('waiting for both.')}</span>\n\t\t\t\t\t</h1>\n\t\t\t\t\t<p class=\"mt-6 max-w-xl text-sm leading-relaxed text-muted md:text-base\">\n\t\t\t\t\t\t{t('follow the live state below. reactions and comments travel in realtime.')}\n\t\t\t\t\t</p>\n\t\t\t\t{/if}\n\t\t\t{:else}\n\t\t\t\t<!-- team modes: unified lobby for challenger, joiners, and spectators.\n\t\t\t\t     Everyone watches the squad fill up; challenger's analysis runs in\n\t\t\t\t     the background and surfaces in the team roster below. -->\n\t\t\t\t<h1 class=\"font-display text-[clamp(2.8rem,9vw,6.5rem)] font-bold leading-[0.85] tracking-tighter\">\n\t\t\t\t\t{t('{format} duel.', { format: duel.format })}<br /><span class=\"text-blue\">{t('fill the squad.')}</span>\n\t\t\t\t</h1>\n\t\t\t\t<p class=\"mt-6 max-w-xl text-sm leading-relaxed text-muted md:text-base\">\n\t\t\t\t\t{#if entries.length + 1 >= 1 + duel.maxEntries}\n\t\t\t\t\t\t{t('all in. the synchronized reveal drops any second now.')}\n\t\t\t\t\t{:else}\n\t\t\t\t\t\t{t('share the link — once both teams are full, the ai reveals every score at the same instant.')}\n\t\t\t\t\t{/if}\n\t\t\t\t</p>\n\n\t\t\t\t<div class=\"mt-10 max-w-md\">\n\t\t\t\t\t<!-- progress indicator: challenger + every entry slot -->\n\t\t\t\t\t<div class=\"mb-5 flex items-center gap-3\">\n\t\t\t\t\t\t<div class=\"flex gap-1.5\">\n\t\t\t\t\t\t\t<span class=\"h-1.5 w-6 rounded-full bg-blue\"></span>\n\t\t\t\t\t\t\t{#each Array(duel.maxEntries) as _, i (i)}\n\t\t\t\t\t\t\t\t<span class=\"h-1.5 w-6 rounded-full {entries.length > i ? 'bg-blue' : 'bg-border'}\"></span>\n\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<p class=\"text-[11px] font-semibold text-muted\">\n\t\t\t\t\t\t\t{t('{n} of {max} joined', { n: 1 + entries.length, max: 1 + duel.maxEntries })}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<!-- timer (always shown until full) -->\n\t\t\t\t\t{#if entries.length < duel.maxEntries}\n\t\t\t\t\t\t<div class=\"mb-4 flex items-center gap-2\">\n\t\t\t\t\t\t\t<svg class=\"h-3.5 w-3.5 shrink-0 {expUrgent ? 'text-coral' : 'text-muted/50'}\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><polyline points=\"12 6 12 12 16 14\"/></svg>\n\t\t\t\t\t\t\t<span class=\"font-display text-lg font-bold tabular-nums {expUrgent ? 'text-coral' : 'text-text'}\">{t('{h}h {m}m left', { h: pad(expH), m: pad(expM) })}</span>\n\t\t\t\t\t\t\t<span class=\"text-[11px] text-muted/50\">{t('— share before time runs out')}</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t{/if}\n\n\t\t\t\t\t{#if isChallenger && duel.challengerGenerationStatus === 'failed'}\n\t\t\t\t\t\t<p class=\"mb-4 flex items-center gap-1.5 text-xs text-coral\">\n\t\t\t\t\t\t\t<svg class=\"h-3.5 w-3.5 shrink-0\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\"/><line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\"/></svg>\n\t\t\t\t\t\t\t{t('your analysis failed —')} <a href=\"/d\" class=\"underline underline-offset-2\">{t('start a new duel')}</a>\n\t\t\t\t\t\t</p>\n\t\t\t\t\t{:else if isChallenger && challengerProcessing}\n\t\t\t\t\t\t<p class=\"mb-4 flex items-center gap-1.5 text-xs text-muted/60\">\n\t\t\t\t\t\t\t<span class=\"inline-block h-2 w-2 animate-pulse rounded-full bg-blue/60\"></span>\n\t\t\t\t\t\t\t{t('AI is rating your photo in the background — share away.')}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t{/if}\n\t\t\t\t</div>\n\t\t\t{/if}\n\n\t\t\t<!-- Single share box visible to everyone in the lobby. Challenger-alone\n\t\t\t     gets the \"share the link\" imperative in the hero above, so here we\n\t\t\t     only render the small uppercase label for joiners/spectators. -->\n\t\t\t<div class=\"mt-6 max-w-md\">\n\t\t\t\t{#if !(isChallenger && !firstEntry)}\n\t\t\t\t\t<p class=\"mb-3 text-[10px] font-bold uppercase tracking-[0.2em] text-muted\">{t('share the link')}</p>\n\t\t\t\t{/if}\n\t\t\t\t<ShareLink code={duel.code} format={duel.format} isInviter={isChallenger} sharePosition=\"duel_page\" />\n\n\t\t\t\t{#if isChallenger && !firstEntry && duel.status === 'open' && !isFeatured}\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"mt-3 flex w-full items-center justify-center gap-2 rounded-xl border border-blue/40 bg-blue/[.08] px-4 py-3 font-display text-[13px] font-semibold text-blue transition-colors hover:bg-blue/[.14]\"\n\t\t\t\t\t\tonclick={() => (featurePromptOpen = true)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<svg class=\"h-4 w-4\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M13 2 4 14h6l-1 8 9-12h-6z\" /></svg>\n\t\t\t\t\t\t{t('no opponent yet? feature it — matched ~2× more often')}\n\t\t\t\t\t</button>\n\t\t\t\t{/if}\n\t\t\t</div>\n\n\t\t\t<!-- hyped matchup row -->\n\t\t\t{#if duel.format === '1v1'}\n\t\t\t\t<div class=\"matchup-row mt-14\">\n\t\t\t\t\t<div class=\"matchup-side\">\n\t\t\t\t\t\t<DuelAvatar nickname={duel.challengerNickname} avatarUrl={getAvatarUrl(duel.challengerAvatarPath)} size={48} variant=\"blue\" />\n\t\t\t\t\t\t<div class=\"min-w-0\">\n\t\t\t\t\t\t\t<div class=\"flex items-center gap-1.5\">\n\t\t\t\t\t\t\t\t{#if duel.challengerNickname}\n\t\t\t\t\t\t\t\t\t<a class=\"matchup-name text-blue\" href=\"/u/{encodeURIComponent(duel.challengerNickname)}\">{duel.challengerNickname}</a>\n\t\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t\t<p class=\"matchup-name text-blue\">{t('challenger')}</p>\n\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t<UserBadge rater={duel.challengerIsRater} subscriber={duel.challengerIsSubscriber} verified={duel.challengerIsVerified} size={13} />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<p class=\"matchup-state\"><span class=\"state-dot state-dot--blue\"></span>{t('locked in')}</p>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"vs-wrap\" aria-hidden=\"true\">\n\t\t\t\t\t\t<span class=\"vs-ring\"></span>\n\t\t\t\t\t\t<span class=\"vs-hype\" data-text=\"VS\">VS</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"matchup-side matchup-side--right\">\n\t\t\t\t\t\t<div class=\"min-w-0\">\n\t\t\t\t\t\t\t<div class=\"flex items-center justify-end gap-1.5\">\n\t\t\t\t\t\t\t\t{#if firstEntry?.nickname}\n\t\t\t\t\t\t\t\t\t<a class=\"matchup-name text-coral\" href=\"/u/{encodeURIComponent(firstEntry.nickname)}\">{firstEntry.nickname}</a>\n\t\t\t\t\t\t\t\t{:else if firstEntry}\n\t\t\t\t\t\t\t\t\t<p class=\"matchup-name text-coral\">{t('anon')}</p>\n\t\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t\t<p class=\"matchup-name matchup-name--muted\">{t('opponent')}</p>\n\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t{#if firstEntry}<UserBadge rater={firstEntry.isRater} subscriber={firstEntry.isSubscriber} verified={firstEntry.isVerified} size={13} />{/if}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<p class=\"matchup-state matchup-state--right\">\n\t\t\t\t\t\t\t\t{#if opponentPresenceState === 'ready'}\n\t\t\t\t\t\t\t\t\t<span class=\"state-dot state-dot--coral\"></span>{t('locked in')}\n\t\t\t\t\t\t\t\t{:else if opponentPresenceState === 'rating'}\n\t\t\t\t\t\t\t\t\t<span class=\"state-dot state-dot--coral\"></span>{t('rating…')}\n\t\t\t\t\t\t\t\t{:else if opponentPresenceState === 'uploading'}\n\t\t\t\t\t\t\t\t\t<span class=\"state-dot state-dot--coral\"></span>{t('uploading…')}\n\t\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t\t<span class=\"state-dot state-dot--muted\"></span>{t('not joined')}\n\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<DuelAvatar\n\t\t\t\t\t\t\tnickname={firstEntry?.nickname ?? null}\n\t\t\t\t\t\t\tavatarUrl={getAvatarUrl(firstEntry?.avatarPath ?? null)}\n\t\t\t\t\t\t\tsize={48}\n\t\t\t\t\t\t\tvariant={firstEntry ? 'coral' : 'muted'}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t{:else}\n\t\t\t\t<!-- team matchup: stacked roster per side, VS in the middle. Same chrome as 1v1. -->\n\t\t\t\t<div class=\"matchup-row team-matchup mt-14\">\n\t\t\t\t\t<div class=\"team-stack\">\n\t\t\t\t\t\t<span class=\"team-label text-blue\">{t('team a')}</span>\n\t\t\t\t\t\t{#each teamA as row, i (i)}\n\t\t\t\t\t\t\t{#if row.kind === 'challenger'}\n\t\t\t\t\t\t\t\t<div class=\"team-member\">\n\t\t\t\t\t\t\t\t\t<DuelAvatar nickname={row.nickname} avatarUrl={getAvatarUrl(duel.challengerAvatarPath)} size={32} variant=\"blue\" />\n\t\t\t\t\t\t\t\t\t<div class=\"min-w-0\">\n\t\t\t\t\t\t\t\t\t\t{#if row.nickname}\n\t\t\t\t\t\t\t\t\t\t\t<a class=\"member-name text-blue\" href=\"/u/{encodeURIComponent(row.nickname)}\">{row.nickname}</a>\n\t\t\t\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t\t\t\t<p class=\"member-name text-blue\">{t('challenger')}</p>\n\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t\t<p class=\"member-state\"><span class=\"state-dot state-dot--blue\"></span>{t('locked in')}</p>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t{:else if row.kind === 'entry'}\n\t\t\t\t\t\t\t\t<div class=\"team-member\">\n\t\t\t\t\t\t\t\t\t<DuelAvatar nickname={row.entry.nickname} avatarUrl={getAvatarUrl(row.entry.avatarPath)} size={32} variant=\"blue\" />\n\t\t\t\t\t\t\t\t\t<div class=\"min-w-0\">\n\t\t\t\t\t\t\t\t\t\t{#if row.entry.nickname}\n\t\t\t\t\t\t\t\t\t\t\t<a class=\"member-name text-blue\" href=\"/u/{encodeURIComponent(row.entry.nickname)}\">{row.entry.nickname}</a>\n\t\t\t\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t\t\t\t<p class=\"member-name text-blue\">{t('anon')}</p>\n\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t\t<p class=\"member-state\">\n\t\t\t\t\t\t\t\t\t\t\t{#if row.entry.status === 'completed'}\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"state-dot state-dot--blue\"></span>{t('locked in')}\n\t\t\t\t\t\t\t\t\t\t\t{:else if row.entry.status === 'processing'}\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"state-dot state-dot--blue\"></span>{t('rating…')}\n\t\t\t\t\t\t\t\t\t\t\t{:else if row.entry.status === 'failed'}\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"state-dot state-dot--muted\"></span>{t('failed')}\n\t\t\t\t\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"state-dot state-dot--blue\"></span>{t('uploading…')}\n\t\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t<div class=\"team-member team-member--open\">\n\t\t\t\t\t\t\t\t\t<DuelAvatar nickname={null} size={32} variant=\"muted\" />\n\t\t\t\t\t\t\t\t\t<div class=\"min-w-0\">\n\t\t\t\t\t\t\t\t\t\t<p class=\"member-name member-name--muted\">{t('open slot')}</p>\n\t\t\t\t\t\t\t\t\t\t<p class=\"member-state\"><span class=\"state-dot state-dot--muted\"></span>{t('waiting')}</p>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t{/each}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"vs-wrap\" aria-hidden=\"true\">\n\t\t\t\t\t\t<span class=\"vs-ring\"></span>\n\t\t\t\t\t\t<span class=\"vs-hype\" data-text=\"VS\">VS</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"team-stack team-stack--right\">\n\t\t\t\t\t\t<span class=\"team-label text-coral\">{t('team b')}</span>\n\t\t\t\t\t\t{#each teamB as row, i (i)}\n\t\t\t\t\t\t\t{#if row.kind === 'entry'}\n\t\t\t\t\t\t\t\t<div class=\"team-member team-member--right\">\n\t\t\t\t\t\t\t\t\t<div class=\"min-w-0\">\n\t\t\t\t\t\t\t\t\t\t{#if row.entry.nickname}\n\t\t\t\t\t\t\t\t\t\t\t<a class=\"member-name text-coral\" href=\"/u/{encodeURIComponent(row.entry.nickname)}\">{row.entry.nickname}</a>\n\t\t\t\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t\t\t\t<p class=\"member-name text-coral\">{t('anon')}</p>\n\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t\t<p class=\"member-state member-state--right\">\n\t\t\t\t\t\t\t\t\t\t\t{#if row.entry.status === 'completed'}\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"state-dot state-dot--coral\"></span>{t('locked in')}\n\t\t\t\t\t\t\t\t\t\t\t{:else if row.entry.status === 'processing'}\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"state-dot state-dot--coral\"></span>{t('rating…')}\n\t\t\t\t\t\t\t\t\t\t\t{:else if row.entry.status === 'failed'}\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"state-dot state-dot--muted\"></span>{t('failed')}\n\t\t\t\t\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"state-dot state-dot--coral\"></span>{t('uploading…')}\n\t\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t<DuelAvatar nickname={row.entry.nickname} avatarUrl={getAvatarUrl(row.entry.avatarPath)} size={32} variant=\"coral\" />\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t<div class=\"team-member team-member--right team-member--open\">\n\t\t\t\t\t\t\t\t\t<div class=\"min-w-0\">\n\t\t\t\t\t\t\t\t\t\t<p class=\"member-name member-name--muted\">{t('open slot')}</p>\n\t\t\t\t\t\t\t\t\t\t<p class=\"member-state member-state--right\"><span class=\"state-dot state-dot--muted\"></span>{t('waiting')}</p>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t<DuelAvatar nickname={null} size={32} variant=\"muted\" />\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t{/each}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t{/if}\n\n\n\n\t\t\t<!-- Batch 23: expires/code/mode stat strip removed. The expiry\n\t\t\t\t timer is already echoed in the share row above; the duel\n\t\t\t\t code is meaningless to share recipients (the link encodes\n\t\t\t\t it); mode is implied by the rest of the page chrome. -->\n\n\t\t<!-- ─── FOMO (opponent-new landing) ───────────────────────────────── -->\n\t\t{:else if view === 'fomo' && duel}\n\t\t\t<!-- two-column \"vs\" split on desktop: who-challenged-you on the left,\n\t\t\t     the action on the right. stacks to a single column on mobile. -->\n\t\t\t<div class=\"md:grid md:grid-cols-[1.05fr_1fr] md:items-start md:gap-x-12\">\n\t\t\t\t<!-- LEAD — challenger, headline, stakes -->\n\t\t\t\t<div>\n\t\t\t\t\t<div class=\"flex items-center gap-3\">\n\t\t\t\t\t\t<DuelAvatar nickname={duel.challengerNickname} avatarUrl={getAvatarUrl(duel.challengerAvatarPath)} size={48} />\n\t\t\t\t\t\t<div class=\"min-w-0\">\n\t\t\t\t\t\t\t<p class=\"text-[10px] font-bold uppercase tracking-[0.2em] text-muted\">{t('challenger')}</p>\n\t\t\t\t\t\t\t{#if duel.challengerNickname}\n\t\t\t\t\t\t\t\t<a class=\"challenger-link\" href=\"/u/{encodeURIComponent(duel.challengerNickname)}\">{duel.challengerNickname}</a>\n\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t<p class=\"challenger-link text-text\">{t('someone')}</p>\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{#if watcherCount > 0}\n\t\t\t\t\t\t\t<span class=\"ml-auto inline-flex shrink-0 items-center gap-1.5 rounded-full border border-border bg-white/[0.03] px-3 py-1.5 font-display text-[10px] font-bold uppercase tracking-[0.15em] text-muted\">\n\t\t\t\t\t\t\t\t<span class=\"h-1.5 w-1.5 rounded-full\" style=\"background: var(--color-accent)\"></span>\n\t\t\t\t\t\t\t\t{t('{n} watching', { n: watcherCount })}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t{/if}\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<h1 class=\"mt-5 font-display text-[clamp(2.5rem,7vw,4.25rem)] font-bold leading-[0.9] tracking-tighter\">\n\t\t\t\t\t\t{#if viewerBlocked}\n\t\t\t\t\t\t\t{t(\"this isn't\")}<br /><span class=\"text-muted\">{t('for you.')}</span>\n\t\t\t\t\t\t{:else if targeted}\n\t\t\t\t\t\t\t{t(\"you've been\")}<br /><span class=\"text-blue\">{t('called out.')}</span>\n\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t{t(\"you've been\")}<br /><span class=\"text-blue\">{t('challenged.')}</span>\n\t\t\t\t\t\t{/if}\n\t\t\t\t\t</h1>\n\n\t\t\t\t\t<!-- RAT-88: private-duel notice — shown so the visitor knows\n\t\t\t\t\t     immediately whether the link applies to them. -->\n\t\t\t\t\t{#if targeted}\n\t\t\t\t\t\t<div class=\"mt-5\">\n\t\t\t\t\t\t\t<div class=\"inline-flex items-center gap-2 rounded-full border border-coral/30 bg-coral/[.08] px-3 py-1.5\">\n\t\t\t\t\t\t\t\t<svg class=\"h-3 w-3 text-coral\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n\t\t\t\t\t\t\t\t\t<rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" />\n\t\t\t\t\t\t\t\t\t<path d=\"M7 11V7a5 5 0 0 1 10 0v4\" />\n\t\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t\t<span class=\"font-display text-[10px] font-bold uppercase tracking-[0.2em] text-coral\">\n\t\t\t\t\t\t\t\t\t{t('private duel · for {name}', { name: targeting?.label ?? '' })}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t{#if viewerBlocked}\n\t\t\t\t\t\t\t\t<p class=\"mt-3 max-w-lg text-[13px] leading-relaxed text-muted\">\n\t\t\t\t\t\t\t\t\t{#each t('the challenger picked {name} directly. only they can accept this one. start your own and call out whoever you want.').split('{name}') as part, i (i)}{#if i}<span class=\"text-text\">{targeting?.label}</span>{/if}{part}{/each}\n\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t{:else if viewerAmbiguous}\n\t\t\t\t\t\t\t\t<p class=\"mt-3 max-w-lg text-[13px] leading-relaxed text-muted\">\n\t\t\t\t\t\t\t\t\t{#each t('only {name} can accept this duel. log in as them to continue, or start your own.').split('{name}') as part, i (i)}{#if i}<span class=\"text-text\">{targeting?.label}</span>{/if}{part}{/each}\n\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t<p class=\"mt-3 max-w-lg text-[13px] leading-relaxed text-muted\">\n\t\t\t\t\t\t\t\t\t{#each t(\"they called {you} out specifically. nobody else can accept this — it's yours to take or skip.\").split('{you}') as part, i (i)}{#if i}<span class=\"text-text\">{t('you')}</span>{/if}{part}{/each}\n\t\t\t\t\t\t\t\t</p>\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-4 max-w-md text-[15px] leading-relaxed text-muted\">\n\t\t\t\t\t\t\t{#each t(\"they think they're bigger. {cta}, scores drop together.\").split('{cta}') as part, i (i)}{#if i}<span class=\"text-text\">{t('upload yours — the ai settles it in 15 seconds')}</span>{/if}{part}{/each}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t{/if}\n\n\t\t\t\t\t<!-- \"challenger locked in · you're up\" status pill (matches the mockup) -->\n\t\t\t\t\t{#if !viewerBlocked}\n\t\t\t\t\t\t<div class=\"mt-5\">\n\t\t\t\t\t\t\t<div class=\"inline-flex items-center gap-2 rounded-full border border-border bg-white/[0.03] px-3 py-1.5\">\n\t\t\t\t\t\t\t\t<svg class=\"h-3 w-3 text-muted\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n\t\t\t\t\t\t\t\t\t<rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" />\n\t\t\t\t\t\t\t\t\t<path d=\"M7 11V7a5 5 0 0 1 10 0v4\" />\n\t\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t\t<span class=\"font-display text-[10px] font-bold uppercase tracking-[0.2em] text-muted\">\n\t\t\t\t\t\t\t\t\t{t('{name} locked in', { name: duel.challengerNickname ?? t('challenger') })}&nbsp;·&nbsp;<span class=\"text-blue\">{t(\"you're up\")}</span>\n\t\t\t\t\t\t\t\t</span>\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\n\t\t\t\t\t<!-- public-duel notice — only when not blocked -->\n\t\t\t\t\t{#if duel.showChallengerPhoto && !viewerBlocked}\n\t\t\t\t\t\t<div class=\"mt-5\">\n\t\t\t\t\t\t\t<div class=\"inline-flex items-center gap-2 rounded-full border border-blue/30 bg-blue/[.08] px-3 py-1.5\">\n\t\t\t\t\t\t\t\t<span class=\"relative flex h-2 w-2\">\n\t\t\t\t\t\t\t\t\t<span class=\"absolute inline-flex h-full w-full animate-ping rounded-full bg-blue/60\"></span>\n\t\t\t\t\t\t\t\t\t<span class=\"relative inline-flex h-2 w-2 rounded-full bg-blue\"></span>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<span class=\"font-display text-[10px] font-bold uppercase tracking-[0.2em] text-blue\">{t('public duel · photos visible')}</span>\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</div>\n\n\t\t\t\t<!-- ACTION — upload + join, or start-your-own when blocked -->\n\t\t\t\t<div class=\"mt-8 md:mt-0\">\n\t\t\t\t\t{#if viewerBlocked}\n\t\t\t\t\t\t<!-- The user can't accept this duel no matter what they upload\n\t\t\t\t\t\t     — push them to start their own. -->\n\t\t\t\t\t\t<div class=\"flex flex-col gap-3\">\n\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\thref=\"/d\"\n\t\t\t\t\t\t\t\tclass=\"inline-flex items-center justify-center rounded-xl bg-blue px-7 py-3.5 font-display text-sm font-semibold text-white no-underline transition-all hover:bg-blue/80\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{t('start your own duel →')}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\thref=\"/\"\n\t\t\t\t\t\t\t\tclass=\"inline-flex items-center justify-center rounded-xl border border-border px-7 py-3.5 font-display text-sm font-semibold text-muted no-underline transition-colors hover:border-muted/60 hover:text-text\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{t('back home')}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t{:else}\n\t\t\t\t\t\t<div class=\"mx-auto max-w-lg md:mx-0\">\n\t\t\t\t\t\t\t{#snippet duelJoinUpload()}\n\t\t\t\t\t\t\t\t<DuelUploadZone {selectedFile} {dragOver} onfile={handleFile} onremove={() => (selectedFile = null)} />\n\t\t\t\t\t\t\t{/snippet}\n\t\t\t\t\t\t\t<ReusePhoto\n\t\t\t\t\t\t\t\tloggedIn={hasSession}\n\t\t\t\t\t\t\t\tlastPhotoUrl={data.notFound ? null : (data.lastPhotoUrl ?? null)}\n\t\t\t\t\t\t\t\tothers=\"Arena\"\n\t\t\t\t\t\t\t\tuseBtnClass=\"bg-blue text-white\"\n\t\t\t\t\t\t\t\ttoggleOnClass=\"bg-blue\"\n\t\t\t\t\t\t\t\tsaveMode={hasSession ? 'toggle' : 'signup'}\n\t\t\t\t\t\t\t\thasSelection={!!selectedFile}\n\t\t\t\t\t\t\t\tbind:save={savePhoto}\n\t\t\t\t\t\t\t\tonSignUp={openJoinPicker}\n\t\t\t\t\t\t\t\tonBack={() => (selectedFile = null)}\n\t\t\t\t\t\t\t\tonUseSaved={useSavedPhotoJoin}\n\t\t\t\t\t\t\t\tupload={duelJoinUpload}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t{#if selectedFile}\n\t\t\t\t\t\t\t<div class=\"mt-5\">\n\t\t\t\t\t\t\t\t{#if hasSession}\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\tclass=\"cursor-pointer rounded-xl bg-blue px-7 py-3.5 font-display text-sm font-semibold text-white transition-all hover:bg-blue/80 disabled:opacity-50\"\n\t\t\t\t\t\t\t\t\t\tonclick={submitDirectly}\n\t\t\t\t\t\t\t\t\t\tdisabled={submitting}\n\t\t\t\t\t\t\t\t\t>{submitting ? t('uploading…') : t('accept the challenge')}</button>\n\t\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t\t<!-- RAT-529: upload and see the score first; the sign-in\n\t\t\t\t\t\t\t\t\t\t comes at the reveal, where it keeps the result. -->\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\tclass=\"cursor-pointer rounded-xl bg-blue px-7 py-3.5 font-display text-sm font-semibold text-white transition-all hover:bg-blue/80 disabled:opacity-50\"\n\t\t\t\t\t\t\t\t\t\tonclick={submitDirectly}\n\t\t\t\t\t\t\t\t\t\tdisabled={submitting}\n\t\t\t\t\t\t\t\t\t>{submitting ? t('uploading…') : t('accept the challenge')}</button>\n\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t{#if submitError}<p class=\"mt-3 text-xs text-coral\">{submitError}</p>{/if}\n\t\t\t\t\t{/if}\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- quiet expiry nudge — replaces the old expires/code/score strip;\n\t\t\t     code is useless to an invitee, \"score sealed\" was filler. -->\n\t\t\t<div class=\"mt-12 flex items-center gap-2 text-[11px] font-semibold tracking-wide text-muted/70\">\n\t\t\t\t<svg class=\"h-3.5 w-3.5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n\t\t\t\t\t<circle cx=\"12\" cy=\"12\" r=\"9\" />\n\t\t\t\t\t<path d=\"M12 7v5l3 3\" />\n\t\t\t\t</svg>\n\t\t\t\t<span>{t('expires in')} <span class=\"font-bold tabular-nums {expUrgent ? 'text-coral' : 'text-muted'}\">{pad(expH)}:{pad(expM)}:{pad(expS)}</span></span>\n\t\t\t</div>\n\n\t\t<!-- ─── AUTH EMAIL ──────────────────────────────────────────────── -->\n\t\t{:else if view === 'auth-email'}\n\t\t\t<div class=\"mx-auto flex min-h-[60vh] max-w-md flex-col items-center justify-center text-center\">\n\t\t\t\t<h2 class=\"font-display text-[clamp(2rem,6vw,3.5rem)] font-bold leading-[0.9] tracking-tighter\">{t('one more thing')}<br /><span class=\"text-muted\">{t('before the duel.')}</span></h2>\n\t\t\t\t<p class=\"mx-auto mt-5 max-w-xs text-sm leading-relaxed text-muted\">{t('one tap with google, or use email — no password.')}</p>\n\t\t\t\t<div class=\"mt-8 w-full\">\n\t\t\t\t\t<OAuthButtonRow next={`/d/${duel?.code ?? ''}`} beforeRedirect={prepareOAuthRedirect} />\n\t\t\t\t</div>\n\t\t\t\t<div class=\"mt-6 w-full max-w-xs\">\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"email\"\n\t\t\t\t\t\tbind:value={email}\n\t\t\t\t\t\tplaceholder=\"you@email.com\"\n\t\t\t\t\t\tdisabled={emailSending}\n\t\t\t\t\t\tclass=\"w-full rounded-xl border border-border bg-surface py-3.5 px-4 text-sm text-text placeholder:text-muted/20 focus:border-blue/40 focus:outline-none disabled:opacity-50\"\n\t\t\t\t\t\tonkeydown={(e) => { if (e.key === 'Enter') submitEmail(); }}\n\t\t\t\t\t/>\n\t\t\t\t\t{#if emailError}<p class=\"mt-2 text-[11px] text-coral\">{emailError}</p>{:else}<p class=\"mt-2 text-[11px] text-muted/30\">{t('6-digit code, no password.')}</p>{/if}\n\t\t\t\t</div>\n\t\t\t\t<div class=\"mt-6 flex flex-col items-center gap-3\">\n\t\t\t\t\t<button class=\"w-full max-w-xs cursor-pointer rounded-xl bg-blue px-7 py-3.5 font-display text-sm font-semibold text-white hover:bg-blue/80 disabled:opacity-50\" onclick={submitEmail} disabled={emailSending}>\n\t\t\t\t\t\t{emailSending ? t('sending…') : t('send code')}\n\t\t\t\t\t</button>\n\t\t\t\t\t{#if !emailSending}\n\t\t\t\t\t\t<button class=\"cursor-pointer text-xs text-muted/30 hover:text-text\" onclick={() => { joinStep = 'fomo'; }}>{t('← back')}</button>\n\t\t\t\t\t{/if}\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t<!-- ─── AUTH OTP ─────────────────────────────────────────────────── -->\n\t\t{:else if view === 'auth-otp'}\n\t\t\t<div class=\"mx-auto flex min-h-[60vh] max-w-md flex-col items-center justify-center text-center\">\n\t\t\t\t<h2 class=\"font-display text-[clamp(2rem,6vw,3.5rem)] font-bold leading-[0.9] tracking-tighter\">{t('enter the code.')}</h2>\n\t\t\t\t<p class=\"mt-5 max-w-sm text-sm text-muted\">{t('6-digit code sent to')} <strong class=\"break-all text-text\">{email}</strong></p>\n\t\t\t\t<div class=\"mt-8 w-full max-w-[220px]\">\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\tinputmode=\"numeric\"\n\t\t\t\t\t\tautocomplete=\"one-time-code\"\n\t\t\t\t\t\tmaxlength=\"6\"\n\t\t\t\t\t\tbind:value={otpCode}\n\t\t\t\t\t\tplaceholder=\"000000\"\n\t\t\t\t\t\tdisabled={otpVerifying || submitting}\n\t\t\t\t\t\tclass=\"w-full rounded-xl border border-border bg-surface py-4 text-center font-display text-2xl font-bold tracking-[0.3em] text-text placeholder:text-muted/10 focus:border-blue/40 focus:outline-none disabled:opacity-50\"\n\t\t\t\t\t\tonkeydown={(e) => { if (e.key === 'Enter') verifyOtp(); }}\n\t\t\t\t\t/>\n\t\t\t\t\t{#if otpError}<p class=\"mt-2 text-[11px] text-coral\">{otpError}</p>{:else if submitError}<p class=\"mt-2 text-[11px] text-coral\">{submitError}</p>{:else}<p class=\"mt-2 text-[11px] text-muted/30\">{t('check inbox or spam')}</p>{/if}\n\t\t\t\t</div>\n\t\t\t\t<div class=\"mt-6 flex flex-col items-center gap-3\">\n\t\t\t\t\t<button class=\"inline-flex w-full max-w-xs cursor-pointer items-center justify-center gap-2 rounded-xl bg-blue px-7 py-3.5 font-display text-sm font-semibold text-white hover:bg-blue/80 disabled:opacity-50\" onclick={verifyOtp} disabled={otpVerifying || submitting || otpCode.length < 6}>\n\t\t\t\t\t\t{#if submitting}\n\t\t\t\t\t\t\t<svg class=\"h-4 w-4 animate-spin\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\"><path d=\"M21 12a9 9 0 1 1-6.219-8.56\"/></svg>\n\t\t\t\t\t\t\t{t('submitting…')}\n\t\t\t\t\t\t{:else if otpVerifying}\n\t\t\t\t\t\t\t<svg class=\"h-4 w-4 animate-spin\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\"><path d=\"M21 12a9 9 0 1 1-6.219-8.56\"/></svg>\n\t\t\t\t\t\t\t{t('verifying…')}\n\t\t\t\t\t\t{:else}{t('verify & join')}{/if}\n\t\t\t\t\t</button>\n\t\t\t\t\t<div class=\"flex items-center gap-3\">\n\t\t\t\t\t\t{#if otpCooldown > 0}\n\t\t\t\t\t\t\t<span class=\"text-xs text-muted/30\">{t('resend in {n}s', { n: otpCooldown })}</span>\n\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t<button class=\"cursor-pointer text-xs text-muted/30 hover:text-text\" onclick={resendOtp}>{t('resend code')}</button>\n\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t<span class=\"text-muted/10\">|</span>\n\t\t\t\t\t\t<button class=\"cursor-pointer text-xs text-muted/30 hover:text-text\" onclick={() => { joinStep = 'email'; }}>{t('different email')}</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t<!-- ─── OPPONENT PROCESSING ──────────────────────────────────────── -->\n\t\t{:else if view === 'opponent-processing'}\n\t\t\t<div class=\"loader-shell\">\n\t\t\t\t<div class=\"mx-auto w-fit\"><AnalyzingProgress colorClass=\"text-blue\" size={72} /></div>\n\t\t\t\t<h2 class=\"mt-8 font-display text-[clamp(1.6rem,5vw,2.5rem)] font-bold tracking-tighter\">\n\t\t\t\t\t{t('analyzing')}<span class=\"text-blue\">…</span>\n\t\t\t\t</h2>\n\t\t\t\t<p class=\"mt-4 max-w-sm text-sm text-muted\">{t(\"the ai is rating your photo across 6 dimensions. the challenger's score is sealed — results revealed simultaneously.\")}</p>\n\t\t\t</div>\n\n\t\t<!-- ─── OPPONENT FAILED ──────────────────────────────────────────── -->\n\t\t{:else if view === 'opponent-failed'}\n\t\t\t<div class=\"flex min-h-[60vh] flex-col items-center justify-center text-center\">\n\t\t\t\t<svg class=\"h-16 w-16 text-coral/30\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\"/><line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\"/></svg>\n\t\t\t\t<h2 class=\"mt-6 font-display text-[clamp(1.8rem,5vw,3rem)] font-bold tracking-tight\">\n\t\t\t\t\t{analysisTimedOut ? t('still') : t('analysis')} <span class=\"text-coral\">{analysisTimedOut ? t('thinking…') : t('failed.')}</span>\n\t\t\t\t</h2>\n\t\t\t\t<p class=\"mt-3 max-w-sm text-sm text-muted\">\n\t\t\t\t\t{#if analysisTimedOut}\n\t\t\t\t\t\t{t('the ai took too long to score your photo. your photo is safe — give it another shot.')}\n\t\t\t\t\t{:else}\n\t\t\t\t\t\t{myEntry?.errorMessage || t('something went wrong.')}\n\t\t\t\t\t{/if}\n\t\t\t\t</p>\n\t\t\t\t<button\n\t\t\t\t\tclass=\"mt-8 cursor-pointer rounded-xl bg-blue px-7 py-3.5 font-display text-sm font-semibold text-white hover:bg-blue/80\"\n\t\t\t\t\tonclick={retryAnalysis}\n\t\t\t\t>{t('try again')}</button>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"mt-4 cursor-pointer text-xs text-muted underline underline-offset-2 hover:text-text\"\n\t\t\t\t\tonclick={() => { entryId = null; selectedFile = null; uploadedImagePath = null; joinStep = 'fomo'; }}\n\t\t\t\t>{t('upload a different photo')}</button>\n\t\t\t</div>\n\n\t\t<!-- ─── COUNTDOWN ──────────────────────────────────────────────── -->\n\t\t{:else if view === 'countdown' && duel && duel.countdownStartedAt}\n\t\t\t<div class=\"loader-shell\">\n\t\t\t\t<div class=\"mb-10\">\n\t\t\t\t\t<PresenceBar\n\t\t\t\t\t\tpresences={presences}\n\t\t\t\t\t\tchallengerNickname={duel.challengerNickname}\n\t\t\t\t\t\topponentNickname={firstEntry?.nickname ?? null}\n\t\t\t\t\t\tchallengerState={challengerPresenceState}\n\t\t\t\t\t\topponentState={opponentPresenceState}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"flex flex-col items-center text-center\">\n\t\t\t\t\t<SyncCountdown countdownStartedAt={duel.countdownStartedAt} oncomplete={onCountdownComplete} />\n\t\t\t\t\t<p class=\"mt-10 text-[11px] text-muted/50\">\n\t\t\t\t\t\t{t('broadcast channel ·')} <span class=\"font-mono\">{duel.code}</span> · {t('{n} synced', { n: presences.length })}\n\t\t\t\t\t</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t<!-- ─── REVEALED ──────────────────────────────────────────────── -->\n\t\t{:else if view === 'revealed' && duel && firstEntry?.status === 'completed'}\n\t\t\t<!-- RAT-467: `challengerScore` is `Number(...) || 0` on the server, so a\n\t\t\t     challenger whose analysis failed arrives here as a hard 0.0 — and\n\t\t\t     the arena then rendered \"0.0 /10\" and handed the win to the other\n\t\t\t     side. 208 revealed duels are in exactly that state, every one of\n\t\t\t     them a shared link. Only trust the number once the generation\n\t\t\t     actually completed; null renders as \"—\". -->\n\t\t\t{@const cScore =\n\t\t\t\tduel.challengerGenerationStatus === 'completed' ? duel.challengerScore : null}\n\t\t\t{@const eScore = firstEntry.score != null ? Number(firstEntry.score) : null}\n\t\t\t<!-- Team mode aggregates scores into an average, which has no sensible\n\t\t\t     \"missing\" value — keep the existing numeric fallback there. Only the\n\t\t\t     1v1 arena distinguishes null from 0. -->\n\t\t\t{@const cScoreNum = duel.challengerScore}\n\n\t\t\t<!-- Result leads with the matchup (the payoff) — no CTAs above it.\n\t\t\t     All onward navigation is consolidated into the single hub at the\n\t\t\t     end of the page (after the breakdown). -->\n\t\t\t{#if duel.format === '1v1'}\n\t\t\t\t<DuelFightArena\n\t\t\t\t\tchallengerScore={cScore}\n\t\t\t\t\tchallengerNickname={duel.challengerNickname}\n\t\t\t\t\tchallengerAvatarUrl={getAvatarUrl(duel.challengerAvatarPath)}\n\t\t\t\t\tchallengerImageUrl={duel.challengerImageUrl}\n\t\t\t\t\tentryScore={eScore}\n\t\t\t\t\tentryNickname={firstEntry.nickname}\n\t\t\t\t\tentryAvatarUrl={getAvatarUrl(firstEntry.avatarPath)}\n\t\t\t\t\tentryImageUrl={firstEntry.imageUrl}\n\t\t\t\t/>\n\n\t\t\t\t<!-- custom duel: surface the rubric the AI scored on, under the result -->\n\t\t\t\t{#if duel.customJudgePrompt}\n\t\t\t\t\t<div class=\"mx-auto mt-6 max-w-xl rounded-xl border border-blue/25 bg-blue/[.06] px-4 py-3\">\n\t\t\t\t\t\t<div class=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t<svg class=\"h-3.5 w-3.5 text-blue\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M12 1a5 5 0 0 0-5 5v3H6a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-9a2 2 0 0 0-2-2h-1V6a5 5 0 0 0-5-5zm3 8H9V6a3 3 0 0 1 6 0v3z\"/></svg>\n\t\t\t\t\t\t\t<span class=\"font-display text-[11px] font-bold uppercase tracking-[0.18em] text-blue\">{t('custom duel')}</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<p class=\"mt-1.5 text-[13px] leading-relaxed text-text\">\n\t\t\t\t\t\t\t<span class=\"text-muted\">{t('judged on:')}</span> {duel.customJudgePrompt}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</div>\n\t\t\t\t{/if}\n\n\t\t\t\t<!-- RAT-27: post-duel follow CTA right under the matchup. RAT-64:\n\t\t\t\t\t fresh design — small eyebrow label \"unfinished business\" flanked by\n\t\t\t\t\t hairline rules (intentional section break), then a tight chip:\n\t\t\t\t\t avatar + bold @nickname + filled coral FollowButton. Typography\n\t\t\t\t\t + composition do the work, no card, no neon. -->\n\t\t\t\t{#if data.followOpponent && !data.followOpponent.viewerFollows}\n\t\t\t\t\t{@const opponent = data.followOpponent}\n\t\t\t\t\t{@const opponentAvatarPath = isChallenger ? firstEntry?.avatarPath ?? null : duel.challengerAvatarPath}\n\t\t\t\t\t{@const opponentHref = opponent.nickname ? `/u/${encodeURIComponent(opponent.nickname)}` : null}\n\t\t\t\t\t<div\n\t\t\t\t\t\tclass=\"follow-cta\"\n\t\t\t\t\t\tstyle=\"--accent-color: var(--color-blue); --accent-color-dark: var(--color-blue-dark); --accent-color-light: var(--color-blue-light);\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<span class=\"follow-cta__eyebrow\">{t('unfinished business')}</span>\n\t\t\t\t\t\t<div class=\"follow-cta__row\">\n\t\t\t\t\t\t\t<DuelAvatar\n\t\t\t\t\t\t\t\tnickname={opponent.nickname}\n\t\t\t\t\t\t\t\tavatarUrl={getAvatarUrl(opponentAvatarPath)}\n\t\t\t\t\t\t\t\tsize={40}\n\t\t\t\t\t\t\t\thref={opponentHref}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t{#if opponentHref}\n\t\t\t\t\t\t\t\t<a class=\"follow-cta__name\" href={opponentHref}>@{opponent.nickname}</a>\n\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t<span class=\"follow-cta__name follow-cta__name--muted\">{t('@them')}</span>\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t<FollowButton\n\t\t\t\t\t\t\t\ttargetUserId={opponent.userId}\n\t\t\t\t\t\t\t\tinitialIsFollowing={opponent.viewerFollows}\n\t\t\t\t\t\t\t\tsource=\"post_duel\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t{/if}\n\t\t\t{:else}\n\t\t\t\t{@const teamAEntries = entries.filter((e) => e.teamPosition === 'A').sort((x, y) => x.slotIndex - y.slotIndex)}\n\t\t\t\t{@const teamBEntries = entries.filter((e) => e.teamPosition === 'B').sort((x, y) => x.slotIndex - y.slotIndex)}\n\t\t\t\t{@const teamAScores = [cScoreNum, ...teamAEntries.map((e) => Number(e.score) || 0)]}\n\t\t\t\t{@const teamBScores = teamBEntries.map((e) => Number(e.score) || 0)}\n\t\t\t\t{@const teamAAvg = teamAScores.reduce((s, x) => s + x, 0) / teamAScores.length}\n\t\t\t\t{@const teamBAvg = teamBScores.length ? teamBScores.reduce((s, x) => s + x, 0) / teamBScores.length : 0}\n\t\t\t\t{@const winner = teamAAvg > teamBAvg ? 'A' : teamBAvg > teamAAvg ? 'B' : 'tie'}\n\t\t\t\t<!-- Public photo mode is decided at duel creation; joiners inherit it\n\t\t\t\t     (see [code]/+page.server.ts submitEntry). One source of truth. -->\n\t\t\t\t{@const showPhotos = duel.showChallengerPhoto}\n\n\t\t\t\t{@const teamAMembersUI = [\n\t\t\t\t\t{ id: 'challenger', nickname: duel.challengerNickname, avatarPath: duel.challengerAvatarPath, imageUrl: duel.challengerImageUrl, score: cScoreNum },\n\t\t\t\t\t...teamAEntries.map((e) => ({ id: e.id, nickname: e.nickname, avatarPath: e.avatarPath, imageUrl: e.imageUrl, score: Number(e.score) || 0 }))\n\t\t\t\t]}\n\t\t\t\t{@const teamBMembersUI = teamBEntries.map((e) => ({ id: e.id, nickname: e.nickname, avatarPath: e.avatarPath, imageUrl: e.imageUrl, score: Number(e.score) || 0 }))}\n\n\t\t\t\t<!-- Team result layout: side-by-side, average score per side big, members rendered\n\t\t\t\t     as either large clickable photos (public duel) or compact avatar rows. -->\n\t\t\t\t<div class=\"team-result\">\n\t\t\t\t\t<div class=\"team-side team-side--blue {winner === 'A' ? 'team-side--winner' : winner === 'tie' ? 'team-side--tie' : 'team-side--loser'}\">\n\t\t\t\t\t\t<div class=\"team-side__head\">\n\t\t\t\t\t\t\t<span class=\"team-label text-blue\">{t('team a')}</span>\n\t\t\t\t\t\t\t{#if winner === 'A'}\n\t\t\t\t\t\t\t\t<span class=\"team-badge team-badge--winner team-badge--winner-blue\">\n\t\t\t\t\t\t\t\t\t<svg width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M5 16L3 5l5.5 5L12 4l3.5 6L21 5l-2 11H5zm0 2h14v2H5z\"/></svg>\n\t\t\t\t\t\t\t\t\t{t('winner')}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t{:else if winner === 'tie'}<span class=\"team-badge team-badge--tie\">{t('tie')}</span>\n\t\t\t\t\t\t\t{:else}<span class=\"team-badge team-badge--loser\">−{(teamBAvg - teamAAvg).toFixed(1)}</span>{/if}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"team-avg\">\n\t\t\t\t\t\t\t<span class=\"team-avg__value\">{teamAAvg.toFixed(1)}</span>\n\t\t\t\t\t\t\t<span class=\"team-avg__label\">{t('team avg')}</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{#if showPhotos}\n\t\t\t\t\t\t\t<div class=\"team-photos team-photos--{teamAMembersUI.length}\">\n\t\t\t\t\t\t\t\t{#each teamAMembersUI as m (m.id)}\n\t\t\t\t\t\t\t\t\t{@const href = m.nickname ? `/u/${encodeURIComponent(m.nickname)}` : null}\n\t\t\t\t\t\t\t\t\t<figure class=\"member-photo\">\n\t\t\t\t\t\t\t\t\t\t{#if m.imageUrl}\n\t\t\t\t\t\t\t\t\t\t\t<button type=\"button\" class=\"member-photo__img-btn\" onclick={() => (lightboxImage = m.imageUrl)} aria-label={t('open {name} photo', { name: m.nickname ?? t('member') })}>\n\t\t\t\t\t\t\t\t\t\t\t\t<img src={m.imageUrl} alt={m.nickname ?? t('team a member')} loading=\"lazy\" />\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"member-photo__expand\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7\"/></svg>\n\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"member-photo__img-placeholder\">\n\t\t\t\t\t\t\t\t\t\t\t\t<DuelAvatar nickname={m.nickname} avatarUrl={getAvatarUrl(m.avatarPath)} size={64} variant=\"blue\" />\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t\t<figcaption class=\"member-photo__caption\">\n\t\t\t\t\t\t\t\t\t\t\t{#if href}\n\t\t\t\t\t\t\t\t\t\t\t\t<a href={href} class=\"member-photo__name text-blue\">{m.nickname}</a>\n\t\t\t\t\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"member-photo__name text-blue\">{m.nickname ?? t('anon')}</span>\n\t\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"member-photo__score\">{m.score.toFixed(1)}</span>\n\t\t\t\t\t\t\t\t\t\t</figcaption>\n\t\t\t\t\t\t\t\t\t</figure>\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{:else}\n\t\t\t\t\t\t\t<ul class=\"team-roster\">\n\t\t\t\t\t\t\t\t{#each teamAMembersUI as m (m.id)}\n\t\t\t\t\t\t\t\t\t{@const href = m.nickname ? `/u/${encodeURIComponent(m.nickname)}` : null}\n\t\t\t\t\t\t\t\t\t<li class=\"roster-row\">\n\t\t\t\t\t\t\t\t\t\t<DuelAvatar nickname={m.nickname} avatarUrl={getAvatarUrl(m.avatarPath)} size={36} variant=\"blue\" />\n\t\t\t\t\t\t\t\t\t\t{#if href}\n\t\t\t\t\t\t\t\t\t\t\t<a href={href} class=\"roster-row__name text-blue\">{m.nickname}</a>\n\t\t\t\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"roster-row__name text-blue\">{m.nickname ?? t('anon')}</span>\n\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t\t<span class=\"roster-row__score\">{m.score.toFixed(1)}</span>\n\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t{/if}\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"team-vs\" aria-hidden=\"true\">\n\t\t\t\t\t\t<span class=\"vs-hype team-vs__glitch\" data-text=\"VS\">VS</span>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"team-side team-side--coral {winner === 'B' ? 'team-side--winner' : winner === 'tie' ? 'team-side--tie' : 'team-side--loser'}\">\n\t\t\t\t\t\t<div class=\"team-side__head\">\n\t\t\t\t\t\t\t<span class=\"team-label text-coral\">{t('team b')}</span>\n\t\t\t\t\t\t\t{#if winner === 'B'}\n\t\t\t\t\t\t\t\t<span class=\"team-badge team-badge--winner team-badge--winner-coral\">\n\t\t\t\t\t\t\t\t\t<svg width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M5 16L3 5l5.5 5L12 4l3.5 6L21 5l-2 11H5zm0 2h14v2H5z\"/></svg>\n\t\t\t\t\t\t\t\t\t{t('winner')}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t{:else if winner === 'tie'}<span class=\"team-badge team-badge--tie\">{t('tie')}</span>\n\t\t\t\t\t\t\t{:else}<span class=\"team-badge team-badge--loser\">−{(teamAAvg - teamBAvg).toFixed(1)}</span>{/if}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"team-avg\">\n\t\t\t\t\t\t\t<span class=\"team-avg__value\">{teamBAvg.toFixed(1)}</span>\n\t\t\t\t\t\t\t<span class=\"team-avg__label\">{t('team avg')}</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{#if showPhotos}\n\t\t\t\t\t\t\t<div class=\"team-photos team-photos--{teamBMembersUI.length}\">\n\t\t\t\t\t\t\t\t{#each teamBMembersUI as m (m.id)}\n\t\t\t\t\t\t\t\t\t{@const href = m.nickname ? `/u/${encodeURIComponent(m.nickname)}` : null}\n\t\t\t\t\t\t\t\t\t<figure class=\"member-photo\">\n\t\t\t\t\t\t\t\t\t\t{#if m.imageUrl}\n\t\t\t\t\t\t\t\t\t\t\t<button type=\"button\" class=\"member-photo__img-btn\" onclick={() => (lightboxImage = m.imageUrl)} aria-label={t('open {name} photo', { name: m.nickname ?? t('member') })}>\n\t\t\t\t\t\t\t\t\t\t\t\t<img src={m.imageUrl} alt={m.nickname ?? t('team b member')} loading=\"lazy\" />\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"member-photo__expand\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7\"/></svg>\n\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"member-photo__img-placeholder\">\n\t\t\t\t\t\t\t\t\t\t\t\t<DuelAvatar nickname={m.nickname} avatarUrl={getAvatarUrl(m.avatarPath)} size={64} variant=\"coral\" />\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t\t<figcaption class=\"member-photo__caption\">\n\t\t\t\t\t\t\t\t\t\t\t{#if href}\n\t\t\t\t\t\t\t\t\t\t\t\t<a href={href} class=\"member-photo__name text-coral\">{m.nickname}</a>\n\t\t\t\t\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"member-photo__name text-coral\">{m.nickname ?? t('anon')}</span>\n\t\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"member-photo__score\">{m.score.toFixed(1)}</span>\n\t\t\t\t\t\t\t\t\t\t</figcaption>\n\t\t\t\t\t\t\t\t\t</figure>\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{:else}\n\t\t\t\t\t\t\t<ul class=\"team-roster\">\n\t\t\t\t\t\t\t\t{#each teamBMembersUI as m (m.id)}\n\t\t\t\t\t\t\t\t\t{@const href = m.nickname ? `/u/${encodeURIComponent(m.nickname)}` : null}\n\t\t\t\t\t\t\t\t\t<li class=\"roster-row\">\n\t\t\t\t\t\t\t\t\t\t<DuelAvatar nickname={m.nickname} avatarUrl={getAvatarUrl(m.avatarPath)} size={36} variant=\"coral\" />\n\t\t\t\t\t\t\t\t\t\t{#if href}\n\t\t\t\t\t\t\t\t\t\t\t<a href={href} class=\"roster-row__name text-coral\">{m.nickname}</a>\n\t\t\t\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"roster-row__name text-coral\">{m.nickname ?? t('anon')}</span>\n\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t\t<span class=\"roster-row__score\">{m.score.toFixed(1)}</span>\n\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t{/if}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t{/if}\n\n\t\t\t<!-- ─── share the matchup (RAT-67) ───────────────────────────────── -->\n\t\t\t<!-- Mirrors lobby ShareLink: 2:1 row (primary share + where-to-post),\n\t\t\t     italic helper underneath, tertiary copy-link below, then the\n\t\t\t     low-usage feed post as a text link at the very bottom. -->\n\t\t\t<div class=\"mt-10 border-t border-border pt-8\">\n\t\t\t\t<p class=\"mb-5 text-[10px] font-bold uppercase tracking-[0.2em] text-muted\">{t('post this duel')}</p>\n\t\t\t\t<div class=\"flex flex-col gap-2 sm:flex-row\">\n\t\t\t\t\t<button\n\t\t\t\t\t\tonclick={shareImage}\n\t\t\t\t\t\tdisabled={shareImageInFlight}\n\t\t\t\t\t\tclass=\"group relative w-full overflow-hidden rounded-xl bg-blue py-4 font-display text-base font-bold text-white transition-all hover:bg-blue/90 disabled:opacity-60 sm:flex-[2]\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<span class=\"pointer-events-none absolute inset-0 -translate-x-full bg-gradient-to-r from-transparent via-white/20 to-transparent transition-transform duration-700 group-hover:translate-x-full\"></span>\n\t\t\t\t\t\t<span class=\"relative flex items-center justify-center gap-2.5\">\n\t\t\t\t\t\t\t{#if shareImageInFlight}\n\t\t\t\t\t\t\t\t<svg class=\"h-4 w-4 shrink-0 animate-spin\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2.5\"><circle cx=\"12\" cy=\"12\" r=\"9\" stroke-opacity=\"0.25\"/><path d=\"M21 12a9 9 0 0 0-9-9\"/></svg>\n\t\t\t\t\t\t\t\t{t('preparing the image…')}\n\t\t\t\t\t\t\t{:else if shareImageStatus === 'shared'}\n\t\t\t\t\t\t\t\t<svg class=\"h-4 w-4 shrink-0\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2.5\"><polyline points=\"20 6 9 17 4 12\"/></svg>\n\t\t\t\t\t\t\t\t{t('out for delivery.')}\n\t\t\t\t\t\t\t{:else if shareImageStatus === 'downloaded'}\n\t\t\t\t\t\t\t\t<svg class=\"h-4 w-4 shrink-0\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2.5\"><polyline points=\"20 6 9 17 4 12\"/></svg>\n\t\t\t\t\t\t\t\t{t('saved — go drop it.')}\n\t\t\t\t\t\t\t{:else if shareImageStatus === 'error'}\n\t\t\t\t\t\t\t\t<svg class=\"h-4 w-4 shrink-0\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M12 8v4M12 16h.01\"/></svg>\n\t\t\t\t\t\t\t\t{t('broken — retry')}\n\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t<svg class=\"h-4 w-4 shrink-0\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"/><polyline points=\"7 10 12 15 17 10\"/><line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\"/></svg>\n\t\t\t\t\t\t\t\t{t('download the matchup')}\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonclick={openResultCommunityModal}\n\t\t\t\t\t\tclass=\"w-full rounded-xl border border-border px-3 py-4 font-display text-sm font-semibold text-text transition-all hover:border-muted hover:bg-white/[.03] sm:flex-1\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<span class=\"flex items-center justify-center gap-2\">\n\t\t\t\t\t\t\t<svg class=\"h-4 w-4 shrink-0\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 11l18-8-8 18-2-8-8-2z\"/></svg>\n\t\t\t\t\t\t\t{t('where to post')}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tonclick={copyResultLink}\n\t\t\t\t\tclass=\"mt-3 flex w-full items-center justify-center gap-2 rounded-xl border border-border py-3 font-display text-sm font-semibold text-muted transition-all hover:border-muted hover:text-text\"\n\t\t\t\t>\n\t\t\t\t\t{#if resultShareCopied}\n\t\t\t\t\t\t<svg class=\"h-3.5 w-3.5 shrink-0\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2.5\"><polyline points=\"20 6 9 17 4 12\"/></svg>\n\t\t\t\t\t\t{t('link copied')}\n\t\t\t\t\t{:else}\n\t\t\t\t\t\t<svg class=\"h-3.5 w-3.5 shrink-0\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\"/><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"/></svg>\n\t\t\t\t\t\t{t('copy link')}\n\t\t\t\t\t{/if}\n\t\t\t\t</button>\n\n\t\t\t\t<!-- RAT-271: post the duel to the on-platform feed. Lowest-used share\n\t\t\t\t     action (~5% of result viewers), so demoted to a tertiary text\n\t\t\t\t     link below copy link. Shown to BOTH participants (challenger +\n\t\t\t\t     opponent) — not anon spectators, who'd hit a login wall on click.\n\t\t\t\t     The API posts it as the current user (no challenger-only rule). -->\n\t\t\t\t{#if isChallenger || myEntry}\n\t\t\t\t\t<div class=\"mt-3 text-center\">\n\t\t\t\t\t\t<PostToFeedCta kind=\"duel_result\" sourceContentId={duel.code} variant=\"text\" label={t('post this duel to your feed')} />\n\t\t\t\t\t</div>\n\t\t\t\t{/if}\n\t\t\t</div>\n\n\t\t\t<!-- RAT-467: the onward hub below is written for the two people IN the\n\t\t\t     duel — it offers to reuse \"this photo\" and to start \"another\" duel.\n\t\t\t     Most of the traffic here has neither: /d/<code> links get ~196k\n\t\t\t     visits a quarter from Reddit and shares, and those readers arrive\n\t\t\t     with no photo and no duel of their own. They used to fall through\n\t\t\t     to participant copy, so the busiest surface in the product asked\n\t\t\t     its biggest audience to do something they couldn't.\n\t\t\t     Placed under the verdict rather than above it on purpose: the\n\t\t\t     result is the hook that earned the click, and \"could I beat them?\"\n\t\t\t     only lands once they've seen the scores. -->\n\t\t\t{#if !isChallenger && !myEntry}\n\t\t\t\t<div class=\"mt-8 border-t border-border pt-8\">\n\t\t\t\t\t<p class=\"mb-5 text-[10px] font-bold uppercase tracking-[0.2em] text-muted\">\n\t\t\t\t\t\t{t(\"think you'd beat them?\")}\n\t\t\t\t\t</p>\n\t\t\t\t\t<a\n\t\t\t\t\t\thref=\"/d\"\n\t\t\t\t\t\tonclick={() => analytics.trackCtaClick('duel', 'duel_result_spectator', 1)}\n\t\t\t\t\t\tclass=\"group mb-3 flex items-center gap-4 rounded-xl border border-blue/30 bg-blue/[.06] px-5 py-4 no-underline transition-all hover:border-blue/50\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<div class=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-blue/10\">\n\t\t\t\t\t\t\t<svg class=\"h-5 w-5 text-blue\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M13 10V3L4 14h7v7l9-11h-7z\"/></svg>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"min-w-0 flex-1\">\n\t\t\t\t\t\t\t<p class=\"font-display text-sm font-bold text-text\">{t('start your own duel')}</p>\n\t\t\t\t\t\t\t<p class=\"mt-0.5 text-[12px] leading-snug text-muted\">\n\t\t\t\t\t\t\t\t{t('same AI · same 6 scores · free')}\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<svg class=\"h-4 w-4 shrink-0 text-blue/70 transition-transform group-hover:translate-x-0.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2.2\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5l7 7-7 7\"/></svg>\n\t\t\t\t\t</a>\n\t\t\t\t\t<!-- A duel needs someone to duel. For a visitor with nobody lined\n\t\t\t\t\t     up that is real friction, and /rate is the same analysis with\n\t\t\t\t\t     no opponent — the split the journey audit flagged as P0. -->\n\t\t\t\t\t<a\n\t\t\t\t\t\thref=\"/rate\"\n\t\t\t\t\t\tonclick={() => analytics.trackCtaClick('rate', 'duel_result_spectator', 2)}\n\t\t\t\t\t\tclass=\"inline-flex w-full items-center justify-center rounded-xl border border-border px-6 py-4 font-display text-sm font-semibold text-text no-underline transition-all hover:border-muted hover:bg-white/[.03]\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{t('no opponent? just get rated →')}\n\t\t\t\t\t</a>\n\t\t\t\t</div>\n\t\t\t{/if}\n\n\t\t\t<!-- Onward CTAs sit right under the share zone (above the breakdown)\n\t\t\t     so they're seen without scrolling past the full dimension/verdict\n\t\t\t     analysis. Arena leads (strongest second step for duel players —\n\t\t\t     the swipe→match→chat loop retains best); beat is the secondary\n\t\t\t     competitive option; another duel kept light. /a/submit + /b/start\n\t\t\t     reuse this photo (one tap). Participants only — spectators get\n\t\t\t     their own block above. -->\n\t\t\t{#if isChallenger || myEntry}\n\t\t\t<div class=\"mt-8 border-t border-border pt-8\">\n\t\t\t\t<p class=\"mb-5 text-[10px] font-bold uppercase tracking-[0.2em] text-muted\">{t(\"what's next for you?\")}</p>\n\t\t\t\t<!-- RAT-529: the conversation is the next step — and a signed-out joiner\n\t\t\t\t\t keeps the score they just saw by signing in here. -->\n\t\t\t\t{#if myEntry && !hasSession && duel}\n\t\t\t\t\t<div class=\"mb-3 flex items-center gap-4 rounded-xl bg-surface-2 px-5 py-4\">\n\t\t\t\t\t\t<div class=\"min-w-0 flex-1\">\n\t\t\t\t\t\t\t<p class=\"font-display text-sm font-bold text-text\">{t('keep this score')}</p>\n\t\t\t\t\t\t\t<p class=\"mt-0.5 text-[12px] leading-snug text-muted-2\">\n\t\t\t\t\t\t\t\t{duel.challengerNickname ? t('sign in to save it and message @{name} for a rematch.', { name: duel.challengerNickname }) : t('sign in to save it.')}\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"shrink-0 rounded-lg bg-blue px-4 py-2.5 font-display text-sm font-bold text-white\"\n\t\t\t\t\t\t\tonclick={() => duel && openAuthSheet(`/d/${duel.code}?claim=1`, 'duel_reveal')}\n\t\t\t\t\t\t>{t('sign in')}</button>\n\t\t\t\t\t</div>\n\t\t\t\t{:else if hasSession && !data.notFound && data.followOpponent?.nickname}\n\t\t\t\t\t<a\n\t\t\t\t\t\thref=\"{resolve('/(chat)/c/[nickname]', { nickname: data.followOpponent.nickname })}?from=duel\"\n\t\t\t\t\t\tonclick={() => analytics.trackCtaClick('duel_rematch_message', 'duel_result', 0)}\n\t\t\t\t\t\tclass=\"mb-3 flex w-full items-center justify-center rounded-xl bg-text px-6 py-4 font-display text-sm font-bold text-bg no-underline\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{t('message @{name} — rematch?', { name: data.followOpponent.nickname })}\n\t\t\t\t\t</a>\n\t\t\t\t{/if}\n\t\t\t\t<a\n\t\t\t\t\thref=\"/a/submit\"\n\t\t\t\t\tonclick={() => analytics.trackCtaClick('arena', 'duel_result', 1)}\n\t\t\t\t\tclass=\"group mb-3 flex items-center gap-4 rounded-xl border border-orange/30 bg-orange/[.06] px-5 py-4 no-underline transition-all hover:border-orange/50\"\n\t\t\t\t>\n\t\t\t\t\t<div class=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-orange/10\">\n\t\t\t\t\t\t<svg class=\"h-5 w-5 text-orange\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M12.963 2.286a.75.75 0 0 0-1.071-.136 9.742 9.742 0 0 0-3.539 6.177A7.547 7.547 0 0 1 6.648 6.61a.75.75 0 0 0-1.152.082A9 9 0 1 0 15.68 4.534a7.46 7.46 0 0 1-2.717-2.248ZM15.75 14.25a3.75 3.75 0 1 1-7.313-1.172c.628.465 1.35.81 2.133 1.005a5.99 5.99 0 0 1 1.925-3.547 3.75 3.75 0 0 1 3.255 3.71Z\"/></svg>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"min-w-0 flex-1\">\n\t\t\t\t\t\t<p class=\"font-display text-sm font-bold text-text\">{t('post this to the arena')}</p>\n\t\t\t\t\t\t<p class=\"mt-0.5 text-[12px] leading-snug text-muted\">{t('public feed · strangers vote · get matched · free')}</p>\n\t\t\t\t\t</div>\n\t\t\t\t\t<svg class=\"h-4 w-4 shrink-0 text-orange/70 transition-transform group-hover:translate-x-0.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2.2\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5l7 7-7 7\"/></svg>\n\t\t\t\t</a>\n\t\t\t\t<div class=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n\t\t\t\t\t<a href=\"/b/start\" onclick={() => analytics.trackCtaClick('beat', 'duel_result', 2)} class=\"inline-flex items-center justify-center rounded-xl border border-border px-6 py-4 font-display text-sm font-semibold text-text no-underline transition-all hover:border-muted hover:bg-white/[.03]\">\n\t\t\t\t\t\t{t('let the crowd vote — beat me')}\n\t\t\t\t\t</a>\n\t\t\t\t\t<a href=\"/d\" onclick={() => analytics.trackCtaClick('duel', 'duel_result', 3)} class=\"inline-flex items-center justify-center rounded-xl border border-border px-6 py-4 font-display text-sm font-semibold text-text no-underline transition-all hover:border-muted hover:bg-white/[.03]\">\n\t\t\t\t\t\t{t('start another duel')}\n\t\t\t\t\t</a>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t{/if}\n\n\t\t\t{#if data.xpAwards?.length}\n\t\t\t\t<div class=\"mt-12\">\n\t\t\t\t\t<h3 class=\"font-display text-sm font-bold tracking-wider text-muted uppercase\">{t('xp earned')}</h3>\n\t\t\t\t\t<div class=\"mt-4 divide-y divide-border overflow-hidden rounded-2xl border border-border bg-surface\">\n\t\t\t\t\t\t{#each data.xpAwards as a (a.userId)}\n\t\t\t\t\t\t\t<div class=\"flex items-center gap-3 px-4 py-3\">\n\t\t\t\t\t\t\t\t<DuelAvatar nickname={a.nickname} avatarUrl={getAvatarUrl(a.avatarPath)} size={40} />\n\t\t\t\t\t\t\t\t<div class=\"min-w-0 flex-1\">\n\t\t\t\t\t\t\t\t\t<p class=\"truncate text-sm font-semibold text-text\">{a.nickname ?? t('someone')}</p>\n\t\t\t\t\t\t\t\t\t<p class=\"text-[11px] font-medium tracking-wide text-muted uppercase\">\n\t\t\t\t\t\t\t\t\t\t{a.result === 'win' ? t('won') : a.result === 'draw' ? t('draw') : t('lost')}\n\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<span class=\"font-display text-sm font-bold {a.result === 'win' ? 'text-green' : 'text-muted'}\">+{a.xp} XP</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{/each}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t{/if}\n\n\t\t\t<!-- The breakdown compares two sets of dimension scores. With one side\n\t\t\t     unscored there is nothing to compare — and its `results` are null\n\t\t\t     too, so it would render an empty half next to a real one. Skip it\n\t\t\t     rather than invent the missing column. -->\n\t\t\t{#if duel.format === '1v1' && cScore !== null && eScore !== null}\n\t\t\t\t<div class=\"mt-14\">\n\t\t\t\t\t<DuelResults\n\t\t\t\t\t\tchallengerScore={cScore}\n\t\t\t\t\t\tchallengerResults={duel.challengerResults}\n\t\t\t\t\t\tchallengerNickname={duel.challengerNickname}\n\t\t\t\t\t\tentryScore={eScore}\n\t\t\t\t\t\tentryResults={firstEntry.results}\n\t\t\t\t\t\tentryNickname={firstEntry.nickname}\n\t\t\t\t\t\tmode={duel.mode}\n\t\t\t\t\t\tcomparison={duel.comparison}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t{:else if duel.format !== '1v1'}\n\t\t\t\t<!-- Team-mode full breakdown. Mirrors 1v1 DuelResults section by\n\t\t\t\t     section, just team-aggregated (dimensions, comparison) or\n\t\t\t\t     multiplied per member (verdicts, tips). -->\n\t\t\t\t{@const teamAEntries = entries.filter((e) => e.teamPosition === 'A').sort((x, y) => x.slotIndex - y.slotIndex)}\n\t\t\t\t{@const teamBEntries = entries.filter((e) => e.teamPosition === 'B').sort((x, y) => x.slotIndex - y.slotIndex)}\n\t\t\t\t{@const teamAScores = [cScoreNum, ...teamAEntries.map((e) => Number(e.score) || 0)]}\n\t\t\t\t{@const teamBScores = teamBEntries.map((e) => Number(e.score) || 0)}\n\t\t\t\t{@const teamAAvg = teamAScores.reduce((s, x) => s + x, 0) / teamAScores.length}\n\t\t\t\t{@const teamBAvg = teamBScores.length ? teamBScores.reduce((s, x) => s + x, 0) / teamBScores.length : 0}\n\t\t\t\t{@const teamWinner = teamAAvg > teamBAvg ? 'A' : teamBAvg > teamAAvg ? 'B' : 'tie'}\n\t\t\t\t{@const teamAMembers = [\n\t\t\t\t\t{ nickname: duel.challengerNickname ?? t('challenger'), score: cScoreNum, results: duel.challengerResults }\n\t\t\t\t, ...teamAEntries.map((e) => ({ nickname: e.nickname ?? t('anon'), score: Number(e.score) || 0, results: e.results }))]}\n\t\t\t\t{@const teamBMembers = teamBEntries.map((e) => ({ nickname: e.nickname ?? t('anon'), score: Number(e.score) || 0, results: e.results }))}\n\t\t\t\t{@const dimensionNames = duel.challengerResults?.dimensions?.map((d) => d.name) ?? []}\n\t\t\t\t{@const teamADims = dimensionNames.map((name, i) => {\n\t\t\t\t\tconst cDim = duel.challengerResults?.dimensions?.[i];\n\t\t\t\t\tconst memberDims = teamAEntries.map((e) => e.results?.dimensions?.[i]?.score).filter((s): s is number => typeof s === 'number');\n\t\t\t\t\tconst allScores = [cDim?.score ?? 0, ...memberDims];\n\t\t\t\t\tconst avg = allScores.length ? allScores.reduce((s, x) => s + x, 0) / allScores.length : 0;\n\t\t\t\t\treturn { name, color: cDim?.color ?? '#888', score: avg };\n\t\t\t\t})}\n\t\t\t\t{@const teamBDims = dimensionNames.map((name, i) => {\n\t\t\t\t\tconst cDim = duel.challengerResults?.dimensions?.[i];\n\t\t\t\t\tconst memberDims = teamBEntries.map((e) => e.results?.dimensions?.[i]?.score).filter((s): s is number => typeof s === 'number');\n\t\t\t\t\tconst avg = memberDims.length ? memberDims.reduce((s, x) => s + x, 0) / memberDims.length : 0;\n\t\t\t\t\treturn { name, color: cDim?.color ?? '#888', score: avg };\n\t\t\t\t})}\n\t\t\t\t{@const teamADimsWon = teamADims.filter((d, i) => d.score > teamBDims[i].score).length}\n\t\t\t\t{@const teamBDimsWon = teamBDims.filter((d, i) => d.score > teamADims[i].score).length}\n\t\t\t\t<!-- Per-dimension representative feedback: take the top scorer's feedback on each side as the canonical voice. -->\n\t\t\t\t{@const teamADimFeedback = dimensionNames.map((_, i) => {\n\t\t\t\t\tconst all = [\n\t\t\t\t\t\t{ score: duel.challengerResults?.dimensions?.[i]?.score ?? -Infinity, fb: duel.challengerResults?.dimensions?.[i]?.feedback ?? '', name: duel.challengerNickname ?? t('challenger') },\n\t\t\t\t\t\t...teamAEntries.map((e) => ({ score: e.results?.dimensions?.[i]?.score ?? -Infinity, fb: e.results?.dimensions?.[i]?.feedback ?? '', name: e.nickname ?? t('anon') }))\n\t\t\t\t\t];\n\t\t\t\t\tconst top = all.reduce((best, x) => (x.score > best.score ? x : best), all[0] ?? { score: 0, fb: '', name: '' });\n\t\t\t\t\treturn top;\n\t\t\t\t})}\n\t\t\t\t{@const teamBDimFeedback = dimensionNames.map((_, i) => {\n\t\t\t\t\tconst all = teamBEntries.map((e) => ({ score: e.results?.dimensions?.[i]?.score ?? -Infinity, fb: e.results?.dimensions?.[i]?.feedback ?? '', name: e.nickname ?? t('anon') }));\n\t\t\t\t\tconst top = all.length ? all.reduce((best, x) => (x.score > best.score ? x : best), all[0]) : { score: 0, fb: '', name: '' };\n\t\t\t\t\treturn top;\n\t\t\t\t})}\n\n\t\t\t\t<!-- Dims-won / averages strip — same as 1v1's row, team-flavored -->\n\t\t\t\t{#if dimensionNames.length > 0}\n\t\t\t\t\t<div class=\"mt-14 mb-10 flex flex-wrap items-center gap-8 border-b border-border pb-6\">\n\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t<p class=\"text-[10px] font-bold uppercase tracking-[0.2em] text-muted\">{t('dimensions won')}</p>\n\t\t\t\t\t\t\t<p class=\"mt-1 font-display text-2xl font-extrabold tabular-nums\">\n\t\t\t\t\t\t\t\t<span class=\"text-blue\">{teamADimsWon}</span>\n\t\t\t\t\t\t\t\t<span class=\"text-muted/30 mx-1\">vs</span>\n\t\t\t\t\t\t\t\t<span class=\"text-coral\">{teamBDimsWon}</span>\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t<p class=\"text-[10px] font-bold uppercase tracking-[0.2em] text-muted\">{t('team averages')}</p>\n\t\t\t\t\t\t\t<p class=\"mt-1 font-display text-sm font-bold\">\n\t\t\t\t\t\t\t\t<span class=\"text-blue\">{teamAAvg.toFixed(1)}</span>\n\t\t\t\t\t\t\t\t<span class=\"text-muted/30 mx-1\">vs</span>\n\t\t\t\t\t\t\t\t<span class=\"text-coral\">{teamBAvg.toFixed(1)}</span>\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<h2 class=\"font-display text-[clamp(1.8rem,5vw,3rem)] font-bold leading-[0.95] tracking-tighter\">\n\t\t\t\t\t\t\t{t('the full breakdown.')}<br /><span class=\"text-muted\">{t('{n} dimensions. team avg vs team avg.', { n: dimensionNames.length })}</span>\n\t\t\t\t\t\t</h2>\n\t\t\t\t\t\t<p class=\"mt-3 mb-8 text-sm text-muted\">{t(\"every dimension averaged across the squad — top scorer's feedback shown as the team voice.\")}</p>\n\n\t\t\t\t\t\t<div class=\"flex flex-col\">\n\t\t\t\t\t\t\t{#each teamADims as aDim, i (aDim.name)}\n\t\t\t\t\t\t\t\t{@const bDim = teamBDims[i]}\n\t\t\t\t\t\t\t\t{@const dimWinner = aDim.score > bDim.score ? 'A' : bDim.score > aDim.score ? 'B' : 'tie'}\n\t\t\t\t\t\t\t\t{@const diff = Math.abs(aDim.score - bDim.score)}\n\t\t\t\t\t\t\t\t{@const aFb = teamADimFeedback[i]}\n\t\t\t\t\t\t\t\t{@const bFb = teamBDimFeedback[i]}\n\t\t\t\t\t\t\t\t<div class=\"border-b border-border py-5 last:border-b-0\">\n\t\t\t\t\t\t\t\t\t<div class=\"mb-3 flex items-center justify-between\">\n\t\t\t\t\t\t\t\t\t\t<div class=\"flex items-center gap-2.5\">\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"h-2.5 w-2.5 rounded-full\" style=\"background: {aDim.color}\"></div>\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"font-display text-sm font-semibold\">{aDim.name}</span>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t{#if dimWinner === 'A'}\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"text-[9px] font-bold uppercase text-muted/30\">{t('team a')} +{diff.toFixed(1)}</span>\n\t\t\t\t\t\t\t\t\t\t{:else if dimWinner === 'B'}\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"text-[9px] font-bold uppercase text-muted/30\">{t('team b')} +{diff.toFixed(1)}</span>\n\t\t\t\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"text-[9px] font-bold uppercase text-muted/20\">{t('tied')}</span>\n\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t<div class=\"flex items-center gap-3\">\n\t\t\t\t\t\t\t\t\t\t<span class=\"w-8 text-right font-display text-sm font-bold tabular-nums\" style=\"color: {aDim.color}\">{aDim.score.toFixed(1)}</span>\n\t\t\t\t\t\t\t\t\t\t<div class=\"flex h-1.5 flex-1 gap-0.5 overflow-hidden rounded-full bg-border/30\">\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"rounded-l-full transition-all duration-[1.5s]\" style=\"width: {aDim.score * 10}%; background: {aDim.color}; opacity: 0.5;\"></div>\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"ml-auto rounded-r-full transition-all duration-[1.5s]\" style=\"width: {bDim.score * 10}%; background: {aDim.color}; opacity: 0.3;\"></div>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t<span class=\"w-8 text-left font-display text-sm font-bold tabular-nums\" style=\"color: {aDim.color}\">{bDim.score.toFixed(1)}</span>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t{#if aFb.fb || bFb.fb}\n\t\t\t\t\t\t\t\t\t\t<div class=\"mt-2 flex items-start justify-between gap-6\">\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"max-w-[45%]\">\n\t\t\t\t\t\t\t\t\t\t\t\t{#if aFb.name && aFb.fb}\n\t\t\t\t\t\t\t\t\t\t\t\t\t<p class=\"mb-1 text-[10px] font-bold uppercase tracking-[0.2em] text-muted/40\">{t('top voice · {name}', { name: aFb.name })}</p>\n\t\t\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t\t\t\t<p class=\"text-[11px] leading-relaxed text-muted/40\">{aFb.fb}</p>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"max-w-[45%] text-right\">\n\t\t\t\t\t\t\t\t\t\t\t\t{#if bFb.name && bFb.fb}\n\t\t\t\t\t\t\t\t\t\t\t\t\t<p class=\"mb-1 text-[10px] font-bold uppercase tracking-[0.2em] text-muted/40\">{t('top voice · {name}', { name: bFb.name })}</p>\n\t\t\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t\t\t\t<p class=\"text-[11px] leading-relaxed text-muted/40\">{bFb.fb}</p>\n\t\t\t\t\t\t\t\t\t\t\t</div>\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</div>\n\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t{/if}\n\n\t\t\t\t<!-- WHY THE WINNER WON — big titled section, mirrors 1v1 layout -->\n\t\t\t\t{#if duel.comparison}\n\t\t\t\t\t<div class=\"mt-10\">\n\t\t\t\t\t\t<h2 class=\"font-display text-[clamp(1.8rem,5vw,3rem)] font-bold leading-[0.95] tracking-tighter\">\n\t\t\t\t\t\t\t{#if teamWinner === 'A'}\n\t\t\t\t\t\t\t\t<span class=\"text-blue\">{t('team a')}</span> {t('ran the table.')}<br /><span class=\"text-muted\">{duel.mode === 'roast' ? t('the autopsy.') : t('the play-by-play.')}</span>\n\t\t\t\t\t\t\t{:else if teamWinner === 'B'}\n\t\t\t\t\t\t\t\t<span class=\"text-coral\">{t('team b')}</span> {t('ran the table.')}<br /><span class=\"text-muted\">{duel.mode === 'roast' ? t('the autopsy.') : t('the play-by-play.')}</span>\n\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t{t('the deadlock.')}<br /><span class=\"text-muted\">{t('nobody flinched.')}</span>\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t</h2>\n\t\t\t\t\t\t<p class=\"mt-3 mb-8 text-sm text-muted\">\n\t\t\t\t\t\t\t{#if teamWinner === 'tie'}\n\t\t\t\t\t\t\t\t{t(\"ai studied both squads. couldn't pick. genuinely impressive.\")}\n\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t{t('every score, every rank. ai picked sides — no diplomacy.')}\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t</p>\n\n\t\t\t\t\t\t<div class=\"verdict-text text-[14px] leading-[1.8] text-text/70\" style=\"text-align: justify;\">{duel.comparison.verdict}</div>\n\n\t\t\t\t\t\t{#if duel.comparison.keyDifferences.length > 0}\n\t\t\t\t\t\t\t<div class=\"mt-8 flex flex-col\">\n\t\t\t\t\t\t\t\t{#each duel.comparison.keyDifferences as diff (diff.dimension)}\n\t\t\t\t\t\t\t\t\t<div class=\"border-b border-border/40 py-4 last:border-b-0\">\n\t\t\t\t\t\t\t\t\t\t<div class=\"mb-1.5 flex items-center justify-between\">\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"font-display text-sm font-semibold lowercase\">{diff.dimension}</span>\n\t\t\t\t\t\t\t\t\t\t\t{#if diff.favors === 'challenger'}\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"text-[9px] font-bold uppercase tracking-[0.15em] text-blue/70\">{t('team a edge')}</span>\n\t\t\t\t\t\t\t\t\t\t\t{:else if diff.favors === 'entry'}\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"text-[9px] font-bold uppercase tracking-[0.15em] text-coral/70\">{t('team b edge')}</span>\n\t\t\t\t\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"text-[9px] font-bold uppercase tracking-[0.15em] text-muted/40\">{t('tied')}</span>\n\t\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t<p class=\"text-[12px] leading-relaxed text-muted/60\">{diff.reasoning}</p>\n\t\t\t\t\t\t\t\t\t</div>\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{/if}\n\t\t\t\t\t</div>\n\t\t\t\t{/if}\n\n\t\t\t\t<!-- Per-member individual verdicts — mirrors 1v1's side-by-side verdicts but with a row per member. -->\n\t\t\t\t{#if teamAMembers.some((m) => m.results?.verdict) || teamBMembers.some((m) => m.results?.verdict)}\n\t\t\t\t\t<div class=\"mt-10\">\n\t\t\t\t\t\t<h2 class=\"font-display text-[clamp(1.8rem,5vw,3rem)] font-bold leading-[0.95] tracking-tighter\">\n\t\t\t\t\t\t\t{t('what the AI thinks.')}<br /><span class=\"text-muted\">{t('every player. every angle.')}</span>\n\t\t\t\t\t\t</h2>\n\t\t\t\t\t\t<p class=\"mt-3 mb-8 text-sm text-muted\">{t('the unfiltered AI verdicts on each member of the squad.')}</p>\n\n\t\t\t\t\t\t<div class=\"grid gap-10 md:grid-cols-2\">\n\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t<p class=\"mb-4 text-[10px] font-bold uppercase tracking-[0.2em] text-blue\">{t('team a')}</p>\n\t\t\t\t\t\t\t\t<div class=\"space-y-8\">\n\t\t\t\t\t\t\t\t\t{#each teamAMembers as m, i (i)}\n\t\t\t\t\t\t\t\t\t\t{#if m.results?.verdict}\n\t\t\t\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"mb-2 flex items-baseline justify-between gap-3\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<p class=\"font-display text-sm font-bold text-blue\">{m.nickname}</p>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"font-display text-sm font-bold tabular-nums text-text/70\">{m.score.toFixed(1)}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"verdict-text text-[13px] leading-[1.7] text-text/60\" style=\"text-align: justify;\">{@html sanitizeVerdict(m.results.verdict)}</div>\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"mt-3 flex flex-wrap items-center gap-4 border-t border-border/30 pt-2\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t{#if m.results.rank}<span class=\"text-[11px] text-muted/40\">{t('rank:')} <strong class=\"text-accent/60\">{m.results.rank}</strong></span>{/if}\n\t\t\t\t\t\t\t\t\t\t\t\t\t{#if m.results.potential > m.score}<span class=\"text-[11px] text-muted/40\">{t('potential:')} <strong class=\"text-text/60\">{m.results.potential.toFixed(1)}</strong></span>{/if}\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t<p class=\"mb-4 text-[10px] font-bold uppercase tracking-[0.2em] text-coral\">{t('team b')}</p>\n\t\t\t\t\t\t\t\t<div class=\"space-y-8\">\n\t\t\t\t\t\t\t\t\t{#each teamBMembers as m, i (i)}\n\t\t\t\t\t\t\t\t\t\t{#if m.results?.verdict}\n\t\t\t\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"mb-2 flex items-baseline justify-between gap-3\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<p class=\"font-display text-sm font-bold text-coral\">{m.nickname}</p>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"font-display text-sm font-bold tabular-nums text-text/70\">{m.score.toFixed(1)}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"verdict-text text-[13px] leading-[1.7] text-text/60\" style=\"text-align: justify;\">{@html sanitizeVerdict(m.results.verdict)}</div>\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"mt-3 flex flex-wrap items-center gap-4 border-t border-border/30 pt-2\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t{#if m.results.rank}<span class=\"text-[11px] text-muted/40\">{t('rank:')} <strong class=\"text-accent/60\">{m.results.rank}</strong></span>{/if}\n\t\t\t\t\t\t\t\t\t\t\t\t\t{#if m.results.potential > m.score}<span class=\"text-[11px] text-muted/40\">{t('potential:')} <strong class=\"text-text/60\">{m.results.potential.toFixed(1)}</strong></span>{/if}\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t{/if}\n\n\t\t\t\t<!-- Per-member tips. Mirrors 1v1's two-column tips block. -->\n\t\t\t\t{#if teamAMembers.some((m) => m.results?.tips?.length) || teamBMembers.some((m) => m.results?.tips?.length)}\n\t\t\t\t\t<div class=\"mt-10\">\n\t\t\t\t\t\t<h2 class=\"font-display text-[clamp(1.8rem,5vw,3rem)] font-bold leading-[0.95] tracking-tighter\">\n\t\t\t\t\t\t\t{t('room for improvement.')}<br /><span class=\"text-muted\">{t('for the whole squad.')}</span>\n\t\t\t\t\t\t</h2>\n\t\t\t\t\t\t<p class=\"mt-3 mb-8 text-sm text-muted\">{t(\"the AI's recommendations, per player.\")}</p>\n\n\t\t\t\t\t\t<div class=\"grid gap-10 md:grid-cols-2\">\n\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t<p class=\"mb-4 text-[10px] font-bold uppercase tracking-[0.2em] text-blue\">{t('team a')}</p>\n\t\t\t\t\t\t\t\t<div class=\"space-y-6\">\n\t\t\t\t\t\t\t\t\t{#each teamAMembers as m, mi (mi)}\n\t\t\t\t\t\t\t\t\t\t{#if m.results?.tips?.length}\n\t\t\t\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t\t\t\t<p class=\"mb-3 text-[11px] font-semibold uppercase tracking-[0.15em] text-blue/70\">{m.nickname}</p>\n\t\t\t\t\t\t\t\t\t\t\t\t{#each m.results.tips as tip (tip.num)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"flex gap-3 border-b border-border/30 py-3 last:border-b-0\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"shrink-0 pt-0.5 font-display text-[10px] font-bold text-muted/20\">{tip.num}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<p class=\"text-[12px] font-semibold text-text/70\">{tip.title}</p>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<p class=\"mt-0.5 text-[11px] leading-relaxed text-muted/40\">{tip.desc}</p>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"mt-1 inline-flex items-center gap-1 rounded bg-accent/[.08] px-1.5 py-0.5 text-[10px] font-semibold text-accent\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<svg class=\"h-2.5 w-2.5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"><polyline points=\"23,6 13.5,15.5 8.5,10.5 1,18\"/><polyline points=\"17,6 23,6 23,12\"/></svg>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{tip.impact}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t<p class=\"mb-4 text-[10px] font-bold uppercase tracking-[0.2em] text-coral\">{t('team b')}</p>\n\t\t\t\t\t\t\t\t<div class=\"space-y-6\">\n\t\t\t\t\t\t\t\t\t{#each teamBMembers as m, mi (mi)}\n\t\t\t\t\t\t\t\t\t\t{#if m.results?.tips?.length}\n\t\t\t\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t\t\t\t<p class=\"mb-3 text-[11px] font-semibold uppercase tracking-[0.15em] text-coral/70\">{m.nickname}</p>\n\t\t\t\t\t\t\t\t\t\t\t\t{#each m.results.tips as tip (tip.num)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"flex gap-3 border-b border-border/30 py-3 last:border-b-0\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"shrink-0 pt-0.5 font-display text-[10px] font-bold text-muted/20\">{tip.num}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<p class=\"text-[12px] font-semibold text-text/70\">{tip.title}</p>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<p class=\"mt-0.5 text-[11px] leading-relaxed text-muted/40\">{tip.desc}</p>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"mt-1 inline-flex items-center gap-1 rounded bg-accent/[.08] px-1.5 py-0.5 text-[10px] font-semibold text-accent\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<svg class=\"h-2.5 w-2.5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"><polyline points=\"23,6 13.5,15.5 8.5,10.5 1,18\"/><polyline points=\"17,6 23,6 23,12\"/></svg>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{tip.impact}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t{/if}\n\t\t\t{/if}\n\n\t\t\t<!-- Repeat the onward hub at the very bottom so deep-readers who scrolled\n\t\t\t\t     the full breakdown still have a way forward (mirrors the hub above\n\t\t\t\t     the breakdown). location='duel_result_bottom' so we can measure\n\t\t\t\t     whether this end-of-page copy earns its place.\n\t\t\t\t     RAT-467: split by audience like the top hub. A spectator who read\n\t\t\t\t     the entire breakdown is the most engaged visitor on the page —\n\t\t\t\t     worth asking properly rather than handing them \"post THIS photo\"\n\t\t\t\t     for a photo they never uploaded. -->\n\t\t\t{#if !isChallenger && !myEntry}\n\t\t\t\t<div class=\"mt-16 border-t border-border pt-10\">\n\t\t\t\t\t<p class=\"mb-5 text-[10px] font-bold uppercase tracking-[0.2em] text-muted\">\n\t\t\t\t\t\t{t('read the whole thing?')}\n\t\t\t\t\t</p>\n\t\t\t\t\t<div class=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n\t\t\t\t\t\t<a\n\t\t\t\t\t\t\thref=\"/d\"\n\t\t\t\t\t\t\tonclick={() => analytics.trackCtaClick('duel', 'duel_result_spectator_bottom', 1)}\n\t\t\t\t\t\t\tclass=\"inline-flex items-center justify-center rounded-xl bg-blue px-6 py-4 font-display text-sm font-semibold text-white no-underline transition-all hover:bg-blue/80\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{t('start your own duel')}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t\t<a\n\t\t\t\t\t\t\thref=\"/rate\"\n\t\t\t\t\t\t\tonclick={() => analytics.trackCtaClick('rate', 'duel_result_spectator_bottom', 2)}\n\t\t\t\t\t\t\tclass=\"inline-flex items-center justify-center rounded-xl border border-border px-6 py-4 font-display text-sm font-semibold text-text no-underline transition-all hover:border-muted hover:bg-white/[.03]\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{t('just get rated')}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t{:else}\n\t\t\t\t<div class=\"mt-16 border-t border-border pt-10\">\n\t\t\t\t\t<p class=\"mb-5 text-[10px] font-bold uppercase tracking-[0.2em] text-muted\">{t(\"what's next for you?\")}</p>\n\t\t\t\t\t<a\n\t\t\t\t\t\thref=\"/a/submit\"\n\t\t\t\t\t\tonclick={() => analytics.trackCtaClick('arena', 'duel_result_bottom', 1)}\n\t\t\t\t\t\tclass=\"group mb-3 flex items-center gap-4 rounded-xl border border-orange/30 bg-orange/[.06] px-5 py-4 no-underline transition-all hover:border-orange/50\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<div class=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-orange/10\">\n\t\t\t\t\t\t\t<svg class=\"h-5 w-5 text-orange\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M12.963 2.286a.75.75 0 0 0-1.071-.136 9.742 9.742 0 0 0-3.539 6.177A7.547 7.547 0 0 1 6.648 6.61a.75.75 0 0 0-1.152.082A9 9 0 1 0 15.68 4.534a7.46 7.46 0 0 1-2.717-2.248ZM15.75 14.25a3.75 3.75 0 1 1-7.313-1.172c.628.465 1.35.81 2.133 1.005a5.99 5.99 0 0 1 1.925-3.547 3.75 3.75 0 0 1 3.255 3.71Z\"/></svg>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"min-w-0 flex-1\">\n\t\t\t\t\t\t\t<p class=\"font-display text-sm font-bold text-text\">{t('post this to the arena')}</p>\n\t\t\t\t\t\t\t<p class=\"mt-0.5 text-[12px] leading-snug text-muted\">{t('public feed · strangers vote · get matched · free')}</p>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<svg class=\"h-4 w-4 shrink-0 text-orange/70 transition-transform group-hover:translate-x-0.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2.2\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5l7 7-7 7\"/></svg>\n\t\t\t\t\t</a>\n\t\t\t\t\t<div class=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n\t\t\t\t\t\t<a href=\"/b/start\" onclick={() => analytics.trackCtaClick('beat', 'duel_result_bottom', 2)} class=\"inline-flex items-center justify-center rounded-xl border border-border px-6 py-4 font-display text-sm font-semibold text-text no-underline transition-all hover:border-muted hover:bg-white/[.03]\">\n\t\t\t\t\t\t\t{t('let the crowd vote — beat me')}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t\t<a href=\"/d\" onclick={() => analytics.trackCtaClick('duel', 'duel_result_bottom', 3)} class=\"inline-flex items-center justify-center rounded-xl border border-border px-6 py-4 font-display text-sm font-semibold text-text no-underline transition-all hover:border-muted hover:bg-white/[.03]\">\n\t\t\t\t\t\t\t{t('start another duel')}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t{/if}\n\n\t\t\t\t<!-- spectator waitlist (still useful post-reveal for email notifs) — hidden since it's revealed -->\n\n\t\t<!-- ─── TERMINAL FALLBACK ──────────────────────────────────────────\n\t\t     The derived `view` matched no branch above, or a branch's extra\n\t\t     guard (`&& duel`, `&& firstEntry?.status === 'completed'`, …)\n\t\t     rejected it. Without this the wrapper renders NOTHING — a silent\n\t\t     blank page on the viral inbound surface. Degrade to the same\n\t\t     graceful pane used for corrupted server-side loads instead. -->\n\t\t{:else}\n\t\t\t<div class=\"flex min-h-[60vh] flex-col items-center justify-center text-center\">\n\t\t\t\t<h1 class=\"font-display text-[clamp(2.5rem,8vw,5rem)] font-bold tracking-tighter\">\n\t\t\t\t\t{t('this duel')}<br /><span class=\"text-muted/40\">{t('went sideways.')}</span>\n\t\t\t\t</h1>\n\t\t\t\t<p class=\"mt-4 max-w-md text-sm text-muted\">\n\t\t\t\t\t{t(\"something didn't load right. try a refresh — if it sticks, it's on us, and we already got the heads-up.\")}\n\t\t\t\t</p>\n\t\t\t\t<div class=\"mt-8 flex flex-col gap-2 sm:flex-row sm:justify-center\">\n\t\t\t\t\t<button type=\"button\" onclick={goBack} class=\"inline-flex items-center justify-center gap-2 rounded-xl border border-border px-6 py-3.5 font-display text-sm font-semibold text-text transition-all hover:border-muted hover:bg-white/[.03]\">\n\t\t\t\t\t\t<svg class=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M19 12H5M12 19l-7-7 7-7\"/></svg>\n\t\t\t\t\t\t{t('go back')}\n\t\t\t\t\t</button>\n\t\t\t\t\t<a href=\"/d\" class=\"inline-flex items-center justify-center rounded-xl bg-blue px-6 py-3.5 font-display text-sm font-semibold text-white no-underline hover:bg-blue/80\">{t('start your own')}</a>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t{/if}\n\n\t\t<!-- Spectator waitlist — only pre-reveal in lobby/fomo/countdown -->\n\t\t{#if duel && !duel.revealed && (view === 'lobby' || view === 'countdown') && !isChallenger && !myEntry}\n\t\t\t<section class=\"mt-16 border-t border-border pt-12\">\n\t\t\t\t<h2 class=\"font-display text-[clamp(1.6rem,4vw,2.5rem)] font-bold leading-[0.95] tracking-tighter\">\n\t\t\t\t\t{t('not joining?')}<br /><span class=\"text-muted\">{t('get notified.')}</span>\n\t\t\t\t</h2>\n\t\t\t\t<p class=\"mt-3 max-w-lg text-sm leading-relaxed text-muted\">{t(\"drop your email — we'll ping you the second results are revealed.\")}</p>\n\t\t\t\t{#if waitlistDone}\n\t\t\t\t\t<div class=\"mt-6 flex items-center gap-2 text-sm text-accent\">\n\t\t\t\t\t\t<svg class=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2.5\"><polyline points=\"20 6 9 17 4 12\"/></svg>\n\t\t\t\t\t\t{t(\"you're on the list.\")}\n\t\t\t\t\t</div>\n\t\t\t\t{:else}\n\t\t\t\t\t<div class=\"mt-6 flex max-w-md items-center gap-2\">\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\ttype=\"email\"\n\t\t\t\t\t\t\tbind:value={waitlistEmail}\n\t\t\t\t\t\t\tplaceholder=\"your@email.com\"\n\t\t\t\t\t\t\tdisabled={waitlistSubmitting}\n\t\t\t\t\t\t\tclass=\"min-w-0 flex-1 rounded-xl border border-border bg-surface px-4 py-3 text-sm text-text placeholder:text-muted/20 focus:border-blue/30 focus:outline-none disabled:opacity-50\"\n\t\t\t\t\t\t\tonkeydown={(e) => { if (e.key === 'Enter') submitWaitlist(); }}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\tclass=\"shrink-0 cursor-pointer rounded-xl bg-blue px-5 py-3 font-display text-sm font-semibold text-white hover:bg-blue/80 disabled:opacity-50\"\n\t\t\t\t\t\t\tonclick={submitWaitlist}\n\t\t\t\t\t\t\tdisabled={waitlistSubmitting || !waitlistEmail.includes('@')}\n\t\t\t\t\t\t>{waitlistSubmitting ? '…' : t('notify me')}</button>\n\t\t\t\t\t</div>\n\t\t\t\t\t{#if waitlistError}<p class=\"mt-2 text-xs text-coral\">{waitlistError}</p>{/if}\n\t\t\t\t{/if}\n\t\t\t</section>\n\t\t{/if}\n\t</div>\n\n\t<!-- ─── REPORT LINK (RAT-236) ─── -->\n\t{#if duel}\n\t\t<div class=\"mx-auto mt-8 mb-12 max-w-3xl px-5 text-center\">\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tonclick={() => (reportOpen = true)}\n\t\t\t\tclass=\"text-[11px] text-muted/40 underline-offset-2 transition-colors hover:text-muted hover:underline\"\n\t\t\t>\n\t\t\t\t{t('report this duel')}\n\t\t\t</button>\n\t\t</div>\n\t{/if}\n</main>\n\n{#if duel}\n\t<ReportContentModal\n\t\tbind:open={reportOpen}\n\t\tentityType=\"duel_entry\"\n\t\tentityId={duel.id}\n\t\tonclose={() => (reportOpen = false)}\n\t/>\n{/if}\n\n<!-- ─── Member-photo lightbox (team-mode reveal) ──────────────────── -->\n{#if lightboxImage}\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"lightbox\"\n\t\tonclick={() => (lightboxImage = null)}\n\t\tonkeydown={(e) => { if (e.key === 'Escape') lightboxImage = null; }}\n\t\taria-label={t('close photo')}\n\t>\n\t\t<img src={lightboxImage} alt=\"\" />\n\t\t<span class=\"lightbox__close\" aria-hidden=\"true\">\n\t\t\t<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\"><path d=\"M6 18L18 6M6 6l12 12\"/></svg>\n\t\t</span>\n\t</button>\n{/if}\n\n<!-- ─── Global floating dock (emoji + chat combined) ──────────────── -->\n{#if duel && showDock}\n\t<!-- RAT-277: pass liftAboveNav explicitly instead of relying on a\n\t\t body class. !duelFocusMode (= not lobby/fomo) means the bottom\n\t\t nav is visible, so the dock must lift above it. -->\n\t<DuelDock\n\t\tcode={duel.code}\n\t\treactions={activeReactions}\n\t\tcomments={comments}\n\t\tpermission={duel.commentsPermission}\n\t\thasSession={hasSession}\n\t\tliftAboveNav={!duelFocusMode}\n\t\tonreact={broadcastReaction}\n\t\toncomment={submitComment}\n\t\tonvoice={submitVoice}\n\t/>\n{/if}\n\n<!-- challenger feature-the-board prompt while waiting with no opponent. -->\n{#if featurePromptOpen && duel}\n\t<DuelFeatureNudge code={duel.code} onclose={() => (featurePromptOpen = false)} />\n{/if}\n\n<!-- \"where to post\" modal launched from the revealed-view CTA hub. The\n     showImageShare prop turns on the save-image-first step (RAT-67), and\n     postTitle pre-fills the reddit submit form with the destroyed headline. -->\n{#if showResultCommunityModal && ResultCommunityModal && duel}\n\t<ResultCommunityModal\n\t\tcode={duel.code}\n\t\turl={resultShareUrl}\n\t\tisInviter={isChallenger}\n\t\tsharePosition=\"result_page\"\n\t\tshowImageShare\n\t\tpostTitle={resultPostTitle}\n\t\tonclose={() => (showResultCommunityModal = false)}\n\t/>\n{/if}\n\n<style>\n\t/* Batch 23: focus-mode main override. body.duel-focus-mode is set by\n\t   $effect when view is lobby/fomo — pb-60 (240px) is overkill once\n\t   the nav is hidden and the dock drops to env+12. Trim to ~120px so\n\t   content sits closer to the dock without overlapping it. */\n\t:global(body.duel-focus-mode) .duel-main {\n\t\tpadding-bottom: 120px;\n\t}\n\n\t/* warp field */\n\t.warp-field {\n\t\tposition: absolute; inset: 0; overflow: hidden; pointer-events: none;\n\t\tperspective: 400px;\n\t}\n\t/* Loader views (countdown / \"analyzing…\") render as a fixed, viewport-pinned\n\t   layer: the content is short and fits, and a position:fixed layer cannot be\n\t   scrolled — so focusing the chat dock input (mobile keyboard) can't drag the\n\t   loader off-screen the way a normal in-flow + min-h-screen page can. */\n\t.loader-shell {\n\t\tposition: fixed;\n\t\tinset: 0;\n\t\tz-index: 1;\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\tpadding: 96px 20px 128px;\n\t\ttext-align: center;\n\t\toverflow: hidden;\n\t}\n\t.warp-streak {\n\t\tposition: absolute; top: 50%; left: 50%;\n\t\twidth: var(--len); height: 1px;\n\t\tbackground: linear-gradient(90deg, transparent, rgba(255,255,255, var(--o)), transparent);\n\t\ttransform-origin: 0% 50%;\n\t\ttransform: rotate(var(--angle)) translateX(var(--dist));\n\t\tanimation: warp-out var(--dur) linear var(--del) infinite;\n\t}\n\t@keyframes warp-out {\n\t\t0% { transform: rotate(var(--angle)) translateX(5%) scaleX(0.3); opacity: 0; }\n\t\t15% { opacity: 1; }\n\t\t100% { transform: rotate(var(--angle)) translateX(120%) scaleX(2); opacity: 0; }\n\t}\n\n\t/* ─── hyped matchup row ─── */\n\t.matchup-row {\n\t\tposition: relative;\n\t\tdisplay: flex; align-items: center;\n\t\tgap: 10px;\n\t\tpadding: 18px 14px;\n\t\tborder: 1px solid var(--color-border);\n\t\tborder-radius: 20px;\n\t\tbackground:\n\t\t\tradial-gradient(ellipse 45% 90% at 50% 50%, rgba(0,0,0,0.55) 0%, transparent 70%),\n\t\t\tlinear-gradient(180deg, rgba(255,255,255,0.014) 0%, rgba(255,255,255,0) 100%),\n\t\t\trgba(10,10,10,0.4);\n\t\tbox-shadow:\n\t\t\t0 40px 80px -40px rgba(0,0,0,0.9),\n\t\t\t0 1px 0 rgba(255,255,255,0.04) inset,\n\t\t\t0 -1px 0 rgba(0,0,0,0.4) inset;\n\t\toverflow: hidden;\n\t}\n\t@media (min-width: 640px) {\n\t\t.matchup-row {\n\t\t\tdisplay: inline-flex;\n\t\t\tgap: clamp(0.75rem, 3vw, 2rem);\n\t\t\tpadding: 22px clamp(1rem, 3vw, 1.75rem);\n\t\t}\n\t}\n\t/* glow behind VS — dual-tone (desktop only; mobile renders the soft blur as\n\t   a hard-edged blob in Safari/Chrome, so we hide it under 640px) */\n\t.matchup-row::before {\n\t\tcontent: '';\n\t\tposition: absolute; left: 50%; top: 50%;\n\t\twidth: 140px; height: 140px;\n\t\ttransform: translate(-50%, -50%);\n\t\tbackground:\n\t\t\tradial-gradient(circle, rgba(59,130,246,0.18) 0%, rgba(59,130,246,0) 55%),\n\t\t\tradial-gradient(circle at 60% 60%, rgba(255,77,109,0.08) 0%, rgba(255,77,109,0) 60%);\n\t\tfilter: blur(20px);\n\t\tpointer-events: none; z-index: 0;\n\t\tanimation: vs-pulse 3.4s ease-in-out infinite;\n\t\tdisplay: none;\n\t}\n\t@media (min-width: 640px) {\n\t\t.matchup-row::before {\n\t\t\tdisplay: block;\n\t\t\twidth: clamp(180px, 20vw, 260px); height: clamp(180px, 20vw, 260px);\n\t\t\tfilter: blur(24px);\n\t\t}\n\t}\n\t/* subtle dark center \"well\" layered on top of bg */\n\t.matchup-row::after {\n\t\tcontent: '';\n\t\tposition: absolute; left: 50%; top: 50%;\n\t\twidth: 100px; height: 100px;\n\t\ttransform: translate(-50%, -50%);\n\t\tbackground: radial-gradient(circle, rgba(0,0,0,0.7) 0%, transparent 70%);\n\t\tpointer-events: none; z-index: 0;\n\t}\n\t@media (min-width: 640px) {\n\t\t.matchup-row::after { width: clamp(120px, 14vw, 180px); height: clamp(120px, 14vw, 180px); }\n\t}\n\t.matchup-row > * { position: relative; z-index: 1; }\n\t@keyframes vs-pulse {\n\t\t0%, 100% { opacity: 0.9; transform: translate(-50%, -50%) scale(0.95); }\n\t\t50%      { opacity: 1;   transform: translate(-50%, -50%) scale(1.08); }\n\t}\n\t.matchup-side {\n\t\tdisplay: flex; align-items: center; gap: 10px;\n\t\tmin-width: 0; flex: 1;\n\t}\n\t.matchup-side--right { justify-content: flex-end; text-align: right; }\n\t.matchup-side > .min-w-0 { min-width: 0; }\n\n\t/* Team-mode matchup: vertical roster on each side, VS centered between them. */\n\t.matchup-row.team-matchup { align-items: stretch; padding: 18px 14px; }\n\t.matchup-row.team-matchup > .vs-wrap { align-self: center; }\n\t.team-stack {\n\t\tdisplay: flex; flex-direction: column; gap: 8px;\n\t\tflex: 1; min-width: 0;\n\t}\n\t.team-stack--right { align-items: flex-end; }\n\t.team-label {\n\t\tdisplay: block;\n\t\tfont-family: var(--font-display);\n\t\tfont-size: 10px; font-weight: 800; letter-spacing: 0.2em;\n\t\ttext-transform: uppercase;\n\t\topacity: 0.85;\n\t\tmargin-bottom: 4px;\n\t}\n\t.team-member {\n\t\tdisplay: flex; align-items: center; gap: 10px;\n\t\tmin-width: 0;\n\t}\n\t.team-member--right { justify-content: flex-end; text-align: right; }\n\t.team-member--open { opacity: 0.55; }\n\t.team-member > .min-w-0 { min-width: 0; }\n\t.member-name {\n\t\tdisplay: block;\n\t\tfont-family: var(--font-display);\n\t\tfont-size: 0.95rem; font-weight: 800;\n\t\tletter-spacing: -0.01em;\n\t\ttext-decoration: none;\n\t\tmax-width: 100%;\n\t\toverflow: hidden; text-overflow: ellipsis; white-space: nowrap;\n\t}\n\t@media (min-width: 640px) {\n\t\t.member-name { font-size: 1.05rem; }\n\t}\n\t.member-name--muted { color: rgba(115,115,115,0.6); }\n\t.member-state {\n\t\tdisplay: flex; align-items: center; gap: 6px;\n\t\tfont-family: var(--font-display);\n\t\tfont-size: 10px; font-weight: 700; letter-spacing: 0.12em;\n\t\ttext-transform: uppercase;\n\t\tcolor: rgba(115,115,115,0.7);\n\t\tmargin-top: 2px;\n\t}\n\t.member-state--right { justify-content: flex-end; }\n\n\t/* ─── Team-mode reveal ───────────────────────────────────────────────\n\t * Two team cards flanking a center VS. Each card uses CSS custom props\n\t * (--team-c, --team-glow) keyed by colour modifier so winner glow + badges\n\t * pick up the right brand shade without per-team duplicate rules. */\n\t.team-result {\n\t\tdisplay: grid;\n\t\tgrid-template-columns: 1fr;\n\t\tgap: 14px;\n\t\tmargin-top: 24px;\n\t}\n\t@media (min-width: 880px) {\n\t\t.team-result {\n\t\t\tgrid-template-columns: 1fr auto 1fr;\n\t\t\tgap: clamp(1rem, 2vw, 2rem);\n\t\t\talign-items: stretch;\n\t\t}\n\t}\n\t.team-side {\n\t\t--team-c: 115, 115, 115;\n\t\tposition: relative;\n\t\tdisplay: flex; flex-direction: column;\n\t\tgap: 16px;\n\t\tpadding: 20px 18px;\n\t\tborder: 1px solid var(--color-border);\n\t\tborder-radius: 20px;\n\t\tbackground: var(--color-surface);\n\t\tmin-width: 0;\n\t\ttransition: opacity 0.2s, border-color 0.2s;\n\t}\n\t@media (min-width: 768px) { .team-side { padding: 24px 22px; } }\n\t.team-side--blue { --team-c: 59, 130, 246; }\n\t.team-side--coral { --team-c: 255, 77, 109; }\n\t.team-side--tie { border-color: rgba(115,115,115,0.4); }\n\t.team-side--loser { opacity: 0.55; }\n\n\t/* Winner: rotating conic-gradient stroke around the border. The pseudo sits on\n\t * top with a mask cutout so only a 2px ring is visible. @property lets the angle\n\t * actually animate (without it conic-gradient just hard-cuts). */\n\t@property --winner-angle { syntax: '<angle>'; initial-value: 0deg; inherits: false; }\n\t.team-side--winner {\n\t\tborder-color: transparent;\n\t}\n\t.team-side--winner::before {\n\t\tcontent: '';\n\t\tposition: absolute; inset: 0;\n\t\tborder-radius: inherit;\n\t\tpadding: 2px;\n\t\tbackground: conic-gradient(\n\t\t\tfrom var(--winner-angle),\n\t\t\trgba(var(--team-c), 0.85) 0deg,\n\t\t\trgba(var(--team-c), 0.2) 90deg,\n\t\t\trgba(var(--team-c), 0.85) 180deg,\n\t\t\trgba(var(--team-c), 0.2) 270deg,\n\t\t\trgba(var(--team-c), 0.85) 360deg\n\t\t);\n\t\t-webkit-mask: linear-gradient(#000, #000) content-box, linear-gradient(#000, #000);\n\t\t-webkit-mask-composite: xor;\n\t\tmask-composite: exclude;\n\t\tpointer-events: none;\n\t\tanimation: winner-rotate 5s linear infinite;\n\t}\n\t@keyframes winner-rotate { to { --winner-angle: 360deg; } }\n\t@supports not (background: conic-gradient(from 0deg, red, blue)) {\n\t\t.team-side--winner { border-color: rgba(var(--team-c), 0.6); }\n\t\t.team-side--winner::before { display: none; }\n\t}\n\n\t.team-side__head {\n\t\tdisplay: flex; align-items: center; justify-content: space-between;\n\t\tgap: 8px;\n\t}\n\t.team-label {\n\t\tfont-family: var(--font-display);\n\t\tfont-size: 11px; font-weight: 800;\n\t\tletter-spacing: 0.22em; text-transform: uppercase;\n\t}\n\t.team-badge {\n\t\tfont-family: var(--font-display);\n\t\tfont-size: 9px; font-weight: 800; letter-spacing: 0.18em;\n\t\ttext-transform: uppercase;\n\t\tpadding: 5px 10px; border-radius: 999px;\n\t\tdisplay: inline-flex; align-items: center; gap: 5px;\n\t}\n\t.team-badge--winner { background: rgba(var(--team-c), 0.18); color: rgb(var(--team-c)); border: 1px solid rgba(var(--team-c), 0.4); }\n\t.team-badge--tie { background: rgba(115,115,115,0.18); color: var(--color-text); }\n\t.team-badge--loser {\n\t\tbackground: transparent;\n\t\tcolor: rgba(115,115,115,0.7);\n\t\tborder: 1px solid var(--color-border);\n\t\tfont-variant-numeric: tabular-nums;\n\t}\n\n\t.team-avg {\n\t\tdisplay: flex; align-items: baseline; gap: 12px;\n\t}\n\t.team-avg__value {\n\t\tfont-family: var(--font-display);\n\t\tfont-size: clamp(2.8rem, 7vw, 4rem);\n\t\tfont-weight: 900; letter-spacing: -0.035em;\n\t\tline-height: 1;\n\t\tfont-variant-numeric: tabular-nums;\n\t}\n\t.team-side--winner .team-avg__value { color: rgb(var(--team-c)); }\n\t.team-avg__label {\n\t\tfont-family: var(--font-display);\n\t\tfont-size: 10px; font-weight: 700; letter-spacing: 0.22em;\n\t\ttext-transform: uppercase; color: var(--color-muted); opacity: 0.7;\n\t}\n\n\t/* ── Photo gallery (public duel) ─────────────────────────────────── */\n\t.team-photos {\n\t\tdisplay: grid;\n\t\tgrid-template-columns: repeat(2, minmax(0, 1fr));\n\t\tgap: 10px;\n\t}\n\t/* Per-count overrides — 1 stays large, 2 is the sweet spot, 3 + 4 stay 2-wide\n\t * so the per-photo size doesn't shrink to a thumbnail at 4v4 (which would\n\t * defeat the \"see the actual photo\" point). 4v4 wraps to a 2×2 grid. */\n\t.team-photos--1 { grid-template-columns: minmax(0, 1fr); max-width: 220px; }\n\t.team-photos--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }\n\t.team-photos--3 .member-photo__img-btn,\n\t.team-photos--4 .member-photo__img-btn {\n\t\taspect-ratio: 1 / 1; /* square at higher density so faces don't get tall */\n\t}\n\t.member-photo {\n\t\tdisplay: flex; flex-direction: column; gap: 8px;\n\t\tmargin: 0;\n\t}\n\t.member-photo__img-btn {\n\t\tposition: relative; display: block; width: 100%;\n\t\taspect-ratio: 4 / 5;\n\t\tborder-radius: 14px;\n\t\toverflow: hidden;\n\t\tborder: 1px solid var(--color-border);\n\t\tbackground: rgba(0,0,0,0.4);\n\t\tcursor: zoom-in;\n\t\tpadding: 0;\n\t\ttransition: border-color 0.18s;\n\t}\n\t.member-photo__img-btn:hover { border-color: var(--color-muted); }\n\t.member-photo__img-btn img {\n\t\twidth: 100%; height: 100%;\n\t\tobject-fit: cover;\n\t\tdisplay: block;\n\t}\n\t.member-photo__expand {\n\t\tposition: absolute; right: 8px; bottom: 8px;\n\t\tdisplay: inline-flex; align-items: center; justify-content: center;\n\t\twidth: 26px; height: 26px;\n\t\tborder-radius: 8px;\n\t\tbackground: rgba(0,0,0,0.55);\n\t\tbackdrop-filter: blur(4px);\n\t\tcolor: rgba(255,255,255,0.85);\n\t\topacity: 0; transition: opacity 0.18s;\n\t}\n\t.member-photo__img-btn:hover .member-photo__expand,\n\t.member-photo__img-btn:focus-visible .member-photo__expand { opacity: 1; }\n\t.member-photo__img-placeholder {\n\t\tdisplay: flex; align-items: center; justify-content: center;\n\t\twidth: 100%; aspect-ratio: 4 / 5;\n\t\tborder-radius: 14px;\n\t\tbackground: rgba(255,255,255,0.02);\n\t\tborder: 1px dashed var(--color-border);\n\t}\n\t.member-photo__caption {\n\t\tdisplay: flex; align-items: baseline; justify-content: space-between;\n\t\tgap: 8px; padding: 0 4px;\n\t\tmin-width: 0;\n\t}\n\t.member-photo__name {\n\t\tfont-family: var(--font-display);\n\t\tfont-size: 12px; font-weight: 700;\n\t\tletter-spacing: -0.01em;\n\t\ttext-decoration: none;\n\t\tmin-width: 0; max-width: 70%;\n\t\toverflow: hidden; text-overflow: ellipsis; white-space: nowrap;\n\t}\n\t.member-photo__name:hover { text-decoration: underline; text-underline-offset: 3px; }\n\t.member-photo__score {\n\t\tfont-family: var(--font-display);\n\t\tfont-size: 14px; font-weight: 800;\n\t\tletter-spacing: -0.02em;\n\t\tcolor: var(--color-text);\n\t\tfont-variant-numeric: tabular-nums;\n\t}\n\n\t/* ── Roster (private duel — avatar rows) ─────────────────────────── */\n\t.team-roster {\n\t\tlist-style: none; padding: 0; margin: 0;\n\t\tdisplay: flex; flex-direction: column; gap: 6px;\n\t}\n\t.roster-row {\n\t\tdisplay: flex; align-items: center; gap: 12px;\n\t\tpadding: 10px 12px;\n\t\tborder-radius: 12px;\n\t\tbackground: rgba(255,255,255,0.02);\n\t\tborder: 1px solid transparent;\n\t\ttransition: background 0.18s, border-color 0.18s;\n\t}\n\t.roster-row:hover { background: rgba(255,255,255,0.04); border-color: var(--color-border); }\n\t.roster-row__name {\n\t\tflex: 1; min-width: 0;\n\t\tfont-family: var(--font-display);\n\t\tfont-size: 0.95rem; font-weight: 700;\n\t\tletter-spacing: -0.01em;\n\t\ttext-decoration: none;\n\t\toverflow: hidden; text-overflow: ellipsis; white-space: nowrap;\n\t}\n\t.roster-row__name:hover { text-decoration: underline; text-underline-offset: 3px; }\n\t.roster-row__score {\n\t\tfont-family: var(--font-display);\n\t\tfont-size: 1.05rem; font-weight: 800; letter-spacing: -0.02em;\n\t\tcolor: var(--color-text);\n\t\tfont-variant-numeric: tabular-nums;\n\t\tline-height: 1;\n\t}\n\n\t/* ── Center VS divider — chromatic-aberration glitch, no chrome ──── */\n\t.team-vs {\n\t\tdisplay: flex; align-items: center; justify-content: center;\n\t\tpadding: 4px 0;\n\t}\n\t.team-vs__glitch {\n\t\tfont-size: 1.4rem;\n\t}\n\t@media (min-width: 880px) {\n\t\t.team-vs__glitch { font-size: clamp(1.6rem, 2.4vw, 2.4rem); }\n\t}\n\n\t/* ── Lightbox (member photo full-size) ───────────────────────────── */\n\t.lightbox {\n\t\tposition: fixed; inset: 0; z-index: 100;\n\t\tdisplay: flex; align-items: center; justify-content: center;\n\t\tpadding: 24px;\n\t\tbackground: rgba(0,0,0,0.92);\n\t\tbackdrop-filter: blur(8px);\n\t\tcursor: zoom-out;\n\t}\n\t.lightbox img {\n\t\tmax-width: 100%;\n\t\tmax-height: calc(100vh - 80px);\n\t\tobject-fit: contain;\n\t\tborder-radius: 12px;\n\t\tbox-shadow: 0 32px 80px -16px rgba(0,0,0,0.8);\n\t}\n\t.lightbox__close {\n\t\tposition: absolute; top: 16px; right: 16px;\n\t\twidth: 36px; height: 36px;\n\t\tborder-radius: 50%;\n\t\tbackground: rgba(255,255,255,0.1);\n\t\tcolor: white;\n\t\tdisplay: inline-flex; align-items: center; justify-content: center;\n\t\tcursor: pointer; border: 0;\n\t\ttransition: background 0.18s;\n\t}\n\t.lightbox__close:hover { background: rgba(255,255,255,0.2); }\n\n\t@media (min-width: 640px) {\n\t\t.matchup-side { flex: initial; gap: 12px; }\n\t}\n\t.matchup-name--muted { color: rgba(115,115,115,0.5); }\n\t.matchup-name {\n\t\tdisplay: block;\n\t\tfont-family: var(--font-display);\n\t\tfont-size: 1rem; font-weight: 800;\n\t\tletter-spacing: -0.01em;\n\t\ttext-decoration: none;\n\t\ttransition: opacity 0.15s;\n\t\tmax-width: 100%;\n\t\toverflow: hidden; text-overflow: ellipsis; white-space: nowrap;\n\t}\n\t@media (min-width: 640px) {\n\t\t.matchup-name { font-size: clamp(1.05rem, 2.4vw, 1.35rem); }\n\t}\n\ta.matchup-name:hover { opacity: 0.8; text-decoration: underline; text-underline-offset: 4px; }\n\t.challenger-link {\n\t\tdisplay: inline-block; margin-top: 2px;\n\t\tfont-family: var(--font-display);\n\t\tfont-size: clamp(1.25rem, 3vw, 1.6rem); font-weight: 800;\n\t\tletter-spacing: -0.01em; color: var(--color-text);\n\t\ttext-decoration: none; transition: opacity 0.15s;\n\t}\n\ta.challenger-link:hover { opacity: 0.8; text-decoration: underline; text-underline-offset: 4px; }\n\t.matchup-state {\n\t\tmargin-top: 6px;\n\t\tdisplay: none; align-items: center; gap: 8px;\n\t\tfont-family: var(--font-display);\n\t\tfont-size: 10px; font-weight: 700;\n\t\ttext-transform: uppercase; letter-spacing: 0.2em;\n\t\tcolor: var(--color-muted);\n\t\twhite-space: nowrap;\n\t}\n\t/* PresenceBar above already shows state — keep in-row state only on wider screens */\n\t@media (min-width: 640px) {\n\t\t.matchup-state { display: flex; }\n\t}\n\t.matchup-state--right { justify-content: flex-end; flex-direction: row-reverse; }\n\t.state-dot {\n\t\tdisplay: inline-block; width: 6px; height: 6px; border-radius: 50%;\n\t}\n\t.state-dot--blue {\n\t\tbackground: var(--color-blue); box-shadow: 0 0 6px rgba(59,130,246,0.6);\n\t\tanimation: state-pulse 2.4s ease-in-out infinite;\n\t}\n\t.state-dot--coral {\n\t\tbackground: var(--color-coral); box-shadow: 0 0 6px rgba(255,77,109,0.6);\n\t\tanimation: state-pulse 2.4s ease-in-out infinite;\n\t}\n\t.state-dot--muted { background: var(--color-muted); opacity: 0.4; }\n\t@keyframes state-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.35; } }\n\n\t/* ─── hyped VS badge ─── */\n\t.vs-wrap {\n\t\tposition: relative; display: inline-flex; align-items: center; justify-content: center;\n\t\twidth: 58px; height: 58px;\n\t\tflex-shrink: 0;\n\t}\n\t@media (min-width: 640px) {\n\t\t.vs-wrap { width: clamp(70px, 9vw, 100px); height: clamp(70px, 9vw, 100px); }\n\t}\n\t.vs-ring {\n\t\tposition: absolute; inset: 0;\n\t\tborder-radius: 50%;\n\t\tborder: 1px solid rgba(255,255,255,0.06);\n\t\tanimation: vs-breathe 3.2s ease-in-out infinite;\n\t}\n\t.vs-ring::before, .vs-ring::after {\n\t\tcontent: ''; position: absolute; inset: -1px;\n\t\tborder-radius: 50%; border: 1px solid transparent;\n\t}\n\t.vs-ring::before {\n\t\tborder-top-color: var(--color-blue);\n\t\tborder-right-color: var(--color-blue);\n\t\tanimation: vs-spin-a 4s linear infinite;\n\t\topacity: 0.35;\n\t}\n\t.vs-ring::after {\n\t\tborder-bottom-color: var(--color-coral);\n\t\tborder-left-color: var(--color-coral);\n\t\tanimation: vs-spin-b 5.2s linear infinite;\n\t\topacity: 0.28;\n\t}\n\t@keyframes vs-spin-a { to { transform: rotate(360deg); } }\n\t@keyframes vs-spin-b { to { transform: rotate(-360deg); } }\n\t@keyframes vs-breathe {\n\t\t0%, 100% { transform: scale(1); border-color: rgba(255,255,255,0.06); }\n\t\t50%      { transform: scale(1.04); border-color: rgba(255,255,255,0.12); }\n\t}\n\n\t.vs-hype {\n\t\tposition: relative;\n\t\tfont-family: var(--font-display);\n\t\tfont-size: 1.2rem;\n\t\tfont-weight: 900;\n\t\tletter-spacing: 0.05em;\n\t\tcolor: var(--color-text);\n\t\ttext-shadow:\n\t\t\t0 0 30px rgba(59,130,246,0.3),\n\t\t\t0 0 8px rgba(59,130,246,0.15);\n\t}\n\t@media (min-width: 640px) {\n\t\t.vs-hype { font-size: clamp(1.4rem, 3.2vw, 2.2rem); }\n\t}\n\t.vs-hype::before, .vs-hype::after {\n\t\tcontent: attr(data-text); position: absolute; top: 0; left: 0; right: 0; bottom: 0;\n\t\tdisplay: flex; align-items: center; justify-content: center;\n\t\tpointer-events: none;\n\t}\n\t.vs-hype::before {\n\t\tcolor: var(--color-coral); opacity: 0;\n\t\tclip-path: polygon(0 0, 100% 0, 100% 45%, 0 45%);\n\t\tanimation: g1 3s ease-in-out infinite;\n\t}\n\t.vs-hype::after {\n\t\tcolor: var(--color-blue); opacity: 0;\n\t\tclip-path: polygon(0 55%, 100% 55%, 100% 100%, 0 100%);\n\t\tanimation: g2 2.8s ease-in-out infinite;\n\t}\n\t@keyframes g1 {\n\t\t0%, 72%, 80%, 100% { transform: translate(0,0); opacity: 0; }\n\t\t74% { transform: translate(-4px, -1px); opacity: 0.9; }\n\t\t76% { transform: translate(3px, 1px); opacity: 1; }\n\t\t78% { transform: translate(-1px, 0); opacity: 0.7; }\n\t}\n\t@keyframes g2 {\n\t\t0%, 68%, 76%, 100% { transform: translate(0,0); opacity: 0; }\n\t\t70% { transform: translate(3px, 1px); opacity: 0.9; }\n\t\t72% { transform: translate(-3px, -1px); opacity: 1; }\n\t\t74% { transform: translate(1px, 0); opacity: 0.7; }\n\t}\n\n\t/* ─── compact stats strip ─── */\n\t.stat-strip {\n\t\tdisplay: grid; grid-template-columns: repeat(3, 1fr);\n\t\tgap: 0;\n\t\tborder-top: 1px solid var(--color-border);\n\t\tpadding-top: 20px;\n\t}\n\t.stat {\n\t\tdisplay: flex; flex-direction: column; gap: 6px;\n\t\tpadding: 4px 0;\n\t}\n\t.stat + .stat { border-left: 1px solid var(--color-border); padding-left: 20px; }\n\t.stat-label {\n\t\tfont-family: var(--font-display);\n\t\tfont-size: 9px; font-weight: 700;\n\t\ttext-transform: uppercase; letter-spacing: 0.25em;\n\t\tcolor: var(--color-muted); opacity: 0.6;\n\t}\n\t.stat-value {\n\t\tfont-family: var(--font-display);\n\t\tfont-size: clamp(1rem, 2.4vw, 1.25rem); font-weight: 800;\n\t\tletter-spacing: -0.01em;\n\t\tcolor: var(--color-text);\n\t\tfont-variant-numeric: tabular-nums;\n\t}\n\n\t@media (prefers-reduced-motion: reduce) {\n\t\t.warp-streak,\n\t\t.state-dot,\n\t\t.vs-ring, .vs-ring::before, .vs-ring::after,\n\t\t.vs-hype::before, .vs-hype::after { animation: none; }\n\t}\n\n\t/* ─── post-duel follow CTA (RAT-64) ──────────────────────────\n\t   Eyebrow label flanked by hairline rules (\"unfinished business\")\n\t   sits as an intentional section divider. Below: a tight chip\n\t   with the opponent's avatar, bold @handle, and the filled coral\n\t   FollowButton. No card, no surface fill, no neon — typography\n\t   and composition do the lifting. */\n\t.follow-cta {\n\t\tmargin-top: 28px;\n\t\tdisplay: flex; flex-direction: column; align-items: center;\n\t\tgap: 14px;\n\t}\n\t.follow-cta__eyebrow {\n\t\tposition: relative;\n\t\tfont-family: var(--font-display);\n\t\tfont-size: 10px; font-weight: 700;\n\t\ttext-transform: uppercase;\n\t\tletter-spacing: 0.3em;\n\t\tcolor: var(--color-muted);\n\t\topacity: 0.6;\n\t\twhite-space: nowrap;\n\t}\n\t.follow-cta__eyebrow::before,\n\t.follow-cta__eyebrow::after {\n\t\tcontent: '';\n\t\tposition: absolute; top: 50%;\n\t\twidth: 32px; height: 1px;\n\t\tbackground: var(--color-border);\n\t}\n\t.follow-cta__eyebrow::before { right: calc(100% + 12px); }\n\t.follow-cta__eyebrow::after { left: calc(100% + 12px); }\n\t.follow-cta__row {\n\t\tdisplay: flex; align-items: center;\n\t\tflex-wrap: wrap; justify-content: center;\n\t\tgap: 12px;\n\t}\n\t.follow-cta__name {\n\t\tfont-family: var(--font-display);\n\t\tfont-size: 17px; font-weight: 800;\n\t\tletter-spacing: -0.01em;\n\t\tcolor: var(--color-text);\n\t\ttext-decoration: none;\n\t\ttransition: color 0.18s;\n\t}\n\t.follow-cta__name:hover { color: var(--color-coral); }\n\t.follow-cta__name--muted { color: var(--color-muted); cursor: default; }\n</style>\n"],"version":3}