Introduce cmarker/codly-based MD workflow, brutalist cover layout, and shared brand tokens so colleagues can author reports in report.md while the template handles PDF output. Co-authored-by: Cursor <cursoragent@cursor.com>
149 lines
4.1 KiB
Plaintext
149 lines
4.1 KiB
Plaintext
#import "theme.typ": *
|
|
#import "logo.typ": grelin-logo, cover-index-badge
|
|
#import "decor.typ": tech-dots, tech-barcode, tech-label
|
|
|
|
#let format-cover-date(date) = {
|
|
let parts = date.split("-")
|
|
if parts.len() == 3 {
|
|
parts.at(0) + "." + parts.at(1) + "." + parts.at(2)
|
|
} else {
|
|
date
|
|
}
|
|
}
|
|
|
|
#let cover-meta-strip(meta) = box(
|
|
width: 100%,
|
|
fill: color-ink,
|
|
inset: (x: 12pt, y: 8pt),
|
|
)[
|
|
#grid(
|
|
columns: (1fr, auto, 1fr, auto, 1fr),
|
|
column-gutter: 12pt,
|
|
align: horizon,
|
|
tech-label("VERSION", fill: color-neon, size: 6.5pt),
|
|
text(font: mono-font, size: 8pt, fill: white)[#meta.version],
|
|
tech-label("DATE", fill: color-neon, size: 6.5pt),
|
|
text(font: mono-font, size: 8pt, fill: white)[#format-cover-date(meta.date)],
|
|
align(right)[
|
|
tech-label("STATUS · DRAFT", fill: color-neon, size: 6.5pt)
|
|
],
|
|
)
|
|
]
|
|
|
|
#let cover-block(meta) = {
|
|
pagebreak(weak: true)
|
|
block(width: 100%, below: space-chapter)[
|
|
#box(width: 100%, height: cover-block-height, fill: white)[
|
|
#place(top + left)[#grelin-logo()]
|
|
#place(top + right)[#cover-index-badge("01")]
|
|
|
|
#place(left + top, dy: 52pt)[#tech-barcode(14pt, 120pt, bars: 5)]
|
|
#place(right + top, dy: 72pt)[
|
|
#rotate(-90deg, reflow: true)[
|
|
#tech-label("FEASIBILITY REPORT", fill: color-caption, size: 6.5pt)
|
|
]
|
|
]
|
|
|
|
#place(left + top, dx: 28pt, dy: 100pt)[
|
|
#box(width: 88%, height: 130pt, clip: true)[#tech-dots(width: 100%, height: 100%, step: 11pt)]
|
|
]
|
|
|
|
#place(left + top, dx: 24pt, dy: 168pt)[
|
|
#box(width: 92%, fill: color-neon, inset: (x: 16pt, y: 18pt))[
|
|
#text(
|
|
font: heading-font,
|
|
size: size-cover-title,
|
|
weight: "black",
|
|
fill: color-ink,
|
|
hyphenate: false,
|
|
)[#meta.title]
|
|
]
|
|
]
|
|
|
|
#place(left + bottom, dy: -36pt)[
|
|
#box(width: 100%)[#cover-meta-strip(meta)]
|
|
]
|
|
|
|
#place(left + bottom, dy: -8pt)[
|
|
#tech-barcode(100%, 10pt, bars: 48)
|
|
]
|
|
]
|
|
]
|
|
pagebreak()
|
|
}
|
|
|
|
#let accent-line() = box(width: 100%, height: 2pt, fill: color-ink)
|
|
|
|
#let summary-block(meta) = {
|
|
if meta.summary != "" {
|
|
block(width: 100%, above: space-block, below: space-chapter)[
|
|
#box(
|
|
width: 100%,
|
|
fill: white,
|
|
stroke: 1.5pt + color-ink,
|
|
inset: summary-inset,
|
|
)[
|
|
#box(width: 100%, fill: color-neon, inset: (x: 10pt, y: 5pt))[
|
|
#tech-label("ABSTRACT", fill: color-ink, size: 7pt)
|
|
]
|
|
#v(10pt)
|
|
#text(font: heading-font, size: size-h2, weight: "black", fill: color-ink)[摘要]
|
|
#v(space-block)
|
|
#set par(leading: leading-summary, justify: true)
|
|
#set text(size: size-body, fill: color-body)
|
|
#meta.summary
|
|
#v(space-section)
|
|
#grid(
|
|
columns: (auto, 1fr, auto, 1fr),
|
|
column-gutter: 8pt,
|
|
align: horizon,
|
|
tech-label("DATE", size: 6.5pt),
|
|
text(font: mono-font, size: size-meta, fill: color-body)[#meta.date],
|
|
tech-label("ORG", size: 6.5pt),
|
|
text(font: mono-font, size: size-meta, fill: color-body)[#meta.company],
|
|
)
|
|
]
|
|
]
|
|
}
|
|
}
|
|
|
|
#let page-footer() = context {
|
|
grid(
|
|
columns: (auto, 1fr, auto),
|
|
align: horizon,
|
|
tech-barcode(36pt, 8pt, bars: 10),
|
|
box(width: 100%, height: 1pt, fill: color-ink),
|
|
box(fill: color-ink, inset: (x: 8pt, y: 3pt))[
|
|
#text(font: mono-font, size: 8pt, fill: color-neon)[
|
|
#counter(page).display("1")
|
|
#h(0.12em)
|
|
#sym.slash
|
|
#h(0.12em)
|
|
#counter(page).final().first()
|
|
]
|
|
],
|
|
)
|
|
}
|
|
|
|
#let page-accent-bar() = place(
|
|
left + top,
|
|
tech-barcode(page-accent-bar-width, 100%, bars: 4),
|
|
)
|
|
|
|
#let page-header(meta) = [
|
|
#grid(
|
|
columns: (auto, 1fr, auto),
|
|
column-gutter: 8pt,
|
|
align: horizon,
|
|
box(fill: color-neon, inset: (x: 6pt, y: 2pt))[
|
|
#text(font: mono-font, size: 7pt, weight: "bold", fill: color-ink)[#upper(meta.brand)]
|
|
],
|
|
box(width: 100%, height: 1pt, fill: color-ink),
|
|
align(right)[
|
|
#text(font: mono-font, size: 7pt, fill: color-caption)[#meta.title]
|
|
],
|
|
)
|
|
#v(6pt)
|
|
#accent-line()
|
|
]
|