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 f6f2112e77bc8c011e38c83a
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
/* Tasks. 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-foot { margin-top: 0; }
.page-pad { padding-block: 56px 80px; }
.narrow { max-width: 640px; }
.loading { display: flex; align-items: center; gap: 12px; color: var(--muted); }
.small { font-size: 14px; }
.grow { flex: 1; min-width: 0; }
.left { text-align: left; }
.link-btn { padding: 0; border: 0; background: none; color: var(--cobalt); font: inherit; cursor: pointer; display: inline-flex; align-items: center; gap: 5px; }
.link-btn:hover { color: var(--cobalt-ink); text-decoration: underline; }
.icon-btn { display: inline-grid; place-items: center; width: 38px; height: 38px; border: 0; border-radius: 10px; background: none; cursor: pointer; color: var(--muted); flex: none; }
.icon-btn:hover { background: #0000000a; color: var(--ink); }
.icon-btn-sm { width: 30px; height: 30px; border-radius: 8px; }
.input-sm { min-height: 38px; padding: 7px 10px; font-size: 15px; }
.btn-danger-solid { background: var(--brick); border-color: var(--brick); color: #fff; }
.btn-danger-solid:hover { background: #8f3824; }
.toast-slot { position: fixed; left: 0; right: 0; bottom: 0; z-index: 80; pointer-events: none; }
.toast-slot .toast { pointer-events: auto; max-width: calc(100% - 32px); }
/* Landing hero with the board maker */
.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) 460px; grid-template-areas: "intro start" "points start" "yours start"; grid-template-rows: auto auto 1fr; column-gap: 56px; align-items: start; }
.hero-intro { grid-area: intro; }
.hero-start { grid-area: start; }
.hero-points { grid-area: points; }
.hero-yours { grid-area: yours; }
.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: 200px; height: auto; margin-bottom: -6px; }
.create { display: grid; gap: 16px; padding: 24px; }
@media (max-width: 960px) { .app-hero-grid { grid-template-columns: minmax(0, 1fr); grid-template-areas: "intro" "yours" "start" "points"; grid-template-rows: none; row-gap: 26px; } .hero-points { margin-top: 0; } }
@media (max-width: 600px) { .app-hero { padding-top: 16px; } .create { padding: 18px; } .hero-art { width: 112px; margin-bottom: 4px; } }
.templates { display: grid; gap: 8px; border: 0; padding: 0; margin: 0; min-width: 0; }
.templates legend { margin-bottom: 8px; }
.tpl { display: grid; grid-template-columns: 20px minmax(0, 1fr); column-gap: 10px; align-items: baseline; padding: 11px 13px; border: 1px solid var(--line-strong); border-radius: var(--radius); background: #fff; cursor: pointer; transition: border-color .15s, background .15s; }
.tpl:hover { border-color: #b5bdc8; }
.tpl.on { border-color: var(--ink-solid); background: #fbfbfa; box-shadow: inset 0 0 0 1px var(--ink-solid); }
.tpl input { grid-row: span 2; margin: 0; width: 16px; height: 16px; accent-color: var(--ink-solid); transform: translateY(2px); }
.tpl-name { font: 600 15px/1.3 var(--sans); }
.tpl-sum { font-size: 13.5px; color: var(--muted); line-height: 1.4; }
.tpl:has(input:focus-visible) { outline: 2px solid var(--cobalt); outline-offset: 2px; }
.create-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.create-foot .link-btn { font-weight: 600; font-size: 14.5px; }
.import-note { display: grid; gap: 6px; }
.import-note .link-btn { justify-self: start; font-size: 14px; }
.your-boards { margin-top: 30px; }
@media (max-width: 960px) { .your-boards { margin-top: 0; } }
.your-boards ul { list-style: none; padding: 0; margin-top: 10px; display: grid; gap: 6px; max-width: 460px; }
.your-boards li { display: flex; align-items: center; gap: 10px; padding: 6px 6px 6px 14px; border: 1px solid var(--line); border-radius: 12px; background: #fff; }
.your-boards li a { flex: 1; min-width: 0; font-weight: 600; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.your-boards li a:hover { color: var(--cobalt); }
/* Landing sections */
.steps { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 28px; margin-top: 28px; counter-reset: step; padding: 0; }
.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; }
@media (max-width: 760px) { .steps { grid-template-columns: minmax(0, 1fr); } }
.features { list-style: none; padding: 0; margin-top: 26px; display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 14px; }
.features li { padding: 20px; border: 1px solid var(--line); border-radius: 16px; background: #fff; }
.tpl-links, .more-apps { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px; list-style: none; padding: 0; margin-top: 22px; }
.tpl-links a, .more-apps a { display: grid; gap: 4px; height: 100%; padding: 16px 18px; border: 1px solid var(--line); border-radius: 14px; background: #fff; color: var(--ink); }
.tpl-links a:hover, .more-apps a:hover { border-color: var(--line-strong); box-shadow: var(--shadow); color: var(--ink); }
.tpl-links strong, .more-apps strong { font: 400 22px/1.15 var(--serif); }
.tpl-links span, .more-apps span { color: var(--muted); font-size: 14px; }
.compare td:first-child { font-weight: 600; }
.compare td { min-width: 150px; }
.compare td:first-child { min-width: 130px; }
.trello-grid, .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) { .trello-grid, .api-grid { grid-template-columns: minmax(0, 1fr); gap: 24px; } }
.mini-steps { margin: 0; padding: 0 0 0 22px; display: grid; gap: 12px; font-size: 16px; color: #33363c; }
.api-grid code { font: 500 .88em var(--mono); padding: .1em .35em; border-radius: 5px; background: var(--panel); border: 1px solid var(--panel-line); }
/* Board page */
.board-page { display: flex; flex-direction: column; }
.board-page.view-board { height: calc(100dvh - 64px); min-height: 480px; }
.board-head { padding: 18px 24px 0; display: grid; gap: 12px; }
.board-head-inner { display: flex; align-items: center; justify-content: space-between; gap: 12px 20px; flex-wrap: wrap; }
.board-title-block { display: flex; align-items: center; gap: 12px; min-width: 0; flex-wrap: wrap; }
.board-title { font: 380 clamp(26px, 3vw, 34px)/1.1 var(--serif); letter-spacing: -.025em; overflow-wrap: anywhere; }
.board-actions { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.you-btn { max-width: 190px; padding-left: 8px; }
.you-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.invite { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.archived-note { padding: 10px 14px; }
.toolbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding-bottom: 12px; border-bottom: 1px solid var(--line); }
.segmented { display: inline-flex; gap: 3px; padding: 3px; border-radius: 11px; background: var(--panel); border: 1px solid var(--panel-line); }
.segmented button { display: inline-flex; align-items: center; gap: 6px; min-height: 34px; padding: 0 12px; border: 0; border-radius: 8px; background: transparent; cursor: pointer; font: 600 14px var(--sans); color: var(--muted); }
.segmented button[aria-selected="true"] { background: #fff; color: var(--ink-solid); box-shadow: 0 1px 3px #0000001a; }
.search { display: flex; align-items: center; gap: 8px; flex: 0 1 280px; min-width: 0; height: 40px; padding: 0 12px; border: 1px solid var(--line-strong); border-radius: var(--radius); background: #fff; color: var(--muted); }
.search:focus-within { border-color: var(--cobalt); box-shadow: 0 0 0 3px #2e5ec41f; }
.search input { flex: 1; min-width: 0; border: 0; outline: 0; background: transparent; font-size: 15px; color: var(--ink); }
.btn.is-on { border-color: var(--ink-solid); }
.filter-note { font-size: 14px; color: var(--muted); }
.board-main { flex: 1; min-height: 0; display: flex; flex-direction: column; }
@media (max-width: 700px) {
.board-head { padding: 14px 16px 0; }
.board-actions { margin-left: 0; width: 100%; }
.board-actions .you-btn { margin-right: auto; }
.segmented { flex: 1 1 100%; }
.segmented button { flex: 1; justify-content: center; padding: 0 8px; }
.search { flex: 1 1 auto; }
}
/* Kanban */
.kanban { flex: 1; min-height: 0; display: flex; align-items: flex-start; gap: 12px; overflow-x: auto; overflow-y: hidden; padding: 16px 24px 20px; overscroll-behavior-x: contain; }
.kanban-end { flex: 0 0 4px; height: 1px; }
.col-slot { display: flex; gap: 12px; height: 100%; flex: none; align-items: flex-start; }
.col { flex: none; width: 284px; max-height: 100%; display: flex; flex-direction: column; border-radius: 14px; background: var(--panel); border: 1px solid var(--panel-line); }
.col-head { display: flex; align-items: center; gap: 6px; padding: 8px 6px 4px 8px; cursor: grab; touch-action: manipulation; -webkit-user-select: none; user-select: none; }
.col-title-wrap { flex: 1; min-width: 0; font: inherit; }
.col-title { display: block; width: 100%; padding: 6px 6px; border: 0; border-radius: 7px; background: none; text-align: left; font: 650 15px/1.3 var(--sans); color: var(--ink-solid); cursor: inherit; overflow-wrap: anywhere; }
.col-title:not(:disabled):hover { background: #0000000a; }
.col-title:disabled { color: var(--ink-solid); }
.col-title-input { flex: 1; min-height: 36px; padding: 6px 8px; font-weight: 600; font-size: 15px; }
.col-count { padding: 2px 8px; border-radius: 999px; background: #fff; border: 1px solid var(--panel-line); font: 600 12px/1.4 var(--sans); color: var(--muted); }
.col-cards { flex: 1 1 auto; min-height: 8px; overflow-y: auto; padding: 4px 8px 4px; display: grid; gap: 8px; align-content: start; }
.col-empty { padding: 10px 8px; font-size: 13.5px; color: var(--faint); }
.tile-slot { display: grid; gap: 8px; }
.tile { -webkit-tap-highlight-color: transparent; display: grid; gap: 7px; width: 100%; padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px; background: #fff; box-shadow: 0 1px 1px #1a1d240d; text-align: left; cursor: pointer; overflow: hidden; position: relative; -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; touch-action: manipulation; transition: border-color .12s, box-shadow .12s; }
.tile:hover { border-color: var(--line-strong); }
.tile:focus-visible { outline: 2px solid var(--cobalt); outline-offset: 1px; }
.tile.has-cover { padding-top: 16px; }
.tile-cover { position: absolute; left: 0; right: 0; top: 0; height: 7px; }
.tile.lifted { border-color: var(--cobalt); box-shadow: 0 0 0 2px var(--cobalt), 0 10px 24px -10px #1a1d2466; transform: rotate(-1deg); }
.tile-labels { display: flex; flex-wrap: wrap; gap: 4px; }
.lbl { display: inline-flex; align-items: center; min-height: 20px; padding: 0 8px; border-radius: 999px; font: 600 11.5px/1.2 var(--sans); max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lbl-lg { min-height: 26px; padding: 0 10px; font-size: 13px; }
.lbl-swatch { display: inline-block; width: 22px; height: 6px; border-radius: 3px; }
.tile-title { font: 500 15px/1.4 var(--sans); color: var(--ink); overflow-wrap: anywhere; }
.tile-badges { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; color: var(--muted); }
.badge { display: inline-flex; align-items: center; gap: 4px; min-height: 22px; padding: 0 6px; border-radius: 6px; font: 600 12.5px/1 var(--sans); color: var(--muted); }
.badge-done { color: #2f5a3c; background: var(--sage-wash); }
.due-overdue { color: #7c2f1d; background: var(--brick-wash); }
.due-today { color: #6d5413; background: #f6ecc9; }
.due-done { color: #2f5a3c; background: var(--sage-wash); }
.tile-people { display: inline-flex; margin-left: auto; }
.tile-people .avatar + .avatar { margin-left: -6px; }
.avatar { display: inline-grid; place-items: center; flex: none; width: 26px; height: 26px; border-radius: 50%; background: var(--cobalt-wash); border: 2px solid #fff; color: var(--cobalt-ink); font: 650 10.5px/1 var(--sans); letter-spacing: .02em; }
.avatar-more { background: var(--panel); color: var(--muted); }
.tile-ph { border-radius: 10px; background: #dfe5ee; border: 1px dashed #b9c3d1; }
.col-ph { flex: none; align-self: stretch; border-radius: 14px; background: #e7ecf3; border: 1px dashed #b9c3d1; max-height: 100%; }
.add-card { display: flex; align-items: center; gap: 6px; margin: 4px 8px 8px; padding: 9px 8px; border: 0; border-radius: 8px; background: none; cursor: pointer; color: var(--muted); font: 600 14px var(--sans); text-align: left; }
.add-card:hover { background: #0000000a; color: var(--ink); }
.composer { display: grid; gap: 8px; padding: 4px 8px 10px; }
.composer-input { min-height: 64px; font-size: 15px; padding: 9px 11px; }
.add-list { flex: none; display: flex; align-items: center; gap: 6px; width: 284px; padding: 12px 14px; border: 1px dashed var(--line-strong); border-radius: 14px; background: #ffffff99; cursor: pointer; color: var(--muted); font: 600 14.5px var(--sans); }
.add-list:hover { background: #fff; color: var(--ink); }
.add-list-open { display: grid; gap: 8px; cursor: default; background: var(--panel); border-style: solid; border-color: var(--panel-line); }
.is-dragging { display: none !important; }
.tile-slot:has(> .is-dragging) { display: none; }
.drag-ghost { position: fixed; left: 0; top: 0; z-index: 90; pointer-events: none; will-change: transform; }
.drag-ghost .tile { box-shadow: 0 14px 30px -10px #1a1d2466; border-color: var(--line-strong); }
.drag-ghost .col-ghost { width: 100%; box-shadow: 0 14px 30px -10px #1a1d2466; }
body.dragging, body.dragging * { cursor: grabbing !important; -webkit-user-select: none; user-select: none; }
@media (max-width: 700px) {
.kanban { padding: 14px 16px 18px; scroll-snap-type: x mandatory; scroll-padding: 0 16px; gap: 10px; }
body.dragging .kanban { scroll-snap-type: none; }
.col, .add-list { width: min(82vw, 300px); scroll-snap-align: start; }
.col-slot { gap: 10px; }
}
/* Popovers and menus */
.popover { position: fixed; z-index: 70; width: max-content; min-width: 220px; max-width: min(340px, calc(100vw - 16px)); max-height: min(70vh, 560px); overflow-y: auto; padding: 6px; border: 1px solid var(--line); border-radius: 12px; background: #fff; box-shadow: 0 18px 50px -14px #1a1d2459; }
.menu { display: grid; }
.menu button { display: flex; align-items: center; gap: 10px; min-height: 40px; padding: 0 10px; border: 0; border-radius: 8px; background: none; cursor: pointer; font: 500 14.5px var(--sans); color: var(--ink); text-align: left; }
.menu button:hover:not(:disabled) { background: var(--panel); }
.menu button:disabled { color: var(--faint); cursor: default; }
.menu button svg { color: var(--muted); }
.menu hr { border: 0; border-top: 1px solid var(--line); margin: 4px 0; }
.menu-form { display: grid; gap: 12px; padding: 8px; }
.menu-title { font: 650 12px/1.2 var(--sans); letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.picker { width: min(300px, calc(100vw - 32px)); }
.pick-list { list-style: none; padding: 0; display: grid; gap: 2px; }
.pick-list li { display: flex; align-items: center; gap: 8px; min-height: 40px; }
.pick-list li + li { border-top: 1px solid var(--line); }
.pick-check { flex: 1; min-width: 0; gap: 8px; padding: 4px 0; }
.label-edit { flex: 1; padding: 8px 0; }
.filter-panel { width: min(300px, calc(100vw - 32px)); }
.filter-panel fieldset { display: grid; gap: 6px; border: 0; padding: 0; margin: 0; min-width: 0; }
.filter-panel legend { margin-bottom: 6px; font: 600 13.5px var(--sans); color: #33363c; }
.filter-panel .check { font-size: 14.5px; }
.swatches { display: flex; flex-wrap: wrap; gap: 6px; }
.swatch { width: 30px; height: 26px; border-radius: 7px; border: 2px solid transparent; cursor: pointer; padding: 0; }
.swatch[aria-checked="true"] { border-color: var(--ink-solid); box-shadow: inset 0 0 0 2px #fff; }
.swatch-none { background: repeating-linear-gradient(135deg, #fff 0 5px, #e8eaee 5px 10px); border-color: var(--line-strong); }
.swatch-none[aria-checked="true"] { border-color: var(--ink-solid); }
/* Modal */
.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(90vh, 920px); border-radius: 18px; background: #fff; box-shadow: 0 30px 80px -20px #0006; animation: rise .18s ease; outline: none; }
.modal-wide { width: min(760px, 100%); }
.modal-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; padding: 18px 20px 6px; }
.modal-title { flex: 1; min-width: 0; font: 400 26px/1.2 var(--serif); letter-spacing: -.015em; }
.modal-body { padding: 10px 20px 22px; overflow-y: auto; overflow-x: hidden; }
.modal .stack { grid-template-columns: minmax(0, 1fr); }
.modal-foot { display: flex; align-items: center; gap: 10px; padding: 14px 20px; 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, .modal-wide { width: 100%; max-height: 94dvh; border-radius: 18px 18px 0 0; }
.modal-head { padding: 14px 14px 4px 16px; }
.modal-body { padding: 8px 16px 22px; }
}
.title-edit { width: 100%; resize: none; overflow: hidden; padding: 4px 6px; margin-left: -6px; border: 1px solid transparent; border-radius: 8px; background: transparent; font: 400 24px/1.25 var(--serif); letter-spacing: -.015em; color: var(--ink-solid); }
.title-edit:hover:not([readonly]) { border-color: var(--line); }
.title-edit:focus { outline: none; border-color: var(--cobalt); box-shadow: 0 0 0 3px #2e5ec41f; background: #fff; }
.card-where { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-bottom: 14px; }
.move-btn { min-height: 30px; padding: 0 10px; color: var(--cobalt); }
.props { display: grid; gap: 10px; padding: 14px 0 18px; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.prop { display: grid; grid-template-columns: 110px minmax(0, 1fr); gap: 12px; align-items: center; min-height: 34px; }
.prop-label { font: 600 13.5px var(--sans); color: var(--muted); }
.prop-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.chip-btn { display: inline-flex; align-items: center; gap: 5px; min-height: 30px; padding: 0 10px; border: 1px dashed var(--line-strong); border-radius: 999px; background: #fff; cursor: pointer; font: 600 13px var(--sans); color: var(--muted); }
.chip-btn:hover { border-style: solid; color: var(--ink); }
.person { display: inline-flex; align-items: center; gap: 6px; min-height: 30px; padding: 0 10px 0 2px; border-radius: 999px; background: var(--panel); font: 500 14px var(--sans); }
.person-sm { min-height: 26px; font-size: 13px; }
.person-sm .avatar { width: 22px; height: 22px; font-size: 9.5px; }
.due-edit { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.due-edit .input { width: auto; }
@media (max-width: 600px) { .prop { grid-template-columns: minmax(0, 1fr); gap: 4px; } }
.detail-section { display: grid; gap: 10px; padding-top: 20px; }
.detail-h { display: flex; align-items: center; gap: 8px; font: 650 15px var(--sans); color: var(--ink-solid); }
.detail-h svg { color: var(--muted); }
.md { font-size: 15.5px; line-height: 1.6; max-width: none; overflow-wrap: anywhere; }
.md > * + * { margin-top: .7em; }
.md h1, .md h2, .md h3 { font: 650 16.5px/1.35 var(--sans); margin-top: 1.1em; letter-spacing: 0; }
.desc-input { min-height: 160px; font-size: 15px; }
.desc-empty { display: block; width: 100%; min-height: 64px; padding: 12px; border: 0; border-radius: 10px; background: var(--panel); color: var(--muted); text-align: left; cursor: pointer; font: inherit; font-size: 15px; }
.desc-empty:hover { background: #e8edf5; color: var(--ink); }
.progress { display: flex; align-items: center; gap: 10px; }
.progress-num { width: 36px; font: 600 12.5px var(--sans); color: var(--muted); }
.progress-bar { flex: 1; height: 7px; border-radius: 4px; background: var(--panel); overflow: hidden; }
.progress-bar span { display: block; height: 100%; background: var(--sage); border-radius: 4px; transition: width .2s; }
.checklist { list-style: none; padding: 0; display: grid; gap: 2px; }
.checklist li { display: flex; align-items: center; gap: 10px; min-height: 40px; padding: 0 2px; border-radius: 8px; }
.checklist li:hover { background: #fafbfc; }
.checklist input[type="checkbox"] { width: 18px; height: 18px; accent-color: var(--sage); flex: none; }
.check-text { flex: 1; min-width: 0; padding: 6px 4px; border: 0; background: none; text-align: left; font: 400 15px/1.4 var(--sans); color: var(--ink); cursor: text; overflow-wrap: anywhere; }
.is-done .check-text { color: var(--faint); text-decoration: line-through; }
.comments { list-style: none; padding: 0; display: grid; gap: 14px; }
.comments li { display: flex; gap: 10px; align-items: flex-start; }
.comment-body { flex: 1; min-width: 0; }
.comment-meta { font-size: 14px; }
.comment-text { margin-top: 4px; padding: 9px 12px; border-radius: 10px; background: var(--panel); white-space: pre-wrap; overflow-wrap: anywhere; font-size: 15px; }
.comment-tools { display: flex; gap: 14px; margin-top: 4px; font-size: 13px; }
.comment-input { min-height: 70px; font-size: 15px; }
.card-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 24px; padding-top: 16px; border-top: 1px solid var(--line); }
.link-code { flex: 1 1 180px; 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; }
.device-list { list-style: none; padding: 0; display: grid; }
.device-list li { display: flex; align-items: center; gap: 10px; min-height: 48px; border-top: 1px solid var(--line); }
.device-list li:first-child { border-top: 0; }
.danger-zone { padding-top: 16px; border-top: 1px solid var(--line); }
/* List view */
.table-view { padding: 16px 24px 40px; }
.cards-table { background: #fff; border: 1px solid var(--line); border-radius: 14px; border-collapse: separate; border-spacing: 0; overflow: hidden; }
.cards-table td { vertical-align: middle; }
.cards-table tr:last-child td { border-bottom: 0; }
.sort-btn { padding: 0; border: 0; background: none; font: inherit; letter-spacing: inherit; text-transform: inherit; color: inherit; cursor: pointer; }
.row-open { display: inline-flex; align-items: center; gap: 8px; padding: 0; border: 0; background: none; text-align: left; font: 600 15px/1.4 var(--sans); color: var(--ink); cursor: pointer; overflow-wrap: anywhere; }
.row-open:hover { color: var(--cobalt); }
.dot { display: inline-block; flex: none; width: 10px; height: 10px; border-radius: 50%; }
.t-list { color: var(--muted); white-space: nowrap; }
.view-empty { padding: 32px 24px; }
@media (max-width: 760px) {
.table-view { padding: 14px 16px 32px; }
.cards-table, .cards-table tbody, .cards-table tr, .cards-table td { display: block; }
.cards-table thead { display: none; }
.cards-table tr { padding: 12px 14px; border-bottom: 1px solid var(--line); }
.cards-table tr:last-child { border-bottom: 0; }
.cards-table td { padding: 2px 0; border: 0; }
.cards-table td:empty { display: none; }
.cards-table td.t-title { padding-bottom: 6px; }
.cards-table td[data-label]::before { content: attr(data-label) ": "; color: var(--faint); font-size: 13px; }
.cards-table td[data-label] .prop-chips { display: inline-flex; vertical-align: middle; }
}
/* Calendar view */
.calendar { padding: 16px 24px 40px; }
.cal-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.cal-title { font: 380 26px/1.2 var(--serif); letter-spacing: -.02em; }
.cal-note { margin-top: 6px; }
.cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); margin-top: 14px; border: 1px solid var(--line); border-radius: 14px; overflow: hidden; background: var(--line); gap: 1px; }
.cal-wd { padding: 8px 10px; background: #fff; font: 650 11.5px/1 var(--sans); letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.cal-day { min-height: 112px; padding: 6px; background: #fff; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.cal-day.other { background: #fafbfc; }
.cal-day.other .cal-num { color: var(--faint); }
.cal-num { font: 600 13px var(--sans); color: #33363c; padding: 2px 4px; align-self: flex-start; border-radius: 6px; }
.cal-day.today .cal-num { background: var(--ink-solid); color: #fff; }
.cal-chip { display: flex; align-items: center; gap: 5px; width: 100%; min-height: 26px; padding: 3px 7px; border: 0; border-radius: 6px; background: var(--panel); cursor: pointer; font: 500 12.5px/1.3 var(--sans); color: var(--ink); text-align: left; }
.cal-chip:hover { filter: brightness(.97); }
.cal-chip-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.cal-time { font-weight: 650; flex: none; }
.cal-more { font-size: 12.5px; padding: 0 4px; }
.cal-agenda { display: none; }
@media (max-width: 760px) {
.calendar { padding: 14px 16px 32px; }
.cal-grid { display: none; }
.cal-agenda { display: grid; grid-template-columns: minmax(0, 1fr); gap: 14px; margin-top: 14px; }
.agenda-day { display: grid; grid-template-columns: minmax(0, 1fr); gap: 6px; }
.agenda-date { font: 650 13px var(--sans); color: var(--muted); letter-spacing: .02em; }
.agenda-day.today .agenda-date { color: var(--ink-solid); }
.agenda-cards { display: grid; grid-template-columns: minmax(0, 1fr); gap: 6px; }
.agenda-cards .cal-chip { min-height: 40px; font-size: 14.5px; padding: 8px 12px; border-radius: 10px; }
}
/* Template pages (built as static HTML by template-pages.ts) */
.tpl-hero > * { max-width: 860px; }
.tpl-hero h1 { margin-top: 12px; }
.tpl-hero .lede { margin-top: 18px; }
.crumbs { margin-bottom: 18px; font-size: 14px; color: var(--faint); }
.crumbs a { color: var(--muted); }
.tpl-cta { display: flex; align-items: center; flex-wrap: wrap; gap: 12px 16px; margin-top: 26px; }
.tpl-preview { margin-top: 20px; padding-inline: max(24px, calc((100% - 1180px) / 2)); overflow-y: visible; }
.tpl-preview .col { width: 250px; }
.tpl-preview .tile { cursor: default; }
.tpl-cols { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 40px; }
.tpl-list { margin-top: 14px; padding-left: 20px; display: grid; gap: 8px; color: #33363c; }
@media (max-width: 760px) { .tpl-cols { grid-template-columns: minmax(0, 1fr); gap: 28px; } .tpl-preview { padding-inline: 16px; } }
.hero-yours:empty { display: none; }
Change history
Point OpenApps links to openapps.free
Bind agent address in policy
Use OpenApps service URLs and add contribution strip
Bounded source sync
Bounded source sync
Bounded source sync
Bounded source sync