194 lines
79 KiB
C#
194 lines
79 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Text;
|
||
using System.Text.RegularExpressions;
|
||
using AxCopilot.Models;
|
||
using Markdig;
|
||
|
||
namespace AxCopilot.Services.Agent;
|
||
|
||
public static class TemplateService
|
||
{
|
||
public record MoodColors(string Background, string CardBg, string PrimaryText, string SecondaryText, string Accent, string Border);
|
||
|
||
public static readonly TemplateMood[] AvailableMoods = new TemplateMood[10]
|
||
{
|
||
new TemplateMood("modern", "현대적", "\ud83d\udd37", "깔끔한 라인, 넓은 여백, 미니멀한 색상 — 테크 기업 스타일"),
|
||
new TemplateMood("professional", "전문가", "\ud83d\udcca", "신뢰감 있는 네이비 톤, 데이터 중심 레이아웃 — 비즈니스 보고서"),
|
||
new TemplateMood("creative", "아이디어", "\ud83c\udfa8", "생동감 있는 그라데이션, 카드 레이아웃 — 브레인스토밍·기획서"),
|
||
new TemplateMood("minimal", "미니멀", "◻\ufe0f", "극도로 절제된 흑백, 타이포그래피 중심 — 학술·논문 스타일"),
|
||
new TemplateMood("elegant", "우아한", "✨", "세리프 서체, 골드 포인트, 격식 있는 레이아웃 — 공식 문서"),
|
||
new TemplateMood("dark", "다크 모드", "\ud83c\udf19", "어두운 배경, 고대비 텍스트 — 개발자·야간 리딩"),
|
||
new TemplateMood("colorful", "컬러풀", "\ud83c\udf08", "밝고 활기찬 멀티 컬러, 둥근 모서리 — 프레젠테이션·요약"),
|
||
new TemplateMood("corporate", "기업 공식", "\ud83c\udfe2", "보수적인 레이아웃, 로고 영역, 페이지 번호 — 사내 공식 보고서"),
|
||
new TemplateMood("magazine", "매거진", "\ud83d\udcf0", "멀티 컬럼, 큰 히어로 헤더, 인용 강조 — 뉴스레터·매거진"),
|
||
new TemplateMood("dashboard", "대시보드", "\ud83d\udcc8", "KPI 카드, 차트 영역, 그리드 레이아웃 — 데이터 대시보드")
|
||
};
|
||
|
||
private static readonly Dictionary<string, CustomMoodEntry> _customMoods = new Dictionary<string, CustomMoodEntry>(StringComparer.OrdinalIgnoreCase);
|
||
|
||
private const string CssModern = "@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');\n* { margin:0; padding:0; box-sizing:border-box; }\nbody { font-family: 'Inter', 'Segoe UI', 'Malgun Gothic', sans-serif;\n background: #f5f5f7; color: #1d1d1f; line-height: 1.75; padding: 48px 24px; }\n.container { max-width: 880px; margin: 0 auto; background: #fff;\n border-radius: 16px; padding: 56px 52px;\n box-shadow: 0 4px 24px rgba(0,0,0,0.06); }\nh1 { font-size: 28px; font-weight: 700; letter-spacing: -0.5px; color: #1d1d1f; margin-bottom: 4px; }\nh2 { font-size: 20px; font-weight: 600; margin: 36px 0 14px; color: #1d1d1f;\n padding-bottom: 8px; border-bottom: 2px solid #e5e5ea; }\nh3 { font-size: 16px; font-weight: 600; margin: 24px 0 10px; color: #0071e3; }\n.meta { font-size: 12px; color: #86868b; margin-bottom: 28px; letter-spacing: 0.3px; }\np { margin: 10px 0; font-size: 14.5px; }\ntable { width: 100%; border-collapse: collapse; margin: 20px 0; font-size: 13.5px;\n border-radius: 10px; overflow: hidden; }\nth { background: #f5f5f7; text-align: left; padding: 12px 14px; font-weight: 600;\n color: #1d1d1f; border-bottom: 2px solid #d2d2d7; }\ntd { padding: 10px 14px; border-bottom: 1px solid #f0f0f2; }\ntr:hover td { background: #f9f9fb; }\nul, ol { margin: 10px 0 10px 28px; font-size: 14.5px; }\nli { margin: 5px 0; }\ncode { background: #f5f5f7; padding: 2px 8px; border-radius: 6px; font-size: 13px;\n font-family: 'SF Mono', Consolas, monospace; color: #e3116c; }\npre { background: #1d1d1f; color: #f5f5f7; padding: 20px; border-radius: 12px;\n overflow-x: auto; font-size: 13px; margin: 16px 0; line-height: 1.6; }\npre code { background: transparent; color: inherit; padding: 0; }\nblockquote { border-left: 3px solid #0071e3; padding: 12px 20px; margin: 16px 0;\n background: #f0f7ff; color: #1d1d1f; border-radius: 0 8px 8px 0; font-size: 14px; }\n.highlight { background: linear-gradient(120deg, #e0f0ff 0%, #f0e0ff 100%);\n padding: 16px 20px; border-radius: 10px; margin: 16px 0; }\n.badge { display: inline-block; padding: 3px 10px; border-radius: 20px; font-size: 11px;\n font-weight: 600; background: #0071e3; color: #fff; margin: 2px 4px 2px 0; }";
|
||
|
||
private const string CssProfessional = "* { margin:0; padding:0; box-sizing:border-box; }\nbody { font-family: 'Segoe UI', 'Malgun Gothic', Arial, sans-serif;\n background: #eef1f5; color: #1e293b; line-height: 1.7; padding: 40px 20px; }\n.container { max-width: 900px; margin: 0 auto; background: #fff;\n border-radius: 8px; padding: 48px;\n box-shadow: 0 1px 8px rgba(0,0,0,0.08);\n border-top: 4px solid #1e3a5f; }\nh1 { font-size: 26px; font-weight: 700; color: #1e3a5f; margin-bottom: 4px; }\nh2 { font-size: 18px; font-weight: 600; margin: 32px 0 12px; color: #1e3a5f;\n border-bottom: 2px solid #c8d6e5; padding-bottom: 6px; }\nh3 { font-size: 15px; font-weight: 600; margin: 22px 0 8px; color: #2c5282; }\n.meta { font-size: 12px; color: #94a3b8; margin-bottom: 24px; border-bottom: 1px solid #e2e8f0;\n padding-bottom: 12px; }\np { margin: 8px 0; font-size: 14px; }\ntable { width: 100%; border-collapse: collapse; margin: 16px 0; font-size: 13.5px;\n border: 1px solid #e2e8f0; }\nth { background: #1e3a5f; color: #fff; text-align: left; padding: 10px 14px;\n font-weight: 600; font-size: 12.5px; text-transform: uppercase; letter-spacing: 0.5px; }\ntd { padding: 9px 14px; border-bottom: 1px solid #e2e8f0; }\ntr:nth-child(even) td { background: #f8fafc; }\ntr:hover td { background: #eef2ff; }\nul, ol { margin: 8px 0 8px 24px; }\nli { margin: 4px 0; font-size: 14px; }\ncode { background: #f1f5f9; padding: 2px 6px; border-radius: 4px; font-size: 12.5px;\n font-family: Consolas, monospace; color: #1e3a5f; }\npre { background: #0f172a; color: #e2e8f0; padding: 18px; border-radius: 6px;\n overflow-x: auto; font-size: 12.5px; margin: 14px 0; }\npre code { background: transparent; color: inherit; padding: 0; }\nblockquote { border-left: 4px solid #1e3a5f; padding: 10px 18px; margin: 14px 0;\n background: #f0f4f8; color: #334155; }\n.callout { background: #eff6ff; border: 1px solid #bfdbfe; border-radius: 6px;\n padding: 14px 18px; margin: 14px 0; font-size: 13.5px; }\n.callout strong { color: #1e40af; }";
|
||
|
||
private const string CssCreative = "@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');\n* { margin:0; padding:0; box-sizing:border-box; }\nbody { font-family: 'Poppins', 'Segoe UI', 'Malgun Gothic', sans-serif;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n min-height: 100vh; color: #2d3748; line-height: 1.75; padding: 48px 24px; }\n.container { max-width: 880px; margin: 0 auto; background: rgba(255,255,255,0.95);\n backdrop-filter: blur(20px); border-radius: 20px; padding: 52px;\n box-shadow: 0 20px 60px rgba(0,0,0,0.15); }\nh1 { font-size: 30px; font-weight: 700;\n background: linear-gradient(135deg, #667eea, #e040fb);\n -webkit-background-clip: text; -webkit-text-fill-color: transparent;\n margin-bottom: 4px; }\nh2 { font-size: 20px; font-weight: 600; margin: 36px 0 14px; color: #553c9a;\n position: relative; padding-left: 16px; }\nh2::before { content: ''; position: absolute; left: 0; top: 4px; width: 4px; height: 22px;\n background: linear-gradient(180deg, #667eea, #e040fb); border-radius: 4px; }\nh3 { font-size: 16px; font-weight: 600; margin: 22px 0 10px; color: #7c3aed; }\n.meta { font-size: 12px; color: #a0aec0; margin-bottom: 28px; }\np { margin: 10px 0; font-size: 14.5px; }\ntable { width: 100%; border-collapse: separate; border-spacing: 0; margin: 18px 0;\n font-size: 13.5px; border-radius: 12px; overflow: hidden;\n box-shadow: 0 4px 12px rgba(102,126,234,0.1); }\nth { background: linear-gradient(135deg, #667eea, #764ba2); color: #fff;\n text-align: left; padding: 12px 14px; font-weight: 600; }\ntd { padding: 10px 14px; border-bottom: 1px solid #f0e7fe; }\ntr:hover td { background: #faf5ff; }\nul, ol { margin: 10px 0 10px 28px; font-size: 14.5px; }\nli { margin: 5px 0; }\nli::marker { color: #7c3aed; }\ncode { background: #f5f3ff; padding: 2px 8px; border-radius: 6px; font-size: 13px;\n font-family: 'Fira Code', Consolas, monospace; color: #7c3aed; }\npre { background: #1a1a2e; color: #e0d4f5; padding: 20px; border-radius: 14px;\n overflow-x: auto; font-size: 13px; margin: 16px 0;\n border: 1px solid rgba(124,58,237,0.2); }\npre code { background: transparent; color: inherit; padding: 0; }\nblockquote { border-left: 4px solid #7c3aed; padding: 14px 20px; margin: 16px 0;\n background: linear-gradient(135deg, #f5f3ff, #faf5ff);\n border-radius: 0 12px 12px 0; font-style: italic; }\n.card { background: #fff; border: 1px solid #e9d8fd; border-radius: 14px;\n padding: 20px; margin: 14px 0; box-shadow: 0 2px 8px rgba(124,58,237,0.08); }\n.tag { display: inline-block; padding: 3px 12px; border-radius: 20px; font-size: 11px;\n font-weight: 500; background: linear-gradient(135deg, #667eea, #764ba2);\n color: #fff; margin: 2px 4px 2px 0; }";
|
||
|
||
private const string CssMinimal = "* { margin:0; padding:0; box-sizing:border-box; }\nbody { font-family: 'Georgia', 'Batang', serif;\n background: #fff; color: #222; line-height: 1.85; padding: 60px 24px; }\n.container { max-width: 720px; margin: 0 auto; padding: 0; }\nh1 { font-size: 32px; font-weight: 400; color: #000; margin-bottom: 4px;\n letter-spacing: -0.5px; }\nh2 { font-size: 20px; font-weight: 400; margin: 40px 0 14px; color: #000;\n border-bottom: 1px solid #ddd; padding-bottom: 8px; }\nh3 { font-size: 16px; font-weight: 600; margin: 28px 0 10px; color: #333; }\n.meta { font-size: 12px; color: #999; margin-bottom: 36px; font-style: italic; }\np { margin: 12px 0; font-size: 15px; text-align: justify; }\ntable { width: 100%; border-collapse: collapse; margin: 20px 0; font-size: 14px; }\nth { text-align: left; padding: 8px 0; font-weight: 600; border-bottom: 2px solid #000;\n font-size: 12px; text-transform: uppercase; letter-spacing: 1px; color: #555; }\ntd { padding: 8px 0; border-bottom: 1px solid #eee; }\ntr:hover td { background: #fafafa; }\nul, ol { margin: 12px 0 12px 20px; font-size: 15px; }\nli { margin: 6px 0; }\ncode { background: #f7f7f7; padding: 2px 6px; border-radius: 2px; font-size: 13px;\n font-family: 'Courier New', monospace; }\npre { background: #f7f7f7; color: #333; padding: 18px; margin: 16px 0;\n overflow-x: auto; font-size: 13px; border: 1px solid #e5e5e5; }\npre code { background: transparent; padding: 0; }\nblockquote { border-left: 3px solid #000; padding: 8px 20px; margin: 16px 0;\n color: #555; font-style: italic; }\nhr { border: none; border-top: 1px solid #ddd; margin: 32px 0; }";
|
||
|
||
private const string CssElegant = "@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;500;600;700&family=Source+Sans+3:wght@300;400;600&display=swap');\n* { margin:0; padding:0; box-sizing:border-box; }\nbody { font-family: 'Source Sans 3', 'Malgun Gothic', sans-serif;\n background: #faf8f5; color: #3d3929; line-height: 1.75; padding: 48px 24px; }\n.container { max-width: 860px; margin: 0 auto; background: #fff;\n border-radius: 4px; padding: 56px 52px;\n box-shadow: 0 1px 4px rgba(0,0,0,0.06);\n border: 1px solid #e8e4dd; }\nh1 { font-family: 'Playfair Display', Georgia, serif; font-size: 30px;\n font-weight: 700; color: #2c2416; margin-bottom: 6px; letter-spacing: -0.3px; }\nh2 { font-family: 'Playfair Display', Georgia, serif; font-size: 20px;\n font-weight: 600; margin: 36px 0 14px; color: #2c2416;\n border-bottom: 1px solid #d4c9b8; padding-bottom: 8px; }\nh3 { font-size: 15px; font-weight: 600; margin: 24px 0 10px; color: #8b7a5e; }\n.meta { font-size: 12px; color: #b0a48e; margin-bottom: 28px; letter-spacing: 0.5px;\n text-transform: uppercase; }\np { margin: 10px 0; font-size: 14.5px; }\ntable { width: 100%; border-collapse: collapse; margin: 18px 0; font-size: 13.5px; }\nth { background: #f8f5f0; text-align: left; padding: 10px 14px; font-weight: 600;\n color: #5a4d38; border-bottom: 2px solid #d4c9b8; font-size: 12.5px;\n letter-spacing: 0.5px; }\ntd { padding: 9px 14px; border-bottom: 1px solid #f0ece5; }\ntr:hover td { background: #fdfcfa; }\nul, ol { margin: 10px 0 10px 26px; font-size: 14.5px; }\nli { margin: 5px 0; }\ncode { background: #f8f5f0; padding: 2px 7px; border-radius: 3px; font-size: 12.5px;\n font-family: 'Courier New', monospace; color: #8b6914; }\npre { background: #2c2416; color: #e8e0d0; padding: 18px; border-radius: 4px;\n overflow-x: auto; font-size: 12.5px; margin: 16px 0; }\npre code { background: transparent; color: inherit; padding: 0; }\nblockquote { border-left: 3px solid #c9a96e; padding: 12px 20px; margin: 16px 0;\n background: #fdf9f0; color: #5a4d38; font-style: italic;\n font-family: 'Playfair Display', Georgia, serif; }\n.ornament { text-align: center; color: #c9a96e; font-size: 18px; margin: 24px 0; letter-spacing: 8px; }";
|
||
|
||
private const string CssDark = "@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&family=Inter:wght@300;400;500;600;700&display=swap');\n* { margin:0; padding:0; box-sizing:border-box; }\nbody { font-family: 'Inter', 'Segoe UI', 'Malgun Gothic', sans-serif;\n background: #0d1117; color: #e6edf3; line-height: 1.75; padding: 48px 24px; }\n.container { max-width: 880px; margin: 0 auto; background: #161b22;\n border-radius: 12px; padding: 52px;\n border: 1px solid #30363d;\n box-shadow: 0 8px 32px rgba(0,0,0,0.3); }\nh1 { font-size: 28px; font-weight: 700; color: #f0f6fc; margin-bottom: 4px; }\nh2 { font-size: 20px; font-weight: 600; margin: 36px 0 14px; color: #f0f6fc;\n border-bottom: 1px solid #30363d; padding-bottom: 8px; }\nh3 { font-size: 16px; font-weight: 600; margin: 24px 0 10px; color: #58a6ff; }\n.meta { font-size: 12px; color: #8b949e; margin-bottom: 28px; }\np { margin: 10px 0; font-size: 14.5px; color: #c9d1d9; }\ntable { width: 100%; border-collapse: collapse; margin: 18px 0; font-size: 13.5px;\n border: 1px solid #30363d; border-radius: 8px; overflow: hidden; }\nth { background: #21262d; text-align: left; padding: 10px 14px; font-weight: 600;\n color: #f0f6fc; border-bottom: 1px solid #30363d; }\ntd { padding: 9px 14px; border-bottom: 1px solid #21262d; color: #c9d1d9; }\ntr:hover td { background: #1c2128; }\nul, ol { margin: 10px 0 10px 28px; font-size: 14.5px; color: #c9d1d9; }\nli { margin: 5px 0; }\ncode { background: #1c2128; padding: 2px 8px; border-radius: 6px; font-size: 13px;\n font-family: 'JetBrains Mono', Consolas, monospace; color: #79c0ff; }\npre { background: #0d1117; color: #c9d1d9; padding: 20px; border-radius: 8px;\n overflow-x: auto; font-size: 13px; margin: 16px 0;\n border: 1px solid #30363d; }\npre code { background: transparent; color: inherit; padding: 0; }\nblockquote { border-left: 3px solid #58a6ff; padding: 12px 20px; margin: 16px 0;\n background: #161b22; color: #8b949e;\n border-radius: 0 8px 8px 0; }\na { color: #58a6ff; text-decoration: none; }\na:hover { text-decoration: underline; }\n.label { display: inline-block; padding: 2px 8px; border-radius: 12px; font-size: 11px;\n font-weight: 500; border: 1px solid #30363d; color: #8b949e; margin: 2px 4px 2px 0; }";
|
||
|
||
private const string CssColorful = "@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@300;400;600;700;800&display=swap');\n* { margin:0; padding:0; box-sizing:border-box; }\nbody { font-family: 'Nunito', 'Segoe UI', 'Malgun Gothic', sans-serif;\n background: linear-gradient(135deg, #ffecd2 0%, #fcb69f 50%, #ffecd2 100%);\n min-height: 100vh; color: #2d3436; line-height: 1.75; padding: 48px 24px; }\n.container { max-width: 880px; margin: 0 auto; background: #fff;\n border-radius: 20px; padding: 52px;\n box-shadow: 0 12px 40px rgba(0,0,0,0.08); }\nh1 { font-size: 30px; font-weight: 800; color: #e17055; margin-bottom: 4px; }\nh2 { font-size: 20px; font-weight: 700; margin: 34px 0 14px; color: #6c5ce7;\n padding: 6px 14px; background: #f8f0ff; border-radius: 8px; display: inline-block; }\nh3 { font-size: 16px; font-weight: 700; margin: 22px 0 10px; color: #00b894; }\n.meta { font-size: 12px; color: #b2bec3; margin-bottom: 28px; }\np { margin: 10px 0; font-size: 14.5px; }\ntable { width: 100%; border-collapse: separate; border-spacing: 0; margin: 18px 0;\n font-size: 13.5px; border-radius: 14px; overflow: hidden;\n box-shadow: 0 2px 8px rgba(108,92,231,0.1); }\nth { background: linear-gradient(135deg, #a29bfe, #6c5ce7); color: #fff;\n text-align: left; padding: 12px 14px; font-weight: 700; }\ntd { padding: 10px 14px; border-bottom: 1px solid #f0f0f0; }\ntr:hover td { background: #faf0ff; }\nul, ol { margin: 10px 0 10px 28px; font-size: 14.5px; }\nli { margin: 5px 0; }\nli::marker { color: #e17055; font-weight: 700; }\ncode { background: #fff3e0; padding: 2px 8px; border-radius: 6px; font-size: 13px;\n font-family: Consolas, monospace; color: #e17055; }\npre { background: #2d3436; color: #dfe6e9; padding: 20px; border-radius: 14px;\n overflow-x: auto; font-size: 13px; margin: 16px 0; }\npre code { background: transparent; color: inherit; padding: 0; }\nblockquote { border-left: 4px solid #fdcb6e; padding: 14px 20px; margin: 16px 0;\n background: #fffbf0; border-radius: 0 12px 12px 0; color: #636e72; }\n.chip { display: inline-block; padding: 4px 14px; border-radius: 20px; font-size: 12px;\n font-weight: 700; color: #fff; margin: 3px 4px 3px 0; }\n.chip-red { background: #e17055; } .chip-blue { background: #74b9ff; }\n.chip-green { background: #00b894; } .chip-purple { background: #6c5ce7; }\n.chip-yellow { background: #fdcb6e; color: #2d3436; }";
|
||
|
||
private const string CssCorporate = "* { margin:0; padding:0; box-sizing:border-box; }\nbody { font-family: 'Segoe UI', 'Malgun Gothic', Arial, sans-serif;\n background: #f2f2f2; color: #333; line-height: 1.65; padding: 32px 20px; }\n.container { max-width: 900px; margin: 0 auto; background: #fff; padding: 0;\n box-shadow: 0 1px 4px rgba(0,0,0,0.1); }\n.header-bar { background: #003366; color: #fff; padding: 28px 40px 20px;\n border-bottom: 3px solid #ff6600; }\n.header-bar h1 { font-size: 22px; font-weight: 700; color: #fff; margin-bottom: 2px; }\n.header-bar .meta { color: rgba(255,255,255,0.7); margin-bottom: 0; font-size: 12px; }\n.body-content { padding: 36px 40px 40px; }\nh1 { font-size: 22px; font-weight: 700; color: #003366; margin-bottom: 4px; }\nh2 { font-size: 17px; font-weight: 600; margin: 28px 0 10px; color: #003366;\n border-left: 4px solid #ff6600; padding-left: 12px; }\nh3 { font-size: 14.5px; font-weight: 600; margin: 20px 0 8px; color: #004488; }\n.meta { font-size: 11.5px; color: #999; margin-bottom: 20px; }\np { margin: 8px 0; font-size: 13.5px; }\ntable { width: 100%; border-collapse: collapse; margin: 14px 0; font-size: 12.5px;\n border: 1px solid #ddd; }\nth { background: #003366; color: #fff; text-align: left; padding: 8px 12px;\n font-weight: 600; font-size: 11.5px; }\ntd { padding: 7px 12px; border: 1px solid #e0e0e0; }\ntr:nth-child(even) td { background: #f9f9f9; }\nul, ol { margin: 8px 0 8px 24px; font-size: 13.5px; }\nli { margin: 3px 0; }\ncode { background: #f4f4f4; padding: 1px 5px; border-radius: 3px; font-size: 12px;\n font-family: Consolas, monospace; }\npre { background: #f4f4f4; color: #333; padding: 14px; border-radius: 4px;\n overflow-x: auto; font-size: 12px; margin: 12px 0; border: 1px solid #ddd; }\npre code { background: transparent; padding: 0; }\nblockquote { border-left: 4px solid #ff6600; padding: 10px 16px; margin: 12px 0;\n background: #fff8f0; color: #555; }\n.footer { text-align: center; font-size: 10.5px; color: #aaa; margin-top: 32px;\n padding-top: 12px; border-top: 1px solid #eee; }\n.stamp { display: inline-block; border: 2px solid #003366; color: #003366; padding: 4px 16px;\n border-radius: 4px; font-size: 11px; font-weight: 700; text-transform: uppercase;\n letter-spacing: 1px; }";
|
||
|
||
private const string CssMagazine = "@import url('https://fonts.googleapis.com/css2?family=Merriweather:wght@300;400;700;900&family=Open+Sans:wght@300;400;600;700&display=swap');\n* { margin:0; padding:0; box-sizing:border-box; }\nbody { font-family: 'Open Sans', 'Malgun Gothic', sans-serif;\n background: #f0ece3; color: #2c2c2c; line-height: 1.7; padding: 48px 24px; }\n.container { max-width: 900px; margin: 0 auto; background: #fff;\n border-radius: 2px; padding: 0; overflow: hidden;\n box-shadow: 0 4px 16px rgba(0,0,0,0.08); }\n.hero { background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);\n padding: 48px 44px 36px; color: #fff; }\n.hero h1 { font-family: 'Merriweather', Georgia, serif; font-size: 32px; font-weight: 900;\n line-height: 1.3; margin-bottom: 8px; }\n.hero .meta { color: rgba(255,255,255,0.6); margin-bottom: 0; font-size: 13px; }\n.content { padding: 40px 44px 44px; }\nh1 { font-family: 'Merriweather', Georgia, serif; font-size: 28px; font-weight: 900;\n color: #1a1a2e; margin-bottom: 4px; }\nh2 { font-family: 'Merriweather', Georgia, serif; font-size: 20px; font-weight: 700;\n margin: 36px 0 14px; color: #1a1a2e; }\nh3 { font-size: 15px; font-weight: 700; margin: 24px 0 10px; color: #e94560;\n text-transform: uppercase; letter-spacing: 1px; font-size: 12px; }\n.meta { font-size: 12px; color: #999; margin-bottom: 24px; }\np { margin: 10px 0; font-size: 15px; }\np:first-of-type::first-letter { font-family: 'Merriweather', Georgia, serif;\n font-size: 48px; float: left; line-height: 1; padding-right: 8px; color: #e94560;\n font-weight: 900; }\ntable { width: 100%; border-collapse: collapse; margin: 18px 0; font-size: 13.5px; }\nth { background: #1a1a2e; color: #fff; text-align: left; padding: 10px 14px;\n font-weight: 600; }\ntd { padding: 9px 14px; border-bottom: 1px solid #eee; }\ntr:hover td { background: #fafafa; }\nul, ol { margin: 10px 0 10px 28px; font-size: 14.5px; }\nli { margin: 5px 0; }\ncode { background: #f5f5f5; padding: 2px 6px; border-radius: 3px; font-size: 12.5px;\n font-family: 'Courier New', monospace; }\npre { background: #1a1a2e; color: #e0e0e0; padding: 18px; border-radius: 4px;\n overflow-x: auto; font-size: 12.5px; margin: 16px 0; }\npre code { background: transparent; color: inherit; padding: 0; }\nblockquote { font-family: 'Merriweather', Georgia, serif; font-size: 18px;\n font-style: italic; color: #555; border: none; padding: 20px 0; margin: 24px 0;\n text-align: center; position: relative; }\nblockquote::before { content: '\\201C'; font-size: 60px; color: #e94560;\n position: absolute; top: -10px; left: 50%; transform: translateX(-50%);\n opacity: 0.3; }\n.pullquote { font-size: 20px; font-family: 'Merriweather', Georgia, serif;\n font-weight: 700; color: #e94560; border-top: 3px solid #e94560;\n border-bottom: 3px solid #e94560; padding: 16px 0; margin: 24px 0;\n text-align: center; }";
|
||
|
||
private const string CssDashboard = "@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');\n* { margin:0; padding:0; box-sizing:border-box; }\nbody { font-family: 'Inter', 'Segoe UI', 'Malgun Gothic', sans-serif;\n background: #f0f2f5; color: #1a1a2e; line-height: 1.6; padding: 32px 24px; }\n.container { max-width: 1000px; margin: 0 auto; padding: 0; background: transparent; }\nh1 { font-size: 26px; font-weight: 700; color: #1a1a2e; margin-bottom: 4px; }\nh2 { font-size: 17px; font-weight: 600; margin: 28px 0 14px; color: #1a1a2e; }\nh3 { font-size: 14px; font-weight: 600; margin: 18px 0 8px; color: #6c7893; }\n.meta { font-size: 12px; color: #8c95a6; margin-bottom: 24px; }\np { margin: 8px 0; font-size: 13.5px; color: #4a5568; }\n.kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px; margin: 20px 0; }\n.kpi-card { background: #fff; border-radius: 12px; padding: 20px;\n box-shadow: 0 1px 4px rgba(0,0,0,0.06); }\n.kpi-card .kpi-label { font-size: 12px; color: #8c95a6; font-weight: 500;\n text-transform: uppercase; letter-spacing: 0.5px; }\n.kpi-card .kpi-value { font-size: 28px; font-weight: 700; color: #1a1a2e; margin: 4px 0; }\n.kpi-card .kpi-change { font-size: 12px; font-weight: 600; }\n.kpi-up { color: #10b981; } .kpi-down { color: #ef4444; }\n.chart-area { background: #fff; border-radius: 12px; padding: 24px; margin: 16px 0;\n box-shadow: 0 1px 4px rgba(0,0,0,0.06); min-height: 200px; }\ntable { width: 100%; border-collapse: collapse; margin: 16px 0; font-size: 13px;\n background: #fff; border-radius: 10px; overflow: hidden;\n box-shadow: 0 1px 4px rgba(0,0,0,0.06); }\nth { background: #f7f8fa; text-align: left; padding: 10px 14px; font-weight: 600;\n color: #6c7893; font-size: 11.5px; text-transform: uppercase; letter-spacing: 0.5px;\n border-bottom: 1px solid #edf0f4; }\ntd { padding: 10px 14px; border-bottom: 1px solid #f3f4f6; }\ntr:hover td { background: #f9fafb; }\nul, ol { margin: 8px 0 8px 24px; font-size: 13.5px; }\nli { margin: 4px 0; }\ncode { background: #f1f3f5; padding: 2px 7px; border-radius: 5px; font-size: 12px;\n font-family: 'JetBrains Mono', Consolas, monospace; }\npre { background: #1a1a2e; color: #c9d1d9; padding: 18px; border-radius: 10px;\n overflow-x: auto; font-size: 12px; margin: 14px 0; }\npre code { background: transparent; color: inherit; padding: 0; }\nblockquote { border-left: 3px solid #4b5efc; padding: 10px 16px; margin: 14px 0;\n background: #f0f0ff; border-radius: 0 8px 8px 0; font-size: 13px; }\n.status-badge { display: inline-block; padding: 2px 10px; border-radius: 12px;\n font-size: 11px; font-weight: 600; }\n.status-ok { background: #d1fae5; color: #065f46; }\n.status-warn { background: #fef3c7; color: #92400e; }\n.status-err { background: #fee2e2; color: #991b1b; }";
|
||
|
||
private const string CssShared = "\n/* ── 목차 (TOC) ── */\nnav.toc { background: #f8f9fa; border: 1px solid #e9ecef; border-radius: 10px;\n padding: 20px 28px; margin: 24px 0 32px; }\nnav.toc h2 { font-size: 15px; font-weight: 700; margin: 0 0 12px; padding: 0; border: none;\n color: inherit; display: block; background: none; }\nnav.toc ul { list-style: none; margin: 0; padding: 0; }\nnav.toc li { margin: 4px 0; }\nnav.toc li.toc-h3 { padding-left: 18px; }\nnav.toc a { text-decoration: none; color: #4b5efc; font-size: 13.5px; }\nnav.toc a:hover { text-decoration: underline; }\n\n/* ── 커버 페이지 ── */\n.cover-page { text-align: center; padding: 80px 40px 60px; margin: -56px -52px 40px;\n border-radius: 16px 16px 0 0; position: relative; overflow: hidden;\n background: linear-gradient(135deg, #4b5efc 0%, #7c3aed 100%); color: #fff; }\n.cover-page h1 { font-size: 36px; font-weight: 800; margin-bottom: 12px; color: #fff;\n -webkit-text-fill-color: #fff; }\n.cover-page .cover-subtitle { font-size: 18px; opacity: 0.9; margin-bottom: 24px; }\n.cover-page .cover-meta { font-size: 13px; opacity: 0.7; }\n.cover-page .cover-divider { width: 60px; height: 3px; background: rgba(255,255,255,0.5);\n margin: 20px auto; border-radius: 2px; }\n\n/* ── 콜아웃 (callout) ── */\n.callout { border-radius: 8px; padding: 16px 20px; margin: 16px 0; font-size: 14px;\n border-left: 4px solid; display: flex; gap: 10px; align-items: flex-start; }\n.callout::before { font-size: 16px; flex-shrink: 0; margin-top: 1px; }\n.callout-info { background: #eff6ff; border-color: #3b82f6; color: #1e40af; }\n.callout-info::before { content: 'ℹ\ufe0f'; }\n.callout-warning { background: #fffbeb; border-color: #f59e0b; color: #92400e; }\n.callout-warning::before { content: '⚠\ufe0f'; }\n.callout-tip { background: #f0fdf4; border-color: #22c55e; color: #166534; }\n.callout-tip::before { content: '\ud83d\udca1'; }\n.callout-danger { background: #fef2f2; border-color: #ef4444; color: #991b1b; }\n.callout-danger::before { content: '\ud83d\udea8'; }\n.callout-note { background: #f5f3ff; border-color: #8b5cf6; color: #5b21b6; }\n.callout-note::before { content: '\ud83d\udcdd'; }\n\n/* ── 배지 (badge) — 공통 ── */\n.badge, .tag, .chip { display: inline-block; padding: 3px 10px; border-radius: 20px;\n font-size: 11px; font-weight: 600; margin: 2px 4px 2px 0; }\n.badge-blue { background: #dbeafe; color: #1e40af; }\n.badge-green { background: #d1fae5; color: #065f46; }\n.badge-red { background: #fee2e2; color: #991b1b; }\n.badge-yellow { background: #fef3c7; color: #92400e; }\n.badge-purple { background: #ede9fe; color: #5b21b6; }\n.badge-gray { background: #f3f4f6; color: #374151; }\n.badge-orange { background: #ffedd5; color: #9a3412; }\n\n/* ── 하이라이트 박스 ── */\n.highlight-box { background: linear-gradient(120deg, #e0f0ff 0%, #f0e0ff 100%);\n padding: 16px 20px; border-radius: 10px; margin: 16px 0; }\n\n/* ── CSS 차트 (bar/horizontal) ── */\n.chart-bar { margin: 20px 0; }\n.chart-bar .bar-item { display: flex; align-items: center; margin: 6px 0; gap: 10px; }\n.chart-bar .bar-label { min-width: 100px; font-size: 13px; text-align: right; flex-shrink: 0; }\n.chart-bar .bar-track { flex: 1; background: #e5e7eb; border-radius: 6px; height: 22px;\n overflow: hidden; }\n.chart-bar .bar-fill { height: 100%; border-radius: 6px; display: flex; align-items: center;\n padding: 0 8px; font-size: 11px; font-weight: 600; color: #fff;\n transition: width 0.3s ease; min-width: fit-content; }\n.bar-fill.blue { background: #3b82f6; } .bar-fill.green { background: #22c55e; }\n.bar-fill.red { background: #ef4444; } .bar-fill.yellow { background: #f59e0b; }\n.bar-fill.purple { background: #8b5cf6; } .bar-fill.orange { background: #f97316; }\n\n/* ── CSS 도넛 차트 ── */\n.chart-donut { width: 160px; height: 160px; border-radius: 50%; margin: 20px auto;\n background: conic-gradient(var(--seg1-color, #3b82f6) 0% var(--seg1, 0%),\n var(--seg2-color, #22c55e) var(--seg1, 0%) var(--seg2, 0%),\n var(--seg3-color, #f59e0b) var(--seg2, 0%) var(--seg3, 0%),\n var(--seg4-color, #ef4444) var(--seg3, 0%) var(--seg4, 0%),\n #e5e7eb var(--seg4, 0%) 100%);\n display: flex; align-items: center; justify-content: center; position: relative; }\n.chart-donut::after { content: ''; width: 100px; height: 100px; background: #fff;\n border-radius: 50%; position: absolute; }\n.chart-donut .donut-label { position: absolute; z-index: 1; font-size: 18px; font-weight: 700; }\n\n/* ── 진행률 바 ── */\n.progress { background: #e5e7eb; border-radius: 8px; height: 10px; margin: 8px 0;\n overflow: hidden; }\n.progress-fill { height: 100%; border-radius: 8px; background: #3b82f6; }\n\n/* ── 타임라인 ── */\n.timeline { position: relative; padding-left: 28px; margin: 20px 0; }\n.timeline::before { content: ''; position: absolute; left: 8px; top: 0; bottom: 0;\n width: 2px; background: #e5e7eb; }\n.timeline-item { position: relative; margin: 16px 0; }\n.timeline-item::before { content: ''; position: absolute; left: -24px; top: 5px;\n width: 12px; height: 12px; border-radius: 50%; background: #4b5efc;\n border: 2px solid #fff; box-shadow: 0 0 0 2px #4b5efc; }\n.timeline-item .timeline-date { font-size: 12px; color: #6b7280; font-weight: 600; }\n.timeline-item .timeline-content { font-size: 14px; margin-top: 4px; }\n\n/* ── 섹션 자동 번호 ── */\nbody { counter-reset: section; }\nh2.numbered { counter-increment: section; counter-reset: subsection; }\nh2.numbered::before { content: counter(section) '. '; }\nh3.numbered { counter-increment: subsection; }\nh3.numbered::before { content: counter(section) '-' counter(subsection) '. '; }\n\n/* ── 그리드 레이아웃 ── */\n.grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; margin: 16px 0; }\n.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin: 16px 0; }\n.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin: 16px 0; }\n\n/* ── 카드 공통 ── */\n.card { background: #fff; border: 1px solid #e5e7eb; border-radius: 12px;\n padding: 20px; box-shadow: 0 1px 3px rgba(0,0,0,0.06); }\n.card-header { font-size: 15px; font-weight: 700; margin-bottom: 8px; }\n\n/* ── 구분선 ── */\n.divider { border: none; border-top: 1px solid #e5e7eb; margin: 32px 0; }\n.divider-thick { border: none; border-top: 3px solid #e5e7eb; margin: 40px 0; }\n\n/* ── 인쇄/PDF 최적화 ── */\n@media print {\n body { background: #fff !important; padding: 0 !important; }\n .container { box-shadow: none !important; border: none !important;\n max-width: none !important; padding: 20px !important; }\n .cover-page { break-after: page; }\n h2, h3 { break-after: avoid; }\n table, figure, .chart-bar, .callout { break-inside: avoid; }\n nav.toc { break-after: page; }\n a { color: inherit !important; text-decoration: none !important; }\n a[href]::after { content: ' (' attr(href) ')'; font-size: 10px; color: #999; }\n .no-print { display: none !important; }\n}";
|
||
|
||
public static IReadOnlyList<TemplateMood> AllMoods
|
||
{
|
||
get
|
||
{
|
||
List<TemplateMood> list = new List<TemplateMood>(AvailableMoods);
|
||
foreach (CustomMoodEntry value in _customMoods.Values)
|
||
{
|
||
list.Add(new TemplateMood(value.Key, value.Label, value.Icon, value.Description));
|
||
}
|
||
return list;
|
||
}
|
||
}
|
||
|
||
public static void LoadCustomMoods(IEnumerable<CustomMoodEntry> entries)
|
||
{
|
||
_customMoods.Clear();
|
||
foreach (CustomMoodEntry entry in entries)
|
||
{
|
||
if (!string.IsNullOrWhiteSpace(entry.Key))
|
||
{
|
||
_customMoods[entry.Key] = entry;
|
||
}
|
||
}
|
||
}
|
||
|
||
public static string GetCss(string moodKey)
|
||
{
|
||
if (_customMoods.TryGetValue(moodKey, out CustomMoodEntry value))
|
||
{
|
||
return value.Css + "\n\n/* ── 목차 (TOC) ── */\nnav.toc { background: #f8f9fa; border: 1px solid #e9ecef; border-radius: 10px;\n padding: 20px 28px; margin: 24px 0 32px; }\nnav.toc h2 { font-size: 15px; font-weight: 700; margin: 0 0 12px; padding: 0; border: none;\n color: inherit; display: block; background: none; }\nnav.toc ul { list-style: none; margin: 0; padding: 0; }\nnav.toc li { margin: 4px 0; }\nnav.toc li.toc-h3 { padding-left: 18px; }\nnav.toc a { text-decoration: none; color: #4b5efc; font-size: 13.5px; }\nnav.toc a:hover { text-decoration: underline; }\n\n/* ── 커버 페이지 ── */\n.cover-page { text-align: center; padding: 80px 40px 60px; margin: -56px -52px 40px;\n border-radius: 16px 16px 0 0; position: relative; overflow: hidden;\n background: linear-gradient(135deg, #4b5efc 0%, #7c3aed 100%); color: #fff; }\n.cover-page h1 { font-size: 36px; font-weight: 800; margin-bottom: 12px; color: #fff;\n -webkit-text-fill-color: #fff; }\n.cover-page .cover-subtitle { font-size: 18px; opacity: 0.9; margin-bottom: 24px; }\n.cover-page .cover-meta { font-size: 13px; opacity: 0.7; }\n.cover-page .cover-divider { width: 60px; height: 3px; background: rgba(255,255,255,0.5);\n margin: 20px auto; border-radius: 2px; }\n\n/* ── 콜아웃 (callout) ── */\n.callout { border-radius: 8px; padding: 16px 20px; margin: 16px 0; font-size: 14px;\n border-left: 4px solid; display: flex; gap: 10px; align-items: flex-start; }\n.callout::before { font-size: 16px; flex-shrink: 0; margin-top: 1px; }\n.callout-info { background: #eff6ff; border-color: #3b82f6; color: #1e40af; }\n.callout-info::before { content: 'ℹ\ufe0f'; }\n.callout-warning { background: #fffbeb; border-color: #f59e0b; color: #92400e; }\n.callout-warning::before { content: '⚠\ufe0f'; }\n.callout-tip { background: #f0fdf4; border-color: #22c55e; color: #166534; }\n.callout-tip::before { content: '\ud83d\udca1'; }\n.callout-danger { background: #fef2f2; border-color: #ef4444; color: #991b1b; }\n.callout-danger::before { content: '\ud83d\udea8'; }\n.callout-note { background: #f5f3ff; border-color: #8b5cf6; color: #5b21b6; }\n.callout-note::before { content: '\ud83d\udcdd'; }\n\n/* ── 배지 (badge) — 공통 ── */\n.badge, .tag, .chip { display: inline-block; padding: 3px 10px; border-radius: 20px;\n font-size: 11px; font-weight: 600; margin: 2px 4px 2px 0; }\n.badge-blue { background: #dbeafe; color: #1e40af; }\n.badge-green { background: #d1fae5; color: #065f46; }\n.badge-red { background: #fee2e2; color: #991b1b; }\n.badge-yellow { background: #fef3c7; color: #92400e; }\n.badge-purple { background: #ede9fe; color: #5b21b6; }\n.badge-gray { background: #f3f4f6; color: #374151; }\n.badge-orange { background: #ffedd5; color: #9a3412; }\n\n/* ── 하이라이트 박스 ── */\n.highlight-box { background: linear-gradient(120deg, #e0f0ff 0%, #f0e0ff 100%);\n padding: 16px 20px; border-radius: 10px; margin: 16px 0; }\n\n/* ── CSS 차트 (bar/horizontal) ── */\n.chart-bar { margin: 20px 0; }\n.chart-bar .bar-item { display: flex; align-items: center; margin: 6px 0; gap: 10px; }\n.chart-bar .bar-label { min-width: 100px; font-size: 13px; text-align: right; flex-shrink: 0; }\n.chart-bar .bar-track { flex: 1; background: #e5e7eb; border-radius: 6px; height: 22px;\n overflow: hidden; }\n.chart-bar .bar-fill { height: 100%; border-radius: 6px; display: flex; align-items: center;\n padding: 0 8px; font-size: 11px; font-weight: 600; color: #fff;\n transition: width 0.3s ease; min-width: fit-content; }\n.bar-fill.blue { background: #3b82f6; } .bar-fill.green { background: #22c55e; }\n.bar-fill.red { background: #ef4444; } .bar-fill.yellow { background: #f59e0b; }\n.bar-fill.purple { background: #8b5cf6; } .bar-fill.orange { background: #f97316; }\n\n/* ── CSS 도넛 차트 ── */\n.chart-donut { width: 160px; height: 160px; border-radius: 50%; margin: 20px auto;\n background: conic-gradient(var(--seg1-color, #3b82f6) 0% var(--seg1, 0%),\n var(--seg2-color, #22c55e) var(--seg1, 0%) var(--seg2, 0%),\n var(--seg3-color, #f59e0b) var(--seg2, 0%) var(--seg3, 0%),\n var(--seg4-color, #ef4444) var(--seg3, 0%) var(--seg4, 0%),\n #e5e7eb var(--seg4, 0%) 100%);\n display: flex; align-items: center; justify-content: center; position: relative; }\n.chart-donut::after { content: ''; width: 100px; height: 100px; background: #fff;\n border-radius: 50%; position: absolute; }\n.chart-donut .donut-label { position: absolute; z-index: 1; font-size: 18px; font-weight: 700; }\n\n/* ── 진행률 바 ── */\n.progress { background: #e5e7eb; border-radius: 8px; height: 10px; margin: 8px 0;\n overflow: hidden; }\n.progress-fill { height: 100%; border-radius: 8px; background: #3b82f6; }\n\n/* ── 타임라인 ── */\n.timeline { position: relative; padding-left: 28px; margin: 20px 0; }\n.timeline::before { content: ''; position: absolute; left: 8px; top: 0; bottom: 0;\n width: 2px; background: #e5e7eb; }\n.timeline-item { position: relative; margin: 16px 0; }\n.timeline-item::before { content: ''; position: absolute; left: -24px; top: 5px;\n width: 12px; height: 12px; border-radius: 50%; background: #4b5efc;\n border: 2px solid #fff; box-shadow: 0 0 0 2px #4b5efc; }\n.timeline-item .timeline-date { font-size: 12px; color: #6b7280; font-weight: 600; }\n.timeline-item .timeline-content { font-size: 14px; margin-top: 4px; }\n\n/* ── 섹션 자동 번호 ── */\nbody { counter-reset: section; }\nh2.numbered { counter-increment: section; counter-reset: subsection; }\nh2.numbered::before { content: counter(section) '. '; }\nh3.numbered { counter-increment: subsection; }\nh3.numbered::before { content: counter(section) '-' counter(subsection) '. '; }\n\n/* ── 그리드 레이아웃 ── */\n.grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; margin: 16px 0; }\n.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin: 16px 0; }\n.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin: 16px 0; }\n\n/* ── 카드 공통 ── */\n.card { background: #fff; border: 1px solid #e5e7eb; border-radius: 12px;\n padding: 20px; box-shadow: 0 1px 3px rgba(0,0,0,0.06); }\n.card-header { font-size: 15px; font-weight: 700; margin-bottom: 8px; }\n\n/* ── 구분선 ── */\n.divider { border: none; border-top: 1px solid #e5e7eb; margin: 32px 0; }\n.divider-thick { border: none; border-top: 3px solid #e5e7eb; margin: 40px 0; }\n\n/* ── 인쇄/PDF 최적화 ── */\n@media print {\n body { background: #fff !important; padding: 0 !important; }\n .container { box-shadow: none !important; border: none !important;\n max-width: none !important; padding: 20px !important; }\n .cover-page { break-after: page; }\n h2, h3 { break-after: avoid; }\n table, figure, .chart-bar, .callout { break-inside: avoid; }\n nav.toc { break-after: page; }\n a { color: inherit !important; text-decoration: none !important; }\n a[href]::after { content: ' (' attr(href) ')'; font-size: 10px; color: #999; }\n .no-print { display: none !important; }\n}";
|
||
}
|
||
if (1 == 0)
|
||
{
|
||
}
|
||
string text = moodKey switch
|
||
{
|
||
"modern" => "@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');\n* { margin:0; padding:0; box-sizing:border-box; }\nbody { font-family: 'Inter', 'Segoe UI', 'Malgun Gothic', sans-serif;\n background: #f5f5f7; color: #1d1d1f; line-height: 1.75; padding: 48px 24px; }\n.container { max-width: 880px; margin: 0 auto; background: #fff;\n border-radius: 16px; padding: 56px 52px;\n box-shadow: 0 4px 24px rgba(0,0,0,0.06); }\nh1 { font-size: 28px; font-weight: 700; letter-spacing: -0.5px; color: #1d1d1f; margin-bottom: 4px; }\nh2 { font-size: 20px; font-weight: 600; margin: 36px 0 14px; color: #1d1d1f;\n padding-bottom: 8px; border-bottom: 2px solid #e5e5ea; }\nh3 { font-size: 16px; font-weight: 600; margin: 24px 0 10px; color: #0071e3; }\n.meta { font-size: 12px; color: #86868b; margin-bottom: 28px; letter-spacing: 0.3px; }\np { margin: 10px 0; font-size: 14.5px; }\ntable { width: 100%; border-collapse: collapse; margin: 20px 0; font-size: 13.5px;\n border-radius: 10px; overflow: hidden; }\nth { background: #f5f5f7; text-align: left; padding: 12px 14px; font-weight: 600;\n color: #1d1d1f; border-bottom: 2px solid #d2d2d7; }\ntd { padding: 10px 14px; border-bottom: 1px solid #f0f0f2; }\ntr:hover td { background: #f9f9fb; }\nul, ol { margin: 10px 0 10px 28px; font-size: 14.5px; }\nli { margin: 5px 0; }\ncode { background: #f5f5f7; padding: 2px 8px; border-radius: 6px; font-size: 13px;\n font-family: 'SF Mono', Consolas, monospace; color: #e3116c; }\npre { background: #1d1d1f; color: #f5f5f7; padding: 20px; border-radius: 12px;\n overflow-x: auto; font-size: 13px; margin: 16px 0; line-height: 1.6; }\npre code { background: transparent; color: inherit; padding: 0; }\nblockquote { border-left: 3px solid #0071e3; padding: 12px 20px; margin: 16px 0;\n background: #f0f7ff; color: #1d1d1f; border-radius: 0 8px 8px 0; font-size: 14px; }\n.highlight { background: linear-gradient(120deg, #e0f0ff 0%, #f0e0ff 100%);\n padding: 16px 20px; border-radius: 10px; margin: 16px 0; }\n.badge { display: inline-block; padding: 3px 10px; border-radius: 20px; font-size: 11px;\n font-weight: 600; background: #0071e3; color: #fff; margin: 2px 4px 2px 0; }",
|
||
"professional" => "* { margin:0; padding:0; box-sizing:border-box; }\nbody { font-family: 'Segoe UI', 'Malgun Gothic', Arial, sans-serif;\n background: #eef1f5; color: #1e293b; line-height: 1.7; padding: 40px 20px; }\n.container { max-width: 900px; margin: 0 auto; background: #fff;\n border-radius: 8px; padding: 48px;\n box-shadow: 0 1px 8px rgba(0,0,0,0.08);\n border-top: 4px solid #1e3a5f; }\nh1 { font-size: 26px; font-weight: 700; color: #1e3a5f; margin-bottom: 4px; }\nh2 { font-size: 18px; font-weight: 600; margin: 32px 0 12px; color: #1e3a5f;\n border-bottom: 2px solid #c8d6e5; padding-bottom: 6px; }\nh3 { font-size: 15px; font-weight: 600; margin: 22px 0 8px; color: #2c5282; }\n.meta { font-size: 12px; color: #94a3b8; margin-bottom: 24px; border-bottom: 1px solid #e2e8f0;\n padding-bottom: 12px; }\np { margin: 8px 0; font-size: 14px; }\ntable { width: 100%; border-collapse: collapse; margin: 16px 0; font-size: 13.5px;\n border: 1px solid #e2e8f0; }\nth { background: #1e3a5f; color: #fff; text-align: left; padding: 10px 14px;\n font-weight: 600; font-size: 12.5px; text-transform: uppercase; letter-spacing: 0.5px; }\ntd { padding: 9px 14px; border-bottom: 1px solid #e2e8f0; }\ntr:nth-child(even) td { background: #f8fafc; }\ntr:hover td { background: #eef2ff; }\nul, ol { margin: 8px 0 8px 24px; }\nli { margin: 4px 0; font-size: 14px; }\ncode { background: #f1f5f9; padding: 2px 6px; border-radius: 4px; font-size: 12.5px;\n font-family: Consolas, monospace; color: #1e3a5f; }\npre { background: #0f172a; color: #e2e8f0; padding: 18px; border-radius: 6px;\n overflow-x: auto; font-size: 12.5px; margin: 14px 0; }\npre code { background: transparent; color: inherit; padding: 0; }\nblockquote { border-left: 4px solid #1e3a5f; padding: 10px 18px; margin: 14px 0;\n background: #f0f4f8; color: #334155; }\n.callout { background: #eff6ff; border: 1px solid #bfdbfe; border-radius: 6px;\n padding: 14px 18px; margin: 14px 0; font-size: 13.5px; }\n.callout strong { color: #1e40af; }",
|
||
"creative" => "@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');\n* { margin:0; padding:0; box-sizing:border-box; }\nbody { font-family: 'Poppins', 'Segoe UI', 'Malgun Gothic', sans-serif;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n min-height: 100vh; color: #2d3748; line-height: 1.75; padding: 48px 24px; }\n.container { max-width: 880px; margin: 0 auto; background: rgba(255,255,255,0.95);\n backdrop-filter: blur(20px); border-radius: 20px; padding: 52px;\n box-shadow: 0 20px 60px rgba(0,0,0,0.15); }\nh1 { font-size: 30px; font-weight: 700;\n background: linear-gradient(135deg, #667eea, #e040fb);\n -webkit-background-clip: text; -webkit-text-fill-color: transparent;\n margin-bottom: 4px; }\nh2 { font-size: 20px; font-weight: 600; margin: 36px 0 14px; color: #553c9a;\n position: relative; padding-left: 16px; }\nh2::before { content: ''; position: absolute; left: 0; top: 4px; width: 4px; height: 22px;\n background: linear-gradient(180deg, #667eea, #e040fb); border-radius: 4px; }\nh3 { font-size: 16px; font-weight: 600; margin: 22px 0 10px; color: #7c3aed; }\n.meta { font-size: 12px; color: #a0aec0; margin-bottom: 28px; }\np { margin: 10px 0; font-size: 14.5px; }\ntable { width: 100%; border-collapse: separate; border-spacing: 0; margin: 18px 0;\n font-size: 13.5px; border-radius: 12px; overflow: hidden;\n box-shadow: 0 4px 12px rgba(102,126,234,0.1); }\nth { background: linear-gradient(135deg, #667eea, #764ba2); color: #fff;\n text-align: left; padding: 12px 14px; font-weight: 600; }\ntd { padding: 10px 14px; border-bottom: 1px solid #f0e7fe; }\ntr:hover td { background: #faf5ff; }\nul, ol { margin: 10px 0 10px 28px; font-size: 14.5px; }\nli { margin: 5px 0; }\nli::marker { color: #7c3aed; }\ncode { background: #f5f3ff; padding: 2px 8px; border-radius: 6px; font-size: 13px;\n font-family: 'Fira Code', Consolas, monospace; color: #7c3aed; }\npre { background: #1a1a2e; color: #e0d4f5; padding: 20px; border-radius: 14px;\n overflow-x: auto; font-size: 13px; margin: 16px 0;\n border: 1px solid rgba(124,58,237,0.2); }\npre code { background: transparent; color: inherit; padding: 0; }\nblockquote { border-left: 4px solid #7c3aed; padding: 14px 20px; margin: 16px 0;\n background: linear-gradient(135deg, #f5f3ff, #faf5ff);\n border-radius: 0 12px 12px 0; font-style: italic; }\n.card { background: #fff; border: 1px solid #e9d8fd; border-radius: 14px;\n padding: 20px; margin: 14px 0; box-shadow: 0 2px 8px rgba(124,58,237,0.08); }\n.tag { display: inline-block; padding: 3px 12px; border-radius: 20px; font-size: 11px;\n font-weight: 500; background: linear-gradient(135deg, #667eea, #764ba2);\n color: #fff; margin: 2px 4px 2px 0; }",
|
||
"minimal" => "* { margin:0; padding:0; box-sizing:border-box; }\nbody { font-family: 'Georgia', 'Batang', serif;\n background: #fff; color: #222; line-height: 1.85; padding: 60px 24px; }\n.container { max-width: 720px; margin: 0 auto; padding: 0; }\nh1 { font-size: 32px; font-weight: 400; color: #000; margin-bottom: 4px;\n letter-spacing: -0.5px; }\nh2 { font-size: 20px; font-weight: 400; margin: 40px 0 14px; color: #000;\n border-bottom: 1px solid #ddd; padding-bottom: 8px; }\nh3 { font-size: 16px; font-weight: 600; margin: 28px 0 10px; color: #333; }\n.meta { font-size: 12px; color: #999; margin-bottom: 36px; font-style: italic; }\np { margin: 12px 0; font-size: 15px; text-align: justify; }\ntable { width: 100%; border-collapse: collapse; margin: 20px 0; font-size: 14px; }\nth { text-align: left; padding: 8px 0; font-weight: 600; border-bottom: 2px solid #000;\n font-size: 12px; text-transform: uppercase; letter-spacing: 1px; color: #555; }\ntd { padding: 8px 0; border-bottom: 1px solid #eee; }\ntr:hover td { background: #fafafa; }\nul, ol { margin: 12px 0 12px 20px; font-size: 15px; }\nli { margin: 6px 0; }\ncode { background: #f7f7f7; padding: 2px 6px; border-radius: 2px; font-size: 13px;\n font-family: 'Courier New', monospace; }\npre { background: #f7f7f7; color: #333; padding: 18px; margin: 16px 0;\n overflow-x: auto; font-size: 13px; border: 1px solid #e5e5e5; }\npre code { background: transparent; padding: 0; }\nblockquote { border-left: 3px solid #000; padding: 8px 20px; margin: 16px 0;\n color: #555; font-style: italic; }\nhr { border: none; border-top: 1px solid #ddd; margin: 32px 0; }",
|
||
"elegant" => "@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;500;600;700&family=Source+Sans+3:wght@300;400;600&display=swap');\n* { margin:0; padding:0; box-sizing:border-box; }\nbody { font-family: 'Source Sans 3', 'Malgun Gothic', sans-serif;\n background: #faf8f5; color: #3d3929; line-height: 1.75; padding: 48px 24px; }\n.container { max-width: 860px; margin: 0 auto; background: #fff;\n border-radius: 4px; padding: 56px 52px;\n box-shadow: 0 1px 4px rgba(0,0,0,0.06);\n border: 1px solid #e8e4dd; }\nh1 { font-family: 'Playfair Display', Georgia, serif; font-size: 30px;\n font-weight: 700; color: #2c2416; margin-bottom: 6px; letter-spacing: -0.3px; }\nh2 { font-family: 'Playfair Display', Georgia, serif; font-size: 20px;\n font-weight: 600; margin: 36px 0 14px; color: #2c2416;\n border-bottom: 1px solid #d4c9b8; padding-bottom: 8px; }\nh3 { font-size: 15px; font-weight: 600; margin: 24px 0 10px; color: #8b7a5e; }\n.meta { font-size: 12px; color: #b0a48e; margin-bottom: 28px; letter-spacing: 0.5px;\n text-transform: uppercase; }\np { margin: 10px 0; font-size: 14.5px; }\ntable { width: 100%; border-collapse: collapse; margin: 18px 0; font-size: 13.5px; }\nth { background: #f8f5f0; text-align: left; padding: 10px 14px; font-weight: 600;\n color: #5a4d38; border-bottom: 2px solid #d4c9b8; font-size: 12.5px;\n letter-spacing: 0.5px; }\ntd { padding: 9px 14px; border-bottom: 1px solid #f0ece5; }\ntr:hover td { background: #fdfcfa; }\nul, ol { margin: 10px 0 10px 26px; font-size: 14.5px; }\nli { margin: 5px 0; }\ncode { background: #f8f5f0; padding: 2px 7px; border-radius: 3px; font-size: 12.5px;\n font-family: 'Courier New', monospace; color: #8b6914; }\npre { background: #2c2416; color: #e8e0d0; padding: 18px; border-radius: 4px;\n overflow-x: auto; font-size: 12.5px; margin: 16px 0; }\npre code { background: transparent; color: inherit; padding: 0; }\nblockquote { border-left: 3px solid #c9a96e; padding: 12px 20px; margin: 16px 0;\n background: #fdf9f0; color: #5a4d38; font-style: italic;\n font-family: 'Playfair Display', Georgia, serif; }\n.ornament { text-align: center; color: #c9a96e; font-size: 18px; margin: 24px 0; letter-spacing: 8px; }",
|
||
"dark" => "@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&family=Inter:wght@300;400;500;600;700&display=swap');\n* { margin:0; padding:0; box-sizing:border-box; }\nbody { font-family: 'Inter', 'Segoe UI', 'Malgun Gothic', sans-serif;\n background: #0d1117; color: #e6edf3; line-height: 1.75; padding: 48px 24px; }\n.container { max-width: 880px; margin: 0 auto; background: #161b22;\n border-radius: 12px; padding: 52px;\n border: 1px solid #30363d;\n box-shadow: 0 8px 32px rgba(0,0,0,0.3); }\nh1 { font-size: 28px; font-weight: 700; color: #f0f6fc; margin-bottom: 4px; }\nh2 { font-size: 20px; font-weight: 600; margin: 36px 0 14px; color: #f0f6fc;\n border-bottom: 1px solid #30363d; padding-bottom: 8px; }\nh3 { font-size: 16px; font-weight: 600; margin: 24px 0 10px; color: #58a6ff; }\n.meta { font-size: 12px; color: #8b949e; margin-bottom: 28px; }\np { margin: 10px 0; font-size: 14.5px; color: #c9d1d9; }\ntable { width: 100%; border-collapse: collapse; margin: 18px 0; font-size: 13.5px;\n border: 1px solid #30363d; border-radius: 8px; overflow: hidden; }\nth { background: #21262d; text-align: left; padding: 10px 14px; font-weight: 600;\n color: #f0f6fc; border-bottom: 1px solid #30363d; }\ntd { padding: 9px 14px; border-bottom: 1px solid #21262d; color: #c9d1d9; }\ntr:hover td { background: #1c2128; }\nul, ol { margin: 10px 0 10px 28px; font-size: 14.5px; color: #c9d1d9; }\nli { margin: 5px 0; }\ncode { background: #1c2128; padding: 2px 8px; border-radius: 6px; font-size: 13px;\n font-family: 'JetBrains Mono', Consolas, monospace; color: #79c0ff; }\npre { background: #0d1117; color: #c9d1d9; padding: 20px; border-radius: 8px;\n overflow-x: auto; font-size: 13px; margin: 16px 0;\n border: 1px solid #30363d; }\npre code { background: transparent; color: inherit; padding: 0; }\nblockquote { border-left: 3px solid #58a6ff; padding: 12px 20px; margin: 16px 0;\n background: #161b22; color: #8b949e;\n border-radius: 0 8px 8px 0; }\na { color: #58a6ff; text-decoration: none; }\na:hover { text-decoration: underline; }\n.label { display: inline-block; padding: 2px 8px; border-radius: 12px; font-size: 11px;\n font-weight: 500; border: 1px solid #30363d; color: #8b949e; margin: 2px 4px 2px 0; }",
|
||
"colorful" => "@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@300;400;600;700;800&display=swap');\n* { margin:0; padding:0; box-sizing:border-box; }\nbody { font-family: 'Nunito', 'Segoe UI', 'Malgun Gothic', sans-serif;\n background: linear-gradient(135deg, #ffecd2 0%, #fcb69f 50%, #ffecd2 100%);\n min-height: 100vh; color: #2d3436; line-height: 1.75; padding: 48px 24px; }\n.container { max-width: 880px; margin: 0 auto; background: #fff;\n border-radius: 20px; padding: 52px;\n box-shadow: 0 12px 40px rgba(0,0,0,0.08); }\nh1 { font-size: 30px; font-weight: 800; color: #e17055; margin-bottom: 4px; }\nh2 { font-size: 20px; font-weight: 700; margin: 34px 0 14px; color: #6c5ce7;\n padding: 6px 14px; background: #f8f0ff; border-radius: 8px; display: inline-block; }\nh3 { font-size: 16px; font-weight: 700; margin: 22px 0 10px; color: #00b894; }\n.meta { font-size: 12px; color: #b2bec3; margin-bottom: 28px; }\np { margin: 10px 0; font-size: 14.5px; }\ntable { width: 100%; border-collapse: separate; border-spacing: 0; margin: 18px 0;\n font-size: 13.5px; border-radius: 14px; overflow: hidden;\n box-shadow: 0 2px 8px rgba(108,92,231,0.1); }\nth { background: linear-gradient(135deg, #a29bfe, #6c5ce7); color: #fff;\n text-align: left; padding: 12px 14px; font-weight: 700; }\ntd { padding: 10px 14px; border-bottom: 1px solid #f0f0f0; }\ntr:hover td { background: #faf0ff; }\nul, ol { margin: 10px 0 10px 28px; font-size: 14.5px; }\nli { margin: 5px 0; }\nli::marker { color: #e17055; font-weight: 700; }\ncode { background: #fff3e0; padding: 2px 8px; border-radius: 6px; font-size: 13px;\n font-family: Consolas, monospace; color: #e17055; }\npre { background: #2d3436; color: #dfe6e9; padding: 20px; border-radius: 14px;\n overflow-x: auto; font-size: 13px; margin: 16px 0; }\npre code { background: transparent; color: inherit; padding: 0; }\nblockquote { border-left: 4px solid #fdcb6e; padding: 14px 20px; margin: 16px 0;\n background: #fffbf0; border-radius: 0 12px 12px 0; color: #636e72; }\n.chip { display: inline-block; padding: 4px 14px; border-radius: 20px; font-size: 12px;\n font-weight: 700; color: #fff; margin: 3px 4px 3px 0; }\n.chip-red { background: #e17055; } .chip-blue { background: #74b9ff; }\n.chip-green { background: #00b894; } .chip-purple { background: #6c5ce7; }\n.chip-yellow { background: #fdcb6e; color: #2d3436; }",
|
||
"corporate" => "* { margin:0; padding:0; box-sizing:border-box; }\nbody { font-family: 'Segoe UI', 'Malgun Gothic', Arial, sans-serif;\n background: #f2f2f2; color: #333; line-height: 1.65; padding: 32px 20px; }\n.container { max-width: 900px; margin: 0 auto; background: #fff; padding: 0;\n box-shadow: 0 1px 4px rgba(0,0,0,0.1); }\n.header-bar { background: #003366; color: #fff; padding: 28px 40px 20px;\n border-bottom: 3px solid #ff6600; }\n.header-bar h1 { font-size: 22px; font-weight: 700; color: #fff; margin-bottom: 2px; }\n.header-bar .meta { color: rgba(255,255,255,0.7); margin-bottom: 0; font-size: 12px; }\n.body-content { padding: 36px 40px 40px; }\nh1 { font-size: 22px; font-weight: 700; color: #003366; margin-bottom: 4px; }\nh2 { font-size: 17px; font-weight: 600; margin: 28px 0 10px; color: #003366;\n border-left: 4px solid #ff6600; padding-left: 12px; }\nh3 { font-size: 14.5px; font-weight: 600; margin: 20px 0 8px; color: #004488; }\n.meta { font-size: 11.5px; color: #999; margin-bottom: 20px; }\np { margin: 8px 0; font-size: 13.5px; }\ntable { width: 100%; border-collapse: collapse; margin: 14px 0; font-size: 12.5px;\n border: 1px solid #ddd; }\nth { background: #003366; color: #fff; text-align: left; padding: 8px 12px;\n font-weight: 600; font-size: 11.5px; }\ntd { padding: 7px 12px; border: 1px solid #e0e0e0; }\ntr:nth-child(even) td { background: #f9f9f9; }\nul, ol { margin: 8px 0 8px 24px; font-size: 13.5px; }\nli { margin: 3px 0; }\ncode { background: #f4f4f4; padding: 1px 5px; border-radius: 3px; font-size: 12px;\n font-family: Consolas, monospace; }\npre { background: #f4f4f4; color: #333; padding: 14px; border-radius: 4px;\n overflow-x: auto; font-size: 12px; margin: 12px 0; border: 1px solid #ddd; }\npre code { background: transparent; padding: 0; }\nblockquote { border-left: 4px solid #ff6600; padding: 10px 16px; margin: 12px 0;\n background: #fff8f0; color: #555; }\n.footer { text-align: center; font-size: 10.5px; color: #aaa; margin-top: 32px;\n padding-top: 12px; border-top: 1px solid #eee; }\n.stamp { display: inline-block; border: 2px solid #003366; color: #003366; padding: 4px 16px;\n border-radius: 4px; font-size: 11px; font-weight: 700; text-transform: uppercase;\n letter-spacing: 1px; }",
|
||
"magazine" => "@import url('https://fonts.googleapis.com/css2?family=Merriweather:wght@300;400;700;900&family=Open+Sans:wght@300;400;600;700&display=swap');\n* { margin:0; padding:0; box-sizing:border-box; }\nbody { font-family: 'Open Sans', 'Malgun Gothic', sans-serif;\n background: #f0ece3; color: #2c2c2c; line-height: 1.7; padding: 48px 24px; }\n.container { max-width: 900px; margin: 0 auto; background: #fff;\n border-radius: 2px; padding: 0; overflow: hidden;\n box-shadow: 0 4px 16px rgba(0,0,0,0.08); }\n.hero { background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);\n padding: 48px 44px 36px; color: #fff; }\n.hero h1 { font-family: 'Merriweather', Georgia, serif; font-size: 32px; font-weight: 900;\n line-height: 1.3; margin-bottom: 8px; }\n.hero .meta { color: rgba(255,255,255,0.6); margin-bottom: 0; font-size: 13px; }\n.content { padding: 40px 44px 44px; }\nh1 { font-family: 'Merriweather', Georgia, serif; font-size: 28px; font-weight: 900;\n color: #1a1a2e; margin-bottom: 4px; }\nh2 { font-family: 'Merriweather', Georgia, serif; font-size: 20px; font-weight: 700;\n margin: 36px 0 14px; color: #1a1a2e; }\nh3 { font-size: 15px; font-weight: 700; margin: 24px 0 10px; color: #e94560;\n text-transform: uppercase; letter-spacing: 1px; font-size: 12px; }\n.meta { font-size: 12px; color: #999; margin-bottom: 24px; }\np { margin: 10px 0; font-size: 15px; }\np:first-of-type::first-letter { font-family: 'Merriweather', Georgia, serif;\n font-size: 48px; float: left; line-height: 1; padding-right: 8px; color: #e94560;\n font-weight: 900; }\ntable { width: 100%; border-collapse: collapse; margin: 18px 0; font-size: 13.5px; }\nth { background: #1a1a2e; color: #fff; text-align: left; padding: 10px 14px;\n font-weight: 600; }\ntd { padding: 9px 14px; border-bottom: 1px solid #eee; }\ntr:hover td { background: #fafafa; }\nul, ol { margin: 10px 0 10px 28px; font-size: 14.5px; }\nli { margin: 5px 0; }\ncode { background: #f5f5f5; padding: 2px 6px; border-radius: 3px; font-size: 12.5px;\n font-family: 'Courier New', monospace; }\npre { background: #1a1a2e; color: #e0e0e0; padding: 18px; border-radius: 4px;\n overflow-x: auto; font-size: 12.5px; margin: 16px 0; }\npre code { background: transparent; color: inherit; padding: 0; }\nblockquote { font-family: 'Merriweather', Georgia, serif; font-size: 18px;\n font-style: italic; color: #555; border: none; padding: 20px 0; margin: 24px 0;\n text-align: center; position: relative; }\nblockquote::before { content: '\\201C'; font-size: 60px; color: #e94560;\n position: absolute; top: -10px; left: 50%; transform: translateX(-50%);\n opacity: 0.3; }\n.pullquote { font-size: 20px; font-family: 'Merriweather', Georgia, serif;\n font-weight: 700; color: #e94560; border-top: 3px solid #e94560;\n border-bottom: 3px solid #e94560; padding: 16px 0; margin: 24px 0;\n text-align: center; }",
|
||
"dashboard" => "@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');\n* { margin:0; padding:0; box-sizing:border-box; }\nbody { font-family: 'Inter', 'Segoe UI', 'Malgun Gothic', sans-serif;\n background: #f0f2f5; color: #1a1a2e; line-height: 1.6; padding: 32px 24px; }\n.container { max-width: 1000px; margin: 0 auto; padding: 0; background: transparent; }\nh1 { font-size: 26px; font-weight: 700; color: #1a1a2e; margin-bottom: 4px; }\nh2 { font-size: 17px; font-weight: 600; margin: 28px 0 14px; color: #1a1a2e; }\nh3 { font-size: 14px; font-weight: 600; margin: 18px 0 8px; color: #6c7893; }\n.meta { font-size: 12px; color: #8c95a6; margin-bottom: 24px; }\np { margin: 8px 0; font-size: 13.5px; color: #4a5568; }\n.kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px; margin: 20px 0; }\n.kpi-card { background: #fff; border-radius: 12px; padding: 20px;\n box-shadow: 0 1px 4px rgba(0,0,0,0.06); }\n.kpi-card .kpi-label { font-size: 12px; color: #8c95a6; font-weight: 500;\n text-transform: uppercase; letter-spacing: 0.5px; }\n.kpi-card .kpi-value { font-size: 28px; font-weight: 700; color: #1a1a2e; margin: 4px 0; }\n.kpi-card .kpi-change { font-size: 12px; font-weight: 600; }\n.kpi-up { color: #10b981; } .kpi-down { color: #ef4444; }\n.chart-area { background: #fff; border-radius: 12px; padding: 24px; margin: 16px 0;\n box-shadow: 0 1px 4px rgba(0,0,0,0.06); min-height: 200px; }\ntable { width: 100%; border-collapse: collapse; margin: 16px 0; font-size: 13px;\n background: #fff; border-radius: 10px; overflow: hidden;\n box-shadow: 0 1px 4px rgba(0,0,0,0.06); }\nth { background: #f7f8fa; text-align: left; padding: 10px 14px; font-weight: 600;\n color: #6c7893; font-size: 11.5px; text-transform: uppercase; letter-spacing: 0.5px;\n border-bottom: 1px solid #edf0f4; }\ntd { padding: 10px 14px; border-bottom: 1px solid #f3f4f6; }\ntr:hover td { background: #f9fafb; }\nul, ol { margin: 8px 0 8px 24px; font-size: 13.5px; }\nli { margin: 4px 0; }\ncode { background: #f1f3f5; padding: 2px 7px; border-radius: 5px; font-size: 12px;\n font-family: 'JetBrains Mono', Consolas, monospace; }\npre { background: #1a1a2e; color: #c9d1d9; padding: 18px; border-radius: 10px;\n overflow-x: auto; font-size: 12px; margin: 14px 0; }\npre code { background: transparent; color: inherit; padding: 0; }\nblockquote { border-left: 3px solid #4b5efc; padding: 10px 16px; margin: 14px 0;\n background: #f0f0ff; border-radius: 0 8px 8px 0; font-size: 13px; }\n.status-badge { display: inline-block; padding: 2px 10px; border-radius: 12px;\n font-size: 11px; font-weight: 600; }\n.status-ok { background: #d1fae5; color: #065f46; }\n.status-warn { background: #fef3c7; color: #92400e; }\n.status-err { background: #fee2e2; color: #991b1b; }",
|
||
_ => "@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');\n* { margin:0; padding:0; box-sizing:border-box; }\nbody { font-family: 'Inter', 'Segoe UI', 'Malgun Gothic', sans-serif;\n background: #f5f5f7; color: #1d1d1f; line-height: 1.75; padding: 48px 24px; }\n.container { max-width: 880px; margin: 0 auto; background: #fff;\n border-radius: 16px; padding: 56px 52px;\n box-shadow: 0 4px 24px rgba(0,0,0,0.06); }\nh1 { font-size: 28px; font-weight: 700; letter-spacing: -0.5px; color: #1d1d1f; margin-bottom: 4px; }\nh2 { font-size: 20px; font-weight: 600; margin: 36px 0 14px; color: #1d1d1f;\n padding-bottom: 8px; border-bottom: 2px solid #e5e5ea; }\nh3 { font-size: 16px; font-weight: 600; margin: 24px 0 10px; color: #0071e3; }\n.meta { font-size: 12px; color: #86868b; margin-bottom: 28px; letter-spacing: 0.3px; }\np { margin: 10px 0; font-size: 14.5px; }\ntable { width: 100%; border-collapse: collapse; margin: 20px 0; font-size: 13.5px;\n border-radius: 10px; overflow: hidden; }\nth { background: #f5f5f7; text-align: left; padding: 12px 14px; font-weight: 600;\n color: #1d1d1f; border-bottom: 2px solid #d2d2d7; }\ntd { padding: 10px 14px; border-bottom: 1px solid #f0f0f2; }\ntr:hover td { background: #f9f9fb; }\nul, ol { margin: 10px 0 10px 28px; font-size: 14.5px; }\nli { margin: 5px 0; }\ncode { background: #f5f5f7; padding: 2px 8px; border-radius: 6px; font-size: 13px;\n font-family: 'SF Mono', Consolas, monospace; color: #e3116c; }\npre { background: #1d1d1f; color: #f5f5f7; padding: 20px; border-radius: 12px;\n overflow-x: auto; font-size: 13px; margin: 16px 0; line-height: 1.6; }\npre code { background: transparent; color: inherit; padding: 0; }\nblockquote { border-left: 3px solid #0071e3; padding: 12px 20px; margin: 16px 0;\n background: #f0f7ff; color: #1d1d1f; border-radius: 0 8px 8px 0; font-size: 14px; }\n.highlight { background: linear-gradient(120deg, #e0f0ff 0%, #f0e0ff 100%);\n padding: 16px 20px; border-radius: 10px; margin: 16px 0; }\n.badge { display: inline-block; padding: 3px 10px; border-radius: 20px; font-size: 11px;\n font-weight: 600; background: #0071e3; color: #fff; margin: 2px 4px 2px 0; }",
|
||
};
|
||
if (1 == 0)
|
||
{
|
||
}
|
||
string text2 = text;
|
||
return text2 + "\n\n/* ── 목차 (TOC) ── */\nnav.toc { background: #f8f9fa; border: 1px solid #e9ecef; border-radius: 10px;\n padding: 20px 28px; margin: 24px 0 32px; }\nnav.toc h2 { font-size: 15px; font-weight: 700; margin: 0 0 12px; padding: 0; border: none;\n color: inherit; display: block; background: none; }\nnav.toc ul { list-style: none; margin: 0; padding: 0; }\nnav.toc li { margin: 4px 0; }\nnav.toc li.toc-h3 { padding-left: 18px; }\nnav.toc a { text-decoration: none; color: #4b5efc; font-size: 13.5px; }\nnav.toc a:hover { text-decoration: underline; }\n\n/* ── 커버 페이지 ── */\n.cover-page { text-align: center; padding: 80px 40px 60px; margin: -56px -52px 40px;\n border-radius: 16px 16px 0 0; position: relative; overflow: hidden;\n background: linear-gradient(135deg, #4b5efc 0%, #7c3aed 100%); color: #fff; }\n.cover-page h1 { font-size: 36px; font-weight: 800; margin-bottom: 12px; color: #fff;\n -webkit-text-fill-color: #fff; }\n.cover-page .cover-subtitle { font-size: 18px; opacity: 0.9; margin-bottom: 24px; }\n.cover-page .cover-meta { font-size: 13px; opacity: 0.7; }\n.cover-page .cover-divider { width: 60px; height: 3px; background: rgba(255,255,255,0.5);\n margin: 20px auto; border-radius: 2px; }\n\n/* ── 콜아웃 (callout) ── */\n.callout { border-radius: 8px; padding: 16px 20px; margin: 16px 0; font-size: 14px;\n border-left: 4px solid; display: flex; gap: 10px; align-items: flex-start; }\n.callout::before { font-size: 16px; flex-shrink: 0; margin-top: 1px; }\n.callout-info { background: #eff6ff; border-color: #3b82f6; color: #1e40af; }\n.callout-info::before { content: 'ℹ\ufe0f'; }\n.callout-warning { background: #fffbeb; border-color: #f59e0b; color: #92400e; }\n.callout-warning::before { content: '⚠\ufe0f'; }\n.callout-tip { background: #f0fdf4; border-color: #22c55e; color: #166534; }\n.callout-tip::before { content: '\ud83d\udca1'; }\n.callout-danger { background: #fef2f2; border-color: #ef4444; color: #991b1b; }\n.callout-danger::before { content: '\ud83d\udea8'; }\n.callout-note { background: #f5f3ff; border-color: #8b5cf6; color: #5b21b6; }\n.callout-note::before { content: '\ud83d\udcdd'; }\n\n/* ── 배지 (badge) — 공통 ── */\n.badge, .tag, .chip { display: inline-block; padding: 3px 10px; border-radius: 20px;\n font-size: 11px; font-weight: 600; margin: 2px 4px 2px 0; }\n.badge-blue { background: #dbeafe; color: #1e40af; }\n.badge-green { background: #d1fae5; color: #065f46; }\n.badge-red { background: #fee2e2; color: #991b1b; }\n.badge-yellow { background: #fef3c7; color: #92400e; }\n.badge-purple { background: #ede9fe; color: #5b21b6; }\n.badge-gray { background: #f3f4f6; color: #374151; }\n.badge-orange { background: #ffedd5; color: #9a3412; }\n\n/* ── 하이라이트 박스 ── */\n.highlight-box { background: linear-gradient(120deg, #e0f0ff 0%, #f0e0ff 100%);\n padding: 16px 20px; border-radius: 10px; margin: 16px 0; }\n\n/* ── CSS 차트 (bar/horizontal) ── */\n.chart-bar { margin: 20px 0; }\n.chart-bar .bar-item { display: flex; align-items: center; margin: 6px 0; gap: 10px; }\n.chart-bar .bar-label { min-width: 100px; font-size: 13px; text-align: right; flex-shrink: 0; }\n.chart-bar .bar-track { flex: 1; background: #e5e7eb; border-radius: 6px; height: 22px;\n overflow: hidden; }\n.chart-bar .bar-fill { height: 100%; border-radius: 6px; display: flex; align-items: center;\n padding: 0 8px; font-size: 11px; font-weight: 600; color: #fff;\n transition: width 0.3s ease; min-width: fit-content; }\n.bar-fill.blue { background: #3b82f6; } .bar-fill.green { background: #22c55e; }\n.bar-fill.red { background: #ef4444; } .bar-fill.yellow { background: #f59e0b; }\n.bar-fill.purple { background: #8b5cf6; } .bar-fill.orange { background: #f97316; }\n\n/* ── CSS 도넛 차트 ── */\n.chart-donut { width: 160px; height: 160px; border-radius: 50%; margin: 20px auto;\n background: conic-gradient(var(--seg1-color, #3b82f6) 0% var(--seg1, 0%),\n var(--seg2-color, #22c55e) var(--seg1, 0%) var(--seg2, 0%),\n var(--seg3-color, #f59e0b) var(--seg2, 0%) var(--seg3, 0%),\n var(--seg4-color, #ef4444) var(--seg3, 0%) var(--seg4, 0%),\n #e5e7eb var(--seg4, 0%) 100%);\n display: flex; align-items: center; justify-content: center; position: relative; }\n.chart-donut::after { content: ''; width: 100px; height: 100px; background: #fff;\n border-radius: 50%; position: absolute; }\n.chart-donut .donut-label { position: absolute; z-index: 1; font-size: 18px; font-weight: 700; }\n\n/* ── 진행률 바 ── */\n.progress { background: #e5e7eb; border-radius: 8px; height: 10px; margin: 8px 0;\n overflow: hidden; }\n.progress-fill { height: 100%; border-radius: 8px; background: #3b82f6; }\n\n/* ── 타임라인 ── */\n.timeline { position: relative; padding-left: 28px; margin: 20px 0; }\n.timeline::before { content: ''; position: absolute; left: 8px; top: 0; bottom: 0;\n width: 2px; background: #e5e7eb; }\n.timeline-item { position: relative; margin: 16px 0; }\n.timeline-item::before { content: ''; position: absolute; left: -24px; top: 5px;\n width: 12px; height: 12px; border-radius: 50%; background: #4b5efc;\n border: 2px solid #fff; box-shadow: 0 0 0 2px #4b5efc; }\n.timeline-item .timeline-date { font-size: 12px; color: #6b7280; font-weight: 600; }\n.timeline-item .timeline-content { font-size: 14px; margin-top: 4px; }\n\n/* ── 섹션 자동 번호 ── */\nbody { counter-reset: section; }\nh2.numbered { counter-increment: section; counter-reset: subsection; }\nh2.numbered::before { content: counter(section) '. '; }\nh3.numbered { counter-increment: subsection; }\nh3.numbered::before { content: counter(section) '-' counter(subsection) '. '; }\n\n/* ── 그리드 레이아웃 ── */\n.grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; margin: 16px 0; }\n.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin: 16px 0; }\n.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin: 16px 0; }\n\n/* ── 카드 공통 ── */\n.card { background: #fff; border: 1px solid #e5e7eb; border-radius: 12px;\n padding: 20px; box-shadow: 0 1px 3px rgba(0,0,0,0.06); }\n.card-header { font-size: 15px; font-weight: 700; margin-bottom: 8px; }\n\n/* ── 구분선 ── */\n.divider { border: none; border-top: 1px solid #e5e7eb; margin: 32px 0; }\n.divider-thick { border: none; border-top: 3px solid #e5e7eb; margin: 40px 0; }\n\n/* ── 인쇄/PDF 최적화 ── */\n@media print {\n body { background: #fff !important; padding: 0 !important; }\n .container { box-shadow: none !important; border: none !important;\n max-width: none !important; padding: 20px !important; }\n .cover-page { break-after: page; }\n h2, h3 { break-after: avoid; }\n table, figure, .chart-bar, .callout { break-inside: avoid; }\n nav.toc { break-after: page; }\n a { color: inherit !important; text-decoration: none !important; }\n a[href]::after { content: ' (' attr(href) ')'; font-size: 10px; color: #999; }\n .no-print { display: none !important; }\n}";
|
||
}
|
||
|
||
public static TemplateMood? GetMood(string key)
|
||
{
|
||
TemplateMood templateMood = Array.Find(AvailableMoods, (TemplateMood m) => m.Key == key);
|
||
if (templateMood != null)
|
||
{
|
||
return templateMood;
|
||
}
|
||
CustomMoodEntry value;
|
||
return _customMoods.TryGetValue(key, out value) ? new TemplateMood(value.Key, value.Label, value.Icon, value.Description) : null;
|
||
}
|
||
|
||
public static string GetMoodListForPrompt()
|
||
{
|
||
StringBuilder stringBuilder = new StringBuilder();
|
||
stringBuilder.AppendLine("Available document design moods (pass as 'mood' parameter to html_create):");
|
||
foreach (TemplateMood allMood in AllMoods)
|
||
{
|
||
StringBuilder stringBuilder2 = stringBuilder;
|
||
StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(11, 3, stringBuilder2);
|
||
handler.AppendLiteral(" - \"");
|
||
handler.AppendFormatted(allMood.Key);
|
||
handler.AppendLiteral("\": ");
|
||
handler.AppendFormatted(allMood.Label);
|
||
handler.AppendLiteral(" — ");
|
||
handler.AppendFormatted(allMood.Description);
|
||
stringBuilder2.AppendLine(ref handler);
|
||
}
|
||
return stringBuilder.ToString();
|
||
}
|
||
|
||
public static string RenderMarkdownToHtml(string markdown, string moodKey = "modern")
|
||
{
|
||
MarkdownPipeline pipeline = new MarkdownPipelineBuilder().UseAdvancedExtensions().Build();
|
||
string value = Markdown.ToHtml(markdown, pipeline);
|
||
string css = GetCss(moodKey);
|
||
return $"<!DOCTYPE html>\n<html lang=\"ko\">\n<head>\n<meta charset=\"UTF-8\"/>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/>\n<style>{css}</style>\n</head>\n<body>\n<div class=\"container\">\n{value}\n</div>\n</body>\n</html>";
|
||
}
|
||
|
||
public static string HighlightFilePaths(string html, string? workFolder)
|
||
{
|
||
if (string.IsNullOrEmpty(workFolder) || string.IsNullOrEmpty(html))
|
||
{
|
||
return html;
|
||
}
|
||
Regex regex = new Regex("(?<![\"'=/>])(\\b[A-Za-z]:\\\\[^\\s<>\"]+|\\.{0,2}/[^\\s<>\"]+(?:\\.[a-zA-Z]{1,10})?|\\b[\\w\\-]+(?:/[\\w\\-\\.]+)+(?:\\.[a-zA-Z]{1,10})?|\\b[\\w\\-]+\\.(?:cs|py|js|ts|tsx|jsx|json|xml|html|htm|css|md|txt|yml|yaml|toml|sh|bat|ps1|csproj|sln|docx|xlsx|pptx|pdf|csv)\\b)", RegexOptions.Compiled);
|
||
return regex.Replace(html, delegate(Match match)
|
||
{
|
||
string value = match.Value;
|
||
string text = html.Substring(0, match.Index);
|
||
if (text.Length > 0)
|
||
{
|
||
int num = text.LastIndexOf('<');
|
||
int num2 = text.LastIndexOf('>');
|
||
if (num > num2)
|
||
{
|
||
return value;
|
||
}
|
||
}
|
||
return "<span style=\"color:#3B82F6;font-weight:500;\">" + value + "</span>";
|
||
});
|
||
}
|
||
|
||
public static MoodColors GetMoodColors(string moodKey)
|
||
{
|
||
if (1 == 0)
|
||
{
|
||
}
|
||
MoodColors result = moodKey switch
|
||
{
|
||
"modern" => new MoodColors("#f5f5f7", "#ffffff", "#1d1d1f", "#6e6e73", "#0066cc", "#e5e5e7"),
|
||
"professional" => new MoodColors("#f0f2f5", "#ffffff", "#1a365d", "#4a5568", "#2c5282", "#e2e8f0"),
|
||
"creative" => new MoodColors("#faf5ff", "#ffffff", "#2d3748", "#718096", "#7c3aed", "#e9d5ff"),
|
||
"minimal" => new MoodColors("#fafafa", "#ffffff", "#111111", "#555555", "#333333", "#e0e0e0"),
|
||
"elegant" => new MoodColors("#fefdf8", "#fffef9", "#2c1810", "#6b5c4f", "#b8860b", "#e8e0d4"),
|
||
"dark" => new MoodColors("#0d1117", "#161b22", "#e6edf3", "#8b949e", "#58a6ff", "#30363d"),
|
||
"colorful" => new MoodColors("#f0f9ff", "#ffffff", "#1e293b", "#64748b", "#3b82f6", "#e0f2fe"),
|
||
"corporate" => new MoodColors("#f3f4f6", "#ffffff", "#1f2937", "#6b7280", "#1e40af", "#e5e7eb"),
|
||
"magazine" => new MoodColors("#f9fafb", "#ffffff", "#111827", "#6b7280", "#dc2626", "#f3f4f6"),
|
||
"dashboard" => new MoodColors("#0f172a", "#1e293b", "#f1f5f9", "#94a3b8", "#3b82f6", "#334155"),
|
||
_ => new MoodColors("#f5f5f7", "#ffffff", "#1d1d1f", "#6e6e73", "#0066cc", "#e5e5e7"),
|
||
};
|
||
if (1 == 0)
|
||
{
|
||
}
|
||
return result;
|
||
}
|
||
}
|