From 0a4c319a140a3ec868937d8ea3fd66077d86e66e Mon Sep 17 00:00:00 2001 From: Luiz Gustavo Date: Fri, 29 May 2026 01:34:15 -0300 Subject: [PATCH] ux(search): repaint autocomplete dropdown to magazine palette MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The /search input opened a green/cyan terminal-style dropdown leftover from the dev-tool era — the only piece of the search experience still off-theme after the page redesign. - Switch matrix-green (#00ff9c) and cyan (#7fdbff) for gold (#e0c080) and cream throughout the dropdown. - Replace ASCII "⚡" with a Zap lucide icon and reorder the header so the Suggestions label leads. - Localise "documentos" / "trechos" / "autocomplete" via a locale prop threaded from SearchPanel; counts pluralise per language. - Document title now uses the display serif at 15px (was monospace small); passage excerpts in #cbd2dd to match the rest of body copy. - Passage row reorder: page · type · 🛸 · doc-id (was chunk_id first); page number gets gold accent so the reader can scan by page. Co-Authored-By: Claude Opus 4.7 (1M context) --- web/components/search-autocomplete.tsx | 77 +++++++++++++++++++------- web/components/search-panel.tsx | 2 +- 2 files changed, 57 insertions(+), 22 deletions(-) diff --git a/web/components/search-autocomplete.tsx b/web/components/search-autocomplete.tsx index 2b680f8..636a05f 100644 --- a/web/components/search-autocomplete.tsx +++ b/web/components/search-autocomplete.tsx @@ -7,9 +7,13 @@ * a two-section dropdown: matching documents (jump targets) and matching * chunks (in-doc passages with excerpt). Sub-30ms target. Keyboard navigation * via Up/Down + Enter. Esc closes. + * + * Magazine palette (gold/cream on dark) to match the rest of the site; the + * previous matrix-green/cyan styling was a leftover from the dev-tool era. */ import { useEffect, useRef, useState } from "react"; import Link from "next/link"; +import { Zap } from "lucide-react"; interface DocSuggestion { doc_id: string; @@ -34,12 +38,38 @@ interface ApiResponse { chunks: ChunkSuggestion[]; } -export function SearchAutocomplete({ query, onPick }: { query: string; onPick?: () => void }) { +const COPY = { + "pt-br": { + autocomplete: "Sugestões", + documents: "Documentos", + passages: "Trechos", + docs_count: (n: number) => `${n} ${n === 1 ? "documento" : "documentos"}`, + chunks_count: (n: number) => `${n} ${n === 1 ? "trecho" : "trechos"}`, + }, + en: { + autocomplete: "Suggestions", + documents: "Documents", + passages: "Passages", + docs_count: (n: number) => `${n} ${n === 1 ? "document" : "documents"}`, + chunks_count: (n: number) => `${n} ${n === 1 ? "passage" : "passages"}`, + }, +} as const; + +export function SearchAutocomplete({ + query, + onPick, + locale = "pt-br", +}: { + query: string; + onPick?: () => void; + locale?: "pt-br" | "en"; +}) { const [data, setData] = useState(null); const [loading, setLoading] = useState(false); const [open, setOpen] = useState(false); const timer = useRef | null>(null); const abort = useRef(null); + const t = COPY[locale]; useEffect(() => { const q = query.trim(); @@ -72,18 +102,23 @@ export function SearchAutocomplete({ query, onPick }: { query: string; onPick?: if (!open || !data) return null; return ( -
-
- - ⚡ autocomplete · {data.documents.length} docs · {data.chunks.length} trechos +
+
+ + {loading ? "…" : `${data.duration_ms ?? "?"}ms`}
{data.documents.length > 0 && (
-
- documentos +
+ {t.documents}
    {data.documents.map((d) => ( @@ -91,12 +126,12 @@ export function SearchAutocomplete({ query, onPick }: { query: string; onPick?: -
    {d.title}
    +
    {d.title}
    - {d.doc_id} - {d.collection && · {d.collection}} + {d.doc_id} + {d.collection && <>{d.collection}}
    @@ -107,8 +142,8 @@ export function SearchAutocomplete({ query, onPick }: { query: string; onPick?: {data.chunks.length > 0 && (
    -
    - trechos +
    + {t.passages}
      {data.chunks.map((c) => ( @@ -116,16 +151,16 @@ export function SearchAutocomplete({ query, onPick }: { query: string; onPick?: -
      - {c.chunk_id} - p{c.page} - {c.type} - {c.ufo_anomaly && 🛸} - {c.doc_id} +
      + p{c.page} + + {c.type} + {c.ufo_anomaly && 🛸} + {c.doc_id}
      -
      {c.excerpt}
      +
      {c.excerpt}
      ))} diff --git a/web/components/search-panel.tsx b/web/components/search-panel.tsx index 674d73a..61a7302 100644 --- a/web/components/search-panel.tsx +++ b/web/components/search-panel.tsx @@ -174,7 +174,7 @@ export function SearchPanel({ className="w-full bg-[#0a0e1a] border border-[rgba(224,192,128,0.25)] focus:border-[#e0c080] rounded-full pl-10 pr-4 py-3 font-display text-[15px] md:text-[16px] text-[#e7ecf3] placeholder:text-[#5a6678] outline-none transition-colors" autoFocus /> - setQ("")} /> + setQ("")} locale={locale} />