204 lines
4.4 KiB
CSS
Executable File
204 lines
4.4 KiB
CSS
Executable File
:root { color-scheme: dark light; }
|
|
/* Overlay opacity is configurable here. Set to 1 to let PNG alpha be authoritative */
|
|
:root {
|
|
--overlay-opacity: 1; /* default overlay alpha applied client-side */
|
|
}
|
|
|
|
body {
|
|
font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
|
|
margin: 0;
|
|
padding: 1rem;
|
|
background: #0b1020;
|
|
color: #e7eaf6;
|
|
|
|
}
|
|
|
|
h1, h2 {
|
|
margin: 0.5rem 0 0.25rem;
|
|
}
|
|
|
|
.grid {
|
|
display: grid;
|
|
gap: 1rem;
|
|
/*
|
|
grid-auto-flow: column;
|
|
grid-auto-columns: 1280px;
|
|
justify-content: start;
|
|
*/
|
|
grid-template-columns: repeat(auto-fit, minmax(1280px, 1fr));
|
|
align-items: start;
|
|
}
|
|
|
|
.panel {
|
|
background: #141b34;
|
|
border: 1px solid #242c4f;
|
|
border-radius: 12px;
|
|
padding: 1rem;
|
|
box-shadow: 0 10px 24px rgba(0,0,0,0.25);
|
|
}
|
|
|
|
.video-wrap {
|
|
position: relative;
|
|
background: #000;
|
|
border-radius: 8px;
|
|
overflow: hidden;
|
|
width: 100%;
|
|
max-width: 1280px;
|
|
aspect-ratio: 4 / 3;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
/* Ensure canvas and overlay are sized identically and keep the same aspect ratio
|
|
so overlays align correctly when the window is resized. */
|
|
.video-wrap canvas,
|
|
.video-wrap img,
|
|
#overlayImg {
|
|
position: absolute;
|
|
inset: 0; /* top:0; right:0; bottom:0; left:0 */
|
|
/*width: 100%;*/
|
|
width: 1280px;
|
|
height: 100%;
|
|
/* Use `contain` so both layers scale uniformly and show letterboxing instead
|
|
of stretching or cropping when the container size differs from the image. */
|
|
object-fit: contain;
|
|
background: #000;
|
|
}
|
|
|
|
.video-wrap canvas {
|
|
z-index: 1;
|
|
}
|
|
.video-wrap img,
|
|
#overlayImg {
|
|
z-index: 2;
|
|
pointer-events: none; /* don't block interactions with the canvas */
|
|
opacity: var(--overlay-opacity);
|
|
}
|
|
|
|
.status {
|
|
font-size: 0.9rem;
|
|
opacity: 0.85;
|
|
margin: 0.5rem 0 0;
|
|
}
|
|
|
|
.controls {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
|
gap: 0.5rem;
|
|
margin-top: 0.75rem;
|
|
}
|
|
|
|
.controls label {
|
|
display: grid;
|
|
gap: 0.25rem;
|
|
font-size: 0.9rem;
|
|
}
|
|
|
|
select, input, button {
|
|
padding: 0.5rem 0.6rem;
|
|
border-radius: 8px;
|
|
border: 1px solid #2d3766;
|
|
background: #0d1530;
|
|
color: #e7eaf6;
|
|
}
|
|
|
|
button.primary {
|
|
background: #355dff;
|
|
border-color: #355dff;
|
|
}
|
|
|
|
a {
|
|
color: #9eb8ff;
|
|
}
|
|
|
|
footer {
|
|
margin-top: 1.25rem;
|
|
opacity: 0.7;
|
|
font-size: 0.9rem;
|
|
}
|
|
|
|
.muted {
|
|
opacity: 0.8;
|
|
}
|
|
|
|
|
|
/* Ensure overlay uses contain and respects alpha channel from the PNG
|
|
(the PNG's transparency is the authoritative source of which pixels
|
|
are transparent; CSS opacity only adjusts global alpha). */
|
|
#overlayImg {
|
|
position: absolute;
|
|
inset: 0; /* shorthand for top:0; right:0; bottom:0; left:0; */
|
|
width: 100%;
|
|
height: 100%;
|
|
pointer-events: none;
|
|
opacity: var(--overlay-opacity);
|
|
object-fit: contain; /* preserve aspect ratio and don't distort */
|
|
background: transparent;
|
|
}
|
|
|
|
/* CSV table styles */
|
|
.csv-table {
|
|
width: 440px; /* 4 columns * 200px each */
|
|
border-collapse: collapse;
|
|
margin-top: 0.5rem;
|
|
table-layout: fixed; /* use fixed layout so column widths are respected */
|
|
}
|
|
.csv-table th, .csv-table td {
|
|
border: 1px solid rgba(255,255,255,0.06);
|
|
padding: 0.35rem 0.5rem;
|
|
text-align: center;
|
|
font-size: 0.9rem;
|
|
width: 110px; /* fixed column width */
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
.csv-table th {
|
|
background: rgba(255,255,255,0.02);
|
|
font-weight: 600;
|
|
}
|
|
.csv-table tr:nth-child(even) td {
|
|
background: rgba(255,255,255,0.01);
|
|
}
|
|
|
|
/* Right-align CSV numeric data and use tabular digits for stable column alignment */
|
|
.csv-table td { text-align: right; font-variant-numeric: tabular-nums; }
|
|
|
|
#GCodeWindow {
|
|
width: 100%;
|
|
height: 200px;
|
|
}
|
|
|
|
/* Layout: place the buttons and GCode window side-by-side in their panel.
|
|
- `#divButtons` gets a fixed ~300px width
|
|
- `#divGCodeWindow` uses the remaining width
|
|
- On small screens they stack vertically for usability */
|
|
/* Use floats for a predictable two-column layout inside the panel. */
|
|
#divButtons {
|
|
float: left;
|
|
width: 300px;
|
|
box-sizing: border-box;
|
|
margin-right: 1rem;
|
|
}
|
|
#divGCodeWindow {
|
|
display: block;
|
|
margin-left: 320px; /* 300px left column + 1rem gap */
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
/* Clear floats inside panels so subsequent content flows correctly */
|
|
.panel::after {
|
|
content: "";
|
|
display: table;
|
|
clear: both;
|
|
}
|
|
@media (max-width: 800px) {
|
|
#divButtons, #divGCodeWindow {
|
|
display: block;
|
|
float: none;
|
|
width: 100%;
|
|
margin-left: 0;
|
|
margin-right: 0;
|
|
}
|
|
}
|
|
|