/* Table Bookings — magic-link flow (dark/gold, matches the booking page) */

/* .hp-tb-toasts is listed alongside .hp-tb because frontend.js hoists the toast
   container to <body> to escape Divi's transformed content wrapper. Outside .hp-tb
   every one of these custom properties resolves to nothing, which left the toast
   with default browser colours — grey text on a dark card, far too quiet to
   notice. It needs its own copy of the palette, not a parent to inherit from. */
.hp-tb,
.hp-tb-toasts {
    --hp-gold: #E8B156;
    --hp-gold-soft: rgba(232, 177, 86, .13);
    --hp-gold-line: rgba(232, 177, 86, .42);
    /* Derived from the accent in PHP (hp_tb_accent_css); these literals are the
       fallback if that inline style is ever missing. */
    --hp-gold-hover: #edbb68;
    --hp-gold-fill: rgba(232, 177, 86, .16);
    --hp-gold-edge: rgba(232, 177, 86, .5);
    --hp-gold-glow: rgba(232, 177, 86, .35);
    --hp-on-gold: #1a1408;
    --hp-surface: #1a1a1a;
    --hp-surface-2: #222222;
    --hp-line: rgba(255, 255, 255, .09);
    --hp-text: #F4F2ED;
    --hp-muted: #9d9a93;
    --hp-danger: #e05540;
    --hp-ok: #4caf7d;
    font-family: 'Lato', sans-serif;
    color: var(--hp-text);
    -webkit-font-smoothing: antialiased;
}

.hp-tb *,
.hp-tb-toasts,
.hp-tb-toasts * { box-sizing: border-box; }

/* ── Page header ───────────────────────────────────────────────
   Replaces the old order-ref line + per-table cards. Palette additions on top
   of the existing gold/green vars, taken from the design handoff. */
.hp-tb,
.hp-tb-toasts {
    --hp-row: #191817;
    --hp-row-ok: #181a17;
    --hp-hair: #2a2725;
    --hp-hair-ok: #2c3327;
    --hp-chip: #211f1e;
    --hp-chip-ok: #1f221e;
    --hp-chip-line: #302d2a;
    --hp-track: #211f1e;
    --hp-track-row: #262322;
    --hp-track-ok: #242822;
    --hp-dim: #8c847b;
    --hp-dimmer: #7d766e;
    --hp-off: #5f5952;
    --hp-dash: #55504a;
    --hp-on-gold: #1a1408;
    /* No webfont for this on the front end — the theme provides Lato for UI text,
       so the row index just needs tabular-ish digits from the system stack. */
    --hp-mono: ui-monospace, SFMono-Regular, Menlo, monospace;
}

.hp-tb-head { margin: 0 0 20px; }
.hp-tb-eyebrow {
    margin: 0; font-size: 12px; font-weight: 500; line-height: 1;
    letter-spacing: .09em; text-transform: uppercase; color: var(--hp-dim);
}
.hp-tb-h1 {
    margin: 14px 0 8px; font-size: 34px; font-weight: 700; line-height: 1.15;
    letter-spacing: -.01em; color: #f5f2ec;
}
.hp-tb-lede {
    margin: 0; max-width: 640px; font-size: 16px; line-height: 1.55;
    color: var(--hp-muted); text-wrap: pretty;
}

/* Tracks tables assigned, not overall progress — see the note in shortcode.php. */
.hp-tb-topbar { display: flex; align-items: center; gap: 16px; margin: 26px 0 0; }
.hp-tb-topbar-track {
    flex: 1; height: 6px; border-radius: 99px; background: var(--hp-track); overflow: hidden;
}
.hp-tb-topbar-fill {
    display: block; height: 100%; border-radius: 99px; background: var(--hp-gold);
    transition: width .3s ease-out;
}
.hp-tb-topbar-count {
    display: inline-flex; align-items: center; gap: 7px;
    font-size: 13px; font-weight: 600; line-height: 1; color: var(--hp-muted); white-space: nowrap;
}
/* Named container for the queries at the end of this file. inline-size only, so
   height still grows with content. */
.hp-tb-summary { container-type: inline-size; container-name: hptb; }
.hp-tb-summary.is-done .hp-tb-topbar-track { background: var(--hp-track-ok); }
.hp-tb-summary.is-done .hp-tb-topbar-fill { background: var(--hp-ok); }
.hp-tb-summary.is-done .hp-tb-topbar-count { color: var(--hp-ok); }

/* ── Tracker ───────────────────────────────────────────────────
   One row per table. The 1px gap over the container background draws the
   hairlines, so rows need no borders of their own. */
.hp-tb-trk {
    list-style: none; margin: 0 0 26px; padding: 0;
    display: flex; flex-direction: column; gap: 1px;
    background: var(--hp-hair); border: 1px solid var(--hp-hair);
    border-radius: 10px; overflow: hidden;
}
.hp-tb-trk.is-done { background: var(--hp-hair-ok); border-color: var(--hp-hair-ok); }

.hp-tb-trk-row {
    display: flex; align-items: center; gap: 18px;
    padding: 14px 18px; background: var(--hp-row);
    transition: background .15s ease;
}
.hp-tb-trk-row.is-complete { background: var(--hp-row-ok); }

.hp-tb-trk-badge {
    width: 26px; height: 26px; flex: none; border-radius: 99px;
    display: flex; align-items: center; justify-content: center;
    font-family: var(--hp-mono);
    font-size: 11px; font-weight: 600; line-height: 1; color: var(--hp-dim);
    border: 1.5px dashed var(--hp-dash);
}
.hp-tb-trk-row.is-needs-guests .hp-tb-trk-badge {
    border: 1.5px solid var(--hp-gold-edge); background: var(--hp-gold-fill); color: var(--hp-gold);
}
.hp-tb-trk-row.is-complete .hp-tb-trk-badge {
    border: 1.5px solid rgba(76, 175, 125, .5); background: rgba(76, 175, 125, .08);
    color: var(--hp-ok); font-family: inherit; font-size: 13px; font-weight: 700;
}

.hp-tb-trk-main { flex: 1; min-width: 0; display: flex; align-items: center; gap: 18px; }
.hp-tb-trk-name { width: 190px; flex: none; font-size: 15px; font-weight: 700; line-height: 1; color: #f5f2ec; }
.hp-tb-trk-meta { flex: 1; min-width: 0; display: flex; align-items: center; gap: 18px; }

.hp-tb-trk-num {
    width: 230px; flex: none; display: flex; align-items: center; gap: 8px;
    font-size: 14px; font-weight: 500; line-height: 1; color: var(--hp-muted);
}
.hp-tb-trk-val { font-weight: 700; color: #f5f2ec; }
.hp-tb-trk-val.is-todo { color: var(--hp-gold); }
.hp-tb-trk-key-m { display: none; }

.hp-tb-trk-guests { width: 230px; flex: none; display: flex; align-items: center; gap: 9px; }
.hp-tb-trk-glabel { flex: 1; min-width: 0; font-size: 14px; font-weight: 500; line-height: 1; }
.hp-tb-trk-gm { display: none; }
.hp-tb-trk-guests.is-wait .hp-tb-trk-glabel { color: var(--hp-off); }
.hp-tb-trk-guests.is-todo .hp-tb-trk-glabel { color: var(--hp-gold); }
.hp-tb-trk-guests.is-part .hp-tb-trk-glabel { color: var(--hp-text-2, #cfc9c1); }
.hp-tb-trk-guests.is-ok .hp-tb-trk-glabel { color: var(--hp-ok); font-weight: 600; }
/* Fixed width, deliberately: as flex:1 the bar changed length row to row
   because "1/1" is narrower than "10/10". */
.hp-tb-trk-bar {
    width: 88px; flex: none; height: 5px; border-radius: 99px;
    background: var(--hp-track-row); overflow: hidden;
}
.hp-tb-trk-fill {
    display: block; height: 100%; border-radius: 99px; background: var(--hp-gold);
    transition: width .3s ease-out;
}
.hp-tb-trk-guests.is-ok .hp-tb-trk-bar { background: var(--hp-track-ok); }
.hp-tb-trk-guests.is-ok .hp-tb-trk-fill { background: var(--hp-ok); }

.hp-tb-locktag {
    display: inline-flex; align-items: center; gap: 4px; flex: none;
    font-size: 11px; font-weight: 600; line-height: 1; color: var(--hp-dimmer);
    background: var(--hp-chip); border: 1px solid var(--hp-chip-line);
    padding: 4px 7px; border-radius: 99px; white-space: nowrap;
}
.hp-tb-locktag svg { display: block; fill: var(--hp-dimmer); }
.hp-tb-trk-row.is-complete .hp-tb-locktag { background: var(--hp-chip-ok); border-color: var(--hp-hair-ok); }

.hp-tb-trk-cta {
    flex: none; margin-left: auto; text-decoration: none; white-space: nowrap;
    line-height: 1; border-radius: 7px; transition: .15s ease;
}
.hp-tb-trk-cta.is-primary {
    background: var(--hp-gold); color: var(--hp-on-gold);
    font-size: 13px; font-weight: 700; padding: 10px 16px; border: 1px solid var(--hp-gold);
}
.hp-tb-trk-cta.is-primary:hover { background: var(--hp-gold-hover); border-color: var(--hp-gold-hover); }
.hp-tb-trk-cta.is-quiet {
    background: transparent; color: #cfc9c1; border: 1px solid #3a4034;
    font-size: 13px; font-weight: 600; padding: 9px 15px;
}
.hp-tb-trk-cta.is-quiet:hover { border-color: #4a5142; background: rgba(255, 255, 255, .03); }
.hp-tb-trk-cta:focus-visible { outline: 2px solid var(--hp-gold); outline-offset: 2px; }

/* ── Theme hardening ──────────────────────────────────────────
   Divi resets content lists with `#left-area ol, .entry-content ol, .et-l--body
   ol, …` { list-style-type: decimal; padding: 0 0 23px; line-height: 26px }.
   That is an ID selector, so no amount of class specificity on .hp-tb-trk beats
   it — hence the #hp-tb scope, which matches Divi on ID count and wins on
   classes. Left unhandled it added 23px of dead space under the tracker and its
   line-height inherited down, inflating the row buttons from 39px to 48px.

   Note specificity is per-property: the h1 and p rules below win on class alone,
   but only for properties we actually declare, and we never declared padding —
   so Divi's `h1 { padding-bottom: 10px }` and `p { padding-bottom: 1em }` were
   applying. The lede only looked right by accident, being the last <p> and so
   caught by Divi's :last-of-type override. Declared explicitly now. */
#hp-tb .hp-tb-trk {
    padding: 0;
    list-style: none;
    /* Children set their own; this stops 26px cascading into the rows. */
    line-height: 1.3;
}
#hp-tb .hp-tb-h1,
#hp-tb .hp-tb-eyebrow,
#hp-tb .hp-tb-lede { padding: 0; }

/* Tablet: name on its own line, meta wraps beneath, CTA stays right. */
@media (max-width: 1023px) {
    .hp-tb-h1 { font-size: 28px; }
    .hp-tb-lede { font-size: 15px; line-height: 1.5; }
    .hp-tb-topbar { gap: 14px; margin-top: 22px; }
    .hp-tb-trk-row { gap: 14px; padding: 16px 18px; }
    .hp-tb-trk-main { flex-direction: column; align-items: flex-start; gap: 8px; }
    .hp-tb-trk-name { width: auto; }
    .hp-tb-trk-meta { flex-wrap: wrap; gap: 14px; width: 100%; }
    .hp-tb-trk-num { width: auto; font-size: 13px; }
    .hp-tb-trk-guests { width: 170px; }
    .hp-tb-trk-glabel { font-size: 13px; }
    .hp-tb-trk-bar { width: 60px; }
    .hp-tb-trk-cta.is-primary { padding: 11px 15px; }
}

/* Mobile: each table becomes a card — label/value rows and a full-width CTA. */
@media (max-width: 639px) {
    .hp-tb-eyebrow { font-size: 10.5px; }
    .hp-tb-eyebrow-who { display: none; }
    .hp-tb-h1 { font-size: 24px; line-height: 1.2; margin-top: 10px; }
    .hp-tb-lede { font-size: 14px; }
    .hp-tb-topbar { gap: 12px; margin-top: 18px; }
    .hp-tb-topbar-count { font-size: 12px; }

    .hp-tb-trk {
        gap: 12px; background: none; border: none; border-radius: 0; overflow: visible;
    }
    .hp-tb-trk.is-done { background: none; border: none; }
    .hp-tb-trk-row {
        display: block; padding: 16px; border-radius: 10px;
        border: 1px solid var(--hp-hair);
    }
    .hp-tb-trk-row.is-complete { border-color: var(--hp-hair-ok); }
    /* Badge + name form the card header, so the badge leaves the flex row. */
    .hp-tb-trk-badge {
        width: 24px; height: 24px; font-size: 10.5px;
        float: left; margin: 0 10px 14px 0;
    }
    .hp-tb-trk-main { display: block; }
    .hp-tb-trk-name { display: block; font-size: 16px; line-height: 24px; margin-bottom: 14px; }
    .hp-tb-trk-meta { display: block; }

    /* "Table no. 67" becomes "Table number | 67" on its own row. */
    .hp-tb-trk-num, .hp-tb-trk-guests {
        width: auto; display: flex; align-items: center; justify-content: space-between;
        gap: 10px; font-size: 13px;
    }
    .hp-tb-trk-num { padding-bottom: 10px; border-bottom: 1px solid #232120; }
    .hp-tb-trk-row.is-complete .hp-tb-trk-num { border-bottom-color: var(--hp-hair-ok); }
    .hp-tb-trk-key { display: none; }
    .hp-tb-trk-key-m { display: block; color: var(--hp-dim); font-weight: 500; }
    .hp-tb-trk-num .hp-tb-trk-val { margin-left: auto; font-size: 14px; }
    .hp-tb-trk-dash { display: none; }

    .hp-tb-trk-guests { padding: 10px 0 4px; flex-wrap: wrap; }
    .hp-tb-trk-glabel { flex: none; order: 2; margin-left: auto; font-size: 14px; font-weight: 700; }
    .hp-tb-trk-gd { display: none; }
    .hp-tb-trk-gm { display: block; }
    /* Label rows first, then the bar full-width beneath both. */
    .hp-tb-trk-guests::before {
        content: 'Guest details'; order: 1; font-size: 13px; font-weight: 500; color: var(--hp-dim);
    }
    .hp-tb-trk-bar { order: 3; width: 100%; margin-top: 12px; }
    .hp-tb-trk-glock { order: 4; margin-top: 10px; }

    .hp-tb-trk-cta {
        display: flex; align-items: center; justify-content: center;
        margin: 16px 0 0; height: 48px; width: 100%;
        font-size: 15px; border-radius: 8px;
    }
    .hp-tb-trk-cta.is-primary, .hp-tb-trk-cta.is-quiet { padding: 0; font-weight: 700; }
}

/* ── Same layouts, keyed on the CONTAINER ──────────────────────
   The media queries above are keyed on the viewport, but the width this
   component actually gets is set by the theme: the magic-link page runs Divi's
   right-sidebar layout, so at a 1180px viewport the content column is only
   ~846px — too narrow for the one-line row, which overlapped the button with
   the guest bar. Container queries fix that properly.

   Both are kept deliberately. They apply identical declarations, so whichever
   matches gives the same result: the container query handles a narrow column on
   a wide screen, and the viewport query still covers browsers without container
   query support (pre-2023), where the fallback is today's behaviour rather than
   no responsive layout at all. Generated from the blocks above — keep in step. */
@container hptb (max-width: 930px) {
    .hp-tb-h1 { font-size: 28px; }
    .hp-tb-lede { font-size: 15px; line-height: 1.5; }
    .hp-tb-topbar { gap: 14px; margin-top: 22px; }
    .hp-tb-trk-row { gap: 14px; padding: 16px 18px; }
    .hp-tb-trk-main { flex-direction: column; align-items: flex-start; gap: 8px; }
    .hp-tb-trk-name { width: auto; }
    .hp-tb-trk-meta { flex-wrap: wrap; gap: 14px; width: 100%; }
    .hp-tb-trk-num { width: auto; font-size: 13px; }
    .hp-tb-trk-guests { width: 170px; }
    .hp-tb-trk-glabel { font-size: 13px; }
    .hp-tb-trk-bar { width: 60px; }
    .hp-tb-trk-cta.is-primary { padding: 11px 15px; }
}

@container hptb (max-width: 440px) {
    .hp-tb-eyebrow { font-size: 10.5px; }
    .hp-tb-eyebrow-who { display: none; }
    .hp-tb-h1 { font-size: 24px; line-height: 1.2; margin-top: 10px; }
    .hp-tb-lede { font-size: 14px; }
    .hp-tb-topbar { gap: 12px; margin-top: 18px; }
    .hp-tb-topbar-count { font-size: 12px; }

    .hp-tb-trk {
        gap: 12px; background: none; border: none; border-radius: 0; overflow: visible;
    }
    .hp-tb-trk.is-done { background: none; border: none; }
    .hp-tb-trk-row {
        display: block; padding: 16px; border-radius: 10px;
        border: 1px solid var(--hp-hair);
    }
    .hp-tb-trk-row.is-complete { border-color: var(--hp-hair-ok); }
    /* Badge + name form the card header, so the badge leaves the flex row. */
    .hp-tb-trk-badge {
        width: 24px; height: 24px; font-size: 10.5px;
        float: left; margin: 0 10px 14px 0;
    }
    .hp-tb-trk-main { display: block; }
    .hp-tb-trk-name { display: block; font-size: 16px; line-height: 24px; margin-bottom: 14px; }
    .hp-tb-trk-meta { display: block; }

    /* "Table no. 67" becomes "Table number | 67" on its own row. */
    .hp-tb-trk-num, .hp-tb-trk-guests {
        width: auto; display: flex; align-items: center; justify-content: space-between;
        gap: 10px; font-size: 13px;
    }
    .hp-tb-trk-num { padding-bottom: 10px; border-bottom: 1px solid #232120; }
    .hp-tb-trk-row.is-complete .hp-tb-trk-num { border-bottom-color: var(--hp-hair-ok); }
    .hp-tb-trk-key { display: none; }
    .hp-tb-trk-key-m { display: block; color: var(--hp-dim); font-weight: 500; }
    .hp-tb-trk-num .hp-tb-trk-val { margin-left: auto; font-size: 14px; }
    .hp-tb-trk-dash { display: none; }

    .hp-tb-trk-guests { padding: 10px 0 4px; flex-wrap: wrap; }
    .hp-tb-trk-glabel { flex: none; order: 2; margin-left: auto; font-size: 14px; font-weight: 700; }
    .hp-tb-trk-gd { display: none; }
    .hp-tb-trk-gm { display: block; }
    /* Label rows first, then the bar full-width beneath both. */
    .hp-tb-trk-guests::before {
        content: 'Guest details'; order: 1; font-size: 13px; font-weight: 500; color: var(--hp-dim);
    }
    .hp-tb-trk-bar { order: 3; width: 100%; margin-top: 12px; }
    .hp-tb-trk-glock { order: 4; margin-top: 10px; }

    .hp-tb-trk-cta {
        display: flex; align-items: center; justify-content: center;
        margin: 16px 0 0; height: 48px; width: 100%;
        font-size: 15px; border-radius: 8px;
    }
    .hp-tb-trk-cta.is-primary, .hp-tb-trk-cta.is-quiet { padding: 0; font-weight: 700; }
}


.hp-tb-venue { margin: 0 0 26px; text-align: center; }
.hp-tb-venue-img { max-width: 100%; height: auto; border-radius: 14px; border: 1px solid var(--hp-line); padding: 40px; }

.hp-tb-card {
    background: var(--hp-surface);
    border: 1px solid var(--hp-line);
    border-radius: 16px;
    padding: 26px 26px 24px;
    margin-bottom: 22px;
}
.hp-tb-invalid h3 { margin: 0 0 10px; color: var(--hp-text); }
.hp-tb-invalid a { color: var(--hp-gold); }

.hp-tb-unit-title { margin: 0 0 6px; font-size: 22px; font-weight: 700; color: #fff; }
.hp-tb-choose-note { margin: 0 0 16px; color: var(--hp-muted); font-size: 15px; }

/* Stage 1: table numbers */
.hp-tb-numbers { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 20px; }
.hp-tb-number {
    display: flex; flex-direction: column; align-items: center; gap: 2px;
    min-width: 92px; padding: 12px 16px;
    background: var(--hp-surface-2); border: 1px solid var(--hp-line); border-radius: 12px;
    cursor: pointer; transition: border-color .15s, background .15s;
    font-size: 15px;
}
.hp-tb-number:hover { border-color: var(--hp-gold-line); }
.hp-tb-number input { position: absolute; opacity: 0; pointer-events: none; }
.hp-tb-number:has(input:checked),
.hp-tb-number.is-checked {
    border-color: var(--hp-gold);
    background: var(--hp-gold-soft);
}
.hp-tb-number-label { font-weight: 700; color: var(--hp-text); }
.hp-tb-number small { color: var(--hp-muted); font-size: 12px; }

/* Screen-reader-only (frontend copy; admin.css has its own) */
.hp-tb-sr {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* ── Stage 1 alternative: interactive floorplan ──────────
   The plan and the chip list share one .hp-tb-numbers (frontend.js's
   rebuildNumbers() targets that class, so there can only be one). Both take a
   full flex row; bare .hp-tb-number chips appended straight into the container
   by rebuildNumbers still flow exactly as they did before. */
.hp-tb-plan,
.hp-tb-choices,
.hp-tb-offplan { flex: 1 0 100%; min-width: 0; }
.hp-tb-choices,
.hp-tb-choices-row { display: flex; flex-wrap: wrap; gap: 10px; }
.hp-tb-offplan { margin: 0 0 16px; }
.hp-tb-offplan-lead { margin: 0 0 9px; font-size: 13.5px; color: var(--hp-muted); }

/* The plan is drawn, not overlaid on artwork. Padding on the OUTER box keeps
   tables clear of the border; the inner layer is the coordinate space the grid
   percentages refer to, so the padding can't throw positions off. */
.hp-tb-plan {
    position: relative; margin: 0 0 12px; padding: 26px;
    border: 1px solid var(--hp-line); border-radius: 14px;
    background: var(--hp-surface-2);
}
.hp-tb-plan-layer {
    position: relative;
    /* Square-ish cells, so round tables sit on an even grid at any width. */
    aspect-ratio: var(--hp-tb-cols, 12) / var(--hp-tb-rows, 6);
}

.hp-tb-plan-stage {
    position: absolute; display: flex; align-items: center; justify-content: center;
    border-radius: 10px; background: rgba(255, 255, 255, .13);
    border: 1px solid rgba(255, 255, 255, .18); box-sizing: border-box;
    min-height: 22px; overflow: hidden;
}
.hp-tb-plan-stage span {
    color: #fff; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
    font-size: clamp(10px, 1.4vw, 17px); white-space: nowrap;
}

/* --hp-tb-r is the table diameter as a % of the plan width, derived from the
   grid so tables always leave a gap. The px floor keeps a dense room legible. */
.hp-tb-number.hp-tb-marker {
    position: absolute; transform: translate(-50%, -50%);
    width: var(--hp-tb-r, 6%); aspect-ratio: 1;
    min-width: 26px; min-height: 26px; padding: 0; gap: 0;
    border-radius: 50%; align-items: center; justify-content: center;
    line-height: 1; text-align: center;
    /* In practice this always resolves to the 13px minimum, and that is what
       makes the numbers readable. The middle term does NOT scale with the plan:
       --hp-tb-r is a percentage (4.875% for a 16-column room) and a percentage
       in font-size is relative to the PARENT FONT SIZE, not the width — so
       calc(4.875% * 0.34) is ~0.27px, far below the floor, and the 16px ceiling
       can never be reached. Measured 13px at both a 1114px and a 704px plan.
       Kept in this form deliberately: the floor is the knob worth turning. To
       make it genuinely proportional the unit would have to change (cqw against
       the plan as a container), which is a different change. */
    font-size: clamp(13px, calc(var(--hp-tb-r, 6%) * 0.34), 16px);
}
.hp-tb-number.hp-tb-marker .hp-tb-number-label { font-size: inherit; font-weight: 700; }

/* Bookable */
.hp-tb-marker.is-free,
.hp-tb-marker.is-partial {
    background: var(--hp-gold-soft); border-color: var(--hp-gold-line); cursor: pointer;
}
.hp-tb-marker.is-free:hover,
.hp-tb-marker.is-partial:hover { background: var(--hp-gold); }
.hp-tb-marker.is-free:hover .hp-tb-number-label,
.hp-tb-marker.is-partial:hover .hp-tb-number-label { color: var(--hp-on-gold); }
.hp-tb-marker.is-partial { border-style: dashed; }

/* Not bookable — inert spans, no input to check */
.hp-tb-marker.is-taken,
.hp-tb-marker.is-other,
.hp-tb-marker.is-unsold {
    background: rgba(255, 255, 255, .05); border-color: var(--hp-line);
    color: var(--hp-muted); cursor: default;
}
.hp-tb-marker.is-taken { background: rgba(224, 85, 64, .16); border-color: rgba(224, 85, 64, .3); }
.hp-tb-marker.is-taken .hp-tb-number-label,
.hp-tb-marker.is-other .hp-tb-number-label,
.hp-tb-marker.is-unsold .hp-tb-number-label { color: var(--hp-muted); font-weight: 400; }

/* Chosen + keyboard focus. The radio stays in the layout (opacity:0, not
   display:none) precisely so it remains focusable.
   .is-checked is the path that actually runs: frontend.js adds it on the change
   event. The :has() variants are a no-JS bonus — note they don't re-evaluate
   when .checked is set programmatically, only on real interaction. The state
   classes are repeated in each selector so this beats .is-free/.is-partial
   however :has() specificity happens to be counted, and border-style resets the
   dashed edge that .is-partial applies. */
.hp-tb-marker.is-free:has(input:checked),
.hp-tb-marker.is-partial:has(input:checked),
.hp-tb-marker.is-checked { background: var(--hp-gold); border-color: var(--hp-gold); border-style: solid; }
.hp-tb-marker.is-free:has(input:checked) .hp-tb-number-label,
.hp-tb-marker.is-partial:has(input:checked) .hp-tb-number-label,
.hp-tb-marker.is-checked .hp-tb-number-label { color: var(--hp-on-gold); }
.hp-tb-marker:has(input:focus-visible) { outline: 3px solid #fff; outline-offset: 2px; z-index: 2; }
.hp-tb-marker:focus-within { outline: 3px solid #fff; outline-offset: 2px; z-index: 2; }

/* Read-only plan (guest-details screen): this order's own tables, linked to
   their guest sections. Highlighted like a chosen table so the two screens read
   the same way; everything else is inert and grey. */
.hp-tb-marker.is-mine {
    background: var(--hp-gold); border-color: var(--hp-gold); color: var(--hp-on-gold);
    cursor: pointer; text-decoration: none;
}
.hp-tb-marker.is-mine .hp-tb-number-label { color: var(--hp-on-gold); }
.hp-tb-marker.is-mine:hover,
.hp-tb-marker.is-mine:focus-visible { box-shadow: 0 0 0 3px var(--hp-gold-glow); }
.hp-tb-marker.is-off {
    background: rgba(255, 255, 255, .05); border-color: var(--hp-line);
    color: var(--hp-muted); cursor: default; font-weight: 400;
}
.hp-tb-order-plan { margin: 0 0 26px; }

/* The section a plan link jumped to, briefly, so it's obvious where you landed. */
.hp-tb-unit { scroll-margin-top: 20px; }
.hp-tb-unit.is-jump-target { box-shadow: 0 0 0 2px var(--hp-gold-line); transition: box-shadow .25s; }

/* ── [table_plan]: static, colour-coded plan for the public product page ──
   A diagram, not a picker. Nothing here is interactive or focusable; the colour
   carries the meaning and the key names it. Package colours arrive as
   --hp-tb-pkg-<sku> custom properties on the wrapper (includes/package-colours.php)
   and are pulled in per marker via data-sku, so the palette lives in one place
   rather than being inlined onto every table. */
.hp-tb-planview { margin: 0 0 24px; }
.hp-tb-planview-title { margin: 0 0 12px; font-size: 18px; font-weight: 700; color: var(--hp-text); }

/* No gridlines and no pointer affordance — the two things that would make this
   read as something you can act on.

   Sits on --hp-surface rather than the booker plan's --hp-surface-2, which is
   the same #1a1a1a the shop uses for its package cards: on the product page the
   plan reads as one more panel in that stack rather than a lighter box floating
   on top of them. The booker page keeps --hp-surface-2, where the plan IS the
   thing being acted on and should stand off its background. */
.hp-tb-plan.is-static { cursor: default; background: var(--hp-surface); }
.hp-tb-plan.is-static .hp-tb-planview-table { cursor: default; pointer-events: none; }

.hp-tb-planview-table {
    border: 1px solid transparent;
    background: var(--hp-surface);
    color: var(--hp-muted);
    font-weight: 700;
    transition: opacity .22s ease, background .22s ease, border-color .22s ease;
}
/* A table sold by a package: its own colour, tinted rather than solid so the
   number stays readable at 26px. The tints come from PHP as concrete rgba on a
   [data-sku] rule, so marker and swatch can never drift apart and there is no
   color-mix support question on a public page. */
.hp-tb-planview-table.is-package {
    background: var(--hp-tb-pkg-bg);
    border-color: var(--hp-tb-pkg-line);
    color: var(--hp-tb-pkg-ink);
}
/* Sold out: struck through and drained, but still showing its package colour
   faintly so the room's layout still reads. */
.hp-tb-planview-table.is-sold {
    background: rgba(255, 255, 255, .04);
    border-color: rgba(255, 255, 255, .12);
    color: var(--hp-off);
    text-decoration: line-through;
    text-decoration-thickness: 1px;
}
/* Not sold by any package — context only, same treatment as the booker plan. */
.hp-tb-planview-table.is-unsold {
    background: rgba(255, 255, 255, .02);
    border-color: rgba(255, 255, 255, .07);
    color: var(--hp-off);
}

/* Dimmed because the basket now has a different package in it. Opacity rather
   than a colour change, so it reads as "still there, just not yours". */
.hp-tb-planview.is-filtered .hp-tb-planview-table.is-package.is-dimmed,
.hp-tb-planview.is-filtered .hp-tb-planview-table.is-unsold { opacity: .18; }
.hp-tb-planview.is-filtered .hp-tb-planview-key-item.is-dimmed { opacity: .32; }

/* A hover is a peek, not a choice, so it dims less far than the basket state it
   sits on top of — enough to answer "where would I be?", while still reading as
   provisional rather than as the thing you have committed to. */
.hp-tb-planview.is-preview.is-filtered .hp-tb-planview-table.is-package.is-dimmed,
.hp-tb-planview.is-preview.is-filtered .hp-tb-planview-table.is-unsold { opacity: .3; }
.hp-tb-planview.is-preview.is-filtered .hp-tb-planview-key-item.is-dimmed { opacity: .45; }

/* Hovering a key entry previews that package on the plan, which is worth having
   on a page with no shop on it — most pages. Needs a cursor to be findable;
   nothing happens on click, which is why there is no active state. */
.hp-tb-planview-key-item[data-sku] { cursor: pointer; }
.hp-tb-planview-key-item[data-sku]:hover { color: var(--hp-text); }

/* Scaled up ~10% from the booker plan's legend. This key is doing more work than
   that one: on a public page it is the only thing explaining what the colours
   mean, to someone who has no context and has not been told to look. */
.hp-tb-planview-key {
    display: flex; flex-wrap: wrap; gap: 9px 20px;
    margin: 15px 0 0; padding: 0; list-style: none;
}
.hp-tb-planview-key-item {
    display: inline-flex; align-items: center; gap: 9px;
    font-size: 15px; color: var(--hp-muted);
    transition: opacity .22s ease;
}
/* Sized in em so the swatch tracks the label — one number to change if this is
   ever rescaled again, and it can't drift out of proportion. */
.hp-tb-planview-swatch {
    width: 1.04em; height: 1.04em; flex: none; border-radius: 50%;
    background: var(--hp-tb-pkg-bg);
    border: 1px solid var(--hp-tb-pkg-line);
}
.hp-tb-planview-key-item.is-sold-key .hp-tb-planview-swatch {
    background: rgba(255, 255, 255, .04); border-color: rgba(255, 255, 255, .18);
}

/* Only shown at the width where the plan starts scrolling (see the 760px block). */
.hp-tb-plan-scroll-hint {
    display: none; margin: -4px 0 12px; font-size: 12.5px; color: var(--hp-dimmer);
}
.hp-tb-plan-legend { display: flex; flex-wrap: wrap; gap: 16px; margin: 0 0 16px; font-size: 13px; color: var(--hp-muted); }
.hp-tb-key { display: inline-flex; align-items: center; gap: 7px; }
.hp-tb-key::before { content: ''; width: 13px; height: 13px; border-radius: 50%; border: 1px solid var(--hp-line); flex: none; }
/* Each swatch mirrors exactly one marker state above. Keep them in step: the
   key is the only thing telling a booker what the colours mean. */
.hp-tb-key-free::before { background: var(--hp-gold-soft); border-color: var(--hp-gold-line); }
.hp-tb-key-part::before { background: var(--hp-gold-soft); border-color: var(--hp-gold-line); border-style: dashed; }
.hp-tb-key-taken::before { background: rgba(224, 85, 64, .16); border-color: rgba(224, 85, 64, .3); }
.hp-tb-key-off::before { background: rgba(255, 255, 255, .05); }
.hp-tb-key-mine::before { background: var(--hp-gold); border-color: var(--hp-gold); }

/* ── Toasts ────────────────────────────────────────────────────
   Save outcomes and the duplicate-name warning, bottom right. Replaces the
   inline warning block that used to sit above the tables: it pushed the whole
   page down each time it appeared, and a save confirmation next to the button
   was easy to miss once the page was long enough to scroll. */
.hp-tb-toasts {
    /* Hoisted out of .hp-tb (see above), so it also has to restate what it used to
       inherit: the typeface and the base text colour. */
    font-family: 'Lato', sans-serif; color: var(--hp-text); -webkit-font-smoothing: antialiased;
    /* Above Divi's fixed header (99999) and its own overlays. A toast is
       transient and dismissible, so it is the one element that should win. The
       container is also hoisted to <body> in frontend.js — z-index alone can't
       help if a transformed ancestor has trapped the fixed positioning. */
    position: fixed; z-index: 2000000; right: 20px; bottom: 20px;
    display: flex; flex-direction: column-reverse; align-items: flex-end; gap: 10px;
    width: min(380px, calc(100vw - 40px)); pointer-events: none;
}
.hp-tb-toast {
    pointer-events: auto; width: 100%; box-sizing: border-box;
    display: flex; align-items: flex-start; gap: 10px;
    padding: 13px 14px; border-radius: 12px;
    background: #1c1b1a; border: 1px solid var(--hp-line);
    box-shadow: 0 10px 30px rgba(0, 0, 0, .45);
    font-size: 14px; line-height: 1.45; color: var(--hp-text);
    /* Entry only; leaving is handled by .is-going so it can't fight the layout. */
    animation: hp-tb-toast-in .22s ease-out both;
}
@keyframes hp-tb-toast-in {
    from { opacity: 0; transform: translateY(8px) scale(.98); }
    to   { opacity: 1; transform: none; }
}
.hp-tb-toast.is-going {
    opacity: 0; transform: translateY(6px);
    transition: opacity .18s ease, transform .18s ease;
}
@media (prefers-reduced-motion: reduce) {
    .hp-tb-toast { animation: none; }
    .hp-tb-toast.is-going { transition: none; }
}

.hp-tb-toast-icon {
    flex: none; width: 20px; height: 20px; margin-top: 1px; border-radius: 99px;
    display: flex; align-items: center; justify-content: center;
    font-size: 12px; font-weight: 700; line-height: 1;
}
.hp-tb-toast-body { flex: 1; min-width: 0; }
.hp-tb-toast-title { display: block; font-weight: 700; }
.hp-tb-toast-note { display: block; margin-top: 3px; font-size: 13px; color: var(--hp-muted); }
.hp-tb-toast-close {
    flex: none; width: 22px; height: 22px; padding: 0; margin: -2px -4px 0 0;
    background: none; border: 0; border-radius: 6px; cursor: pointer;
    color: var(--hp-dimmer); font-size: 15px; line-height: 1;
}
.hp-tb-toast-close:hover { color: var(--hp-text); background: rgba(255, 255, 255, .06); }
.hp-tb-toast-close:focus-visible { outline: 2px solid var(--hp-gold); outline-offset: 1px; }

.hp-tb-toast.is-ok { border-color: rgba(76, 175, 125, .4); }
.hp-tb-toast.is-ok .hp-tb-toast-icon { background: rgba(76, 175, 125, .14); color: var(--hp-ok); }
.hp-tb-toast.is-warn { border-color: var(--hp-gold-line); }
.hp-tb-toast.is-warn .hp-tb-toast-icon { background: var(--hp-gold-fill); color: var(--hp-gold); }
.hp-tb-toast.is-error { border-color: rgba(224, 85, 64, .45); }
.hp-tb-toast.is-error .hp-tb-toast-icon { background: rgba(224, 85, 64, .14); color: #ff9c8a; }

/* Names in the duplicate warning */
.hp-tb-dupe-list { list-style: none; margin: 6px 0 0; padding: 0; font-size: 13px; }
.hp-tb-dupe-list li { margin: 3px 0; color: var(--hp-muted); }
.hp-tb-dupe-list strong { color: var(--hp-text); }

@media (max-width: 640px) {
    /* Full width along the bottom, clear of the mobile CTA. */
    .hp-tb-toasts { right: 12px; left: 12px; bottom: 12px; width: auto; }
}

/* Exactly one of plan / list is ever displayed, using display:none rather than
   visual hiding, so assistive tech never encounters the same table twice. The
   plan's markers are real radios with their own labels, so hiding the list on
   desktop costs nothing in accessibility. */
.hp-tb-numbers.is-plan .hp-tb-choices { display: none; }

/* Buttons */
.hp-tb-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    padding: 12px 22px; border-radius: 11px; border: 1px solid var(--hp-gold-line);
    background: var(--hp-gold); color: var(--hp-on-gold); font-family: inherit;
    font-size: 15px; font-weight: 700; cursor: pointer; transition: .15s;
}
.hp-tb-btn:hover:not(:disabled) { filter: brightness(1.06); }
.hp-tb-btn:disabled { opacity: .45; cursor: not-allowed; }
.hp-tb-btn-small { padding: 6px 14px; font-size: 13px; }
.hp-tb-linkbtn {
    background: none; border: none; color: var(--hp-muted); font-family: inherit;
    font-size: 14px; cursor: pointer; text-decoration: underline; padding: 6px 8px;
}
.hp-tb-linkbtn:hover { color: var(--hp-text); }

/* Confirm step */
.hp-tb-confirm { margin-top: 6px; }
.hp-tb-confirm-note {
    color: var(--hp-muted); font-size: 14.5px; margin: 0 0 12px; max-width: 560px;
    margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--hp-line);
}
.hp-tb-confirm-note strong { color: var(--hp-text); white-space: nowrap; }
.hp-tb-confirm-controls { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.hp-tb-email {
    min-width: 260px; border-radius: 11px;
    border: 1px solid var(--hp-line); background: var(--hp-surface-2);
    color: var(--hp-text); font-family: inherit; font-size: 15px;
}
/* Two classes' worth of specificity (vs. one) so padding here beats the
   theme's global input[type="email"] { padding: 2px } rule — .hp-tb-email
   alone loses that specificity fight, which is the padding: 2px the
   confirm-controls email input was actually rendering with. */
.hp-tb-confirm-controls .hp-tb-email { padding: 12px; }
.hp-tb-email:focus { outline: none; border-color: var(--hp-gold-line); }

.hp-tb-msg { margin-top: 14px; padding: 10px 14px; border-radius: 9px; font-size: 14px;
    background: rgba(224, 85, 64, .12); border: 1px solid rgba(224, 85, 64, .35); color: #ff9c8a; }

.hp-tb-fallback { color: var(--hp-muted); font-size: 15px; }
.hp-tb-fallback a { color: var(--hp-gold); }

/* Stage 2: guests */
.hp-tb-guests-title { margin: 0 0 10px; font-size: 19px; font-weight: 700; color: #fff; }
.hp-tb-guest-intro { color: var(--hp-muted); font-size: 14.5px; margin-bottom: 14px; }
/* !important on padding: a conflicting (theme/global) style was winning the
   specificity fight and zeroing out padding-bottom specifically. */
.hp-tb-lock-note { font-size: 14px; color: var(--hp-ok); background: rgba(76, 175, 125, .08);
    border: 1px solid rgba(76, 175, 125, .35); border-radius: 10px; padding: 10px 14px !important; margin: 0 0 18px; }
/* .is-staff shares this treatment rather than getting its own: the two never
   appear together (one replaces the other), they describe the same closed
   booking, and a second near-identical block would only drift. Gold was wrong
   here — it is the event accent, so it reads as primary rather than as caution. */
.hp-tb-lock-note.is-locked,
.hp-tb-lock-note.is-staff { color: #ff9c8a; background: rgba(224, 85, 64, .08); border-color: rgba(224, 85, 64, .35); }
.hp-tb-lock-note.is-staff strong { color: #ff9c8a; }

/* Tools row (same-company) */
.hp-tb-guest-tools { margin: 0 0 12px; display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.hp-tb-same-company { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; color: var(--hp-muted); cursor: pointer; }
.hp-tb-same-company input { accent-color: var(--hp-gold); width: 16px; height: 16px; }
.hp-tb-company-confirm {
    display: inline-flex; align-items: center; gap: 10px;
    padding: 6px 12px; border-radius: 9px; font-size: 13.5px; color: #ffc9a3;
    background: var(--hp-gold-soft); border: 1px solid var(--hp-gold-line);
}
.hp-tb-company-confirm[hidden] { display: none; }

/* Two rows per guest: name/company/email, then dietary/alcohol/accessibility.
   Same layout on desktop and tablet; stacks on mobile (see media query). */
.hp-tb-guest-row {
    position: relative;
    display: grid;
    grid-template-columns: 30px 26px minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) 34px;
    grid-template-areas:
        "move seat name    company email  clear"
        ".    .    dietary alcohol access ."
        ".    .    note    note    note   .";
    gap: 10px 10px;
    align-items: start;
    padding: 14px 4px 5px;
    margin-bottom: 5px;
    border-top: 1px solid rgba(255, 255, 255, .07);
}
.hp-tb-guest-row:first-child { border-top: none; }
/* The row right after a tinted one loses its divider line, so the tinted
   background doesn't get cut off by a stray border sitting just past its edge. */
.hp-tb-guest-row.is-incomplete + .hp-tb-guest-row,
.hp-tb-guest-row.is-saved + .hp-tb-guest-row { border-top: 1px solid rgba(255, 255, 255, 0); }

/* align-self: center makes these sit dead-centre on the first field row
   automatically — no pixel nudges to drift when field heights change. */
.hp-tb-move        { grid-area: move; align-self: center; }
.hp-tb-seat        { grid-area: seat; align-self: center; }
.hp-tb-fld-name    { grid-area: name; }
.hp-tb-fld-company { grid-area: company; }
.hp-tb-fld-email   { grid-area: email; }
.hp-tb-fld-dietary { grid-area: dietary; }
.hp-tb-fld-alcohol { grid-area: alcohol; }
.hp-tb-fld-access  { grid-area: access; }
.hp-tb-clear       { grid-area: clear; align-self: center; }
.hp-tb-row-note    { grid-area: note; }

/* Fields rely on placeholders visually; the label text stays in the DOM for
   screen readers only (keeps each control properly named). */
.hp-tb-field { display: flex; flex-direction: column; min-width: 0; }
.hp-tb-field-label {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* Mandatory-field feedback. is-saved means "this guest is stored as shown" —
   it's removed as soon as the row is edited and restored when a save confirms
   it, so the tint tracks the server rather than the screen. */
.hp-tb-guest-row.is-incomplete { background: rgba(224, 85, 64, .06); border-radius: 8px; }
.hp-tb-guest-row.is-saved { background: rgba(76, 175, 125, .07); border-radius: 8px; }
.hp-tb-row-note {
    font-size: 12.5px; color: #ff9c8a; margin-top: -2px;
}
.hp-tb-row-note[hidden] { display: none; }
.hp-tb-f-email.is-invalid { border-color: var(--hp-danger); }
.hp-tb-field-error { font-size: 11.5px; color: #ff9c8a; margin-top: 3px; }
.hp-tb-field-error[hidden] { display: none; }
.hp-tb-guest-row.ui-sortable-helper { background: var(--hp-surface-2); border-radius: 10px; box-shadow: 0 10px 24px rgba(0,0,0,.45); border-top: none; }
.hp-tb-guest-row input, .hp-tb-guest-row select {
    width: 100%; padding: 9px 11px; border-radius: 9px;
    border: 1px solid var(--hp-line); background: rgba(255, 255, 255, .035);
    color: var(--hp-text); font-family: inherit; font-size: 14px;
}
.hp-tb-guest-row input:focus, .hp-tb-guest-row select:focus { outline: none; border-color: var(--hp-gold-line); color: #fff; }
.hp-tb-guest-row input:disabled, .hp-tb-guest-row select:disabled { opacity: .6; cursor: not-allowed; }
.hp-tb-guest-row select { appearance: auto; }
/* Browser autofill (Chrome/Safari) forces its own near-black-on-pale-yellow
   text/background via -webkit-text-fill-color, which normal `color` can't
   override — almost certainly the "dark grey, hard to read while typing"
   effect on Name/Company/Email once the browser offers to autofill them. */
.hp-tb-guest-row input:-webkit-autofill,
.hp-tb-guest-row input:-webkit-autofill:hover,
.hp-tb-guest-row input:-webkit-autofill:focus {
    -webkit-text-fill-color: #fff;
    caret-color: #fff;
    /* Two layers, because the field background is now translucent: the white
       wash on top of an opaque base, so an autofilled field matches an ordinary
       one while the base still hides the browser's yellow. */
    -webkit-box-shadow: 0 0 0 1000px rgba(255, 255, 255, .035) inset, 0 0 0 1000px var(--hp-surface) inset;
    box-shadow: 0 0 0 1000px rgba(255, 255, 255, .035) inset, 0 0 0 1000px var(--hp-surface) inset;
}

.hp-tb-seat { font-weight: 700; color: var(--hp-gold); text-align: center; font-size: 15px; }
.hp-tb-move { display: inline-flex; align-items: center; gap: 3px; }
.hp-tb-move[hidden] { display: none; }
.hp-tb-drag { display: inline-flex; justify-content: center; color: var(--hp-muted); cursor: grab; }
.hp-tb-drag:active { cursor: grabbing; }
/* Arrows are the mobile/touch reorder control — desktop uses drag only. */
.hp-tb-arrows { display: none; flex-direction: column; gap: 2px; }
.hp-tb-arrows button {
    display: inline-flex; align-items: center; justify-content: center;
    width: 18px; height: 14px; padding: 0; border: 1px solid var(--hp-line); border-radius: 4px;
    background: var(--hp-surface-2); color: var(--hp-muted); cursor: pointer;
}
.hp-tb-arrows button:hover { color: var(--hp-gold); border-color: var(--hp-gold-line); }

/* Dietary select + detail stack (inside its labelled field) */
.hp-tb-dietary { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.hp-tb-f-dietary-detail[hidden] { display: none; }
.hp-tb-clear {
    display: inline-flex; align-items: center; justify-content: center;
    width: 30px; height: 30px; border-radius: 8px; border: 1px solid var(--hp-line);
    background: none; color: var(--hp-muted); cursor: pointer; transition: .15s;
}
.hp-tb-clear:hover { color: var(--hp-danger); border-color: rgba(224, 85, 64, .5); }

.hp-tb-clear-confirm {
    position: absolute; inset: 2px; z-index: 3;
    display: flex; align-items: center; justify-content: flex-end; gap: 10px;
    padding: 0 8px; border-radius: 10px;
    background: rgba(26, 26, 26, .96); border: 1px solid rgba(224, 85, 64, .45);
    font-size: 14px;
}
.hp-tb-clear-confirm[hidden] { display: none; }
.hp-tb-clear-confirm .hp-tb-clear-yes { background: var(--hp-danger); border-color: var(--hp-danger); color: #fff; }

.hp-tb-guest-actions { display: flex; align-items: center; gap: 14px; margin-top: 18px; flex-wrap: wrap; }
.hp-tb-save-msg { font-size: 14px; color: var(--hp-ok); transition: opacity .2s; }
.hp-tb-save-msg.is-saving { color: var(--hp-muted); }
.hp-tb-save-msg.is-error { color: #ff9c8a; }
/* Edits typed but not written yet. Was inheriting the green "saved" colour. */
.hp-tb-save-msg.is-warn { color: #ffc9a3; }

/* Phones get the list, not the plan. A 65-table room drawn 340px wide puts the
   markers at roughly 8px — the numbers are neither readable nor tappable, so the
   plan is dropped entirely rather than shrunk into uselessness, and the list
   becomes the picker. */
/* The plan used to be hidden below this width, on the grounds that table
   numbers would be illegible. It is now shown so it can be judged on a real
   phone. Squeezing 16 columns into ~340px would make each marker about 8px, so
   instead the plan scrolls sideways and the grid keeps a minimum width that
   leaves every marker at its 26px floor and comfortably tappable.

   The list stays hidden, preserving the rule that exactly one of plan/list is
   ever in the DOM's a11y tree — if the plan turns out to be unusable at this
   size, deleting this block restores the list-only behaviour. */
@media (max-width: 760px) {
    .hp-tb-plan {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-x: contain;
        padding: 18px;
        /* Coloured so the bar itself reads as "there's more this way", not just
           a stray grey rule that looks like clipped/broken content. --hp-gold is
           the same event-accent variable used everywhere else on this page
           (set inline per event by hp_tb_accent_css() — see config.php), so the
           bar matches whatever colour that event is themed in, gold or not.
           overflow-x:auto already means no scrollbar renders at all when a plan
           is narrow enough to fit — these rules only ever have something to
           paint once that's not the case. */
        scrollbar-width: thin;
        scrollbar-color: var(--hp-gold) var(--hp-gold-soft);
    }
    /* Firefox and Chromium 121+ take the standard properties above. Everything
       else that supports a paintable scrollbar (desktop/Android WebKit) needs
       these instead — NOT iOS Safari, which renders its own translucent grey
       overlay indicator for a scrollable div and ignores ::-webkit-scrollbar
       entirely; there is no CSS override for that. The scroll hint text below
       is what actually carries this on iPhone. */
    .hp-tb-plan::-webkit-scrollbar { height: 7px; }
    .hp-tb-plan::-webkit-scrollbar-track { background: var(--hp-gold-soft); border-radius: 999px; }
    .hp-tb-plan::-webkit-scrollbar-thumb { background: var(--hp-gold); border-radius: 999px; }
    /* 16 columns x ~33px keeps markers at/above their min-width. */
    .hp-tb-plan-layer { min-width: calc(var(--hp-tb-cols, 12) * 33px); }
    .hp-tb-plan-scroll-hint { display: block; }
}

@media (max-width: 640px) {
    .hp-tb-card { padding: 18px 16px; }
    .hp-tb-email { min-width: 0; flex: 1; }

    /* Guest grid → one field per line, seat + controls on their own top line */
    .hp-tb-guest-row {
        /* auto: the reorder arrows sit side by side here and need more room
           than the 30px drag-handle column used on desktop */
        grid-template-columns: auto 26px 1fr 34px;
        grid-template-areas:
            "move    seat    .       clear"
            "name    name    name    name"
            "company company company company"
            "email   email   email   email"
            "dietary dietary dietary dietary"
            "alcohol alcohol alcohol alcohol"
            "access  access  access  access"
            "note    note    note    note";
        gap: 10px 8px;
        padding: 16px 2px 18px;
    }
    /* Controls share one line of their own here */
    .hp-tb-seat  { text-align: left; }
    .hp-tb-clear { justify-self: end; }

    .hp-tb-arrows { display: inline-flex; flex-direction: row; gap: 4px; }
    .hp-tb-arrows button { width: 30px; height: 26px; }
    .hp-tb-seat { padding-left: 2px; }
    .hp-tb-drag { display: none; } /* drag is awkward on touch — arrows do the job */
}

/* Locked guests: reorder + clear UI invisible and inert — but their grid
   cells stay in place so columns keep lining up with the header. */
.hp-tb-guests[data-locked="1"] .hp-tb-move,
.hp-tb-guests[data-locked="1"] .hp-tb-clear {
    visibility: hidden !important;
    pointer-events: none !important;
}
