Wedding Invitation
diff --git a/vite-tailwindcss/src/components/themes/covers/CoverInkwash.vue b/vite-tailwindcss/src/components/themes/covers/CoverInkwash.vue
new file mode 100644
index 0000000..50a550f
--- /dev/null
+++ b/vite-tailwindcss/src/components/themes/covers/CoverInkwash.vue
@@ -0,0 +1,114 @@
+
+
+
+
+
山 水 有 相 逢
+
+
+
![封面]()
+
+
+
+ {{ groom }}
+ 囍
+ {{ bride }}
+
+
+
{{ date }} · {{ lunar }}
+
+
+
+
+
+
diff --git a/vite-tailwindcss/src/components/themes/covers/CoverKodak.vue b/vite-tailwindcss/src/components/themes/covers/CoverKodak.vue
new file mode 100644
index 0000000..0fcafab
--- /dev/null
+++ b/vite-tailwindcss/src/components/themes/covers/CoverKodak.vue
@@ -0,0 +1,127 @@
+
+
+
+
+
+
+
+
+
+
![封面]()
+
{{ dateStamp }}
+
+
+
WEDDING FILM · 400
+
+
+
{{ groom }} ♥ {{ bride }}
+
{{ date }} · {{ lunar }}
+
+
+
+
+
+
diff --git a/vite-tailwindcss/src/components/themes/covers/CoverPassport.vue b/vite-tailwindcss/src/components/themes/covers/CoverPassport.vue
new file mode 100644
index 0000000..e1ea3a2
--- /dev/null
+++ b/vite-tailwindcss/src/components/themes/covers/CoverPassport.vue
@@ -0,0 +1,209 @@
+
+
+
+ LOVE AIRLINES
+ FIRST CLASS
+
+
+
+
+
![封面]()
+
+
+
+
+ PASSENGERS{{ groom }} / {{ bride }}
+
+
+ DATE{{ date }}
+ GATEFOREVER
+
+
+
+
APPROVED ♥
+
+
+
+
+
+
+
+
+
diff --git a/vite-tailwindcss/src/components/themes/covers/CoverScrapbook.vue b/vite-tailwindcss/src/components/themes/covers/CoverScrapbook.vue
new file mode 100644
index 0000000..e4f94ed
--- /dev/null
+++ b/vite-tailwindcss/src/components/themes/covers/CoverScrapbook.vue
@@ -0,0 +1,157 @@
+
+
+
○ my wedding journal ○
+
+
+
+
+
+
![封面]()
+
us ♥
+
+
♥
+
★
+
+
+
+ {{ groom }}
+ &
+ {{ bride }}
+
+
+
+ {{ date }}
+ {{ lunar }}
+
+
+
+
+
+
+
diff --git a/vite-tailwindcss/src/components/themes/covers/CoverY2k.vue b/vite-tailwindcss/src/components/themes/covers/CoverY2k.vue
new file mode 100644
index 0000000..b9ce903
--- /dev/null
+++ b/vite-tailwindcss/src/components/themes/covers/CoverY2k.vue
@@ -0,0 +1,186 @@
+
+
+
+
+ wedding.exe
+ ▁▢✕
+
+
+
+
![封面]()
+
+
{{ groom }} ♥ {{ bride }}
+
{{ date }} ☆ {{ lunar }}
+
+ loading love… 99%
+
+
+
+
+
+
+ ✦
+ click to continue
+
+
+
+
+
+
+
diff --git a/vite-tailwindcss/src/composables/borderStyles.js b/vite-tailwindcss/src/composables/borderStyles.js
index c8b7e3c..1d05f3f 100644
--- a/vite-tailwindcss/src/composables/borderStyles.js
+++ b/vite-tailwindcss/src/composables/borderStyles.js
@@ -16,7 +16,11 @@ export const BORDER_STYLES = [
{ value: 'glow', label: '柔光金晕', group: 'base' },
{ value: 'stamp', label: '邮票齿孔', group: 'postcard', shaped: true },
{ value: 'postcard', label: '复古明信片', group: 'postcard' },
- { value: 'arch', label: '拱门', group: 'postcard', ratio: '3 / 4' },
+ { value: 'wreath', label: '花环相框', group: 'postcard', ratio: '3 / 4' },
+ { value: 'baroque', label: '巴洛克金镜', group: 'postcard', ratio: '3 / 4' },
+ { value: 'fan', label: '折扇扇面', group: 'postcard', shaped: true, ratio: '4 / 3' },
+ { value: 'moonwin', label: '月洞圆窗', group: 'postcard', ratio: '1 / 1' },
+ { value: 'ribbon', label: '蝴蝶结缎带', group: 'postcard', ratio: '3 / 4' },
{ value: 'oval', label: '椭圆相框', group: 'postcard', ratio: '3 / 4' },
{ value: 'circle', label: '正圆相框', group: 'postcard', ratio: '1 / 1' },
{ value: 'heart', label: '心形', group: 'postcard', shaped: true, ratio: '1 / 1' },
@@ -44,12 +48,17 @@ export const BORDER_STYLE_GROUPS = [
{ key: 'scenic', label: '横幅 · 云雾花', items: BORDER_STYLES.filter((b) => b.group === 'scenic') },
]
+/** 旧配置值映射:拱门样式已下线,历史数据自动呈现为花环相框 */
+const LEGACY_BORDER_MAP = { arch: 'wreath' }
+
/** 取样式元数据(未知值回落白卡纸) */
export function borderStyleMeta(style) {
- return BORDER_STYLES.find((b) => b.value === style) || BORDER_STYLES.find((b) => b.value === 'mat')
+ const v = LEGACY_BORDER_MAP[style] || style
+ return BORDER_STYLES.find((b) => b.value === v) || BORDER_STYLES.find((b) => b.value === 'mat')
}
export function borderClass(style) {
- const v = BORDER_STYLES.some((b) => b.value === style) ? style : 'mat'
+ const mapped = LEGACY_BORDER_MAP[style] || style
+ const v = BORDER_STYLES.some((b) => b.value === mapped) ? mapped : 'mat'
return 'gf-frame gf-' + v
}
diff --git a/vite-tailwindcss/src/composables/heartCollage.js b/vite-tailwindcss/src/composables/heartCollage.js
index e5d8701..24e66ef 100644
--- a/vite-tailwindcss/src/composables/heartCollage.js
+++ b/vite-tailwindcss/src/composables/heartCollage.js
@@ -1,32 +1,157 @@
import { clampHeroFocus, heroFocusCss } from '@/composables/posterDefaults'
-/** 爱心拼接槽位:百分比绝对定位(顶开叉、中最宽、底收尖)
- * r : 格子圆角(外缘格用大弧度圆角把方块阶梯"磨"成心形弧线)
- * clip : 格子裁切(心尖用 V 形三角收出尖端)
- * 槽位索引与角色保持不变,存量配置的图片顺序不受影响 */
-export const HEART_SLOTS = [
- { l: 6, t: 0, w: 38, h: 14, r: '50% 50% 6px 6px' }, // 0 左上叶(半圆顶)
- { l: 56, t: 0, w: 38, h: 14, r: '50% 50% 6px 6px' }, // 1 右上叶(半圆顶)
- { l: 0, t: 14.8, w: 13, h: 15, r: '55% 6px 6px 6px' }, // 2 左外上(肩部外弧)
- { l: 0, t: 30.6, w: 13, h: 14.6, r: '6px 6px 6px 55%' }, // 3 左外下(收腰起弧)
- { l: 14, t: 14.8, w: 26, h: 30.4 }, // 4 左大图
- { l: 41, t: 14.8, w: 18, h: 30.4 }, // 5 中轴
- { l: 60, t: 14.8, w: 26, h: 30.4 }, // 6 右大图
- { l: 87, t: 14.8, w: 13, h: 15, r: '6px 55% 6px 6px' }, // 7 右外上(肩部外弧)
- { l: 87, t: 30.6, w: 13, h: 14.6, r: '6px 6px 55% 6px' }, // 8 右外下(收腰起弧)
- { l: 8, t: 46.2, w: 16, h: 16, r: '6px 6px 6px 65%' }, // 9 左下收腰(底外弧)
- { l: 25, t: 46.2, w: 50, h: 16 }, // 10 中下横
- { l: 76, t: 46.2, w: 16, h: 16, r: '6px 6px 65% 6px' }, // 11 右下收腰(底外弧)
- { l: 34, t: 63, w: 32, h: 16.5, clip: 'polygon(0 0, 100% 0, 50% 100%)' }, // 12 心尖(V 形)
+/**
+ * 爱心拼接:多套拼法方案(后台可选,classic 为默认)
+ * 槽位字段:
+ * - l/t/w/h : 百分比绝对定位
+ * - r : 圆角(弧形磨边)
+ * - clip : clip-path(V 形心尖等)
+ * - shape : 'heart' —— 整格心形 mask 裁切
+ * - label : 后台拼图板槽位名
+ */
+
+export const HEART_MASK_CSS = "url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath fill='%23000' d='M462.3 62.6C407.5 15.9 326 24.3 275.7 76.2L256 96.5l-19.7-20.3C186.1 24.3 104.5 15.9 49.7 62.6c-62.8 53.6-66.1 149.8-9.9 207.9l193.5 199.8c12.5 12.9 32.8 12.9 45.3 0l193.5-199.8c56.3-58.1 53-154.3-9.8-207.9z'/%3E%3C/svg%3E\") no-repeat 50% 50% / 100% 100%"
+const HEART_MASK_SVG = HEART_MASK_CSS
+
+/* —— classic 经典阶梯(v1 原始矩形,默认) —— */
+const SLOTS_CLASSIC = [
+ { l: 10, t: 0, w: 32, h: 13, label: '左上叶' },
+ { l: 58, t: 0, w: 32, h: 13, label: '右上叶' },
+ { l: 0, t: 14, w: 14, h: 15.5, label: '左外上' },
+ { l: 0, t: 30.5, w: 14, h: 15.5, label: '左外下' },
+ { l: 15, t: 14, w: 26, h: 32, label: '左大图' },
+ { l: 42, t: 14, w: 16, h: 32, label: '中轴' },
+ { l: 59, t: 14, w: 26, h: 32, label: '右大图' },
+ { l: 86, t: 14, w: 14, h: 15.5, label: '右外上' },
+ { l: 86, t: 30.5, w: 14, h: 15.5, label: '右外下' },
+ { l: 10, t: 47, w: 13, h: 16, label: '左下' },
+ { l: 24, t: 47, w: 52, h: 16, label: '中下横' },
+ { l: 77, t: 47, w: 13, h: 16, label: '右下' },
+ { l: 38, t: 64, w: 24, h: 14, label: '心尖' },
]
-export const HEART_SLOT_COUNT = HEART_SLOTS.length
-
-export const HEART_SLOT_LABELS = [
- '左上叶', '右上叶', '左外上', '左外下', '左大图', '中轴', '右大图',
- '右外上', '右外下', '左下', '中下横', '右下', '心尖',
+/* —— soft 圆弧心(外缘大圆角 + V 形心尖) —— */
+const SLOTS_SOFT = [
+ { l: 6, t: 0, w: 38, h: 14, r: '50% 50% 6px 6px', label: '左上叶' },
+ { l: 56, t: 0, w: 38, h: 14, r: '50% 50% 6px 6px', label: '右上叶' },
+ { l: 0, t: 14.8, w: 13, h: 15, r: '55% 6px 6px 6px', label: '左外上' },
+ { l: 0, t: 30.6, w: 13, h: 14.6, r: '6px 6px 6px 55%', label: '左外下' },
+ { l: 14, t: 14.8, w: 26, h: 30.4, label: '左大图' },
+ { l: 41, t: 14.8, w: 18, h: 30.4, label: '中轴' },
+ { l: 60, t: 14.8, w: 26, h: 30.4, label: '右大图' },
+ { l: 87, t: 14.8, w: 13, h: 15, r: '6px 55% 6px 6px', label: '右外上' },
+ { l: 87, t: 30.6, w: 13, h: 14.6, r: '6px 6px 55% 6px', label: '右外下' },
+ { l: 8, t: 46.2, w: 16, h: 16, r: '6px 6px 6px 65%', label: '左下' },
+ { l: 25, t: 46.2, w: 50, h: 16, label: '中下横' },
+ { l: 76, t: 46.2, w: 16, h: 16, r: '6px 6px 65% 6px', label: '右下' },
+ { l: 34, t: 63, w: 32, h: 16.5, clip: 'polygon(0 0, 100% 0, 50% 100%)', label: '心尖' },
]
+/* —— ring 环绕心(中央大圆 + 12 小圆沿心形轮廓) —— */
+const SLOTS_RING = [
+ { l: 30, t: 24, w: 40, h: 32, r: '50%', label: '中央主图' },
+ { l: 43, t: 5.4, w: 14, h: 11.2, r: '50%', label: '凹口' },
+ { l: 28, t: 0, w: 14, h: 11.2, r: '50%', label: '左叶顶' },
+ { l: 58, t: 0, w: 14, h: 11.2, r: '50%', label: '右叶顶' },
+ { l: 13, t: 3.4, w: 14, h: 11.2, r: '50%', label: '左叶外' },
+ { l: 73, t: 3.4, w: 14, h: 11.2, r: '50%', label: '右叶外' },
+ { l: 3, t: 20.4, w: 14, h: 11.2, r: '50%', label: '左肩' },
+ { l: 83, t: 20.4, w: 14, h: 11.2, r: '50%', label: '右肩' },
+ { l: 9, t: 39.4, w: 14, h: 11.2, r: '50%', label: '左腰' },
+ { l: 77, t: 39.4, w: 14, h: 11.2, r: '50%', label: '右腰' },
+ { l: 25, t: 57.4, w: 14, h: 11.2, r: '50%', label: '左下' },
+ { l: 61, t: 57.4, w: 14, h: 11.2, r: '50%', label: '右下' },
+ { l: 43, t: 72, w: 14, h: 11.2, r: '50%', label: '心尖' },
+]
+
+/* —— grid 格子心(等大方格阶梯,像素心) —— */
+const SLOTS_GRID = (() => {
+ const W = 18
+ const H = 14.4
+ const colX = [5, 24, 43, 62, 81]
+ const rowY = [2, 20, 38, 56]
+ const cells = [
+ [0, 1], [0, 3],
+ [1, 0], [1, 1], [1, 2], [1, 3], [1, 4],
+ [2, 1], [2, 2], [2, 3],
+ [3, 2],
+ ]
+ const labels = ['左叶', '右叶', '左耳', '左颊', '中心', '右颊', '右耳', '左收', '中收', '右收', '心尖']
+ return cells.map(([row, col], i) => ({
+ l: colX[col], t: rowY[row], w: W, h: H, r: '4px', label: labels[i] || `格${i + 1}`,
+ }))
+})()
+
+/* —— wings 比翼心(两大翼 + 中缝收尖列,少图大脸友好) —— */
+const SLOTS_WINGS = [
+ { l: 2, t: 3, w: 46, h: 54, r: '48% 46% 8% 62% / 42% 38% 8% 34%', label: '左翼' },
+ { l: 52, t: 3, w: 46, h: 54, r: '46% 48% 62% 8% / 38% 42% 34% 8%', label: '右翼' },
+ { l: 42.5, t: 59, w: 15, h: 12, r: '50%', label: '收心一' },
+ { l: 44, t: 72.5, w: 12, h: 9.6, r: '50%', label: '收心二' },
+ { l: 45.5, t: 83.5, w: 9, h: 7.2, r: '50%', label: '心尖' },
+]
+
+/* —— mosaic 马赛克心(大小方块混拼) —— */
+const SLOTS_MOSAIC = [
+ { l: 8, t: 2, w: 22, h: 15, r: '6px', label: '左叶大' },
+ { l: 70, t: 2, w: 22, h: 15, r: '6px', label: '右叶大' },
+ { l: 32, t: 6, w: 16, h: 11, r: '5px', label: '左叶内' },
+ { l: 52, t: 6, w: 16, h: 11, r: '5px', label: '右叶内' },
+ { l: 4, t: 19, w: 30, h: 21, r: '6px', label: '左脸' },
+ { l: 66, t: 19, w: 30, h: 21, r: '6px', label: '右脸' },
+ { l: 36, t: 19, w: 28, h: 14, r: '5px', label: '中上' },
+ { l: 36, t: 35, w: 28, h: 10, r: '4px', label: '中带' },
+ { l: 12, t: 42, w: 24, h: 15, r: '5px', label: '左收' },
+ { l: 64, t: 42, w: 24, h: 15, r: '5px', label: '右收' },
+ { l: 38, t: 47, w: 24, h: 12, r: '4px', label: '中横' },
+ { l: 26, t: 59, w: 16, h: 11, r: '4px', label: '左下' },
+ { l: 58, t: 59, w: 16, h: 11, r: '4px', label: '右下' },
+ { l: 43, t: 61, w: 14, h: 14, r: '4px', label: '中下' },
+ { l: 44, t: 77, w: 12, h: 8.5, r: '4px', label: '心尖' },
+]
+
+/* —— orbit 星环心(心形大图 + 8 小圆环绕) —— */
+const SLOTS_ORBIT = [
+ { l: 20, t: 16, w: 60, h: 46, shape: 'heart', label: '心形主图' },
+ { l: 22, t: 0, w: 12, h: 9.6, r: '50%', label: '左上星' },
+ { l: 66, t: 0, w: 12, h: 9.6, r: '50%', label: '右上星' },
+ { l: 4, t: 18, w: 12, h: 9.6, r: '50%', label: '左星' },
+ { l: 84, t: 18, w: 12, h: 9.6, r: '50%', label: '右星' },
+ { l: 12, t: 42, w: 12, h: 9.6, r: '50%', label: '左下星' },
+ { l: 76, t: 42, w: 12, h: 9.6, r: '50%', label: '右下星' },
+ { l: 30, t: 63, w: 12, h: 9.6, r: '50%', label: '尖左星' },
+ { l: 58, t: 63, w: 12, h: 9.6, r: '50%', label: '尖右星' },
+]
+
+export const HEART_LAYOUTS = [
+ { key: 'classic', label: '经典阶梯', desc: '矩形块阶梯拼合(默认)', slots: SLOTS_CLASSIC },
+ { key: 'soft', label: '圆弧心', desc: '外缘弧形磨边 + V 形心尖', slots: SLOTS_SOFT },
+ { key: 'ring', label: '环绕心', desc: '中央大圆 + 小圆沿轮廓环绕', slots: SLOTS_RING },
+ { key: 'grid', label: '格子心', desc: '等大方格像素心', slots: SLOTS_GRID },
+ { key: 'wings', label: '比翼心', desc: '两大翼 + 收尖圆列(图少脸大)', slots: SLOTS_WINGS },
+ { key: 'mosaic', label: '马赛克心', desc: '大小方块混拼', slots: SLOTS_MOSAIC },
+ { key: 'orbit', label: '星环心', desc: '心形整图 + 星点环绕', slots: SLOTS_ORBIT },
+]
+
+const HEART_LAYOUT_MAP = Object.fromEntries(HEART_LAYOUTS.map((x) => [x.key, x]))
+
+export function normalizeHeartLayout(key) {
+ return HEART_LAYOUT_MAP[key] ? key : 'classic'
+}
+
+export function heartLayoutMeta(key) {
+ return HEART_LAYOUT_MAP[normalizeHeartLayout(key)]
+}
+
+/** 取页面配置对应的槽位数组 */
+export function heartSlotsFor(page) {
+ return heartLayoutMeta(page?.heartLayout).slots
+}
+
+/* —— 兼容旧引用:默认方案 —— */
+export const HEART_SLOTS = SLOTS_CLASSIC
+export const HEART_SLOT_COUNT = SLOTS_CLASSIC.length
+
export function heartSlotStyle(slot) {
return {
left: `${slot.l}%`,
@@ -36,17 +161,21 @@ export function heartSlotStyle(slot) {
}
}
-export function heartSlotLabel(i) {
- return HEART_SLOT_LABELS[i] || `图${i + 1}`
+export function heartSlotLabel(page, i) {
+ const slots = heartSlotsFor(page)
+ return slots[i]?.label || `图${i + 1}`
}
-/** 格子形状样式(圆角/裁切),作用在展示格上让整体轮廓贴近心形 */
-export function heartCellShape(i) {
- const s = HEART_SLOTS[i]
- if (!s) return {}
+/** 格子形状样式(圆角/裁切/心形 mask),作用在展示格上 */
+export function heartCellShape(slot) {
+ if (!slot) return {}
const style = {}
- if (s.r) style.borderRadius = s.r
- if (s.clip) style.clipPath = s.clip
+ if (slot.r) style.borderRadius = slot.r
+ if (slot.clip) style.clipPath = slot.clip
+ if (slot.shape === 'heart') {
+ style.webkitMask = HEART_MASK_SVG
+ style.mask = HEART_MASK_SVG
+ }
return style
}
diff --git a/vite-tailwindcss/src/style.css b/vite-tailwindcss/src/style.css
index c2ed8c7..c6b04f5 100644
--- a/vite-tailwindcss/src/style.css
+++ b/vite-tailwindcss/src/style.css
@@ -57,11 +57,11 @@ html[data-theme='guofeng-new'] {
--c-muted: #8b8a80;
--c-ink: #2c302c;
--c-ink-soft: #4a4f48;
- --c-paper: #faf8f2;
- --c-bg: #f6f3ec;
- --c-bg-deep: #ece7db;
+ --c-paper: #f7f5e8;
+ --c-bg: #f2efe0;
+ --c-bg-deep: #e6e2ce;
--c-card: #fffefa;
- --c-on-primary: #f6f3ec;
+ --c-on-primary: #f2efe0;
--t-font-title: var(--font-serif);
--t-font-kicker: var(--font-kai);
--t-font-body: var(--font-serif);
@@ -79,9 +79,9 @@ html[data-theme='guofeng-old'] {
--c-muted: #9a8578;
--c-ink: #3a2428;
--c-ink-soft: #5c3a40;
- --c-paper: #fdf6f0;
- --c-bg: #f9efe6;
- --c-bg-deep: #f2e3d4;
+ --c-paper: #fcf4e6;
+ --c-bg: #f8ecda;
+ --c-bg-deep: #f0dec4;
--c-card: #fffaf4;
--c-on-primary: #f7e7c3;
--t-font-title: var(--font-mashan);
@@ -101,9 +101,9 @@ html[data-theme='french'] {
--c-muted: #9c8b90;
--c-ink: #3d3136;
--c-ink-soft: #5c454e;
- --c-paper: #fdfafa;
- --c-bg: #fdf6f4;
- --c-bg-deep: #f7e9e7;
+ --c-paper: #fdf4f6;
+ --c-bg: #fceef0;
+ --c-bg-deep: #f7e2e4;
--c-card: #ffffff;
--c-on-primary: #ffffff;
--t-font-title: var(--font-calligraphy);
@@ -115,17 +115,17 @@ html[data-theme='french'] {
}
/* 现代简约:暖灰低饱和 · 无衬线 · 细几何 */
html[data-theme='modern'] {
- --c-primary: #8a8578;
- --c-primary-deep: #757064;
- --c-primary-rgb: 138, 133, 120;
- --c-line: #a39e91;
- --c-line-rgb: 163, 158, 145;
- --c-muted: #8f8c85;
- --c-ink: #2e2d2a;
- --c-ink-soft: #4a4842;
- --c-paper: #fbfaf8;
- --c-bg: #f7f6f3;
- --c-bg-deep: #edebe6;
+ --c-primary: #6e7b84;
+ --c-primary-deep: #5c6a74;
+ --c-primary-rgb: 110, 123, 132;
+ --c-line: #93a4ae;
+ --c-line-rgb: 147, 164, 174;
+ --c-muted: #84909a;
+ --c-ink: #2a3238;
+ --c-ink-soft: #46525c;
+ --c-paper: #f8fafb;
+ --c-bg: #f1f4f6;
+ --c-bg-deep: #e4eaee;
--c-card: #ffffff;
--c-on-primary: #ffffff;
--t-font-title: var(--font-sans);
@@ -145,9 +145,9 @@ html[data-theme='forest'] {
--c-muted: #86928a;
--c-ink: #29322c;
--c-ink-soft: #3d4a40;
- --c-paper: #f9fcf9;
- --c-bg: #f3f8f2;
- --c-bg-deep: #e9f0e7;
+ --c-paper: #f3f9f2;
+ --c-bg: #ecf4ea;
+ --c-bg-deep: #dfeadd;
--c-card: #ffffff;
--c-on-primary: #ffffff;
--t-font-title: var(--font-longcang);
@@ -189,9 +189,9 @@ html[data-theme='magazine'] {
--c-muted: #7d786f;
--c-ink: #1f1c19;
--c-ink-soft: #3a352e;
- --c-paper: #faf8f4;
- --c-bg: #f5f2ec;
- --c-bg-deep: #eae6dd;
+ --c-paper: #f7f4ec;
+ --c-bg: #f2eee4;
+ --c-bg-deep: #e4dfd0;
--c-card: #ffffff;
--c-on-primary: #ffffff;
--t-font-title: var(--font-display);
@@ -211,11 +211,11 @@ html[data-theme='newspaper'] {
--c-muted: #6f6b62;
--c-ink: #262420;
--c-ink-soft: #423e35;
- --c-paper: #fbf9f2;
- --c-bg: #f6f3ea;
- --c-bg-deep: #ebe7da;
+ --c-paper: #f9f5e4;
+ --c-bg: #f4efdc;
+ --c-bg-deep: #e7e0c8;
--c-card: #fffdf6;
- --c-on-primary: #fbf9f2;
+ --c-on-primary: #f9f5e4;
--t-font-title: var(--font-serif);
--t-font-kicker: var(--font-display);
--t-font-body: var(--font-serif);
@@ -233,9 +233,9 @@ html[data-theme='pixel'] {
--c-muted: #8a7f74;
--c-ink: #33261f;
--c-ink-soft: #54433a;
- --c-paper: #fdf9ee;
- --c-bg: #faf3e6;
- --c-bg-deep: #f0e6d2;
+ --c-paper: #fcf5e0;
+ --c-bg: #f9f0da;
+ --c-bg-deep: #eee0c0;
--c-card: #fffdf4;
--c-on-primary: #fffdf4;
--t-font-title: var(--font-pixel);
@@ -245,21 +245,219 @@ html[data-theme='pixel'] {
--t-radius-btn: 0px;
--t-bg-texture: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Crect x='0' y='0' width='4' height='4' fill='%2333261f' fill-opacity='0.02'/%3E%3Crect x='4' y='4' width='4' height='4' fill='%2333261f' fill-opacity='0.02'/%3E%3C/svg%3E");
}
-/* 极简主义:黑白留白 · 细线 · 轴线 */
-html[data-theme='zen'] {
- --c-primary: #2a2a28;
- --c-primary-deep: #111111;
- --c-primary-rgb: 42, 42, 40;
- --c-line: #8f8d88;
- --c-line-rgb: 143, 141, 136;
- --c-muted: #85837e;
- --c-ink: #262624;
- --c-ink-soft: #444442;
- --c-paper: #fdfdfc;
- --c-bg: #fafaf8;
- --c-bg-deep: #f0f0ed;
+/* 水彩画境:雾蓝淡彩 · 晕染 · 柔圆 */
+html[data-theme='watercolor'] {
+ --c-primary: #7f9bb3;
+ --c-primary-deep: #6a86a0;
+ --c-primary-rgb: 127, 155, 179;
+ --c-line: #a8c0d0;
+ --c-line-rgb: 168, 192, 208;
+ --c-muted: #8b939c;
+ --c-ink: #33404a;
+ --c-ink-soft: #52626e;
+ --c-paper: #f5f9fc;
+ --c-bg: #edf4fa;
+ --c-bg-deep: #dde9f2;
--c-card: #ffffff;
--c-on-primary: #ffffff;
+ --t-font-title: var(--font-calligraphy);
+ --t-font-kicker: var(--font-sans);
+ --t-font-body: var(--font-sans);
+ --t-radius-card: 20px;
+ --t-radius-btn: 999px;
+ --t-bg-texture: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cg fill-opacity='0.05'%3E%3Ccircle cx='40' cy='48' r='26' fill='%237f9bb3'/%3E%3Ccircle cx='138' cy='30' r='18' fill='%23c8a8c0'/%3E%3Ccircle cx='120' cy='128' r='30' fill='%2388b8a8'/%3E%3Ccircle cx='34' cy='140' r='16' fill='%23a8c0d0'/%3E%3C/g%3E%3C/svg%3E");
+}
+/* 樱花物语:粉白渐彩 · 花瓣 */
+html[data-theme='sakura'] {
+ --c-primary: #d98a9e;
+ --c-primary-deep: #c67689;
+ --c-primary-rgb: 217, 138, 158;
+ --c-line: #e8b4c2;
+ --c-line-rgb: 232, 180, 194;
+ --c-muted: #a08d93;
+ --c-ink: #43333a;
+ --c-ink-soft: #64505a;
+ --c-paper: #fdf3f6;
+ --c-bg: #fcedf1;
+ --c-bg-deep: #f6dfe6;
+ --c-card: #ffffff;
+ --c-on-primary: #ffffff;
+ --t-font-title: var(--font-calligraphy);
+ --t-font-kicker: "Pinyon Script", cursive;
+ --t-font-body: var(--font-sans);
+ --t-radius-card: 16px;
+ --t-radius-btn: 999px;
+ --t-bg-texture: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cg fill='%23e8a8bc' fill-opacity='0.08'%3E%3Cellipse cx='26' cy='30' rx='5' ry='3.2' transform='rotate(-24 26 30)'/%3E%3Cellipse cx='104' cy='18' rx='4' ry='2.6' transform='rotate(18 104 18)'/%3E%3Cellipse cx='120' cy='96' rx='5.5' ry='3.4' transform='rotate(-40 120 96)'/%3E%3Cellipse cx='48' cy='112' rx='4.4' ry='2.8' transform='rotate(30 48 112)'/%3E%3Cellipse cx='78' cy='64' rx='3.6' ry='2.2' transform='rotate(-12 78 64)'/%3E%3C/g%3E%3C/svg%3E");
+}
+/* 水墨山水:宣纸墨韵 · 朱砂印 */
+html[data-theme='inkwash'] {
+ --c-primary: #3a3f3a;
+ --c-primary-deep: #262a26;
+ --c-primary-rgb: 58, 63, 58;
+ --c-line: #8a9088;
+ --c-line-rgb: 138, 144, 136;
+ --c-muted: #82887e;
+ --c-ink: #2a2e2a;
+ --c-ink-soft: #4a504a;
+ --c-paper: #f7f7f0;
+ --c-bg: #f2f2ea;
+ --c-bg-deep: #e2e2d6;
+ --c-card: #fdfdfa;
+ --c-on-primary: #f2f2ea;
+ --t-font-title: var(--font-kai);
+ --t-font-kicker: var(--font-kai);
+ --t-font-body: var(--font-serif);
+ --t-radius-card: 2px;
+ --t-radius-btn: 2px;
+ --t-bg-texture: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cg fill='%233a3f3a' fill-opacity='0.028'%3E%3Cpath d='M0 158q50-36 100-10t100-16v68H0z'/%3E%3C/g%3E%3Cg fill='%233a3f3a' fill-opacity='0.02'%3E%3Ccircle cx='150' cy='40' r='2'/%3E%3Ccircle cx='36' cy='60' r='1.4'/%3E%3C/g%3E%3C/svg%3E");
+}
+/* 复古电影:上映海报 · 做旧奶油 */
+html[data-theme='cinema'] {
+ --c-primary: #b8322e;
+ --c-primary-deep: #962622;
+ --c-primary-rgb: 184, 50, 46;
+ --c-line: #d4a24a;
+ --c-line-rgb: 212, 162, 74;
+ --c-muted: #97887a;
+ --c-ink: #3a2c22;
+ --c-ink-soft: #5c4738;
+ --c-paper: #f5ead4;
+ --c-bg: #efe0c8;
+ --c-bg-deep: #e2d0ae;
+ --c-card: #fbf4e8;
+ --c-on-primary: #fbf4e8;
+ --t-font-title: var(--font-display);
+ --t-font-kicker: var(--font-cinzel);
+ --t-font-body: var(--font-serif);
+ --t-radius-card: 6px;
+ --t-radius-btn: 4px;
+ --t-bg-texture: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='90' height='90'%3E%3Cg fill='%233a2c22' fill-opacity='0.026'%3E%3Ccircle cx='16' cy='26' r='1.1'/%3E%3Ccircle cx='58' cy='12' r='1.5'/%3E%3Ccircle cx='80' cy='46' r='1'/%3E%3Ccircle cx='34' cy='62' r='1.3'/%3E%3Ccircle cx='68' cy='80' r='1.1'/%3E%3C/g%3E%3C/svg%3E");
+}
+/* 胶片日记:柯达暖调 · 齿孔框 */
+html[data-theme='kodak'] {
+ --c-primary: #e0782e;
+ --c-primary-deep: #c86420;
+ --c-primary-rgb: 224, 120, 46;
+ --c-line: #3c3a34;
+ --c-line-rgb: 60, 58, 52;
+ --c-muted: #96897a;
+ --c-ink: #38302a;
+ --c-ink-soft: #5c5044;
+ --c-paper: #fbf4de;
+ --c-bg: #f8f0d8;
+ --c-bg-deep: #eddfba;
+ --c-card: #fffdf6;
+ --c-on-primary: #fffdf6;
+ --t-font-title: var(--font-sans);
+ --t-font-kicker: var(--font-number);
+ --t-font-body: var(--font-sans);
+ --t-radius-card: 8px;
+ --t-radius-btn: 8px;
+ --t-bg-texture: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100'%3E%3Cg fill='%2338302a' fill-opacity='0.022'%3E%3Ccircle cx='20' cy='30' r='1.2'/%3E%3Ccircle cx='66' cy='14' r='1'/%3E%3Ccircle cx='84' cy='60' r='1.3'/%3E%3Ccircle cx='38' cy='78' r='1'/%3E%3C/g%3E%3C/svg%3E");
+}
+/* 文艺影调:对称构图 · 衬线留白 */
+html[data-theme='arthouse'] {
+ --c-primary: #4a4640;
+ --c-primary-deep: #322f2a;
+ --c-primary-rgb: 74, 70, 64;
+ --c-line: #9a948a;
+ --c-line-rgb: 154, 148, 138;
+ --c-muted: #8c877d;
+ --c-ink: #363330;
+ --c-ink-soft: #5a564e;
+ --c-paper: #f4efdc;
+ --c-bg: #f1ede2;
+ --c-bg-deep: #e3decd;
+ --c-card: #fdfbf7;
+ --c-on-primary: #f4efdc;
+ --t-font-title: var(--font-display);
+ --t-font-kicker: var(--font-display);
+ --t-font-body: var(--font-serif);
+ --t-radius-card: 0px;
+ --t-radius-btn: 0px;
+ --t-bg-texture: none;
+}
+/* 环球旅行:护照蓝金 · 登机牌 */
+html[data-theme='passport'] {
+ --c-primary: #2e4a68;
+ --c-primary-deep: #223a54;
+ --c-primary-rgb: 46, 74, 104;
+ --c-line: #b08a4a;
+ --c-line-rgb: 176, 138, 74;
+ --c-muted: #85898c;
+ --c-ink: #2c3640;
+ --c-ink-soft: #4a5662;
+ --c-paper: #f4f7fa;
+ --c-bg: #eceff2;
+ --c-bg-deep: #dde3ea;
+ --c-card: #fcfaf4;
+ --c-on-primary: #eceff2;
+ --t-font-title: var(--font-display);
+ --t-font-kicker: var(--font-number);
+ --t-font-body: var(--font-sans);
+ --t-radius-card: 10px;
+ --t-radius-btn: 6px;
+ --t-bg-texture: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cg fill='none' stroke='%232e4a68' stroke-opacity='0.04' stroke-width='1' stroke-dasharray='4 5'%3E%3Cpath d='M-10 120C40 60 120 100 170 30'/%3E%3C/g%3E%3Cg fill='%232e4a68' fill-opacity='0.05'%3E%3Cpath d='M96 66l10 4-10 4 2-4z'/%3E%3C/g%3E%3C/svg%3E");
+}
+/* 手账拼贴:牛皮纸 · 胶带贴纸 */
+html[data-theme='scrapbook'] {
+ --c-primary: #c47a5a;
+ --c-primary-deep: #a86446;
+ --c-primary-rgb: 196, 122, 90;
+ --c-line: #8aa88a;
+ --c-line-rgb: 138, 168, 138;
+ --c-muted: #9a8f80;
+ --c-ink: #453a30;
+ --c-ink-soft: #665748;
+ --c-paper: #fbf2dc;
+ --c-bg: #f7ecd4;
+ --c-bg-deep: #ecdcba;
+ --c-card: #fffcf4;
+ --c-on-primary: #fffcf4;
+ --t-font-title: var(--font-longcang);
+ --t-font-kicker: var(--font-liujian);
+ --t-font-body: var(--font-sans);
+ --t-radius-card: 6px;
+ --t-radius-btn: 8px;
+ --t-bg-texture: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='60' height='60'%3E%3Cg fill='%23453a30' fill-opacity='0.03'%3E%3Ccircle cx='12' cy='12' r='1.4'/%3E%3Ccircle cx='42' cy='30' r='1.4'/%3E%3Ccircle cx='20' cy='48' r='1.4'/%3E%3C/g%3E%3C/svg%3E");
+}
+/* 千禧蒸汽波:紫青渐变 · 复古窗口 */
+html[data-theme='y2k'] {
+ --c-primary: #7a4ae0;
+ --c-primary-deep: #6238c0;
+ --c-primary-rgb: 122, 74, 224;
+ --c-line: #4adce0;
+ --c-line-rgb: 74, 220, 224;
+ --c-muted: #8d87a0;
+ --c-ink: #322a48;
+ --c-ink-soft: #544a70;
+ --c-paper: #efeafa;
+ --c-bg: #e7e1f8;
+ --c-bg-deep: #d4cbee;
+ --c-card: #faf8ff;
+ --c-on-primary: #faf8ff;
+ --t-font-title: var(--font-sans);
+ --t-font-kicker: var(--font-pixel);
+ --t-font-body: var(--font-sans);
+ --t-radius-card: 8px;
+ --t-radius-btn: 6px;
+ --t-bg-texture: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cg fill='%237a4ae0' fill-opacity='0.05'%3E%3Cpath d='M30 20l2.4 6 6 2.4-6 2.4-2.4 6-2.4-6-6-2.4 6-2.4z'/%3E%3Cpath d='M92 74l1.8 4.4 4.4 1.8-4.4 1.8-1.8 4.4-1.8-4.4-4.4-1.8 4.4-1.8z'/%3E%3C/g%3E%3Cg fill='%234adce0' fill-opacity='0.05'%3E%3Ccircle cx='72' cy='28' r='2.4'/%3E%3Ccircle cx='24' cy='92' r='2'/%3E%3C/g%3E%3C/svg%3E");
+}
+/* 极简主义:暖白留白 · 细线 · 轴线 */
+html[data-theme='zen'] {
+ --c-primary: #57503f;
+ --c-primary-deep: #3e392c;
+ --c-primary-rgb: 87, 80, 63;
+ --c-line: #a89f8e;
+ --c-line-rgb: 168, 159, 142;
+ --c-muted: #8f887a;
+ --c-ink: #3c362e;
+ --c-ink-soft: #5c5548;
+ --c-paper: #fdfbf7;
+ --c-bg: #faf7f2;
+ --c-bg-deep: #f0ebe2;
+ --c-card: #fffef9;
+ --c-on-primary: #fdfbf7;
--t-font-title: var(--font-sans);
--t-font-kicker: var(--font-sans);
--t-font-body: var(--font-sans);
diff --git a/vite-tailwindcss/src/styles/frames.css b/vite-tailwindcss/src/styles/frames.css
index a379275..9bc783f 100644
--- a/vite-tailwindcss/src/styles/frames.css
+++ b/vite-tailwindcss/src/styles/frames.css
@@ -127,20 +127,24 @@
:where(.gf-postcard, .gf-film, .gf-stamp, .gf-arch, .gf-oval, .gf-circle, .gf-leaf,
.gf-heart, .gf-flower, .gf-hexagon, .gf-scallop, .gf-wave, .gf-zigzag,
.gf-torn, .gf-ticket, .gf-bevel,
+.gf-wreath, .gf-baroque, .gf-fan, .gf-moonwin, .gf-ribbon,
.gf-cloud, .gf-mist, .gf-bloom, .gf-panorama, .gf-ovalwide) {
position: relative;
}
-/* 边缘渐隐内晕:照片边缘向纸色柔和过渡,与边框/裁切形状融为一体
- (mask/clip 类的伪元素会随形状一并裁切,晕自动贴合轮廓) */
+/* 边缘渐隐内晕:照片边缘向页面纸色柔和过渡,与边框/裁切形状融为一体
+ (mask/clip 类的伪元素会随形状一并裁切,晕自动贴合轮廓;
+ 颜色用 color-mix 跟随主题纸色,深浅主题都能融入页面) */
.gf-heart::after, .gf-flower::after, .gf-scallop::after, .gf-wave::after,
.gf-zigzag::after, .gf-torn::after, .gf-stamp::after, .gf-ticket::after,
.gf-hexagon::after, .gf-bevel::after, .gf-arch::after, .gf-oval::after,
-.gf-circle::after, .gf-leaf::after, .gf-cloud::after, .gf-ovalwide::after {
+.gf-circle::after, .gf-leaf::after, .gf-cloud::after, .gf-ovalwide::after,
+.gf-wreath::after, .gf-baroque::after, .gf-fan::after, .gf-moonwin::after,
+.gf-ribbon::after {
content: '';
position: absolute;
inset: 0;
- background: radial-gradient(ellipse 62% 62% at 50% 50%, rgba(255, 252, 246, 0) 55%, rgba(255, 252, 246, 0.48) 100%);
+ background: radial-gradient(ellipse 64% 64% at 50% 50%, transparent 50%, color-mix(in srgb, var(--c-paper, #fffcf6) 62%, transparent) 100%);
pointer-events: none;
}
@@ -205,39 +209,143 @@
pointer-events: none;
}
-/* 拱门(顶部全圆,婚礼穹顶造型) */
-.gf-arch {
- padding: 8px;
- border: 1px solid rgba(201, 169, 120, 0.5);
- border-radius: 999px 999px 14px 14px;
- box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.65), 0 14px 32px rgba(120, 90, 60, 0.16);
- background: #fff;
-}
-.gf-arch > img {
- border-radius: 992px 992px 8px 8px;
-}
-/* 拱顶花饰圆章(呼应尾页门框 keystone) */
-.gf-arch::before {
- content: '❀';
- position: absolute;
- top: 12px;
- left: 50%;
- transform: translateX(-50%);
- width: 26px;
- height: 26px;
+/* 花环相框(月桂双枝环抱椭圆照片,arch 为历史别名) */
+.gf-arch,
+.gf-wreath {
+ padding: 22px;
+ border: 0;
border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 12px;
- line-height: 1;
- color: #b08e63;
- background: rgba(253, 251, 247, 0.92);
- box-shadow: 0 0 0 1px rgba(201, 169, 120, 0.45), 0 2px 6px rgba(120, 90, 60, 0.18);
+ box-shadow: none;
+ background: transparent;
+}
+.gf-arch > img,
+.gf-wreath > img {
+ border-radius: 50%;
+}
+.gf-arch::before,
+.gf-wreath::before {
+ content: '';
+ position: absolute;
+ inset: -4px;
+ background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 250'%3E%3Cg fill='none' stroke='%238a9a76' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M104 240C48 230 16 178 20 112 22 70 38 38 66 18'/%3E%3Cpath d='M96 240c56-10 88-62 84-128-2-42-18-74-46-94'/%3E%3C/g%3E%3Cg fill='%239ab48a'%3E%3Cellipse cx='34' cy='196' rx='11' ry='4.6' transform='rotate(38 34 196)'/%3E%3Cellipse cx='23' cy='164' rx='11' ry='4.6' transform='rotate(64 23 164)'/%3E%3Cellipse cx='19' cy='128' rx='11' ry='4.6' transform='rotate(82 19 128)'/%3E%3Cellipse cx='24' cy='92' rx='11' ry='4.6' transform='rotate(102 24 92)'/%3E%3Cellipse cx='38' cy='56' rx='11' ry='4.6' transform='rotate(124 38 56)'/%3E%3Cellipse cx='60' cy='30' rx='11' ry='4.6' transform='rotate(146 60 30)'/%3E%3Cellipse cx='166' cy='196' rx='11' ry='4.6' transform='rotate(-38 166 196)'/%3E%3Cellipse cx='177' cy='164' rx='11' ry='4.6' transform='rotate(-64 177 164)'/%3E%3Cellipse cx='181' cy='128' rx='11' ry='4.6' transform='rotate(-82 181 128)'/%3E%3Cellipse cx='176' cy='92' rx='11' ry='4.6' transform='rotate(-102 176 92)'/%3E%3Cellipse cx='162' cy='56' rx='11' ry='4.6' transform='rotate(-124 162 56)'/%3E%3Cellipse cx='140' cy='30' rx='11' ry='4.6' transform='rotate(-146 140 30)'/%3E%3C/g%3E%3Cg fill='%23b8cba6' opacity='.85'%3E%3Cellipse cx='46' cy='222' rx='9' ry='3.8' transform='rotate(22 46 222)'/%3E%3Cellipse cx='154' cy='222' rx='9' ry='3.8' transform='rotate(-22 154 222)'/%3E%3Cellipse cx='84' cy='10' rx='9' ry='3.8' transform='rotate(168 84 10)'/%3E%3Cellipse cx='116' cy='10' rx='9' ry='3.8' transform='rotate(12 116 10)'/%3E%3C/g%3E%3Cg fill='%23e4aeb6'%3E%3Cg transform='translate(100 244)'%3E%3Ccircle cx='0' cy='-4' r='3.4'/%3E%3Ccircle cx='3.8' cy='1.4' r='3.4'/%3E%3Ccircle cx='-3.8' cy='1.4' r='3.4'/%3E%3Ccircle r='1.8' fill='%23c9a24a'/%3E%3C/g%3E%3Cg transform='translate(30 40) scale(.8)'%3E%3Ccircle cx='0' cy='-4' r='3.4'/%3E%3Ccircle cx='3.8' cy='1.4' r='3.4'/%3E%3Ccircle cx='-3.8' cy='1.4' r='3.4'/%3E%3Ccircle r='1.8' fill='%23c9a24a'/%3E%3C/g%3E%3Cg transform='translate(170 40) scale(.8)'%3E%3Ccircle cx='0' cy='-4' r='3.4'/%3E%3Ccircle cx='3.8' cy='1.4' r='3.4'/%3E%3Ccircle cx='-3.8' cy='1.4' r='3.4'/%3E%3Ccircle r='1.8' fill='%23c9a24a'/%3E%3C/g%3E%3C/g%3E%3Cg fill='%23d98a9e' opacity='.7'%3E%3Ccircle cx='52' cy='210' r='2.6'/%3E%3Ccircle cx='148' cy='210' r='2.6'/%3E%3Ccircle cx='26' cy='76' r='2.4'/%3E%3Ccircle cx='174' cy='76' r='2.4'/%3E%3C/g%3E%3C/svg%3E") center / 100% 100% no-repeat;
pointer-events: none;
z-index: 1;
}
+/* 巴洛克金镜(凡尔赛宫廷椭圆镜:金渐变边 + 顶部卷草冠饰) */
+.gf-baroque {
+ padding: 9px;
+ border: 3.5px solid transparent;
+ border-radius: 50%;
+ background:
+ linear-gradient(180deg, #fffdf8, #fbf4e6) padding-box,
+ linear-gradient(140deg, #ead7aa 0%, #b08d54 26%, #f6ecd0 48%, #a8834a 72%, #e2cb98 100%) border-box;
+ box-shadow:
+ 0 0 0 1px rgba(140, 108, 60, 0.5),
+ 0 0 0 6px rgba(246, 236, 208, 0.55),
+ 0 0 0 7.5px rgba(176, 141, 84, 0.5),
+ 0 16px 36px rgba(120, 90, 50, 0.22);
+}
+.gf-baroque > img {
+ border-radius: 50%;
+}
+.gf-baroque::before {
+ content: '';
+ position: absolute;
+ top: -21px;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 84px;
+ height: 26px;
+ background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 84 26'%3E%3Cg fill='none' stroke='%23b08d54' stroke-width='1.6' stroke-linecap='round'%3E%3Cpath d='M42 22c-6-2-8-7-5-11 2.6-3.4 7-2.4 7 1 0 2.6-2.6 3.4-4 1.6'/%3E%3Cpath d='M42 22c6-2 8-7 5-11-2.6-3.4-7-2.4-7 1 0 2.6 2.6 3.4 4 1.6'/%3E%3Cpath d='M30 21C20 19 14 13 16 7c4 2 8 6 10 11'/%3E%3Cpath d='M54 21c10-2 16-8 14-14-4 2-8 6-10 11'/%3E%3Cpath d='M14 8C10 6 6 6 3 9c3 2 6 2 9 1'/%3E%3Cpath d='M70 8c4-2 8-2 11 1-3 2-6 2-9 1'/%3E%3C/g%3E%3Ccircle cx='42' cy='6' r='2.6' fill='%23c9a24a'/%3E%3C/svg%3E") center / contain no-repeat;
+ pointer-events: none;
+ z-index: 1;
+}
+
+/* 折扇扇面(底心圆点展开的扇形:clip 扇角 ∩ mask 环带,附扇骨放射线)
+ 环带 mask 内外缘放宽渐变即自带羽化,clip 斜边与顶边由 ::after 贴边雾软化 */
+.gf-fan {
+ padding: 0;
+ border: 0;
+ border-radius: 0;
+ box-shadow: none;
+ background: transparent;
+ clip-path: polygon(50% 126%, -14% -6%, 114% -6%);
+ -webkit-clip-path: polygon(50% 126%, -14% -6%, 114% -6%);
+ -webkit-mask: radial-gradient(146% 146% at 50% 126%, transparent 27%, #000 33%, #000 93%, transparent 98.5%);
+ mask: radial-gradient(146% 146% at 50% 126%, transparent 27%, #000 33%, #000 93%, transparent 98.5%);
+}
+/* 扇骨:自底心放射的细白线 + 弧沿描边 */
+.gf-fan::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background:
+ repeating-conic-gradient(from -57deg at 50% 126%, rgba(255, 253, 246, 0.6) 0 0.5deg, transparent 0.5deg 16.2deg),
+ radial-gradient(146% 146% at 50% 126%, transparent 91%, rgba(190, 155, 105, 0.45) 92.5%, rgba(190, 155, 105, 0.45) 95%, transparent 96.5%),
+ radial-gradient(146% 146% at 50% 126%, transparent 30%, rgba(190, 155, 105, 0.4) 31.5%, rgba(190, 155, 105, 0.4) 34%, transparent 35.5%);
+ pointer-events: none;
+ z-index: 1;
+}
+/* 扇面贴边雾:顶边下坠 + 左右斜边 + 内弧收口(覆盖通用椭圆晕,全部贴合扇形轮廓) */
+.gf-fan::after {
+ background:
+ linear-gradient(180deg, color-mix(in srgb, var(--c-paper, #fffcf6) 78%, transparent), transparent 15%),
+ linear-gradient(68deg, color-mix(in srgb, var(--c-paper, #fffcf6) 72%, transparent), transparent 26%),
+ linear-gradient(292deg, color-mix(in srgb, var(--c-paper, #fffcf6) 72%, transparent), transparent 26%),
+ radial-gradient(146% 146% at 50% 126%, transparent 28%, color-mix(in srgb, var(--c-paper, #fffcf6) 55%, transparent) 34%, transparent 42%);
+}
+
+/* 月洞圆窗(正圆开窗 + 双环窗线 + 右上探入梅枝) */
+.gf-moonwin {
+ padding: 9px;
+ border: 0;
+ border-radius: 50%;
+ box-shadow: none;
+ background: transparent;
+}
+.gf-moonwin > img {
+ border-radius: 50%;
+}
+.gf-moonwin::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ border-radius: 50%;
+ border: 1.5px solid rgba(110, 120, 105, 0.6);
+ box-shadow:
+ inset 0 0 0 4px rgba(255, 255, 255, 0.6),
+ inset 0 0 0 5px rgba(110, 120, 105, 0.35);
+ background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cg fill='none' stroke='%236e7869' stroke-width='1.1' stroke-linecap='round'%3E%3Cpath d='M96 22C84 30 72 34 58 34'/%3E%3Cpath d='M84 27c-2-5-1-9 3-12'/%3E%3Cpath d='M70 32c-1-4 0-7 3-9'/%3E%3C/g%3E%3Cg fill='%23d9a0a5'%3E%3Ccircle cx='80' cy='24' r='2.6'/%3E%3Ccircle cx='68' cy='30' r='2.2'/%3E%3Ccircle cx='58' cy='33' r='1.8'/%3E%3C/g%3E%3Ccircle cx='74' cy='21' r='1.2' fill='%23c9a24a'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
+ pointer-events: none;
+ z-index: 1;
+}
+
+/* 蝴蝶结缎带框(顶部系结垂带的礼物相框) */
+.gf-ribbon {
+ padding: 13px 11px 11px;
+ border: 1px solid rgba(217, 160, 165, 0.55);
+ border-radius: 12px;
+ background: linear-gradient(180deg, #fffafa, #fdf1f3);
+ box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.7), 0 12px 28px rgba(190, 120, 130, 0.18);
+}
+.gf-ribbon > img {
+ border-radius: 7px;
+}
+.gf-ribbon::before {
+ content: '';
+ position: absolute;
+ top: -15px;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 66px;
+ height: 44px;
+ background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 66 44'%3E%3Cg fill='%23e093a3'%3E%3Cpath d='M33 12C26 4 14 2 8 8c-5 5-3 13 4 15 8 2 17-4 21-11z' fill='%23e8a8b2'/%3E%3Cpath d='M33 12c7-8 19-10 25-4 5 5 3 13-4 15-8 2-17-4-21-11z' fill='%23e8a8b2'/%3E%3Cpath d='M33 12C28 7 20 6 16 10c-3 3-2 8 2 9 6 2 12-2 15-7z' fill='%23f2c4cc' opacity='.9'/%3E%3Cpath d='M33 12c5-5 13-6 17-2 3 3 2 8-2 9-6 2-12-2-15-7z' fill='%23f2c4cc' opacity='.9'/%3E%3Cpath d='M27 20l-7 20 8-3 3 5 4-22z' fill='%23e8a8b2'/%3E%3Cpath d='M39 20l7 20-8-3-3 5-4-22z' fill='%23dfa0aa'/%3E%3Ccircle cx='33' cy='13' r='5' fill='%23d9899a'/%3E%3Ccircle cx='33' cy='13' r='2.2' fill='%23f2c4cc'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat;
+ filter: drop-shadow(0 3px 5px rgba(190, 120, 130, 0.3));
+ pointer-events: none;
+ z-index: 2;
+}
+
/* 椭圆相框 */
.gf-oval {
padding: 7px;
@@ -305,6 +413,16 @@
clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
-webkit-clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
}
+/* 六向贴形边雾:每条边各一道向内渐隐,取代不贴形的通用椭圆晕 */
+.gf-hexagon::after {
+ background:
+ linear-gradient(210deg, color-mix(in srgb, var(--c-paper, #fffcf6) 62%, transparent), transparent 17%),
+ linear-gradient(270deg, color-mix(in srgb, var(--c-paper, #fffcf6) 62%, transparent), transparent 17%),
+ linear-gradient(330deg, color-mix(in srgb, var(--c-paper, #fffcf6) 62%, transparent), transparent 17%),
+ linear-gradient(30deg, color-mix(in srgb, var(--c-paper, #fffcf6) 62%, transparent), transparent 17%),
+ linear-gradient(90deg, color-mix(in srgb, var(--c-paper, #fffcf6) 62%, transparent), transparent 17%),
+ linear-gradient(150deg, color-mix(in srgb, var(--c-paper, #fffcf6) 62%, transparent), transparent 17%);
+}
/* 八瓣花(多层 radial mask 合成花形,推荐 1:1) */
.gf-flower {
@@ -313,35 +431,35 @@
border-radius: 0;
box-shadow: none;
-webkit-mask:
- radial-gradient(19% 19% at 50% 19%, #000 98%, #0000 100%),
- radial-gradient(19% 19% at 71.9% 28.1%, #000 98%, #0000 100%),
- radial-gradient(19% 19% at 81% 50%, #000 98%, #0000 100%),
- radial-gradient(19% 19% at 71.9% 71.9%, #000 98%, #0000 100%),
- radial-gradient(19% 19% at 50% 81%, #000 98%, #0000 100%),
- radial-gradient(19% 19% at 28.1% 71.9%, #000 98%, #0000 100%),
- radial-gradient(19% 19% at 19% 50%, #000 98%, #0000 100%),
- radial-gradient(19% 19% at 28.1% 28.1%, #000 98%, #0000 100%),
- radial-gradient(34% 34% at 50% 50%, #000 98%, #0000 100%);
+ radial-gradient(19% 19% at 50% 19%, #000 68%, #0000 99%),
+ radial-gradient(19% 19% at 71.9% 28.1%, #000 68%, #0000 99%),
+ radial-gradient(19% 19% at 81% 50%, #000 68%, #0000 99%),
+ radial-gradient(19% 19% at 71.9% 71.9%, #000 68%, #0000 99%),
+ radial-gradient(19% 19% at 50% 81%, #000 68%, #0000 99%),
+ radial-gradient(19% 19% at 28.1% 71.9%, #000 68%, #0000 99%),
+ radial-gradient(19% 19% at 19% 50%, #000 68%, #0000 99%),
+ radial-gradient(19% 19% at 28.1% 28.1%, #000 68%, #0000 99%),
+ radial-gradient(34% 34% at 50% 50%, #000 82%, #0000 100%);
mask:
- radial-gradient(19% 19% at 50% 19%, #000 98%, #0000 100%),
- radial-gradient(19% 19% at 71.9% 28.1%, #000 98%, #0000 100%),
- radial-gradient(19% 19% at 81% 50%, #000 98%, #0000 100%),
- radial-gradient(19% 19% at 71.9% 71.9%, #000 98%, #0000 100%),
- radial-gradient(19% 19% at 50% 81%, #000 98%, #0000 100%),
- radial-gradient(19% 19% at 28.1% 71.9%, #000 98%, #0000 100%),
- radial-gradient(19% 19% at 19% 50%, #000 98%, #0000 100%),
- radial-gradient(19% 19% at 28.1% 28.1%, #000 98%, #0000 100%),
- radial-gradient(34% 34% at 50% 50%, #000 98%, #0000 100%);
+ radial-gradient(19% 19% at 50% 19%, #000 68%, #0000 99%),
+ radial-gradient(19% 19% at 71.9% 28.1%, #000 68%, #0000 99%),
+ radial-gradient(19% 19% at 81% 50%, #000 68%, #0000 99%),
+ radial-gradient(19% 19% at 71.9% 71.9%, #000 68%, #0000 99%),
+ radial-gradient(19% 19% at 50% 81%, #000 68%, #0000 99%),
+ radial-gradient(19% 19% at 28.1% 71.9%, #000 68%, #0000 99%),
+ radial-gradient(19% 19% at 19% 50%, #000 68%, #0000 99%),
+ radial-gradient(19% 19% at 28.1% 28.1%, #000 68%, #0000 99%),
+ radial-gradient(34% 34% at 50% 50%, #000 82%, #0000 100%);
}
-/* 心形(SVG mask 裁切,推荐 1:1) */
+/* 心形(SVG mask 裁切 + 内嵌高斯模糊羽化边,推荐 1:1) */
.gf-heart {
padding: 0;
border: 0;
border-radius: 0;
box-shadow: none;
- -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath fill='%23000' d='M462.3 62.6C407.5 15.9 326 24.3 275.7 76.2L256 96.5l-19.7-20.3C186.1 24.3 104.5 15.9 49.7 62.6c-62.8 53.6-66.1 149.8-9.9 207.9l193.5 199.8c12.5 12.9 32.8 12.9 45.3 0l193.5-199.8c56.3-58.1 53-154.3-9.8-207.9z'/%3E%3C/svg%3E") no-repeat 50% 50% / 100% 100%;
- mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath fill='%23000' d='M462.3 62.6C407.5 15.9 326 24.3 275.7 76.2L256 96.5l-19.7-20.3C186.1 24.3 104.5 15.9 49.7 62.6c-62.8 53.6-66.1 149.8-9.9 207.9l193.5 199.8c12.5 12.9 32.8 12.9 45.3 0l193.5-199.8c56.3-58.1 53-154.3-9.8-207.9z'/%3E%3C/svg%3E") no-repeat 50% 50% / 100% 100%;
+ -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cdefs%3E%3Cfilter id='f' x='-20%25' y='-20%25' width='140%25' height='140%25'%3E%3CfeGaussianBlur stdDeviation='12'/%3E%3C/filter%3E%3C/defs%3E%3Cpath filter='url(%23f)' fill='%23000' d='M462.3 62.6C407.5 15.9 326 24.3 275.7 76.2L256 96.5l-19.7-20.3C186.1 24.3 104.5 15.9 49.7 62.6c-62.8 53.6-66.1 149.8-9.9 207.9l193.5 199.8c12.5 12.9 32.8 12.9 45.3 0l193.5-199.8c56.3-58.1 53-154.3-9.8-207.9z'/%3E%3C/svg%3E") no-repeat 50% 50% / 100% 100%;
+ mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cdefs%3E%3Cfilter id='f' x='-20%25' y='-20%25' width='140%25' height='140%25'%3E%3CfeGaussianBlur stdDeviation='12'/%3E%3C/filter%3E%3C/defs%3E%3Cpath filter='url(%23f)' fill='%23000' d='M462.3 62.6C407.5 15.9 326 24.3 275.7 76.2L256 96.5l-19.7-20.3C186.1 24.3 104.5 15.9 49.7 62.6c-62.8 53.6-66.1 149.8-9.9 207.9l193.5 199.8c12.5 12.9 32.8 12.9 45.3 0l193.5-199.8c56.3-58.1 53-154.3-9.8-207.9z'/%3E%3C/svg%3E") no-repeat 50% 50% / 100% 100%;
}
/* 扇贝花边(四边外凸圆弧波浪) */
@@ -541,12 +659,12 @@
box-shadow: none;
background: #fff;
-webkit-mask:
- radial-gradient(var(--gf-c), #000 98%, #0000) 0 0 / calc(3.4 * var(--gf-c)) calc(3.4 * var(--gf-c)) round,
- radial-gradient(calc(0.68 * var(--gf-c)), #000 98%, #0000) calc(1.7 * var(--gf-c)) calc(1.7 * var(--gf-c)) / calc(3.4 * var(--gf-c)) calc(3.4 * var(--gf-c)) round,
+ radial-gradient(var(--gf-c), #000 62%, #0000 99%) 0 0 / calc(3.4 * var(--gf-c)) calc(3.4 * var(--gf-c)) round,
+ radial-gradient(calc(0.68 * var(--gf-c)), #000 62%, #0000 99%) calc(1.7 * var(--gf-c)) calc(1.7 * var(--gf-c)) / calc(3.4 * var(--gf-c)) calc(3.4 * var(--gf-c)) round,
linear-gradient(#000 0 0) 50% / calc(100% - 2.4 * var(--gf-c)) calc(100% - 2.4 * var(--gf-c)) no-repeat;
mask:
- radial-gradient(var(--gf-c), #000 98%, #0000) 0 0 / calc(3.4 * var(--gf-c)) calc(3.4 * var(--gf-c)) round,
- radial-gradient(calc(0.68 * var(--gf-c)), #000 98%, #0000) calc(1.7 * var(--gf-c)) calc(1.7 * var(--gf-c)) / calc(3.4 * var(--gf-c)) calc(3.4 * var(--gf-c)) round,
+ radial-gradient(var(--gf-c), #000 62%, #0000 99%) 0 0 / calc(3.4 * var(--gf-c)) calc(3.4 * var(--gf-c)) round,
+ radial-gradient(calc(0.68 * var(--gf-c)), #000 62%, #0000 99%) calc(1.7 * var(--gf-c)) calc(1.7 * var(--gf-c)) / calc(3.4 * var(--gf-c)) calc(3.4 * var(--gf-c)) round,
linear-gradient(#000 0 0) 50% / calc(100% - 2.4 * var(--gf-c)) calc(100% - 2.4 * var(--gf-c)) no-repeat;
}
/* 右上飘着的小云 */
@@ -692,9 +810,45 @@
z-index: 1;
}
-/* 异形裁切类的投影:mask 会裁掉 box-shadow,由父级 drop-shadow 跟随轮廓补投影 */
+/* ———— 云雾加持:拱门/椭圆/云朵边缘的飘动雾层 ————
+ 覆盖上方通用渐隐层:顶部柔光 + 两团缓慢漂移的白雾 + 底部升雾 + 周缘主题色淡晕。
+ 雾团层带显式 background-size,靠 background-position 关键帧漂移。 */
+.gf-arch::after,
+.gf-wreath::after,
+.gf-moonwin::after,
+.gf-oval::after,
+.gf-ovalwide::after,
+.gf-cloud::after {
+ background:
+ radial-gradient(120% 60% at 50% 0%, rgba(255, 255, 255, 0.32), transparent 46%) 50% 0 / 100% 100%,
+ radial-gradient(50% 50% at 50% 50%, rgba(255, 255, 255, 0.5), transparent 72%) 8% 96% / 64% 34%,
+ radial-gradient(50% 50% at 50% 50%, rgba(255, 255, 255, 0.4), transparent 74%) 92% 99% / 56% 28%,
+ linear-gradient(0deg, color-mix(in srgb, var(--c-paper, #fffcf6) 58%, transparent), transparent 30%) 0 0 / 100% 100%,
+ radial-gradient(ellipse 72% 72% at 50% 46%, transparent 56%, color-mix(in srgb, var(--c-paper, #fffcf6) 46%, transparent) 100%) 0 0 / 100% 100%;
+ background-repeat: no-repeat;
+ animation: gfFogDrift 15s ease-in-out infinite alternate;
+}
+@keyframes gfFogDrift {
+ from {
+ background-position: 50% 0, 0% 96%, 100% 99%, 0 0, 0 0;
+ }
+ to {
+ background-position: 50% 0, 34% 90%, 64% 96%, 0 0, 0 0;
+ }
+}
+/* 晨雾框的底部双雾团:缓慢涌动 */
+.gf-mist::before {
+ animation: gfMistSway 11s ease-in-out infinite alternate;
+}
+@keyframes gfMistSway {
+ from { transform: translateX(-7px) scaleY(1); }
+ to { transform: translateX(7px) scaleY(1.12); }
+}
+
+/* 异形裁切类的投影:mask 会裁掉 box-shadow,由父级 drop-shadow 跟随轮廓补投影
+ (投影刻意压淡:裁切形状靠边缘虚化融入页面,重阴影会显得生硬) */
.gf-shape-shadow {
- filter: drop-shadow(0 10px 18px rgba(96, 72, 50, 0.22));
+ filter: drop-shadow(0 6px 12px rgba(96, 72, 50, 0.12));
}
/* 辅助:图片保持原始宽高比(单图铺满+保比例时使用,覆盖 gf-frame 的 height:100%) */
diff --git a/vite-tailwindcss/src/styles/theme-packs.css b/vite-tailwindcss/src/styles/theme-packs.css
index 08b4c19..ef3830e 100644
--- a/vite-tailwindcss/src/styles/theme-packs.css
+++ b/vite-tailwindcss/src/styles/theme-packs.css
@@ -9,6 +9,67 @@
.wrapper {
font-family: var(--t-font-body);
}
+
+/* ============================================================
+ 页面级背景拉距:每套模板一条纵向色调过渡(跨全页),
+ 彻底区分「整体色感」,不再全是相近的米白
+ ============================================================ */
+html[data-theme='cinema'] .wrapper {
+ background:
+ radial-gradient(120% 46% at 50% 0%, rgba(140, 38, 34, 0.07), transparent 70%),
+ linear-gradient(175deg, #f5ead2 0%, #f0e2c8 45%, #e4cfaa 100%);
+}
+html[data-theme='kodak'] .wrapper {
+ background:
+ radial-gradient(120% 40% at 50% 0%, rgba(224, 120, 46, 0.13), transparent 70%),
+ linear-gradient(175deg, #fdf6e2 0%, #faf0d8 42%, #f0dfb2 100%);
+}
+html[data-theme='passport'] .wrapper {
+ background: linear-gradient(175deg, #eef0ec 0%, #e6ecf2 48%, #d8e2ec 100%);
+}
+html[data-theme='scrapbook'] .wrapper {
+ background: linear-gradient(175deg, #f8efdc 0%, #f5ead2 50%, #ead8ba 100%);
+}
+html[data-theme='y2k'] .wrapper {
+ background: linear-gradient(165deg, #ece6fa 0%, #e0ecfa 45%, #f6e2f4 100%);
+}
+html[data-theme='watercolor'] .wrapper {
+ background: linear-gradient(170deg, #f2f8fc 0%, #ecf3f8 38%, #f6eef6 72%, #ecf6f0 100%);
+}
+html[data-theme='sakura'] .wrapper {
+ background: linear-gradient(175deg, #fdf3f6 0%, #fbecf1 50%, #f6e0e8 100%);
+}
+html[data-theme='inkwash'] .wrapper {
+ background: linear-gradient(175deg, #f8f8f4 0%, #f1f1ea 55%, #e6e6db 100%);
+}
+html[data-theme='guofeng-old'] .wrapper {
+ background:
+ radial-gradient(120% 42% at 50% 0%, rgba(168, 50, 62, 0.07), transparent 70%),
+ linear-gradient(175deg, #faf0e4 0%, #f7e8d8 45%, #f0dac4 100%);
+}
+html[data-theme='guofeng-new'] .wrapper {
+ background: linear-gradient(175deg, #f7f4ec 0%, #f1eee2 55%, #e7e4d4 100%);
+}
+html[data-theme='magazine'] .wrapper {
+ background: linear-gradient(175deg, #f5f2ea 0%, #eeebe0 55%, #e2ded0 100%);
+}
+html[data-theme='newspaper'] .wrapper {
+ background: linear-gradient(175deg, #f8f4e4 0%, #f3eeda 50%, #e9e0c4 100%);
+}
+html[data-theme='pixel'] .wrapper {
+ background: linear-gradient(175deg, #fbf4e4 0%, #f8edd4 50%, #efe0bc 100%);
+}
+html[data-theme='zen'] .wrapper {
+ background: linear-gradient(175deg, #fbf8f3 0%, #f7f3ea 55%, #efe9dc 100%);
+}
+html[data-theme='arthouse'] .wrapper {
+ background: linear-gradient(175deg, #f5f2eb 0%, #efebe0 55%, #e4dfd0 100%);
+}
+html[data-theme='night'] .wrapper {
+ background:
+ radial-gradient(120% 50% at 50% 0%, rgba(64, 92, 140, 0.32), transparent 72%),
+ linear-gradient(175deg, #101b2e 0%, #0d1728 55%, #080f1c 100%);
+}
/* 纹理挂在既有的背景装饰层上(fixed 装饰层,pointer-events 已禁) */
.bg-glow {
background-image: var(--t-bg-texture);
@@ -150,9 +211,6 @@ html[data-theme='modern'] .emblem-kicker {
html[data-theme='modern'] .emblem-seal {
border-radius: 12px;
}
-html[data-theme='modern'] .ending-keystone .ek-mark {
- display: none;
-}
/* ============================================================
森系自然:叶纹纸感(纹理已由 --t-bg-texture 提供)
@@ -217,12 +275,10 @@ html[data-theme='night'] .ending-kicker span::before {
幕布内容变体(emblem-inner 内,按主题分支渲染)
============================================================ */
/* 完整模板:隐藏经典弧线花饰(幕布内容已是各自的专属排版) */
-html[data-theme='guofeng-new'] .cover-filigree,
-html[data-theme='guofeng-old'] .cover-filigree,
-html[data-theme='magazine'] .cover-filigree,
-html[data-theme='newspaper'] .cover-filigree,
-html[data-theme='pixel'] .cover-filigree,
-html[data-theme='zen'] .cover-filigree {
+html:is([data-theme='guofeng-new'], [data-theme='guofeng-old'], [data-theme='magazine'],
+[data-theme='newspaper'], [data-theme='pixel'], [data-theme='zen'],
+[data-theme='inkwash'], [data-theme='cinema'], [data-theme='kodak'],
+[data-theme='arthouse'], [data-theme='passport'], [data-theme='scrapbook'], [data-theme='y2k']) .cover-filigree {
display: none;
}
@@ -231,32 +287,26 @@ html[data-theme='zen'] .cover-filigree {
—— 保留 curtain DOM 骨架(退场动画仍作用于同一批元素),
卡片撑满全屏后每套做成完全不同的「开场画面」
============================================================ */
-html[data-theme='guofeng-new'] .curtain-emblem,
-html[data-theme='guofeng-old'] .curtain-emblem,
-html[data-theme='magazine'] .curtain-emblem,
-html[data-theme='newspaper'] .curtain-emblem,
-html[data-theme='pixel'] .curtain-emblem,
-html[data-theme='zen'] .curtain-emblem {
+html:is([data-theme='guofeng-new'], [data-theme='guofeng-old'], [data-theme='magazine'],
+[data-theme='newspaper'], [data-theme='pixel'], [data-theme='zen'],
+[data-theme='inkwash'], [data-theme='cinema'], [data-theme='kodak'],
+[data-theme='arthouse'], [data-theme='passport'], [data-theme='scrapbook'], [data-theme='y2k']) .curtain-emblem {
padding: 0;
}
-html[data-theme='guofeng-new'] .invite-cover,
-html[data-theme='guofeng-old'] .invite-cover,
-html[data-theme='magazine'] .invite-cover,
-html[data-theme='newspaper'] .invite-cover,
-html[data-theme='pixel'] .invite-cover,
-html[data-theme='zen'] .invite-cover {
+html:is([data-theme='guofeng-new'], [data-theme='guofeng-old'], [data-theme='magazine'],
+[data-theme='newspaper'], [data-theme='pixel'], [data-theme='zen'],
+[data-theme='inkwash'], [data-theme='cinema'], [data-theme='kodak'],
+[data-theme='arthouse'], [data-theme='passport'], [data-theme='scrapbook'], [data-theme='y2k']) .invite-cover {
width: 100%;
min-height: 100dvh;
max-width: none;
border-radius: 0 !important;
padding: 0;
}
-html[data-theme='guofeng-new'] .emblem-inner,
-html[data-theme='guofeng-old'] .emblem-inner,
-html[data-theme='magazine'] .emblem-inner,
-html[data-theme='newspaper'] .emblem-inner,
-html[data-theme='pixel'] .emblem-inner,
-html[data-theme='zen'] .emblem-inner {
+html:is([data-theme='guofeng-new'], [data-theme='guofeng-old'], [data-theme='magazine'],
+[data-theme='newspaper'], [data-theme='pixel'], [data-theme='zen'],
+[data-theme='inkwash'], [data-theme='cinema'], [data-theme='kodak'],
+[data-theme='arthouse'], [data-theme='passport'], [data-theme='scrapbook'], [data-theme='y2k']) .emblem-inner {
min-height: 100dvh;
display: flex;
flex-direction: column;
@@ -264,35 +314,79 @@ html[data-theme='zen'] .emblem-inner {
justify-content: center;
padding: max(44px, env(safe-area-inset-top)) 30px max(44px, env(safe-area-inset-bottom));
}
-/* 满屏形态不需要门板与模糊底图(各主题另行指定背景) */
-html[data-theme='guofeng-new'] .curtain-door,
-html[data-theme='guofeng-old'] .curtain-door,
-html[data-theme='newspaper'] .curtain-door,
-html[data-theme='pixel'] .curtain-door,
-html[data-theme='zen'] .curtain-door,
-html[data-theme='magazine'] .curtain-door,
-html[data-theme='guofeng-old'] .curtain-bg,
-html[data-theme='newspaper'] .curtain-bg,
-html[data-theme='pixel'] .curtain-bg,
-html[data-theme='zen'] .curtain-bg {
+/* 满屏形态不需要门板与模糊底图(各主题另行指定背景;老中式保留双门做宫门) */
+html:is([data-theme='guofeng-new'], [data-theme='magazine'],
+[data-theme='newspaper'], [data-theme='pixel'], [data-theme='zen'],
+[data-theme='inkwash'], [data-theme='cinema'], [data-theme='kodak'],
+[data-theme='arthouse'], [data-theme='passport'], [data-theme='scrapbook'], [data-theme='y2k']) .curtain-door,
+html:is([data-theme='guofeng-old'], [data-theme='newspaper'], [data-theme='pixel'], [data-theme='zen'],
+[data-theme='inkwash'], [data-theme='cinema'], [data-theme='kodak'],
+[data-theme='arthouse'], [data-theme='passport'], [data-theme='scrapbook'], [data-theme='y2k']) .curtain-bg {
+ display: none;
+}
+html:is([data-theme='inkwash'], [data-theme='cinema'], [data-theme='kodak'],
+[data-theme='arthouse'], [data-theme='passport'], [data-theme='scrapbook']) .curtain-veil {
display: none;
}
-/* —— 老中式:朱红宫门(门钉阵列 + 中缝金线 + 匾额婚书) —— */
+/* —— 老中式:真·朱红宫门(双扇门板 + 门钉 + 铺首 + 悬浮匾额) —— */
+html[data-theme='guofeng-old'] .curtain-root {
+ background: #4a1216;
+}
html[data-theme='guofeng-old'] .curtain-veil {
display: none;
}
+/* 双扇宫门:门钉两列 + 木纹 + 靠中缝受光 */
+html[data-theme='guofeng-old'] .curtain-door {
+ background:
+ radial-gradient(circle 5px at 32% 50%, rgba(217, 178, 92, 0.95) 92%, transparent) 0 24px / 100% 88px repeat-y,
+ radial-gradient(circle 5px at 68% 50%, rgba(217, 178, 92, 0.95) 92%, transparent) 0 68px / 100% 88px repeat-y,
+ repeating-linear-gradient(90deg, rgba(60, 12, 16, 0.12) 0 3px, transparent 3px 26px),
+ linear-gradient(174deg, #a83440 0%, #8f2a35 52%, #78222c 100%);
+ box-shadow: inset 0 0 60px rgba(50, 8, 12, 0.5);
+}
+html[data-theme='guofeng-old'] .curtain-door-left {
+ border-right: 2px solid rgba(var(--c-line-rgb), 0.65);
+}
+html[data-theme='guofeng-old'] .curtain-door-right {
+ border-left: 2px solid rgba(var(--c-line-rgb), 0.65);
+}
+html[data-theme='guofeng-old'] .curtain-door::before {
+ display: none;
+}
+/* 铺首门环:金色双环,挂在各门靠中缝一侧 */
+html[data-theme='guofeng-old'] .curtain-door::after {
+ content: '';
+ position: absolute;
+ top: 52%;
+ width: 34px;
+ height: 34px;
+ inset-inline: auto;
+ border: 0;
+ border-radius: 50%;
+ background:
+ radial-gradient(circle at 50% 32%, #e8c878, #b8923a 60%, #8a6a1a 100%);
+ box-shadow:
+ inset 0 0 0 4px rgba(120, 34, 44, 0.9),
+ inset 0 0 0 6px rgba(217, 178, 92, 0.85),
+ 0 4px 10px rgba(40, 6, 10, 0.5);
+ pointer-events: none;
+}
+html[data-theme='guofeng-old'] .curtain-door-left::after {
+ right: 12%;
+}
+html[data-theme='guofeng-old'] .curtain-door-right::after {
+ left: 12%;
+}
+html[data-theme='guofeng-old'] .door-sheen {
+ background: linear-gradient(115deg, rgba(255, 236, 200, 0.16) 0%, transparent 34%, transparent 68%, rgba(255, 236, 200, 0.1) 100%);
+ background-image: none;
+}
+/* 匾额悬于门上(invite-cover 透明,匾额即 emblem-inner) */
html[data-theme='guofeng-old'] .invite-cover {
border: none;
box-shadow: none;
- background:
- /* 左右两列门钉 */
- radial-gradient(circle 5px at 14% 50%, rgba(217, 178, 92, 0.95) 92%, transparent) 0 0 / 100% 92px repeat-y,
- radial-gradient(circle 5px at 86% 50%, rgba(217, 178, 92, 0.95) 92%, transparent) 0 46px / 100% 92px repeat-y,
- /* 中缝金线 */
- linear-gradient(90deg, transparent 49.7%, rgba(var(--c-line-rgb), 0.5) 50%, transparent 50.3%),
- radial-gradient(ellipse at 50% 10%, rgba(216, 90, 90, 0.32), transparent 50%),
- linear-gradient(174deg, #ab3641 0%, #932c37 52%, #7e2530 100%);
+ background: transparent;
}
/* 匾额:婚书内容嵌一块金边红匾 */
html[data-theme='guofeng-old'] .emblem-inner {
@@ -1138,6 +1232,1991 @@ html[data-theme='pixel'] .section-dot {
border-radius: 0;
}
+/* ============================================================
+ 日历模板(cal-style-*):8 种视觉样式,auto 跟随主题、可手动指定
+ classic 为默认样式(不覆盖)
+ ============================================================ */
+/* —— 中式红金:宫墙红实底 + 泥金文字(成套皮肤,颜色自足不随主题漂移) —— */
+.calendar-card.cal-style-redgold {
+ --cal-title: #f2d9a2;
+ --cal-sub: #d9b06c;
+ --cal-kicker: #e7c584;
+ --cal-week: #e7c584;
+ --cal-day: #e6cfa0;
+ --cal-rule: rgba(231, 197, 132, 0.55);
+ --cal-title-rule: rgba(231, 197, 132, 0.85);
+ border: 2px solid rgba(201, 162, 74, 0.85);
+ outline: 1px solid rgba(201, 162, 74, 0.4);
+ outline-offset: 4px;
+ border-radius: 4px;
+ background:
+ radial-gradient(130% 56% at 50% 0%, rgba(224, 110, 96, 0.2), transparent 62%),
+ linear-gradient(172deg, #9c2c3a 0%, #86222e 55%, #701a25 100%);
+ box-shadow: 0 18px 46px rgba(58, 10, 16, 0.38), inset 0 0 0 8px rgba(201, 162, 74, 0.1);
+}
+.calendar-card.cal-style-redgold::before {
+ border-color: rgba(201, 162, 74, 0.45);
+}
+/* 版式:请柬轴式——顶部金底通栏「囍期已定」+ 底部金底通栏尾注 */
+.calendar-card.cal-style-redgold {
+ padding-top: 56px;
+ padding-bottom: 52px;
+}
+.calendar-card.cal-style-redgold .calendar-kicker {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ padding: 8px 0 7px;
+ font-size: 0;
+ letter-spacing: 0;
+ background: linear-gradient(90deg, transparent, rgba(201, 162, 74, 0.92) 18%, rgba(216, 171, 94, 0.95) 50%, rgba(201, 162, 74, 0.92) 82%, transparent);
+}
+.calendar-card.cal-style-redgold .calendar-kicker::before {
+ content: '囍 期 已 定';
+ font-size: 13px;
+ letter-spacing: 0.5em;
+ padding-left: 0.5em;
+ color: #7a1a25;
+ font-family: var(--font-kai);
+ font-weight: 700;
+}
+.calendar-card.cal-style-redgold .calendar-title {
+ font-family: var(--font-kai);
+ margin-top: 4px;
+}
+.calendar-card.cal-style-redgold .calendar-note {
+ position: absolute;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ margin: 0;
+ padding: 8px 0 7px;
+ color: #7a1a25;
+ background: linear-gradient(90deg, transparent, rgba(201, 162, 74, 0.92) 18%, rgba(216, 171, 94, 0.95) 50%, rgba(201, 162, 74, 0.92) 82%, transparent);
+}
+.calendar-card.cal-style-redgold .calendar-note i {
+ background: rgba(122, 26, 37, 0.55);
+}
+/* 顶部横幅上方的金铃穗结 */
+.calendar-card.cal-style-redgold::after {
+ content: '';
+ position: absolute;
+ top: 33px;
+ left: 50%;
+ width: 46px;
+ height: 1px;
+ transform: translateX(-50%);
+ background: linear-gradient(90deg, transparent, rgba(231, 197, 132, 0.8), transparent);
+ pointer-events: none;
+}
+.calendar-card.cal-style-redgold .calendar-weekdays {
+ border-top: 1px solid rgba(231, 197, 132, 0.35);
+ border-bottom: 1px solid rgba(231, 197, 132, 0.35);
+ padding: 6px 0;
+}
+.calendar-card.cal-style-redgold .calendar-weekdays span {
+ font-family: var(--font-kai);
+}
+/* 完整模板的章节头落在深红卡内时改用泥金,保证对比度 */
+.calendar-card.cal-style-redgold :is(.sh-index, .sh-kicker, .sh-title, .sh-note) {
+ color: #f2d9a2;
+}
+.calendar-card.cal-style-redgold .sh-index {
+ opacity: 0.4;
+}
+.calendar-card.cal-style-redgold .sh-rule {
+ background: rgba(231, 197, 132, 0.55);
+}
+/* —— 水墨素卡:宣纸实底 + 墨字楷题 + 朱砂点缀 —— */
+.calendar-card.cal-style-ink {
+ --cal-title: #2e332e;
+ --cal-sub: #6b716b;
+ --cal-kicker: #6b716b;
+ --cal-week: #3a3f3a;
+ --cal-day: #4a504a;
+ --cal-sel-ink: #fdf6f0;
+ --cal-rule: rgba(58, 63, 58, 0.4);
+ --cal-title-rule: rgba(58, 63, 58, 0.6);
+ border: 1px solid rgba(58, 63, 58, 0.45);
+ border-radius: 2px;
+ box-shadow: inset 0 0 0 4px #f9f8f2, inset 0 0 0 5px rgba(58, 63, 58, 0.24), 0 12px 30px rgba(58, 63, 58, 0.1);
+ background: #f9f8f2;
+}
+.calendar-card.cal-style-ink::before {
+ border-color: rgba(58, 63, 58, 0.18);
+}
+/* 版式:文人排版——整体左对齐、大留白、右上角朱砂闲章、底部淡墨横扫 */
+.calendar-card.cal-style-ink {
+ text-align: left;
+ padding: 34px 26px 30px;
+ background:
+ radial-gradient(120% 30% at 50% 108%, rgba(58, 63, 58, 0.07), transparent 70%),
+ #f9f8f2;
+}
+.calendar-card.cal-style-ink::after {
+ content: '囍';
+ position: absolute;
+ top: 24px;
+ right: 24px;
+ width: 26px;
+ height: 26px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 15px;
+ color: #f9f8f2;
+ background: #b5493f;
+ border-radius: 3px;
+ transform: rotate(6deg);
+ font-family: var(--font-kai);
+ box-shadow: 0 2px 6px rgba(120, 40, 34, 0.25);
+ pointer-events: none;
+}
+.calendar-card.cal-style-ink .calendar-title {
+ font-family: var(--font-kai);
+ letter-spacing: 0.18em;
+ justify-content: flex-start;
+ font-size: 34px;
+ margin-top: 14px;
+}
+.calendar-card.cal-style-ink .calendar-title i {
+ display: none;
+}
+.calendar-card.cal-style-ink .calendar-kicker {
+ letter-spacing: 0.5em;
+}
+.calendar-card.cal-style-ink .calendar-date-line {
+ margin-left: 0;
+ margin-bottom: 26px;
+}
+.calendar-card.cal-style-ink .calendar-note {
+ justify-content: flex-start;
+ font-family: var(--font-kai);
+ letter-spacing: 0.3em;
+}
+.calendar-card.cal-style-ink .calendar-note i {
+ order: 2;
+ width: 34px;
+ background: linear-gradient(90deg, rgba(58, 63, 58, 0.4), transparent);
+}
+/* —— 报刊粗格:老报纸黄实底 + 黑白铅字排印 —— */
+.calendar-card.cal-style-paper {
+ --cal-title: #262420;
+ --cal-sub: #56524a;
+ --cal-kicker: #262420;
+ --cal-week: #262420;
+ --cal-day: #33302a;
+ --cal-sel-ink: #262420;
+ --cal-rule: rgba(38, 36, 32, 0.65);
+ --cal-title-rule: rgba(38, 36, 32, 0.8);
+ border-radius: 0;
+ border: 1px solid #262420;
+ border-top: 3px double #262420;
+ border-bottom: 3px double #262420;
+ outline: 1px solid #262420;
+ outline-offset: 4px;
+ box-shadow: none;
+ background:
+ repeating-linear-gradient(0deg, rgba(38, 36, 32, 0.02) 0 1px, transparent 1px 7px),
+ #f7f2df;
+}
+.calendar-card.cal-style-paper::before {
+ display: none;
+}
+.calendar-card.cal-style-paper .calendar-weekdays {
+ border-top: 3px double #262420;
+ border-bottom: 1px solid #262420;
+ padding: 6px 0;
+}
+.calendar-card.cal-style-paper .calendar-day-num,
+.calendar-card.cal-style-paper .calendar-title {
+ font-family: var(--font-serif);
+}
+.calendar-card.cal-style-paper .calendar-title {
+ text-transform: uppercase;
+ letter-spacing: 0.06em;
+ font-weight: 700;
+}
+.calendar-card.cal-style-paper .calendar-kicker {
+ font-family: var(--font-serif);
+ letter-spacing: 0.32em;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 10px;
+}
+.calendar-card.cal-style-paper .calendar-kicker::before,
+.calendar-card.cal-style-paper .calendar-kicker::after {
+ content: '◆';
+ font-size: 7px;
+ letter-spacing: 0;
+ padding: 0;
+ color: #262420;
+}
+/* 版式:报纸表格——日期行框成副题栏,网格改真表格线 */
+.calendar-card.cal-style-paper .calendar-date-line {
+ border-top: 1px solid rgba(38, 36, 32, 0.55);
+ border-bottom: 1px solid rgba(38, 36, 32, 0.55);
+ padding: 5px 0;
+ margin: 12px auto 18px;
+ font-family: var(--font-serif);
+ text-transform: uppercase;
+ letter-spacing: 0.22em;
+}
+.calendar-card.cal-style-paper .calendar-grid {
+ gap: 0;
+ border-left: 1px solid rgba(38, 36, 32, 0.4);
+ border-bottom: 1px solid rgba(38, 36, 32, 0.4);
+}
+.calendar-card.cal-style-paper .calendar-day {
+ border-right: 1px solid rgba(38, 36, 32, 0.4);
+ border-top: 1px solid rgba(38, 36, 32, 0.4);
+ font-size: 13px;
+}
+.calendar-card.cal-style-paper .calendar-day.is-empty {
+ visibility: visible;
+ background:
+ repeating-linear-gradient(45deg, rgba(38, 36, 32, 0.08) 0 1px, transparent 1px 5px);
+}
+.calendar-card.cal-style-paper .calendar-day.is-empty .calendar-day-num {
+ visibility: hidden;
+}
+.calendar-card.cal-style-paper .calendar-weekdays {
+ margin-bottom: 0;
+ border-bottom: none;
+}
+.calendar-card.cal-style-paper .calendar-note {
+ font-family: var(--font-serif);
+ border: 1px solid rgba(38, 36, 32, 0.55);
+ padding: 6px 14px;
+ width: fit-content;
+ margin-left: auto;
+ margin-right: auto;
+ letter-spacing: 0.3em;
+ font-size: 11px;
+}
+.calendar-card.cal-style-paper .calendar-note i {
+ display: none;
+}
+/* —— 复古票根:牛皮纸实底 + 撕票口 + 票号排印 —— */
+.calendar-card.cal-style-ticket {
+ --cal-title: #6e4f26;
+ --cal-sub: #97723d;
+ --cal-kicker: #7a5c30;
+ --cal-week: #8a6a3a;
+ --cal-day: #5c4a2e;
+ --cal-sel-ink: #9c5a30;
+ --cal-rule: rgba(151, 114, 61, 0.5);
+ --cal-title-rule: rgba(151, 114, 61, 0.75);
+ border-radius: 14px;
+ border: 1px solid rgba(151, 114, 61, 0.5);
+ background:
+ repeating-linear-gradient(90deg, rgba(151, 114, 61, 0.03) 0 2px, transparent 2px 9px),
+ #f3e7cf;
+ -webkit-mask:
+ radial-gradient(9px at 0 50%, transparent 98%, #000) 0 0 / 51% 100% no-repeat,
+ radial-gradient(9px at 100% 50%, transparent 98%, #000) 100% 0 / 51% 100% no-repeat;
+ mask:
+ radial-gradient(9px at 0 50%, transparent 98%, #000) 0 0 / 51% 100% no-repeat,
+ radial-gradient(9px at 100% 50%, transparent 98%, #000) 100% 0 / 51% 100% no-repeat;
+}
+.calendar-card.cal-style-ticket::before {
+ border: 1px dashed rgba(151, 114, 61, 0.45);
+}
+.calendar-card.cal-style-ticket .calendar-weekdays {
+ border-top: 1px dashed rgba(151, 114, 61, 0.5);
+ border-bottom: 1px dashed rgba(151, 114, 61, 0.5);
+ padding: 6px 0;
+}
+.calendar-card.cal-style-ticket .calendar-kicker,
+.calendar-card.cal-style-ticket .calendar-title {
+ font-family: var(--font-number);
+}
+/* 版式:票面信息左排 + 票号 + 底部条码 + 微倾 */
+.calendar-card.cal-style-ticket {
+ text-align: left;
+ transform: rotate(-1deg);
+ padding-bottom: 58px;
+}
+.calendar-card.cal-style-ticket .calendar-kicker {
+ letter-spacing: 0.3em;
+ display: flex;
+ align-items: baseline;
+ justify-content: space-between;
+}
+.calendar-card.cal-style-ticket .calendar-kicker::after {
+ content: 'NO. 0520';
+ font-size: 10px;
+ letter-spacing: 0.12em;
+ color: #9c5a30;
+ border: 1px solid rgba(156, 90, 48, 0.5);
+ padding: 1px 6px;
+ border-radius: 2px;
+}
+.calendar-card.cal-style-ticket .calendar-title {
+ justify-content: flex-start;
+ letter-spacing: 0.08em;
+}
+.calendar-card.cal-style-ticket .calendar-title i {
+ display: none;
+}
+.calendar-card.cal-style-ticket .calendar-date-line {
+ margin-left: 0;
+ text-transform: uppercase;
+}
+/* 底部条码 + 尾注右移当"检票口"小字 */
+.calendar-card.cal-style-ticket::after {
+ content: '';
+ position: absolute;
+ left: 24px;
+ bottom: 22px;
+ width: 118px;
+ height: 20px;
+ background: repeating-linear-gradient(90deg, #5c4a2e 0 2px, transparent 2px 4px, #5c4a2e 4px 7px, transparent 7px 9px);
+ opacity: 0.85;
+ pointer-events: none;
+}
+.calendar-card.cal-style-ticket .calendar-note {
+ position: absolute;
+ right: 24px;
+ bottom: 22px;
+ margin: 0;
+ height: 20px;
+ font-size: 10px;
+ letter-spacing: 0.24em;
+ font-family: var(--font-number);
+}
+.calendar-card.cal-style-ticket .calendar-note i {
+ display: none;
+}
+/* —— 像素方格:奶油实底 + 墨色硬框 + 品红像素影 —— */
+.calendar-card.cal-style-pixel {
+ --cal-title: #33261f;
+ --cal-sub: #6b5a4a;
+ --cal-kicker: #c94f7c;
+ --cal-week: #33261f;
+ --cal-day: #4a3a30;
+ --cal-sel-ink: #fff;
+ --cal-rule: rgba(51, 38, 31, 0.5);
+ --cal-title-rule: rgba(51, 38, 31, 0.7);
+ border-radius: 0;
+ border: 3px solid #33261f;
+ box-shadow: 6px 6px 0 rgba(201, 79, 124, 0.75);
+ background: #fdf6e4;
+}
+.calendar-card.cal-style-pixel::before {
+ display: none;
+}
+.calendar-card.cal-style-pixel .calendar-kicker,
+.calendar-card.cal-style-pixel .calendar-title {
+ font-family: var(--font-pixel, monospace);
+}
+.calendar-card.cal-style-pixel .calendar-title {
+ font-size: 22px;
+ letter-spacing: 0.14em;
+ margin-top: 16px;
+}
+/* 版式:游戏窗口——品红标题栏 + 关闭钮 + 方格纸网格 + 闪烁尾注 */
+.calendar-card.cal-style-pixel {
+ padding-top: 54px;
+}
+.calendar-card.cal-style-pixel .calendar-kicker {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ display: flex;
+ align-items: center;
+ padding: 7px 12px;
+ background: #c94f7c;
+ color: #fff;
+ letter-spacing: 0.18em;
+ border-bottom: 3px solid #33261f;
+ text-align: left;
+}
+.calendar-card.cal-style-pixel .calendar-kicker::before {
+ content: '♥ ';
+ font-size: 10px;
+ letter-spacing: 0;
+}
+.calendar-card.cal-style-pixel .calendar-kicker::after {
+ content: '✕';
+ margin-left: auto;
+ width: 16px;
+ height: 16px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 9px;
+ letter-spacing: 0;
+ padding: 0;
+ background: #fdf6e4;
+ color: #33261f;
+ border: 2px solid #33261f;
+ box-shadow: 2px 2px 0 rgba(51, 38, 31, 0.5);
+}
+.calendar-card.cal-style-pixel .calendar-grid {
+ gap: 2px;
+ padding: 6px;
+ border: 2px dashed rgba(51, 38, 31, 0.3);
+}
+.calendar-card.cal-style-pixel .calendar-day {
+ background: rgba(51, 38, 31, 0.04);
+ font-family: var(--font-pixel, monospace);
+ font-size: 12px;
+}
+.calendar-card.cal-style-pixel .calendar-day.is-empty {
+ visibility: visible;
+ background: rgba(51, 38, 31, 0.1);
+}
+.calendar-card.cal-style-pixel .calendar-weekdays {
+ font-family: var(--font-pixel, monospace);
+ font-weight: 400;
+}
+.calendar-card.cal-style-pixel .calendar-note {
+ font-family: var(--font-pixel, monospace);
+ font-size: 11px;
+ letter-spacing: 0.2em;
+ animation: calPixelBlink 1.4s steps(2) infinite;
+}
+.calendar-card.cal-style-pixel .calendar-note::before {
+ content: '▶';
+ font-size: 9px;
+ color: #c94f7c;
+}
+.calendar-card.cal-style-pixel .calendar-note i {
+ display: none;
+}
+@keyframes calPixelBlink {
+ 50% { opacity: 0.35; }
+}
+/* —— 极简数字:纯白实底 + 细字重 + 大留白 —— */
+.calendar-card.cal-style-minimal {
+ --cal-title: #1f1e1b;
+ --cal-sub: #8b8a86;
+ --cal-kicker: #8b8a86;
+ --cal-week: #55534e;
+ --cal-day: #6e6c66;
+ --cal-sel-ink: #1f1e1b;
+ --cal-rule: rgba(31, 30, 27, 0.3);
+ --cal-title-rule: rgba(31, 30, 27, 0.4);
+ border: 1px solid #ececea;
+ box-shadow: 0 14px 40px rgba(31, 30, 27, 0.06);
+ background: #fefefd;
+ padding: 38px 26px 34px;
+}
+.calendar-card.cal-style-minimal::before {
+ display: none;
+}
+/* 版式:非对称极简——左对齐超大细字标题、宽松网格、右对齐小尾注 */
+.calendar-card.cal-style-minimal {
+ text-align: left;
+ padding: 44px 30px 36px;
+}
+.calendar-card.cal-style-minimal .calendar-title {
+ font-size: 46px;
+ letter-spacing: 0.06em;
+ font-weight: 200;
+ justify-content: flex-start;
+ margin-top: 18px;
+}
+.calendar-card.cal-style-minimal .calendar-title i {
+ display: none;
+}
+.calendar-card.cal-style-minimal .calendar-kicker {
+ letter-spacing: 0.56em;
+}
+.calendar-card.cal-style-minimal .calendar-date-line {
+ margin: 6px 0 30px;
+ font-size: 10px;
+ letter-spacing: 0.3em;
+}
+.calendar-card.cal-style-minimal .calendar-weekdays {
+ border: none;
+ font-family: var(--font-sans, sans-serif);
+ font-weight: 400;
+ letter-spacing: 0.1em;
+}
+.calendar-card.cal-style-minimal .calendar-weekdays,
+.calendar-card.cal-style-minimal .calendar-grid {
+ gap: 12px 6px;
+}
+.calendar-card.cal-style-minimal .calendar-day {
+ font-size: 13px;
+}
+.calendar-card.cal-style-minimal .calendar-note {
+ justify-content: flex-end;
+ font-family: var(--font-sans, sans-serif);
+ font-weight: 400;
+ font-size: 10px;
+ letter-spacing: 0.34em;
+ margin-top: 30px;
+}
+.calendar-card.cal-style-minimal .calendar-note i {
+ order: -1;
+ width: 30px;
+ background: rgba(31, 30, 27, 0.25);
+}
+/* ———— 婚期选中标记:随日历模板换形态(classic 保留笔刷红心) ———— */
+.calendar-card[class*='cal-style-']:not(.cal-style-classic) .heart-ring {
+ display: none;
+}
+.calendar-card[class*='cal-style-']:not(.cal-style-classic) .calendar-day.is-selected .calendar-day-num {
+ background: transparent;
+ box-shadow: none;
+ text-shadow: none;
+}
+.calendar-card[class*='cal-style-'] .calendar-day.is-selected::after {
+ content: '';
+ position: absolute;
+ z-index: 1;
+ pointer-events: none;
+}
+/* 红金:泥金圆章 + 深红喜字(深红底上以金为记) */
+.cal-style-redgold .calendar-day.is-selected .calendar-day-num {
+ color: #86222e;
+}
+.cal-style-redgold .calendar-day.is-selected::after {
+ inset: -4px;
+ border-radius: 50%;
+ background: radial-gradient(circle at 38% 30%, #f2d9a2, #d8ab5e 68%);
+ box-shadow: 0 0 0 2px rgba(122, 26, 37, 0.55), 0 4px 12px rgba(30, 4, 8, 0.4);
+ z-index: 0;
+ animation: calPulse 2s ease-in-out infinite;
+}
+/* 水墨:朱砂印章(方章 + 微旋) */
+.cal-style-ink .calendar-day.is-selected .calendar-day-num {
+ color: #fdf6f0;
+}
+.cal-style-ink .calendar-day.is-selected::after {
+ inset: -3px;
+ border-radius: 4px;
+ background: #b5493f;
+ box-shadow: inset 0 0 0 1.5px rgba(253, 246, 240, 0.35), 0 3px 8px rgba(120, 40, 34, 0.3);
+ transform: rotate(-4deg);
+ z-index: 0;
+}
+/* 报刊:粗黑双线方框圈注 */
+.cal-style-paper .calendar-day.is-selected .calendar-day-num {
+ font-weight: 800;
+}
+.cal-style-paper .calendar-day.is-selected::after {
+ inset: -2px;
+ border: 2px solid #262420;
+ outline: 1px solid #262420;
+ outline-offset: 2px;
+}
+/* 票根:虚线检票圆章 */
+.cal-style-ticket .calendar-day.is-selected .calendar-day-num {
+ color: #9c5a30;
+ font-weight: 800;
+}
+.cal-style-ticket .calendar-day.is-selected::after {
+ inset: -6px;
+ border-radius: 50%;
+ border: 2px dashed #9c5a30;
+ transform: rotate(-8deg);
+ animation: calStampSpin 14s linear infinite;
+}
+@keyframes calStampSpin {
+ to { transform: rotate(352deg); }
+}
+/* 像素:像素心点阵 */
+.cal-style-pixel .calendar-day.is-selected {
+ outline: none !important;
+}
+.cal-style-pixel .calendar-day.is-selected .calendar-day-num {
+ color: #fff;
+ z-index: 4;
+}
+.cal-style-pixel .calendar-day.is-selected::after {
+ width: 6px;
+ height: 6px;
+ left: 50%;
+ top: 50%;
+ margin: -12px 0 0 -15px;
+ background: transparent;
+ box-shadow:
+ 6px 0 #c94f7c, 18px 0 #c94f7c,
+ 0 6px #c94f7c, 6px 6px #c94f7c, 12px 6px #c94f7c, 18px 6px #c94f7c, 24px 6px #c94f7c,
+ 6px 12px #c94f7c, 12px 12px #c94f7c, 18px 12px #c94f7c,
+ 12px 18px #c94f7c;
+ animation: calPulse 1.6s steps(2) infinite;
+}
+/* 极简:细线正圆 */
+.cal-style-minimal .calendar-day.is-selected .calendar-day-num {
+ font-weight: 700;
+ color: #1f1e1b;
+}
+.cal-style-minimal .calendar-day.is-selected::after {
+ inset: -5px;
+ border-radius: 50%;
+ border: 1.5px solid #1f1e1b;
+}
+/* 手账:手绘涂鸦圈(不规则圆角 + 双层) */
+.cal-style-journal .calendar-day.is-selected .calendar-day-num {
+ color: #b5493f;
+ font-weight: 800;
+}
+.cal-style-journal .calendar-day.is-selected::after {
+ inset: -6px -8px -4px -6px;
+ border: 2.5px solid rgba(181, 73, 63, 0.85);
+ border-radius: 58% 42% 55% 45% / 48% 55% 45% 52%;
+ transform: rotate(-5deg);
+}
+@keyframes calPulse {
+ 0%, 100% { opacity: 1; }
+ 50% { opacity: 0.72; }
+}
+
+/* —— 手账贴纸:奶油实底 + 红棕虚线框 + 顶部和纸胶带 —— */
+.calendar-card.cal-style-journal {
+ --cal-title: #8a5a3a;
+ --cal-sub: #a3805e;
+ --cal-kicker: #b5493f;
+ --cal-week: #9a7a55;
+ --cal-day: #6e553c;
+ --cal-sel-ink: #b5493f;
+ --cal-rule: rgba(181, 73, 63, 0.4);
+ --cal-title-rule: rgba(163, 128, 94, 0.6);
+ position: relative;
+ border: 1.5px dashed #c99a6e;
+ border-radius: 8px;
+ background:
+ repeating-linear-gradient(0deg, rgba(163, 128, 94, 0.035) 0 1px, transparent 1px 9px),
+ #fffdf6;
+ box-shadow: 0 10px 26px rgba(69, 58, 48, 0.14);
+ transform: rotate(-0.6deg);
+}
+.calendar-card.cal-style-journal::before {
+ content: '';
+ position: absolute;
+ inset: auto;
+ border: none;
+ top: -12px;
+ left: 50%;
+ width: 84px;
+ height: 24px;
+ transform: translateX(-50%) rotate(-3deg);
+ background: rgba(196, 122, 90, 0.45);
+ box-shadow: 0 1px 4px rgba(69, 58, 48, 0.15);
+ pointer-events: none;
+}
+.calendar-card.cal-style-journal .calendar-kicker,
+.calendar-card.cal-style-journal .calendar-title {
+ font-family: var(--font-liujian);
+}
+.calendar-card.cal-style-journal .calendar-kicker {
+ text-transform: none;
+ letter-spacing: 0.16em;
+}
+.calendar-card.cal-style-journal .calendar-title {
+ letter-spacing: 0.1em;
+}
+/* 版式:拼贴手帐——斜置标题、右上彩色圆点贴纸、手绘虚线框尾注 */
+.calendar-card.cal-style-journal .calendar-title {
+ transform: rotate(-1.6deg);
+ font-size: 32px;
+}
+.calendar-card.cal-style-journal .calendar-title i {
+ width: 22px;
+ height: 3px;
+ border-radius: 3px;
+ background: rgba(181, 73, 63, 0.4);
+}
+.calendar-card.cal-style-journal::after {
+ content: '';
+ position: absolute;
+ top: 20px;
+ right: 26px;
+ width: 9px;
+ height: 9px;
+ border-radius: 50%;
+ background: rgba(181, 73, 63, 0.75);
+ box-shadow:
+ 14px 5px 0 rgba(151, 148, 72, 0.7),
+ 5px 16px 0 rgba(94, 129, 173, 0.65);
+ pointer-events: none;
+}
+.calendar-card.cal-style-journal .calendar-date-line {
+ font-family: var(--font-liujian);
+ font-size: 13px;
+ letter-spacing: 0.1em;
+}
+.calendar-card.cal-style-journal .calendar-weekdays {
+ font-family: var(--font-liujian);
+ font-size: 12px;
+ font-weight: 400;
+}
+.calendar-card.cal-style-journal .calendar-note {
+ font-family: var(--font-liujian);
+ border: 1.5px dashed rgba(181, 73, 63, 0.5);
+ border-radius: 10px 14px 12px 16px;
+ width: fit-content;
+ margin-left: auto;
+ margin-right: auto;
+ padding: 5px 16px;
+ transform: rotate(0.8deg);
+ font-size: 14px;
+ font-weight: 400;
+ letter-spacing: 0.14em;
+}
+.calendar-card.cal-style-journal .calendar-note i {
+ display: none;
+}
+
+/* —— 法式蕾丝:奶油粉双线蕾丝衬 + 花体 + 满格粉心婚期 —— */
+.calendar-card.cal-style-french {
+ --cal-title: #a05468;
+ --cal-sub: #b98a95;
+ --cal-kicker: #c78a96;
+ --cal-week: #c78a96;
+ --cal-day: #8a626d;
+ --cal-rule: rgba(199, 138, 150, 0.5);
+ --cal-title-rule: rgba(199, 138, 150, 0.7);
+ border: none;
+ border-radius: 18px;
+ background:
+ radial-gradient(90% 50% at 50% 0%, rgba(255, 255, 255, 0.7), transparent 60%),
+ linear-gradient(170deg, #fdf3f5, #fbe8ee);
+ box-shadow:
+ 0 18px 44px rgba(199, 138, 150, 0.26),
+ inset 0 0 0 1px rgba(199, 138, 150, 0.35),
+ inset 0 0 0 7px rgba(253, 243, 245, 0.9),
+ inset 0 0 0 8px rgba(199, 138, 150, 0.4);
+}
+.calendar-card.cal-style-french::before {
+ inset: 14px;
+ border: 1px dashed rgba(199, 138, 150, 0.4);
+ border-radius: 12px;
+}
+.calendar-card.cal-style-french::after {
+ content: '❦';
+ position: absolute;
+ top: 18px;
+ left: 50%;
+ transform: translateX(-50%);
+ font-size: 15px;
+ color: rgba(199, 138, 150, 0.75);
+ pointer-events: none;
+}
+.calendar-card.cal-style-french .calendar-title {
+ font-family: var(--font-display);
+ font-style: italic;
+ font-size: 32px;
+}
+.calendar-card.cal-style-french .calendar-kicker {
+ font-style: italic;
+ letter-spacing: 0.4em;
+}
+.calendar-card.cal-style-french .calendar-note {
+ font-family: var(--font-display);
+ font-style: italic;
+ letter-spacing: 0.22em;
+}
+.calendar-card.cal-style-french .calendar-day.is-selected .calendar-day-num {
+ color: #fff;
+ font-size: 13px;
+}
+.calendar-card.cal-style-french .calendar-day.is-selected::after {
+ content: '♥';
+ inset: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 30px;
+ line-height: 1;
+ color: #e08aa0;
+ z-index: 0;
+ filter: drop-shadow(0 3px 6px rgba(199, 106, 130, 0.45));
+ animation: calHeartBeat 1.8s ease-in-out infinite;
+}
+@keyframes calHeartBeat {
+ 0%, 100% { transform: scale(1); }
+ 14% { transform: scale(1.14); }
+ 28% { transform: scale(1); }
+ 42% { transform: scale(1.1); }
+}
+
+/* —— 瑞士网格:方格纸底 + 900 黑体巨题 + 信号红块 —— */
+.calendar-card.cal-style-mono {
+ --cal-title: #111;
+ --cal-sub: #555;
+ --cal-kicker: #fff;
+ --cal-week: #111;
+ --cal-day: #333;
+ --cal-rule: #111;
+ --cal-title-rule: #111;
+ text-align: left;
+ border: none;
+ border-radius: 0;
+ background:
+ linear-gradient(rgba(17, 17, 17, 0.05) 1px, transparent 1px),
+ linear-gradient(90deg, rgba(17, 17, 17, 0.05) 1px, transparent 1px),
+ #fff;
+ background-size: 22px 22px, 22px 22px, auto;
+ box-shadow: 0 16px 40px rgba(0, 0, 0, 0.1);
+}
+.calendar-card.cal-style-mono::before {
+ display: none;
+}
+.calendar-card.cal-style-mono .calendar-kicker {
+ display: inline-block;
+ background: #e63329;
+ padding: 4px 12px;
+ letter-spacing: 0.3em;
+ font-weight: 700;
+ font-family: var(--font-sans, sans-serif);
+}
+.calendar-card.cal-style-mono .calendar-title {
+ justify-content: flex-start;
+ font-family: var(--font-sans, sans-serif);
+ font-weight: 900;
+ font-size: 42px;
+ letter-spacing: -0.01em;
+ text-transform: uppercase;
+ margin-top: 16px;
+}
+.calendar-card.cal-style-mono .calendar-title i {
+ display: none;
+}
+.calendar-card.cal-style-mono .calendar-date-line {
+ margin: 8px 0 24px;
+ font-family: var(--font-sans, sans-serif);
+ text-transform: uppercase;
+ letter-spacing: 0.24em;
+ border-bottom: 2px solid #111;
+ padding-bottom: 10px;
+}
+.calendar-card.cal-style-mono .calendar-weekdays {
+ font-family: var(--font-sans, sans-serif);
+ font-weight: 700;
+}
+.calendar-card.cal-style-mono .calendar-day {
+ font-family: var(--font-sans, sans-serif);
+}
+.calendar-card.cal-style-mono .calendar-note {
+ justify-content: flex-start;
+ font-family: var(--font-sans, sans-serif);
+ font-weight: 800;
+ letter-spacing: 0.3em;
+ color: #111;
+}
+.calendar-card.cal-style-mono .calendar-note i {
+ order: -1;
+ width: 10px;
+ height: 10px;
+ background: #e63329;
+}
+.calendar-card.cal-style-mono .calendar-day.is-selected .calendar-day-num {
+ color: #fff;
+}
+.calendar-card.cal-style-mono .calendar-day.is-selected::after {
+ inset: -3px;
+ background: #e63329;
+ z-index: 0;
+}
+
+/* —— 野餐格纹:绿白格布 + 白餐纸 + 樱桃婚期 —— */
+.calendar-card.cal-style-picnic {
+ --cal-title: #3e5a42;
+ --cal-sub: #7a8a72;
+ --cal-kicker: #5f8a5a;
+ --cal-week: #4c6b50;
+ --cal-day: #445c48;
+ --cal-sel-ink: #fff;
+ --cal-rule: rgba(95, 138, 90, 0.5);
+ --cal-title-rule: rgba(95, 138, 90, 0.6);
+ border: 1px solid rgba(95, 138, 90, 0.35);
+ border-radius: 10px;
+ background:
+ linear-gradient(#fffefb, #fffefb) 50% 50% / calc(100% - 30px) calc(100% - 30px) no-repeat,
+ repeating-linear-gradient(0deg, rgba(95, 138, 90, 0.2) 0 10px, transparent 10px 20px),
+ repeating-linear-gradient(90deg, rgba(95, 138, 90, 0.2) 0 10px, transparent 10px 20px),
+ #f6faf3;
+ box-shadow: 0 14px 34px rgba(78, 112, 87, 0.16);
+}
+.calendar-card.cal-style-picnic::before {
+ display: none;
+}
+.calendar-card.cal-style-picnic .calendar-title {
+ font-family: var(--font-display);
+ font-style: italic;
+}
+.calendar-card.cal-style-picnic .calendar-kicker {
+ letter-spacing: 0.42em;
+}
+.calendar-card.cal-style-picnic .calendar-day.is-selected::after {
+ inset: -4px;
+ border-radius: 50%;
+ background: radial-gradient(circle at 34% 28%, #e46856, #c23c2c 72%);
+ box-shadow: inset 0 -2px 4px rgba(120, 24, 16, 0.35), 0 3px 8px rgba(120, 24, 16, 0.3);
+ z-index: 0;
+}
+
+/* —— 玻璃温室:尖顶花房剪影 + 玻璃格线 —— */
+.calendar-card.cal-style-greenhouse {
+ --cal-title: #3c5a48;
+ --cal-sub: #74907e;
+ --cal-kicker: #5e8a78;
+ --cal-week: #4c7060;
+ --cal-day: #446052;
+ --cal-rule: rgba(94, 138, 120, 0.5);
+ --cal-title-rule: rgba(94, 138, 120, 0.65);
+ border: none;
+ border-radius: 0;
+ /* 尖顶用固定像素:斜边不随卡片高度变化,避免切到顶部日期内容 */
+ clip-path: polygon(50% 0, 100% 76px, 100% 100%, 0 100%, 0 76px);
+ padding-top: 102px;
+ background:
+ linear-gradient(rgba(94, 138, 120, 0.45), rgba(94, 138, 120, 0.45)) 50% 76px / 100% 1px no-repeat,
+ repeating-linear-gradient(90deg, rgba(94, 138, 120, 0.14) 0 1px, transparent 1px 38px),
+ repeating-linear-gradient(0deg, rgba(94, 138, 120, 0.14) 0 1px, transparent 1px 44px),
+ radial-gradient(120% 130px at 50% 0%, rgba(255, 255, 255, 0.85), transparent 80%),
+ linear-gradient(176deg, #f2faf6 0%, #e2f0e8 100%);
+ box-shadow: none;
+ filter: drop-shadow(0 16px 28px rgba(70, 100, 86, 0.24));
+}
+.calendar-card.cal-style-greenhouse::before {
+ display: none;
+}
+/* 顶尖风向钮 */
+.calendar-card.cal-style-greenhouse::after {
+ content: '';
+ position: absolute;
+ top: 7px;
+ left: 50%;
+ width: 2px;
+ height: 14px;
+ margin-left: -1px;
+ background: rgba(94, 138, 120, 0.6);
+ border-radius: 2px;
+ box-shadow: 0 -3px 0 1.5px rgba(94, 138, 120, 0.75);
+ pointer-events: none;
+}
+.calendar-card.cal-style-greenhouse .calendar-title {
+ font-family: var(--font-display);
+ font-style: italic;
+}
+.calendar-card.cal-style-greenhouse .calendar-day.is-selected .calendar-day-num {
+ color: #2e4438;
+}
+.calendar-card.cal-style-greenhouse .calendar-day.is-selected::after {
+ inset: -4px;
+ border-radius: 50%;
+ background: radial-gradient(circle at 34% 28%, rgba(255, 255, 255, 0.75), rgba(148, 196, 172, 0.6) 62%);
+ box-shadow: 0 0 0 1.5px rgba(94, 138, 120, 0.6), inset 0 -2px 5px rgba(94, 138, 120, 0.3);
+ z-index: 0;
+}
+
+/* —— 植物标本:压花蕨叶 + 和纸胶带 + 红圈标注 —— */
+.calendar-card.cal-style-herbarium {
+ --cal-title: #3c4a3a;
+ --cal-sub: #84907c;
+ --cal-kicker: #84907c;
+ --cal-week: #54644e;
+ --cal-day: #485844;
+ --cal-rule: rgba(84, 100, 78, 0.4);
+ --cal-title-rule: rgba(84, 100, 78, 0.55);
+ border: 1px solid #d8d2c0;
+ border-radius: 3px;
+ background:
+ url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 70 90'%3E%3Cg fill='none' stroke='%238aa07c' stroke-width='1.2' stroke-linecap='round' opacity='.55'%3E%3Cpath d='M35 88C33 60 34 34 38 6'/%3E%3Cpath d='M36 72C26 68 20 60 20 50M36 74c10-4 16-12 16-22M35 56c-8-3-13-9-13-17M36 58c8-4 12-10 12-18M36 40c-7-2-11-7-11-14M37 42c7-3 10-8 10-15M37 24c-5-2-8-6-8-11M38 26c5-3 8-7 8-12'/%3E%3C/g%3E%3C/svg%3E") calc(100% - 14px) 16px / 58px 76px no-repeat,
+ url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 70 90'%3E%3Cg transform='translate(70 90) rotate(180)'%3E%3Cg fill='none' stroke='%238aa07c' stroke-width='1.2' stroke-linecap='round' opacity='.45'%3E%3Cpath d='M35 88C33 60 34 34 38 6'/%3E%3Cpath d='M36 72C26 68 20 60 20 50M36 74c10-4 16-12 16-22M35 56c-8-3-13-9-13-17M36 58c8-4 12-10 12-18M36 40c-7-2-11-7-11-14M37 42c7-3 10-8 10-15M37 24c-5-2-8-6-8-11M38 26c5-3 8-7 8-12'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E") 12px calc(100% - 12px) / 50px 66px no-repeat,
+ repeating-linear-gradient(0deg, rgba(84, 100, 78, 0.02) 0 1px, transparent 1px 9px),
+ #fbf9f1;
+ box-shadow: 0 12px 30px rgba(84, 100, 78, 0.14);
+}
+/* 左上 / 右下和纸胶带 */
+.calendar-card.cal-style-herbarium::before {
+ content: '';
+ inset: auto;
+ border: none;
+ top: -7px;
+ left: 22px;
+ width: 58px;
+ height: 17px;
+ background: rgba(168, 186, 152, 0.5);
+ transform: rotate(-42deg);
+ transform-origin: left center;
+ pointer-events: none;
+}
+.calendar-card.cal-style-herbarium::after {
+ content: '';
+ position: absolute;
+ bottom: -7px;
+ right: 22px;
+ width: 58px;
+ height: 17px;
+ background: rgba(196, 176, 144, 0.42);
+ transform: rotate(-42deg);
+ transform-origin: right center;
+ pointer-events: none;
+}
+.calendar-card.cal-style-herbarium .calendar-title {
+ font-family: var(--font-serif);
+ font-style: italic;
+ letter-spacing: 0.1em;
+}
+.calendar-card.cal-style-herbarium .calendar-kicker {
+ letter-spacing: 0.5em;
+}
+.calendar-card.cal-style-herbarium .calendar-note {
+ border: 1px solid rgba(84, 100, 78, 0.4);
+ width: fit-content;
+ margin-left: auto;
+ margin-right: auto;
+ padding: 5px 16px;
+ font-family: var(--font-serif);
+ font-style: italic;
+ font-size: 11px;
+ letter-spacing: 0.24em;
+}
+.calendar-card.cal-style-herbarium .calendar-note i {
+ display: none;
+}
+.calendar-card.cal-style-herbarium .calendar-day.is-selected .calendar-day-num {
+ color: #b5493f;
+ font-weight: 800;
+}
+.calendar-card.cal-style-herbarium .calendar-day.is-selected::after {
+ inset: -5px;
+ border-radius: 50%;
+ border: 1.5px solid rgba(181, 73, 63, 0.85);
+ box-shadow: 0 0 0 3.5px rgba(181, 73, 63, 0.16);
+ transform: rotate(-4deg);
+}
+
+/* —— 林间满月:夜空满月题字 + 桂枝剪影 + 金月婚期 —— */
+.calendar-card.cal-style-fullmoon {
+ --cal-title: #2e3c30;
+ --cal-sub: #9db4a4;
+ --cal-kicker: #d9cba0;
+ --cal-week: #c9d8c2;
+ --cal-day: #b8c9b4;
+ --cal-rule: rgba(217, 203, 160, 0.4);
+ --cal-title-rule: rgba(217, 203, 160, 0.55);
+ border: 1px solid rgba(214, 226, 208, 0.25);
+ border-radius: 14px;
+ padding-top: 158px;
+ background:
+ radial-gradient(4px 4px at 18% 34%, rgba(255, 255, 255, 0.8) 40%, transparent 70%),
+ radial-gradient(3px 3px at 82% 22%, rgba(255, 255, 255, 0.6) 40%, transparent 70%),
+ radial-gradient(3px 3px at 72% 46%, rgba(255, 255, 255, 0.45) 40%, transparent 70%),
+ radial-gradient(3px 3px at 12% 14%, rgba(255, 255, 255, 0.5) 40%, transparent 70%),
+ radial-gradient(116px 116px at 50% 88px, #f3ecd4 49%, rgba(243, 236, 212, 0.4) 55%, transparent 63%),
+ radial-gradient(230px 230px at 50% 88px, rgba(243, 236, 212, 0.16), transparent 68%),
+ linear-gradient(178deg, #26342e 0%, #1a2622 58%, #131c18 100%);
+ box-shadow: 0 20px 46px rgba(8, 14, 11, 0.5);
+}
+.calendar-card.cal-style-fullmoon::before {
+ content: '';
+ inset: auto;
+ border: none;
+ top: 96px;
+ left: 50%;
+ width: 150px;
+ height: 44px;
+ transform: translateX(-50%);
+ background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 150 44'%3E%3Cg fill='none' stroke='%232a362e' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M2 34C36 26 70 20 148 24'/%3E%3Cpath d='M46 28c-4-8-10-12-18-12'/%3E%3Cpath d='M92 23c2-8 8-13 16-14'/%3E%3C/g%3E%3Cg fill='%232a362e'%3E%3Cellipse cx='36' cy='22' rx='7' ry='2.8' transform='rotate(-30 36 22)'/%3E%3Cellipse cx='62' cy='24' rx='7' ry='2.8' transform='rotate(14 62 24)'/%3E%3Cellipse cx='104' cy='14' rx='7' ry='2.8' transform='rotate(-24 104 14)'/%3E%3Cellipse cx='124' cy='20' rx='6' ry='2.5' transform='rotate(10 124 20)'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat;
+ opacity: 0.85;
+ pointer-events: none;
+}
+/* 年月题在满月之中 */
+.calendar-card.cal-style-fullmoon .calendar-title {
+ position: absolute;
+ top: 62px;
+ left: 50%;
+ transform: translateX(-50%);
+ margin: 0;
+ font-family: var(--font-kai);
+ font-size: 21px;
+ letter-spacing: 0.16em;
+ white-space: nowrap;
+}
+.calendar-card.cal-style-fullmoon .calendar-title i {
+ display: none;
+}
+.calendar-card.cal-style-fullmoon .calendar-kicker {
+ position: absolute;
+ top: 22px;
+ left: 0;
+ right: 0;
+ letter-spacing: 0.5em;
+}
+.calendar-card.cal-style-fullmoon .calendar-note {
+ font-family: var(--font-kai);
+ letter-spacing: 0.3em;
+}
+.calendar-card.cal-style-fullmoon .calendar-day.is-selected .calendar-day-num {
+ color: #2a362e;
+}
+.calendar-card.cal-style-fullmoon .calendar-day.is-selected::after {
+ inset: -4px;
+ border-radius: 50%;
+ background: radial-gradient(circle at 38% 32%, #f5e8c0, #d9c288 70%);
+ box-shadow: 0 0 12px rgba(243, 236, 212, 0.55);
+ z-index: 0;
+ animation: calPulse 2.2s ease-in-out infinite;
+}
+
+/* —— 花园吊牌:木纹牌 + 麻绳双孔 + 白漆手写 —— */
+.calendar-card.cal-style-gardensign {
+ --cal-title: #fdf9ee;
+ --cal-sub: #e2d4b8;
+ --cal-kicker: #f0e4c8;
+ --cal-week: #ecdfc0;
+ --cal-day: #e6d8ba;
+ --cal-rule: rgba(253, 249, 238, 0.4);
+ --cal-title-rule: rgba(253, 249, 238, 0.5);
+ border: 2.5px solid rgba(253, 249, 238, 0.45);
+ border-radius: 12px;
+ padding-top: 64px;
+ background:
+ repeating-linear-gradient(0deg, rgba(50, 34, 20, 0.14) 0 1.5px, transparent 1.5px 16px),
+ repeating-linear-gradient(0deg, transparent 0 44px, rgba(255, 240, 214, 0.05) 44px 46px),
+ linear-gradient(174deg, #8a6844 0%, #6e5236 55%, #5a442c 100%);
+ box-shadow: 0 18px 40px rgba(48, 34, 18, 0.4), inset 0 0 0 1px rgba(30, 20, 10, 0.25);
+}
+.calendar-card.cal-style-gardensign::before {
+ content: '';
+ inset: auto;
+ border: none;
+ top: 0;
+ left: 50%;
+ width: 200px;
+ height: 60px;
+ transform: translateX(-50%);
+ background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 60'%3E%3Cg fill='none' stroke='%23d9c49c' stroke-width='3' stroke-dasharray='4 2.6' stroke-linecap='round'%3E%3Cpath d='M62 38 100 2'/%3E%3Cpath d='M138 38 100 2'/%3E%3C/g%3E%3Cg fill='%23241708'%3E%3Ccircle cx='62' cy='40' r='5'/%3E%3Ccircle cx='138' cy='40' r='5'/%3E%3C/g%3E%3Cg fill='none' stroke='%23f0e4c8' stroke-width='1.4' opacity='.7'%3E%3Ccircle cx='62' cy='40' r='6.5'/%3E%3Ccircle cx='138' cy='40' r='6.5'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat;
+ pointer-events: none;
+}
+.calendar-card.cal-style-gardensign .calendar-title,
+.calendar-card.cal-style-gardensign .calendar-kicker,
+.calendar-card.cal-style-gardensign .calendar-note {
+ font-family: var(--font-liujian);
+}
+.calendar-card.cal-style-gardensign .calendar-title {
+ font-size: 32px;
+ letter-spacing: 0.12em;
+}
+.calendar-card.cal-style-gardensign .calendar-kicker {
+ text-transform: none;
+ letter-spacing: 0.2em;
+ font-size: 12px;
+}
+.calendar-card.cal-style-gardensign .calendar-day.is-selected .calendar-day-num {
+ color: #fdf9ee;
+ font-weight: 800;
+}
+.calendar-card.cal-style-gardensign .calendar-day.is-selected::after {
+ inset: -5px;
+ border-radius: 52% 48% 55% 45% / 46% 56% 44% 54%;
+ border: 2px solid rgba(253, 249, 238, 0.85);
+ transform: rotate(-5deg);
+}
+
+/* —— 星夜弯月:闪烁双层星空 + 金月牙 + 金星婚期 —— */
+.calendar-card.cal-style-starry {
+ --cal-title: #e8c987;
+ --cal-sub: #9aa4c8;
+ --cal-kicker: #c8b088;
+ --cal-week: #d9c294;
+ --cal-day: #b9c2de;
+ --cal-rule: rgba(232, 201, 135, 0.4);
+ --cal-title-rule: rgba(232, 201, 135, 0.7);
+ border: 1px solid rgba(232, 201, 135, 0.35);
+ background:
+ radial-gradient(140% 70% at 50% -10%, #2c3560, transparent 62%),
+ linear-gradient(172deg, #1d2440 0%, #151b32 58%, #10152a 100%);
+ box-shadow: 0 20px 50px rgba(6, 10, 26, 0.55), inset 0 0 0 1px rgba(232, 201, 135, 0.1);
+}
+.calendar-card.cal-style-starry::before {
+ content: '';
+ inset: auto;
+ border: none;
+ top: 0;
+ left: 0;
+ width: 2px;
+ height: 2px;
+ border-radius: 50%;
+ background: transparent;
+ box-shadow:
+ 36px 44px 0 rgba(255, 255, 255, 0.9), 92px 26px 0 rgba(255, 255, 255, 0.5),
+ 150px 58px 0 rgba(255, 255, 255, 0.85), 210px 30px 0 rgba(255, 255, 255, 0.55),
+ 268px 70px 0 rgba(255, 255, 255, 0.9), 318px 40px 0 rgba(255, 255, 255, 0.5),
+ 64px 120px 0 rgba(255, 255, 255, 0.45), 300px 130px 0 rgba(255, 255, 255, 0.6),
+ 28px 96px 0 rgba(232, 201, 135, 0.8), 250px 100px 0 rgba(232, 201, 135, 0.7),
+ 120px 88px 0 rgba(255, 255, 255, 0.35), 190px 112px 0 rgba(255, 255, 255, 0.5);
+ animation: calStarTwinkle 2.6s ease-in-out infinite;
+ pointer-events: none;
+}
+.calendar-card.cal-style-starry::after {
+ content: '';
+ position: absolute;
+ top: 22px;
+ right: 26px;
+ width: 26px;
+ height: 26px;
+ border-radius: 50%;
+ box-shadow: inset -7px 4px 0 0 #e8c987;
+ transform: rotate(-14deg);
+ filter: drop-shadow(0 0 8px rgba(232, 201, 135, 0.5));
+ pointer-events: none;
+}
+@keyframes calStarTwinkle {
+ 0%, 100% { opacity: 1; }
+ 50% { opacity: 0.45; }
+}
+.calendar-card.cal-style-starry .calendar-title {
+ font-family: var(--font-display);
+}
+.calendar-card.cal-style-starry .calendar-day.is-selected .calendar-day-num {
+ color: #10152a;
+ font-size: 12px;
+}
+.calendar-card.cal-style-starry .calendar-day.is-selected::after {
+ content: '★';
+ inset: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 32px;
+ line-height: 1;
+ color: #e8c987;
+ z-index: 0;
+ filter: drop-shadow(0 0 9px rgba(232, 201, 135, 0.8));
+ animation: calStarTwinkle 2s ease-in-out infinite;
+}
+
+/* —— 水彩晕染:不规则纸边 + 四色晕斑 + 水痕婚期 —— */
+.calendar-card.cal-style-aquarelle {
+ --cal-title: #4e6a80;
+ --cal-sub: #8296a8;
+ --cal-kicker: #7f9bb3;
+ --cal-week: #7f9bb3;
+ --cal-day: #56636e;
+ --cal-rule: rgba(127, 155, 179, 0.5);
+ --cal-title-rule: rgba(127, 155, 179, 0.7);
+ border: none;
+ border-radius: 8px 24px 12px 28px / 22px 10px 26px 12px;
+ background:
+ radial-gradient(48% 34% at 16% 10%, rgba(127, 155, 179, 0.32), transparent 70%),
+ radial-gradient(42% 30% at 88% 22%, rgba(217, 138, 158, 0.28), transparent 70%),
+ radial-gradient(50% 36% at 72% 94%, rgba(222, 196, 132, 0.32), transparent 70%),
+ radial-gradient(36% 28% at 10% 88%, rgba(139, 186, 168, 0.3), transparent 70%),
+ #fdfefe;
+ box-shadow: 0 16px 40px rgba(110, 130, 150, 0.18);
+}
+.calendar-card.cal-style-aquarelle::before {
+ display: none;
+}
+.calendar-card.cal-style-aquarelle .calendar-title {
+ font-family: var(--font-display);
+ font-style: italic;
+}
+.calendar-card.cal-style-aquarelle .calendar-kicker {
+ letter-spacing: 0.5em;
+}
+.calendar-card.cal-style-aquarelle .calendar-day.is-selected .calendar-day-num {
+ color: #fff;
+}
+.calendar-card.cal-style-aquarelle .calendar-day.is-selected::after {
+ inset: -5px;
+ border-radius: 55% 45% 60% 40% / 50% 62% 42% 58%;
+ background: radial-gradient(circle at 38% 32%, rgba(127, 155, 179, 0.92), rgba(150, 122, 190, 0.6) 62%, rgba(127, 155, 179, 0.15) 88%);
+ z-index: 0;
+}
+
+/* —— 樱吹雪:卡内花瓣飘落 + 樱花婚期 —— */
+.calendar-card.cal-style-hanami {
+ --cal-title: #b0566e;
+ --cal-sub: #c4899a;
+ --cal-kicker: #d98a9e;
+ --cal-week: #c9758c;
+ --cal-day: #8f5f6c;
+ --cal-rule: rgba(217, 138, 158, 0.5);
+ --cal-title-rule: rgba(217, 138, 158, 0.7);
+ border-radius: 22px;
+ border: 1px solid rgba(217, 138, 158, 0.4);
+ background:
+ radial-gradient(100% 50% at 50% 0%, rgba(255, 255, 255, 0.65), transparent 58%),
+ linear-gradient(170deg, #fdf4f7, #fae7ee 58%, #f7dde7);
+ box-shadow: 0 18px 44px rgba(196, 116, 140, 0.22), inset 0 0 0 6px rgba(255, 255, 255, 0.55);
+ overflow: hidden;
+}
+.calendar-card.cal-style-hanami::before {
+ content: '❀';
+ inset: auto;
+ border: none;
+ top: -6%;
+ left: 10%;
+ font-size: 20px;
+ line-height: 1;
+ color: rgba(217, 138, 158, 0.5);
+ text-shadow:
+ 84px 60px 0 rgba(217, 138, 158, 0.35),
+ 196px 24px 0 rgba(217, 138, 158, 0.42),
+ 260px 110px 0 rgba(217, 138, 158, 0.3);
+ animation: calHanamiFall 8s linear infinite;
+ pointer-events: none;
+}
+.calendar-card.cal-style-hanami .calendar-note::after {
+ content: '❀';
+ font-size: 12px;
+ color: rgba(217, 138, 158, 0.8);
+}
+@keyframes calHanamiFall {
+ 0% { transform: translateY(-30px) rotate(0deg); opacity: 0; }
+ 12% { opacity: 1; }
+ 92% { opacity: 0.9; }
+ 100% { transform: translateY(520px) rotate(150deg); opacity: 0; }
+}
+.calendar-card.cal-style-hanami .calendar-title {
+ font-family: var(--font-display);
+ font-style: italic;
+}
+.calendar-card.cal-style-hanami .calendar-day.is-selected .calendar-day-num {
+ color: #fff;
+ font-size: 12px;
+}
+.calendar-card.cal-style-hanami .calendar-day.is-selected::after {
+ content: '❀';
+ inset: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 34px;
+ line-height: 1;
+ color: #d9748e;
+ z-index: 0;
+ filter: drop-shadow(0 3px 6px rgba(176, 86, 110, 0.4));
+}
+
+/* —— 月洞窗:圆窗竖排题字 + 黛绿玉环婚期 —— */
+.calendar-card.cal-style-neochina {
+ --cal-title: #3c5348;
+ --cal-sub: #708a7c;
+ --cal-kicker: #6f8c7d;
+ --cal-week: #587466;
+ --cal-day: #47604f;
+ --cal-rule: rgba(72, 97, 86, 0.45);
+ --cal-title-rule: rgba(72, 97, 86, 0.6);
+ padding-top: 178px;
+ border: 1px solid rgba(72, 97, 86, 0.45);
+ border-radius: 6px;
+ background:
+ radial-gradient(110% 40% at 50% 0%, rgba(255, 255, 255, 0.55), transparent 55%),
+ linear-gradient(175deg, #f6f6ee, #ecefe2);
+ box-shadow: 0 18px 44px rgba(52, 72, 62, 0.16), inset 0 0 0 5px rgba(255, 255, 255, 0.5);
+}
+.calendar-card.cal-style-neochina::before {
+ inset: auto;
+ top: 26px;
+ left: 50%;
+ width: 128px;
+ height: 128px;
+ margin-left: -64px;
+ border-radius: 50%;
+ border: 1.5px solid rgba(72, 97, 86, 0.6);
+ box-shadow:
+ 0 0 0 5px rgba(72, 97, 86, 0.08),
+ inset 0 0 0 4px rgba(255, 255, 255, 0.65),
+ inset 0 0 26px rgba(72, 97, 86, 0.1);
+}
+.calendar-card.cal-style-neochina .calendar-title {
+ position: absolute;
+ top: 44px;
+ left: 50%;
+ transform: translateX(-50%);
+ writing-mode: vertical-rl;
+ height: 94px;
+ margin: 0;
+ font-family: var(--font-kai);
+ font-size: 19px;
+ letter-spacing: 0.3em;
+ justify-content: center;
+}
+.calendar-card.cal-style-neochina .calendar-title i {
+ display: none;
+}
+.calendar-card.cal-style-neochina .calendar-kicker {
+ letter-spacing: 0.52em;
+ font-family: var(--font-kai);
+}
+.calendar-card.cal-style-neochina .calendar-note {
+ font-family: var(--font-kai);
+ letter-spacing: 0.3em;
+}
+.calendar-card.cal-style-neochina .calendar-day.is-selected .calendar-day-num {
+ color: #384f44;
+}
+.calendar-card.cal-style-neochina .calendar-day.is-selected::after {
+ inset: -5px;
+ border-radius: 50%;
+ border: 2px solid #6f8c7d;
+ box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.7), 0 0 0 3px rgba(111, 140, 125, 0.2);
+}
+
+/* —— 杂志内页:巨题黑白版式 + 黑色页脚通栏 + 刊号圈婚期 —— */
+.calendar-card.cal-style-magazine {
+ --cal-title: #1f1c19;
+ --cal-sub: #6b665e;
+ --cal-kicker: #1f1c19;
+ --cal-week: #1f1c19;
+ --cal-day: #3c3831;
+ --cal-rule: #1f1c19;
+ --cal-title-rule: #1f1c19;
+ text-align: left;
+ border: none;
+ border-radius: 0;
+ background: #fbfaf7;
+ box-shadow: 0 22px 50px rgba(31, 28, 25, 0.16);
+ padding-bottom: 64px;
+}
+.calendar-card.cal-style-magazine::before {
+ display: none;
+}
+.calendar-card.cal-style-magazine .calendar-kicker {
+ display: block;
+ letter-spacing: 0.6em;
+ border-bottom: 3px solid #1f1c19;
+ padding-bottom: 9px;
+ font-family: var(--font-cinzel, serif);
+}
+.calendar-card.cal-style-magazine .calendar-title {
+ justify-content: flex-start;
+ font-family: var(--font-serif);
+ font-weight: 900;
+ font-size: 44px;
+ letter-spacing: 0;
+ margin-top: 16px;
+}
+.calendar-card.cal-style-magazine .calendar-title i {
+ display: none;
+}
+.calendar-card.cal-style-magazine .calendar-date-line {
+ margin: 6px 0 22px;
+ text-transform: uppercase;
+ letter-spacing: 0.3em;
+ font-size: 10px;
+}
+.calendar-card.cal-style-magazine .calendar-note {
+ position: absolute;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ margin: 0;
+ padding: 11px 0;
+ background: #1f1c19;
+ color: #fbfaf7;
+ letter-spacing: 0.4em;
+ font-size: 11px;
+ font-family: var(--font-serif);
+}
+.calendar-card.cal-style-magazine .calendar-note i {
+ display: none;
+}
+.calendar-card.cal-style-magazine .calendar-day.is-selected .calendar-day-num {
+ font-weight: 900;
+ color: #1f1c19;
+}
+.calendar-card.cal-style-magazine .calendar-day.is-selected::after {
+ inset: -4px;
+ border-radius: 50%;
+ border: 2.5px solid #1f1c19;
+ background: #fff;
+ z-index: 0;
+}
+
+/* —— 登机牌:航司蓝条 + 航段虚线 + 条码 + 舷窗婚期 —— */
+.calendar-card.cal-style-boarding {
+ --cal-title: #2e4a68;
+ --cal-sub: #5c7186;
+ --cal-kicker: #fff;
+ --cal-week: #40587a;
+ --cal-day: #3c4f63;
+ --cal-rule: rgba(46, 74, 104, 0.4);
+ --cal-title-rule: rgba(46, 74, 104, 0.6);
+ text-align: left;
+ padding-top: 58px;
+ border-radius: 12px;
+ border: 1px solid rgba(46, 74, 104, 0.4);
+ background:
+ repeating-linear-gradient(0deg, rgba(46, 74, 104, 0.025) 0 1px, transparent 1px 8px),
+ #f7f9fb;
+ box-shadow: 0 16px 40px rgba(46, 74, 104, 0.18);
+ overflow: hidden;
+}
+.calendar-card.cal-style-boarding::before {
+ display: none;
+}
+.calendar-card.cal-style-boarding .calendar-kicker {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 9px 16px;
+ background: linear-gradient(90deg, #2e4a68, #3a5c80);
+ letter-spacing: 0.3em;
+ font-family: var(--font-number);
+}
+.calendar-card.cal-style-boarding .calendar-kicker::after {
+ content: '✈ FIRST CLASS';
+ font-size: 9px;
+ letter-spacing: 0.14em;
+ color: rgba(255, 255, 255, 0.85);
+ padding: 0;
+}
+.calendar-card.cal-style-boarding .calendar-title {
+ justify-content: flex-start;
+ font-family: var(--font-number);
+ letter-spacing: 0.08em;
+}
+.calendar-card.cal-style-boarding .calendar-title i {
+ display: none;
+}
+.calendar-card.cal-style-boarding .calendar-date-line {
+ margin: 12px 0 20px;
+ font-family: var(--font-number);
+ text-transform: uppercase;
+ letter-spacing: 0.2em;
+ border-top: 2px dashed rgba(46, 74, 104, 0.4);
+ border-bottom: 2px dashed rgba(46, 74, 104, 0.4);
+ padding: 7px 0;
+}
+.calendar-card.cal-style-boarding .calendar-weekdays,
+.calendar-card.cal-style-boarding .calendar-day {
+ font-family: var(--font-number);
+}
+.calendar-card.cal-style-boarding .calendar-note {
+ justify-content: space-between;
+ font-family: var(--font-number);
+ letter-spacing: 0.26em;
+ font-size: 11px;
+}
+.calendar-card.cal-style-boarding .calendar-note i {
+ order: -1;
+ width: 58px;
+ height: 15px;
+ background: repeating-linear-gradient(90deg, #2e4a68 0 2px, transparent 2px 4px, #2e4a68 4px 7px, transparent 7px 9px);
+}
+.calendar-card.cal-style-boarding .calendar-day.is-selected .calendar-day-num {
+ color: #2e4a68;
+ font-weight: 800;
+}
+.calendar-card.cal-style-boarding .calendar-day.is-selected::after {
+ inset: -5px;
+ border-radius: 50%;
+ border: 2px solid #2e4a68;
+ box-shadow: inset 0 0 0 3px rgba(247, 249, 251, 0.9), inset 0 0 0 4px rgba(46, 74, 104, 0.55);
+}
+
+/* —— 胶片场记:上下齿孔黑条 + 片名金字 + 红色对焦框婚期 —— */
+.calendar-card.cal-style-film {
+ --cal-title: #33261f;
+ --cal-sub: #7a6852;
+ --cal-kicker: #f8d75c;
+ --cal-week: #6e5a40;
+ --cal-day: #4c3e2e;
+ --cal-rule: rgba(122, 104, 82, 0.5);
+ --cal-title-rule: rgba(122, 104, 82, 0.7);
+ padding-top: 60px;
+ padding-bottom: 60px;
+ border-radius: 4px;
+ border: 1px solid rgba(43, 39, 35, 0.6);
+ background: #f9f1dc;
+ box-shadow: 0 18px 44px rgba(43, 39, 35, 0.25);
+}
+.calendar-card.cal-style-film::before {
+ content: '';
+ inset: auto;
+ top: 0;
+ left: 0;
+ right: 0;
+ height: 30px;
+ border: none;
+ background:
+ repeating-linear-gradient(90deg, transparent 0 9px, rgba(249, 241, 220, 0.92) 9px 21px, transparent 21px 30px) center / auto 12px no-repeat,
+ #2b2723;
+}
+.calendar-card.cal-style-film::after {
+ content: '';
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ height: 30px;
+ background:
+ repeating-linear-gradient(90deg, transparent 0 9px, rgba(249, 241, 220, 0.92) 9px 21px, transparent 21px 30px) center / auto 12px no-repeat,
+ #2b2723;
+ pointer-events: none;
+}
+.calendar-card.cal-style-film .calendar-kicker {
+ font-family: var(--font-number);
+ letter-spacing: 0.42em;
+ color: #b3541e;
+}
+.calendar-card.cal-style-film .calendar-title {
+ font-family: var(--font-number);
+ letter-spacing: 0.1em;
+}
+.calendar-card.cal-style-film .calendar-note {
+ font-family: var(--font-number);
+ letter-spacing: 0.3em;
+}
+.calendar-card.cal-style-film .calendar-day.is-selected .calendar-day-num {
+ color: #c9302c;
+ font-weight: 800;
+}
+.calendar-card.cal-style-film .calendar-day.is-selected::after {
+ inset: -5px;
+ background:
+ linear-gradient(#c9302c, #c9302c) left top / 9px 2px,
+ linear-gradient(#c9302c, #c9302c) left top / 2px 9px,
+ linear-gradient(#c9302c, #c9302c) right top / 9px 2px,
+ linear-gradient(#c9302c, #c9302c) right top / 2px 9px,
+ linear-gradient(#c9302c, #c9302c) left bottom / 9px 2px,
+ linear-gradient(#c9302c, #c9302c) left bottom / 2px 9px,
+ linear-gradient(#c9302c, #c9302c) right bottom / 9px 2px,
+ linear-gradient(#c9302c, #c9302c) right bottom / 2px 9px;
+ background-repeat: no-repeat;
+}
+
+/* —— 影院灯牌:灯泡流转边 + 放映厅金字 + 灯泡婚期 —— */
+.calendar-card.cal-style-marquee {
+ --cal-title: #f0e2c8;
+ --cal-sub: #cbb27e;
+ --cal-kicker: #cbb27e;
+ --cal-week: #d9c294;
+ --cal-day: #c8b088;
+ --cal-rule: rgba(240, 226, 200, 0.4);
+ --cal-title-rule: rgba(240, 226, 200, 0.6);
+ padding-top: 56px;
+ padding-bottom: 56px;
+ border: 3px solid #3a2f26;
+ border-radius: 14px;
+ background:
+ radial-gradient(120% 50% at 50% 0%, rgba(90, 70, 40, 0.4), transparent 60%),
+ linear-gradient(175deg, #1c1714, #120f0c);
+ box-shadow: 0 20px 50px rgba(0, 0, 0, 0.55), inset 0 0 0 1px rgba(240, 226, 200, 0.15);
+}
+.calendar-card.cal-style-marquee::before,
+.calendar-card.cal-style-marquee::after {
+ content: '';
+ position: absolute;
+ left: 18px;
+ right: 18px;
+ height: 12px;
+ border: none;
+ background: radial-gradient(circle 4px at 12px 6px, #f2cf7e 55%, rgba(242, 207, 126, 0.25) 70%, transparent 80%) 0 0 / 24px 12px repeat-x;
+ animation: calMarqueeLights 1.1s linear infinite;
+ pointer-events: none;
+}
+.calendar-card.cal-style-marquee::before {
+ inset: auto;
+ top: 14px;
+}
+.calendar-card.cal-style-marquee::after {
+ bottom: 14px;
+}
+@keyframes calMarqueeLights {
+ to { background-position: 24px 0; }
+}
+.calendar-card.cal-style-marquee .calendar-kicker {
+ font-family: var(--font-cinzel, serif);
+ letter-spacing: 0.5em;
+}
+.calendar-card.cal-style-marquee .calendar-title {
+ font-family: var(--font-cinzel, serif);
+ letter-spacing: 0.18em;
+}
+.calendar-card.cal-style-marquee .calendar-day.is-selected .calendar-day-num {
+ color: #1c1714;
+}
+.calendar-card.cal-style-marquee .calendar-day.is-selected::after {
+ inset: -4px;
+ border-radius: 50%;
+ background: radial-gradient(circle at 38% 32%, #f7e3ae, #f2cf7e 70%);
+ box-shadow: 0 0 14px rgba(242, 207, 126, 0.85);
+ z-index: 0;
+ animation: calPulse 1.6s ease-in-out infinite;
+}
+
+/* —— 千禧玻璃:彩虹渐变边玻璃卡 + 光泽扫过 + 闪星婚期 —— */
+.calendar-card.cal-style-y2k {
+ --cal-title: #5a3ab8;
+ --cal-sub: #7a6aa8;
+ --cal-kicker: #8a5cf0;
+ --cal-week: #6a4ac8;
+ --cal-day: #4e4468;
+ --cal-rule: rgba(122, 74, 224, 0.4);
+ --cal-title-rule: rgba(122, 74, 224, 0.6);
+ border: 2px solid transparent;
+ border-radius: 20px;
+ background:
+ linear-gradient(rgba(255, 255, 255, 0.72), rgba(255, 255, 255, 0.5)) padding-box,
+ linear-gradient(130deg, #8a5cf0, #4aaee0 52%, #e879c8) border-box;
+ backdrop-filter: blur(12px);
+ -webkit-backdrop-filter: blur(12px);
+ box-shadow: 0 18px 44px rgba(122, 74, 224, 0.28), inset 0 1px 0 rgba(255, 255, 255, 0.85);
+ overflow: hidden;
+}
+.calendar-card.cal-style-y2k::before {
+ display: none;
+}
+.calendar-card.cal-style-y2k::after {
+ content: '';
+ position: absolute;
+ top: -20px;
+ bottom: -20px;
+ left: 0;
+ width: 52px;
+ transform: translateX(-90px) skewX(-18deg);
+ background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.7), transparent);
+ animation: calY2kSheen 3.8s ease-in-out infinite;
+ pointer-events: none;
+}
+@keyframes calY2kSheen {
+ 0%, 55% { transform: translateX(-90px) skewX(-18deg); }
+ 100% { transform: translateX(440px) skewX(-18deg); }
+}
+.calendar-card.cal-style-y2k .calendar-title {
+ font-weight: 800;
+ background: linear-gradient(120deg, #7a4ae0, #3f9be0 60%, #d060b8);
+ -webkit-background-clip: text;
+ background-clip: text;
+ color: transparent;
+}
+.calendar-card.cal-style-y2k .calendar-title i {
+ background: linear-gradient(90deg, transparent, rgba(122, 74, 224, 0.6), transparent);
+}
+.calendar-card.cal-style-y2k .calendar-day.is-selected .calendar-day-num {
+ color: #5a3ab8;
+ font-weight: 800;
+ font-size: 12px;
+}
+.calendar-card.cal-style-y2k .calendar-day.is-selected::after {
+ content: '✦';
+ inset: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 30px;
+ line-height: 1;
+ color: #8a5cf0;
+ z-index: 0;
+ filter: drop-shadow(0 0 8px rgba(138, 92, 240, 0.7));
+ animation: calStarTwinkle 2.2s ease-in-out infinite;
+}
+
+/* —— 画廊白盒:装裱厚白框 + 作品标签 + 红点「已被预定」 —— */
+.calendar-card.cal-style-gallery {
+ --cal-title: #2c2a26;
+ --cal-sub: #8b877e;
+ --cal-kicker: #8b877e;
+ --cal-week: #55524b;
+ --cal-day: #6a665e;
+ --cal-rule: rgba(44, 42, 38, 0.3);
+ --cal-title-rule: rgba(44, 42, 38, 0.45);
+ padding: 46px 34px 40px;
+ border: 1px solid #dcd9d2;
+ border-radius: 0;
+ background: #fff;
+ box-shadow:
+ 0 24px 50px rgba(44, 42, 38, 0.15),
+ inset 0 0 0 14px #fff,
+ inset 0 0 0 15px #2c2a26;
+}
+.calendar-card.cal-style-gallery::before {
+ display: none;
+}
+.calendar-card.cal-style-gallery .calendar-kicker {
+ letter-spacing: 0.52em;
+}
+.calendar-card.cal-style-gallery .calendar-title {
+ font-family: var(--font-display);
+ font-style: italic;
+}
+.calendar-card.cal-style-gallery .calendar-note {
+ border: 1px solid #dcd9d2;
+ width: fit-content;
+ margin-left: auto;
+ margin-right: auto;
+ padding: 7px 16px;
+ font-size: 10px;
+ letter-spacing: 0.28em;
+ box-shadow: 0 3px 8px rgba(44, 42, 38, 0.07);
+}
+.calendar-card.cal-style-gallery .calendar-note i {
+ display: none;
+}
+.calendar-card.cal-style-gallery .calendar-day.is-selected .calendar-day-num {
+ color: #2c2a26;
+ font-weight: 900;
+}
+.calendar-card.cal-style-gallery .calendar-day.is-selected::after {
+ inset: auto;
+ top: 1px;
+ right: 3px;
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ background: #c9302c;
+ box-shadow: 0 1px 4px rgba(201, 48, 44, 0.5);
+}
+
+/* ============================================================
+ 区块级主题化:日历 / 日程 / 相册 / 背景光斑
+ —— 让每套完整模板的每一屏都长得不一样
+ ============================================================ */
+
+/* —— 日报编辑:表格线排印、照片做旧 —— */
+html[data-theme='newspaper'] .calendar-kicker,
+html[data-theme='newspaper'] .calendar-title {
+ font-family: var(--font-serif);
+}
+html[data-theme='newspaper'] .schedule-row {
+ border-bottom: 1px solid rgba(var(--c-line-rgb), 0.55);
+ padding-bottom: 10px;
+}
+html[data-theme='newspaper'] .schedule-time {
+ font-family: var(--font-display);
+ font-style: italic;
+}
+html[data-theme='newspaper'] .schedule-event,
+html[data-theme='newspaper'] .schedule-desc {
+ font-family: var(--font-serif);
+}
+html[data-theme='newspaper'] .preview-img,
+html[data-theme='newspaper'] .ending-photo img {
+ filter: grayscale(0.28) contrast(1.03);
+}
+html[data-theme='newspaper'] .bg-glow i {
+ opacity: 0.16;
+ filter: blur(50px) saturate(0.3);
+}
+
+/* —— 杂志封面:目录式日程、点线页码 —— */
+html[data-theme='magazine'] .calendar-title {
+ font-family: var(--font-display);
+ font-weight: 700;
+}
+html[data-theme='magazine'] .schedule-row {
+ border-bottom: 1px dotted rgba(var(--c-line-rgb), 0.7);
+ padding-bottom: 12px;
+}
+html[data-theme='magazine'] .schedule-time {
+ font-family: var(--font-display);
+ font-style: italic;
+ font-weight: 700;
+}
+html[data-theme='magazine'] .schedule-kicker,
+html[data-theme='magazine'] .calendar-kicker {
+ font-family: var(--font-cinzel);
+ letter-spacing: 0.5em;
+}
+html[data-theme='magazine'] .bg-glow i {
+ opacity: 0.18;
+ filter: blur(56px) saturate(0.4);
+}
+
+/* —— 复古像素:QUEST LOG 日程、高饱和照片 —— */
+html[data-theme='pixel'] .calendar-day.is-selected .heart-ring {
+ filter: saturate(1.4);
+}
+html[data-theme='pixel'] .schedule-row {
+ border: 2px solid var(--c-ink);
+ box-shadow: 3px 3px 0 rgba(var(--c-line-rgb), 0.4);
+ padding: 10px 12px;
+ margin-bottom: 10px;
+ background: var(--c-card);
+}
+html[data-theme='pixel'] .schedule-event::before {
+ content: '▶ ';
+ color: var(--c-primary);
+}
+html[data-theme='pixel'] .schedule-node i {
+ border-radius: 0;
+}
+html[data-theme='pixel'] .preview-img {
+ filter: saturate(1.18) contrast(1.04);
+}
+html[data-theme='pixel'] .bg-glow i {
+ opacity: 0.14;
+}
+
+/* —— 极简主义:全部去装饰、细线、大行距 —— */
+html[data-theme='zen'] .schedule-row {
+ border-bottom: 1px solid rgba(var(--c-line-rgb), 0.4);
+ padding-bottom: 14px;
+ margin-bottom: 14px;
+}
+html[data-theme='zen'] .schedule-node i {
+ width: 5px;
+ height: 5px;
+ border-radius: 0;
+}
+html[data-theme='zen'] .preview-img {
+ filter: grayscale(0.12);
+}
+html[data-theme='zen'] .bg-glow i {
+ opacity: 0;
+}
+
+/* —— 老中式:仪程单、红金光斑 —— */
+html[data-theme='guofeng-old'] .calendar-kicker {
+ font-family: var(--font-kai);
+ letter-spacing: 0.4em;
+ color: var(--c-primary);
+}
+html[data-theme='guofeng-old'] .schedule-row {
+ border-bottom: 1px dashed rgba(var(--c-line-rgb), 0.6);
+ padding-bottom: 10px;
+}
+html[data-theme='guofeng-old'] .schedule-time,
+html[data-theme='guofeng-old'] .schedule-event {
+ font-family: var(--font-kai);
+}
+html[data-theme='guofeng-old'] .schedule-time {
+ color: var(--c-primary);
+ font-weight: 700;
+}
+html[data-theme='guofeng-old'] .schedule-node i {
+ background: var(--c-line);
+}
+html[data-theme='guofeng-old'] .bg-glow i {
+ filter: blur(46px) hue-rotate(-18deg) saturate(1.15);
+ opacity: 0.5;
+}
+
+/* —— 新中式:楷体仪程、青调光斑 —— */
+html[data-theme='guofeng-new'] .calendar-kicker {
+ font-family: var(--font-kai);
+ letter-spacing: 0.44em;
+}
+html[data-theme='guofeng-new'] .schedule-time,
+html[data-theme='guofeng-new'] .schedule-event {
+ font-family: var(--font-kai);
+}
+html[data-theme='guofeng-new'] .schedule-time {
+ color: var(--c-primary);
+}
+html[data-theme='guofeng-new'] .schedule-node i {
+ background: #b5493f;
+}
+html[data-theme='guofeng-new'] .schedule-row {
+ border-bottom: 1px solid rgba(var(--c-primary-rgb), 0.18);
+ padding-bottom: 10px;
+}
+html[data-theme='guofeng-new'] .bg-glow i {
+ filter: blur(50px) hue-rotate(90deg) saturate(0.5);
+ opacity: 0.3;
+}
+
/* 极简:去圆角、细字、去装饰花字 */
html[data-theme='zen'] .invite-cover {
border-radius: 0;
@@ -1161,7 +3240,1325 @@ html[data-theme='zen'] .map-cta {
border-radius: 0;
box-shadow: none;
}
-html[data-theme='zen'] .rsvp-cta-deco,
-html[data-theme='zen'] .ek-mark {
+html[data-theme='zen'] .rsvp-cta-deco {
display: none;
}
+
+/* ============================================================
+ 新增八套完整模板 + 两套风格包:字体矩阵
+ ============================================================ */
+html[data-theme='inkwash'] .calligraphy,
+html[data-theme='inkwash'] .calligraphy-strong,
+html[data-theme='inkwash'] .gallery-subtitle {
+ font-family: var(--font-kai) !important;
+}
+html[data-theme='cinema'] .calligraphy,
+html[data-theme='cinema'] .calligraphy-strong,
+html[data-theme='cinema'] .gallery-subtitle,
+html[data-theme='arthouse'] .calligraphy,
+html[data-theme='arthouse'] .calligraphy-strong,
+html[data-theme='arthouse'] .gallery-subtitle,
+html[data-theme='passport'] .calligraphy,
+html[data-theme='passport'] .calligraphy-strong,
+html[data-theme='passport'] .gallery-subtitle {
+ font-family: var(--font-display) !important;
+}
+html[data-theme='kodak'] .calligraphy,
+html[data-theme='kodak'] .calligraphy-strong,
+html[data-theme='kodak'] .gallery-subtitle,
+html[data-theme='y2k'] .calligraphy,
+html[data-theme='y2k'] .calligraphy-strong,
+html[data-theme='y2k'] .gallery-subtitle {
+ font-family: var(--font-sans) !important;
+ font-weight: 600;
+}
+html[data-theme='scrapbook'] .calligraphy,
+html[data-theme='scrapbook'] .calligraphy-strong,
+html[data-theme='scrapbook'] .gallery-subtitle {
+ font-family: var(--font-longcang) !important;
+}
+
+/* ============================================================
+ 新模板幕布:背景特化与内容样式
+ ============================================================ */
+/* —— 水墨:宣纸卷轴 —— */
+html[data-theme='inkwash'] .invite-cover {
+ background:
+ var(--t-bg-texture),
+ var(--c-bg);
+ border: none;
+ box-shadow: none;
+}
+.em-ink-rod {
+ display: block;
+ width: min(74vw, 300px);
+ height: 10px;
+ border-radius: 5px;
+ background: linear-gradient(180deg, #57504a, #33302c);
+ margin: 12px 0;
+}
+.em-ink-title {
+ font-family: var(--font-kai);
+ font-size: 21px;
+ letter-spacing: 0.5em;
+ text-indent: 0.5em;
+ color: var(--c-ink);
+ margin: 16px 0 12px;
+}
+.em-ink-names {
+ font-family: var(--font-kai);
+ font-size: clamp(23px, 7vw, 28px);
+ letter-spacing: 0.2em;
+ color: var(--c-ink);
+}
+.em-ink-date {
+ margin: 12px 0 14px;
+ font-family: var(--font-serif);
+ font-size: 11px;
+ letter-spacing: 0.2em;
+ color: var(--c-muted);
+}
+.em-ink-seal {
+ width: 30px;
+ height: 30px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-bottom: 16px;
+ font-family: var(--font-kai);
+ font-size: 15px;
+ color: #fdf6f0;
+ background: #b5493f;
+ border-radius: 3px;
+}
+/* —— 电影:做旧海报(三段式:横幅 / 主标 / 制作名单) —— */
+html[data-theme='cinema'] .invite-cover {
+ background:
+ var(--t-bg-texture),
+ radial-gradient(120% 50% at 50% 0%, rgba(140, 38, 34, 0.1), transparent 65%),
+ radial-gradient(ellipse at 50% 0%, rgba(212, 162, 74, 0.2), transparent 55%),
+ var(--c-bg);
+ border: none;
+ box-shadow: none;
+}
+html[data-theme='cinema'] .emblem-inner {
+ justify-content: space-between;
+}
+.em-cn-top {
+ width: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 10px;
+}
+.em-cn-studio {
+ font-family: var(--font-serif);
+ font-size: 10px;
+ letter-spacing: 0.2em;
+ color: var(--c-muted);
+}
+.em-cn-mid {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+.em-cn-bottom {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 12px;
+}
+.em-cn-credits {
+ font-family: var(--font-serif);
+ font-size: 9.5px;
+ letter-spacing: 0.14em;
+ color: var(--c-muted);
+ border-top: 1px solid rgba(var(--c-line-rgb), 0.5);
+ padding-top: 10px;
+}
+.em-cn-badge {
+ display: inline-block;
+ padding: 4px 12px;
+ font-family: var(--font-cinzel);
+ font-size: 10px;
+ letter-spacing: 0.26em;
+ color: var(--c-on-primary);
+ background: var(--c-primary);
+ border-radius: 3px;
+ transform: rotate(-3deg);
+ box-shadow: 2px 3px 0 rgba(58, 44, 34, 0.25);
+}
+.em-cn-title {
+ margin: 22px 0 14px;
+ font-family: var(--font-display);
+ font-weight: 700;
+ font-size: clamp(34px, 11vw, 46px);
+ letter-spacing: 0.1em;
+ color: var(--c-primary);
+ text-shadow: 2px 2px 0 rgba(212, 162, 74, 0.4);
+}
+.em-cn-star {
+ font-family: var(--font-serif);
+ font-size: 10px;
+ letter-spacing: 0.5em;
+ text-indent: 0.5em;
+ color: var(--c-muted);
+}
+.em-cn-names {
+ margin: 10px 0 14px;
+ font-family: var(--font-serif);
+ font-weight: 700;
+ font-size: clamp(20px, 6vw, 25px);
+ letter-spacing: 0.2em;
+ color: var(--c-ink);
+}
+.em-cn-date {
+ margin-bottom: 28px;
+ font-family: var(--font-serif);
+ font-size: 12px;
+ letter-spacing: 0.18em;
+ color: var(--c-ink-soft);
+}
+/* —— 胶片:胶卷盒 —— */
+html[data-theme='kodak'] .invite-cover {
+ background:
+ var(--t-bg-texture),
+ var(--c-bg);
+ border: none;
+ box-shadow: none;
+}
+.em-kd-strip {
+ display: flex;
+ gap: 4px;
+ margin-bottom: 20px;
+}
+.em-kd-strip i {
+ width: 26px;
+ height: 8px;
+ border-radius: 2px;
+}
+.em-kd-strip i:nth-child(1) { background: #e0782e; }
+.em-kd-strip i:nth-child(2) { background: #d84438; }
+.em-kd-strip i:nth-child(3) { background: #e8b02e; }
+.em-kd-title {
+ font-size: clamp(27px, 8.4vw, 36px);
+ font-weight: 800;
+ letter-spacing: 0.06em;
+ color: var(--c-primary);
+}
+.em-kd-sub {
+ margin: 8px 0 20px;
+ font-family: var(--font-number);
+ font-size: 10px;
+ letter-spacing: 0.3em;
+ color: var(--c-muted);
+}
+.em-kd-names {
+ font-size: clamp(19px, 5.8vw, 24px);
+ font-weight: 600;
+ letter-spacing: 0.12em;
+ color: var(--c-ink);
+}
+.em-kd-date {
+ margin: 10px 0 24px;
+ font-family: var(--font-number);
+ font-size: 12px;
+ letter-spacing: 0.14em;
+ color: var(--c-ink-soft);
+}
+/* —— 文艺:分幕页 —— */
+html[data-theme='arthouse'] .invite-cover {
+ background: var(--c-bg);
+ border: none;
+ box-shadow: none;
+}
+.em-ah-chapter {
+ font-family: var(--font-display);
+ font-size: 11px;
+ letter-spacing: 0.6em;
+ text-indent: 0.6em;
+ color: var(--c-muted);
+}
+.em-ah-names {
+ margin: 26px 0 20px;
+ font-family: var(--font-display);
+ font-size: clamp(25px, 7.6vw, 32px);
+ letter-spacing: 0.14em;
+ color: var(--c-ink);
+}
+.em-ah-names em {
+ font-style: italic;
+ font-size: 0.62em;
+ color: var(--c-muted);
+ margin: 0 0.3em;
+}
+.em-ah-line {
+ display: block;
+ width: 1px;
+ height: 34px;
+ background: rgba(var(--c-line-rgb), 0.7);
+ margin: 0 auto 20px;
+}
+.em-ah-date {
+ margin-bottom: 30px;
+ font-family: var(--font-serif);
+ font-size: 11px;
+ letter-spacing: 0.3em;
+ color: var(--c-muted);
+}
+/* —— 旅行:护照封面(深蓝金) —— */
+html[data-theme='passport'] .invite-cover {
+ background:
+ radial-gradient(ellipse at 50% 8%, rgba(76, 108, 146, 0.5), transparent 55%),
+ linear-gradient(172deg, #2e4a68 0%, #223a54 55%, #1a2e44 100%);
+ border: none;
+ box-shadow: none;
+}
+html[data-theme='passport'] .emblem-inner {
+ color: #e8dfc8;
+}
+.em-pp-top {
+ font-family: var(--font-cinzel);
+ font-size: 11px;
+ letter-spacing: 0.44em;
+ text-indent: 0.44em;
+ color: rgba(232, 223, 200, 0.85);
+}
+.em-pp-crest {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 66px;
+ height: 66px;
+ margin: 22px 0;
+ font-size: 26px;
+ color: #d8ba7a;
+ border: 2px solid rgba(216, 186, 122, 0.8);
+ border-radius: 50%;
+ box-shadow: inset 0 0 0 4px rgba(34, 58, 84, 0.9), inset 0 0 0 5px rgba(216, 186, 122, 0.4);
+}
+.em-pp-title {
+ font-family: var(--font-cinzel);
+ font-weight: 700;
+ font-size: clamp(27px, 8.4vw, 34px);
+ letter-spacing: 0.3em;
+ text-indent: 0.3em;
+ color: #d8ba7a;
+}
+.em-pp-sub {
+ margin: 8px 0 22px;
+ font-family: var(--font-cinzel);
+ font-size: 11px;
+ letter-spacing: 0.5em;
+ text-indent: 0.5em;
+ color: rgba(232, 223, 200, 0.75);
+}
+.em-pp-names {
+ margin-bottom: 30px;
+ font-family: var(--font-number);
+ font-size: clamp(17px, 5.2vw, 21px);
+ letter-spacing: 0.16em;
+ color: #f0e8d4;
+}
+html[data-theme='passport'] .emblem-hint {
+ color: rgba(232, 223, 200, 0.7);
+}
+html[data-theme='passport'] .emblem-hint .dot {
+ background: #d8ba7a;
+}
+/* —— 手账:牛皮纸缝线 —— */
+html[data-theme='scrapbook'] .invite-cover {
+ background:
+ var(--t-bg-texture),
+ var(--c-bg);
+ border: none;
+ box-shadow: inset 0 0 0 14px var(--c-bg), inset 0 0 0 15px rgba(var(--c-primary-rgb), 0.35);
+}
+.em-sb-tape {
+ display: block;
+ width: 88px;
+ height: 26px;
+ margin-bottom: -12px;
+ background: rgba(138, 168, 138, 0.5);
+ transform: rotate(-4deg);
+ box-shadow: 0 1px 4px rgba(69, 58, 48, 0.16);
+ position: relative;
+ z-index: 1;
+}
+.em-sb-label {
+ padding: 26px 30px;
+ background: var(--c-card);
+ border: 1px dashed rgba(var(--c-primary-rgb), 0.45);
+ border-radius: 8px;
+ transform: rotate(-1.2deg);
+ box-shadow: 0 10px 26px rgba(69, 58, 48, 0.14);
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ margin-bottom: 26px;
+}
+.em-sb-small {
+ font-family: var(--font-liujian);
+ font-size: 14px;
+ color: var(--c-muted);
+}
+.em-sb-names {
+ font-family: var(--font-longcang);
+ font-size: clamp(25px, 7.6vw, 32px);
+ color: var(--c-ink);
+}
+.em-sb-date {
+ font-family: var(--font-liujian);
+ font-size: 13px;
+ color: var(--c-ink-soft);
+}
+/* —— Y2K:开机窗口 —— */
+html[data-theme='y2k'] .invite-cover {
+ background:
+ var(--t-bg-texture),
+ linear-gradient(160deg, #ece8f8 0%, #e0ecf8 48%, #f4e4f4 100%);
+ border: none;
+ box-shadow: none;
+}
+html[data-theme='y2k'] .emblem-inner {
+ max-width: 330px;
+ margin: 0 auto;
+ min-height: 0;
+ border: 2px solid #9088b8;
+ border-radius: 10px;
+ background: var(--c-card);
+ box-shadow:
+ inset 1px 1px 0 rgba(255, 255, 255, 0.9),
+ 6px 8px 0 rgba(122, 74, 224, 0.18),
+ 0 20px 46px rgba(84, 74, 112, 0.22);
+ padding: 0 0 22px;
+ overflow: hidden;
+}
+.em-yk-bar {
+ width: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 7px 10px;
+ margin-bottom: 20px;
+ background: linear-gradient(90deg, #7a4ae0, #4a90e0 55%, #4adce0);
+ color: #fff;
+ font-family: var(--font-pixel);
+ font-size: 11px;
+ letter-spacing: 0.1em;
+}
+.em-yk-bar i {
+ width: 16px;
+ height: 16px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 8px;
+ font-style: normal;
+ background: rgba(255, 255, 255, 0.92);
+ color: #544a70;
+ border-radius: 3px;
+}
+.em-yk-names {
+ font-size: clamp(23px, 7vw, 28px);
+ font-weight: 800;
+ letter-spacing: 0.08em;
+ background: linear-gradient(180deg, #7a4ae0 8%, #4a90e0 44%, #4adce0 58%, #e04ad0 100%);
+ -webkit-background-clip: text;
+ background-clip: text;
+ color: transparent;
+ filter: drop-shadow(0 2px 0 rgba(255, 255, 255, 0.8));
+}
+.em-yk-date {
+ margin: 12px 0 16px;
+ font-family: var(--font-pixel);
+ font-size: 10px;
+ color: var(--c-ink-soft);
+}
+.em-yk-load {
+ width: 78%;
+ height: 12px;
+ border: 2px solid #9088b8;
+ border-radius: 4px;
+ padding: 1px;
+ background: #fff;
+ margin-bottom: 14px;
+}
+.em-yk-load i {
+ display: block;
+ width: 99%;
+ height: 100%;
+ border-radius: 2px;
+ background: repeating-linear-gradient(90deg, #7a4ae0 0 8px, #4adce0 8px 16px);
+ animation: emYkLoad 1.6s steps(8) infinite;
+}
+@keyframes emYkLoad {
+ 0% { background-position: 0 0; }
+ 100% { background-position: 32px 0; }
+}
+
+/* ============================================================
+ 幕布专属入场动画:每套完整模板不同的「开场感」
+ —— fill-mode 用 backwards:动画结束释放 transform,
+ 不影响九种退场动画的 transition/animation 接管
+ ============================================================ */
+/* 杂志:大片 Ken Burns 缓推 + 刊头压入 + 大字上浮 */
+html[data-theme='magazine'] .curtain-root:not(.is-opening) .curtain-bg {
+ animation: mgKenburns 9s ease-out forwards;
+}
+@keyframes mgKenburns {
+ 0% { transform: scale(1.03); }
+ 100% { transform: scale(1.12) translateY(-1.2%); }
+}
+html[data-theme='magazine'] .em-mag-logo,
+html[data-theme='magazine'] .em-mag-issue {
+ animation: mgDropIn 0.85s cubic-bezier(0.2, 0.9, 0.3, 1) backwards;
+}
+html[data-theme='magazine'] .em-mag-issue { animation-delay: 0.12s; }
+@keyframes mgDropIn {
+ 0% { opacity: 0; transform: translateY(-34px); }
+ 100% { opacity: 1; transform: translateY(0); }
+}
+html[data-theme='magazine'] .em-mag-names,
+html[data-theme='magazine'] .em-mag-bar,
+html[data-theme='magazine'] .em-mag-copy {
+ animation: mgRiseIn 0.9s cubic-bezier(0.2, 0.9, 0.3, 1) 0.25s backwards;
+}
+html[data-theme='magazine'] .em-mag-bar { animation-delay: 0.38s; }
+html[data-theme='magazine'] .em-mag-copy { animation-delay: 0.5s; }
+@keyframes mgRiseIn {
+ 0% { opacity: 0; transform: translateY(38px); }
+ 100% { opacity: 1; transform: translateY(0); }
+}
+/* 报纸:整版旋转定格(经典电影转场) */
+html[data-theme='newspaper'] .curtain-root:not(.is-opening) .emblem-inner {
+ animation: npSpinIn 1.05s cubic-bezier(0.18, 0.8, 0.28, 1) backwards;
+}
+@keyframes npSpinIn {
+ 0% { opacity: 0; transform: rotate(-720deg) scale(0.06); }
+ 70% { opacity: 1; }
+ 100% { opacity: 1; transform: rotate(0) scale(1); }
+}
+/* 像素:CRT 开机(横条展开 + 亮度闪) */
+html[data-theme='pixel'] .curtain-root:not(.is-opening) .invite-cover {
+ animation: pxCrtOn 0.75s steps(7) backwards;
+ transform-origin: 50% 50%;
+}
+@keyframes pxCrtOn {
+ 0% { transform: scaleY(0.008); filter: brightness(3.4); }
+ 55% { transform: scaleY(1.02); filter: brightness(1.8); }
+ 100% { transform: scaleY(1); filter: brightness(1); }
+}
+/* 极简:超慢显影淡入 */
+html[data-theme='zen'] .curtain-root:not(.is-opening) .emblem-inner {
+ animation: zenSlowIn 2.4s ease backwards;
+}
+@keyframes zenSlowIn {
+ 0% { opacity: 0; transform: translateY(10px); }
+ 100% { opacity: 1; transform: translateY(0); }
+}
+/* 新中式:月洞环由小及大 + 帖文浮起 */
+html[data-theme='guofeng-new'] .curtain-root:not(.is-opening) .curtain-emblem::before {
+ animation: gnMoonGrow 1.1s cubic-bezier(0.2, 0.9, 0.3, 1) backwards;
+}
+@keyframes gnMoonGrow {
+ 0% { opacity: 0; transform: translate(-50%, -50%) scale(0.4); }
+ 100% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
+}
+html[data-theme='guofeng-new'] .curtain-root:not(.is-opening) .curtain-veil {
+ animation: gnVeilIn 1s ease backwards;
+}
+@keyframes gnVeilIn {
+ 0% { opacity: 0; }
+ 100% { opacity: 1; }
+}
+html[data-theme='guofeng-new'] .curtain-root:not(.is-opening) .emblem-inner {
+ animation: gnSheetUp 0.9s cubic-bezier(0.2, 0.9, 0.3, 1) 0.5s backwards;
+}
+@keyframes gnSheetUp {
+ 0% { opacity: 0; transform: translateY(30px); }
+ 100% { opacity: 1; transform: translateY(0); }
+}
+/* 老中式:双门自两侧合拢 + 匾额自上落下回弹 */
+html[data-theme='guofeng-old'] .curtain-root:not(.is-opening) .curtain-door-left {
+ animation: goDoorInL 0.95s cubic-bezier(0.2, 0.85, 0.3, 1) backwards;
+}
+html[data-theme='guofeng-old'] .curtain-root:not(.is-opening) .curtain-door-right {
+ animation: goDoorInR 0.95s cubic-bezier(0.2, 0.85, 0.3, 1) backwards;
+}
+@keyframes goDoorInL {
+ 0% { transform: translateX(-100%); }
+ 100% { transform: translateX(0); }
+}
+@keyframes goDoorInR {
+ 0% { transform: translateX(100%); }
+ 100% { transform: translateX(0); }
+}
+html[data-theme='guofeng-old'] .curtain-root:not(.is-opening) .emblem-inner {
+ animation: goPlaqueDrop 0.85s cubic-bezier(0.28, 1.4, 0.42, 1) 0.75s backwards;
+}
+@keyframes goPlaqueDrop {
+ 0% { opacity: 0; transform: translateY(-72px); }
+ 100% { opacity: 1; transform: translateY(0); }
+}
+/* 水墨:卷轴纵向展开 */
+html[data-theme='inkwash'] .curtain-root:not(.is-opening) .emblem-inner {
+ animation: inkUnroll 1.05s cubic-bezier(0.2, 0.85, 0.3, 1) backwards;
+ transform-origin: 50% 50%;
+}
+@keyframes inkUnroll {
+ 0% { opacity: 0; transform: scaleY(0.06); }
+ 60% { opacity: 1; }
+ 100% { opacity: 1; transform: scaleY(1); }
+}
+/* 电影:老胶片闪烁两下 + 三段错峰 */
+html[data-theme='cinema'] .curtain-root:not(.is-opening) .emblem-inner {
+ animation: cnFlicker 1.1s steps(1) backwards;
+}
+@keyframes cnFlicker {
+ 0% { opacity: 0; }
+ 12% { opacity: 1; }
+ 22% { opacity: 0.25; }
+ 34% { opacity: 1; }
+ 46% { opacity: 0.55; }
+ 58%, 100% { opacity: 1; }
+}
+html[data-theme='cinema'] .curtain-root:not(.is-opening) .em-cn-mid {
+ animation: cnRise 0.8s ease 0.6s backwards;
+}
+html[data-theme='cinema'] .curtain-root:not(.is-opening) .em-cn-bottom {
+ animation: cnRise 0.8s ease 0.85s backwards;
+}
+@keyframes cnRise {
+ 0% { opacity: 0; transform: translateY(22px); }
+ 100% { opacity: 1; transform: translateY(0); }
+}
+/* 胶片:过曝显影定格 */
+html[data-theme='kodak'] .curtain-root:not(.is-opening) .emblem-inner {
+ animation: kdDevelop 1.5s ease-out backwards;
+}
+@keyframes kdDevelop {
+ 0% { opacity: 0.4; filter: brightness(2.6) sepia(0.7) blur(3px); }
+ 55% { opacity: 1; filter: brightness(1.4) sepia(0.3) blur(0.5px); }
+ 100% { opacity: 1; filter: brightness(1) sepia(0) blur(0); }
+}
+/* 文艺:黑场缓亮 */
+html[data-theme='arthouse'] .curtain-root:not(.is-opening) .emblem-inner {
+ animation: ahLightUp 2.1s ease backwards;
+}
+@keyframes ahLightUp {
+ 0% { opacity: 0; filter: brightness(0.2); }
+ 55% { opacity: 1; filter: brightness(0.72); }
+ 100% { opacity: 1; filter: brightness(1); }
+}
+/* 旅行:徽章印章砸下 + 行序滑入 */
+html[data-theme='passport'] .curtain-root:not(.is-opening) .em-pp-crest {
+ animation: ppStampIn 0.55s cubic-bezier(0.2, 1.2, 0.3, 1) 0.45s backwards;
+}
+@keyframes ppStampIn {
+ 0% { opacity: 0; transform: scale(2.6) rotate(-14deg); }
+ 70% { opacity: 1; transform: scale(0.94) rotate(2deg); }
+ 100% { opacity: 1; transform: scale(1) rotate(0); }
+}
+html[data-theme='passport'] .curtain-root:not(.is-opening) .em-pp-top {
+ animation: ppLineIn 0.7s ease backwards;
+}
+html[data-theme='passport'] .curtain-root:not(.is-opening) .em-pp-title {
+ animation: ppLineIn 0.7s ease 0.75s backwards;
+}
+html[data-theme='passport'] .curtain-root:not(.is-opening) .em-pp-sub {
+ animation: ppLineIn 0.7s ease 0.88s backwards;
+}
+html[data-theme='passport'] .curtain-root:not(.is-opening) .em-pp-names {
+ animation: ppLineIn 0.7s ease 1s backwards;
+}
+@keyframes ppLineIn {
+ 0% { opacity: 0; transform: translateY(16px); }
+ 100% { opacity: 1; transform: translateY(0); }
+}
+/* 手账:贴纸逐个「啪」地贴上 */
+html[data-theme='scrapbook'] .curtain-root:not(.is-opening) .em-sb-tape {
+ animation: sbSlap 0.5s cubic-bezier(0.2, 1.4, 0.36, 1) 0.5s backwards;
+}
+html[data-theme='scrapbook'] .curtain-root:not(.is-opening) .em-sb-label {
+ animation: sbSlap 0.55s cubic-bezier(0.2, 1.4, 0.36, 1) 0.15s backwards;
+}
+@keyframes sbSlap {
+ 0% { opacity: 0; transform: scale(1.5) rotate(6deg); }
+ 100% { opacity: 1; }
+}
+/* Y2K:窗口弹出(标题栏先行) */
+html[data-theme='y2k'] .curtain-root:not(.is-opening) .emblem-inner {
+ animation: ykWinPop 0.65s cubic-bezier(0.24, 1.3, 0.36, 1) backwards;
+}
+@keyframes ykWinPop {
+ 0% { opacity: 0; transform: scale(0.12); }
+ 72% { opacity: 1; transform: scale(1.04); }
+ 100% { opacity: 1; transform: scale(1); }
+}
+html[data-theme='y2k'] .curtain-root:not(.is-opening) .em-yk-names,
+html[data-theme='y2k'] .curtain-root:not(.is-opening) .em-yk-date,
+html[data-theme='y2k'] .curtain-root:not(.is-opening) .em-yk-load {
+ animation: ppLineIn 0.5s ease 0.5s backwards;
+}
+html[data-theme='y2k'] .curtain-root:not(.is-opening) .em-yk-date { animation-delay: 0.62s; }
+html[data-theme='y2k'] .curtain-root:not(.is-opening) .em-yk-load { animation-delay: 0.74s; }
+
+/* 弱动效偏好:入场动画直接呈现、循环装饰停用(退场不受影响) */
+@media (prefers-reduced-motion: reduce) {
+ .curtain-root:not(.is-opening) .curtain-bg,
+ .curtain-root:not(.is-opening) .curtain-door,
+ .curtain-root:not(.is-opening) .emblem-inner,
+ .curtain-root:not(.is-opening) .curtain-veil,
+ .curtain-root:not(.is-opening) .curtain-emblem::before,
+ .curtain-root:not(.is-opening) :is(.em-mag-logo, .em-mag-issue, .em-mag-names, .em-mag-bar, .em-mag-copy,
+ .em-cn-mid, .em-cn-bottom, .em-pp-crest, .em-pp-top, .em-pp-title, .em-pp-sub, .em-pp-names,
+ .em-sb-tape, .em-sb-label, .em-yk-names, .em-yk-date, .em-yk-load) {
+ animation-duration: 0.01s !important;
+ animation-delay: 0s !important;
+ }
+ .em-px-heart,
+ .em-px-start,
+ .em-yk-load i {
+ animation: none !important;
+ }
+}
+
+/* ============================================================
+ 新模板:邀请文案页
+ ============================================================ */
+/* 水墨竖排 */
+.formal-ink {
+ position: relative;
+ padding: 20px 26px;
+}
+.fi-cols {
+ display: flex;
+ justify-content: center;
+ gap: 36px;
+ height: 21rem;
+}
+.fi-main {
+ font-family: var(--font-kai);
+ font-size: 19px;
+ letter-spacing: 0.3em;
+ line-height: 1.9;
+ color: var(--c-ink);
+}
+.fi-main-2 {
+ margin-top: 46px;
+ font-size: 16px;
+ color: var(--c-ink-soft);
+}
+.fi-seal {
+ position: absolute;
+ right: 12px;
+ bottom: 10px;
+ width: 28px;
+ height: 28px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-family: var(--font-kai);
+ font-size: 14px;
+ color: #fdf6f0;
+ background: #b5493f;
+ border-radius: 3px;
+ opacity: 0.92;
+}
+/* 电影字幕卡 */
+.formal-cn {
+ max-width: 320px;
+ display: flex;
+ flex-direction: column;
+ gap: 14px;
+ text-align: center;
+}
+.fc-time {
+ font-family: var(--font-number);
+ font-size: 10px;
+ letter-spacing: 0.14em;
+ color: var(--c-muted);
+}
+.fc-line {
+ margin: 0;
+ font-family: var(--font-serif);
+ font-weight: 700;
+ font-size: 18px;
+ line-height: 2;
+ letter-spacing: 0.06em;
+ color: var(--c-ink);
+ white-space: pre-wrap;
+}
+.fc-line-2 {
+ font-size: 15px;
+ font-weight: 400;
+ color: var(--c-ink-soft);
+}
+.fc-note {
+ font-family: var(--font-serif);
+ font-size: 10px;
+ letter-spacing: 0.14em;
+ color: var(--c-muted);
+}
+/* 胶片相纸背书 */
+.formal-kd {
+ position: relative;
+ max-width: 320px;
+ width: 100%;
+ padding: 26px 24px 34px;
+ background: var(--c-card);
+ border-radius: 8px;
+ box-shadow: 0 14px 34px rgba(56, 48, 42, 0.14);
+ background-image: repeating-linear-gradient(180deg, transparent 0 30px, rgba(var(--c-line-rgb), 0.14) 30px 31px);
+ text-align: center;
+}
+.fk-head {
+ display: block;
+ font-size: 11px;
+ letter-spacing: 0.3em;
+ color: var(--c-muted);
+ margin-bottom: 14px;
+}
+.fk-line {
+ margin: 0 0 10px;
+ font-size: 13.5px;
+ line-height: 2.2;
+ letter-spacing: 0.06em;
+ color: var(--c-ink-soft);
+ white-space: pre-wrap;
+}
+.fk-stamp {
+ position: absolute;
+ right: 14px;
+ bottom: 10px;
+ font-family: var(--font-number);
+ font-size: 12px;
+ color: #ff9a3c;
+ text-shadow: 0 0 6px rgba(255, 130, 30, 0.6);
+}
+/* 文艺引言 */
+.formal-ah {
+ max-width: 300px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 18px;
+ text-align: center;
+}
+.fa-num {
+ font-family: var(--font-display);
+ font-size: 22px;
+ color: var(--c-muted);
+}
+.fa-line {
+ margin: 0;
+ font-family: var(--font-serif);
+ font-size: 15px;
+ line-height: 2.3;
+ letter-spacing: 0.14em;
+ color: var(--c-ink);
+ white-space: pre-wrap;
+}
+.fa-line-2 {
+ font-size: 13px;
+ color: var(--c-ink-soft);
+}
+/* 旅行签证页 */
+.formal-pp {
+ position: relative;
+ max-width: 320px;
+ width: 100%;
+ padding: 30px 24px 26px;
+ background: var(--c-card);
+ border: 1px solid rgba(var(--c-primary-rgb), 0.3);
+ border-radius: 10px;
+ box-shadow: 0 14px 36px rgba(44, 54, 64, 0.14);
+}
+.fp-visa {
+ position: absolute;
+ right: 14px;
+ top: 12px;
+ padding: 4px 9px;
+ font-family: var(--font-number);
+ font-size: 10px;
+ letter-spacing: 0.14em;
+ color: #b5493f;
+ border: 2px solid #b5493f;
+ border-radius: 5px;
+ transform: rotate(8deg);
+ opacity: 0.85;
+}
+.fp-line {
+ margin: 0 0 12px;
+ font-size: 13px;
+ line-height: 2.1;
+ letter-spacing: 0.05em;
+ color: var(--c-ink-soft);
+ white-space: pre-wrap;
+}
+.fp-foot {
+ display: block;
+ margin-top: 6px;
+ font-family: var(--font-number);
+ font-size: 10px;
+ letter-spacing: 0.2em;
+ color: var(--c-primary);
+}
+/* 手账便签 */
+.formal-sb {
+ position: relative;
+ max-width: 310px;
+ width: 100%;
+ padding: 34px 26px 26px;
+ background: var(--c-card);
+ border-radius: 4px;
+ transform: rotate(-1deg);
+ box-shadow: 0 12px 30px rgba(69, 58, 48, 0.16);
+ background-image: repeating-linear-gradient(180deg, transparent 0 32px, rgba(var(--c-line-rgb), 0.35) 32px 33px);
+}
+.fs-clip {
+ position: absolute;
+ left: 22px;
+ top: -12px;
+ width: 14px;
+ height: 34px;
+ border: 3px solid #8aa88a;
+ border-radius: 8px 8px 3px 3px;
+ border-bottom: none;
+ opacity: 0.85;
+}
+.fs-line {
+ margin: 0 0 10px;
+ font-family: var(--font-liujian);
+ font-size: 16px;
+ line-height: 2;
+ color: var(--c-ink-soft);
+ white-space: pre-wrap;
+}
+/* Y2K 对话框 */
+.formal-yk {
+ max-width: 320px;
+ width: 100%;
+ border: 2px solid #9088b8;
+ border-radius: 10px;
+ background: var(--c-card);
+ box-shadow: 6px 8px 0 rgba(122, 74, 224, 0.16), 0 16px 40px rgba(84, 74, 112, 0.2);
+ overflow: hidden;
+}
+.fy-bar {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 6px 10px;
+ background: linear-gradient(90deg, #7a4ae0, #4a90e0 55%, #4adce0);
+ color: #fff;
+ font-family: var(--font-pixel);
+ font-size: 10px;
+}
+.fy-bar i {
+ width: 15px;
+ height: 15px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 8px;
+ font-style: normal;
+ background: rgba(255, 255, 255, 0.92);
+ color: #544a70;
+ border-radius: 3px;
+}
+.fy-body {
+ padding: 18px 18px 16px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 8px;
+}
+.fy-line {
+ margin: 0;
+ font-size: 13px;
+ line-height: 2;
+ letter-spacing: 0.04em;
+ color: var(--c-ink-soft);
+ white-space: pre-wrap;
+ text-align: center;
+}
+.fy-btn {
+ margin-top: 8px;
+ padding: 5px 22px;
+ font-family: var(--font-pixel);
+ font-size: 11px;
+ color: var(--c-on-primary);
+ background: var(--c-primary);
+ border-radius: 5px;
+ box-shadow: 2px 3px 0 rgba(84, 74, 112, 0.4);
+}
+
+/* ============================================================
+ 新模板:落款 + 区块微调 + 照片滤镜
+ ============================================================ */
+.elf-ink {
+ font-family: var(--font-kai);
+ font-size: 12px;
+ letter-spacing: 0.3em;
+ color: var(--c-ink-soft);
+}
+.elf-ink b {
+ display: inline-flex;
+ width: 20px;
+ height: 20px;
+ align-items: center;
+ justify-content: center;
+ margin: 0 6px;
+ font-size: 11px;
+ font-weight: 400;
+ color: #fdf6f0;
+ background: #b5493f;
+ border-radius: 2px;
+ vertical-align: middle;
+}
+.elf-cn {
+ font-family: var(--font-display);
+ font-weight: 700;
+ letter-spacing: 0.3em;
+ color: var(--c-primary);
+}
+.elf-kd {
+ font-family: var(--font-number);
+ letter-spacing: 0.2em;
+ color: var(--c-primary);
+}
+.elf-ah {
+ font-family: var(--font-display);
+ font-style: italic;
+ font-size: 13px;
+ letter-spacing: 0.24em;
+}
+.elf-pp {
+ font-family: var(--font-number);
+ letter-spacing: 0.2em;
+ color: var(--c-primary);
+}
+.elf-sb {
+ font-family: var(--font-liujian);
+ font-size: 14px;
+ color: var(--c-ink-soft);
+}
+.elf-yk {
+ font-family: var(--font-pixel);
+ font-size: 11px;
+ letter-spacing: 0.12em;
+ color: var(--c-primary);
+}
+
+/* 照片滤镜与区块气质 */
+html[data-theme='inkwash'] .preview-img,
+html[data-theme='inkwash'] .ending-photo img {
+ filter: saturate(0.8) contrast(1.03);
+}
+html[data-theme='kodak'] .preview-img,
+html[data-theme='kodak'] .ending-photo img {
+ filter: sepia(0.16) saturate(1.14) contrast(1.02);
+}
+html[data-theme='cinema'] .preview-img,
+html[data-theme='cinema'] .ending-photo img {
+ filter: sepia(0.12) saturate(1.1);
+}
+html[data-theme='arthouse'] .preview-img,
+html[data-theme='arthouse'] .ending-photo img {
+ filter: saturate(0.82) contrast(1.03);
+}
+html[data-theme='y2k'] .preview-img {
+ filter: saturate(1.15) contrast(1.02);
+}
+/* 日程/日历微调 */
+html[data-theme='inkwash'] .schedule-time,
+html[data-theme='inkwash'] .schedule-event {
+ font-family: var(--font-kai);
+}
+html[data-theme='inkwash'] .schedule-node i {
+ background: #b5493f;
+}
+html[data-theme='cinema'] .schedule-time {
+ font-family: var(--font-number);
+ color: var(--c-primary);
+ font-weight: 700;
+}
+html[data-theme='kodak'] .schedule-time {
+ font-family: var(--font-number);
+ color: var(--c-primary);
+}
+html[data-theme='passport'] .schedule-row {
+ border: 1px dashed rgba(var(--c-primary-rgb), 0.35);
+ border-radius: 8px;
+ padding: 10px 12px;
+ margin-bottom: 10px;
+ background: var(--c-card);
+}
+html[data-theme='passport'] .schedule-time {
+ font-family: var(--font-number);
+ color: var(--c-primary);
+}
+html[data-theme='scrapbook'] .schedule-row {
+ background: var(--c-card);
+ border-radius: 8px;
+ padding: 10px 12px;
+ margin-bottom: 10px;
+ box-shadow: 0 4px 12px rgba(69, 58, 48, 0.1);
+}
+html[data-theme='scrapbook'] .schedule-time,
+html[data-theme='scrapbook'] .schedule-event {
+ font-family: var(--font-longcang);
+}
+html[data-theme='y2k'] .schedule-row {
+ border: 2px solid #b8b0d8;
+ border-radius: 8px;
+ padding: 10px 12px;
+ margin-bottom: 10px;
+ background: var(--c-card);
+}
+html[data-theme='y2k'] .schedule-time {
+ font-family: var(--font-pixel);
+ color: var(--c-primary);
+}
+html[data-theme='arthouse'] .schedule-row {
+ border-bottom: 1px solid rgba(var(--c-line-rgb), 0.45);
+ padding-bottom: 13px;
+}
+html[data-theme='arthouse'] .schedule-time {
+ font-family: var(--font-display);
+ font-style: italic;
+}
+
+/* ==================== 主题专属 Loading 屏 ====================
+ 底色/印记已走 --c-* 变量(风格包自动跟色),此处给完整模板
+ 定制形态:印记形状、装饰显隐、专属小动画。 */
+
+/* 现代/极简类主题收起古典花瓣星光 */
+html:is(
+ [data-theme='magazine'], [data-theme='newspaper'], [data-theme='pixel'],
+ [data-theme='zen'], [data-theme='inkwash'], [data-theme='cinema'],
+ [data-theme='kodak'], [data-theme='arthouse'], [data-theme='passport'],
+ [data-theme='y2k']
+) :is(.boot-petal, .boot-spark) {
+ display: none;
+}
+/* 方形印记主题不需要旋转圆环 */
+html:is(
+ [data-theme='magazine'], [data-theme='newspaper'], [data-theme='pixel'],
+ [data-theme='arthouse'], [data-theme='scrapbook'], [data-theme='y2k']
+) .boot-seal-ring {
+ display: none;
+}
+
+/* 夜空风格包:压暗底色亮斑 */
+html[data-theme='night'] .boot-loading {
+ background:
+ radial-gradient(ellipse at 50% 38%, rgba(64, 70, 104, 0.75), transparent 60%),
+ linear-gradient(165deg, #232842 0%, #171b30 100%);
+}
+html[data-theme='night'] .boot-seal {
+ background: linear-gradient(160deg, #2e3452, #20253e);
+}
+
+/* 老中式:宫墙红底 + 泥金 */
+html[data-theme='guofeng-old'] .boot-loading {
+ background:
+ radial-gradient(ellipse at 50% 36%, rgba(210, 80, 92, 0.5), transparent 58%),
+ linear-gradient(170deg, #8c2430 0%, #6e1a24 55%, #571219 100%);
+}
+html[data-theme='guofeng-old'] .boot-seal {
+ color: #f5d9a0;
+ background: radial-gradient(circle at 36% 30%, rgba(255, 236, 200, 0.2), transparent 50%), linear-gradient(160deg, #a63846, #86222e);
+ border-color: rgba(201, 162, 74, 0.8);
+ box-shadow: inset 0 0 0 5px rgba(201, 162, 74, 0.16), 0 14px 34px rgba(30, 6, 10, 0.5);
+}
+html[data-theme='guofeng-old'] .boot-loading :is(.boot-kicker, .boot-hint, .boot-petal) { color: #e7c584; }
+html[data-theme='guofeng-old'] .boot-names { color: #f7e7c3; }
+html[data-theme='guofeng-old'] .boot-names span { color: #d8ab5e; }
+html[data-theme='guofeng-old'] .boot-frame { border-color: rgba(216, 171, 94, 0.55); }
+html[data-theme='guofeng-old'] .boot-seal-ring-a { border-top-color: rgba(232, 197, 132, 0.85); }
+html[data-theme='guofeng-old'] .boot-dots i { background: #e7c584; }
+
+/* 新中式:月洞窗细圈 */
+html[data-theme='guofeng-new'] .boot-seal {
+ background: transparent;
+ border: 1.5px solid rgba(var(--c-primary-rgb), 0.6);
+ box-shadow: inset 0 0 0 4px rgba(var(--c-primary-rgb), 0.08);
+}
+
+/* 杂志:黑方块字标 */
+html[data-theme='magazine'] .boot-seal {
+ border-radius: 6px;
+ background: #1f1c19;
+ border-color: #1f1c19;
+ color: #f5f2ea;
+ font-family: var(--font-display);
+ font-style: italic;
+ box-shadow: 0 14px 30px rgba(31, 28, 25, 0.35);
+}
+html[data-theme='magazine'] .boot-kicker { letter-spacing: 0.6em; }
+html[data-theme='magazine'] .boot-frame { border-color: rgba(31, 28, 25, 0.6); }
+html[data-theme='magazine'] .boot-rule :is(span, i) { color: #1f1c19; }
+
+/* 报刊:双线方框铅字 */
+html[data-theme='newspaper'] .boot-seal {
+ border-radius: 2px;
+ background: var(--c-paper);
+ border: 2px solid #262420;
+ outline: 1px solid #262420;
+ outline-offset: 3px;
+ color: #262420;
+ box-shadow: none;
+}
+html[data-theme='newspaper'] .boot-frame { border-color: rgba(38, 36, 32, 0.55); }
+
+/* 像素:硬阴影方块 + 步进闪烁 */
+html[data-theme='pixel'] .boot-seal {
+ border-radius: 0;
+ border: 3px solid var(--c-ink);
+ background: var(--c-card);
+ box-shadow: 6px 6px 0 rgba(var(--c-primary-rgb), 0.8);
+ font-family: var(--font-pixel);
+ animation: boot-seal-in 0.85s steps(5) both, bootPixelBlink 1.2s steps(2) 0.85s infinite;
+}
+html[data-theme='pixel'] .boot-loading :is(.boot-kicker, .boot-hint) { font-family: var(--font-pixel); letter-spacing: 0.3em; }
+html[data-theme='pixel'] .boot-dots i {
+ border-radius: 0;
+ width: 8px;
+ height: 8px;
+ animation-timing-function: steps(2);
+}
+html[data-theme='pixel'] .boot-frame { border-width: 0; }
+html[data-theme='pixel'] .boot-frame-tl { border-top-width: 3px; border-left-width: 3px; border-color: var(--c-ink); }
+html[data-theme='pixel'] .boot-frame-tr { border-top-width: 3px; border-right-width: 3px; border-color: var(--c-ink); }
+html[data-theme='pixel'] .boot-frame-bl { border-bottom-width: 3px; border-left-width: 3px; border-color: var(--c-ink); }
+html[data-theme='pixel'] .boot-frame-br { border-bottom-width: 3px; border-right-width: 3px; border-color: var(--c-ink); }
+@keyframes bootPixelBlink {
+ 50% { box-shadow: 6px 6px 0 rgba(var(--c-line-rgb), 0.8); }
+}
+
+/* 禅意:无底细圈,一切从简 */
+html[data-theme='zen'] .boot-seal {
+ background: transparent;
+ border: 1px solid rgba(var(--c-primary-rgb), 0.5);
+ box-shadow: none;
+ font-weight: 400;
+}
+html[data-theme='zen'] :is(.boot-frame, .boot-glow) { display: none; }
+html[data-theme='zen'] .boot-seal-ring-b { display: none; }
+
+/* 水墨:墨圈朱点 */
+html[data-theme='inkwash'] .boot-seal {
+ background: radial-gradient(circle at 40% 32%, rgba(255, 255, 255, 0.5), transparent 50%), var(--c-paper);
+ border: 2px solid rgba(58, 63, 58, 0.75);
+ color: #3a3f3a;
+ box-shadow: inset 0 0 14px rgba(58, 63, 58, 0.14);
+}
+html[data-theme='inkwash'] .boot-seal-ring-a { border-top-color: rgba(58, 63, 58, 0.6); }
+html[data-theme='inkwash'] .boot-dots i { background: #b5493f; }
+
+/* 电影:放映厅黑 + 倒计时扫描圈 */
+html[data-theme='cinema'] .boot-loading {
+ background:
+ radial-gradient(ellipse at 50% 34%, rgba(90, 70, 40, 0.5), transparent 58%),
+ linear-gradient(170deg, #191512 0%, #0e0c0a 100%);
+}
+html[data-theme='cinema'] .boot-seal {
+ background: #0e0c0a;
+ border: 2px solid rgba(240, 226, 200, 0.85);
+ color: #f0e2c8;
+ box-shadow: 0 0 40px rgba(240, 226, 200, 0.12);
+}
+html[data-theme='cinema'] .boot-seal-wrap::before {
+ content: '';
+ position: absolute;
+ inset: -14px;
+ border-radius: 50%;
+ background: conic-gradient(from 0deg, rgba(240, 226, 200, 0.4), transparent 40deg);
+ animation: boot-ring-spin 1.4s linear infinite;
+ z-index: -1;
+}
+html[data-theme='cinema'] .boot-loading :is(.boot-kicker, .boot-hint) { color: #cbb27e; }
+html[data-theme='cinema'] .boot-names { color: #f0e2c8; }
+html[data-theme='cinema'] .boot-names span { color: #b8322e; }
+html[data-theme='cinema'] .boot-frame { border-color: rgba(240, 226, 200, 0.4); }
+html[data-theme='cinema'] .boot-dots i { background: #cbb27e; }
+
+/* 柯达胶卷:齿孔胶片盘旋转 */
+html[data-theme='kodak'] .boot-seal {
+ background: #2b2723;
+ border: 2px solid #2b2723;
+ color: #f8d75c;
+ font-family: var(--font-number);
+ letter-spacing: 0.06em;
+}
+html[data-theme='kodak'] .boot-seal-wrap::before {
+ content: '';
+ position: absolute;
+ inset: -12px;
+ border-radius: 50%;
+ border: 7px dotted rgba(43, 39, 35, 0.85);
+ animation: boot-ring-spin 3.2s linear infinite;
+}
+html[data-theme='kodak'] .boot-seal-ring { display: none; }
+html[data-theme='kodak'] .boot-kicker { color: #b3541e; }
+
+/* 艺术画廊:白底黑细框 */
+html[data-theme='arthouse'] .boot-seal {
+ border-radius: 0;
+ background: var(--c-card);
+ border: 1.5px solid #2c2a26;
+ color: #2c2a26;
+ font-family: var(--font-display);
+ font-style: italic;
+ box-shadow: 10px 10px 24px rgba(44, 42, 38, 0.12);
+}
+
+/* 护照通行:钢印虚线圈 */
+html[data-theme='passport'] .boot-seal {
+ background: transparent;
+ border: 2px dashed rgba(46, 74, 104, 0.7);
+ color: #2e4a68;
+ box-shadow: none;
+ animation: boot-seal-in 0.85s cubic-bezier(0.22, 1, 0.36, 1) both, boot-ring-spin 22s linear 0.9s infinite;
+}
+html[data-theme='passport'] .boot-seal-ring-a { border-top-color: rgba(46, 74, 104, 0.6); }
+html[data-theme='passport'] .boot-kicker { letter-spacing: 0.52em; }
+
+/* 手帐拼贴:白贴纸 + 和纸胶带 */
+html[data-theme='scrapbook'] .boot-seal {
+ border-radius: 10px;
+ background: #fffdf6;
+ border: 1px solid rgba(120, 90, 55, 0.25);
+ transform: rotate(-4deg);
+ box-shadow: 0 10px 24px rgba(120, 90, 55, 0.2);
+}
+html[data-theme='scrapbook'] .boot-seal-wrap::before {
+ content: '';
+ position: absolute;
+ top: -4px;
+ left: 50%;
+ width: 64px;
+ height: 18px;
+ margin-left: -32px;
+ background: rgba(196, 122, 90, 0.4);
+ transform: rotate(3deg);
+ z-index: 3;
+}
+
+/* Y2K:糖果渐变圆 + 外发光 */
+html[data-theme='y2k'] .boot-loading {
+ background:
+ radial-gradient(ellipse at 24% 22%, rgba(122, 74, 224, 0.22), transparent 48%),
+ radial-gradient(ellipse at 78% 74%, rgba(74, 174, 224, 0.25), transparent 50%),
+ linear-gradient(165deg, #ece6fa 0%, #e0ecfa 45%, #f6e2f4 100%);
+}
+html[data-theme='y2k'] .boot-seal {
+ background: linear-gradient(140deg, #8a5cf0, #4aaee0 55%, #e879c8);
+ border: 2px solid rgba(255, 255, 255, 0.85);
+ color: #fff;
+ box-shadow: 0 0 34px rgba(122, 74, 224, 0.45);
+}
+html[data-theme='y2k'] .boot-dots i { background: #7a4ae0; }
diff --git a/vite-tailwindcss/src/utils/calendarStyles.js b/vite-tailwindcss/src/utils/calendarStyles.js
new file mode 100644
index 0000000..0b192a9
--- /dev/null
+++ b/vite-tailwindcss/src/utils/calendarStyles.js
@@ -0,0 +1,64 @@
+/**
+ * 日历(Save The Date 屏)视觉模板
+ * - 配置值 'auto'(默认)= 跟随整站风格模板的推荐样式
+ * - 也可手动指定任意样式,与主题解耦
+ * 样式类挂在 .calendar-card 上:cal-style-
(CSS 见 theme-packs.css)
+ */
+export const DEFAULT_CALENDAR_STYLE = 'auto'
+
+export const CALENDAR_STYLES = [
+ { key: 'classic', label: '香槟金卡', desc: '经典白卡金线(默认样式)' },
+ { key: 'french', label: '法式蕾丝', desc: '扇贝蕾丝边 · 花体粉金' },
+ { key: 'mono', label: '瑞士网格', desc: '粗黑标题 · 红黑双色' },
+ { key: 'picnic', label: '野餐格纹', desc: '绿白格布 · 樱桃婚期' },
+ { key: 'greenhouse', label: '玻璃温室', desc: '尖顶花房 · 玻璃格线' },
+ { key: 'herbarium', label: '植物标本', desc: '压花蕨叶 · 胶带标签' },
+ { key: 'fullmoon', label: '林间满月', desc: '夜空满月 · 桂枝剪影' },
+ { key: 'gardensign', label: '花园吊牌', desc: '木牌麻绳 · 白漆手写' },
+ { key: 'starry', label: '星夜弯月', desc: '闪烁星空 · 金月婚期' },
+ { key: 'aquarelle', label: '水彩晕染', desc: '多彩晕斑 · 水痕婚期' },
+ { key: 'hanami', label: '樱吹雪', desc: '飘落花瓣 · 樱花婚期' },
+ { key: 'redgold', label: '中式红金', desc: '宫墙红底 · 通栏金幅' },
+ { key: 'neochina', label: '月洞窗', desc: '圆窗题字 · 黛绿玉环' },
+ { key: 'ink', label: '水墨素卡', desc: '文人左排 · 朱砂闲章' },
+ { key: 'paper', label: '报刊粗格', desc: '表格网格 · 铅字排印' },
+ { key: 'magazine', label: '杂志内页', desc: '巨字刊号 · 黑白对比' },
+ { key: 'pixel', label: '像素方格', desc: '游戏窗口 · 标题栏' },
+ { key: 'minimal', label: '极简数字', desc: '非对称 · 超大细字' },
+ { key: 'journal', label: '手账贴纸', desc: '胶带贴纸 · 手绘圈' },
+ { key: 'ticket', label: '复古票根', desc: '票号条码 · 撕票口' },
+ { key: 'boarding', label: '登机牌', desc: '航司蓝条 · 舱位信息' },
+ { key: 'film', label: '胶片场记', desc: '上下齿孔 · 对焦婚期' },
+ { key: 'marquee', label: '影院灯牌', desc: '灯泡流转 · 金星婚期' },
+ { key: 'y2k', label: '千禧玻璃', desc: '玻璃拟态 · 光泽扫过' },
+ { key: 'gallery', label: '画廊白盒', desc: '画框标签 · 红点已定' },
+]
+
+/** 各风格模板的专属日历样式(20 主题一对一,ticket 保留为手动可选) */
+const THEME_CALENDAR_MAP = {
+ champagne: 'classic',
+ french: 'french',
+ modern: 'mono',
+ forest: 'picnic',
+ night: 'starry',
+ watercolor: 'aquarelle',
+ sakura: 'hanami',
+ 'guofeng-old': 'redgold',
+ 'guofeng-new': 'neochina',
+ inkwash: 'ink',
+ newspaper: 'paper',
+ magazine: 'magazine',
+ pixel: 'pixel',
+ zen: 'minimal',
+ scrapbook: 'journal',
+ passport: 'boarding',
+ cinema: 'marquee',
+ kodak: 'film',
+ arthouse: 'gallery',
+ y2k: 'y2k',
+}
+
+export function resolveCalendarStyle(value, themeKey) {
+ if (value && value !== 'auto' && CALENDAR_STYLES.some((s) => s.key === value)) return value
+ return THEME_CALENDAR_MAP[themeKey] || 'classic'
+}
diff --git a/vite-tailwindcss/src/utils/themes.js b/vite-tailwindcss/src/utils/themes.js
index f1cd362..dcacaf3 100644
--- a/vite-tailwindcss/src/utils/themes.js
+++ b/vite-tailwindcss/src/utils/themes.js
@@ -33,6 +33,16 @@ export const SITE_THEMES = [
desc: '深蓝烫金 · 暗色主题 · 星月点缀',
primary: '#c9a96a', line: '#8fa3c0', bg: '#101b2e',
},
+ {
+ key: 'watercolor', kind: 'pack', label: '水彩画境',
+ desc: '清透淡彩 · 晕染纹理 · 柔圆卡片',
+ primary: '#7f9bb3', line: '#a8c0d0', bg: '#f7fafc',
+ },
+ {
+ key: 'sakura', kind: 'pack', label: '樱花物语',
+ desc: '粉白渐彩 · 花瓣纷落 · 春日气息',
+ primary: '#d98a9e', line: '#e8b4c2', bg: '#fdf5f7',
+ },
// ———— 完整模板 ————
{
key: 'guofeng-new', kind: 'layout', label: '新中式',
@@ -61,8 +71,43 @@ export const SITE_THEMES = [
},
{
key: 'zen', kind: 'layout', label: '极简主义',
- desc: '黑白留白 · 细线 · 轴线排版',
- primary: '#2a2a28', line: '#8f8d88', bg: '#fafaf8',
+ desc: '暖白留白 · 细线 · 轴线排版',
+ primary: '#57503f', line: '#a89f8e', bg: '#faf7f2',
+ },
+ {
+ key: 'inkwash', kind: 'layout', label: '水墨山水',
+ desc: '宣纸墨韵 · 卷轴排版 · 朱砂印',
+ primary: '#3a3f3a', line: '#8a9088', bg: '#f6f6f2',
+ },
+ {
+ key: 'cinema', kind: 'layout', label: '复古电影',
+ desc: '上映海报 · 主演字幕 · 场记章节',
+ primary: '#b8322e', line: '#d4a24a', bg: '#f2e8d8',
+ },
+ {
+ key: 'kodak', kind: 'layout', label: '胶片日记',
+ desc: '胶卷齿孔 · 日期水印 · 柯达暖调',
+ primary: '#e0782e', line: '#3c3a34', bg: '#faf6ec',
+ },
+ {
+ key: 'arthouse', kind: 'layout', label: '文艺影调',
+ desc: '对称构图 · 分幕章节 · 衬线留白',
+ primary: '#4a4640', line: '#9a948a', bg: '#f4f1ea',
+ },
+ {
+ key: 'passport', kind: 'layout', label: '环球旅行',
+ desc: '护照登机牌 · 邮戳航线 · 出发到永远',
+ primary: '#2e4a68', line: '#b08a4a', bg: '#f2f0e8',
+ },
+ {
+ key: 'scrapbook', kind: 'layout', label: '手账拼贴',
+ desc: '胶带贴纸 · 牛皮纸 · 手写标签',
+ primary: '#c47a5a', line: '#8aa88a', bg: '#faf4e8',
+ },
+ {
+ key: 'y2k', kind: 'layout', label: '千禧蒸汽波',
+ desc: '复古窗口 · 渐变镜面字 · 星星光标',
+ primary: '#7a4ae0', line: '#4adce0', bg: '#ece8f8',
},
]
@@ -79,6 +124,7 @@ const LEGACY_THEME_MAP = {
ocean: 'night',
lilac: 'french',
sunset: 'champagne',
+ filmnoir: 'arthouse',
}
export function normalizeSiteTheme(key) {
@@ -102,13 +148,151 @@ export function isDarkTheme(key) {
return !!siteThemeMeta(key).dark
}
+/* ============================================================
+ 主题特效色板(fx):点赞爱心 / 高光 / 花瓣 / 漂浮爱心
+ 未定义专属色板的主题回落到默认(香槟婚礼暖彩)
+ ============================================================ */
+const DEFAULT_FX = {
+ like: [
+ '#ff2442', '#ff2d55', '#ff4770', '#ff6b8a',
+ '#f472b6', '#ec4899', '#e879f9', '#c084fc',
+ '#a78bfa', '#818cf8', '#60a5fa', '#38bdf8',
+ '#2dd4bf', '#34d399', '#fbbf24', '#f59e0b',
+ '#fb923c', '#a88c6b', '#d4a574', '#e8b4b8',
+ '#f43f5e', '#fb7185', '#fda4af',
+ ],
+ likeGlow: [
+ '#ff8da6', '#ffb0c4', '#f9a8d4', '#e9d5ff',
+ '#c4b5fd', '#93c5fd', '#6ee7b7', '#fde68a',
+ '#fdba74', '#f5d0b0', '#ffffff',
+ ],
+ petal: ['#f7dce3', '#fbeee3', '#f3c9d6', '#efdcc8', '#f9e7d6'],
+ bubble: ['#c9b08a', '#e2b3c0', '#d4af37', '#e8c9d2'],
+}
+
+const THEME_FX = {
+ night: {
+ like: ['#c9a96a', '#e8cf96', '#8fa3c0', '#d4b060', '#f0e0b0', '#a8b8d8'],
+ likeGlow: ['#f5e6b8', '#ffffff', '#c7d4ea'],
+ petal: ['#c9a96a', '#8fa3c0', '#e8cf96', '#5a7099', '#d8c8a0'],
+ bubble: ['#c9a96a', '#8fa3c0', '#ac9060'],
+ },
+ 'guofeng-old': {
+ like: ['#c9414e', '#e05a66', '#c9a24a', '#e8c878', '#a8323e', '#f0a0a0'],
+ likeGlow: ['#f7e7c3', '#ffd9d0', '#ffe9a8'],
+ petal: ['#f2c4c4', '#e8a8a8', '#e8d0a0', '#f0dcc8'],
+ bubble: ['#c9a24a', '#d98a8a', '#b84a55'],
+ },
+ 'guofeng-new': {
+ like: ['#486156', '#6f8f80', '#b5493f', '#b0885a', '#8fae9c'],
+ likeGlow: ['#d8e4dc', '#f0d8d0', '#e8d8c0'],
+ petal: ['#d8e4d8', '#e8ded0', '#f0d0c8', '#dce8dc'],
+ bubble: ['#8fae9c', '#c9a080', '#b5493f'],
+ },
+ magazine: {
+ like: ['#1f1c19', '#4a453e', '#8a8378', '#b8ac9c', '#d4c8b8'],
+ likeGlow: ['#ffffff', '#e8e0d4'],
+ petal: ['#e8e2d8', '#d8d2c6', '#c8c2b6'],
+ bubble: ['#8a8378', '#b0a898'],
+ },
+ newspaper: {
+ like: ['#2b2822', '#57524a', '#8a8478', '#6b675e', '#a8a294'],
+ likeGlow: ['#f6f3ea', '#dcd6c8'],
+ petal: ['#e8e2d2', '#dcd6c4', '#d0cab8'],
+ bubble: ['#8a8478', '#a8a294'],
+ },
+ pixel: {
+ like: ['#c94f7c', '#5f9ea0', '#e8a03c', '#7a4ae0', '#4aa34a', '#e0557a'],
+ likeGlow: ['#ffd9e8', '#c8f0f0', '#ffe9b8'],
+ petal: ['#f7c8da', '#c0e4e4', '#f5e0b8', '#e0d0f5'],
+ bubble: ['#c94f7c', '#5f9ea0', '#e8a03c'],
+ },
+ zen: {
+ like: ['#57503f', '#7a7260', '#a89f8e', '#c4bcac'],
+ likeGlow: ['#fffef9', '#ede8dc'],
+ petal: ['#ece7dc', '#e0dace', '#d6cfc0'],
+ bubble: ['#a89f8e', '#c0b8a8'],
+ },
+ watercolor: {
+ like: ['#7f9bb3', '#a8c0d0', '#c8a8c0', '#88b8a8', '#d0b8d8'],
+ likeGlow: ['#e8f0f8', '#ffffff'],
+ petal: ['#dce8f0', '#e8dce8', '#d8e8e0', '#f0e8f0'],
+ bubble: ['#a8c0d0', '#c8a8c0', '#88b8a8'],
+ },
+ sakura: {
+ like: ['#d98a9e', '#e8a8b8', '#f0c0cc', '#c67689', '#f5d5dc'],
+ likeGlow: ['#ffe4ec', '#ffffff'],
+ petal: ['#f8d5de', '#f5c8d4', '#fce4ea', '#f0b8c8'],
+ bubble: ['#e8b4c2', '#d98a9e', '#f0c0cc'],
+ },
+ inkwash: {
+ like: ['#3a3f3a', '#5c625c', '#8a9088', '#b5493f', '#b8bcb4'],
+ likeGlow: ['#eef0ec', '#ffffff'],
+ petal: ['#dfe2dc', '#d0d4cc', '#e8eae4'],
+ bubble: ['#8a9088', '#b5493f'],
+ },
+ cinema: {
+ like: ['#b8322e', '#d4552e', '#d4a24a', '#8c2320', '#e8c878'],
+ likeGlow: ['#ffe9c8', '#ffd9c0'],
+ petal: ['#f0dcc0', '#e8d0b0', '#f5e6cc'],
+ bubble: ['#d4a24a', '#b8322e'],
+ },
+ kodak: {
+ like: ['#e0782e', '#e89a3c', '#c85a28', '#f0b860', '#a84a20'],
+ likeGlow: ['#ffe0b8', '#ffefd0'],
+ petal: ['#f5dcbe', '#f0d0a8', '#f8e8cc'],
+ bubble: ['#e0782e', '#e89a3c'],
+ },
+ arthouse: {
+ like: ['#4a4640', '#6e6a62', '#9a948a', '#b8b2a6'],
+ likeGlow: ['#f4f1ea', '#ffffff'],
+ petal: ['#e6e2d8', '#dcd8cc', '#d0ccc0'],
+ bubble: ['#9a948a', '#b8b2a6'],
+ },
+ passport: {
+ like: ['#2e4a68', '#4a6a8c', '#b08a4a', '#6a88a8', '#d0a860'],
+ likeGlow: ['#e0ecf5', '#f0e4c8'],
+ petal: ['#d8e2ec', '#e8e0cc', '#ccd8e4'],
+ bubble: ['#4a6a8c', '#b08a4a'],
+ },
+ scrapbook: {
+ like: ['#c47a5a', '#8aa88a', '#d8a848', '#a86a8c', '#6a9ab0'],
+ likeGlow: ['#ffe8d0', '#e0f0e0'],
+ petal: ['#f0dcc8', '#d8e8d0', '#f5e8c8', '#e8d0dc'],
+ bubble: ['#c47a5a', '#8aa88a', '#d8a848'],
+ },
+ y2k: {
+ like: ['#7a4ae0', '#4adce0', '#e04ad0', '#8c8cff', '#4a90e0'],
+ likeGlow: ['#e0d8ff', '#c8f8ff', '#ffd8f8'],
+ petal: ['#e0d8f8', '#d0f0f8', '#f0d8f0'],
+ bubble: ['#7a4ae0', '#4adce0', '#e04ad0'],
+ },
+}
+
+/** 取主题特效色板(点赞/花瓣/漂浮爱心) */
+export function themeFx(key) {
+ const k = normalizeSiteTheme(key)
+ return { ...DEFAULT_FX, ...(THEME_FX[k] || {}) }
+}
+
/** 应用主题到整页(html[data-theme]),前台按配置、后台跟随编辑值 */
+const THEME_CACHE_KEY = 'wedding-site-theme'
+
export function applySiteTheme(key) {
const k = normalizeSiteTheme(key)
document.documentElement.dataset.theme = k
+ try { localStorage.setItem(THEME_CACHE_KEY, k) } catch { /* 隐私模式等场景忽略 */ }
if (k === 'pixel') ensurePixelCjkFont()
}
+/**
+ * 上次访问缓存的主题:配置接口返回前先用它渲染 Loading 屏与首屏,
+ * 二次访问即可看到专属主题 Loading,且避免主题闪变(首次访问回退默认)。
+ */
+export function cachedSiteTheme() {
+ try { return normalizeSiteTheme(localStorage.getItem(THEME_CACHE_KEY) || DEFAULT_SITE_THEME) } catch { return DEFAULT_SITE_THEME }
+}
+
/**
* 中文像素字形按需加载:
* 本地 @fontsource 包只含 latin 子集(英文/数字像素),中日韩全量字形
diff --git a/vite-tailwindcss/src/views/admin/AdminEditor.vue b/vite-tailwindcss/src/views/admin/AdminEditor.vue
index b2cd574..b0e4d01 100644
--- a/vite-tailwindcss/src/views/admin/AdminEditor.vue
+++ b/vite-tailwindcss/src/views/admin/AdminEditor.vue
@@ -558,8 +558,8 @@
-
-
+
+
@@ -590,9 +590,73 @@
风格包=在经典排版上成套更换配色、字体与装饰纹样;完整模板=首屏封面、章节标题与尾页的排版结构也随之重构(杂志 / 报纸 / 像素 / 极简)。选择后本页即时预览配色,保存后对宾客生效。