- );
-}
-
-function CommandList({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- );
-}
-
-function CommandEmpty({
- ...props
-}: React.ComponentProps) {
- return (
-
- );
-}
-
-function CommandGroup({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- );
-}
-
-function CommandSeparator({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- );
-}
-
-function CommandItem({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- );
-}
-
-function CommandShortcut({
- className,
- ...props
-}: React.ComponentProps<"span">) {
- return (
-
- );
-}
-
-export {
- Command,
- CommandDialog,
- CommandInput,
- CommandList,
- CommandEmpty,
- CommandGroup,
- CommandItem,
- CommandShortcut,
- CommandSeparator,
-};
diff --git a/hooks/use-search.ts b/hooks/use-search.ts
new file mode 100644
index 0000000..c254772
--- /dev/null
+++ b/hooks/use-search.ts
@@ -0,0 +1,61 @@
+"use client";
+
+import { useRouter } from "next/navigation";
+import { type FormEvent, type KeyboardEvent, useRef, useState } from "react";
+
+type UseSearchOptions = {
+ onClose?: () => void;
+ clearOnSubmit?: boolean;
+};
+
+export function useSearch(options: UseSearchOptions = {}) {
+ const { onClose, clearOnSubmit = true } = options;
+ const router = useRouter();
+ const [isOpen, setIsOpen] = useState(false);
+ const [query, setQuery] = useState("");
+ const inputRef = useRef(null);
+
+ const open = () => setIsOpen(true);
+
+ const close = () => {
+ setIsOpen(false);
+ inputRef.current?.blur();
+ onClose?.();
+ };
+
+ const reset = () => {
+ setQuery("");
+ close();
+ };
+
+ const handleSubmit = (e: FormEvent) => {
+ e.preventDefault();
+ const trimmedQuery = query.trim();
+ if (trimmedQuery) {
+ router.push(`/search?q=${encodeURIComponent(trimmedQuery)}`);
+ if (clearOnSubmit) {
+ reset();
+ } else {
+ close();
+ }
+ }
+ };
+
+ const handleKeyDown = (e: KeyboardEvent) => {
+ if (e.key === "Escape") {
+ close();
+ }
+ };
+
+ return {
+ isOpen,
+ query,
+ setQuery,
+ inputRef,
+ open,
+ close,
+ reset,
+ handleSubmit,
+ handleKeyDown,
+ };
+}
diff --git a/x_docs/DONE/search.md b/x_docs/DONE/search.md
new file mode 100644
index 0000000..4acc7de
--- /dev/null
+++ b/x_docs/DONE/search.md
@@ -0,0 +1,139 @@
+# Search Design Specification - STALE DOCUMENTATION / HISTORICAL RECORD ONLY
+
+Target: Stack Overflow-inspired search pattern adapted for DevFlow. Breakpoint: `md` (768px).
+
+**Reference screenshots:** `z-mobile.jpg`, `z-desktop.jpg`
+
+> **Scope:** This specification covers ONLY the search input and hints panel. Reference screenshots show Stack Overflow's full UI — ignore all elements except the search components (topbar search icon/input and hints dropdown).
+
+---
+
+## Functional Requirements
+
+| Requirement | Details |
+|-------------|---------|
+| **Focus behaviour** | Dropdown opens on input focus, closes on blur/Escape |
+| **Close behaviour** | Click outside OR Escape key closes search completely (2-state model) |
+| **Form submission** | Enter key submits to `/search?q={query}` |
+| **Operator insertion** | None — hints are display-only guidance |
+
+---
+
+## Current Topbar Structure
+
+**Mobile (`< md`) — `mobile-topbar.tsx`:**
+
+```
+Logo | [SEARCH ICON - to add] | Hamburger (MobileNav)
+```
+
+**Desktop (`>= md`) — `desktop-topbar.tsx`:**
+
+```
+Searchbox (placeholder) | Sign in / Sign up
+```
+
+**Existing:** `components/search/searchbox.tsx` — placeholder component, already imported in desktop topbar.
+
+---
+
+## Mobile Search
+
+**Topbar modification:** Add search icon button between Logo and Hamburger menu.
+
+**Behaviour (2-state model):**
+
+1. **Idle state:** Search icon only visible in topbar (between logo and hamburger)
+2. **Active state (on click):**
+ - Search input appears **below topbar** at full width
+ - Search icon in topbar gets subtle highlight
+ - Topbar remains intact (logo, search icon, hamburger visible)
+ - After 0.5s delay: Static hints panel appears below input
+ - **Close:** Click outside OR Escape → returns to idle state
+
+**Hints Panel:**
+
+- Single column layout
+- **Overlays page content** (positioned absolutely, does not push content down)
+- Non-interactive guidance (not selectable)
+- Footer: "Ask a question" button (primary style) → `/questions/ask`
+
+---
+
+## Desktop Search (>= md)
+
+**Topbar:** Searchbox (always visible) | Sign in / Sign up
+
+**Behaviour (2-state model):**
+
+1. **Idle state:** Search input always visible inline in topbar (current `Searchbox` location)
+2. **Active state (on focus):**
+ - Hints dropdown appears immediately below input (no delay)
+ - Input gets focus ring/highlight
+ - Topbar remains intact
+ - **Close:** Click outside OR Escape → hints close
+
+**Hints Dropdown:**
+
+- **Two-column layout** (left column: tag/user/phrase, right column: filters)
+- **Overlays page content** (positioned absolutely, does not push content down)
+- Non-interactive guidance (not selectable)
+- Footer: "Ask a question" button (primary style) → `/questions/ask`
+- **Excluded:** "Search help" link (visible in reference screenshot, not implementing)
+
+---
+
+## Shared Hints Content
+
+| Syntax | Description |
+|--------|-------------|
+| `[tag]` | search within a tag |
+| `user:1234` | search by author |
+| `"words here"` | exact phrase |
+| `answers:0` | unanswered questions |
+| `score:3` | posts with a 3+ score |
+| `is:question` | type of post |
+
+---
+
+## Divergences from Stack Overflow
+
+**Excluded hints (not applicable to DevFlow):**
+
+- `collective:"Name"` — collective content (SO-specific feature)
+- `isaccepted:yes` — search within status (not implemented)
+
+**Excluded UI elements:**
+
+- "Search help" link — not required
+
+**Behaviour changes:**
+
+- **Mobile close:** SO uses 3-state model (idle → input+hints → input-only). DevFlow uses simpler 2-state model (idle ↔ active) — click outside closes completely
+
+---
+
+## Key Differences
+
+| Aspect | Mobile | Desktop |
+|--------|--------|---------|
+| Search visibility | Icon only (hidden input) | Always visible input |
+| Input position | Below topbar (overlay) | Inline in topbar |
+| Hints layout | Single column | Two columns |
+
+---
+
+## Implementation Notes
+
+- **Component type:** Expandable search input with static hints popover
+- **Not a combobox:** Hints are guidance text, not selectable options
+- **Hints panel positioning:** Absolutely positioned overlay (not in document flow), requires appropriate z-index
+- Search input and hints panel are a single-level component (not modal/nested)
+- Topbar remains visible when search is active (mobile)
+- Mobile requires adding search icon to `mobile-topbar.tsx`
+- Desktop uses existing `Searchbox` component location
+
+**Styling:**
+
+- Use `font-mono` for operator syntax display
+- Use `text-muted-foreground` for descriptions
diff --git a/x_docs/my_notes/prompt-QA.md b/x_docs/my_notes/prompt-QA.md
new file mode 100644
index 0000000..c977000
--- /dev/null
+++ b/x_docs/my_notes/prompt-QA.md
@@ -0,0 +1,198 @@
+# Code Quality Evaluation
+
+Evaluate all **staged files** (`git diff --cached --name-only`) for code quality, architecture, and best practices.
+
+## Current Baseline Status
+
+All checks pass as of evaluation start - no need to run these yourself:
+
+- **Lint & Typecheck** (`npm run check`): ✅ Passing
+- **Unit Tests** (`npm run test:unit`): ✅ 44 tests passing
+- **E2E Tests** (`npm run test:e2e`): ✅ 17 tests passing
+
+## Tech Stack Context
+
+- Next.js 16 (App Router, async params)
+- React 19 (React Compiler enabled)
+- Tailwind CSS v4 (new @import syntax, @theme inline)
+- shadcn/ui (New York style, CSS variables)
+- TypeScript strict mode
+- British English
+
+## Baseline Context
+
+Always read `globals.css` first to understand the project's theming tokens and CSS architecture.
+
+## Evaluation Criteria
+
+Analyse staged files against these principles, grouped by category:
+
+### 1. Architecture
+
+- Component responsibility and separation of concerns
+- Custom hooks extracting reusable logic
+- Appropriate file/folder structure
+
+Note:
+
+- For current desktop search architecture, see inbetween tags `` in appendix
+- (do not limit architecture consideration to this only, its provided as an aid)
+
+### 2. shadcn/ui Approach
+
+- Use shadcn MCP tools to compare components against upstream registry
+- Find best-practice usage examples via `get_item_examples_from_registries`
+- Use the `/shadcn-ui:shadcn-ui` skill for guidance
+- Check for proper composition patterns (Slot, asChild, variants via CVA)
+
+### 3. Tailwind Best Practices
+
+- Utility-first (avoid unnecessary custom CSS)
+- Mobile-first responsive design (base styles for mobile, md:/lg: for larger)
+- Consistent use of design tokens (bg-card not arbitrary colours)
+
+### 4. Centralised Theming
+
+- CSS variables for colours, spacing, radii
+- No hardcoded colours or magic numbers
+- Theme-aware styling (proper dark: variants)
+- Consistent token usage across components
+
+### 5. Code Quality
+
+- **DRY**: Extract repeated patterns (but not prematurely)
+- **YAGNI**: No speculative abstractions
+- **Elegance**: Code that's easy to read and understand
+- **Pragmatism**: When principles conflict, favour clarity and practicality
+
+## Process
+
+1. Read `globals.css` for theming context
+2. Get staged files: `git diff --cached --name-only`
+3. Read all staged files thoroughly
+4. Launch explorer agents to understand surrounding context
+5. Use shadcn MCP tools to check registry patterns and find examples
+6. Analyse against all criteria above
+7. Write findings to `report.md`
+
+## Output Format
+
+Write a `report.md` file with this structure:
+
+```md
+# Code Quality Report
+
+**Files evaluated**: [list of staged files]
+**Date**: [timestamp]
+
+## Summary
+
+[1-2 sentence overall assessment]
+
+## Architecture
+
+[Issues or "No issues found"]
+
+## shadcn/ui Approach
+
+[Issues or "No issues found"]
+
+## Tailwind Best Practices
+
+[Issues or "No issues found"]
+
+## Centralised Theming
+
+[Issues or "No issues found"]
+
+## Code Quality (DRY, YAGNI, Elegance)
+
+[Issues or "No issues found"]
+```
+
+### Issue Format
+
+Each issue should follow this format:
+
+```md
+### 🔴 [Short issue title]
+
+**File**: `path/to/file.tsx:42`
+**Problem**: [Clear description of what's wrong]
+**Why it matters**: [Why this is bad practice / the consequence of not fixing]
+```
+
+### Severity Indicators
+
+- 🔴 **High**: Significant impact on maintainability, consistency, or correctness
+- 🟡 **Medium**: Suboptimal but functional; worth addressing
+- 🟢 **Low**: Minor improvement; nice-to-have
+
+## Guiding Principle
+
+**Elegant pragmatism**: Favour code that is easy to understand and practically maintainable. When principles conflict (e.g., DRY suggests extraction but YAGNI suggests it's premature), choose the option that results in clearer, more readable code. Flag genuine tradeoffs for user decision.
+
+## Important
+
+- Do NOT include code snippets or proposed fixes
+- Focus on explaining WHY something is a problem
+- User will investigate each issue separately to brainstorm solutions
+
+## Appendix: Current Desktop Search Architecture
+
+
+
+## Design
+
+The desktop search bar is intentionally narrower than the main content area (`max-w-2xl` = 672px vs content's `max-w-5xl` = 1024px). This provides visual distinction so the popover doesn't blend into the page content.
+
+## Component Hierarchy
+
+```
+desktop-topbar.tsx (server)
+└── DesktopSearch (client) ─── desktop-search.tsx
+ ├── useSearch hook ─────── hooks/use-search.ts
+ ├── SearchInput ────────── search-input.tsx (shared with mobile)
+ ├── SearchPopoverContent ─ search-popover-content.tsx (shared)
+ └── SearchHints ────────── search-hints.tsx (shared, variant="desktop")
+```
+
+## Width Control Points
+
+**1. Container in `desktop-topbar.tsx:9-12`:**
+
+```tsx
+
+
{/* ← Controls search bar max width (672px) */}
+
+
+
+```
+
+**2. Popover in `search-popover-content.tsx:17`:**
+
+```tsx
+className="w-(--radix-popover-trigger-width) ..." {/* ← Matches input width exactly */}
+```
+
+The `--radix-popover-trigger-width` CSS variable is auto-set by Radix to match the PopoverAnchor element (the `