More visual tweaks

This commit is contained in:
Ian Keane 2026-08-26 17:54:57 -04:00
parent 537e279780
commit 0b0cc6fda5
4 changed files with 71 additions and 87 deletions

View file

@ -40,8 +40,8 @@
,(date-range (field tc 'date-start) (field tc 'date-end)))
(div (@ (class "title-meta"))
,(field tc 'company) " • " ,(field tc 'location))
(div (@ (class "title-blurb"))
,(bullets (field tc 'blurb)))))
(p (@ (class "title-blurb"))
,(string-join (field tc 'blurb) " "))))
;; Emit a title card followed by its project cards as a flat list of siblings
(define (render-title-flat tc)
@ -130,6 +130,43 @@
(list `(h2 (@ (class "sec-heading")) ,cur-label))
cur-items)))))))
;; ─── Column distribution ───────────────────────────────────────────────────────
;; Wrap all items in two independent divs, splitting at the midpoint.
;; Because each col is a separate block formatting context, expanding a card
;; pushes siblings down within that col only — no cross-column movement,
;; no hover loop.
;;
;; num-columns: change to 3 if your resume gets too long, and update the
;; CSS grid-template-columns to match.
(define num-columns 3)
(define (heading? item)
(and (pair? item) (eq? (car item) 'h2)))
(define (list-ref* lst i)
(if (= i 0) (car lst) (list-ref* (cdr lst) (- i 1))))
(define (split-into-columns items n)
(let* ((total (length items))
(chunk (inexact->exact (ceiling (/ total n)))))
(let loop ((i 0) (start 0) (remaining n) (acc '()))
(if (= remaining 1)
(reverse (cons `(div (@ (class "col")) ,@(list-tail items start)) acc))
(let* ((raw-end (min (+ start chunk) total))
;; Walk backwards from the cut point: if the last item
;; in this slice is a heading (orphaned at col bottom),
;; move it to the next column.
(end (let nudge ((e raw-end))
(if (and (> e (+ start 1))
(heading? (list-ref* items (- e 1))))
(nudge (- e 1))
e))))
(loop (+ i 1) end (- remaining 1)
(cons `(div (@ (class "col"))
,@(list-tail (list-head items end) start))
acc)))))))
;; ─── Front matter ─────────────────────────────────────────────────────────────
(define (render-front-matter fm)
@ -143,40 +180,19 @@
(define (render-resume res)
(let* ((fm (field res 'front-matter))
(items (sections->flat-items (field res 'sections))))
(items (sections->flat-items (field res 'sections)))
(cols (split-into-columns items num-columns)))
`(*TOP*
(html (@ (lang "en"))
(head
(meta (@ (charset "UTF-8")))
(meta (@ (name "viewport") (content "width=device-width, initial-scale=1")))
(title ,(field fm 'name))
(link (@ (rel "stylesheet") (href "style.css")))
;; Measure the front-matter height after every resize/zoom and
;; set .columns height to exactly fill the remaining space.
(script "
function setColHeight() {
var fm = document.querySelector('.front-matter');
var col = document.querySelector('.columns');
if (!fm || !col) return;
var used = fm.getBoundingClientRect().height
+ parseInt(getComputedStyle(document.body).paddingTop) * 2;
col.style.height = (window.innerHeight - used) + 'px';
}
window.addEventListener('load', setColHeight);
window.addEventListener('resize', setColHeight);
// zoom via ctrl+/- fires resize in most browsers, but also poll as fallback
var _lastW = window.innerWidth, _lastH = window.innerHeight;
setInterval(function() {
if (window.innerWidth !== _lastW || window.innerHeight !== _lastH) {
_lastW = window.innerWidth; _lastH = window.innerHeight;
setColHeight();
}
}, 200);
"))
(link (@ (rel "stylesheet") (href "style.css"))))
(body
,(render-front-matter fm)
(main (@ (class "columns"))
,@items))))))
,@cols))))))
(display "<!DOCTYPE html>\n")
(sxml->xml (render-resume resume))

File diff suppressed because one or more lines are too long

View file

@ -91,9 +91,7 @@
(list
(make-title
"Senior Software Engineer" "Acme Corp" "Remote" "Jun 2022" "Present"
'("Led a team of 4 engineers on the core platform."
"Drove adoption of internal developer tooling."
"Reviewed architecture proposals and mentored junior engineers.")
'("Led a team of 4 engineers on the core platform, driving adoption of internal developer tooling and mentoring junior engineers through architecture proposals and code review.")
(list
(make-project
"Distributed Config Service" "Mar 2023" "Present"
@ -111,8 +109,7 @@
'("Go" "Bleve" "React" "OpenAPI"))))
(make-title
"Software Engineer II" "Acme Corp" "Remote" "Jan 2020" "May 2022"
'("Owned the authentication service end-to-end."
"Reduced API latency by 35% through caching improvements.")
'("Owned the authentication service end-to-end, reducing API latency by 35% through targeted caching improvements.")
(list
(make-project
"Auth Service Rewrite" "Jan 2020" "Dec 2020"
@ -135,9 +132,7 @@
(list
(make-title
"Full-Stack Engineer" "Startup XYZ" "Athens, GA" "Jul 2017" "Dec 2019"
'("Built product features across the React frontend and Node.js backend."
"Maintained CI/CD pipelines and AWS infrastructure."
"Collaborated directly with design and product teams.")
'("Built product features across the React frontend and Node.js backend, maintained CI/CD pipelines and AWS infrastructure, and collaborated directly with design and product teams.")
(list
(make-project
"Real-Time Dashboard" "Feb 2019" "Dec 2019"
@ -197,8 +192,8 @@
(list 'resume
(cons 'front-matter my-front-matter)
(cons 'sections (list my-education
job-acme
job-startup
job-acme
my-hobby-projects
my-interests
my-favorite-software))))

View file

@ -65,31 +65,26 @@ a { color: var(--accent); text-decoration: none; }
}
/* ─── Column layout ──────────────────────────────────────────────────────────── */
/* Two independent .col divs. Expanding a card pushes siblings within
its own col only cards never shift between columns, no hover loop.
To go to 3 cols: set num-columns=3 in generate.scm, regenerate,
and change repeat(2,...) to repeat(3,...) below. */
.columns {
column-width: 22em;
column-gap: 2em;
column-fill: balance;
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 0 2em;
align-items: start;
}
/* Prevent any card from being split across a column boundary */
.sec-heading,
.title-card,
.project-card,
.education-card,
.interests,
.favorite-software {
break-inside: avoid;
}
.col { min-width: 0; }
/* Keep each section heading attached to whatever follows it */
.sec-heading {
break-after: avoid;
@media (max-width: 600px) {
.columns { grid-template-columns: 1fr; }
}
/* ─── Section headings ───────────────────────────────────────────────────────── */
.sec-heading {
font-size: 0.7rem;
font-weight: 800;
font-size: 0.95rem;
text-transform: uppercase;
letter-spacing: 0.12em;
color: var(--accent);
@ -114,8 +109,7 @@ a { color: var(--accent); text-decoration: none; }
.project-name,
.edu-degree {
font-weight: 700;
font-size: 0.88rem;
}
font-size: 0.78rem;}
.date-range {
font-size: 0.72rem;
@ -138,14 +132,12 @@ a { color: var(--accent); text-decoration: none; }
margin-bottom: 4px;
}
.title-blurb ul { padding-left: 12px; }
.title-blurb li {
font-size: 0.82rem;
p.title-blurb {
font-size: 0.68rem;
line-height: 1.5;
margin-bottom: 1px;
color: rgba(255,255,255,0.85);
margin-top: 3px;
}
.title-blurb li::before { content: "- "; color: var(--muted); }
/* ─── Project card ───────────────────────────────────────────────────────────── */
.project-card {
@ -173,15 +165,15 @@ a { color: var(--accent); text-decoration: none; }
opacity: 0.7;
}
.project-name { font-size: 0.83rem; }
.project-name { font-size: 0.72rem; }
.project-summary ul { padding-left: 12px; margin-top: 2px; }
.project-summary li {
font-size: 0.8rem;
font-size: 0.68rem;
line-height: 1.5;
color: rgba(255,255,255,0.85);
}
.project-summary li::before { content: "- "; color: var(--muted); }
.project-summary li::before { content: " "; color: var(--muted); }
.project-details {
max-height: 0;
@ -196,12 +188,12 @@ a { color: var(--accent); text-decoration: none; }
}
.project-details ul { padding-left: 12px; margin-top: 4px; }
.project-details li {
font-size: 0.78rem;
font-size: 0.68rem;
color: var(--muted);
line-height: 1.5;
margin-bottom: 1px;
}
.project-details li::before { content: "- "; }
.project-details li::before { content: " "; }
.tech-list {
display: flex;
@ -233,7 +225,7 @@ a { color: var(--accent); text-decoration: none; }
margin-bottom: 1px;
color: rgba(255,255,255,0.85);
}
.edu-bullets li::before { content: "- "; color: var(--muted); }
.edu-bullets li::before { content: " "; color: var(--muted); }
.edu-extras {
max-height: 0;
@ -254,7 +246,7 @@ a { color: var(--accent); text-decoration: none; }
line-height: 1.5;
margin-bottom: 1px;
}
.edu-extras li::before { content: "- "; }
.edu-extras li::before { content: " "; }
/* ─── Interests — 2-column micro-card grid ───────────────────────────────────── */
.interests {