/*
 * The public booking page — R39's six questions asked one at a time down a
 * single page, and the Client's own Booking page, which share one layout.
 *
 * Every colour, radius and space here is a token from `global.css`, which is
 * `docs/DESIGN.md` read off the live melinda.lv. Nothing is redefined; what is
 * only ever used on this page is a custom property on this page's own root,
 * below, rather than pushed onto `:root`.
 *
 * DESIGN.md §13 asks for a small set of breakpoints instead of the live site's
 * eight. This file uses two: 600px, where the phone layout ends, and 900px,
 * where there is room for two columns of times.
 */

.booking {
    /* R11.2: 48px, not the site's 44px. This is the page DESIGN.md §7 means. */
    --booking-target: 48px;
    --booking-field-height: var(--booking-target);

    /* A form column, narrower than the 1200px the marketing pages use. */
    --booking-column: 680px;

    /*
     * The question and the column beside it, side by side. Past the 1200px the
     * marketing pages use: the week stands seven columns of times wide, and at
     * 1080 they were narrow enough to read as a wall. 1320 still leaves a
     * margin either side on a 1440px laptop, which 1400 does not.
     */
    --booking-wide: 1320px;
    --booking-aside: 340px;

    --booking-title-tracking: var(--letter-spacing-page-title);

    /* One step down from h2's 32px, which is a shout on a telephone. */
    --booking-heading-size: 22px;
    --booking-heading-line: 28px;

    /*
     * The procedure list follows melinda.lv/cenradis/ as it renders. A
     * Category is its card title, `.h1`: 22px — the question's size — bold,
     * 1.33 high, with its accent rule 10px under it. A row is its table row:
     * 1.29 high, and on a telephone 13px in 8px 5px of padding.
     */
    --booking-category-size: var(--booking-heading-size);
    --booking-category-line: 1.33;
    --booking-category-weight: 700;
    --booking-category-rule-gap: 10px;
    --booking-cell-line: 1.29;
    --booking-cell-size-phone: 13px;
    --booking-cell-padding-phone: 8px 5px;

    /* The step bar: the mark, the gutter each name gets, and its size. */
    --booking-step-mark: 32px;
    --booking-step-gutter: 4px;
    --booking-step-name: var(--appointment-field-font);
    --booking-step-lift: 1.08;

    --booking-day-size: 40px;
    --booking-control-size: 22px;
    --booking-slot-column: 90px;
    --booking-slot-column-wide: 110px;
    /*
     * The width melinda.lv draws the same mark at: its own header renders
     * 214.7px of writing, and the file is cropped to its writing, so the
     * width is the whole measurement. Set by width and not by height —
     * matching a mark means matching how wide it reads.
     */
    --booking-logo-width: 215px;
    --booking-logo-width-phone: 150px;
    --booking-language-dim: .65;

    --booking-hairline: 1px;
    --booking-rule: 2px;
    --booking-gap: var(--space-sm);

    background: var(--appointment-card-background-tinted);
    min-height: 100vh;
}

/* Layout */

/*
 * Three columns and not `space-between`, so the name in the middle sits on
 * the header's own centre line: the two 1fr tracks are equal whichever flank
 * is wider, and the Client's own Booking page, which has no Languages, still
 * centres it against an empty third column.
 */
.booking__masthead {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: var(--space-sm);
    min-height: var(--header-height);
    padding-inline: var(--container-padding);
    background: var(--color-surface-dark);
}

/* The Salon's own mark, at the width melinda.lv draws it. */
.booking__logo {
    justify-self: start;
    width: var(--booking-logo-width);
    height: auto;
}

@media (max-width: 600px) {
    .booking__logo {
        width: var(--booking-logo-width-phone);
    }
}

/*
 * The Salon's name beside its mark. Under 820px the three columns stop
 * fitting side by side, and the middle one is dropped rather than allowed to
 * push the Languages off the screen; the mark still says the name.
 */
.booking__salon {
    color: var(--color-text-inverse);
    font-family: var(--font-nav);
    font-size: var(--font-size-body);
    letter-spacing: var(--letter-spacing-button);
    text-transform: uppercase;
    white-space: nowrap;
}

@media (max-width: 820px) {
    .booking__salon {
        display: none;
    }

    /*
     * Two columns once the middle one is empty. Left at three, the Languages
     * fell into the middle `auto` track with an equal 1fr of nothing to the
     * right of them, so they sat short of the edge rather than against it.
     */
    .booking__masthead {
        grid-template-columns: 1fr auto;
    }
}

/*
 * R101's three Languages, as three links. The one the page is already in is
 * marked rather than hidden: a Client who cannot read the page has to be able
 * to see all three at once to find their own.
 */
.booking__languages {
    display: flex;
    align-items: center;
    justify-self: end;
    gap: var(--space-2xs);
}

.booking__language {
    display: flex;
    align-items: center;
    min-height: var(--booking-target);
    padding-inline: var(--space-2xs);
    border-radius: var(--radius-control);
    color: var(--color-text-inverse);
    font-size: var(--appointment-field-font);
    letter-spacing: var(--booking-title-tracking);
    text-decoration: none;
    opacity: var(--booking-language-dim);
    transition: var(--button-transition);
}

.booking__language:hover,
.booking__language:focus-visible {
    opacity: 1;
}

.booking__language[aria-current] {
    background: var(--color-surface-dark-alt);
    opacity: 1;
}

/*
 * The same three Languages on a telephone, as a dropdown against the right
 * edge. `display: none` and not `visibility`: whichever of the two is not in
 * use has to leave the grid, or the masthead would count four columns, and has
 * to leave the screen reader with it, or the Languages would be read twice.
 */
.booking__language-menu {
    display: none;
}

@media (max-width: 600px) {
    .booking__languages {
        display: none;
    }

    .booking__language-menu {
        display: block;
        position: relative;
        justify-self: end;
    }
}

/* The browser's own triangle, taken off both ways it is drawn. */
.booking__language-summary {
    display: flex;
    align-items: center;
    gap: var(--space-2xs);
    min-height: var(--booking-target);
    padding-inline: var(--space-2xs);
    border-radius: var(--radius-control);
    background: var(--color-surface-dark-alt);
    color: var(--color-text-inverse);
    font-size: var(--appointment-field-font);
    letter-spacing: var(--booking-title-tracking);
    list-style: none;
    cursor: pointer;
}

.booking__language-summary::-webkit-details-marker {
    display: none;
}

/* Pointing down when it is shut, and up once it is open. */
.booking__language-caret {
    font-size: var(--font-size-h3);
    line-height: 1;
    transform: rotate(90deg);
    transition: var(--button-transition);
}

.booking__language-menu[open] .booking__language-caret {
    transform: rotate(-90deg);
}

.booking__language-panel {
    position: absolute;
    top: calc(100% + var(--space-2xs));
    right: 0;
    z-index: var(--header-z-index);
    display: grid;
    min-width: 100%;
    padding: var(--space-2xs);
    border-radius: var(--radius-control);
    background: var(--color-surface-dark);
    box-shadow: var(--appointment-card-shadow);
}

.booking__language-panel .booking__language {
    justify-content: center;
}

.booking__main {
    max-width: var(--booking-column);
    padding-block: var(--space-lg) var(--space-2xl);
}

/* The booking flow stands two columns wide; link.blade and move.blade do not. */
.booking__main:has(.booking__columns) {
    max-width: var(--booking-wide);
}

.booking__card {
    margin-bottom: var(--booking-gap);
}

.booking__heading {
    color: var(--color-heading-section);
    font-size: var(--booking-heading-size);
    line-height: var(--booking-heading-line);
    text-transform: none;
    padding-bottom: var(--space-2xs);
    border-bottom: var(--booking-rule) solid var(--color-border-title-rule);
    margin-bottom: var(--space-md);
}

.booking__group {
    font-size: var(--font-size-h3);
    line-height: var(--line-height-h3);
    margin-block: var(--space-md) var(--space-2xs);
}

.booking__lead {
    color: var(--color-text-secondary);
    margin-bottom: var(--space-md);
}

/* The one sentence the Client's own Booking page is there to say. */
.booking__verdict {
    color: var(--color-text-primary);
    font-family: var(--font-heading);
    font-size: var(--font-size-h3);
    line-height: var(--line-height-h3);
    letter-spacing: var(--letter-spacing-h3);
    padding-bottom: var(--space-sm);
    border-bottom: var(--booking-rule) solid var(--color-border-title-rule);
    margin-bottom: var(--space-md);
}

.booking__empty {
    color: var(--color-text-body);
    margin-bottom: var(--space-md);
}

.booking__notice {
    border: var(--booking-hairline) solid var(--color-accent);
    border-radius: var(--radius-control);
    background: var(--appointment-soc-hover);
    color: var(--appointment-soc-text);
    padding: var(--space-xs) var(--space-sm);
    margin-bottom: var(--booking-gap);
}

.booking__hold {
    color: var(--appointment-label-active);
    font-size: var(--appointment-field-font);
    margin-bottom: var(--space-md);
}

.booking__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--appointment-field-gap);
    margin-top: var(--space-md);
}

/* On the Booking link page the contact block's rule sat on the buttons. */
.booking__actions + .contact-block {
    margin-top: var(--space-md);
}

/*
 * DESIGN.md §11 has a bar stuck to the bottom of a telephone screen, and the
 * press used to sit in it. It does not any more: asked for, and it reads
 * better — the press belongs under the summary it follows, and a bar floating
 * over the week hid a row of times behind it.
 *
 * The tokens in §11 are still there and still describe that bar. Nothing on
 * this page uses them now.
 */
@media (max-width: 600px) {
    .aside__actions .btn {
        flex: 1 1 auto;
        min-height: var(--booking-target);
    }
}

/*
 * The disabled state of the one global button. It is here rather than in
 * `global.css` because this is the only page that produces it — the choice
 * gate holds "next" back until the question is answered. The moment a second
 * page disables a button, this rule moves.
 */
.btn:disabled {
    opacity: .55;
    box-shadow: none;
    cursor: not-allowed;
}

/* A link on the Client's own Booking page, a press on the booking page. */
.booking__again {
    display: inline-flex;
    align-items: center;
    min-height: var(--booking-target);
    padding: 0;
    border: 0;
    background: none;
    color: var(--appointment-soc-text);
    font-size: var(--appointment-field-font);
    text-decoration: underline;
    cursor: pointer;
}

/*
 * The path, the question, and the column beside it
 *
 * One page, one question at a time (R39). The bar across the top says where
 * the Client is and how far is left; the open question is a card on the left;
 * what they have already answered — and how to reach the Salon — is on the
 * right. Below 900px there is room for one column and the sidebar falls under
 * the question.
 */

/*
 * The five steps are a path, not a row of tabs: a mark for each, the name under
 * it, and the line between them coloured as far as the Client has come. The
 * markup is unchanged — a mark and a name inside a press — so this is only how
 * they are drawn, and `BookingStepBarTest` still holds the presses to the
 * answers held.
 *
 * The line into a step is drawn on the step itself, reaching back half a cell
 * to the one before it. Every cell is `flex: 1 1 0`, so half a cell to the left
 * is exactly the previous mark, and the first step's line is taken away rather
 * than left hanging off the edge.
 */

.steps {
    display: flex;
    margin-bottom: var(--booking-gap);
}

.steps__item {
    position: relative;
    display: flex;
    flex: 1 1 0;
    min-width: 0;
}

.steps__item::before {
    content: "";
    position: absolute;
    top: calc(var(--booking-step-mark) / 2 - var(--booking-rule) / 2);
    right: 50%;
    left: -50%;
    height: var(--booking-rule);
    background: var(--appointment-rule);
}

.steps__item:first-child::before {
    content: none;
}

/* The path is drawn up to where the Client stands, and no further. */
.steps__item--done::before,
.steps__item--open::before {
    background: var(--color-border-title-rule);
}

/*
 * The whole cell, and on a step already answered it is a button. The press is
 * the size of the cell and not the size of the words in it (R11.2).
 */
.steps__inner {
    /*
     * Above the path. The line into a step is drawn on that step and reaches
     * back over the mark before it, so without this the next step's line is
     * painted straight across the mark the Client is standing on.
     */
    position: relative;
    z-index: 1;
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    align-items: center;
    gap: var(--space-2xs);
    min-height: var(--booking-target);
    padding: 0 var(--booking-step-gutter);
    border: 0;
    background: none;
    color: inherit;
    font-family: inherit;
    text-align: center;
}

button.steps__inner {
    cursor: pointer;
}

/*
 * The mark. One size for a number and for a tick, so the names under them sit
 * on one line across the bar. It carries the page's own background, because the
 * path runs behind it and must not show through.
 */
.steps__mark {
    display: flex;
    flex: none;
    align-items: center;
    justify-content: center;
    width: var(--booking-step-mark);
    height: var(--booking-step-mark);
    border: var(--booking-rule) solid var(--appointment-rule);
    border-radius: 50%;
    background: var(--appointment-card-background-tinted);
    color: var(--color-text-muted);
    font-size: var(--appointment-field-font);
    font-variant-numeric: tabular-nums;
    line-height: 1;
    transition: var(--button-transition);
}

.steps__name {
    color: var(--color-text-muted);
    font-size: var(--booking-step-name);
    font-weight: 600;
    letter-spacing: var(--letter-spacing-button);
    line-height: 1.2;
    transition: var(--button-transition);
}

/*
 * Where the Client stands: the brand's own gradient, and its glow around it.
 *
 * `background-origin` and not only the colour. A gradient is measured over the
 * padding box by default and painted over the border box, so the 2px this mark
 * keeps as a transparent border was 2px the gradient had to repeat into — a
 * hard rim of the gradient's far end wrapped around the whole circle, which
 * read as a fill that stopped short of the edge.
 */
.steps__item--open .steps__mark {
    border-color: transparent;
    background: var(--button-gradient);
    background-origin: border-box;
    box-shadow: var(--button-glow);
    color: var(--button-text);
}

.steps__item--open .steps__name {
    color: var(--color-accent-strong);
    font-weight: var(--font-weight-button);
}

/*
 * Behind them, and answered: an outlined mark and a tick.
 *
 * Not filled. A filled rose mark was #b76e79 against a gradient starting at
 * #bb7f6e, so the step the Client stands on and the three behind it read as
 * four of the same thing. Only one mark on the bar is filled, and it is the
 * one they are on.
 */
.steps__item--done .steps__mark {
    border-color: var(--color-accent);
    background: var(--appointment-soc-hover);
    color: var(--appointment-soc-text);
}

.steps__item--done .steps__name {
    color: var(--appointment-soc-text);
}

/*
 * Answered means pressable, and the press says so before it is made. The mark
 * lights rather than the cell filling in — there is no cell left to fill.
 */
.steps__item--done button.steps__inner:hover .steps__mark,
.steps__item--done button.steps__inner:focus-visible .steps__mark {
    border-color: var(--color-accent-strong);
    transform: scale(var(--booking-step-lift));
}

.steps__item--done button.steps__inner:hover .steps__name,
.steps__item--done button.steps__inner:focus-visible .steps__name {
    color: var(--color-accent-strong);
}

/* Still to come: legible, but plainly not pressable. */
.steps__item--later .steps__mark,
.steps__item--later .steps__name {
    color: var(--color-text-muted);
}

/* Five names across a telephone: the tracking is what has to give. */
@media (max-width: 600px) {
    .steps {
        --booking-step-name: var(--font-size-table-head);
    }

    .steps__name {
        letter-spacing: normal;
    }
}

/* The two columns */

.booking__columns {
    display: grid;
    gap: var(--booking-gap);
    align-items: start;
}

@media (min-width: 900px) {
    .booking__columns {
        grid-template-columns: minmax(0, 1fr) var(--booking-aside);
    }
}

.booking__question {
    min-width: 0;
}

.section__heading {
    display: flex;
    align-items: baseline;
    gap: var(--space-xs);
    color: var(--color-heading-section);
    font-size: var(--booking-heading-size);
    line-height: var(--booking-heading-line);
    text-transform: none;
}

/*
 * The heading the week wears: the dates it is showing, and the two ways to a
 * different week at the end of the same line.
 *
 * `center` and not the baseline every other heading uses. The presses beside
 * the dates are 48px tall and the dates are a 28px line, so on a baseline the
 * dates rode at the top of the row with the arrows halfway down it.
 */
.section__heading:has(.week__steps) {
    align-items: center;
}

/* "31.08 – 06.09.2026" is one thing; a break inside it names two other days. */
.section__heading:has(.week__steps) .section__name {
    white-space: nowrap;
}

/*
 * A telephone has 336px for all of this, and at the 22px every other heading
 * uses the dates alone took 198px of it — the pair of presses then had 30px
 * too little and the dates broke across two lines.
 */
@media (max-width: 600px) {
    .section__heading:has(.week__steps) {
        gap: var(--space-2xs);
        font-size: var(--font-size-body);
    }

    .section--open > .section__heading:has(.week__steps) {
        margin-bottom: var(--space-2xs);
    }
}

/* The bar across the top is where the numbering is read; twice is once too many. */
.section__number {
    display: none;
}

/* The open one wears the card's own rule under its heading. */
.section--open > .section__heading {
    padding-bottom: var(--space-2xs);
    border-bottom: var(--booking-rule) solid var(--color-border-title-rule);
    margin-bottom: var(--space-md);
}

.section--open:focus-visible {
    outline: var(--booking-rule) solid var(--color-accent);
    outline-offset: var(--space-2xs);
}

/* The column beside the question */

.aside {
    display: grid;
    gap: var(--booking-gap);
    min-width: 0;
}

.aside__card {
    padding: var(--appointment-card-padding);
}

.aside__title {
    color: var(--color-heading-section);
    font-size: var(--appointment-field-font);
    font-weight: 600;
    letter-spacing: var(--letter-spacing-button);
    text-transform: uppercase;
}

.aside__prompt {
    color: var(--color-text-muted);
    font-size: var(--appointment-field-font);
    margin-top: var(--space-sm);
}

.aside__summary {
    display: grid;
    gap: var(--space-xs);
    margin-top: var(--space-sm);
}

.aside__row {
    display: grid;
    gap: var(--space-2xs);
    padding-bottom: var(--space-xs);
    border-bottom: var(--booking-hairline) solid var(--appointment-rule);
}

.aside__term {
    color: var(--appointment-soc-title);
    font-size: var(--appointment-soc-font-size);
    letter-spacing: var(--letter-spacing-button);
    text-transform: uppercase;
}

/* `margin: 0` because the reset covers p, ul and ol but not dd, and a browser
   indents one by 40px — which walked the answer away from its own label. */
.aside__value {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-2xs) var(--space-sm);
    margin: 0;
}

.aside__answer {
    color: var(--appointment-soc-text);
    font-size: var(--appointment-field-font);
    font-weight: 600;
}

.aside__price {
    color: var(--appointment-text);
    font-size: var(--appointment-field-font);
}

.aside__change {
    display: inline-flex;
    margin-left: auto;
    align-items: center;
    min-height: var(--booking-target);
    padding: 0;
    border: 0;
    background: none;
    color: var(--appointment-soc-text);
    font-size: var(--appointment-soc-font-size);
    text-decoration: underline;
    cursor: pointer;
}

.aside__actions {
    display: flex;
    margin-top: var(--space-md);
}

.aside__forward {
    flex: 1 1 auto;
}

/* The forward press Enter presses (`partials/flow`): laid out, never seen. */
.booking__default {
    position: absolute;
    /* The standard hide-from-eyes idiom, not a design value. */
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* Address and the social row, under the summary. */

.aside__contact-title {
    display: flex;
    align-items: center;
    gap: var(--space-2xs);
    color: var(--appointment-soc-title);
    font-size: var(--appointment-soc-font-size);
    letter-spacing: var(--letter-spacing-button);
    text-transform: uppercase;
}

.aside__address {
    color: var(--appointment-text);
    font-size: var(--appointment-field-font);
    margin: var(--space-2xs) 0 var(--space-md);
}

.aside__card--contact .contact-block {
    padding-top: var(--space-md);
    border-top: var(--booking-hairline) solid var(--appointment-rule);
}

/*
 * On a telephone this card stands on its own across the screen instead of
 * beside the question, and six short lines pinned to its left edge read as
 * something left over rather than as the card's own contents. Centred only
 * here: beside the question it is a narrow column and the left edge is what
 * the eye runs down.
 */
@media (max-width: 600px) {
    .aside__card--contact {
        text-align: center;
    }

    .aside__contact-title,
    .aside__card--contact .contact-block__title,
    .aside__card--contact .contact-block__link,
    .aside__card--contact .contact-block__socials {
        justify-content: center;
    }
}

/* The price list */

/*
 * Three columns — the Procedure, how long it takes, what it costs — with
 * DESIGN.md §9's headers over them. Every row carries the same track widths
 * from `--procedure-columns` on the form, so the Categories can break the list
 * into groups without the columns drifting between one group and the next.
 *
 * It is set as melinda.lv/cenradis/ sets its price list, read off the live
 * page: the same title over each group, the same rows, the same hairlines.
 */

.procedures__table {
    --procedure-columns: minmax(0, 1fr) 8rem 7rem var(--booking-target);
}

.procedures__head {
    display: grid;
    align-items: baseline;
    grid-template-columns: var(--procedure-columns);
    gap: var(--space-sm);
    padding: var(--table-cell-padding);
    color: var(--color-accent-text);
    font-size: var(--font-size-table-head);
}

/* Over the two facts, which stand centred under them as on /cenradis/. */
.procedures__head > :not(:first-child) {
    text-align: center;
}

/*
 * A Category is the heading of its part of the list, and the Procedures under
 * it are the items. It is /cenradis/'s card title: Open Sans in bold capitals,
 * black, with a short accent rule under it. DESIGN.md §3 keeps headings unbolded
 * everywhere else; here the price list the Client already knows wins.
 */
.procedures__category {
    color: var(--color-text-primary);
    font-family: var(--font-body);
    font-size: var(--booking-category-size);
    font-weight: var(--booking-category-weight);
    line-height: var(--booking-category-line);
    letter-spacing: normal;
    text-transform: uppercase;
    margin-block: var(--space-lg) var(--space-sm);
}

/* The first one opens the card; the card's own padding is the space above it. */
.procedures__category:first-of-type {
    margin-top: 0;
}

.procedures__category::after {
    content: "";
    display: block;
    width: var(--space-3xl);
    height: var(--booking-rule);
    margin-top: var(--booking-category-rule-gap);
    background: var(--color-accent);
}

/* Rows of a table, as /cenradis/ has them: a hairline between, no boxes. */
.procedures {
    display: grid;
}

.procedures__item + .procedures__item {
    border-top: var(--booking-hairline) solid var(--table-rule);
}

.procedure {
    display: grid;
    grid-template-columns: var(--procedure-columns);
    align-items: center;
    gap: var(--space-2xs) var(--space-sm);
    width: 100%;
    min-height: var(--booking-target);
    padding: var(--table-cell-padding);
    border: 0;
    border-radius: 0;
    background: transparent;
    text-align: left;
    cursor: pointer;
    transition: var(--button-transition);
}

/*
 * Still a press, which a price list row is not: the row warms under the
 * pointer, and the keyboard's ring is the page's own `:focus-visible`.
 */
/*
 * `:disabled` is the press `flow.js` has sent and is waiting on, drawn as the
 * choice it is about to be. On a slow telephone the row stood exactly as it
 * was until the answer came, and the Client pressed again, or another row.
 * Meanwhile (`aria-busy`) the old choice stops looking chosen, or two rows
 * stood lit at once.
 */
.procedure:hover,
.procedure:focus-visible,
.procedure--chosen:not([aria-busy="true"] *),
.procedure:disabled {
    background: var(--appointment-card-background-tinted);
}

.procedure--chosen:not([aria-busy="true"] *) .procedure__go,
.procedure:disabled .procedure__go {
    border-color: var(--color-border-title-rule);
    background: var(--color-border-title-rule);
    color: var(--color-text-inverse);
}

/* The item, and the two facts beside it: /cenradis/'s cells, all three alike. */
.procedure__name,
.procedure__duration,
.procedure__price {
    color: var(--color-text-primary);
    font-size: var(--font-size-table-cell);
    font-weight: var(--font-weight-body);
    line-height: var(--booking-cell-line);
}

/*
 * The arrow. Its own circle, so the eye finds the same spot on every row and
 * reads "this one is a press" without a border round the whole line.
 */
.procedure__go {
    display: flex;
    align-items: center;
    justify-content: center;
    justify-self: end;
    width: var(--booking-control-size);
    height: var(--booking-control-size);
    border: var(--booking-hairline) solid var(--appointment-soc-border);
    border-radius: 50%;
    color: var(--color-accent-strong);
    transition: var(--button-transition);
}

.procedure:hover .procedure__go,
.procedure:focus-visible .procedure__go {
    border-color: var(--color-accent-strong);
    background: var(--appointment-card-background-tinted);
}

.procedure__duration,
.procedure__price {
    text-align: center;
}

/*
 * The Master's note about the Procedure. Its own line under the name, where it
 * has the width to be read, and indented to nothing so it reads as belonging
 * to the row rather than as a fourth column.
 */
.procedure__description {
    grid-column: 1 / -1;
    max-width: 60ch;
    color: var(--color-text-secondary);
    font-size: var(--font-size-table-cell);
    line-height: var(--line-height-body);
}

/*
 * On a telephone there is no room for three columns, so the name takes the
 * width and the two facts sit under it, side by side on one quiet line. The
 * headers go: they label columns that are no longer there.
 */
@media (max-width: 600px) {
    .procedures__head {
        display: none;
    }

    .procedure {
        grid-template-columns: auto 1fr auto;
        column-gap: var(--space-sm);
        padding: var(--booking-cell-padding-phone);
    }

    /* /cenradis/ drops its cells to 13px here; the note under a name follows. */
    .procedure__name,
    .procedure__duration,
    .procedure__price,
    .procedure__description {
        font-size: var(--booking-cell-size-phone);
    }

    .procedure__name {
        grid-column: 1 / 3;
    }

    /* Beside the name, spanning it and the line of facts under it. */
    .procedure__go {
        grid-column: 3;
        grid-row: 1 / 3;
        align-self: center;
    }

    .procedure__duration {
        grid-column: 1;
        grid-row: 2;
        text-align: start;
    }

    .procedure__price {
        grid-column: 2;
        grid-row: 2;
        text-align: start;
    }
}

/* Step two — the screening question */

.choice {
    border: 0;
    padding: 0;
    margin: 0;
}

.choice__question {
    color: var(--color-text-body);
    padding: 0;
    margin-bottom: var(--space-md);
}

.choice__option {
    display: flex;
    align-items: center;
    gap: var(--appointment-field-gap);
    min-height: var(--booking-target);
    padding: 0 var(--space-sm);
    border: var(--booking-hairline) solid var(--appointment-border);
    border-radius: var(--appointment-field-radius);
    margin-bottom: var(--appointment-field-gap);
    cursor: pointer;
}

.choice__option:hover {
    border-color: var(--color-accent-glow);
}

.choice__input {
    width: var(--booking-control-size);
    height: var(--booking-control-size);
    accent-color: var(--color-accent-strong);
}

.choice__label {
    color: var(--appointment-text);
}

/* The day picker, on the page that moves a Booking */

.month {
    border: var(--booking-hairline) solid var(--appointment-rule);
    border-radius: var(--appointment-card-radius);
    padding: var(--space-sm);
}

.month__bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--appointment-field-gap);
    margin-bottom: var(--space-2xs);
}

.month__name {
    color: var(--color-text-primary);
    font-family: var(--font-heading);
    font-size: var(--font-size-h3);
    letter-spacing: var(--letter-spacing-h3);
    order: 0;
    flex: 1 1 auto;
    text-align: center;
}

/* The month picker's, at the two ends of its own bar. */
.month__step {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: var(--booking-target);
    min-height: var(--booking-target);
    border-radius: var(--appointment-field-radius);
    color: var(--appointment-soc-text);
    text-decoration: none;
}

.month__step:hover,
.month__step:focus-visible {
    background: var(--appointment-soc-hover);
}

/*
 * The week's, beside the dates in the heading. No box and no frame around
 * them: they belong to the dates, and anything drawn round them made a second
 * thing sitting off on its own. The chevron is the whole control, and it
 * answers by changing colour.
 */
.week__step {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 var(--space-2xs);
    color: var(--appointment-soc-text);
    text-decoration: none;
    transition: var(--button-transition);
}

.week__step:hover,
.week__step:focus-visible {
    color: var(--color-accent-strong);
}

/* The two ways to another week, right beside the dates that name this one. */
.week__steps {
    display: flex;
    align-items: center;
    align-self: center;
}

.month__arrow {
    font-size: var(--font-size-h3);
    line-height: 1;
}

/* Sized off the dates beside it, so the pair holds together at either size. */
.week__arrow {
    font-size: 1.2em;
    line-height: 1;
}

/*
 * Read out, never drawn.
 *
 * The arrows would say nothing to a screen reader without their labels. The
 * page's own `<h1>` is here for a different reason: it was asked off the
 * screen — this is a tool the Salon's own Clients are handed a link to, not a
 * page anybody searches for — and a document with no `<h1>` leaves a reader
 * with nothing to say the page is. The browser tab still carries it too.
 */
.booking__title,
.month__step-label,
.week__step-label {
    position: absolute;
    /* The standard hide-from-eyes-not-from-readers idiom, not a design value. */
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.month__grid {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
}

.month__weekday {
    color: var(--table-head-color);
    font-size: var(--font-size-table-head);
    font-weight: var(--font-weight-body);
    padding: var(--table-cell-padding);
}

.month__cell {
    padding: var(--booking-hairline);
    text-align: center;
}

.month__day {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-width: var(--booking-day-size);
    min-height: var(--booking-target);
    border: 0;
    border-radius: var(--appointment-field-radius);
    background: none;
    color: var(--color-text-primary);
    font-size: var(--font-size-table-cell);
    cursor: pointer;
}

.month__day:hover,
.month__day:focus-visible {
    background: var(--appointment-soc-hover);
}

.month__day--outside {
    color: var(--color-text-muted);
}

.month__day--chosen {
    background: var(--button-gradient);
    color: var(--button-text);
}

.month__day--closed {
    color: var(--color-border-divider);
    cursor: default;
}

.month__day--closed:hover {
    background: none;
}

/*
 * The week picker: the day and the time in one screen. Seven columns, Monday
 * first, each holding that day's free times — pressing one answers both, which
 * is why there is no second section after this.
 *
 * Seven on a telephone too. Stacked into seven rows the same week ran 2780px,
 * because the days added up; side by side the page is only as tall as the
 * busiest one of them, which is a little over one screen for the whole week.
 * What that costs is width: 41px a column on a 390px screen, which is why the
 * heading there is one letter and the card gives back some of its padding.
 *
 * No box of its own. The dates and the arrows are the section's heading now,
 * and a bordered box inside a card was a second frame around the same thing —
 * one that also took 32px off the seven columns.
 */

.week__days {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: var(--appointment-field-gap);
}

.week__day {
    min-width: 0;
}

.week__head {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding-bottom: var(--space-2xs);
    border-bottom: var(--booking-hairline) solid var(--appointment-rule);
    margin-bottom: var(--space-2xs);
}

.week__weekday {
    color: var(--table-head-color);
    font-size: var(--font-size-table-head);
}

/* The weekday's first letter, which is all a 41px column has room for. */
.week__initial {
    display: none;
    color: var(--table-head-color);
    font-size: var(--appointment-field-font);
    font-weight: 600;
}

.week__date {
    color: var(--color-text-primary);
    font-size: var(--font-size-table-cell);
}

.week__slots {
    display: grid;
    gap: var(--appointment-field-gap);
}

/* A dash and not an empty box: a column has to say that it was asked. */
.week__none {
    color: var(--color-border-divider);
    text-align: center;
    line-height: var(--booking-target);
}

/* Seven of these across the question column, so the face is the smaller size. */
.week__days .slot {
    font-size: var(--font-size-table-cell);
}

/* The border it keeps is transparent, so the gradient has to cover it too.
   `:disabled` is a press on its way, as on the Procedure rows. */
.slot--chosen:not([aria-busy="true"] *),
.slot:disabled {
    background: var(--button-gradient);
    background-origin: border-box;
    border-color: transparent;
    color: var(--button-text);
}

/*
 * The same seven columns on a telephone, squeezed to fit and no further.
 *
 * The press stays 48px tall, which is what makes this usable by somebody who
 * is not quick with a telephone: the column is narrow, the target is not
 * short. Everything given up to reach 41px a column is spacing and type —
 * the card's own padding, the gaps between the columns, and the size of the
 * two lines over each of them.
 */
@media (max-width: 600px) {
    /* Only the card the week stands in. A form does not want to lose its
       padding, and neither does the price list. */
    .booking__card:has(.week__days) {
        padding: var(--space-xs);
    }

    /* 8px both ways. Tighter would buy a wider column and cost a
       mis-press: these are 48px targets an arthritic thumb has to hit, and
       two of them a hairline apart is one target with two answers. */
    .week__days,
    .week__slots {
        gap: var(--space-2xs);
    }

    .week__weekday {
        display: none;
    }

    .week__initial {
        display: block;
    }

    .week__date {
        font-size: var(--font-size-table-head);
    }

    /* A button's own side padding made each time 47px wide in a column of
       39 at 375px, and 31 at 320: the times lay against, and then over, the
       next day's. No side padding, and the face gives way below 13px only
       where 13px does not fit. */
    .week__days .slot {
        padding-inline: 0;
        font-size: min(var(--appointment-field-font), 3.4vw);
    }
}

/* The times */

.slots {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(var(--booking-slot-column), 1fr));
    gap: var(--appointment-field-gap);
}

.slot {
    width: 100%;
    min-height: var(--booking-target);
    border: var(--booking-hairline) solid var(--color-accent);
    border-radius: var(--appointment-field-radius);
    background: var(--appointment-card-background);
    color: var(--color-text-primary);
    font-size: var(--font-size-body);
    cursor: pointer;
    transition: var(--button-transition);
}

.slot:hover,
.slot:focus-visible {
    background: var(--color-accent);
}

@media (min-width: 900px) {
    .slots {
        grid-template-columns: repeat(auto-fill, minmax(var(--booking-slot-column-wide), 1fr));
    }
}

/* The details form — DESIGN.md §7, raised to the 48px target */

.field {
    position: relative;
    margin-bottom: var(--space-md);
}

/*
 * Exactly the 48px target, and `height` rather than `min-height` so it stays
 * that whatever a browser would otherwise give an input. The text is left to
 * the browser to centre in that height, which is what it does with a
 * single-line input and no vertical padding to argue with.
 *
 * The line height is pinned at 1 so the body's 26px cannot push the text past
 * the box.
 */
.field__input {
    width: 100%;
    height: var(--booking-field-height);
    padding: 0 var(--appointment-field-padding);
    border: var(--booking-hairline) solid var(--appointment-border);
    border-radius: var(--appointment-field-radius);
    background: var(--appointment-card-background);
    color: var(--appointment-text);
    font-size: var(--font-size-body);
    line-height: 1;
}

.field__input:hover {
    border-color: var(--appointment-border-filled);
}

.field__input:focus {
    border-color: var(--color-accent-glow);
    outline: none;
}

/*
 * The border's change of colour alone is a shade apart from the resting one,
 * and a Client tabbing through the form could not see which field had them.
 * The ring doubles the border in the same colour, so the look stays the
 * field's own and the page's outline is not drawn over it.
 */
.field__input:focus-visible {
    box-shadow: 0 0 0 1px var(--color-accent-glow);
}

/*
 * The label sits inside the field, over where the text will go, and is gone
 * once there is text to read there instead. It is aligned to the input's own
 * height rather than to the middle of the field, because the field also holds
 * the help line and the error line.
 */
.field__label {
    position: absolute;
    top: 0;
    left: var(--appointment-field-padding);
    display: flex;
    align-items: center;
    height: var(--booking-field-height);
    color: var(--appointment-label);
    font-size: var(--appointment-label-font);
    line-height: 1;
    pointer-events: none;
    transition: var(--button-transition);
}

/*
 * Gone, not shrunk into the corner. It is still a real `<label for>` in the
 * markup, so a screen reader still names the field; what goes is the sight of
 * it, once the Client has written the answer in its place.
 */
.field__input:not(:placeholder-shown) + .field__label {
    opacity: 0;
}

.field--wrong .field__input {
    border-color: var(--appointment-error);
}

.field__error {
    color: var(--appointment-error);
    font-size: var(--appointment-field-font);
    margin-top: var(--space-2xs);
}

.field__help {
    color: var(--color-text-muted);
    font-size: var(--appointment-field-font);
    margin-top: var(--space-2xs);
}

/*
 * The country in front of the telephone number — `partials/telephone.blade.php`.
 * The button lies over the left of the input rather than beside it, so the row
 * is still the one 48px control DESIGN.md §7 asks for and the floated label
 * still has a place to float to.
 *
 * The flags are `public/flags`, copied out of lipis/flag-icons (MIT; the licence
 * is kept beside them). In the list they are lazy images on a list that ships
 * `hidden`, which is what stops a Client who never opens it from fetching any
 * of them, and one who does from fetching all of them. Refreshing them is a
 * copy out of `node_modules/flag-icons/flags/4x3`; this page has no build step.
 */

.field--tel {
    --booking-flag-width: 22px;
    --booking-flag-height: 16px;
    --booking-country-width: 54px;
    --booking-country-list-height: 280px;

    /* Over the fields under it, under the sticky bar at the foot of the page. */
    --booking-country-list-layer: 2;
}

.tel {
    position: relative;
}

.tel__country {
    position: absolute;
    top: var(--booking-hairline);
    left: var(--booking-hairline);
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2xs);
    width: var(--booking-country-width);
    height: calc(var(--booking-field-height) - var(--booking-rule));
    padding: 0;
    border: 0;
    border-radius: var(--appointment-field-radius) 0 0 var(--appointment-field-radius);
    background: transparent;
    cursor: pointer;
}

/*
 * It ships disabled and the script enables it. Until then it is a flag and
 * nothing more — there is no arrow inviting a press that would do nothing.
 */
.tel__country:disabled {
    cursor: default;
}

.tel__country:disabled .tel__chevron {
    display: none;
}

.tel__chevron {
    width: 0;
    height: 0;
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
    border-top: 5px solid currentColor;
    color: var(--appointment-label);
}

.tel__input {
    padding-left: calc(var(--booking-country-width) + var(--space-2xs));
}

.tel__label {
    left: calc(var(--booking-country-width) + var(--space-2xs));
}

.tel__list {
    position: absolute;
    z-index: var(--booking-country-list-layer);
    top: var(--booking-field-height);
    right: 0;
    left: 0;
    max-height: var(--booking-country-list-height);
    overflow-y: auto;
    margin-top: var(--space-2xs);
    padding: var(--space-2xs);
    border: var(--booking-hairline) solid var(--appointment-border);
    border-radius: var(--appointment-field-radius);
    background: var(--appointment-card-background);
    box-shadow: var(--appointment-card-shadow);
}

.tel__option {
    display: flex;
    align-items: center;
    gap: var(--appointment-field-gap);
    width: 100%;
    min-height: var(--booking-target);
    padding: 0 var(--space-2xs);
    border: 0;
    border-radius: var(--appointment-field-radius);
    background: transparent;
    color: var(--appointment-text);
    font-size: var(--appointment-field-font);
    text-align: left;
    cursor: pointer;
}

.tel__option:hover,
.tel__option:focus-visible {
    background: var(--appointment-card-background-tinted);
}

/* The search hides a row by `hidden`, which `display: flex` above would undo. */
.tel__option[hidden] {
    display: none;
}

.tel__name {
    flex: 1;
}

.tel__dial {
    color: var(--color-text-muted);
}

.tel__flag {
    flex: none;
    width: var(--booking-flag-width);
    height: var(--booking-flag-height);
    border: var(--booking-hairline) solid var(--appointment-border);
    border-radius: var(--radius-sm);
    object-fit: cover;
}

/* A country flag-icons draws no flag for keeps the gap, so the names line up. */
.tel__flag--none {
    visibility: hidden;
}

/*
 * The search over the countries. It stays at the top while the list scrolls
 * under it: the list's own padding is taken back on the sticky edge, or the
 * names would show through the gap above it.
 */
.tel__search {
    position: sticky;
    top: calc(-1 * var(--space-2xs));
    z-index: 1;
    width: 100%;
    min-height: var(--booking-target);
    margin-bottom: var(--space-2xs);
    padding: 0 var(--appointment-field-padding);
    border: var(--booking-hairline) solid var(--appointment-border);
    border-radius: var(--appointment-field-radius);
    background: var(--appointment-card-background);
    box-shadow: 0 calc(-1 * var(--space-2xs)) 0 var(--appointment-card-background);
    color: var(--appointment-text);
    font-size: var(--appointment-field-font);
}

.tel__search:focus-visible {
    outline: none;
    border-color: var(--appointment-border-filled);
}

.tel__none {
    padding: var(--space-xs) var(--space-2xs);
    color: var(--color-text-muted);
    font-size: var(--appointment-field-font);
}

/*
 * The endings offered under the email field — `partials/email.blade.php`.
 *
 * They sit in the flow and push what is below them down, which is what
 * melinda.lv's own form does. An overlay would cover the line that says the
 * field is optional, which is the one thing a Client hesitating over it needs
 * to read.
 */
.email__endings {
    display: grid;
    gap: var(--space-2xs);
    margin-top: var(--space-2xs);
}

.email__ending {
    display: flex;
    align-items: center;
    width: 100%;
    min-height: var(--booking-target);
    padding: 0 var(--appointment-field-padding);
    border: var(--booking-hairline) solid var(--appointment-border);
    border-radius: var(--appointment-field-radius);
    background: var(--appointment-card-background);
    color: var(--appointment-text);
    font-size: var(--font-size-body);
    text-align: left;
    cursor: pointer;
    transition: var(--button-transition);
}

.email__ending:hover,
.email__ending:focus-visible {
    border-color: var(--appointment-border-filled);
    background: var(--appointment-card-background-tinted);
}

.tick {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: center;
    column-gap: var(--appointment-field-gap);
    min-height: var(--booking-target);
    margin-bottom: var(--space-md);
}

.tick__input {
    width: var(--booking-control-size);
    height: var(--booking-control-size);
    accent-color: var(--color-accent-strong);
}

.tick__label {
    color: var(--appointment-text);
    cursor: pointer;
}

.tick__note {
    grid-column: 2;
    color: var(--color-text-muted);
    font-size: var(--appointment-field-font);
}

.tick__note--wrong {
    color: var(--appointment-error);
}

/* What was booked */

.summary {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--space-2xs) var(--space-sm);
    margin-bottom: var(--space-md);
}

.summary__term {
    color: var(--table-head-color);
    font-size: var(--font-size-table-head);
    text-transform: uppercase;
}

.summary__value {
    color: var(--color-text-primary);
    font-size: var(--font-size-table-cell);
}
