/* Hallmark · shape: Manifesto · genre: atmospheric · theme: Cosmic · job: hire
 * hero: Banner · nav: edge-aligned · footer: colophon block · imagery: particle canvas · signature: the ENTER orbit
 * axes: dark/display-condensed/chromatic-cyan-violet · posture: restrained · contrast: check · v2.0.0 */
/* Hallmark · pre-emit critique: P4 H4 E3 S3 R5 V5 · weakest: S, personal facts were absent; kept clear edit slots instead of inventing a persona */
@import url("./tokens.css");
@import url("./base.css");

:root { --font-label: var(--font-accent); }
@property --gradient-shift { syntax: "<length>"; inherits: false; initial-value: 0px; }
html { scroll-behavior: smooth; }
body { min-height: 100vh; position: relative; isolation: isolate; background: var(--color-paper); --particle-opacity: 0.72; }
body::before { --gradient-shift: 28vh; content: ""; position: fixed; z-index: -1; inset: 0; pointer-events: none; background: radial-gradient(ellipse at 16% calc(18% + var(--gradient-shift)), color-mix(in oklab, var(--color-cosmic-violet) 28%, transparent), transparent 42%), radial-gradient(ellipse at 86% calc(68% + var(--gradient-shift)), color-mix(in oklab, var(--color-cosmic-blue) 23%, transparent), transparent 48%); transition: --gradient-shift 3.3s var(--ease-out); }
body.site-open::before { --gradient-shift: 0vh; }
.container { max-width: 1440px; }
a { text-decoration-color: var(--color-rule); text-decoration-thickness: 1px; text-underline-offset: 0.24em; }
a:hover { text-decoration-color: var(--color-accent); }
button { color: inherit; }
.cosmos-canvas { position: fixed; inset: 0; z-index: 0; width: 100vw; height: 100vh; display: block; pointer-events: none; }
body.site-open { --particle-opacity: 0.42; }
body.glow-boost { --particle-opacity: 0.95; }
.entry-screen { position: fixed; z-index: 2; inset: 0; display: grid; place-items: center; visibility: hidden; opacity: 0; pointer-events: none; transition: opacity 1.1s var(--ease-out), visibility 0s linear 1.1s; }
html.js body.intro-mode .entry-screen { visibility: visible; opacity: 1; pointer-events: auto; transition: opacity 1.1s var(--ease-out); }
html.js body.intro-mode { height: 100vh; overflow: hidden; }
html.js body.intro-mode .skip-link { visibility: hidden; }
/* Welcome button: a flat black void. Hover only raises its opacity, with no transition. */
.entry-button { display: grid; width: clamp(10rem, 24vw, 15rem); aspect-ratio: 1; place-items: center; padding: 0; border: 0; border-radius: 50%; background: #000; color: var(--color-ink); cursor: pointer; opacity: 0.7; }
.entry-button:hover { opacity: 1; }
.entry-button:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 10px; }
.entry-label { display: inline-flex; align-items: center; gap: 0.55rem; font: 500 var(--text-lg)/1 var(--font-display); letter-spacing: 0.14em; }
.entry-label::before, .entry-label::after { width: 0.7rem; height: 1px; background: currentColor; content: ""; opacity: 0.6; }
.entry-label::after { margin-left: -0.14em; }
/* The Welcome button fades in over two seconds whenever the entry screen appears. */
html.js body.intro-mode .entry-button { animation: entry-fade-in 2s var(--ease-in-out) backwards; }
@keyframes entry-fade-in { from { opacity: 0; } }
.entry-screen, .site-header, main, .site-footer { transition: opacity 1.1s var(--ease-out), visibility 0s linear 1.1s; }
html.js body.intro-mode .site-header, html.js body.intro-mode main, html.js body.intro-mode .site-footer { visibility: hidden; opacity: 0; pointer-events: none; }
html.js body.site-open .entry-screen { visibility: hidden; opacity: 0; pointer-events: none; }
html.js body.site-open .site-header, html.js body.site-open main, html.js body.site-open .site-footer { visibility: visible; opacity: 1; pointer-events: auto; transition: opacity 1.1s var(--ease-out); }
/* Header and first-screen layout. */
.site-header { position: relative; z-index: 1; min-height: 5rem; display: flex; align-items: center; justify-content: space-between; gap: var(--space-lg); border-bottom: 1px solid var(--color-rule); }
.wordmark { font: 400 1.125rem/1 var(--font-accent); letter-spacing: 0.01em; text-decoration: none; white-space: nowrap; }
.wordmark span { color: var(--color-accent); }
.site-nav, .header-tools { display: flex; align-items: center; gap: var(--space-lg); }
.site-nav a, .text-button { font: 400 var(--text-sm)/1.3 var(--font-body); text-decoration: none; }
.site-nav a { display: inline-flex; min-height: 44px; align-items: center; }
.text-button { min-height: 44px; padding: 0; border: 0; background: transparent; color: var(--color-ink-2); cursor: pointer; }
.text-button:hover { color: var(--color-accent); }
.text-button:disabled { opacity: 0.55; cursor: not-allowed; }
/* Header links and buttons share one hover: the colour shifts and an underline draws in. The theme button has a fixed width so the layout stays still when its label changes. */
.text-button { white-space: nowrap; transition: color var(--dur-short) var(--ease-out); }
.site-nav a { color: var(--color-ink-2); transition: color var(--dur-short) var(--ease-out); }
.site-nav a:hover, .site-nav a:focus-visible { color: var(--color-accent); }
.text-button-label, .nav-label { padding-bottom: 3px; background: linear-gradient(currentColor, currentColor) no-repeat 0 100% / 0 1px; transition: background-size var(--dur-long) var(--ease-out); }
.text-button:hover .text-button-label, .text-button:focus-visible .text-button-label, .site-nav a:hover .nav-label, .site-nav a:focus-visible .nav-label { background-size: 100% 1px; }
.theme-toggle { min-width: 8.5rem; text-align: left; }
/* On wide screens the logo and the tools share the width equally, so the nav sits in the true centre. */
@media (min-width: 60.01rem) {
  .site-header { gap: var(--space-md); }
  .site-header .wordmark, .site-header .header-tools { flex: 1 1 0; min-width: max-content; }
  .site-header .header-tools { justify-content: flex-end; }
}
.hero { min-height: 34rem; padding-block: clamp(3rem, 8vh, 5rem) var(--space-3xl); display: grid; grid-template-columns: minmax(0, 1fr) minmax(15rem, 0.8fr); align-items: center; column-gap: clamp(2rem, 8vw, 8rem); position: relative; isolation: isolate; }
.hero-copy { max-width: 50rem; }
.hero-note, .section-label { margin-bottom: var(--space-md); color: var(--color-muted); font: 400 var(--text-sm)/1.4 var(--font-body); }
.hero .lead { max-width: 39ch; color: var(--color-ink-2); }
.hero-actions { display: flex; flex-wrap: wrap; gap: var(--space-sm); margin-top: var(--space-xl); }
.button { display: inline-flex; min-height: 48px; align-items: center; justify-content: center; padding-inline: var(--space-lg); border: 1px solid var(--color-ink); color: var(--color-ink); font: 400 1rem/1 var(--font-body); text-decoration: none; transition: background-color var(--dur-short) var(--ease-out), color var(--dur-short) var(--ease-out), transform var(--dur-micro) var(--ease-out); }
.button-primary { border-color: var(--color-accent); background: var(--color-accent); color: var(--color-accent-ink); }
.button:hover { transform: translateY(-2px); }
.button-primary:hover { background: var(--color-ink); border-color: var(--color-ink); }
.button-quiet { border-color: var(--color-rule); }
.button-quiet:hover { background: var(--color-paper-2); }
.button:active { transform: translateY(1px); }
/* The profile returns to the open, ruled layout; only the portrait gains a frame. */
.profile-widget { width: min(100%, 22rem); margin-inline: auto; padding-bottom: 3.25rem; }
.profile-stage { position: relative; width: 100%; aspect-ratio: 4 / 5; }
.profile-info { position: absolute; inset: 0; z-index: 1; }
.profile-copy { padding-top: clamp(2rem, 6vh, 3rem); transition: opacity 0.45s var(--ease-out) 1.8s, transform 0.45s var(--ease-out) 1.8s; }
.aside-title { margin-bottom: var(--space-md); color: var(--color-muted); font: 400 var(--text-sm)/1.2 var(--font-body); letter-spacing: 0.08em; text-transform: none; }
.aside-name { color: var(--color-ink); font: 500 clamp(2rem, 4vw, 2.75rem)/1.08 var(--font-display); letter-spacing: 0.01em; }
.aside-copy { max-width: 28ch; margin-top: var(--space-md); color: var(--color-ink-2); font-size: var(--text-sm); }
.photo-box { position: absolute; inset: 0; margin: 0; }
.photo-window { position: absolute; inset: 0; overflow: hidden; transition: clip-path 0.9s var(--ease-in-out); }
.photo-window img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 18%; }
.stage-line { position: absolute; z-index: 2; right: 0; left: 0; height: 2px; background: var(--color-accent); }
.stage-line-top { top: 0; }
.stage-line-bottom { bottom: 0; }
.reveal-button { position: absolute; z-index: 3; bottom: 1rem; left: 0; display: flex; min-height: 44px; align-items: center; gap: var(--space-xs); color: var(--color-muted); }
.reveal-button .text-button-label { font-size: var(--text-sm); }
.sparkle { width: 1.45rem; height: 1.45rem; flex: none; overflow: visible; fill: currentColor; color: var(--color-accent); }
.sparkle-main { transform-box: fill-box; transform-origin: center; animation: sparkle-pulse 2.4s ease-in-out infinite; }
.sparkle-small { transform-box: fill-box; transform-origin: center; animation: sparkle-pulse 2.4s ease-in-out 0.5s infinite; }
@keyframes sparkle-pulse { 0%, 100% { opacity: 0.58; transform: scale(0.82); } 50% { opacity: 1; transform: scale(1.12); } }
.js .photo-window { clip-path: inset(50% 0); }
.js .profile-stage.is-open .profile-copy { opacity: 0; transform: translateY(-0.5rem); pointer-events: none; transition-delay: 0s; }
.js .profile-stage.is-open .photo-window { clip-path: inset(0); transition-delay: 0.9s; }
.js .profile-stage.is-transitioning .stage-line-top { animation: profile-rail-top 1.8s var(--ease-in-out) both; }
.js .profile-stage.is-transitioning .stage-line-bottom { animation: profile-rail-bottom 1.8s var(--ease-in-out) both; }
.js .profile-stage.is-open .reveal-button { bottom: -3.25rem; }
.js .profile-stage.is-transitioning.is-open .reveal-button { animation: profile-button-ride 1.8s var(--ease-in-out) both; }
.js .profile-stage.is-transitioning:not(.is-open) .reveal-button { animation: profile-button-ride 1.8s var(--ease-in-out) reverse both; }
@keyframes profile-rail-top { 50% { top: calc(50% - 1px); } }
@keyframes profile-rail-bottom { 50% { bottom: calc(50% - 1px); } }
@keyframes profile-button-ride { 0% { bottom: 1rem; } 50% { bottom: calc(50% + 0.5rem); } 100% { bottom: -3.25rem; } }
html:not(.js) .photo-box, html:not(.js) .reveal-button { display: none; }
html:not(.js) .profile-widget { padding-bottom: 0; }
.scroll-link { position: absolute; bottom: var(--space-lg); left: var(--gutter); color: var(--color-muted); font-size: var(--text-sm); }
/* Keep the cosmic field below all readable page content. */
main > section { position: relative; isolation: isolate; }
main, .site-footer { position: relative; z-index: 1; }
/* Page sections and their reading order. */
.section { padding-block: var(--section-gap); }
.section-heading { max-width: 56rem; margin-bottom: clamp(2rem, 4vw, 3rem); }
.section-heading h2, .contact-layout h2 { max-width: 15ch; font-weight: 500; }
.about-layout { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 0.8fr); gap: clamp(2rem, 8vw, 8rem); align-items: start; }
.about-lead { max-width: 18ch; font: 400 clamp(1.8rem, 4vw, 3.2rem)/1.2 var(--font-display); }
.editable { color: var(--color-accent); }
.about-detail { color: var(--color-ink-2); }
.about-detail > p:first-child { max-width: 60ch; }
.fact-line { display: flex; justify-content: space-between; gap: var(--space-lg); padding-block: var(--space-sm); border-bottom: 1px solid var(--color-rule); }
.fact-line:first-of-type { margin-top: var(--space-xl); border-top: 1px solid var(--color-rule); }
.fact-line span { color: var(--color-muted); }
.fact-line strong { color: var(--color-ink); font-weight: 400; text-align: right; }
.section-education { background: color-mix(in oklab, var(--color-paper-2) 47%, transparent); color: var(--color-ink); }
.education-list { padding: 0; margin: 0; list-style: none; border-top: 1px solid var(--color-rule); }
.education-list li { display: grid; grid-template-columns: minmax(9rem, 0.3fr) minmax(0, 1fr); gap: var(--space-lg); padding-block: var(--space-lg); border-bottom: 1px solid var(--color-rule); }
.education-years { color: var(--color-muted); font: 400 var(--text-sm)/1.4 var(--font-body); }
.education-list h3 { font-family: var(--font-display); font-weight: 400; }
.education-school { margin-top: var(--space-2xs); color: var(--color-accent); }
.education-note { max-width: 60ch; margin-top: var(--space-sm); color: var(--color-muted); }
.projects-heading { display: flex; justify-content: space-between; align-items: end; gap: var(--space-2xl); }
.projects-heading > p { max-width: 45ch; color: var(--color-muted); }
.project-list { padding: 0; margin: 0; list-style: none; border-top: 1px solid var(--color-rule); }
.project-list li { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: var(--space-lg); min-height: 6.5rem; padding-block: var(--space-lg); border-bottom: 1px solid var(--color-rule); }
.project-list h3 { font-weight: 400; }
.project-list li p { margin-top: var(--space-xs); color: var(--color-muted); }
.project-list li > a { white-space: nowrap; }
.contact-section { background: color-mix(in oklab, var(--color-paper-2) 47%, transparent); color: var(--color-ink); }
.contact-layout { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 0.8fr); gap: clamp(2rem, 8vw, 8rem); align-items: start; }
.contact-email { display: inline-block; margin-top: var(--space-md); font: 400 clamp(1.5rem, 3.5vw, 2.6rem)/1.2 var(--font-display); overflow-wrap: anywhere; }
.contact-copy > p { color: var(--color-ink-2); }
.social-links { display: flex; flex-wrap: wrap; gap: var(--space-lg); margin-top: var(--space-xl); }
.site-footer { min-height: 7rem; display: flex; justify-content: space-between; align-items: center; gap: var(--space-lg); color: var(--color-muted); font-size: var(--text-sm); }
.site-footer .wordmark { color: var(--color-ink); }
.back-top { white-space: nowrap; }
/* Keyboard access and the Intersection Observer reveal state. */
.skip-link { position: absolute; z-index: var(--z-toast); top: var(--space-sm); left: var(--space-sm); padding: var(--space-sm) var(--space-md); background: var(--color-ink); color: var(--color-paper); transform: translateY(-160%); }
.skip-link:focus { transform: translateY(0); }
.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; }
.js [data-reveal] { opacity: 0; transform: translateY(0.65rem); transition: opacity var(--dur-long) var(--ease-out), transform var(--dur-long) var(--ease-out); }
.js [data-reveal].is-in { opacity: 1; transform: none; }
/* Stack columns and expand touch targets on narrower screens. */
@media (max-width: 60rem) {
  .site-header { flex-wrap: wrap; justify-content: space-between; padding-block: var(--space-md); }
  .site-nav { order: 3; width: 100%; justify-content: space-between; gap: var(--space-sm); }
  .header-tools { gap: var(--space-md); }
  .hero { min-height: 31rem; grid-template-columns: minmax(0, 1fr) minmax(11rem, 0.55fr); column-gap: var(--space-xl); }
  .projects-heading { align-items: start; }
}
@media (max-width: 42rem) {
  body { --particle-opacity: 0.54; }
  body.glow-boost { --particle-opacity: 0.74; }
  .site-header { gap: var(--space-sm); }
  .wordmark { font-size: 1rem; }
  .header-tools { gap: var(--space-sm); }
  .text-button { font-size: 0.8rem; }
  .site-nav a { font-size: 0.875rem; }
  .hero { min-height: auto; grid-template-columns: minmax(0, 1fr); row-gap: var(--space-2xl); padding-block: var(--space-3xl) var(--space-4xl); }
  .profile-widget { width: min(100%, 20rem); }
  .scroll-link { bottom: var(--space-lg); }
  .about-layout, .contact-layout { grid-template-columns: minmax(0, 1fr); gap: var(--space-xl); }
  .education-list li { grid-template-columns: minmax(0, 1fr); gap: var(--space-xs); }
  .projects-heading { flex-direction: column; gap: var(--space-lg); }
  .project-list li { grid-template-columns: minmax(0, 1fr); gap: var(--space-sm); }
  .site-footer { flex-wrap: wrap; padding-block: var(--space-lg); }
  .site-footer p { order: 3; width: 100%; }
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js [data-reveal] { opacity: 1; transform: none; transition: none; }
  .button { transition: none; }
  .text-button, .text-button-label, .nav-label, .site-nav a { transition: none; }
  .profile-info, .photo-window, .stage-line { transition: none !important; }
  .sparkle-main, .sparkle-small { animation: none !important; }
  html.js body.intro-mode .entry-button { animation: none; }
  .entry-button, .entry-screen, .site-header, main, .site-footer { transition: none; }
}
