CtrlK
BlogDocsLog inGet started
Tessl Logo

pantheon-ai/website-theme-porter

Port the visual theme and styling from a live website to a React/Tailwind CSS project. Extracts colours, typography, spacing, and component styles — via agent-browser automation, manual inspection, curl/wget, or direct source reading — writes structured documentation and all artifacts under .context/artifacts/{website}/ with timestamps, applies findings as Tailwind v4 CSS tokens, then verifies by visually diffing the original site against the local or deployed version. Use when cloning a brand, replicating a design system, matching a reference site, migrating visual identity, copying a style guide, or porting a theme from any live URL into a React codebase.

95

1.44x
Quality

94%

Does it follow best practices?

Impact

98%

1.44x

Average score across 5 eval scenarios

SecuritybySnyk

Advisory

Suggest reviewing before use

Overview
Quality
Evals
Security
Files

criteria.jsonevals/scenario-3/

{
  "context": "Tests whether the agent authors src/index.css correctly for Tailwind v4: no hsl() wrapping in @theme inline, correct :root / @theme inline structure, --radius defined, @layer base with body vars, no arbitrary Tailwind values in components, and font loaded via link tag.",
  "type": "weighted_checklist",
  "checklist": [
    {
      "name": "No hsl() in @theme inline",
      "description": "Inside the @theme inline block, colour tokens are NOT wrapped in hsl() — they use var() references to :root variables (e.g. --color-primary: var(--primary) not --color-primary: hsl(349 80% 56%))",
      "max_score": 15
    },
    {
      "name": "hsl() used in :root",
      "description": "Inside the :root block, colour values ARE wrapped in hsl() (e.g. --primary: hsl(349 80% 56%))",
      "max_score": 8
    },
    {
      "name": "Tailwind import present",
      "description": "src/index.css starts with @import \"tailwindcss\"",
      "max_score": 5
    },
    {
      "name": "radius token defined",
      "description": "src/index.css defines a --radius variable in :root (set to 0.5rem or 8px equivalent)",
      "max_score": 8
    },
    {
      "name": "@layer base body styles",
      "description": "src/index.css contains an @layer base block that sets body background-color, color, and font-family using CSS variables (not hardcoded values)",
      "max_score": 8
    },
    {
      "name": "Font loaded in index.html",
      "description": "index.html includes a <link> tag loading the Nunito font from Google Fonts with display=swap",
      "max_score": 8
    },
    {
      "name": "Font preconnect",
      "description": "index.html includes <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">",
      "max_score": 5
    },
    {
      "name": "No arbitrary values in Button",
      "description": "src/components/Button.tsx does NOT contain any Tailwind arbitrary value syntax (e.g. bg-[#E94560], text-[#FFFFFF])",
      "max_score": 15
    },
    {
      "name": "Semantic tokens in Button",
      "description": "src/components/Button.tsx uses semantic Tailwind classes derived from the token names (e.g. bg-primary, text-primary-foreground)",
      "max_score": 15
    },
    {
      "name": "All tokens mapped in @theme inline",
      "description": "All semantic tokens from colours.md (--background, --foreground, --primary, --primary-foreground, --muted, --muted-foreground, --border) are mapped in @theme inline",
      "max_score": 13
    }
  ]
}

evals

SKILL.md

tile.json