/* ==========================================================================
   Base — reset, typography, and the content blocks shared across slides.
   Layout/deck behaviour lives in deck.css.
   ========================================================================== */

@import url("https://fonts.googleapis.com/css2?family=Newsreader:ital,opsz,wght@0,6..72,400;0,6..72,500;0,6..72,600;1,6..72,400;1,6..72,500&family=Inter:wght@400;500;600&display=swap");

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

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: var(--lh-normal);
  -webkit-font-smoothing: antialiased;
}

img {
  max-width: 100%;
  display: block;
}

h1, h2, h3 {
  font-family: var(--font-serif);
  font-weight: 500;
  line-height: var(--lh-tight);
  margin: 0;
}

p {
  margin: 0;
}

a {
  color: var(--color-link);
  text-decoration-thickness: 1.5px;
  text-underline-offset: 0.2em;
  transition: color var(--dur-fast) var(--ease);
}

a:hover {
  color: var(--color-link-hover);
}

ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

button {
  font-family: inherit;
  cursor: pointer;
}

/* One visible focus indicator for every interactive element, rather than
   relying on each browser's default against a custom-styled control. */
:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
  border-radius: 2px;
}

/* The AH monogram in front of the name. Built from live text rather than the
   favicon SVG: at 24px the SVG's traced letters fall between pixels and look
   soft on non-Retina screens, while real text gets the browser's pixel
   snapping and stays as crisp as the name beside it. */
.wordmark__mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 0.3125rem;
  background: var(--color-text);
  color: var(--color-bg);
  font-family: var(--font-sans);
  font-size: 0.6875rem;
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0;
}

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

.container {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 var(--space-5);
  width: 100%;
}

.container--wide {
  max-width: var(--max-width-wide);
}

.section__head {
  margin-bottom: var(--space-7);
}

.section__head h2 {
  font-size: var(--fs-h1);
}

.eyebrow {
  display: block;
  font-size: var(--fs-tiny);
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: var(--space-3);
}

.lead {
  font-size: var(--fs-lead);
  color: var(--color-text-muted);
  max-width: 58ch;
  font-family: var(--font-serif);
  line-height: var(--lh-snug);
}

.lead a {
  font-weight: 500;
}

/* ---- Intro: text beside portrait ---- */

.intro {
  display: grid;
  /* The photo grows with the screen: 16.25rem (260px) on small laptops, up to
     20rem (320px) from about 1280px wide, where it matches the text height. */
  grid-template-columns: minmax(0, 1fr) clamp(16.25rem, 25vw, 20rem);
  gap: var(--space-9);
  align-items: center;
}

/* Horizontal link card — a whole row is the target, arrow signals where it goes. */

.card-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  padding: var(--space-4) var(--space-5);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-bg-light);
  color: var(--color-text);
  text-decoration: none;
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}

/* Stays light on hover; the border deepening and the arrow nudging carry it. */
.card-link:hover {
  color: var(--color-text);
  border-color: var(--color-border-strong);
}

.card-link:active {
  background: var(--color-bg);
}

.card-link__text {
  font-weight: 500;
}

.card-link__arrow {
  color: var(--color-accent);
  transition: transform var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}

.card-link:hover .card-link__arrow {
  color: var(--color-control-active);
  transform: translateX(0.25rem);
}

@media (prefers-reduced-motion: reduce) {
  .card-link__arrow {
    transition: none;
  }
  .card-link:hover .card-link__arrow {
    transform: none;
  }
}

.intro__photo {
  margin: 0;
  aspect-ratio: 1;
  border-radius: 50%;
  overflow: hidden;
  background: var(--color-bg-raised);
}

/* The file is already cropped to head and shoulders, at the full resolution
   the original allows (584px square, shown at up to 320px). The full-length
   original is in the git history (v0.9) if the framing ever needs redoing. */
.intro__photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

@media (max-width: 53.75em) {
  .intro {
    grid-template-columns: 1fr;
    gap: var(--space-5);
  }

  .intro__photo {
    order: -1;
    width: 6.5rem;
  }
}

/* ---- Experience list ---- */

.job {
  display: grid;
  /* Wide enough for the full company history on one line. */
  grid-template-columns: 20rem 1fr;
  gap: var(--space-5) var(--space-7);
  padding: var(--space-6) 0;
  border-top: var(--border-width) solid var(--color-border);
}

.job:first-child {
  border-top: none;
  padding-top: 0;
}

/* Company (or school) leads in the text colour and bold; the dates sit under
   it, lighter and muted. */
.job__meta {
  color: var(--color-text);
  font-size: var(--fs-small);
  font-weight: 600;
}

.job__period {
  display: block;
  margin-top: var(--space-1);
  color: var(--color-text-muted);
  font-weight: 400;
}

.job__title {
  font-size: var(--fs-h3);
  margin-bottom: var(--space-2);
}

.job__title span {
  color: var(--color-text-muted);
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  font-weight: 400;
}

.job__desc {
  max-width: 62ch;
}

@media (max-width: 40em) {
  .job {
    grid-template-columns: 1fr;
    gap: var(--space-2);
  }
}

/* ---- Work, grouped by category ---- */

.work-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-5);
}

/* Each category spans three rows of the parent grid and shares them through
   subgrid, so heading, description and list line up across columns however
   many lines each description wraps to, at any width or text size. */
.work-category {
  display: grid;
  grid-row: span 3;
  grid-template-rows: auto auto 1fr;
  grid-template-rows: subgrid;
  row-gap: 0;
  align-content: start;
}

.work-category h3 {
  font-size: var(--fs-h3);
  margin-bottom: var(--space-4);
  padding-bottom: var(--space-3);
  border-bottom: var(--border-width) solid var(--color-border);
}

.work-category__desc {
  color: var(--color-text-muted);
  font-size: var(--fs-small);
  margin-bottom: var(--space-5);
  text-wrap: pretty;
}

.work-item {
  padding: var(--space-3) 0;
  border-top: var(--border-width) dashed var(--color-border);
}

.work-item:first-of-type {
  border-top: none;
}

.work-item__link {
  display: block;
  color: var(--color-text);
  text-decoration: none;
}

.work-item__title {
  display: block;
  font-weight: 500;
  transition: color var(--dur-fast) var(--ease);
}

/* These all leave the site, so mark them as outbound. */
.work-item__title::after {
  content: " \2197";
  color: var(--color-text-muted);
  font-weight: 400;
}

.work-item__link:hover .work-item__title {
  color: var(--color-link);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.work-item__summary {
  display: block;
  color: var(--color-text-muted);
  font-size: var(--fs-small);
  margin-top: 0.125rem;
}

@media (max-width: 48.75em) {
  .work-grid {
    grid-template-columns: 1fr;
  }
}

/* ---- Community & mentoring ---- */

.community__lead {
  max-width: 66ch;
  margin-bottom: var(--space-4);
}

.community__lead:last-of-type {
  margin-bottom: var(--space-7);
}

/* Two-column reference list — used for talks and certifications alike. */

.list-block h3 {
  font-size: var(--fs-h3);
  margin-bottom: var(--space-4);
  padding-bottom: var(--space-3);
  border-bottom: var(--border-width) solid var(--color-border);
}

.list-block--spaced {
  margin-top: var(--space-7);
}

.list-block ul {
  columns: 2;
  column-gap: var(--space-8);
}

/* Separators sit on the bottom, not the top: with CSS columns a top border
   would also land on the first item of the second column, drawing a stray
   rule right under the heading. Every item keeps its line, including the
   last: CSS can only pick out the last item of the list, not of each column,
   so removing it left one column ending with a line and the other without. */
.list-item {
  break-inside: avoid;
  padding: var(--space-3) 0;
  border-bottom: var(--border-width) dashed var(--color-border);
}

/* Deliberately no :first-child padding reset. With CSS columns that selector
   means "first in the list", not "first in each column", so zeroing it there
   drops the second column 12px lower than the first. Every item keeps the
   same padding and the columns line up. */

.list-item__title {
  display: block;
  font-weight: 500;
}

/* Some entries link out to a recording or a write-up; the rest are plain text. */
.list-item__link {
  display: block;
  color: var(--color-text);
  text-decoration: none;
}

.list-item__link .list-item__title::after {
  content: " \2197";
  color: var(--color-text-muted);
  font-weight: 400;
}

.list-item__link:hover .list-item__title {
  color: var(--color-link);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.list-item__meta {
  display: block;
  color: var(--color-text-muted);
  font-size: var(--fs-small);
  margin-top: 0.125rem;
}

@media (max-width: 48.75em) {
  .list-block ul {
    columns: 1;
  }
}

/* ---- Quotes ---- */

/* Set as pull quotes rather than cards: a single short excerpt doesn't need a
   container to hold it, and the boxes were the heaviest thing on the page. */
/* Fixed at two rather than auto-fit: at the container's full width auto-fit
   would slip to three ~300px columns, which is too narrow a measure for serif
   quotes and leaves a ragged 3+1 row on four. Two keeps the rhythm at any
   count. align-items: start so each rule matches its own quote, not the row. */
.quote-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  align-items: start;
  gap: var(--space-8) var(--space-7);
}

@media (max-width: 45em) {
  .quote-grid {
    grid-template-columns: 1fr;
  }
}

.quote {
  margin: 0;
  padding-left: var(--space-5);
  border-left: 2px solid var(--color-border);
}

.quote blockquote {
  margin: 0 0 var(--space-4);
  font-family: var(--font-serif);
  font-size: var(--fs-lead);
  line-height: var(--lh-snug);
  text-wrap: pretty;
}

.quote blockquote p {
  margin: 0;
}

/* Excerpts joined across an elision get a gap, not a full paragraph break. */
.quote blockquote p + p {
  margin-top: var(--space-3);
}

.quote__name {
  display: block;
  font-weight: 600;
  font-size: var(--fs-small);
}

.quote__role {
  display: block;
  color: var(--color-text-muted);
  font-size: var(--fs-tiny);
  margin-top: 0.125rem;
}

/* ---- Contact ---- */

.contact h2 {
  font-size: var(--fs-h1);
  margin-bottom: var(--space-4);
  max-width: 18ch;
}

.contact__lead {
  color: var(--color-text-muted);
  font-size: var(--fs-lead);
  font-family: var(--font-serif);
  max-width: 46ch;
  margin-bottom: var(--space-6);
}

.contact__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-6);
}

.contact__links a {
  font-size: var(--fs-h3);
  font-family: var(--font-serif);
  text-decoration: none;
  border-bottom: 1px solid var(--color-border);
  padding-bottom: 0.125rem;
}

.contact__links a:hover {
  border-color: var(--color-link);
}

/* For readers who want more than the portfolio, ahead of the contact links. */
.contact__more {
  margin-bottom: var(--space-7);
  max-width: 25rem;
}

/* ---- Scroll reveal ---- */

/* Scoped to .js (set by an inline script in the head) so that without
   JavaScript the content is simply visible rather than stuck at opacity 0. */
.js .reveal {
  opacity: 0;
  transform: translateY(1rem);
  transition: opacity var(--dur-slow) var(--ease), transform var(--dur-slow) var(--ease);
}

.js .reveal.is-visible {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .deck {
    scroll-behavior: auto;
  }
  .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
}
