+
+ 裂缝 / 失言 / 道歉信
+
+
+ {{ memory.event_title }}
+
+
+ 这次裂开的,不只是情绪,而是我把不该说出去的事说给了别人听。
+
+
-
-
+
+
+
+
-
-
-
- 旁人皆三千江水,
-
+
+
+
+ Long Apology
+
+
+ 对不起
+
+
+
+
+ 我写了很长的小作文
+
+
+
+ {{ tag }}
+
+
+
-
-
+
+
+
+
+
+
-
-
- 唯你是心上
- 涟漪
-
+
+
+
+
+ The Mistake
+
+
+ 我说了
+ 不该说的事
+
+
+
+
+
+
+ 那些原本只属于你的过去,不该被我拿出去换成别人的一句两句评价。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Their Voices
+
+
+ 不是你的错,
+ 却落在你身上
+
+
+
+
+
+
+ 我后来才反应过来,我最该做的是护着你,而不是让你被别人看见、议论、定义。
+
+
-
+
+
+
+
+ Photo Evidence
+
+
+ 把那天也留在这一页
+
+
+ 这张照片不只是记录当时的场景,也提醒我,这一页里有真实发生过的伤害,也有我认真写下的道歉。
+
+
+
+ 争执那天
+
+
+ 真实现场
+
+
+ 道歉也被记住
+
+
+
+
+
+
+
+
+ {{ splitHint }}
+
+
+
+
+
+ 隐私被说出去了
+
+
+ 别人开始评头论足
+
+
+ 我写了很长的解释和道歉
+
+
+
+
diff --git a/frontend/src/components/HeartMangaBackdrop.vue b/frontend/src/components/HeartMangaBackdrop.vue
index 62abdd4..abdb867 100644
--- a/frontend/src/components/HeartMangaBackdrop.vue
+++ b/frontend/src/components/HeartMangaBackdrop.vue
@@ -1,25 +1,68 @@
-
diff --git a/frontend/src/components/HeartWindowPage.vue b/frontend/src/components/HeartWindowPage.vue
index 9ec4f14..f60fe08 100644
--- a/frontend/src/components/HeartWindowPage.vue
+++ b/frontend/src/components/HeartWindowPage.vue
@@ -3,6 +3,7 @@ import { usePointerSwipe, usePreferredReducedMotion } from '@vueuse/core'
import { computed, ref } from 'vue'
import type { Memory } from '../api/client'
import HeartMangaBackdrop from './HeartMangaBackdrop.vue'
+import PolaroidCard from './PolaroidCard.vue'
import { renderMarkdown } from '../utils/renderMarkdown'
const props = defineProps<{
@@ -26,152 +27,229 @@ usePointerSwipe(stageRef, {
})
const openDeg = computed(() => openAmount.value * 78)
-
const bodyHtml = computed(() => renderMarkdown(props.memory.main_text))
+const isOpen = computed(() => openAmount.value > 0.4)
+const statusText = computed(() =>
+ isOpen.value ? '心窗已经被推开,光会落进来。' : '如果不开心,就把这一页轻轻打开。',
+)
+const finaleTags = ['不开心时', '想说话时', '只想被陪着时']
function toggleDoors() {
- openAmount.value = openAmount.value > 0.4 ? 0 : 0.92
+ openAmount.value = isOpen.value ? 0 : 0.92
}
-
-
- 不开心就打开心墙
-
-
- 我会在你身边 · open
-
+
+
+
+
+
+
+ Finale / Open When You Need Me
+
+
+ 心墙与窗 · 终章
+
+
+ 这一页不再讲相遇或争执,而是把“我会在你身边”做成一扇真的能被推开的窗。
+
+
-
-
-
-
+
心窗机关
+
{{ statusText }}
-
-
-
-
-
- 藏宝格 · 情书券插槽
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+ Open When You Need Me
+
+
+
+
+
+
+
+
+
+ 推开一点
+
+
+
+
+
+
+
+
+
+ 左右轻扫也可以开合这一扇窗。
+
+
+
+
+
+
+
+
+
+ Promise Window
+
+
+ 你需要我的时候,
+ 这一页永远能打开
+
+
+ 终章不是结束,而是留下一种使用方式:难过的时候、想说话的时候、什么都不想解释的时候,都可以来敲这扇窗。
+
+
+
+ {{ tag }}
+
+
+
+
+
+
+
+
+ Keepsake Ticket
+
+
+
+
+
+
+
+ Love 520 · 非流通纪念券
+
+
+ 壹佰份喜欢
+
+
+ 使用规则:情绪低落时可无限次兑换陪伴、拥抱、安静地在身边。
+
+
+ open when you need me
+
+
+
+
+
+
diff --git a/frontend/src/components/HomeRentalPage.vue b/frontend/src/components/HomeRentalPage.vue
new file mode 100644
index 0000000..84ad1f6
--- /dev/null
+++ b/frontend/src/components/HomeRentalPage.vue
@@ -0,0 +1,149 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Tiny Home / 05.08
+
+
+ 一起租了房
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Balcony
+
+
+ 阳台晒进来的光,像新生活按下了开始键。
+
+
+
+
+
+
+
+
+
+
+ {{ tag }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/components/IkeaDatePage.vue b/frontend/src/components/IkeaDatePage.vue
new file mode 100644
index 0000000..26b61d6
--- /dev/null
+++ b/frontend/src/components/IkeaDatePage.vue
@@ -0,0 +1,145 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Blue Box Date / 05.10
+
+
+ 逛宜家的小日子
+
+
+
+
+ Showroom Mood
+
+
Blue + Yellow
+
+
+
+
+
+
+
+ SALE
+
+
+
+
+
+
+
+
+ Cart List
+
+
+ 台灯
+ 地毯
+ 热狗
+
+
+
+
+
+
+
+
+
+
+
+ {{ tag }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/components/LuckinCoffeePage.vue b/frontend/src/components/LuckinCoffeePage.vue
new file mode 100644
index 0000000..4be0364
--- /dev/null
+++ b/frontend/src/components/LuckinCoffeePage.vue
@@ -0,0 +1,182 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Orange C / Desk Light
+
+
+ 瑞幸咖啡
+
+
+
+
+
+
+
+
+
+
+
+ Receipt
+
+
+
+ 生椰拿铁
+ x 1
+
+
+ 橙 C 美式
+ x 1
+
+
+ 记住你的喜好
+ 1 次
+
+
+
+
+
+
+
+ Desk Corner
+
+
+ 你连桌角的小小“灵笼”都看见了。喜欢有时候不是一句话,是被认真注意到。
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/components/NepalPageContainer.vue b/frontend/src/components/NepalPageContainer.vue
index fb2c764..5758b8f 100644
--- a/frontend/src/components/NepalPageContainer.vue
+++ b/frontend/src/components/NepalPageContainer.vue
@@ -1,14 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Make Up / 05.04
+
+
+ 和好了,在一起吧
+
+
+
+
+
+
+
+
+
+ Before
+
+
别扭、沉默、想解释
+
+
+
+
+
+
+ After
+
+
说开了、靠近了、在一起了
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/utils/storyPageTransition.ts b/frontend/src/utils/storyPageTransition.ts
index 35e01d3..29c62f8 100644
--- a/frontend/src/utils/storyPageTransition.ts
+++ b/frontend/src/utils/storyPageTransition.ts
@@ -42,6 +42,8 @@ export function getStoryTransitionName(m: Memory | null): StoryTransitionName {
const t = m.unique_feature_type as MemoryFeatureType
if (t === 'heart_window') return 'story-heart'
if (t === 'fissure_page') return 'story-fissure'
+ if (t === 'first_meet' || t === 'first_meet_ju' || t === 'first_meet_rui') return 'story-night'
+ if (t === 'first_meet_train') return 'story-dawn'
return transitionForStandardStyle(m.nepal_art_style)
}
@@ -57,6 +59,12 @@ export function getStoryShellClasses(m: Memory | null): string {
if (t === 'fissure_page') {
return 'border-fuchsia-300/30 shadow-[0_22px_65px_-24px_rgba(120,60,160,0.28)] ring-fuchsia-200/20'
}
+ if (t === 'first_meet' || t === 'first_meet_ju' || t === 'first_meet_rui') {
+ return 'border-slate-400/35 shadow-[0_24px_70px_-22px_rgba(30,58,138,0.28)] ring-cyan-900/15'
+ }
+ if (t === 'first_meet_train') {
+ return 'border-amber-200/50 shadow-[0_24px_72px_-22px_rgba(234,88,12,0.24)] ring-amber-100/35'
+ }
const shells: Partial
> = {
dawn_meet:
'border-amber-200/45 shadow-[0_22px_68px_-22px_rgba(217,119,6,0.22)] ring-amber-100/30',
@@ -87,6 +95,10 @@ export function getStoryNavAccentClass(m: Memory | null): string {
const t = m.unique_feature_type
if (t === 'heart_window') return 'hover:border-rose-300/50 hover:bg-rose-50/80'
if (t === 'fissure_page') return 'hover:border-fuchsia-300/45 hover:bg-fuchsia-50/70'
+ if (t === 'first_meet' || t === 'first_meet_ju' || t === 'first_meet_rui') {
+ return 'hover:border-slate-400/45 hover:bg-slate-100/85'
+ }
+ if (t === 'first_meet_train') return 'hover:border-amber-300/50 hover:bg-amber-50/80'
const accents: Partial> = {
dawn_meet: 'hover:border-amber-300/50 hover:bg-amber-50/80',
blush_argue: 'hover:border-rose-300/45 hover:bg-rose-50/75',