Source
This app’s code and revision history are public. Download a copy or explore the files below.
Public
The app’s code and revision history are public.
Run it yourself
Take the whole tree and run it on your own machine. The download needs no account. Cloning needs a sign-in.
Download .zip
bounded clone 703ed60f2cc5ad3d98a5bf4a
A copy you download is not bounded. The guarantees this app runs under - declared egress, proven invariants, writes that fail closed - live in the runtime serving this page, not in the files. What you get is auditable source you can read and run, with no runtime guarantees attached.
src/styles.css
/* Time. Shared look comes from /kit.css; this is the app's own layout. Phones first. */
body.app-mode .landing-only { display: none !important; }
body:not(.app-mode) #app:empty { display: none; }
body.app-mode .site-foot { display: none; }
body.app-mode .site-nav { display: none; }
.page-pad { padding-block: 56px 80px; }
.loading { display: flex; align-items: center; gap: 12px; color: var(--muted); padding: 32px 0; }
.small { font-size: 14px; }
.grow { flex: 1; min-width: 0; }
.num { text-align: right !important; font-variant-numeric: tabular-nums; white-space: nowrap; }
.strong { font-weight: 650; }
.clip { max-width: 0; width: 60%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.self-start { justify-self: start; align-self: flex-start; }
.link-btn { padding: 0; border: 0; background: none; color: var(--cobalt); font: inherit; cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }
.section-sm { margin-top: 32px; display: grid; gap: 12px; }
.plain-list { padding-left: 1.2em; display: grid; gap: 6px; color: #3d4148; font-size: 15px; }
.brand-app { color: var(--muted); font-weight: 500; }
.brand-sep { color: var(--line-strong); font-weight: 300; }
.nav-cta { background: var(--ink-solid); color: #fff !important; }
.nav-cta:hover { background: #2a2c31 !important; }
@media (max-width: 420px) { .brand-word { display: none; } }
@media (max-width: 600px) { .hide-sm { display: none; } }
/* Landing hero with the start box */
.app-hero { padding: 40px 0 72px; background: linear-gradient(180deg, #faf6ee 0%, #fdfdfc 100%); border-bottom: 1px solid #f0ebe1; }
.app-hero-grid { display: grid; grid-template-columns: minmax(0, 1fr) 420px; grid-template-areas: "text start" "more start"; column-gap: 56px; align-items: center; }
.hero-text { grid-area: text; align-self: end; }
.hero-more { grid-area: more; align-self: start; }
#start { grid-area: start; }
.app-hero h1 { margin-top: 14px; }
.app-hero .lede { margin-top: 18px; }
.hero-points { list-style: none; padding: 0; margin-top: 26px; display: grid; gap: 10px; font-size: 15.5px; color: #3c4048; }
.hero-points li { display: flex; gap: 10px; align-items: baseline; }
.hero-points li::before { content: ""; flex: 0 0 8px; height: 8px; border-radius: 50%; background: var(--cobalt); transform: translateY(-2px); }
.hero-art { width: 210px; height: auto; margin-bottom: -6px; }
@media (max-width: 900px) {
.app-hero-grid { grid-template-columns: minmax(0, 1fr); grid-template-areas: "text" "start" "more"; row-gap: 24px; }
.app-hero { padding-top: 16px; }
.hero-art { width: 150px; }
.app-hero .lede { margin-top: 4px; }
}
.start { padding: 22px; display: grid; gap: 12px; }
.start-label { font: 600 15px/1.3 var(--sans); color: var(--ink); }
.start-input { min-height: 54px; font-size: 17px; }
.start-running { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: 15px; }
.start-running strong { font: 500 28px/1 var(--sans); font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
/* Landing sections */
.steps { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 28px; margin-top: 28px; padding: 0; counter-reset: step; }
.steps li { list-style: none; counter-increment: step; }
.steps li::before { content: counter(step); display: grid; place-items: center; width: 34px; height: 34px; margin-bottom: 14px; border-radius: 50%; background: var(--ink-solid); color: #fff; font: 650 15px var(--sans); }
.steps h3, .features h3 { font: 600 18px/1.3 var(--sans); }
.steps p, .features p { margin-top: 8px; color: #4a4e56; }
.features { list-style: none; padding: 0; margin-top: 26px; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
.features li { padding: 20px; border: 1px solid var(--line); border-radius: 16px; background: #fff; }
.two-up { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
.who { padding: 24px; display: grid; gap: 10px; align-content: start; }
.who p:last-child { color: #4a4e56; }
@media (max-width: 860px) { .steps, .features, .two-up { grid-template-columns: minmax(0, 1fr); } }
.api-grid { display: grid; grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr); gap: 40px; align-items: start; }
.api-grid .code { font-size: 12.5px; }
@media (max-width: 900px) { .api-grid { grid-template-columns: minmax(0, 1fr); } }
.more-apps { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px; list-style: none; padding: 0; margin-top: 22px; }
.more-apps a { display: grid; gap: 4px; padding: 16px 18px; border: 1px solid var(--line); border-radius: 14px; background: #fff; color: var(--ink); }
.more-apps a:hover { border-color: var(--line-strong); box-shadow: var(--shadow); color: var(--ink); }
.more-apps strong { font: 400 22px/1.1 var(--serif); }
.more-apps span { color: var(--muted); font-size: 14px; }
.compare td:first-child { font-weight: 600; }
.compare { min-width: 680px; }
/* Running timer in the header */
#head-timer { margin-left: auto; min-width: 0; }
body:not(.app-mode) #head-timer { display: none; }
.head-timer { display: flex; align-items: center; gap: 2px; min-width: 0; padding: 3px 3px 3px 10px; border-radius: 12px; background: var(--paper-warm); border: 1px solid #ece2cf; }
.head-clock { display: flex; align-items: center; gap: 8px; min-width: 0; color: var(--ink); font: 600 14px/1 var(--sans); }
.head-clock:hover { color: var(--ink-solid); }
.head-time { font-variant-numeric: tabular-nums; }
.head-label { max-width: 26vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--muted); font-weight: 500; }
.head-stop { width: 32px; height: 32px; color: var(--brick); }
.pulse { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--brick); animation: pulse 1.6s ease-in-out infinite; }
@keyframes pulse { 50% { opacity: .35; } }
@media (max-width: 480px) { .head-label { display: none; } }
/* App shell: tab bar on phones, side navigation on wide screens */
.shell { width: var(--page); margin-inline: auto; padding: 20px 0 110px; display: grid; grid-template-columns: minmax(0, 1fr); gap: 24px; }
.shell-main { min-width: 0; }
.side-nav { display: none; }
.tab-bar { position: fixed; left: 0; right: 0; bottom: 0; z-index: 30; display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); padding: 6px 6px calc(6px + env(safe-area-inset-bottom)); background: #fdfdfcf2; -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); border-top: 1px solid var(--line); }
.tab-bar a { display: grid; justify-items: center; gap: 3px; min-height: 52px; padding: 6px 0; border-radius: 12px; color: var(--muted); font: 600 11.5px/1 var(--sans); }
.tab-bar a[aria-current="page"] { color: var(--cobalt-ink); background: var(--cobalt-wash); }
@media (min-width: 960px) {
.shell { grid-template-columns: 190px minmax(0, 1fr); padding-bottom: 80px; }
.tab-bar { display: none; }
.side-nav { display: grid; align-content: start; gap: 4px; position: sticky; top: 84px; height: max-content; }
.side-nav a { display: flex; align-items: center; gap: 12px; min-height: 46px; padding: 0 14px; border-radius: 12px; border: 1px solid transparent; color: #33363c; font: 600 15px/1 var(--sans); }
.side-nav a:hover { background: #0000000a; color: var(--ink-solid); }
.side-nav a[aria-current="page"] { color: var(--cobalt-ink); background: var(--cobalt-wash); border-color: #d1ddf5; }
}
.page { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; align-content: start; min-width: 0; }
.page-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.page-title { font: 360 clamp(30px, 3.4vw, 40px)/1.1 var(--serif); letter-spacing: -.025em; }
.narrow-page { max-width: 560px; }
/* Timer bar */
.timer-bar { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; padding: 12px; }
.timer-bar.running { border-color: #e7d9bd; background: #fffdf8; }
.timer-input { width: 100%; min-width: 0; min-height: 48px; padding: 8px 10px; border: 0; border-radius: 10px; background: transparent; font: 500 17px/1.3 var(--sans); }
.timer-input:focus { outline: none; background: var(--panel); }
.timer-input::placeholder { color: #9a9ea6; }
.timer-controls { display: flex; align-items: center; gap: 6px; min-width: 0; }
.timer-clock { min-width: 92px; padding: 0 6px; border: 0; background: none; font: 500 22px/1 var(--sans); font-variant-numeric: tabular-nums; letter-spacing: -.01em; text-align: right; color: var(--ink); cursor: pointer; border-radius: 8px; min-height: 40px; }
.timer-clock:hover { background: #0000000a; }
.timer-clock.idle { color: var(--faint); cursor: default; display: inline-flex; align-items: center; justify-content: flex-end; }
.timer-go { min-width: 104px; }
.timer-go.stop { background: var(--brick); border-color: var(--brick); }
.timer-go.stop:hover { background: #8f3824; }
@media (min-width: 760px) {
.timer-bar { grid-template-columns: minmax(0, 1fr) auto; align-items: center; padding: 10px 10px 10px 14px; }
.timer-controls .grow { display: none; }
}
@media (max-width: 400px) { .timer-clock { min-width: 0; font-size: 19px; } .timer-go { min-width: 0; padding: 0 14px; } }
/* Pickers and popovers */
.picker { position: relative; min-width: 0; }
.pick-btn { display: inline-flex; align-items: center; gap: 7px; max-width: 100%; min-height: 40px; min-width: 40px; padding: 0 10px; border: 1px solid transparent; border-radius: 10px; background: none; color: var(--muted); font: 600 14px/1 var(--sans); cursor: pointer; justify-content: center; }
.pick-btn:hover { background: #0000000a; color: var(--ink); }
.pick-btn.on { color: var(--ink); background: var(--panel); border-color: var(--panel-line); }
.pick-text { max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 480px) { .timer-controls .pick-text { max-width: 90px; } }
@media (max-width: 600px) { .timer-controls .pick-label { display: none; } }
.bill-sym { font: 650 15px/1 var(--sans); }
.pick-btn.bill.on { color: #2f5a3c; background: var(--sage-wash); border-color: #cfe2d4; }
.pop { position: absolute; top: calc(100% + 6px); z-index: 70; width: min(320px, calc(100vw - 32px)); max-height: min(420px, 60vh); display: flex; flex-direction: column; gap: 6px; padding: 8px; border: 1px solid var(--line); border-radius: 14px; background: #fff; box-shadow: 0 18px 50px -14px #0004; }
.pop-left { left: 0; }
.pop-right { right: 0; }
.pop-search { min-height: 40px; padding: 8px 10px; font-size: 15px; }
.pop-list { list-style: none; padding: 0; margin: 0; overflow-y: auto; display: grid; }
.pop-list ul { list-style: none; padding: 0; }
.pop-group { padding: 8px 8px 2px; font: 650 11px/1.2 var(--sans); letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.pop-item { display: flex; align-items: center; gap: 9px; width: 100%; min-height: 40px; padding: 6px 8px; border: 0; border-radius: 8px; background: none; text-align: left; font: 500 15px/1.25 var(--sans); color: var(--ink); cursor: pointer; }
.pop-item:hover { background: var(--panel); }
.pop-item input { width: 17px; height: 17px; accent-color: var(--ink-solid); }
.pop-item svg { margin-left: auto; color: var(--cobalt); }
.pop-empty { padding: 8px; color: var(--muted); font-size: 14px; }
.pop-create { display: flex; align-items: center; gap: 8px; min-height: 40px; padding: 6px 8px; border: 0; border-top: 1px solid var(--line); background: none; color: var(--cobalt-ink); font: 600 14.5px/1.2 var(--sans); cursor: pointer; text-align: left; }
.pop-create:hover { background: var(--cobalt-wash); }
/* Projects as labels */
.dot { flex: none; width: 10px; height: 10px; border-radius: 50%; }
.dot-lg { width: 14px; height: 14px; }
.proj { display: inline-flex; align-items: center; gap: 7px; min-width: 0; max-width: 100%; }
.proj-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.proj-client { color: var(--muted); font-weight: 400; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tag-chip { display: inline-flex; align-items: center; min-height: 22px; padding: 0 8px; border-radius: 99px; background: var(--panel); border: 1px solid var(--panel-line); color: #3c4048; font: 600 12px/1 var(--sans); white-space: nowrap; }
.bill-mark { display: grid; place-items: center; width: 22px; height: 22px; border-radius: 6px; background: var(--sage-wash); color: #2f5a3c; font: 650 12.5px/1 var(--sans); }
/* Recent entries */
.timer-sub { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.totals { display: flex; gap: 16px; color: var(--muted); font-size: 14.5px; }
.totals strong { color: var(--ink); font-weight: 650; font-variant-numeric: tabular-nums; }
.days { display: grid; gap: 20px; }
.day-label { display: flex; justify-content: space-between; gap: 12px; margin-bottom: 8px; padding: 0 4px; font: 650 12px/1 var(--sans); letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.day-label span:last-child { font-variant-numeric: tabular-nums; letter-spacing: .02em; color: #3c4048; }
.entry-list { list-style: none; padding: 0; border: 1px solid var(--line); border-radius: 14px; background: #fff; overflow: hidden; }
.entry { display: flex; align-items: center; }
.entry + .entry { border-top: 1px solid var(--line); }
.entry-main { flex: 1; min-width: 0; display: flex; align-items: center; gap: 12px; padding: 12px 6px 12px 16px; border: 0; background: none; text-align: left; cursor: pointer; color: var(--ink); }
.entry-main:hover { background: #fafbfc; }
.entry-what { flex: 1; min-width: 0; display: grid; gap: 4px; }
.entry-desc { font: 600 15.5px/1.3 var(--sans); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.entry-desc.muted { font-weight: 500; }
.entry-meta { display: flex; align-items: center; gap: 6px; min-width: 0; font-size: 13.5px; overflow: hidden; }
.entry-side { display: flex; align-items: center; gap: 12px; flex: none; }
.entry-span { color: var(--muted); font-size: 13.5px; font-variant-numeric: tabular-nums; }
.entry-dur { min-width: 64px; text-align: right; font: 600 15px/1 var(--sans); font-variant-numeric: tabular-nums; }
.entry-play { flex: none; margin-right: 6px; color: var(--muted); }
.entry-play:hover { color: var(--ink-solid); }
@media (max-width: 640px) { .entry-span { display: none; } .entry-meta .tag-chip { display: none; } .entry-side { gap: 8px; } .entry-main { padding-left: 12px; } }
@media (max-width: 480px) { .entry-meta .proj-client { display: none; } }
.empty { display: grid; justify-items: center; gap: 10px; padding: 36px 20px; border: 1px dashed var(--line-strong); border-radius: 16px; text-align: center; }
.empty .btn { margin-top: 8px; }
.empty-art { width: 170px; height: auto; }
/* Sheets */
.modal-backdrop { position: fixed; inset: 0; z-index: 60; display: grid; place-items: center; padding: 20px; background: #15171b66; animation: fade .15s ease; overflow: hidden; }
.modal { display: flex; flex-direction: column; width: min(560px, 100%); max-height: min(88vh, 900px); border-radius: 18px; background: #fff; box-shadow: 0 30px 80px -20px #0006; animation: rise .18s ease; }
.modal-wide { width: min(720px, 100%); }
.modal-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 18px 20px 6px; }
.modal-title { font: 400 26px/1.2 var(--serif); letter-spacing: -.015em; min-width: 0; overflow-wrap: anywhere; }
.modal-body { padding: 12px 20px 20px; overflow-y: auto; }
.modal-foot { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 14px 20px calc(14px + env(safe-area-inset-bottom)); border-top: 1px solid var(--line); }
.icon-btn { display: grid; place-items: center; flex: none; width: 38px; height: 38px; border: 0; border-radius: 10px; background: none; cursor: pointer; color: var(--muted); }
.icon-btn:hover { background: #0000000a; color: var(--ink); }
@keyframes fade { from { opacity: 0; } }
@keyframes rise { from { opacity: 0; transform: translateY(10px); } }
@media (max-width: 600px) {
.modal-backdrop { place-items: end stretch; padding: 0; }
.modal, .modal-wide { width: 100%; max-height: 92vh; border-radius: 18px 18px 0 0; }
.modal-foot .btn { padding: 0 14px; }
}
.two { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
@media (max-width: 480px) { .two { grid-template-columns: minmax(0, 1fr); } }
.entry-picks { display: flex; flex-wrap: wrap; gap: 6px; }
.entry-picks .pick-btn { border-color: var(--line); }
.time-grid { display: grid; grid-template-columns: 1.3fr 1fr 1fr 1fr; gap: 10px; }
@media (max-width: 560px) { .time-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.time-grid .input { padding-inline: 10px; }
.money-input { display: flex; align-items: center; border: 1px solid var(--line-strong); border-radius: var(--radius); background: #fff; }
.money-input:focus-within { border-color: var(--cobalt); box-shadow: 0 0 0 3px #2e5ec41f; }
.money-input > span { padding-left: 12px; color: var(--muted); font: 600 14px var(--sans); }
.money-input .input { border: 0; box-shadow: none !important; }
.segmented { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 4px; padding: 4px; border-radius: 12px; background: var(--panel); border: 1px solid var(--panel-line); }
.segmented button { min-height: 38px; padding: 0 8px; border: 0; border-radius: 9px; background: transparent; cursor: pointer; font: 600 14px var(--sans); color: var(--muted); }
.segmented button[aria-checked="true"] { background: #fff; color: var(--ink-solid); box-shadow: 0 1px 3px #0000001a; }
fieldset.plain { border: 0; padding: 0; margin: 0; min-width: 0; }
.swatches { display: flex; flex-wrap: wrap; gap: 8px; }
.swatch { width: 34px; height: 34px; border-radius: 50%; border: 0; cursor: pointer; box-shadow: inset 0 0 0 2px #fff0; }
.swatch[aria-pressed="true"] { box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--ink-solid); }
.link-row { display: flex; align-items: center; gap: 8px; min-width: 0; }
.link-code { flex: 1; min-width: 0; padding: 9px 11px; border-radius: 8px; background: var(--panel); border: 1px solid var(--panel-line); font: 13px var(--mono); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.small-code { font-size: 12px; white-space: pre-wrap; overflow-wrap: anywhere; }
/* Timesheet */
.week-nav { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.week-range { font: 600 15px/1 var(--sans); padding: 0 4px; }
.sheet-total { margin-top: -8px; }
.sheet { min-width: 760px; }
.sheet th, .sheet td { padding: 8px 8px; vertical-align: middle; }
.sheet thead th { font-size: 11.5px; }
.sheet thead th span { display: block; margin-top: 3px; font: 500 14px/1 var(--sans); letter-spacing: 0; text-transform: none; color: var(--ink); }
.sheet thead th.is-today, .sheet thead th.is-today span { color: var(--cobalt-ink); }
.sheet tbody th, .sheet tfoot th { font: 600 14.5px/1.3 var(--sans); text-transform: none; letter-spacing: 0; color: var(--ink); }
.sheet tbody th { width: 28%; max-width: 0; }
.sheet tbody th .proj { max-width: 100%; }
.sheet tfoot th, .sheet tfoot td { font-weight: 650; border-bottom: 0; border-top: 1px solid var(--line-strong); }
.cell { width: 64px; min-height: 38px; padding: 6px 8px; border: 1px solid var(--line); border-radius: 8px; background: #fff; text-align: right; font: 500 15px/1 var(--sans); font-variant-numeric: tabular-nums; }
.cell:hover { border-color: var(--line-strong); }
.cell:focus { outline: none; border-color: var(--cobalt); box-shadow: 0 0 0 3px #2e5ec41f; }
.cell.multi { background: var(--paper-warm); border-color: #ece2cf; }
.cell::placeholder { color: #c3c7cd; }
.sheet-add th { font-weight: 500; }
.add-row { display: flex; align-items: center; gap: 8px; }
.add-row .pick-btn { border-color: var(--line); }
.sheet-narrow { display: none; }
@media (max-width: 760px) {
.sheet-wide { display: none; }
.sheet-narrow { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }
}
.day-tabs { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }
.day-tabs button { display: grid; justify-items: center; gap: 3px; padding: 8px 0; border: 1px solid var(--line); border-radius: 12px; background: #fff; cursor: pointer; color: var(--muted); }
.day-tabs button span { font: 650 11px/1 var(--sans); text-transform: uppercase; }
.day-tabs button strong { font: 600 16px/1 var(--sans); color: var(--ink); }
.day-tabs button small { font: 500 11px/1 var(--sans); font-variant-numeric: tabular-nums; }
.day-tabs button.is-today strong { color: var(--cobalt-ink); }
.day-tabs button[aria-selected="true"] { border-color: var(--ink-solid); box-shadow: inset 0 0 0 1px var(--ink-solid); }
.sheet-list { list-style: none; padding: 0; border: 1px solid var(--line); border-radius: 14px; background: #fff; }
.sheet-list li { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 56px; padding: 8px 12px 8px 14px; font: 600 15px/1.3 var(--sans); }
.sheet-list li + li { border-top: 1px solid var(--line); }
.sheet-list .cell { width: 84px; min-height: 42px; font-size: 16px; }
/* Reports */
.report-actions { gap: 8px; }
.filters { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.range-nav { display: flex; align-items: center; gap: 2px; }
.select-inline { width: auto; min-height: 40px; padding: 6px 30px 6px 10px; font: 600 14px/1.2 var(--sans); max-width: 100%; }
.custom-range { display: flex; align-items: center; gap: 6px; }
.input-sm { min-height: 40px; padding: 6px 8px; font-size: 14.5px; width: auto; }
.input-grow { flex: 1; min-width: 0; width: auto; }
.range-label { font: 400 22px/1.2 var(--serif); letter-spacing: -.01em; }
.stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.stat-card { display: grid; gap: 4px; padding: 16px 18px; border: 1px solid var(--line); border-radius: 14px; background: #fff; }
.stat-card > span { font: 650 11.5px/1 var(--sans); letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.stat-card strong { font: 400 30px/1.1 var(--serif); letter-spacing: -.02em; overflow-wrap: anywhere; }
.stat-card small { color: var(--muted); font-size: 13px; }
@media (max-width: 640px) { .stats { grid-template-columns: minmax(0, 1fr); } .stat-card { grid-template-columns: 1fr auto; align-items: baseline; } .stat-card small { grid-column: 1 / -1; } }
.chart { margin: 0; padding: 16px 16px 10px; }
.chart-title { font: 600 14px/1 var(--sans); color: #33363c; margin-bottom: 14px; }
.chart-plot { position: relative; height: 200px; margin-left: 34px; }
.chart-grid span { position: absolute; left: 0; right: 0; border-top: 1px solid var(--line); }
.chart-grid em { position: absolute; left: -34px; top: -8px; width: 28px; text-align: right; font: normal 500 11.5px/1 var(--sans); color: var(--faint); font-variant-numeric: tabular-nums; }
.chart-bars { position: absolute; inset: 0 0 -22px 0; display: flex; gap: 2px; }
.bar-slot { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.bar-hit { position: relative; flex: 1; display: flex; align-items: flex-end; justify-content: center; padding: 0; border: 0; background: none; cursor: default; }
.bar-hit:hover, .bar-hit:focus-visible { background: #2e5ec40d; outline-offset: 0; }
.bar { display: block; width: min(24px, 70%); min-height: 0; border-radius: 4px 4px 0 0; background: var(--cobalt); }
.bar-label { height: 22px; padding-top: 6px; text-align: center; font: 500 11px/1 var(--sans); color: var(--muted); white-space: nowrap; overflow: visible; }
.bar-tip { position: absolute; bottom: calc(100% + 6px); left: 50%; z-index: 5; display: none; min-width: 170px; max-width: 240px; padding: 10px 12px; border-radius: 10px; background: var(--ink-solid); color: #fff; font: 500 12.5px/1.45 var(--sans); text-align: left; transform: translateX(-50%); pointer-events: none; }
.bar-tip strong { display: block; margin-bottom: 4px; font-weight: 650; }
.bar-tip span { display: flex; align-items: center; gap: 6px; color: #dfe2e7; }
.bar-tip i { flex: none; width: 8px; height: 8px; border-radius: 50%; box-shadow: 0 0 0 1.5px var(--ink-solid); }
.bar-hit:hover .bar-tip, .bar-hit:focus-visible .bar-tip { display: block; }
.bar-slot:first-child .bar-tip, .bar-slot:nth-child(2) .bar-tip { left: 0; transform: none; }
.bar-slot:last-child .bar-tip, .bar-slot:nth-last-child(2) .bar-tip { left: auto; right: 0; transform: none; }
.chart { margin-bottom: 8px; }
.chart-plot { margin-bottom: 26px; }
.tabs { display: flex; gap: 6px; border-bottom: 1px solid var(--line); overflow-x: auto; }
.tabs button { flex: none; min-height: 44px; padding: 0 14px; border: 0; border-bottom: 2px solid transparent; background: none; cursor: pointer; font: 600 15px var(--sans); color: var(--muted); }
.tabs button[aria-selected="true"] { color: var(--ink-solid); border-bottom-color: var(--ink-solid); }
.breakdown th[scope="row"] { font: 600 14.5px/1.3 var(--sans); text-transform: none; letter-spacing: 0; color: var(--ink); max-width: 0; width: 40%; }
.breakdown td, .breakdown th { vertical-align: middle; }
.share-col { width: 22%; }
@media (max-width: 600px) { .share-col { display: none; } .breakdown th[scope="row"] { width: 55%; } }
@media (max-width: 480px) { .breakdown .proj-client, .sheet-list .proj-client { display: none; } }
.share-col small { display: block; margin-top: 4px; color: var(--muted); font-size: 12px; }
.share-bar { display: block; height: 6px; border-radius: 99px; background: #eceff3; overflow: hidden; }
.share-bar span { display: block; height: 100%; border-radius: 99px; }
.table-note { padding: 10px 14px; }
.entries-detail summary { cursor: pointer; padding: 10px 2px; font: 600 15px/1.3 var(--sans); }
.detail td { font-size: 14.5px; }
.invoice-lines td { font-size: 14.5px; }
.invoice-lines tfoot th { font: 600 14px/1.2 var(--sans); text-transform: none; letter-spacing: 0; color: var(--ink); text-align: right; }
/* Projects */
.proj-list { list-style: none; padding: 0; overflow: hidden; }
.proj-row { display: flex; align-items: center; gap: 10px; padding-right: 12px; }
.proj-row + .proj-row { border-top: 1px solid var(--line); }
.proj-main { flex: 1; min-width: 0; display: flex; align-items: center; gap: 14px; padding: 14px 16px; border: 0; background: none; text-align: left; cursor: pointer; color: var(--ink); }
.proj-main:hover { background: #fafbfc; }
.proj-main.static { cursor: default; }
.proj-main.static:hover { background: none; }
.proj-text { display: grid; gap: 2px; min-width: 0; }
.proj-text strong { font: 600 16px/1.3 var(--sans); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chip-list { list-style: none; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.chip-btn { display: inline-flex; align-items: center; gap: 6px; min-height: 36px; padding: 0 12px; border: 1px solid var(--line); border-radius: 99px; background: #fff; cursor: pointer; font: 600 14px/1 var(--sans); color: var(--ink); }
.chip-btn svg { color: var(--faint); }
.chip-btn:hover { border-color: var(--line-strong); }
.people { list-style: none; padding: 0; display: grid; border: 1px solid var(--line); border-radius: 12px; }
.people li { display: flex; align-items: center; gap: 10px; padding: 8px 8px 8px 14px; font-size: 15px; }
.people li + li { border-top: 1px solid var(--line); }
/* Settings and join */
.settings { max-width: 720px; }
.set-card { display: grid; gap: 12px; padding: 20px; }
.account-card { background: var(--cobalt-wash); border-color: #d1ddf5; }
.keys { list-style: none; padding: 0; display: grid; border: 1px solid var(--line); border-radius: 12px; }
.keys li { display: flex; align-items: center; gap: 10px; padding: 8px 8px 8px 14px; }
.keys li + li { border-top: 1px solid var(--line); }
.join-card { display: grid; gap: 14px; padding: 24px; }
.join-art { width: 150px; height: auto; }
/* Toast with an action */
.toast { display: flex; align-items: center; gap: 14px; max-width: calc(100vw - 32px); bottom: calc(84px + env(safe-area-inset-bottom)); }
@media (min-width: 960px) { .toast { bottom: 24px; } }
.toast-action { padding: 4px 8px; border: 0; border-radius: 6px; background: #ffffff1f; color: #fff; font: 650 14px/1 var(--sans); cursor: pointer; }
.toast-action:hover { background: #ffffff33; }
Change history
Point OpenApps links to openapps.free
Bind agent address constants in policy
Use functions.openapps.xyz alias and add OpenApp contribution strip
Bounded source sync
Bounded source sync
Bounded source sync
Bounded source sync