// Quill Keyboard — reusable iPhone mockup with the in-keyboard AI toolbar.
// Props: w (screen width px), kind 'ai'|'standard', popup bool, draft text, label.
const KB_ROWS_EN = [
'q w e r t y u i o p'.split(' '),
'a s d f g h j k l'.split(' '),
'z x c v b n m'.split(' '),
];
// the action chips shown on the AI bar (subset of the library)
const BAR_ACTIONS = ['Summarize', 'Fix grammar', 'Make formal', 'Shorten', 'Translate', 'Explain'];
const BAR_TABS = [
{ name: 'Quick', icon: 'sparkles' },
{ name: 'Writing', icon: 'pen-line' },
{ name: 'Translate', icon: 'languages' },
{ name: 'Clipboard', icon: 'clipboard' },
];
function StatusBar({ dark }) {
const c = dark ? '#fff' : '#1D1D1F';
return (
9:41
);
}
function Bubble({ side, children, tint }) {
const me = side === 'me';
return (
{children}
);
}
// the floating result popup ("lives where the text is")
function ResultPopup({ bottom = 330 }) {
return (
SummarizeClaude Sonnet
Following up on the proposal — checking the timing still works for your team.
);
}
function MessagesApp({ draft, kind }) {
return (
{/* nav bar */}
Alice
{/* thread */}
Hey! Are we still on for the proposal recap?yes — putting the follow-up together nowAmazing, thank you 🙏of courseHow did the call with their team go?really well actuallythey liked the phased rollout idealove thatNo rush at all. We just need the timing confirmed for the team before Friday.totally, makes senseDid you ever send that recap over?almost donesending in a sec
{/* compose bar */}
{draft}|
);
}
function AppHeader({ title, right = 'Done' }) {
return (