/* =====================================================================================================
   RebarOpt Web — shared stylesheet
   The ONLY place colours, type sizes, spacing and component looks are defined. Pages use the classes below
   and Bootstrap 5.3 classes; they never set colours or sizes of their own. Rules: docs/10_UI_STYLE_GUIDE.md
   Load order in _Layout.cshtml:  bootstrap.min.css  →  bootstrap-icons.min.css  →  tabulator.min.css  →  rebaropt.css
                                  →  site.css
   Values are carried over from the desktop theme (RebarOpt.Desktop/Themes/*.xaml).
   Since Phase 4 this copy (src/RebarOpt.Web/wwwroot/css/rebaropt.css) is the source of truth; design/rebaropt.css
   stays as the original specification. Every component here has a specimen on /admin/style-reference.
   ===================================================================================================== */

/* Phone-first tag scanning: camera stays within its card, with large reachable action buttons. */
.ro-scan-camera { width: 100%; max-height: 20rem; object-fit: contain; background: var(--ro-header-band); border-radius: var(--ro-radius); }
.ro-scan-actions { display: grid; grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); gap: var(--ro-space-2); }
.ro-scan-actions .btn { min-height: 3rem; }

/* Coordinate maps, calibrated plans and structure layout use the same responsive surfaces. */
.ro-map-frame { display: block; width: 100%; max-height: 38rem; aspect-ratio: 5 / 3; overflow: hidden; background: var(--ro-header-band); border: 1px solid var(--ro-border); border-radius: var(--ro-radius); }
.ro-map-grid { stroke: var(--ro-border); stroke-width: 1; }
.ro-map-place { fill: var(--ro-offcut); stroke: var(--ro-text); stroke-width: 1; }
.ro-map-marker { fill: var(--ro-primary); stroke: var(--ro-surface); stroke-width: 2; }
.ro-map-label { fill: var(--ro-text); font-size: var(--ro-fs-md); paint-order: stroke; stroke: var(--ro-surface); stroke-width: 3; }
.ro-map-image { display: block; width: 100%; height: 100%; object-fit: contain; }
.ro-site-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); gap: var(--ro-space-3); }
.ro-site-tile { display: grid; gap: var(--ro-space-1); border: 1px solid var(--ro-border); border-radius: var(--ro-radius); padding: var(--ro-space-3); background: var(--ro-surface); color: var(--ro-text); }
.ro-site-tile:hover { background: var(--ro-row-hover); }
.ro-site-tile.is-selected { border-color: var(--ro-primary); background: var(--ro-primary-light); }

/* Specialist projections/drawings are bounded, keyboard-focusable assets; pan/zoom changes geometry only. */
.ro-model-viewport { display: grid; place-items: center; width: 100%; aspect-ratio: 5 / 3; max-height: 38rem; overflow: hidden; touch-action: none; background: var(--ro-header-band); border: 1px solid var(--ro-border); border-radius: var(--ro-radius); }
.ro-model-viewport img, .ro-model-viewport > svg { display: block; max-width: 100%; width: 100%; height: 100%; object-fit: contain; transform-origin: center; user-select: none; }
.ro-model-viewport:focus-visible { outline: 2px solid var(--ro-primary); outline-offset: var(--ro-space-1); }

/* The coach is docked beside wide pages and stacked below the complete page at tablet width. */
.ro-guide-workspace { display: grid; grid-template-columns: minmax(0, 1fr) minmax(16rem, 20rem); align-items: start; gap: var(--ro-space-4); }
.ro-guide-page { min-width: 0; }
.ro-guide-panel { position: sticky; top: var(--ro-space-3); min-width: 0; }
.ro-guide-panel p, .ro-guide-route li { overflow-wrap: anywhere; }
.ro-guide-route { padding-left: var(--ro-space-5); }
.ro-guide-route li { margin-top: var(--ro-space-2); }
@media (max-width: 1199.98px) { .ro-guide-workspace { grid-template-columns: minmax(0, 1fr); } .ro-guide-panel { position: static; } }

/* Driver.js structural selectors, restyled entirely from shared tokens. Vendor CSS is not loaded. */
.driver-active .driver-overlay, .driver-active * { pointer-events: none; }
.driver-active .driver-active-element, .driver-active .driver-active-element *, .driver-popover, .driver-popover * { pointer-events: auto; }
.driver-popover { box-sizing: border-box; position: fixed; top: 0; right: 0; min-width: min(16rem, calc(100vw - var(--ro-space-6))); max-width: min(22rem, calc(100vw - var(--ro-space-6))); margin: 0; padding: var(--ro-space-4); border-radius: var(--ro-radius-lg); background: var(--ro-surface); color: var(--ro-text); box-shadow: var(--ro-shadow-pop); z-index: 1000000000; font-family: var(--ro-font); font-size: var(--ro-fs-base); }
.driver-popover-title { display: block; position: relative; margin: 0 var(--ro-space-5) var(--ro-space-2) 0; font-size: var(--ro-fs-md); font-weight: var(--ro-fw-semibold); line-height: 1.5; }
.driver-popover-close-btn { position: absolute; top: var(--ro-space-1); right: var(--ro-space-1); width: var(--ro-control-h); height: var(--ro-control-h); border: 0; background: transparent; color: var(--ro-text-secondary); font-size: var(--ro-fs-lg); cursor: pointer; }
.driver-popover-close-btn:focus-visible, .driver-popover-footer button:focus-visible { outline: 2px solid var(--ro-primary); outline-offset: var(--ro-space-1); }
.driver-popover-description { margin-bottom: 0; line-height: 1.5; }
.driver-popover-description p:last-child { margin-bottom: 0; }
.driver-popover-footer { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--ro-space-2); margin-top: var(--ro-space-4); }
.driver-popover-progress-text { color: var(--ro-muted); font-size: var(--ro-fs-sm); }
.driver-popover-navigation-btns { display: flex; flex-grow: 1; justify-content: flex-end; gap: var(--ro-space-1); }
.driver-popover-footer .driver-popover-btn-disabled { opacity: 0.5; pointer-events: none; }
.driver-no-interaction, .driver-no-interaction * { pointer-events: none !important; }
.driver-popover-arrow { position: absolute; border: var(--ro-space-1) solid var(--ro-surface); }
.driver-popover-arrow-side-over, .driver-popover-arrow-side-center, .driver-popover-arrow-none { display: none; }
.driver-popover-arrow-side-left { left: 100%; border-right-color: transparent; border-bottom-color: transparent; border-top-color: transparent; }
.driver-popover-arrow-side-right { right: 100%; border-left-color: transparent; border-bottom-color: transparent; border-top-color: transparent; }
.driver-popover-arrow-side-top { top: 100%; border-right-color: transparent; border-bottom-color: transparent; border-left-color: transparent; }
.driver-popover-arrow-side-bottom { bottom: 100%; border-left-color: transparent; border-top-color: transparent; border-right-color: transparent; }
.driver-popover-arrow-side-left.driver-popover-arrow-align-start, .driver-popover-arrow-side-right.driver-popover-arrow-align-start { top: var(--ro-space-4); }
.driver-popover-arrow-side-top.driver-popover-arrow-align-start, .driver-popover-arrow-side-bottom.driver-popover-arrow-align-start { left: var(--ro-space-4); }
.driver-popover-arrow-align-end.driver-popover-arrow-side-left, .driver-popover-arrow-align-end.driver-popover-arrow-side-right { bottom: var(--ro-space-4); }
.driver-popover-arrow-side-top.driver-popover-arrow-align-end, .driver-popover-arrow-side-bottom.driver-popover-arrow-align-end { right: var(--ro-space-4); }
.driver-popover-arrow-side-left.driver-popover-arrow-align-center, .driver-popover-arrow-side-right.driver-popover-arrow-align-center { top: 50%; margin-top: calc(-1 * var(--ro-space-1)); }
.driver-popover-arrow-side-top.driver-popover-arrow-align-center, .driver-popover-arrow-side-bottom.driver-popover-arrow-align-center { left: 50%; margin-left: calc(-1 * var(--ro-space-1)); }
.ro-guide-popover-specimen { position: relative; z-index: auto; }

/* -----------------------------------------------------------------------------------------------------
   1. Design tokens
   ----------------------------------------------------------------------------------------------------- */
:root {
  /* Brand and shell (desktop Colors.xaml; UI refresh D54: deeper navigation, light top bar) */
  --ro-primary: #1F6FEB;
  --ro-primary-dark: #155BC7;
  --ro-primary-light: #E8F0FE;
  --ro-nav: #16203A;
  --ro-nav-hover: #222D48;
  --ro-nav-active: #1E3A6E;
  --ro-nav-text: #C5CEDD;
  --ro-nav-dim: #8391A8;

  /* Surfaces and text */
  --ro-bg: #F3F5F9;
  --ro-surface: #FFFFFF;
  --ro-header-band: #F1F4F8;
  --ro-table-head: #F7F9FC;
  --ro-border: #E1E6EE;
  --ro-border-strong: #C9D1DD;
  --ro-text: #1A2233;
  --ro-text-secondary: #475467;
  --ro-muted: #667085;
  --ro-row-alt: #FAFBFD;
  --ro-row-hover: #F1F6FE;
  --ro-scrollbar: #C5CDD9;
  --ro-scrollbar-hover: #98A3B5;
  --ro-focus-ring: rgba(31, 111, 235, 0.22);

  /* Semantic tones: base (icons, bars, borders), light (chip/alert backgrounds), ink (text on light) */
  --ro-success: #2E8B57;  --ro-success-light: #E3F3EA;  --ro-success-ink: #1F6B42;
  --ro-warning: #D98E04;  --ro-warning-light: #FBF1DA;  --ro-warning-ink: #8A5A00;
  --ro-danger:  #C0392B;  --ro-danger-light:  #F9E0DD;  --ro-danger-ink:  #A12E22;
  --ro-info:    #1F6FEB;  --ro-info-light:    #E3ECFB;  --ro-info-ink:    #155BC7;
  --ro-neutral: #6B7280;  --ro-neutral-light: #ECEFF3;  --ro-neutral-ink: #4B5563;

  /* Domain colours: steel diagrams, cutting patterns, charts */
  --ro-offcut: #F0B429;
  --ro-scrap: #D64545;
  --ro-fabricated: #4C7FD1;
  --ro-fabricated-alt: #6F9BE0;

  /* Chart series, in this order (Chart.js reads these through RebarOpt.chartColors()) */
  --ro-chart-1: #1F6FEB;
  --ro-chart-2: #2E8B57;
  --ro-chart-3: #F0B429;
  --ro-chart-4: #D64545;
  --ro-chart-5: #6F9BE0;
  --ro-chart-6: #6B7280;

  /* Typography (desktop Typography.xaml; web body is 14px instead of 13px for browser legibility) */
  --ro-font: "Segoe UI", system-ui, -apple-system, Roboto, "Helvetica Neue", Arial, sans-serif;
  --ro-font-mono: Consolas, "Cascadia Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --ro-fs-xs: 0.6875rem;   /* 11px  chip, status bar */
  --ro-fs-sm: 0.75rem;     /* 12px  form label, muted text, KPI label, table header */
  --ro-fs-ui: 0.8125rem;   /* 13px  menu entries, section titles */
  --ro-fs-base: 0.875rem;  /* 14px  body */
  --ro-fs-md: 1rem;        /* 16px  card title */
  --ro-fs-lg: 1.375rem;    /* 22px  page title */
  --ro-fs-kpi: 1.625rem;   /* 26px  KPI value */
  --ro-fs-auth-title: 2rem;
  --ro-fs-auth-hero: 3.25rem;
  --ro-fw-semibold: 600;

  /* Spacing scale (4px base) */
  --ro-space-1: 0.25rem;  /* 4  */
  --ro-space-2: 0.5rem;   /* 8  */
  --ro-space-3: 0.75rem;  /* 12 */
  --ro-space-4: 1rem;     /* 16 */
  --ro-space-5: 1.5rem;   /* 24 */
  --ro-space-6: 2rem;     /* 32 */

  /* Shape and depth */
  --ro-radius-sm: 4px;    /* inputs inside grids, small tags */
  --ro-radius: 8px;       /* buttons, inputs, nav items */
  --ro-radius-lg: 12px;   /* cards, tables, modals */
  --ro-radius-pill: 999px;
  --ro-shadow-xs: 0 1px 2px rgba(16, 24, 40, 0.05);
  --ro-shadow-card: 0 1px 3px rgba(16, 24, 40, 0.06), 0 1px 2px rgba(16, 24, 40, 0.04);
  --ro-shadow-pop: 0 12px 32px rgba(16, 24, 40, 0.16);
  --ro-shadow-sticky: 0 6px 8px -6px rgba(16, 24, 40, 0.18);
  --ro-shadow-pin: 6px 0 8px -6px rgba(16, 24, 40, 0.18);   /* right edge of a table's pinned first column */

  /* Layout */
  --ro-scroll-region-max-h: 40rem;
  --ro-topbar-h: 56px;
  --ro-nav-w: 248px;
  --ro-statusbar-h: 26px;
  --ro-control-h: 34px;
  --ro-row-h: 36px;
  /* Filter panels: every filter has one width, so the filters line up in columns; a search box and a long picker
     (BBS revision, run) are wider. */
  --ro-filter-w: 12rem;
  --ro-filter-w-text: 15rem;
  --ro-filter-w-wide: 18rem;
  --ro-form-max: 60rem;
  /* Tables never grow taller than the visible page (D54). rebaropt.js measures the page and sets --ro-fit-h on each
     table; this fallback (window minus shell and page header) applies until it has, and without scripts. */
  --ro-table-min-h: 16rem;
  --ro-table-max-h: max(var(--ro-table-min-h), calc(100vh - 15rem));
}

/* -----------------------------------------------------------------------------------------------------
   2. Bootstrap mapped onto the tokens (CSS variables, no Sass build needed)
   ----------------------------------------------------------------------------------------------------- */
:root {
  --bs-body-font-family: var(--ro-font);
  --bs-body-font-size: var(--ro-fs-base);
  --bs-body-color: var(--ro-text);
  --bs-body-bg: var(--ro-bg);
  --bs-secondary-color: var(--ro-muted);
  --bs-border-color: var(--ro-border);
  --bs-border-radius: var(--ro-radius);
  --bs-border-radius-lg: var(--ro-radius-lg);
  --bs-border-radius-sm: var(--ro-radius-sm);
  --bs-primary: var(--ro-primary);
  --bs-primary-rgb: 31, 111, 235;
  --bs-success: var(--ro-success);
  --bs-success-rgb: 46, 139, 87;
  --bs-warning: var(--ro-warning);
  --bs-warning-rgb: 217, 142, 4;
  --bs-danger: var(--ro-danger);
  --bs-danger-rgb: 192, 57, 43;
  --bs-link-color: var(--ro-primary-dark);
  --bs-link-color-rgb: 21, 91, 199;
  --bs-link-hover-color: var(--ro-primary);
  --bs-focus-ring-color: rgba(31, 111, 235, 0.35);
  --bs-font-monospace: var(--ro-font-mono);
}

body { font-variant-numeric: tabular-nums; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
/* Links read as links without an underline everywhere a link is plainly one (tables, menus, buttons); running text
   (.ro-prose, alerts, form help) keeps the underline so colour is never the only signal (§7 rule 8). */
a { text-decoration: none; }
a:not([class]):hover { text-decoration: underline; text-underline-offset: 2px; }
.ro-prose a, .alert a, .form-text a, p > a:not([class]) { text-decoration: underline; text-underline-offset: 2px; }

/* Thin, quiet scrollbars on every scroll area (page, tables, lists); the native bar shows its own on hover. */
* { scrollbar-width: thin; scrollbar-color: var(--ro-scrollbar) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--ro-scrollbar); border-radius: var(--ro-radius-pill); border: 2px solid transparent; background-clip: padding-box; }
::-webkit-scrollbar-thumb:hover { background-color: var(--ro-scrollbar-hover); }
::-webkit-scrollbar-corner { background: transparent; }

.btn { --bs-btn-font-size: var(--ro-fs-base); --bs-btn-padding-x: 0.875rem; --bs-btn-padding-y: 0.375rem;
       --bs-btn-border-radius: var(--ro-radius); --bs-btn-font-weight: 500; --bs-btn-focus-box-shadow: 0 0 0 0.25rem var(--ro-focus-ring);
       min-height: var(--ro-control-h); display: inline-flex; align-items: center; justify-content: center; gap: 0.375rem;
       transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease; }
.btn-sm { --bs-btn-font-size: var(--ro-fs-sm); --bs-btn-padding-x: 0.625rem; --bs-btn-padding-y: 0.25rem; min-height: 28px; gap: 0.25rem; }
.btn-primary {
  --bs-btn-bg: var(--ro-primary); --bs-btn-border-color: var(--ro-primary);
  --bs-btn-hover-bg: var(--ro-primary-dark); --bs-btn-hover-border-color: var(--ro-primary-dark);
  --bs-btn-active-bg: var(--ro-primary-dark); --bs-btn-active-border-color: var(--ro-primary-dark);
  --bs-btn-disabled-bg: var(--ro-primary); --bs-btn-disabled-border-color: var(--ro-primary);
  box-shadow: var(--ro-shadow-xs);
}
.btn-outline-secondary {
  --bs-btn-color: var(--ro-text); --bs-btn-bg: var(--ro-surface); --bs-btn-border-color: var(--ro-border-strong);
  --bs-btn-hover-color: var(--ro-text); --bs-btn-hover-bg: var(--ro-row-hover); --bs-btn-hover-border-color: var(--ro-border-strong);
  --bs-btn-active-color: var(--ro-text); --bs-btn-active-bg: var(--ro-header-band); --bs-btn-active-border-color: var(--ro-border-strong);
  --bs-btn-disabled-color: var(--ro-muted); --bs-btn-disabled-bg: var(--ro-surface); --bs-btn-disabled-border-color: var(--ro-border);
  box-shadow: var(--ro-shadow-xs);
}
.btn-success { --bs-btn-bg: var(--ro-success); --bs-btn-border-color: var(--ro-success);
               --bs-btn-hover-bg: var(--ro-success-ink); --bs-btn-hover-border-color: var(--ro-success-ink);
               --bs-btn-disabled-bg: var(--ro-success); --bs-btn-disabled-border-color: var(--ro-success); box-shadow: var(--ro-shadow-xs); }
.btn-danger  { --bs-btn-bg: var(--ro-danger); --bs-btn-border-color: var(--ro-danger);
               --bs-btn-hover-bg: var(--ro-danger-ink); --bs-btn-hover-border-color: var(--ro-danger-ink); box-shadow: var(--ro-shadow-xs); }
.btn-link    { --bs-btn-color: var(--ro-primary-dark); --bs-btn-hover-color: var(--ro-primary); text-decoration: none; }
.btn-link:hover { text-decoration: underline; }
.btn:disabled, .btn.disabled { box-shadow: none; }

.form-control, .form-select { min-height: var(--ro-control-h); font-size: var(--ro-fs-base); border-color: var(--ro-border-strong);
                              border-radius: var(--ro-radius); background-color: var(--ro-surface); box-shadow: var(--ro-shadow-xs);
                              transition: border-color 0.15s ease, box-shadow 0.15s ease; }   /* Bootstrap would use the page background (--bs-body-bg) */
.form-control:hover:not(:focus):not(:disabled), .form-select:hover:not(:focus):not(:disabled) { border-color: var(--ro-scrollbar-hover); }
.form-control:focus, .form-select:focus { border-color: var(--ro-primary); box-shadow: 0 0 0 0.25rem var(--ro-focus-ring); }
.form-control:disabled, .form-select:disabled, .form-control[readonly] { background-color: var(--ro-header-band); box-shadow: none; }
.form-control::placeholder { color: var(--ro-muted); opacity: 0.85; }
.form-control-sm, .form-select-sm { min-height: 28px; font-size: var(--ro-fs-sm); border-radius: var(--ro-radius-sm); }
.form-label { font-size: var(--ro-fs-sm); font-weight: 500; color: var(--ro-text-secondary); margin-bottom: var(--ro-space-1); }
.form-text { font-size: var(--ro-fs-sm); color: var(--ro-muted); }
.input-group-text { font-size: var(--ro-fs-sm); color: var(--ro-muted); background: var(--ro-header-band); border-color: var(--ro-border-strong); }
.invalid-feedback, .field-validation-error { font-size: var(--ro-fs-sm); color: var(--ro-danger-ink); }
.input-validation-error { border-color: var(--ro-danger) !important; }

.nav-underline { --bs-nav-underline-gap: 0; --bs-nav-underline-border-width: 2px; --bs-nav-link-color: var(--ro-text-secondary);
                 --bs-nav-link-hover-color: var(--ro-text); --bs-nav-underline-link-active-color: var(--ro-primary-dark);
                 border-bottom: 1px solid var(--ro-border); gap: var(--ro-space-1); }
.nav-underline .nav-link { padding: var(--ro-space-2) 0.875rem; font-size: var(--ro-fs-base); font-weight: 500; }

.modal { --bs-modal-border-radius: var(--ro-radius-lg); --bs-modal-header-padding: var(--ro-space-4) var(--ro-space-5);
         --bs-modal-padding: var(--ro-space-5); --bs-modal-box-shadow: var(--ro-shadow-pop); --bs-modal-border-color: var(--ro-border); }
.modal-title { font-size: var(--ro-fs-md); font-weight: var(--ro-fw-semibold); }
/* A table in a modal scrolls within the modal's own height. */
.modal .ro-table-wrap { max-height: min(60vh, 32rem); }
/* Wave 3: a confirmation keeps the line breaks of its message (the desktop wrote its questions in paragraphs). */
.ro-confirm__message { white-space: pre-line; }

.alert { --bs-alert-padding-y: var(--ro-space-3); --bs-alert-padding-x: var(--ro-space-4); --bs-alert-border-radius: var(--ro-radius); font-size: var(--ro-fs-base); }
.alert-success { --bs-alert-color: var(--ro-success-ink); --bs-alert-bg: var(--ro-success-light); --bs-alert-border-color: #BFE3CD; }
.alert-warning { --bs-alert-color: var(--ro-warning-ink); --bs-alert-bg: var(--ro-warning-light); --bs-alert-border-color: #F1DCA6; }
.alert-danger  { --bs-alert-color: var(--ro-danger-ink);  --bs-alert-bg: var(--ro-danger-light);  --bs-alert-border-color: #F0C1BB; }
.alert-info    { --bs-alert-color: var(--ro-info-ink);    --bs-alert-bg: var(--ro-info-light);    --bs-alert-border-color: #BED2F6; }

.pagination { --bs-pagination-font-size: var(--ro-fs-sm); --bs-pagination-color: var(--ro-primary-dark); --bs-pagination-bg: var(--ro-surface);
              --bs-pagination-border-color: var(--ro-border); --bs-pagination-border-radius: var(--ro-radius);
              --bs-pagination-hover-color: var(--ro-primary); --bs-pagination-hover-bg: var(--ro-row-hover); --bs-pagination-hover-border-color: var(--ro-border);
              --bs-pagination-focus-color: var(--ro-primary); --bs-pagination-focus-bg: var(--ro-row-hover);
              --bs-pagination-focus-box-shadow: 0 0 0 0.25rem var(--ro-focus-ring);
              --bs-pagination-active-color: #FFFFFF; --bs-pagination-active-bg: var(--ro-primary); --bs-pagination-active-border-color: var(--ro-primary);
              --bs-pagination-disabled-color: var(--ro-muted); --bs-pagination-disabled-bg: var(--ro-surface); --bs-pagination-disabled-border-color: var(--ro-border);
              margin: 0; }

.dropdown-menu { --bs-dropdown-font-size: var(--ro-fs-base); --bs-dropdown-color: var(--ro-text); --bs-dropdown-bg: var(--ro-surface);
                 --bs-dropdown-border-color: var(--ro-border); --bs-dropdown-border-radius: var(--ro-radius); --bs-dropdown-box-shadow: var(--ro-shadow-pop);
                 --bs-dropdown-link-color: var(--ro-text); --bs-dropdown-link-hover-color: var(--ro-text); --bs-dropdown-link-hover-bg: var(--ro-row-hover);
                 --bs-dropdown-link-active-color: #FFFFFF; --bs-dropdown-link-active-bg: var(--ro-primary); --bs-dropdown-header-color: var(--ro-muted);
                 --bs-dropdown-item-padding-y: 0.375rem; --bs-dropdown-padding-y: var(--ro-space-1);
                 box-shadow: var(--bs-dropdown-box-shadow); }
.dropdown-menu:not(.ro-notices) .dropdown-item { border-radius: var(--ro-radius-sm); width: calc(100% - var(--ro-space-2)); margin: 0 var(--ro-space-1); }

.form-check-input { border-color: var(--ro-border-strong); }
.form-check-input:checked { background-color: var(--ro-primary); border-color: var(--ro-primary); }
.form-check-input:focus { border-color: var(--ro-primary); box-shadow: 0 0 0 0.25rem var(--ro-focus-ring); }

/* -----------------------------------------------------------------------------------------------------
   3. Application shell: top bar, left navigation, breadcrumb, page area, status bar
   ----------------------------------------------------------------------------------------------------- */
.ro-shell { display: grid; grid-template-columns: var(--ro-nav-w) minmax(0, 1fr);
            grid-template-rows: var(--ro-topbar-h) minmax(0, 1fr) var(--ro-statusbar-h);
            height: 100vh; height: 100dvh; overflow: hidden; }

/* Top bar (D54): light, with the brand in a navigation-coloured block that continues the menu column. */
.ro-topbar { grid-column: 1 / -1; background: var(--ro-surface); color: var(--ro-text); display: flex; align-items: center;
             gap: var(--ro-space-2); padding: 0 var(--ro-space-4) 0 0; border-bottom: 1px solid var(--ro-border);
             box-shadow: var(--ro-shadow-xs); position: sticky; top: 0; z-index: 1030; min-width: 0; }
.ro-topbar__brand { display: flex; align-items: center; gap: var(--ro-space-2); align-self: stretch; flex: 0 0 var(--ro-nav-w);
                    width: var(--ro-nav-w); margin: 0 var(--ro-space-2) -1px 0; padding: 0 var(--ro-space-4) 1px;
                    background: var(--ro-nav); font-weight: var(--ro-fw-semibold); font-size: var(--ro-fs-md); color: #FFFFFF;
                    text-decoration: none; }
.ro-topbar__brand:hover { color: #FFFFFF; }
.ro-topbar__brand img { height: 28px; width: auto; }
.ro-topbar .form-select, .ro-topbar .form-control { background-color: var(--ro-bg); border-color: var(--ro-border);
                    color: var(--ro-text); min-height: 36px; font-size: var(--ro-fs-ui); box-shadow: none; }
.ro-topbar .form-select:focus, .ro-topbar .form-control:focus { background-color: var(--ro-surface); border-color: var(--ro-primary);
                    box-shadow: 0 0 0 0.25rem var(--ro-focus-ring); }
.ro-topbar .form-control::placeholder { color: var(--ro-muted); }
.ro-topbar form[role="search"] { flex: 0 1 15rem; min-width: 8rem; }
.ro-topbar__search { position: relative; }
.ro-topbar__search > i { position: absolute; left: 0.75rem; top: 50%; transform: translateY(-50%); color: var(--ro-muted); pointer-events: none; }
.ro-topbar__search .form-control { width: 100%; padding-left: 2.125rem; }
.ro-topbar__btn { background: transparent; border: 0; color: var(--ro-text-secondary); border-radius: var(--ro-radius);
                  padding: 0.4375rem 0.625rem; font-size: var(--ro-fs-ui); font-weight: 500; display: inline-flex; align-items: center;
                  gap: 0.375rem; text-decoration: none; white-space: nowrap; position: relative; }
.ro-topbar__btn:hover, .ro-topbar__btn:focus-visible, .ro-topbar__btn[aria-expanded="true"] { background: var(--ro-header-band); color: var(--ro-text); text-decoration: none; }
.ro-topbar__btn[aria-pressed="true"] { background: var(--ro-primary-light); color: var(--ro-primary-dark); }
.ro-topbar__btn > .bi { font-size: var(--ro-fs-md); }
.ro-topbar__spacer { flex: 1 1 auto; }
.ro-topbar__badge { background: var(--ro-danger); color: #FFFFFF; border-radius: var(--ro-radius-pill); font-size: 0.625rem;
                    padding: 0 0.375rem; line-height: 1.4; font-weight: var(--ro-fw-semibold); }
.ro-topbar__badge[hidden] { display: none; }
/* Owner review (2026-10-08): guidance and help, a divider, then the account area. Every button is one height, an
   icon-only button is square, the bell's count sits on its corner, and the user shows as an avatar with initials. */
.ro-topbar__btn { min-height: 36px; }
.ro-topbar__btn--icon { width: 36px; padding: 0; justify-content: center; }
.ro-topbar__btn--icon .ro-topbar__badge { position: absolute; top: 1px; right: -2px; min-width: 1.125rem; text-align: center;
                                          box-shadow: 0 0 0 2px var(--ro-surface); }
.ro-topbar__divider { flex: 0 0 auto; align-self: center; width: 1px; height: 1.5rem; margin: 0 var(--ro-space-1); background: var(--ro-border); }
.ro-topbar__user { gap: var(--ro-space-2); padding-left: var(--ro-space-1); }
.ro-topbar__btn > .ro-topbar__caret { font-size: var(--ro-fs-xs); color: var(--ro-muted); }
.ro-avatar { display: inline-grid; place-items: center; flex: 0 0 auto; width: 28px; height: 28px; border-radius: 50%;
             background: var(--ro-primary-light); color: var(--ro-primary-dark); font-size: var(--ro-fs-xs);
             font-weight: var(--ro-fw-semibold); letter-spacing: 0.02em; line-height: 1; }
.ro-avatar--lg { width: 40px; height: 40px; font-size: var(--ro-fs-base); }
/* User menu: who is signed in (avatar, name, user name and role), then the account actions; Sign out last, in the
   danger ink so it is not taken for an ordinary entry. */
.ro-user-menu { min-width: 16rem; }
.ro-user-menu__head { display: flex; align-items: center; gap: var(--ro-space-3); padding: var(--ro-space-2) var(--ro-space-4) var(--ro-space-2) var(--ro-space-3); }
.ro-user-menu__who { display: grid; min-width: 0; line-height: 1.35; }
.ro-user-menu__name, .ro-user-menu__meta { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ro-user-menu__name { font-weight: var(--ro-fw-semibold); color: var(--ro-text); }
.ro-user-menu__meta { font-size: var(--ro-fs-sm); color: var(--ro-muted); }
.ro-user-menu .dropdown-divider { margin: var(--ro-space-1) 0; border-top-color: var(--ro-border); opacity: 1; }
.ro-user-menu .ro-user-menu__signout, .ro-user-menu .ro-user-menu__signout > .bi { color: var(--ro-danger-ink); }
.ro-user-menu .ro-user-menu__signout:hover, .ro-user-menu .ro-user-menu__signout:focus-visible { background: var(--ro-danger-light); }
/* A menu entry's icon sits in a fixed column, muted, so the entries' words line up. */
.dropdown-item:has(> .bi:first-child) { display: flex; align-items: center; }
.dropdown-item > .bi:first-child { flex: 0 0 1.25rem; margin-right: var(--ro-space-2); color: var(--ro-muted); }
.ro-topbar__brand-text { display: grid; line-height: 1.2; min-width: 0; }
.ro-topbar__brand-text > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ro-topbar__company { font-size: var(--ro-fs-xs); font-weight: 400; color: var(--ro-nav-text); }
.ro-topbar__project { display: flex; align-items: center; gap: var(--ro-space-2); min-width: 0; flex: 0 1 28rem; }
.ro-topbar__project .form-select { width: 100%; min-width: 10rem; font-weight: 500; }
.ro-topbar__label { font-size: var(--ro-fs-sm); color: var(--ro-muted); white-space: nowrap; }
.ro-topbar__context { font-size: var(--ro-fs-sm); color: var(--ro-text); white-space: nowrap; }

/* Left navigation: sections, and under an open section its pages along a guide line. */
.ro-nav { background: var(--ro-nav); color: var(--ro-nav-text); overflow-y: auto; padding: var(--ro-space-3) var(--ro-space-2) var(--ro-space-5);
          position: sticky; top: var(--ro-topbar-h); height: calc(100vh - var(--ro-topbar-h) - var(--ro-statusbar-h));
          scrollbar-color: var(--ro-nav-hover) transparent; }
.ro-nav::-webkit-scrollbar-thumb { background-color: var(--ro-nav-hover); }
.ro-nav ul { list-style: none; margin: 0; padding: 0; }
.ro-nav > ul > li + li { margin-top: 2px; }
.ro-nav a, .ro-nav button { display: flex; align-items: center; gap: 0.625rem; width: 100%; text-align: left;
          padding: 0.4375rem var(--ro-space-3); border: 0; background: transparent; color: var(--ro-nav-text);
          border-radius: var(--ro-radius); font-size: var(--ro-fs-base); font-weight: 500; text-decoration: none; position: relative;
          transition: background-color 0.15s ease, color 0.15s ease; }
.ro-nav a:hover, .ro-nav button:hover { background: var(--ro-nav-hover); color: #FFFFFF; text-decoration: none; }
.ro-nav__icon { flex: 0 0 var(--ro-space-4); text-align: center; color: var(--ro-nav-dim); font-size: var(--ro-fs-md); }
.ro-nav a:hover .ro-nav__icon, .ro-nav button:hover .ro-nav__icon,
.ro-nav a.active .ro-nav__icon, .ro-nav button[aria-expanded="true"] .ro-nav__icon { color: inherit; }
.ro-nav button[aria-expanded="true"] { color: #FFFFFF; }
.ro-nav .ro-nav__children { margin: 2px 0 var(--ro-space-2) calc(var(--ro-space-3) + 0.4375rem); padding-left: var(--ro-space-2);
          border-left: 1px solid var(--ro-nav-hover); }
.ro-nav .ro-nav__children li + li { margin-top: 1px; }
.ro-nav .ro-nav__children a { padding: 0.375rem var(--ro-space-3); font-size: var(--ro-fs-ui); font-weight: 400; gap: var(--ro-space-2); }
.ro-nav .ro-nav__children .ro-nav__icon { font-size: var(--ro-fs-ui); }
.ro-nav a.active { background: var(--ro-nav-active); color: #FFFFFF; font-weight: 500; }
.ro-nav a.active::before { content: ""; position: absolute; left: 0; top: 6px; bottom: 6px; width: 3px;
          border-radius: 2px; background: var(--ro-primary); }
.ro-nav .ro-nav__children a.active::before { left: calc(-1 * var(--ro-space-2) - 1px); width: 2px; top: 4px; bottom: 4px; }
.ro-nav__chevron { margin-left: auto; font-size: var(--ro-fs-xs); color: var(--ro-nav-dim); transition: transform 0.15s ease; }
.ro-nav button[aria-expanded="true"] .ro-nav__chevron { transform: rotate(90deg); }
/* A page that a later wave builds: shown only when RebarOpt:Navigation:ShowPlannedPages is on, never a link. */
.ro-nav .ro-nav__planned { display: flex; align-items: center; gap: var(--ro-space-2); padding: 0.5rem var(--ro-space-3);
          color: var(--ro-nav-dim); font-size: var(--ro-fs-base); cursor: default; }
.ro-nav .ro-nav__children .ro-nav__planned { padding: 0.375rem var(--ro-space-3); font-size: var(--ro-fs-ui); }
.ro-nav__wave { margin-left: auto; font-family: var(--ro-font-mono); font-size: var(--ro-fs-xs); }

/* Page area. The page content scrolls in .ro-page-workspace, whose scrollbar sits at the window's edge (the gutter is
   its padding); the breadcrumb above it and the page header pinned at its top stay in view. */
.ro-main { --ro-gutter: var(--ro-space-5); display: flex; flex-direction: column; min-width: 0; min-height: 0;
           padding: var(--ro-space-3) 0 0; }
.ro-main > nav { padding: 0 var(--ro-gutter); }
.ro-page-workspace { flex: 1; min-height: 0; overflow: auto; padding: 0 var(--ro-gutter) var(--ro-space-5);
                     scroll-padding-top: var(--ro-sticky-h, 0px); }
.ro-page-workspace:focus-visible { outline-offset: -2px; }
.ro-page-workspace.ro-guide-workspace { align-items: stretch; }
.ro-page-workspace > .ro-guide-panel { align-self: start; }
/* Only the rendered page content scrolls; its title and actions stay below the breadcrumb, with a divider once the
   content scrolls under them (rebaropt.js sets is-scrolled). */
.ro-page-workspace > .ro-guide-page > .ro-page-header { position: sticky; top: 0; z-index: 1020;
           background: var(--ro-bg); padding: var(--ro-space-1) 0 var(--ro-space-4); margin-bottom: 0;
           transition: box-shadow 0.15s ease; }
.ro-page-workspace:not(.ro-guide-workspace) > .ro-guide-page > .ro-page-header { margin-inline: calc(-1 * var(--ro-gutter)); padding-inline: var(--ro-gutter); }
.ro-page-workspace.is-scrolled > .ro-guide-page > .ro-page-header { box-shadow: 0 1px 0 var(--ro-border), var(--ro-shadow-sticky); }
@media (max-width: 1199.98px) {
  /* Keep the header pinned even when scrolling into the coach below the page. */
  .ro-page-workspace.ro-guide-workspace { display: block; }
  .ro-page-workspace.ro-guide-workspace > .ro-guide-page { display: contents; }
  .ro-page-workspace > .ro-guide-panel { margin-top: var(--ro-space-4); }
}

.ro-breadcrumb { --bs-breadcrumb-font-size: var(--ro-fs-sm); --bs-breadcrumb-divider: "›"; --bs-breadcrumb-divider-color: var(--ro-scrollbar-hover);
                 --bs-breadcrumb-item-active-color: var(--ro-muted); --bs-breadcrumb-margin-bottom: var(--ro-space-1);
                 --bs-breadcrumb-item-padding-x: var(--ro-space-2); }
.ro-breadcrumb a { color: var(--ro-text-secondary); text-decoration: none; }
.ro-breadcrumb a:hover { color: var(--ro-primary-dark); text-decoration: none; }

.ro-statusbar { grid-column: 1 / -1; background: var(--ro-surface); border-top: 1px solid var(--ro-border);
                color: var(--ro-muted); font-size: var(--ro-fs-xs); display: flex; flex-wrap: wrap; align-items: center;
                gap: var(--ro-space-1) var(--ro-space-5); padding: 0 var(--ro-space-4); overflow: hidden; }
.ro-statusbar__end { margin-left: auto; }

/* -----------------------------------------------------------------------------------------------------
   4. Page anatomy
   ----------------------------------------------------------------------------------------------------- */
.ro-page-header { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between;
                  gap: var(--ro-space-3); margin-bottom: var(--ro-space-4); }
.ro-page-title { font-size: var(--ro-fs-lg); font-weight: var(--ro-fw-semibold); color: var(--ro-text); margin: 0; line-height: 1.25;
                  letter-spacing: -0.01em; }
.ro-page-subtitle { font-size: var(--ro-fs-base); color: var(--ro-muted); margin: var(--ro-space-1) 0 0; }
.ro-page-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ro-space-2); }

.ro-section-title { font-size: var(--ro-fs-ui); font-weight: var(--ro-fw-semibold); color: var(--ro-text-secondary);
                    margin: 0 0 var(--ro-space-2); }
.ro-muted { color: var(--ro-muted); font-size: var(--ro-fs-sm); }
.ro-mono { font-family: var(--ro-font-mono); }
.ro-stack { display: grid; gap: var(--ro-space-4); }

.ro-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ro-space-2); margin-bottom: var(--ro-space-3); }
.ro-toolbar__spacer { flex: 1 1 auto; }
.ro-toolbar .form-control, .ro-toolbar .form-select { width: auto; min-width: 10rem; }
/* Filter panel (a GET form; owner review 2026-10-08): one panel above the list it filters. Every filter has the same
   width, so the filters line up in columns, and every control, button and link has the same height on one bottom line.
   A filter is a control on its own (its first choice says "All …") or a label with its caption above the control
   (Dashboard); a search box is wider, and so is a long picker marked ro-filter-wide. Apply and Reset follow the last
   filter; a summary after ro-toolbar__spacer sits at the right. */
form.ro-toolbar[method="get" i] { align-items: flex-end; gap: var(--ro-space-3); background: var(--ro-surface); border: 1px solid var(--ro-border);
                                  border-radius: var(--ro-radius-lg); box-shadow: var(--ro-shadow-xs); padding: var(--ro-space-3) var(--ro-space-4); }
form.ro-toolbar[method="get" i] > :is(.form-control, .form-select, label:not(.form-label, .form-check-label, .form-check)) { flex: 0 1 var(--ro-filter-w); width: var(--ro-filter-w); min-width: 0; }
form.ro-toolbar[method="get" i] > :is(input[type="search"], input[type="text"], input:not([type])) { flex-basis: var(--ro-filter-w-text); }
form.ro-toolbar[method="get" i] > :is(.form-control, .form-select, label).ro-filter-wide { flex-basis: var(--ro-filter-w-wide); }
form.ro-toolbar[method="get" i] > label:not(.form-label, .form-check-label, .form-check) { display: flex; flex-direction: column; gap: var(--ro-space-1); margin: 0;
                                  font-size: var(--ro-fs-sm); font-weight: 500; color: var(--ro-text-secondary); }
form.ro-toolbar[method="get" i] > label > :is(.form-control, .form-select) { width: 100%; min-width: 0; }
/* A caption beside its control, a check box, a link and the summary sit on the controls' line. */
form.ro-toolbar[method="get" i] > :is(label.form-label, .form-check, span:not(.ro-toolbar__spacer), strong, a:not(.btn)) {
  display: inline-flex; align-items: center; min-height: var(--ro-control-h); margin: 0; }
form.ro-toolbar[method="get" i] > .form-check { gap: var(--ro-space-2); padding-left: 0; }
form.ro-toolbar[method="get" i] > .form-check .form-check-input { float: none; margin: 0; }
form.ro-toolbar[method="get" i] > .btn, form.ro-toolbar[method="get" i] > .btn-group > .btn { --bs-btn-font-size: var(--ro-fs-base); --bs-btn-padding-x: 0.875rem; --bs-btn-padding-y: 0.375rem; min-height: var(--ro-control-h); }
form.ro-toolbar[method="get" i] > :is(.btn-link, a:not(.btn)) { padding-inline: var(--ro-space-2); font-weight: 500; }
/* With captions above the filters (Dashboard), the actions close the panel at the right end of its last line. */
form.ro-toolbar[method="get" i]:has(> label:not(.form-label, .form-check-label, .form-check)) > button.btn:first-of-type { margin-left: auto; }
.ro-card form.ro-toolbar[method="get" i] { border: 0; box-shadow: none; padding: 0; }

/* -----------------------------------------------------------------------------------------------------
   5. Cards and KPI cards
   ----------------------------------------------------------------------------------------------------- */
.ro-card { background: var(--ro-surface); border: 1px solid var(--ro-border); border-radius: var(--ro-radius-lg);
           box-shadow: var(--ro-shadow-card); padding: var(--ro-space-4) var(--ro-space-5); min-width: 0; }
.ro-card__title { font-size: var(--ro-fs-md); font-weight: var(--ro-fw-semibold); margin: 0 0 var(--ro-space-3); }
.ro-card--flush { padding: 0; overflow: hidden; }
/* A table inside a card uses the card's frame. */
.ro-card .ro-table-wrap { box-shadow: none; }
.ro-card--flush > .ro-table-wrap { border: 0; border-radius: 0; }

/* Block spacing (UI refresh): a card, table frame or empty state always keeps 16 px to the block after it, whether or
   not the view adds mb-3 (the same value; vertical margins collapse, so nothing doubles). The last block in its
   container keeps none, so a card's padding stays even; in a container that spaces its children with gap (stack, grid
   row, flex row, KPI strip, BBS Entry, coach) the gap is the only spacing. */
.ro-card, .ro-table-wrap, .ro-empty { margin-bottom: var(--ro-space-4); }
:is(.ro-card, .ro-table-wrap, .ro-empty):last-child { margin-bottom: 0; }
:is(.ro-stack, .d-grid, .d-flex, .d-inline-flex, .row, .ro-entry, .ro-guide-workspace, .ro-site-grid, .ro-scan-actions, .ro-kpis)
  > :is(.ro-card, .ro-table-wrap, .ro-empty) { margin-bottom: 0; }
details[open] > summary { margin-bottom: var(--ro-space-3); }
summary { cursor: pointer; }

/* KPI cards: label, figure, unit; a tone shows as a coloured edge (the label and figure always say it too). */
.ro-kpis { display: grid; grid-template-columns: repeat(auto-fill, minmax(10.5rem, 1fr)); gap: var(--ro-space-3); margin-bottom: var(--ro-space-4); }
.ro-kpi { position: relative; overflow: hidden; background: var(--ro-surface); border: 1px solid var(--ro-border);
          border-radius: var(--ro-radius-lg); box-shadow: var(--ro-shadow-card); padding: var(--ro-space-3) var(--ro-space-4);
          display: grid; align-content: start; gap: 0.125rem; color: inherit; text-decoration: none;
          transition: border-color 0.15s ease, box-shadow 0.15s ease; }
.ro-kpi::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: transparent; }
a.ro-kpi:hover { border-color: var(--ro-border-strong); box-shadow: var(--ro-shadow-pop); color: inherit; text-decoration: none; }
a.ro-kpi::after { content: "\203A"; position: absolute; top: var(--ro-space-2); right: var(--ro-space-3); color: var(--ro-muted); font-size: var(--ro-fs-md); }
.ro-kpi__label { font-size: var(--ro-fs-sm); font-weight: 500; color: var(--ro-muted); padding-right: var(--ro-space-3); }
.ro-kpi__value { font-size: var(--ro-fs-kpi); font-weight: var(--ro-fw-semibold); line-height: 1.2; letter-spacing: -0.02em; color: var(--ro-text); }
.ro-kpi__unit { font-size: var(--ro-fs-sm); font-weight: 400; color: var(--ro-muted); margin-left: 0.25rem; letter-spacing: 0; }
.ro-kpi__compare { font-size: var(--ro-fs-xs); color: var(--ro-muted); }
.ro-kpi--success::before { background: var(--ro-success); }
.ro-kpi--warning::before { background: var(--ro-warning); }
.ro-kpi--danger::before  { background: var(--ro-danger); }

/* -----------------------------------------------------------------------------------------------------
   6. Status chips (one tone per meaning; the tone for each status is decided in C#, never in the view)
   ----------------------------------------------------------------------------------------------------- */
.ro-chip { display: inline-flex; align-items: center; gap: 0.25rem; border-radius: var(--ro-radius-pill);
           padding: 0.0625rem 0.5rem; font-size: var(--ro-fs-xs); font-weight: var(--ro-fw-semibold); line-height: 1.6;
           white-space: nowrap; background: var(--ro-neutral-light); color: var(--ro-neutral-ink); }
.ro-chip--success { background: var(--ro-success-light); color: var(--ro-success-ink); }
.ro-chip--warning { background: var(--ro-warning-light); color: var(--ro-warning-ink); }
.ro-chip--danger  { background: var(--ro-danger-light);  color: var(--ro-danger-ink); }
.ro-chip--info    { background: var(--ro-info-light);    color: var(--ro-info-ink); }
.ro-chip--neutral { background: var(--ro-neutral-light); color: var(--ro-neutral-ink); }
.ro-chip--offcut  { background: var(--ro-warning-light); color: var(--ro-warning-ink); }
.ro-chip--scrap   { background: var(--ro-danger-light);  color: var(--ro-danger-ink); }

/* -----------------------------------------------------------------------------------------------------
   7. Tables (read-only lists rendered by Razor) and Tabulator (editable grids)
   ----------------------------------------------------------------------------------------------------- */
/* A table never grows taller than the visible page (D54): its rows scroll inside the frame under a pinned header row
   (and a pinned footer of totals), and a wide table scrolls sideways with its scrollbar in view. rebaropt.js sets
   --ro-fit-h: the rest of the window when the table is the page's last large block, otherwise the window's height
   under the page header. */
.ro-table-wrap { position: relative; overflow: auto; max-height: var(--ro-fit-h, var(--ro-table-max-h));
                 background: var(--ro-surface); border: 1px solid var(--ro-border); border-radius: var(--ro-radius-lg);
                 box-shadow: var(--ro-shadow-xs); }
.ro-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: var(--ro-fs-base); margin: 0; }
.ro-table thead th { position: sticky; top: 0; z-index: 2; background: var(--ro-table-head); color: var(--ro-text-secondary);
                     font-size: var(--ro-fs-sm); font-weight: var(--ro-fw-semibold); text-align: left; vertical-align: bottom;
                     padding: 0.5625rem var(--ro-space-3); border-bottom: 1px solid var(--ro-border); white-space: nowrap; }
/* A label cell in the body (key / value tables: Diagnostics, details). */
.ro-table tbody th { background: var(--ro-table-head); color: var(--ro-text-secondary); font-size: var(--ro-fs-sm); font-weight: var(--ro-fw-semibold);
                     text-align: left; padding: 0.25rem var(--ro-space-3); height: var(--ro-row-h); border-bottom: 1px solid var(--ro-border);
                     white-space: nowrap; vertical-align: middle; }
.ro-table td { padding: 0.25rem var(--ro-space-3); height: var(--ro-row-h); border-bottom: 1px solid var(--ro-border); vertical-align: middle; }
.ro-table tbody tr:nth-child(even) td { background: var(--ro-row-alt); }
.ro-table tbody tr:hover td { background: var(--ro-row-hover); }
.ro-table tbody tr.is-selected td, .ro-table tbody tr.is-selected th { background: var(--ro-primary-light); }
.ro-table tbody tr.is-selected > :first-child { box-shadow: inset 3px 0 0 var(--ro-primary); }
.ro-table tbody tr:last-child td, .ro-table tbody tr:last-child th { border-bottom: 0; }
/* Totals stay in view at the foot of the frame. */
.ro-table tfoot td, .ro-table tfoot th { position: sticky; bottom: 0; z-index: 1; background: var(--ro-table-head); font-weight: var(--ro-fw-semibold);
                                         padding: 0.25rem var(--ro-space-3); height: var(--ro-row-h); border-top: 1px solid var(--ro-border); }
.ro-table .ro-num, .ro-table th.ro-num { text-align: right; }
.ro-table tr[data-href] { cursor: pointer; }
.ro-table tr[data-href]:focus-visible { outline-offset: -2px; }
/* A data row reads on one line, as the desktop's grids: a wide table scrolls sideways inside its frame instead of
   squeezing its text columns into several lines. Running text opts in to wrapping (ro-col-text), and so does the value
   beside a label cell (key / value tables). */
.ro-table td { white-space: nowrap; }
.ro-table tbody th ~ td { white-space: normal; overflow-wrap: anywhere; }
.ro-table tbody td.ro-num { white-space: nowrap; }
.ro-table a:not([class]) { font-weight: 500; }
/* Running text keeps every row on one line (owner review 2026-10-08): a note, reason, title or description
   (ro-col-text) ends in an ellipsis at a readable width and shows in full as the cell's tooltip (rebaropt.js). A message
   that must be read where it stands (a validation message, an import or drawing problem, a checklist detail) is
   ro-col-wrap and wraps. */
.ro-table .ro-col-text { min-width: 12rem; max-width: 24rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ro-table .ro-col-wrap { min-width: 16rem; max-width: 32rem; white-space: normal; }
/* A row's actions stay side by side on its line instead of stacking in a narrow column (the views wrap them in
   d-flex flex-wrap, whose wrapping is a Bootstrap !important utility). */
.ro-table td:not(.ro-col-wrap) > .d-flex { flex-wrap: nowrap !important; }
/* A table wider than its frame keeps its first column (the code that names the row) pinned at the left while the
   other columns scroll sideways. rebaropt.js marks the frame is-wide (only when that column is narrow) and
   is-scrolled-x, which draws the pinned column's edge. Row tints, hover and selection still colour the pinned cell. */
.ro-table-wrap.is-wide .ro-table tr > :first-child { position: sticky; left: 0; z-index: 1; }
.ro-table-wrap.is-wide .ro-table thead tr > :first-child { z-index: 3; }
.ro-table-wrap.is-wide .ro-table tfoot tr > :first-child { z-index: 2; }   /* over the pinned totals' neighbours */
:where(.ro-table-wrap.is-wide) .ro-table tbody td:first-child { background-color: var(--ro-surface); }
:where(.ro-table-wrap.is-wide) .ro-table--form tbody tr:hover td:first-child { background-color: var(--ro-surface); }
.ro-table-wrap.is-scrolled-x .ro-table tr > :first-child { box-shadow: var(--ro-shadow-pin); }
.ro-table-wrap.is-scrolled-x .ro-table tbody tr.is-selected > :first-child { box-shadow: inset 3px 0 0 var(--ro-primary), var(--ro-shadow-pin); }
.ro-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ro-unit { color: var(--ro-muted); font-size: var(--ro-fs-sm); margin-left: 0.125rem; }

/* Tabulator: same look as .ro-table */
.tabulator { font-family: var(--ro-font); font-size: var(--ro-fs-base); border: 1px solid var(--ro-border);
             border-radius: var(--ro-radius-lg); background: var(--ro-surface); box-shadow: var(--ro-shadow-xs); }
.tabulator .tabulator-header { background: var(--ro-table-head); border-bottom: 1px solid var(--ro-border); color: var(--ro-text-secondary); }
.tabulator .tabulator-header .tabulator-col { background: var(--ro-table-head); border-right: 1px solid var(--ro-border); }
.tabulator .tabulator-header .tabulator-col .tabulator-col-title { font-size: var(--ro-fs-sm); font-weight: var(--ro-fw-semibold); }
.tabulator .tabulator-tableholder .tabulator-placeholder .tabulator-placeholder-contents { color: var(--ro-muted); font-size: var(--ro-fs-base); font-weight: 400; }
.tabulator-row { min-height: var(--ro-row-h); background: var(--ro-surface); border-bottom: 1px solid var(--ro-border); }
.tabulator-row.tabulator-row-even { background: var(--ro-row-alt); }
.tabulator-row.tabulator-selectable:hover { background: var(--ro-row-hover); }
.tabulator-row.tabulator-selected { background: var(--ro-primary-light); }
.tabulator-row .tabulator-cell { border-right: 1px solid transparent; padding: 0.375rem var(--ro-space-2); }
.tabulator-row .tabulator-cell.tabulator-editing { border: 1px solid var(--ro-primary); padding: 0; }
.tabulator-row .tabulator-cell.ro-cell-error { background: var(--ro-danger-light); }
.tabulator-row .tabulator-cell.ro-cell-warning { background: var(--ro-warning-light); }

/* -----------------------------------------------------------------------------------------------------
   8. Forms layout
   ----------------------------------------------------------------------------------------------------- */
.ro-form { max-width: var(--ro-form-max); }
.ro-form-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr)); gap: var(--ro-space-3) var(--ro-space-4); }
.ro-form-grid .ro-span-all { grid-column: 1 / -1; }
.ro-required::after { content: " *"; color: var(--ro-danger); }
.ro-form-actions { display: flex; flex-wrap: wrap; gap: var(--ro-space-2); justify-content: flex-end;
                   padding-top: var(--ro-space-4); margin-top: var(--ro-space-4); border-top: 1px solid var(--ro-border); }

/* -----------------------------------------------------------------------------------------------------
   9. Feedback: empty state, toasts, loading, progress
   ----------------------------------------------------------------------------------------------------- */
.ro-empty { text-align: center; padding: var(--ro-space-6) var(--ro-space-4); color: var(--ro-text-secondary); }
.ro-empty__icon { display: inline-grid; place-items: center; width: 3.5rem; height: 3.5rem; border-radius: 50%;
                  background: var(--ro-primary-light); color: var(--ro-primary); font-size: 1.5rem; }
.ro-empty__title { font-size: var(--ro-fs-md); font-weight: var(--ro-fw-semibold); color: var(--ro-text); margin: var(--ro-space-3) 0 var(--ro-space-1); }
.ro-empty p { max-width: 34rem; margin: 0 auto var(--ro-space-3); }

.ro-toasts { position: fixed; right: var(--ro-space-4); bottom: calc(var(--ro-statusbar-h) + var(--ro-space-4)); z-index: 1090;
             display: grid; gap: var(--ro-space-2); width: min(24rem, calc(100vw - 2rem)); }
.ro-toast { background: var(--ro-surface); border: 1px solid var(--ro-border); border-left: 4px solid var(--ro-info);
            border-radius: var(--ro-radius); box-shadow: var(--ro-shadow-pop); padding: var(--ro-space-3) var(--ro-space-4); font-size: var(--ro-fs-base);
            animation: ro-toast-in 0.2s ease-out; }
@keyframes ro-toast-in { from { opacity: 0; transform: translateY(0.5rem); } to { opacity: 1; transform: none; } }
.ro-toast--success { border-left-color: var(--ro-success); }
.ro-toast--warning { border-left-color: var(--ro-warning); }
.ro-toast--danger  { border-left-color: var(--ro-danger); }

.ro-progress { height: 8px; background: var(--ro-neutral-light); border-radius: var(--ro-radius-pill); overflow: hidden; }
.ro-progress__bar { height: 100%; background: var(--ro-primary); border-radius: inherit; transition: width 0.3s ease; }
.htmx-indicator { opacity: 0; transition: opacity 0.2s; }
.htmx-request .htmx-indicator, .htmx-request.htmx-indicator { opacity: 1; }

/* -----------------------------------------------------------------------------------------------------
   10. Domain components
   ----------------------------------------------------------------------------------------------------- */
/* Optimization Workflow: 8 gated stages */
.ro-stages { display: grid; grid-template-columns: repeat(8, minmax(0, 1fr)); gap: var(--ro-space-1); margin-bottom: var(--ro-space-4); }
.ro-stage { display: grid; justify-items: center; gap: var(--ro-space-1); padding: var(--ro-space-2) var(--ro-space-1);
            border: 0; background: transparent; border-radius: var(--ro-radius); font-size: var(--ro-fs-xs);
            font-weight: var(--ro-fw-semibold); color: var(--ro-text-secondary); letter-spacing: 0.03em; }
.ro-stage:hover { background: var(--ro-row-hover); }
.ro-stage__dot { width: 2rem; height: 2rem; border-radius: 50%; display: grid; place-items: center; font-size: var(--ro-fs-sm);
                 color: #FFFFFF; background: var(--ro-neutral-light); border: 1px solid var(--ro-border); }
.ro-stage--active .ro-stage__dot    { background: var(--ro-primary); border-color: var(--ro-primary); }
.ro-stage--completed .ro-stage__dot { background: var(--ro-success); border-color: var(--ro-success); }
.ro-stage--warning .ro-stage__dot   { background: var(--ro-warning); border-color: var(--ro-warning); }
.ro-stage--blocked .ro-stage__dot   { background: var(--ro-danger);  border-color: var(--ro-danger); }
.ro-stage--not-started .ro-stage__dot { color: var(--ro-muted); }
.ro-stage.is-selected { background: var(--ro-primary-light); color: var(--ro-primary-dark); }
@media (max-width: 900px) { .ro-stages { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

/* Cutting pattern legend swatches (the bar SVG itself uses these variables) */
.ro-swatch { display: inline-block; width: 0.75rem; height: 0.75rem; border-radius: 2px; vertical-align: -1px; margin-right: 0.3rem; }
.ro-swatch--piece { background: var(--ro-fabricated); }
.ro-swatch--offcut { background: var(--ro-offcut); }
.ro-swatch--scrap { background: var(--ro-scrap); }

/* Cutting pattern bar (_CuttingPatternBar partial): proportional SVG, pieces alternate, residual amber or red */
.ro-pattern { display: block; width: 100%; height: auto; }
.ro-pattern__piece { fill: var(--ro-fabricated); }
.ro-pattern__piece--alt { fill: var(--ro-fabricated-alt); }
.ro-pattern__offcut { fill: var(--ro-offcut); }
.ro-pattern__scrap { fill: var(--ro-scrap); }
.ro-pattern__label { font-family: var(--ro-font); font-size: 11px; fill: #FFFFFF; text-anchor: middle; }
.ro-pattern__label--on-offcut { fill: #3B2A00; }

/* Stored baseline/optimized metrics; SVG geometry is calculated on the server, figures use DisplayFormat. */
.ro-chart { display: block; width: 100%; max-width: 48rem; height: auto; }
.ro-chart__baseline { fill: var(--ro-chart-1); }
.ro-chart__optimized { fill: var(--ro-chart-2); }
.ro-chart__label, .ro-chart__value { font-family: var(--ro-font); font-size: var(--ro-fs-sm); fill: var(--ro-text); }
.ro-chart__value { text-anchor: end; }

/* Bounded, keyboard-accessible content lists keep the surrounding editor actions reachable. */
.ro-scroll-region { max-block-size: var(--ro-scroll-region-max-h); overflow: auto;
                    padding: var(--ro-space-3); border: 1px solid var(--ro-border); border-radius: var(--ro-radius); }
.ro-scroll-region:focus-visible { outline: 2px solid var(--ro-primary); outline-offset: 2px; }

/* -----------------------------------------------------------------------------------------------------
   10a. Notifications (top-bar bell drop-down; tone bar as on the desktop)
   ----------------------------------------------------------------------------------------------------- */
.ro-notices { width: min(26rem, calc(100vw - 2rem)); padding: 0; overflow: hidden; }
.ro-notices__head { display: flex; align-items: center; justify-content: space-between; gap: var(--ro-space-2);
                    padding: var(--ro-space-2) var(--ro-space-3); border-bottom: 1px solid var(--ro-border); font-weight: var(--ro-fw-semibold); }
.ro-notices__list { list-style: none; margin: 0; padding: 0; max-height: 26rem; overflow-y: auto; }
.ro-notices__empty { padding: var(--ro-space-3); color: var(--ro-muted); font-size: var(--ro-fs-sm); }
.ro-notice { display: grid; gap: 0.125rem; width: 100%; text-align: left; background: transparent; border: 0;
             border-left: 3px solid var(--ro-info); padding: var(--ro-space-2) var(--ro-space-3); color: var(--ro-text); }
.ro-notice:hover, .ro-notice:focus-visible { background: var(--ro-row-hover); }
.ro-notice--success { border-left-color: var(--ro-success); }
.ro-notice--warning { border-left-color: var(--ro-warning); }
.ro-notice--danger  { border-left-color: var(--ro-danger); }
.ro-notice--neutral { border-left-color: var(--ro-neutral); }
.ro-notice__title { font-weight: var(--ro-fw-semibold); }
.ro-notice.is-read .ro-notice__title { font-weight: 400; }
.ro-notice__message, .ro-notice__time { font-size: var(--ro-fs-sm); color: var(--ro-muted); }
/* The Notifications page lists more than the drop-down: no inner scroll there. */
.ro-notices__list--page { max-height: none; }

/* -----------------------------------------------------------------------------------------------------
   10b. Pages outside the shell: sign-in and the error page (_LayoutBare)
   ----------------------------------------------------------------------------------------------------- */
.ro-auth { min-height: 100vh; display: grid; place-items: center; padding: var(--ro-space-5) var(--ro-space-4); }
.ro-auth__card { width: min(24rem, 100%); }
.ro-auth__card--wide { width: min(36rem, 100%); }
.ro-auth__brand { display: flex; align-items: center; gap: var(--ro-space-2); font-size: var(--ro-fs-md); font-weight: var(--ro-fw-semibold);
                  color: var(--ro-text); margin-bottom: var(--ro-space-4); }
.ro-auth__brand img { height: 32px; width: auto; }

/* Sign-in: full reinforcement workflow identity and an organization-managed credentials form. */
.ro-auth--login { padding: 0; background: var(--ro-surface); }
.ro-login { display: grid; grid-template-columns: 1.1fr 1fr; width: 100%; min-height: 100vh; min-height: 100svh; }
.ro-login__identity {
  display: flex; flex-direction: column; justify-content: space-between; gap: var(--ro-space-5);
  padding: var(--ro-space-6) clamp(2rem, 5vw, 5rem); color: var(--ro-surface); background: var(--ro-nav);
  background-image: radial-gradient(ellipse at 100% 0%, var(--ro-nav-hover), transparent 65%);
  min-width: 0;
}
.ro-login__brand { display: flex; align-items: center; gap: var(--ro-space-3); font-size: var(--ro-fs-lg); font-weight: var(--ro-fw-semibold); overflow-wrap: anywhere; }
.ro-login__logo { display: grid; place-items: center; width: 48px; height: 48px; flex: 0 0 auto; background: var(--ro-surface); border-radius: var(--ro-radius-lg); }
.ro-login__logo img { width: 34px; height: 34px; object-fit: contain; }
.ro-login__brand-caption { display: block; margin-top: var(--ro-space-1); font-size: var(--ro-fs-sm); font-weight: 400; color: var(--ro-nav-text); }
.ro-login__story { width: 100%; max-width: 36rem; }
.ro-login__eyebrow { display: block; font-size: var(--ro-fs-xs); font-weight: var(--ro-fw-semibold); text-transform: uppercase; letter-spacing: 0.16em; color: var(--ro-muted); }
.ro-login__identity .ro-login__eyebrow { color: var(--ro-nav-text); }
.ro-login__headline { margin: var(--ro-space-4) 0 var(--ro-space-5); font-size: var(--ro-fs-auth-hero); font-weight: var(--ro-fw-semibold); line-height: 1.08; letter-spacing: -0.04em; }
.ro-login__headline > span { color: var(--ro-fabricated-alt); }
.ro-login__description { max-width: 28rem; margin: 0 0 var(--ro-space-5); color: var(--ro-nav-text); font-size: var(--ro-fs-md); line-height: 1.7; }
.ro-login__blueprint { padding: var(--ro-space-4); border: 1px solid var(--ro-nav-dim); border-radius: var(--ro-radius-lg); background: var(--ro-nav-hover); }
.ro-login__drawing-label { display: flex; align-items: center; justify-content: space-between; gap: var(--ro-space-3); color: var(--ro-nav-text); font-size: var(--ro-fs-sm); }
.ro-login__drawing { display: block; width: 100%; height: auto; max-height: 9rem; margin: var(--ro-space-3) 0; }
.ro-login__grid-line { stroke: var(--ro-nav-dim); stroke-opacity: 0.15; stroke-width: 1; }
.ro-login__dimension { stroke: var(--ro-nav-text); stroke-width: 1; }
.ro-login__steel-shadow { stroke: var(--ro-nav); stroke-width: 11; stroke-linejoin: round; stroke-linecap: round; }
.ro-login__steel { stroke: var(--ro-fabricated-alt); stroke-width: 5; stroke-linejoin: round; stroke-linecap: round; }
.ro-login__connector { stroke: var(--ro-nav-text); stroke-width: 1.5; }
.ro-login__cut-piece { fill: var(--ro-fabricated-alt); }
.ro-login__cut-offcut { fill: var(--ro-offcut); }
.ro-login__drawing-key { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ro-space-3); color: var(--ro-nav-text); font-size: var(--ro-fs-xs); }
.ro-login__drawing-key > span { display: inline-flex; align-items: center; gap: var(--ro-space-2); }
.ro-login__drawing-key > span:last-child { margin-left: auto; }
.ro-login__drawing-key i { display: inline-block; width: 8px; height: 8px; border-radius: 2px; }
.ro-login__key-piece { background: var(--ro-fabricated-alt); }
.ro-login__key-offcut { background: var(--ro-offcut); }
.ro-login__workflow { display: flex; justify-content: space-between; flex-wrap: wrap; gap: var(--ro-space-3); padding: 0; margin: var(--ro-space-5) 0 0; list-style: none; color: var(--ro-nav-text); font-size: var(--ro-fs-sm); }
.ro-login__workflow li { display: inline-flex; align-items: center; gap: var(--ro-space-2); }
.ro-login__workflow i { color: var(--ro-fabricated-alt); font-size: var(--ro-fs-base); }
.ro-login__identity-footer { margin: 0; color: var(--ro-nav-text); font-size: var(--ro-fs-sm); }
.ro-login__panel { display: flex; flex-direction: column; justify-content: center; align-items: center; position: relative; padding: 5rem clamp(1.5rem, 5vw, 5rem); min-width: 0; background: var(--ro-surface); }
.ro-login__form-wrap { width: 100%; max-width: 24rem; }
.ro-login__title { font-size: var(--ro-fs-auth-title); font-weight: var(--ro-fw-semibold); line-height: 1.2; letter-spacing: -0.025em; margin: var(--ro-space-3) 0; }
.ro-login__intro { color: var(--ro-text-secondary); line-height: 1.65; margin-bottom: var(--ro-space-6); }
.ro-login__field { margin-bottom: var(--ro-space-5); }
.ro-login__field .form-label { margin-bottom: var(--ro-space-2); color: var(--ro-text); font-size: var(--ro-fs-base); font-weight: 500; }
.ro-login__input { position: relative; }
.ro-login__input > i { position: absolute; top: 50%; left: var(--ro-space-4); transform: translateY(-50%); color: var(--ro-muted); pointer-events: none; font-size: var(--ro-fs-md); }
.ro-login__input .form-control { min-height: 48px; padding-left: 2.75rem; border-radius: var(--ro-radius); }
.ro-login__input--password .form-control { padding-right: 3rem; }
.ro-login__input .form-control::placeholder { color: var(--ro-muted); opacity: 1; }
.ro-login__password-toggle { position: absolute; right: var(--ro-space-1); top: 50%; transform: translateY(-50%); display: grid; place-items: center; width: 40px; height: 40px; padding: 0; border: 0; border-radius: var(--ro-radius-sm); background: transparent; color: var(--ro-text-secondary); font-size: var(--ro-fs-md); }
.ro-login__password-toggle[hidden] { display: none; }
.ro-login__password-toggle:hover { color: var(--ro-primary-dark); background: var(--ro-row-hover); }
.ro-login__password-toggle:focus-visible { outline: 2px solid var(--ro-primary); outline-offset: 1px; }
.ro-login__submit { display: flex; align-items: center; justify-content: center; gap: var(--ro-space-3); width: 100%; min-height: 48px; font-weight: var(--ro-fw-semibold); }
.ro-login__help { display: flex; align-items: flex-start; gap: var(--ro-space-3); padding-top: var(--ro-space-5); margin-top: var(--ro-space-6); border-top: 1px solid var(--ro-border); color: var(--ro-text-secondary); font-size: var(--ro-fs-sm); line-height: 1.7; }
.ro-login__help > i { font-size: var(--ro-fs-md); color: var(--ro-muted); }
.ro-login__help p { margin: 0; }
.ro-login__help strong { color: var(--ro-text); font-weight: var(--ro-fw-semibold); }
.ro-login__access { display: flex; align-items: center; gap: var(--ro-space-2); color: var(--ro-muted); font-size: var(--ro-fs-sm); margin: var(--ro-space-5) 0 0; }
.ro-login__footer { position: absolute; bottom: var(--ro-space-5); left: var(--ro-space-5); right: var(--ro-space-5); text-align: center; color: var(--ro-muted); font-size: var(--ro-fs-xs); overflow-wrap: anywhere; }
.ro-login__footer > span { margin: 0 var(--ro-space-2); }
/* The living reference demonstrates the component within the normal application shell. */
.ro-login--specimen { min-height: auto; border: 1px solid var(--ro-border); border-radius: var(--ro-radius-lg); overflow: hidden; }
.ro-login--specimen .ro-login__identity { padding: var(--ro-space-6); }
.ro-login--specimen .ro-login__headline { font-size: var(--ro-fs-auth-title); }
.ro-login--specimen .ro-login__panel { padding: var(--ro-space-6); }
@media (max-width: 1100px) {
  .ro-login__headline { font-size: calc(var(--ro-fs-auth-title) + var(--ro-fs-md)); }
  .ro-login__identity { padding: var(--ro-space-6); }
  .ro-login__panel { padding-right: var(--ro-space-6); padding-left: var(--ro-space-6); }
}
@media (max-width: 767.98px) {
  .ro-login { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
  .ro-login__identity { padding: var(--ro-space-5); gap: var(--ro-space-5); }
  .ro-login__story { margin: 0; }
  .ro-login__headline { margin: var(--ro-space-3) 0; font-size: var(--ro-fs-auth-title); }
  .ro-login__headline br { display: none; }
  .ro-login__description { margin-bottom: 0; font-size: var(--ro-fs-base); max-width: none; }
  .ro-login__blueprint, .ro-login__workflow, .ro-login__identity-footer { display: none; }
  .ro-login__panel { justify-content: flex-start; padding: var(--ro-space-6) var(--ro-space-5) 5rem; }
  .ro-login__title { font-size: var(--ro-fs-kpi); }
  .ro-login__intro { margin-bottom: var(--ro-space-5); }
}

/* -----------------------------------------------------------------------------------------------------
   10c. Wave 1 components: section list, tree, wizard steps, code block, prose, logo preview, text KPI
   ----------------------------------------------------------------------------------------------------- */
/* Section list: a vertical list of the sections of one page (Settings, Help). The current one is .active. */
.ro-sections { list-style: none; margin: 0; padding: var(--ro-space-1); background: var(--ro-surface); border: 1px solid var(--ro-border);
               border-radius: var(--ro-radius-lg); box-shadow: var(--ro-shadow-card); }
.ro-sections a { display: block; padding: var(--ro-space-2) var(--ro-space-3); border-radius: var(--ro-radius); color: var(--ro-text); text-decoration: none; }
.ro-sections a:hover { background: var(--ro-row-hover); }
.ro-sections a.active { background: var(--ro-primary-light); color: var(--ro-primary-dark); font-weight: var(--ro-fw-semibold); }

/* Tree: nested lists of links (Project Structure). The kind is a muted label; the selected node is .is-selected. */
.ro-tree, .ro-tree ul { list-style: none; margin: 0; padding: 0; }
.ro-tree ul { margin-left: var(--ro-space-3); padding-left: var(--ro-space-4); border-left: 1px solid var(--ro-border); }
.ro-tree a { display: inline-flex; align-items: baseline; gap: var(--ro-space-2); padding: var(--ro-space-1) var(--ro-space-2);
             border-radius: var(--ro-radius); color: var(--ro-text); text-decoration: none; }
.ro-tree a:hover { background: var(--ro-row-hover); }
.ro-tree a.is-selected { background: var(--ro-primary-light); color: var(--ro-primary-dark); }
.ro-tree__kind { font-size: var(--ro-fs-xs); font-weight: var(--ro-fw-semibold); color: var(--ro-muted); text-transform: uppercase; letter-spacing: 0.03em; }

/* Wizard steps (setup wizard): a bar over each step, blue for the current one, green with a tick once done. */
.ro-steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr)); gap: var(--ro-space-2); list-style: none;
            margin: 0 0 var(--ro-space-4); padding: 0; }
.ro-step { border-top: 4px solid var(--ro-border); padding-top: var(--ro-space-2); font-size: var(--ro-fs-sm); color: var(--ro-text-secondary); }
.ro-step__num { font-weight: var(--ro-fw-semibold); margin-right: var(--ro-space-1); }
.ro-step--active { border-top-color: var(--ro-primary); color: var(--ro-text); font-weight: var(--ro-fw-semibold); }
.ro-step--completed { border-top-color: var(--ro-success); }

/* Code block: log lines and stored values, monospaced, wrapped, scrolling past 24rem. */
.ro-code-block { font-family: var(--ro-font-mono); font-size: var(--ro-fs-sm); background: var(--ro-header-band); color: var(--ro-text);
                 border: 1px solid var(--ro-border); border-radius: var(--ro-radius); padding: var(--ro-space-2) var(--ro-space-3);
                 max-height: 24rem; overflow: auto; white-space: pre-wrap; word-break: break-word; margin: 0; }

/* Prose: running text such as help topics, at a readable line length. */
.ro-prose { max-width: 48rem; }
.ro-prose p { margin: 0 0 var(--ro-space-3); }

/* Logo preview (Settings, setup wizard). */
.ro-logo-preview { display: block; max-height: 80px; max-width: min(20rem, 100%); width: auto; padding: var(--ro-space-2);
                   background: var(--ro-surface); border: 1px solid var(--ro-border); border-radius: var(--ro-radius-sm); }

/* A KPI whose value is a short text (a run code) rather than a figure. */
.ro-kpi__value--text { font-size: var(--ro-fs-lg); }

/* -----------------------------------------------------------------------------------------------------
   10d. Wave 2 components: form table, shape drawing, shape cards, segment type
   ----------------------------------------------------------------------------------------------------- */
/* Form table: a table whose cells hold inputs (diameter overrides, import mappings, the shape designer's segments).
   The rows grow to the small inputs; the inputs fill their cells. */
.ro-table--form td { padding-top: 0.1875rem; padding-bottom: 0.1875rem; }
.ro-table--form td .form-control { min-width: 5rem; }
.ro-table--form td .form-select { min-width: 9rem; }
.ro-table--form tbody tr:hover td { background: inherit; }

/* Shape drawing: an SVG drawing of a bar shape (an <img> of the server's SVG) on a white frame, scaled to the width. */
.ro-shape { background: var(--ro-surface); border: 1px solid var(--ro-border); border-radius: var(--ro-radius); padding: var(--ro-space-2); }
.ro-shape img { display: block; width: 100%; height: auto; }
.ro-shape--thumb { padding: var(--ro-space-1); }
.ro-shape--thumb img { aspect-ratio: 16 / 10; object-fit: contain; }
.ro-shape--row { width: 6rem; }
.ro-shape__empty { display: grid; place-items: center; aspect-ratio: 16 / 10; color: var(--ro-muted); font-size: var(--ro-fs-sm); text-align: center; }

/* Shape cards: the Shape Library's card view; each card opens the shape. */
.ro-shape-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr)); gap: var(--ro-space-3); list-style: none; margin: 0; padding: 0; }
.ro-shape-card { display: grid; gap: var(--ro-space-2); height: 100%; padding: var(--ro-space-2); background: var(--ro-surface); border: 1px solid var(--ro-border);
                 border-radius: var(--ro-radius-lg); box-shadow: var(--ro-shadow-card); }
.ro-shape-card:hover { border-color: var(--ro-primary); }
.ro-shape-card__title { display: flex; align-items: baseline; gap: var(--ro-space-2); color: var(--ro-text); text-decoration: none; font-weight: var(--ro-fw-semibold); }
.ro-shape-card__title:hover { color: var(--ro-primary-dark); }
.ro-shape-card__meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ro-space-1) var(--ro-space-2); font-size: var(--ro-fs-sm); color: var(--ro-muted); }
.ro-shape-card.is-inactive { opacity: 0.7; }

/* Segment type (Custom Shape Editor): a bend row is indented under its straight so the bar reads as a sequence. */
.ro-segment-bend td:nth-child(2) { padding-left: var(--ro-space-5); }

/* -----------------------------------------------------------------------------------------------------
   Wave 3: bar bending schedules
   ----------------------------------------------------------------------------------------------------- */
/* Detail list: label above value, in a narrow column (the desktop's DetailLabel blocks: comparison, row detail). */
.ro-details { display: grid; gap: var(--ro-space-1) 0; margin: 0; }
.ro-details dt { font-size: var(--ro-fs-xs); font-weight: var(--ro-fw-semibold); color: var(--ro-text-secondary); text-transform: uppercase; letter-spacing: 0.02em; margin-top: var(--ro-space-2); }
.ro-details dt:first-child { margin-top: 0; }
.ro-details dd { margin: 0; overflow-wrap: anywhere; }

/* Row tint of a read-only table, from the row's meaning (comparison: added, removed, unchanged); the text says it too. */
.ro-table tbody tr.ro-row--success td { background: var(--ro-success-light); }
.ro-table tbody tr.ro-row--danger td { background: var(--ro-danger-light); }
.ro-table tbody tr.ro-row--warning td { background: var(--ro-warning-light); }
.ro-table tbody tr.ro-row--muted td { color: var(--ro-muted); }
.ro-table tbody tr.ro-row--success.is-selected td, .ro-table tbody tr.ro-row--danger.is-selected td,
.ro-table tbody tr.ro-row--warning.is-selected td { background: var(--ro-primary-light); }

/* A long list of ticks read down in columns (export columns, column chooser). */
.ro-columns { columns: 2 14rem; column-gap: var(--ro-space-5); }
.ro-columns > * { break-inside: avoid; }

/* A small label above a control that sits among detail lists (BBS Entry header's revision picker). */
.ro-details-label { display: block; font-size: var(--ro-fs-xs); font-weight: var(--ro-fw-semibold); color: var(--ro-text-secondary);
                    text-transform: uppercase; letter-spacing: 0.02em; margin-bottom: var(--ro-space-1); }

/* Status line: counts and totals, as the desktop's grid footer. Attached under the table or grid it sums; elsewhere
   (after a pager) a small panel of its own (UI refresh). */
.ro-statusline { display: flex; flex-wrap: wrap; gap: var(--ro-space-1) var(--ro-space-5); padding: var(--ro-space-2) var(--ro-space-3);
                 background: var(--ro-header-band); border: 1px solid var(--ro-border); border-radius: var(--ro-radius-lg);
                 margin-top: var(--ro-space-2); font-size: var(--ro-fs-sm); color: var(--ro-text-secondary); }
:is(.ro-table-wrap, .ro-entry) + .ro-statusline { border-top: 0; border-radius: 0 0 var(--ro-radius-lg) var(--ro-radius-lg); margin-top: 0; }
.ro-table-wrap:has(+ .ro-statusline) { margin-bottom: 0; border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.ro-statusline strong { color: var(--ro-text); font-variant-numeric: tabular-nums; }

/* A list with one selected item that buttons act on (column chooser: tick to show, Up / Down to order). */
.ro-pick-list { list-style: none; margin: 0; padding: 0; border: 1px solid var(--ro-border); border-radius: var(--ro-radius); max-height: 24rem; overflow-y: auto; }
.ro-pick-list li { display: flex; align-items: center; gap: var(--ro-space-2); padding: var(--ro-space-1) var(--ro-space-3); border-bottom: 1px solid var(--ro-border); cursor: pointer; }
.ro-pick-list li:last-child { border-bottom: 0; }
.ro-pick-list li:hover { background: var(--ro-row-hover); }
.ro-pick-list li.is-selected { background: var(--ro-primary-light); }

/* Editable grid cells (Tabulator): a dimension the line's shape needs; a small drawing in a cell; a cell waiting for
   the server's recalculation. */
.tabulator-row .tabulator-cell.ro-cell-needed { box-shadow: inset 0 -2px 0 var(--ro-primary); }
.tabulator-row .tabulator-cell.ro-cell-pending { color: var(--ro-muted); }
.tabulator-row .tabulator-cell .ro-cell-thumb { display: block; height: 1.75rem; width: 100%; object-fit: contain; cursor: zoom-in; }
.tabulator .tabulator-group { background: var(--ro-header-band); border-bottom: 1px solid var(--ro-border); font-weight: var(--ro-fw-semibold); }

/* -----------------------------------------------------------------------------------------------------
   11. Accessibility, motion, print, small screens
   ----------------------------------------------------------------------------------------------------- */
:focus-visible { outline: 2px solid var(--ro-primary); outline-offset: 2px; }
.ro-nav a:focus-visible, .ro-nav button:focus-visible, .ro-topbar__brand:focus-visible { outline-color: #FFFFFF; outline-offset: -2px; }
.ro-topbar__btn:focus-visible { outline-offset: -2px; }
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition: none !important; animation: none !important; } }

@media (max-width: 1199.98px) {
  /* Narrow desktop: the top bar's actions show their icons (each keeps its title and accessible name), so the project
     selector keeps a readable width. */
  .ro-topbar__project { flex-basis: 18rem; }
  .ro-topbar__btn-text { display: none; }
}
@media (max-width: 991.98px) {
  .ro-shell { grid-template-columns: minmax(0, 1fr); }
  .ro-nav { position: fixed; left: 0; top: var(--ro-topbar-h); bottom: var(--ro-statusbar-h); width: var(--ro-nav-w); z-index: 1040;
            transform: translateX(-100%); transition: transform 0.2s ease; height: auto; }
  .ro-shell.nav-open .ro-nav { transform: none; box-shadow: var(--ro-shadow-pop); }
  /* Tablet: the menu is a drawer, so the brand is just the logo on the bar; Help is its icon, so the project selector
     and search keep their room. */
  .ro-topbar { padding-left: var(--ro-space-2); }
  .ro-topbar__brand { flex: 0 0 auto; width: auto; margin: 0; padding: 0 var(--ro-space-1); background: transparent; }
  .ro-topbar__brand-text, .ro-topbar__btn-text { display: none; }
  .ro-main { --ro-gutter: var(--ro-space-4); }
}
.ro-nav-toggle { display: none; }
@media (max-width: 991.98px) { .ro-nav-toggle { display: inline-flex; } }

@media (max-width: 575.98px) {
  /* Phone: one filter per line, the full width of the panel. */
  form.ro-toolbar[method="get" i] > :is(.form-control, .form-select, label:not(.form-label, .form-check-label, .form-check)) { flex: 1 1 100%; }
  .ro-topbar { gap: var(--ro-space-1); padding: 0 var(--ro-space-2); }
  .ro-topbar__project { flex: 1 1 auto; }
  .ro-topbar__project .form-select { min-width: 0; }
  .ro-topbar__btn { padding-inline: var(--ro-space-2); flex-shrink: 0; }
  .ro-topbar__btn--icon { padding-inline: 0; }
  .ro-topbar__spacer, .ro-topbar__divider, .ro-topbar__caret { display: none; }
  .ro-main { --ro-gutter: var(--ro-space-3); }
}

@media print {
  .ro-topbar, .ro-nav, .ro-statusbar, .ro-page-actions, .ro-toolbar { display: none !important; }
  .ro-shell { display: block; height: auto; overflow: visible; }
  .ro-main { display: block; }
  .ro-page-workspace { overflow: visible; padding: 0; }
  .ro-page-workspace > .ro-guide-page > .ro-page-header { position: static; box-shadow: none; margin-inline: 0; padding-inline: 0; }
  .ro-table-wrap { max-height: none !important; overflow: visible; box-shadow: none; }
  .ro-table thead th, .ro-table tfoot td, .ro-table tfoot th { position: static; }
  .ro-table tr > :first-child { position: static !important; box-shadow: none !important; }   /* no pinned column on paper */
  .ro-table .ro-col-text { white-space: normal; overflow: visible; max-width: 32rem; }   /* paper has no tooltip */
  .ro-card, .ro-kpi { box-shadow: none; }
}
