diff --git a/themes/hereford/colors.typ b/themes/hereford/colors.typ new file mode 100644 index 0000000..a260581 --- /dev/null +++ b/themes/hereford/colors.typ @@ -0,0 +1,30 @@ +// TODO: these names are terrible, fix them +#let dark-red = rgb("#e05c4a") +#let light-dark-red = rgb("#f86f5d") + + +#let red = rgb("#e06666") +#let light-red = rgb("#ea9999") +#let orange = rgb("#f6b26b") +#let light-orange = rgb("#fce5cd") +#let yellow = rgb("#ffd966") +#let light-yellow = rgb("#fff2cc") +#let green = rgb("#93c47d") +#let light-green = rgb("#d9ead3") +#let blue = rgb("#6d9eeb") +#let light-blue = rgb("#c9daf8") +#let purple = rgb("#c4b0ff") +#let light-purple = rgb("#ede5ff") +#let pink = rgb("#d5a6bd") +#let light-pink = rgb("#ead1dc") +#let brown = rgb("#ca9994") +#let light-brown = rgb("#deafab") +#let gray = rgb("#999999") +#let light-gray = rgb("#b7b7b7") + +#let pro-green = rgb("#a5f1a3") +#let con-red = rgb("#ff9999") + +#let surface-0 = rgb("#d9d9d9") +#let surface-1 = rgb("#cccccc") +#let surface-3 = rgb("#eeeeee") diff --git a/themes/hereford/components/components.typ b/themes/hereford/components/components.typ new file mode 100644 index 0000000..bbdb5de --- /dev/null +++ b/themes/hereford/components/components.typ @@ -0,0 +1,4 @@ +#import "./decision-matrix.typ": * +#import "pro-con.typ": * +#import "./toc.typ": * +#import "glossary.typ": * diff --git a/themes/hereford/components/decision-matrix.typ b/themes/hereford/components/decision-matrix.typ new file mode 100644 index 0000000..eaac177 --- /dev/null +++ b/themes/hereford/components/decision-matrix.typ @@ -0,0 +1,140 @@ +#import "/utils.typ" +#import "../colors.typ": * + +#let decision-matrix( + properties: none, + ..choices, +) = { + let data = utils.calc-decision-matrix( + properties: properties, + ..choices, + ) + + //repr(data) + + let winning-column + for ( + index, + result, + ) in data.enumerate() { + if result.values.total.highest == true { + winning-column = index + 2 + break + } + } + + let table-height = properties.len() + 2 + let table-length = choices.pos().len() + 2 + + import table: hline, vline, cell + show cell: it => { + set align(center + horizon) + box( + height: 30pt, + it, + ) + } + table( + columns: for _ in range(choices.pos().len() + 2) { + ( + 1fr, + ) + }, + stroke: none, + fill: ( + x, + y, + ) => { + if y == 0 or ( + x == 0 and not y == properties.len() + 1 + ) { + yellow.lighten(50%) + } + + if x == winning-column and not y == 0 {yellow.lighten(50%)} + }, + + // we make lines + + vline(stroke: yellow, end: table-height - 1), + hline(stroke: yellow), + + ..for num in range(0, table-height) { + let stroke = if num < 2 {yellow} else {gray} + (hline(y: num, stroke: stroke, start: 2),) + }, + + hline(stroke: gray, y: table-height, start: 1), + + ..for num in range(1, table-height + 2) { + ( + vline(x: num, stroke: yellow, start: 0, end: 1), + vline(x: num, stroke: gray, start: 1), + ) + }, + + // outline the properties + ..for num in range(0, table-height) { + (hline(y: num, stroke: yellow, start: 0, end: 1),) + }, + + + + // outline the weights + hline(stroke: pro-green, start: 1, end: 2), + hline(y: table-height - 1, stroke: pro-green, start: 1, end: 2), + vline(x: 1, stroke: pro-green, end: table-height - 1), + vline(x: 2, stroke: pro-green, end: table-height - 1), + + ..for num in range(0, table-height) { + (hline(y: num, stroke: pro-green, start: 1, end: 2),) + }, + + + // outline the best choice + hline(start: winning-column, end: winning-column + 1, stroke: yellow), + vline(x: winning-column, stroke: yellow), + vline(x: winning-column + 1, stroke: yellow), + hline(y: table-height, start: winning-column, end: winning-column + 1, stroke: yellow), + + ..for num in range(0, table-height + 1) { + (hline(y: num, stroke: yellow, start: winning-column, end: winning-column + 1),) + }, + + + // ok we're done making lines + + + [], + cell(fill: pro-green.lighten(50%))[*Weights*], + ..for choice in choices.pos() { + ( + [*#choice.at(0)*], + ) + }, + ..for ( + index, + property, + ) in properties.enumerate() { + ( + [*#property.name*], + table.cell(fill: pro-green.lighten(50%))[#property.weight], + ..for result in data { + ( + [#result.values.values().at(index).value], + ) + }, + ) + }, + [], + [*Totals:*], + ..for ( + index, + result, + ) in data.enumerate() { + ( + [#result.values.at("total").value], + ) + }, + ) +} diff --git a/themes/hereford/components/glossary.typ b/themes/hereford/components/glossary.typ new file mode 100644 index 0000000..bc10842 --- /dev/null +++ b/themes/hereford/components/glossary.typ @@ -0,0 +1 @@ +#let glossary() = {} diff --git a/themes/hereford/components/pro-con.typ b/themes/hereford/components/pro-con.typ new file mode 100644 index 0000000..ee1f0b2 --- /dev/null +++ b/themes/hereford/components/pro-con.typ @@ -0,0 +1,59 @@ +#import "../colors.typ": * + +#let pro-con( + pros: [], + cons: [], +) = { + show grid.cell.where( + y: 0, + x: 0, + ): it => rect( + radius: 5pt, + width: 100%, + fill: pro-green, + it, + ) + show grid.cell.where( + y: 0, + x: 1, + ): it => rect( + radius: 5pt, + width: 100%, + fill: con-red, + it, + ) + + grid( + columns: ( + 1fr, + 1fr, + ), + gutter: 5pt, + inset: ( + x, + y, + ) => if y == 0 { + 2pt + } else { + ( + top: 10pt, + rest: 5pt, + ) + }, + row-gutter: -5pt, + fill: ( + x, + y, + ) => if y == 0 { + return + } else if x == 0 { + pro-green.lighten(50%) + } else if x == 1 { + con-red.lighten(50%) + }, + align(center)[*Pros*], + align(center)[*Cons*], + pros, + cons, + ) +} diff --git a/themes/hereford/components/toc.typ b/themes/hereford/components/toc.typ new file mode 100644 index 0000000..93bbd98 --- /dev/null +++ b/themes/hereford/components/toc.typ @@ -0,0 +1,35 @@ +#import "/utils.typ" + +#let toc() = utils.print-toc(( + _, + body, + _, +) => { + set align(center) + let line = table.vline(stroke: gray) + table( + stroke: none, + columns: ( + 1fr, + 1fr, + 2fr, + 1fr, + ), + [*Page \#*], + line, + [*EDP Step*], + line, + [*Entry Description*], + line, + [*Date*], + line, + ..for entry in body { + ( + [#entry.page-number], + [#entry.type], + [#entry.title], + [#entry.date.display("[month]/[day]/[year]")], + ) + }, + ) +}) diff --git a/themes/hereford/entries.typ b/themes/hereford/entries.typ new file mode 100644 index 0000000..65bc4cd --- /dev/null +++ b/themes/hereford/entries.typ @@ -0,0 +1,166 @@ +#import "./colors.typ": * +#import "./format.typ": format-heading + +#let entry-type-metadata = ( + identify: ( + color: red, + text: "Identify", + ), + brainstorm: ( + color: orange, + text: "Brainstorm", + ), + decide: ( + color: yellow, + text: "Solution", + ), + build: ( + color: green, + text: "Build", + ), + program: ( + color: blue, + text: "Program", + ), + test: ( + color: purple, + text: "Test", + ), + reflection: ( + color: pink, + text: "Reflection", + ), + management: ( + color: brown, + text: "Management", + ), + strategy: ( + color: gray, + text: "Strategy", + ), +) + +#let heading-text-size = 14pt + +#let cover( + ctx: (:), +) = { } + +#let frontmatter-entry( + ctx: (:), + body, +) = { + show heading: it => format-heading(it, surface-0) + show: page.with( + margin: ( + top: 5em, + ), + header: { + // background bar + place( + top + right, + dx: 100pt, + box( + width: 250%, + height: 100%, + fill: surface-0, + ), + ) + // the other thing + set align(center + horizon) + box( + radius: 0.3em, + width: 200pt, + outset: 9pt, + fill: surface-1, + text( + size: heading-text-size, + weight: "bold", + ctx.title, + ), + ) + }, + ) + + body +} + +#let body-entry( + ctx: (:), + body, +) = { + let metadata = entry-type-metadata.at(ctx.type) + show heading: it => format-heading(it, metadata.color.lighten(60%)) + show: page.with( + header: { + // background bar + place( + top + left, + dx: -100pt, + box( + width: 250%, + height: 100%, + fill: metadata.color.lighten(60%), + ), + ) + // edp box + place( + horizon + left, + box( + radius: 0.3em, + outset: 9pt, + width: 90pt, + fill: metadata.color, + align( + center, + text( + size: 14pt, + weight: "bold", + metadata.text, + ), + ), + ), + ) + // title + set align(center + horizon) + text( + weight: "bold", + size: 14pt, + ctx.title, + ) + }, + footer: { + place( + dx: -50pt, + box( + fill: surface-0, + width: 200%, + height: 100%, + ), + ) + set align(horizon + center) + grid( + columns: ( + 1fr, + 1fr, + 1fr, + ), + [*Name* #h(5pt) #ctx.author], + [*Date* #h(5pt) #ctx.date.display("[month]/[day]/[year]")], + [*Page* #h(5pt) #context counter(page).display()], + ) + }, + ) + + body +} + +#let appendix-entry( + ctx: (:), + body, +) = { + frontmatter-entry( + ctx: ctx, + body, + ) +} diff --git a/themes/hereford/format.typ b/themes/hereford/format.typ new file mode 100644 index 0000000..76f3b98 --- /dev/null +++ b/themes/hereford/format.typ @@ -0,0 +1,40 @@ +#import "./colors.typ": * + +#let format-heading( + it, + color, +) = { + if it.level == 1 { + set text(size: 13pt) + set block(spacing: 1em) + block( + radius: 0.3em, + outset: 7pt, + width: 100%, + fill: color, + it.body, + ) + } else { + set text(size: 12pt) + it + } +} + +#let rules( + doc, +) = { + set page( + "us-letter", + margin: ( + top: 2cm, + x: 1.5cm, + bottom: 1.5cm, + ), + ) + set text( + font: "Roboto", + size: 11pt, + ) + + doc +} diff --git a/themes/hereford/hereford.typ b/themes/hereford/hereford.typ new file mode 100644 index 0000000..7c65fb5 --- /dev/null +++ b/themes/hereford/hereford.typ @@ -0,0 +1,14 @@ +#import "./format.typ": rules +#import "./entries.typ": cover, frontmatter-entry, body-entry, appendix-entry +#import "./components/components.typ" +#import "./colors.typ" + +#let hereford-theme = ( + // Global show and set rules + rules: rules, + cover: cover, + // Entry pages + frontmatter-entry: frontmatter-entry, + body-entry: body-entry, + appendix-entry: appendix-entry, +) diff --git a/themes/themes.typ b/themes/themes.typ index 6fce657..9ad29be 100644 --- a/themes/themes.typ +++ b/themes/themes.typ @@ -1,3 +1,4 @@ #import "./default/default.typ" #import "./radial/radial.typ" -#import "./linear/linear.typ" \ No newline at end of file +#import "./linear/linear.typ" +#import "./hereford/hereford.typ"