@zaclinley/dsh-mailharbor 0.12.2 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/lib/client.js +168 -4
- package/lib/client.js.map +2 -2
- package/lib/index.js +295 -31
- package/lib/index.js.map +4 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.13.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 246bd54: Inline signature images and everyday mail actions.
|
|
8
|
+
|
|
9
|
+
- Inline `cid:` images (signatures, embedded screenshots) are rewritten to
|
|
10
|
+
data URLs in the reader for both server and archived mail, instead of
|
|
11
|
+
appearing as attachments or broken images.
|
|
12
|
+
- Star, archive, delete-to-trash and move-to-folder actions in the reader; the
|
|
13
|
+
local backup is updated and the server is moved when the message still exists
|
|
14
|
+
there.
|
|
15
|
+
- Selection mode gains bulk read/unread/star/archive/delete.
|
|
16
|
+
- Stars are stored locally and mirrored to IMAP `\Flagged`; the list shows a
|
|
17
|
+
star marker.
|
|
18
|
+
|
|
3
19
|
## 0.12.2
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/lib/client.js
CHANGED
|
@@ -35,7 +35,7 @@ __export(index_exports, {
|
|
|
35
35
|
module.exports = __toCommonJS(index_exports);
|
|
36
36
|
|
|
37
37
|
// src/client/styles.css
|
|
38
|
-
var styles_default = "/* MailHarbor panel + settings.\n Tokens come from the DSH shell (dark by default); fallbacks match the\n default dark theme so the panel also renders in a bare host page.\n Component rules are all scoped under `.mailharbor` and the generic element\n reset lives in `:where()` so it cannot outrank a component class. */\n\n.mailharbor {\n --m-bg: var(--dsw-alias-bg-base, #151517);\n --m-bg-1: var(--dsw-alias-bg-layer-1, #232324);\n --m-bg-2: var(--dsw-alias-bg-layer-2, #2c2c2e);\n --m-bg-3: var(--dsw-alias-bg-layer-3, #353638);\n --m-line: var(--dsw-alias-border-l2, #ffffff1f);\n --m-line-soft: var(--dsw-alias-border-l1, #ffffff0f);\n --m-line-strong: var(--dsw-alias-border-l3, #ffffff29);\n --m-text: var(--dsw-alias-label-primary, #f9fafb);\n --m-text-2: var(--dsw-alias-label-secondary, #cfd3d6);\n --m-text-3: var(--dsw-alias-label-tertiary, #adb2b8);\n --m-caption: var(--dsw-alias-label-caption, #81858c);\n --m-accent: #5686fe;\n --m-accent-soft: rgba(86, 134, 254, 0.14);\n --m-primary-bg: var(--dsw-alias-brand-primary, #f9fafb);\n --m-primary-fg: var(--dsw-alias-label-primary-foreground, #0f1115);\n --m-hover: var(--dsw-alias-interactive-bg-hover, #ffffff14);\n --m-danger: #f25a5a;\n --m-ok: #3fbf7f;\n --m-warn: var(--dsw-alias-state-warn-label, #dd8629);\n --m-radius: 8px;\n --m-shadow: 0 18px 60px rgba(0, 0, 0, 0.5);\n\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n background: var(--m-bg);\n color: var(--m-text);\n font-size: 13px;\n line-height: 1.5;\n -webkit-font-smoothing: antialiased;\n}\n\n.mailharbor *,\n.mailharbor *::before,\n.mailharbor *::after {\n box-sizing: border-box;\n}\n\n/* ---------- base controls ---------- */\n\n.mailharbor :where(button) {\n font: inherit;\n color: inherit;\n background: transparent;\n border: 0;\n margin: 0;\n cursor: pointer;\n}\n\n.mailharbor button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n height: 30px;\n padding: 0 12px;\n border-radius: var(--m-radius);\n border: 1px solid transparent;\n color: var(--m-text-2);\n font-size: 12.5px;\n font-weight: 500;\n white-space: nowrap;\n transition:\n background 120ms ease,\n color 120ms ease,\n border-color 120ms ease;\n}\n\n.mailharbor button:hover:not(:disabled) {\n background: var(--m-hover);\n color: var(--m-text);\n}\n\n.mailharbor button:disabled {\n opacity: 0.45;\n cursor: default;\n}\n\n.mailharbor button.primary {\n background: var(--m-primary-bg);\n color: var(--m-primary-fg);\n border-color: transparent;\n}\n\n.mailharbor button.primary:hover:not(:disabled) {\n background: var(--m-primary-bg);\n filter: brightness(0.94);\n color: var(--m-primary-fg);\n}\n\n.mailharbor button.ghost {\n border-color: var(--m-line);\n color: var(--m-text-2);\n}\n\n.mailharbor button.ghost:hover:not(:disabled) {\n border-color: var(--m-line-strong);\n color: var(--m-text);\n}\n\n.mailharbor button.subtle {\n color: var(--m-text-3);\n padding: 0 8px;\n}\n\n.mailharbor button.icon {\n width: 30px;\n padding: 0;\n}\n\n.mailharbor button.danger {\n color: var(--m-danger);\n}\n\n.mailharbor input,\n.mailharbor select,\n.mailharbor textarea {\n font: inherit;\n color: var(--m-text);\n background: var(--m-bg-1);\n border: 1px solid var(--m-line);\n border-radius: var(--m-radius);\n padding: 0 10px;\n height: 32px;\n min-width: 0;\n}\n\n.mailharbor textarea {\n height: auto;\n padding: 8px 10px;\n resize: vertical;\n line-height: 1.6;\n}\n\n.mailharbor select {\n padding-right: 26px;\n appearance: none;\n background-image:\n linear-gradient(45deg, transparent 50%, var(--m-text-3) 50%),\n linear-gradient(135deg, var(--m-text-3) 50%, transparent 50%);\n background-position:\n calc(100% - 15px) 14px,\n calc(100% - 10px) 14px;\n background-size:\n 5px 5px,\n 5px 5px;\n background-repeat: no-repeat;\n}\n\n.mailharbor ::placeholder {\n color: var(--m-caption);\n}\n\n.mailharbor input:focus-visible,\n.mailharbor select:focus-visible,\n.mailharbor textarea:focus-visible,\n.mailharbor button:focus-visible,\n.mailharbor [contenteditable='true']:focus-visible {\n outline: 2px solid rgba(86, 134, 254, 0.55);\n outline-offset: -1px;\n}\n\n.mailharbor .spacer {\n flex: 1;\n}\n\n.mailharbor .muted {\n color: var(--m-text-3);\n}\n\n.mailharbor .small {\n font-size: 12px;\n}\n\n.mailharbor .badge {\n display: inline-flex;\n align-items: center;\n height: 18px;\n padding: 0 6px;\n border-radius: 999px;\n font-size: 10.5px;\n font-weight: 500;\n background: var(--m-bg-3);\n color: var(--m-text-2);\n}\n\n.mailharbor .badge.ok {\n background: rgba(63, 191, 127, 0.16);\n color: var(--m-ok);\n}\n\n.mailharbor .badge.warn {\n background: rgba(221, 134, 41, 0.16);\n color: var(--m-warn);\n}\n\n.mailharbor .error {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 14px;\n color: var(--m-danger);\n background: rgba(242, 90, 90, 0.1);\n border-bottom: 1px solid rgba(242, 90, 90, 0.2);\n font-size: 12.5px;\n}\n\n/* ---------- shell ---------- */\n\n.mailharbor-topbar {\n display: flex;\n align-items: center;\n gap: 10px;\n height: 52px;\n padding: 0 14px;\n border-bottom: 1px solid var(--m-line-soft);\n background: var(--m-bg);\n flex: none;\n}\n\n.mailharbor-account {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n max-width: 220px;\n padding: 4px 8px 4px 4px;\n border-radius: 999px;\n border: 1px solid transparent;\n cursor: default;\n}\n\n.mailharbor-account:hover {\n background: var(--m-hover);\n}\n\n.mailharbor-account .name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-weight: 500;\n}\n\n.mailharbor-account select {\n height: 26px;\n background: transparent;\n border-color: transparent;\n font-weight: 500;\n}\n\n.mailharbor-body {\n display: flex;\n flex: 1;\n min-height: 0;\n position: relative;\n}\n\n.mailharbor button.active {\n background: var(--m-accent-soft);\n color: var(--m-text);\n}\n\n.mailharbor-list {\n display: flex;\n flex-direction: column;\n width: 360px;\n flex: none;\n border-right: 1px solid var(--m-line-soft);\n min-height: 0;\n}\n\n.mailharbor-reader {\n flex: 1;\n min-width: 0;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n\n@media (max-width: 1000px) {\n .mailharbor-list {\n width: 300px;\n }\n}\n\n.mailharbor-narrow .mailharbor-body[data-mode='reader'] .mailharbor-list {\n display: none;\n}\n\n.mailharbor-narrow .mailharbor-body[data-mode='list'] .mailharbor-reader {\n display: none;\n}\n\n/* ---------- segmented control ---------- */\n\n.mailharbor-segment {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n padding: 2px;\n border-radius: 9px;\n background: var(--m-bg-2);\n}\n\n.mailharbor-segment button {\n height: 26px;\n padding: 0 12px;\n border-radius: 7px;\n color: var(--m-text-3);\n font-size: 12px;\n}\n\n.mailharbor-segment button:hover:not(.active) {\n color: var(--m-text-2);\n background: transparent;\n}\n\n.mailharbor-segment button.active {\n background: var(--m-bg-3);\n color: var(--m-text);\n}\n\n/* ---------- list ---------- */\n\n.mailharbor-filters {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px;\n border-bottom: 1px solid var(--m-line-soft);\n flex: none;\n}\n\n.mailharbor-filters select {\n width: 128px;\n flex: none;\n font-size: 12px;\n}\n\n.mailharbor-filters input[type='search'] {\n flex: 1;\n height: 30px;\n font-size: 12.5px;\n}\n\n.mailharbor-rows {\n flex: 1;\n overflow: auto;\n min-height: 0;\n}\n\n.mailharbor-row {\n display: flex;\n flex-direction: column;\n gap: 3px;\n width: 100%;\n padding: 10px 14px;\n border: 0;\n border-bottom: 1px solid var(--m-line-soft);\n border-left: 2px solid transparent;\n border-radius: 0;\n background: transparent;\n color: inherit;\n text-align: left;\n cursor: pointer;\n user-select: none;\n}\n\n.mailharbor-row:hover {\n background: var(--m-hover);\n}\n\n.mailharbor-row.selected {\n background: var(--m-accent-soft);\n border-left-color: var(--m-accent);\n}\n\n.mailharbor-row .line-1,\n.mailharbor-row .line-2 {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n width: 100%;\n}\n\n.mailharbor-row .from {\n font-weight: 600;\n font-size: 12.5px;\n color: var(--m-text-2);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.mailharbor-row .date {\n margin-left: auto;\n color: var(--m-caption);\n font-size: 11px;\n flex: none;\n}\n\n.mailharbor-row .subject {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--m-text-2);\n font-size: 12.5px;\n}\n\n.mailharbor-row .snippet {\n color: var(--m-caption);\n font-size: 11.5px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n width: 100%;\n}\n\n.mailharbor-row.unread .from,\n.mailharbor-row.unread .subject {\n color: var(--m-text);\n}\n\n.mailharbor-row .dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--m-accent);\n flex: none;\n}\n\n.mailharbor-row .paperclip {\n color: var(--m-caption);\n flex: none;\n display: inline-flex;\n}\n\n.mailharbor-list-foot {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-top: 1px solid var(--m-line-soft);\n color: var(--m-text-3);\n font-size: 11.5px;\n flex: none;\n}\n\n.mailharbor-empty {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 10px;\n padding: 48px 24px;\n color: var(--m-text-3);\n text-align: center;\n}\n\n.mailharbor-empty svg {\n opacity: 0.5;\n}\n\n.mailharbor-empty .title {\n color: var(--m-text-2);\n font-size: 13px;\n font-weight: 500;\n}\n\n/* ---------- reader ---------- */\n\n.mailharbor-reader-head {\n padding: 16px 20px 12px;\n border-bottom: 1px solid var(--m-line-soft);\n flex: none;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.mailharbor-reader-title {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n}\n\n.mailharbor-reader-title h2 {\n margin: 0;\n font-size: 17px;\n line-height: 1.35;\n font-weight: 600;\n letter-spacing: -0.01em;\n word-break: break-word;\n}\n\n.mailharbor-reader-meta {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 4px 10px;\n color: var(--m-text-3);\n font-size: 12px;\n}\n\n.mailharbor-reader-meta .who {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n color: var(--m-text-2);\n}\n\n.mailharbor-reader-meta .who strong {\n color: var(--m-text);\n font-weight: 600;\n}\n\n.mailharbor-reader-actions {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.mailharbor-reader-body {\n flex: 1;\n min-height: 0;\n display: flex;\n flex-direction: column;\n padding: 14px 18px 18px;\n background: var(--m-bg-2);\n}\n\n.mailharbor-reader-body iframe {\n flex: 1;\n width: 100%;\n border: 0;\n border-radius: 10px;\n background: #fff;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);\n}\n\n.mailharbor-reader-body pre {\n flex: 1;\n overflow: auto;\n margin: 0;\n padding: 20px 22px;\n white-space: pre-wrap;\n word-break: break-word;\n background: #fff;\n border-radius: 10px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);\n color: #171a21;\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 12.5px;\n line-height: 1.7;\n}\n\n.mailharbor-attachments {\n padding: 10px 18px;\n border-top: 1px solid var(--m-line-soft);\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n flex: none;\n background: var(--m-bg);\n}\n\n.mailharbor-attachment {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n height: 30px;\n padding: 0 10px;\n border: 1px solid var(--m-line);\n border-radius: var(--m-radius);\n font-size: 12px;\n text-decoration: none;\n color: var(--m-text-2);\n max-width: 260px;\n background: var(--m-bg-1);\n}\n\n.mailharbor-attachment:hover {\n border-color: var(--m-line-strong);\n color: var(--m-text);\n}\n\n.mailharbor-attachment .name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* ---------- AI rail ---------- */\n\n.mailharbor-ai {\n display: flex;\n flex-direction: column;\n width: 340px;\n flex: none;\n min-height: 0;\n border-left: 1px solid var(--m-line-soft);\n background: var(--m-bg);\n}\n\n.mailharbor-ai-head {\n display: flex;\n align-items: center;\n gap: 8px;\n height: 46px;\n padding: 0 8px 0 14px;\n border-bottom: 1px solid var(--m-line-soft);\n flex: none;\n}\n\n.mailharbor-ai-head strong {\n font-size: 13px;\n font-weight: 600;\n}\n\n.mailharbor-ai-confirm {\n display: inline-flex;\n gap: 2px;\n}\n\n.mailharbor-ai-context {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 9px 14px 10px;\n border-bottom: 1px solid var(--m-line-soft);\n flex: none;\n}\n\n.mailharbor-ai-context strong {\n font-size: 12.5px;\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.mailharbor-ai-warn {\n padding: 8px 14px;\n color: var(--m-warn);\n background: rgba(221, 134, 41, 0.1);\n font-size: 12px;\n flex: none;\n}\n\n.mailharbor-ai-quick {\n display: flex;\n gap: 6px;\n padding: 10px 14px;\n border-bottom: 1px solid var(--m-line-soft);\n flex: none;\n}\n\n.mailharbor-ai-quick button {\n flex: 1;\n padding: 0 6px;\n}\n\n.mailharbor-ai-list {\n flex: 1;\n min-height: 0;\n overflow: auto;\n display: flex;\n flex-direction: column;\n gap: 10px;\n padding: 12px 14px;\n}\n\n.mailharbor-ai-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n padding: 30px 12px;\n text-align: center;\n color: var(--m-text-3);\n}\n\n.mailharbor-ai-empty .title {\n color: var(--m-text-2);\n font-weight: 500;\n font-size: 12.5px;\n}\n\n.mailharbor-ai-card {\n display: flex;\n flex-direction: column;\n border: 1px solid var(--m-line-soft);\n border-radius: 10px;\n background: var(--m-bg-1);\n overflow: hidden;\n}\n\n.mailharbor-ai-card.generating {\n opacity: 0.7;\n}\n\n.mailharbor-ai-card-head {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 7px 8px 7px 12px;\n border-bottom: 1px solid var(--m-line-soft);\n font-size: 11.5px;\n color: var(--m-text-3);\n}\n\n.mailharbor-ai-card-head > span:first-child {\n color: var(--m-text-2);\n font-weight: 600;\n}\n\n.mailharbor-ai-summary {\n display: flex;\n flex-direction: column;\n gap: 10px;\n padding: 10px 12px;\n}\n\n.mailharbor-ai-summary section h4 {\n margin: 0 0 3px;\n font-size: 11px;\n color: var(--m-text-3);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.mailharbor-ai-summary section p {\n margin: 0;\n white-space: pre-wrap;\n font-size: 12.5px;\n line-height: 1.65;\n color: var(--m-text);\n}\n\n.mailharbor-ai-text {\n padding: 10px 12px;\n\n white-space: pre-wrap;\n font-size: 12.5px;\n line-height: 1.65;\n color: var(--m-text);\n}\n\n.mailharbor-ai-card-actions {\n display: flex;\n align-items: center;\n gap: 4px;\n flex-wrap: wrap;\n padding: 6px 8px;\n border-top: 1px solid var(--m-line-soft);\n}\n\n.mailharbor-ai-card-actions button {\n height: 26px;\n padding: 0 8px;\n font-size: 11.5px;\n}\n\n.mailharbor-ai-ask {\n display: flex;\n gap: 6px;\n padding: 10px 12px;\n border-top: 1px solid var(--m-line-soft);\n flex: none;\n}\n\n.mailharbor-ai-ask input {\n flex: 1;\n height: 32px;\n}\n\n.mailharbor-ai-error {\n color: var(--m-danger);\n font-size: 12px;\n padding: 0 2px;\n}\n\n@media (max-width: 1280px) {\n .mailharbor-ai {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: min(420px, 94%);\n z-index: 6;\n border-left: 1px solid var(--m-line);\n box-shadow: -12px 0 40px rgba(0, 0, 0, 0.45);\n }\n}\n\n/* ---------- AI summary ---------- */\n\n.mailharbor-divider {\n width: 1px;\n height: 18px;\n margin: 0 4px;\n background: var(--m-line);\n}\n\n.mailharbor-summary {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.mailharbor-summary section h4 {\n margin: 0 0 6px;\n font-size: 11.5px;\n font-weight: 600;\n color: var(--m-text-3);\n text-transform: uppercase;\n letter-spacing: 0.06em;\n}\n\n.mailharbor-summary section p {\n margin: 0;\n white-space: pre-wrap;\n line-height: 1.75;\n color: var(--m-text);\n}\n\n/* ---------- modal / forms ---------- */\n\n.mailharbor-portal {\n position: fixed;\n inset: 0;\n z-index: 80;\n height: auto;\n background: transparent;\n pointer-events: none;\n}\n\n.mailharbor-portal .mailharbor-modal-mask {\n pointer-events: auto;\n}\n\n.mailharbor-modal-mask {\n position: fixed;\n inset: 0;\n z-index: 60;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 24px;\n background: rgba(0, 0, 0, 0.55);\n backdrop-filter: blur(2px);\n}\n\n.mailharbor-modal {\n display: flex;\n flex-direction: column;\n width: min(720px, 100%);\n max-height: 86vh;\n overflow: hidden;\n border: 1px solid var(--m-line);\n border-radius: 14px;\n background: var(--m-bg-1);\n color: var(--m-text);\n box-shadow: var(--m-shadow);\n}\n\n.mailharbor-modal > header {\n display: flex;\n align-items: center;\n gap: 8px;\n height: 52px;\n padding: 0 14px 0 18px;\n border-bottom: 1px solid var(--m-line-soft);\n font-size: 14px;\n font-weight: 600;\n}\n\n.mailharbor-modal .content {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 18px;\n overflow: auto;\n}\n\n.mailharbor-modal > footer {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 18px;\n border-top: 1px solid var(--m-line-soft);\n}\n\n.mailharbor-field {\n display: flex;\n flex-direction: column;\n gap: 5px;\n min-width: 0;\n}\n\n.mailharbor-field > input,\n.mailharbor-field > select,\n.mailharbor-field > textarea,\n.mailharbor-card > textarea {\n width: 100%;\n min-width: 0;\n}\n\n.mailharbor-field > label {\n font-size: 11.5px;\n color: var(--m-text-3);\n}\n\n.mailharbor-grid {\n display: grid;\n grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);\n gap: 10px;\n min-width: 0;\n}\n\n.mailharbor-grid.three {\n grid-template-columns: minmax(0, 2fr) minmax(72px, 90px) auto;\n align-items: end;\n min-width: 0;\n}\n\n.mailharbor-toggle {\n display: inline-flex;\n align-items: center;\n gap: 7px;\n color: var(--m-text-2);\n font-size: 12.5px;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.mailharbor-toggle input[type='checkbox'] {\n width: 14px;\n height: 14px;\n accent-color: var(--m-accent);\n}\n\n/* ---------- composer ---------- */\n\n.mailharbor-toolbar {\n display: flex;\n align-items: center;\n gap: 2px;\n flex-wrap: wrap;\n padding: 6px;\n border: 1px solid var(--m-line-soft);\n border-bottom: 0;\n border-radius: 10px 10px 0 0;\n background: var(--m-bg-2);\n}\n\n.mailharbor-toolbar button {\n height: 26px;\n padding: 0 9px;\n border-radius: 6px;\n color: var(--m-text-2);\n font-size: 12px;\n}\n\n.mailharbor-toolbar button:hover {\n background: var(--m-bg-3);\n color: var(--m-text);\n}\n\n.mailharbor-editor {\n min-height: 240px;\n max-height: 44vh;\n overflow: auto;\n padding: 14px 16px;\n border: 1px solid var(--m-line-soft);\n border-radius: 0 0 10px 10px;\n background: #fff;\n color: #171a21;\n outline: none;\n font-size: 13.5px;\n line-height: 1.7;\n}\n\n.mailharbor-editor:empty::before {\n content: attr(data-placeholder);\n color: #9aa0ab;\n}\n\n/* ---------- inline confirm ---------- */\n\n.mailharbor-confirm {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-radius: 8px;\n border: 1px solid var(--m-line);\n background: var(--m-bg-2);\n color: var(--m-text-2);\n font-size: 12.5px;\n}\n\n/* ---------- selection / extraction ---------- */\n\n.mailharbor-selectbar {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n margin: 0 12px 8px;\n border: 1px solid var(--m-accent-soft);\n border-radius: 9px;\n background: var(--m-accent-soft);\n}\n\n.mailharbor-selectbar select {\n height: 28px;\n max-width: 200px;\n}\n\n.mailharbor-row.selectable input[type='checkbox'] {\n width: 15px;\n height: 15px;\n flex: none;\n accent-color: var(--m-accent);\n}\n\n.mailharbor-extract-row {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 9px 10px;\n border: 1px solid var(--m-line-soft);\n border-radius: 9px;\n background: var(--m-bg-1);\n cursor: pointer;\n}\n\n.mailharbor-extract-row input {\n margin-top: 2px;\n accent-color: var(--m-accent);\n}\n\n.mailharbor-extract-row > span {\n display: flex;\n flex-direction: column;\n gap: 3px;\n min-width: 0;\n}\n\n.mailharbor-kv {\n display: grid;\n grid-template-columns: auto minmax(0, 1fr);\n gap: 6px 12px;\n margin: 0;\n font-size: 12.5px;\n}\n\n.mailharbor-kv dt {\n color: var(--m-text-3);\n}\n\n.mailharbor-kv dd {\n margin: 0;\n overflow-wrap: anywhere;\n}\n\n/* ---------- tasks panel ---------- */\n\n.mailharbor .chip {\n height: 26px;\n padding: 0 10px;\n border: 1px solid var(--m-line);\n border-radius: 999px;\n color: var(--m-text-3);\n font-size: 12px;\n}\n\n.mailharbor .chip.active {\n background: var(--m-accent-soft);\n border-color: transparent;\n color: var(--m-text);\n}\n\n.tasks-body {\n flex: 1;\n min-height: 0;\n overflow: auto;\n display: flex;\n flex-direction: column;\n gap: 18px;\n padding: 18px 20px 48px;\n width: 100%;\n max-width: 940px;\n margin: 0 auto;\n}\n\n.tasks-overview {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));\n gap: 12px;\n}\n\n.tasks-progress,\n.tasks-project {\n display: flex;\n flex-direction: column;\n gap: 7px;\n padding: 12px 14px;\n border: 1px solid var(--m-line-soft);\n border-radius: 12px;\n background: var(--m-bg-1);\n min-width: 0;\n}\n\n.tasks-progress-head,\n.tasks-project-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n min-width: 0;\n}\n\n.tasks-project-head .name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 12.5px;\n font-weight: 500;\n}\n\n.tasks-bar {\n height: 6px;\n border-radius: 999px;\n background: var(--m-bg-3);\n overflow: hidden;\n}\n\n.tasks-bar span {\n display: block;\n height: 100%;\n border-radius: 999px;\n background: var(--m-accent);\n transition: width 200ms ease;\n}\n\n.tasks-bar.small {\n height: 4px;\n}\n\n.tasks-filters {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n.tasks-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.tasks-row {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 9px 12px;\n border: 1px solid var(--m-line-soft);\n border-radius: 10px;\n background: var(--m-bg-1);\n}\n\n.tasks-row input[type='checkbox'] {\n width: 16px;\n height: 16px;\n flex: none;\n accent-color: var(--m-accent);\n}\n\n.tasks-row .tasks-title {\n flex: 1;\n min-width: 0;\n height: auto;\n padding: 0;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 4px;\n text-align: left;\n border: 0;\n background: transparent;\n}\n\n.tasks-row .tasks-title:hover {\n background: transparent;\n}\n\n.tasks-row .tasks-title > span:first-child {\n font-size: 13px;\n color: var(--m-text);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n max-width: 100%;\n}\n\n.tasks-row.done .tasks-title > span:first-child {\n color: var(--m-text-3);\n text-decoration: line-through;\n}\n\n.tasks-meta {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 6px;\n font-size: 11px;\n color: var(--m-text-3);\n}\n\n.tasks-meta .due.overdue {\n color: var(--m-danger);\n}\n\n.tasks-list-wrap {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n/* ---------- markdown ---------- */\n\n.mailharbor-markdown {\n display: flex;\n flex-direction: column;\n gap: 8px;\n font-size: 12.5px;\n line-height: 1.68;\n overflow-wrap: anywhere;\n}\n\n.mailharbor-markdown > *:first-child {\n margin-top: 0;\n}\n\n.mailharbor-markdown > *:last-child {\n margin-bottom: 0;\n}\n\n.mailharbor-markdown p {\n margin: 0;\n white-space: pre-wrap;\n}\n\n.mailharbor-markdown h1,\n.mailharbor-markdown h2,\n.mailharbor-markdown h3,\n.mailharbor-markdown h4,\n.mailharbor-markdown h5,\n.mailharbor-markdown h6 {\n margin: 4px 0 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--m-text);\n}\n\n.mailharbor-markdown ul,\n.mailharbor-markdown ol {\n margin: 0;\n padding-left: 20px;\n display: flex;\n flex-direction: column;\n gap: 3px;\n}\n\n.mailharbor-markdown li::marker {\n color: var(--m-text-3);\n}\n\n.mailharbor-markdown a {\n color: var(--m-accent);\n text-decoration: none;\n}\n\n.mailharbor-markdown a:hover {\n text-decoration: underline;\n}\n\n.mailharbor-markdown code {\n padding: 1px 4px;\n border-radius: 4px;\n background: var(--m-bg-2);\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 11.5px;\n}\n\n.mailharbor-markdown pre {\n margin: 0;\n padding: 10px 12px;\n border-radius: 8px;\n background: var(--m-bg);\n border: 1px solid var(--m-line-soft);\n overflow: auto;\n}\n\n.mailharbor-markdown pre code {\n padding: 0;\n background: transparent;\n}\n\n.mailharbor-markdown blockquote {\n margin: 0;\n padding-left: 10px;\n border-left: 2px solid var(--m-line);\n color: var(--m-text-2);\n}\n\n.mailharbor-markdown hr {\n width: 100%;\n margin: 4px 0;\n border: 0;\n border-top: 1px solid var(--m-line-soft);\n}\n\n/* ---------- composer AI ---------- */\n\n.mailharbor-toolbar button.ai {\n color: var(--m-accent);\n}\n\n.mailharbor-compose-foot {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n flex-wrap: wrap;\n}\n\n.mailharbor-versions {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-wrap: wrap;\n padding-top: 8px;\n}\n\n.mailharbor-versions .chip {\n height: 22px;\n padding: 0 8px;\n border: 1px solid var(--m-line);\n border-radius: 999px;\n color: var(--m-text-3);\n font-size: 11px;\n}\n\n.mailharbor-versions .chip.active {\n background: var(--m-accent-soft);\n border-color: transparent;\n color: var(--m-text);\n}\n\n/* ---------- settings ---------- */\n\n.mailharbor.mailharbor-settings-page {\n height: auto;\n min-height: 100%;\n overflow: visible;\n}\n\n.mailharbor-settings {\n flex: 0 0 auto;\n width: 100%;\n max-width: 100%;\n min-width: 0;\n padding: 18px 20px 48px;\n display: flex;\n flex-direction: column;\n gap: 16px;\n overflow-x: hidden;\n}\n\n.mailharbor-settings > * {\n min-width: 0;\n}\n\n.mailharbor-settings h2 {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n letter-spacing: -0.01em;\n}\n\n.mailharbor-settings h3 {\n margin: 0;\n font-size: 12px;\n font-weight: 600;\n color: var(--m-text-3);\n text-transform: uppercase;\n letter-spacing: 0.06em;\n}\n\n.mailharbor-card {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 16px;\n border: 1px solid var(--m-line-soft);\n border-radius: 12px;\n background: var(--m-bg-1);\n min-width: 0;\n overflow: hidden;\n}\n\n.mailharbor-account-row {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.mailharbor-account-row .meta {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.mailharbor-account-row .meta strong {\n font-weight: 600;\n}\n\n.mailharbor-account-row .meta span {\n color: var(--m-text-3);\n font-size: 11.5px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.mailharbor .avatar {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n border-radius: 50%;\n background: var(--m-accent-soft);\n color: var(--m-accent);\n font-weight: 600;\n}\n\n.mailharbor-log {\n padding: 10px 12px;\n border-radius: 8px;\n background: var(--m-bg);\n border: 1px solid var(--m-line-soft);\n color: var(--m-text-2);\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 11px;\n line-height: 1.6;\n max-height: 220px;\n overflow: auto;\n white-space: pre-wrap;\n}\n\n.mailharbor-kv {\n display: grid;\n grid-template-columns: minmax(120px, 170px) 1fr;\n gap: 6px 14px;\n font-size: 12px;\n margin: 0;\n}\n\n.mailharbor-kv dt {\n color: var(--m-text-3);\n}\n\n.mailharbor-kv dd {\n margin: 0;\n color: var(--m-text-2);\n word-break: break-all;\n}\n\n.mailharbor hr {\n border: 0;\n border-top: 1px solid var(--m-line-soft);\n margin: 2px 0;\n}\n\n/* ---------- conversation rows ---------- */\n\n.mailharbor-thread {\n display: flex;\n flex-direction: column;\n}\n\n.mailharbor-row.compact {\n padding-top: 6px;\n padding-bottom: 6px;\n padding-left: 34px;\n background: var(--m-bg);\n}\n\n.mailharbor-row.compact .line-1 {\n opacity: 0.85;\n}\n\n.mailharbor-row.compact .snippet {\n -webkit-line-clamp: 1;\n}\n\n.mailharbor .to-label {\n font-size: 10.5px;\n color: var(--m-text-3);\n flex: none;\n}\n\n.mailharbor .thread-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n border-radius: 999px;\n background: var(--m-bg-3);\n color: var(--m-text-2);\n font-size: 10.5px;\n flex: none;\n}\n\n.mailharbor .thread-count:hover {\n background: var(--m-accent-soft);\n color: var(--m-text);\n}\n\n.mailharbor-account {\n height: auto;\n padding: 3px 8px 3px 3px;\n border-radius: 8px;\n gap: 8px;\n}\n\n.mailharbor-account:hover {\n background: var(--m-hover);\n}\n\n/* ---------- mailbox sidebar ---------- */\n\n.mailharbor-side {\n display: flex;\n flex-direction: column;\n gap: 2px;\n width: 214px;\n flex: none;\n padding: 10px 8px;\n overflow: auto;\n border-right: 1px solid var(--m-line-soft);\n background: var(--m-bg);\n}\n\n.mailharbor-side-section {\n padding: 12px 8px 4px;\n font-size: 10.5px;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n color: var(--m-text-3);\n}\n\n.mailharbor-side-item {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n height: 32px;\n padding: 0 8px;\n border-radius: 8px;\n color: var(--m-text-2);\n font-size: 12.5px;\n text-align: left;\n flex: none;\n}\n\n.mailharbor-side-item:hover {\n background: var(--m-hover);\n}\n\n.mailharbor-side-item.active {\n background: var(--m-accent-soft);\n color: var(--m-text);\n}\n\n.mailharbor-side-item .name {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.mailharbor-side-item .sub {\n display: block;\n font-size: 10.5px;\n color: var(--m-text-3);\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.mailharbor-side-item .count {\n font-size: 11px;\n color: var(--m-text-3);\n}\n\n.mailharbor-side-item svg {\n flex: none;\n color: var(--m-text-3);\n}\n\n.mailharbor-side-item.active svg {\n color: var(--m-accent);\n}\n\n@media (max-width: 900px) {\n .mailharbor-side {\n display: none;\n }\n}\n\n/* ---------- task board ---------- */\n\n.tasks-board-wrap {\n flex: 1;\n min-height: 0;\n overflow: auto;\n display: flex;\n flex-direction: column;\n gap: 14px;\n padding: 16px 18px 40px;\n}\n\n.tasks-summary {\n display: flex;\n align-items: center;\n gap: 20px;\n padding: 14px 16px;\n border: 1px solid var(--m-line-soft);\n border-radius: 12px;\n background: var(--m-bg-1);\n}\n\n.tasks-summary-main {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 7px;\n}\n\n.tasks-summary-labels {\n display: flex;\n align-items: baseline;\n gap: 10px;\n}\n\n.tasks-stats {\n display: flex;\n gap: 18px;\n}\n\n.tasks-stat {\n display: flex;\n flex-direction: column;\n gap: 1px;\n min-width: 42px;\n}\n\n.tasks-stat strong {\n font-size: 16px;\n font-weight: 600;\n color: var(--m-text);\n}\n\n.tasks-stat span {\n font-size: 11px;\n color: var(--m-text-3);\n}\n\n.tasks-stat.danger strong {\n color: var(--m-danger);\n}\n\n.tasks-toolbar {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.tasks-board {\n display: grid;\n grid-template-columns: repeat(4, minmax(0, 1fr));\n gap: 14px;\n align-items: start;\n}\n\n.task-column {\n display: flex;\n flex-direction: column;\n gap: 8px;\n min-height: 140px;\n padding: 8px;\n border: 1px solid var(--m-line-soft);\n border-radius: 12px;\n background: var(--m-bg-1);\n}\n\n.task-column-head {\n display: flex;\n align-items: center;\n gap: 7px;\n padding: 2px 4px 6px;\n}\n\n.task-column-head strong {\n font-size: 12.5px;\n font-weight: 600;\n}\n\n.task-column-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n border-radius: 999px;\n background: var(--m-bg-3);\n color: var(--m-text-3);\n font-size: 10.5px;\n}\n\n.task-dot {\n width: 7px;\n height: 7px;\n border-radius: 999px;\n background: var(--m-text-3);\n}\n\n.task-dot.NEEDS-ACTION {\n background: #8a8f98;\n}\n\n.task-dot.IN-PROCESS {\n background: var(--m-accent);\n}\n\n.task-dot.COMPLETED {\n background: var(--m-ok);\n}\n\n.task-dot.CANCELLED {\n background: var(--m-danger);\n opacity: 0.7;\n}\n\n.task-column-body {\n display: flex;\n flex-direction: column;\n gap: 8px;\n min-height: 60px;\n}\n\n.task-column-empty {\n padding: 18px 8px;\n text-align: center;\n color: var(--m-text-3);\n font-size: 11.5px;\n border: 1px dashed var(--m-line-soft);\n border-radius: 9px;\n}\n\n.task-card {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 10px 11px;\n border: 1px solid var(--m-line-soft);\n border-radius: 10px;\n background: var(--m-bg);\n cursor: grab;\n transition:\n border-color 120ms ease,\n box-shadow 120ms ease;\n}\n\n.task-card:hover {\n border-color: var(--m-line);\n box-shadow: 0 4px 14px rgba(0, 0, 0, 0.16);\n}\n\n.task-card.dragging {\n opacity: 0.5;\n}\n\n.task-card-top {\n display: flex;\n align-items: flex-start;\n gap: 7px;\n}\n\n.task-card-title {\n flex: 1;\n min-width: 0;\n font-size: 12.5px;\n line-height: 1.45;\n color: var(--m-text);\n overflow-wrap: anywhere;\n}\n\n.task-priority {\n width: 3px;\n height: 14px;\n margin-top: 2px;\n border-radius: 999px;\n background: transparent;\n flex: none;\n}\n\n.task-priority.p5 {\n background: #d9a441;\n}\n\n.task-priority.p9 {\n background: var(--m-danger);\n}\n\n.task-card-delete {\n width: 18px;\n height: 18px;\n flex: none;\n border-radius: 5px;\n color: var(--m-text-3);\n opacity: 0;\n}\n\n.task-card:hover .task-card-delete {\n opacity: 1;\n}\n\n.task-card-notes {\n margin: 0;\n font-size: 11.5px;\n line-height: 1.55;\n color: var(--m-text-3);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.task-card-meta {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 6px;\n font-size: 10.5px;\n color: var(--m-text-3);\n}\n\n.task-due,\n.task-owner,\n.task-project,\n.task-priority-label {\n display: inline-flex;\n align-items: center;\n gap: 3px;\n padding: 1px 6px;\n border-radius: 5px;\n background: var(--m-bg-2);\n}\n\n.task-due.overdue {\n color: var(--m-danger);\n background: rgba(242, 90, 90, 0.12);\n}\n\n.task-project {\n color: var(--m-accent);\n background: var(--m-accent-soft);\n}\n\n.task-source {\n align-self: flex-start;\n display: inline-flex;\n align-items: center;\n gap: 4px;\n height: 22px;\n padding: 0 6px;\n border-radius: 5px;\n color: var(--m-text-3);\n font-size: 10.5px;\n}\n\n.task-source:hover {\n background: var(--m-hover);\n color: var(--m-text-2);\n}\n\n@media (max-width: 1180px) {\n .tasks-board {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n }\n}\n\n@media (max-width: 720px) {\n .tasks-board {\n grid-template-columns: minmax(0, 1fr);\n }\n}\n\n/* ---------- AI search ---------- */\n\n.mailharbor-ai-search {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 12px 8px;\n padding: 7px 10px;\n border-radius: 8px;\n background: var(--m-accent-soft);\n color: var(--m-text-2);\n font-size: 12px;\n}\n\n.mailharbor-ai-search.searching {\n background: var(--m-bg-2);\n color: var(--m-text-3);\n}\n\n/* ---------- task editor ---------- */\n\n.mailharbor-tasks .mailharbor-modal {\n max-width: 760px;\n}\n\n.task-editor {\n display: grid;\n grid-template-columns: minmax(0, 1fr) 230px;\n gap: 18px;\n}\n\n.task-editor-main {\n display: flex;\n flex-direction: column;\n gap: 14px;\n min-width: 0;\n}\n\n.task-editor-title input {\n width: 100%;\n height: 38px;\n font-size: 15px;\n font-weight: 500;\n}\n\n.task-editor-section {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.task-editor-section label,\n.task-editor-field label {\n font-size: 11px;\n color: var(--m-text-3);\n}\n\n.task-editor-section textarea {\n width: 100%;\n resize: vertical;\n}\n\n.task-editor-side {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 12px;\n border: 1px solid var(--m-line-soft);\n border-radius: 10px;\n background: var(--m-bg-1);\n align-self: start;\n}\n\n.task-editor-field {\n display: flex;\n flex-direction: column;\n gap: 5px;\n min-width: 0;\n}\n\n.task-editor-field input,\n.task-editor-field select {\n width: 100%;\n}\n\n.task-priority-picker {\n display: grid;\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: 4px;\n padding: 3px;\n border: 1px solid var(--m-line);\n border-radius: 8px;\n background: var(--m-bg);\n}\n\n.task-priority-picker button {\n height: 26px;\n border-radius: 6px;\n font-size: 11.5px;\n color: var(--m-text-3);\n}\n\n.task-priority-picker button.active {\n background: var(--m-accent-soft);\n color: var(--m-text);\n}\n\n.task-editor-foot {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n}\n\n/* ---------- project manager ---------- */\n\n.project-manager {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.project-manager-row {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n border: 1px solid var(--m-line-soft);\n border-radius: 10px;\n background: var(--m-bg-1);\n}\n\n.project-manager-main {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 3px;\n}\n\n.project-manager-main strong {\n font-size: 13px;\n}\n\n.project-manager-main .small {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.project-manager-main input {\n width: 100%;\n height: 28px;\n}\n\n.project-manager-actions {\n display: flex;\n gap: 4px;\n flex: none;\n align-items: center;\n}\n\n/* ---------- task editor v2 ---------- */\n\n.task-editor-v2 {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.task-editor-head {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.task-editor-head .task-title-input {\n width: 100%;\n height: 42px;\n padding: 0 12px;\n border-radius: 10px;\n border: 1px solid var(--m-line);\n background: var(--m-bg);\n color: var(--m-text);\n font-size: 16px;\n font-weight: 500;\n}\n\n.task-editor-head .task-title-input:focus {\n outline: none;\n border-color: var(--m-accent);\n}\n\n.task-status-picker {\n display: grid;\n grid-template-columns: repeat(4, minmax(0, 1fr));\n gap: 4px;\n padding: 4px;\n border: 1px solid var(--m-line-soft);\n border-radius: 10px;\n background: var(--m-bg-1);\n}\n\n.task-status-picker button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n height: 30px;\n border-radius: 7px;\n color: var(--m-text-3);\n font-size: 12px;\n}\n\n.task-status-picker button:hover {\n background: var(--m-hover);\n}\n\n.task-status-picker button.active {\n background: var(--m-bg-3);\n color: var(--m-text);\n}\n\n.task-editor-columns {\n display: grid;\n grid-template-columns: minmax(0, 1fr) 250px;\n gap: 18px;\n}\n\n.task-editor-col {\n display: flex;\n flex-direction: column;\n gap: 8px;\n min-width: 0;\n}\n\n.task-editor-col textarea {\n width: 100%;\n resize: vertical;\n min-height: 120px;\n}\n\n.task-editor-col.side {\n padding: 12px;\n border: 1px solid var(--m-line-soft);\n border-radius: 10px;\n background: var(--m-bg-1);\n align-self: start;\n}\n\n.task-label {\n font-size: 11px;\n color: var(--m-text-3);\n margin-top: 2px;\n}\n\n.task-hint {\n margin: 0;\n font-size: 11.5px;\n color: var(--m-text-3);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.task-hint.danger {\n color: var(--m-danger);\n white-space: normal;\n}\n\n.task-source-row {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n}\n\n.task-due {\n position: relative;\n}\n\n.task-due-trigger {\n display: flex;\n align-items: center;\n gap: 7px;\n width: 100%;\n height: 32px;\n padding: 0 10px;\n border: 1px solid var(--m-line);\n border-radius: 8px;\n background: var(--m-bg);\n color: var(--m-text-2);\n font-size: 12.5px;\n}\n\n.task-due-trigger.empty {\n color: var(--m-text-3);\n}\n\n.task-due-trigger span {\n flex: 1;\n text-align: left;\n}\n\n.task-due-popover {\n position: absolute;\n z-index: 20;\n top: calc(100% + 6px);\n left: 0;\n width: 250px;\n padding: 10px;\n border: 1px solid var(--m-line);\n border-radius: 10px;\n background: var(--m-bg-2);\n box-shadow: 0 12px 30px rgba(0, 0, 0, 0.35);\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.task-due-quick {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 5px;\n}\n\n.task-due-quick button {\n height: 28px;\n border-radius: 7px;\n background: var(--m-bg-1);\n border: 1px solid var(--m-line-soft);\n font-size: 11.5px;\n color: var(--m-text-2);\n}\n\n.task-due-quick button.active {\n background: var(--m-accent-soft);\n border-color: transparent;\n color: var(--m-text);\n}\n\n.task-due-popover input[type='date'] {\n width: 100%;\n}\n\n.task-due-foot {\n display: flex;\n justify-content: space-between;\n}\n\n.task-priority-picker {\n display: grid;\n grid-template-columns: repeat(4, minmax(0, 1fr));\n gap: 4px;\n padding: 3px;\n border: 1px solid var(--m-line);\n border-radius: 8px;\n background: var(--m-bg);\n}\n\n.task-priority-picker button {\n height: 28px;\n border-radius: 6px;\n font-size: 11.5px;\n color: var(--m-text-3);\n border: 1px solid transparent;\n}\n\n.task-priority-picker button.p3 {\n color: #5aa7f0;\n}\n\n.task-priority-picker button.p5 {\n color: #d9a441;\n}\n\n.task-priority-picker button.p9 {\n color: var(--m-danger);\n}\n\n.task-priority-picker button.active {\n background: var(--m-bg-3);\n border-color: var(--m-line);\n color: var(--m-text);\n}\n\n.task-priority-picker button.p9.active {\n background: rgba(242, 90, 90, 0.16);\n border-color: rgba(242, 90, 90, 0.35);\n color: var(--m-danger);\n}\n\n.task-priority-picker button.p5.active {\n background: rgba(217, 164, 65, 0.16);\n border-color: rgba(217, 164, 65, 0.35);\n color: #d9a441;\n}\n\n.task-priority-picker button.p3.active {\n background: rgba(90, 167, 240, 0.16);\n border-color: rgba(90, 167, 240, 0.35);\n color: #5aa7f0;\n}\n\n.task-priority.p3 {\n background: #5aa7f0;\n}\n\n.task-priority-label.p9 {\n color: var(--m-danger);\n background: rgba(242, 90, 90, 0.12);\n}\n\n.task-priority-label.p5 {\n color: #d9a441;\n background: rgba(217, 164, 65, 0.12);\n}\n\n.task-priority-label.p3 {\n color: #5aa7f0;\n background: rgba(90, 167, 240, 0.12);\n}\n\n@media (max-width: 720px) {\n .task-editor-columns {\n grid-template-columns: minmax(0, 1fr);\n }\n}\n\n.mailharbor-spinner {\n display: inline-block;\n width: 13px;\n height: 13px;\n border: 2px solid currentColor;\n border-right-color: transparent;\n border-radius: 50%;\n animation: mailharbor-spin 0.7s linear infinite;\n opacity: 0.8;\n vertical-align: -2px;\n flex: none;\n}\n\n@keyframes mailharbor-spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n.extract-body {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.extract-title {\n width: 100%;\n height: 30px;\n font-size: 13px;\n font-weight: 500;\n}\n\n.extract-meta {\n display: grid;\n grid-template-columns: 150px 110px minmax(0, 1fr);\n gap: 6px;\n}\n\n.extract-meta input,\n.extract-meta select {\n height: 28px;\n font-size: 11.5px;\n width: 100%;\n}\n\n.extract-owner {\n width: 100%;\n}\n\n@media (max-width: 720px) {\n .extract-meta {\n grid-template-columns: minmax(0, 1fr);\n }\n}\n\n/* ---------- conversation reading ---------- */\n\n.mailharbor-thread-view {\n flex: 1;\n min-height: 0;\n overflow: auto;\n display: flex;\n flex-direction: column;\n gap: 10px;\n padding: 14px 18px 32px;\n background: var(--m-bg);\n}\n\n.mailharbor-thread-hint {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 0 4px 2px;\n font-size: 11.5px;\n color: var(--m-text-3);\n}\n\n.mailharbor-thread-msg {\n border: 1px solid var(--m-line-soft);\n border-radius: 12px;\n background: var(--m-bg-1);\n overflow: hidden;\n}\n\n.mailharbor-thread-msg.selected {\n border-color: var(--m-accent);\n box-shadow: 0 0 0 1px var(--m-accent-soft);\n}\n\n.mailharbor-thread-head {\n display: flex;\n align-items: center;\n gap: 9px;\n width: 100%;\n height: auto;\n padding: 9px 12px;\n text-align: left;\n border-radius: 0;\n}\n\n.mailharbor-thread-head:hover {\n background: var(--m-hover);\n}\n\n.thread-who {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.thread-who strong {\n font-size: 12.5px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.thread-to {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.mailharbor-thread-preview {\n padding: 0 14px 10px 47px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.mailharbor-thread-body {\n padding: 0 12px 12px;\n}\n\n.mailharbor-thread-frame {\n height: 380px;\n border: 1px solid var(--m-line-soft);\n border-radius: 8px;\n overflow: hidden;\n background: #fff;\n}\n\n.mailharbor-thread-frame iframe {\n display: block;\n width: 100%;\n height: 100%;\n border: 0;\n background: #fff;\n}\n\n.thread-loading {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 4px 12px;\n}\n\n@media (max-width: 900px) {\n .thread-to {\n display: none;\n }\n}\n\n/* ---------- compact reader ---------- */\n\n.mailharbor-reader-head {\n padding: 10px 16px 8px;\n gap: 6px;\n}\n\n.mailharbor-reader-title h2 {\n font-size: 15px;\n}\n\n.mailharbor-reader-meta.compact {\n gap: 10px;\n align-items: center;\n}\n\n.mailharbor-reader-meta.compact .who {\n gap: 6px;\n}\n\n.mailharbor-reader-recipients {\n display: flex;\n flex-wrap: wrap;\n gap: 6px 14px;\n font-size: 11.5px;\n color: var(--m-text-3);\n padding: 0 2px;\n}\n\n.mailharbor-reader-actions {\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.mailharbor-reader-actions button {\n height: 28px;\n padding: 0 8px;\n}\n\n.mailharbor-attachments.compact {\n display: flex;\n gap: 6px;\n padding: 6px 16px;\n overflow-x: auto;\n border-top: 1px solid var(--m-line-soft);\n flex-wrap: nowrap;\n}\n\n.mailharbor-attachments.compact .mailharbor-attachment {\n flex: none;\n padding: 4px 8px;\n border: 1px solid var(--m-line-soft);\n border-radius: 6px;\n max-width: 260px;\n}\n\n.mailharbor-reader-body {\n flex: 1;\n min-height: 0;\n}\n\n.thread-who {\n flex-direction: row;\n align-items: baseline;\n gap: 6px;\n min-width: 0;\n}\n\n.thread-who strong {\n max-width: 45%;\n}\n\n.thread-who .small {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n}\n\n.thread-date {\n flex: none;\n}\n\n.mailharbor button.mailharbor-thread-head {\n justify-content: flex-start;\n padding: 7px 10px;\n gap: 8px;\n}\n\n.mailharbor-thread-preview {\n padding: 0 12px 8px 40px;\n}\n\n.mailharbor-thread-frame {\n height: clamp(220px, 42vh, 420px);\n}\n\n.mailharbor-refreshing {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 0 14px 6px;\n font-size: 11px;\n color: var(--m-text-3);\n}\n\n.mailharbor-attachment-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 8px 0 2px;\n}\n\n.mailharbor-attachment-chips .mailharbor-attachment {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n max-width: 280px;\n padding: 4px 8px;\n border: 1px solid var(--m-line-soft);\n border-radius: 6px;\n background: var(--m-bg-1);\n font-size: 11.5px;\n}\n\n.mailharbor-attachment-chips .mailharbor-attachment .name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.mailharbor-thread-recipients {\n display: flex;\n flex-wrap: wrap;\n gap: 4px 14px;\n padding: 0 2px 8px;\n}\n\n.mailharbor-thread-frame {\n height: clamp(260px, 55vh, 640px);\n}\n\n.mailharbor-thread-body {\n padding: 8px 12px 12px;\n}\n\n.mailharbor-ai-summary.clamp,\n.mailharbor-ai-text.clamp {\n max-height: 150px;\n overflow: hidden;\n mask-image: linear-gradient(to bottom, #000 72%, transparent 100%);\n -webkit-mask-image: linear-gradient(to bottom, #000 72%, transparent 100%);\n}\n\n.mailharbor-ai-full {\n display: flex;\n flex-direction: column;\n gap: 14px;\n max-height: 66vh;\n overflow: auto;\n padding-right: 4px;\n font-size: 13px;\n line-height: 1.7;\n color: var(--m-text);\n}\n\n.mailharbor-ai-full h4 {\n margin: 0 0 4px;\n font-size: 11px;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n color: var(--m-text-3);\n}\n\n.mailharbor-ai-full .mailharbor-markdown {\n font-size: 13px;\n line-height: 1.7;\n}\n\n/* ---------- sync popover ---------- */\n\n.mailharbor-sync {\n position: relative;\n}\n\n.mailharbor-sync-pop {\n position: absolute;\n top: calc(100% + 8px);\n right: 0;\n z-index: 30;\n width: 320px;\n padding: 12px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n border: 1px solid var(--m-line);\n border-radius: 10px;\n background: var(--m-bg-2);\n box-shadow: 0 16px 40px rgba(0, 0, 0, 0.4);\n}\n\n.mailharbor-sync-head {\n display: flex;\n align-items: baseline;\n gap: 8px;\n}\n\n.mailharbor-sync-stats {\n display: flex;\n justify-content: space-between;\n gap: 8px;\n font-size: 11.5px;\n color: var(--m-text-3);\n}\n\n.mailharbor-sync-log {\n max-height: 110px;\n overflow: auto;\n padding: 6px 8px;\n border-radius: 6px;\n background: var(--m-bg);\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 10.5px;\n white-space: pre-wrap;\n color: var(--m-text-3);\n}\n\n.mailharbor-sync-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.mailharbor-thread-msg,\n.mailharbor-ai-card {\n flex: none;\n}\n\n.mailharbor-unread-banner {\n display: flex;\n align-items: center;\n gap: 6px;\n margin: 0 10px 8px;\n padding: 6px 10px;\n border-radius: 8px;\n background: var(--m-accent-soft);\n color: var(--m-text-2);\n font-size: 11.5px;\n text-align: left;\n}\n\n.mailharbor-unread-banner:hover {\n background: var(--m-accent-soft);\n color: var(--m-text);\n}\n";
|
|
38
|
+
var styles_default = "/* MailHarbor panel + settings.\n Tokens come from the DSH shell (dark by default); fallbacks match the\n default dark theme so the panel also renders in a bare host page.\n Component rules are all scoped under `.mailharbor` and the generic element\n reset lives in `:where()` so it cannot outrank a component class. */\n\n.mailharbor {\n --m-bg: var(--dsw-alias-bg-base, #151517);\n --m-bg-1: var(--dsw-alias-bg-layer-1, #232324);\n --m-bg-2: var(--dsw-alias-bg-layer-2, #2c2c2e);\n --m-bg-3: var(--dsw-alias-bg-layer-3, #353638);\n --m-line: var(--dsw-alias-border-l2, #ffffff1f);\n --m-line-soft: var(--dsw-alias-border-l1, #ffffff0f);\n --m-line-strong: var(--dsw-alias-border-l3, #ffffff29);\n --m-text: var(--dsw-alias-label-primary, #f9fafb);\n --m-text-2: var(--dsw-alias-label-secondary, #cfd3d6);\n --m-text-3: var(--dsw-alias-label-tertiary, #adb2b8);\n --m-caption: var(--dsw-alias-label-caption, #81858c);\n --m-accent: #5686fe;\n --m-accent-soft: rgba(86, 134, 254, 0.14);\n --m-primary-bg: var(--dsw-alias-brand-primary, #f9fafb);\n --m-primary-fg: var(--dsw-alias-label-primary-foreground, #0f1115);\n --m-hover: var(--dsw-alias-interactive-bg-hover, #ffffff14);\n --m-danger: #f25a5a;\n --m-ok: #3fbf7f;\n --m-warn: var(--dsw-alias-state-warn-label, #dd8629);\n --m-radius: 8px;\n --m-shadow: 0 18px 60px rgba(0, 0, 0, 0.5);\n\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n background: var(--m-bg);\n color: var(--m-text);\n font-size: 13px;\n line-height: 1.5;\n -webkit-font-smoothing: antialiased;\n}\n\n.mailharbor *,\n.mailharbor *::before,\n.mailharbor *::after {\n box-sizing: border-box;\n}\n\n/* ---------- base controls ---------- */\n\n.mailharbor :where(button) {\n font: inherit;\n color: inherit;\n background: transparent;\n border: 0;\n margin: 0;\n cursor: pointer;\n}\n\n.mailharbor button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n height: 30px;\n padding: 0 12px;\n border-radius: var(--m-radius);\n border: 1px solid transparent;\n color: var(--m-text-2);\n font-size: 12.5px;\n font-weight: 500;\n white-space: nowrap;\n transition:\n background 120ms ease,\n color 120ms ease,\n border-color 120ms ease;\n}\n\n.mailharbor button:hover:not(:disabled) {\n background: var(--m-hover);\n color: var(--m-text);\n}\n\n.mailharbor button:disabled {\n opacity: 0.45;\n cursor: default;\n}\n\n.mailharbor button.primary {\n background: var(--m-primary-bg);\n color: var(--m-primary-fg);\n border-color: transparent;\n}\n\n.mailharbor button.primary:hover:not(:disabled) {\n background: var(--m-primary-bg);\n filter: brightness(0.94);\n color: var(--m-primary-fg);\n}\n\n.mailharbor button.ghost {\n border-color: var(--m-line);\n color: var(--m-text-2);\n}\n\n.mailharbor button.ghost:hover:not(:disabled) {\n border-color: var(--m-line-strong);\n color: var(--m-text);\n}\n\n.mailharbor button.subtle {\n color: var(--m-text-3);\n padding: 0 8px;\n}\n\n.mailharbor button.icon {\n width: 30px;\n padding: 0;\n}\n\n.mailharbor button.danger {\n color: var(--m-danger);\n}\n\n.mailharbor input,\n.mailharbor select,\n.mailharbor textarea {\n font: inherit;\n color: var(--m-text);\n background: var(--m-bg-1);\n border: 1px solid var(--m-line);\n border-radius: var(--m-radius);\n padding: 0 10px;\n height: 32px;\n min-width: 0;\n}\n\n.mailharbor textarea {\n height: auto;\n padding: 8px 10px;\n resize: vertical;\n line-height: 1.6;\n}\n\n.mailharbor select {\n padding-right: 26px;\n appearance: none;\n background-image:\n linear-gradient(45deg, transparent 50%, var(--m-text-3) 50%),\n linear-gradient(135deg, var(--m-text-3) 50%, transparent 50%);\n background-position:\n calc(100% - 15px) 14px,\n calc(100% - 10px) 14px;\n background-size:\n 5px 5px,\n 5px 5px;\n background-repeat: no-repeat;\n}\n\n.mailharbor ::placeholder {\n color: var(--m-caption);\n}\n\n.mailharbor input:focus-visible,\n.mailharbor select:focus-visible,\n.mailharbor textarea:focus-visible,\n.mailharbor button:focus-visible,\n.mailharbor [contenteditable='true']:focus-visible {\n outline: 2px solid rgba(86, 134, 254, 0.55);\n outline-offset: -1px;\n}\n\n.mailharbor .spacer {\n flex: 1;\n}\n\n.mailharbor .muted {\n color: var(--m-text-3);\n}\n\n.mailharbor .small {\n font-size: 12px;\n}\n\n.mailharbor .badge {\n display: inline-flex;\n align-items: center;\n height: 18px;\n padding: 0 6px;\n border-radius: 999px;\n font-size: 10.5px;\n font-weight: 500;\n background: var(--m-bg-3);\n color: var(--m-text-2);\n}\n\n.mailharbor .badge.ok {\n background: rgba(63, 191, 127, 0.16);\n color: var(--m-ok);\n}\n\n.mailharbor .badge.warn {\n background: rgba(221, 134, 41, 0.16);\n color: var(--m-warn);\n}\n\n.mailharbor .error {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 14px;\n color: var(--m-danger);\n background: rgba(242, 90, 90, 0.1);\n border-bottom: 1px solid rgba(242, 90, 90, 0.2);\n font-size: 12.5px;\n}\n\n/* ---------- shell ---------- */\n\n.mailharbor-topbar {\n display: flex;\n align-items: center;\n gap: 10px;\n height: 52px;\n padding: 0 14px;\n border-bottom: 1px solid var(--m-line-soft);\n background: var(--m-bg);\n flex: none;\n}\n\n.mailharbor-account {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n max-width: 220px;\n padding: 4px 8px 4px 4px;\n border-radius: 999px;\n border: 1px solid transparent;\n cursor: default;\n}\n\n.mailharbor-account:hover {\n background: var(--m-hover);\n}\n\n.mailharbor-account .name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-weight: 500;\n}\n\n.mailharbor-account select {\n height: 26px;\n background: transparent;\n border-color: transparent;\n font-weight: 500;\n}\n\n.mailharbor-body {\n display: flex;\n flex: 1;\n min-height: 0;\n position: relative;\n}\n\n.mailharbor button.active {\n background: var(--m-accent-soft);\n color: var(--m-text);\n}\n\n.mailharbor-list {\n display: flex;\n flex-direction: column;\n width: 360px;\n flex: none;\n border-right: 1px solid var(--m-line-soft);\n min-height: 0;\n}\n\n.mailharbor-reader {\n flex: 1;\n min-width: 0;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n\n@media (max-width: 1000px) {\n .mailharbor-list {\n width: 300px;\n }\n}\n\n.mailharbor-narrow .mailharbor-body[data-mode='reader'] .mailharbor-list {\n display: none;\n}\n\n.mailharbor-narrow .mailharbor-body[data-mode='list'] .mailharbor-reader {\n display: none;\n}\n\n/* ---------- segmented control ---------- */\n\n.mailharbor-segment {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n padding: 2px;\n border-radius: 9px;\n background: var(--m-bg-2);\n}\n\n.mailharbor-segment button {\n height: 26px;\n padding: 0 12px;\n border-radius: 7px;\n color: var(--m-text-3);\n font-size: 12px;\n}\n\n.mailharbor-segment button:hover:not(.active) {\n color: var(--m-text-2);\n background: transparent;\n}\n\n.mailharbor-segment button.active {\n background: var(--m-bg-3);\n color: var(--m-text);\n}\n\n/* ---------- list ---------- */\n\n.mailharbor-filters {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px;\n border-bottom: 1px solid var(--m-line-soft);\n flex: none;\n}\n\n.mailharbor-filters select {\n width: 128px;\n flex: none;\n font-size: 12px;\n}\n\n.mailharbor-filters input[type='search'] {\n flex: 1;\n height: 30px;\n font-size: 12.5px;\n}\n\n.mailharbor-rows {\n flex: 1;\n overflow: auto;\n min-height: 0;\n}\n\n.mailharbor-row {\n display: flex;\n flex-direction: column;\n gap: 3px;\n width: 100%;\n padding: 10px 14px;\n border: 0;\n border-bottom: 1px solid var(--m-line-soft);\n border-left: 2px solid transparent;\n border-radius: 0;\n background: transparent;\n color: inherit;\n text-align: left;\n cursor: pointer;\n user-select: none;\n}\n\n.mailharbor-row:hover {\n background: var(--m-hover);\n}\n\n.mailharbor-row.selected {\n background: var(--m-accent-soft);\n border-left-color: var(--m-accent);\n}\n\n.mailharbor-row .line-1,\n.mailharbor-row .line-2 {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n width: 100%;\n}\n\n.mailharbor-row .from {\n font-weight: 600;\n font-size: 12.5px;\n color: var(--m-text-2);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.mailharbor-row .date {\n margin-left: auto;\n color: var(--m-caption);\n font-size: 11px;\n flex: none;\n}\n\n.mailharbor-row .subject {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--m-text-2);\n font-size: 12.5px;\n}\n\n.mailharbor-row .snippet {\n color: var(--m-caption);\n font-size: 11.5px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n width: 100%;\n}\n\n.mailharbor-row.unread .from,\n.mailharbor-row.unread .subject {\n color: var(--m-text);\n}\n\n.mailharbor-row .dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--m-accent);\n flex: none;\n}\n\n.mailharbor-row .paperclip {\n color: var(--m-caption);\n flex: none;\n display: inline-flex;\n}\n\n.mailharbor-list-foot {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-top: 1px solid var(--m-line-soft);\n color: var(--m-text-3);\n font-size: 11.5px;\n flex: none;\n}\n\n.mailharbor-empty {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 10px;\n padding: 48px 24px;\n color: var(--m-text-3);\n text-align: center;\n}\n\n.mailharbor-empty svg {\n opacity: 0.5;\n}\n\n.mailharbor-empty .title {\n color: var(--m-text-2);\n font-size: 13px;\n font-weight: 500;\n}\n\n/* ---------- reader ---------- */\n\n.mailharbor-reader-head {\n padding: 16px 20px 12px;\n border-bottom: 1px solid var(--m-line-soft);\n flex: none;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.mailharbor-reader-title {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n}\n\n.mailharbor-reader-title h2 {\n margin: 0;\n font-size: 17px;\n line-height: 1.35;\n font-weight: 600;\n letter-spacing: -0.01em;\n word-break: break-word;\n}\n\n.mailharbor-reader-meta {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 4px 10px;\n color: var(--m-text-3);\n font-size: 12px;\n}\n\n.mailharbor-reader-meta .who {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n color: var(--m-text-2);\n}\n\n.mailharbor-reader-meta .who strong {\n color: var(--m-text);\n font-weight: 600;\n}\n\n.mailharbor-reader-actions {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.mailharbor-reader-body {\n flex: 1;\n min-height: 0;\n display: flex;\n flex-direction: column;\n padding: 14px 18px 18px;\n background: var(--m-bg-2);\n}\n\n.mailharbor-reader-body iframe {\n flex: 1;\n width: 100%;\n border: 0;\n border-radius: 10px;\n background: #fff;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);\n}\n\n.mailharbor-reader-body pre {\n flex: 1;\n overflow: auto;\n margin: 0;\n padding: 20px 22px;\n white-space: pre-wrap;\n word-break: break-word;\n background: #fff;\n border-radius: 10px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);\n color: #171a21;\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 12.5px;\n line-height: 1.7;\n}\n\n.mailharbor-attachments {\n padding: 10px 18px;\n border-top: 1px solid var(--m-line-soft);\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n flex: none;\n background: var(--m-bg);\n}\n\n.mailharbor-attachment {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n height: 30px;\n padding: 0 10px;\n border: 1px solid var(--m-line);\n border-radius: var(--m-radius);\n font-size: 12px;\n text-decoration: none;\n color: var(--m-text-2);\n max-width: 260px;\n background: var(--m-bg-1);\n}\n\n.mailharbor-attachment:hover {\n border-color: var(--m-line-strong);\n color: var(--m-text);\n}\n\n.mailharbor-attachment .name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* ---------- AI rail ---------- */\n\n.mailharbor-ai {\n display: flex;\n flex-direction: column;\n width: 340px;\n flex: none;\n min-height: 0;\n border-left: 1px solid var(--m-line-soft);\n background: var(--m-bg);\n}\n\n.mailharbor-ai-head {\n display: flex;\n align-items: center;\n gap: 8px;\n height: 46px;\n padding: 0 8px 0 14px;\n border-bottom: 1px solid var(--m-line-soft);\n flex: none;\n}\n\n.mailharbor-ai-head strong {\n font-size: 13px;\n font-weight: 600;\n}\n\n.mailharbor-ai-confirm {\n display: inline-flex;\n gap: 2px;\n}\n\n.mailharbor-ai-context {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 9px 14px 10px;\n border-bottom: 1px solid var(--m-line-soft);\n flex: none;\n}\n\n.mailharbor-ai-context strong {\n font-size: 12.5px;\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.mailharbor-ai-warn {\n padding: 8px 14px;\n color: var(--m-warn);\n background: rgba(221, 134, 41, 0.1);\n font-size: 12px;\n flex: none;\n}\n\n.mailharbor-ai-quick {\n display: flex;\n gap: 6px;\n padding: 10px 14px;\n border-bottom: 1px solid var(--m-line-soft);\n flex: none;\n}\n\n.mailharbor-ai-quick button {\n flex: 1;\n padding: 0 6px;\n}\n\n.mailharbor-ai-list {\n flex: 1;\n min-height: 0;\n overflow: auto;\n display: flex;\n flex-direction: column;\n gap: 10px;\n padding: 12px 14px;\n}\n\n.mailharbor-ai-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n padding: 30px 12px;\n text-align: center;\n color: var(--m-text-3);\n}\n\n.mailharbor-ai-empty .title {\n color: var(--m-text-2);\n font-weight: 500;\n font-size: 12.5px;\n}\n\n.mailharbor-ai-card {\n display: flex;\n flex-direction: column;\n border: 1px solid var(--m-line-soft);\n border-radius: 10px;\n background: var(--m-bg-1);\n overflow: hidden;\n}\n\n.mailharbor-ai-card.generating {\n opacity: 0.7;\n}\n\n.mailharbor-ai-card-head {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 7px 8px 7px 12px;\n border-bottom: 1px solid var(--m-line-soft);\n font-size: 11.5px;\n color: var(--m-text-3);\n}\n\n.mailharbor-ai-card-head > span:first-child {\n color: var(--m-text-2);\n font-weight: 600;\n}\n\n.mailharbor-ai-summary {\n display: flex;\n flex-direction: column;\n gap: 10px;\n padding: 10px 12px;\n}\n\n.mailharbor-ai-summary section h4 {\n margin: 0 0 3px;\n font-size: 11px;\n color: var(--m-text-3);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.mailharbor-ai-summary section p {\n margin: 0;\n white-space: pre-wrap;\n font-size: 12.5px;\n line-height: 1.65;\n color: var(--m-text);\n}\n\n.mailharbor-ai-text {\n padding: 10px 12px;\n\n white-space: pre-wrap;\n font-size: 12.5px;\n line-height: 1.65;\n color: var(--m-text);\n}\n\n.mailharbor-ai-card-actions {\n display: flex;\n align-items: center;\n gap: 4px;\n flex-wrap: wrap;\n padding: 6px 8px;\n border-top: 1px solid var(--m-line-soft);\n}\n\n.mailharbor-ai-card-actions button {\n height: 26px;\n padding: 0 8px;\n font-size: 11.5px;\n}\n\n.mailharbor-ai-ask {\n display: flex;\n gap: 6px;\n padding: 10px 12px;\n border-top: 1px solid var(--m-line-soft);\n flex: none;\n}\n\n.mailharbor-ai-ask input {\n flex: 1;\n height: 32px;\n}\n\n.mailharbor-ai-error {\n color: var(--m-danger);\n font-size: 12px;\n padding: 0 2px;\n}\n\n@media (max-width: 1280px) {\n .mailharbor-ai {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: min(420px, 94%);\n z-index: 6;\n border-left: 1px solid var(--m-line);\n box-shadow: -12px 0 40px rgba(0, 0, 0, 0.45);\n }\n}\n\n/* ---------- AI summary ---------- */\n\n.mailharbor-divider {\n width: 1px;\n height: 18px;\n margin: 0 4px;\n background: var(--m-line);\n}\n\n.mailharbor-summary {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.mailharbor-summary section h4 {\n margin: 0 0 6px;\n font-size: 11.5px;\n font-weight: 600;\n color: var(--m-text-3);\n text-transform: uppercase;\n letter-spacing: 0.06em;\n}\n\n.mailharbor-summary section p {\n margin: 0;\n white-space: pre-wrap;\n line-height: 1.75;\n color: var(--m-text);\n}\n\n/* ---------- modal / forms ---------- */\n\n.mailharbor-portal {\n position: fixed;\n inset: 0;\n z-index: 80;\n height: auto;\n background: transparent;\n pointer-events: none;\n}\n\n.mailharbor-portal .mailharbor-modal-mask {\n pointer-events: auto;\n}\n\n.mailharbor-modal-mask {\n position: fixed;\n inset: 0;\n z-index: 60;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 24px;\n background: rgba(0, 0, 0, 0.55);\n backdrop-filter: blur(2px);\n}\n\n.mailharbor-modal {\n display: flex;\n flex-direction: column;\n width: min(720px, 100%);\n max-height: 86vh;\n overflow: hidden;\n border: 1px solid var(--m-line);\n border-radius: 14px;\n background: var(--m-bg-1);\n color: var(--m-text);\n box-shadow: var(--m-shadow);\n}\n\n.mailharbor-modal > header {\n display: flex;\n align-items: center;\n gap: 8px;\n height: 52px;\n padding: 0 14px 0 18px;\n border-bottom: 1px solid var(--m-line-soft);\n font-size: 14px;\n font-weight: 600;\n}\n\n.mailharbor-modal .content {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 18px;\n overflow: auto;\n}\n\n.mailharbor-modal > footer {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 18px;\n border-top: 1px solid var(--m-line-soft);\n}\n\n.mailharbor-field {\n display: flex;\n flex-direction: column;\n gap: 5px;\n min-width: 0;\n}\n\n.mailharbor-field > input,\n.mailharbor-field > select,\n.mailharbor-field > textarea,\n.mailharbor-card > textarea {\n width: 100%;\n min-width: 0;\n}\n\n.mailharbor-field > label {\n font-size: 11.5px;\n color: var(--m-text-3);\n}\n\n.mailharbor-grid {\n display: grid;\n grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);\n gap: 10px;\n min-width: 0;\n}\n\n.mailharbor-grid.three {\n grid-template-columns: minmax(0, 2fr) minmax(72px, 90px) auto;\n align-items: end;\n min-width: 0;\n}\n\n.mailharbor-toggle {\n display: inline-flex;\n align-items: center;\n gap: 7px;\n color: var(--m-text-2);\n font-size: 12.5px;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.mailharbor-toggle input[type='checkbox'] {\n width: 14px;\n height: 14px;\n accent-color: var(--m-accent);\n}\n\n/* ---------- composer ---------- */\n\n.mailharbor-toolbar {\n display: flex;\n align-items: center;\n gap: 2px;\n flex-wrap: wrap;\n padding: 6px;\n border: 1px solid var(--m-line-soft);\n border-bottom: 0;\n border-radius: 10px 10px 0 0;\n background: var(--m-bg-2);\n}\n\n.mailharbor-toolbar button {\n height: 26px;\n padding: 0 9px;\n border-radius: 6px;\n color: var(--m-text-2);\n font-size: 12px;\n}\n\n.mailharbor-toolbar button:hover {\n background: var(--m-bg-3);\n color: var(--m-text);\n}\n\n.mailharbor-editor {\n min-height: 240px;\n max-height: 44vh;\n overflow: auto;\n padding: 14px 16px;\n border: 1px solid var(--m-line-soft);\n border-radius: 0 0 10px 10px;\n background: #fff;\n color: #171a21;\n outline: none;\n font-size: 13.5px;\n line-height: 1.7;\n}\n\n.mailharbor-editor:empty::before {\n content: attr(data-placeholder);\n color: #9aa0ab;\n}\n\n/* ---------- inline confirm ---------- */\n\n.mailharbor-confirm {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-radius: 8px;\n border: 1px solid var(--m-line);\n background: var(--m-bg-2);\n color: var(--m-text-2);\n font-size: 12.5px;\n}\n\n/* ---------- selection / extraction ---------- */\n\n.mailharbor-selectbar {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n margin: 0 12px 8px;\n border: 1px solid var(--m-accent-soft);\n border-radius: 9px;\n background: var(--m-accent-soft);\n}\n\n.mailharbor-selectbar select {\n height: 28px;\n max-width: 200px;\n}\n\n.mailharbor-row.selectable input[type='checkbox'] {\n width: 15px;\n height: 15px;\n flex: none;\n accent-color: var(--m-accent);\n}\n\n.mailharbor-extract-row {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 9px 10px;\n border: 1px solid var(--m-line-soft);\n border-radius: 9px;\n background: var(--m-bg-1);\n cursor: pointer;\n}\n\n.mailharbor-extract-row input {\n margin-top: 2px;\n accent-color: var(--m-accent);\n}\n\n.mailharbor-extract-row > span {\n display: flex;\n flex-direction: column;\n gap: 3px;\n min-width: 0;\n}\n\n.mailharbor-kv {\n display: grid;\n grid-template-columns: auto minmax(0, 1fr);\n gap: 6px 12px;\n margin: 0;\n font-size: 12.5px;\n}\n\n.mailharbor-kv dt {\n color: var(--m-text-3);\n}\n\n.mailharbor-kv dd {\n margin: 0;\n overflow-wrap: anywhere;\n}\n\n/* ---------- tasks panel ---------- */\n\n.mailharbor .chip {\n height: 26px;\n padding: 0 10px;\n border: 1px solid var(--m-line);\n border-radius: 999px;\n color: var(--m-text-3);\n font-size: 12px;\n}\n\n.mailharbor .chip.active {\n background: var(--m-accent-soft);\n border-color: transparent;\n color: var(--m-text);\n}\n\n.tasks-body {\n flex: 1;\n min-height: 0;\n overflow: auto;\n display: flex;\n flex-direction: column;\n gap: 18px;\n padding: 18px 20px 48px;\n width: 100%;\n max-width: 940px;\n margin: 0 auto;\n}\n\n.tasks-overview {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));\n gap: 12px;\n}\n\n.tasks-progress,\n.tasks-project {\n display: flex;\n flex-direction: column;\n gap: 7px;\n padding: 12px 14px;\n border: 1px solid var(--m-line-soft);\n border-radius: 12px;\n background: var(--m-bg-1);\n min-width: 0;\n}\n\n.tasks-progress-head,\n.tasks-project-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n min-width: 0;\n}\n\n.tasks-project-head .name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 12.5px;\n font-weight: 500;\n}\n\n.tasks-bar {\n height: 6px;\n border-radius: 999px;\n background: var(--m-bg-3);\n overflow: hidden;\n}\n\n.tasks-bar span {\n display: block;\n height: 100%;\n border-radius: 999px;\n background: var(--m-accent);\n transition: width 200ms ease;\n}\n\n.tasks-bar.small {\n height: 4px;\n}\n\n.tasks-filters {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n.tasks-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.tasks-row {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 9px 12px;\n border: 1px solid var(--m-line-soft);\n border-radius: 10px;\n background: var(--m-bg-1);\n}\n\n.tasks-row input[type='checkbox'] {\n width: 16px;\n height: 16px;\n flex: none;\n accent-color: var(--m-accent);\n}\n\n.tasks-row .tasks-title {\n flex: 1;\n min-width: 0;\n height: auto;\n padding: 0;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 4px;\n text-align: left;\n border: 0;\n background: transparent;\n}\n\n.tasks-row .tasks-title:hover {\n background: transparent;\n}\n\n.tasks-row .tasks-title > span:first-child {\n font-size: 13px;\n color: var(--m-text);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n max-width: 100%;\n}\n\n.tasks-row.done .tasks-title > span:first-child {\n color: var(--m-text-3);\n text-decoration: line-through;\n}\n\n.tasks-meta {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 6px;\n font-size: 11px;\n color: var(--m-text-3);\n}\n\n.tasks-meta .due.overdue {\n color: var(--m-danger);\n}\n\n.tasks-list-wrap {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n/* ---------- markdown ---------- */\n\n.mailharbor-markdown {\n display: flex;\n flex-direction: column;\n gap: 8px;\n font-size: 12.5px;\n line-height: 1.68;\n overflow-wrap: anywhere;\n}\n\n.mailharbor-markdown > *:first-child {\n margin-top: 0;\n}\n\n.mailharbor-markdown > *:last-child {\n margin-bottom: 0;\n}\n\n.mailharbor-markdown p {\n margin: 0;\n white-space: pre-wrap;\n}\n\n.mailharbor-markdown h1,\n.mailharbor-markdown h2,\n.mailharbor-markdown h3,\n.mailharbor-markdown h4,\n.mailharbor-markdown h5,\n.mailharbor-markdown h6 {\n margin: 4px 0 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--m-text);\n}\n\n.mailharbor-markdown ul,\n.mailharbor-markdown ol {\n margin: 0;\n padding-left: 20px;\n display: flex;\n flex-direction: column;\n gap: 3px;\n}\n\n.mailharbor-markdown li::marker {\n color: var(--m-text-3);\n}\n\n.mailharbor-markdown a {\n color: var(--m-accent);\n text-decoration: none;\n}\n\n.mailharbor-markdown a:hover {\n text-decoration: underline;\n}\n\n.mailharbor-markdown code {\n padding: 1px 4px;\n border-radius: 4px;\n background: var(--m-bg-2);\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 11.5px;\n}\n\n.mailharbor-markdown pre {\n margin: 0;\n padding: 10px 12px;\n border-radius: 8px;\n background: var(--m-bg);\n border: 1px solid var(--m-line-soft);\n overflow: auto;\n}\n\n.mailharbor-markdown pre code {\n padding: 0;\n background: transparent;\n}\n\n.mailharbor-markdown blockquote {\n margin: 0;\n padding-left: 10px;\n border-left: 2px solid var(--m-line);\n color: var(--m-text-2);\n}\n\n.mailharbor-markdown hr {\n width: 100%;\n margin: 4px 0;\n border: 0;\n border-top: 1px solid var(--m-line-soft);\n}\n\n/* ---------- composer AI ---------- */\n\n.mailharbor-toolbar button.ai {\n color: var(--m-accent);\n}\n\n.mailharbor-compose-foot {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n flex-wrap: wrap;\n}\n\n.mailharbor-versions {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-wrap: wrap;\n padding-top: 8px;\n}\n\n.mailharbor-versions .chip {\n height: 22px;\n padding: 0 8px;\n border: 1px solid var(--m-line);\n border-radius: 999px;\n color: var(--m-text-3);\n font-size: 11px;\n}\n\n.mailharbor-versions .chip.active {\n background: var(--m-accent-soft);\n border-color: transparent;\n color: var(--m-text);\n}\n\n/* ---------- settings ---------- */\n\n.mailharbor.mailharbor-settings-page {\n height: auto;\n min-height: 100%;\n overflow: visible;\n}\n\n.mailharbor-settings {\n flex: 0 0 auto;\n width: 100%;\n max-width: 100%;\n min-width: 0;\n padding: 18px 20px 48px;\n display: flex;\n flex-direction: column;\n gap: 16px;\n overflow-x: hidden;\n}\n\n.mailharbor-settings > * {\n min-width: 0;\n}\n\n.mailharbor-settings h2 {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n letter-spacing: -0.01em;\n}\n\n.mailharbor-settings h3 {\n margin: 0;\n font-size: 12px;\n font-weight: 600;\n color: var(--m-text-3);\n text-transform: uppercase;\n letter-spacing: 0.06em;\n}\n\n.mailharbor-card {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 16px;\n border: 1px solid var(--m-line-soft);\n border-radius: 12px;\n background: var(--m-bg-1);\n min-width: 0;\n overflow: hidden;\n}\n\n.mailharbor-account-row {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.mailharbor-account-row .meta {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.mailharbor-account-row .meta strong {\n font-weight: 600;\n}\n\n.mailharbor-account-row .meta span {\n color: var(--m-text-3);\n font-size: 11.5px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.mailharbor .avatar {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n border-radius: 50%;\n background: var(--m-accent-soft);\n color: var(--m-accent);\n font-weight: 600;\n}\n\n.mailharbor-log {\n padding: 10px 12px;\n border-radius: 8px;\n background: var(--m-bg);\n border: 1px solid var(--m-line-soft);\n color: var(--m-text-2);\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 11px;\n line-height: 1.6;\n max-height: 220px;\n overflow: auto;\n white-space: pre-wrap;\n}\n\n.mailharbor-kv {\n display: grid;\n grid-template-columns: minmax(120px, 170px) 1fr;\n gap: 6px 14px;\n font-size: 12px;\n margin: 0;\n}\n\n.mailharbor-kv dt {\n color: var(--m-text-3);\n}\n\n.mailharbor-kv dd {\n margin: 0;\n color: var(--m-text-2);\n word-break: break-all;\n}\n\n.mailharbor hr {\n border: 0;\n border-top: 1px solid var(--m-line-soft);\n margin: 2px 0;\n}\n\n/* ---------- conversation rows ---------- */\n\n.mailharbor-thread {\n display: flex;\n flex-direction: column;\n}\n\n.mailharbor-row.compact {\n padding-top: 6px;\n padding-bottom: 6px;\n padding-left: 34px;\n background: var(--m-bg);\n}\n\n.mailharbor-row.compact .line-1 {\n opacity: 0.85;\n}\n\n.mailharbor-row.compact .snippet {\n -webkit-line-clamp: 1;\n}\n\n.mailharbor .to-label {\n font-size: 10.5px;\n color: var(--m-text-3);\n flex: none;\n}\n\n.mailharbor .thread-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n border-radius: 999px;\n background: var(--m-bg-3);\n color: var(--m-text-2);\n font-size: 10.5px;\n flex: none;\n}\n\n.mailharbor .thread-count:hover {\n background: var(--m-accent-soft);\n color: var(--m-text);\n}\n\n.mailharbor-account {\n height: auto;\n padding: 3px 8px 3px 3px;\n border-radius: 8px;\n gap: 8px;\n}\n\n.mailharbor-account:hover {\n background: var(--m-hover);\n}\n\n/* ---------- mailbox sidebar ---------- */\n\n.mailharbor-side {\n display: flex;\n flex-direction: column;\n gap: 2px;\n width: 214px;\n flex: none;\n padding: 10px 8px;\n overflow: auto;\n border-right: 1px solid var(--m-line-soft);\n background: var(--m-bg);\n}\n\n.mailharbor-side-section {\n padding: 12px 8px 4px;\n font-size: 10.5px;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n color: var(--m-text-3);\n}\n\n.mailharbor-side-item {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n height: 32px;\n padding: 0 8px;\n border-radius: 8px;\n color: var(--m-text-2);\n font-size: 12.5px;\n text-align: left;\n flex: none;\n}\n\n.mailharbor-side-item:hover {\n background: var(--m-hover);\n}\n\n.mailharbor-side-item.active {\n background: var(--m-accent-soft);\n color: var(--m-text);\n}\n\n.mailharbor-side-item .name {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.mailharbor-side-item .sub {\n display: block;\n font-size: 10.5px;\n color: var(--m-text-3);\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.mailharbor-side-item .count {\n font-size: 11px;\n color: var(--m-text-3);\n}\n\n.mailharbor-side-item svg {\n flex: none;\n color: var(--m-text-3);\n}\n\n.mailharbor-side-item.active svg {\n color: var(--m-accent);\n}\n\n@media (max-width: 900px) {\n .mailharbor-side {\n display: none;\n }\n}\n\n/* ---------- task board ---------- */\n\n.tasks-board-wrap {\n flex: 1;\n min-height: 0;\n overflow: auto;\n display: flex;\n flex-direction: column;\n gap: 14px;\n padding: 16px 18px 40px;\n}\n\n.tasks-summary {\n display: flex;\n align-items: center;\n gap: 20px;\n padding: 14px 16px;\n border: 1px solid var(--m-line-soft);\n border-radius: 12px;\n background: var(--m-bg-1);\n}\n\n.tasks-summary-main {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 7px;\n}\n\n.tasks-summary-labels {\n display: flex;\n align-items: baseline;\n gap: 10px;\n}\n\n.tasks-stats {\n display: flex;\n gap: 18px;\n}\n\n.tasks-stat {\n display: flex;\n flex-direction: column;\n gap: 1px;\n min-width: 42px;\n}\n\n.tasks-stat strong {\n font-size: 16px;\n font-weight: 600;\n color: var(--m-text);\n}\n\n.tasks-stat span {\n font-size: 11px;\n color: var(--m-text-3);\n}\n\n.tasks-stat.danger strong {\n color: var(--m-danger);\n}\n\n.tasks-toolbar {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.tasks-board {\n display: grid;\n grid-template-columns: repeat(4, minmax(0, 1fr));\n gap: 14px;\n align-items: start;\n}\n\n.task-column {\n display: flex;\n flex-direction: column;\n gap: 8px;\n min-height: 140px;\n padding: 8px;\n border: 1px solid var(--m-line-soft);\n border-radius: 12px;\n background: var(--m-bg-1);\n}\n\n.task-column-head {\n display: flex;\n align-items: center;\n gap: 7px;\n padding: 2px 4px 6px;\n}\n\n.task-column-head strong {\n font-size: 12.5px;\n font-weight: 600;\n}\n\n.task-column-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n border-radius: 999px;\n background: var(--m-bg-3);\n color: var(--m-text-3);\n font-size: 10.5px;\n}\n\n.task-dot {\n width: 7px;\n height: 7px;\n border-radius: 999px;\n background: var(--m-text-3);\n}\n\n.task-dot.NEEDS-ACTION {\n background: #8a8f98;\n}\n\n.task-dot.IN-PROCESS {\n background: var(--m-accent);\n}\n\n.task-dot.COMPLETED {\n background: var(--m-ok);\n}\n\n.task-dot.CANCELLED {\n background: var(--m-danger);\n opacity: 0.7;\n}\n\n.task-column-body {\n display: flex;\n flex-direction: column;\n gap: 8px;\n min-height: 60px;\n}\n\n.task-column-empty {\n padding: 18px 8px;\n text-align: center;\n color: var(--m-text-3);\n font-size: 11.5px;\n border: 1px dashed var(--m-line-soft);\n border-radius: 9px;\n}\n\n.task-card {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 10px 11px;\n border: 1px solid var(--m-line-soft);\n border-radius: 10px;\n background: var(--m-bg);\n cursor: grab;\n transition:\n border-color 120ms ease,\n box-shadow 120ms ease;\n}\n\n.task-card:hover {\n border-color: var(--m-line);\n box-shadow: 0 4px 14px rgba(0, 0, 0, 0.16);\n}\n\n.task-card.dragging {\n opacity: 0.5;\n}\n\n.task-card-top {\n display: flex;\n align-items: flex-start;\n gap: 7px;\n}\n\n.task-card-title {\n flex: 1;\n min-width: 0;\n font-size: 12.5px;\n line-height: 1.45;\n color: var(--m-text);\n overflow-wrap: anywhere;\n}\n\n.task-priority {\n width: 3px;\n height: 14px;\n margin-top: 2px;\n border-radius: 999px;\n background: transparent;\n flex: none;\n}\n\n.task-priority.p5 {\n background: #d9a441;\n}\n\n.task-priority.p9 {\n background: var(--m-danger);\n}\n\n.task-card-delete {\n width: 18px;\n height: 18px;\n flex: none;\n border-radius: 5px;\n color: var(--m-text-3);\n opacity: 0;\n}\n\n.task-card:hover .task-card-delete {\n opacity: 1;\n}\n\n.task-card-notes {\n margin: 0;\n font-size: 11.5px;\n line-height: 1.55;\n color: var(--m-text-3);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.task-card-meta {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 6px;\n font-size: 10.5px;\n color: var(--m-text-3);\n}\n\n.task-due,\n.task-owner,\n.task-project,\n.task-priority-label {\n display: inline-flex;\n align-items: center;\n gap: 3px;\n padding: 1px 6px;\n border-radius: 5px;\n background: var(--m-bg-2);\n}\n\n.task-due.overdue {\n color: var(--m-danger);\n background: rgba(242, 90, 90, 0.12);\n}\n\n.task-project {\n color: var(--m-accent);\n background: var(--m-accent-soft);\n}\n\n.task-source {\n align-self: flex-start;\n display: inline-flex;\n align-items: center;\n gap: 4px;\n height: 22px;\n padding: 0 6px;\n border-radius: 5px;\n color: var(--m-text-3);\n font-size: 10.5px;\n}\n\n.task-source:hover {\n background: var(--m-hover);\n color: var(--m-text-2);\n}\n\n@media (max-width: 1180px) {\n .tasks-board {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n }\n}\n\n@media (max-width: 720px) {\n .tasks-board {\n grid-template-columns: minmax(0, 1fr);\n }\n}\n\n/* ---------- AI search ---------- */\n\n.mailharbor-ai-search {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 12px 8px;\n padding: 7px 10px;\n border-radius: 8px;\n background: var(--m-accent-soft);\n color: var(--m-text-2);\n font-size: 12px;\n}\n\n.mailharbor-ai-search.searching {\n background: var(--m-bg-2);\n color: var(--m-text-3);\n}\n\n/* ---------- task editor ---------- */\n\n.mailharbor-tasks .mailharbor-modal {\n max-width: 760px;\n}\n\n.task-editor {\n display: grid;\n grid-template-columns: minmax(0, 1fr) 230px;\n gap: 18px;\n}\n\n.task-editor-main {\n display: flex;\n flex-direction: column;\n gap: 14px;\n min-width: 0;\n}\n\n.task-editor-title input {\n width: 100%;\n height: 38px;\n font-size: 15px;\n font-weight: 500;\n}\n\n.task-editor-section {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.task-editor-section label,\n.task-editor-field label {\n font-size: 11px;\n color: var(--m-text-3);\n}\n\n.task-editor-section textarea {\n width: 100%;\n resize: vertical;\n}\n\n.task-editor-side {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 12px;\n border: 1px solid var(--m-line-soft);\n border-radius: 10px;\n background: var(--m-bg-1);\n align-self: start;\n}\n\n.task-editor-field {\n display: flex;\n flex-direction: column;\n gap: 5px;\n min-width: 0;\n}\n\n.task-editor-field input,\n.task-editor-field select {\n width: 100%;\n}\n\n.task-priority-picker {\n display: grid;\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: 4px;\n padding: 3px;\n border: 1px solid var(--m-line);\n border-radius: 8px;\n background: var(--m-bg);\n}\n\n.task-priority-picker button {\n height: 26px;\n border-radius: 6px;\n font-size: 11.5px;\n color: var(--m-text-3);\n}\n\n.task-priority-picker button.active {\n background: var(--m-accent-soft);\n color: var(--m-text);\n}\n\n.task-editor-foot {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n}\n\n/* ---------- project manager ---------- */\n\n.project-manager {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.project-manager-row {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n border: 1px solid var(--m-line-soft);\n border-radius: 10px;\n background: var(--m-bg-1);\n}\n\n.project-manager-main {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 3px;\n}\n\n.project-manager-main strong {\n font-size: 13px;\n}\n\n.project-manager-main .small {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.project-manager-main input {\n width: 100%;\n height: 28px;\n}\n\n.project-manager-actions {\n display: flex;\n gap: 4px;\n flex: none;\n align-items: center;\n}\n\n/* ---------- task editor v2 ---------- */\n\n.task-editor-v2 {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.task-editor-head {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.task-editor-head .task-title-input {\n width: 100%;\n height: 42px;\n padding: 0 12px;\n border-radius: 10px;\n border: 1px solid var(--m-line);\n background: var(--m-bg);\n color: var(--m-text);\n font-size: 16px;\n font-weight: 500;\n}\n\n.task-editor-head .task-title-input:focus {\n outline: none;\n border-color: var(--m-accent);\n}\n\n.task-status-picker {\n display: grid;\n grid-template-columns: repeat(4, minmax(0, 1fr));\n gap: 4px;\n padding: 4px;\n border: 1px solid var(--m-line-soft);\n border-radius: 10px;\n background: var(--m-bg-1);\n}\n\n.task-status-picker button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n height: 30px;\n border-radius: 7px;\n color: var(--m-text-3);\n font-size: 12px;\n}\n\n.task-status-picker button:hover {\n background: var(--m-hover);\n}\n\n.task-status-picker button.active {\n background: var(--m-bg-3);\n color: var(--m-text);\n}\n\n.task-editor-columns {\n display: grid;\n grid-template-columns: minmax(0, 1fr) 250px;\n gap: 18px;\n}\n\n.task-editor-col {\n display: flex;\n flex-direction: column;\n gap: 8px;\n min-width: 0;\n}\n\n.task-editor-col textarea {\n width: 100%;\n resize: vertical;\n min-height: 120px;\n}\n\n.task-editor-col.side {\n padding: 12px;\n border: 1px solid var(--m-line-soft);\n border-radius: 10px;\n background: var(--m-bg-1);\n align-self: start;\n}\n\n.task-label {\n font-size: 11px;\n color: var(--m-text-3);\n margin-top: 2px;\n}\n\n.task-hint {\n margin: 0;\n font-size: 11.5px;\n color: var(--m-text-3);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.task-hint.danger {\n color: var(--m-danger);\n white-space: normal;\n}\n\n.task-source-row {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n}\n\n.task-due {\n position: relative;\n}\n\n.task-due-trigger {\n display: flex;\n align-items: center;\n gap: 7px;\n width: 100%;\n height: 32px;\n padding: 0 10px;\n border: 1px solid var(--m-line);\n border-radius: 8px;\n background: var(--m-bg);\n color: var(--m-text-2);\n font-size: 12.5px;\n}\n\n.task-due-trigger.empty {\n color: var(--m-text-3);\n}\n\n.task-due-trigger span {\n flex: 1;\n text-align: left;\n}\n\n.task-due-popover {\n position: absolute;\n z-index: 20;\n top: calc(100% + 6px);\n left: 0;\n width: 250px;\n padding: 10px;\n border: 1px solid var(--m-line);\n border-radius: 10px;\n background: var(--m-bg-2);\n box-shadow: 0 12px 30px rgba(0, 0, 0, 0.35);\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.task-due-quick {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 5px;\n}\n\n.task-due-quick button {\n height: 28px;\n border-radius: 7px;\n background: var(--m-bg-1);\n border: 1px solid var(--m-line-soft);\n font-size: 11.5px;\n color: var(--m-text-2);\n}\n\n.task-due-quick button.active {\n background: var(--m-accent-soft);\n border-color: transparent;\n color: var(--m-text);\n}\n\n.task-due-popover input[type='date'] {\n width: 100%;\n}\n\n.task-due-foot {\n display: flex;\n justify-content: space-between;\n}\n\n.task-priority-picker {\n display: grid;\n grid-template-columns: repeat(4, minmax(0, 1fr));\n gap: 4px;\n padding: 3px;\n border: 1px solid var(--m-line);\n border-radius: 8px;\n background: var(--m-bg);\n}\n\n.task-priority-picker button {\n height: 28px;\n border-radius: 6px;\n font-size: 11.5px;\n color: var(--m-text-3);\n border: 1px solid transparent;\n}\n\n.task-priority-picker button.p3 {\n color: #5aa7f0;\n}\n\n.task-priority-picker button.p5 {\n color: #d9a441;\n}\n\n.task-priority-picker button.p9 {\n color: var(--m-danger);\n}\n\n.task-priority-picker button.active {\n background: var(--m-bg-3);\n border-color: var(--m-line);\n color: var(--m-text);\n}\n\n.task-priority-picker button.p9.active {\n background: rgba(242, 90, 90, 0.16);\n border-color: rgba(242, 90, 90, 0.35);\n color: var(--m-danger);\n}\n\n.task-priority-picker button.p5.active {\n background: rgba(217, 164, 65, 0.16);\n border-color: rgba(217, 164, 65, 0.35);\n color: #d9a441;\n}\n\n.task-priority-picker button.p3.active {\n background: rgba(90, 167, 240, 0.16);\n border-color: rgba(90, 167, 240, 0.35);\n color: #5aa7f0;\n}\n\n.task-priority.p3 {\n background: #5aa7f0;\n}\n\n.task-priority-label.p9 {\n color: var(--m-danger);\n background: rgba(242, 90, 90, 0.12);\n}\n\n.task-priority-label.p5 {\n color: #d9a441;\n background: rgba(217, 164, 65, 0.12);\n}\n\n.task-priority-label.p3 {\n color: #5aa7f0;\n background: rgba(90, 167, 240, 0.12);\n}\n\n@media (max-width: 720px) {\n .task-editor-columns {\n grid-template-columns: minmax(0, 1fr);\n }\n}\n\n.mailharbor-spinner {\n display: inline-block;\n width: 13px;\n height: 13px;\n border: 2px solid currentColor;\n border-right-color: transparent;\n border-radius: 50%;\n animation: mailharbor-spin 0.7s linear infinite;\n opacity: 0.8;\n vertical-align: -2px;\n flex: none;\n}\n\n@keyframes mailharbor-spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n.extract-body {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.extract-title {\n width: 100%;\n height: 30px;\n font-size: 13px;\n font-weight: 500;\n}\n\n.extract-meta {\n display: grid;\n grid-template-columns: 150px 110px minmax(0, 1fr);\n gap: 6px;\n}\n\n.extract-meta input,\n.extract-meta select {\n height: 28px;\n font-size: 11.5px;\n width: 100%;\n}\n\n.extract-owner {\n width: 100%;\n}\n\n@media (max-width: 720px) {\n .extract-meta {\n grid-template-columns: minmax(0, 1fr);\n }\n}\n\n/* ---------- conversation reading ---------- */\n\n.mailharbor-thread-view {\n flex: 1;\n min-height: 0;\n overflow: auto;\n display: flex;\n flex-direction: column;\n gap: 10px;\n padding: 14px 18px 32px;\n background: var(--m-bg);\n}\n\n.mailharbor-thread-hint {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 0 4px 2px;\n font-size: 11.5px;\n color: var(--m-text-3);\n}\n\n.mailharbor-thread-msg {\n border: 1px solid var(--m-line-soft);\n border-radius: 12px;\n background: var(--m-bg-1);\n overflow: hidden;\n}\n\n.mailharbor-thread-msg.selected {\n border-color: var(--m-accent);\n box-shadow: 0 0 0 1px var(--m-accent-soft);\n}\n\n.mailharbor-thread-head {\n display: flex;\n align-items: center;\n gap: 9px;\n width: 100%;\n height: auto;\n padding: 9px 12px;\n text-align: left;\n border-radius: 0;\n}\n\n.mailharbor-thread-head:hover {\n background: var(--m-hover);\n}\n\n.thread-who {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.thread-who strong {\n font-size: 12.5px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.thread-to {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.mailharbor-thread-preview {\n padding: 0 14px 10px 47px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.mailharbor-thread-body {\n padding: 0 12px 12px;\n}\n\n.mailharbor-thread-frame {\n height: 380px;\n border: 1px solid var(--m-line-soft);\n border-radius: 8px;\n overflow: hidden;\n background: #fff;\n}\n\n.mailharbor-thread-frame iframe {\n display: block;\n width: 100%;\n height: 100%;\n border: 0;\n background: #fff;\n}\n\n.thread-loading {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 4px 12px;\n}\n\n@media (max-width: 900px) {\n .thread-to {\n display: none;\n }\n}\n\n/* ---------- compact reader ---------- */\n\n.mailharbor-reader-head {\n padding: 10px 16px 8px;\n gap: 6px;\n}\n\n.mailharbor-reader-title h2 {\n font-size: 15px;\n}\n\n.mailharbor-reader-meta.compact {\n gap: 10px;\n align-items: center;\n}\n\n.mailharbor-reader-meta.compact .who {\n gap: 6px;\n}\n\n.mailharbor-reader-recipients {\n display: flex;\n flex-wrap: wrap;\n gap: 6px 14px;\n font-size: 11.5px;\n color: var(--m-text-3);\n padding: 0 2px;\n}\n\n.mailharbor-reader-actions {\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.mailharbor-reader-actions button {\n height: 28px;\n padding: 0 8px;\n}\n\n.mailharbor-attachments.compact {\n display: flex;\n gap: 6px;\n padding: 6px 16px;\n overflow-x: auto;\n border-top: 1px solid var(--m-line-soft);\n flex-wrap: nowrap;\n}\n\n.mailharbor-attachments.compact .mailharbor-attachment {\n flex: none;\n padding: 4px 8px;\n border: 1px solid var(--m-line-soft);\n border-radius: 6px;\n max-width: 260px;\n}\n\n.mailharbor-reader-body {\n flex: 1;\n min-height: 0;\n}\n\n.thread-who {\n flex-direction: row;\n align-items: baseline;\n gap: 6px;\n min-width: 0;\n}\n\n.thread-who strong {\n max-width: 45%;\n}\n\n.thread-who .small {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n}\n\n.thread-date {\n flex: none;\n}\n\n.mailharbor button.mailharbor-thread-head {\n justify-content: flex-start;\n padding: 7px 10px;\n gap: 8px;\n}\n\n.mailharbor-thread-preview {\n padding: 0 12px 8px 40px;\n}\n\n.mailharbor-thread-frame {\n height: clamp(220px, 42vh, 420px);\n}\n\n.mailharbor-refreshing {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 0 14px 6px;\n font-size: 11px;\n color: var(--m-text-3);\n}\n\n.mailharbor-attachment-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 8px 0 2px;\n}\n\n.mailharbor-attachment-chips .mailharbor-attachment {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n max-width: 280px;\n padding: 4px 8px;\n border: 1px solid var(--m-line-soft);\n border-radius: 6px;\n background: var(--m-bg-1);\n font-size: 11.5px;\n}\n\n.mailharbor-attachment-chips .mailharbor-attachment .name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.mailharbor-thread-recipients {\n display: flex;\n flex-wrap: wrap;\n gap: 4px 14px;\n padding: 0 2px 8px;\n}\n\n.mailharbor-thread-frame {\n height: clamp(260px, 55vh, 640px);\n}\n\n.mailharbor-thread-body {\n padding: 8px 12px 12px;\n}\n\n.mailharbor-ai-summary.clamp,\n.mailharbor-ai-text.clamp {\n max-height: 150px;\n overflow: hidden;\n mask-image: linear-gradient(to bottom, #000 72%, transparent 100%);\n -webkit-mask-image: linear-gradient(to bottom, #000 72%, transparent 100%);\n}\n\n.mailharbor-ai-full {\n display: flex;\n flex-direction: column;\n gap: 14px;\n max-height: 66vh;\n overflow: auto;\n padding-right: 4px;\n font-size: 13px;\n line-height: 1.7;\n color: var(--m-text);\n}\n\n.mailharbor-ai-full h4 {\n margin: 0 0 4px;\n font-size: 11px;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n color: var(--m-text-3);\n}\n\n.mailharbor-ai-full .mailharbor-markdown {\n font-size: 13px;\n line-height: 1.7;\n}\n\n/* ---------- sync popover ---------- */\n\n.mailharbor-sync {\n position: relative;\n}\n\n.mailharbor-sync-pop {\n position: absolute;\n top: calc(100% + 8px);\n right: 0;\n z-index: 30;\n width: 320px;\n padding: 12px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n border: 1px solid var(--m-line);\n border-radius: 10px;\n background: var(--m-bg-2);\n box-shadow: 0 16px 40px rgba(0, 0, 0, 0.4);\n}\n\n.mailharbor-sync-head {\n display: flex;\n align-items: baseline;\n gap: 8px;\n}\n\n.mailharbor-sync-stats {\n display: flex;\n justify-content: space-between;\n gap: 8px;\n font-size: 11.5px;\n color: var(--m-text-3);\n}\n\n.mailharbor-sync-log {\n max-height: 110px;\n overflow: auto;\n padding: 6px 8px;\n border-radius: 6px;\n background: var(--m-bg);\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 10.5px;\n white-space: pre-wrap;\n color: var(--m-text-3);\n}\n\n.mailharbor-sync-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.mailharbor-thread-msg,\n.mailharbor-ai-card {\n flex: none;\n}\n\n.mailharbor-unread-banner {\n display: flex;\n align-items: center;\n gap: 6px;\n margin: 0 10px 8px;\n padding: 6px 10px;\n border-radius: 8px;\n background: var(--m-accent-soft);\n color: var(--m-text-2);\n font-size: 11.5px;\n text-align: left;\n}\n\n.mailharbor-unread-banner:hover {\n background: var(--m-accent-soft);\n color: var(--m-text);\n}\n\n.mailharbor-starred {\n display: inline-flex;\n align-items: center;\n color: #e0b341;\n flex: none;\n}\n\n.mailharbor-reader-actions select {\n height: 28px;\n max-width: 130px;\n font-size: 11.5px;\n}\n";
|
|
39
39
|
|
|
40
40
|
// src/client/icon.tsx
|
|
41
41
|
var import_react = require("react");
|
|
@@ -88,6 +88,24 @@ var api = {
|
|
|
88
88
|
`messages${query({ ...params, unread: params.unread === true ? 1 : void 0 })}`
|
|
89
89
|
),
|
|
90
90
|
message: (params) => request(`messages/${encodeURIComponent(params.id)}${query({ ...params })}`),
|
|
91
|
+
star: (params) => request(
|
|
92
|
+
`messages/${encodeURIComponent(params.id)}/star${query({
|
|
93
|
+
accountId: params.accountId ?? null,
|
|
94
|
+
source: params.source,
|
|
95
|
+
mailbox: params.mailbox
|
|
96
|
+
})}`,
|
|
97
|
+
{ method: "POST", body: JSON.stringify({ starred: params.starred }) }
|
|
98
|
+
),
|
|
99
|
+
moveMessage: (params) => request(
|
|
100
|
+
`messages/${encodeURIComponent(params.id)}/move${query({
|
|
101
|
+
accountId: params.accountId ?? null
|
|
102
|
+
})}`,
|
|
103
|
+
{ method: "POST", body: JSON.stringify({ target: params.target }) }
|
|
104
|
+
),
|
|
105
|
+
bulkAction: (payload) => request("messages/bulk", {
|
|
106
|
+
method: "POST",
|
|
107
|
+
body: JSON.stringify(payload)
|
|
108
|
+
}),
|
|
91
109
|
setRead: (params) => request(
|
|
92
110
|
`messages/${encodeURIComponent(params.id)}/read${query({
|
|
93
111
|
accountId: params.accountId ?? null,
|
|
@@ -521,6 +539,11 @@ var PATHS = {
|
|
|
521
539
|
folder: (0, import_react3.createElement)("path", {
|
|
522
540
|
d: "M3.5 6.5A1.5 1.5 0 0 1 5 5h4l2 2.5h8A1.5 1.5 0 0 1 20.5 9v8.5A1.5 1.5 0 0 1 19 19H5a1.5 1.5 0 0 1-1.5-1.5z"
|
|
523
541
|
}),
|
|
542
|
+
star: (0, import_react3.createElement)("path", {
|
|
543
|
+
d: "m12 3.6 2.6 5.3 5.9.9-4.3 4.1 1 5.9-5.2-2.8-5.2 2.8 1-5.9-4.3-4.1 5.9-.9z",
|
|
544
|
+
fill: "currentColor",
|
|
545
|
+
stroke: "none"
|
|
546
|
+
}),
|
|
524
547
|
calendar: (0, import_react3.createElement)(
|
|
525
548
|
"g",
|
|
526
549
|
null,
|
|
@@ -2056,7 +2079,12 @@ function Reader({
|
|
|
2056
2079
|
onClose,
|
|
2057
2080
|
thread = [],
|
|
2058
2081
|
onSelectMessage,
|
|
2059
|
-
loadDetail
|
|
2082
|
+
loadDetail,
|
|
2083
|
+
folders = [],
|
|
2084
|
+
onStar,
|
|
2085
|
+
onArchive,
|
|
2086
|
+
onDelete,
|
|
2087
|
+
onMove
|
|
2060
2088
|
}) {
|
|
2061
2089
|
const [plain, setPlain] = (0, import_react8.useState)(false);
|
|
2062
2090
|
const [loadImages, setLoadImages] = (0, import_react8.useState)(false);
|
|
@@ -2121,6 +2149,17 @@ function Reader({
|
|
|
2121
2149
|
(0, import_react8.createElement)(Icon, { name: "chevronLeft" })
|
|
2122
2150
|
),
|
|
2123
2151
|
(0, import_react8.createElement)("h2", { style: { flex: 1 } }, detail.subject),
|
|
2152
|
+
onStar === void 0 ? null : (0, import_react8.createElement)(
|
|
2153
|
+
"button",
|
|
2154
|
+
{
|
|
2155
|
+
className: "ghost icon",
|
|
2156
|
+
title: detail.starred === true ? "\u53D6\u6D88\u661F\u6807" : "\u6807\u661F",
|
|
2157
|
+
"aria-label": detail.starred === true ? "\u53D6\u6D88\u661F\u6807" : "\u6807\u661F",
|
|
2158
|
+
style: detail.starred === true ? { color: "#e0b341" } : void 0,
|
|
2159
|
+
onClick: () => onStar(detail.starred !== true)
|
|
2160
|
+
},
|
|
2161
|
+
(0, import_react8.createElement)(Icon, { name: "star", size: 15 })
|
|
2162
|
+
),
|
|
2124
2163
|
(0, import_react8.createElement)(
|
|
2125
2164
|
"button",
|
|
2126
2165
|
{
|
|
@@ -2185,6 +2224,33 @@ function Reader({
|
|
|
2185
2224
|
"\u8F6C\u53D1"
|
|
2186
2225
|
),
|
|
2187
2226
|
(0, import_react8.createElement)("span", { className: "mailharbor-divider" }),
|
|
2227
|
+
onArchive === void 0 ? null : (0, import_react8.createElement)(
|
|
2228
|
+
"button",
|
|
2229
|
+
{ className: "ghost", onClick: onArchive, title: "\u79FB\u5230\u5F52\u6863\u6587\u4EF6\u5939" },
|
|
2230
|
+
(0, import_react8.createElement)(Icon, { name: "archive", size: 14 }),
|
|
2231
|
+
"\u5F52\u6863"
|
|
2232
|
+
),
|
|
2233
|
+
onDelete === void 0 ? null : (0, import_react8.createElement)(
|
|
2234
|
+
"button",
|
|
2235
|
+
{ className: "ghost", onClick: onDelete, title: "\u79FB\u5230\u5783\u573E\u7BB1" },
|
|
2236
|
+
(0, import_react8.createElement)(Icon, { name: "trash", size: 14 }),
|
|
2237
|
+
"\u5220\u9664"
|
|
2238
|
+
),
|
|
2239
|
+
onMove === void 0 || folders.length === 0 ? null : (0, import_react8.createElement)(
|
|
2240
|
+
"select",
|
|
2241
|
+
{
|
|
2242
|
+
value: "",
|
|
2243
|
+
"aria-label": "\u79FB\u52A8\u5230\u6587\u4EF6\u5939",
|
|
2244
|
+
title: "\u79FB\u52A8\u5230\u6587\u4EF6\u5939",
|
|
2245
|
+
onChange: (event) => {
|
|
2246
|
+
const target = event.target.value;
|
|
2247
|
+
if (target !== "") onMove(target);
|
|
2248
|
+
}
|
|
2249
|
+
},
|
|
2250
|
+
(0, import_react8.createElement)("option", { value: "" }, "\u79FB\u52A8\u5230\u2026"),
|
|
2251
|
+
folders.map((folder) => (0, import_react8.createElement)("option", { key: folder.name, value: folder.name }, folder.label))
|
|
2252
|
+
),
|
|
2253
|
+
(0, import_react8.createElement)("span", { className: "mailharbor-divider" }),
|
|
2188
2254
|
(0, import_react8.createElement)(
|
|
2189
2255
|
"button",
|
|
2190
2256
|
{ className: "ghost", onClick: () => onAiAction("summary") },
|
|
@@ -2970,6 +3036,81 @@ ${projectPicker.subject}`,
|
|
|
2970
3036
|
setError(errorText5(caught));
|
|
2971
3037
|
}
|
|
2972
3038
|
};
|
|
3039
|
+
const archiveFolder = () => folders.find((folder) => /archive|存档/i.test(folder.name))?.name ?? "";
|
|
3040
|
+
const trashFolder = () => folders.find((folder) => /trash|deleted|已删除/i.test(folder.name))?.name ?? "";
|
|
3041
|
+
const starMessage = async (starred) => {
|
|
3042
|
+
if (selected === null) return;
|
|
3043
|
+
try {
|
|
3044
|
+
await api.star({
|
|
3045
|
+
id: selected.id,
|
|
3046
|
+
accountId: selected.accountId,
|
|
3047
|
+
source,
|
|
3048
|
+
mailbox,
|
|
3049
|
+
starred
|
|
3050
|
+
});
|
|
3051
|
+
setSelected({ ...selected, starred });
|
|
3052
|
+
setPage((current) => ({
|
|
3053
|
+
...current,
|
|
3054
|
+
items: current.items.map(
|
|
3055
|
+
(row) => row.id === selected.id && row.accountId === selected.accountId ? { ...row, starred } : row
|
|
3056
|
+
)
|
|
3057
|
+
}));
|
|
3058
|
+
} catch (caught) {
|
|
3059
|
+
setError(errorText5(caught));
|
|
3060
|
+
}
|
|
3061
|
+
};
|
|
3062
|
+
const moveCurrent = async (target, message) => {
|
|
3063
|
+
if (selected === null) return;
|
|
3064
|
+
try {
|
|
3065
|
+
await api.moveMessage({ id: selected.id, accountId: selected.accountId, mailbox, target });
|
|
3066
|
+
setSelected(null);
|
|
3067
|
+
notice(message);
|
|
3068
|
+
refresh();
|
|
3069
|
+
} catch (caught) {
|
|
3070
|
+
setError(errorText5(caught));
|
|
3071
|
+
}
|
|
3072
|
+
};
|
|
3073
|
+
const archiveMessage = () => {
|
|
3074
|
+
const target = archiveFolder();
|
|
3075
|
+
if (target === "") {
|
|
3076
|
+
notice("\u6CA1\u6709\u627E\u5230\u5F52\u6863\u6587\u4EF6\u5939");
|
|
3077
|
+
return;
|
|
3078
|
+
}
|
|
3079
|
+
void moveCurrent(target, "\u5DF2\u5F52\u6863");
|
|
3080
|
+
};
|
|
3081
|
+
const deleteMessage = () => {
|
|
3082
|
+
const target = trashFolder();
|
|
3083
|
+
if (target === "") {
|
|
3084
|
+
notice("\u6CA1\u6709\u627E\u5230\u5783\u573E\u7BB1\u6587\u4EF6\u5939");
|
|
3085
|
+
return;
|
|
3086
|
+
}
|
|
3087
|
+
void moveCurrent(target, "\u5DF2\u79FB\u5230\u5783\u573E\u7BB1");
|
|
3088
|
+
};
|
|
3089
|
+
const runBulk = async (action) => {
|
|
3090
|
+
const ids = selectedKeys.map((key) => key.slice(key.lastIndexOf(":") + 1));
|
|
3091
|
+
if (ids.length === 0 || accountScope === null) return;
|
|
3092
|
+
const target = action === "archive" ? archiveFolder() : action === "delete" ? trashFolder() : "";
|
|
3093
|
+
if ((action === "archive" || action === "delete") && target === "") {
|
|
3094
|
+
notice(action === "archive" ? "\u6CA1\u6709\u627E\u5230\u5F52\u6863\u6587\u4EF6\u5939" : "\u6CA1\u6709\u627E\u5230\u5783\u573E\u7BB1\u6587\u4EF6\u5939");
|
|
3095
|
+
return;
|
|
3096
|
+
}
|
|
3097
|
+
try {
|
|
3098
|
+
await api.bulkAction({
|
|
3099
|
+
accountId: accountScope,
|
|
3100
|
+
action,
|
|
3101
|
+
ids,
|
|
3102
|
+
...target === "" ? {} : { target }
|
|
3103
|
+
});
|
|
3104
|
+
notice(
|
|
3105
|
+
action === "read" ? "\u5DF2\u6807\u4E3A\u5DF2\u8BFB" : action === "unread" ? "\u5DF2\u6807\u4E3A\u672A\u8BFB" : action === "star" ? "\u5DF2\u6807\u661F" : action === "archive" ? "\u5DF2\u5F52\u6863" : "\u5DF2\u79FB\u5230\u5783\u573E\u7BB1"
|
|
3106
|
+
);
|
|
3107
|
+
setSelectMode(false);
|
|
3108
|
+
setSelectedKeys([]);
|
|
3109
|
+
refresh();
|
|
3110
|
+
} catch (caught) {
|
|
3111
|
+
setError(errorText5(caught));
|
|
3112
|
+
}
|
|
3113
|
+
};
|
|
2973
3114
|
const startCompose = (mode) => {
|
|
2974
3115
|
const owner = account ?? accounts.find((item) => item.id === state?.activeAccountId) ?? accounts[0];
|
|
2975
3116
|
if (owner === void 0) return;
|
|
@@ -3192,6 +3333,11 @@ ${projectPicker.subject}`,
|
|
|
3192
3333
|
}) : item.unread ? (0, import_react9.createElement)("span", { className: "dot" }) : null,
|
|
3193
3334
|
sent ? (0, import_react9.createElement)("span", { className: "to-label" }, "\u6536\u4EF6\u4EBA ") : null,
|
|
3194
3335
|
(0, import_react9.createElement)("span", { className: "from" }, `${who}${extra}`),
|
|
3336
|
+
item.starred ? (0, import_react9.createElement)(
|
|
3337
|
+
"span",
|
|
3338
|
+
{ className: "mailharbor-starred", title: "\u5DF2\u6807\u661F" },
|
|
3339
|
+
(0, import_react9.createElement)(Icon, { name: "star", size: 12 })
|
|
3340
|
+
) : null,
|
|
3195
3341
|
item.hasAttachments ? (0, import_react9.createElement)(Icon, { name: "paperclip", size: 13 }) : null,
|
|
3196
3342
|
source === "local" && item.backedUp === false ? (0, import_react9.createElement)("span", { className: "badge warn" }, "\u672A\u5907\u4EFD") : null,
|
|
3197
3343
|
meta.groupCount !== void 0 && meta.groupCount > 1 ? (0, import_react9.createElement)(
|
|
@@ -3517,6 +3663,16 @@ ${projectPicker.subject}`,
|
|
|
3517
3663
|
},
|
|
3518
3664
|
"\u52A0\u5165\u9879\u76EE"
|
|
3519
3665
|
),
|
|
3666
|
+
(0, import_react9.createElement)("span", { className: "mailharbor-divider" }),
|
|
3667
|
+
(0, import_react9.createElement)("button", { className: "ghost small", onClick: () => void runBulk("read") }, "\u5DF2\u8BFB"),
|
|
3668
|
+
(0, import_react9.createElement)("button", { className: "ghost small", onClick: () => void runBulk("unread") }, "\u672A\u8BFB"),
|
|
3669
|
+
(0, import_react9.createElement)("button", { className: "ghost small", onClick: () => void runBulk("star") }, "\u6807\u661F"),
|
|
3670
|
+
(0, import_react9.createElement)("button", { className: "ghost small", onClick: () => void runBulk("archive") }, "\u5F52\u6863"),
|
|
3671
|
+
(0, import_react9.createElement)(
|
|
3672
|
+
"button",
|
|
3673
|
+
{ className: "ghost small danger", onClick: () => void runBulk("delete") },
|
|
3674
|
+
"\u5220\u9664"
|
|
3675
|
+
),
|
|
3520
3676
|
(0, import_react9.createElement)(
|
|
3521
3677
|
"button",
|
|
3522
3678
|
{
|
|
@@ -3699,7 +3855,15 @@ ${projectPicker.subject}`,
|
|
|
3699
3855
|
onClose: narrow ? () => setSelected(null) : void 0,
|
|
3700
3856
|
thread: threadItems,
|
|
3701
3857
|
onSelectMessage: (item) => void openMessage(item),
|
|
3702
|
-
loadDetail: loadDetailFor
|
|
3858
|
+
loadDetail: loadDetailFor,
|
|
3859
|
+
folders: folders.map((folder) => ({
|
|
3860
|
+
name: folder.name,
|
|
3861
|
+
label: folderName(folder.label ?? folder.name)
|
|
3862
|
+
})),
|
|
3863
|
+
onStar: (starred) => void starMessage(starred),
|
|
3864
|
+
onArchive: archiveMessage,
|
|
3865
|
+
onDelete: deleteMessage,
|
|
3866
|
+
onMove: (target) => void moveCurrent(target, "\u5DF2\u79FB\u52A8")
|
|
3703
3867
|
})
|
|
3704
3868
|
),
|
|
3705
3869
|
railOpen ? (0, import_react9.createElement)(AiRail, {
|
|
@@ -5391,7 +5555,7 @@ function TaskEditor({
|
|
|
5391
5555
|
}
|
|
5392
5556
|
|
|
5393
5557
|
// src/client/index.tsx
|
|
5394
|
-
var VERSION = "0.
|
|
5558
|
+
var VERSION = "0.13.0";
|
|
5395
5559
|
var inject = ["slots"];
|
|
5396
5560
|
var PANEL_ID = "mailharbor";
|
|
5397
5561
|
var TASKS_PANEL_ID = "mailharbor-tasks";
|