Initial Lime window manager

This commit is contained in:
2026-10-02 14:14:47 -05:00
commit ccd691edd0
121 changed files with 29719 additions and 0 deletions

170
work/bar-title-edges.html Normal file
View File

@@ -0,0 +1,170 @@
<div id="lime-bar-title-edges" aria-label="Lime title section edge comparison">
<style>
#lime-bar-title-edges {
--lime-bg: light-dark(#fff7ed, #060a0c);
--lime-ink: light-dark(#35271d, #ffdbb0);
--lime-muted: light-dark(#685a4d, #a8adb0);
--lime-focus-bg: light-dark(#f0dfc8, #121f25);
--lime-idle-bg: light-dark(#f7eee1, #0b1216);
--lime-accent: light-dark(#8a470c, #ffac54);
--lime-separator: light-dark(#946336, #b88755);
--lime-edge: light-dark(#d5c6b5, #25343b);
--lime-title-edge: light-dark(#bca68d, #40535d);
--lime-space: 9px;
font-family: ui-monospace, "DejaVu Sans Mono", monospace;
color: var(--lime-ink); display: grid; gap: 20px; padding: 4px 0;
}
#lime-bar-title-edges * { box-sizing: border-box; }
#lime-bar-title-edges .focus-toggle {
display: flex; align-items: center; gap: 8px; justify-self: start;
font-size: 14px; line-height: 1.5; cursor: pointer;
}
#lime-bar-title-edges .focus-toggle input { accent-color: var(--lime-accent); }
@media (pointer: coarse) {
#lime-bar-title-edges .focus-toggle { min-height: 44px; }
}
#lime-bar-title-edges .variant { min-width: 0; }
#lime-bar-title-edges .caption {
display: flex; gap: 8px; flex-wrap: wrap; align-items: baseline;
font-size: 12px; line-height: 1.5; color: var(--lime-muted); margin-bottom: 7px;
}
#lime-bar-title-edges .recommended { color: var(--lime-accent); }
#lime-bar-title-edges .bar {
display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
min-width: 0; width: 100%; height: 34px;
background: var(--lime-bg); border: 1px solid var(--lime-edge);
font-size: 12px; line-height: 1;
}
#lime-bar-title-edges .identity, #lime-bar-title-edges .status {
display: flex; align-items: center; min-width: 0; padding: 0 var(--lime-space);
}
#lime-bar-title-edges .logo { font-weight: 500; flex: none; }
#lime-bar-title-edges .context { white-space: nowrap; }
#lime-bar-title-edges .activity { color: var(--lime-muted); }
#lime-bar-title-edges .dirty { color: var(--lime-accent); }
#lime-bar-title-edges .layout { white-space: nowrap; flex: none; }
#lime-bar-title-edges .divider {
flex: none; margin: 0 var(--lime-space); color: var(--lime-separator);
}
#lime-bar-title-edges .divider::before { content: "|"; }
#lime-bar-title-edges .title-region {
display: flex; align-items: center; min-width: 0; padding: 0 12px;
background: var(--lime-focus-bg); color: var(--lime-accent);
}
#lime-bar-title-edges .leading .title-region { box-shadow: inset 2px 0 var(--lime-accent); }
#lime-bar-title-edges .paired .title-region {
box-shadow: inset 1px 0 var(--lime-title-edge), inset -1px 0 var(--lime-title-edge);
}
#lime-bar-title-edges .title-text {
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
}
#lime-bar-title-edges:has(.focus-toggle input:not(:checked)) .title-region {
background: var(--lime-idle-bg); color: var(--lime-muted);
}
#lime-bar-title-edges:has(.focus-toggle input:not(:checked)) .leading .title-region { box-shadow: none; }
#lime-bar-title-edges .status[hidden] { display: none; }
#lime-bar-title-edges .status-item {
display: flex; align-items: center; white-space: nowrap; min-width: 0;
}
#lime-bar-title-edges .status-icon {
display: inline-flex; align-items: center; margin-right: 5px;
color: var(--lime-muted); flex: none;
}
#lime-bar-title-edges .status-icon svg { width: 13px; height: 13px; stroke-width: 1.8; }
#lime-bar-title-edges .music-value { overflow: hidden; text-overflow: ellipsis; max-width: 100px; }
#lime-bar-title-edges .clock-value { font-variant-numeric: tabular-nums; }
@media (max-width: 640px) {
#lime-bar-title-edges .music, #lime-bar-title-edges .music-divider { display: none; }
}
@media (max-width: 440px) {
#lime-bar-title-edges { --lime-space: 5px; }
#lime-bar-title-edges .volume, #lime-bar-title-edges .volume-divider { display: none; }
#lime-bar-title-edges .title-region { padding: 0 7px; }
}
</style>
<label class="focus-toggle">
<input type="checkbox" checked>
<span>Head focused</span>
</label>
<section class="variant plain" aria-label="Background only, no title stripes">
<div class="caption"><span>1 · Background only</span><span class="recommended">My pick</span></div>
<div class="bar" role="img" aria-label="Focused head with a tinted title section and no edge stripes">
<div class="identity">
<span class="logo">Lime</span><span class="divider" aria-hidden="true"></span>
<span class="context"><span class="activity">WM</span>:Code<span class="dirty">*</span></span>
<span class="divider" aria-hidden="true"></span><span class="layout">[]=</span>
</div>
<div class="title-region"><span class="title-text">config.lisp — VS Code</span></div>
<div class="status">
<span class="status-item music"><span class="status-icon" aria-hidden="true"><i data-lucide="music-2"></i></span><span class="music-value">スパイダー</span></span>
<span class="divider music-divider" aria-hidden="true"></span>
<span class="status-item volume"><span class="status-icon" aria-hidden="true"><i data-lucide="volume-2"></i></span>25%</span>
<span class="divider volume-divider" aria-hidden="true"></span>
<span class="status-item clock"><span class="status-icon" aria-hidden="true"><i data-lucide="clock-3"></i></span><span class="clock-value">03:01</span></span>
</div>
</div>
</section>
<section class="variant leading" aria-label="Current design with a left focus stripe">
<div class="caption">2 · Left accent · Current treatment</div>
<div class="bar" role="img" aria-label="Focused head with a two-pixel accent stripe at the start of the title section">
<div class="identity">
<span class="logo">Lime</span><span class="divider" aria-hidden="true"></span>
<span class="context"><span class="activity">WM</span>:Code<span class="dirty">*</span></span>
<span class="divider" aria-hidden="true"></span><span class="layout">[]=</span>
</div>
<div class="title-region"><span class="title-text">config.lisp — VS Code</span></div>
<div class="status">
<span class="status-item music"><span class="status-icon" aria-hidden="true"><i data-lucide="music-2"></i></span><span class="music-value">スパイダー</span></span>
<span class="divider music-divider" aria-hidden="true"></span>
<span class="status-item volume"><span class="status-icon" aria-hidden="true"><i data-lucide="volume-2"></i></span>25%</span>
<span class="divider volume-divider" aria-hidden="true"></span>
<span class="status-item clock"><span class="status-icon" aria-hidden="true"><i data-lucide="clock-3"></i></span><span class="clock-value">03:01</span></span>
</div>
</div>
</section>
<section class="variant paired" aria-label="Quiet one-pixel edges on both sides">
<div class="caption">3 · Two subtle edges</div>
<div class="bar" role="img" aria-label="Focused head with muted one-pixel separators on both sides of the title section">
<div class="identity">
<span class="logo">Lime</span><span class="divider" aria-hidden="true"></span>
<span class="context"><span class="activity">WM</span>:Code<span class="dirty">*</span></span>
<span class="divider" aria-hidden="true"></span><span class="layout">[]=</span>
</div>
<div class="title-region"><span class="title-text">config.lisp — VS Code</span></div>
<div class="status">
<span class="status-item music"><span class="status-icon" aria-hidden="true"><i data-lucide="music-2"></i></span><span class="music-value">スパイダー</span></span>
<span class="divider music-divider" aria-hidden="true"></span>
<span class="status-item volume"><span class="status-icon" aria-hidden="true"><i data-lucide="volume-2"></i></span>25%</span>
<span class="divider volume-divider" aria-hidden="true"></span>
<span class="status-item clock"><span class="status-icon" aria-hidden="true"><i data-lucide="clock-3"></i></span><span class="clock-value">03:01</span></span>
</div>
</div>
</section>
<script>
(() => {
const root = document.getElementById('lime-bar-title-edges');
const focusToggle = root.querySelector('.focus-toggle input');
const state = { status: true, title: 'config.lisp — VS Code' };
function render() {
root.querySelectorAll('.title-text').forEach(el => el.textContent = state.title);
root.querySelectorAll('.status').forEach(el => el.hidden = !state.status);
root.querySelectorAll('.bar').forEach(el => {
const variant = el.closest('section').getAttribute('aria-label');
el.setAttribute('aria-label', variant + '. ' + (focusToggle.checked ? 'Focused' : 'Unfocused') + ' head; Lime menu; WM:Code, unsaved changes; master-stack layout; ' + state.title + (state.status ? '; music: スパイダー, volume: 25 percent, time: 03:01.' : '.'));
});
}
focusToggle.addEventListener('change', render);
render();
if (globalThis.Tweak) {
const tweak = new Tweak({ container: root, onChange: render });
tweak.addToggle(state, 'status', { label: 'Status visible' });
tweak.addSelect(state, 'title', { label: 'Window title', options: ['config.lisp — VS Code', 'Terminal', 'Window management notes — Waterfox'] });
}
})();
</script>
</div>