The design decisions behind the 2026 pages, the home and contact sales. Everything here is built from the live classes and tokens: if something looks wrong on this page, it is wrong on the site too.
The rules every page follows. When a new case comes up, it gets solved inside these, not around them.
Client-First class names, Webflow Variables and Designer controls. Custom code only for what the Designer cannot express (:has, :checked, autofill, keyframes), kept in the page head and commented.
Vertical rhythm is padding on the section, never margin between sections. Inside a section, space is a flex or grid gap, never margin-bottom. Every text class resets its top and bottom margin to 0, or Webflow's default heading and paragraph margins leak in.
px only for borders and shadows, which are decoration. rem for type, padding and gaps, so they grow with the reader's font size. ch for reading measure (max-width-text is 60ch). Letter-spacing in em, so tracking scales with the type.
Sizes are set per breakpoint in the Designer (desktop, tablet, mobile), never with clamp(). What you see in a breakpoint is exactly what ships.
Text classes own font, size and colour. Alignment and width come from the container: the same heading-style-h1 is centred on the home (inside section-header.is-center) and left-aligned on contact sales.
Every rule is near-black, never grey; grey rules read as missing. border/subtle is only for panel edges.
A page-specific tweak becomes a combo class, so the shared class stays untouched everywhere else. Name the combo after what it does (is-line, is-full, is-tight), and rename it when that changes.
No pinned stages, scroll-snap or wheel steppers. Motion only styles content that scrolls normally; native CSS sticky is allowed because the reader still drives it.
Semantic tokens in the folk 2026 collection. Most alias the legacy default collection, so each hex value lives in one place. The ui/* tokens are for the product mockups only and never style the page.
Three families, one scale. The class must match the heading level: heading-style-h1 only on the page's single H1, heading-style-h2 on every section title, h3 on feature titles.
Inter, body text, fields, buttons, product UI
A lead paragraph, used sparingly when a section needs one more step of emphasis.
Body copy. Black, never muted or secondary. Pair it with max-width-text (60ch) for anything longer than a line.
Secondary detail: roles under a testimonial name, card descriptions.
Two layers. A unit-free numeric scale, and six semantic names that point at it. Classes bind to the semantic name so the Designer reads by intent; the numbers are the escape hatch. No t-shirt sizes, no px names.
Every section is the same four layers: section_name › padding-section › padding-global › container-large. Sections then reorder freely, with no margin maths.
container-large 90rem (1440px), so 1440 to 1728 laptops keep a side margin. container-medium 64rem, container-small 48rem. Media bands sit inside the container, not full-bleed; only the hero band bleeds past it.
1.5rem on each side at every breakpoint.
Top and bottom padding of every section. .is-hero sets 3rem on top so the product shot shows on landing.
Title and intro of a section. .is-tight closes the gap to the content, .is-center centres everything inside it (home hero).
Measured on the Figma: the 5-up cards and the 6-up logo row do not fit a 12-column grid. What is constant is the measure and the 1.5rem gutter, so rows are equal fractions. Two-column heroes use their own grid (contact-hero: 1fr 1fr, 6rem gap, stacked on tablet).
Desktop from 992px (with 1440 and 1920 above it), tablet up to 991px, mobile landscape up to 767px, mobile portrait up to 479px. Type and spacing change at tablet and mobile.
The rows on this page are the system's own hairline: 1px, border/hairline, with gutter padding.
How a section starts: a rule across the container, then its title. Used on every home section after the hero, and on the contact sales hero.
The rule alone, when the content sets its own spacing (footer CTA).
Lists are separated by a top hairline on each row, never by gaps alone.
Sharp corners everywhere: cards, panels, fields, logo tiles. The one exception is the primary CTA, a full pill (999px radius).
Panel strokes use outline (all four longhands) so they take no layout space and paint above children. Anything one-sided, like a row rule or an underline, uses border.
Every demo form is wired to the site-wide qualification script. Style it freely; keep the wiring below exactly as it is.
Wrapper .signup-form_wrap, form with data-folk-demo="contact", one input[type=email], one .js-select whose values are 1-2, 3-9, 10-49, 50-249, 250-999, 1000+. The script looks up the company on email blur, then routes qualified 10+ to /demo-calendly, qualified 3–9 to /book-a-folk-demo-2, everyone else to the unqualified redirect.
Email, team size and button in one bordered row, 0.875rem, 3rem tall.
Contact sales. No box, no background, 1.25rem text, a 1px black underline, 4rem tall. The placeholder is the title (no labels; each field carries an aria-label). Placeholder and unpicked select in text/secondary. No focus underline: the caret is the cue, and the select shows a 2px line on keyboard focus only.
Black pill, full width, 1rem, 3.5rem tall.
Fields tight (0.5rem), button and note stack (1rem), block (2rem) between the two groups.
A native select over option tiles: tiles needed a bridge script to reach the qualification script, the select needs none. The page head paints over Chrome's blue autofill and keeps the field font on suggested values.
Entrances are attributes, not interactions. Elements rise and fade in turn; no blur, and nothing waits on the reader's scroll position beyond entering the screen.
On a section or a grid. load plays with the page (heroes), view when the group enters the screen, scroll item by item as they enter. data-reveal-at="60%" delays it until the top reaches that height.
up: fade and rise 1rem. lines: a title revealed line by line. fade: opacity only, used for hairline containers so the rule appears with its section.
One attribute instead of three for the usual patterns.
Above-the-fold titles use the CSS-only reveal, so they count as painted straight away (LCP). Never put a JS fade on a container that holds the H1.
With reduced motion, without JavaScript, or in the Designer, everything is simply visible. The engine is reveal.js in the site footer; home-only modes live in reveal-extra.js.
Shared sections live as Webflow components, so a change in one place updates every page that uses them.
Editing either changes every page. The Footer's Base variant includes the CTA form. Never rename .nav-items-wrapper, .nav-item-wrapper, .logo-context-menu or .sub-nav-item: scripts and CSS target them.
The home's logo wall and testimonial rows, reused on contact sales.
The inline demo form, already wired to the qualification script.
Illustrations are coded Webflow elements, not images: sharp at any DPI, interactive, animatable. They use their own ui- classes and tokens and never borrow the page's spacing.