Blog
Technical notes on web development, DevOps, and AI integration.
124 articles
- 15:30frontend
The Context Panel Stopped Being a Card: Border Became a Divider
The right context panel dropped its floating-card frame for a single left-border divider, matching the sidebar's design language.
TL;DR: The author changed a right panel from floating card to flush panel by swapping rounded corners and a four-sided border for a single left border. The border's job shifted from frame to divider, not removal. Lesson: when converting a card to a panel, ask what the border should do now.
#css#tailwind#frontend - 15:30frontend
My Navbar's Bottom Border Was There All Along, Only Transparent
The unscrolled navbar looked borderless because border-transparent still renders 1px with an invisible color. One-line fix: border-border/60.
TL;DR: The navbar's "missing" border was actually always rendered with border-transparent, reserving its pixel and preventing layout shift on scroll. The fix was one class swap to border-border/60, letting the existing transition handle everything. Lesson: keep elements present and control their color, not their visibility.
#css#tailwind#frontend - 03:12frontend
My Light-Mode Navbar Uses bg-white/60, Not the Token
Brightening the shared background token shifts the whole page. A navbar needs a solid chrome feel, so a literal color plus the dark variant wins.
TL;DR: Light mode made the navbar look like dirty glass because the shared background token added a grayish cast. The fix swaps in literal bg-white utilities for light mode in both scroll branches while dark mode keeps the token. Trade-off: the navbar won't follow future theme changes, but a dedicated token is a one-line swap later.
#css#tailwind#design - 03:07frontend
I Moved the Chat Mode Toggle to the Top of the Sidebar
Mode chips at the bottom of a sidebar stay invisible until you scroll. Moved to the top, with type and aria-pressed kept intact.
TL;DR: Moving the chat mode switch to the sidebar's top fixed a real usability bug: users only found the search-versus-about toggle after scrolling past the decision point. Core lesson: layout order is decision order, so mode-setting controls belong above scrollable content. The move kept accessibility attributes like aria-pressed and type=button intact, shrinking the form to one responsibility.
#react#accessibility#tailwind - 02:58frontend
My Chat Panel Got Clipped by the Fixed Navbar
A fixed navbar takes no space in the document flow, so a 100dvh chat panel still ran short. The fix pairs xl:mt-14 with a 100dvh subtraction.
TL;DR: A fixed navbar floats above the document flow, so it occupies no space and the panel's top slid underneath it despite having the correct height. The fix pairs xl:mt-14 with xl:h-[calc(100dvh-3.5rem)], since h-dvh only answers how tall, not where content starts. Visually, padding and gaps were dropped for one border divider, creating an edge-to-edge three-column surface.
#css#tailwind#layout - 00:46frontend
Conditional Footer in Next.js: Keep the Client Small
Hiding the footer on a chat route without giving up server rendering, using the composition pattern from the Next.js docs.
TL;DR: Hiding a site footer on a full-height chat page, the author rejected CSS display hacks and demoting the whole layout to a Client Component. Instead, a tiny ConditionalFooter client wrapper uses usePathname to return null on /ai routes while the server-rendered Footer passes through as children. Lesson: keep client conditions in small leaves and slot Server Components in as children.
#nextjs#react#typescript - 00:39frontend
React Duplicate Keys from localStorage: My Two-Layer Fix
Legacy localStorage ids collided in my React chat. Here is the reindex plus seeding fix that silenced the duplicate key error.
TL;DR: A React "duplicate key" warning came from legacy localStorage chat data holding duplicate turn ids, plus a counter effect that read stale values and minted collisions. The fix: reindex every restored turn to 0..n-1 and seed the next id inside the restore effect itself. Lesson: treat persisted data as untrusted and normalize it at the boundary.
#react#localstorage#typescript - 23:40frontend
Aligning Container Gutters With the Navbar Edges
Cards that refuse to line up with the navbar logo come down to gutters: every container moved from px-4 sm:px-6 lg:px-8 to px-3 sm:px-4.
TL;DR: A misaligned card row turned out to be a Tailwind gutter mismatch: the main section used px-4 sm:px-6 lg:px-8 while the navbar used px-3 sm:px-4, leaving a 16-pixel difference at large screens. The fix normalized every max-w-6xl and max-w-7xl container to px-3 sm:px-4, giving one source of truth. Lesson: straight-line misalignment usually means two padding systems assumed identical.
#css#frontend#tailwind - 23:30frontend
This Blog's Header and Footer Stopped Being Pills and Became Bars
Refactoring the navbar and footer from a max-w-6xl pill into full-bleed bars: max-width moves up one level while content stays mx-auto max-w-6xl.
TL;DR: The blog's pill-shaped header and footer became full-bleed bars with semi-transparent backgrounds and backdrop blur. The trick: the outer element spans the whole viewport while inner content stays wrapped in mx-auto max-w-6xl for readability. A permanent border slot that transitions from border-transparent to visible on scroll prevents any layout shift.
#css#frontend#tailwind