/* Every form in the product: the five things that can be made, and the reading
   that is written against a Key Result.

   One shape for all of them — the thing being made named at the top, the name
   of a field above the box it names, boxes that line up in columns, the button
   that writes on its own line, and a refusal in plain words directly under the
   field it belongs to. The classes are .form-*, because they are the form's and
   not the create form's; the .create-* names below are only about where a form
   is put on a screen. */

/* The shape ---------------------------------------------------------------- */

.form {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-5);
    width: 100%;
}

/* What is being made. The control that opened this form is gone the moment the
   form takes its place, and a tree holds Objectives and Key Results both, so
   without this there is nothing on screen saying which one is being written. */
.form-title {
    font-size: var(--text-md);
    font-weight: var(--weight-semibold);
    letter-spacing: -0.01em;
    color: var(--ink);
}

/* The fields stand in columns of one width, so their names line up down the
   form however many there are. A field that carries a list or a name takes the
   whole row. The block is bounded: a single box stretched across a wide screen
   leaves the field beside it stranded at the far edge. */
.form-fields {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    align-items: start;
    gap: var(--space-6) var(--space-5);
    width: 100%;
    max-width: 760px;
}

.form-field {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    min-width: 0;
    /* A fieldset carries browser chrome the rest of the fields do not. */
    margin: 0;
    padding: 0;
    border: 0;
}

.form-field[hidden] {
    display: none;
}

/* A name is the longest thing typed into any of these forms, so it is given two
   columns and the field beside it keeps the third. A list of things to tick, a
   description and the targets take the whole row. */
.form-field-wide {
    grid-column: span 2;
}

.form-field-span {
    grid-column: 1 / -1;
}

.form-field-line {
    display: flex;
    align-items: center;
    gap: var(--space-3);
}

/* Not a hint about how the product works — the unit the number is in. */
.form-field-suffix {
    font-size: var(--text-base);
    color: var(--ink-muted);
}

/* The controls ------------------------------------------------------------- */

.form .field-input,
.form .select {
    width: 100%;
}

/* A field a person types into stands taller than a control sitting in a row of
   other controls; tokens.css says so, and every box in a form takes that one
   height. The select is written for the toolbar, so it is given the field
   height and the field's ink here rather than a height of its own. */
.form .select {
    height: var(--field-height);
    color: var(--ink);
}

/* One focus ring, the product's, on every control in a form. login.css hand
   rolls two more for .field-input — one for a good box, one for a refused one —
   and the select next to it takes the token from base.css, so a form focuses
   three different ways. Both are answered here. Delete those two rules from
   login.css and all four lines below go with them. */
.form .field-input:focus {
    border-color: var(--line-strong);
    box-shadow: none;
}

.form .field-input:focus-visible {
    box-shadow: var(--focus-ring);
}

/* A box that was refused stays red, including while the keyboard is in it. */
.form .field-input[aria-invalid='true'],
.form .field-input[aria-invalid='true']:focus {
    border-color: var(--red);
    box-shadow: none;
}

.form .field-input[aria-invalid='true']:focus-visible {
    box-shadow: var(--focus-ring);
}

/* A field the state of the form has closed off: still named, still in its
   place, plainly not taking anything yet. */
.form .field-input:disabled,
.form .select:disabled {
    background: var(--surface-sunken);
    border-color: var(--line);
    color: var(--ink-faint);
}

/* A number, a date and a unit are read at a glance and are given the width they
   need, not the width of the column they sit in. */
/* A number is typed, not stepped. The browser's little arrows appear only on
   hover and focus, and while they are there they shove the figure sideways in
   a box that is read by its right edge. */
.form-number {
    max-width: 108px;
    text-align: right;
    appearance: textfield;
}

.form-number::-webkit-inner-spin-button,
.form-number::-webkit-outer-spin-button {
    appearance: none;
    margin: 0;
}

.form-date {
    max-width: 168px;
}

.form-unit {
    max-width: 150px;
}

/* A box for the one description in the product. It has no grip in its corner:
   a drag handle is a control, and dragging it does nothing the form needs. */
.form-text {
    height: auto;
    min-height: 66px;
    padding: var(--space-3) var(--space-4);
    line-height: var(--leading-normal);
    resize: none;
}

/* What was refused ---------------------------------------------------------
   Under the field it was refused for, in the product's words. Only what no
   field on the form owns is said above the button instead. */

.form-field-problem,
.form-problem {
    font-size: var(--text-sm);
    color: var(--red);
}

.form-field-problem:empty,
.form-problem:empty {
    display: none;
}

/* The box that was refused, not every box near it. A block of several lines —
   the targets — is not painted red from edge to edge: the sentence under it
   says which line, and the keyboard is already there. */
.form-field-wrong > .field-input,
.form-field-wrong > .select,
.form-field-wrong > .form-field-line > .field-input {
    border-color: var(--red);
}

/* A picker that was refused is marked the same way a box is. */
.form-field-wrong > .form-choice-list {
    border-color: var(--red);
}

/* Choosing several --------------------------------------------------------
   Ticking boxes, not a multi-select. Every choice is visible and reachable, and
   a long list scrolls inside itself rather than pushing Create off the screen. */

.form-choice-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
    gap: var(--space-1) var(--space-5);
    max-height: 152px;
    overflow-y: auto;
}

.form-choice {
    display: inline-flex;
    align-items: flex-start;
    gap: var(--space-3);
    font-size: var(--text-base);
    color: var(--ink-secondary);
    cursor: pointer;
    padding: var(--space-2) 0;
    min-width: 0;
}

.form-choice:has(:checked),
.form-choice:hover {
    color: var(--ink);
}

.form-choice-box {
    width: 14px;
    height: 14px;
    accent-color: var(--accent);
    margin: 0;
    /* On the line of the first row of the name, whether or not it wraps. */
    margin-top: 3px;
    flex: none;
}

/* The name is the whole of the choice, so it wraps rather than being cut. */
.form-choice-name {
    overflow-wrap: anywhere;
}

/* Targets ------------------------------------------------------------------
   One or several: 10 by 27 August, 30 by 30 September. The columns are named
   once at the top and every line below stands under them, with the unit beside
   the number so a line reads as the sentence it is. */

.form-targets {
    align-items: flex-start;
    gap: var(--space-3);
}

.form-target-rows {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    width: 100%;
}

/* The names and the lines under them share one set of columns, so a column name
   always stands over the box it names however wide the form is. The unit column
   is a fixed width: it must not resize the line as the unit is typed. */
.form-target-head,
.form-target-row {
    display: grid;
    grid-template-columns: 108px 92px 168px 28px;
    align-items: center;
    gap: var(--space-3);
    width: 100%;
}

.form-targets-paired .form-target-head,
.form-targets-paired .form-target-row {
    grid-template-columns: 108px 108px 92px 168px 28px;
}

/* No unit has been typed yet, so there is nothing for that column to hold and
   it is not held open. */
.form-targets-bare .form-target-head,
.form-targets-bare .form-target-row {
    grid-template-columns: 108px 168px 28px;
}

.form-targets-paired.form-targets-bare .form-target-head,
.form-targets-paired.form-targets-bare .form-target-row {
    grid-template-columns: 108px 108px 168px 28px;
}

.form-targets-bare .form-target-unit,
.form-targets-bare .form-target-name-unit {
    display: none;
}

.form-target-head {
    margin-bottom: calc(-1 * var(--space-1));
}

/* A column above a box is a field being named, so it is named the way every
   other field in the product is named. Casing must not depend on which form was
   opened: VALUE on the record panel and Value on the create panel of the same
   screen is two products. Everything .field-label does, plus the column's own
   alignment. */
.form-target-name {
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    letter-spacing: var(--tracking-caps);
    text-transform: uppercase;
    color: var(--ink-muted);
}

.form-target-name-date {
    padding-left: var(--space-1);
}

/* The unit the target counts, taken from the Unit field above. */
.form-target-unit {
    font-size: var(--text-base);
    color: var(--ink-muted);
    overflow-wrap: anywhere;
}

/* The same control, in the same size, with the same answer to being hovered and
   to being disabled, as the one on the block that changes these targets
   afterwards. A person learns the target block once. */
.form-target-remove {
    display: grid;
    place-items: center;
    width: 28px;
    height: 28px;
    border-radius: var(--radius-sm);
    color: var(--ink-faint);
    font-size: var(--text-md);
    line-height: 1;
    transition: background var(--duration) ease, color var(--duration) ease;
}

.form-target-remove:hover:not([disabled]) {
    background: var(--red-soft);
    color: var(--red);
}

/* One target is the least a Key Result can have, so while there is one it
   plainly cannot be taken away. */
.form-target-remove[disabled] {
    opacity: 0.35;
    cursor: default;
}

.form-target-add {
    align-self: flex-start;
}

/* Writing it ---------------------------------------------------------------
   The button that writes stands on its own line under everything it is about,
   in every form. */

.form-actions {
    display: flex;
    align-items: center;
    gap: var(--space-3);
}

/* Three weights, and no fourth. The button that writes is filled. A control
   that opens a form or adds a line to one is a button too, quieter — it does
   not write anything, but it is the only way to reach what it opens, so it
   cannot read as a line of grey text. Cancel and the control that takes a
   target away are plain: they undo, and undoing is never the loudest thing on
   a screen. */
.button-second {
    height: var(--field-height);
    padding: 0 var(--space-5);
    background: var(--surface);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    font-size: var(--text-base);
    font-weight: var(--weight-medium);
    color: var(--ink);
    transition: background var(--duration) ease, border-color var(--duration) ease;
}

.button-second:hover {
    background: var(--surface-hover);
    border-color: var(--ink-faint);
}

.button-quiet {
    height: var(--field-height);
    padding: 0 var(--space-4);
    border-radius: var(--radius);
    font-size: var(--text-base);
    color: var(--ink-secondary);
    transition: background var(--duration) ease, color var(--duration) ease;
}

.button-quiet:hover {
    background: var(--surface-hover);
    color: var(--ink);
}

/* Where a form is put ------------------------------------------------------
   Creating happens where the thing will live, at the URL it already has. */

.create-row {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    padding: var(--space-5) var(--space-6);
    border-top: 1px solid var(--line);
    background: var(--surface-sunken);
}

/* A form needs air around it; the one control that stands here when it is shut
   does not. */
.create-row:has(.create-form) {
    padding: var(--space-6);
}

/* Recording a reading ------------------------------------------------------
   The panel it stands in rules off its own heading and lists the readings
   underneath, so this takes the padding of a row in that list and is ruled off
   the same way. */

.reading {
    padding: var(--space-5) var(--space-6);
    border-bottom: 1px solid var(--line);
}

/* Two short fields, so they stand side by side rather than in the columns a
   form with six of them needs. */
.reading-fields {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: var(--space-4) var(--space-5);
}

/* A phone: one column, and controls at a size a thumb can hit. */
@media (max-width: 720px) {
    .create-row,
    .create-row:has(.create-form) {
        padding: var(--space-5);
    }

    .form-fields {
        grid-template-columns: minmax(0, 1fr);
        gap: var(--space-5);
    }

    .form-field-wide {
        grid-column: 1 / -1;
    }

    .form .field-input:not(.form-text),
    .form .select,
    .form .button-primary,
    .form .button-quiet,
    .button-second {
        height: var(--row-height);
    }

    .form-number,
    .form-date,
    .form-unit {
        max-width: none;
    }

    .form-target-head,
    .form-target-row {
        grid-template-columns: minmax(0, 1fr) 68px minmax(0, 1.3fr) 28px;
    }

    .form-targets-paired .form-target-head,
    .form-targets-paired .form-target-row {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 68px minmax(0, 1.2fr) 28px;
    }

    .form-targets-bare .form-target-head,
    .form-targets-bare .form-target-row {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr) 28px;
    }

    .form-targets-paired.form-targets-bare .form-target-head,
    .form-targets-paired.form-targets-bare .form-target-row {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.2fr) 28px;
    }

    .form-choice-list {
        grid-template-columns: minmax(0, 1fr);
        max-height: 220px;
    }

    .form-choice {
        padding: var(--space-3) 0;
    }

    .reading-fields {
        gap: var(--space-4) var(--space-5);
    }
}
