﻿@charset "UTF-8";
/* ############################################################################
   QLYNIC  ·  recurring-bookings.css
   PUBLIC PAGE STYLESHEET   —   ~/public/css/recurring-bookings.css
   ----------------------------------------------------------------------------
   PAGE ......... RecurringBookings.aspx   (was SmartAvailability.aspx)
   THEME ........ MERIDIAN v1
   PREFIX ....... .qrb- / --qrb-      qrb = Qlynic ReViews.
                  Shares nothing with .qab- .qac- .qbo- .qbt- .qds- .qsh-
                  .qem- .qif- .qmd- .qrx- .qrm- or the dashboard (.rv- / .q-).
                  NOTE: the DASHBOARD reviews page owns .rv- — this is .qrb-
                  for exactly that reason. Do not shorten it.

   ══ HOUSE RULE ══════════════════════════════════════════════════════════
       AlbertaClinic   · blueprint grid ..... horizontal plot-wipe
       ApiClients      · the emanation ...... the unfold
       Blackout        · the hatch .......... the draw-down
       BookingTimeline · the stipple ........ the placement
       DoctorServices  · the deck ........... the focus
       DoctorShifts    · the hours .......... the swing
       EMR             · the trace .......... the land
       IntakeForms     · the answers ........ the entry
       MultiDoctor     · the columns ........ the drop
       Prescriptions   · the blister ........ the settle
       Reminders       · the wake ........... the send
       Reviews         · the arils .......... the glitch-in
       SmallClinics    · the corridor ....... the scan
       Recurring       · the perforation .... the stamp
   ═══════════════════════════════════════════════════════════════════════
   ############################################################################ */


/* ============================================================================
   00 · TOKENS
   ============================================================================ */
.qrb {
    --qrb-font-sans: "Geist", -apple-system, "SF Pro Display", "Segoe UI Variable Display", "Segoe UI", system-ui, Roboto, Arial, sans-serif;
    --qrb-font-mono: "Geist Mono", "JetBrains Mono", ui-monospace, "SF Mono", Consolas, monospace;
    --qrb-fs-hero: clamp(2.2rem, 1.3rem + 3.5vw, 3.75rem);
    --qrb-fs-h2: clamp(1.5rem, 1.3rem + 0.95vw, 2.1rem);
    --qrb-fs-h3: clamp(1.1rem, 1.05rem + 0.3vw, 1.3rem);
    --qrb-fs-lead: clamp(1.0625rem, 1rem + 0.32vw, 1.24rem);
    --qrb-fs-body: 1.03125rem;
    --qrb-fs-sm: 0.9063rem;
    --qrb-fs-xs: 0.8125rem;
    --qrb-fs-label: 0.6875rem;
    --qrb-fs-micro: 0.5938rem;
    --qrb-track-hero: -0.042em;
    --qrb-track-label: 0.16em;
    --qrb-sp-1: 0.25rem;
    --qrb-sp-2: 0.5rem;
    --qrb-sp-3: 0.75rem;
    --qrb-sp-4: 1rem;
    --qrb-sp-5: 1.25rem;
    --qrb-sp-6: 1.5rem;
    --qrb-sp-7: 1.75rem;
    --qrb-sp-8: 2rem;
    --qrb-sp-9: 2.5rem;
    --qrb-sp-10: 3rem;
    --qrb-r-sm: 8px;
    --qrb-r-md: 12px;
    --qrb-r-lg: 16px;
    --qrb-r-xl: 22px;
    --qrb-r-pill: 999px;
    --qrb-w: 74rem;
    --qrb-w-wide: 84rem;
    --qrb-w-narrow: 46rem;
    --qrb-gutter: clamp(1.25rem, 4vw, 2.5rem);
    --qrb-bg-0: #05070D;
    --qrb-bg-1: #080B14;
    --qrb-surface-1: #0C1220;
    --qrb-surface-2: #111A2C;
    --qrb-surface-3: #16203A;
    --qrb-text: #F0F4FB;
    --qrb-text-secondary: #A9B4CB;
    --qrb-text-muted: #6C7893;
    --qrb-text-faint: #49546E;
    --qrb-rule: rgba(151, 173, 220, 0.14);
    --qrb-rule-faint: rgba(151, 173, 220, 0.08);
    --qrb-rule-strong: rgba(151, 173, 220, 0.26);
    --qrb-edge-light: rgba(216, 230, 255, 0.09);
    --qrb-azure: #4D8DFF;
    --qrb-violet: #8A7CFF;
    --qrb-signal: #2BD9EC; /* cyan — LIVE THINGS ONLY */
    --qrb-warn: #F2B94B;
    --qrb-alert: #FF5C74;
    --qrb-good: #34D399;
    --qrb-spectrum: linear-gradient(135deg, #4D8DFF 0%, #8A7CFF 100%);
    --qrb-spectrum-wide: linear-gradient(100deg, #2BD9EC -12%, #4D8DFF 38%, #8A7CFF 88%);
    --qrb-azure-tint: rgba(77, 141, 255, 0.12);
    --qrb-alert-tint: rgba(255, 92, 116, 0.12);
    --qrb-good-tint: rgba(52, 211, 153, 0.12);
    --qrb-lift: 0 1px 0 var(--qrb-edge-light) inset, 0 30px 70px -28px rgba(2, 4, 10, 0.92);
    --qrb-glow: 0 0 0 1px rgba(77, 141, 255, 0.38), 0 10px 46px -10px rgba(77, 141, 255, 0.55);
    --qrb-focus: 0 0 0 2px var(--qrb-bg-0), 0 0 0 4px var(--qrb-signal);
    --qrb-ease: cubic-bezier(0.22, 1, 0.36, 1);
    --qrb-ease-io: cubic-bezier(0.65, 0, 0.35, 1);
    --qrb-t-fast: 140ms;
    --qrb-t-med: 260ms;
    position: relative;
    background: var(--qrb-bg-0);
    color: var(--qrb-text);
    font: 400 var(--qrb-fs-body)/1.65 var(--qrb-font-sans);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
}

    .qrb *, .qrb *::before, .qrb *::after {
        box-sizing: border-box;
    }

    .qrb ::selection {
        background: rgba(77, 141, 255, 0.35);
        color: var(--qrb-text);
    }

    .qrb :focus-visible {
        outline: none;
        box-shadow: var(--qrb-focus);
        border-radius: var(--qrb-r-sm);
    }


    /* ============================================================================
   01 · PRIMITIVES
   ============================================================================ */
    .qrb .qrb-container {
        width: 100%;
        max-width: var(--qrb-w);
        margin-inline: auto;
        padding-inline: var(--qrb-gutter);
    }

    .qrb .qrb-container--wide {
        max-width: var(--qrb-w-wide);
    }

    .qrb .qrb-container--narrow {
        max-width: var(--qrb-w-narrow);
    }

    /* ── ATMOSPHERE — "the perforation" ────────────────────────────────────────
   Faint dotted tear-lines at wide intervals, like a booklet of appointment
   cards waiting to be torn off. Quiet, physical, and the only ground on the
   site built on a paper idea rather than a technical or cosmic one.

   The galaxy that used to be here was rejected for the same reason as the
   orbit above it: too busy, and it made the page harder to read rather than
   easier. A ground should be felt, not studied.
   ------------------------------------------------------------------------ */
    .qrb .qrb-field {
        position: absolute;
        inset: 0;
        overflow: hidden;
        pointer-events: none;
        z-index: 0;
    }

    .qrb .qrb-field__perf {
        position: absolute;
        inset: -6% 0;
        background-image: repeating-linear-gradient(180deg, rgba(151, 173, 220, 0.16) 0 3px, transparent 3px 9px);
        background-size: 1px 100%;
        background-repeat: repeat-y;
        background-position: 17% 0, 41% 0, 68% 0, 89% 0;
        /* Four tear-lines, drawn once and placed four times. */
        box-shadow: none;
    }

        .qrb .qrb-field__perf::before,
        .qrb .qrb-field__perf::after {
            content: "";
            position: absolute;
            inset-block: 0;
            width: 1px;
            background: repeating-linear-gradient(180deg, rgba(151, 173, 220, 0.14) 0 3px, transparent 3px 9px);
        }

        .qrb .qrb-field__perf::before {
            inset-inline-start: 41%;
        }

        .qrb .qrb-field__perf::after {
            inset-inline-start: 89%;
        }

    .qrb .qrb-field__wash {
        position: absolute;
        inset: 0;
        background: radial-gradient(ellipse 62% 52% at 26% 22%, rgba(77, 141, 255, 0.15), transparent 68%), linear-gradient(122deg, transparent 42%, rgba(138, 124, 255, 0.09) 100%);
    }
    /* A single slow pass, like a page settling. Nothing repeats fast enough to
   be noticed while reading. */
    .qrb .qrb-field__wash {
        animation: qrb-settle 120s ease-in-out infinite;
    }

@keyframes qrb-settle {
    0%, 100% {
        transform: translate3d(0, 0, 0);
        opacity: 0.92;
    }

    50% {
        transform: translate3d(0, -1.5%, 0);
        opacity: 1;
    }
}

/* ── Type ───────────────────────────────────────────────────────────────── */
.qrb .qrb-hero-title {
    margin: 0;
    font: 600 var(--qrb-fs-hero)/1.04 var(--qrb-font-sans);
    letter-spacing: var(--qrb-track-hero);
    text-wrap: balance;
    color: var(--qrb-text);
}

.qrb .qrb-h2 {
    margin: 0;
    font: 600 var(--qrb-fs-h2)/1.15 var(--qrb-font-sans);
    letter-spacing: -0.022em;
    text-wrap: balance;
}

.qrb .qrb-lead {
    margin: 0;
    font-size: var(--qrb-fs-lead);
    line-height: 1.58;
    color: var(--qrb-text-secondary);
    text-wrap: pretty;
}

.qrb .qrb-em {
    background: var(--qrb-spectrum-wide);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
}

.qrb .qrb-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: var(--qrb-sp-3);
    margin: 0;
    font: 500 var(--qrb-fs-label)/1 var(--qrb-font-mono);
    letter-spacing: var(--qrb-track-label);
    text-transform: uppercase;
    color: var(--qrb-text-muted);
}

    .qrb .qrb-eyebrow::before {
        content: "";
        width: 1.25rem;
        height: 1px;
        background: var(--qrb-azure);
        flex: none;
    }

/* ── Buttons ────────────────────────────────────────────────────────────── */
.qrb .qrb-btn {
    -webkit-appearance: none;
    appearance: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--qrb-sp-2);
    padding: 0.82rem 1.5rem;
    border-radius: 14px;
    border: 1px solid transparent;
    font: 500 var(--qrb-fs-sm)/1 var(--qrb-font-sans);
    text-decoration: none;
    cursor: pointer;
    white-space: nowrap;
    transition: background var(--qrb-t-fast) var(--qrb-ease), border-color var(--qrb-t-fast) var(--qrb-ease), box-shadow var(--qrb-t-med) var(--qrb-ease), transform var(--qrb-t-fast) var(--qrb-ease);
}

    .qrb .qrb-btn:active {
        transform: translateY(1px);
    }

.qrb .qrb-btn--primary {
    background: var(--qrb-spectrum);
    color: #FFFFFF;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22);
}

    .qrb .qrb-btn--primary:hover {
        box-shadow: inset 0 1px 0 rgba(255,255,255,0.22), var(--qrb-glow);
    }

.qrb .qrb-btn--secondary {
    background: rgba(151, 173, 220, 0.07);
    border-color: var(--qrb-rule);
    color: var(--qrb-text);
    box-shadow: inset 0 1px 0 var(--qrb-edge-light);
}

    .qrb .qrb-btn--secondary:hover {
        border-color: var(--qrb-rule-strong);
        background: rgba(151, 173, 220, 0.12);
    }

.qrb .qrb-ico {
    width: 18px;
    height: 18px;
    flex: none;
    stroke-width: 1.5;
}

.qrb .qrb-ico--sm {
    width: 15px;
    height: 15px;
}

.qrb .qrb-btn .qrb-ico {
    width: 16px;
    height: 16px;
    transition: transform var(--qrb-t-fast) var(--qrb-ease);
}

.qrb .qrb-btn:hover .qrb-ico {
    transform: translateX(3px);
}

.qrb .qrb-sr {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* ── THE REVEAL — "the stamp"  (fail-open) ─────────────────────────────────
   THIS PAGE'S SIGNATURE.

   Elements arrive from slightly ABOVE and slightly OVERSIZED, then press down
   and settle. A short drop, a firm landing, no bounce and no rotation.

   Nothing else on the site moves DOWNWARD into place — MultiDoctor's drop is
   a 14px translate with no scale and no pressure. And for a page about
   appointments being committed or not, a stamp is the right gesture: the
   thing either lands or it does not.

   Eased, not stepped. Reviews and SmallClinics own the stepped snap.
   ------------------------------------------------------------------------ */
.qrb-js [data-qrb-reveal] {
    opacity: 0;
    transform: translate3d(0, -14px, 0) scale(1.035);
    will-change: opacity, transform;
    transition: opacity 380ms var(--qrb-ease) var(--qrb-rvd, 0ms), transform 620ms cubic-bezier(0.16, 0.9, 0.28, 1) var(--qrb-rvd, 0ms);
}

    .qrb-js [data-qrb-reveal].is-in {
        opacity: 1;
        transform: none;
    }

    .qrb-js [data-qrb-reveal].is-done {
        will-change: auto;
    }

@media (prefers-reduced-motion: reduce) {
    .qrb [data-qrb-reveal],
    .qrb [data-qrb-reveal].is-in {
        opacity: 1;
        transform: none;
        transition: none;
    }

    .qrb .qrb-field__wash {
        animation: none;
    }

    .qrb-js [data-qrb-reveal].is-in {
        animation: none;
        opacity: 1;
    }

    .qrb *, .qrb *::before, .qrb *::after {
        animation-duration: 0.001s !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001s !important;
    }
}










/* ############################################################################
   SECTION 01 · TWELVE TUESDAYS. TWO RIGHT ANSWERS.
   ----------------------------------------------------------------------------
   ══ THE ARGUMENT ══════════════════════════════════════════════════════════
   From the phone-booking path in the codebase:

      ' ALL-OR-NOTHING: every occurrence is validated with the same
      ' ValidateSlot engine first; if any fails, NOTHING is written and the
      ' failing sessions are named. (Book's online flow silently skips bad
      ' occurrences - fine for self-serve, wrong for a staffed phone call
      ' where the admin can just adjust.)

   Same feature, two behaviours, chosen on who is holding the mouse.

   ██ WHY THIS IS A CARD AND NOT A DIAGRAM ██████████████████████████████████
   The first build drew twelve points on an orbit. It was a picture of a
   SERIES when the reader wanted a picture of A DATE THAT DOES NOT FIT — and
   it never showed a single date. House rule 8, which this project wrote for
   itself: the graphic shows the actual thing, and if it needs a caption it
   is the wrong graphic. The orbit needed one.

   A twelve-session course already has a physical object in the world: the
   card a physio hands you with twelve boxes on it. Everyone who would buy
   this software has held one. So every date is printed and readable, and
   there is nothing to decode.
   ███████████████████████████████████████████████████████████████████████████

   ACCENT BUDGET (Law 2)
     Azure on a booked box. Amber on a date that cannot happen. One green
     stamp when the series is written, one amber when it is not. Nothing else.
   ############################################################################ */

.qrb .qrb-s1 {
    position: relative;
    overflow: clip;
    display: grid;
    align-items: center;
    min-height: clamp(36rem, 82svh, 50rem);
    padding-block: clamp(3rem, 7vw, 5rem);
    border-block-end: 1px solid var(--qrb-rule-faint);
}

.qrb .qrb-s1__inner {
    position: relative;
    z-index: 1;
    width: 100%;
}

.qrb .qrb-s1__grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 31rem);
    gap: clamp(2rem, 5vw, 4.5rem);
    align-items: center;
}

/* ── LEFT · the two answers ─────────────────────────────────────────────── */
.qrb .qrb-s1__copy {
    display: grid;
    gap: var(--qrb-sp-5);
    align-content: center;
    justify-items: start;
    max-width: 34rem;
}

.qrb .qrb-s1__title {
    max-width: 11em;
    font-size: clamp(2.4rem, 1.4rem + 4.1vw, 4.3rem);
    line-height: 0.99;
    letter-spacing: -0.046em;
}

.qrb .qrb-s1__lead {
    max-width: 34em;
}

.qrb .qrb-s1__switch {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--qrb-sp-2);
    width: 100%;
    max-width: 30rem;
}

.qrb .qrb-s1__opt {
    -webkit-appearance: none;
    appearance: none;
    display: grid;
    gap: 2px;
    justify-items: start;
    text-align: start;
    padding: var(--qrb-sp-3);
    border-radius: var(--qrb-r-md);
    border: 1px solid var(--qrb-rule-faint);
    background: rgba(3, 5, 10, 0.42);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: border-color 380ms var(--qrb-ease), background 380ms var(--qrb-ease);
}

    .qrb .qrb-s1__opt b {
        font: 600 var(--qrb-fs-sm)/1.2 var(--qrb-font-sans);
        letter-spacing: -0.014em;
        color: var(--qrb-text-secondary);
        transition: color 380ms var(--qrb-ease);
    }

    .qrb .qrb-s1__opt em {
        font: 400 var(--qrb-fs-micro)/1.4 var(--qrb-font-mono);
        font-style: normal;
        letter-spacing: 0.04em;
        color: var(--qrb-text-faint);
    }

    .qrb .qrb-s1__opt.is-on {
        border-color: rgba(77, 141, 255, 0.45);
        background: rgba(77, 141, 255, 0.09);
    }

        .qrb .qrb-s1__opt.is-on b {
            color: var(--qrb-text);
        }

.qrb .qrb-s1__verdict {
    max-width: 34em;
    margin: 0;
    padding-inline-start: var(--qrb-sp-5);
    border-inline-start: 2px solid var(--qrb-azure);
    font-size: var(--qrb-fs-sm);
    line-height: 1.65;
    color: var(--qrb-text-muted);
    text-wrap: pretty;
}

    .qrb .qrb-s1__verdict b {
        display: block;
        font-weight: 600;
        font-size: var(--qrb-fs-body);
        letter-spacing: -0.014em;
        color: var(--qrb-text);
    }

.qrb .qrb-s1__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--qrb-sp-3);
}


/* ============================================================================
   S01.2 · THE CARD
   ============================================================================ */
.qrb .qrb-s1__stagewrap {
    display: grid;
    gap: var(--qrb-sp-3);
    justify-items: center;
}

.qrb .qrb-s1__card {
    width: 100%;
    max-width: 31rem;
    display: grid;
    gap: var(--qrb-sp-4);
    padding: clamp(var(--qrb-sp-4), 2.4vw, var(--qrb-sp-6));
    border: 1px solid var(--qrb-rule);
    border-radius: var(--qrb-r-lg);
    background: var(--qrb-surface-1);
    box-shadow: 0 40px 80px -40px rgba(2, 4, 10, 0.95), inset 0 1px 0 var(--qrb-edge-light);
}

.qrb .qrb-s1__card-h {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--qrb-sp-3);
    padding-block-end: var(--qrb-sp-3);
    border-block-end: 1px solid var(--qrb-rule);
}

.qrb .qrb-s1__course {
    display: grid;
    gap: 3px;
    min-width: 0;
}

    .qrb .qrb-s1__course b {
        font: 600 var(--qrb-fs-sm)/1.2 var(--qrb-font-sans);
        letter-spacing: -0.014em;
        color: var(--qrb-text);
    }

    .qrb .qrb-s1__course em {
        font: 400 var(--qrb-fs-micro)/1.4 var(--qrb-font-mono);
        font-style: normal;
        letter-spacing: 0.06em;
        color: var(--qrb-text-faint);
    }

.qrb .qrb-s1__of {
    font: 600 var(--qrb-fs-lead)/1 var(--qrb-font-mono);
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.03em;
    color: var(--qrb-text-faint);
}

/* ── THE TWELVE BOXES · every date printed ──────────────────────────────── */
.qrb .qrb-s1__boxes {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--qrb-sp-2);
    margin: 0;
    padding: 0;
    list-style: none;
}

.qrb .qrb-s1__box {
    position: relative;
    display: grid;
    gap: 1px;
    padding: var(--qrb-sp-3) var(--qrb-sp-2);
    border-radius: var(--qrb-r-sm);
    border: 1px solid var(--qrb-rule-faint);
    background: rgba(3, 5, 10, 0.45);
    text-align: center;
    transition: opacity 420ms var(--qrb-ease) calc(var(--i) * 26ms), border-color 420ms var(--qrb-ease), background 420ms var(--qrb-ease);
}

.qrb .qrb-s1__no {
    font: 500 var(--qrb-fs-micro)/1 var(--qrb-font-mono);
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.1em;
    color: var(--qrb-text-faint);
}

.qrb .qrb-s1__date {
    font: 600 var(--qrb-fs-sm)/1.25 var(--qrb-font-sans);
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.014em;
    color: var(--qrb-text);
}

.qrb .qrb-s1__why {
    font: 400 var(--qrb-fs-micro)/1.3 var(--qrb-font-mono);
    letter-spacing: 0.04em;
    color: var(--qrb-text-faint);
}

/* A booked one. */
.qrb .qrb-s1__card[data-mode="online"] .qrb-s1__box {
    border-color: rgba(77, 141, 255, 0.34);
    background: rgba(77, 141, 255, 0.07);
}
    /* A date that cannot happen. Struck through, in both modes. */
    .qrb .qrb-s1__box.is-bad,
    .qrb .qrb-s1__card[data-mode="online"] .qrb-s1__box.is-bad {
        border-color: rgba(242, 185, 75, 0.42);
        background: rgba(242, 185, 75, 0.08);
    }

        .qrb .qrb-s1__box.is-bad .qrb-s1__date {
            color: var(--qrb-warn);
            text-decoration: line-through;
            text-decoration-thickness: 1px;
            text-underline-offset: 2px;
        }

        .qrb .qrb-s1__box.is-bad .qrb-s1__why {
            color: var(--qrb-warn);
        }

/* Nothing was written, so nothing is marked as booked. */
.qrb .qrb-s1__card[data-mode="desk"] .qrb-s1__box {
    border-color: var(--qrb-rule-faint);
    background: rgba(3, 5, 10, 0.45);
    opacity: 0.4;
}

    .qrb .qrb-s1__card[data-mode="desk"] .qrb-s1__box.is-bad {
        opacity: 1;
        border-color: rgba(242, 185, 75, 0.6);
        background: rgba(242, 185, 75, 0.12);
    }

/* ── The foot ───────────────────────────────────────────────────────────── */
.qrb .qrb-s1__card-f {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--qrb-sp-2) var(--qrb-sp-5);
    padding-block-start: var(--qrb-sp-3);
    border-block-start: 1px solid var(--qrb-rule);
}

.qrb .qrb-s1__tally {
    display: inline-flex;
    align-items: baseline;
    gap: var(--qrb-sp-2);
    font: 400 var(--qrb-fs-xs)/1 var(--qrb-font-mono);
    letter-spacing: 0.04em;
    color: var(--qrb-text-muted);
}

    .qrb .qrb-s1__tally b {
        font-weight: 600;
        font-size: var(--qrb-fs-h3);
        font-variant-numeric: tabular-nums;
        letter-spacing: -0.03em;
        color: var(--qrb-azure);
        transition: color 420ms var(--qrb-ease);
    }

.qrb .qrb-s1__tally--bad b {
    color: var(--qrb-warn);
}

.qrb .qrb-s1__card[data-mode="desk"] .qrb-s1__tally b {
    color: var(--qrb-text-faint);
}

.qrb .qrb-s1__card[data-mode="desk"] .qrb-s1__tally--bad b {
    color: var(--qrb-warn);
}

/* The stamp. Rotated a degree and a half, because a stamp never lands square. */
.qrb .qrb-s1__stampmark {
    margin-inline-start: auto;
    padding: 0.24rem 0.7rem;
    border: 2px solid rgba(52, 211, 153, 0.55);
    border-radius: var(--qrb-r-sm);
    font: 700 var(--qrb-fs-xs)/1.3 var(--qrb-font-mono);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--qrb-good);
    transform: rotate(-1.5deg);
    transition: color 420ms var(--qrb-ease), border-color 420ms var(--qrb-ease);
}

.qrb .qrb-s1__card[data-mode="desk"] .qrb-s1__stampmark {
    border-color: rgba(242, 185, 75, 0.6);
    color: var(--qrb-warn);
}

.qrb .qrb-s1__cap {
    margin: 0;
    text-align: center;
    font: 400 var(--qrb-fs-micro)/1.5 var(--qrb-font-mono);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--qrb-text-faint);
}


/* ============================================================================
   S01 · RESPONSIVE
   The boxes go three across, then two. Never one: a single column of twelve
   stops looking like a card and starts looking like a list, and the whole
   point is that you can see all twelve at once.
   ============================================================================ */
@media (max-width: 68rem) {
    .qrb .qrb-s1 {
        min-height: clamp(32rem, 72svh, 44rem);
    }

    .qrb .qrb-s1__grid {
        grid-template-columns: minmax(0, 1fr);
        gap: clamp(2rem, 6vw, 3rem);
    }

    .qrb .qrb-s1__copy {
        max-width: 42rem;
    }

    .qrb .qrb-s1__stagewrap {
        justify-items: start;
    }
}

@media (max-width: 40rem) {
    .qrb .qrb-s1 {
        min-height: 0;
        padding-block: clamp(2.25rem, 8vw, 3.25rem);
    }

    .qrb .qrb-s1__title {
        max-width: 13em;
    }

    .qrb .qrb-s1__switch {
        grid-template-columns: minmax(0, 1fr);
    }

    .qrb .qrb-s1__actions {
        width: 100%;
    }

        .qrb .qrb-s1__actions .qrb-btn {
            flex: 1 1 100%;
        }

    .qrb .qrb-s1__verdict {
        padding-inline-start: var(--qrb-sp-4);
    }

    .qrb .qrb-s1__card {
        max-width: 100%;
        padding: var(--qrb-sp-4);
    }

    .qrb .qrb-s1__boxes {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .qrb .qrb-s1__stampmark {
        margin-inline-start: 0;
    }
}

/* Reduced motion: the card holds the online state, every date readable. */
@media (prefers-reduced-motion: reduce) {
    .qrb .qrb-s1__box,
    .qrb .qrb-s1__tally b,
    .qrb .qrb-s1__stampmark,
    .qrb .qrb-s1__opt {
        transition: none;
    }
}

/* ############################################################################
   END OF SECTION 01 — append SECTION 02 below this line.
   ############################################################################ */








































/* ############################################################################
   SECTION 02 · NOBODY CAN SIT ON YOUR 10:15.
   ----------------------------------------------------------------------------
   Append to ~/public/css/recurring-bookings.css, directly under SECTION 01.

   ██ THIRTY WAS NOT PICKED. IT WAS SOLVED FOR. █████████████████████████████
        8 + 0x5 =  8   fits
        8 + 4x5 = 28   fits
        8 + 5x5 = 33   over the ceiling
   Four asks fit under it and a fifth cannot. The 2 minutes left over are the
   evidence that somebody worked the number out rather than typing a round
   one — so the track SHOWS them, as a visibly empty tail, instead of the
   copy claiming it.
   ███████████████████████████████████████████████████████████████████████████

   ══ THE TRACK IS COMPUTED IN THE TEMPLATE ═════════════════════════════════
   Every segment width comes from the three constants at the top of the
   markup. Change the hold, the extension or the ceiling and the whole thing
   redraws — including how many extensions exist, since that is an integer
   division rather than a typed 4.

   ══ SAME REGISTER AS THE CARD ═════════════════════════════════════════════
   Literal and printed: minutes are written on the segments, the ruler is
   marked at 0, 8, 28 and 30. Nothing here is a metaphor for time; it is a
   measurement of it.

   ACCENT BUDGET (Law 2)
     Azure on the opening eight minutes — the part the patient is given.
     Violet on each extension, so asking looks different from being given.
     Amber once, on the refusal. The headroom is empty ink, which is the
     whole point of it.
   ############################################################################ */

.qrb .qrb-s2 {
    position: relative;
    overflow: clip;
    padding-block: clamp(3.25rem, 8vw, 6rem);
    background: var(--qrb-bg-1);
    border-block-end: 1px solid var(--qrb-rule-faint);
}

.qrb .qrb-s2__inner {
    position: relative;
    z-index: 1;
}

.qrb .qrb-s2__head {
    display: grid;
    gap: var(--qrb-sp-4);
    justify-items: start;
    max-width: 46rem;
    margin-block-end: clamp(2rem, 4.5vw, 3rem);
}

.qrb .qrb-s2__title {
    max-width: 13em;
}

.qrb .qrb-s2__sub {
    max-width: 42em;
}


/* ============================================================================
   S02.1 · THE TRACK
   ============================================================================ */
.qrb .qrb-s2__bench {
    display: grid;
    gap: var(--qrb-sp-5);
    max-width: 54rem;
    padding: clamp(var(--qrb-sp-4), 3vw, var(--qrb-sp-6));
    border: 1px solid var(--qrb-rule);
    border-radius: var(--qrb-r-lg);
    background: var(--qrb-surface-1);
    box-shadow: inset 0 1px 0 var(--qrb-edge-light);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

.qrb .qrb-s2__bar {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--qrb-sp-3);
    flex-wrap: wrap;
}

.qrb .qrb-s2__lbl {
    font: 400 var(--qrb-fs-micro)/1 var(--qrb-font-mono);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--qrb-text-faint);
}

.qrb .qrb-s2__now {
    font: 400 var(--qrb-fs-xs)/1 var(--qrb-font-mono);
    color: var(--qrb-text-muted);
}

    .qrb .qrb-s2__now b {
        font-weight: 600;
        font-size: var(--qrb-fs-h3);
        font-variant-numeric: tabular-nums;
        letter-spacing: -0.03em;
        color: var(--qrb-azure);
        transition: color 380ms var(--qrb-ease);
    }
/* The slot went back, so there are no minutes left to show. */
.qrb .qrb-s2__bench[data-step="5"] .qrb-s2__now b {
    color: var(--qrb-warn);
}

.qrb .qrb-s2__trackwrap {
    display: grid;
    gap: var(--qrb-sp-2);
}

.qrb .qrb-s2__track {
    display: flex;
    gap: 2px;
    height: 2.6rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.qrb .qrb-s2__seg,
.qrb .qrb-s2__head-room {
    display: grid;
    place-content: center;
    width: var(--w);
    flex: none;
    border-radius: 3px;
    transition: opacity 420ms var(--qrb-ease), background 420ms var(--qrb-ease), box-shadow 420ms var(--qrb-ease);
}

/* Not yet asked for. */
.qrb .qrb-s2__seg {
    background: rgba(3, 5, 10, 0.5);
    box-shadow: inset 0 0 0 1px var(--qrb-rule-faint);
    opacity: 0.34;
}
    /* The eight minutes the patient is simply given. */
    .qrb .qrb-s2__seg.is-first {
        opacity: 1;
        background: linear-gradient(180deg, rgba(77, 141, 255, 0.34), rgba(77, 141, 255, 0.18));
        box-shadow: inset 0 0 0 1px rgba(77, 141, 255, 0.5);
    }
/* Each extension lights as it is asked for. Asking looks different from
   being given, which is why these are violet and the first one is azure. */
.qrb .qrb-s2__bench[data-step="1"] .qrb-s2__seg:nth-child(-n+2),
.qrb .qrb-s2__bench[data-step="2"] .qrb-s2__seg:nth-child(-n+3),
.qrb .qrb-s2__bench[data-step="3"] .qrb-s2__seg:nth-child(-n+4),
.qrb .qrb-s2__bench[data-step="4"] .qrb-s2__seg:nth-child(-n+5),
.qrb .qrb-s2__bench[data-step="5"] .qrb-s2__seg:nth-child(-n+5) {
    opacity: 1;
    background: linear-gradient(180deg, rgba(138, 124, 255, 0.32), rgba(138, 124, 255, 0.16));
    box-shadow: inset 0 0 0 1px rgba(138, 124, 255, 0.48);
}
/* except the first, which is always the given eight */
.qrb .qrb-s2__bench .qrb-s2__seg.is-first {
    background: linear-gradient(180deg, rgba(77, 141, 255, 0.34), rgba(77, 141, 255, 0.18));
    box-shadow: inset 0 0 0 1px rgba(77, 141, 255, 0.5);
}
/* The slot went back. */
.qrb .qrb-s2__bench[data-step="5"] .qrb-s2__seg {
    opacity: 0.28;
}

    .qrb .qrb-s2__bench[data-step="5"] .qrb-s2__seg.is-first {
        opacity: 0.28;
    }

.qrb .qrb-s2__len {
    font: 500 var(--qrb-fs-micro)/1 var(--qrb-font-mono);
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.04em;
    color: var(--qrb-text-secondary);
}

/* THE HEADROOM. It stays empty, and that emptiness is the argument. */
.qrb .qrb-s2__head-room {
    background: repeating-linear-gradient(45deg, rgba(151, 173, 220, 0.09) 0 1px, transparent 1px 6px);
    box-shadow: inset 0 0 0 1px var(--qrb-rule-faint);
}

    .qrb .qrb-s2__head-room .qrb-s2__len {
        color: var(--qrb-text-faint);
    }
/* A fifth ask would have needed more than this. */
.qrb .qrb-s2__bench[data-step="5"] .qrb-s2__head-room {
    background: repeating-linear-gradient(45deg, rgba(242, 185, 75, 0.26) 0 1px, transparent 1px 6px);
    box-shadow: inset 0 0 0 1px rgba(242, 185, 75, 0.5);
}

.qrb .qrb-s2__ruler {
    position: relative;
    height: 0.9rem;
}

    .qrb .qrb-s2__ruler span {
        position: absolute;
        inset-inline-start: var(--x);
        transform: translateX(-50%);
        font: 400 var(--qrb-fs-micro)/1 var(--qrb-font-mono);
        font-variant-numeric: tabular-nums;
        color: var(--qrb-text-faint);
    }

        .qrb .qrb-s2__ruler span:first-child {
            transform: none;
        }

        .qrb .qrb-s2__ruler span:last-child {
            transform: translateX(-100%);
        }

/* ── The asks ───────────────────────────────────────────────────────────── */
.qrb .qrb-s2__asks {
    display: flex;
    align-items: center;
    gap: var(--qrb-sp-3);
    flex-wrap: wrap;
    padding-block-start: var(--qrb-sp-4);
    border-block-start: 1px solid var(--qrb-rule-faint);
}

.qrb .qrb-s2__ask-l {
    padding: 0.34rem 0.7rem;
    border-radius: var(--qrb-r-sm);
    border: 1px solid var(--qrb-rule);
    background: rgba(151, 173, 220, 0.06);
    font: 500 var(--qrb-fs-xs)/1 var(--qrb-font-sans);
    color: var(--qrb-text-secondary);
    transition: opacity 380ms var(--qrb-ease), color 380ms var(--qrb-ease);
}
/* The button is gone once the ceiling is reached. */
.qrb .qrb-s2__bench[data-step="5"] .qrb-s2__ask-l {
    opacity: 0.34;
    color: var(--qrb-text-faint);
}

.qrb .qrb-s2__pips {
    display: flex;
    gap: 5px;
}

    .qrb .qrb-s2__pips i {
        width: 9px;
        height: 9px;
        border-radius: 50%;
        background: rgba(151, 173, 220, 0.16);
        box-shadow: inset 0 0 0 1px var(--qrb-rule-faint);
        transition: background 380ms var(--qrb-ease) calc(var(--p) * 50ms);
    }

.qrb .qrb-s2__bench[data-step="1"] .qrb-s2__pips i:nth-child(-n+1),
.qrb .qrb-s2__bench[data-step="2"] .qrb-s2__pips i:nth-child(-n+2),
.qrb .qrb-s2__bench[data-step="3"] .qrb-s2__pips i:nth-child(-n+3),
.qrb .qrb-s2__bench[data-step="4"] .qrb-s2__pips i:nth-child(-n+4),
.qrb .qrb-s2__bench[data-step="5"] .qrb-s2__pips i {
    background: var(--qrb-violet);
}

.qrb .qrb-s2__ask-n {
    margin-inline-start: auto;
    font: 400 var(--qrb-fs-xs)/1 var(--qrb-font-mono);
    color: var(--qrb-text-muted);
}

    .qrb .qrb-s2__ask-n b {
        font-weight: 600;
        font-variant-numeric: tabular-nums;
        color: var(--qrb-text);
    }

.qrb .qrb-s2__say {
    margin: 0;
    min-height: 2.6em;
    font-size: var(--qrb-fs-sm);
    line-height: 1.6;
    color: var(--qrb-text-muted);
    text-wrap: pretty;
    transition: color 380ms var(--qrb-ease);
}

.qrb .qrb-s2__bench[data-step="5"] .qrb-s2__say {
    color: var(--qrb-warn);
}


/* ============================================================================
   S02.2 · THREE THINGS UNDERNEATH
   ============================================================================ */
.qrb .qrb-s2__notes {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: clamp(1.5rem, 3vw, 2.5rem);
    margin: clamp(2.25rem, 5vw, 3.25rem) 0 0;
    padding: 0;
    list-style: none;
}

.qrb .qrb-s2__n {
    display: grid;
    gap: var(--qrb-sp-2);
    align-content: start;
    padding-block-start: var(--qrb-sp-5);
    border-block-start: 1px solid var(--qrb-rule-strong);
}

.qrb .qrb-s2__n-t {
    margin: 0;
    font: 600 var(--qrb-fs-h3)/1.3 var(--qrb-font-sans);
    letter-spacing: -0.016em;
    color: var(--qrb-text);
}

.qrb .qrb-s2__n-b {
    margin: 0;
    font-size: var(--qrb-fs-sm);
    line-height: 1.65;
    color: var(--qrb-text-muted);
    text-wrap: pretty;
}


/* ============================================================================
   S02 · RESPONSIVE
   The track never wraps and never stacks. It is one continuous half hour, and
   a half hour broken across two lines is not one.
   ============================================================================ */
@media (max-width: 68rem) {
    .qrb .qrb-s2__notes {
        grid-template-columns: minmax(0, 1fr);
        gap: 0;
    }

    .qrb .qrb-s2__n {
        padding-block: var(--qrb-sp-5);
    }

        .qrb .qrb-s2__n + .qrb-s2__n {
            border-block-start-color: var(--qrb-rule);
        }
}

@media (max-width: 40rem) {
    .qrb .qrb-s2 {
        padding-block: clamp(2.5rem, 9vw, 3.5rem);
    }

    .qrb .qrb-s2__title {
        max-width: 15em;
    }

    .qrb .qrb-s2__bench {
        padding: var(--qrb-sp-4);
    }

    .qrb .qrb-s2__track {
        height: 2.1rem;
    }
    /* Five numbers inside 2.1rem of segments is a smudge. The ruler still
       carries 0, 8, 28 and 30, which is what the section needs read. */
    .qrb .qrb-s2__seg .qrb-s2__len {
        display: none;
    }

    .qrb .qrb-s2__ask-n {
        margin-inline-start: 0;
        width: 100%;
    }
}

/* Reduced motion: the bench holds the opening eight minutes. */
@media (prefers-reduced-motion: reduce) {
    .qrb .qrb-s2__seg,
    .qrb .qrb-s2__head-room,
    .qrb .qrb-s2__pips i,
    .qrb .qrb-s2__ask-l,
    .qrb .qrb-s2__now b,
    .qrb .qrb-s2__say {
        transition: none;
    }
}

/* ############################################################################
   END OF SECTION 02 — append SECTION 03 below this line.
   ############################################################################ */























/* ############################################################################
   SECTION 03 · THERE IS NO SECOND SYSTEM.
   ----------------------------------------------------------------------------
   Append to ~/public/css/recurring-bookings.css, directly under SECTION 02.

   ══ THE DEVICE — TWO COLUMNS THAT ARE IDENTICAL ═══════════════════════════
   Five checks, ticking down both columns at once. Every row matches.

   Two identical columns sounds like a dull picture, and that IS the picture.
   Sameness is the whole argument, so the graphic should be boring in exactly
   that way. If a later edit adds a difference between the columns to make it
   "more interesting", the section stops being true.

   ██ NOTHING IN THIS FILE STYLES ONE SIDE DIFFERENTLY FROM THE OTHER. ██████
   [data-side] exists on the markup for readability, and no rule reads it.
   That is deliberate: the CSS cannot make them diverge because it does not
   know which is which.
   ███████████████████████████████████████████████████████████████████████████

   ══ THE FIFTH ROW ═════════════════════════════════════════════════════════
   Her own booking is taken OUT of the clash check. Without it, moving from
   10:15 to 10:30 would collide with the appointment she is trying to move,
   and the software would look broken while behaving correctly. It is styled
   as an exclusion rather than a pass, because it is one.

   ACCENT BUDGET (Law 2)
     Azure on a check that has run. Violet once, on the exclusion, because it
     is a different kind of outcome. Nothing else.
   ############################################################################ */

.qrb .qrb-s3 {
    position: relative;
    overflow: clip;
    padding-block: clamp(3.25rem, 8vw, 6rem);
    border-block-end: 1px solid var(--qrb-rule-faint);
}

.qrb .qrb-s3__inner {
    position: relative;
    z-index: 1;
}

.qrb .qrb-s3__grid {
    display: grid;
    grid-template-columns: minmax(0, 30rem) minmax(0, 1fr);
    gap: clamp(2rem, 5vw, 4.5rem);
    align-items: center;
}


/* ============================================================================
   S03.1 · THE TWO COLUMNS
   ============================================================================ */
.qrb .qrb-s3__stagewrap {
    display: grid;
    gap: var(--qrb-sp-3);
    justify-items: center;
}

.qrb .qrb-s3__panel {
    width: 100%;
    max-width: 30rem;
    display: grid;
    gap: var(--qrb-sp-4);
    padding: clamp(var(--qrb-sp-4), 2.4vw, var(--qrb-sp-6));
    border: 1px solid var(--qrb-rule);
    border-radius: var(--qrb-r-lg);
    background: var(--qrb-surface-1);
    box-shadow: 0 40px 80px -40px rgba(2, 4, 10, 0.95), inset 0 1px 0 var(--qrb-edge-light);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

/* One grid, shared by the header, every row and the footer, so the two
   columns cannot fall out of alignment. */
.qrb .qrb-s3__cols,
.qrb .qrb-s3__row,
.qrb .qrb-s3__out {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 4.6rem 4.6rem;
    align-items: center;
    gap: var(--qrb-sp-2);
}

.qrb .qrb-s3__cols {
    padding-block-end: var(--qrb-sp-3);
    border-block-end: 1px solid var(--qrb-rule);
}

.qrb .qrb-s3__col-l {
    font: 400 var(--qrb-fs-micro)/1 var(--qrb-font-mono);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--qrb-text-faint);
}

.qrb .qrb-s3__col-h {
    font: 600 var(--qrb-fs-micro)/1.3 var(--qrb-font-mono);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    text-align: center;
    color: var(--qrb-text-secondary);
}

.qrb .qrb-s3__rows {
    display: grid;
    gap: 0;
    margin: 0;
    padding: 0;
    list-style: none;
}

.qrb .qrb-s3__row {
    padding-block: var(--qrb-sp-3);
    border-block-end: 1px solid var(--qrb-rule-faint);
}

    .qrb .qrb-s3__row:last-child {
        border-block-end: 0;
    }

.qrb .qrb-s3__what {
    font-size: var(--qrb-fs-xs);
    line-height: 1.4;
    color: var(--qrb-text-secondary);
}

/* THE CELL. There is no rule anywhere in this file that reads [data-side],
   so the two columns are styled by the same declarations and cannot diverge. */
.qrb .qrb-s3__cell {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    font: 400 var(--qrb-fs-micro)/1.3 var(--qrb-font-mono);
    letter-spacing: 0.04em;
    color: var(--qrb-text-faint);
    opacity: 0;
    transform: translate3d(0, -4px, 0);
    transition: opacity 340ms var(--qrb-ease), transform 460ms var(--qrb-ease), color 340ms var(--qrb-ease);
}

    .qrb .qrb-s3__cell i {
        width: 7px;
        height: 7px;
        border-radius: 50%;
        background: currentColor;
        flex: none;
    }

/* Both columns of a row appear on the same step. One selector, two cells. */
.qrb .qrb-s3__panel[data-step="1"] .qrb-s3__row:nth-child(-n+1) .qrb-s3__cell,
.qrb .qrb-s3__panel[data-step="2"] .qrb-s3__row:nth-child(-n+2) .qrb-s3__cell,
.qrb .qrb-s3__panel[data-step="3"] .qrb-s3__row:nth-child(-n+3) .qrb-s3__cell,
.qrb .qrb-s3__panel[data-step="4"] .qrb-s3__row:nth-child(-n+4) .qrb-s3__cell,
.qrb .qrb-s3__panel[data-step="5"] .qrb-s3__row .qrb-s3__cell,
.qrb .qrb-s3__panel[data-step="6"] .qrb-s3__row .qrb-s3__cell {
    opacity: 1;
    transform: none;
    color: var(--qrb-azure);
}
/* The exclusion is a different kind of outcome, so it gets a different
   colour and keeps it. */
.qrb .qrb-s3__row.is-out .qrb-s3__what {
    color: var(--qrb-text-muted);
}

.qrb .qrb-s3__panel[data-step="5"] .qrb-s3__row.is-out .qrb-s3__cell,
.qrb .qrb-s3__panel[data-step="6"] .qrb-s3__row.is-out .qrb-s3__cell {
    color: var(--qrb-violet);
}

/* ── What both doors are offered ────────────────────────────────────────── */
.qrb .qrb-s3__out {
    padding-block-start: var(--qrb-sp-3);
    border-block-start: 1px solid var(--qrb-rule);
    opacity: 0;
    transform: translate3d(0, -5px, 0);
    transition: opacity 420ms var(--qrb-ease), transform 560ms var(--qrb-ease);
}

.qrb .qrb-s3__panel[data-step="6"] .qrb-s3__out {
    opacity: 1;
    transform: none;
}

.qrb .qrb-s3__out-l {
    font: 400 var(--qrb-fs-micro)/1 var(--qrb-font-mono);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--qrb-text-faint);
}

.qrb .qrb-s3__out-v {
    grid-column: span 1;
    font: 500 var(--qrb-fs-micro)/1.35 var(--qrb-font-mono);
    font-variant-numeric: tabular-nums;
    text-align: center;
    color: var(--qrb-azure);
}

.qrb .qrb-s3__say {
    margin: 0;
    font-size: var(--qrb-fs-sm);
    line-height: 1.6;
    color: var(--qrb-text-muted);
    opacity: 0;
    transition: opacity 420ms var(--qrb-ease) 160ms;
}

.qrb .qrb-s3__panel[data-step="6"] .qrb-s3__say {
    opacity: 1;
}

.qrb .qrb-s3__cap {
    margin: 0;
    text-align: center;
    font: 400 var(--qrb-fs-micro)/1.5 var(--qrb-font-mono);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--qrb-text-faint);
}


/* ============================================================================
   S03.2 · WHY IT MATTERS
   ============================================================================ */
.qrb .qrb-s3__copy {
    display: grid;
    gap: var(--qrb-sp-5);
    align-content: center;
    justify-items: start;
}

.qrb .qrb-s3__title {
    max-width: 12em;
}

.qrb .qrb-s3__lead {
    max-width: 38em;
}

.qrb .qrb-s3__notes {
    display: grid;
    gap: var(--qrb-sp-4);
    margin: var(--qrb-sp-2) 0 0;
    padding: 0;
    list-style: none;
}

.qrb .qrb-s3__n {
    display: grid;
    grid-template-columns: 2rem minmax(0, 1fr);
    gap: 2px var(--qrb-sp-3);
    padding-block-start: var(--qrb-sp-4);
    border-block-start: 1px solid var(--qrb-rule-faint);
}

.qrb .qrb-s3__n-n {
    grid-row: 1 / 3;
    font: 500 var(--qrb-fs-label)/1.4 var(--qrb-font-mono);
    letter-spacing: var(--qrb-track-label);
    color: var(--qrb-azure);
}

.qrb .qrb-s3__n-t {
    margin: 0;
    font: 600 var(--qrb-fs-h3)/1.3 var(--qrb-font-sans);
    letter-spacing: -0.016em;
    color: var(--qrb-text);
}

.qrb .qrb-s3__n-b {
    margin: 0;
    font-size: var(--qrb-fs-sm);
    line-height: 1.65;
    color: var(--qrb-text-muted);
    text-wrap: pretty;
}


/* ============================================================================
   S03 · RESPONSIVE
   The two columns stay side by side at every width. Stacked, they stop being
   a comparison and become two lists, and the comparison is the point.
   ============================================================================ */
@media (max-width: 68rem) {
    .qrb .qrb-s3__grid {
        grid-template-columns: minmax(0, 1fr);
        gap: clamp(2rem, 6vw, 3rem);
    }

    .qrb .qrb-s3__stagewrap {
        justify-items: start;
    }

    .qrb .qrb-s3__copy {
        max-width: 44rem;
    }
}

@media (max-width: 40rem) {
    .qrb .qrb-s3 {
        padding-block: clamp(2.5rem, 9vw, 3.5rem);
    }

    .qrb .qrb-s3__title {
        max-width: 14em;
    }

    .qrb .qrb-s3__panel {
        max-width: 100%;
        padding: var(--qrb-sp-4);
    }

    .qrb .qrb-s3__cols,
    .qrb .qrb-s3__row,
    .qrb .qrb-s3__out {
        grid-template-columns: minmax(0, 1fr) 3.9rem 3.9rem;
    }

    .qrb .qrb-s3__out-v {
        font-size: 0.5rem;
    }

    .qrb .qrb-s3__n {
        grid-template-columns: 1.7rem minmax(0, 1fr);
    }
}

/* Reduced motion: the script paints the finished panel and stops. */
@media (prefers-reduced-motion: reduce) {
    .qrb .qrb-s3__cell,
    .qrb .qrb-s3__out,
    .qrb .qrb-s3__say {
        transition: none;
    }
}

/* ############################################################################
   END OF SECTION 03 — append SECTION 04 below this line.
   ############################################################################ */
































/* ############################################################################
   SECTION 04 · NOBODY ASKS ABOUT ANY OF THIS.
   ----------------------------------------------------------------------------
   Append to ~/public/css/recurring-bookings.css, directly under SECTION 03.
   End of the sheet.

   ══ THE DEVICE — QUESTIONS NOBODY SENDS ═══════════════════════════════════
   Three questions that never make it onto an evaluation checklist, answered
   in one line each. It reprises all three sections in their own words and it
   is warm rather than triumphal, which is what a close on a quiet page wants.

   THE ANSWER IS SHORTER THAN THE QUESTION IN ALL THREE. That is the tone of
   the section: the questions are long because nobody has thought about them,
   and the answers are short because somebody has.

   ══ NO SCRIPT, NO KEYFRAMES ═══════════════════════════════════════════════
   Section 01 cycles, Section 02 ticks, Section 03 runs in lockstep. This one
   holds still. Three moving sections and a fourth would be a page that never
   lets the reader stop.

   ACCENT BUDGET (Law 2)
     One azure rule beside each answer, and the primary button. The questions
     are ink. Nothing else — a close has nothing left to argue.
   ############################################################################ */

.qrb .qrb-s4 {
    position: relative;
    overflow: clip;
    padding-block: clamp(3.5rem, 9vw, 6.5rem);
    /* no border-block-end — this section hands off to the master footer */
}

.qrb .qrb-s4__inner {
    position: relative;
    z-index: 1;
    display: grid;
    justify-items: center;
    gap: var(--qrb-sp-5);
    text-align: center;
}

.qrb .qrb-s4__title {
    max-width: 13em;
}

.qrb .qrb-s4__sub {
    max-width: 40em;
}


/* ============================================================================
   S04.1 · THE QUESTIONS
   ============================================================================ */
.qrb .qrb-s4__wrap {
    position: relative;
    z-index: 1;
    display: grid;
    gap: var(--qrb-sp-4);
    justify-items: center;
    margin-block: clamp(2.5rem, 6vw, 4rem);
}

.qrb .qrb-s4__qa {
    display: grid;
    gap: var(--qrb-sp-5);
    width: 100%;
    margin: 0;
    padding: 0;
    list-style: none;
}

.qrb .qrb-s4__pair {
    display: grid;
    gap: var(--qrb-sp-2);
    padding-block-start: var(--qrb-sp-5);
    border-block-start: 1px solid var(--qrb-rule-faint);
}

    .qrb .qrb-s4__pair:first-child {
        padding-block-start: 0;
        border-block-start: 0;
    }

/* The question is long, because nobody has thought about it. */
.qrb .qrb-s4__q {
    font-size: var(--qrb-fs-sm);
    line-height: 1.6;
    color: var(--qrb-text-muted);
    text-wrap: pretty;
}
/* The answer is short, because somebody has. */
.qrb .qrb-s4__a {
    padding-inline-start: var(--qrb-sp-4);
    border-inline-start: 2px solid var(--qrb-azure);
    font: 600 var(--qrb-fs-h3)/1.35 var(--qrb-font-sans);
    letter-spacing: -0.016em;
    color: var(--qrb-text);
    text-wrap: pretty;
}

.qrb .qrb-s4__cap {
    margin: 0;
    font: 400 var(--qrb-fs-micro)/1.5 var(--qrb-font-mono);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--qrb-text-faint);
}


/* ============================================================================
   S04.2 · THE END
   ============================================================================ */
.qrb .qrb-s4__end {
    position: relative;
    z-index: 1;
    display: grid;
    justify-items: center;
    gap: var(--qrb-sp-5);
    text-align: center;
}

.qrb .qrb-s4__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--qrb-sp-3);
}

.qrb .qrb-s4__trust {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--qrb-sp-2) var(--qrb-sp-6);
    margin: 0;
    padding: 0;
    list-style: none;
    font: 400 var(--qrb-fs-xs)/1.4 var(--qrb-font-mono);
    letter-spacing: 0.02em;
    color: var(--qrb-text-faint);
}

    .qrb .qrb-s4__trust li {
        display: inline-flex;
        align-items: center;
        gap: var(--qrb-sp-2);
    }

        .qrb .qrb-s4__trust li::before {
            content: "";
            width: 3px;
            height: 3px;
            border-radius: 50%;
            background: var(--qrb-azure);
            flex: none;
        }


/* ============================================================================
   S04 · RESPONSIVE
   The answers keep their rule at every width. It is the only thing marking
   them as answers rather than more of the question.
   ============================================================================ */
@media (max-width: 40rem) {
    .qrb .qrb-s4 {
        padding-block: clamp(2.75rem, 10vw, 4rem);
    }

    .qrb .qrb-s4__title {
        max-width: 15em;
    }

    .qrb .qrb-s4__a {
        padding-inline-start: var(--qrb-sp-3);
    }

    .qrb .qrb-s4__actions {
        width: 100%;
    }

        .qrb .qrb-s4__actions .qrb-btn {
            flex: 1 1 100%;
        }

    .qrb .qrb-s4__trust {
        gap: var(--qrb-sp-2) var(--qrb-sp-4);
    }
}

/* Reduced motion: nothing here moves in the first place. */

/* ############################################################################
   END OF SECTION 04 — end of recurring-bookings.css
   ############################################################################ */