.table-compact {
    font-size: 0.8rem;
}

.table-compact th,
.table-compact td {
    padding: 0.35rem 0.5rem;
}

.table-compact .form-control,
.table-compact .form-select {
    font-size: 0.8rem;
    padding: 0.15rem 0.35rem;
}

.table-compact .btn-sm {
    font-size: 0.75rem;
    padding: 0.05rem 0.3rem;
}

/* Pins a table's header cells to the top of the viewport as its body scrolls
   past, so long tables stay legible without losing column context. Single-row
   headers just need top: 0; multi-row headers (e.g. the results grid) get
   their top offsets set in JS since row heights depend on content/font. */
.table thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    background-color: #fff;
}

/* Bootstrap's .table-responsive sets only overflow-x: auto. Per the overflow
   spec, browsers silently promote an unset (or explicitly visible) overflow-y
   to auto too whenever overflow-x isn't visible - there's no way to declare
   one axis visible while the other scrolls, the browser always promotes the
   visible one back to auto. So rather than fight that, this embraces it as a
   real internal scroll box: bounding its height means it actually scrolls
   (both axes) within itself once content overflows, which is what lets a
   position: sticky; top: 0 header resolve against and stick within it. */
.table-responsive {
    max-height: 70vh;
    overflow: auto;
}

/* Freezes the results grid's first three columns (Test Code, Sample ID,
   Sample Name) so they stay visible while scrolling horizontally through the
   many test/reading columns to their right, the same way the header row
   stays visible while scrolling down. Offsets are the running sum of the
   preceding columns' widths from #results-colgroup (70, 90px); they're
   hardcoded because those widths are static (only the trailing test columns
   are added/removed at runtime). The header row's sticky top/z-index already
   come from sticky_thead.js - this only adds left, which JS doesn't set -
   and z-index 3 there already outranks the z-index 2 given to the body cells
   below, so the frozen top-left corner paints above both scrolling headers
   and scrolling body cells. */
#results-thead tr:first-child th:nth-child(1),
#results-body tr td:nth-child(1) {
    position: sticky;
    left: 0;
}

#results-thead tr:first-child th:nth-child(2),
#results-body tr td:nth-child(2) {
    position: sticky;
    left: 70px;
}

#results-thead tr:first-child th:nth-child(3),
#results-body tr td:nth-child(3) {
    position: sticky;
    left: 160px;
}

#results-body tr td:nth-child(1),
#results-body tr td:nth-child(2),
#results-body tr td:nth-child(3) {
    z-index: 2;
    background-color: #fff;
}

/* Breaks a section out of the centered Bootstrap .container to span the full
   viewport width, giving wide tables (like the results grid) more room before
   they need to scroll. overflow-x here (rather than relying on a nested
   .table-responsive) keeps a table that's still wider than the viewport
   scrolling within its own row instead of widening the whole page. */
.full-bleed {
    width: 100vw;
    position: relative;
    left: 50%;
    right: 50%;
    margin-left: -50vw;
    margin-right: -50vw;
    padding-left: 1rem;
    padding-right: 1rem;
    box-sizing: border-box;
    /* Same overflow-y auto-promotion gotcha as .table-responsive above - a
       bounded height turns this into a real internal scroll box (both axes),
       which is what lets the results grid's sticky header and sticky left
       columns actually stick within it. */
    max-height: 70vh;
    overflow: auto;
}

/* Spreadsheet-style editable grid (internal results entry table): thin uniform
   gridlines and borderless inputs that fill their cell edge-to-edge, so the
   table reads like a data grid instead of a form with a table drawn under it.
   table-layout: fixed with each <col> given a fixed px width (not a
   percentage, and no width: 100% on the table itself) makes every column a
   real, stable size instead of being squeezed to fit the viewport. Once a
   table like the results grid has enough columns to exceed its container's
   width, it grows past it and the surrounding .table-responsive wrapper
   scrolls horizontally instead of cramming everything down to illegibility. */
.table-excel {
    font-size: 0.68rem;
    border-collapse: collapse;
    table-layout: fixed;
}

.table-excel th,
.table-excel td {
    border: 1px solid #ced4da;
    padding: 0.25rem 0.3rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.table-excel thead th {
    background-color: #f1f3f5;
    color: #212529;
    vertical-align: middle;
}

.table-excel td.cell-input {
    padding: 0;
}

.table-excel td.cell-input .form-control,
.table-excel td.cell-input .form-select {
    border: none;
    border-radius: 0;
    box-shadow: none;
    background: transparent;
    font-size: 0.68rem;
    padding: 0.25rem 0.3rem;
    width: 100%;
}

.table-excel td.cell-input .form-control:focus,
.table-excel td.cell-input .form-select:focus {
    background-color: #e7f1ff;
    box-shadow: inset 0 0 0 2px #86b7fe;
    position: relative;
    z-index: 1;
}

.table-excel .btn-sm {
    font-size: 0.75rem;
    padding: 0.05rem 0.3rem;
}

/* Brighter green for success notifications than Bootstrap's default muted
   alert-success. */
.alert-success {
    background-color: #d1f7dc;
    border-color: #4ade80;
    color: #14532d;
}

/* Bold white-on-bright-green notification for a newly created submission,
   standing out from the more muted green success alerts above. */
.alert-submission-created {
    background-color: #16a34a;
    border-color: #15803d;
    color: #fff;
    font-weight: bold;
}
