Generally you’d move the Tuplet Number simply by offsetting its X/Y-offset values. If you want some refinement maybe do
{
\override TupletNumber.Y-offset =
#(lambda (grob)
(let* ((bracket (ly:grob-object grob 'bracket))
(stc (ly:grob-property grob 'stencil))
(ext (ly:stencil-extent stc Y))
(align (ly:grob-property grob 'self-alignment-Y 0))
(palign (ly:grob-property grob 'parent-alignment-Y align))
(align (/ (1+ align) 2))
(palign (/ (1+ palign) 2))
(pos (ly:grob-property bracket 'positions)))
(+ (* palign (cdr pos)) (* (- 1 palign) (car pos))
(* align (cdr ext)) (* (- 1 palign) (car ext)))))
\override TupletNumber.X-offset =
#(lambda (grob)
(let* ((bracket (ly:grob-object grob 'bracket))
(stc (ly:grob-property grob 'stencil))
(ext (ly:stencil-extent stc X))
(align (ly:grob-property grob 'self-alignment-X 0))
(palign (ly:grob-property grob 'parent-alignment-X align))
(align (/ (1+ align) 2))
(palign (/ (1+ palign) 2))
(pos (ly:grob-property bracket 'X-positions)))
(display palign)
(+ (* palign (cdr pos)) (* (- 1 palign) (car pos))
(* align (cdr ext)) (* (- 1 palign) (car ext)))))
\override TupletBracket.tuplet-slur = ##t
\override TupletNumber.padding =
#(lambda (grob)
(let ((b (ly:grob-object grob 'bracket)))
(- (interval-center (ly:grob-property b 'edge-height)))))
\override TupletNumber.self-alignment-Y =
#(lambda (grob)
(ly:grob-property (ly:grob-object grob 'bracket) 'direction))
\override TupletNumber.parent-alignment-Y =
#(lambda (grob)
(* 2 (ly:grob-property (ly:grob-object grob 'bracket) 'direction)))
\override TupletNumber.parent-alignment-X = #-0.8
\tuplet 3/2 { c'4 d' e' }
\tuplet 3/2 { c''4 d'' e'' }
}
This would look like this
\override TupletBracket.tuplet-slur = ##t
(see: lilypond.org/doc/v2.24/Documentation/notation/…).