posterskill-academic-posters

AI-assisted academic conference poster generation from Overleaf source using Claude Code

INSTALLATION
npx skills add https://github.com/aradotso/trending-skills --skill posterskill-academic-posters
Run in your project or agent environment. Adjust flags if your CLI version differs.

SKILL.md

$27

Start Claude Code and trigger the skill:

claude
/make-poster

Claude will ask for your project website URL and any formatting specs, then generate a poster/ directory with index.html.

Directory Structure

poster/                  # this repo

├── .claude/

│   └── commands/

│       └── make-poster.md   # the skill command

├── overleaf/            # your cloned Overleaf project

├── references/          # optional reference PDFs for style matching

└── poster/              # generated output

    ├── index.html       # the poster (self-contained)

    └── logos/           # downloaded institutional logos

What Gets Generated

The output poster/index.html is a React app (loaded via CDN) containing:

  • **CARD_REGISTRY** — each card's title, color, and JSX body content
  • **DEFAULT_LAYOUT** — column structure and card ordering
  • **DEFAULT_LOGOS** — institutional logos for the header
  • **window.posterAPI** — programmatic API for layout automation

Visual Editor Features

Open poster/index.html in Chrome to access the built-in editor:

Feature

How to Use

Resize columns

Drag column dividers left/right

Resize cards

Drag row dividers up/down within a column

Swap cards

Click one diamond handle, then another

Move/insert cards

Click a handle, then click a drop zone

Adjust font size

Click A- / A+ buttons in toolbar

Preview print layout

Click Preview button

Export layout

Click Copy Config to get JSON

Programmatic API ( window.posterAPI )

Available in the browser console or via Playwright automation:

// Swap two cards by ID

posterAPI.swapCards('method', 'results')

// Move a card to a specific column and position

posterAPI.moveCard('quant', 'col1', 2)

// Resize a column (in mm)

posterAPI.setColumnWidth('col1', 280)

// Set a specific card's height (in mm)

posterAPI.setCardHeight('method', 150)

// Scale all text globally

posterAPI.setFontScale(1.5)

// Measure whitespace waste (lower = better layout)

posterAPI.getWaste()

// Get the current layout as an object

posterAPI.getLayout()

// Get the full config as JSON (paste back to Claude)

posterAPI.getConfig()

// Reset to default layout

posterAPI.resetLayout()

Iteration Workflow

The core loop for refining your poster:

  • Claude generates first draft, opens poster/index.html in your browser
  • You edit in the browser — drag dividers, swap cards, resize columns
  • Click "Copy Config" in the toolbar to export your layout as JSON
  • Paste the JSON back to Claude — it updates DEFAULT_LAYOUT in the HTML
  • Repeat until the layout is perfect
  • Print to PDF: File → Print → Margins: None, Background Graphics: On

Playwright Automation (used internally by Claude)

Claude uses Playwright to automate layout verification. You can use it too:

const { chromium } = require('playwright');

async function optimizePoster() {

  const browser = await chromium.launch();

  const page = await browser.newPage();

  await page.goto(`file://${__dirname}/poster/index.html`);

  // Use the posterAPI to adjust layout programmatically

  const waste = await page.evaluate(() => posterAPI.getWaste());

  console.log('Whitespace waste:', waste);

  // Resize a column

  await page.evaluate(() => posterAPI.setColumnWidth('col1', 300));

  // Take a screenshot for visual verification

  await page.screenshot({ path: 'poster-preview.png', fullPage: true });

  // Generate PDF at print resolution

  await page.pdf({

    path: 'poster.pdf',

    width: '841mm',   // A0 landscape width

    height: '1189mm',

    printBackground: true,

  });

  await browser.close();

}

Card Registry Structure

Each card in the poster is defined in CARD_REGISTRY:

const CARD_REGISTRY = {

  abstract: {

    title: "Abstract",

    color: "#f0f4ff",

    body: `

      <p>Your abstract text here. Supports full JSX including

      <strong>bold</strong>, <em>italic</em>, and inline math.</p>

    `

  },

  method: {

    title: "Method",

    color: "#fff8f0",

    body: `

      <img src="figures/pipeline.png" style={{width:'100%'}} />

      <p>Caption describing the pipeline above.</p>

    `

  },

  results: {

    title: "Results",

    color: "#f0fff4",

    body: `

      <table>...</table>

    `

  }

};

Default Layout Structure

const DEFAULT_LAYOUT = {

  columns: [

    {

      id: 'col1',

      widthMm: 280,

      cards: ['abstract', 'method']

    },

    {

      id: 'col2',

      widthMm: 320,

      cards: ['results', 'quant']

    },

    {

      id: 'col3',

      widthMm: 280,

      cards: ['conclusion', 'references']

    }

  ]

};

Inputs Claude Uses

Input

Where It Comes From

Required

Paper content

overleaf/ directory

Yes

Project website

URL (asked at runtime)

Yes

Reference posters

references/*.pdf

No

Author website

URL for brand matching

No

Formatting specs

Conference URL or text

Asked if missing

Logos

Auto-downloaded to poster/logos/

Auto

Common Patterns

Adding a custom figure card

// In CARD_REGISTRY, add a new card

custom_fig: {

  title: "Qualitative Results",

  color: "#fafafa",

  body: `

    <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:'8px'}}>

      <img src="figures/result1.png" style={{width:'100%'}} />

      <img src="figures/result2.png" style={{width:'100%'}} />

    </div>

    <p style={{fontSize:'0.85em', textAlign:'center'}}>

      Comparison on held-out test scenes.

    </p>

  `

}

Then add it to DEFAULT_LAYOUT:

{ id: 'col2', widthMm: 320, cards: ['results', 'custom_fig'] }

Logos configuration

const DEFAULT_LOGOS = [

  { src: 'logos/university.png', height: 60 },

  { src: 'logos/lab.png', height: 50 },

  { src: 'logos/sponsor.png', height: 45 },

];

Printing to PDF

In Chrome:

  • Open poster/index.html
  • Click Preview to verify layout
  • Ctrl+P / Cmd+P
  • Set Margins: None
  • Enable Background graphics
  • Set paper size to your conference spec (A0, 36×48in, etc.)
  • Save as PDF

Troubleshooting

Poster looks different in print vs browser

→ Use Chrome (not Firefox/Safari). Enable "Background graphics" in print dialog.

Figures not loading

→ Ensure figure paths in the HTML are relative to poster/index.html. Claude copies figures to poster/figures/ — verify the directory exists.

Logos not fetched

→ Claude uses Playwright to download logos from your project website. If it fails, manually copy logo files to poster/logos/ and update DEFAULT_LOGOS paths.

Layout config not updating after paste

→ Make sure you paste the full JSON from Copy Config — Claude looks for the complete DEFAULT_LAYOUT and DEFAULT_LOGOS objects to replace.

Font too small/large for poster size

→ Use posterAPI.setFontScale(1.2) in the browser console, or click A+ / A- buttons, then Copy Config and paste to Claude.

Whitespace gaps between cards

→ Run posterAPI.getWaste() in console to quantify. Use posterAPI.setCardHeight('cardId', heightMm) to tune card heights, or drag row dividers manually.

Example Output

See the Fillerbuster poster (repo) as a live example of posterskill output.

BrowserAct

Let your agent run on any real-world website

Bypass CAPTCHA & anti-bot for free. Start local, scale to cloud.

Explore BrowserAct Skills →

Stop writing automation&scrapers

Install the CLI. Run your first Skill in 30 seconds. Scale when you're ready.

Start free
free · no credit card