Back to Sketch Loop
SOURCE / PINNED RELEASE

Made of little things.

Sketch Loop

Release
14966bba4a2a
Author-recorded commit
e68361295d81…
License
LICENSE
Author’s source reference
nostr://npub1n8ga89w8h6tvwamxusfyzexw8gjy84yxu9rxgnmk955cxtml4ujswzxydd/wss%3A%2F%2Fgit.napplet.soy%2F/n-929bc2a88cb

Archive hash verified: 5e0385e3c08f944f. The source-to-build association is the author’s claim; it has not been independently rebuilt.

src/styles.css
:root {
  --bg: #141b1c; --fg: #edf2e9; --primary: #b9ed80;
  --surface: color-mix(in srgb, var(--bg) 94%, var(--fg));
  --raised: color-mix(in srgb, var(--bg) 89%, var(--fg));
  --border: color-mix(in srgb, var(--fg) 16%, var(--bg));
  --muted: color-mix(in srgb, var(--fg) 57%, var(--bg));
  --accent-ink: #111c17; --control-h: 28px;
  font: 13px/1.45 'Avenir Next', 'Segoe UI', sans-serif;
  color-scheme: dark;
}
* { box-sizing: border-box; }
html, body, #app { height: 100%; margin: 0; background: var(--bg); color: var(--fg); }
body { overflow: hidden; }
button, input, select, textarea { font: inherit; color: inherit; }
button, select, input { min-width: 0; border: 1px solid var(--border); border-radius: 4px; background: var(--surface); }
button, select { height: var(--control-h); }
button { cursor: pointer; padding: 0 9px; white-space: nowrap; display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
button:hover { background: var(--raised); border-color: var(--muted); }
button:disabled { opacity: .45; cursor: default; }
button.primary { background: var(--primary); color: var(--accent-ink); border-color: transparent; font-weight: 650; }
button.primary:hover { filter: brightness(1.08); }
button:focus-visible, select:focus-visible, input:focus-visible, textarea:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }
[hidden] { display: none !important; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
#app { display: grid; grid-template-rows: auto minmax(0,1fr) auto; container-type: inline-size; position: relative; }
.toolbar { display: flex; justify-content: space-between; gap: 8px; padding: 8px; border-bottom: 1px solid var(--border); }
.toolbar-actions, .view-tabs { display: flex; align-items: center; gap: 4px; }
.view-tabs { gap: 0; }
.view-tabs button { border-color: transparent; background: transparent; color: var(--muted); border-radius: 3px; }
.view-tabs button[aria-pressed=true] { color: var(--fg); background: var(--raised); }
.toolbar-actions > button:not(.primary) { min-width: 28px; padding: 0 6px; }
.workspace { min-height: 0; min-width: 0; display: grid; grid-template-columns: minmax(0, .95fr) minmax(0,1.3fr); grid-template-rows: minmax(100px,1fr) auto; }
.editor-pane { grid-row: 1 / 3; display: flex; flex-direction: column; min-height: 0; min-width: 0; border-right: 1px solid var(--border); }
.pane-bar { display: flex; align-items: center; gap: 8px; padding: 8px 12px; min-width: 0; min-height: 44px; border-bottom: 1px solid var(--border); font-size: 12px; }
.pane-bar select { flex: 1; border: 0; padding: 0; background: transparent; }
.pane-bar select option { background: var(--bg); color: var(--fg); }
.pane-bar button { font-size: 11px; }
.badge { font: 10px/1.5 'SFMono-Regular', Consolas, monospace; border: 1px solid var(--border); color: var(--muted); padding: 0 4px; border-radius: 3px; }
.code-wrap { display: flex; flex: 1; min-height: 0; min-width: 0; padding: 12px 0; overflow: hidden; background: var(--surface); }
#line-numbers { width: 38px; flex-shrink: 0; text-align: right; padding-right: 9px; color: var(--muted); opacity: .65; overflow: hidden; user-select: none; white-space: pre; }
textarea { flex: 1; resize: none; min-width: 0; width: 100%; border: 0; border-radius: 0; background: transparent; padding: 0 12px 8px 0; tab-size: 2; }
textarea, #line-numbers { font: 12px/1.85 'SFMono-Regular', Consolas, 'Liberation Mono', monospace; }
.editor-meta, .preview-meta { display: flex; justify-content: space-between; gap: 8px; padding: 6px 12px; color: var(--muted); font-size: 10px; border-top: 1px solid var(--border); }
.preview-pane { display: flex; flex-direction: column; min-height: 0; min-width: 0; }
.live-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--primary); flex-shrink: 0; }
.live-dot.paused { background: var(--muted); }
.spacer { flex: 1; }
.mono { font-family: 'SFMono-Regular', Consolas, monospace; font-size: 10px; }
.stage { position: relative; flex: 1; min-height: 0; display: grid; place-items: center; overflow: hidden; padding: 24px; background: var(--bg); background-image: radial-gradient(var(--border) .6px, transparent .6px); background-size: 12px 12px; }
#canvas-slot { width: 100%; height: 100%; min-height: 0; display: flex; justify-content: center; align-items: center; }
#canvas-slot canvas { display: block; width: 100%; height: 100%; object-fit: contain; image-rendering: var(--pixel-rendering, pixelated); }
.frame-label { position: absolute; bottom: 7px; right: 10px; color: var(--muted); font-size: 9px; letter-spacing: .06em; }
.preview-meta > span:first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.preview-meta > span:last-child { flex-shrink: 0; }
.export-pane { padding: 12px; border-top: 1px solid var(--border); min-width: 0; overflow-y: auto; max-height: 48vh; }
.export-top { display: flex; gap: 8px; align-items: center; margin-bottom: 12px; }
.section-label { font-weight: 650; }
.export-description { color: var(--muted); font-size: 11px; flex: 1; }
.export-top button { margin-left: auto; }
.export-fields { display: grid; grid-template-columns: repeat(4,minmax(0,1fr)); gap: 8px; }
.export-fields label { display: flex; flex-direction: column; gap: 4px; font-size: 11px; color: var(--muted); }
.export-fields select { width: 100%; padding: 0 6px; color: var(--fg); }
.input-unit { display: flex; align-items: center; position: relative; }
.input-unit input { width: 100%; height: var(--control-h); padding: 0 24px 0 8px; color: var(--fg); appearance: textfield; }
.input-unit input::-webkit-inner-spin-button { appearance: none; }
.input-unit span { position: absolute; right: 7px; font-size: 10px; color: var(--muted); pointer-events: none; }
.export-actions { display: flex; align-items: center; gap: 8px; margin-top: 12px; flex-wrap: wrap; }
.check-label { display: flex; align-items: center; gap: 4px; font-size: 11px; }
input[type=checkbox] { accent-color: var(--primary); margin: 0; }
#export-summary { flex: 1; color: var(--muted); text-align: right; }
.export-hint { font-size: 10px; color: var(--muted); margin: 10px 0 0; line-height: 1.5; }
#status { font-size: 11px; padding: 5px 8px; border-top: 1px solid var(--border); overflow-wrap: anywhere; max-height: 80px; overflow-y: auto; color: var(--muted); }
#status[data-kind=error] { color: var(--fg); background: color-mix(in srgb, #d85240 18%,var(--bg)); }
#status[data-kind=ok] { color: var(--fg); }
#progress-area { margin-top: 12px; }
progress { width: 100%; height: 5px; border: 0; accent-color: var(--primary); display: block; margin-bottom: 5px; }
#progress-label { color: var(--muted); }
#result { display: flex; gap: 12px; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); }
#gif-preview { width: 35%; height: 85px; object-fit: contain; background: #000; }
.result-info { display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 4px; min-width: 0; }
#result-details { color: var(--muted); }
#help { position: absolute; inset: 0; background: var(--bg); z-index: 4; display: flex; flex-direction: column; }
#help .pane-bar { justify-content: space-between; }
.help-content { padding: 0 12px 12px; overflow-y: auto; font-size: 12px; }
.help-content p { margin: 12px 0; }
.help-content code { font-size: 11px; }
@media (min-width: 1100px) { .workspace { grid-template-columns: minmax(0,.85fr) minmax(0,1.5fr); } .stage { padding: 32px; } textarea, #line-numbers { font-size: 13px; } }
@media (max-width: 639px), (max-height: 399px) {
  .workspace { display: block; }
  .editor-pane, .preview-pane, .export-pane { height: 100%; max-height: none; border-right: 0; }
  #app[data-view=preview] .editor-pane, #app[data-view=preview] .export-pane,
  #app[data-view=editor] .preview-pane, #app[data-view=editor] .export-pane,
  #app[data-view=export] .editor-pane, #app[data-view=export] .preview-pane { display: none; }
  .stage { padding: 12px; }
  .export-fields { grid-template-columns: repeat(2,minmax(0,1fr)); }
  .export-pane { border-top: 0; }
}
@media (max-width: 479px) { .toolbar .label { display: none; } .toolbar { gap: 4px; } .toolbar button { min-width: 28px; padding: 0 7px; } }
@media (max-width: 239px) { .toolbar { padding: 4px; } .toolbar-actions, .view-tabs { gap: 1px; } .toolbar button { padding: 0 4px; min-width: 24px; } #help-toggle { display: none; } .pane-bar { padding: 4px 8px; min-height: 32px; } .badge, .editor-meta, .preview-meta, .export-description { display: none; } #export-summary { display: none; } .export-pane { padding: 8px; } .export-actions { justify-content: space-between; } #status { font-size: 10px; padding: 2px 4px; max-height: 28px; } }
@media (max-height: 249px) { .pane-bar, .preview-meta, .editor-meta { display: none; } .stage { padding: 4px 8px; } .toolbar { padding-top: 4px; padding-bottom: 4px; } .frame-label { display: none; } #status { max-height: 25px; } }