/* ============================================
   Portfolio — Clean Minimal Light
   ============================================ */

@import url('https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,400;9..144,500&family=Inter:wght@400;500;600;700&display=swap');

:root {
  /* Color */
  --color-bg: #FAFAF8;
  --color-text: #1A1A1A;
  --color-text-muted: #6B6B6B;
  --color-accent: #4CAF50;
  --color-accent-tint: #EAF7EB;
  --color-link: #3B82C4;
  --color-border: #E8E8E4;

  /* Type */
  --font-display: 'Fraunces', Georgia, serif;
  --font-body: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;

  /* Spacing scale */
  --space-xs: 0.5rem;
  --space-sm: 1rem;
  --space-md: 2rem;
  --space-lg: 4rem;
  --space-xl: 6rem;
  --space-2xl: 8rem;

  /* Layout */
  --content-width: 720px;
  --border-radius: 6px;
}

/* ---------- Reset ---------- */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

body {
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  position: relative;
  /* Mirrors the 80% browser zoom the design was built at, so it renders
     correctly at a visitor's default 100% zoom instead of looking oversized.
     `zoom` is non-standard but supported in all Chromium browsers (Chrome,
     Edge) and Safari; Firefox will simply ignore it and render at 100%. */
  zoom: 90%;
}

/* Page wrapper is the positioning context for the background strip below,
   so it only spans the nav + profile area instead of the whole page. */
.page-wrapper {
  max-width: var(--content-width);
  margin: 0 auto;
  padding: 0 var(--space-md);
  position: relative;
  z-index: 0;
  /* White up top (nav/profile), easing into sky blue progressively
     through the Projects section so it's visibly present well before
     the footer, rather than only appearing right at the bottom edge. */
  background: linear-gradient(180deg, #FFFFFF 0%, #FFFFFF 20%, #EDF5FA 55%, #E1EDF7 85%);
}

/* A duplicate of the wrapper's own background, extending past the
   left/right edges and fading out via an opacity mask. This gives the
   same "edges dissolve" look as a blur, but since it's a pure alpha
   gradient (not a rasterized blur), it renders perfectly smooth with
   no pixelation/noise — filter: blur() on a large area tends to
   introduce visible grain over subtle color gradients like this one. */
.page-wrapper::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: -50px;
  right: -50px;
  background: linear-gradient(180deg, #FFFFFF 0%, #FFFFFF 20%, #EDF5FA 55%, #E1EDF7 85%);
  -webkit-mask-image: linear-gradient(to right, transparent 0%, black 50px, black calc(100% - 50px), transparent 100%);
  mask-image: linear-gradient(to right, transparent 0%, black 50px, black calc(100% - 50px), transparent 100%);
  z-index: -1;
  pointer-events: none;
}

/* Blurred background image, kept on its own layer so the blur never
   touches actual page content (a filter on the wrapper itself would blur
   text too). No longer used on .page-wrapper — see .contact::before,
   which anchors it to the footer's exact bounds instead. */

img {
  max-width: 100%;
  display: block;
}

a {
  color: inherit;
  text-decoration: none;
}

/* Visible keyboard focus everywhere */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
  border-radius: 2px;
}

/* ---------- Nav ---------- */
.nav {
  padding: 1rem 0 var(--space-md);
}

.nav nav {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-md);
  flex-wrap: wrap;
}

.nav a {
  font-size: 0.8125rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-text-muted);
  position: relative;
  padding-bottom: 2px;
}

.nav a::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 0;
  height: 1px;
  background: var(--color-link);
  transition: width 0.2s ease;
}

.nav a:hover,
.nav a:focus-visible {
  color: var(--color-text);
}

.nav a:hover::after,
.nav a:focus-visible::after {
  width: 100%;
}

/* ---------- Profile ---------- */
.profile {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-md) 0 0;
}

.profile-text {
  flex: 1;
}

.profile-text .name {
  font-family: var(--font-display);
  font-size: 2rem;
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -0.01em;
}

.role-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  margin-top: -0.5rem;
  flex-wrap: wrap;
}

.profile-text .role {
  font-size: 0.9375rem;
  color: var(--color-text-muted);
}

/* ---------- Social profiles ---------- */
.social-profiles {
  display: flex;
  gap: 0.5rem;
}

.social-profiles a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  color: var(--color-text-muted);
  border-radius: 50%;
  transition: color 0.2s ease, background-color 0.2s ease;
}

.social-profiles a svg,
.social-profiles a i {
  width: 22.5px;
  height: 22.5px;
  font-size: 22.5px;
}

.social-profiles a:hover,
.social-profiles a:focus-visible {
  color: var(--color-accent);
  background-color: var(--color-accent-tint);
}

/* ---------- Tech stack ---------- */
.tech-stack {
  padding: 1rem 0 1rem;
  border-bottom: 1px solid var(--color-border);
}

.tech-stack-list {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
  list-style: none;
}

.tech-stack-list li {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  font-size: 1.1rem;
  border: 1px solid var(--color-border);
  border-radius: var(--border-radius);
  transition: border-color 0.2s ease, transform 0.2s ease;
}

.tech-stack-list li:hover {
  border-color: var(--color-accent);
  transform: translateY(-2px);
}

/* ---------- Section heading pattern ---------- */
.experience {
  padding: var(--space-md) 0;
}

.projects {
  padding: var(--space-md) 0;
  /* Break out of .page-wrapper's side padding/width so project cards get
     more breathing room, same technique used for .contact below. */
  margin: 0 calc(-1 * var(--space-lg));
  padding-left: var(--space-lg);
  padding-right: var(--space-lg);
}

.heatmap {
  padding: 0.5rem 0 var(--space-sm);
  border-bottom: 1px solid var(--color-border);
}

.heatmap h2,
.experience h2,
.projects h2 {
  font-size: 0.8125rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-text-muted);
  margin-bottom: 0.25rem;
}

.heatmap-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.25rem;
}

.heatmap-header h2 {
  margin-bottom: 0;
}

.year-select {
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--color-text-muted);
  background: transparent;
  border: 1px solid var(--color-border);
  border-radius: var(--border-radius);
  padding: 0.25rem 0.5rem;
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease;
}

.year-select:hover,
.year-select:focus-visible {
  border-color: var(--color-accent);
  color: var(--color-text);
  outline: none;
}

/* ---------- Heatmap (signature element) ---------- */
.heatmap-grid {
  display: grid;
  grid-auto-flow: column;
  grid-template-rows: repeat(7, 11px);
  grid-auto-columns: 11px;
  gap: 3px;
  overflow-x: auto;
  padding-bottom: var(--space-xs);
  scrollbar-width: none;
}

.heatmap-grid::-webkit-scrollbar {
  display: none;
}

.heatmap-grid .cell {
  width: 11px;
  height: 11px;
  border-radius: 2px;
  background: var(--color-border);
}

.heatmap-grid .cell.empty {
  background: transparent;
}

.heatmap-grid .cell[data-level="1"] { background: color-mix(in srgb, var(--color-accent) 20%, var(--color-border)); }
.heatmap-grid .cell[data-level="2"] { background: color-mix(in srgb, var(--color-accent) 45%, var(--color-border)); }
.heatmap-grid .cell[data-level="3"] { background: color-mix(in srgb, var(--color-accent) 70%, var(--color-border)); }
.heatmap-grid .cell[data-level="4"] { background: var(--color-accent); }

/* ---------- Projects ---------- */
.project-list {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-sm);
}

.project-card {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: 12px;
  padding: var(--space-sm);
  transition: border-color 0.35s cubic-bezier(0.4, 0, 0.2, 1),
              transform 0.35s cubic-bezier(0.4, 0, 0.2, 1),
              box-shadow 0.35s cubic-bezier(0.4, 0, 0.2, 1);
}

.project-card:hover {
  border-color: var(--color-text);
  transform: translateY(-4px);
  box-shadow: 0 12px 24px -8px rgba(0, 0, 0, 0.12);
}

.project-image {
  width: 100%;
  aspect-ratio: 21 / 9;
  object-fit: cover;
  border-radius: 8px;
  margin-bottom: var(--space-sm);
}

.project-body {
  flex: 1;
  min-width: 0;
}

.project-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  margin-bottom: 0.35rem;
}

.project-card h3 {
  font-size: 1.0625rem;
  font-weight: 600;
}

.project-github {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--color-text-muted);
  font-size: 1.1rem;
  flex-shrink: 0;
  transition: color 0.2s ease;
}

.project-github:hover,
.project-github:focus-visible {
  color: var(--color-text);
}

.project-card p {
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--color-text-muted);
  margin-bottom: var(--space-sm);
}

.project-card .tags {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.project-card .tags span {
  position: relative;
  overflow: hidden;
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.03em;
  color: #FAFAF8;
  background: linear-gradient(180deg, #3a3a3a 0%, #1a1a1a 60%, #000000 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25),
              inset 0 -1px 2px rgba(0, 0, 0, 0.4);
  padding: 0.2rem 0.6rem;
  border-radius: 100px;
}

.project-card .tags span::after {
  content: '';
  position: absolute;
  top: 0;
  left: -75%;
  width: 50%;
  height: 100%;
  background: linear-gradient(120deg, transparent, rgba(255, 255, 255, 0.35), transparent);
  transform: skewX(-20deg);
  filter: blur(8.5px);
  transition: left 0.7s cubic-bezier(0.4, 0, 0.2, 1);
}

.project-card:hover .tags span::after {
  left: 125%;
}

/* ---------- Contact / footer ---------- */
.contact {
  position: relative;
  /* Establishes a new stacking context so the ::before layer's
     z-index: -1 is scoped to *this* element instead of escaping to the
     root of the page. Without this, the negative z-index would paint
     behind .page-wrapper's background instead of just behind the
     footer's own content. */
  z-index: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-lg);
  align-items: stretch;
  /* Break out of .page-wrapper's side padding so the background can
     reach the true outer edge of the central column, then re-add the
     same padding here so the actual content (heading, form, etc.)
     lines up exactly where it did before. */
  margin: 0 calc(-1 * var(--space-md));
  padding: var(--space-md) var(--space-md) var(--space-lg);
}

/* Blurred background image, kept on its own layer so the blur never
   touches actual page content (a filter on .contact itself would blur
   text too). Stretched (rather than cropped via `cover`) so the whole
   image is visible. Contained within .contact's own bounds (no top
   bleed) so it doesn't overlap the Projects section above it. */
.contact::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-image: url('assets/images/background2.jpeg');
  background-size: 100% 100%;
  background-position: center;
  background-repeat: no-repeat;
  filter: blur(2.5px);
  opacity: 0.28;
  z-index: -1;
  pointer-events: none;
  -webkit-mask-image:
    linear-gradient(to bottom, transparent 0%, black 25%, black 100%),
    radial-gradient(ellipse 50% 300% at center, black 30%, transparent 100%);
  mask-image:
    linear-gradient(to bottom, transparent 0%, black 25%, black 100%),
    radial-gradient(ellipse 50% 300% at center, black 30%, transparent 100%);
  -webkit-mask-composite: source-in, source-over;
  mask-composite: intersect;
}

/* Darker side bleed, scoped only to the footer (not the whole page),
   so it blends into the sky-blue tone of the background photo above.
   Sits behind the image layer (z-index -2 vs -1) so the photo itself
   stays fully visible where the two overlap — this only shows in the
   true overhang beyond the footer's own left/right edges. */
.contact::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: -50px;
  right: -50px;
  background: linear-gradient(180deg, #C1D9EC 0%, #A9C7E1 100%);
  filter: blur(40px);
  z-index: -2;
  pointer-events: none;
}

.contact-info {
  align-self: center;
  margin-top: -3.5rem;
}

.contact-info h2 {
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 500;
  margin-bottom: var(--space-xs);
  color: var(--color-text);
}

.contact-blurb {
  font-size: 0.9375rem;
  color: var(--color-text-muted);
  line-height: 1.6;
  margin-bottom: var(--space-sm);
  max-width: 32ch;
}

/* Non-clickable email: black/white by default, green underline on hover */
.contact-info .email {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.9375rem;
  color: var(--color-text);
  cursor: default;
  border-bottom: 1px solid transparent;
  transition: border-color 0.2s ease;
}

.contact-info .email:hover {
  border-color: var(--color-link);
}

.contact-form form {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.form-group {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.contact-form label {
  font-size: 0.8125rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-text-muted);
}

.contact-form input,
.contact-form textarea {
  font-family: var(--font-body);
  font-size: 0.9375rem;
  color: var(--color-text);
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--border-radius);
  padding: 0.7rem 0.9rem;
  resize: vertical;
}

.contact-form input:focus,
.contact-form textarea:focus {
  border-color: var(--color-accent);
  outline: none;
}

/* Monochrome submit button (black bg, white text) to match the
   black & white contact section */
.contact-form button {
  align-self: flex-start;
  font-family: var(--font-body);
  font-size: 0.875rem;
  font-weight: 600;
  color: #FAFAF8;
  background: var(--color-text);
  border: none;
  border-radius: var(--border-radius);
  padding: 0.7rem 1.4rem;
  cursor: pointer;
  transition: background-color 0.2s ease;
}

.contact-form button:hover {
  background: #3a3a3a;
}

/* ---------- Responsive ---------- */
@media (max-width: 640px) {
  :root {
    --space-lg: 2.5rem;
    --space-xl: 3.5rem;
    --space-2xl: 4rem;
  }

  .profile-text .name {
    font-size: 1.6rem;
  }

  .contact {
    grid-template-columns: 1fr;
  }

  .project-list {
    grid-template-columns: 1fr;
  }

  .project-card {
    flex-direction: column;
  }

  .project-image {
    width: 100%;
  }
}