/* ============================================================
   Verion Chat Widget — fixed bottom-left dock that opens into a
   left-side panel. Design system pulled 1:1 from the Off Menu
   reference screenshots (near-black #0B0B0B panel, 24px corners,
   subtle white-at-low-alpha borders, no accent colour beyond white
   itself). Chat panel is a short docked box; "Book a Call"
   collapses that back down and re-opens it much taller/wider to
   host the 6-step wizard comfortably.

   Every animation from the pasted onboarding React reference is
   ported here as CSS transitions/keyframes matched to the same
   timings (fadeInUp: y 20→0 / 0.3s; contentVariants: x 50→0 in
   0.3s, exit x -50 in 0.2s; progress row entrance y -20→0 / 0.5s;
   card entrance y 20→0 / 0.5s @ 0.2s delay; option stagger
   delay 0.1s × index; hover scales 1.02/1.05/1.1, tap scales
   0.98/0.95).

   Everything is namespaced under `.vc-*` so nothing else on the
   site can collide with these rules.
   ============================================================ */

/* ---- Real shadcn dark-theme tokens, measured live off the actual
   21st.dev component render (cdn.21st.dev bundle, computed styles
   read directly via devtools-equivalent JS, not guessed from
   Tailwind class names). These are the true oklch values converted
   to hex, used ONLY inside the booking wizard so its card genuinely
   sits as a lighter elevated layer above the panel - the depth cue
   the flat near-black version was missing. ---- */
:root {
  --vc-wiz-bg: #0a0a0a;        /* oklch(0.145 0 0) - page/panel background */
  --vc-wiz-card: #1a1a1a;      /* oklch(0.205 0 0) - card sits lighter, above bg */
  --vc-wiz-fg: #fbfbfb;        /* oklch(0.985 0 0) - foreground text */
  --vc-wiz-muted-fg: #b4b4b4;  /* oklch(0.708 0 0) - muted-foreground (descriptions) */
  --vc-wiz-muted: #454545;     /* oklch(0.269 0 0) - muted bg (bar track, inactive dot) */
  --vc-wiz-primary: #ebebeb;   /* oklch(0.922 0 0) - primary (buttons, active dot/bar) */
  --vc-wiz-primary-fg: #1a1a1a;/* oklch(0.205 0 0) - text/icon on primary */
  --vc-wiz-border: rgba(255,255,255,.15); /* border-input / card border ~10-15% white */
}

/* ---- Idle dock: always-extended pill, slightly wider than before ---- */
.vc-root {
  position: fixed;
  left: 20px;
  bottom: 20px;
  z-index: 90;
  font-family: var(--font-body);
  color: #fff;
}
/* The "blurred shape behind the text" idea (2026-09-16 -> 2026-09-18)
   went through two failed text-shadow attempts before this - text-
   shadow only ever traces the glyph outlines and approximates its blur
   with a box-blur, so no amount of tuning it ever gave the "soft pale
   shape sitting behind the text" look that was actually being asked
   for; it also kept reading as a harder edge than intended. Removed
   entirely. The RIGHT version of this already existed elsewhere in
   this file, untouched this whole time: see .vc-msg-text::before below
   for the actual chat-bubble text, which uses a real blurred panel
   (backdrop-filter blur + a radial-gradient MASK, which is what
   genuinely fades to nothing at its own edges with no hard boundary,
   rather than text-shadow's approximation) - now recolored pale per
   explicit request instead of dark. */
/* Sizing/font/color matched to the reference (Off Menu), read
   directly off their live page's computed styles rather than
   guessed from a screenshot: pill height 58px, text is "Neue
   Montreal" at 14px/350 weight, color rgb(237,236,236) - a warm
   off-white, not pure #fff. Neue Montreal itself is a paid commercial
   font we can't legally bundle, so it's listed first (used if the
   visitor happens to already have it installed) with Switzer -
   already loaded site-wide - as the fallback. */
/* Rewritten 2026-09-13: .vc-dock (the button) now lives INSIDE
   .vc-panel instead of as a separate sibling element that crossfaded
   with it. Reference video analysis: the pill doesn't fade away while
   a different box fades in - the SAME shape visibly contracts to a
   circle, widens, then heightens (and reverses the same way on
   close/switch). That requires one element whose box IS what's
   animating, with the idle icon+label and the open panel content as
   two layers inside it that cross-fade - not two separately-sized
   elements. See setupMorph()/openSequence() etc. in verion-chat.js
   for the actual phase choreography; this file just declares the
   box's own transition and the two content layers. */
.vc-dock {
  /* Normal flow (NOT absolutely positioned) is what's actually
     load-bearing here: with .vc-panel-inner pulled out of flow via
     position:absolute below, .vc-dock is .vc-panel's only in-flow
     child, so its own content (icon+label+padding) is exactly what
     determines the panel's shrink-to-fit idle width - no hardcoded
     idle width needed anywhere, and measureIdleWidth() in JS can
     reliably read it back whenever it needs to. */
  position: relative;
  height: 100%;
  appearance: none;
  -webkit-appearance: none;
  background: none;
  border: none;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 9px 27px 9px 8px; /* right side extended a little (22 -> 27) to give the pill more room */
  cursor: pointer;
  color: rgb(237, 236, 236);
  font-family: 'Neue Montreal', var(--font-body);
  font-size: 14px;
  font-weight: 350;
  letter-spacing: 0.2px;
  white-space: nowrap;
  outline: none;
}
/* The icon+label stay visible with no opacity toggle through every
   phase of the actual morph (pill -> circle -> widen -> heighten) -
   that part of the "never disappears, only the text crossfades" ask
   is correct and unchanged. BUT once the box is fully open and real
   content is ready, .vc-panel-inner does NOT reliably cover it - its
   own empty areas (e.g. the chat body before any messages exist) are
   transparent, not opaque, so the dock was showing straight through
   as a stray second icon/"Ask me anything" floating mid-panel. Fixed
   by explicitly hiding the dock once vc-content-ready lands (after
   the morph finishes) - the real input row at the bottom is the only
   icon+"Ask me anything" left visible from that point on. */
.vc-root.vc-is-open .vc-dock {
  pointer-events: none;
}
.vc-root.vc-content-ready .vc-dock {
  opacity: 0;
  visibility: hidden;
}
.vc-dock:focus-visible {
  outline: 2px solid rgba(255,255,255,.55);
  outline-offset: -4px;
}
/* Nudges just the text, independent of the icon - translate doesn't
   affect layout/flow, so this can't shift the icon or change the
   gap between them. Its own opacity transition is what lets the label
   crossfade between "Let's work together" (idle) and "Ask me
   anything" (open) right as the pill passes through the circle -
   see setLabel() in verion-chat.js. */
.vc-dock-label {
  transition: opacity .2s ease;
  transform: translate(3px, 2px);
}
/* Ambient orb icon - a 10-dot outer ring plus a tight 4-dot centre
   cluster (14 dots total), shared by the dock pill and the chat
   input row so both read as the same mark. Matches the user's
   reference structure exactly, not a plain single ring. Real per-dot
   elements (not a CSS `background` trick) so each one genuinely
   animates. No rotation on the container itself - explicitly NOT a
   continuously-spinning icon; the only rotation is the small twist
   each dot carries through its own retract/expand cycle below. */
.vc-dock-icon, .vc-input-icon {
  position: relative;
  width: 40px;
  height: 40px;
  flex-shrink: 0;
}
.vc-orb-svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}
/* Every dot shares this one cycle with no per-dot delay, so the
   whole cluster (ring + centre) retracts and releases together as a
   single synchronized breath, not a travelling wave. The midpoint
   position (--mx/--my, computed in orbSVG()) is each dot's own rest
   vector pulled in toward the centre AND rotated a little - that
   small carried rotation is the "spin a little" from the reference
   component's own gather/release mechanic, and it fully unwinds back
   to 0 as the dot releases to its unrotated rest spot, so nothing
   drifts or accumulates across loops.
   Real <circle> elements now (not a div + border-radius): SVG's
   rasterizer draws true vector curves that stay crisp regardless of
   the fractional-pixel translate() below, which is what was making
   the old HTML-span dots look soft/blurry - `transform-box: fill-box`
   + `transform-origin: center` make scale() shrink toward the dot's
   OWN centre rather than the SVG viewport's corner. */
.vc-orb-dot {
  fill: rgba(245,245,244,.92);
  transform-box: fill-box;
  transform-origin: center;
  transform: translate(var(--ox), var(--oy));
  animation: vc-orb-pulse 6.5s ease-in-out infinite;
}
.vc-input-icon .vc-orb-dot { fill: rgba(245,245,244,.78); }
@keyframes vc-orb-pulse {
  /* Opacity held constant across the whole cycle - it used to dip to
     .3 at the squish point, which read as the color "getting weaker"
     instead of staying a strong, consistent white throughout. Only
     position/scale animate now. */
  0%, 100% { transform: translate(var(--ox), var(--oy)) scale(1); }
  50% { transform: translate(var(--mx), var(--my)) scale(.88); }
}
@keyframes vc-orb-spin { to { transform: rotate(360deg); } } /* still used by .vc-spinner */
@media (prefers-reduced-motion: reduce) {
  .vc-orb-dot { animation: none; }
}
/* ============================================================
   Panel — the ONE morphing box (pill -> chat/book box and back), not
   a separately-sized element that fades in while the dock fades out.
   Ported from the user-supplied 21st.dev "expandable-tabs" reference:
   its outer shell keeps ONE constant border-radius the entire time
   (their rounded-[26px], never transitioned) and only springs
   width/height - the shape reads as a full capsule while short
   (radius clamps to half the height) and a normal rounded-rect corner
   once tall (radius is well under half the height by then), purely as
   a side effect of the SAME number the whole time. BOX_RADIUS here is
   exactly half of PILL_H (58/2 = 29) for the same reason - see the
   morph sequencer comment in verion-chat.js for why animating
   border-radius itself (999 -> 24, the old approach) was what caused
   the corners to visibly snap/sharpen mid-expand.
   width/height are NOT CSS-transitioned any more - verion-chat.js now
   drives both every frame from a real JS spring (springBoxTo()),
   ported from the reference's own SHELL_SPRING. A CSS `transition` on
   a property some other engine is already writing every frame would
   just fight it (same reasoning as --mx/--my below not carrying a
   `transition`). Only `transform` (the idle pill's small resting
   nudge) still animates via plain CSS - unrelated to the box's own
   size. Idle size (the pill) is intentionally NOT set here - left to
   size itself to its .vc-dock content naturally, so it's always
   correct for whatever the label text needs with no hardcoded idle
   width. */
.vc-panel {
  position: absolute;
  left: 0;
  bottom: 0;
  height: 58px;
  /* Block-level flex container so .vc-dock (its only in-flow child -
     .vc-panel-inner is pulled out via position:absolute) is centred
     and sizes the panel's idle width to its own content. */
  display: flex;
  align-items: center;
  border-radius: 29px;
  color: rgba(245,245,244,.92);
  transform: translate(-5px, 5px); /* the pill's requested 5px-left/5px-down nudge - released once open */
  transition: transform .3s ease;
}
.vc-root.vc-is-open .vc-panel { transform: none; }
/* The actual visible black box - background/border/shadow all live
   HERE, on a pseudo-element, instead of directly on .vc-panel. That's
   what lets the hover-expand grow ONLY the box: .vc-panel itself has
   no overflow:hidden and no background of its own, so this layer can
   scale up freely without dragging .vc-dock's icon/text (real
   children, painted on top, completely unaffected by a transform on
   a totally separate element) along with it - they stay perfectly
   still while just the box underneath them grows. border-radius:
   inherit keeps it in sync with whatever shape .vc-panel is currently
   mid-morph into (JS sets that on .vc-panel, not this). */
.vc-panel::before {
  content: '';
  position: absolute;
  inset: 0;
  background: #0B0B0B;
  border: 1px solid rgba(255,255,255,.06);
  border-radius: inherit;
  box-shadow: 0 4px 14px rgba(0,0,0,.22), 0 2px 4px rgba(0,0,0,.1);
  pointer-events: none;
  /* --mx/--my/--scale: BOTH the magnetic follow and the hover/active
     scale pop are now driven by one continuous JS physics loop
     (magnetTick() in verion-chat.js - a real spring, matched to the
     user-supplied Magnetic component's exact constants) instead of a
     CSS transition on this property. A CSS `transition` here would
     fight a value that's already being updated every animation frame
     from JS, so `transition` below covers box-shadow only now. */
  transform: translate(var(--mx, 0px), var(--my, 0px)) scale(var(--scale, 1));
  transition: box-shadow .22s ease;
}
.vc-root.vc-is-open .vc-panel::before {
  box-shadow: 0 16px 44px rgba(0,0,0,.4), 0 4px 12px rgba(0,0,0,.18);
}
/* Idle-only hover/active box-shadow - the scale pop itself is JS-
   driven (see above), this just deepens the shadow to match. Gated
   off once open so it never fires on the full-size chat/book box. */
.vc-root:not(.vc-is-open) .vc-panel:hover::before {
  box-shadow: 0 6px 20px rgba(0,0,0,.28), 0 2px 6px rgba(0,0,0,.12);
}
/* Booking mode: panel is close to the reference's `max-w-lg` (512px)
   container width to keep the same field / padding proportions the
   reference is designed around, plus room for the taller inputs.
   Just the background swap here now - actual width/height are JS-set
   inline per phase (see targetDims() in verion-chat.js). */
.vc-root.vc-mode-book .vc-panel::before {
  background: var(--vc-wiz-bg);
}

.vc-panel-inner {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  overflow: hidden; /* .vc-panel itself no longer clips (see .vc-panel::before notes) - content clips here instead */
  display: flex;
  flex-direction: column;
  height: 100%;
  opacity: 0;
  pointer-events: none;
  /* Driven by vc-content-ready (added once the box finishes its full
     grow sequence, removed the instant a close/switch starts) rather
     than vc-is-open directly - vc-is-open flips the moment you click,
     long before the box has finished growing into shape. */
  transition: opacity .32s ease;
}
.vc-root.vc-content-ready .vc-panel-inner {
  opacity: 1;
  pointer-events: auto;
}

/* Header: tab switcher + close - no underline per Off Menu style,
   active tab is just white/bold, inactive is gray. */
.vc-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 18px 14px;
  flex-shrink: 0;
}
.vc-tabs {
  display: flex;
  gap: 18px;
}
.vc-tab {
  background: none;
  border: none;
  color: rgba(245,245,244,.5);
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  padding: 4px 0;
  transition: color .18s ease, font-weight .18s ease;
}
.vc-tab:hover { color: rgba(245,245,244,.8); }
.vc-tab.is-active {
  color: #fff;
  font-weight: 700;
}
.vc-close {
  width: 28px; height: 28px;
  border-radius: 999px;
  border: none;
  background: rgba(255,255,255,.08);
  color: rgba(245,245,244,.75);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background-color .18s ease, color .18s ease;
}
.vc-close:hover { background: rgba(255,255,255,.14); color: #fff; }
.vc-close svg { width: 12px; height: 12px; }

/* Body scroll region — scrollbar HIDDEN per spec. position:relative +
   z-index so its own content (the actual message text) stacks ABOVE
   .vc-orb-empty, its now-sibling (both positioned, so this is what
   decides which one paints on top - see that rule for why they're
   siblings and not nested). */
.vc-body {
  position: relative;
  z-index: 1;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  /* Stops scroll-chaining: once this list hits its own top/bottom
     edge, further wheel/touch delta must NOT bleed through to the
     page behind it. data-lenis-prevent (on .vc-panel) only stops
     Lenis's own wheel hijack from re-targeting the window scroll -
     it does nothing about the browser's native overscroll bounce
     handing leftover delta to the next scrollable ancestor once this
     one is exhausted, which is the actual cause of "the background
     also scrolls" once you scroll to the end of a short panel. */
  overscroll-behavior: contain;
  padding: 18px 20px;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.vc-body::-webkit-scrollbar { display: none; }
/* Per-step scroll lock (book mode only, see updateBodyLock() in
   verion-chat.js) - a step whose content actually fits the visible
   area shouldn't scroll/bounce at all (explicit fix: short steps like
   Team or the just-confirmed Location map were still rubber-banding
   even though there was nothing to reveal by scrolling); a step that
   genuinely overflows (Tools) keeps scrolling normally. Scoped to
   .vc-mode-book so a stale class left over from the wizard can never
   suppress scrolling on the actual chat transcript. */
.vc-root.vc-mode-book #vc-body.vc-body-locked { overflow-y: hidden; }

/* Since it's a flex column with justify-content:flex-end, a short
   conversation hugs the BOTTOM of the visible area instead of jamming
   up against the top - "the message goes up too much" - growing
   upward as more messages arrive, same as most chat UIs. min-height:
   100% is what gives justify-content room to push a short transcript
   down at all (.vc-body has a real flex-resolved height, so 100%
   resolves). */
.vc-chat-body {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 100%;
}

/* Thinking orb - a persistent watermark behind the transcript (not
   hidden once messages exist - see initThinkingOrb() in
   verion-chat.js for why that changed and why this is a sibling of
   #vc-body, positioned against the non-scrolling .vc-panel-inner,
   rather than a descendant of the element that actually scrolls.
   `top` is set in JS (measured off the real header height, not
   guessed here) so it lines up correctly under the header regardless
   of exactly how tall that ends up being. Sized dramatically bigger
   (72 -> 176px) per request, sitting comfortably within the ~320px
   chat column. pointer-events:none so it never intercepts clicks/
   selection meant for the transcript in front of it. */
.vc-orb-empty {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  z-index: 0;
  pointer-events: none;
}
.vc-thinking-orb {
  display: block;
  width: 240px;
  height: 240px;
}

/* Chat mode content - flat transcript, no bubbles. Each turn is a
   "Name  Time" meta line followed by its text, stacked top-to-bottom
   in send order (both the visitor and the assistant read the same
   way - no left/right bubble split). Matches the reference: full-
   width text, name+timestamp as the only visual separator between
   turns, the assistant's answer rendered brighter/bolder than the
   visitor's own question to keep the reply as the visual focus. */
.vc-chat-msg {
  display: flex;
  flex-direction: column;
  gap: 22px;
}
.vc-msg-group {
  display: flex;
  flex-direction: column;
  gap: 6px;
  /* Flies up into place - see vc-msg-in below, applied via JS the
     instant each group is appended so new turns visibly arrive
     rather than just popping into the transcript. */
  animation: vc-msg-in .38s cubic-bezier(.22,1,.36,1) both;
}
@keyframes vc-msg-in {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}
.vc-msg-meta {
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.vc-msg-name {
  font-size: 12.5px;
  font-weight: 700;
  color: rgba(245,245,244,.95);
}
.vc-msg-time {
  font-size: 11.5px;
  font-weight: 500;
  color: rgba(245,245,244,.4);
}
.vc-msg-text {
  font-size: 14px;
  line-height: 1.6;
  word-wrap: break-word;
  white-space: pre-wrap;
  /* Legibility fix for the thinking orb sitting permanently behind
     the transcript (see verion-chat.js notes above initThinkingOrb).
     REVISED (2026-09-14): the first pass put the blur/tint directly
     on this box as a flat rgba background - explicitly called out as
     reading like "a normal black chat box" with a hard rectangular
     edge, a "long pale bubble". Fixed by moving the blur/tint onto a
     ::before pseudo instead, oversized past the text's own edges and
     then MASKED with a soft radial gradient - the blur fades out to
     nothing at its own edges rather than being clipped by a straight
     border-radius corner, so it reads as one soft diffuse cloud
     behind the words instead of a compact bordered box. `isolation:
     isolate` gives this element its own stacking context so the
     pseudo's negative z-index only reaches back behind the text
     itself, not anything else in the panel. align-self:flex-start
     (parent is a flex column) keeps the box sized to the text's own
     content width rather than stretching full-width. */
  position: relative;
  isolation: isolate;
  display: inline-block;
  align-self: flex-start;
  padding: 4px 3px;
}
/* 2026-10-14 redesign: no bubbles. The visitor's question sits muted on the
   dark panel, the assistant's reply is bright, sub-questions bold. Matches the
   Off Menu reference. No box means no boundary to clash with the sphere behind
   the panel. */
.vc-msg-group-user .vc-msg-text { color: rgba(245,245,244,.55); }
.vc-msg-group-bot .vc-msg-text { color: rgba(245,245,244,.96); line-height: 1.55; }
/* The old streaming reply used to be a box that grew with the text; now the
   text is inline on the panel, so the only "streaming" effect is each word
   fading in (see .vc-word below). */
.vc-msg-group-bot .vc-msg-text.is-streaming { overflow: visible; }
.vc-msg-inner { display: block; width: 100%; }
/* Each word of a reply fades into focus as it lands. */
.vc-word { animation: vc-word-in .3s cubic-bezier(.23,1,.32,1) both; }
@keyframes vc-word-in {
  from { opacity: 0; filter: blur(3px); }
  to   { opacity: 1; filter: blur(0); }
}
.vc-msg-text strong { color: #fff; font-weight: 700; }

/* Typing indicator - three dots, same meta-line treatment as a real
   reply so it doesn't look like a different kind of UI element. */
.vc-msg-typing-dots {
  display: flex;
  align-items: center;
  gap: 4px;
  height: 22px;
  padding: 0 2px;
}
.vc-msg-typing-dots span {
  width: 5px; height: 5px;
  border-radius: 50%;
  background: rgba(245,245,244,.5);
  animation: vc-typing-bounce 1.1s ease-in-out infinite;
}
.vc-msg-typing-dots span:nth-child(2) { animation-delay: .15s; }
.vc-msg-typing-dots span:nth-child(3) { animation-delay: .3s; }
@keyframes vc-typing-bounce {
  0%, 60%, 100% { opacity: .35; transform: translateY(0); }
  30% { opacity: 1; transform: translateY(-2px); }
}
/* Scroll-down hint - only ever shown on the Tools step (see
   updateScrollHint() in verion-chat.js), and only while #vc-body
   genuinely has more content below. Floats over the bottom of the
   scrolling area, just above the input row; a small persistent bounce
   is what actually reads as "there's more, scroll" rather than a
   static arrow blending into the rest of the UI. */
.vc-scroll-hint {
  position: absolute;
  left: 50%;
  bottom: 80px; /* clears .vc-input-row, which sits below #vc-body and stays visible in book mode too */
  transform: translateX(-50%);
  z-index: 40;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--vc-wiz-card);
  border: 0.8px solid var(--vc-wiz-border);
  color: var(--vc-wiz-fg);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 8px 20px rgba(0,0,0,.4);
  opacity: 0;
  pointer-events: none;
  transition: opacity .25s ease, border-color .2s ease;
}
.vc-scroll-hint.is-visible {
  opacity: 1;
  pointer-events: auto;
  animation: vc-scroll-hint-bounce 1.6s ease-in-out infinite;
}
.vc-scroll-hint:hover { border-color: var(--vc-wiz-primary); }
.vc-scroll-hint svg { width: 16px; height: 16px; }
@keyframes vc-scroll-hint-bounce {
  0%, 100% { transform: translateX(-50%) translateY(0); }
  50% { transform: translateX(-50%) translateY(4px); }
}

/* Suggested-question pills - shown above the input until the first
   message is sent (matches the Off Menu reference's row of quick
   prompts under its opening greeting). Tapping one drops its text
   straight into the send flow, same as typing it out. */
.vc-suggest-row {
  flex-shrink: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 0 18px 12px;
}
.vc-suggest-pill {
  background: rgba(255,255,255,.06);
  color: rgba(245,245,244,.9);
  border: 1px solid rgba(255,255,255,.1);
  border-radius: 999px;
  padding: 8px 14px;
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 500;
  cursor: pointer;
  transition: background-color .18s ease, border-color .18s ease, transform .12s ease;
}
.vc-suggest-pill:hover { background: rgba(255,255,255,.11); border-color: rgba(255,255,255,.18); }
.vc-suggest-pill:active { transform: scale(.97); }

/* Input row (chat mode only) */
.vc-input-row {
  flex-shrink: 0;
  display: flex;
  /* bottom-aligned so the orb and the send button stay on the last line
     while the typing box grows upward */
  align-items: flex-end;
  gap: 12px;
  padding: 12px 18px 16px;
  border-top: 1px solid rgba(255,255,255,.06);
}
.vc-input-wrap {
  position: relative;
  flex: 1;
  min-width: 0;
  display: flex;
}
/* Typing box: one line = 40px, the same height as the orb beside it. JS
   (sizeInput) sets the height as the text grows, up to 3 lines, then the
   box scrolls inside. No visible scrollbar, and the right padding is
   always reserved for the expand button, so the text never shifts
   sideways when the box fills up. overscroll-behavior keeps the mouse
   wheel inside the box: it never spills over into the chat or booking
   content above. */
.vc-input {
  flex: 1;
  display: block;
  min-width: 0;
  box-sizing: border-box;
  height: 40px;
  margin: 0;
  background: none;
  border: none;
  color: #fff;
  font-family: inherit;
  font-size: 13.5px;
  line-height: 20px;
  outline: none;
  padding: 10px 30px 10px 0;
  resize: none;
  overflow-y: hidden;
  overflow-wrap: anywhere;
  overscroll-behavior: contain;
  scrollbar-width: none;
  transition: height .2s cubic-bezier(.23,1,.32,1);
}
.vc-input::placeholder { color: rgba(245,245,244,.4); }
.vc-input::-webkit-scrollbar { display: none; width: 0; height: 0; }
/* Expand / collapse: only present once the message is longer than the box. */
.vc-input-expand {
  position: absolute;
  top: 8px;
  right: 0;
  width: 24px;
  height: 24px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 7px;
  background: rgba(255,255,255,.08);
  color: rgba(245,245,244,.75);
  cursor: pointer;
  animation: vc-fade-in .18s cubic-bezier(.23,1,.32,1) both;
  transition: background-color .18s ease, color .18s ease, transform .16s ease-out;
}
.vc-input-expand[hidden] { display: none; }
.vc-input-expand svg { width: 13px; height: 13px; }
.vc-input-expand:active { transform: scale(.94); }
@media (hover: hover) and (pointer: fine) {
  .vc-input-expand:hover { background: rgba(255,255,255,.14); color: #fff; }
}
/* Send: a small round arrow on the last line, dim until there is text. */
.vc-send {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  margin-bottom: 4px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: #f5f5f4;
  color: #141311;
  cursor: pointer;
  transition: background-color .18s ease, color .18s ease, transform .16s ease-out;
}
.vc-send svg { width: 15px; height: 15px; }
.vc-send:disabled { background: rgba(255,255,255,.1); color: rgba(245,245,244,.35); cursor: default; }
.vc-send:not(:disabled):active { transform: scale(.94); }
@media (hover: hover) and (pointer: fine) {
  .vc-send:not(:disabled):hover { background: #ffffff; }
}
@keyframes vc-fade-in { from { opacity: 0; } to { opacity: 1; } }

/* ---------- 2026-10-14: welcome + conversation state ---------- */
/* Welcome content: a bigger animated sphere above a short greeting. Only
   visible in the welcome state; swapped out for the transcript after the
   first question. The pills in .vc-suggest-row below sit under this. */
.vc-welcome {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 24px;
  flex: 1;
  padding: 24px 18px 8px;
  text-align: center;
  animation: vc-welcome-in .32s cubic-bezier(.22,1,.36,1) both;
}
.vc-welcome-orb { width: 110px; height: 110px; }
.vc-welcome-orb .vc-orb-svg { width: 100%; height: 100%; }
.vc-welcome-greet { display: flex; flex-direction: column; gap: 6px; max-width: 280px; }
.vc-welcome-hi { font-size: 15.5px; line-height: 1.35; color: #fff; margin: 0; font-weight: 500; }
.vc-welcome-sub { font-size: 13.5px; line-height: 1.45; color: rgba(245,245,244,.55); margin: 0; }
@keyframes vc-welcome-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Follow-up pills: one row under each AI reply, offering 2-3 short questions
   the visitor is likely to ask next. Smaller and quieter than the welcome
   pills so they feel like a continuation of the reply, not a form. */
.vc-followup-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 2px;
  animation: vc-msg-in .32s cubic-bezier(.22,1,.36,1) .1s both;
}
.vc-followup-pill {
  background: rgba(255,255,255,.05);
  color: rgba(245,245,244,.82);
  border: 1px solid rgba(255,255,255,.08);
  border-radius: 999px;
  padding: 6px 11px;
  font-family: inherit;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  transition: background-color .16s ease, border-color .16s ease, color .16s ease, transform .12s ease;
}
.vc-followup-pill:hover { background: rgba(255,255,255,.1); border-color: rgba(255,255,255,.16); color: #fff; }
.vc-followup-pill:active { transform: scale(.97); }

/* Back arrow: appears next to Close in the conversation state, replacing the
   Chat / Book a Call tabs. Click returns to the welcome state. */
.vc-back {
  width: 28px; height: 28px;
  border-radius: 999px;
  display: grid;
  place-items: center;
  background: rgba(255,255,255,.08);
  color: rgba(245,245,244,.75);
  border: 0;
  padding: 0;
  cursor: pointer;
  transition: background-color .18s ease, color .18s ease, transform .14s ease-out;
  animation: vc-fade-in .22s cubic-bezier(.22,1,.36,1) both;
}
.vc-back[hidden] { display: none; }
.vc-back svg { width: 14px; height: 14px; }
.vc-back:active { transform: scale(.94); }
@media (hover: hover) and (pointer: fine) {
  .vc-back:hover { background: rgba(255,255,255,.14); color: #fff; }
}

/* Thinking state: the input placeholder reads "Thinking..." and the input is
   disabled. The small sphere icon beside it pulses a touch quicker. */
.vc-root.vc-chat-busy .vc-input::placeholder { color: rgba(245,245,244,.65); font-style: italic; }

/* Mode-conditional visibility */
.vc-root.vc-mode-book .vc-chat-body { display: none; }
.vc-root:not(.vc-mode-book) .vc-book-body { display: none; }
/* The "ask me anything" input row (icon + input) is intentionally NOT
   hidden in book mode - it stays pinned at the bottom of BOTH tabs, so
   there's always a quick way to ask a question without leaving the
   booking flow. Only the chat-only suggested-question pills (How much
   does this cost? etc.) are book-mode-specific - those genuinely don't
   belong once you're filling out the wizard, so they're hidden there. */
.vc-root.vc-mode-book .vc-suggest-row { display: none; }

/* Welcome vs conversation: the welcome section + the four suggestion pills
   belong to the welcome state only; the big watermark orb behind the
   transcript belongs to the conversation state only (the welcome has its
   own, smaller orb inside). The transcript (#vc-chat-msg) is empty in the
   welcome state, so hiding it there is cosmetic but prevents a stray
   margin above the input. */
.vc-root.vc-chat-mode-welcome .vc-tabs { display: flex; }
.vc-root.vc-chat-mode-chat .vc-tabs,
.vc-root.vc-chat-mode-thinking .vc-tabs { display: none; }
.vc-root.vc-chat-mode-chat .vc-welcome,
.vc-root.vc-chat-mode-thinking .vc-welcome,
.vc-root.vc-chat-mode-chat .vc-suggest-row,
.vc-root.vc-chat-mode-thinking .vc-suggest-row { display: none; }
.vc-root.vc-chat-mode-welcome .vc-chat-msg { display: none; }
.vc-root.vc-chat-mode-welcome .vc-orb-empty { display: none; }

/* ============================================================
   Booking wizard — every animation timing pulled straight from
   the pasted React reference and rebuilt as CSS keyframes /
   transitions matching the same numbers.
   ============================================================ */
/* Reference container: `w-full max-w-lg mx-auto py-8` = 32px vertical */
.vc-book-body { padding: 8px 0 12px; }

/* Progress indicator: slides in from y:-20 → 0, duration 0.5s
   (reference: `initial={{ opacity: 0, y: -20 }}, animate: {..., y: 0},
   transition: { duration: 0.5 }}`) */
/* Reference: mb-8 = 32px between progress and card. */
/* Sibling of #vc-body (see the markup comment in verion-chat.js) so
   the dots/bar can never scroll away with a tall step's content -
   only ever hidden entirely outside book mode. flex-shrink:0 keeps it
   from being squeezed by #vc-body's own flex:1 in the rare case both
   are competing for space. */
#vc-wiz-progress-fixed {
  flex-shrink: 0;
  padding: 18px 20px 0; /* matches #vc-body's own inset (18px 20px) so the card below still lines up flush */
}
.vc-root:not(.vc-mode-book) #vc-wiz-progress-fixed { display: none; }

/* Back/Next footer - a sibling of #vc-body (see the markup comment in
   verion-chat.js), pinned below the scrolling area instead of inside
   it, so it's never pushed off-screen by a step growing taller (the
   Country field pushed it past the fold before this fix). No background
   of its own (explicit correction - it was using the card's lighter
   --vc-wiz-card gray, which read as a mismatched panel floating over
   the actual dark background); it now sits directly on the panel's own
   background, same as the "Ask me anything" input row at the very
   bottom, and borrows that exact same hairline treatment
   (rgba(255,255,255,.06)) instead of the more visible --vc-wiz-border
   used for actual card edges. */
#vc-wiz-footer-fixed {
  flex-shrink: 0;
  padding: 14px 20px 16px; /* matches #vc-body's own 20px horizontal inset so Back/Next line up flush with the card's own edges above */
  border-top: 1px solid rgba(255,255,255,.06);
}
.vc-root:not(.vc-mode-book) #vc-wiz-footer-fixed { display: none; }
.vc-wiz-progress {
  margin-bottom: 12px; /* #vc-body's own top padding (18px) adds on top of this now that they're separate containers */
  animation: vc-slide-down .5s cubic-bezier(.22,1,.36,1) both;
}
@keyframes vc-slide-down {
  from { opacity: 0; transform: translateY(-20px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Reference sizes: dots w-4 h-4 (16px), label text-xs mt-1.5 (12px, 6px gap),
   flex justify-between, mb-2 gap. */
.vc-wiz-dotrow {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 8px;
  gap: 4px;
}
.vc-wiz-dotcell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px; /* mt-1.5 = 6px in reference */
  cursor: pointer;
  flex: 1;
  min-width: 0;
  transition: transform .18s ease;
}
.vc-wiz-dotcell:hover { transform: scale(1.1); } /* whileHover: 1.1 */
.vc-wiz-dot {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--vc-wiz-muted); /* measured: oklch(0.269 0 0) = #454545 */
  border: none; padding: 0;
  cursor: inherit;
  transition:
    background-color .3s ease,
    box-shadow .3s ease,
    transform .12s ease;
  flex-shrink: 0;
}
.vc-wiz-dot:active { transform: scale(.95); } /* whileTap: 0.95 */
.vc-wiz-dot.done { background: var(--vc-wiz-primary); }
.vc-wiz-dot.current {
  background: var(--vc-wiz-primary);
  box-shadow: 0 0 0 4px rgba(235,235,235,.2); /* ring-4 ring-primary/20, measured */
}
.vc-wiz-dotlabel {
  font-size: 12px; /* text-xs in the reference */
  color: var(--vc-wiz-muted-fg);
  text-align: center;
  line-height: 1.2;
  transition: color .3s ease;
  display: none;
}
@media (min-width: 480px) {
  .vc-wiz-dotlabel { display: block; } /* hidden sm:block */
}
.vc-wiz-dotcell.current .vc-wiz-dotlabel {
  color: var(--vc-wiz-fg);
  font-weight: 500; /* font-medium in reference, not bold */
}

/* Progress bar: `h-1.5 rounded-full overflow-hidden mt-2` = 6px tall,
   full radius, 8px above. Width transition 0.3s per reference. */
.vc-wiz-bar {
  width: 100%;
  height: 6px;
  background: var(--vc-wiz-muted);
  border-radius: 999px;
  overflow: hidden;
  margin-top: 8px;
}
.vc-wiz-bar-fill {
  height: 100%;
  background: var(--vc-wiz-primary);
  width: 0%;
  transition: width .3s ease;
}

/* Card that holds the current step — slides up from y:20 → 0 with
   delay 0.2s (reference: `initial: { opacity: 0, y: 20 },
   transition: { duration: 0.5, delay: 0.2 }`). rounded-3xl = 24px. */
/* Card: reference is `border shadow-md rounded-3xl overflow-hidden`.
   Measured live off the real component: bg-card (#1a1a1a) sits
   VISIBLY LIGHTER than the page background behind it (#0a0a0a) -
   that tonal step is what reads as "real depth," not a flat panel. */
.vc-wiz-card {
  background: var(--vc-wiz-card);
  border: 0.8px solid var(--vc-wiz-border);
  border-radius: 24px; /* rounded-3xl */
  overflow: hidden;
  /* shadow-md, exact two-layer value read off the live render */
  box-shadow: 0 4px 6px -1px rgba(0,0,0,.1), 0 2px 4px -2px rgba(0,0,0,.1);
  animation: vc-slide-up .5s .2s cubic-bezier(.22,1,.36,1) both;
  /* Explicit request: the card (and the step-indicator text right
     below it, which just follows in normal flow) sat too far down
     from the progress dots above it - nudged the whole thing up. */
  margin-top: -15px;
}
@keyframes vc-slide-up {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Card structure matched to shadcn defaults used in the reference:
   - CardHeader: p-6 (24px all sides) + space-y-1.5 (6px between title/desc)
   - CardContent: p-6 pt-0 (24px x, 0 top) + space-y-4 (16px between fields)
   - CardFooter: pt-6 pb-4 (24px top, 16px bottom in the reference override) */
.vc-wiz-header {
  padding: 24px 24px 24px;
}
.vc-wiz-title {
  font-family: var(--font-display);
  font-size: 24px; /* text-2xl, measured */
  font-weight: 600; /* font-semibold */
  color: var(--vc-wiz-fg);
  line-height: 1; /* leading-none - measured lineHeight equalled fontSize */
  letter-spacing: -0.025em; /* tracking-tight, measured -0.6px on 24px */
  margin: 0 0 6px; /* space-y-1.5 gap */
}
.vc-wiz-desc {
  font-size: 14px; /* text-sm, measured */
  color: var(--vc-wiz-muted-fg);
  line-height: 1.43; /* measured 20px / 14px */
  margin: 0;
}
.vc-wiz-content {
  padding: 0 24px 24px;
  /* space-y-4 handled by .vc-field margin-bottom: 16px */
}
.vc-wiz-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  /* No padding of its own - #vc-wiz-footer-fixed (its wrapper, now that
     this lives outside the card - see the markup comment in
     verion-chat.js) provides the inset instead. */
}

/* ============================================================
   Location "map" card - Location step only (see locMapHTML() in
   verion-chat.js). Ported from the user-supplied React reference,
   with explicit departures: it is NEVER clickable (cursor stays
   default, no click listener is ever attached to it), it never
   returns to idle/collapsed on its own (only runLocationConfirm() in
   verion-chat.js drives is-expanded), and there is no checkmark / no
   status pill - the pin icon is drawn exactly as the reference does
   and never swapped for anything else.
   Sits in normal flow, top-center of the step ("top in the middle"
   while idle). REVISED (2026-09-14): originally the fields below it
   just got pushed down as the card grew, forcing a scroll to reach
   Back/Next - fixed by collapsing .vc-locmap-fields (see below) the
   instant Confirm runs, so the card expands into space that's
   already empty instead of shoving the footer around. */
.vc-locmap {
  display: flex;
  justify-content: center;
  margin: 0 0 20px;
  cursor: default;
}
.vc-locmap-box {
  position: relative;
  width: 210px;
  height: 84px;
  border-radius: 20px;
  overflow: hidden;
  background: var(--vc-wiz-bg);
  border: 0.8px solid var(--vc-wiz-border);
  transition:
    width .6s cubic-bezier(.16,1,.3,1),
    height .6s cubic-bezier(.16,1,.3,1),
    border-radius .5s cubic-bezier(.16,1,.3,1);
}
.vc-locmap.is-expanded .vc-locmap-box {
  width: 100%;
  max-width: 350px;
  height: 215px;
  border-radius: 24px;
}

/* The two fields (City/Region + Industry) sitting under the card.
   Collapsed via max-height (generous - just needs to clear real
   content height) the instant Confirm is clicked, so they're fully
   out of flow before the map finishes expanding into that freed
   space - see runLocationConfirm() in verion-chat.js. */
.vc-locmap-fields {
  max-height: 320px;
  opacity: 1;
  overflow: hidden;
  transition: max-height .45s cubic-bezier(.4,0,.2,1), opacity .3s ease, margin-top .45s ease;
}
.vc-locmap-fields.is-collapsed {
  max-height: 0;
  opacity: 0;
  margin-top: -16px; /* cancels the first field's own margin-bottom so no gap is left behind */
  pointer-events: none;
}

/* Faint grid texture, collapsed state only - matches the reference's
   idle "opacity-[0.03]" grid pattern. */
.vc-locmap-grid {
  position: absolute;
  inset: 0;
  opacity: .05;
  background-image:
    linear-gradient(rgba(235,235,235,.6) 1px, transparent 1px),
    linear-gradient(90deg, rgba(235,235,235,.6) 1px, transparent 1px);
  background-size: 18px 18px;
  transition: opacity .3s ease;
}
.vc-locmap.is-expanded .vc-locmap-grid { opacity: 0; }

/* The "map" itself - roads, buildings, pin - only painted in once
   expanded, same as the reference's AnimatePresence-gated scene. */
.vc-locmap-scene {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity .5s ease .1s;
  pointer-events: none;
}
.vc-locmap.is-expanded .vc-locmap-scene { opacity: 1; }
.vc-locmap-tint {
  position: absolute;
  inset: 0;
  /* A touch darker than --vc-wiz-muted (#454545) on purpose - the
     shared muted token read slightly too bright/washed-out for this
     specific "closer to the original reference" ask, without
     wanting to darken --vc-wiz-muted everywhere else it's used. */
  background: #3c3c3c;
}

/* Roads: plain divs whose width (horizontal) / height (vertical)
   transitions 0 -> 100%, each with its own inline transition-delay/
   -duration set in roadDiv() (verion-chat.js) lifted straight off the
   reference's per-line values - the last one lands at 1.5s, matching
   the reference's own total draw time exactly. A flat percentage
   transition can't stop "midway" the way the earlier stroke-dasharray
   version visibly did - it either hasn't started or it's done. */
.vc-locmap-road {
  position: absolute;
  transition-property: width, height;
  transition-timing-function: ease;
}
.vc-locmap-road-h { left: 0; width: 0%; transform: translateY(-50%); }
.vc-locmap-road-v { top: 0; height: 0%; transform: translateX(-50%); }
.vc-locmap.is-expanded .vc-locmap-road-h { width: 100%; }
.vc-locmap.is-expanded .vc-locmap-road-v { height: 100%; }

/* Buildings - positions/delays matched 1:1 to the reference's six
   motion.div entries. */
.vc-locmap-bldg {
  position: absolute;
  border-radius: 3px;
  background: rgba(235,235,235,.16);
  border: 1px solid rgba(235,235,235,.12);
  opacity: 0;
  transform: scale(.8);
  transition: opacity .4s ease, transform .4s ease;
}
.vc-locmap.is-expanded .vc-locmap-bldg { opacity: 1; transform: scale(1); }
.vc-locmap-bldg.b1 { top: 40%; left: 10%; width: 15%; height: 20%; transition-delay: .5s; }
.vc-locmap-bldg.b2 { top: 15%; left: 35%; width: 12%; height: 15%; transition-delay: .6s; }
.vc-locmap-bldg.b3 { top: 70%; left: 75%; width: 18%; height: 18%; transition-delay: .7s; }
.vc-locmap-bldg.b4 { top: 20%; right: 10%; width: 10%; height: 25%; transition-delay: .55s; }
.vc-locmap-bldg.b5 { top: 55%; left: 5%;  width: 8%;  height: 12%; transition-delay: .65s; }
.vc-locmap-bldg.b6 { top: 8%;  left: 75%; width: 14%; height: 10%; transition-delay: .75s; }

/* Pin - the exact reference icon (green teardrop marker), never
   swapped for a checkmark or anything else. Drops in with a small
   bounce, same delay as the reference's own spring (0.3s). */
.vc-locmap-pin {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 30px;
  height: 30px;
  transform: translate(-50%, -72%) scale(0);
  transition: transform .4s cubic-bezier(.34,1.56,.64,1) .3s;
}
.vc-locmap.is-expanded .vc-locmap-pin { transform: translate(-50%, -72%) scale(1); }
.vc-locmap-pin-icon {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  filter: drop-shadow(0 0 10px rgba(52,211,153,.5));
}
/* Fix: the wrapping <svg fill="none"> (needed so the teardrop <path>
   isn't auto-filled black) was inheriting straight down onto this
   circle too, since it never had its own fill - same as the
   reference's "hole" punched through the pin reading as invisible
   instead of dark. Matches the reference's fill-background exactly. */
.vc-locmap-pin-hole { fill: var(--vc-wiz-bg); }

.vc-locmap-content {
  position: relative;
  z-index: 1;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 14px 16px;
}
.vc-locmap-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
}
.vc-locmap-icon {
  width: 17px;
  height: 17px;
  color: #34D399;
  filter: drop-shadow(0 0 4px rgba(52,211,153,.3));
  transition: opacity .3s ease;
}
.vc-locmap.is-expanded .vc-locmap-icon { opacity: 0; }

/* Edit - restored per explicit request, as a bold/visible button
   (not the old faint "Live" pill) but toned down from a flat #ebebeb
   off-white (read as "too strong") and sized up into a proper,
   generously-padded pill rather than a cramped chip. Hidden while
   idle/loading and only revealed once the map is fully expanded -
   it's the ONE clickable thing on this otherwise inert card, wired
   in mountWizard() to retract the map + reopen the fields so they
   can fix what they typed. */
.vc-locmap-edit {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: rgba(235,235,235,.82);
  color: var(--vc-wiz-primary-fg);
  border: none;
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .01em;
  padding: 7px 14px 7px 11px;
  border-radius: 999px;
  cursor: pointer;
  opacity: 0;
  transform: translateY(-4px) scale(.9);
  pointer-events: none;
  transition: opacity .3s ease .1s, transform .3s ease .1s, background-color .2s ease, box-shadow .2s ease;
}
.vc-locmap.is-expanded .vc-locmap-edit {
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: auto;
}
.vc-locmap-edit:hover { background: rgba(235,235,235,.95); box-shadow: 0 0 0 3px rgba(235,235,235,.12); }
.vc-locmap-edit:active { transform: scale(.95); }
.vc-locmap-edit svg { width: 13px; height: 13px; stroke: currentColor; flex-shrink: 0; }
.vc-locmap-label {
  margin: 0 0 5px;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--vc-wiz-fg);
}
.vc-locmap-underline {
  height: 1px;
  width: 30%;
  background: linear-gradient(90deg, rgba(52,211,153,.5), rgba(52,211,153,.25), transparent);
  transition: width .4s ease .1s;
}
.vc-locmap.is-expanded .vc-locmap-underline { width: 100%; }

/* Step transition between steps (contentVariants in the reference):
   hidden: x:50, opacity:0; visible: x:0, opacity:1 (duration 0.3);
   exit: x:-50, opacity:0 (duration 0.2). Implemented as CSS keyframe
   played on class-swap into `is-active`. Since we swap in-place
   rather than animating the outgoing step out (plain HTML can't do
   framer's AnimatePresence trivially), only the entrance animation
   is played - the previous step is hidden by display:none. */
.vc-wiz-step { display: none; }
.vc-wiz-step.is-active {
  display: block;
  animation: vc-content-in .3s ease both;
}
@keyframes vc-content-in {
  from { opacity: 0; transform: translateX(50px); }
  to   { opacity: 1; transform: translateX(0); }
}

/* Field entrance (fadeInUp in the reference): y:20 → 0, duration 0.3.
   Each field inside a step gets a small stagger via --vc-i inline
   custom property so they cascade in like the reference does. */
.vc-field,
.vc-radio-list > .vc-opt,
.vc-check-list > .vc-opt,
.vc-check-grid > .vc-opt {
  animation: vc-fade-up .3s cubic-bezier(.22,1,.36,1) both;
  animation-delay: calc(var(--vc-i, 0) * .1s);
}
@keyframes vc-fade-up {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}
/* Options stagger sideways like the reference (x:-10 for goal/time,
   y:10 for style/feature). Using a per-list orientation attr. */
[data-stagger="x"] > .vc-opt {
  animation-name: vc-fade-in-x;
}
@keyframes vc-fade-in-x {
  from { opacity: 0; transform: translateX(-10px); }
  to   { opacity: 1; transform: translateX(0); }
}
[data-stagger="y"] > .vc-opt {
  animation-name: vc-fade-in-y;
}
@keyframes vc-fade-in-y {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Reference: `space-y-4` between fields (16px) + `space-y-2` inside each
   field (8px between Label and Input). Measured live off the real
   component: inputs are h-10 (40px), 8px radius (their rounded-md
   resolves to 8px, not Tailwind's 6px default - a customized theme),
   12/8px padding, 14px font, border white @ ~15%, bg matches the
   page background (not the card - inputs sit "recessed" a step
   darker than the card they're on). Focus adds ring-2 ring-primary/20. */
.vc-field { margin-bottom: 16px; }
.vc-field:last-child { margin-bottom: 0; }
/* Each .vc-field's own entrance animation leaves it parked at
   transform: translateY(0) even once finished - not literally `none`
   - which quietly makes every field its own stacking context. That
   traps a dropdown panel's z-index inside its own field, unable to
   rise above a later sibling field (e.g. a textarea right below it).
   Toggled by mountWizard() onto whichever field currently has an open
   .vc-select, so its panel can actually paint above the rest of the
   step while open. */
.vc-field.vc-field-elevated { position: relative; z-index: 30; }
.vc-field label {
  display: block;
  font-size: 14px; /* text-sm */
  font-weight: 500; /* font-medium */
  color: var(--vc-wiz-fg);
  line-height: 1; /* leading-none */
  margin-bottom: 8px; /* space-y-2 = 8px */
}
.vc-field input,
.vc-field textarea,
.vc-field select {
  width: 100%;
  font-family: var(--font-body);
  font-size: 14px; /* text-sm, measured */
  color: var(--vc-wiz-fg);
  background: var(--vc-wiz-bg); /* measured: matches page bg, recessed vs card */
  border: 0.8px solid var(--vc-wiz-border);
  border-radius: 8px; /* measured: 8px, not the Tailwind-default 6px */
  padding: 8px 12px; /* py-2 px-3, measured */
  height: 40px; /* h-10, measured */
  transition: border-color .3s ease, box-shadow .3s ease;
}
.vc-field textarea {
  height: auto;
  min-height: 80px;
  padding: 10px 12px; /* Textarea has py-2 but its own min-h */
  resize: vertical;
}
.vc-field input::placeholder,
.vc-field textarea::placeholder { color: var(--vc-wiz-muted-fg); }
.vc-field input:focus,
.vc-field textarea:focus,
.vc-field select:focus {
  outline: none;
  border-color: var(--vc-wiz-primary); /* focus:border-primary */
  box-shadow: 0 0 0 2px rgba(235,235,235,.2); /* ring-2 ring-primary/20, measured */
}
/* Inline "this address looks wrong" check (like Gmail's own) - see the
   blur/input wiring in verion-chat.js. A red border alone isn't enough
   context (is it required? too short? actually malformed?), so this
   pairs it with an actual message; kept collapsed at height:0 rather
   than display:none so it can slide/fade in instead of popping. */
.vc-field input.is-invalid {
  border-color: #e5484d;
  box-shadow: 0 0 0 2px rgba(229,72,77,.18);
}
.vc-field-error {
  display: block;
  max-height: 0;
  overflow: hidden;
  font-size: 12.5px;
  font-weight: 500;
  color: #ff6b6f;
  opacity: 0;
  transform: translateY(-2px);
  transition: opacity .2s ease, transform .2s ease, max-height .2s ease, margin-top .2s ease;
}
.vc-field-error.is-visible {
  max-height: 20px;
  opacity: 1;
  transform: translateY(0);
  margin-top: 6px;
}

/* ============================================================
   Custom dropdown (replaces the native <select> - see
   customSelectHTML() in verion-chat.js). A native select's open
   popup is the OS's own unstylable list, which is exactly what read
   as "shows everything, really bad, unprofessional" against this
   dark UI - this is a real trigger + an animated options panel that
   actually matches the rest of the wizard. Trigger box is sized/
   styled identically to .vc-field input/select so swapping one for
   the other is invisible until you interact with it. */
.vc-select { position: relative; }
/* Contact step's phone row - a compact country-code select sitting
   to the left of the actual number input. */
.vc-phone-group {
  display: flex;
  gap: 8px;
  align-items: flex-start;
}
.vc-phone-country { flex: 0 0 96px; }
.vc-phone-country-trigger { padding-right: 8px; }
.vc-phone-input { flex: 1; min-width: 0; }
.vc-phone-dial { color: var(--vc-wiz-muted-fg); margin-left: 4px; }
.vc-select-trigger {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-family: var(--font-body);
  font-size: 14px;
  text-align: left;
  color: var(--vc-wiz-fg);
  background: var(--vc-wiz-bg);
  border: 0.8px solid var(--vc-wiz-border);
  border-radius: 8px;
  padding: 8px 12px; /* right padding is what keeps the caret off the edge */
  height: 40px;
  cursor: pointer;
  transition: border-color .3s ease, box-shadow .3s ease;
}
.vc-select-trigger:hover { border-color: rgba(255,255,255,.28); }
.vc-select.is-open .vc-select-trigger,
.vc-select-trigger:focus-visible {
  outline: none;
  border-color: var(--vc-wiz-primary);
  box-shadow: 0 0 0 2px rgba(235,235,235,.2);
}
.vc-select-value {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.vc-select-value.is-placeholder { color: var(--vc-wiz-muted-fg); }
.vc-select-caret {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  color: var(--vc-wiz-muted-fg);
  transition: transform .25s cubic-bezier(.4,0,.2,1), color .2s ease;
}
.vc-select.is-open .vc-select-caret { transform: rotate(180deg); color: var(--vc-wiz-fg); }

/* Country's searchable trigger (cfg.searchable in customSelectHTML) -
   same box as every other .vc-select-trigger, but holding a real text
   input instead of a button + static label, so typing directly into
   the question filters the list below it. Text cursor instead of a
   pointer, since this one is genuinely typeable, not just clickable. */
.vc-combo-trigger { cursor: text; }
/* Explicit fix: the generic ".vc-field input" rule (every plain text
   field's own border/background/radius/height/padding) was beating
   this on specificity (one class here vs. a class+tag there), so the
   input was quietly getting its OWN rounded border+background nested
   inside the trigger's already-rounded box - the "double edge" visible
   on its left corners. Qualifying the selector with .vc-field bumps
   this above that rule so the input actually renders borderless/
   transparent as intended, with only the trigger's own single box
   visible. */
.vc-field .vc-combo-input {
  flex: 1;
  min-width: 0;
  width: 100%;
  height: auto;
  border: none;
  background: transparent;
  padding: 0;
  margin: 0;
  border-radius: 0;
  font-family: inherit;
  font-size: inherit;
  color: inherit;
  outline: none;
}
.vc-field .vc-combo-input::placeholder { color: var(--vc-wiz-muted-fg); }
.vc-field .vc-combo-input:focus { border: none; box-shadow: none; }

/* Options panel - ALWAYS opens downward, directly below the question.
   REVISED (2026-09-14): no longer positioned relative to .vc-select
   at all - mountWizard() physically moves this node out to #vc-panel
   and sets left/top/width inline every time it opens (see the long
   comment above the dropdown wiring in verion-chat.js for why: it's
   the fix for both the "renders under other UI" and "makes the whole
   page scroll" bugs). left/top/width below are just closed-state
   defaults so it never flashes at 0,0 before JS positions it.
   Capped shorter than before (was 232px - read as "too big") and a
   flat z-index high enough to clear literally everything else in the
   panel, since it now lives as a direct sibling of the header/body/
   footer rather than nested three levels deep inside one field.
   Enter vs exit deliberately use DIFFERENT transitions: opening runs
   on this rule's own springy overshoot curve (the same "back ease"
   used for the location pin drop elsewhere in this file) so it
   genuinely bounces into place like the reference's Framer spring;
   closing (the base .vc-select-panel rule below) stays a plain quick
   ease-out with no bounce, matching the reference's own asymmetric
   open/close feel. CSS resolves each transition using whichever
   rule's `transition` is in effect for the state being transitioned
   TO, which is what makes opening and closing feel different despite
   being the same property. */
.vc-select-panel {
  position: absolute;
  left: 0;
  top: 0;
  transform-origin: top center;
  z-index: 200;
  background: var(--vc-wiz-card);
  border: 0.8px solid var(--vc-wiz-border);
  border-radius: 12px;
  box-shadow: 0 14px 32px rgba(0,0,0,.5), 0 2px 10px rgba(0,0,0,.35);
  padding: 6px;
  /* flex column + gap, not options just stacked flush - explicit
     request for real breathing room between each option instead of
     one dense block; bumped max-height a little at the same time
     since Challenge now has 9 real options to scroll through. */
  display: flex;
  flex-direction: column;
  gap: 3px;
  max-height: 210px;
  overflow-y: auto;
  overscroll-behavior: contain; /* stop scroll-chaining into the page once this list hits its own edge */
  opacity: 0;
  transform: scale(.94) translateY(-4px);
  pointer-events: none;
  transition: opacity .2s cubic-bezier(.4,0,.6,1), transform .2s cubic-bezier(.4,0,.6,1);
  /* Firefox's own scrollbar-styling API - the thin track/thumb
     "shows where you're scrolling at" without a custom JS-tracked
     thumb. WebKit gets the same look via ::-webkit-scrollbar below. */
  scrollbar-width: thin;
  scrollbar-color: rgba(235,235,235,.28) transparent;
}
.vc-select-panel.is-open {
  opacity: 1;
  transform: scale(1) translateY(0);
  pointer-events: auto;
  transition: opacity .3s cubic-bezier(.16,1,.3,1), transform .46s cubic-bezier(.34,1.56,.64,1);
}
/* Location's Industry select opens upward instead of downward, per
   explicit request - everything else (Challenge, phone country)
   keeps opening down. Only the anchor edge (for the scale bounce) and
   the closed-state offset direction change; is-open still settles to
   the same scale(1) translateY(0). */
.vc-select-panel-up {
  transform-origin: bottom center;
  transform: scale(.94) translateY(4px);
}
.vc-select-panel::-webkit-scrollbar { width: 6px; }
.vc-select-panel::-webkit-scrollbar-track { background: transparent; }
.vc-select-panel::-webkit-scrollbar-thumb {
  background: rgba(235,235,235,.28);
  border-radius: 999px;
}
.vc-select-panel::-webkit-scrollbar-thumb:hover { background: rgba(235,235,235,.42); }

/* No fade-mask on the last row anymore - explicit correction, it read
   as the bottom of the list being permanently "blurred" rather than a
   scroll hint. Every option in every dropdown stays fully visible;
   the visible scrollbar thumb above is the only scroll affordance
   now. */
.vc-select-opt {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  border-radius: 7px;
  font-size: 13.5px;
  color: var(--vc-wiz-fg);
  cursor: pointer;
  transition: background-color .15s ease;
}
.vc-select-opt:hover { background: rgba(255,255,255,.07); }
.vc-select-opt-label { flex: 1; min-width: 0; }
/* Icon per option (Challenge) - a bit more left-side room than the
   plain text-only rows, per explicit request. */
.vc-select-opt-has-icon { padding-left: 12px; }
.vc-select-opt-icon {
  width: 19px;
  height: 19px;
  flex-shrink: 0;
  color: var(--vc-wiz-muted-fg);
}
.vc-select-opt-icon svg { width: 100%; height: 100%; }
.vc-select-opt.is-selected .vc-select-opt-icon { color: var(--vc-wiz-primary); }

/* Reveal field for any select built with { other: true } (Challenge)
   - same collapse treatment as Tools' own "Other" field. */
/* Pops open rather than just sliding - adds the same spring-y overshoot
   curve already used for the dropdown panel itself opening, layered on
   top of the existing height/opacity reveal, so checking "Other"
   actually feels like something popping into place. */
.vc-select-other-field {
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transform: scaleY(.85);
  transform-origin: top;
  transition: max-height .35s cubic-bezier(.4,0,.2,1), opacity .25s ease, margin-top .35s ease, transform .35s cubic-bezier(.34,1.56,.64,1);
}
.vc-select-other-field.is-open {
  max-height: 60px;
  opacity: 1;
  margin-top: 10px;
  transform: scaleY(1);
}
.vc-select-other-field input {
  width: 100%;
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--vc-wiz-fg);
  background: var(--vc-wiz-bg);
  border: 0.8px solid var(--vc-wiz-border);
  border-radius: 8px;
  padding: 8px 12px;
  height: 40px;
  transition: border-color .3s ease, box-shadow .3s ease;
}
.vc-select-other-field input::placeholder { color: var(--vc-wiz-muted-fg); }
.vc-select-other-field input:focus {
  outline: none;
  border-color: var(--vc-wiz-primary);
  box-shadow: 0 0 0 2px rgba(235,235,235,.2);
}
.vc-select-opt.is-selected { color: var(--vc-wiz-primary); font-weight: 600; }
.vc-select-opt-check {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  color: var(--vc-wiz-primary);
  opacity: 0;
  transform: scale(.6);
  transition: opacity .18s cubic-bezier(.34,1.56,.64,1), transform .18s cubic-bezier(.34,1.56,.64,1);
}
.vc-select-opt.is-selected .vc-select-opt-check { opacity: 1; transform: scale(1); }

/* ============================================================
   Tools step - a 2-column card grid instead of a dropdown, per
   explicit spec ("it shouldn't be like one question... show all the
   different multi answers"). Each card is a compact HORIZONTAL row
   (logo/icon + name, checkmark trailing) rather than the earlier tall
   stacked layout - that read as "too much" height for a list this
   long. Multi-select, click as many as apply; a bright border + soft
   inset glow marks a selection (the "edges have a border... that good
   UI thing" ask). The same .vc-tools-card row component is reused for
   Team's single-column, single-select list below. Cards are grouped
   under small section-label dividers (see TOOL_GROUPS in
   verion-chat.js) - each one spans the full grid width and forces a
   fresh row, which both gives the long list actual structure and is
   what keeps "None of the above" paired with "Other" on the final row
   regardless of how many cards are in the groups above them. */
.vc-tools-grid {
  display: grid;
  /* minmax(0,1fr), not plain 1fr - a bare 1fr track still has an
     implicit auto-minimum sized to its content, so a long label like
     "Gmail / Google Workspace" was quietly pushing the whole grid
     wider than the panel and getting clipped at the screen edge.
     minmax(0,1fr) removes that floor so columns actually share the
     available width instead of growing to fit their longest label. */
  grid-template-columns: minmax(0,1fr) minmax(0,1fr);
  gap: 10px;
  /* margin-top on top of the field label's own 8px - same fix as the
     Team grid, explicit request: the "What are you using right now?"
     label was reading too close to the first row of cards. */
  margin-top: 10px;
}
.vc-tools-grid-single { grid-template-columns: 1fr; }
/* Section label above a group of tool cards - spans both columns so it
   always starts a fresh row (see the comment above .vc-tools-grid).
   First one sits flush under the field label above the grid; every
   later one gets extra breathing room from the row of cards before it
   so the groups read as distinct, not just a label wedged between
   rows. */
.vc-tools-divider {
  grid-column: 1 / -1;
  margin-top: 14px;
  padding-bottom: 2px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--vc-wiz-muted-fg);
  animation: vc-fade-up .3s cubic-bezier(.22,1,.36,1) both;
  animation-delay: calc(var(--vc-i, 0) * .04s);
}
.vc-tools-divider:first-child { margin-top: 0; }
/* Team: only 4 options, so a 2x2 grid of noticeably bigger/thicker
   cards reads far better than a single thin column - explicit
   correction, plus a proper hover lift (not just the shared
   press-down) since that step's cards were called out as needing
   better tactile feedback. */
/* margin-top on top of the field label's own 8px - explicit request,
   the label ("How big is your team?") was reading too close to the
   cards right under it. */
.vc-tools-grid-2x2 { grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 10px; }
.vc-tools-grid-2x2 .vc-tools-card-row { flex-direction: column; align-items: flex-start; gap: 10px; padding: 14px 16px; }
.vc-tools-grid-2x2 .vc-tools-icon { width: 26px; height: 26px; }
.vc-tools-grid-2x2 .vc-tools-label { white-space: normal; font-size: 14px; }
.vc-tools-grid-2x2 .vc-tools-check { position: absolute; top: 12px; right: 12px; }
.vc-tools-grid-2x2 .vc-tools-card:hover { transform: translateY(-2px); }
.vc-tools-card {
  position: relative;
  background: var(--vc-wiz-bg);
  border: 0.8px solid var(--vc-wiz-border);
  border-radius: 12px;
  font-family: var(--font-body);
  text-align: left;
  cursor: pointer;
  animation: vc-fade-up .3s cubic-bezier(.22,1,.36,1) both;
  animation-delay: calc(var(--vc-i, 0) * .04s);
  transition: border-color .2s ease, background-color .2s ease, box-shadow .2s ease, transform .15s ease;
}
.vc-tools-card:hover { border-color: rgba(255,255,255,.28); }
.vc-tools-card:active { transform: scale(.97); }
.vc-tools-card.is-selected {
  border-color: var(--vc-wiz-primary);
  background: rgba(235,235,235,.06);
  box-shadow: 0 0 0 1px var(--vc-wiz-primary) inset;
}
/* Compact row: icon left, name next to it, checkmark trailing on the
   right - this is what actually saves the height a taller stacked
   card was wasting. */
.vc-tools-card-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 10px; /* tightened - Tools' rows were reading as too wide/wasteful with the wider padding */
}
/* Chip-style icon holder - the same soft translucent circle used for
   the real tool logos in the "We Build Around You" strip on the how-
   it-works section (see .tpc-tools-icon in styles.css), just scaled
   down for this compact row. A flat, borderless logo floating right
   next to text was reading as "distorted/bad quality" for anything
   that isn't a perfect square mark; a consistent round backdrop plus
   a white-tinted logo (matches that same section) fixes both the
   perceived quality and gives every row the same visual weight. */
.vc-tools-icon {
  width: 33px;
  height: 33px;
  border-radius: 50%;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255,255,255,.07);
  border: 0.8px solid rgba(255,255,255,.14);
  color: var(--vc-wiz-muted-fg);
  transition: color .2s ease, border-color .2s ease;
}
.vc-tools-icon svg { width: 17px; height: 17px; }
.vc-tools-logo {
  width: 18px;
  height: 18px;
  object-fit: contain;
}
.vc-tools-card.is-selected .vc-tools-icon { color: var(--vc-wiz-primary); border-color: var(--vc-wiz-primary); }
.vc-tools-label {
  flex: 1;
  min-width: 0;
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1.35;
  color: var(--vc-wiz-fg);
  /* Wraps instead of truncating - with the grid overflow bug fixed
     (see .vc-tools-grid) there's real room for a two-line label like
     "Gmail / Google Workspace" instead of losing half of it to an
     ellipsis. */
  white-space: normal;
}
.vc-tools-check {
  position: static;
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--vc-wiz-primary);
  color: var(--vc-wiz-primary-fg);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transform: scale(.4);
  transition: opacity .2s cubic-bezier(.34,1.56,.64,1), transform .2s cubic-bezier(.34,1.56,.64,1);
}
.vc-tools-check svg { width: 11px; height: 11px; }
.vc-tools-card.is-selected .vc-tools-check { opacity: 1; transform: scale(1); }

/* Same spring-y pop as .vc-select-other-field above, for consistency -
   checking "Other" in the Tools grid should feel the same as checking
   it in the Challenge dropdown. */
.vc-tools-other-field {
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transform: scaleY(.85);
  transform-origin: top;
  transition: max-height .35s cubic-bezier(.4,0,.2,1), opacity .25s ease, margin-top .35s ease, transform .35s cubic-bezier(.34,1.56,.64,1);
}
.vc-tools-other-field.is-open {
  max-height: 60px;
  opacity: 1;
  margin-top: 10px;
  transform: scaleY(1);
}
.vc-tools-other-field input {
  width: 100%;
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--vc-wiz-fg);
  background: var(--vc-wiz-bg);
  border: 0.8px solid var(--vc-wiz-border);
  border-radius: 8px;
  padding: 8px 12px;
  height: 40px;
  transition: border-color .3s ease, box-shadow .3s ease;
}
.vc-tools-other-field input::placeholder { color: var(--vc-wiz-muted-fg); }
.vc-tools-other-field input:focus {
  outline: none;
  border-color: var(--vc-wiz-primary);
  box-shadow: 0 0 0 2px rgba(235,235,235,.2);
}

/* ============================================================
   Schedule step - a real month calendar + a time-slot list, ported
   by hand from the user's 21st.dev "calendar-with-time-presets"
   reference (shadcn Calendar next to a scrollable Button list),
   reskinned onto the vc-wiz-* dark tokens instead of shadcn's own
   light theme. Split into two views (date, then time) instead of
   permanently stacked - see the comment above calendarHTML() in
   verion-chat.js for the scroll-friction bug this fixes. Only one
   view is ever in the document at a time (display:none on the
   other), so .vc-cal-times-list below no longer needs its own
   capped-height inner scrollbar - the step's one outer scroll area
   (#vc-body) is the only scroll container now. ============================================================ */
.vc-cal-views { position: relative; }
.vc-cal-view { display: none; }
.vc-cal-view.is-active { display: block; }
.vc-cal-view.is-animating-in { animation: vc-cal-view-in .3s cubic-bezier(.22,1,.36,1) both; }
@keyframes vc-cal-view-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}
/* Its own small back-link, separate from the wizard's own Back
   footer button (which still means "previous step") - shows the
   date they picked so the time list never loses that context. */
.vc-cal-back {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-bottom: 12px;
  padding: 0;
  background: none;
  border: none;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  color: var(--vc-wiz-muted-fg);
  cursor: pointer;
  transition: color .15s ease;
}
.vc-cal-back:hover { color: var(--vc-wiz-fg); }
.vc-cal-back svg { width: 15px; height: 15px; flex-shrink: 0; }
.vc-cal {
  border: 0.8px solid var(--vc-wiz-border);
  border-radius: 14px;
  padding: 14px;
  background: var(--vc-wiz-bg);
}
.vc-cal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}
.vc-cal-label {
  font-size: 14px;
  font-weight: 600;
  color: var(--vc-wiz-fg);
}
.vc-cal-nav {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  color: var(--vc-wiz-muted-fg);
  cursor: pointer;
  transition: background-color .15s ease, color .15s ease;
}
.vc-cal-nav:hover:not(:disabled) { background: rgba(255,255,255,.08); color: var(--vc-wiz-fg); }
.vc-cal-nav:disabled { opacity: .3; cursor: not-allowed; }
.vc-cal-nav svg { width: 16px; height: 16px; }
.vc-cal-weekdays {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  margin-bottom: 4px;
}
.vc-cal-weekdays span {
  text-align: center;
  font-size: 11px;
  font-weight: 600;
  color: var(--vc-wiz-muted-fg);
  padding: 4px 0;
}
.vc-cal-grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0,1fr));
  gap: 2px;
}
.vc-cal-day-empty { visibility: hidden; }
.vc-cal-day {
  position: relative;
  aspect-ratio: 1;
  border: none;
  background: transparent;
  border-radius: 10px;
  color: var(--vc-wiz-fg);
  font-family: var(--font-body);
  font-size: 13px;
  cursor: pointer;
  transition: background-color .15s ease, color .15s ease;
}
.vc-cal-day:hover:not(:disabled):not(.is-selected) { background: rgba(255,255,255,.08); }
.vc-cal-day:disabled { color: rgba(245,245,244,.25); cursor: not-allowed; }
/* Today gets a small dot marker (distinct from the solid "selected"
   pill below) - same idea as a normal calendar app's "today" mark. */
.vc-cal-day.is-today::after {
  content: '';
  position: absolute;
  bottom: 4px;
  left: 50%;
  transform: translateX(-50%);
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--vc-wiz-primary);
}
.vc-cal-day.is-selected {
  background: var(--vc-wiz-primary);
  color: var(--vc-wiz-primary-fg);
  font-weight: 600;
}
.vc-cal-day.is-selected.is-today::after { background: var(--vc-wiz-primary-fg); }

.vc-cal-times { margin-top: 18px; }
.vc-cal-times-label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: var(--vc-wiz-muted-fg);
  margin-bottom: 10px;
}
/* Plain two-column grid of tappable time-slot buttons - ported from a
   21st.dev "calendar-scheduler" reference (minus its own date column,
   since the date is already picked on the previous screen), replacing
   the old 3D scroll-wheel picker per explicit request ("get rid of
   the wheel completely"). As many rows as the offered times need -
   see CAL_HOURS in verion-chat.js. */
.vc-cal-timegrid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}
.vc-cal-timeslot {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 44px;
  border-radius: 10px;
  border: 0.8px solid var(--vc-wiz-border);
  background: var(--vc-wiz-bg);
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 500;
  color: var(--vc-wiz-fg);
  cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
.vc-cal-timeslot:hover:not(.is-selected) { background: rgba(255,255,255,.06); border-color: rgba(255,255,255,.22); }
.vc-cal-timeslot.is-selected {
  background: var(--vc-wiz-primary);
  border-color: var(--vc-wiz-primary);
  color: var(--vc-wiz-primary-fg);
  font-weight: 700;
}
.vc-cal-timeslot .vc-cal-time-tag { opacity: .7; }
.vc-cal-timeslot.is-selected .vc-cal-time-tag { color: var(--vc-wiz-primary-fg); opacity: .85; }
.vc-cal-time-tag {
  font-size: 11px;
  font-weight: 500;
  color: var(--vc-wiz-muted-fg);
}
/* An inset info chip, not a bare caption line sitting flush under the
   last time slot - explicit request for more visual separation + more
   room below the time list before the footer. */
.vc-cal-note {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 20px 0 4px;
  padding: 10px 12px;
  background: rgba(255,255,255,.04);
  border: 0.8px solid var(--vc-wiz-border);
  border-radius: 10px;
}
.vc-cal-note svg {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  margin-top: 1px;
  color: var(--vc-wiz-muted-fg);
}
.vc-cal-note p {
  margin: 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--vc-wiz-muted-fg);
}

/* Radio/checkbox rows in the reference: each is
   `<motion.div className="flex items-center space-x-2 rounded-md border p-3 cursor-pointer hover:bg-accent transition-colors">`
   with a RadioGroupItem/Checkbox (`h-4 w-4`) and a full-width Label.
   → 12px padding, 8px gap (space-x-2), 6px radius (rounded-md), 16px radio/check.
   `.space-y-2` on the RadioGroup itself = 8px gap between options.
   whileHover: scale 1.02, whileTap: scale 0.98. */
.vc-radio-list, .vc-check-list {
  display: flex;
  flex-direction: column;
  gap: 8px; /* space-y-2 */
}
.vc-check-grid {
  display: grid;
  grid-template-columns: 1fr 1fr; /* md:grid-cols-2 */
  gap: 8px;
}
.vc-opt {
  display: flex;
  align-items: center;
  gap: 8px; /* space-x-2 */
  padding: 12px; /* p-3 */
  border: 0.8px solid var(--vc-wiz-border);
  background: transparent;
  border-radius: 8px; /* measured: 8px like inputs, not 6px */
  cursor: pointer;
  font-size: 14px; /* text-sm - Label default */
  color: var(--vc-wiz-fg);
  transition:
    background-color .2s ease,
    border-color .2s ease,
    transform .18s ease;
}
.vc-opt:hover {
  background: rgba(255,255,255,.08); /* hover:bg-accent, measured tone */
  border-color: rgba(255,255,255,.24);
  transform: scale(1.02);
}
.vc-opt:active { transform: scale(.98); }
.vc-opt-mark {
  width: 16px; /* h-4 w-4 */
  height: 16px;
  flex-shrink: 0;
  border: 1px solid var(--vc-wiz-primary); /* border-primary, measured */
  background: transparent;
  transition: border-color .18s, background-color .18s;
  position: relative;
}
.vc-radio-list .vc-opt-mark { border-radius: 50%; }
.vc-check-list .vc-opt-mark,
.vc-check-grid .vc-opt-mark { border-radius: 2px; } /* rounded-sm */
.vc-opt.is-checked { border-color: rgba(255,255,255,.35); background: rgba(255,255,255,.05); }
.vc-opt.is-checked .vc-opt-mark { border-color: var(--vc-wiz-primary); background: var(--vc-wiz-primary); }
/* Radio inner dot — reference: <Circle className="h-2.5 w-2.5 fill-current" /> */
.vc-radio-list .vc-opt.is-checked .vc-opt-mark::after {
  content: '';
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: 10px; height: 10px; /* h-2.5 w-2.5 */
  border-radius: 50%;
  background: var(--vc-wiz-primary-fg);
}
/* Checkbox check — reference: <Check className="h-4 w-4" /> */
.vc-check-list .vc-opt.is-checked .vc-opt-mark::after,
.vc-check-grid .vc-opt.is-checked .vc-opt-mark::after {
  content: '';
  position: absolute;
  left: 3px; top: 6px;
  width: 8px; height: 4px;
  border-left: 1.5px solid var(--vc-wiz-primary-fg);
  border-bottom: 1.5px solid var(--vc-wiz-primary-fg);
  transform: rotate(-45deg);
}

/* Step indicator: text under the card that fades in at delay 0.4s
   (reference: `opacity: 0 → 1, delay: 0.4, duration: 0.5`). Explicit
   visual upgrade (still no animation change, per spec) - one flat gray
   sentence ("Step 1 of 7: Personal") read as an afterthought, so it's
   now a small uppercase "eyebrow" count, a hairline dot separator, and
   the step's own title in the brighter foreground color - same
   information, real typographic hierarchy instead of one plain line. */
.vc-step-indicator {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 14px;
  animation: vc-fade .5s .4s ease both;
}
.vc-step-indicator-count {
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--vc-wiz-muted-fg);
}
.vc-step-indicator-dot {
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--vc-wiz-muted-fg);
  flex-shrink: 0;
}
.vc-step-indicator-title {
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  color: var(--vc-wiz-fg);
}
@keyframes vc-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Buttons match shadcn default sizing (`h-10 px-4 py-2 text-sm font-medium`)
   with the demo's `rounded-2xl gap-1` overrides = 16px radius, 4px gap.
   Back is `variant="outline"` (border + hover accent). Next is default
   (bg-primary hover:bg-primary/90). Each wrapped in motion.div with
   whileHover 1.05 / whileTap 0.95. Disabled: opacity 0.5, pointer none. */
/* Back button measured live: bg matches the page background (not
   transparent), border white ~15%, text near-white - a solid
   "outline" button, not a ghost one. */
.vc-back {
  background: var(--vc-wiz-bg);
  border: 0.8px solid var(--vc-wiz-border);
  color: var(--vc-wiz-fg);
  font-family: var(--font-body);
  font-size: 14px; /* text-sm */
  font-weight: 500; /* font-medium */
  cursor: pointer;
  padding: 8px 16px; /* py-2 px-4 */
  height: 40px; /* h-10 */
  border-radius: 16px; /* rounded-2xl */
  display: inline-flex; align-items: center; gap: 4px; /* gap-1 */
  transition:
    background-color .3s ease,
    color .3s ease,
    border-color .3s ease,
    opacity .3s ease,
    transform .15s ease;
}
.vc-back:hover:not(:disabled) {
  background: rgba(255,255,255,.08); /* hover:bg-accent */
  transform: scale(1.05);
}
.vc-back:active:not(:disabled) { transform: scale(.95); }
.vc-back:disabled { opacity: .5; cursor: not-allowed; pointer-events: none; }
.vc-back svg { width: 16px; height: 16px; stroke: currentColor; } /* h-4 w-4 */

/* Primary button measured live: bg is the soft off-white #ebebeb
   (not pure #fff), text is the same near-black as the card (#1a1a1a). */
.vc-primary {
  background: var(--vc-wiz-primary);
  color: var(--vc-wiz-primary-fg);
  border: none;
  height: 40px;      /* h-10 */
  padding: 8px 16px; /* py-2 px-4 */
  border-radius: 16px; /* rounded-2xl */
  font-family: var(--font-body);
  font-size: 14px;   /* text-sm */
  font-weight: 500;  /* font-medium */
  cursor: pointer;
  display: inline-flex; align-items: center; gap: 4px; /* gap-1 */
  transition:
    background-color .3s ease,
    opacity .3s ease,
    transform .15s ease;
}
.vc-primary:hover:not(:disabled) {
  background: #f5f5f5; /* hover:bg-primary/90, measured lightening */
  transform: scale(1.05);
}
.vc-primary:active:not(:disabled) { transform: scale(.95); }
.vc-primary:disabled { opacity: .5; cursor: not-allowed; pointer-events: none; }
.vc-primary svg { width: 16px; height: 16px; stroke: currentColor; } /* h-4 w-4 */

/* Loader spinner (Loader2 in the reference during submit). Spins
   against the primary-fg tone since it sits on the off-white button. */
.vc-spinner {
  width: 14px; height: 14px;
  border: 2px solid rgba(26,26,26,.25);
  border-top-color: var(--vc-wiz-primary-fg);
  border-radius: 50%;
  animation: vc-orb-spin 0.8s linear infinite;
}

/* Success screen */
.vc-success {
  text-align: center;
  padding: 32px 28px 24px; /* a touch more side room than the other steps' 24px - explicit request, nothing here shares a row with a label to align against */
}
/* Icon plays a two-stage "confirming -> done" reveal instead of an
   instant static pop: a ring draws itself in (stroke-dasharray, real
   geometry, not a fake spinner) then the checkmark draws in right as
   the ring finishes - and both use the accent green (matches the
   location card's pin, the one other spot of color in this whole dark
   system) instead of the flat gray circle this used to sit in. */
.vc-success-icon {
  position: relative;
  width: 56px; height: 56px;
  margin: 0 auto 20px;
  border-radius: 50%;
  background: rgba(52,211,153,.12);
}
.vc-success-ring {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  transform: rotate(-90deg); /* draw starts at 12 o'clock, not 3 o'clock */
}
.vc-success-ring circle {
  fill: none;
  stroke: #34D399;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: vc-ring-draw .5s cubic-bezier(.4,0,.2,1) .1s forwards;
}
.vc-success-check {
  position: absolute;
  top: 50%; left: 50%;
  width: 22px; height: 22px;
  transform: translate(-50%, -50%);
  color: #34D399;
}
.vc-success-check path {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  opacity: 0;
  animation: vc-check-draw .3s cubic-bezier(.4,0,.2,1) .5s forwards;
}
@keyframes vc-ring-draw { to { stroke-dashoffset: 0; } }
@keyframes vc-check-draw { 0% { opacity: 1; } to { stroke-dashoffset: 0; opacity: 1; } }
/* Matched to .vc-wiz-title/.vc-wiz-desc (the same header the other 6
   steps use) - was its own smaller one-off scale (20px/13px), which
   read as an afterthought next to every other step's 24px/14px. */
.vc-success h2 {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 600;
  letter-spacing: -0.025em;
  color: var(--vc-wiz-fg);
  line-height: 1.2;
  margin: 0 0 16px;
}
/* The appointment itself, pulled out of sentence flow into its own
   small card - explicit request for real visual hierarchy instead of
   a run-on sentence that could wrap onto its own orphan line. */
.vc-success-appt {
  text-align: left;
  background: rgba(255,255,255,.03);
  border: 0.8px solid var(--vc-wiz-border);
  border-radius: 12px;
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.vc-success-appt-row {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  color: var(--vc-wiz-fg);
  font-weight: 500;
}
.vc-success-appt-row svg {
  width: 17px; height: 17px;
  flex-shrink: 0;
  color: var(--vc-wiz-muted-fg);
}
.vc-success-note {
  margin: 14px 0 0;
  font-size: 12.5px;
  color: var(--vc-wiz-muted-fg);
  line-height: 1.6;
}
.vc-success-note strong {
  display: inline-block;
  margin-top: 3px;
  font-size: 13.5px;
  color: var(--vc-wiz-fg);
  font-weight: 600;
}

/* Editable overview shown under the success message - additive only,
   built from the exact same tokens/spacing scale as the rest of the
   wizard (no new colors, no new radii, nothing that touches the
   existing design system). Each group mirrors one wizard step, with
   an Edit link that jumps straight back to it via go(). */
.vc-summary {
  margin-top: 24px;
  padding-top: 24px;
  border-top: 0.8px solid var(--vc-wiz-border);
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
/* Each step gets its own bordered card, not a flat list separated by
   nothing but a gap - explicit request for real, scannable structure
   ("personal, name, email... it looks so sad") instead of everything
   just running down the page at the same visual weight. Same card
   treatment as .vc-success-appt above it, so the whole success screen
   reads as one consistent system. */
.vc-summary-group {
  background: rgba(255,255,255,.03);
  border: 0.8px solid var(--vc-wiz-border);
  border-radius: 12px;
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.vc-summary-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.vc-summary-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: var(--vc-wiz-muted-fg);
}
.vc-summary-title svg { width: 14px; height: 14px; flex-shrink: 0; }
/* A real pill button (border + icon), not a bare underlined text link
   pinned to the far edge - explicit request, matches the pencil icon
   already used for the same "edit" action on the location card. */
.vc-summary-edit {
  display: flex;
  align-items: center;
  gap: 5px;
  background: var(--vc-wiz-bg);
  border: 0.8px solid var(--vc-wiz-border);
  border-radius: 999px;
  padding: 5px 11px 5px 9px;
  font-family: var(--font-body);
  font-size: 11.5px;
  font-weight: 600;
  color: var(--vc-wiz-fg);
  cursor: pointer;
  transition: border-color .15s ease, background-color .15s ease;
}
.vc-summary-edit svg { width: 12px; height: 12px; flex-shrink: 0; }
.vc-summary-edit:hover { border-color: rgba(255,255,255,.28); background: rgba(255,255,255,.06); }
.vc-summary-rows {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
/* Stacked (label above, value below), not a two-column row - a squeezed
   side-by-side layout was forcing long values (the full booked date +
   time, a comma-joined tools list) to compete for width against their
   label, which is what was reading as "cut off" and forced the text
   small to begin with. Full row width to wrap into fixes that outright
   and lets the value read at a normal, comfortable size - matches how
   a real booking confirmation (Calendly, Stripe) lays out its summary. */
.vc-summary-row {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.vc-summary-label { font-size: 12px; color: var(--vc-wiz-muted-fg); }
.vc-summary-value {
  font-size: 14.5px;
  line-height: 1.45;
  color: var(--vc-wiz-fg);
  overflow-wrap: anywhere;
}

/* Responsive: very narrow screens */
@media (max-width: 500px) {
  .vc-root { left: 12px; bottom: 12px; }
  /* Target widths/heights on narrow screens are computed in JS
     (isNarrow()/targetDims() in verion-chat.js) instead of a CSS
     override, since the panel's size is now JS-driven per phase. */
}

/* Respect reduced motion */
@media (prefers-reduced-motion: reduce) {
  .vc-panel,
  .vc-panel-inner,
  .vc-wiz-step,
  .vc-wiz-bar-fill,
  .vc-wiz-progress,
  .vc-wiz-card,
  .vc-field,
  .vc-opt,
  .vc-step-indicator,
  .vc-success-icon,
  .vc-success-ring circle,
  .vc-success-check path,
  .vc-cal-view,
  .vc-msg-group,
  .vc-msg-typing-dots span,
  .vc-word,
  .vc-input,
  .vc-input-expand,
  .vc-msg-group-bot .vc-msg-text.is-streaming,
  .vc-locmap-fields,
  .vc-locmap-box,
  .vc-locmap-grid,
  .vc-locmap-scene,
  .vc-locmap-road,
  .vc-locmap-bldg,
  .vc-locmap-pin,
  .vc-locmap-pin-icon,
  .vc-locmap-icon,
  .vc-locmap-edit,
  .vc-locmap-underline,
  .vc-select-trigger,
  .vc-select-caret,
  .vc-select-panel,
  .vc-select-opt,
  .vc-select-opt-check,
  .vc-tools-card,
  .vc-tools-icon,
  .vc-tools-check,
  .vc-tools-other-field,
  .vc-select-other-field,
  .vc-scroll-hint { animation: none; transition: none; }
  /* animation:none above also cancels the opacity/dashoffset the draw-in
     keyframes were supplying - without these, reduced motion would leave
     the ring/check invisible instead of just skipping straight to done. */
  .vc-success-ring circle { stroke-dashoffset: 0; }
  .vc-success-check path { stroke-dashoffset: 0; opacity: 1; }
}

/* ---- Sending note / error pop-up above the booking submit button ---- */
.vc-send-pop {
  position: absolute;
  right: 4px;
  bottom: calc(100% + 10px);
  z-index: 5;
  display: flex;
  align-items: flex-start;
  gap: 9px;
  max-width: min(300px, calc(100% - 8px));
  padding: 10px 14px 11px;
  border-radius: 14px;
  background: #1c1b19;
  color: #f4f3ef;
  font-size: 12.5px;
  line-height: 1.45;
  box-shadow: 0 10px 28px -8px rgba(0, 0, 0, .55), 0 0 0 1px rgba(255, 255, 255, .08);
  pointer-events: none;
  /* hidden state: slightly smaller, lower and see-through (never scale(0)) */
  opacity: 0;
  transform: translateY(8px) scale(.96);
  transform-origin: calc(100% - 28px) 100%;
  transition: opacity 140ms ease-out, transform 140ms ease-out;
}
.vc-send-pop.is-in {
  opacity: 1;
  transform: translateY(0) scale(1);
  transition: opacity 220ms cubic-bezier(.23, 1, .32, 1), transform 260ms cubic-bezier(.23, 1, .32, 1);
}
.vc-send-pop::after {
  content: "";
  position: absolute;
  right: 26px;
  bottom: -5px;
  width: 10px;
  height: 10px;
  background: #1c1b19;
  transform: rotate(45deg);
  border-radius: 0 0 3px 0;
  box-shadow: 1px 1px 0 rgba(255, 255, 255, .08);
}
.vc-send-pop-dot {
  flex: none;
  width: 7px;
  height: 7px;
  margin-top: 5px;
  border-radius: 50%;
  background: #f4f3ef;
  animation: vc-send-pulse 1.2s ease-in-out infinite;
}
.vc-send-pop.is-error .vc-send-pop-dot { background: #ff7a6b; animation: none; }
@keyframes vc-send-pulse { 0%, 100% { opacity: .35; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .vc-send-pop, .vc-send-pop.is-in { transition: opacity 120ms linear; transform: none; }
  .vc-send-pop-dot { animation: none; }
}
/* "Message us on WhatsApp" on the confirmation screen */
.vc-wa-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin: 14px auto 0;
  padding: 10px 18px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, .28);
  color: #f4f3ef;
  font-size: 13px;
  text-decoration: none;
  transition: background-color .2s ease, transform .16s ease-out;
}
@media (hover: hover) and (pointer: fine) { .vc-wa-btn:hover { background: rgba(255, 255, 255, .1); } }
.vc-wa-btn:active { transform: scale(.97); }
