/* How much space a panel takes — issue #323.
   ═══════════════════════════════════════════════════════════════════════════════════════════
   Plain CSS under wwwroot/css/ rather than SCSS, for the reason in Styles/README.md: the Dart
   Sass step runs under ContinueOnError and Node is not installed here, so a rule added under
   Styles/ may never reach a browser.

   THE RULE IS TWO AXES, AND NEITHER WORKS ALONE.

     * WHAT A PANEL HOLDS decides the measure that suits it. A table's width is set by its data,
       so it takes whatever it is given; a form gains nothing past the width of its controls; prose
       past about 80 characters a line stops being readable.
     * WHERE A PANEL LIVES decides what it may actually have. Five views lay panels out in Bootstrap
       columns — _ActivityCompanyBody alone has eleven — and six carry h-100 to match a sibling's
       height. In both the container has already decided, and a measure of the panel's own would
       fight it.

   So the measure only ever CAPS. It is a custom property rather than a width, which is what lets a
   context override it in one line instead of every panel inside it carrying an exception.

   WHAT THIS REPLACED. #main was Bootstrap's fixed `container` unless a view set FullWidth, so an
   admin grid was squeezed into roughly three quarters of the window and scrolled sideways for the
   rest: measured on /admin/errors at an 865px viewport, #main was 720px and the table needed
   1,082px. Widening it is only half the answer — a panel that then stretches a paragraph to 185
   characters a line is worse than the scrollbar was. */

/* ── The measure ─────────────────────────────────────────────────────────────────────────── */

:root {
    /* A reading measure. Line length, not pixels: it follows the font rather than contradicting it. */
    --panel-measure-prose: 78ch;

    /* Controls stop gaining from width well before prose does — a text input at 1,200px is not
       easier to fill in, and the label above it ends up stranded from its field. */
    --panel-measure-form: 48rem;
}

.admin-panel {
    /* 100% is "whatever the context allows", which is the right default and the table's answer. */
    max-width: var(--panel-measure, 100%);
}

.admin-panel--table { --panel-measure: 100%; }
.admin-panel--form  { --panel-measure: var(--panel-measure-form); }
.admin-panel--prose { --panel-measure: var(--panel-measure-prose); }

/* ── Where it lives beats what it holds ──────────────────────────────────────────────────── */

/* A panel in a layout column has already been sized by the column. Applying a measure on top of
   that would shrink it away from its own column and break the alignment with the panel beside it,
   which is the whole point of putting them in a row. */
[class*="col-"] > .admin-panel,
[class*="col-"] > * > .admin-panel { --panel-measure: 100%; }

/* Matches the row rather than its own content. For a row of panels, where the content's height is
   the wrong answer and the row's is the right one. */
.admin-panel--fill { height: 100%; }

/* A panel nested inside another panel's body is furniture of that panel, not a page-level card. */
.admin-panel .admin-panel { --panel-measure: 100%; }

/* ── The chrome ──────────────────────────────────────────────────────────────────────────── */

/* The header is a strip, and its content is a title on the left with optional controls on the
   right. One rule, rather than the eight d-flex permutations the hand-written headers grew. */
.admin-panel-header--split {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: .5rem;
}

.admin-panel-title {
    display: inline-flex;
    align-items: center;
    min-width: 0;
}

.admin-panel-actions {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
}

/* The padded body. A wrapper rather than padding on the panel itself, because padding on the panel
   pushes the header strip inward and the strip has to run edge to edge. */
.admin-panel-body { padding: 1rem; }

/* ── Collapsible ─────────────────────────────────────────────────────────────────────────── */

/* details/summary, so opening and closing costs no script and no round trip. The caret replaces the
   default disclosure triangle, which is not stylable enough across browsers. */
.admin-panel-summary {
    cursor: pointer;
    user-select: none;
    list-style: none;
}

.admin-panel-summary::-webkit-details-marker { display: none; }
.admin-panel-summary::marker { content: ""; }

.admin-panel-summary::after {
    content: "\f282";                       /* bi-chevron-down */
    font-family: "bootstrap-icons";
    margin-left: auto;
    font-size: .8em;
    color: var(--chrome-muted);
    transition: transform .15s ease;
}

.admin-panel-details[open] > .admin-panel-summary::after { transform: rotate(180deg); }
.admin-panel-summary:hover::after { color: var(--chrome-ink); }

@media (prefers-reduced-motion: reduce) {
    .admin-panel-summary::after { transition: none; }
}

/* ── Column weight ───────────────────────────────────────────────────────────────────────── */

/* The same two axes, one level down. A column's width is what its VALUES need plus what the
   SCREEN says matters — which is why weight is a number the screen picks rather than a percentage
   derived from nothing.

   A FIXED column shrinks to its content. width:1% is how you say that to a table-layout:auto
   table: it is a hint the browser cannot honour, so the column falls back to its content's width
   and the surplus goes to the columns that asked for a share. Before this, a Level column holding
   a badge was declared 6% and took 101px of a 1,719px table; the message column beside it was
   truncating.

   A FLEX column takes a share of what is left. AdminGrid turns the weights into percentages, so
   two flex columns at weights 2 and 1 divide the remainder two to one. */
table.dataTable.admin-table th.dt-col-fixed,
table.dataTable.cp-table th.dt-col-fixed {
    width: 1%;
    white-space: nowrap;
}

table.dataTable.admin-table td.dt-col-fixed,
table.dataTable.cp-table td.dt-col-fixed {
    white-space: nowrap;
    overflow-wrap: normal;
    word-break: normal;
}

/* A flex column holding clamped text has no intrinsic width to ask for — the clamped box is happy
   at any size — so without a floor the fixed columns take everything and it collapses to a few
   characters. The floor is a minimum, not the width; the weight distributes what is above it. */
table.dataTable.admin-table th.dt-col-flex,
table.dataTable.cp-table th.dt-col-flex {
    min-width: 8rem;
}

/* ── Row height ──────────────────────────────────────────────────────────────────────────── */

/* The vertical half of the same question: a cell may spend height instead of width. One
   300-character message left unclamped makes a 90px row beside 40px neighbours and the grid reads
   as ragged, so the default is two lines — but two lines is a screen-level decision, not a law, and
   a grid with room can afford more. The full value stays in the title attribute either way. */
table.dataTable td .dt-clamp { --dt-clamp-lines: 2; }

table.dataTable.admin-table td .dt-clamp,
table.dataTable.cp-table td .dt-clamp {
    display: -webkit-box;
    -webkit-line-clamp: var(--dt-clamp-lines);
    -webkit-box-orient: vertical;
    overflow: hidden;
}
