/* The management workstation, drawn as a Windows 7 desktop application:
   grey window faces, white panes, the system blue on whatever is selected,
   tabs along the bottom of the docked windows, and nothing that is not there
   to be read or pressed. One set of colours serves every surface. */
:root {
  --face: #f0f0f0;
  --pane: #ffffff;
  --line: #a0a0a0;
  --line-soft: #d5d5d5;
  --line-faint: #ebebeb;
  --frame-line: #c4c4c4;
  --page-line: #898c95;
  --group-line: #d5dfe5;
  --group-ink: #1f4f86;
  --column-head: linear-gradient(#fff, #f1f2f4);
  --zebra: #f4f4f4;
  --select: #3399ff;
  --select-soft: #cce8ff;
  --select-soft-line: #99d1ff;
  --hover: #e5f1fb;
  --hover-line: #7eb4ea;
  --text: #000000;
  --text-dim: #5f5f5f;
  --text-faint: #8a8a8a;
  --caption: linear-gradient(#fbfcfd, #e9eef4);
  --title: linear-gradient(#e4edf8, #cddcee);
  --button: linear-gradient(#fbfbfb, #e3e3e3);
  --button-hover: linear-gradient(#f3f9fe, #d4eafb);
  --button-line: #8c8c8c;
  --button-line-hover: #3c7fb1;
  --button-pressed: #c4e0f8;
  --field-line: #abadb3;
  --disabled-text: #6d6d6d;
  --disabled-fill: #f4f4f4;
  --disabled-line: #d0d0d0;
  --invalid-line: #d05050;
  --invalid-fill: #fff4f4;
  --up: #1340c8;
  --down: #d0191a;
  --warn-text: #8a5a00;
  --warn-fill: #fff8e1;
  --warn-line: #e6cf8e;
  --error-text: #a01010;
  --error-fill: #fdecec;
  --error-line: #e0a0a0;

  font-family: Tahoma, "Segoe UI", Verdana, sans-serif;
  font-size: 11px;
  color: var(--text);
  background: var(--face);
  font-synthesis: none;
}

* { box-sizing: border-box; }
html, body, #app { width: 100%; height: 100%; margin: 0; overflow: hidden; }
button, input, textarea, select { font: inherit; color: inherit; }

/* ---------------------------------------------------------------------------
   The frame. This is a web page, not an emulated desktop: it owns the whole
   viewport and has no title bar of its own. The status bar is the last grid
   row, so it sits on the bottom edge at every window size. Nothing has a
   minimum width: the window is the frame, every region inside it is fixed, and
   only the contents of a list or a page ever scroll.
   ------------------------------------------------------------------------ */
.desktop-app {
  height: 100%;
  display: grid;
  grid-template-rows: 27px minmax(0, 1fr) 22px;
  background: var(--face);
  overflow: hidden;
}
.desktop-app.has-billing-banner {
  grid-template-rows: 27px 24px minmax(0, 1fr) 22px;
}
.billing-banner {
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 0 10px;
  border-bottom: 1px solid var(--warn-line);
  background: var(--warn-fill);
  color: var(--warn-text);
  font-weight: bold;
  white-space: nowrap;
  overflow: hidden;
}
.billing-banner.restricted {
  border-bottom-color: var(--error-line);
  background: var(--error-fill);
  color: var(--error-text);
}
.billing-banner-text { overflow: hidden; text-overflow: ellipsis; }
.billing-banner-link { color: inherit; text-decoration: underline; flex: 0 0 auto; }

/* Which workspace is on screen. The two are one application, so they are
   tabs on its top edge rather than two windows. */
.top-tabs { display: flex; align-items: flex-end; gap: 2px; padding: 3px 6px 0; background: var(--face); border-bottom: 1px solid var(--line); overflow: hidden; }
.top-tabs > button:not(.logout) { height: 23px; min-width: 112px; display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 0 12px; border: 1px solid var(--line); border-bottom: 0; border-radius: 3px 3px 0 0; background: linear-gradient(#f6f6f6, #e2e2e2); color: var(--text-dim); }
.top-tabs > button:not(.logout):hover { background: linear-gradient(#f5fafe, #dcecfa); color: var(--text); }
.top-tabs > button.active { height: 24px; margin-bottom: -1px; background: var(--face); color: var(--text); font-weight: bold; }
.top-tabs .operator { margin: 0 10px 6px auto; color: var(--text-dim); }
.top-tabs button.logout { height: 21px; min-width: 84px; margin-bottom: 3px; padding: 0 10px; border: 1px solid var(--button-line); border-radius: 3px; background: var(--button); }
.top-tabs button.logout:hover { border-color: var(--hover-line); background: var(--button-hover); }

.workspace { position: relative; min-width: 0; min-height: 0; display: grid; grid-template-rows: 21px 32px minmax(0, 1fr); overflow: hidden; }

/* ---------------------------------------------------------------------------
   Menus
   ------------------------------------------------------------------------ */
.classic-menu { display: flex; align-items: stretch; padding: 0 2px; background: var(--face); }
.menu-root { position: relative; display: flex; }
.menu-root > button { border: 1px solid transparent; background: transparent; padding: 0 8px; margin: 1px 0; }
.menu-root > button:hover, .menu-root > button.open { border-color: var(--hover-line); background: var(--hover); }
.menu-drop, .context-menu { margin: 0; padding: 2px; list-style: none; border: 1px solid #979797; background: #f5f5f5 linear-gradient(90deg, #f1f1f1 26px, #e2e3e3 26px, #e2e3e3 27px, #fff 27px, #fff 28px, #f5f5f5 28px); box-shadow: 2px 2px 4px rgba(0, 0, 0, .25); }
.menu-drop { position: absolute; z-index: 45; top: 20px; left: 0; min-width: 220px; }
.context-menu { position: fixed; z-index: 40; min-width: 200px; max-height: 100vh; overflow-y: auto; }
.menu-drop li button, .context-menu li button { width: 100%; height: 22px; display: flex; align-items: center; border: 1px solid transparent; border-radius: 3px; background: transparent; padding: 0 16px 0 0; text-align: left; white-space: nowrap; }
.menu-drop li button:hover:not(:disabled), .context-menu li button:hover:not(:disabled) { border-color: #aeccf1; background: linear-gradient(#f2f7fd, #dcebfc); }
.menu-drop li button:disabled, .context-menu li button:disabled { color: var(--text-faint); }
.menu-drop li button:disabled svg, .context-menu li button:disabled svg { opacity: .45; }
.menu-gutter { width: 22px; height: 20px; flex: 0 0 22px; display: grid; place-items: center; margin-right: 10px; border: 1px solid transparent; border-radius: 2px; }
.menu-gutter.checked { border-color: #a8c8ec; background: #e0edfb; }
.context-separator { height: 1px; margin: 3px 2px 3px 30px; background: #e0e0e0; }

/* ---------------------------------------------------------------------------
   The toolbar: icon and label, flat until pointed at, grouped by hairlines.
   ------------------------------------------------------------------------ */
.toolbar { display: flex; align-items: center; gap: 1px; padding: 2px 4px; background: linear-gradient(#fafafa, #ebebeb); border-top: 1px solid #fff; border-bottom: 1px solid var(--line-soft); overflow: hidden; }
.tool-button { height: 26px; display: flex; align-items: center; gap: 4px; flex: 0 0 auto; border: 1px solid transparent; border-radius: 3px; background: transparent; padding: 0 7px 0 5px; white-space: nowrap; }
.tool-button:hover:not(:disabled) { border-color: var(--hover-line); background: var(--button-hover); }
.tool-button:active:not(:disabled) { background: var(--button-pressed); }
.tool-button:disabled { color: var(--text-faint); }
.tool-button:disabled svg { opacity: .4; filter: grayscale(.6); }
.tool-separator { width: 1px; height: 20px; flex: 0 0 1px; margin: 0 4px; background: var(--line-soft); box-shadow: 1px 0 #fff; }
.tool-icon { width: 18px; height: 18px; display: grid; place-items: center; }
/* Every icon slot is a grid cell holding one duotone SVG, so the glyph never
   shifts a row's height the way a text glyph did. */
.pane-icon, .tab-icon, .row-icon, .request-icon { display: grid; place-items: center; }

/* The way the desk trades is the first thing on the Manager toolbar and the
   loudest: each half wears its own palette colour when it is the one in force,
   tinted rather than filled so its icon stays visible. */
.trade-mode-switch { display: flex; flex: 0 0 auto; margin-right: 6px; border: 1px solid var(--button-line); border-radius: 3px; overflow: hidden; background: var(--pane); }
.trade-mode { display: flex; align-items: center; gap: 5px; height: 24px; padding: 0 10px 0 7px; border: 0; background: transparent; color: var(--text-dim); font-weight: bold; white-space: nowrap; }
.trade-mode + .trade-mode { border-left: 1px solid var(--button-line); }
.trade-mode:hover:not(:disabled):not(.active) { background: var(--hover); }
.trade-mode:disabled { opacity: .45; }
/* Each way is one palette, worn by its half of the switch and by the ticket
   and the receipt that trade that way. */
.trade-mode.client, .trade-page.as-client, .trade-receipt.as-client { --mode: #0e8a17; --mode-fill: #e2f4e3; --mode-line: #9fd3a4; --mode-text: #0b7413; }
.trade-mode.manager, .trade-page.as-manager, .trade-receipt.as-manager { --mode: #cc5500; --mode-fill: #fcebdf; --mode-line: #ecb48e; --mode-text: #b34a00; }
.trade-mode.active { background: var(--mode-fill); color: var(--mode-text); box-shadow: inset 0 -2px var(--mode); }

/* The find box on the toolbar: a login, a name or an order. */
.find-box { display: flex; align-items: center; gap: 4px; margin-left: auto; padding-left: 8px; }
.find-box input { width: 190px; height: 22px; padding: 0 5px; }
.find-box.missed input { border-color: var(--invalid-line); background: var(--invalid-fill); }

/* ---------------------------------------------------------------------------
   Docked windows
   ------------------------------------------------------------------------ */
.pane { border: 1px solid var(--line); background: var(--pane); min-width: 0; min-height: 0; overflow: hidden; }
.pane-title { height: 20px; display: flex; align-items: center; gap: 5px; padding: 0 6px; background: var(--caption); border-bottom: 1px solid var(--line-soft); white-space: nowrap; overflow: hidden; }
.danger-title { color: #8e1515; }

/* A window's tabs along its bottom edge: the one on top is white and joined
   to the page above it, the others are words on the window face. */
.bottom-tabs { height: 22px; display: flex; align-items: flex-start; gap: 0; padding: 0 3px; background: var(--face); border-top: 1px solid var(--line); overflow: hidden; }
.bottom-tabs button { height: 20px; display: inline-flex; align-items: center; gap: 5px; margin-top: -1px; padding: 0 10px; border: 1px solid transparent; border-top: 0; border-radius: 0 0 3px 3px; background: transparent; color: var(--text-dim); white-space: nowrap; }
.bottom-tabs button:hover:not(.active) { color: var(--text); background: var(--hover); }
.bottom-tabs button.active { height: 21px; border-color: var(--line); background: var(--pane); color: var(--text); }
.tab-page { min-width: 0; min-height: 0; overflow: hidden; display: grid; }
.tab-page > * { min-width: 0; min-height: 0; }

/* ---------------------------------------------------------------------------
   Administrator: the navigator and the section panel
   ------------------------------------------------------------------------ */
/* The navigator lists a fixed set of sections, so its column is sized to the
   longest label and never scrolls: a second scrollbar beside the one that
   matters is noise. */
.admin-body { display: grid; grid-template-columns: 178px minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); gap: 3px; padding: 3px; min-height: 0; overflow: hidden; }
.navigator { display: grid; grid-template-rows: 20px minmax(0, 1fr); }
.tree { padding: 4px 0 8px 4px; overflow: hidden; }
.tree-root, .tree-item { width: calc(100% - 4px); display: flex; align-items: center; gap: 6px; border: 1px solid transparent; border-radius: 2px; background: transparent; text-align: left; white-space: nowrap; overflow: hidden; }
.tree-root { height: 22px; padding: 0 4px; font-weight: bold; }
.tree-item { position: relative; height: 21px; padding: 0 4px 0 6px; }
.tree-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.tree-root:hover, .tree-item:hover { border-color: #bcdcf4; background: var(--hover); }
.tree-root.selected, .tree-item.selected { border-color: var(--select-soft-line); background: var(--select-soft); }
/* The dotted connectors of a Windows tree: one line down the branch, a tick
   to each section. */
.tree-branch { position: relative; margin-left: 12px; padding-left: 12px; }
.tree-branch::before { content: ""; position: absolute; left: 0; top: 0; bottom: 11px; border-left: 1px dotted var(--line); }
.tree-item::before { content: ""; position: absolute; left: -12px; top: 10px; width: 10px; border-top: 1px dotted var(--line); }
.tree-icon { width: 16px; height: 16px; flex: 0 0 16px; display: grid; place-items: center; }

/* The one scrollable region in the workspace. Its title stays put and its
   content row is what scrolls, so a wide list is reachable without the
   window frame moving. */
.admin-main { display: grid; grid-template-rows: 20px minmax(0, 1fr); min-width: 0; min-height: 0; }
.admin-main.with-request { grid-template-rows: 20px minmax(0, 1fr) auto; }
.admin-main > :not(.pane-title):not(.request-panel) { min-width: 0; min-height: 0; overflow: auto; }

/* The server node lists what each section administers, in a read-only
   table. */
.server-overview { overflow: auto; }
.list-table .number { width: 70px; }
.list-table td:first-child { width: 200px; }
.list-table td:first-child .row-icon { display: inline-grid; vertical-align: -3px; margin-right: 6px; }
.overview-row { cursor: default; }
.overview-row:hover { background: var(--hover) !important; }

/* The server settings: one property a line, under the subject it belongs to. */
.property-layout { overflow: auto; padding: 10px; }
.property-grid { max-width: 780px; border: 1px solid var(--frame-line); }
.property-head, .property-row { display: grid; grid-template-columns: 240px minmax(0, 1fr); }
.property-head span { height: 22px; display: flex; align-items: center; padding: 0 6px; background: var(--column-head); border-bottom: 1px solid var(--frame-line); }
.property-head span + span { border-left: 1px solid var(--line-soft); }
.property-group { height: 20px; display: flex; align-items: center; padding: 0 6px; font-weight: bold; color: var(--group-ink); background: #eef3f9; border-bottom: 1px solid var(--line-faint); }
.property-row { min-height: 20px; border-bottom: 1px solid var(--line-faint); }
.property-row:hover { background: var(--hover); }
.property-name { padding: 3px 6px 3px 18px; border-right: 1px solid var(--line-faint); color: var(--text-dim); }
.property-value { padding: 3px 6px; overflow-wrap: anywhere; }
.property-actions { display: flex; gap: 6px; margin-top: 10px; }

/* ---------------------------------------------------------------------------
   The request row under a list that grows without bound: one line.
   Its answer is frozen, so this row is the only thing that changes what the
   list above it shows.
   ------------------------------------------------------------------------ */
.request-panel { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; min-height: 30px; padding: 3px 6px; border-top: 1px solid var(--line-soft); background: var(--face); }
.request-field { display: flex; align-items: center; gap: 5px; white-space: nowrap; }
.request-field > span { color: var(--text-dim); }
.request-field.wide input { width: 220px; }
.request-field.short input { width: 64px; }
.request-field input.timestamp-input.minutes { width: 124px; }
.request-field.check { flex-direction: row-reverse; }
.request-field small { color: var(--text-dim); }
.request-state { margin-left: auto; color: var(--text-dim); white-space: nowrap; }
.request-state.failed { color: var(--error-text); white-space: normal; max-width: 420px; }
.request-panel > button { min-width: 88px; }

/* The Manager's journal row shares its window with the tab strip's count, so
   its boxes are narrower and it says nothing the tab already says. */
.request-panel.compact { gap: 4px 9px; }
.request-panel.compact .request-field.wide input { width: 140px; }
.request-panel.compact .request-field select { max-width: 112px; }
.request-panel.compact .request-field input.timestamp-input.minutes { width: 114px; }

/* ---------------------------------------------------------------------------
   Lists
   ------------------------------------------------------------------------ */
.grid-frame { position: relative; width: 100%; height: 100%; min-height: 0; }
/* A list's empty message fills what holds it; over a grid it lies on the
   rows, below the grid's 22 px heading. */
.empty-grid { display: grid; place-items: center; height: 100%; padding: 12px; color: var(--text-faint); text-align: center; pointer-events: none; }
.grid-frame > .empty-grid { position: absolute; inset: 22px 0 0; height: auto; }
.ag-header { background: var(--column-head) !important; }
.ag-header-cell-label { gap: 3px; }
.ag-cell { font-variant-numeric: tabular-nums; }
.ag-row-selected { color: #fff; }
.ag-row-selected .ag-cell svg { filter: drop-shadow(0 0 1px rgba(255, 255, 255, .9)); }
.ag-row-selected:hover::before { background-color: var(--select) !important; }
.cell-center, .header-center .ag-header-cell-label { justify-content: center; text-align: center; }
.cell-center { display: flex; align-items: center; }
/* A boolean cell is its flag icon; sit it on the text baseline the row uses. */
.ag-cell svg { vertical-align: text-bottom; }
.lead-cell { display: flex; align-items: center; gap: 5px; min-width: 0; }
.lead-cell .row-icon { flex: 0 0 14px; }
.bar-cell { position: relative; display: block; height: 100%; }
.bar-cell::before { content: ""; position: absolute; left: 50%; top: 2px; bottom: 2px; border-left: 1px solid #c8c8c8; }
.bar-cell .bar { position: absolute; top: 5px; bottom: 5px; }
.bar-cell .bar.long { background: #5276d6; }
.bar-cell .bar.short { background: #d65a5a; }

/* A read-only table inside a property sheet. */
.read-only-table-wrap { min-width: 0; overflow: auto; border: 1px solid var(--frame-line); background: var(--pane); }
.read-only-table { width: 100%; border-collapse: collapse; white-space: nowrap; }
.read-only-table th, .nested-table th { height: 22px; padding: 0 6px; text-align: left; font-weight: normal; background: var(--column-head); border-right: 1px solid var(--line-soft); border-bottom: 1px solid var(--frame-line); }
.read-only-table td { height: 20px; padding: 0 6px; font-variant-numeric: tabular-nums; }
.read-only-table tbody tr:nth-child(even) { background: var(--zebra); }
.read-only-table .number { text-align: right; }
.read-only-table .empty-table { height: 80px; color: var(--text-faint); text-align: center; }
.read-only-table tr.summary-row td { background: #e8e8e8; font-weight: bold; }
/* A table whose rows are chosen by a click: the row under the pointer lit,
   the chosen one in the system blue. */
:is(.rule-table, .week-table, .close-by-list, .trade-list) tbody tr:not(.summary-row) { cursor: default; }
:is(.rule-table, .week-table, .close-by-list, .trade-list) tbody tr:not(.summary-row):not(.selected):hover td { background: var(--hover); }
:is(.rule-table, .week-table, .close-by-list, .trade-list) tbody tr.selected td { color: #fff; background: var(--select); }

/* ---------------------------------------------------------------------------
   Manager: Market Watch, the list windows, Margin Calls and the Toolbox
   ------------------------------------------------------------------------ */
.manager-body { --market-watch: 252px; display: grid; grid-template-columns: var(--market-watch) minmax(0, 1fr) 300px; grid-template-rows: minmax(0, 64%) minmax(0, 36%); gap: 3px; padding: 3px; min-height: 0; }
/* Market Watch's Spread and Time columns widen the window by what they take,
   so an instrument's name keeps the 96 px it has beside Bid and Ask alone
   (at least 84 px on a laptop's screen) rather than being squeezed out of its
   row. */
.manager-body.quotes-with-spread { --market-watch: 282px; }
.manager-body.quotes-with-time { --market-watch: 306px; }
.manager-body.quotes-with-spread.quotes-with-time { --market-watch: 338px; }
/* The View menu switches the service windows off. */
.manager-body.no-market-watch { grid-template-columns: minmax(0, 1fr) 300px; }
.manager-body.no-margin-calls { grid-template-columns: var(--market-watch) minmax(0, 1fr); }
.manager-body.no-market-watch.no-margin-calls { grid-template-columns: minmax(0, 1fr); }
.manager-body.no-toolbox { grid-template-rows: minmax(0, 1fr); }
.manager-body.no-market-watch .risk-toolbox { grid-column: 1 / 3; }
.manager-body.no-margin-calls .risk-toolbox { grid-column: 2 / 3; }
.manager-body.no-market-watch.no-margin-calls .risk-toolbox { grid-column: 1 / 2; }
.manager-center { display: grid; grid-template-rows: minmax(0, 1fr) 22px; }
.margin-calls { display: grid; grid-template-rows: 20px minmax(0, 1fr); }
.risk-toolbox { grid-column: 2 / 4; display: grid; grid-template-rows: minmax(0, 1fr) 22px; }
/* Requests is two lists, one over the other: what waits, and what routing did. */
.split-lists { display: grid; grid-template-rows: minmax(0, 2fr) minmax(0, 3fr); }
.split-list { display: grid; grid-template-rows: 20px minmax(0, 1fr); min-height: 0; }
.split-list + .split-list { border-top: 1px solid var(--line); }
.list-caption { display: flex; align-items: center; gap: 5px; padding: 0 6px; background: var(--caption); border-bottom: 1px solid var(--line-soft); }
.list-with-request { display: grid; grid-template-rows: minmax(0, 1fr) auto; }

/* Market Watch runs the body's full height, beside one row or two: line -1
   ends the last row the body declares, where line 3 would add an empty row
   below the windows once the Toolbox is off. */
.market-watch { grid-row: 1 / -1; display: grid; grid-template-rows: 20px minmax(0, 1fr) 22px; }
.quote-table { display: grid; grid-template-rows: 22px minmax(0, 1fr); min-height: 0; }
.quote-head, .quote-row { display: grid; grid-template-columns: minmax(0, 1fr) 72px 72px; align-items: center; }
.quote-head.with-spread, .quote-row.with-spread { grid-template-columns: minmax(0, 1fr) 66px 66px 42px; }
.quote-head.with-time, .quote-row.with-time { grid-template-columns: minmax(0, 1fr) 62px 62px 74px; }
.quote-head.with-spread.with-time, .quote-row.with-spread.with-time { grid-template-columns: minmax(0, 1fr) 58px 58px 42px 72px; }
/* Only the rows scroll, and a classic scrollbar takes its width from them
   alone: the head keeps the same gutter, so every heading stands over its
   column. */
.quote-head { padding: 0 6px 0 4px; background: var(--column-head); border-bottom: 1px solid var(--frame-line); overflow: hidden; scrollbar-gutter: stable; }
.quote-head span { height: 22px; display: flex; align-items: center; }
.quote-head span:not(:first-child) { justify-content: flex-end; }
.quote-list { overflow: auto; min-height: 0; scrollbar-gutter: stable; }
.quote-row { height: 20px; padding: 0 6px 0 4px; cursor: default; font-variant-numeric: tabular-nums; }
.quote-row:nth-child(even) { background: var(--zebra); }
.quote-row:hover { background: var(--hover); }
.quote-row > span { text-align: right; overflow: hidden; white-space: nowrap; }
.quote-row .quote-symbol { display: flex; align-items: center; gap: 4px; text-align: left; font-weight: bold; }
.quote-row .row-icon { width: 13px; height: 13px; flex: 0 0 13px; }
.quote-row .bid, .quote-row .ask { color: #303030; }
.quote-row.up .bid, .quote-row.up .ask { color: var(--up); }
.quote-row.down .bid, .quote-row.down .ask { color: var(--down); }
.quote-row.unquoted .quote-symbol { color: var(--text-faint); }
.quote-row.selected, .quote-row.selected:hover { color: #fff; background: var(--select); }
.quote-row.selected .bid, .quote-row.selected .ask, .quote-row.selected .quote-symbol { color: #fff; }
.spread, .quote-time { color: var(--text-dim); }
.tick-chart { display: grid; grid-template-rows: 20px minmax(0, 1fr); min-height: 0; background: var(--pane); }
.tick-chart-symbol { display: flex; align-items: center; padding: 0 6px; font-weight: bold; }
.tick-chart-plot { min-height: 0; overflow: hidden; }
/* uPlot's own layout rules, which the tick chart needs and its package ships
   only as a stylesheet: the plot, its overlay and its axes are positioned
   inside one wrapper. */
.tick-chart .uplot { width: min-content; font: 10px Tahoma, sans-serif; line-height: 1.5; }
.tick-chart .u-wrap { position: relative; user-select: none; }
.tick-chart .u-over, .tick-chart .u-under, .tick-chart .u-axis { position: absolute; }
.tick-chart .u-under { overflow: hidden; }
.tick-chart .uplot canvas { display: block; position: relative; width: 100%; height: 100%; }
.tick-chart .u-axis.u-off, .tick-chart .u-select.u-off { display: none; }
/* ---------------------------------------------------------------------------
   Executions: the story, its prices, and the minute of the market around it
   ------------------------------------------------------------------------ */
.execution-summary { display: grid; gap: 12px; align-content: start; }
/* How it ended, in one line, in the colours a state has everywhere else. */
.execution-headline { display: flex; align-items: baseline; gap: 10px; padding: 6px 10px; border: 1px solid var(--line-soft); border-left-width: 4px; background: var(--face); }
.execution-headline .headline-text { font-size: 13px; font-weight: bold; }
.execution-headline.executed { border-left-color: #0e8a17; }
.execution-headline.executed .headline-text { color: #0b7413; }
.execution-headline.rejected { border-left-color: var(--down); background: var(--error-fill); }
.execution-headline.rejected .headline-text { color: var(--error-text); }
.execution-headline.waiting { border-left-color: #cc5500; background: var(--warn-fill); }
.execution-headline.waiting .headline-text { color: var(--warn-text); }
.execution-headline.canceled { border-left-color: var(--text-faint); }
/* The timeline: each moment a dot on one line, the time between two written
   above the stretch that joins them. */
.execution-timeline { display: flex; align-items: flex-start; margin: 0; padding: 18px 8px 2px; list-style: none; overflow-x: auto; }
.timeline-moment { position: relative; flex: 1 1 0; min-width: 190px; display: grid; justify-items: start; gap: 1px; padding-top: 16px; }
.timeline-moment:last-child { flex: 0 0 auto; min-width: 170px; }
.timeline-moment::before { content: ""; position: absolute; left: 0; right: 0; top: 5px; height: 2px; background: var(--page-line); }
.timeline-moment:last-child::before { right: auto; width: 0; }
.timeline-dot { position: absolute; left: 0; top: 0; width: 12px; height: 12px; box-sizing: border-box; border-radius: 50%; background: var(--pane); border: 3px solid #444; }
.timeline-moment:last-child .timeline-dot { background: #444; }
.timeline-label { font-weight: bold; }
.timeline-time { font-family: Consolas, "Courier New", monospace; font-variant-numeric: tabular-nums; }
.timeline-note { color: var(--text-dim); }
.timeline-elapsed { position: absolute; left: 18px; right: 6px; top: -9px; text-align: center; color: var(--text-dim); font-family: Consolas, "Courier New", monospace; font-size: 11px; }
/* The prices it is judged by. */
.execution-figures { display: flex; flex-wrap: wrap; gap: 10px 26px; }
.execution-figure { display: grid; gap: 1px; min-width: 120px; padding-left: 8px; border-left: 3px solid var(--line-soft); }
.figure-label { color: var(--text-dim); }
.figure-value { font-family: Consolas, "Courier New", monospace; font-size: 17px; font-variant-numeric: tabular-nums; }
.figure-detail { color: var(--text-dim); max-width: 280px; }
.execution-figure.favour { border-left-color: #0e8a17; }
.execution-figure.favour .figure-value { color: #0b7413; }
.execution-figure.against { border-left-color: var(--down); }
.execution-figure.against .figure-value { color: var(--down); }
.execution-quotes { width: auto; min-width: 420px; }
.execution-quotes td, .execution-quotes th { padding-right: 18px; }
.execution-words { margin: 0; display: grid; grid-template-columns: 130px minmax(0, 1fr); gap: 8px; }
.execution-words .words-label { color: var(--text-dim); }
.execution-links, .execution-open { margin: 10px 0 0; display: flex; flex-wrap: wrap; gap: 6px; }
.execution-links .link-button { min-width: 0; }
.execution-open button { display: inline-flex; align-items: center; gap: 6px; }
.execution-facts { display: grid; grid-template-columns: 150px minmax(0, 1fr); gap: 6px 14px; margin: 0; }
.execution-facts dt { color: var(--text-dim); text-align: right; }
.execution-facts dd { margin: 0; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.execution-none { margin: 6px 0; color: var(--text-dim); }
.execution-chart-caption { margin-bottom: 6px; color: var(--text-dim); }
.execution-chart-page .execution-chart { grid-template-rows: minmax(0, 1fr); height: 370px; border: 1px solid var(--frame-line); }
.execution-chart .u-legend { padding: 3px 6px; font: 10px Tahoma, sans-serif; text-align: left; }
.execution-chart .u-legend .u-series { display: inline-block; margin-right: 12px; }
.execution-chart .u-legend .u-marker { display: inline-block; width: 12px; height: 3px; margin-right: 4px; vertical-align: middle; }
.execution-chart .u-legend th { font-weight: normal; }
.execution-chart .u-legend th > * { display: inline-block; vertical-align: middle; }
.execution-chart .u-legend td { display: inline-block; min-width: 54px; font-variant-numeric: tabular-nums; }
.execution-chart .u-cursor-x, .execution-chart .u-cursor-y { position: absolute; left: 0; top: 0; pointer-events: none; will-change: transform; }
.execution-chart .u-cursor-pt { position: absolute; top: 0; left: 0; border-radius: 50%; pointer-events: none; will-change: transform; }
.execution-chart .u-select { position: absolute; pointer-events: none; }
.execution-chart .u-hz .u-cursor-x, .execution-chart .u-cursor-y { border-bottom: 1px dashed #999; }
.execution-chart .u-cursor-x { border-right: 1px dashed #999; }
.execution-chart .u-cursor-y { border-bottom: 1px dashed #999; }
.execution-chart .u-legend.u-live th::after { content: ""; }
/* An execution in a small grid: a state in the colour it has elsewhere. */
.execution-list { max-height: 330px; }
.execution-list tbody tr.execution-row { cursor: default; }
.execution-list tbody tr.execution-row:not(.selected):hover td { background: var(--hover); }
.execution-list tbody tr.execution-row.selected td { color: #fff; background: var(--select); }
.execution-list tbody tr.execution-row.rejected:not(.selected) td:nth-child(4) { color: var(--down); }
.execution-list tbody tr.execution-row.waiting:not(.selected) td:nth-child(4) { color: var(--warn-text); }
.execution-list tbody tr.execution-row.executed:not(.selected) td:nth-child(4) { color: #0b7413; }
.execution-list tbody tr:focus-visible { outline: 1px dotted #000; outline-offset: -2px; }
.entity-editor.editor-execution { width: min(920px, calc(100vw - 44px)); }
.entity-editor.editor-execution:not(.single-page) .editor-page { min-height: min(470px, calc(100vh - 190px)); }

.symbols-window { width: min(640px, 92vw); max-height: 84vh; display: grid; grid-template-rows: 26px auto minmax(0, 1fr) auto; }
.symbols-body { display: grid; gap: 8px; }
.symbol-group { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
.symbol-group .symbol-name { min-width: 64px; font-weight: bold; }
.symbol-group .symbol-description { color: var(--text-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------------------------------------------------------------------------
   The status bar
   ------------------------------------------------------------------------ */
.statusbar { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 130px) minmax(0, 170px) minmax(0, 190px); align-items: center; padding: 0 2px; background: var(--face); border-top: 1px solid var(--line-soft); }
.statusbar span { padding: 0 8px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.statusbar span + span { border-left: 1px solid var(--line-soft); }
.statusbar .load-error { color: var(--error-text); }
.statusbar .zone-fallback { color: var(--warn-text); }
/* The connection's lamp, in its state's colour. */
.connection::before { content: ""; display: inline-block; width: 7px; height: 7px; margin-right: 5px; border-radius: 50%; background: currentColor; vertical-align: 1px; }
.connection.online { color: #087d19; }
.connection.offline { color: #a21a1a; }
.connection.connecting, .connection.waiting { color: #8a6d00; }

/* ---------------------------------------------------------------------------
   Windows: login, dialogs, property sheets
   ------------------------------------------------------------------------ */
.login-desktop, .boot-screen { width: 100%; height: 100%; display: grid; place-items: center; background: linear-gradient(160deg, #2c6aa8, #154c80 70%); }
.boot-screen { color: #fff; font-size: 13px; }
.window { border: 1px solid #707070; border-radius: 4px 4px 0 0; background: var(--face); box-shadow: 0 6px 24px rgba(0, 20, 50, .35); overflow: hidden; }
.window-title { height: 26px; display: flex; align-items: center; gap: 6px; padding: 0 4px 0 9px; color: #1a1a1a; font-size: 12px; background: var(--title); border-bottom: 1px solid #a9b8cc; }
.window-title span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.window-title button { width: 28px; min-width: 0; height: 18px; flex: 0 0 28px; margin-left: auto; padding: 0; border: 1px solid #8f9fb3; border-radius: 3px; background: linear-gradient(#fbfbfb, #dfe5ec); line-height: 14px; font-size: 13px; }
.window-title button:hover:not(:disabled) { color: #fff; border-color: #8a1b1b; background: linear-gradient(#e88a7d, #c42b1c); }
.window-title button:hover:not(:disabled) svg { fill: #fff; }
.window-title button > svg, button.spin > svg, button.row-remove > svg, button.receipt-dismiss > svg { display: block; margin: 0 auto; }

.login-window { width: 380px; display: grid; grid-template-columns: 84px 1fr; gap: 10px 4px; padding-bottom: 14px; }
.login-window .window-title { grid-column: 1 / 3; }
.login-logo { grid-row: 2 / 5; width: 52px; height: 52px; justify-self: center; margin-top: 4px; display: grid; place-items: center; color: #fff; font-size: 28px; font-weight: bold; border-radius: 6px; background: linear-gradient(135deg, #3b86d6, #154c80); box-shadow: inset 0 1px rgba(255, 255, 255, .4); }
.login-intro { grid-column: 2; margin: 2px 14px 2px 0; color: var(--text-dim); line-height: 15px; }
.login-connection { grid-column: 2; margin: 0 14px 2px 0; }
.login-window label { display: grid; grid-template-columns: 62px 1fr; gap: 6px; align-items: center; margin-right: 14px; grid-column: 2; }
.login-window label > span { text-align: right; }
.login-window input { height: 22px; padding: 0 5px; }
.login-window .error-strip, .login-window .notice-strip, .login-window .dialog-buttons { grid-column: 1 / 3; margin: 0 14px; }

/* Buttons, everywhere a window or a row of controls has them. The selectors
   carry no weight of their own (:where), so a button's own class — the title
   bar's close box, a tab, Deposit and Withdrawal — always says the last word. */
:where(.window, .property-actions, .request-panel) button:where(:not(.trade-mode):not(.tab)) {
  height: 23px; min-width: 75px; padding: 0 10px;
  border: 1px solid var(--button-line); border-radius: 3px; background: var(--button);
}
:where(.window, .property-actions, .request-panel) button:where(:not(.trade-mode):not(.tab)):hover:not(:disabled) { border-color: var(--button-line-hover); background: var(--button-hover); }
:where(.window, .property-actions, .request-panel) button:where(:not(.trade-mode):not(.tab)):active:not(:disabled) { background: var(--button-pressed); }
:where(.window, .property-actions, .request-panel) button:where(:not(.trade-mode):not(.tab)):disabled { color: var(--text-faint); border-color: var(--frame-line); background: var(--disabled-fill); }
.default-button { border-color: var(--button-line-hover) !important; box-shadow: inset 0 0 0 1px #9ccbf0; }
/* A box to type in or choose from, wherever a window or a row of controls has
   one: one look, focused and disabled alike, and one checkbox. These carry no
   weight of their own either, so a box's own size — the login's and the find
   box's taller one, a spinner's, a clock's — says the last word. */
:where(.window, .request-panel, .find-box) :where(input:not([type="checkbox"]), select, textarea) {
  height: 21px; padding: 0 4px;
  border: 1px solid var(--field-line); border-radius: 0; color: var(--text); background: var(--pane);
}
:where(.window, .request-panel, .find-box) :where(input:not([type="checkbox"]), select, textarea):focus { outline: 0; border-color: var(--select); }
:where(.window, .request-panel, .find-box) :where(input:not([type="checkbox"]), select, textarea):disabled { color: var(--disabled-text); background: var(--disabled-fill); border-color: var(--disabled-line); }
:where(.window) input[type="checkbox"] { width: 13px; height: 13px; margin: 0; accent-color: #2f7fd1; }

.error-strip { padding: 5px 8px; color: var(--error-text); background: var(--error-fill); border: 1px solid var(--error-line); }
.notice-strip { padding: 5px 8px; color: var(--warn-text); background: var(--warn-fill); border: 1px solid var(--warn-line); }
.dialog-buttons { display: flex; justify-content: flex-end; align-items: center; gap: 7px; padding-top: 6px; }
.dialog-buttons .button-gap { flex: 1; }

/* A window opens high in the screen and stays where it opened: whatever grows
   inside it grows downwards, so nothing moves out from under the pointer. */
.modal-shade { position: fixed; z-index: 20; inset: 0; display: grid; place-items: start center; padding-top: max(20px, 7vh); background: rgba(20, 35, 55, .28); }

/*
 * Property sheets.
 *
 * A record is edited in a modal property sheet rather than inline: a title
 * naming the record, tabs, a white page per tab
 * opening with its subject's picture and what the page is for, labels
 * right-aligned against their boxes, and OK / Cancel at the foot.
 */
.entity-editor {
  width: min(860px, calc(100vw - 44px));
  max-height: calc(100vh - max(20px, 7vh) - 12px);
  display: grid;
  grid-template-rows: 26px auto minmax(200px, 1fr) auto;
}
.entity-editor.single-page { grid-template-rows: 26px minmax(160px, 1fr) auto; }
/* A property sheet keeps one size across its pages, as a Windows property
   sheet does, so changing tabs never moves OK and Cancel. */
.entity-editor:not(.single-page) .editor-page { min-height: min(340px, calc(100vh - 190px)); }

/* A window with a field or two is as narrow as a small dialog, its fields in
   one column. */
.entity-editor.editor-password, .entity-editor.editor-security { width: min(540px, calc(100vw - 44px)); }
.editor-password .form-grid, .editor-security .form-grid { grid-template-columns: minmax(0, 1fr); }
.entity-editor.editor-tick { width: min(680px, calc(100vw - 44px)); }
.quote-nudge { display: flex; gap: 6px; }
.quote-nudge button { min-width: 70px !important; }

/* A holiday's date reads across one line, year, month and day. */
.editor-holiday .field-group .form-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.editor-holiday .field-group .form-field { grid-template-columns: 50px minmax(0, 1fr); }

/* A property sheet's tabs: Windows 7 notebook tabs, the open one white and
   joined to its page, the others a step lower behind it. */
.editor-tabs { min-width: 0; display: flex; align-items: flex-end; gap: 0; padding: 6px 8px 0 10px; overflow: hidden; background: var(--face); }
.editor-tabs button.tab { position: relative; flex: 0 0 auto; height: 20px; margin: 0 -1px -1px 0; padding: 0 9px; border: 1px solid var(--page-line); border-radius: 2px 2px 0 0; background: linear-gradient(#f4f4f4, #e1e1e1); }
.editor-tabs button.tab:hover:not(.active) { background: linear-gradient(#f3f9fe, #d6ebfb); }
.editor-tabs button.tab.active { z-index: 1; height: 23px; margin-left: -2px; margin-right: -3px; padding: 0 11px; border-bottom-color: var(--pane); background: var(--pane); }

.editor-page { min-height: 0; display: flex; flex-direction: column; margin: 0 8px; border: 1px solid var(--page-line); background: var(--pane); }
.editor-page > .editor-body { flex: 1 1 auto; }
.editor-page > .editor-intro, .editor-page > .editor-hint { flex: 0 0 auto; }
.single-page .editor-page { margin-top: 8px; }
.editor-intro { display: grid; grid-template-columns: 40px minmax(0, 1fr); align-items: center; gap: 12px; padding: 10px 14px 6px; }
.editor-intro p { margin: 0; color: #333; line-height: 15px; }
.intro-icon { width: 40px; height: 40px; display: grid; place-items: center; }
.editor-body { min-height: 0; overflow: auto; padding: 8px 14px 12px; }

/* The fields of a page in two columns, each a right-aligned label against its
   box. A box is as wide as what it holds; the column only bounds it. */
.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); align-content: start; gap: 5px 22px; }
.form-field { min-width: 0; display: grid; grid-template-columns: 138px minmax(0, 1fr); align-items: center; gap: 2px 8px; }
.field-label { line-height: 14px; text-align: right; color: #1a1a1a; }
.form-field.has-help > .field-label, .check-field.has-help .check-label,
.check-group.has-help > legend { cursor: help; }
.form-field.has-help:not(.check-field) > .field-label::after,
.check-field.has-help .check-label::after,
.check-group.has-help > legend::after { content: ""; display: inline-block; width: 4px; height: 4px; margin: 0 0 2px 4px; border-radius: 50%; background: #6d9bd4; vertical-align: middle; }
/* A box of checkboxes reads down its own columns, without a label column. */
.field-group .check-field { grid-template-columns: 0 minmax(0, 1fr); gap: 0 4px; padding-left: 8px; }
.field-control { min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; }
.field-control > input:where(:not([type="checkbox"]):not([type="color"])),
.field-control > select,
.field-control > textarea { flex: 1 1 auto; width: 100%; min-width: 0; }
.field-control > input.size-short, .field-control > select.size-short { flex: 0 0 96px; width: 96px; }
.field-control > input.size-medium, .field-control > select.size-medium { flex: 0 1 180px; width: 180px; }
.field-control > input.timestamp-input { flex: 0 0 160px; width: 160px; }
.field-control > input.timestamp-input.minutes { flex: 0 0 128px; width: 128px; }
.field-control > .static-value { padding: 2px 0; font-variant-numeric: tabular-nums; }
.check-field > .field-control { gap: 6px; }
.check-label { color: #1a1a1a; }
.form-field textarea { min-height: 44px; height: auto; resize: vertical; padding: 3px 4px; }
input.invalid { border-color: var(--invalid-line) !important; background: var(--invalid-fill) !important; }
input::placeholder { color: #a8a8a8; }
.field-wide { grid-column: 1 / -1; }
.field-unit { color: var(--text-dim); white-space: nowrap; }
.field-note { display: block; margin-top: 3px; color: var(--text-dim); line-height: 14px; }
.field-inert { flex: 0 0 auto; padding: 1px 5px; color: var(--warn-text); background: var(--warn-fill); border: 1px solid var(--warn-line); border-radius: 2px; white-space: nowrap; cursor: help; }
.check-group > .field-inert { justify-self: start; grid-column: 1 / -1; }

/* A box of related fields, such as Lots, Commissions or Timeouts, and a box
   of checkboxes. */
.field-group, .check-group { min-width: 0; padding: 6px 10px 9px; border: 1px solid var(--group-line); border-radius: 3px; }
:is(.field-group, .check-group) > legend { padding: 0 4px; color: var(--group-ink); }
.field-group { margin: 4px 0 2px; }

.time-control { display: grid; grid-template-columns: 46px 8px 46px; align-items: center; gap: 2px; justify-content: start; }
.time-control span { text-align: center; font-weight: bold; }
.time-control input { width: 100%; min-width: 0; }
.color-control { display: flex; align-items: center; gap: 7px; }
.color-control input[type="color"] { width: 44px; padding: 1px 2px; }
.color-control span { color: var(--text-dim); }
/* Randomize and copy stands beside its password box, and what came of the copy
   reads on its own line under the box, in the colour the sheets say what an
   operator's input produced. */
.field-control > .field-note { flex: 1 0 100%; margin-top: 0; color: var(--group-ink); }
.field-control > .field-note.refused { color: var(--error-text); }
/* The label stays level with its box, not centred on the box and the line. */
.form-field:has(> .field-control > .field-note) > .field-label { align-self: start; padding-top: 5px; }

/* A client or an account by number: a Windows 7 editable combo box, its drop
   arrow inside the box, which every box's rules draw, and beside it, in the colour of what an
   operator's input produced, who the number names. The list drops from the
   frame, fixed to the window so no page clips it, its numbers in one column
   of figures, so the digits a search typed stand in a bold column down it. */
.field-control:has(> .chooser) { flex-wrap: nowrap; }
.chooser { position: relative; flex: 0 0 120px; display: flex; }
.chooser.size-medium { flex-basis: 180px; }
.window .chooser > input { flex: 1 1 auto; width: 100%; min-width: 0; padding-right: 21px; font-variant-numeric: tabular-nums; }
.window .chooser > button.chooser-arrow { position: absolute; top: 1px; right: 1px; bottom: 1px; width: 17px; min-width: 0; height: auto; padding: 0; border: 0; border-left: 1px solid transparent; border-radius: 0; background: transparent; }
.window .chooser > button.chooser-arrow::before { content: ""; position: absolute; left: 5px; top: 8px; border: 3.5px solid transparent; border-bottom: 0; border-top: 4px solid #3d3d3d; }
.window .chooser > button.chooser-arrow:hover:not(:disabled),
.window .chooser > input[aria-expanded="true"] + button.chooser-arrow { border-left-color: var(--hover-line); background: linear-gradient(#eaf6fd, #d9f0fc); }
.window .chooser > button.chooser-arrow:disabled::before { border-top-color: var(--text-faint); }
.chooser-note { flex: 1 1 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--group-ink); }
.chooser-note.unknown { color: var(--warn-text); }
.chooser-note.refused { color: var(--error-text); }

.chooser-list { position: fixed; z-index: 40; display: flex; flex-direction: column; border: 1px solid #646464; background: var(--pane); box-shadow: 2px 2px 4px rgba(0, 0, 0, .25); }
.chooser-list.above { box-shadow: 2px -1px 4px rgba(0, 0, 0, .2); }
.chooser-list ul { flex: 1 1 auto; min-height: 0; margin: 0; padding: 1px 0; list-style: none; overflow-y: auto; }
.chooser-list li { height: 18px; display: grid; grid-template-columns: 9ch minmax(0, 1fr) minmax(0, 1.25fr); align-items: center; gap: 12px; padding: 0 6px; white-space: nowrap; cursor: default; }
.chooser-list li > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.chooser-id { font-variant-numeric: tabular-nums; }
.chooser-detail { color: var(--text-dim); }
.chooser-list li.last-special { margin-bottom: 1px; box-shadow: 0 1px 0 var(--line-faint); }
.chooser-list li[aria-selected="true"] { color: #fff; background: var(--select); }
.chooser-list li[aria-selected="true"] .chooser-detail { color: #e6f2ff; }
.chooser-list li[aria-disabled="true"], .chooser-list li[aria-disabled="true"] .chooser-detail { color: var(--text-faint); }
.chooser-list li[aria-disabled="true"][aria-selected="true"] { background: var(--line-faint); }
.chooser-foot { flex: 0 0 auto; padding: 3px 6px 4px; color: var(--text-dim); line-height: 14px; background: var(--face); border-top: 1px solid var(--line-faint); }

.check-group { margin: 2px 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px 16px; }
.check-group label { min-width: 0; display: flex; align-items: center; gap: 6px; }

/* The description line at the foot of a page: what the field pointed at does. */
.editor-hint { height: 74px; overflow: auto; padding: 6px 14px 7px; color: #333; line-height: 15px; border-top: 1px solid var(--line-faint); background: #f8f9fb; }
.editor-hint strong { color: #1a1a1a; }
.hint-idle { color: var(--text-faint); }

.nested-table-wrap { min-width: 0; overflow-x: auto; padding-bottom: 2px; }
.nested-table { width: 100%; border-collapse: collapse; table-layout: fixed; background: var(--pane); border: 1px solid var(--frame-line); }
.nested-table th { padding: 0 5px; white-space: nowrap; }
.nested-table th small { color: var(--text-dim); }
.nested-table td { height: 24px; padding: 1px 2px; border-right: 1px solid var(--line-faint); border-bottom: 1px solid var(--line-faint); }
.nested-table input:not([type="checkbox"]), .nested-table select { width: 100%; min-width: 0; }
/* The row buttons stay in view while a wide rule table scrolls under them. */
.nested-table td:last-child, .nested-table th:last-child { width: 82px; text-align: center; white-space: nowrap; position: sticky; right: 0; background: var(--pane); box-shadow: -1px 0 0 var(--line-soft); }
.nested-table td:last-child button, .session-row button.row-remove { width: 22px; min-width: 0; height: 19px; padding: 0; vertical-align: middle; }
.nested-table td:last-child button + button { margin-left: 2px; }
.nested-table td:last-child button svg { display: block; margin: auto; }
.nested-table td:last-child button:disabled svg { opacity: .35; }
button.row-remove { color: #8d1515; font-size: 13px; }
.add-button { display: inline-flex; align-items: center; gap: 5px; margin-top: 6px; }

/* White-listed addresses: a box a row, and beside it what the server reads it
   as, or that it reads no address there, in the refusal's own colour. */
.address-table { max-width: 560px; }
.address-table th.address-reading { width: 132px; }
.address-table th:last-child, .address-table td:last-child { width: 34px; }
.address-table td.address-reading { padding: 0 6px; color: var(--text-dim); white-space: nowrap; }
.address-table td.address-reading.invalid { color: var(--error-text); }
.address-table input.not-an-address { border-color: var(--invalid-line); background: var(--invalid-fill); }
.address-table td.address-none { width: auto; height: 30px; padding: 0 8px; text-align: left; position: static; box-shadow: none; color: var(--text-dim); }

/* A group's symbol rules: the list, its buttons beside it, and the chosen
   rule set out underneath. */
.rule-list { display: grid; gap: 8px; }
.rule-list-top { display: grid; grid-template-columns: minmax(0, 1fr) 92px; gap: 8px; align-items: start; }
.rule-list-top .read-only-table-wrap { max-height: 150px; }
.rule-buttons { display: grid; gap: 5px; }
.rule-buttons button { min-width: 0; width: 100%; }
.rule-detail { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 14px; }
.rule-detail .field-group:first-child { grid-column: 1 / -1; }
.rule-detail .field-group:first-child .form-grid { grid-template-columns: minmax(0, 1fr) auto auto; }
.rule-detail .field-group:not(:first-child) .form-grid { grid-template-columns: minmax(0, 1fr); }
.rule-detail .form-field { grid-template-columns: 112px minmax(0, 1fr); }
.rule-detail .field-group:first-child .form-field.field-wide { grid-column: auto; }
.rule-detail .field-group:first-child .check-field { grid-template-columns: 0 auto; padding-left: 12px; }

.table-field { display: block; }
.table-field > span { display: block; margin-bottom: 4px; text-align: left; font-weight: bold; }
.password-action { display: flex; align-items: center; gap: 14px; }
.password-action p { flex: 1; margin: 0; color: #444; line-height: 15px; }
.history-request { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; padding: 6px 8px; border: 1px solid var(--group-line); border-radius: 3px; background: #fafbfc; }
.history-request .history-title { font-weight: bold; }
.history-request .error-strip { flex: 1 0 100%; }

.sessions-editor { min-width: 0; display: grid; gap: 8px; }
.sessions-editor > .field-group { margin: 0; }
.week-table td:first-child { width: 110px; }
.session-columns { min-width: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.session-columns h4 { margin: 0 0 5px; color: #333; font-size: 11px; font-weight: normal; text-decoration: underline; text-decoration-color: #c8d3de; text-underline-offset: 3px; }
.session-list { min-width: 0; }
.session-none { margin-bottom: 4px; color: var(--text-faint); }
/* The mode, the two clocks, how long the session lasts, and Remove — one line. */
.session-row { min-width: 0; display: flex; align-items: center; gap: 5px; margin-bottom: 4px; }
.session-row .session-mode { flex: 0 0 104px; width: 104px; }
.session-clocks { display: flex; align-items: center; gap: 3px; min-width: 0; color: var(--text-dim); }
.session-clocks span { padding: 0 1px; }
.session-row input.clock-box { flex: 0 0 38px; width: 38px; text-align: right; padding: 0 2px; }
/* The length of the session, beside the boxes that produced it. This is what
   shows an operator that the closing minute is worked in full. */
.session-duration { flex: 0 0 auto; height: 21px; display: flex; align-items: center; padding: 0 4px; white-space: nowrap; color: var(--group-ink); font-weight: bold; cursor: help; }

/* Group Operations: the accounts, and the operations as buttons beside them. */
.group-operations { display: grid; grid-template-columns: minmax(0, 1fr) 190px; gap: 10px; min-height: 220px; }
.group-operations > .read-only-table-wrap { max-height: 320px; }
.group-operation-buttons { display: grid; align-content: start; gap: 5px; }
.group-operation-buttons button { width: 100%; }
.operation-field { display: grid; gap: 2px; margin-top: 4px; color: var(--text-dim); }
.operation-field select, .operation-field input { width: 100%; }
.operation-gap { height: 8px; }

/* Money in and money out, in the colours of the Deposit and Withdrawal
   buttons. */
.window button.deposit-button { min-width: 96px; border-color: #4a78c2; background: linear-gradient(#e9f0fd, #b9cdf3); }
.window button.withdraw-button { min-width: 96px; border-color: #c25050; background: linear-gradient(#fdeaea, #f2b8b8); }

.entity-editor > .dialog-buttons, .confirm-window > .dialog-buttons { padding: 9px 8px 9px; background: var(--face); }

.confirm-window { width: min(460px, calc(100vw - 44px)); }
.confirm-body { min-height: 92px; padding: 18px 18px 10px; display: grid; grid-template-columns: 40px 1fr; align-items: start; gap: 14px; background: var(--pane); border-bottom: 1px solid var(--line-faint); }
.confirm-body p { margin: 2px 0 8px; line-height: 16px; }
.confirm-icon { width: 34px; height: 34px; display: grid; place-items: center; color: #17120a; font-size: 21px; font-weight: bold; background: radial-gradient(circle at 35% 30%, #fde68a, #f2c94c 60%, #d8a821); border: 1px solid #a8841f; border-radius: 50%; }
.confirm-icon.info { color: #fff; background: radial-gradient(circle at 35% 30%, #8cc4f5, #2f7fd1 65%); border-color: #1d5fa8; font-family: Georgia, serif; }
.confirm-detail { color: var(--text-dim); }
.confirm-body > .error-strip { grid-column: 1 / -1; }
.danger-button { color: #8e1010; font-weight: bold; }

.about-facts { border-collapse: collapse; margin-top: 4px; }
.about-facts td { padding: 2px 12px 2px 0; }
.about-facts td:first-child { color: var(--text-dim); }

@media (max-width: 760px) {
  .form-grid { grid-template-columns: minmax(0, 1fr); }
  .field-wide { grid-column: 1; }
  .check-group { grid-template-columns: minmax(0, 1fr); }
  .session-columns { grid-template-columns: minmax(0, 1fr); }
}

/* On a laptop's screen the side windows give the lists their width. */
@media (max-width: 1500px) {
  .manager-body { --market-watch: 232px; grid-template-columns: var(--market-watch) minmax(0, 1fr) 226px; }
  .manager-body.quotes-with-spread { --market-watch: 270px; }
  .manager-body.quotes-with-time { --market-watch: 294px; }
  .manager-body.quotes-with-spread.quotes-with-time { --market-watch: 326px; }
  .manager-body.no-market-watch { grid-template-columns: minmax(0, 1fr) 226px; }
  .quote-head, .quote-row { grid-template-columns: minmax(0, 1fr) 64px 64px; }
  .admin-body { grid-template-columns: 164px minmax(0, 1fr); }
}

/* ---------------------------------------------------------------------------
   Trading on an account: the account sheet's Trade page — a tick chart beside
   one ticket for every operation — and its Trades list.
   The ticket wears the way the desk trades, the switch's green or orange, as
   a band down its working pane, so routing applying or not is never a matter
   of memory.
   ------------------------------------------------------------------------ */
.trade-page { display: grid; grid-template-rows: auto minmax(0, 1fr); gap: 8px; min-width: 0; }
.trade-mode-row { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; }
.trade-mode-row .trade-mode-switch { margin-right: 0; }
.trade-mode-note { color: var(--mode-text); }
.trade-body { display: grid; grid-template-columns: minmax(200px, 296px) minmax(0, 1fr); gap: 12px; min-width: 0; }
.trade-chart { min-height: 300px; display: grid; border: 1px solid var(--frame-line); }
.trade-ticket { min-width: 0; display: grid; align-content: start; gap: 5px; }

.trade-field { min-width: 0; display: grid; grid-template-columns: 70px minmax(0, 1fr); align-items: center; gap: 8px; }
.trade-label { text-align: right; color: #1a1a1a; white-space: nowrap; }
.trade-control { min-width: 0; display: flex; align-items: center; gap: 6px; }
.trade-control > select, .trade-control > input:not([type="checkbox"]) { flex: 1 1 auto; width: 100%; min-width: 0; }
.trade-control > input.timestamp-input { flex: 0 0 128px; width: 128px; }
.trade-unit { color: var(--text-dim); white-space: nowrap; }
.trade-pair { min-width: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.trade-pair > .trade-field:last-child { grid-template-columns: 64px minmax(0, 1fr); }
.trade-subject { padding: 2px 0; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.trade-subject.loss { color: var(--down); }

/* A spinner: the box, and two arrows stacked beside it. */
.spin-box { flex: 0 1 136px; min-width: 0; display: flex; }
.spin-box input { width: 100%; min-width: 0; text-align: right; font-variant-numeric: tabular-nums; }
.spin-buttons { flex: 0 0 15px; display: grid; grid-template-rows: 1fr 1fr; height: 21px; border: 1px solid var(--field-line); border-left: 0; }
.window button.spin { width: 100%; min-width: 0; height: auto; padding: 0; border: 0; border-radius: 0; font-size: 8px; line-height: 8px; background: linear-gradient(#fbfbfb, #e4e4e4); }
.window button.spin + button.spin { border-top: 1px solid var(--line-soft); }
.window button.spin:hover:not(:disabled) { background: var(--button-hover); }

.trade-pane { min-width: 0; display: grid; gap: 6px; margin: 4px 0 0; padding: 10px 12px 9px 15px; border: 1px solid var(--frame-line); border-radius: 3px; background: #fcfcfc; box-shadow: inset 4px 0 0 var(--mode); }
.trade-pane:disabled { opacity: 1; }
.trade-warning { padding: 4px 8px; color: var(--warn-text); background: var(--warn-fill); border: 1px solid var(--warn-line); line-height: 14px; }
.trade-hint { margin: 0; color: var(--text-dim); line-height: 14px; }

/* The account's Bid and Ask: large, the sides' colours, the last digit
   small. */
.trade-quote { display: flex; justify-content: center; align-items: baseline; margin: 6px 0 2px; font-size: 26px; line-height: 30px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.trade-quote small { font-size: 16px; }
.trade-quote .bid { color: var(--down); }
.trade-quote .ask { color: var(--up); }
.trade-quote .slash { padding: 0 8px; color: #303030; }
.trade-quote .no-quote { font-size: 13px; color: var(--text-faint); }

/* The button that sends says exactly what it does, in its own colour: red to
   sell, blue to buy or change, yellow to close, red to delete. */
.trade-actions { min-width: 0; display: grid; gap: 8px; }
.trade-actions.two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.window .trade-actions button { width: 100%; min-width: 0; height: 28px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.window .trade-actions button.sell-button { border-color: #b24c4c; background: linear-gradient(#f9d2cf, #eb9b95); }
.window .trade-actions button.buy-button { border-color: #4b6db4; background: linear-gradient(#d6e0f8, #9fb4ec); }
.window .trade-actions :is(button.place-button, button.modify-button) { border-color: #4b6db4; background: linear-gradient(#e3eafb, #bccbf2); }
.window .trade-actions button.close-button { border-color: #ad9a32; background: linear-gradient(#fcf7cf, #ede195); }
.window .trade-actions button.delete-button { border-color: #b24c4c; background: linear-gradient(#fbe6e4, #f1b7b2); }
.window .trade-actions button:hover:not(:disabled) { filter: brightness(1.04); border-color: var(--button-line-hover); }
.window .trade-actions button:disabled { color: var(--text-faint); border-color: var(--frame-line); background: var(--disabled-fill); }
.trade-status { min-height: 15px; color: var(--text-dim); line-height: 15px; }
.trade-status.error { color: var(--error-text); }
.trade-status.warning { color: var(--warn-text); }
/* A request whose answer was lost holds the ticket until it is sent again or
   let go. */
.trade-hold { display: grid; gap: 6px; padding: 6px 8px; background: var(--warn-fill); border: 1px solid var(--warn-line); }
.trade-hold .trade-hint { color: var(--warn-text); }

.close-by-list { max-height: 118px; overflow: auto; border: 1px solid var(--frame-line); background: var(--pane); }
.close-by-list tbody tr:focus-visible, .trade-list tbody tr:focus-visible { outline: 1px dotted #000; outline-offset: -2px; }

/* The Trades page's list: a row is chosen, opened and offers its menu; what
   the last trade opened or changed lights up once as the page returns. */
.trade-list tbody tr.just-changed td { animation: just-changed 2.4s ease-out; }
@keyframes just-changed { from { background: #ffe98a; color: #000; } }
@media (prefers-reduced-motion: reduce) {
  .trade-list tbody tr.just-changed td { animation: none; }
  .trade-list tbody tr.just-changed td:first-child { box-shadow: inset 3px 0 0 #e0b400; }
}
.trade-list .empty-table .empty-action { margin-left: 10px; }
/* Below the account's money line, the history History asked for, in the same
   columns; it scrolls sideways with them when they outgrow the page. */
.trade-list .history-note { height: 40px; color: var(--text-faint); text-align: center; }
/* The money line stays readable however far the columns are scrolled. */
.trade-list .summary-row td > span { position: sticky; left: 6px; }
.trade-receipt { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; padding: 4px 6px 4px 8px; color: var(--mode-text); background: var(--mode-fill); border: 1px solid var(--mode-line); }
.trade-receipt .receipt-text { font-weight: bold; }
.trade-receipt .receipt-how { color: #444; }
.window .trade-receipt button.receipt-dismiss { width: 22px; min-width: 0; height: 19px; margin-left: auto; padding: 0; }

/* The account sheet keeps one size across its pages, and the Trade page is
   its tallest. */
.entity-editor.editor-account:not(.single-page) .editor-page { min-height: min(470px, calc(100vh - 190px)); }

/* The Deal window: the ticket alone, for a manager who may not open account
   sheets. */
.trade-window { width: min(860px, calc(100vw - 44px)); max-height: calc(100vh - max(20px, 7vh) - 12px); display: grid; grid-template-rows: 26px minmax(0, 1fr) auto; }
.trade-window-page { min-height: 0; overflow: auto; margin: 8px 8px 0; padding: 10px 14px 12px; border: 1px solid var(--page-line); background: var(--pane); }
.trade-window > .dialog-buttons { padding: 9px 8px; }

@media (max-width: 760px) {
  .trade-body { grid-template-columns: minmax(0, 1fr); }
  .trade-chart { min-height: 180px; }
}
