"""Generate a PowerPoint (.pptx) executive presentation from a DocumentModel."""

from __future__ import annotations

from pathlib import Path

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

from ..core.models import (
    BlockquoteBlock,
    CodeBlock,
    ContentBlock,
    DocumentModel,
    GenerationResult,
    HeadingBlock,
    ImageBlock,
    ListBlock,
    MermaidBlock,
    OutputFormat,
    ParagraphBlock,
    Section,
    TableBlock,
)
from .base import BaseGenerator
from .styles import Colors, Fonts


class PptxGenerator(BaseGenerator):
    """Generates a beautifully styled ``.pptx`` PowerPoint presentation."""

    format = OutputFormat.PPTX
    _MAX_BLOCKS_PER_SLIDE = 5

    def generate(self, doc: DocumentModel, output_dir: Path) -> GenerationResult:
        output_dir = self._ensure_dir(output_dir)
        fname = self._safe_filename(doc.metadata.repo_name or "presentation", "pptx")
        output_path = output_dir / fname
        self._mermaid_index = 0

        try:
            prs = self._build(doc)
            prs.save(str(output_path))
            return GenerationResult(format=self.format, output_path=output_path)
        except Exception as exc:
            return GenerationResult(
                format=self.format, output_path=output_path, success=False, error=str(exc)
            )

    # ------------------------------------------------------------------
    # Builder
    # ------------------------------------------------------------------

    def _build(self, doc: DocumentModel) -> Presentation:
        prs = Presentation()
        prs.slide_width = Inches(13.333)
        prs.slide_height = Inches(7.5)

        self._add_title_slide(prs, doc)

        section_titles = [s.title for s in doc.sections if s.title]
        # If there's only one root section, use its subsections for the agenda
        if len(doc.sections) == 1 and doc.sections[0].subsections:
            section_titles = [s.title for s in doc.sections[0].subsections if s.title]
        if section_titles:
            self._add_agenda_slide(prs, section_titles)

        for section in doc.sections:
            self._add_section_divider(prs, section.title)
            self._render_section(prs, section)

        # Knowledge Graph slide (if available)
        if self.kg and self.kg.entities:
            self._add_knowledge_graph_slide(prs)

        self._add_summary_slide(prs, doc)
        self._add_closing_slide(prs, doc)

        return prs

    # ------------------------------------------------------------------
    # Slide builders
    # ------------------------------------------------------------------

    def _add_title_slide(self, prs: Presentation, doc: DocumentModel) -> None:
        slide = prs.slides.add_slide(prs.slide_layouts[6])
        self._set_slide_bg(slide, Colors.PRIMARY_DARK)

        # Top accent bar
        self._add_rect(slide, 0, 0, prs.slide_width, Inches(0.08), Colors.ACCENT)

        # Decorative side stripe
        self._add_rect(slide, 0, 0, Inches(0.5), prs.slide_height, Colors.ACCENT)

        # Title
        self._add_textbox(
            slide,
            text=doc.metadata.repo_name or "Project Overview",
            left=Inches(1.5), top=Inches(1.8),
            width=Inches(10), height=Inches(1.5),
            font_size=Pt(48), bold=True,
            color=Colors.WHITE, alignment=PP_ALIGN.LEFT,
            font_name=Fonts.HEADING,
        )

        # Subtitle divider
        self._add_rect(
            slide, Inches(1.5), Inches(3.5),
            Inches(3), Inches(0.06), Colors.ACCENT,
        )

        # Description
        if doc.metadata.description:
            self._add_textbox(
                slide,
                text=doc.metadata.description[:180],
                left=Inches(1.5), top=Inches(3.8),
                width=Inches(9), height=Inches(1.2),
                font_size=Pt(18),
                color=Colors.PRIMARY_LIGHT, alignment=PP_ALIGN.LEFT,
            )

        # Footer info
        footer_text = (
            f"Generated by opendocs  ·  "
            f"{doc.metadata.generated_at[:10] if doc.metadata.generated_at else ''}"
        )
        self._add_textbox(
            slide, text=footer_text,
            left=Inches(1.5), top=Inches(6.5),
            width=Inches(8), height=Inches(0.4),
            font_size=Pt(11),
            color=Colors.MUTED, alignment=PP_ALIGN.LEFT,
        )

        # Bottom accent bar
        self._add_rect(
            slide, 0, Emu(prs.slide_height - Inches(0.08)),
            prs.slide_width, Inches(0.08), Colors.ACCENT,
        )

    def _add_agenda_slide(self, prs: Presentation, titles: list[str]) -> None:
        slide = prs.slides.add_slide(prs.slide_layouts[6])

        # Left accent strip
        self._add_rect(slide, 0, 0, Inches(0.15), prs.slide_height, Colors.ACCENT)

        # Title
        self._add_textbox(
            slide, text="Agenda",
            left=Inches(0.8), top=Inches(0.4),
            width=Inches(11), height=Inches(1),
            font_size=Pt(36), bold=True, color=Colors.PRIMARY_DARK,
            font_name=Fonts.HEADING,
        )

        # Underline
        self._add_rect(
            slide, Inches(0.8), Inches(1.3),
            Inches(2), Inches(0.05), Colors.ACCENT,
        )

        # Numbered items
        lines: list[str] = []
        for i, t in enumerate(titles[:15], 1):
            lines.append(f"{i:02d}   {t}")
        body = "\n\n".join(lines)

        self._add_textbox(
            slide, text=body,
            left=Inches(1.2), top=Inches(1.8),
            width=Inches(10), height=Inches(5),
            font_size=Pt(17), color=Colors.TEXT,
        )

    def _add_section_divider(self, prs: Presentation, title: str) -> None:
        """Full-bleed section divider slide."""
        slide = prs.slides.add_slide(prs.slide_layouts[6])
        self._set_slide_bg(slide, Colors.HEADING)

        # Accent stripe across the middle
        self._add_rect(
            slide, 0, Inches(3.3),
            prs.slide_width, Inches(0.06), Colors.ACCENT,
        )

        # Section title
        self._add_textbox(
            slide, text=title,
            left=Inches(1.5), top=Inches(2.2),
            width=Inches(10), height=Inches(1),
            font_size=Pt(40), bold=True,
            color=Colors.WHITE, alignment=PP_ALIGN.LEFT,
            font_name=Fonts.HEADING,
        )

        # Decorative corner
        self._add_rect(
            slide, Inches(1.5), Inches(3.6),
            Inches(1.5), Inches(0.04), Colors.ACCENT,
        )

    def _add_summary_slide(self, prs: Presentation, doc: DocumentModel) -> None:
        """Quick stats summary slide."""
        slide = prs.slides.add_slide(prs.slide_layouts[6])

        self._add_rect(slide, 0, 0, Inches(0.15), prs.slide_height, Colors.PRIMARY)

        self._add_textbox(
            slide, text="Document Summary",
            left=Inches(0.8), top=Inches(0.4),
            width=Inches(11), height=Inches(1),
            font_size=Pt(32), bold=True, color=Colors.PRIMARY_DARK,
            font_name=Fonts.HEADING,
        )

        self._add_rect(
            slide, Inches(0.8), Inches(1.3),
            Inches(2.5), Inches(0.05), Colors.ACCENT,
        )

        # Stat cards
        stats = [
            ("Sections", str(len(doc.sections))),
            ("Content Blocks", str(len(doc.all_blocks))),
            ("Diagrams", str(len(doc.mermaid_diagrams))),
            ("Characters", f"{len(doc.raw_markdown):,}"),
        ]

        for i, (label, value) in enumerate(stats):
            left = Inches(1.0 + i * 3)
            # Card background
            self._add_rounded_rect(
                slide, left, Inches(2.2),
                Inches(2.5), Inches(2.5), Colors.BG_LIGHT,
            )
            # Value
            self._add_textbox(
                slide, text=value,
                left=left, top=Inches(2.6),
                width=Inches(2.5), height=Inches(1.2),
                font_size=Pt(42), bold=True,
                color=Colors.PRIMARY_DARK, alignment=PP_ALIGN.CENTER,
            )
            # Label
            self._add_textbox(
                slide, text=label,
                left=left, top=Inches(3.8),
                width=Inches(2.5), height=Inches(0.6),
                font_size=Pt(14),
                color=Colors.MUTED, alignment=PP_ALIGN.CENTER,
            )

    def _add_closing_slide(self, prs: Presentation, doc: DocumentModel) -> None:
        slide = prs.slides.add_slide(prs.slide_layouts[6])
        self._set_slide_bg(slide, Colors.PRIMARY_DARK)

        self._add_rect(slide, 0, 0, prs.slide_width, Inches(0.08), Colors.ACCENT)
        self._add_rect(slide, 0, 0, Inches(0.5), prs.slide_height, Colors.ACCENT)

        self._add_textbox(
            slide, text="Thank You",
            left=Inches(1.5), top=Inches(2.0),
            width=Inches(10), height=Inches(1.5),
            font_size=Pt(52), bold=True,
            color=Colors.WHITE, alignment=PP_ALIGN.LEFT,
            font_name=Fonts.HEADING,
        )

        self._add_rect(
            slide, Inches(1.5), Inches(3.6),
            Inches(3), Inches(0.06), Colors.ACCENT,
        )

        if doc.metadata.repo_url:
            self._add_textbox(
                slide, text=doc.metadata.repo_url,
                left=Inches(1.5), top=Inches(4.0),
                width=Inches(9), height=Inches(0.6),
                font_size=Pt(16),
                color=Colors.PRIMARY_LIGHT, alignment=PP_ALIGN.LEFT,
            )

        self._add_textbox(
            slide, text="Auto-generated by opendocs",
            left=Inches(1.5), top=Inches(6.5),
            width=Inches(8), height=Inches(0.4),
            font_size=Pt(11),
            color=Colors.MUTED, alignment=PP_ALIGN.LEFT,
        )

        self._add_rect(
            slide, 0, Emu(prs.slide_height - Inches(0.08)),
            prs.slide_width, Inches(0.08), Colors.ACCENT,
        )

    # ------------------------------------------------------------------
    # Section rendering
    # ------------------------------------------------------------------

    def _render_section(self, prs: Presentation, section: Section) -> None:
        # Separate renderable blocks from diagram/image blocks
        renderable: list[ContentBlock] = []
        diagrams: list[MermaidBlock | ImageBlock] = []
        for block in section.blocks:
            if isinstance(block, (MermaidBlock, ImageBlock)):
                diagrams.append(block)
            else:
                renderable.append(block)

        has_body = bool(renderable) or bool(diagrams)
        has_subs = bool(section.subsections)

        # If this section has no body content and only serves as a
        # grouping header for subsections, insert a compact divider
        # instead of an empty content slide.
        if not has_body and has_subs:
            self._add_section_divider(prs, section.title)
        else:
            # Regular content slide
            slide = prs.slides.add_slide(prs.slide_layouts[6])

            # Left accent strip
            self._add_rect(slide, 0, 0, Inches(0.15), prs.slide_height, Colors.PRIMARY)

            # Section title with underline
            self._add_textbox(
                slide, text=section.title,
                left=Inches(0.8), top=Inches(0.3),
                width=Inches(11), height=Inches(0.9),
                font_size=Pt(28), bold=True, color=Colors.PRIMARY_DARK,
                font_name=Fonts.HEADING,
            )
            self._add_rect(
                slide, Inches(0.8), Inches(1.15),
                Inches(2), Inches(0.04), Colors.ACCENT,
            )

            # Add diagram/image slides
            for d in diagrams:
                if isinstance(d, MermaidBlock):
                    self._add_diagram_slide(prs, d)
                else:
                    self._add_image_slide(prs, d)

            # Collect body content (text blocks)
            body_parts: list[str] = []
            for block in renderable[: self._MAX_BLOCKS_PER_SLIDE]:
                line = self._block_to_text(block)
                if line:
                    body_parts.append(line)

            if body_parts:
                self._add_rich_body(slide, body_parts)

        for sub in section.subsections:
            self._render_section(prs, sub)

    def _add_rich_body(self, slide, parts: list[str]) -> None:
        """Add body content with proper spacing."""
        txbox = slide.shapes.add_textbox(
            Inches(1.0), Inches(1.5), Inches(11), Inches(5.3),
        )
        tf = txbox.text_frame
        tf.word_wrap = True

        for i, part in enumerate(parts):
            p = tf.paragraphs[0] if i == 0 else tf.add_paragraph()
            p.text = part
            p.font.size = Pt(15)
            p.font.color.rgb = RGBColor(*Colors.TEXT)
            p.space_after = Pt(12)

    def _add_diagram_slide(self, prs: Presentation, block: MermaidBlock) -> None:
        """Add a dedicated slide for a Mermaid diagram image."""
        idx = self._mermaid_index
        self._mermaid_index += 1

        img_path = self.image_cache.get_mermaid(idx) if self.image_cache else None
        if img_path and img_path.exists():
            slide = prs.slides.add_slide(prs.slide_layouts[6])
            self._add_rect(slide, 0, 0, Inches(13.333), Inches(0.06), Colors.ACCENT)

            self._add_textbox(
                slide, text=f"Diagram {idx + 1}",
                left=Inches(0.8), top=Inches(0.2),
                width=Inches(10), height=Inches(0.6),
                font_size=Pt(22), bold=True, color=Colors.PRIMARY_DARK,
            )

            # Center the image on the slide
            slide.shapes.add_picture(
                str(img_path),
                left=Inches(1.5), top=Inches(1.0),
                width=Inches(10), height=Inches(5.8),
            )

    def _add_image_slide(self, prs: Presentation, block: ImageBlock) -> None:
        """Add a dedicated slide for an external image."""
        img_path = self.image_cache.get_external(block.src) if self.image_cache else None
        if img_path and img_path.exists():
            try:
                slide = prs.slides.add_slide(prs.slide_layouts[6])
                self._add_rect(slide, 0, 0, Inches(13.333), Inches(0.06), Colors.ACCENT)

                caption = block.alt or "Image"
                self._add_textbox(
                    slide, text=f"  {caption}",
                    left=Inches(0.8), top=Inches(0.2),
                    width=Inches(10), height=Inches(0.6),
                    font_size=Pt(20), bold=True, color=Colors.PRIMARY_DARK,
                )

                slide.shapes.add_picture(
                    str(img_path),
                    left=Inches(1.5), top=Inches(1.0),
                    width=Inches(10), height=Inches(5.5),
                )
            except Exception:
                pass  # Skip corrupt / unsupported image files

    @staticmethod
    def _block_to_text(block: ContentBlock) -> str:
        if isinstance(block, ParagraphBlock):
            if block.spans:
                parts = []
                for s in block.spans:
                    if s.is_link and s.url:
                        parts.append(f"{s.text} ({s.url})")
                    else:
                        parts.append(s.text)
                return "".join(parts)[:500]
            return block.text[:500]
        if isinstance(block, ListBlock):
            lines = []
            for i, item in enumerate(block.items[:10]):
                if block.rich_items and i < len(block.rich_items):
                    parts = []
                    for s in block.rich_items[i]:
                        if s.is_link and s.url:
                            parts.append(f"{s.text} ({s.url})")
                        else:
                            parts.append(s.text)
                    lines.append(f"    ●   {''.join(parts)}")
                else:
                    lines.append(f"    ●   {item}")
            return "\n".join(lines)
        if isinstance(block, CodeBlock):
            snippet = block.code[:350]
            lang = f" ({block.language})" if block.language else ""
            return f"Code{lang}:\n{snippet}"
        if isinstance(block, MermaidBlock):
            return "[Mermaid Diagram -- see technical report for details]"
        if isinstance(block, BlockquoteBlock):
            return f'"{block.text[:300]}"'
        if isinstance(block, TableBlock):
            header = " │ ".join(block.headers) if block.headers else ""
            rows = "\n".join(" │ ".join(r) for r in block.rows[:6])
            return f"{header}\n{'─' * len(header)}\n{rows}" if header else rows
        return ""

    # ------------------------------------------------------------------
    # Shape helpers
    # ------------------------------------------------------------------

    @staticmethod
    def _add_textbox(
        slide, text: str,
        left, top, width, height,
        font_size=Pt(14),
        bold: bool = False,
        color: tuple = Colors.TEXT,
        alignment=PP_ALIGN.LEFT,
        font_name: str | None = None,
    ):
        txbox = slide.shapes.add_textbox(left, top, width, height)
        tf = txbox.text_frame
        tf.word_wrap = True

        p = tf.paragraphs[0]
        p.text = text
        p.font.size = font_size
        p.font.bold = bold
        p.font.color.rgb = RGBColor(*color)
        p.alignment = alignment
        if font_name:
            p.font.name = font_name
        return txbox

    @staticmethod
    def _set_slide_bg(slide, color: tuple) -> None:
        bg = slide.background
        fill = bg.fill
        fill.solid()
        fill.fore_color.rgb = RGBColor(*color)

    @staticmethod
    def _add_rect(slide, left, top, width, height, color: tuple):
        """Add a solid rectangle shape (used for accent bars / stripes)."""
        shape = slide.shapes.add_shape(
            MSO_SHAPE.RECTANGLE, left, top, width, height,
        )
        shape.fill.solid()
        shape.fill.fore_color.rgb = RGBColor(*color)
        shape.line.fill.background()  # no border
        return shape

    @staticmethod
    def _add_rounded_rect(slide, left, top, width, height, color: tuple):
        """Add a rounded rectangle (card-style)."""
        shape = slide.shapes.add_shape(
            MSO_SHAPE.ROUNDED_RECTANGLE, left, top, width, height,
        )
        shape.fill.solid()
        shape.fill.fore_color.rgb = RGBColor(*color)
        shape.line.fill.background()
        return shape

    # ------------------------------------------------------------------
    # Knowledge Graph slide
    # ------------------------------------------------------------------

    def _add_knowledge_graph_slide(self, prs: Presentation) -> None:
        """Add a slide summarizing the extracted Knowledge Graph."""
        from ..core.knowledge_graph import EntityType

        kg = self.kg
        if not kg:
            return

        slide = prs.slides.add_slide(prs.slide_layouts[6])

        # Accent bar
        self._add_rect(slide, Inches(0), Inches(0), Inches(13.333), Inches(0.08), Colors.SLIDE_ACCENT_BAR)

        # Title
        self._add_textbox(
            slide, text="Knowledge Graph",
            left=Inches(0.8), top=Inches(0.3),
            width=Inches(11), height=Inches(0.8),
            font_size=Pt(32), bold=True, color=Colors.HEADING,
        )

        # Stats summary on left
        stats = kg.extraction_stats or kg.compute_stats()
        stats_text = (
            f"Entities: {stats.get('total_entities', 0)}\n"
            f"Relations: {stats.get('total_relations', 0)}\n"
            f"Deterministic: {stats.get('deterministic_entities', 0)}\n"
            f"LLM-Extracted: {stats.get('llm_entities', 0)}"
        )
        self._add_textbox(
            slide, text=stats_text,
            left=Inches(0.8), top=Inches(1.4),
            width=Inches(3.5), height=Inches(2),
            font_size=Pt(16), color=Colors.TEXT,
        )

        # Entity types on right — cap to fit slide
        type_lines = []
        for et in EntityType:
            entities = kg.entities_of_type(et)
            if entities:
                names = ", ".join(e.name for e in entities[:4])
                suffix = f"  (+{len(entities) - 4})" if len(entities) > 4 else ""
                type_lines.append(f"▸ {et.value.replace('_', ' ').title()}: {names}{suffix}")

        if type_lines:
            self._add_textbox(
                slide, text="\n".join(type_lines[:8]),
                left=Inches(5), top=Inches(1.4),
                width=Inches(7.5), height=Inches(5.5),
                font_size=Pt(13), color=Colors.TEXT,
            )

        # Add KG diagram image slide if available
        kg_img = self.image_cache.kg_diagram if self.image_cache else None
        if kg_img and kg_img.exists():
            diagram_slide = prs.slides.add_slide(prs.slide_layouts[6])
            self._add_rect(diagram_slide, 0, 0, Inches(13.333), Inches(0.06), Colors.ACCENT)
            self._add_textbox(
                diagram_slide, text="Architecture Graph",
                left=Inches(0.8), top=Inches(0.2),
                width=Inches(10), height=Inches(0.6),
                font_size=Pt(26), bold=True, color=Colors.PRIMARY_DARK,
            )
            diagram_slide.shapes.add_picture(
                str(kg_img),
                left=Inches(1.0), top=Inches(1.0),
                width=Inches(11), height=Inches(6),
            )

        # -- LLM Summary slide (if summaries are present) --
        if kg.executive_summary or kg.stakeholder_summaries:
            self._add_llm_summary_slide(prs)

    def _add_llm_summary_slide(self, prs: Presentation) -> None:
        """Add slides with LLM-generated executive and stakeholder summaries.

        Content is split across multiple slides so nothing overflows:
        - Slide 1: Executive summary
        - Slide 2+: One slide per stakeholder persona
        """
        kg = self.kg
        if not kg:
            return

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

        # ── Slide 1: Executive Summary ──────────────────────────────
        if kg.executive_summary:
            slide = prs.slides.add_slide(prs.slide_layouts[6])
            self._add_rect(slide, 0, 0, SLIDE_W, Inches(0.08), Colors.SLIDE_ACCENT_BAR)

            self._add_textbox(
                slide, text="AI-Generated Executive Summary",
                left=Inches(0.8), top=Inches(0.3),
                width=Inches(11), height=Inches(0.7),
                font_size=Pt(28), bold=True, color=Colors.HEADING,
            )

            # Accent underline
            self._add_rect(
                slide, Inches(0.8), Inches(1.05),
                Inches(3), Inches(0.04), Colors.ACCENT,
            )

            # Summary text — large readable area
            summary = kg.executive_summary.strip()
            # Split into paragraphs if very long
            if len(summary) > 600:
                summary = summary[:600].rsplit(" ", 1)[0] + "…"

            self._add_textbox(
                slide, text=summary,
                left=Inches(0.8), top=Inches(1.4),
                width=Inches(11.5), height=Inches(5.2),
                font_size=Pt(16), color=Colors.TEXT,
            )

            # Footer
            self._add_textbox(
                slide, text="Generated by LLM semantic analysis",
                left=Inches(0.8), top=Inches(6.8),
                width=Inches(8), height=Inches(0.4),
                font_size=Pt(10), color=Colors.MUTED,
            )

        # ── Slides 2+: Stakeholder Views (one per persona) ──────────
        persona_config = {
            "cto": ("CTO / Technical Lead Assessment", Colors.PRIMARY),
            "investor": ("Investor / Business Analysis", Colors.SUCCESS),
            "developer": ("Developer Experience Review", Colors.INFO),
        }

        for persona, content in kg.stakeholder_summaries.items():
            if not content or content.strip().startswith("["):
                continue

            title, accent_color = persona_config.get(
                persona, (f"{persona.title()} View", Colors.PRIMARY)
            )

            slide = prs.slides.add_slide(prs.slide_layouts[6])
            self._add_rect(slide, 0, 0, SLIDE_W, Inches(0.08), Colors.SLIDE_ACCENT_BAR)

            # Title
            self._add_textbox(
                slide, text=title,
                left=Inches(0.8), top=Inches(0.3),
                width=Inches(11), height=Inches(0.7),
                font_size=Pt(26), bold=True, color=Colors.HEADING,
            )

            # Colored accent underline
            self._add_rect(
                slide, Inches(0.8), Inches(1.05),
                Inches(2.5), Inches(0.04), accent_color,
            )

            # Parse bullet points from the content
            raw_lines = [
                ln.strip().lstrip("-•●▸ ").strip()
                for ln in content.strip().split("\n")
                if ln.strip()
            ]

            # Limit to what fits on one slide (max ~6 bullets)
            display_lines = raw_lines[:6]
            if len(raw_lines) > 6:
                display_lines.append(f"… and {len(raw_lines) - 6} more insights")

            # Build a text frame with properly formatted bullets
            txbox = slide.shapes.add_textbox(
                Inches(1.0), Inches(1.4),
                Inches(11.3), Inches(5.5),
            )
            tf = txbox.text_frame
            tf.word_wrap = True

            for i, line in enumerate(display_lines):
                p = tf.paragraphs[0] if i == 0 else tf.add_paragraph()
                # Truncate individual bullets that are too long
                if len(line) > 250:
                    line = line[:247] + "…"
                p.text = f"●  {line}"
                p.font.size = Pt(14)
                p.font.color.rgb = RGBColor(*Colors.TEXT)
                p.space_after = Pt(10)
                p.space_before = Pt(4)

            # Footer
            self._add_textbox(
                slide, text="Generated by LLM semantic analysis",
                left=Inches(0.8), top=Inches(7.0),
                width=Inches(8), height=Inches(0.35),
                font_size=Pt(10), color=Colors.MUTED,
            )
