We migrated to x.com·visit our pages
SLF · Agent operating guide

Read this before you change anything.

This guide does not document the class system — you can query that. It documents what the tooling will get wrong, what it reports incorrectly, and how to verify that a change actually landed. Every failure below has cost real time on this site.

Scope: SLF is the internal framework behind stacklumen.com and iainfeeney.com. Brand colours and the display scale are exclusive to it. Never carry SLF classes, tokens or values into client work — that is what SAF is for.

01 · Verify before you believe

Three rules. They prevent most of what follows.

Read the class off the element, never from a style querySilent
WrongQuery styles for hero-title, find a plausible name, edit it. Nothing changes on the page.
RightQuery the element, read its styleNames, edit that class. Pages carry parallel families — hw-hero-title and sl-hw-h1 both exist; only one is live.

Cost: two wasted edit rounds on /how-we-work before anyone noticed the edited class wasn't attached to anything.

The Designer canvas is the honest view for layoutVerify

The Designer does not run page embeds, site custom code or registered scripts. So an overflow that production hides with runtime overflow-x: hidden is visible there and only there. “It only looks wrong in the Designer” usually means a real bug that production is papering over.

The inverse is also true: a page style embed is invisible in the Designer but wins on the published page. Native styling looks correct while the live site renders something else.

A tool result is not proof the change landedSilent

Some writes report success and do nothing. Some report failure and succeeded. Re-read the thing you changed before reporting it done.

02 · This will lie to you

Ranked by what they have actually cost. Silent means it reports success and does nothing. Throws means it fails loudly and may take a good batch down with it. Verify means the result is real but misleading. Limit means the platform simply cannot do it.

Page embeds shadow native classesVerify

App-ported pages carry one style embed. Its rules sit in the body, load after the site stylesheet, and beat native classes at equal specificity. Descendant selectors inside it beat them outright.

SymptomYou set a heading to 112px. The Designer shows 112px. The published page renders 80px.
FixBefore changing a class on a ported page, read the page's embed and delete any rule that duplicates the class. Keep only what Webflow cannot express.
query_styles property filtering is substring on name and valueVerify
WrongFilter on color, treat the matches as “classes with blue text”. It also matched background-color, border-top-color and outline-color.
RightRe-read each match and confirm which property actually held the value before writing.

Cost: fifteen filled badges turned blue-on-blue — invisible label text shipped across several pages.

Same-name global and combo classesVerify

A global .pp-btn-primary and a combo .pp-btn.pp-btn-primary can both exist. The style tool always resolves the name to the combo, so the global is unreachable and quietly retains stale values.

Timeouts and conflicts usually mean the write succeededThrows

“MPS did not acknowledge” and “[Conflict] could not be applied” both commonly follow a write that landed. Query first. A blind retry produces the real error.

set_text on a builder-made TextBlock does nothingSilent
FixQuery children one level down and set text on the String node instead. Then sweep for leftover placeholder copy — it is invisible in tool results and only shows on the page.
Properties that reject the whole batchThrows

Vendor-prefixed properties and shorthand padding bound to a variable fail the entire call, taking every sibling action with them. Isolate anything experimental into its own action.

Variables cannot hold fluid typeLimit

Size variables reject clamp(). Colours, spacing, radii and widths tokenise; the display scale stays literal in the class and is governed by this guide.

100vw is wider than the viewportVerify

It includes the scrollbar. On a fixed element that already has left and right set, the width declaration is redundant and causes horizontal overflow. Use width auto, max-width none, and remove min-width — min-width beats max-width, so leaving it defeats the fix.

03 · Native or embed?

Default to native. An embed is justified only when the selector cannot be expressed as a Webflow class. If you cannot name the specific property or selector that blocks you, it does not qualify.

Genuinely impossible — embed is correct
@keyframes definitions · :has() · :target · :last-of-type · vendor pseudo-elements like ::-webkit-scrollbar · any descendant or child selector · runtime state classes such as .w--open · CSS custom property definitions
The exception nobody expectsLimit

CSS for elements that JavaScript creates at runtime cannot be migrated. Those elements never exist in the Designer, so no class can attach to them. The navbar embeds are legitimately unmigratable for exactly this reason — do not try.

Not impossible — style natively instead
Colours, spacing, radius, type, layout, grid, flex · hover and focus (use the pseudo argument) · breakpoint overrides (use the breakpoint argument) · active and current states (use a combo class)

04 · The SLF scale

Weight is 600 on every heading — never 400 or 500. Tracking tightens as size grows. Inherited Relume classes shipped with no letter-spacing and line-height 1.2; that untracked setting is what reads as weak, and it is not a weight problem.

page hero clamp(48px, 7.5vw, 112px) lh .96 ls -.038em big statement clamp(44px, 6.4vw, 92px) lh 1 ls -.038em CTA title clamp(40px, 6vw, 84px) lh 1 ls -.036em section title clamp(36px, 5.2vw, 68px) lh 1.02 ls -.034em sub-section clamp(30px, 3.9vw, 50px) lh 1.1 ls -.03em card title clamp(20px, 2vw, 26px) lh 1.2 ls -.02em lede clamp(17px, 1.7vw, 21px) lh 1.6 ls -.005em

Font stack is Inter first, always. Body copy renders Inter, so any class with Helvetica first renders a visibly different face on the same page. Brand blue is #0075ff — ported pages contain #0065ff and #0066f5; both are wrong.

Reference pages like this one deliberately cap at the section tier, not the hero tier. A 112px headline competing with technical content is a mistake.

05 · Scope and permission

Proceed without asking
Conforming type to the scale · binding literals to existing tokens · correcting off-brand colour · adding missing focus states · fixing overflow and responsive defects
Stop and ask first
Deleting classes that elements still reference · restructuring sections or page layout · rewriting an embed you have not read in full · anything touching CMS bindings · publishing
NeverExclusive

SLF classes, tokens, brand colours and the display scale are exclusive to Stacklumen products. They do not go into client work, templates or the public clonable. Client projects use SAF; the free clonable uses generic values only.

Publishing ships the entire site, never one page. Review native styling in the Designer; publish in batches only when verifying embed or script behaviour.

06 · Framework routing

The class prefix tells you which framework you are in, and therefore which rules apply. Get this wrong and you leak proprietary styling into client or public work.

slf- SLF internal stacklumen.com, iainfeeney.com brand colours exclusive saf- SAF client agency engagements confidential under MSA sdf- SDF templates sold and licensed field-of-use limited sdfc- SDFC public the free clonable generic values only

Marketing pages also carry a per-page prefix for their own components. These are page-scoped, not framework-scoped, and are safe to edit within their page.

dq- documentation hw- / sl-hw- how we work cr- copyright pr- web pricing sm- system wu- where we're going sl-mi- mission sl-v- verticals sl-rd- roadmap rm- ai pd- products pp- portfolio ec- ecosystem up- upgrades ad- advertising tl- toolumen cl- changelog bl- baselumen prg- programs fw- form hookups aig- ai guide se- security sl-lg- legal sl-tm- terms
Parallel families existVerify

Some pages carry two complete families side by side — an orphaned older set and the live one. /how-we-work has both hw- and sl-hw-, and only sl-hw- is attached to elements. Always confirm against the element before editing.

07 · Page anatomy

Every new page on stacklumen.com gets the same chrome, in this order. These component IDs cannot be derived — use them directly.

Site Banner 19d9e0d2-e9bf-fa80-efe5-8508595b5aa1 Native Navbar 585b545c-dcc3-0b3e-e605-184633321eba … page sections … Site Footer 3042403b-43eb-d944-dcb5-316657041a9f OG image asset 6a5a5b75ea33a36564594b8d

Section shell is slf-sec wrapping slf-in. One section per parent div — never stack multiple sections inside a shared wrapper. Build repeated chrome as components, not copies.

Creating a pageVerify

Create the page, read the Body element at depth 0 for its ID, then append into that. Set SEO title, description and the OG asset at creation — retrofitting them is easy to forget. Draft pages stay out of publishes, which makes them the safe place to prototype.

Elements inside a component definitionThrows

Pass scope_component_id or the lookup fails with “Element not found”. This applies to the banner, navbar and footer — anything inside the chrome.

08 · Design options — surface & depth

Pick one per section. Do not stack them — a hero gets atmosphere or a flat surface, never both.

Hero gradient — fades to white under the navbarPreferred

Colour gathers downward and the top is pure white, so the translucent navbar blends with no seam. Layer order matters — the white scrim is painted first, on top.

background-color: #ffffff; background-image: linear-gradient(180deg, #fff 0%, rgba(255,255,255,.86) 18%, rgba(255,255,255,0) 42%), radial-gradient(1200px 560px at 68% 104%, rgba(0,117,255,.20), rgba(0,117,255,0) 66%), radial-gradient(940px 480px at 10% 98%, rgba(59,158,255,.15), rgba(59,158,255,0) 64%), linear-gradient(180deg, rgba(148,163,184,0) 40%, rgba(148,163,184,.10) 100%);
Why it worksBlooms are anchored below 96% vertical, so only their upper falloff shows. Anchoring them above the top edge produces the opposite effect and fights the navbar.
Animated bloom fieldEmbed only

Absolutely-positioned blurred circles with drifting keyframes, masked to an ellipse. Requires @keyframes so it lives in an embed. Use for landing heroes only — never on reference or legal pages.

Elevation
card resting 0 1px 2px rgba(15,23,42,.04), 0 18px 40px -24px rgba(15,23,42,.18) control 0 1px 2px rgba(15,23,42,.08) brand glow inset 0 1px 0 rgba(255,255,255,.22), 0 6px 18px rgba(0,117,255,.28)

Brand glow is SLF-exclusive. Client and clonable work uses neutral shadows only.

09 · Design options — type treatments

Gradient-clipped headlineSLF only
background-image: linear-gradient(135deg,#0a0a0a 0%,#0a0a0a 45%,#0075ff 85%,#3b9eff 100%); color: transparent; background-clip: text; -webkit-text-fill-color: transparent; padding-bottom: .08em; /* stops descenders clipping */
WatchWithout the padding-bottom, descenders on g, y and p get cut. Never apply to text that may sit on a dark surface — the ink stop disappears.
Accent span inside a headline

A solid brand-coloured span for the second clause. Cheaper than a gradient and safe anywhere. This is the “Build with Stacklumen” pattern.

Eyebrow
11px · 600 · uppercase · letter-spacing .14em · Brand or Text Muted optional 6px dot or 14px rule before, via ::before

Uppercase plus tracking is how a label reads as a label. Never switch to a mono face for that effect — Inter, Helvetica and Arial only.

10 · Design options — components

Button, with combo variants
base inline-flex · 13px 22px · radius 2px · 15px/500 · gap 8px is-secondary white bg · Line border · Ink text is-ghost transparent · reduced horizontal padding is-sm / is-lg 9px 15px / 17px 30px focus-visible 2px solid Ink, offset 2px

Variants are always combo classes on the base, never separate globals. A same-named global and combo can both exist and the tool only reaches the combo — that is how values drift.

Status pill
3px 9px · 10px/600 · uppercase · tracking .08em · radius 999px · 1px border tint = colour at 6% · border = colour at 40%
Callout
grid auto 1fr · gap 16px · padding 14px 18px border 1px Line · border-left 2px Brand · background Surface Alt

The 2px left border carries the meaning. Swap only that colour for success or warning — keep every other edge neutral.

Specimen panel

A bordered card of key/value rows that renders the system's own tokens. Use in a hero when the page's subject is the system. It doubles as documentation and cannot drift, because it shows the real values.

card 1px Line · radius 14px · Surface · resting elevation head 13px 18px · Surface Alt · 10.5px/600 uppercase · tracking .1em row flex space-between · 13px 18px · border-bottom 1px
Status dot
6px · radius 50% · Brand · box-shadow 0 0 12px rgba(0,117,255,.6)

Composite values cannot bind to a token, so the glow stays literal. Update it by hand when brand colour changes.

11 · Design options — layout & responsive

Shells
marketing section slf-sec › slf-in · Shell Max 1240px reference document grid 240px 1fr · gap 64px · sticky TOC + 74ch column split hero grid 1.05fr .95fr · gap 56px · align center reading measure 70ch body · 74ch container

Reference pages cap headings at the section tier, never the hero tier. Long technical prose at full container width is unreadable — constrain the measure.

The 992–1279 dead zoneConvention

Webflow's base breakpoint covers 992px upward, so there is no way to target small desktops directly. Invert the usual instinct:

RightMake base compact and use the large breakpoint (≥ 1280px) to restore generous spacing. Base then serves 992–1279 correctly.
WrongDesign base for a wide desktop and hope 1043px copes. It does not — flex children compress and labels collide.
Flex children that must shrink
min-width: 0 /* without this a flex child cannot shrink below content */ white-space: nowrap /* on labels that must never break mid-word */ flex-shrink: 0 /* on icons, dots, badges */
Breakpoints
xxl ≥ 1920 · xl ≥ 1440 · large ≥ 1280 · base ≥ 992 medium ≤ 991 · small ≤ 767 · tiny ≤ 479

Larger breakpoints are min-width, smaller are max-width and cascade downward. There is no 1024px breakpoint — media queries written against one in an embed will not align with anything native.

06 · Framework routing07 · Page anatomy08 · Surface & depth09 · Type treatments10 · Components11 · Layout & responsive