@font-face { font-family: 'Fraunces'; font-style: normal; font-weight: 300 600; font-display: swap; src: url(fonts/fraunces-latin.woff2) format('woff2'); }
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 300 600; font-display: swap; src: url(fonts/inter-latin.woff2) format('woff2'); }
@font-face { font-family: 'JetBrains Mono'; font-style: normal; font-weight: 400; font-display: swap; src: url(fonts/jetbrains-mono-latin-400.woff2) format('woff2'); }
@font-face { font-family: 'JetBrains Mono'; font-style: normal; font-weight: 500; font-display: swap; src: url(fonts/jetbrains-mono-latin-500.woff2) format('woff2'); }
:root {
--bg:         oklch(8% 0.002 260);
--bg-card:    oklch(12% 0.003 260);
--bg-card-h:  oklch(16% 0.004 260);
--surface:    oklch(14% 0.003 260);
--fg:         oklch(96% 0.002 260);
--fg-bright:  oklch(99% 0 0);
--muted:      oklch(58% 0.004 260);
--faint:      oklch(60% 0.003 260);
--border:     oklch(28% 0.003 260);
--border-hi:  oklch(50% 0.004 260);
--accent:     oklch(96% 0.002 260);
--font-display: 'Fraunces', 'Iowan Old Style', Georgia, serif;
--font-body:    'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
--font-mono:    'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;
--fs-mega:  clamp(48px, 8vw, 88px);
--fs-h1:    clamp(36px, 5vw, 56px);
--fs-h2:    clamp(24px, 3vw, 36px);
--fs-h3:    18px;
--fs-lead:  17px;
--fs-body:  15px;
--fs-meta:  12px;
--fs-micro: 11px;
--gap-xs: 8px;
--gap-sm: 12px;
--gap-md: 20px;
--gap-lg: 32px;
--gap-xl: 56px;
--gap-2xl: 96px;
--container: 960px;
--gutter: 32px;
--radius: 12px;
--radius-lg: 16px;
}
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-snap-type: y proximity; scrollbar-width: none; -ms-overflow-style: none; overflow-x: hidden; }
html::-webkit-scrollbar { display: none; width: 0; }
body { scroll-snap-type: y proximity; scrollbar-width: none; overflow-x: hidden; }
body::-webkit-scrollbar { display: none; width: 0; }
body {
margin: 0;
background: var(--bg);
color: var(--fg);
font-family: var(--font-body);
font-size: var(--fs-body);
line-height: 1.6;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; cursor: pointer; }
p { text-wrap: pretty; margin: 0; }
h1, h2, h3 { text-wrap: balance; margin: 0; }
.container { max-width: var(--container); margin-inline: auto; padding-inline: var(--gutter); }
.section { min-height: 100vh; display: flex; flex-direction: column; justify-content: center; padding-block: clamp(48px, 10vh, 96px); scroll-snap-align: start; scroll-snap-stop: always; }
.stack { display: flex; flex-direction: column; }
.stack > * + * { margin-top: var(--gap-md); }
.row { display: flex; align-items: center; gap: var(--gap-md); }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: var(--gap-md); }
h1 { font-family: var(--font-display); font-size: var(--fs-mega); line-height: 1; letter-spacing: -0.03em; font-weight: 400; }
h2 { font-family: var(--font-display); font-size: var(--fs-h2); line-height: 1.15; letter-spacing: -0.02em; font-weight: 400; }
h3 { font-family: var(--font-body); font-size: var(--fs-h3); font-weight: 500; letter-spacing: -0.005em; }
.lead { font-size: var(--fs-lead); line-height: 1.65; color: var(--muted); max-width: 48ch; }
.eyebrow {
font-family: var(--font-mono); font-size: var(--fs-micro);
letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted);
margin: 0 0 var(--gap-md);
}
.meta { font-family: var(--font-mono); font-size: var(--fs-meta); color: var(--muted); }
.num  { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.hr { border: 0; border-top: 1px solid var(--border); margin: 0; }
.hr-thin { border: 0; border-top: 1px solid var(--border); width: 48px; margin: 0; }
.mobile-nav { display: none; }
/* ─── nav ──────────────────────────────────────────────────────── */
.topnav {
position: fixed; top: 0; right: 0; bottom: 0; z-index: 100;
width: 1px; background: var(--border);
display: flex; flex-direction: column; align-items: center;
}
.topnav-inner {
display: flex; flex-direction: column; align-items: flex-end;
gap: 20px; padding: 0 16px 0 0;
position: absolute; right: 0; top: 50%; transform: translateY(-50%);
white-space: nowrap;
}
.logo {
position: fixed; top: 20px; left: 24px; z-index: 101;
font-family: var(--font-display); font-size: 14px; font-weight: 400;
letter-spacing: 0.02em; color: var(--faint);
margin: 0;
}
.topnav nav { display: flex; flex-direction: column; gap: 14px; }
.topnav nav a {
font-family: var(--font-mono); font-size: 13px;
letter-spacing: 0.12em; text-transform: uppercase;
color: var(--faint); transition: color 0.2s;
display: flex; align-items: center; gap: 10px; flex-direction: row-reverse;
}
.topnav nav a::before {
content: ''; width: 8px; height: 1px; background: var(--faint);
transition: width 0.2s, background 0.2s;
}
.topnav nav a:hover { color: var(--fg); }
.topnav nav a:hover::before { width: 16px; background: var(--fg); }
.topnav nav a.active { color: var(--fg); }
.topnav nav a.active::before { width: 16px; background: var(--fg); }
.nav-cta {
position: fixed; bottom: 24px; right: 24px; z-index: 101;
font-family: var(--font-mono); font-size: 13px;
letter-spacing: 0.1em; text-transform: uppercase;
color: var(--fg); display: inline-flex; align-items: center; gap: 8px;
padding: 10px 20px; border: 1px solid var(--border-hi); border-radius: 100px;
background: oklch(14% 0.003 260 / 0.8); backdrop-filter: blur(12px) saturate(1.3);
transition: color 0.2s, border-color 0.2s, background 0.2s;
}
.nav-cta:hover { color: var(--fg-bright); border-color: var(--fg); background: oklch(18% 0.004 260 / 0.9); }
@media (max-width: 720px) {
.topnav { display: none; }
.mobile-nav {
position: fixed; bottom: 0; left: 0; right: 0; z-index: 100;
display: flex; justify-content: space-around; align-items: center;
background: oklch(10% 0.003 260 / 0.92); backdrop-filter: blur(16px) saturate(1.4);
border-top: 1px solid var(--border);
padding: 16px 0 calc(16px + env(safe-area-inset-bottom));
}
.mobile-nav a {
font-family: var(--font-mono); font-size: 11px;
letter-spacing: 0.08em; text-transform: uppercase;
color: var(--faint); transition: color 0.2s;
padding: 14px 16px; white-space: nowrap;
}
.mobile-nav a.active { color: var(--fg); }
.mobile-nav a:hover { color: var(--muted); }
.nav-cta { top: 16px; right: 16px; bottom: auto; font-size: 11px; padding: 8px 16px; }
}
/* ─── hero ─────────────────────────────────────────────────────── */
.hero { text-align: center; position: relative; overflow: hidden; }
.hero::before {
content: ''; position: absolute; inset: -50%; z-index: 0; pointer-events: none;
background:
radial-gradient(circle at 30% 40%, oklch(16% 0.015 260 / 0.5), transparent 50%),
radial-gradient(circle at 70% 60%, oklch(14% 0.01 280 / 0.4), transparent 50%);
animation: drift 12s ease-in-out infinite alternate;
}
@keyframes drift {
0% { transform: translate(0, 0) scale(1); }
50% { transform: translate(5%, -3%) scale(1.1); }
100% { transform: translate(-3%, 4%) scale(1.05); }
}
.hero > * { position: relative; z-index: 1; }
.hero .greeting {
font-family: var(--font-mono); font-size: var(--fs-micro);
letter-spacing: 0.18em; text-transform: uppercase;
color: var(--muted); margin-bottom: var(--gap-md);
min-height: 1.8em; display: flex; align-items: center; justify-content: center;
}
.hero h1 { color: var(--fg-bright); margin-bottom: var(--gap-md); }
.hero .hr-thin { margin-inline: auto; margin-bottom: var(--gap-md); }
.hero .lead { margin-inline: auto; margin-bottom: var(--gap-lg); }
.hero-cta {
display: inline-flex; align-items: center; gap: 10px;
font-family: var(--font-mono); font-size: 16px;
letter-spacing: 0.14em; text-transform: uppercase;
color: var(--fg); transition: color 0.2s;
}
.hero-cta::after { content: '→'; transition: transform 0.2s; }
.hero-cta:hover { color: var(--muted); }
.hero-cta:hover::after { transform: translateX(4px); }
/* ─── featured projects ────────────────────────────────────────── */
.projects-head {
display: flex; align-items: center; justify-content: space-between;
margin-bottom: var(--gap-lg); gap: var(--gap-md);
}
.projects-head .label {
font-family: var(--font-mono); font-size: var(--fs-micro);
letter-spacing: 0.16em; text-transform: uppercase; color: var(--fg);
}
.projects-head .view-all {
font-family: var(--font-mono); font-size: var(--fs-micro);
letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted);
transition: color 0.2s;
}
.projects-head .view-all:hover { color: var(--fg); }
.project-grid {
display: flex; gap: var(--gap-md);
overflow-x: auto; overflow-y: visible;
scroll-snap-type: x mandatory;
-webkit-overflow-scrolling: touch;
padding-bottom: 8px; margin: 0 calc(var(--gutter) * -1);
padding-inline: var(--gutter);
scrollbar-width: none; -ms-overflow-style: none;
}
.project-grid::-webkit-scrollbar { display: none; }
.project-card {
flex: 0 0 min(900px, 96vw); scroll-snap-align: center;
}
@media (max-width: 760px) {
.project-card { flex-basis: 92vw; }
}
.project-card {
display: flex; flex-direction: column;
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
overflow: visible;
transition: background 0.3s, border-color 0.3s, transform 0.3s;
}
.project-card:hover {
background: var(--bg-card-h);
border-color: var(--border-hi);
box-shadow: 0 12px 40px oklch(0% 0 0 / 0.4);
}
.project-card .img-wrap {
aspect-ratio: 16 / 9; overflow: hidden; position: relative;
border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}
.project-card .img-wrap img {
width: 100%; height: 100%; object-fit: cover;
filter: brightness(0.85) saturate(0.9);
transition: transform 0.5s ease, filter 0.4s, opacity 0.6s ease;
}
.project-card .img-wrap picture {
display: block;
position: absolute; inset: 0;
opacity: 0;
transition: opacity 0.8s ease;
}
.project-card .img-wrap picture:first-of-type {
position: relative;
}
.project-card .img-wrap picture.img-active {
opacity: 1;
}
.project-card:hover .img-wrap img {
transform: scale(1.04);
filter: brightness(1) saturate(1);
}
.project-card .img-wrap video {
position: absolute; inset: 0; width: 100%; height: 100%;
object-fit: cover; opacity: 0;
transition: opacity 0.8s ease;
pointer-events: none;
}
.project-card:hover .img-wrap video.video-active { opacity: 1; }
.project-card .img-wrap video.video-active { opacity: 1; }
.project-card:hover .img-wrap img { opacity: 0; }
.project-card.video-playing .img-wrap img { opacity: 0; }
.card-unmute {
position: absolute; top: 12px; right: 12px; z-index: 5;
display: inline-flex; align-items: center; justify-content: center;
width: 32px; height: 32px; border-radius: 100px;
background: oklch(14% 0.003 260 / 0.85); backdrop-filter: blur(8px) saturate(1.3);
border: 1px solid var(--border); color: var(--fg);
cursor: pointer; opacity: 0; pointer-events: none;
transition: opacity 0.25s ease, border-color 0.2s, color 0.2s;
}
.project-card.video-playing .card-unmute { opacity: 1; pointer-events: auto; }
.card-unmute:hover { border-color: var(--border-hi); color: var(--fg-bright); }
.card-unmute:focus-visible { outline: 2px solid var(--fg); outline-offset: 2px; }
.card-unmute.unmuted { opacity: 0; pointer-events: none; }
.clip-indicator {
position: absolute; bottom: 12px; left: 12px; z-index: 3;
display: flex; gap: 6px; opacity: 0;
transition: opacity 0.3s ease;
}
.project-card:hover .clip-indicator { opacity: 1; }
.clip-indicator span {
width: 24px; height: 3px; border-radius: 2px;
background: oklch(40% 0.003 260 / 0.6);
transition: background 0.3s ease;
}
.clip-indicator span.clip-active { background: var(--fg); }
.project-card .card-body { padding: 20px 22px 22px; }
.project-card h2 {
font-family: var(--font-display); font-size: 20px; font-weight: 500;
letter-spacing: -0.01em; color: var(--fg-bright); margin-bottom: 6px;
}
.project-card .card-label {
font-family: var(--font-mono); font-size: var(--fs-micro);
letter-spacing: 0.08em; color: var(--muted);
}
.project-card .card-desc {
font-family: var(--font-display); font-size: var(--fs-body); font-weight: 300;
letter-spacing: -0.005em; line-height: 1.7; color: var(--fg);
margin-top: 12px;
overflow: hidden;
max-height: 999px;
transition: max-height 0.35s ease, opacity 0.25s ease;
opacity: 1;
}
.card-desc-wrap { margin-top: 12px; }
.card-desc-wrap + .card-repo { margin-top: 14px; }
.card-desc-toggle {
display: none;
font-family: var(--font-mono); font-size: 11px;
letter-spacing: 0.06em; color: var(--muted);
background: none; border: none; padding: 0; cursor: pointer;
margin-top: 6px; transition: color 0.2s;
}
.card-desc-toggle:hover { color: var(--fg); }
.card-desc-toggle:focus-visible { outline: 2px solid var(--fg); outline-offset: 2px; }
.card-desc-toggle .arrow { display: inline-block; margin-left: 4px; transition: transform 0.3s ease; }
@media (max-width: 760px) {
.card-desc-toggle { display: inline-block; }
.card-desc-wrap .card-desc {
max-height: 4.5em; opacity: 0.85;
}
.card-desc-wrap.expanded .card-desc {
max-height: 999px; opacity: 1;
}
.card-desc-wrap.expanded .card-desc-toggle .arrow { transform: rotate(180deg); }
.project-card .card-desc { margin-top: 0; }
.project-card .card-desc + .card-repo { margin-top: 14px; }
}
.card-link { font-size: 0.7em; color: var(--muted); transition: color 0.2s; }
.project-card:hover .card-link { color: var(--fg); }
.card-repo {
display: inline-flex; align-items: center; gap: 4px;
font-family: var(--font-mono); font-size: 11px; font-weight: 400;
letter-spacing: 0.04em; color: var(--muted);
padding: 3px 10px; border: 1px solid var(--border); border-radius: 100px;
background: oklch(12% 0.003 260 / 0.5); text-decoration: none;
transition: color 0.2s, border-color 0.2s, background 0.2s;
margin-top: 10px; cursor: pointer;
}
.card-repo:hover { color: var(--fg); border-color: var(--border-hi); background: oklch(16% 0.004 260 / 0.8); }
.live-badge {
position: absolute; top: 12px; left: 12px; z-index: 2;
display: inline-flex; align-items: center; gap: 6px;
padding: 4px 10px; border-radius: 100px;
background: oklch(14% 0.003 260 / 0.85); backdrop-filter: blur(8px) saturate(1.3);
border: 1px solid oklch(40% 0.12 145 / 0.5);
font-family: var(--font-mono); font-size: 10px;
letter-spacing: 0.1em; text-transform: uppercase;
color: oklch(75% 0.15 145);
opacity: 0; transition: opacity 0.3s ease;
}
.project-card.video-playing .live-badge { opacity: 1; }
.video-dim-overlay {
position: fixed; inset: 0; z-index: 90;
background: oklch(4% 0.002 260 / 0);
pointer-events: none;
transition: background 0.5s ease;
}
.video-dim-overlay.active { background: oklch(4% 0.002 260 / 0.82); }
.project-card.video-playing { z-index: 91; }
.live-badge::before {
content: ''; width: 6px; height: 6px; border-radius: 50%;
background: oklch(70% 0.18 145);
box-shadow: 0 0 6px oklch(70% 0.18 145 / 0.8);
}
.card-tooltip {
position: absolute; bottom: 12px; right: 12px; z-index: 2;
padding: 6px 12px; border-radius: 100px;
background: oklch(14% 0.003 260 / 0.9); backdrop-filter: blur(8px) saturate(1.3);
border: 1px solid var(--border);
font-family: var(--font-mono); font-size: 10px;
letter-spacing: 0.06em; color: var(--fg);
opacity: 0; transform: translateY(4px);
transition: opacity 0.25s ease, transform 0.25s ease;
pointer-events: none; white-space: nowrap;
}
.project-card:hover .card-tooltip { opacity: 1; transform: translateY(0); }
.pagination { display: none; }
.project-breadcrumbs {
display: flex; align-items: center; justify-content: center;
gap: 0; margin-top: var(--gap-lg);
flex-wrap: wrap; row-gap: 8px;
}
.project-breadcrumbs .crumb {
font-family: var(--font-mono); font-size: var(--fs-micro);
letter-spacing: 0.06em; color: var(--faint);
cursor: pointer; padding: 4px 0;
transition: color 0.2s; white-space: nowrap;
}
.project-breadcrumbs .crumb:hover { color: var(--muted); }
.project-breadcrumbs .crumb.active { color: var(--fg); }
.project-breadcrumbs .crumb.active:hover { color: var(--fg-bright); }
.project-breadcrumbs .sep {
color: var(--faint); font-family: var(--font-mono);
font-size: var(--fs-micro); margin: 0 8px; opacity: 0.5;
}
.carousel-arrow {
position: absolute; z-index: 10; top: 50%; transform: translateY(-50%);
width: 48px; height: 48px; border-radius: 50%;
background: oklch(14% 0.003 260 / 0.85); backdrop-filter: blur(12px) saturate(1.3);
border: 1px solid var(--border); color: var(--fg);
font-family: var(--font-mono); font-size: 18px;
display: flex; align-items: center; justify-content: center;
cursor: pointer; opacity: 0; transition: opacity 0.25s, background 0.2s, border-color 0.2s;
}
.carousel-arrow:hover { background: oklch(20% 0.004 260 / 0.9); border-color: var(--border-hi); }
.carousel-arrow:focus-visible { outline: 2px solid var(--fg); outline-offset: 2px; }
.carousel-arrow-prev { left: 80px; }
.carousel-arrow-next { right: 128px; }
#work:hover .carousel-arrow { opacity: 1; }
@media (max-width: 760px) {
.carousel-arrow { width: 40px; height: 40px; font-size: 16px; }
.carousel-arrow-prev { left: 12px; }
.carousel-arrow-next { right: 12px; }
}
/* ─── about ────────────────────────────────────────────────────── */
.about-grid {
display: grid; grid-template-columns: 1fr 1.5fr;
gap: var(--gap-xl); align-items: start;
}
@media (max-width: 760px) { .about-grid { grid-template-columns: 1fr; } }
.about-label {
font-family: var(--font-mono); font-size: var(--fs-micro);
letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted);
}
.about-text p { color: var(--fg); font-size: 17px; line-height: 1.8; font-family: var(--font-display); font-weight: 300; letter-spacing: -0.005em; }
.about-text p + p { margin-top: var(--gap-md); }
.about-text { text-align: center; }
.about-scroll {
max-height: 400px; overflow-y: auto; overflow-x: hidden;
padding-right: 12px; text-align: center;
scrollbar-width: thin; scrollbar-color: var(--border) transparent;
}
.about-scroll::-webkit-scrollbar { width: 4px; }
.about-scroll::-webkit-scrollbar-track { background: transparent; }
.about-scroll::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }
.about-portrait {
position: relative; width: 100%; max-width: 320px;
aspect-ratio: 3 / 4; overflow: hidden;
border-radius: var(--radius-lg);
}
.about-portrait img {
width: 100%; height: 100%; object-fit: cover;
filter: brightness(0.85) contrast(1.05) saturate(0.9);
-webkit-mask-image: radial-gradient(ellipse 105% 105% at 50% 45%, #000 50%, transparent 90%);
mask-image: radial-gradient(ellipse 105% 105% at 50% 45%, #000 50%, transparent 90%);
transition: opacity 1.8s ease;
}
.about-portrait .portrait-video {
position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
opacity: 0; transition: opacity 1.8s ease;
filter: brightness(0.85) contrast(1.05) saturate(0.9);
-webkit-mask-image: radial-gradient(ellipse 105% 105% at 50% 45%, #000 50%, transparent 90%);
mask-image: radial-gradient(ellipse 105% 105% at 50% 45%, #000 50%, transparent 90%);
}
.about-portrait.video-active .portrait-video { opacity: 1; }
.about-portrait.video-active img { opacity: 0; }
.portrait-unmute {
position: absolute; bottom: 12px; right: 12px; z-index: 3;
display: inline-flex; align-items: center; gap: 6px;
padding: 5px 11px; border-radius: 100px;
background: oklch(14% 0.003 260 / 0.85); backdrop-filter: blur(8px) saturate(1.3);
border: 1px solid var(--border);
font-family: var(--font-mono); font-size: 10px;
letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg);
cursor: pointer; display: none;
animation: umFadeIn 0.4s ease;
}
.about-portrait.video-active .portrait-unmute.is-muted { display: inline-flex; }
@keyframes umFadeIn { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } }
.portrait-unmute:hover { border-color: var(--border-hi); background: oklch(18% 0.004 260 / 0.9); color: var(--fg-bright); }
.portrait-unmute:focus-visible { outline: 2px solid var(--fg); outline-offset: 2px; }
.portrait-unmute .um-icon { display: inline-flex; align-items: center; justify-content: center; width: 12px; height: 12px; }
/* hover-only video controls */
.portrait-controls {
position: absolute; bottom: 12px; left: 12px; z-index: 4;
display: inline-flex; align-items: center; gap: 8px;
padding: 5px 11px; border-radius: 100px;
background: oklch(14% 0.003 260 / 0.85); backdrop-filter: blur(8px) saturate(1.3);
border: 1px solid var(--border);
font-family: var(--font-mono); font-size: 10px;
letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg);
opacity: 0; pointer-events: none;
transition: opacity 0.25s ease;
}
.about-portrait:hover .portrait-controls,
.about-portrait:focus-within .portrait-controls { opacity: 1; pointer-events: auto; }
.portrait-controls:hover { border-color: var(--border-hi); background: oklch(18% 0.004 260 / 0.9); color: var(--fg-bright); }
.portrait-controls button {
display: inline-flex; align-items: center; justify-content: center; gap: 5px;
background: none; border: none; color: inherit; cursor: pointer;
font: inherit; letter-spacing: inherit; text-transform: inherit;
padding: 0; -webkit-appearance: none; appearance: none;
}
.portrait-controls button:focus-visible { outline: 2px solid var(--fg); outline-offset: 2px; border-radius: 100px; }
.portrait-controls .pc-icon { display: inline-flex; width: 12px; height: 12px; }
.about-portrait::after {
content: ''; position: absolute; inset: 0; pointer-events: none;
background: linear-gradient(to bottom, transparent 45%, var(--bg) 100%);
}
@media (max-width: 760px) {
.about-portrait { max-width: 240px; margin-inline: auto; }
}
.stats {
display: grid; grid-template-columns: repeat(4, 1fr);
gap: var(--gap-md); margin-top: var(--gap-lg);
}
@media (max-width: 640px) { .stats { grid-template-columns: repeat(2, 1fr); } }
.stat { border-top: 1px solid var(--border); padding-top: 16px; }
.stat .num {
font-family: var(--font-display); font-size: 32px; font-weight: 400;
color: var(--fg-bright); letter-spacing: -0.02em; line-height: 1;
}
.stat .stat-label {
font-family: var(--font-mono); font-size: var(--fs-micro);
letter-spacing: 0.06em; color: var(--muted); margin-top: 8px;
}
.timeline { margin-top: var(--gap-lg); }
.tl-row {
display: grid; grid-template-columns: 140px 1fr;
gap: var(--gap-lg); padding: 18px 0;
border-top: 1px solid var(--border);
align-items: baseline;
}
.tl-row .meta { color: var(--muted); font-size: 12px; letter-spacing: 0.04em; }
.tl-row h3 { font-family: var(--font-body); font-size: 16px; font-weight: 500; color: var(--fg); }
.tl-row p { margin: 4px 0 0; color: var(--muted); font-size: 14px; }
@media (max-width: 640px) { .tl-row { grid-template-columns: 1fr; gap: 4px; } }
/* ─── expertise ────────────────────────────────────────────────── */
.expertise-grid {
display: grid; grid-template-columns: repeat(2, 1fr);
gap: var(--gap-lg); margin-top: var(--gap-lg);
}
@media (max-width: 640px) { .expertise-grid { grid-template-columns: 1fr; } }
.expertise-group {
border-top: 1px solid var(--border); padding-top: 18px;
}
.expertise-group h3 {
font-family: var(--font-mono); font-size: var(--fs-micro);
letter-spacing: 0.14em; text-transform: uppercase;
color: var(--muted); margin-bottom: 12px;
}
.expertise-group .items {
display: flex; flex-wrap: wrap; gap: 8px 14px;
font-size: 15px; color: var(--fg); line-height: 1.5;
}
.expertise-group .items span { white-space: nowrap; }
/* ─── contact ──────────────────────────────────────────────────── */
.contact-inner { text-align: center; max-width: 480px; margin-inline: auto; }
.contact-inner .lead { margin-inline: auto; margin-bottom: var(--gap-lg); }
.contact-form { display: flex; flex-direction: column; gap: var(--gap-md); text-align: left; }
.field { display: flex; flex-direction: column; gap: 6px; }
.field label {
font-family: var(--font-mono); font-size: var(--fs-micro);
letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted);
}
.input, .textarea {
width: 100%; padding: 12px 14px;
border: 1px solid var(--border);
border-radius: var(--radius);
background: var(--surface);
color: var(--fg); font: inherit; font-size: 15px;
transition: border-color 0.2s;
}
.input:focus, .textarea:focus {
outline: none; border-color: var(--border-hi);
}
.textarea { min-height: 100px; resize: vertical; }
.submit-btn {
align-self: center; margin-top: var(--gap-sm);
font-family: var(--font-mono); font-size: 12px;
letter-spacing: 0.14em; text-transform: uppercase;
color: var(--fg); background: transparent;
border: 1px solid var(--border);
padding: 10px 24px; border-radius: var(--radius);
transition: border-color 0.2s, color 0.2s;
display: inline-flex; align-items: center; gap: 8px;
}
.submit-btn::after { content: '→'; transition: transform 0.2s; }
.submit-btn:hover { border-color: var(--fg); }
.submit-btn:hover::after { transform: translateX(3px); }
.submit-btn:disabled { opacity: 0.4; }
.form-confirm {
font-family: var(--font-mono); font-size: 12px;
color: var(--muted); text-align: center;
}
/* ─── footer ───────────────────────────────────────────────────── */
.pagefoot {
padding-block: var(--gap-xl);
border-top: 1px solid var(--border);
}
.pagefoot .row-between { flex-wrap: wrap; }
.footer-bio { font-family: var(--font-display); font-size: 16px; font-weight: 500; color: var(--fg-bright); }
.footer-links { display: flex; gap: 20px; flex-wrap: wrap; margin-top: 10px; }
.footer-links a {
font-family: var(--font-mono); font-size: 11px;
letter-spacing: 0.12em; text-transform: uppercase;
color: var(--muted); transition: color 0.2s;
}
.footer-links a:hover { color: var(--fg); }
.footer-right { text-align: right; }
@media (max-width: 640px) { .footer-right { text-align: left; } }
/* ─── focus ────────────────────────────────────────────────────── */
a:focus-visible, button:focus-visible {
outline: 1px solid var(--fg); outline-offset: 3px;
}
.input:focus-visible, .textarea:focus-visible { outline: none; }
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
/* ─── mobile optimization ─────────────────────────────────────── */
@media (max-width: 760px) {
:root {
--gutter: 20px;
--gap-md: 16px;
--gap-lg: 24px;
--gap-xl: 40px;
--gap-2xl: 64px;
}
html, body { scroll-snap-type: none; }
.section { min-height: auto; scroll-snap-align: none; scroll-snap-stop: normal; padding-block: clamp(32px, 6vh, 48px); }
/* .section is a column flexbox, so .container is a flex item whose
default min-width:auto prevents it from shrinking below its
content's min-content width. On mobile this made wide children
(e.g. the horizontal project carousel) blow the container out to
--container (960px) even in a 390px viewport, leaving the grid
nearly unscrollable and cutting off cards after the 2nd. Force
the container to honour the viewport on small screens. */
.section > .container { width: 100%; max-width: 100%; min-width: 0; }
.hero { min-height: 100svh; display: flex; flex-direction: column; justify-content: center; align-items: center; text-align: center; }
.hero .container { width: 100%; max-width: 100%; padding-inline: var(--gutter); }
.hero h1 { font-size: clamp(36px, 11vw, 52px); }
.hero .lead { font-size: 15px; max-width: 90%; }
.hero-cta { font-size: 14px; }
.projects-head { margin-bottom: var(--gap-md); }
.projects-head .label { font-size: 10px; }
.project-grid { scroll-snap-type: x proximity; -webkit-overflow-scrolling: touch; overflow-y: hidden; }
.project-card { flex-basis: calc(100vw - 2 * var(--gutter) - var(--gap-md)); scroll-snap-align: center; }
.project-card .img-wrap { aspect-ratio: 4 / 3; }
.project-card .card-body { padding: 16px 18px 18px; }
.project-card h2 { font-size: 18px; }
.project-breadcrumbs {
display: flex; flex-wrap: nowrap; justify-content: flex-start;
gap: 8px; margin-bottom: 70px; padding-bottom: 12px;
overflow-x: auto; overflow-y: hidden;
scrollbar-width: none; -ms-overflow-style: none;
-webkit-overflow-scrolling: touch;
width: 100%; box-sizing: border-box;
padding-left: 0; padding-right: 0;
}
.project-breadcrumbs::-webkit-scrollbar { display: none; }
.project-breadcrumbs .crumb {
font-size: 10px; white-space: nowrap;
padding: 6px 12px; border: 1px solid var(--border); border-radius: 100px;
background: oklch(12% 0.003 260 / 0.6);
}
.project-breadcrumbs .crumb.active { border-color: var(--border-hi); background: oklch(16% 0.004 260 / 0.8); }
.project-breadcrumbs .sep { display: none; }
.carousel-arrow { display: none; }
.carousel-arrow-prev { left: 8px; }
.carousel-arrow-next { right: 8px; }
.project-card .img-wrap video.video-active { opacity: 1; }
.project-card.video-playing .img-wrap img { opacity: 0; }
.project-card .clip-indicator { opacity: 1; }
.project-card .card-unmute { opacity: 1; pointer-events: auto; }
.about-text p { font-size: 16px; }
.stat .num { font-size: 26px; }
.contact-inner { max-width: 100%; }
.contact-form { gap: 14px; }
.footer-links { gap: 14px; }
.footer-links a { font-size: 10px; }
.nav-cta { top: 16px; right: 16px; bottom: auto; font-size: 11px; padding: 8px 16px; }
.video-dim-overlay.active { background: transparent; }
}
@media (max-width: 420px) {
:root { --gutter: 16px; }
.hero h1 { font-size: 38px; }
.hero .lead { font-size: 14px; }
.project-card { flex-basis: calc(100vw - 2 * var(--gutter) - var(--gap-md)); }
.project-breadcrumbs .sep { display: none; }
.project-breadcrumbs .crumb { font-size: 9px; }
.stats { grid-template-columns: 1fr 1fr; gap: 12px; }
.stat .num { font-size: 22px; }
.footer-links { gap: 10px; }
}
/* Blog section */
.blog-intro { margin: 0.75rem 0 0; max-width: 36rem; color: var(--muted); font-family: var(--font-display); font-size: var(--fs-lead); line-height: 1.6; font-weight: 300; letter-spacing: -0.005em; }
.blog-grid { display: grid; grid-template-columns: 1fr; gap: var(--gap-lg); margin-top: var(--gap-xl); }
@media (min-width: 700px) { .blog-grid { grid-template-columns: repeat(2, 1fr); gap: var(--gap-md); } }
@media (min-width: 1100px) { .blog-grid { grid-template-columns: repeat(4, 1fr); gap: var(--gap-md); } }
.blog-card { display: flex; flex-direction: column; text-decoration: none; color: inherit; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; background: var(--bg-card); transition: border-color 0.25s ease, transform 0.25s ease; }
.blog-card:hover { border-color: var(--border-hi); transform: translateY(-2px); }
.blog-card-media { aspect-ratio: 16 / 10; overflow: hidden; background: oklch(10% 0.002 260); }
.blog-card-media img, .blog-card-media video { width: 100%; height: 100%; object-fit: cover; display: block; }
.blog-card-body { padding: var(--gap-sm) 1.2rem var(--gap-md); display: flex; flex-direction: column; gap: 0.45rem; flex: 1; }
.blog-tag { font-family: var(--font-mono); font-size: var(--fs-micro); letter-spacing: 0.16em; text-transform: uppercase; color: var(--faint); }
.blog-card h3 { margin: 0; font-family: var(--font-display); font-weight: 400; font-size: 1.35rem; letter-spacing: -0.01em; color: var(--fg-bright); }
.blog-card-body p { margin: 0; color: var(--muted); font-size: var(--fs-body); line-height: 1.55; font-weight: 300; flex: 1; }
.blog-read { margin-top: 0.6rem; font-family: var(--font-mono); font-size: var(--fs-micro); letter-spacing: 0.16em; text-transform: uppercase; color: var(--fg); }