/* ==========================================================================
   Home page
   ========================================================================== */

.hero {
  position: relative;
  overflow: hidden;
  background: var(--color-bg);
}

.hero__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  will-change: transform;
}

.hero__bg-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  transition: opacity 0.5s ease;
}

/* Hidden until js/main.js confirms WebGL is available and the first
   distorted frame has rendered; the plain video above stays the visible
   fallback otherwise (no JS, no WebGL, coarse/touch pointer, reduced
   motion). See initHeroRipple() in main.js. */
.hero__bg-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity 0.5s ease;
}

.hero__bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(to bottom, transparent 78%, var(--color-bg) 100%),
    radial-gradient(60% 70% at 78% 15%, rgba(255, 170, 210, 0.25), transparent 70%);
}

.hero__content {
  position: relative;
  z-index: 1;
  min-height: 80vh;
  padding-block: clamp(72px, 11vw, 128px) clamp(56px, 9vw, 96px);
  display: flex;
  flex-direction: column;
  justify-content: center;
  will-change: transform, opacity;
}

@media (prefers-reduced-motion: reduce) {
  .hero__content {
    transform: none !important;
    opacity: 1 !important;
  }
}

.hero__title {
  max-width: 936px;
  font-weight: 800;
  font-size: var(--fs-h1);
  line-height: 1.17;
  animation: hero-title-in 1s cubic-bezier(0.16, 1, 0.3, 1) both;
}

/* Manual break before "I provide" — off everywhere by default, since the
   natural wrap already looks right outside the 1440-1920px band. */
.hero__title-break {
  display: none;
}

/* 1440-1920px specifically: force "I provide ..." onto its own line. This
   sits inside the shared 641px+ desktop block below, so it inherits that
   block's fixed 50px title size and centered column — it just adds the
   extra break on top for this one width band. */
@media (min-width: 1440px) and (max-width: 1920px) {
  .hero__title-break {
    display: inline;
  }
}

@keyframes hero-title-in {
  from {
    opacity: 0;
    transform: translateY(22px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero__title {
    animation: none;
  }
}

.hero__hint {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: clamp(28px, 5vw, 43px);
  font-size: var(--fs-body);
  text-decoration: none;
  cursor: pointer;
  width: fit-content;
  transition: opacity 0.2s ease, transform 0.2s ease;
}

.hero__hint:hover {
  opacity: 0.7;
  transform: translateY(2px);
}

.divider {
  height: 4px;
  background: var(--color-ink);
}

/* ---------- Works grid ---------- */

.works {
  padding-block: clamp(40px, 6vw, 48px);
}

.works__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 24px;
}

.work-card {
  position: relative;
  display: block;
  aspect-ratio: 696 / 392;
  border-radius: 0;
  overflow: hidden;
  text-decoration: none;
  color: var(--color-white);
  background: linear-gradient(135deg, #6a5a7a, #2a2038);
  isolation: isolate;
  transition: border-radius 0.3s ease, opacity 0.8s cubic-bezier(0.16, 1, 0.3, 1), transform 0.8s cubic-bezier(0.16, 1, 0.3, 1);
}

/* Added by JS right before observing each card, so the hidden-then-reveal
   state only ever exists when the reveal script actually runs — with JS off
   (or failing) the cards are just visible by default, no dependency. */
.work-card.pre-reveal {
  opacity: 0;
  transform: translateY(56px) scale(0.98);
}

@media (prefers-reduced-motion: reduce) {
  .work-card.pre-reveal {
    opacity: 1;
    transform: none;
  }
}

.work-card__cover {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
  transition: transform 0.4s ease;
}

.work-card__overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: var(--color-overlay);
}

.work-card__title {
  position: absolute;
  z-index: 2;
  left: 50%;
  bottom: clamp(20px, 6%, 32px);
  transform: translateX(-50%);
  width: 88%;
  text-align: center;
  font-weight: 700;
  font-size: var(--fs-card-title);
  line-height: 1.25;
}

.work-card__badge {
  position: absolute;
  z-index: 2;
  top: 16px;
  right: 16px;
  padding: 6px 14px;
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, 0.15);
  backdrop-filter: blur(6px);
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

a.work-card:hover {
  border-radius: 48px;
}

a.work-card:hover .work-card__cover {
  transform: scale(1.04);
}

.work-card--soon {
  cursor: default;
  pointer-events: none;
}

.work-card--soon .work-card__title {
  opacity: 0.9;
}

/* ---------- About me ---------- */

.about {
  position: relative;
  overflow: hidden;
  padding-block: clamp(84px, 15vw, 144px) clamp(108px, 18vw, 192px);
}

.about__glow {
  position: absolute;
  z-index: 0;
  border-radius: 50%;
  filter: blur(70px);
  pointer-events: none;
}

.about__glow--one {
  width: 440px;
  height: 440px;
  left: 2%;
  bottom: 6%;
  background: radial-gradient(circle, rgba(255, 200, 150, 0.45), transparent 70%);
  animation: float-glow-one 11s ease-in-out infinite;
}

.about__glow--two {
  width: 440px;
  height: 440px;
  left: 10%;
  top: 6%;
  background: radial-gradient(circle, rgba(180, 210, 255, 0.4), transparent 70%);
  animation: float-glow-two 13s ease-in-out infinite;
}

@keyframes float-glow-one {
  0%,
  100% {
    transform: translate(0, 0);
  }
  50% {
    transform: translate(16px, -14px);
  }
}

@keyframes float-glow-two {
  0%,
  100% {
    transform: translate(0, 0);
  }
  50% {
    transform: translate(-14px, 16px);
  }
}

.about__inner {
  position: relative;
  z-index: 1;
}

.about__title {
  font-weight: 800;
  font-size: var(--fs-h1);
  margin-bottom: clamp(32px, 6vw, 56px);
}

.about__content {
  display: grid;
  grid-template-columns: 304px 1fr;
  gap: clamp(24px, 5vw, 56px);
  align-items: start;
}

.about__portrait {
  width: 304px;
  max-width: 100%;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  border: 4px solid var(--color-ink);
  overflow: hidden;
  background: linear-gradient(135deg, #d9c8b8, #b79a86);
}

.about__portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.about__text p {
  margin-bottom: 16px;
}

.about__text p:last-child {
  margin-bottom: 0;
}

.about__text a {
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ---------- Large screens ---------- */

/* Every desktop width above the mobile breakpoint (not just 1920px+) gets
   this treatment: the title+hint column (.hero__inner) narrows to 70% of
   the container and that whole column sits centered in the working area —
   but the text and the hint link inside it both stay flush left against the
   column's own left edge (auto margins center the column itself; nothing
   here centers the text or the hint independently, so they naturally line
   up with each other). The title is fixed at 50px instead of scaling with
   viewport width, so it reads noticeably smaller/tighter than the old
   flush-left, full-width layout on any laptop/desktop screen under 1920px.
   Section height is capped at 80vh. */
@media (min-width: 641px) {
  .hero__content {
    min-height: 80vh;
  }

  .hero__inner {
    width: 70%;
    margin-inline: auto;
  }

  .hero__title {
    max-width: none;
    text-align: left;
    font-size: 50px;
  }

  .hero__hint {
    margin-inline: 0;
  }
}

/* Past 2560px (QHD and up) a narrowed, centered column looks lost in the
   middle of an ultra-wide screen, so the title goes back to sitting flush
   left against the working area — like the base layout — with a modestly
   larger size. Section height stays at the same 80% used at 1920px. */
@media (min-width: 2560px) {
  .hero__content {
    align-items: flex-start;
    min-height: 80vh;
  }

  .hero__inner {
    width: auto;
    margin-inline: 0;
  }

  .hero__title {
    max-width: 936px;
    text-align: left;
    font-size: 56px;
  }

  .hero__hint {
    margin-inline: 0;
  }
}

/* ---------- Responsive ---------- */

@media (max-width: 1024px) {
  .about__content {
    grid-template-columns: 220px 1fr;
  }

  .about__portrait {
    width: 220px;
  }
}

@media (max-width: 860px) {
  .works__grid {
    grid-template-columns: 1fr;
  }

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

  .about__portrait {
    width: 180px;
  }
}

@media (max-width: 640px) {
  .hero__content {
    min-height: 80vh;
    padding-block: 88px 48px;
  }

  .hero__title {
    font-size: clamp(34px, 9.75vw, 40px);
  }

  .work-card {
    aspect-ratio: 4 / 3;
  }

  .about__portrait {
    width: 100%;
    aspect-ratio: 1 / 1;
    border-radius: 50%;
    border: 4px solid var(--color-ink);
  }
}
