/* ---- the Columns list dialog ---- */

.dynamic-list-body {
    margin: 0 0 25px 0;
    /* as wide as the table, so the sticky Add bar also covers the rows when scrolled sideways */
    width: max-content;
    min-width: 100%;
}

/* the Add bar stays visible while the column list scrolls.
   .dialog-main-area has 12px of padding at the top - the sticky bar has to reach up into it,
   otherwise rows show ("bleed") above the Add button while scrolling.
   the 12px must match iScrollPadTop in dynamic_list_data.js */
.dynamic-list-add-bar {
    /* Add on the left, the rest of the buttons pushed over to the right */
    display: flex;
    align-items: center;
    gap: 8px;
    /* sticky on both axes - the list scrolls sideways underneath it.
       its width is set to the width of the scrollport in ColumnDef_addBar_fitToScrollport */
    position: sticky;
    top: -12px;
    left: 0;
    /* above the sticky table headers so they scroll under the Add button */
    z-index: 20;
    background: var(--color-cards-background);
    padding: 12px 0 8px 0;
    margin-top: -12px;
}

/* which list is open - sits at the left end of the bar, ahead of the Add button */
.dynamic-list-title {
    font-weight: 600;
    white-space: nowrap;
    padding-right: 4px;
}

.dynamic-list-table {
    width: auto;
    table-layout: auto;
    /* separate rather than collapse - a collapsed border belongs to the table rather than to
       the cell, so the frozen columns below would leave their borders behind when scrolled */
    border-collapse: separate;
    border-spacing: 0;
}

.dynamic-list-th {
    border-bottom: 1px solid #ccc;
    padding: 4px 8px;
    text-align: left;
    white-space: nowrap;
}

/* 'narrow' columns hold a short number or a tick - they get a fixed small width
   and their caption wraps onto 2 lines */
.dynamic-list-th-narrow {
    text-align: center;
    width: 58px;
    white-space: normal;
}

.dynamic-list-td {
    border-bottom: 1px solid #eee;
    padding: 4px 8px;
    white-space: nowrap;
}

.dynamic-list-td-center {
    text-align: center;
}

/* a column defined as Grayed - the whole row is drawn gray, the same way the
   column itself is drawn in the list it belongs to. a Hidden column does not show
   in its list at all, so its row is fainter again.
   both come before the edited-row rules on purpose - same specificity, so the
   highlight of the row just edited still wins */
.dynamic-list-table tbody tr.dynamic-list-tr-grayed > td {
    color: gray;
}

.dynamic-list-table tbody tr.dynamic-list-tr-hidden > td {
    color: silver;
}

/* the row last opened in the editor, so it's obvious which one was just edited.
   same colours as tr.selected in tables_v47.css */
.dynamic-list-table tbody tr.dynamic-list-tr-edited {
    background-color: var(--color-table-row-selected);
}

.dynamic-list-table tbody tr.dynamic-list-tr-edited > td {
    color: var(--color-table-row-selected-forecolor);
}

/* a row is clicked to pick out its column for the Move Up / Move Down buttons */
.dynamic-list-table tbody tr {
    cursor: pointer;
}

/* the row picked out to be moved - the colours of the row last edited, with a bar down its
   left-hand edge to say it is the one the Move buttons act on. the bar is an inset shadow
   rather than a border, so picking a row does not shift the rows below it */
.dynamic-list-table tbody tr.dynamic-list-tr-selected {
    background-color: var(--color-table-row-selected);
}

.dynamic-list-table tbody tr.dynamic-list-tr-selected > td {
    color: var(--color-table-row-selected-forecolor);
    font-weight: 600;
}

/* ---- the frozen columns ---- */

/* the first few columns (the Edit / Delete icons, Col Id and Column Name) stay put while
   the rest of the list scrolls sideways, so it stays obvious which column a row is.
   how far along each one parks is set in code - ColumnDef_frozenColumns_setOffsets - since
   it depends on the widths the columns end up with */
.dynamic-list-th-frozen {
    position: sticky;
    /* over the ordinary headers (z-index 10 in tables_v48.css), under the sticky Add bar */
    z-index: 12;
}

.dynamic-list-table tbody td.dynamic-list-td-frozen {
    position: sticky;
    z-index: 2;
    /* the rows carry no background of their own - without one here the columns passing
       underneath would show through */
    background: var(--color-cards-background);
}

/* a frozen cell is painted over its row, so it has to repeat whatever background the row
   itself is showing. same order as the row rules above - the edited row still wins on hover */
.dynamic-list-table tbody tr:hover > td.dynamic-list-td-frozen {
    background: var(--color-table-row-hover);
}

.dynamic-list-table tbody tr.dynamic-list-tr-edited > td.dynamic-list-td-frozen {
    background: var(--color-table-row-selected);
}

/* the picked-out row is the one that matters, so it comes last of the three */
.dynamic-list-table tbody tr.dynamic-list-tr-selected > td.dynamic-list-td-frozen {
    background: var(--color-table-row-selected);
}

/* the bar goes on the first cell of the row, which is a frozen one - so it stays in view
   when the list is scrolled sideways */
.dynamic-list-table tbody tr.dynamic-list-tr-selected > td:first-child {
    box-shadow: inset 3px 0 0 0 var(--color-link, #3a86ff);
}

/* the last of the frozen columns - a soft shadow marks where the frozen part ends */
.dynamic-list-frozen-edge {
    box-shadow: 2px 0 3px -1px rgba(0, 0, 0, 0.16);
}

.dynamic-list-td-empty {
    padding: 8px;
}

.dynamic-list-icon-delete {
    margin-left: 10px;
}


/* ---- the Add / Edit column dialogs ---- */

.dynamic-list-add-body {
    margin: 25px 0 40px 0;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.dynamic-list-edit-body {
    margin: 25px 0 40px 0;
    display: flex;
    flex-direction: row;
    align-items: flex-start;
    gap: 24px;
    /* the two fixed groups plus the json one need ~1000px side by side, and the dialog is
       narrower than that - the groups keep their own width and drop onto the next line
       rather than being cut off at the edge (the dialog itself clips, it does not scroll) */
    flex-wrap: wrap;
}

/* the Edit Column Definition dialog is taller than the 650px every other dialog gets -
   it holds seven groups of fields, and the shorter it is the more of it the sticky
   button bar covers. kept under the height of the window as well, so a small screen
   does not end up with a dialog it cannot see the bottom of */
#_id_dialog_columnDef_edit .dialog-main-area {
    max-height: min(780px, 84vh);
}

/* the button bar is centered and sticky to the bottom of the dialog, which puts it
   straight over the last group of the middle column - the Excel one. moved along to the
   right, where it is clear of that column and sits under the Advanced one instead.
   the shared rule leaves 20px here, so this is 180px of it (half the margin added) */
#_id_dialog_columnDef_edit .dialog-button-bar {
    margin-left: 380px;
}

/* the groups sit in two columns side by side */
/* fixed widths rather than shares of the dialog, so the groups keep the same size
   whatever the dialog is doing. 15px label margin + 105px label + 10px gap + 140px
   control + 28px of group padding needs ~300 */
.dynamic-list-edit-column {
    display: flex;
    flex-direction: column;
    gap: 20px;
    flex: 0 0 300px;
    min-width: 0;
}

/* the Advanced column holds the json boxes rather than labelled controls - it is
   the one that grows, so all the width left over by the other two goes to it */
.dynamic-list-edit-column-wide {
    flex: 1 1 360px;
}

/* a bordered group (fieldset) with a caption, used to group the editor fields */
.dynamic-list-group {
    border: 1px solid silver;
    border-radius: 6px;
    padding: 10px 14px 14px 14px;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.dynamic-list-group-legend {
    padding: 0 6px;
    font-weight: 600;
    color: var(--color-text-1);
}

.dynamic-list-row {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 10px;
}

/* wide enough for the longest of them (Column Name, Header Align, More Details) and no
   wider - the labels still line up as a column, without a gap before the controls */
.dynamic-list-row-label {
    flex: 0 0 105px;
    text-align: left;
}

/* a row whose control is too big to sit beside its label - the label goes above */
.dynamic-list-row-stacked {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

/* this row stacks, so the 140px on .dynamic-list-row-label would be read as a
   height and leave a gap above the box - the label takes its natural size here */
.dynamic-list-row-stacked .dynamic-list-row-label {
    flex: 0 0 auto;
}

/* the label of a stacked row, with the field's sub-editor button beside it */
.dynamic-list-row-stacked-header {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 10px;
}

.dynamic-list-json-build-button {
    padding: 1px 10px;
    font-size: 0.75rem;
    line-height: 1.6;
    cursor: pointer;
}

/* the Complex Col Definition field is only greyed, never emptied - a column that is not
   the Complex type does nothing with it, but what is stored in it is still kept */
.dynamic-list-json-build-button:disabled {
    opacity: 0.45;
    cursor: default;
}

.dynamic-list-textarea-json:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* json is easier to read and line up in a monospace font */
.dynamic-list-textarea-json {
    width: 100%;
    box-sizing: border-box;
    font-family: Consolas, 'Courier New', monospace;
    font-size: 0.78rem;
    white-space: pre;
    overflow-wrap: normal;
    overflow-x: auto;
    resize: vertical;
}

/* without a fixed width the control stretches - the fixed ones keep the numbers
   and dropdowns compact (the width itself is set in code) */
.dynamic-list-control-fixed {
    margin-right: auto;
}

.dynamic-list-control-grow {
    flex: 1;
}


/* ---- the Event Listener sub-editor ---- */

.dynamic-list-event-body {
    margin: 25px 0 40px 0;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

/* the field held something that could not be parsed - OK is going to replace it */
.dynamic-list-event-warning {
    padding: 6px 10px;
    border: 1px solid var(--color-borders-1);
    border-left: 4px solid crimson;
    border-radius: 4px;
    font-size: 0.8rem;
}

/* the Function dropdown with its note underneath */
.dynamic-list-event-function {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

/* lines the note up under the dropdown rather than under its label -
   105px of .dynamic-list-row-label plus the 10px gap of .dynamic-list-row */
.dynamic-list-event-hint-indent {
    margin-left: 115px;
}

.dynamic-list-event-params {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.dynamic-list-event-hint {
    font-size: 0.78rem;
    opacity: 0.75;
}

.dynamic-list-event-param-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.dynamic-list-event-param-row {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 6px;
}

/* the position in the list - it is the order the params are passed in, so it is shown */
.dynamic-list-event-param-no {
    flex: 0 0 22px;
    text-align: right;
    font-size: 0.8rem;
    opacity: 0.75;
}

.dynamic-list-event-param-text {
    flex: 1;
    min-width: 0;
}

.dynamic-list-event-icon {
    flex: 0 0 auto;
    width: 26px;
    padding: 1px 0;
    font-size: 0.75rem;
    line-height: 1.6;
    cursor: pointer;
}

.dynamic-list-event-icon:disabled {
    opacity: 0.35;
    cursor: default;
}

.dynamic-list-event-empty {
    font-size: 0.8rem;
    font-style: italic;
    opacity: 0.6;
}

.dynamic-list-event-add {
    align-self: flex-start;
    padding: 2px 12px;
    font-size: 0.78rem;
    line-height: 1.6;
    cursor: pointer;
}


/* ---- the Complex Col Definition sub-editor ---- */
/* it reuses the event body, hint, param and button styles above - these are the element
   cards it stacks them in */

.dynamic-list-complex-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
    /* a cell can carry a few elements, and each is four rows tall - the list scrolls
       rather than pushing the Result box off the bottom of the dialog */
    max-height: 45vh;
    overflow-y: auto;
}

/* one element of the cell - its own box, since each has its own type and listener */
.dynamic-list-complex-element {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 10px 12px;
    border: 1px solid var(--color-borders-1);
    border-radius: 6px;
}

.dynamic-list-complex-element-head {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 8px;
}

/* the position in the list - it is the order the elements are drawn in, so it is shown */
.dynamic-list-complex-element-no {
    font-size: 0.8rem;
    font-weight: 600;
}

.dynamic-list-complex-element-buttons {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 6px;
    margin-left: auto;
}

/* the params of this element's listener, indented under it so they read as belonging
   to the Function above rather than to the element as a whole */
.dynamic-list-complex-params {
    margin-left: 115px;
}

/* the Locked When section - it applies to the whole cell rather than to one element,
   so it sits below the list of them with a rule between */
.dynamic-list-complex-lock {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding-top: 10px;
    border-top: 1px solid var(--color-borders-1);
}


/* ---- the Import Column Definitions dialog ---- */

.dynamic-list-import-body {
    margin: 25px 0 40px 0;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

/* what the import takes, above the box - it is a paragraph rather than a label, so it
   is a size down from the fields and does not shout */
.dynamic-list-import-note {
    font-size: 0.78rem;
    line-height: 1.35;
    opacity: 0.75;
}

/* the tick under the box */
.dynamic-list-import-row {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 8px;
}

/* the paste is a whole list of columns at once, so the box is deeper than the json
   fields of the column editor */
.dynamic-list-textarea-import {
    min-height: 320px;
}

/* what the import did, in the message dialog afterwards */
.dynamic-list-import-summary ul {
    margin: 6px 0 0 0;
    padding-left: 20px;
}

.dynamic-list-import-summary li {
    font-size: 0.85rem;
    line-height: 1.4;
}

.dynamic-list-import-summary-title {
    margin-top: 12px;
    font-weight: 600;
}


/* ---- the Header Backcolor field of the column editor ---- */

/* the box and its swatch sit on one line, in the space the other controls of the
   row get */
.dynamic-list-color-field {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 6px;
}

.dynamic-list-color-field input {
    flex: 1 1 auto;
    min-width: 0;
}

/* what the color in the box actually looks like - the color itself is set in code,
   since it is whatever was typed */
.dynamic-list-color-swatch {
    flex: 0 0 22px;
    width: 22px;
    height: 22px;
    border: 1px solid var(--color-borders-1);
    border-radius: 3px;
}

/* nothing there, or not a color - the diagonal says so rather than leaving what
   looks like a white swatch */
.dynamic-list-color-swatch-empty {
    background-image: linear-gradient(to top right,
            transparent calc(50% - 1px), var(--color-borders-1) 50%,
            transparent calc(50% + 1px));
}
