/* * Blueforce Field OS — central panel stylesheet. * --------------------------------------------------------------------------- * Colour and metrics come from web/static/tokens.css and from nowhere else. * This file declares no custom property and no literal colour: one palette * change in tokens.css moves both operator surfaces. A colour here is a state * or the action accent, never decoration (docs/DESIGN.md, Rules 1 and 2). * * Layout follows docs/DESIGN.md FIRST VIEWPORT: dark header band, one large * figure in the summary strip, then the fleet list beside the selected device's * detail region. */ *, *::before, *::after { box-sizing: border-box; } html { background: var(--bg-app); } body { margin: 0; background: var(--bg-app); color: var(--text); font-family: var(--font-ui); font-size: var(--size-md); line-height: var(--leading-normal); } a { color: var(--accent); } a:hover { color: var(--accent-hover); } .mono { font-family: var(--font-data); font-variant-numeric: tabular-nums; } :focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; } .visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; } .skip-link { position: absolute; left: var(--sp-2); top: calc(-1 * var(--sp-7)); z-index: 2; padding: var(--sp-2) var(--sp-3); background: var(--bg-panel); color: var(--accent); border: 1px solid var(--border-strong); border-radius: var(--radius); transition: top .1s linear; } .skip-link:focus { top: var(--sp-2); } /* -- Header band: the one dark region ---------------------------------- */ .app-header { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-5); min-height: var(--header-h); padding: var(--sp-2) var(--sp-4); background: var(--bg-header); color: var(--text-on-dark); } .app-header__identity { display: flex; flex-direction: column; } .app-header__product { margin: 0; font-size: var(--size-lg); font-weight: 600; line-height: var(--leading-tight); letter-spacing: .01em; } .app-header__surface { font-size: var(--size-xs); color: var(--text-on-dark); opacity: .75; } .app-header__target, .app-header__privilege { display: flex; flex-direction: column; gap: var(--sp-1); margin: 0; font-size: var(--size-sm); } .app-header__label { font-size: var(--size-xs); letter-spacing: .06em; text-transform: uppercase; color: var(--text-on-dark); opacity: .7; } .app-header__value { color: var(--text-on-dark); } .app-header__reason { max-width: 34ch; font-size: var(--size-xs); color: var(--text-on-dark); opacity: .8; } .app-header__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); } .app-header__privilege { max-width: 40ch; text-align: right; } .gated-reason { max-width: 30ch; font-size: var(--size-xs); color: var(--text-on-dark); opacity: .8; } .app-header__nav { display: flex; gap: var(--sp-3); margin-right: auto; } .nav-link { color: var(--text-on-dark); font-size: var(--size-sm); text-decoration: none; padding-bottom: var(--sp-1); border-bottom: 2px solid transparent; } .nav-link[aria-current="page"] { border-bottom-color: var(--text-on-dark); } /* -- Buttons and inputs: one height ------------------------------------ */ .button { display: inline-flex; align-items: center; justify-content: center; height: var(--control-h); padding: 0 var(--sp-3); font-family: inherit; font-size: var(--size-sm); font-weight: 600; text-decoration: none; color: var(--text); background: var(--bg-panel); border: 1px solid var(--border-strong); border-radius: var(--radius); cursor: pointer; } .button--primary { color: var(--text-on-accent); background: var(--accent); border-color: var(--accent); } .button--primary:hover { color: var(--text-on-accent); background: var(--accent-hover); } .button--gated:disabled { color: var(--text-faint); background: var(--bg-sunken); border-color: var(--border); cursor: not-allowed; } input[type="search"], select { height: var(--control-h); padding: 0 var(--sp-2); font-family: inherit; font-size: var(--size-sm); color: var(--text); background: var(--bg-panel); border: 1px solid var(--border-strong); border-radius: var(--radius); } /* -- Page frame -------------------------------------------------------- */ .app-main { display: flex; flex-direction: column; gap: var(--sp-4); padding: var(--sp-4); max-width: 1600px; margin: 0 auto; } .app-footer { display: flex; flex-wrap: wrap; gap: var(--sp-4); padding: var(--sp-3) var(--sp-4); font-size: var(--size-xs); color: var(--text-muted); border-top: 1px solid var(--border); } .section-title { margin: 0 0 var(--sp-2); font-size: var(--size-xl); line-height: var(--leading-tight); } .subsection-title { margin: 0 0 var(--sp-2); font-size: var(--size-lg); line-height: var(--leading-tight); } .section-note { margin: 0 0 var(--sp-2); font-size: var(--size-sm); color: var(--text-muted); } .cell-note { font-size: var(--size-xs); color: var(--text-muted); } /* -- Data-source banner: what the operator is looking at --------------- */ .data-banner { display: flex; align-items: baseline; gap: var(--sp-3); padding: var(--sp-2) var(--sp-3); font-size: var(--size-sm); border: 1px solid var(--border-strong); border-radius: var(--radius); } .data-banner--info { background: var(--info-soft); border-color: var(--info); } .data-banner--warn { background: var(--warn-soft); border-color: var(--warn); } .data-banner--danger { background: var(--danger-soft); border-color: var(--danger); } .data-banner__word { font-size: var(--size-xs); font-weight: 700; letter-spacing: .06em; } /* -- Summary strip: the one loud figure -------------------------------- */ .summary { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-4) var(--sp-6); padding: var(--sp-4); background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); } .summary__lead { display: grid; gap: var(--sp-1); padding-right: var(--sp-5); border-right: 1px solid var(--border); } .summary__lead-figure { font-size: var(--size-2xl); font-weight: 700; line-height: var(--leading-tight); color: var(--state-ready); } .summary__lead-label { font-size: var(--size-sm); font-weight: 600; } .summary__lead-note { font-size: var(--size-xs); color: var(--text-muted); } .summary__grid { display: flex; flex-wrap: wrap; gap: var(--sp-5); margin: 0; padding: 0; list-style: none; } .summary__cell { display: grid; gap: var(--sp-1); } .summary__cell-value { font-size: var(--size-lg); font-weight: 600; line-height: var(--leading-tight); } .summary__cell-word { font-size: var(--size-xs); font-weight: 700; letter-spacing: .04em; } .summary__cell-note { font-size: var(--size-xs); color: var(--text-muted); } /* -- Two-column body: list beside detail ------------------------------- */ .split { display: grid; grid-template-columns: minmax(0, 1fr) minmax(320px, 400px); gap: var(--sp-4); align-items: start; } @media (max-width: 1100px) { .split { grid-template-columns: minmax(0, 1fr); } } .split__list, .split__detail { padding: var(--sp-4); background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--radius-lg); } /* -- Filter bar -------------------------------------------------------- */ .filter-bar { display: grid; gap: var(--sp-2); margin-bottom: var(--sp-3); padding: var(--sp-3); background: var(--bg-sunken); border-radius: var(--radius); } .filter-bar__form { display: flex; flex-wrap: wrap; align-items: end; gap: var(--sp-3); margin: 0; } .filter-field { display: grid; gap: var(--sp-1); margin: 0; font-size: var(--size-xs); color: var(--text-muted); } .filter-field--check { grid-auto-flow: column; align-items: center; gap: var(--sp-2); height: var(--control-h); } .filter-field--actions { grid-auto-flow: column; align-items: center; gap: var(--sp-2); font-size: var(--size-sm); } .filter-bar__summary { margin: 0; font-size: var(--size-xs); color: var(--text-muted); } .wave-strip { margin: 0 0 var(--sp-3); font-size: var(--size-xs); color: var(--text-muted); } .wave-strip__item { white-space: nowrap; } /* -- Fleet table ------------------------------------------------------- */ .fleet-table { width: 100%; border-collapse: collapse; font-size: var(--size-sm); } .fleet-table th { padding: var(--sp-2); text-align: left; font-size: var(--size-xs); font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--text-muted); border-bottom: 1px solid var(--border-strong); } .fleet-table td { height: var(--row-h); padding: var(--sp-2); border-bottom: 1px solid var(--border); vertical-align: middle; } .fleet-row:hover td { background: var(--bg-sunken); } .fleet-row--selected td { background: var(--accent-soft); } .row-select { text-decoration: none; } .row-select:hover { text-decoration: underline; } /* -- Badges: a word plus a state colour -------------------------------- */ .badge { display: inline-flex; align-items: center; padding: var(--sp-1) var(--sp-2); font-family: var(--font-data); font-size: var(--size-xs); font-weight: 700; letter-spacing: .04em; border: 1px solid; border-radius: var(--radius); } .badge--state-provisioned { color: var(--state-provisioned); background: var(--info-soft); border-color: var(--state-provisioned); } .badge--state-enrolled { color: var(--state-enrolled); background: var(--warn-soft); border-color: var(--state-enrolled); } .badge--state-ready { color: var(--state-ready); background: var(--ok-soft); border-color: var(--state-ready); } .badge--state-failed { color: var(--state-failed); background: var(--danger-soft); border-color: var(--state-failed); } .badge--state-absent { color: var(--state-absent); background: var(--idle-soft); border-color: var(--state-absent); } .badge--privilege-read-only { color: var(--text-on-dark); background: transparent; border-color: var(--text-on-dark); } .badge--privilege-full { color: var(--warn); background: var(--warn-soft); border-color: var(--warn); } /* -- Detail region ----------------------------------------------------- */ .detail__state { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); margin: 0 0 var(--sp-3); } .detail__meaning { font-size: var(--size-sm); color: var(--text-muted); } .selection-note, .reason { margin: 0 0 var(--sp-3); padding: var(--sp-2) var(--sp-3); font-size: var(--size-sm); border: 1px solid; border-radius: var(--radius); } .selection-note { background: var(--idle-soft); border-color: var(--state-absent); } .reason { background: var(--danger-soft); border-color: var(--state-failed); color: var(--text); } .facts { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: var(--sp-2) var(--sp-3); margin: 0 0 var(--sp-4); font-size: var(--size-sm); } .facts dt { font-size: var(--size-xs); letter-spacing: .04em; text-transform: uppercase; color: var(--text-muted); align-self: center; } .facts dd { margin: 0; } .channels { display: grid; gap: var(--sp-2); margin: 0 0 var(--sp-2); padding: 0; list-style: none; } .channel { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--sp-1) var(--sp-2); padding: var(--sp-2); background: var(--bg-sunken); border-radius: var(--radius); } .channel__name { font-weight: 600; font-size: var(--size-sm); } .channel__status { justify-self: end; font-size: var(--size-xs); font-weight: 700; } .channel__status--ok { color: var(--ok); } .channel__status--warn { color: var(--warn); } .channel__status--danger { color: var(--danger); } .channel__status--idle { color: var(--idle); } .channel__meta { font-size: var(--size-xs); color: var(--text-faint); } .channel__hint { font-size: var(--size-xs); color: var(--text-muted); } .notes__list { display: grid; gap: var(--sp-1); margin: 0 0 var(--sp-3); padding-left: var(--sp-4); font-size: var(--size-xs); color: var(--text-muted); } /* -- Warnings and invalid records -------------------------------------- */ .warnings, .invalid { padding: var(--sp-3); margin-bottom: var(--sp-3); border: 1px solid; border-radius: var(--radius); } .warnings { background: var(--info-soft); border-color: var(--info); } .invalid { background: var(--danger-soft); border-color: var(--state-failed); } .warnings__list, .invalid__list { display: grid; gap: var(--sp-1); margin: 0; padding-left: var(--sp-4); font-size: var(--size-sm); } .empty-note { margin: var(--sp-3) 0 0; padding: var(--sp-3); font-size: var(--size-sm); background: var(--bg-sunken); border-radius: var(--radius); } /* -- About/durum view -------------------------------------------------- */ .about { display: grid; gap: var(--sp-4); } .card { padding: var(--sp-4); background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--radius-lg); } .card--danger { background: var(--danger-soft); border-color: var(--state-failed); } .about-table { width: 100%; border-collapse: collapse; font-size: var(--size-sm); } .about-table th { padding: var(--sp-2); text-align: left; font-size: var(--size-xs); letter-spacing: .04em; text-transform: uppercase; color: var(--text-muted); border-bottom: 1px solid var(--border-strong); } .about-table td { padding: var(--sp-2); border-bottom: 1px solid var(--border); vertical-align: top; } .rules { display: grid; gap: var(--sp-2); margin: 0; padding-left: var(--sp-4); font-size: var(--size-sm); }