feat(template): retro_futurism 调整和 hack 模板

This commit is contained in:
SXP-Simon
2026-02-12 19:55:24 +08:00
parent b0ee9ff82f
commit 8c58a7b3d3
13 changed files with 1505 additions and 526 deletions
+3 -3
View File
@@ -72,15 +72,15 @@ _✨ 一个基于 AstrBot 的智能群聊分析插件,支持 **QQ (OneBot)**
<details> <details>
<summary>点击展开查看其他模板效果图</summary> <summary>点击展开查看其他模板效果图</summary>
retro_futurism 模板效果图
![retro_futurism效果图](./assets/retro_futurism-demo.jpg)
format 模板效果图 format 模板效果图
![format效果图](./assets/format-demo.jpg) ![format效果图](./assets/format-demo.jpg)
simple 模板效果图(用于展示贡献指南) simple 模板效果图(用于展示贡献指南)
![simple效果图](./assets/simple-demo.jpg) ![simple效果图](./assets/simple-demo.jpg)
retro_futurism 模板效果图
![retro_futurism效果图](./assets/retro_futurism-demo.jpg)
</details> </details>
## 使用方法 ## 使用方法
+1
View File
@@ -69,6 +69,7 @@
"options": [ "options": [
"scrapbook", "scrapbook",
"retro_futurism", "retro_futurism",
"hack",
"simple", "simple",
"format" "format"
], ],
@@ -0,0 +1,13 @@
{% if chart_data %}
{% for item in chart_data %}
<div class="activity-col">
<span class="activity-val-top">{{ item.count }}</span>
<div class="activity-bar-v" style="--h:{{ " %.2f"|format(item.percentage) }}%;"></div>
<span class="activity-tick">{{ "%02d"|format(item.hour) }}:00</span>
</div>
{% endfor %}
{% else %}
<div class="activity-col" style="flex:1; justify-content: center; height: 100px;">
<div class="comment">// NO_DATA_STREAM</div>
</div>
{% endif %}
@@ -0,0 +1,606 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Night Mode Analysis Portal</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&family=Inter:wght@400;600;800&family=Noto+Sans+SC:wght@400;700&display=swap"
rel="stylesheet">
<style>
:root {
--bg-deep: #0a0a0a;
--bg-panel: #141414;
--bg-card: #1c1c1c;
--text-primary: #ffffff;
--text-secondary: #a0a0a0;
--accent-orange: #ff9900;
/* Primary */
--accent-blue: #3399ff;
/* Secondary */
--accent-red: #ff3366;
--accent-green: #00ff88;
/* Reduced use */
--border-color: #2a2a2a;
--grid-color: rgba(255, 255, 255, 0.03);
--font-mono: 'JetBrains Mono', monospace;
--font-body: 'Inter', 'Noto Sans SC', sans-serif;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
background-color: var(--bg-deep);
color: var(--text-primary);
font-family: var(--font-body);
background-image:
radial-gradient(circle at 50% 10%, rgba(255, 153, 0, 0.08) 0%, transparent 70%),
linear-gradient(var(--grid-color) 1px, transparent 1px),
linear-gradient(90deg, var(--grid-color) 1px, transparent 1px);
background-size: 100% 100%, 30px 30px, 30px 30px;
min-height: 100vh;
font-size: 18px;
position: relative;
}
body::before {
content: "";
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(rgba(18, 16, 16, 0) 50%, rgba(0, 0, 0, 0.05) 50%);
background-size: 100% 4px;
pointer-events: none;
z-index: 9999;
opacity: 0.2;
}
.layout {
max-width: 1200px;
margin: 0 auto;
padding: 60px 40px;
}
/* Terminal Window Style */
.window {
background: rgba(20, 20, 20, 0.7);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid rgba(255, 255, 255, 0.05);
border-radius: 12px;
overflow: hidden;
box-shadow: 0 30px 60px rgba(0, 0, 0, 0.6);
margin-bottom: 40px;
}
.window-header {
background: #1e1e1e;
padding: 12px 20px;
display: flex;
align-items: center;
border-bottom: 1px solid var(--border-color);
}
.traffic-lights {
display: flex;
gap: 8px;
}
.light {
width: 12px;
height: 12px;
border-radius: 50%;
}
.light.red {
background: #ff5f56;
}
.light.yellow {
background: #ffbd2e;
}
.light.green {
background: #27c93f;
}
.window-title {
margin-left: 20px;
font-family: var(--font-mono);
font-size: 0.8rem;
color: var(--text-secondary);
flex: 1;
}
/* Top Navigation Bar from Reference */
.top-nav {
display: flex;
gap: 20px;
margin-bottom: 40px;
font-family: var(--font-mono);
font-size: 0.85rem;
align-items: center;
}
.nav-item {
color: var(--text-secondary);
padding: 6px 12px;
border-radius: 4px;
border: 1px solid transparent;
display: flex;
align-items: center;
gap: 8px;
}
.nav-item.active {
color: var(--accent-orange);
background: rgba(255, 153, 0, 0.05);
border-color: rgba(255, 153, 0, 0.2);
}
/* Typography */
.prompt {
color: var(--accent-orange);
/* Changed from green */
font-weight: bold;
}
.keyword {
color: var(--accent-red);
}
.comment {
color: #555;
}
h1 {
font-size: 5rem;
font-weight: 900;
margin: 0 0 25px;
letter-spacing: -3px;
line-height: 0.9;
background: linear-gradient(135deg, #fff 60%, var(--accent-orange));
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
}
.cursor {
display: inline-block;
width: 15px;
height: 1.2em;
background: var(--text-primary);
vertical-align: middle;
margin-left: 5px;
animation: blink 1s infinite;
}
@keyframes blink {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0;
}
}
/* Stats Grid */
.stats-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
margin-bottom: 40px;
}
.stat-card {
background: rgba(28, 28, 28, 0.6);
backdrop-filter: blur(8px);
border: 1px solid rgba(255, 153, 0, 0.1);
padding: 24px;
border-radius: 12px;
transition: all 0.3s ease;
}
.stat-card:hover {
border-color: var(--accent-orange);
background: rgba(28, 28, 28, 0.8);
transform: translateY(-5px);
}
.stat-label {
font-family: var(--font-mono);
color: var(--text-secondary);
font-size: 0.85rem;
margin-bottom: 20px;
display: flex;
align-items: center;
gap: 8px;
}
.stat-label::before {
content: '>';
color: var(--accent-orange);
}
.stat-value {
font-size: 3.5rem;
font-weight: 800;
color: var(--accent-orange);
font-family: var(--font-mono);
text-shadow: 0 0 20px rgba(255, 153, 0, 0.3);
}
/* Main Layout Grid */
.main-container {
display: grid;
grid-template-columns: 58% 42%;
/* Golden ratio-ish split */
gap: 40px;
align-items: flex-start;
}
.left-col {
display: flex;
flex-direction: column;
gap: 40px;
}
.right-col {
display: flex;
flex-direction: column;
gap: 40px;
}
.section-header {
font-family: var(--font-mono);
font-size: 1.1rem;
margin-bottom: 25px;
color: var(--text-secondary);
display: flex;
align-items: center;
gap: 10px;
}
/* Code Block Container */
.code-block {
background: rgba(20, 20, 20, 0.8);
border: 1px solid rgba(255, 153, 0, 0.15);
padding: 30px;
border-radius: 12px;
font-family: var(--font-mono);
line-height: 1.6;
box-shadow: inset 0 0 40px rgba(0, 0, 0, 0.2);
}
/* Chart Styling - Reference inspired */
.chart-container {
height: 300px;
position: relative;
padding: 40px 10px 50px;
display: flex;
align-items: flex-end;
justify-content: space-between;
gap: 2px;
overflow: visible;
}
.chart-svg {
width: 100%;
height: 100%;
}
.chart-line {
fill: none;
stroke: var(--accent-orange);
stroke-width: 3;
}
.chart-area {
fill: url(#areaGradient);
opacity: 0.3;
}
/* Horizontal Activity Chart Elements */
.activity-col {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
height: 100%;
justify-content: flex-end;
min-width: 0;
}
.activity-bar-v {
width: 80%;
max-width: 12px;
background: var(--accent-orange);
height: var(--h, 0%);
border-radius: 1px 1px 0 0;
box-shadow: 0 0 8px rgba(255, 153, 0, 0.3);
position: relative;
}
.activity-bar-v::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(to top, rgba(255, 255, 255, 0.05), transparent);
}
.activity-tick {
font-family: var(--font-mono);
font-size: 0.5rem;
color: var(--text-secondary);
margin-top: 10px;
transform: rotate(-60deg);
transform-origin: top center;
white-space: nowrap;
}
.activity-val-top {
font-family: var(--font-mono);
font-size: 0.55rem;
color: var(--text-primary);
margin-bottom: 4px;
opacity: 0.6;
}
/* Vertical Flow Elements */
.user-grid,
.quote-container,
.topic-list {
display: flex;
flex-direction: column;
gap: 20px;
width: 100%;
}
@media (max-width: 900px) {
.user-grid,
.quote-container {
grid-template-columns: 1fr;
}
}
.user-card {
background: var(--bg-card);
border: 1px solid var(--border-color);
padding: 20px;
border-radius: 8px;
display: flex;
gap: 20px;
transition: border-color 0.2s;
}
.user-card:hover {
border-color: var(--accent-blue);
}
.user-avatar {
width: 50px;
height: 50px;
border-radius: 8px;
border: 1px solid #333;
}
.user-info h4 {
margin: 0 0 5px;
font-size: 1.1rem;
}
.tag {
font-family: var(--font-mono);
font-size: 0.75rem;
padding: 2px 8px;
border-radius: 4px;
border: 1px solid;
margin-right: 8px;
}
.tag.mbti {
color: #ffcc00;
border-color: rgba(255, 204, 0, 0.3);
background: rgba(255, 204, 0, 0.05);
}
.tag.title {
color: var(--accent-blue);
border-color: rgba(51, 153, 255, 0.3);
background: rgba(51, 153, 255, 0.05);
}
.topic-list {
display: flex;
flex-direction: column;
gap: 24px;
}
.topic-item {
padding: 20px;
border-left: 3px solid var(--accent-orange);
background: rgba(255, 255, 255, 0.02);
}
.topic-title {
font-weight: bold;
font-size: 1.5rem;
margin-bottom: 12px;
color: var(--accent-orange);
}
/* Quotes */
.quote-item {
padding: 24px;
border: 1px solid rgba(255, 255, 255, 0.05);
border-radius: 12px;
display: flex;
gap: 20px;
align-items: flex-start;
background: rgba(30, 30, 30, 0.4);
backdrop-filter: blur(5px);
margin-bottom: 20px;
}
.quote-avatar {
width: 45px;
height: 45px;
border-radius: 50%;
border: 1px solid #333;
flex-shrink: 0;
overflow: hidden;
}
.quote-avatar img {
width: 100%;
height: 100%;
object-fit: cover;
}
.quote-body {
flex: 1;
}
.quote-text {
font-style: italic;
font-size: 1.1rem;
color: var(--accent-orange);
margin-bottom: 12px;
line-height: 1.5;
}
.quote-author {
font-family: var(--font-mono);
font-size: 0.9rem;
color: var(--accent-blue);
margin-bottom: 8px;
}
/* Footer */
footer {
margin-top: 80px;
padding-top: 40px;
border-top: 1px solid var(--border-color);
display: flex;
justify-content: space-between;
font-family: var(--font-mono);
font-size: 0.8rem;
color: var(--text-secondary);
}
.footer-token {
color: var(--accent-green);
}
</style>
</head>
<body>
<div class="layout">
<!-- Top Navigation Mockup -->
<div class="top-nav">
<div class="nav-item active">● ready</div>
<div class="nav-item">~/analysis</div>
<div style="flex: 1"></div>
<div class="nav-item">$ ai --summary</div>
<div class="nav-item">$ cd /groups</div>
<div class="nav-item">$ api --status</div>
<div class="nav-item">🌐 EN</div>
<div class="user-avatar" style="width: 25px; height: 25px; border-radius: 50%;"></div>
</div>
<div class="main-container">
<!-- Left Side: Analytical Data -->
<div class="left-col">
<div>
<div class="comment">// main.ts</div>
<h1><span class="prompt">&gt;</span> Group Activity<br>Insights<span class="cursor"></span></h1>
<div class="comment" style="margin-bottom: 30px;">// Report for {{current_date}}</div>
<div class="code-block">
<span class="keyword">const</span> stats = {<br>
&nbsp;&nbsp;messages: <span style="color: var(--accent-orange);">{{message_count}}</span>,<br>
&nbsp;&nbsp;active_users: <span
style="color: var(--accent-orange);">{{participant_count}}</span>,<br>
&nbsp;&nbsp;peak_time: <span
style="color: var(--accent-blue);">'{{most_active_period}}'</span><br>
};<br>
<span class="comment">// Total characters: {{total_characters}}</span>
</div>
</div>
<!-- Topics moved into left column -->
<div>
<div class="section-header">
<span class="prompt">$</span> ls ./topics
</div>
<div class="topic-list">
{{topics_html}}
</div>
</div>
</div>
<!-- Right Side: Visuals & Members -->
<div class="right-col">
<div class="window">
<div class="window-header">
<div class="traffic-lights">
<div class="light red"></div>
<div class="light yellow"></div>
<div class="light green"></div>
</div>
<div class="window-title">trend-analytics.tsx</div>
</div>
<div class="chart-container">
{{hourly_chart_html}}
</div>
</div>
<!-- User Titles grouped here -->
<div style="margin-top: 20px;">
<div class="section-header">
<span class="prompt">$</span> cat ./user_titles
</div>
<div class="user-grid">
{{titles_html}}
</div>
</div>
<!-- Golden Quotes grouped here -->
<div style="margin-top: 20px;">
<div class="section-header">
<span class="prompt">$</span> grep -r "golden_quotes"
</div>
<div class="quote-container">
{{quotes_html}}
</div>
</div>
</div>
</div>
<footer>
<div>SYSTEM_REPORT // CHANNEL: {{platform_id}} // {{current_datetime}}</div>
<div>
TOKENS: <span class="footer-token">{{total_tokens}}</span>
[P: {{prompt_tokens}} | C: {{completion_tokens}}]
</div>
<div style="color: var(--accent-orange);">AstrBotDevs/AstrBot 群分析</div>
</footer>
</div>
</body>
</html>
@@ -0,0 +1,394 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Night Mode Analysis Portal (PDF)</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&family=Inter:wght@400;600;800&family=Noto+Sans+SC:wght@400;700&display=swap"
rel="stylesheet">
<style>
/* PDF specific styles */
@page {
size: A4;
margin: 0;
}
:root {
--bg-deep: #0a0a0a;
--bg-panel: #141414;
--bg-card: #1c1c1c;
--text-primary: #ffffff;
--text-secondary: #a0a0a0;
--accent-orange: #ff9900;
--accent-blue: #3399ff;
--accent-red: #ff3366;
--accent-green: #00ff88;
--border-color: #2a2a2a;
--grid-color: rgba(255, 255, 255, 0.03);
--font-mono: 'JetBrains Mono', monospace;
--font-body: 'Inter', 'Noto Sans SC', sans-serif;
}
* {
box-sizing: border-box;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
body {
margin: 0;
background-color: var(--bg-deep);
color: var(--text-primary);
font-family: var(--font-body);
background-image:
linear-gradient(var(--grid-color) 1px, transparent 1px),
linear-gradient(90deg, var(--grid-color) 1px, transparent 1px);
background-size: 30px 30px;
min-height: 100vh;
font-size: 16px;
}
.layout {
max-width: 1000px;
margin: 0 auto;
padding: 40px;
}
.main-container {
display: grid;
grid-template-columns: 1.2fr 0.8fr;
/* Balanced 2-column split */
gap: 30px;
align-items: flex-start;
}
.left-col,
.right-col {
display: flex;
flex-direction: column;
gap: 30px;
}
/* Terminal Window Style */
.window {
background: var(--bg-panel);
border: 1px solid var(--border-color);
border-radius: 12px;
overflow: hidden;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4);
margin-bottom: 0;
}
.window-header {
background: #1e1e1e;
padding: 10px 15px;
display: flex;
align-items: center;
border-bottom: 1px solid var(--border-color);
}
.traffic-lights {
display: flex;
gap: 8px;
}
.light {
width: 10px;
height: 10px;
border-radius: 50%;
}
.light.red {
background: #ff5f56;
}
.light.green {
background: #27c93f;
}
.window-title {
margin-left: 15px;
font-family: var(--font-mono);
font-size: 0.75rem;
color: var(--text-secondary);
}
.top-nav {
display: flex;
gap: 15px;
margin-bottom: 30px;
font-family: var(--font-mono);
font-size: 0.8rem;
align-items: center;
}
.nav-item {
color: var(--accent-orange);
font-weight: bold;
}
.prompt {
color: var(--accent-orange);
font-weight: bold;
}
.keyword {
color: var(--accent-red);
}
.comment {
color: #555;
}
h1 {
font-size: 3.5rem;
font-weight: 800;
margin: 0 0 15px;
letter-spacing: -1.5px;
line-height: 1;
color: #fff;
}
.stat-card {
background: var(--bg-card);
border: 1px solid rgba(255, 153, 0, 0.2);
padding: 20px;
border-radius: 8px;
}
.stat-label {
font-family: var(--font-mono);
color: var(--text-secondary);
font-size: 0.8rem;
margin-bottom: 10px;
display: flex;
align-items: center;
gap: 5px;
}
.stat-label::before {
content: '>';
color: var(--accent-orange);
}
.stat-value {
font-size: 2.5rem;
font-weight: 700;
color: var(--accent-orange);
font-family: var(--font-mono);
}
.section-header {
font-family: var(--font-mono);
font-size: 1rem;
margin-bottom: 15px;
color: var(--text-secondary);
}
.code-block {
background: rgba(255, 255, 255, 0.02);
border: 1px solid var(--border-color);
padding: 20px;
border-radius: 6px;
font-family: var(--font-mono);
line-height: 1.5;
font-size: 0.9rem;
}
.chart-container {
height: 220px;
position: relative;
padding: 20px 5px;
display: flex;
align-items: flex-end;
justify-content: space-between;
}
.topic-list,
.user-grid,
.quote-grid {
display: flex;
flex-direction: column;
gap: 15px;
}
.user-card {
background: var(--bg-card);
border: 1px solid var(--border-color);
padding: 15px;
border-radius: 6px;
display: flex;
gap: 15px;
border-left: 3px solid var(--accent-blue);
}
.user-avatar {
width: 45px;
height: 45px;
border-radius: 6px;
}
.user-info h4 {
margin: 0 0 4px;
font-size: 1rem;
}
.tag {
font-family: var(--font-mono);
font-size: 0.7rem;
padding: 1px 6px;
border-radius: 3px;
border: 1px solid;
margin-right: 5px;
}
.tag.mbti {
color: #ffcc00;
border-color: rgba(255, 204, 0, 0.3);
background: rgba(255, 204, 0, 0.1);
}
.tag.title {
color: var(--accent-blue);
border-color: rgba(51, 153, 255, 0.3);
}
.topic-item {
padding: 15px;
border-left: 3px solid var(--accent-orange);
background: rgba(255, 255, 255, 0.01);
}
.topic-title {
font-weight: bold;
font-size: 1.3rem;
margin-bottom: 8px;
color: var(--accent-orange);
}
.quote-item {
padding: 15px;
border: 1px solid var(--border-color);
border-radius: 6px;
display: flex;
gap: 15px;
align-items: flex-start;
background: #111;
}
.quote-avatar {
width: 35px;
height: 35px;
border-radius: 50%;
border: 1px solid #333;
flex-shrink: 0;
overflow: hidden;
}
.quote-avatar img {
width: 100%;
height: 100%;
object-fit: cover;
}
.quote-body {
flex: 1;
}
.quote-text {
font-style: italic;
font-size: 0.95rem;
color: var(--accent-orange);
margin-bottom: 5px;
line-height: 1.4;
}
footer {
margin-top: 60px;
padding-top: 20px;
border-top: 1px solid var(--border-color);
display: flex;
justify-content: space-between;
font-family: var(--font-mono);
font-size: 0.75rem;
color: var(--text-secondary);
}
.avoid-break {
page-break-inside: avoid;
}
</style>
</head>
<body>
<div class="layout">
<div class="top-nav">
<div class="nav-item">● ready</div>
<div class="nav-item">~/report</div>
</div>
<div class="main-container">
<!-- Left Column: Insights & Topics -->
<div class="left-col">
<div>
<div class="comment">// Report: {{current_date}}</div>
<h1><span class="prompt">&gt;</span> Daily Analysis</h1>
<div class="code-block">
<span class="keyword">stats</span> = {<br>
&nbsp;&nbsp;msg: {{message_count}},<br>
&nbsp;&nbsp;users: {{participant_count}}<br>
}
</div>
</div>
<div class="avoid-break">
<div class="section-header"><span class="prompt">$</span> ls ./topics</div>
<div class="topic-list">
{{topics_html}}
</div>
</div>
</div>
<!-- Right Column: Chart & People -->
<div class="right-col">
<div class="window avoid-break">
<div class="window-header">
<div class="traffic-lights">
<div class="light red"></div>
<div class="light green"></div>
</div>
<div class="window-title">activity.log</div>
</div>
<div class="chart-container">
{{hourly_chart_html}}
</div>
</div>
<div class="avoid-break">
<div class="section-header"><span class="prompt">$</span> cat users</div>
<div class="user-grid">
{{titles_html}}
</div>
</div>
<div class="avoid-break">
<div class="section-header"><span class="prompt">$</span> grep golden</div>
<div class="quote-grid">
{{quotes_html}}
</div>
</div>
</div>
</div>
<footer>
<div>SYSTEM_REPORT // CHANNEL: {{platform_id}} // {{current_datetime}}</div>
<div style="color: var(--accent-orange);">AstrBotDevs/AstrBot 群分析</div>
</footer>
</div>
</body>
</html>
@@ -0,0 +1,24 @@
{% if quotes %}
<div class="user-grid">
{% for quote in quotes %}
<div class="quote-item avoid-break">
<div class="quote-avatar">
{% if quote.avatar_url %}
<img src="{{ quote.avatar_url }}" alt="{{ quote.sender }}">
{% elif quote.avatar_data %}
<img src="{{ quote.avatar_data }}" alt="{{ quote.sender }}">
{% else %}
<div
style="width:100%; height:100%; display:flex; align-items:center; justify-content:center; background: #222; font-family: var(--font-mono); font-size: 10px; color: #444;">
ID</div>
{% endif %}
</div>
<div class="quote-body">
<div class="quote-text">"{{ quote.content }}"</div>
<div class="quote-author">-- {{ quote.sender }}</div>
<div class="comment" style="font-size: 0.8rem;">// Reason: {{ quote.reason }}</div>
</div>
</div>
{% endfor %}
</div>
{% endif %}
@@ -0,0 +1,11 @@
{% if topics %}
<div class="topic-list">
{% for topic in topics %}
<div class="topic-item avoid-break">
<div class="topic-title">{{ topic.topic.topic }}</div>
<div class="comment" style="margin-bottom: 15px;">/* Participants: {{ topic.contributors }} */</div>
<div style="line-height: 1.6; opacity: 0.9;">{{ topic.detail | safe }}</div>
</div>
{% endfor %}
</div>
{% endif %}
@@ -0,0 +1,26 @@
{% if titles %}
<div class="user-grid">
{% for title in titles %}
<div class="user-card avoid-break">
<div class="user-avatar">
{% if title.avatar_data %}
<img src="{{ title.avatar_data }}" alt="{{ title.name }}"
style="width:100%; height:100%; object-fit:cover; border-radius: 6px;">
{% else %}
<div
style="width:100%; height:100%; display:flex; align-items:center; justify-content:center; background: #222; border-radius: 6px; font-family: var(--font-mono); font-size: 10px; color: #444;">
ID_REF</div>
{% endif %}
</div>
<div class="user-info">
<h4>{{ title.name }}</h4>
<div style="margin-bottom: 10px;">
<span class="tag mbti">{{ title.mbti }}</span>
<span class="tag title">{{ title.title }}</span>
</div>
<div style="font-size: 0.85rem; color: var(--text-secondary); line-height: 1.4;">{{ title.reason }}</div>
</div>
</div>
{% endfor %}
</div>
{% endif %}
@@ -1,15 +1,15 @@
{% if chart_data %} {% if chart_data %}
{% for item in chart_data %} <div class="activity-container">
<div class="activity-row"> {% for item in chart_data %}
<div class="activity-hour">{{ "%02d"|format(item.hour) }}:00</div> <div class="activity-col">
<div class="activity-meter"> <span class="activity-col-count">{{ item.count }}</span>
<div class="activity-bar" style="--pct: {{ "%.2f"|format(item.percentage) }}%;"></div> <div class="activity-bar-vertical" style="--h: {{ " %.2f"|format(item.percentage) }}%;"></div>
<span class="activity-label-hour">{{ "%02d"|format(item.hour) }}:00</span>
</div> </div>
<div class="activity-count">{{ item.count }}</div> {% endfor %}
</div> </div>
{% endfor %}
{% else %} {% else %}
<div class="activity-row"> <div class="activity-col" style="flex:1; justify-content: center; height: 100px;">
<div class="topic-meta" style="grid-column: span 3;">NO_DATA_AVAILABLE</div> <div class="topic-meta">NO_DATA_AVAILABLE_FOR_ACTIVITY_SPECTRUM</div>
</div> </div>
{% endif %} {% endif %}
File diff suppressed because it is too large Load Diff
@@ -1,17 +1,20 @@
{% if quotes %} {% if quotes %}
{% for quote in quotes %} {% for quote in quotes %}
<article class="quote-item"> <section class="quote-item">
<span class="color-third"></span> {% if quote.avatar_url %}
<div class="quote-icon"> <div class="quote-avatar">
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <img src="{{ quote.avatar_url }}" alt="{{ quote.sender }}">
<path d="M6 17h3l2-4V7H5v6h3zm8 0h3l2-4V7h-6v6h3z"/>
</svg>
</div> </div>
<div> {% elif quote.avatar_data %}
<p class="quote-content">{{ quote.content }}</p> <div class="quote-avatar">
<div class="quote-author">{{ quote.sender }}</div> <img src="{{ quote.avatar_data }}" alt="{{ quote.sender }}">
<p class="quote-note">{{ quote.reason }}</p>
</div> </div>
</article> {% endif %}
<div class="quote-body">
<div class="quote-content">{{ quote.content }}</div>
<div class="quote-author">ORIGIN: {{ quote.sender }}</div>
<div class="quote-reason-small">ANALYSIS // {{ quote.reason }}</div>
</div>
</section>
{% endfor %} {% endfor %}
{% endif %} {% endif %}
@@ -1,17 +1,12 @@
{% if topics %} {% if topics %}
{% for topic in topics %} {% for topic in topics %}
<article class="topic-item"> <section class="topic-item">
<span class="color-third"></span>
<div class="topic-icon">
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6l-2 2V4h16v12z"/>
</svg>
</div>
<div class="topic-content"> <div class="topic-content">
<h3 class="topic-title">{{ topic.topic.topic }}</h3> <h3 class="topic-title">{{ topic.topic.topic }}</h3>
<p class="topic-meta">PARTICIPANTS: {{ topic.contributors }}</p> <div class="topic-meta">SUBJECT ID: #{{ "%02d"|format(loop.index) }} // PARTICIPANTS: {{ topic.contributors }}
<p class="topic-detail">{{ topic.detail | safe }}</p> </div>
<div class="topic-detail">{{ topic.detail | safe }}</div>
</div> </div>
</article> </section>
{% endfor %} {% endfor %}
{% endif %} {% endif %}
@@ -1,23 +1,24 @@
{% if titles %} {% if titles %}
{% for title in titles %} {% for title in titles %}
<article class="title-item"> <div class="title-item">
<div class="title-header"> <div class="title-avatar-wrap">
<div class="title-avatar"> {% if title.avatar_data %}
{% if title.avatar_data %} <img src="{{ title.avatar_data }}" alt="{{ title.name }}">
<img src="{{ title.avatar_data }}" alt="{{ title.name }}"> {% else %}
{% else %} <div
<div class="title-avatar-fallback">CRT</div> style="width:100%; height:100%; display:flex; align-items:center; justify-content:center; font-family:var(--font-mono); font-size:12px; opacity:0.3;">
{% endif %} DATA_ERR</div>
</div> {% endif %}
<div class="title-info">
<span class="title-name">{{ title.name }}</span>
<div class="title-badges">
<span class="title-mbti">{{ title.mbti }}</span>
<span class="title-role">{{ title.title }}</span>
</div>
</div>
</div> </div>
<p class="title-reason">{{ title.reason }}</p> <div class="title-info">
</article> <h4>{{ title.name }}</h4>
<div class="title-badge">
<span>{{ title.mbti }}</span>
<span style="color:var(--c-dec-3);">//</span>
<span>{{ title.title }}</span>
</div>
<div class="title-reason">{{ title.reason }}</div>
</div>
</div>
{% endfor %} {% endfor %}
{% endif %} {% endif %}