/* Roadmap host layout + graph theme bindings. DS tokens only — no raw colors.
   The shared renderer reads the --pg-* roles from its mount element (never document.body),
   so a theme change re-resolves colors without touching data, ranking or positions. */

html, body { margin: 0; height: 100%; }
/* the site's sidebar, then the page: one row of controls over the view, with nothing above it */
body.rm { display: flex; min-height: 100vh; background: var(--bg); color: var(--fg); font-family: var(--font-sans); }
.rm-page { position: relative; flex: 1; min-width: 0; display: flex; flex-direction: column; }   /* positioned: its heading is rm-hidden text */

/* ---------- the site's sidebar ---------- */
/* The homepage's spine on this page. build-roadmap.py writes the spine's own rules into the page ahead of this file, and
   its brand and links into .rm-side, so those are the homepage's and are not repeated here. This is what the page puts
   around them: a head for the brand and the toggle, the links in a pane that scrolls between that head and the account
   row, one design system's section at a time, the rail of icons, and the drawer. First, what the spine has from the
   homepage's page-wide rules. */
html { --rm-side: var(--rail-w); }   /* how wide the sidebar is now: a toast keeps clear of it */
.rm-side { flex: none; display: flex; flex-direction: column; box-sizing: border-box; width: var(--rm-side); min-height: 0;
  border-right: 1px solid var(--border); background: var(--bg-subtle); -webkit-font-smoothing: antialiased; }
.rm-side :is(.brand, .spine), .rm-side :is(.brand, .spine) *, .rm-side :is(.brand, .spine) *::before { box-sizing: border-box; }
:where(.rm-side) a { color: inherit; text-decoration: none; }   /* :where, so a link's own colour still wins, as on the homepage */
/* the head: the brand is the way home, the toggle is the design system's rail toggle in the spine's quiet colours */
.rm-side-head { flex: none; display: flex; align-items: center; gap: 4px; padding: 18px 14px 8px; }
.rm-side .brand { flex: 1; min-width: 0; padding: 6px 8px; border-radius: var(--radius-control); }
.rm-side .sb-iconbtn { flex: none; color: var(--fg-tertiary); }
.rm-side .sb-iconbtn:hover { background: var(--bg); color: var(--fg-secondary); }
.rm-side-toggle .fa-arrow-right-to-line, [data-side="closed"] .rm-side-toggle .fa-arrow-left-to-line, .rm-side-close { display: none; }
[data-side="closed"] .rm-side-toggle .fa-arrow-right-to-line { display: inline-block; }
.rm-side a:focus-visible, .rm-side button:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--blue-01); }
/* the links: the spine without its own frame, which .rm-side has taken over, scrolling under the head */
.rm-side .spine { position: static; flex: 1; align-self: stretch; width: auto; height: auto; min-height: 0; padding: 0 14px 16px; border-right: 0; background: none; }
/* A design system's section, whole as on its homepage, is the rest of the spine's column: from the spine's one rule,
   under this page's own link, to the account row's. The page holds one for each system the site was built with and
   shows one: the system used last (index.html says which before the first paint), or the only one there is. The small
   button that stands for the heading's choice in the rail is out of sight here. */
.rm-sys { display: flex; flex-direction: column; flex: 1 0 auto; gap: 4px; }
.rm-sys > .nav-system { margin-top: 8px; padding-top: 12px; border-top: 1px solid var(--border); }   /* the rule, as the homepage draws it under its Roadmap link */
[data-system="crm"] .rm-sys[data-sys="retailing"], [data-system="retailing"] .rm-sys[data-sys="crm"]:has(~ .rm-sys[data-sys="retailing"]) { display: none; }
.rm-sys-pick { display: none; }
/* the account row: pinned under a hairline, one button from edge to edge. The avatar sits on the links' icon column. */
.rm-side-foot { flex: none; padding: 8px 14px; border-top: 1px solid var(--border); }
.rm-account { display: flex; align-items: center; gap: 9px; width: 100%; padding: 4px 10px 4px 3px; border: 0; border-radius: var(--radius-control);
  background: none; font: var(--t-action); color: var(--fg); text-align: left; cursor: pointer; transition: background .1s var(--ease); }
.rm-account:hover, .rm-account[aria-expanded="true"] { background: var(--bg); }
.rm-account-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rm-account i { flex: none; font-size: 11px; color: var(--fg-tertiary); }
/* Where a sign-in is stored (index.html says so before the first paint) the row's place is kept until host.js fills it,
   so the links above it do not move when it does. Laid out and unseen: !important, as the design system's [hidden] is. */
[data-account] .rm-side-foot[hidden] { display: block !important; visibility: hidden; }
/* Where host.js could not be read (index.html marks the page), what only it works is not left dead: the fold, a
   phone's Menu, the way past the sidebar, and the choice of system. !important, as the design system's [hidden] is. */
[data-unread] :is(.rm-side-toggle, .rm-menu, .rm-skip, .sys-seg, .rm-sys-pick) { display: none !important; }
/* the way past the sidebar, for the keyboard: on screen only while it has focus */
.rm-skip { position: fixed; left: 8px; top: 8px; z-index: 9; }
.rm-skip:not(:focus) { width: 1px; height: 1px; margin: -1px; padding: 0; border: 0; overflow: hidden; clip-path: inset(50%); }
.rm-skip:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--blue-01); }
.rm-scrim { display: none; }
/* Folded, on anything wider than a phone: a rail of icons, as the design system's rail folds (64px, the toggle under the
   brand). The brand is its mark, the left end of the same picture; a link is its icon, its name kept for a screen reader
   as rm-hidden text is (build-roadmap.py gives each name an element) and said in a tooltip (sidebar.js); a group's
   heading is a rule; the account row is the avatar. Under the design system's rule, where there is a choice of system,
   a small button names the one whose icons follow and opens the design system's menu to change it: the rail's fill
   for a selector (gray-06, r5), in the spine's smallest type so the longer name fits. */
@media (min-width: 768px) {
  html[data-side="closed"] { --rm-side: 64px; }
  [data-side="closed"] .rm-side-head { flex-direction: column; gap: 8px; padding: 18px 0 8px; }
  [data-side="closed"] .rm-side .brand { flex: none; padding: 2px 6px; }
  [data-side="closed"] .rm-side .brand img { width: 24px; height: 28px; object-fit: cover; object-position: left center; }   /* at this height the mark ends at 21px and the name starts at 25px */
  [data-side="closed"] .rm-side .rm-side-name { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  [data-side="closed"] .rm-side .spine { padding-bottom: 12px; scrollbar-width: none; }   /* no room for a scrollbar beside the icons; the wheel and the keys still scroll it */
  [data-side="closed"] .rm-side .spine::-webkit-scrollbar { display: none; }
  [data-side="closed"] .rm-side .nav-item, [data-side="closed"] .rm-side .spine-foot a { justify-content: center; }
  [data-side="closed"] .rm-side .nav-item { height: 38px; padding: 7px 0; }   /* as tall as with its name beside it, also before the icon font is in */
  [data-side="closed"] .rm-side .nav-item .meta, [data-side="closed"] .rm-side .nav-label .dot { display: none; }
  [data-side="closed"] .rm-side .nav-kids { margin-left: 0; border-left: 0; }   /* the parts of a screen keep their place in the one column of icons: no indent, no guide line */
  [data-side="closed"] .rm-sys > .nav-system { padding-top: 0; border-top: 0; }   /* here the heading is the rule */
  [data-side="closed"] .rm-side .nav-group { margin-top: 4px; }
  [data-side="closed"] .rm-side .nav-label { height: 1px; min-height: 0; margin: 0 6px 8px; padding: 0; overflow: hidden; background: var(--border); color: transparent; }
  [data-side="closed"] .rm-side .sys-seg { display: none; }
  /* centred on the icons whatever its width: the longer name is wider than the column of icons */
  [data-side="closed"] .rm-sys-pick { display: block; position: relative; left: 50%; transform: translateX(-50%); min-width: 35px; height: 24px; margin-bottom: 4px; padding: 0 6px;
    border: 0; border-radius: var(--radius-control); background: var(--gray-06); font: var(--t-indicator); color: var(--fg); white-space: nowrap; cursor: pointer; }
  [data-side="closed"] .rm-sys-pick:hover, [data-side="closed"] .rm-sys-pick[aria-expanded="true"] { background: var(--gray-05); }
  [data-side="closed"] .rm-side .spine-foot { gap: 2px; padding: 8px 0 0; border-top: 1px solid var(--border); }   /* a rule, as over each group of icons */
  [data-side="closed"] .rm-side .spine-foot a { position: relative; height: 28px; border-radius: var(--radius-control); }
  [data-side="closed"] .rm-side-foot { padding: 8px 0; }
  [data-side="closed"] .rm-account { width: auto; margin: 0 auto; padding: 4px; }
  [data-side="closed"] .rm-account-name, [data-side="closed"] .rm-account i { display: none; }
}
/* On a phone it is not in the layout: a drawer over the page and a scrim behind it, opened from the row of controls and
   always whole, whatever was chosen on a wider screen. Shut, it is out of sight and out of the Tab order. */
@media (max-width: 767px) {
  html { --rm-side: 0px; }
  .rm-side { position: fixed; inset: 0 auto 0 0; z-index: 8; width: min(var(--rail-w), calc(100vw - 56px)); box-shadow: var(--elevation-popover);
    transform: translateX(-100%); visibility: hidden; transition: transform .22s var(--ease), visibility 0s .22s; }
  .rm--drawer .rm-side { transform: none; visibility: visible; transition: transform .22s var(--ease); }
  .rm--drawer .rm-scrim { display: block; position: fixed; inset: 0; z-index: 7; background: var(--overlay-trans-64); }
  .rm-side-toggle, .rm-skip { display: none; }
  .rm-side-close { display: inline-flex; }
}
@media (prefers-reduced-motion: reduce) { .rm-side, .rm--drawer .rm-side, .rm-account { transition: none; } }

/* what the roadmap is drawn from, in the row of controls: the date it is as of, quietly. Over real data that is all, and
   the date's tooltip says the rest (host.js), so the keyboard can stop on it. Over invented data a yellow tag stands
   before the date. Short of room the date leaves the row and then the tag shows its short form (filters.js measures,
   and sets the row's classes); the tag itself is never hidden. A screen reader has the tag's long form either way, and
   the date in the tag's own sentence. A date that has left the row, and its sentence, are in the account menu (below). */
.rm-asof { flex: none; font: var(--t-label); color: var(--fg-tertiary); white-space: nowrap; }
.rm-asof[data-tip] { margin: -2px -4px; padding: 2px 4px; border-radius: var(--r-3); cursor: default; }   /* room for its focus ring, taking none in the row */
.rm-datatag { position: relative; flex: none; cursor: default; white-space: nowrap; }
/* The warning tag keeps the banner's readable text colour: yellow-on-pale-yellow all but disappears in the light theme. */
.rm-datatag.sb-tag--yellow { color: var(--gray-00); border-color: var(--yellow-01); }
.rm-asof:focus-visible, .rm-datatag:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--blue-01); }
.rm-tag-short, .rm-views--undated .rm-asof { display: none; }
.rm-views--brief .rm-tag-short { display: inline; }
.rm-views--brief .rm-tag-full { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* views bar, as a database's, on one row: the views at the left as the DS segmented control (an icon and a name, the open
   view a filled pill); at the right the date the roadmap is as of, the applied filters as tags, then Filter and Sort as DS
   icon buttons. filters.js keeps it on one line: where the four names do not fit, only the open view keeps its name
   (rm-views--tight); where that does not fit either, on a phone, none does (rm-views--icons), and on the narrowest the
   four icons are 32px buttons, as wide as the icon buttons beside them (rm-views--slim). */
.rm-views { display: flex; align-items: center; column-gap: 16px; min-height: 48px; padding: 0 16px; border-bottom: 1px solid var(--border); }
.rm-menu { display: none; flex: none; }   /* a phone's way to the sidebar (below) */
.rm-modes { flex: none; }
.rm-modes button { display: inline-flex; align-items: center; gap: 6px; }
.rm-mode-icon { flex: none; display: inline-flex; justify-content: center; width: 16px; }   /* a set width: the row is measured before the icon font is in */
.rm-views--tight .rm-modes button:not(.on) .rm-mode-name, .rm-views--icons .rm-mode-name { display: none; }
.rm-views--slim .rm-modes button { padding: 0 8px; }
.rm-tools { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex: none; margin-left: auto; }
.rm-views .sb-iconbtn:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--blue-01); }
.rm-tools .sb-counter .count { pointer-events: none; }   /* a press on the count is a press on Filter */
.rm .sb-msel .ml:first-child { padding-left: 8px; }   /* label-only chip, as in the Contacts sort chip */
.rm .sb-msel:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--blue-01); }
/* On a phone the row also holds the button that opens the sidebar, so its gaps are the tools' own 8px and its gutters
   the plan's 12px; under 380px it gives up more of its gutters, so the page still never scrolls sideways from 360px. */
@media (max-width: 767px) {
  .rm-views { column-gap: 8px; padding: 0 12px; }
  .rm-menu { display: inline-flex; }
}
@media (max-width: 379px) { .rm-views { padding: 0 8px; } }

/* applied filters: one small DS tag for each filter that has a value, at the left of the Filter button. A tag holds two
   buttons: its body (the filter's icon and values) opens the filter's checklist, its x removes the filter. Long values
   end in an ellipsis (the tooltip has them all); short of room, filters.js cuts the tags shorter (--rm-ftag-cap), then
   hides them all, so they never push the row onto a second line. */
.rm-ftags { display: flex; align-items: center; gap: 6px; }
.rm-ftag { gap: 4px; max-width: var(--rm-ftag-cap, 200px); }
.rm-ftag button { position: relative; display: inline-flex; align-items: center; padding: 0; border: 0; border-radius: var(--r-2); background: none; font: inherit; color: inherit; cursor: pointer; }
.rm-ftag button::after { content: ""; position: absolute; inset: -8px 0; }   /* as tall to press as the 32px buttons beside it */
.rm-ftag button:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--blue-01); }
.rm-ftag-body { gap: 4px; min-width: 0; }
.rm-ftag .rm-ftag-body::after { inset: -8px 0 -8px -4px; }   /* and out to the tag's own edge: no part of a tag is dead */
.rm-ftag-icon { flex: none; display: inline-flex; justify-content: center; width: 16px; }
.rm-ftag-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rm-ftag .rm-ftag-x { flex: none; justify-content: center; width: 16px; height: 16px; }
.rm-ftag .rm-ftag-x::after { inset: -8px -4px; }
.rm-ftag-x:hover { background: var(--blue-02); }

/* Filter, Sort and account popovers: the DS menu, on <body> and fixed (filters.js places each under its button, right
   edges lined up), so no pane's overflow clips one and each sits above the map, its legend and tooltip, and the inspector. */
.rm-pop { position: fixed; z-index: 10; max-width: calc(100vw - 16px); }
.rm-pop--wide { width: 320px; }   /* both of Filter's screens, so going from one to the other moves nothing */
.rm-pop-list { min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
/* Filter's first screen: a property's values sit at the right in the DS count's quiet style, and give way to its name. */
.rm-pop-pname { flex: none; }
.rm-pop-prop .mcount { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* A checklist's header: the way back, the property's name, "Clear". The back arrow sits over the checkboxes. */
.rm-pop-head { display: flex; align-items: center; gap: 6px; box-sizing: border-box; min-height: 40px; padding: 4px 4px 4px 6px; border-bottom: 1px solid var(--gray-05); }
.rm-pop-name { flex: 1; min-width: 0; font: var(--t-label-sb); color: var(--fg); }
/* A checklist row is a DS menu row holding a DS checkbox; its 24px box is tucked into the row's padding,
   so the row keeps a menu row's height and the box lines up with the header. */
.rm-pop .sb-checkbox { min-width: 0; margin: -4px 0 -4px -6px; }
.rm-pop .sb-checkbox .tt { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The checkbox's own tick: the menu row's selected-tick rule (.sb-menuitem .ck) would hide, recolour and shift it. */
.rm-pop .sb-checkbox .ck { margin: 0; color: inherit; font-size: inherit; visibility: inherit; }
.rm-pop-none .sb-checkbox .tt, .rm-pop-none .mcount { color: var(--fg-tertiary); }
/* The account menu's plain lines, over its one row: who is signed in, then quieter the date and what it says about the
   data, wherever the row of controls has no room for the date (host.js). An address or a sentence longer than the menu
   is wide (the account row's width, filters.js) goes on to the next line; from the folded rail's avatar, where the
   menu is its own width, the lines are no wider than that row is in the open sidebar. */
.rm-pop-lines { box-sizing: border-box; max-width: calc(var(--rail-w) - 28px); padding: 9px 12px; border-bottom: 1px solid var(--gray-05); font: var(--t-tiny); color: var(--fg); overflow-wrap: anywhere; }
.rm-pop-lines div + div { margin-top: 4px; font: var(--t-label); color: var(--fg-secondary); }
.rm-pop .sb-menuitem:focus-visible, .rm-pop .sb-dd-search:focus-within { outline: none; box-shadow: inset 0 0 0 2px var(--blue-01); }
.rm-pop .sb-iconbtn:focus-visible, .rm-pop .sb-btn:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--blue-01); }

.rm-body { flex: 1; min-height: 0; display: flex; container: rm-body / inline-size; }   /* its width, not the screen's, says whether the legend has a column */
/* Until the roadmap is here (index.html starts in this state and host.js ends it), and where it could not be loaded, the
   map, the plan and the panel are not laid out, in any view: the view is the waiting mark alone, or the notice.
   !important, as the design system's [hidden] is: what each view shows is settled further down, by rules that outweigh this. */
.rm-body[data-state] > :is(.rm-map, .rm-plan, .rm-inspector) { display: none !important; }
/* the waiting mark: the sign-in page's, in the middle of the view and larger than it is there (44px), as a page is.
   orb.js draws it in the colour it inherits: the page's text colour, dark on the light theme and light on the dark.
   Under it, as on that page, the words that say what is waited for, hung 12px below the mark so the mark keeps the
   middle: the mark is not drawn until host.js is in, and does not turn under reduced motion. */
.rm-wait { position: relative; flex: 1; display: grid; place-items: center; min-width: 0; min-height: 0; }   /* positioned: its words hang from its middle */
.rm-wait:focus { outline: none; }   /* it keeps the keyboard's place after "Try again"; there is nothing on it to press */
.rm-orb { display: block; width: 72px; height: 72px; color: var(--fg); }
.rm-wait-words { position: absolute; top: calc(50% + 48px); left: 0; right: 0; text-align: center; font: var(--t-label); color: var(--fg-secondary); }
/* the notice: the DS empty state over the whole view, inside the map's gutters, its one or two buttons side by side */
.rm-failed { flex: 1; min-width: 0; margin: 24px; text-align: center; }
.rm-failed-acts { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 8px; }
.rm-failed .sb-btn:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--blue-01); }
.rm-map { position: relative; flex: 1; min-width: 0; min-height: 0;
  /* Graph colour roles. Set on the map so the engine's mount and the legend beside it read the same values. */
  --pg-ink: var(--fg-secondary);
  --pg-ink-dim: var(--gray-05);
  --pg-focus: var(--primary);
  --pg-line: var(--fg-tertiary);
  --pg-label: var(--fg);
  --pg-label-muted: var(--fg-tertiary);
  --pg-label-bg: var(--surface);
  --pg-label-border: var(--border);
  --pg-font: var(--font-sans);
  --pg-font-label: 12px;   /* the engine wants sizes, not font shorthands: the sizes inside --t-label / --t-indicator */
  --pg-font-sub: 11px;
  --pg-radius: var(--radius-control);
  /* Seven Feature colours (host.js: paletteSize 7). Blue, --series-1, is left out: it is the selection colour. */
  --pg-cage-1: var(--series-2); --pg-cage-2: var(--series-3); --pg-cage-3: var(--series-4); --pg-cage-4: var(--series-5);
  --pg-cage-5: var(--series-6); --pg-cage-6: var(--series-7); --pg-cage-7: var(--series-8); --pg-cage-8: var(--series-2);
  --pg-status-prioritize: var(--gray-04);
  --pg-status-product: var(--yellow-01);
  --pg-status-technology: var(--orange-01);
  --pg-status-qa: var(--blue-01);
  --pg-status-released: var(--green-01);
}
/* On the light theme a Feature's colour is a thin line or a small dot on white, where the DS chart colours are too pale
   to see (the yellow is 1.5:1). There each is mixed a little past half-way to the text colour, and a line draws more
   firmly than on dark: one that answers in full at full strength, one that answers in part at 0.8. Every Feature's
   node and full line is then 4:1 or better on white and every line in part 3:1 or better. The legend's drawings and
   the map's labels read the same colours. */
[data-theme="light"] .rm-map {
  --pg-thread: 1; --pg-thread-part: 0.8;
  --pg-cage-1: color-mix(in srgb, var(--series-2) 45%, var(--fg)); --pg-cage-2: color-mix(in srgb, var(--series-3) 45%, var(--fg));
  --pg-cage-3: color-mix(in srgb, var(--series-4) 45%, var(--fg)); --pg-cage-4: color-mix(in srgb, var(--series-5) 45%, var(--fg));
  --pg-cage-5: color-mix(in srgb, var(--series-6) 45%, var(--fg)); --pg-cage-6: color-mix(in srgb, var(--series-7) 45%, var(--fg));
  --pg-cage-7: color-mix(in srgb, var(--series-8) 45%, var(--fg)); --pg-cage-8: color-mix(in srgb, var(--series-2) 45%, var(--fg));
  /* The stage word in a Feature's label on the map is small text on white: the same mix, and the first stage's grey a text grey. */
  --pg-status-prioritize: var(--fg-secondary);
  --pg-status-product: color-mix(in srgb, var(--yellow-01) 45%, var(--fg)); --pg-status-technology: color-mix(in srgb, var(--orange-01) 45%, var(--fg));
  --pg-status-qa: color-mix(in srgb, var(--blue-01) 45%, var(--fg)); --pg-status-released: color-mix(in srgb, var(--green-01) 45%, var(--fg));
}
.rm-mount { position: absolute; inset: 0; }
.rm-mount:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--blue-01); }
/* map zoom: a small group floating on the map, bottom right, as DS bordered icon buttons on the surface colour. Above the
   canvas and under the hover tooltip; the legend keeps the bottom left, and stops short of the column of three (below).
   It comes with the legend (the element before it): where no map is drawn there is neither. */
.rm-zoom { position: absolute; right: 16px; bottom: 16px; z-index: 1; display: flex; flex-direction: column; gap: 4px; }
.rm-legend[hidden] ~ .rm-zoom { display: none; }
.rm-zoom .sb-iconbtn:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--blue-01); }

/* legend — a DS card holding a DS legend list; each swatch is a small drawing of the mark itself. On a narrow map, a
   phone's or one squeezed between the open sidebar and the inspector, it leaves the zoom its column: the 32px buttons,
   8px beside them, the map's two 16px gutters, and the card's own two borders, which its width does not count. */
.rm-legend { position: absolute; left: 16px; bottom: 16px; z-index: 1; width: 296px; max-width: calc(100% - 74px); max-height: calc(100% - 32px); overflow-y: auto; background: var(--surface); border-color: var(--border); }
.rm-legend summary { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 12px; cursor: pointer; list-style: none; font: var(--t-label-sb); color: var(--fg); }
.rm-legend summary::-webkit-details-marker { display: none; }
.rm-legend summary:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--blue-01); }
.rm-legend summary i { font-size: 11px; color: var(--fg-tertiary); transition: transform .15s; }
.rm-legend[open] summary i { transform: rotate(180deg); }
.rm-legend:not([open]) { width: auto; }
.rm-legend-list { flex-direction: column; flex-wrap: nowrap; gap: 6px; padding: 2px 12px 8px; }
.rm-legend-list .it { align-items: flex-start; gap: 10px; }
.rm-legend-list .it b { display: block; font: var(--t-label-sb); color: var(--fg); }
.rm-legend-keys { padding: 6px 12px; border-top: 1px solid var(--border); font: var(--t-label); color: var(--fg-tertiary); }
.rm-legend:not([open]) .rm-legend-keys { display: none; }
.rm-glyph { flex: none; width: 36px; height: 20px; margin-top: 1px; fill: none; stroke-width: 1.25; }
.rm-glyph .ink { fill: var(--pg-ink); stroke: none; shape-rendering: crispEdges; }
.rm-glyph polygon.ink { shape-rendering: auto; }   /* a triangle or diamond: a slanted edge drawn crisp is a staircase */
.rm-glyph .faded { stroke: var(--pg-ink-dim); shape-rendering: crispEdges; }
.rm-glyph .hub { stroke: var(--pg-ink); stroke-width: 1.6; shape-rendering: crispEdges; }
.rm-glyph .line { stroke: var(--pg-ink); opacity: .55; }
.rm-glyph .space { stroke: var(--pg-ink); opacity: .6; }
.rm-glyph .halo { stroke: var(--pg-line); opacity: .7; }
.rm-glyph .feature-link { stroke: var(--pg-cage-1); stroke-dasharray: 2 1.6; }
.rm-glyph .feature-a { stroke: var(--pg-cage-1); }
.rm-glyph .feature-b { stroke: var(--pg-cage-2); stroke-dasharray: 2.5 2; }
.rm-glyph .feature-dot { fill: var(--pg-cage-1); stroke: none; }   /* the core of a Feature's node, inside its outline */
.rm-glyph .focus { stroke: var(--pg-focus); }
.rm-glyph .focus-dot { fill: var(--pg-focus); stroke: none; shape-rendering: crispEdges; }
@media (prefers-reduced-motion: reduce) { .rm-legend summary i { transition: none; } }
/* Where the page is wide an open legend takes its own column, so it never covers part of the map: from 1216px of page,
   which is a 1280px screen beside the folded sidebar, or a 1480px one beside the open one. */
@container rm-body (min-width: 1216px) { .rm-map:has(.rm-legend[open]) .rm-mount { left: 328px; } }

.rm-inspector { width: 360px; flex: none; display: flex; flex-direction: column; min-height: 0; border-left: 1px solid var(--border); background: var(--surface); }
.rm-tabs { border-top: 0; }
.rm-listpane { flex: 1; min-height: 0; overflow-y: auto; }
.rm-detail { position: relative; flex: 1; min-height: 0; overflow-y: auto; padding: 16px; }   /* positioned: as the plan is, for rm-hidden text */
.rm-foot { padding: 8px 96px 8px 16px;  /* right: clear of the site's floating theme chip */ border-top: 1px solid var(--border); font: var(--t-label); color: var(--fg-tertiary); }
.rm-foot:empty { display: none; }

@container rm-body (max-width: 1023px) {   /* by the page's width, as the legend's column is: the sidebar may be open beside it */
  .rm-inspector { width: 300px; }
}
@media (max-width: 767px) {
  .rm-body { flex-direction: column; }
  .rm-map { flex: none; height: 60vh; }
  .rm-inspector { width: auto; border-left: 0; border-top: 1px solid var(--border); }
  .rm-failed { margin: 12px; }   /* the row's own gutters */
}

/* inspector rows + detail — DS Item View rows (sb-item--row), the site's status pill, DS tooltip */
.rm-list .sb-item, .rm-detail .sb-item { background: transparent; align-items: flex-start; padding: 10px 16px; }
.rm-detail .sb-item { padding: 10px 4px 10px 0; }
.rm-rowbody { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.rm-rowbody .nm { overflow-wrap: anywhere; }
.rm-list .sb-item .mt, .rm-detail .sb-item .mt { flex: none; }
.rm-sub { font: var(--t-tiny); color: var(--fg-tertiary); }
/* A Feature's row on the map ends with its stage and, beside it, who it is assigned to: their names while those fit and
   the DS avatar group otherwise, as on a board's card (people.js measures). */
.rm-rowfoot { display: flex; align-items: center; gap: 8px; min-width: 0; }
.rm-rowfoot .rm-status { flex: none; align-self: center; }
.rm-rowfoot .rm-people { flex: 1; font: var(--t-tiny); color: var(--fg-secondary); }
.rm-rowfoot .rm-people .nm { font: inherit; }   /* a person's name, not the row's: the DS row would set it as its title */
/* A stage's colours, wherever the stage is drawn: its pill, its column on the board, its bar on the timeline.
   Prioritize, the first stage, is the plain grey one. */
.rm-status, .rm-col, .rm-gbar { --rm-ink: var(--gray-02); --rm-tint: var(--gray-07); --rm-edge: var(--gray-05); }
.rm-status--product, .rm-col--product, .rm-gbar--product { --rm-ink: var(--yellow-01); --rm-tint: var(--yellow-02); --rm-edge: color-mix(in srgb, var(--yellow-01) 45%, transparent); }
.rm-status--technology, .rm-col--technology, .rm-gbar--technology { --rm-ink: var(--orange-01); --rm-tint: var(--orange-02); --rm-edge: color-mix(in srgb, var(--orange-01) 45%, transparent); }
.rm-status--qa, .rm-col--qa, .rm-gbar--qa { --rm-ink: var(--blue-01); --rm-tint: var(--blue-02); --rm-edge: color-mix(in srgb, var(--blue-01) 45%, transparent); }
.rm-status--released, .rm-col--released, .rm-gbar--released { --rm-ink: var(--green-01); --rm-tint: var(--green-02); --rm-edge: color-mix(in srgb, var(--green-01) 45%, transparent); }
.rm-status { display: inline-flex; align-self: flex-start; align-items: center; gap: 6px; font: var(--t-label-sb); white-space: nowrap;
  border-radius: var(--radius-chip); padding: 2px 9px; border: 1px solid var(--rm-edge); background: var(--rm-tint); color: var(--rm-ink); }
.rm-status .led { width: 6px; height: 6px; border-radius: var(--radius-pill); background: var(--rm-ink); }
.rm-status--product { color: var(--gray-00); }   /* yellow on pale yellow cannot be read in the light theme; the dot keeps the stage's colour */
.rm-dback { margin: -4px 0 8px -8px; }
.rm-dtitle { margin: 0 0 8px; font: var(--t-heading6); color: var(--fg); }
.rm-dtext { margin: 0; font: var(--t-paragraph); color: var(--fg-secondary); }
.rm-dsec { margin-top: 16px; }
.rm-dlabel { font: var(--t-label-sb); color: var(--fg-tertiary); margin-bottom: 4px; }
.rm-more { padding: 12px 16px; font: var(--t-tiny); color: var(--fg-tertiary); }
.rm-hovertip { position: absolute; pointer-events: none; z-index: 2; }

/* ---------- plan views: the Features laid out as Notion lays out a database (a board, a timeline, a table), in DS parts ---------- */
/* The plan scrolls both ways. Its top and left gutters are margins on what it holds, not padding, so a header row or a
   column of names that sticks meets the plan's own edge; it is positioned, so text kept only for screen readers
   (rm-hidden) stays inside its scroll and never widens the page. */
.rm-plan { --rm-gutter: 16px; position: relative; flex: 1; min-width: 0; min-height: 0; overflow: auto; padding: 0 var(--rm-gutter) 56px 0; }   /* bottom: clear of the site's floating theme chip */
.rm-plan > * { margin: var(--rm-gutter) 0 0 var(--rm-gutter); }
body:not([data-mode="map"])[data-mode] .rm-detail { padding-bottom: 56px; }
.rm-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
/* Outside the map view the map, with its legend and zoom, is hidden, and the inspector is only a selected project's detail. */
body[data-mode="board"] .rm-map, body[data-mode="timeline"] .rm-map, body[data-mode="list"] .rm-map { display: none; }
body:not([data-mode="map"])[data-mode] .rm-inspector { display: none; }
body:not([data-mode="map"])[data-mode].rm--picked .rm-inspector { display: flex; }
body:not([data-mode="map"])[data-mode] .rm-tabs, body:not([data-mode="map"])[data-mode] .rm-listpane, body:not([data-mode="map"])[data-mode] .rm-foot { display: none; }
.rm-modes button:focus-visible, .rm-pcard:focus-visible, .rm-detail .rm-doclink:focus-visible, .rm-md a:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--blue-01); }
/* A row's button fills its row, and a table's cell clips what is in it: there the ring is drawn inside. */
.rm-glabel:focus-visible, .rm-sort:focus-visible, .rm-ptable .sb-dtcell:has(:focus-visible) { outline: none; box-shadow: inset 0 0 0 2px var(--blue-01); }
.rm-planempty { margin: 48px auto; text-align: center; font: var(--t-paragraph); color: var(--fg-tertiary); }
.rm-count { font: var(--t-tiny); color: var(--fg-tertiary); }   /* how many a group holds, beside its name */
.rm-picon { flex: none; width: 16px; text-align: center; color: var(--fg-tertiary); }   /* a property's icon, beside its name */
.rm-ptags { display: flex; flex-wrap: wrap; gap: 4px; }

/* people: DS avatars. On one line they keep their names (sb-who) while those fit, and are the DS avatar group otherwise
   (people.js measures, so the names never wrap or show an ellipsis between people); a lone name may be cut short. */
.rm-people { display: flex; min-width: 0; }
.rm-people-names { display: flex; gap: 6px 12px; min-width: 0; overflow: hidden; white-space: nowrap; }
.rm-people .sb-who { flex: none; }
.rm-people .sb-who:only-child { flex: 0 1 auto; }
.rm-people .nm { overflow: hidden; text-overflow: ellipsis; color: inherit; }   /* the name reads as the text around it: quiet on a card, plain in a table or a panel */
.rm-people--wrap .rm-people-names { flex-direction: column; }

/* board: one DS lane (sb-leadwrap) for each stage, softly tinted as Notion tints a board's columns. A lane's header is
   the stage's pill and a count; it carries its stage and each card its project's id, ready for cards to be moved between lanes. */
.rm-board { display: grid; grid-template-columns: repeat(5, minmax(220px, 1fr)); gap: 12px; align-items: start; min-width: 1160px; }
.rm-col { background: var(--rm-tint); }
.rm-col .rm-status { background: var(--white); }   /* on its own tint the pill would be an outline; the card colour sets it apart */
.rm-colempty { margin: 0; padding: 4px 8px 8px; font: var(--t-tiny); color: var(--fg-tertiary); }
/* card: the DS card as one button. Selected as the DS item card is; hover is the DS's row hover, a shade lighter than the
   item card's, which is the tags' own grey. The title, then one property to a line. */
.rm-pcard { display: flex; flex-direction: column; gap: 6px; width: 100%; padding: 10px 12px; text-align: left; font-family: var(--font-sans); color: var(--fg); cursor: pointer; transition: background .12s, border-color .12s; }
.rm-pcard:hover { background: var(--gray-07); border-color: var(--gray-05); }
.rm-pcard.is-selected { background: var(--blue-03); border-color: var(--blue-01); }
.rm-pname { display: flex; gap: 8px; align-items: baseline; justify-content: space-between; font: var(--t-paragraph-sb); line-height: 1.43; }
.rm-pname .nm { min-width: 0; overflow-wrap: anywhere; }
.rm-pline, .rm-pcard .rm-people { font: var(--t-tiny); color: var(--fg-secondary); }
/* A project that is part of another names its parent, quietly: on its card and under its title in its panel. The parent's
   name opens the parent, and says so under the pointer. */
.rm-partof { margin: 0; font: var(--t-tiny); color: var(--fg-tertiary); overflow-wrap: anywhere; }
.rm-partof .lk { border: 0; padding: 0; background: none; font: inherit; color: var(--fg-secondary); text-align: left; cursor: pointer; }
.rm-partof .lk:hover { color: var(--blue-01); text-decoration: underline; }
.rm-partof .lk:focus-visible { outline: none; border-radius: var(--r-2); box-shadow: 0 0 0 2px var(--blue-01); }
.rm-detail .rm-partof { margin: -4px 0 8px; }

/* moving a card, on a live board only (plan.js). The card stays where it was, faded, so its place is held open; a copy of
   it follows the pointer, lifted and slightly see-through; a line marks the gap it will land in, and the column under the
   pointer is ringed in its stage's colour. A card whose move is still being saved is faded and cannot be picked up.
   None of it is animated: the copy is where the pointer is. Under reduced motion a card's own hover does not fade either. */
.rm-board--live .cards { position: relative; }   /* the line is placed in it */
@media (prefers-reduced-motion: reduce) { .rm-pcard { transition: none; } }
.rm-pcard.is-lifted { opacity: .35; cursor: grabbing; }
.rm-pcard.is-saving { opacity: .6; cursor: progress; }
.rm-pghost { position: fixed; left: 0; top: 0; z-index: 9; pointer-events: none; opacity: .92; box-shadow: var(--elevation-popover); transition: none; }
.rm-col.is-over { box-shadow: inset 0 0 0 2px var(--rm-ink); }
.rm-dropline { position: absolute; left: 2px; right: 2px; z-index: 10; height: 2px; border-radius: var(--radius-pill); background: var(--blue-01); pointer-events: none; }   /* over the copy, which is under the pointer and so over the gap */

/* toasts (host.js): the DS toast where the DS puts it, bottom centre and 16px from the edges, of the page beside the
   sidebar and so never over it; over everything else. On a phone the sidebar is a drawer over the page: while that is
   open a toast waits behind its scrim. A press reaches the toast and nothing around it. Its buttons (what it offers, and
   Dismiss on one that stays) take the toast's own text colour, also under the pointer: the DS hover would put its pale
   grey behind that text. */
.rm-toasts { position: fixed; left: calc(var(--rm-side) + 16px); right: 16px; bottom: 16px; z-index: 12; display: flex; justify-content: center; pointer-events: none; }
.rm-toasts .sb-toast { max-width: 100%; box-sizing: border-box; pointer-events: auto; cursor: pointer; }
.rm-toast-end { flex: none; display: flex; align-items: center; gap: 4px; }
.rm-toasts .sb-btn--text, .rm-toasts .sb-iconbtn { flex: none; color: inherit; }
.rm-toasts .sb-btn--text:hover, .rm-toasts .sb-iconbtn:hover { background: color-mix(in srgb, currentColor 16%, transparent); color: inherit; }
.rm-toasts .sb-btn--text:focus-visible, .rm-toasts .sb-iconbtn:focus-visible { outline: none; box-shadow: 0 0 0 2px currentColor; }
@media (max-width: 767px) { .rm-toasts { bottom: 56px; } }   /* on a phone a toast is as wide as the screen: it sits above the site's floating theme chip */
.rm--drawer .rm-toasts { z-index: 6; }   /* under the scrim (7) and the drawer (8) */

/* a live project's Stage, in its panel (host.js): the DS status dropdown, and in its menu a dot in each stage's colour */
.rm-stagedd:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--blue-01); }
.rm-stagedd[aria-disabled="true"] { opacity: .6; cursor: progress; }
.rm-stagedd.sb-statusdd--yellow { color: var(--gray-00); border-color: var(--yellow-01); }   /* as the Product pill: yellow on pale yellow cannot be read in the light theme */
.rm-stagedot { display: block; width: 6px; height: 6px; margin: 0 auto; border-radius: var(--radius-pill); background: var(--rm-ink, var(--gray-02)); }

/* timeline: the projects' names in a column that stays put and, for each project, a bar from start to due in its stage's
   tint, under a band of months and dates. The chart scrolls inside its own frame, both ways, so the band and the names
   never leave it. plan.js sets how wide the chart is (--rm-gwide, from the scale) and gives every bar, date and line its place. */
.rm-timeline { position: relative; display: flex; flex-direction: column; box-sizing: border-box; max-height: calc(100% - var(--rm-gutter)); container-type: inline-size;
  border: 1px solid var(--border); border-radius: var(--r-5); overflow: hidden; }
.rm-gscroll { flex: 0 1 auto; min-height: 0; overflow: auto; overscroll-behavior-x: contain; scroll-padding-top: 64px; }   /* a row reached with the keyboard is never left under the band */
.rm-gantt { --rm-gside: 280px; position: relative; display: flex; flex-direction: column; width: max-content; min-width: 100%; }
.rm-gscale, .rm-grow { display: grid; grid-template-columns: var(--rm-gside) minmax(var(--rm-gwide, 0px), 1fr); }
.rm-gscale { position: sticky; top: 0; z-index: 3; height: 64px; border-bottom: 1px solid var(--border); background: var(--gray-07); }
.rm-grow { min-height: 40px; }
.rm-grow + .rm-grow > * { border-top: 1px solid var(--border); }   /* on the cells, not the row: nothing shows between two of the names that stay put */
.rm-gcorner, .rm-glabel { position: sticky; left: 0; z-index: 2; min-width: 0; border: 0; border-right: 1px solid var(--border); }
.rm-gcorner { display: flex; align-items: center; gap: 6px; padding: 0 12px; background: var(--gray-07); font: var(--t-tiny); color: var(--fg-secondary); }
.rm-glabel { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 6px 12px;
  background: var(--bg); text-align: left; font: var(--t-tiny-sb); color: var(--fg); cursor: pointer; }
.rm-glabel .rm-status, .rm-urow .rm-status, .rm-ptable .rm-status, .rm-prop .rm-status { align-self: center; flex: none; }   /* beside a name or in a cell, not under a row's name */
.rm-glabel:hover .nm { color: var(--blue-01); }
.rm-glabel.is-selected { background: var(--blue-02); }
.rm-glabel .nm, .rm-urow .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.rm-gtrack { position: relative; min-width: 0; }
/* the view's controls, over the right end of the band's row of months: "No date", the scale, then back, today and forward.
   The months pass under them. Where the frame is too narrow for both they take a row of their own, above the band. */
.rm-gtools { position: absolute; top: 0; right: 0; z-index: 4; display: flex; align-items: center; gap: 4px; box-sizing: border-box; height: 40px; padding: 0 8px 0 32px;
  background: linear-gradient(to right, transparent, var(--gray-07) 24px); }
.rm-gtools .sb-btn--dropdown { height: 32px; }   /* the DS dropdown button at the height of the toolbar's 32px buttons */
.rm-gnav { display: flex; align-items: center; }
.rm-gnav .is-disabled { cursor: default; }   /* an arrow at its end of the chart */
.rm-gtools .sb-btn:focus-visible, .rm-gtools .sb-iconbtn:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--blue-01); }
.rm-timeline--bare .rm-gtools { position: static; justify-content: flex-end; padding-left: 8px; background: var(--gray-07); border-bottom: 1px solid var(--border); }
@container (max-width: 880px) {
  .rm-gtools { position: static; flex-wrap: wrap; justify-content: flex-end; height: auto; min-height: 40px; padding: 4px 8px; background: var(--gray-07); border-bottom: 1px solid var(--border); }
}
/* with no dated project there is no chart: the frame says so, under the "No date" button */
.rm-gbare { margin: 0; padding: 48px 24px; text-align: center; font: var(--t-paragraph); color: var(--fg-tertiary); }
/* the band: each month by name over its own days, the name held at the left edge while any of its month is in view; under
   the names today and, by the scale (plan.js), every day or each Monday by its date */
.rm-gmonth { position: absolute; top: 0; bottom: 0; box-sizing: border-box; border-left: 1px solid var(--border-strong); }
.rm-gmonth.is-cut { border-left: 0; }   /* the chart starts part-way through this month */
.rm-gmonth span { position: sticky; left: var(--rm-gside); display: block; width: max-content; padding: 13px 8px 0; font: var(--t-label-sb); color: var(--fg-secondary); white-space: nowrap; }
.rm-gtick { position: absolute; bottom: 6px; transform: translateX(-50%); font: var(--t-indicator); color: var(--fg-tertiary); }
.rm-gnow { position: absolute; bottom: 3px; z-index: 1; transform: translateX(-50%); padding: 2px 6px; border-radius: var(--radius-pill);
  background: var(--blue-01); font: var(--t-indicator); font-weight: var(--fw-semibold); color: var(--fg-on-dark); white-space: nowrap; }
/* behind the rows: a rule where each month starts, and today's line */
.rm-grules { position: absolute; top: 0; bottom: 0; left: var(--rm-gside); right: 0; pointer-events: none; }
.rm-grule, .rm-gtoday { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--border); }
.rm-gtoday { background: var(--blue-01); }
/* between the rules and the bars: a line from each project that blocks another to the one it blocks, in the secondary
   text grey (the DS yellow is 1.5:1 on a white chart), and dashed in the danger red, a little towards the text colour,
   where the dates break the order: late is told by the dashes as well as the hue. The lines of the project pointed at
   stand out from the rest. */
.rm-gdeps { position: absolute; top: 0; left: var(--rm-gside); width: calc(100% - var(--rm-gside)); height: 100%; overflow: visible; pointer-events: none; }
.rm-gdep { --rm-dep: var(--fg-secondary); transition: opacity .12s; }
.rm-gdep.is-late { --rm-dep: color-mix(in srgb, var(--danger) 80%, var(--fg)); }
.rm-gdep.is-late path { stroke-dasharray: 5 4; }
.rm-gdep path { fill: none; stroke: var(--rm-dep); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.rm-gdep polygon { fill: var(--rm-dep); stroke: var(--rm-dep); stroke-width: 1; stroke-linejoin: round; }
.rm-gdeps.is-picking .rm-gdep { opacity: .5; }
.rm-gdeps.is-picking .rm-gdep.is-on { opacity: 1; }
.rm-gdeps.is-picking .rm-gdep.is-on path { stroke-width: 2.25; }
@media (prefers-reduced-motion: reduce) { .rm-gdep { transition: none; } }
/* a bar, with its title inside it, held at the left edge while a long bar runs off it; plan.js moves the title out
   (is-out), after the bar or before it, where it does not fit */
.rm-gbar { position: absolute; top: 50%; height: 24px; transform: translateY(-50%); display: flex; align-items: center; box-sizing: border-box;
  border: 1px solid var(--rm-edge); border-radius: var(--r-5); background: var(--rm-tint); cursor: pointer; }
.rm-gtitle { position: sticky; left: calc(var(--rm-gside) + 8px); min-width: 0; margin: 0 8px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: var(--t-label-sb); color: var(--fg); }
.rm-gbar.is-out .rm-gtitle { position: absolute; left: calc(100% + var(--rm-gafter, 8px)); margin: 0; font: var(--t-label); color: var(--fg-secondary);
  background: var(--bg); box-shadow: 0 0 0 3px var(--bg); }   /* over the rules and lines behind it, so none strikes through the words */
.rm-gbar.is-out.is-before .rm-gtitle { left: auto; right: calc(100% + 8px); }
.rm-gbar.is-from { --rm-gafter: 20px; }   /* a project that blocks another: its line turns just after its bar, so its title starts further off */
/* a project with one date: a small diamond on that day, in the stage's own colour */
.rm-gbar.is-point { width: 10px; height: 10px; border: 0; background: none; }
.rm-gbar.is-point::before { content: ""; position: absolute; inset: 0; border-radius: var(--r-2); background: var(--rm-ink); transform: rotate(45deg); }
/* after a bar, or after its title: who it is assigned to and its products, quietly, on one line that plan.js cuts off at
   the chart's end */
.rm-gtrail { position: absolute; top: 50%; transform: translateY(-50%); display: flex; align-items: center; gap: 8px; box-sizing: border-box; padding: 2px; overflow: hidden;
  white-space: nowrap; font: var(--t-label); color: var(--fg-tertiary); background: var(--bg); box-shadow: 0 0 0 3px var(--bg); }
.rm-gtrail .rm-people { flex: 0 1 auto; max-width: 240px; }
.rm-gtrail .rm-ptags { flex: none; flex-wrap: nowrap; }
/* "No date": the projects with nothing to draw, behind one quiet button among the controls. Its list is the DS menu, a
   row for each project, in columns that line up down the list: name, stage, people, and a tick on the project that is open */
.rm-pop--undated { width: 480px; }
.rm-urow { display: grid; grid-template-columns: minmax(0, 1fr) 100px 104px 12px; }
.rm-urow .rm-status { grid-column: 2; justify-self: start; }
.rm-urow .rm-people { grid-column: 3; font: var(--t-tiny); color: var(--fg-secondary); }
.rm-urow .ck { grid-column: 4; }
@media (max-width: 767px) {   /* a phone's list is too narrow for the people as well; they stay in each row's name for a screen reader */
  .rm-urow { grid-template-columns: minmax(0, 1fr) 100px 12px; }
  .rm-urow .rm-people { display: none; }
  .rm-urow .ck { grid-column: 3; }
}

/* list: the DS data table (sb-datatable) on a bordered card, with a count under it. The plan scrolls, not the table, so
   the header row stays in view and a re-sort or a selection keeps its place. The columns' least widths come to 1302px
   with the card's borders and the plan's gutters: the whole list on a 1366px screen beside the folded sidebar
   (sidebar.js opens the sidebar by default only where the list is whole beside that too). */
.rm-tablebox { min-width: min-content; border: 1px solid var(--border); border-radius: var(--r-5); overflow: clip; }   /* clip, not hidden: the header sticks to the plan's own scroll */
.rm-ptable { overflow: visible;
  --dt-cols: 64px minmax(260px, 1fr) minmax(136px, 148px) minmax(200px, 220px) minmax(156px, 248px) 124px 124px 124px 80px; }
.rm-ptable .sb-dtgrid { width: auto; }   /* as wide as the page: the DS grid would grow to the longest title on one line */
.rm-ptable .sb-dthead .sb-dtcell { gap: 6px; }
/* A sorting header is a button over its whole cell, with the DS table header's hover. */
.rm-sort { display: flex; flex: 1; align-items: center; align-self: stretch; gap: 6px; margin: -8px -16px; padding: 8px 16px; border: 0; background: none;
  font: inherit; color: inherit; cursor: pointer; text-align: left; outline: none; }
.rm-sort:hover { background: var(--gray-06); }
/* The whole row opens the project, so the whole row answers the pointer; the selected row is the DS table's pressed row,
   and stays that colour under the pointer: its rule is written to outrank the row's hover above it and the DS's own
   hover on a single cell. */
.rm-ptable .sb-dtrow:not(.sb-dthead):hover > .sb-dtcell { background: var(--gray-07); cursor: pointer; }
.rm-ptable .sb-dtrow.is-selected:not(.sb-dthead) > .sb-dtcell,
.rm-ptable .sb-dtrow.is-selected:not(.sb-dthead) > .sb-dtcell:hover:not(.sb-dtcell--empty):not(.sb-dtcell--stage):not(.sb-dtcell--status) { background: var(--blue-02); }
.rm-rowpick { border: 0; background: none; padding: 0; cursor: pointer; text-align: left; outline: none; }
.rm-listcount { margin: 8px 0 0; padding: 0 16px; font: var(--t-label); color: var(--fg-tertiary); }
.rm-doclink { font: var(--t-tiny-bold); color: var(--blue-01); text-decoration: none; }
.rm-doclink:hover { text-decoration: underline; }
.rm-ptable .rm-doclink { outline: none; }
.rm-dfacts { margin: 8px 0 4px; }

/* a project's panel: its properties, one to a row as in Notion's side peek: a quiet icon and name, then the value */
.rm-props { margin: 12px 0 16px; }
.rm-prop { display: grid; grid-template-columns: 148px minmax(0, 1fr); column-gap: 8px; }
.rm-prop dt, .rm-prop dd { display: flex; align-items: center; min-height: 32px; margin: 0; padding: 4px 0; box-sizing: border-box; font: var(--t-tiny); }
.rm-prop dt { align-self: start; gap: 8px; color: var(--fg-secondary); }
.rm-prop dd { color: var(--fg); overflow-wrap: anywhere; }
.rm-prop .rm-empty { color: color-mix(in srgb, var(--fg) 65%, transparent); }   /* a placeholder, fainter than any value in either theme, and still readable (4.7:1 on white) */
/* the description, the last property: the one that runs to paragraphs, so its name is over it and it has the row's
   whole width. It is shown as host.js makes it of its light Markdown (markdown): paragraphs, lists, bold, italic, code
   and links, in the panel's paragraph type. Code is the page's own type on a grey chip: the DS has no fixed-width one. */
.rm-prop--wide { position: relative; grid-template-columns: minmax(0, 1fr); }
.rm-prop--wide dd { display: block; min-height: 0; padding-top: 0; }
.rm-md { font: var(--t-paragraph); color: var(--fg-secondary); overflow-wrap: anywhere; }
.rm-md > * { margin: 0; }
.rm-md > * + * { margin-top: 8px; }
.rm-md ul, .rm-md ol { padding-left: 20px; }
.rm-md li + li, .rm-md li > ul, .rm-md li > ol { margin-top: 2px; }
.rm-md li > ul, .rm-md li > ol { margin-bottom: 0; }
.rm-md strong { font-weight: var(--fw-semibold); color: var(--fg); }
.rm-md code { padding: 1px 4px; border-radius: var(--r-3); background: var(--gray-06); font: var(--t-tiny); color: var(--fg); }
.rm-md a { border-radius: var(--r-2); color: var(--blue-01); text-underline-offset: 2px; }
.rm-desc .rm-sub { margin: 8px 0 0; }

/* a live project's panel (host.js; pickers.js draws the popovers): its people, its dates, what blocks it and its docs
   link are changed in their own rows, as on a Notion page. A value that can be changed is a quiet button over its whole
   cell, grey under the pointer and while its popover is open; open, it keeps its height (pickers.js), and a value that
   outgrows it shows from its first line. While a change to the project is on its way to OpsHub its controls wait, as
   the stage dropdown does, and the row being saved ends in the DS spinner. */
.rm-edit { display: flex; align-items: center; align-items: safe center; flex: 1; align-self: stretch; box-sizing: border-box; min-width: 0; margin: -4px -8px; padding: 4px 8px; border: 0; border-radius: var(--r-5);
  background: none; font: inherit; color: inherit; text-align: left; overflow-wrap: anywhere; cursor: pointer; }
.rm-edit:hover, .rm-edit[aria-expanded="true"] { background: var(--gray-06); }
.rm-edit:focus-visible, .rm-dep-open:focus-visible, .rm-dep-x:focus-visible, .rm-dep-add:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--blue-01); }
.rm-edit[aria-disabled="true"] { opacity: .6; }
.rm-edit[aria-disabled="true"], .rm-dep-x[aria-disabled="true"], .rm-dep-add[aria-disabled="true"] { cursor: progress; }
.rm-saving { flex: none; width: 12px; height: 12px; margin-left: 12px; box-sizing: border-box; border-width: 1.5px; color: var(--fg-tertiary); }
@media (prefers-reduced-motion: reduce) { .rm-saving { animation: none; } }
/* Where the whole cell cannot be the button, a small quiet one stands beside the value: "Change" after the docs link,
   which is a link of its own, and "Edit" at the end of the description's name. A press on the description's own words
   opens it too, so they are grey under the pointer as a value's button is. Its spinner takes Edit's place. */
.rm-edit--small { flex: none; align-self: center; margin: 0 0 0 8px; color: var(--fg-secondary); }
/* The docs link stays on one line. Where the row has no room for "Change" beside it, "Change" goes under it, its word
   under the link's first. */
.rm-docs { display: flex; flex-wrap: wrap; align-items: center; column-gap: 16px; min-width: 0; }
.rm-docs .rm-doclink { white-space: nowrap; }
.rm-docs .rm-edit--small { margin-left: -8px; }
.rm-prop--wide .rm-edit--small { position: absolute; top: 4px; right: 0; margin: 0; }
.rm-prop--wide .rm-saving { position: absolute; top: 10px; right: 4px; margin: 0; }
.rm-md--edit { margin: 0 -8px; padding: 4px 8px; border-radius: var(--r-5); cursor: pointer; }
.rm-md--edit:hover { background: var(--gray-06); }
/* the description being written (pickers.js: text), in the row: the DS field around a textarea as tall as what it holds,
   up to a height past which it scrolls; a quiet line saying what formatting works; what came of a save that did not
   save; someone else's description, where they changed it meanwhile, set off by a rule at its left; then Save and
   Cancel, or in their place the question asked before what was typed is dropped. */
.rm-write { display: flex; flex-direction: column; gap: 8px; padding-bottom: 4px; }
.rm-write .sb-field { display: flex; min-width: 0; }
.rm-write .sb-field-box { align-items: flex-start; padding: 6px 8px; }
.rm-write .sb-field:focus-within .sb-field-box { border-color: var(--blue-01); }
.rm-write-text { display: block; width: 100%; max-height: 320px; font: var(--t-tiny); line-height: 1.5; overflow-y: auto; }
.rm-write-hint, .rm-write-note { margin: 0; font: var(--t-label); line-height: 1.4; color: var(--fg-secondary); }   /* the hint is the one line that says what formatting works: no fainter than this (5.7:1 on white) */
.rm-write-note { padding: 8px; border-radius: var(--r-5); background: var(--gray-07); }
.rm-write-theirs { padding-left: 10px; border-left: 2px solid var(--border-strong); }
.rm-write-acts { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.rm-write-ask { flex: 1 0 100%; font: var(--t-tiny); color: var(--fg); }
.rm-write .sb-btn:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--blue-01); }   /* clear of the button: Save is the ring's own blue */
.rm-write .sb-btn[aria-disabled="true"] { cursor: progress; }
/* what blocks a project, and what it blocks: one project to a line, its title a link as a sub-project's parent is. On a
   live project the DS icon button beside a blocker removes it, and the row ends with "Add", the DS text button with an icon. */
.rm-deps { display: flex; flex-direction: column; align-items: flex-start; flex: 1; min-width: 0; }
.rm-deps ul { align-self: stretch; margin: 0; padding: 0; list-style: none; }
.rm-dep { display: flex; align-items: flex-start; justify-content: space-between; gap: 4px; }
.rm-dep-open { min-width: 0; padding: 4px 0; border: 0; border-radius: var(--r-2); background: none; font: inherit; color: inherit; text-align: left; overflow-wrap: anywhere; cursor: pointer; }
.rm-dep-open:hover { color: var(--blue-01); text-decoration: underline; }
.rm-dep-x { flex: none; }
.rm-dep-add { margin: -5px 0 -5px -12px; }   /* its icon starts where the titles above it do, and it makes its row no taller than the others */
/* the popovers those rows open: the DS menu, placed as the toolbar's is (.rm-pop). Who a project is assigned to is a
   checklist row holding a DS avatar and name, the address quiet beside them; a project to choose is its title and stage.
   A row that waits, or that cannot be changed here, is the DS disabled row. */
.rm-pick:focus { outline: none; }
.rm-pick .sb-menuitem.is-disabled:hover { background: none; }
.rm-pick-person .sb-checkbox { flex: none; }
.rm-pick-person .sb-who { flex: none; max-width: 50%; }
.rm-pick-person .sb-who .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: inherit; }
.rm-pick-person .mcount { flex: 0 1 auto; min-width: 0; margin-left: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: var(--t-label); color: var(--fg-tertiary); }
.rm-pick-add .rm-pick-name, .rm-pick-project .nm { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rm-pick-project .rm-status { align-self: center; flex: none; }
.rm-pick-note { padding: 9px 12px; border-bottom: 1px solid var(--gray-05); background: var(--gray-07); font: var(--t-label); line-height: 1.4; color: var(--fg-secondary); overflow-wrap: anywhere; }
/* a date's popover: the DS field around a native date input, on the field's own white so its floating label reads as
   it does on a form; "Clear" beside it, and under them the DS field error when a date cannot be taken. The docs link's
   popover is the same, around a text field. */
.rm-pick-date { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 6px 8px; padding: 16px 12px 12px; background: var(--white); }
.rm-pick-date .sb-field-input { font: var(--t-tiny); }
.rm-pick-date .sb-field:not(.is-error):focus-within .sb-field-box { border-color: var(--blue-01); }
.rm-pick-date .sb-field:not(.is-error):focus-within .sb-label { color: var(--blue-01); }
.rm-pick-date .sb-field-error { grid-column: 1 / -1; max-width: 264px; line-height: 1.4; }
@media (max-width: 767px) {
  .rm-plan { --rm-gutter: 12px; padding-bottom: 12px; }
  body:not([data-mode="map"])[data-mode].rm--picked .rm-plan { display: none; }   /* a phone shows the detail in place of the plan */
  .rm-gantt { --rm-gside: 132px; }
  .rm-glabel .rm-status { display: none; }
}
