SOURCE / PINNED RELEASE
Made of little things.
Freeze Frame Response
- Release
- 3e45de6048a3…
- Author-recorded commit
- d04885dad630…
- License
- LICENSE
- Author’s source reference
- nostr://npub182jczunncwe0jn6frpqwq3e0qjws7yqqnc3auccqv9nte2dnd63scjm4rf/wss%3A%2F%2Fgit.napplet.soy%2F/n-ba52e30d5f2
Archive hash verified: e747ab4f9e35a11f…. The source-to-build association is the author’s claim; it has not been independently rebuilt.
/*
Freeze Frame Response — municipal incident terminal.
Visual direction: deadpan civic paperwork wrapped around a frozen city cutaway.
App-owned palette; the host theme is intentionally not applied.
*/
:root {
--ink: #12181b;
--ink-2: #182126;
--ink-3: #202c32;
--paper: #efe6d0;
--paper-2: #e4d8bd;
--paper-ink: #20221d;
--line: rgba(239, 230, 208, 0.16);
--line-strong: rgba(239, 230, 208, 0.3);
--text: #e9e2d0;
--muted: #9aa5a4;
--hazard: #f2b52f;
--hazard-soft: #f7cd6b;
--freeze: #8ce6e8;
--danger: #f0846d;
--masonry: #c97146;
--furniture: #5e90c8;
--glass: #5fae8c;
--mattress: #e9dfc7;
--shadow: 6px 6px 0 rgba(0, 0, 0, 0.38);
--control-h: 46px;
--napplet-text-selection: none;
color-scheme: dark;
font: 13px/1.4 ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
}
* {
box-sizing: border-box;
}
:where(html, body, body *) {
-webkit-user-select: var(--napplet-text-selection, none);
user-select: var(--napplet-text-selection, none);
}
:where([data-napplet-select="text"], input, textarea) {
-webkit-user-select: text;
user-select: text;
}
html,
body,
#app {
height: 100%;
margin: 0;
background: var(--ink);
color: var(--text);
}
button {
font: inherit;
color: inherit;
}
.app {
container-type: inline-size;
display: grid;
grid-template-rows: auto minmax(0, 1fr) auto;
gap: 0;
height: 100%;
min-height: 0;
background:
radial-gradient(circle at 50% -30%, rgba(94, 144, 200, 0.1), transparent 60%),
var(--ink);
overflow: hidden;
}
/* ── HUD ─────────────────────────────────────────────────────────────── */
.hud {
display: flex;
align-items: center;
gap: 10px;
padding: 7px 10px;
background: linear-gradient(180deg, #222e34, #172025);
border-bottom: 1px solid var(--line);
border-top: 2px solid var(--hazard);
min-width: 0;
}
.case {
display: flex;
align-items: baseline;
gap: 8px;
min-width: 0;
flex: 1;
}
.case-no {
font: 700 9px/1 ui-monospace, "SFMono-Regular", Consolas, monospace;
letter-spacing: 0.12em;
color: var(--hazard);
white-space: nowrap;
padding: 3px 5px;
border: 1px solid rgba(242, 181, 47, 0.35);
background: rgba(242, 181, 47, 0.08);
}
.case-name {
font: 700 14px/1.15 ui-sans-serif, system-ui, sans-serif;
letter-spacing: 0.01em;
color: var(--text);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
min-width: 0;
}
.stats {
display: flex;
gap: 5px;
align-items: center;
flex-shrink: 0;
}
.stat {
display: inline-flex;
align-items: baseline;
gap: 4px;
padding: 3px 6px;
border: 1px solid var(--line);
background: rgba(10, 14, 16, 0.4);
font-family: ui-monospace, "SFMono-Regular", Consolas, monospace;
white-space: nowrap;
}
.stat-k {
font-size: 8px;
letter-spacing: 0.09em;
color: var(--muted);
}
.stat b {
font-size: 12px;
color: var(--freeze);
}
.stat:nth-child(2) b {
color: var(--hazard);
}
.hud-actions {
display: flex;
gap: 4px;
flex-shrink: 0;
}
.icon-btn {
width: 28px;
height: 28px;
display: grid;
place-items: center;
border: 1px solid var(--line-strong);
background: var(--ink-3);
color: var(--text);
font: 700 14px/1 ui-monospace, monospace;
cursor: pointer;
padding: 0;
}
.icon-btn:hover {
border-color: var(--hazard);
color: var(--hazard);
}
.icon-btn:focus-visible,
.tool:focus-visible,
.small-btn:focus-visible,
.resume-btn:focus-visible,
.primary-btn:focus-visible {
outline: 2px solid var(--freeze);
outline-offset: 2px;
}
/* ── Stage ───────────────────────────────────────────────────────────── */
.stage {
position: relative;
min-height: 0;
min-width: 0;
margin: 6px;
border: 1px solid rgba(239, 230, 208, 0.14);
background: #0b1114;
overflow: hidden;
box-shadow: inset 0 0 40px rgba(0, 0, 0, 0.5);
}
#scene {
display: block;
width: 100%;
height: 100%;
touch-action: none;
cursor: default;
outline: none;
}
#scene.placing {
cursor: crosshair;
}
.freeze-badge {
position: absolute;
top: 8px;
left: 8px;
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 7px;
border: 1px solid var(--freeze);
background: rgba(15, 21, 24, 0.86);
color: var(--freeze);
font: 700 9px/1 ui-monospace, "SFMono-Regular", Consolas, monospace;
letter-spacing: 0.09em;
pointer-events: none;
backdrop-filter: blur(4px);
z-index: 2;
}
.freeze-badge #freezeClock {
color: var(--text);
font-weight: 400;
letter-spacing: 0;
}
.freeze-dot {
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--freeze);
box-shadow: 0 0 8px var(--freeze);
animation: pulse 1.8s ease-in-out infinite;
}
.freeze-badge.running {
border-color: var(--hazard);
color: var(--hazard);
}
.freeze-badge.running .freeze-dot {
background: var(--hazard);
box-shadow: 0 0 8px var(--hazard);
animation-duration: 0.7s;
}
.freeze-badge.settled {
border-color: var(--line-strong);
color: var(--muted);
}
.freeze-badge.settled .freeze-dot {
background: var(--muted);
box-shadow: none;
animation: none;
}
@keyframes pulse {
0%,
100% {
opacity: 1;
transform: scale(1);
}
50% {
opacity: 0.35;
transform: scale(0.7);
}
}
.toast {
position: absolute;
left: 50%;
bottom: 10px;
transform: translate(-50%, 8px);
max-width: calc(100% - 16px);
padding: 6px 10px;
background: rgba(15, 21, 24, 0.94);
border-left: 3px solid var(--hazard);
color: var(--text);
font: 600 11px/1.35 ui-sans-serif, system-ui, sans-serif;
opacity: 0;
transition: opacity 140ms ease, transform 140ms ease;
pointer-events: none;
z-index: 3;
}
.toast.show {
opacity: 1;
transform: translate(-50%, 0);
}
/* ── Overlay and paper cards ─────────────────────────────────────────── */
.overlay {
position: fixed;
inset: 0;
display: grid;
place-items: center;
padding: 10px;
background: rgba(7, 11, 13, 0.72);
backdrop-filter: blur(2px);
overflow: auto;
z-index: 20;
}
.overlay[hidden] {
display: none;
}
.card {
width: min(560px, 100%);
max-height: calc(100% - 2px);
overflow: auto;
padding: 18px 20px 16px;
background:
linear-gradient(rgba(32, 34, 29, 0.04) 1px, transparent 1px) 0 0 / 100% 26px,
var(--paper);
color: var(--paper-ink);
border: 1px solid #c7bca2;
box-shadow: var(--shadow);
}
.card-kicker {
margin: 0 0 7px;
padding-bottom: 6px;
border-bottom: 1px dashed #a99f88;
font: 700 9px/1.2 ui-monospace, "SFMono-Regular", Consolas, monospace;
letter-spacing: 0.13em;
color: #766e5c;
}
.card h2 {
margin: 0 0 4px;
font: 800 24px/1.02 ui-sans-serif, system-ui, sans-serif;
letter-spacing: -0.015em;
text-transform: uppercase;
}
.tagline {
margin: 0 0 9px;
color: #5f594b;
font: italic 12px/1.4 ui-sans-serif, system-ui, sans-serif;
}
.brief-copy {
margin: 0 0 9px;
font-size: 12.5px;
}
.legend {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 3px 8px;
margin: 9px 0;
padding: 7px 0;
border-top: 1px dashed #a99f88;
border-bottom: 1px dashed #a99f88;
font: 600 10px/1.3 ui-monospace, monospace;
color: #4d493e;
}
.legend span {
display: inline-flex;
align-items: center;
gap: 5px;
}
.swatch {
width: 10px;
height: 10px;
display: inline-block;
border: 1px solid rgba(20, 25, 28, 0.4);
}
.swatch.mattress {
background: var(--mattress);
}
.swatch.masonry {
background: var(--masonry);
}
.swatch.furniture {
background: var(--furniture);
}
.swatch.glass {
background: var(--glass);
}
.howto {
margin: 9px 0 8px;
padding: 7px 9px;
border-left: 3px solid var(--hazard);
background: rgba(32, 34, 29, 0.07);
font-size: 11.5px;
}
.howto b {
display: block;
margin-bottom: 2px;
font: 700 9px/1.2 ui-monospace, monospace;
letter-spacing: 0.1em;
text-transform: uppercase;
}
kbd {
padding: 0 3px;
border: 1px solid #a99f88;
background: #faf5e8;
font: 700 9px/1.4 ui-monospace, monospace;
}
.hint {
margin: 0;
color: #6a6252;
font-size: 11px;
font-style: italic;
}
.card-actions {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
flex-wrap: wrap;
margin-top: 12px;
}
.service-record {
font: 600 9px/1.3 ui-monospace, monospace;
letter-spacing: 0.04em;
color: #776f5e;
}
.primary-btn {
min-height: 38px;
padding: 0 14px;
border: 1px solid var(--ink);
background: var(--ink);
color: var(--paper);
font: 800 11px/1 ui-monospace, monospace;
letter-spacing: 0.07em;
text-transform: uppercase;
cursor: pointer;
box-shadow: 3px 3px 0 var(--hazard);
}
.primary-btn:hover {
background: #2a353b;
}
.small-btn {
min-height: 34px;
padding: 0 10px;
border: 1px solid #8e8674;
background: transparent;
color: var(--paper-ink);
font: 700 10px/1 ui-monospace, monospace;
letter-spacing: 0.06em;
text-transform: uppercase;
cursor: pointer;
}
.small-btn:hover {
border-color: var(--ink);
background: rgba(32, 34, 29, 0.08);
}
.small-btn:disabled {
opacity: 0.4;
cursor: not-allowed;
}
/* Report card */
.report-head {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 10px;
margin-bottom: 8px;
}
.report-head h2 {
flex: 1;
font-size: 22px;
}
.stamp {
flex-shrink: 0;
transform: rotate(-3deg);
padding: 4px 7px;
border: 2px double currentColor;
font: 800 11px/1.15 ui-monospace, monospace;
letter-spacing: 0.08em;
text-align: center;
}
.stamp.closed {
color: #2c6b4c;
}
.stamp.partial {
color: #8a6411;
}
.stamp.review {
color: #a63827;
}
.report-grid {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
gap: 2px 10px;
padding: 7px 0;
border-top: 1px dashed #a99f88;
border-bottom: 1px dashed #a99f88;
font: 600 10.5px/1.45 ui-monospace, monospace;
color: #4d493e;
}
.report-grid b {
text-align: right;
color: var(--paper-ink);
}
.damage {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 10px;
padding: 7px 0 6px;
border-bottom: 2px solid var(--ink);
font: 700 9px/1.2 ui-monospace, monospace;
letter-spacing: 0.1em;
text-transform: uppercase;
color: #6a6252;
}
.damage strong {
font: 800 25px/1 ui-monospace, monospace;
letter-spacing: -0.03em;
color: var(--paper-ink);
}
.report-notes {
margin: 8px 0;
padding-left: 16px;
font-size: 11px;
color: #4a463a;
}
.report-notes li {
margin: 3px 0;
}
.save-note {
min-height: 13px;
margin: 0;
font: 600 9px/1.3 ui-monospace, monospace;
color: #7b7361;
}
/* ── Dock ────────────────────────────────────────────────────────────── */
.dock {
display: grid;
grid-template-columns: minmax(0, 1fr);
gap: 5px;
padding: 6px;
background: linear-gradient(180deg, #1a2429, #121a1e);
border-top: 1px solid var(--line);
}
.tools {
display: flex;
gap: 4px;
min-width: 0;
}
.tool {
flex: 1 1 0;
min-width: 0;
min-height: var(--control-h, 46px);
display: grid;
grid-template-columns: auto minmax(0, 1fr) auto;
align-items: center;
gap: 6px;
padding: 4px 7px;
border: 1px solid var(--line);
border-bottom: 2px solid transparent;
background: var(--ink-3);
color: var(--text);
cursor: pointer;
text-align: left;
}
.tool:hover:not(:disabled) {
border-color: var(--line-strong);
background: #26343b;
}
.tool.selected {
border-color: var(--hazard);
border-bottom-color: var(--hazard);
background: #2a3129;
box-shadow: inset 0 0 0 1px rgba(242, 181, 47, 0.18);
}
.tool:disabled {
opacity: 0.38;
cursor: not-allowed;
}
.tool-icon {
width: 22px;
text-align: center;
color: var(--hazard);
font: 700 19px/1 ui-monospace, monospace;
}
.tool-text {
display: grid;
gap: 1px;
min-width: 0;
}
.tool-name {
font: 700 11.5px/1.15 ui-sans-serif, system-ui, sans-serif;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.tool-key {
color: var(--muted);
font: 600 8px/1 ui-monospace, monospace;
letter-spacing: 0.08em;
}
.tool-count {
min-width: 19px;
height: 19px;
display: grid;
place-items: center;
align-self: center;
border: 1px solid var(--line-strong);
background: rgba(8, 12, 14, 0.7);
color: var(--hazard);
font: 700 10px/1 ui-monospace, monospace;
}
.dock-actions {
display: flex;
gap: 4px;
justify-content: flex-end;
}
.dock .small-btn {
min-height: calc(var(--control-h, 46px) - 4px);
border-color: var(--line-strong);
background: var(--ink-3);
color: var(--text);
white-space: nowrap;
}
.dock .small-btn:hover:not(:disabled) {
border-color: var(--hazard);
background: #26343b;
}
.resume-btn {
min-height: calc(var(--control-h, 46px) - 4px);
padding: 0 16px;
border: 1px solid var(--hazard-soft);
background: var(--hazard);
color: var(--ink);
font: 800 11px/1 ui-monospace, monospace;
letter-spacing: 0.05em;
text-transform: uppercase;
cursor: pointer;
box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.45);
white-space: nowrap;
}
.resume-btn:hover:not(:disabled) {
background: var(--hazard-soft);
}
.resume-btn:disabled {
opacity: 0.4;
cursor: not-allowed;
box-shadow: none;
}
/* ── Responsive ──────────────────────────────────────────────────────── */
@container (min-width: 700px) {
.dock {
grid-template-columns: minmax(0, 1fr) auto;
align-items: stretch;
padding: 7px 8px;
}
.tool,
.dock .small-btn,
.resume-btn {
min-height: var(--control-h, 46px);
}
}
@container (max-width: 520px) {
.hud {
gap: 6px;
padding: 5px 7px;
}
.case {
gap: 5px;
}
.case-name {
font-size: 12px;
}
.stat-k {
display: none;
}
.stat {
padding: 3px 5px;
}
.tool-name {
font-size: 10.5px;
}
}
@container (max-width: 380px) {
.case-no {
font-size: 8px;
padding: 2px 4px;
}
.case-name {
font-size: 11px;
max-width: 120px;
}
.hud-actions {
gap: 3px;
}
.icon-btn {
width: 26px;
height: 26px;
}
.tool {
padding: 4px 5px;
gap: 4px;
}
.tool-icon {
width: 17px;
font-size: 17px;
}
.tool-count {
min-width: 16px;
height: 16px;
font-size: 9px;
}
.resume-btn {
padding: 0 9px;
font-size: 10px;
}
.card {
padding: 12px 13px;
}
.card h2 {
font-size: 19px;
}
.legend {
grid-template-columns: 1fr;
}
}
@media (max-width: 280px) {
.case-name {
display: none;
}
#tiltButton {
display: none;
}
.tool-key {
display: none;
}
.tool {
grid-template-columns: minmax(0, 1fr);
place-items: center;
padding: 2px;
}
.tool-icon {
display: none;
}
.tool-count {
min-width: 20px;
height: 20px;
font-size: 10px;
}
.hud {
justify-content: space-between;
}
}
@media (max-height: 300px) {
.hud {
gap: 5px;
padding: 3px 6px;
border-top-width: 1px;
}
.case-no {
display: none;
}
.case-name {
font-size: 10.5px;
max-width: 132px;
}
.stat {
padding: 2px 4px;
}
.stat-k {
display: none;
}
.stat b {
font-size: 10px;
}
.icon-btn {
width: 23px;
height: 23px;
font-size: 12px;
}
.stage {
margin: 2px;
}
.dock {
grid-template-columns: minmax(0, 1fr) auto;
gap: 3px;
padding: 3px;
}
.tools {
gap: 3px;
}
.tool {
min-height: 32px;
grid-template-columns: auto auto;
gap: 3px;
padding: 2px 4px;
}
.tool-text {
display: none;
}
.tool-icon {
width: 14px;
font-size: 14px;
}
.tool-count {
min-width: 14px;
height: 14px;
font-size: 8px;
}
.dock-actions {
gap: 3px;
}
.dock .small-btn {
min-height: 32px;
padding: 0 5px;
font-size: 8px;
}
.resume-btn {
min-height: 32px;
padding: 0 7px;
font-size: 8.5px;
letter-spacing: 0;
}
.freeze-badge {
top: 3px;
left: 3px;
gap: 3px;
padding: 2px 4px;
font-size: 7px;
}
.freeze-dot {
width: 5px;
height: 5px;
}
.toast {
bottom: 4px;
padding: 4px 6px;
font-size: 9.5px;
}
.overlay {
padding: 4px;
}
.card {
padding: 9px 10px;
max-height: 100%;
}
.card h2 {
font-size: 15px;
line-height: 1.05;
}
.card-kicker {
margin-bottom: 4px;
padding-bottom: 3px;
font-size: 7px;
}
.tagline,
.brief-copy,
.legend,
.hint {
display: none;
}
.howto {
margin: 5px 0;
padding: 5px 6px;
font-size: 9px;
}
.howto b {
font-size: 7px;
}
.card-actions {
margin-top: 6px;
}
.primary-btn {
min-height: 28px;
padding: 0 8px;
font-size: 8.5px;
}
.small-btn {
min-height: 28px;
font-size: 8px;
}
.report-grid,
.report-notes {
font-size: 8.5px;
}
.report-head h2 {
font-size: 15px;
}
.damage strong {
font-size: 18px;
}
.service-record,
.save-note {
display: none;
}
}
@media (max-height: 300px) and (max-width: 440px) {
#tiltButton {
display: none;
}
}
@media (prefers-reduced-motion: reduce) {
.freeze-dot {
animation: none;
}
.toast {
transition: none;
}
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
