/* ==========================================================================
   andy.rusterholz.org

   One stylesheet, no framework, no build step. Organized as:
   fonts, tokens, base, layout, home, subpages, prose, projects, resume,
   footer, print.

   The governing idea is a well-set document: hairline rules and small-caps
   labels do the organizing, so there are no cards, panels, or boxes anywhere.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Fonts — self-hosted, see fonts/LICENSE.md for provenance and sizes
   -------------------------------------------------------------------------- */

@font-face {
  font-family: "Source Serif 4";
  src: url("fonts/source-serif-4-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Source Serif 4";
  src: url("fonts/source-serif-4-600.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Source Serif 4";
  src: url("fonts/source-serif-4-italic-400.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: "IBM Plex Mono";
  src: url("fonts/ibm-plex-mono-500.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "IBM Plex Mono";
  src: url("fonts/ibm-plex-mono-600.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

/* Pinned to optical size 72: the display cut, not a scaled-up text cut. */
@font-face {
  font-family: "Newsreader Display";
  src: url("fonts/newsreader-display-500.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

/* --------------------------------------------------------------------------
   Tokens
   -------------------------------------------------------------------------- */

:root {
  --paper:   #F7F7F4;
  --ink:     #1A1E1C;
  --muted:   #64706B;
  --rule:    #DFE0DA;
  --accent:  #2C6E63;
  --frame:   #E8E9E3;

  --serif:   "Source Serif 4", Charter, Georgia, serif;
  --display: "Newsreader Display", "Source Serif 4", Charter, Georgia, serif;
  --mono:    "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root {
    --paper:  #121614;
    --ink:    #E4E9E6;
    --muted:  #8C9B95;
    --rule:   #252C29;
    --accent: #6FC2B0;
    --frame:  #1C2220;
  }
}

/* --------------------------------------------------------------------------
   Base
   -------------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  font-size: 1.0625rem;
  line-height: 1.62;
  font-variant-numeric: oldstyle-nums;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a { color: var(--accent); }

a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 1px;
}

/* Links in running prose: underlined, but lightly, so a paragraph with
   several of them does not turn into a fence. */
.prose a,
.lede a {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-color: color-mix(in srgb, var(--accent) 35%, transparent);
}
.prose a:hover,
.lede a:hover { text-decoration-color: var(--accent); }

/* A shared label style: mono, uppercase, tracked out. Used for the standfirst,
   the availability flag, section heads, and metadata lines. */
.label {
  font-family: var(--mono);
  font-size: 0.875rem;
  font-weight: 500;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}

/* Skip link, visible only when focused. */
.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--paper);
  color: var(--accent);
  padding: 0.75rem 1rem;
  font-family: var(--mono);
  font-size: 0.875rem;
  z-index: 10;
}
.skip:focus { left: 0; }

/* --------------------------------------------------------------------------
   Layout

   One column at every width. On wide viewports the column tracks the viewport
   at ~46%, with a floor so it never gets mean on a small laptop and a ceiling
   so the measure never outgrows comfortable reading on a large display.
   -------------------------------------------------------------------------- */

.page {
  max-width: 34rem;
  margin: 0 auto;
  padding: 2.75rem 1.375rem 4rem;
}

/* --------------------------------------------------------------------------
   Home — masthead
   -------------------------------------------------------------------------- */

.masthead {
  display: flex;
  align-items: center;
  gap: 1.125rem;
  margin-bottom: 1.875rem;
}

/* Without min-width, this flex item refuses to shrink below the width of the
   name, and the whole page ends up wider than a 375px phone. */
.masthead > div {
  min-width: 0;
}

.portrait {
  flex: 0 0 auto;
  width: 90px;
  height: 90px;
  border-radius: 2px;
  background: var(--frame);
  border: 1px solid var(--rule);
  overflow: hidden;
  display: grid;
  place-items: center;
}

.portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.masthead h1 {
  margin: 0;
  font-family: var(--display);
  font-size: 2.125rem;
  font-weight: 500;
  line-height: 1.04;
  letter-spacing: -0.01em;
}

.standfirst {
  margin: 0.4375rem 0 0;
  color: var(--accent);
}

/* --------------------------------------------------------------------------
   Home — lede and availability
   -------------------------------------------------------------------------- */

.lede {
  margin: 0 0 1.75rem;
}

.availability {
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  padding: 1.25rem 0 1.3125rem;
  margin: 0;
}

.flag {
  display: block;
  margin: 0 0 0.5rem;
  font-weight: 600;
  color: var(--accent);
  letter-spacing: 0.14em;
}

.availability p { margin: 0 0 0.5rem; }
.availability p:last-child { margin-bottom: 0; }

/* --------------------------------------------------------------------------
   Home — index of contents

   A table of contents, not a grid of cards. The rows subgrid into one column
   pair so the descriptions line up under each other whatever the names
   measure; without subgrid support each row sizes its own name column.
   -------------------------------------------------------------------------- */

.index {
  display: grid;
  grid-template-columns: max-content 1fr;
  column-gap: 0.75rem;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  padding: 1.25rem 0 1.3125rem;
}

/* Neighbors share a rule rather than stacking two: the availability block's
   bottom rule opens the index on the home page, and the footer's top rule
   closes it on the contact and 404 pages. */
.availability + .index { border-top: 0; }
main > .index:last-child { border-bottom: 0; padding-bottom: 0; }

.index .flag { grid-column: 1 / -1; }

.index a {
  display: grid;
  grid-template-columns: max-content 1fr;
  grid-template-columns: subgrid;
  grid-column: 1 / -1;
  column-gap: inherit;
  align-items: baseline;
  padding: 0.5rem 0;
  text-decoration: none;
  color: inherit;
}

.index .n {
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-color: color-mix(in srgb, var(--accent) 35%, transparent);
}
.index a:hover .n { text-decoration-color: var(--accent); }

.index .d {
  font-size: 0.9375rem;
  color: var(--muted);
  line-height: 1.4;
}

/* --------------------------------------------------------------------------
   Subpages — site header
   -------------------------------------------------------------------------- */

.sitehead {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem 1.25rem;
  padding-bottom: 0.875rem;
  border-bottom: 1px solid var(--rule);
  margin-bottom: 2.25rem;
}

.sitename {
  font-family: var(--display);
  font-size: 1.4375rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: inherit;
  text-decoration: none;
}
.sitename:hover { color: var(--accent); }

.sitehead nav {
  display: flex;
  gap: 1rem;
}

.sitehead nav a {
  font-family: var(--mono);
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: none;
}
.sitehead nav a:hover { color: var(--accent); }

.sitehead nav a[aria-current="page"] {
  color: var(--ink);
  border-bottom: 1px solid var(--accent);
}

/* Page title */

.pagetitle {
  margin: 0 0 0.5rem;
  font-family: var(--display);
  font-size: 2.125rem;
  font-weight: 500;
  line-height: 1.08;
  letter-spacing: -0.01em;
}

.pagenote {
  margin: 0 0 2.25rem;
  color: var(--muted);
  font-size: 1rem;
}

/* --------------------------------------------------------------------------
   Prose
   -------------------------------------------------------------------------- */

.prose p { margin: 0 0 1rem; }
.prose p:last-child { margin-bottom: 0; }

/* Inline code. IBM Plex Mono is already loaded for the labels, so this costs no
   extra font weight -- but 500 is the lightest cut we ship, so ask for it rather
   than letting 400 synthesize. Sized in em so it tracks its surrounding text,
   and against Source Serif the mono face is signal enough without a box. */
.prose code {
  font-family: var(--mono);
  font-size: 0.8125em;
  font-weight: 500;
  overflow-wrap: break-word;
}

.prose ul {
  margin: 0 0 1rem;
  padding-left: 1.125rem;
  list-style: none;
}

.prose li {
  position: relative;
  margin-bottom: 0.5rem;
}

/* A hairline dash for a bullet, in keeping with the rules elsewhere. */
.prose li::before {
  content: "";
  position: absolute;
  left: -1.125rem;
  top: 0.72em;
  width: 0.5rem;
  height: 1px;
  background: var(--accent);
}

.prose strong { font-weight: 600; }
.prose em { font-style: italic; }

.prose code {
  font-family: var(--mono);
  font-size: 0.875em;
  background: var(--frame);
  padding: 0.1em 0.35em;
  border-radius: 2px;
}

/* --------------------------------------------------------------------------
   Projects
   -------------------------------------------------------------------------- */

.project {
  border-top: 1px solid var(--rule);
  padding-top: 1.75rem;
  margin-bottom: 2.5rem;
}

.project:last-of-type { margin-bottom: 1.5rem; }

.project h2 {
  margin: 0 0 0.375rem;
  font-family: var(--display);
  font-size: 1.75rem;
  font-weight: 500;
  letter-spacing: -0.005em;
}

.project .meta {
  margin: 0 0 1rem;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
}

.project .meta .sep {
  color: var(--rule);
  padding: 0 0.4em;
}

.project .links {
  margin: 1rem 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
}

.project .links a {
  font-family: var(--mono);
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
  text-decoration-color: color-mix(in srgb, var(--accent) 35%, transparent);
}
.project .links a:hover { text-decoration-color: var(--accent); }

/* --------------------------------------------------------------------------
   Résumé

   This markup is generated from resume/andy-rusterholz-resume.md by
   bin/build-resume, so the selectors below match plain markdown output:
     h1  the name          h2  section        h3  employer
     h3 + p   the location and dates line
     p > strong:first-child   a run-in heading for a body of work
   -------------------------------------------------------------------------- */

.resume-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  margin: -1.25rem 0 1.75rem;
}

.resume-actions a {
  font-family: var(--mono);
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
  text-decoration-color: color-mix(in srgb, var(--accent) 35%, transparent);
}
.resume-actions a:hover { text-decoration-color: var(--accent); }

.resume h1 {
  margin: 0 0 0.5rem;
  font-family: var(--display);
  font-size: 2.125rem;
  font-weight: 500;
  line-height: 1.08;
  letter-spacing: -0.01em;
}

/* The site URL and the GitHub handle, hidden on screen and restored in print.
   On screen they are noise -- the URL is the address bar, and the footer
   already links GitHub -- and all four items need 953px of type against a
   column that never exceeds 768px, so the line wrapped at every width. On paper
   there is no address bar and no footer, so they have to be there. */
.print-only { display: none; }

/* The contact line directly under the name. */
.resume h1 + p {
  margin: 0 0 2rem;
  font-family: var(--mono);
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  color: var(--muted);
}
.resume h1 + p strong { font-weight: 500; }
.resume h1 + p a { color: var(--muted); }
.resume h1 + p a:hover { color: var(--accent); }

.resume h2 {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 2.25rem 0 1rem;
  font-family: var(--mono);
  font-size: 0.875rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
}
.resume h2::after {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  background: var(--rule);
}

.resume h3 {
  margin: 1.75rem 0 0.125rem;
  font-family: var(--display);
  font-size: 1.375rem;
  font-weight: 500;
  letter-spacing: -0.005em;
}

/* Location and dates. */
.resume h3 + p {
  margin: 0 0 0.875rem;
  font-family: var(--mono);
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  color: var(--muted);
}
.resume h3 + p strong { font-weight: 500; }

/* A run-in heading: the bold lead of a paragraph, set apart from its sentence. */
.resume p > strong:first-child {
  font-weight: 600;
  color: var(--ink);
}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.sitefoot {
  margin-top: 3.5rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--rule);
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem 1.25rem;
  font-family: var(--mono);
  font-size: 0.8125rem;
  color: var(--muted);
}

.sitefoot a {
  color: var(--muted);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-color: var(--rule);
}
.sitefoot a:hover { color: var(--accent); text-decoration-color: var(--accent); }

/* --------------------------------------------------------------------------
   Wider viewports
   -------------------------------------------------------------------------- */

@media (min-width: 48rem) {
  body { font-size: 1.3125rem; }

  .page {
    max-width: clamp(40rem, 46vw, 52rem);
    padding: 5rem 2rem 6.5rem;
  }

  .label { font-size: 0.9375rem; }

  /* home */
  .masthead { gap: 2rem; margin-bottom: 2.75rem; }
  .portrait { width: 168px; height: 168px; }
  .masthead h1 { font-size: 3.5rem; }
  .standfirst { margin-top: 0.625rem; }

  .lede { margin-bottom: 2.25rem; }

  .availability, .index { padding: 1.5rem 0 1.5625rem; }
  .flag { margin-bottom: 0.625rem; }

  .index { grid-template-columns: 9rem 1fr; column-gap: 1.5rem; }
  .index .n { font-size: 1.25rem; }
  .index .d { font-size: 1rem; }

  /* subpages */
  .sitehead { padding-bottom: 1rem; margin-bottom: 3rem; }
  .sitename { font-size: 1.75rem; }
  .sitehead nav { gap: 1.5rem; }
  .sitehead nav a { font-size: 0.875rem; }

  .pagetitle { font-size: 3rem; }
  .pagenote { font-size: 1.125rem; margin-bottom: 3rem; }

  /* projects */
  .project { padding-top: 2.25rem; margin-bottom: 3rem; }
  .project h2 { font-size: 2.25rem; }
  .project .meta { font-size: 0.875rem; margin-bottom: 1.25rem; }
  .project .links a { font-size: 0.875rem; }

  /* résumé */
  .resume h1 { font-size: 3rem; }
  .resume h1 + p { font-size: 0.9375rem; margin-bottom: 2.5rem; }
  .resume h2 { font-size: 0.9375rem; margin-top: 3rem; }
  .resume h3 { font-size: 1.625rem; margin-top: 2.25rem; }
  .resume h3 + p { font-size: 0.875rem; }

  .sitefoot { font-size: 0.875rem; margin-top: 4.5rem; }
}

/* --------------------------------------------------------------------------
   Print — for a browser printing this page

   This block used to produce resume.pdf, via headless Chrome. It no longer
   does: the downloadable PDF is baked from the same markdown outside this repo
   and copied into public/ by bin/build-resume. What is left here governs
   Cmd-P on the web page, which should still come out as a clean document --
   no site chrome, and the contact details the screen hides.
   -------------------------------------------------------------------------- */

@page {
  size: letter;
  margin: 0.4in 0.45in;
}

@media print {
  :root {
    --paper:  #FFFFFF;
    --ink:    #16211E;
    --muted:  #56625F;
    --rule:   #C9CFCC;
    --accent: #235A51;
    --frame:  #F0F0EC;
  }

  /* Every length below is in pt or em. rem would resolve against the 16px
     root and silently keep screen-sized spacing around 9pt type -- which is
     exactly how this first rendered at four pages instead of two. */

  /* 8.25pt over 1.25 is what fits this résumé's ~1,800 words onto two pages.
     Changing either number is very likely to spill it onto a third. */
  body {
    background: #fff;
    font-size: 8.25pt;
    line-height: 1.25;
  }

  .page {
    max-width: none;
    padding: 0;
  }

  /* The PDF is a standalone document: no navigation, no site chrome. */
  .sitehead,
  .sitefoot,
  .skip,
  .no-print { display: none !important; }

  .print-only { display: inline; }

  a {
    color: var(--ink);
    text-decoration: none;
  }

  .resume h1 {
    font-size: 15pt;
    line-height: 1.05;
    margin: 0 0 2pt;
  }

  .resume h1 + p {
    font-size: 7.25pt;
    letter-spacing: 0.03em;
    margin: 0 0 6pt;
    color: var(--muted);
  }

  .resume h2 {
    font-size: 7.25pt;
    letter-spacing: 0.12em;
    margin: 6.5pt 0 2.5pt;
    color: var(--accent);
    break-after: avoid;
  }

  .resume h3 {
    font-size: 10.5pt;
    line-height: 1.1;
    margin: 5pt 0 0;
    break-after: avoid;
  }

  .resume h3 + p {
    font-size: 7.25pt;
    letter-spacing: 0.03em;
    margin: 1pt 0 3pt;
    break-after: avoid;
  }

  .prose p { margin: 0 0 2pt; }

  .prose ul { margin: 0 0 2pt; padding-left: 9pt; }
  .prose li { margin-bottom: 0.5pt; break-inside: avoid; }
  .prose li::before { left: -9pt; top: 0.68em; width: 4.5pt; }

  /* Keep a body-of-work heading with at least the start of what follows it. */
  .resume p > strong:first-child { break-after: avoid; }

  /* Never strand a section heading or an employer at the foot of a page. */
  .resume h2, .resume h3 { break-inside: avoid; }
}
