DNYUZ
No Result
View All Result
DNYUZ
No Result
View All Result
DNYUZ
Home News

She had a baby, tried AI coding, and built the nutrition app she actually wanted

May 28, 2026
in News
She had a baby, tried AI coding, and built the nutrition app she actually wanted
Lisa Lin
Jacob Kepler for BI

Lisa Lin had long worked alongside coders. When she had her son, she tried it for herself.

The 33-year-old has worked in operations roles at a variety of tech companies, including Uber. But she was “non-technical,” as her industry would call it; she couldn’t code.

Then came the AI revolution, and her baby. Lin moved from a full-time operations role to a contractor while taking on the new job of stay-at-home mom.

She’d heard horror stories about those early months, but has been pleasantly surprised. “He’s a happy baby,” she said.

When her baby was about 5 months old, she began testing out nutritional apps to introduce solid foods and identify allergens. She tried a popular nutrition app but found it overwhelming. “Day to day, it’s a lot of information to digest,” she said.

AI Conversation Embed — Annotated

{
“platform”: “generic”,
“caption”: “Lin’s conversation with Lovable about designing the nutrition app’s home page.”,
“credit”: “Conversation edited for length.”,
“messages”: [
{ “role”: “user”, “text”: “Update the Today screen for the Baby Nutrition App (MVP) with the following mobile-first, dynamic layout and interactions. Align all styles and fonts with the onboarding flow.\n\nStyle Guidelines (consistent with onboarding):\n • Background: linear gradient (#A8CBB7 at 14%, #FFF9F2 at 69%)\n • Text: black (#000000)\n • Borders: transparent\n\nLayout:\n • Header:\n ◦ Display baby’s name + age (calculated from birthday)\n • Weekly Progress Ring:\n ◦ Show progress for 7 days (Monday → Sunday)\n ◦ Ring style: deep teal (#2F6B5F)\n ◦ Each day checked/filled if daily goal achieved\n • Bottom Navigation:\n ◦ Tabs: Today / Recipes / Insights / Profile\n ◦ Highlight Today tab\n ◦ Maintain touch-friendly spacing\n\nInteractions & Notes:\n • Logging food updates weekly progress ring instantly\n • Floating \”+\” button opens log modal” },
{ “role”: “assistant”, “text”: “I’ll update the Today screen with the complete mobile-first layout including weekly progress ring, food cards, nutrient tracking, recipes, and bottom navigation.\n\nUpdated Today screen with weekly progress ring, dynamic food cards, nutrient tracking, recipe carousel, bottom navigation, and floating + button — all styled with the onboarding gradient and mobile-first layout.”, “note”: “A structured, concise and specific prompt helps the tool understand your needs better and sets boundaries so it doesn’t go out of control or use its own imagination to create something you don’t need or want.\n\nThis also helps keep the cost down — instead of having back-and-forth conversations, one structured prompt spends fewer tokens.” }
]
}

:root {
–bg: #f7f7f8;
–frame: #ffffff;
–border: #e5e5ea;
–text: #1a1a1a;
–muted: #8e8e93;
–user-bubble: #e9e9eb;
–assistant-bubble: #ffffff;
–brand: #1a1a1a;
–accent: #d97757;
}
* { box-sizing: border-box; }
html, body {
margin: 0;
padding: 0;
background: #ffffff;
font-family: -apple-system, BlinkMacSystemFont, “Segoe UI”, Roboto, Helvetica, Arial, sans-serif;
color: var(–text);
-webkit-font-smoothing: antialiased;
}

/* — Two-column layout — */
.embed-outer {
max-width: 780px;
margin: 16px auto;
padding: 0 12px;
}
.two-col {
display: flex;
gap: 0;
align-items: stretch;
}
.chat-col {
flex: 0 0 380px;
max-width: 380px;
min-width: 0;
}
.notes-col {
flex: 1;
min-width: 160px;
padding: 0 0 0 20px;
display: flex;
flex-direction: column;
justify-content: center;
gap: 16px;
}

/* — Chat frame (same as standard embed) — */
.frame {
background: var(–frame);
border: 1px solid var(–border);
border-radius: 18px;
overflow: hidden;
box-shadow: 0 1px 3px rgba(0,0,0,0.04), 0 8px 24px rgba(0,0,0,0.06);
}
.header {
display: flex;
align-items: center;
gap: 10px;
padding: 12px 14px;
background: var(–frame);
color: var(–text);
border-bottom: 1px solid var(–border);
}
.header .logo {
width: 22px; height: 22px;
display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.header .logo svg { width: 100%; height: 100%; display: block; }
.header .name {
font-weight: 600; font-size: 13px; line-height: 1.2;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.messages {
padding: 12px 12px 14px;
background: var(–bg);
display: flex;
flex-direction: column;
gap: 8px;
height: 420px;
overflow-y: auto;
scroll-behavior: smooth;
-webkit-overflow-scrolling: touch;
overscroll-behavior: contain;
}
.messages::-webkit-scrollbar { width: 6px; }
.messages::-webkit-scrollbar-thumb { background: rgba(0,0,0,0.18); border-radius: 3px; }
.messages::-webkit-scrollbar-track { background: transparent; }

/* — Messages — */
.msg-row {
opacity: 0;
transform: translateY(10px);
transition: opacity 0.5s ease, transform 0.5s ease;
}
.msg-row.in { opacity: 1; transform: translateY(0); }
.msg {
display: flex;
max-width: 100%;
}
.msg.user { justify-content: flex-end; }
.msg.assistant { justify-content: flex-start; }
.bubble {
max-width: 84%;
padding: 8px 12px;
border-radius: 16px;
font-size: 13.5px;
line-height: 1.42;
word-wrap: break-word;
white-space: pre-wrap;
position: relative;
}
.bubble .line { display: block; }
.bubble .line-blank { height: 0.5em; }
.bubble .line.bullet-1 { padding-left: 1.1em; text-indent: -1.1em; }
.bubble .line.bullet-2 { padding-left: 2.6em; text-indent: -1.1em; }
.bubble .line.indent-1 { padding-left: 1.1em; }
.msg.user .bubble {
background: var(–user-bubble);
color: var(–text);
border-bottom-right-radius: 6px;
}
.msg.assistant .bubble {
background: var(–assistant-bubble);
color: var(–text);
border: 1px solid var(–border);
border-bottom-left-radius: 6px;
}
.bubble.image-bubble { padding: 6px; overflow: hidden; }
.bubble.image-bubble img { display: block; width: 100%; height: auto; border-radius: 12px; }
.bubble .caption { font-size: 12px; color: var(–muted); padding: 8px 6px 4px; line-height: 1.35; }

/* — Annotation marker (inline, inside the chat bubble row) — */
.note-marker {
display: inline-flex;
align-items: center;
justify-content: center;
width: 18px; height: 18px;
border-radius: 50%;
background: var(–accent);
color: #fff;
font-size: 10px;
font-weight: 700;
flex-shrink: 0;
line-height: 1;
margin-left: 6px;
vertical-align: middle;
cursor: default;
}
.msg.assistant .note-marker { margin-left: 0; margin-right: 6px; }

/* — Annotation notes (sidebar) — */
.note-sidebar {
opacity: 0;
transform: translateY(6px);
transition: opacity 0.3s ease, transform 0.5s ease 0.15s;
font-size: 13px !important;
line-height: 1.3 !important;
font-family: garnett, helvetica, arial, sans-serif !important;
font-weight: 600 !important;
color: #555 !important;
}
.note-sidebar.in { opacity: 1; transform: translateY(0); }
.single-note .note-marker,
.single-note .note-num { display: none; }
.note-num {
display: inline-flex;
align-items: center;
justify-content: center;
width: 18px; height: 18px;
border-radius: 50%;
background: var(–accent);
color: #fff;
font-size: 10px;
font-weight: 700;
line-height: 1;
margin-right: 8px;
flex-shrink: 0;
vertical-align: top;
}
.note-text {
font-size: 13px !important;
line-height: 1.3 !important;
color: #555 !important;
letter-spacing: -0.01em !important;
font-family: garnett, helvetica, arial, sans-serif !important;
font-weight: 600 !important;
}
.note-sidebar .note-text { display: block; margin: 0 !important; padding: 0 !important; white-space: pre-wrap; }
.note-sidebar::before {
content: “\201C”;
display: block;
font-size: 48px;
line-height: 1;
color: var(–accent);
margin-bottom: -12px;
font-family: garnett, helvetica, arial, sans-serif;
}

/* — Inline note (mobile fallback) — */
.note-inline {
display: none !important;
padding: 10px 0;
background: none;
border-radius: 0;
font-size: 13px;
line-height: 1.3;
color: #555;
white-space: pre-wrap;
}
.note-quote {
display: none;
font-family: Georgia, serif;
font-size: 32px;
line-height: 1;
color: var(–accent);
margin-bottom: -6px;
}

/* — Divider — */
.divider {
display: flex; align-items: center; gap: 10px; margin: 6px 2px 2px;
opacity: 0; transform: translateY(10px);
transition: opacity 0.5s ease, transform 0.5s ease;
}
.divider.in { opacity: 1; transform: translateY(0); }
.divider::before, .divider::after { content: ”; flex: 1; height: 1px; background: var(–border); }
.divider span { font-size: 10px; text-transform: uppercase; letter-spacing: 0.08em; color: var(–muted); font-weight: 600; white-space: nowrap; }

/* — Caption + credit — */
.image-source-caption { display: block; margin: 8px 4px 0; }
.image-caption { font-size: 13px; line-height: 1.4; color: #1a1a1a; font-weight: 600; margin: 0; }
.image-source { font-weight: 400; color: #6b6b73; }

/* — Platform themes — */
.platform-chatgpt { –accent: #10a37f; }
.platform-gemini { –accent: #1a73e8; }
.platform-claude { –accent: #d97757; }
.platform-generic { –accent: #395aff; }

/* — Responsive: collapse notes inline on narrow widths — */
@media (max-width: 620px) {
.two-col { flex-direction: column; }
.chat-col { flex: 1 1 auto; max-width: 100%; }
.notes-col { display: none; }
.note-inline {
display: block !important;
max-width: 100%;
margin: 4px 0;
font-family: garnett, helvetica, arial, sans-serif !important;
font-weight: 600 !important;
font-size: 13px !important;
line-height: 1.4 !important;
color: var(–accent) !important;
}
.note-inline .note-num { display: none; }
.note-inline .note-quote { display: none !important; }
.note-marker { display: none; }
}

(function() {
const cfg = JSON.parse(document.getElementById(‘chat-config’).textContent);
const platform = (cfg.platform || ‘chatgpt’).toLowerCase();

const PLATFORMS = {
chatgpt: {
name: ‘ChatGPT’,
logo: ”
},
gemini: {
name: ‘Gemini’,
logo: ”
},
claude: {
name: ‘Claude’,
logo: ”
},
generic: {
name: ‘AI Chat’,
// Simple chat-bubble icon — neutral, no brand
logo: ”
}
};

const p = PLATFORMS[platform] || PLATFORMS.generic;
// Allow config “name” to override the default platform name (e.g. “Lovable”, “Cursor”, “Bolt”)
const displayName = cfg.name || p.name;
const root = document.getElementById(‘root’);
root.classList.add(‘platform-‘ + platform);

// Collect notes for sidebar
let noteNum = 0;
const notes = [];
(cfg.messages || []).forEach((m, i) => {
if (m.note) {
noteNum++;
notes.push({ num: noteNum, text: m.note, msgIndex: i });
m._noteNum = noteNum;
}
});
// When there’s only one annotation, hide numbered badges everywhere
if (notes.length <= 1) root.classList.add('single-note'); const captionHtml = (cfg.caption || cfg.credit) ? `

${cfg.caption ? esc(cfg.caption) + ‘ ‘ : ”}
${cfg.credit ? ‘‘ + esc(cfg.credit) + ‘‘ : ”}

` : ”;

const sidebarHtml = notes.map(n =>
” +
‘‘ + n.num + ‘‘ +
‘

‘ + esc(n.text) + ‘

‘ +
”
).join(”);

root.innerHTML = `

${p.logo}
${esc(displayName)}

${captionHtml}

${sidebarHtml}

`;

const msgsEl = document.getElementById(‘messages’);
(cfg.messages || []).forEach((m, i) => {
if (m.role === ‘divider’) {
const d = document.createElement(‘div’);
d.className=”divider”;
d.style.transitionDelay = (Math.min(i, 6) * 80) + ‘ms’;
d.innerHTML = m.label ? ‘‘ + esc(m.label) + ‘‘ : ”;
msgsEl.appendChild(d);
return;
}

const row = document.createElement(‘div’);
row.className=”msg-row”;
row.style.transitionDelay = (Math.min(i, 6) * 80) + ‘ms’;
row.dataset.index = i;

const msgDiv = document.createElement(‘div’);
msgDiv.className=”msg ” + (m.role === ‘user’ ? ‘user’ : ‘assistant’);

const markerHtml = m._noteNum
? ‘‘ + m._noteNum + ‘‘
: ”;

if (m.image) {
const cap = m.caption ? ” + esc(m.caption) + ” : ”;
if (m.role === ‘user’) {
msgDiv.innerHTML =
” +
‘' + esc(m.alt || '') + '‘ +
cap +
” + markerHtml;
} else {
msgDiv.innerHTML =
markerHtml +
” +
‘' + esc(m.alt || '') + '‘ +
cap +
”;
}
} else {
const bodyHtml = renderText(m.text || ”);
if (m.role === ‘user’) {
msgDiv.innerHTML = ” + bodyHtml + ” + markerHtml;
} else {
msgDiv.innerHTML = markerHtml + ” + bodyHtml + ”;
}
}

row.appendChild(msgDiv);

// Inline note for mobile — placed before the annotated message
if (m.note) {
const inlineNote = document.createElement(‘div’);
inlineNote.className=”note-inline msg-row”;
inlineNote.style.transitionDelay = (Math.min(i, 6) * 80) + ‘ms’;
inlineNote.innerHTML = esc(m.note);
msgsEl.appendChild(inlineNote);
}

msgsEl.appendChild(row);
});

// Animate in
const items = msgsEl.querySelectorAll(‘.msg-row, .divider’);
const sideNotes = document.querySelectorAll(‘.note-sidebar’);
if (‘IntersectionObserver’ in window) {
const io = new IntersectionObserver((entries) => {
entries.forEach(e => {
if (e.isIntersecting) {
e.target.classList.add(‘in’);
// Also reveal matching sidebar note
const idx = e.target.dataset && e.target.dataset.index;
if (idx !== undefined) {
const sn = document.querySelector(‘.note-sidebar[data-for=”‘ + idx + ‘”]’);
if (sn) sn.classList.add(‘in’);
}
io.unobserve(e.target);
}
});
}, { root: msgsEl, threshold: 0.15, rootMargin: ‘0px 0px -20px 0px’ });
items.forEach(el => io.observe(el));
requestAnimationFrame(() => {
const cr = msgsEl.getBoundingClientRect();
items.forEach(el => {
const r = el.getBoundingClientRect();
if (r.top cr.top) {
el.classList.add(‘in’);
const idx = el.dataset && el.dataset.index;
if (idx !== undefined) {
const sn = document.querySelector(‘.note-sidebar[data-for=”‘ + idx + ‘”]’);
if (sn) sn.classList.add(‘in’);
}
io.unobserve(el);
}
});
});
} else {
items.forEach(el => el.classList.add(‘in’));
sideNotes.forEach(el => el.classList.add(‘in’));
}

// Show sidebar notes after a short delay
setTimeout(() => {
document.querySelectorAll(‘.note-sidebar’).forEach(el => el.classList.add(‘in’));
}, 600);

function esc(s) {
return String(s).replace(/[&”‘]/g, c => ({
‘&’:’&’,”:’>’,'”‘:'”‘,”‘”:”’
}[c]));
}

// Render text with hanging indent on bulleted lines
function renderText(s) {
const lines = String(s).split(‘\n’);
return lines.map(line => {
if (line.trim() === ”) {
return ‘ ‘;
}
// Detect leading whitespace and bullet character
const m = line.match(/^(\s*)([•◦●○\-*])\s+(.*)$/);
if (m) {
const ws = m[1].length;
const depth = ws >= 8 ? 2 : 1;
return ‘‘ + esc(m[2] + ‘ ‘ + m[3]) + ‘‘;
}
// Indented non-bullet line
const indentMatch = line.match(/^(\s+)(.*)$/);
if (indentMatch && indentMatch[2]) {
return ‘‘ + esc(indentMatch[2]) + ‘‘;
}
return ‘‘ + esc(line) + ‘‘;
}).join(”);
}
})();

All Lin wanted was an app that would “tell me what I should do today,” she said.

“I’m huge on nutrition,” Lin said. “I want to make sure I’m doing this right because, honestly, my pediatrician didn’t tell me anything. They just handed me a paper.”

So, she got out Lovable, an AI app builder, and started tinkering. She joined the growing class of “vibe coders” who construct apps and sites with little-to-no engineering knowledge. All they need is an AI tool, some good prompts, a vision of what could help make their lives better, and a willingness to experiment.

Lin gathered data on which 50-100 foods to first introduce to your baby. Her information came primarily from the Department of Agriculture’s database, with assistance from ChatGPT and some online articles. She then built a daily checklist with the goal of making sure her baby was eating the right foods at the right time — and named it Nutribabe.

For many vibe coders, the thrill of prompting leads to hours and hours of work. Lin couldn’t do that with a five-month-old; she rarely got an hour uninterrupted.

“I don’t get to sit down at the computer for three hours and vibe code everything,” Lin said. “I don’t have the luxury to do that.”

Lin would often spend thirty minutes with Lovable before returning to her baby when he cried or needed feeding. Her peak hours were in the morning, and it took about one month to build the first iteration.

.vertical-pair__images {
display: flex;/*Remove to avoid stacking on mobile*/
flex-direction: column;
gap: 4px; /*Adjust to change space between the images on mobile*/
}

.vertical-pair__images .figure {
width: 100%;
}

@media (min-width: 768px) {
.vertical-pair__images {
flex-direction: row;/*Remove to avoid stacking on mobile*/
align-items: flex-start;
gap: 8px; /*Adjust to change space between the images on desktop*/
}

.vertical-pair__images .figure {
flex: 1;
min-width: 0;
}

/* OPTIONAL: Make the pair wider than the text column on desktop.
Remove or comment out this block to revert to default width.
Adjust the percentage to control how wide it extends —
margin-left should always be half the extra width to keep it centered.
Examples:
width: 110% → margin-left: -5%
width: 120% → margin-left: -10%
width: 130% → margin-left: -15% */
@media (min-width: 768px) {
.vertical-pair {
width: 150%;
margin-left: -25%;
}
}

}

Lisa Lin

Lisa Lin

Lin wanted a way to manage her baby’s nutrition. “My pediatrician didn’t tell me anything,” she said.

Jacob Kepler for BI

The most challenging task was building the app’s internal infrastructure. Nutribabe includes a recommendation engine based on the baby’s age and preferences.

Having a techie husband helps. Lin met her partner in San Francisco, where she moved after living in China and Singapore. They matched on Coffee Meets Bagel and stayed in San Francisco before moving to Las Vegas.

Her husband is a machine learning engineer. “He’s an expert on everything AI,” Lin said. “Sometimes, I get tips.”

That also helped inform her biggest piece of advice.

“When it comes to building as a non-technical person, the most important thing is getting tips,” Lin said. She could easily vibe code a shoddy app, she said, but wouldn’t know whether there were bugs or security concerns without asking for help from someone in the know.

.vertical-video-wrapper {
display: flex;
justify-content: center;
}

@media (min-width: 768px) {
.vertical-video-wrapper .vertical-video {
width: min(calc(80vh * var(–video-w) / var(–video-h)), 100%);
min-width: 0;
}
}

Your browser does not support the video element.

Lin kept her app’s interface simple so users wouldn’t be overwhelmed by information.

Lisa Lin

Once the app was built, Lin started using it every day.

“I definitely felt more organized,” she said. “I felt more confident and more calm.”

Lin’s next challenge: converting the web app into a mobile platform. She wants to open it to the public, but is planning to get in a bit more user testing first.

“I still want to validate some specific product features with my mom friend,” she said.

Read the original article on Business Insider

The post She had a baby, tried AI coding, and built the nutrition app she actually wanted appeared first on Business Insider.

Walmart’s warehouse club assembled a growing army of fans to help in its race against Costco
News

Walmart’s warehouse club assembled a growing army of fans to help in its race against Costco

by Business Insider
May 28, 2026

The Member's Mark Community helped Sam's Club design these jogger pants. Dominick Reuter/Business InsiderWalmart's warehouse club is taking customer feedback ...

Read more
News

Cotopaxi Allpa 35L Travel Pack Del Día Dark: Sustainable and Chic

May 28, 2026
News

Die Walkure, Gustavo Dudamel and Frank Gehry attempt Wagner history at Disney Hall

May 28, 2026
News

They Gerrymandered His District Away in Three Days. He is Still Running

May 28, 2026
News

Use designated money to cool California schools, not to enrich utilities

May 28, 2026
She had a baby, tried AI coding, and built the nutrition app she actually wanted

She had a baby, tried AI coding, and built the nutrition app she actually wanted

May 28, 2026
Trump’s ‘slush fund’ hits wall as judges hurl fresh fraud claims: WaPo

Trump’s ‘slush fund’ hits wall as judges hurl fresh fraud claims: WaPo

May 28, 2026
Amazon Thinks the Future of Data Centers Depends on a Technical Problem It Just Solved

Amazon Thinks the Future of Data Centers Depends on a Technical Problem It Just Solved

May 28, 2026

DNYUZ © 2026

No Result
View All Result

DNYUZ © 2026