/* Tokens from the Figma file "Portfolio homepage" (Desktop 29:3, Tablet 35:84, Mobile 35:67) */
:root {
  --color-bg: #121212;
  --color-fg: #ffffff;
  --color-fg-bio: rgba(255, 255, 255, 0.6);
  --color-fg-muted: rgba(255, 255, 255, 0.5);

  --font-display: "Inter", system-ui, sans-serif;
  /* The design uses SF Pro Text; Apple devices get it natively, everyone else gets Inter. */
  --font-text: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Inter", "Segoe UI", system-ui, sans-serif;

  /* Mobile (390) is the base; tablet and desktop override below. */
  --page-pb: 32px;
  --page-px: 24px;
  --name-size: 36px;
  --name-leading: 1.05;
  --tagline-size: 16px;
  --footer-gap: 48px;
  --link-min-h: 44px;
}

@media (min-width: 768px) {
  :root {
    --page-pb: 40px;
    --page-px: 48px;
    --name-size: 48px;
    --tagline-size: 17px;
  }
}

@media (min-width: 1024px) {
  :root {
    --page-pb: 39px;
    --name-leading: 0.91;
    --footer-gap: 40px;
    --link-min-h: 0;
  }
}

@media (max-width: 359px) {
  :root {
    --name-size: 30px;
  }
}

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

html,
body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-fg);
}

body {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

/* Mobile and tablet: the intro is centred in the space left above the footer. */
.page {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-height: 100vh;
  min-height: 100dvh;
  padding: env(safe-area-inset-top) var(--page-px) calc(var(--page-pb) + env(safe-area-inset-bottom));
}

.main {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
}

/* Desktop: the intro is centred on the whole viewport. Equal 1fr rows sit above and below it, the footer
   sits in the bottom row, and top padding mirrors the bottom so the centring isn't offset. */
@media (min-width: 1024px) {
  .page {
    display: grid;
    grid-template-rows: 1fr auto 1fr;
    justify-items: center;
    padding-top: calc(var(--page-pb) + env(safe-area-inset-top));
  }

  .main {
    grid-row: 2;
  }

  .footer {
    grid-row: 3;
    align-self: end;
  }
}

.intro {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
  width: 100%;
  max-width: 480px;
  text-align: center;
  overflow-wrap: break-word;
}

.intro__name {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--name-size);
  line-height: var(--name-leading);
  letter-spacing: -0.02em;
}

.intro__name-muted {
  color: var(--color-fg-muted);
}

.intro__tagline {
  margin: 0;
  font-family: var(--font-text);
  font-weight: 400;
  font-size: var(--tagline-size);
  line-height: normal;
}

.footer {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--footer-gap);
  width: 100%;
  max-width: 400px;
}

.bio {
  margin: 0;
  font-family: var(--font-text);
  font-weight: 300;
  font-size: 13px;
  line-height: 16px;
  color: var(--color-fg-bio);
  text-align: center;
}

.nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 24px;
}

.nav__link {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: var(--link-min-h);
  padding: 8px;
  border-radius: 6px;
  font-family: var(--font-text);
  font-size: 13px;
  line-height: 16px;
  color: var(--color-fg-muted);
  text-decoration: none;
  white-space: nowrap;
  transition: color 150ms ease-out;
}

.nav__link:hover {
  color: var(--color-fg);
}

.nav__link:focus-visible {
  color: var(--color-fg);
  outline: 1px solid var(--color-fg-muted);
  outline-offset: 0;
}

/* Page-load entrance: name, tagline, bio, then links, each rising gently into place. On the 404 page "Back to
   home" takes the bio's turn. Only the start state is filled in, so nothing stays hidden if animations don't run. */
.intro__name,
.intro__tagline,
.intro .nav__link,
.bio,
.nav {
  animation: appear 800ms cubic-bezier(0.23, 1, 0.32, 1) backwards;
}

.intro__name {
  animation-delay: 100ms;
}

.intro__tagline {
  animation-delay: 280ms;
}

.bio,
.intro .nav__link {
  animation-delay: 460ms;
}

.nav {
  animation-delay: 640ms;
}

@keyframes appear {
  from {
    opacity: 0;
    filter: blur(4px);
    transform: translateY(10px);
  }
}

/* Five links with 24px gaps need 338px, which only fits from 390px up. On narrower phones the links spread
   across the full width instead; their 8px padding keeps them apart. */
@media (max-width: 389px) {
  .nav {
    justify-content: space-between;
    gap: 0;
    width: 100%;
  }
}

/* Cookie consent banner, built by analytics.js. It isn't in the Figma file, so it borrows the footer's type.
   Both buttons get equal weight so declining is as easy as accepting. */
.consent {
  position: fixed;
  right: 16px;
  bottom: calc(16px + env(safe-area-inset-bottom));
  left: 16px;
  z-index: 10;
  display: flex;
  flex-direction: column;
  gap: 16px;
  max-width: 360px;
  margin-inline: auto;
  padding: 16px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  background: #1a1a1a;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
  /* Waits for the page entrance to finish; hidden (and unclickable) until then. */
  animation: consent-in 300ms ease-out 1200ms backwards;
}

/* Desktop: tuck it into the corner so it doesn't cover the centred nav. */
@media (min-width: 1024px) {
  .consent {
    right: 24px;
    bottom: 24px;
    left: auto;
    margin: 0;
  }
}

.consent__text {
  margin: 0;
  font-family: var(--font-text);
  font-weight: 300;
  font-size: 13px;
  line-height: 16px;
  color: var(--color-fg-bio);
}

.consent__actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

.consent__button {
  min-height: var(--link-min-h);
  padding: 8px 12px;
  border: 0;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.08);
  font-family: var(--font-text);
  font-size: 13px;
  line-height: 16px;
  color: var(--color-fg);
  cursor: pointer;
  transition: background-color 150ms ease-out;
}

.consent__button:hover {
  background: rgba(255, 255, 255, 0.14);
}

.consent__button:focus-visible {
  outline: 1px solid var(--color-fg-muted);
  outline-offset: 2px;
}

@keyframes consent-in {
  from {
    visibility: hidden;
    opacity: 0;
    transform: translateY(8px);
  }
}

@media (prefers-reduced-motion: reduce) {
  .nav__link,
  .consent__button {
    transition: none;
  }

  .intro__name,
  .intro__tagline,
  .intro .nav__link,
  .bio,
  .nav,
  .consent {
    animation: none;
  }
}
