feat(marketing): 3-card options comparator replaces table#21
Conversation
The old Tailark comparator-7 rendered a 3-column feature table with
tooltip-gated descriptions. It was the only table on a page of
cards \u2014 the visual language mismatched the rest of the narrative
scroll (hero \u2192 bento cards \u2192 how-it-works \u2192 feature cards \u2192 pricing
cards \u2192 FAQ). Reader's eye hit the tabular row and snagged.
Rewritten as a 3-col OptionCard grid. Each card:
- option name (small label)
- headline metric (tabular-nums large number)
- time-to-site subtitle
- short paragraph explaining the option
- 3 signal bullets (Check/X icon in rounded pill, emerald for
positive, muted for negative)
- cost footer with border-t separator
Helpbase card is emphasized:
- heavier shadow, opaque bg-card (the other two are bg-card/40)
- 'Recommended' badge top-right
- all positive signals
No tooltips required \u2014 the signal text is short enough to read inline,
and more detail is available in the other sections below.
Behavior preserved: same 3-way comparison (roll your own / hosted SaaS
/ helpbase), same 'to first site' metric, same cost ladder. Just
rendered as cards that sit naturally next to the pricing section.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (20)
📝 WalkthroughWalkthroughReplaced the comparator’s feature-by-plan table with a new options-driven 3-card layout; updated hero/container and several illustration/preview components; adjusted button variant interactions; removed multiple UI primitives from templates/registry and added Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
The hero's content wrapper carried 'corner-t-notch rounded-t-[2rem]
border-x border-t' \u2014 a Tailark hero-section/six poster frame at
max-w-6xl that wrapped the headline + sub + CTAs + terminal.
Three reasons it had to go:
1. The frame's bottom edge floated orphan in the viewport when you
scrolled past it. The frame ended at the hero's bottom with
nothing visually continuing it below \u2014 a horizontal line that
pointed at empty space.
2. The page already has section frames where they pay rent
(how-it-works grid, demo cross-link card, faqs sidebar+accordion).
Each of those frames groups a content cluster. The hero frame
wrapped one large content block but didn't group anything that
wasn't already visually unified by typography and the terminal.
3. The 6xl frame width didn't align with anything below \u2014 every
other framed section sits at 5xl. Two different widths, two
different visual languages on one page.
Mintlify, Stripe, and Anthropic don't frame their heroes. The hero
is the hero because of the headline, the terminal, and the install
command \u2014 not because of a border.
Three classes removed (corner-t-notch, rounded-t-[2rem], border-x,
border-t) plus the corner-t-notch decoration. Hero typography and
content untouched.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
apps/web/components/comparator-7.tsx (1)
157-166: Pin the cost footer to the bottom of each card.The card is already
flex flex-col; usingmt-autokeeps cost footers aligned when body copy wraps differently.📐 Proposed refinement
- <div className="border-border/60 mt-6 flex items-baseline gap-1 border-t pt-4"> + <div className="border-border/60 mt-auto flex items-baseline gap-1 border-t pt-4">🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/components/comparator-7.tsx` around lines 157 - 166, The cost/footer div containing option.cost should be pinned to the bottom of each flex-column card by adding the utility that pushes it to the end of the column; update the div with className "border-border/60 mt-6 flex items-baseline gap-1 border-t pt-4" (the footer that renders {option.cost} and {option.costNote}) to include "mt-auto" (e.g., "mt-auto mt-6 ...") so the cost footer aligns across cards when body content wraps.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/web/components/comparator-7.tsx`:
- Around line 126-151: The signal icons are currently decorative only; inside
the option.signals.map rendering add accessible state text and mark the SVG
icons as decorative: set the Check and X components to aria-hidden="true" and
add a visually-hidden span (e.g., className "sr-only") next to each icon that
outputs the semantic state based on signal.positive (for example "Positive" vs
"Tradeoff"/"Negative") so screen readers receive the meaning while visual users
keep the same UI; update the spans wrapping the icons and the icon components
accordingly.
- Around line 95-98: Replace the invalid Tailwind opacity token
"shadow-black/6.5" inside the emphasized class string (the ternary using
option.emphasized) with a valid Tailwind opacity—either a nearest standard step
like "shadow-black/5" or an arbitrary value using bracket notation such as
"shadow-black/[0.065]"; update the class array element in the comparator-7
component where option.emphasized controls the string so the resulting class
list uses a valid Tailwind opacity token.
---
Nitpick comments:
In `@apps/web/components/comparator-7.tsx`:
- Around line 157-166: The cost/footer div containing option.cost should be
pinned to the bottom of each flex-column card by adding the utility that pushes
it to the end of the column; update the div with className "border-border/60
mt-6 flex items-baseline gap-1 border-t pt-4" (the footer that renders
{option.cost} and {option.costNote}) to include "mt-auto" (e.g., "mt-auto mt-6
...") so the cost footer aligns across cards when body content wraps.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 27063bdf-d240-43c3-b5fb-201088344ad0
📒 Files selected for processing (2)
apps/web/components/comparator-7.tsxapps/web/components/marketing/hero.tsx
| "ring-border relative flex flex-col rounded-2xl border border-transparent p-6 ring-1", | ||
| option.emphasized | ||
| ? "bg-card shadow-black/6.5 z-10 shadow-xl" | ||
| : "bg-card/40", |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Find and read tailwind config and package.json to understand Tailwind version and opacity settings
find . -type f \( -name "tailwind.config.*" -o -name "package.json" \) -not -path "*/node_modules/*" | head -20Repository: Codehagen/Helpbase
Length of output: 384
🏁 Script executed:
# Check the specific file mentioned in the review
cat -n apps/web/components/comparator-7.tsx | sed -n '90,105p'Repository: Codehagen/Helpbase
Length of output: 808
🏁 Script executed:
# Search for other instances of shadow opacity syntax in the codebase
rg "shadow-.*/([\d\.]+)" --no-heading -A 1 -B 1 | head -40Repository: Codehagen/Helpbase
Length of output: 15361
🏁 Script executed:
# Check Tailwind configuration for custom opacity tokens
find . -type f -name "tailwind.config.*" -not -path "*/node_modules/*" | head -5Repository: Codehagen/Helpbase
Length of output: 44
🏁 Script executed:
# Read the main tailwind config
cat tailwind.config.ts 2>/dev/null || cat tailwind.config.js 2>/dev/null || cat tailwind.config.mjs 2>/dev/null || echo "No tailwind config found at root"Repository: Codehagen/Helpbase
Length of output: 94
🏁 Script executed:
# Check package.json for Tailwind version
grep -A 2 "tailwindcss" ./package.jsonRepository: Codehagen/Helpbase
Length of output: 157
🏁 Script executed:
# Check if opacity 6.5 is used elsewhere in the codebase
rg "/(6\.5|0\.065)" --no-heading -B 2 -A 2Repository: Codehagen/Helpbase
Length of output: 14166
🏁 Script executed:
# Search more carefully for Tailwind config files (might be in nested packages)
find . -type f \( -name "tailwind.config.*" -o -name "tailwind.css" \) -not -path "*/node_modules/*" -not -path "*/.next/*" 2>/dev/nullRepository: Codehagen/Helpbase
Length of output: 44
🏁 Script executed:
# Check package.json files for tailwind config references or versions
grep -r "tailwindcss" */package.json --include="package.json" | grep -v node_modules | head -20Repository: Codehagen/Helpbase
Length of output: 109
🏁 Script executed:
# Look for CSS files that might define custom opacity or theme extensions
find . -type f -name "*.css" -not -path "*/node_modules/*" | xargs grep -l "opacity\|theme\|6\.5" 2>/dev/null | head -10Repository: Codehagen/Helpbase
Length of output: 202
🏁 Script executed:
# Search more broadly for tailwind configuration in the entire repository
find . -type f \( -name "*.ts" -o -name "*.js" -o -name "*.mjs" \) -not -path "*/node_modules/*" -not -path "*/.next/*" | xargs grep -l "tailwind.*config\|theme.*opacity" 2>/dev/null | head -10Repository: Codehagen/Helpbase
Length of output: 44
🏁 Script executed:
# Check one of the CSS files to understand the theme setup
cat ./packages/ui/src/styles/globals.cssRepository: Codehagen/Helpbase
Length of output: 12037
🏁 Script executed:
# Search for any custom theme or opacity configuration in TS/JS files
rg "opacity.*[6\.5|0\.065]|@layer|theme\s*:" -A 5 -B 2 --type ts --type js | head -60Repository: Codehagen/Helpbase
Length of output: 4902
🏁 Script executed:
# Check if there's any custom opacity configuration in the CSS variables or extended theme
rg "opacity|--opacity" packages/ui/src/styles/globals.css apps/web/styles/ 2>/dev/null || echo "No opacity in theme"Repository: Codehagen/Helpbase
Length of output: 795
🏁 Script executed:
# Check Tailwind documentation to understand the version being used
grep -r "tailwindcss\|@tailwindcss" package.json apps/web/package.json 2>/dev/null | head -5Repository: Codehagen/Helpbase
Length of output: 296
🏁 Script executed:
# Check for postcss config
find . -type f \( -name "postcss.config.*" -o -name ".postcssrc*" \) -not -path "*/node_modules/*"Repository: Codehagen/Helpbase
Length of output: 180
🏁 Script executed:
# Check the apps/web package.json for any theme or tailwind-specific config
cat apps/web/package.json | grep -A 50 "tailwind\|theme" || head -100 apps/web/package.jsonRepository: Codehagen/Helpbase
Length of output: 1133
🏁 Script executed:
# Search for any extend theme or opacity configuration in the app
rg "extend.*theme|opacity.*scale" apps/web --type ts --type js | head -20Repository: Codehagen/Helpbase
Length of output: 316
🏁 Script executed:
# Check the postcss config
cat apps/web/postcss.config.mjsRepository: Codehagen/Helpbase
Length of output: 117
🏁 Script executed:
# Search for any CSS custom properties or theme extensions related to opacity
rg "6\.5|0\.065" apps/web/ packages/ui/src/styles/ -B 3 -A 3 --type css --type ts | head -100Repository: Codehagen/Helpbase
Length of output: 8015
🏁 Script executed:
# Check if Tailwind v4 docs mention how /6.5 is handled
# Let's test by looking at what the actual build might generate
find apps/web -type f -name "*.tsx" -o -name "*.css" | xargs grep -l "shadow-black/6.5" | wc -lRepository: Codehagen/Helpbase
Length of output: 64
🏁 Script executed:
# Check the workspace UI postcss config to see if there's any custom opacity definition
cat packages/ui/postcss.config.mjsRepository: Codehagen/Helpbase
Length of output: 202
🏁 Script executed:
# Verify the actual Tailwind v4 syntax by checking their documentation patterns
# Let's also count how many build-time warnings might be generated
rg "shadow-" apps/web/components/*.tsx | grep -c "shadow-black"Repository: Codehagen/Helpbase
Length of output: 63
🏁 Script executed:
# Check the `@theme` block in globals.css for any opacity configuration
cat packages/ui/src/styles/globals.css | grep -A 100 "@theme inline" | grep -i opacityRepository: Codehagen/Helpbase
Length of output: 44
🏁 Script executed:
# Check if there's any Tailwind config that might extend opacity values in Tailwind v4
# Also look for any extend or custom theme configuration
find . -type f \( -name "*.ts" -o -name "*.js" -o -name "*.css" \) -not -path "*/node_modules/*" | xargs grep -l "opacity.*6\.5\|extend.*opacity" 2>/dev/null | head -10Repository: Codehagen/Helpbase
Length of output: 44
🏁 Script executed:
# Let's verify what the standard Tailwind v4 opacity scale is by checking if 6.5 converts to decimal correctly
# 6.5 would be 6.5% opacity = 0.065 in decimal (or as a ratio 6.5/100)
python3 << 'EOF'
# Standard Tailwind opacity scale: 5, 10, 15, ... 95
# In percentages and decimal equivalents
standard_scale = [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]
print("Standard Tailwind opacity scale:")
for val in standard_scale:
print(f" /{val} = {val/100}")
print("\nFor 6.5:")
print(f" /6.5 would be {6.5/100} (not in standard scale)")
print(f" /[0.065] would be 0.065 (6.5%)")
EOFRepository: Codehagen/Helpbase
Length of output: 420
Use valid Tailwind opacity syntax for the emphasized shadow.
shadow-black/6.5 is not a standard Tailwind opacity value. Tailwind's opacity scale includes 5, 10, 15... 95 (increments of 5). Arbitrary opacity values must use bracket notation.
🎨 Proposed fix
- ? "bg-card shadow-black/6.5 z-10 shadow-xl"
+ ? "bg-card z-10 shadow-xl shadow-black/[0.065]"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "ring-border relative flex flex-col rounded-2xl border border-transparent p-6 ring-1", | |
| option.emphasized | |
| ? "bg-card shadow-black/6.5 z-10 shadow-xl" | |
| : "bg-card/40", | |
| "ring-border relative flex flex-col rounded-2xl border border-transparent p-6 ring-1", | |
| option.emphasized | |
| ? "bg-card z-10 shadow-xl shadow-black/[0.065]" | |
| : "bg-card/40", |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/web/components/comparator-7.tsx` around lines 95 - 98, Replace the
invalid Tailwind opacity token "shadow-black/6.5" inside the emphasized class
string (the ternary using option.emphasized) with a valid Tailwind
opacity—either a nearest standard step like "shadow-black/5" or an arbitrary
value using bracket notation such as "shadow-black/[0.065]"; update the class
array element in the comparator-7 component where option.emphasized controls the
string so the resulting class list uses a valid Tailwind opacity token.
| {option.signals.map((signal, i) => ( | ||
| <li | ||
| key={i} | ||
| className="flex items-start gap-2"> | ||
| {signal.positive ? ( | ||
| <span className="bg-emerald-500/15 text-emerald-600 dark:text-emerald-400 mt-px flex size-4 shrink-0 items-center justify-center rounded-full"> | ||
| <Check | ||
| className="size-2.5" | ||
| strokeWidth={3} | ||
| /> | ||
| </span> | ||
| ) : ( | ||
| <span className="bg-foreground/10 text-muted-foreground mt-px flex size-4 shrink-0 items-center justify-center rounded-full"> | ||
| <X | ||
| className="size-2.5" | ||
| strokeWidth={3} | ||
| /> | ||
| </span> | ||
| )} | ||
| <span | ||
| className={cn( | ||
| signal.positive | ||
| ? "text-foreground" | ||
| : "text-muted-foreground", | ||
| )}> | ||
| {signal.text} |
There was a problem hiding this comment.
Expose the check/X meaning to assistive tech.
The positive/tradeoff state is currently visual-only. Add hidden text for the state and mark decorative icons as hidden.
♿ Proposed fix
{signal.positive ? (
<span className="bg-emerald-500/15 text-emerald-600 dark:text-emerald-400 mt-px flex size-4 shrink-0 items-center justify-center rounded-full">
<Check
+ aria-hidden="true"
className="size-2.5"
strokeWidth={3}
/>
</span>
) : (
<span className="bg-foreground/10 text-muted-foreground mt-px flex size-4 shrink-0 items-center justify-center rounded-full">
<X
+ aria-hidden="true"
className="size-2.5"
strokeWidth={3}
/>
</span>
)}
<span
className={cn(
signal.positive
? "text-foreground"
: "text-muted-foreground",
)}>
+ <span className="sr-only">
+ {signal.positive ? "Advantage: " : "Tradeoff: "}
+ </span>
{signal.text}
</span>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/web/components/comparator-7.tsx` around lines 126 - 151, The signal
icons are currently decorative only; inside the option.signals.map rendering add
accessible state text and mark the SVG icons as decorative: set the Check and X
components to aria-hidden="true" and add a visually-hidden span (e.g., className
"sr-only") next to each icon that outputs the semantic state based on
signal.positive (for example "Positive" vs "Tradeoff"/"Negative") so screen
readers receive the meaning while visual users keep the same UI; update the
spans wrapping the icons and the icon components accordingly.
…review to source+rendered
Two improvements in the 'Every file is yours' row.
FlowIllustration hub:
The center node was the Tailark logomark (LogoIcon \u2014 a purple/teal
gradient geometric shape that ships with their illustration kit).
That's their brand bleeding through ours. Replaced with a clean white
'h' letterform on the dark circle, matching the helpbase wordmark in
the header. Bumped the circle bg from black/75 to black/85 so the
letterform reads cleanly in light mode. Removed the LogoIcon import.
MdxSourcePreview:
Was source-only \u2014 a single panel of fake .mdx code. The card's copy
promises 'Import React components, version control every change, diff
in PR review' but the visual didn't show the moment that matters most:
MDX source rendering as actual docs.
Rebuilt as a stacked card:
- Header tab: filename + 'SOURCE' label
- Source panel: syntax-highlighted MDX (violet frontmatter keys,
amber numbers, emerald strings, sky-blue JSX tags) \u2014 a real-feeling
code block, not flat mono text
- Divider
- Rendered panel: 'RENDERED' label, then the h1 styled as a real
heading, body text, and the <Callout type="tip"> shown as an
actual amber-tinted callout box with a lucide Lightbulb icon
This makes the abstract claim concrete: MDX is code AND it's docs.
The visual literally shows the transformation the platform performs.
Both files are in components/illustrations/ which is in
HOSTED_TIER_EXCLUDES \u2014 no template drift.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The marketing page button (used by header CTAs, hero 'See live demo',
pricing tier CTAs, and demo cross-link CTAs) had only transition-colors
\u2014 hover worked but clicks had zero visual feedback. The shared
packages/ui button had active:translate-y-px so CopyButton already
felt right, but everything else didn't.
Applied Emil Kowalski's micro-interaction blueprint from animations.dev:
- Transition widened from colors-only to
transition-[color,background-color,transform,box-shadow]
so transform and shadow can animate together.
- duration-150 ease-out \u2014 micro-interaction range (100\u2013150ms),
ease-out for the element entering its pressed state.
- active:scale-[0.98] \u2014 2% squeeze on press. Buttons are h-9/h-10,
3% would read as cartoonish; 2% feels like a tap, not a gimmick.
- active:shadow-sm (default, destructive) / active:shadow-xs (outline)
\u2014 shadow reduces on press, mimicking a physical button being
depressed. Subtle but readable.
- motion-reduce:transition-none motion-reduce:active:scale-100
\u2014 respects prefers-reduced-motion, disables animation for users
who've opted out.
- Removed the stray duration-200 override on outline (now inherits
the base duration-150 for consistency across variants).
Tailwind v4's hover: modifier already guards against mobile tap-flicker
via @media (hover: hover), so no extra work needed there.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/web/components/illustrations/flow.tsx`:
- Around line 186-190: The "h" glyph span uses class text-background which can
render too dark against the dark-mode badge (dark:bg-illustration/75); update
the span's dark-mode foreground to ensure legibility by adding a dark-specific
text class (for example dark:text-foreground or dark:text-white) to the span
containing the "h" so it forces a light color in dark mode while leaving
light-mode styling unchanged.
In `@apps/web/components/illustrations/mdx-source-preview.tsx`:
- Line 23: Visible heading text uses lowercase brand casing "Install helpbase";
update the UI copy to use proper product casing "Install Helpbase" where the
span with className "text-foreground" renders that heading in the
mdx-source-preview component (also update the other occurrences of the same
literal in this file). Replace only the displayed text (not package/CLI
literals) so the component's visible headings read "Install Helpbase".
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: c636d5be-2199-4dd6-9fd3-e772f5493f02
📒 Files selected for processing (3)
apps/web/components/illustrations/flow.tsxapps/web/components/illustrations/mdx-source-preview.tsxapps/web/components/ui/button.tsx
| <div className="dark:bg-illustration/75 dark:ring-border-illustration relative flex size-14 items-center justify-center rounded-full bg-black/85 shadow-xl shadow-black/20 ring-1 ring-black backdrop-blur"> | ||
| <span className="text-background text-lg font-semibold leading-none tracking-tight"> | ||
| h | ||
| </span> | ||
| </div> |
There was a problem hiding this comment.
Verify dark-mode contrast of the "h" glyph.
The badge background switches to dark:bg-illustration/75 in dark mode while the glyph keeps text-background. Since --background is typically dark in dark themes and --illustration also tends to be a dark/neutral surface, the "h" may render dark-on-dark and become barely visible. In light mode it's fine (white h on bg-black/85). Consider forcing a light foreground in dark mode (e.g. dark:text-foreground or a fixed dark:text-white) so the wordmark stays legible on both themes.
The whole illustration is aria-hidden, so this is purely visual, not an a11y blocker.
🎨 Suggested tweak
- <span className="text-background text-lg font-semibold leading-none tracking-tight">
+ <span className="text-background dark:text-foreground text-lg font-semibold leading-none tracking-tight">
h
</span>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/web/components/illustrations/flow.tsx` around lines 186 - 190, The "h"
glyph span uses class text-background which can render too dark against the
dark-mode badge (dark:bg-illustration/75); update the span's dark-mode
foreground to ensure legibility by adding a dark-specific text class (for
example dark:text-foreground or dark:text-white) to the span containing the "h"
so it forces a light color in dark mode while leaving light-mode styling
unchanged.
| <span className="text-muted-foreground">title:</span>{" "} | ||
| <span className="text-foreground">Getting started</span> | ||
| <span className="text-violet-600 dark:text-violet-400">title:</span>{" "} | ||
| <span className="text-foreground">Install helpbase</span> |
There was a problem hiding this comment.
Use the product casing in visible heading copy.
Install helpbase reads like a brand-casing typo in title/heading contexts. Consider Install Helpbase here while keeping any literal package/CLI names lowercase if needed.
✏️ Proposed copy adjustment
- <span className="text-foreground">Install helpbase</span>
+ <span className="text-foreground">Install Helpbase</span>
...
- <span className="text-foreground"># Install helpbase</span>
+ <span className="text-foreground"># Install Helpbase</span>
...
- Install helpbase
+ Install HelpbaseAlso applies to: 32-32, 56-56
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/web/components/illustrations/mdx-source-preview.tsx` at line 23, Visible
heading text uses lowercase brand casing "Install helpbase"; update the UI copy
to use proper product casing "Install Helpbase" where the span with className
"text-foreground" renders that heading in the mdx-source-preview component (also
update the other occurrences of the same literal in this file). Replace only the
displayed text (not package/CLI literals) so the component's visible headings
read "Install Helpbase".
PR #20 added components/footer.tsx with an import of @/components/ui/button, but apps/web's button.tsx is in HOSTED_TIER_EXCLUDES because it carries marketing-only press feedback styling. The synced footer landed in the scaffold templates and registry without a Button to resolve, breaking both smoke:install and smoke:registry on Turbopack with 'Module not found: @/components/ui/button'. CI has been red on main since fb004ed; this fix restores green. Three coordinated changes: 1. inlineShadcnPrimitivesToTemplates now inlines BOTH Badge and Button from packages/ui/src/components/ into templates/components/ui/. Button uses the umbrella radix-ui import (Slot.Root pattern), works cleanly with @workspace import rewrites. 2. registry.json adds 'button' to registryDependencies and '@radix-ui/react-slot' to dependencies, so consumers running 'shadcn add helpbase' get Button auto-installed from the official shadcn registry and the slot primitive resolves for any other shadcn primitive that needs it. 3. Templates package.json now ships @radix-ui/react-slot directly. The umbrella radix-ui package re-exports it under Slot.Root with a different API, so primitives that import { Slot } from '@radix-ui/react-slot' need the individual package. Plus: deleted 7 dead UI primitives from templates AND registry that were copied from apps/web by the default sync rule. None of them were used by anything in the scaffold path: - card.tsx, chart.tsx, infinite-slider.tsx, input.tsx, label.tsx, text-scramble.tsx, tooltip.tsx Their only consumers in apps/web were components in HOSTED_TIER_EXCLUDES (pricing, bento, chart-illustration). Shipping them as dead code dragged in recharts, motion/react, and other marketing-only deps the scaffold doesn't need. Added all 7 to HOSTED_TIER_EXCLUDES so future syncs don't recreate them. Scaffold consumers can shadcn-add card / tooltip / etc. on demand. Locally verified: - pnpm smoke:install passes (templates path) - pnpm smoke:registry passes (shadcn add path) - pnpm registry:build regenerates public/r/*.json clean Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
comparator-7with a 3-card options block that matches the page's card languageWhy
The old table was the only tabular element on a page of cards. Eye snagged on it during scroll. The new layout reads naturally adjacent to the pricing section and keeps the exact same 3-way comparison message (roll your own / hosted SaaS / helpbase).
Test plan
🤖 Generated with Claude Code
Summary by CodeRabbit
Style
New Features