/*
 * The console's own layer, on top of RadiantUI.
 *
 * The division of labour has not changed: anything that looks like a control - tables, buttons, inputs, pagination -
 * still belongs to RadiantUI, because a second opinion on what a button looks like is how a console starts drifting
 * away from the rest of the product. What lives here is the shell, the layout, the motion vocabulary and the states
 * RadiantUI has no opinion about.
 *
 * Two deliberate exceptions are marked "RADIANTUI OVERRIDE" further down, each with its reason.
 */

/* ------------------------------------------------------------------------------------------------
 * 1. Typeface
 *
 * RadiantUI's root.css declares font-family: 'Inter' on the universal selector and ships no font file and no
 * @font-face, so on any machine without Inter installed - which is every stock Windows install - the browser falls
 * back to its default font and the console renders in a serif. The universal selector beats anything inherited from
 * body, which is why the previous rule on html, body alone never took effect below the body element.
 *
 * Inter stays first in the stack so an installed copy still wins, then the platform UI faces. No webfont: this
 * console is meant to run on plant networks with no route to the internet, and a font request that hangs is a
 * console that renders in the fallback anyway.
 */
:root {
    --rc-font: Inter, "Segoe UI Variable Text", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
    --rc-font-mono: "Cascadia Mono", Consolas, "SF Mono", ui-monospace, monospace;
}

*,
*::before,
*::after {
    font-family: var(--rc-font);
}

.rc-mono,
.rc-hash,
.rc-secret,
.rc-mono * {
    font-family: var(--rc-font-mono);
}

/* ------------------------------------------------------------------------------------------------
 * 2. Tokens
 *
 * Semantic names, resolved onto RadiantUI's palette where one exists, so a change to the house colours carries
 * through instead of leaving the console behind. Everything below references only these.
 */
:root {
    color-scheme: light;

    /* Surfaces and ink */
    --rc-shell-bg: #eef1f5;
    --rc-surface: #ffffff;
    --rc-surface-sunken: #f6f8fa;
    --rc-surface-hover: #f2f5f9;
    --rc-ink: #1a2027;
    --rc-ink-muted: #626c77;
    --rc-border: #dee3e9;
    --rc-border-strong: #c9d1da;

    /* Accent. RadiantUI's --blue is 4.2:1 on white, below the 4.5:1 floor, so text uses the darker ink variant. */
    --rc-accent: var(--blue, #0582ca);
    --rc-accent-ink: #05658f;
    --rc-accent-deep: #024e7a;
    --rc-accent-wash: #e8f3fb;

    /* Status. Dark ink on a light wash, all past 4.5:1. */
    --rc-ok-ink: var(--dark-green, #0b5927);
    --rc-ok-wash: #e3f7ea;
    --rc-warn-ink: var(--dark-yellow, #a15e01);
    --rc-warn-wash: var(--light-yellow, #fff3ca);
    --rc-danger-ink: var(--dark-red, #8b0b0b);
    --rc-danger-wash: #fdeaea;

    /* Navigation rail */
    --rc-nav-width: 248px;
    --rc-nav-bg: #171f28;
    --rc-nav-bg-top: #1d2732;
    --rc-nav-fg: #e6ecf2;
    --rc-nav-fg-muted: #9aa7b4;

    /* Spacing, on a 4px rhythm */
    --rc-1: 4px;
    --rc-2: 8px;
    --rc-3: 12px;
    --rc-4: 16px;
    --rc-5: 20px;
    --rc-6: 24px;
    --rc-8: 32px;
    --rc-gap: var(--rc-4);

    /* Radii, aligned to RadiantUI's --border-radius-material so cards and controls agree */
    --rc-radius-sm: 8px;
    --rc-radius: 12px;
    --rc-radius-pill: 999px;

    /* Elevation */
    --rc-e1: 0 1px 2px rgba(16, 24, 40, 0.05);
    --rc-e2: 0 2px 6px -1px rgba(16, 24, 40, 0.09), 0 1px 2px rgba(16, 24, 40, 0.05);
    --rc-e3: 0 14px 28px -12px rgba(16, 24, 40, 0.20), 0 2px 6px rgba(16, 24, 40, 0.05);

    /* Type scale */
    --rc-text-xs: 11px;
    --rc-text-sm: 12px;
    --rc-text-label: 13px;
    --rc-text-body: 16px;
    --rc-text-lg: 18px;
    --rc-text-h2: 17px;
    --rc-text-h1: 24px;

    /*
     * Motion. One rhythm for the whole console: exits run at the fast step, which is the 60-70% of the enter
     * duration that keeps a dismissal feeling immediate rather than reluctant.
     */
    --rc-dur-fast: 120ms;
    --rc-dur: 200ms;
    --rc-dur-slow: 280ms;
    --rc-ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
    --rc-ease-in: cubic-bezier(0.4, 0, 1, 1);
}

/* ------------------------------------------------------------------------------------------------
 * 3. Base
 */
html {
    box-sizing: border-box;
}

html,
body {
    height: 100%;
    background: var(--rc-shell-bg);
    color: var(--rc-ink);
    font-size: var(--rc-text-body);
    line-height: 1.5;
    -webkit-text-size-adjust: 100%;
}

/*
 * Tabular figures wherever a number can change under the reader: without them a count ticking from 999 to 1.000
 * shifts every column beside it.
 */
.rc-num,
.rc-stat-value,
.rc-badge,
.rc-pager-range {
    font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------------------------------------------
 * 4. Focus
 *
 * One visible ring, on the keyboard only. RadiantUI's reset zeroes border-width globally, so the outline is the
 * only indicator left standing - never remove it.
 */
:where(a, button, [role="button"], input, select, textarea, summary, [tabindex]):focus-visible {
    outline: 2px solid var(--rc-accent);
    outline-offset: 2px;
    border-radius: var(--rc-radius-sm);
}

/*
 * Clipped rather than parked off-screen at a negative top. Negative positioning has to reason about which ancestor
 * is the containing block and how far the page is scrolled; clipping does not, and the focused state uses position
 * fixed so it lands relative to the viewport whatever it is nested in.
 *
 * No transition on the geometry either: this element goes from unreachable to reachable, and the reader who needs it
 * is mid-keystroke.
 */
.rc-skip {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    padding: 0;
}

.rc-skip:focus {
    position: fixed;
    top: var(--rc-3);
    left: var(--rc-3);
    z-index: 1000;
    width: auto;
    height: auto;
    clip-path: none;
    overflow: visible;
    padding: var(--rc-2) var(--rc-4);
    background: var(--rc-surface);
    color: var(--rc-accent-ink);
    border: 1px solid var(--rc-border);
    border-radius: var(--rc-radius-sm);
    box-shadow: var(--rc-e2);
}

/* ------------------------------------------------------------------------------------------------
 * 5. Motion vocabulary
 *
 * Enter animations only, on transform and opacity, so nothing here can reflow the page or move a hit target under
 * a finger that is already travelling towards it.
 */
@keyframes rc-rise {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: none; }
}

@keyframes rc-fade {
    from { opacity: 0; }
    to   { opacity: 1; }
}

@keyframes rc-pop {
    0%   { opacity: 0; transform: scale(0.9); }
    60%  { transform: scale(1.02); }
    100% { opacity: 1; transform: none; }
}

@keyframes rc-rail {
    from { transform: scaleY(0); opacity: 0; }
    to   { transform: none; opacity: 1; }
}

@keyframes rc-shimmer {
    from { background-position: 180% 0; }
    to   { background-position: -80% 0; }
}

.rc-rise {
    animation: rc-rise var(--rc-dur-slow) var(--rc-ease-out) both;
}

/*
 * Staggered entrance for lists. --i is set inline per row and clamped by the caller, because a 200-row stagger is
 * a progress bar nobody asked for.
 */
.rc-stagger > * {
    animation: rc-rise var(--rc-dur) var(--rc-ease-out) both;
    animation-delay: calc(var(--i, 0) * 30ms);
}

/*
 * The same stagger without the rise, for lists inside a scroll container.
 *
 * Measured, not guessed: an element carrying an animation whose keyframes translate it 6px downwards contributes
 * those 6px to its container's scrollable area for as long as the animation stays attached - so a list that fits its
 * box exactly still grew a scrollbar, and the box jittered by 6px. Fading has no geometry, so it cannot do that.
 */
.rc-stagger-fade > * {
    animation: rc-fade var(--rc-dur) var(--rc-ease-out) both;
    animation-delay: calc(var(--i, 0) * 30ms);
}

/*
 * The whole motion layer is opt-out in one place. Everything above animates transform, opacity or a paint
 * property, so switching it off leaves the final state already correct - no layout depends on an animation
 * having run.
 */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 1ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 1ms !important;
        scroll-behavior: auto !important;
    }
}

/* ------------------------------------------------------------------------------------------------
 * 6. Icons
 */
.rc-icon {
    flex: none;
    display: block;
}

/* An icon set beside text is centred on the text, not on the line box. */
.rc-icon-inline {
    display: inline-block;
    vertical-align: -0.18em;
}

/* ------------------------------------------------------------------------------------------------
 * 7. Shell
 */
.rc-shell {
    display: grid;
    grid-template-columns: var(--rc-nav-width) minmax(0, 1fr);
    min-height: 100vh;
    min-height: 100dvh;
}

.rc-nav {
    display: flex;
    flex-direction: column;
    background: linear-gradient(180deg, var(--rc-nav-bg-top) 0%, var(--rc-nav-bg) 220px);
    color: var(--rc-nav-fg);
    padding: var(--rc-5) 0 var(--rc-4);
    position: sticky;
    top: 0;
    height: 100vh;
    height: 100dvh;
    overflow-y: auto;
}

.rc-brand {
    display: flex;
    align-items: center;
    gap: var(--rc-3);
    padding: 0 var(--rc-5) var(--rc-5);
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.rc-brand-mark {
    display: grid;
    place-items: center;
    width: 38px;
    height: 38px;
    flex: none;
    border-radius: var(--rc-radius-sm);
    background: linear-gradient(145deg, var(--rc-accent), var(--rc-accent-deep));
    color: #ffffff;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
}

.rc-brand-name {
    display: block;
    font-size: var(--rc-text-lg);
    font-weight: 600;
    letter-spacing: -0.01em;
    line-height: 1.2;
}

.rc-brand-sub {
    display: block;
    font-size: var(--rc-text-sm);
    color: var(--rc-nav-fg-muted);
    margin-top: 1px;
}

.rc-nav-links {
    list-style: none;
    margin: var(--rc-4) 0 0;
    padding: 0 var(--rc-3);
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.rc-nav-links a {
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--rc-3);
    min-height: 44px;
    padding: var(--rc-2) var(--rc-3);
    border-radius: var(--rc-radius-sm);
    color: var(--rc-nav-fg);
    text-decoration: none;
    font-size: 15px;
    font-weight: 500;
    transition: background var(--rc-dur) var(--rc-ease-out), color var(--rc-dur) var(--rc-ease-out);
}

/*
 * The glyph sits in its own tile rather than floating loose against the rail. Three items in a sidebar are easy to
 * mistake for plain text links; a tile reads as an icon at a glance and gives the active state something to fill.
 */
.rc-nav-icon {
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    flex: none;
    border-radius: var(--rc-radius-sm);
    background: rgba(255, 255, 255, 0.06);
    color: var(--rc-nav-fg-muted);
    transition: background var(--rc-dur) var(--rc-ease-out), color var(--rc-dur) var(--rc-ease-out),
                transform var(--rc-dur) var(--rc-ease-out);
}

.rc-nav-links a:hover {
    background: rgba(255, 255, 255, 0.07);
}

.rc-nav-links a:hover .rc-nav-icon {
    background: rgba(255, 255, 255, 0.12);
    color: var(--rc-nav-fg);
    transform: translateY(-1px);
}

.rc-nav-links a.active {
    background: rgba(5, 130, 202, 0.18);
    color: #ffffff;
    font-weight: 600;
}

/* Filled, not merely tinted: the active section should be findable without reading anything. */
.rc-nav-links a.active .rc-nav-icon {
    background: linear-gradient(145deg, var(--rc-accent), var(--rc-accent-deep));
    color: #ffffff;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.28);
}

/*
 * The active rail grows out of the item rather than appearing whole. 3px wide and scaled on Y, so it animates on
 * transform and cannot nudge the label beside it.
 */
.rc-nav-links a.active::before {
    content: "";
    position: absolute;
    left: calc(-1 * var(--rc-3) + 1px);
    top: 50%;
    width: 3px;
    height: 22px;
    margin-top: -11px;
    border-radius: 0 3px 3px 0;
    background: var(--rc-accent);
    animation: rc-rail var(--rc-dur) var(--rc-ease-out) both;
}

/*
 * Stacked rather than side by side. With the sign-out control carrying a label there is no room for both on one
 * 248px line, and squeezing them would either truncate the user name or shrink the target.
 */
.rc-nav-footer {
    margin: var(--rc-4) var(--rc-3) 0;
    padding: var(--rc-3) 0 0;
    border-top: 1px solid rgba(255, 255, 255, 0.08);
    display: flex;
    flex-direction: column;
    gap: var(--rc-1);
}

.rc-user {
    display: flex;
    align-items: center;
    gap: var(--rc-2);
    min-width: 0;
    padding: 0 var(--rc-2);
    font-size: var(--rc-text-label);
    color: var(--rc-nav-fg-muted);
}

.rc-user span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 500;
}

/*
 * Signing out is the one destructive thing in the rail, so it is marked as such: a red glyph, its own label rather
 * than icon-only, and a red wash on hover. The label matters - an unlabelled icon in a corner is the control people
 * click by accident and the one they cannot find on purpose.
 *
 * --red is RadiantUI's, at 4.7:1 against the rail, so the glyph clears the 3:1 floor for non-text with room to spare.
 * The colour is not the only signal: the arrow-out-of-a-door glyph and the word "Esci" both carry it.
 */
.rc-exit {
    display: flex;
    align-items: center;
    gap: var(--rc-2);
    min-height: 40px;
    padding: 0 var(--rc-2) 0 0;
    border: none;
    border-radius: var(--rc-radius-sm);
    background: none;
    color: var(--rc-nav-fg-muted);
    font-size: var(--rc-text-label);
    font-weight: 600;
    cursor: pointer;
    transition: background var(--rc-dur) var(--rc-ease-out), color var(--rc-dur) var(--rc-ease-out),
                transform var(--rc-dur-fast) var(--rc-ease-out);
}

.rc-exit-icon {
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    flex: none;
    border-radius: var(--rc-radius-sm);
    background: rgba(255, 81, 84, 0.14);
    color: var(--red, #ff5154);
    transition: background var(--rc-dur) var(--rc-ease-out), transform var(--rc-dur) var(--rc-ease-out);
}

.rc-exit:hover {
    background: rgba(255, 81, 84, 0.14);
    color: #ffb3b4;
}

.rc-exit:hover .rc-exit-icon {
    background: rgba(255, 81, 84, 0.26);
    transform: translateX(1px);
}

.rc-exit:active {
    transform: scale(0.97);
}

.rc-main {
    padding: var(--rc-6) var(--rc-8);
    min-width: 0;
}

/* ------------------------------------------------------------------------------------------------
 * 8. Page furniture
 */
.rc-page-head {
    display: flex;
    align-items: flex-start;
    gap: var(--rc-4);
    margin-bottom: var(--rc-5);
    animation: rc-fade var(--rc-dur) var(--rc-ease-out) both;
}

.rc-page-head-icon {
    display: grid;
    place-items: center;
    width: 42px;
    height: 42px;
    flex: none;
    border-radius: var(--rc-radius-sm);
    background: var(--rc-accent-wash);
    color: var(--rc-accent-ink);
}

.rc-page-head-text {
    min-width: 0;
}

.rc-main h1 {
    margin: 0;
    font-size: var(--rc-text-h1);
    font-weight: 650;
    letter-spacing: -0.015em;
    line-height: 1.25;
}

.rc-subtitle {
    color: var(--rc-ink-muted);
    margin: 2px 0 0;
    font-size: var(--rc-text-label);
}

/*
 * Qualified with .rc-main because the generic content-link rule further down is .rc-main a, which outweighs a bare
 * .rc-back and would repaint this quiet grey link in accent blue - where it would compete with the heading beside it.
 */
.rc-main a.rc-back {
    display: inline-flex;
    align-items: center;
    gap: var(--rc-1);
    min-height: 32px;
    margin-bottom: var(--rc-2);
    color: var(--rc-ink-muted);
    font-size: var(--rc-text-label);
    font-weight: 500;
    text-decoration: none;
    transition: color var(--rc-dur) var(--rc-ease-out);
}

.rc-main a.rc-back:hover {
    color: var(--rc-accent-ink);
}

.rc-back .rc-icon {
    transition: transform var(--rc-dur) var(--rc-ease-out);
}

.rc-back:hover .rc-icon {
    transform: translateX(-2px);
}

.rc-card {
    background: var(--rc-surface);
    border: 1px solid var(--rc-border);
    border-radius: var(--rc-radius);
    padding: var(--rc-5);
    margin-bottom: var(--rc-gap);
    box-shadow: var(--rc-e1);
    min-width: 0;
}

.rc-card > h2 {
    display: flex;
    align-items: center;
    gap: var(--rc-2);
    margin: 0 0 var(--rc-3);
    font-size: var(--rc-text-h2);
    font-weight: 600;
}

.rc-card > h2 .rc-icon {
    color: var(--rc-ink-muted);
}

.rc-card-tight {
    padding: var(--rc-3) var(--rc-4);
}

.rc-toolbar {
    display: flex;
    gap: var(--rc-3);
    align-items: center;
    flex-wrap: wrap;
}

.rc-grow {
    flex: 1;
    min-width: 240px;
}

/* ------------------------------------------------------------------------------------------------
 * 9. Statistics
 */
.rc-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
    gap: var(--rc-3);
    margin-bottom: var(--rc-gap);
}

.rc-stat {
    display: flex;
    align-items: center;
    gap: var(--rc-3);
    padding: var(--rc-3) var(--rc-4);
    background: var(--rc-surface);
    border: 1px solid var(--rc-border);
    border-radius: var(--rc-radius);
    box-shadow: var(--rc-e1);
    transition: transform var(--rc-dur) var(--rc-ease-out), box-shadow var(--rc-dur) var(--rc-ease-out);
}

.rc-stat:hover {
    transform: translateY(-2px);
    box-shadow: var(--rc-e2);
}

.rc-stat-icon {
    display: grid;
    place-items: center;
    width: 38px;
    height: 38px;
    flex: none;
    border-radius: var(--rc-radius-sm);
    background: var(--rc-accent-wash);
    color: var(--rc-accent-ink);
}

.rc-stat-icon.machines  { background: #eaf1fe; color: #1f4f9e; }
.rc-stat-icon.drivers   { background: #f1ecfd; color: #57329b; }
.rc-stat-icon.variables { background: #e6f6ee; color: #14663a; }

.rc-stat-label {
    display: block;
    font-size: var(--rc-text-xs);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    font-weight: 600;
    color: var(--rc-ink-muted);
}

.rc-stat-value {
    display: block;
    font-size: 22px;
    font-weight: 650;
    line-height: 1.2;
    letter-spacing: -0.02em;
}

/* Inside a card the statistics are a plain row, not nested cards. */
.rc-card .rc-stats {
    grid-template-columns: repeat(auto-fit, minmax(110px, max-content));
    gap: var(--rc-6);
    margin-bottom: 0;
}

.rc-card .rc-stat {
    padding: 0;
    border: none;
    box-shadow: none;
    background: none;
}

.rc-card .rc-stat:hover {
    transform: none;
    box-shadow: none;
}

/* ------------------------------------------------------------------------------------------------
 * 10. Badges
 *
 * Every status badge carries a glyph as well as a colour. Colour on its own is invisible to a reader who cannot
 * distinguish it, and this console gets read on plant-floor screens with the contrast turned down.
 */
.rc-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 9px;
    border-radius: var(--rc-radius-pill);
    background: var(--rc-surface-sunken);
    border: 1px solid var(--rc-border);
    color: var(--rc-ink-muted);
    font-size: var(--rc-text-sm);
    font-weight: 600;
    white-space: nowrap;
    line-height: 1.6;
}

.rc-badge.ok {
    background: var(--rc-ok-wash);
    border-color: transparent;
    color: var(--rc-ok-ink);
}

.rc-badge.warn {
    background: var(--rc-warn-wash);
    border-color: transparent;
    color: var(--rc-warn-ink);
}

.rc-badge.danger {
    background: var(--rc-danger-wash);
    border-color: transparent;
    color: var(--rc-danger-ink);
}

.rc-badge.accent {
    background: var(--rc-accent-wash);
    border-color: transparent;
    color: var(--rc-accent-ink);
}

.rc-badge-count {
    min-width: 24px;
    justify-content: center;
    padding: 1px 7px;
}

/* ------------------------------------------------------------------------------------------------
 * 11. Selectable rows
 *
 * A real button, not a div with a click handler: keyboard reachable, announced as a control with its pressed
 * state, and 44px tall so it can be hit without aiming.
 */
.rc-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.rc-item {
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--rc-2);
    width: 100%;
    min-height: 44px;
    padding: var(--rc-2) var(--rc-3);
    border: none;
    border-radius: var(--rc-radius-sm);
    background: none;
    color: inherit;
    font-size: 15px;
    text-align: left;
    cursor: pointer;
    transition: background var(--rc-dur) var(--rc-ease-out), transform var(--rc-dur-fast) var(--rc-ease-out);
}

.rc-item:hover {
    background: var(--rc-surface-hover);
}

.rc-item:active {
    transform: scale(0.99);
}

.rc-item > .rc-icon:first-child {
    color: var(--rc-ink-muted);
    transition: color var(--rc-dur) var(--rc-ease-out);
}

.rc-item-name {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 500;
}

/*
 * Two-line variant, for the machine list.
 *
 * One line forced name, driver count and variable count to compete for the same row, so every badge shortened the
 * name it sat next to - and the name is the only thing anyone scans for. Splitting them puts the identifier on its
 * own line at full width and demotes the counts to a caption, which is what they are.
 */
.rc-item-stacked {
    align-items: center;
    min-height: 56px;
    padding: var(--rc-2) var(--rc-3);
}

.rc-item-body {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.rc-item-title {
    display: flex;
    align-items: center;
    gap: var(--rc-2);
    min-width: 0;
}

.rc-item-title > span:first-child {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 600;
}

.rc-item-meta {
    display: flex;
    align-items: center;
    gap: 5px;
    font-size: var(--rc-text-sm);
    font-weight: 400;
    color: var(--rc-ink-muted);
    font-variant-numeric: tabular-nums;
}

.rc-item[aria-pressed="true"] .rc-item-meta {
    color: var(--rc-accent-ink);
}

/* A machine the plant has switched off still belongs in the list, just not at the same weight as a live one. */
.rc-item-off .rc-item-title > span:first-child,
.rc-item-off .rc-item-meta {
    opacity: 0.62;
}

/*
 * The list scrolls inside the card instead of growing the page. A plant with ninety machines would otherwise push
 * the drivers and variables far below the fold, and the reader would be scrolling the whole document to change
 * a selection whose result is off-screen.
 */
.rc-list-scroll {
    max-height: min(58vh, 520px);
    overflow-y: auto;
    margin: 0 calc(-1 * var(--rc-2));
    padding: 0 var(--rc-2);
}

/* Client-side narrowing of a list already in memory, so it filters as you type without touching the database. */
.rc-filter {
    position: relative;
    margin-bottom: var(--rc-2);
}

.rc-filter .rc-icon {
    position: absolute;
    left: var(--rc-2);
    top: 50%;
    margin-top: -8px;
    color: var(--rc-ink-muted);
    pointer-events: none;
}

.rc-filter input {
    width: 100%;
    min-height: 40px;
    padding: 0 var(--rc-2) 0 34px;
    border: 1px solid var(--rc-border);
    border-radius: var(--rc-radius-sm);
    background: var(--rc-surface-sunken);
    color: var(--rc-ink);
    font-size: var(--rc-text-label);
    transition: border-color var(--rc-dur) var(--rc-ease-out), background var(--rc-dur) var(--rc-ease-out);
}

.rc-filter input:focus {
    background: var(--rc-surface);
    border-color: var(--rc-accent);
    outline: none;
    box-shadow: 0 0 0 3px rgba(5, 130, 202, 0.14);
}

.rc-filter input::placeholder {
    color: var(--rc-ink-muted);
}

.rc-item[aria-pressed="true"] {
    background: var(--rc-accent-wash);
    color: var(--rc-accent-ink);
    font-weight: 600;
}

.rc-item[aria-pressed="true"] > .rc-icon:first-child {
    color: var(--rc-accent);
}

.rc-item[aria-pressed="true"]::before {
    content: "";
    position: absolute;
    left: 0;
    top: 50%;
    width: 3px;
    height: 20px;
    margin-top: -10px;
    border-radius: 0 3px 3px 0;
    background: var(--rc-accent);
    animation: rc-rail var(--rc-dur) var(--rc-ease-out) both;
}

.rc-chevron {
    color: var(--rc-border-strong);
    transition: transform var(--rc-dur) var(--rc-ease-out), color var(--rc-dur) var(--rc-ease-out);
}

.rc-item:hover .rc-chevron {
    color: var(--rc-ink-muted);
    transform: translateX(2px);
}

/* ------------------------------------------------------------------------------------------------
 * 12. Empty, loading and message states
 */
.rc-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--rc-2);
    padding: var(--rc-8) var(--rc-4);
    color: var(--rc-ink-muted);
    text-align: center;
    animation: rc-fade var(--rc-dur-slow) var(--rc-ease-out) both;
}

.rc-empty-icon {
    display: grid;
    place-items: center;
    width: 52px;
    height: 52px;
    border-radius: var(--rc-radius-pill);
    background: var(--rc-surface-sunken);
    color: var(--rc-border-strong);
    margin-bottom: var(--rc-1);
}

.rc-empty strong {
    color: var(--rc-ink);
    font-weight: 600;
    font-size: 15px;
}

.rc-empty p {
    margin: 0;
    max-width: 48ch;
    font-size: var(--rc-text-label);
    line-height: 1.6;
}

.rc-empty-inline {
    padding: var(--rc-5) var(--rc-4);
}

/*
 * Skeletons rather than a spinner: the reader sees the shape of what is coming, and the layout does not jump when
 * it arrives because the placeholder already occupies its height.
 */
.rc-skeleton {
    background: linear-gradient(90deg, var(--rc-surface-sunken) 0%, #e9edf2 40%, var(--rc-surface-sunken) 80%);
    background-size: 220% 100%;
    border-radius: var(--rc-radius-sm);
    animation: rc-shimmer 1.3s linear infinite;
}

.rc-skeleton-row {
    height: 44px;
    margin-bottom: var(--rc-2);
}

.rc-skeleton-stat {
    height: 68px;
}

.rc-message {
    display: flex;
    align-items: flex-start;
    gap: var(--rc-2);
    padding: var(--rc-3) var(--rc-4);
    border-radius: var(--rc-radius-sm);
    font-size: var(--rc-text-label);
    line-height: 1.55;
    margin-bottom: var(--rc-gap);
    animation: rc-rise var(--rc-dur) var(--rc-ease-out) both;
}

.rc-message .rc-icon {
    margin-top: 1px;
}

.rc-message.warn {
    background: var(--rc-warn-wash);
    color: var(--rc-warn-ink);
    border: 1px solid rgba(161, 94, 1, 0.22);
}

.rc-message.danger {
    background: var(--rc-danger-wash);
    color: var(--rc-danger-ink);
    border: 1px solid rgba(139, 11, 11, 0.18);
}

.rc-message.info {
    background: var(--rc-accent-wash);
    color: var(--rc-accent-ink);
    border: 1px solid rgba(5, 130, 202, 0.20);
}

.rc-hint {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: var(--rc-3) 0 0;
    font-size: var(--rc-text-sm);
    color: var(--rc-ink-muted);
}

/* ------------------------------------------------------------------------------------------------
 * 13. Layout helpers
 */
.rc-split {
    display: grid;
    grid-template-columns: minmax(260px, 32%) minmax(0, 1fr);
    gap: var(--rc-gap);
    align-items: start;
}

.rc-stack {
    display: flex;
    flex-direction: column;
    gap: var(--rc-gap);
    min-width: 0;
}

.rc-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--rc-2) var(--rc-4);
    margin: var(--rc-2) 0 0;
    font-size: var(--rc-text-label);
    color: var(--rc-ink-muted);
}

.rc-meta > span {
    display: inline-flex;
    align-items: center;
    gap: 5px;
}

/* Wide tables carry their own horizontal scroll, so one never makes the page scroll sideways. */
.rc-scroll-x {
    overflow-x: auto;
    min-width: 0;
}

.rc-mono {
    font-size: 14px;
}

.rc-hash {
    font-size: var(--rc-text-sm);
    color: var(--rc-ink-muted);
}

.rc-truncate {
    display: block;
    max-width: 42ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ------------------------------------------------------------------------------------------------
 * 14. Pager
 */
.rc-pager {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--rc-3);
    margin-top: var(--rc-3);
    padding-top: var(--rc-3);
    border-top: 1px solid var(--rc-border);
    flex-wrap: wrap;
}

.rc-pager-range {
    font-size: var(--rc-text-label);
    color: var(--rc-ink-muted);
    margin-right: auto;
}

.rc-pagebutton {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 40px;
    padding: 0 var(--rc-3);
    border: 1px solid var(--rc-border-strong);
    border-radius: var(--rc-radius-sm);
    background: var(--rc-surface);
    color: var(--rc-ink);
    font-size: var(--rc-text-label);
    font-weight: 600;
    cursor: pointer;
    transition: background var(--rc-dur) var(--rc-ease-out), border-color var(--rc-dur) var(--rc-ease-out),
                transform var(--rc-dur-fast) var(--rc-ease-out);
}

.rc-pagebutton:hover:not(:disabled) {
    background: var(--rc-surface-hover);
    border-color: var(--rc-ink-muted);
}

.rc-pagebutton:active:not(:disabled) {
    transform: scale(0.97);
}

.rc-pagebutton:disabled {
    opacity: 0.45;
    cursor: default;
}

/* ------------------------------------------------------------------------------------------------
 * 15. Inline controls
 */

/*
 * In-page actions are buttons, not anchors. An anchor with href="#" looks the same and behaves differently: Blazor
 * intercepts anchor clicks for navigation, so the page navigates away before - or instead of - the handler running.
 */
.rc-inline-link {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    background: none;
    border: none;
    padding: 0;
    font: inherit;
    font-weight: 500;
    color: var(--rc-accent-ink);
    text-decoration: underline;
    text-underline-offset: 2px;
    cursor: pointer;
    text-align: left;
    transition: color var(--rc-dur) var(--rc-ease-out);
}

.rc-inline-link:hover {
    color: var(--rc-accent-deep);
}

/*
 * A disclosure control, not a link to somewhere else - so no underline, and the chevron does the talking. It rotates
 * rather than being swapped for a different glyph, which is what makes open and closed feel like the same control in
 * two states instead of two different controls.
 */
.rc-disclosure {
    text-decoration: none;
    gap: var(--rc-1);
}

.rc-disclosure:hover {
    text-decoration: underline;
    text-underline-offset: 2px;
}

.rc-disclosure-icon {
    transition: transform var(--rc-dur) var(--rc-ease-out);
}

.rc-disclosure[aria-expanded="false"]:hover .rc-disclosure-icon {
    transform: translateX(2px);
}

.rc-main a {
    color: var(--rc-accent-ink);
    text-decoration: none;
    font-weight: 500;
    border-bottom: 1px solid transparent;
    transition: border-color var(--rc-dur) var(--rc-ease-out);
}

.rc-main a:hover {
    border-bottom-color: currentColor;
}

.rc-main a.rc-back:hover {
    border-bottom-color: transparent;
}

/* A copy control that swaps its glyph for a tick. The swap is the confirmation, so no toast is needed. */
.rc-copy {
    position: relative;
    display: inline-grid;
    place-items: center;
    width: 28px;
    height: 28px;
    border: none;
    border-radius: 6px;
    background: none;
    color: var(--rc-ink-muted);
    cursor: pointer;
    transition: background var(--rc-dur) var(--rc-ease-out), color var(--rc-dur) var(--rc-ease-out);
}

/*
 * The visible control is 28px because it sits inline in a line of metadata, where a 44px chip would push the line
 * apart. The hit area is 44px regardless, extended past the paint rather than shrunk to it - which is the whole
 * point of the minimum: it is about what the finger can reach, not what the eye can see.
 */
.rc-copy::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 44px;
    height: 44px;
    transform: translate(-50%, -50%);
}

.rc-copy:hover {
    background: var(--rc-surface-sunken);
    color: var(--rc-ink);
}

.rc-copy.done {
    color: var(--rc-ok-ink);
}

.rc-copy.done .rc-icon {
    animation: rc-pop var(--rc-dur) var(--rc-ease-out) both;
}

.rc-field {
    margin: var(--rc-4) 0;
}

.rc-field > label,
.rc-label {
    display: block;
    font-size: var(--rc-text-label);
    font-weight: 600;
    color: var(--rc-ink);
    margin-bottom: 6px;
}

.rc-field-hint {
    display: block;
    font-size: var(--rc-text-sm);
    color: var(--rc-ink-muted);
    margin-top: 5px;
}

/* Native checkbox and select: a 44px row, a visible label, and no reliance on browser default sizing. */
.rc-check {
    display: inline-flex;
    align-items: center;
    gap: var(--rc-2);
    min-height: 44px;
    padding: 0 var(--rc-2);
    border-radius: var(--rc-radius-sm);
    font-size: var(--rc-text-label);
    cursor: pointer;
    transition: background var(--rc-dur) var(--rc-ease-out);
}

.rc-check:hover {
    background: var(--rc-surface-hover);
}

.rc-check input {
    width: 18px;
    height: 18px;
    accent-color: var(--rc-accent);
    cursor: pointer;
}

.rc-select {
    min-height: 48px;
    padding: 0 var(--rc-3);
    border: 1px solid var(--rc-border-strong);
    border-radius: var(--rc-radius);
    background: var(--rc-surface);
    color: var(--rc-ink);
    font-size: var(--rc-text-body);
    cursor: pointer;
}

.rc-secret {
    font-size: 14px;
    background: var(--rc-nav-bg);
    color: #a8f0c4;
    padding: var(--rc-3);
    border-radius: var(--rc-radius-sm);
    word-break: break-all;
}

/*
 * The login field and button.
 *
 * The one place the console styles its own controls, and not by preference: the login form is a native post, because
 * a cookie can only be written before the response starts. RadTextbox and RadButton render no name attribute, so a
 * native post carries nothing from them. These two follow RadiantUI's own proportions - 48px tall, 12px radius,
 * 16px text, the same 0.96 press - so the page still reads as part of the product.
 *
 * They also replace class names that matched nothing at all: the markup here previously said "rad-textbox" and
 * "rad-button rad-button-primary", while RadiantUI styles ".rad-input" and ".rad-btn". Both controls were rendering
 * as browser defaults.
 */
.rc-input {
    width: 100%;
    min-height: 48px;
    padding: 0 var(--rc-3);
    border: 1px solid var(--rc-border-strong);
    border-radius: var(--rc-radius);
    background: var(--rc-surface);
    color: var(--rc-ink);
    font-size: var(--rc-text-body);
    transition: border-color var(--rc-dur) var(--rc-ease-out), box-shadow var(--rc-dur) var(--rc-ease-out);
}

.rc-input:hover {
    border-color: var(--rc-ink-muted);
}

.rc-input:focus {
    border-color: var(--rc-accent);
    box-shadow: 0 0 0 3px rgba(5, 130, 202, 0.16);
    outline: none;
}

.rc-input:focus-visible {
    outline: none;
}

.rc-submit {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--rc-2);
    width: 100%;
    min-height: 48px;
    border: none;
    border-radius: var(--rc-radius);
    background: linear-gradient(180deg, var(--rc-accent), var(--rc-accent-deep));
    color: #ffffff;
    font-size: var(--rc-text-body);
    font-weight: 600;
    cursor: pointer;
    box-shadow: var(--rc-e2);
    transition: filter var(--rc-dur) var(--rc-ease-out), transform var(--rc-dur-fast) var(--rc-ease-out),
                box-shadow var(--rc-dur) var(--rc-ease-out);
}

.rc-submit:hover {
    filter: brightness(1.08);
    box-shadow: var(--rc-e3);
}

.rc-submit:active {
    transform: scale(0.96);
}

/* ------------------------------------------------------------------------------------------------
 * 16. Login
 */
.rc-login {
    display: grid;
    place-items: center;
    min-height: 100vh;
    min-height: 100dvh;
    padding: var(--rc-4);
    background:
        radial-gradient(900px 500px at 15% -10%, rgba(5, 130, 202, 0.10), transparent 60%),
        radial-gradient(700px 400px at 100% 100%, rgba(5, 130, 202, 0.07), transparent 60%),
        var(--rc-shell-bg);
}

.rc-login-card {
    width: 100%;
    max-width: 380px;
    background: var(--rc-surface);
    border: 1px solid var(--rc-border);
    border-radius: var(--rc-radius);
    padding: var(--rc-8) var(--rc-6) var(--rc-6);
    box-shadow: var(--rc-e3);
    animation: rc-rise var(--rc-dur-slow) var(--rc-ease-out) both;
}

.rc-login-brand {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--rc-2);
    margin-bottom: var(--rc-5);
}

.rc-login-brand .rc-brand-mark {
    width: 48px;
    height: 48px;
    border-radius: var(--rc-radius);
}

.rc-login-card h1 {
    margin: 0;
    font-size: 21px;
    font-weight: 650;
    letter-spacing: -0.015em;
}

.rc-login-card .rc-subtitle {
    text-align: center;
    margin: 0;
}

/* ------------------------------------------------------------------------------------------------
 * 17. RADIANTUI OVERRIDE - row density
 *
 * RadiantUI sets table rows to 64px, sized for touch on a phone. A driver page lists 50 variables, which at 64px is
 * 3.200px of scrolling to read one driver, and the reader loses the column headings on the way down. 44px is the
 * touch-target minimum, so the row stays hittable while a page of variables fits on one screen.
 *
 * Scoped to .rc-dense and applied only to the long inventory tables. Everything else keeps RadiantUI's sizing, and
 * nothing here touches colour, border or type - only the height the console has a legitimate opinion about.
 */
.rc-dense .rad-table-table tbody tr:not(.rad-table-group-header):not(.rad-table-detail-row) td:not(.group-spacer-col) {
    height: 44px;
    padding-top: 6px;
    padding-bottom: 6px;
}

.rc-dense .rad-table-table thead th {
    padding-top: 10px;
    padding-bottom: 10px;
}

/*
 * RADIANTUI OVERRIDE - row affordance
 *
 * The fleet and connector tables open on double click. Without a hover state the row gives no sign it is clickable,
 * which is the whole reason the gesture goes unnoticed.
 */
.rc-rows .rad-table-table tbody tr:not(.rad-table-group-header) {
    cursor: pointer;
    transition: background var(--rc-dur-fast) var(--rc-ease-out);
}

.rc-rows .rad-table-table tbody tr:not(.rad-table-group-header):hover td {
    background: var(--rc-surface-hover);
}

/* ------------------------------------------------------------------------------------------------
 * 18. Accounts
 *
 * The sign-in page's password panel, and the row controls on the users page.
 */

/*
 * Success, alongside warn/danger/info above. It exists for exactly one message - "password updated" - and that
 * message needs to read as an outcome rather than as another thing that went wrong.
 */
.rc-message.ok {
    background: var(--rc-ok-wash);
    color: var(--rc-ok-ink);
    border: 1px solid rgba(11, 110, 60, 0.18);
}

/*
 * A native <details>. Changing a password is a rare errand that happens to start on this screen, so it is
 * present but folded: no second page to navigate to, and nothing competing with the field the reader came for.
 * Native rather than scripted because the panel has to work on a statically rendered page, where there is no
 * circuit to handle a click.
 */
.rc-login-more {
    margin-top: var(--rc-5);
    border-top: 1px solid var(--rc-border);
    padding-top: var(--rc-4);
}

.rc-login-more > summary {
    display: flex;
    align-items: center;
    gap: var(--rc-2);
    min-height: 40px;
    font-size: var(--rc-text-label);
    font-weight: 600;
    color: var(--rc-accent-ink);
    cursor: pointer;
    list-style: none;
}

/* Safari renders its own triangle through a pseudo-element that list-style does not reach. */
.rc-login-more > summary::-webkit-details-marker {
    display: none;
}

.rc-login-more > summary:hover {
    color: var(--rc-accent-deep);
}

.rc-login-more[open] > summary {
    margin-bottom: var(--rc-2);
}

/*
 * The second button on a screen that already has a primary one. Same size and shape, quieter surface: two
 * gradient buttons stacked would ask the reader to decide which one the page is actually for.
 */
.rc-submit.secondary {
    background: var(--rc-surface);
    color: var(--rc-accent-ink);
    border: 1px solid var(--rc-border-strong);
    box-shadow: none;
}

.rc-submit.secondary:hover {
    background: var(--rc-surface-hover);
    box-shadow: none;
}

/*
 * Row controls on the users page. They wrap rather than overflow, because the destructive one must never be
 * the one pushed out of sight behind a horizontal scroll.
 */
.rc-row-actions {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--rc-3);
}

.rc-inline-link.danger {
    color: var(--rc-danger-ink);
}

.rc-inline-link.danger:hover {
    color: var(--rc-danger-ink);
    filter: brightness(0.85);
}

/* A field inside a table row: the full-height input would double the row it sits in. */
.rc-input-inline {
    width: auto;
    min-width: 180px;
    min-height: 34px;
    font-size: var(--rc-text-label);
}

/* ------------------------------------------------------------------------------------------------
 * 19. Responsive
 *
 * The rail becomes a horizontal bar before the content gets squeezed, rather than after.
 */
@media (max-width: 1100px) {
    .rc-split {
        grid-template-columns: minmax(0, 1fr);
    }
}

@media (max-width: 920px) {
    .rc-shell {
        grid-template-columns: minmax(0, 1fr);
    }

    .rc-nav {
        position: static;
        height: auto;
        padding: var(--rc-3) 0;
        background: var(--rc-nav-bg);
    }

    .rc-brand {
        padding: 0 var(--rc-4) var(--rc-3);
    }

    .rc-nav-links {
        flex-direction: row;
        overflow-x: auto;
        margin-top: var(--rc-3);
        padding: 0 var(--rc-4) var(--rc-1);
        gap: var(--rc-1);
    }

    .rc-nav-links a {
        white-space: nowrap;
    }

    /* Side by side, the rail belongs under the item: a left rail on a horizontal bar points at nothing. */
    .rc-nav-links a.active::before {
        left: var(--rc-3);
        right: var(--rc-3);
        top: auto;
        bottom: 2px;
        width: auto;
        height: 2px;
        margin-top: 0;
        border-radius: 2px;
        animation-name: rc-fade;
    }

    .rc-nav-footer {
        margin: var(--rc-3) var(--rc-4) 0;
    }

    .rc-main {
        padding: var(--rc-4);
    }
}

@media (max-width: 560px) {
    :root {
        --rc-text-h1: 20px;
    }

    .rc-main {
        padding: var(--rc-3);
    }

    .rc-card {
        padding: var(--rc-4);
    }

    .rc-page-head-icon {
        display: none;
    }

    .rc-pager {
        justify-content: space-between;
    }

    .rc-pager-range {
        order: -1;
        flex-basis: 100%;
        margin: 0 0 var(--rc-2);
    }
}
