/*
 * Page chrome and screen layout only. Anything that looks like a control or carries a colour, a radius
 * or a font belongs in css/design-system/components.css.
 */

html,
body {
    height: 100%;
}

body {
    margin: 0;
    overflow: hidden; /* the panel scrolls, the page does not */
}

/* The buttons at the foot of a card, or under a block. */

/* What sits at the right end of a list row: a status, then the row's one action. */
.app-row-actions {
    display: inline-flex;
    align-items: center;
    gap: var(--ds-space-3);
}

/* The upload dialog's "+": under its list of files, or in the middle while it has none. */
.app-upload-add {
    display: flex;
}

.ds-empty + .app-upload-add {
    justify-content: center;
}

/* A status and the spinner of the work behind it, on one line. */
.app-inline-status {
    display: flex;
    align-items: center;
    gap: var(--ds-space-2);
}

/* A row that fills its width with its fields; every item stands on the bottom line, so a button at its end sits on
   the line of the fields' controls. */
.app-form-row--fill {
    align-items: flex-end;
}

.app-form-row--fill > .ds-field {
    flex: 1 1 0;
    min-width: 0;
}

.app-form-row--fill > .ds-btn {
    flex: none;
}

/* A heading that takes the free width of its line, so what follows it stands at the line's end. */
.app-heading-fill {
    flex: 1;
    min-width: 0;
}

/* Form fields a pack asked to sit side by side; they share the row evenly and wrap on a narrow screen. */
.app-form-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ds-space-4);
}

.app-form-row > * {
    flex: 1 1 130px;
    min-width: 0;
}

/* The field that takes twice a share. */
.app-form-row > .app-form-row-wide {
    flex-grow: 2;
}

/* A note under the row's fields, across its whole width. */
.app-form-row > .app-form-row-note {
    flex-basis: 100%;
    margin: 0;
}

/* The inspect dialog: a table scrolls both ways inside it, under the segments, and a long cell is cut. */
.app-inspect,
.app-inspect-scroll {
    height: 100%;
}

.app-inspect-view {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-4);
    align-items: flex-start;
    height: 100%;
}

.app-inspect-holder {
    flex: 1;
    align-self: stretch;
    min-height: 0;
}

.app-inspect-entry > .ds-kv {
    margin-top: var(--ds-space-5);
}

.app-inspect-scroll {
    overflow: auto;
}

.app-inspect-table td {
    max-width: 320px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.app-inspect-open {
    margin: var(--ds-space-4) 0;
}

.app-inspect-preview {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
}

.app-inspect-preview > .ds-prose,
.app-inspect-preview > .ds-code {
    align-self: stretch;
}

.app-inspect-media {
    max-width: 100%;
    max-height: 70vh;
}

.app-inspect-frame {
    align-self: stretch;
    height: 70vh;
    border: 0;
}

/* A small icon button beside a label, on the label's line; lifted to the letters' middle, which sits above `middle`. */
.app-inline-action {
    position: relative;
    top: calc(1px - var(--ds-space-1));

    /* Taller than the text beside it: the negative block margin keeps its line as tall as the others. */
    margin-block: calc(0px - var(--ds-space-1));
    margin-left: var(--ds-space-2);
    vertical-align: middle;
}

/* The actions that end a detail column: kept at its bottom however little stands above them. */
.app-detail-foot {
    margin-top: auto;
}

/* In a padded scroller it also covers that padding, or what scrolls past shows under it. */
.ds-panel-content > .app-detail-foot {
    bottom: calc(0px - var(--ds-space-6));
    padding-bottom: var(--ds-space-6);
}

/* A captioned block inside a card: its caption row, then its content. */
.app-card-block {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-2);
    min-width: 0;
    margin-top: var(--ds-space-5);
}

.app-card-block:first-child {
    margin-top: 0;
}

.app-card-block-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ds-space-3);
    min-height: var(--ds-control-height-xs);
}

.app-table-scroll {
    overflow-x: auto;
}

.app-nowrap {
    white-space: nowrap;
}

/* Rows of uneven height read from their first line. */
.app-table-top td {
    vertical-align: top;
}

/* The same columns in every group's table, so switching groups moves nothing; a longer name is clipped, not wrapped. */
.app-tools-table {
    table-layout: fixed;
}

.app-tools-table th:nth-child(1) {
    width: 12rem;
}

.app-tools-table th:nth-child(2) {
    width: 10rem;
}

.app-tools-table td:nth-child(-n + 2) {
    overflow: hidden;
    text-overflow: ellipsis;
}

/* The column that takes what the others leave. */
.app-table-fill {
    width: 100%;
}

/* A user who hasn't signed in yet, or an archived user or person. */
.app-not-signed-in,
.app-archived {
    opacity: 0.55;
}

/* The membership editor: its filter above the table. */
.app-membership-editor {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-4);
}

/* A column of pictures takes only the avatar's width. */
.app-table-avatar {
    width: 1%;
}

/* A background queue's items: the three short columns are centred, headings included, between the item and its
   last error, which takes the room. `.ds-table` is restated to outrank `.ds-table th`. */
.ds-table.app-queue-items :is(th, td):nth-child(n + 2):nth-child(-n + 4) {
    text-align: center;
}

.ds-table.app-queue-items td:first-child {
    width: 28%;
    white-space: normal;
    overflow-wrap: anywhere;
}

.ds-table.app-queue-items :is(th, td):last-child {
    width: 46%;
}

/* The ignored items stand apart from the items above them. */
.app-queue-ignored {
    margin-top: var(--ds-space-4);
}

/* A trailing cell holding a row's action, as narrow as it and at the row's end. */
.app-table-action {
    width: 1%;
    text-align: right;
    white-space: nowrap;
}

/* Tables stacked under one section keep their columns in line: every width but the first is set. */
.app-table-aligned {
    min-width: 44rem;
    table-layout: fixed;
}

.app-col-wide {
    width: 22rem;
}

.app-col-medium {
    width: 14rem;
}

.app-col-check {
    width: 6rem;
}

.app-col-action {
    width: 8rem;
}

/* Two buttons side by side, the longer "Stop ignoring" among them. */
.app-col-actions {
    width: 15rem;
}

/* A little more room under a connectors table's last row. */
.app-table-end-space {
    padding-bottom: 3px;
}

/* Text reads from the top of a row; its one control stays in the middle. */
.app-table-aligned.app-table-top :is(td.app-table-action, td.ds-table-check) {
    vertical-align: middle;
}

:is(.app-table-aligned, .app-run-table) td.app-nowrap > * {
    overflow: hidden;
    text-overflow: ellipsis;
}

/* A table whose columns keep the shares their `col`s set. */
.app-table-fixed {
    width: 100%;
    table-layout: fixed;
}

.app-col-quarter {
    width: 25%;
}

.app-col-fifth {
    width: 20%;
}

/* Two sections of narrow tables, each half the width when both fit. */
.app-kind-more {
    margin-top: var(--ds-space-4);
}

.app-table-pair {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 24rem), 1fr));
    column-gap: var(--ds-space-5);
    align-items: start;
}

/* The ingest and transform run tables, side by side when both fit. */
.app-run-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 550px), 1fr));
    column-gap: var(--ds-space-5);
    align-items: start;
}

/* One kind of usage's own controls, after the period. */
.app-usage-controls {
    display: flex;
    gap: var(--ds-space-4);
}

.app-usage-controls[hidden] {
    display: none;
}

.app-usage-search {
    width: 280px;
}

.app-usage-call {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-3);
}

.app-usage-call > p {
    margin: 0;
}

/* A turn of a sequence: its prompt over the calls made for it. */
.app-usage-turn {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-3);
}

.app-usage-turn + .app-usage-turn {
    margin-top: var(--ds-space-6);
}

.app-usage-sequence + .app-usage-sequence {
    margin-top: var(--ds-space-7);
}

/* On the edge of the table's text. */
.app-usage-turn-head {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-1);
    padding: 0 var(--ds-space-6);
}

.app-usage-turn-head > :is(h3, p) {
    margin: 0;
    white-space: pre-wrap;
}

/* Export and import: controls side by side, and a connector beside the configuration that takes it. */
.app-transfer-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--ds-space-4);
}

.app-transfer-list {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-4);
}

.app-transfer-connector {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--ds-space-4);
}

/* Charts side by side where two fit. */
.app-usage-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 550px), 1fr));
    gap: var(--ds-space-5);
    margin-top: var(--ds-space-5);
}

/* A run table keeps its columns while a pack's history opens and closes under it; the name takes the rest. */
.app-run-table {
    min-width: 22rem;
    table-layout: fixed;
}

/* The longest short date, `Nov 28, 12:59 PM`, and the cell's padding. */
.app-run-col-date {
    width: 9.25rem;
}

/* The button's own air spaces it from the date. */
.app-run-table td:last-child {
    padding-left: 0;
}

.app-run-col-fold {
    width: calc(var(--ds-control-height-sm) + var(--ds-space-3) + var(--ds-space-2));
}

/* A running run's spinner and time, or a queued one's date, with its cancel button at the end. */
.app-run-live {
    display: flex;
    align-items: center;
    gap: var(--ds-space-2);
}

/* One entry of a list the configuration form grows: the entry, then its remove button. */
.app-schema-row {
    display: flex;
    align-items: flex-start;
    gap: var(--ds-space-2);
}

.app-schema-row > :first-child {
    flex: 1;
    min-width: 0;
}

/* A rule editor: "Match" and its choice at the end of the heading, the kind column as narrow as its content, the kind
   and its fields side by side, and the add button its own width. */
.app-rules-match {
    display: inline-flex;
    align-items: center;
    gap: var(--ds-space-2);
}

.app-rules-kind {
    width: 1%;
}

.app-rules-kind > .ds-field {
    display: inline-block;
    vertical-align: top;
}

.app-rules-add {
    align-self: flex-end;
}

/* A case read as a sentence: the word that leads a line, the line, and the word or the button that ends it, all on
   the line's first baseline. */
.app-case-lines {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) var(--ds-control-height-sm);
    gap: var(--ds-space-3);
    align-items: baseline;
}

.app-case-lines > .ds-field-error {
    grid-column: 1 / -1;
}

.app-case-lines > .app-case-and {
    text-align: center;
}

/* A case's conditions, with the case's menu beside the first of them. */
.app-case-top {
    display: flex;
    align-items: flex-start;
    gap: var(--ds-space-3);
}

.app-case-top > :first-child {
    flex: 1;
    min-width: 0;
}

/* The menu's disc is shorter than a condition, and stands in the middle of the first one. */
.app-case-top > .ds-menu {
    margin-top: calc((var(--ds-control-height) - var(--ds-control-height-sm)) / 2);
}

/* The small filters under the All users search, side by side on one line, each label cut short when narrow. */
.app-rail-filters {
    display: flex;
    gap: var(--ds-space-2);
}

.app-rail-filters > .ds-dropdown {
    flex: 1 1 0;
    min-width: 0;
}

.app-rail-filters > .ds-dropdown > .ds-btn {
    width: 100%;
}

/* Small cards one after another in a row, folding onto the next when the row is full. */
.app-card-flow {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ds-space-2);
    margin-top: var(--ds-space-2);
}

.app-card-flow > * {
    max-width: min(100%, 26rem);
}

/* On a phone each cell of a row is a line of its own, and the row's rule stands under the last. */
@media (width <= 900px) {
    .app-table-stacked {
        min-width: 0;
    }

    .app-table-stacked :is(colgroup, thead) {
        display: none;
    }

    .app-table-stacked :is(tbody, tr, td) {
        display: block;
    }

    /* Spelt out to outrank the table card's own edge cells. */
    .ds-card--table .ds-table.app-table-stacked tbody tr > td {
        padding-inline: var(--ds-space-6);
    }

    .ds-card--table .ds-table.app-table-stacked tbody tr > td:not(:last-child) {
        padding-bottom: 0;
        border-bottom: 0;
    }

    .ds-card--table .ds-table.app-table-stacked tbody tr > td:not(:first-child) {
        padding-top: var(--ds-space-2);
    }
}
