Initial Lime window manager
This commit is contained in:
163
work/bar-design-comparison.html
Normal file
163
work/bar-design-comparison.html
Normal file
@@ -0,0 +1,163 @@
|
||||
<div id="lime-bar-design-comparison" aria-label="Lime bar design comparisons">
|
||||
<style>
|
||||
#lime-bar-design-comparison {
|
||||
--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-edge: light-dark(#d5c6b5, #25343b);
|
||||
font-family: ui-monospace, "DejaVu Sans Mono", monospace;
|
||||
color: var(--lime-ink);
|
||||
display: grid;
|
||||
gap: 22px;
|
||||
padding: 4px 0;
|
||||
}
|
||||
#lime-bar-design-comparison * { box-sizing: border-box; }
|
||||
#lime-bar-design-comparison .variant { min-width: 0; }
|
||||
#lime-bar-design-comparison .caption {
|
||||
display: flex; gap: 8px; flex-wrap: wrap; align-items: baseline;
|
||||
font-size: 12px; line-height: 1.5; margin-bottom: 7px;
|
||||
color: var(--lime-muted);
|
||||
}
|
||||
#lime-bar-design-comparison .caption strong { font-weight: 500; color: var(--lime-ink); }
|
||||
#lime-bar-design-comparison .recommended { color: var(--lime-accent); }
|
||||
#lime-bar-design-comparison .bar {
|
||||
position: relative; display: grid;
|
||||
grid-template-columns: auto minmax(0, 1fr) auto;
|
||||
height: 34px; width: 100%; min-width: 0;
|
||||
background: var(--lime-bg); font-size: 12px; line-height: 1;
|
||||
border: 1px solid var(--lime-edge);
|
||||
}
|
||||
#lime-bar-design-comparison .identity {
|
||||
grid-column: 1; display: flex; align-items: center; gap: 8px;
|
||||
padding: 0 10px; min-width: 0; max-width: 280px;
|
||||
border-right: 1px solid var(--lime-edge);
|
||||
}
|
||||
#lime-bar-design-comparison .logo { font-weight: 500; flex: none; }
|
||||
#lime-bar-design-comparison .context {
|
||||
overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
|
||||
max-width: 170px;
|
||||
}
|
||||
#lime-bar-design-comparison .layout { white-space: nowrap; flex: none; }
|
||||
#lime-bar-design-comparison .title-region {
|
||||
grid-column: 2; display: flex; align-items: center; min-width: 0;
|
||||
padding: 0 10px; background: var(--lime-focus-bg);
|
||||
border-left: 2px solid var(--lime-accent);
|
||||
color: var(--lime-accent);
|
||||
}
|
||||
#lime-bar-design-comparison .title-text {
|
||||
display: block; overflow: hidden; white-space: nowrap;
|
||||
text-overflow: ellipsis; min-width: 0;
|
||||
}
|
||||
#lime-bar-design-comparison .status {
|
||||
grid-column: 3; display: flex; align-items: center; gap: 8px;
|
||||
padding: 0 10px; white-space: nowrap;
|
||||
border-left: 1px solid var(--lime-edge);
|
||||
}
|
||||
#lime-bar-design-comparison .status[hidden] { display: none; }
|
||||
#lime-bar-design-comparison .music { color: var(--lime-muted); }
|
||||
#lime-bar-design-comparison .clock { color: var(--lime-accent); }
|
||||
#lime-bar-design-comparison .center-region .title-region { justify-content: center; }
|
||||
#lime-bar-design-comparison .screen-center .identity { border-right: 0; }
|
||||
#lime-bar-design-comparison .screen-center .status { border-left: 0; }
|
||||
#lime-bar-design-comparison .screen-center .bar { border-left: 3px solid var(--lime-accent); }
|
||||
#lime-bar-design-comparison .screen-center .title-region {
|
||||
position: absolute; top: 0; bottom: 0; padding: 0;
|
||||
grid-column: auto; grid-row: auto;
|
||||
display: flex; justify-content: center; border: 0; background: transparent;
|
||||
}
|
||||
#lime-bar-design-comparison[data-focused="false"] .title-region {
|
||||
background: var(--lime-idle-bg); border-left-color: transparent;
|
||||
color: var(--lime-muted);
|
||||
}
|
||||
#lime-bar-design-comparison[data-focused="false"] .screen-center .title-region { background: transparent; }
|
||||
#lime-bar-design-comparison[data-focused="false"] .screen-center .bar { border-left-color: var(--lime-edge); }
|
||||
#lime-bar-design-comparison .state-label { margin-left: auto; }
|
||||
@media (max-width: 620px) {
|
||||
#lime-bar-design-comparison .music { display: none; }
|
||||
#lime-bar-design-comparison .identity { max-width: 200px; }
|
||||
#lime-bar-design-comparison .context { max-width: 110px; }
|
||||
}
|
||||
@media (max-width: 420px) {
|
||||
#lime-bar-design-comparison .volume { display: none; }
|
||||
#lime-bar-design-comparison .identity { padding: 0 6px; gap: 6px; max-width: 168px; }
|
||||
#lime-bar-design-comparison .context { max-width: 80px; }
|
||||
#lime-bar-design-comparison .title-region, #lime-bar-design-comparison .status { padding: 0 6px; }
|
||||
#lime-bar-design-comparison .state-label { margin-left: 0; }
|
||||
}
|
||||
</style>
|
||||
|
||||
<section class="variant left-region" aria-label="Sectioned bar with a left-aligned title">
|
||||
<div class="caption"><strong>A · Sectioned, left-aligned</strong><span class="recommended">Recommended</span><span class="state-label">Focused head</span></div>
|
||||
<div class="bar" role="img" aria-label="Menu, activity and layout at left; highlighted expanding title region; status at right">
|
||||
<div class="identity"><span class="logo">Lime</span><span class="context">WM:Code*</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="music">♪ スパイダー</span><span class="volume">25%</span><span class="clock">03:01</span></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="variant center-region" aria-label="Sectioned bar with its title centered inside the middle region">
|
||||
<div class="caption"><strong>B · Sectioned, region-centered</strong><span class="state-label">Focused head</span></div>
|
||||
<div class="bar" role="img" aria-label="Same three sections, with the title centered inside its highlighted section">
|
||||
<div class="identity"><span class="logo">Lime</span><span class="context">WM:Code*</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="music">♪ スパイダー</span><span class="volume">25%</span><span class="clock">03:01</span></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="variant screen-center" aria-label="Minimal bar with true head-centered title and an edge focus marker">
|
||||
<div class="caption"><strong>C · Minimal, head-centered</strong><span class="state-label">Focused head</span></div>
|
||||
<div class="bar" role="img" aria-label="Unsectioned bar with title anchored to the head center where space permits, and focus indicated at the left edge">
|
||||
<div class="identity"><span class="logo">Lime</span><span class="context">WM:Code*</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="music">♪ スパイダー</span><span class="volume">25%</span><span class="clock">03:01</span></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
(() => {
|
||||
const root = document.getElementById('lime-bar-design-comparison');
|
||||
const state = {
|
||||
focused: true,
|
||||
status: true,
|
||||
context: 'WM:Code*',
|
||||
title: 'config.lisp — VS Code'
|
||||
};
|
||||
function placeScreenTitle() {
|
||||
const bar = root.querySelector('.screen-center .bar');
|
||||
const region = bar.querySelector('.title-region');
|
||||
const identity = bar.querySelector('.identity');
|
||||
const status = bar.querySelector('.status');
|
||||
const left = identity.offsetWidth + 8;
|
||||
const right = bar.clientWidth - (status.hidden ? 8 : status.offsetWidth + 8);
|
||||
const available = Math.max(0, right - left);
|
||||
const text = region.querySelector('.title-text');
|
||||
region.style.width = available + 'px';
|
||||
const desired = Math.min(available, text.scrollWidth);
|
||||
const centered = (bar.clientWidth - desired) / 2;
|
||||
const clamped = Math.max(left, Math.min(centered, right - desired));
|
||||
region.style.width = desired + 'px';
|
||||
region.style.left = clamped + 'px';
|
||||
}
|
||||
function render() {
|
||||
root.dataset.focused = String(state.focused);
|
||||
root.querySelectorAll('.context').forEach(el => el.textContent = state.context);
|
||||
root.querySelectorAll('.title-text').forEach(el => el.textContent = state.title);
|
||||
root.querySelectorAll('.status').forEach(el => el.hidden = !state.status);
|
||||
root.querySelectorAll('.state-label').forEach(el => el.textContent = state.focused ? 'Focused head' : 'Unfocused head');
|
||||
placeScreenTitle();
|
||||
}
|
||||
render();
|
||||
new ResizeObserver(placeScreenTitle).observe(root);
|
||||
if (globalThis.Tweak) {
|
||||
const tweak = new Tweak({ container: root, onChange: render });
|
||||
tweak.addToggle(state, 'focused', { label: 'Head focused' });
|
||||
tweak.addToggle(state, 'status', { label: 'Status visible' });
|
||||
tweak.addSelect(state, 'context', { label: 'Activity and view', options: ['WM:Code*', 'Lime development:Debug*', 'Chill:Music'] });
|
||||
tweak.addSelect(state, 'title', { label: 'Window title', options: ['config.lisp — VS Code', 'Terminal', 'Window management notes — Waterfox', 'Untitled window'] });
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
Reference in New Issue
Block a user