<template>
	<view class="page-container">
		<Header :showBack="true" backIconColor="#e6e6e6" />
		
		<view class="castlove-content">
			<!-- 背景图片 -->
			<image class="background-image" src="/static/background/profile-bg.png" mode="aspectFill"></image>

			<!-- 蒙层 -->
			<view class="background-overlay"></view>

			<!-- 内容区域 -->
			<view class="content-wrapper">
				<scroll-view class="content-wrapper" scroll-y="true" :show-scrollbar="false" :enhanced="true">
				<!-- 图片上传区域 -->
				<view class="upload-section">
					<view class="upload-box" @click="chooseImage">
						<image v-if="uploadedImage" class="uploaded-image" :src="uploadedImage" mode="aspectFit">
						</image>
						<view v-else class="upload-placeholder">
							<image class="upload-icon" src="/static/icon/add.png" mode="aspectFit"></image>
							<text class="upload-text">点击上传藏品图片</text>
						</view>
					</view>
					<view class="upload-hint">支持JPG、PNG格式，大小不超过5MB</view>
				</view>

				<!-- 表单区域 -->
				<view class="form-section">
					<!-- 素材类型选择器 -->
					<view class="form-item form-item-picker">
						<text class="form-label">素材类型</text>
						<view class="custom-picker">
							<view class="picker-display" @click="toggleMaterialTypePicker">
								<text class="picker-text">{{ materialTypes[materialTypeIndex] }}</text>
								<text class="picker-arrow"
									:class="{ 'picker-arrow-up': showMaterialTypePicker }">›</text>
							</view>
							<!-- 自定义下拉选项列表 -->
							<view v-if="showMaterialTypePicker" class="picker-options">
								<view v-for="(type, index) in materialTypes" :key="index" class="picker-option"
									:class="{ 'picker-option-active': materialTypeIndex === index }"
									@click.stop="selectMaterialType(index)">
									<text class="picker-option-text">{{ type }}</text>
									<text v-if="materialTypeIndex === index" class="picker-option-check">✓</text>
								</view>
							</view>
						</view>
					</view>

					<!-- 藏品名称输入框 -->
					<view class="form-item">
						<text class="form-label">藏品名称</text>
						<input class="form-input" v-model="nftName" placeholder="请输入藏品名称"
							placeholder-class="input-placeholder" />
					</view>

					<!-- 藏品事件输入框 -->
					<view class="form-item">
						<text class="form-label">藏品事件</text>
						<input class="form-input" v-model="nftEvent" placeholder="请输入藏品事件"
							placeholder-class="input-placeholder" />
					</view>

					<!-- 备注输入框 -->
					<view class="form-item">
						<text class="form-label">备注</text>
						<textarea class="form-textarea" v-model="nftRemark" placeholder="请输入备注信息"
							placeholder-class="textarea-placeholder" maxlength="200" auto-height
							:show-confirm-bar="false" />
					</view>
				</view>

				<!-- 底部按钮区域 -->
				<view class="button-section">
					<button class="btn-secondary" @click="handleBack">返回</button>
					<button class="btn-primary" @click="handleConfirm">开始铸造</button>
				</view>
				</scroll-view>
			</view>
		</view>
		
		<!-- 蒙层 - 导航栏展开时显示 -->
		<view v-if="navExpanded" class="nav-mask" @click="navExpanded = false"></view>
		
		<BottomNav :activeTab="2" @update:activeTab="handleTabChange" :isExpanded="navExpanded" @update:isExpanded="navExpanded = $event" />
	</view>
</template>

<script setup>
import { ref } from 'vue';
import Header from "../components/Header.vue";
import BottomNav from "../components/BottomNav.vue";
import { getOssSignatureApi, deleteMintOrderApi } from '@/utils/api.js';

const navExpanded = ref(false);

// 表单数据
const uploadedImage = ref(''); // 本地预览路径
const uploadedImageUrl = ref(''); // OSS完整URL
const uploadedImageBase64 = ref(''); // Base64格式
const originalFileName = ref(''); // 原始文件名
const currentOrderId = ref(''); // 当前订单ID
const isUploading = ref(false); // 上传中状态
const materialTypes = ['粉丝自制', '热爱痕迹', '其他'];
const materialTypeIndex = ref(0);
const showMaterialTypePicker = ref(false);
const nftName = ref('');
const nftEvent = ref('');
const nftRemark = ref('');

// 选择图片
const chooseImage = () => {
	// 如果正在上传，禁止选择新图片
	if (isUploading.value) {
		uni.showToast({
			title: '图片上传中，请稍候',
			icon: 'none'
		});
		return;
	}

	uni.chooseImage({
		count: 1,
		sourceType: ['album', 'camera'],
		success: (res) => {
			const filePath = res.tempFilePaths[0];
			const tempFile = res.tempFiles && res.tempFiles[0];

			// 获取文件信息进行验证
			uni.getFileInfo({
				filePath: filePath,
				success: (fileInfo) => {
					// 验证文件大小（5MB = 5 * 1024 * 1024 bytes）
					const maxSize = 5 * 1024 * 1024;
					if (fileInfo.size > maxSize) {
						uni.showToast({
							title: '图片大小不能超过5MB',
							icon: 'none',
							duration: 2000
						});
						return;
					}

					// 验证文件格式
					const mimeType = (tempFile && tempFile.type) ? tempFile.type.toLowerCase() : '';
					const pathLower = filePath.toLowerCase();
					const validByMime = mimeType === 'image/jpeg' || mimeType === 'image/png';
					const validByExt = pathLower.endsWith('.jpg') || pathLower.endsWith('.jpeg') || pathLower.endsWith('.png');
					if (!validByMime && !validByExt) {
						uni.showToast({
							title: '只支持JPG和PNG格式',
							icon: 'none',
							duration: 2000
						});
						return;
					}

					// 提取原始文件名
					const rawName = (tempFile && tempFile.name)
						? tempFile.name
						: filePath.split('/').pop();
					originalFileName.value = rawName;

					// 验证通过，转换为 base64
					convertImageToBase64(filePath, originalFileName.value);
				},
				fail: (error) => {
					console.error('获取文件信息失败:', error);
					uni.showToast({
						title: '获取文件信息失败',
						icon: 'none'
					});
				}
			});
		},
		fail: (err) => {
			console.error('选择图片失败:', err);
			uni.showToast({
				title: '选择图片失败',
				icon: 'none'
			});
		}
	});
};

// 将图片转换为 base64（兼容 H5、App、小程序）
const convertImageToBase64 = (filePath, fileName) => {
	isUploading.value = true;
	uni.showLoading({ title: '处理中...', mask: true });

	// 判断运行环境
	// #ifdef H5
	// H5 环境：使用 FileReader
	convertImageToBase64H5(filePath, fileName);
	// #endif
	
	// #ifndef H5
	// App/小程序环境：使用 FileSystemManager
	convertImageToBase64Native(filePath, fileName);
	// #endif
};

// H5 环境的 base64 转换
const convertImageToBase64H5 = (filePath, fileName) => {
	// H5 环境下，filePath 是 blob URL
	// 需要通过 fetch 获取 blob，然后用 FileReader 转换
	fetch(filePath)
		.then(res => res.blob())
		.then(blob => {
			const reader = new FileReader();
			reader.onload = (e) => {
				// e.target.result 已经是完整的 data:image/xxx;base64,xxx 格式
				uploadedImageBase64.value = e.target.result;
				uploadedImage.value = filePath;
				
				console.log('[CastloveContent] Base64转换成功 (H5)');
				console.log('[CastloveContent] Base64长度:', uploadedImageBase64.value.length);
				
				uni.hideLoading();
				uni.showToast({
					title: '图片加载成功',
					icon: 'success',
					duration: 1500
				});
				
				isUploading.value = false;
			};
			reader.onerror = (error) => {
				console.error('Base64转换失败 (H5):', error);
				uni.hideLoading();
				uni.showToast({
					title: '图片处理失败',
					icon: 'none',
					duration: 2000
				});
				isUploading.value = false;
			};
			reader.readAsDataURL(blob);
		})
		.catch(error => {
			console.error('获取图片失败 (H5):', error);
			uni.hideLoading();
			uni.showToast({
				title: '图片处理失败',
				icon: 'none',
				duration: 2000
			});
			isUploading.value = false;
		});
};

// App/小程序环境的 base64 转换
const convertImageToBase64Native = (filePath, fileName) => {
	// #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ
	// 小程序环境
	const fs = uni.getFileSystemManager();
	fs.readFile({
		filePath: filePath,
		encoding: 'base64',
		success: (res) => {
			const ext = fileName.toLowerCase().split('.').pop();
			let mimeType = 'image/jpeg';
			if (ext === 'png') {
				mimeType = 'image/png';
			}
			
			uploadedImageBase64.value = `data:${mimeType};base64,${res.data}`;
			uploadedImage.value = filePath;
			
			console.log('[CastloveContent] Base64转换成功 (小程序)');
			
			uni.hideLoading();
			uni.showToast({
				title: '图片加载成功',
				icon: 'success',
				duration: 1500
			});
			
			isUploading.value = false;
		},
		fail: (error) => {
			console.error('[CastloveContent] Base64转换失败:', error);
			uni.hideLoading();
			uni.showToast({
				title: '图片处理失败',
				icon: 'none',
				duration: 2000
			});
			isUploading.value = false;
		}
	});
	// #endif
	
	// #ifdef APP-PLUS
	// App环境：使用plus.io API
	plus.io.resolveLocalFileSystemURL(filePath, (entry) => {
		entry.file((file) => {
			const reader = new plus.io.FileReader();
			reader.onloadend = (e) => {
				uploadedImageBase64.value = e.target.result;
				uploadedImage.value = filePath;
				
				console.log('[CastloveContent] Base64转换成功 (App)');
				
				uni.hideLoading();
				uni.showToast({
					title: '图片加载成功',
					icon: 'success',
					duration: 1500
				});
				
				isUploading.value = false;
			};
			reader.onerror = (error) => {
				console.error('[CastloveContent] Base64转换失败:', error);
				uni.hideLoading();
				uni.showToast({
					title: '图片处理失败',
					icon: 'none',
					duration: 2000
				});
				isUploading.value = false;
			};
			reader.readAsDataURL(file);
		});
	}, (error) => {
		console.error('[CastloveContent] 读取文件失败:', error);
		uni.hideLoading();
		uni.showToast({
			title: '图片处理失败',
			icon: 'none',
			duration: 2000
		});
		isUploading.value = false;
	});
	// #endif
};

// 上传图片到OSS
const uploadImageToOss = async (filePath, fileName) => {
	try {
		isUploading.value = true;
		uni.showLoading({ title: '上传中...', mask: true });

		// 1. 获取OSS签名（type='asset'），后端返回order_id
		const signRes = await getOssSignatureApi('asset');
		if (signRes.code !== 200) {
			throw new Error(signRes.message || '获取签名失败');
		}

		// 保存order_id
		currentOrderId.value = signRes.data.order_id;

		// 2. 构建FormData并上传到OSS
		uni.uploadFile({
			url: signRes.data.host,
			filePath: filePath,
			name: 'file',
			formData: {
				key: signRes.data.dir + fileName,
				policy: signRes.data.policy,
				success_action_status: '200',
				'x-oss-credential': signRes.data.x_oss_credential,
				'x-oss-date': signRes.data.x_oss_date,
				'x-oss-security-token': signRes.data.security_token,
				'x-oss-signature': signRes.data.signature,
				'x-oss-signature-version': signRes.data.x_oss_signature_version
			},
			success: (uploadRes) => {
				try {
					if (uploadRes.statusCode === 200 || uploadRes.statusCode === 204) {
						// 3. 拼接完整URL
						uploadedImageUrl.value = `${signRes.data.host}/${signRes.data.dir}${fileName}`;

						// 4. 显示预览图（使用本地路径）
						uploadedImage.value = filePath;

						uni.hideLoading();
						uni.showToast({
							title: '上传成功',
							icon: 'success',
							duration: 1500
						});
					} else {
						throw new Error(`上传失败，状态码: ${uploadRes.statusCode}`);
					}
				} catch (error) {
					console.error('处理上传结果失败:', error);
					uni.hideLoading();
					uni.showToast({
						title: error.message || '上传失败',
						icon: 'none',
						duration: 2000
					});
				} finally {
					isUploading.value = false;
				}
			},
			fail: (error) => {
				console.error('OSS上传失败:', error);
				uni.hideLoading();
				uni.showToast({
					title: '上传失败',
					icon: 'none',
					duration: 2000
				});
				isUploading.value = false;
			}
		});

	} catch (error) {
		console.error('上传图片失败:', error);
		uni.hideLoading();
		uni.showToast({
			title: error.message || '上传失败',
			icon: 'none',
			duration: 2000
		});
		isUploading.value = false;
	}
};

// 切换素材类型选择器显示
const toggleMaterialTypePicker = () => {
	showMaterialTypePicker.value = !showMaterialTypePicker.value;
};

// 选择素材类型
const selectMaterialType = (index) => {
	materialTypeIndex.value = index;
	showMaterialTypePicker.value = false;
};

// 返回按钮
const handleBack = async () => {
	// 如果有未保存的数据，提示用户
	if (uploadedImage.value || nftName.value || nftEvent.value || nftRemark.value) {
		uni.showModal({
			title: '提示',
			content: '确定要返回吗？未保存的数据将会丢失',
			success: async (res) => {
				if (res.confirm) {
					// 如果有订单ID，需要删除订单
					if (currentOrderId.value) {
						try {
							await deleteMintOrderApi(currentOrderId.value);
						} catch (error) {
							console.error('删除订单失败:', error);
						}
					}

					// 清空表单数据
					resetForm();
					// 返回广场页面
					uni.redirectTo({
						url: '/pages/square/square'
					});
				}
			}
		});
	} else {
		// 没有未保存数据，直接返回
		uni.redirectTo({
			url: '/pages/square/square'
		});
	}
};

// 底部导航切换
const handleTabChange = (newTab) => {
	const routes = [
		'/pages/square/square',
		'/pages/starbook/index',
		'/pages/castlove/mall',
		'/pages/starcity/index',
		'/pages/friends/index'
	];
	
	if (newTab >= 0 && newTab < routes.length) {
		uni.redirectTo({
			url: routes[newTab]
		});
	}
};

// 确认铸造按钮
const handleConfirm = async () => {
	// 表单验证
	if (!uploadedImage.value) {
		uni.showToast({
			title: '请上传藏品图片',
			icon: 'none'
		});
		return;
	}

	if (!uploadedImageBase64.value) {
		uni.showToast({
			title: '图片尚未处理完成',
			icon: 'none'
		});
		return;
	}

	if (!nftName.value.trim()) {
		uni.showToast({
			title: '请输入藏品名称',
			icon: 'none'
		});
		return;
	}

	if (!nftEvent.value.trim()) {
		uni.showToast({
			title: '请输入藏品事件',
			icon: 'none'
		});
		return;
	}

	// 保存表单数据到全局存储
	const formData = {
		image: uploadedImage.value,
		imageBase64: uploadedImageBase64.value, // Base64格式
		name: nftName.value.trim(),
		event: nftEvent.value.trim(),
		remark: nftRemark.value.trim(),
		materialType: materialTypes[materialTypeIndex.value]
	};

	try {
		uni.setStorageSync('castlove_form_data', JSON.stringify(formData));
		console.log('[CastloveContent] 表单数据已保存，Base64长度:', uploadedImageBase64.value.length);
	} catch (e) {
		console.error('保存表单数据失败:', e);
		uni.showToast({
			title: '保存数据失败',
			icon: 'none'
		});
		return;
	}

	// 清空表单
	resetForm();

	// 跳转到发现页面
	uni.navigateTo({
		url: '/pages/discover/discover'
	});
};

// 重置表单
const resetForm = () => {
	uploadedImage.value = '';
	uploadedImageUrl.value = '';
	uploadedImageBase64.value = '';
	originalFileName.value = '';
	currentOrderId.value = '';
	isUploading.value = false;
	materialTypeIndex.value = 0;
	nftName.value = '';
	nftEvent.value = '';
	nftRemark.value = '';
};
</script>

<style scoped>
.page-container {
	position: relative;
	width: 100vw;
	height: 100vh;
	min-height: 100vh;
	overflow: hidden;
}

.castlove-content {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	width: 100%;
	height: 100%;
	z-index: 1;
	overflow-y: auto;
	overflow-x: hidden;
}

.background-image {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	width: 100%;
	height: 100%;
	z-index: 0;
	object-fit: cover;
	min-width: 100%;
	min-height: 100%;
}

.background-overlay {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	width: 100%;
	height: 100%;
	z-index: 0;
	background: rgba(0, 0, 0, 0.3);
}

.content-wrapper {
	position: relative;
	z-index: 1;
	width: 100%;
	min-height: 100%;
	padding: 100rpx 40rpx 40rpx 32rpx;
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
}

/* 图片上传区域 */
.upload-section {
	width: 100%;
	display: flex;
	flex-direction: column;
	align-items: center;
	margin-bottom: 40rpx;
}

.upload-box {
	width: 500rpx;
	height: 500rpx;
	background: rgba(255, 255, 255, 0.15);
	backdrop-filter: blur(10rpx);
	border-radius: 30rpx;
	border: 4rpx dashed rgba(255, 255, 255, 0.5);
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
	box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.2);
}

.upload-hint {
	margin-top: 20rpx;
	font-size: 24rpx;
	color: rgba(255, 255, 255, 0.7);
	text-align: center;
}

.uploaded-image {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.upload-placeholder {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 20rpx;
}

.upload-icon {
	width: 120rpx;
	height: 120rpx;
	opacity: 0.8;
}

.upload-text {
	font-size: 28rpx;
	color: rgba(255, 255, 255, 0.9);
	font-weight: 500;
}

/* 表单区域 */
.form-section {
	width: 100%;
	display: flex;
	flex-direction: column;
	gap: 30rpx;
	margin-bottom: 40rpx;
}

.form-item {
	width: 100%;
	display: flex;
	flex-direction: column;
	gap: 16rpx;
}

.form-item-picker {
	position: relative;
	z-index: 10;
}

.form-label {
	font-size: 36rpx;
	color: #e6e6e6;
	font-weight: 500;
	font-family: 'ZaoZiGongFangJianHei-1', sans-serif;
	padding: 18rpx 18rpx;
	background: linear-gradient(165deg, #F0E4B1 0%, #F08399 50%, #B94E73 90%, #834B9E 100%);
	border-radius: 44rpx;
	display: inline-block;
	align-self: flex-start;
	box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.3);
	text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.4);
}

/* 自定义选择器 */
.custom-picker {
	position: relative;
	width: 100%;
	z-index: 10;
}

.picker-display {
	width: 100%;
	height: 88rpx;
	background: rgba(255, 255, 255, 0.15);
	backdrop-filter: blur(10rpx);
	border-radius: 20rpx;
	padding: 0 30rpx;
	display: flex;
	align-items: center;
	justify-content: space-between;
	box-sizing: border-box;
	box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
	transition: all 0.3s ease;
	text-shadow: 0 4rpx 4rpx rgba(0, 0, 0, 0.3);
}

.picker-display:active {
	background: rgba(255, 255, 255, 0.2);
}

.picker-text {
	font-size: 32rpx;
	color: rgba(255, 255, 255, 0.85);
	text-shadow: 0 4rpx 4rpx rgba(0, 0, 0, 0.3);
}

.picker-arrow {
	font-size: 48rpx;
	color: rgba(255, 255, 255, 0.7);
	font-weight: bold;
	transform: rotate(90deg);
	transition: transform 0.3s ease;
}

.picker-arrow-up {
	transform: rotate(-90deg);
}

/* 下拉选项列表 */
.picker-options {
	position: absolute;
	top: 100%;
	left: 0;
	right: 0;
	width: 100%;
	margin-top: 10rpx;
	background: rgba(255, 255, 255, 0.2);
	backdrop-filter: blur(15rpx);
	border-radius: 20rpx;
	overflow: hidden;
	box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.2);
	z-index: 10;
	animation: slideDown 0.3s ease-out;
	text-shadow: 0 4rpx 4rpx rgba(0, 0, 0, 0.3);
}

@keyframes slideDown {
	from {
		opacity: 0;
		transform: translateY(-10rpx);
	}

	to {
		opacity: 1;
		transform: translateY(0);
	}
}

.picker-option {
	width: 100%;
	height: 88rpx;
	padding: 0 30rpx;
	display: flex;
	align-items: center;
	justify-content: space-between;
	box-sizing: border-box;
	transition: background 0.2s ease;
	border-bottom: 1rpx solid rgba(255, 255, 255, 0.1);
}

.picker-option:last-child {
	border-bottom: none;
}

.picker-option:active {
	background: rgba(255, 255, 255, 0.15);
}

.picker-option-active {
	background: rgba(255, 255, 255, 0.1);
}

.picker-option-text {
	font-size: 32rpx;
	color: #e6e6e6;
}

.picker-option-check {
	font-size: 36rpx;
	color: #e6e6e6;
	font-weight: bold;
}

.form-input {
	width: 100%;
	height: 88rpx;
	background: rgba(255, 255, 255, 0.15);
	backdrop-filter: blur(10rpx);
	border-radius: 20rpx;
	padding: 0 30rpx;
	font-size: 32rpx;
	color: #e6e6e6;
	box-sizing: border-box;
	box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
}

.input-placeholder {
	color: rgba(255, 255, 255, 0.85);
	font-size: 32rpx;
	text-shadow: 0 4rpx 4rpx rgba(0, 0, 0, 0.3);
}

.form-textarea {
	width: 100%;
	min-height: 88rpx;
	max-height: 400rpx;
	background: rgba(255, 255, 255, 0.15);
	backdrop-filter: blur(10rpx);
	border-radius: 20rpx;
	padding: 20rpx 30rpx;
	font-size: 32rpx;
	color: #e6e6e6;
	box-sizing: border-box;
	box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
	line-height: 1.5;
}

.textarea-placeholder {
	color: rgba(255, 255, 255, 0.85);
	font-size: 32rpx;
	text-shadow: 0 4rpx 4rpx rgba(0, 0, 0, 0.3);
}

/* 底部按钮区域 */
.button-section {
	width: 100%;
	display: flex;
	gap: 20rpx;
	margin-top: auto;
	padding-top: 40rpx;
	padding-bottom: 40rpx;
}

.btn-secondary,
.btn-primary {
	flex: 1;
	height: 88rpx;
	line-height: 88rpx;
	border-radius: 44rpx;
	font-size: 36rpx;
	font-family: 'ZaoZiGongFangJianHei-1', sans-serif;
	font-weight: 600;
	border: none;
	display: flex;
	align-items: center;
	justify-content: center;
	box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.3);
	text-shadow: 0 4rpx 4rpx rgba(0, 0, 0, 0.3);
}

.btn-secondary {
	background: rgba(255, 255, 255, 0.2);
	backdrop-filter: blur(10rpx);
	color: #e6e6e6;
	border: 2rpx solid rgba(255, 255, 255, 0.4);
}

.btn-secondary::after {
	border: none;
}

.btn-primary {
	background: linear-gradient(165deg, #F0E4B1 0%, #F08399 50%, #B94E73 90%, #834B9E 100%);
	color: #e6e6e6;


}

.btn-primary::after {
	border: none;
}

.btn-secondary:active {
	background: rgba(255, 255, 255, 0.3);
}

.btn-primary:active {
	opacity: 0.9;
}

.nav-mask {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	width: 100%;
	height: 100%;
	background: rgba(0, 0, 0, 0.3);
	z-index: 999;
	animation: fadeIn 0.3s ease-out;
}

@keyframes fadeIn {
	from {
		opacity: 0;
	}
	to {
		opacity: 1;
	}
}
</style>
