diff --git a/build-safari.sh b/build-safari.sh new file mode 100755 index 0000000..9ffaf78 --- /dev/null +++ b/build-safari.sh @@ -0,0 +1,66 @@ +#!/bin/bash +# +# Convert Silent Send for Safari using Apple's safari-web-extension-converter. +# +# Prerequisites: +# - macOS with Xcode installed (free from Mac App Store) +# - Apple Developer account ($99/year) for App Store distribution +# - Xcode Command Line Tools: xcode-select --install +# +# This script: +# 1. Builds the Firefox variant (Safari uses browser.* API like Firefox) +# 2. Runs safari-web-extension-converter to generate an Xcode project +# 3. The Xcode project can then be built, tested, and submitted to App Store +# + +set -e + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +OUT_DIR="$SCRIPT_DIR/safari-build" + +# Check for Xcode +if ! command -v xcrun &> /dev/null; then + echo "Error: Xcode is required. Install from the Mac App Store." + echo "Then run: xcode-select --install" + exit 1 +fi + +if ! xcrun --find safari-web-extension-converter &> /dev/null; then + echo "Error: safari-web-extension-converter not found." + echo "Make sure Xcode is installed and up to date." + exit 1 +fi + +# Build the Firefox variant (Safari uses browser.* API) +echo "Building extension..." +"$SCRIPT_DIR/build.sh" firefox + +echo "" +echo "Converting for Safari..." + +# Remove previous build +rm -rf "$OUT_DIR" + +# Convert — generates an Xcode project +xcrun safari-web-extension-converter \ + "$SCRIPT_DIR/dist/firefox" \ + --project-location "$OUT_DIR" \ + --app-name "Silent Send" \ + --bundle-identifier "com.silentsend.extension" \ + --swift \ + --macos-only \ + --no-open + +echo "" +echo "Safari project created at: $OUT_DIR" +echo "" +echo "Next steps:" +echo " 1. Open $OUT_DIR/Silent Send.xcodeproj in Xcode" +echo " 2. Select your Apple Developer Team in Signing & Capabilities" +echo " 3. Build and run (Cmd+R) to test in Safari" +echo " 4. To distribute: Product → Archive → Distribute App" +echo "" +echo "For App Store submission, you'll also need:" +echo " - App Store screenshots (1280x800 for Mac)" +echo " - Privacy policy URL" +echo " - App description and keywords" diff --git a/manifest.firefox.json b/manifest.firefox.json index 27d0ca1..f0c056e 100644 --- a/manifest.firefox.json +++ b/manifest.firefox.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "Silent Send", - "version": "2.0.3", + "version": "2.0.5", "description": "Intercepts personal info and substitutes it with user-defined replacements before sending to AI services.", "browser_specific_settings": { "gecko": { diff --git a/manifest.json b/manifest.json index 034e60e..ad9d1fa 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "Silent Send", - "version": "2.0.3", + "version": "2.0.5", "description": "Intercepts personal info and substitutes it with user-defined replacements before sending to AI services.", "permissions": [ "storage", diff --git a/package.json b/package.json index a203aae..e33f7f7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "silent-send", - "version": "2.0.3", + "version": "2.0.5", "private": true, "license": "BSL-1.1", "description": "Browser extension that substitutes personal data before sending to AI services", diff --git a/src/content/content.js b/src/content/content.js index 10fa4a7..47fd4e5 100644 --- a/src/content/content.js +++ b/src/content/content.js @@ -14,7 +14,8 @@ function safeHTML(el, html) { const template = document.createElement('template'); template.innerHTML = html; - el.replaceChildren(...template.content.childNodes); + // Convert to static array — childNodes is live and shrinks as nodes move + el.replaceChildren(...Array.from(template.content.childNodes)); } // ============================================================ @@ -181,6 +182,32 @@ replacements.push({ original: matched, replaced: sub, category: 'name', pattern: 'smart' }); return sub; }); + // Concatenated forms: JohnSmith, johnsmith, john.smith, john_smith, john-smith + // Also reversed: SmithJohn, smithjohn, smith.john, etc. + const f = first.real, l = last.real; + const fs = first.substitute, ls = last.substitute; + const concatPatterns = [ + // first+last + [f + l, fs + ls], + [f + '.' + l, fs + '.' + ls], + [f + '_' + l, fs + '_' + ls], + [f + '-' + l, fs + '-' + ls], + // last+first + [l + f, ls + fs], + [l + '.' + f, ls + '.' + fs], + [l + '_' + f, ls + '_' + fs], + [l + '-' + f, ls + '-' + fs], + ]; + for (const [real, sub] of concatPatterns) { + result = result.replace(new RegExp('\\b' + esc(real) + '\\b', 'gi'), (matched) => { + // Preserve case: all-lower→lower, ALL-UPPER→upper, else use sub as-is + let replacement = sub; + if (matched === matched.toLowerCase()) replacement = sub.toLowerCase(); + else if (matched === matched.toUpperCase()) replacement = sub.toUpperCase(); + replacements.push({ original: matched, replaced: replacement, category: 'name', pattern: 'smart-concat' }); + return replacement; + }); + } } } @@ -355,17 +382,26 @@ // Common English words that are capitalized but aren't proper nouns. // Used by the proper noun heuristic to reduce false positives. + // Includes common verbs, nouns, adjectives that appear in titles, + // headings, UI buttons, and instructions. const COMMON_CAPITALIZED = new Set([ + // Prepositions, conjunctions, articles, pronouns 'the', 'a', 'an', 'and', 'or', 'but', 'if', 'then', 'else', 'when', 'at', 'by', 'for', 'with', 'about', 'against', 'between', 'through', 'during', 'before', 'after', 'above', 'below', 'to', 'from', 'up', 'down', 'in', 'out', 'on', 'off', 'over', 'under', 'again', 'further', - 'then', 'once', 'here', 'there', 'all', 'each', 'every', 'both', + 'once', 'here', 'there', 'all', 'each', 'every', 'both', 'few', 'more', 'most', 'other', 'some', 'such', 'no', 'nor', 'not', 'only', 'own', 'same', 'so', 'than', 'too', 'very', 'can', 'will', 'just', 'should', 'now', 'also', 'into', 'could', 'would', 'may', 'might', 'shall', 'must', 'need', 'have', 'has', 'had', 'do', 'does', 'did', 'be', 'is', 'am', 'are', 'was', 'were', 'been', 'being', + 'i', 'you', 'he', 'she', 'it', 'we', 'they', 'me', 'him', 'her', + 'us', 'them', 'my', 'your', 'his', 'its', 'our', 'their', + 'this', 'that', 'these', 'those', 'what', 'who', 'how', 'why', + 'which', 'where', 'when', 'while', 'since', 'because', 'although', + 'however', 'therefore', 'moreover', 'furthermore', 'nevertheless', + // Common verbs (appear in titles, headings, buttons, instructions) 'get', 'got', 'make', 'made', 'go', 'went', 'gone', 'take', 'took', 'come', 'came', 'see', 'saw', 'know', 'knew', 'think', 'thought', 'say', 'said', 'tell', 'told', 'give', 'gave', 'find', 'found', @@ -378,25 +414,110 @@ 'buy', 'wait', 'serve', 'die', 'send', 'expect', 'build', 'stay', 'fall', 'cut', 'reach', 'kill', 'remain', 'suggest', 'raise', 'pass', 'sell', 'require', 'report', 'decide', 'pull', 'develop', 'note', - 'however', 'because', 'although', 'since', 'while', 'where', 'which', - 'what', 'who', 'how', 'why', 'this', 'that', 'these', 'those', - 'i', 'you', 'he', 'she', 'it', 'we', 'they', 'me', 'him', 'her', - 'us', 'them', 'my', 'your', 'his', 'its', 'our', 'their', - 'new', 'old', 'big', 'small', 'long', 'short', 'good', 'bad', - 'great', 'little', 'right', 'left', 'first', 'last', 'next', - 'sure', 'like', 'well', 'back', 'still', 'even', 'much', 'many', - // Programming/tech words that appear capitalized + 'generate', 'design', 'manage', 'process', 'handle', 'check', 'verify', + 'submit', 'apply', 'accept', 'reject', 'approve', 'deny', 'confirm', + 'cancel', 'delete', 'remove', 'edit', 'modify', 'view', 'display', + 'search', 'filter', 'sort', 'select', 'choose', 'pick', 'enter', + 'input', 'output', 'upload', 'download', 'install', 'uninstall', + 'enable', 'disable', 'activate', 'deactivate', 'toggle', 'switch', + 'connect', 'disconnect', 'sync', 'refresh', 'reload', 'reset', + 'save', 'load', 'store', 'restore', 'backup', 'export', 'import', + 'copy', 'paste', 'drag', 'drop', 'click', 'press', 'hold', 'release', + 'scroll', 'zoom', 'resize', 'expand', 'collapse', 'hide', 'reveal', + 'lock', 'unlock', 'encrypt', 'decrypt', 'sign', 'register', 'login', + 'logout', 'subscribe', 'unsubscribe', 'share', 'publish', 'deploy', + 'launch', 'test', 'debug', 'fix', 'patch', 'merge', 'split', 'join', + 'link', 'attach', 'detach', 'insert', 'append', 'prepend', 'wrap', + 'format', 'parse', 'convert', 'transform', 'translate', 'compile', + 'execute', 'render', 'animate', 'validate', 'sanitize', 'escape', + // Common nouns (appear in titles, headings, labels) + 'account', 'action', 'address', 'alert', 'analysis', 'answer', + 'application', 'area', 'article', 'asset', 'background', 'badge', + 'banner', 'board', 'body', 'border', 'bottom', 'box', 'brand', + 'browser', 'buffer', 'button', 'cache', 'calendar', 'card', 'case', + 'category', 'center', 'channel', 'chart', 'chat', 'child', 'choice', + 'class', 'client', 'cloud', 'cluster', 'code', 'collection', 'color', + 'column', 'command', 'comment', 'community', 'company', 'component', + 'config', 'configuration', 'connection', 'console', 'contact', + 'container', 'content', 'context', 'control', 'corner', 'count', + 'country', 'cover', 'custom', 'dashboard', 'data', 'database', + 'date', 'day', 'default', 'description', 'design', 'desktop', + 'detail', 'device', 'dialog', 'directory', 'document', 'domain', + 'draft', 'driver', 'edge', 'editor', 'element', 'email', 'end', + 'engine', 'entry', 'environment', 'error', 'event', 'example', + 'exception', 'extension', 'feature', 'feedback', 'field', 'file', + 'filter', 'folder', 'font', 'footer', 'form', 'format', 'frame', + 'function', 'gallery', 'general', 'global', 'grid', 'group', + 'guide', 'handler', 'header', 'health', 'help', 'helper', 'history', + 'home', 'host', 'icon', 'image', 'index', 'info', 'input', 'instance', + 'interface', 'issue', 'item', 'job', 'key', 'label', 'language', + 'layout', 'level', 'library', 'light', 'limit', 'line', 'link', + 'list', 'local', 'location', 'log', 'logo', 'main', 'manager', + 'manual', 'map', 'margin', 'master', 'match', 'media', 'member', + 'memory', 'menu', 'message', 'method', 'middle', 'mobile', 'modal', + 'mode', 'model', 'module', 'monitor', 'name', 'navigation', 'network', + 'node', 'note', 'notification', 'number', 'object', 'option', + 'order', 'origin', 'output', 'overlay', 'overview', 'owner', 'package', + 'padding', 'page', 'panel', 'parent', 'parser', 'password', 'path', + 'pattern', 'permission', 'photo', 'pipeline', 'placeholder', 'plan', + 'platform', 'player', 'plugin', 'point', 'policy', 'pool', 'popup', + 'port', 'position', 'post', 'power', 'preview', 'primary', 'print', + 'priority', 'process', 'product', 'profile', 'program', 'progress', + 'project', 'prompt', 'property', 'protocol', 'provider', 'proxy', + 'public', 'query', 'queue', 'quick', 'radio', 'range', 'rate', + 'reader', 'record', 'region', 'release', 'remote', 'render', + 'report', 'request', 'resource', 'response', 'result', 'review', + 'role', 'root', 'route', 'row', 'rule', 'runtime', 'sample', + 'scanner', 'schema', 'scope', 'screen', 'script', 'search', + 'section', 'security', 'select', 'sender', 'server', 'service', + 'session', 'setting', 'settings', 'setup', 'share', 'shell', + 'shortcut', 'sidebar', 'signal', 'simple', 'single', 'site', 'size', + 'slider', 'slot', 'snapshot', 'socket', 'solution', 'source', 'space', + 'stage', 'standard', 'start', 'state', 'status', 'step', 'stop', + 'storage', 'store', 'stream', 'string', 'style', 'subject', + 'success', 'summary', 'support', 'switch', 'symbol', 'syntax', + 'system', 'table', 'target', 'task', 'team', 'template', 'terminal', + 'test', 'text', 'theme', 'thread', 'time', 'timer', 'title', 'token', + 'tool', 'toolbar', 'tooltip', 'top', 'total', 'track', 'traffic', + 'tree', 'trigger', 'type', 'unit', 'update', 'upload', 'user', + 'util', 'utility', 'value', 'variable', 'version', 'video', 'view', + 'virtual', 'warning', 'watch', 'web', 'widget', 'width', 'window', + 'wizard', 'word', 'worker', 'workspace', 'wrapper', 'zone', + // Common adjectives + 'active', 'advanced', 'available', 'basic', 'best', 'better', 'blank', + 'bold', 'clean', 'clear', 'close', 'closed', 'complete', 'complex', + 'connected', 'correct', 'critical', 'current', 'dark', 'deep', + 'detailed', 'different', 'direct', 'double', 'dynamic', 'early', + 'easy', 'empty', 'entire', 'equal', 'essential', 'exact', 'extra', + 'fast', 'final', 'fine', 'fixed', 'flat', 'free', 'fresh', 'front', + 'full', 'generic', 'given', 'good', 'great', 'green', 'hard', + 'hidden', 'high', 'hot', 'huge', 'human', 'initial', 'inner', + 'internal', 'invalid', 'large', 'late', 'latest', 'left', 'light', + 'live', 'long', 'low', 'major', 'maximum', 'middle', 'minimum', + 'minor', 'mixed', 'modern', 'multiple', 'native', 'natural', + 'nested', 'neutral', 'new', 'normal', 'null', 'old', 'online', + 'open', 'optional', 'outer', 'overall', 'parallel', 'partial', + 'pending', 'plain', 'popular', 'possible', 'previous', 'primary', + 'private', 'proper', 'protected', 'quick', 'random', 'raw', 'ready', + 'real', 'recent', 'red', 'related', 'relative', 'remote', 'required', + 'responsive', 'rich', 'right', 'round', 'safe', 'secure', 'selected', + 'sensitive', 'separate', 'serial', 'shared', 'short', 'silent', + 'similar', 'simple', 'single', 'small', 'smart', 'smooth', 'soft', + 'solid', 'special', 'specific', 'stable', 'standard', 'static', + 'strict', 'strong', 'supported', 'sweet', 'thin', 'tight', 'tiny', + 'total', 'true', 'unique', 'universal', 'unknown', 'upper', 'valid', + 'various', 'virtual', 'visible', 'visual', 'warm', 'weak', 'white', + 'whole', 'wide', 'wild', + // Programming/tech terms 'string', 'number', 'boolean', 'object', 'array', 'function', 'class', 'type', 'error', 'null', 'undefined', 'true', 'false', 'return', 'import', 'export', 'default', 'const', 'let', 'var', 'async', 'await', 'try', 'catch', 'throw', 'finally', 'switch', 'case', 'break', - 'note', 'example', 'warning', 'important', 'todo', 'fixme', 'hack', - 'step', 'option', 'result', 'value', 'key', 'data', 'info', - 'file', 'code', 'test', 'debug', 'config', 'setup', 'update', - // Common sentence starters that aren't names + 'example', 'warning', 'important', 'todo', 'fixme', 'hack', + // Common sentence starters 'please', 'thanks', 'hello', 'hi', 'hey', 'dear', 'sincerely', - 'regards', 'best', 'cheers', 'sorry', 'yes', 'no', 'ok', 'okay', - // Days and months (not PPI) + 'regards', 'best', 'cheers', 'sorry', 'yes', 'ok', 'okay', + // Days and months 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday', 'january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december', diff --git a/src/lib/auto-detect.js b/src/lib/auto-detect.js index 35a9eab..bea7464 100644 --- a/src/lib/auto-detect.js +++ b/src/lib/auto-detect.js @@ -257,6 +257,8 @@ const AutoDetect = { }; // Common English words to exclude from proper noun detection +// Comprehensive list including verbs, nouns, adjectives that appear +// in titles, headings, UI buttons, and instructions const COMMON_WORDS = new Set([ 'the', 'and', 'but', 'for', 'not', 'you', 'all', 'can', 'had', 'her', 'was', 'one', 'our', 'out', 'are', 'has', 'his', 'how', 'its', 'may', @@ -276,6 +278,84 @@ const COMMON_WORDS = new Set([ 'number', 'other', 'point', 'right', 'small', 'state', 'thing', 'think', 'those', 'three', 'through', 'under', 'until', 'water', 'world', 'write', 'might', 'should', 'because', 'although', + // Common verbs (titles, headings, buttons, instructions) + 'generate', 'design', 'manage', 'process', 'handle', 'check', 'verify', + 'submit', 'apply', 'accept', 'reject', 'approve', 'deny', 'confirm', + 'cancel', 'delete', 'remove', 'edit', 'modify', 'view', 'display', + 'search', 'filter', 'sort', 'select', 'choose', 'pick', 'enter', + 'upload', 'download', 'install', 'enable', 'disable', 'activate', + 'connect', 'disconnect', 'sync', 'refresh', 'reload', 'reset', + 'save', 'load', 'store', 'restore', 'backup', 'copy', 'paste', + 'lock', 'unlock', 'encrypt', 'decrypt', 'sign', 'register', 'login', + 'logout', 'subscribe', 'share', 'publish', 'deploy', 'launch', + 'merge', 'split', 'join', 'link', 'attach', 'insert', 'append', + 'format', 'parse', 'convert', 'transform', 'translate', 'compile', + 'execute', 'render', 'animate', 'validate', 'sanitize', 'escape', + 'create', 'build', 'start', 'stop', 'open', 'close', 'run', 'send', + // Common nouns (titles, headings, labels) + 'account', 'action', 'address', 'alert', 'analysis', 'application', + 'area', 'article', 'asset', 'background', 'badge', 'banner', 'board', + 'body', 'border', 'bottom', 'box', 'browser', 'buffer', 'button', + 'cache', 'calendar', 'card', 'category', 'center', 'channel', 'chart', + 'chat', 'child', 'choice', 'client', 'cloud', 'code', 'collection', + 'color', 'column', 'command', 'comment', 'community', 'company', + 'component', 'config', 'configuration', 'connection', 'console', + 'contact', 'container', 'content', 'context', 'control', 'count', + 'country', 'custom', 'dashboard', 'data', 'database', 'date', 'day', + 'default', 'description', 'design', 'desktop', 'detail', 'device', + 'dialog', 'directory', 'document', 'domain', 'draft', 'driver', + 'edge', 'editor', 'element', 'email', 'engine', 'entry', 'environment', + 'error', 'event', 'example', 'extension', 'feature', 'feedback', + 'field', 'file', 'filter', 'folder', 'font', 'footer', 'form', + 'frame', 'function', 'gallery', 'general', 'global', 'grid', + 'guide', 'handler', 'header', 'health', 'help', 'history', 'home', + 'host', 'icon', 'image', 'index', 'info', 'input', 'instance', + 'interface', 'issue', 'item', 'job', 'key', 'label', 'language', + 'layout', 'level', 'library', 'light', 'limit', 'line', 'link', + 'list', 'local', 'location', 'log', 'logo', 'main', 'manager', + 'manual', 'map', 'media', 'member', 'memory', 'menu', 'message', + 'method', 'mobile', 'modal', 'mode', 'model', 'module', 'monitor', + 'navigation', 'network', 'node', 'note', 'notification', 'object', + 'option', 'order', 'origin', 'output', 'overlay', 'overview', 'owner', + 'package', 'page', 'panel', 'parent', 'parser', 'password', 'path', + 'pattern', 'permission', 'photo', 'pipeline', 'placeholder', 'plan', + 'platform', 'player', 'plugin', 'point', 'policy', 'pool', 'popup', + 'port', 'position', 'post', 'power', 'preview', 'primary', 'print', + 'priority', 'process', 'product', 'profile', 'program', 'progress', + 'project', 'prompt', 'property', 'protocol', 'provider', 'proxy', + 'public', 'query', 'queue', 'quick', 'range', 'rate', 'reader', + 'record', 'region', 'release', 'remote', 'report', 'request', + 'resource', 'response', 'result', 'review', 'role', 'root', 'route', + 'row', 'rule', 'runtime', 'sample', 'scanner', 'schema', 'scope', + 'screen', 'script', 'search', 'section', 'security', 'select', + 'sender', 'server', 'service', 'session', 'setting', 'settings', + 'setup', 'share', 'shell', 'shortcut', 'sidebar', 'signal', 'simple', + 'single', 'site', 'size', 'slider', 'snapshot', 'socket', 'solution', + 'source', 'space', 'stage', 'standard', 'status', 'step', 'storage', + 'stream', 'string', 'style', 'subject', 'success', 'summary', + 'support', 'switch', 'symbol', 'syntax', 'system', 'table', 'target', + 'task', 'team', 'template', 'terminal', 'test', 'text', 'theme', + 'thread', 'title', 'token', 'tool', 'toolbar', 'tooltip', 'total', + 'track', 'traffic', 'tree', 'trigger', 'type', 'unit', 'update', + 'upload', 'user', 'utility', 'value', 'variable', 'version', 'video', + 'view', 'virtual', 'warning', 'watch', 'web', 'widget', 'width', + 'window', 'wizard', 'word', 'worker', 'workspace', 'wrapper', 'zone', + // Common adjectives + 'active', 'advanced', 'available', 'basic', 'clean', 'clear', 'complete', + 'connected', 'correct', 'critical', 'current', 'dark', 'deep', + 'different', 'direct', 'double', 'dynamic', 'easy', 'empty', 'entire', + 'exact', 'extra', 'fast', 'final', 'fixed', 'flat', 'free', 'fresh', + 'full', 'generic', 'given', 'hidden', 'initial', 'inner', 'internal', + 'invalid', 'latest', 'live', 'major', 'maximum', 'minimum', 'minor', + 'mixed', 'modern', 'multiple', 'native', 'natural', 'nested', 'normal', + 'online', 'optional', 'outer', 'overall', 'partial', 'pending', 'plain', + 'popular', 'possible', 'previous', 'private', 'proper', 'protected', + 'random', 'raw', 'ready', 'real', 'recent', 'related', 'relative', + 'required', 'responsive', 'safe', 'secure', 'selected', 'sensitive', + 'separate', 'shared', 'silent', 'similar', 'smart', 'smooth', 'solid', + 'special', 'specific', 'stable', 'static', 'strict', 'strong', + 'supported', 'unique', 'universal', 'unknown', 'upper', 'valid', + 'various', 'visible', 'visual', 'whole', 'wide', // Programming / tech terms 'string', 'number', 'boolean', 'object', 'array', 'function', 'class', 'type', 'error', 'null', 'undefined', 'true', 'false', 'return', diff --git a/src/options/options.html b/src/options/options.html index abe7481..ea8ce0a 100644 --- a/src/options/options.html +++ b/src/options/options.html @@ -589,7 +589,7 @@ diff --git a/src/options/options.js b/src/options/options.js index 5f6eaa6..fbf0b11 100644 --- a/src/options/options.js +++ b/src/options/options.js @@ -17,7 +17,7 @@ const $ = (sel) => document.querySelector(sel); // --- Safe innerHTML replacement (AMO-compliant) --- function safeHTML(el, html) { const doc = new DOMParser().parseFromString(html, 'text/html'); - el.replaceChildren(...doc.body.childNodes); + el.replaceChildren(...Array.from(doc.body.childNodes)); } document.addEventListener('DOMContentLoaded', async () => { diff --git a/src/popup/popup.css b/src/popup/popup.css index df8f32c..4dc2ed8 100644 --- a/src/popup/popup.css +++ b/src/popup/popup.css @@ -623,6 +623,35 @@ body { font-size: 12px; } +/* Options tab */ +.setting-item { + display: flex; + align-items: center; + justify-content: space-between; + padding: 8px 0; + border-bottom: 1px solid #f3f4f6; +} + +.setting-item:last-of-type { border-bottom: none; } + +.setting-label { + flex: 1; + min-width: 0; +} + +.setting-label strong { + font-size: 12px; + display: block; + color: #1f2937; +} + +.setting-label .setting-desc { + font-size: 10px; + color: #9ca3af; + display: block; + margin-top: 1px; +} + /* Footer */ .footer { padding: 8px 16px; diff --git a/src/popup/popup.html b/src/popup/popup.html index 33accc5..38c8635 100644 --- a/src/popup/popup.html +++ b/src/popup/popup.html @@ -33,6 +33,7 @@ + @@ -193,6 +194,54 @@
+ +Sync, encryption, org, version history, import/export, and more
+