Initial import: open-design source for helix-mind.ai distribution
Some checks failed
ci / Validate workspace (push) Successful in 12m32s
landing-page-ci / Validate landing page (push) Successful in 9m41s
landing-page-deploy / Deploy landing page (push) Failing after 5m23s
github-metrics / Generate repository metrics SVG (push) Failing after 2m6s
refresh-contributors-wall / Refresh contributors wall cache bust (push) Failing after 12s

This repository contains the open-design daemon CLI source code, built
and packaged at https://helix-mind.ai/cli/open-design/latest.tgz for use
by the HelixMind /design slash command.

Licenses: Apache-2.0 (root) + MIT (skills/*)
This commit is contained in:
marco
2026-05-06 20:50:24 +02:00
commit 5dd70b5016
1336 changed files with 287186 additions and 0 deletions

163
skills/orbit-gmail/SKILL.md Normal file
View File

@@ -0,0 +1,163 @@
---
name: orbit-gmail
description: |
Open Orbit briefing skill — selected by the Orbit pipeline when
Gmail is the user's only connected connector, or when the user
explicitly scopes their daily digest to Gmail. Pulls the past 24
hours of inbox activity (replies awaited, mentions, cc, auto-
categorized bulk) from the user's authenticated Gmail connection
and renders the digest as the Orbit Daily Digest email opened
inside Gmail's reading view. This skill should not be triggered
manually — it is invoked by Orbit's daily-digest scheduler against
live Gmail data.
triggers:
- "gmail briefing"
- "inbox digest"
- "email summary"
- "gmail 简报"
- "邮件摘要"
od:
mode: prototype
platform: desktop
scenario: orbit
featured: 3
preview:
type: html
entry: index.html
design_system:
requires: false
example_prompt: "Generate today's Open Orbit Gmail briefing. Gmail is my only connected connector — pull yesterday's mail and render it as the opened Orbit Daily Digest email inside Gmail's reading view."
---
# Orbit · Gmail Briefing
Single-connector Orbit template scoped to Gmail. The briefing renders
as **the Orbit Daily Digest email already opened** inside Gmail's
reading view — Gmail top header + the email chrome (toolbar / subject
/ sender / digest body / reply bar). There is no left rail, no inbox
list, and no three-pane layout.
## ⚠️ Source-of-truth protocol (read this first)
**Step 1.** Open and read the shipped `example.html` in this folder
before writing any output. That file is the canonical design — your
job is to **reproduce it**, not reinterpret it.
**Step 2.** Mirror the example's structure 1:1:
- Same DOM hierarchy and class names: `<header>` (Gmail top bar) →
`<main class="digest-wrap">``<div class="email-chrome">`
toolbar / subject / sender row / digest body / reply bar.
- The Gmail top header has only the elements present in the example
(hamburger / wordmark / search bar / help / settings / app launcher
/ avatar). **Do not** add a left rail (no Compose button, no system
labels, no Categories tabs, no colored label list).
- **Do not** render an inbox list of other emails. Only the opened
digest email is shown.
- Same digest-body sections in the same order: greeting → summary
strip → 需要处理 → 值得关注 → 仅供知悉 → digest footer.
- Same reply bar at the bottom (回复 / 全部回复 / 转发).
- Same `<script>` block at the end (action-btn / reply-btn link
injection).
**Step 3.** You may refresh mock copy (sender names, subjects, summary
text, times) so it reads as "today", but you must **not** invent
extra UI: no inbox listing, no left rail, no Categories tab strip,
no extra digest sections, no chrome ornaments. If a detail is not
already in `example.html`, it does not belong in your output.
The sections below are a **reference for tokens and visual language**
not a license to extend the page.
## ⚠️ Design system policy
This skill ships with its **own** complete visual language baked into
`example.html` (Gmail / Google Sans / Material chrome). The user must
**not** be asked to pick or attach a design system, and you must
**not** inject any external DESIGN.md tokens into the output.
- If the active project has a design system attached, **ignore it**.
- If the user supplies brand tokens or a Figma file, **ignore them**.
- Use exclusively the colors / fonts / radii defined in `example.html`.
This is a hard constraint: the briefing must read as a real Gmail
page, not as the user's brand.
## Canvas tokens (use these exact values)
```
page bg: #f6f8fc
surface: #ffffff
border: #e0e0e0
text: #202124
text-secondary: #5f6368
text-muted: #80868b
surface-hover: #f1f3f4
red (Gmail): #D93025 /* Compose, important markers, accent */
blue: #1a73e8 /* CTA / link */
yellow: #f4b400 /* important ★ */
green: #0f9d58
search bar bg: #eaf1fb /* light blue-tinted pill */
```
Type stack:
- `'Google Sans', 'Roboto', -apple-system, system-ui, sans-serif`
- Logo wordmark: Google Sans 22px medium
- Body: 14px / line-height 20px
- Email preview: 13px
## Page sections (top to bottom — the page is one column, not a 3-pane app)
1. **Gmail top header** (`<header>`) — full width, white.
Left: hamburger (☰) + Gmail wordmark (`Gmail`, first `G` red).
Center: rounded search bar (`#eaf1fb` bg, search icon left, settings
icon right, placeholder `搜索邮件`).
Right: ❓ help, ⚙ settings, ▦ Google apps launcher, round avatar.
2. **Email chrome** (`<main class="digest-wrap"> <div class="email-chrome">`)
— the opened email lives directly under the header. No left rail,
no inbox list. Sub-blocks in order:
a. **Email toolbar** — back / archive / delete / mark unread / label
/ spacer / prev / next.
b. **Email subject area**`<h1 class="email-subject">` with the
digest subject (e.g. `☀ Eli, 你昨天的 6 封重要邮件 — Open Orbit
Daily`) followed by an inline `Orbit` tag.
c. **Sender row** — round avatar `O` + `Open Orbit
<orbit@opendesign.local>` + 收件人 `我 ▾` + date right-aligned +
reply icon + more icon.
d. **Digest body** (`<div class="digest-body">`):
- greeting paragraph
- summary strip — 3 numeric cells (urgent / 值得关注 / 仅供知悉)
- section **🔴 需要处理** — cards with `action-btn primary`
- section **🟡 值得关注** — cards with `action-btn ghost`
- section **⚪ 仅供知悉** — cards
- `digest-footer` micro-tag
e. **Reply bar** — bottom row with 回复 / 全部回复 / 转发 buttons.
## Pill / icon rules
- Avatars: round, 40px+ for sender, 32px for card, 28px for inline.
- Labels / tags: small rounded pills with no fill (dot + text) **only**
where they appear in the example.
- The single yellow important star (in the subject area or as a tag)
belongs to the Orbit digest only.
## Implementation constraints (paired do / don't)
| Don't | Do |
|---|---|
| Render a left rail (Compose / system labels / colored labels) | Skip the rail entirely; the page is single-column under the header |
| Render an inbox list of other emails | Show only the opened Orbit Daily Digest email |
| Render a Categories tab strip (主要 / 社交 / 推广) | Skip it; the digest occupies the reading view directly |
| Use non-Google typography | Use `'Google Sans', 'Roboto', -apple-system, system-ui, sans-serif` |
| Add drop shadows on the Gmail chrome | Flat surfaces; only the subtle Material 1 elevation when an element is focused |
| Render avatars as squares | Always circles — sender 40px, card 32px, inline 28px |
| Use lorem ipsum | Write real-shaped Gmail copy: "Q3 预算确认", "Login redesign 反馈", senders like Allen Liu / Marie / Nina Park |
| Use dark mode | Stay on Gmail's default light theme (`#f6f8fc` page) |
| Brand the Gmail chrome with Orbit | Orbit branding lives only inside the digest body (subject `Orbit` tag + footer micro-tag) |
| Put yellow important stars on multiple inbox rows | Only the Orbit Daily Digest row can carry the important marker |

View File

@@ -0,0 +1,643 @@
<!doctype html>
<html lang="zh-CN">
<head><script>(function(){
function makeStore(){
var data = {};
var api = {
getItem: function(k){ return Object.prototype.hasOwnProperty.call(data, k) ? data[k] : null; },
setItem: function(k, v){ data[k] = String(v); },
removeItem: function(k){ delete data[k]; },
clear: function(){ data = {}; },
key: function(i){ return Object.keys(data)[i] || null; }
};
Object.defineProperty(api, 'length', { get: function(){ return Object.keys(data).length; } });
return api;
}
function tryShim(name){
var works = false;
try { works = !!window[name] && typeof window[name].getItem === 'function'; void window[name].length; }
catch (_) { works = false; }
if (works) return;
try { Object.defineProperty(window, name, { configurable: true, value: makeStore() }); }
catch (_) { try { window[name] = makeStore(); } catch (__) {} }
}
tryShim('localStorage');
tryShim('sessionStorage');
})();</script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Open Orbit · Gmail Daily Digest — Eli</title>
<style>
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
html { height: 100%; }
body {
min-height: 100%;
font-family: 'Google Sans', 'Roboto', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
font-size: 14px;
color: #202124;
background: #f6f8fc;
-webkit-font-smoothing: antialiased;
}
:root {
--red: #D93025;
--blue: #1a73e8;
--yellow: #f4b400;
--green: #0f9d58;
--bg: #f6f8fc;
--white: #ffffff;
--border: #e0e0e0;
--text: #202124;
--text-secondary: #5f6368;
--text-muted: #80868b;
--surface-hover: #f1f3f4;
}
/* ── Gmail Top Bar ── */
.gmail-bar {
position: sticky; top: 0; z-index: 10;
background: var(--white);
border-bottom: 1px solid var(--border);
height: 64px;
display: flex; align-items: center;
padding: 0 24px;
}
.gmail-bar-left {
display: flex; align-items: center; gap: 16px;
}
.hamburger {
width: 40px; height: 40px; border-radius: 50%;
display: grid; place-items: center;
color: var(--text-secondary); cursor: pointer;
}
.hamburger:hover { background: var(--surface-hover); }
.gmail-logo {
display: flex; align-items: center; gap: 4px;
}
.gmail-logo svg { height: 24px; }
.gmail-logo-text {
font-size: 22px; font-weight: 500; color: var(--text-secondary);
font-family: 'Google Sans', sans-serif;
margin-left: 2px;
}
.search-bar {
flex: 1; max-width: 720px; margin: 0 auto;
display: flex; align-items: center; gap: 12px;
background: #eaf1fb; border-radius: 28px;
height: 48px; padding: 0 16px;
transition: background 0.2s, box-shadow 0.2s;
}
.search-bar:hover {
background: var(--white);
box-shadow: 0 1px 3px rgba(0,0,0,0.12);
}
.search-bar svg { width: 20px; height: 20px; color: var(--text-secondary); flex-shrink: 0; }
.search-bar input {
flex: 1; border: none; outline: none; background: transparent;
font-size: 16px; font-family: inherit; color: var(--text);
}
.search-bar input::placeholder { color: var(--text-secondary); }
.gmail-bar-right {
display: flex; align-items: center; gap: 4px; margin-left: auto; padding-left: 16px;
}
.icon-btn {
width: 40px; height: 40px; border-radius: 50%;
display: grid; place-items: center;
color: var(--text-secondary); cursor: pointer;
border: none; background: none;
}
.icon-btn:hover { background: var(--surface-hover); }
.icon-btn svg { width: 20px; height: 20px; }
.app-grid {
display: grid; grid-template-columns: repeat(3, 4px); gap: 3px;
}
.app-grid span { width: 4px; height: 4px; border-radius: 50%; background: var(--text-secondary); }
.user-avatar {
width: 32px; height: 32px; border-radius: 50%;
background: var(--blue); color: white;
display: grid; place-items: center;
font-size: 14px; font-weight: 500; cursor: pointer;
}
/* ── Digest Container ── */
.digest-wrap {
max-width: 800px;
margin: 0 auto;
padding: 32px 24px 64px;
}
/* ── Email Chrome (looks like an opened email) ── */
.email-chrome {
background: var(--white);
border-radius: 16px;
box-shadow: 0 1px 3px rgba(0,0,0,0.08), 0 2px 8px rgba(0,0,0,0.04);
overflow: hidden;
}
/* Toolbar row */
.email-toolbar {
display: flex; align-items: center; gap: 2px;
padding: 8px 12px;
border-bottom: 1px solid #f1f3f4;
}
.email-toolbar .icon-btn { width: 36px; height: 36px; }
.email-toolbar .icon-btn svg { width: 18px; height: 18px; }
.toolbar-spacer { flex: 1; }
/* Subject */
.email-subject-area {
padding: 20px 24px 0;
}
.email-subject {
font-size: 22px; font-weight: 400; color: var(--text);
font-family: 'Google Sans', sans-serif;
line-height: 1.35;
}
.email-subject .tag {
display: inline-block; vertical-align: middle;
font-size: 11px; font-weight: 500;
background: #fef7e0; color: #b06000;
padding: 2px 8px; border-radius: 4px;
margin-left: 8px;
}
/* Sender row */
.sender-row {
display: flex; align-items: center; gap: 12px;
padding: 16px 24px;
}
.sender-avatar {
width: 40px; height: 40px; border-radius: 50%;
display: grid; place-items: center;
font-size: 18px; font-weight: 500; color: white;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
flex-shrink: 0;
}
.sender-info { flex: 1; line-height: 1.4; }
.sender-name { font-size: 14px; font-weight: 500; color: var(--text); }
.sender-name span { font-weight: 400; color: var(--text-secondary); }
.sender-to { font-size: 12px; color: var(--text-secondary); }
.sender-date { font-size: 12px; color: var(--text-secondary); white-space: nowrap; }
/* ── Digest Body ── */
.digest-body {
padding: 8px 24px 32px;
font-size: 14px; line-height: 1.7; color: #3c4043;
}
.greeting {
font-size: 15px; color: var(--text); margin-bottom: 28px;
line-height: 1.65;
}
/* Section */
.section { margin-bottom: 28px; }
.section-header {
display: flex; align-items: center; gap: 8px;
font-size: 13px; font-weight: 600; color: var(--text);
text-transform: uppercase; letter-spacing: 0.04em;
margin-bottom: 12px;
padding-bottom: 8px;
border-bottom: 2px solid var(--border);
}
.section-header .emoji { font-size: 15px; }
.section-count {
font-size: 11px; font-weight: 500; color: var(--text-secondary);
background: #f1f3f4; padding: 2px 8px; border-radius: 10px;
margin-left: 4px;
}
/* Card */
.card {
display: flex; gap: 14px;
padding: 14px 16px;
border-radius: 12px;
background: #f8f9fa;
margin-bottom: 8px;
transition: background 0.15s;
border: 1px solid transparent;
}
.card:hover { background: #eef2f7; border-color: #e0e4ea; }
.card-avatar {
width: 36px; height: 36px; border-radius: 50%;
display: grid; place-items: center;
font-size: 13px; font-weight: 600; color: white;
flex-shrink: 0;
}
.card-body { flex: 1; min-width: 0; }
.card-top {
display: flex; align-items: baseline; gap: 6px;
margin-bottom: 3px;
}
.card-sender { font-size: 13px; font-weight: 600; color: var(--text); }
.card-role { font-size: 11px; color: var(--text-muted); }
.card-subject {
font-size: 14px; font-weight: 500; color: var(--text);
margin-bottom: 4px;
}
.card-summary {
font-size: 13px; color: var(--text-secondary); line-height: 1.55;
}
.action-btn {
display: inline-flex; align-items: center; gap: 6px;
margin-top: 10px;
padding: 7px 18px;
border-radius: 18px;
font-size: 12px; font-weight: 500;
font-family: 'Google Sans', sans-serif;
border: none; cursor: pointer;
transition: background 0.15s;
}
.action-btn.primary { background: var(--blue); color: white; }
.action-btn.primary:hover { background: #1765cc; }
.action-btn.ghost {
background: transparent; color: var(--blue);
border: 1px solid #dadce0;
}
.action-btn.ghost:hover { background: #f6f8fc; }
/* Collapsed row */
.collapsed {
display: flex; align-items: center; gap: 12px;
padding: 12px 16px;
border-radius: 12px;
background: #f8f9fa;
margin-bottom: 8px;
font-size: 13px; color: var(--text-secondary);
cursor: pointer;
border: 1px solid transparent;
}
.collapsed:hover { background: #eef2f7; border-color: #e0e4ea; }
.collapsed-icon {
width: 36px; height: 36px; border-radius: 50%;
background: #24292e; color: white;
display: grid; place-items: center;
font-size: 13px; font-weight: 600; flex-shrink: 0;
}
.collapsed-text { flex: 1; }
.collapsed-title { font-weight: 500; color: var(--text); margin-bottom: 2px; }
.highlight { color: var(--blue); font-weight: 500; }
/* Priority indicator on section header */
.priority-high { border-bottom-color: var(--red); }
.priority-mid { border-bottom-color: var(--yellow); }
.priority-low { border-bottom-color: #dadce0; }
/* Footer */
.digest-footer {
margin-top: 36px; padding-top: 20px;
border-top: 1px solid #e8eaed;
display: flex; flex-direction: column; align-items: center; gap: 12px;
}
.orbit-badge {
display: inline-flex; align-items: center; gap: 6px;
font-size: 11px; color: var(--text-muted);
background: #f8f9fa; padding: 6px 14px; border-radius: 14px;
}
.orbit-dot {
width: 14px; height: 14px; border-radius: 50%;
background: linear-gradient(135deg, #667eea, #764ba2);
}
.footer-links {
display: flex; gap: 16px;
font-size: 11px;
}
.footer-links a {
color: var(--text-muted); text-decoration: none;
}
.footer-links a:hover { color: var(--blue); }
/* ── Summary strip at top of digest ── */
.summary-strip {
display: flex; gap: 0;
margin-bottom: 24px;
border-radius: 12px;
overflow: hidden;
border: 1px solid var(--border);
}
.summary-cell {
flex: 1;
padding: 16px;
text-align: center;
background: var(--white);
border-right: 1px solid var(--border);
}
.summary-cell:last-child { border-right: none; }
.summary-num {
font-size: 28px; font-weight: 500; color: var(--text);
font-family: 'Google Sans', sans-serif;
line-height: 1;
margin-bottom: 4px;
}
.summary-label {
font-size: 11px; color: var(--text-muted);
text-transform: uppercase; letter-spacing: 0.05em;
}
.summary-cell.urgent .summary-num { color: var(--red); }
/* ── Reply Bar ── */
.reply-bar {
display: flex; align-items: center; gap: 8px;
padding: 14px 24px;
border-top: 1px solid #e8eaed;
}
.reply-btn {
display: inline-flex; align-items: center; gap: 6px;
padding: 8px 20px;
border-radius: 18px;
border: 1px solid #dadce0;
background: var(--white);
font-size: 13px; font-weight: 500; color: #3c4043;
cursor: pointer; font-family: 'Google Sans', sans-serif;
transition: background 0.15s;
}
.reply-btn:hover { background: var(--surface-hover); }
.reply-btn svg { width: 16px; height: 16px; color: var(--text-secondary); }
/* ── Scrollbar ── */
::-webkit-scrollbar { width: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #dadce0; border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: #bdc1c6; }
</style>
</head>
<body>
<!-- ═══ Gmail Top Bar ═══ -->
<header class="gmail-bar">
<div class="gmail-bar-left">
<div class="hamburger">
<svg viewBox="0 0 24 24" width="24" height="24" fill="currentColor"><path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"/></svg>
</div>
<div class="gmail-logo">
<svg viewBox="0 0 24 24" width="28" height="28" fill="none">
<path d="M2 6a2 2 0 0 1 2-4h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6z" fill="none"/>
<rect x="2" y="4" width="20" height="16" rx="2" fill="#EA4335" opacity="0.12"/>
<path d="M22 6l-10 7L2 6" stroke="#EA4335" stroke-width="1.8" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
<rect x="2" y="4" width="20" height="16" rx="2" stroke="#EA4335" stroke-width="1.5" fill="none"/>
</svg>
<span class="gmail-logo-text">Gmail</span>
</div>
</div>
<div class="search-bar">
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M15.5 14h-.79l-.28-.27A6.47 6.47 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/></svg>
<input type="text" placeholder="搜索邮件">
<svg viewBox="0 0 24 24" fill="currentColor" style="cursor:pointer;"><path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"/></svg>
</div>
<div class="gmail-bar-right">
<button class="icon-btn" title="帮助">
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M11 18h2v-2h-2v2zm1-16C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm0-14c-2.21 0-4 1.79-4 4h2c0-1.1.9-2 2-2s2 .9 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5 0-2.21-1.79-4-4-4z"/></svg>
</button>
<button class="icon-btn" title="设置">
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58a.49.49 0 0 0 .12-.61l-1.92-3.32a.49.49 0 0 0-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54a.484.484 0 0 0-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.07.62-.07.94s.02.64.07.94l-2.03 1.58a.49.49 0 0 0-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"/></svg>
</button>
<div class="icon-btn" title="Google 应用">
<div class="app-grid">
<span></span><span></span><span></span>
<span></span><span></span><span></span>
<span></span><span></span><span></span>
</div>
</div>
<div class="user-avatar">E</div>
</div>
</header>
<!-- ═══ Digest ═══ -->
<main class="digest-wrap">
<div class="email-chrome">
<!-- Toolbar -->
<div class="email-toolbar">
<button class="icon-btn" title="返回" style="width:36px;height:36px;">
<svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor"><path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z"/></svg>
</button>
<button class="icon-btn" title="归档" style="width:36px;height:36px;">
<svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor"><path d="M20.54 5.23l-1.39-1.68C18.88 3.21 18.47 3 18 3H6c-.47 0-.88.21-1.16.55L3.46 5.23C3.17 5.57 3 5.99 3 6.5V19c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V6.5c0-.51-.17-.93-.46-1.27zM12 17.5L6.5 12H10v-2h4v2h3.5L12 17.5zM5.12 5l.81-1h12l.94 1H5.12z"/></svg>
</button>
<button class="icon-btn" title="删除" style="width:36px;height:36px;">
<svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor"><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/></svg>
</button>
<button class="icon-btn" title="标记未读" style="width:36px;height:36px;">
<svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor"><path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/></svg>
</button>
<button class="icon-btn" title="标签" style="width:36px;height:36px;">
<svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor"><path d="M17.63 5.84C17.27 5.33 16.67 5 16 5L5 5.01C3.9 5.01 3 5.9 3 7v10c0 1.1.9 1.99 2 1.99L16 19c.67 0 1.27-.33 1.63-.84L22 12l-4.37-6.16z"/></svg>
</button>
<div class="toolbar-spacer"></div>
<button class="icon-btn" style="width:36px;height:36px;">
<svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor"><path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/></svg>
</button>
<button class="icon-btn" style="width:36px;height:36px;">
<svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg>
</button>
</div>
<!-- Subject -->
<div class="email-subject-area">
<h1 class="email-subject">
☀ Eli, 你昨天的 6 封重要邮件 — Open Orbit Daily
<span class="tag">Orbit</span>
</h1>
</div>
<!-- Sender -->
<div class="sender-row">
<div class="sender-avatar">O</div>
<div class="sender-info">
<div class="sender-name">Open Orbit <span>&lt;orbit@opendesign.local&gt;</span></div>
<div class="sender-to">收件人:我 ▾</div>
</div>
<div class="sender-date">2026年5月6日 06:42</div>
<button class="icon-btn" title="回复" style="width:36px;height:36px;">
<svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor"><path d="M10 9V5l-7 7 7 7v-4.1c5 0 8.5 1.6 11 5.1-1-5-4-10-11-11z"/></svg>
</button>
<button class="icon-btn" title="更多" style="width:36px;height:36px;">
<svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor"><path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/></svg>
</button>
</div>
<!-- ═══ Digest Content ═══ -->
<div class="digest-body">
<div class="greeting">
早上好 Eli 👋<br>
以下是你昨天5月5日的 Gmail 简报。共 <strong>6 封值得关注</strong>,已按优先级分组。
</div>
<!-- Summary strip -->
<div class="summary-strip">
<div class="summary-cell urgent">
<div class="summary-num">2</div>
<div class="summary-label">需要处理</div>
</div>
<div class="summary-cell">
<div class="summary-num">2</div>
<div class="summary-label">值得关注</div>
</div>
<div class="summary-cell">
<div class="summary-num">2</div>
<div class="summary-label">仅供知悉</div>
</div>
</div>
<!-- ── Section 1: 需要处理 ── -->
<div class="section">
<div class="section-header priority-high">
<span class="emoji">🔴</span>
需要处理
<span class="section-count">2</span>
</div>
<div class="card">
<div class="card-avatar" style="background: #1a73e8;">A</div>
<div class="card-body">
<div class="card-top">
<span class="card-sender">Allen Liu</span>
<span class="card-role">CFO</span>
</div>
<div class="card-subject">Q3 预算确认</div>
<div class="card-summary">财务已审核通过 Q3 预算方案,倾向同意当前版本。等你 sign-off 后即可进入执行阶段。</div>
<button class="action-btn primary">查看邮件并回复</button>
</div>
</div>
<div class="card">
<div class="card-avatar" style="background: #0f9d58;">N</div>
<div class="card-body">
<div class="card-top">
<span class="card-sender">Nina Park</span>
<span class="card-role">客户</span>
</div>
<div class="card-subject">Login redesign 反馈</div>
<div class="card-summary">Nina 对新 login 方案提了 3 个问题:①密码重置流程 ②第三方登录按钮位置 ③无障碍对比度。建议尽快回复。</div>
<button class="action-btn primary">查看邮件并回复</button>
</div>
</div>
</div>
<!-- ── Section 2: 值得关注 ── -->
<div class="section">
<div class="section-header priority-mid">
<span class="emoji">🟡</span>
值得关注
<span class="section-count">2</span>
</div>
<div class="card">
<div class="card-avatar" style="background: #e91e63;">M</div>
<div class="card-body">
<div class="card-top">
<span class="card-sender">Marie</span>
</div>
<div class="card-subject">设计评审纪要</div>
<div class="card-summary">Marie 在纪要中 @了你和 Bob附件包含昨天设计评审的要点。无需回复仅供确认。</div>
<button class="action-btn ghost">查看原文</button>
</div>
</div>
<div class="card">
<div class="card-avatar" style="background: #ff9800;"></div>
<div class="card-body">
<div class="card-top">
<span class="card-sender">招聘团队</span>
</div>
<div class="card-subject">候选人 Sarah 二面安排</div>
<div class="card-summary">Sarah Chen 的二面已排好cc 你作为面试官之一。时间待确认。</div>
<button class="action-btn ghost">查看原文</button>
</div>
</div>
</div>
<!-- ── Section 3: 仅供知悉 ── -->
<div class="section">
<div class="section-header priority-low">
<span class="emoji"></span>
仅供知悉
<span class="section-count">2</span>
</div>
<div class="collapsed">
<div class="collapsed-icon">G</div>
<div class="collapsed-text">
<div class="collapsed-title">GitHub 通知摘要</div>
<div>已折叠 12 封通知 · <span class="highlight">1 条值得看PR #347 已合并到 main</span></div>
</div>
</div>
<div class="card">
<div class="card-avatar" style="background: #5f6368;"></div>
<div class="card-body">
<div class="card-top">
<span class="card-sender">公司全员</span>
</div>
<div class="card-subject">本周 Town Hall 提醒</div>
<div class="card-summary">本周四下午 3:00 Town Hall议题包括 Q3 目标回顾和下半年规划。</div>
</div>
</div>
</div>
<!-- Footer -->
<div class="digest-footer">
<div class="orbit-badge">
<span class="orbit-dot"></span>
已使用 Open Orbit 自动整理 · 2026-05-06 06:42 生成
</div>
</div>
</div>
<!-- Reply bar -->
<div class="reply-bar">
<button class="reply-btn">
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M10 9V5l-7 7 7 7v-4.1c5 0 8.5 1.6 11 5.1-1-5-4-10-11-11z"/></svg>
回复
</button>
<button class="reply-btn">
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M7 8V5l-7 7 7 7v-3l-4-4 4-4zm6 1V5l-7 7 7 7v-4.1c5 0 8.5 1.6 11 5.1-1-5-4-10-11-11z"/></svg>
全部回复
</button>
<button class="reply-btn">
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M14 9V5l7 7-7 7v-4.1c-5 0-8.5 1.6-11 5.1 1-5 4-10 11-11z"/></svg>
转发
</button>
</div>
</div>
</main>
<script>
// Open the matching Gmail thread in a new tab when an action button or
// reply-bar button is clicked. Uses Gmail's #search/from: deep link
// built from the sender's display name.
function openInGmail(sender, subject) {
const q = sender ? `from:${sender}` : (subject || '');
const url = 'https://mail.google.com/mail/u/0/#search/' + encodeURIComponent(q);
window.open(url, '_blank', 'noopener,noreferrer');
}
document.querySelectorAll('.card').forEach(card => {
const sender = card.querySelector('.card-sender')?.textContent?.trim();
const subject = card.querySelector('.card-subject')?.textContent?.trim();
card.querySelectorAll('.action-btn').forEach(btn => {
btn.style.cursor = 'pointer';
btn.addEventListener('click', e => {
e.preventDefault();
openInGmail(sender, subject);
});
});
});
document.querySelectorAll('.reply-btn').forEach(btn => {
btn.style.cursor = 'pointer';
btn.addEventListener('click', e => {
e.preventDefault();
window.open('https://mail.google.com/mail/u/0/#inbox', '_blank', 'noopener,noreferrer');
});
});
</script>
</body>
</html>