@import '../mixins';
@import 'tw';

/*
 * The settings list, shared by every platform screen.
 *
 * What it replaces: thirteen identical rows in one flat column, each with a
 * sentence underneath restating its own label - "Recurring Meeting / Enable
 * recurring meeting.", "Timezone / Meeting Timezone." - and a Save button a
 * thousand pixels below the switch you just flipped. 168 words to show 13
 * switches.
 *
 * Three ideas replace it:
 *
 * 1. The label is the description. A row that needs a sentence has the wrong
 *    label, so the labels were rewritten and the sentences deleted.
 * 2. Three groups, never more. Thirteen choices in one column is thirteen
 *    decisions; three groups of four or five is three.
 * 3. Save comes to you. The bar appears only once something has changed, and
 *    confirms in place when it is done.
 *
 * Surfaces follow Tailwind: slate neutrals, `ring-1 ring-slate-900/6` in place
 * of a grey border, `shadow-sm`, `rounded-2xl`, and the 4px spacing grid.
 */

/* ------------------------------------------------------------------ group -- */

/*
 * The column these sit in.
 *
 * Unconstrained they ran the full page, which put a toggle roughly 1300px from
 * its own label - two columns of unrelated things rather than one row you read
 * across. The heading, the card and the save bar all share the measure so the
 * left edge is a single line down the screen.
 */
.gmt-sl-group,
.gmt-cred {
    max-width: 100%;
}

.gmt-sl-group {
    box-sizing: border-box;

    /* One gap between cards, whichever kind of card it is. Connect spaced its
       two 12px apart and Configuration spaced its three 26px, so the same page
       had two rhythms depending on which tab you were standing on. */
    + .gmt-sl-group {
        margin-top: 20px;
    }

    * {
        box-sizing: border-box;
    }
}

/*
 * The group's head row, and the credential card's head row, are the same row:
 * 48px, 12px by 16px, a 14px semibold name at the left. It was a 12px
 * uppercase label floating above the card on the page ground, which is a
 * second card grammar on a screen that only needs one.
 */
/*
 * Name over summary, on the card's own white.
 *
 * Two things were wrong. The pair sat on one baseline, so a heading read as one
 * long run - "Server-to-Server OAuth Lets GoodMeet create meetings on your
 * Zoom account. Required" - with no rank between the name and the sentence
 * explaining it. And the band was tinted, which is the grammar of a table
 * header: it made every card look like it was about to list records.
 *
 * Stacked, the size and colour do the ranking, and the room above and below
 * does the separating that the tint was hired for. A grey bar is what you reach
 * for when the type is not carrying its own hierarchy.
 */
.gmt-sl-group__head {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 3px;
    padding: 18px 18px 16px;
}

/*
 * What the group governs, beside its name.
 *
 * Deliberately the same size, colour and placement as `.gmt-cred__summary` on
 * the credential cards: one screen, two kinds of card, one way of introducing
 * a section. Wraps to its own line before it would squeeze the title.
 */
.gmt-sl-group__summary,
.gmt-cred__summary {
    margin: 0;
    color: $slate-500; /* 4.76:1 on white - a caption, not a second heading. */
    font-family: $font-sans;
    font-size: 13px;
    font-weight: 400;
    line-height: 19px;
}

.gmt-sl-group__title {
    margin: 0;
    font-family: $font-sans;

    /* A step above the row labels under it, which are $text-sm. Without that
       step the card had two 14px semibold voices and no first among them. */
    font-size: 16px;
    font-weight: 700;
    line-height: $text-base-lh;
    letter-spacing: -0.01em;
    color: $slate-900; /* 17.9:1 on the card. */
}

/*
 * The hairline under the head, drawn inset so it adds no width - the same one
 * a credential card draws under its own.
 *
 * The body used to carry no padding at all, which left the rows flush against
 * both ends of the card they sit in: the first switch started 12px under the
 * divider and the last one finished 8px off the card's bottom edge, while the
 * head above it was padded 18 and 16. One half of the card breathing and the
 * other half not is what reads as odd, and it is why the group looked squeezed
 * even though every row inside it was correctly spaced.
 *
 * The rows keep their own 10px, so these numbers are what is added to it: 20px
 * of air under the divider, 22px under the last control. A shade more at the
 * bottom than the top, because a block sitting on an edge needs slightly more
 * beneath it than above it to look centred.
 */
.gmt-sl-group__body {
    /* The rows carry 10px of their own, so these are the remainder. */
    padding: ($card-ink-top - 10px) 0 ($card-ink-bottom - 10px);
    box-shadow: inset 0 1px 0 $slate-100;
}

/*
 * A ring rather than a border. It is the page's own ink at 6%, so it reads as
 * the edge of a surface instead of as a grey line drawn on top of one - which
 * is most of why a Tailwind card looks lighter than a bordered one.
 */
.gmt-sl-group__rows {
    border: 0;
    border-radius: $radius-panel;
    background: #fff;
    box-shadow: $panel-shadow;
    overflow: hidden;
}

/* -------------------------------------------------------------------- row -- */

/*
 * Label left, control right, on one line. The old row put the control in a 70%
 * column starting at the 30% mark, so on a 1200px panel the switch sat 360px
 * from its own label with nothing in between.
 */
/*
 * One width for every control that takes typed or chosen input.
 *
 * It was declared here and then not used: the selects and the settings-tab
 * password fields kept their own 320px, so a text field on Connect measured 340
 * and a select on Configuration measured 320 - close enough to look like a
 * mistake and far enough to be one.
 *
 * A text field measured 744px on Connect while a select measured 320 on
 * Configurations, so the same card family spoke two different grammars. This is
 * the single number both now use; switches and buttons keep their own size,
 * because they are not fields.
 */
:root {
    --gmt-control-w: 340px;
}

/*
 * Below 600px the label sits above its control.
 *
 * The grid's label track is minmax(0, 420px), so on a phone it gave way to the
 * control and collapsed to a few pixels: "Event status" broke one letter per
 * line and the segmented controls ran past the card edge.
 */
@media ( max-width: 600px ) {
    /* Doubled class: this block sits above the base rule, so it needs the weight. */
    .gmt-sl-group .gmt-form-group.gmt-form-group {
        grid-template-columns: minmax( 0, 1fr );
        gap: 8px;
    }

    .gmt-sl-group .gmt-form-group.gmt-form-group > label {
        width: auto !important;
    }

    .gmt-sl-group .gmt-form-group .input-wrapper {
        flex-wrap: wrap;
        max-width: 100%;
    }

    /* A field fills the row; the switch and Pro badge keep their own size. */
    .gmt-sl-group .gmt-form-group .input-wrapper > .gmt-tw:not(.select-pro):not(:has(.gmt-seg)) {
        flex: 1 1 100%;
    }

    /* Fields are sized off this; 340px ran past a phone card. */
    .gmt-sl-group {
        --gmt-control-w: 100%;
    }
}

/* A locked row is pressable along its whole length, so it says so. */
.gmt-sl-group .gmt-form-group.is-locked {
    cursor: pointer;
}

.gmt-sl-group .gmt-form-group {
    /*
     * Label, control, then slack - in that order, and the slack is a real
     * column rather than the gap between two ends.
     *
     * This was `space-between` across the card full width, which put a two
     * word label at one end and a 44px switch at the other with, measured, a
     * median of 714px of nothing between them. Twenty-two rows of that is a
     * page you cannot scan: by the time the eye reaches the switch it has lost
     * which row it started on, which is how the wrong setting gets toggled.
     *
     * Capping the label column also aligns every control on one x, so the
     * switches read as a column instead of a ragged edge.
     */
    display: grid;
    grid-template-columns: minmax(0, 420px) auto minmax(0, 1fr);
    align-items: center;
    gap: 20px;
    width: 100%;
    min-height: 44px;
    margin: 0;

    /* Vertical padding does the separating the hairline used to do. Rows sit
       flat: no hover tint, the controls carry their own hover. */
    padding: 10px 18px;

    > label {
        display: flex;
        align-items: baseline;
        flex-wrap: wrap;
        /* 8px between a label and its hint mark; 0 between lines, so a
           description that wraps onto its own line sits under the label
           instead of 11px below it. */
        gap: 0 8px;
        width: auto !important;
        margin: 0;
        font-family: $font-sans;
        font-size: $text-sm;
        font-weight: 400;
        line-height: $text-sm-lh;
        letter-spacing: 0;
        color: $slate-900; /* 17.85:1 on white. */
        cursor: default;

        /*
         * What the setting does, under its name.
         *
         * This was the exception, for the rare row whose label could not carry
         * itself. It is the rule now: a two word label and a switch, measured
         * across a row, told the reader nothing about what the switch would do
         * and left the row with nothing in it but space.
         */
        small.description {
            flex-basis: 100%;
            margin-top: 3px;

            /* 12.5px, the size the guide's step detail already uses for the
               same job - a line explaining the thing above it. $text-xs is
               12px, and 12 against 12.5 is a difference nobody can see and
               every stylesheet has to carry. */
            font-size: 12.5px;
            font-weight: 400;
            line-height: 18px;
            color: $slate-500;
        }
    }

    > .input-wrapper {
        display: flex;
        align-items: center;

        /* Its own column start, so a switch, a select and a text field all
           begin on the same x down the page. */
        justify-content: flex-start;
        gap: 12px;
        flex: none;
        width: auto;
        max-width: var(--gmt-control-w);
    }
}

/* ----------------------------------------------------------------- switch -- */

/*
 * 44x24, the proportions every modern switch has settled on, with the whole
 * track as the target. It used to be a 56x28 grey slab with a 2px border and no
 * colour when on, so a screen of them said nothing at a glance about which were
 * which.
 *
 * Specificity: the dashboard stylesheet carries
 * `.gmt-form-group .input-wrapper .gmt-switch-field` at (0,3,0), so anything
 * shorter than this silently loses and the switch computes `display: block`.
 */
.gmt-sl-group .gmt-form-group .input-wrapper .gmt-switch-field {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    position: relative;

    input[type="checkbox"] {
        /*
         * The dashboard stylesheet hides this with `display: none !important`,
         * which takes every switch in the plugin out of the tab order: they
         * could only ever be operated with a pointer. Kept invisible, but
         * present, so the control is focusable and the label it drives can show
         * a focus ring.
         */
        display: block !important;
        position: absolute;

        /*
         * 44x24 drawn on the label, 44x44 to hit - and the reach lives here,
         * on the input, because this element is `opacity: 0` and therefore
         * cannot paint whatever a foreign stylesheet decides to give it.
         *
         * It was briefly a `label::after`, which is a contested pseudo-element
         * on this page: something in the admin gives it a grey box-shadow and a
         * 50% radius, so the invisible hit area rendered as a grey pill hanging
         * off the bottom of every switch. That is what the `content: none`
         * below has always been for.
         */
        top: 50%;
        left: 0;
        width: 44px;
        height: 44px;
        transform: translateY(-50%);
        z-index: 1;
        margin: 0;
        opacity: 0;
        cursor: pointer;

        + label {
            display: block;
            position: relative;

            /*
             * 44x24 drawn, 44x44 to hit.
             *
             * The drawn switch is 24px tall, which clears WCAG 2.5.8 at AA and
             * nothing else: it is a small target for a pointer and a genuinely
             * hard one on a touchscreen, and there are nine of them stacked
             * down this card. The reach comes from a pseudo-element so the row
             * metrics do not move an inch, the same way the hint mark does it.
             */
            width: 44px !important;
            height: 24px;

            /* Nothing here. The admin styles this pseudo-element with a grey
               shadow and a round corner, and the switch draws its own knob in
               ::before, so the only correct value is none. */
            &::after {
                content: none;
            }
            margin: 0;
            padding: 0;
            border: 0;
            border-radius: $rounded-full;
            background: $slate-200;
            /*
             * The boundary, since the fill cannot be one: slate-200 on a white
             * card is 1.19:1 and WCAG 1.4.11 asks 3:1 of a control edge. The
             * ring composites to 3.3:1.
             */
            box-shadow: inset 0 0 0 1px rgba(15, 23, 42, 0.45);
            cursor: pointer;
            transition: background-color $dur $ease, box-shadow $dur $ease;

            /* The knob. */
            &::before {
                content: '';
                position: absolute;
                top: 2px;
                left: 2px;
                width: 20px;
                height: 20px;
                border-radius: 50%;
                background: #fff;
                box-shadow: 0 1px 2px rgba(15, 23, 42, 0.25), 0 0 0 0.5px rgba(15, 23, 42, 0.04);
                transition: transform $dur $ease;
            }

        }

        &:hover + label {
            background: $slate-300;
        }

        &:checked + label {
            background: $blue-600;
            /* The fill is 5.17:1 against the card, so it is its own boundary. */
            box-shadow: none;

            &::before {
                transform: translateX(20px);
            }
        }

        &:checked:hover + label {
            background: $blue-700;
        }

        /* Keyboard only. A ring on every mouse click reads as a stuck state. */
        &:focus-visible + label {
            @include tw-ring-focus;
        }

        /*
         * A disabled input still sits on top of the switch it hides behind, and
         * a disabled control absorbs a click without firing one - so with the
         * 44px reach on this element, aiming at a Pro toggle hit nothing at
         * all. Taking it out of the pointer's way lets the press reach the row.
         */
        &:disabled {
            pointer-events: none;
        }

        &:disabled + label {
            cursor: pointer; /* It opens the Pro dialog, so it is not inert. */
            opacity: 0.5;
        }
    }
}

/* --------------------------------------------------------------- selects -- */

.gmt-sl-group .input-wrapper select {
    box-sizing: border-box;
    width: var(--gmt-control-w);
    max-width: 100%;
    min-height: 40px;
    margin: 0;
    padding: 8px 36px 8px 12px;
    border: 0;
    border-radius: $rounded-lg;
    background-color: #fff;
    /* ring-1 ring-slate-900/12, the input flavour of the card's edge. */
    box-shadow: 0 0 0 1px $ring-control, $shadow-xs;
    color: $slate-900;
    font-family: $font-sans;
    font-size: $text-sm;
    line-height: $text-sm-lh;
    transition: box-shadow $dur $ease;

    &:hover {
        box-shadow: 0 0 0 1px $slate-500, $shadow-xs;
    }

    /* ring-2 ring-blue-500 on focus, the Tailwind form idiom. */
    &:focus {
        box-shadow: 0 0 0 1px $blue-500, 0 0 0 3px rgba(59, 130, 246, 0.25);
        outline: none;
    }
}

/*
 * :not(.gmt-rs__input): react-select renders its own text input inside the
 * control. Given this ring and min-height it drew as a second tiny box - the
 * double bar before every select's placeholder on Host Settings.
 */
.gmt-sl-group .input-wrapper input[type="text"]:not(.gmt-rs__input),
.gmt-sl-group .input-wrapper input[type="number"],
.gmt-sl-group .input-wrapper input[type="password"] {
    box-sizing: border-box;
    width: var(--gmt-control-w);
    max-width: 100%;
    min-height: 40px;
    margin: 0;
    padding: 8px 12px;
    border: 0;
    border-radius: $rounded-lg;
    box-shadow: 0 0 0 1px $ring-control, $shadow-xs;
    color: $slate-900;
    font-family: $font-sans;
    font-size: $text-sm;

    &:focus {
        box-shadow: 0 0 0 1px $blue-500, 0 0 0 3px rgba(59, 130, 246, 0.25);
        outline: none;
    }
}

/* -------------------------------------------------------------- pro chips -- */

/*
 * Pro, on a row that is locked. The old tag was a 13px amber pill as wide as
 * the switch beside it; this is a caption that names the tier and nothing else,
 * because the row's own label already said what the feature is.
 */
.gmt-sl-group .gmt-form-group .gmt-new-tag,
.gmt-sl-group .gmt-form-group .gmt-upcomming-tag {
    /*
     * float: right elsewhere in the admin CSS, which inside a flex row takes
     * the chip out of the line and drops it under the switch.
     */
    float: none;

    /*
     * After the control, in DOM order.
     *
     * It carried `order: -1` to sit between the label and the switch, which
     * put a piece of pricing in the middle of the one thing the row exists to
     * do. Read left to right the row is now: what the setting is, the control,
     * and then why the control will not move.
     */
    display: inline-flex;
    align-items: center;
    height: 20px;
    margin: 0;
    padding: 0 8px;
    border-radius: $rounded-md;
    font-family: $font-sans;
    font-size: 11px;
    font-weight: 600;
    line-height: 1;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    white-space: nowrap;
    cursor: pointer;
}

.gmt-sl-group .gmt-form-group .gmt-new-tag {
    background: $emerald-50;
    color: $emerald-700; /* 5.24:1 on the chip. */
    box-shadow: inset 0 0 0 1px rgba(4, 120, 87, 0.16);
    cursor: default;
}

.gmt-sl-group .gmt-form-group .gmt-upcomming-tag {
    background: $slate-100;
    color: $slate-600; /* 6.94:1 on the chip. */
    box-shadow: inset 0 0 0 1px $ring-strong;
    cursor: default;
}

/* --------------------------------------------------------------- save bar -- */

/*
 * Save, when there is something to save.
 *
 * It used to sit at the bottom of the document, so on the Configurations screen
 * you flipped a switch at 300px and then scrolled to 1050px to commit it, with
 * nothing on the way telling you that you had to. This rides the bottom of the
 * viewport and only exists while the form is dirty, which also means a screen
 * you are only reading has no button on it at all.
 */
/*
 * The end of the interaction, designed on purpose. The bar turns green, says
 * the thing in the past tense and then leaves - so the last beat of changing a
 * setting is a confirmation rather than a button still sitting there asking to
 * be pressed again.
 */
/* ------------------------------------------------------------ credentials -- */

/*
 * A set of keys, and whether they work.
 *
 * Same surface as the settings groups, because it is the same idea: a titled
 * block of related controls. What is different is the header, which carries the
 * one fact the old screen never showed - a connected account looked exactly
 * like an empty form.
 */
.gmt-cred {
    box-sizing: border-box;
    border: 0;
    border-radius: $radius-panel;
    background: #fff;
    box-shadow: $panel-shadow;

    * {
        box-sizing: border-box;
    }

    + .gmt-cred {
        margin-top: 20px;
    }
}

/* The same head, on the card that has a badge and a state to place beside the
   name. The row stays a row; only the name and its line stack inside it. */
.gmt-cred__head {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 48px;
    padding: 16px 18px;
}

/*
 * A head that is a button has to be reset back into a row: a bare button
 * brings its own font, its own centring and its own cursor.
 */
.gmt-cred__head.is-toggle {
    width: 100%;
    border: 0;
    background: none;
    font-family: $font-sans;
    text-align: left;
    cursor: pointer;
    transition: background-color $dur $ease;
}

button.gmt-cred__head:hover {
    background: $slate-50;
}

button.gmt-cred__head:focus-visible {
    @include tw-ring-focus;
    outline-offset: -2px;
}

/* The chevron says the row folds, and turns when it has. */
.gmt-cred__chev {
    flex: none;

    /* Last in the row, after the state and the Edit/Hide word. */
    order: 9;
    margin-left: 0;
    color: $slate-500; /* 4.6:1 on the card. */
    transition: transform 200ms $ease;
}

.gmt-cred__head.is-toggle[aria-expanded="true"] .gmt-cred__chev {
    transform: rotate(90deg);
}

/* The name and, while the set is shut, what opening it gets you. */
.gmt-cred__heading {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 3px;
    min-width: 0;
}

/* Name, badge and hint share the title's baseline. */
.gmt-cred__titlerow {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 4px 10px;
    min-width: 0;
}

/* Not a control any more - the row is. It reports which way a press goes. */
.gmt-cred__toggle {
    flex: none;
    margin-left: auto;
    padding: 0;
    border: 0;
    background: none;
    color: $blue-600; /* 5.44:1. */
    font-family: $font-sans;
    font-size: 13px;
    font-weight: 500;
    line-height: 20px;
}

@media ( prefers-reduced-motion: reduce ) {

    .gmt-cred__chev,
    .gmt-cred__head.is-toggle {
        transition: none;
    }

    .gmt-cred__head.is-toggle[aria-expanded="true"] .gmt-cred__chev {
        transform: none;
    }
}

.gmt-cred__title {
    margin: 0;
    font-family: $font-sans;

    /* A step above the row labels under it, which are $text-sm. Without that
       step the card had two 14px semibold voices and no first among them. */
    font-size: 16px;
    font-weight: 700;
    line-height: $text-base-lh;
    letter-spacing: -0.01em;
    color: $slate-900;
}

/*
 * Required or optional.
 *
 * The same chip for both, because the information is the contrast between the
 * two words - "Required" in a warning colour would say the setting is wrong,
 * which it is not, and "Optional" in green would say it is done, which it also
 * is not. Neither is a state; both are a fact about the field below.
 *
 * Smaller and lighter than the title it follows, so it reads as a note on the
 * heading rather than as a second heading.
 */
.gmt-cred__req {
    flex: none;
    padding: 2px 8px;
    border-radius: $rounded-full;
    background: $slate-100;
    font-family: $font-sans;
    font-size: 11px;
    font-weight: 600;
    line-height: 17px;
    letter-spacing: 0.01em;
    color: $slate-600; /* 6.94:1 on slate-100. */

    /* Optional sits one step back: it is the set you can walk past. */
    &.is-optional {
        background: none;
        box-shadow: inset 0 0 0 1px $slate-200;
        color: $slate-500; /* 4.76:1 on white. */
    }
}

/* The chip takes the space the state chip would have, so the toggle stays at
   the outside edge whether or not this set is connected. */
.gmt-cred__req + .gmt-cred__spacer,
.gmt-cred__req + .gmt-cred__state {
    margin-left: 0;
}

/*
 * The state, as a chip: told by shape and ground as well as by colour, so it
 * still reads without the green.
 */
.gmt-cred__state {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin: 0;
    margin-right: auto;
    padding: 3px 10px 3px 8px;
    border-radius: $rounded-full;
    background: $slate-100;
    font-family: $font-sans;
    font-size: $text-xs;
    font-weight: 600;
    line-height: $text-xs-lh;
    color: $slate-600; /* 6.94:1 on slate-100. */

    &.is-on {
        background: $emerald-50;
        color: $emerald-700; /* 5.24:1 on emerald-50. */
    }
}

/* Holds the header's shape when the chip is absent, so Edit stays at the
   outside edge rather than sliding in beside the title. */
.gmt-cred__spacer {
    flex: 1;
}



/*
 * The card is two padded sections with the guide running full width between
 * them: the way out on top, the form below. Splitting them is what lets the
 * strip be a band across the card rather than a block inside either one's
 * padding.
 */
.gmt-cred__lead {
    padding: 14px 16px;
    box-shadow: inset 0 1px 0 $slate-100;
}

/* Nothing above it when the guide is absent, so it carries the head's
   hairline itself. */
.gmt-cred__lead + .gmt-cred__body {
    box-shadow: none;
}

/*
 * 18px at the sides, the head's own gutter: the title and the first field label
 * were landing on 230 and 228, which is the kind of two-pixel drift that reads
 * as sloppiness without ever being nameable.
 *
 * The bottom now matches the settings groups on the other tabs. It was 14,
 * which put the last control 12px off the card's edge while an identical-looking
 * card one tab over kept 22 - close enough to look accidental, far enough to
 * see.
 */
.gmt-cred__body {
    /* The password rows carry 6px of their own, so these are the remainder.
       Left as 8px on top and 14px underneath, this band ran 14px of ink above
       and 28 below - a two-to-one lean nobody chose, on the one card where the
       imbalance shows because both edges are drawn as hairlines. */
    padding: ($card-ink-top - 6px) 18px ($card-ink-bottom - 6px);
    box-shadow: inset 0 1px 0 $slate-100;
}

/* The password fields, as list rows rather than as stacked blocks. */
/*
 * The credential field row.
 */
.gmt-cred__body .input-container,
.form-wrapper .goodmeet-connect-tab-content .accordion .input-container {
    margin: 0;
    padding: 0;

    /*
     * No rule under the row.
     *
     * Each of these is a label and a boxed input, and the box already has a
     * top and a bottom edge of its own. A divider underneath drew a third
     * horizontal line through a two-line row, which is what made a form of
     * three fields read as a table of three records - and it left a stray
     * line hanging under the last one, above the card's own edge.
     *
     * Space separates them now, which is all a stack of labelled fields has
     * ever needed.
     */
    .input-field {
        display: flex;
        align-items: center;
        gap: 16px;

        padding: 6px 0;

        label {
            flex: none;
            width: 168px;
            margin: 0;
            font-family: $font-sans;
            font-size: $text-sm;
            font-weight: 400;
            line-height: $text-sm-lh;
            color: $slate-900;
        }

        .text-input {
            width: 100%;
            min-height: 40px;

            margin: 0;

            /* Right padding clears the reveal, so a long key never runs under it. */
            padding: 8px 44px 8px 12px;
            border: 0;
            border-radius: $rounded-lg;
            box-shadow: 0 0 0 1px $ring-control, $shadow-xs;
            color: $slate-900;
            font-family: $font-sans;
            font-size: $text-sm;

            &:focus {
                box-shadow: 0 0 0 1px $blue-500, 0 0 0 3px rgba(59, 130, 246, 0.25);
                outline: none;
            }
        }
    }
}

/*
 * Webex and Teams wrap their credential fields in a legacy panel carrying
 * `padding: 40px 20px 10px 30px`. That 30px pushed every field on those two
 * screens a step right of the redirect row directly above them, so the card
 * had two left edges and two right edges - the rows lined up with nothing.
 *
 * It is also a white panel at 65% width with a 15px radius, sitting on the
 * white card - a box drawn inside a box, which is where the second right edge
 * at 914 came from.
 *
 * The card already sets the inset and the surface. Nothing inside it needs to
 * set either again. The extra class matches the legacy rule's specificity,
 * which is otherwise a tie the later stylesheet wins.
 */
.form-wrapper .goodmeet-connect-tab-content .accordion .gmt-section-pannel {
    width: auto;
    padding: 0;
    border-radius: 0;
    background: none;
}

/* One gap between the URL and its Copy, not the row's gap plus the button's
   own margin on top of it. */
.form-wrapper .goodmeet-connect-tab-content .url-copy .copy-button {
    margin-left: 0;
}

/* --------------------------------------------------- credential reveal -- */

/*
 * The shell that holds a password field and its reveal, and the reveal
 * itself. Deliberately unscoped: PassInputField is rendered by five screens,
 * two of which style their rows from their own stylesheets, and a reveal
 * positioned against the wrong ancestor lands in the middle of the page.
 */
.gmt-secret {
    position: relative;
    display: flex;
    align-items: center;
    flex: 1;
    min-width: 0;

    /*
     * The shared control width.
     *
     * This has been wrong in both directions. Capped at 440 the field stopped
     * at 884 while the card ran to 1156, so the card had two right edges. Set
     * to fill, it became a 744px box for a 22 character token while the select
     * next door was 320 - one card family, two grammars.
     *
     * One token now, wide enough for a 32 character secret and no wider.
     */
    max-width: var(--gmt-control-w);
}

/* Jitsi's API screen sizes its own inputs from its own stylesheet, so the
   room for the reveal is claimed here rather than only in the row rules
   above - otherwise a long key runs under the eye on that one screen. */
.gmt-secret .text-input {
    width: 100%;
    padding-right: 44px;
}

/*
 * Inside the field, at its right edge - where every password field on the web
 * keeps it, so nobody has to be told what it is. Quiet until the pointer
 * arrives: it is an affordance, not an action anybody came to the screen to
 * take.
 *
 * 34px rather than the usual 44px floor. The control cannot be taller than
 * the 40px field it sits inside, and a full-height end-cap reads as a second
 * button bolted to the input.
 */
.gmt-secret__reveal {
    position: absolute;
    right: 4px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    padding: 0;
    border: 0;
    border-radius: $rounded-md;
    background: transparent;
    color: $slate-500; /* 4.76:1, well past the 3:1 a glyph owes. */
    cursor: pointer;
    transition: color $dur $ease, background-color $dur $ease;
}

.gmt-secret__reveal:hover {
    background: $slate-100;
    color: $slate-900; /* 16.3:1. */
}

.gmt-secret__reveal:focus-visible {
    @include tw-ring-focus;
    outline-offset: -1px;
    color: $slate-900;
}

/* Revealed is a state worth seeing at a glance down the column. */
.gmt-secret__reveal[aria-pressed="true"] {
    color: $blue-600;
}


/* The redirect URL: a value to copy, so it is a field, not a paragraph. */
.gmt-cred__row {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 6px 0;

    > label {
        flex: none;
        width: 168px;
        margin: 0;
        font-family: $font-sans;
        font-size: $text-sm;
        font-weight: 500;
        line-height: $text-sm-lh;
        color: $slate-900;
    }
}

.gmt-cred__copy {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1;
    min-width: 0;
    /* The same measure as the credential fields, so one control width holds
       across the whole card. The redirect URL is longer than a key, so this one
       is allowed to run wider. */
    max-width: calc(var(--gmt-control-w) * 1.6);

    input {
        flex: 1;
        min-width: 0;
        min-height: 38px;
        margin: 0;
        padding: 8px 12px;
        border: 0;
        border-radius: $rounded-lg;
        background: $slate-50;
        box-shadow: 0 0 0 1px $ring-strong;
        color: $slate-700; /* 9.42:1 on slate-50. */
        font-family: $font-mono;
        font-size: $text-xs;
    }

    /* Read-only and wrapped, so a long URL shows in full. One click selects
       all of it for anyone who copies by hand. */
    .gmt-cred__url {
        flex: 1;
        min-width: 0;
        margin: 0;
        padding: 9px 12px;
        border-radius: $rounded-lg;
        background: $slate-50;
        box-shadow: 0 0 0 1px $ring-strong;
        color: $slate-700; /* 9.42:1 on slate-50. */
        font-family: $font-mono;
        font-size: $text-xs;
        line-height: 18px;
        overflow-wrap: anywhere;
        user-select: all;
    }

    .gmt-cred__url-part {
        white-space: nowrap;
    }

    /* URL on its own full-width line, Copy under it: beside it, the URL had
       under 300px and broke into three ragged lines. */
    &.is-stacked {
        flex-wrap: wrap;

        .gmt-cred__url {
            flex-basis: 100%;
        }
    }

    button {
        flex: none;
        min-width: 84px;
        min-height: 38px;
        padding: 8px 16px;
        border: 0;
        border-radius: $rounded-lg;
        background: $slate-100;
        box-shadow: 0 0 0 1px $ring-strong;
        color: $slate-700; /* 9.09:1 on slate-100. */
        font-family: $font-sans;
        font-size: $text-sm;
        font-weight: 600;
        cursor: pointer;
        transition: background-color $dur $ease, color $dur $ease;

        &:hover {
            background: $slate-200;
            color: $slate-900;
        }

        &:focus-visible {
            @include tw-ring-focus;
        }
    }
}

/*
 * The one link that replaced four sentences, at the foot of the fields - which
 * is where somebody who cannot fill them in actually starts looking.
 */
.gmt-cred__help,
.gmt-cred__help:link,
.gmt-cred__help:visited {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin-top: 16px;
    color: $blue-600; /* 5.17:1 on white. */
    font-family: $font-sans;
    font-size: $text-sm;
    font-weight: 500;
    text-decoration: none;
}

.gmt-cred__help:hover,
.gmt-cred__help:focus,
.gmt-cred__help:active {
    color: $blue-700;
    text-decoration: underline;
    text-underline-offset: 3px;
    box-shadow: none;
}

.gmt-cred__help:focus-visible {
    @include tw-ring-focus;
    border-radius: $rounded-md;
}

/* Renew: a real action, but a rare one, so it never looks like the main one. */
.gmt-cred__minor {
    margin-top: 16px;
    min-height: 34px;
    padding: 7px 14px;
    border: 0;
    border-radius: $rounded-lg;
    background: #fff;
    box-shadow: 0 0 0 1px $ring-control, $shadow-xs;
    color: $slate-700; /* 10.3:1 on white. */
    font-family: $font-sans;
    font-size: $text-sm;
    font-weight: 500;
    cursor: pointer;
    transition: background-color $dur $ease, box-shadow $dur $ease;

    &:hover {
        background: $slate-50;
        box-shadow: 0 0 0 1px $slate-500, $shadow-xs;
    }

    &:focus-visible {
        @include tw-ring-focus;
    }
}

/* In the footer row it sits beside the main button, so no top margin. */
.gmt-mr-auto > .gmt-cred__minor {
    margin-top: 0;
}

/* ------------------------------------------------------------ responsive -- */

@include respond-to('small') {

    .gmt-sl-group .gmt-form-group {
        align-items: flex-start;
        flex-direction: column;
        gap: 12px;
        padding: 16px;

        > .input-wrapper {
            justify-content: flex-start;
            width: 100%;
            max-width: 100%;
        }

        select,
        input[type="text"],
        input[type="number"],
        input[type="password"] {
            width: 100%;
            max-width: 100%;
        }
    }

    .gmt-cred__body .input-container .input-field,
    .gmt-cred__row {
        align-items: flex-start;
        flex-direction: column;
        gap: 8px;

        > label,
        label {
            width: 100%;
        }
    }

    .gmt-cred__copy {
        width: 100%;
    }
}

@media ( prefers-reduced-motion: reduce ) {

    .gmt-sl-group *,
    .gmt-cred * {
        transition: none !important;
    }
}

/* ----------------------------------------------------------------- hints -- */

/*
 * The mark that carries a setting's explanation.
 *
 * Quiet at rest so a row of them does not read as a row of warnings, and it
 * only appears on the settings that genuinely need one - a mark beside every
 * label would put the reader back in front of thirteen things to read.
 *
 * The glyph is 15px, the drawn box 24px and the target 44px: Fitts's law does
 * not care how big the drawing is, only how big the thing you have to hit is,
 * and 44px is the floor for anything touchable. A pseudo-element carries the
 * extra reach so the row's metrics do not change.
 */
.gmt-sl-group .gmt-form-group > label .gmt-hint,
.gmt-jm-fields label .gmt-hint,
.gmt-cred .gmt-hint {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    position: relative;
    flex: none;
    /* Centred on the label's line box, not its baseline: a baseline-aligned
       button sits a couple of pixels above the text beside it. */
    align-self: center;
    width: 22px;
    height: 22px;
    margin: -3px 0 -3px -4px;
    padding: 0;
    border: 0;
    border-radius: $rounded-full;
    background: transparent;

    /* 4.76:1. Comfortably past the 3:1 a non-text glyph owes, because the
       first version of this mark was missed entirely, and a hint nobody
       notices is a hint nobody reads. */
    color: $slate-400;
    cursor: help;

    /* The fill behind the glyph: absent at rest, a soft wash on hover. */
    .gmt-hint__disc {
        opacity: 0;
        transition: opacity $dur $ease;
    }

    /* The reach, not the drawing. */
    &::after {
        content: '';
        position: absolute;
        top: 50%;
        left: 50%;
        width: 44px;
        height: 44px;
        transform: translate(-50%, -50%);
    }
    transition: color $dur $ease, transform $dur $ease;

    /* The brand blue and a tinted disc - the mark answers the pointer before
       the tooltip does, so the hover never feels like nothing happened. */
    &:hover,
    &[aria-describedby] {
        color: $blue-600;

        .gmt-hint__disc {
            opacity: 0.12;
        }
    }

    &:active {
        transform: scale(0.94);
    }

    &:focus-visible {
        @include tw-ring-focus;
        color: $blue-600;
    }
}

/*
 * The tooltip itself. Ink-dark with a hairline inner edge and a layered
 * shadow, so it sits above the card rather than being printed on it; the
 * arrow shares the fill so the two read as one shape.
 */
.gmt-hint__tip.gmt-hint__tip {
    z-index: 100000;
    width: max-content;
    max-width: 260px;
    padding: 8px 12px;
    border-radius: 10px;
    background: #0F172A;
    color: #F1F5F9;
    font-size: 12.5px;
    font-weight: 500;
    line-height: 1.5;
    letter-spacing: 0.005em;
    text-align: left;
    white-space: normal;
    box-shadow:
        inset 0 0 0 1px rgba(255, 255, 255, 0.07),
        0 1px 2px rgba(15, 23, 42, 0.18),
        0 8px 24px -6px rgba(15, 23, 42, 0.35);
    transform: translateY(3px);
    transition: opacity 150ms $ease, transform 150ms $ease;

    &.react-tooltip__show {
        transform: translateY(0);
    }
}

/* react-tooltip pads its own inner wrapper; the padding lives on the tip. */
.gmt-hint__tip .react-tooltip-content-wrapper {
    padding: 0;
}

.gmt-hint__tip .gmt-hint__arrow.gmt-hint__arrow {
    width: 12px;
    height: 12px;
    border-radius: 0 0 2px 0;
    background: #0F172A;
}

/*
 * The tooltip moved to scss/common/_tooltip.scss.
 *
 * It was the plugin's only good tooltip and it was reachable from one group
 * of screens. Everything else that wanted one fell back to a `title`
 * attribute, which the browser draws in its own grey slab after its own
 * delay and which no stylesheet can reach. One tooltip, loaded once, is the
 * point of moving it.
 */


/* A hint that slides is a preference; a hint that slides for somebody who has
   asked things to hold still is a bug. */
@media ( prefers-reduced-motion: reduce ) {

    .gmt-hint__tip.gmt-hint__tip {
        transform: none;
        transition: opacity 1ms linear;
    }

    .gmt-sl-group .gmt-form-group > label .gmt-hint,
    .gmt-jm-fields label .gmt-hint,
    .gmt-cred .gmt-hint {

        &:hover,
        &:active {
            transform: none;
        }
    }
}

/* ---------------------------------------------------------- the progress -- */

/* -------------------------------------------------------- shape warnings -- */

/*
 * Under the field, in amber rather than red.
 *
 * Nothing here is refused - these formats belong to Zoom, Webex and Microsoft
 * and they change without notice, so a validator confident enough to block a
 * key it does not recognise will one day block a valid one. Red under a value
 * the plugin will happily save says the wrong thing about what just happened.
 */
/*
 * A problem with what is already typed, at the top of the set it concerns.
 *
 * Amber rather than red, and it does not block the save: these formats belong
 * to Zoom and a validator confident enough to refuse a value it does not
 * recognise will one day refuse a valid one. It says what is suspicious and
 * why, then gets out of the way.
 */
.gmt-cred__warn {
    display: flex;
    gap: 8px;
    margin: 0 0 12px;
    padding: 9px 12px;
    border-radius: $rounded-lg;
    background: $amber-50;
    box-shadow: inset 3px 0 0 $amber-300;
    color: $amber-900; /* 11.6:1 on amber-50. */
    font-family: $font-sans;
    font-size: 12.5px;
    line-height: 1.55;
}

.gmt-field-warn {
    margin: 2px 0 6px 184px;
    color: $amber-800; /* 7.09:1 on the card, measured. */
    font-family: $font-sans;
    font-size: 12.5px;
    line-height: 1.5;
}

.gmt-secret .text-input.has-warning {
    box-shadow: 0 0 0 1px $amber-700, $shadow-xs;
}

@include respond-to('small') {

    .gmt-field-warn {
        margin-left: 0;
    }
}

/* -------------------------------------------------------- the way out -- */

/*
 * The one link on a credential card that leaves the site.
 *
 * Dark rather than brand blue. It is the first move, but the thing you came to
 * finish is the form under it, and two filled blue buttons on one card rank
 * nothing. Its state is answered on every pseudo-class because wp-admin colours
 * every anchor state at a specificity a single class cannot beat.
 */
.gmt-cred__out,
.gmt-cred__out:link,
.gmt-cred__out:visited {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin: 0;
    padding: 10px 16px;
    border: 0;
    border-radius: $rounded-lg;

    /*
     * The plugin's own ink, filled. I made this a grey ghost on the reasoning
     * that a link off the site should not outweigh the page's own action - and
     * that reading was wrong here. On an unconnected card this IS the action:
     * the form below it cannot be filled until somebody has gone and made the
     * app, so the first move earns the only filled button on the card.
     */
    background: $brand-ink;
    color: #fff; /* 16.9:1. */
    font-family: $font-sans;
    font-size: 13px;
    font-weight: 600;
    line-height: 20px;
    text-decoration: none;
    transition: background-color $dur $ease;
}

.gmt-cred__out svg {
    color: rgba(255, 255, 255, 0.7); /* 11.8:1 - the arrow trails the label. */
}

.gmt-cred__out:hover,
.gmt-cred__out:focus,
.gmt-cred__out:active {
    background: #14294a;
    color: #fff;
    text-decoration: none;
    box-shadow: none;
}

.gmt-cred__out:focus-visible {
    @include tw-ring-focus;
}

/* --------------------------------------------------- connect tab leading -- */

/*
 * The same gap under the nav on every platform.
 *
 * Webex and Teams sat 40px below the section nav where Zoom, Jitsi and Google
 * Meet sat at 20 - measured, and stable across reloads. The extra 20 is a top
 * margin on the first block inside their connect markup, collapsing up through
 * the form: every element in the chain reports `margin-top: 0` because the
 * margin is specified further down and collapses, which is why it does not show
 * up on the element that appears to be offset.
 *
 * It is the h3.title in Webex and Teams own connect markup: wp-admin gives an
 * h3 a 20px top margin, and with no border or padding on any of the four
 * elements between it and the form, that margin collapses straight up and moves
 * the form instead of the heading. MhCredentialGroup does not have it because
 * its own title is set to margin: 0.
 */
.form-wrapper .goodmeet-connect-tab-content .accordion h3.title,
.form-wrapper .goodmeet-connect-tab-content .webex-credentials-info h3.title,
.form-wrapper .goodmeet-connect-tab-content .msteams-credentials-info h3.title {
    margin-top: 0;
}

/*
 * Webex and Teams still render their own connect markup rather than
 * MhCredentialGroup, so their screens had no card at all: a 22px heading
 * straight on the page ground, a grey box round the redirect URL, and fields
 * below it. Beside Zoom's panelled version they read as two different products.
 *
 * Converting those two components is the right fix and a larger one. Until
 * then the existing markup wears the same surface, so the five platforms agree.
 */
.form-wrapper .goodmeet-connect-tab-content .accordion {
    box-sizing: border-box;
    padding: 4px 16px 14px;
    border-radius: $radius-panel;
    background: #fff;
    box-shadow: $panel-shadow;

    + .accordion {
        margin-top: 12px;
    }
}

/* The heading, at the size MhCredentialGroup gives its own. */
.form-wrapper .goodmeet-connect-tab-content h3.title {
    margin: 0;
    padding: 12px 0 10px;
    font-family: $font-sans;
    font-size: $text-sm;
    font-weight: 600;
    line-height: $text-sm-lh;
    letter-spacing: -0.01em;
    color: $slate-900;
}

/*
 * The redirect URL is a field like the others, not a panel of its own. It was a
 * grey box with a heading and a filled blue button inside the card, which made
 * a value you copy look like the main thing on the screen.
 */
.form-wrapper .goodmeet-connect-tab-content .msteams-redirect-url-section {
    display: flex;
    align-items: center;
    gap: 16px;
    margin: 0;
    padding: 6px 0;
    border: 0;
    border-radius: 0;
    background: none;

    h3.title {
        box-sizing: border-box;
        flex: none;
        width: 168px;
        padding: 0;
        font-size: $text-sm;
        font-weight: 500;
        line-height: $text-sm-lh;
        color: $slate-900;
    }

    .url-copy {
        box-sizing: border-box;
        display: flex;
        align-items: center;
        gap: 8px;
        flex: 1;
        min-width: 0;
        padding: 0;

        input {
            flex: 1;
            min-width: 0;
            min-height: 38px;
            margin: 0;
            padding: 8px 12px;
            border: 0;
            border-radius: $radius-control;
            background: $slate-50;
            box-shadow: 0 0 0 1px $ring-strong;
            color: $slate-700; /* 9.42:1 on slate-50. */
            font-family: $font-mono;
            font-size: $text-xs;
        }

        /* Quiet, like Zoom's Copy: it duplicates a value, it does not commit. */
        .copy-button {
            flex: none;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            min-width: 84px;
            min-height: 38px;
            padding: 8px 16px;
            border: 0;
            border-radius: $radius-control;
            background: $slate-100;
            box-shadow: 0 0 0 1px $ring-strong;
            color: $slate-700; /* 9.09:1 on slate-100. */
            font-size: $text-sm;
            font-weight: 600;
            cursor: pointer;
            transition: background-color $dur $ease, color $dur $ease;

            &:hover {
                background: $slate-200;
                color: $slate-900;
            }

            &:focus-visible {
                @include tw-ring-focus;
            }
        }
    }
}

/*
 * The heading in Webex and Teams' own markup.
 *
 * Their platform stylesheets set it at 20px with a longer selector than the
 * shared rule above, so it stayed a page heading inside a card where Zoom's is
 * a 14px card title. Named here at matching depth, after them in the cascade.
 */
.form-wrapper .goodmeet-connect-tab-content .accordion .webex-credentials-info h3.title,
.form-wrapper .goodmeet-connect-tab-content .accordion .msteams-credentials-info h3.title {
    margin: 0;
    padding: 12px 0 10px;
    font-family: $font-sans;
    font-size: $text-sm;
    font-weight: 600;
    line-height: $text-sm-lh;
    letter-spacing: -0.01em;
    color: $slate-900;
}

@keyframes gmt-cred-arrive {
    0% { transform: scale(0.4); opacity: 0; }
    60% { transform: scale(1.08); opacity: 1; }
    100% { transform: scale(1); opacity: 1; }
}

.gmt-cred__state.is-on svg {
    animation: gmt-cred-arrive 420ms $ease both;
}

@media ( prefers-reduced-motion: reduce ) {

    .gmt-cred__state.is-on svg {
        animation: none;
    }
}

/* ------------------------------------------------- jitsi hosting modes -- */

/*
 * The three hosting options are Tailwind, in the component - they are cards
 * with a selected state, which is what utilities are good at and what a
 * stylesheet ends up re-describing badly.
 *
 * What is left here is the one part that cannot be: the rows inside an
 * expanded card come from PassInputField and TextAreaField, whose markup is
 * shared with the credential cards and laid out for them.
 */

/*
 * Label above control, capped at the control's own width.
 *
 * The settings grid puts a label on the card's left edge and its control on a
 * column roughly 650px away. Down a list of thirteen switches that is right:
 * every control lands on one x and the eye reads a column. Inside an expanded
 * option card there is no column - one field, one label - so the same grid
 * just leaves 650px of nothing between two things that belong together.
 */
.gmt-jm-fields {
    display: flex;
    flex-direction: column;
    gap: 16px;
    max-width: 420px;

    .input-container,
    .textarea-field {
        margin: 0;
        padding: 0;
    }

    /* The row, unstacked. */
    .input-field {
        display: flex;
        flex-direction: column;
        align-items: stretch;
        gap: 6px;
        width: 100%;
        margin: 0;
        padding: 0;
        background: none;

        /* The settings list paints a hover across the whole row. Here the row
           is not the target - the field inside it is. */
        &:hover {
            background: none;
        }

        &::after {
            content: none;
        }
    }

    label {
        display: flex;
        align-items: center;
        gap: 6px;
        width: auto;
        max-width: 100%;
        margin: 0;
        padding: 0;
        color: $slate-800; /* 12.6:1 on the card. */
        font-family: $font-sans;
        font-size: 13px;
        font-weight: 500;
        line-height: 20px;

        &::after {
            content: none;
        }
    }

    /* The input and its reveal share a box, so the box is what has the width. */
    .gmt-secret {
        width: 100%;
        max-width: 100%;
    }

    /* No reveal on a plain text field, so no room reserved for one. */
    .gmt-secret:not(:has(.gmt-secret__reveal)) .text-input {
        padding-right: 12px;
    }

    .text-input,
    textarea {
        box-sizing: border-box;
        width: 100%;
        max-width: 100%;
        min-height: 40px;
        margin: 0;
        border: 0;
        border-radius: $rounded-lg;
        background: #fff;
        box-shadow: inset 0 0 0 1px $slate-300;
        color: $slate-900;
        font-family: $font-sans;
        font-size: $text-sm;
        line-height: $text-sm-lh;

        &:focus {
            box-shadow: inset 0 0 0 1px $blue-600;
            outline: none;
        }

        &:focus-visible {
            @include tw-ring-focus;
        }
    }

    textarea {
        padding: 10px 12px;
        font-family: $font-mono;
        font-size: 12.5px;
        line-height: 1.6;
        resize: vertical;
    }
}

/*
 * The public-domain select.
 *
 * wp-admin paints its own arrow onto every select as a background image, at a
 * specificity one utility class does not beat - so `appearance: none` removed
 * the native control's arrow and left WordPress's, one chevron short of the
 * left of the drawn one. Two arrows on one control.
 */
.gmt-jm-select select {
    background-image: none;

    /*
     * And the full width of its wrapper.
     *
     * Something upstream caps a select at 400px, so inside a 420px column the
     * control stopped 20px short while the chevron - positioned against the
     * wrapper - sat on the boundary, half inside the field and half outside it.
     * From a screenshot that reads as two arrows; it was one, drawn across an
     * edge that should not have been there.
     */
    width: 100%;
    max-width: 100%;
}

/*
 * Two secondary controls at the footer's left end.
 *
 * The slot was written for one. With two in it they need a gap of their own,
 * and the destructive one needs to read as destructive without shouting: this
 * is a reversible act on a card whose keys survive it, so it is a quiet button
 * that turns red under the pointer rather than a red button sitting there
 * daring somebody to press it.
 */
.gmt-cred__minor + .gmt-cred__minor {
    margin-left: 8px;
}

.gmt-cred__minor.is-danger:hover {
    background: #FEF2F2;
    box-shadow: 0 0 0 1px #FECACA, $shadow-xs;
    color: #B42318; /* 6.01:1 on that tint; 10.35:1 as slate-700 at rest. */
}

.gmt-cred__minor.is-danger:focus-visible {
    outline: 2px solid #B42318;
    outline-offset: 2px;
}
