/* ==========================================================================
   Kllakar interaction layer (2026-09-30)
   Sits on top of the approved design. It does not change colors, type or
   layout intent: it adds blur reveals, the marble image hover, the hero
   projector light, a custom cursor, magnetic controls and alignment fixes.
   ========================================================================== */



/* --------------------------------------------------------------------------
   1. Alignment fixes
   -------------------------------------------------------------------------- */

/* Header: "Who I am", logo and MENU now share one optical centre line. */
.logo { top: 63px; }
.menu-button { top: 72px; }

/* Hero headline: line-height scales with the font instead of a fixed 87.3px. */
.hero h1 { line-height: .985; }

/* Middle service card sits exactly on the frame's centre axis. */
@media (min-width: 961px) {
  .service-center { left: calc(50% - 232.5px); }
}

.founder-copy { width: auto; max-width: 825px; }

/* One consistent gap between a section title and its content. */
.work-grid,
.review-shell,
.faq-list { margin-top: var(--heading-gap); }

/* Work cards: title and project number share a baseline. */
.work-grid div { align-items: baseline; }
.work-grid b { line-height: 1; }

/* FAQ answers line up with the question text above them. */
.faq-list p {
  width: auto;
  max-width: none;
  margin: 18px 0 0;
  padding: 0 26px;
}

/* Review footer number aligned to the reviewer name. */
.review-footer { align-items: center; }

@media (max-width: 760px) {
  :root { --heading-gap: 32px; }
  .logo { top: 55px; }
  .menu-button { top: 60px; }
  .faq-list p { padding: 0 15px; }
}

/* --------------------------------------------------------------------------
   2. Blur reveal
   Replaces the old fade + slide. Elements come into focus as they enter.
   -------------------------------------------------------------------------- */

.reveal {
  opacity: 0;
  filter: blur(8px);
  transform: translateY(12px);
  transition:
    opacity .45s var(--ease-soft) var(--reveal-delay, 0ms),
    filter .5s var(--ease-soft) var(--reveal-delay, 0ms),
    transform .55s var(--ease-out) var(--reveal-delay, 0ms);
}
.reveal.is-visible {
  opacity: 1;
  filter: none;
  transform: none;
}
.service.reveal.is-visible:hover { transform: translateY(-4px); }

/* Word-by-word blur for headings. The gradient of each heading is kept
   intact by mapping the gradient onto every word (see interactions.js). */
.split-blur.is-split { position: relative; }
.split-blur.is-gradient { background: none !important; }
.split-blur .bw {
  display: inline-block;
  opacity: 0;
  filter: blur(4px);
  transform: translateY(.32em);
  transition:
    opacity .28s var(--ease-soft),
    filter .34s var(--ease-soft),
    transform .38s var(--ease-out);
  transition-delay: calc(var(--base-delay, 0ms) + var(--i) * 22ms);
  will-change: filter, transform, opacity;
}
.split-blur.is-gradient .bw {
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  background-repeat: no-repeat;
}
.split-blur.words-in .bw {
  opacity: 1;
  filter: blur(0);
  transform: none;
}
.split-blur.words-done .bw { will-change: auto; filter: none; }

/* Hero: headline handled word by word, subline blurs in after it. */
.js-motion .hero-copy { animation: none; }
.js-motion .hero-copy p {
  opacity: 0;
  filter: blur(3px);
  transform: translateY(12px);
  transition: opacity .28s var(--ease-soft) .38s, filter .32s var(--ease-soft) .38s, transform .5s var(--ease-out) .38s;
}
.js-motion .hero.is-loaded .hero-copy p { opacity: 1; filter: none; transform: none; }

.js-motion .hero-visual {
  opacity: 0;
  filter: blur(10px);
  transition: opacity .7s var(--ease-soft), filter .8s var(--ease-soft);
}
.js-motion .hero.is-loaded .hero-visual { opacity: 1; filter: none; }

@media (max-width: 760px) {
  .js-motion .hero-visual { animation: none; }
}

/* --------------------------------------------------------------------------
   3. Hero: projector light + parallax
   The hero image is dim; a soft projector light brings the scene up where
   the visitor points. At rest it sits on the astronaut.
   -------------------------------------------------------------------------- */

.hero {
  --spot-x: 50%;
  --spot-y: 58%;
  --spot-r: 230px;
  --par-x: 0px;
  --par-y: 0px;
}
.hero-visual {
  translate: var(--par-x) var(--par-y);
  transition: translate .6s var(--ease-out);
}
.hero-spot {
  position: absolute;
  inset: 0;
  background: inherit;
  filter: brightness(2.1) saturate(1.2) contrast(1.05);
  -webkit-mask-image: radial-gradient(circle var(--spot-r) at var(--spot-x) var(--spot-y), #000 0%, rgba(0, 0, 0, .55) 45%, transparent 100%);
  mask-image: radial-gradient(circle var(--spot-r) at var(--spot-x) var(--spot-y), #000 0%, rgba(0, 0, 0, .55) 45%, transparent 100%);
  opacity: .9;
  pointer-events: none;
  transition: opacity .5s ease;
}
.hero.is-lit .hero-spot { opacity: 1; }
.hero-copy {
  translate: calc(var(--par-x) * -.45) calc(var(--par-y) * -.45);
  transition: translate .6s var(--ease-out);
}

/* --------------------------------------------------------------------------
   4. Marble image hover
   A liquid-marble displacement (SVG filter, driven by JS) plus a polished
   light that follows the pointer across the surface.
   -------------------------------------------------------------------------- */

.marble-frame {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: var(--card-image-radius);
  isolation: isolate;
}
.service-detail-media .marble-frame { border-radius: 12px; }
.work-media,
.project-gallery figure { position: relative; isolation: isolate; }

.marble-frame img,
.work-media img,
.blog-card-media img,
.project-gallery figure img {
  transition: scale .9s var(--ease-out), filter .35s ease;
}
.marble-frame img { border-radius: 0; }

.is-marble img {
  scale: 1.07;
}
/* The old zoom on the work cards is replaced by the marble zoom. */
.work-grid article:hover img,
.blog-card:hover img,
.project-gallery figure:hover img { transform: none; }

.marble-sheen {
  position: absolute;
  inset: 0;
  z-index: 2;
  border-radius: inherit;
  background:
    radial-gradient(circle 260px at var(--mx, 50%) var(--my, 50%), rgba(255, 255, 255, .26), rgba(255, 255, 255, 0) 62%),
    linear-gradient(115deg, rgba(255, 255, 255, 0) 40%, rgba(255, 255, 255, .08) 50%, rgba(255, 255, 255, 0) 60%);
  mix-blend-mode: soft-light;
  opacity: 0;
  pointer-events: none;
  transition: opacity .5s ease;
}
.is-marble .marble-sheen { opacity: 1; }

@media (max-width: 760px) {
  .service-detail-media .marble-frame { border-radius: 8px; }
}

/* --------------------------------------------------------------------------
   5. Custom cursor (fine pointers only)
   -------------------------------------------------------------------------- */

.has-cursor,
.has-cursor * { cursor: none !important; }
.has-cursor :is(input, textarea, select) { cursor: text !important; }
.has-cursor :is(input[type="date"], input[type="time"]) { cursor: pointer !important; }

.k-cursor,
.k-cursor-dot {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 9999;
  pointer-events: none;
  opacity: 0;
  transition: opacity .25s ease;
}
.k-cursor-dot {
  width: 6px;
  height: 6px;
  margin: -3px 0 0 -3px;
  border-radius: 50%;
  background: var(--pink);
}
.k-cursor {
  width: 38px;
  height: 38px;
  margin: -19px 0 0 -19px;
}
.k-cursor-ring {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  border: 1px solid rgba(255, 255, 255, .55);
  border-radius: 50%;
  background: rgba(252, 11, 241, 0);
  transition:
    transform .45s var(--ease-out),
    background-color .3s ease,
    border-color .3s ease;
}
.k-cursor-label {
  color: #fff;font: 700 12px/1 var(--font-body);
  letter-spacing: .04em;
  opacity: 0;
  transform: scale(.6);
  transition: opacity .25s ease, transform .35s var(--ease-out);
}

.cursor-visible .k-cursor,
.cursor-visible .k-cursor-dot { opacity: 1; }

/* Links and buttons */
.cursor-link .k-cursor-ring {
  transform: scale(1.45);
  border-color: var(--pink);
  background: rgba(252, 11, 241, .12);
}
/* Images: a "View" disc */
.cursor-view .k-cursor-ring {
  transform: scale(2);
  border-color: transparent;
  background: rgba(252, 11, 241, .88);
}
.cursor-view .k-cursor-label { opacity: 1; transform: scale(.5); }
.cursor-view .k-cursor-dot { opacity: 0; }
/* Hero: the ring opens up like a lens around the projector light */
.cursor-hero .k-cursor-ring {
  transform: scale(1.9);
  border-color: rgba(255, 255, 255, .22);
}
/* Text fields: step aside for the text caret */
.cursor-text .k-cursor,
.cursor-text .k-cursor-dot { opacity: 0; }
.cursor-down .k-cursor-ring { transform: scale(.8); }
.cursor-down.cursor-link .k-cursor-ring { transform: scale(1.2); }

/* --------------------------------------------------------------------------
   6. Magnetic controls
   Uses the individual `translate` property so it never fights the existing
   hover transforms.
   -------------------------------------------------------------------------- */

.is-magnetic {
  translate: var(--mag-x, 0px) var(--mag-y, 0px);
  transition-property: translate, border-color, background-color, color, filter, transform;
  transition-duration: .5s, .22s, .22s, .22s, .22s, .22s;
  transition-timing-function: var(--ease-out), ease, ease, ease, ease, ease;
}
.is-magnetic.is-pulling { transition-duration: .15s, .22s, .22s, .22s, .22s, .22s; }

/* --------------------------------------------------------------------------
   7. Reduced motion: everything is shown immediately and nothing follows
   the pointer.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .reveal,
  .split-blur .bw,
  .js-motion .hero-copy p,
  .js-motion .hero-visual {
    opacity: 1 !important;
    filter: none !important;
    transform: none !important;
  }
  .hero-visual,
  .hero-copy,
  .is-magnetic { translate: none !important; }
  .is-marble img { scale: 1; }
}

/* FAQ questions stay left-aligned when they wrap to two lines. */
.faq-item { gap: 16px; text-align: left; }
.faq-item span { text-align: left; }

/* ==========================================================================
   Testimonial: centred review cards in a carousel with dot pagination
   ========================================================================== */
.testimonial { }
.t-carousel {margin: var(--heading-gap) calc(var(--frame-pad) * -1) 0;padding: 48px var(--frame-pad) 0;
  border-top: 1px solid var(--line);
}
.t-track {
  display: flex;
  overflow-x: auto;
  overscroll-behavior-inline: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  outline-offset: 4px;
}
.t-track::-webkit-scrollbar { display: none; }
.t-track.is-dragging { cursor: grabbing; user-select: none; }
.t-card {
  flex: 0 0 100%;
  margin: 0;
  padding: 40px 48px 36px;
  background: #080808;
  text-align: center;
  scroll-snap-align: center;
  opacity: .35;
  filter: blur(4px);
  transition: opacity .5s ease, filter .5s ease;
}
.t-card.is-active { opacity: 1; filter: none; }
.t-mark {
  display: block;
  height: 44px;
  color: var(--pink);
  font: 400 110px / .9 var(--font-display);
}
.t-card blockquote { margin: 16px auto 0; max-width: 780px; }
.t-card blockquote p {
  margin: 0;
  color: #f0f0f0;
  font-size: clamp(18px, 2.2vw, 26px);
  line-height: 1.45;
  text-wrap: balance;
}
.t-card figcaption { margin-top: 26px; }
.t-card figcaption strong { display: block; color: #fff; font-size: 16px; font-weight: 700; }
.t-card figcaption span { display: block; margin-top: 4px; color: #8f8f8f; font-size: 13px; }

.t-dots {
  display: flex;
  justify-content: center;
  gap: 4px;
  margin-top: 22px;
}
.t-dots[hidden] { display: none; }
.t-dot {
  position: relative;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
}
.t-dot::before {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #3a3a3a;
  content: "";
  transform: translate(-50%, -50%);
  transition: width .35s var(--ease-out), background-color .25s ease;
}
.t-dot:hover::before { background: #777; }
.t-dot[aria-current="true"]::before { width: 22px; border-radius: 4px; background: var(--pink); }

@media (min-width: 761px) and (max-width: 960px) {
  .testimonial { }
  .t-carousel { margin-right: -48px; margin-left: -48px;padding: 40px var(--frame-pad) 0; }
}
@media (max-width: 760px) {
  .testimonial { }
  .t-carousel {margin: var(--heading-gap) calc(var(--frame-pad) * -1) 0;padding: 32px var(--frame-pad) 0; }
  .t-card { padding: 28px 20px 26px; }
  .t-mark { height: 36px; font-size: 88px; }
  .t-card blockquote p { font-size: 17px; }
}
@media (prefers-reduced-motion: reduce) {
  .t-card { filter: none; transition: none; }
}

/* ==========================================================================
   Blog detail FAQ
   ========================================================================== */
.blog-faq {
  position: relative;padding: 68px var(--frame-pad) 78px;
  border-top: 1px solid var(--line);
  text-align: center;
}
.blog-faq h2 {
  margin: 8px 0 0;
  background: linear-gradient(#f3f3f3, #818181);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  font: 400 var(--section-title-size) / 1 var(--font-display);
  text-transform: uppercase;
}
.blog-faq .faq-list { width: 720px; max-width: 100%; }
@media (max-width: 760px) {
  .blog-faq {padding: 52px var(--frame-pad) 60px; }
  .blog-faq h2 { font-size: 32px; }
}

/* ==========================================================================
   Project gallery viewer
   ========================================================================== */
.project-gallery figure.is-zoomable { cursor: zoom-in; }
.k-lightbox,
.k-lightbox * { cursor: auto !important; }
.k-lightbox button { cursor: pointer !important; }
.k-lightbox {
  width: 100vw;
  max-width: none;
  height: 100vh;
  max-height: none;
  margin: 0;
  padding: 64px 24px 88px;
  border: 0;
  background: rgba(0, 0, 0, .94);
  color: #fff;
}
.k-lightbox::backdrop { background: rgba(0, 0, 0, .6); backdrop-filter: blur(8px); }
.k-lightbox[open] { display: grid; place-items: center; animation: k-lightbox-in .35s var(--ease-out); }
.k-lightbox figure { margin: 0; max-width: min(1200px, 100%); max-height: 100%; }
.k-lightbox img {
  max-width: 100%;
  max-height: calc(100vh - 190px);
  margin: 0 auto;
  border-radius: 8px;
  object-fit: contain;
}
.k-lightbox figcaption { margin-top: 14px; color: #8a8a8a; font-size: 13px; text-align: center; }
.k-lightbox-close {
  position: absolute;
  top: 16px;
  right: 16px;
  width: 44px;
  height: 44px;
  border: 1px solid #333;
  border-radius: 50%;
  background: transparent;
  color: #fff;
  font-size: 24px;
  line-height: 1;
}
.k-lightbox-close:hover { border-color: var(--pink); }
.k-lightbox-nav {
  position: absolute;
  bottom: 24px;
  left: 50%;
  display: flex;
  align-items: center;
  gap: 16px;
  color: #8a8a8a;
  font-size: 12px;
  font-weight: 700;
  transform: translateX(-50%);
}
.k-lightbox-nav[hidden] { display: none; }
.k-lightbox-nav button {
  width: 44px;
  height: 44px;
  border: 1px solid #333;
  border-radius: 8px;
  background: transparent;
  color: #fff;
}
.k-lightbox-nav button:hover { border-color: var(--pink); }
@keyframes k-lightbox-in { from { opacity: 0; } to { opacity: 1; } }


/* Custom cursor is back (v2.5.6). Native cursor is only used when JS has not added .has-cursor. */
.k-lightbox * { cursor: auto !important; }
html.has-cursor .k-lightbox, html.has-cursor .k-lightbox * { cursor: auto !important; }
