/**
 * Front-end styling for the booking widget (shortcode + block, one shared
 * markup - see public/booking.php's render() and public/calendar.php).
 * Scoped entirely under .bookertron-booking / .bookertron-confirmation /
 * .bookertron-manage so it never leaks into the surrounding theme, and built
 * on CSS custom properties so a theme (or a future admin color setting)
 * can override the accent without touching this file.
 */

.bookertron-booking,
.bookertron-confirmation,
.bookertron-manage,
.bookertron-admin-calendar {
    --bookertron-accent: #2563eb;
    --bookertron-accent-contrast: #ffffff;
    --bookertron-available-bg: #e8f5e9;
    --bookertron-available-fg: #1b5e20;
    --bookertron-full-bg: #fdf2e9;
    --bookertron-full-fg: #9a5b13;
    --bookertron-closed-bg: transparent;
    --bookertron-muted: #9aa0a6;
    --bookertron-border: #e2e5e9;
    --bookertron-surface: #ffffff;
    --bookertron-text: #1f2328;
    --bookertron-error: #c62828;
    --bookertron-radius: 10px;

    /* color-scheme, not just `color` - without it, a native <input
       type="date"/"time"> renders its internal value text using whatever
       color-scheme it INHERITS (often "dark" on a modern theme/browser
       combo that declares one ambiently), completely ignoring our own
       explicit background here. That's exactly how "white on white" and
       "black on black" happen: the input's shadow-DOM text color comes
       from color-scheme, not from the `color:` property authors normally
       reach for. Declaring it explicitly, matching whichever background we
       actually set below, is the fix - not just here but in
       stripe-checkout.js too (see that file's own note on the Stripe
       Elements iframe, which has exactly the same failure mode for a
       different reason). */
    color-scheme: light;

    box-sizing: border-box;
    max-width: 30rem;
    margin: 1.5rem 0;
    padding: 1.5rem;
    background: var(--bookertron-surface);
    border: 1px solid var(--bookertron-border);
    border-radius: var(--bookertron-radius);
    color: var(--bookertron-text);
    font-size: 1rem;
    line-height: 1.5;
}

.bookertron-booking *,
.bookertron-confirmation *,
.bookertron-manage * {
    box-sizing: border-box;
}

.bookertron-booking h3 {
    margin: 0 0 1.25rem;
    font-size: 1.15rem;
    font-weight: 600;
}

/* --- Service picker --- */

.bookertron-service-picker {
    margin-bottom: 1.25rem;
}

.bookertron-service-picker label {
    display: block;
    margin-bottom: 0.35rem;
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--bookertron-muted);
}

.bookertron-service-picker select {
    width: 100%;
    padding: 0.55rem 0.75rem;
    border: 1px solid var(--bookertron-border);
    border-radius: 8px;
    background: var(--bookertron-surface);
    color: var(--bookertron-text);
    font-size: 1rem;
}

/* --- Calendar --- */

.bookertron-calendar {
    margin-bottom: 1.5rem;
}

.bookertron-calendar-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 0.75rem;
    font-size: 0.9rem;
}

.bookertron-calendar-nav strong {
    font-size: 1rem;
    font-weight: 600;
}

.bookertron-calendar-nav a {
    color: var(--bookertron-accent);
    text-decoration: none;
    padding: 0.25rem 0.4rem;
    border-radius: 6px;
}

.bookertron-calendar-nav a:hover,
.bookertron-calendar-nav a:focus-visible {
    background: var(--bookertron-available-bg);
}

/* The Next affordance on the last bookable month. Same box as the link so the
   nav row does not shift on that one month, but muted and not interactive. */
.bookertron-calendar-nav-end {
    color: var(--bookertron-muted);
    padding: 0.25rem 0.4rem;
    border-radius: 6px;
    cursor: default;
}

.bookertron-calendar-grid {
    width: 100%;
    border-collapse: separate;
    border-spacing: 3px;
    table-layout: fixed;
    font-variant-numeric: tabular-nums;
}

.bookertron-calendar-grid th {
    padding-bottom: 0.4rem;
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--bookertron-muted);
}

.bookertron-calendar-grid td {
    text-align: center;
    height: 2.4rem;
    vertical-align: middle;
    border-radius: 8px;
    font-size: 0.9rem;
}

.bookertron-calendar-grid td a {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    color: inherit;
    text-decoration: none;
    border-radius: 8px;
    transition: transform 0.08s ease;
}

.bookertron-day-available {
    background: var(--bookertron-available-bg);
    color: var(--bookertron-available-fg);
    font-weight: 600;
}

.bookertron-day-full {
    background: var(--bookertron-full-bg);
    color: var(--bookertron-full-fg);
}

.bookertron-day-available a:hover,
.bookertron-day-available a:focus-visible,
.bookertron-day-full a:hover,
.bookertron-day-full a:focus-visible {
    transform: scale(1.08);
    outline: none;
}

.bookertron-day-selected {
    box-shadow: 0 0 0 2px var(--bookertron-accent) inset;
}

/* The chosen span, painted by rental-picker.js from the two date fields. The
   endpoints take the same accent fill the appointment picker gives a checked
   slot; the days in between get a translucent wash of the same accent, layered
   with an inset ring so it reads over the available/full/closed backgrounds
   without hiding them - a closed Sunday inside a weekend hire must still look
   closed, just included. color-mix keeps the wash derived from the one accent
   token, so both themes follow automatically; the ring alone carries the
   meaning in browsers without it. */
.bookertron-day-range-start,
.bookertron-day-range-end {
    background: var(--bookertron-accent);
    color: var(--bookertron-accent-contrast);
    font-weight: 600;
}

.bookertron-day-range-start a,
.bookertron-day-range-end a {
    color: var(--bookertron-accent-contrast);
}

.bookertron-day-in-range {
    box-shadow: 0 0 0 2px var(--bookertron-accent) inset;
}

@supports (background: color-mix(in srgb, red 20%, transparent)) {
    .bookertron-day-in-range {
        background: color-mix(in srgb, var(--bookertron-accent) 18%, transparent);
        box-shadow: none;
    }
}

.bookertron-day-closed,
.bookertron-day-past,
.bookertron-day-empty {
    color: var(--bookertron-muted);
}

.bookertron-day-past {
    text-decoration: line-through;
    opacity: 0.5;
}

/* --- Time slots --- */

.bookertron-slots fieldset {
    margin: 0 0 1.25rem;
    padding: 0;
    border: none;
}

.bookertron-slots legend {
    padding: 0 0 0.6rem;
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--bookertron-muted);
}

.bookertron-slot-list {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.bookertron-slot {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.45rem 0.85rem;
    border: 1px solid var(--bookertron-border);
    border-radius: 999px;
    font-size: 0.9rem;
    cursor: pointer;
    transition: border-color 0.1s ease, background 0.1s ease;
}

.bookertron-slot:hover {
    border-color: var(--bookertron-accent);
}

.bookertron-slot:has(input:checked) {
    background: var(--bookertron-accent);
    border-color: var(--bookertron-accent);
    color: var(--bookertron-accent-contrast);
}

.bookertron-slot input {
    accent-color: var(--bookertron-accent-contrast);
}

/* --- Contact fields --- */

.bookertron-booking form p {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin: 0 0 1.25rem;
}

.bookertron-booking form p label {
    flex: 1 1 8rem;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--bookertron-muted);
}

/* The rental form's time controls are <select>, not <input type="time"> - that
   control was swapped out because its step-mismatch validation rejected
   perfectly legitimate submissions, and this rule was not updated to follow. It
   left the time dropdowns on browser defaults with no padding at all while the
   date inputs beside them kept theirs: measured at 41px against 19px in
   Chromium, 39 against 23 in Firefox, 41 against 31 in WebKit. Every browser,
   every viewport - it simply shows up worst on a phone, where the two sit side
   by side.

   It happened a second time with input[type="number"], the party-size field:
   added to the form, not added here, and it rendered as a thin unstyled bar
   under the full-height date and time controls. THIS LIST IS THE RULE - a new
   control on the booking form belongs in it, or it will not match the ones
   around it. Every type the form actually uses is named. */
.bookertron-booking form input[type="text"],
.bookertron-booking form input[type="email"],
.bookertron-booking form input[type="tel"],
.bookertron-booking form input[type="date"],
.bookertron-booking form input[type="time"],
.bookertron-booking form input[type="number"],
.bookertron-booking form select {
    padding: 0.55rem 0.7rem;
    border: 1px solid var(--bookertron-border);
    border-radius: 8px;
    font-size: 1rem;
    font-weight: 400;
    text-transform: none;
    letter-spacing: normal;
    color: var(--bookertron-text);
    /* Set explicitly, not inherited. A text input picks up the theme's own
       field styling; a <select> does not, so in dark mode the dropdowns came
       out several shades lighter than the date boxes beside them once they
       finally matched in height. Same value the service picker above uses. */
    background: var(--bookertron-surface);
    /* Comfortably above the 44px touch target iOS and WCAG 2.5.8 ask for, on
       the form factor where mis-taps actually cost a booking. */
    min-height: 44px;
    box-sizing: border-box;
}

/* On iOS both of these render as native widgets, and a native widget sizes
   itself: the min-height and vertical padding above are advisory at best and
   ignored at worst. That is why the pair matched in every desktop engine and in
   Playwright's phone emulation, and still came out different heights on a real
   iPhone - the first fix equalised only the browsers that already agreed, and
   zeroing the select's vertical padding to do it left it the shorter of the two
   on the one device that had the problem.

   Turning the native appearance off makes both ordinary boxes, so the shared
   padding, min-height and border-box above are what decide the size, on every
   engine. Tapping either still opens the native picker - only the chrome is
   ours now, which is why the select needs its chevron drawn back on. */
.bookertron-booking form input[type="date"],
.bookertron-booking form input[type="time"],
.bookertron-booking form select {
    -webkit-appearance: none;
    appearance: none;
}

.bookertron-booking form select {
    /* The dropdown arrow the rule above just removed. A flat mid-grey rather
       than a theme variable, because a background image cannot read
       currentColor, and this one reads against both surfaces. */
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%23888888' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.7rem center;
    background-size: 12px 8px;
    /* Room for it, so a long service name cannot run underneath. */
    padding-right: 2rem;
}

/* The form's own `p { display: flex }` above outranks the user-agent's
   `[hidden] { display: none }`, so the warning rendered as an empty box on
   every load until this rule put it back. */
.bookertron-rental-warning[hidden] {
    display: none;
}

.bookertron-rental-warning {
    margin: 0 0 0.75rem;
    padding: 0.65rem 0.85rem;
    border-radius: 8px;
    background: var(--bookertron-full-bg);
    color: var(--bookertron-full-fg);
    font-size: 0.95rem;
}

.bookertron-rental-estimate {
    margin: 0 0 1.25rem;
    padding: 0.65rem 0.85rem;
    border-radius: 8px;
    background: var(--bookertron-available-bg);
    color: var(--bookertron-available-fg);
    font-size: 0.95rem;
}

/* --- Buttons --- */

.bookertron-booking button,
.bookertron-manage button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.65rem 1.5rem;
    border: none;
    border-radius: 999px;
    background: var(--bookertron-accent);
    color: var(--bookertron-accent-contrast);
    font-size: 1rem;
    font-weight: 600;
    cursor: pointer;
    transition: opacity 0.1s ease;
}

.bookertron-booking button:hover,
.bookertron-manage button:hover {
    opacity: 0.9;
}

.bookertron-booking button:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

/* --- Stripe payment step --- */

.bookertron-stripe-payment #bookertron-card-element {
    padding: 0.85rem;
    margin-bottom: 1rem;
    border: 1px solid var(--bookertron-border);
    border-radius: 8px;
    background: var(--bookertron-surface);
}

/* Apple Pay / Google Pay. Both this and the divider below are rendered with
   the `hidden` attribute and only revealed by stripe-checkout.js once Stripe
   confirms a wallet is actually available on the device - so there is no
   display rule here that could override `hidden` and leave an empty box on
   every wallet-less desktop. */
.bookertron-stripe-payment .bookertron-express-checkout {
    margin-bottom: 1rem;
}

/* A centred "or pay by card" with a rule either side, drawn with borders on
   the pseudo-elements so it needs no background matching and stays correct on
   any themed surface. */
.bookertron-stripe-payment .bookertron-express-divider {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin: 0 0 1rem;
    color: var(--bookertron-muted);
    font-size: 0.85rem;
}

.bookertron-stripe-payment .bookertron-express-divider::before,
.bookertron-stripe-payment .bookertron-express-divider::after {
    content: "";
    flex: 1;
    border-top: 1px solid var(--bookertron-border);
}

/* Move-this-booking. The day picker and the two actions are separate <form>
   elements by necessity - one is a GET that reloads the day, the others POST -
   so nothing lays them out relative to each other by default and, with a theme
   that renders buttons as large pills, they collide. */
.bookertron-manage .bookertron-reschedule {
    margin: 1.25rem 0;
    padding-top: 1.25rem;
    border-top: 1px solid var(--bookertron-border);
}

.bookertron-manage .bookertron-reschedule h4 {
    margin: 0 0 0.35rem;
}

.bookertron-manage .bookertron-reschedule .description {
    margin: 0 0 0.9rem;
    color: var(--bookertron-muted);
    font-size: 0.9rem;
}

.bookertron-manage .bookertron-reschedule form {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem;
    margin: 0 0 0.75rem;
}

.bookertron-manage .bookertron-reschedule label {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.bookertron-manage form + form {
    margin-top: 0.75rem;
}

/* --- Errors & confirmation --- */

.bookertron-error {
    margin: 0 0 1rem;
    padding: 0.6rem 0.85rem;
    border-radius: 8px;
    background: #fdecea;
    color: var(--bookertron-error);
    font-size: 0.9rem;
}

.bookertron-confirmation {
    max-width: 30rem;
    margin: 1.5rem 0;
    padding: 1.5rem;
    background: var(--bookertron-available-bg);
    border: 1px solid var(--bookertron-available-fg);
    border-radius: var(--bookertron-radius);
}

.bookertron-confirmation h3 {
    margin-top: 0;
    color: var(--bookertron-available-fg);
}

/* Automatic (Auto theme): follows the visitor's own OS/browser preference -
   unchanged from before this session's widget-config work. Guarded with
   :not([data-theme="light"]) so an explicit Light override (below) still
   wins even on a dark-preferring browser; an explicit Dark override doesn't
   need a matching guard here since its own standalone rule below applies
   unconditionally regardless of what this media query does. */
@media (prefers-color-scheme: dark) {
    .bookertron-booking:not([data-theme="light"]),
    .bookertron-confirmation:not([data-theme="light"]),
    .bookertron-manage:not([data-theme="light"]),
    .bookertron-admin-calendar:not([data-theme="light"]) {
        color-scheme: dark;
        --bookertron-surface: #1e2126;
        --bookertron-text: #f0f1f3;
        --bookertron-border: #33373d;
        --bookertron-available-bg: #16311c;
        --bookertron-available-fg: #8fd99a;
        --bookertron-full-bg: #3a2b12;
        --bookertron-full-fg: #f0b968;
        --bookertron-muted: #8a9099;
        --bookertron-error: #ff8a80;
    }

    .bookertron-booking:not([data-theme="light"]) .bookertron-error,
    .bookertron-confirmation:not([data-theme="light"]) .bookertron-error,
    .bookertron-manage:not([data-theme="light"]) .bookertron-error {
        background: #3a1a1a;
    }
}

/* Explicit theme override (a saved widget config's Light/Dark choice -
   admin-widgets.php) - applies regardless of the visitor's OS preference,
   which is the whole point of an explicit choice beating an automatic one.
   Dark's tokens are the exact ones above, just no longer conditional on
   prefers-color-scheme; Light doesn't need its own token block at all,
   since the unguarded base rule at the top of this file already IS the
   light palette - it only needs re-asserting when this same element would
   otherwise have matched the dark media query above, which the :not()
   guard on that query already handles. */
.bookertron-booking[data-theme="dark"],
.bookertron-confirmation[data-theme="dark"],
.bookertron-manage[data-theme="dark"],
.bookertron-admin-calendar[data-theme="dark"] {
    color-scheme: dark;
    --bookertron-surface: #1e2126;
    --bookertron-text: #f0f1f3;
    --bookertron-border: #33373d;
    --bookertron-available-bg: #16311c;
    --bookertron-available-fg: #8fd99a;
    --bookertron-full-bg: #3a2b12;
    --bookertron-full-fg: #f0b968;
    --bookertron-muted: #8a9099;
    --bookertron-error: #ff8a80;
}

.bookertron-booking[data-theme="dark"] .bookertron-error,
.bookertron-confirmation[data-theme="dark"] .bookertron-error,
.bookertron-manage[data-theme="dark"] .bookertron-error {
    background: #3a1a1a;
}

/* Landscape layout (a saved widget config's choice) - Portrait (the
   default, no attribute emitted) stays exactly the original single stacked
   column. The calendar stays full-width above in both layouts (it's
   inherently grid/table-shaped and doesn't split into a "pane" sensibly);
   only the form below it - slot-list/rental-time-fields on one side,
   contact details + submit on the other - becomes two columns. Scoped to
   the two specific form classes, not a blanket `form` selector, since the
   service-picker and date-picker are also <form> elements that should
   never be grid-ified. */
.bookertron-booking[data-layout="landscape"] {
    max-width: 46rem;
}

.bookertron-booking[data-layout="landscape"] .bookertron-slots,
.bookertron-booking[data-layout="landscape"] .bookertron-rental-form {
    display: grid;
    grid-template-columns: 1.3fr 1fr;
    gap: 2rem;
    align-items: start;
}

@media (max-width: 640px) {
    /* Never force two cramped columns on a narrow viewport, regardless of
       the chosen layout - landscape is an opt-in widening for a wide
       embed, not a promise to defy the visitor's actual screen. */
    .bookertron-booking[data-layout="landscape"] {
        max-width: 30rem;
    }
    .bookertron-booking[data-layout="landscape"] .bookertron-slots,
    .bookertron-booking[data-layout="landscape"] .bookertron-rental-form {
        display: block;
    }
}

@media (max-width: 420px) {
    .bookertron-calendar-grid td {
        height: 2.1rem;
        font-size: 0.8rem;
    }
}

/* --- The admin bookings calendar --- */

/* Shares the token block above (it is in that selector list, including both
   dark variants) but not the card's width: a month of bookings wants the
   page, not a 30rem column. */
.bookertron-admin-calendar {
    max-width: none;
}

.bookertron-admin-calendar-filter {
    margin: 0 0 1rem;
}

.bookertron-admin-calendar-filter select {
    padding: 0.35rem 0.5rem;
    border: 1px solid var(--bookertron-border);
    border-radius: 8px;
    background: var(--bookertron-surface);
    color: var(--bookertron-text);
    font-size: 0.95rem;
}

.bookertron-admin-calendar-notice {
    padding: 0.5rem 0.75rem;
    border-radius: 8px;
    background: var(--bookertron-full-bg);
    color: var(--bookertron-full-fg);
}

/* The shared grid rule fixes cell height at 2.4rem for the picker's compact
   month; cells holding a list of bookings size to their content instead. */
.bookertron-admin-calendar-grid td {
    height: auto;
    min-height: 4.5rem;
    vertical-align: top;
    text-align: left;
    padding: 0.3rem;
    border: 1px solid var(--bookertron-border);
}

.bookertron-admin-day-number {
    display: block;
    font-size: 0.75rem;
    color: var(--bookertron-muted);
    margin-bottom: 0.2rem;
    text-decoration: none;
}

a.bookertron-admin-day-number:hover {
    color: var(--bookertron-accent);
}

.bookertron-admin-day-selected {
    background: var(--bookertron-available-bg);
}

.bookertron-admin-entry a {
    color: inherit;
    text-decoration: none;
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* --- The detail panels below the calendar --- */

.bookertron-admin-detail {
    margin-top: 1rem;
    padding: 1rem;
    border: 1px solid var(--bookertron-border);
    border-radius: var(--bookertron-radius);
}

.bookertron-admin-detail h4 {
    margin: 0 0 0.6rem;
}

.bookertron-admin-detail-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.bookertron-admin-detail-list a {
    color: var(--bookertron-accent);
    text-decoration: none;
}

.bookertron-admin-detail-when {
    font-weight: 600;
}

.bookertron-admin-detail-pay {
    font-size: 0.85rem;
    color: var(--bookertron-muted);
}

.bookertron-admin-detail-table {
    border-collapse: collapse;
}

.bookertron-admin-detail-table th {
    text-align: left;
    padding: 0.25rem 1rem 0.25rem 0;
    color: var(--bookertron-muted);
    font-weight: 600;
    vertical-align: top;
    white-space: nowrap;
}

.bookertron-admin-detail-table td {
    padding: 0.25rem 0;
}

.bookertron-admin-day-today {
    box-shadow: 0 0 0 2px var(--bookertron-accent) inset;
}

.bookertron-admin-day-today .bookertron-admin-day-number {
    color: var(--bookertron-accent);
    font-weight: 700;
}

.bookertron-admin-day-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.bookertron-admin-entry {
    font-size: 0.75rem;
    line-height: 1.3;
    padding: 0.15rem 0.35rem;
    border-radius: 6px;
    background: var(--bookertron-available-bg);
    color: var(--bookertron-available-fg);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.bookertron-admin-entry-time {
    font-weight: 600;
}

/* A hire that spans days keeps one visual thread across its cells - the same
   family as the picker's range wash, squared off toward its continuation so
   the eye can follow it along a row. */
.bookertron-admin-entry-span-start,
.bookertron-admin-entry-span-mid,
.bookertron-admin-entry-span-end {
    box-shadow: 0 0 0 1px var(--bookertron-accent) inset;
}

@supports (background: color-mix(in srgb, red 20%, transparent)) {
    .bookertron-admin-entry-span-start,
    .bookertron-admin-entry-span-mid,
    .bookertron-admin-entry-span-end {
        background: color-mix(in srgb, var(--bookertron-accent) 16%, transparent);
        color: var(--bookertron-text);
        box-shadow: none;
    }
}

.bookertron-admin-entry-span-start { border-radius: 6px 0 0 6px; }
.bookertron-admin-entry-span-mid   { border-radius: 0; }
.bookertron-admin-entry-span-end   { border-radius: 0 6px 6px 0; }

.bookertron-admin-entry-unpaid {
    display: inline-block;
    width: 0.5em;
    height: 0.5em;
    border-radius: 50%;
    background: var(--bookertron-full-fg);
    vertical-align: middle;
}

.bookertron-admin-entry-more {
    font-size: 0.7rem;
    color: var(--bookertron-muted);
    padding: 0 0.35rem;
}
