/* ============================================================================
   MOEDATECH - MANSOUR ON home-v4                                    2026-08-27
   GENERATED by mansour/build_mansour.py - do not hand-edit.
   Hosted, so changes ship with a deploy and NO Webflow publish.

   Additive only. home-v4's own `.pill` keeps every resting style it already
   has - this file adds the OPEN state, the field, the send button and Mansour.
   Nothing here restyles the button at rest.
   ========================================================================= */

.v4m-pill {
  --v4m-open: 660px;
  /* --v4m-rest and --v4m-h are set inline by the script, measured off the
     real anchor before it is replaced. */
  --v4m-man: 38px;
  --v4m-accent: #e65d00;       /* the v4 system action colour */
  --v4m-ink: #46464a;

  position: relative;
  overflow: hidden;
  isolation: isolate;
  /* NOTE: width is declared !important on .is-open below. In v3 a plain CSS
     transition stalled, a WAAPI animation outranked the inline style, and an
     inline rAF tween got restarted. !important outranks animations, so nothing
     can silently win against it. Do not "tidy" it away. */
  transition: width .52s cubic-bezier(.34, 1.2, .44, 1), box-shadow .3s ease;
  will-change: width;
  cursor: pointer;
}
.v4m-pill.is-open { width: var(--v4m-open) !important; cursor: text; }

/* The narrow-screen clamp lives in a media query rather than a min() with vw:
   keeping viewport units out of the animated property removes one more way for
   this declaration to resolve to something unexpected. */
@media (max-width: 720px) {
  .v4m-pill.is-open { width: calc(100vw - 44px) !important; }
}

/* the resting label, lifted out of the flow so the pill's own padding and
   centring cannot move it while the box grows */
.v4m-label {
  position: absolute;
  inset-inline-start: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  white-space: nowrap;
  transition: opacity .16s ease;
}
html[dir="rtl"] .v4m-label { transform: translate(50%, -50%); }
.v4m-pill.is-open .v4m-label { opacity: 0; }

/* The field you actually type in. Its native caret is hidden on purpose:
   Mansour IS the caret, standing where the next letter will land. */
.v4m-input {
  position: absolute;
  inset-inline-start: 26px;
  top: 50%;
  transform: translateY(-50%);
  width: calc(100% - 26px - 74px);
  background: none; border: 0; outline: none; padding: 0; margin: 0;
  font-family: inherit; font-size: 16px; line-height: 20px; font-weight: 400;
  color: var(--v4m-ink);
  caret-color: transparent;
  opacity: 0; pointer-events: none;
  transition: opacity .2s ease;
  text-align: start;
}
.v4m-pill.is-open .v4m-input { opacity: 1; pointer-events: auto; }
.v4m-input::placeholder { color: #9b9ba1; }

/* NOTHING may draw a field boundary inside the pill.
   Hisham reported a pale rounded outline appearing while typing, exactly the
   size of the input's box. Three separate mechanisms can draw that, so all
   three are shut off in every state:
     - appearance: the input was resolving to `auto`, which lets the platform
       paint native field chrome even with border:0
     - a focus ring, from any :focus / :focus-visible rule on the site
     - a box-shadow, which nothing here had reset

   `!important` is deliberate and must stay. Webflow renders Code Embeds
   INLINE, so this site's stylesheet sits in the BODY - after this hosted file
   in the head - and therefore wins every equal-specificity tie. That is the
   same trap that cost time on home-v3. */
.v4m-pill .v4m-input,
.v4m-pill .v4m-input:hover,
.v4m-pill .v4m-input:focus,
.v4m-pill .v4m-input:focus-visible,
.v4m-pill .v4m-input:active {
  -webkit-appearance: none !important;
  appearance: none !important;
  background: none !important;
  background-image: none !important;
  border: 0 !important;
  border-radius: 0 !important;
  outline: 0 none !important;
  box-shadow: none !important;
}

/* Hidden twin in the identical font. Measuring THIS is the only reliable way to
   know where the caret sits, because an input cannot be measured. */
.v4m-mirror {
  position: absolute; inset-inline-start: -9999px; top: 0;
  visibility: hidden; white-space: pre;
  font-family: inherit; font-size: 16px; line-height: 20px; font-weight: 400;
}

/* The send button. A span-like anchor pinned to the inline END, so it mirrors
   with the page and Mansour always walks toward it. */
.v4m-send {
  position: absolute;
  inset-inline-end: 9px;
  top: 50%;
  width: 40px; height: 40px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--v4m-accent);
  text-decoration: none;
  transform: translateY(-50%) scale(.4);
  opacity: 0;
  transition: opacity .26s ease, transform .34s cubic-bezier(.34, 1.3, .44, 1);
}
.v4m-pill.is-open .v4m-send { opacity: 1; transform: translateY(-50%) scale(1); }
.v4m-send svg { width: 18px; height: 18px; fill: #fff; display: block; }
/* the paper-plane points along the reading direction */
html[dir="rtl"] .v4m-send svg { transform: scaleX(-1); }

/* the moment Mansour lands on it */
.v4m-send.is-hit { animation: v4mPress .42s cubic-bezier(.3, 1.4, .4, 1); }
@keyframes v4mPress {
  0%   { transform: translateY(-50%) scale(1); }
  28%  { transform: translateY(-50%) scale(.82); }
  100% { transform: translateY(-50%) scale(1); }
}
.v4m-send::after {
  content: ''; position: absolute; inset: -4px; border-radius: 50%;
  border: 2px solid var(--v4m-accent); opacity: 0;
}
.v4m-send.is-hit::after { animation: v4mRing .6s ease-out; }
@keyframes v4mRing {
  0%   { opacity: .85; transform: scale(.9); }
  100% { opacity: 0;   transform: scale(1.65); }
}

/* ---- Mansour ------------------------------------------------------------
   The outer span carries POSITION (set by JS), the inner one carries the idle
   bob (CSS), so the two never fight over a single transform. */
.v4m-man {
  position: absolute;
  inset-inline-start: 0;
  top: 50%;
  width: var(--v4m-man); height: var(--v4m-man);
  margin-top: calc(var(--v4m-man) / -2);
  opacity: 0;
  pointer-events: none;
}
.v4m-man-svg { width: 100%; height: 100%; display: block; overflow: visible; }
.v4m-man-in  { display: block; width: 100%; height: 100%; }
.v4m-man.is-live .v4m-man-in { animation: v4mBob .62s ease-in-out infinite; }
@keyframes v4mBob {
  0%, 100% { transform: translateY(0)    scaleY(1); }
  45%      { transform: translateY(-2px) scaleY(1.03); }
}

/* ---- waiting for you ----
   Set while he has looked up from the line because you stopped typing. A slow
   lean-in rather than anything on the eyes: the blink lives on .v4m-lid and
   the gaze on .v4m-eye, and touching either from here would fight them.
   Declared AFTER the idle bob so it wins on equal specificity. */
.v4m-man.is-waiting .v4m-man-in { animation: v4mWait 1.9s ease-in-out infinite; }
@keyframes v4mWait {
  0%, 100% { transform: translateY(0)     scale(1); }
  50%      { transform: translateY(-2.5px) scale(1.045); }
}
@media (prefers-reduced-motion: reduce) {
  .v4m-man.is-waiting .v4m-man-in { animation: none; }
}

/* he has to be able to climb out of the pill for the send beat */
.v4m-pill.is-exiting { overflow: visible; }

@media (prefers-reduced-motion: reduce) {
  .v4m-pill { transition: none; }
  .v4m-man.is-live .v4m-man-in { animation: none; }
}

/* ---- the rig's own idle life (generated by home_v3/gen_rig.py) ---------- */
/* generated by gen_rig.py -- do not hand-edit */
/* CSS transforms on SVG need these two, or the origin is the bbox centre and
   the matrix no longer means what the attribute meant. */
.v4m-eye{transform-box:view-box;transform-origin:0 0}
.v4m-lid{transform-box:fill-box;transform-origin:50% 50%}

.v4m-eye0{animation:v4mGaze0 9s ease-in-out infinite}
.v4m-eye1{animation:v4mGaze1 9s ease-in-out infinite}
/* both lids on one timeline, so he blinks with both eyes at once */
.v4m-lid{animation:v4mBlink 9s linear infinite}
/* a slow head tilt around the ball centre, so he is never quite still */
.v4m-man-body{transform-box:view-box;transform-origin:60px 70px;
  animation:v4mSway 7s ease-in-out infinite}

@keyframes v4mGaze0{
  0%{transform:matrix(0.887, -0.318, 0.42, 0.855, 67.182, 54.457)}
  15%{transform:matrix(0.977, -0.211, 0.192, 0.917, 56.677, 57.125)}
  30%{transform:matrix(0.887, -0.318, 0.42, 0.855, 67.182, 54.457)}
  48%{transform:matrix(0.666, -0.409, 0.606, 0.784, 76.515, 52.254)}
  63%{transform:matrix(0.886, -0.235, 0.33, 0.925, 72.397, 58.658)}
  82%{transform:matrix(0.903, -0.381, 0.43, 0.807, 60.233, 52.819)}
  100%{transform:matrix(0.887, -0.318, 0.42, 0.855, 67.182, 54.457)}
}
@keyframes v4mGaze1{
  0%{transform:matrix(0.664, -0.063, 0.42, 0.855, 83.49, 50.456)}
  15%{transform:matrix(0.883, -0.007, 0.192, 0.917, 76.236, 54.844)}
  30%{transform:matrix(0.664, -0.063, 0.42, 0.855, 83.49, 50.456)}
  48%{transform:matrix(0.348, -0.111, 0.606, 0.784, 87.168, 46.786)}
  63%{transform:matrix(0.592, -0.048, 0.33, 0.925, 87.932, 55.689)}
  82%{transform:matrix(0.771, -0.094, 0.43, 0.807, 77.83, 47.824)}
  100%{transform:matrix(0.664, -0.063, 0.42, 0.855, 83.49, 50.456)}
}

/* he looks where he is about to jump */
.v4m-man.is-aiming .v4m-eye0{animation:none;transform:matrix(0.644, -0.415, 0.605, 0.791, 77.806, 52.888)}
.v4m-man.is-aiming .v4m-eye1{animation:none;transform:matrix(0.312, -0.125, 0.605, 0.791, 87.847, 47.217)}

@keyframes v4mBlink{
  0%,32.4%{transform:scaleY(1)}
  33.4%{transform:scaleY(.08)}
  34.4%,76.4%{transform:scaleY(1)}
  77.4%{transform:scaleY(.08)}
  78.4%,100%{transform:scaleY(1)}
}
@keyframes v4mSway{
  0%,100%{transform:rotate(-2deg)}
  50%{transform:rotate(2deg)}
}

@media (prefers-reduced-motion:reduce){
  .v4m-eye0,.v4m-eye1,.v4m-lid,.v4m-man-body{animation:none}
}
