// CHANGE BRAND COLOR HERE
#let brand-color = rgb("#334155")
// Page Setup with Header and Footer
#set page(
paper: "a4",
margin: (top: 3cm, bottom: 2.5cm, left: 2cm, right: 2cm),
// Header: Logo and Report Title
header: [
#grid(
columns: (1fr, auto),
[#text(weight: "bold", fill: brand-color)[PDFDyno Analytics]],
[#text(fill: luma(100))[#data.report_title]]
)
#line(length: 100%, stroke: 0.5pt + luma(200))
],
// Footer: Pagination
footer: [
#line(length: 100%, stroke: 0.5pt + luma(200))
#align(center)[
#text(size: 9pt, fill: luma(150))[
// Automatic page numbers via Typst context
#context [
Page #counter(page).display() of #counter(page).final().at(0)
]
]
]
]
)
#set text(font: "Helvetica", size: 10pt)
// Title Section
#align(center)[
#text(size: 24pt, weight: "bold")[#data.report_title] \
#v(5pt)
#text(size: 12pt, fill: luma(100))[Generated on: #data.generated_date]
]
#v(1.5cm)
// Executive Summary
#block(fill: rgb("#f3f4f6"), inset: 15pt, radius: 5pt, width: 100%)[
*Executive Summary* \
#data.summary
]
#v(1cm)
// Data Table
*Performance Metrics:*
#v(5pt)
#table(
columns: (1fr, auto, auto, auto),
inset: 10pt,
fill: (x, y) => if y == 0 { brand-color } else if calc.even(y) { rgb("#f9fafb") } else { white },
stroke: 0.5pt + luma(200),
// Table Header (white text on brand color)
[#text(fill: white)[*Metric*]],
[#text(fill: white)[*Current*]],
[#text(fill: white)[*Previous*]],
[#text(fill: white)[*Change*]],
// Generate rows
..data.metrics.map(row => (
row.name,
row.current,
row.previous,
row.change
)).flatten()
)
#v(1fr)
// This forces the following text to the end of the page, or onto the next page