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 7385a6c1c47153b1728160ff
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
/* Book. Shared look comes from /kit.css (dialogs, skeletons, empty states, motion); this is the app's own layout. */
body.app-mode .landing-only { display: none !important; }
body:not(.app-mode) #app:empty { display: none; }
/* App screens fill the screen, so the footer stays below the fold while they load and never jumps. */
body.app-mode #app { min-height: calc(100vh - 64px); min-height: calc(100dvh - 64px); }
.page-pad { padding-block: 56px 80px; }
.narrow { max-width: 640px; }
.link-btn { display: inline-flex; align-items: center; justify-self: start; gap: 4px; padding: 2px 0; border: 0; background: none; color: var(--cobalt); font: var(--type-control); cursor: pointer; }
@media (hover: hover) { .link-btn:hover { color: var(--cobalt-ink); } }
@media (pointer: coarse) { .link-btn { min-height: 44px; } }
.optional { margin-left: 6px; font-weight: 400; color: var(--faint); }
.select-inline { width: auto; max-width: 100%; min-height: 40px; padding: 6px 30px 6px 10px; font: var(--type-input); font-weight: 600; }
.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: #fff; border: 1px solid var(--panel-line); font: 13px var(--mono); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Skeletons, shaped like what loads in their place */
.sk-name { width: 40%; }
.sk-title { height: 34px; width: 85%; margin-top: 10px; }
.sk-fact { width: 50%; }
.sk-h { width: 180px; height: 18px; }
.sk-month { width: 140px; height: 16px; margin: 12px auto 4px; }
.sk-cal { margin-top: 14px; }
.sk-day { width: 100%; max-width: 48px; aspect-ratio: 1; justify-self: center; border-radius: 50%; }
.sk-link { height: 62px; margin-top: 22px; border-radius: 12px; }
.sk-url { width: 70%; }
.sk-row { height: 78px; border-radius: 14px; }
.sk-tab { width: 160px; height: 16px; margin: 14px 0; }
.sk-dash-title { height: 44px; width: min(420px, 80vw); }
/* Landing hero with the page maker */
.app-hero { padding: 44px 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) 470px; gap: 56px; align-items: start; }
.app-hero-copy { padding-top: 12px; }
.hero-art { width: 190px; height: auto; margin-bottom: 4px; }
.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); }
/* On narrow screens the page maker comes right after the pitch, before the bullet points. */
@media (max-width: 960px) {
.app-hero-grid { grid-template-columns: minmax(0, 1fr); gap: 0; }
.app-hero-copy { display: contents; }
#your-pages { order: 1; }
#create { order: 2; margin-top: 28px; }
.hero-points { order: 3; margin-top: 28px; }
}
@media (max-width: 600px) { .app-hero { padding: 24px 0 48px; } .hero-art { width: 130px; } .app-hero .display { font-size: 40px; } }
.your-pages { margin-top: 28px; display: grid; gap: 10px; }
.your-title { font: var(--type-caps); letter-spacing: .12em; text-transform: uppercase; color: var(--muted); }
.your-list { list-style: none; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 8px; }
.your-list a { display: grid; gap: 2px; min-height: 56px; padding: 10px 14px; border: 1px solid var(--line); border-radius: 12px; background: #fff; color: var(--ink); transition: border-color var(--motion-fast) var(--ease-out), box-shadow var(--motion-fast) var(--ease-out); }
@media (hover: hover) { .your-list a:hover { border-color: var(--line-strong); box-shadow: var(--shadow); color: var(--ink); } }
.your-list strong { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.your-list span { font-size: 13px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Page maker */
.editor { display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px; padding: 22px; }
.editor-submit { display: grid; gap: 10px; }
.seg { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 4px; padding: 4px; border: 1px solid var(--line-strong); border-radius: 12px; background: #fff; }
.seg button { min-height: 40px; border: 0; border-radius: 8px; background: none; color: #3c4048; font: var(--type-control); cursor: pointer; transition: background-color var(--motion-fast) var(--ease-out), color var(--motion-fast) var(--ease-out); }
@media (hover: hover) { .seg button:hover { background: var(--panel); } }
@media (pointer: coarse) { .seg button { min-height: 44px; } }
.seg button.on, .seg button.on:hover { background: var(--ink-solid); color: #fff; }
.times-head { display: flex; align-items: center; justify-content: space-between; gap: 6px 12px; flex-wrap: wrap; }
.zone-note { display: inline-flex; align-items: center; gap: 4px; font-size: 13px; color: var(--muted); }
.zone-note .link-btn { margin-left: 4px; }
.hours-summary { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 14px; border: 1px solid var(--line); border-radius: 12px; background: #fff; font-size: 15px; }
.hours-summary p + p { margin-top: 2px; }
.hours { display: grid; border: 1px solid var(--line); border-radius: 12px; background: #fff; }
/* The day, then its ranges; on phones the ranges drop to their own full-width line. */
.day-row { display: grid; grid-template-columns: 72px minmax(0, 1fr); align-items: start; gap: 6px 8px; padding: 8px 10px; }
.day-row + .day-row { border-top: 1px solid var(--line); }
.day-check { min-height: 44px; font: var(--type-control); }
.day-check input { width: 18px; height: 18px; }
.day-ranges { display: grid; gap: 6px; }
.day-off { display: flex; align-items: center; min-height: 44px; font-size: 15px; color: var(--faint); }
.range { display: flex; align-items: center; gap: 6px; }
.select-time { flex: 1 1 0; width: 0; min-width: 0; min-height: 44px; padding: 8px 26px 8px 10px; font: var(--type-input); }
.range-bad .select-time { border-color: var(--brick); }
.slot-to { flex: none; font-size: 14px; color: var(--muted); }
@media (max-width: 600px) {
.day-ranges { grid-column: 1 / -1; }
}
.off-list { list-style: none; padding: 0; display: grid; gap: 6px; }
.off-list li { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 44px; padding: 4px 4px 4px 14px; border: 1px solid var(--line); border-radius: 10px; background: #fff; font-size: 15px; }
.off-add { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 10px; padding: 12px; border: 1px solid var(--line); border-radius: 12px; background: #fff; }
.off-buttons { grid-column: 1 / -1; --gap: 8px; }
.address { display: flex; align-items: center; min-height: 46px; border: 1px solid var(--line-strong); border-radius: var(--radius); background: #fff; overflow: hidden; transition: border-color var(--motion-fast) var(--ease-out), box-shadow var(--motion-fast) var(--ease-out); }
.address:focus-within { border-color: var(--cobalt); box-shadow: 0 0 0 3px #2e5ec41f; }
.address.address-bad { border-color: var(--brick); }
.address-host { flex: none; max-width: 68%; padding-left: 13px; color: var(--muted); font-size: 16px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.address input { flex: 1; min-width: 0; padding: 11px 13px 11px 1px; border: 0; outline: none; background: none; font: var(--type-input); font-weight: 600; }
.field small.good { color: #2f5a3c; }
.field small.bad { color: var(--brick); }
.address-fixed { font-size: 15.5px; color: var(--muted); overflow-wrap: anywhere; }
.address-fixed strong { color: var(--ink); font-weight: 600; }
.more { display: grid; grid-template-columns: minmax(0, 1fr); gap: 18px; padding-top: 4px; }
.more-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
.question { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 8px; }
.question .input { flex: 1 1 260px; min-width: 0; }
.check-sm { font-size: 14px; color: #3c4048; white-space: nowrap; }
.check-sm input { width: 16px; height: 16px; }
.editor-edit { box-shadow: none; }
.editor-edit .action-bar { justify-content: flex-start; }
@media (max-width: 600px) {
.editor { padding: 16px; gap: 18px; }
.more-grid { grid-template-columns: minmax(0, 1fr); }
.day-row { padding: 6px 8px 8px; }
.question .check-sm { margin-left: auto; }
}
/* Landing sections */
.steps { display: grid; grid-template-columns: repeat(3, 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 { font: 600 18px/1.3 var(--sans); }
.steps p { margin-top: 8px; color: #4a4e56; }
@media (max-width: 760px) { .steps { 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: 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); }
@media (hover: hover) { .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; }
@media (max-width: 760px) {
.compare { min-width: 640px; font-size: 14px; }
.compare th, .compare td { padding: 11px 12px; }
}
/* Public booking page */
.bp { padding: 40px 0 72px; background: linear-gradient(180deg, #faf6ee 0%, #fdfdfc 360px); }
.bp-wrap { max-width: 1040px; }
.bp-card { display: grid; grid-template-columns: 300px minmax(0, 1fr); overflow: hidden; }
.bp-info { display: grid; align-content: start; padding: 28px 26px; border-right: 1px solid var(--line); }
.bp-name { font: 600 15px/1.3 var(--sans); color: var(--muted); overflow-wrap: anywhere; }
.bp-title { margin-top: 6px; font: 380 clamp(28px, 3vw, 36px)/1.1 var(--serif); letter-spacing: -.025em; overflow-wrap: anywhere; }
.bp-facts { list-style: none; padding: 0; margin-top: 18px; display: grid; gap: 10px; font-size: 15px; color: #3c4048; }
.bp-facts li { display: flex; gap: 10px; align-items: center; }
.bp-facts svg { flex: none; color: var(--muted); }
.bp-desc { margin-top: 18px; font-size: 15px; color: #3d4148; white-space: pre-wrap; overflow-wrap: anywhere; }
.bp-main { display: grid; grid-template-columns: minmax(0, 1fr); align-content: start; gap: 18px; padding: 26px 28px 28px; min-width: 0; }
.bp-step { display: grid; grid-template-columns: minmax(0, 1fr); gap: 18px; }
.bp-h { font: 600 19px/1.3 var(--sans); letter-spacing: -.01em; }
.move-note strong { font-weight: 600; color: var(--ink); }
.bp-pick { display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px; }
.bp-pick.has-day { grid-template-columns: minmax(0, 1fr) 210px; }
.bp-times { display: grid; align-content: start; gap: 10px; min-width: 0; scroll-margin-top: 80px; }
.bp-day { font: 600 15px/1.3 var(--sans); }
.time-list { list-style: none; padding: 0; display: grid; gap: 8px; max-height: 380px; overflow-y: auto; padding-right: 2px; }
.time-btn { width: 100%; min-height: 46px; border: 1px solid #c9d6f0; border-radius: 10px; background: #fff; color: var(--cobalt-ink); font: 600 15px/1 var(--sans); cursor: pointer; transition: background-color var(--motion-fast) var(--ease-out), border-color var(--motion-fast) var(--ease-out), transform var(--motion-fast) var(--ease-out); }
@media (hover: hover) { .time-btn:hover { background: var(--cobalt-wash); border-color: var(--cobalt); } }
.bp-foot { margin-top: 18px; text-align: center; font-size: 13.5px; color: var(--muted); }
.tz-bar { display: flex; align-items: center; gap: 8px 10px; flex-wrap: wrap; font-size: 14.5px; color: #3d4148; }
.tz-bar strong { font-weight: 600; }
.tz-bar svg { color: var(--muted); }
.tz-bar .link-btn { margin-left: 6px; }
.cal { padding: 4px 0; }
.cal-head { display: flex; align-items: center; justify-content: space-between; }
.cal-month { font: 600 15.5px/1 var(--sans); }
.cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; margin-top: 6px; }
.cal-wd { padding: 6px 0; text-align: center; font: var(--type-caps); color: var(--faint); text-transform: uppercase; letter-spacing: .04em; }
.cal-day { aspect-ratio: 1; width: 100%; max-width: 48px; justify-self: center; border: 0; border-radius: 50%; background: transparent; color: #b4b9c0; font: 500 15px/1 var(--sans); cursor: default; transition: background-color var(--motion-fast) var(--ease-out), color var(--motion-fast) var(--ease-out); }
.cal-day.open { background: var(--cobalt-wash); color: var(--cobalt-ink); font-weight: 650; cursor: pointer; }
@media (hover: hover) { .cal-day.open:hover { background: #d7e3f8; } }
.cal-day.today { box-shadow: inset 0 0 0 1px var(--line-strong); }
.cal-day.on, .cal-day.on:hover { background: var(--cobalt); color: #fff; }
.book-form { display: grid; grid-template-columns: minmax(0, 1fr); gap: 14px; max-width: 520px; }
.back-link { margin-bottom: -4px; }
.chosen { display: grid; gap: 2px; }
.chosen-time { font-size: 16px; font-weight: 600; }
.chosen-time .muted { margin-left: 4px; font-weight: 400; }
.textarea-sm { min-height: 72px; }
@media (max-width: 860px) {
.bp { padding-top: 20px; }
.bp-card { grid-template-columns: minmax(0, 1fr); }
.bp-info { padding: 22px 20px 18px; border-right: 0; border-bottom: 1px solid var(--line); }
.bp-main { padding: 20px; }
.bp-pick.has-day { grid-template-columns: minmax(0, 1fr); }
.time-list { grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); max-height: none; overflow: visible; }
}
@media (max-width: 600px) {
.bp-wrap { width: calc(100% - 24px); }
.bp-info { padding: 18px 16px 16px; }
.bp-main { padding: 18px 16px 20px; }
.bp-facts { margin-top: 12px; }
}
/* One booking */
.manage { max-width: 680px; display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px; }
.done-head { display: grid; gap: 12px; }
.done-mark { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; background: var(--sage-wash); color: #2f6b45; }
.meet-card { display: grid; padding: 24px 26px; }
.meet-off { box-shadow: none; }
.meet-title { margin-top: 10px; font: 380 clamp(26px, 3.2vw, 34px)/1.12 var(--serif); letter-spacing: -.022em; overflow-wrap: anywhere; }
.meet-day { margin-top: 14px; font: 600 17px/1.35 var(--sans); }
.meet-time { margin-top: 2px; font-size: 16px; color: #3d4148; }
.meet-link { display: flex; align-items: center; gap: 12px; margin-top: 20px; padding: 12px 14px; border: 1px solid var(--panel-line); border-radius: 12px; background: var(--panel); }
.meet-icon { display: grid; place-items: center; flex: none; width: 36px; height: 36px; border-radius: 10px; background: #fff; color: var(--cobalt); }
.meet-link-text { display: grid; gap: 2px; flex: 1; min-width: 0; }
.meet-link-text a { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.meet-actions { margin-top: 16px; }
.meet-off .meet-title, .meet-off .meet-day, .meet-off .meet-time { color: var(--muted); }
.keep-box { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; padding: 18px 20px; border: 1px solid var(--line); border-radius: 16px; background: #fff; }
.keep-actions { --gap: 8px; }
.you-gave { display: grid; gap: 10px; }
.you-gave dl { display: grid; gap: 8px; margin: 0; }
.you-gave dl > div { display: grid; grid-template-columns: 140px minmax(0, 1fr); gap: 12px; font-size: 15px; }
.you-gave dt { color: var(--muted); }
.you-gave dd { margin: 0; overflow-wrap: anywhere; white-space: pre-wrap; }
@media (max-width: 600px) {
.meet-card { padding: 20px 18px; }
.meet-actions .btn, .keep-actions .btn { flex: 1 1 0; }
.meet-link { flex-wrap: wrap; }
.you-gave dl > div { grid-template-columns: minmax(0, 1fr); gap: 0; }
}
/* Owner's dashboard */
.dash-head { border-bottom: 1px solid var(--line); background: linear-gradient(180deg, #faf6ee, #fdfdfc); }
.dash-head-inner { display: flex; align-items: flex-end; justify-content: space-between; gap: 18px 24px; flex-wrap: wrap; padding: 30px 0 18px; }
.dash-title-block { display: grid; min-width: 0; }
.dash-title { margin-top: 8px; font: 360 clamp(30px, 4vw, 44px)/1.08 var(--serif); letter-spacing: -.03em; overflow-wrap: anywhere; }
.dash-meta { margin-top: 8px; font-size: 15px; color: var(--muted); }
.dash-link { display: grid; gap: 8px; justify-items: start; min-width: 0; }
.dash-url { max-width: 100%; font: 600 15px/1.3 var(--sans); overflow-wrap: anywhere; }
.dash-link-actions { --gap: 8px; }
.tabs { display: flex; gap: 4px; }
.tabs button { position: relative; display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 14px; border: 0; background: none; color: var(--muted); font: var(--type-control); cursor: pointer; transition: color var(--motion-fast) var(--ease-out); }
.tabs button.on { color: var(--ink-solid); }
.tabs button::after { content: ""; position: absolute; left: 10px; right: 10px; bottom: -1px; height: 2px; border-radius: 2px; background: var(--ink-solid); transform: scaleX(0); transition: transform var(--motion) var(--ease-out); }
.tabs button.on::after { transform: scaleX(1); }
.tab-count { display: grid; place-items: center; min-width: 22px; height: 22px; padding: 0 6px; border-radius: 999px; background: var(--cobalt-wash); color: var(--cobalt-ink); font-size: 12.5px; }
.dash-body { display: grid; grid-template-columns: minmax(0, 1fr); gap: 18px; max-width: 860px; padding-top: 26px; padding-bottom: 80px; }
.invite { position: relative; display: flex; align-items: center; gap: 12px 16px; flex-wrap: wrap; padding-right: 52px; }
.invite-text { flex: 1 1 320px; }
.invite-actions { --gap: 8px; }
.invite-close { position: absolute; top: 6px; right: 6px; color: #2f5a3c; }
.feed-cta { position: relative; display: flex; align-items: center; justify-content: space-between; gap: 12px 18px; flex-wrap: wrap; padding: 14px 52px 14px 18px; border: 1px solid var(--panel-line); border-radius: 14px; background: var(--panel); }
.feed-close { position: absolute; top: 6px; right: 6px; color: var(--muted); }
.feed-cta > div:first-child { flex: 1 1 320px; display: grid; gap: 2px; }
.feed-title { font: 600 15.5px/1.35 var(--sans); }
.feed-cta .muted { font-size: 14.5px; }
.tz-note { font-size: 14px; color: var(--muted); }
.bk-days { display: grid; gap: 18px; }
.day-label { margin-bottom: 8px; font: var(--type-caps); letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.bk-list { list-style: none; padding: 0; border: 1px solid var(--line); border-radius: 14px; background: #fff; overflow: hidden; }
.bk { display: grid; grid-template-columns: 96px minmax(0, 1fr) auto; gap: 8px 16px; align-items: start; padding: 14px 16px; }
.bk + .bk { border-top: 1px solid var(--line); }
.bk-time { display: grid; gap: 2px; }
.bk-time strong { font: 650 15.5px/1.3 var(--sans); }
.bk-time span { font-size: 13.5px; color: var(--muted); }
.bk-who { display: grid; gap: 4px; min-width: 0; font-size: 15px; }
.bk-who p { overflow-wrap: anywhere; }
.bk-who a { margin-left: 6px; font-size: 14.5px; }
.bk-answer { font-size: 14.5px; color: #3d4148; white-space: pre-wrap; }
.bk-answer span { margin-right: 6px; color: var(--muted); }
.bk-status { font-size: 13.5px; color: var(--brick); font-weight: 600; }
.bk-moved { font-size: 13.5px; color: var(--cobalt-ink); font-weight: 600; }
.bk-off .bk-time strong, .bk-off .bk-who strong { color: var(--muted); text-decoration: line-through; text-decoration-thickness: 1px; }
.bk-actions { display: flex; gap: 6px; }
.fold summary { display: flex; align-items: center; min-height: 44px; cursor: pointer; font: var(--type-control); color: #3c4048; }
.fold[open] summary { margin-bottom: 6px; }
.fold[open] > .bk-days { animation: oa-enter var(--motion) var(--ease-out); }
.settings { display: grid; grid-template-columns: minmax(0, 1fr) 280px; gap: 24px; align-items: start; }
.admin-box { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; padding: 18px; border: 1px solid var(--panel-line); border-radius: 16px; background: var(--panel); }
.admin-box .dropdown { justify-self: start; }
@media (max-width: 860px) {
.settings { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 600px) {
.dash-head-inner { padding-top: 22px; }
.bk { grid-template-columns: 76px minmax(0, 1fr); padding: 12px 14px; }
.bk-actions { grid-column: 1 / -1; }
.bk-actions .btn { flex: 1; }
.bk-who a { display: block; margin-left: 0; }
}
Change history
Add favicon.ico and link tag
Quality pass: guest reschedule, days off, calendar feed, API docs
Bounded source sync
Bounded source sync
Bounded source sync
Bounded source sync
Bounded source sync
Bounded source sync
Bounded source sync