This commit is contained in:
2025-09-28 17:07:09 +08:00
commit 888f8d9939
38 changed files with 1544 additions and 0 deletions

107
pages/detail/detail.js Normal file
View File

@@ -0,0 +1,107 @@
Page({
data: {
dream: {},
dreamId: '',
emotions: [
{ name: '开心', value: 'happy', icon: 'smile' },
{ name: '害怕', value: 'scared', icon: 'warn' },
{ name: '治愈', value: 'healing', icon: 'like' },
{ name: '怪异', value: 'strange', icon: 'question' },
{ name: '悲伤', value: 'sad', icon: 'cry' },
{ name: '愤怒', value: 'angry', icon: 'no' },
{ name: '紧张', value: 'nervous', icon: 'waiting' },
{ name: '平静', value: 'calm', icon: 'sleep' }
]
},
onLoad(options) {
const id = options.id;
this.setData({
dreamId: id
});
this.loadDreamDetail(id);
},
// 加载梦境详情
loadDreamDetail(id) {
wx.getStorage({
key: 'dreamRecords',
success: (res) => {
const records = res.data || [];
const dream = records.find(record => record.id === id);
if (dream) {
this.setData({
dream
});
} else {
wx.showToast({
title: '未找到记录',
icon: 'none'
});
setTimeout(() => {
wx.navigateBack();
}, 1500);
}
}
});
},
// 获取情绪图标
getEmotionIcon(emotion) {
const emotionObj = this.data.emotions.find(item => item.value === emotion);
return emotionObj ? emotionObj.icon : 'info';
},
// 获取情绪名称
getEmotionName(emotion) {
const emotionObj = this.data.emotions.find(item => item.value === emotion);
return emotionObj ? emotionObj.name : '';
},
// 删除记录
deleteRecord() {
const that = this;
wx.showModal({
title: '确认删除',
content: '确定要删除这条梦境记录吗?',
success(res) {
if (res.confirm) {
wx.getStorage({
key: 'dreamRecords',
success: (res) => {
let records = res.data || [];
records = records.filter(record => record.id !== that.data.dreamId);
wx.setStorage({
key: 'dreamRecords',
data: records,
success: () => {
wx.showToast({
title: '删除成功',
icon: 'success',
duration: 2000
});
setTimeout(() => {
wx.navigateBack();
}, 1500);
}
});
}
});
}
}
});
},
// 编辑记录
editRecord() {
// 在实际应用中,这里应该跳转到编辑页面
// 并传递当前记录的数据
wx.showToast({
title: '编辑功能开发中',
icon: 'none'
});
}
});

3
pages/detail/detail.json Normal file
View File

@@ -0,0 +1,3 @@
{
"usingComponents": {}
}

82
pages/detail/detail.wxml Normal file
View File

@@ -0,0 +1,82 @@
<view class="container">
<view class="detail-header">
<text class="dream-title">{{dream.title}}</text>
<text class="dream-date">{{dream.date}}</text>
<!-- 情绪指示器 -->
<view class="emotion-indicator" wx:if="{{dream.emotion}}">
<icon
type="{{getEmotionIcon(dream.emotion)}}"
size="20"
color="#4a6fa5"
/>
<text class="emotion-text">{{getEmotionName(dream.emotion)}}</text>
</view>
<!-- 标签区域 -->
<view class="tags-container" wx:if="{{dream.tags.length > 0}}">
<view
wx:for="{{dream.tags}}"
wx:key="index"
class="tag"
>
{{item}}
</view>
</view>
</view>
<!-- 详情内容 -->
<view class="detail-content">
<!-- 场景 -->
<view class="content-section" wx:if="{{dream.scene}}">
<view class="section-header">
<icon type="location" size="18" color="#4a6fa5" />
<text class="section-title">场景</text>
</view>
<text class="section-content">{{dream.scene}}</text>
</view>
<!-- 人物 -->
<view class="content-section" wx:if="{{dream.characters}}">
<view class="section-header">
<icon type="user" size="18" color="#4a6fa5" />
<text class="section-title">人物</text>
</view>
<text class="section-content">{{dream.characters}}</text>
</view>
<!-- 情节 -->
<view class="content-section" wx:if="{{dream.plot}}">
<view class="section-header">
<icon type="list" size="18" color="#4a6fa5" />
<text class="section-title">情节</text>
</view>
<text class="section-content">{{dream.plot}}</text>
</view>
<!-- 其他细节 -->
<view class="content-section" wx:if="{{dream.details}}">
<view class="section-header">
<icon type="info" size="18" color="#4a6fa5" />
<text class="section-title">其他细节</text>
</view>
<text class="section-content">{{dream.details}}</text>
</view>
</view>
<!-- 操作按钮 -->
<view class="action-buttons">
<button
class="delete-btn"
bindtap="deleteRecord"
>
删除记录
</button>
<button
class="edit-btn"
bindtap="editRecord"
>
编辑记录
</button>
</view>
</view>

1
pages/detail/detail.wxss Normal file
View File

@@ -0,0 +1 @@
/* pages/detail/detail.wxss */

129
pages/history/history.js Normal file
View File

@@ -0,0 +1,129 @@
Page({
data: {
records: [],
filteredRecords: [],
allTags: [],
selectedFilterTag: '',
searchKeyword: ''
},
onLoad() {
this.loadDreamRecords();
},
onShow() {
// 每次页面显示时重新加载数据
this.loadDreamRecords();
},
// 加载梦境记录
loadDreamRecords() {
wx.getStorage({
key: 'dreamRecords',
success: (res) => {
const records = res.data || [];
const allTags = this.extractAllTags(records);
this.setData({
records,
filteredRecords: records,
allTags
});
}
});
},
// 提取所有标签
extractAllTags(records) {
const tagSet = new Set();
records.forEach(record => {
record.tags.forEach(tag => {
tagSet.add(tag);
});
});
return Array.from(tagSet);
},
// 搜索功能
onSearchChange(e) {
const keyword = e.detail.value.trim().toLowerCase();
this.setData({
searchKeyword: keyword
});
this.filterRecords(keyword, this.data.selectedFilterTag);
},
// 选择筛选标签
selectFilterTag(e) {
const tag = e.currentTarget.dataset.tag;
this.setData({
selectedFilterTag: tag
});
this.filterRecords(this.data.searchKeyword, tag);
},
// 筛选记录
filterRecords(keyword, tag) {
let filtered = [...this.data.records];
// 按标签筛选
if (tag) {
filtered = filtered.filter(record =>
record.tags.includes(tag)
);
}
// 按关键词搜索
if (keyword) {
filtered = filtered.filter(record => {
const textToSearch = [
record.title,
record.scene,
record.characters,
record.plot,
record.details,
...record.tags
].join(' ').toLowerCase();
return textToSearch.includes(keyword);
});
}
this.setData({
filteredRecords: filtered
});
},
// 获取情绪对应的图标
getEmotionIcon(emotion) {
const emotionMap = {
'happy': 'smile',
'scared': 'warn',
'healing': 'like',
'strange': 'question',
'sad': 'cry',
'angry': 'no',
'nervous': 'waiting',
'calm': 'sleep'
};
return emotionMap[emotion] || 'info';
},
// 跳转到记录页面
navigateToRecord() {
wx.navigateTo({
url: '/pages/record/record'
});
},
// 跳转到详情页面
navigateToDetail(e) {
const id = e.currentTarget.dataset.id;
wx.navigateTo({
url: `/pages/detail/detail?id=${id}`
});
}
});

View File

@@ -0,0 +1,3 @@
{
"usingComponents": {}
}

View File

@@ -0,0 +1,90 @@
<view class="container">
<view class="header">
<text class="title">我的梦境记录</text>
<text class="count">{{records.length}} 条记录</text>
</view>
<!-- 搜索框 -->
<view class="search-box">
<icon type="search" size="16" color="#999" class="search-icon" />
<input
class="search-input"
placeholder="搜索标签或内容..."
bindinput="onSearchChange"
/>
</view>
<!-- 标签筛选 -->
<view class="filter-tags" wx:if="{{allTags.length > 0}}">
<scroll-view scroll-x="true" class="tags-scroll">
<view
class="filter-tag {{selectedFilterTag === '' ? 'active' : ''}}"
bindtap="selectFilterTag"
data-tag=""
>
全部
</view>
<view
wx:for="{{allTags}}"
wx:key="index"
class="filter-tag {{selectedFilterTag === item ? 'active' : ''}}"
bindtap="selectFilterTag"
data-tag="{{item}}"
>
{{item}}
</view>
</scroll-view>
</view>
<!-- 记录列表 -->
<view class="records-list">
<view wx:if="{{filteredRecords.length === 0}}" class="empty-state">
<icon type="sleep" size="60" color="#ccc" />
<text class="empty-text">还没有记录呢</text>
<text class="empty-desc">快去记录你的第一个梦境吧</text>
<button
class="add-btn"
bindtap="navigateToRecord"
>
+ 记录新梦境
</button>
</view>
<view
wx:for="{{filteredRecords}}"
wx:key="id"
class="record-item"
bindtap="navigateToDetail"
data-id="{{item.id}}"
>
<view class="record-header">
<text class="record-title">{{item.title}}</text>
<text class="record-date">{{item.date}}</text>
</view>
<view class="record-preview">
<text class="preview-text">
{{item.plot.length > 50 ? item.plot.substring(0, 50) + '...' : item.plot || '点击查看详情'}}
</text>
</view>
<view class="record-tags">
<view
wx:for="{{item.tags}}"
wx:key="index"
class="record-tag"
>
{{item}}
</view>
<view class="emotion-indicator" wx:if="{{item.emotion}}">
<icon
type="{{getEmotionIcon(item.emotion)}}"
size="16"
color="#4a6fa5"
/>
</view>
</view>
</view>
</view>
</view>

View File

@@ -0,0 +1 @@
/* pages/history/history.wxss */

82
pages/index/index.js Normal file
View File

@@ -0,0 +1,82 @@
Page({
data: {
animationFrame: null // 用于保存定时器ID
},
onReady() {
// 获取Canvas上下文
const query = wx.createSelectorQuery()
// 获取Canvas宽高
query.select('.starry-canvas')
.fields({ node: true, size: true })
.exec((res) => {
const canvas = res[0].node
const ctx = canvas.getContext('2d')
const dpr = wx.getSystemInfoSync().pixelRatio
canvas.width = res[0].width * dpr
canvas.height = res[0].height * dpr
ctx.scale(dpr, dpr)
// 绘制星空
this.drawStars(canvas, ctx)
})
},
// 绘制动态星空
drawStars(canvas, ctx) {
const width = canvas.width / wx.getSystemInfoSync().pixelRatio
const height = canvas.height / wx.getSystemInfoSync().pixelRatio
// 创建星星数组
const stars = []
const starCount = 200 // 星星数量
// 初始化星星
for (let i = 0; i < starCount; i++) {
stars.push({
x: Math.random() * width,
y: Math.random() * height,
radius: Math.random() * 1.5 + 0.5, // 星星大小
opacity: Math.random(), // 透明度
speed: Math.random() * 0.5 + 0.1 // 移动速度
})
}
// 动画循环 - 使用setInterval替代requestAnimationFrame
const animate = () => {
// 清空画布
ctx.clearRect(0, 0, width, height)
// 绘制每颗星星
stars.forEach(star => {
// 更新星星位置(向上移动)
star.y -= star.speed
if (star.y < 0) {
star.y = height // 星星移出屏幕后重新从底部出现
}
// 随机闪烁效果
star.opacity += (Math.random() - 0.5) * 0.02
star.opacity = Math.max(0.1, Math.min(1, star.opacity))
// 绘制星星
ctx.beginPath()
ctx.arc(star.x, star.y, star.radius, 0, Math.PI * 2)
ctx.fillStyle = `rgba(255, 255, 255, ${star.opacity})`
ctx.fill()
})
}
// 开始动画每30ms更新一次约33fps
this.data.animationFrame = setInterval(animate, 30)
},
// 页面卸载时清除定时器,避免内存泄漏
onUnload() {
if (this.data.animationFrame) {
clearInterval(this.data.animationFrame)
}
}
})

5
pages/index/index.json Normal file
View File

@@ -0,0 +1,5 @@
{
"usingComponents": {
"navigation-bar": "/components/navigation-bar/navigation-bar"
}
}

12
pages/index/index.wxml Normal file
View File

@@ -0,0 +1,12 @@
<!-- 动态星空背景 -->
<canvas
class="starry-canvas"
type="2d"
canvas-id="starrySky"
></canvas>
<!-- 前景内容 -->
<view class="content">
<text class="title">梦之笺</text>
<text class="subtitle">记录你的梦</text>
</view>

34
pages/index/index.wxss Normal file
View File

@@ -0,0 +1,34 @@
.starry-canvas {
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: #0a0a1a; /* 深蓝色夜空 */
z-index: 0;
}
.content {
position: relative;
z-index: 1;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
color: #ffffff;
padding: 20rpx;
}
.title {
font-size: 60rpx;
font-weight: bold;
margin-bottom: 20rpx;
text-shadow: 0 0 10rpx rgba(255, 255, 255, 0.5);
}
.subtitle {
font-size: 32rpx;
opacity: 0.9;
}

83
pages/index2/index2.js Normal file
View File

@@ -0,0 +1,83 @@
Page({
data: {
playbackRate: 5.0, // 默认1倍速
animationFrame: null // 用于保存定时器ID
},
onReady() {
// 获取Canvas上下文
const query = wx.createSelectorQuery()
// 获取Canvas宽高
query.select('.starry-canvas')
.fields({ node: true, size: true })
.exec((res) => {
const canvas = res[0].node
const ctx = canvas.getContext('2d')
const dpr = wx.getSystemInfoSync().pixelRatio
canvas.width = res[0].width * dpr
canvas.height = res[0].height * dpr
ctx.scale(dpr, dpr)
// 绘制星空
this.drawStars(canvas, ctx)
})
},
// 绘制动态星空
drawStars(canvas, ctx) {
const width = canvas.width / wx.getSystemInfoSync().pixelRatio
const height = canvas.height / wx.getSystemInfoSync().pixelRatio
// 创建星星数组
const stars = []
const starCount = 200 // 星星数量
// 初始化星星
for (let i = 0; i < starCount; i++) {
stars.push({
x: Math.random() * width,
y: Math.random() * height,
radius: Math.random() * 1.5 + 0.5, // 星星大小
opacity: Math.random(), // 透明度
speed: Math.random() * 0.5 + 0.1 // 移动速度
})
}
// 动画循环 - 使用setInterval替代requestAnimationFrame
const animate = () => {
// 清空画布
ctx.clearRect(0, 0, width, height)
// 绘制每颗星星
stars.forEach(star => {
// 更新星星位置(向上移动)
star.y -= star.speed
if (star.y < 0) {
star.y = height // 星星移出屏幕后重新从底部出现
}
// 随机闪烁效果
star.opacity += (Math.random() - 0.5) * 0.02
star.opacity = Math.max(0.1, Math.min(1, star.opacity))
// 绘制星星
ctx.beginPath()
ctx.arc(star.x, star.y, star.radius, 0, Math.PI * 2)
ctx.fillStyle = `rgba(255, 255, 255, ${star.opacity})`
ctx.fill()
})
}
// 开始动画每30ms更新一次约33fps
this.data.animationFrame = setInterval(animate, 30)
},
// 页面卸载时清除定时器,避免内存泄漏
onUnload() {
if (this.data.animationFrame) {
clearInterval(this.data.animationFrame)
}
}
})

5
pages/index2/index2.json Normal file
View File

@@ -0,0 +1,5 @@
{
"usingComponents": {
"navigation-bar": "/components/navigation-bar/navigation-bar"
}
}

15
pages/index2/index2.wxml Normal file
View File

@@ -0,0 +1,15 @@
<view class="page-container">
<video id="bg-video"
src="http://exam.yinyue.click/sky.mp4"
loop
muted
autoplay
object-fit="cover"
controls="{{false}}">
playback-rate="{{playbackRate}}">
</video>
<!-- 这里可以添加首页其他内容,比如标题、按钮等 -->
<view class="content">
<text class="title">欢迎来到我的梦境</text>
</view>
</view>

31
pages/index2/index2.wxss Normal file
View File

@@ -0,0 +1,31 @@
.page-container {
position: relative;
width: 100%;
height: 100vh;
overflow: hidden;
}
#bg-video {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
}
.content {
position: relative;
z-index: 1;
display: flex;
justify-content: center;
align-items: center;
height: 100%;
color: white;
text-align: center;
}
.title {
font-size: 64rpx;
font-weight: bold;
}

172
pages/record/record.js Normal file
View File

@@ -0,0 +1,172 @@
Page({
data: {
// 梦境内容
title: '',
scene: '',
characters: '',
plot: '',
details: '',
// 标签数据
dreamTags: [
'飞行', '追逐', '考试', '重逢', '坠落',
'迷路', '被追逐', '飞翔', '裸奔', '牙齿脱落',
'死亡', '结婚', '学校', '怪物', '亲人',
'朋友', '陌生人', '水', '火', '天空',
'未来', '过去', '重复的梦', '清明梦', '噩梦'
],
selectedTags: [],
// 情绪数据
emotions: [
{ name: '开心', value: 'happy', icon: 'smile' },
{ name: '害怕', value: 'scared', icon: 'warn' },
{ name: '治愈', value: 'healing', icon: 'like' },
{ name: '怪异', value: 'strange', icon: 'question' },
{ name: '悲伤', value: 'sad', icon: 'cry' },
{ name: '愤怒', value: 'angry', icon: 'no' },
{ name: '紧张', value: 'nervous', icon: 'waiting' },
{ name: '平静', value: 'calm', icon: 'sleep' }
],
selectedEmotion: ''
},
// 标题输入
onTitleChange(e) {
this.setData({
title: e.detail.value
});
},
// 场景输入
onSceneChange(e) {
this.setData({
scene: e.detail.value
});
},
// 人物输入
onCharactersChange(e) {
this.setData({
characters: e.detail.value
});
},
// 情节输入
onPlotChange(e) {
this.setData({
plot: e.detail.value
});
},
// 细节输入
onDetailsChange(e) {
this.setData({
details: e.detail.value
});
},
// 切换标签选择状态
toggleTag(e) {
const tag = e.currentTarget.dataset.tag;
const { selectedTags } = this.data;
let newSelectedTags;
if (selectedTags.includes(tag)) {
// 移除标签
newSelectedTags = selectedTags.filter(t => t !== tag);
} else {
// 添加标签
newSelectedTags = [...selectedTags, tag];
}
this.setData({
selectedTags: newSelectedTags
});
},
// 选择情绪
selectEmotion(e) {
const emotion = e.currentTarget.dataset.emotion;
this.setData({
selectedEmotion: emotion
});
},
// 保存梦境记录
saveDreamRecord() {
// 简单验证
if (!this.data.title && !this.data.scene && !this.data.plot) {
wx.showToast({
title: '请至少填写一些内容',
icon: 'none',
duration: 2000
});
return;
}
// 创建记录对象
const dreamRecord = {
id: Date.now().toString(), // 使用时间戳作为唯一ID
title: this.data.title || '无标题梦境',
scene: this.data.scene,
characters: this.data.characters,
plot: this.data.plot,
details: this.data.details,
tags: this.data.selectedTags,
emotion: this.data.selectedEmotion,
date: new Date().toLocaleDateString(),
timestamp: Date.now()
};
// 从本地存储获取已有记录
wx.getStorage({
key: 'dreamRecords',
success: (res) => {
const records = res.data || [];
records.unshift(dreamRecord); // 添加到数组开头
// 保存回本地存储
wx.setStorage({
key: 'dreamRecords',
data: records,
success: () => {
wx.showToast({
title: '记录保存成功',
icon: 'success',
duration: 2000
});
// 返回首页
setTimeout(() => {
wx.navigateBack({
delta: 1
});
}, 1500);
}
});
},
fail: () => {
// 如果没有已有记录,创建新数组
wx.setStorage({
key: 'dreamRecords',
data: [dreamRecord],
success: () => {
wx.showToast({
title: '记录保存成功',
icon: 'success',
duration: 2000
});
// 返回首页
setTimeout(() => {
wx.navigateBack({
delta: 1
});
}, 1500);
}
});
}
});
}
});

3
pages/record/record.json Normal file
View File

@@ -0,0 +1,3 @@
{
"usingComponents": {}
}

114
pages/record/record.wxml Normal file
View File

@@ -0,0 +1,114 @@
<view class="container">
<!-- 记录标题 -->
<view class="input-section">
<text class="section-title">梦境标题</text>
<input
class="dream-title"
placeholder="给你的梦境起个名字吧..."
bindinput="onTitleChange"
/>
</view>
<!-- 分段记录区域 -->
<view class="section">
<text class="section-title">梦境内容</text>
<text class="section-desc">可以分场景、人物、情绪等方面记录</text>
<!-- 场景描述 -->
<view class="segment">
<view class="segment-header">
<icon type="location" size="18" color="#4a6fa5" />
<text class="segment-title">场景</text>
</view>
<textarea
class="segment-content"
placeholder="描述一下梦中的场景环境..."
bindinput="onSceneChange"
></textarea>
</view>
<!-- 人物描述 -->
<view class="segment">
<view class="segment-header">
<icon type="user" size="18" color="#4a6fa5" />
<text class="segment-title">人物</text>
</view>
<textarea
class="segment-content"
placeholder="梦中出现了哪些人物?他们做了什么?"
bindinput="onCharactersChange"
></textarea>
</view>
<!-- 情节描述 -->
<view class="segment">
<view class="segment-header">
<icon type="list" size="18" color="#4a6fa5" />
<text class="segment-title">情节</text>
</view>
<textarea
class="segment-content"
placeholder="描述梦境中的主要情节和发展..."
bindinput="onPlotChange"
></textarea>
</view>
<!-- 其他细节 -->
<view class="segment">
<view class="segment-header">
<icon type="info" size="18" color="#4a6fa5" />
<text class="segment-title">其他细节</text>
</view>
<textarea
class="segment-content"
placeholder="还有什么想记录的细节?"
bindinput="onDetailsChange"
></textarea>
</view>
</view>
<!-- 标签选择 -->
<view class="section">
<text class="section-title">梦境标签</text>
<text class="section-desc">选择与你的梦境相关的标签</text>
<view class="tags-container">
<view
wx:for="{{dreamTags}}"
wx:key="index"
class="tag {{selectedTags.includes(item) ? 'tag-selected' : ''}}"
bindtap="toggleTag"
data-tag="{{item}}"
>
{{item}}
</view>
</view>
</view>
<!-- 情绪标记 -->
<view class="section">
<text class="section-title">情绪标记</text>
<text class="section-desc">这个梦境带给你什么感受?</text>
<view class="emotions-container">
<view
wx:for="{{emotions}}"
wx:key="index"
class="emotion {{selectedEmotion === item.value ? 'emotion-selected' : ''}}"
bindtap="selectEmotion"
data-emotion="{{item.value}}"
>
<icon type="{{item.icon}}" size="24" />
<text>{{item.name}}</text>
</view>
</view>
</view>
<!-- 保存按钮 -->
<button
class="save-btn"
bindtap="saveDreamRecord"
>
保存梦境记录
</button>
</view>

148
pages/record/record.wxss Normal file
View File

@@ -0,0 +1,148 @@
.container {
padding: 16px;
background-color: #f5f7fa;
min-height: 100vh;
}
.section {
margin-bottom: 24px;
background-color: white;
border-radius: 12px;
padding: 16px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}
.input-section {
margin-bottom: 24px;
}
.section-title {
font-size: 18px;
font-weight: 600;
color: #333;
margin-bottom: 8px;
display: block;
}
.section-desc {
font-size: 14px;
color: #666;
margin-bottom: 16px;
display: block;
}
.dream-title {
width: 100%;
padding: 12px 16px;
border: 1px solid #e5e7eb;
border-radius: 8px;
font-size: 16px;
background-color: white;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}
.segment {
margin-bottom: 16px;
}
.segment:last-child {
margin-bottom: 0;
}
.segment-header {
display: flex;
align-items: center;
margin-bottom: 8px;
}
.segment-title {
font-size: 16px;
color: #4a6fa5;
margin-left: 8px;
font-weight: 500;
}
.segment-content {
width: 100%;
min-height: 80px;
padding: 12px 16px;
border: 1px solid #e5e7eb;
border-radius: 8px;
font-size: 15px;
line-height: 1.6;
}
.tags-container {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.tag {
padding: 6px 14px;
background-color: #f1f5f9;
border-radius: 20px;
font-size: 14px;
color: #475569;
cursor: pointer;
transition: all 0.2s ease;
}
.tag-selected {
background-color: #4a6fa5;
color: white;
}
.emotions-container {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
gap: 15px;
}
.emotion {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 80px;
height: 80px;
background-color: #f1f5f9;
border-radius: 12px;
cursor: pointer;
transition: all 0.2s ease;
}
.emotion text {
margin-top: 8px;
font-size: 14px;
color: #475569;
}
.emotion-selected {
background-color: #4a6fa5;
}
.emotion-selected text {
color: white;
}
.emotion-selected icon {
color: white;
}
.save-btn {
width: 100%;
padding: 14px 0;
background-color: #4a6fa5;
color: white;
font-size: 16px;
font-weight: 500;
border-radius: 8px;
margin-top: 16px;
margin-bottom: 30px;
}
.save-btn::after {
border: none;
}