gliner/ui/glinerworkbench.razor.scss
// GlinerWorkbench — dark two-column developer workbench theme (UI redesign).
// Presentation only: no inference/model semantics. Plain flex layout + normal
// s&box stylesheet features (no CSS grid, no web-only CSS).
// palette --------------------------------------------------------------------
$bg: #0b0e14; // backdrop
$card: #12161f; // primary card surface
$inset: #0d1017; // input / nested surface
$inset-2: #171c27; // hover surface
$border: rgba(129, 148, 182, 0.16);
$border-2: rgba(129, 148, 182, 0.28);
$text: #e6ebf2;
$text-2: #8b96a8;
$muted: #6a7488;
$blue: #4c8dff;
$blue-hi: #619aff;
$green: #46c07a;
$amber: #d9a04c;
$red: #e05b5b;
GlinerWorkbench {
position: absolute;
left: 20px;
top: 20px;
right: 20px;
bottom: 20px;
font-size: 13px;
font-weight: 400;
color: $text;
cursor: default;
}
// The workbench surface is the key-catcher wrapper panel's root
// (GlinerKeyCatcherPanel), so everything hangs off this class selector.
.workbench {
flex-direction: column;
flex-grow: 1;
gap: 14px;
width: 100%;
pointer-events: all;
// ---- shared card ---------------------------------------------------------
.card {
flex-direction: column;
background-color: $card;
border: 1px solid $border;
border-radius: 10px;
min-height: 0;
}
.card-scroll {
flex-direction: column;
flex-grow: 1;
min-height: 0;
overflow-y: auto;
overflow-x: hidden;
padding: 16px 18px;
gap: 18px;
scrollbar-width: 8px;
scrollbar-thumb-color: rgba(129, 148, 182, 0.25);
scrollbar-track-color: transparent;
}
// ---- header ---------------------------------------------------------------
.header {
flex-direction: row;
align-items: center;
justify-content: space-between;
background-color: $card;
border: 1px solid $border;
border-radius: 10px;
padding: 12px 18px;
gap: 16px;
}
.header-titles {
flex-direction: column;
gap: 2px;
min-width: 320px;
}
.title {
font-size: 15px;
font-weight: 600;
color: $text;
white-space: nowrap;
}
.subtitle {
font-size: 11.5px;
color: $text-2;
white-space: nowrap;
}
.header-controls {
flex-direction: row;
align-items: center;
gap: 22px;
}
.backend-block {
flex-direction: row;
align-items: center;
gap: 10px;
}
.backend-caption {
color: $text-2;
font-size: 12px;
}
// segmented control (shared by backend switch + result view toggle)
.seg {
flex-direction: row;
background-color: $inset;
border: 1px solid $border;
border-radius: 8px;
padding: 3px;
gap: 3px;
}
.seg-btn {
padding: 5px 14px;
border-radius: 6px;
background-color: transparent;
border: 0;
color: $text-2;
font-size: 12px;
font-weight: 500;
cursor: pointer;
white-space: nowrap;
align-items: center;
&:hover {
color: $text;
background-color: rgba(129, 148, 182, 0.10);
}
&.active {
background-color: $blue;
color: #ffffff;
font-weight: 600;
&:hover {
background-color: $blue-hi;
}
.seg-note {
color: rgba(255, 255, 255, 0.75);
}
}
&.disabled {
opacity: 0.4;
pointer-events: none;
}
}
.seg-note {
font-size: 10.5px;
font-weight: 400;
color: $muted;
}
.seg-small .seg-btn {
padding: 4px 10px;
font-size: 11.5px;
}
// status block
.status-block {
flex-direction: column;
align-items: flex-end;
gap: 2px;
min-width: 190px;
}
.status-line {
flex-direction: row;
align-items: center;
gap: 7px;
}
.dot {
width: 9px;
height: 9px;
border-radius: 5px;
background-color: $muted;
&.ready { background-color: $green; }
&.busy { background-color: $blue; }
&.warn { background-color: $amber; }
&.error { background-color: $red; }
}
.status-text {
font-size: 13px;
font-weight: 600;
color: $muted;
&.ready { color: $green; }
&.busy { color: $blue; }
&.warn { color: $amber; }
&.error { color: $red; }
}
.status-sub {
font-size: 11px;
color: $text-2;
white-space: nowrap;
}
// ---- body layout ------------------------------------------------------------
.body {
flex-direction: row;
flex-grow: 1;
gap: 14px;
min-height: 0;
}
.input-card {
flex-grow: 0;
flex-shrink: 1;
flex-basis: 51%;
min-width: 470px;
}
.results-card {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0;
min-width: 400px;
}
// ---- input sections ----------------------------------------------------------
.section {
flex-direction: column;
gap: 6px;
}
.section-head {
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.section-title {
font-size: 13.5px;
font-weight: 600;
color: $text;
}
.card-title {
font-size: 14.5px;
font-weight: 600;
color: $text;
}
.card-subtitle {
font-size: 13px;
font-weight: 600;
color: $text;
}
.helper {
font-size: 11.5px;
color: $text-2;
}
.count-chip {
padding: 2px 9px;
border-radius: 10px;
background-color: $inset;
border: 1px solid $border;
color: $text-2;
font-size: 11.5px;
font-weight: 600;
&.chip-warn {
color: $amber;
border-color: rgba(217, 160, 76, 0.4);
}
}
// text entries -----------------------------------------------------------
TextEntry {
background-color: $inset;
border: 1px solid $border;
border-radius: 8px;
padding: 8px 11px;
font-size: 12.5px;
color: $text;
&:focus {
border-color: rgba(76, 141, 255, 0.55);
}
}
.context-input {
width: 100%;
height: 130px;
}
.task-input {
width: 100%;
height: 34px;
}
.field-foot {
flex-direction: row;
justify-content: space-between;
font-size: 10.5px;
color: $muted;
}
.field-foot-note {
color: $muted;
opacity: 0.8;
}
.field-warn {
font-size: 11px;
color: $amber;
}
// candidate rows -------------------------------------------------------------
.candidate-row {
flex-direction: row;
align-items: center;
gap: 8px;
height: 38px;
}
.candidate-index {
width: 16px;
color: $muted;
font-size: 11.5px;
text-align: right;
}
.candidate-label {
width: 150px;
height: 34px;
white-space: nowrap;
}
.candidate-desc {
flex-grow: 1;
height: 34px;
min-width: 120px;
}
.icon-button {
width: 26px;
height: 26px;
align-items: center;
justify-content: center;
border-radius: 6px;
background-color: transparent;
border: 1px solid transparent;
color: $muted;
font-size: 12px;
cursor: pointer;
&:hover {
background-color: rgba(224, 91, 91, 0.12);
border-color: rgba(224, 91, 91, 0.35);
color: $red;
}
&.disabled {
opacity: 0.25;
pointer-events: none;
}
}
.add-button {
height: 34px;
align-items: center;
justify-content: center;
border-radius: 8px;
border: 1px dashed $border-2;
background-color: transparent;
color: $text-2;
font-size: 12.5px;
font-weight: 500;
cursor: pointer;
&:hover {
background-color: $inset-2;
color: $text;
border-color: rgba(76, 141, 255, 0.5);
}
&.disabled {
opacity: 0.35;
pointer-events: none;
}
}
// ---- action bar ---------------------------------------------------------------
.action-bar {
flex-direction: row;
align-items: center;
gap: 10px;
padding: 14px 18px;
border-top: 1px solid $border;
}
.primary-button {
flex-direction: row;
align-items: center;
justify-content: center;
gap: 10px;
height: 38px;
padding: 0 26px;
border-radius: 8px;
border: 1px solid rgba(76, 141, 255, 0.6);
background-color: $blue;
color: #ffffff;
font-size: 13.5px;
font-weight: 600;
cursor: pointer;
&:hover {
background-color: $blue-hi;
}
&:active {
background-color: #3f7be0;
}
&.disabled {
opacity: 0.45;
pointer-events: none;
}
&.running {
background-color: rgba(76, 141, 255, 0.18);
border-color: rgba(76, 141, 255, 0.45);
color: $blue-hi;
cursor: default;
pointer-events: none;
}
}
.action-hint-note {
font-size: 10.5px;
color: $muted;
padding: 2px 7px;
background-color: $inset;
border: 1px solid $border;
border-radius: 4px;
}
.secondary-button {
height: 38px;
padding: 0 18px;
border-radius: 8px;
border: 1px solid $border-2;
background-color: transparent;
color: $text-2;
font-size: 13px;
font-weight: 500;
cursor: pointer;
&:hover {
background-color: $inset-2;
color: $text;
}
&.disabled {
opacity: 0.35;
pointer-events: none;
}
}
.run-block-note {
font-size: 11px;
color: $amber;
margin-left: 4px;
}
// ---- results --------------------------------------------------------------------
.results-head {
flex-direction: column;
gap: 2px;
padding: 14px 18px 0 18px;
}
.results-body {
gap: 16px;
}
.results-foot {
flex-direction: row;
justify-content: flex-end;
align-items: center;
gap: 7px;
padding: 8px 18px;
border-top: 1px solid $border;
color: $muted;
font-size: 11px;
}
.foot-sep {
opacity: 0.5;
}
// banners / states -----------------------------------------------------------
.banner {
padding: 10px 12px;
border-radius: 8px;
font-size: 12.5px;
white-space: normal;
&.banner-error {
background-color: rgba(224, 91, 91, 0.10);
border: 1px solid rgba(224, 91, 91, 0.35);
color: #f0a3a3;
}
&.banner-warn {
background-color: rgba(217, 160, 76, 0.10);
border: 1px solid rgba(217, 160, 76, 0.35);
color: #e8c290;
}
}
.state-note {
flex-direction: column;
gap: 6px;
padding: 26px 8px;
align-items: center;
.state-title {
font-size: 14.5px;
font-weight: 600;
color: $text-2;
}
.state-sub {
font-size: 12px;
color: $muted;
white-space: normal;
}
&.running-note {
.state-title { color: $blue; }
}
}
// selected action card -------------------------------------------------------
.selected-card {
flex-direction: row;
align-items: center;
justify-content: space-between;
gap: 18px;
padding: 14px 16px;
border-radius: 10px;
border: 1px solid rgba(70, 192, 122, 0.45);
background-color: rgba(70, 192, 122, 0.07);
}
.selected-main {
flex-direction: column;
gap: 3px;
min-width: 0;
}
.selected-caption {
font-size: 11px;
font-weight: 600;
color: $green;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.selected-label {
font-size: 21px;
font-weight: 700;
color: $text;
white-space: nowrap;
}
.selected-desc {
font-size: 12.5px;
color: $text-2;
white-space: nowrap;
}
.selected-side {
flex-direction: column;
align-items: flex-end;
gap: 4px;
min-width: 150px;
}
.selected-score-caption {
font-size: 11px;
color: $text-2;
}
.selected-score {
font-size: 19px;
font-weight: 700;
color: $text;
}
// score bars ------------------------------------------------------------------
.bar-track {
width: 150px;
height: 6px;
border-radius: 3px;
background-color: rgba(129, 148, 182, 0.14);
overflow: hidden;
}
.selected-track {
width: 150px;
height: 7px;
}
.bar-fill {
height: 100%;
border-radius: 3px;
background-color: $blue;
&.fill-green {
background-color: $green;
}
&.fill-blue {
background-color: rgba(76, 141, 255, 0.75);
}
}
// ranking -----------------------------------------------------------------------
.ranking-head {
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.ranking-table {
flex-direction: column;
border: 1px solid $border;
border-radius: 8px;
overflow: hidden;
}
.ranking-row {
flex-direction: row;
align-items: center;
gap: 10px;
padding: 0 12px;
height: 40px;
border-bottom: 1px solid rgba(129, 148, 182, 0.08);
&.head {
height: 32px;
background-color: rgba(129, 148, 182, 0.06);
border-bottom: 1px solid $border;
color: $text-2;
font-size: 11.5px;
font-weight: 500;
}
&.winner {
background-color: rgba(70, 192, 122, 0.07);
}
&:last-child {
border-bottom: 0;
}
}
.rank-no {
width: 22px;
color: $muted;
font-size: 12px;
}
.rank-label {
width: 120px;
color: $text;
font-weight: 500;
white-space: nowrap;
overflow: hidden;
}
.ranking-row.winner {
.rank-no {
color: $green;
font-weight: 700;
}
.rank-label {
color: $green;
font-weight: 700;
}
}
.rank-desc {
flex-grow: 1;
color: $text-2;
font-size: 12px;
white-space: nowrap;
overflow: hidden;
min-width: 60px;
}
.rank-score {
width: 64px;
text-align: right;
color: $text;
font-weight: 600;
white-space: nowrap;
}
.rank-logit {
width: 70px;
text-align: right;
color: $text-2;
font-size: 12px;
white-space: nowrap;
}
.rank-bar {
width: 150px;
flex-direction: row;
}
// diagnostics ----------------------------------------------------------------------
.diag {
flex-direction: column;
border: 1px solid $border;
border-radius: 8px;
overflow: hidden;
}
.diag-head {
flex-direction: row;
align-items: center;
gap: 8px;
padding: 10px 12px;
font-size: 12.5px;
font-weight: 600;
color: $text-2;
cursor: pointer;
&:hover {
color: $text;
background-color: rgba(129, 148, 182, 0.05);
}
}
.diag-arrow {
font-size: 10px;
color: $muted;
}
.diag-grid {
flex-direction: row;
flex-wrap: wrap;
padding: 4px 12px 12px 12px;
row-gap: 12px;
}
.diag-cell {
width: 33%;
flex-direction: column;
gap: 3px;
padding-right: 12px;
}
.diag-label {
font-size: 11px;
color: $muted;
}
.diag-value {
font-size: 12.5px;
font-weight: 500;
color: $text;
white-space: nowrap;
}
.diag-foot {
padding: 0 12px 10px 12px;
font-size: 10.5px;
color: $muted;
}
}