@@ -12,48 +12,35 @@ import { showModal } from '../ui/ink/components/Modal.js';
1212import packageJson from '../../package.json' with { type : 'json' } ;
1313import type { LoadedConfig } from '../types.js' ;
1414
15- // Large FIGlet ASCII art — circles on left (lines 1-2), "Autohand Code" fills all lines
15+ // ASCII logo + ANSI Regular FIGlet "Autohand" — side-by-side, cross-platform
16+ const GAP = ' ' ;
1617const LOGO_LINES = [
17- '◎ ◎ ◎ ◎ ___ __ __ __ ______ __ ' ,
18- '◎ ◎ ◎ ◎ / | __ __/ /_____ / /_ ____ _____ ____/ / / ____/___ ____/ /__ ' ,
19- ' / /| |/ / / / __/ __ \\/ __ \\/ __ `/ __ \\/ __ / / / / __ \\/ __ / _ \\ ' ,
20- ' / ___ / /_/ / /_/ /_/ / / / / /_/ / / / / /_/ / / /___/ /_/ / /_/ / __/ ' ,
21- ' /_/ |_\\__,_/\\__/\\____/_/ /_/\\__,_/_/ /_/\\__,_/ \\____/\\____/\\__,_/\\___/ ' ,
18+ '(@) (@) (@) (@)' + GAP + ' █████ ██ ██ ████████ ██████ ██ ██ █████ ███ ██ ██████ ',
19+ '(@) (@) (@) (@)' + GAP + '██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ████ ██ ██ ██ ',
20+ ' ' + GAP + '███████ ██ ██ ██ ██ ██ ███████ ███████ ██ ██ ██ ██ ██ ',
21+ ' ' + GAP + '██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ',
22+ ' ' + GAP + '██ ██ ██████ ██ ██████ ██ ██ ██ ██ ██ ████ ██████ ',
2223] ;
2324
25+ /** Total number of rendered lines. */
26+ const WELCOME_HEIGHT = LOGO_LINES . length ;
27+
2428/**
25- * Typewriter: circles appear column by column on both rows,
26- * then the full FIGlet text reveals line by line.
29+ * Typewriter: renders the logo line by line, horizontally centered.
2730 */
2831async function typewriteWelcome ( startRow : number ) : Promise < void > {
29- const hide = '\x1b[?25l' ;
30- const show = '\x1b[?25h' ;
31- const moveTo = ( r : number , c : number ) => `\x1b[${ r } ;${ c } H` ;
32-
33- process . stdout . write ( hide ) ;
34-
35- // Phase 1: Type circles column by column (both rows at once)
36- for ( let col = 0 ; col < 4 ; col ++ ) {
37- const x = 1 + col * 2 ; // column position (◎ + space = 2 chars)
38- process . stdout . write ( moveTo ( startRow , x ) + chalk . white ( '◎' ) ) ;
39- process . stdout . write ( moveTo ( startRow + 1 , x ) + chalk . white ( '◎' ) ) ;
40- await new Promise ( r => setTimeout ( r , 100 ) ) ;
41- }
32+ const cols = process . stdout . columns || 80 ;
33+ const maxWidth = Math . max ( ...LOGO_LINES . map ( l => l . length ) ) ;
34+ const leftPad = Math . max ( 0 , Math . floor ( ( cols - maxWidth ) / 2 ) ) ;
35+ const pad = ' ' . repeat ( leftPad ) ;
4236
43- await new Promise ( r => setTimeout ( r , 150 ) ) ;
44-
45- // Phase 2: Reveal the text portion of each line
37+ process . stdout . write ( '\x1b[?25l' ) ; // hide cursor
4638 for ( let i = 0 ; i < LOGO_LINES . length ; i ++ ) {
47- const line = LOGO_LINES [ i ] ;
48- // For circle lines (0,1), only write the text part after the circles
49- const textStart = i < 2 ? 9 : 0 ; // circles take 9 chars "◎ ◎ ◎ ◎ "
50- const text = i < 2 ? line . slice ( textStart ) : line ;
51- const col = i < 2 ? 10 : 1 ;
52- process . stdout . write ( moveTo ( startRow + i , col ) + chalk . white ( text ) ) ;
53- await new Promise ( r => setTimeout ( r , 60 ) ) ;
39+ process . stdout . write ( `\x1b[${ startRow + i } ;1H\x1b[2K` ) ;
40+ process . stdout . write ( chalk . white ( pad + LOGO_LINES [ i ] ) ) ;
41+ await new Promise ( r => setTimeout ( r , 70 ) ) ;
5442 }
55-
56- process . stdout . write ( show ) ;
43+ process . stdout . write ( '\x1b[?25h' ) ; // show cursor
5744}
5845
5946/**
@@ -148,19 +135,22 @@ async function promptLogin(config: LoadedConfig): Promise<LoadedConfig> {
148135 // Clear screen and position content vertically centered
149136 process . stdout . write ( '\x1b[2J\x1b[H' ) ;
150137
151- // Layout: logo (5 lines) + blank + version + blank + modal (~12 lines)
152- const logoHeight = LOGO_LINES . length ;
153- const contentHeight = logoHeight + 6 ;
138+ // Layout: logo (8 lines) + blank + version + blank + modal (~12)
139+ const contentHeight = WELCOME_HEIGHT + 6 ;
154140 const topPadding = Math . max ( 0 , Math . floor ( ( rows - contentHeight ) / 2 ) ) ;
155141 const logoRow = topPadding + 1 ; // 1-based terminal row
156142
157- // Typewriter the circles, then reveal the FIGlet text
143+ // Typewriter: icon + FIGlet side-by-side
158144 await typewriteWelcome ( logoRow ) ;
159145
160- // Position cursor below the logo for version + modal
161- process . stdout . write ( `\x1b[${ logoRow + logoHeight } ;1H` ) ;
146+ // Position cursor below the art for version + modal
147+ process . stdout . write ( `\x1b[${ logoRow + WELCOME_HEIGHT } ;1H` ) ;
148+ const cols = process . stdout . columns || 80 ;
149+ const maxWidth = Math . max ( ...LOGO_LINES . map ( l => l . length ) ) ;
150+ const leftPad = Math . max ( 0 , Math . floor ( ( cols - maxWidth ) / 2 ) ) ;
151+ const versionPad = ' ' . repeat ( leftPad + Math . floor ( ( maxWidth - version . length ) / 2 ) ) ;
162152 console . log ( ) ;
163- console . log ( chalk . gray ( ` ${ version } ` ) ) ;
153+ console . log ( chalk . gray ( `${ versionPad } ${ version } ` ) ) ;
164154 console . log ( ) ;
165155
166156 const selected = await showModal ( {
0 commit comments