Dynamic Theme Detector
Relevant source files
The following files were used as context for generating this wiki page:
The Dynamic Theme Detector identifies the visual state of the host web page to ensure UI components maintain high contrast and legibility. It detects system-level preferences and page-level dark mode settings to adjust the appearance of highlights, underlines, and margin notes. By adapting colors dynamically, the system prevents accessibility issues where dark highlights might overlap with dark text or vice versa.
This module works in conjunction with the Annotation Engine to render localized UI elements like manual annotation editors and margin cards that match the host site's aesthetic.
Sources: CHANGELOG.md:19-24, README.md:275-276, extension/src/content/manual.ts:12-50
Architecture and Logic
The theme detection logic primarily resides in theme-detector.ts and styles.ts. It analyzes the computed styles of the document.body and document.documentElement to determine if a site is in "dark" or "light" mode.
Detection Workflow
The system evaluates the background color of the page. If the background brightness falls below a specific threshold, the detector classifies the theme as dark.
The detector uses the getThemeMode() function to return a string literal of either 'light' or 'dark'. This value informs the color selection for all rendered overlays.
Sources: extension/src/content/renderer/theme-detector.ts, extension/src/content/manual.ts:13
Visual Adaptation Layers
The Dynamic Theme Detector influences multiple UI layers within the extension, ensuring consistent contrast across different site styles.
Annotation Visuals
The getVisual(type) function in styles.ts retrieves specific styling properties based on the current theme. For example, annotation colors are automatically adjusted for contrast, using lighter highlights on dark backgrounds and inverted text colors when necessary.
| Property | Description | Source |
|---|---|---|
backgroundColor | Adjusts alpha and brightness for highlights | styles.ts |
underlineStyle | Changes solid/dotted/wavy styles based on type | styles.ts |
labelColor | High-contrast color for annotation tags | manual.ts |
Sources: extension/src/content/renderer/styles.ts, CHANGELOG.md:20-22, extension/src/content/manual.ts:15-50
Manual Annotation Editor
When a user creates a manual annotation, the editor UI adapts its color palette using predefined theme maps.
// extension/src/content/manual.ts:28-50
const DARK_COLORS = {
cardBg: 'rgba(18,18,18,0.55)',
cardBorder: 'rgba(255,255,255,0.08)',
cardText: '#f0f0f0',
inputBg: 'rgba(255,255,255,0.07)',
labelColor: '#f0f0f0',
};
const LIGHT_COLORS = {
cardBg: 'rgba(255,255,255,0.35)',
cardText: '#111111',
inputBg: 'rgba(255,255,255,0.5)',
labelColor: '#111111',
};
Sources: extension/src/content/manual.ts:28-50
Integration with PDF Export
The theme detection state is partially overridden during PDF export. Since PDF documents are typically printed on white paper, the handleExportPdf function enforces a light-mode logic for annotation colors to ensure print quality, regardless of the user's current browser theme.
Implementation Details
The core function getAccent() in manual.ts demonstrates how the theme detector is called to retrieve the correct visual accent for user-generated content.
// extension/src/content/manual.ts:12-14
function getAccent(): string {
return getAnnotationColor('user_written', getThemeMode());
}
This ensures that the "user_written" annotation type, used for manual notes, always respects the visual constraints of the detected theme.
Sources: extension/src/content/manual.ts:12-14, extension/src/content/renderer/styles.ts
The Dynamic Theme Detector provides a critical accessibility layer by bridging the gap between static extension UI and the diverse visual landscapes of the modern web. By programmatically analyzing brightness and applying conditional styling maps, it maintains the legibility of Oddity 1's analytical overlays across millions of unique host pages.