/* ============================================================
   Lustify brand overlay on top of candy.ai cloned styles.
   Loaded AFTER /assets/style.css to win the cascade.
   ============================================================ */

/* font-display: optional → browser shows fallback if web font isn't ready in
   ~100ms (no late swap → no reflow / "jumping" text on slow connections).
   On fast networks (cached) font still loads. Safari especially sensitive to
   swap-induced layout shift. */
@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;400;500;600;700&display=optional');

/* ---------- 1. Brand variables override --------------------- */
:root {
  --primary-color: #e23cc5 !important;
  --secondary-color: #c438ef !important;
  --surface-primary-color: #11152b !important;
  --primary-color-hover: #190b1b !important;
  --primary-color-semi: rgba(226, 60, 197, 0.45) !important;
  --primary-color-medium: #8b2a83 !important;
  --progress-color: #e23cc5 !important;
  --loading-gradient-color: #ff409a !important;
  --end-gradient-color: #c438ef !important;
  --loading-text-color: #ff409a !important;
  --token-label-bg: #c438ef !important;
  --caret-color: #e23cc5 !important;
  --variant-b-premium-cta: linear-gradient(135deg, #ff409a, #c438ef) !important;
  --variant-b-premium-modal-cta: linear-gradient(135deg, #ff409a, #c438ef) !important;
  --variant-b-premium-tab-border: #e23cc5 !important;
  --card-image-overlay: linear-gradient(0deg, rgba(17,21,43,0.7) 0%, rgba(17,21,43,0.7) 100%) !important;
}

/* ---------- 2. Font ----------------------------------------- */
/* Define a size-adjusted system fallback so that when Plus Jakarta Sans
   loads (or doesn't), text metrics stay consistent and don't reflow. */
@font-face {
  font-family: 'Jakarta Fallback';
  src: local('Helvetica Neue'), local('Arial');
  size-adjust: 100%;
  ascent-override: 96%;
  descent-override: 24%;
  line-gap-override: 0%;
}

html, body, *, *::before, *::after,
.font-poppins, .font-roboto, [class*="font-"] {
  font-family: 'Plus Jakarta Sans', 'Jakarta Fallback', system-ui, -apple-system, sans-serif !important;
}

/* ---------- 3. Backgrounds --------------------------------- */
html, body {
  background-color: #050613 !important;
  color: #f3f4f6 !important;
}

/* The candy palette uses #131313 / #1a1a1a / #1c1c1c for surfaces.
   Map all to lustify panel #11152b */
[class*="bg-zinc-900"], [class*="bg-zinc-800"], [class*="bg-neutral-900"],
[class*="bg-gray-900"], [class*="bg-black-medium"], [class*="bg-black-light"],
[class*="bg-surface-primary"],
[style*="rgb(30, 30, 30)"], [style*="rgb(28, 28, 28)"],
[style*="rgb(26, 26, 26)"], [style*="rgb(19, 19, 19)"],
[style*="rgb(24, 24, 27)"], [style*="#131313"], [style*="#1a1a1a"],
[style*="#1c1c1c"], [style*="#1C1C1C"] {
  background-color: #11152b !important;
}

/* Pure-black surfaces -> deepest lustify */
[class*="bg-black"]:not([class*="bg-black-"]),
[style*="background:#000"], [style*="background-color:#000"],
[style*="background: #000"], [style*="background-color: #000"],
[style*="rgb(0, 0, 0)"] {
  background-color: #050613 !important;
}

/* Slight elevation panels -> magenta-tinted */
[class*="bg-zinc-700"], [class*="bg-neutral-800"], [class*="bg-gray-800"],
[style*="rgb(54, 54, 54)"], [style*="rgb(66, 66, 66)"],
[style*="#363636"], [style*="#424242"] {
  background-color: #190b1b !important;
}

/* ---------- 4. CTA / accent buttons ------------------------ */
.bg-primary,
button.bg-primary,
[class*="bg-primary"]:not([class*="bg-primary-"]),
button[class*="bg-pink"], button[class*="bg-rose"], button[class*="bg-red-"],
a[class*="bg-pink"], a[class*="bg-rose"], a[class*="bg-red-"],
[class*="bg-pink-500"], [class*="bg-rose-500"], [class*="bg-red-500"],
[class*="bg-pink-600"], [class*="bg-rose-600"], [class*="bg-red-600"],
[style*="rgb(231, 81, 117)"], [style*="rgb(231, 82, 117)"],
[style*="rgb(249, 113, 135)"], [style*="rgb(231, 80, 115)"],
[style*="rgb(213, 75, 108)"], [style*="rgb(225, 79, 114)"],
[style*="#e75175"], [style*="#E75175"],
[style*="#f97187"], [style*="#F97187"],
[style*="#d54b6c"], [style*="#D54B6C"],
[style*="#e14f72"], [style*="#E14F72"] {
  background: linear-gradient(135deg, #ff409a, #c438ef) !important;
  background-color: transparent !important;
  border-color: transparent !important;
  color: #fff !important;
}

/* ---------- 5. Progress bar -------------------------------- */
[class*="progress"] > *, [role="progressbar"] > *,
[class*="bg-pink-500"], [class*="bg-rose-500"],
.progress-bar, .progress > .bar {
  background: linear-gradient(90deg, #ff409a, #c438ef) !important;
}

/* ---------- 6. Text colors --------------------------------- */
[class*="text-zinc-400"], [class*="text-gray-400"],
[class*="text-neutral-400"], [class*="text-zinc-500"],
[class*="text-gray-500"], [class*="text-white\\/80"],
[class*="text-white/60"], [class*="text-white/80"] {
  color: #b1b5db !important;
}
[class*="text-zinc-600"], [class*="text-gray-600"], [class*="text-neutral-500"] {
  color: #7d829e !important;
}
.text-primary, [class*="text-primary"] {
  color: #ff5fb1 !important;
}

/* White text stays white but tint pure-white container backgrounds rarely.
   Keep .text-white as-is. */

/* ---------- 7. Selected / ring states ---------------------- */
[class*="ring-pink"], [class*="border-pink"],
[class*="ring-rose"], [class*="border-rose"],
[class*="ring-red"], [class*="border-red"],
.border-primary, [class*="border-primary"] {
  border-color: #e23cc5 !important;
  --tw-ring-color: #e23cc5 !important;
}

/* Form fields */
input, textarea, select {
  background-color: #190b1b !important;
  border-color: #2a2046 !important;
  color: #f3f4f6 !important;
}
input::placeholder, textarea::placeholder { color: #7d829e !important; }
input:focus, textarea:focus, select:focus {
  border-color: #e23cc5 !important;
  outline-color: #e23cc5 !important;
}

/* ---------- 8. Logo / brand text --------------------------- */
.lustify-brand {
  font-weight: 700;
  background: linear-gradient(135deg, #ff409a, #c438ef);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  letter-spacing: -0.01em;
}

/* Hide candy raster logos we replaced inline via build.py — but if
   any remain, give them a subtle tint via filter so they don't look
   out of place. */
img[alt="CandyAI" i], img[alt="Candy.ai" i] {
  filter: hue-rotate(290deg) saturate(1.2);
}

/* ---------- 9. Misc gradients we want to overwrite ---------- */
[style*="linear-gradient(240deg, rgb(77, 29, 40)"],
[style*="linear-gradient(90deg, rgb(19, 19, 19) 0%, rgb(50, 29, 65)"] {
  background: linear-gradient(135deg, rgba(226,60,197,0.18), rgba(17,21,43,0)) !important;
}

/* Card overlays / fades that referenced #131313 */
[style*="rgba(19, 19, 19"] {
  background: linear-gradient(to bottom, transparent 0%, rgba(5,6,19,0.5) 50%, #050613 100%) !important;
}

/* Sidebar / nav backdrop */
nav, header, aside, footer {
  background-color: transparent;
}
nav[class*="bg-"], header[class*="bg-"] {
  background-color: rgba(17, 21, 43, 0.85) !important;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}

/* ---------- 10. Mobile fixes (≤1023px) ---------------------- */
/* The candy.ai sidebar is a <nav class="webkit-transition-sidebar ...">
   anchored fixed top-0 left-0 w-[100px] h-full on mobile, hidden behind a
   hamburger toggle that ran via JS we stripped. Without JS the panel sits
   permanently visible at 100px wide and crushes the funnel content.
   Hide it (plus any aside/sidebar-ish element) on small viewports. */
@media (max-width: 1023px) {
  nav.webkit-transition-sidebar,
  nav[class*="webkit-transform-sidebar"],
  nav[class*="sidebar"],
  [class*="webkit-transition-sidebar"],
  aside[class*="sidebar"],
  aside[class*="side-nav"],
  aside[class*="side_nav"],
  [class*="SideBar"],
  [class*="LeftNav"],
  [class*="left-nav"] {
    display: none !important;
    visibility: hidden !important;
    width: 0 !important;
  }

  /* Tooltips that follow the (now-hidden) sidebar items */
  .tooltip-sidebar { display: none !important; }

  /* Some candy markup pushes main content right via padding/margin for the
     sidebar gutter; reset on mobile so content fills the viewport. */
  main, [class*="main-content"], [class*="content-wrapper"],
  [class*="lg:pl-"], [class*="lg:ml-"] {
    padding-left: 0 !important;
    margin-left: 0 !important;
  }

  /* Tighten header padding so the CTA ("Create Free Account") doesn't clip */
  header, [class*="header"]:not([class*="header-"]), nav[class*="navbar"] {
    padding-left: 12px !important;
    padding-right: 12px !important;
  }

  /* Drop the Login link on mobile — keeps the primary signup CTA visible */
  header a[href*="login"], header a[href*="sign_in"],
  header a[href*="login_pop_up"],
  nav a[href*="login"], nav a[href*="sign_in"],
  button[class*="login"], a[class*="login"] {
    display: none !important;
  }
}

/* ---------- 11. Funnel selection highlight + generation UI ---------- */

/* Hide candy.ai's static "Selected" checkmark icons baked into the HTML dump.
   They appear on every card by default since JS toggle was stripped during
   prototype build, which made several options look pre-selected. Our own
   .lustify-selected ::after checkmark replaces them. CSS-only so they NEVER
   flash on initial paint (was a Safari FOUC source). */
img[alt="Selected"],
img[src*="checkmark-"] {
  display: none !important;
}

/* candy.ai server-rendered some radios with `checked` attribute. The CSS-only
   sibling-checked selector adds a white box-shadow ring → looks like a fake
   selection. Strip it so cards start unselected. */
input[type="radio"]:checked + *,
.radio-button-card__content:has(input[type="radio"]:checked) {
  box-shadow: none !important;
}

/* Kill the static white ring (box-shadow 0 0 0 3px white) that the dumped
   HTML applies to candy's default-checked card (Straight, Black, etc).
   Restored only on .lustify-selected by section 11 below. */
.radio-button-card__content {
  box-shadow: none !important;
}
label img[alt="Selected"] { display: none !important; }

.lustify-selected {
  position: relative;
  /* Safari/WebKit fix: <label> defaults to display:inline, so position:relative
     on an inline element makes its containing block the *line box*, not the
     element's visual rect. The ::after checkmark then lands on the wrong corner
     (top-left of the line box instead of top-right of the card). Forcing
     block-level layout pins the containing block to the visual rect. */
  display: block;
  transform: scale(1.015);
  transition: transform .15s ease;
}
/* Apply the same to all candy.ai option labels so geometry is consistent before
   selection (matches the layout used on step-1/2/3/4 cards). */
label:has(> .radio-button-card__content),
label:has(> video),
label:has(> img[alt]:not([alt="Selected"])) {
  display: block;
}
/* Apply the actual pink frame to the inner image card — it has overflow:hidden
   on the outer label so we use INSET box-shadow which always renders inside. */
.lustify-selected .radio-button-card__content {
  box-shadow:
    inset 0 0 0 4px #ff409a,
    inset 0 0 32px rgba(255, 64, 154, 0.45) !important;
  border-radius: 14px;
}
/* Fallback for our injected Outfit buttons + any non-candy card layouts
   that don't have the radio-button-card__content child. */
.lustify-selected:not(:has(.radio-button-card__content)) {
  outline: 3px solid #ff409a !important;
  outline-offset: 2px;
  box-shadow: 0 0 18px rgba(255, 64, 154, 0.45) !important;
  border-radius: 12px;
}
.lustify-selected::after {
  content: "✓";
  position: absolute;
  top: 6px;
  right: 6px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: linear-gradient(135deg, #ff409a, #c438ef);
  color: #fff;
  font-weight: 700;
  font-size: 13px;
  line-height: 22px;
  text-align: center;
  z-index: 5;
  pointer-events: none;
}
.lustify-spinner {
  display: inline-block;
  width: 48px;
  height: 48px;
  border: 4px solid rgba(255, 255, 255, 0.1);
  border-top-color: #ff409a;
  border-radius: 50%;
  animation: lustify-spin 1s linear infinite;
}
@keyframes lustify-spin { to { transform: rotate(360deg); } }
.lustify-gen-status {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  padding: 32px;
  color: #f3f4f6;
  text-align: center;
  width: 100%;
  height: 100%;
  justify-content: center;
}

/* ---------- 11.5 Card click fix ---------------------- */
/* candy.ai labels (step-1 style cards, step-2/3/4 attribute cards) wrap a
   <video> or <img> which swallows pointer events. We disable pointer events
   on the inner media so clicks bubble to <label>, where our delegate picks
   them up. Selectors are broad — any media child of any label. */
html body label {
  cursor: pointer !important;
}
html body label > video,
html body label > img,
html body label video.cursor-pointer,
html body label img.cursor-pointer,
html body label .radio-button-card__content,
html body label .radio-button-card__content *,
html body label [class*="aspect-"] {
  pointer-events: none !important;
}

/* Reduce candy.ai's huge `pb-28` (112px) bottom padding on the last fieldset
   of each step — that gap was reserved for a floating NEXT button we don't
   render on mobile. Cuts the "empty space" between Breast Size and our
   injected Outfit section. */
fieldset.pb-28,
fieldset[class*="pb-28"] {
  padding-bottom: 16px !important;
}

/* ---------- 12. Lustify customisation ---------------------- */
/* ---------- 12a. Pre-paint hides (kill FOUC) ----------------- */
/* Hide candy.ai elements via CSS during initial render so Safari doesn't
   flash them before our JS data-lustify-hidden cleanup runs. */
button.nav-hamburger,
button[class*="nav-hamburger"],
[class*="nav-hamburger"],
/* Header CTAs */
[data-action*="openRegistrationModal"],
[data-action*="openSignInModal"],
[data-action*="closeMobileMenuAndOpenRegistrationModal"],
/* Trans gender pill */
#gender-tab-trans,
button[id^="gender-tab-trans"],
button[data-gender="male_to_female_trans"],
/* Locale switcher and mobile menu triggers in the header */
[data-action*="locale-switcher"],
[data-action*="handleMenuClick"],
[data-action*="setMobileSidebarValueToDefault"] {
  display: none !important;
}

/* Hide header CTAs and hamburger menu — Lustify funnel has no nav. */
header a[href*="sign_up"],
header a[href*="signup"],
header a[href*="login"],
header a[href*="sign_in"],
header button[class*="hamburger"],
header button[aria-label*="menu" i],
header button[aria-label*="hamburger" i],
header [class*="hamburger"],
header [class*="burger"],
header [class*="open-side"],
nav button[aria-label*="menu" i],
button[class*="cookie"],
a:has(> svg[class*="hamburger"]),
[class*="hamburger-btn"] {
  display: none !important;
}
/* The standalone Create Free Account / Login pill block in the top-right. */
header > a, header > button,
header [class*="signup"], header [class*="login"],
header [class*="create-free-account"] {
  display: none !important;
}

/* Hide candy.ai sidebar on ALL viewports — Lustify has no nav menu. */
nav.webkit-transition-sidebar,
nav[class*="webkit-transform-sidebar"],
[class*="webkit-transition-sidebar"],
.tooltip-sidebar {
  display: none !important;
}

/* Reset main content layout that was padded for the (now-hidden) sidebar. */
main, [class*="main-content"], [class*="content-wrapper"],
[class*="lg:pl-"], [class*="lg:ml-"] {
  padding-left: 0 !important;
  margin-left: 0 !important;
}

/* Hide Trans gender pill — only Girls option in Lustify. The pill is the
   button containing the male/trans icon next to the Girls pill. We can't
   target by exact text because layout uses an SVG icon, so we target the
   *second* button inside the gender fieldset (Girls is first). */
fieldset:has(button:nth-of-type(2)) > button:nth-of-type(2),
[class*="gender"] button:nth-of-type(2),
[class*="profile_gender"] button:nth-of-type(2) {
  display: none !important;
}

/* Lustify-specific data attribute: when funnel-state.js relabels Anime→Amateur
   it tags the label with data-lustify-style="amateur" so we can theme later. */
[data-lustify-hidden="true"] {
  display: none !important;
}
