<template>
	<view class="page">
		<scroll-view scroll-y class="page-scroll">
			<view class="hero-card">
				<view class="hero-title">AI 创意助手</view>
				<view class="hero-desc">
					支持文本指令与多类型附件联合驱动工作流，自动返回视频、脚本 Markdown 或图像 / 排版结果。
				</view>
				<view class="hero-actions">
					<view class="hero-action" @tap="fillExample('video')">短视频创意</view>
					<view class="hero-action" @tap="fillExample('script')">脚本创作</view>
					<view class="hero-action" @tap="fillExample('image')">海报排版</view>
				</view>
			</view>

			<view class="panel-card">
				<view class="panel-title">输入配置</view>
				<view class="field-list">
					<view class="field-item">
						<view class="field-label">文本指令</view>
						<textarea
							v-model="content"
							class="field-textarea field-textarea--large"
							placeholder="请输入用户的文本指令或需求描述，例如：根据活动照片和通知文档，生成一条公众号推文封面及 60 秒短视频脚本。"
							placeholder-style="color: #c0c4cc;"
							maxlength="-1"
						/>
					</view>

					<view class="field-item">
						<view class="field-label">上传附件</view>
						<view class="upload-bar">
							<view class="upload-btn" @tap="chooseFiles">{{ uploading ? '上传中...' : '添加附件' }}</view>
							<view class="upload-tip">支持图片、视频、音频和常见文档类型。</view>
						</view>
						<view v-if="uploadedFiles.length" class="file-list">
							<view
								v-for="(item, index) in uploadedFiles"
								:key="`${item.url || item.path || item.name}-${index}`"
								class="file-item-card"
							>
								<view class="file-main">
									<view class="file-badge">{{ getFileTypeLabel(item) }}</view>
									<view class="file-text">
										<view class="file-name">{{ item.name || getFileName(item) }}</view>
										<view class="file-url">{{ resolveFileUrl(item) || '-' }}</view>
									</view>
								</view>
								<view class="file-remove" @tap="removeUploadedFile(index)">移除</view>
							</view>
						</view>
					</view>
				</view>

				<view class="submit-bar">
					<view class="ghost-btn" @tap="resetAll">重置</view>
					<view class="primary-btn" :class="{ 'primary-btn--disabled': !canSubmit || loading }" @tap="runWorkflow">
						{{ loading ? '执行中' : '生成' }}
					</view>
				</view>
			</view>

			<view class="panel-card result-card">
				<view class="result-head">
					<view class="panel-title">工作流结果</view>
					<view class="result-status" :class="loading ? 'result-status--loading' : hasAnyResult ? 'result-status--done' : ''">
						{{ loading ? '执行中' : hasAnyResult ? '已完成' : '待执行' }}
					</view>
				</view>

				<view v-if="loading" class="loading-panel">
					<view class="loading-kicker">WORKFLOW RUNNING</view>
					<view class="loading-title">{{ loadingTitle }}</view>
					<view class="loading-desc">{{ loadingDescription }}</view>
					<view class="loading-steps">
						<view
							v-for="(item, index) in loadingSteps"
							:key="item.title"
							class="loading-step"
							:class="{ 'is-active': index === 1 }"
						>
							<view class="loading-step-index">0{{ index + 1 }}</view>
							<view class="loading-step-main">
								<view class="loading-step-title">{{ item.title }}</view>
								<view class="loading-step-desc">{{ item.desc }}</view>
							</view>
						</view>
					</view>
				</view>

				<view v-else-if="!hasAnyResult" class="result-empty">
					填写文本指令并上传附件后执行工作流
				</view>

				<view v-else class="result-body">
					<view v-if="statusMessage" class="status-alert">
						{{ statusMessage }}
					</view>

					<view v-if="videoFiles.length" class="result-section">
						<view class="section-title">视频生成结果</view>
						<view class="video-list">
							<view
								v-for="(item, index) in videoFiles"
								:key="`${resolveFileUrl(item)}-${index}`"
								class="video-card"
							>
								<video
									v-if="isVideoFile(item)"
									class="video-player"
									controls
									object-fit="cover"
									:src="resolveFileUrl(item)"
								></video>
								<view class="result-meta">
									<view class="result-name">{{ item.name || getFileName(item) }}</view>
									<view class="result-link" @tap="copyFileLink(item)">复制链接</view>
								</view>
							</view>
						</view>
					</view>

					<view v-if="scriptDisplayContent" class="result-section">
						<view class="section-title">脚本创作结果</view>
						<zero-markdown-view
							class="script-shell script-markdown"
							:markdown="scriptDisplayContent"
						/>
					</view>

					<view v-if="photoFiles.length" class="result-section">
						<view class="section-title">图像 / 排版结果</view>
						<view class="photo-grid">
							<view
								v-for="(item, index) in photoFiles"
								:key="`${resolveFileUrl(item)}-${index}`"
								class="photo-card"
							>
								<image
									v-if="isImageFile(item)"
									class="photo-image"
									mode="aspectFill"
									:src="resolveFileUrl(item)"
									@tap="previewImage(item)"
								/>
								<view v-else class="photo-fallback">
									<view class="file-badge">{{ getFileTypeLabel(item) }}</view>
									<view class="result-link" @tap="copyFileLink(item)">复制结果链接</view>
								</view>
								<view class="result-meta">
									<view class="result-name">{{ item.name || getFileName(item) }}</view>
									<view class="result-link" @tap="copyFileLink(item)">复制链接</view>
								</view>
							</view>
						</view>
					</view>
				</view>

				<view class="result-actions">
					<view class="result-btn" @tap="copyScript">复制脚本</view>
					<view class="result-btn" @tap="clearResult">清空结果</view>
				</view>
			</view>
		</scroll-view>
	</view>
</template>

<script>
	import { creativeAssistant, uploadAiFile } from './service'

	const DOCUMENT_FILE_EXTS = new Set([
		'TXT',
		'MD',
		'MARKDOWN',
		'PDF',
		'HTML',
		'XLSX',
		'XLS',
		'DOCX',
		'CSV',
		'EML',
		'MSG',
		'PPTX',
		'PPT',
		'XML',
		'EPUB'
	])
	const AUDIO_FILE_EXTS = new Set(['MP3', 'M4A', 'WAV', 'WEBM', 'AMR', 'AAC', 'OGG'])
	const VIDEO_FILE_EXTS = new Set(['MP4', 'MOV', 'MPEG', 'MPGA', 'WEBM', 'AVI', 'M4V'])

	export default {
		data() {
			return {
				loading: false,
				uploading: false,
				content: '',
				uploadedFiles: [],
				workflowResponse: null,
				workflowOutputs: null,
				loadingSteps: [
					{
						title: '输入理解',
						desc: '解析文本指令、识别目标输出和执行路径'
					},
					{
						title: '内容生成',
						desc: '调用工作流处理视频、脚本或图像排版任务'
					},
					{
						title: '结果整理',
						desc: '回收文件链接并整理结构化输出'
					}
				]
			}
		},
		computed: {
			canSubmit() {
				return !!String(this.content || '').trim() || this.uploadedFiles.length > 0
			},
			videoFiles() {
				return (this.workflowOutputs && this.workflowOutputs.video_result) || []
			},
			scriptMarkdown() {
				return String((this.workflowOutputs && this.workflowOutputs.Script_result) || '')
			},
			scriptDisplayContent() {
        console.log(this.scriptMarkdown
          .replace(/<think>[\s\S]*?<\/think>/g, '')
          .trim())
				return this.scriptMarkdown
					.replace(/<think>[\s\S]*?<\/think>/g, '')
					.trim()
			},
			photoFiles() {
				return (this.workflowOutputs && this.workflowOutputs.photo_files) || []
			},
			statusMessage() {
				return (
					(this.workflowOutputs && this.workflowOutputs.video_message) ||
					(this.workflowOutputs && this.workflowOutputs.photo_message) ||
					''
				)
			},
			hasAnyResult() {
				return !!(
					this.videoFiles.length ||
					this.scriptMarkdown.trim() ||
					this.photoFiles.length
				)
			},
			loadingTitle() {
				if (this.uploadedFiles.length && String(this.content || '').trim()) {
					return '正在分析指令并处理附件'
				}
				if (this.uploadedFiles.length) {
					return '正在解析附件并生成结果'
				}
				return '正在根据文本指令生成内容'
			},
			loadingDescription() {
				return '该工作流可能持续数分钟，请保持页面开启。系统正在后台完成素材理解、内容生成与结果整理。'
			}
		},
		methods: {
			showToast(title) {
				uni.showToast({
					title,
					icon: 'none'
				})
			},
			normalizeOutputPayload(payload) {
				if (!payload) {
					return {}
				}
				if (payload.outputs && typeof payload.outputs === 'object') {
					return payload.outputs
				}
				if (payload.data && payload.data.outputs && typeof payload.data.outputs === 'object') {
					return payload.data.outputs
				}
				return payload
			},
			resolveFileUrl(file) {
				if (!file) {
					return ''
				}
				return String(file.url || file.downloadUrl || file.thumbnail || file.path || '')
			},
			getFileName(file) {
				const value = this.resolveFileUrl(file)
				if (!value) {
					return '未命名文件'
				}
				try {
					return decodeURIComponent(value.split('?')[0].split('/').pop() || value)
				} catch (error) {
					return value.split('?')[0].split('/').pop() || value
				}
			},
			getFileExt(file) {
				const name = String((file && (file.name || this.getFileName(file))) || '').toLowerCase()
				return name.split('.').pop() || ''
			},
			isImageFile(file) {
				const contentType = String((file && file.contentType) || '').toLowerCase()
				if (contentType.startsWith('image/')) {
					return true
				}
				return ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'webp'].includes(this.getFileExt(file))
			},
			isVideoFile(file) {
				const contentType = String((file && file.contentType) || '').toLowerCase()
				if (contentType.startsWith('video/')) {
					return true
				}
				return ['mp4', 'mov', 'm4v', 'webm', 'avi'].includes(this.getFileExt(file))
			},
			isAudioFile(file) {
				const contentType = String((file && file.contentType) || '').toLowerCase()
				if (contentType.startsWith('audio/')) {
					return true
				}
				return ['mp3', 'wav', 'aac', 'm4a', 'ogg', 'amr'].includes(this.getFileExt(file))
			},
			getUploadFileType(file) {
				const contentType = String((file && file.contentType) || '').toLowerCase()
				const ext = this.getFileExt(file).toUpperCase()
				if (contentType.startsWith('image/')) {
					return 'image'
				}
				if (AUDIO_FILE_EXTS.has(ext)) {
					return 'audio'
				}
				if (VIDEO_FILE_EXTS.has(ext)) {
					return 'video'
				}
				if (DOCUMENT_FILE_EXTS.has(ext)) {
					return 'document'
				}
				return 'document'
			},
			getFileTypeLabel(file) {
				if (this.isImageFile(file)) {
					return '图片'
				}
				if (this.isVideoFile(file)) {
					return '视频'
				}
				if (this.isAudioFile(file)) {
					return '音频'
				}
				return '文档'
			},
			clearResult() {
				this.workflowResponse = null
				this.workflowOutputs = null
			},
			resetAll() {
				this.content = ''
				this.uploadedFiles = []
				this.clearResult()
			},
			removeUploadedFile(index) {
				this.uploadedFiles = this.uploadedFiles.filter((item, current) => current !== index)
			},
			async chooseFiles() {
				if (this.uploading) {
					return
				}
				try {
					const result = await new Promise((resolve, reject) => {
						uni.chooseMessageFile({
							count: 9,
							type: 'all',
							success: resolve,
							fail: reject
						})
					})
					const tempFiles = (result && result.tempFiles) || []
					if (!tempFiles.length) {
						return
					}
					this.uploading = true
					uni.showLoading({
						title: '上传中',
						mask: true
					})
					for (let index = 0; index < tempFiles.length; index += 1) {
						const file = tempFiles[index]
						if (file.size && file.size / 1024 / 1024 > 100) {
							this.showToast('单个附件不能超过 100MB')
							continue
						}
						const uploaded = await uploadAiFile(file)
						this.uploadedFiles = [
							...this.uploadedFiles,
							{
								id: uploaded.id,
								name: uploaded.name || file.name,
								path: uploaded.path,
								url: uploaded.url,
								downloadUrl: uploaded.downloadUrl,
								contentType: uploaded.contentType
							}
						]
					}
					this.showToast('附件上传成功')
				} catch (error) {
					if (error && error.errMsg && String(error.errMsg).includes('cancel')) {
						return
					}
					this.showToast((error && error.message) || '上传失败')
				} finally {
					this.uploading = false
					uni.hideLoading()
				}
			},
			buildRequestPayload() {
				const payload = {
					user_content: String(this.content || '').trim(),
					user_contentString: String(this.content || '').trim()
				}
				if (this.uploadedFiles.length) {
					payload.user_files = this.uploadedFiles.map((item) => ({
						transfer_method: 'local_file',
						type: this.getUploadFileType(item),
						upload_file_id: item.id,
						url: ''
					}))
				}
				return payload
			},
			async runWorkflow() {
				if (!this.canSubmit) {
					this.showToast('请先输入文本指令或上传附件')
					return
				}
				if (this.loading) {
					return
				}
				this.loading = true
				try {
					const result = await creativeAssistant(this.buildRequestPayload())
					this.workflowResponse = result || null
					this.workflowOutputs = this.normalizeOutputPayload(result || null)
					if (!this.hasAnyResult) {
						this.showToast('接口已返回，但未识别到文档约定的输出字段')
					} else {
						this.showToast('工作流执行完成')
					}
				} catch (error) {
					this.showToast((error && error.message) || '工作流执行失败')
				} finally {
					this.loading = false
				}
			},
			copyScript() {
				if (!this.scriptDisplayContent) {
					this.showToast('暂无脚本结果')
					return
				}
				uni.setClipboardData({
					data: this.scriptDisplayContent,
					success: () => {
						this.showToast('脚本已复制')
					}
				})
			},
			copyFileLink(file) {
				const url = this.resolveFileUrl(file)
				if (!url) {
					this.showToast('当前文件缺少链接')
					return
				}
				uni.setClipboardData({
					data: url,
					success: () => {
						this.showToast('链接已复制')
					}
				})
			},
			previewImage(file) {
				const url = this.resolveFileUrl(file)
				if (!url) {
					this.showToast('当前图片缺少地址')
					return
				}
				const urls = this.photoFiles.map((item) => this.resolveFileUrl(item)).filter(Boolean)
				uni.previewImage({
					current: url,
					urls
				})
			},
			fillExample(type) {
				if (type === 'video') {
					this.content = '请根据我上传的活动照片和通知文档，生成一条 45 秒校园活动宣传短视频，画面节奏明快，配一段适合配音的解说文案，并输出视频结果。'
					return
				}
				if (type === 'script') {
					this.content = '围绕“青年志愿者进社区”主题创作一份短视频分镜脚本，要求包含开场钩子、3 个主要场景和结尾号召，输出为 Markdown 脚本。'
					return
				}
				this.content = '请根据上传的活动照片、LOGO 和文案素材，生成一套公众号头图与活动海报排版，风格青春、明亮，输出图片文件。'
			}
		}
	}
</script>

<style lang="scss" scoped>
	.page {
		min-height: 100vh;
		background:
			radial-gradient(circle at top right, rgba(20, 150, 242, 0.14), transparent 24%),
			linear-gradient(180deg, #fff8f3 0%, #f7fbff 100%);
	}

	.page-scroll {
		height: 100vh;
		padding: 28rpx 24rpx 40rpx;
	}

	.hero-card {
		padding: 34rpx 30rpx;
		border-radius: 32rpx;
		background: linear-gradient(135deg, #0c5f9f 0%, #1496f2 48%, #67c7ff 100%);
		box-shadow: 0 18rpx 40rpx rgba(143, 31, 45, 0.2);
		color: #333;
	}

	.hero-kicker {
		font-size: 22rpx;
		letter-spacing: 4rpx;
		color: rgba(255, 235, 237, 0.72);
	}

	.hero-title {
		margin-top: 18rpx;
		font-size: 42rpx;
		line-height: 1.35;
		font-weight: 700;
		color: #fff8f8;
	}

	.hero-desc {
		margin-top: 16rpx;
		font-size: 24rpx;
		line-height: 1.8;
		color: rgba(255, 239, 241, 0.88);
	}

	.hero-actions {
		display: flex;
		flex-wrap: wrap;
		gap: 14rpx;
		margin-top: 26rpx;
	}

	.hero-action {
		padding: 12rpx 20rpx;
		border-radius: 999rpx;
		background: rgba(255, 255, 255, 0.12);
		font-size: 22rpx;
		color: #fff6f6;
	}

	.panel-card {
		margin-top: 24rpx;
		padding: 26rpx;
		border-radius: 30rpx;
		background: rgba(255, 255, 255, 0.96);
		border: 1rpx solid rgba(20, 150, 242, 0.08);
		box-shadow: 0 14rpx 34rpx rgba(87, 54, 30, 0.08);
	}

	.panel-title {
		font-size: 30rpx;
		font-weight: 700;
		color: #1f2329;
	}

	.field-list {
		display: flex;
		flex-direction: column;
		gap: 22rpx;
		margin-top: 20rpx;
	}

	.field-label {
		margin-bottom: 12rpx;
		font-size: 25rpx;
		font-weight: 600;
		color: #2b3037;
	}

	.field-textarea {
		width: 100%;
		min-height: 220rpx;
		padding: 22rpx 24rpx;
		border-radius: 22rpx;
		background: #fcf6f2;
		border: 1rpx solid #d6eafb;
		font-size: 24rpx;
		line-height: 1.8;
		color: #2a2e35;
		box-sizing: border-box;
	}

	.field-textarea--large {
		min-height: 360rpx;
	}

	:deep(.field-input.uv-input) {
		width: 100%;
		min-height: 88rpx;
		padding: 0 24rpx;
		border-radius: 12rpx;
		border: 1px solid #dcdfe6;
		background: #ffffff;
		box-sizing: border-box;
	}

	:deep(.field-input.uv-input .uv-input__content__field-wrapper__field) {
		height: 88rpx;
		min-height: 88rpx;
		font-size: 28rpx;
		line-height: 88rpx;
		color: #303133;
	}

	.upload-bar {
		display: flex;
		flex-direction: column;
		gap: 12rpx;
	}

	.upload-btn {
		align-self: flex-start;
		padding: 14rpx 24rpx;
		border-radius: 20rpx;
		background: rgba(20, 150, 242, 0.1);
		color: #1496f2;
		font-size: 24rpx;
		font-weight: 600;
	}

	.upload-tip {
		font-size: 22rpx;
		line-height: 1.7;
		color: #88715f;
	}

	.file-list {
		display: flex;
		flex-direction: column;
		gap: 14rpx;
		margin-top: 16rpx;
	}

	.file-item-card {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 12rpx;
		padding: 18rpx 20rpx;
		border-radius: 22rpx;
		background: #f4faff;
		border: 1rpx solid #d6eafb;
	}

	.file-main {
		display: flex;
		align-items: center;
		gap: 12rpx;
		flex: 1;
		min-width: 0;
	}

	.file-badge {
		flex-shrink: 0;
		min-width: 72rpx;
		padding: 8rpx 14rpx;
		border-radius: 999rpx;
		background: #eaf5ff;
		color: #1496f2;
		text-align: center;
		font-size: 20rpx;
		font-weight: 600;
	}

	.file-text {
		flex: 1;
		min-width: 0;
	}

	.file-name,
	.file-url,
	.result-name {
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}

	.file-name {
		color: #3b2c20;
		font-size: 24rpx;
		font-weight: 600;
	}

	.file-url {
		margin-top: 8rpx;
		color: #8c7462;
		font-size: 20rpx;
	}

	.file-remove {
		flex-shrink: 0;
		color: #ff4d4f;
		font-size: 22rpx;
	}

	.submit-bar,
	.result-actions {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 18rpx;
		margin-top: 24rpx;
	}

	.ghost-btn,
	.primary-btn,
	.result-btn {
		height: 88rpx;
		line-height: 88rpx;
		border-radius: 22rpx;
		font-size: 28rpx;
		font-weight: 700;
		text-align: center;
	}

	.ghost-btn {
		background: #f6f7fa;
		color: #6f5a4b;
		border: 1rpx solid #ead7c8;
	}

	.primary-btn {
		background: linear-gradient(135deg, #0f7dd1 0%, #1496f2 100%);
		color: #fff;
	}

	.primary-btn--disabled {
		opacity: 0.6;
	}

	.result-btn {
		background: #edf6ff;
		color: #0f7dd1;
	}

	.result-card {
		margin-bottom: 20rpx;
	}

	.result-head {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 16rpx;
	}

	.result-status {
		padding: 10rpx 16rpx;
		border-radius: 999rpx;
		background: #f3f0ed;
		color: #8b827d;
		font-size: 20rpx;
		font-weight: 600;
	}

	.result-status--loading {
		background: #edf5ff;
		color: #1554ad;
	}

	.result-status--done {
		background: #eef9f1;
		color: #1f8f49;
	}

	.result-empty {
		margin-top: 22rpx;
		padding: 32rpx 24rpx;
		border-radius: 24rpx;
		background: #f8fafc;
		font-size: 24rpx;
		line-height: 1.75;
		color: #8a94a0;
		text-align: center;
	}

	.result-body {
		display: flex;
		flex-direction: column;
		gap: 18rpx;
		margin-top: 22rpx;
	}

	.status-alert {
		padding: 20rpx 22rpx;
		border-radius: 22rpx;
		background: #f8fbff;
		color: #5f6b7a;
		font-size: 22rpx;
		line-height: 1.7;
	}

	.loading-panel {
		display: grid;
		gap: 18rpx;
		margin-top: 22rpx;
		padding: 22rpx;
		border-radius: 20rpx;
		background:
			radial-gradient(circle at top right, rgba(255, 182, 122, 0.24), transparent 30%),
			linear-gradient(135deg, #fff7ef 0%, #fffdfb 100%);
		border: 1rpx solid #d6eafb;
	}

	.loading-kicker {
		font-size: 20rpx;
		letter-spacing: 3rpx;
		color: #1496f2;
	}

	.loading-title {
		font-size: 30rpx;
		font-weight: 700;
		color: #0f7dd1;
	}

	.loading-desc {
		font-size: 22rpx;
		line-height: 1.75;
		color: #8b735e;
	}

	.loading-steps {
		display: flex;
		flex-direction: column;
		gap: 14rpx;
	}

	.loading-step {
		display: flex;
		align-items: flex-start;
		gap: 16rpx;
		padding: 16rpx 18rpx;
		border-radius: 18rpx;
		background: rgba(255, 255, 255, 0.72);
	}

	.loading-step.is-active {
		border: 1rpx solid rgba(214, 117, 44, 0.18);
	}

	.loading-step-index {
		font-size: 22rpx;
		font-weight: 700;
		color: #1496f2;
	}

	.loading-step-title {
		font-size: 24rpx;
		font-weight: 700;
		color: #0f7dd1;
	}

	.loading-step-desc {
		margin-top: 6rpx;
		font-size: 20rpx;
		line-height: 1.6;
		color: #8b735e;
	}

	.result-section {
		display: flex;
		flex-direction: column;
		gap: 14rpx;
	}

	.section-title {
		font-size: 26rpx;
		font-weight: 700;
		color: #2d3238;
	}

	.video-list {
		display: flex;
		flex-direction: column;
		gap: 16rpx;
	}

	.video-card,
	.photo-card {
		padding: 18rpx;
		border-radius: 22rpx;
		background: #f4faff;
		border: 1rpx solid #d6eafb;
	}

	.video-player {
		width: 100%;
		height: 360rpx;
		border-radius: 18rpx;
		background: #000;
	}

	.script-shell {
		padding: 22rpx 24rpx;
		border-radius: 22rpx;
		background: #f8fafc;
		border: 1rpx solid #ebeff5;
	}

	.script-markdown {
		display: block;
		font-size: 24rpx;
		line-height: 1.85;
		color: #2b3037;
		word-break: break-all;

		p { margin: 0 0 16rpx; }
		p:last-child { margin-bottom: 0; }

		h1, h2, h3, h4, h5, h6 {
			font-weight: 700;
			margin: 20rpx 0 10rpx;
			color: #1a1f27;
		}
		h1 { font-size: 36rpx; }
		h2 { font-size: 32rpx; }
		h3 { font-size: 28rpx; }

		ul, ol {
			padding-left: 36rpx;
			margin: 10rpx 0;
		}
		li { margin-bottom: 8rpx; }

		code {
			display: inline;
			padding: 2rpx 10rpx;
			border-radius: 8rpx;
			background: rgba(20, 150, 242, 0.08);
			color: #1496f2;
			font-size: 22rpx;
			font-family: monospace;
		}

		pre {
			padding: 20rpx;
			border-radius: 14rpx;
			background: #f1f3f7;
			margin: 14rpx 0;
			overflow-x: auto;
		}
		pre code {
			padding: 0;
			background: transparent;
			color: #2d3a47;
			font-size: 22rpx;
			white-space: pre;
		}

		blockquote {
			margin: 12rpx 0;
			padding: 10rpx 20rpx;
			border-left: 6rpx solid rgba(20, 150, 242, 0.3);
			color: #6b5f59;
			background: rgba(20, 150, 242, 0.04);
			border-radius: 0 12rpx 12rpx 0;
		}

		hr {
			margin: 18rpx 0;
			border: none;
			border-top: 1rpx solid #e0e6ed;
		}

		strong { font-weight: 700; }
		em { font-style: italic; }
	}

	.photo-grid {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 16rpx;
	}

	.photo-image {
		width: 100%;
		height: 240rpx;
		border-radius: 18rpx;
		background: #f2f4f8;
	}

	.photo-fallback {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		gap: 16rpx;
		height: 240rpx;
		border-radius: 18rpx;
		background: #fff;
	}

	.result-meta {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 12rpx;
		margin-top: 14rpx;
	}

	.result-name {
		flex: 1;
		font-size: 22rpx;
		color: #3b2c20;
		font-weight: 600;
	}

	.result-link {
		flex-shrink: 0;
		font-size: 22rpx;
		color: #c45f17;
	}
</style>
