# maging — AI Output Formatter

> **AI 답변을, 쓸 수 있는 결과물로.**
> 코딩 없이, 디자인 없이 — LLM이 위젯·테마로 단일 HTML 결과물을 바로 생성합니다.

---

## Themes (35)

Set on `<html data-theme="NAME">`. Each theme bundles palette, typography, radius, shadow. Changing the attribute instantly re-styles every widget.

**Light (18):** `claude` (warm cream+terracotta) · `linear` (indigo minimal) · `stripe` (payment purple) · `notion` (off-white) · `airbnb` (coral) · `linkedin` (corporate blue) · `instagram` (vivid) · `youtube` (red) · `reddit` (orange) · `medium` (editorial green serif) · `apple` (system blue) · `duolingo` (owl green) · `tiffany` (robin-egg blue+gold) · `mailchimp` (cavendish yellow) · `tmobile` (magenta) · `fedex` (purple+orange) · `hermes` (cream serif) · `barbie` (pastel pink)

**Dark (17):** `vercel` (pure black) · `github` (dimmed) · `x` (sharp mono) · `slack` (aubergine) · `discord` (blurple) · `openai` (AI teal) · `spotify` (neon green) · `twitch` (gaming purple) · `netflix` (cinematic red) · `figma` (multi) · `amazon` (navy) · `adobe` (creative red) · `bloomberg` (terminal amber) · `nasa` (worm blue+red) · `heineken` (bottle green) · `deere` (tractor green+yellow) · `ups` (pullman brown)

Pick by intent: minimal→`linear`/`vercel` · warm→`claude`/`notion` · corporate→`linkedin`/`stripe` · bold→`netflix`/`adobe` · luxury→`hermes`/`tiffany` · playful→`barbie`/`duolingo` · terminal→`bloomberg` · engineering→`nasa`. Default: `claude`.

---

## Core Widgets

Mount: `window.Maging.<name>(selector, config)`. All auto-refresh on theme change.

### METRIC TILES

**`kpiCard`** — Label + value + delta% + sparkline. `compact: true` for mini mode.
```js
Maging.kpiCard(sel, { label, value, delta?, deltaGoodWhen?, sparkline?, icon?, compact? })
```

**`heroTile`** — Typography-first hero. No chart. Use for the single most important number.
```js
Maging.heroTile(sel, { kicker?, value, tagline?, stats?: [{ label, value }] })
```

**`metricChart`** — Hero number + labeled mini line chart. Current vs previous period.
```js
Maging.metricChart(sel, { label, value, delta?, icon?, context?, categories, series: [{ name, data }], target?, yFormatter? })
```

**`metricStack`** — Bento: main metric + 2×2 sub-metrics.
```js
Maging.metricStack(sel, { title, main: { label, value, delta? }, items: [{ label, value }] })
```

**`compareCard`** — A vs B comparison with delta.
```js
Maging.compareCard(sel, { title, left: { label, value }, right: { label, value }, delta?, deltaLabel? })
```

**`countdownTile`** — Real-time days/hrs/min countdown.
```js
Maging.countdownTile(sel, { title, target, label?, context? })
```

**`ringProgress`** — Circular progress + center value + threshold colors.
```js
Maging.ringProgress(sel, { value, max, unit, label, context?, thresholds? })
```

**`bulletChart`** — Target vs actual vs benchmark.
```js
Maging.bulletChart(sel, { value, target?, benchmark?, max, min?, ranges?, valueFormatter?, unit? })
```

**`sparklineList`** — Row list: label + value + delta + mini-sparkline.
```js
Maging.sparklineList(sel, { title, items: [{ label, value, delta, sparkline, deltaGoodWhen? }] })
```

**`goalGrid`** — Multi-goal progress bars (OKR-style).
```js
Maging.goalGrid(sel, { title, items: [{ label, value, max, unit?, sublabel? }], thresholds? })
```

### CHARTS

**`lineChart`** — Multi-series line/area chart.
```js
Maging.lineChart(sel, { title?, categories, series: [{ name, data }], stack?, area?, yFormatter? })
```

**`barChart`** — Horizontal (default) or vertical bars.
```js
Maging.barChart(sel, { title?, items: [{ label, value }], horizontal?, yFormatter?, showLabels? })
```

**`donutChart`** — Proportion visualization + center label.
```js
Maging.donutChart(sel, { title?, slices: [{ label, value, color? }], centerLabel?, centerValue? })
```

**`funnelChart`** — Stage-by-stage conversion.
```js
Maging.funnelChart(sel, { title?, stages: [{ label, value }], valueSuffix? })
```

**`gaugeChart`** — Semi-circle gauge with thresholds.
```js
Maging.gaugeChart(sel, { title?, label, value, max, unit, thresholds? })
```

**`radarChart`** — Multi-axis comparison.
```js
Maging.radarChart(sel, { title?, indicators: [{ name, max }], series: [{ name, data }] })
```

**`heatmapChart`** — 2D density (weekday × hour, etc.).
```js
Maging.heatmapChart(sel, { title?, xAxis, yAxis, matrix, tooltipFormatter? })
```

**`treemapChart`** — Area = value distribution.
```js
Maging.treemapChart(sel, { title?, items: [{ name, value }], valueFormatter? })
```

**`scatterChart`** — X/Y correlation + bubble sizes.
```js
Maging.scatterChart(sel, { title?, points: [{ label, x, y, size? }], xLabel?, yLabel? })
```

**`sankeyChart`** — Node-link flow.
```js
Maging.sankeyChart(sel, { title?, nodes: [{ name }], links: [{ source, target, value }], valueFormatter? })
```

**`waterfallChart`** — Start→gains→losses→total.
```js
Maging.waterfallChart(sel, { title?, items: [{ label, value, type? }], valueFormatter? })
```

**`mapChart`** — Korean province hex-tilemap.
```js
Maging.mapChart(sel, { title?, items: [{ region, value }], valueFormatter? })
```

**`cohortMatrix`** — Cohort × period retention matrix.
```js
Maging.cohortMatrix(sel, { title?, cohorts, periods, data, sizes?, valueFormatter? })
```

### LISTS & STATUS

**`leaderboard`** — Avatar + progress bar + rank.
```js
Maging.leaderboard(sel, { title?, items: [{ name, initial?, percent, meta? }] })
```

**`activityTable`** — Table with optional LIVE badge and optional grouped column headers.
```js
Maging.activityTable(sel, {
  title?, columns: [{ key, label, align?, render? }], rows: [...], live?,
  headerGroups?: [{ label, span, align? }]  // colspan 그룹 헤더 (선택)
})
```
`headerGroups`: 컬럼 위에 span 그룹 행 추가. `span`은 묶을 columns 수. 예) `[{ label: '26년', span: 3 }, { label: '25년', span: 2 }]`

**`timeline`** — Vertical event feed.
```js
Maging.timeline(sel, { title?, items: [{ time, text, type? }] })
```

**`inboxPreview`** — Notification/email list.
```js
Maging.inboxPreview(sel, { title?, items: [{ icon?, text, time, type? }] })
```

**`statusGrid`** — Service health dot matrix.
```js
Maging.statusGrid(sel, { title?, columns?, items: [{ label, status, value? }] })
```

### CALENDAR & PROJECT

**`calendarHeatmap`** — GitHub-contribution style.
```js
Maging.calendarHeatmap(sel, { title?, year?, values: [[date, value]], max?, cellSize? })
```

**`eventCalendar`** — Month grid.
```js
Maging.eventCalendar(sel, { title?, year?, month?, events: [{ date, label, type? }] })
```

**`progressStepper`** — Phase tracker (done/active/pending).
```js
Maging.progressStepper(sel, { title?, steps: [{ label, status, date?, badge? }] })
```

### STRUCTURAL

**`pageHeader`** — Full-width H1 block.
```js
Maging.pageHeader(sel, { kicker?, title, subtitle?, meta? })
```

**`sectionHead`** — Section divider.
```js
Maging.sectionHead(sel, { index?, kicker?, title, tag? })
```

**`alertBanner`** — Horizontal stripe (not a card).
```js
Maging.alertBanner(sel, { type, title, message?, icon?, action?: { label, href? }, dismissable? })
```

---

## Utility

```js
Maging.fmt.krw(value)       // 43.8억원 (HTML — unit styled small)
Maging.fmt.krwPlain(value)  // 43.8억원 (plain text — for chart axis/tooltip)
Maging.fmt.num(value)       // 48,291
Maging.fmt.pct(value)       // 85.3%
Maging.setTheme(name)       // switch theme at runtime
```

---

## NEVER DO

- **No `₩` prefix** — Korean convention is suffix `원`. Use `Maging.fmt.krw`.
- **No `DOMContentLoaded`** — use `maging:ready` (dashboard) or place `<script>` after maging.js (landing).
- **No custom `:root` CSS variables** — maging.css defines all `--mw-*` tokens per theme.
- **No invented class names** — Grid layout + Maging API only.
- **No code comments** — burns tokens.
- **No manual number formatters** — use `Maging.fmt.*`.

## License

MIT


---

## Mode: Landing Page

> 마케팅 랜딩페이지와 전환 최적화에 특화된 모드입니다.

### Setup

```html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@m1kapp/maging@0.1.15/dist/maging.css">
<script src="https://cdn.jsdelivr.net/npm/@m1kapp/maging@0.1.15/dist/maging.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@m1kapp/maging@0.1.15/dist/maging-landing.js"></script>
<body class="mw-themed">
```

Landing mode uses `maging.js` + `maging-landing.js` (NOT `maging-all.js`). ECharts is optional — only needed if you use chart widgets. Place widget mount calls in a `<script>` tag after the maging scripts.

---

### Landing Page Widgets (10)

**`heroSection`** — Full-width hero with radial glow.
```js
Maging.heroSection(sel, {
  kicker?,       // uppercase label
  title,         // supports <br> for line breaks
  subtitle?,
  ctas?: [{ label, href, primary? }],
  padding?       // default '6rem 1.5rem 4rem'
})
```

**`featureGrid`** — Icon + title + description card grid.
```js
Maging.featureGrid(sel, {
  cols?,         // 2 | 3 | 4, default 3
  items: [{ icon, title, desc }]
})
```

**`pricingTable`** — Plan comparison with Popular badge.
```js
Maging.pricingTable(sel, {
  plans: [{
    name, desc?, price, period?,
    popular?, badge?,
    features: string[],
    cta?: { label, href }
  }]
})
```

**`testimonialGrid`** — Quote + author card grid.
```js
Maging.testimonialGrid(sel, {
  cols?,         // 2 | 3, default 3
  items: [{ quote, name, role?, initial? }]
})
```

**`logoBar`** — Social proof logo strip.
```js
Maging.logoBar(sel, { items: [{ name, icon? }] })
```

**`ctaSection`** — Conversion CTA block with background.
```js
Maging.ctaSection(sel, {
  kicker?, title, desc?,
  ctas: [{ label, href, primary? }],
  padding?
})
```

**`faqAccordion`** — Accordion FAQ.
```js
Maging.faqAccordion(sel, { items: [{ q, a }] })
```

**`stepGuide`** — Numbered "How it works" section with optional code/image.
```js
Maging.stepGuide(sel, {
  steps: [{
    title, desc?,
    code?,    // string — shown in dark code block
    image?    // string — image URL
  }]
})
```

**`codeBlock`** — Syntax display with Copy button.
```js
Maging.codeBlock(sel, { code, lang?, title? })
```

**`comparisonTable`** — Feature comparison (us vs them).
```js
Maging.comparisonTable(sel, {
  columns: string[],       // column headers
  highlight?: number,      // 0-based index of "our" column
  rows: [{
    label: string,         // feature name
    values: (boolean|string)[]  // true → ✓, false → —, string → as-is
  }]
})
```

---

### Layout Pattern

Landing pages use **section-based vertical scroll**, not dashboard grids.

```html
<section style="max-width:1100px;margin:0 auto;padding:5rem 1.5rem;">
  <div style="text-align:center;margin-bottom:2.5rem;">
    <p style="...kicker styles...">FEATURES</p>
    <h2 style="...title styles...">제목</h2>
    <p style="...desc styles...">설명</p>
  </div>
  <div id="feature-grid"></div>
</section>
```

**Section order:** Hero → Social proof (logos + stats) → Features → How it works (stepGuide) → Code example → Comparison → Testimonials → Pricing → FAQ → CTA

**Tips:**
- Use `<hr>` dividers between sections (1px solid, opacity 0.5)
- Center-align section headers for features, testimonials, pricing
- Left-align for step guide, FAQ, code examples
- Core widgets (`kpiCard`, `lineChart`, etc.) can be mixed in for data sections
- Keep testimonials to 3 (one row)
- Keep pricing to 2–3 plans

---

### Generation Rules (Landing Page)

1. Include the 3-line setup (css + maging.js + maging-landing.js).
2. Pick ONE theme. Landing pages work well with: `claude`, `linear`, `notion`, `stripe`, `vercel`.
3. `<body class="mw-themed">`.
4. Follow the section order above. Skip sections that don't apply.
5. Mount widgets in a `<script>` tag at the end of `<body>`.
6. **Copy tone:** Specific > generic. "슬랙 알림 보내려고 코드 짜는 건 이제 그만" beats "반복 업무를 자동화하세요".
7. **Numbers:** Use real-looking numbers (2,847 not 3,000). Avoid suspiciously round metrics.
8. **Testimonials:** Vary the structure. Not every quote should be "X가 Y% 줄었습니다".
9. **FAQ:** Short, conversational answers. "아뇨" > "아닙니다, 저희 서비스는~".
10. **No ₩ prefix.** Use Korean units: 4.9만, 128억.
11. Output one fenced code block: ` ```html … ``` `.
