fix: keyboard multi-select uses stable IDs, improve Swiss theme, add Brutalist theme
This commit is contained in:
@@ -1,6 +1,9 @@
|
|||||||
// Outlook Relook — Gmail-Style Keyboard Navigation & Multi-Select
|
// Outlook Relook — Gmail-Style Keyboard Navigation & Multi-Select
|
||||||
// Adds keyboard focus cursor and multi-select to OWA's message list.
|
// Adds keyboard focus cursor and multi-select to OWA's message list.
|
||||||
// Gated by the keyboardMultiSelect setting.
|
// Gated by the keyboardMultiSelect setting.
|
||||||
|
//
|
||||||
|
// Tracks selections by stable message ID (data attribute or aria-label)
|
||||||
|
// rather than DOM element reference, since OWA frequently re-renders rows.
|
||||||
|
|
||||||
window.OutlookRelook = window.OutlookRelook || {};
|
window.OutlookRelook = window.OutlookRelook || {};
|
||||||
|
|
||||||
@@ -11,26 +14,42 @@ window.OutlookRelook.Keyboard = (function () {
|
|||||||
var currentSettings = {};
|
var currentSettings = {};
|
||||||
var cleanupFns = [];
|
var cleanupFns = [];
|
||||||
|
|
||||||
// State
|
// State — track by ID strings, not DOM references
|
||||||
var focusedIndex = -1; // Index of the focused message in the list
|
var focusedId = null; // ID of the focused message
|
||||||
var selectedSet = new Set(); // Set of selected message DOM elements
|
var selectedIds = new Set(); // Set of selected message IDs
|
||||||
var countBadge = null; // Selection count badge element
|
var countBadge = null;
|
||||||
|
|
||||||
// --- Helpers ---
|
// --- Message ID extraction ---
|
||||||
|
// OWA messages have various attributes we can use as stable IDs.
|
||||||
|
// Try data-convid, data-itemid, id, or fall back to aria-label.
|
||||||
|
|
||||||
|
function getMessageId(el) {
|
||||||
|
return el.getAttribute('data-convid')
|
||||||
|
|| el.getAttribute('data-itemid')
|
||||||
|
|| el.getAttribute('data-tid')
|
||||||
|
|| el.getAttribute('id')
|
||||||
|
|| el.getAttribute('aria-label')
|
||||||
|
|| null;
|
||||||
|
}
|
||||||
|
|
||||||
function getMessageItems() {
|
function getMessageItems() {
|
||||||
// Get all message items from the message list
|
|
||||||
var items = document.querySelectorAll(
|
var items = document.querySelectorAll(
|
||||||
'[role="listbox"] [role="option"], [role="list"] [role="listitem"]'
|
'[role="listbox"] [role="option"], [role="list"] [role="listitem"]'
|
||||||
);
|
);
|
||||||
return Array.from(items);
|
return Array.from(items);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function findItemById(items, id) {
|
||||||
|
if (!id) return -1;
|
||||||
|
for (var i = 0; i < items.length; i++) {
|
||||||
|
if (getMessageId(items[i]) === id) return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
function isComposeOrDialogActive() {
|
function isComposeOrDialogActive() {
|
||||||
var active = document.activeElement;
|
var active = document.activeElement;
|
||||||
if (!active) return false;
|
if (!active) return false;
|
||||||
|
|
||||||
// Check if focus is in a compose area, search bar, or dialog
|
|
||||||
var tag = active.tagName.toLowerCase();
|
var tag = active.tagName.toLowerCase();
|
||||||
if (tag === 'input' || tag === 'textarea') return true;
|
if (tag === 'input' || tag === 'textarea') return true;
|
||||||
if (active.getAttribute('contenteditable') === 'true') return true;
|
if (active.getAttribute('contenteditable') === 'true') return true;
|
||||||
@@ -38,53 +57,90 @@ window.OutlookRelook.Keyboard = (function () {
|
|||||||
if (active.closest('[role="search"]')) return true;
|
if (active.closest('[role="search"]')) return true;
|
||||||
if (active.closest('[aria-label*="compose" i]')) return true;
|
if (active.closest('[aria-label*="compose" i]')) return true;
|
||||||
if (active.closest('[aria-label*="New message" i]')) return true;
|
if (active.closest('[aria-label*="New message" i]')) return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setFocus(items, index) {
|
// --- Visual state application ---
|
||||||
// Remove old focus
|
// Re-applies focus and selection classes to current DOM elements
|
||||||
var oldFocused = document.querySelector('.or-kb-focused');
|
// based on the ID-based state. Called after every key action and
|
||||||
if (oldFocused) oldFocused.classList.remove('or-kb-focused');
|
// by the MutationObserver when OWA re-renders.
|
||||||
|
|
||||||
if (index < 0 || index >= items.length) return;
|
function applyVisualState(items) {
|
||||||
|
// Clear all visual markers first
|
||||||
|
var oldFocused = document.querySelectorAll('.or-kb-focused');
|
||||||
|
for (var f = 0; f < oldFocused.length; f++) oldFocused[f].classList.remove('or-kb-focused');
|
||||||
|
var oldSelected = document.querySelectorAll('.or-kb-selected');
|
||||||
|
for (var s = 0; s < oldSelected.length; s++) oldSelected[s].classList.remove('or-kb-selected');
|
||||||
|
|
||||||
focusedIndex = index;
|
if (!items) items = getMessageItems();
|
||||||
var item = items[index];
|
|
||||||
item.classList.add('or-kb-focused');
|
|
||||||
|
|
||||||
// Scroll into view if needed
|
// Apply focus
|
||||||
item.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
|
if (focusedId) {
|
||||||
}
|
var focusIdx = findItemById(items, focusedId);
|
||||||
|
if (focusIdx >= 0) {
|
||||||
function toggleSelect(item) {
|
items[focusIdx].classList.add('or-kb-focused');
|
||||||
if (selectedSet.has(item)) {
|
}
|
||||||
selectedSet.delete(item);
|
|
||||||
item.classList.remove('or-kb-selected');
|
|
||||||
} else {
|
|
||||||
selectedSet.add(item);
|
|
||||||
item.classList.add('or-kb-selected');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply selections
|
||||||
|
selectedIds.forEach(function (id) {
|
||||||
|
var idx = findItemById(items, id);
|
||||||
|
if (idx >= 0) {
|
||||||
|
items[idx].classList.add('or-kb-selected');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
updateCountBadge();
|
updateCountBadge();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Focus management ---
|
||||||
|
|
||||||
|
function getFocusedIndex(items) {
|
||||||
|
if (!focusedId) return -1;
|
||||||
|
return findItemById(items, focusedId);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setFocus(items, index) {
|
||||||
|
if (index < 0 || index >= items.length) return;
|
||||||
|
focusedId = getMessageId(items[index]);
|
||||||
|
applyVisualState(items);
|
||||||
|
items[index].scrollIntoView({ block: 'nearest', behavior: 'smooth' });
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Selection management ---
|
||||||
|
|
||||||
|
function toggleSelect(items, index) {
|
||||||
|
if (index < 0 || index >= items.length) return;
|
||||||
|
var id = getMessageId(items[index]);
|
||||||
|
if (!id) return;
|
||||||
|
|
||||||
|
if (selectedIds.has(id)) {
|
||||||
|
selectedIds.delete(id);
|
||||||
|
} else {
|
||||||
|
selectedIds.add(id);
|
||||||
|
}
|
||||||
|
applyVisualState(items);
|
||||||
|
}
|
||||||
|
|
||||||
function clearSelection() {
|
function clearSelection() {
|
||||||
selectedSet.forEach(function (item) {
|
selectedIds.clear();
|
||||||
item.classList.remove('or-kb-selected');
|
var oldSelected = document.querySelectorAll('.or-kb-selected');
|
||||||
});
|
for (var i = 0; i < oldSelected.length; i++) oldSelected[i].classList.remove('or-kb-selected');
|
||||||
selectedSet.clear();
|
|
||||||
updateCountBadge();
|
updateCountBadge();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getActionTargets(items) {
|
function getActionTargets(items) {
|
||||||
// If messages are selected, return those. Otherwise return the focused message.
|
var targets = [];
|
||||||
if (selectedSet.size > 0) {
|
if (selectedIds.size > 0) {
|
||||||
return Array.from(selectedSet);
|
selectedIds.forEach(function (id) {
|
||||||
|
var idx = findItemById(items, id);
|
||||||
|
if (idx >= 0) targets.push(items[idx]);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
var fi = getFocusedIndex(items);
|
||||||
|
if (fi >= 0) targets.push(items[fi]);
|
||||||
}
|
}
|
||||||
if (focusedIndex >= 0 && focusedIndex < items.length) {
|
return targets;
|
||||||
return [items[focusedIndex]];
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Selection count badge ---
|
// --- Selection count badge ---
|
||||||
@@ -101,7 +157,7 @@ window.OutlookRelook.Keyboard = (function () {
|
|||||||
function updateCountBadge() {
|
function updateCountBadge() {
|
||||||
if (!countBadge) countBadge = createCountBadge();
|
if (!countBadge) countBadge = createCountBadge();
|
||||||
if (!countBadge) return;
|
if (!countBadge) return;
|
||||||
var count = selectedSet.size;
|
var count = selectedIds.size;
|
||||||
if (count === 0) {
|
if (count === 0) {
|
||||||
countBadge.style.opacity = '0';
|
countBadge.style.opacity = '0';
|
||||||
} else {
|
} else {
|
||||||
@@ -111,30 +167,20 @@ window.OutlookRelook.Keyboard = (function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// --- Actions ---
|
// --- Actions ---
|
||||||
// Each action simulates what a user would do in OWA to perform the operation.
|
|
||||||
// We click the message to select it in OWA, then trigger the toolbar action.
|
|
||||||
|
|
||||||
function performAction(targets, actionFn) {
|
function performAction(targets, actionFn) {
|
||||||
if (targets.length === 0) return;
|
if (targets.length === 0) return;
|
||||||
|
|
||||||
// Process targets one at a time with a small delay between each
|
|
||||||
var i = 0;
|
var i = 0;
|
||||||
function processNext() {
|
function processNext() {
|
||||||
if (i >= targets.length) {
|
if (i >= targets.length) {
|
||||||
// After all targets processed, clear selection
|
|
||||||
clearSelection();
|
clearSelection();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var target = targets[i];
|
var target = targets[i];
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
// Click the message to make it OWA-selected
|
|
||||||
target.click();
|
target.click();
|
||||||
|
|
||||||
// Small delay to let OWA register the selection, then perform action
|
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
actionFn(target);
|
actionFn(target);
|
||||||
// Delay before next target
|
|
||||||
setTimeout(processNext, 150);
|
setTimeout(processNext, 150);
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
@@ -143,19 +189,14 @@ window.OutlookRelook.Keyboard = (function () {
|
|||||||
|
|
||||||
function actionDelete(targets) {
|
function actionDelete(targets) {
|
||||||
performAction(targets, function () {
|
performAction(targets, function () {
|
||||||
// Find and click the delete button in the toolbar
|
|
||||||
var deleteBtn = document.querySelector(
|
var deleteBtn = document.querySelector(
|
||||||
'[aria-label*="Delete" i][role="button"], [aria-label*="delete" i][role="menuitem"]'
|
'[aria-label*="Delete" i][role="button"], [aria-label*="delete" i][role="menuitem"]'
|
||||||
);
|
);
|
||||||
if (deleteBtn) {
|
if (deleteBtn) {
|
||||||
deleteBtn.click();
|
deleteBtn.click();
|
||||||
} else {
|
} else {
|
||||||
// Fallback: try dispatching Delete key
|
|
||||||
var deleteEvent = new KeyboardEvent('keydown', {
|
var deleteEvent = new KeyboardEvent('keydown', {
|
||||||
key: 'Delete',
|
key: 'Delete', code: 'Delete', bubbles: true, cancelable: true
|
||||||
code: 'Delete',
|
|
||||||
bubbles: true,
|
|
||||||
cancelable: true
|
|
||||||
});
|
});
|
||||||
document.activeElement.dispatchEvent(deleteEvent);
|
document.activeElement.dispatchEvent(deleteEvent);
|
||||||
}
|
}
|
||||||
@@ -183,7 +224,6 @@ window.OutlookRelook.Keyboard = (function () {
|
|||||||
if (readBtn) {
|
if (readBtn) {
|
||||||
readBtn.click();
|
readBtn.click();
|
||||||
} else {
|
} else {
|
||||||
// Try context menu approach
|
|
||||||
triggerContextMenuAction(/mark as read/i);
|
triggerContextMenuAction(/mark as read/i);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -203,11 +243,8 @@ window.OutlookRelook.Keyboard = (function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function actionMove(targets) {
|
function actionMove(targets) {
|
||||||
// For move, we just need to trigger OWA's move dialog on the current selection
|
|
||||||
if (targets.length > 0) {
|
if (targets.length > 0) {
|
||||||
// Click the first target to ensure something is selected
|
|
||||||
targets[0].click();
|
targets[0].click();
|
||||||
|
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
var moveBtn = document.querySelector(
|
var moveBtn = document.querySelector(
|
||||||
'[aria-label*="Move to" i][role="button"], [aria-label*="Move" i][role="menuitem"]'
|
'[aria-label*="Move to" i][role="button"], [aria-label*="Move" i][role="menuitem"]'
|
||||||
@@ -222,19 +259,14 @@ window.OutlookRelook.Keyboard = (function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function triggerContextMenuAction(pattern) {
|
function triggerContextMenuAction(pattern) {
|
||||||
// Open context menu on the focused/selected element
|
|
||||||
var focused = document.querySelector('.or-kb-focused');
|
var focused = document.querySelector('.or-kb-focused');
|
||||||
if (!focused) return;
|
if (!focused) return;
|
||||||
|
|
||||||
var rect = focused.getBoundingClientRect();
|
var rect = focused.getBoundingClientRect();
|
||||||
var contextEvent = new MouseEvent('contextmenu', {
|
var contextEvent = new MouseEvent('contextmenu', {
|
||||||
bubbles: true,
|
bubbles: true, cancelable: true,
|
||||||
cancelable: true,
|
clientX: rect.x + 10, clientY: rect.y + 10,
|
||||||
clientX: rect.x + 10,
|
|
||||||
clientY: rect.y + 10,
|
|
||||||
});
|
});
|
||||||
focused.dispatchEvent(contextEvent);
|
focused.dispatchEvent(contextEvent);
|
||||||
|
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
var menuItems = document.querySelectorAll('[role="menuitem"]');
|
var menuItems = document.querySelectorAll('[role="menuitem"]');
|
||||||
for (var j = 0; j < menuItems.length; j++) {
|
for (var j = 0; j < menuItems.length; j++) {
|
||||||
@@ -243,7 +275,6 @@ window.OutlookRelook.Keyboard = (function () {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Close context menu if not found
|
|
||||||
document.body.click();
|
document.body.click();
|
||||||
}, 300);
|
}, 300);
|
||||||
}
|
}
|
||||||
@@ -251,7 +282,6 @@ window.OutlookRelook.Keyboard = (function () {
|
|||||||
// --- Key handler ---
|
// --- Key handler ---
|
||||||
|
|
||||||
function handleKeydown(e) {
|
function handleKeydown(e) {
|
||||||
// Skip if keyboard mode is off or compose/dialog is active
|
|
||||||
if (!currentSettings.keyboardMultiSelect) return;
|
if (!currentSettings.keyboardMultiSelect) return;
|
||||||
if (isComposeOrDialogActive()) return;
|
if (isComposeOrDialogActive()) return;
|
||||||
|
|
||||||
@@ -262,15 +292,21 @@ window.OutlookRelook.Keyboard = (function () {
|
|||||||
var shift = e.shiftKey;
|
var shift = e.shiftKey;
|
||||||
|
|
||||||
// Initialize focus if not set
|
// Initialize focus if not set
|
||||||
if (focusedIndex < 0 || focusedIndex >= items.length) {
|
var currentIdx = getFocusedIndex(items);
|
||||||
// Find the currently OWA-selected item, or start at 0
|
if (currentIdx < 0) {
|
||||||
for (var f = 0; f < items.length; f++) {
|
for (var f = 0; f < items.length; f++) {
|
||||||
if (items[f].getAttribute('aria-selected') === 'true') {
|
if (items[f].getAttribute('aria-selected') === 'true' ||
|
||||||
focusedIndex = f;
|
items[f].classList.contains('is-selected')) {
|
||||||
|
currentIdx = f;
|
||||||
|
focusedId = getMessageId(items[f]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (focusedIndex < 0) focusedIndex = 0;
|
if (currentIdx < 0) {
|
||||||
|
currentIdx = 0;
|
||||||
|
focusedId = getMessageId(items[0]);
|
||||||
|
}
|
||||||
|
applyVisualState(items);
|
||||||
}
|
}
|
||||||
|
|
||||||
var handled = true;
|
var handled = true;
|
||||||
@@ -280,19 +316,14 @@ window.OutlookRelook.Keyboard = (function () {
|
|||||||
case 'j':
|
case 'j':
|
||||||
case 'ArrowDown':
|
case 'ArrowDown':
|
||||||
if (shift) {
|
if (shift) {
|
||||||
// Select current and move down
|
toggleSelect(items, currentIdx);
|
||||||
if (focusedIndex >= 0 && focusedIndex < items.length) {
|
if (currentIdx < items.length - 1) {
|
||||||
if (!selectedSet.has(items[focusedIndex])) {
|
setFocus(items, currentIdx + 1);
|
||||||
toggleSelect(items[focusedIndex]);
|
toggleSelect(items, currentIdx + 1);
|
||||||
}
|
|
||||||
}
|
|
||||||
if (focusedIndex < items.length - 1) {
|
|
||||||
setFocus(items, focusedIndex + 1);
|
|
||||||
toggleSelect(items[focusedIndex]);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (focusedIndex < items.length - 1) {
|
if (currentIdx < items.length - 1) {
|
||||||
setFocus(items, focusedIndex + 1);
|
setFocus(items, currentIdx + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -300,46 +331,35 @@ window.OutlookRelook.Keyboard = (function () {
|
|||||||
case 'k':
|
case 'k':
|
||||||
case 'ArrowUp':
|
case 'ArrowUp':
|
||||||
if (shift) {
|
if (shift) {
|
||||||
// Select current and move up
|
toggleSelect(items, currentIdx);
|
||||||
if (focusedIndex >= 0 && focusedIndex < items.length) {
|
if (currentIdx > 0) {
|
||||||
if (!selectedSet.has(items[focusedIndex])) {
|
setFocus(items, currentIdx - 1);
|
||||||
toggleSelect(items[focusedIndex]);
|
toggleSelect(items, currentIdx - 1);
|
||||||
}
|
|
||||||
}
|
|
||||||
if (focusedIndex > 0) {
|
|
||||||
setFocus(items, focusedIndex - 1);
|
|
||||||
toggleSelect(items[focusedIndex]);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (focusedIndex > 0) {
|
if (currentIdx > 0) {
|
||||||
setFocus(items, focusedIndex - 1);
|
setFocus(items, currentIdx - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'x':
|
case 'x':
|
||||||
case ' ':
|
case ' ':
|
||||||
// Toggle select on focused message
|
e.preventDefault();
|
||||||
e.preventDefault(); // Prevent page scroll on Space
|
toggleSelect(items, currentIdx);
|
||||||
if (focusedIndex >= 0 && focusedIndex < items.length) {
|
|
||||||
toggleSelect(items[focusedIndex]);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '#':
|
case '#':
|
||||||
// Delete selected/focused messages
|
|
||||||
targets = getActionTargets(items);
|
targets = getActionTargets(items);
|
||||||
actionDelete(targets);
|
actionDelete(targets);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'e':
|
case 'e':
|
||||||
// Archive selected/focused messages
|
|
||||||
targets = getActionTargets(items);
|
targets = getActionTargets(items);
|
||||||
actionArchive(targets);
|
actionArchive(targets);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'I':
|
case 'I':
|
||||||
// Shift+i — Mark as read
|
|
||||||
if (shift) {
|
if (shift) {
|
||||||
targets = getActionTargets(items);
|
targets = getActionTargets(items);
|
||||||
actionMarkRead(targets);
|
actionMarkRead(targets);
|
||||||
@@ -349,7 +369,6 @@ window.OutlookRelook.Keyboard = (function () {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'U':
|
case 'U':
|
||||||
// Shift+u — Mark as unread
|
|
||||||
if (shift) {
|
if (shift) {
|
||||||
targets = getActionTargets(items);
|
targets = getActionTargets(items);
|
||||||
actionMarkUnread(targets);
|
actionMarkUnread(targets);
|
||||||
@@ -359,21 +378,18 @@ window.OutlookRelook.Keyboard = (function () {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'v':
|
case 'v':
|
||||||
// Move selected messages
|
|
||||||
targets = getActionTargets(items);
|
targets = getActionTargets(items);
|
||||||
actionMove(targets);
|
actionMove(targets);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'Escape':
|
case 'Escape':
|
||||||
// Deselect all
|
|
||||||
clearSelection();
|
clearSelection();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'Enter':
|
case 'Enter':
|
||||||
case 'o':
|
case 'o':
|
||||||
// Open focused message in reading pane
|
if (currentIdx >= 0 && currentIdx < items.length) {
|
||||||
if (focusedIndex >= 0 && focusedIndex < items.length) {
|
items[currentIdx].click();
|
||||||
items[focusedIndex].click();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -383,33 +399,32 @@ window.OutlookRelook.Keyboard = (function () {
|
|||||||
|
|
||||||
if (handled) {
|
if (handled) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
// Only preventDefault for keys we handle (except Enter which OWA should also process)
|
|
||||||
if (key !== 'Enter' && key !== 'o') {
|
if (key !== 'Enter' && key !== 'o') {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Cleanup stale selections when message list re-renders ---
|
// --- Re-apply visual state when OWA re-renders the message list ---
|
||||||
|
|
||||||
function setupListObserver() {
|
function setupListObserver() {
|
||||||
var listObserver = new MutationObserver(function () {
|
var listObserver = new MutationObserver(function () {
|
||||||
// Remove stale entries from selectedSet (elements no longer in DOM)
|
// Prune IDs that no longer exist in DOM
|
||||||
selectedSet.forEach(function (item) {
|
var items = getMessageItems();
|
||||||
if (!document.contains(item)) {
|
var currentIds = new Set();
|
||||||
selectedSet.delete(item);
|
for (var i = 0; i < items.length; i++) {
|
||||||
}
|
var id = getMessageId(items[i]);
|
||||||
});
|
if (id) currentIds.add(id);
|
||||||
updateCountBadge();
|
|
||||||
|
|
||||||
// Reset focusedIndex if the focused item is gone
|
|
||||||
var focusedEl = document.querySelector('.or-kb-focused');
|
|
||||||
if (!focusedEl || !document.contains(focusedEl)) {
|
|
||||||
focusedIndex = -1;
|
|
||||||
}
|
}
|
||||||
|
selectedIds.forEach(function (id) {
|
||||||
|
if (!currentIds.has(id)) selectedIds.delete(id);
|
||||||
|
});
|
||||||
|
if (focusedId && !currentIds.has(focusedId)) focusedId = null;
|
||||||
|
|
||||||
|
// Re-apply classes to new DOM elements
|
||||||
|
applyVisualState(items);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Watch the message list container for child changes
|
|
||||||
var checkInterval = setInterval(function () {
|
var checkInterval = setInterval(function () {
|
||||||
var list = document.querySelector('[role="listbox"], [role="list"]');
|
var list = document.querySelector('[role="listbox"], [role="list"]');
|
||||||
if (list) {
|
if (list) {
|
||||||
@@ -444,7 +459,6 @@ window.OutlookRelook.Keyboard = (function () {
|
|||||||
var isEnabled = settings.keyboardMultiSelect;
|
var isEnabled = settings.keyboardMultiSelect;
|
||||||
currentSettings = settings;
|
currentSettings = settings;
|
||||||
|
|
||||||
// Only tear down and restart if the keyboard setting itself changed
|
|
||||||
if (wasEnabled !== isEnabled) {
|
if (wasEnabled !== isEnabled) {
|
||||||
stop();
|
stop();
|
||||||
start(settings);
|
start(settings);
|
||||||
@@ -457,11 +471,10 @@ window.OutlookRelook.Keyboard = (function () {
|
|||||||
}
|
}
|
||||||
cleanupFns = [];
|
cleanupFns = [];
|
||||||
|
|
||||||
// Clean up DOM state
|
|
||||||
clearSelection();
|
clearSelection();
|
||||||
var focused = document.querySelector('.or-kb-focused');
|
var focused = document.querySelector('.or-kb-focused');
|
||||||
if (focused) focused.classList.remove('or-kb-focused');
|
if (focused) focused.classList.remove('or-kb-focused');
|
||||||
focusedIndex = -1;
|
focusedId = null;
|
||||||
|
|
||||||
if (countBadge) {
|
if (countBadge) {
|
||||||
countBadge.remove();
|
countBadge.remove();
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
<select id="theme" data-setting="theme">
|
<select id="theme" data-setting="theme">
|
||||||
<option value="swiss">Swiss</option>
|
<option value="swiss">Swiss</option>
|
||||||
<option value="material">Material</option>
|
<option value="material">Material</option>
|
||||||
|
<option value="brutalist">Brutalist</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="or-radio-group" data-setting="colorScheme">
|
<div class="or-radio-group" data-setting="colorScheme">
|
||||||
|
|||||||
253
themes/brutalist.css
Normal file
253
themes/brutalist.css
Normal file
@@ -0,0 +1,253 @@
|
|||||||
|
/*
|
||||||
|
* Outlook Relook — Brutalist Theme
|
||||||
|
* Stark minimalism. Monospace. Borders only, almost no fills.
|
||||||
|
* High contrast. Maximum information density. No comfort.
|
||||||
|
* Inspired by terminal UIs, tax forms, and concrete architecture.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ============================================================
|
||||||
|
LIGHT VARIANT
|
||||||
|
============================================================ */
|
||||||
|
html[data-outlook-relook-scheme="light"] {
|
||||||
|
--or-bg-primary: #ffffff;
|
||||||
|
--or-bg-secondary: #ffffff;
|
||||||
|
--or-bg-tertiary: #ffffff;
|
||||||
|
--or-bg-hover: transparent;
|
||||||
|
--or-bg-selected: transparent;
|
||||||
|
--or-text-primary: #000000;
|
||||||
|
--or-text-secondary: #000000;
|
||||||
|
--or-text-tertiary: #555555;
|
||||||
|
--or-text-disabled: #999999;
|
||||||
|
--or-border: #000000;
|
||||||
|
--or-border-light: #000000;
|
||||||
|
--or-accent: var(--or-accent-override, #000000);
|
||||||
|
--or-accent-hover: var(--or-accent-override, #333333);
|
||||||
|
--or-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================================
|
||||||
|
DARK VARIANT
|
||||||
|
============================================================ */
|
||||||
|
html[data-outlook-relook-scheme="dark"] {
|
||||||
|
--or-bg-primary: #000000;
|
||||||
|
--or-bg-secondary: #000000;
|
||||||
|
--or-bg-tertiary: #000000;
|
||||||
|
--or-bg-hover: transparent;
|
||||||
|
--or-bg-selected: transparent;
|
||||||
|
--or-text-primary: #ffffff;
|
||||||
|
--or-text-secondary: #ffffff;
|
||||||
|
--or-text-tertiary: #aaaaaa;
|
||||||
|
--or-text-disabled: #555555;
|
||||||
|
--or-border: #ffffff;
|
||||||
|
--or-border-light: #ffffff;
|
||||||
|
--or-accent: var(--or-accent-override, #ffffff);
|
||||||
|
--or-accent-hover: var(--or-accent-override, #cccccc);
|
||||||
|
--or-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================================
|
||||||
|
TYPOGRAPHY — Monospace, tight, utilitarian
|
||||||
|
============================================================ */
|
||||||
|
html[data-outlook-relook-scheme] *,
|
||||||
|
html[data-outlook-relook-scheme] *::before,
|
||||||
|
html[data-outlook-relook-scheme] *::after {
|
||||||
|
font-family: 'SF Mono', 'Menlo', 'Monaco', 'Consolas', 'Liberation Mono', monospace !important;
|
||||||
|
letter-spacing: -0.03em !important;
|
||||||
|
-webkit-font-smoothing: none !important;
|
||||||
|
font-smooth: never !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-outlook-relook-scheme] body {
|
||||||
|
font-size: 12px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================================
|
||||||
|
STRIP EVERYTHING — more aggressive than Swiss
|
||||||
|
============================================================ */
|
||||||
|
html[data-outlook-relook-scheme] * {
|
||||||
|
border-radius: 0 !important;
|
||||||
|
text-shadow: none !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
background-image: none !important;
|
||||||
|
transition: none !important;
|
||||||
|
animation: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================================
|
||||||
|
SURFACES — pure white/black, no distinction between panes
|
||||||
|
============================================================ */
|
||||||
|
html[data-outlook-relook-scheme] body {
|
||||||
|
background-color: var(--or-bg-primary) !important;
|
||||||
|
color: var(--or-text-primary) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Top bar — just a bottom border */
|
||||||
|
html[data-outlook-relook-scheme] [role="banner"],
|
||||||
|
html[data-outlook-relook-scheme] header {
|
||||||
|
background-color: var(--or-bg-primary) !important;
|
||||||
|
border-bottom: 2px solid var(--or-border) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Folder pane — border only, no background change */
|
||||||
|
html[data-outlook-relook-scheme] [role="navigation"],
|
||||||
|
html[data-outlook-relook-scheme] [role="complementary"] {
|
||||||
|
background-color: var(--or-bg-primary) !important;
|
||||||
|
border-right: 2px solid var(--or-border) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Message list — no background */
|
||||||
|
html[data-outlook-relook-scheme] [role="listbox"],
|
||||||
|
html[data-outlook-relook-scheme] [role="list"] {
|
||||||
|
background-color: var(--or-bg-primary) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Message list items — borders only, no fills */
|
||||||
|
html[data-outlook-relook-scheme] [role="option"],
|
||||||
|
html[data-outlook-relook-scheme] [role="listitem"] {
|
||||||
|
background-color: transparent !important;
|
||||||
|
border-bottom: 1px solid var(--or-border) !important;
|
||||||
|
color: var(--or-text-primary) !important;
|
||||||
|
padding: 3px 8px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hover: invert colors instead of fill */
|
||||||
|
html[data-outlook-relook-scheme="light"] [role="option"]:hover,
|
||||||
|
html[data-outlook-relook-scheme="light"] [role="listitem"]:hover {
|
||||||
|
background-color: #000000 !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-outlook-relook-scheme="dark"] [role="option"]:hover,
|
||||||
|
html[data-outlook-relook-scheme="dark"] [role="listitem"]:hover {
|
||||||
|
background-color: #ffffff !important;
|
||||||
|
color: #000000 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Selected: invert */
|
||||||
|
html[data-outlook-relook-scheme="light"] [role="option"][aria-selected="true"],
|
||||||
|
html[data-outlook-relook-scheme="light"] [role="listitem"][aria-selected="true"] {
|
||||||
|
background-color: #000000 !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-outlook-relook-scheme="dark"] [role="option"][aria-selected="true"],
|
||||||
|
html[data-outlook-relook-scheme="dark"] [role="listitem"][aria-selected="true"] {
|
||||||
|
background-color: #ffffff !important;
|
||||||
|
color: #000000 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reading pane */
|
||||||
|
html[data-outlook-relook-scheme] [role="main"] {
|
||||||
|
background-color: var(--or-bg-primary) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================================
|
||||||
|
TOOLBAR — stark, no visual weight
|
||||||
|
============================================================ */
|
||||||
|
html[data-outlook-relook-scheme] [role="toolbar"] {
|
||||||
|
background-color: var(--or-bg-primary) !important;
|
||||||
|
border-bottom: 1px solid var(--or-border) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-outlook-relook-scheme] [role="toolbar"] button,
|
||||||
|
html[data-outlook-relook-scheme] [role="toolbar"] [role="button"] {
|
||||||
|
background-color: transparent !important;
|
||||||
|
border: 1px solid transparent !important;
|
||||||
|
color: var(--or-text-primary) !important;
|
||||||
|
text-transform: uppercase !important;
|
||||||
|
font-size: 10px !important;
|
||||||
|
letter-spacing: 0.05em !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-outlook-relook-scheme] [role="toolbar"] button:hover,
|
||||||
|
html[data-outlook-relook-scheme] [role="toolbar"] [role="button"]:hover {
|
||||||
|
border-color: var(--or-border) !important;
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================================
|
||||||
|
BUTTONS — outlined only, never filled
|
||||||
|
============================================================ */
|
||||||
|
html[data-outlook-relook-scheme] button,
|
||||||
|
html[data-outlook-relook-scheme] [role="button"] {
|
||||||
|
background-color: transparent !important;
|
||||||
|
color: var(--or-text-primary) !important;
|
||||||
|
border: 1px solid transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-outlook-relook-scheme] button:hover,
|
||||||
|
html[data-outlook-relook-scheme] [role="button"]:hover {
|
||||||
|
border-color: var(--or-border) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Links: same color as text, underlined */
|
||||||
|
html[data-outlook-relook-scheme] a {
|
||||||
|
color: var(--or-text-primary) !important;
|
||||||
|
text-decoration: underline !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-outlook-relook-scheme] a:hover {
|
||||||
|
text-decoration: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================================
|
||||||
|
FOLDER PANE — all caps, no fills
|
||||||
|
============================================================ */
|
||||||
|
html[data-outlook-relook-scheme] [role="treeitem"] {
|
||||||
|
color: var(--or-text-primary) !important;
|
||||||
|
background-color: transparent !important;
|
||||||
|
text-transform: uppercase !important;
|
||||||
|
font-size: 10px !important;
|
||||||
|
letter-spacing: 0.06em !important;
|
||||||
|
border-bottom: 1px solid var(--or-border-light) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-outlook-relook-scheme] [role="treeitem"]:hover {
|
||||||
|
text-decoration: underline !important;
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-outlook-relook-scheme] [role="treeitem"][aria-selected="true"] {
|
||||||
|
font-weight: 900 !important;
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================================
|
||||||
|
SECONDARY TEXT
|
||||||
|
============================================================ */
|
||||||
|
html[data-outlook-relook-scheme] [role="option"] span,
|
||||||
|
html[data-outlook-relook-scheme] [role="listitem"] span {
|
||||||
|
color: var(--or-text-tertiary) !important;
|
||||||
|
font-size: 11px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-outlook-relook-scheme] time {
|
||||||
|
color: var(--or-text-tertiary) !important;
|
||||||
|
font-size: 10px !important;
|
||||||
|
text-transform: uppercase !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================================
|
||||||
|
DIALOGS — bordered box, no fill
|
||||||
|
============================================================ */
|
||||||
|
html[data-outlook-relook-scheme] [role="dialog"],
|
||||||
|
html[data-outlook-relook-scheme] [role="alertdialog"] {
|
||||||
|
background-color: var(--or-bg-primary) !important;
|
||||||
|
border: 2px solid var(--or-border) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================================
|
||||||
|
SCROLLBARS — hairline
|
||||||
|
============================================================ */
|
||||||
|
html[data-outlook-relook-scheme] ::-webkit-scrollbar {
|
||||||
|
width: 2px !important;
|
||||||
|
height: 2px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-outlook-relook-scheme] ::-webkit-scrollbar-track {
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-outlook-relook-scheme] ::-webkit-scrollbar-thumb {
|
||||||
|
background: var(--or-text-primary) !important;
|
||||||
|
}
|
||||||
192
themes/swiss.css
192
themes/swiss.css
@@ -1,6 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* Outlook Relook — Swiss / Helvetica Theme
|
* Outlook Relook — Swiss / Helvetica Theme
|
||||||
* Monochrome, tight grid, no decoration. Content density is king.
|
* Ruthlessly minimal. Black, white, grey, accent. Nothing else.
|
||||||
|
* Helvetica Neue everywhere. Zero decoration. Grid discipline.
|
||||||
|
* If an element doesn't serve the content, it should be invisible.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* ============================================================
|
/* ============================================================
|
||||||
@@ -8,18 +10,18 @@
|
|||||||
============================================================ */
|
============================================================ */
|
||||||
html[data-outlook-relook-scheme="light"] {
|
html[data-outlook-relook-scheme="light"] {
|
||||||
--or-bg-primary: #ffffff;
|
--or-bg-primary: #ffffff;
|
||||||
--or-bg-secondary: #fafafa;
|
--or-bg-secondary: #ffffff;
|
||||||
--or-bg-tertiary: #f0f0f0;
|
--or-bg-tertiary: #f7f7f7;
|
||||||
--or-bg-hover: #e8e8e8;
|
--or-bg-hover: #f0f0f0;
|
||||||
--or-bg-selected: #e0e0e0;
|
--or-bg-selected: #f0f0f0;
|
||||||
--or-text-primary: #000000;
|
--or-text-primary: #000000;
|
||||||
--or-text-secondary: #333333;
|
--or-text-secondary: #555555;
|
||||||
--or-text-tertiary: #666666;
|
--or-text-tertiary: #888888;
|
||||||
--or-text-disabled: #999999;
|
--or-text-disabled: #bbbbbb;
|
||||||
--or-border: #d0d0d0;
|
--or-border: #000000;
|
||||||
--or-border-light: #e5e5e5;
|
--or-border-light: #e0e0e0;
|
||||||
--or-accent: var(--or-accent-override, #000000);
|
--or-accent: var(--or-accent-override, #ff0000);
|
||||||
--or-accent-hover: var(--or-accent-override, #333333);
|
--or-accent-hover: var(--or-accent-override, #cc0000);
|
||||||
--or-shadow: none;
|
--or-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,71 +29,86 @@ html[data-outlook-relook-scheme="light"] {
|
|||||||
DARK VARIANT
|
DARK VARIANT
|
||||||
============================================================ */
|
============================================================ */
|
||||||
html[data-outlook-relook-scheme="dark"] {
|
html[data-outlook-relook-scheme="dark"] {
|
||||||
--or-bg-primary: #1a1a1a;
|
--or-bg-primary: #0a0a0a;
|
||||||
--or-bg-secondary: #222222;
|
--or-bg-secondary: #0a0a0a;
|
||||||
--or-bg-tertiary: #2a2a2a;
|
--or-bg-tertiary: #141414;
|
||||||
--or-bg-hover: #333333;
|
--or-bg-hover: #1a1a1a;
|
||||||
--or-bg-selected: #3a3a3a;
|
--or-bg-selected: #1a1a1a;
|
||||||
--or-text-primary: #e8e8e8;
|
--or-text-primary: #ffffff;
|
||||||
--or-text-secondary: #cccccc;
|
--or-text-secondary: #aaaaaa;
|
||||||
--or-text-tertiary: #999999;
|
--or-text-tertiary: #666666;
|
||||||
--or-text-disabled: #666666;
|
--or-text-disabled: #444444;
|
||||||
--or-border: #3a3a3a;
|
--or-border: #ffffff;
|
||||||
--or-border-light: #2f2f2f;
|
--or-border-light: #222222;
|
||||||
--or-accent: var(--or-accent-override, #e8e8e8);
|
--or-accent: var(--or-accent-override, #ff3333);
|
||||||
--or-accent-hover: var(--or-accent-override, #ffffff);
|
--or-accent-hover: var(--or-accent-override, #ff6666);
|
||||||
--or-shadow: none;
|
--or-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================
|
/* ============================================================
|
||||||
TYPOGRAPHY
|
TYPOGRAPHY — Helvetica Neue, aggressively applied
|
||||||
============================================================ */
|
============================================================ */
|
||||||
html[data-outlook-relook-scheme] body,
|
html[data-outlook-relook-scheme] *,
|
||||||
html[data-outlook-relook-scheme] [role="main"],
|
html[data-outlook-relook-scheme] *::before,
|
||||||
html[data-outlook-relook-scheme] [role="navigation"],
|
html[data-outlook-relook-scheme] *::after {
|
||||||
html[data-outlook-relook-scheme] [role="complementary"],
|
|
||||||
html[data-outlook-relook-scheme] [role="banner"],
|
|
||||||
html[data-outlook-relook-scheme] input,
|
|
||||||
html[data-outlook-relook-scheme] button,
|
|
||||||
html[data-outlook-relook-scheme] select,
|
|
||||||
html[data-outlook-relook-scheme] textarea {
|
|
||||||
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif !important;
|
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif !important;
|
||||||
letter-spacing: -0.01em !important;
|
letter-spacing: -0.02em !important;
|
||||||
|
-webkit-font-smoothing: antialiased !important;
|
||||||
|
-moz-osx-font-smoothing: grayscale !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================
|
/* ============================================================
|
||||||
SURFACES & BACKGROUNDS
|
STRIP ALL DECORATION — the core Swiss principle
|
||||||
|
============================================================ */
|
||||||
|
html[data-outlook-relook-scheme] * {
|
||||||
|
border-radius: 0 !important;
|
||||||
|
text-shadow: none !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
background-image: none !important;
|
||||||
|
text-decoration-color: var(--or-text-primary) !important;
|
||||||
|
outline-color: var(--or-accent) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove ALL gradients, transitions, and transforms from non-essential elements */
|
||||||
|
html[data-outlook-relook-scheme] button,
|
||||||
|
html[data-outlook-relook-scheme] [role="button"],
|
||||||
|
html[data-outlook-relook-scheme] [role="tab"],
|
||||||
|
html[data-outlook-relook-scheme] [role="menuitem"],
|
||||||
|
html[data-outlook-relook-scheme] [role="option"],
|
||||||
|
html[data-outlook-relook-scheme] [role="listitem"],
|
||||||
|
html[data-outlook-relook-scheme] [role="treeitem"] {
|
||||||
|
transition: none !important;
|
||||||
|
animation: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================================
|
||||||
|
SURFACES — flatten everything to white (or black in dark)
|
||||||
============================================================ */
|
============================================================ */
|
||||||
html[data-outlook-relook-scheme] body {
|
html[data-outlook-relook-scheme] body {
|
||||||
background-color: var(--or-bg-primary) !important;
|
background-color: var(--or-bg-primary) !important;
|
||||||
color: var(--or-text-primary) !important;
|
color: var(--or-text-primary) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Top bar */
|
|
||||||
html[data-outlook-relook-scheme] [role="banner"],
|
html[data-outlook-relook-scheme] [role="banner"],
|
||||||
html[data-outlook-relook-scheme] header {
|
html[data-outlook-relook-scheme] header {
|
||||||
background-color: var(--or-bg-primary) !important;
|
background-color: var(--or-bg-primary) !important;
|
||||||
border-bottom: 1px solid var(--or-border) !important;
|
border-bottom: 1px solid var(--or-border) !important;
|
||||||
box-shadow: var(--or-shadow) !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Folder pane */
|
|
||||||
html[data-outlook-relook-scheme] [role="navigation"],
|
html[data-outlook-relook-scheme] [role="navigation"],
|
||||||
html[data-outlook-relook-scheme] [role="complementary"] {
|
html[data-outlook-relook-scheme] [role="complementary"] {
|
||||||
background-color: var(--or-bg-secondary) !important;
|
background-color: var(--or-bg-primary) !important;
|
||||||
border-right: 1px solid var(--or-border-light) !important;
|
border-right: 1px solid var(--or-border-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Message list */
|
|
||||||
html[data-outlook-relook-scheme] [role="listbox"],
|
html[data-outlook-relook-scheme] [role="listbox"],
|
||||||
html[data-outlook-relook-scheme] [role="list"] {
|
html[data-outlook-relook-scheme] [role="list"] {
|
||||||
background-color: var(--or-bg-primary) !important;
|
background-color: var(--or-bg-primary) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Message list items */
|
|
||||||
html[data-outlook-relook-scheme] [role="option"],
|
html[data-outlook-relook-scheme] [role="option"],
|
||||||
html[data-outlook-relook-scheme] [role="listitem"] {
|
html[data-outlook-relook-scheme] [role="listitem"] {
|
||||||
background-color: var(--or-bg-primary) !important;
|
background-color: transparent !important;
|
||||||
border-bottom: 1px solid var(--or-border-light) !important;
|
border-bottom: 1px solid var(--or-border-light) !important;
|
||||||
color: var(--or-text-primary) !important;
|
color: var(--or-text-primary) !important;
|
||||||
}
|
}
|
||||||
@@ -104,74 +121,81 @@ html[data-outlook-relook-scheme] [role="listitem"]:hover {
|
|||||||
html[data-outlook-relook-scheme] [role="option"][aria-selected="true"],
|
html[data-outlook-relook-scheme] [role="option"][aria-selected="true"],
|
||||||
html[data-outlook-relook-scheme] [role="listitem"][aria-selected="true"] {
|
html[data-outlook-relook-scheme] [role="listitem"][aria-selected="true"] {
|
||||||
background-color: var(--or-bg-selected) !important;
|
background-color: var(--or-bg-selected) !important;
|
||||||
|
border-left: 3px solid var(--or-accent) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reading pane */
|
|
||||||
html[data-outlook-relook-scheme] [role="main"] {
|
html[data-outlook-relook-scheme] [role="main"] {
|
||||||
background-color: var(--or-bg-primary) !important;
|
background-color: var(--or-bg-primary) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================
|
/* ============================================================
|
||||||
DECORATIVE REMOVAL
|
TOOLBAR — minimal, no background distinction
|
||||||
============================================================ */
|
============================================================ */
|
||||||
html[data-outlook-relook-scheme] * {
|
html[data-outlook-relook-scheme] [role="toolbar"] {
|
||||||
border-radius: 0 !important;
|
background-color: var(--or-bg-primary) !important;
|
||||||
text-shadow: none !important;
|
border-bottom: 1px solid var(--or-border-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
html[data-outlook-relook-scheme] button,
|
/* Toolbar buttons: text only, no background */
|
||||||
html[data-outlook-relook-scheme] [role="button"],
|
html[data-outlook-relook-scheme] [role="toolbar"] button,
|
||||||
html[data-outlook-relook-scheme] [role="tab"],
|
html[data-outlook-relook-scheme] [role="toolbar"] [role="button"] {
|
||||||
html[data-outlook-relook-scheme] [role="menuitem"] {
|
background-color: transparent !important;
|
||||||
box-shadow: none !important;
|
border: none !important;
|
||||||
background-image: none !important;
|
color: var(--or-text-primary) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-outlook-relook-scheme] [role="toolbar"] button:hover,
|
||||||
|
html[data-outlook-relook-scheme] [role="toolbar"] [role="button"]:hover {
|
||||||
|
background-color: var(--or-bg-hover) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================
|
/* ============================================================
|
||||||
BUTTONS & INTERACTIVE
|
BUTTONS — understate everything
|
||||||
============================================================ */
|
============================================================ */
|
||||||
|
html[data-outlook-relook-scheme] button,
|
||||||
|
html[data-outlook-relook-scheme] [role="button"] {
|
||||||
|
background-color: transparent !important;
|
||||||
|
color: var(--or-text-primary) !important;
|
||||||
|
}
|
||||||
|
|
||||||
html[data-outlook-relook-scheme] button:hover,
|
html[data-outlook-relook-scheme] button:hover,
|
||||||
html[data-outlook-relook-scheme] [role="button"]:hover {
|
html[data-outlook-relook-scheme] [role="button"]:hover {
|
||||||
background-color: var(--or-bg-hover) !important;
|
background-color: var(--or-bg-hover) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Links: accent color, no underline by default */
|
||||||
html[data-outlook-relook-scheme] a {
|
html[data-outlook-relook-scheme] a {
|
||||||
color: var(--or-accent) !important;
|
color: var(--or-accent) !important;
|
||||||
|
text-decoration: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
html[data-outlook-relook-scheme] a:hover {
|
html[data-outlook-relook-scheme] a:hover {
|
||||||
|
text-decoration: underline !important;
|
||||||
color: var(--or-accent-hover) !important;
|
color: var(--or-accent-hover) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================
|
/* ============================================================
|
||||||
TOOLBAR / COMMAND BAR
|
FOLDER PANE — text hierarchy only, no visual chrome
|
||||||
============================================================ */
|
|
||||||
html[data-outlook-relook-scheme] [role="toolbar"] {
|
|
||||||
background-color: var(--or-bg-primary) !important;
|
|
||||||
border-bottom: 1px solid var(--or-border-light) !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================================
|
|
||||||
FOLDER PANE TREE ITEMS
|
|
||||||
============================================================ */
|
============================================================ */
|
||||||
html[data-outlook-relook-scheme] [role="treeitem"] {
|
html[data-outlook-relook-scheme] [role="treeitem"] {
|
||||||
color: var(--or-text-secondary) !important;
|
color: var(--or-text-secondary) !important;
|
||||||
|
background-color: transparent !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
html[data-outlook-relook-scheme] [role="treeitem"]:hover {
|
html[data-outlook-relook-scheme] [role="treeitem"]:hover {
|
||||||
background-color: var(--or-bg-hover) !important;
|
|
||||||
color: var(--or-text-primary) !important;
|
color: var(--or-text-primary) !important;
|
||||||
|
background-color: transparent !important;
|
||||||
|
text-decoration: underline !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
html[data-outlook-relook-scheme] [role="treeitem"][aria-selected="true"] {
|
html[data-outlook-relook-scheme] [role="treeitem"][aria-selected="true"] {
|
||||||
background-color: var(--or-bg-selected) !important;
|
|
||||||
color: var(--or-text-primary) !important;
|
color: var(--or-text-primary) !important;
|
||||||
font-weight: 600 !important;
|
font-weight: 700 !important;
|
||||||
|
background-color: transparent !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================
|
/* ============================================================
|
||||||
SECONDARY TEXT
|
SECONDARY TEXT — clear hierarchy
|
||||||
============================================================ */
|
============================================================ */
|
||||||
html[data-outlook-relook-scheme] [role="option"] span,
|
html[data-outlook-relook-scheme] [role="option"] span,
|
||||||
html[data-outlook-relook-scheme] [role="listitem"] span {
|
html[data-outlook-relook-scheme] [role="listitem"] span {
|
||||||
@@ -180,4 +204,32 @@ html[data-outlook-relook-scheme] [role="listitem"] span {
|
|||||||
|
|
||||||
html[data-outlook-relook-scheme] time {
|
html[data-outlook-relook-scheme] time {
|
||||||
color: var(--or-text-tertiary) !important;
|
color: var(--or-text-tertiary) !important;
|
||||||
|
font-size: 11px !important;
|
||||||
|
text-transform: uppercase !important;
|
||||||
|
letter-spacing: 0.03em !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================================
|
||||||
|
DIALOGS & OVERLAYS
|
||||||
|
============================================================ */
|
||||||
|
html[data-outlook-relook-scheme] [role="dialog"],
|
||||||
|
html[data-outlook-relook-scheme] [role="alertdialog"] {
|
||||||
|
background-color: var(--or-bg-primary) !important;
|
||||||
|
border: 1px solid var(--or-border) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================================
|
||||||
|
SCROLLBARS — thin, monochrome
|
||||||
|
============================================================ */
|
||||||
|
html[data-outlook-relook-scheme] ::-webkit-scrollbar {
|
||||||
|
width: 4px !important;
|
||||||
|
height: 4px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-outlook-relook-scheme] ::-webkit-scrollbar-track {
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-outlook-relook-scheme] ::-webkit-scrollbar-thumb {
|
||||||
|
background: var(--or-text-tertiary) !important;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user