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 9383f719c9b37ff76411858f
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
/* Monitor. Shared look comes from /kit.css; this is the app's own layout.
The landing uses the paper look; the app screens use a night look for dark rooms. */
body.app-mode .landing-only, body.app-mode .site-head, body.app-mode .site-foot { display: none !important; }
body.app-mode { background: #0e0f11; }
body:not(.app-mode) #app:empty { display: none; }
/* Landing hero with the device chooser */
.app-hero { padding: 48px 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; gap: 56px; align-items: center; }
.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: 220px; height: auto; margin-bottom: -4px; }
.start-card { padding: 22px; }
@media (max-width: 900px) {
/* Phones: the device chooser comes right after the headline, before the selling points. */
.app-hero { padding: 24px 0 48px; }
.app-hero-grid { grid-template-columns: 1fr; gap: 0; }
.app-hero-grid > div:first-child { display: contents; }
.hero-art { width: 130px; margin-bottom: 4px; }
.start-card { order: 1; margin-top: 24px; padding: 16px; }
.hero-points { order: 2; }
}
/* The device chooser (landing hero and the app home) */
.launcher { display: grid; gap: 12px; }
.launcher-label { font: 650 12px/1.2 var(--sans); letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.choice { display: flex; align-items: center; gap: 14px; min-height: 80px; padding: 14px 16px; border: 1px solid var(--line); border-radius: 14px; background: #fff; color: var(--ink); text-decoration: none; }
.choice:hover { border-color: var(--line-strong); box-shadow: var(--shadow); color: var(--ink); }
.choice-icon { display: grid; place-items: center; flex: 0 0 52px; height: 52px; border-radius: 13px; background: var(--paper-warm); border: 1px solid #ece2cf; color: var(--ink-solid); }
.choice-text { display: grid; gap: 2px; min-width: 0; }
.choice-text strong { font: 600 17px/1.25 var(--sans); }
.choice-text small { color: var(--muted); font-size: 14px; line-height: 1.4; }
.again { display: grid; gap: 10px; margin-bottom: 6px; }
.again-list { list-style: none; padding: 0; display: grid; gap: 8px; }
.again-item { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 58px; padding: 0 18px; border-radius: 12px; background: var(--ink-solid); color: #fff; font: 600 16px/1.2 var(--sans); text-decoration: none; }
.again-item:hover { background: #2a2c31; color: #fff; }
.again-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.again-go { flex: none; font-size: 14.5px; opacity: .85; }
.launcher-note { margin-top: 4px; font-size: 13px; color: var(--muted); text-align: center; }
/* 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, .privacy-list h3 { font: 600 18px/1.3 var(--sans); }
.steps p, .features p, .privacy-list p { margin-top: 8px; color: #4a4e56; }
.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 p { margin-top: 6px; font-size: 15px; }
@media (max-width: 900px) { .features { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 760px) { .steps, .features { grid-template-columns: 1fr; } }
.privacy { background: var(--paper-warm); border-block: 1px solid #ece2cf; }
.privacy-grid { display: grid; grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr); gap: 40px; align-items: start; }
.privacy-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 22px 28px; padding: 0; list-style: none; }
.privacy-note { grid-column: 1 / -1; max-width: 80ch; }
@media (max-width: 900px) { .privacy-grid, .privacy-list { grid-template-columns: 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: 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: 640px; }
/* ---------- The night look: every app screen ---------- */
.night {
--n-bg: #0e0f11; --n-surface: #17181b; --n-surface-2: #202125; --n-line: #2d2f34; --n-line-strong: #41444b;
--n-text: #ece8df; --n-muted: #a39e94; --n-faint: #706c65; --n-accent: #93acec; --n-good: #8cc09b; --n-warn: #e2c27e; --n-bad: #e8a08c;
min-height: 100vh; min-height: 100dvh; background: var(--n-bg); color: var(--n-text); color-scheme: dark;
}
.night a { color: var(--n-accent); }
.night :is(a, button, input, select):focus-visible { outline-color: var(--n-accent); }
.night-page { width: min(560px, 100%); margin-inline: auto; padding: 0 16px calc(24px + env(safe-area-inset-bottom)); display: flex; flex-direction: column; gap: 14px; }
.night-h1 { margin-top: 8px; font: 350 32px/1.12 var(--serif); letter-spacing: -.025em; text-wrap: balance; }
.night-h2 { font: 650 12px/1.2 var(--sans); letter-spacing: .1em; text-transform: uppercase; color: var(--n-muted); }
.night-lede { color: var(--n-muted); font-size: 16.5px; line-height: 1.55; }
.night-muted { color: var(--n-muted); }
.night-strong { color: var(--n-text); font-weight: 600; }
.small { font-size: 14px; }
.grow { flex: 1; min-width: 0; }
.center-fill { display: flex; align-items: center; justify-content: center; gap: 12px; min-height: 40vh; color: var(--n-muted); }
.center-fill.small { min-height: 120px; }
.night .spinner { border-color: #ffffff26; border-top-color: currentColor; }
.bar { position: sticky; top: 0; z-index: 5; display: flex; align-items: center; gap: 8px; min-height: 58px; margin-inline: -16px; padding: env(safe-area-inset-top) 10px 0; background: #0e0f11f2; }
.bar-back { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 12px; color: var(--n-text) !important; }
.bar-back:hover { background: #ffffff10; }
.bar-title { flex: 1; min-width: 0; font: 600 17px/1.2 var(--sans); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bar-right { display: flex; align-items: center; gap: 4px; }
.night .btn { background: var(--n-text); border-color: var(--n-text); color: #0e0f11; }
.night .btn:hover { background: #fff; color: #0e0f11; }
.night .btn-line { background: transparent; border-color: var(--n-line-strong); color: var(--n-text); }
.night .btn-line:hover { background: #ffffff0d; color: var(--n-text); }
.night .btn-quiet { background: transparent; border-color: transparent; color: var(--n-text); }
.night .btn-quiet:hover { background: #ffffff10; color: var(--n-text); }
.btn-xl { min-height: 60px; padding: 0 22px; font-size: 16px; border-radius: 14px; }
.night .btn-danger-solid { background: var(--n-bad); border-color: var(--n-bad); color: #1b0f0b; }
.night .danger { color: var(--n-bad); }
.link-btn { padding: 6px 2px; border: 0; background: none; color: var(--n-accent); font: 600 14.5px var(--sans); cursor: pointer; }
.night .icon-btn { display: grid; place-items: center; width: 44px; height: 44px; border: 0; border-radius: 12px; background: none; color: var(--n-text); cursor: pointer; }
.night .icon-btn:hover { background: #ffffff10; }
.night .icon-btn[aria-pressed="true"] { color: var(--n-warn); }
.night .field > span, .night .field > label { color: var(--n-text); }
.night .field small { color: var(--n-muted); }
.night .input { background: var(--n-surface-2); border-color: var(--n-line-strong); color: var(--n-text); }
.night .input::placeholder { color: var(--n-faint); }
.night .input:focus { border-color: var(--n-accent); box-shadow: 0 0 0 3px #93acec2e; }
.night .notice { background: var(--n-surface); border-color: var(--n-line); color: var(--n-text); text-align: left; }
.night .notice-error { background: #2b1814; border-color: #53302a; color: #f2bfb0; }
.night .notice-ok { background: #15241a; border-color: #29452f; color: #b2dbbd; }
.night .notice-warn { background: #2a2414; border-color: #4d4224; color: #ecd59d; width: 100%; cursor: pointer; font: inherit; font-size: 14.5px; }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.panel-night { display: grid; gap: 10px; padding: 16px; border: 1px solid var(--n-line); border-radius: 16px; background: var(--n-surface); }
.stack-buttons { display: grid; gap: 10px; }
.footer-actions { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px 16px; padding-top: 4px; }
.night .launcher-label { color: var(--n-muted); }
.night .choice { background: var(--n-surface); border-color: var(--n-line); color: var(--n-text); }
.night .choice:hover { border-color: var(--n-line-strong); box-shadow: none; }
.night .choice-icon { background: var(--n-surface-2); border-color: var(--n-line); color: var(--n-text); }
.night .choice-text small, .night .launcher-note { color: var(--n-muted); }
.night .again-item { background: var(--n-text); color: #0e0f11; }
/* Setup and pairing */
.setup, .pair-form { display: grid; gap: 14px; }
.tips { display: grid; gap: 8px; margin-top: 4px; padding-left: 18px; color: var(--n-muted); font-size: 14.5px; }
.code-input { min-height: 64px; font: 600 30px/1 var(--sans); letter-spacing: .18em; text-align: center; font-variant-numeric: tabular-nums; }
.pair-steps { display: grid; gap: 6px; padding-left: 20px; color: var(--n-muted); font-size: 15px; }
.pair-steps strong { color: var(--n-text); }
.code-box { display: grid; justify-items: center; gap: 14px; padding: 18px 0 4px; }
.pair-code { font: 650 52px/1 var(--sans); letter-spacing: .06em; font-variant-numeric: tabular-nums; }
.pair-code span { display: inline-block; width: .3em; }
.qr { width: 196px; height: 196px; padding: 0; border-radius: 12px; }
.code-left { color: var(--n-muted); font-size: 14px; }
.code-expired { display: grid; justify-items: center; gap: 12px; padding: 24px 0; color: var(--n-muted); }
.scanner { position: relative; overflow: hidden; border-radius: 14px; background: #000; aspect-ratio: 1; }
.scanner video { width: 100%; height: 100%; object-fit: cover; }
.scanner-frame { position: absolute; inset: 18%; border: 2px solid #ffffffcc; border-radius: 16px; }
/* Baby station */
.preview { position: relative; overflow: hidden; aspect-ratio: 4 / 3; border-radius: 16px; background: #000; }
.preview video { width: 100%; height: 100%; object-fit: cover; }
.live-chip, .state-chip { display: inline-flex; align-items: center; gap: 6px; min-height: 28px; padding: 0 11px; border-radius: 999px; background: #000000a6; color: var(--n-muted); font: 600 13px/1 var(--sans); white-space: nowrap; }
.live-chip { position: absolute; left: 10px; top: 10px; }
.live-chip::before, .state-chip::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--n-faint); }
.live-chip.on, .state-chip.on { color: var(--n-text); }
.live-chip.on::before, .state-chip.on::before { background: var(--n-good); }
.state-chip { background: var(--n-surface-2); }
.preview-flip { position: absolute; right: 10px; bottom: 10px; display: grid; place-items: center; width: 48px; height: 48px; border: 0; border-radius: 50%; background: #000000a6; color: #fff; cursor: pointer; }
.watchers { list-style: none; padding: 0; display: grid; }
.watchers li { display: flex; align-items: center; gap: 12px; min-height: 58px; border-top: 1px solid var(--n-line); }
.watchers li:first-child { border-top: 0; }
.watcher-name { display: block; font: 600 15.5px/1.3 var(--sans); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.watcher-state { display: block; color: var(--n-muted); font-size: 13.5px; }
.dot { flex: 0 0 9px; height: 9px; border-radius: 50%; background: var(--n-faint); }
.dot.on { background: var(--n-good); }
.dimmed { position: fixed; inset: 0; z-index: 30; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; width: 100%; border: 0; background: #000; color: #3f3c37; font: 500 15px/1.4 var(--sans); cursor: pointer; text-align: center; padding: 24px; }
.dim-clock { font: 300 64px/1 var(--serif); color: #4b4842; letter-spacing: -.02em; }
.dim-status { color: #5a5650; }
.dim-talk, .dim-note { color: #6b665e; }
.dim-warn { color: #8f7440; }
.dim-hint { position: absolute; bottom: calc(28px + env(safe-area-inset-bottom)); color: #2f2d2a; font-size: 13px; }
/* Sound meter: --level is set ten times a second without re-rendering */
.meter { position: relative; height: 10px; border-radius: 999px; background: var(--n-surface-2); overflow: hidden; }
.meter span { position: absolute; inset: 0 auto 0 0; width: var(--level, 0%); border-radius: inherit; background: var(--n-good); transition: width .1s linear; }
.meter i { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--n-warn); }
.meter-label { display: flex; justify-content: space-between; gap: 12px; margin-bottom: -6px; color: var(--n-muted); font: 600 12.5px/1.2 var(--sans); }
.meter-label i { display: inline-block; width: 2px; height: 10px; margin-right: 6px; background: var(--n-warn); vertical-align: -1px; }
/* Parent watching */
.watch .night-page { min-height: 100vh; min-height: 100dvh; gap: 12px; }
@media (min-width: 900px) { .watch .night-page { width: min(880px, 100%); } }
.status-line { margin-top: -8px; color: var(--n-muted); font-size: 13.5px; }
/* The picture keeps the camera's shape (portrait or landscape) and leaves room for the controls. */
.stage { position: relative; flex: none; aspect-ratio: var(--ratio, 4 / 3); width: min(100%, calc(62vh * var(--ratio, 1.333))); margin-inline: auto; overflow: hidden; border-radius: 16px; background: #000; }
.stage video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
.stage video.night-view { filter: brightness(1.9) contrast(1.35) saturate(.7); }
.stage-overlay { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px; padding: 22px; border: 0; background: #0e0f11e6; color: var(--n-text); font: 500 16px/1.5 var(--sans); text-align: center; text-wrap: balance; }
.stage-overlay.tap { cursor: pointer; background: #0e0f11cc; }
.listening { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; padding: 20px; color: var(--n-muted); text-align: center; }
.listening p { color: var(--n-text); font: 350 28px/1.1 var(--serif); }
.alert-banner { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border-radius: 14px; background: #2a2414; border: 1px solid #4d4224; color: #ecd59d; font: 600 15px/1.35 var(--sans); }
.controls { display: grid; gap: 10px; margin-top: auto; padding-top: 6px; }
.tiles { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.tile { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; min-height: 74px; padding: 8px 4px; border: 1px solid var(--n-line); border-radius: 14px; background: var(--n-surface); color: var(--n-text); font: 600 13px/1.2 var(--sans); cursor: pointer; }
.tile[aria-pressed="true"] { border-color: #93acec80; background: #1b2236; color: #c9d6f7; }
.tile:disabled { opacity: .4; cursor: not-allowed; }
.talk { min-height: 66px; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; touch-action: none; }
.night .talk.on { background: var(--n-accent); border-color: var(--n-accent); color: #0e1222; }
/* Sheets (night) */
.sheet-backdrop { position: fixed; inset: 0; z-index: 60; display: grid; place-items: center; padding: 20px; background: #000000a6; animation: fade .15s ease; }
.sheet { display: flex; flex-direction: column; width: min(520px, 100%); max-height: min(90vh, 860px); border: 1px solid #2d2f34; border-radius: 18px; background: #17181b; color: #ece8df; box-shadow: 0 30px 80px -20px #000; animation: rise .18s ease; color-scheme: dark; }
.sheet-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 16px 16px 4px 20px; }
.sheet-title { font: 380 26px/1.2 var(--serif); letter-spacing: -.015em; }
.sheet-body { display: grid; gap: 14px; padding: 10px 20px calc(20px + env(safe-area-inset-bottom)); overflow-y: auto; }
.sheet .icon-btn { display: grid; place-items: center; width: 44px; height: 44px; border: 0; border-radius: 12px; background: none; color: #ece8df; cursor: pointer; }
.sheet-actions { display: grid; gap: 10px; margin-top: 4px; }
@keyframes fade { from { opacity: 0; } }
@keyframes rise { from { opacity: 0; transform: translateY(10px); } }
@media (max-width: 600px) {
.sheet-backdrop { place-items: end stretch; padding: 0; }
.sheet { width: 100%; max-height: 92vh; border-radius: 18px 18px 0 0; border-bottom: 0; }
}
.segmented { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 4px; padding: 4px; border-radius: 12px; background: #0e0f11; border: 1px solid #2d2f34; }
.segmented button { min-height: 44px; border: 0; border-radius: 9px; background: transparent; color: #a39e94; font: 600 14px var(--sans); cursor: pointer; }
.segmented button[aria-checked="true"] { background: #ece8df; color: #0e0f11; }
.sound-list { list-style: none; padding: 0; display: grid; gap: 8px; }
.sound-row { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 62px; padding: 10px 14px; border: 1px solid #2d2f34; border-radius: 12px; background: #202125; color: #ece8df; text-align: left; cursor: pointer; font: inherit; }
.sound-row strong { display: block; font: 600 15.5px/1.3 var(--sans); }
.sound-row small { color: #a39e94; font-size: 13.5px; }
.sound-row[aria-pressed="true"] { border-color: #93acec80; background: #1b2236; }
.sound-state { flex: none; color: #a39e94; font: 600 13.5px var(--sans); }
.sound-row[aria-pressed="true"] .sound-state { color: #c9d6f7; }
input[type="range"] { width: 100%; accent-color: #ece8df; min-height: 36px; }
.facts { display: grid; gap: 0; margin: 0; }
.facts div { display: flex; justify-content: space-between; gap: 16px; padding: 11px 0; border-top: 1px solid #2d2f34; }
.facts div:first-child { border-top: 0; }
.facts dt { color: #a39e94; }
.facts dd { margin: 0; text-align: right; font-weight: 600; }
.center { text-align: center; }
.app-mode .toast { bottom: calc(24px + env(safe-area-inset-bottom)); background: #ece8df; color: #0e0f11; max-width: calc(100% - 32px); text-align: center; }
Change history
Move store links to openapps.free
Release with preview
Bind agent address in policy
Use OpenApps service URLs and add contribution strip (retry)
Bounded source sync
Bounded source sync
Bounded source sync
Bounded source sync