/* Copyright (c) 2026 Bc. Jan Krejčí. All rights reserved.
   Proprietary and confidential. See LICENSE in the project root. */

/* ==========================================================================
   Booking.

   Written for the person who has never booked anything online. Everything
   below follows from that one reader:

   · Free time is drawn as something — a pale green block that says "Volno" —
     not as the absence of anything. Green is the one colour everybody reads as
     "go", and "this can be had" is the only thing the schedule has to say.

   · Every target is at least the size of a fingertip. On a phone a half hour
     is 44 px tall, the days are buttons you can hit with a thumb, and the length
     of a booking is changed with a plus and a minus instead of by dragging.

   · The next step is always where the eye already is. On a monitor that is the
     panel on the right; on anything narrower it is a sheet that rises from the
     bottom of the screen the moment a time is tapped.

   · Nothing is ever the only signal. A full day is a word as well as a colour,
     a picked time is a shape as well as a tone.

   Depends on the tokens in chropyne-site.css and adds only what booking needs.
   Rewritten 2026-09-18: the previous file had grown by accretion, carried two
   copies of its own narrow-screen rules and none at all for the month, which is
   how the month shipped as unstyled text.
   ========================================================================== */

:root {
    /* The hour column. Declared once because the heading grid and the body grid
       are separate and have to agree to the pixel: six pixels of disagreement
       puts the pinned axis on top of the first day. */
    --b-axis: 56px;

    --b-radius: 12px;
    --b-radius-lg: 18px;

    /* Depth is a whisper. One elevation for cards, one for the thing that has
       just been picked or has just risen. Any more and it becomes a dashboard. */
    --b-lift: 0 1px 2px rgba(35, 40, 43, .04), 0 10px 30px -14px rgba(35, 40, 43, .18);
    --b-lift-strong: 0 2px 6px rgba(35, 40, 43, .08), 0 22px 48px -18px rgba(35, 40, 43, .32);

    /* Free. The façade's green, softened into something words can sit on. */
    --b-free-bg: #EEF5EC;
    --b-free-edge: #BFD8BA;
    --b-free-ink: #2F5A2A;

    /* The six façade colours, softened into surfaces a block of text can sit on.
       The saturated original stays as the edge, so the code is legible at a
       glance while the fill never fights the words inside it. */
    --b-tone-1-bg: #FBEAE7;  --b-tone-1-edge: #C0392B;  --b-tone-1-ink: #7E2C22;
    --b-tone-2-bg: #FCEFE0;  --b-tone-2-edge: #D2711F;  --b-tone-2-ink: #82491A;
    --b-tone-3-bg: #FAF4DC;  --b-tone-3-edge: #C9A227;  --b-tone-3-ink: #756019;
    --b-tone-4-bg: #E8F1E6;  --b-tone-4-edge: #4A7C42;  --b-tone-4-ink: #33562D;
    --b-tone-5-bg: #E6EFF4;  --b-tone-5-edge: #2E6C8E;  --b-tone-5-ink: #234F67;
    --b-tone-6-bg: #EEEAF3;  --b-tone-6-edge: #6B4E8C;  --b-tone-6-ink: #4C3764;

    --b-spring: cubic-bezier(.2, .9, .25, 1.05);
}

/* The icons. One grid, one stroke, always the colour of the text beside them. */
.ch-i {
    width: 1.15em;
    height: 1.15em;
    flex: none;
    vertical-align: -.2em;
}

/* ==========================================================================
   The page
   ========================================================================== */

.ch-book2 {
    background: var(--ch-bg);
    padding-block: var(--ch-s7) var(--ch-s9);
}

.ch-book2__top { margin-bottom: var(--ch-s5); }

.ch-book2__title h1 {
    font-size: clamp(1.9rem, 1.4rem + 1.6vw, 2.6rem);
    letter-spacing: -.02em;
    margin-bottom: var(--ch-s2);
}

.ch-book2__title p {
    max-width: 52ch;
    color: var(--ch-text-muted);
    font-size: 1.02rem;
}

/* Under the schedule and exactly as wide: a note belongs to what it is about.
   Doubled class, because the site gives every paragraph a reading measure and
   a single class does not outrank it — that measure is what left the note
   narrower than the schedule and pressed right up against it. */
.ch-book2__notice.ch-book2__notice {
    display: flex;
    align-items: flex-start;
    gap: var(--ch-s3);
    width: 100%;
    max-width: none;
    box-sizing: border-box;
    margin: var(--ch-s5) 0 0;
    padding: var(--ch-s3) var(--ch-s4);
    border-radius: var(--b-radius);
    background: var(--ch-wood-100);
    color: #6E5129;
    font-size: .86rem;
    line-height: 1.5;
}

.ch-book2__notice .ch-i { margin-top: .15em; }

.ch-book2__split {
    display: grid;
    gap: var(--ch-s5);
    grid-template-columns: minmax(0, 1fr) 380px;
    align-items: start;
}

.ch-book2__schedule { min-width: 0; position: relative; }

/* While the next day or view is on its way, the current one stays put. If the
   answer is quick — as it nearly always is — nothing changes at all; only a
   wait long enough to notice dims the schedule and runs a hairline across the
   top, so a slow connection still says that the click was heard. */
.ch-book2__schedule > .ch-grid2,
.ch-book2__schedule > .ch-monthcard,
.ch-book2__schedule > .ch-dayhead {
    transition: opacity 200ms var(--ch-ease) 0ms;
}

.ch-book2__schedule.is-busy > .ch-grid2,
.ch-book2__schedule.is-busy > .ch-monthcard,
.ch-book2__schedule.is-busy > .ch-dayhead {
    opacity: .55;
    transition-delay: 180ms;
}

.ch-book2__schedule::before {
    content: "";
    position: absolute;
    z-index: 5;
    left: 12px;
    right: 12px;
    top: 0;
    height: 2px;
    border-radius: 2px;
    background: linear-gradient(90deg, transparent, var(--ch-wood-500), transparent);
    background-size: 40% 100%;
    background-repeat: no-repeat;
    opacity: 0;
    pointer-events: none;
    transition: opacity 150ms var(--ch-ease);
}

.ch-book2__schedule.is-busy::before {
    opacity: 1;
    transition-delay: 180ms;
    animation: b-busy 1.1s linear infinite;
}

@keyframes b-busy {
    from { background-position: -40% 0; }
    to { background-position: 140% 0; }
}

/* The phone's day strip lives in the markup at every width and is shown only
   where it belongs, so the first paint is already the right one. */
.ch-book2__strip { display: none; }

.ch-card {
    background: var(--ch-surface-raised);
    border: 1px solid var(--ch-line);
    border-radius: var(--b-radius-lg);
    padding: var(--ch-s5);
    box-shadow: var(--b-lift);
}

/* ==========================================================================
   The toolbar — monitors
   ========================================================================== */

.ch-bar2 {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--ch-s3);
    margin-bottom: var(--ch-s4);
}

.ch-bar2__move {
    display: inline-flex;
    border: 1px solid var(--ch-line);
    border-radius: var(--b-radius);
    background: var(--ch-surface-raised);
    overflow: hidden;
}

.ch-bar2__arrow {
    width: 46px;
    height: 46px;
    display: grid;
    place-items: center;
    border: 0;
    background: transparent;
    color: var(--ch-text);
    cursor: pointer;
    transition: background var(--ch-fast) var(--ch-ease);
}

.ch-bar2__arrow + .ch-bar2__arrow { border-left: 1px solid var(--ch-line); }
.ch-bar2__arrow:hover:not(:disabled) { background: var(--ch-bg); }
.ch-bar2__arrow:disabled { color: var(--ch-text-faint); cursor: default; }

.ch-bar2__today {
    min-height: 46px;
    padding-inline: var(--ch-s4);
    border: 1px solid var(--ch-line);
    border-radius: var(--b-radius);
    background: var(--ch-surface-raised);
    color: var(--ch-text);
    font: inherit;
    font-size: .92rem;
    font-weight: 500;
    cursor: pointer;
    transition: border-color var(--ch-fast) var(--ch-ease);
}

.ch-bar2__today:hover:not(:disabled) { border-color: var(--ch-line-strong); }
.ch-bar2__today:disabled { color: var(--ch-text-faint); cursor: default; }

/* The answer to "what am I looking at", given the room to be that. */
.ch-bar2__range {
    flex: 1 1 12rem;
    margin: 0;
    max-width: none;
    font-size: 1.2rem;
    font-weight: 600;
    letter-spacing: -.01em;
    font-variant-numeric: tabular-nums;
}

.ch-bar2__range::first-letter { text-transform: uppercase; }

.ch-bar2__views {
    display: inline-flex;
    padding: 4px;
    gap: 2px;
    border: 1px solid var(--ch-line);
    border-radius: var(--b-radius);
    background: var(--ch-graphite-050);
}

.ch-bar2__view {
    min-height: 38px;
    padding-inline: var(--ch-s4);
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--ch-text-muted);
    font: inherit;
    font-size: .9rem;
    font-weight: 500;
    cursor: pointer;
    transition: background var(--ch-fast) var(--ch-ease), color var(--ch-fast) var(--ch-ease);
}

.ch-bar2__view:hover { color: var(--ch-text); }

.ch-bar2__view.is-on {
    background: var(--ch-surface-raised);
    color: var(--ch-text);
    box-shadow: 0 1px 2px rgba(35, 40, 43, .12);
}

/* ==========================================================================
   The day strip — phones
   ==========================================================================
   Big buttons in one sideways row. The rail bleeds to the screen edges so it
   reads as something that continues, which is the hint that it scrolls. */

.ch-strip2 {
    margin-inline: calc(var(--ch-s4) * -1);
    margin-bottom: var(--ch-s4);
}

.ch-strip2__rail {
    display: flex;
    gap: var(--ch-s2);
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x proximity;
    scroll-padding-inline: var(--ch-s4);
    padding: 4px var(--ch-s4) var(--ch-s2);
    scrollbar-width: none;
}

.ch-strip2__rail::-webkit-scrollbar { display: none; }

.ch-strip2__day {
    flex: none;
    width: 66px;
    min-height: 92px;
    display: grid;
    justify-items: center;
    align-content: center;
    gap: 2px;
    padding: var(--ch-s2) 4px 10px;
    border: 1px solid var(--ch-line);
    border-radius: 16px;
    background: var(--ch-surface-raised);
    color: var(--ch-text);
    font: inherit;
    scroll-snap-align: start;
    cursor: pointer;
    box-shadow: 0 1px 2px rgba(35, 40, 43, .04);
    transition: background var(--ch-fast) var(--ch-ease),
                border-color var(--ch-fast) var(--ch-ease),
                transform var(--ch-fast) var(--ch-ease);
    -webkit-tap-highlight-color: transparent;
}

.ch-strip2__day:active { transform: scale(.96); }

.ch-strip2__day.is-weekend:not(.is-selected) { background: #FBF8F2; border-color: #EDE3D4; }
.ch-strip2__day.is-weekend:not(.is-selected) .ch-strip2__name,
.ch-strip2__day.is-weekend:not(.is-selected) .ch-strip2__num { color: var(--ch-wood-600); }

.ch-strip2__name {
    font-size: .74rem;
    font-weight: 600;
    letter-spacing: .02em;
    color: var(--ch-text-muted);
    white-space: nowrap;
}

.ch-strip2__num {
    font-size: 1.55rem;
    font-weight: 600;
    line-height: 1.05;
    font-variant-numeric: tabular-nums;
    letter-spacing: -.02em;
}

.ch-strip2__month {
    font-size: .7rem;
    color: var(--ch-text-faint);
}

/* How much of the day is left, as a bar under the date. */
.ch-strip2__meter {
    width: 34px;
    height: 4px;
    margin-top: 4px;
    border-radius: 2px;
    background: var(--ch-graphite-050);
    overflow: hidden;
}

.ch-strip2__fill {
    display: block;
    width: var(--fill);
    height: 100%;
    border-radius: inherit;
    background: var(--ch-free);
}

.ch-strip2__day.is-tight .ch-strip2__fill { background: var(--ch-warn); }

.ch-strip2__day.is-full,
.ch-strip2__day.is-closed { background: var(--ch-bg); }

.ch-strip2__day.is-full .ch-strip2__num,
.ch-strip2__day.is-closed .ch-strip2__num { color: var(--ch-text-faint); }

.ch-strip2__day.is-selected {
    background: var(--ch-graphite-900);
    border-color: var(--ch-graphite-900);
    color: var(--ch-text-inverse);
    box-shadow: var(--b-lift-strong);
}

.ch-strip2__day.is-selected .ch-strip2__name,
.ch-strip2__day.is-selected .ch-strip2__month { color: rgba(244, 243, 238, .7); }

.ch-strip2__day.is-selected .ch-strip2__meter { background: rgba(244, 243, 238, .18); }
.ch-strip2__day.is-selected .ch-strip2__fill { background: #9FD18F; }

.ch-strip2__day--more {
    border-style: dashed;
    background: transparent;
    box-shadow: none;
    color: var(--ch-text-muted);
}

.ch-strip2__icon .ch-i { width: 26px; height: 26px; }
.ch-strip2__day--more .ch-strip2__name { white-space: normal; text-align: center; line-height: 1.2; }

/* ==========================================================================
   Above the schedule: the day, and what to do
   ========================================================================== */

.ch-dayhead {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: var(--ch-s2);
    margin-bottom: var(--ch-s3);
}

.ch-dayhead__title {
    margin: 0;
    font-size: 1.35rem;
    font-weight: 600;
    letter-spacing: -.015em;
    text-align: center;
}

.ch-dayhead__arrow {
    width: 44px;
    height: 44px;
    display: grid;
    place-items: center;
    border: 1px solid var(--ch-line);
    border-radius: 50%;
    background: var(--ch-surface-raised);
    color: var(--ch-text);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: border-color var(--ch-fast) var(--ch-ease), transform var(--ch-fast) var(--ch-ease);
}

.ch-dayhead__arrow:hover:not(:disabled) { border-color: var(--ch-line-strong); }
.ch-dayhead__arrow:active:not(:disabled) { transform: scale(.92); }
.ch-dayhead__arrow:disabled { color: var(--ch-text-faint); background: transparent; cursor: default; }

.ch-hint {
    display: none;
    align-items: center;
    gap: var(--ch-s3);
    max-width: none;
    margin: 0 0 var(--ch-s3);
    font-size: .95rem;
    font-weight: 500;
    color: var(--b-free-ink);
}

/* A slow pulse in the colour of free time, pointing the eye at what to press. */
.ch-hint__pulse {
    position: relative;
    width: 12px;
    height: 12px;
    flex: none;
    border-radius: 50%;
    background: var(--ch-free);
}

.ch-hint__pulse::after {
    content: "";
    position: absolute;
    inset: -5px;
    border-radius: 50%;
    border: 2px solid var(--ch-free);
    opacity: 0;
    animation: b-pulse 2.2s var(--ch-ease) infinite;
}

@keyframes b-pulse {
    0% { transform: scale(.5); opacity: .8; }
    80%, 100% { transform: scale(1.4); opacity: 0; }
}

/* ==========================================================================
   The grid
   ========================================================================== */

.ch-grid2 {
    background: var(--ch-surface-raised);
    border: 1px solid var(--ch-line);
    border-radius: var(--b-radius-lg);
    padding: var(--ch-s4) var(--ch-s4) var(--ch-s5);
    box-shadow: var(--b-lift);
}

.ch-grid2__scroll { min-width: 0; }

.ch-grid2__head {
    display: grid;
    grid-template-columns: var(--b-axis) repeat(var(--lanes), minmax(0, 1fr));
    gap: var(--ch-s2);
    /* The headings stay put while the day scrolls under them, so a column is
       never anonymous. */
    position: sticky;
    top: 68px;
    z-index: 3;
    background: var(--ch-surface-raised);
    padding-bottom: var(--ch-s3);
}

.ch-grid2__corner { grid-column: 1; }

.ch-grid2__lanehead {
    display: grid;
    gap: 1px;
    justify-items: center;
    align-content: center;
    min-height: 56px;
    padding: var(--ch-s2);
    border: 1px solid transparent;
    border-radius: var(--b-radius);
    background: transparent;
    color: var(--ch-text);
    font: inherit;
    cursor: pointer;
    transition: background var(--ch-fast) var(--ch-ease), border-color var(--ch-fast) var(--ch-ease);
}

.ch-grid2__lanehead:hover { background: var(--ch-bg); border-color: var(--ch-line); }

.ch-grid2__lanename {
    font-size: .84rem;
    font-weight: 600;
    letter-spacing: .02em;
}

.ch-grid2__lanename::first-letter { text-transform: uppercase; }

.ch-grid2__lanesub {
    font-size: .78rem;
    color: var(--ch-text-muted);
    font-variant-numeric: tabular-nums;
}

/* The weekend, as a paper diary marks it: the day's name in the warm timber
   tone and the column a shade warmer than the rest. Quiet enough that the
   free time in it still reads first. */
.ch-grid2__lanehead.is-weekend .ch-grid2__lanename { color: var(--ch-wood-600); }
.ch-grid2__lanehead.is-weekend .ch-grid2__lanesub { color: #A58560; }
.ch-grid2__lane.is-weekend .ch-grid2__track { background: #FBF8F2; border-color: #EDE3D4; }
.ch-grid2__lanehead.is-weekend.is-current .ch-grid2__lanename,
.ch-grid2__lanehead.is-weekend.is-current .ch-grid2__lanesub { color: #E6CBA6; }

/* Today is a ring; the column being worked on is a fill. Two different facts,
   two different marks, so both can be true at once. */
.ch-grid2__lanehead.is-today { box-shadow: inset 0 0 0 1.5px var(--ch-wood-400); }

.ch-grid2__lanehead.is-current {
    background: var(--ch-graphite-900);
    border-color: var(--ch-graphite-900);
    color: var(--ch-text-inverse);
}

.ch-grid2__lanehead.is-current .ch-grid2__lanesub { color: rgba(244, 243, 238, .65); }

/* One column needs no heading: the day above already says what it is, and a
   button that leads nowhere is a button somebody will press and wonder about. */
.ch-grid2.is-single .ch-grid2__head { display: none; }

.ch-grid2__body {
    display: grid;
    grid-template-columns: var(--b-axis) minmax(0, 1fr);
    gap: var(--ch-s3);
    /* The first hour label is centred on the top edge of the track, so half of
       it would sit outside the box and be clipped by whatever is above. */
    padding-top: 7px;
}

.ch-grid2__axis {
    position: relative;
    height: calc(var(--steps) * var(--step-h));
}

/* Labels sit on the line they name rather than in the band below it, which is
   how a clock face reads. */
.ch-grid2__hour {
    position: absolute;
    right: 0;
    top: calc(var(--at) * var(--step-h));
    transform: translateY(-50%);
    font-size: .76rem;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
    color: var(--ch-text-faint);
    white-space: nowrap;
}

.ch-grid2__lanes {
    display: grid;
    grid-template-columns: repeat(var(--lanes), minmax(0, 1fr));
    gap: var(--ch-s2);
    min-width: 0;
}

.ch-grid2__lane { min-width: 0; }

.ch-grid2__track {
    position: relative;
    height: calc(var(--steps) * var(--step-h));
    border: 1px solid var(--ch-line);
    border-radius: var(--b-radius);
    background: var(--ch-surface-raised);
    overflow: hidden;
    /* A finger scrolls the page up and down; a tap picks a time. The code
       chooses on the tap for touch, so the vertical pan is left to the browser
       — refusing it made a day on a phone impossible to scroll. */
    touch-action: pan-y;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

.ch-grid2__track:focus { outline: none; }

.ch-grid2__track:focus-visible {
    outline: 2px solid var(--ch-wood-600);
    outline-offset: 2px;
}

/* One rule per step, heavier on the hour, so the eye can count without a grid
   drawn over the content. */
.ch-grid2__rule {
    position: absolute;
    left: 0;
    right: 0;
    top: calc(var(--at) * var(--step-h));
    height: 1px;
    background: var(--ch-line);
    opacity: .45;
}

.ch-grid2__rule.is-hour { opacity: 1; }

/* The part of the day that has gone. One flat shape: the past is a single
   uninterrupted fact, and drawing it as steps would invite a click. */
.ch-grid2__past {
    position: absolute;
    inset: 0 0 auto 0;
    height: calc(var(--to) * var(--step-h));
    background:
        repeating-linear-gradient(135deg, rgba(142, 151, 155, .08) 0 6px, transparent 6px 12px),
        var(--ch-bg);
    z-index: 1;
}

/* Everything drawn on the track is scenery; the track is the control. A pointer
   event reports its position against whatever element caught it, so a line or a
   block left in the event path makes every press land at opening time. */
.ch-grid2__rule,
.ch-grid2__past,
.ch-grid2__free,
.ch-grid2__event,
.ch-grid2__peek,
.ch-grid2__caret,
.ch-grid2__pick,
.ch-grid2__now { pointer-events: none; }

/* --------------------------------------------------------------------------
   Free time
   -------------------------------------------------------------------------- */

.ch-grid2__free {
    position: absolute;
    left: 4px;
    right: 4px;
    top: calc(var(--from) * var(--step-h) + 2px);
    height: calc((var(--to) - var(--from)) * var(--step-h) - 4px);
    z-index: 1;
    border-radius: 9px;
    background: var(--b-free-bg);
    box-shadow: inset 0 0 0 1px var(--b-free-edge);
    transition: background var(--ch-fast) var(--ch-ease);
}

.ch-grid2__free-label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 10px;
    font-size: .8rem;
    font-weight: 600;
    color: var(--b-free-ink);
    white-space: nowrap;
}

.ch-grid2__free-range {
    font-weight: 500;
    font-variant-numeric: tabular-nums;
    opacity: .75;
}

.ch-grid2__free-plus {
    display: inline-grid;
    place-items: center;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: var(--ch-free);
    color: #FFF;
    font-size: .85rem;
    line-height: 1;
}

.ch-grid2__free { overflow: hidden; }

.ch-grid2__track:hover .ch-grid2__free { background: #E6F0E3; }

/* A week column is about eighty pixels wide: the word fits, the hours do not.
   The hours are already on the axis beside it. */
.ch-grid2:not(.is-single) .ch-grid2__free-range { display: none; }

.ch-grid2:not(.is-single) .ch-grid2__free-label {
    gap: 5px;
    padding: 6px 7px;
    font-size: .76rem;
}

.ch-grid2:not(.is-single) .ch-grid2__free-plus { width: 16px; height: 16px; font-size: .78rem; }

/* --------------------------------------------------------------------------
   Bookings
   -------------------------------------------------------------------------- */

.ch-grid2__event {
    position: absolute;
    left: 4px;
    right: 4px;
    top: calc(var(--from) * var(--step-h) + 2px);
    height: calc((var(--to) - var(--from)) * var(--step-h) - 4px);
    z-index: 2;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    gap: 1px;
    padding: 6px var(--ch-s3) 6px 12px;
    border-radius: 9px;
    overflow: hidden;
    font-size: .76rem;
    line-height: 1.3;
    /* The saturated original of the façade colour, as a spine down the left.
       The fill is the same colour softened until words can sit on it. */
    box-shadow: inset 4px 0 0 var(--edge, var(--ch-graphite-300));
    background: var(--fill, var(--ch-graphite-050));
    color: var(--ink, var(--ch-graphite-500));
}

.ch-grid2__event-time { font-variant-numeric: tabular-nums; opacity: .85; }
.ch-grid2__event-name { font-weight: 600; }

.ch-grid2__event-where {
    opacity: .7;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The six façade colours, as a code for what is being played. The name is
   always written inside the block, so the colour is a shortcut and never the
   only way to know. */
.ch-tone-1 { --fill: var(--b-tone-1-bg); --edge: var(--b-tone-1-edge); --ink: var(--b-tone-1-ink); }
.ch-tone-2 { --fill: var(--b-tone-2-bg); --edge: var(--b-tone-2-edge); --ink: var(--b-tone-2-ink); }
.ch-tone-3 { --fill: var(--b-tone-3-bg); --edge: var(--b-tone-3-edge); --ink: var(--b-tone-3-ink); }
.ch-tone-4 { --fill: var(--b-tone-4-bg); --edge: var(--b-tone-4-edge); --ink: var(--b-tone-4-ink); }
.ch-tone-5 { --fill: var(--b-tone-5-bg); --edge: var(--b-tone-5-edge); --ink: var(--b-tone-5-ink); }
.ch-tone-6 { --fill: var(--b-tone-6-bg); --edge: var(--b-tone-6-edge); --ink: var(--b-tone-6-ink); }

/* Being taken by somebody else right now. Warm, because waiting two minutes is
   sometimes the right move and this has to be tellable apart from gone. */
.ch-grid2__event--held { --fill: var(--ch-wood-100); --edge: var(--ch-wood-500); --ink: #7A5A2E; }

/* Closed by the hall. Hatched, so it reads as "not on offer" rather than
   "somebody beat you to it" — two different disappointments. */
.ch-grid2__event--blocked {
    --ink: var(--ch-graphite-500);
    --edge: var(--ch-graphite-150);
    background:
        repeating-linear-gradient(45deg, rgba(142, 151, 155, .14) 0 6px, transparent 6px 12px),
        var(--ch-bg);
}

/* --------------------------------------------------------------------------
   Picking a time
   -------------------------------------------------------------------------- */

/* What taking this time would mean, before anything is committed to. Mouse
   only: a finger has no hover, and a tap already means "this one". */
.ch-grid2__peek {
    position: absolute;
    left: 4px;
    right: 4px;
    top: calc(var(--from) * var(--step-h) + 2px);
    height: calc((var(--to) - var(--from)) * var(--step-h) - 4px);
    z-index: 5;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 2px;
    padding: 4px var(--ch-s3);
    border-radius: 9px;
    background: var(--ch-graphite-900);
    color: var(--ch-text-inverse);
    box-shadow: var(--b-lift-strong);
    font-size: .78rem;
    line-height: 1.25;
    animation: b-peek 120ms var(--ch-ease);
}

.ch-grid2__peek-time { font-variant-numeric: tabular-nums; font-weight: 600; }
.ch-grid2__peek-cta { color: var(--ch-wood-400); }

@keyframes b-peek {
    from { opacity: 0; transform: scale(.98); }
    to { opacity: 1; transform: none; }
}

/* What has been picked. The only saturated thing on the track. */
.ch-grid2__pick {
    position: absolute;
    left: 2px;
    right: 2px;
    top: calc(var(--from) * var(--step-h) + 1px);
    height: calc((var(--to) - var(--from)) * var(--step-h) - 2px);
    z-index: 6;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 2px;
    padding: 6px var(--ch-s3);
    border-radius: 10px;
    background: var(--ch-wood-500);
    color: #FFF;
    box-shadow: 0 0 0 3px rgba(181, 131, 74, .25), 0 10px 24px -8px rgba(154, 106, 53, .55);
    font-size: .82rem;
    line-height: 1.25;
    animation: b-pick 220ms var(--b-spring);
}

.ch-grid2__pick-time { font-variant-numeric: tabular-nums; font-weight: 700; font-size: .95em; }
.ch-grid2__pick-len { opacity: .92; }

@keyframes b-pick {
    from { opacity: .3; transform: scale(.94); }
    to { opacity: 1; transform: none; }
}

/* Where the keyboard is standing. An outline rather than a fill, so it can sit
   over a booking without hiding it and is never mistaken for a selection. */
.ch-grid2__caret {
    position: absolute;
    left: 2px;
    right: 2px;
    top: calc(var(--from) * var(--step-h));
    height: calc((var(--to) - var(--from)) * var(--step-h));
    z-index: 7;
    display: none;
    border: 2px solid var(--ch-graphite-800);
    border-radius: 9px;
}

/* Only for the keyboard. A tap or a click also focuses the track, and a black
   frame appearing somewhere else on the day at the moment of tapping reads as a
   second, mysterious selection. */
.ch-grid2__track:focus-visible .ch-grid2__caret { display: block; }

/* Now. The first thing anyone wants to know about today. */
.ch-grid2__now {
    position: absolute;
    left: 0;
    right: 0;
    top: calc(var(--at) * var(--step-h));
    height: 0;
    z-index: 8;
    border-top: 2px solid var(--ch-bad);
}

.ch-grid2__now-dot {
    position: absolute;
    left: -4px;
    top: -5px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--ch-bad);
}

/* The shape of the grid while it loads, so nothing jumps when the real one
   arrives. A spinner says "wait"; this says "here is where it will be". */
.ch-gridskel {
    display: grid;
    gap: 6px;
    padding: var(--ch-s5);
    background: var(--ch-surface-raised);
    border: 1px solid var(--ch-line);
    border-radius: var(--b-radius-lg);
}

.ch-gridskel__row {
    height: 26px;
    border-radius: 6px;
    background: linear-gradient(90deg, var(--ch-graphite-050) 0%, var(--ch-bg) 50%, var(--ch-graphite-050) 100%);
    background-size: 200% 100%;
    animation: b-shimmer 1.4s linear infinite;
}

@keyframes b-shimmer {
    from { background-position: 200% 0; }
    to { background-position: -200% 0; }
}

/* ==========================================================================
   The month
   ========================================================================== */

.ch-monthcard {
    background: var(--ch-surface-raised);
    border: 1px solid var(--ch-line);
    border-radius: var(--b-radius-lg);
    padding: var(--ch-s5);
    box-shadow: var(--b-lift);
}

.ch-monthcard__head {
    display: none;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: var(--ch-s2);
    margin-bottom: var(--ch-s4);
}

.ch-monthcard__title {
    margin: 0;
    font-size: 1.3rem;
    font-weight: 600;
    letter-spacing: -.015em;
    text-align: center;
}

.ch-monthcard__close {
    display: none;
    align-items: center;
    justify-content: center;
    gap: var(--ch-s2);
    width: 100%;
    min-height: 50px;
    margin-top: var(--ch-s4);
    border: 1px solid var(--ch-line);
    border-radius: 14px;
    background: var(--ch-surface-raised);
    color: var(--ch-text);
    font: inherit;
    font-size: .95rem;
    font-weight: 500;
    cursor: pointer;
}

.ch-cal { display: grid; gap: var(--ch-s3); }

.ch-cal__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ch-s3);
}

.ch-cal__title strong { font-size: 1.2rem; font-weight: 600; margin-right: .35em; }
.ch-cal__title strong::first-letter { text-transform: uppercase; }
.ch-cal__title span { color: var(--ch-text-muted); }

.ch-cal__nav {
    width: 44px;
    height: 44px;
    display: grid;
    place-items: center;
    border: 1px solid var(--ch-line);
    border-radius: var(--b-radius);
    background: var(--ch-surface-raised);
    color: var(--ch-text);
    cursor: pointer;
}

.ch-cal__nav:disabled { color: var(--ch-text-faint); cursor: default; }

.ch-cal__weekdays,
.ch-cal__grid {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 6px;
}

.ch-cal__weekdays span {
    text-align: center;
    font-size: .74rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--ch-text-faint);
    padding-bottom: 2px;
}

.ch-cal__weekdays span.is-weekend { color: var(--ch-wood-600); }

.ch-cal__day.is-weekend:not(.is-selected):not(:disabled) {
    background: #FBF8F2;
    border-color: #EDE3D4;
}

.ch-cal__day.is-weekend:not(.is-selected) .ch-cal__num { color: var(--ch-wood-600); }
.ch-cal__day.is-weekend:disabled .ch-cal__num { color: #CDB89B; }

.ch-cal__day {
    position: relative;
    display: grid;
    justify-items: center;
    align-content: center;
    gap: 6px;
    aspect-ratio: 1 / 1;
    min-height: 48px;
    padding: 6px 4px;
    border: 1px solid var(--ch-line);
    border-radius: 14px;
    background: var(--ch-surface-raised);
    color: var(--ch-text);
    font: inherit;
    cursor: pointer;
    transition: background var(--ch-fast) var(--ch-ease),
                border-color var(--ch-fast) var(--ch-ease),
                transform var(--ch-fast) var(--ch-ease);
    -webkit-tap-highlight-color: transparent;
}

.ch-cal__day:hover:not(:disabled) {
    border-color: var(--ch-graphite-300);
    transform: translateY(-1px);
    box-shadow: var(--b-lift);
}

.ch-cal__day:focus-visible { outline: 2px solid var(--ch-wood-600); outline-offset: 2px; }

.ch-cal__num {
    font-size: 1.05rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    line-height: 1;
}

.ch-cal__meter {
    width: 60%;
    max-width: 44px;
    height: 4px;
    border-radius: 2px;
    background: var(--ch-graphite-050);
    overflow: hidden;
}

.ch-cal__meter--empty { background: transparent; }

.ch-cal__meter-fill {
    display: block;
    width: var(--fill);
    height: 100%;
    border-radius: inherit;
    background: var(--ch-free);
}

.ch-cal__day.is-tight .ch-cal__meter-fill { background: var(--ch-warn); }

.ch-cal__day.is-outside { visibility: hidden; }

.ch-cal__day.is-past,
.ch-cal__day.is-closed,
.ch-cal__day.is-full,
.ch-cal__day:disabled {
    background: transparent;
    border-color: transparent;
    color: var(--ch-text-faint);
    cursor: default;
}

.ch-cal__day.is-full .ch-cal__num { text-decoration: line-through; text-decoration-thickness: 1px; }

.ch-cal__day.is-today { box-shadow: inset 0 0 0 1.5px var(--ch-wood-400); }

.ch-cal__day.is-selected {
    background: var(--ch-graphite-900);
    border-color: var(--ch-graphite-900);
    color: var(--ch-text-inverse);
}

.ch-cal__day.is-selected .ch-cal__meter { background: rgba(244, 243, 238, .18); }
.ch-cal__day.is-selected .ch-cal__meter-fill { background: #9FD18F; }

.ch-cal__legend {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ch-s2) var(--ch-s5);
    margin-top: var(--ch-s2);
    padding-top: var(--ch-s3);
    border-top: 1px solid var(--ch-line);
    font-size: .8rem;
    color: var(--ch-text-muted);
}

.ch-cal__key { display: inline-flex; align-items: center; gap: var(--ch-s2); }

.ch-cal__key::before {
    content: "";
    width: 18px;
    height: 4px;
    border-radius: 2px;
    background: var(--ch-free);
}

.ch-cal__key--tight::before { background: var(--ch-warn); }
.ch-cal__key--full::before { background: var(--ch-graphite-150); }

.ch-cal__grid { transition: opacity var(--ch-base) var(--ch-ease), transform var(--ch-base) var(--ch-ease); }
.ch-cal.is-shifting-forward .ch-cal__grid { opacity: .4; transform: translateX(-6px); }
.ch-cal.is-shifting-back .ch-cal__grid { opacity: .4; transform: translateX(6px); }

/* ==========================================================================
   The panel — what you are about to book
   ========================================================================== */

.ch-book2__panel { position: sticky; top: calc(68px + var(--ch-s4)); }

.ch-panel2 {
    position: relative;
    background: var(--ch-surface-raised);
    border: 1px solid var(--ch-line);
    border-radius: var(--b-radius-lg);
    box-shadow: var(--b-lift);
    overflow: hidden;
}

.ch-panel2__photo { position: relative; }

.ch-panel2__photo img {
    display: block;
    width: 100%;
    height: 160px;
    object-fit: cover;
}

/* The caption sits on the photograph under a gradient rather than beside it, so
   the picture keeps its full width and the words stay legible over whatever
   happens to be behind them. */
.ch-panel2__photo-cap {
    position: absolute;
    inset: auto 0 0 0;
    display: grid;
    gap: 1px;
    padding: var(--ch-s5) var(--ch-s4) var(--ch-s3);
    background: linear-gradient(to top, rgba(20, 24, 26, .78), transparent);
    color: #FFF;
}

.ch-panel2__photo-cap strong { font-size: 1.05rem; font-weight: 600; }
.ch-panel2__photo-cap span { font-size: .8rem; opacity: .8; }

.ch-panel2__body { position: relative; padding: var(--ch-s5) var(--ch-s5) var(--ch-s5); }

.ch-panel2__title {
    margin: 0 0 var(--ch-s4);
    font-size: 1.2rem;
    font-weight: 600;
    letter-spacing: -.01em;
}

/* The sheet's handle and its close button exist only when it is a sheet. */
.ch-panel2__grabber,
.ch-panel2__close { display: none; }

/* --------------------------------------------------------------------------
   The three steps, before anything is picked
   -------------------------------------------------------------------------- */

.ch-guide {
    display: grid;
    gap: var(--ch-s4);
    margin: 0;
    padding: 0;
    list-style: none;
    counter-reset: none;
}

.ch-guide__step {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--ch-s3);
    align-items: start;
    font-size: .9rem;
    color: var(--ch-text-muted);
    line-height: 1.45;
}

.ch-guide__step strong {
    display: block;
    color: var(--ch-text);
    font-size: .98rem;
    font-weight: 600;
}

.ch-guide__n {
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--ch-bg);
    border: 1px solid var(--ch-line);
    color: var(--ch-text);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.ch-guide__step:nth-child(2) .ch-guide__n {
    background: var(--b-free-bg);
    border-color: var(--b-free-edge);
    color: var(--b-free-ink);
}

/* --------------------------------------------------------------------------
   What has been picked
   -------------------------------------------------------------------------- */

.ch-detail { margin: 0; display: grid; }

.ch-detail__row {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: center;
    gap: var(--ch-s3);
    padding-block: var(--ch-s3);
    border-top: 1px solid var(--ch-line);
}

.ch-detail__row:last-child { border-bottom: 1px solid var(--ch-line); }

.ch-detail dt {
    display: inline-flex;
    align-items: center;
    gap: var(--ch-s2);
    font-size: .82rem;
    color: var(--ch-text-muted);
}

.ch-detail dd {
    margin: 0;
    display: grid;
    gap: 2px;
    text-align: right;
    line-height: 1.35;
}

.ch-detail dd strong { font-weight: 600; }
.ch-detail dd strong::first-letter { text-transform: uppercase; }

.ch-detail dd span {
    font-size: .84rem;
    color: var(--ch-text-muted);
    font-variant-numeric: tabular-nums;
}

.ch-detail dd .ch-detail__big {
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--ch-text);
    letter-spacing: -.01em;
}

/* The total is the line the eye should land on. */
.ch-detail__row--total .ch-detail__money { font-size: 1.3rem; letter-spacing: -.01em; }

.ch-detail__tbd { color: var(--ch-text-faint); font-weight: 500; }

/* --------------------------------------------------------------------------
   How long — a minus and a plus
   -------------------------------------------------------------------------- */

.ch-length {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: var(--ch-s2) var(--ch-s3);
    margin-top: var(--ch-s4);
    padding: var(--ch-s3) var(--ch-s3) var(--ch-s3) var(--ch-s4);
    border-radius: var(--b-radius);
    background: var(--ch-bg);
}

.ch-length__label { font-size: .88rem; font-weight: 500; color: var(--ch-text-muted); }

.ch-length__control {
    display: inline-flex;
    align-items: center;
    gap: var(--ch-s2);
}

.ch-length__btn {
    width: 48px;
    height: 48px;
    display: grid;
    place-items: center;
    border: 1px solid var(--ch-line);
    border-radius: 50%;
    background: var(--ch-surface-raised);
    color: var(--ch-text);
    cursor: pointer;
    box-shadow: 0 1px 2px rgba(35, 40, 43, .06);
    transition: transform var(--ch-fast) var(--ch-ease), border-color var(--ch-fast) var(--ch-ease);
    -webkit-tap-highlight-color: transparent;
}

.ch-length__btn .ch-i { width: 22px; height: 22px; }
.ch-length__btn:hover:not(:disabled) { border-color: var(--ch-graphite-300); }
.ch-length__btn:active:not(:disabled) { transform: scale(.92); }
.ch-length__btn:disabled { color: var(--ch-text-faint); background: transparent; box-shadow: none; cursor: default; }

.ch-length__value {
    min-width: 5.6em;
    text-align: center;
    font-size: 1.1rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.ch-length__note {
    grid-column: 1 / -1;
    font-size: .78rem;
    color: var(--ch-text-faint);
    text-align: right;
}

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */

.ch-panel2__actions {
    display: grid;
    gap: var(--ch-s2);
    margin-top: var(--ch-s5);
}

.ch-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--ch-s2);
    min-height: 56px;
    padding-inline: var(--ch-s5);
    border: 1px solid transparent;
    border-radius: 14px;
    font: inherit;
    font-size: 1.02rem;
    font-weight: 600;
    cursor: pointer;
    transition: background var(--ch-fast) var(--ch-ease),
                border-color var(--ch-fast) var(--ch-ease),
                transform var(--ch-fast) var(--ch-ease);
    -webkit-tap-highlight-color: transparent;
}

.ch-btn--primary {
    background: var(--ch-graphite-900);
    color: var(--ch-text-inverse);
    box-shadow: 0 8px 20px -10px rgba(35, 40, 43, .6);
}

.ch-btn--primary:hover:not(:disabled) { background: #000; transform: translateY(-1px); }
.ch-btn--primary:active:not(:disabled) { transform: scale(.985); }

.ch-btn:disabled { opacity: .45; cursor: not-allowed; transform: none; }

.ch-btn--quiet {
    min-height: 46px;
    background: transparent;
    color: var(--ch-text-muted);
    font-size: .95rem;
    font-weight: 500;
}

.ch-btn--quiet:hover { color: var(--ch-text); background: var(--ch-bg); }

.ch-panel2__foot {
    display: flex;
    align-items: flex-start;
    gap: var(--ch-s3);
    margin-top: var(--ch-s5);
    padding-top: var(--ch-s4);
    border-top: 1px solid var(--ch-line);
    font-size: .84rem;
    color: var(--ch-text-muted);
}

.ch-panel2__foot .ch-i { margin-top: .15em; color: var(--ch-text-faint); }
.ch-panel2__foot strong { display: block; color: var(--ch-text); font-weight: 600; }

/* ==========================================================================
   The form
   ==========================================================================
   Three fields and a note. Nothing is asked for that the hall does not need. */

.ch-form {
    display: grid;
    gap: var(--ch-s4);
    margin-top: var(--ch-s4);
}

.ch-field { display: grid; gap: 6px; }

.ch-field__label {
    font-size: .88rem;
    font-weight: 600;
    color: var(--ch-text);
}

.ch-field__input {
    min-height: 52px;
    padding: var(--ch-s2) var(--ch-s4);
    border: 1px solid var(--ch-line-strong);
    border-radius: var(--b-radius);
    background: var(--ch-surface-raised);
    color: var(--ch-text);
    font: inherit;
    /* 16 px or more, or iOS zooms the whole page the moment a field is tapped
       and never zooms back. */
    font-size: 1rem;
    transition: border-color var(--ch-fast) var(--ch-ease), box-shadow var(--ch-fast) var(--ch-ease);
}

.ch-field__input::placeholder { color: var(--ch-text-faint); }

.ch-field__input:focus {
    outline: none;
    border-color: var(--ch-wood-500);
    /* A ring rather than a thicker border, so the field does not change size
       and the line of inputs does not shuffle as focus moves down it. */
    box-shadow: 0 0 0 4px rgba(181, 131, 74, .18);
}

.ch-field__input--area { resize: vertical; min-height: 72px; line-height: 1.45; }

.ch-form__error {
    margin: 0;
    max-width: none;
    padding: var(--ch-s3) var(--ch-s4);
    border-radius: var(--b-radius);
    background: #FBEAE7;
    color: #7E2C22;
    font-size: .92rem;
    line-height: 1.45;
}

.ch-form__small {
    display: flex;
    align-items: flex-start;
    gap: var(--ch-s2);
    margin: 0;
    max-width: none;
    font-size: .8rem;
    color: var(--ch-text-faint);
}

.ch-form__small .ch-i { margin-top: .1em; }

/* ==========================================================================
   Done
   ========================================================================== */

.ch-done { text-align: center; }

.ch-done__tick {
    display: grid;
    place-items: center;
    width: 64px;
    height: 64px;
    margin: 0 auto var(--ch-s3);
    border-radius: 50%;
    background: var(--ch-free);
    color: #FFF;
    box-shadow: 0 0 0 8px var(--b-free-bg);
    animation: b-done 420ms var(--b-spring);
}

.ch-done__tick .ch-i { width: 32px; height: 32px; }

@keyframes b-done {
    from { transform: scale(.4); opacity: 0; }
    to { transform: none; opacity: 1; }
}

.ch-done__title { margin: 0; font-size: 1.45rem; font-weight: 600; }

.ch-done__number {
    display: inline-block;
    margin: var(--ch-s3) 0 var(--ch-s5);
    padding: 6px 14px;
    border-radius: 999px;
    background: var(--ch-bg);
    font-size: 1.05rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    letter-spacing: .04em;
}

.ch-done .ch-detail { text-align: left; }

.ch-done__sent {
    margin: var(--ch-s4) 0 var(--ch-s3);
    font-size: .88rem;
    color: var(--ch-text-muted);
}

.ch-done .ch-btn { width: 100%; }

/* ==========================================================================
   Below a monitor: the panel becomes a sheet
   ==========================================================================
   The schedule takes the whole width. The panel is out of the way until a
   time is picked, then rises from the bottom of the screen with the answer
   and the button — under the thumb that did the picking, instead of a scroll
   away beneath a whole day. The page gets room at the bottom so the sheet
   never covers the last hours of the day. */

@media (max-width: 1099px) {
    .ch-book2__split { grid-template-columns: minmax(0, 1fr); }
    .ch-book2__panel { position: static; }

    .ch-hint { display: flex; }

    .ch-panel2 { display: none; }

    .ch-panel2.has-pick {
        display: block;
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 60;
        max-height: min(88dvh, 720px);
        overflow-y: auto;
        overscroll-behavior: contain;
        border: 0;
        border-radius: 22px 22px 0 0;
        box-shadow: 0 -12px 40px -8px rgba(35, 40, 43, .28);
        animation: b-sheet 320ms var(--b-spring);
    }

    /* Filling in the form is the one moment the schedule behind should step
       back: the page is dimmed, not covered, so the picked time stays visible
       through it. */
    .ch-panel2.has-pick.is-form { box-shadow: 0 0 0 100vmax rgba(35, 40, 43, .38); }

    .ch-panel2.has-pick .ch-panel2__photo { display: none; }

    .ch-panel2.has-pick .ch-panel2__body {
        width: min(100%, 560px);
        margin-inline: auto;
        padding: var(--ch-s5) var(--ch-s4) calc(var(--ch-s4) + env(safe-area-inset-bottom));
    }

    .ch-panel2.has-pick .ch-panel2__grabber {
        display: block;
        width: 40px;
        height: 5px;
        margin: -8px auto var(--ch-s3);
        border-radius: 3px;
        background: var(--ch-graphite-150);
    }

    .ch-panel2.has-pick .ch-panel2__close {
        display: grid;
        place-items: center;
        position: absolute;
        top: var(--ch-s3);
        right: var(--ch-s3);
        width: 44px;
        height: 44px;
        border: 0;
        border-radius: 50%;
        background: var(--ch-bg);
        color: var(--ch-text);
        cursor: pointer;
    }

    .ch-panel2.has-pick .ch-panel2__title { padding-right: 52px; margin-bottom: var(--ch-s3); }

    /* In the sheet the "no account" note has already been read by now. */
    .ch-panel2.has-pick .ch-panel2__foot { display: none; }

    .ch-panel2.has-pick .ch-panel2__actions {
        grid-template-columns: 1fr auto;
        margin-top: var(--ch-s4);
    }

    .ch-panel2.has-pick .ch-panel2__actions .ch-btn--primary { order: 2; }
    .ch-panel2.has-pick .ch-panel2__actions .ch-btn--quiet { order: 1; }

    .ch-book2:has(.ch-panel2.has-pick) { padding-bottom: 380px; }
}

@keyframes b-sheet {
    from { transform: translateY(100%); }
    to { transform: none; }
}

/* The site header stops being sticky where the menu folds into the burger, so
   the column headings pin to the very top instead of under it. */
@media (max-width: 1080px) {
    .ch-grid2__head { top: 0; }
}

@media (max-width: 860px) {
    .ch-book2 { padding-block: var(--ch-s5) var(--ch-s8); }
}

/* ==========================================================================
   Phones
   ==========================================================================
   One day, full width, a finger's height per half hour, and the days above it
   as big buttons. The monitor's toolbar goes: three rows of controls above the
   schedule was three rows to understand before the first thing to press. */

@media (max-width: 760px) {
    :root { --b-axis: 46px; }

    .ch-bar2 { display: none; }
    .ch-book2__strip { display: block; }

    .ch-book2__top { margin-bottom: var(--ch-s4); }
    .ch-book2__title h1 { font-size: 1.85rem; }
    .ch-book2__title p { font-size: .95rem; }

    .ch-book2__notice.ch-book2__notice { margin-top: var(--ch-s4); font-size: .82rem; }

    .ch-dayhead {
        position: sticky;
        top: 0;
        z-index: 20;
        margin-inline: calc(var(--ch-s4) * -1);
        padding: 10px var(--ch-s4);
        background: rgba(244, 243, 238, .92);
        -webkit-backdrop-filter: saturate(1.4) blur(10px);
        backdrop-filter: saturate(1.4) blur(10px);
        border-bottom: 1px solid transparent;
    }

    .ch-dayhead__title { font-size: 1.12rem; }

    /* Until the browser has said how wide it is, a phone would see the week grid
       it is about to leave. It sees the space where the day will be instead. */
    .ch-book2:not(.is-measured) .ch-book2__schedule { visibility: hidden; min-height: 60vh; }

    .ch-grid2 { padding: var(--ch-s3) var(--ch-s3) var(--ch-s4); border-radius: var(--b-radius-lg); }
    .ch-grid2__body { gap: var(--ch-s2); }
    .ch-grid2__hour { font-size: .78rem; }
    .ch-grid2__event { font-size: .8rem; }
    .ch-grid2__free-label { font-size: .88rem; padding: 10px 12px; }
    .ch-grid2__pick { font-size: .92rem; }

    /* The week, when someone asks for it anyway on a wide phone held sideways,
       keeps readable columns and scrolls with its hours pinned. */
    .ch-grid2__scroll {
        overflow-x: auto;
        overflow-y: hidden;
        overscroll-behavior-x: contain;
    }

    /* One column never scrolls sideways, so it is not a scroll container at
       all: a box with overflow set grows a thin scrollbar down its edge in some
       browsers, and a line that moves nothing is a line people try to drag. */
    .ch-grid2.is-single .ch-grid2__scroll { overflow: visible; }

    .ch-grid2:not(.is-single) .ch-grid2__head,
    .ch-grid2:not(.is-single) .ch-grid2__body {
        min-width: calc(var(--b-axis) + var(--lanes) * 88px);
    }

    .ch-monthcard { padding: var(--ch-s4) var(--ch-s3); }
    .ch-monthcard__head { display: grid; }
    .ch-monthcard__close { display: flex; }
    .ch-cal__weekdays, .ch-cal__grid { gap: 4px; }
    .ch-cal__day { border-radius: 12px; min-height: 44px; }
    .ch-cal__num { font-size: 1rem; }
}

/* ==========================================================================
   Reduced motion
   ==========================================================================
   Nothing here is load bearing: every animation is a nicety over a layout that
   is already correct without it. */

@media (prefers-reduced-motion: reduce) {
    .ch-book2__schedule.is-busy::before,
    .ch-grid2__peek,
    .ch-grid2__pick,
    .ch-gridskel__row,
    .ch-done__tick,
    .ch-panel2.has-pick,
    .ch-hint__pulse::after { animation: none; }

    .ch-btn--primary:hover:not(:disabled),
    .ch-cal__day:hover:not(:disabled) { transform: none; }

    .ch-bar2__arrow,
    .ch-bar2__today,
    .ch-bar2__view,
    .ch-strip2__day,
    .ch-cal__day,
    .ch-cal__grid,
    .ch-length__btn,
    .ch-field__input { transition: none; }
}
