cristobal-ai

SMART Investments — Infographics Site Skill

Vercel deployment logs: `https://vercel.com/dashboard`

cristobal-ai 0 Updated 4w ago

Resources

15
GitHub

Install

npx skillscat add cristobal-ai/infographics

Install via the SkillsCat registry.

SKILL.md

SMART Investments — Infographics Site Skill

Project Context for Claude Code

This file gives Claude Code full context about the SMART Investments infographics site.
Load it at the start of every session with: claude --add-context SKILL.md


Repository

  • GitHub: cristobal-ai/infographics
  • Live URL: https://infographics.smrtinvestments.com
  • Deploy: Vercel (auto-deploys on push to main)
  • Stack: Pure HTML/CSS/JS — no build step, no bundler, no framework

Directory Structure

/
├── index.html                        ← Main hub (card grid, Firebase bookmarks, i18n)
├── locales/
│   ├── en.json                       ← English strings for index (ui + cards)
│   └── es.json                       ← Spanish strings for index (ui + cards)
├── api/
│   ├── chat.js                       ← Vercel Edge Function → Gemini API router
│   └── config.js                     ← Vercel Edge Function → Firebase config (secrets)
├── KLBP_TAXSTRATEGY/index.html
├── KLBP_TAXSTRATEGY_ES/index.html
├── KLBP_Market_Analysis/index.html
├── KLBP_Market_Feb2026/index.html
├── Industrial_Flex_NNN/index.html
├── 6_Flex-Industrial-Asset/index.html
├── KLBP_POA_Explained/index.html
├── KLBP_OwnersJourney/index.html
├── estructura_mex/index.html         ← Spanish (original)
└── estructura_mex_en/index.html      ← English version

Naming convention for Spanish translations: append _ES to the English folder name.
Example: KLBP_TAXSTRATEGYKLBP_TAXSTRATEGY_ES


Brand System

Token Value Usage
Navy #193A64 Primary brand color, headers
Red #af2924 Accent, "A" in SMART logo, borders
Cyan #06B6D4 Scrollbar, highlights
Dark footer #0f1729 Footer background
Font Montserrat / Roboto Headings / body

Custom scrollbar (apply to every page):

::-webkit-scrollbar { width: 10px; }
::-webkit-scrollbar-track { background: #e2e8f0; }
::-webkit-scrollbar-thumb { background: #0ea5e9; border-radius: 5px; }

SVG Logo

The full SMART logo SVG is large (~38KB). It lives inline in every page header.
NEVER truncate or simplify it. Copy it verbatim from any existing page.
The reliable source is: KLBP_TAXSTRATEGY/index.html lines ~20–130 of the header.


Language Toggle Pattern

Every English infographic must have a badge in the top-right of the header:

<a href="/PAGENAME_ES" class="lang-badge">🇲🇽 Ver en Español</a>

Every Spanish infographic must have the reciprocal badge:

<a href="/PAGENAME" class="lang-badge">🇺🇸 View in English</a>

Badge CSS (add to every page <style>):

.lang-badge {
    display: inline-flex; align-items: center; gap: 6px;
    background: #193A64; color: white;
    font-size: 0.75rem; font-weight: 700;
    padding: 4px 10px; border-radius: 20px;
    text-decoration: none; transition: background 0.2s;
}
.lang-badge:hover { background: #af2924; }

AI Panel Pattern

Every infographic has a floating AI assistant panel (bottom-right).
The panel calls POST /api/chat with { query, topic }.

Topic keys (defined in api/chat.js):

Topic key Used in
tax_strategy KLBP_TAXSTRATEGY
market_analysis KLBP_Market_Analysis, KLBP_Market_Feb2026
leasing_agent Industrial_Flex_NNN
landlord_consultant KLBP_POA_Explained
impuesto_herencia estructura_mex (Spanish legal terms)
default fallback

Spanish AI panels use the same topic key as English — only the UI strings change.


Localization Rules

Translation workflow

  1. Prereq — make sure the English source is bilingual-ready. Older infographics may not yet have the .lang-badge CSS rule or the 🇲🇽 Ver en Español <a> element. If either is missing, add both to the English file before creating the Spanish version.
  2. Copy, don't rewrite. cp EN/index.html ES/index.html then apply targeted Edits to translate text. Rewriting from scratch risks truncating the inline SVG logo (which sits on a single ~38KB line) — copy-then-translate preserves it verbatim and keeps canvas IDs and chart logic in lockstep with the source.
  3. Change <html lang="en"><html lang="es">
  4. Translate ALL visible user-facing text (including JS-side strings: chart labels, axis titles, dataset labels, loading/error messages, button text, placeholders)
  5. Keep in English: numeric data, acronyms (QIP, NNN, FIRPTA, IRS, NRA), JS/API code, CSS class names, chart color values, topic keys
  6. Replace the English page's 🇲🇽 Ver en Español badge target with the Spanish page's 🇺🇸 View in English badge (point at the English URL)
  7. Update locales/es.json: set "available": true, update "url" to "/PAGENAME_ES"

es.json card update template

{
  "id": "CARD_ID",
  "badge": "TRANSLATED BADGE",
  "title": "TRANSLATED TITLE",
  "description": "TRANSLATED DESCRIPTION",
  "cta": "Ver Infografía",
  "url": "/PAGENAME_ES",
  "available": true
}

Chart label translation

  • Chart.js labels arrays: translate display strings
  • Chart.js datasets[].label: translate
  • Plotly title.text, xaxis.title.text, yaxis.title.text: translate
  • Plotly x arrays (waterfall categories): translate
  • Plotly text arrays (bar labels): keep as numbers/symbols
  • Chart data values: NEVER change

Vercel Edge Functions

api/chat.js

  • Runtime: edge
  • Receives: { query: string, topic: string }
  • Routes to Gemini API using SYSTEM_PROMPTS[topic]
  • Response: Gemini candidate JSON

api/config.js

  • Runtime: edge
  • Returns Firebase config from env vars
  • Only accessible from smrtinvestments.com

Never expose GEMINI_API_KEY or Firebase secrets in client-side HTML.


index.html i18n Engine

The index page loads /locales/{lang}.json at runtime.
Cards are driven entirely by the JSON — no HTML edits needed for content changes.

To add a new card:

  1. Add entry to locales/en.json cards array
  2. Add translated entry to locales/es.json cards array
    (set "available": false until Spanish version exists)
  3. Add visual style to CARD_STYLE object in index.html

CARD_STYLE object (in index.html <script>):

'new-card-id': {
    accent: 'bg-sky-500',
    badgeBg: 'bg-sky-100',
    badgeText: 'text-sky-700',
    hoverText: 'group-hover:text-sky-600',
    emoji: '📄'
}

Common Tasks

Translate an infographic to Spanish

# 1. Read the source
cat KLBP_TAXSTRATEGY/index.html | wc -l   # verify you have the full file

# 2. Create destination
mkdir -p KLBP_TAXSTRATEGY_ES

# 3. Ask Claude Code to translate
# "Translate KLBP_TAXSTRATEGY/index.html to Spanish.
#  Write the result to KLBP_TAXSTRATEGY_ES/index.html.
#  Follow the rules in SKILL.md."

# 4. Verify
diff <(grep -o 'canvas id="[^"]*"' KLBP_TAXSTRATEGY/index.html | sort) \
     <(grep -o 'canvas id="[^"]*"' KLBP_TAXSTRATEGY_ES/index.html | sort)
# Should produce no output (same canvas IDs)

# 5. Update es.json
# Set available: true, url: "/KLBP_TAXSTRATEGY_ES" for tax-strategy card

# 6. Push
git add . && git commit -m "feat: add KLBP_TAXSTRATEGY Spanish translation" && git push

Add lang badge to existing English page

# Find the header right-side div and add the badge
# Pattern to find: the div that contains the nav label or right-side content
grep -n "lang-badge\|View in English\|Ver en Español" KLBP_TAXSTRATEGY/index.html

Verify SVG logo is intact

The SMART logo SVG sits on a single line, so grep -c (which counts matching lines, not matches) always returns 1–2 — even on a fully truncated SVG. Use grep -o ... | wc -l to count actual occurrences:

grep -o "clipPath" KLBP_TAXSTRATEGY_ES/index.html | wc -l
# Should match the English source exactly (typically 200+; KLBP_TAXSTRATEGY has 204)

Quality Checklist (run before every commit)

# 1. SVG logo present and not truncated
# (grep -c counts lines, not matches — SVG sits on one line, so use grep -o + wc -l)
[ "$(grep -o "clipPath" SOURCE.html | wc -l)" = "$(grep -o "clipPath" FILE.html | wc -l)" ] && echo "SVG match" || echo "SVG MISMATCH"

# 2. Lang badge present
grep "lang-badge" FILE.html

# 3. API route intact
grep "/api/chat" FILE.html

# 4. html lang attribute correct
grep '<html lang=' FILE.html

# 5. All canvas IDs match source (for translations)
diff <(grep -o 'canvas id="[^"]*"' SOURCE.html | sort) \
     <(grep -o 'canvas id="[^"]*"' TRANSLATED.html | sort)

# 6. No hardcoded secrets
grep -i "api.key\|apikey\|secret\|password" FILE.html  # expect no output

Git Workflow

git status                    # see what changed
git diff                      # review changes before commit
git add .                     # stage all
git commit -m "description"   # commit
git push                      # triggers Vercel auto-deploy
# Live in ~30 seconds at infographics.smrtinvestments.com

Vercel deployment logs: https://vercel.com/dashboard