seedhammer-v1-companion/web/emulator/app.css
mineracks b4635f4efc emulator: stack SD card slot below chassis, not beside it
.emu-device-card was display:flex justify-content:center, so adding
the SD card div as a sibling of .emu-chassis put them side-by-side
in a row. The chassis's internal grid then competed with the SD card
for horizontal space and the LCD column collapsed.

Fix: flex-direction:column on .emu-device-card so the chassis sits
on top at full width, with the SD card affordance stacked below.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 21:04:16 +10:00

266 lines
7.4 KiB
CSS

/* SeedHammer v1 emulator — chassis styling. Mirrors the physical
device: orange anodised aluminium body in landscape orientation,
one disc joystick on the left, recessed LCD in the centre, three
round side keys on the right. */
.emu-device-card {
padding: 24px;
display: flex;
flex-direction: column;
align-items: center;
}
/* Outer chassis — orange anodised look, with subtle gradient + edge
highlight so it reads as machined metal rather than flat colour. */
.emu-chassis {
--chassis-orange: #ff7a1f;
--chassis-edge: #c45a0f;
--chassis-corner-radius: 36px;
display: grid;
grid-template-columns: 130px 1fr 70px;
align-items: center;
gap: 18px;
padding: 22px 28px;
background:
linear-gradient(180deg, #ff8a30 0%, var(--chassis-orange) 50%, #ed6b14 100%);
border-radius: var(--chassis-corner-radius);
box-shadow:
0 16px 40px rgba(0, 0, 0, 0.35),
inset 0 0 0 1.5px rgba(255, 255, 255, 0.18),
inset 0 2px 0 rgba(255, 255, 255, 0.32),
inset 0 -2px 0 rgba(0, 0, 0, 0.22);
max-width: 720px;
width: 100%;
}
/* ─── LCD recess ─────────────────────────────────────────────────── */
.emu-lcd-bezel {
background:
linear-gradient(180deg, #1a1a1a 0%, #0a0a0a 100%);
border-radius: 14px;
padding: 14px;
box-shadow:
inset 0 2px 4px rgba(0, 0, 0, 0.7),
inset 0 -1px 0 rgba(255, 255, 255, 0.08);
display: flex;
align-items: center;
justify-content: center;
}
.emu-lcd-screen {
background: #000;
border-radius: 4px;
overflow: hidden;
width: 100%;
aspect-ratio: 1 / 1;
max-width: 320px;
max-height: 320px;
display: flex;
align-items: center;
justify-content: center;
}
#lcd {
display: block;
width: 100%;
height: 100%;
image-rendering: pixelated;
image-rendering: crisp-edges;
background: #000;
}
/* ─── Disc joystick (left) ───────────────────────────────────────── */
/* The disc itself: a round metal-look button. Five overlapping
square-ish hit zones inside cover the 5 joystick directions. The
visible disc is a circle; we hide the .disc-zone rectangles
underneath so users see one cohesive control with arrow hints. */
.emu-joystick {
position: relative;
width: 120px;
height: 120px;
border-radius: 50%;
background:
radial-gradient(circle at 35% 30%, #f8f4ee 0%, #c8c2b6 65%, #8a857a 100%);
box-shadow:
inset 0 -3px 6px rgba(0, 0, 0, 0.25),
inset 0 3px 3px rgba(255, 255, 255, 0.6),
0 6px 16px rgba(0, 0, 0, 0.45);
justify-self: center;
}
.emu-disc-zone {
position: absolute;
background: transparent;
border: none;
color: rgba(60, 50, 35, 0.7);
font-size: 16px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
user-select: none;
transition: background 0.08s;
}
.emu-disc-zone:hover {
color: rgba(40, 30, 15, 1);
}
.emu-disc-zone.pressed {
background: rgba(0, 0, 0, 0.18);
}
.disc-up { top: 0; left: 33%; width: 34%; height: 34%; border-radius: 50% 50% 8px 8px; }
.disc-down { bottom: 0; left: 33%; width: 34%; height: 34%; border-radius: 8px 8px 50% 50%; }
.disc-left { top: 33%; left: 0; width: 34%; height: 34%; border-radius: 50% 8px 8px 50%; }
.disc-right { top: 33%; right: 0; width: 34%; height: 34%; border-radius: 8px 50% 50% 8px; }
.disc-center {
top: 30%; left: 30%; width: 40%; height: 40%;
border-radius: 50%;
background: radial-gradient(circle at 35% 30%, #ffffff 0%, #d4cfc4 60%, #8a857a 100%);
box-shadow:
inset 0 -2px 4px rgba(0, 0, 0, 0.3),
inset 0 2px 2px rgba(255, 255, 255, 0.6);
}
.disc-center.pressed {
background: radial-gradient(circle at 35% 30%, #d8d2c5 0%, #b0a99b 60%, #6f6a5d 100%);
}
/* ─── Side keys (right) ──────────────────────────────────────────── */
.emu-keys {
display: flex;
flex-direction: column;
gap: 16px;
align-items: center;
}
.emu-key {
width: 48px;
height: 48px;
border-radius: 50%;
border: none;
font: inherit;
font-weight: 700;
font-size: 18px;
color: rgba(60, 50, 35, 0.85);
background:
radial-gradient(circle at 35% 30%, #fafafa 0%, #cdc8bd 70%, #8a857a 100%);
box-shadow:
0 4px 10px rgba(0, 0, 0, 0.35),
inset 0 -2px 4px rgba(0, 0, 0, 0.22),
inset 0 2px 2px rgba(255, 255, 255, 0.6);
cursor: pointer;
user-select: none;
transition: transform 0.05s;
}
.emu-key:active,
.emu-key.pressed {
transform: translateY(1px);
background:
radial-gradient(circle at 35% 30%, #d4cfc4 0%, #a8a297 70%, #6f6a5d 100%);
box-shadow:
0 2px 4px rgba(0, 0, 0, 0.35),
inset 0 -2px 4px rgba(0, 0, 0, 0.22),
inset 0 2px 2px rgba(255, 255, 255, 0.4);
}
/* ─── Keymap reference (unchanged) ───────────────────────────────── */
.emu-keymap {
width: 100%;
border-collapse: collapse;
font-size: 13px;
}
.emu-keymap td {
padding: 6px 12px;
border-bottom: 1px solid var(--hairline);
vertical-align: top;
}
.emu-keymap td:first-child { width: 14em; }
.emu-keymap td:nth-child(2) { width: 8em; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.emu-keymap tr:last-child td { border-bottom: none; }
.emu-keymap kbd {
background: var(--surface-strong);
border: 1px solid var(--hairline);
border-radius: 4px;
padding: 2px 8px;
font-family: ui-monospace, monospace;
font-size: 12px;
display: inline-block;
}
/* ─── SD card slot (below chassis) ───────────────────────────────── */
.emu-sdcard {
display: flex;
align-items: center;
gap: 18px;
margin: 24px auto 0;
max-width: 360px;
}
.emu-sdcard-slot {
position: relative;
width: 100px;
height: 36px;
background: linear-gradient(180deg, #1d1d1d, #0c0c0c);
border-radius: 4px;
box-shadow:
inset 0 2px 4px rgba(0, 0, 0, 0.6),
inset 0 -1px 0 rgba(255, 255, 255, 0.05);
overflow: hidden;
}
.emu-sdcard-card {
position: absolute;
top: 4px;
width: 56px;
height: 28px;
background: linear-gradient(180deg, #f6f3eb 0%, #d6d1c2 100%);
border-radius: 3px;
border: 1px solid #aaa298;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
display: flex;
align-items: center;
justify-content: center;
font-size: 10px;
font-weight: 700;
color: #555;
letter-spacing: 0.05em;
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.emu-sdcard-card.inserted { transform: translateX(8px); }
.emu-sdcard-card.ejected { transform: translateX(48px); }
.emu-sdcard-controls {
display: flex;
flex-direction: column;
gap: 4px;
align-items: flex-start;
}
.emu-sdcard-controls small {
color: var(--text-dim);
font-size: 12px;
font-variant-numeric: tabular-nums;
}
.btn.small {
padding: 6px 14px;
font-size: 12px;
background: #1a1a1a;
color: #fff;
border: none;
border-radius: 8px;
cursor: pointer;
font-weight: 600;
}
/* ─── Responsive ─────────────────────────────────────────────────── */
@media (max-width: 600px) {
.emu-chassis {
grid-template-columns: 90px 1fr 56px;
gap: 12px;
padding: 16px 18px;
}
.emu-joystick { width: 90px; height: 90px; }
.emu-key { width: 38px; height: 38px; font-size: 15px; }
}