@@ -4063,22 +4063,84 @@ function applyOnboardingHighlight(selector) {
40634063 }
40644064}
40654065
4066+ function positionOnboardingCard ( selector ) {
4067+ const card = $ ( '#onboarding-card' ) ;
4068+ if ( ! card ) return ;
4069+
4070+ if ( ! selector ) {
4071+ card . classList . add ( 'centered' ) ;
4072+ const arrow = card . querySelector ( '.card-arrow' ) ;
4073+ if ( arrow ) arrow . remove ( ) ;
4074+ return ;
4075+ }
4076+
4077+ card . classList . remove ( 'centered' ) ;
4078+
4079+ const el = document . querySelector ( selector ) ;
4080+ if ( ! el ) return ;
4081+
4082+ const elRect = el . getBoundingClientRect ( ) ;
4083+ const cardW = 440 ;
4084+ const cardMaxH = window . innerHeight - 80 ;
4085+ const gap = 14 ;
4086+
4087+ // Remove old arrow and create a new one
4088+ const oldArrow = card . querySelector ( '.card-arrow' ) ;
4089+ if ( oldArrow ) oldArrow . remove ( ) ;
4090+ const arrow = document . createElement ( 'div' ) ;
4091+ arrow . className = 'card-arrow' ;
4092+ card . appendChild ( arrow ) ;
4093+
4094+ let top , arrowDir ;
4095+
4096+ // Try below first
4097+ const spaceBelow = window . innerHeight - elRect . bottom ;
4098+ const spaceAbove = elRect . top ;
4099+ const approxCardH = Math . min ( 360 , cardMaxH ) ;
4100+
4101+ if ( spaceBelow >= approxCardH + gap + 20 ) {
4102+ top = elRect . bottom + gap ;
4103+ arrowDir = 'up' ;
4104+ } else if ( spaceAbove >= approxCardH + gap + 20 ) {
4105+ top = elRect . top - gap - approxCardH ;
4106+ arrowDir = 'down' ;
4107+ } else {
4108+ // Center as fallback
4109+ top = Math . max ( 20 , ( window . innerHeight - approxCardH ) / 2 ) ;
4110+ arrowDir = null ;
4111+ }
4112+
4113+ // Center card horizontally under the element, but clamp to viewport
4114+ let left = elRect . left + elRect . width / 2 - cardW / 2 ;
4115+ left = Math . max ( 16 , Math . min ( left , window . innerWidth - cardW - 16 ) ) ;
4116+
4117+ top = Math . max ( 16 , Math . min ( top , window . innerHeight - approxCardH - 16 ) ) ;
4118+
4119+ card . style . top = top + 'px' ;
4120+ card . style . left = left + 'px' ;
4121+ card . style . transform = 'none' ;
4122+
4123+ if ( arrowDir ) {
4124+ arrow . className = `card-arrow ${ arrowDir } ` ;
4125+ } else {
4126+ arrow . remove ( ) ;
4127+ }
4128+ }
4129+
40664130function renderOnboardingStep ( stepIndex ) {
40674131 const card = $ ( '#onboarding-card' ) ;
40684132 if ( ! card ) return ;
40694133
40704134 const step = ONBOARDING_STEPS [ stepIndex ] ;
4071- const isLast = stepIndex === ONBOARDING_STEPS . length - 1 ;
4072- const isFirst = stepIndex === 0 ;
40734135
40744136 let dotsHtml = '<div class="onboarding-dots">' ;
40754137 ONBOARDING_STEPS . forEach ( ( _ , i ) => {
40764138 dotsHtml += `<span class="onboarding-dot ${ i === stepIndex ? 'active' : '' } "></span>` ;
40774139 } ) ;
40784140 dotsHtml += '</div>' ;
40794141
4080- const leftBtn = step . buttons [ 0 ] ; // Skip
4081- const rightBtn = step . buttons [ 1 ] ; // Start / Next / Got it!
4142+ const leftBtn = step . buttons [ 0 ] ;
4143+ const rightBtn = step . buttons [ 1 ] ;
40824144
40834145 card . innerHTML = html `
40844146 ${ dotsHtml }
@@ -4090,7 +4152,16 @@ function renderOnboardingStep(stepIndex) {
40904152 </ div >
40914153 ` ;
40924154
4093- applyOnboardingHighlight ( step . highlight ) ;
4155+ const backdrop = $ ( '#onboarding-backdrop' ) ;
4156+ if ( step . highlight ) {
4157+ if ( backdrop ) backdrop . style . display = 'none' ;
4158+ applyOnboardingHighlight ( step . highlight ) ;
4159+ } else {
4160+ if ( backdrop ) backdrop . style . display = 'block' ;
4161+ clearOnboardingHighlight ( ) ;
4162+ }
4163+
4164+ positionOnboardingCard ( step . highlight ) ;
40944165 initIcons ( ) ;
40954166}
40964167
@@ -4106,24 +4177,26 @@ async function startOnboarding() {
41064177 overlay . id = 'onboarding-overlay' ;
41074178 overlay . className = 'onboarding-overlay' ;
41084179 overlay . innerHTML = html `
4109- < div class ="onboarding-backdrop " id ="onboarding-backdrop "> </ div >
4110- < div class ="onboarding-card " id ="onboarding-card "> </ div >
4180+ < div class ="onboarding-backdrop " id ="onboarding-backdrop " style =" display:none " > </ div >
4181+ < div class ="onboarding-card centered " id ="onboarding-card "> </ div >
41114182 ` ;
41124183 document . body . appendChild ( overlay ) ;
41134184
41144185 renderOnboardingStep ( 0 ) ;
41154186
4116- $ ( '#onboarding-skip' ) . addEventListener ( 'click' , stopOnboarding ) ;
4117- $ ( '#onboarding-next' ) . addEventListener ( 'click' , ( ) => {
4118- if ( onboardingStep === 0 ) {
4119- onboardingStep = 1 ;
4120- renderOnboardingStep ( onboardingStep ) ;
4121- $ ( '#onboarding-skip' ) . addEventListener ( 'click' , stopOnboarding ) ;
4122- $ ( '#onboarding-next' ) . addEventListener ( 'click' , handleOnboardingNext ) ;
4123- } else {
4124- handleOnboardingNext ( ) ;
4125- }
4126- } ) ;
4187+ const attachListeners = ( ) => {
4188+ $ ( '#onboarding-skip' ) . addEventListener ( 'click' , stopOnboarding ) ;
4189+ $ ( '#onboarding-next' ) . addEventListener ( 'click' , ( ) => {
4190+ if ( onboardingStep === 0 ) {
4191+ onboardingStep = 1 ;
4192+ renderOnboardingStep ( onboardingStep ) ;
4193+ attachListeners ( ) ;
4194+ } else {
4195+ handleOnboardingNext ( ) ;
4196+ }
4197+ } ) ;
4198+ } ;
4199+ attachListeners ( ) ;
41274200}
41284201
41294202function handleOnboardingNext ( ) {
0 commit comments