/* ============================================================
   Hero Section
   ============================================================ */

.hero {
  --hero-paper-height: calc(max(100vw / 1.6, 100dvh) * 0.085);
  --hero-title-font: clamp(4rem, 9vw, 8rem);
  position: relative;
  width: 100%;
  min-height: 100vh;
  min-height: 100svh;
  min-height: 104dvh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  background-color: var(--color-bg);
}

.hero__background {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center bottom;
  pointer-events: none;
}

.hero__content {
  container-type: inline-size;
  position: relative;
  z-index: 1;
  padding: 0 var(--space-lg);
  padding-top: 6rem;
  max-width: var(--max-width);
  width: 100%;
  margin: 0 auto;
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
}

.hero__greeting-container {
  position: relative;
  display: inline-block;
  margin-bottom: var(--space-lg);
  margin-left: 1%;
  width: 15%;
  /* Resting transform, overridden per-breakpoint below; the entrance
     animation reads this var so it never fights a responsive offset. */
  transform: var(--hero-greeting-rest, translateY(0));
}

/* Spring keyframes – button width (gentle single overshoot) */
@keyframes greeting-button-spring {
  0% {
    width: 145px;
  }
  60% {
    width: 224px;
  }
  80% {
    width: 215px;
  }
  100% {
    width: 218px;
  }
}

/* Same spring curve, wider end value – fits the longer German hover text
   ("ICH BIN VIKTOR WILHELM") with the same ~24px left/right padding as the
   English pill. English is untouched; this only applies under lang="de". */
@keyframes greeting-button-spring-de {
  0% {
    width: 145px;
  }
  60% {
    width: 274px;
  }
  80% {
    width: 265px;
  }
  100% {
    width: 268px;
  }
}

html[lang="de"] .hero__greeting-container:hover .hero__greeting {
  animation-name: greeting-button-spring-de;
}

/* Hand keyframes – starts upside-down, rotates 112.5deg clockwise to final position */
@keyframes greeting-hand-spin {
  0% {
    transform: translateX(0) rotate(-112.5deg);
    opacity: 0;
  }
  10% {
    opacity: 1;
  }
  60% {
    transform: translateX(79px) rotate(5deg);
    opacity: 1;
  }
  80% {
    transform: translateX(70px) rotate(-3deg);
    opacity: 1;
  }
  100% {
    transform: translateX(73px) rotate(0deg);
    opacity: 1;
  }
}

/* Same spin, shifted further right by the same 50px the German pill gains
   (268px vs 218px), so the hand still lands at the pill's right edge. */
@keyframes greeting-hand-spin-de {
  0% {
    transform: translateX(0) rotate(-112.5deg);
    opacity: 0;
  }
  10% {
    opacity: 1;
  }
  60% {
    transform: translateX(129px) rotate(5deg);
    opacity: 1;
  }
  80% {
    transform: translateX(120px) rotate(-3deg);
    opacity: 1;
  }
  100% {
    transform: translateX(123px) rotate(0deg);
    opacity: 1;
  }
}

/* Wave hand – fixed at right edge, rotates into view from upside-down */
.hero__greeting-icon {
  position: absolute;
  bottom: 100%;
  left: 99px;
  height: 40px;
  width: 40px;
  display: block;
  transform-origin: center center;
  transform: translateX(0) rotate(-112.5deg);
  opacity: 0;
  pointer-events: none;
}

.hero__greeting-container:hover .hero__greeting-icon {
  animation: greeting-hand-spin 900ms ease forwards;
}

html[lang="de"] .hero__greeting-container:hover .hero__greeting-icon {
  animation-name: greeting-hand-spin-de;
}

/* Pill button – grows only in X+ direction with spring */
.hero__greeting {
  position: relative;
  display: inline-flex;
  align-items: center;
  width: 145px;
  height: 40px;
  padding: 12px 24px;
  border-radius: 100px;
  border: 1.5px solid var(--color-off-white);
  white-space: nowrap;
  overflow: hidden;
  box-sizing: border-box;

  transition: border-color 300ms ease;
}

.hero__greeting-container:hover .hero__greeting {
  animation: greeting-button-spring 800ms ease forwards;
  border-color: var(--color-off-white);
}

/* Blue fill – right is already full, unfolds to the left */
.hero__greeting::before {
  content: "";
  position: absolute;
  inset: 0;
  background-color: var(--color-blue);
  border-radius: 100px;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 80ms ease-out;
}

.hero__greeting-container:hover .hero__greeting::before {
  transform: scaleX(1);
}

/* Text layers – fixed at left edge, never move */
.hero__greeting-text--default,
.hero__greeting-text--hover {
  position: absolute;
  z-index: 1;
  top: 50%;
  left: 24px;
  transform: translateY(-50%);
  white-space: nowrap;
  font-family: var(--font-base);
  font-weight: 500;
  font-style: normal;
  font-size: 1.125rem;
  line-height: 1.2;
  letter-spacing: 0;
  color: var(--color-text-light);
}

.hero__greeting-text--default {
  opacity: 1;
  transition: opacity 250ms ease;
}

.hero__greeting-text--hover {
  opacity: 0;
  transition: opacity 250ms ease;
}

.hero__greeting-container:hover .hero__greeting-text--default {
  opacity: 0;
}

.hero__greeting-container:hover .hero__greeting-text--hover {
  opacity: 1;
  transition: opacity 250ms ease;
}

/* Wraps title + polaroid so the polaroid can be anchored to the title's
   own box on desktop. Transparent to layout everywhere else so it doesn't
   affect the existing flex order on mobile/tablet. */
.hero__title-wrap {
  display: contents;
}

/* "Frontend DEVELOPER" – two-line heading */
.hero__title {
  line-height: 1;
  margin-bottom: var(--space-lg);
  width: 100%;
  margin-left: 1%;
}

.hero__title-top {
  display: block;
  font-size: var(--hero-title-font);
  font-weight: 700;
  color: var(--color-text-light);
  letter-spacing: -0.1em;
  text-align: left;
  transform: translateY(-1rem);
}

.hero__title-bottom {
  display: flex;
  justify-content: flex-start;
  align-items: baseline;
  font-size: var(--hero-title-font);
  font-weight: 700;
  color: var(--color-text-light);
  letter-spacing: -0.1em;
  text-transform: uppercase;
  margin-left: 0;
  white-space: nowrap;
}

/* Letter hover effect */
.hero__title-letter {
  display: inline-block;
  box-sizing: border-box;
  padding-inline: 0.04em;
  text-align: center;
  transform-origin: bottom center;
  position: relative;
  will-change: transform, width;
  transition:
    transform 820ms cubic-bezier(0.22, 1, 0.36, 1),
    width 820ms cubic-bezier(0.22, 1, 0.36, 1);
  cursor: default;
}

/* Normal char – fades out on hover */
.hero__title-letter__normal {
  display: inline-block;
  pointer-events: none;
  transition: opacity 540ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* Hover char – sits on top, fades in on hover */
.hero__title-letter__hover {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  text-align: center;
  opacity: 0;
  color: #f7c518;
  text-transform: none;
  pointer-events: none;
  transition: opacity 540ms cubic-bezier(0.22, 1, 0.36, 1);
}

.hero__title-letter--active .hero__title-letter__normal {
  opacity: 0;
  transition: opacity 540ms cubic-bezier(0.22, 1, 0.36, 1);
}

.hero__title-letter--active .hero__title-letter__hover {
  opacity: 1;
  transition: opacity 540ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* Frontend + Developer: letters stay on baseline */
.hero__title-top .hero__title-letter--active,
.hero__title-bottom .hero__title-letter--active {
  transform: scale(1);
}

/* Frontend: slower width transition so trailing letters glide left more gently */
.hero__title-top .hero__title-letter {
  transition:
    transform 820ms cubic-bezier(0.22, 1, 0.36, 1),
    width 1000ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* Frontend: lowercase letters grow */
.hero__title-top .hero__title-letter--lower {
  transition:
    transform 820ms cubic-bezier(0.22, 1, 0.36, 1),
    width 1000ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* Frontend: uppercase letters shrink */
.hero__title-top .hero__title-letter--upper {
  transition:
    transform 820ms cubic-bezier(0.22, 1, 0.36, 1),
    width 1000ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* Developer: lowercase letters grow */
.hero__title-bottom .hero__title-letter--lower {
  transition:
    transform 820ms cubic-bezier(0.22, 1, 0.36, 1),
    width 820ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* Developer: uppercase letters shrink */
.hero__title-bottom .hero__title-letter--upper {
  transition:
    transform 820ms cubic-bezier(0.22, 1, 0.36, 1),
    width 820ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* Developer: all letters slide right together when hovering last letter "r" */
.hero__title-bottom--r-hover .hero__title-letter,
.hero__title-bottom--r-hover .hero__title-letter--active {
  transform: translateX(1.5rem);
  transition: transform 1100ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* CTA Button */
.hero__cta {
  align-self: flex-end;
  margin-right: 7.5rem;
  min-width: 156px;
  width: auto;
  padding: 0 1rem;
  height: 44px;
  transform: translate(0, 0);
  transition: transform 90ms ease-in;
  box-shadow: inset 0 0 0 1px var(--color-off-white);
  -webkit-user-drag: none;
}

/* Default PNG – fades out on hover */
.hero__cta-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border-radius: 100px;
  transition: opacity 80ms ease-in;
  -webkit-user-drag: none;
}

.hero__cta:hover .hero__cta-img {
  opacity: 0;
}

/* Orange fill – snaps in on hover */
.hero__cta::after {
  z-index: 0;
}

.hero__cta:hover::after {
  box-shadow: inset 0 0 0 1px var(--color-off-white);
}

/* Text – hidden in default (text baked into PNG), visible on hover for i18n */
.hero__cta-text {
  position: relative;
  z-index: 1;
  white-space: nowrap;
  font-family: var(--font-base);
  font-weight: 500;
  font-size: 1.125rem;
  line-height: 1.2;
  color: var(--color-text-light);
  opacity: 0;
  transition: opacity 80ms ease-in;
}

.hero__cta:hover .hero__cta-text {
  opacity: 1;
}

/* German: hide baked-in PNG text, always show translated span */
[lang="de"] .hero__cta-img {
  opacity: 0;
  pointer-events: none;
}

[lang="de"] .hero__cta {
  box-shadow:
    inset 0 0 0 1px var(--color-off-white),
    3px 3.5px 0 0 var(--color-off-white);
}

[lang="de"] .hero__cta:hover {
  box-shadow: inset 0 0 0 1px var(--color-off-white);
}

[lang="de"] .hero__cta-text {
  opacity: 1;
}

/* Social Media Links */
.hero__social {
  position: absolute;
  left: var(--space-lg);
  display: none;
  flex-direction: column;
  gap: 0.5rem;
  z-index: 2;
  bottom: calc(var(--hero-paper-height) + 3rem);
}

.hero__social-link {
  display: block;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  overflow: hidden;
  position: relative;
  cursor: pointer;
  -webkit-user-drag: none;
}

.hero__social-icon {
  width: 40px;
  height: 40px;
  display: block;
  -webkit-user-drag: none;
}

.hero__social-link::after {
  content: "";
  position: absolute;
  inset: 0;
  background-color: var(--color-blue);
  border-radius: 50%;
  transform: scaleY(0);
  transform-origin: top center;
  transition: none;
}

.hero__social-link:hover::after {
  transform: scaleY(1);
  mix-blend-mode: screen;
}

@keyframes social-wipe-out {
  from {
    transform: scaleY(1);
  }
  to {
    transform: scaleY(0);
  }
}

.hero__social-link--leaving::after {
  transform-origin: bottom center;
  animation: social-wipe-out 200ms ease forwards;
  mix-blend-mode: normal;
  transition: none;
}

/* Polaroid Photo */
.hero__polaroid {
  display: block;
  position: relative;
  margin: var(--space-lg) auto;
  /* Resting transform, overridden per-breakpoint below; the entrance
     animation reads this var so it never fights a responsive offset. */
  transform: var(--hero-polaroid-rest, rotate(8deg));
  width: fit-content;
  z-index: 1;
  -webkit-user-drag: none;
}

.hero__polaroid-frame {
  display: block;
  width: 200px;
  height: 237px;
  object-fit: cover;
  opacity: 1;
  position: relative;
  z-index: 1;
  pointer-events: none;
  -webkit-user-drag: none;
}

.hero__polaroid-photo {
  position: absolute;
  top: 6%;
  left: 6%;
  width: 88%;
  height: 70%;
  object-fit: cover;
  filter: grayscale(100%);
  transition: filter 500ms ease;
  -webkit-user-drag: none;
}

@keyframes photo-color-spring {
  0% {
    filter: grayscale(100%) saturate(1) brightness(1);
  }
  40% {
    filter: grayscale(0%) saturate(1.8) brightness(0.82);
  }
  58% {
    filter: grayscale(15%) saturate(0.9) brightness(0.96);
  }
  72% {
    filter: grayscale(0%) saturate(1.5) brightness(0.85);
  }
  86% {
    filter: grayscale(8%) saturate(1.05) brightness(0.93);
  }
  100% {
    filter: grayscale(0%) saturate(1.2) brightness(0.88);
  }
}

.hero__polaroid:hover .hero__polaroid-photo {
  animation: photo-color-spring 700ms ease forwards;
}

@keyframes caption-spring {
  0% {
    transform: translateX(0);
    opacity: 0;
  }
  15% {
    transform: translateX(0);
    opacity: 1;
  }
  35% {
    transform: translateX(-1.5px);
    opacity: 1;
  }
  55% {
    transform: translateX(1.25px);
    opacity: 1;
  }
  72% {
    transform: translateX(-0.75px);
    opacity: 1;
  }
  86% {
    transform: translateX(0.5px);
    opacity: 1;
  }
  100% {
    transform: translateX(0);
    opacity: 1;
  }
}

.hero__polaroid-caption {
  position: absolute;
  bottom: 6%;
  left: 0;
  right: 0;
  text-align: center;
  font-family: "Kalam", cursive;
  font-weight: 700;
  font-style: normal;
  font-size: 24px;
  line-height: 120%;
  color: var(--color-text-dark);
  pointer-events: none;
  z-index: 2;
  transition: opacity 300ms ease;
}

.hero__polaroid-caption--default {
  opacity: 1;
}

.hero__polaroid-caption--hover {
  opacity: 0;
}

.hero__polaroid:hover .hero__polaroid-caption--default {
  opacity: 0;
}

.hero__polaroid:hover .hero__polaroid-caption--hover {
  animation: caption-spring 600ms ease forwards;
}

@media (min-width: 620px) {
  .hero__social {
    display: flex;
  }
}

@media (max-width: 767px) {
  .hero__content {
    padding-left: 1rem;
    padding-right: 1rem;
  }

  .hero__title {
    margin-left: -4px;
  }

  .hero__title-top,
  .hero__title-bottom {
    font-size: clamp(3rem, calc(100cqw / 6), 4rem);
  }

  .hero__polaroid {
    order: 1;
  }

  .hero__cta {
    margin-right: 0;
  }
}

@media (max-width: 540px) {
  .hero__content {
    padding-top: calc(1rem + clamp(0rem, 2svh, 2rem));
  }

  .hero__greeting-container {
    margin-bottom: clamp(0.5rem, 2svh, 1.5rem);
  }

  .hero__title {
    margin-bottom: clamp(0.5rem, 2svh, 1.5rem);
  }

  .hero__polaroid {
    margin: clamp(1.5rem, 5svh, 3.5rem) auto 0;
  }
}

/* Short mobile/tablet viewports (e.g. landscape phones): the stacked
   content overflows a 600px-tall viewport and the polaroid + social
   icons get clipped at the bottom, so shift the whole composition up
   as one block instead of retuning each element's own spacing. */
@media (max-width: 767px) and (max-height: 600px) {
  .hero__content,
  .hero__social {
    transform: translateY(-3rem);
  }
}

/* 541–767px is between the compact ≤540px spacing and the 768px+
   desktop layout, so on short viewports it still uses the roomy base
   spacing and the composition doesn't fit above the fold. Reuse the
   same svh-based compact spacing as the ≤540px rule above. */
@media (min-width: 541px) and (max-width: 767px) and (max-height: 600px) {
  .hero__content {
    padding-top: calc(1rem + clamp(0rem, 2svh, 2rem));
  }

  .hero__greeting-container {
    margin-bottom: clamp(0.5rem, 2svh, 1.5rem);
  }

  .hero__title {
    margin-bottom: clamp(0.5rem, 2svh, 1.5rem);
  }

  .hero__polaroid {
    margin: clamp(1.5rem, 5svh, 3.5rem) auto 0;
  }
}

/* 621–767px specifically: fine-tune around the shared -3rem shift
   above. The social nav isn't part of .hero__content (it's a sibling
   <nav>), so it only ever had its own -3rem transform, not the
   parent's — cancel it here and let the nav fall back to its default
   bottom-anchored position (~3rem above the hero's bottom edge).
   Greeting+title and the polaroid get their own extra transform on
   top of the inherited -3rem from .hero__content; .hero__cta is left
   untouched so it keeps exactly its current position. */
@media (min-width: 621px) and (max-width: 767px) and (max-height: 600px) {
  .hero__social {
    transform: none;
  }

  .hero__greeting-container {
    --hero-greeting-rest: translateY(1rem);
  }

  .hero__title-top {
    transform: translateY(0);
  }

  .hero__title-bottom {
    transform: translateY(1rem);
  }

  .hero__polaroid {
    --hero-polaroid-rest: translateY(-1rem) rotate(8deg);
  }
}

@media (min-width: 768px) {
  .hero__content {
    padding-top: 0;
    padding-left: 10rem;
    justify-content: center;
    top: -40px;
  }

  .hero__title {
    width: 87%;
  }

  .hero__title-bottom {
    justify-content: flex-end;
    margin-left: 10rem;
  }

  .hero__title-wrap {
    display: block;
    position: relative;
  }

  .hero__polaroid {
    position: absolute;
    right: clamp(1.25rem, calc(43vw - 286px), 16%);
    bottom: 100%;
    margin: 0 0 calc(var(--hero-title-font) * -0.8125);
  }

  .hero__social {
    left: max(var(--space-lg), calc((100% - var(--max-width)) / 2 - 48px));
  }
}

@media (min-width: 768px) and (max-height: 650px) {
  .hero__content {
    top: 0;
    justify-content: flex-start;
    /* Enough room for the polaroid (anchored above the title, see the
       min-width:768px rule) to clear the header without touching it. */
    padding-top: max(2rem, calc(230px - var(--hero-title-font) * 0.8125));
  }

  .hero__greeting-container {
    margin-bottom: 1rem;
  }

  .hero__title {
    margin-bottom: 1rem;
  }

}

/* ── Entrance animation (page load only) ─────────────────────
   Own keyframes, not AOS — plays once on load via CSS `animation`
   (`animation-fill-mode: both`), never re-triggers on scroll since
   nothing here is scroll-driven. Title, CTA and social links have no
   competing static transform, so they slide+fade directly. Greeting
   and polaroid DO carry a per-breakpoint resting transform (see
   --hero-greeting-rest / --hero-polaroid-rest above), so their
   keyframes read that var and append the entrance offset on top of it
   instead of overwriting it — the animation's end state always
   matches whatever the current breakpoint's static position is.
   Skipped entirely under prefers-reduced-motion. */
@media (prefers-reduced-motion: no-preference) {
  .hero__greeting-container {
    animation: hero-enter-greeting 900ms ease-out both;
  }

  .hero__title {
    animation: hero-enter-up 900ms ease-out 150ms both;
  }

  .hero__cta {
    animation: hero-enter-up 900ms ease-out 300ms backwards;
  }

  .hero__polaroid {
    animation: hero-enter-polaroid 900ms ease-out 450ms both;
  }

  .hero__social-link:nth-child(1) {
    animation: hero-enter-up 900ms ease-out 600ms both;
  }

  .hero__social-link:nth-child(2) {
    animation: hero-enter-up 900ms ease-out 630ms both;
  }

  .hero__social-link:nth-child(3) {
    animation: hero-enter-up 900ms ease-out 660ms both;
  }
}

@keyframes hero-enter-up {
  from {
    opacity: 0;
    transform: translateY(48px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes hero-enter-greeting {
  from {
    opacity: 0;
    transform: var(--hero-greeting-rest, translateY(0)) translateY(48px);
  }
  to {
    opacity: 1;
    transform: var(--hero-greeting-rest, translateY(0));
  }
}

@keyframes hero-enter-polaroid {
  from {
    opacity: 0;
    transform: var(--hero-polaroid-rest, rotate(8deg)) translateY(48px) scale(0.95);
  }
  to {
    opacity: 1;
    transform: var(--hero-polaroid-rest, rotate(8deg)) scale(1);
  }
}
