← back to Ventura Corridor

public/trademarks.html

101 lines

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Trademarks · The Corridor</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
<style>
@import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,300;0,400;0,500;1,400;1,500&family=Inter:wght@300;400;500&family=JetBrains+Mono:wght@200;300;400&display=swap');
:root{--paper:#faf6ee;--ink:#1a1815;--ink-mute:#6e6356;--metal:#8a6d3b;--metal-glow:#b89968;--accent:#6a3a1a;--rule:#d8cdb8}
*{box-sizing:border-box}
html,body{margin:0;background:var(--paper);color:var(--ink);font-family:'Inter',sans-serif;font-weight:300;line-height:1.55}
header{text-align:center;padding:60px 24px 32px;border-bottom:1px solid var(--rule)}
header .kicker{font-size:9px;letter-spacing:.4em;text-transform:uppercase;color:var(--metal);font-weight:500}
header h1{font-family:'Cormorant Garamond',serif;font-style:italic;font-weight:500;font-size:64px;margin:8px 0 0;color:var(--ink);letter-spacing:-0.02em}
header h1 em{color:var(--metal);font-style:normal}
header .deck{font-family:'Cormorant Garamond',serif;font-style:italic;font-size:18px;color:var(--ink-mute);margin-top:12px;max-width:560px;margin-left:auto;margin-right:auto}
.searchbar{padding:32px 24px 8px;text-align:center}
.searchbar input{font-family:'Cormorant Garamond',serif;font-size:28px;font-style:italic;background:transparent;border:none;border-bottom:1px solid var(--rule);color:var(--ink);padding:14px 12px;min-width:520px;max-width:92vw;outline:none;text-align:center}
.searchbar input:focus{border-bottom-color:var(--metal)}
.searchbar .examples{font-size:11px;letter-spacing:.18em;color:var(--ink-mute);margin-top:14px}
.searchbar .examples b{color:var(--metal);font-family:'JetBrains Mono',monospace;font-weight:400;background:rgba(184,153,104,0.08);padding:2px 8px;margin:0 3px;cursor:pointer}
.count{text-align:center;font-size:10px;letter-spacing:.28em;text-transform:uppercase;color:var(--ink-mute);margin:6px 0 0}
main{max-width:860px;margin:0 auto;padding:20px 24px 90px}
.tm{display:grid;grid-template-columns:1fr auto;gap:6px 18px;padding:18px 0;border-bottom:1px solid var(--rule)}
.tm:hover{background:rgba(184,153,104,0.04);padding-left:8px;padding-right:8px}
.tm .mark{font-family:'Cormorant Garamond',serif;font-style:italic;font-size:24px;color:var(--ink);line-height:1.15}
.tm .owner{font-size:12px;color:var(--ink-mute);letter-spacing:.03em;margin-top:2px}
.tm .owner b{color:var(--metal);font-style:normal;font-weight:500}
.tm .gs{grid-column:1/2;font-size:12px;color:var(--ink-mute);margin-top:6px;max-width:620px}
.tm .side{grid-column:2/3;grid-row:1/3;text-align:right;min-width:150px}
.tm .status{display:inline-block;font-size:9px;letter-spacing:.2em;text-transform:uppercase;color:var(--metal-glow);border:1px solid var(--rule);padding:3px 8px;font-weight:500}
.tm .cls{display:block;font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--metal);margin-top:8px;letter-spacing:.05em}
.tm .filed{display:block;font-family:'JetBrains Mono',monospace;font-size:10px;color:var(--ink-mute);margin-top:4px;letter-spacing:.05em}
.empty{text-align:center;padding:80px 24px;color:var(--ink-mute);font-style:italic;font-family:'Cormorant Garamond',serif;font-size:22px}
.toolbar{position:fixed;top:14px;right:14px;display:flex;gap:6px;z-index:100}
.toolbar a{font-size:9px;letter-spacing:.22em;text-transform:uppercase;color:var(--ink-mute);background:var(--paper);padding:5px 10px;border:1px solid var(--rule);text-decoration:none}
.toolbar a:hover{color:var(--metal);border-color:var(--metal)}
</style>
</head>
<body>
<div class="toolbar">
  <a href="/find.html">Business finder</a>
  <a href="/">← Corridor</a>
</div>
<header>
  <div class="kicker">The Corridor · trademark registry</div>
  <h1>Who owns the <em>mark</em>?</h1>
  <div class="deck">Search the USPTO trademark full-text record by word mark or by owner. Surface the IP footprint behind any business or brand on the boulevard.</div>
</header>
<div class="searchbar">
  <input id="q" type="search" autofocus oninput="onSearch()" placeholder="a word mark, or a company / owner name">
  <div class="examples">try
    <b onclick="qy('APPLE')">APPLE</b>
    <b onclick="qy('cider')">cider</b>
    <b onclick="qy('ventures llc')">ventures llc</b>
    <b onclick="qy('coffee')">coffee</b>
  </div>
  <div class="count" id="count"></div>
</div>
<main id="results"></main>
<script>
function escHtml(s){return String(s ?? '').replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));}
function titleCase(s){return String(s ?? '').toLowerCase().replace(/\b\w/g,c=>c.toUpperCase());}
function qy(s){document.getElementById('q').value=s;onSearch();}
let _t;
function onSearch(){clearTimeout(_t);_t=setTimeout(go,200);}
async function go(){
  const q=document.getElementById('q').value.trim();
  const countEl=document.getElementById('count');
  if(q.length<2){document.getElementById('results').innerHTML='';countEl.textContent='';return;}
  let data;
  try{ data=await fetch('/api/trademarks?q='+encodeURIComponent(q)).then(r=>r.json()); }
  catch(e){ document.getElementById('results').innerHTML=`<div class="empty">Lookup failed.</div>`; return; }
  const rows=data.rows||[];
  countEl.textContent = rows.length ? `${data.count}${rows.length>=100?'+':''} match${rows.length===1?'':'es'}` : '';
  document.getElementById('results').innerHTML = rows.length===0
    ? `<div class="empty">No trademarks match “${escHtml(q)}”.</div>`
    : rows.map(r=>{
        const owner = titleCase(r.owner_name||'');
        const loc = [r.owner_city&&titleCase(r.owner_city), r.owner_state].filter(Boolean).join(', ');
        const filed = r.filing_date ? String(r.filing_date).replace(/^(\d{4})(\d{2})(\d{2})$/,'$1-$2-$3') : '';
        const reg = r.registration_number ? ` · Reg ${escHtml(r.registration_number)}` : '';
        return `<div class="tm">
          <div>
            <div class="mark">${escHtml(r.mark||'—')}</div>
            <div class="owner"><b>${escHtml(owner||'—')}</b>${loc?' · '+escHtml(loc):''}${reg}</div>
          </div>
          <div class="side">
            <span class="status">${escHtml(r.status_label||'—')}</span>
            ${r.primary_class?`<span class="cls">Int'l class ${escHtml(r.primary_class)}</span>`:''}
            ${filed?`<span class="filed">filed ${escHtml(filed)}</span>`:''}
          </div>
          ${r.goods_services?`<div class="gs">${escHtml(String(r.goods_services).slice(0,220))}${r.goods_services.length>220?'…':''}</div>`:''}
        </div>`;
      }).join('');
}
</script>
</body>
</html>