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 ee59501e91bae6d2c23a8370
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
/* Lists. Shared look comes from /kit.css; this is the app's own layout. */
body.app-mode .landing-only { display: none !important; }
body:not(.app-mode) #app:empty { display: none; }
body.app-mode .site-nav .landing-link { display: none; }
.grow { flex: 1; min-width: 0; }
.loading { display: flex; align-items: center; gap: 12px; color: var(--muted); }
.page { width: var(--page); margin-inline: auto; padding-block: 28px 96px; }
.narrow { max-width: 680px; }
.page-title { font: 360 clamp(30px, 4vw, 42px)/1.1 var(--serif); letter-spacing: -.028em; margin-bottom: 14px; }
.page .lede + .btn { margin-top: 22px; }
.two { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 12px; }
.input-lg { min-height: 52px; font-size: 16.5px; }
@media (max-width: 760px) { .page { width: calc(100% - 32px); padding-top: 16px; } }
/* ---------- Landing ---------- */
.app-hero { padding: 40px 0 72px; background: var(--paper-warm); border-bottom: 1px solid #efe6d6; }
.app-hero-grid { display: grid; grid-template-columns: minmax(0, 1fr) 430px; gap: 56px; align-items: center; }
.app-hero h1 { margin-top: 14px; }
.app-hero .lede { margin-top: 18px; }
.hero-art { width: 220px; height: auto; margin: 0 0 6px -8px; -webkit-mask-image: radial-gradient(closest-side, #000 72%, transparent); mask-image: radial-gradient(closest-side, #000 72%, transparent); }
.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); }
@media (max-width: 900px) {
.app-hero { padding: 20px 0 48px; }
.app-hero-grid { grid-template-columns: minmax(0, 1fr); gap: 0; }
.hero-copy { display: contents; }
.hero-art { width: 110px; margin-bottom: 0; }
.app-hero .display { font-size: 36px; }
#start { order: 1; margin-top: 18px; }
.app-hero .lede { order: 2; margin-top: 22px; }
.hero-points { order: 3; }
}
.start { display: grid; gap: 14px; padding: 22px; }
.new-list { display: grid; gap: 14px; }
.picks { display: flex; flex-wrap: wrap; gap: 8px; }
.pick { min-height: 40px; padding: 0 14px; border: 1px solid var(--line-strong); border-radius: 999px; background: #fff; color: var(--ink); font: 600 14.5px/1 var(--sans); cursor: pointer; }
.pick:hover { border-color: #b5bdc8; background: #fafbfc; }
.pick[aria-pressed="true"] { border-color: var(--ink-solid); background: var(--ink-solid); color: #fff; }
.start-mine { padding-top: 14px; border-top: 1px solid var(--line); display: grid; gap: 8px; }
.start-mine ul { list-style: none; padding: 0; display: grid; gap: 6px; }
.start-mine li a { display: flex; justify-content: space-between; gap: 12px; align-items: center; min-height: 44px; padding: 0 14px; border-radius: 10px; background: var(--panel); border: 1px solid var(--panel-line); color: var(--ink); font-weight: 600; }
.start-mine li a small { color: var(--muted); font-weight: 500; font-size: 13.5px; }
.features { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin-top: 26px; padding: 0; list-style: none; }
.features li { padding: 18px 20px; border: 1px solid var(--line); border-radius: 14px; background: #fff; }
.features h3, .steps h3 { font: 600 18px/1.3 var(--sans); }
.features p, .steps p { margin-top: 8px; color: #4a4e56; font-size: 15px; }
@media (max-width: 900px) { .features { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 600px) { .features { grid-template-columns: minmax(0, 1fr); } }
.how { background: var(--paper-warm); border-block: 1px solid #ece2cf; }
.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); }
@media (max-width: 760px) { .steps { grid-template-columns: minmax(0, 1fr); } }
.answer { margin-top: 16px; max-width: 70ch; font-size: 17px; color: #33363c; }
.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; }
.split-cols { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 40px; }
.split-cols ul { margin-top: 14px; padding-left: 1.2em; display: grid; gap: 8px; color: #3d4148; }
@media (max-width: 760px) { .split-cols { grid-template-columns: minmax(0, 1fr); gap: 28px; } }
/* ---------- Your lists ---------- */
.lists { list-style: none; padding: 0; display: grid; gap: 10px; margin-bottom: 28px; }
.lists a { display: grid; gap: 2px; padding: 16px 18px; border: 1px solid var(--line); border-radius: 14px; background: #fff; color: var(--ink); box-shadow: var(--shadow); }
.lists a:hover { border-color: var(--line-strong); color: var(--ink); }
.lists-name { font: 400 24px/1.2 var(--serif); letter-spacing: -.015em; }
.lists-meta { color: var(--muted); font-size: 14px; }
.new-card { display: grid; gap: 14px; padding: 20px; }
.empty { display: grid; justify-items: center; gap: 10px; padding: 32px 20px; text-align: center; }
.empty .art { width: 200px; height: auto; }
.empty .muted { max-width: 42ch; }
/* ---------- A list ---------- */
.list-page { padding-top: 18px; }
.list-head { display: grid; gap: 8px; }
.back { display: inline-flex; align-items: center; gap: 4px; width: fit-content; min-height: 36px; margin-left: -6px; padding: 0 8px 0 4px; border-radius: 8px; color: var(--muted); font: 600 14.5px var(--sans); }
.back:hover { background: #0000000a; color: var(--ink); }
.list-title-row { display: flex; align-items: center; gap: 8px; }
.list-title { font: 360 clamp(30px, 6vw, 42px)/1.08 var(--serif); letter-spacing: -.028em; overflow-wrap: anywhere; }
.list-sub { margin-top: 4px; color: var(--muted); font-size: 14.5px; }
.icon-btn { display: grid; place-items: center; flex: 0 0 auto; width: 44px; height: 44px; border: 0; border-radius: 10px; background: none; cursor: pointer; color: var(--muted); }
.icon-btn:hover { background: #0000000a; color: var(--ink); }
.icon-btn:disabled { opacity: .3; cursor: default; }
.sync { display: flex; align-items: center; gap: 8px; color: var(--muted); font-size: 13.5px; }
.sync svg { flex: 0 0 auto; }
.sync-live .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--sage); box-shadow: 0 0 0 3px var(--sage-wash); }
.sync-error { color: var(--brick); }
.sync-error button { margin-left: 6px; border: 0; background: none; color: var(--cobalt); font: 600 13.5px var(--sans); cursor: pointer; }
.hint-box { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-top: 14px; }
.add { position: sticky; top: 64px; z-index: 5; margin: 14px -16px 0; padding: 10px 16px; background: #fdfdfcf2; -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); }
.add-bar { display: flex; gap: 8px; }
.add-input { min-height: 54px; font-size: 17px; border-radius: 14px; }
.add-btn { min-height: 54px; min-width: 54px; padding: 0 18px; border-radius: 14px; }
.suggest { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 10px; }
.suggest-label { font: 650 11.5px/1 var(--sans); letter-spacing: .1em; text-transform: uppercase; color: var(--muted); margin-right: 2px; }
@media (max-width: 420px) { .add-label { display: none; } .add-btn { padding: 0; } }
.group { margin-top: 18px; }
.group-label { font: 650 12px/1 var(--sans); letter-spacing: .1em; text-transform: uppercase; color: var(--muted); padding: 0 4px 8px; }
.group-label-row { display: flex; align-items: center; justify-content: space-between; }
.group-label-row .group-label { padding-bottom: 0; }
.items { list-style: none; padding: 0; border: 1px solid var(--line); border-radius: 16px; background: #fff; overflow: hidden; }
.item { display: flex; align-items: stretch; }
.item + .item { border-top: 1px solid var(--line); }
.item-main { flex: 1; min-width: 0; display: flex; align-items: center; gap: 14px; min-height: 60px; padding: 8px 4px 8px 16px; border: 0; background: none; text-align: left; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.item-main:active { background: #f6f7f9; }
.box { display: grid; place-items: center; flex: 0 0 28px; height: 28px; border: 2px solid var(--line-strong); border-radius: 50%; color: #fff; transition: background .12s, border-color .12s; }
.item-text { display: grid; min-width: 0; }
.item-name { font: 500 17px/1.3 var(--sans); overflow-wrap: anywhere; }
.item-meta { font-size: 14px; color: var(--muted); overflow-wrap: anywhere; }
.item-edit { flex: 0 0 52px; display: grid; place-items: center; border: 0; background: none; color: var(--faint); cursor: pointer; }
.item-edit:hover { color: var(--ink); background: #0000000a; }
.item.done .box { background: var(--sage); border-color: var(--sage); }
.item.done .item-name { color: var(--faint); text-decoration: line-through; text-decoration-color: #b8bcc3; }
.item.done .item-meta { color: var(--faint); }
.checked { margin-top: 26px; }
.checked .items { background: #fbfbfa; }
.all-done { margin-top: 18px; padding: 14px 16px; border-radius: 14px; background: var(--sage-wash); color: #2f5a3c; font-weight: 600; }
/* ---------- Sheets ---------- */
.modal-backdrop { position: fixed; inset: 0; z-index: 60; display: grid; place-items: center; padding: 20px; background: #15171b66; animation: fade .15s ease; }
.modal { display: flex; flex-direction: column; min-width: 0; 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-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 16px 16px 4px 20px; }
.modal-title { font: 400 26px/1.2 var(--serif); letter-spacing: -.015em; overflow-wrap: anywhere; }
.modal-body { padding: 12px 20px 20px; overflow-y: auto; }
.modal-foot { display: flex; align-items: center; gap: 10px; padding: 14px 20px calc(14px + env(safe-area-inset-bottom)); border-top: 1px solid var(--line); }
@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 { width: 100%; max-height: 92vh; border-radius: 18px 18px 0 0; }
}
.sheet { display: grid; grid-template-columns: minmax(0, 1fr); gap: 22px; }
.sheet section { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }
.sheet section + section { padding-top: 20px; border-top: 1px solid var(--line); }
.link-row { display: flex; align-items: center; gap: 8px; }
.link-code { flex: 1; min-width: 0; padding: 10px 12px; border-radius: 8px; background: var(--panel); border: 1px solid var(--panel-line); font: 13px var(--mono); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; user-select: all; }
.small-code { font-size: 11.5px; white-space: pre-wrap; word-break: break-all; }
.people { list-style: none; padding: 0; display: grid; }
.people li { display: flex; align-items: center; gap: 10px; min-height: 48px; border-top: 1px solid var(--line); font-size: 15px; }
.people li:first-child { border-top: 0; }
.people .chip { margin-left: 8px; }
.confirm { display: grid; gap: 10px; padding: 14px; border-radius: 12px; background: var(--brick-wash); border: 1px solid #efcfc5; }
.name-row { display: flex; align-items: flex-end; gap: 8px; }
.menu { display: grid; border: 1px solid var(--line); border-radius: 14px; overflow: hidden; }
.menu button { display: grid; gap: 2px; min-height: 58px; padding: 10px 16px; border: 0; background: #fff; text-align: left; font: 600 15.5px var(--sans); cursor: pointer; }
.menu button + button { border-top: 1px solid var(--line); }
.menu button:hover { background: #fafbfc; }
.menu button:disabled { color: var(--faint); cursor: default; }
.menu button small { font: 400 13.5px var(--sans); color: var(--muted); }
.menu .danger { color: var(--brick); }
.btn-danger-solid { background: var(--brick); border-color: var(--brick); }
.btn-danger-solid:hover { background: #8f3923; }
.aisles { list-style: none; padding: 0; margin-top: 12px; border: 1px solid var(--line); border-radius: 14px; }
.aisles li { display: flex; align-items: center; gap: 4px; min-height: 52px; padding: 0 6px 0 16px; font-weight: 600; }
.aisles li + li { border-top: 1px solid var(--line); }
.toast { display: flex; align-items: center; gap: 14px; max-width: calc(100% - 32px); bottom: calc(24px + env(safe-area-inset-bottom)); }
.toast button { flex: 0 0 auto; border: 0; background: none; color: #9db8ef; font: 650 14px var(--sans); cursor: pointer; padding: 4px 2px; }
Change history
Point OpenApps links to openapps.free
Bind agent address in policy constants
Use OpenApps service URLs and add contribution strip
Bounded source sync
Bounded source sync
Bounded source sync