:root {
--ink: oklch(0.25 0.015 255);
--muted: oklch(0.53 0.02 255);
--line: oklch(0.85 0.012 255);
--paper: oklch(0.97 0.004 265);
--card: oklch(1 0 0);
--bar: oklch(1 0 0 / 0.94);
--accent: oklch(0.55 0.17 260);
--accent-soft: oklch(0.95 0.02 260);
--accent-line: oklch(0.82 0.07 260);
--edge: oklch(0.72 0.015 255);
--code: oklch(0.955 0.003 265);
--chip: oklch(0.96 0.04 80);
--chip-ink: oklch(0.5 0.11 70);
--chip-line: oklch(0.89 0.07 80);
--danger: oklch(0.58 0.21 27);
--error: oklch(0.45 0.16 27);
--error-bg: oklch(0.95 0.025 20);
--error-line: oklch(0.83 0.08 20);
--shadow: oklch(0 0 0 / 0.1);
color-scheme: light;
font: 14px/1.5 system-ui, -apple-system, 'Segoe UI', sans-serif;
color: var(--ink);
background: var(--paper);
touch-action: pan-x pan-y;
}
:root[data-theme='dark'] {
--ink: oklch(0.94 0 0);
--muted: oklch(0.7 0 0);
--line: oklch(0.38 0 0);
--paper: oklch(0.24 0 0);
--card: oklch(0.29 0 0);
--bar: oklch(0.27 0 0 / 0.94);
--accent: oklch(0.68 0.14 260);
--accent-soft: oklch(0.32 0.04 260);
--accent-line: oklch(0.48 0.09 260);
--edge: oklch(0.52 0 0);
--code: oklch(0.34 0 0);
--chip: oklch(0.33 0.04 80);
--chip-ink: oklch(0.85 0.09 80);
--chip-line: oklch(0.45 0.06 80);
--danger: oklch(0.68 0.19 25);
--error: oklch(0.85 0.08 20);
--error-bg: oklch(0.32 0.06 20);
--error-line: oklch(0.45 0.1 20);
--shadow: oklch(0 0 0 / 0.35);
color-scheme: dark;
}
body {
margin: 0;
}
button,
select,
input {
font: inherit;
color: var(--ink);
}
#bar {
position: fixed;
inset: 0 0 auto 0;
z-index: 10;
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.5rem 1rem;
padding: 0.6rem 1rem;
background: var(--bar);
border-bottom: 1px solid var(--line);
backdrop-filter: blur(6px);
}
#bar .title {
font-size: 1.05rem;
}
#bar .dirty {
color: var(--danger);
font-size: 0.85rem;
}
#bar .dim {
color: var(--muted);
font-size: 0.9rem;
}
#bar select,
#bar button,
#bar summary,
.labels button {
font-size: 0.9rem;
padding: 0.2rem 0.6rem;
border: 1px solid var(--line);
border-radius: 6px;
background: var(--card);
cursor: pointer;
}
#bar button.on {
color: var(--card);
background: var(--accent);
border-color: var(--accent);
}
#bar .push {
margin-left: auto;
}
.menu {
position: relative;
}
.menu summary {
list-style: none;
}
.menu summary::after {
content: ' â–¾';
color: var(--muted);
}
.menu .items {
position: absolute;
right: 0;
top: calc(100% + 4px);
display: flex;
flex-direction: column;
gap: 2px;
padding: 4px;
background: var(--card);
border: 1px solid var(--line);
border-radius: 8px;
box-shadow: 0 4px 16px var(--shadow);
}
#bar .menu .items button {
border: none;
text-align: left;
}
#bar .menu .items button:hover {
background: var(--accent-soft);
}
#canvas {
position: relative;
min-width: 100%;
}
#canvas > svg {
position: absolute;
inset: 0 auto auto 0;
pointer-events: none;
}
#canvas path {
fill: none;
stroke: var(--edge);
stroke-width: 1.5;
}
#canvas path.visited {
stroke: var(--accent);
stroke-width: 2.5;
}
.card {
position: absolute;
box-sizing: border-box;
width: 24rem;
padding: 0.9rem 1.1rem;
background: var(--card);
border: 1px solid var(--line);
border-radius: 10px;
box-shadow: 0 1px 3px var(--shadow);
cursor: pointer;
transition: box-shadow 0.15s;
}
.card:hover {
box-shadow: 0 3px 12px var(--shadow);
}
.card.visited {
background: var(--accent-soft);
border-color: var(--accent-line);
}
.card.current {
border: 2px solid var(--accent);
box-shadow: 0 0 0 4px oklch(from var(--accent) l c h / 0.2), 0 4px 16px var(--shadow);
}
.card.terminal {
border-bottom-width: 6px;
}
.card.editing {
z-index: 5;
cursor: auto;
box-shadow: 0 8px 30px var(--shadow);
}
.card header {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.4rem;
margin-bottom: 0.4rem;
padding-right: 1rem;
}
.card h2 {
flex-basis: 100%;
margin: 0;
font-size: 1.1rem;
line-height: 1.3;
}
.card .delete {
position: absolute;
top: 0.3rem;
right: 0.4rem;
padding: 0 0.3rem;
font-size: 1.1rem;
line-height: 1;
color: var(--danger);
background: none;
border: none;
border-radius: 4px;
cursor: pointer;
opacity: 0.55;
}
.card .delete:hover {
opacity: 1;
background: var(--error-bg);
}
.chip {
font: 0.72rem/1.4 ui-monospace, monospace;
padding: 0 0.4rem;
border-radius: 999px;
background: var(--chip);
color: var(--chip-ink);
border: 1px solid var(--chip-line);
}
.pill {
display: inline-flex;
align-items: center;
gap: 0.15rem;
font-size: 0.75rem;
font-weight: 500;
line-height: 1.5;
padding: 0 0.55rem;
border-radius: 999px;
white-space: nowrap;
}
.pill .unlabel {
padding: 0;
margin-right: -0.2rem;
font-size: 0.85rem;
line-height: 1;
color: inherit;
background: none;
border: none;
cursor: pointer;
opacity: 0.7;
}
.pill .unlabel:hover {
opacity: 1;
}
.add {
appearance: none;
width: 1.6rem;
text-align-last: center;
font-size: 0.75rem;
line-height: 1.5;
padding: 0 0.45rem;
color: var(--muted);
background: none;
border: 1px dashed var(--line);
border-radius: 999px;
cursor: pointer;
}
.add:hover {
color: var(--ink);
border-color: var(--muted);
}
.body > :first-child {
margin-top: 0;
}
.body > :last-child {
margin-bottom: 0;
}
.body p,
.body ul,
.body ol {
margin: 0.5rem 0;
}
.body blockquote {
margin: 0.5rem 0;
padding-left: 0.8rem;
border-left: 3px solid var(--line);
color: var(--muted);
}
.body code {
font-size: 0.88em;
background: var(--code);
padding: 0 0.25em;
border-radius: 3px;
}
.label {
position: absolute;
max-width: 11rem;
padding: 0.15rem 0.6rem;
font: inherit;
font-size: 0.82rem;
line-height: 1.35;
text-align: center;
color: var(--ink);
background: var(--card);
border: 1px solid var(--line);
border-radius: 999px;
cursor: pointer;
}
.label:hover {
border-color: var(--accent);
}
.label.visited {
background: var(--accent);
border-color: var(--accent);
color: var(--card);
}
.labels {
box-sizing: border-box;
width: min(52rem, 94vw);
padding: 0;
color: var(--ink);
background: var(--card);
border: 1px solid var(--line);
border-radius: 10px;
box-shadow: 0 12px 40px var(--shadow);
}
.labels::backdrop {
background: oklch(0 0 0 / 0.4);
}
.labels > header {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.8rem 1rem;
background: var(--paper);
border-bottom: 1px solid var(--line);
}
.labels h2 {
flex: 1;
margin: 0;
font-size: 1rem;
}
.labels .primary {
color: oklch(1 0 0);
background: oklch(0.55 0.15 150);
border-color: oklch(0.5 0.15 150);
}
.labels ul {
margin: 0;
padding: 0;
list-style: none;
}
.labels li {
display: grid;
grid-template-columns: 14rem 1fr 6rem auto auto;
align-items: center;
gap: 1rem;
padding: 0.7rem 1rem;
border-bottom: 1px solid var(--line);
}
.labels li:last-child {
border-bottom: none;
}
.labels .description,
.labels .uses {
color: var(--muted);
font-size: 0.85rem;
}
.labels .pill {
justify-self: start;
}
.labels button.link {
padding: 0;
color: var(--muted);
background: none;
border: none;
}
.labels button.link:hover {
color: var(--accent);
text-decoration: underline;
}
.labels button.danger:hover {
color: var(--danger);
}
.editor {
display: flex;
flex-wrap: wrap;
align-items: end;
gap: 0.6rem 1rem;
padding: 1rem;
background: var(--paper);
border-bottom: 1px solid var(--line);
}
.editor .preview {
flex-basis: 100%;
}
.editor label {
display: flex;
flex-direction: column;
gap: 0.25rem;
font-size: 0.85rem;
font-weight: 600;
}
.editor input {
font-size: 0.9rem;
font-weight: 400;
padding: 0.25rem 0.5rem;
background: var(--card);
border: 1px solid var(--line);
border-radius: 6px;
}
.editor input:invalid {
border-color: var(--danger);
}
.editor .color {
display: flex;
gap: 0.4rem;
}
.editor .swatches {
display: flex;
flex-wrap: wrap;
gap: 4px;
flex-basis: 100%;
}
.labels .editor .swatches button {
width: 1.4rem;
height: 1.4rem;
padding: 0;
border: none;
border-radius: 4px;
}
.editor > div:last-child {
flex-basis: 100%;
}
textarea {
box-sizing: border-box;
width: 100%;
min-height: 8rem;
font: 0.85rem/1.45 ui-monospace, monospace;
color: var(--ink);
background: var(--card);
border: 1px solid var(--line);
border-radius: 6px;
padding: 0.5rem;
resize: vertical;
}
.errors {
margin: 0.5rem 0 0;
padding: 0.6rem 0.6rem 0.6rem 1.6rem;
color: var(--error);
background: var(--error-bg);
border: 1px solid var(--error-line);
border-radius: 6px;
font-size: 0.9rem;
}
#canvas > .errors {
max-width: 50rem;
margin: 2rem;
}