Landing shell
The public page's ground, its frame of cards, its measure and the one way a block arrives. It also declares the landing's locals, which every other landing file reads.
Since Light 2
Synced from the product, 2026-09-30 (P16). The page is a stack of white cards with rounded corners standing on the canvas, with a small inset around them, and every block rises into place the first time it is seen. The full-bleed bands of the old page, and their surface fill as the edge between them, are gone.
The one fluid surface, and its numbers are literals of this page. The app steps between two registered points; this page scales continuously, so most of its sizes are clamp() of the width, and a clamp has no token level to live at. They are declared once, here, as locals on .landing. Colour is never a literal: every shade is a role or a share of one through color-mix, cast in --tone-shade for a shadow (tokens.css, added for this page).
Pinned light. The root carries data-theme="light", so every role resolves to its light value whatever the person chose in Settings. Live below, rendered by the real css inside a .landing pinned to data-theme="light", white in the dark stand too, as node 1.1 is for a person who chose dark in Settings (P16).
Tendd is not a budgeting app. It is a simple, low-pressure way to see and control what you are subscribed to.
Trust and security
Trust is earned, not claimed. Here is exactly what Tendd can and cannot do.
.landingthe ground (--bg-page), the ink, and the locals:--lp-inset,--lp-r2rem,--lp-r-md1.5rem,--lp-gut,--lp-pad-y,--lp-max82.5rem,--lp-nav-h, three curves, the hover time and lift, the glass, two shadows and the fading separator--lp-sep. It clips sideways, because the ghost words and the watermark are wider than the page by design.lp-framethe column of cards,--lp-insetaround and between them;.lp-mainis the same inside it.lp-cardone card: the surface, the large radius, and every child lifted above the world's canvas.lp-wrapthe measure, 82.5rem, centred, with the fluid gutter and the fluid vertical air.lp-rvthe one way a block arrives: it rises 28px and fades in over 900 to 1100ms. Hidden only when the boot script ran AND motion is allowed;.lp-norevealis the boot script's fallback at 3.2s.lp-split .lp-wia split heading's words, rising 80ms apart
Behaviour on width
One registered point, 47.5rem: the inset goes .5rem to .75rem. Under 40rem the bar's height local drops to 56px. Everything else is fluid.
U2 and U3, context. No tab bar on the landing, and no .appbar: the page carries its own header, the landing bar. U11: the one footer in the product is this page's, the site footer.
The one shadow of this system is not the one spent here. Inside the app depth is a ground change and --shadow is its single exception. This page floats cards and icons over paper, and a float is a shadow; the landing's are cast in --tone-shade and never in a colour of their own.
Every class on the page is lp- or is-, because .row, .card, .btn, .total and a dozen other short names are already the app's, styled under .landing as well (P16).
What it was, until 2026-09-26
Synced from the product, 2026-09-30 (P16). This section and every one after it, down to "Where it comes from", describe this component as it stood before Light 2 replaced the public page on 2026-09-26. Its classes then were .lp-wrap at 80rem and .lp-section with its band modifiers .lp-trust, .lp-plan and .lp-final, full-bleed bands on canvas and surface, and a --grid-col-min set for the benefit grid. None of it is a present-tense claim about the product any more; what is true now is Since Light 2 above. It is kept as the record, because a stand amends its history and does not delete it.
It is the landing's answer to what app-shell.css does for a screen, and it could not be that file. The app shell centres one column of blocks a person is working through, at --container-page, with the tab bar or the rail around it. A landing has no navigation to hold, its blocks are arguments a person is deciding between, and it runs full bleed section by section so a band can take its own ground. Two jobs, two files.
The measure is --container-wide, the same value the app uses above its desktop point. That is deliberate rather than convenient: a person who reads this page and then signs up should not feel the page change width under them.
Anatomy, until 2026-09-26
.lp-wrapthe measure, 80rem, centred, with the screen's own side padding: 16px at the narrow end and 40 past the tablet point, which is what the app shell spends there too.lp-section80px of air on a phone, 96 past the tablet point. It is the widest gap in this product, and it is the point: on an app screen the next block is the next thing you do, here it is a different claim.lp-section.lp-trust,.lp-section.lp-planthe two bands that stand on the surface fill instead of the canvas. No border between them: the fill change is the edge, which is the Flat Paper Rule every card in this product already follows.lp-section.lp-finalthe closing block, and the only centred thing on the page. Centring a column of arguments would cost the left edge each one is read from; centring one sentence and one button is what an ending looks like
Behaviour on width
One point, the registered 47.5rem. The measure's padding goes 16 to 40 and the section rhythm 80 to 96. Nothing else changes, and there is no second point: the page is a single column of full-bleed bands at every width, so there is nothing for a second one to switch.
Limits, until 2026-09-26
The grid floor is set here and it is the grid's own axis, not an override. .grid counts columns from --grid-col-min, and the default 10rem is sized for preset tiles in a 588px pane. Inside a 1200px landing measure that floor produced seven tracks for three cards, so the benefit cards sat in the left third with four empty tracks beside them. This file sets --grid-col-min: 20rem on the sections, which is the floor a paragraph of argument needs, and no column count is written anywhere.
Where it comes from
Drawn by design/system/components/landing-shell.css through ../system/index.css, the same entry point a product screen loads, and synced byte for byte from the product on 2026-09-30. It stands on the coloured landing, under every block of it. The grey wireframes/index.html is frozen at the structure before Light 2 and does not carry it: a component that arrived with a founder's decision after the grey closed, like the brand mark before it. Registered in docs/inventory.md and in _nav.js, in the organism group.