diff --git a/apps/sim/app/(landing)/comparison/components/comparison-table/comparison-table.tsx b/apps/sim/app/(landing)/comparison/components/comparison-table/comparison-table.tsx index 70a21ae4e24..2b13db94836 100644 --- a/apps/sim/app/(landing)/comparison/components/comparison-table/comparison-table.tsx +++ b/apps/sim/app/(landing)/comparison/components/comparison-table/comparison-table.tsx @@ -10,6 +10,39 @@ export interface ComparisonTableProps { competitor: CompetitorProfile } +/** + * Pins the row-label column during horizontal scroll on genuinely spacious + * viewports (the standard pattern for responsive data tables, e.g. + * Stripe/GitHub/Notion comparison tables) so a reader keeps row context while + * scrolling to see the Sim/competitor values. Below `lg` (this page's own + * tablet-and-below tier, per `.claude/rules` for this route group) the table + * switches to a stacked layout instead (see `MOBILE_STACK_*`) rather than + * relying on horizontal scroll at a width too narrow to render a 3-column + * table comfortably, so sticky positioning is scoped to `lg:` only. The + * shadow is a permanent CSS-only affordance (no scroll-position JS) so this + * stays a zero-hydration server component. + */ +const STICKY_LABEL_COL = 'lg:sticky lg:left-0 lg:z-10 lg:shadow-[2px_0_4px_-2px_rgba(0,0,0,0.08)]' + +/** + * Below `lg` (1024px) a 3-column grid doesn't reliably have room to be + * legible, so each fact instead stacks as label -> Sim's value -> the + * competitor's value, with a small name tag on each value since the column + * headers are no longer directly above. Applied to the label cell. + */ +const MOBILE_STACK_LABEL = 'max-lg:border-r-0 max-lg:border-b-0 max-lg:pt-3 max-lg:pb-1' + +/** + * Applied to a value cell (Sim's or the competitor's) in the stacked mobile + * layout. `items-stretch` overrides the cell's base `items-center` (which + * would otherwise shrink-wrap and center each child horizontally in a + * flex-col): stretching gives the name tag and the value their own + * full-width box to left-align and truncate within, instead of a + * content-sized box with no boundary to clip against. + */ +const MOBILE_STACK_VALUE = + 'max-lg:flex-col max-lg:items-stretch max-lg:gap-0.5 max-lg:border-r-0 max-lg:px-4' + function ColumnHeader({ name, iconTile, @@ -22,12 +55,14 @@ function ColumnHeader({ return (
{iconTile} - {name} + + {name} +
) } @@ -49,15 +84,21 @@ export function ComparisonTable({ sim, competitor }: ComparisonTableProps) {
- Compare - + + Compare + + {sim.name} vs {competitor.name}
@@ -89,6 +130,8 @@ export function ComparisonTable({ sim, competitor }: ComparisonTableProps) { role='columnheader' className={cn( 'border-[var(--border)] border-r bg-[var(--surface-1)] px-4 py-2', + STICKY_LABEL_COL, + 'max-lg:border-r-0', sectionIdx > 0 && 'border-[var(--border-1)] border-t' )} > @@ -99,7 +142,7 @@ export function ComparisonTable({ sim, competitor }: ComparisonTableProps) {
0 && 'border-[var(--border-1)] border-t' )} /> @@ -115,28 +158,42 @@ export function ComparisonTable({ sim, competitor }: ComparisonTableProps) {
- {row.label} + + {row.label} +
+ + {sim.name} +
+ + {competitor.name} +
diff --git a/apps/sim/app/(landing)/comparison/components/source-info/source-info.tsx b/apps/sim/app/(landing)/comparison/components/source-info/source-info.tsx index fba0e4debd8..200d1c35aaf 100644 --- a/apps/sim/app/(landing)/comparison/components/source-info/source-info.tsx +++ b/apps/sim/app/(landing)/comparison/components/source-info/source-info.tsx @@ -1,7 +1,7 @@ 'use client' import type { ReactNode } from 'react' -import { Tooltip } from '@sim/emcn' +import { cn, Tooltip } from '@sim/emcn' import type { FactSource } from '@/lib/compare/data' export interface SourceLinkProps { @@ -29,7 +29,7 @@ export function SourceLink({ source, children, className }: SourceLinkProps) { target='_blank' rel='noopener noreferrer' aria-label={`${source.label} (opens source)`} - className={className} + className={cn('block min-w-0', className)} > {children} diff --git a/apps/sim/components/icons.tsx b/apps/sim/components/icons.tsx index 9505f29ee94..ea1eeea8a10 100644 --- a/apps/sim/components/icons.tsx +++ b/apps/sim/components/icons.tsx @@ -1565,8 +1565,8 @@ export function LangChainIcon(props: SVGProps) { return ( )