mirror of
https://github.com/ParkerTenBroeck/hdl_sim.git
synced 2026-06-07 05:28:45 -04:00
603 lines
11 KiB
CSS
603 lines
11 KiB
CSS
:root {
|
|
--bg: #1e1e1e;
|
|
--surface: #252526;
|
|
--surface-muted: #2a2a2b;
|
|
--surface-header: #2d2d30;
|
|
--surface-soft: #1f1f20;
|
|
--surface-soft-2: #2a2a2b;
|
|
|
|
--text: #d4d4d4;
|
|
--text-muted: #a9adb3;
|
|
|
|
--accent: #0e639c;
|
|
--accent-soft: #1177bb;
|
|
--accent-muted: #264f78;
|
|
--ok: #22c55e;
|
|
--bad: #ef4444;
|
|
--warn: #f59e0b;
|
|
|
|
--border-strong: #4d4d4d;
|
|
--border: #3c3c3c;
|
|
--border-soft: #343436;
|
|
|
|
--button-primary-bg: #0e639c;
|
|
--button-primary-bg-hover: #1177bb;
|
|
--button-secondary-bg: #33363a;
|
|
--button-secondary-bg-hover: #3f4349;
|
|
--button-border: #2f5f8f;
|
|
|
|
--pill-bg: #323234;
|
|
--pill-border: #5e6166;
|
|
--pill-connected-bg: #1f2c23;
|
|
--pill-connected-border: #407a4d;
|
|
--pill-disconnected-bg: #342325;
|
|
--pill-disconnected-border: #8d4f56;
|
|
|
|
--led-off-bg: #303033;
|
|
--led-off-border: #5b5d62;
|
|
--led-on-bg: #2a9d58;
|
|
--led-on-border: #5ccd88;
|
|
--led-group-bg: #242427;
|
|
--led-group-border: #4f5258;
|
|
|
|
--seg-off-bg: #3a3b3f;
|
|
--seg-on-bg: #f59e0b;
|
|
|
|
--toggle-off-bg: #3a3d41;
|
|
--toggle-off-knob: #c4c7cc;
|
|
--toggle-on-bg: #2f7d4d;
|
|
--toggle-on-knob: #7be8a5;
|
|
|
|
--momentary-bg: #373a3e;
|
|
--momentary-border: #60646b;
|
|
--momentary-down-bg: #365a7f;
|
|
--momentary-down-border: #5f8fc0;
|
|
--keypad-op-bg: #44484f;
|
|
--transparent: transparent;
|
|
--card-shadow: 0 10px 18px rgba(0, 0, 0, 0.35);
|
|
|
|
--radius: 14px;
|
|
--radius-sm: 10px;
|
|
--mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
--sans: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji";
|
|
}
|
|
|
|
* {
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
html,
|
|
body {
|
|
height: 100%;
|
|
}
|
|
|
|
body {
|
|
margin: 0;
|
|
background: var(--bg);
|
|
color: var(--text);
|
|
font-family: var(--sans);
|
|
}
|
|
|
|
button {
|
|
padding: 8px 12px;
|
|
border: 1px solid var(--button-border);
|
|
border-radius: var(--radius-sm);
|
|
background: var(--button-primary-bg);
|
|
color: var(--text);
|
|
cursor: pointer;
|
|
transition: background 0.15s ease, transform 0.05s ease;
|
|
}
|
|
|
|
button:hover {
|
|
background: var(--button-primary-bg-hover);
|
|
}
|
|
|
|
button:active {
|
|
transform: translateY(1px);
|
|
}
|
|
|
|
button.secondary {
|
|
background: var(--button-secondary-bg);
|
|
}
|
|
|
|
button.secondary:hover {
|
|
background: var(--button-secondary-bg-hover);
|
|
}
|
|
|
|
button:focus-visible {
|
|
outline: 1px solid var(--accent-soft);
|
|
outline-offset: 1px;
|
|
}
|
|
|
|
button:disabled {
|
|
opacity: 0.6;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
textarea {
|
|
width: 100%;
|
|
height: 100%;
|
|
padding: 12px;
|
|
border: 0;
|
|
outline: none;
|
|
resize: none;
|
|
color: var(--text);
|
|
background: var(--surface-soft);
|
|
font-family: var(--mono);
|
|
font-size: 13px;
|
|
line-height: 1.35;
|
|
}
|
|
|
|
.muted {
|
|
font-size: 12px;
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.is-hidden {
|
|
display: none !important;
|
|
}
|
|
|
|
.grid {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
align-items: stretch;
|
|
gap: 14px;
|
|
padding: 14px;
|
|
}
|
|
|
|
.card {
|
|
flex: 1 1 520px;
|
|
min-height: 0;
|
|
overflow: hidden;
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius);
|
|
background: var(--surface);
|
|
box-shadow: var(--card-shadow);
|
|
}
|
|
|
|
.cardHeader {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
gap: 10px;
|
|
padding: 12px;
|
|
border-bottom: 1px solid var(--border-soft);
|
|
background: var(--surface-header);
|
|
}
|
|
|
|
.cardHeaderWrap {
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.cardTitle {
|
|
font-weight: 700;
|
|
}
|
|
|
|
.cardActions {
|
|
display: flex;
|
|
gap: 8px;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.panelTopStatus {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
margin-left: auto;
|
|
flex-wrap: nowrap;
|
|
white-space: nowrap;
|
|
min-width: 0;
|
|
flex: 0 0 auto;
|
|
}
|
|
|
|
.pill {
|
|
display: inline-flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
padding: 6px 10px;
|
|
font-size: 12px;
|
|
border: 1px solid var(--pill-border);
|
|
border-radius: 999px;
|
|
background: var(--pill-bg);
|
|
min-width: 104px;
|
|
}
|
|
|
|
.pill.state-disabled {
|
|
border-color: var(--pill-disconnected-border);
|
|
background: var(--pill-disconnected-bg);
|
|
}
|
|
|
|
.pill.state-connected {
|
|
border-color: color-mix(in srgb, var(--accent-soft) 75%, white 25%);
|
|
background: color-mix(in srgb, var(--accent-muted) 72%, black 28%);
|
|
}
|
|
|
|
.pill.state-running {
|
|
border-color: var(--pill-connected-border);
|
|
background: var(--pill-connected-bg);
|
|
box-shadow: 0 0 0 1px color-mix(in srgb, var(--ok) 40%, transparent);
|
|
}
|
|
|
|
.modeToggle {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
font-size: 11px;
|
|
color: var(--text-muted);
|
|
user-select: none;
|
|
flex: 0 0 auto;
|
|
}
|
|
|
|
.modeToggle input {
|
|
position: absolute;
|
|
opacity: 0;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.modeSlider {
|
|
width: 36px;
|
|
height: 18px;
|
|
border: 1px solid var(--border-strong);
|
|
border-radius: 999px;
|
|
background: var(--toggle-off-bg);
|
|
position: relative;
|
|
}
|
|
|
|
.modeSlider::after {
|
|
content: "";
|
|
position: absolute;
|
|
top: 1px;
|
|
left: 1px;
|
|
width: 14px;
|
|
height: 14px;
|
|
border-radius: 999px;
|
|
background: var(--toggle-off-knob);
|
|
transition: transform 0.12s ease, background 0.12s ease;
|
|
}
|
|
|
|
.modeToggle input:checked + .modeSlider {
|
|
background: var(--accent-muted);
|
|
}
|
|
|
|
.modeToggle input:checked + .modeSlider::after {
|
|
transform: translateX(17px);
|
|
background: var(--accent-soft);
|
|
}
|
|
|
|
.blockTitle {
|
|
margin-bottom: 8px;
|
|
font-size: 12px;
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.subBlockTitle {
|
|
margin: 10px 0 8px;
|
|
font-size: 11px;
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.hint {
|
|
padding: 10px 12px;
|
|
border-top: 1px solid var(--border-soft);
|
|
color: var(--text-muted);
|
|
font-size: 12px;
|
|
background: var(--surface-soft-2);
|
|
}
|
|
|
|
.editor {
|
|
display: flex;
|
|
flex-direction: column;
|
|
min-height: 420px;
|
|
flex: 1.4 1 620px;
|
|
}
|
|
|
|
.editorWrap {
|
|
display: flex;
|
|
width: 100%;
|
|
height: 100%;
|
|
min-height: 0;
|
|
background: var(--surface-soft);
|
|
}
|
|
|
|
.editorLanguageLabel {
|
|
font-size: 12px;
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.editorLanguageSelect {
|
|
min-width: 104px;
|
|
padding: 7px 10px;
|
|
border: 1px solid var(--border-soft);
|
|
border-radius: 10px;
|
|
color: var(--text);
|
|
background: var(--surface-soft);
|
|
font: inherit;
|
|
}
|
|
|
|
.editorLanguageSelect:focus {
|
|
outline: 2px solid var(--accent-soft);
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
.lineGutter {
|
|
width: 54px;
|
|
margin: 0;
|
|
padding: 12px 10px 12px 12px;
|
|
overflow: hidden;
|
|
user-select: none;
|
|
text-align: right;
|
|
border-right: 1px solid var(--border-soft);
|
|
color: var(--text-muted);
|
|
background: var(--surface-soft-2);
|
|
font-family: var(--mono);
|
|
font-size: 13px;
|
|
line-height: 1.35;
|
|
}
|
|
|
|
textarea#vhdlEditor {
|
|
flex: 1;
|
|
overflow: auto;
|
|
overscroll-behavior-y: none;
|
|
background: var(--transparent);
|
|
}
|
|
|
|
.io .outputs {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 14px;
|
|
padding: 12px;
|
|
}
|
|
|
|
.ledRow {
|
|
display: grid;
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
gap: 10px;
|
|
}
|
|
|
|
.ledGroup {
|
|
display: grid;
|
|
grid-template-columns: repeat(8, minmax(0, 1fr));
|
|
gap: 6px;
|
|
padding: 8px;
|
|
border: 1px solid var(--led-group-border);
|
|
border-radius: 8px;
|
|
background: var(--led-group-bg);
|
|
}
|
|
|
|
.led {
|
|
position: relative;
|
|
display: grid;
|
|
place-items: center;
|
|
width: 100%;
|
|
border: 1px solid var(--led-off-border);
|
|
border-radius: 999px;
|
|
background: var(--led-off-bg);
|
|
aspect-ratio: 1 / 1;
|
|
}
|
|
|
|
.led::after {
|
|
content: attr(data-bit);
|
|
color: var(--text-muted);
|
|
font-family: var(--mono);
|
|
font-size: 8px;
|
|
line-height: 1;
|
|
}
|
|
|
|
.led.on {
|
|
border-color: var(--led-on-border);
|
|
background: var(--led-on-bg);
|
|
box-shadow: 0 0 6px color-mix(in srgb, var(--led-on-bg) 50%, transparent);
|
|
}
|
|
|
|
.hexRow {
|
|
display: grid;
|
|
grid-template-columns: 1fr;
|
|
gap: 6px;
|
|
overflow-x: hidden;
|
|
}
|
|
|
|
.hexGroup {
|
|
display: grid;
|
|
grid-template-columns: repeat(8, minmax(0, 1fr));
|
|
gap: 4px;
|
|
width: 100%;
|
|
padding: 6px;
|
|
border: 1px solid var(--border-soft);
|
|
border-radius: 10px;
|
|
background: var(--surface-muted);
|
|
}
|
|
|
|
.hexDigitWrap {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
min-width: 0;
|
|
}
|
|
|
|
.sevenSeg {
|
|
position: relative;
|
|
width: 100%;
|
|
max-width: 88px;
|
|
aspect-ratio: 88 / 136;
|
|
padding: 8%;
|
|
border: 1px solid var(--border-strong);
|
|
border-radius: 12px;
|
|
background: var(--surface-soft);
|
|
}
|
|
|
|
.seg {
|
|
position: absolute;
|
|
border-radius: 6px;
|
|
background: var(--seg-off-bg);
|
|
}
|
|
|
|
.seg.on {
|
|
background: var(--seg-on-bg);
|
|
box-shadow: 0 0 4px color-mix(in srgb, var(--seg-on-bg) 45%, transparent);
|
|
}
|
|
|
|
.seg.a { top: 8%; left: 21%; width: 58%; height: 7%; }
|
|
.seg.b { top: 14%; right: 11%; width: 10%; height: 34%; }
|
|
.seg.c { bottom: 14%; right: 11%; width: 10%; height: 34%; }
|
|
.seg.d { bottom: 8%; left: 21%; width: 58%; height: 7%; }
|
|
.seg.e { bottom: 14%; left: 11%; width: 10%; height: 34%; }
|
|
.seg.f { top: 14%; left: 11%; width: 10%; height: 34%; }
|
|
.seg.g { top: 46.5%; left: 21%; width: 58%; height: 7%; }
|
|
.seg.dp {
|
|
right: 5%;
|
|
bottom: 5%;
|
|
width: 9%;
|
|
height: 9%;
|
|
border-radius: 999px;
|
|
}
|
|
|
|
.digitLabel {
|
|
margin-top: 4px;
|
|
color: var(--text-muted);
|
|
font-family: var(--mono);
|
|
font-size: 10px;
|
|
}
|
|
|
|
.inputs {
|
|
display: flex;
|
|
flex-direction: column;
|
|
min-height: 0;
|
|
flex: 1.2 1 560px;
|
|
}
|
|
|
|
.twoCols {
|
|
display: grid;
|
|
gap: 12px;
|
|
min-height: 0;
|
|
padding: 12px;
|
|
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
|
}
|
|
|
|
.ioGrid {
|
|
display: grid;
|
|
gap: 6px;
|
|
grid-template-columns: repeat(auto-fit, minmax(64px, 1fr));
|
|
}
|
|
|
|
.ioCell {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 4px;
|
|
min-width: 64px;
|
|
min-height: 52px;
|
|
padding: 6px 4px;
|
|
border: 1px solid var(--border-soft);
|
|
border-radius: 12px;
|
|
background: var(--surface-soft);
|
|
}
|
|
|
|
.ioCell label {
|
|
color: var(--text-muted);
|
|
font-family: var(--mono);
|
|
font-size: 11px;
|
|
}
|
|
|
|
.toggle {
|
|
position: relative;
|
|
width: 34px;
|
|
height: 20px;
|
|
border: 1px solid var(--border-strong);
|
|
border-radius: 999px;
|
|
background: var(--toggle-off-bg);
|
|
cursor: pointer;
|
|
}
|
|
|
|
.toggle::after {
|
|
content: "";
|
|
position: absolute;
|
|
top: 2px;
|
|
left: 2px;
|
|
width: 14px;
|
|
height: 14px;
|
|
border-radius: 999px;
|
|
background: var(--toggle-off-knob);
|
|
transition: left 0.12s ease, background 0.12s ease;
|
|
}
|
|
|
|
.toggle.on {
|
|
background: var(--toggle-on-bg);
|
|
box-shadow: 0 0 0 1px color-mix(in srgb, var(--toggle-on-knob) 35%, transparent);
|
|
}
|
|
|
|
.toggle.on::after {
|
|
left: 16px;
|
|
background: var(--toggle-on-knob);
|
|
}
|
|
|
|
.momentary {
|
|
width: 34px;
|
|
height: 24px;
|
|
border: 1px solid var(--momentary-border);
|
|
border-radius: var(--radius-sm);
|
|
background: var(--momentary-bg);
|
|
}
|
|
|
|
.momentary.down {
|
|
border-color: var(--momentary-down-border);
|
|
background: var(--momentary-down-bg);
|
|
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent-soft) 35%, transparent);
|
|
}
|
|
|
|
.keypadGrid {
|
|
display: grid;
|
|
gap: 6px;
|
|
grid-template-columns: repeat(4, minmax(50px, 1fr));
|
|
}
|
|
|
|
.keypadBtn {
|
|
width: 100%;
|
|
min-height: 32px;
|
|
font-family: var(--mono);
|
|
font-size: 12px;
|
|
}
|
|
|
|
.keypadBtn.op {
|
|
background: var(--keypad-op-bg);
|
|
}
|
|
|
|
.keypadBtn.op:hover {
|
|
background: var(--accent-muted);
|
|
}
|
|
|
|
.logs {
|
|
display: flex;
|
|
flex-direction: column;
|
|
min-height: 0;
|
|
flex: 1 1 560px;
|
|
}
|
|
|
|
.logView {
|
|
height: 100%;
|
|
margin: 0;
|
|
padding: 12px;
|
|
overflow: auto;
|
|
white-space: pre-wrap;
|
|
word-break: break-word;
|
|
background: var(--surface-soft);
|
|
font-family: var(--mono);
|
|
font-size: 12px;
|
|
line-height: 1.35;
|
|
}
|
|
|
|
@media (max-width: 1100px) {
|
|
.card {
|
|
flex-basis: 100%;
|
|
}
|
|
|
|
.twoCols {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.panelTopStatus {
|
|
margin-left: auto;
|
|
width: auto;
|
|
justify-content: flex-end;
|
|
}
|
|
}
|