/* ---- 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: 3px 0 4px -2px rgba(0, 0, 0, 0.25);
}

.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 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);
}
