﻿/* The box builder: the harvest screen, the grid, the legend and one box.

   Phone-first on purpose. The harvest gets counted in a field, on a phone, with dirty hands — BoxBot's
   dense desktop grid is unusable there and it is the half of the week's work that does not happen at a
   desk. So the small-screen rules are the base and the desktop rules are the media query on top.

   Two things are load-bearing and tested rather than trusted:
     - .cc-tap is at least 44px in both directions. Every control a farmer presses carries it.
     - The harvest list and the compromise list reflow to one column at 375px.
   PhoneLayoutTests reads this file and fails the build if either goes. */

/* ── Hit targets ──────────────────────────────────────────────────────────── */

.cc-tap,
.cc-tap.btn,
.cc-tap.form-control {
    min-height: 44px;
    min-width: 44px;
}

.cc-tap.form-check-label {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    min-height: 44px;
}

/* ── Steps ────────────────────────────────────────────────────────────────── */

.cc-step {
    margin-bottom: 1.5rem;
    padding-top: 1rem;
    border-top: 1px solid var(--bs-border-color, #dee2e6);
}

/* ── 1. The harvest ───────────────────────────────────────────────────────── */

/* One row per crop. On a phone the name takes the full width and the number sits under it at a size a
   thumb can hit; there is no horizontal scrolling, because a table that scrolls sideways in a field is a
   table nobody fills in. */
.cc-harvest .list-group-item {
    flex-wrap: wrap;
    row-gap: .5rem;
}

.cc-harvest-name {
    flex: 1 1 100%;
    min-width: 0;
}

/* The number and its unit are ONE control, fixed in width, and the unit lives INSIDE it.

   The unit used to sit beside the field as an auto-width sibling, and this catalogue says "each", "bag",
   "lb" and "punnet" — four different widths — so the Perishable tick after it started at a different x on
   every row. That is the ragged right-hand column the owner reported. Both halves are fixed on purpose:
   pinning only the group moves the same bug one layer in, because a wide suffix would then eat the
   number's width instead of the tick's position. HarvestRowAlignmentTests holds both. */
.cc-harvest-qty-group {
    flex: 0 0 13rem;
    max-width: 13rem;
}

/* Wide enough for the value, not for the storage precision. 6.5rem clipped "262.50" mid-number at
   1.1rem once the spin buttons took their share; the displayed value is now trimmed (BoxBuilderCopy.Field)
   AND the field fits a five-figure count with two decimals. 13rem of group less 4rem of suffix leaves the
   number the same 9rem it always had, and the whole group is still well inside one column at 375px, which
   PhoneLayoutTests holds. */
.cc-harvest-qty {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 1.1rem;
    text-align: right;
}

/* The unit, as the field's suffix. Fixed width and clipped rather than allowed to grow: a farm whose unit
   word is longer than this must not be the farm whose rows go ragged. Nothing is lost when it clips — the
   line above the field already reads "stock says 40 punnet", and the input's aria-label names the unit for
   a screen reader. Padding trimmed from Bootstrap's .75rem so "punnet" fits inside the 4rem. */
.cc-harvest-unit {
    flex: 0 0 4rem;
    width: 4rem;
    padding-left: .25rem;
    padding-right: .25rem;
    justify-content: center;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    font-size: .85rem;
}

@media (min-width: 576px) {
    .cc-harvest-name {
        flex: 1 1 auto;
    }
}

/* ── 2. The dials ─────────────────────────────────────────────────────────── */

.cc-dial {
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: .5rem;
    padding: .75rem;
    height: 100%;
}

.cc-dial legend {
    float: none;
    width: auto;
    font-weight: 600;
}

/* The typed dial value: a farmer who wants 5 or 7 is not limited to the presets above it. Narrow, so it
   reads as one more control on the dial rather than as the dial. */
.cc-dial-number {
    max-width: 16rem;
}

/* ── The preview ──────────────────────────────────────────────────────────── */

/* Numbers and short labels. No speedometer gauges: the arc encodes nothing the number does not, it reads
   badly to a screen reader, and it cannot be compared precisely — which is the whole job. */
.cc-stat {
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: .5rem;
    padding: .75rem;
    height: 100%;
}

.cc-stat-value {
    font-size: 1.5rem;
    font-weight: 600;
    line-height: 1.1;
}

.cc-stat-label {
    font-size: .85rem;
}

/* The compromise list is the primary output, so it reads as a list of sentences and not as a table of
   codes. At 375px each line stacks: text, then its actions. */
.cc-compromises .list-group-item {
    padding: .75rem;
}

@media (max-width: 575.98px) {
    .cc-compromises .btn {
        width: 100%;
        text-align: left;
    }

    .cc-stats > [class*="col-"] {
        flex: 0 0 100%;
        max-width: 100%;
    }
}

/* ── 3. The grid ──────────────────────────────────────────────────────────── */

.cc-grid-group {
    margin-top: 1rem;
}

.cc-grid-heading {
    font-size: .9rem;
    font-weight: 600;
    margin-bottom: .35rem;
}

.cc-grid {
    display: grid;
    gap: .5rem;
    grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
}

/* On a phone the heat map degrades to a single-column list — a wall of 9.5rem squares on a 375px screen
   is two per row and a very long scroll, and the list carries the same words. */
@media (max-width: 575.98px) {
    .cc-grid {
        grid-template-columns: 1fr;
    }
}

.cc-box {
    display: flex;
    flex-direction: column;
    gap: .15rem;
    align-items: flex-start;
    text-align: left;
    padding: .5rem;
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: .5rem;
    background: var(--bs-body-bg, #fff);
    min-height: 5.5rem;
}

.cc-box-open {
    outline: 2px solid var(--bs-primary, #0d6efd);
    outline-offset: 1px;
}

.cc-box-member {
    font-weight: 600;
    font-size: .9rem;
}

.cc-box-value,
.cc-box-state {
    font-size: .78rem;
}

/* The word inside the square. Colour is the pattern; this is the meaning, and it is never optional. */
.cc-box-state {
    font-weight: 600;
}

.cc-box-thumbs {
    display: flex;
    gap: .15rem;
    margin-top: auto;
}

/* Colour is the CATEGORY of problem and the left border's weight is its severity — one amber for
   everything is what makes BoxBot's heat map unreadable. Every one of these has a word beside it in the
   legend and inside the square; none of them is the only channel. */
.cc-box.box-ok       { border-left: 4px solid #198754; }
.cc-box.box-under    { border-left: 6px solid #dc3545; }
.cc-box.box-over     { border-left: 4px solid #fd7e14; }
.cc-box.box-short    { border-left: 6px solid #6f42c1; }
.cc-box.box-missed   { border-left: 4px solid #0dcaf0; }
.cc-box.box-thin     { border-left: 4px solid #ffc107; }
.cc-box.box-spoiling { border-left: 4px solid #20c997; }
.cc-box.box-disliked { border-left: 6px solid #d63384; }
.cc-box.box-empty    { border-left: 4px solid #adb5bd; }

/* ── The legend ───────────────────────────────────────────────────────────── */

.cc-legend {
    margin: .75rem 0;
    font-size: .8rem;
}

.cc-legend-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem 1rem;
    margin-bottom: .35rem;
}

.cc-legend-heading {
    font-weight: 600;
}

.cc-swatch {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    white-space: nowrap;
}

.cc-swatch-dot {
    width: .75rem;
    height: .75rem;
    border-radius: 50%;
    border: 1px solid rgba(0, 0, 0, .25);
    flex: 0 0 auto;
}

.cc-swatch.pref-never  .cc-swatch-dot { background: #d63384; }
.cc-swatch.pref-less   .cc-swatch-dot { background: #ffc107; }
.cc-swatch.pref-ok     .cc-swatch-dot { background: #adb5bd; }
.cc-swatch.pref-more   .cc-swatch-dot { background: #6ea8fe; }
.cc-swatch.pref-love   .cc-swatch-dot { background: #198754; }

.cc-swatch.box-ok       .cc-swatch-dot { background: #198754; }
.cc-swatch.box-under    .cc-swatch-dot { background: #dc3545; }
.cc-swatch.box-over     .cc-swatch-dot { background: #fd7e14; }
.cc-swatch.box-short    .cc-swatch-dot { background: #6f42c1; }
.cc-swatch.box-missed   .cc-swatch-dot { background: #0dcaf0; }
.cc-swatch.box-thin     .cc-swatch-dot { background: #ffc107; }
.cc-swatch.box-spoiling .cc-swatch-dot { background: #20c997; }
.cc-swatch.box-disliked .cc-swatch-dot { background: #d63384; }
.cc-swatch.box-empty    .cc-swatch-dot { background: #adb5bd; }

/* ── Thumbnails ───────────────────────────────────────────────────────────── */

/* A produce box rendered as a spreadsheet is the loudest thing wrong with both competitors. Every item on
   every screen gets one of these, and a farm with no photos gets a letter rather than a hole. */
.cc-thumb {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    border-radius: .35rem;
    flex: 0 0 auto;
    background: var(--bs-secondary-bg, #e9ecef);
}

.cc-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.cc-thumb-sm { width: 2rem;   height: 2rem; }
.cc-thumb-md { width: 2.75rem; height: 2.75rem; }

/* A gallery tile, where the picture IS the content rather than a label beside one: it takes the width it
   is given and a fixed, modest height. Still a .cc-thumb, so a row whose image never uploaded shows the
   product's letters instead of a broken icon. */
.cc-thumb-tile {
    display: flex;
    width: 100%;
    height: 8.75rem;
}

.cc-thumb-tile .cc-thumb-initials { font-size: 1.5rem; }

.cc-thumb-initials {
    font-weight: 700;
    font-size: .75rem;
    color: #21252980;
    color: rgba(33, 37, 41, .75);
}

/* ── One box ──────────────────────────────────────────────────────────────── */

.cc-candidates {
    max-height: 22rem;
    overflow-y: auto;
}
