Skip to content

About

Site for TM Hospitality Strategies, restaurant and hospitality consulting, with free operator calculators: prime cost (with monthly tracker), plate and pour cost, break-even, actual food cost, and menu engineering. Vanilla HTML/CSS/JS, offline-capable, no runtime dependencies.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

TM Hospitality Strategies. Sharper concepts. Tighter operations. Better margins.


The official marketing site for TM Hospitality Strategies

A fast, accessible, single-page build with a dark/light theme, five operator calculators and a message builder.
No framework, no runtime dependencies.


Visit the live site


Deploy CI Lighthouse accessibility Lighthouse performance
axe WCAG Dependencies License


Preview  ·  Quick start  ·  Customize  ·  Quality gates  ·  Roadmap  ·  Issues


2 themes

Light and dark,
follows your system

0 requests

No third‑party calls,
cookies or analytics

0 violations

axe‑core, WCAG 2.2 AA,
in both themes

60+ checks

Browser tests, plus unit tests,
on every push

Note

Content status. The About, Services, Approach, Selected work and FAQ copy is placeholder text drafted for layout review. Each spot that needs real information is marked TODO(verify) in index.html, and no testimonials, statistics or client names have been invented. Tracked in #14.

Table of contents
1 · The sitePreview · What's on the page · Design system
2 · Build and runQuick start · Customize · Project structure · Deployment
3 · QualityQuality gates · Tech stack · Privacy and security · Roadmap


PART 1 · THE SITE

Preview

The site in both themes. It follows the visitor's system setting and has a manual toggle.

Light theme hero: 'Sharper concepts. Tighter operations. Better margins.' beside the animated TMHS brand scene
Light · hero
Dark theme hero with glowing logo-blue accents
Dark · hero
Prime cost calculator with sliders, a gauge, a cost breakdown bar and what-if savings
Light · prime cost
Cocktail cost calculator in the dark theme, pricing a drink from bottle prices and pours
Dark · cocktail cost
Case study placeholder cards with blueprint covers and a challenge, approach and outcome outline
Selected work · placeholders
Contact panel with a message builder that includes the calculator results
Contact · message builder
Services bento grid with a large Concept and positioning card
Services · bento layout
Approach: four steps joined by a progress line
Approach · scroll-linked progress line
Mobile hero at 390px wide
Mobile · 390px
Mobile navigation menu open
Mobile menu · keyboard operable

Screenshots, the banner and the social card are generated by scripts/screenshots.cjs.


What's on the page

Section Purpose
Header Sticky glass bar with section links, a current-section indicator, a reading-progress line and a dark/light toggle with a circular reveal.
Hero Value proposition, two calls to action and an animated brand scene (orbiting light, drifting rings, pointer parallax on fine pointers).
Focus marquee Pausable strip of service areas and venue types. It names no clients.
About The story behind the brand, a pull quote and three principles.
Services Bento grid: concept and positioning, operations, financial performance, growth and openings.
Approach Listen, diagnose, build, sustain, joined by a progress line that fills as you scroll.
Operator toolkit Five tabbed calculators that run entirely in the browser. Prime cost: sliders, or typed percentages and dollar amounts straight from the P&L, a live gauge and rule-of-thumb band, a month-by-month tracker (trend chart, table, CSV export and import, kept only in the browser), a breakdown of where each sales dollar goes and what each point of prime cost is worth. Plate cost and cocktail cost: ingredient or pour rows (bottle price, size and pour), a target cost % and an optional menu price, giving a suggested price, actual cost % and gross profit. Break-even: fixed costs, variable costs (dragged, typed to a decimal or as the P&L dollar total), average check and days open give the sales needed a month, a week and a day open, the guests a day it takes, and how far the visitor's own sales sit above or below it. Actual food cost: opening inventory, purchases, closing inventory and food sales give food used and actual food cost %, and against an optional theoretical food cost, the gap in points and dollars a month and a year (with a check for counts that don't add up). Your menu: dishes and drinks saved from the plate and cocktail tools, side by side with cost, price, cost % and margin; with last month's sales counts, menu engineering sorts each group into stars, plowhorses, puzzles and dogs (Kasavana and Smith: margin against the sales-weighted average, popularity against 70% of an equal share), with a one-line action for each. Saved dishes reopen in their calculator and round-trip as CSV. Any result can be shared as a link or printed (or saved as a PDF) as a one-page sheet with the date and a link back, and "Talk through these numbers" carries it into the contact message. The prime cost tracker also offers a spreadsheet template with the same formulas and bands. Each calculator page has an "Embed this calculator" snippet: other sites can show the calculator alone (?embed=1, optional &theme=dark), credited and linked back, sized to fit through postMessage, and kept out of search results.
Selected work Case-study cards with a blueprint cover and a challenge, approach and outcome outline, labeled as placeholders until real write-ups exist.
FAQ Two-column layout: a short intro with an "Ask something else" link beside a native <details> accordion.
Contact LinkedIn and Instagram, plus a message builder: pick topics and a business type, add a note and, optionally, the calculator results, then copy the message or (once an email is configured) send it with mailto:. On mobile a quick-contact bar appears between the hero and this section.
404 Branded error page that resolves its assets correctly from any nested URL.

Design system

Tokens live in css/tokens.css and follow the TM Hospitality Strategies Canva brand kit and logo.

Navy swatch
Navy
#0E1A33
Brand navy swatch
Brand
#203164
Brand blue swatch
Brand blue
#336193
Action blue swatch
Action
#1F4E8C
Logo blue swatch
Logo blue
#00A5F6
Canvas swatch
Canvas
#F6F7FA
Principle How it shows up
Tokens Fluid type and spacing scales, elevation and glow tokens, with complete light and dark sets.
Type Fraunces (with true italics for accent words) for headings and Inter for text: self-hosted variable fonts, subset to Latin and trimmed to the weights used (149 KB in total).
Theme Follows the system setting until the visitor chooses, then remembers the choice. No flash on load.
Contrast Every text pairing is chosen for WCAG AA and verified by axe in both themes. The bright logo blue is decorative, or used for text only on navy.
Motion Transforms and opacity only, paused or disabled under prefers-reduced-motion. Content is fully visible without JavaScript.

PART 2 · BUILD AND RUN

Quick start

Tip

There is nothing to install. Any static file server works.

git clone https://github.com/TMHSDigital/Github-Pages-Demo-1.git
cd Github-Pages-Demo-1
python -m http.server 8000      # or: npx serve

Then open http://localhost:8000.


Customize

Everything is plain files. Change it, reload the page.

To change Do this
Copy and sections Edit index.html. Search for TODO(verify) to find placeholder text.
Colors, fonts, spacing Edit the tokens in css/tokens.css. Light values are in :root, dark in [data-theme="dark"].
Calculator bands Edit BANDS in js/calc-math.js, the note under the calculator in index.html, the prime cost explainer and the bands in scripts/make-tracker-template.py. npm run test:unit fails until all of them agree (then run python scripts/make-tracker-template.py; see Generated files). Band colors are the --band-* tokens. Confirm the ranges before relying on them.
Example recipes and targets Edit defaults() in js/calc-recipe.js and the matching static values in index.html. The break-even example lives in the value attributes of its fields in index.html.
Contact email Set CONTACT_EMAIL in js/inquiry.js. While empty, the buttons point to LinkedIn and the message is copied instead of emailed.
Logo Replace assets/images/tmhs-logo.png and tmhs-logo-96.png (an SVG master is tracked in #16).
Social cards, app icons, banner, screenshots Run node scripts/screenshots.cjs after changing the page. It also renders one social card per calculator page from docs/tool-card.html (text set in the CARDS list in the script).
Header, footer or a calculator Edit it in index.html (the blocks between sync: markers), then run npm run sync to update the pages in tools/. CI fails if they drift apart.
Add a calculator Write its script and its sync:tool-<key> panel and tab in index.html, create tools/<slug>/index.html (copy one and edit the prose), add one entry to tools/tools.json, then run npm run sync and node scripts/screenshots.cjs. The sitemap, manifest shortcuts, links between tool pages, embed snippet, social card and test list all come from that entry, and CI fails if any part is missing.
Repo name or domain Change site in tools/tools.json and run npm run sync: every page, the sitemap, robots.txt, the 404 page's base path and the embed snippets follow. The full checklist, including the GitHub settings, is in CONTRIBUTING.

Project structure

Show the file tree
.
├── index.html               Single page: hero, about, services, approach, toolkit, work, FAQ, contact
├── 404.html                 Branded error page (uses <base> for the repo path)
├── manifest.webmanifest     Web app manifest: name, icons, shortcuts to each calculator
├── sw.js                    Service worker source (network first, keeps the pages a visitor opens; the build fills in its version)
├── privacy/                 Privacy page (plain language; listed under "pages" in tools/tools.json)
├── tools/                   tools.json (the site address, the tool registry, other pages) and one indexable page per calculator, with a worked example:
│                            prime-cost-calculator/, plate-cost-calculator/, pour-cost-calculator/,
│                            break-even-calculator/, food-cost-calculator/
├── css/
│   ├── tokens.css           Fonts, brand tokens, fluid scales, light and dark themes
│   ├── base.css             Reset, typography, layout primitives, buttons, reveal rules
│   └── components.css       Header, hero scene, marquee, sections, toolkit, contact, footer
├── js/
│   ├── theme.js             Dark/light toggle (pre-paint snippet lives in index.html)
│   ├── calc-math.js         Pure calculator maths (TMHSCalc) and the tool registry
│   ├── calc-prime.js        Prime cost tool: gauge, breakdown, what-if
│   ├── calc-tracker.js      Prime cost month-by-month tracker (localStorage, chart, CSV)
│   ├── calc-recipe.js       Plate and cocktail cost tools (one shared row-based tool)
│   ├── calc-breakeven.js    Break-even tool: sales per month, week and day, guests a day
│   ├── calc-foodcost.js     Actual food cost from inventory, and the gap to theoretical
│   ├── calc-menu.js         Your menu: saved dishes and drinks, menu engineering, CSV
│   ├── calc-tabs.js         Toolkit tabs, shared links and copy link
│   ├── inquiry.js           Contact message builder and CONTACT_EMAIL
│   └── main.js              Menu, scroll reveal, nav spy, parallax, marquee pause, quick-contact bar
├── assets/
│   ├── fonts/               Self-hosted Fraunces (upright and italic) and Inter, latin variable woff2
│   ├── images/              Logo, small logo, favicon, apple-touch and app icons, social cards (site and one per calculator)
│   └── downloads/           Prime cost tracker spreadsheet template
├── tests/
│   ├── calc-math.test.cjs   Unit tests for the calculator maths (node:test, no browser)
│   ├── bands.test.cjs, links.test.cjs  Unit tests: band copies agree, link extraction
│   ├── smoke.cjs            Browser test runner (Playwright): runs the areas below in parallel
│   └── browser/             One file per area: site, keyboard, pages, theme, prime, tracker, recipe, menu, breakeven, foodcost,
│                            contact, embed-print, build, tool-pages
├── scripts/
│   ├── stage.cjs            Builds the publishable _site (minified CSS/JS, site files only)
│   ├── sync-tool-pages.cjs  Copies shared markup from index.html into tools/*/; builds tool lists, sitemap and manifest shortcuts from tools/tools.json
│   ├── check-links.cjs      External link checker
│   ├── lighthouse.cjs       Lighthouse floors for every page in the sitemap
│   ├── screenshots.cjs      Regenerates docs/screenshots, the banner, social cards and app icons
│   ├── make-tracker-template.py  Builds assets/downloads/prime-cost-tracker.xlsx (Python)
│   └── requirements.txt     Pinned Python dependency for the template (openpyxl)
├── docs/                    README banner, calculator social card and app icon sources, screenshots
├── package.json             Pinned build and test tooling (no runtime dependencies)
├── eslint.config.cjs        Lint rules
├── CONTRIBUTING.md  SECURITY.md  LICENSE
└── .github/
    ├── workflows/ci.yml     Validation, tests, Lighthouse, internal links, then deploy
    ├── workflows/links.yml  Weekly external link check; reports rot as an issue
    └── dependabot.yml       Weekly GitHub Actions and npm tooling updates

Deployment

Every push to main runs ci.yml: it builds _site/ with scripts/stage.cjs, runs every quality gate against it, and only if they all pass publishes that exact _site/ to GitHub Pages. The build bundles and minifies the CSS (inlined into the home page to save a render-blocking request), minifies the scripts, adds a hash-based Content-Security-Policy, dates each sitemap entry from the page's last commit, writes the service worker (versioned by a hash of the published files) and copies only site files (index.html, 404.html, the calculator pages in tools/, manifest.webmanifest, robots.txt, sitemap.xml, assets). Source files stay unbundled for development.

Preview the published build locally
npm ci
npm run build && cd _site && python -m http.server 8000

PART 3 · QUALITY AND ROADMAP

Quality gates

ci.yml runs on every push and pull request. Tool versions are pinned in package.json and installed with npm ci.

Gate Tool Standard
Calculator maths node:test Table-driven unit tests for every calculation and input parser, run first
HTML validity html-validate No errors
JavaScript lint ESLint No errors
Layout Playwright, source and staged build No horizontal scroll at 375, 768 and 1280px; no console errors
Features Playwright Theme toggle persists and follows the system; prime, plate and cocktail maths, shorthand (120k), decimal-comma and dot-grouped (120.000) input, negative sales flagged, prime cost lines typed as dollars or decimal percentages, the month tracker (save, trend, CSV round trip, remove, two-step clear, blocked storage), per-field caps shown in the field, live readouts, caret-safe formatting and reset; ingredient rows add, remove and cap at 12; shared links open the right tool with their numbers, the address bar then follows edits so a reload keeps them, and copy link round-trips; the message builder includes calculator results and switches to mailto: when an email is set; the mobile quick-contact bar shows and hides; marquee pauses; one header call to action per layout; valid JSON-LD
Resilience Playwright With JavaScript off, or if the main script fails to load, all content stays visible; the mobile nav stays reachable
Keyboard Playwright A full Tab walk of every page (home, each calculator, privacy) at 1280 and 375px, with saved months and dishes loaded: every stop has an accessible name, is visible or shows focus on the control it stands in for, and follows reading order. Skip link first, menu moves focus into its links and closes on Escape or an outside click, toolkit tabs follow the ARIA arrow/Home/End pattern, focus stays put when rows are added or removed, FAQ operable, visible focus rings
Reflow and spacing Playwright No sideways scrolling or cut-off content at 320px and 640px (400% and 200% zoom), including with WCAG text-spacing overrides
Accessibility axe-core 0 violations (WCAG 2.0, 2.1 and 2.2 A/AA, best practice) at mobile and desktop, in both themes and with reduced motion, including the plate and cocktail tools and a filled-in message
Security Playwright, staged build Content-Security-Policy present on every page and no violations while using the theme toggle, toolkit tabs, message builder and 404 page
Performance and quality Lighthouse, staged build Every page in sitemap.xml: Performance 90 or higher; Accessibility, Best Practices and SEO 95 or higher (a page under a floor gets one rerun). Scores are posted to the CI job summary
Links internal checker in CI; external checker weekly (links.yml) No broken internal links, or no deploy. Broken external links open a link-rot issue instead of blocking a release
Run the checks locally
npm ci            # pinned tooling; tests use your installed Chrome
npm run test:unit # calculator maths only, no browser needed
npm run check     # unit tests, HTML validation, lint, browser tests on the source and on the published build
npm run links     # external link check (home, 404, README and every tool page); CI runs it weekly
npm run build && npm run lighthouse   # Lighthouse floors for every page in the sitemap

Important

Automated checks do not replace a real screen-reader review. A manual NVDA and VoiceOver pass is still recommended before launch (#17).


Tech stack

HTML5 CSS3 JavaScript GitHub Pages GitHub Actions

No framework, no bundler in development and no runtime dependencies.
Playwright, axe-core and esbuild are used only for testing and publishing and are never shipped.


Privacy and security

  • A plain-language privacy page (/privacy/, linked from every footer) says the same for visitors. It is marked TODO(verify) until the owner has reviewed it (#29).
  • The site makes no third-party requests: fonts are self-hosted, and there are no cookies, analytics or forms. The calculators and the message builder run locally and never send what you enter. The only things ever stored are what the visitor chooses to save (a month in the prime cost tracker, a dish in their menu), and those stay in their browser's localStorage until they remove them. A shared calculator link carries its numbers in the URL, and only to whoever you give it to; after opening one, the address bar keeps up with your changes (still only in the URL, never stored).
  • The published site can be installed as an app, and every page a visitor has opened works offline afterwards. Its service worker downloads nothing up front: each page hands it the files it already loaded. It keeps only the site's own files, never anything a visitor types, and always tries the network first so a new deploy shows up straight away.
  • The published pages carry a strict Content-Security-Policy: only the site's own files run, and the few inline blocks are allowed by hash (generated in scripts/stage.cjs).
  • GitHub Actions are pinned to commit SHAs and kept current by Dependabot.
  • Found a vulnerability? See SECURITY.md and report it privately through the repository's Security tab.

Roadmap

Open work is tracked in Issues, grouped here by what each item is waiting on.

Needs your input

  • Replace placeholder copy with real content (#14)
  • Choose a contact method, email or booking link (#15)
  • Confirm the prime cost bands and the example plate and cocktail recipes and targets (#27)
  • Provide the original vector logo (#16)
  • Add photography and richer visuals (#20)

Needs a decision

  • Rename the repo or move to a custom domain (#18)
  • How TMHS and TMHS Digital relate on the site (#19)
  • Analytics and privacy statement (#29)

Open to work

  • Manual screen-reader and zoom review (#17)


TM Hospitality Strategies

LinkedIn  ·  Instagram  ·  MIT License

About

Site for TM Hospitality Strategies, restaurant and hospitality consulting, with free operator calculators: prime cost (with monthly tracker), plate and pour cost, break-even, actual food cost, and menu engineering. Vanilla HTML/CSS/JS, offline-capable, no runtime dependencies.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages