diff --git a/.gitignore b/.gitignore index 246e0be..f4f24d4 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,11 @@ src/analysis/ARCHITECTURE.md .serena/.gitignore .serena/project.yml +debug_output.html +src/models/__pycache__/__init__.cpython-312.pyc +src/models/__pycache__/data_models.cpython-312.pyc +src/reports/__pycache__/__init__.cpython-312.pyc +src/reports/__pycache__/generators.cpython-312.pyc +src/reports/__pycache__/templates.cpython-312.pyc +src/visualization/__pycache__/__init__.cpython-312.pyc +src/visualization/__pycache__/activity_charts.cpython-312.pyc diff --git a/src/reports/templates/scrapbook/image_template.html b/src/reports/templates/scrapbook/image_template.html index 34263bc..b48c4b8 100644 --- a/src/reports/templates/scrapbook/image_template.html +++ b/src/reports/templates/scrapbook/image_template.html @@ -77,6 +77,29 @@ max-width: 1000px; margin: 0 auto; position: relative; + background: #fff; + border: 2px solid var(--ink-primary); + border-radius: 20px; + padding: 40px; + /* Stacked "Paper" Effect: Blue Shadow -> Pink Shadow -> Soft Drop Shadow */ + box-shadow: + 8px 8px 0 var(--color-blue), + 16px 16px 0 var(--color-pink), + 0 20px 40px rgba(0, 0, 0, 0.1); + } + + /* Stitching Effect */ + .container::before { + content: ""; + position: absolute; + top: 12px; + bottom: 12px; + left: 12px; + right: 12px; + border: 2px dashed var(--ink-secondary); + border-radius: 15px; + pointer-events: none; + opacity: 0.5; } /* ==================== 1. 头部设计 ==================== */ @@ -134,43 +157,57 @@ } /* ==================== 2. 统计邮票 ==================== */ - .stats-row { + /* ==================== 2. 统计区域 (新版) ==================== */ + .stats-wrapper { display: flex; - justify-content: center; - gap: 30px; + gap: 25px; margin-bottom: 40px; - flex-wrap: wrap; + align-items: stretch; + } + + .stats-grid { + flex: 2; + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 20px; } .stamp { - width: 150px; + width: 100%; + height: 100%; background: #fff; - padding: 10px; - box-shadow: 3px 3px 8px rgba(0, 0, 0, 0.05); - /* 邮票齿孔背景 */ - background-image: radial-gradient(transparent 50%, #fff 51%); - background-size: 10px 10px; - background-position: -5px -5px; + padding: 15px; + box-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1); + border: 2px solid var(--ink-primary); + border-radius: 12px; + position: relative; display: flex; flex-direction: column; align-items: center; - transition: transform 0.3s; - border: 1px solid #eee; + justify-content: center; + transition: transform 0.2s; + } + + /* 装饰性背景纹理 */ + .stamp::after { + content: ""; + position: absolute; + top: 5px; + bottom: 5px; + left: 5px; + right: 5px; + border: 1px dotted #e0e0e0; + border-radius: 8px; + pointer-events: none; } .stamp:hover { - transform: scale(1.1) rotate(0deg) !important; - z-index: 10; + transform: translateY(-2px); } .stamp-inner { - border: 1px solid var(--ink-secondary); - width: 100%; - padding: 15px 0; - display: flex; - flex-direction: column; - align-items: center; - background: radial-gradient(circle, #fff 50%, #fafafa 100%); + text-align: center; + z-index: 1; } .stamp-num { @@ -255,18 +292,21 @@ } /* ==================== 4. 活跃时段 ==================== */ + /* ==================== 4. 活跃时段 (新版) ==================== */ .highlight-section { - grid-column: span 5; + flex: 1; background: var(--color-yellow); - padding: 30px; - transform: rotate(2deg); - box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.1); + padding: 20px; + border: 2px solid var(--ink-primary); + border-radius: 20px; + box-shadow: 6px 6px 0 var(--color-pink); display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; position: relative; + background-image: repeating-linear-gradient(45deg, rgba(255, 255, 255, 0.2) 0, rgba(255, 255, 255, 0.2) 10px, transparent 10px, transparent 20px); } .tape-top { @@ -386,42 +426,59 @@ .user-card { break-inside: avoid; background: #fff; - border: 2px solid #e0e0e0; - border-radius: 12px; - padding: 20px; - margin-bottom: 25px; - box-shadow: 4px 4px 0 rgba(0, 0, 0, 0.05); + border: 2px solid var(--ink-primary); + border-radius: 16px; + padding: 24px; + margin-bottom: 30px; + /* Muted Blue-Grey Shadow */ + box-shadow: 6px 6px 0 rgba(70, 80, 100, 0.15), 6px 6px 0 1px var(--ink-primary); position: relative; display: flex; flex-direction: column; transition: transform 0.2s; + /* Very subtle grain */ + background-color: #fff; + background-image: url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)' opacity='0.03'/%3E%3C/svg%3E"); } .user-card:hover { - transform: translateY(-3px); + transform: translateY(-4px) rotate(1deg); z-index: 5; - border-color: var(--ink-primary); + box-shadow: 8px 8px 0 rgba(0, 0, 0, 0.15), 8px 8px 0 2px var(--ink-primary); } .card-tape { position: absolute; - top: -10px; + top: -12px; left: 50%; - transform: translateX(-50%); - width: 60px; - height: 18px; - background: var(--color-blue); - opacity: 0.9; + transform: translateX(-50%) rotate(-2deg); + width: 80px; + height: 24px; + background: rgba(255, 255, 255, 0.4); + /* Fallback */ + background-color: var(--color-blue); + opacity: 0.8; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + /* Jagged edges for tape look */ + mask-image: linear-gradient(135deg, transparent 5px, black 0) top left, linear-gradient(-135deg, transparent 5px, black 0) top right, linear-gradient(45deg, transparent 5px, black 0) bottom left, linear-gradient(-45deg, transparent 5px, black 0) bottom right; + mask-size: 51% 51%; + mask-repeat: no-repeat; + -webkit-mask-image: radial-gradient(circle at 2px 2px, transparent 2px, black 2.5px); + -webkit-mask-size: 100% 100%; + /* Simplify mask for compatibility */ + /* Simpler tape look since masks can be tricky across renderers */ + border-left: 2px dashed rgba(255, 255, 255, 0.3); + border-right: 2px dashed rgba(255, 255, 255, 0.3); } .user-card:nth-child(2n) .card-tape { - background: var(--color-pink); - transform: rotate(2deg); + background-color: var(--color-pink); + transform: translateX(-50%) rotate(3deg); } .user-card:nth-child(3n) .card-tape { - background: var(--color-green); - transform: rotate(-2deg); + background-color: var(--color-green); + transform: translateX(-50%) rotate(-1deg); } .user-header { @@ -494,16 +551,24 @@ .u-reason { font-family: var(--font-hand); - font-size: 0.95rem; - color: #555; + font-size: 1.05rem; + color: #444; line-height: 1.6; - text-align: justify; - background: #fafafa; - padding: 12px; - border-radius: 8px; + + /* Quote Block Style */ + background: #f8fbff; + border-left: 4px solid var(--color-blue); + padding: 12px 15px; + margin-top: 15px; + border-radius: 4px; position: relative; } + .u-reason::before { + content: ""; + /* Removed big quote mark to clean up */ + } + /* ==================== 7. 每日回响 ==================== */ .quotes-section { grid-column: span 12; @@ -704,66 +769,62 @@ -
- -
-
-
-
- - - - -
{{message_count}}
-
消息总数
-
+
+ +
+ +
+
+ + + +
{{message_count}}
+
消息总数
-
-
- - - - -
{{participant_count}}
-
参与人数
-
+
+ +
+
+ + + +
{{participant_count}}
+
参与人数
-
-
- - - - -
{{emoji_count}}
-
表情统计
-
+
+ +
+
+ + + +
{{emoji_count}}
+
表情统计
-
-
- - - - -
{{total_characters}}
-
总字符数
-
+
+ +
+
+ + + +
{{total_characters}}
+
总字符数
- -
-
-
✨ Highlight - Time
+ +
+
+
+ ✨ Highlight Time +
{{most_active_period}}
(此刻,世界色彩斑斓)
diff --git a/src/reports/templates/scrapbook/pdf_template.html b/src/reports/templates/scrapbook/pdf_template.html index 34263bc..b48c4b8 100644 --- a/src/reports/templates/scrapbook/pdf_template.html +++ b/src/reports/templates/scrapbook/pdf_template.html @@ -77,6 +77,29 @@ max-width: 1000px; margin: 0 auto; position: relative; + background: #fff; + border: 2px solid var(--ink-primary); + border-radius: 20px; + padding: 40px; + /* Stacked "Paper" Effect: Blue Shadow -> Pink Shadow -> Soft Drop Shadow */ + box-shadow: + 8px 8px 0 var(--color-blue), + 16px 16px 0 var(--color-pink), + 0 20px 40px rgba(0, 0, 0, 0.1); + } + + /* Stitching Effect */ + .container::before { + content: ""; + position: absolute; + top: 12px; + bottom: 12px; + left: 12px; + right: 12px; + border: 2px dashed var(--ink-secondary); + border-radius: 15px; + pointer-events: none; + opacity: 0.5; } /* ==================== 1. 头部设计 ==================== */ @@ -134,43 +157,57 @@ } /* ==================== 2. 统计邮票 ==================== */ - .stats-row { + /* ==================== 2. 统计区域 (新版) ==================== */ + .stats-wrapper { display: flex; - justify-content: center; - gap: 30px; + gap: 25px; margin-bottom: 40px; - flex-wrap: wrap; + align-items: stretch; + } + + .stats-grid { + flex: 2; + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 20px; } .stamp { - width: 150px; + width: 100%; + height: 100%; background: #fff; - padding: 10px; - box-shadow: 3px 3px 8px rgba(0, 0, 0, 0.05); - /* 邮票齿孔背景 */ - background-image: radial-gradient(transparent 50%, #fff 51%); - background-size: 10px 10px; - background-position: -5px -5px; + padding: 15px; + box-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1); + border: 2px solid var(--ink-primary); + border-radius: 12px; + position: relative; display: flex; flex-direction: column; align-items: center; - transition: transform 0.3s; - border: 1px solid #eee; + justify-content: center; + transition: transform 0.2s; + } + + /* 装饰性背景纹理 */ + .stamp::after { + content: ""; + position: absolute; + top: 5px; + bottom: 5px; + left: 5px; + right: 5px; + border: 1px dotted #e0e0e0; + border-radius: 8px; + pointer-events: none; } .stamp:hover { - transform: scale(1.1) rotate(0deg) !important; - z-index: 10; + transform: translateY(-2px); } .stamp-inner { - border: 1px solid var(--ink-secondary); - width: 100%; - padding: 15px 0; - display: flex; - flex-direction: column; - align-items: center; - background: radial-gradient(circle, #fff 50%, #fafafa 100%); + text-align: center; + z-index: 1; } .stamp-num { @@ -255,18 +292,21 @@ } /* ==================== 4. 活跃时段 ==================== */ + /* ==================== 4. 活跃时段 (新版) ==================== */ .highlight-section { - grid-column: span 5; + flex: 1; background: var(--color-yellow); - padding: 30px; - transform: rotate(2deg); - box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.1); + padding: 20px; + border: 2px solid var(--ink-primary); + border-radius: 20px; + box-shadow: 6px 6px 0 var(--color-pink); display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; position: relative; + background-image: repeating-linear-gradient(45deg, rgba(255, 255, 255, 0.2) 0, rgba(255, 255, 255, 0.2) 10px, transparent 10px, transparent 20px); } .tape-top { @@ -386,42 +426,59 @@ .user-card { break-inside: avoid; background: #fff; - border: 2px solid #e0e0e0; - border-radius: 12px; - padding: 20px; - margin-bottom: 25px; - box-shadow: 4px 4px 0 rgba(0, 0, 0, 0.05); + border: 2px solid var(--ink-primary); + border-radius: 16px; + padding: 24px; + margin-bottom: 30px; + /* Muted Blue-Grey Shadow */ + box-shadow: 6px 6px 0 rgba(70, 80, 100, 0.15), 6px 6px 0 1px var(--ink-primary); position: relative; display: flex; flex-direction: column; transition: transform 0.2s; + /* Very subtle grain */ + background-color: #fff; + background-image: url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)' opacity='0.03'/%3E%3C/svg%3E"); } .user-card:hover { - transform: translateY(-3px); + transform: translateY(-4px) rotate(1deg); z-index: 5; - border-color: var(--ink-primary); + box-shadow: 8px 8px 0 rgba(0, 0, 0, 0.15), 8px 8px 0 2px var(--ink-primary); } .card-tape { position: absolute; - top: -10px; + top: -12px; left: 50%; - transform: translateX(-50%); - width: 60px; - height: 18px; - background: var(--color-blue); - opacity: 0.9; + transform: translateX(-50%) rotate(-2deg); + width: 80px; + height: 24px; + background: rgba(255, 255, 255, 0.4); + /* Fallback */ + background-color: var(--color-blue); + opacity: 0.8; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + /* Jagged edges for tape look */ + mask-image: linear-gradient(135deg, transparent 5px, black 0) top left, linear-gradient(-135deg, transparent 5px, black 0) top right, linear-gradient(45deg, transparent 5px, black 0) bottom left, linear-gradient(-45deg, transparent 5px, black 0) bottom right; + mask-size: 51% 51%; + mask-repeat: no-repeat; + -webkit-mask-image: radial-gradient(circle at 2px 2px, transparent 2px, black 2.5px); + -webkit-mask-size: 100% 100%; + /* Simplify mask for compatibility */ + /* Simpler tape look since masks can be tricky across renderers */ + border-left: 2px dashed rgba(255, 255, 255, 0.3); + border-right: 2px dashed rgba(255, 255, 255, 0.3); } .user-card:nth-child(2n) .card-tape { - background: var(--color-pink); - transform: rotate(2deg); + background-color: var(--color-pink); + transform: translateX(-50%) rotate(3deg); } .user-card:nth-child(3n) .card-tape { - background: var(--color-green); - transform: rotate(-2deg); + background-color: var(--color-green); + transform: translateX(-50%) rotate(-1deg); } .user-header { @@ -494,16 +551,24 @@ .u-reason { font-family: var(--font-hand); - font-size: 0.95rem; - color: #555; + font-size: 1.05rem; + color: #444; line-height: 1.6; - text-align: justify; - background: #fafafa; - padding: 12px; - border-radius: 8px; + + /* Quote Block Style */ + background: #f8fbff; + border-left: 4px solid var(--color-blue); + padding: 12px 15px; + margin-top: 15px; + border-radius: 4px; position: relative; } + .u-reason::before { + content: ""; + /* Removed big quote mark to clean up */ + } + /* ==================== 7. 每日回响 ==================== */ .quotes-section { grid-column: span 12; @@ -704,66 +769,62 @@
-
- -
-
-
-
- - - - -
{{message_count}}
-
消息总数
-
+
+ +
+ +
+
+ + + +
{{message_count}}
+
消息总数
-
-
- - - - -
{{participant_count}}
-
参与人数
-
+
+ +
+
+ + + +
{{participant_count}}
+
参与人数
-
-
- - - - -
{{emoji_count}}
-
表情统计
-
+
+ +
+
+ + + +
{{emoji_count}}
+
表情统计
-
-
- - - - -
{{total_characters}}
-
总字符数
-
+
+ +
+
+ + + +
{{total_characters}}
+
总字符数
- -
-
-
✨ Highlight - Time
+ +
+
+
+ ✨ Highlight Time +
{{most_active_period}}
(此刻,世界色彩斑斓)