/* Project overrides for the Unifex theme.
   Loaded after main.css so these win. Keep this file small — it only adapts
   the template to real, variable-length data from Supabase.

   Note: the theme's own responsive ladders for .banner-three-title,
   .banner-three-center-title and .banner-three-left-title are deliberately
   left alone. The hero prints a single word, exactly like the reference. */

/* ---------------------------------------------------------------
   Lenis smooth scroll (stands in for the theme's paid ScrollSmoother).
   Both bootstrap.min.css and main.css set `scroll-behavior: smooth` on html,
   which fights Lenis's programmatic scrolling — Lenis requires it off.
   --------------------------------------------------------------- */
html.lenis,
html.lenis body {
  height: auto;
  scroll-behavior: auto !important;
}

.lenis.lenis-smooth {
  scroll-behavior: auto !important;
}

.lenis.lenis-stopped {
  overflow: clip;
}

.lenis.lenis-smooth [data-lenis-prevent] {
  overscroll-behavior: contain;
}

.lenis.lenis-smooth iframe {
  pointer-events: none;
}

/* Nothing in this design should scroll sideways.
   `clip` rather than `hidden`: hidden turns html/body into a scroll container,
   which silently disables `position: sticky` for every descendant (that's what
   pins the "works" backdrop). */
html,
body {
  overflow-x: clip;
  max-width: 100%;
}

/* ---------------------------------------------------------------
   Hero portrait
   The reference cutout is a 705x827 PNG rendered at its natural size.
   Profile images are uploaded through the admin at arbitrary sizes, so
   pin them to the same box and let them scale down with the viewport.
   The element keeps the theme's `start-50 translate-middle-x` centring.
   --------------------------------------------------------------- */
/* ---------------------------------------------------------------
   Hero "what I do" list
   The theme's <li> is d-inline-flex, which only reads as one-per-line because
   its placeholder labels are long ("Branding & Identity"). Short skill names
   run together on a single line, so pin each to its own row.
   --------------------------------------------------------------- */
.banner-three-list ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Bootstrap's .d-inline-flex utility is !important, so this has to match it. */
.banner-three-list ul li {
  display: flex !important;
  width: 100%;
}

/* ---------------------------------------------------------------
   Hero word
   The reference word ("developer") happens to fill the container, so the
   theme leaves it left-aligned. Ours comes from the database and can be any
   length, so centre it — that keeps it balanced behind the portrait whether
   it's one line or wraps to two.
   --------------------------------------------------------------- */
.banner-three-title {
  text-align: center;
  overflow-wrap: break-word;
  hyphens: none;
  margin-inline: auto;
  max-width: 100%;
}

/* Two-line words need the block to breathe without shoving the portrait,
   which is anchored to the bottom of the wrapper. */
.banner-three-wrapper {
  min-height: 0;
}

/* ---------------------------------------------------------------
   Counter cards
   The theme pins them to 284px, which reads as cramped once they stack.
   --------------------------------------------------------------- */
@media screen and (max-width: 991px) {
  .about-three-wrap-shape {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
  }

  .about-three-wrap-shape .banner-three-counter-item {
    max-width: none;
    flex: 1 1 260px;
  }
}

@media screen and (max-width: 575px) {
  .about-three-wrap-shape .banner-three-counter-item,
  .banner-three-right .banner-three-counter-item {
    max-width: none;
    width: 100%;
    flex: 1 1 100%;
    margin-inline: 0;
  }

  /* The theme nudges the second card up to overlap; pointless when stacked. */
  .banner-three-counter-item:nth-child(2) {
    margin-block-start: 0;
  }
}

/* Sized against the viewport, not a fixed pixel box: the reference cutout is
   head-and-shoulders and narrow, but an uploaded portrait can be a full torso
   shot that would bury the hero word. Capping at a share of the viewport keeps
   the word readable either side of the subject at every width. */
.banner-three-man {
  width: min(705px, 44vw);
  pointer-events: none;
}

.banner-three-man img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 827px;
  margin-inline: auto;
  object-fit: contain;
  object-position: bottom center;
}

@media screen and (max-width: 1399px) {
  .banner-three-man {
    width: min(560px, 42vw);
  }
}

@media screen and (max-width: 991px) {
  .banner-three-man {
    width: min(430px, 42vw);
  }
}

@media screen and (max-width: 767px) {
  .banner-three-man {
    width: min(340px, 44vw);
  }
}

@media screen and (max-width: 575px) {
  .banner-three-man {
    width: min(270px, 46vw);
  }
}

/* ---------------------------------------------------------------
   Header logo — the name set in two tones
   --------------------------------------------------------------- */
.site-logo {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  line-height: 1;
  white-space: nowrap;
}

.site-logo-dark {
  color: hsl(var(--heading-color));
}

.site-logo-light {
  color: hsl(var(--white));
  background: hsl(var(--heading-color));
  padding: 6px 12px 8px;
  border-radius: 8px;
}

/* On the dark offcanvas panel the tones swap round. */
.site-logo-invert .site-logo-dark {
  color: hsl(var(--white));
}

.site-logo-invert .site-logo-light {
  color: hsl(var(--heading-color));
  background: hsl(var(--white));
}

/* ---------------------------------------------------------------
   Data-driven sections the theme sized for fixed placeholder content
   --------------------------------------------------------------- */

/* ---------------------------------------------------------------
   Tech stack slider — sits under the experience circle in About
   --------------------------------------------------------------- */
.skills-slide-viewport {
  overflow: hidden;
  width: 100%;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}

.skills-slide-item {
  flex: 0 0 auto;
  width: 118px;
  padding: 18px 10px;
  margin-inline-end: 12px;
  border-radius: 12px;
  background: #fff;
  box-shadow:
    0 4px 4px 0 rgba(0, 0, 0, 0.06),
    -4px -4px 0 0 rgba(255, 255, 255, 0.25);
}

.skills-slide-item img {
  width: 38px;
  height: 38px;
  object-fit: contain;
}

.skills-slide-fallback {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 8px;
  background: hsl(var(--main-two) / 0.12);
  color: hsl(var(--main-two));
  font-size: 18px;
}

@media screen and (max-width: 575px) {
  .skills-slide-item {
    width: 96px;
    padding: 14px 8px;
  }
}

/* ---------------------------------------------------------------
   Black buttons — orange sweep on hover ("download cv", "view projects")
   The theme animates .tw-hover-btn-circle-dot from 0 to 520px, but with
   `bottom: 0` plus `translate(-50%,-50%)` the grown disc is shifted up by half
   its own height and ends up above the button instead of flooding it.
   Anchor it to the bottom centre and scale from there.
   z-index stays -1 on purpose: inside .tw-hover-btn's stacking context that
   paints the disc above the button's background but below the label text,
   which is a bare text node we can't lift.
   --------------------------------------------------------------- */
.tw-hover-btn .tw-hover-btn-circle-dot {
  bottom: 0;
  left: 50%;
  width: 26px;
  height: 26px;
  transform: translate(-50%, 50%) scale(0);
  transform-origin: center;
  transition: transform 0.6s ease-out;
  z-index: -1;
}

.tw-hover-btn:hover .tw-hover-btn-circle-dot,
.tw-hover-btn:focus-visible .tw-hover-btn-circle-dot {
  width: 26px;
  height: 26px;
  transform: translate(-50%, 50%) scale(40);
}

/* ---------------------------------------------------------------
   Experience circle hover
   The theme grows .tw-btn-circle-dot from 63px to 820px, but with its
   translate(-50%,-50%) anchor that lands the grown dot above the circle
   instead of flooding it, so the label just turns white on white.
   Scale from a fixed anchor inside the circle instead — the circle's
   overflow:hidden + rounded-circle clip it to the disc.
   --------------------------------------------------------------- */
.about-three-counter .tw-btn-circle {
  background: #f5f5f5;
  isolation: isolate;
}

.about-three-counter .tw-btn-circle-dot,
.portfolio-three-counter .tw-btn-circle-dot {
  z-index: 0;
  left: 18%;
  bottom: 14%;
  width: 63px;
  height: 63px;
  transform: translate(-50%, 50%) scale(1);
  transform-origin: center;
  transition: transform 0.6s ease;
}

.about-three-counter:hover .tw-btn-circle-dot,
.portfolio-three-counter:hover .tw-btn-circle-dot {
  width: 63px;
  height: 63px;
  transform: translate(-50%, 50%) scale(16);
}

/* Keep the label above the flood. */
.about-three-counter .tw-btn-circle > span,
.portfolio-three-counter .tw-btn-circle > span {
  position: relative;
  z-index: 2;
}

/* ---------------------------------------------------------------
   "works" backdrop stays put while the project cards scroll past.
   Sticky with zero height so it pins itself without reserving space —
   more reliable than a ScrollTrigger pin on an absolute element.
   --------------------------------------------------------------- */
.portfolio-three-shape {
  position: sticky;
  top: 22vh;
  height: 0;
  z-index: 0;
  pointer-events: none;
  user-select: none;
  overflow: visible;
  text-align: center;
}

.portfolio-three-shape-title {
  margin: 0;
  line-height: 0.75;
  color: hsl(var(--heading-color));
  opacity: 0.08;
  white-space: nowrap;
}

/* Cards ride over the backdrop. */
.portfolio-three-area .portfolio-three-wrapper {
  position: relative;
  z-index: 2;
}

@media screen and (max-width: 991px) {
  .portfolio-three-shape-title {
    font-size: 30vw;
  }
}

/* Skill tiles need a consistent box since the icons vary. */
.brand-three-item {
  min-height: 150px;
  padding: 24px 12px;
}

/* Certificate slides: the theme assumes a fixed thumb, ours are uploads. */
.testimonial-three-thumb {
  flex: 0 0 auto;
  max-width: 380px;
}

.testimonial-three-thumb img {
  object-fit: cover;
}

@media screen and (max-width: 991px) {
  .testimonial-three-wrapper {
    flex-wrap: wrap;
  }

  .testimonial-three-thumb {
    max-width: 100%;
  }
}

/* Swiper pagination inherits the theme's accent. */
.testimonial-three-slider .swiper-pagination-bullet-active {
  background: hsl(var(--main-two));
}

/* Experience rows have no thumbnail, so let the content use the full row. */
.service-three-item .service-three-content {
  width: 100%;
}
