from __future__ import annotations

from dataclasses import dataclass
from pathlib import Path
from typing import Iterable, Sequence

from pptx import Presentation
from pptx.dml.color import RGBColor
from pptx.enum.shapes import MSO_AUTO_SHAPE_TYPE
from pptx.enum.text import PP_ALIGN
from pptx.util import Inches, Pt


@dataclass(frozen=True)
class Theme:
    navy: RGBColor
    navy_2: RGBColor
    bg: RGBColor
    white: RGBColor
    text: RGBColor
    muted: RGBColor
    line: RGBColor
    accent_yellow: RGBColor
    accent_blue: RGBColor
    accent_red: RGBColor
    accent_green: RGBColor

    font: str
    font_bold: str


T = Theme(
    navy=RGBColor(0x10, 0x1D, 0x2E),
    navy_2=RGBColor(0x14, 0x2A, 0x45),
    bg=RGBColor(0xF6, 0xF7, 0xFB),
    white=RGBColor(0xFF, 0xFF, 0xFF),
    text=RGBColor(0x1F, 0x29, 0x37),
    muted=RGBColor(0x6B, 0x72, 0x80),
    line=RGBColor(0xE5, 0xE7, 0xEB),
    accent_yellow=RGBColor(0xF0, 0xB4, 0x3B),
    accent_blue=RGBColor(0x3B, 0x82, 0xF6),
    accent_red=RGBColor(0xEF, 0x44, 0x44),
    accent_green=RGBColor(0x22, 0xC5, 0x5E),
    font="Apple SD Gothic Neo",
    font_bold="Apple SD Gothic Neo",
)


SLIDE_W = Inches(13.333)
SLIDE_H = Inches(7.5)


def _rgb(hex6: str) -> RGBColor:
    h = hex6.lstrip("#")
    return RGBColor(int(h[0:2], 16), int(h[2:4], 16), int(h[4:6], 16))


def set_slide_bg(slide, color: RGBColor) -> None:
    fill = slide.background.fill
    fill.solid()
    fill.fore_color.rgb = color


def add_rect(slide, x, y, w, h, *, fill: RGBColor | None, line: RGBColor | None, radius: bool = False):
    shape_type = MSO_AUTO_SHAPE_TYPE.ROUNDED_RECTANGLE if radius else MSO_AUTO_SHAPE_TYPE.RECTANGLE
    shp = slide.shapes.add_shape(shape_type, x, y, w, h)
    if fill is None:
        shp.fill.background()
    else:
        shp.fill.solid()
        shp.fill.fore_color.rgb = fill
    if line is None:
        shp.line.fill.background()
    else:
        shp.line.color.rgb = line
        shp.line.width = Pt(1)
    return shp


def add_textbox(
    slide,
    x,
    y,
    w,
    h,
    text: str,
    *,
    size: int,
    bold: bool = False,
    color: RGBColor | None = None,
    align: int = PP_ALIGN.LEFT,
    line_spacing: float | None = None,
):
    tb = slide.shapes.add_textbox(x, y, w, h)
    tf = tb.text_frame
    tf.clear()
    p = tf.paragraphs[0]
    run = p.add_run()
    run.text = text
    f = run.font
    f.name = T.font_bold if bold else T.font
    f.size = Pt(size)
    f.bold = bold
    f.color.rgb = color or T.text
    p.alignment = align
    if line_spacing is not None:
        p.line_spacing = line_spacing
    return tb


def add_bullets(
    slide,
    x,
    y,
    w,
    h,
    bullets: Sequence[str],
    *,
    size: int = 18,
    color: RGBColor | None = None,
    bullet_color: RGBColor | None = None,
    line_spacing: float = 1.15,
):
    tb = slide.shapes.add_textbox(x, y, w, h)
    tf = tb.text_frame
    tf.clear()
    tf.word_wrap = True
    for i, b in enumerate(bullets):
        p = tf.paragraphs[0] if i == 0 else tf.add_paragraph()
        p.text = b
        p.level = 0
        p.font.name = T.font
        p.font.size = Pt(size)
        p.font.color.rgb = color or T.text
        p.line_spacing = line_spacing
        p.space_after = Pt(6)
        p.bullet = True
        if bullet_color is not None:
            # python-pptx doesn't support bullet color directly; keep as text color.
            pass
    return tb


def add_pill(slide, x, y, w, h, text: str, *, fill: RGBColor, fg: RGBColor):
    pill = add_rect(slide, x, y, w, h, fill=fill, line=None, radius=True)
    tf = pill.text_frame
    tf.clear()
    p = tf.paragraphs[0]
    p.alignment = PP_ALIGN.CENTER
    run = p.add_run()
    run.text = text
    run.font.name = T.font
    run.font.size = Pt(12)
    run.font.color.rgb = fg
    return pill


def add_footer(slide, slide_no: int, *, dark: bool) -> None:
    y = SLIDE_H - Inches(0.35)
    add_rect(slide, Inches(0), y, SLIDE_W, Inches(0.35), fill=(T.navy if dark else T.bg), line=None, radius=False)
    fg = _rgb("#D1D5DB") if dark else T.muted
    add_textbox(
        slide,
        Inches(0.5),
        y + Inches(0.06),
        Inches(6),
        Inches(0.25),
        "윤도상  |  2026.03",
        size=11,
        bold=False,
        color=fg,
        align=PP_ALIGN.LEFT,
    )
    add_textbox(
        slide,
        SLIDE_W - Inches(2.0),
        y + Inches(0.06),
        Inches(1.5),
        Inches(0.25),
        f"Slide  {slide_no:02d}" if dark else f"{slide_no:02d}",
        size=11,
        bold=False,
        color=fg,
        align=PP_ALIGN.RIGHT,
    )


def add_title_block(
    slide,
    title: str,
    subtitle: str | None = None,
    *,
    dark: bool,
    y: float = 0.6,
    pretitle: str | None = None,
):
    fg = T.white if dark else T.text
    if pretitle:
        add_textbox(
            slide,
            Inches(0.7),
            Inches(y),
            Inches(12),
            Inches(0.3),
            pretitle,
            size=14,
            bold=True,
            color=T.accent_yellow if dark else T.accent_yellow,
        )
        y += 0.35
    add_textbox(
        slide,
        Inches(0.7),
        Inches(y),
        Inches(12),
        Inches(0.8),
        title,
        size=40 if len(title) <= 18 else 34,
        bold=True,
        color=fg,
    )
    if subtitle:
        add_textbox(
            slide,
            Inches(0.7),
            Inches(y + 0.85),
            Inches(12),
            Inches(0.4),
            subtitle,
            size=18,
            bold=True,
            color=T.accent_yellow if dark else T.muted,
        )


def add_card(
    slide,
    x,
    y,
    w,
    h,
    *,
    title: str,
    body: Sequence[str],
    accent: RGBColor,
    dark_text: bool = True,
):
    add_rect(slide, x, y, w, h, fill=T.white, line=T.line, radius=True)
    add_rect(slide, x, y, w, Inches(0.08), fill=accent, line=None, radius=False)
    add_textbox(
        slide,
        x + Inches(0.25),
        y + Inches(0.4),
        w - Inches(0.5),
        Inches(0.4),
        title,
        size=18,
        bold=True,
        color=T.text if dark_text else T.white,
    )
    add_bullets(
        slide,
        x + Inches(0.25),
        y + Inches(0.9),
        w - Inches(0.5),
        h - Inches(1.1),
        list(body),
        size=14,
        color=T.muted,
        line_spacing=1.2,
    )


def slide_01_cover(prs: Presentation) -> None:
    s = prs.slides.add_slide(prs.slide_layouts[6])
    set_slide_bg(s, T.navy)
    add_pill(
        s,
        Inches(4.2),
        Inches(0.35),
        Inches(4.9),
        Inches(0.42),
        "LLM AI 툴 활용 교육",
        fill=_rgb("#24364D"),
        fg=_rgb("#E5E7EB"),
    )
    add_textbox(s, Inches(3.6), Inches(2.1), Inches(6.2), Inches(0.9), "AI에게", size=54, bold=True, color=T.white, align=PP_ALIGN.CENTER)
    add_textbox(s, Inches(2.9), Inches(3.05), Inches(7.6), Inches(0.9), "잘 시키는 법", size=54, bold=True, color=T.white, align=PP_ALIGN.CENTER)
    add_rect(s, Inches(6.1), Inches(4.1), Inches(1.2), Inches(0.05), fill=T.accent_yellow, line=None)
    add_textbox(
        s,
        Inches(2.4),
        Inches(4.35),
        Inches(8.6),
        Inches(0.5),
        "실무자를 위한 LLM 프롬프트 & 워크플로우 완전 가이드",
        size=18,
        bold=True,
        color=T.accent_yellow,
        align=PP_ALIGN.CENTER,
    )
    add_footer(s, 1, dark=True)


def slide_02_core_assumptions(prs: Presentation) -> None:
    s = prs.slides.add_slide(prs.slide_layouts[6])
    set_slide_bg(s, T.bg)
    add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "AI 활용의 핵심 전제 3가지", size=14, bold=True, color=T.accent_yellow)
    add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "이것만 알아도 80%다", size=40, bold=True, color=T.text)
    add_pill(s, Inches(10.1), Inches(1.1), Inches(2.6), Inches(0.38), "Chapter 1. AI는 어떻게 생각하는가?", fill=_rgb("#EEF2F7"), fg=T.muted)

    cw = Inches(3.95)
    ch = Inches(2.7)
    y = Inches(2.05)
    gap = Inches(0.4)
    x1 = Inches(0.7)
    add_card(
        s,
        x1,
        y,
        cw,
        ch,
        title="AI는 당신이 준\n정보만큼 답한다",
        body=["입력(Prompt)의 질이 곧", "출력(Output)의 질을 결정합니다.", "맥락이 없으면 답도 없습니다."],
        accent=T.accent_blue,
    )
    add_card(
        s,
        x1 + cw + gap,
        y,
        cw,
        ch,
        title="AI는 틀린 답을\n자신 있게 말한다",
        body=["환각(Hallucination) 현상은", "AI의 구조적 특성입니다.", "절대 맹신하지 마세요."],
        accent=T.accent_red,
    )
    add_card(
        s,
        x1 + (cw + gap) * 2,
        y,
        cw,
        ch,
        title="AI는 도구이지,\n판단자가 아니다",
        body=["결과물에 대한 최종 검증과", "책임은 항상 사람(나)에게", "있습니다."],
        accent=T.accent_green,
    )

    bar_y = Inches(5.55)
    add_rect(s, Inches(0.7), bar_y, Inches(11.93), Inches(0.85), fill=T.navy_2, line=None, radius=True)
    add_pill(s, Inches(0.95), bar_y + Inches(0.18), Inches(1.15), Inches(0.42), "실제 사례", fill=T.accent_yellow, fg=T.navy)
    add_pill(s, Inches(2.2), bar_y + Inches(0.18), Inches(3.1), Inches(0.42), "\"세차장에 갑니다\" (중의적)", fill=_rgb("#2B3E59"), fg=_rgb("#E5E7EB"))
    add_textbox(s, Inches(5.35), bar_y + Inches(0.18), Inches(0.4), Inches(0.42), "→", size=22, bold=True, color=T.accent_yellow, align=PP_ALIGN.CENTER)
    add_pill(s, Inches(5.7), bar_y + Inches(0.18), Inches(3.2), Inches(0.42), "\"세차하러 갑니다\" (명확)", fill=_rgb("#2B3E59"), fg=_rgb("#E5E7EB"))
    add_textbox(
        s,
        Inches(9.1),
        bar_y + Inches(0.18),
        Inches(3.3),
        Inches(0.42),
        "정보 단 하나(목적) 차이로\nAI의 답변 품질이 완전히 달라집니다!",
        size=12,
        bold=True,
        color=_rgb("#E5E7EB"),
        align=PP_ALIGN.RIGHT,
    )
    add_footer(s, 2, dark=False)


def slide_03_llm(prs: Presentation) -> None:
    s = prs.slides.add_slide(prs.slide_layouts[6])
    set_slide_bg(s, T.navy)
    add_title_block(s, "LLM이란 무엇인가?", "Large Language Model — 대규모 언어 모델", dark=True, y=0.5)
    add_pill(s, Inches(11.5), Inches(0.6), Inches(1.4), Inches(0.38), "Chapter 1", fill=_rgb("#24364D"), fg=_rgb("#E5E7EB"))

    x = Inches(0.7)
    y = Inches(2.0)
    w = Inches(4.8)
    h = Inches(1.05)
    gap = Inches(0.35)

    def left_item(yy, title, desc):
        add_rect(s, x, yy, w, h, fill=_rgb("#1B2A3F"), line=_rgb("#2B3E59"), radius=True)
        add_textbox(s, x + Inches(0.3), yy + Inches(0.2), w - Inches(0.6), Inches(0.35), title, size=18, bold=True, color=T.white)
        add_textbox(s, x + Inches(0.3), yy + Inches(0.55), w - Inches(0.6), Inches(0.45), desc, size=13, bold=False, color=_rgb("#D1D5DB"))

    left_item(y, "확률 기반 언어 예측", "다음에 올 단어를 통계적으로\n예측하는 '확률 기계'입니다.")
    left_item(y + h + gap, "\"지식\"이 아닌 \"패턴\"", "사전처럼 정답을 저장한 것이 아니라,\n수많은 문장의 패턴을 학습했습니다.")
    left_item(y + (h + gap) * 2, "확률적 답변 생성", "같은 질문에도 매번 확률적으로\n가장 자연스러운 답을 생성합니다.")

    # Right diagram card
    rx = Inches(5.8)
    ry = Inches(2.05)
    rw = Inches(7.0)
    rh = Inches(4.25)
    add_rect(s, rx, ry, rw, rh, fill=_rgb("#1B2A3F"), line=_rgb("#2B3E59"), radius=True)
    add_textbox(s, rx + Inches(0.35), ry + Inches(0.25), Inches(4), Inches(0.35), "LLM 작동 프로세스 예시", size=13, bold=True, color=_rgb("#9CA3AF"))

    # INPUT box
    add_textbox(s, rx + Inches(0.55), ry + Inches(0.8), Inches(1.5), Inches(0.3), "INPUT (입력)", size=11, bold=True, color=_rgb("#9CA3AF"))
    add_rect(s, rx + Inches(0.55), ry + Inches(1.15), Inches(2.2), Inches(0.85), fill=_rgb("#132236"), line=_rgb("#2B3E59"), radius=True)
    add_textbox(
        s,
        rx + Inches(0.7),
        ry + Inches(1.28),
        Inches(1.9),
        Inches(0.55),
        "\"대한민국의\n수도는\"",
        size=16,
        bold=True,
        color=T.white,
        align=PP_ALIGN.CENTER,
    )
    # Prediction circle
    add_textbox(s, rx + Inches(3.0), ry + Inches(0.8), Inches(2.5), Inches(0.3), "PREDICTION (예측)", size=11, bold=True, color=T.accent_yellow, align=PP_ALIGN.CENTER)
    circ = s.shapes.add_shape(MSO_AUTO_SHAPE_TYPE.OVAL, rx + Inches(3.2), ry + Inches(1.05), Inches(2.55), Inches(2.55))
    circ.fill.background()
    circ.line.color.rgb = T.accent_yellow
    circ.line.width = Pt(2)
    # Prob bars inside
    add_textbox(s, rx + Inches(3.35), ry + Inches(1.45), Inches(2.25), Inches(0.25), "서울  92%", size=11, bold=True, color=_rgb("#E5E7EB"))
    add_rect(s, rx + Inches(3.35), ry + Inches(1.72), Inches(2.1), Inches(0.08), fill=T.accent_yellow, line=None)
    add_textbox(s, rx + Inches(3.35), ry + Inches(1.95), Inches(2.25), Inches(0.25), "부산   5%", size=11, bold=False, color=_rgb("#9CA3AF"))
    add_rect(s, rx + Inches(3.35), ry + Inches(2.22), Inches(0.55), Inches(0.08), fill=_rgb("#64748B"), line=None)
    add_textbox(s, rx + Inches(3.35), ry + Inches(2.45), Inches(2.25), Inches(0.25), "평양   1%", size=11, bold=False, color=_rgb("#9CA3AF"))
    add_rect(s, rx + Inches(3.35), ry + Inches(2.72), Inches(0.25), Inches(0.08), fill=_rgb("#64748B"), line=None)

    # OUTPUT box
    add_textbox(s, rx + Inches(5.85), ry + Inches(0.8), Inches(1.5), Inches(0.3), "OUTPUT (출력)", size=11, bold=True, color=_rgb("#9CA3AF"), align=PP_ALIGN.RIGHT)
    add_rect(s, rx + Inches(5.6), ry + Inches(1.25), Inches(2.15), Inches(0.85), fill=_rgb("#0F2C2A"), line=_rgb("#34D399"), radius=True)
    add_textbox(
        s,
        rx + Inches(5.75),
        ry + Inches(1.38),
        Inches(1.85),
        Inches(0.55),
        "\"서울입니다.\"",
        size=18,
        bold=True,
        color=_rgb("#A7F3D0"),
        align=PP_ALIGN.CENTER,
    )

    # Arrows
    add_textbox(s, rx + Inches(2.85), ry + Inches(1.45), Inches(0.3), Inches(0.3), "›", size=28, bold=True, color=_rgb("#9CA3AF"), align=PP_ALIGN.CENTER)
    add_textbox(s, rx + Inches(5.45), ry + Inches(1.45), Inches(0.3), Inches(0.3), "›", size=28, bold=True, color=_rgb("#9CA3AF"), align=PP_ALIGN.CENTER)

    add_rect(s, rx + Inches(0.45), ry + Inches(3.8), rw - Inches(0.9), Inches(0.55), fill=_rgb("#24364D"), line=None, radius=True)
    add_textbox(
        s,
        rx + Inches(0.7),
        ry + Inches(3.92),
        rw - Inches(1.4),
        Inches(0.3),
        "ChatGPT, Claude, Gemini 등은 모두 이와 같은 원리로 작동합니다.",
        size=12,
        bold=True,
        color=_rgb("#D1D5DB"),
        align=PP_ALIGN.CENTER,
    )
    add_footer(s, 3, dark=True)


def slide_04_good_vs_bad(prs: Presentation) -> None:
    s = prs.slides.add_slide(prs.slide_layouts[6])
    set_slide_bg(s, T.bg)
    add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "효율적인 AI 활용을 위한 첫걸음", size=14, bold=True, color=T.muted)
    add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "AI가 잘하는 것  vs  못하는 것", size=40, bold=True, color=T.text)
    add_pill(s, Inches(9.9), Inches(1.1), Inches(2.95), Inches(0.38), "Chapter 1. AI의 본질 이해", fill=_rgb("#EEF2F7"), fg=T.muted)

    left_x = Inches(0.8)
    col_y = Inches(2.0)
    col_w = Inches(6.05)
    col_h = Inches(4.25)
    right_x = Inches(6.45)

    add_rect(s, left_x, col_y, col_w, col_h, fill=_rgb("#E9FBF1"), line=None, radius=True)
    add_rect(s, right_x, col_y, col_w, col_h, fill=_rgb("#FDECEC"), line=None, radius=True)
    add_textbox(s, left_x + Inches(0.35), col_y + Inches(0.3), col_w - Inches(0.7), Inches(0.35), "✓  AI가 잘하는 것", size=20, bold=True, color=_rgb("#15803D"))
    add_textbox(s, right_x + Inches(0.35), col_y + Inches(0.3), col_w - Inches(0.7), Inches(0.35), "✕  AI가 못하는 것 / 주의", size=20, bold=True, color=_rgb("#B91C1C"))

    good = [
        "구조화된 글 작성 및 요약",
        "번역 및 언어 변환",
        "패턴 인식 및 분류",
        "코드 생성 및 디버깅",
        "반복 업무 자동화",
        "대용량 문서 핵심 추출",
    ]
    bad = [
        "최신 실시간 정보 확인 (검색 미연동 시)",
        "복잡한 수학 계산·논리적 검증",
        "사용자의 숨겨진 의도 자동 파악",
        "사실 여부 100% 보장 (환각 위험)",
        "인간적 감각·경험 기반의 판단",
        "결과물에 대한 법적 책임",
    ]

    add_bullets(s, left_x + Inches(0.55), col_y + Inches(0.9), col_w - Inches(1.1), col_h - Inches(1.2), good, size=16, color=T.text)
    add_bullets(s, right_x + Inches(0.55), col_y + Inches(0.9), col_w - Inches(1.1), col_h - Inches(1.2), bad, size=16, color=T.text)

    # Center VS bubble
    vs = s.shapes.add_shape(MSO_AUTO_SHAPE_TYPE.OVAL, Inches(6.1), Inches(3.8), Inches(0.7), Inches(0.7))
    vs.fill.solid()
    vs.fill.fore_color.rgb = _rgb("#EEF2F7")
    vs.line.color.rgb = T.line
    vs.text_frame.text = "VS"
    vs.text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER
    vs.text_frame.paragraphs[0].runs[0].font.name = T.font_bold
    vs.text_frame.paragraphs[0].runs[0].font.bold = True
    vs.text_frame.paragraphs[0].runs[0].font.size = Pt(14)
    vs.text_frame.paragraphs[0].runs[0].font.color.rgb = T.muted

    # Bottom callout
    add_rect(s, Inches(0.7), Inches(6.55), Inches(11.93), Inches(0.65), fill=T.navy_2, line=None, radius=True)
    add_textbox(
        s,
        Inches(0.95),
        Inches(6.66),
        Inches(11.4),
        Inches(0.42),
        "AI를 \"잘 쓴다\"는 것은, AI가 못하는 영역을 사람이 보완한다는 뜻입니다.",
        size=16,
        bold=True,
        color=_rgb("#E5E7EB"),
        align=PP_ALIGN.CENTER,
    )
    add_footer(s, 4, dark=False)


def slide_05_hallucination(prs: Presentation) -> None:
    s = prs.slides.add_slide(prs.slide_layouts[6])
    set_slide_bg(s, T.bg)
    add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "⚠  왜 AI는 그럴듯하게 거짓말하는가?", size=14, bold=True, color=T.accent_red)
    add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "AI의 환각(Hallucination) 현상", size=40, bold=True, color=T.text)
    add_pill(s, Inches(11.2), Inches(1.05), Inches(1.55), Inches(0.4), "Critical Issue", fill=_rgb("#FEE2E2"), fg=_rgb("#B91C1C"))

    # Definition box
    add_rect(s, Inches(0.7), Inches(1.9), Inches(11.93), Inches(1.0), fill=_rgb("#F3F4F6"), line=None, radius=True)
    add_textbox(s, Inches(1.0), Inches(2.05), Inches(11.3), Inches(0.3), "환각(Hallucination)이란?", size=16, bold=True, color=T.text)
    add_textbox(
        s,
        Inches(1.0),
        Inches(2.35),
        Inches(11.3),
        Inches(0.5),
        "AI가 사실이 아닌 내용을 마치 사실인 것처럼 자신 있게 답하는 현상입니다.\n"
        "AI는 확률적으로 '자연스러운 문장'을 생성하는 과정에서 거짓 정보를 유창하게 만들어낼 수 있습니다.",
        size=13,
        bold=False,
        color=T.muted,
        line_spacing=1.2,
    )

    # Risk cards
    x = Inches(0.7)
    y = Inches(3.1)
    w = Inches(3.82)
    h = Inches(1.55)
    g = Inches(0.35)

    def risk(xx, title, bullets):
        add_rect(s, xx, y, w, h, fill=_rgb("#FFF1F2"), line=_rgb("#FECACA"), radius=True)
        add_textbox(s, xx + Inches(0.25), y + Inches(0.2), w - Inches(0.5), Inches(0.3), title, size=14, bold=True, color=_rgb("#B91C1C"))
        add_bullets(s, xx + Inches(0.25), y + Inches(0.55), w - Inches(0.5), h - Inches(0.6), bullets, size=12, color=_rgb("#7F1D1D"))

    risk(x, "가짜 정보 생성 사례", ["존재하지 않는 논문·자료 인용", "역사적 사실을 왜곡하여 설명", "없는 기능을 가진 것처럼 설명"])
    risk(x + w + g, "수치 오류 사례", ["틀린 계산 결과를 정확한 척 제시", "단위(원, 달러) 혼동하여 표기", "최신 통계가 아닌 과거 데이터 인용"])
    risk(x + (w + g) * 2, "법적/규정 위험 사례", ["개정 전 법률이나 규정을 답변", "저작권/라이선스 규정을 무시한 활용", "개인정보 보호 규정을 위반하는 제안"])

    add_textbox(s, Inches(0.7), Inches(4.85), Inches(12), Inches(0.3), "✅  환각을 피하는 3가지 습관", size=16, bold=True, color=_rgb("#15803D"))

    # Habits
    hy = Inches(5.2)
    hw = Inches(3.82)
    hh = Inches(1.1)

    def habit(xx, title, desc):
        add_rect(s, xx, hy, hw, hh, fill=_rgb("#E9FBF1"), line=_rgb("#BBF7D0"), radius=True)
        add_textbox(s, xx + Inches(0.25), hy + Inches(0.25), hw - Inches(0.5), Inches(0.25), title, size=14, bold=True, color=_rgb("#15803D"), align=PP_ALIGN.CENTER)
        add_textbox(s, xx + Inches(0.25), hy + Inches(0.55), hw - Inches(0.5), Inches(0.4), desc, size=12, bold=False, color=_rgb("#166534"), align=PP_ALIGN.CENTER, line_spacing=1.2)

    habit(Inches(0.7), "원문 대조 확인", "중요한 수치·법률·사실 관계는\n반드시 원문 문서와 대조하세요.")
    habit(Inches(0.7) + hw + g, "출처 요청하기", "\"이 정보의 출처(URL)를 알려줘\"라고\n요청하여 근거를 확인하세요.")
    habit(Inches(0.7) + (hw + g) * 2, "'초안'으로만 활용", "AI 답변은 최종 결과물이 아닌\n'검토가 필요한 초안'으로 대하세요.")

    add_footer(s, 5, dark=False)


def slide_06_prompt_definition(prs: Presentation) -> None:
    s = prs.slides.add_slide(prs.slide_layouts[6])
    set_slide_bg(s, T.bg)
    add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 2. 입력의 질이 출력의 질을 결정한다", size=14, bold=True, color=T.muted)
    add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "프롬프트란 무엇인가?", size=40, bold=True, color=T.text)
    add_textbox(s, Inches(0.7), Inches(1.55), Inches(12), Inches(0.35), "AI와 소통하는 \"언어\" — 목적·상황·제약·형식을 한 번에 전달하는 지시서", size=16, bold=True, color=T.muted)

    add_textbox(s, Inches(0.7), Inches(2.1), Inches(12), Inches(0.3), "나쁜 프롬프트  vs  좋은 프롬프트 (예시 3가지)", size=16, bold=True, color=T.text)
    rows = [
        ("보고서 써줘", "대상(누가 읽는지), 목적(왜), 형식(목차/분량)을 포함해서\n\"임원 보고용 1페이지 요약\"으로 작성해줘."),
        ("요약해줘", "\"다음 글을 3줄 요약 + 핵심 키워드 5개\" 형식으로 요약해줘."),
        ("분석해줘", "\"표로 정리(열: 문제, 원인, 영향, 개선안)\" 하고,\n결론을 먼저 제시한 뒤 근거를 번호로 달아줘."),
    ]
    y = Inches(2.5)
    for i, (bad, good) in enumerate(rows):
        yy = y + Inches(1.25) * i
        add_rect(s, Inches(0.7), yy, Inches(5.9), Inches(1.05), fill=_rgb("#FFF1F2"), line=_rgb("#FECACA"), radius=True)
        add_rect(s, Inches(6.75), yy, Inches(5.88), Inches(1.05), fill=_rgb("#E9FBF1"), line=_rgb("#BBF7D0"), radius=True)
        add_textbox(s, Inches(0.95), yy + Inches(0.2), Inches(5.4), Inches(0.25), "❌ 나쁜 프롬프트", size=12, bold=True, color=_rgb("#B91C1C"))
        add_textbox(s, Inches(7.0), yy + Inches(0.2), Inches(5.4), Inches(0.25), "✅ 좋은 프롬프트", size=12, bold=True, color=_rgb("#15803D"))
        add_textbox(s, Inches(0.95), yy + Inches(0.5), Inches(5.4), Inches(0.5), bad, size=18, bold=True, color=_rgb("#7F1D1D"))
        add_textbox(s, Inches(7.0), yy + Inches(0.5), Inches(5.4), Inches(0.6), good, size=14, bold=False, color=_rgb("#166534"), line_spacing=1.15)

    add_footer(s, 6, dark=False)


def slide_07_language(prs: Presentation) -> None:
    s = prs.slides.add_slide(prs.slide_layouts[6])
    set_slide_bg(s, T.bg)
    add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 2. 프롬프트 설계 원칙", size=14, bold=True, color=T.muted)
    add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "[사례 1] 언어 선택: 한국어  vs  영어", size=34, bold=True, color=T.text)

    add_rect(s, Inches(0.7), Inches(1.9), Inches(11.93), Inches(2.3), fill=T.white, line=T.line, radius=True)
    add_textbox(s, Inches(1.0), Inches(2.15), Inches(11.3), Inches(0.3), "왜 영어 입력이 더 정확한 경우가 있는가?", size=18, bold=True, color=T.text)
    add_bullets(
        s,
        Inches(1.0),
        Inches(2.55),
        Inches(11.3),
        Inches(1.4),
        ["학습 데이터 불균형 (영어 데이터가 압도적으로 많음)", "전문 용어·기술 용어의 영어 표현이 더 풍부", "일부 모델/도구는 영어 지시에서 더 안정적으로 동작"],
        size=16,
        color=T.text,
    )
    add_rect(s, Inches(0.7), Inches(4.45), Inches(11.93), Inches(1.35), fill=_rgb("#24364D"), line=None, radius=True)
    add_textbox(s, Inches(1.0), Inches(4.62), Inches(5.8), Inches(0.3), "실무 팁", size=14, bold=True, color=T.accent_yellow)
    add_textbox(s, Inches(1.0), Inches(4.92), Inches(6.6), Inches(0.7), "영어로 묻고, 한국어로 출력 요청하기\n예) \"Answer in Korean, and format as a table.\"", size=14, bold=True, color=_rgb("#E5E7EB"), line_spacing=1.2)
    add_textbox(s, Inches(8.0), Inches(4.75), Inches(4.4), Inches(0.9), "실습\n동일 질문 한/영 비교 결과 시연", size=16, bold=True, color=_rgb("#E5E7EB"), align=PP_ALIGN.CENTER, line_spacing=1.2)
    add_footer(s, 7, dark=False)


def slide_08_context(prs: Presentation) -> None:
    s = prs.slides.add_slide(prs.slide_layouts[6])
    set_slide_bg(s, T.bg)
    add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 2. 프롬프트 설계 원칙", size=14, bold=True, color=T.muted)
    add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "[사례 2] 정보의 완전성 — 맥락이 없으면 중의성이 생긴다", size=28, bold=True, color=T.text)
    add_textbox(s, Inches(0.7), Inches(1.55), Inches(12), Inches(0.35), "핵심 원리: \"목적 + 상황 + 제약 조건\"을 모두 포함하라", size=16, bold=True, color=T.muted)

    add_rect(s, Inches(0.7), Inches(2.05), Inches(11.93), Inches(1.9), fill=T.white, line=T.line, radius=True)
    add_rect(s, Inches(0.7), Inches(2.05), Inches(5.8), Inches(1.9), fill=_rgb("#FFF1F2"), line=None, radius=True)
    add_rect(s, Inches(6.83), Inches(2.05), Inches(5.8), Inches(1.9), fill=_rgb("#E9FBF1"), line=None, radius=True)
    add_textbox(s, Inches(1.05), Inches(2.25), Inches(5.2), Inches(0.3), "❌ 중의적", size=14, bold=True, color=_rgb("#B91C1C"))
    add_textbox(s, Inches(7.15), Inches(2.25), Inches(5.2), Inches(0.3), "✅ 명확", size=14, bold=True, color=_rgb("#15803D"))
    add_textbox(s, Inches(1.05), Inches(2.65), Inches(5.2), Inches(0.8), "\"세차장에 갑니다. 걸어갈까요?\"", size=22, bold=True, color=_rgb("#7F1D1D"), line_spacing=1.1)
    add_textbox(s, Inches(7.15), Inches(2.65), Inches(5.2), Inches(0.8), "\"세차하러 갑니다. 걸어갈까요?\"", size=22, bold=True, color=_rgb("#166534"), line_spacing=1.1)
    add_textbox(s, Inches(1.05), Inches(3.35), Inches(5.2), Inches(0.4), "목적이 빠지면 해석이 여러 개로 갈립니다.", size=14, bold=False, color=_rgb("#7F1D1D"))
    add_textbox(s, Inches(7.15), Inches(3.35), Inches(5.2), Inches(0.4), "목적을 넣으면 AI도 명확히 답합니다.", size=14, bold=False, color=_rgb("#166534"))

    add_rect(s, Inches(0.7), Inches(4.2), Inches(11.93), Inches(1.85), fill=_rgb("#24364D"), line=None, radius=True)
    add_textbox(s, Inches(1.0), Inches(4.35), Inches(11.3), Inches(0.3), "실무 적용", size=14, bold=True, color=T.accent_yellow)
    add_bullets(
        s,
        Inches(1.0),
        Inches(4.7),
        Inches(11.3),
        Inches(1.2),
        ["보고서/기획서 요청 시: \"누가 읽는지\"(대상) + \"목적\" + \"형식(분량/목차)\"을 함께 제공", "제약 조건(기간/데이터 범위/금지사항)을 명시하면 결과가 안정적으로 개선"],
        size=15,
        color=_rgb("#E5E7EB"),
    )
    add_footer(s, 8, dark=False)


def slide_09_5w1h(prs: Presentation) -> None:
    s = prs.slides.add_slide(prs.slide_layouts[6])
    set_slide_bg(s, T.bg)
    add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 2. 프롬프트 설계 원칙", size=14, bold=True, color=T.muted)
    add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "5W1H 프롬프트 프레임", size=40, bold=True, color=T.text)

    frame = [
        ("Who", "역할 설정", "예: \"너는 제약업계 10년 경력의 마케터야\""),
        ("What", "원하는 산출물", "예: \"임원 보고용 1페이지 요약\""),
        ("Why", "목적·배경", "예: \"AX 과제 선정 회의 자료로 사용할 거야\""),
        ("When/Where", "상황·컨텍스트", "예: \"지난 분기 데이터 기준, 국내 시장\""),
        ("How", "출력 형식", "예: \"표(열: 항목, 근거, 리스크) + 결론 먼저\""),
    ]
    y = Inches(2.0)
    row_h = Inches(0.95)
    for i, (k, t, ex) in enumerate(frame):
        yy = y + row_h * i
        add_rect(s, Inches(0.7), yy, Inches(11.93), row_h - Inches(0.12), fill=T.white, line=T.line, radius=True)
        add_rect(s, Inches(0.7), yy, Inches(1.6), row_h - Inches(0.12), fill=_rgb("#24364D"), line=None, radius=True)
        add_textbox(s, Inches(0.7), yy + Inches(0.18), Inches(1.6), Inches(0.3), k, size=16, bold=True, color=T.accent_yellow, align=PP_ALIGN.CENTER)
        add_textbox(s, Inches(2.45), yy + Inches(0.18), Inches(3.2), Inches(0.3), t, size=18, bold=True, color=T.text)
        add_textbox(s, Inches(2.45), yy + Inches(0.5), Inches(9.9), Inches(0.35), ex, size=14, bold=False, color=T.muted)
    add_footer(s, 9, dark=False)


def slide_10_format(prs: Presentation) -> None:
    s = prs.slides.add_slide(prs.slide_layouts[6])
    set_slide_bg(s, T.bg)
    add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 2. 프롬프트 설계 원칙", size=14, bold=True, color=T.muted)
    add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "출력 형식을 지정하라", size=40, bold=True, color=T.text)
    add_textbox(s, Inches(0.7), Inches(1.55), Inches(12), Inches(0.35), "형식을 안 주면 AI가 알아서 결정 → 원하는 형태가 아닐 수 있음", size=16, bold=True, color=T.muted)

    add_rect(s, Inches(0.7), Inches(2.05), Inches(5.9), Inches(3.0), fill=_rgb("#FFF1F2"), line=_rgb("#FECACA"), radius=True)
    add_rect(s, Inches(6.75), Inches(2.05), Inches(5.88), Inches(3.0), fill=_rgb("#E9FBF1"), line=_rgb("#BBF7D0"), radius=True)
    add_textbox(s, Inches(0.95), Inches(2.25), Inches(5.4), Inches(0.3), "Before", size=14, bold=True, color=_rgb("#B91C1C"))
    add_textbox(s, Inches(7.0), Inches(2.25), Inches(5.4), Inches(0.3), "After", size=14, bold=True, color=_rgb("#15803D"))
    add_textbox(s, Inches(0.95), Inches(2.65), Inches(5.4), Inches(1.0), "\"이 자료 분석해줘\"", size=22, bold=True, color=_rgb("#7F1D1D"))
    add_textbox(
        s,
        Inches(7.0),
        Inches(2.65),
        Inches(5.4),
        Inches(1.4),
        "\"표로 만들어줘 (열: 항목명, 장점, 단점)\"\n\"3줄 요약으로\"\n\"결론 먼저, 근거는 번호 순으로\"",
        size=16,
        bold=True,
        color=_rgb("#166534"),
        line_spacing=1.2,
    )
    add_rect(s, Inches(0.7), Inches(5.25), Inches(11.93), Inches(1.1), fill=_rgb("#24364D"), line=None, radius=True)
    add_textbox(
        s,
        Inches(1.0),
        Inches(5.4),
        Inches(11.3),
        Inches(0.8),
        "체크포인트\n- 형식(표/글머리/단계)\n- 분량(3줄/1페이지)\n- 순서(결론 먼저)\n- 톤(전문/간결/친절)",
        size=14,
        bold=True,
        color=_rgb("#E5E7EB"),
        line_spacing=1.15,
    )
    add_footer(s, 10, dark=False)


def slide_11_role(prs: Presentation) -> None:
    s = prs.slides.add_slide(prs.slide_layouts[6])
    set_slide_bg(s, T.bg)
    add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 2. 프롬프트 설계 원칙", size=14, bold=True, color=T.muted)
    add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "역할 부여(Role Prompting) 기법", size=36, bold=True, color=T.text)
    add_textbox(s, Inches(0.7), Inches(1.55), Inches(12), Inches(0.35), "\"너는 ○○이야\" 선언의 효과: 관점·깊이·어조를 통제", size=16, bold=True, color=T.muted)

    add_rect(s, Inches(0.7), Inches(2.05), Inches(11.93), Inches(2.1), fill=T.white, line=T.line, radius=True)
    add_textbox(s, Inches(1.0), Inches(2.25), Inches(11.3), Inches(0.3), "예시", size=14, bold=True, color=T.muted)
    add_rect(s, Inches(1.0), Inches(2.6), Inches(11.3), Inches(1.35), fill=_rgb("#24364D"), line=None, radius=True)
    add_textbox(
        s,
        Inches(1.3),
        Inches(2.75),
        Inches(10.7),
        Inches(1.0),
        "너는 대웅제약 CFO야.\n다음 데이터를 분석해줘. (목표: 비용 절감 관점, 리스크 포함, 1페이지 요약)",
        size=18,
        bold=True,
        color=_rgb("#E5E7EB"),
        line_spacing=1.2,
    )

    add_rect(s, Inches(0.7), Inches(4.35), Inches(11.93), Inches(2.0), fill=_rgb("#E9FBF1"), line=_rgb("#BBF7D0"), radius=True)
    add_textbox(s, Inches(1.0), Inches(4.55), Inches(11.3), Inches(0.3), "실습", size=14, bold=True, color=_rgb("#15803D"))
    add_bullets(
        s,
        Inches(1.0),
        Inches(4.9),
        Inches(11.3),
        Inches(1.3),
        ["동일 데이터를 영업팀장 / 재무팀장 / CEO 역할로 각각 분석", "출력의 관점·강조점·결론이 어떻게 달라지는지 비교"],
        size=16,
        color=_rgb("#166534"),
    )
    add_footer(s, 11, dark=False)


def slide_12_steps(prs: Presentation) -> None:
    s = prs.slides.add_slide(prs.slide_layouts[6])
    set_slide_bg(s, T.bg)
    add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 3. AI를 더 똑똑하게 쓰는 고급 기법", size=14, bold=True, color=T.muted)
    add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "단계적 사고 유도", size=40, bold=True, color=T.text)
    add_textbox(s, Inches(0.7), Inches(1.55), Inches(12), Inches(0.35), "복잡한 문제일수록 절차(단계)를 나눠서 요청하면 결과가 좋아집니다.", size=16, bold=True, color=T.muted)

    add_rect(s, Inches(0.7), Inches(2.0), Inches(11.93), Inches(1.8), fill=T.white, line=T.line, radius=True)
    add_textbox(s, Inches(1.0), Inches(2.2), Inches(11.3), Inches(0.3), "좋은 요청 방식", size=14, bold=True, color=T.muted)
    add_bullets(
        s,
        Inches(1.0),
        Inches(2.55),
        Inches(11.3),
        Inches(1.1),
        ["\"문제를 단계별로 해결 절차로 나눠서 제시해줘\"", "\"각 단계마다 체크리스트를 만들고, 누락된 정보를 질문해줘\"", "\"최종 답변은 마지막에 요약해줘\""],
        size=16,
        color=T.text,
    )
    add_rect(s, Inches(0.7), Inches(4.05), Inches(11.93), Inches(2.3), fill=_rgb("#24364D"), line=None, radius=True)
    add_textbox(s, Inches(1.0), Inches(4.25), Inches(11.3), Inches(0.3), "예시 (AX 과제 선정 기준 적용)", size=14, bold=True, color=T.accent_yellow)
    add_textbox(
        s,
        Inches(1.0),
        Inches(4.55),
        Inches(11.3),
        Inches(1.6),
        "과제 후보 3개를 아래 체크리스트 7개 기준으로 하나씩 평가해줘.\n"
        "1) 목표 명확성  2) 데이터 확보 가능성  3) 기대효과(정량/정성)\n"
        "4) 구현 난이도  5) 리스크(보안/규정)  6) 확장성  7) 일정 적합성\n"
        "출력: 표(열: 기준, 평가, 근거, 리스크) + 결론(우선순위) 먼저",
        size=15,
        bold=True,
        color=_rgb("#E5E7EB"),
        line_spacing=1.2,
    )
    add_footer(s, 12, dark=False)


def slide_13_fewshot(prs: Presentation) -> None:
    s = prs.slides.add_slide(prs.slide_layouts[6])
    set_slide_bg(s, T.bg)
    add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 3. 고급 기법", size=14, bold=True, color=T.muted)
    add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "예시 제공 (Few‑Shot Prompting)", size=34, bold=True, color=T.text)
    add_textbox(s, Inches(0.7), Inches(1.55), Inches(12), Inches(0.35), "\"이런 식으로 해줘\" — 예시 1~3개의 위력", size=16, bold=True, color=T.muted)

    add_rect(s, Inches(0.7), Inches(2.0), Inches(11.93), Inches(2.25), fill=T.white, line=T.line, radius=True)
    add_textbox(s, Inches(1.0), Inches(2.2), Inches(11.3), Inches(0.3), "효과", size=14, bold=True, color=T.muted)
    add_bullets(s, Inches(1.0), Inches(2.55), Inches(11.3), Inches(1.5), ["출력 형식, 어조, 수준을 예시로 통제", "모호한 요구를 '정답 샘플'로 명확히 전달", "팀 내 산출물 스타일을 표준화"], size=16, color=T.text)

    add_rect(s, Inches(0.7), Inches(4.45), Inches(11.93), Inches(1.9), fill=_rgb("#E9FBF1"), line=_rgb("#BBF7D0"), radius=True)
    add_textbox(s, Inches(1.0), Inches(4.65), Inches(11.3), Inches(0.3), "[사례 3] 응용", size=14, bold=True, color=_rgb("#15803D"))
    add_textbox(
        s,
        Inches(1.0),
        Inches(4.95),
        Inches(11.3),
        Inches(1.2),
        "`20260223_report_10.doc`를 예시로 제공 → 동일 형식의 보고서를 자동 생성\n"
        "프롬프트에 \"예시 문서의 목차/톤/표현을 유지\" 조건을 포함",
        size=16,
        bold=True,
        color=_rgb("#166534"),
        line_spacing=1.2,
    )
    add_footer(s, 13, dark=False)


def slide_14_context_window(prs: Presentation) -> None:
    s = prs.slides.add_slide(prs.slide_layouts[6])
    set_slide_bg(s, T.bg)
    add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 3. 고급 기법", size=14, bold=True, color=T.muted)
    add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "맥락 누적 활용 (Context Window 관리)", size=30, bold=True, color=T.text)
    add_textbox(s, Inches(0.7), Inches(1.55), Inches(12), Inches(0.35), "대화가 길어질수록 앞 조건을 잊을 수 있으니, 핵심 조건을 관리해야 합니다.", size=16, bold=True, color=T.muted)

    add_rect(s, Inches(0.7), Inches(2.05), Inches(11.93), Inches(1.8), fill=T.white, line=T.line, radius=True)
    add_textbox(s, Inches(1.0), Inches(2.25), Inches(11.3), Inches(0.3), "실무 습관", size=14, bold=True, color=T.muted)
    add_bullets(
        s,
        Inches(1.0),
        Inches(2.6),
        Inches(11.3),
        Inches(1.2),
        ["중요한 조건은 대화 앞부분에 배치", "새 대화 시작 시 \"지금까지 정한 것\" 요약을 먼저 붙여넣기", "긴 문서는 분할(Chunk) + 요약 누적 전략 사용"],
        size=16,
        color=T.text,
    )

    add_rect(s, Inches(0.7), Inches(4.05), Inches(11.93), Inches(2.3), fill=_rgb("#24364D"), line=None, radius=True)
    add_textbox(s, Inches(1.0), Inches(4.25), Inches(11.3), Inches(0.3), "분할 전략 예시", size=14, bold=True, color=T.accent_yellow)
    add_textbox(
        s,
        Inches(1.0),
        Inches(4.55),
        Inches(11.3),
        Inches(1.6),
        "1) 문서를 3~5페이지 단위로 나눠 요약 요청\n"
        "2) 각 요약을 '핵심 포인트/결정사항/숫자' 위주로 정리\n"
        "3) 마지막에 모든 요약을 합쳐 최종 보고서 작성 요청",
        size=16,
        bold=True,
        color=_rgb("#E5E7EB"),
        line_spacing=1.2,
    )
    add_footer(s, 14, dark=False)


def slide_15_iterative(prs: Presentation) -> None:
    s = prs.slides.add_slide(prs.slide_layouts[6])
    set_slide_bg(s, T.bg)
    add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 3. 고급 기법", size=14, bold=True, color=T.muted)
    add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "반복 정제 (Iterative Refinement)", size=34, bold=True, color=T.text)
    add_textbox(s, Inches(0.7), Inches(1.55), Inches(12), Inches(0.35), "첫 번째 답이 완벽할 필요는 없습니다. 초안 → 피드백 → 확정", size=16, bold=True, color=T.muted)

    add_rect(s, Inches(0.7), Inches(2.05), Inches(11.93), Inches(2.0), fill=T.white, line=T.line, radius=True)
    add_textbox(s, Inches(1.0), Inches(2.25), Inches(11.3), Inches(0.3), "자주 쓰는 후속 프롬프트", size=14, bold=True, color=T.muted)
    add_bullets(
        s,
        Inches(1.0),
        Inches(2.6),
        Inches(11.3),
        Inches(1.3),
        ["\"더 간결하게\"", "\"3번 항목을 더 구체적으로\"", "\"전문적 어조로 바꿔줘\"", "\"표로 재구성해줘\"", "\"리스크/반론도 함께 제시해줘\""],
        size=16,
        color=T.text,
    )

    add_rect(s, Inches(0.7), Inches(4.25), Inches(11.93), Inches(2.1), fill=_rgb("#E9FBF1"), line=_rgb("#BBF7D0"), radius=True)
    add_textbox(s, Inches(1.0), Inches(4.45), Inches(11.3), Inches(0.3), "실무 비유", size=14, bold=True, color=_rgb("#15803D"))
    add_textbox(
        s,
        Inches(1.0),
        Inches(4.75),
        Inches(11.3),
        Inches(1.4),
        "AI는 탁월한 \"초안 작성자\"입니다.\n"
        "사람은 검토자(Reviewer)로서 방향을 잡고, 근거·수치·규정을 확인해 완성도를 올립니다.",
        size=18,
        bold=True,
        color=_rgb("#166534"),
        line_spacing=1.2,
    )
    add_footer(s, 15, dark=False)


def slide_16_files(prs: Presentation) -> None:
    s = prs.slides.add_slide(prs.slide_layouts[6])
    set_slide_bg(s, T.bg)
    add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 3. 고급 기법", size=14, bold=True, color=T.muted)
    add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "파일·데이터 연동 활용", size=40, bold=True, color=T.text)
    add_textbox(s, Inches(0.7), Inches(1.55), Inches(12), Inches(0.35), "CSV, Excel, Word, PDF 등 정형/반정형 데이터를 먹이면 성능이 크게 개선됩니다.", size=16, bold=True, color=T.muted)

    add_rect(s, Inches(0.7), Inches(2.05), Inches(11.93), Inches(2.35), fill=T.white, line=T.line, radius=True)
    add_textbox(s, Inches(1.0), Inches(2.25), Inches(11.3), Inches(0.3), "실무 예시", size=14, bold=True, color=T.muted)
    add_bullets(
        s,
        Inches(1.0),
        Inches(2.6),
        Inches(11.3),
        Inches(1.7),
        ["채용: 지원서(CSV) + 평가 기준(문서) → 자동 평가 코멘트 생성", "과제 선정: 신청 양식 + 프로세스 문서 → 기준별 점수/근거 표 생성", "성과 평가: KPI 테이블 + 코멘트 → 요약 및 이슈 탐지"],
        size=16,
        color=T.text,
    )

    add_rect(s, Inches(0.7), Inches(4.6), Inches(11.93), Inches(1.75), fill=_rgb("#24364D"), line=None, radius=True)
    add_textbox(s, Inches(1.0), Inches(4.8), Inches(11.3), Inches(0.3), "포인트: 데이터 구조화", size=14, bold=True, color=T.accent_yellow)
    add_textbox(
        s,
        Inches(1.0),
        Inches(5.1),
        Inches(11.3),
        Inches(1.1),
        "AI는 정형 데이터(표/필드)를 더 잘 처리합니다.\n"
        "입력 데이터에 컬럼명, 단위, 기간, 정의를 명시하면 오류가 크게 줄어듭니다.",
        size=16,
        bold=True,
        color=_rgb("#E5E7EB"),
        line_spacing=1.2,
    )
    add_footer(s, 16, dark=False)


def slide_17_trust(prs: Presentation) -> None:
    s = prs.slides.add_slide(prs.slide_layouts[6])
    set_slide_bg(s, T.bg)
    add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 4. 실수하지 않는 AI 활용법", size=14, bold=True, color=T.muted)
    add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "AI를 믿어야 할 때  vs  검증해야 할 때", size=28, bold=True, color=T.text)

    add_rect(s, Inches(0.7), Inches(1.9), Inches(5.9), Inches(4.45), fill=_rgb("#E9FBF1"), line=_rgb("#BBF7D0"), radius=True)
    add_rect(s, Inches(6.75), Inches(1.9), Inches(5.88), Inches(4.45), fill=_rgb("#FFF1F2"), line=_rgb("#FECACA"), radius=True)
    add_textbox(s, Inches(0.95), Inches(2.15), Inches(5.4), Inches(0.35), "믿어도 되는 경우", size=18, bold=True, color=_rgb("#15803D"))
    add_textbox(s, Inches(7.0), Inches(2.15), Inches(5.4), Inches(0.35), "반드시 검증", size=18, bold=True, color=_rgb("#B91C1C"))
    add_bullets(s, Inches(0.95), Inches(2.6), Inches(5.4), Inches(3.6), ["형식 작업(문장 다듬기, 문서 구성)", "요약, 번역", "초안 작성(메일/보고서)", "코드 생성(단, 테스트/리뷰 필수)"], size=16, color=_rgb("#166534"))
    add_bullets(s, Inches(7.0), Inches(2.6), Inches(5.4), Inches(3.6), ["수치·통계", "법률·규정", "최신 정보", "사람 이름/조직명", "의사결정에 영향을 주는 사실"], size=16, color=_rgb("#7F1D1D"))

    add_rect(s, Inches(0.7), Inches(6.55), Inches(11.93), Inches(0.65), fill=_rgb("#24364D"), line=None, radius=True)
    add_textbox(s, Inches(1.0), Inches(6.68), Inches(11.3), Inches(0.4), "\"AI가 틀렸다\"가 아니라 \"내가 확인하지 않았다\"", size=18, bold=True, color=_rgb("#E5E7EB"), align=PP_ALIGN.CENTER)
    add_footer(s, 17, dark=False)


def slide_18_security(prs: Presentation) -> None:
    s = prs.slides.add_slide(prs.slide_layouts[6])
    set_slide_bg(s, T.bg)
    add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 4. 보안과 개인정보", size=14, bold=True, color=T.muted)
    add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "무엇을 넣으면 안 되는가", size=40, bold=True, color=T.text)
    add_rect(s, Inches(0.7), Inches(1.9), Inches(11.93), Inches(2.45), fill=_rgb("#FFF1F2"), line=_rgb("#FECACA"), radius=True)
    add_textbox(s, Inches(1.0), Inches(2.1), Inches(11.3), Inches(0.3), "입력 금지", size=16, bold=True, color=_rgb("#B91C1C"))
    add_bullets(s, Inches(1.0), Inches(2.45), Inches(11.3), Inches(1.8), ["사내 기밀 데이터", "개인식별정보(PII): 이름/주민번호/연락처/계좌/주소 등", "고객·환자·직원 데이터 원문", "계약서/특허 등 민감 문서의 원문"], size=16, color=_rgb("#7F1D1D"))

    add_rect(s, Inches(0.7), Inches(4.55), Inches(11.93), Inches(1.8), fill=_rgb("#E9FBF1"), line=_rgb("#BBF7D0"), radius=True)
    add_textbox(s, Inches(1.0), Inches(4.75), Inches(11.3), Inches(0.3), "대안", size=16, bold=True, color=_rgb("#15803D"))
    add_bullets(s, Inches(1.0), Inches(5.1), Inches(11.3), Inches(1.1), ["가명화/익명화 후 활용 (ID 치환, 숫자 범위화)", "내부/사내 AI 툴 사용 여부 확인", "필요 최소 정보만 제공 + 출력은 요약 중심"], size=16, color=_rgb("#166534"))
    add_footer(s, 18, dark=False)


def slide_19_copyright(prs: Presentation) -> None:
    s = prs.slides.add_slide(prs.slide_layouts[6])
    set_slide_bg(s, T.bg)
    add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 4. 저작권과 책임", size=14, bold=True, color=T.muted)
    add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "AI 결과물의 저작권과 책임", size=36, bold=True, color=T.text)
    add_rect(s, Inches(0.7), Inches(1.9), Inches(11.93), Inches(4.45), fill=T.white, line=T.line, radius=True)
    add_bullets(
        s,
        Inches(1.0),
        Inches(2.2),
        Inches(11.3),
        Inches(3.8),
        ["AI 생성물의 법적 지위는 국가/시점/정책에 따라 달라질 수 있음", "출처 표기와 사실 확인의 의무는 사용자에게 있음", "최종 결과물에 대한 책임은 항상 사람에게", "사내 가이드라인(대웅그룹 AI 활용 가이드라인)과 연계해 준수"],
        size=18,
        color=T.text,
    )
    add_footer(s, 19, dark=False)


def slide_20_skills(prs: Presentation) -> None:
    s = prs.slides.add_slide(prs.slide_layouts[6])
    set_slide_bg(s, T.bg)
    add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 4. 역량 재정의", size=14, bold=True, color=T.muted)
    add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "AI 환경에서의 직무 역량 재정의", size=30, bold=True, color=T.text)
    add_rect(s, Inches(0.7), Inches(1.9), Inches(5.9), Inches(4.45), fill=_rgb("#FFF1F2"), line=_rgb("#FECACA"), radius=True)
    add_rect(s, Inches(6.75), Inches(1.9), Inches(5.88), Inches(4.45), fill=_rgb("#E9FBF1"), line=_rgb("#BBF7D0"), radius=True)
    add_textbox(s, Inches(0.95), Inches(2.15), Inches(5.4), Inches(0.35), "상대적으로 약해지는 역량", size=16, bold=True, color=_rgb("#B91C1C"))
    add_textbox(s, Inches(7.0), Inches(2.15), Inches(5.4), Inches(0.35), "더 중요해지는 역량", size=16, bold=True, color=_rgb("#15803D"))
    add_bullets(s, Inches(0.95), Inches(2.55), Inches(5.4), Inches(3.7), ["단순 요약/정리", "반복 문서 작성", "기본 번역", "정형 보고서 초안"], size=16, color=_rgb("#7F1D1D"))
    add_bullets(s, Inches(7.0), Inches(2.55), Inches(5.4), Inches(3.7), ["문제 정의와 목표 설정", "좋은 질문(프롬프트) 설계", "검증·리스크 관리", "의사결정과 책임", "업무 프로세스 설계(워크플로우)"], size=16, color=_rgb("#166534"))
    add_rect(s, Inches(0.7), Inches(6.55), Inches(11.93), Inches(0.65), fill=_rgb("#24364D"), line=None, radius=True)
    add_textbox(s, Inches(1.0), Inches(6.68), Inches(11.3), Inches(0.4), "\"AI에게 좋은 질문을 하는 능력\" = 새로운 핵심 역량", size=18, bold=True, color=_rgb("#E5E7EB"), align=PP_ALIGN.CENTER)
    add_footer(s, 20, dark=False)


def slide_21_scenarios(prs: Presentation) -> None:
    s = prs.slides.add_slide(prs.slide_layouts[6])
    set_slide_bg(s, T.bg)
    add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 5. 실전 적용 — 대웅 AX 과제와 연결", size=14, bold=True, color=T.muted)
    add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "부서별 AI 활용 시나리오 맵", size=40, bold=True, color=T.text)

    cards = [
        ("영업", ["채권 현황 조회", "인사이트 자동 생성"], T.accent_blue),
        ("마케팅", ["대시보드 결산 자동 작성", "기사/콘텐츠 초안 생성"], T.accent_yellow),
        ("재무/회계", ["지출 증빙 검토 자동화", "이상 지출 탐지"], T.accent_green),
        ("연구개발", ["특허·논문 요약", "보고서 초안"], _rgb("#A855F7")),
        ("HR", ["면접 분석", "교육 콘텐츠 생성"], T.accent_red),
    ]
    x0 = Inches(0.7)
    y0 = Inches(2.0)
    w = Inches(3.82)
    h = Inches(1.75)
    g = Inches(0.35)
    positions = [
        (x0, y0),
        (x0 + w + g, y0),
        (x0 + (w + g) * 2, y0),
        (x0 + w / 2 + g / 2, y0 + h + g),
        (x0 + (w + g) * 1.5, y0 + h + g),
    ]
    for (title, lines, accent), (xx, yy) in zip(cards, positions, strict=True):
        add_rect(s, xx, yy, w, h, fill=T.white, line=T.line, radius=True)
        add_rect(s, xx, yy, w, Inches(0.08), fill=accent, line=None)
        add_textbox(s, xx + Inches(0.25), yy + Inches(0.35), w - Inches(0.5), Inches(0.3), title, size=18, bold=True, color=T.text)
        add_bullets(s, xx + Inches(0.25), yy + Inches(0.75), w - Inches(0.5), Inches(0.9), lines, size=14, color=T.muted)
    add_footer(s, 21, dark=False)


def slide_22_ax_application(prs: Presentation) -> None:
    s = prs.slides.add_slide(prs.slide_layouts[6])
    set_slide_bg(s, T.bg)
    add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 5. 실전 적용", size=14, bold=True, color=T.muted)
    add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "AX 과제 신청 단계에서의 AI 활용", size=32, bold=True, color=T.text)
    add_textbox(s, Inches(0.7), Inches(1.55), Inches(12), Inches(0.35), "신청서 작성 → 자기검토 → 평가 기준 정렬까지 한 번에", size=16, bold=True, color=T.muted)

    add_rect(s, Inches(0.7), Inches(2.05), Inches(11.93), Inches(2.25), fill=T.white, line=T.line, radius=True)
    add_textbox(s, Inches(1.0), Inches(2.25), Inches(11.3), Inches(0.3), "활용 포인트", size=14, bold=True, color=T.muted)
    add_bullets(
        s,
        Inches(1.0),
        Inches(2.6),
        Inches(11.3),
        Inches(1.6),
        ["신청서 작성 시 AI 도움받기: As‑Is → To‑Be 구조화", "과제 평가 기준에 맞는 자기검토(누락 항목 질문하도록)", "정량 효과/리스크(보안·규정)까지 포함해 완성도 향상"],
        size=16,
        color=T.text,
    )
    add_rect(s, Inches(0.7), Inches(4.55), Inches(11.93), Inches(1.8), fill=_rgb("#24364D"), line=None, radius=True)
    add_textbox(s, Inches(1.0), Inches(4.75), Inches(11.3), Inches(0.3), "데모 데이터", size=14, bold=True, color=T.accent_yellow)
    add_textbox(
        s,
        Inches(1.0),
        Inches(5.05),
        Inches(11.3),
        Inches(1.2),
        "`20260223.csv` + `AX추진프로세스.docx` → 자동 평가 보고서 생성 시연",
        size=18,
        bold=True,
        color=_rgb("#E5E7EB"),
        line_spacing=1.2,
    )
    add_footer(s, 22, dark=False)


def slide_23_routine(prs: Presentation) -> None:
    s = prs.slides.add_slide(prs.slide_layouts[6])
    set_slide_bg(s, T.bg)
    add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 5. 실전 적용", size=14, bold=True, color=T.muted)
    add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "나만의 AI 활용 루틴 만들기", size=40, bold=True, color=T.text)

    cards = [
        ("Daily", "AI 초안 작성 → 내가 검토·수정", T.accent_blue),
        ("Weekly", "반복 업무 프롬프트 템플릿화", T.accent_green),
        ("Monthly", "AI 활용 성과 측정 (시간 절감, 품질)", T.accent_yellow),
    ]
    x = Inches(0.7)
    y = Inches(2.05)
    w = Inches(3.82)
    h = Inches(2.0)
    g = Inches(0.35)
    for i, (t, d, a) in enumerate(cards):
        xx = x + (w + g) * i
        add_rect(s, xx, y, w, h, fill=T.white, line=T.line, radius=True)
        add_rect(s, xx, y, w, Inches(0.08), fill=a, line=None)
        add_textbox(s, xx + Inches(0.25), y + Inches(0.45), w - Inches(0.5), Inches(0.3), t, size=18, bold=True, color=T.text)
        add_textbox(s, xx + Inches(0.25), y + Inches(0.85), w - Inches(0.5), Inches(0.9), d, size=16, bold=True, color=T.muted, line_spacing=1.2)

    add_rect(s, Inches(0.7), Inches(4.35), Inches(11.93), Inches(2.0), fill=_rgb("#E9FBF1"), line=_rgb("#BBF7D0"), radius=True)
    add_textbox(s, Inches(1.0), Inches(4.55), Inches(11.3), Inches(0.3), "권장", size=14, bold=True, color=_rgb("#15803D"))
    add_textbox(s, Inches(1.0), Inches(4.85), Inches(11.3), Inches(1.2), "프롬프트 라이브러리를 구축하세요.\n(업무별 템플릿 + 예시 + 검증 체크리스트)", size=20, bold=True, color=_rgb("#166534"), line_spacing=1.2)
    add_footer(s, 23, dark=False)


def slide_24_closing(prs: Presentation) -> None:
    s = prs.slides.add_slide(prs.slide_layouts[6])
    set_slide_bg(s, T.navy)
    add_textbox(s, Inches(0.7), Inches(0.7), Inches(12), Inches(0.4), "PART 5. 마무리", size=14, bold=True, color=_rgb("#D1D5DB"))
    add_textbox(s, Inches(0.7), Inches(1.1), Inches(12), Inches(0.9), "AI와 함께 일하는 미래", size=46, bold=True, color=T.white)
    add_rect(s, Inches(0.7), Inches(2.15), Inches(11.93), Inches(0.05), fill=T.accent_yellow, line=None)
    add_textbox(s, Inches(0.7), Inches(2.35), Inches(12), Inches(0.6), "AI는 대체자가 아닌 증폭기(Amplifier)", size=28, bold=True, color=T.accent_yellow)
    add_bullets(
        s,
        Inches(0.9),
        Inches(3.2),
        Inches(12),
        Inches(2.0),
        ["잘 쓰는 사람과 못 쓰는 사람의 격차는 계속 벌어진다", "지금 시작하는 것이 가장 빠른 것", "핵심은: 목적·맥락·제약·형식 + 검증"],
        size=20,
        color=_rgb("#E5E7EB"),
    )
    add_rect(s, Inches(0.7), Inches(5.7), Inches(11.93), Inches(0.9), fill=_rgb("#24364D"), line=None, radius=True)
    add_textbox(s, Inches(0.7), Inches(5.9), Inches(11.93), Inches(0.5), "Q&A  /  다음 학습 자원 안내", size=26, bold=True, color=T.white, align=PP_ALIGN.CENTER)
    add_footer(s, 24, dark=True)


def build_ppt() -> Presentation:
    prs = Presentation()
    prs.slide_width = SLIDE_W
    prs.slide_height = SLIDE_H

    # Slides 1-5 (re-created as editable)
    slide_01_cover(prs)
    slide_02_core_assumptions(prs)
    slide_03_llm(prs)
    slide_04_good_vs_bad(prs)
    slide_05_hallucination(prs)

    # Slides 6-24 per outline
    slide_06_prompt_definition(prs)
    slide_07_language(prs)
    slide_08_context(prs)
    slide_09_5w1h(prs)
    slide_10_format(prs)
    slide_11_role(prs)
    slide_12_steps(prs)
    slide_13_fewshot(prs)
    slide_14_context_window(prs)
    slide_15_iterative(prs)
    slide_16_files(prs)
    slide_17_trust(prs)
    slide_18_security(prs)
    slide_19_copyright(prs)
    slide_20_skills(prs)
    slide_21_scenarios(prs)
    slide_22_ax_application(prs)
    slide_23_routine(prs)
    slide_24_closing(prs)

    return prs


def validate(prs: Presentation) -> None:
    if len(prs.slides) != 24:
        raise ValueError(f"expected 24 slides, got {len(prs.slides)}")
    # Ensure no full-slide raster images are used (editable requirement)
    from pptx.enum.shapes import MSO_SHAPE_TYPE

    pics = 0
    for slide in prs.slides:
        for sh in slide.shapes:
            if sh.shape_type == MSO_SHAPE_TYPE.PICTURE:
                pics += 1
    if pics != 0:
        raise ValueError(f"expected 0 picture shapes, got {pics}")


def main() -> None:
    base_dir = Path(__file__).resolve().parent
    out = base_dir / "outputs" / "ai_work.pptx"
    out.parent.mkdir(parents=True, exist_ok=True)
    prs = build_ppt()
    validate(prs)
    prs.save(str(out))
    print(f"wrote {out} ({out.stat().st_size:,} bytes)")


if __name__ == "__main__":
    main()

