/* =============================================================================
   DEX CRM - KUDIO NEW FIELD DESIGN

   The notched outline: one rounded shape with the field's name written into
   its top edge and the border broken around the words. It replaces the
   label-above-a-box pattern, which spent a line of vertical space on every
   field and let the name drift away from its control in dense two-column
   layouts.

   The label never animates and never doubles as a placeholder. A form scanned
   at a glance still has to say what each box is when every box is full, which
   is the one thing a Material floating label stops doing.

   Introduced on the Checkout settings screens and meant to spread from there,
   so it lives in its own stylesheet rather than beside any one screen. Every
   colour, radius, spacing and size below is an existing token.
   ============================================================================= */

/* A fieldset is the only element whose border a browser will break by itself -
   the legend inside it cuts the notch natively. The alternative is painting a
   strip of background colour over the line, and that lie shows the moment the
   field sits on any surface other than the one it was tuned against. */
.kudio-field {
    display: block;
    min-inline-size: 0;
    margin: 0;
    /* The outline supplies its own vertical space, so the control inside is
       shorter than a standalone one - otherwise every field stands a third
       taller than the rest of the app's controls for no reason. */
    padding: 0 11px 4px;
    border: 1px solid var(--border-strong);
    /* Nearly square. The label is written into the top edge, so that edge has
       to read as a ruled line with a gap in it - a 10px corner curves away
       under the notch's own inset and turns the outline back into a bubble. */
    border-radius: var(--radius-tiny);
    background: var(--surface-panel);
    transition:
        border-color var(--duration-instant) var(--easing-standard),
        background var(--duration-instant) var(--easing-standard);
}

/* The notch is exactly as wide as the legend, so this padding is the gap either
   side of the words rather than a number tuned against them. */
.kudio-field__legend {
    width: auto;
    /* Label and value share a left edge, which is the whole point of writing
       the name into the border: the eye should be able to run one line down a
       column of fields. The value starts at the fieldset's padding edge, and
       the legend's own padding would otherwise start the words 5px further in,
       so the same 5px is taken back off the margin. The gap either side of the
       words is untouched - it now opens to the LEFT of the left-hand corner
       inset instead of pushing the text right. */
    margin-inline-start: -5px;
    /* Not negative, ever. A browser paints the block-start border through the
       centre of the legend's MARGIN box, so pulling the margin up does not lift
       the words onto the line - it drops them half the margin BELOW it and
       hauls the control up underneath them. Zero is what makes the label
       straddle the border and leaves the control its own space. */
    margin-block-end: 0;
    padding: 0 5px;
    /* The height that negative margin used to claw back comes out of the strut
       instead. The legend inherited the base size to hold a label set at the
       tiny one, reserving a band of empty line nobody could see. */
    font-size: var(--font-size-tiny);
    line-height: 1;
}

/* Every selector below that names the control or the label is written as a
   descendant of `.kudio-field` rather than on its own. It has to be: a swept
   legacy field keeps its `.form-field__label` and `.form-field__control`
   classes so the screens' own queries still find it, and several stylesheets
   aim two-class rules at those - `.form-section .form-field__control` sets a
   34px height, `.cal-event-form .form-field__label` a 5px margin. A one-class
   rule here loses to both and the notch quietly comes apart. */
.kudio-field .kudio-field__label {
    /* Inline, so the legend keeps its own line box and a swept legacy field
       stands exactly as tall as one built by `DEX.KudioField.field`. As a
       block - which is what `.form-field__label` makes it - the legend shrinks
       to the cap height of the words and the outline comes up short of the
       buttons beside it, on swept screens only. */
    display: inline;
    margin: 0;
    /* The legend's band is now one tiny line and nothing more, and the label is
       the tallest thing in it, so any inherited line-height would be added to
       every field's height rather than to the label's alone. */
    line-height: 1;
    font-size: var(--font-size-tiny);
    font-weight: 500;
    color: var(--text-muted);
    cursor: pointer;
}

/* Required marks the label, not the value - the value is the customer's. */
.kudio-field__required {
    margin-left: 2px;
    color: var(--status-danger);
}

/* Larger than the label, and carrying no border of its own: the outline around
   the whole fieldset is the field's only edge. */
.kudio-field .kudio-field__control {
    display: block;
    width: 100%;
    height: 28px;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    font: inherit;
    font-size: var(--font-size-base);
    color: var(--text-primary);
    outline: 0;
}

.kudio-field .kudio-field__control::placeholder {
    color: var(--text-muted);
}

.kudio-field textarea.kudio-field__control {
    height: auto;
    min-height: 58px;
    padding: 2px 0;
    line-height: 1.55;
    resize: vertical;
}

/* The caret stays inside the outline on the right, so the select reads as the
   same one shape as every other field rather than a box with a widget on it. */
.kudio-field select.kudio-field__control {
    appearance: none;
    cursor: pointer;
    padding-right: 22px;
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%238b929b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0 center;
}

/* Thickening the border would push everything below it down by a pixel, so the
   extra width is taken back out of the padding and the box does not budge. Only
   three sides need paying for: the block-start border is drawn inside the
   legend's band, which is taller than either border width, so it costs the
   same nothing at 1px and at 2px. */
.kudio-field:focus-within {
    border-color: var(--accent);
    border-width: 2px;
    padding: 0 10px 3px;
}

.kudio-field:focus-within .kudio-field__label {
    color: var(--accent);
}

/* `.form-field__control--invalid` is how every legacy screen marks a field it
   has just rejected, added and removed long after the sweep has run - so the
   error state is read off the control rather than off a class somebody would
   have to remember to put on the fieldset as well. */
.kudio-field--error,
.kudio-field--error:focus-within,
.kudio-field:has(.form-field__control--invalid) {
    border-color: var(--status-danger);
}

.kudio-field--error .kudio-field__label,
.kudio-field--error:focus-within .kudio-field__label,
.kudio-field:has(.form-field__control--invalid) .kudio-field__label {
    color: var(--status-danger);
}

/* Dashed rather than merely paler: "you cannot type here" has to survive being
   read by somebody who does not see the colour change. */
.kudio-field:has(.kudio-field__control:disabled),
.kudio-field:has(.kudio-field__control[readonly]),
.kudio-field--read-only {
    border-style: dashed;
    background: var(--surface-subtle);
}

.kudio-field:has(.kudio-field__control:disabled) .kudio-field__label,
.kudio-field:has(.kudio-field__control[readonly]) .kudio-field__label,
.kudio-field--read-only .kudio-field__label {
    color: var(--text-muted);
}

.kudio-field .kudio-field__control:disabled {
    color: var(--text-muted);
    cursor: not-allowed;
}

/* `.form-section .form-field__control[readonly]` paints its own grey box, which
   inside the outline reads as a field within a field. */
.kudio-field .kudio-field__control[readonly] {
    background: transparent;
}

/* Helper text belongs below the outline, never inside it - inside, it competes
   with the value for the one line the eye is meant to land on. */
.kudio-field-group {
    display: block;
    min-width: 0;
}

.kudio-field-hint {
    margin: 5px 2px 0;
    font-size: var(--font-size-tiny);
    line-height: 1.5;
    color: var(--text-muted);
}

.kudio-field-error {
    margin: 5px 2px 0;
    font-size: var(--font-size-tiny);
    font-weight: 500;
    line-height: 1.5;
    color: var(--status-danger);
}

.kudio-field-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 14px;
}

.kudio-field-group--full {
    grid-column: 1 / -1;
}


/* =============================================================================
   SWEPT LEGACY FIELDS

   `DEX.KudioField.upgrade` moves the control of an old `.form-field` inside a
   fieldset without discarding either the wrapper or its classes, so the shape
   is right but a handful of the old rules still land on the parts. These are
   the ones that would show. Nothing here is per screen - it is the same three
   legacy classes wherever they appear.
   ============================================================================= */

/* The old markup put the whole field on a stack with a gap under the label. The
   legend supplies that relationship now, so the leftover margin only pushes the
   value away from the outline it belongs to. */
.form-field[data-kudio-field] > .kudio-field {
    margin-bottom: 0;
}

/* Two outlines stacked flush read as one block. The old field separated itself
   without help - a line of small grey text over a control is its own gap - but
   a box has an edge, and an edge needs air around it.

   A grid spaces the fields inside it and not the row of them, so the four
   combinations of a lone field and a grid of them all need the same margin;
   naming them as one `:is()` pair keeps that a single number to change. */
.form-section >
    :is(.form-field[data-kudio-field], .form-grid) +
    :is(.form-field[data-kudio-field], .form-grid) {
    margin-top: 12px;
}

/* A read-only value drew its own dashed box. Inside the outline that is a
   second border around the same thing, so the fieldset takes the dashes
   (`.kudio-field--read-only`) and the box gives them up. */
.kudio-field .form-field__readonly-value {
    height: 28px;
    padding: 0;
    border: 0;
    background: transparent;
}

/* iOS zooms the page in whenever a focused control is under 16px, and
   components.css guards against it with a one-class rule that the two-class
   rules above now outrank. Restated here so the guard survives the sweep. */
@media (max-width: 560px) {
    .kudio-field .kudio-field__control {
        font-size: 16px;
    }
}
