From 0492ebaaacafa8c19fdf21e1900296d99a646c72 Mon Sep 17 00:00:00 2001 From: Vijay Janapa Reddi Date: Sun, 28 Dec 2025 13:25:55 -0500 Subject: [PATCH] feat(kits): add custom TikZ cover page with circuit board design - Create custom LaTeX cover page using labdivision-style circuit decorations - Use teal brand color with traces, nodes, and subtle geometric background - Display HARDWARE/KITS title on two lines with authors and companion text - Remove titlepage extension config in favor of custom LaTeX implementation - Add titlepage-bg.tex for potential future background customization --- kits/config/_quarto-pdf.yml | 66 ++---------------- kits/tex/before-body-includes.tex | 107 ++++++++++++++++++++++++------ kits/tex/titlepage-bg.tex | 101 ++++++++++++++++++++++++++++ 3 files changed, 192 insertions(+), 82 deletions(-) create mode 100644 kits/tex/titlepage-bg.tex diff --git a/kits/config/_quarto-pdf.yml b/kits/config/_quarto-pdf.yml index c9990abe0..2441bc506 100644 --- a/kits/config/_quarto-pdf.yml +++ b/kits/config/_quarto-pdf.yml @@ -82,69 +82,11 @@ format: \usepackage{needspace} \let\Needspace\needspace - # Cover page configuration - # Clean typographic cover - distinct from main textbook - # No background image - uses teal color accents instead - coverpage: true - coverpage-title: "Machine Learning Systems" - coverpage-author: ["Marcelo Rovai", "with Vijay Janapa Reddi"] - coverpage-footer: "Hands-On Labs for" - coverpage-theme: - page-text-align: "center" - page-color: "0d9488" - page-fontcolor: "FFFFFF" - - author-style: "plain" - author-sep: "newline" - author-fontsize: 18 - author-align: "right" - author-bottom: "0.15\\paperwidth" - author-left: 7in - author-width: 6in - - header-style: "none" - date-style: "none" - - title-fontsize: 48 - title-left: "0.075\\paperwidth" - title-bottom: "0.30\\paperwidth" - title-width: "0.9\\paperwidth" - - footer-fontsize: 24 - footer-left: "0.075\\paperwidth" - footer-bottom: "0.40\\paperwidth" - footer-width: "0.9\\paperwidth" - footer-align: "left" - # Title page configuration - titlepage: true - titlepage-theme: - elements: ["\\titleblock", - "Marcelo Rovai", - "with Vijay Janapa Reddi", - "\\vspace{60mm}", - "Hands-on embedded ML laboratories accompanying the Machine Learning Systems textbook.", - "\\vspace{10mm}", - "A Companion to Introduction to Machine Learning Systems", - "\\vfill", - "{{< meta date >}}", - "\\vfill"] - date: "today" - date-format: long - - page-align: "left" - title-style: "plain" - title-fontstyle: ["huge", "bfseries"] - title-space-after: "4\\baselineskip" - title-subtitle-space-between: "0.05\\textheight" - subtitle-fontstyle: ["large", "textit"] - author-style: "plain" - author-fontstyle: "large" - affiliation-style: "none" - footer-style: "plain" - footer-fontstyle: "large" - logo-size: "0.15\\textheight" - logo-space-after: "1\\baselineskip" + # Using custom LaTeX cover page defined in before-body-includes.tex + # Matches the division/labdivision style from header-includes.tex + coverpage: false + titlepage: false # LaTeX includes include-in-header: tex/header-includes.tex diff --git a/kits/tex/before-body-includes.tex b/kits/tex/before-body-includes.tex index 227bcffe8..b1155d9fc 100644 --- a/kits/tex/before-body-includes.tex +++ b/kits/tex/before-body-includes.tex @@ -1,25 +1,92 @@ -% Disable the default title page -\renewcommand{\maketitle}{ - \newgeometry{top=0.5in,bottom=1in,inner=1in,outer=1in} % Geometry for title page - \begin{titlepage} - \begin{center} - \thispagestyle{empty} - \includegraphics[trim=0 -10 0 0, clip, width=\textwidth]{cover-image-white.png} % Adjust the size and path to your image - {{\Huge\bfseries Machine Learning Systems}\\[1em] \par} - \vspace*{\fill} - {\large Written, edited and curated by \\[.1cm] Prof. Vijay Janapa Reddi \\[.2cm] Harvard University \\[1em] \normalsize {\itshape With special thanks to the community for their contributions and support.} \\[1em] \vfill \scriptsize Last Modified: \today\par \vfill} - \end{center} - \end{titlepage} - \restoregeometry % Restore original geometry -} +% ============================================================================= +% HARDWARE KITS COVER PAGE +% ============================================================================= +% Uses the same circuit board style as labdivision from header-includes.tex +% ============================================================================= -\let\endtitlepage\relax +% Custom cover page using labdivision-style circuit decorations +\begin{titlepage} +\thispagestyle{empty} +\begin{tikzpicture}[remember picture,overlay] + +% Circuit background with subtle gradient (same as labdivision) +\coordinate(S1)at([yshift=-200mm]current page.north west); +\draw[draw=none,fill=BlueDD!5](S1)--++(45:16)coordinate(S2)- +|(S2|-current page.north west)--(current page.north west)coordinate(S3)--(S1); + +% TOP AREA: Circuit lines in upper white space +\draw[crimson!50, line width=1.5pt] ([xshift=30mm,yshift=-40mm]current page.north west) -- ++(60mm,0); +\draw[crimson!40, line width=1pt] ([xshift=120mm,yshift=-50mm]current page.north west) -- ++(50mm,0); +\draw[crimson!50, line width=1.5pt] ([xshift=40mm,yshift=-70mm]current page.north west) -- ++(40mm,0); + +% Connecting lines in top area +\draw[crimson!30, line width=1pt] ([xshift=60mm,yshift=-40mm]current page.north west) -- ++(0,-20mm); +\draw[crimson!30, line width=1pt] ([xshift=145mm,yshift=-50mm]current page.north west) -- ++(0,10mm); + +% Neural nodes in top area +\fill[crimson!70] ([xshift=60mm,yshift=-40mm]current page.north west) circle (2.5mm); +\fill[white] ([xshift=60mm,yshift=-40mm]current page.north west) circle (1.5mm); +\fill[crimson!60] ([xshift=145mm,yshift=-50mm]current page.north west) circle (2mm); +\fill[white] ([xshift=145mm,yshift=-50mm]current page.north west) circle (1mm); +\fill[crimson!80] ([xshift=80mm,yshift=-70mm]current page.north west) circle (2mm); +\fill[white] ([xshift=80mm,yshift=-70mm]current page.north west) circle (1mm); + +% BOTTOM AREA: Circuit lines in lower white space +\draw[crimson!50, line width=1.5pt] ([xshift=20mm,yshift=-200mm]current page.north west) -- ++(70mm,0); +\draw[crimson!40, line width=1pt] ([xshift=110mm,yshift=-210mm]current page.north west) -- ++(60mm,0); +\draw[crimson!50, line width=1.5pt] ([xshift=35mm,yshift=-230mm]current page.north west) -- ++(45mm,0); + +% Connecting lines in bottom area +\draw[crimson!30, line width=1pt] ([xshift=55mm,yshift=-200mm]current page.north west) -- ++(0,-20mm); +\draw[crimson!30, line width=1pt] ([xshift=140mm,yshift=-210mm]current page.north west) -- ++(0,15mm); + +% Neural nodes in bottom area +\fill[crimson!70] ([xshift=55mm,yshift=-200mm]current page.north west) circle (2.5mm); +\fill[white] ([xshift=55mm,yshift=-200mm]current page.north west) circle (1.5mm); +\fill[crimson!60] ([xshift=140mm,yshift=-210mm]current page.north west) circle (2mm); +\fill[white] ([xshift=140mm,yshift=-210mm]current page.north west) circle (1mm); +\fill[crimson!80] ([xshift=80mm,yshift=-230mm]current page.north west) circle (2mm); +\fill[white] ([xshift=80mm,yshift=-230mm]current page.north west) circle (1mm); + +% SIDE AREAS: Subtle circuit elements on left and right edges +\draw[crimson!30, line width=1pt] ([xshift=15mm,yshift=-120mm]current page.north west) -- ++(20mm,0); +\draw[crimson!30, line width=1pt] ([xshift=175mm,yshift=-130mm]current page.north west) -- ++(15mm,0); +\fill[crimson!50] ([xshift=25mm,yshift=-120mm]current page.north west) circle (1.5mm); +\fill[white] ([xshift=25mm,yshift=-120mm]current page.north west) circle (0.8mm); +\fill[crimson!50] ([xshift=185mm,yshift=-130mm]current page.north west) circle (1.5mm); +\fill[white] ([xshift=185mm,yshift=-130mm]current page.north west) circle (0.8mm); + +% Title in center (two lines) +\node[inner sep=0mm,draw=none,anchor=center, +align=center,font={\fontsize{44pt}{50pt}\selectfont\bfseries}] +(TITLE) at ([yshift=20mm]current page.center) {\color{crimson}HARDWARE\\KITS}; + +% Authors +\node[inner sep=0mm,draw=none,anchor=north,text width=0.8\textwidth, +align=center,font={\large}] +(AUTHORS) at ([yshift=-15mm]TITLE.south) {% +\color{black}Marcelo Rovai\\[3pt] +\color{black!70}with Vijay Janapa Reddi\\[3pt] +\color{black!50}\normalsize Harvard University +}; + +% Companion text box at bottom +\node[inner sep=12pt,draw=none,fill=black!5,rounded corners=4pt, +anchor=south,text width=0.6\textwidth,align=center] +(COMPANION) at ([yshift=55mm]current page.south) {% +{\small\color{black!60}\textit{A Hands-On Companion to the}}\\[4pt] +{\normalsize\color{crimson}\textbf{Machine Learning Systems} textbook}\\[4pt] +{\small\color{crimson}\href{https://mlsysbook.ai}{mlsysbook.ai}} +}; + +% Date at very bottom +\node[inner sep=0mm,draw=none,anchor=south,font={\footnotesize}] +at ([yshift=15mm]current page.south) {\color{black!40}\today}; + +\end{tikzpicture} +\end{titlepage} % ============================================================================= % FORCE ARABIC PAGE NUMBERING FROM START % ============================================================================= -% Hardware Kits doesn't have a traditional frontmatter/mainmatter split, -% so we use Arabic numerals (1, 2, 3...) throughout the entire document. -\AtBeginDocument{ - \pagenumbering{arabic} -} +\pagenumbering{arabic} diff --git a/kits/tex/titlepage-bg.tex b/kits/tex/titlepage-bg.tex new file mode 100644 index 000000000..361708f8d --- /dev/null +++ b/kits/tex/titlepage-bg.tex @@ -0,0 +1,101 @@ +% ============================================================================= +% HARDWARE KITS TITLE PAGE BACKGROUND +% ============================================================================= +% Circuit board inspired TikZ decorations for the title page +% Uses teal (#0d9488) as the primary accent color +% ============================================================================= + +\begin{tikzpicture}[remember picture, overlay] + % Define teal color + \definecolor{kitsteal}{HTML}{0d9488} + + % Define styles for circuit elements + \tikzset{ + trace/.style={draw=kitsteal!35, line width=1.5pt}, + trace-light/.style={draw=kitsteal!20, line width=1pt}, + trace-thin/.style={draw=kitsteal!15, line width=0.6pt}, + pad/.style={circle, fill=kitsteal!40, draw=kitsteal!60, minimum size=6pt, inner sep=0pt}, + pad-small/.style={circle, fill=kitsteal!30, draw=kitsteal!45, minimum size=4pt, inner sep=0pt}, + pad-large/.style={circle, fill=kitsteal!50, draw=kitsteal!70, minimum size=8pt, inner sep=0pt}, + via/.style={circle, fill=white, draw=kitsteal!40, minimum size=5pt, inner sep=0pt, line width=0.8pt} + } + + % TOP-LEFT: Primary circuit cluster (dense) + \node[pad-large] (tl1) at ($(current page.north west)+(2.2cm,-2.2cm)$) {}; + \node[pad] (tl2) at ($(tl1)+(1.4cm,0)$) {}; + \node[pad] (tl3) at ($(tl1)+(0,-1.2cm)$) {}; + \node[pad-small] (tl4) at ($(tl1)+(2.2cm,-0.4cm)$) {}; + \node[pad-small] (tl5) at ($(tl1)+(0.8cm,-1.8cm)$) {}; + \node[via] (tl6) at ($(tl1)+(1.6cm,-1.4cm)$) {}; + \node[pad-small] (tl7) at ($(tl1)+(2.8cm,-1.0cm)$) {}; + % Traces + \draw[trace] (tl1) -- (tl2); + \draw[trace] (tl1) -- (tl3); + \draw[trace-light] (tl2) -- (tl4); + \draw[trace-light] (tl3) -- (tl5); + \draw[trace-light] (tl4) -- (tl6); + \draw[trace-light] (tl5) -- (tl6); + \draw[trace-thin] (tl4) -- (tl7); + \draw[trace-thin] (tl6) -- (tl7); + + % TOP-RIGHT: Secondary cluster (lighter) + \node[pad] (tr1) at ($(current page.north east)+(-2.0cm,-2.0cm)$) {}; + \node[pad-small] (tr2) at ($(tr1)+(-1.2cm,-0.3cm)$) {}; + \node[pad-small] (tr3) at ($(tr1)+(-0.5cm,-1.2cm)$) {}; + \node[via] (tr4) at ($(tr1)+(-1.5cm,-1.0cm)$) {}; + \draw[trace-light] (tr1) -- (tr2); + \draw[trace-light] (tr1) -- (tr3); + \draw[trace-thin] (tr2) -- (tr4); + \draw[trace-thin] (tr3) -- (tr4); + + % BOTTOM-LEFT: Sparse elements + \node[pad] (bl1) at ($(current page.south west)+(1.8cm,2.2cm)$) {}; + \node[pad-small] (bl2) at ($(bl1)+(1.0cm,0.5cm)$) {}; + \node[pad-small] (bl3) at ($(bl1)+(1.8cm,0)$) {}; + \node[via] (bl4) at ($(bl1)+(0.5cm,1.2cm)$) {}; + \draw[trace-light] (bl1) -- (bl2); + \draw[trace-light] (bl2) -- (bl3); + \draw[trace-thin] (bl1) -- (bl4); + + % BOTTOM-RIGHT: Dense secondary cluster (diagonal balance) + \node[pad-large] (br1) at ($(current page.south east)+(-2.2cm,2.2cm)$) {}; + \node[pad] (br2) at ($(br1)+(-1.4cm,0)$) {}; + \node[pad] (br3) at ($(br1)+(0,1.2cm)$) {}; + \node[pad-small] (br4) at ($(br1)+(-2.2cm,0.4cm)$) {}; + \node[pad-small] (br5) at ($(br1)+(-0.8cm,1.8cm)$) {}; + \node[via] (br6) at ($(br1)+(-1.6cm,1.4cm)$) {}; + \node[pad-small] (br7) at ($(br1)+(-2.8cm,1.0cm)$) {}; + \draw[trace] (br1) -- (br2); + \draw[trace] (br1) -- (br3); + \draw[trace-light] (br2) -- (br4); + \draw[trace-light] (br3) -- (br5); + \draw[trace-light] (br4) -- (br6); + \draw[trace-light] (br5) -- (br6); + \draw[trace-thin] (br4) -- (br7); + \draw[trace-thin] (br6) -- (br7); + + % Left edge: vertical pathway + \node[pad-small] (le1) at ($(current page.west)+(0.9cm,6.0cm)$) {}; + \node[via] (le2) at ($(current page.west)+(1.1cm,4.0cm)$) {}; + \node[pad-small] (le3) at ($(current page.west)+(0.9cm,2.0cm)$) {}; + \node[via] (le4) at ($(current page.west)+(1.1cm,-1.0cm)$) {}; + \draw[trace-thin] (le1) -- (le2); + \draw[trace-thin] (le2) -- (le3); + \draw[trace-thin] (le3) -- (le4); + + % Right edge: vertical pathway + \node[pad-small] (re1) at ($(current page.east)+(-0.9cm,5.0cm)$) {}; + \node[via] (re2) at ($(current page.east)+(-1.1cm,2.5cm)$) {}; + \node[pad-small] (re3) at ($(current page.east)+(-0.9cm,0cm)$) {}; + \node[via] (re4) at ($(current page.east)+(-1.1cm,-3.0cm)$) {}; + \draw[trace-thin] (re1) -- (re2); + \draw[trace-thin] (re2) -- (re3); + \draw[trace-thin] (re3) -- (re4); + + % Subtle corner accents - small right angles suggesting PCB corners + \draw[trace-thin] ($(current page.north west)+(0.5cm,-0.5cm)$) -- ++(0,-0.8cm) -- ++(0.8cm,0); + \draw[trace-thin] ($(current page.north east)+(-0.5cm,-0.5cm)$) -- ++(0,-0.8cm) -- ++(-0.8cm,0); + \draw[trace-thin] ($(current page.south west)+(0.5cm,0.5cm)$) -- ++(0,0.8cm) -- ++(0.8cm,0); + \draw[trace-thin] ($(current page.south east)+(-0.5cm,0.5cm)$) -- ++(0,0.8cm) -- ++(-0.8cm,0); + +\end{tikzpicture}