/* ==========================================================================
   Sections — page-level layout, in the order the sections appear.
   Theme toggle · hero · skills · about · stacks · projects · contact · footer
   ========================================================================== */

/* ── Theme toggle ───────────────────────────────────────────────────────── */
.theme-toggle,
.music-toggle {
  position: fixed;
  top: 1rem;
  z-index: 40;
}

.theme-toggle {
  right: 1rem;
}

/* Revealed by js/main.js only once the audio file is confirmed to load. */
.music-toggle {
  left: 1rem;
}

.music-toggle[hidden] {
  display: none;
}

/* On phones the two pinned buttons eat scarce screen edge, so let them sit in
   the document and scroll away with the hero instead of following the page.
   body is static, so absolute here resolves against the document origin. */
@media (max-width: 639px) {

  .theme-toggle,
  .music-toggle {
    position: absolute;
  }
}

/* Soft pulse while a track is playing. */
.music-toggle.is-playing .btn {
  color: var(--foreground);
}

.music-toggle.is-playing .btn::after {
  content: "";
  position: absolute;
  inset: 0;
  border: 1px solid color-mix(in oklab, var(--foreground) 35%, transparent);
  border-radius: inherit;
  animation: ping 1.8s cubic-bezier(0, 0, .2, 1) infinite;
}

.music-toggle .btn {
  position: relative;
}

.theme-toggle iconify-icon {
  transition: transform .3s cubic-bezier(.4, 0, .2, 1);
}

.theme-toggle .btn:hover iconify-icon {
  transform: rotate(18deg);
}

/* Class added for the duration of the switch by js/main.js. */
.theme-toggle .is-switching {
  animation: spin .4s cubic-bezier(.4, 0, .2, 1);
}

/* ── Hero ───────────────────────────────────────────────────────────────── */
.hero {
  position: relative;
  isolation: isolate;
  display: flex;
  min-height: 46vh;
  width: 100%;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  padding: 4rem 1.5rem 2rem;
  text-align: center;
}

/* Banner image, fading into the page background. */
.hero-bg {
  position: absolute;
  inset: 0;
  z-index: -1;
}

/* Two versions of the same ridgeline — night for dark, daylight for light.
   Applied as a background rather than an <img> so only the theme in use is
   ever downloaded. */
.hero-bg-img {
  position: absolute;
  inset: 0;
  background-image: url("../assets/hero-banner.jpg");
  background-position: center 62%;
  background-size: cover;
  background-repeat: no-repeat;
  opacity: .75;
}

.light .hero-bg-img {
  background-image: url("../assets/hero-banner-light.jpg");
  opacity: .9;
}

.hero-bg-fade {
  position: absolute;
  inset: 0;
  background-image: linear-gradient(to bottom,
      color-mix(in oklab, var(--background) 5%, transparent) 0%,
      color-mix(in oklab, var(--background) 80%, transparent) 55%,
      var(--background) 100%);
}

/* Dot grid over the banner, masked to a soft ellipse behind the name so it
   never reaches an edge. Same pattern as the empty-project placeholder — one
   motif, two uses. Kept faint so it reads as texture, not a second subject.
   Sits above .hero-bg (both z-index -1) but below the hero content. */
.hero::after {
  content: "";
  pointer-events: none;
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: radial-gradient(color-mix(in oklab, var(--foreground) 18%, transparent) 1px, transparent 1px);
  background-size: 22px 22px;
  opacity: .22;
  -webkit-mask-image: radial-gradient(ellipse 45% 42% at 50% 38%, #000 0%, transparent 72%);
  mask-image: radial-gradient(ellipse 45% 42% at 50% 38%, #000 0%, transparent 72%);
}

.avatar-wrap {
  position: relative;
  margin-bottom: 1rem;
}

.avatar-glow {
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: 3rem;
  background-color: color-mix(in oklab, var(--foreground) 10%, transparent);
  transform: scale(1.05);
  filter: blur(32px);
}

.avatar-ring {
  position: absolute;
  inset: -.5rem;
  border: 1px dashed color-mix(in oklab, var(--foreground) 20%, transparent);
  border-radius: 9999px;
  animation: spin 16s linear infinite;
}

.avatar {
  position: relative;
  height: 5rem;
  width: 5rem;
  overflow: hidden;
  border: 2px solid var(--background);
  border-radius: 9999px;
  background-color: var(--muted);
  box-shadow: var(--shadow-lg), 0 0 0 1px color-mix(in oklab, var(--border) 60%, transparent);
  transition: transform .2s ease, box-shadow .2s ease;
}

.avatar img {
  height: 100%;
  width: 100%;
  object-fit: cover;
  filter: grayscale(1);
  transition: filter .3s ease;
}

.avatar-wrap:hover .avatar {
  transform: scale(1.1);
  box-shadow: var(--shadow-lg), 0 0 0 1px color-mix(in oklab, var(--foreground) 30%, transparent);
}

.avatar-wrap:hover .avatar img {
  filter: grayscale(0);
}

.hero-name {
  font-size: 1.875rem;
  font-weight: 700;
  line-height: 2.25rem;
  letter-spacing: -.025em;
}

.hero-role {
  margin-top: .375rem;
  color: var(--muted-foreground);
  font-size: .875rem;
}

.hero-actions {
  margin-top: 1.25rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: .5rem;
}

.hero-socials {
  margin-left: .25rem;
  display: flex;
  align-items: center;
  gap: .125rem;
}

@media (min-width: 640px) {
  .hero-name {
    font-size: 2.25rem;
    line-height: 2.5rem;
  }

  .hero-role {
    font-size: 1rem;
  }
}

/* ── Skills ─────────────────────────────────────────────────────────────── */
.skills {
  width: 100%;
  padding: 0 1.5rem;
}

.skills-row {
  margin: 0 auto;
  display: flex;
  width: fit-content;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: .375rem;
}

.skill {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: .375rem;
  border-radius: var(--radius-md);
  cursor: default;
  transition: background-color .15s ease;
}

.skill:hover {
  background-color: var(--muted);
}

.skill iconify-icon {
  font-size: 1.75rem;
  transition: transform .2s ease;
}

.skill:hover iconify-icon {
  transform: translateY(-2px);
}

/* ── About ──────────────────────────────────────────────────────────────── */
.about {
  margin: 0 auto;
  width: 100%;
  max-width: 36rem;
  padding: 3rem 1.5rem;
  text-align: center;
}

.about p {
  font-size: .875rem;
  line-height: 1.7;
}

.about .em {
  color: var(--foreground);
  font-weight: 600;
}

@media (min-width: 640px) {
  .about p {
    font-size: 1rem;
  }
}

/* ── Stacked panels (education, experience) ─────────────────────────────── */
.stack-section {
  margin: 0 auto;
  width: fit-content;
  max-width: min(100%, 39rem);
  padding: 1.5rem;
}

/* ── Projects ───────────────────────────────────────────────────────────── */
.projects {
  margin: 0 auto;
  width: 100%;
  max-width: 64rem;
  padding: 3rem 1.5rem;
}

.project-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
}

@media (min-width: 640px) {
  .project-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1024px) {
  .project-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* Shown by js/main.js only when there are more cards than fit the grid. */
.projects-more {
  margin-top: 1rem;
  display: flex;
  justify-content: center;
}

.projects-more[hidden] {
  display: none;
}

.projects-more iconify-icon {
  transition: transform .3s ease;
}

.projects-more.is-open iconify-icon {
  transform: rotate(180deg);
}

/* ── Contact ────────────────────────────────────────────────────────────── */
.contact {
  margin: 0 auto;
  width: 100%;
  max-width: 42rem;
  padding: 1.5rem;
}

/* Uses the same .panel shell as Education / Experience / Projects — border,
   radius, fill and notched label all come from there. Only the padding and
   centring are specific to this one. */
/* No overflow:hidden here — the notched .panel-label sits above the top edge
   and would be clipped. The blobs are already clipped by .panel-blobs. */
.panel-contact {
  padding: 2.5rem 1.5rem 2rem;
  text-align: center;
}

.status-pill {
  display: inline-flex;
  align-items: center;
  gap: .375rem;
  padding: .25rem .75rem;
  border: 1px solid color-mix(in oklab, var(--border) 40%, transparent);
  border-radius: 9999px;
  color: var(--muted-foreground);
  font-size: 11px;
}

.ping {
  position: relative;
  display: flex;
  height: .375rem;
  width: .375rem;
}

.ping-wave {
  position: absolute;
  display: inline-flex;
  height: 100%;
  width: 100%;
  border-radius: 9999px;
  background-color: var(--foreground);
  opacity: .6;
  animation: ping 1s cubic-bezier(0, 0, .2, 1) infinite;
}

.ping-dot {
  position: relative;
  display: inline-flex;
  height: .375rem;
  width: .375rem;
  border-radius: 9999px;
  background-color: var(--foreground);
}

.contact-title {
  margin-top: 1rem;
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -.025em;
}

.contact-title span {
  color: var(--muted-foreground);
}

.contact-sub {
  margin: .75rem auto 0;
  max-width: 24rem;
  color: var(--muted-foreground);
  font-size: .75rem;
  line-height: 1.6;
}

.contact-actions {
  margin-top: 1.75rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
}

@media (min-width: 640px) {
  .panel-contact {
    padding: 3.5rem 3rem 3rem;
  }

  .contact-title {
    font-size: 2.25rem;
  }

  .contact-sub {
    font-size: .875rem;
  }
}

/* ── Footer ─────────────────────────────────────────────────────────────── */
.footer {
  padding: 2rem 1.5rem 3rem;
  color: var(--muted-foreground);
  font-size: .75rem;
  text-align: center;
}
