Skip to content

No.317 · Forms· New

Segment Counter

A text-message field that shows how the message will really be billed: where it splits into parts, which characters cost double, and which single character (often a curly apostrophe) switched the whole message to the 70-character encoding, with a one-click fix.

The prompt

Copy this text

Automatic copying is unavailable. Copy the selected text using your device’s copy command.

Written for the variant you picked above: Light

Build a text-message composer that explains SMS billing instead of showing a bare '142/160'. Rules: messages use the 7-bit GSM alphabet (160 characters in one part, 153 per part once split) unless any character falls outside it, in which case the whole message becomes UCS-2 (70, or 67 per part, emoji counting two); a few GSM characters (€ [ ] { } ^ ~ \ |) cost two. Parts never split a two-unit character. Surface: a 14px-radius white card in Inter with an uppercase field label. The field is a mono 14px textarea on a soft grey well with 24px lines; behind it a pixel-aligned overlay repeats the text so marks can sit under the real characters: a character that forced UCS-2 gets a red wash and red outline, a double-cost character a mustard underline, and where a new part begins a 2px green bar with a tiny 'Part 2' tag floats above the line. The textarea's own text is transparent with a visible caret, so typing, selection and spellcheck stay native. Below: one bar per part ('Part 1 153/153', filled green in proportion, red-tinted under UCS-2), a status line '2 messages · GSM-7 · 193 characters · 113 left in this part' with an optional cost per recipient, and notes: 'One character (“’”) moved this message to UCS-2, so each part holds 70 characters instead of 160' with a 'Use plain quotes and dashes' button when every culprit has a safe replacement, '€ counts as two characters', and a warning when the message exceeds the allowed number of parts. Selected variant — Light (light): Palette for this theme (Light): --segc-accent #1f6b52; --segc-bad #c2361f; --segc-bad-wash rgb(194 54 31 / 0.16); --segc-bg #ffffff; --segc-dbl #9a6a00; --segc-field #f6f6f3; --segc-ink #1c1d1f; --segc-line rgb(28 29 31 / 0.14); --segc-muted #686b71. Treat these as the root colour tokens, one value per role, and name them to suit your code. Select it with the theme option set to "light". Keep every dimension, spacing value, state and motion from the brief unchanged, and keep text at 4.5:1 contrast or better on these surfaces. This selection takes precedence over references to other themes or options in the general brief. Implement this selected appearance; do not add a variant picker or alternative appearances unless requested. Implementation requirements: Use React and TypeScript. Keep the component self-contained, with uniquely scoped CSS and no animation libraries. Include required imports, styles and font setup in the result. Interaction: Type normally; marks and counts update on every keystroke. The fix button replaces curly quotes, long dashes, ellipses and non-breaking spaces with GSM equivalents. onChange(text, parts) reports each edit. Motion: Part bars fill over 200ms; the field border turns accent on focus over 140ms. Reduced motion removes both. Accessibility: The textarea has a real label and is described by the status line and the notes, so screen-reader users hear the count, the encoding and why it changed. The overlay is aria-hidden; nothing is conveyed by its colours alone. Responsive behavior: The field and part bars fill their container; part bars wrap. Touch: Works with any on-screen keyboard; emoji from the keyboard show the encoding switch immediately. Preserve keyboard access, visible focus and reduced-motion behavior. Keep fictional demo data and simulated service calls in a separate usage example; expose callbacks for real actions and recover from rejected requests. Keep usage-example links inside the demo: use local buttons or prevent navigation. Demonstration links must not navigate to Vitrine routes or open other pages; preserve real URL support in the reusable component itself. Verify the result at narrow and wide viewport sizes, with keyboard input and reduced motion enabled.

Notes

Interaction
Type normally; marks and counts update on every keystroke. The fix button replaces curly quotes, long dashes, ellipses and non-breaking spaces with GSM equivalents. onChange(text, parts) reports each edit.
Motion
Part bars fill over 200ms; the field border turns accent on focus over 140ms. Reduced motion removes both.
Accessibility
The textarea has a real label and is described by the status line and the notes, so screen-reader users hear the count, the encoding and why it changed. The overlay is aria-hidden; nothing is conveyed by its colours alone.
Responsive
The field and part bars fill their container; part bars wrap.
On touch
Works with any on-screen keyboard; emoji from the keyboard show the encoding switch immediately.

Featured

363 components