Findit Design System (Astro)
Reusable tokens and components for every page of the Findit template. The published Framer template is the reference
for look and behavior; component names follow the Framer components, and every component has the same name, props and
classes as in the Next.js version (../nextjs), so both render the same DOM. Import components by path
(../../design-system/components/cards/PropertyCard.astro); pages map content to props in src/lib/to-ui.ts. Every
component is shown on /style-guide.
Tokens
Section titled “Tokens”| File | Holds |
|---|---|
theme.css |
Colours (ink, body, grey, surface, cultured, star, danger), breakpoints md 810 / lg 1200, the ticker animation |
tokens/text.ts |
Text styles: display, h1–h6, bigParagraph, paragraph, smallParagraph, menu, button, label, smallButton, tiny |
tokens/motion.ts |
springSoft (bounce 0, 0.4 s), springButton (bounce 0.2, 0.4 s), reveal (height), transitions (names for data-transition) |
Framer’s translucent colours are opacity modifiers: Black 50/10/05/03 → ink/50, ink/10, ink/5, ink/3;
White 80/10 → white/80, white/10. Font: Manrope (Astro Fonts API, --font-manrope).
Components
Section titled “Components”| Group | Component | Framer |
|---|---|---|
| actions | Button (primary, secondary, white, shadow) |
Button/Primary |
| actions | TabButton (button or link) |
Button/Tab |
| brand | Logo |
Misc/Logo |
| cards | PropertyCard (complete, simple), Chip |
Card/Property |
| cards | CityCard, PostCard, AgentCard, TeamCard, TestimonialCard |
Card/City, Post, Agent, Team, Testimonials |
| cards | BenefitItem, HighlightChip, ProcessStep, FactList (dark, light) |
Card/Benefit, Misc/Icon Text, Card/Step, Fact Number |
| forms | Form, FormField / FieldControl, RadioGroup, SubmitButton, NewsletterForm |
Form |
| icons | Icon (Phosphor paths in paths.ts) |
Phosphor |
| layout | Section, SectionLabel, SectionTitle (split, center, stack), Divider |
Title Section, Misc/Label |
| media | HeroVideo, YouTubeEmbed, FillImage |
Card/Hero Video, YouTube |
| data | DetailList, ContactList |
Property details / utility list, Contact |
| navigation | Navigation (row, stack), Hamburger, Breadcrumbs |
Button/Menu, Button/Hamburger, Breadcrumbs |
| patterns | Ticker, Carousel, Timeline, AccordionItem, PropertyFilter, RichText |
Ticker, Carousel, Card/Timeline, Card/Accordions, Misc/Property Nav, Rich text |
| text | InlineText (**bold**, [links](/path), line breaks from content) |
— |
| utils | CurrentYear |
— |
Conventions
Section titled “Conventions”- Hover = data attributes. Mark the hoverable element
data-hover; every element that changes on hover getsdata-motion(motionStates(rest, hover)fromutils/motion.ts) and, unless it uses the default spring (springButton),data-transition="soft". Write the rest state inline (style="transform: scale(1.05)") so the page looks right before the script runs.scripts/hover.tsanimates them; touch devices and reduced motion are respected. - State = a script per component. Interactive components (
AccordionItem,Carousel,PropertyFilter,HeroVideo,YouTubeEmbed, forms, the header menu) hold a<script>that calls aninit…()function fromscripts/. Scripts find their elements bydata-*attributes and skip ones already set up. - Slots render once. A component that shows its slot twice (the button label flip, the ticker’s second copy) renders
it to a string with
Astro.slots.render("default")first.TickerandCarouseltake their items as<li>elements. - Hidden panels use the
hiddenattribute on elements without adisplayclass, and inlinedisplay: noneon the rest (a Tailwindflexwould overridehidden). - Text that Framer puts in its own element (a chip label, a stat, a button label) gets its own
<span>here too, so the layout check (tools/qa/layout-diff) measures the same boxes; borders Framer draws inside an element use anafter:border, neverborder. - Images: content refers to
/images/<file>;FillImagefinds the file insrc/assets/imagesand serves resized WebP.