@@ -121,7 +121,7 @@ function renderRich(s: string, codeClass = 'text-cyan-300'): ReactNode {
121121 return s . split ( / ( ` [ ^ ` ] + ` | \* [ ^ * ] + \* ) / g) . map ( ( part , i ) => {
122122 if ( part . length > 1 && part . startsWith ( '`' ) && part . endsWith ( '`' ) ) {
123123 return (
124- < code key = { i } className = { `font-mono ${ codeClass } ` } >
124+ < code key = { i } className = { `font-mono break-words ${ codeClass } ` } >
125125 { part . slice ( 1 , - 1 ) }
126126 </ code >
127127 )
@@ -245,16 +245,22 @@ function InfoRow({
245245 value,
246246 tone = 'default' ,
247247 mono = true ,
248+ breakAll = true ,
248249} : {
249250 label : string
250251 value : ReactNode
251252 tone ?: Tone
252253 mono ?: boolean
254+ breakAll ?: boolean
253255} ) {
254256 return (
255257 < div className = "flex items-baseline justify-between gap-4 text-sm" >
256258 < span className = "text-slate-400 shrink-0" > { label } </ span >
257- < span className = { `text-right break-all ${ mono ? 'font-mono' : '' } ${ TONE_TEXT [ tone ] } ` } >
259+ < span
260+ className = { `text-right ${ breakAll ? 'break-all' : 'break-words' } ${
261+ mono ? 'font-mono' : ''
262+ } ${ TONE_TEXT [ tone ] } `}
263+ >
258264 { value }
259265 </ span >
260266 </ div >
@@ -289,6 +295,7 @@ function SectionCard({
289295 accent = 'cyan' ,
290296 action,
291297 danger,
298+ id,
292299 children,
293300} : {
294301 title : string
@@ -297,6 +304,7 @@ function SectionCard({
297304 accent ?: 'cyan' | 'emerald' | 'amber' | 'slate'
298305 action ?: ReactNode
299306 danger ?: boolean
307+ id ?: string
300308 children : ReactNode
301309} ) {
302310 const text = {
@@ -313,6 +321,7 @@ function SectionCard({
313321 } [ accent ]
314322 return (
315323 < section
324+ id = { id }
316325 className = { `glass-card glow-border rounded-2xl sm:rounded-3xl p-5 sm:p-6 md:p-7 space-y-4 sm:space-y-5 ${
317326 danger ? 'danger' : ''
318327 } `}
@@ -365,6 +374,7 @@ export default function App() {
365374 const [ txHash , setTxHash ] = useState ( '' )
366375 const [ sharesInput , setSharesInput ] = useState ( '' )
367376 const [ sunsetConfirmOpen , setSunsetConfirmOpen ] = useState ( false )
377+ const justConnectedRef = useRef ( false )
368378
369379 // ── Bootstrap: load config + wallet list ──
370380 useEffect ( ( ) => {
@@ -384,6 +394,17 @@ export default function App() {
384394 }
385395 } , [ ] )
386396
397+ // After a fresh connect, scroll the vault section into view on mobile.
398+ useEffect ( ( ) => {
399+ if ( ! vault || ! justConnectedRef . current ) return
400+ justConnectedRef . current = false
401+ if ( typeof window !== 'undefined' && window . innerWidth < 640 ) {
402+ document
403+ . getElementById ( 'vault-section' )
404+ ?. scrollIntoView ( { behavior : 'smooth' , block : 'start' } )
405+ }
406+ } , [ vault ] )
407+
387408 // ── Connect flow ──
388409 async function handleConnect ( ) {
389410 setStatus ( null )
@@ -428,6 +449,7 @@ export default function App() {
428449 setLucid ( ld )
429450 setWalletAddr ( addr )
430451 setNetworkResolved ( resolvedNet )
452+ justConnectedRef . current = true
431453 setStatus ( { kind : 'ok' , text : t ( 'st.connected' ) } )
432454 await loadOnChainState ( ld , resolvedNet )
433455 } catch ( e ) {
@@ -723,9 +745,31 @@ export default function App() {
723745 </ div >
724746 ) }
725747
748+ { /* ── Vault load failed (connected but state unreadable) ── */ }
749+ { lucid && ! vault && (
750+ < SectionCard
751+ title = { t ( 'vault.loadFailedTitle' ) }
752+ eyebrow = { t ( 'vault.eyebrow' ) }
753+ iconPath = { ICON . alert }
754+ accent = "amber"
755+ >
756+ < p className = "text-xs sm:text-sm text-slate-400 leading-relaxed" >
757+ { t ( 'vault.loadFailedBody' ) }
758+ </ p >
759+ < button
760+ onClick = { handleRefresh }
761+ disabled = { busy }
762+ className = "btn-shine w-full bg-gradient-to-r from-amber-500 to-cyan-500 hover:from-amber-400 hover:to-cyan-400 active:scale-[0.99] disabled:from-slate-600 disabled:to-slate-600 disabled:cursor-not-allowed text-slate-950 font-bold py-3 rounded-xl transition-all"
763+ >
764+ { busy ? t ( 'wd.btnBusy' ) : t ( 'vault.retry' ) }
765+ </ button >
766+ </ SectionCard >
767+ ) }
768+
726769 { /* ── Vault State ── */ }
727770 { lucid && vault && (
728771 < SectionCard
772+ id = "vault-section"
729773 title = { t ( 'vault.title' ) }
730774 eyebrow = { t ( 'vault.eyebrow' ) }
731775 iconPath = { ICON . vault }
@@ -783,10 +827,12 @@ export default function App() {
783827 < InfoRow
784828 label = { t ( 'vault.lastCompound' ) }
785829 value = { fmtTime ( vault . lastCompoundTime , t ( 'vault.never' ) ) }
830+ breakAll = { false }
786831 />
787832 < InfoRow
788833 label = { t ( 'vault.lastRealloc' ) }
789834 value = { fmtTime ( vault . lastReallocTime , t ( 'vault.never' ) ) }
835+ breakAll = { false }
790836 />
791837 </ DataPanel >
792838
@@ -945,6 +991,7 @@ export default function App() {
945991 < InfoRow
946992 label = { t ( 'sunset.lastActivity' ) }
947993 value = { fmtTime ( sunset . lastActivityMs , t ( 'vault.never' ) ) }
994+ breakAll = { false }
948995 />
949996 < InfoRow
950997 label = { t ( 'sunset.daysSince' ) }
0 commit comments