`, hovering over the gear maintains the parent's `:hover` state — no gap or flicker when moving the cursor from the text to the gear.
+
+**Gear icon properties:**
+- `display: inline` always, visibility controlled via `opacity` + `pointer-events` (allows CSS transition).
+- Font size: 10–11px, matching badge text proportion.
+- Color: inherits badge text color. At rest (parent hovered): `opacity: 0.6`. On direct gear hover: `opacity: 1`.
+- Left margin: `4px` to separate from subreddit text.
+- `cursor: pointer`.
+
+**Click behavior:**
+- `event.preventDefault()` — prevents navigating the subreddit link.
+- `event.stopPropagation()` — prevents bubbling to the badge click handler.
+- Calls `openPopover()` with the badge element, subreddit name, and current settings.
+
+Only subreddit badges get the gear icon. Comments badges do not.
+
+## Popover — Structure
+
+The popover is a `` appended to `document.body` with `position: absolute` and a high `z-index` (e.g., `10000`).
+
+### Contents
+
+```
+┌──────────────────────────┐
+│ r/javascript [×] │ ← header with subreddit name and close button
+├──────────────────────────┤
+│ Background [■] #fde8e0 │ ← color swatch + hex text input
+│ Border [■] #c84a20 │
+│ Text [■] #c84a20 │
+├──────────────────────────┤
+│ Preview: [ r/javascript ]│ ← live preview badge
+├──────────────────────────┤
+│ [Reset Default] [Save]│ ← action buttons
+│ [Cancel]│
+└──────────────────────────┘
+```
+
+- **Header:** Subreddit name as a label (e.g., "r/javascript"), truncated with ellipsis if long. Close button (×) on the right.
+- **Color rows:** Three rows, one per property (background, border, text). Each row has a label, an ` ` swatch, and a ` ` for hex value. The two inputs are synced bidirectionally.
+- **Live preview:** A `` styled as an `rt-badge rt-badge--subreddit`, with the subreddit name as text content. Inline styles update in real time as the user adjusts any color input.
+- **Footer:** "Reset to Default" button (left), "Save" and "Cancel" buttons (right).
+
+### Positioning
+
+On open, the popover is positioned below the clicked badge, aligned to its left edge:
+
+1. Get the badge's `getBoundingClientRect()`.
+2. Calculate `top = rect.bottom + window.scrollY + 6px` (6px gap).
+3. Calculate `left = rect.left + window.scrollX`.
+4. If the popover would overflow the viewport bottom, flip above: `top = rect.top + window.scrollY - popoverHeight - 6px`.
+5. Clamp `left` so the popover doesn't overflow left or right edges.
+
+A small CSS arrow (`::before` pseudo-element) points toward the badge.
+
+### Lifecycle
+
+- **Open:** Clicking a gear icon calls `openPopover()`. If the popover is already open for a different subreddit, it re-positions and re-populates (no stacking). If the popover is already open for the *same* subreddit, the click toggles it closed (cancel behavior).
+- **Close without saving:** Clicking Cancel, clicking the × button, clicking outside the popover, pressing Escape, or toggling the same gear icon.
+- **Close with saving:** Clicking Save.
+- **Dark mode toggle while open:** If dark mode changes while the popover is open (e.g., user toggles RES night mode), the popover's visual theme updates via the existing dark mode observer, but the color *values* in the inputs are not changed — they reflect the user's in-progress edits regardless of mode.
+
+## Color Editing and Preview
+
+### Initial values
+
+When the popover opens for a subreddit:
+- If an override exists in `settings.subredditColors[subredditName]`, those values populate the inputs.
+- If no override exists, the inputs show the current global subreddit badge colors for the active mode (light or dark), derived from `settings[prefix + ".subredditBgColor"]` etc. This way the user starts from the "current appearance" and can adjust from there.
+
+### Input syncing
+
+- Changing the ` ` updates the text input's value.
+- Changing the text input updates the color picker if the value is a valid hex color (`/^#[0-9a-f]{6}$/i`). Invalid values show a subtle red border on the text input but do not update the picker.
+
+### Live preview
+
+- As any color input changes (via `input` event), the preview badge's inline styles update immediately.
+- The preview badge is styled identically to a real subreddit badge (same classes), with inline `style` overrides for the three color properties.
+- Actual page badges are **not** updated until Save is clicked.
+
+## Save, Cancel, and Reset
+
+### Save
+
+1. Writes `{bg, border, text}` into `settings.subredditColors[subredditName]`.
+2. Calls `RedditTweaks.saveSettings(settings)` → writes to `browser.storage.local`.
+3. The existing `storage.onChanged` listener in `main.js` fires, calling `updateColors()`, which re-applies per-subreddit overrides to all badges on the page — all instances of that subreddit update, not just the one that was clicked.
+4. Closes the popover.
+
+### Cancel
+
+- Dismisses the popover without writing anything.
+- Triggered by: clicking Cancel, clicking ×, clicking outside the popover, pressing Escape.
+- Page badges remain unchanged.
+
+### Reset to Default
+
+1. Deletes `settings.subredditColors[subredditName]` (removes the key entirely).
+2. Saves the updated settings.
+3. The badge reverts to global colors via the `updateColors()` flow.
+4. The popover inputs update to show the global defaults so the user sees what "default" means.
+5. The popover **stays open** so the user can confirm or adjust further.
+
+### Sync with popup
+
+Both the inline popover and the popup's per-subreddit overrides section read/write the same `subredditColors` object in `browser.storage.local`. Changes made inline appear in the popup next time it's opened, and vice versa. No additional sync logic is needed.
+
+## Styling
+
+### Popover
+
+- White background (`#fff`), `1px solid #ccc` border, `border-radius: 6px`.
+- `box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15)` for depth.
+- Padding: `12px`.
+- Max-width: `260px`.
+- Font: same stack as the extension (`-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif`), 13px base.
+- CSS arrow (via `::before` pseudo-element) pointing toward the anchor badge.
+
+### Dark mode variant
+
+The popover detects the current mode using the same `isDarkMode(settings)` logic in `badges.js`. When dark:
+- Background: `#2a2a2a`.
+- Border: `#555`.
+- Text: `#e0e0e0`.
+- Input borders adjusted for contrast.
+- Applied via `.rt-dark` class on the popover element, consistent with the existing badge dark mode approach.
+
+### Color input rows
+
+- Flex layout: label (left), color swatch + hex text (right).
+- Color swatches: `28px × 20px`, `1px solid #ccc` border, `border-radius: 3px`.
+- Hex text inputs: `70px` wide, monospace font, `font-size: 12px`.
+
+### Buttons
+
+- **Save:** Accent blue background (`#4a90d9`), white text, `border-radius: 3px`.
+- **Cancel:** Text-only or light secondary style, same as popup's `.btn-secondary`.
+- **Reset to Default:** Secondary style, positioned on the left side of the footer to avoid accidental clicks near Save.
+
+### All classes use the `rt-` prefix
+
+Consistent with the rest of the extension: `rt-color-popover`, `rt-popover-header`, `rt-popover-row`, `rt-popover-preview`, `rt-popover-footer`, etc.
+
+## File Changes
+
+| File | Change |
+|---|---|
+| `content/tweaks/badges.js` | Add gear icon injection in `processPost()`. Add popover creation, open/close/save/reset functions. |
+| `content/styles/badges.css` | Add styles for `.rt-badge-gear`, `.rt-color-popover` and its children, light and dark variants. |
+| `lib/settings.js` | No changes. |
+| `content/main.js` | No changes. |
+| `popup/popup.js` | No changes. |
+| `popup/popup.html` | No changes. |
+| `manifest.json` | No changes. |
+
+Two files modified, zero new files.
+
+## Edge Cases
+
+- **Subreddit badge absent:** No gear icon added, no popover trigger. Follows existing behavior where the subreddit badge is skipped.
+- **Popover open when page scrolls:** Popover uses `position: absolute` and scrolls with page content. No repositioning needed.
+- **Popover open when RES loads new posts:** New posts get processed normally. The open popover stays in place.
+- **Multiple rapid gear clicks:** Single popover instance re-positions and re-populates. No stacking.
+- **Invalid hex input:** Text input shows subtle error border. Save uses the color picker's last valid value.
+- **Very long subreddit names:** Header truncates with `text-overflow: ellipsis`.
+- **Extension disabled mid-session:** Page reloads (existing behavior), removing all injected elements including the popover.
+
+## Testing
+
+Manual testing additions:
+
+1. Hovering over a subreddit badge shows the gear icon; moving off hides it.
+2. Moving from badge text to gear icon does not flicker/hide the gear.
+3. Clicking the gear opens the popover positioned near the badge.
+4. Clicking the gear does not navigate the subreddit link.
+5. Popover shows current override values (or global defaults if no override exists).
+6. Changing colors updates the live preview badge in real time.
+7. Actual page badges do not change until Save is clicked.
+8. Clicking Save persists the override and updates all badges for that subreddit on the page.
+9. Clicking Cancel (or outside, or Escape) dismisses without saving.
+10. Reset to Default removes the override, reverts badge to global colors, and shows global values in the popover.
+11. Inline changes appear in the popup's per-subreddit overrides section.
+12. Popup changes to per-subreddit overrides are reflected when the inline popover is next opened.
+13. Gear icon does not appear on comments badges.
+14. Popover dark mode variant works when RES night mode is active.
+15. Only one popover open at a time — clicking a different gear re-positions the popover.