# Grove — Next.js SaaS Landing Page Template

> For finance and workflow products: a Next.js SaaS landing page template with the whole marketing site, pricing, signup and a customer story. 11 routes.

- Price: $34, one-time
- License: Standard
- Version: 2.8.2
- Category: SaaS landing page
- Editions: React, HTML
- Dark mode: Yes
- Stack: Next.js >=15, React >=19, Tailwind CSS >=4
- Dependencies: `lucide-react`

## What's inside

- 11 pages
- 39 components
- 80 design tokens plus 80 dark overrides

## Pages

| Path | Sections |
| --- | --- |
| `/` | `site-header`, `hero`, `logo-cloud`, `feature-showcase`, `feature-split`, `feature-grid`, `testimonials`, `pricing-table`, `faq`, `cta`, `site-footer` |
| `/pricing` | `site-header`, `page-header`, `pricing-table`, `pricing-comparison`, `faq`, `logo-cloud`, `cta`, `site-footer` |
| `/customers` | `site-header`, `customer-header`, `before-state-ledger`, `walkthrough`, `close-timeline`, `outcome-evidence`, `role-quotes`, `cta`, `site-footer` |
| `/blog` | `site-header`, `page-header`, `blog-index`, `newsletter`, `site-footer` |
| `/demo` | `site-header`, `page-header`, `walkthrough`, `testimonials`, `cta`, `site-footer` |
| `/month-end-guide` | `site-header`, `page-header`, `guide`, `testimonials`, `logo-cloud`, `cta`, `site-footer` |
| `/signup` | `site-header`, `auth-form`, `logo-cloud`, `cta`, `site-footer` |
| `/login` | `site-header`, `auth-form`, `site-footer` |
| `/contact` | `site-header`, `contact-map`, `contact-desk`, `logo-cloud`, `cta`, `site-footer` |
| `/privacy` | `site-header`, `page-header`, `legal-doc`, `cta`, `site-footer` |
| `/components` | `site-header`, `hero`, `logo-cloud`, `feature-showcase`, `feature-split`, `feature-grid`, `testimonials`, `customer-header`, `before-state-ledger`, `close-timeline`, `outcome-evidence`, `role-quotes`, `pricing-table`, `pricing-comparison`, `faq`, `cta`, `newsletter`, `page-header`, `blog-index`, `auth-form`, `walkthrough`, `guide`, `contact-desk`, `contact-map`, `legal-doc`, `site-footer` |

## Components

| Name | What it renders |
| --- | --- |
| `site-header` | Sticky header with wordmark, six nav links and quiet sign-in and start-trial actions (the hero owns the only filled primary); mobile menu is a native &lt;details&gt; disclosure, so no client JavaScript |
| `hero` | Asymmetric-offset hero (A8): editorial headline, lead, one primary action and a subordinate text link in columns 2-7 of twelve, beside a token-built ledger panel that runs off the right frame edge from lg up and returns to the flow below it; the panel's four-cell summary rail is set at 130% of the panel so three cells and their closing hairline fill the frame and the fourth runs off it. The section ground is one radial paper wash. Owns the home page's h1, demotable to h2 via headingLevel for the styleguide |
| `logo-cloud` | Quiet muted band listing customer studios as wordmarks beside a customer count |
| `feature-showcase` | Three numbered how-it-works steps in a hairline grid, followed by a month-end checklist panel |
| `feature-split` | Two mirrored copy-and-panel rows: a bar-chart cash forecast figure and an outstanding-invoices list with status pills |
| `feature-grid` | Six secondary capabilities as a hairline-separated card grid, each card a title, a body and an uppercase plan line, with a section-level link out to pricing |
| `testimonials` | One large lead quote opening on a wide photograph of the studio it describes, with a portrait in the attribution, two supporting quote cards each carrying their speaker's portrait, and a three-up statistics strip |
| `customer-header` | Customer-story opener with a demotable heading, Fieldwork identity, canonical Studio plan, two evaluation links and the existing studio photograph beside rather than behind text, its caption carrying the sample-content boundary; includes a long-identity adversary |
| `before-state-ledger` | Three-row prior-process ledger on the 3rem pitch with customer-reported source language and a missing-source state that removes comparison claims |
| `close-timeline` | Horizontally contained semantic table of six March work sessions, exact active-time arithmetic and terminal sign-off; complete and unresolved states use word, icon and independent status roles |
| `outcome-evidence` | Evidence register separating Fieldwork sample observations from product aggregates, with source, period, definition and a partial-source state that suppresses improvement claims |
| `role-quotes` | Two existing sample voices with portraits, one sample-content caption for the section and a long-role narrow-container adversary; quotes remain separate from measured evidence |
| `pricing-table` | Three plan cards on a shared subgrid, so the audience line, price, call to action, feature label and closing note share horizontal rules across all three regardless of copy length; five differentiating features and an honest 'outgrow it when' note; heading optional via showHeading |
| `pricing-comparison` | Full plan comparison matrix as a semantic table with grouped row headers, screen-reader labels on tick/dash cells and horizontal scroll on small screens |
| `faq` | Sticky heading beside a native &lt;details&gt; accordion; ships a 'general' and a 'billing' question set selected by the variant prop |
| `cta` | Closing call to action on a tinted accent panel washed from the card token at the mark's corner, with two buttons, the close checklist rendered from the fixture as ruled rows with the automatic ones ticked, and a set-up-time definition list |
| `newsletter` | Subscribe block with a labelled email input and submit button, posting to a plain form action, and a designed success state marked by the ledger hedge's seedling figure |
| `page-header` | Editorial page opener with eyebrow, h1, an optional lead and an optional one-line mono meta strip, in a full or compact band; used by the pricing, journal, walkthrough, guide and legal pages, and demotable to h2 via headingLevel for the styleguide |
| `blog-index` | Topic filter pills, one featured article card and a two-up grid of further posts, each with a generated editorial still-life cover statically imported from src/assets; the post and topic hrefs are fixture data for the buyer's CMS |
| `auth-form` | Sign-up and sign-in in one file, selected by the variant prop: an editorial column (trust bullets and a what-happens-next list on signup, status and support on signin) beside a sticky form card with labelled inputs, a visible focus ring and a 3:1 input border; owns its page's h1, demotable to h2 via headingLevel for the styleguide; posts to its own path, no backend |
| `walkthrough` | Four chapters of one sample month at Fieldwork Studio, each pairing a mono timecode and copy with a compact token-built figure; showHeading controls the outline, showClosing lets a composed route supply its own evidence timeline and next step, and surface preserves alternating route grounds |
| `guide` | The long-form template: a sticky contents rail beside one measure of running prose, then the month written out as a full-bleed register whose six dated rows sit at the 3rem pitch on their own ruled ground, closing on a quiet secondary ask |
| `contact-desk` | Three contact routes in a hairline grid with the two people who answer shown as portraits, beside a sticky message form with a subject select, a textarea, client-side validation and a designed success state |
| `contact-map` | Address block and getting-here routes around a full-bleed hand-authored area plan — an inline SVG street sketch drawn entirely in theme tokens, so it needs no tile provider, no API key and no cookie banner and recolours under rebrand; in opening mode it carries the contact page's h1 with the address set into the masthead's second column and the plan directly beneath |
| `legal-doc` | Privacy, cookies and terms as one document: a sticky contents rail beside one measure of prose, broken by a full-bleed register of subprocessors set at the 3rem pitch |
| `site-footer` | Three-column footer navigation, brand block with status line, and a legal bottom bar |
| `ui/button` | Shared primitive: Button and ButtonLink in primary/secondary/ghost variants and sm/md/lg sizes, plus a pending state that disables the control, marks it aria-busy and swaps the label for a report of what is happening — Grove does not spin |
| `ui/badge` | Shared primitives: Badge pill in accent, neutral, solid, information, positive, warning and critical tones plus the Eyebrow uppercase section label |
| `ui/container` | Shared primitive: the single horizontal gutter and max-width rhythm (prose/default/wide) |
| `ui/icons` | Shared primitive: the bespoke GroveMark brand glyph (currentColor, strokeWidth 1.5) — every other icon in the theme is a named lucide-react import |
| `ui/spot` | Shared primitive: Sprout, one ledger row on the theme's 48-unit pitch with a seedling standing on it, the mark of the two success receipts. The hand-drawn LedgerHedge that used to sit beside it was retired in 2.8.x for a figure computed from the close checklist; every other mark in the theme is lucide |
| `ui/article-card` | Shared primitive: article excerpt card with an optional full-bleed cover image (alt required by the type), topic, date, author initials disc and reading time; the featured variant enlarges it and a bleed variant takes the cover edge to edge with only the body returning to the measure; covers carry a token scrim in dark mode so paper photographs do not glow |
| `ui/type` | Shared primitive: the type ladder, the dark-mode weight step, the numeral rules and the motion vocabulary, composed once as class strings so no component hardcodes a size |
| `ui/field` | Shared primitive on tt-ui: the Field shell plus Input, Textarea and Select. One line under the control at a time, in the order error, then success, then description; ids and aria-describedby are derived rather than retyped; the critical edge stays put under hover so invalid and focused are both legible |
| `ui/form` | Shared primitive on tt-ui: the submit flow the three forms share. Grove's own error sentences rather than the browser's, focus to the summary when several fields failed and to the control when one did, the fieldset disabled and aria-busy while a submit is in flight, and noValidate applied from script so the form still validates and still posts with JavaScript off |
| `ui/ground` | Shared primitive: the 3rem ledger row pitch every list, table, checklist and register in the theme locks to — the signature device. It used to also draw a ruled paper ground; 2.2.0 removed the ruling and kept the pitch. |
| `ui/mode-toggle` | Shared primitive: the header's light/dark switch — Sun/Moon, aria-pressed, localStorage, writing the mode class onto the nearest .tt-grove wrapper or the document element |
| `ui/accordion-disclosure` | Shared primitive on tt-ui: the FAQ answer row and the mobile nav panel, two recipes over one native &lt;details&gt;. Escape from inside collapses it and puts focus back on the summary — the one thing the element never gave it — while the answers stay in the page with the script switched off, and the height tween runs on ::details-content |
| `ui/form-error-summary` | Shared primitive on tt-ui: the panel a refused sign-up or enquiry shows. It does not exist until something is wrong, is announced when it appears, counts the failures in a sentence and links each row to the field it names; one failing field never reaches it, because focus goes straight to that control instead |
## Design tokens

| Token | Light | Dark override |
| --- | --- | --- |
| `--background` | `#f5f5f3` | `#111210` |
| `--foreground` | `#20211f` | `#eceeea` |
| `--card` | `#ffffff` | `#191a18` |
| `--card-foreground` | `#20211f` | `#eceeea` |
| `--primary` | `#2d693d` | `#6db27c` |
| `--primary-foreground` | `#ffffff` | `#0f1f12` |
| `--primary-hover` | `#1a582d` | `#7fc48e` |
| `--primary-active` | `#02481d` | `#90d69e` |
| `--secondary` | `#e9eae7` | `#232522` |
| `--secondary-foreground` | `#3f433f` | `#dadcd7` |
| `--muted` | `#efefec` | `#1d1f1c` |
| `--muted-foreground` | `#5d625d` | `#a7ada5` |
| `--accent` | `#fce4c3` | `#2e2314` |
| `--accent-foreground` | `#67491a` | `#e2c08f` |
| `--border` | `#d6d8d4` | `#343733` |
| `--ring` | `#2d693d` | `#6db27c` |
| `--surface-tint` | `#f1f2ef` | `#20221f` |
| `--surface-sunken` | `#e9eae7` | `#0d0e0c` |
| `--surface-raised` | `#ffffff` | `#20221f` |
| `--surface-overlay` | `#ffffff` | `#282a27` |
| `--input-border` | `#747a74` | `#777d75` |
| `--field` | `#ffffff` | `#161815` |
| `--field-border` | `#747a74` | `#777d75` |
| `--control-border` | `#626862` | `#8f958d` |
| `--control-hover` | `#f1f2ef` | `#20221f` |
| `--control-active` | `#e9eae7` | `#282a27` |
| `--selection` | `#e4efe6` | `#1c3021` |
| `--selection-foreground` | `#214f2e` | `#b8e1c0` |
| `--selection-border` | `#5d8d68` | `#5e9069` |
| `--link` | `#2d693d` | `#8bcf99` |
| `--link-hover` | `#1a582d` | `#a5e3b1` |
| `--link-active` | `#02481d` | `#bceec5` |
| `--info` | `#245b86` | `#acd5f1` |
| `--info-soft` | `#e9f2f8` | `#172633` |
| `--info-border` | `#5c89aa` | `#527793` |
| `--positive` | `#26643a` | `#addbb6` |
| `--positive-soft` | `#e8f3ea` | `#19291d` |
| `--positive-border` | `#588c64` | `#537b5c` |
| `--warning` | `#6c4d14` | `#efd49e` |
| `--warning-soft` | `#fbf0dc` | `#2d2516` |
| `--warning-border` | `#9a742b` | `#8d7543` |
| `--critical` | `#8a3030` | `#efb4af` |
| `--critical-soft` | `#f8e9e8` | `#301c1c` |
| `--critical-border` | `#a95b58` | `#9d6762` |
| `--shadow-color` | `rgb(20 22 20 / 0.10)` | `rgb(0 0 0 / 0.55)` |
| `--shadow-raised` | `0 12px 32px rgb(20 22 20 / 0.10)` | `0 14px 36px rgb(0 0 0 / 0.40)` |
| `--shadow-overlay` | `0 18px 48px rgb(20 22 20 / 0.16)` | `0 20px 52px rgb(0 0 0 / 0.55)` |
| `--chart-projected` | `#78977e` | `#55755b` |
| `--radius` | `0.75rem` | `0.75rem` |
| `--radius-sm` | `0.25rem` | `0.25rem` |
| `--font-display` | `var(--font-grove-display), Georgia, "Times New Roman", serif` | `var(--font-grove-display), Georgia, "Times New Roman", serif` |
| `--font-text` | `var(--font-grove-text), ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif` | `var(--font-grove-text), ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif` |
| `--font-sans` | `var(--font-text)` | `var(--font-text)` |
| `--font-mono` | `var(--font-grove-mono), ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace` | `var(--font-grove-mono), ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace` |
| `--text-caption` | `0.75rem` | `0.75rem` |
| `--text-small` | `0.875rem` | `0.875rem` |
| `--text-body` | `1rem` | `1rem` |
| `--text-lead` | `1.125rem` | `1.125rem` |
| `--leading-caption` | `1.4` | `1.4` |
| `--leading-small` | `1.45` | `1.45` |
| `--leading-body` | `1.55` | `1.55` |
| `--leading-lead` | `1.6` | `1.6` |
| `--text-d1` | `1.5rem` | `1.5rem` |
| `--text-d2` | `1.875rem` | `1.875rem` |
| `--text-d3` | `clamp(1.75rem, 1.504rem + 1.0497vw, 2.344rem)` | `clamp(1.75rem, 1.504rem + 1.0497vw, 2.344rem)` |
| `--text-d4` | `clamp(2rem, 1.6146rem + 1.6442vw, 2.93rem)` | `clamp(2rem, 1.6146rem + 1.6442vw, 2.93rem)` |
| `--leading-d1` | `1.25` | `1.25` |
| `--leading-d2` | `1.2` | `1.2` |
| `--leading-d3` | `1.14` | `1.14` |
| `--leading-d4` | `1.08` | `1.08` |
| `--tracking-d4` | `-0.025em` | `-0.025em` |
| `--tracking-d3` | `-0.02em` | `-0.02em` |
| `--tracking-d2` | `-0.01em` | `-0.01em` |
| `--tracking-d1` | `-0.01em` | `-0.01em` |
| `--tracking-body` | `0em` | `0em` |
| `--tracking-eyebrow` | `0.09em` | `0.09em` |
| `--duration-feedback` | `140ms` | `140ms` |
| `--duration-state` | `240ms` | `240ms` |
| `--ease-feedback` | `cubic-bezier(0, 0, 0.2, 1)` | `cubic-bezier(0, 0, 0.2, 1)` |
| `--ease-state` | `cubic-bezier(0.22, 1, 0.36, 1)` | `cubic-bezier(0.22, 1, 0.36, 1)` |
## Use it

- Registry: `bunx shadcn add https://tailthemes.com/r/grove.json`
- MCP: [https://tailthemes.com/api/mcp](https://tailthemes.com/api/mcp)
- Download: [https://tailthemes.com/api/download/grove](https://tailthemes.com/api/download/grove)

## Links

- Product page: [https://tailthemes.com/themes/grove](https://tailthemes.com/themes/grove)
- Live preview: [https://tailthemes.com/preview/grove](https://tailthemes.com/preview/grove)
- Docs: [https://tailthemes.com/docs/grove](https://tailthemes.com/docs/grove)
- Manifest JSON: [https://tailthemes.com/api/themes/grove](https://tailthemes.com/api/themes/grove)
- Registry item: [https://tailthemes.com/r/grove.json](https://tailthemes.com/r/grove.json)
