/*
 * Form: the design system's form pattern (.shop-form) - a column of fields,
 * each a label, its input, and help text tied to it with aria-describedby; a
 * checkbox with its label; the actions. Scoped to .shop-form, so none of it
 * reaches the legacy forms elsewhere, which keep Foundation's field styles
 * until they are migrated onto this. The inputs themselves are still rendered
 * by formItem() (framework/commonHelpers.php), which keeps their names and
 * validation; this only sets their look. First used by the withdrawal form.
 *
 * input./textarea. qualify the class so it beats base.css's element rules
 * (Decision 5).
 */

/* Text after the form (the legal page runs on) starts clear of the button. */
.shop-form {
    margin-block-end: var(--shop-space-6);
}

.shop-form form {
    display: grid;
    gap: var(--shop-space-5);
    max-width: 32rem;
    margin: 0;
}

.shop-form__field {
    display: grid;
    gap: var(--shop-space-2);
}

.shop-form__label {
    color: var(--shop-ink);
    font-size: var(--shop-text-base);
    font-weight: var(--shop-weight-semibold);
    line-height: var(--shop-leading-snug);
}

.shop-form__optional {
    color: var(--shop-text-soft);
    font-weight: normal;
}

/* .shop-form-qualified: the form usually sits inside .cms-prose, whose
   paragraph margins would otherwise space the help text. */
.shop-form .shop-form__help {
    margin: 0;
    color: var(--shop-text-soft);
    font-size: var(--shop-text-md);
    line-height: var(--shop-leading-snug);
}

/* 16px text so iOS does not zoom on focus; a 48px field, the design's field
   border and radius. */
input.shop-form__input,
textarea.shop-form__input {
    box-sizing: border-box;
    width: 100%;
    min-height: 48px;
    margin: 0;
    padding: var(--shop-space-3);
    border: 1px solid var(--shop-border-input);
    border-radius: var(--shop-radius-md);
    background: var(--shop-surface);
    box-shadow: none;
    color: var(--shop-ink);
    font-family: var(--shop-font);
    font-size: var(--shop-text-base);
    line-height: var(--shop-leading-snug);
    /* Foundation fades border and shadow over 0.45s; the focus ring is instant. */
    transition: none;
}

textarea.shop-form__input {
    min-height: 7.5rem;
    resize: vertical;
}

/* An order number is short; a full-width field would say otherwise. */
input.shop-form__input--short {
    max-width: 14rem;
}

input.shop-form__input:focus,
textarea.shop-form__input:focus {
    border-color: var(--shop-accent);
    outline: 2px solid var(--shop-accent);
    outline-offset: 0;
    background: var(--shop-surface);
    /* Foundation gives some input types (email among them) a grey focus glow. */
    box-shadow: none;
}

input.shop-form__input:disabled,
textarea.shop-form__input:disabled {
    background: var(--shop-surface-subtle);
    color: var(--shop-text-soft);
}

/* formItem() renders the checkbox and its <label> as siblings: box first, the
   label beside it, wrapping under itself rather than under the box. Element
   selectors here (and on the form) because formItem()/formHeader() cannot
   put classes on them. */
.shop-form__check {
    display: flex;
    align-items: flex-start;
    gap: var(--shop-space-3);
}

.shop-form__check input[type="checkbox"] {
    flex: none;
    width: 20px;
    height: 20px;
    margin: 2px 0 0;
    accent-color: var(--shop-accent);
}

.shop-form__check input[type="checkbox"] + label {
    /* Foundation's checkbox + label margins, answered at their weight. */
    margin: 0;
    color: var(--shop-text);
    font-size: var(--shop-text-base);
    line-height: var(--shop-leading-snug);
    cursor: pointer;
}

.shop-form__check input[type="checkbox"]:focus-visible {
    outline: 2px solid var(--shop-accent);
    outline-offset: 2px;
}

.shop-form__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--shop-space-3);
}

/* ---------------------------------------------------------------------------
   Grown for the checkout (Decision 24). Everything below is still scoped to
   .shop-form, so the withdrawal form keeps exactly the look it had: it uses
   none of these classes.
   --------------------------------------------------------------------------- */

/* A group of fields that answer one question, as a real fieldset. Foundation
   gives legend a margin and a border and fieldset a padded box; both are
   answered here rather than relied on. */
.shop-form__group {
    margin: 0;
    padding: 0;
    border: 0;
}

.shop-form__legend {
    /* Foundation sets legend's margin-bottom and background; a legend also
       cannot be a grid item, so the spacing lives on it. */
    margin: 0 0 var(--shop-space-3);
    padding: 0;
    background: none;
    color: var(--shop-ink);
    font-size: var(--shop-text-base);
    font-weight: var(--shop-weight-semibold);
    line-height: var(--shop-leading-snug);
}

/* Fields that belong on one line where there is room: the two halves of a
   name, an e-mail address and a telephone number. Below 640px they stack. */
.shop-form__row {
    display: grid;
    /* Stacked, the fields are as far apart as any two in the card. */
    gap: var(--shop-space-5);
}

/* A postcode and a house number are both short, so they share a line at every
   width - at 320px each still has room for anything typed in it, and on a
   phone they are the pair people expect side by side. A postcode is shorter
   than a house number with its addition, but not by much: two fifths against
   three, so neither gets room it cannot use. */
.shop-form__row--uneven {
    grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
    column-gap: var(--shop-space-3);
}

@media (min-width: 640px) {
    .shop-form__row {
        grid-template-columns: repeat(var(--shop-form-row-columns, 2), minmax(0, 1fr));
        column-gap: var(--shop-space-4);
    }

    .shop-form__row--uneven {
        grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
    }
}

/* Two fields side by side keep their parts on the same lines: label with label,
   field with field, message with message. Without this, a message that wraps in
   the narrower column (a postcode's, at the widths where that column is around
   220px) pushes only its own field and the pair goes ragged. The fields keep
   their own 8px rhythm; only the alignment comes from the row. */
@supports (grid-template-rows: subgrid) {
    .shop-form__row--uneven {
        grid-template-rows: auto auto auto;
        row-gap: 0;
        align-items: start;
    }

    .shop-form__row--uneven > .shop-form__field {
        grid-row: span 3;
        grid-template-rows: subgrid;
        row-gap: 0;
    }

    /* A subgrid track exists even while its message is empty, and a row gap
       beside it would still count: the pair then sat 12px further from the
       next field than any other two fields. The 8px lives on the parts. */
    .shop-form__row--uneven .shop-form__label {
        margin-block-end: var(--shop-space-2);
    }

    .shop-form__row--uneven .shop-form__error:not(:empty) {
        margin-block-start: var(--shop-space-2);
    }

    @media (min-width: 640px) {
        .shop-form__row {
            grid-template-rows: auto auto auto;
            row-gap: 0;
            align-items: start;
        }

        .shop-form__row > .shop-form__field {
            grid-row: span 3;
            grid-template-rows: subgrid;
            row-gap: 0;
        }

        .shop-form__row .shop-form__label {
            margin-block-end: var(--shop-space-2);
        }

        .shop-form__row .shop-form__error:not(:empty) {
            margin-block-start: var(--shop-space-2);
        }
    }
}

/* The select the country is chosen from. Foundation styles `select` at (0,0,1)
   with its own arrow and height, so this names the element too (Decision 5).
   appearance: none drops the platform arrow; the chevron is drawn here so the
   field matches the text inputs beside it. */
select.shop-form__input {
    box-sizing: border-box;
    width: 100%;
    min-height: 48px;
    margin: 0;
    padding: var(--shop-space-3);
    padding-inline-end: var(--shop-space-8);
    border: 1px solid var(--shop-border-input);
    border-radius: var(--shop-radius-md);
    background-color: var(--shop-surface);
    /* A chevron, as the disclosures use, drawn in the ink colour. */
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%231e1b4b' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 6 8 10.5 12.5 6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right var(--shop-space-3) center;
    background-size: 16px 16px;
    box-shadow: none;
    color: var(--shop-ink);
    font-family: var(--shop-font);
    font-size: var(--shop-text-base);
    line-height: var(--shop-leading-snug);
    appearance: none;
}

select.shop-form__input:focus {
    border-color: var(--shop-accent);
    outline: 2px solid var(--shop-accent);
    outline-offset: 0;
    box-shadow: none;
}

/* A choice out of a few: one card per option, the whole card the control. The
   label wraps its input, so the card is the target - 48px tall at least, which
   is also what a thumb needs. */
.shop-form__choices {
    display: grid;
    gap: var(--shop-space-3);
    margin: 0;
    padding: 0;
    border: 0;
    list-style: none;
}

.shop-form__choice {
    display: flex;
    align-items: flex-start;
    gap: var(--shop-space-3);
    min-height: 48px;
    padding: var(--shop-space-3) var(--shop-space-4);
    border: 1px solid var(--shop-border);
    border-radius: var(--shop-radius-md);
    background: var(--shop-surface);
    color: var(--shop-ink);
    font-size: var(--shop-text-base);
    line-height: var(--shop-leading-snug);
    cursor: pointer;
}

/* The radio keeps its own semantics and its own focus ring; it is only made
   big enough to hit. */
.shop-form__choice input[type="radio"],
.shop-form__choice input[type="checkbox"] {
    flex: none;
    width: 20px;
    height: 20px;
    /* Optically centred on the first line of the label beside it. */
    margin: 1px 0 0;
    accent-color: var(--shop-accent);
}

/* The chosen option carries the accent, so the choice survives a screenshot in
   greyscale as well as in colour: border, tint and a bolder title. */
.shop-form__choice:has(input:checked) {
    border-color: var(--shop-accent);
    background: var(--shop-accent-soft);
}

.shop-form__choice:has(input:checked) .shop-form__choice-title {
    font-weight: var(--shop-weight-semibold);
}

.shop-form__choice:hover {
    border-color: var(--shop-accent);
}

/* The ring belongs to the card, not to the 20px circle, so it is visible at a
   glance while the keyboard walks the group. */
.shop-form__choice:has(input:focus-visible) {
    outline: 2px solid var(--shop-accent);
    outline-offset: 2px;
}

/* The card carries the ring; the 20px control inside it would draw a second,
   square one around the circle. */
.shop-form__choice input:focus-visible {
    outline: none;
}

/* White, not the lavender subtle surface: beside the chosen card's tint that
   read as a second selection. The quiet text and logo say "unavailable". */
.shop-form__choice:has(input:disabled) {
    border-color: var(--shop-border);
    background: var(--shop-surface);
    color: var(--shop-text-soft);
    cursor: default;
}

.shop-form__choice-body {
    display: grid;
    gap: var(--shop-space-1);
    min-width: 0;
}

.shop-form__choice-title {
    display: flex;
    align-items: center;
    gap: var(--shop-space-2);
    flex-wrap: wrap;
}

.shop-form__choice-note {
    color: var(--shop-text-soft);
    font-size: var(--shop-text-md);
}

/* Two or three options that are one decision (deliver or collect): side by
   side from 640px, stacked below it. */
@media (min-width: 640px) {
    .shop-form__choices--inline {
        grid-auto-flow: column;
        grid-auto-columns: minmax(0, 1fr);
    }
}

/* A question answered in a word (Dhr. / Mevr.): each card as wide as its
   words need, side by side at every width, and never narrower than a thumb
   can comfortably hit. */
.shop-form__choices--compact {
    display: flex;
    flex-wrap: wrap;
}

.shop-form__choices--compact .shop-form__choice {
    /* Two fit beside each other in a 320px phone's card (2 x 112 + 12). */
    min-width: 7rem;
    align-items: center;
}

.shop-form__choices--compact .shop-form__choice input[type="radio"] {
    margin-block-start: 0;
}

/* Invalid ------------------------------------------------------------------
   Keyed on aria-invalid, the attribute the field carries for assistive
   technology anyway, so the colour is never the only signal: the message below
   the field says what is wrong, and the field is named in the summary at the
   top of the form.

   Its own colour, not the amber of a warning notice: on this surface amber is
   the summary's voice ("please check these"), and a single field saying "this
   one is wrong" is a different thing. Purple stays what it has always been -
   focus and choice - so an invalid field that is focused keeps the purple ring
   and the red edge, and says both at once.

   (The site-wide form-validation.js marks [data-invalid] and the legacy .error
   class instead; a form on this pattern does not carry data-abide, so the two
   conventions never meet.) */
input.shop-form__input[aria-invalid="true"],
select.shop-form__input[aria-invalid="true"],
textarea.shop-form__input[aria-invalid="true"] {
    border-color: var(--shop-error-border);
    border-width: 2px;
}

input.shop-form__input[aria-invalid="true"]:focus,
select.shop-form__input[aria-invalid="true"]:focus,
textarea.shop-form__input[aria-invalid="true"]:focus {
    border-color: var(--shop-error-border);
    /* A valid field turns purple on focus, so the ring sits flush against it
       and the two read as one edge (the rule above). Here the border stays red,
       so the ring is given back the 2px the rest of the surface uses: a hair of
       white between the purple and the red, and each says its own thing. */
    outline-offset: 2px;
}

.shop-form__error {
    display: flex;
    align-items: flex-start;
    gap: var(--shop-space-2);
    margin: 0;
    color: var(--shop-error-text);
    font-size: var(--shop-text-md);
    font-weight: var(--shop-weight-semibold);
    line-height: var(--shop-leading-snug);
}

/* The "!" that says as much as the colour does. */
.shop-form__error::before {
    content: "!";
    display: grid;
    place-items: center;
    flex: none;
    width: 1.125rem;
    height: 1.125rem;
    border-radius: 50%;
    background: var(--shop-error-text);
    color: var(--shop-surface);
    font-size: 0.8125rem;
    line-height: 1;
}

/* A field the customer has not reached yet has no message; the element stays in
   the grid so nothing jumps when one appears. */
.shop-form__error:empty {
    display: none;
}

/* A link in the form's own text - the conditions the consent box points at.
   Same reason and same states as the notice's: combined.css's legacy purple
   otherwise wins. A link styled as a button keeps its own colour. */
.shop-form a:not(.shop-btn),
.shop-form a:not(.shop-btn):visited {
    color: var(--shop-accent);
}

.shop-form a:not(.shop-btn):hover,
.shop-form a:not(.shop-btn):focus {
    color: var(--shop-accent-strong);
}
