diff --git a/static/css/documents-gallery-editor.css b/static/css/documents-gallery-editor.css
index 213808695..3ef2c067c 100644
--- a/static/css/documents-gallery-editor.css
+++ b/static/css/documents-gallery-editor.css
@@ -10,6 +10,7 @@
* order:
* 1. static/style.css
* 2. static/css/documents-gallery-editor.css
+ * 3. static/css/email-calendar-notes-tasks.css
*
* Rules were moved verbatim. A rule stays in style.css when its selector group
* covers more than one panel, when the class is shared design language used by
diff --git a/static/css/email-calendar-notes-tasks.css b/static/css/email-calendar-notes-tasks.css
new file mode 100644
index 000000000..3f5cced50
--- /dev/null
+++ b/static/css/email-calendar-notes-tasks.css
@@ -0,0 +1,1572 @@
+/* Email, calendar, notes and tasks panels.
+ *
+ * Split out of style.css for maintainability, not for performance: this file
+ * is loaded eagerly from index.html immediately after style.css, so the rules
+ * land in the cascade in exactly the order they had inside the single file.
+ * Nothing here is lazy-loaded.
+ *
+ * LOAD ORDER IS PART OF THE CONTRACT. The tags in static/index.html and
+ * the PRECACHE list in static/sw.js must both list the stylesheets in this
+ * order:
+ * 1. static/style.css
+ * 2. static/css/documents-gallery-editor.css
+ * 3. static/css/email-calendar-notes-tasks.css
+ *
+ * Rules were moved verbatim. A rule stays in style.css when its selector group
+ * covers more than one panel, when the class is shared design language used by
+ * modules outside this panel, or when moving it would change which of two
+ * equally specific rules wins.
+ */
+
+@keyframes email-notif-breathe {
+ 0%, 100% {
+ box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent, var(--red)) 60%, transparent);
+ opacity: 0.85;
+ }
+ 50% {
+ box-shadow: 0 0 6px 2px color-mix(in srgb, var(--accent, var(--red)) 55%, transparent);
+ opacity: 1;
+ }
+ }
+.memory-item.task-paused:hover {
+ opacity: 0.85 !important;
+ filter: saturate(0.9);
+}
+.email-folder-picker .email-folder-select-control {
+ padding-left: 26px;
+}
+/* Email bulk-select mode owns the whole card. Sender names and tags must not
+ open search/filter actions until Select is cancelled. */
+#email-lib-grid.email-selecting .email-meta-sender,
+#email-lib-grid.email-selecting .email-card-tags,
+#email-lib-grid.email-selecting .email-card-favorite,
+#email-lib-grid.email-selecting .email-card-nav-arrows,
+#email-lib-grid.email-selecting .email-card-status,
+#email-lib-grid.email-selecting .email-card-actions {
+ pointer-events: none !important;
+}
+.email-reader-actions-inline > .email-reader-more-wrap { order: 5; }
+/* ── Tasks ── */
+#tool-tasks-btn.task-failure-pending,
+#rail-tasks.task-failure-pending {
+ color: var(--red, #f87171);
+}
+#tool-tasks-btn.task-completion-pending,
+#rail-tasks.task-completion-pending {
+ color: var(--accent, var(--green, #86efac));
+}
+#tool-tasks-btn.task-failure-pending::after,
+#rail-tasks.task-failure-pending::after,
+#tool-tasks-btn.task-completion-pending::after,
+#rail-tasks.task-completion-pending::after {
+ content: '';
+ width: 7px;
+ height: 7px;
+ border-radius: 999px;
+ background: var(--red, #f87171);
+ box-shadow: 0 0 7px var(--red, #f87171), 0 0 3px var(--red, #f87171);
+ flex: 0 0 auto;
+}
+#tool-tasks-btn.task-completion-pending::after,
+#rail-tasks.task-completion-pending::after {
+ background: var(--accent, var(--green, #86efac));
+ box-shadow: 0 0 7px var(--accent, var(--green, #86efac)), 0 0 3px var(--accent, var(--green, #86efac));
+}
+#tool-tasks-btn.task-failure-pending.task-completion-pending,
+#rail-tasks.task-failure-pending.task-completion-pending {
+ color: var(--red, #f87171);
+}
+#tool-tasks-btn.task-failure-pending.task-completion-pending::after,
+#rail-tasks.task-failure-pending.task-completion-pending::after {
+ background: var(--red, #f87171);
+ box-shadow: 0 0 7px var(--red, #f87171), 0 0 3px var(--red, #f87171);
+}
+#rail-tasks.task-failure-pending::after,
+#rail-tasks.task-completion-pending::after {
+ position: absolute;
+ right: 8px;
+ top: 8px;
+}
+.tasks-activity-card,
+.tasks-activity-list {
+ min-height: 0;
+}
+.tasks-activity-list {
+ overflow-y: auto;
+ -webkit-overflow-scrolling: touch;
+}
+.task-log-row.task-log-row-error .task-log-task-icon svg {
+ opacity: 0.82 !important;
+}
+.task-log-running-inline .task-log-running-label { font-weight: 500; }
+.task-log-running-elapsed {
+ margin-left: 6px;
+ opacity: 0.6;
+ font-variant-numeric: tabular-nums;
+}
+.task-log-time {
+ opacity: 0.5;
+ font-variant-numeric: tabular-nums;
+}
+@keyframes task-log-pulse {
+ 0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, #60a5fa 60%, transparent); }
+ 50% { box-shadow: 0 0 0 4px color-mix(in srgb, #60a5fa 0%, transparent); }
+}
+.task-log-row-body li { margin: 2px 0; }
+.task-log-row-body hr {
+ border: none;
+ border-top: 1px solid color-mix(in srgb, var(--fg) 12%, transparent);
+ margin: 8px 0;
+}
+.task-log-row-toggle::before {
+ color: color-mix(in srgb, var(--accent, var(--fg)) 80%, transparent);
+ opacity: 0.8;
+}
+.task-log-row-toggle:hover::before { opacity: 1; }
+/* A