Punk Theme Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Apply a Classic Punk / Zine aesthetic to the entire L’Underfitting Quarto blog via a single custom.scss file.
Architecture: Delete styles.css (conflicts with new theme), update _quarto.yml to load custom.scss via the Quarto SCSS theme system, then build the stylesheet component by component. No .qmd content files are touched.
Tech Stack: Quarto 1.x, SCSS (Quarto SCSS theming), Bootstrap 5 (Quarto’s base), Google Fonts (Courier Prime + Lora), system font Impact.
File Map
| Action | Path | Responsibility |
|---|---|---|
| Delete | styles.css |
Removed — conflicts with punk spec |
| Create | custom.scss |
All punk styles — single source of truth |
| Modify | _quarto.yml |
Point theme at custom.scss, remove css: styles.css |
Task 1: Bootstrap — delete styles.css and wire custom.scss
Files: - Delete: styles.css - Create: custom.scss - Modify: _quarto.yml
Run from the project root (where _quarto.yml lives):
rm styles.cssCreate custom.scss at the project root with this minimal content:
/*-- scss:defaults --*/
$body-bg: #F5F0E8;
/*-- scss:rules --*/
// Punk theme — L'Underfitting
// Rules are added in subsequent tasks.The /*-- scss:defaults --*/ block overrides Bootstrap Sass variables (processed before Bootstrap compiles). The /*-- scss:rules --*/ block adds plain CSS rules after Bootstrap.
Find the format.html block (currently lines 71–74) and replace:
format:
html:
theme: cosmo
css: styles.css
toc: truewith:
format:
html:
theme: [cosmo, custom.scss]
toc: truequarto previewExpected: site loads, background is #F5F0E8 (cream/newsprint). No build errors. If build fails, check that custom.scss has the correct /*-- scss:defaults --*/ section marker — Quarto requires it.
Task 2: Google Fonts + Paper Grain Texture
Files: - Modify: custom.scss
Add the Google Fonts @import as the first line of the /*-- scss:rules --*/ section (before any other rules — SCSS may warn if @import appears after other rules):
// ── Fonts ──────────────────────────────────────────────────────────────
@import url('https://fonts.googleapis.com/css2?family=Courier+Prime:ital,wght@0,400;0,700;1,400&family=Lora:ital,wght@0,400;0,600;1,400&display=swap');
// ── Paper grain texture ─────────────────────────────────────────────────
body {
background-color: #F5F0E8;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23n)' opacity='0.035'/%3E%3C/svg%3E");
}quarto previewExpected: body still newsprint cream, fonts loading (check Network tab — fonts.googleapis.com requests). Paper grain is subtle — you may need to look closely.
Task 5: Headings + Body Typography (Article Pages)
Files: - Modify: custom.scss
Append to /*-- scss:rules --*/:
// ── Headings ─────────────────────────────────────────────────────────────
h1, h2, h3, h4, h5, h6 {
font-family: Impact, 'Arial Black', sans-serif;
text-transform: uppercase;
color: #1A1A1A;
}
h1 { font-size: 2.8rem; letter-spacing: -0.02em; line-height: 1; }
h2 { font-size: 1.8rem; border-bottom: 2px solid #1A1A1A; padding-bottom: 0.25rem; margin-bottom: 0.75rem; }
h3 { font-size: 1.1rem; }
// Override heading color inside the dark title banner (set in Task 4)
.quarto-title-banner h1,
.quarto-title-banner h2,
.quarto-title-banner h3 {
color: #F5F0E8;
border-bottom: none;
}// ── Article body ──────────────────────────────────────────────────────────
// Target the article content column under page-layout: full.
// Quarto wraps article content in .page-body > .content (inspect rendered
// HTML to confirm the selector if styles don't apply — full layout removes
// the standard .container constraint).
.page-body .content,
article.content,
.quarto-section-identifier {
font-family: 'Lora', Georgia, serif;
font-size: 1rem;
line-height: 1.75;
color: #222;
max-width: 680px;
margin-left: auto;
margin-right: auto;
}
// Links
.page-body .content a,
article.content a {
color: #CC2200;
text-decoration: underline;
text-underline-offset: 2px;
}
// Blockquotes
blockquote {
border-left: 3px solid #CC2200;
padding-left: 0.8rem;
font-family: 'Courier Prime', monospace;
font-style: italic;
color: #444;
margin: 1rem 0;
}
// Inline code
code:not(pre code) {
font-family: 'Courier Prime', monospace;
background-color: #EDE8DF;
color: #CC2200;
padding: 0 3px;
border-radius: 0;
}
// Code blocks
pre {
background-color: #1A1A1A !important;
border-left: 3px solid #CC2200;
border-radius: 0;
code {
font-family: 'Courier Prime', monospace;
color: #F5C842;
font-size: 0.85rem;
}
}quarto previewNavigate to a blog post. Expected: Impact section headings, Lora body at 1rem, Courier blockquotes with red left border, dark code blocks with yellow text. If max-width: 680px isn’t applying, open DevTools, inspect .page-body children, and identify the actual content wrapper selector — update the rule accordingly.
Task 7: Table Listing (Projects Page)
Files: - Modify: custom.scss
Append to /*-- scss:rules --*/:
// ── Table-type listing (projects/index.qmd) ──────────────────────────────
.quarto-listing-table table {
border-collapse: collapse;
width: 100%;
thead tr {
background-color: #1A1A1A;
th {
font-family: Impact, sans-serif;
font-size: 0.75rem;
text-transform: uppercase;
letter-spacing: 0.1em;
color: #F5C842;
border: none;
padding: 0.6rem 0.8rem;
}
}
tbody tr {
background-color: #F5F0E8;
border-bottom: 1px dashed #AAA;
&:hover { background-color: #EDE8DF; }
td {
font-family: 'Courier Prime', monospace;
font-size: 0.8rem;
color: #333;
padding: 0.6rem 0.8rem;
border: none;
a {
color: #CC2200;
text-decoration: underline;
text-underline-offset: 2px;
}
}
}
}quarto previewNavigate to the Projects page. Expected: dark header row with yellow Impact column names, newsprint body rows with dashed separators, red links, hover darkens row.
Task 8: Callout Blocks + Code Fold Toggle
Files: - Modify: custom.scss
Append to /*-- scss:rules --*/:
// ── Callout blocks ───────────────────────────────────────────────────────
.callout {
border-left: 4px solid #CC2200 !important;
border-right: none;
border-top: none;
border-bottom: none;
border-radius: 0;
background: #EDE8DF !important;
.callout-title {
font-family: Impact, sans-serif;
font-size: 0.85rem;
text-transform: uppercase;
color: #1A1A1A;
background: transparent;
}
.callout-icon::before {
color: #CC2200;
}
// Remove per-type color backgrounds
&.callout-note,
&.callout-tip,
&.callout-warning,
&.callout-caution,
&.callout-important {
background: #EDE8DF !important;
border-left-color: #CC2200 !important;
}
}// ── Code fold / code tools ───────────────────────────────────────────────
.code-fold-btn,
details summary {
font-family: 'Courier Prime', monospace;
font-size: 0.8rem;
color: #CC2200;
background: transparent;
border: none;
cursor: pointer;
padding: 0;
}
.code-tools-menu {
background: #1A1A1A;
border: 1px solid #333;
.dropdown-item {
color: #F5C842;
font-family: 'Courier Prime', monospace;
font-size: 0.75rem;
&:hover { background-color: #CC2200; color: #fff; }
}
}quarto previewNavigate to a post with a callout (e.g., any post using ::: {.callout-note}). Expected: warm beige background, red left border, Impact title. Check a post with code-fold: true — the toggle should be Courier in red.
Notes for Implementer
- SCSS section markers matter.
/*-- scss:defaults --*/= Bootstrap variable overrides (compiled before Bootstrap)./*-- scss:rules --*/= plain CSS rules (appended after Bootstrap). Rules in defaults won’t work and vice versa. !importantis sometimes unavoidable against Bootstrap’s generated specificity. Use it deliberately, not everywhere.- The article body
max-width: 680pxselector is the most likely to need adjustment. Underpage-layout: full, Quarto removes the standard.containercolumn. Inspect the rendered HTML of a blog post and find the actual wrapper element around the prose content — target that. - Don’t touch
.qmdfiles. All changes go incustom.scssand_quarto.ymlonly. - Quarto rebuilds the full
_site/directory. Deleting the sourcestyles.cssis enough —_site/styles.cssis a build artifact that will be regenerated correctly without it.