/* ==========================================================================
   KeyBindX overrides — loaded after main.css so it wins on equal specificity.
   Keep template/vendor CSS untouched; put all custom rules here.
   ========================================================================== */

/* Inline desktop nav in the header bar.
   main.css sizes .main-menu links for a tall header (38px block padding);
   header-three is a compact bar, so tighten the rhythm and spacing. */
.header-menu .main-menu > nav > ul > li {
  padding-inline-end: 0;
}

.header-menu .main-menu > nav > ul > li:not(:last-child) {
  margin-right: 28px;
}

.header-menu .main-menu > nav > ul > li > a {
  padding: 22px 0;
  font-size: 16px;
  white-space: nowrap;
}

/* The bar is only ever on screen at the very top of the page, which is now the
   dark hero video — so the links are light, not the template's heading colour.
   (.header-two-menu sets that colour, hence the matching specificity here.) */
.header-two-menu .main-menu > nav > ul > li > a {
  color: #ffffff;
  position: relative;
  z-index: 1;
  font-size: 14px;
  letter-spacing: 0.01em;
  padding: 9px 15px;
  border-radius: 999px;
}

/* One pill for the whole row, slid between items by keybindx.js, instead of a
   pseudo-element per link. Travelling between neighbours is what reads as
   considered rather than a plain hover state. */
.header-menu .main-menu > nav > ul {
  position: relative;
}

.nav-pill {
  position: absolute;
  z-index: 0;
  top: 0;
  left: 0;
  height: 0;
  width: 0;
  border-radius: 999px;
  background: #e11d2a;
  opacity: 0;
  pointer-events: none;
}

/* Label roll: the resting copy leaves upward while its duplicate arrives from
   below. keybindx.js builds the two copies. */
.nav-roll {
  display: block;
  position: relative;
  overflow: hidden;
}

.nav-roll-in,
.nav-roll-out {
  display: block;
  transition: transform 0.42s cubic-bezier(0.65, 0, 0.35, 1);
}

.nav-roll-out {
  position: absolute;
  inset: 0;
  transform: translateY(105%);
}

.header-two-menu .main-menu > nav > ul > li > a:hover .nav-roll-in {
  transform: translateY(-105%);
}

.header-two-menu .main-menu > nav > ul > li > a:hover .nav-roll-out {
  transform: translateY(0);
}

/* main.css turns the link orange on hover; on a red pill it has to stay white.
   Higher specificity than its `li:hover a` rule. */
.header-two-menu .main-menu > nav > ul > li:hover > a,
.header-two-menu .main-menu > nav > ul > li > a:hover {
  color: #ffffff;
}

/* The links carry their own padding now — pull the gap back in. */
.header-menu .main-menu > nav > ul > li:not(:last-child) {
  margin-right: 4px;
}

/* The logo sits straight on the hero video now — no card, no padding, no
   embossed shadow. main.css gives it all three. */
.header-three-logo {
  background: transparent;
  box-shadow: none;
  /* No card, but the mark still needs to clear the viewport edge. */
  padding: 0 0 0 8px;
}

/* Menu button (mobile only) still needs a chip to sit on, just a flat one. */
.header-three-menu button {
  box-shadow: none;
  background: #ffffff;
}

/* Hero wordmark. The template's heading font (Phudu) has no lowercase
   glyphs, so it can only render KEYBINDX — switch this one heading to the
   body font (Instrument Sans) to get the brand's "KeyBindX" casing, and
   colour the X with the logo red. */
.banner-three-title {
  font-family: var(--body-font);
  font-weight: 700;
  letter-spacing: -0.035em;
  text-transform: none;
  text-align: center;
  /* Must stay on one line — the intro animation flings the three parts in
     three different directions, which only reads if they start side by side. */
  white-space: nowrap;
  font-size: clamp(60px, 16.5vw, 330px);
  /* Instrument Sans only ships up to 700, so extra weight comes from a stroke
     rather than font-weight: 800 — that would trigger the browser's faux-bold,
     which smears badly at this size. */
  -webkit-text-stroke: 4px currentColor;
}

.banner-three-title .hero-part {
  display: inline-block;
  will-change: transform;
}

/* The hero now sits on dark video, so the wordmark takes the logo's
   light-background-inverted form: white type, red X. */
.banner-three-title {
  color: #ffffff;
}

.banner-three-title .brand-x {
  color: #e11d2a;
}

/* Pull the statement up under the wordmark and drop it to a supporting size —
   the template ran it at display scale, which fought the wordmark for
   attention. */
/* Was opened up to clear the decorative marker circle; that circle is gone, so
   the statement sits back under the wordmark where it belongs. */
.banner-three-title {
  /* line-height is 83%, so the "y" descender hangs ~0.2em below the box —
     clear it, or it lands on the statement underneath. */
  margin-block-end: calc(0.2em + 16px) !important;
}

/* Solid, tracked-out caps in the body font. The template's outlined Phudu
   read as blurry and cramped on the video. */
.banner-three-center-title {
  font-family: var(--body-font);
  font-weight: 500;
  color: rgba(255, 255, 255, 0.88);
  -webkit-text-stroke: 0;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  font-size: 15px;
  line-height: 1.7;
  max-width: 560px;
  margin-inline: auto;
  margin-block-end: 26px;
}

/* Decorative line art behind the hero — a dark PNG, invisible on the video.
   brightness(0) flattens it to black, invert(1) then makes it pure white.
   The nudge down keeps its marker circle off the wordmark now that the hero
   block is vertically centred. */
.banner-three-line-shape {
  margin-block-end: -46px;
}

.banner-three-line-shape img {
  filter: brightness(0) invert(1);
  opacity: 0.35;
}

/* The marker circle never found a home in the compacted hero — it landed on
   the wordmark or the statement wherever it was put. */
.banner-three-carcel-shape {
  display: none;
}

.banner-three-button .tw-hover-btn {
  background: #ffffff !important;
  color: #02090f !important;
}

/* ==========================================================================
   Hero scroll intro
   ========================================================================== */

.banner-three-area {
  position: relative;
  overflow: hidden;
}

/* The hero is pinned for the whole intro and its background ends up black, so
   any height beyond the viewport became a dead black gap between the intro and
   the About section. Pin exactly one screen. Nothing is lost: the part this
   clips sits below the fold, and the intro never scrolls the section past its
   own top. Desktop only — below 992px there is no intro and the hero is a
   normal, self-sizing section. */
/* Exactly one screen at every width — the intro pins it, so any extra height
   became dead space to scroll past. The template's fixed top/bottom padding
   also parked the wordmark high, which reads as off-centre against a full-bleed
   video; centring the block in the viewport fixes that. */
.banner-three-area {
  height: 100vh;
  display: flex;
  align-items: center;
  padding-block: 0;
}

.banner-three-area > .container {
  width: 100%;
  /* Nudged off dead centre — the fixed header covers the top of the screen,
     so optical centre sits a little below geometric centre. */
  transform: translateY(46px);
}

@media screen and (max-width: 991px) {
  .banner-three-area > .container {
    transform: translateY(20px);
  }

  /* The header logo is a wide lockup with a tagline under it — at desktop size
     it dominates a phone screen. */
  .header-three-logo img {
    max-width: 140px;
  }

  /* -0.035em is a display-type tightening. At phone sizes the letters start
     touching, so ease off. */
  .banner-three-title {
    letter-spacing: -0.005em;
    margin-block-end: calc(0.2em + 10px) !important;
  }

  .banner-three-center-title {
    font-size: 12px;
    letter-spacing: 0.16em;
    margin-block-end: 18px;
  }

  /* The template's button padding is sized for a desktop hero. */
  .banner-three-button .tw-hover-btn {
    font-size: 13px;
    padding: 11px 22px !important;
  }
}

/* The row was a three-up (list card / statement / stats card) laid out with
   space-between. With the two side cards gone the statement is the only child
   left, so it has to be centred explicitly. */
.banner-three-wrap {
  justify-content: center !important;
}

/* Hero video, full screen. It lives inside the two curtain panels rather than
   behind them — the panels cover the whole viewport, so anything underneath
   would never be seen. Each panel holds a viewport-sized copy anchored to its
   own outer edge, so `overflow: hidden` on the panel shows exactly one half
   and the two read as a single full-bleed video. When the panels part, the
   video tears down the middle with them, the same trick as the X.
   keybindx.js keeps the two copies in sync. */
.hero-video {
  position: absolute;
  top: 0;
  /* 200% of the half-width panel = one full hero width. Not 100vw: that
     includes the scrollbar, so the two halves drifted apart by its width. */
  width: 200%;
  height: 100%;
  object-fit: cover;
}

.is-left .hero-video {
  left: 0;
}

.is-right .hero-video {
  right: 0;
}

/* The footage is dark and busy; the wordmark needs a floor to sit on. */
.hero-scrim {
  position: absolute;
  inset: 0;
  background: rgba(2, 9, 15, 0.55);
}

/* ==========================================================================
   Video showcase deck
   ========================================================================== */

/* The deck lives inside the hero, behind the curtain — the split opens onto it
   instead of onto flat black, and there is no separate section afterwards to
   leave an empty stretch between the reel and About. */
.video-stack {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: #02090f;
  overflow: hidden;
}

.video-stack-inner {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Cards share one centre point; JS slides them left/right so the next clip
   waits at the edge of the screen and the finished one exits to the other side. */
.video-card {
  position: absolute;
  width: min(52vw, 700px);
  aspect-ratio: 16 / 9;
  border-radius: 16px;
  overflow: hidden;
  background: #0b1218;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.55);
  will-change: transform, opacity;
}

/* --- deck copy ------------------------------------------------------- */

.deck-head,
.deck-foot {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  width: min(90vw, 760px);
  text-align: center;
  z-index: 2;
  pointer-events: none;
}

.deck-head {
  top: clamp(90px, 13vh, 150px);
}

.deck-foot {
  bottom: clamp(56px, 10vh, 110px);
}

.deck-eyebrow {
  display: inline-block;
  font-family: var(--body-font);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: #e11d2a;
  margin-block-end: 10px;
}

.deck-title {
  font-size: clamp(28px, 3.6vw, 52px);
  line-height: 1.1;
  color: #ffffff;
  margin: 0;
}

.deck-note {
  font-family: var(--body-font);
  font-size: 16px;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.72);
  margin: 0 auto 8px;
  max-width: 620px;
}

.deck-price {
  font-family: var(--body-font);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.45);
  margin: 0;
}

/* On a phone the card is nearly full-width, so the copy has to give it room
   rather than sit on top of it. */
@media screen and (max-width: 991px) {
  .deck-head {
    top: clamp(72px, 11vh, 110px);
  }

  .deck-foot {
    bottom: clamp(36px, 7vh, 70px);
  }

  .deck-title {
    font-size: clamp(24px, 7vw, 34px);
  }

  .deck-note {
    font-size: 14px;
    line-height: 1.5;
  }

  .deck-price {
    font-size: 11px;
  }

  .deck-eyebrow {
    font-size: 11px;
  }
}

.video-card video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

@media screen and (max-width: 991px) {
  .video-card {
    width: 88vw;
  }
}

/* ==========================================================================
   Services
   ========================================================================== */

/* The pill shape was never in the CSS — it is baked into the thumbnail PNGs
   (552x257 with transparent corners), and the box took its size from the image
   too. Drop a video in and both disappear: it renders at its own size with
   square corners. Define the box here instead, so an <img> and a <video> are
   interchangeable. */
.service-three-thumb a {
  display: block;
  width: 552px;
  max-width: 100%;
  aspect-ratio: 552 / 257;
  border-radius: 999px;
  overflow: hidden;
}

.service-three-thumb img,
.service-three-thumb video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ==========================================================================
   Services — mirrored rows
   ========================================================================== */

/* Rows 02 and 04 read right-to-left: image on the left, copy on the right.
   The whole block mirrors — row, the number/title pair inside it, the title
   alignment, the tag row, and the arrow glyph, which would otherwise point
   away from the text it belongs to. */
.service-three-single.is-flipped .service-three-item {
  flex-direction: row-reverse;
}

.service-three-single.is-flipped .service-three-content {
  flex-direction: row-reverse;
}

.service-three-single.is-flipped .service-three-title {
  text-align: right;
}

.service-three-single.is-flipped .portfolio-list ul {
  justify-content: flex-end;
}

.service-three-single.is-flipped .service-three-number {
  flex-direction: row-reverse;
}

.service-three-single.is-flipped .service-three-number img {
  transform: scaleX(-1);
}

@media screen and (max-width: 991px) {
  /* Stacked on a phone — mirroring there just makes the copy ragged. */
  .service-three-single.is-flipped .service-three-title {
    text-align: left;
  }

  .service-three-single.is-flipped .portfolio-list ul {
    justify-content: flex-start;
  }
}

/* ==========================================================================
   About
   ========================================================================== */

.about-eyebrow {
  font-family: var(--body-font);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #e11d2a;
}

.about-heading {
  font-size: clamp(30px, 3.4vw, 54px);
  line-height: 1.15;
  max-width: 20ch;
}

/* The template's accent (--main-two-600) is orange; the brand red is the
   logo's own #E11D2A. */
.brand-accent {
  color: #e11d2a;
}

/* SplitText word wrappers in the About copy — inline-block so they can scale,
   and given the surrounding line-height back so the paragraph does not reflow
   when the split runs. */
/* A transform never moves the neighbouring word, so a swelling word simply
   grows into the gap beside it. Widening the gaps is the only real fix —
   a negative-margin trick eats the space instead of adding to it, and a
   scale small enough to fit the default gap is too small to see. */
.about-three-right p {
  word-spacing: 0.16em;
}

.about-word {
  display: inline-block;
  will-change: transform, opacity;
}

/* ==========================================================================
   About stats
   ========================================================================== */

/* main.css floats this row above the section (top: -172px) so it overlaps the
   hero. It belongs below the About copy now, in normal flow. */
.about-stats {
  position: static;
  margin-block-start: 100px;
  gap: 32px;
  flex-wrap: wrap;
}

/* ...and as plain figures rather than raised cards. */
.about-stats .banner-three-counter-item {
  box-shadow: none;
  background: transparent;
  padding: 0;
  max-width: none;
  flex: 1 1 0;
}

.about-stats .banner-three-counter-item:nth-child(2) {
  margin-block-start: 0;
}

.banner-three-area > .container {
  position: relative;
  z-index: 2;
}

/* The hero box is taller than the viewport, but it is pinned with its top at
   the viewport top — so 100vh here is exactly the visible area, which is what
   the split has to line up with. */
.hero-curtain {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 100vh;
  /* Above the deck it is hiding, below the wordmark. */
  z-index: 1;
  pointer-events: none;
}

.hero-curtain-half {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 50%;
  background: #02090f;
  overflow: hidden;
  will-change: transform;
}

.hero-curtain-half.is-left {
  left: 0;
}

.hero-curtain-half.is-right {
  right: 0;
}

/* Half an X in each panel, meeting exactly on the centre line. Together they
   read as one X; when the panels part, the X tears in two with them. */
.hero-split-x {
  position: absolute;
  top: 50%;
  font-family: var(--body-font);
  font-weight: 700;
  /* Must match .banner-three-title exactly — the live X hands over to these. */
  font-size: clamp(60px, 16.5vw, 330px);
  -webkit-text-stroke: 4px currentColor;
  letter-spacing: -0.035em;
  line-height: 1;
  color: #e11d2a;
  opacity: 0;
  white-space: nowrap;
  will-change: transform;

  /* Rainbow extrusion trailing the letter. --depth is 0 at rest and the
     timeline drives it up while the X is in motion, so the stack fans out
     into a 3D trail and collapses again when it settles. */
  --depth: 0;
  text-shadow:
    calc(var(--depth) * 1px) calc(var(--depth) * 0.55px) 0 #ff0040,
    calc(var(--depth) * 2px) calc(var(--depth) * 1.1px) 0 #ff8a00,
    calc(var(--depth) * 3px) calc(var(--depth) * 1.65px) 0 #ffd400,
    calc(var(--depth) * 4px) calc(var(--depth) * 2.2px) 0 #24d17e,
    calc(var(--depth) * 5px) calc(var(--depth) * 2.75px) 0 #0a84ff,
    calc(var(--depth) * 6px) calc(var(--depth) * 3.3px) 0 #7b2ff7;
}

/* Centring is applied by GSAP as xPercent/yPercent, not a CSS transform —
   the timeline tweens x/y on these elements, and a px transform written by
   GSAP would wipe out a CSS translate(). xPercent/yPercent compose instead. */
.is-left .hero-split-x {
  right: 0;
}

.is-right .hero-split-x {
  left: 0;
}

/* During the intro the header must be under the timeline's control alone.
   Two things fought it otherwise:
     - it is only sticky once main.js adds .fixed-header at 260px of scroll, so
       before that it scrolled away on its own and then snapped back into view
       the moment the class landed;
     - .fixed-header runs a slideDown keyframe animating transform back to
       translateY(0), and a CSS animation beats GSAP's inline transform.
   Sticky from the first pixel (and in flow, so nothing shifts when the class
   is removed later), with the keyframe disabled. */
/* Fixed, not sticky. ScrollSmoother used to take the header out of the hero's
   way; without it a sticky header holds ~100px of flow above the hero, which
   pushed the video down and left the white nav links sitting on a white strip.
   Fixed removes it from flow so the hero starts at the top of the viewport
   again. The .fixed-header half of the selector is there to outrank main.js's
   own `position: sticky !important`. */
.header,
.header.fixed-header {
  position: fixed !important;
  inset-block-start: 0;
  inset-inline: 0;
  z-index: 99;
  will-change: transform;
}

/* ScrollSmoother clipped its wrapper, which is what kept the marquee and the
   oversized decorative shapes from producing a horizontal scrollbar. Restore
   that. `clip` rather than `hidden`: it does not create a scroll container, so
   ScrollTrigger's pinning and any sticky descendants keep working. */
#smooth-wrapper {
  overflow-x: clip;
}

/* The header's show/hide is driven by GSAP everywhere on the page now, so the
   template's keyframe has to stay out of it for good — a CSS animation wins
   over an inline transform and would snap the bar back into view.
   The white background goes too: .fixed-header paints one once you are 260px
   down, and the bar only ever shows over the dark hero, so it read as a white
   slab across the top of the video. */
.header.fixed-header {
  animation: none !important;
  background: transparent !important;
  box-shadow: none !important;
  backdrop-filter: none !important;
}

/* Below the top of the page the bar can be over anything — including the white
   About section, where its white links would disappear. keybindx.js adds this
   once you are past 60px; at the very top it stays fully transparent so the
   hero video shows through. */
.header.is-solid,
.header.fixed-header.is-solid {
  background: rgba(2, 9, 15, 0.88) !important;
  backdrop-filter: blur(14px) !important;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.28) !important;
}

/* ==========================================================================
   Portfolio / Works Section Staggered (Zigzag) Grid Layout
   ========================================================================== */
.portfolio-three-shape {
  display: block !important;
  position: absolute !important;
  top: 0 !important;
  left: 50% !important;
  transform: translateX(-50%) !important;
  pointer-events: none !important;
  user-select: none !important;
  z-index: 0 !important;
  overflow: hidden !important;
}

.portfolio-three-shape-title {
  color: transparent !important;
  -webkit-text-stroke: 2px rgba(0, 0, 0, 0.06) !important;
  text-transform: lowercase !important;
  line-height: 0.8 !important;
  white-space: nowrap !important;
  pointer-events: none !important;
}

.portfolio-three-wrapper {
  display: grid !important;
  grid-template-columns: repeat(2, 1fr) !important;
  gap: 40px !important;
  align-items: start !important;
}

.portfolio-three-item {
  max-width: 100% !important;
  width: 100% !important;
  margin-top: 0 !important;
  margin-bottom: 0 !important;
}

.portfolio-three-item:nth-child(even) {
  margin-top: 380px !important;
}

@media screen and (max-width: 991px) {
  .portfolio-three-wrapper {
    grid-template-columns: 1fr !important;
    gap: 30px !important;
  }
  .portfolio-three-item:nth-child(even) {
    margin-top: 0 !important;
  }
}

/* ==========================================================================
   Redesigned Contact Section (High-End Premium Glassmorphism)
   ========================================================================== */
.footer-three-area {
  background: linear-gradient(180deg, #05080e 0%, #080e18 100%) !important;
  position: relative;
  overflow: hidden;
}

.footer-contact-glass {
  background: rgba(255, 255, 255, 0.03) !important;
  border: 1px solid rgba(255, 255, 255, 0.08) !important;
  backdrop-filter: blur(16px);
  border-radius: 24px !important;
  padding: 44px !important;
  box-shadow: 0 30px 60px rgba(0, 0, 0, 0.5) !important;
}

.contact-input-wrap .form-control {
  background: rgba(255, 255, 255, 0.08) !important;
  border: 1px solid rgba(255, 255, 255, 0.2) !important;
  border-radius: 14px !important;
  color: #ffffff !important;
  height: 56px !important;
  padding-left: 20px !important;
  font-size: 15px !important;
  transition: all 0.3s ease !important;
}

.contact-input-wrap .form-control::placeholder {
  color: rgba(255, 255, 255, 0.65) !important;
  opacity: 1 !important;
}

.contact-input-wrap textarea.form-control {
  height: 130px !important;
  padding-top: 16px !important;
}

.contact-input-wrap .form-control:focus {
  background: rgba(255, 255, 255, 0.12) !important;
  border-color: #f7383a !important;
  box-shadow: 0 0 20px rgba(247, 56, 58, 0.35) !important;
}

.service-select-pill {
  cursor: pointer;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.12);
  color: #ccc;
  padding: 8px 18px;
  border-radius: 30px;
  font-size: 13px;
  font-weight: 500;
  transition: all 0.25s ease;
  user-select: none;
}

.service-select-pill:hover,
.service-select-pill.active {
  background: #f7383a !important;
  color: #fff !important;
  border-color: #f7383a !important;
  box-shadow: 0 4px 15px rgba(247, 56, 58, 0.4);
}

.contact-submit-btn {
  background: linear-gradient(135deg, #f7383a 0%, #ff5e3a 100%) !important;
  color: #fff !important;
  border: none !important;
  border-radius: 50px !important;
  font-size: 16px !important;
  font-weight: 700 !important;
  letter-spacing: 1px !important;
  padding: 16px 32px !important;
  transition: all 0.3s ease !important;
  box-shadow: 0 10px 30px rgba(247, 56, 58, 0.35) !important;
}

.contact-submit-btn:hover {
  transform: translateY(-2px) !important;
  box-shadow: 0 15px 35px rgba(247, 56, 58, 0.5) !important;
  color: #fff !important;
}

.contact-info-card {
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 18px;
  padding: 20px 24px;
  transition: all 0.3s ease;
}

.contact-info-card:hover {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.15);
  transform: translateY(-3px);
}
