AI ExperienceDesign EngineeringDesign SystemsMobileProduct Design
ClaudeGoogle Apps ScriptGoogle Sheets
Google Sheetthe databaseTransactions, bills, the payoff plan, settings and a log of every change.
→
Apps Script APICode.gsChecks the Google token, runs only whitelisted functions, syncs bank emails, calls the AI.
→
Static front endindex.html + config.jsOne file on my own domain, cached so it opens instantly.
→
iPhone home screenMarea AppIts own icon and name, no browser bar. It feels like a native app.
Source  Css · Css2 · App1–3 · Data1–2  →  build-front.py  →  index.html
The build refuses to ship if a template is unresolved, config.js loads after the app, the page has no title, or the API URL is the private test one.
/* One door to the server. About 40 calls go through here, so moving
   the front end out of Apps Script meant changing one function. */
const inAppsScript = () =>
  typeof google !== 'undefined' && google.script && google.script.run;

const callServer = (name, ...args) => {
  if (inAppsScript()) return new Promise((resolve, reject) => {
    google.script.run
      .withSuccessHandler(resolve)
      .withFailureHandler(reject)[name](...args);
  });
  return callApi(name, args);  // fetch + Google token
};
Still to pay this cycle
3 bills
InternetPaid
WaterDue 11th
CardOver budget
Log a purchase
body · Classic
Still to pay this cycle
3 bills
InternetPaid
WaterDue 11th
CardOver budget
Log a purchase
body.is-ember · Ember
Large title--large-title 700 34/41
Title 2--title-2 700 22/28
Headline--headline 600 17/22
Body--body 400 17/22
Footnote--footnote 400 13/18
/* Pure white on pure black is the harshest pair there is. At 21:1 text blooms off the background, and on OLED screens true black smears while you scroll. Nothing past 15:1 adds anything. */
--text: #F2F2F5;  --bg: #101013;
19automated test suites run on every change
31spacing values found in 470 uses, collapsed into one scale
4 → 2skins explored, skins shipped
2files to deploy: index.html to my server, Code.gs to Apps Script
1 · configBoth values filled in, nothing left as a placeholder
2 · sign-inGoogle returns a token for this app
3 · serverThe live Apps Script version answers
4 · tokenThe server accepts it: right app, not expired, my email
5 · dataThe sheet reads and writes

Marea

Secret Link