/* AI With Tom OS — one visual system for every module.

   The palette is AI With Tom's, lifted from ~/Desktop/ai-with-tom-site/style.css
   so the OS and the website read as one thing: blue #2F6BFF on white, amber for
   attention, the site's own greys and hairlines, Inter + Space Mono.

   Light by default, exactly like the site, because most of this is numbers and
   they are easier to read on white. It follows the system setting unless Tom has
   picked one with the toggle, and that choice wins on every device he uses.

   Tokens on :root; every module uses these and nothing else. */

:root {
  /* --- surfaces, straight from the site --- */
  --bg: #f5f6f8;            /* site --surface, used as the page */
  --bg-2: #ffffff;          /* site --bg, used for cards */
  --bg-3: #eceef2;          /* hover + subtle fills */
  --line: #e3e5ea;          /* site --border */
  --line-2: #d3d7de;
  --rule: rgba(18,18,18,.11);

  /* --- text --- */
  --fg: #16181d;            /* site --text */
  --fg-2: #5d6470;          /* site --muted */
  --fg-3: #a0a5ae;          /* site --faint */

  /* --- brand --- */
  --accent: #2F6BFF;        /* site --accent */
  --accent-lt: #4D9CFF;
  --accent-tint: #EAF1FF;
  --accent-fg: #ffffff;

  /* --- meaning. Money is the whole point of this app, so these three carry
         real weight: good = received, warn = owed, bad = overdue or lost. --- */
  --ok: #1f6f43;            /* site --good */
  --ok-tint: #e9f3ed;
  --warn: #E8952B;          /* site --amber */
  --warn-tint: #FFF4E0;
  --bad: #9b2c2c;           /* site --bad */
  --bad-tint: #fbeaea;
  --info: #2F6BFF;

  --shadow: 0 8px 26px rgba(14,21,36,.10);
  --shadow-sm: 0 1px 2px rgba(14,21,36,.05);
  --radius: 14px;
  --radius-s: 9px;
  --sidebar: 232px;

  /* Motion. One easing for entrances (decelerate), one for exits (accelerate),
     one spring-ish for anything that should feel physical. Durations are short
     on purpose: a working tool should feel instant, not animated. */
  --e-out: cubic-bezier(.16, .84, .44, 1);
  --e-in: cubic-bezier(.4, 0, 1, 1);
  --e-spring: cubic-bezier(.22, 1.2, .36, 1);
  --t-fast: .13s;
  --t: .22s;
  --t-slow: .34s;

  --font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
  --mono: 'Space Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  color-scheme: light;
}

/* Dark: the site's own dark-mode values. Follows the system unless Tom has
   explicitly chosen light, and the explicit dark choice below always wins. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0d0e12; --bg-2: #171920; --bg-3: #1e212a; --line: #282b34; --line-2: #363a45;
    --rule: rgba(233,235,240,.10);
    --fg: #e9ebf0; --fg-2: #99a0ac; --fg-3: #767d89;
    --accent: #7ea6ff; --accent-lt: #9dbcff; --accent-tint: #141c31; --accent-fg: #0d0e12;
    --ok: #5fc98c; --ok-tint: #152f1e;
    --warn: #e0a469; --warn-tint: #2a2013;
    --bad: #f08b8b; --bad-tint: #2b1717;
    --info: #7ea6ff;
    --shadow: 0 10px 30px rgba(0,0,0,.45); --shadow-sm: 0 1px 2px rgba(0,0,0,.3);
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --bg: #0d0e12; --bg-2: #171920; --bg-3: #1e212a; --line: #282b34; --line-2: #363a45;
  --rule: rgba(233,235,240,.10);
  --fg: #e9ebf0; --fg-2: #99a0ac; --fg-3: #767d89;
  --accent: #7ea6ff; --accent-lt: #9dbcff; --accent-tint: #141c31; --accent-fg: #0d0e12;
  --ok: #5fc98c; --ok-tint: #152f1e;
  --warn: #e0a469; --warn-tint: #2a2013;
  --bad: #f08b8b; --bad-tint: #2b1717;
  --info: #7ea6ff;
  --shadow: 0 10px 30px rgba(0,0,0,.45); --shadow-sm: 0 1px 2px rgba(0,0,0,.3);
  color-scheme: dark;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--bg); color: var(--fg); font-family: var(--font); font-size: 14px; line-height: 1.45;
  -webkit-font-smoothing: antialiased; min-height: 100vh;
}
a { color: var(--info); text-decoration: none; }
a:hover { text-decoration: underline; }
button, input, select, textarea { font: inherit; color: inherit; }
[hidden] { display: none !important; }
::selection { background: var(--accent-tint); color: var(--fg); }

/* ---------- layout ---------- */
.shell { display: grid; grid-template-columns: var(--sidebar) 1fr; min-height: 100vh; }
.side {
  position: sticky; top: 0; height: 100vh; overflow-y: auto; border-right: 1px solid var(--rule);
  background: var(--bg-2); padding: 18px 14px; display: flex; flex-direction: column; gap: 6px;
}
.brand { display: flex; align-items: center; gap: 10px; padding: 6px 8px 16px; }
.brand .logo { width: 30px; height: 30px; border-radius: 9px; background: var(--accent); display: grid; place-items: center; flex: none; }
.brand .logo svg { display: block; }
.brand h1 { font-size: 15px; margin: 0; letter-spacing: -.015em; white-space: nowrap; }
.brand small { display: block; color: var(--fg-3); font-size: 11px; }
.nav a {
  display: flex; align-items: center; gap: 10px; padding: 9px 10px; border-radius: var(--radius-s);
  color: var(--fg-2); font-weight: 500; transition: background .12s, color .12s;
}
.nav a:hover { background: var(--bg-3); color: var(--fg); text-decoration: none; }
.nav a { position: relative; }
/* The rail grows from the centre rather than snapping on — cheap, and it makes
   moving between views feel connected rather than like a page load. */
.nav a::before {
  content: ''; position: absolute; left: 0; top: 50%; width: 2.5px; height: 0; border-radius: 2px;
  background: var(--accent); transform: translateY(-50%); transition: height var(--t) var(--e-spring);
}
.nav a.active::before { height: 60%; }
.nav a.active { background: var(--bg-3); color: var(--fg); }
.nav a:active { transform: translateX(1px); }
.nav a .ico { width: 18px; text-align: center; opacity: .8; font-size: 15px; }
.nav .group { margin: 14px 10px 4px; font-family: var(--mono); font-size: 9.5px; letter-spacing: .16em; text-transform: uppercase; color: var(--fg-3); font-weight: 700; }
.nav .chip { margin-left: auto; font-size: 10.5px; padding: 1px 7px; border-radius: 99px; background: var(--bg); border: 1px solid var(--line); color: var(--fg-3); }
.side .foot { margin-top: auto; padding: 10px 8px 0; display: flex; align-items: center; gap: 8px; color: var(--fg-3); font-size: 12px; }
.side .foot .who { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.main { min-width: 0; padding: 26px 32px 60px; }
.topbar {
  display: flex; align-items: center; gap: 12px; margin-bottom: 20px; flex-wrap: wrap;
  position: sticky; top: 0; z-index: 20; padding: 12px 32px; margin: -26px -32px 14px;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: saturate(160%) blur(12px); -webkit-backdrop-filter: saturate(160%) blur(12px);
  border-bottom: 1px solid transparent; transition: border-color var(--t) ease, background var(--t) ease;
}
.topbar.stuck { border-bottom-color: var(--line); }
.topbar h2 { margin: 0; font-size: 22px; letter-spacing: -.02em; font-weight: 700; }
.topbar .sub { color: var(--fg-3); font-size: 13px; }
.topbar .spacer { flex: 1; }

/* ---------- primitives ---------- */
.card {
  background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--radius); padding: 16px 18px;
  box-shadow: var(--shadow-sm);
  transition: border-color var(--t) ease, transform var(--t) var(--e-out), box-shadow var(--t) ease;
}
.card:hover { border-color: var(--line-2); }
.card h3 { margin: 0 0 10px; font-size: 13px; font-weight: 600; color: var(--fg-2); letter-spacing: .01em; display: flex; align-items: center; gap: 8px; }
.card h3 .r { margin-left: auto; font-weight: 500; color: var(--fg-3); font-size: 12px; }
.grid { display: grid; gap: 14px; align-items: start; }
.span2 { grid-column: 1 / -1; }
.g2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.g3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.g4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.stack { display: flex; flex-direction: column; gap: 14px; }
.row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

.tile {
  background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 16px;
  min-height: 92px; display: flex; flex-direction: column; position: relative; overflow: hidden;
  box-shadow: var(--shadow-sm);
  transition: border-color var(--t) ease, transform var(--t) var(--e-out), box-shadow var(--t) ease;
}
/* A one-pixel accent wash along the top edge, revealed on hover. Enough to make
   the tiles feel alive without decorating a page about money. */
.tile::after {
  content: ''; position: absolute; inset: 0 0 auto; height: 2px; background: currentColor;
  opacity: 0; transform: scaleX(.3); transform-origin: left; transition: opacity var(--t) ease, transform var(--t-slow) var(--e-out);
}
.tile:hover { transform: translateY(-2px); border-color: var(--line-2); box-shadow: var(--shadow); }
.tile:hover::after { opacity: .5; transform: scaleX(1); }
/* The class colours `currentColor` for the hover wash above; the children below
   set their own colours, so the tile text never inherits the accent. */
.tile.ok { color: var(--ok); } .tile.warn { color: var(--warn); } .tile.bad { color: var(--bad); } .tile.info { color: var(--info); }
.tile .k { font-family: var(--mono); font-size: 10px; color: var(--fg-2); font-weight: 700; letter-spacing: .14em; text-transform: uppercase; }
.tile .v { font-size: 26px; font-weight: 700; letter-spacing: -.02em; margin-top: 6px; font-variant-numeric: tabular-nums; }
.tile .d { color: var(--fg-3); font-size: 12px; margin-top: auto; padding-top: 6px; }
.tile .k { color: var(--fg-3); } .tile .d { color: var(--fg-3); } .tile .v { color: var(--fg); }
.tile.ok .v { color: var(--ok); } .tile.warn .v { color: var(--warn); } .tile.bad .v { color: var(--bad); } .tile.info .v { color: var(--info); }

.btn {
  display: inline-flex; align-items: center; gap: 6px; padding: 7px 12px; border-radius: var(--radius-s);
  border: 1px solid var(--line-2); background: var(--bg-3); color: var(--fg); cursor: pointer; font-weight: 500; font-size: 13px;
  transition: background var(--t-fast) ease, border-color var(--t-fast) ease, transform var(--t-fast) var(--e-out), box-shadow var(--t-fast) ease;
  white-space: nowrap;
}
.btn:hover { border-color: var(--fg-3); transform: translateY(-1px); }
.btn:active { transform: translateY(0); transition-duration: .05s; }
.btn:focus-visible { outline: none; box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 35%, transparent); }
.btn.primary { background: var(--accent); border-color: transparent; color: var(--accent-fg); }
.btn.primary:hover { filter: brightness(1.08); }
.btn.danger { color: var(--bad); }
.btn.sm { padding: 4px 9px; font-size: 12px; }
.btn.ghost { background: transparent; border-color: transparent; color: var(--fg-2); }
.btn.ghost:hover { background: var(--bg-3); }
.btn:disabled { opacity: .5; cursor: default; }

.pill { display: inline-flex; align-items: center; gap: 5px; padding: 2px 8px; border-radius: 99px; font-size: 11.5px; font-weight: 600; border: 1px solid var(--line-2); color: var(--fg-2); background: var(--bg-3); white-space: nowrap; }
.pill .dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.pill.ok { color: var(--ok); } .pill.warn { color: var(--warn); } .pill.bad { color: var(--bad); } .pill.info { color: var(--info); } .pill.accent { color: var(--accent); }
.tag { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--fg-2); }
.tag i { width: 8px; height: 8px; border-radius: 3px; display: inline-block; }

input[type=text], input[type=number], input[type=date], input[type=datetime-local], input[type=password], input[type=url], select, textarea {
  width: 100%; padding: 8px 10px; border-radius: var(--radius-s); border: 1px solid var(--line-2); background: var(--bg); color: var(--fg); outline: none;
}
input:focus, select:focus, textarea:focus { border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 20%, transparent); }
textarea { min-height: 80px; resize: vertical; }
label.f { display: flex; flex-direction: column; gap: 5px; font-size: 12px; color: var(--fg-3); font-weight: 500; }
label.f.full { grid-column: 1 / -1; }
.form { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.check { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: var(--fg-2); cursor: pointer; }
.check input { width: auto; }

table.t { width: 100%; border-collapse: collapse; font-size: 13px; }
table.t th { text-align: left; font-family: var(--mono); font-size: 10px; text-transform: uppercase; letter-spacing: .12em; color: var(--fg-2); font-weight: 700; padding: 8px 10px; border-bottom: 1px solid var(--line); }
table.t td { padding: 10px; border-bottom: 1px solid var(--line); vertical-align: top; }
table.t tr:last-child td { border-bottom: 0; }
table.t tr.click { cursor: pointer; }
table.t td { transition: background var(--t-fast) ease; }
table.t tr.click:hover td { background: var(--bg-3); }
table.t tr.click:active td { background: var(--line); }
table.t td.num, table.t th.num { text-align: right; font-variant-numeric: tabular-nums; }
.muted { color: var(--fg-3); }
.small { font-size: 12px; }
.mono { font-family: var(--mono); font-size: 12px; }
.money { font-variant-numeric: tabular-nums; }
.empty { color: var(--fg-3); padding: 18px; text-align: center; border: 1px dashed var(--line-2); border-radius: var(--radius-s); }
.note { border-left: 3px solid var(--warn); background: var(--warn-tint); padding: 10px 12px; border-radius: 6px; font-size: 12.5px; color: var(--fg-2); }
.note.info { border-color: var(--accent); background: var(--accent-tint); }
.note.bad { border-color: var(--bad); background: var(--bad-tint); }
hr.sep { border: 0; border-top: 1px solid var(--line); margin: 12px 0; }

/* list items */
.li {
  display: flex; align-items: flex-start; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--line);
  transition: background var(--t-fast) ease, padding-left var(--t-fast) var(--e-out);
  border-radius: 6px;
}
.li:hover { background: var(--bg-3); padding-left: 6px; }
.li .h, .li .s { transition: color var(--t-fast) ease, text-decoration-color var(--t) ease; }
.li:last-child { border-bottom: 0; }
.li .t { flex: 1; min-width: 0; }
.li .t .h { font-weight: 500; }
.li .t .s { color: var(--fg-3); font-size: 12px; margin-top: 2px; }
.li .when { color: var(--fg-3); font-size: 12px; white-space: nowrap; font-variant-numeric: tabular-nums; }
.li.done .h { text-decoration: line-through; color: var(--fg-3); }
.cb {
  width: 18px; height: 18px; border-radius: 6px; border: 1.5px solid var(--line-2); background: transparent;
  cursor: pointer; flex: none; margin-top: 1px; display: grid; place-items: center; color: transparent; font-size: 12px;
  transition: background var(--t-fast) ease, border-color var(--t-fast) ease, transform var(--t) var(--e-spring);
}
.cb:hover { border-color: var(--ok); transform: scale(1.12); }
.cb.on { background: var(--ok); border-color: var(--ok); color: #fff; animation: pop .34s var(--e-spring); }

/* progress bar */
.bar { height: 8px; border-radius: 99px; background: var(--bg-3); overflow: hidden; border: 1px solid var(--line); }
.bar > i { display: block; height: 100%; border-radius: 99px; background: var(--accent); transition: width var(--t-slow) var(--e-out); }

/* ---------- overlay modal (no <dialog>: Safari <15.4 fails silently) ---------- */
.overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,.55); display: grid; place-items: center; z-index: 50; padding: 20px;
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
  animation: fade var(--t) ease both;
}
.overlay.out { animation: fade var(--t-fast) var(--e-in) reverse both; }
.modal {
  background: var(--bg-2); border: 1px solid var(--line-2); border-radius: 16px; width: min(720px, 100%);
  max-height: calc(100vh - 40px); overflow: auto; box-shadow: var(--shadow);
  animation: modalIn var(--t-slow) var(--e-spring) both;
}
.overlay.out .modal { animation: modalIn var(--t-fast) var(--e-in) reverse both; }
.modal .mh { display: flex; align-items: center; gap: 10px; padding: 16px 20px; border-bottom: 1px solid var(--line); position: sticky; top: 0; background: var(--bg-2); z-index: 1; }
.modal .mh h3 { margin: 0; font-size: 16px; }
.modal .mb { padding: 18px 20px; }
.modal .mf { display: flex; gap: 8px; padding: 14px 20px; border-top: 1px solid var(--line); justify-content: flex-end; position: sticky; bottom: 0; background: var(--bg-2); }
.modal .mf .left { margin-right: auto; }

/* drawer */
.drawer-back { z-index: 39; backdrop-filter: none; -webkit-backdrop-filter: none; }
.drawer {
  position: fixed; top: 0; right: 0; bottom: 0; width: min(560px, 100%); background: var(--bg-2);
  border-left: 1px solid var(--line-2); box-shadow: var(--shadow); z-index: 40; overflow: auto;
  animation: slideIn var(--t-slow) var(--e-out) both;
}
.drawer.out { animation: slideIn var(--t) var(--e-in) reverse both; }
/* The drawer's own contents come in just behind the panel, so it reads as one
   movement instead of a panel that arrives already full. */
.drawer .db > .stack > * { animation: fadeUp var(--t-slow) var(--e-out) both; }
.drawer .db > .stack > *:nth-child(1) { animation-delay: .06s; }
.drawer .db > .stack > *:nth-child(2) { animation-delay: .1s; }
.drawer .db > .stack > *:nth-child(3) { animation-delay: .14s; }
.drawer .db > .stack > *:nth-child(n+4) { animation-delay: .18s; }
.drawer .dh { display: flex; align-items: center; gap: 10px; padding: 16px 20px; border-bottom: 1px solid var(--line); position: sticky; top: 0; background: var(--bg-2); }
.drawer .db { padding: 16px 20px 40px; }

/* stage ladder */
.ladder { display: flex; gap: 4px; align-items: center; flex-wrap: wrap; }
.ladder .st {
  padding: 4px 9px; border-radius: 99px; font-size: 11.5px; font-weight: 600; border: 1px solid var(--line-2);
  color: var(--fg-3); cursor: pointer; background: var(--bg);
  transition: background var(--t) ease, color var(--t) ease, border-color var(--t) ease, transform var(--t) var(--e-spring);
}
.ladder .st:hover { transform: translateY(-1px); color: var(--fg); border-color: var(--fg-3); }
.ladder .st.done { color: var(--fg-2); border-color: var(--line-2); background: var(--bg-3); }
.ladder .st.now { color: #fff; background: var(--accent); border-color: transparent; }
.ladder .st.money.now { background: var(--ok); }
.ladder .st.lost.now { background: var(--bad); }

/* calendar month grid */
.cal { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px; }
.cal .dh { font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--fg-3); font-weight: 600; padding: 0 6px 4px; }
.cal .day { min-height: 96px; background: var(--bg-2); border: 1px solid var(--line); border-radius: 10px; padding: 6px; display: flex; flex-direction: column; gap: 4px; }
.cal .day.out { opacity: .45; }
.cal .day.today { border-color: var(--accent); }
.cal .day .n { font-size: 12px; color: var(--fg-3); font-weight: 600; }
.cal .day { transition: border-color var(--t) ease, transform var(--t) var(--e-out); }
.cal .day:hover { border-color: var(--line-2); }
.cal .ev {
  font-size: 11.5px; padding: 3px 6px; border-radius: 6px; background: var(--bg-3); border-left: 3px solid var(--accent);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer;
  transition: transform var(--t-fast) var(--e-out), background var(--t-fast) ease;
}
.cal .ev:hover { transform: translateX(2px); background: var(--line); }
.cal .ev.dim { opacity: .55; border-style: dashed; }

/* agenda */
.agenda .dayh { font-size: 12px; font-weight: 700; color: var(--fg-2); margin: 14px 0 4px; display: flex; gap: 8px; align-items: baseline; }
.agenda .dayh small { color: var(--fg-3); font-weight: 500; }
.agenda .ev { display: flex; gap: 12px; padding: 7px 0; border-bottom: 1px solid var(--line); }
.agenda .ev .tm { width: 92px; flex: none; color: var(--fg-3); font-variant-numeric: tabular-nums; font-size: 12.5px; }
.agenda .ev .ti { flex: 1; }
.agenda .ev .ti .loc { color: var(--fg-3); font-size: 12px; }

/* week hours grid */
.hours .r { display: grid; grid-template-columns: 170px 1fr 120px; gap: 12px; align-items: center; padding: 9px 0; border-bottom: 1px solid var(--line); }
.hours .r:last-child { border-bottom: 0; }

/* iframe apps */
.frame { width: 100%; height: calc(100vh - 110px); border: 1px solid var(--line); border-radius: var(--radius); background: #fff; }

/* sign-in */
.signin { min-height: 100vh; display: grid; place-items: center; padding: 20px; }
.signin .card { width: min(380px, 100%); padding: 28px; }
.signin h1 { margin: 0 0 4px; font-size: 22px; }
.signin p { color: var(--fg-3); margin: 0 0 18px; }
.err { color: var(--bad); font-size: 13px; margin-top: 8px; }

/* toast */
.toast {
  position: fixed; bottom: 18px; left: 50%; background: var(--bg-3); border: 1px solid var(--line-2);
  padding: 9px 14px; border-radius: 10px; box-shadow: var(--shadow); z-index: 60; font-size: 13px;
  animation: toastIn var(--t-slow) var(--e-spring) both;
}
.toast.out { animation: toastIn var(--t) var(--e-in) reverse both; }

/* toggles */
.seg { display: inline-flex; border: 1px solid var(--line-2); border-radius: 9px; overflow: hidden; }
.seg button { padding: 6px 11px; border: 0; background: transparent; color: var(--fg-2); cursor: pointer; font-size: 12.5px; font-weight: 500; transition: background var(--t-fast) ease, color var(--t-fast) ease; }
.seg button:hover { background: var(--bg-3); color: var(--fg); }
.seg button.on { background: var(--bg-3); color: var(--fg); }

/* ---------- phone ---------- */
.menu-btn { display: none; }
@media (max-width: 900px) {
  .shell { grid-template-columns: 1fr; }
  .side { position: fixed; left: 0; top: 0; bottom: 0; width: 260px; z-index: 45; transform: translateX(-100%); transition: transform .18s; }
  .side.open { transform: none; box-shadow: var(--shadow); }
  .main { padding: 16px 16px 60px; }
  .menu-btn { display: inline-flex; }
  .g2, .g3, .g4 { grid-template-columns: 1fr 1fr; }
  .form { grid-template-columns: 1fr; }
  .cal .day { min-height: 60px; }
  .hours .r { grid-template-columns: 1fr; gap: 6px; }
  .frame { height: calc(100vh - 90px); }
}
@media (max-width: 560px) { .g2, .g3, .g4 { grid-template-columns: 1fr; } .topbar h2 { font-size: 19px; } }

/* ==========================================================================
   MOTION
   Entrances only, all short. The rule of thumb: nothing may delay a click, and
   nothing animates twice for the same piece of information.
   ========================================================================== */

@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes fadeUp { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes modalIn { from { opacity: 0; transform: translateY(12px) scale(.97); } to { opacity: 1; transform: none; } }
@keyframes slideIn { from { transform: translateX(100%); } to { transform: none; } }
@keyframes toastIn { from { opacity: 0; transform: translate(-50%, 10px); } to { opacity: 1; transform: translate(-50%, 0); } }
@keyframes pop { 0% { transform: scale(.7); } 60% { transform: scale(1.15); } 100% { transform: scale(1); } }
@keyframes shimmer { from { background-position: -420px 0; } to { background-position: 420px 0; } }
@keyframes spin { to { transform: rotate(360deg); } }

/* View enter. `.enter` is added when the route changes and removed shortly
   after, so re-rendering a list (ticking a task, filtering a table) does NOT
   replay the stagger — which is what makes staggered UIs tiring to use. */
#view { animation: fade var(--t) ease both; }
#view.enter > .stack > *,
#view.enter > .grid > *,
#view.enter > .card { animation: fadeUp var(--t-slow) var(--e-out) both; }
#view.enter > .stack > *:nth-child(1), #view.enter > .grid > *:nth-child(1) { animation-delay: .02s; }
#view.enter > .stack > *:nth-child(2), #view.enter > .grid > *:nth-child(2) { animation-delay: .06s; }
#view.enter > .stack > *:nth-child(3), #view.enter > .grid > *:nth-child(3) { animation-delay: .1s; }
#view.enter > .stack > *:nth-child(4), #view.enter > .grid > *:nth-child(4) { animation-delay: .14s; }
#view.enter > .stack > *:nth-child(n+5), #view.enter > .grid > *:nth-child(n+5) { animation-delay: .17s; }
/* Tiles inside the first row get their own quick cascade. */
#view.enter .grid.g4 > .tile:nth-child(1) { animation-delay: .03s; }
#view.enter .grid.g4 > .tile:nth-child(2) { animation-delay: .07s; }
#view.enter .grid.g4 > .tile:nth-child(3) { animation-delay: .11s; }
#view.enter .grid.g4 > .tile:nth-child(4) { animation-delay: .15s; }

.side .nav a { animation: fadeUp .3s var(--e-out) both; }
.signin .card { animation: modalIn .4s var(--e-spring) both; }

/* ---------- skeletons: shape of the answer, not the word "Loading" ---------- */
.skel { display: grid; gap: 14px; }
.sk {
  border-radius: var(--radius); border: 1px solid var(--line); background: var(--bg-2); position: relative; overflow: hidden;
}
.sk::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--fg) 7%, transparent), transparent);
  background-size: 420px 100%; animation: shimmer 1.2s linear infinite;
}
.sk.tile { min-height: 92px; }
.sk.card { min-height: 190px; }
.sk.row { height: 44px; border-radius: var(--radius-s); }

.spinner {
  width: 14px; height: 14px; border-radius: 50%; border: 2px solid var(--line-2); border-top-color: var(--accent);
  animation: spin .7s linear infinite; display: inline-block; vertical-align: -2px;
}

/* ---------- command palette (⌘K) ---------- */
.pal { position: fixed; inset: 0; z-index: 70; background: rgba(0,0,0,.5); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); padding: 12vh 20px 20px; animation: fade var(--t-fast) ease both; }
.pal.out { animation: fade var(--t-fast) var(--e-in) reverse both; }
.pal-box {
  max-width: 560px; margin: 0 auto; background: var(--bg-2); border: 1px solid var(--line-2); border-radius: 16px;
  box-shadow: var(--shadow); overflow: hidden; animation: modalIn var(--t) var(--e-spring) both;
}
.pal.out .pal-box { animation: modalIn var(--t-fast) var(--e-in) reverse both; }
.pal-box input {
  width: 100%; border: 0; border-bottom: 1px solid var(--line); border-radius: 0; background: transparent;
  padding: 15px 18px; font-size: 15px;
}
.pal-box input:focus { box-shadow: none; border-color: var(--line); }
.pal-list { max-height: 46vh; overflow: auto; padding: 6px; }
.pal-list .it {
  display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-radius: var(--radius-s); cursor: pointer;
  color: var(--fg-2); transition: background var(--t-fast) ease, color var(--t-fast) ease;
}
.pal-list .it .ico { width: 18px; text-align: center; opacity: .8; }
.pal-list .it .sub { margin-left: auto; font-size: 11.5px; color: var(--fg-3); }
.pal-list .it.on { background: var(--bg-3); color: var(--fg); box-shadow: inset 2.5px 0 0 var(--accent); }
.pal-foot { display: flex; gap: 12px; padding: 9px 16px; border-top: 1px solid var(--line); color: var(--fg-3); font-size: 11.5px; }
kbd {
  font-family: var(--mono); font-size: 10.5px; padding: 1.5px 5px; border-radius: 5px;
  border: 1px solid var(--line-2); background: var(--bg); color: var(--fg-2);
}

/* ---------- accessibility ----------
   Anyone who has asked their system to stop moving things gets a static UI.
   Opacity fades stay: they carry no motion and keep state changes legible. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
  .btn:hover, .tile:hover, .li:hover { transform: none !important; }
}

/* A card with nothing in it should say so in one quiet line, not draw a big
   dashed box around the absence. `.empty` stays for genuinely empty screens. */
.quiet { color: var(--fg-3); font-size: 13px; padding: 6px 0 2px; }

/* ==========================================================================
   THE DOORS
   A pair of plain white wooden shoji doors that slide apart once you sign in.
   Purely decorative and deliberately brief — it covers the moment the app is
   rendering behind them, so it costs nothing in time.

   Built from gradients rather than an image: it stays crisp at any size, adds
   no request, and the lattice can be re-spaced with one variable.
   ========================================================================== */
.doors {
  position: fixed; inset: 0; z-index: 90; pointer-events: none; overflow: hidden;
  --paper: #FCFAF5;        /* washi — warm, not clinical */
  --wood:  #F1EDE4;        /* the plain white timber frame */
  --wood-edge: #DFD7C7;
  --lattice: #E7E0D1;      /* kumiko */
  --cell-h: 88px;
  --cell-w: 104px;
}
/* A touch less glare when the app behind is dark. */
:root[data-theme="dark"] .doors { filter: brightness(.92); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .doors { filter: brightness(.92); } }

.doors .door {
  position: absolute; top: -2%; bottom: -2%; width: 50.6%;
  background: var(--wood);
  border: 1px solid var(--wood-edge);
  padding: 16px;
  /* Slow to start, decisive through the middle — how a heavy sliding door
     actually behaves. A plain ease looks like a slideshow transition. */
  transition: transform 1.05s cubic-bezier(.62, .02, .34, 1);
  will-change: transform;
}
.doors .door.l { left: 0;  box-shadow: 14px 0 34px rgba(24, 20, 12, .22); }
.doors .door.r { right: 0; box-shadow: -14px 0 34px rgba(24, 20, 12, .22); }
.doors.open .door.l { transform: translateX(-101.5%); }
.doors.open .door.r { transform: translateX(101.5%); }

/* The paper, with its lattice drawn straight onto it. */
.doors .panel {
  height: 100%; width: 100%;
  background-color: var(--paper);
  background-image:
    repeating-linear-gradient(to bottom, transparent 0 calc(var(--cell-h) - 3px), var(--lattice) calc(var(--cell-h) - 3px) var(--cell-h)),
    repeating-linear-gradient(to right,  transparent 0 calc(var(--cell-w) - 3px), var(--lattice) calc(var(--cell-w) - 3px) var(--cell-w));
  box-shadow: inset 0 0 60px rgba(120, 104, 74, .07);
}
/* The stile down the meeting edge, so the two doors read as a closed pair. */
.doors .door.l .panel { border-right: 5px solid var(--wood); }
.doors .door.r .panel { border-left: 5px solid var(--wood); }

/* The finger pull — a small recess, the one detail that makes it a door. */
.doors .pull {
  position: absolute; top: 50%; width: 11px; height: 46px; border-radius: 6px;
  background: linear-gradient(to right, rgba(140,124,94,.16), rgba(140,124,94,.05));
  border: 1px solid var(--wood-edge); transform: translateY(-50%);
}
.doors .door.l .pull { right: 26px; }
.doors .door.r .pull { left: 26px; }

/* Anyone who has asked for less motion gets the app, not the theatre. */
@media (prefers-reduced-motion: reduce) { .doors { display: none; } }
/* ---------- Home's petal field ----------
   Static, scattered, drawn once. The falling version was dropped on 2026-09-23
   (Tom: "we've got to quit those") — motion in the background competes with the
   numbers in front of it, which is the opposite of what a money screen needs.

   ⚠️ Colours go in RAW and are URL-encoded exactly once. Pre-encoding the '#'
   and then quoting gives %2523…, an invalid colour, and SVG silently falls back
   to no paint at all. That cost a round trip; don't repeat it. */
:root {
  --art-petals: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%271600%27%20height%3D%271000%27%20viewBox%3D%270%200%201600%201000%27%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%28982%2C939%29%20rotate%2860%29%20scale%2810.7%29%27%20fill%3D%27%23E9A6BF%27%20opacity%3D%270.78%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%28175%2C398%29%20rotate%28198%29%20scale%289.1%29%27%20fill%3D%27%23E9A6BF%27%20opacity%3D%270.87%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%281225%2C802%29%20rotate%28230%29%20scale%2813.9%29%27%20fill%3D%27%23EBAFC6%27%20opacity%3D%270.84%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%28833%2C636%29%20rotate%28246%29%20scale%2816.7%29%27%20fill%3D%27%23F0B8CC%27%20opacity%3D%270.65%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%28172%2C372%29%20rotate%28308%29%20scale%2810.5%29%27%20fill%3D%27%23E9A6BF%27%20opacity%3D%270.66%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%28950%2C834%29%20rotate%28198%29%20scale%2812.4%29%27%20fill%3D%27%23F7CEDC%27%20opacity%3D%270.77%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%28493%2C691%29%20rotate%2877%29%20scale%2811.6%29%27%20fill%3D%27%23F7CEDC%27%20opacity%3D%270.59%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%28944%2C417%29%20rotate%28151%29%20scale%2816.8%29%27%20fill%3D%27%23E9A6BF%27%20opacity%3D%270.77%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%281351%2C801%29%20rotate%28175%29%20scale%2812.6%29%27%20fill%3D%27%23EBAFC6%27%20opacity%3D%270.63%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%2834%2C876%29%20rotate%2841%29%20scale%2816.3%29%27%20fill%3D%27%23F7CEDC%27%20opacity%3D%270.56%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%28330%2C765%29%20rotate%2873%29%20scale%288.6%29%27%20fill%3D%27%23F0B8CC%27%20opacity%3D%270.59%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%281520%2C389%29%20rotate%2857%29%20scale%2812.2%29%27%20fill%3D%27%23E9A6BF%27%20opacity%3D%270.62%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%28873%2C8%29%20rotate%2890%29%20scale%2815.6%29%27%20fill%3D%27%23F7CEDC%27%20opacity%3D%270.88%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%28297%2C176%29%20rotate%2877%29%20scale%289.2%29%27%20fill%3D%27%23F0B8CC%27%20opacity%3D%270.66%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%2887%2C643%29%20rotate%28239%29%20scale%2812.6%29%27%20fill%3D%27%23F7CEDC%27%20opacity%3D%270.74%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%28652%2C961%29%20rotate%28153%29%20scale%289.1%29%27%20fill%3D%27%23F0B8CC%27%20opacity%3D%270.66%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%281349%2C938%29%20rotate%28340%29%20scale%2814.5%29%27%20fill%3D%27%23F7CEDC%27%20opacity%3D%270.79%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%281200%2C475%29%20rotate%28300%29%20scale%2816.6%29%27%20fill%3D%27%23E9A6BF%27%20opacity%3D%270.70%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%28976%2C573%29%20rotate%28312%29%20scale%2812.0%29%27%20fill%3D%27%23F0B8CC%27%20opacity%3D%270.89%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%281398%2C389%29%20rotate%28192%29%20scale%288.9%29%27%20fill%3D%27%23EBAFC6%27%20opacity%3D%270.75%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%281403%2C850%29%20rotate%2853%29%20scale%288.1%29%27%20fill%3D%27%23E9A6BF%27%20opacity%3D%270.79%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%28101%2C589%29%20rotate%28259%29%20scale%288.8%29%27%20fill%3D%27%23F0B8CC%27%20opacity%3D%270.78%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%28124%2C513%29%20rotate%28323%29%20scale%2816.0%29%27%20fill%3D%27%23F0B8CC%27%20opacity%3D%270.81%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%28593%2C203%29%20rotate%2899%29%20scale%2812.7%29%27%20fill%3D%27%23F0B8CC%27%20opacity%3D%270.66%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%28433%2C329%29%20rotate%2896%29%20scale%2810.6%29%27%20fill%3D%27%23F7CEDC%27%20opacity%3D%270.76%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%28562%2C277%29%20rotate%2819%29%20scale%2811.8%29%27%20fill%3D%27%23E9A6BF%27%20opacity%3D%270.68%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%281235%2C90%29%20rotate%2858%29%20scale%2816.9%29%27%20fill%3D%27%23F7CEDC%27%20opacity%3D%270.72%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%28653%2C512%29%20rotate%28188%29%20scale%289.3%29%27%20fill%3D%27%23F7CEDC%27%20opacity%3D%270.70%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%28762%2C189%29%20rotate%28172%29%20scale%2816.6%29%27%20fill%3D%27%23F7CEDC%27%20opacity%3D%270.96%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%28456%2C974%29%20rotate%28339%29%20scale%2811.6%29%27%20fill%3D%27%23EBAFC6%27%20opacity%3D%270.64%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%28243%2C431%29%20rotate%28264%29%20scale%288.0%29%27%20fill%3D%27%23EBAFC6%27%20opacity%3D%270.65%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%281182%2C170%29%20rotate%28241%29%20scale%2816.1%29%27%20fill%3D%27%23E9A6BF%27%20opacity%3D%270.76%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%28796%2C233%29%20rotate%28183%29%20scale%289.7%29%27%20fill%3D%27%23EBAFC6%27%20opacity%3D%270.73%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%281470%2C408%29%20rotate%28300%29%20scale%2813.0%29%27%20fill%3D%27%23EBAFC6%27%20opacity%3D%270.85%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%28367%2C868%29%20rotate%28217%29%20scale%2813.3%29%27%20fill%3D%27%23EBAFC6%27%20opacity%3D%270.92%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%28779%2C838%29%20rotate%28348%29%20scale%2815.2%29%27%20fill%3D%27%23E9A6BF%27%20opacity%3D%270.80%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%281584%2C907%29%20rotate%28116%29%20scale%2815.1%29%27%20fill%3D%27%23F7CEDC%27%20opacity%3D%270.65%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%2815%2C88%29%20rotate%28281%29%20scale%2812.0%29%27%20fill%3D%27%23F0B8CC%27%20opacity%3D%270.76%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%28570%2C525%29%20rotate%28282%29%20scale%2812.6%29%27%20fill%3D%27%23F0B8CC%27%20opacity%3D%270.88%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%281043%2C900%29%20rotate%28266%29%20scale%2812.2%29%27%20fill%3D%27%23E9A6BF%27%20opacity%3D%270.71%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%281167%2C813%29%20rotate%28241%29%20scale%2816.1%29%27%20fill%3D%27%23F7CEDC%27%20opacity%3D%270.73%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%281131%2C665%29%20rotate%28208%29%20scale%2811.5%29%27%20fill%3D%27%23EBAFC6%27%20opacity%3D%270.76%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%28613%2C769%29%20rotate%28112%29%20scale%289.6%29%27%20fill%3D%27%23F0B8CC%27%20opacity%3D%270.63%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%281581%2C272%29%20rotate%28162%29%20scale%289.1%29%27%20fill%3D%27%23F0B8CC%27%20opacity%3D%270.69%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%28740%2C105%29%20rotate%28186%29%20scale%2813.8%29%27%20fill%3D%27%23E9A6BF%27%20opacity%3D%270.60%27%2F%3E%3Cpath%20d%3D%27M0%2C-1%20C0.95%2C-0.55%200.72%2C0.72%200%2C1%20C-0.72%2C0.72%20-0.95%2C-0.55%200%2C-1%20Z%27%20transform%3D%27translate%28992%2C173%29%20rotate%28286%29%20scale%2810.8%29%27%20fill%3D%27%23E9A6BF%27%20opacity%3D%270.88%27%2F%3E%3C%2Fsvg%3E");
  --art-petals-opacity: .62;
  --art-car-stroke: #163a5f;
  --art-car-opacity: .30;
}
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) {
  --art-petals-opacity: .34;
  --art-car-stroke: #7ea6ff;
  --art-car-opacity: .34;
} }
:root[data-theme="dark"] {
  --art-petals-opacity: .34;
  --art-car-stroke: #7ea6ff;
  --art-car-opacity: .34;
}

/* The art layer sits behind everything and never intercepts a click. `data-art`
   is set per view by the router — Home and the money tab only. The deal
   pipelines are deliberately plain: clients and callers sign in to those. */
.main { position: relative; }
.main::before { content: ''; position: fixed; pointer-events: none; z-index: 0; }
#view, .topbar { position: relative; z-index: 1; }

[data-art="home"] .main::before {
  left: var(--sidebar); right: 0; top: 0; bottom: 0;
  background: var(--art-petals) no-repeat center / cover;
  opacity: var(--art-petals-opacity);
}
@media (max-width: 900px) { [data-art] .main::before { left: 0; } }

/* ---------- the car ----------
   Original line art, drawn here rather than sourced: a low rear-engined coupé
   silhouette. Deliberately NO crest and no wordmark — that is someone else's
   trademark and it is not going in a product. It is the shape, as a goal.

   Admin views only, so a client never sees it. On the money tab it draws
   itself in like a configurator reveal; elsewhere it is a still watermark. */
.car-wrap {
  /* In the flow, after the last card, not fixed behind opaque ones. Fixed at
     13% opacity it was invisible in practice (Tom, 2026-09-23: "I still can't
     see the Porsche"), because every card on this page is solid white. Here it
     has the page's own empty space to itself. */
  display: block; margin: 26px 0 8px auto; width: min(560px, 62vw);
  pointer-events: none; opacity: var(--art-car-opacity);
}
.car-wrap .car { display: block; width: 100%; height: auto; overflow: visible; }
.car-wrap .car path, .car-wrap .car circle {
  fill: none; stroke: var(--art-car-stroke); stroke-width: 3.4;
  stroke-linecap: round; stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}
/* The reveal: every line has its own dash length set in JS, then the offset is
   walked to zero. Staggered so the body leads and the details follow. */
.car-wrap.draw .car path, .car-wrap.draw .car circle {
  animation: drawIn 1.5s cubic-bezier(.3, .5, .25, 1) both;
}
.car-wrap.draw .car > *:nth-child(1) { animation-delay: .05s; }
.car-wrap.draw .car > *:nth-child(2) { animation-delay: .38s; }
.car-wrap.draw .car > *:nth-child(3) { animation-delay: .52s; }
.car-wrap.draw .car > *:nth-child(4) { animation-delay: .60s; }
.car-wrap.draw .car > *:nth-child(5) { animation-delay: .66s; }
.car-wrap.draw .car > *:nth-child(6) { animation-delay: .70s; }
.car-wrap.draw .car > *:nth-child(n+7) { animation-delay: .46s; }
@keyframes drawIn { from { stroke-dashoffset: var(--len); } to { stroke-dashoffset: 0; } }

@media (max-width: 900px) { .car-wrap { display: none; } }
@media (prefers-reduced-motion: reduce) { .car-wrap.draw .car path, .car-wrap.draw .car circle { animation: none; } }

/* ---------- the money source chart ---------- */
.mchart { display: flex; gap: 6px; align-items: stretch; height: 140px; }
.mchart .mcol { flex: 1; display: flex; align-items: flex-end; }
.mchart .stackcol {
  width: 100%; height: 100%; display: flex; flex-direction: column-reverse; justify-content: flex-start;
  gap: 1px; border-radius: 5px; overflow: hidden;
}
.mchart .mcol.now .stackcol { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 6px; }
.mlabels { display: flex; gap: 6px; margin-top: 8px; }
.mlabels .mlabel {
  flex: 1; text-align: center; font-size: 9.5px; color: var(--fg-3);
  display: flex; flex-direction: column; gap: 2px; line-height: 1.25;
}
.mlabels .mlabel span { font-family: var(--mono); font-size: 9px; color: var(--fg-3); }
.mlabels .mlabel.now { color: var(--fg); font-weight: 700; }
.mlabels .mlabel.now span { color: var(--fg-2); }

/* A tile you can open says so. */
.tile.drill { cursor: pointer; }
.tile.drill:hover { border-color: var(--accent); }
.tile.drill::before {
  content: '›'; position: absolute; right: 12px; top: 10px; color: var(--fg-3);
  font-size: 15px; opacity: 0; transition: opacity var(--t) ease, transform var(--t) var(--e-out);
}
.tile.drill:hover::before { opacity: .8; transform: translateX(2px); }

/* ---------- the drop box ---------- */
.drop {
  border: 1.5px dashed var(--line-2); border-radius: var(--radius); padding: 18px; text-align: center;
  cursor: pointer; margin-bottom: 10px; background: var(--bg-3);
  transition: border-color var(--t) ease, background var(--t) ease, transform var(--t) var(--e-out);
}
.drop:hover { border-color: var(--accent); }
.drop.over { border-color: var(--accent); background: var(--accent-tint); transform: scale(1.01); }
.drop.busy { border-style: solid; border-color: var(--accent); cursor: progress; }
.drop .dzi b { display: block; font-size: 13.5px; margin-bottom: 2px; }
.drop .dzp { margin-top: 10px; color: var(--fg-2); }
.card.click:hover { border-color: var(--accent); }
