From 982a16d86e6de75662672e14bd3ad19351aac460 Mon Sep 17 00:00:00 2001 From: wagesj45 Date: Sun, 24 Aug 2025 00:39:20 -0500 Subject: [PATCH] feat(theme): apply new color palette and polish UI - Add theme variables and restyle popup/options using Primary 3 as background and Primary 2 as surfaces; accents use Primary 1.\n- Move Save to a footer section on the options page; add responsive layout and button variants.\n- Update icon build defaults to use Primary 2 for add-on and Primary 1 for toolbar icons.\n- Add build-and-commit helper to run build, stage generated assets, commit, and optionally push.\n- Add npm scripts: build:commit and build:commit:push. --- package.json | 2 + scripts/build-and-commit.js | 101 +++++++++++++++++++++++++++++++++ scripts/build-icons.js | 14 +++-- src/options/index.html | 17 ++++-- src/options/styles.css | 68 ++++++++++++++++++++-- src/popup/styles.css | 109 ++++++++++++++++++++++++++++++++---- 6 files changed, 285 insertions(+), 26 deletions(-) create mode 100644 scripts/build-and-commit.js diff --git a/package.json b/package.json index 1649a2b..060620b 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,8 @@ "dev": "web-ext run --start-url https://archive.org --source-dir .", "build:icons": "node scripts/build-icons.js", "build": "npm run build:icons && web-ext build -o -a dist", + "build:commit": "node scripts/build-and-commit.js", + "build:commit:push": "PUSH=true node scripts/build-and-commit.js --push", "lint": "echo 'Add ESLint config to enable' && exit 0", "format": "echo 'Add Prettier config to enable' && exit 0", "test": "echo 'No tests yet' && exit 0", diff --git a/scripts/build-and-commit.js b/scripts/build-and-commit.js new file mode 100644 index 0000000..bf888bb --- /dev/null +++ b/scripts/build-and-commit.js @@ -0,0 +1,101 @@ +#!/usr/bin/env node +/* + Build + commit (+ optional push) helper. + + - Runs the existing build (`npm run build`) + - Stages generated assets (icons by default; optionally dist with INCLUDE_DIST=true) + - Commits with a conventional message including the package version + - If `--push` or `PUSH=true`, pushes to the current branch's upstream + + Notes: + - Respects .gitignore (dist is ignored unless INCLUDE_DIST=true) + - Safe no-op when there is nothing to commit +*/ + +const fs = require('fs'); +const path = require('path'); +const { spawnSync } = require('child_process'); + +const REPO = path.join(__dirname, '..'); +const PKG_PATH = path.join(REPO, 'package.json'); + +function run(cmd, args, opts = {}) { + const res = spawnSync(cmd, args, { stdio: 'inherit', ...opts }); + if (res.error) throw res.error; + return res.status || 0; +} + +function runOut(cmd, args, opts = {}) { + const res = spawnSync(cmd, args, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], ...opts }); + if (res.error) throw res.error; + return { code: res.status || 0, out: (res.stdout || '').trim(), err: (res.stderr || '').trim() }; +} + +function ensureGit() { + const { code } = runOut('git', ['--version']); + if (code !== 0) { + console.error('git not found in PATH'); + process.exit(1); + } +} + +function pkgVersion() { + const pkg = JSON.parse(fs.readFileSync(PKG_PATH, 'utf8')); + return pkg.version || '0.0.0'; +} + +function main() { + ensureGit(); + + // 1) Build (icons + xpi) + console.log('• Running build…'); + const codeBuild = run('npm', ['run', 'build'], { cwd: REPO }); + if (codeBuild !== 0) process.exit(codeBuild); + + // 2) Stage generated assets + const includeDist = String(process.env.INCLUDE_DIST || '').toLowerCase() === 'true'; + console.log('• Staging generated assets…'); + // Always stage icons (tracked or untracked) + run('git', ['add', 'icons/icon-*.png'], { cwd: REPO }); + if (includeDist) { + // dist is ignored; force add if requested + run('git', ['add', '-f', 'dist'], { cwd: REPO }); + } + + // 3) Check if anything is staged + const { out: staged } = runOut('git', ['diff', '--cached', '--name-only'], { cwd: REPO }); + if (!staged) { + console.log('✓ Nothing to commit. Up to date.'); + return; + } + + // 4) Commit + const version = pkgVersion(); + const msg = `chore(build): update generated assets (v${version})`; + console.log(`• Committing: ${msg}`); + const codeCommit = run('git', ['commit', '-m', msg], { cwd: REPO }); + if (codeCommit !== 0) process.exit(codeCommit); + + // 5) Optional push + const shouldPush = process.argv.includes('--push') || String(process.env.PUSH || '').toLowerCase() === 'true'; + if (!shouldPush) { + console.log('✓ Commit created. Skipping push (enable with --push or PUSH=true).'); + return; + } + + console.log('• Pushing to upstream…'); + // If upstream exists, push; else set upstream to origin/ + const { code: upCode } = runOut('git', ['rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{u}'], { cwd: REPO }); + if (upCode === 0) { + const codePush = run('git', ['push'], { cwd: REPO }); + if (codePush !== 0) process.exit(codePush); + } else { + const { out: branch } = runOut('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { cwd: REPO }); + const codePush = run('git', ['push', '-u', 'origin', branch], { cwd: REPO }); + if (codePush !== 0) process.exit(codePush); + } + console.log('✓ Pushed.'); +} + +main(); + diff --git a/scripts/build-icons.js b/scripts/build-icons.js index f6f955f..dc86cef 100644 --- a/scripts/build-icons.js +++ b/scripts/build-icons.js @@ -3,9 +3,13 @@ Generates extension and toolbar PNG icons from the base SVG with transparent background and configurable stroke colors. Requires ImageMagick (`magick`). - Config via environment variables (optional): - ICON_COLOR_ADDON – hex color for add-on icons (48/96/128). Default: #111827 - ICON_COLOR_TOOLBAR – hex color for toolbar icons (16/32). Default: #111827 + Theme defaults (aligned with project palette): + Primary 2 (deep): #223544 → add-on icon strokes (default) + Primary 1 (light): #5AC3D6 → toolbar icon strokes (default) + + Override via environment variables (optional): + ICON_COLOR_ADDON – hex color for add-on icons (48/96/128). Default: #223544 + ICON_COLOR_TOOLBAR – hex color for toolbar icons (16/32). Default: #5AC3D6 Usage: node scripts/build-icons.js @@ -21,8 +25,8 @@ const SRC_SVG = path.join(ICONS_DIR, 'file-search.svg'); const ADDON_SIZES = [48, 96, 128]; const TOOLBAR_SIZES = [16, 32]; -const COLOR_ADDON = process.env.ICON_COLOR_ADDON || '#111827'; -const COLOR_TOOLBAR = process.env.ICON_COLOR_TOOLBAR || '#111827'; +const COLOR_ADDON = process.env.ICON_COLOR_ADDON || '#223544'; +const COLOR_TOOLBAR = process.env.ICON_COLOR_TOOLBAR || '#5AC3D6'; function ensureMagick() { // Prefer calling binaries directly to avoid shell init output polluting stdout. diff --git a/src/options/index.html b/src/options/index.html index c9d3640..211ee9c 100644 --- a/src/options/index.html +++ b/src/options/index.html @@ -19,12 +19,7 @@
- - - -
-
- +
@@ -48,6 +43,16 @@ + + diff --git a/src/options/styles.css b/src/options/styles.css index 722729e..8464605 100644 --- a/src/options/styles.css +++ b/src/options/styles.css @@ -1,9 +1,67 @@ -body { font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif; margin: 16px; } -header h1 { margin: 0 0 12px; font-size: 18px; } -section { margin: 12px 0; } +:root { + --c-primary-1: #5AC3D6; + --c-primary-2: #223544; + --c-primary-3: #4E6D84; + --c-emph-1: #F5A623; + --c-emph-2: #D94E87; + --c-emph-3: #49C46D; + + --bg: var(--c-primary-3); + --surface: var(--c-primary-2); + --text: #EAF2F7; + --muted: rgba(255,255,255,0.75); + --border: rgba(255,255,255,0.18); + --input-bg: rgba(255,255,255,0.06); + --input-border: rgba(255,255,255,0.22); + --link: var(--c-primary-1); + --focus: var(--c-primary-1); +} + +body { + font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif; + margin: 16px; + background: var(--bg); + color: var(--text); +} + +header h1 { margin: 0 0 12px; font-size: 18px; color: var(--text); } + +main { + display: grid; + gap: 12px; +} + +@media (min-width: 820px) { + main { grid-template-columns: 1fr 1fr; } + .footer-actions { grid-column: 1 / -1; } +} + +section { + margin: 0; + background: var(--surface); + padding: 12px; + border-radius: 10px; + border: 1px solid var(--border); +} + .row { display: flex; align-items: center; gap: 8px; margin: 8px 0; flex-wrap: wrap; } label { font-size: 14px; } label input { margin-left: 6px; min-width: 360px; } -button { font-size: 13px; padding: 6px 12px; } -#status { font-size: 13px; white-space: pre-wrap; } +input, select { + background: var(--input-bg); + color: var(--text); + border: 1px solid var(--input-border); + border-radius: 8px; + padding: 6px 8px; +} +input::placeholder { color: var(--muted); } +input:focus, select:focus { outline: 2px solid var(--focus); outline-offset: 1px; } + +button { font-size: 13px; padding: 8px 14px; border-radius: 8px; cursor: pointer; border: 1px solid transparent; } +button:hover { filter: brightness(1.05); } +.btn-primary { background: var(--c-primary-1); color: #11343C; } +.btn-outline { background: transparent; color: var(--text); border-color: var(--input-border); } +.btn-danger { background: var(--c-emph-2); color: #fff; } + +#status { font-size: 13px; white-space: pre-wrap; color: var(--muted); } diff --git a/src/popup/styles.css b/src/popup/styles.css index f659c54..669d8b9 100644 --- a/src/popup/styles.css +++ b/src/popup/styles.css @@ -1,14 +1,103 @@ -body { font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif; margin: 10px; } -header h1 { font-size: 14px; margin: 0 0 8px; } -section { margin-bottom: 10px; } -.row { display: flex; align-items: center; gap: 8px; margin: 6px 0; flex-wrap: wrap; } -label { font-size: 12px; } +:root { + --c-primary-1: #5AC3D6; /* accent light */ + --c-primary-2: #223544; /* deep surface */ + --c-primary-3: #4E6D84; /* app background */ + --c-emph-1: #F5A623; /* amber */ + --c-emph-2: #D94E87; /* pink */ + --c-emph-3: #49C46D; /* green */ + + --bg: var(--c-primary-3); + --surface: var(--c-primary-2); + --text: #EAF2F7; + --muted: rgba(255,255,255,0.75); + --border: rgba(255,255,255,0.18); + --input-bg: rgba(255,255,255,0.06); + --input-border: rgba(255,255,255,0.22); + --link: var(--c-primary-1); + --focus: var(--c-primary-1); +} + +body { + font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif; + margin: 10px; + background: var(--bg); + color: var(--text); +} + +header h1 { + font-size: 14px; + margin: 0 0 8px; + color: var(--text); +} + +section { + margin-bottom: 10px; + background: var(--surface); + padding: 8px; + border-radius: 8px; + border: 1px solid var(--border); +} + +.row { + display: flex; + align-items: center; + gap: 8px; + margin: 6px 0; + flex-wrap: wrap; +} + +label { font-size: 12px; color: var(--text); } label input { margin-left: 6px; } + .chk { align-items: center; } -button { font-size: 12px; padding: 4px 10px; } + +input, select { + background: var(--input-bg); + color: var(--text); + border: 1px solid var(--input-border); + border-radius: 6px; + padding: 4px 6px; +} +input::placeholder { color: var(--muted); } +input:focus, select:focus { outline: 2px solid var(--focus); outline-offset: 1px; } + +button { + font-size: 12px; + padding: 6px 12px; + background: var(--c-primary-1); + color: #11343C; + border: 1px solid transparent; + border-radius: 6px; + cursor: pointer; +} +button:hover { filter: brightness(1.05); } +button:active { transform: translateY(0.5px); } + #count { font-weight: bold; margin: 0 4px; } -#status { font-size: 12px; white-space: pre-wrap; } -.link { font-size: 12px; margin-left: auto; text-decoration: underline; cursor: pointer; } -.preview ul, #preview { list-style: none; padding: 0; margin: 6px 0; max-height: 160px; overflow: auto; border: 1px solid #ddd; border-radius: 4px; } -#preview li { font-size: 12px; padding: 4px 6px; border-bottom: 1px solid #eee; } +#status { font-size: 12px; white-space: pre-wrap; color: var(--muted); } + +.link { + font-size: 12px; + margin-left: auto; + text-decoration: underline; + cursor: pointer; + color: var(--link); +} + +.preview ul, #preview { + list-style: none; + padding: 0; + margin: 6px 0; + max-height: 160px; + overflow: auto; + border: 1px solid var(--border); + border-radius: 6px; + background: var(--input-bg); +} + +#preview li { + font-size: 12px; + padding: 4px 6px; + border-bottom: 1px solid rgba(255,255,255,0.08); +} #preview li:last-child { border-bottom: 0; }