/* davidfagg.com — components */
@import url("tokens.css");

/* base ------------------------------------------------------------------ */
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  font: 400 var(--step-1)/1.7 var(--font-text);
  background: var(--paper);
  color: var(--body);
  -webkit-font-smoothing: antialiased;
  letter-spacing: .002em;
}
img { max-width: 100%; height: auto; display: block; }
a { color: inherit; }
h1, h2, h3 { color: var(--ink); font-weight: 650; text-wrap: balance; }
.hero .sub, .standfirst, .prose p, .card .txt p, .about-teaser p, .contact p { text-wrap: pretty; }
.wrap { max-width: var(--max); margin-inline: auto; padding-inline: var(--gutter); }

/* a11y */
.skip {
  position: absolute; left: -999px; top: var(--s-3); z-index: 100;
  background: var(--ink); color: var(--paper); padding: var(--s-3) var(--s-5);
  border-radius: var(--r-s); font-size: var(--step-0);
}
.skip:focus { left: var(--s-3); }
/* the header is sticky at ~60px, so anchor targets must clear it */
#main, #work, #contact, :target { scroll-margin-top: 76px; }
/* the skip link moves focus into main; don't ring the whole page for it */
main[tabindex="-1"]:focus, main[tabindex="-1"]:focus-visible { outline: none; }
/* One ring, two grounds. The navy accent is invisible against the navy contact
   panel and the ink skip link (1:1), so those surfaces flip the ring to white.
   No border-radius override here — elements keep their own. */
:focus-visible { outline: 2px solid var(--focus-ring, var(--accent)); outline-offset: 3px; }
.contact .inner, .skip { --focus-ring: #fff; }

/* type helpers ----------------------------------------------------------- */
.caps {
  font-size: var(--step--2); font-weight: 560; letter-spacing: .17em;
  text-transform: uppercase; color: var(--mid);
}
.prose { max-width: var(--measure); }
.prose p + p { margin-top: var(--s-4); }

/* header ------------------------------------------------------------------ */
.site-head {
  position: sticky; top: 0; z-index: 40;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid transparent;
  transition: border-color var(--t-quick) ease;
}
.site-head.is-stuck { border-bottom-color: var(--line); }
.site-head .bar { display: flex; align-items: center; justify-content: space-between; padding-block: 1.05rem; }
.brand { font: 560 1.05rem/1 var(--font-text); color: var(--ink); text-decoration: none; letter-spacing: -.01em; }
.brand b { font-family: var(--font-display); font-weight: 600; }
.site-nav { display: flex; gap: clamp(1rem, 3vw, 2.1rem); font-size: var(--step-0); }
.site-nav a { text-decoration: none; color: var(--mid); transition: color var(--t-quick) ease; }
.site-nav a:hover { color: var(--ink); }
.site-nav a[aria-current] { color: var(--ink); font-weight: 600; }

/* hero ------------------------------------------------------------------ */
.hero { text-align: center; padding-block: clamp(4rem, 10vw, 7.5rem) var(--s-8); }
.hero .caps { color: var(--accent); }
.hero h1 {
  font-family: var(--font-display);
  font-size: var(--step-5); line-height: 1.06; font-weight: 720;
  letter-spacing: -.028em; max-width: 21ch; margin: var(--s-5) auto 0;
}
.hero em { font-style: normal; color: var(--accent); font-weight: 560; position: relative; }
.hero em::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -2px; height: 2px;
  border-radius: 2px; background: color-mix(in srgb, var(--accent) 45%, transparent);
  transform: scaleX(1); transform-origin: left;
}
@media (prefers-reduced-motion: no-preference) {
  .hero em::after { transform: scaleX(0); animation: draw .55s var(--ease-out) .75s forwards; }
}
@keyframes draw { to { transform: scaleX(1); } }
.hero .sub { max-width: 47ch; margin: var(--s-5) auto 0; font-size: var(--step-2); line-height: 1.6; color: var(--body); }
.hero .cta { margin-top: var(--s-6); display: flex; gap: var(--s-3); justify-content: center; flex-wrap: wrap; }

/* load-in stagger */
@media (prefers-reduced-motion: no-preference) {
  .hero > * { animation: rise .7s var(--ease-out) both; }
  .hero > *:nth-child(2) { animation-delay: .07s; }
  .hero > *:nth-child(3) { animation-delay: .14s; }
  .hero > *:nth-child(4) { animation-delay: .21s; }
}
@keyframes rise { from { opacity: 0; transform: translateY(14px); } }

/* buttons ------------------------------------------------------------------ */
.btn {
  display: inline-block; text-decoration: none; font-weight: 600; font-size: var(--step-0);
  padding: .82rem 1.5rem; border-radius: var(--r-s);
  transition: transform var(--t-quick) var(--ease-out), background var(--t-quick) ease, box-shadow var(--t-quick) ease;
}
.btn-primary { background: var(--accent); color: var(--paper); }
.btn-primary:hover { background: var(--accent-deep); transform: translateY(-1px); box-shadow: var(--shadow-card); }
.btn-ghost { border: 1.5px solid var(--line); color: var(--ink); background: transparent; }
.btn-ghost:hover { border-color: var(--ink); transform: translateY(-1px); }

/* employer strip ------------------------------------------------------------ */
.employers { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-6); justify-content: center; padding-block: var(--s-2) var(--s-8); }
.employers span { font-size: var(--step--1); font-weight: 560; letter-spacing: .12em; text-transform: uppercase; color: var(--mid); }

/* hero image band ----------------------------------------------------------- */
.photo-band { padding-bottom: var(--s-8); }
.photo-band figure { position: relative; }
.photo-band img { border-radius: var(--r-m); box-shadow: var(--shadow-card); }
.photo-band figcaption {
  margin-top: var(--s-3); font-size: var(--step--1); color: var(--mid); text-align: right;
}

/* stats ------------------------------------------------------------------ */
.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--s-4); padding-bottom: var(--s-9); }
.stat { background: var(--wash); border-radius: var(--r-m); padding: var(--s-6) var(--s-5); text-align: center; }
.stat b {
  display: block; font: 700 clamp(1.9rem, 3vw, 2.5rem)/1 var(--font-display);
  color: var(--ink); letter-spacing: -.03em; font-variant-numeric: tabular-nums;
}
.stat > span { display: block; margin-top: var(--s-3); font-size: var(--step--1); line-height: 1.55; color: var(--mid); }
.stats .reveal:nth-child(2) { transition-delay: 90ms; }
.stats .reveal:nth-child(3) { transition-delay: 180ms; }
.stats .reveal:nth-child(4) { transition-delay: 270ms; }

/* work cards ------------------------------------------------------------------ */
.work { padding-bottom: var(--s-8); }
.work-head { text-align: center; margin-bottom: var(--s-7); }
/* drawn rules, not em-dash characters — screen readers announce CSS content */
.work-head .caps::before, .work-head .caps::after {
  content: ""; display: inline-block; width: 1.5rem; height: 1px;
  background: var(--line); vertical-align: middle; margin-inline: var(--s-3);
}
.card {
  display: grid; grid-template-columns: 1fr 1fr; align-items: stretch;
  background: #fff; border: 1px solid var(--line); border-radius: var(--r-m);
  overflow: hidden; text-decoration: none; margin-bottom: var(--s-5);
  transition: transform var(--t-move) var(--ease-out), box-shadow var(--t-move) var(--ease-out);
}
.card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lift); }
.card .txt { padding: clamp(1.6rem, 3.4vw, 2.8rem); align-self: center; }
.card h3 { font-family: var(--font-display); font-size: var(--step-3); font-weight: 680; letter-spacing: -.022em; line-height: 1.18; margin-block: var(--s-3) var(--s-3); }
.card p { font-size: var(--step-0); color: var(--body); }
.card .go { display: inline-block; margin-top: var(--s-4); font-weight: 600; font-size: var(--step-0); color: var(--accent); }
.card .go::after { content: " →"; transition: transform var(--t-quick) var(--ease-out); display: inline-block; }
.card:hover .go::after { transform: translateX(4px); }
.card .pic { position: relative; overflow: hidden; background: var(--wash); min-height: 280px; }
.card .pic img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: transform .8s var(--ease-out); }
.card:hover .pic img { transform: scale(1.025); }
.card:nth-of-type(even) .pic { order: -1; }
/* the one card whose artefact is drawn rather than photographed */
.card .pic.drawn { display: flex; align-items: center; background: #fff; padding: clamp(1.4rem, 3vw, 2.2rem); }
.card .pic.drawn svg { width: 100%; height: auto; font-family: var(--font-text); }

/* about teaser ------------------------------------------------------------------ */
.about-teaser { text-align: center; padding-block: var(--s-9); border-top: 1px solid var(--line); }
.about-teaser .avatar {
  width: 108px; height: 108px; border-radius: 50%; object-fit: cover;
  margin: 0 auto var(--s-5); border: 1px solid var(--line);
}
.about-teaser h2 { font-family: var(--font-display); font-size: var(--step-4); font-weight: 720; letter-spacing: -.025em; max-width: 24ch; margin-inline: auto; }
.about-teaser p { max-width: 54ch; margin: var(--s-5) auto 0; }
.about-teaser .more { display: inline-block; margin-top: var(--s-5); font-weight: 600; color: var(--accent); text-decoration: none; border-bottom: 1.5px solid var(--accent-tint); transition: border-color var(--t-quick) ease; }
.about-teaser .more:hover { border-color: var(--accent); }

/* contact ------------------------------------------------------------------ */
.contact { padding-bottom: var(--s-9); }
.contact .inner {
  background: var(--accent); color: var(--accent-tint);
  border-radius: var(--r-m); text-align: center;
  padding: clamp(3rem, 7vw, 5rem) var(--s-6);
}
.contact h2 { color: #fff; font-family: var(--font-display); font-weight: 700; font-size: var(--step-4); letter-spacing: -.025em; max-width: 24ch; margin-inline: auto; }
.contact p { max-width: 46ch; margin: var(--s-4) auto 0; }
.contact .lines { margin-top: var(--s-6); display: flex; gap: var(--s-4); justify-content: center; flex-wrap: wrap; }
.contact .btn-light { background: var(--paper); color: var(--ink); }
.contact .btn-light:hover { background: #fff; transform: translateY(-1px); }
.contact .btn-line { border: 1.5px solid color-mix(in srgb, #fff 40%, transparent); color: #fff; }
.contact .btn-line:hover { border-color: #fff; transform: translateY(-1px); }

/* footer ------------------------------------------------------------------ */
.site-foot { border-top: 1px solid var(--line); padding-block: var(--s-6) var(--s-8); }
.site-foot .row { display: flex; justify-content: space-between; gap: var(--s-4); flex-wrap: wrap; font-size: var(--step--1); color: var(--mid); }
.site-foot a { color: var(--mid); }
.site-foot a:hover { color: var(--ink); }

/* case study ------------------------------------------------------------------ */
.case-head { text-align: center; padding-block: clamp(3.5rem, 8vw, 6rem) var(--s-7); }
.case-head .caps { color: var(--accent); }
.case-head h1 { font-family: var(--font-display); font-size: var(--step-5); font-weight: 720; letter-spacing: -.028em; line-height: 1.06; max-width: 18ch; margin: var(--s-4) auto 0; }
.case-head .standfirst { max-width: 52ch; margin: var(--s-5) auto 0; font-size: var(--step-2); line-height: 1.6; }
@media (prefers-reduced-motion: no-preference) {
  .case-head > * { animation: rise .7s var(--ease-out) both; }
  .case-head > *:nth-child(2) { animation-delay: .07s; }
  .case-head > *:nth-child(3) { animation-delay: .14s; }
}

.outcomes { padding-block: var(--s-7); }
.case-prose { padding-block: var(--s-6) var(--s-8); }
.case-prose .prose { margin-inline: auto; }
.case-prose h2 { font-family: var(--font-display); font-size: var(--step-3); font-weight: 680; letter-spacing: -.02em; margin: var(--s-8) 0 var(--s-4); }
.case-prose h2:first-child { margin-top: 0; }
.case-prose h2::before { content: ""; display: block; width: 2rem; height: 3px; background: var(--accent); border-radius: 2px; margin-bottom: var(--s-4); transform-origin: left; }
@media (prefers-reduced-motion: no-preference) {
  .case-prose h2::before { transform: scaleX(0); transition: transform .5s var(--ease-out) .1s; }
  .case-prose h2.is-in::before { transform: scaleX(1); }
}

/* case study: one lead section, the rest grouped as support ---------------- */
.case-lead h2 { font-size: var(--step-4); letter-spacing: -.025em; }
.case-lead .lead-in { font-size: var(--step-2); line-height: 1.6; color: var(--body); }
.case-support { border-top: 1px solid var(--line); margin-top: var(--s-8); padding-top: var(--s-5); }
.case-support h3 {
  font-family: var(--font-display); font-size: var(--step-1); font-weight: 650;
  letter-spacing: -.012em; color: var(--ink); margin: var(--s-6) 0 var(--s-2);
}
.case-support h3:first-of-type { margin-top: var(--s-4); }

/* authored diagrams — drawn here, no client imagery ------------------------ */
.diagram .d-frame {
  background: var(--wash); border: 1px solid var(--line); border-radius: var(--r-m);
  padding: var(--s-6) var(--s-5);
  overflow-x: auto;
}
/* SVG text scales with the viewBox, so a full-width drawing squeezed into a
   phone renders its labels at ~4px. Hold a floor and let the frame scroll. */
.diagram svg { display: block; width: 100%; height: auto; min-width: 820px; font-family: var(--font-text); }
@media (max-width: 700px) { .diagram .d-frame { padding: var(--s-5) var(--s-4); } }
.d-label { font-size: 15px; fill: var(--body); }
.d-key { font-size: 12px; font-weight: 560; letter-spacing: .14em; text-transform: uppercase; fill: var(--mid); }
.d-value { font-size: 19px; font-weight: 650; fill: var(--ink); font-family: var(--font-display); font-variant-numeric: tabular-nums; }
.d-note { font-size: 13.5px; fill: var(--mid); }
.d-rule { stroke: color-mix(in srgb, var(--ink) 16%, transparent); stroke-width: 1; }
.d-bar-was { fill: color-mix(in srgb, var(--accent) 12%, transparent); stroke: color-mix(in srgb, var(--accent) 40%, transparent); }
.d-bar-now { fill: var(--accent); }
.d-box { fill: #fff; stroke: var(--line); stroke-width: 1; }
.d-box-key { fill: color-mix(in srgb, var(--accent) 8%, transparent); stroke: var(--accent); stroke-width: 1.5; }
.d-arrow { stroke: color-mix(in srgb, var(--accent) 55%, transparent); stroke-width: 1.5; fill: none; }

/* app shots band */
.shots { padding-block: var(--s-5) var(--s-6); }
.shots .row {
  display: grid; grid-template-columns: repeat(5, 1fr); gap: var(--s-4);
}
.shots img { border-radius: var(--r-m); border: 1px solid var(--line); box-shadow: var(--shadow-card); }
.shots figcaption { margin-top: var(--s-4); text-align: center; font-size: var(--step--1); color: var(--mid); }
.shots figcaption a { color: var(--mid); }

.nda {
  max-width: var(--measure); margin: var(--s-6) auto 0;
  background: var(--wash); border-radius: var(--r-m);
  padding: var(--s-5) var(--s-6); font-size: var(--step--1); color: var(--mid); font-style: italic;
}
.case-next { text-align: center; padding-block: var(--s-4) var(--s-9); }
.case-next a { font-weight: 600; color: var(--accent); text-decoration: none; font-size: var(--step-0); }
.case-next a:hover { text-decoration: underline; text-underline-offset: 4px; }

/* case video ------------------------------------------------------------------ */
.case-video { margin: var(--s-6) 0 var(--s-7); }
.case-video video { width: 100%; height: auto; border-radius: var(--r-m); border: 1px solid var(--line); background: var(--ink); display: block; }
.case-video figcaption { margin-top: var(--s-3); font-size: var(--step--1); color: var(--mid); }

/* case figures ------------------------------------------------------------------ */
.case-prose > figure { margin: var(--s-6) 0 var(--s-7); }
.case-prose figure img, .fig-grid img { border-radius: var(--r-m); border: 1px solid var(--line); width: 100%; height: auto; }
.case-prose figcaption { margin-top: var(--s-3); font-size: var(--step--1); color: var(--mid); }
.fig-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-4); }
.fig-grid.cols-3 { grid-template-columns: repeat(3, 1fr); }
.stats.cols-3 { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 700px) {
  .fig-grid, .fig-grid.cols-3 { grid-template-columns: 1fr; }
  .stats.cols-3 { grid-template-columns: 1fr 1fr; }
}

/* about page ------------------------------------------------------------------ */
.about-head { text-align: center; padding-block: clamp(3.5rem, 8vw, 6rem) var(--s-6); }
.about-head .avatar { width: 148px; height: 148px; border-radius: 50%; object-fit: cover; margin: 0 auto var(--s-6); border: 1px solid var(--line); }
.about-head h1 { font-family: var(--font-display); font-size: var(--step-5); font-weight: 720; letter-spacing: -.028em; line-height: 1.06; }
.about-head .standfirst { max-width: 52ch; margin: var(--s-5) auto 0; font-size: var(--step-2); line-height: 1.6; }
.about-body { padding-block: var(--s-6) var(--s-8); }
.about-body .prose { margin-inline: auto; }
.about-body h2 { font-family: var(--font-display); font-size: var(--step-3); font-weight: 680; letter-spacing: -.02em; margin: var(--s-8) 0 var(--s-5); }
.about-body h2::before { content: ""; display: block; width: 2rem; height: 3px; background: var(--accent); border-radius: 2px; margin-bottom: var(--s-4); }
.timeline { max-width: var(--measure); margin-inline: auto; }
.timeline .row { display: grid; grid-template-columns: 150px 1fr; gap: var(--s-4); padding-block: var(--s-4); border-top: 1px solid var(--line); }
.timeline .row:last-child { border-bottom: 1px solid var(--line); }
.timeline .when { font-size: var(--step--1); color: var(--mid); padding-top: 3px; }
.timeline .what b { display: block; color: var(--ink); font-weight: 600; font-size: var(--step-0); }
.timeline .what span { display: block; font-size: var(--step--1); color: var(--mid); margin-top: 2px; }
.pill-list { display: flex; flex-wrap: wrap; gap: var(--s-2); max-width: var(--measure); margin-inline: auto; padding: 0; list-style: none; }
.pill-list li { font-size: var(--step--1); color: var(--body); background: var(--wash); border-radius: var(--r-s); padding: 8px 14px; }
@media (max-width: 560px) { .timeline .row { grid-template-columns: 1fr; gap: 4px; } }

/* scroll reveal ------------------------------------------------------------------ */
.reveal { opacity: 0; transform: translateY(18px); transition: opacity .65s var(--ease-out), transform .65s var(--ease-out); }
.reveal.is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
  html { scroll-behavior: auto; }
}

/* responsive ------------------------------------------------------------------ */
@media (max-width: 880px) {
  .stats { grid-template-columns: repeat(2, 1fr); }
  .card { grid-template-columns: 1fr; }
  .card .pic, .card:nth-of-type(even) .pic { order: -1; min-height: 220px; }
  .shots .row { grid-template-columns: repeat(5, 72%); overflow-x: auto; scroll-snap-type: x mandatory; padding-bottom: var(--s-3); }
  .shots .row > * { scroll-snap-align: center; }
}
@media (max-width: 560px) {
  .site-nav { gap: 1rem; }
  .stats { grid-template-columns: 1fr 1fr; gap: var(--s-3); }
}
