/* ─────────────────────────────────────────────────────────
   Mekael Wesley-Rosa: portfolio
   One size (16px), two weights (400 / 600 for emphasis), two ink values.
   Hierarchy comes from position, spacing, ink, and weight. Nothing else.
   Underlines are reserved for links.
   ───────────────────────────────────────────────────────── */

:root {
  --ink: #000;
  --ink-50: rgba(0, 0, 0, 0.5);
  --rule: rgba(0, 0, 0, 0.13);
  --placeholder: rgba(0, 0, 0, 0.07);
  --bg: #fff;

  --u: 16px; /* baseline unit: all spacing is a multiple */
  --line: 24px; /* 16 × 1.5 */
  --measure: 34rem; /* ~62 characters */
  --gutter: 32px;
}

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family:
    "Inter",
    -apple-system,
    BlinkMacSystemFont,
    "Helvetica Neue",
    sans-serif;
  font-size: 16px;
  font-weight: 400;
  line-height: 1.5;
  font-feature-settings:
    "liga" 1,
    "kern" 1;
  -webkit-font-smoothing: antialiased;
}

::selection {
  background: var(--ink);
  color: var(--bg);
}

h1,
h2,
h3,
h4,
h5,
h6,
p,
ul,
ol,
li,
figure,
dl,
dd,
dt,
blockquote,
figcaption {
  margin: 0;
  font-size: inherit;
  font-weight: inherit;
}
ul,
ol {
  padding: 0;
  list-style: none;
}

a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
  transition: border-color 120ms ease;
}
a:hover {
  border-bottom-color: var(--ink);
}

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

.dim {
  color: var(--ink-50);
}
.num {
  font-variant-numeric: tabular-nums;
}
.bare {
  border-bottom: 0;
}

/* text-wrap: pretty removes widows without hand-kerning every line */
p,
li,
figcaption,
blockquote,
.balance {
  text-wrap: pretty;
}

/* ── Structure ──────────────────────────────────────────── */

.wrap {
  max-width: 1040px;
  margin: 0 auto;
  padding: 0 var(--gutter);
}

.rule {
  height: 1px;
  background: var(--rule);
  border: 0;
  margin: 0;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--bg);
  padding: var(--u);
  border: 1px solid var(--ink);
  z-index: 10;
}
.skip:focus {
  left: var(--gutter);
  top: var(--u);
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ── Masthead + nav ─────────────────────────────────────── */

.masthead {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--u) var(--gutter);
  align-items: baseline;
  padding: var(--u) 0;
}

.masthead-id {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--gutter);
}

.nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--gutter);
}
.nav a {
  border-bottom: 0;
  color: var(--ink-50);
}
.nav a:hover {
  color: var(--ink);
}
.nav a[aria-current="page"] {
  color: var(--ink);
}

.copy-email {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--rule);
  padding: 0;
  cursor: pointer;
  transition: border-color 120ms ease;
}
.copy-email:hover {
  border-bottom-color: var(--ink);
}

/* ── Page furniture ────────────────────────────────────── */

.statement {
  padding: calc(var(--u) * 5) 0 calc(var(--u) * 4);
  max-width: var(--measure);
}
.statement p + p {
  margin-top: var(--line);
}

.section-head {
  display: flex;
  justify-content: space-between;
  gap: var(--gutter);
  padding: var(--u) 0;
}

.section {
  padding: calc(var(--u) * 2) 0 calc(var(--u) * 5);
}

.prose {
  max-width: var(--measure);
}
.prose p + p,
.prose ul + p,
.prose p + ul {
  margin-top: var(--line);
}
.prose li {
  padding-left: var(--u);
  position: relative;
}
.prose li::before {
  content: "•";
  position: absolute;
  left: 0;
  color: var(--ink-50);
}
.prose li + li {
  margin-top: 8px;
}

/* ── Grey box placeholders ─────────────────────────────── */

.frame {
  aspect-ratio: 3 / 2;
  background: var(--placeholder);
  transition: opacity 160ms ease;
}
.frame--tall {
  aspect-ratio: 4 / 5;
}
.frame--wide {
  aspect-ratio: 16 / 9;
}
.frame--square {
  aspect-ratio: 1 / 1;
}
.frame--band {
  aspect-ratio: 21 / 9;
}

/* ── Work index ────────────────────────────────────────── */

.work {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: calc(var(--u) * 4) var(--gutter);
  padding: calc(var(--u) * 2) 0 calc(var(--u) * 6);
}

.piece {
  display: block;
  border-bottom: 0;
}
.piece .frame {
  margin-bottom: var(--u);
}
.piece:hover .frame {
  opacity: 0.82;
}
.piece:hover .piece-title {
  border-bottom-color: var(--ink);
}

.piece-title {
  display: inline;
  border-bottom: 1px solid transparent;
  transition: border-color 120ms ease;
}
.piece-line {
  margin-top: 2px;
}
/* Source label, above the title so it aligns across every card. */
.piece-meta {
  color: var(--ink-50);
  margin-bottom: 2px;
}

/* ── Archive list (secondary work) ─────────────────────── */

.archive {
  display: grid;
  padding: var(--u) 0 calc(var(--u) * 5);
}
.archive > * {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--u) var(--gutter);
  padding: 10px 0;
  border-bottom: 1px solid var(--rule);
  border-top: 0;
}
.archive > *:first-child {
  border-top: 1px solid var(--rule);
}
.archive a:hover {
  background: var(--placeholder);
}
.archive a:hover .archive-name {
  border-bottom-color: var(--ink);
}
.archive-name {
  border-bottom: 1px solid transparent;
  transition: border-color 120ms ease;
  justify-self: start;
}

/* ── Homepage testimonial ──────────────────────────────── */

.vouch {
  max-width: var(--measure);
  padding: calc(var(--u) * 2) 0;
}
.vouch p {
  text-indent: -0.42em;
}
.vouch footer {
  margin-top: 8px;
}

/* ── Range grid ────────────────────────────────────────── */

.range {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: calc(var(--u) * 2) var(--gutter);
  padding: calc(var(--u) * 2) 0 calc(var(--u) * 6);
}
.range .frame {
  margin-bottom: 12px;
}

/* ── Two-column data rows (resume, skills, facts) ──────── */

.rows {
  display: grid;
}
.row {
  display: grid;
  grid-template-columns: 12rem 1fr;
  gap: var(--u) var(--gutter);
  padding: var(--u) 0;
  border-top: 1px solid var(--rule);
}
.row:last-child {
  border-bottom: 1px solid var(--rule);
}
.row-body {
  max-width: var(--measure);
}
.row-body p + p,
.row-body ul + p,
.row-body p + ul {
  margin-top: var(--line);
}
.row-body li {
  padding-left: var(--u);
  position: relative;
}
.row-body li::before {
  content: "•";
  position: absolute;
  left: 0;
  color: var(--ink-50);
}
.row-body li + li {
  margin-top: 8px;
}

.facts {
  display: grid;
  gap: 12px;
  align-content: start;
}
.fact {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--u);
}

/* ── Case study ────────────────────────────────────────── */

.cs-head {
  padding: calc(var(--u) * 4) 0 calc(var(--u) * 2);
}
.cs-title {
  max-width: var(--measure);
}

.cs-meta {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--u) var(--gutter);
  padding: var(--u) 0 calc(var(--u) * 2);
}
.cs-meta div {
  display: grid;
  gap: 2px;
  align-content: start;
}

.cs-body {
  display: grid;
  grid-template-columns: 12rem 1fr;
  gap: var(--gutter);
  padding: calc(var(--u) * 3) 0;
  border-top: 1px solid var(--rule);
}
.cs-body h2 {
  color: var(--ink-50);
}
.cs-body > div:last-child {
  max-width: var(--measure);
}
.cs-body p + p,
.cs-body ul + p,
.cs-body p + ul,
.cs-body p + blockquote,
.cs-body blockquote + p {
  margin-top: var(--line);
}
.cs-body li {
  padding-left: var(--u);
  position: relative;
}
.cs-body li::before {
  content: "•";
  position: absolute;
  left: 0;
  color: var(--ink-50);
}
.cs-body li + li {
  margin-top: 8px;
}

blockquote {
  padding-left: var(--u);
  border-left: 1px solid var(--rule);
  color: var(--ink-50);
}

.plate {
  padding: calc(var(--u) * 2) 0;
}
.plate figcaption {
  margin-top: 12px;
}
.plate-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--u) var(--gutter);
}

.next {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--u) var(--gutter);
  padding: calc(var(--u) * 3) 0 calc(var(--u) * 4);
}

/* ── Quotes ────────────────────────────────────────────── */

.quotes {
  display: grid;
  gap: calc(var(--u) * 2);
  padding: calc(var(--u) * 2) 0 calc(var(--u) * 5);
}
.quote {
  max-width: var(--measure);
}
.quote p {
  text-indent: -0.42em;
  /* Full ink: the blockquote rule dims to --ink-50, but here the quote is the
     content, not an aside. The attribution below it stays dim. */
  color: var(--ink);
}
.quote footer {
  margin-top: 8px;
}

/* ── Footer ────────────────────────────────────────────── */

.foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--u) var(--gutter);
  padding: calc(var(--u) * 2) 0 calc(var(--u) * 4);
}
.foot-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--gutter);
}

/* ── Load reveal ───────────────────────────────────────── */

.reveal {
  opacity: 0;
  transform: translateY(6px);
}
.ready .reveal {
  opacity: 1;
  transform: none;
  transition:
    opacity 500ms ease,
    transform 500ms ease;
}
.ready .reveal:nth-child(2) {
  transition-delay: 60ms;
}
.ready .reveal:nth-child(3) {
  transition-delay: 120ms;
}

@media (prefers-reduced-motion: reduce) {
  .reveal,
  .ready .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
  a,
  button,
  .frame {
    transition: none !important;
  }
}

/* ── Narrow ────────────────────────────────────────────── */

@media (max-width: 880px) {
  .archive a {
    grid-template-columns: 1fr 10rem;
  }
  .archive a span:last-child {
    display: none;
  }
  .range {
    grid-template-columns: repeat(2, 1fr);
  }
  .cs-meta {
    grid-template-columns: repeat(2, 1fr);
  }
  .plate-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 640px) {
  :root {
    --gutter: 20px;
  }
  .masthead {
    grid-template-columns: 1fr;
    gap: 12px;
  }
  .work {
    grid-template-columns: 1fr;
    gap: calc(var(--u) * 3) 0;
  }
  .row,
  .cs-body {
    grid-template-columns: 1fr;
    gap: 12px;
  }
  .row {
    padding: var(--u) 0;
  }
  .cs-body {
    padding: calc(var(--u) * 2) 0;
  }
  .plate-grid {
    grid-template-columns: 1fr;
  }
  .statement {
    padding: calc(var(--u) * 3) 0 calc(var(--u) * 2);
  }
  .cs-head {
    padding: calc(var(--u) * 2) 0 var(--u);
  }
  .frame--tall,
  .frame--wide,
  .frame--square,
  .frame--band {
    aspect-ratio: 3 / 2;
  }
}

/* ── v2 additions: tighter case-study rhythm ───────────── */

.lede {
  max-width: var(--measure);
  padding: calc(var(--u) * 3) 0 calc(var(--u) * 2);
}
.lede p + p {
  margin-top: var(--u);
}

.facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: var(--u) var(--gutter);
  padding: var(--u) 0 calc(var(--u) * 2);
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}
.facts div {
  display: grid;
  gap: 2px;
}

.block {
  display: grid;
  grid-template-columns: 8rem 1fr;
  gap: var(--gutter);
  padding: calc(var(--u) * 2) 0;
  border-top: 1px solid var(--rule);
  max-width: 54rem;
}
.block > div > * + * {
  margin-top: var(--u);
}
.block ul {
  display: grid;
  gap: 6px;
  padding-left: 0;
}

@media (max-width: 40rem) {
  .block {
    grid-template-columns: 1fr;
    gap: var(--u);
  }
}

.more a {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--gutter);
  padding: 10px 0;
  border-bottom: 1px solid var(--rule);
  border-top: 0;
}
.more a:first-child {
  border-top: 1px solid var(--rule);
}
.more a:hover {
  background: var(--placeholder);
}

/* ── v2.1: summary-first architecture ──────────────────── */

.gist {
  max-width: var(--measure);
  padding: calc(var(--u) * 2) 0 calc(var(--u) * 3);
}
.gist p {
  text-indent: -0.05em;
}
.gist p + p {
  margin-top: calc(var(--u) * 0.75);
}
/* Emphasis is weight, never a rule. Underlines mean links and nothing else. */
strong {
  font-weight: 600;
}

/* Job title is the headline; the company line tucks under it as a subhead. */
.tight > .role + p {
  margin-top: 2px;
}

/* Role chapters: hierarchy from ink and spacing only, per the rule above. */
.chapter {
  color: var(--ink-50);
}
.tight > .chapter + ul {
  margin-top: 5px;
}

.tight ul {
  display: grid;
  gap: 5px;
  padding-left: 0;
}

/* Summary stats: value above label, on one shared baseline.
   Lives in a .block so it obeys the page's 8rem / 1fr rhythm. */
.stats {
  grid-column: 1 / -1; /* reclaim the 8rem label column */
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--u) var(--gutter);
  align-items: start;
}
.stats > div {
  display: grid;
  grid-template-rows: auto auto;
  gap: 2px;
}
.stats dd {
  grid-row: 1;
}
.stats dt {
  grid-row: 2;
}

/* Spec list: dim label stacked above the list it describes. */
.spec {
  display: grid;
  gap: 2px;
}
.spec dd + dt {
  margin-top: calc(var(--u) - 2px);
}

/* First block on a page: no rule above it. */
.block--open {
  border-top: 0;
}

@media (max-width: 40rem) {
  .stats {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* List markers. Same dim bullet the case-study pages use.
   The global reset strips list-style, so the marker is drawn here. */
.block li,
.tight li {
  padding-left: var(--u);
  position: relative;
}
.block li::before,
.tight li::before {
  content: "•";
  position: absolute;
  left: 0;
  color: var(--ink-50);
}
.tight > * + * {
  margin-top: var(--u);
}

/* ── One photo per section (About) ──────────────────────── */

/* A single image inside a body column. Caption sits under it,
   and .tight handles the space above. */
.shot figcaption {
  margin-top: 8px;
}

/* ── Pan-model case study: claim subheads + pull quotes ──
   Both hold the single-size, single-weight rule. Hierarchy
   comes from ink, rules, and space only. */

/* h3 inside a story block: a claim, not a label. */
.tight h3,
.block h3 {
  color: var(--ink);
}
.tight > h3 + p,
.block > h3 + p {
  margin-top: 4px;
}
.tight > * + h3,
.block > * + h3 {
  margin-top: calc(var(--u) * 1.5);
}

/* Pull quote — lifted verbatim from the body as a scan anchor.
   Reclaims the 8rem label column so it sits proud of the prose. */
.pull {
  grid-column: 1 / -1;
  max-width: 46rem;
  padding: calc(var(--u) * 1.5) 0;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  text-indent: -0.42em;
}
.block > .pull:first-child {
  border-top: 0;
}

/* Results list — the percentage block that closes a case study. */
.results {
  display: grid;
  gap: 6px;
}
.results div {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--gutter);
  padding: 8px 0;
  border-bottom: 1px solid var(--rule);
}
.results div:first-child {
  border-top: 1px solid var(--rule);
}

/* ── Diagrams ────────────────────────────────────────────
   Inline SVG, same palette as everything else: ink, 50%
   ink, the rule, the placeholder fill. No new colors, no
   new type sizes. Strokes inherit currentColor so the
   diagram tracks the text it explains. */

.diagram {
  grid-column: 1 / -1;
  max-width: 46rem;
  padding: calc(var(--u) * 1.5) 0 0;
}
.diagram svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
  color: var(--ink);
}
.diagram figcaption {
  color: var(--ink-50);
  margin-top: var(--u);
}

/* Parts of a diagram, so the SVG markup stays readable. */
.d-box {
  fill: none;
  stroke: currentColor;
  stroke-width: 1;
}
.d-fill {
  fill: var(--placeholder);
  stroke: none;
}
.d-line {
  stroke: currentColor;
  stroke-width: 1;
  fill: none;
}
.d-dim {
  stroke: var(--ink-50);
  fill: none;
  stroke-width: 1;
}
.d-dash {
  stroke: var(--ink-50);
  stroke-width: 1;
  fill: none;
  stroke-dasharray: 3 3;
}
.d-t {
  fill: currentColor;
  font-size: 13px;
}
.d-t--dim {
  fill: var(--ink-50);
  font-size: 13px;
}
.d-rule {
  stroke: var(--rule);
  stroke-width: 1;
}

/* ── Print / PDF export ─────────────────────────────────
   Cmd-P on resume.html, "Save as PDF", margins None.
   Produces the ATS-parseable copy that gets uploaded. */

@media print {
  @page {
    margin: 14mm 14mm;
  }
  html {
    font-size: 10.5pt;
  }
  body {
    background: #fff;
    color: #000;
  }

  /* Nav, skip link and footer links carry no meaning on paper. */
  header .nav,
  .skip,
  .foot-links,
  hr.rule {
    display: none !important;
  }

  /* Name and contact belong at the top of the page. */
  .masthead {
    padding: 0 0 6pt;
    border-bottom: 0.5pt solid #999;
  }

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

  /* No reveal animation, no faded ink on paper. */
  .reveal,
  .ready .reveal {
    opacity: 1 !important;
    transform: none !important;
  }
  .dim {
    color: #444;
  }

  a {
    border-bottom: 0;
    color: #000;
  }

  /* Never split a job or a bullet across pages. */
  .block,
  li,
  .spec > * {
    break-inside: avoid;
    page-break-inside: avoid;
  }
  .block {
    padding: 8pt 0;
  }
  h2,
  h3,
  h4,
  h5 {
    break-after: avoid;
    page-break-after: avoid;
  }

  /* Contact line, print only, so the PDF is self-contained. */
  .print-contact {
    display: block !important;
  }
}

.print-contact {
  display: none;
}
