/* GENERATED by tools/tint/build.mjs from resources/dist/css/cs.css (sha1 fc355bf2f27ba6ccae88a3032132935309e4b1ab), tint "neutral". Don't edit; run the script. */
/*
 * CrewSuite compact styles (cs.css). Bootstrap 5.3 from the CDN plus these rules; no build
 * step. Every house class starts with cs- and every token with --cs-. Keep the order: the
 * nested-form shading (further down) must follow the depth-and-forms block it refines.
 * Read DESIGN.md (in this package) before adding a rule; when you add a colour,
 * write its contrast ratio in a comment (WCAG AA: 4.5:1, 3:1 for large text).
 */

:root {
    --cs-font-size-base: .9375rem;
    --cs-font-size-sm: .75rem;
    --cs-font-size-lg: 1.125rem;
    --bs-body-font-family: "Arimo", Arial, sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue"; /* Arimo: Arial's letter widths, with real 500 / 600 / 700 */
    --bs-body-font-size: var(--cs-font-size-base);
}

/* [Proposed, October 16] Shades and tints: the only way to step a surface lighter or darker than the one under it.
 * A fixed colour at a fixed transparency over the base, never a new tinted hex, so a step looks the same on any base
 * (white, the page, the blue form well): a field box and a detail grid on the same panel are the same shade. A step is
 * a background (or a border or an inset shadow) of one of these over whatever is under it. Where the box must hide what
 * scrolls or opens under it (a sticky cell, a menu), the step is a layer over an opaque base:
 * background: linear-gradient(var(--cs-shade-2), var(--cs-shade-2)) #fff. The deliberate base colours stay colours:
 * the page, white cards, the steel heads, the parent-card navy, the blue form well, badge, row-state and status tones,
 * and the accent tints that mark a selected or current item.
 * [Proposed, October 16, evening] Two families, never mixed on one surface (Design §3.3):
 *   --cs-shade-*       steel: every UI surface (heads, tabs, bars, wells, panels, nests, field boxes, facts, menus,
 *                      hovers on controls). Steel blue rgb(15, 70, 124) over white gives the kit's steel greys:
 *                      #f7f7f7, #f1f1f1, #eaeaea, #e0e0e0, and keeps a blue well blue-grey.
 *   --cs-data-shade-*  neutral grey: the rows of a data result only (a stripe, a row hover, a subtotal, a drill-down
 *                      well, a result row or list item hover, a timeline entry). Black over white.
 * Nothing is a warm grey. */
:root {
    --cs-shade-1: rgba(55, 55, 55, 0.04); /* the lightest step: a read-only detail grid, a head bar's top */
    --cs-shade-2: rgba(55, 55, 55, 0.07); /* one step: a field box, a nested container, a control's hover, a child table's head */
    --cs-shade-3: rgba(64, 64, 64, 0.11); /* a label area (facts, log facts), a pressed menu item, a progress track */
    --cs-shade-4: rgba(61, 61, 61, 0.16); /* the strongest: a parent card's well, a step's hairline */
    --cs-data-shade-1: rgba(0, 0, 0, .03); /* a row stripe, a timeline entry */
    --cs-data-shade-2: rgba(0, 0, 0, .05); /* a row pointed at */
    --cs-data-shade-3: rgba(0, 0, 0, .08); /* a timeline entry's border */
    --cs-data-shade-4: rgba(0, 0, 0, .12); /* a subtotal row, a drill-down row's well */
    --cs-tint-1: rgba(255, 255, 255, .4);
    --cs-tint-2: rgba(255, 255, 255, .6); /* a tab pointed at, an Add button's foot */
    --cs-tint-3: rgba(255, 255, 255, .8); /* an Add button's top */
}

h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
    font-family: "Jost", -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
    font-weight: 500;
}

b, strong { font-weight: 500; }
small, .small { font-size: 80%; }
.text-sm { font-size: var(--cs-font-size-sm); }
.text-lg { font-size: var(--cs-font-size-lg); }

.text-gray { color: #646464 !important; } /* 5.9:1 on white, 4.9:1 on the deepest form well (was #747474, 3.8:1 there) */
.text-dgray { color: #646464 !important; }
.bg-light { background: var(--cs-shade-1) !important; }
.nav-tabs .nav-link.active { background-color: #ececec; }

/* ---------------------------------------------------------------------------
 * The shell: left sidebar of modules, top bar with search.
 * Same density on every page (the compact scale above).
 * ------------------------------------------------------------------------- */
:root {
    --cs-sidebar-w: 232px;
    --cs-rail-w: 52px; /* [Proposed, October 16] the collapsed sidebar: a rail of icons, the pancake's width */
    --cs-side-now: var(--cs-sidebar-w); /* what the page makes room for: the sidebar, or the rail when collapsed */
    --cs-bar-h: 50px;
    --cs-nav-bg: #1b1b1b;
    --cs-nav-fg: #c2c2c2;
    --cs-nav-active: #ffffff;
    --cs-nav-hover: #2b2b2b;
    --cs-accent: #3578be;
    --cs-page-bg: #f5f5f5;
    --cs-border: #e4e4e4;
    --cs-muted: #585858; /* 5.2:1 on the tinted wells (was #696969) */
}
body.cs-body { background: var(--cs-page-bg); }
.cs-sidebar { position: fixed; inset: var(--cs-bar-h) auto 0 0; width: var(--cs-sidebar-w); background: var(--cs-nav-bg); color: var(--cs-nav-fg); overflow-y: auto; z-index: 1030; }
.cs-nav { list-style: none; margin: 0; padding: 10px 8px 24px; }
.cs-nav .section { font-size: .68rem; letter-spacing: .08em; text-transform: uppercase; color: #9e9e9e; /* 5.0:1 on the sidebar */ padding: 14px 10px 4px; }
.cs-nav a { display: flex; align-items: center; gap: .6rem; padding: 6px 10px; border-radius: 6px; color: var(--cs-nav-fg); text-decoration: none; font-size: .86rem; }
.cs-nav a:hover { background: var(--cs-nav-hover); color: #fff; }
.cs-nav a.active { background: var(--cs-accent); color: var(--cs-nav-active); }
.cs-nav a .bi { font-size: 1rem; width: 1.1rem; text-align: center; }
.cs-nav a .count { margin-left: auto; background: #c62f2a; color: #fff; border-radius: 10px; font-size: .68rem; padding: 1px 7px; }
.cs-nav a.active .count { background: #fff; color: var(--cs-accent); }

/* A settings-style sub-menu: sections grouped under small headers, like the sidebar. */
.cs-settings-nav { padding: 6px 6px 10px; }
.cs-settings-nav-head { font-size: .68rem; letter-spacing: .08em; text-transform: uppercase; color: var(--cs-muted); font-weight: 600; padding: 12px 10px 4px; border-top: 1px solid var(--cs-border); margin-top: 6px; }
.cs-settings-nav-link { display: flex; align-items: center; gap: .55rem; padding: 5px 10px; border-radius: 6px; color: #2f2f2f; text-decoration: none; }
.cs-settings-nav-link .bi { width: 1rem; text-align: center; color: var(--cs-muted); }
.cs-settings-nav-link:hover { background: var(--cs-shade-2); color: #2f2f2f; } /* 11.8:1 */
.cs-settings-nav-link.active { background: var(--cs-accent); color: #fff; }
.cs-settings-nav-link.active .bi { color: #fff; }
.cs-settings-group-title { font-size: .72rem; letter-spacing: .08em; text-transform: uppercase; color: var(--cs-muted); font-weight: 600; margin: 18px 0 8px; }
.cs-settings-group-title:first-child { margin-top: 0; }
.cs-main { margin-left: var(--cs-side-now); min-height: calc(100vh - var(--cs-bar-h)); display: flex; flex-direction: column; }
.cs-content { padding: 20px; flex: 1; }

/* Top bar: black and full width, shared by every CrewSuite app */
body.cs-has-bar { padding-top: var(--cs-bar-h); }
.cs-topbar { position: fixed; top: 0; left: 0; right: 0; height: var(--cs-bar-h); z-index: 1035; background: #000; color: #fff; border-bottom: 1px solid #212121; display: flex; align-items: center; gap: 12px; padding: 0 16px 0 0; }
/* [Proposed] App name first, search right after it. The brand lines up with the sidebar when it fits and grows when the name is longer: never cropped. */
.cs-brand { display: flex; align-items: center; gap: 10px; flex-shrink: 0; min-width: calc(var(--cs-sidebar-w) - 12px); padding-right: 8px; }
.cs-brand img { display: block; }
/* [Proposed, October 16] The brand, left to right: the pancake (the sidebar toggle), the company mark ("ODC", text in a
 * web font, a link to ODC Home), a 2px rule, then the app's wordmark or app switcher. The mark and its rule come from
 * config('crewsuite.wordmark.mark'); an app without one (Commence) shows the pancake, then its wordmark.
 * The pancake is the old logo's four bars, drawn in CSS: as tall as the mark's capitals, as wide as the rail below it. */
.cs-pancake { flex: none; align-self: stretch; display: flex; align-items: center; justify-content: center; width: var(--cs-rail-w); margin-right: -6px; padding: 0; border: 0; background: none; color: #dbdbdb; } /* 13.6:1 on black */
.cs-pancake > i { display: block; width: 21px; height: 15px; background: repeating-linear-gradient(180deg, currentColor 0 3px, transparent 3px 4px); transform-origin: left; transition: transform .18s ease; }
.cs-pancake:hover, .cs-pancake:focus-visible { background: #2b2b2b; color: #fff; }
.cs-pancake:focus-visible { outline: 2px solid #a5c6ec; outline-offset: -2px; }
.cs-pancake[aria-expanded="false"] > i { transform: scaleX(.72); } /* collapsed: the bars shorten toward the sidebar's side */
.cs-mark { flex: none; color: #dbdbdb; font: 800 21px/1 Montserrat, "Open Sans", Arial, sans-serif; letter-spacing: -.01em; text-decoration: none; white-space: nowrap; } /* the old logo's grey, 13.6:1 */
a.cs-mark:hover { color: #fff; }
.cs-brand-rule { flex: none; width: 2px; height: 22px; background: rgba(255, 255, 255, .35); }
.cs-wordmark { color: #fff; font-family: "Open Sans", "Segoe UI", "Helvetica Neue", Arial, sans-serif; font-weight: 700; font-size: 21px; line-height: 1; letter-spacing: -.02em; text-transform: uppercase; text-decoration: none; white-space: nowrap; }
.cs-wordmark > span { font-weight: 300; }
a.cs-wordmark:hover { color: #fff; opacity: .85; }
.cs-bar-btn { color: #dbdbdb; background: transparent; border: 1px solid #3b3b3b; } /* [Proposed, October 16] the bar's darks are the sidebar's navy, not neutral */
.cs-bar-btn:hover, .cs-bar-btn:focus { color: #fff; background: #2b2b2b; border-color: #545454; }
.cs-bar-note { color: #9e9e9e; font-size: .86rem; }
.cs-bar-actions { display: flex; align-items: center; gap: 8px; margin-left: auto; flex-shrink: 0; }
/* [Proposed, October 20] The app's own controls in the bar (CrewSuite::shell's 'bar' views), left of the primary action and
 * Help: light words on the black bar; a switch sized to the bar, its knob light while it is off. */
.cs-bar-app { display: flex; align-items: center; gap: 6px; color: #dbdbdb; font-size: .8rem; white-space: nowrap; }
.cs-bar-app .form-check { display: flex; align-items: center; gap: 6px; min-height: 0; margin: 0; padding-left: 0; }
.cs-bar-app .form-check-input { float: none; flex: none; margin: 0; background-color: #212121; border-color: #545454; cursor: pointer; }
.cs-bar-app .form-switch .form-check-input:not(:checked) { --bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%239e9e9e'/%3e%3c/svg%3e"); }
.cs-bar-app .form-check-input:checked { background-color: var(--cs-accent); border-color: var(--cs-accent); }
.cs-bar-app .form-check-label { color: #dbdbdb; cursor: pointer; } /* 12.6:1 on black */
.cs-bar-app .cs-help { color: #9e9e9e; border-color: #545454; background: transparent; }
/* The user menu is a tab pulled out of the bar: the toggle fills the bar's height and darkens when
 * pointed at or open; the menu (data-bs-display="static", no Popper) hangs from the bar's bottom edge,
 * because .cs-user is position: static and the fixed bar is what it's placed against. */
.cs-user { flex-shrink: 0; align-self: stretch; display: flex; position: static; }
.cs-user-toggle { display: flex; align-items: center; gap: 8px; height: 100%; padding: 0 12px; margin-right: -16px; color: #fff; text-decoration: none; font-size: .875rem; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; }
.cs-user-toggle:hover, .cs-user-toggle:focus, .cs-user-toggle.show { color: #fff; background: #2b2b2b; }
.cs-user-toggle .cs-avatar { box-shadow: 0 0 0 1px #ffffff55; }
.cs-user .dropdown-menu[data-bs-popper] { top: 100%; right: 0; margin-top: 0; min-width: 15rem; border-top: 0; border-radius: 0 0 8px 8px; box-shadow: 0 10px 24px #0f1c2833; padding-top: 0; }
.cs-user-head { display: flex; gap: 10px; align-items: center; padding: 10px 14px; margin-bottom: 4px; border-bottom: 1px solid var(--cs-border); }
.cs-user-head > div { min-width: 0; }
.cs-user-head .name { font-weight: 600; color: #2b2b2b; }
.cs-user-head .email { font-size: .75rem; color: var(--cs-muted); overflow-wrap: anywhere; }
/* The colour tint, picked in the user menu (Design §3.6): three choices in one segmented row, the person's own marked. */
.cs-tint-pick { padding: 6px 14px 8px; }
.cs-tint-label { display: flex; align-items: center; gap: 6px; font-size: .72rem; font-weight: 600; color: var(--cs-muted); margin-bottom: 5px; }
.cs-tint-opts { display: flex; border: 1px solid var(--cs-field-border); border-radius: 6px; overflow: hidden; }
.cs-tint-opts > button { flex: 1 1 0; display: inline-flex; align-items: center; justify-content: center; gap: 5px; border: 0; border-left: 1px solid var(--cs-field-border); background: #fff; padding: 4px 6px; font-size: .78rem; color: #2b2b2b; }
.cs-tint-opts > button:first-child { border-left: 0; }
.cs-tint-opts > button:hover { background: var(--cs-shade-2); }
.cs-tint-opts > button[aria-checked="true"] { background: var(--cs-shade-3); font-weight: 600; box-shadow: inset 0 -2px 0 var(--cs-accent); }
.cs-tint-opts > button:focus-visible { outline: 2px solid var(--cs-accent); outline-offset: -2px; }
.cs-tint-opts > button:disabled { opacity: .6; }
.cs-tint-opts .dot { width: 10px; height: 10px; border-radius: 50%; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .15); }
.cs-tint-status { margin-left: auto; font-weight: 400; color: #a52834; }
@media (max-width: 991.98px) { .cs-brand { min-width: 0; } }
@media (max-width: 575.98px) { .cs-wordmark { display: none; } .cs-topbar { gap: 6px; padding: 0 8px 0 0; } .cs-pancake { width: 44px; } .cs-brand { gap: 8px; } .cs-topbar .cs-bar-btn[title] { display: none; } .cs-user-toggle { margin-right: -8px; padding: 0 8px; } }
@media (max-width: 991.98px) {
    .cs-sidebar { transform: translateX(-100%); transition: transform .2s ease; }
    .cs-sidebar.show { transform: none; }
    .cs-main { margin-left: 0; }
    .cs-content { padding: 14px; }
}
/* The top bar's search, when an app has one (its own Livewire component, CrewSuite §6.6): a ready look an app may use. */
.cs-search { position: relative; flex: 1; max-width: 560px; min-width: 0; }
.cs-search input { padding-left: 2rem; }
.cs-topbar .cs-search input { background: #212121; border-color: #3b3b3b; color: #fff; }
.cs-topbar .cs-search input::placeholder { color: #9e9e9e; } /* 6.1:1 */
.cs-topbar .cs-search input:focus { background: #fff; color: #2b2b2b; border-color: #fff; }
.cs-search .bi-search { position: absolute; left: .65rem; top: 50%; transform: translateY(-50%); color: #9e9e9e; z-index: 1; }
.cs-search-results { position: absolute; top: calc(100% + 4px); left: 0; right: 0; background: #fff; border: 1px solid var(--cs-border); border-radius: 8px; box-shadow: 0 8px 24px #0002; max-height: 70vh; overflow-y: auto; z-index: 1040; }
.cs-search-results .group { font-size: .68rem; text-transform: uppercase; letter-spacing: .06em; color: var(--cs-muted); padding: 8px 12px 2px; }
.cs-search-results a { display: flex; gap: .6rem; align-items: center; padding: 6px 12px; color: inherit; text-decoration: none; font-size: .86rem; }
.cs-search-results a:hover, .cs-search-results a:focus { background: var(--cs-shade-2); }
/* Notice ribbons under the top bar (a demo copy, a testing period, a stand-in): one rule, a tone for meaning. */
.cs-ribbon { --rb-bg: #f1f1f1; --rb-fg: #393939; --rb-border: #dfdfdf; display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 6px 12px; background: var(--rb-bg); color: var(--rb-fg); font-size: .78rem; padding: 3px 8px; border-bottom: 1px solid var(--rb-border); }
.cs-ribbon.tone-warn { --rb-bg: #fff4d6; --rb-fg: #7a5b00; --rb-border: #f1e0a6; } /* 6.1:1 */
.cs-ribbon.tone-info { --rb-bg: #eaf1f8; --rb-fg: #2e5075; --rb-border: #cedbeb; } /* 7.3:1 */
.cs-ribbon.tone-bad { --rb-bg: #8a3b12; --rb-fg: #fff; --rb-border: #8a3b12; justify-content: space-between; font-size: .8rem; padding: 5px 12px; } /* 7.7:1 */
.cs-ribbon .cs-help { color: inherit; opacity: .85; }
.cs-ribbon form { margin: 0 0 0 auto; }

/* Page building blocks */
.cs-page-header { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 12px; margin-bottom: 16px; }
.cs-page-header h1 { font-size: 1.35rem; margin: 0; }
.cs-page-header .sub { color: var(--cs-muted); font-size: .86rem; margin-top: 2px; }
.cs-card { background: #fff; border: 1px solid #dfdfdf; border-radius: 10px; box-shadow: var(--cs-shadow-1); margin-bottom: 16px; }
.cs-card > .head { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 5px 12px; min-height: 36px; border-bottom: 1px solid #525252; border-radius: 9px 9px 0 0; background: linear-gradient(180deg, #676767, #525252); color: #fff; } /* white 5.6:1 at the top, 7.8:1 at the foot */
.cs-card > .head h2 { font-size: .95rem; margin: 0; font-family: Jost, sans-serif; color: #fff; }
.cs-card > .head .hint { color: #e8e8e8; font-size: .78rem; } /* 4.6:1 on the lightest part of the head */
/* [Proposed] Card heads are one line: the hint sits beside the title, not under it, so a head is about 36px, not 58px.
 * Only a container (a card holding cards) keeps the taller two-line head. */
.cs-card > .head > div:first-child { display: flex; flex-wrap: nowrap; align-items: baseline; gap: 0 10px; min-width: 0; flex: 1 1 auto; }
.cs-card > .head > div:first-child > h2 { flex: 0 0 auto; white-space: nowrap; }
.cs-card > .head > div:first-child > .hint { flex: 1 1 0; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* full hint in title="" */
.cs-card > .head h2 { line-height: 1.3; }
.cs-card:has(> .body .cs-card) > .head { padding: 10px 14px; align-items: flex-start; }
.cs-card:has(> .body .cs-card) > .head > div:first-child { display: block; }
.cs-card:has(> .body .cs-card) > .head > div:first-child > .hint { white-space: normal; }
/* [Proposed] A light rule between a card head and the table headings (or chips) under it: 1px, like every table line (October 15). */
.cs-card > .head + .body.flush { border-top: 1px solid #e4e4e4; }
/* What sits on a steel head: light icons, links and help bubbles; buttons, badges and fields keep their own look. */
.cs-card > .head :is(.text-dgray, .text-gray, .text-muted) { color: #e4e4e4 !important; }
.cs-card > .head a:not(.btn):not(.dropdown-item) { color: #e1ecf8; } /* 4.7:1 */
.cs-card > .head .cs-help { color: #e4e4e4; }
.cs-card > .head .cs-help:hover, .cs-card > .head .cs-help[aria-expanded="true"] { color: #fff; }
.cs-card > .head .form-label, .cs-card > .head .form-check-label { color: #fff; }
.cs-card > .body { padding: 14px; }
.cs-card > .body.flush { padding: 0; }
.cs-stat { background: #fff; border: 1px solid var(--cs-border); border-radius: 10px; padding: 12px 14px; display: flex; gap: 12px; align-items: flex-start; height: 100%; text-decoration: none; color: inherit; }
a.cs-stat:hover { border-color: var(--cs-accent); }
.cs-stat .icon { width: 38px; height: 38px; border-radius: 9px; display: flex; align-items: center; justify-content: center; font-size: 1.15rem; flex-shrink: 0; }
.cs-stat .value { font-size: 1.4rem; font-weight: 600; line-height: 1.1; }
.cs-stat .label { color: var(--cs-muted); font-size: .8rem; }
/* [Proposed] Stat tiles line up (October 15): every tile the same height, the value on one baseline (one line), the label
 * up to two lines in a two-line space every tile keeps (the whole label in the callout when it is longer), and a row kept
 * for the hint (one line) whether a tile has one or not. */
.cs-stat > :not(.icon) { flex: 1 1 auto; min-width: 0; display: grid; grid-template-rows: auto auto 1.45rem; align-content: start; }
.cs-stat .value { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cs-stat .label { white-space: normal; line-height: 1.25; height: 2.5em; overflow: hidden; } /* two lines, reserved */
.cs-stat > :not(.icon) > .cs-badge { justify-self: start; align-self: end; max-width: 100%; margin-top: 0 !important; overflow: hidden; text-overflow: ellipsis; }
.cs-stat .cs-badge { white-space: nowrap; }
.cs-tone-blue .icon { background: #e7f0fa; color: #3578be; }
.cs-tone-green .icon { background: #e3f5ea; color: #1e7a45; }
.cs-tone-amber .icon { background: #fff2d9; color: #a86b00; }
.cs-tone-red .icon { background: #fde6e5; color: #c0322d; }
.cs-tone-slate .icon { background: var(--cs-shade-3); color: #515151; } /* the neutral tone is a plain step on the white tile: 6.6:1 */
.cs-empty { text-align: center; color: var(--cs-muted); padding: 28px 16px; }
.cs-empty > .bi { font-size: 1.8rem; display: block; margin-bottom: 6px; color: #a5a5a5; }
.cs-avatar { position: relative; overflow: hidden; display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; color: #fff; font-weight: 600; flex-shrink: 0; line-height: 1; }
.cs-avatar > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.cs-list { list-style: none; margin: 0; padding: 0; }
.cs-list > li { display: flex; align-items: center; gap: 10px; padding: 9px 14px; border-bottom: 1px solid var(--cs-border); }
.cs-list > li:last-child { border-bottom: 0; }
.cs-list > li .grow { flex: 1; min-width: 0; }
.cs-list .title { font-weight: 500; }
.cs-list .meta { color: var(--cs-muted); font-size: .78rem; }
/* [Proposed] Tabs that look like tabs, ported from the reference app's tabs (October 15): each tab is a raised folder tab on
   one baseline; the selected one is white, bold and topped with the accent, and sits over the line
   so it joins what's under it. An unselected tab is one shade (--cs-shade-2) darker than what it sits on, and readable:
   #383838 9.4:1 on the page (October 16: was #eaeaea). */
.cs-tabs { display: flex; gap: 4px; align-items: flex-end; border-bottom: 1px solid #cbcbcb; margin-bottom: 12px; padding: 0 2px; flex-wrap: wrap; }
.cs-tabs > a, .cs-tabs > button:not(.cs-help) { display: inline-flex; align-items: center; gap: 6px; background: var(--cs-shade-2); border: 1px solid #d5d5d5; border-bottom: 0; border-radius: 7px 7px 0 0; padding: 6px 13px 6px; color: #383838; text-decoration: none; font-size: .86rem; line-height: 1.3; position: relative; top: 1px; }
.cs-tabs > a:hover, .cs-tabs > button:not(.cs-help):hover { background: var(--cs-tint-2); color: #2b2b2b; } /* lighter than what it's on: 18:1 on the page */
.cs-tabs > a.active, .cs-tabs > button:not(.cs-help).active { background: #fff; color: #2b2b2b; font-weight: 600; border-color: #cbcbcb; box-shadow: inset 0 3px 0 var(--cs-accent); padding-top: 7px; }
.cs-tabs > a:focus-visible, .cs-tabs > button:not(.cs-help):focus-visible { outline: 2px solid var(--cs-accent); outline-offset: -2px; }
.cs-tabs > .cs-help { align-self: center; margin-left: 4px; }
.cs-tabs .badge, .cs-tabs .cs-badge { font-weight: 500; }
.cs-tabs .btn-group .btn, .cs-tabs .form-select { white-space: nowrap; }
@media (max-width: 575.98px) {
    .cs-tabs { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: thin; }
    .cs-tabs > a, .cs-tabs > button:not(.cs-help) { white-space: nowrap; }
}
/* A second row inside a tab: a segmented row of pills, so the two levels read apart (buttons too, which the reference app's rule left out). */
.cs-tabs.cs-subtabs { border-bottom: 0; gap: 6px; padding: 0; align-items: center; }
.cs-tabs.cs-subtabs > :is(a, button:not(.cs-help)) { top: 0; background: #fff; border: 1px solid #d5d5d5; border-radius: 999px; padding: 3px 11px; font-size: .8rem; }
.cs-tabs.cs-subtabs > :is(a, button:not(.cs-help)).active { background: #eff3f8; border-color: var(--cs-accent); box-shadow: none; padding-top: 3px; }
/* dl.cs-kv (a record's facts, read-only) is a grid of split-box facts: see "Read-only facts" in the Round 7 block. */
.cs-filter-bar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 12px; }
.cs-filter-bar .form-control, .cs-filter-bar .form-select { width: auto; min-width: 160px; }
.cs-filter-bar .grow { flex: 1; min-width: 220px; }
.cs-filter-bar-grouped { flex-direction: column; align-items: stretch; gap: 6px; }
/* [Proposed] The date range field and its panel (<x-cs.date-range>): quick ranges, then Custom's two calendars. */
.cs-dr { position: relative; display: inline-block; min-width: 15.5rem; }
.cs-dr-field { position: relative; }
.cs-dr-icon { position: absolute; left: 8px; top: 50%; transform: translateY(-50%); color: #666666; font-size: .8rem; pointer-events: none; }
.cs-dr .cs-dr-input { width: 100% !important; min-width: 0; padding-left: 26px !important; padding-right: 22px !important; cursor: pointer; background-color: #fff !important; }
.cs-dr-clear { position: absolute; right: 2px; top: 50%; transform: translateY(-50%); border: 0; background: none; color: #666666; padding: 0 4px; line-height: 1; }
.cs-dr-clear:hover { color: var(--cs-text, #262626); }
.cs-dr-panel { position: absolute; z-index: 1060; top: calc(100% + 4px); left: 0; display: flex; gap: 10px; background: #fff; border: 1px solid var(--cs-form-border, #d1d1d1); border-radius: 8px; box-shadow: 0 8px 24px rgba(27, 27, 27, 0.18); padding: 8px; width: max-content; max-width: calc(100vw - 24px); }
.cs-dr-ranges { list-style: none; margin: 0; padding: 0; min-width: 11rem; }
.cs-dr-ranges button { display: block; width: 100%; text-align: left; border: 1px solid transparent; background: #f6f6f6; border-radius: 4px; padding: 3px 8px; margin-bottom: 3px; font-size: .8rem; color: var(--cs-text, #262626); white-space: nowrap; }
.cs-dr-ranges button:hover, .cs-dr-ranges button:focus-visible { background: #e9e9e9; }
.cs-dr-ranges button.active { background: var(--cs-accent, #1067b6); color: #fff; }
.cs-dr-custom { display: flex; flex-direction: column; gap: 6px; }
.cs-dr-calendars { display: flex; gap: 12px; flex-wrap: wrap; }
.cs-dr-cal-head { display: flex; align-items: center; gap: 4px; margin-bottom: 4px; }
.cs-dr-cal-head .form-select { width: auto; min-width: 0; padding-top: 1px; padding-bottom: 1px; font-size: .78rem; }
.cs-dr-nav { border: 0; background: none; padding: 0 4px; color: #515151; }
.cs-dr-grid { border-collapse: collapse; font-size: .78rem; }
.cs-dr-grid th { font-weight: 600; color: #666666; text-align: center; width: 28px; padding: 2px 0; }
.cs-dr-grid .wk { color: #949494; font-size: .7rem; text-align: center; width: 24px; }
.cs-dr-grid td { padding: 1px; text-align: center; }
.cs-dr-grid td button { width: 28px; height: 24px; border: 0; border-radius: 4px; background: none; color: var(--cs-text, #262626); font-size: .78rem; }
.cs-dr-grid td button:hover:not(:disabled) { background: #e9e9e9; }
.cs-dr-grid td button.off { color: #a3a3a3; }
.cs-dr-grid td button.today { font-weight: 700; text-decoration: underline; }
.cs-dr-grid td button.in-range { background: #e1ebf6; border-radius: 0; }
.cs-dr-grid td button.start, .cs-dr-grid td button.end { background: var(--cs-accent, #1067b6); color: #fff; }
.cs-dr-grid td button:disabled { color: #cacaca; text-decoration: line-through; cursor: not-allowed; }
.cs-dr-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; border-top: 1px solid #e7e7e7; padding-top: 6px; }
.cs-dr-typed { display: inline-flex; align-items: center; gap: 4px; font-size: .78rem; color: #515151; margin: 0; }
.cs-dr-typed .form-control { width: 7.5rem; }
.cs-dr-time.form-control { width: 6.5rem; }
.cs-dr-error { color: #b42318; font-size: .78rem; }
@media (max-width: 575.98px) {
    .cs-dr { display: block; flex: 1 1 100%; width: 100%; min-width: 0; }
    .cs-dr-panel { flex-direction: column; left: 0; right: auto; width: auto; }
    .cs-dr-ranges { display: flex; flex-wrap: wrap; gap: 4px; min-width: 0; }
    .cs-dr-ranges button { margin-bottom: 0; }
}
@media print { .cs-dr-panel, .cs-dr-clear, .cs-dr-icon { display: none !important; } .cs-dr-input { padding-left: 0 !important; border: 0; } }
/* [Proposed] Filters grouped by the table they search (<x-cs.filter-group>): the table's word set vertically on the left. */
.cs-filter-group { display: flex; align-items: stretch; gap: 8px; }
/* [Proposed, October 20] Each group sits on a slight tint of its own, so the groups read apart at a glance (was a dashed line). */
.cs-filter-bar-grouped > .cs-filter-group { padding: 5px 8px 5px 5px; background: var(--cs-shade-2); border-radius: 6px; }
.cs-filter-group-label { flex: 0 0 auto; display: flex; align-items: flex-start; justify-content: center; width: 18px; border-right: 2px solid var(--cs-accent); padding-right: 2px; }
.cs-filter-group-label > span { writing-mode: vertical-rl; transform: rotate(180deg); font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: #515151; white-space: nowrap; line-height: 1; }
.cs-filter-group-body { flex: 1; display: flex; flex-wrap: wrap; gap: 8px; align-items: center; min-width: 0; }
.cs-progress { height: 6px; background: var(--cs-shade-3); border-radius: 3px; overflow: hidden; }
.cs-progress > span { display: block; height: 100%; background: #1e7a45; }
/* Tables are compact (about 24px rows); a report adds .cs-table-dense (further down) for about 20px. */
.cs-table { font-size: .8rem; margin: 0; }
.cs-table > :not(caption) > * > * { padding: 3px 8px; }
.cs-table > thead > tr > th { --bs-table-bg: #e6e6e6; --bs-table-color: #2b2b2b; background-image: linear-gradient(180deg, #ededed, #e0e0e0); font-weight: 600; white-space: nowrap; position: sticky; top: 0; z-index: 2; box-shadow: inset 0 -1px 0 #c0c0c0; } /* [Proposed] head B (October 15): one light steel head for every table, list and report; #2b2b2b 10.6:1 at the foot */
.cs-table > thead :is(.text-dgray, .text-gray, .text-muted) { color: #515151 !important; } /* 6.0:1 at the foot */
.cs-table > tbody > tr:nth-child(even):not(.cs-subtotal, .cs-total, .cs-drill-open, .cs-drill-row, .is-deleted, .is-archived, .cs-subhead) > * { background-image: linear-gradient(var(--cs-data-shade-1), var(--cs-data-shade-1)); } /* the stripe: a shade over the cell's own (opaque) base, so a sticky cell still hides what scrolls under it */
/* [Proposed, October 22] A row pointed at: a see-through light yellow laid over every cell as Bootstrap's inset fill (the
 * box-shadow .table-hover paints above a cell's background and stripe), so it reads apart from the grey stripe and still shows
 * a cell's own colour (a status, a sticky column) through it. Was one grey shade, which the stripe swallowed. */
.cs-table { --bs-table-hover-bg: rgba(255, 214, 10, .2); }
.cs-table td { vertical-align: middle; }
.cs-table .cs-badge { padding-top: 0; padding-bottom: 0; }
.cs-card .table-responsive { border-radius: 0 0 10px 10px; }
.cs-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; }
.cs-list a.title, .cs-card a.fw-semibold, .cs-stat a { text-decoration: none; }
.cs-list a.title:hover { text-decoration: underline; }
/* [Proposed] A row's name is bold dark text, not link blue (October 15): blue is for links in prose. Pointing at it or
 * tabbing to it underlines it in the link colour. #2b2b2b 13.4:1 on the stripe; #215e9b 5.8:1 on the hover tint. */
:is(.cs-table td, .cs-table tbody th) a.fw-semibold, .cs-table > tbody > tr > :is(td, th):first-child > a:not(.btn):not(.dropdown-item),
.cs-table .cs-grid-sticky > a:not(.btn), .cs-list a.title, .cs-row > .name a, .cs-split-list a.fw-semibold { color: #2b2b2b; text-decoration: none; }
:is(:is(.cs-table td, .cs-table tbody th) a.fw-semibold, .cs-table > tbody > tr > :is(td, th):first-child > a:not(.btn):not(.dropdown-item),
.cs-table .cs-grid-sticky > a:not(.btn), .cs-list a.title, .cs-row > .name a, .cs-split-list a.fw-semibold):is(:hover, :focus-visible) { color: var(--bs-link-color); text-decoration: underline; text-underline-offset: 2px; }

/* ? help bubbles and knowledge base articles */
.cs-help { border: 0; background: none; padding: 0 2px; margin-left: 2px; color: var(--cs-muted); font-size: .85em; line-height: 1; vertical-align: baseline; cursor: pointer; }
.cs-help:hover, .cs-help[aria-expanded="true"] { color: var(--cs-accent); }
.cs-help:focus-visible { outline: 2px solid var(--cs-accent); outline-offset: 1px; border-radius: 50%; }
.cs-help.missing { color: #c62828; border: 1px dashed #c62828; border-radius: 50%; padding: 0 4px; font-size: .7rem; cursor: help; }
.cs-help-bubble { position: absolute; z-index: 1080; max-width: 320px; background: #262626; color: #f2f2f2; border-radius: 8px; padding: 10px 12px; font-size: .8125rem; line-height: 1.4; box-shadow: 0 8px 24px #0004; }
.cs-help-bubble .title { font-weight: 600; margin-bottom: 4px; color: #fff; }
.cs-help-bubble a { display: inline-block; margin-top: 8px; color: #a5c6ec; }
.cs-kb { font-size: .92rem; line-height: 1.6; max-width: 52rem; }
.cs-kb h1, .cs-kb h2, .cs-kb h3 { margin-top: 1.4em; scroll-margin-top: calc(var(--cs-bar-h) + 16px); }
.cs-kb h2 { font-size: 1.15rem; border-bottom: 1px solid var(--cs-border); padding-bottom: 4px; }
.cs-kb h3 { font-size: 1rem; }
.cs-kb > :first-child { margin-top: 0; }
.cs-kb table { width: 100%; border-collapse: collapse; margin: 0 0 1rem; font-size: .86rem; }
.cs-kb th, .cs-kb td { border: 1px solid var(--cs-border); padding: 4px 8px; vertical-align: top; }
.cs-kb th { background: var(--cs-shade-1); }
.cs-kb code { color: #424242; background: var(--cs-shade-2); padding: 0 3px; border-radius: 3px; }
.cs-kb blockquote { border-left: 3px solid var(--cs-accent); padding-left: 10px; color: var(--cs-muted); }

/* A drawer that slides in from the right */
.cs-drawer-backdrop { position: fixed; inset: 0; background: #0f1c2840; z-index: 1044; }
.cs-drawer { position: fixed; top: 0; right: 0; bottom: 0; width: min(480px, 100vw); background: var(--cs-page-bg); z-index: 1045; overflow-y: auto; padding: 16px; box-shadow: -8px 0 24px #0003; }
.cs-drawer .cs-card { margin-bottom: 12px; }
/* [Proposed, October 20] The large panel (<x-cs.overlay>, Design §9.4): the one exception to "no modals", for one record's
 * large data that needs more room than the drawer (a PO's line items beside its CrewBid materials). 90% of the view over
 * a backdrop that closes it; its head stays put while its body scrolls, and the page behind doesn't scroll. Above the
 * drawer; menus, popups and callouts inside it still open over it (their layers count inside the panel). */
.cs-overlay-root { display: contents; }
.cs-overlay-backdrop { position: fixed; inset: 0; background: #0f1c2866; z-index: 1046; }
.cs-overlay { position: fixed; top: 5vh; left: 5vw; width: 90vw; height: 90vh; z-index: 1047; display: flex; flex-direction: column; background: var(--cs-page-bg); border-radius: 10px; box-shadow: 0 16px 48px #0f1c2859; overflow: hidden; }
.cs-overlay > .cs-overlay-head { flex: none; display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 6px 10px 6px 16px; background: #fff; border-bottom: 1px solid #e4e4e4; }
.cs-overlay-head > .title { min-width: 0; display: flex; align-items: baseline; gap: 10px; }
.cs-overlay-head > .title > h2 { margin: 0; font-size: 1rem; font-weight: 600; color: #2b2b2b; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cs-overlay-head > .title > .sub { color: #585858; font-size: .8rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* 7.0:1 */
.cs-overlay-head > .tools { margin-left: auto; flex: none; display: flex; align-items: center; gap: 8px; }
.cs-overlay > .cs-overlay-body { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 16px; }
html:has(.cs-overlay) { overflow: hidden; } /* the page behind stays where it was */
@media (max-width: 575.98px) { .cs-overlay { inset: 0; width: auto; height: auto; border-radius: 0; } }
@media print { .cs-overlay-backdrop { display: none !important; } .cs-overlay { position: static; width: auto; height: auto; box-shadow: none; overflow: visible; } .cs-overlay > .cs-overlay-body { overflow: visible; } }
.cs-chip { display: inline-flex; align-items: center; gap: 4px; border: 1px solid var(--cs-border); background: #fff; border-radius: 999px; padding: 2px 10px; font-size: .8rem; }
.cs-chip.added { border-color: #1e7a45; background: #eaf6ef; }
.cs-chip.removed { text-decoration: line-through; color: var(--cs-muted); background: var(--cs-shade-1); }

/* ---------------------------------------------------------------------------
 * Depth and forms. Cards lift off the page; a card holding fields becomes a slightly
 * recessed tinted well with white fields set into it (any card body with a field, so new
 * forms get it too); filter bars match. Inside a form, groups of related fields sit on
 * raised white panels (.cs-panel) with a header strip and a coloured edge.
 * ------------------------------------------------------------------------- */
:root {
    --cs-shadow-1: 0 1px 2px rgba(26, 26, 26, 0.07), 0 2px 8px rgba(35, 35, 35, 0.05);
    --cs-shadow-2: 0 2px 4px rgba(30, 30, 30, 0.08), 0 8px 20px rgba(33, 33, 33, 0.09);
    --cs-shadow-child: 0 1px 2px rgba(26, 26, 26, 0.14), 0 3px 8px rgba(30, 30, 30, 0.12); /* [Proposed] child cards and form panels (October 15) */
    --cs-form-bg: #ececec;
    --cs-form-bg-2: #e5e5e5;
    --cs-form-border: #d1d1d1;
    --cs-field-border: #b2b2b2;
    --cs-panel-border: #d9d9d9;
    --cs-tone-give: #1e7a45;
    --cs-tone-take: #c05f00;
    --cs-tone-info: #3578be;
}

.cs-card > .body:has(input:not([type="hidden"]), select, textarea) {
    background: linear-gradient(180deg, var(--cs-form-bg), var(--cs-form-bg-2));
    box-shadow: inset 0 3px 5px -3px var(--cs-shade-4);
    border-radius: 0 0 9px 9px;
}
.cs-card > .body:first-child:has(input:not([type="hidden"]), select, textarea) { border-radius: 9px; box-shadow: inset 0 1px 3px var(--cs-shade-3); }
.cs-card:has(> .body input:not([type="hidden"]), > .body select, > .body textarea) { border-color: var(--cs-form-border); }
.cs-filter-bar { background: linear-gradient(180deg, var(--cs-form-bg), var(--cs-form-bg-2)); border: 1px solid var(--cs-form-border); border-radius: 10px; padding: 8px 10px; box-shadow: var(--cs-shadow-1); }

/* Fields: white, a firmer border and a faint inner shadow, so each reads as a box to fill in */
:is(.cs-card, .cs-filter-bar, .cs-drawer) :is(.form-control, .form-select):not(:focus):not(.is-invalid):not(.is-valid) { border-color: var(--cs-field-border); box-shadow: inset 0 1px 2px rgba(30, 30, 30, 0.08); }
:is(.cs-card, .cs-filter-bar, .cs-drawer) :is(.form-control, .form-select):not(:disabled):not([readonly]) { background-color: #fff; }
:is(.cs-card, .cs-filter-bar, .cs-drawer) .form-check-input:not(:checked):not(.is-invalid) { border-color: #999999; }
:is(.cs-card, .cs-filter-bar) .input-group-text { background: linear-gradient(var(--cs-shade-4), var(--cs-shade-4)) #fff; border-color: var(--cs-field-border); color: #515151; } /* part of the control: a step over white wherever it is, 6.0:1 */
.cs-card > .body :is(.form-label, .form-check-label) { color: #393939; }

/* Raised white panels grouping fields inside a form */
.cs-panel { --tone: var(--cs-panel-border); background: #fff; border: 1px solid var(--cs-panel-border); border-left: 4px solid var(--tone); border-radius: 8px; box-shadow: var(--cs-shadow-child); } /* [Proposed] a little more lift (October 15) */
.cs-panel.tone-give { --tone: var(--cs-tone-give); }
.cs-panel.tone-take { --tone: var(--cs-tone-take); }
.cs-panel.tone-info { --tone: var(--cs-tone-info); }
.cs-panel + .cs-panel { margin-top: 10px; }
.cs-panel-head { display: flex; align-items: center; gap: 8px; padding: 8px 12px; background: linear-gradient(180deg, var(--cs-shade-1), var(--cs-shade-2)); border-bottom: 1px solid var(--cs-shade-3); border-radius: 0 7px 0 0; font-size: .78rem; font-weight: 600; color: #393939; } /* a step over the white panel: 10.3:1 at the foot */
.cs-panel-head .bi { color: var(--tone); }
.cs-panel-body { padding: 12px; }
.cs-step-no { width: 24px; height: 24px; border-radius: 50%; background: var(--tone); color: #fff; font-size: .75rem; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; box-shadow: 0 1px 2px rgba(27, 27, 27, 0.25); }

/* Section headings inside a form, with a rule running to the edge */
.cs-section-title { --tone: var(--cs-tone-info); display: flex; align-items: center; gap: 8px; margin: 18px 0 8px; font-size: .74rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: #393939; }
.cs-section-title::after { content: ""; flex: 1; height: 1px; background: var(--cs-form-border); }
.cs-section-title.tone-give { --tone: var(--cs-tone-give); }
.cs-section-title.tone-take { --tone: var(--cs-tone-take); }
.cs-section-title .dot { width: 24px; height: 24px; border-radius: 50%; background: var(--tone); color: #fff; display: inline-flex; align-items: center; justify-content: center; font-size: .8rem; box-shadow: 0 1px 2px rgba(27, 27, 27, 0.25); }
.cs-subhead { font-size: .72rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--cs-muted); margin: 12px 0 6px; }

/* A small table of rows, e.g. the details a record keeps: a step over what it sits on, its lines a step darker
 * still (translucent, so they darken with the base: a grid of fields is a shade darker, and so are its lines). */
.cs-detail-grid { border: 1px solid var(--cs-shade-3); border-radius: 6px; background: var(--cs-shade-1); padding: 4px 8px; }
.cs-detail-head { font-size: .68rem; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--cs-muted); padding: 4px 0; border-bottom: 1px solid var(--cs-shade-3); }
.cs-detail-row { padding: 5px 0; border-bottom: 1px dashed var(--cs-shade-3); }
.cs-detail-row:last-child { border-bottom: 0; }
.cs-detail-grid .cs-empty-row { color: var(--cs-muted); padding: 6px 0; }

/* "Add …" buttons: dashed until you point at them */
.btn-add { border: 1px dashed #9f9f9f; color: #515151; background: var(--cs-tint-2); }
.btn-add:hover, .btn-add:focus { border-style: solid; border-color: var(--cs-accent); color: var(--cs-accent); background: #fff; }

/* The reason-and-save bar at the foot of an editor */
.cs-savebar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 16px; padding: 10px 12px; background: #fff; border: 1px solid var(--cs-panel-border); border-radius: 8px; box-shadow: var(--cs-shadow-1); }
.cs-savebar .form-control { flex: 1; min-width: 220px; }

/* Tiles that open something lift when pointed at */
.cs-tile { background: #fff; border: 1px solid var(--cs-panel-border); border-radius: 8px; padding: 10px 12px; box-shadow: 0 1px 2px rgba(35, 35, 35, 0.05); transition: box-shadow .15s, transform .15s, border-color .15s; }
.cs-tile:hover { box-shadow: var(--cs-shadow-2); transform: translateY(-1px); border-color: #cbcbcb; }
.cs-tile-icon { width: 36px; height: 36px; border-radius: 9px; display: inline-flex; align-items: center; justify-content: center; font-size: 1.15rem; background: #e7f0fa; color: var(--cs-accent); flex-shrink: 0; }
.cs-section-title.mt-0 { margin-top: 0 !important; }

/* ---------------------------------------------------------------------------
 * Buttons: compact (Bootstrap's are roomy) and raised — a soft gradient, a darker
 * bottom edge and a small shadow; they lift when pointed at and press in when clicked.
 * Fields are the same heights, so a button beside a field lines up: small 26px,
 * regular 30px.
 * ------------------------------------------------------------------------- */
.btn { --bs-btn-padding-y: .33rem; --bs-btn-padding-x: .7rem; --bs-btn-font-size: .8125rem; --bs-btn-line-height: 1.35; }
.btn-sm, .btn-group-sm > .btn { --bs-btn-padding-y: .22rem; --bs-btn-padding-x: .55rem; --bs-btn-font-size: .78rem; --bs-btn-border-radius: .3rem; }
.btn-group-sm > .btn { --bs-btn-padding-y: .16rem; } /* [Proposed] toggle and filter groups are slim: 24px, not 26 (October 15) */
.btn-lg, .btn-group-lg > .btn { --bs-btn-padding-y: .4rem; --bs-btn-padding-x: .9rem; --bs-btn-font-size: .9375rem; }
.btn-xs, .btn-group-xs > .btn { --bs-btn-padding-y: .1rem; --bs-btn-padding-x: .4rem; --bs-btn-font-size: .72rem; --bs-btn-border-radius: .25rem; }
.btn .bi { font-size: 1.05em; line-height: 1; }

.btn:not(.btn-link):not(.btn-close) {
    --cs-btn-lift: inset 0 1px 0 rgba(255, 255, 255, .28), inset 0 -1px 0 rgba(30, 30, 30, 0.12);
    background-image: linear-gradient(180deg, rgba(255, 255, 255, .16), rgba(255, 255, 255, 0) 55%, rgba(38, 38, 38, 0.06));
    box-shadow: var(--cs-btn-lift), 0 1px 2px rgba(27, 27, 27, 0.18);
    transition: color .15s, background-color .15s, border-color .15s, box-shadow .15s, transform .1s;
}
.btn:not(.btn-link):not(.btn-close):hover { box-shadow: var(--cs-btn-lift), 0 2px 6px rgba(30, 30, 30, 0.2); transform: translateY(-1px); }
.btn:not(.btn-link):not(.btn-close):is(:active, .active, .show) { background-image: linear-gradient(180deg, rgba(30, 30, 30, 0.08), rgba(NaN, NaN, NaN, 0) 60%); box-shadow: inset 0 2px 4px rgba(30, 30, 30, 0.24); transform: none; }
.btn:not(.btn-link):not(.btn-close):focus-visible { box-shadow: var(--bs-btn-focus-box-shadow), 0 1px 2px rgba(27, 27, 27, 0.18); }
.btn:not(.btn-link):not(.btn-close):is(:disabled, .disabled) { box-shadow: none; transform: none; }
/* Outline and light buttons are white-to-grey at rest, so they read as buttons, not boxes */
.btn:is([class*="btn-outline-"], .btn-light):not(:hover):not(:active):not(.active):not(.show):not(.btn-check:checked + *) { background-color: #fff; background-image: linear-gradient(180deg, #fff, #f0f0f0); }
.btn-light { --bs-btn-border-color: #d5d5d5; --bs-btn-hover-bg: #ececec; --bs-btn-hover-border-color: #c4c4c4; --bs-btn-active-bg: #e3e3e3; }
/* [Proposed, October 22] Buttons coloured by what they do (Design §8.4), so no button is white on a white row or card: the
 * one-action buttons in a row or a head say their kind by colour. Contrast is for the white (or dark) icon and words. */
.btn-edit { /* Edit (into CrewTime and the like): legacy's green pencil, which people know on sight; white 2.5:1, 3.4:1 on hover */
    --bs-btn-color: #fff; --bs-btn-bg: #5cb85c; --bs-btn-border-color: #4cae4c;
    --bs-btn-hover-color: #fff; --bs-btn-hover-bg: #449d44; --bs-btn-hover-border-color: #398439;
    --bs-btn-active-color: #fff; --bs-btn-active-bg: #398439; --bs-btn-active-border-color: #255625; --bs-btn-focus-shadow-rgb: 76, 174, 76;
}
.btn-menu { /* a menu (⋯, ▾): grey with a white icon, 4.7:1 */
    --bs-btn-color: #fff; --bs-btn-bg: #747474; --bs-btn-border-color: #6a6a6a;
    --bs-btn-hover-color: #fff; --bs-btn-hover-bg: #626262; --bs-btn-hover-border-color: #5d5d5d;
    --bs-btn-active-color: #fff; --bs-btn-active-bg: #5d5d5d; --bs-btn-active-border-color: #575757; --bs-btn-focus-shadow-rgb: 137, 137, 137;
}
.btn-xls { /* a spreadsheet: Excel's green, 6.1:1 */
    --bs-btn-color: #fff; --bs-btn-bg: #1d6f42; --bs-btn-border-color: #185c37;
    --bs-btn-hover-color: #fff; --bs-btn-hover-bg: #185c37; --bs-btn-hover-border-color: #134a2c;
    --bs-btn-active-color: #fff; --bs-btn-active-bg: #134a2c; --bs-btn-active-border-color: #0f3b23; --bs-btn-focus-shadow-rgb: 29, 111, 66;
}
.btn-pdf { /* a PDF: a document red, darker than Delete's (btn-danger), 6.4:1 */
    --bs-btn-color: #fff; --bs-btn-bg: #b3261e; --bs-btn-border-color: #9b2019;
    --bs-btn-hover-color: #fff; --bs-btn-hover-bg: #941f19; --bs-btn-hover-border-color: #7e1a15;
    --bs-btn-active-color: #fff; --bs-btn-active-bg: #7e1a15; --bs-btn-active-border-color: #6a1612; --bs-btn-focus-shadow-rgb: 179, 38, 30;
}
.btn-notes { /* notes: the note yellow (.cs-note), dark amber words 7.0:1 */
    --bs-btn-color: #6b4e00; --bs-btn-bg: #ffe8a3; --bs-btn-border-color: #e9c96b;
    --bs-btn-hover-color: #5a4100; --bs-btn-hover-bg: #ffdf80; --bs-btn-hover-border-color: #dcb94f;
    --bs-btn-active-color: #5a4100; --bs-btn-active-bg: #f7d36a; --bs-btn-active-border-color: #cfa93a; --bs-btn-focus-shadow-rgb: 233, 201, 107;
}
.btn-open { /* open, view or details: the link blue on a light blue tint, 5.9:1 */
    --bs-btn-color: #22609f; --bs-btn-bg: #e8f1fa; --bs-btn-border-color: #9fbada;
    --bs-btn-hover-color: #fff; --bs-btn-hover-bg: #22609f; --bs-btn-hover-border-color: #1d5288;
    --bs-btn-active-color: #fff; --bs-btn-active-bg: #1d5288; --bs-btn-active-border-color: #184674; --bs-btn-focus-shadow-rgb: 34, 96, 159;
}
.btn-clear { /* Clear Search and Clear All: a light red tint, the words 6.3:1, so it reads as a reset without Delete's weight */
    --bs-btn-color: #a52834; --bs-btn-bg: #fdecee; --bs-btn-border-color: #f1b9bf;
    --bs-btn-hover-color: #fff; --bs-btn-hover-bg: #a52834; --bs-btn-hover-border-color: #8e222d;
    --bs-btn-active-color: #fff; --bs-btn-active-bg: #8e222d; --bs-btn-active-border-color: #7a1d26; --bs-btn-focus-shadow-rgb: 165, 40, 52;
}
:is(.btn-edit, .btn-menu, .btn-xls, .btn-pdf) > .bi { color: inherit; }
.btn-add:not(:hover):not(:focus) { background-image: linear-gradient(180deg, var(--cs-tint-3), var(--cs-tint-2)); }
.cs-topbar .btn.cs-bar-btn:not(:hover):not(:active) { background-image: linear-gradient(180deg, #323232, #212121); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .08), 0 1px 2px rgba(0, 0, 0, .5); }

/* Fields at the button heights */
.form-control, .form-select { font-size: .875rem; line-height: 1.35; }
.form-control { padding: .28rem .6rem; }
.form-select { padding: .28rem 2rem .28rem .6rem; background-position: right .55rem center; }
.form-control-sm, .form-select-sm { font-size: .8125rem; line-height: 1.35; }
.form-control-sm { min-height: calc(1.35em + .4rem + calc(var(--bs-border-width) * 2)); padding: .2rem .5rem; }
.form-select-sm { padding: .2rem 1.9rem .2rem .5rem; background-position: right .45rem center; }
textarea.form-control { min-height: calc(1.35em + .56rem + calc(var(--bs-border-width) * 2)); }
textarea.form-control-sm { min-height: calc(1.35em + .4rem + calc(var(--bs-border-width) * 2)); }
.input-group-text { padding: .28rem .6rem; font-size: .875rem; line-height: 1.35; }
.input-group-sm > :is(.form-control, .form-select, .input-group-text) { padding-top: .2rem; padding-bottom: .2rem; font-size: .8125rem; line-height: 1.35; }
.input-group-sm > .btn { --bs-btn-padding-y: .2rem; }

/* ---------------------------------------------------------------------------
 * Nested forms. Fields are always white and whatever holds them is a shade darker,
 * however deep it sits: a card body's well, a panel inside it, a detail grid inside
 * that, a card head or save bar with a field, table cells with a field.
 * [October 16] Each step is one shade (--cs-shade-2, steel 7%) over what it sits on, not a tinted colour of its own,
 * so a panel body, a nest, a detail grid and a field box on the same base are the same shade. The two names stay for
 * the apps' own rules; both are the one step now (were #f0f0f0 and #e9e9e9, solid blue-greys).
 * ------------------------------------------------------------------------- */
:root { --cs-form-bg-nested: var(--cs-shade-2); --cs-form-bg-deep: var(--cs-shade-2); }
.cs-panel-body:has(input:not([type="hidden"]), select, textarea) { background: var(--cs-form-bg-nested); border-radius: 0 0 7px 0; }
.cs-panel-body:first-child:has(input:not([type="hidden"]), select, textarea) { border-radius: 0 7px 7px 0; }
.cs-panel-head:has(input:not([type="hidden"]), select, textarea) { background: linear-gradient(180deg, var(--cs-shade-2), var(--cs-shade-3)); } /* #393939 9.6:1 at the foot */
.cs-detail-grid:has(input:not([type="hidden"]), select, textarea) { background: var(--cs-form-bg-deep); } /* the same step as a field box beside it; its lines darken with it */
.cs-savebar { background: linear-gradient(180deg, var(--cs-shade-1), var(--cs-shade-3)) #fff; } /* a raised white bar, a step down toward its foot */
.cs-card .table:has(input:not([type="hidden"], [type="checkbox"], [type="radio"]), select, textarea) { --bs-table-bg: var(--cs-form-bg-nested); background-color: #fff; } /* [Proposed, October 16] only a field you type in or pick from (text, number, date, select, textarea) makes a form table; a row's select checkbox, a radio or a switch doesn't. Cells a step over the table's white; stripes, subtotals and row states still layer over them */
.cs-card .table:has(input:not([type="hidden"], [type="checkbox"], [type="radio"]), select, textarea) > thead :is(th, td) { --bs-table-bg: #fff; background-image: linear-gradient(var(--cs-shade-1), var(--cs-shade-1)); }
.dropdown-menu:has(.form-check-input) { background-image: linear-gradient(var(--cs-form-bg-nested), var(--cs-form-bg-nested)); } /* over the menu's white, so it still hides the page */
/* A box of fields set inside a form: one step darker than what it's on */
.cs-nest { background: var(--cs-form-bg-nested); border: 1px solid var(--cs-shade-3); border-radius: 8px; padding: 8px 10px; }

/* ---------------------------------------------------------------------------
 * Badges. Counts, statuses, flags and tallies are always badges, never loose small
 * text that blends into the line. Neutral by default; tones for meaning.
 * ------------------------------------------------------------------------- */
.cs-badge { --tone: #4b4b4b; --tone-bg: #ededed; --tone-border: #d9d9d9; display: inline-flex; align-items: center; gap: .3em; padding: .1rem .42rem; font-size: .7rem; font-weight: 600; line-height: 1.35; letter-spacing: .01em; text-transform: none; color: var(--tone); background: var(--tone-bg); border: 1px solid var(--tone-border); border-radius: .3rem; white-space: nowrap; vertical-align: .08em; font-family: Arial, sans-serif; }
/* A long badge (a record's name, an owner) may wrap inside tiles and lists. */
.cs-badge.wrap, .cs-stat .cs-badge { white-space: normal; text-align: left; }
.cs-badge .bi { font-size: .95em; }
.cs-badge.count { border-radius: 999px; padding-inline: .5rem; font-variant-numeric: tabular-nums; }
.cs-badge.mono { font-family: var(--bs-font-monospace); font-weight: 500; }
.cs-badge.tone-give { --tone: #1b6a3d; --tone-bg: #e2f3e9; --tone-border: #bde2cb; }
.cs-badge.tone-take { --tone: #954b00; --tone-bg: #fff0df; --tone-border: #f3d2ac; }
.cs-badge.tone-info { --tone: #28609a; --tone-bg: #e8f1fa; --tone-border: #c6d9ef; }
.cs-badge.tone-warn { --tone: #7a5a00; --tone-bg: #fff4d4; --tone-border: #efdc9f; }
.cs-badge.tone-bad { --tone: #a3261f; --tone-bg: #fde7e6; --tone-border: #f4c3c0; }
.cs-badge.tone-muted { --tone: #5e5e5e; --tone-bg: #f5f5f5; --tone-border: #e4e4e4; font-weight: 500; }
.cs-badges { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
/* Bootstrap's own badges on the same compact scale */
.badge { font-size: .7rem; font-weight: 600; padding: .25em .5em; border-radius: .3rem; letter-spacing: .01em; vertical-align: .08em; }
.badge.text-bg-light { background-color: #ededed !important; color: #4b4b4b !important; border: 1px solid #d9d9d9; }

/* ---------------------------------------------------------------------------
 * Actions sit in a corner: top-right (.cs-corner) or bottom-right (.cs-foot), never
 * in the middle of the text. List rows pin their buttons to the top of the row.
 * ------------------------------------------------------------------------- */
.cs-tile-head { display: flex; align-items: flex-start; gap: 8px; }
.cs-tile-head > .grow { flex: 1; min-width: 0; padding-top: 1px; }
.cs-corner { margin-left: auto; flex-shrink: 0; display: flex; gap: 6px; align-items: center; }
.cs-foot { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 6px 8px; margin-top: auto; padding-top: 8px; }
.cs-foot > .cs-foot-actions { margin-left: auto; display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
.cs-list > li > :is(.btn, .btn-group, .dropdown, form, .cs-corner, .form-control, .form-select) { align-self: flex-start; flex-shrink: 0; }

/* A grid table whose columns are all the same width, however long their names */
.cs-grid-fixed { table-layout: fixed; width: 100%; }
.cs-grid-fixed .cs-grid-name { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; line-height: 1.25; min-height: 2.5em; } /* [Proposed] two lines, the full name in the callout (October 15) */
/* [Proposed] Grid columns stay narrow and even (October 15): without a <colgroup>, every column after the first is
 * --cs-grid-col wide and the first (the label) takes the rest, so values don't spread apart on a wide screen. */
.cs-grid-fixed { --cs-grid-col: 5.5rem; }
.cs-grid-fixed > thead > tr:first-child > th:not(:first-child) { width: var(--cs-grid-col); }
.cs-grid-fixed td:first-child { overflow-wrap: anywhere; }
.cs-grid-fixed th { vertical-align: bottom; }
.cs-card > .head > :last-child:not(:first-child) { flex-shrink: 0; }
/* Phones: a card head's buttons wrap under the title instead of pushing the page sideways. */
@media (max-width: 575.98px) {
    .cs-card > .head { flex-wrap: wrap; }
    .cs-card > .head > :last-child:not(:first-child) { flex-shrink: 1; flex-wrap: wrap; justify-content: flex-end; margin-left: auto; }
}
.cs-card > .head .btn, .cs-page-header .btn { white-space: nowrap; }

/* A sticky side column on wide screens (a preview or a submit card beside a long form). */
@media (min-width: 1200px) {
    .cs-sticky { position: sticky; top: calc(var(--cs-bar-h) + 12px); max-height: calc(100vh - var(--cs-bar-h) - 24px); overflow-y: auto; }
}
/* Toggle groups (btn-check): the chosen option is filled, over the raised-button gradient. */
.btn-check:checked + .btn:is(.btn-outline-secondary, .btn-outline-primary), .btn-check:active + .btn:is(.btn-outline-secondary, .btn-outline-primary) { background: linear-gradient(180deg, #4483c6, #2d6bab); border-color: #27609c; color: #fff; }

/* ---------------------------------------------------------------------------
 * Timeline: numbered steps on a line that turns green as steps finish, one row per person.
 * ------------------------------------------------------------------------- */
.cs-timeline { list-style: none; margin: 0; padding: 0; }
.cs-tl-step { position: relative; padding: 0 0 18px 42px; }
.cs-tl-step:last-child { padding-bottom: 2px; }
.cs-tl-step::before { content: ""; position: absolute; left: 14px; top: 32px; bottom: 4px; width: 2px; border-radius: 2px; background: #dadada; }
.cs-tl-step.is-done::before { background: #8fcaa8; }
.cs-tl-step:last-child::before { display: none; }
.cs-tl-marker { position: absolute; left: 0; top: 0; width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: .8rem; font-weight: 700; background: #fff; border: 2px solid #bebebe; color: #4b4b4b; }
.is-done > .cs-tl-marker { background: #1e7a45; border-color: #1e7a45; color: #fff; }
.is-active > .cs-tl-marker { border-color: var(--cs-accent); color: var(--cs-accent); box-shadow: 0 0 0 4px rgba(53, 120, 190, 0.16); }
.is-bad > .cs-tl-marker { background: #b42a24; border-color: #b42a24; color: #fff; }
.cs-tl-head { min-height: 30px; display: flex; flex-direction: column; justify-content: center; gap: 3px; margin-bottom: 8px; }
.cs-tl-title { font-weight: 600; font-size: .86rem; line-height: 1.3; color: #2b2b2b; }
.cs-tl-people { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.cs-tl-person { display: flex; gap: 9px; align-items: flex-start; background: var(--cs-data-shade-1); border: 1px solid var(--cs-data-shade-3); border-radius: .5rem; padding: 7px 9px; }
.is-active .cs-tl-person.is-waiting { background: #f3f7fc; border-color: #cfdded; }
.cs-tl-person .grow { min-width: 0; flex: 1; }
.cs-tl-name { font-weight: 600; font-size: .82rem; color: #2b2b2b; line-height: 1.25; }
.cs-tl-sub { font-size: .75rem; color: #5b5b5b; line-height: 1.3; }
.cs-tl-person .cs-badges { margin-top: 4px; }
.cs-tl-person.is-muted { background: transparent; } /* lighter than the others: no step at all */
.cs-tl-person.is-muted .cs-tl-name { color: #656565; text-decoration: line-through; text-decoration-color: #a4a4a4; }
.cs-tl-note { font-size: .75rem; color: #5b5b5b; font-style: italic; margin-top: 3px; }

/* Readable warnings: Bootstrap's warning yellow (#ffc107) is about 1.6:1 on white. Warning text
 * and notes use a dark amber that passes WCAG AA (4.5:1) on white and on the tinted wells. */
.text-warning { color: #7a4f00 !important; }
.cs-note-warn { color: #6b4500; background: #fff6dc; border: 1px solid #f0d58a; border-radius: .35rem; padding: 4px 8px; }
/* Contrast (Oct 5): every text colour passes WCAG AA on its own background. */
.btn-outline-secondary { --bs-btn-color: #4e4e4e; --bs-btn-border-color: #a4a4a4; }
.btn-outline-primary { --bs-btn-color: #22609f; }
:root { --bs-link-color: #215e9b; --bs-link-color-rgb: 33, 94, 155; --bs-link-hover-color: #184674; --bs-link-hover-color-rgb: 24, 70, 116; }
.text-danger { color: #a52834 !important; }
.text-success { color: #146c43 !important; }
.btn-outline-success { --bs-btn-color: #146c43; --bs-btn-border-color: #3e9b6c; --bs-btn-disabled-color: #146c43; }
.btn-outline-danger { --bs-btn-color: #a52834; --bs-btn-border-color: #d9757e; --bs-btn-disabled-color: #a52834; }
.btn-outline-primary { --bs-btn-disabled-color: #22609f; }
code { color: #a1195a; }

/* A save bar pinned to the bottom of the screen for long documents, so saving is one click from anywhere. */
.cs-savedock { position: fixed; z-index: 1025; left: var(--cs-side-now); right: 0; bottom: 0; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; padding: 9px 18px; background: #fff; border-top: 1px solid #d7d7d7; box-shadow: 0 -4px 14px rgba(35, 35, 35, 0.1); }
.cs-savedock-status { font-size: .84rem; font-weight: 600; }
.cs-savedock-status .unsaved { color: #7a4f00; }
.cs-savedock-status .unsaved .bi { font-size: .6rem; vertical-align: .15em; }
.cs-savedock-status .saved { color: #146c43; }
.cs-savedock-actions { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.cs-savedock-hint { font-size: .74rem; color: var(--cs-muted); }
@media (max-width: 991.98px) { .cs-savedock { left: 0; padding: 8px 12px; } }

/* Sidebar "Testing" card: things that exist only while the app is being tested, set apart from the app. */
.cs-nav-testing { margin: 4px 12px 24px; padding: 10px 10px 8px; border: 1px dashed #d9a93a; border-radius: 10px; background: rgba(255, 196, 64, .09); }
.cs-nav-testing-label { display: flex; align-items: center; gap: 6px; font-size: .7rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: #ffd36b; }
.cs-nav-testing-note { font-size: .72rem; color: #d1d1d1; margin: 2px 0 8px; }
.cs-nav-testing a { display: flex; align-items: center; gap: .6rem; padding: 6px 8px; border-radius: 6px; color: #fff; background: rgba(255, 255, 255, .06); text-decoration: none; font-size: .86rem; font-weight: 600; }
.cs-nav-testing a:hover { background: rgba(255, 255, 255, .12); color: #fff; }
.cs-nav-testing a.active { background: #8a5d00; color: #fff; } /* 5.6:1 */
.cs-nav-testing a .bi { font-size: 1rem; width: 1.1rem; text-align: center; }
.cs-nav-testing a .count { margin-left: auto; background: #c62f2a; color: #fff; border-radius: 10px; font-size: .68rem; padding: 1px 7px; }
.cs-nav-testing .cs-help { color: #ffd36b; }

/* [Proposed, October 16] The sidebar collapses to a rail (Design §4.2). The pancake toggles html.cs-side-rail, kept per
 * browser and set before the page draws, so it never flashes between pages. Desktop widths only: below 992px the
 * sidebar is the drawer the pancake opens. The rail is the icons alone, a count as a red dot, a section as a hairline;
 * pointed at (after a short pause, so a pass on the way to the first column doesn't open it) or tabbed into, it opens
 * full width over the page with a shadow, and the page doesn't move. */
@media (min-width: 992px) {
    html.cs-side-rail { --cs-side-now: var(--cs-rail-w); }
    .cs-sidebar { transition: width .18s ease, box-shadow .18s ease; }
    .cs-side-rail .cs-sidebar { width: var(--cs-rail-w); overflow-x: hidden; }
    /* [October 20] The rail shows no scrollbar (it cut the icons off); it still scrolls by wheel or key, and the open sidebar shows one. */
    .cs-side-rail .cs-sidebar:not(:hover, :focus-within) { scrollbar-width: none; }
    .cs-side-rail .cs-sidebar:not(:hover, :focus-within)::-webkit-scrollbar { display: none; }
    .cs-side-rail-always .cs-pancake { display: none; } /* crewsuite.sidebar = 'rail': nothing to toggle on a desktop */
    .cs-side-rail .cs-sidebar:is(:hover, :focus-within) { width: var(--cs-sidebar-w); box-shadow: 8px 0 22px rgba(26, 26, 26, 0.35); transition-delay: .15s; }
    .cs-side-rail .cs-sidebar .cs-nav { width: var(--cs-sidebar-w); padding-left: 6px; padding-right: 6px; } /* full width inside, so the labels don't rewrap while it opens */
    .cs-side-rail .cs-sidebar:not(:hover, :focus-within) .cs-nav .section { height: 17px; padding: 8px 4px; font-size: 0; }
    .cs-side-rail .cs-sidebar:not(:hover, :focus-within) .cs-nav .section::after { content: ''; display: block; width: 28px; height: 1px; margin-left: 2px; background: rgba(255, 255, 255, .15); }
    .cs-side-rail .cs-sidebar:not(:hover, :focus-within) :is(.cs-nav, .cs-nav-testing) a { position: relative; width: 40px; padding-left: 0; padding-right: 0; justify-content: center; }
    .cs-side-rail .cs-sidebar:not(:hover, :focus-within) :is(.cs-nav, .cs-nav-testing) a > .lbl { display: none; }
    .cs-side-rail .cs-sidebar:not(:hover, :focus-within) :is(.cs-nav, .cs-nav-testing) a > .count { position: absolute; top: 4px; left: 25px; width: 8px; height: 8px; min-width: 0; padding: 0; font-size: 0; }
    .cs-side-rail .cs-sidebar:not(:hover, :focus-within) .cs-nav-testing { width: 40px; margin: 4px 6px 24px; padding: 6px 0; }
    .cs-side-rail .cs-sidebar:not(:hover, :focus-within) .cs-nav-testing > :not(a) { display: none; } /* its label, note and any control: the links stay */
}
@media (prefers-reduced-motion: reduce) { .cs-sidebar, .cs-pancake > i { transition: none; } }

[x-cloak] { display: none !important; }
/* [Proposed, October 21] The list pager (Design §6.11; Livewire's pagination theme `crewsuite`): small and quiet under the
 * table, the count on the left, the pages on the right as compact buttons in the kit's colours, the page in the accent. */
.cs-pager { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 12px; padding: 8px 10px; font-size: .78rem; } /* its own even padding, so a list wraps it in nothing */
.cs-pager-count { color: var(--cs-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.cs-pager-pages { display: flex; flex-wrap: wrap; align-items: center; gap: 3px; margin: 0; padding: 0; list-style: none; }
.cs-pager-btn { display: inline-flex; align-items: center; justify-content: center; min-width: 26px; height: 26px; padding: 0 7px; border: 1px solid #d1d1d1; border-radius: 5px; background: #fff; color: #2b2b2b; font: inherit; font-size: .78rem; font-variant-numeric: tabular-nums; line-height: 1; cursor: pointer; }
.cs-pager-btn:is(:hover, :focus-visible) { background: #f2f2f2; border-color: #b2b2b2; }
.cs-pager-btn.is-on { background: var(--cs-accent); border-color: var(--cs-accent); color: #fff; font-weight: 600; cursor: default; } /* 4.6:1 */
.cs-pager-btn.is-off { color: #acacac; background: #f8f8f8; cursor: default; }
.cs-pager-btn > .bi { font-size: .75rem; }
.cs-pager-gap { padding: 0 3px; color: var(--cs-muted); }
@media (max-width: 575.98px) { .cs-pager { padding: 8px; } .cs-pager-btn { min-width: 30px; height: 30px; } } /* a phone: the same edge as the card's rows, bigger targets */
@media print { .cs-pager { display: none !important; } }
/* [Proposed, October 20] Busy (cs-busy.js, crewsuite.busy): while Livewire works or a page loads, the page under the top bar
 * dims under a spinner, over a drawer or the large panel too, and under the popups a person may still be in (the cell
 * editor, a date range). */
.cs-busy { position: fixed; inset: var(--cs-bar-h) 0 0 var(--cs-side-now); z-index: 1048; display: flex; align-items: center; justify-content: center; background: rgba(25, 25, 25, 0.2); cursor: progress; animation: cs-busy-in .15s ease; }
.cs-busy > .spinner-border { width: 2.75rem; height: 2.75rem; border-width: .3rem; color: var(--cs-accent); background: #fff; box-shadow: 0 0 0 10px #fff, 0 6px 24px rgba(25, 25, 25, 0.3); }
@keyframes cs-busy-in { from { opacity: 0; } }
@media (max-width: 991.98px) { .cs-busy { left: 0; } }
@media (prefers-reduced-motion: reduce) { .cs-busy { animation: none; } .cs-lightbox-stage > img { transition: none; } }
@media print { .cs-busy { display: none !important; } }

/* [October 26] Feedback (cs-feedback.js, Design §9.6, CrewSuite §6.9): the report drawer (the kit's .cs-drawer with .cs-fb),
 * the marking layer over the page with its toolbar, the marks left faintly on the page, and the fixed button an app off
 * the package gets when it has no [data-cs-feedback] of its own. */
.cs-fb-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.cs-fb-label { font-size: .68rem; letter-spacing: .08em; text-transform: uppercase; font-weight: 700; color: var(--cs-muted); margin: 12px 0 4px; }
.cs-fb-label:first-child { margin-top: 0; }
/* The two kinds: one lit, the subtab look (Design §8.4: a choice, not an action). */
.cs-fb-kinds { display: flex; gap: 6px; }
.cs-fb-kinds > button { flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 7px 10px; background: #fff; border: 1px solid #d5d5d5; border-radius: 7px; color: #383838; font-size: .86rem; }
.cs-fb-kinds > button[aria-checked="true"] { background: #eff3f8; border-color: var(--cs-accent); color: #2b2b2b; font-weight: 600; box-shadow: inset 0 0 0 1px var(--cs-accent); }
.cs-fb-kinds > button:focus-visible { outline: 2px solid var(--cs-accent); outline-offset: 1px; }
/* What goes with the report, in one quiet line, so nobody is surprised. */
.cs-fb-with { font-size: .74rem; color: var(--cs-muted); line-height: 1.4; }
.cs-fb-with b { color: #383838; font-weight: 600; }
/* The marks listed under the box: the number, the comment (two lines at most), the element's words (one line). */
.cs-fb-marks { list-style: none; margin: 6px 0 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.cs-fb-marks > li { display: flex; align-items: center; gap: 8px; font-size: .8rem; padding: 4px 6px 4px 4px; border: 1px solid var(--cs-border); border-radius: 6px; background: #fff; }
.cs-fb-marks > li > .btn { --bs-btn-padding-y: 0; --bs-btn-padding-x: .3rem; margin-left: auto; font-size: .75rem; flex: none; }
.cs-fb-marks .cs-fb-n { flex: none; }
.cs-fb-marks .words { flex: 1 1 auto; min-width: 0; }
.cs-fb-marks .txt { overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow-wrap: anywhere; }
.cs-fb-marks .el { color: var(--cs-muted); font-size: .7rem; font-family: var(--bs-font-monospace); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cs-fb-n { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; border-radius: 50%; background: #c62f2a; color: #fff; font-size: .72rem; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; }
.cs-fb-n.circle { background: #215e9b; }
/* Already reported on this screen: its heading (a flex row of its own, so hidden still hides it), then compact rows:
 * the badges, the first line, who, Me too at the right. */
.cs-fb-rel-head { display: flex; align-items: center; gap: 8px; }
.cs-fb-rel-head[hidden] { display: none; }
.cs-fb-rel { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; column-gap: 8px; row-gap: 2px; align-items: center; padding: 6px 10px; border-bottom: 1px solid var(--cs-border); font-size: .8rem; }
.cs-fb-rel:last-child { border-bottom: 0; }
.cs-fb-rel > .cs-badges { grid-column: 1 / 3; }
.cs-fb-rel > .txt { grid-column: 1 / 3; color: #2b2b2b; }
.cs-fb-rel > .by { grid-column: 1 / 3; color: var(--cs-muted); font-size: .72rem; }
.cs-fb-rel > .act { grid-column: 3; grid-row: 1 / 5; }
.cs-fb-rel > .act .btn { --bs-btn-padding-y: .1rem; --bs-btn-padding-x: .45rem; font-size: .75rem; white-space: nowrap; }
.cs-fb-rel > .act .btn[aria-pressed="true"] { background: #e2f3e9; border-color: #bde2cb; color: #1b6a3d; }
.cs-fb-reply { color: #1b6a3d; font-size: .76rem; grid-column: 1 / 3; }
.cs-fb-reply .bi { margin-right: 3px; }
.cs-fb-sent { display: flex; gap: 10px; align-items: flex-start; }
.cs-fb-sent .bi-check-circle-fill { color: #1b6a3d; font-size: 1.1rem; }
/* The marking layer: over the whole page, above the bar and the sidebar, under the callouts (Design §4.5). */
.cs-fb-layer { position: fixed; inset: 0; z-index: 1079; cursor: crosshair; touch-action: none; }
.cs-fb-layer svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.cs-fb-layer ellipse { fill: none; stroke: #c62f2a; stroke-width: 3; }
.cs-fb-layer ellipse.draft { stroke-dasharray: 6 4; }
.cs-fb-pin { position: absolute; transform: translate(-50%, -50%); z-index: 1; cursor: default; }
.cs-fb-pin .cs-fb-n { width: 24px; height: 24px; font-size: .8rem; box-shadow: 0 0 0 3px #fff, 0 2px 8px #0005; }
.cs-fb-pin-box { position: absolute; z-index: 2; width: 300px; max-width: calc(100vw - 24px); background: #fff; border-radius: 8px; box-shadow: 0 10px 28px #0006; padding: 8px; display: flex; gap: 6px; align-items: flex-start; cursor: default; }
.cs-fb-pin-box textarea { resize: none; }
.cs-fb-pin-box .btn { white-space: nowrap; }
/* The toolbar: fixed bottom centre, a white pill with a dark ring and a strong lifted shadow, so it never blends into the
 * page under it (the drawer is hidden while marking, so this is the only control on screen). It rises from the bottom
 * edge and nudges once, so its arrival is seen; reduced motion gets a plain fade. The owner, October 26. */
.cs-fb-tools { position: fixed; bottom: max(16px, env(safe-area-inset-bottom)); left: 50%; transform: translateX(-50%); z-index: 3; display: flex; align-items: center; gap: 6px; padding: 6px 8px; background: #fff; color: #1b1b1b; border-radius: 999px;
    box-shadow: 0 0 0 1.5px #1b1b1b, 0 18px 48px #0f1c2880, 0 4px 12px #0f1c2859; font-size: .82rem; cursor: default;
    animation: cs-fb-rise .38s cubic-bezier(.2, .8, .2, 1) both, cs-fb-nudge .7s .45s ease-in-out 1; }
@keyframes cs-fb-rise { from { transform: translate(-50%, 28px); opacity: 0; } to { transform: translate(-50%, 0); opacity: 1; } }
@keyframes cs-fb-nudge { 0%, 100% { box-shadow: 0 0 0 1.5px #1b1b1b, 0 18px 48px #0f1c2880, 0 4px 12px #0f1c2859; }
    45% { transform: translate(-50%, -6px); box-shadow: 0 0 0 1.5px #1b1b1b, 0 0 0 7px #c62f2a4d, 0 24px 56px #0f1c2899, 0 4px 12px #0f1c2859; } }
.cs-fb-tools .hint { color: #545454; padding: 0 6px; white-space: nowrap; } /* 7.6:1 on white */
.cs-fb-tools .btn-group .btn { color: #1b1b1b; background: #fff; border-color: #959595; }
.cs-fb-tools .btn-group .btn.active { background: #1b1b1b; color: #fff; border-color: #1b1b1b; }
.cs-fb-tools .btn-group .btn:hover { color: #1b1b1b; background: #ececec; }
.cs-fb-tools .btn-group .btn.active:hover { color: #fff; background: #2b2b2b; }
.cs-fb-tools .btn-outline-secondary { white-space: nowrap; }
.cs-fb-tools .cs-fb-count { color: #545454; white-space: nowrap; }
@media (max-width: 767.98px) { .cs-fb-tools .hint { display: none; } }
@media (prefers-reduced-motion: reduce) { .cs-fb-tools { animation: cs-fb-fade .3s ease-out both; } }
@keyframes cs-fb-fade { from { opacity: 0; } to { opacity: 1; } }
/* The marks left on the page after Done, faint, until the report is sent or cancelled: in the document, so they scroll with it. */
.cs-fb-ghost { position: absolute; inset: 0; pointer-events: none; z-index: 1036; }
.cs-fb-ghost svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.cs-fb-ghost ellipse { fill: none; stroke: #c62f2a; stroke-width: 3; opacity: .55; }
.cs-fb-ghost .cs-fb-pin { opacity: .75; }
/* The element the mouse is over while marking: a thin accent outline, so the person sees what a pin would name. */
.cs-fb-hover { outline: 2px solid var(--cs-accent) !important; outline-offset: 1px; }
/* An app off the package with no [data-cs-feedback] in its bar: the button fixed bottom right, as a last resort. */
.cs-fb-float { position: fixed; right: 16px; bottom: max(16px, env(safe-area-inset-bottom)); z-index: 1034; display: inline-flex; align-items: center; gap: 4px; padding: 6px 12px; font-size: .82rem; color: #fff; background: #1b1b1b; border: 1px solid #545454; border-radius: 999px; box-shadow: 0 6px 20px #0f1c2866; }
.cs-fb-float:hover, .cs-fb-float:focus-visible { background: #2b2b2b; color: #fff; }
@media print { .cs-fb, .cs-fb-backdrop, .cs-fb-layer, .cs-fb-ghost, .cs-fb-float { display: none !important; } }
/* [October 30] What's New (Livewire\WhatsNew, Design §9.7, CrewSuite §6.10): the kit's .cs-drawer with .cs-wn. A week's
 * heading, then one row per entry: the kind's badge in a fixed column, the sentence and its screen's link. */
.cs-wn-root { display: contents; }
.cs-wn-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.cs-wn-week { font-size: .74rem; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--cs-muted); padding: 10px 14px 4px; }
.cs-wn-list { list-style: none; margin: 0; padding: 0 0 6px; }
.cs-wn-list > li { display: grid; grid-template-columns: 74px minmax(0, 1fr); gap: 8px; padding: 6px 14px; font-size: .86rem; line-height: 1.4; }
.cs-wn-list > li > .cs-badge { justify-self: start; align-self: start; margin-top: 1px; }
.cs-wn-list a { white-space: nowrap; }
.cs-wn-loading { display: flex; align-items: center; gap: 8px; padding: 16px 14px; color: var(--cs-muted); font-size: .86rem; }
.cs-wn-foot { font-size: .78rem; color: var(--cs-muted); margin-top: 8px; }
@media print { .cs-wn, .cs-wn-root { display: none !important; } }
/* [Proposed, October 20] The photo viewer (cs-lightbox.js, Design §9.5): a picture large over a dark page, its set's
 * ← → buttons, a head with its name, "2 of 5", Download, open in a new tab and ✕. Above the cell editor, under callouts. */
.cs-lightbox { position: fixed; inset: 0; z-index: 1075; display: flex; flex-direction: column; background: rgba(15, 15, 15, 0.92); color: #fff; }
.cs-lightbox-bar { flex: none; display: flex; align-items: center; gap: 8px; padding: 8px 12px; }
.cs-lightbox-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.cs-lightbox-count { margin-right: auto; color: #d1d1d1; white-space: nowrap; font-variant-numeric: tabular-nums; } /* 11.9:1 */
.cs-lightbox-stage { flex: 1; min-height: 0; position: relative; display: flex; align-items: center; justify-content: center; padding: 0 60px 16px; }
.cs-lightbox-stage > img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 4px; background: rgba(255, 255, 255, .06); box-shadow: 0 8px 32px rgba(0, 0, 0, .5); transition: transform .15s ease; }
/* The head's tools: light on the dark, drawn here (Bootstrap's outline buttons are white until hovered in this kit). */
.cs-lightbox-btn { display: inline-flex; align-items: center; gap: 5px; height: 30px; padding: 0 9px; border: 1px solid rgba(255, 255, 255, .4); border-radius: 6px; background: rgba(255, 255, 255, .1); color: #fff; font: inherit; font-size: .8rem; text-decoration: none; white-space: nowrap; cursor: pointer; }
.cs-lightbox-btn:is(:hover, :focus-visible) { background: rgba(255, 255, 255, .24); color: #fff; }
.cs-lightbox-btn > .bi { font-size: .95rem; }
.cs-lightbox-close { border-color: transparent; background: none; }
.cs-lightbox-dl { position: relative; display: inline-flex; }
.cs-lightbox-menu { position: absolute; right: 0; top: calc(100% + 4px); z-index: 1; display: flex; flex-direction: column; min-width: 15rem; padding: 4px 0; background: #fff; border-radius: 8px; box-shadow: 0 10px 28px rgba(0, 0, 0, .45); }
.cs-lightbox-menu > a { display: flex; align-items: center; gap: 8px; padding: 7px 14px; color: #2b2b2b; font-size: .82rem; text-decoration: none; white-space: nowrap; }
.cs-lightbox-menu > a:is(:hover, :focus-visible) { background: #f2f2f2; color: #2b2b2b; }
.cs-lightbox-nav { position: absolute; top: 50%; transform: translateY(-50%); display: flex; align-items: center; justify-content: center; width: 44px; height: 44px; border: 0; border-radius: 50%; background: rgba(255, 255, 255, .16); color: #fff; font-size: 1.25rem; }
.cs-lightbox-nav:is(:hover, :focus-visible) { background: rgba(255, 255, 255, .3); }
.cs-lightbox-nav.prev { left: 8px; }
.cs-lightbox-nav.next { right: 8px; }
html.cs-lightbox-open { overflow: hidden; }
@media (max-width: 575.98px) { .cs-lightbox-stage { padding: 0 8px 8px; } .cs-lightbox-nav { top: auto; bottom: 16px; transform: none; } }
@media print { .cs-lightbox { display: none !important; } }
/* Tables of numbers: figures line up; a sticky first column keeps names in view while a wide table scrolls sideways. */
.cs-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.cs-table > tbody > tr.cs-subtotal > *, .cs-table > tfoot > tr.cs-subtotal > * { background-image: linear-gradient(var(--cs-data-shade-4), var(--cs-data-shade-4)); --bs-table-color: #2b2b2b; font-weight: 600; border-top: 1px solid #a6a6a6; } /* [Proposed] the strongest step (October 15; a shade since October 16, was #dddddd), so it stands out on stripes and tinted rows: on white #2b2b2b 10.7:1, .cs-neg 5.6:1, .cs-pos 4.9:1 */
.cs-table tr.cs-subtotal :is(.cs-dash, .text-dgray, .text-gray, .text-muted) { color: #515151 !important; } /* 6.0:1 (#696969 is 4.1:1 here) */
.cs-table > :is(tbody, tfoot) > tr:is(.cs-subtotal, .cs-total) > * { --bs-table-bg-state: transparent; } /* a summary row isn't a record: no hover step, which would take .cs-pos under 4.5:1 */
.cs-table > :is(tbody, tfoot) > tr.cs-total > * { --bs-table-bg: #e2f3e9; font-weight: 600; border-top: 1px solid #1e7a45; } /* #393939 9.9:1; [Proposed] 1px, never 2 (October 15) */
.cs-table th.cs-sort { cursor: pointer; user-select: none; }
.cs-table th.cs-sort .bi { font-size: .7rem; }
.cs-table th.cs-sort:hover { text-decoration: underline; text-underline-offset: 3px; }
.cs-table th.cs-sort:focus-visible { outline: 2px solid var(--cs-accent); outline-offset: -2px; }
.cs-grid-sticky { position: sticky; left: 0; z-index: 1; } /* Bootstrap paints the cell with var(--bs-table-bg), so stripes and row tints show through */
.cs-table > thead th.cs-grid-sticky { --bs-table-bg: #e6e6e6; z-index: 3; } /* head cells only: a row label th in tbody must not cover the sticky head */

/* A table's box (October 27, the owner): full height, so the page is the only thing that scrolls up and down; the
 * box scrolls sideways only. A sideways box can't stick its head to the page, so cs-menus.js lays the head over the
 * rows by --cs-head-y while the table runs under the top bar (.is-pinned). It was its own scroll box, which read as
 * a second scroll inside the page's. Without the script the head scrolls away with the page. */
.cs-table-scroll { min-height: 200px; overflow-x: auto; }
.cs-table-scroll > .cs-table > thead > tr > th { transform: translateY(var(--cs-head-y, 0px)); }
.cs-table-scroll.is-pinned > .cs-table > thead > tr > th { z-index: 4; } /* over the rows and any sticky head of a table inside them */
.cs-table-scroll.is-pinned > .cs-table > thead > tr > th.cs-grid-sticky { z-index: 5; }
.cs-card > .body.flush > .cs-table-scroll:last-child { border-radius: 0 0 10px 10px; }

/* ---------------------------------------------------------------------------
 * Report tables (.cs-table.cs-table-dense): about 20px rows, 12px type, nothing wraps, the same light
 * sticky head as a list (a little tighter), subtotal and total rows. For screens that show many rows
 * and columns of figures; list pages keep the compact default.
 * ------------------------------------------------------------------------- */
.cs-table-dense { font-size: .75rem; line-height: 1.3; }
.cs-table-dense > :not(caption) > * > * { padding: 1px 6px; white-space: nowrap; border-color: #e9e9e9; }
.cs-table-dense > thead > tr > th { padding: 3px 6px; } /* [Proposed] head B (October 15): the dark navy report head is gone; the light steel head above applies */
.cs-table-dense > tbody > tr:nth-child(even):not(.cs-subtotal, .cs-total, .cs-drill-open, .cs-drill-row, .is-deleted, .is-archived, .cs-subhead) > * { background-image: linear-gradient(var(--cs-data-shade-1), var(--cs-data-shade-1)); } /* the same stripe as a list (was #f8f8f8) */
.cs-table-dense .cs-badge { font-size: .65rem; padding: 0 5px; line-height: 1.45; }
.cs-table-dense .btn { --bs-btn-padding-y: 0; --bs-btn-padding-x: .35rem; --bs-btn-font-size: .7rem; }
/* .cs-divider: [Proposed] for grouped heads only (October 15). No group lines by default: every column has the same 1px
 * line. A table with a grouped head (a two-row head naming the groups) may mark each group's first column, in the head
 * and the body, with a 2px light separator; on a one-row head the class draws nothing. */
.cs-table:has(> thead > tr + tr) > :not(caption) > tr > .cs-divider { border-left: 2px solid #d1d1d1; }
.cs-table:has(> thead > tr + tr) > thead > tr > .cs-divider { border-left-color: #b4b4b4; } /* a shade darker on the steel head */
.cs-table .cs-wrap { white-space: normal; }
.cs-table .cs-clip { display: inline-block; vertical-align: bottom; max-width: 240px; overflow: hidden; text-overflow: ellipsis; } /* on a span inside the cell; data-tip with the whole text goes on the cell (Design §7.5) */

/* Figures from Odc\CrewSuite\Support\Fmt: negatives red in brackets, a dash for nothing. */
.cs-neg { color: #a3261f; } /* 6.9:1 on the stripe */
.cs-pos { color: #146c43; } /* 6.1:1 */
.cs-dash { color: #696969; } /* 5.1:1 */
.cs-card > .head .cs-neg { color: #ffc9c4; } .cs-card > .head .cs-pos { color: #bff0d3; } .cs-card > .head .cs-dash { color: #e4e4e4; }

/* ---------------------------------------------------------------------------
 * Column filters (<x-cs.th>, HasColumnFilters): a funnel in the header opens a popup to sort,
 * pick values (searchable, with counts), match text, compare a number or set a date range.
 * Active filters show as chips above the table with a way to clear them.
 * ------------------------------------------------------------------------- */
.cs-cf-th { position: relative; padding-right: 1.5rem !important; }
.cs-cf-btn { position: absolute; right: 3px; top: 50%; transform: translateY(-50%); border: 0; background: transparent; color: inherit; opacity: .55; padding: 1px 3px; font-size: .7rem; line-height: 1; border-radius: 3px; }
.cs-cf-btn:hover, .cs-cf-btn:focus-visible { opacity: 1; background: var(--cs-shade-2); }
/* a heading over two head rows keeps its words at the foot (vertical-align: bottom): the funnel stays on their line, not the middle */
.cs-table > thead th[rowspan].cs-cf-th > .cs-cf-btn { top: auto; bottom: 4px; transform: none; }
.cs-cf-btn.on { opacity: 1; color: var(--cs-accent); }
.cs-table > thead .cs-cf-btn.on { color: #28609a; } /* 5.1:1 at the head's foot */
.cs-cf-pop { position: fixed; z-index: 1040; width: 16rem; background: #fff; border: 1px solid var(--cs-form-border); border-radius: 8px; box-shadow: 0 8px 24px #0f1c2833; font-size: .8rem; text-align: left; font-weight: 400; white-space: normal; color: #2b2b2b; }
.cs-cf-sorts { display: flex; flex-direction: column; padding: 4px; border-bottom: 1px solid var(--cs-border); }
.cs-cf-sorts button { display: flex; align-items: center; gap: 6px; text-align: left; border: 0; background: none; padding: 4px 8px; border-radius: 5px; font-size: .8rem; color: inherit; }
.cs-cf-sorts button:hover { background: var(--cs-shade-2); }
.cs-cf-sorts button.active { background: #eef3fa; } /* the sort that's on: the accent tint marks the current choice */
.cs-cf-body { padding: 8px; background: var(--cs-form-bg-nested); }
.cs-cf-body .form-control, .cs-cf-body .form-select { background-color: #fff; border-color: var(--cs-field-border); }
.cs-cf-links { display: flex; justify-content: space-between; margin-top: 4px; font-size: .75rem; }
.cs-cf-links button { border: 0; background: none; padding: 0; color: var(--bs-link-color); }
.cs-cf-list { max-height: 12rem; overflow-y: auto; background: #fff; border: 1px solid var(--cs-field-border); border-radius: 5px; padding: 3px 6px; margin-top: 6px; }
.cs-cf-list label { display: flex; gap: 6px; align-items: center; padding: 1px 0; cursor: pointer; }
.cs-cf-list label > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cs-cf-list .cnt { margin-left: auto; color: var(--cs-muted); font-variant-numeric: tabular-nums; flex-shrink: 0; }
.cs-cf-list .blank { font-style: italic; color: var(--cs-muted); }
/* [Proposed, October 20] A group's heading over its values (a set column's 'group'). */
.cs-cf-list .cs-cf-group { margin: 5px 0 1px; font-size: .68rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: #515151; }
.cs-cf-list > div:first-of-type .cs-cf-group { margin-top: 1px; }
.cs-cf-note { color: var(--cs-muted); font-size: .72rem; margin-top: 4px; }
.cs-cf-foot { display: flex; gap: 6px; justify-content: flex-end; padding: 8px; border-top: 1px solid var(--cs-border); }
/* [Proposed, decided October 15] The filter-and-sort row shows only while a filter or sort is applied, or after the
 * head's funnel toggle (.cs-cf-toggle) opens it; otherwise it is [hidden]. See the Round 7 block. */
.cs-cf-chips { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; min-height: 34px; padding: 4px 10px; border-bottom: 1px solid var(--cs-shade-3); background: linear-gradient(180deg, var(--cs-shade-4), var(--cs-shade-2)); box-shadow: inset 0 2px 3px -1px var(--cs-shade-4); font-size: .78rem; color: #2b2b2b; } /* [Proposed] a recessed well (October 15; shades since October 16): #2b2b2b 10.7:1 at the dark top */
.cs-cf-chips .text-dgray, .cs-cf-chips .text-gray, .cs-cf-chips .text-muted { color: #585858 !important; } /* 5.4:1 at the dark top (#646464 was 4.6:1) */
.cs-cf-chips .cs-badge button { border: 0; background: none; padding: 0 0 0 2px; color: inherit; line-height: 1; }
.cs-cf-chips > .btn { margin-left: auto; }
.cs-cf-count { font-weight: 600; color: #2b2b2b; white-space: nowrap; margin-right: 2px; } /* [Proposed] October 15: the row starts with the count ("24 of 214 RFPs"), then the chips */
.cs-cf-count > .bi { color: #585858; font-weight: 400; }

/* ---------------------------------------------------------------------------
 * Drill-down rows: a chevron in the first cell opens a row under it holding the detail (a
 * nested table, a list) in a grey well, so it reads as belonging to the row above.
 * ------------------------------------------------------------------------- */
.cs-drill-toggle { border: 0; background: none; padding: 0 4px 0 0; color: var(--cs-muted); line-height: 1; }
.cs-drill-toggle .bi { display: inline-block; transition: transform .15s; font-size: .8em; }
.cs-drill-toggle[aria-expanded="true"] .bi { transform: rotate(90deg); }
.cs-table > tbody > tr.cs-drill-open > * { --bs-table-bg: #eaf0f7; }
.cs-table > tbody > tr.cs-drill-row > td { background-image: linear-gradient(var(--cs-data-shade-4), var(--cs-data-shade-4)); padding: 6px 8px 8px 24px; box-shadow: inset 0 2px 4px var(--cs-data-shade-4); white-space: normal; } /* a grey well: the strongest step over the row's base (was #e6e6e6) */
/* A table in a drill-down row is framed on white (a 1px border and a soft shadow): see "Nested tables" in the Round 9 block. */
.cs-drill-row .cs-table > thead > tr > th { position: static; --bs-table-bg: #fff; --bs-table-color: #393939; background-image: linear-gradient(var(--cs-shade-2), var(--cs-shade-2)); font-weight: 600; border-color: #d9d9d9; } /* a child table reads lighter than its parent: one step over its white frame, #393939 10.3:1 */

/* ---------------------------------------------------------------------------
 * Cards inside cards. A card whose body holds other cards becomes their parent by itself: a dark
 * head and a grey well (not the blue of a form) that its children sit raised on.
 * ------------------------------------------------------------------------- */
.cs-card:has(> .body .cs-card) > .head { background: linear-gradient(180deg, #3b3b3b, #272727); border-bottom-color: #272727; } /* white 11.1:1 */
.cs-card > .body.body:has(.cs-card) { background: var(--cs-shade-4); box-shadow: inset 0 2px 4px var(--cs-shade-4); border-radius: 0 0 9px 9px; } /* the strongest step over the white card (was #e6e6e6) */
.cs-card > .body.body:first-child:has(.cs-card) { border-radius: 9px; }
.cs-card > .body:has(.cs-card) .cs-card { margin-bottom: 12px; }
.cs-card .cs-card { box-shadow: var(--cs-shadow-child); } /* [Proposed] child cards lift a little more (October 15) */
.cs-card > .body:has(.cs-card) .cs-card:last-child { margin-bottom: 0; }

/* Markdown text boxes (<x-cs.markdown>, Toast UI Editor) and rendered Markdown (.cs-prose). */
.cs-md .toastui-editor-defaultUI { border: 1px solid var(--cs-form-border); border-radius: 6px; background: #fff; font-family: inherit; }
.cs-md .toastui-editor-defaultUI-toolbar { background: var(--cs-shade-1); border-bottom: 1px solid var(--cs-form-border); border-radius: 6px 6px 0 0; padding: 0 6px; }
.cs-md .toastui-editor-contents { font-size: .9rem; font-family: inherit; }
.cs-md .toastui-editor-contents h2 { font-size: 1.05rem; border-bottom: none; margin: 14px 0 6px; }
.cs-md .toastui-editor-contents h3 { font-size: .95rem; margin: 12px 0 4px; }
.cs-md .toastui-editor-mode-switch { background: var(--cs-shade-1); border-top: 1px solid var(--cs-form-border); }
.cs-prose h1, .cs-prose h2, .cs-prose h3 { font-size: 1rem; font-weight: 700; margin: 14px 0 6px; }
.cs-prose h1:first-child, .cs-prose h2:first-child, .cs-prose h3:first-child { margin-top: 0; }
.cs-prose p { margin: 0 0 8px; }
.cs-prose ul, .cs-prose ol { margin: 0 0 8px; padding-left: 1.3rem; }
.cs-prose li { margin-bottom: 2px; }
.cs-prose table { width: 100%; border-collapse: collapse; margin: 0 0 10px; font-size: .9em; }
.cs-prose th, .cs-prose td { border: 1px solid var(--cs-border); padding: 4px 8px; text-align: left; vertical-align: top; }
.cs-prose th { background: var(--cs-shade-1); font-weight: 600; }
.cs-prose a { color: var(--cs-accent); }
/* Bold the author typed is full bold (the app-wide `strong` is a medium 500). */
.cs-prose strong, .cs-prose b { font-weight: 700; }
/* Our own toolbar buttons (Head or subhead, Remove formatting) sit in Toast UI's 32px slots with a Bootstrap icon in place of the sprite. */
.cs-md .cs-md-btn { display: block; width: 32px; height: 32px; margin: 0; padding: 0; border: 1px solid transparent; border-radius: 3px; background: none; color: #515151; font-size: 18px; line-height: 30px; text-align: center; cursor: pointer; }
.cs-md .cs-md-btn .bi { display: inline-block; line-height: 1; vertical-align: middle; }
.cs-md .cs-md-btn:hover { border-color: #e1e3e9; background: #fff; color: var(--cs-accent); }
.cs-md .toastui-editor-popup { width: auto; min-width: 0; }
.cs-md-pop { display: flex; flex-direction: column; min-width: 150px; padding: 4px; }
.cs-md-pop-item { display: flex; align-items: center; gap: 8px; background: none; border: 0; border-radius: 4px; padding: 6px 10px; font-size: .86rem; text-align: left; color: #2b2b2b; white-space: nowrap; }
.cs-md-pop-item:hover { background: var(--cs-shade-2); color: #215e9b; } /* the link blue: 6.4:1 on the step (the accent is 4.2:1) */
.cs-md-pop-item .bi { width: 1.1rem; text-align: center; }
/* Markdown mode is raw text only: no preview pane, no Write / Preview tabs (the WYSIWYG mode is the preview). */
.cs-md .toastui-editor-md-tab-container, .cs-md .toastui-editor-md-preview, .cs-md .toastui-editor-md-splitter { display: none !important; }
.cs-md .toastui-editor-md-container .toastui-editor { width: 100% !important; }
/* The quick reference under every Markdown box. */
.cs-md-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 14px; margin-top: 4px; font-size: .78rem; }
.cs-md-foot-link { background: none; border: 0; padding: 0; color: var(--cs-muted); text-decoration: none; font-size: inherit; }
.cs-md-foot-link:hover, .cs-md-foot-link[aria-expanded="true"] { color: var(--cs-accent); }
.cs-md-ref { flex-basis: 100%; background: #fff; border: 1px solid var(--cs-form-border); border-radius: 6px; padding: 8px 10px; box-shadow: var(--cs-shadow-1); }
.cs-md-ref table { width: 100%; border-collapse: collapse; font-size: .78rem; }
.cs-md-ref th { text-align: left; color: var(--cs-muted); font-weight: 500; padding: 2px 6px 4px; border-bottom: 1px solid var(--cs-border); }
.cs-md-ref td { padding: 3px 6px; border-bottom: 1px solid #f1f1f1; vertical-align: top; }
.cs-md-ref tr:last-child td { border-bottom: 0; }
.cs-md-ref code { background: var(--cs-shade-1); border-radius: 3px; padding: 0 4px; color: #22364d; white-space: nowrap; }
.cs-md-ref-note { color: var(--cs-muted); margin-top: 6px; }

/* ---------------------------------------------------------------------------
 * [Proposed] DESIGN.md §6–§10 pieces (October 14): the hover callout, state, status and attribute
 * columns, code badges, column kinds, editable tables and the floating editor, the action bar and
 * the row menu, the editing pill. Soft picks: try them on real screens.
 * ------------------------------------------------------------------------- */

/* The hover callout (Design §7.5): what a thing is, at once, on hover or keyboard focus. Replaces title="". */
:where(html:not(.cs-tip-js) [data-tip]:not(.dropdown-toggle)) { position: relative; } /* :where keeps it from beating a sticky th or .cs-grid-sticky; only the CSS fallback needs it */
[data-tip]:not(.dropdown-toggle)::after { content: attr(data-tip); position: absolute; left: 50%; bottom: calc(100% + 6px); transform: translateX(-50%); z-index: 1080; padding: 4px 8px; border-radius: 4px; background: #2b2b2b; color: #fff; font: 600 .74rem/1.3 var(--bs-body-font-family); letter-spacing: 0; text-transform: none; text-align: left; white-space: normal; width: max-content; max-width: 280px; pointer-events: none; } /* white 14.1:1; long notes wrap at 280px */
[data-tip]:not(.dropdown-toggle):not(:hover):not(:focus-visible)::after { display: none; } /* a hidden callout takes no room, so it never adds a scrollbar */
th[data-tip]::after, [data-tip].tip-below::after { bottom: auto; top: calc(100% + 6px); } /* headers open below, so a scroll box can't clip them */
[data-tip].tip-start::after { left: 0; transform: none; }
[data-tip].tip-end::after { left: auto; right: 0; transform: none; }
span[data-tip][tabindex]:focus-visible, i[data-tip][tabindex]:focus-visible { outline: 2px solid var(--cs-accent); outline-offset: 1px; border-radius: 3px; }

/* Icons that carry meaning (Design §7.2–§7.4): a tone each; .is-idle is the faint "not started / none" placeholder. */
.cs-ic { font-size: .85rem; line-height: 1; vertical-align: -1px; color: #5e5e5e; } /* 6.4:1 */
.cs-ic.tone-bad { color: #a3261f; } .cs-ic.tone-warn { color: #8a5d00; } .cs-ic.tone-take { color: #954b00; }
.cs-ic.tone-give { color: #1e7a45; } .cs-ic.tone-info { color: #28609a; } .cs-ic.tone-muted { color: #5e5e5e; }
.cs-ic.is-idle { color: #c0c0c0; } /* deliberately faint: the slot is filled, the words are in aria-label and the callout */

/* Row state column (Design §7.3): blank when live; a tinted row when deleted / archived / left / inactive. */
.cs-table :is(th, td).cs-state { width: 26px; min-width: 26px; padding-left: 6px; padding-right: 2px; text-align: center; }
.cs-table > tbody > tr.is-deleted > * { --bs-table-bg: #fdecec; } /* #2b2b2b 13.6:1 */
.cs-table > tbody > tr.is-archived > * { --bs-table-bg: #eeeeee; } /* a data row: neutral grey (§3.3); #2b2b2b 12.1:1 */
.cs-table > tbody > tr.is-deleted .cs-state .cs-ic { color: #a3261f; }

/* Status icon columns (Design §7.1–§7.2): narrow, centred, never empty. */
.cs-table :is(th, td).cs-sicon { width: 34px; min-width: 34px; text-align: center; padding-left: 2px; padding-right: 2px; }
.cs-table th.cs-sicon { font-size: .68rem; letter-spacing: .02em; }

/* Attributes after the name (Design §7.4): absent when they don't apply. */
.cs-attr { display: inline-flex; align-items: center; gap: 4px; margin-left: 5px; vertical-align: baseline; }
.cs-attr .word { font-size: .64rem; font-weight: 600; letter-spacing: .03em; text-transform: uppercase; color: #5e5e5e; border: 1px solid #d9d9d9; border-radius: 3px; padding: 0 3px; line-height: 1.35; } /* 6.4:1 */

/* Code badges (Design §7.5): a two-letter code and an icon for its second part, in solid colour, white on both halves. */
.cs-code { --code-a: #3a3a3a; --code-b: #515151; display: inline-flex; align-items: stretch; height: 18px; border-radius: 4px; font-size: .68rem; font-weight: 700; line-height: 1; vertical-align: middle; color: #fff; cursor: default; }
.cs-code > .k { display: flex; align-items: center; justify-content: center; min-width: 21px; padding: 0 3px; border-radius: 4px 0 0 4px; background: var(--code-a); letter-spacing: .01em; }
.cs-code > .v { display: flex; align-items: center; justify-content: center; width: 17px; border-radius: 0 4px 4px 0; background: var(--code-b); font-size: .7rem; }
.cs-code > .k:last-child { border-radius: 4px; }
.cs-code.tone-give { --code-a: #145530; --code-b: #1e7a45; } .cs-code.tone-info { --code-a: #204975; --code-b: #28609a; }
.cs-code.tone-warn { --code-a: #634300; --code-b: #8a5d00; } .cs-code.tone-plum { --code-a: #4f2e78; --code-b: #6b3fa0; }
.cs-code.tone-teal { --code-a: #0a4f4c; --code-b: #0f6e6a; } .cs-code.tone-muted { --code-a: #3a3a3a; --code-b: #515151; } /* white ≥ 5.3:1 on each */
.cs-codes { display: inline-grid; grid-template-columns: repeat(var(--slots, 8), 40px); gap: 3px; vertical-align: middle; } /* fixed slots: one code per position */
.cs-codes > .empty { height: 18px; }

/* Column kinds (Design §7.6): the header filled in the kind's colour; a cell that differs from the base tinted lighter. */
.cs-table > thead > tr > th:is(.cs-kind-base, .cs-kind-2, .cs-kind-3) { --bs-table-color: #fff; text-align: center; vertical-align: bottom; white-space: normal; line-height: 1.15; }
.cs-table > thead > tr > th.cs-kind-base { --bs-table-bg: #585858; } /* white 7.1:1 */
.cs-table > thead > tr > th.cs-kind-2 { --bs-table-bg: #306aa7; } /* white 5.9:1 */
.cs-table > thead > tr > th.cs-kind-3 { --bs-table-bg: #ad560a; } /* white 4.9:1 */
.cs-table > tbody > tr > td.cs-kind-base.differs { --bs-table-bg: #f1f1f1; }
.cs-table > tbody > tr > td.cs-kind-2.differs { --bs-table-bg: #e6eef7; }
.cs-table > tbody > tr > td.cs-kind-3.differs { --bs-table-bg: #fdeedf; }
.cs-kind-name { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; } /* two lines, the full name in the callout */

/* Editable tables (Design §6.1, §10.1): 30px rows, click a cell to edit; a blank editable cell shows a faint dot. */
.cs-table-edit > tbody > tr > * { height: 30px; padding-top: 4px; padding-bottom: 4px; }
/* A value someone may change in place, in a table or outside one (a card's facts, a dl.cs-kv). */
/* [Proposed, October 22] An editable cell says so at rest: its value has a faint dotted underline (a read-only cell has none);
 * the hover keeps the row's fill under its outline. */
[data-edit] { cursor: pointer; text-decoration: underline dotted #999999; text-decoration-thickness: 1px; text-underline-offset: 3px; }
[data-edit]:hover { box-shadow: inset 0 0 0 1px #b2b2b2, inset 0 0 0 9999px var(--bs-table-bg-state, var(--bs-table-bg-type, var(--bs-table-accent-bg, transparent))); }
[data-edit]:focus-visible, [data-edit].cs-edit-on { outline: 2px solid var(--cs-accent); outline-offset: -2px; }
.cs-blank { color: #b3b3b3; } /* the faint · in an empty editable cell */
.cs-table td.cs-saved { animation: cs-saved 1.2s ease-out; }
@keyframes cs-saved { from { box-shadow: inset 0 0 0 99px #d6f0df; } to { box-shadow: inset 0 0 0 99px transparent; } }

/* The floating cell editor (js/cs-edit.js): one popover under the cell, above it when there is no room. */
.cs-edit-pop { position: fixed; z-index: 1070; background: #fff; border: 1px solid #b2b2b2; border-radius: 8px; box-shadow: 0 8px 24px rgba(28, 28, 28, 0.22); padding: 8px 8px 6px; font-size: .8rem; width: max-content; min-width: 190px; max-width: min(340px, calc(100vw - 16px)); }
.cs-edit-pop::before { content: ''; position: absolute; left: var(--cs-edit-arrow, 18px); top: -6px; width: 10px; height: 10px; background: #fff; border: solid #b2b2b2; border-width: 1px 0 0 1px; transform: translateX(-50%) rotate(45deg); }
.cs-edit-pop.above::before { top: auto; bottom: -6px; transform: translateX(-50%) rotate(225deg); }
.cs-edit-title { font-weight: 600; color: #2b2b2b; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cs-edit-hint { color: var(--cs-muted); font-size: .75rem; margin-top: 1px; }
.cs-edit-row { display: flex; gap: 4px; align-items: center; margin-top: 6px; }
.cs-edit-row > :first-child { flex: 1; min-width: 0; }
.cs-edit-pop .btn { min-width: 28px; min-height: 28px; padding: 0 6px; }
.cs-edit-pop label { display: block; font-weight: 600; font-size: .72rem; color: #393939; margin: 6px 0 2px; }
.cs-edit-keys { color: var(--cs-muted); font-size: .7rem; margin-top: 6px; }

/* The page's action bar (Design §8.2): the header sticks under the top bar, so its actions stay in view. */
.cs-page-header:has(.cs-actionbar) { position: sticky; top: var(--cs-bar-h); z-index: 20; background: var(--cs-page-bg); margin: -8px -4px 12px; padding: 8px 4px 6px; box-shadow: 0 1px 0 #e4e4e4; }
.cs-actionbar { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; justify-content: flex-end; margin-left: auto; }

/* Row actions (Design §8.3): a ⋯ menu at the right end of each row. */
.cs-table :is(th, td).cs-rowmenu { width: 34px; text-align: right; padding-left: 2px; padding-right: 4px; white-space: nowrap; }
.cs-rowmenu > .dropdown > .btn, .cs-rowmenu > .btn { --bs-btn-padding-y: 0; --bs-btn-padding-x: .35rem; line-height: 1.3; }
.cs-rowmenu .dropdown-toggle::after { display: none; }

/* Who is editing (Design §7.8): your own lock is a pill; someone else's is a read-only banner. */
.cs-editing { display: inline-flex; align-items: center; gap: 6px; padding: 1px 4px 1px 9px; border-radius: 999px; background: #fff0df; border: 1px solid #f3d2ac; color: #954b00; font-size: .76rem; font-weight: 600; white-space: nowrap; } /* 5.6:1 */
.cs-editing .btn { --bs-btn-padding-y: 0; --bs-btn-padding-x: .45rem; --bs-btn-font-size: .72rem; border-radius: 999px; }
.cs-readonly { display: flex; align-items: center; gap: 10px; padding: 7px 12px; margin-bottom: 12px; border-radius: 8px; background: #fff4d4; border: 1px solid #efdc9f; color: #6b4500; font-size: .84rem; } /* 6.9:1 */
.cs-readonly .btn { margin-left: auto; }

/* Fixes found while rebuilding the mockups (October 14). */
.cs-table > tbody > tr > td.cs-overridden { --bs-table-bg: #fff4d4; } /* a value typed over a computed one; the computed value goes in the callout. #2b2b2b 13.9:1 */
.cs-table-scroll, .table-responsive { position: relative; } /* keeps visually-hidden text and callouts inside the scroll box */
.cs-table-scroll, .table-responsive { container-type: inline-size; } /* the box's own width, for what sits inside a wide table */
/* An empty state in a cell that spans a table wider than its scroll box stays in view and centres in the box's visible
 * width, not the table's (which put the words past the card's edge; the owner, October 26, Design §12.4). */
.cs-table-scroll td > .cs-empty, .table-responsive td > .cs-empty { position: sticky; left: 0; width: min(100%, 100cqw); }
body:has(.cs-context) .cs-page-header:has(.cs-actionbar) { position: static; box-shadow: none; } /* with a context bar, the bar sticks instead of the header */
.cs-w-num { max-width: 12rem; } .cs-w-money { max-width: 16rem; } .cs-w-email { max-width: 24rem; } /* field width caps (Design §10.3): number and date / money / email */
.cs-content:has(.cs-savedock) { padding-bottom: 84px; } /* the fixed save dock never covers the last card */
.cs-card > .head code { color: #ffe1ef; background: #ffffff1f; } /* code on a steel head: 6.9:1 */
.cs-badge.tone-neutral { --tone: #4b4b4b; --tone-bg: #ededed; --tone-border: #d9d9d9; } /* the default, by name: new, not started */
@media (max-width: 575.98px) { .cs-page-header:has(.cs-actionbar) { position: static; box-shadow: none; } } /* on phones the header would eat the screen */
.cs-table > thead > tr > th:is(.cs-kind-base, .cs-kind-2, .cs-kind-3) { background-image: none; } /* the head's gradient would hide the kind fill */
.cs-actionbar [data-tip]::after, .cs-context [data-tip]::after { bottom: auto; top: calc(100% + 6px); } /* callouts under the fixed top bar open downward */
.cs-table .cs-clip { white-space: nowrap; } /* put data-tip on a span inside it: overflow: hidden would clip the cell's own callout */
/* [Proposed, October 20] A group row (tr.cs-subhead: a crew's tasks, a phase's lines) is a steel band that stands out from
 * the rows under it: the same band on every group row (never striped, never lit by hover), a firmer line above it and
 * the group's name in bold dark text, in its own case. Darker than the table head's light steel, lighter than a button. */
.cs-table { --cs-group-bg: #dbdbdb; }
.cs-table > tbody > tr.cs-subhead { font-size: inherit; letter-spacing: 0; text-transform: none; }
.cs-table > tbody > tr.cs-subhead > td { --bs-table-bg: var(--cs-group-bg); --bs-table-bg-type: var(--cs-group-bg); --bs-table-bg-state: var(--cs-group-bg); background-image: none; font-weight: 700; color: #2b2b2b; padding-top: 5px; padding-bottom: 5px; border-top: 2px solid #a9a9a9; border-bottom-color: #bfbfbf; } /* #2b2b2b on the band 10.2:1 */
.cs-table > tbody > tr.cs-subhead > td :is(.text-dgray, .text-gray, .text-muted) { color: #474747 !important; } /* 6.7:1 on the band */
/* The outer band (tr.cs-subhead.is-outer), for a group that holds groups (a day over its crews): a darker steel, the same
 * dark text, so the two levels read apart at a glance (the owner, October 26). */
.cs-table > tbody > tr.cs-subhead.is-outer > td { --cs-group-bg: #c3c3c3; border-top-color: #919191; border-bottom-color: #a9a9a9; } /* #2b2b2b on it 8.6:1 */
.cs-table > tbody > tr.cs-subhead.is-outer > td :is(.text-dgray, .text-gray, .text-muted) { color: #3a3a3a !important; } /* 7.3:1 */

/* A sticky context bar under the page header for a record with parts (Design §11.4). */
.cs-context { position: sticky; top: var(--cs-bar-h); z-index: 19; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; padding: 6px 10px; margin-bottom: 12px; background: #fff; border: 1px solid #dfdfdf; border-radius: 8px; box-shadow: var(--cs-shadow-1); font-size: .84rem; }
.cs-context .crumb { color: var(--cs-muted); }
.cs-context .crumb + .crumb::before { content: '›'; margin-right: 6px; color: #a5a5a5; }
.cs-context .ms-auto { margin-left: auto; }

/* ---------------------------------------------------------------------------
 * [Proposed] Round 6 pieces (October 15, demos/FEEDBACK-2026-10-15.md): column lines in every table, the floating
 * callout, slim 24px controls in heads and bars, the bar and meta rows on a card, status top right, full-width
 * rows, list beside detail, people (avatar and name), the log, and the app switcher. Soft picks: try them on real screens.
 * ------------------------------------------------------------------------- */
:root {
    --cs-table-line: #e7e7e7; /* a column line on white and on the stripe: light, never a group marker */
    --cs-table-head-line: #cccccc; /* the head's column line: 1px, a little darker than the body's, on the steel head */
}

/* Every table has thin, light column lines: 1px between cells, on every row. Never 2px (subtotal, total and
 * card-head rules are 1px too). A frozen column keeps a 1px edge as an inset shadow, which scrolls with it. */
.cs-table > :not(caption) > * > *:not(:last-child) { border-right: 1px solid var(--cs-table-line); }
.cs-table > thead > tr > th:not(:last-child) { border-right-color: var(--cs-table-head-line); }
.cs-drill-row .cs-table > thead > tr > th:not(:last-child) { border-right-color: var(--cs-table-head-line); } /* a child table's head is light */
.cs-table > :is(tbody, tfoot) > tr > .cs-grid-sticky { box-shadow: inset -1px 0 0 #d7d7d7, inset 0 0 0 9999px var(--bs-table-bg-state, var(--bs-table-bg-type, var(--bs-table-accent-bg))); }
.cs-table > thead > tr > th.cs-grid-sticky { box-shadow: inset -1px 0 0 #c0c0c0, inset 0 -1px 0 #c0c0c0; }

/* The floating callout (js/cs-tip.js): one page-level box, placed above the element (below it near the top of the
 * screen, and for a th), so a scroll box or a sticky head never clips it. With the script loaded, the CSS ::after
 * callouts (Design §7.5, further up) stay as the fallback only. */
html.cs-tip-js [data-tip]:not(.dropdown-toggle)::after { display: none; } /* :not keeps Bootstrap's dropdown caret */
.cs-tip-float { position: fixed; top: 0; left: 0; z-index: 1080; width: max-content; max-width: min(280px, calc(100vw - 16px)); padding: 4px 8px; border-radius: 4px; background: #2b2b2b; color: #fff; font: 600 .74rem/1.3 var(--bs-body-font-family); letter-spacing: 0; text-transform: none; text-align: left; white-space: pre-line; overflow-wrap: anywhere; pointer-events: none; box-shadow: 0 4px 12px rgba(28, 28, 28, 0.22); } /* white 14.1:1; long notes wrap at 280px */
.cs-tip-float[hidden] { display: none; }
.cs-tip-float::before { content: ''; position: absolute; left: var(--cs-tip-x, 50%); bottom: -4px; width: 8px; height: 8px; background: inherit; transform: translateX(-50%) rotate(45deg); }
.cs-tip-float.below::before { bottom: auto; top: -4px; }

/* A card's controls get their own row under the head (.bar): view toggles, level switches, counts, a select.
 * Items are centred with a small gap; .ms-auto pushes the rest right. */
.cs-card > .bar { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; min-height: 34px; padding: 5px 12px; background: linear-gradient(180deg, var(--cs-shade-1), var(--cs-shade-2)); border-bottom: 1px solid var(--cs-shade-3); font-size: .78rem; color: #393939; } /* a step over the white card: 10.3:1 at the foot */
.cs-card > .bar:last-child { border-bottom: 0; border-radius: 0 0 9px 9px; }
.cs-card > .bar .text-dgray { color: #585858 !important; } /* 6.3:1 at the foot */

/* Slim controls (24px, a size smaller than .btn-sm) in the page's action bar, card heads and bars, filter bars and a
 * split list's filters, so buttons, groups, menus, selects and badges there are one even height, icons centred. */
:is(.cs-actionbar, .cs-card > .head, .cs-card > .bar, .cs-filter-bar, .cs-split-filter) .btn:not(.btn-link, .btn-close, .cs-editing .btn, .dropdown-menu .btn) {
    --bs-btn-padding-y: 0; --bs-btn-padding-x: .5rem; --bs-btn-font-size: .75rem; --bs-btn-line-height: 1.3;
    height: 24px; display: inline-flex; align-items: center; justify-content: center; gap: .3em; white-space: nowrap; vertical-align: middle;
}
:is(.cs-actionbar, .cs-card > .head, .cs-card > .bar, .cs-filter-bar, .cs-split-filter) .btn.dropdown-toggle::after { margin-left: .1em; }
:is(.cs-actionbar, .cs-card > .head, .cs-card > .bar, .cs-filter-bar, .cs-split-filter) :is(.form-control, .form-select):not(textarea) { height: 24px; min-height: 24px; padding-top: 0; padding-bottom: 0; font-size: .75rem; line-height: 1.3; }
:is(.cs-actionbar, .cs-card > .head, .cs-card > .bar, .cs-filter-bar, .cs-split-filter) .form-select { padding-right: 1.6rem; background-position: right .4rem center; background-size: 12px 9px; }
:is(.cs-actionbar, .cs-card > .head, .cs-card > .bar, .cs-filter-bar, .cs-split-filter) .input-group-text { height: 24px; padding-top: 0; padding-bottom: 0; font-size: .75rem; }
:is(.cs-actionbar, .cs-card > .head, .cs-card > .bar, .cs-filter-bar, .cs-split-filter) .cs-select-wrapper { --cs-select-fs: .75rem; --cs-select-py: .18rem; } /* 24px */
:is(.cs-actionbar, .cs-card > .head > :not(:first-child)) .cs-badge:not(.cs-status-stack .cs-badge), .cs-card > .head > .cs-badge:not(:first-child),
:is(.cs-actionbar, .cs-card > .head) .cs-editing { min-height: 24px; padding-top: 0; padding-bottom: 0; vertical-align: middle; }

/* A record card's facts sit in a meta row under the head (.cs-card > .meta): since Round 7 each child is a split-box
 * fact, like .cs-fact. See "Read-only facts" in the Round 7 block. */

/* A record's status sits top right of its page header or card head: a lone .cs-status (a badge, or a box holding
 * one), or several down the right in .cs-status-stack. */
:is(.cs-status, .cs-status-stack) { margin-left: auto; align-self: flex-start; flex-shrink: 0; }
.cs-status-stack { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; }
.cs-status { display: inline-flex; align-items: center; gap: 4px; }
.cs-page-header > :is(.cs-status, .cs-status-stack) ~ .cs-actionbar, .cs-page-header > .cs-actionbar ~ :is(.cs-status, .cs-status-stack) { margin-left: 0; }
.cs-card > .head:has(> .cs-status-stack) { align-items: flex-start; }
.cs-card > .head > .cs-status-stack { padding: 1px 0; }
.cs-card > .body > :is(.cs-status, .cs-status-stack):first-child { float: right; margin: 0 0 6px 12px; }

/* Full-width rows (the default for a list of records; the card grid is the exception): fixed places for the name
 * (and a sub line under it), the attributes and the meta, the same columns on every row, at most two lines.
 * Set --cs-row-cols on .cs-rows to change the widths for a list. */
.cs-rows { list-style: none; margin: 0; padding: 0; --cs-row-cols: minmax(12rem, 2fr) minmax(0, 3fr) minmax(7rem, 12rem); }
.cs-rows > .cs-row { display: grid; grid-template-columns: var(--cs-row-cols) auto; grid-template-areas: "name attrs meta end" "sub attrs meta end"; column-gap: 14px; align-items: center; padding: 6px 14px; border-bottom: 1px solid var(--cs-border); color: inherit; text-decoration: none; font-size: .84rem; line-height: 1.35; }
.cs-rows > .cs-row:last-child { border-bottom: 0; }
.cs-row > .name { grid-area: name; min-width: 0; font-weight: 600; color: #2b2b2b; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* 14.1:1 */
.cs-row > .sub { grid-area: sub; min-width: 0; font-size: .75rem; color: var(--cs-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* 7.1:1 */
.cs-row > .attrs { grid-area: attrs; min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 2px 8px; max-height: 2.8em; overflow: hidden; }
.cs-row > .meta { grid-area: meta; min-width: 0; text-align: right; font-size: .75rem; color: var(--cs-muted); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.cs-row > .end { grid-area: end; display: flex; align-items: center; justify-content: flex-end; gap: 6px; }
:is(a.cs-row, .cs-row.is-link, .cs-row[role="button"]) { cursor: pointer; }
:is(a.cs-row, .cs-row.is-link, .cs-row[role="button"]):hover { background-image: linear-gradient(var(--cs-data-shade-2), var(--cs-data-shade-2)); } /* a step over the row's own colour, a deleted or archived tint included */
.cs-row:is(.active, [aria-selected="true"], [aria-current]:not([aria-current="false"])) { background: #eaf0f7; box-shadow: inset 3px 0 0 var(--cs-accent); } /* #2b2b2b 12.2:1 */
@media (max-width: 767.98px) {
    .cs-rows > .cs-row { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "name end" "sub end" "attrs attrs" "meta meta"; row-gap: 2px; }
    .cs-row > .meta { text-align: left; }
}

/* List beside detail, for records people change one after another: a list column (about 360px) that sticks and
 * scrolls on its own, filter controls on top and clickable rows with a selected state, beside the detail.
 * It stacks on phones. The list's last child scrolls; anything above it (filters, a head) stays put. */
.cs-split { display: grid; grid-template-columns: var(--cs-split-w, 360px) minmax(0, 1fr); gap: 16px; align-items: start; }
:root { --cs-sticky-head: 0px; } /* the height of what sticks under the top bar (a page header with an action bar, a context bar) */
body:has(.cs-page-header .cs-actionbar) { --cs-sticky-head: 64px; }
body:has(.cs-context) { --cs-sticky-head: 50px; } /* the context bar sticks instead of the header */
@media (max-width: 575.98px) { body:has(.cs-page-header .cs-actionbar) { --cs-sticky-head: 0px; } } /* the header doesn't stick on a phone (above), so nothing under it leaves a gap */
.cs-split-list { position: sticky; top: calc(var(--cs-bar-h) + var(--cs-sticky-head) + 12px); max-height: calc(100vh - var(--cs-bar-h) - var(--cs-sticky-head) - 24px); display: flex; flex-direction: column; min-width: 0; margin-bottom: 0; background: #fff; border: 1px solid #dfdfdf; border-radius: 10px; box-shadow: var(--cs-shadow-1); overflow: hidden; }
.cs-split-list > * { flex: none; }
.cs-split-list > :last-child { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.cs-split-list > :is(.cs-split-filter, .cs-filter-bar) { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 0; padding: 6px 8px; border: 0; border-bottom: 1px solid var(--cs-form-border); border-radius: 0; box-shadow: none; background: linear-gradient(180deg, var(--cs-form-bg), var(--cs-form-bg-2)); }
.cs-split-list > :is(.cs-split-filter, .cs-filter-bar) :is(.form-control, .form-select) { min-width: 0; }
.cs-split-list > :is(.cs-split-filter, .cs-filter-bar) .form-control { width: auto; flex: 1 1 8rem; } /* a search box shares the row */
.cs-split-item { display: flex; align-items: center; gap: 10px; padding: 6px 12px; border-bottom: 1px solid var(--cs-border); color: inherit; text-decoration: none; font-size: .84rem; line-height: 1.35; cursor: pointer; }
.cs-split-item > .grow { flex: 1; min-width: 0; }
.cs-split-list :is(.cs-split-item, .cs-row, .cs-list > li, .list-group-item) { cursor: pointer; }
.cs-split-list :is(.cs-split-item, .cs-row, .cs-list > li, .list-group-item):hover { background-image: linear-gradient(var(--cs-data-shade-2), var(--cs-data-shade-2)); color: inherit; }
.cs-split-list :is(.cs-split-item, .cs-row, .cs-list > li, .list-group-item):is(.active, [aria-selected="true"], [aria-current]:not([aria-current="false"])) { background: #eaf0f7; color: #2b2b2b; border-color: var(--cs-border); box-shadow: inset 3px 0 0 var(--cs-accent); } /* 12.2:1 */
.cs-split-detail { min-width: 0; }
/* Row state on list rows, as on table rows (Design §7.3): a tint, no strike-through. #2b2b2b 13.6:1 / 12.9:1 */
:where(.cs-split-item, .cs-row).is-deleted { background: #fdecec; } /* :where keeps hover and the selected state on top */
:where(.cs-split-item, .cs-row).is-archived { background: #eeeeee; }
@media (max-width: 767.98px) {
    .cs-split { grid-template-columns: minmax(0, 1fr); }
    .cs-split-list { position: static; max-height: 50vh; }
}

/* A person: avatar plus name, as much as the room allows. .cs-who-full (full name), .cs-who-first (first name) or
 * .cs-who-avatar (the avatar only; the name stays in the markup for screen readers and goes in the callout).
 * The page sets the avatar's colour; an icon in the circle stands for a system or a supplier. */
.cs-who { display: inline-flex; align-items: center; gap: 5px; max-width: 100%; min-width: 0; overflow: hidden; vertical-align: middle; white-space: nowrap; line-height: 1.3; }
.cs-who > .cs-avatar { width: 20px; height: 20px; flex: none; background: #646464; color: #fff; font-size: .6rem; font-weight: 600; letter-spacing: 0; } /* white 5.9:1 on the default; the palette colours are 4.6:1 or more */
.cs-who > .cs-avatar > .bi { font-size: .7rem; line-height: 1; }
.cs-who-avatar { gap: 0; font-size: 0; } /* hides the name text; the avatar's own sizes are in rem */
.cs-table-dense .cs-who > .cs-avatar, .cs-log .cs-who > .cs-avatar { width: 18px; height: 18px; font-size: .56rem; }

/* A log: one line per entry, small type: the time (a fixed column), who, then what happened. [Proposed, October 16] An
 * entry may carry its changes as small inline facts (.cs-changes > .cs-change) and then wraps compactly: see "The
 * activity log" in the Round 9 block. */
.cs-log { list-style: none; margin: 0; padding: 0; font-size: .75rem; line-height: 1.35; --cs-log-time: 6.5rem; --cs-log-who: 5.5rem; } /* fits a 480px drawer; set wider on a page with room */
.cs-log > li { display: grid; grid-template-columns: var(--cs-log-time) var(--cs-log-who) minmax(0, 1fr); column-gap: 10px; align-items: center; min-height: 24px; padding: 2px 12px; border-bottom: 1px solid #f0f0f0; white-space: nowrap; }
.cs-log > li:last-child { border-bottom: 0; }
.cs-log > li > time { color: var(--cs-muted); font-variant-numeric: tabular-nums; overflow: hidden; text-overflow: ellipsis; } /* 7.1:1 */
.cs-log > li > .cs-who { min-width: 0; }
.cs-log > li > .what { min-width: 0; overflow: hidden; text-overflow: ellipsis; color: #2b2b2b; } /* 14.1:1; the whole line in the callout when it's cut */

/* The app switcher: the app's name in the top bar opens the list of apps this person may use, the current one
 * marked. Like the user menu, the toggle fills the bar's height and the menu hangs from the bar's bottom edge. */
.cs-brand { align-self: stretch; }
.cs-apps { position: relative; display: flex; align-self: stretch; margin-left: -8px; }
.cs-apps-toggle.cs-wordmark { display: flex; align-items: center; height: 100%; padding: 0 8px; }
.cs-apps-toggle:hover, .cs-apps-toggle:focus-visible, .cs-apps-toggle.show { background: #2b2b2b; opacity: 1; }
a.cs-apps-toggle.cs-wordmark:hover { opacity: 1; }
.cs-apps-toggle::after { border-top-width: 5px; border-right-width: 4px; border-left-width: 4px; margin-left: 7px; vertical-align: middle; opacity: .75; }
.cs-apps-icon { display: none; }
.cs-apps .dropdown-menu[data-bs-popper] { top: 100%; left: 0; margin-top: 0; min-width: 15rem; border-top: 0; border-radius: 0 0 8px 8px; box-shadow: 0 10px 24px #0f1c2833; }
.cs-apps-menu .dropdown-header { font-size: .68rem; letter-spacing: .06em; text-transform: uppercase; color: var(--cs-muted); } /* 7.1:1 */
.cs-apps-menu .dropdown-item { display: flex; align-items: center; } /* the icon column and padding are every menu's (below) */
.cs-apps-menu .dropdown-item.is-current { background: #eef3fa; color: #2b2b2b; font-weight: 600; } /* 12.6:1 */
.cs-apps-menu .dropdown-item.is-current > .bi { color: var(--cs-accent); } /* icon 4.2:1 */
@media (max-width: 575.98px) {
    .cs-apps-toggle.cs-wordmark { display: flex; font-size: 0; }
    .cs-apps-toggle::after { margin-left: 4px; }
    .cs-apps-icon { display: inline-block; font-size: 16px; }
}

/* ---------------------------------------------------------------------------
 * [Proposed] Round 6b pieces (October 15, evening): the light steel head (above, with the tables), .cs-divider for
 * grouped heads (above), a scope code set to none, notes, the stronger subtotal (above) and people that fit their room.
 * The big-list picker is its own file, css/cs-picker.css. Soft picks: try them on real screens.
 * ------------------------------------------------------------------------- */

/* A scope code set to none (Design §7.5): a light grey placeholder, the code with an X for the icon (bi-x-lg), the
 * words in the callout ("Foundation: none"). It is a value, not an empty slot. */
.cs-code.is-none { --code-a: #e3e3e3; --code-b: #efefef; color: #494949; box-shadow: inset 0 0 0 1px #d4d4d4; } /* #494949 7.0:1 */
.cs-code.is-none > .v { color: #757575; font-size: .62rem; } /* the X a half lighter: 4.0:1 */

/* Notes are yellow: a block (div.cs-note) or inline (span.cs-note) note, and the note marker (.cs-ic.is-note, the amber
 * bi-sticky-fill) where a note is attached to a row or an item; its text goes in the callout. */
.cs-note { display: block; padding: 6px 10px; border: 1px solid #efdc9f; border-radius: 6px; background: #fff6dc; color: #6b4500; font-size: .8rem; line-height: 1.4; overflow-wrap: anywhere; } /* 7.9:1 */
span.cs-note { display: inline; padding: 0 5px; border-radius: 4px; font-size: .78em; line-height: inherit; box-decoration-break: clone; -webkit-box-decoration-break: clone; }
.cs-note > .bi:first-child { margin-right: 4px; color: #8a5d00; } /* 5.3:1 */
.cs-ic.is-note { color: #8a5d00; } /* 5.8:1 on white, 5.3:1 on the note yellow */
/* A block note ends with its byline at the lower right: the author (.cs-who-first, the full name in the callout) and
 * the date, small and muted. An inline note (span.cs-note) has no room: "by First Last · date" goes in its callout. */
.cs-note > .byline { display: flex; justify-content: flex-end; align-items: center; flex-wrap: wrap; gap: 2px 6px; margin-top: 3px; font-size: .7rem; line-height: 1.3; color: #7a5a1f; } /* 5.9:1 on the note yellow */
.cs-note > .byline > .cs-who { color: inherit; font-weight: 600; }
.cs-note > .byline > .cs-who > .cs-avatar { width: 16px; height: 16px; font-size: .5rem; }
.cs-note > .byline > time { white-space: nowrap; font-variant-numeric: tabular-nums; }

/* Dropdown menus (js/cs-menus.js places them): one layer for every Bootstrap menu, above the sidebar (1030), the top
 * bar (1035) and sticky heads, below the drawer backdrop (1044), the drawer (1045) and callouts (1080). Layers table
 * (Design §4.5): "Dropdown menus | 1038". A menu can't rise above the box it sits in, so while one is open cs-menus.js
 * lifts the sticky or positioned boxes around it (.cs-menu-host) to the same layer. */
.dropdown-menu { --bs-dropdown-zindex: 1038; }
.cs-menu-host { z-index: 1038 !important; }

/* Every button menu is compact and tidy (October 15): 4px inside, an 8px radius, a 1px light border and a soft shadow,
 * as wide as its content (10rem to 22rem; a longer label wraps). Items are 26px at .8rem with the icon in a fixed
 * narrow column, so the labels line up; hover and focus get a light tint. A divider is 1px with little margin, a
 * header small, uppercase and muted; a disabled item is muted with its "why" (.why) small underneath; a danger item is
 * red and goes last, after a divider. The user menu and the app switcher keep their flat top (they hang from the bar).
 * A menu with one choice is not a menu: it is that one button (Design §8.3). A greyed item counts, because it is
 * sometimes active: one action and one greyed item stay a menu (October 15, late). */
.dropdown-menu {
    --bs-dropdown-padding-x: 4px; --bs-dropdown-padding-y: 4px; --bs-dropdown-font-size: .8rem; --bs-dropdown-color: #2b2b2b;
    --bs-dropdown-min-width: 10rem; --bs-dropdown-border-color: #dfdfdf; --bs-dropdown-border-radius: 8px; --bs-dropdown-inner-border-radius: 7px;
    --bs-dropdown-box-shadow: 0 6px 18px rgba(26, 26, 26, 0.14); --bs-dropdown-divider-bg: #e7e7e7; --bs-dropdown-divider-margin-y: 3px;
    --bs-dropdown-link-color: #2b2b2b; --bs-dropdown-link-hover-color: #2b2b2b; --bs-dropdown-link-hover-bg: var(--cs-shade-2); /* 12.6:1 */
    --bs-dropdown-link-active-color: #2b2b2b; --bs-dropdown-link-active-bg: var(--cs-shade-3); /* 11.7:1 */
    --bs-dropdown-link-disabled-color: #707070; /* 4.9:1 */
    --bs-dropdown-item-padding-x: 8px; --bs-dropdown-item-padding-y: 4px; --bs-dropdown-header-color: var(--cs-muted); --bs-dropdown-header-padding-x: 8px; --bs-dropdown-header-padding-y: 4px;
    width: max-content; max-width: calc(100vw - 16px); box-shadow: var(--bs-dropdown-box-shadow); font-size: .8rem;
}
.dropdown-menu:has(> li > .dropdown-item) { max-width: min(22rem, calc(100vw - 16px)); } /* a list of actions; a menu holding a grid or a form keeps its own width */
.dropdown-menu > li > hr.dropdown-divider { margin-left: 4px; margin-right: 4px; opacity: 1; }
.dropdown-item { position: relative; min-height: 26px; padding-left: calc(8px + 1.1rem + 6px); border-radius: 4px; font-size: .8rem; line-height: 1.3; white-space: normal; }
.dropdown-item > .bi:first-child { position: absolute; left: 8px; top: 4px; width: 1.1rem; text-align: center; line-height: 1.3; color: var(--cs-muted); } /* 7.1:1, 6.3:1 on the hover tint */
.dropdown-item:focus-visible { outline: 2px solid var(--cs-accent); outline-offset: -2px; }
.dropdown-item.text-danger { color: #b02a37 !important; } /* 6.5:1 on white, 5.7:1 on its tint */
.dropdown-item.text-danger:is(:hover, :focus) { background: #fdecec; }
.dropdown-item.text-danger > .bi:first-child { color: inherit; }
.dropdown-item.disabled > .bi:first-child { color: inherit; }
.dropdown-item .why { margin-top: 1px; font-size: .7rem; line-height: 1.3; color: #707070; } /* 4.9:1 */
.dropdown-header { padding: 5px 8px 2px; font-size: .66rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--cs-muted); } /* 7.1:1 */
/* One choice: the menu's single item as a small solid icon button (CS.menuButton in the mockups), only when that one
 * item is enabled and the menu has no greyed items. */
.cs-menu-one { --bs-btn-padding-x: .4rem; }

/* A person that fits the room (.cs-who-fit, on a .cs-who-full; CS.who(name, 'full') adds it): the avatar and the full
 * name where there is room, the first name when the cell is squeezed, the avatar alone when it is squeezed further. The
 * name is two spans (.f, the first name, and .l, the rest) in a one-line box that drops what doesn't fit; the whole
 * name stays in the markup for screen readers and goes in the callout. Its narrowest is the avatar, so a table can
 * squeeze the column; its widest is the full name, so it gets that when there's room. */
.cs-who-fit { display: inline-grid; grid-template-columns: auto minmax(0, max-content); align-items: center; }
.cs-who-fit > .nm { display: flex; flex-wrap: wrap; height: 1.3em; overflow: hidden; }
.cs-who-fit > .nm::before { content: ''; width: 0; } /* a first, empty item: a name that doesn't fit beside it wraps away */
.cs-who-fit > .nm > .l { margin-left: .28em; }

/* ---------------------------------------------------------------------------
 * [Proposed] Round 7 pieces (October 15, late; the owner's answers on demos/questions.html): read-only facts as split
 * boxes (Design §5.6), one head line above a table with the filter-and-sort row shown only when used (§5.5, §6.4),
 * and space after icons so icon-and-text pairs never run into each other (§3.5). Soft picks: try them on real screens.
 * ------------------------------------------------------------------------- */
:root {
    --cs-fact-label-bg: var(--cs-shade-3); /* the label's grey area, a step over the white box (was #eaeaea); the label text #585858 on it is 5.9:1 */
    --cs-fact-line: #dadada; /* the box's hairline, and the line between the label and the value */
    --cs-fact-shadow: 0 1px 2px rgba(35, 35, 35, 0.1), 0 2px 4px -2px rgba(30, 30, 30, 0.08);
    --cs-facts-bg: linear-gradient(180deg, var(--cs-shade-2), var(--cs-shade-1)); /* the row the facts sit on: a step over its base, lighter than the label grey (was #f1f1f1 → #f8f8f8) */
    --cs-fact-label-w: 8rem; /* [Proposed, October 16] the label column when facts line up (dl.cs-kv, .cs-facts-grid): "Delivery window", "Labor rate set", "Created by" on one line (was 6rem) */
    --cs-fact-label-max: 9rem; /* [Proposed, October 16] the widest a label gets in a box that sizes it to its words; a longer one wraps */
    --cs-fact-col: 22rem; /* [Proposed, October 20] a column of facts: two at most, each at least this wide, so a fact is never squeezed (16rem October 16, 14rem before) */
    --cs-fact-col-min: 14rem; /* [Proposed, October 20] the narrowest fact in a row of four or fewer, read left to right (was 11rem, the narrowest of .cs-facts-cols-2|3|4) */
    --cs-fact-value-min: 12rem; /* [Proposed, October 30] the narrowest value beside a lined-up label: a detail list's four or fewer facts go one a line before a value gets less (CrewTeam's stage panel, a 6rem value) */
    --cs-fact-gap: 6px; /* between two facts in a column */
}

/* Read-only facts (Design §5.6). One fact is a split box: a small uppercase muted label on grey, a hairline, the value on
 * white, a slight shadow. The kit's one fact style, in three forms:
 *   .cs-fact > .label + .value                     inside a .cs-facts row (or a .cs-facts.cs-facts-grid)
 *   .cs-card > .meta > *                           the meta row under a record's head: any child is one fact, its first
 *                                                  .label / dt / .text-dgray / .text-gray child the label, .value / dd the value
 *   dl.cs-kv > dt + dd (or > div > dt + dd)        a detail list: each pair one fact, the labels lined up
 * A long value wraps inside its box; an empty .value / dd shows "—"; a person (.cs-who), badges and codes sit in the
 * value. Wrap a value that mixes text and elements in .value (or dd): a bare text value is fine on its own.
 * The row of facts has its own background (--cs-facts-bg), lighter than the label grey.
 *
 * [Proposed, October 15, night] Facts flow down, then across. Every fact container is CSS columns (--cs-fact-col, about
 * 16rem each since October 16, as many as fit, balanced): the facts fill the first column top to bottom, then the next,
 * so a tall value only pushes the facts under it in its own column, never a neighbour across. One rule for rows and grids
 * alike: with few facts the balancing puts one fact in each column, so a short set still reads as one row. A .wide fact
 * (or dt.wide and its dd) spans every column; facts before it balance above it, facts after it below. On a phone a row
 * (.cs-facts, .meta) keeps two columns; a detail list (dl.cs-kv, .cs-facts-grid) is one, a fact a line.
 * The label lines up in a list and a grid (--cs-fact-label-w); in a row it is as wide as its words.
 *
 * [Proposed, October 16] Labels have room. The label column is 8rem, so the usual labels sit on one line; a longer
 * label wraps to a second line inside its box (the box grows), never past it. A label sized to its words stops at
 * --cs-fact-label-max (9rem) and wraps from there. The one exception is a bare dt + dd pair (below): its label is one
 * line, cut with … and given the whole label in a callout (cs-tip.js); a detail list whose labels run long wraps each
 * pair in a div, where the label wraps. The flow is only the default: the page places facts itself with
 * .cs-facts-cols-2|3|4, .cs-fact-group, .wide and .cs-facts-row (inline mode), in the Round 9 block at the end. */
.cs-facts, .cs-card > .meta, dl.cs-kv {
    display: block; column-count: 2; column-width: var(--cs-fact-col); column-gap: 8px; column-fill: balance;
    margin: 0; font-size: .8rem; line-height: 1.35; color: #2b2b2b; background: var(--cs-facts-bg);
}
.cs-facts, dl.cs-kv { padding: 8px; border-radius: 8px; }
.cs-card > .meta { padding: 7px 12px 8px; border-bottom: 1px solid #e4e4e4; }
.cs-card > .meta:last-child { border-bottom: 0; border-radius: 0 0 9px 9px; }
:is(.cs-fact, .cs-card > .meta > :not(.cs-fact-group), .cs-card > .meta > .cs-fact-group > *) {
    display: inline-flex; align-items: center; gap: 0 9px; min-width: 0; max-width: 100%; min-height: 25px; margin: 0; padding: 3px 9px 3px 0;
    background: #fff; border: 1px solid var(--cs-fact-line); border-radius: 6px; box-shadow: var(--cs-fact-shadow);
    color: #2b2b2b; font-weight: 500; overflow-wrap: anywhere; /* #2b2b2b 14.1:1 on white */
}
/* In a column each fact is the column's width and stays whole */
:is(:is(.cs-facts, .cs-fact-group) > .cs-fact, .cs-card > .meta > :not(.cs-fact-group), .cs-card > .meta > .cs-fact-group > *) { display: flex; width: 100%; margin: 0 0 var(--cs-fact-gap); break-inside: avoid; }
:is(.cs-fact > .label, :is(.cs-card > .meta > :not(.cs-fact-group), .cs-card > .meta > .cs-fact-group > *) > :is(.label, dt, .text-dgray, .text-gray):first-child) {
    flex: none; align-self: stretch; max-width: var(--cs-fact-label-max); margin: -3px 0; padding: 6px 8px 3px; background: var(--cs-fact-label-bg); border-right: 1px solid var(--cs-fact-line); border-radius: 5px 0 0 5px;
    color: #585858 !important; font-size: .62rem; font-weight: 700; line-height: 1.3; letter-spacing: .07em; text-transform: uppercase; white-space: normal; overflow-wrap: normal; /* 5.9:1 */
}
:is(.cs-fact > .value, :is(.cs-card > .meta > :not(.cs-fact-group), .cs-card > .meta > .cs-fact-group > *) > :is(.value, dd)) { display: block; flex: 1 1 auto; min-width: 0; margin: 0; padding: 0; color: #2b2b2b; font-weight: 500; }
:is(.cs-fact > .value, :is(.cs-card > .meta > :not(.cs-fact-group), .cs-card > .meta > .cs-fact-group > *) > :is(.value, dd), :is(dl.cs-kv, dl.cs-fact-group) dd):empty::before { content: '—'; color: #696969; font-weight: 400; } /* 5.1:1 */
:is(.cs-fact, .cs-card > .meta > *, :is(dl.cs-kv, dl.cs-fact-group) dd) .cs-codes { display: inline-flex; flex-wrap: wrap; gap: 3px; } /* one record's codes wrap; the fixed slots are for lists */
:is(.cs-fact, .cs-card > .meta > *, :is(dl.cs-kv, dl.cs-fact-group) dd) .sub { color: #585858; font-weight: 400; } /* a quiet part of a value (a time beside a person): 7.0:1 */
/* A grid of facts with the labels lined up (a detail card, a drawer) */
:is(.cs-facts-grid > .cs-fact, .cs-facts-grid > .cs-fact-group > .cs-fact) { align-items: stretch; }
:is(.cs-facts-grid > .cs-fact, .cs-facts-grid > .cs-fact-group > .cs-fact) > .label { width: var(--cs-fact-label-w); max-width: none; }
:is(.cs-facts-grid > .cs-fact, .cs-facts-grid > .cs-fact-group > .cs-fact) > .value { align-self: center; }
/* A detail list. A pair wrapped in a div (<div><dt>…</dt><dd>…</dd></div>) is one box, like .cs-fact, and its label wraps.
 * A bare dt + dd pair sits on one line, so a column never parts them: the dd draws the whole box, its label area
 * included, and the dt's words lie over that area (the dt takes 1px of the line, so it always starts a new one). The dd
 * can't grow to a taller dt, so a bare dt is one line: cut with … past 8rem, its whole text in a callout (cs-tip.js).
 * font-size: 0 on the list stops the space between the two from pushing the dd to a new line. A dl.cs-fact-group (a
 * column of a detail list a page places itself, Round 9) holds its pairs the same way. */
:is(dl.cs-kv, dl.cs-fact-group) { font-size: 0; line-height: 0; }
:is(dl.cs-kv, dl.cs-fact-group) :is(dt, dd) { font-size: .8rem; line-height: 1.35; min-width: 0; margin: 0; overflow-wrap: anywhere; }
:is(dl.cs-kv, dl.cs-fact-group) dt { color: #585858; font-size: .62rem; font-weight: 700; line-height: 1.3; letter-spacing: .07em; text-transform: uppercase; overflow-wrap: normal; } /* 5.9:1 on the label grey */
:is(dl.cs-kv, dl.cs-fact-group) dd { color: #2b2b2b; font-weight: 500; }
:is(dl.cs-kv, dl.cs-fact-group) > dt {
    display: inline-block; vertical-align: top; position: relative; z-index: 1; box-sizing: border-box; width: var(--cs-fact-label-w);
    margin: 0 calc(1px - var(--cs-fact-label-w)) var(--cs-fact-gap) 0; padding: 7px 9px 4px; /* 1px wide on the line, so it can't trail the dd before */
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
:is(dl.cs-kv, dl.cs-fact-group) > dd {
    display: inline-block; vertical-align: top; box-sizing: border-box; width: 100%; min-height: 25px; margin: 0 0 var(--cs-fact-gap) -1px;
    padding: 3px 9px 3px calc(var(--cs-fact-label-w) + 8px); border: 1px solid var(--cs-fact-line); border-radius: 6px; box-shadow: var(--cs-fact-shadow);
    background: linear-gradient(90deg, var(--cs-fact-label-bg) 0 calc(var(--cs-fact-label-w) - 1px), var(--cs-fact-line) 0 var(--cs-fact-label-w), transparent 0) #fff; /* the label's shade over the box's white */
}
:is(dl.cs-kv, dl.cs-fact-group) > div {
    display: flex; align-items: stretch; margin: 0 0 var(--cs-fact-gap); break-inside: avoid; min-height: 25px; overflow: hidden;
    background: #fff; border: 1px solid var(--cs-fact-line); border-radius: 6px; box-shadow: var(--cs-fact-shadow);
}
:is(dl.cs-kv, dl.cs-fact-group) > div > dt { flex: none; width: var(--cs-fact-label-w); padding: 6px 8px 3px; background: var(--cs-fact-label-bg); border-right: 1px solid var(--cs-fact-line); }
:is(dl.cs-kv, dl.cs-fact-group) > div > dd { flex: 1 1 auto; align-self: center; padding: 3px 9px; }
/* The last fact keeps no gap under it */
:is(.cs-facts, .cs-card > .meta, .cs-fact-group) > :last-child, :is(dl.cs-kv, dl.cs-fact-group) > :is(dd:last-child, dt:nth-last-child(2), div:last-child) { margin-bottom: 0; }
/* A wide fact spans every column. A bare dt.wide takes no height of its own: its words lie over its dd's label area. */
:is(.cs-facts, .cs-card > .meta) > .wide, dl.cs-kv > div.wide { column-span: all; }
dl.cs-kv > dt.wide { display: block; column-span: all; height: calc(.62rem * 1.3); padding-top: 0; padding-bottom: 0; margin-bottom: calc(-.62rem * 1.3); top: 7px; } /* one label line tall, then pulled back: it takes no room, and a long label is still cut with … */
dl.cs-kv > dt.wide + dd { display: block; column-span: all; width: auto; margin-left: 0; }
/* A card body holding only a detail list is the facts' row itself */
.cs-card > .body:has(> dl.cs-kv:only-child) { background: var(--cs-facts-bg); }
.cs-card > .body:last-child:has(> dl.cs-kv:only-child) { border-radius: 0 0 9px 9px; }
.cs-card > .body:first-child:last-child:has(> dl.cs-kv:only-child) { border-radius: 9px; }
.cs-card > .body > dl.cs-kv:only-child { padding: 0; background: none; }
/* On a phone a row keeps two columns of short facts; a list or a grid is one column, a fact a line. */
@media (max-width: 575.98px) {
    :is(.cs-facts:not(.cs-facts-grid), .cs-card > .meta) { column-width: auto; column-count: 2; }
}

/* One head line above a table (Design §5.5): the title, a ? help bubble, the count, the facts as quiet text, then at the
 * right a compact search, the funnel toggle, Export and ⋯ (.cs-head-tools). The count shows once; explanations live
 * in the ?, not in hint text. On a phone the tools take their own line under the title.
 *   <div class="head">
 *     <div><h2>…</h2><button class="cs-help" …></button><span class="cs-count">24 of 214 RFPs</span>
 *       <span class="cs-head-facts"><span><i class="bi bi-alarm" aria-hidden="true"></i>3 overdue</span>…</span></div>
 *     <div class="cs-head-tools"><input type="search" class="form-control form-control-sm cs-head-search" …>
 *       <button class="btn btn-sm btn-light cs-cf-toggle" …></button> Export, ⋯</div>
 *   </div> */
/* [Proposed, October 15, night] The head line is always one line at desktop widths, so two cards side by side (Line
 * items beside CrewBid materials) have heads of the same height and their rows line up. Nothing in it wraps: the title,
 * the ?, the count and the tools keep their size, and the quiet facts take what's left, cropped with a fade at the
 * right (a fact that doesn't fit is simply out of view). Only once the facts are gone does a long title shorten, with
 * an ellipsis. The whole text of cropped facts or a cut title is in a callout (js/cs-tip.js gives one to any head h2 or
 * .cs-head-facts that is cut and has no data-tip of its own; CS.table's facts set data-tip). Below 576px the tools take
 * their own line under the title, as before. */
.cs-card > .head:has(> .cs-head-tools) { flex-wrap: nowrap; row-gap: 5px; }
.cs-card > .head > div:first-child:has(> :is(.cs-count, .cs-head-facts)) { flex: 1 1 auto; flex-wrap: nowrap; align-items: center; gap: 0 .75rem; min-width: 0; overflow: hidden; margin: -3px 0; padding: 3px 0 3px 3px; margin-left: -3px; } /* room for the ?'s focus ring */
.cs-card > .head > div:first-child:has(> :is(.cs-count, .cs-head-facts)) > h2 { flex: 0 1 auto; min-width: 3rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cs-card > .head > div:first-child:has(> :is(.cs-count, .cs-head-facts)) > :is(.cs-help, .cs-count) { flex: none; }
.cs-card > .head > div:first-child > h2 + .cs-help { margin-left: -7px; } /* the ? hugs its title: 3px after it */
.cs-card > .head > div:first-child:has(> :is(.cs-count, .cs-head-facts)) > h2 + .cs-help { margin-left: calc(3px - .75rem); }
.cs-count { font-size: .8rem; font-weight: 600; white-space: nowrap; font-variant-numeric: tabular-nums; color: #2b2b2b; }
.cs-card > .head .cs-count { color: #fff; } /* 5.6:1 at the head's lightest */
.cs-head-facts { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 2px .75rem; font-size: .78rem; color: var(--cs-muted); }
.cs-card > .head .cs-head-facts {
    display: flex; flex: 1 1 0; flex-wrap: nowrap; min-width: 0; overflow: hidden; white-space: nowrap; color: #e8e8e8; /* 4.6:1 at the head's lightest */
    -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 1.5rem), transparent); mask-image: linear-gradient(90deg, #000 calc(100% - 1.5rem), transparent);
}
.cs-head-facts > * { display: inline-flex; flex: none; align-items: center; gap: .3em; white-space: nowrap; }
.cs-head-tools { display: flex; flex: none; flex-wrap: nowrap; align-items: center; gap: 6px; margin-left: auto; }
.cs-head-search { width: 12.5rem; }
.cs-card > .head .cs-head-search.form-control { width: 12.5rem; min-width: 0; }
@media (max-width: 575.98px) {
    .cs-card > .head:has(> .cs-head-tools) { flex-wrap: wrap; }
    .cs-card > .head > .cs-head-tools { width: 100%; margin-left: 0; justify-content: flex-start; }
    .cs-card > .head .cs-head-search.form-control { flex: 1 1 8rem; width: auto; }
}
/* The funnel toggle (.cs-cf-toggle): opens and closes the filter-and-sort row (aria-controls names it, aria-expanded and
 * .active say it's open); tinted with the number applied (.n) while filters or a sort are on (.is-on). */
.cs-cf-toggle .n { display: inline-flex; align-items: center; justify-content: center; min-width: 15px; height: 15px; padding: 0 4px; border-radius: 999px; background: #28609a; color: #fff; font-size: .62rem; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; } /* white 6.3:1 */
.cs-cf-toggle .n:empty, .cs-cf-toggle .n[hidden] { display: none; }
.btn.btn-light.cs-cf-toggle.is-on:not(:hover):not(:active):not(.active):not(.show) { background-color: #e8f1fa; background-image: linear-gradient(180deg, #f3f7fc, #dfeaf6); border-color: #b9cfe8; color: #204975; } /* 8.5:1 */
.btn.btn-light.cs-cf-toggle.is-on:is(:hover, .active) { border-color: #a0bcdc; color: #204975; }
/* The filter-and-sort row while it is shown: chips, any switches, a ?, then Clear all at the right. (Archived and deleted
 * rows are tabs since October 15, night: see "Tabs in a card" below; an "Include deleted" switch here is superseded.) */
.cs-cf-chips[hidden] { display: none !important; }
.cs-cf-chips .form-check { margin: 0 0 0 4px; min-height: 0; }
.cs-cf-chips .form-check-label { font-size: .76rem; }
.cs-cf-chips > .cs-help { margin-left: auto; }
.cs-cf-chips > .cs-help ~ .btn { margin-left: 0; }

/* Icons never run into text (Design §3.5). An inline icon followed by its words has about .3em after it, and neighbouring
 * icon-and-text pairs about .75rem between them. The kit's flex pieces build it in with gap (buttons in heads and bars,
 * badges, head facts, menu items' icon column), so the markup's own space adds nothing there. In plain text, an
 * icon-and-words pair is .cs-it: <span class="cs-it"><i class="bi bi-alarm" aria-hidden="true"></i>3 overdue</span>. */
.cs-it { display: inline-flex; align-items: center; gap: .3em; white-space: nowrap; }
.cs-it + .cs-it { margin-left: .75rem; }
.cs-card > .bar { column-gap: .75rem; }
.cs-attr { gap: .3em; }

/* ---------------------------------------------------------------------------
 * [Proposed] Round 7b pieces (October 15, night; the owner's notes): facts flow down, then across (in the Round 7 block
 * above), archived and deleted are tabs (Design §11.1), form labels in the fact style with each label and its control in
 * a field box (§10.3), group headers that select their group in a multiselect (cs-select.css), and the picker as one
 * field in a form (cs-picker.css). Soft picks: try them on real screens.
 * ------------------------------------------------------------------------- */

/* Tabs in a card, above its head line (Design §11.1): the views of the table under it (Active · Archived · Deleted,
 * CS.table's views option in the mockups), each with a count. The chosen tab is steel like the head and joins it, the
 * others are light folder tabs on the card's top edge. The row-state views (archived, deleted) carry their state's icon
 * (.cs-tab-state) and sit a little apart from the page's own views when they share a row (All · RFPs · RFEs).
 *   <section class="cs-card">
 *     <div class="cs-tabs" role="tablist" aria-label="Which projects">
 *       <button type="button" role="tab" class="active" aria-selected="true">Active <span class="cs-badge count tone-info">5</span></button>
 *       <button type="button" role="tab" class="cs-tab-state" aria-selected="false"><i class="bi bi-archive" aria-hidden="true"></i>Archived <span class="cs-badge count tone-muted">1</span></button> …
 *     </div>
 *     <div class="head">…</div> … */
.cs-card > .cs-tabs { margin: 0; padding: 6px 8px 0; border-bottom: 0; border-radius: 9px 9px 0 0; background: linear-gradient(180deg, var(--cs-shade-1), var(--cs-shade-3)); } /* a step over the white card; a tab on it is one more */
.cs-card > .cs-tabs > :is(a, button:not(.cs-help)) { top: 0; padding: 4px 11px; font-size: .8rem; }
.cs-card > .cs-tabs > :is(a, button:not(.cs-help)).active { background: #676767; border-color: #676767; color: #fff; box-shadow: inset 0 3px 0 #9fbfe3; padding-top: 4px; } /* white 5.6:1, as on the head */
.cs-card > .cs-tabs > :is(a, button:not(.cs-help)).active:focus-visible { outline-color: #fff; }
.cs-card > .cs-tabs + .head { border-radius: 0; }
.cs-tabs > .cs-tab-state > .bi { font-size: .85em; }
.cs-tabs > :not(.cs-tab-state) + .cs-tab-state { margin-left: 8px; }

/* Form fields (Design §10.3). A form label is in the facts' label style: small, uppercase, muted and letter-spaced. Each
 * label and its control sit in a field box (.cs-field): one step (--cs-shade-2, steel 7%) darker than whatever it's on
 * (translucent, so it works on the well, a panel, a drawer, and matches a detail grid or a nest beside it), the label on
 * top and the white control under it. Hints
 * (.form-text), errors (.is-invalid + .invalid-feedback), a ? after the label, checkbox and radio groups and switches all
 * work inside it.
 *   <div class="cs-field"><label class="form-label" for="qty">Qty</label><input id="qty" class="form-control form-control-sm"></div>
 * A form's grid gets it by itself: in a form, a card body, a panel, a drawer or a nest, every column of a .row that holds a
 * .form-label as a direct child is a field box (or put .cs-field on the column). Such rows are tight, 6px between boxes.
 * Contrast on the box over the well's foot (#d9d9d9): label #515151 5.6:1, hint #585858 5.0:1, error #a52834 5.1:1. At
 * the darkest a form makes (a box in a nest on the well's foot, #cfcfcf): label 5.1:1, hint 4.5:1, error 4.6:1. On a
 * panel body (#e5e5e5): label 6.3:1, hint 5.6:1. The white control is unchanged. */
:root { --cs-field-bg: var(--cs-shade-2); } /* a UI surface, so steel (§3.3) */
:is(form, .cs-card > .body, .cs-panel-body, .cs-drawer, .cs-nest, .cs-field) .form-label {
    color: #515151; font-size: .64rem; font-weight: 700 !important; /* over .fw-semibold, so every label is the same */
    line-height: 1.3; letter-spacing: .07em; text-transform: uppercase;
}
.cs-field { padding: 5px 7px 6px; background: var(--cs-field-bg); border-radius: 6px; }
/* A column that is a field box: its gutter becomes a clear border, so the shade stops short of the next box and the
 * columns keep their widths (no positioned layer, so an open select or picker is never covered by the next field). */
:is(form, .cs-card > .body, .cs-panel-body, .cs-drawer, .cs-nest) .row:has(> [class*="col"] > .form-label, > .cs-field) { --bs-gutter-x: .375rem; --bs-gutter-y: .375rem; }
:is(.row > .cs-field, :is(form, .cs-card > .body, .cs-panel-body, .cs-drawer, .cs-nest) .row > [class*="col"]:has(> .form-label)) {
    padding: 5px 7px 6px; border: solid transparent; border-width: 0 calc(var(--bs-gutter-x) * .5); background: var(--cs-field-bg) padding-box;
    border-radius: calc(var(--bs-gutter-x) * .5 + 6px) / 6px; /* the shaded box's corners are 6px */
}
:is(.cs-field, :is(form, .cs-card > .body, .cs-panel-body, .cs-drawer, .cs-nest) .row > [class*="col"]:has(> .form-label)) > .form-label { display: inline-block; margin: 0 0 3px !important; } /* over .mb-1 */
:is(.cs-field, :is(form, .cs-card > .body, .cs-panel-body, .cs-drawer, .cs-nest) .row > [class*="col"]:has(> .form-label)) > .form-label + .cs-help { margin-left: 2px; }
:is(.cs-field, :is(form, .cs-card > .body, .cs-panel-body, .cs-drawer, .cs-nest) .row > [class*="col"]:has(> .form-label)) .form-text { margin-top: 2px; font-size: .74rem; color: #585858; }
:is(.cs-field, :is(form, .cs-card > .body, .cs-panel-body, .cs-drawer, .cs-nest) .row > [class*="col"]:has(> .form-label)) .invalid-feedback { margin-top: 2px; font-size: .74rem; color: #a52834; }
:is(.cs-field, :is(form, .cs-card > .body, .cs-panel-body, .cs-drawer, .cs-nest) .row > [class*="col"]:has(> .form-label)) .form-check { margin-bottom: 0; }
:is(.cs-field, :is(form, .cs-card > .body, .cs-panel-body, .cs-drawer, .cs-nest) .row > [class*="col"]:has(> .form-label)) .form-check-inline { margin-right: .75rem; }
:is(.cs-field, :is(form, .cs-card > .body, .cs-panel-body, .cs-drawer, .cs-nest) .row > [class*="col"]:has(> .form-label)) .form-check-label { font-size: .8rem; }
:is(.cs-field, :is(form, .cs-card > .body, .cs-panel-body, .cs-drawer, .cs-nest) .row > [class*="col"]:has(> .form-label)) > :is([role="radiogroup"], [role="group"]) { display: flex; flex-wrap: wrap; align-items: center; min-height: calc(1.35em + .4rem + 2px); }

/* ---------------------------------------------------------------------------
 * [Proposed] Round 9 pieces (October 16; the owner's notes): facts the page places itself and an inline mode that
 * shrinks each fact to its words (Design §5.6), one activity log for every app (§11.3), smaller table head type,
 * shadows on whatever sticks (§6.9) and a frame round nested tables (§6.6). Soft picks: try them on real screens.
 * ------------------------------------------------------------------------- */

/* Placing facts (Design §5.6). The flow down, then across (Round 7 block) is only the default; a page picks what goes
 * where, on any fact container (.cs-facts, .cs-card > .meta, dl.cs-kv):
 *   .cs-facts-cols-2 | -3 | -4    that many columns, each at least --cs-fact-col-min (11rem): fewer in a narrow room
 *   .cs-fact-group                one column the page fills itself: a div of .cs-fact boxes (or, in a meta row, of
 *                                 meta facts), or a dl.cs-fact-group of dt + dd pairs for a detail list. The groups sit
 *                                 side by side, one column each, as many across as fit (or as .cs-facts-cols-N says),
 *                                 wrapping to a new row in a narrow room; a group never splits.
 *   .wide                         a fact (or a group) across every column
 *   .cs-facts-row                 inline mode: one wrapping line, no columns, each fact as wide as its label and value
 *   <div class="cs-facts cs-facts-cols-3">
 *     <div class="cs-fact-group"><div class="cs-fact"><span class="label">Vendor</span><span class="value">…</span></div>…</div>
 *     <dl class="cs-fact-group"><dt>Created by</dt><dd>…</dd>…</dl> …
 *   </div> */
:is(.cs-facts, .cs-card > .meta, dl.cs-kv):is(.cs-facts-cols-2, .cs-facts-cols-3, .cs-facts-cols-4) { column-count: 2; column-width: var(--cs-fact-col); --cs-facts-n: 2; } /* October 20: two at most; -3 and -4 are kept as two for older markup */
/* Groups: a grid of columns instead of CSS columns, so each group is exactly one column */
:is(.cs-facts, .cs-card > .meta):has(> .cs-fact-group) {
    display: grid; align-items: start; gap: var(--cs-fact-gap) 8px; columns: auto;
    grid-template-columns: repeat(auto-fit, minmax(max(min(100%, var(--cs-fact-col)), calc((100% - 8px) / 2)), 1fr)); /* two at most (October 20) */
}
:is(.cs-facts, .cs-card > .meta):has(> .cs-fact-group) > * { margin-bottom: 0; }
:is(.cs-facts, .cs-card > .meta):has(> .cs-fact-group) > .wide { grid-column: 1 / -1; }
.cs-fact-group { display: block; min-width: 0; margin: 0; padding: 0; background: none; break-inside: avoid; }
/* On a phone a detail list is one column, as before (a 22rem column already leaves one on a phone) */
@media (max-width: 575.98px) {
    :is(dl.cs-kv, .cs-facts-grid):is(.cs-facts-cols-2, .cs-facts-cols-3, .cs-facts-cols-4) { column-count: 1; }
}

/* Inline mode (.cs-facts-row): one line that wraps, no columns; each fact is only as wide as its label and value, never
 * stretched, so a row of short facts stays short (a record's few facts, an activity log's changes). The label is one
 * line; a long value wraps inside its box. In a detail list, wrap each pair in a div (<div><dt>…</dt><dd>…</dd></div>)
 * so a line never parts a label from its value; bare dt + dd pairs work, but may part at the end of a line.
 *   <div class="cs-facts cs-facts-row"><div class="cs-fact"><span class="label">Qty</span><span class="value">340</span></div> …</div>
 *   <div class="meta cs-facts-row"> … </div>  (a one-line meta row under a card head) */
:is(.cs-facts, .cs-card > .meta, dl.cs-kv).cs-facts-row { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--cs-fact-gap); columns: auto; }
:is(.cs-facts-row > .cs-fact, .cs-facts-row > .cs-fact-group > .cs-fact), .cs-card > .meta.cs-facts-row > *, dl.cs-kv.cs-facts-row > div { display: inline-flex; flex: 0 1 auto; width: auto; margin: 0; }
.cs-facts-row > .cs-fact-group { display: contents; }
.cs-facts-row :is(.cs-fact > .label, .cs-fact > .value), .cs-card > .meta.cs-facts-row > * > *, dl.cs-kv.cs-facts-row > div > :is(dt, dd) { flex: 0 1 auto; width: auto; max-width: none; }
.cs-facts-row .cs-fact > .label, .cs-card > .meta.cs-facts-row > * > :first-child, dl.cs-kv.cs-facts-row > div > dt { flex: none; white-space: nowrap; }
dl.cs-kv.cs-facts-row { font-size: .8rem; line-height: 1.35; }
dl.cs-kv.cs-facts-row > dt { display: block; flex: none; width: auto; margin: 0; padding: 6px 8px 3px; overflow: visible; background: linear-gradient(var(--cs-fact-label-bg), var(--cs-fact-label-bg)) #fff; border: 1px solid var(--cs-fact-line); border-right-color: var(--cs-fact-line); border-radius: 6px 0 0 6px; box-shadow: var(--cs-fact-shadow); }
dl.cs-kv.cs-facts-row > dd { display: block; flex: 0 1 auto; width: auto; min-height: 25px; margin: 0 calc(var(--cs-fact-gap) * 2) 0 calc(-1 * var(--cs-fact-gap) - 1px); padding: 3px 9px; background: #fff; border-left: 0; border-radius: 0 6px 6px 0; align-self: stretch; }
dl.cs-kv.cs-facts-row > :is(.wide, dt.wide + dd) { flex-basis: auto; }

/* [Proposed, October 20] Facts are never squeezed (Design §5.6; the owner, after a PO's facts were squeezed three across):
 *   - two columns at most, each at least --cs-fact-col (22rem), down then across; a narrower room gets one column;
 *   - in columns every label is the same width (--cs-fact-label-w, 8rem), so no fact gets more label than another and
 *     the values line up down each column;
 *   - four facts or fewer read left to right instead: a fact a column, each at least --cs-fact-col-min (14rem), as many
 *     across as fit; their labels are as wide as their words. A detail list's labels stay 8rem, so its columns are at
 *     least the label and --cs-fact-value-min (12rem), 20rem in all (October 30): fewer across, never a sliver of value.
 * Inline mode (.cs-facts-row) is unchanged: a log's or a head line's few short facts. A child counts as a fact; a detail
 * list counts its dt (or its div pairs). */
:is(.cs-facts:not(.cs-facts-row, .cs-facts-grid):has(> :nth-child(5)) > .cs-fact, .cs-facts:not(.cs-facts-row, .cs-facts-grid):has(> :nth-child(5)) > .cs-fact-group > .cs-fact) > .label,
.cs-card > .meta:not(.cs-facts-row):has(> :nth-child(5)) > :is(:not(.cs-fact-group), .cs-fact-group > *) > :is(.label, dt, .text-dgray, .text-gray):first-child { width: var(--cs-fact-label-w); max-width: none; }
:is(.cs-facts, .cs-card > .meta):not(.cs-facts-row, :has(> .cs-fact-group)):not(:has(> :nth-child(5))),
dl.cs-kv:not(.cs-facts-row):not(:has(> dt:nth-of-type(5))):not(:has(> div:nth-of-type(5))) { column-width: calc(var(--cs-fact-label-w) + var(--cs-fact-value-min)); } /* October 30: its label is always 8rem, so the column holds that and a whole value */
:is(.cs-facts, .cs-card > .meta):not(.cs-facts-row, :has(> .cs-fact-group)):has(> :nth-child(3)):not(:has(> :nth-child(4))),
dl.cs-kv:not(.cs-facts-row):is(:has(> dt:nth-of-type(3)), :has(> div:nth-of-type(3))):not(:has(> dt:nth-of-type(4))):not(:has(> div:nth-of-type(4))) { column-count: 3; }
:is(.cs-facts, .cs-card > .meta):not(.cs-facts-row, :has(> .cs-fact-group)):has(> :nth-child(4)):not(:has(> :nth-child(5))),
dl.cs-kv:not(.cs-facts-row):is(:has(> dt:nth-of-type(4)), :has(> div:nth-of-type(4))):not(:has(> dt:nth-of-type(5))):not(:has(> div:nth-of-type(5))) { column-count: 4; }

/* The activity log (Design §11.3): one log for every app (POs, CrewBid records, jobs, tasks). Each entry is the time,
 * who (.cs-who-first; a system or a supplier gets an icon avatar), then one line of small, tight inline facts
 * (.cs-changes > .cs-change), with no plain text before them (October 16): the record it is about (.cs-change-subject,
 * neutral, no icon), the changes, each led by an action icon in its label: add (bi-plus-circle, green), change (bi-pencil,
 * amber; the old value struck through and muted, an arrow, the new value) and delete (bi-dash-circle, red), and last the
 * reason given on save (.cs-change-why, neutral, labelled "Reason"). An add or a delete shows the value only; a change
 * whose old value wasn't kept shows only the new one. The facts wrap like words in the entry's own column. An entry
 * with no changes is a plain summary (span.what), one line, cut with … and given a callout; a subject or a reason on
 * such an entry follows its summary as facts. CS.logEntry() in the mockups.
 *   <li><time datetime="2026-10-08T16:30">Oct 8, 4:30 pm</time><span class="cs-who cs-who-first" data-tip="Tam Nguyen">…Tam</span>
 *     <div class="what"><span class="cs-changes">
 *       <span class="cs-change cs-change-subject"><span class="label">Line item</span><span class="value">CMU 8x8x16 bond beam</span></span>
 *       <span class="cs-change cs-change-edit"><span class="label"><i class="bi bi-pencil" role="img" aria-label="Changed"></i>Unit cost</span>
 *         <span class="value"><del>13.10</del><i class="bi bi-arrow-right" aria-hidden="true"></i><span class="visually-hidden"> to </span><ins>13.89</ins></span></span>
 *       <span class="cs-change cs-change-why"><span class="label">Reason</span><span class="value">Acme October price sheet</span></span>
 *     </span></div></li>
 * The values are names, never raw ids (a user id, a list id): a field-definition registry turns them into words. */
.cs-log > li { align-items: baseline; padding-top: 3px; padding-bottom: 3px; }
.cs-log > li > .what:has(> .cs-changes) { overflow: visible; white-space: normal; text-overflow: clip; line-height: 21px; } /* the facts wrap like words */
.cs-log .what > .sum + .cs-changes { margin-left: 6px; } /* an entry without changes: its summary, then its subject or reason */
.cs-changes { display: inline; }
.cs-change {
    display: inline-flex; align-items: stretch; vertical-align: top; min-width: 0; max-width: 100%; min-height: 19px; margin: 1px 4px 1px 0;
    background: #fff; border: 1px solid var(--cs-fact-line); border-radius: 4px; box-shadow: 0 1px 1px rgba(30, 30, 30, 0.08);
    font-size: .7rem; line-height: 15px; color: #2b2b2b; font-weight: 500; white-space: normal; overflow-wrap: break-word; /* 14.1:1; break-word, not anywhere: a fact never shrinks below its longest word, so a whole fact wraps to the next line instead of its value breaking into slivers */
}
.cs-change > .label {
    display: inline-flex; flex: none; align-items: center; align-self: stretch; gap: 3px; padding: 1px 5px 0 4px; background: var(--cs-fact-label-bg); border-right: 1px solid var(--cs-fact-line); border-radius: 3px 0 0 3px;
    color: #585858; font-size: .58rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; white-space: nowrap; /* 5.9:1 on the label shade (--cs-fact-label-bg) */
}
.cs-change > .label > .bi { font-size: 11px; line-height: 1; letter-spacing: 0; }
.cs-change:is(.cs-change-subject, .cs-change-why) > .label { padding-left: 5px; } /* neutral facts: no action icon */
.cs-change > .value { display: block; align-self: center; min-width: 0; padding: 1px 6px; }
.cs-change > .value > .bi-arrow-right { margin: 0 3px; }
.cs-change > .value.is-short { white-space: nowrap; } /* a short value (CS.logChange: both sides 24 characters or fewer) keeps old → new on one line */
.cs-change > .value:empty::before, .cs-change > .value > :is(del, ins):empty::before { content: '—'; color: #696969; font-weight: 400; } /* a blank value, 5.1:1 */
.cs-change del { color: #696969; font-weight: 400; text-decoration: line-through; text-decoration-color: #949494; } /* the old value, muted: 5.1:1 */
.cs-change ins { color: #2b2b2b; font-weight: 600; text-decoration: none; }
.cs-change > .value > .bi-arrow-right { color: #707070; font-size: .65rem; } /* 4.9:1 */
.cs-change-add > .label > .bi { color: #1e7a45; } /* 4.5:1 on the label shade (an icon needs 3:1) */
.cs-change-edit > .label > .bi { color: #8a5d00; } /* 4.8:1 */
.cs-change-del > .label > .bi { color: #a3261f; } /* 6.2:1 */
.cs-log .cs-changes .cs-who > .cs-avatar { width: 14px; height: 14px; font-size: .45rem; } /* a person as a value */
/* [Proposed] November 3: a structured value's items in a popover (<x-cs.data-facts>, Design §7.10). The button is a
 * light extra-small one with the braces icon; the popover floats fixed under it (js/cs-datafacts.js), white, in two
 * parts: the head (the title and its count) stays put, and the body under it scrolls. The body is a grid of two columns,
 * the keys on a light shade and the values on white, lined up down the popover. A subgroup is a band across both columns,
 * its name and how many items it holds, and its items sit one guide line in (--cs-df-depth: a thin line per level, 14px
 * apart). With a value before it, a changed value shows the old one struck through over the new, an added key's row is
 * green and a removed one's red. */
.cs-data-btn { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
.cs-data-btn > .bi { font-size: .75rem; color: #585858; }
.cs-data-pop { position: fixed; z-index: 1060; display: flex; flex-direction: column; overflow: hidden; width: max-content; min-width: 18rem; max-width: min(34rem, calc(100vw - 16px));
    background: #fff; border: 1px solid #d1d1d1; border-radius: 8px; box-shadow: 0 10px 28px rgba(30, 30, 30, 0.2); font-size: .75rem; line-height: 1.35; color: #2b2b2b; text-align: left; white-space: normal; }
.cs-data-pop[hidden] { display: none; }
.cs-data-pop > .head { flex: none; display: flex; align-items: center; gap: 6px; padding: 6px 10px; background: var(--cs-fact-label-bg); border-bottom: 1px solid var(--cs-fact-line); font-weight: 700; color: #2b2b2b; }
.cs-data-pop > .head > .bi { color: #585858; }
.cs-data-pop > .head > .title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cs-data-pop > .head > .cs-badge { margin-left: auto; }
.cs-data-pop > .body { flex: 1 1 auto; min-height: 0; overflow: auto; overscroll-behavior: contain; }
.cs-data-pop .grid { display: grid; grid-template-columns: minmax(7rem, max-content) minmax(9rem, 1fr); }
.cs-data-pop .grid > * { padding: 4px 10px; border-bottom: 1px solid #f0f0f0; }
/* a key on the shade, one guide line per level of its subgroups */
.cs-data-pop .grid > :is(.key, .grp) { padding-left: calc(10px + var(--cs-df-depth, 0) * 14px);
    background-image: repeating-linear-gradient(to right, #cccccc 0 1px, transparent 1px 14px); background-repeat: no-repeat; background-position: 15px 0; background-size: calc(var(--cs-df-depth, 0) * 14px) 100%; }
.cs-data-pop .grid > .key { background-color: #f8f8f8; border-right: 1px solid #e7e7e7; color: #585858; font-weight: 600; } /* 7.4:1 */
.cs-data-pop .grid > .val { overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
.cs-data-pop .grid > .grp { grid-column: 1 / -1; display: flex; align-items: center; gap: 5px; background-color: #ededed; border-top: 1px solid #e4e4e4; border-bottom-color: #e4e4e4; color: #2b2b2b; font-weight: 700; }
.cs-data-pop .grid > .grp:first-child { border-top: 0; }
.cs-data-pop .grid > .grp > .bi { font-size: .65rem; color: #585858; }
.cs-data-pop .grid > .grp > .n { margin-left: auto; padding-left: 12px; color: #5e5e5e; font-size: .68rem; font-weight: 500; white-space: nowrap; } /* 6.1:1 */
.cs-data-pop .grid > .more { grid-column: 1 / -1; color: #696969; } /* 5.1:1 */
.cs-data-pop .grid > .val.is-changed { background: #fffbea; }
.cs-data-pop .grid > :is(.key, .val, .grp).is-added { background-color: #eef8f1; }
.cs-data-pop .grid > :is(.key, .val, .grp).is-removed { background-color: #fcefee; }
.cs-data-pop del { display: block; color: #696969; text-decoration: line-through; text-decoration-color: #949494; } /* 5.1:1 */
.cs-data-pop ins { display: block; color: #2b2b2b; font-weight: 600; text-decoration: none; }
/* In a narrow log (a 480px drawer at any window width, a phone: the query sees the log's own width) the time and who
 * take the first line and the facts the whole width under them, so a change has room to read. A plain summary (an
 * entry without changes) stays beside who and wraps there rather than shrinking to a few letters; on a phone it goes
 * under them too. */
.cs-log { container-type: inline-size; } /* every log, so entries without changes narrow too */
@container (max-width: 600px) {
    .cs-log > li:has(> .what > .cs-changes) { grid-template-columns: var(--cs-log-time) minmax(0, 1fr); row-gap: 1px; } /* who still lines up down the log */
    .cs-log > li > .what:has(> .cs-changes) { grid-column: 1 / -1; }
    .cs-log > li > .what:not(:has(> .cs-changes)) { white-space: normal; overflow: visible; text-overflow: clip; }
}
@container (max-width: 420px) {
    .cs-log > li { grid-template-columns: max-content minmax(0, 1fr); row-gap: 1px; }
    .cs-log > li > .what { grid-column: 1 / -1; }
}

/* Table heads are a size smaller than the body (October 16): .72rem over a .8rem list, .68rem over a .75rem report.
 * Still #2b2b2b on the light steel head, 10.6:1 at its foot. */
.cs-table > thead > tr > th { font-size: .72rem; line-height: 1.3; }
.cs-table-dense > thead > tr > th { font-size: .68rem; }

/* Whatever sticks casts a soft shadow on what scrolls under it (Design §6.9), so it's clearly in front. cs-menus.js
 * marks the state: .is-scrolled-y / .is-scrolled-x on a table's scroll box (.cs-table-scroll, .table-responsive)
 * once it has scrolled down or sideways, .is-stuck on a sticky page header or context bar once the page has scrolled
 * under it. Without the script the heads keep their 1px line. */
.cs-table-scroll.is-scrolled-y, .table-responsive.is-scrolled-y { --cs-head-drop: 0 5px 7px -4px rgba(28, 28, 28, 0.3); }
.cs-table-scroll.is-scrolled-x, .table-responsive.is-scrolled-x { --cs-col-drop: 6px 0 7px -4px rgba(28, 28, 28, 0.26); }
.cs-drill-row { --cs-head-drop: 0 0 transparent; --cs-col-drop: 0 0 transparent; } /* a table inside doesn't inherit its parent's */
.cs-table > thead > tr > th { box-shadow: inset 0 -1px 0 #c0c0c0, var(--cs-head-drop, 0 0 transparent); }
.cs-table > thead > tr > th.cs-grid-sticky { box-shadow: inset -1px 0 0 #c0c0c0, inset 0 -1px 0 #c0c0c0, var(--cs-head-drop, 0 0 transparent), var(--cs-col-drop, 0 0 transparent); }
.cs-table > :is(tbody, tfoot) > tr > .cs-grid-sticky { box-shadow: inset -1px 0 0 #d7d7d7, inset 0 0 0 9999px var(--bs-table-bg-state, var(--bs-table-bg-type, var(--bs-table-accent-bg))), var(--cs-col-drop, 0 0 transparent); }
.cs-drill-row .cs-table > thead > tr > th { box-shadow: inset 0 -1px 0 #d9d9d9; }
.cs-page-header:has(.cs-actionbar).is-stuck { box-shadow: 0 1px 0 #d6d6d6, 0 8px 14px -8px rgba(28, 28, 28, 0.4); }
.cs-context.is-stuck { box-shadow: 0 1px 2px rgba(30, 30, 30, 0.08), 0 8px 14px -8px rgba(29, 29, 29, 0.34); }

/* Nested tables (Design §6.6): a table in a drill-down row, in a well (a card body of fields or of child cards, a
 * .cs-nest, a panel) or in a child card's padded body sits on white in a frame, a 1px border and a soft shadow, so it
 * doesn't blend into what's behind it. The frame goes on the table, or on its scroll box when it has one;
 * .cs-table-framed asks for it anywhere else. */
:is(.cs-drill-row > td, .cs-nest, .cs-panel-body, .cs-card .cs-card > .body:not(.flush), .cs-card > .body:not(.flush):has(.cs-card), .cs-card > .body:not(.flush):has(input:not([type="hidden"]), select, textarea)) > :is(.cs-table, .table-responsive, .cs-table-scroll),
:is(.cs-table, .table-responsive, .cs-table-scroll).cs-table-framed {
    background: #fff; border: 1px solid #cccccc; border-radius: 6px; box-shadow: var(--cs-shadow-child);
}
:is(:is(.cs-drill-row > td, .cs-nest, .cs-panel-body, .cs-card .cs-card > .body:not(.flush), .cs-card > .body:not(.flush):has(.cs-card), .cs-card > .body:not(.flush):has(input:not([type="hidden"]), select, textarea)) > .cs-table, .cs-table.cs-table-framed) {
    border-collapse: separate; border-spacing: 0; overflow: hidden; /* separate, so the corners round */
}
:is(:is(.cs-drill-row > td, .cs-nest, .cs-panel-body, .cs-card .cs-card > .body:not(.flush), .cs-card > .body:not(.flush):has(.cs-card), .cs-card > .body:not(.flush):has(input:not([type="hidden"]), select, textarea)) > :is(.table-responsive, .cs-table-scroll), :is(.table-responsive, .cs-table-scroll).cs-table-framed) > .cs-table { border-collapse: separate; border-spacing: 0; }
:is(:is(.cs-drill-row > td, .cs-nest, .cs-panel-body, .cs-card .cs-card > .body:not(.flush), .cs-card > .body:not(.flush):has(.cs-card), .cs-card > .body:not(.flush):has(input:not([type="hidden"]), select, textarea)) > :is(.cs-table, .table-responsive > .cs-table, .cs-table-scroll > .cs-table), .cs-table-framed, .cs-table-framed > .cs-table) > :last-child > tr:last-child > * { border-bottom-width: 0; } /* the frame is the last line */

/* Print: chrome off, cards whole. PDFs that must look the same for everyone use their own templates. */
@media print {
    .cs-topbar, .cs-sidebar, .cs-ribbon, .cs-filter-bar, .cs-page-header .d-flex, .cs-savedock { display: none !important; }
    body.cs-has-bar { padding-top: 0; }
    .cs-main { margin-left: 0; }
    .cs-sticky, .cs-side-sticky { position: static; }
    .cs-card { break-inside: avoid; box-shadow: none; }
    .cs-card > .head, .cs-card:has(> .body .cs-card) > .head { background: #ededed !important; color: #000; border-bottom-color: #a6a6a6; }
    .cs-card > .head :is(h2, .hint) { color: #000 !important; }
    .cs-table > thead > tr > th { position: static; transform: none !important; }
    .cs-table > thead > tr > th:not(.cs-kind-base, .cs-kind-2, .cs-kind-3) { --bs-table-bg: #ededed; --bs-table-color: #000; background-image: none; }
    .cs-table-scroll { overflow: visible; }
    .cs-cf-btn, .cs-drill-toggle, .cs-rowmenu, .cs-edit-pop, .cs-actionbar, .cs-tip-float, .cs-card > .bar { display: none !important; }
    .cs-split { display: block; }
    .cs-split-list { display: none; }
    .cs-page-header:has(.cs-actionbar), .cs-context { position: static; box-shadow: none; }
    :is(.cs-drill-row > td, .cs-nest, .cs-panel-body, .cs-card .cs-card > .body, .cs-card > .body) > :is(.cs-table, .table-responsive, .cs-table-scroll), .cs-table-framed { box-shadow: none; }
}

/* [Proposed, October 21] A folding sidebar section (Design §4.2): its heading is a button, its links shut until it is
 * opened (cs.fold.<key> per browser), open while one of its pages is. In the rail the heading is its icon. */
.cs-fold-head { padding: 10px 0 2px; }
.cs-fold-toggle { display: flex; align-items: center; gap: .6rem; width: 100%; padding: 4px 10px; border: 0; border-radius: 6px; background: none; color: #9e9e9e; font: inherit; font-size: .68rem; letter-spacing: .08em; text-transform: uppercase; text-align: left; cursor: pointer; }
.cs-fold-toggle:is(:hover, :focus-visible) { background: var(--cs-nav-hover); color: #fff; }
.cs-fold-toggle > .bi:first-child { font-size: .9rem; width: 1.1rem; text-align: center; letter-spacing: 0; }
.cs-fold-caret { margin-left: auto; font-size: .7rem; transition: transform .15s ease; }
.cs-fold-toggle[aria-expanded="true"] .cs-fold-caret { transform: rotate(180deg); }
.cs-fold { display: none; }
.cs-fold.is-open { display: list-item; list-style: none; }
.cs-fold-items { list-style: none; margin: 0; padding: 0; }
@media (min-width: 992px) {
    .cs-side-rail .cs-sidebar:not(:hover, :focus-within) .cs-nav .cs-fold-head { height: auto; padding: 8px 0 2px; font-size: inherit; }
    .cs-side-rail .cs-sidebar:not(:hover, :focus-within) .cs-nav .cs-fold-head::after { content: none; }
    .cs-side-rail .cs-sidebar:not(:hover, :focus-within) .cs-fold-toggle { width: 40px; padding: 6px 0; justify-content: center; border-top: 1px solid rgba(255, 255, 255, .15); border-radius: 0 0 6px 6px; }
    .cs-side-rail .cs-sidebar:not(:hover, :focus-within) .cs-fold-toggle > :not(.bi:first-child) { display: none; }
    .cs-side-rail .cs-sidebar:not(:hover, :focus-within) .cs-fold-items a { position: relative; width: 40px; padding-left: 0; padding-right: 0; justify-content: center; }
    .cs-side-rail .cs-sidebar:not(:hover, :focus-within) .cs-fold-items a > .lbl { display: none; }
}
@media (prefers-reduced-motion: reduce) { .cs-fold-caret { transition: none; } }

/* [October 21; amended October 22; the default since October 22] The page's name in the top bar (crewsuite.header_in_bar, Design §4.1): only
 * the page's name (its h1, with the sidebar's icon) is laid over the bar's free room; below 992px the name shrinks to that
 * icon. The description and the actions stay in the page, in one row above its first card (the search). The room
 * (.cs-bar-page) is measured by the layout's script (--cs-bar-page-x, --cs-bar-page-w). In print the name is back in the
 * page; a large panel's own header stays as it is. */
.cs-bar-page { flex: 1 1 auto; min-width: 0; align-self: stretch; }
@media screen {
    html body.cs-head-in-bar:has(.cs-page-header .cs-actionbar) { --cs-sticky-head: 0px; }
    body.cs-head-in-bar .cs-content .cs-page-header:not(.cs-overlay .cs-page-header),
    body.cs-head-in-bar .cs-content .cs-page-header:not(.cs-overlay .cs-page-header):has(.cs-actionbar) {
        position: static; align-items: center; gap: 4px 12px; margin: 0 0 10px; padding: 0; background: transparent; box-shadow: none;
    }
    body.cs-head-in-bar .cs-content .cs-page-header:not(.cs-overlay .cs-page-header) > :first-child { flex: 1 1 auto; min-width: 0; }
    body.cs-head-in-bar .cs-content .cs-page-header:not(.cs-overlay .cs-page-header) h1 {
        position: fixed; top: 0; left: var(--cs-bar-page-x, calc(var(--cs-sidebar-w) + 12px)); width: var(--cs-bar-page-w, 40vw); height: var(--cs-bar-h);
        z-index: 1036; margin: 0; padding: 0 2px; display: flex; align-items: center;
        font-size: .98rem; line-height: 1.2; color: #fff; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; pointer-events: none;
    }
    body.cs-head-in-bar .cs-content .cs-page-header:not(.cs-overlay .cs-page-header) h1 .bi { color: #adadad !important; }
    body.cs-head-in-bar .cs-content .cs-page-header:not(.cs-overlay .cs-page-header) .sub { margin-top: 0; font-size: .82rem; }
}
@media screen and (max-width: 991.98px) {
    /* The name reads out still; only the icon shows, the same as the page's link in the sidebar. */
    body.cs-head-in-bar .cs-content .cs-page-header:not(.cs-overlay .cs-page-header) h1 { font-size: 0; justify-content: center; }
    body.cs-head-in-bar .cs-content .cs-page-header:not(.cs-overlay .cs-page-header) h1 .bi { font-size: 1.15rem; margin: 0 !important; }
}
}

/* ===== [October 30] The tint: what the colour rewrite above can't do by itself ===== */

/* Bootstrap's own greys follow the tint (its body text, borders, light buttons, the greys behind a menu item). */
:root {
    --bs-body-color: #242424; --bs-body-color-rgb: 36, 36, 36;
    --bs-secondary-color: rgba(36, 36, 36, .75); --bs-tertiary-color: rgba(36, 36, 36, .5);
    --bs-border-color: #e1e1e1; --bs-secondary-bg: #ececec; --bs-tertiary-bg: #f9f9f9;
    --bs-light: #f9f9f9; --bs-light-rgb: 249, 249, 249;
    --bs-gray-100: #f9f9f9; --bs-gray-200: #ececec; --bs-gray-300: #e1e1e1; --bs-gray-400: #d3d3d3;
    --bs-gray-500: #b4b4b4; --bs-gray-600: #747474; --bs-gray-700: #4f4f4f; --bs-gray-800: #393939; --bs-gray-900: #242424;
    --bs-secondary: #747474; --bs-secondary-rgb: 116, 116, 116;
}
.btn-light { --bs-btn-bg: #f9f9f9; --bs-btn-color: #2b2b2b; }

/* Bootstrap's primary blue (#0d6efd, the brightest and most violet blue on a page) becomes the kit's own blue, calmed:
   white on it 5.5:1. */
:root {
    --bs-primary: #2d6bab; --bs-primary-rgb: 45, 107, 171;
    --bs-primary-text-emphasis: #204975; --bs-primary-bg-subtle: #e8f1fa; --bs-primary-border-subtle: #c6d9ef;
    --bs-focus-ring-color: rgba(53, 120, 190, .25);
}
.btn-primary {
    --bs-btn-bg: #2d6bab; --bs-btn-border-color: #27609c;
    --bs-btn-hover-bg: #22609f; --bs-btn-hover-border-color: #1d5288;
    --bs-btn-active-bg: #1d5288; --bs-btn-active-border-color: #184674;
    --bs-btn-disabled-bg: #2d6bab; --bs-btn-disabled-border-color: #27609c; --bs-btn-focus-shadow-rgb: 53, 120, 190;
}
.btn-outline-primary { --bs-btn-border-color: #22609f; --bs-btn-hover-bg: #22609f; --bs-btn-hover-border-color: #22609f; --bs-btn-active-bg: #1d5288; --bs-btn-active-border-color: #1d5288; }
.form-check-input:checked, .form-check-input[type="checkbox"]:indeterminate { background-color: #2d6bab; border-color: #2d6bab; }
.form-control:focus, .form-select:focus, .form-check-input:focus { border-color: #a5c6ec; box-shadow: 0 0 0 .25rem rgba(53, 120, 190, .25); }
.nav-pills { --bs-nav-pills-link-active-bg: #2d6bab; }
.dropdown-menu { --bs-dropdown-link-active-bg: #2d6bab; }
.list-group { --bs-list-group-active-bg: #2d6bab; --bs-list-group-active-border-color: #2d6bab; }
.pagination { --bs-pagination-active-bg: #2d6bab; --bs-pagination-active-border-color: #2d6bab; --bs-pagination-color: #215e9b; }
.progress, .progress-stacked { --bs-progress-bar-bg: #2d6bab; }
.text-primary { color: #215e9b !important; }
.bg-primary { background-color: #2d6bab !important; }

/* Card heads a step lighter; white title 5.2:1 at the top, the hint and head icons 4.6:1 or better. */
.cs-card > .head { background: linear-gradient(180deg, #6d6d6d, #575757); border-bottom-color: #575757; }
.cs-card > .head .hint, .cs-card > .head :is(.text-dgray, .text-gray, .text-muted) { color: #f2f2f2 !important; }
.cs-card > .head a:not(.btn):not(.dropdown-item) { color: #edf3fb; }
.cs-card > .cs-tabs > :is(a, button:not(.cs-help)).active { background: #6d6d6d; border-color: #6d6d6d; }

/* No blue that doesn't mean something: the sidebar's current page is a lighter block with a thin accent edge, */
.cs-nav a.active { background: #3b3b3b; box-shadow: inset 3px 0 0 var(--cs-accent); }
.cs-nav a.active .count { color: #2b2b2b; }
/* a tile icon is the slate step unless the page gives it a tone, */
.cs-tile-icon { background: var(--cs-shade-3); color: #515151; }
/* a hover lifts with a darker grey edge, */
a.cs-stat:hover { border-color: #999999; }
.btn-add:hover, .btn-add:focus { border-color: #676767; color: #2b2b2b; }
/* and rules that only decorate are grey. */
.cs-filter-group-label { border-right-color: #b2b2b2; }
.cs-kb blockquote { border-left-color: #cccccc; }
