/* ---------- Lead form dialog ----------
   Continues the ENCASE surface: dark ground, white type, orange accent,
   a soft translucent border instead of a hard card edge. */

.lead-dialog {
  padding: 0;
  border: none;
  border-radius: 32px;
  width: min(440px, calc(100vw - 32px));
  max-height: min(680px, 90dvh);
  margin: auto;
  background: #1c1a19;
  color: var(--color-white);
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.5);
}

.lead-dialog::backdrop {
  background: rgba(10, 8, 7, 0.7);
  backdrop-filter: blur(2px);
}

.lead-form {
  display: flex;
  flex-direction: column;
  padding: 28px 24px calc(24px + env(safe-area-inset-bottom, 0px));
  max-height: inherit;
  overflow-y: auto;
  position: relative;
}

/* ---------- Close button — icon only, no pill/border/shadow ---------- */

.lead-dialog__close {
  position: absolute;
  top: 16px;
  right: 16px;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  color: var(--color-white);
  cursor: pointer;
}

.lead-dialog__close svg {
  transition: opacity 0.15s ease;
}

.lead-dialog__close:hover svg,
.lead-dialog__close:active svg {
  opacity: 0.6;
}

.lead-dialog__close:focus-visible {
  outline: 2px solid var(--color-white);
  outline-offset: 2px;
}

.lead-dialog__title {
  margin: 0 0 8px;
  padding-right: 44px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(20px, 2.4vw + 12px, 24px);
  line-height: 1.15;
  text-transform: uppercase;
  color: var(--color-white);
}

/* The project has no literal "Bounded" file — the display font used
   everywhere else on the page (headline, logo) is "Unbounded", the free
   open-source counterpart, loaded via var(--font-display). Using that
   same token here keeps the ₽ glyph consistent with the rest of the
   brand's display type instead of silently falling back to nothing. */
.ruble-symbol {
  font-family: var(--font-display);
  font-weight: inherit;
  font-size: inherit;
  line-height: inherit;
}

.lead-dialog__subtitle {
  /* Fixed 40px gap to the first field's INPUT (its resting, inactive
     position) — not reserved for the floated label. Once that label
     rises out above the input, the visible gap to it shrinks below 40
     on its own; that's expected here, not compensated for. */
  margin: 0 0 40px;
  font-family: var(--font-text);
  font-size: 14px;
  line-height: 1.4;
  color: rgba(255, 255, 255, 0.68);
}

/* ---------- Fields ---------- */

.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  /* Same reservation logic as the subtitle above: 16px target gap to the
     next field + 22px floated-label clearance = 38px margin. */
  margin-bottom: 38px;
}

.field--last {
  /* Gap to the submit button — nothing floats downward into this space
     (a label only ever rises, away from the button), so this is a plain
     40px, no reservation needed. */
  margin-bottom: 40px;
}

.field__control {
  position: relative;
}

.field__input {
  width: 100%;
  height: 48px;
  padding: 0 16px;
  border-radius: 12px;
  border: 1px solid transparent;
  box-sizing: border-box;
  background: rgba(255, 255, 255, 0.05);
  color: var(--color-white);
  font-family: var(--font-text);
  font-size: 16px;
}

/* The visible "placeholder" is the floating label below — the native
   placeholder is only a single space, kept invisible, so :placeholder-shown
   still works as the empty/filled signal without showing duplicate text. */
.field__input::placeholder {
  color: transparent;
}

/* Hover and focus share one 1px white border — no outline, so there is
   only ever a single ring, never a doubled one. Invalid is declared last
   so a red field stays red even while hovered or focused. */
@media (hover: hover) {
  .field__input:hover {
    border-color: #fff;
  }
}

.field__input:focus-visible {
  outline: none;
  border-color: #fff;
}

.field__input[aria-invalid='true'] {
  border-color: #ff6b6b;
}

.field__input:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

/* Floating label: sits centered inside the input like a placeholder by
   default, and on focus or once the field has a value, slides up above
   the input's own top border. Position is transform-only (translateY),
   so it never triggers layout shift or a change in line-height/font-size. */
.field__label {
  position: absolute;
  left: 16px;
  top: 50%;
  margin-top: -7px;
  font-family: var(--font-text);
  font-size: 14px;
  line-height: 14px;
  color: rgba(255, 255, 255, 0.5);
  pointer-events: none;
  transform: translateY(0);
  transition: transform 0.18s ease, color 0.18s ease;
}

.field__input:focus + .field__label,
.field__input:not(:placeholder-shown) + .field__label,
.field__input:-webkit-autofill + .field__label {
  /* Measured against the rendered box (getBoundingClientRect), not
     hand-derived: this puts the label's bottom edge exactly 8px above
     the input's top border, every time. */
  transform: translateY(-39px);
}

.field__hint {
  margin: 0;
  font-family: var(--font-text);
  font-size: 14px;
  line-height: 1.4;
  color: rgba(255, 255, 255, 0.5);
}

.field__error {
  margin: 0;
  font-family: var(--font-text);
  font-size: 12px;
  line-height: 1.4;
  color: #ff8a8a;
}

.field--honeypot {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.lead-form__status {
  margin: 0 0 16px;
  padding: 12px 14px;
  border-radius: 10px;
  font-size: 14px;
  line-height: 1.4;
}

.lead-form__status--error {
  background: rgba(255, 107, 107, 0.12);
  color: #ff9a9a;
}

/* ---------- Success dialog (Figma node 802:2740) ----------
   Its own separate <dialog> (sharing .lead-dialog's chrome — radius,
   background, backdrop, mobile bottom-sheet), opened in place of the
   form dialog once a lead is accepted. This is the "успешно заполнившим
   анкету" state from the attached design, adapted to our compact dialog
   (the original is a full 1440-wide page moment with scattered
   portfolio mockups behind it; that background doesn't translate to a
   440px modal, so this keeps the essential content — check, headline
   with the handwritten "отправлена" + underline, and the "Готово"
   button — at our dialog's own type scale).

   display is set only under [open]: a plain unconditional `display: flex`
   here would (like on any element) override the UA stylesheet's
   `dialog:not([open]) { display: none }`, since normal author rules
   always beat UA rules regardless of specificity — which would make the
   dialog render even while closed. */
.lead-success {
  background: #141414;
  overflow: hidden;
}

.lead-success[open] {
  display: flex;
}

/* The scattered-mockups background layer and the giant "ENCASE" watermark
   below are absolutely positioned, so they sit outside this flex flow —
   .lead-success__content (the check/headline/subtitle/button group) ends
   up as the only flex item, which is what actually gets centered. */
.lead-success__content {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 16px;
  padding: 40px 24px calc(40px + env(safe-area-inset-bottom, 0px));
  position: relative;
  z-index: 1;
  margin: auto;
}

.lead-success__check {
  width: 40px;
  height: auto;
}

.lead-success__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  /* Figma: 40.938px at the 1440px reference frame — scales with viewport
     width the same way the mockups/watermark below do, clamped so it
     stays legible at both very small and very large widths. */
  font-size: clamp(24px, 2.84vw, 41px);
  line-height: 1.3;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  color: var(--color-white);
}

.lead-success__script {
  position: relative;
  display: inline-block;
  margin-top: 6px;
  font-family: var(--font-script);
  font-weight: 700;
  font-size: 1.25em;
  color: var(--color-orange);
}

.lead-success__underline {
  position: absolute;
  left: 0;
  bottom: -10px;
  width: 100%;
  height: auto;
  pointer-events: none;
}

.lead-success__subtitle {
  margin: 4px 0 0;
  font-family: var(--font-text);
  font-size: 16px;
  line-height: 1.4;
  letter-spacing: -0.02em;
  color: var(--color-white);
}

.lead-success__done {
  margin-top: 8px;
  height: 48px;
  padding: 0 32px;
  border: none;
  border-radius: 100px;
  /* Extra stop + double-width background so hover can slide the gradient
     across itself (background-position) instead of just swapping colors —
     matches the main CTA / stub page's orange buttons. */
  background-image: linear-gradient(90deg, var(--color-orange) 0%, var(--color-orange-dark) 50%, var(--color-orange) 100%);
  background-size: 200% 100%;
  background-position: 0% 0%;
  color: var(--color-white);
  font-family: var(--font-text);
  font-weight: 500;
  font-size: 16px;
  cursor: pointer;
  transition: background-position 0.5s ease;
}

.lead-success__done:hover {
  background-position: 100% 0%;
}

.lead-success__done:focus-visible {
  outline: none;
}

/* ---------- Success dialog background: scattered mockups + watermark ----------
   Positions/rotations below are each mockup's center point in the Figma
   frame (1440x900), converted to % of that frame so they scale with the
   dialog; image box size (163x107 in the design) is carried as vw so it
   scales with viewport width the same way. Decorative only — hidden from
   the accessibility tree and never intercepts pointer events, and sits
   behind .lead-success__content via z-index (both are absolutely
   positioned, which by default would otherwise paint above the plain
   in-flow content). */
.success-mockups {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

/* Mockups: hidden at rest, fade in shortly after the dialog opens, hold
   for ~3s, then fall straight through the bottom of the screen — each on
   its own slight delay and with its own extra spin (--fall-rot) added on
   top of its resting --rot, so the drop reads as chaotic rather than a
   single uniform slide. Both animations restart automatically each time
   the dialog re-opens: a closed <dialog> is display:none, which stops
   and resets CSS animations, so there's no JS needed to replay this. */
.success-mockup {
  position: absolute;
  width: 11.32vw;
  height: 7.43vw;
  object-fit: cover;
  border-radius: 6px;
  box-shadow: 0 12px 24px rgba(0, 0, 0, 0.35);
  opacity: 0;
  transform: translate(-50%, -50%) rotate(var(--rot));
  animation: success-mockup-in 0.45s ease forwards, success-mockup-fall 0.9s cubic-bezier(0.55, 0.06, 0.68, 0.19) forwards;
  animation-delay: var(--in-delay, 0.3s), var(--fall-delay, 3s);
}

@keyframes success-mockup-in {
  to {
    opacity: 1;
  }
}

@keyframes success-mockup-fall {
  to {
    transform: translate(-50%, -50%) translateY(140vh) rotate(calc(var(--rot) + var(--fall-rot)));
  }
}

.success-mockup--4 {
  overflow: hidden;
  background: #d9d9d9;
}

.success-mockup--4 img {
  position: absolute;
  width: 107.44%;
  height: 174.05%;
  left: -4.08%;
  top: -66.77%;
  max-width: none;
}

.success-mockup--1 { left: 16.09%; top: 79.49%; --rot: 59.31deg; --in-delay: 0.3s; --fall-delay: 3s; --fall-rot: -8deg; }
.success-mockup--2 { left: 22.8%; top: 105.67%; --rot: -160.84deg; --in-delay: 0.35s; --fall-delay: 3.08s; --fall-rot: 11deg; }
.success-mockup--3 { left: 77.3%; top: 84.58%; --rot: -48.32deg; --in-delay: 0.4s; --fall-delay: 3.04s; --fall-rot: -6deg; }
.success-mockup--4 { left: 68.37%; top: 80.23%; --rot: -9.97deg; --in-delay: 0.45s; --fall-delay: 3.12s; --fall-rot: 9deg; }
.success-mockup--5 { left: 22.74%; top: 66.28%; --rot: 85.41deg; --in-delay: 0.5s; --fall-delay: 3.02s; --fall-rot: -11deg; }
.success-mockup--6 { left: 70.66%; top: 84.79%; --rot: 51.38deg; --in-delay: 0.55s; --fall-delay: 3.16s; --fall-rot: 7deg; }
.success-mockup--7 { left: 98.54%; top: 91.4%; --rot: 55.44deg; --in-delay: 0.6s; --fall-delay: 3.06s; --fall-rot: -9deg; }
.success-mockup--8 { left: 86.65%; top: 85.29%; --rot: 13.95deg; --in-delay: 0.65s; --fall-delay: 3.1s; --fall-rot: 13deg; }

/* The exact Figma artwork (802:2742 "Mask group"): the word "ENCASE" as 6
   letter-shaped vector paths, used there as a mask over a soft top-to-
   bottom gradient. Reproduced the same way — mask-image with the real
   asset, background is the gradient it clips — rather than approximating
   it with styled text. Position/size are that mask's exact box in the
   1440x900 reference frame (left 12.45px, top 794.44px, 1461.85x262.175),
   converted to % / vw so it scales with the dialog like the mockups do. */
.success-watermark {
  position: absolute;
  z-index: 0;
  left: 0.86%;
  top: 88.27%;
  width: 101.51vw;
  height: 18.21vw;
  -webkit-mask-image: url('../svg/success-watermark.svg');
  mask-image: url('../svg/success-watermark.svg');
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  background: linear-gradient(179.27deg, rgba(255, 255, 255, 0.26) 3%, rgba(20, 20, 20, 0.26) 63.3%);
  pointer-events: none;
  opacity: 0;
  animation: success-watermark-in 0.6s ease forwards;
  animation-delay: 0.1s;
}

@keyframes success-watermark-in {
  to {
    opacity: 1;
  }
}

.lead-form__submit {
  height: 52px;
  border: none;
  border-radius: 100px;
  background: linear-gradient(90deg, var(--color-orange) 0%, var(--color-orange-dark) 100%);
  color: var(--color-white);
  font-family: var(--font-text);
  font-weight: 500;
  font-size: 16px;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}

/* Disabled = not all three fields currently pass validation (this covers
   both "nothing typed yet" and "a submit attempt found an error and it
   hasn't been fixed"). Slightly lighter than the dialog surface, with
   gray text — distinct from the bright orange "ready to send" state. */
.lead-form__submit:disabled {
  background: rgba(255, 255, 255, 0.08);
  color: rgba(255, 255, 255, 0.4);
  cursor: not-allowed;
}

.lead-form__submit:focus-visible {
  outline: 2px solid var(--color-white);
  outline-offset: 2px;
}

@media (max-width: 767px) {
  .lead-dialog {
    width: 100%;
    max-width: none;
    margin: auto 0 0;
    border-radius: 32px 32px 0 0;
    max-height: 90dvh;
  }
}

@media (prefers-reduced-motion: no-preference) {
  .lead-dialog {
    transition: opacity 0.18s ease, transform 0.18s ease, overlay 0.18s ease allow-discrete, display 0.18s ease allow-discrete;
  }
}

/* Success dialog opens fullscreen, not at the form dialog's compact size —
   same specificity as .lead-dialog (including its mobile override above),
   so placing this last makes it win at every viewport width. inset:0 on
   a top-layer dialog resolves against the actual current viewport, same
   as 100vw/100dvh would — but unlike those two, it isn't a value iOS
   Safari can leave stale after an orientation-change round-trip (see
   assets/js/viewport-fix.js), so it can't reopen at the wrong size. */
.lead-success {
  inset: 0;
  width: auto;
  max-width: none;
  height: auto;
  max-height: none;
  margin: 0;
  border-radius: 0;
  justify-content: center;
}
