b027e4bdb1
**i18n** — collapsed the ~22 scattered i18n files into a single module and turned on Spanish alongside French. **Sections** — dropped the old compound pattern (`Section.Root`, `Section.Heading`, …). Reusable layout shells moved to `src/templates/`, atomic bits stay in `design-system/`, and each page now owns its copy in local `_components` blocks instead of pulling it out of shared sections. Data files hold arrays only, no prose. **Copy → `<Trans>`** — A lot of headings were split across several `<HeadingPart>`s just for font styling, which meant each piece was a separate translation string. A translator got "Build your Enterprise CRM" and "at AI Speed" as two unrelated strings and had no way to reorder them for their language. Those are now single `<Trans>` units with placeholders. Same idea for the old `\n` + `white-space: pre-line` line-break trick: replaced with a small `ResponsiveLineBreak` element so the break is doesn't quietly rot, and did a dead-code pass. The de-fragmentation changes the message IDs, so around 60 strings will fall back to English in fr/es until Crowdin re-syncs.
57 lines
1.3 KiB
TypeScript
57 lines
1.3 KiB
TypeScript
import { Body } from '@/design-system/components/Body';
|
|
import { getServerI18n } from '@/lib/i18n/server';
|
|
import { theme } from '@/theme';
|
|
import { styled } from '@linaria/react';
|
|
import React from 'react';
|
|
|
|
import type { ProblemPointType } from './problem-point-type';
|
|
|
|
const StyledPoints = styled.div`
|
|
display: grid;
|
|
grid-template-columns: 1fr;
|
|
row-gap: ${theme.spacing(6)};
|
|
|
|
@media (min-width: ${theme.breakpoints.md}px) {
|
|
max-width: 454px;
|
|
}
|
|
`;
|
|
|
|
const StyledDivider = styled.div`
|
|
height: 0;
|
|
border-top: 0.75px dashed ${theme.colors.primary.border[80]};
|
|
width: 100%;
|
|
opacity: 50%;
|
|
`;
|
|
|
|
const StyledPoint = styled.div`
|
|
display: grid;
|
|
grid-template-columns: 1fr;
|
|
row-gap: ${theme.spacing(2)};
|
|
|
|
@media (min-width: ${theme.breakpoints.md}px) {
|
|
max-width: 380px;
|
|
width: 100%;
|
|
}
|
|
`;
|
|
|
|
type PointsProps = {
|
|
points: ProblemPointType[];
|
|
};
|
|
|
|
export function Points({ points }: PointsProps) {
|
|
const i18n = getServerI18n();
|
|
return (
|
|
<StyledPoints>
|
|
{points.map((point, index) => (
|
|
<React.Fragment key={index}>
|
|
<StyledDivider />
|
|
<StyledPoint>
|
|
{point.heading}
|
|
<Body size="sm">{i18n._(point.body)}</Body>
|
|
</StyledPoint>
|
|
</React.Fragment>
|
|
))}
|
|
</StyledPoints>
|
|
);
|
|
}
|