{"slug":"clearing","name":"Clearing — Treasury & Cash Forecast","version":"1.0.0","category":"dashboard","priceCents":3400,"description":"A finance dashboard template for treasury, cash-management and CFO products, built on the artifact a treasury actually runs on: a rolling thirteen-week cash forecast. Seven routes ship — a cash position that opens on the account index rather than a stat rail, the thirteen-week forecast at full size with three costed ways out of the week that breaches the covenant, a Thursday supplier payment run, an account statement, a counterparty page that opens on the net position rather than a balance, an exposure and facilities page, and a living component styleguide. The signature is the horizon: one thirteen-week window drawn three ways — the full grid, a thirteen-cell strip inside an account row, and a single blown-up column — all three resolving through one function that throws on a week outside the window, so no drawing can disagree with another about where the money runs out. A closed week is solid and an open week is hatched, so the distinction that matters most survives greyscale and a colour-blind reader. The register is deliberately flat: white paper, one hairline, and a saturated ink spent in three places only — the brand, the money direction, and the horizon. Green means money in and red means money out on every route, which is why the brand ink is neither. The payment run carries the state layer: selection, filters whose empty state names the filter rather than implying an empty run, an approval above £250,000 that opens a two-eyes confirmation the run's own id has to be typed into, a hold that asks for a category and a sentence before it will record one, and a durable receipt instead of a toast. Every figure on every route derives from one fixture file, and the styleguide checks that spine in front of the reader. 120 design tokens, every one re-authored for dark, all of it derived in OKLCH and every pair computed against its contrast tier. Self-hosted Onest and Chivo Mono. Built for Tailwind v4, Next.js 15 and React 19; every colour lives in theme.css.","summary":"A tailwind finance dashboard template for treasury: the rolling thirteen-week cash forecast, a payment run with a real state layer, 7 routes, one fixture spine.","tags":["tailwind finance dashboard template","nextjs treasury dashboard template","cash flow forecast dashboard template","react fintech admin dashboard","cash management ui template","tailwind-v4"],"palette":{"bg":"#ffffff","surface":"#f6f7fa","accent":"#1e1f8a","text":"#121315","line":"#e4e5e8"},"accent_mode":"monochrome-plus-spot","darkMode":true,"pages":[{"path":"/","title":"Cash position","sections":["app-shell","account-index","position-summary","movements-table"]},{"path":"/forecast","title":"Thirteen-week forecast","sections":["app-shell","ui/horizon"]},{"path":"/payments","title":"Payment run R-2634","sections":["app-shell","payment-run"]},{"path":"/account","title":"Lloyds · Operating","sections":["app-shell","account-statement"]},{"path":"/counterparty","title":"Solvay Chemicals BV","sections":["app-shell","counterparty-detail","ui/horizon"]},{"path":"/exposure","title":"Exposure and facilities","sections":["app-shell","exposure-charts"]},{"path":"/components","title":"The parts","sections":["tokens","ui/horizon","ui/money","ui/button","ui/badge","ui/panel","ui/table","ui/dashboard-layout","ui/dropdown-menu","ui/popover"]}],"components":[{"name":"app-shell","file":"src/components/app-shell.tsx","renders":"Sidebar and rail navigation, the freshness line, search, mode toggle, the covenant count on the Forecast item, and the footer's second-signature line"},{"name":"account-index","file":"src/components/account-index.tsx","renders":"The account index — seven accounts across five banks with what each is for, cleared and uncleared balances, and a sterling total that separates liquid from ring-fenced"},{"name":"position-summary","file":"src/components/position-summary.tsx","renders":"Four position cards, each with one figure, its movement, and the clause saying what it excludes, plus the horizon strip and the covenant verdict"},{"name":"movements-table","file":"src/components/movements-table.tsx","renders":"The last two days of movements with cleared and in-flight states"},{"name":"payment-run","file":"src/components/payment-run.tsx","renders":"The Thursday supplier run: filters, selection, approval with a durable receipt, holds with reasons, and the two-eyes permission boundary"},{"name":"account-statement","file":"src/components/account-statement.tsx","renders":"One account opened — statement head, running-balance statement lines, and the instructions queued against it"},{"name":"exposure-charts","file":"src/components/exposure-charts.tsx","renders":"The cash curve with the covenant floor, receipts against payments by week, currency cover, and the positions-and-marks table"},{"name":"ui/horizon","file":"src/components/ui/horizon.tsx","renders":"THE SIGNATURE — the thirteen-week horizon as a full grid, a thirteen-cell strip, a single column and a legend"},{"name":"ui/data","file":"src/components/ui/data.ts","renders":"The fixture spine: accounts, weeks, payments, exposures and the derivations every route reads"},{"name":"ui/money","file":"src/components/ui/money.tsx","renders":"Figure, DisplayFigure, Delta, DeltaPercent and DualFigure — how a number is printed in this theme"},{"name":"ui/panel","file":"src/components/ui/panel.tsx","renders":"Panel, PanelHeader, PanelFooter and PageHeading — the console's one container"},{"name":"ui/table","file":"src/components/ui/table.tsx","renders":"The console table, its totals row and its empty state"},{"name":"ui/button","file":"src/components/ui/button.tsx","renders":"Button and ButtonLink — four variants, four sizes, disabled and pending"},{"name":"ui/badge","file":"src/components/ui/badge.tsx","renders":"Badge, PaymentBadge, CovenantBadge and Eyebrow"},{"name":"ui/dashboard-layout","file":"src/components/ui/dashboard-layout.tsx","renders":"Shell geometry — expanded and collapsed navigation planes, sticky header, mobile navigation slot and main gutter"},{"name":"ui/mode-toggle","file":"src/components/ui/mode-toggle.tsx","renders":"The light/dark switch, scoped to :root standalone and .tt-clearing embedded"},{"name":"ui/chart.tsx","file":"src/components/ui/chart.tsx","renders":"Chart chrome — the token-only series mapping, the plot frame and the text alternative"},{"name":"ui/dropdown-menu","file":"src/components/ui/dropdown-menu.tsx","renders":"The console's one menu — tt-ui behaviour in this theme's register: an achromatic hover row, a disabled row that keeps its reason under the list, and a critical tone for the one action that cannot be undone"},{"name":"counterparty-detail","file":"src/components/counterparty-detail.tsx","renders":"One counterparty opened — the net position across both ledgers, the credit limit, the weeks this name moves, its open invoices with ageing, and what we owe it in the run"},{"name":"console-menus","file":"src/components/console-menus.tsx","renders":"The header's standing-conditions menu and desk menu, every row derived from the fixture spine rather than authored"},{"name":"ui/popover","file":"src/components/ui/popover.tsx","renders":"The disclosure behind the helper rule — a short line on the panel and its reasoning one press away, with the theme's Hint and HelperLine built on it"},{"name":"ui/dialog","file":"src/components/ui/dialog.tsx","renders":"The console's own card behind a neutral scrim — the hold surface on /payments and the rates note on /components. The width is the surface's and the ground is the panel's, so the styleguide photograph sits at the live width"},{"name":"ui/confirm-dialog","file":"src/components/ui/confirm-dialog.tsx","renders":"The two-eyes gate: approving a selection above £250,000 asks for the run's own id to be typed and names the second signatory, which is the policy the run header has printed since the theme shipped"},{"name":"ui/tabs","file":"src/components/ui/tabs.tsx","renders":"The counterparty's three ledgers — receivable, payable, settled — on the panel's header seam, selection drawn as a 2px rule rather than a fourth ground"},{"name":"ui/field","file":"src/components/ui/field.tsx","renders":"The shell every control in the hold form sits in: a persistent label, one supporting line, and a message row reserved so a field does not grow when it fails"},{"name":"ui/form","file":"src/components/ui/form.tsx","renders":"The submit flow behind the hold dialog — validate on submit, focus the summary or the first invalid control, keep every valid value, and land a durable receipt rather than a toast"},{"name":"ui/form-error-summary","file":"src/components/ui/form-error-summary.tsx","renders":"The focused alert a failed hold puts the reader into, one underlined link per field still owed an answer"},{"name":"ui/search-input","file":"src/components/ui/search-input.tsx","renders":"The payment run's search, over beneficiary and reference: a labelled type=search, a clear that returns focus to the input, and a counted line that is announced and visible. It replaced a header field that filtered nothing on seven routes"}],"tokens":{"--background":"#ffffff","--foreground":"#121315","--card":"#ffffff","--card-foreground":"#121315","--surface-sunken":"#f6f7fa","--row-stripe":"#f7f8fb","--surface-raised":"#ffffff","--surface-overlay":"#ffffff","--overlay-border":"#bcbdc2","--muted":"#f3f4f8","--muted-foreground":"#6c6e73","--secondary":"#f3f4f8","--secondary-foreground":"#2a2c31","--muted-on-soft":"#66686d","--secondary-hover":"#ebedf1","--secondary-active":"#e4e5e9","--border":"#e4e5e8","--border-strong":"#a6a8ad","--shadow-color":"#111524","--scrim":"#171a24","--nav":"#f9fafc","--nav-foreground":"#121315","--nav-muted":"#6c6e73","--nav-label":"#6c6e73","--nav-hover":"#f1f2f6","--nav-selected":"#ffffff","--nav-selected-foreground":"#1e1f8a","--nav-border":"#e4e5e8","--primary":"#1e1f8a","--primary-foreground":"#ffffff","--primary-hover":"#150377","--primary-active":"#0e0064","--primary-soft":"#ebf0fe","--primary-border":"#ced8fa","--primary-ink":"#262d97","--accent":"#ebedf1","--accent-foreground":"#2a2c31","--accent-hover":"#e4e5e9","--accent-active":"#dcdee3","--accent-soft":"#f6f7fa","--accent-border":"#dedfe4","--field":"#f9fafc","--field-border":"#dedfe4","--control":"#ffffff","--control-border":"#dedfe4","--control-hover":"#f0f1f5","--control-active":"#e8e9ee","--ring":"#4455c2","--selection":"#dde7ff","--selection-foreground":"#131a44","--selection-border":"#738aed","--link":"#3340ab","--link-hover":"#20228d","--link-visited":"#5b3d87","--info":"#0072ae","--info-foreground":"#ffffff","--info-soft":"#e1f3ff","--info-border":"#b7e0f9","--info-fill":"#0072ae","--positive":"#0c7937","--positive-foreground":"#ffffff","--positive-soft":"#e3f6e6","--positive-border":"#bee5c5","--positive-fill":"#0c7937","--warning":"#985f00","--warning-foreground":"#ffffff","--warning-soft":"#ffefd9","--warning-border":"#f8d4a8","--warning-fill":"#985f00","--critical":"#bc2826","--critical-foreground":"#ffffff","--critical-soft":"#ffece9","--critical-border":"#facec8","--critical-fill":"#bc2826","--horizon-grid":"#dedfe3","--horizon-actual":"#1e1f8a","--horizon-forecast":"#8499e9","--horizon-floor":"#d86258","--horizon-breach":"#ffece9","--chart-1":"#1e1f8a","--chart-2":"#4455c2","--chart-3":"#828693","--chart-4":"#0c7937","--chart-5":"#bc2826","--radius-sm":"0.375rem","--radius":"0.625rem","--radius-lg":"0.875rem","--radius-xl":"1.25rem","--radius-pill":"999px","--shadow-raised":"0 1px 2px -1px color-mix(in oklab, var(--shadow-color) 10%, transparent)","--shadow-overlay":"0 10px 30px -12px color-mix(in oklab, var(--shadow-color) 26%, transparent), 0 2px 6px -2px color-mix(in oklab, var(--shadow-color) 14%, transparent)","--text-caption":"0.75rem","--leading-caption":"1.4","--text-small":"0.875rem","--leading-small":"1.45","--text-body":"1rem","--leading-body":"1.55","--text-lead":"1.125rem","--leading-lead":"1.6","--text-d1":"1.5rem","--leading-d1":"1.25","--text-d2":"1.8rem","--leading-d2":"1.2","--text-d3":"clamp(1.8rem, 1.651rem + 0.637vw, 2.16rem)","--leading-d3":"1.15","--text-d4":"clamp(2.16rem, 1.981rem + 0.764vw, 2.592rem)","--leading-d4":"1.1","--tracking-d1":"-0.010em","--tracking-d2":"-0.014em","--tracking-d3":"-0.018em","--tracking-d4":"-0.022em","--tracking-label":"0.06em","--font-display":"var(--font-clearing-text), ui-sans-serif, system-ui, sans-serif","--font-text":"var(--font-clearing-text), ui-sans-serif, system-ui, sans-serif","--font-sans":"var(--font-text)","--font-mono":"var(--font-clearing-mono), ui-monospace, monospace","--display-weight":"600","--duration-quick":"110ms","--duration-settle":"160ms","--ease-standard":"cubic-bezier(0.2, 0, 0, 1)"},"tokensDark":{"--background":"#0b0c0e","--foreground":"#f2f3f6","--card":"#161719","--card-foreground":"#f2f3f6","--surface-sunken":"#060608","--row-stripe":"#1a1b1e","--surface-raised":"#1f2023","--surface-overlay":"#26272b","--overlay-border":"#4b4d52","--muted":"#1f2023","--muted-foreground":"#a1a3a8","--secondary":"#1f2023","--secondary-foreground":"#f2f3f6","--muted-on-soft":"#a1a3a8","--secondary-hover":"#292a2e","--secondary-active":"#333438","--border":"#2c2e31","--border-strong":"#56585d","--shadow-color":"#000000","--scrim":"#030306","--nav":"#121315","--nav-foreground":"#f2f3f6","--nav-muted":"#a1a3a8","--nav-label":"#7e828a","--nav-hover":"#1d1e21","--nav-selected":"#232427","--nav-selected-foreground":"#8ca4ff","--nav-border":"#2c2e31","--primary":"#687de0","--primary-foreground":"#0b0c0e","--primary-hover":"#7b91ee","--primary-active":"#90a6f7","--primary-soft":"#1c254d","--primary-border":"#303d77","--primary-ink":"#869efc","--accent":"#292a2e","--accent-foreground":"#f2f3f6","--accent-hover":"#333438","--accent-active":"#3c3d42","--accent-soft":"#1f2023","--accent-border":"#343539","--field":"#161719","--field-border":"#313336","--control":"#1f2023","--control-border":"#343539","--control-hover":"#292a2e","--control-active":"#333438","--ring":"#7189f3","--selection":"#242e60","--selection-foreground":"#ebf0fe","--selection-border":"#687de0","--link":"#8ca4ff","--link-hover":"#abc0ff","--link-visited":"#ae96da","--info":"#41b0eb","--info-foreground":"#0b0c0e","--info-soft":"#072e42","--info-border":"#004e71","--info-fill":"#41b0eb","--positive":"#53be70","--positive-foreground":"#0b0c0e","--positive-soft":"#12301a","--positive-border":"#1b552c","--positive-fill":"#53be70","--warning":"#eea743","--warning-foreground":"#0b0c0e","--warning-soft":"#3c2607","--warning-border":"#663f00","--warning-fill":"#eea743","--critical":"#ed695e","--critical-foreground":"#0b0c0e","--critical-soft":"#431d19","--critical-border":"#742e29","--critical-fill":"#ed695e","--horizon-grid":"#2c2e31","--horizon-actual":"#687de0","--horizon-forecast":"#5568be","--horizon-floor":"#df695e","--horizon-breach":"#431d19","--chart-1":"#687de0","--chart-2":"#8ca4ff","--chart-3":"#888c99","--chart-4":"#53be70","--chart-5":"#ed695e","--radius-sm":"0.375rem","--radius":"0.625rem","--radius-lg":"0.875rem","--radius-xl":"1.25rem","--radius-pill":"999px","--shadow-raised":"0 1px 2px -1px color-mix(in oklab, var(--shadow-color) 10%, transparent)","--shadow-overlay":"0 10px 30px -12px color-mix(in oklab, var(--shadow-color) 26%, transparent), 0 2px 6px -2px color-mix(in oklab, var(--shadow-color) 14%, transparent)","--text-caption":"0.75rem","--leading-caption":"1.4","--text-small":"0.875rem","--leading-small":"1.45","--text-body":"1rem","--leading-body":"1.55","--text-lead":"1.125rem","--leading-lead":"1.6","--text-d1":"1.5rem","--leading-d1":"1.25","--text-d2":"1.8rem","--leading-d2":"1.2","--text-d3":"clamp(1.8rem, 1.651rem + 0.637vw, 2.16rem)","--leading-d3":"1.15","--text-d4":"clamp(2.16rem, 1.981rem + 0.764vw, 2.592rem)","--leading-d4":"1.1","--tracking-d1":"-0.010em","--tracking-d2":"-0.014em","--tracking-d3":"-0.018em","--tracking-d4":"-0.022em","--tracking-label":"0.06em","--font-display":"var(--font-clearing-text), ui-sans-serif, system-ui, sans-serif","--font-text":"var(--font-clearing-text), ui-sans-serif, system-ui, sans-serif","--font-sans":"var(--font-text)","--font-mono":"var(--font-clearing-mono), ui-monospace, monospace","--display-weight":"600","--duration-quick":"110ms","--duration-settle":"160ms","--ease-standard":"cubic-bezier(0.2, 0, 0, 1)"},"compatibility":{"next":">=15","react":">=19","tailwind":">=4"},"dependencies":["lucide-react","recharts"],"editions":{"react":{"source":"src","runtime":"react"},"html":{"source":"html/src","output":"html/dist","engine":"nunjucks","runtime":"vanilla","buildRequired":false}},"ui_library":{"version":"1.4.0","files":["html/src/js/_tt/anchor.js","html/src/js/_tt/confirm-dialog.js","html/src/js/_tt/dialog.js","html/src/js/_tt/dropdown-menu.js","html/src/js/_tt/field-ids.js","html/src/js/_tt/field.js","html/src/js/_tt/focusables.js","html/src/js/_tt/form-error-summary.js","html/src/js/_tt/form.js","html/src/js/_tt/layer.js","html/src/js/_tt/pending.js","html/src/js/_tt/popover.js","html/src/js/_tt/presence.js","html/src/js/_tt/reduced-motion.js","html/src/js/_tt/roving.js","html/src/js/_tt/search-input.js","html/src/js/_tt/tabs.js","src/components/ui/_tt/anchor.ts","src/components/ui/_tt/capture.ts","src/components/ui/_tt/confirm-dialog.axes.ts","src/components/ui/_tt/confirm-dialog.fixtures.ts","src/components/ui/_tt/confirm-dialog.tsx","src/components/ui/_tt/dialog.axes.ts","src/components/ui/_tt/dialog.fixtures.ts","src/components/ui/_tt/dialog.tsx","src/components/ui/_tt/dropdown-menu.axes.ts","src/components/ui/_tt/dropdown-menu.fixtures.ts","src/components/ui/_tt/dropdown-menu.tsx","src/components/ui/_tt/field-ids.ts","src/components/ui/_tt/field.axes.ts","src/components/ui/_tt/field.capture.ts","src/components/ui/_tt/field.fixtures.ts","src/components/ui/_tt/field.tsx","src/components/ui/_tt/focusables.ts","src/components/ui/_tt/form-error-summary.axes.ts","src/components/ui/_tt/form-error-summary.fixtures.ts","src/components/ui/_tt/form-error-summary.tsx","src/components/ui/_tt/form.axes.ts","src/components/ui/_tt/form.fixtures.ts","src/components/ui/_tt/form.part.tsx","src/components/ui/_tt/form.ts","src/components/ui/_tt/host.ts","src/components/ui/_tt/ids.ts","src/components/ui/_tt/layer.ts","src/components/ui/_tt/layout-effect.ts","src/components/ui/_tt/popover.axes.ts","src/components/ui/_tt/popover.fixtures.ts","src/components/ui/_tt/popover.tsx","src/components/ui/_tt/presence.ts","src/components/ui/_tt/recipe.ts","src/components/ui/_tt/reduced-motion.ts","src/components/ui/_tt/roving.ts","src/components/ui/_tt/search-input.axes.ts","src/components/ui/_tt/search-input.capture.ts","src/components/ui/_tt/search-input.fixtures.ts","src/components/ui/_tt/search-input.tsx","src/components/ui/_tt/tabs.axes.ts","src/components/ui/_tt/tabs.fixtures.ts","src/components/ui/_tt/tabs.tsx"]},"license":"standard","design":{"typefaces":{"display":"Onest","text":"Onest","mono":"Chivo Mono"},"typeRatio":1.2,"signature":"The thirteen-week horizon: one rolling cash window drawn three ways — the full grid on /forecast, a thirteen-cell strip inside an account row or a summary card, and one blown-up column at the head of a page about that week. All three resolve through weekFor() (src/components/ui/data.ts), which throws on a week outside the window, so a strip cannot silently render twelve cells. A closed week is solid and an open week is hatched: 'banked' versus 'forecast' is the most important distinction on the screen and it is carried by a texture, not a hue. Not portable — a horizon means nothing on a landing page; it exists only where the substrate is money over time."}}