///|
pub fn BrandBook::to_markdown(self : BrandBook) -> String {
  join_lines([
    "# \{self.name}",
    "",
    self.tagline,
    "",
    "## Voice",
    "",
    "Tone: \{self.voice.tone}",
    "",
    md_list(self.voice.writing_principles),
    "",
    "## Logo Usage",
    "",
    self.assets.primary_logo.to_markdown(),
    "",
    "### Alternate Logos",
    "",
    self.assets.alternate_logos
    .map(fn(logo) { logo.to_markdown() })
    .join("\n\n"),
    "",
    "Imagery style: \{self.assets.imagery_style}",
    "",
    "## Color",
    "",
    self.palette.to_markdown(),
    "",
    "### CSS",
    "",
    "```css",
    self.palette.to_css(),
    "```",
    "",
    "## Typography",
    "",
    self.typography.to_markdown(),
    "",
    "## Components",
    "",
    self.components.map(fn(c) { c.to_markdown() }).join("\n\n"),
    "",
    "## Incorrect Usage",
    "",
    self.forbidden.map(fn(rule) { rule.to_markdown() }).join("\n\n"),
    "",
    "## Source",
    "",
    "- Maintainer: \{self.metadata.maintainer}",
    "- License: \{self.metadata.license}",
    "- Source: \{self.metadata.source}",
    "",
  ])
}

///|
pub fn Logo::to_markdown(self : Logo) -> String {
  join_lines([
    "### \{self.name}",
    "",
    "- Asset: `\{self.path}`",
    "- Minimum width: \{self.min_width_px}px",
    "- Clear space: \{self.clear_space.describe()}",
    "- Background: \{self.background.describe()}",
  ])
}

///|
pub fn Palette::to_markdown(self : Palette) -> String {
  let colors = self.colors.map(fn(c) {
    "| \{c.name} | `\{c.value}` | \{c.role} |"
  })
  let gradients = self.gradients.map(fn(g) {
    "- \{g.name}: \{g.angle}deg, \{g.stops.join(" -> ")}; \{g.usage}"
  })
  join_lines([
    "| Token | Value | Role |",
    "| --- | --- | --- |",
    colors.join("\n"),
    "",
    "### Gradients",
    "",
    gradients.join("\n"),
  ])
}

///|
pub fn Typography::to_markdown(self : Typography) -> String {
  let families = self.families.map(fn(f) {
    "- \{f.name}: \{f.usage}; fallback `\{f.fallback}`"
  })
  let scale = self.scale.map(fn(step) {
    "| \{step.name} | \{step.size_px}px | \{step.line_height_px}px |"
  })
  join_lines([
    "### Families",
    "",
    families.join("\n"),
    "",
    "### Scale",
    "",
    "| Step | Size | Line height |",
    "| --- | --- | --- |",
    scale.join("\n"),
  ])
}

///|
pub fn ComponentSpec::to_markdown(self : ComponentSpec) -> String {
  join_lines([
    "### \{self.name}",
    "",
    self.purpose,
    "",
    "- Anatomy: \{self.anatomy.join(", ")}",
    "- Tokens: \{self.tokens.join(", ")}",
    "- States: \{self.states.join(", ")}",
  ])
}

///|
pub fn MisuseRule::to_markdown(self : MisuseRule) -> String {
  join_lines([
    "### \{self.title}",
    "",
    "- Why it fails: \{self.reason}",
    "- Use instead: \{self.replacement}",
  ])
}