Designing Wardline: A Compliance SaaS Website Template
How the Wardline template makes a compliance automation site feel calm and credible, from a live control dashboard to demo slots that skip holidays.
By Paul Peery
· 8 min read

Wardline is a website template for a compliance automation product: software that helps a company prepare for SOC 2, ISO 27001, HIPAA, GDPR, PCI DSS and NIST CSF. The people who buy that kind of product are security leads and CTOs who read carefully and distrust hype, so the design aims for calm: a cool ink-and-teal palette, a visible grid, status shown with words as well as color, and copy that is precise about what the software does and doesn't do. This post walks through its tools, from a framework overlap explorer to demo booking, and how to adapt them.
The demo company is Wardline, Inc., a fictional compliance platform in Richmond, Virginia. Its customers, integrations, subprocessors and staff are all made up, and the framework badges are generic drawings, not official marks.
Three fonts with three jobs#
Every page loads three Google Fonts families in one <link>:
href="https://fonts.googleapis.com/css2?family=Anek+Latin:wght@500;600;700&family=Source+Sans+3:ital,wght@0,400;0,600;0,700;1,400&family=Roboto+Mono:wght@400;500&display=swap"Anek Latin sets the headings and the large figures, such as the readiness percentage in the hero. It's a firm, plain sans serif that gives a headline weight without looking flashy, which suits a product promising no surprises at audit time. Source Sans 3 does the body text, form labels and tables. It's an open, even typeface built for interfaces, so long explanations of Type I versus Type II reports stay easy to read. Roboto Mono is for control IDs like AC-02, small uppercase labels and figures. Monospaced IDs line up in tables and read as real system data.
The fonts are Tailwind tokens in src/input.css, so font-display and font-mono work as ordinary utilities:
--font-display: "Anek Latin", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
--font-sans: "Source Sans 3", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
--font-mono: "Roboto Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;Ink, teal and status colors that never work alone#
The rest of the @theme block is the palette. Most of it is quiet: a near-white page, white cards, a pale "cloud" for alternate bands and a deep navy ink for text and dark sections. Teal is the single accent, used for buttons, links, focus rings and charts:
--color-ink: #0b1a2c; /* headings, body, dark bands */
--color-teal: #0b6f80; /* the accent: actions, links, focus */
--color-teal-bright: #5fd0d8; /* teal on ink */
--color-pass: #17703f; /* status: passing (always with a label) */
--color-attn: #8a5300; /* status: needs attention (always with a label) */
--color-fail: #b3261e; /* status: failing, errors (always with a label) */The comments on the status colors are a rule the whole template follows. A compliance dashboard is full of green, amber and red, and a reader who can't tell those apart still needs to know what's failing. So every status pill pairs its color with a symbol and a word: "✓ Passing", "▲ Needs attention", "✕ Failing". There's also a separate --color-attn-mark, a brighter amber used only for chart marks and never for text, because the darker amber is the one that's readable on a light background.
A layout set on a visible grid#
The pages sit on a twelve-column grid, and the heroes show it. The .columns class draws twelve faint vertical rules with one repeating gradient:
.columns {
background-image: repeating-linear-gradient(
to right,
transparent 0,
transparent calc(100% / 12 - 1px),
rgb(11 26 44 / 0.055) calc(100% / 12 - 1px),
rgb(11 26 44 / 0.055) calc(100% / 12)
);
}A .columns-ink twin does the same in white on the dark bands and footer. Section labels (.eyebrow) are uppercase mono captions with a small teal square drawn by ::before, and product mockups sit in a .frame, a white window with a thin title bar.
The hero control dashboard#
The home page hero is split five columns of copy to seven of product. The product side is a compliance overview for a sample workspace, with buttons to switch between SOC 2, ISO 27001 and HIPAA. Each framework's numbers live in one object in initHeroDashboard():
const states = {
soc2: { pass: 57, attn: 3, fail: 1, ready: 93, days: 46 },
iso27001: { pass: 54, attn: 7, fail: 2, ready: 86, days: 73 },
hipaa: { pass: 34, attn: 2, fail: 0, ready: 94, days: 29 },
};Clicking a button sets aria-pressed, updates the counts and redraws the stacked status bar. The days value is how far away the next audit window opens. It's added to today's date, so the dashboard never shows an audit window that's already in the past.
Next to the hero, the copy keeps the product honest: Wardline prepares you for the audit, while a licensed CPA firm issues the SOC 2 report and an accredited certification body issues the ISO 27001 certificate.
The framework overlap explorer#
Buyers often need more than one framework and want to know how much work carries over. The frameworks page answers it from a single control library in assets/js/data.js. Each control is an ID, a title and a string of one-letter framework codes:
["AC-02", "Multi-factor authentication on workforce accounts", "SIHPN"],That control counts toward SOC 2, ISO 27001, HIPAA, PCI DSS and NIST CSF. Everything on the page is computed from those letters. overlap() sorts the library into three lists for any pair of frameworks:
CONTROLS.forEach((control) => {
const inA = control[2].includes(ca),
inB = control[2].includes(cb);
if (inA && inB) shared.push(control);
else if (inA) onlyA.push(control);
else if (inB) onlyB.push(control);
});The page draws the result as an SVG Venn diagram with the counts in each region, a table of shared or unique controls, and a matrix of every pair where each number links to that comparison. The choice is kept in the URL (?fw=soc2&vs=iso27001), so a link to a comparison opens on it.
Readiness assessment scoring#
The assessment asks eight questions: company size, cloud setup, policies, identity, logging, vendor reviews, the target framework and the deadline. Five are scored, up to 20 points each. assess() adds them up, ranks the gaps by points missing and turns the answers into a preparation range in weeks:
const low = Math.round((target.weeks[0] + gapWeeks) * factor);
const high = Math.round((target.weeks[1] + gapWeeks * 1.5) * factor);The size factor grows with headcount, and the high end counts the gap weeks one and a half times, which gives the range a wider margin on the slow side. The deadline answer then gives a verdict: "Realistic" if even the high estimate fits, "Tight" if only the low one does, "At risk" otherwise. Answers are saved, and the results link to the demo form prefilled. The page says plainly that the result is an estimate, not an audit.
A pricing calculator that shows its working#
The pricing calculator takes employees in scope (a range slider), the number of frameworks, add-ons and monthly or annual billing. The plan follows headcount, and quote() builds an itemized list: the plan's base, extra employees, extra frameworks, then each add-on, with add-ons a plan already includes listed separately. Annual billing applies one discount constant:
const annualMonthly = Math.round((monthly * (100 - ANNUAL_DISCOUNT)) / 100);Showing the lines, not just a total, helps a buyer who has to justify the quote internally. Every figure is in PLANS and ADDONS in data.js, so the demo prices are easy to replace with your own.
A trust center with rolling dates#
The trust center lists control status by category in expandable panels, the subprocessors in a table, and documents a visitor can request. Requests check for a work email (personal domains are refused) and ask for an NDA when a chosen document needs one.
Report dates are the hard part of a demo that stays online for years: a SOC 2 report period from 2025 looks abandoned by 2028. With KEEP_DEMO_CURRENT on, reportDates() works them out from today. The SOC 2 period ends on the latest September 30 whose report has been issued, with the issue date on the fourth Wednesday of October. The ISO 27001 certificate runs in three-year cycles from March 14, 2025, and the latest penetration test is the most recent August. Turn the flag off and the page shows the fixed dates in FIXED_REPORTS instead.
Elsewhere, elements with data-day-offset fill a date relative to today, and ?now=YYYY-MM-DDTHH:MM previews the site at another Eastern time.
Demo booking that skips weekends and holidays#
The contact page books a demo in three steps: team, details and a time. Slots are fixed times in Richmond on the next five business days. "Business day" means not a weekend and not a US federal holiday, and the holidays are worked out by rule for any year in holidaysFor(), not typed in as a list:
[nth(11, 4, 4), "Thanksgiving Day"],
[observed(key(12, 25)), "Christmas Day"],nth() finds, say, the fourth Thursday of November, and observed() moves a Saturday holiday to the Friday before and a Sunday holiday to the Monday after. Times show in the visitor's own time zone with the Richmond time underneath, and a "Show times in" menu switches zones. A small hash of date and time marks some slots as booked, consistently all day. The call is routed to a specialist by the answers: HIPAA, PCI DSS and larger companies each go to a different person.
Making it yours#
- Colors: change the teal tokens in
src/input.cssand rebuild the CSS withnpm run build. Some generated SVG art inmain.jsuses hex values directly, so search for#0b6f80too. The Tailwind guide covers rebuilding. - Content: frameworks, controls, integrations, pricing, the assessment, the trust center and demo settings are all in
assets/js/data.js. - Real dates: for a live trust center, set
KEEP_DEMO_CURRENTtofalseand fill inFIXED_REPORTSwith your actual report dates. - Forms: the document request and demo forms don't send anything until you connect them; each submit handler has a comment at the spot. See forms for services that work with static sites.
The Wardline documentation has the full list of data, storage keys and URL parameters. Wardline's HTML version is a free download, and it's also available for Next.js, Astro and WordPress with the same design and interactions. For another B2B product site with demo booking and an itemized quote, see Latchline, a customer onboarding platform.

About the author
Paul Peery
Founder of Freeframe
Paul Peery runs Freeframe, which publishes complete multi-page website templates in HTML, Next.js, Astro and WordPress, and writes about getting small websites built, launched and kept up to date.


