/*
 * Regit ticket selector — REGIT-008.
 *
 * The first thing a buyer touches, and the last place to assume the event looks
 * like Command's. CLAUDE.md rule 8: this is a product. Every rule here is keyed
 * on Event Espresso's own classes and works for any number of tickets in any of
 * core's states — on sale, sold out, sale ended, not yet on sale — with any
 * currency, because nothing below knows what a dollar is.
 *
 * Scoped to .tkt-slctr-tbl-wrap-dv, which core wraps every selector in. The
 * selector renders inside whatever theme the site runs, and a rule that escapes
 * this scope restyles somebody's event page.
 *
 * Mobile first: the base rules are the 390px design and the single media query
 * widens it.
 */

.tkt-slctr-tbl-wrap-dv {
    --regit-tkt-text-2xs: 0.6875rem;
    --regit-tkt-text-xs: 0.8125rem;
    --regit-tkt-text-sm: 0.875rem;
    --regit-tkt-text-base: 1rem;
    --regit-tkt-text-lg: 1.125rem;
    --regit-tkt-leading: 1.6;
    /* Rows are scanned, not read. 1.6 is a reading measure and it made a
       two-line ticket name 63px tall on its own. */
    --regit-tkt-leading-row: 1.35;

    --regit-tkt-space-2xs: 0.25rem;
    --regit-tkt-space-xs: 0.5rem;
    --regit-tkt-space-sm: 0.75rem;
    --regit-tkt-space-md: 1.25rem;

    --regit-tkt-ink: #1a1a1a;
    --regit-tkt-ink-muted: #595959;
    --regit-tkt-line: #d5d7da;
    --regit-tkt-accent: #135e96;
    --regit-tkt-accent-hover: #0b4a78;
    --regit-tkt-sold-out: #8a2424;
    --regit-tkt-error-ink: #8a2424;
    --regit-tkt-error-line: #c0392b;
    --regit-tkt-error-field: #b02a2a;
    --regit-tkt-error-bg: #fdf2f2;
    --regit-tkt-pending: #6a4a00;
    --regit-tkt-radius: 6px;
    --regit-tkt-tap: 44px;

    font-size: var(--regit-tkt-text-base);
    line-height: var(--regit-tkt-leading);
    color: var(--regit-tkt-ink);
}

/*
 * Core's status greys, raised to a readable contrast inside the selector.
 *
 * --ee-status-color-light-grey is hsl(219, 2%, 55%), about 3.4:1 on white, and
 * core puts it on the WHOLE ROW of a sold-out or expired ticket via
 * .lt-grey-text. The row a buyer most needs to understand — the one they cannot
 * buy — was the least legible on the page.
 */
.tkt-slctr-tbl-wrap-dv {
    --ee-status-color-light-grey: #595959;
    --ee-status-color-grey: #4a4a4c;
}

/* ---------------------------------------------------------------- table ---- */

/*
 * On a phone this stops being a table.
 *
 * Three columns in 330px does not work, and three attempts at making the
 * arithmetic fit all failed the same way: the status column ran past the
 * wrapper and read "Sold Ou", "Goes On Sa". Percentages, box-sizing and column
 * rebalancing each moved the numbers without fixing the shape, which is the
 * signal to stop adjusting and change the approach.
 *
 * So: below 48em each ticket row is a block — name, price and state stacked,
 * full width, nothing to overflow. At 48em and up it is a table again, where
 * three columns have the room they need. The header row is hidden on the
 * stacked layout because "Details / Price / Qty" above a stack of cards labels
 * nothing; core renders a screen-reader label on the quantity control itself
 * (.ee-a11y-screen-reader-text), so the control keeps its name either way.
 */
/* Body rows only. `tr` on its own also caught the header row, which stayed a
   block when the table came back at 48em and formed its own column track: the
   header cells measured 111/59/46 while the data below them used 215/…, so
   "Details / Price / Qty" floated above the wrong columns. Nested detail tables
   are left alone for the same reason — they are not this table's rows. */
.tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl,
.tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl > tbody,
.tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl > tbody > tr,
.tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl > tbody > tr > td {
    display: block;
    width: auto;
}

.tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl thead {
    /* Hidden from sight, kept for anyone reading the document. */
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl > tbody > tr {
    padding: var(--regit-tkt-space-sm) 0;
    border-bottom: 1px solid var(--regit-tkt-line);
}

.tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl > tbody > tr > td {
    padding: 0 0 var(--regit-tkt-space-2xs);
    border: none;
    /* Everything reads down the left edge in the stacked layout. Core aligns
       the price right and centres the quantity for the table, which in a card
       leaves the price floating away from the name it belongs to. */
    text-align: start;
}

/*
 * Price and availability share a line below the name.
 *
 * They are the pair a visitor compares, and stacking all three cells cost a
 * third line on every ticket for no gain. The name keeps its own line because
 * a session name is long — "Applied AI Assistant (21-Aug-2026, Fri)" — and
 * sharing would wrap it anyway.
 *
 * inline-block on the cells rather than flex on the row: the row is a <tr>,
 * and turning a table row into a flex container is the kind of thing that
 * behaves differently the moment core changes a wrapper.
 */
@media (max-width: 47.99em) {
    .tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl > tbody > tr > .tckt-slctr-tbl-td-price,
    .tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl > tbody > tr > .tckt-slctr-tbl-td-qty {
        display: inline-block;
        vertical-align: middle;
        width: auto;
        padding-bottom: 0;
    }

    .tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl > tbody > tr > .tckt-slctr-tbl-td-qty {
        margin-inline-start: var(--regit-tkt-space-sm);
    }

    /* The quantity control does not need to be as wide as the name above it. */
    .tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl > tbody > tr > td select {
        max-width: 5rem;
    }
}

.tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl > tbody > tr > td select {
    max-width: 8rem;
}

/*
 * The row that holds the collapsed details panel, which core emits for EVERY
 * ticket whether or not anyone opens it.
 *
 * Left alone it takes the padding and the border every row gets: an invisible
 * band and a doubled rule under each ticket, 25px apiece on a phone. The
 * spacing belongs on the panel itself, which core keeps `display: none` while
 * the panel is shut, so a closed ticket costs nothing.
 *
 * Padding and border only. The row keeps its display, so the disclosure still
 * expands it.
 */
.tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl > tbody > tr.ee-hidden-ticket-tr,
.tkt-slctr-tbl-wrap-dv .tckt-slctr-tkt-details-td {
    padding: 0;
    border-bottom: none;
}

.tkt-slctr-tbl-wrap-dv .tckt-slctr-tkt-details-dv {
    padding: 0 var(--regit-tkt-space-sm) var(--regit-tkt-space-sm);
}

.tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl thead th {
    padding: var(--regit-tkt-space-xs);
    font-size: var(--regit-tkt-text-sm);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--regit-tkt-ink-muted);
    border-bottom: 1px solid var(--regit-tkt-line);
}

.tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl tbody td {
    padding: var(--regit-tkt-space-sm) var(--regit-tkt-space-xs);
    border-bottom: 1px solid var(--regit-tkt-line);
    vertical-align: top;
    line-height: var(--regit-tkt-leading);
}

/* break-word, not anywhere.
 *
 * `anywhere` breaks eagerly, at the best fit rather than only when a word
 * cannot fit at all: it produced "SOLD O UT", "Advance purchas e" and "show
 * detai ls +" in a narrow column. `break-word` still rescues a single
 * unbreakable string — a ticket name is written by the site owner and can be
 * anything — without chopping ordinary words. */
.tkt-slctr-tbl-wrap-dv .tckt-slctr-tbl-td-name {
    overflow-wrap: break-word;
}

.tkt-slctr-tbl-wrap-dv .tckt-slctr-tbl-td-qty,
.tkt-slctr-tbl-wrap-dv .tckt-slctr-tbl-td-price {
    overflow-wrap: normal;
    word-break: keep-all;
}

.tkt-slctr-tbl-wrap-dv .tckt-slctr-tbl-td-name {
    font-weight: 600;
}

.tkt-slctr-tbl-wrap-dv .tckt-slctr-tbl-td-price {
    font-variant-numeric: tabular-nums;
}

/*
 * The row's own type size, set on the cells rather than left to inherit.
 *
 * The wrapper above declares `font-size: var(--regit-tkt-text-base)`, and on a
 * real site it loses. A theme that sizes its article body — Upskill's sets
 * 19.8px on a 31.68px line — beats a rule on a container with one class, so
 * every ticket name and price rendered at reading size and a four-ticket table
 * ran to 513px. Sizing the cells is what actually holds, and it stays in `rem`
 * so a site with a different root size still scales.
 *
 * The colour and family are deliberately NOT set: those are the theme's, and a
 * selector that repaints them stops looking like the site it is on.
 */
.tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl .tckt-slctr-tbl-td-name,
.tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl .tckt-slctr-tbl-td-name strong,
.tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl .tckt-slctr-tbl-td-price,
.tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl .tckt-slctr-tbl-td-price .tckt-price--nowrap,
.tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl .tckt-slctr-tbl-td-qty {
    font-size: var(--regit-tkt-text-base);
    line-height: var(--regit-tkt-leading-row);
}

/* The currency code is an annotation on the price, not part of it. */
.tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl .tckt-slctr-tbl-td-price .currency-code {
    font-size: var(--regit-tkt-text-2xs);
    letter-spacing: 0.02em;
}

/* The disclosure that opens the ticket's details. Core styles it as small grey
   text, which reads as a caption rather than a control.
 *
 * Both links, identically. Core renders the pair together and swaps which one
 * is visible, so styling only the "show" half left "hide details -" in
 * whatever colour the theme paints a link — which on Upskill was red. */
.tkt-slctr-tbl-wrap-dv .display-tckt-slctr-tkt-details,
.tkt-slctr-tbl-wrap-dv .hide-tckt-slctr-tkt-details {
    display: inline-block;
    margin-inline-start: var(--regit-tkt-space-xs);
    /* Vertical padding, not min-height. min-height on an inline-block still
       inflates the line box it sits in, which is how a 44px control added 38px
       of empty row to every ticket. The link now sits inside the ticket name's
       own text, where WCAG 2.5.8's inline exception applies, and is still 32px
       tall — comfortably past the 24px minimum. */
    padding: 0.4rem 0;
    font-size: var(--regit-tkt-text-xs);
    font-weight: 400;
    line-height: var(--regit-tkt-leading-row);
    color: var(--regit-tkt-accent);
    text-decoration: underline;
    white-space: nowrap;
    cursor: pointer;
}

/*
 * !important, once, and only here.
 *
 * espresso_core.js:291 and :311 set `display: flex` as an INLINE STYLE on each
 * link every time the panel is toggled. After one open-and-close "show details
 * +" stops being inline and drops to a line of its own, so the row a buyer has
 * touched is permanently taller than the ones they have not. An inline style
 * cannot be beaten by specificity.
 *
 * Matched on that inline style rather than on the class, so the link core is
 * currently HIDING (`display: none`, also inline) stays hidden. A blanket rule
 * was tried first and showed "show details +" and "hide details -" at once.
 */
.tkt-slctr-tbl-wrap-dv .display-tckt-slctr-tkt-details[style*="flex"],
.tkt-slctr-tbl-wrap-dv .hide-tckt-slctr-tkt-details[style*="flex"] {
    display: inline-flex !important;
}

/*
 * A ticket with no description has nothing to disclose.
 *
 * The template marks the details row when the description is empty, because
 * that is where the ticket is in scope: core builds the link in
 * TicketSelectorRowStandard::ticketNameTableCell() from a global config flag
 * (TicketDetails::showTicketDetails()) with no per-ticket filter to hook.
 *
 * :has() is how the mark reaches back to the row above it. Where it is
 * unsupported the link remains and opens an empty panel — the pre-existing
 * behaviour, not a new fault.
 */
.tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl > tbody > tr:has(+ tr.regit-tkt-details--empty) .display-tckt-slctr-tkt-details,
.tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl > tbody > tr:has(+ tr.regit-tkt-details--empty) .hide-tckt-slctr-tkt-details {
    display: none;
}

/* --------------------------------------------------------------- states ---- */

/*
 * Sold out, sale ended and not-yet-on-sale, said in words rather than implied
 * by a shade of grey.
 *
 * Core already prints the word — EE_Ticket::ticket_status() renders it into the
 * quantity cell — and the wording is core's on purpose: it is translated, and a
 * site owner who changes it should see their change. What was missing was any
 * visual weight, and the column it lives in being off-screen.
 */
.tkt-slctr-tbl-wrap-dv tr.ticket-sales-sold-out .tckt-slctr-tbl-td-qty,
.tkt-slctr-tbl-wrap-dv tr.ticket-sales-expired .tckt-slctr-tbl-td-qty,
.tkt-slctr-tbl-wrap-dv tr.ticket-pending .tckt-slctr-tbl-td-qty {
    font-weight: 700;
    /* Not uppercased. "GOES ON SALE AUGUST 19, 2026" in a narrow column is a
       stack of shouting fragments; sentence case wraps like language.
       Centred only in the table layout — see the media query. */
    hyphens: none;
    /* A stacked label, sized and led as one.
     *
     * This is the only cell whose text length nobody chooses. Core builds
     * "Goes On Sale <date>" from the ticket's own start date, `word-break:
     * keep-all` above keeps the month whole, and the quantity column is about
     * 123px — so a long month sets the label in three lines, "Goes On Sale" /
     * "September 1," / "2026". At the row's own size and body leading that came
     * to a 73px row standing beside 47px and 61px ones, over the 70px this
     * table promises.
     *
     * It also arrives on its own. The date moves with the calendar, so the same
     * code was inside the ceiling in August and outside it in September with
     * nobody deploying anything.
     *
     * Sized down one step with label leading rather than body leading, three
     * lines come to 62px — within a pixel of a row carrying a quantity
     * dropdown, so the pending row now sits level with its neighbours instead of
     * bulging, and there are 8px in hand for a month longer than English has.
     * Measured, not estimated: `tests/browser/ticket-selector.spec.js` asserts
     * the ceiling on every row at both widths. */
    font-size: var(--regit-tkt-text-xs);
    line-height: 1.15;
}

/* The colour has to go on the SPAN core puts inside the cell, not on the cell:
   EEH_HTML::span() wraps the word in .sold-out / .ticket-sales-expired /
   .ticket-pending, and a colour on the inner element wins whatever the cell
   says. Styling only the cell left "Expired" in core's grey while "Sold Out"
   looked right, which is the kind of half-applied rule that reads as a
   deliberate distinction. */
.tkt-slctr-tbl-wrap-dv tr.ticket-sales-sold-out .tckt-slctr-tbl-td-qty,
.tkt-slctr-tbl-wrap-dv tr.ticket-sales-expired .tckt-slctr-tbl-td-qty,
.tkt-slctr-tbl-wrap-dv .tckt-slctr-tbl-td-qty .sold-out,
.tkt-slctr-tbl-wrap-dv .tckt-slctr-tbl-td-qty .ticket-sales-sold-out,
.tkt-slctr-tbl-wrap-dv .tckt-slctr-tbl-td-qty .ticket-sales-expired {
    color: var(--regit-tkt-sold-out);
}

.tkt-slctr-tbl-wrap-dv tr.ticket-pending .tckt-slctr-tbl-td-qty,
.tkt-slctr-tbl-wrap-dv .tckt-slctr-tbl-td-qty .ticket-pending {
    color: var(--regit-tkt-pending);
}

/* An unavailable row is quieter than a buyable one, but still legible: the
   name and price stay readable so a buyer can see what they missed and what
   the alternatives cost. */
.tkt-slctr-tbl-wrap-dv tr.ticket-sales-sold-out .tckt-slctr-tbl-td-name,
.tkt-slctr-tbl-wrap-dv tr.ticket-sales-expired .tckt-slctr-tbl-td-name,
.tkt-slctr-tbl-wrap-dv tr.ticket-sales-sold-out .tckt-slctr-tbl-td-price,
.tkt-slctr-tbl-wrap-dv tr.ticket-sales-expired .tckt-slctr-tbl-td-price {
    color: var(--regit-tkt-ink-muted);
}

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

/* box-sizing first. Without it `width: 100%` plus padding and a border makes
   the control wider than its cell, which widened the table past its wrapper and
   clipped the status column: "Sold Ou", "Goes On Sa". The page did not scroll,
   because an ancestor clips the overflow, so the text was simply gone. Themes
   vary on whether they set border-box globally, so a product cannot assume it. */
.tkt-slctr-tbl-wrap-dv select,
.tkt-slctr-tbl-wrap-dv input,
.tkt-slctr-tbl-wrap-dv button,
.tkt-slctr-tbl-wrap-dv .ticket-selector-submit-btn {
    box-sizing: border-box;
}

.tkt-slctr-tbl-wrap-dv select,
.tkt-slctr-tbl-wrap-dv input[type="number"] {
    width: 100%;
    min-height: var(--regit-tkt-tap);
    padding: var(--regit-tkt-space-xs);
    /* Never below 16px: mobile Safari zooms the page on focus below that, and
       the buyer loses their place before they have chosen anything. */
    font-size: var(--regit-tkt-text-base);
    color: var(--regit-tkt-ink);
    background: #fff;
    border: 1px solid #8c8f94;
    border-radius: var(--regit-tkt-radius);
}

.tkt-slctr-tbl-wrap-dv .ticket-selector-submit-btn,
.tkt-slctr-tbl-wrap-dv input[type="submit"] {
    display: block;
    width: 100%;
    min-height: var(--regit-tkt-tap);
    margin-top: var(--regit-tkt-space-md);
    padding: var(--regit-tkt-space-xs) var(--regit-tkt-space-md);
    font-size: var(--regit-tkt-text-base);
    font-weight: 600;
    line-height: var(--regit-tkt-leading);
    color: #fff;
    background: var(--regit-tkt-accent);
    border: 1px solid transparent;
    border-radius: var(--regit-tkt-radius);
    cursor: pointer;
}

.tkt-slctr-tbl-wrap-dv .ticket-selector-submit-btn:hover,
.tkt-slctr-tbl-wrap-dv input[type="submit"]:hover {
    background: var(--regit-tkt-accent-hover);
}

/* Nothing is buyable — every ticket sold out or expired. Core disables the
   button; it should look disabled rather than merely refuse. */
.tkt-slctr-tbl-wrap-dv .ticket-selector-submit-btn[disabled],
.tkt-slctr-tbl-wrap-dv input[type="submit"][disabled] {
    background: var(--regit-tkt-ink-muted);
    cursor: not-allowed;
}

.tkt-slctr-tbl-wrap-dv a:focus-visible,
.tkt-slctr-tbl-wrap-dv select:focus-visible,
.tkt-slctr-tbl-wrap-dv input:focus-visible,
.tkt-slctr-tbl-wrap-dv button:focus-visible {
    outline: 3px solid var(--regit-tkt-accent);
    outline-offset: 2px;
}

/* ------------------------------------------------------------- details ---- */

/*
 * The description, which in the default scope is the whole panel.
 *
 * Sized here for the same reason the row cells are: the theme sets the measure
 * for article paragraphs and wins on a container rule.
 */
.tkt-slctr-tbl-wrap-dv .tckt-slctr-tkt-details-sctn {
    margin: 0;
    padding: 0;
}

.tkt-slctr-tbl-wrap-dv .tckt-slctr-tkt-details-sctn > p {
    margin: 0;
    padding: var(--regit-tkt-space-2xs) 0 0;
    max-width: 65ch;
    font-size: var(--regit-tkt-text-base);
    line-height: var(--regit-tkt-leading);
}

/*
 * "Details" is what the link the buyer just clicked already said, so the
 * heading is kept for the document outline and taken off the screen. Removing
 * it instead would leave the panel's content with no accessible name.
 */
.tkt-slctr-tbl-wrap-dv .tckt-slctr-tkt-details-sctn > h2 {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* The expandable per-ticket details, and the datetime list beneath the table. */
.tkt-slctr-tbl-wrap-dv .tckt-slctr-tkt-details-tbl th,
.tkt-slctr-tbl-wrap-dv .tckt-slctr-tkt-details-tbl td {
    padding: var(--regit-tkt-space-xs);
    font-size: var(--regit-tkt-text-sm);
    line-height: var(--regit-tkt-leading);
}

.tkt-slctr-tbl-wrap-dv .tckt-slctr-tkt-datetime-ul {
    margin: var(--regit-tkt-space-sm) 0;
    padding-inline-start: var(--regit-tkt-space-md);
}

.tkt-slctr-tbl-wrap-dv .tckt-slctr-tkt-datetime-li {
    margin-bottom: var(--regit-tkt-space-xs);
    line-height: var(--regit-tkt-leading);
}

/* --------------------------------------------------------------- wider ---- */

@media (min-width: 48em) {
    /* A table again, where there is room for three columns. */
    .tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl {
        display: table;
        width: 100%;
        border-collapse: collapse;
        table-layout: fixed;
    }

    /* Fixed layout plus explicit columns, so the header sits over the data it
       names. Left to size themselves, the three short header words took 236px
       of a 645px table while the body rows used all of it, and the labels
       floated above the wrong columns. */
    /* The name is the long column and the other two hold a price and a select,
       so the width goes where the words are: a ticket name that fits on one
       line is a row that is one line tall. */
    .tkt-slctr-tbl-wrap-dv .ee-ticket-selector-ticket-details-th {
        width: 64%;
    }

    .tkt-slctr-tbl-wrap-dv .ee-ticket-selector-ticket-price-th,
    .tkt-slctr-tbl-wrap-dv .ee-ticket-selector-ticket-qty-th {
        width: 18%;
    }

    .tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl > tbody {
        display: table-row-group;
    }

    .tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl > tbody > tr {
        display: table-row;
        padding: 0;
    }

    .tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl > tbody > tr > td {
        display: table-cell;
        padding: var(--regit-tkt-space-xs) var(--regit-tkt-space-sm);
        border-bottom: 1px solid var(--regit-tkt-line);
        vertical-align: top;
    }

    .tkt-slctr-tbl-wrap-dv tr.ticket-sales-sold-out .tckt-slctr-tbl-td-qty,
    .tkt-slctr-tbl-wrap-dv tr.ticket-sales-expired .tckt-slctr-tbl-td-qty,
    .tkt-slctr-tbl-wrap-dv tr.ticket-pending .tckt-slctr-tbl-td-qty {
        text-align: center;
    }

    .tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl thead {
        position: static;
        width: auto;
        height: auto;
        overflow: visible;
        clip-path: none;
        white-space: normal;
    }

    .tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl tbody td {
        padding: var(--regit-tkt-space-xs) var(--regit-tkt-space-sm);
    }

    /* The details row is spacing-free at every width — see the rule above the
       media query. Repeated here because the table-layout rules above
       reintroduce both padding and a border, and a border on a collapsed row
       draws a second line under every ticket. */
    .tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl tbody td.tckt-slctr-tkt-details-td,
    .tkt-slctr-tbl-wrap-dv .tkt-slctr-tbl > tbody > tr > td.tckt-slctr-tkt-details-td {
        padding: 0;
        border-bottom: none;
    }

    .tkt-slctr-tbl-wrap-dv select,
    .tkt-slctr-tbl-wrap-dv input[type="number"] {
        max-width: 8rem;
        margin-inline: auto;
    }

    .tkt-slctr-tbl-wrap-dv .ticket-selector-submit-btn,
    .tkt-slctr-tbl-wrap-dv input[type="submit"] {
        width: auto;
        min-width: 14rem;
        margin-inline-start: auto;
    }
}

/* ---------------------------------------------------------------- error ---- */

/*
 * REGIT-035. What a visitor sees when they press Register Now with nothing
 * chosen. assets/js/ticket-selector-validation.js inserts it; with that script
 * absent none of this renders and core's server-side notice takes over.
 *
 * At the button rather than beside a control, because "nothing is chosen" is a
 * fault of the form. Putting it in the quantity cell was built and rejected:
 * that column is 18% of the table and the sentence wrapped to three lines, and
 * on a seven-ticket event it would have to pick a row to sit beside.
 */
.tkt-slctr-tbl-wrap-dv .regit-form-error {
    display: flex;
    align-items: flex-start;
    gap: var(--regit-tkt-space-xs);
    max-width: 34rem;
    margin: 0 0 var(--regit-tkt-space-sm);
    padding: 0.625rem 0.75rem;
    border: 1px solid var(--regit-tkt-error-line);
    /* Not colour alone, per WCAG 1.4.1: the bar and the icon carry the meaning
       as shape, and the hue reinforces it. */
    border-inline-start: 4px solid var(--regit-tkt-error-line);
    border-radius: var(--regit-tkt-radius);
    background: var(--regit-tkt-error-bg);
    font-size: var(--regit-tkt-text-base);
    font-weight: 500;
    line-height: 1.5;
    color: var(--regit-tkt-error-ink);
    text-align: start;
}

.tkt-slctr-tbl-wrap-dv .regit-form-error__icon {
    display: flex;
    flex: none;
    margin-top: 0.1em;
}

.tkt-slctr-tbl-wrap-dv .regit-form-error svg {
    width: 1.15em;
    height: 1.15em;
    fill: var(--regit-tkt-error-line);
}

/* The submit row is right-aligned at 48em and up; a message inside it has to
   stop being a row and become a stack, or it sits beside the button. */
.tkt-slctr-tbl-wrap-dv .ticket-selector-submit-btn-wrap:has(.regit-form-error) {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
}

/* The one-ticket case, where there really is a single control at fault. With
   several, the script marks none of them rather than blaming an arbitrary row. */
.tkt-slctr-tbl-wrap-dv select[aria-invalid="true"],
.tkt-slctr-tbl-wrap-dv input[aria-invalid="true"] {
    border: 2px solid var(--regit-tkt-error-field);
    background-color: #fffafa;
}

/*
 * Regit's own, because core's `.ee-a11y-screen-reader-text` is defined in
 * ticket_selector.css, and that stylesheet is only enqueued when
 * FHEE__EED_Ticket_Selector__load_tckt_slctr_assets returns true — which
 * defaults to false. Depending on it would mean depending on a rule that is
 * usually not on the page, and the failure mode is the word "Error:" appearing
 * in the middle of the sentence.
 */
.tkt-slctr-tbl-wrap-dv .regit-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}
