/* A+ Nails Rowlett — mobile-first salon theme */
:root {
    /* check216 Part D (owner, Oct 28, 2026): LIGHT-ONLY site —
       a phone/browser dark theme must not darken or invert the
       salon (the header emblem, icons and photos disappeared
       into a forced-dark page). "light only" opts the page out
       of the browser's automatic dark theme entirely; the
       _Layout head carries the matching meta, and the canvas
       below is explicitly white. Intentional dark/photographic
       pieces (hero photo + overlays, footer, the CheckIn rest
       photo) keep their own backgrounds — only the page canvas
       and the browser's treatment are pinned light. */
    color-scheme: light only;
    --rose: #b76e79;
    --rose-dark: #96555f;
    --rose-deep: #7e444d;
    --rose-soft: #f9e9e6;
    --blush: #fdf7f4;
    --charcoal: #33302d;
    --muted: #7d7169;
    --gold: #c9a227;
    --white: #ffffff;
    /* check87 (owner, Oct 20, 2026): THE selected color — bright
       yellow, one definition shared by the customer Book page and
       the admin book, so a selection looks the same everywhere and
       the two can never drift. Values are the customer page's
       long-standing picked-slot style. */
    --sel-yellow: #ffe93c;
    --sel-border: #e6cf1e;
    --sel-ink: #33302a;
    --shadow: 0 6px 22px rgba(150, 85, 95, .12);
    --radius: 16px;
    --font-display: "Playfair Display", Georgia, serif;
    --font-body: "Inter", -apple-system, "Segoe UI", sans-serif;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; background: #fff; }

body {
    margin: 0;
    font-family: var(--font-body);
    color: var(--charcoal);
    background: #fff;
    line-height: 1.6;
    font-size: 16px;
}

/* check216 Part D safeguard: even where a browser still
   reports a dark preference (or applies its own default dark
   canvas before CSS settles), the salon's page canvas and
   base ink stay the light design's — white page, charcoal
   text. Component colors are untouched: cards, pills, the
   hero and the footer already carry explicit colors and
   render as designed in both schemes. */
@media (prefers-color-scheme: dark) {
    html, body { background: #fff; }
    body { color: var(--charcoal); }
}

img { max-width: 100%; height: auto; display: block; }

h1, h2, h3 { font-family: var(--font-display); font-weight: 600; line-height: 1.2; margin: 0 0 .5em; }

h1 { font-size: 2rem; }
h2 { font-size: 1.6rem; }
h3 { font-size: 1.2rem; }

p { margin: 0 0 1em; }

a { color: var(--rose-dark); }

.wrap { max-width: 1100px; margin: 0 auto; padding: 0 20px; }

.section { padding: 56px 0; }
.section.alt { background: var(--blush); }

.kicker {
    text-transform: uppercase;
    letter-spacing: .14em;
    font-size: .78rem;
    font-weight: 600;
    color: var(--rose-dark);
    margin-bottom: .4em;
}

.lead { font-size: 1.08rem; color: var(--muted); max-width: 640px; }

/* ---------- Buttons ---------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5em;
    min-height: 52px;
    padding: .8em 1.6em;
    border-radius: 999px;
    font-weight: 600;
    font-size: 1rem;
    text-decoration: none;
    border: 0;
    cursor: pointer;
    transition: transform .12s ease, box-shadow .12s ease, background .12s ease;
}

.btn-call {
    background: var(--rose);
    color: #fff;
    box-shadow: 0 4px 14px rgba(183, 110, 121, .4);
}

.btn-call:hover { background: var(--rose-dark); color: #fff; }

.btn-outline {
    background: #fff;
    color: var(--rose-dark);
    border: 2px solid var(--rose);
}

.btn-outline:hover { background: var(--rose-soft); }

.btn:active { transform: scale(.98); }

/* ---------- Header ---------- */
.view-tabs { display: flex; gap: 8px; justify-content: flex-end; padding-top: 10px; }
.view-tab { padding: 6px 16px; border: 1.5px solid #e5d3cc; border-radius: 999px; background: #fffdfc; font-weight: 600; font-size: .92rem; line-height: 1.2; text-decoration: none; color: inherit; }
.view-tab.active { background: var(--rose); border-color: var(--rose); color: #fff; }

.site-header {
    position: sticky;
    top: 0;
    z-index: 50;
    background: rgba(255, 255, 255, .97);
    backdrop-filter: blur(6px);
    border-bottom: 1px solid #f0e2dd;
}

.header-inner {
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: 68px;
}

.brand img { height: 52px; width: auto; }

.site-nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: #fff;
    flex-direction: column;
    border-bottom: 1px solid #f0e2dd;
    box-shadow: var(--shadow);
}

.site-nav.open { display: flex; }

.site-nav a {
    padding: 14px 20px;
    text-decoration: none;
    color: var(--charcoal);
    font-weight: 500;
    border-top: 1px solid #f7ece8;
}

/* check155 (owner, Oct 25, 2026): "This menu blends into the
   background so it's too hard to see." The open mobile panel is
   unmistakable now: a full rose border on every side and a much
   stronger drop shadow lift the solid white panel off the page,
   and the row dividers step up a tone. Mobile only — the
   desktop nav row has no dropdown panel and is untouched. */
@media (max-width: 767px) {
    .site-nav { border: 1px solid #e5d3cc; box-shadow: 0 16px 38px rgba(150, 85, 95, .28); }
    .site-nav a { border-top-color: #f0e2dd; }
}

.site-nav a.active { color: var(--rose-dark); font-weight: 700; }

.nav-toggle {
    margin-left: auto;
    background: none;
    border: 0;
    padding: 10px;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    gap: 5px;
}

.nav-toggle span {
    display: block;
    width: 24px;
    height: 2.5px;
    background: var(--charcoal);
    border-radius: 2px;
}

/* check139 (owner, Oct 24, 2026): the header phone number "must be on
   same line" — it wrapped at the hyphen inside its pill. The pill
   text never wraps; the pills row sizes to fit it (mobile rule in
   the public-header-pills block below). */
.header-call { min-height: 44px; padding: .55em 1.1em; font-size: .92rem; margin-left: 4px; white-space: nowrap; }

/* ---------- Hero ---------- */
.hero {
    position: relative;
    color: #fff;
    text-align: center;
    padding: 88px 0 96px;
    background: var(--rose-deep);
}

.hero-bg {
    position: absolute;
    inset: 0;
    background: url("../images/hero.jpg") center / cover no-repeat;
    opacity: .5;
}

.hero::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(80, 40, 48, .55), rgba(80, 40, 48, .25));
}

.hero-inner { position: relative; z-index: 1; }

.hero h1 { font-size: 2.5rem; margin-bottom: .3em; text-shadow: 0 2px 12px rgba(0,0,0,.35); }

.hero .tagline { font-size: 1.12rem; margin-bottom: .4em; color: #ffe9e4; }

.hero .rating {
    display: inline-block;
    color: #fff;
    background: rgba(255,255,255,.16);
    border: 1px solid rgba(255,255,255,.35);
    padding: .3em 1em;
    border-radius: 999px;
    font-weight: 600;
    text-decoration: none;
    margin-bottom: 1.4em;
}

.hero .rating .star { color: var(--gold); }

.hero-cta { display: flex; flex-direction: column; gap: 12px; align-items: stretch; max-width: 340px; margin: 0 auto; }

.hero-cta .btn-outline { border-color: #fff; color: #fff; background: transparent; }
.hero-cta .btn-outline:hover { background: rgba(255,255,255,.15); }

/* ---------- Service cards ---------- */
.cards {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 14px;
    margin-top: 28px;
}

.card {
    background: #fff;
    border-radius: var(--radius);
    overflow: hidden;
    box-shadow: var(--shadow);
    text-decoration: none;
    color: inherit;
    display: flex;
    flex-direction: column;
    transition: transform .15s ease;
}

.card:hover { transform: translateY(-3px); }

.card img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }

.card-body { padding: 14px 14px 16px; }

.card-body h3 { font-size: 1.02rem; margin-bottom: .15em; }

.card-body .from { color: var(--rose-dark); font-weight: 600; font-size: .92rem; }

/* ---------- Gallery strip / grid ---------- */
.strip {
    display: flex;
    gap: 12px;
    overflow-x: auto;
    padding: 8px 20px 16px;
    margin: 20px -20px 0;
    scroll-snap-type: x mandatory;
}

.strip img {
    flex: 0 0 240px;
    height: 170px;
    object-fit: cover;
    border-radius: 12px;
    scroll-snap-align: start;
}

.gallery-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 12px;
    margin-top: 24px;
}

.gallery-grid button {
    border: 0;
    padding: 0;
    background: none;
    cursor: zoom-in;
    border-radius: 12px;
    overflow: hidden;
}

.gallery-grid img { width: 100%; aspect-ratio: 1; object-fit: cover; transition: transform .2s ease; }
.gallery-grid button:hover img { transform: scale(1.04); }

.lightbox {
    position: fixed;
    inset: 0;
    z-index: 100;
    background: rgba(30, 22, 24, .92);
    display: none;
    align-items: center;
    justify-content: center;
    padding: 24px;
}

.lightbox.open { display: flex; }

.lightbox img { max-width: 100%; max-height: 86vh; border-radius: 8px; }

.lightbox-close {
    position: absolute;
    top: 14px;
    right: 18px;
    background: none;
    border: 0;
    color: #fff;
    font-size: 2.2rem;
    cursor: pointer;
    line-height: 1;
}

/* ---------- Visit block ---------- */
.visit-grid { display: grid; gap: 28px; margin-top: 8px; }
.award { background: linear-gradient(135deg, #2b2123 0%, #4a3538 100%); }
.award h2, .award .kicker { color: #f7e8dc; }
.award .lead { color: #e8d5c4; }
.award-img { display: block; width: 100%; max-width: 340px; margin: 0 auto; border-radius: 14px; box-shadow: 0 14px 36px rgba(0,0,0,.45); }

.hours-list { list-style: none; margin: 0; padding: 0; }

.hours-list li {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: .65em 0;
    border-bottom: 1px dashed #e8d5cf;
}

.hours-list li span:first-child { font-weight: 600; }

.visit-actions { display: flex; flex-direction: column; gap: 12px; margin-top: 20px; }

.map-frame {
    width: 100%;
    min-height: 300px;
    border: 0;
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}

/* ---------- Menu (Services page) ---------- */
.menu-group { margin-bottom: 40px; }

.menu-group > h2 {
    display: flex;
    align-items: center;
    gap: 12px;
}

.menu-group > h2::after {
    content: "";
    flex: 1;
    height: 1px;
    background: #ecd9d3;
}

.menu-blurb { color: var(--muted); margin: -.4em 0 1em; }

.starts-at { display: flex; flex-wrap: wrap; gap: 8px; margin: .2em 0 1.1em; }

.starts-at span {
    background: var(--rose-soft);
    color: var(--rose-deep);
    font-weight: 700;
    font-size: .95rem;
    padding: 8px 16px;
    border-radius: 999px;
    border: 1px solid #ecd9d3;
}

.menu-list {
    list-style: none;
    margin: 0;
    padding: 6px 20px;
    background: #fff;
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}

.menu-list li { padding: .8em 0; border-bottom: 1px solid #f6ebe7; }

.menu-list li:last-child { border-bottom: 0; }

.menu-list .menu-name { font-weight: 600; }

.menu-list .menu-desc { display: block; color: var(--muted); font-size: .92rem; margin-top: 2px; }

.svc-grid { display: grid; gap: 20px; margin-top: 24px; }

.svc-card { background: #fff; border-radius: var(--radius); box-shadow: var(--shadow); overflow: hidden; }

.svc-card > img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; display: block; }

.svc-body { padding: 20px; }

.svc-body h2 { margin: 0 0 8px; font-size: 1.35rem; }

.svc-body p { color: var(--muted); margin: 0 0 12px; }

.svc-body .starts-at { margin: 0 0 4px; }

.svc-body .menu-note { margin: 10px 0 0; }

@media (min-width: 768px) {
    .svc-grid { grid-template-columns: 1fr 1fr; }
}

/* check144 (owner, Oct 24, 2026): the /Services rotating ring —
   five category circles turning slowly around the salon logo hub.
   check145 (owner, Oct 24, 2026): the reference look — every
   circle wears a rose ribbon band with its name in white and
   carries its minimum price ("35+") directly underneath; ALL
   SIX circles (the logo hub included) are exactly the same
   size, with no front-circle scaling; and the motion is
   composited CSS transforms ONLY (the ring rotates, each circle
   counter-rotates so its photo and ribbon stay upright) — no
   script ever writes a circle's position, so the turn is
   buttery. Positions arrive server-rendered (percent pentagon,
   no-JS safe); the animations run only once the script adds
   .js, and .paused freezes both timelines together while a
   pop-down list is open. */
/* overflow-x: clip — the rotating ring's post-transform
   bounding box is wider than the stage at diagonal angles;
   without clipping it would hand the page a horizontal
   scrollbar. The circles themselves never reach the clip edge
   (their geometry keeps them inside the stage). */
.svc-orbit { margin-top: 26px; overflow-x: clip; }

.svc-stage {
    position: relative;
    width: min(430px, 94vw);
    aspect-ratio: 1;
    margin: 0 auto;
}

.svc-ring { position: absolute; inset: 0; }

/* The -18s phase starts the ring with Artificial Nails at the
   front (the owner's featured circle, as in check144): both
   timelines carry the same delay so the counter-rotation stays
   exactly opposed at every instant. */
.svc-orbit.js .svc-ring { animation: svc-spin 60s linear infinite; animation-delay: -18s; }

@keyframes svc-spin { to { transform: rotate(360deg); } }

.svc-hub {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 26%;
    aspect-ratio: 1;
    transform: translate(-50%, -50%);
    border-radius: 50%;
    background: #fffdfb;
    border: 2.5px solid var(--gold);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    z-index: 5;
}

.svc-hub img { width: 88%; }

.svc-orb {
    position: absolute;
    width: 26%;
    transform: translate(-50%, -50%);
    display: block;
    text-decoration: none;
}

.svc-orb-in {
    position: relative;
    display: block;
}

.svc-orbit.js .svc-orb-in { animation: svc-spin-rev 60s linear infinite; animation-delay: -18s; }

@keyframes svc-spin-rev { to { transform: rotate(-360deg); } }

.svc-orbit.paused .svc-ring,
.svc-orbit.paused .svc-orb-in { animation-play-state: paused; }

@media (prefers-reduced-motion: reduce) {
    .svc-orbit.js .svc-ring,
    .svc-orbit.js .svc-orb-in { animation: none; }
}

.svc-disc {
    display: block;
    position: relative;
    width: 100%;
    aspect-ratio: 1;
    border-radius: 50%;
    border: 3px solid var(--gold);
    overflow: hidden;
    background: #fff;
}

/* The photo is taken out of flow (absolute inset) so its
   natural aspect can never stretch the disc — the disc's
   aspect-ratio alone sets a true circle. */
.svc-disc img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }

/* check145: the rose ribbon band across the circle's lower
   third, the category name in white elegant lettering —
   the owner's reference photo. */
.svc-ribbon {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 17%;
    background: linear-gradient(135deg, var(--rose), var(--rose-dark));
    color: #fff;
    font-family: var(--font-display);
    font-style: italic;
    text-align: center;
    font-size: .8rem;
    line-height: 1.15;
    padding: 4px 3px;
}

/* check145's under-circle minimum tag, check148's rose pill:
   both REMOVED in check149 (owner, Oct 24, 2026 — "I don't
   want to list price on anything"). The .svc-min element no
   longer renders; no rule for it remains. */

.svc-orb.front .svc-disc { border-color: var(--rose-dark); }

.svc-orb.open .svc-disc { border-color: var(--rose-dark); box-shadow: 0 0 0 5px #f3d9d7; }

/* check148: the under-ring front name and price rules are
   REMOVED with their elements — the script's front tracking
   now only drives the .front marker above; nothing renders
   under the ring but the panels. */

/* The five detail panels: stacked and reachable via the circle
   anchors when there is no JavaScript; with JavaScript only the
   open one shows — and it POPS down fast (check145: a quick
   slide/fade drop, the panel sized tight to its content:
   "short" — compact rows, no tall card). */
.svc-panels { margin-top: 22px; }

.svc-orbit.js .svc-panel { display: none; }

.svc-orbit.js .svc-panel.open { display: block; animation: svc-pop .18s ease-out; }

@keyframes svc-pop {
    from { opacity: 0; transform: translateY(-8px); }
    to { opacity: 1; transform: translateY(0); }
}

.svc-panel {
    background: #fffdfb;
    border: 1.5px solid var(--gold);
    border-radius: 20px;
    padding: 4px 18px 10px;
    margin-top: 14px;
    box-shadow: var(--shadow);
    text-align: left;
}

.svc-panel h2 {
    font-family: var(--font-display);
    font-size: 1.3rem;
    color: var(--rose-dark);
    margin: 10px 0 2px;
}

.svc-panel h3 {
    font-size: 1.02rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--gold);
    margin: 10px 0 0;
}

.svc-items { list-style: none; margin: 0; padding: 0; }

.svc-items li { padding: 6px 0; border-bottom: 1px solid #eee0d6; }

.svc-items li:last-child { border-bottom: 0; }

.svc-item-name { font-weight: 600; color: var(--charcoal); }

.svc-item-desc { display: block; color: var(--muted); font-size: .92rem; margin-top: 2px; line-height: 1.45; }

/* check144: an online-blocked service pill (Facial on the
   customer forms) — visible but greyed and unselectable. */
.slot.slot-blocked {
    background: #f4efec;
    color: var(--muted);
    cursor: not-allowed;
    font-weight: 500;
    opacity: .65;
}

.slot.slot-blocked input { cursor: not-allowed; }

.video-grid { display: grid; gap: 16px; margin: 24px 0 8px; }

.video-card video {
    width: 100%;
    border-radius: 12px;
    box-shadow: var(--shadow);
    background: #000;
    aspect-ratio: 9 / 16;
    max-height: 520px;
}

.video-card p { text-align: center; color: var(--muted); font-size: .92rem; margin: 8px 0 0; }

@media (min-width: 768px) {
    .video-grid { grid-template-columns: 1fr 1fr; }
}

.menu-items {
    background: #fff;
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 6px 20px;
}

.menu-item { padding: .85em 0; border-bottom: 1px solid #f6ebe7; }

.menu-item:last-child { border-bottom: 0; }

.menu-row { display: flex; align-items: baseline; gap: 10px; }

.menu-row .name { font-weight: 600; }

.menu-row .dots { flex: 1; border-bottom: 2px dotted #e3c9c2; transform: translateY(-4px); }

.menu-row .price { font-weight: 700; color: var(--rose-dark); white-space: nowrap; }

.menu-item .desc { color: var(--muted); font-size: .92rem; margin: .15em 0 0; }

.menu-note {
    margin-top: 12px;
    background: var(--rose-soft);
    border-radius: 12px;
    padding: 12px 16px;
    font-size: .95rem;
}

/* ---------- Forms ---------- */
.form-card {
    background: #fff;
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 28px 22px;
    max-width: 560px;
}

/* One box per step on the booking page (owner spec, Oct 19, 2026). */
.step-box { margin-top: 20px; }

.field { margin-bottom: 18px; }

.field label { display: block; font-weight: 600; margin-bottom: 6px; }

.field input, .field textarea {
    width: 100%;
    padding: 14px;
    font-size: 1rem;
    font-family: inherit;
    border: 1.5px solid #e5d3cc;
    border-radius: 10px;
    background: #fffdfc;
}

.field input:focus, .field textarea:focus {
    outline: none;
    border-color: var(--rose);
    box-shadow: 0 0 0 3px rgba(183, 110, 121, .15);
}

/* check155: the booking form's clearable contact fields — the
   wrap is the positioning context and the input always keeps
   room on its right, so the ✗ button sits inside the field's
   right edge without ever shifting the layout. */
.clearable-wrap { position: relative; }
.clearable-wrap input { padding-right: 48px; }
.field-clear {
    position: absolute;
    top: 50%;
    right: 6px;
    transform: translateY(-50%);
    width: 36px;
    height: 36px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: var(--rose-soft);
    color: var(--rose-dark);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}
.field-clear svg { width: 16px; height: 16px; }
.field-clear[hidden] { display: none; }

.field textarea { min-height: 130px; resize: vertical; }

.field .error { color: #b3261e; font-size: .88rem; margin-top: 4px; display: block; }

.validation-summary { color: #b3261e; margin-bottom: 1em; }

/* ---------- Footer ---------- */
.site-footer { background: #2c2724; color: #e8ded8; padding: 48px 0 120px; }

.footer-grid { display: grid; gap: 32px; }

.site-footer h3 { color: #fff; font-size: 1.1rem; }

.site-footer .tagline { color: #c9b8ae; }

.site-footer a { color: #f3d9d2; }

.site-footer address { font-style: normal; margin-bottom: .6em; }

.site-footer .rating {
    display: inline-block;
    margin-top: .4em;
    color: #fff;
    text-decoration: none;
    border: 1px solid #6b5d55;
    padding: .35em 1em;
    border-radius: 999px;
    font-weight: 600;
}

.site-footer .rating:hover { border-color: var(--rose); }

.footer-bottom {
    margin-top: 36px;
    padding-top: 20px;
    border-top: 1px solid #4a423c;
    font-size: .88rem;
    color: #a8988e;
}

.footer-bottom .fine { margin: 0; }

/* ---------- Thank you ---------- */
.thanks {
    text-align: center;
    max-width: 560px;
    margin: 0 auto;
    padding: 24px 0;
}

.thanks .big { font-size: 3.2rem; }

/* ---------- Desktop ---------- */
@media (min-width: 768px) {
    h1 { font-size: 2.6rem; }
    .hero h1 { font-size: 3.4rem; }
    .hero-cta { flex-direction: row; justify-content: center; max-width: none; }
    .nav-toggle { display: none; }
    .site-nav {
        display: flex;
        position: static;
        flex-direction: row;
        border: 0;
        box-shadow: none;
        margin-left: auto;
        align-items: center;
    }
    .site-nav a { border: 0; padding: 8px 14px; }
    .header-call { margin-left: 8px; }
    .cards { grid-template-columns: repeat(3, 1fr); gap: 22px; }
    .gallery-grid { grid-template-columns: repeat(3, 1fr); gap: 16px; }
    .visit-grid { grid-template-columns: 1fr 1fr; align-items: start; }
    /* check143: the embedded map column is removed — a lone visit
       child (address + hours + actions) spans the full row. */
    .visit-grid > div:only-child { grid-column: 1 / -1; }
    .visit-actions { flex-direction: row; }
    .visit-actions .btn { flex: 1; }
    .footer-grid { grid-template-columns: 1.2fr 1fr 1fr; }
    .site-footer { padding-bottom: 48px; }
    .form-card { padding: 36px; }
}

/* ---------- Booking (Book / My Appointment) ---------- */
.field select {
    width: 100%;
    padding: 14px;
    font-size: 1rem;
    font-family: inherit;
    border: 1.5px solid #e5d3cc;
    border-radius: 10px;
    background: #fffdfc;
}

.field select:focus {
    outline: none;
    border-color: var(--rose);
    box-shadow: 0 0 0 3px rgba(183, 110, 121, .15);
}

.field .optional { font-weight: 400; color: var(--muted); font-size: .88rem; }

.notice {
    margin-top: 20px;
    background: var(--rose-soft);
    border: 1.5px solid var(--rose);
    border-radius: 12px;
    padding: 14px 18px;
    font-size: .98rem;
}

.notice.error {
    background: #fdecea;
    border-color: #b3261e;
    color: #7a1a14;
}

.slot-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
    gap: 10px;
}

.svc-grid {
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
}

.req { color: var(--rose-deep); font-weight: 700; }
.step-head { display: flex; align-items: center; gap: 10px; font-size: 1.18rem; margin: 26px 0 12px; }
.step-head:first-child { margin-top: 4px; }
.step-n { background: var(--rose); color: #fff; border-radius: 999px; padding: 7px 16px; font-family: var(--font-body); font-size: 1rem; font-weight: 400; letter-spacing: .02em; white-space: nowrap; }

.svc-grid .svc-name { display: block; font-size: 1.06rem; font-weight: 700; line-height: 1.25; }
.svc-grid .svc-dur { display: block; font-size: .9rem; font-weight: 600; opacity: .72; }

.slot {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    min-height: 58px;
    padding: 10px 6px;
    border: 1.5px solid #e5d3cc;
    border-radius: 12px;
    background: #fffdfc;
    cursor: pointer;
    font-weight: 600;
    text-align: center;
}

.slot input {
    position: absolute;
    opacity: 0;
    inset: 0;
    cursor: pointer;
}

.slot:has(input:checked) {
    background: var(--sel-yellow);
    border-color: var(--sel-border);
    color: var(--sel-ink);
    box-shadow: 0 4px 14px rgba(230, 207, 30, .45);
}

.slot:has(input:focus-visible) { outline: 3px solid rgba(183, 110, 121, .5); outline-offset: 2px; }

.slot.full {
    background: #f4efec;
    color: var(--muted);
    cursor: not-allowed;
    font-weight: 500;
}

.slot-state { font-size: .78rem; text-transform: uppercase; letter-spacing: .08em; }

.contact-block {
    margin-top: 44px;
    background: var(--blush);
    border-radius: var(--radius);
    padding: 28px 22px;
    max-width: 560px;
}

.contact-block address { font-style: normal; margin-bottom: 1em; }

.contact-block .hours-list { list-style: none; margin: 0; padding: 0; }

.contact-block .hours-list li {
    display: flex;
    justify-content: space-between;
    gap: 16px;
    padding: 4px 0;
}

.btn.danger { color: #b3261e; border-color: #b3261e; }

/* ---------- Owner admin ---------- */
.admin-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}

.admin-links a { margin-left: 16px; font-weight: 600; }

/* check136 (owner, Oct 24, 2026): on the Book page the owner links
   sit below the book grid as buttons, two per row — a 2-column grid
   of the shared .btn .btn-outline pills, the Sign out POST form
   included as a plain grid cell whose button fills it. */
.book-admin-actions {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 24px;
    margin-top: 20px;
}

.book-admin-actions form { margin: 0; display: flex; }

/* check226 (owner, Oct 28, 2026): plain text links with a hover
   effect instead of pill buttons — the letters turn red and bold
   on hover / tap, which cleans up the space the boxes took. A
   hairline under each row keeps the list easy to scan. */
.book-admin-actions .tool-link {
    display: block;
    width: 100%;
    padding: 13px 2px;
    font-size: 1.08rem;
    font-family: inherit;
    color: #43302b;
    background: none;
    border: 0;
    border-bottom: 1px solid #f0e8e2;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}
.book-admin-actions .tool-link:hover,
.book-admin-actions .tool-link:active { color: #b3261e; font-weight: 700; }
.book-admin-actions .tool-signout { color: #b3261e; }

/* check207 (owner, Oct 27, 2026): the late-booking switches —
   one pair per day in the Book grid's footer row, directly
   under that day's column (design of record:
   mockups/late-booking-toggles). The pair together spans
   half the column width, centered, and sits a little shorter
   than the panel's main buttons. The fill IS the state:
   green = on, red = off (off is every day's default).
   check208 (design of record: mockups/late-booking-workers):
   each start is a split circle like a Block Hours cell — the
   time label above it, left half S (Steven), right half T
   (Tracy), each half its own switch in the same green/red.
   The pair stays small and centered under the column. */
.book-grid .book-late-row td { vertical-align: middle; }

.late-pair { display: flex; gap: 10px; justify-content: center; }

.late-group { text-align: center; }

.late-label { font-size: .95rem; font-weight: 700; color: #96555f; margin-bottom: 4px; }

.late-split {
    display: flex;
    width: 52px;
    height: 52px;
    border-radius: 50%;
    overflow: hidden;
    margin: 0 auto;
    box-shadow: 0 1px 4px rgba(90, 50, 55, .25);
}

.late-half-form { flex: 1; display: flex; margin: 0; }

.late-half {
    flex: 1;
    width: 100%;
    border: none;
    color: #fff;
    font-weight: 800;
    font-size: 14px;
    cursor: pointer;
    font-family: inherit;
}

.late-half.s { border-right: 1px solid rgba(255, 255, 255, .35); }

.late-half.on { background: #3d9950; }

.late-half.off { background: #cf3527; }

.late-half:active { transform: scale(.94); }

/* check138 (owner, Oct 24, 2026): the SOUND chip's own row at the
   middle bottom of the Book page — centered, alone on its row,
   below the owner-button grid and above the visitor pills. */
.book-sound-row {
    text-align: center;
    margin: 20px 0 14px;
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

/* check188 (owner, Oct 27, 2026): the Customer Sign-In pill —
   the Book's last element (approved sample:
   mockups/book-signin-button-sample). Full-width rose pill,
   52px tall like the Book Appointment pill. */
.cust-signin {
    display: block;
    width: 100%;
    margin-top: 18px;
    border: none;
    border-radius: 999px;
    height: 52px;
    line-height: 52px;
    text-align: center;
    text-decoration: none;
    font-size: 17px;
    font-weight: 800;
    letter-spacing: .2px;
    color: #fff;
    background: linear-gradient(135deg, #c0808d, #b76e79 55%, #96555f);
    box-shadow: 0 8px 18px rgba(183, 110, 121, .35);
    cursor: pointer;
}
.cust-signin:active { transform: scale(.99); }

/* check143 (owner, Oct 24, 2026): the alert-sound picker shares the
   SOUND chip's pill look, beside it in the centered sound row. */
.sound-pick { font: inherit; font-size: 14px; font-weight: 700; background: #e8e2dc; color: #6b6259; border: none; border-radius: 999px; padding: 6px 10px; cursor: pointer; }

.day-nav {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin: 20px 0;
}

.day-nav input[type="date"] {
    padding: 12px 14px;
    font-size: 1rem;
    font-family: inherit;
    border: 1.5px solid #e5d3cc;
    border-radius: 10px;
    background: #fffdfc;
}

.day-nav .btn { min-height: 48px; }

.appt-table { width: 100%; border-collapse: collapse; margin-top: 8px; }

.appt-table th, .appt-table td {
    text-align: left;
    padding: 10px 8px;
    border-bottom: 1px solid #f0e2dd;
    vertical-align: top;
}

.appt-table th { font-size: .85rem; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }

.badge {
    display: inline-block;
    padding: .15em .8em;
    border-radius: 999px;
    font-size: .82rem;
    font-weight: 600;
}

.badge-booked { background: #e6f4ea; color: #256029; }
.badge-cancelled { background: #fdecea; color: #b3261e; }
.badge-noshow { background: #fff4e0; color: #8a5a00; }
.badge-overlap { background: #ffedd5; color: #7c2d12; }
.combine-bar { display: flex; gap: 10px; align-items: center; margin: 12px 0 4px; flex-wrap: wrap; }

.row-actions { white-space: nowrap; }

.row-actions form { display: inline-block; margin: 0 4px 4px 0; }

.btn-mini {
    min-height: 40px;
    padding: .45em 1em;
    border-radius: 999px;
    border: 1.5px solid var(--rose);
    background: #fff;
    color: var(--rose-dark);
    font-weight: 600;
    font-size: .88rem;
    cursor: pointer;
}

.btn-mini:hover { background: var(--rose-soft); }

.btn-mini.danger { border-color: #b3261e; color: #b3261e; }

.btn-mini.danger:hover { background: #fdecea; }

/* ---------- PIN pad ---------- */
.pin-wrap { max-width: 340px; margin: 0 auto; }

/* check91 (Oct 20, 2026): the .pin-display dots row that used to sit
   above the PIN box is gone at the owner's direction — the box itself
   masks the typed digits, so no separate dot row is shown. */

.pin-input {
    width: 100%;
    padding: 14px;
    font-size: 1.4rem;
    text-align: center;
    letter-spacing: .4em;
    font-family: inherit;
    border: 1.5px solid #e5d3cc;
    border-radius: 10px;
    background: #fffdfc;
    margin-bottom: 16px;
}

.pin-input:focus {
    outline: none;
    border-color: var(--rose);
    box-shadow: 0 0 0 3px rgba(183, 110, 121, .15);
}

.pin-pad {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 10px;
    margin-bottom: 16px;
}

.pin-key {
    min-height: 68px;
    font-size: 1.5rem;
    font-weight: 600;
    font-family: inherit;
    border: 1.5px solid #e5d3cc;
    border-radius: 14px;
    background: #fff;
    color: var(--charcoal);
    cursor: pointer;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
}

.pin-key:active { background: var(--rose-soft); transform: scale(.97); }

.pin-key-alt { font-size: 1rem; color: var(--rose-dark); }

.pin-key:disabled, .pin-input:disabled { opacity: .45; cursor: not-allowed; }

.pin-hint { text-align: center; color: var(--muted); font-size: .88rem; margin-top: 12px; }

@media (max-width: 640px) {
    .appt-table thead { display: none; }
    .appt-table, .appt-table tbody, .appt-table tr, .appt-table td { display: block; width: 100%; }
    .appt-table tr { padding: 10px 0; border-bottom: 1px solid #f0e2dd; }
    .appt-table td { border: 0; padding: 3px 8px; }
    .appt-table td::before {
        content: attr(data-th) ": ";
        font-weight: 600;
        color: var(--muted);
    }
    .appt-table td.row-actions::before { content: ""; }
}

button.link-btn { background:none; border:none; padding:0; color:#b76e79; text-decoration:underline; font-size:.95rem; cursor:pointer; }
.fineprint { font-size:.85rem; opacity:.75; }

.slot-check { display:flex; align-items:center; gap:8px; border:1px solid #e8d5cf; border-radius:10px; padding:10px 12px; cursor:pointer; background:#fff; }
.slot-check input { width:18px; height:18px; accent-color:#b76e79; }

/* Owner paper-book view (/Admin/Book) */
.book-grid { border-collapse:separate; border-spacing:0; width:100%; min-width:880px; background:#fff; border-top:1px solid #e3d2cc; border-left:1px solid #e3d2cc; }
/* check90 (owner, Oct 20, 2026): fixed layout so the Book page's
   day-column widths are exact — TODAY and TOMORROW render 1.5x a
   standard day column. The widths themselves are set in px by a
   small script on the Book page (see Book.cshtml for why CSS
   calc cannot express them in Chrome); fixed layout makes the
   header row's widths size the columns, and with no script the
   day columns just share the width equally, as before.
   check94 (owner, Oct 21, 2026): the script grows every column
   from that base — standard 1.3x, today/tomorrow 1.8x net — and
   sets the table's own width to the sum, so the book overflows
   its scroll box sideways with the Time column pinned. */
.book-grid { table-layout:fixed; }
.book-grid th, .book-grid td { border-right:1px solid #e3d2cc; border-bottom:1px solid #e3d2cc; padding:8px 10px; vertical-align:top; font-size:.92rem; }
.book-grid thead th { background:#faf1ee; text-align:left; }
.book-date { font-weight:400; font-size:.85rem; opacity:.8; }
.book-time-head, .book-time { width:64px; text-align:right; font-weight:600; background:#faf7f5; }
/* The Time column stays locked in place while the week scrolls sideways
   under it (owner request, Oct 17, 2026). Sticky needs the separate
   border model above; the corner cell sits one layer higher.
   check125 (Oct 24, 2026): the layer is z-index 4, above the cells'
   pluses (z-index 2) and half-hit overlays (z-index 3) — a scrolled-off
   day column's pluses used to tie the gutter at z-index 2 and win on
   DOM order, painting a stray orange plus over the 9:00 label. */
.book-grid .book-time { position:sticky; left:0; z-index:4; box-shadow:4px 0 6px -3px rgba(61,51,48,.35); }
/* Half-hour rows keep their slot and grid lines but show no time number —
   the Time column reads on the hour only, like the paper book (owner
   spec, Oct 18, 2026). */
.book-grid tr.book-half .book-time { color:transparent; }
.book-grid .book-time-head { position:sticky; left:0; z-index:3; background:#faf1ee; box-shadow:4px 0 6px -3px rgba(61,51,48,.35); }
.book-closed { background:#e9e4e1; color:#9a8f8a; text-align:center; }
.book-blocked { background:#f7e3e3; color:#a33; text-align:center; font-size:.85rem; }
.book-appt { background:#fbeef1; }
.book-appt a { color:inherit; text-decoration:none; display:block; }

/* Customer booking date control: a button showing the full day
   ("Saturday Oct 17, 2026") that opens our own Monday-first calendar.
   Picking a day loads that day's times immediately.
   check204 (owner, Oct 27, 2026): the control is ONE big rose
   button in the .btn-call treatment — calendar icon, the day
   label in big bold white letters, a BIG bold down chevron
   (about twice the label's size, heavy weight, matching the
   approved sample) — and NO sub-line or other words. */
.date-pick { position: relative; }
.date-display { display: flex; align-items: center; gap: 11px; width: 100%; padding: 13px 17px; font-family: inherit; border: 0; border-radius: 12px; background: var(--rose); color: #fff; cursor: pointer; text-align: left; box-shadow: 0 4px 14px rgba(183, 110, 121, .35); transition: background .12s ease, box-shadow .12s ease; }
.date-display:hover { background: var(--rose-dark); }
.date-display:focus { outline: none; box-shadow: 0 0 0 3px rgba(183, 110, 121, .35), 0 4px 14px rgba(183, 110, 121, .35); }
.date-display .date-cal { flex: 0 0 auto; width: 32px; height: 32px; }
.date-display .date-text { flex: 1 1 auto; font-size: 1.3rem; font-weight: 700; line-height: 1.15; }
.date-display .date-chev { flex: 0 0 auto; font-size: 2.6rem; font-weight: 900; line-height: 1; }
.cal-pop { position: absolute; left: 0; right: 0; top: calc(100% + 6px); z-index: 60; background: #fff; border: 1px solid #ecd9d3; border-radius: 16px; box-shadow: 0 18px 40px rgba(90,50,50,.18); padding: 12px; }
.cal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.cal-title { font-weight: 700; }
.cal-nav { width: 38px; height: 38px; border-radius: 50%; border: 1px solid #ecd9d3; background: #fff; font-size: 1.3rem; line-height: 1; cursor: pointer; color: var(--rose-dark); }
.cal-nav:disabled { opacity: .3; cursor: default; }
.cal-week, .cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; text-align: center; }
.cal-week span { font-size: .72rem; letter-spacing: .06em; color: #a08d84; padding: 4px 0; text-transform: uppercase; }
.cal-day { aspect-ratio: 1; border: 0; border-radius: 50%; background: transparent; font: inherit; font-size: .95rem; cursor: pointer; }
.cal-day:hover:not(:disabled) { background: var(--rose-soft); }
.cal-day:disabled { opacity: .28; cursor: default; }
.cal-day.today { box-shadow: inset 0 0 0 1.5px var(--gold); }
.cal-day.sel { background: var(--sel-yellow); color: var(--sel-ink); font-weight: 700; }

/* Customer color mark: a small circle next to the customer's name
   everywhere in the owner console. "white" is a black ring, white inside. */
.cdot { display: inline-block; width: 13px; height: 13px; border-radius: 50%; vertical-align: baseline; margin-right: 6px; }
.cdot-black { background: #2b2320; }
.cdot-gold { background: radial-gradient(circle at 35% 30%, #e8c87a, #c9a227); border: 1px solid #b08d1e; }
.cdot-gray { background: #9b918c; }
.cdot-white { background: #fff; border: 2px solid #2b2320; width: 11px; height: 11px; }

/* Owner book: the two main action buttons + week flipping. */
.owner-actions { display: flex; gap: 10px; margin: 14px 0 6px; }
.owner-actions .btn { flex: 1; text-align: center; padding: 15px 6px; font-size: 1.02rem; border-radius: 12px; }
.week-nav { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 10px 0 4px; }
.week-nav .wk-label { font-weight: 700; text-align: center; }
.week-nav a { white-space: nowrap; }

/* Instant customer picker (Add booking + Search Customer). The full
   directory ships with the page; filtering happens on the phone with
   zero waiting — no search button, no reloads. */
.pick-results { margin-top: 10px; }
.pick-row { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; background: #fff; border: 1.5px solid #ecd9d3; border-radius: 12px; padding: 11px 13px; margin-bottom: 8px; cursor: pointer; font: inherit; color: inherit; text-decoration: none; }
.pick-row:hover { border-color: var(--rose); }
.pick-row .p-name { font-weight: 700; }
.pick-row .p-sub { color: #6f5f58; font-size: .88rem; display: block; }
.p-note { font-style: italic; color: #6f5f58; font-size: .92rem; }
.pick-row .p-note { display: block; }
.pick-row .p-go { margin-left: auto; color: var(--rose-dark); font-weight: 800; }
.pick-row .pick-main { flex: 1; color: inherit; text-decoration: none; }
.pick-row .p-profile { margin-left: auto; flex: none; color: var(--rose-dark); font-weight: 700; font-size: .9rem; text-decoration: none; border: 1.5px solid #ecd9d3; border-radius: 999px; padding: 7px 13px; }
.pick-row .p-profile:hover { border-color: var(--rose); }
.pick-empty { color: #6f5f58; padding: 8px 2px; }
/* Phone live search (owner spec, Oct 20, 2026): the gold row under the
   phone matches that starts a brand-new customer with the typed number. */
.pick-addnew { background: #fdf6ec; border-color: #eed9ae; color: #9a6a12; font-weight: 700; }
.pick-addnew:hover { border-color: #e9a13b; }
.pick-addnew .plus-badge { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: 50%; background: #e9a13b; color: #fff; font-size: 17px; font-weight: 800; line-height: 1; flex: none; }
/* No-phone ask (owner spec, Oct 20, 2026): the in-page prompt shown
   when an owner save is attempted with the phone left empty. */
.nophone-prompt { background: #fdf6ec; border: 1.5px solid #eed9ae; border-radius: 12px; padding: 14px; margin-bottom: 16px; }
/* Walk-in button + banner (check107, owner, Oct 23, 2026 — approved
   sample mockups/walkin-button.html): the button sits UNDER the Find
   customer search box on the Add form (never on its right side, never
   inside it); the banner is the state the card collapses to in
   walk-in mode, and the same banner shows on a saved walk-in's Edit
   screen. Reusable classes — no inline styles. */
.walkin-btn { margin-top: 14px; width: 100%; border: 2px solid var(--rose); background: var(--rose-soft); color: var(--rose-dark); border-radius: 14px; padding: 13px 16px; text-align: left; cursor: pointer; font: inherit; }
.walkin-btn:hover { border-color: var(--rose-dark); }
.walkin-btn-t { font-size: 21px; font-weight: 800; display: block; }
.walkin-btn-d { font-size: 16px; color: #7a5a60; display: block; margin-top: 2px; }
.walkin-on { display: flex; align-items: center; justify-content: space-between; gap: 10px; background: var(--rose-soft); border: 2px solid var(--rose); border-radius: 14px; padding: 14px 16px; }
.walkin-on-t { font-size: 21px; font-weight: 800; color: var(--rose-dark); display: block; }
.walkin-on-d { font-size: 16px; color: #7a5a60; display: block; margin-top: 2px; }
.walkin-change { background: none; border: none; font: inherit; font-size: 17px; font-weight: 700; color: var(--rose-dark); text-decoration: underline; cursor: pointer; white-space: nowrap; padding: 0; }
.nophone-q { font-weight: 700; margin: 0 0 10px; }
.nophone-btns { display: flex; gap: 10px; flex-wrap: wrap; }

/* Customer notes thread (Edit page + customer profile). */
.note-item { background: #fdf6ee; border-left: 3px solid var(--gold); border-radius: 0 10px 10px 0; padding: 8px 12px; margin-bottom: 8px; }
.note-item .n-date { font-size: .78rem; color: #a08d84; display: block; margin-bottom: 2px; }
.mark-picker { display: flex; gap: 12px; align-items: center; }
.mark-pick-btn { background: none; border: 0; cursor: pointer; padding: 6px; border-radius: 50%; }
.mark-pick-btn.sel { outline: 2px solid var(--rose); outline-offset: 2px; }
.mark-pick-btn .cdot { width: 22px; height: 22px; margin: 0; }
.mark-pick-btn .cdot-white { width: 19px; height: 19px; }

/* Search Customer: tappable color dot + inline color strip (Oct 17, 2026). */
.pick-row { flex-wrap: wrap; }
.pick-main { flex: 1; color: inherit; text-decoration: none; min-width: 0; }
.dot-btn { background: none; border: 0; cursor: pointer; padding: 8px 6px; margin: -4px 0; }
.dot-btn .cdot { width: 20px; height: 20px; margin: 0; }
.dot-btn .cdot-white { width: 17px; height: 17px; }
.color-strip { flex-basis: 100%; display: flex; gap: 10px; align-items: center; padding: 8px 4px 2px; border-top: 1px dashed #ecd9d3; margin-top: 8px; }
.color-strip .mark-pick-btn .cdot { width: 24px; height: 24px; }
.color-strip .mark-pick-btn .cdot-white { width: 21px; height: 21px; }

/* Customer note log: Date | Time | Note, oldest first, newest at the
   bottom (owner spec, Oct 17, 2026). */
.log-table { width:100%; border-collapse:collapse; font-size:.92rem; }
.log-table th { text-align:left; font-size:.75rem; letter-spacing:.08em; text-transform:uppercase; color:#a08d84; padding:4px 8px 4px 0; border-bottom:1.5px solid #ecd9d3; }
.log-table td { padding:7px 8px 7px 0; border-bottom:1px solid #f3e6e0; vertical-align:top; }
.log-table .lt-when { white-space:nowrap; color:#6f5f58; }

/* Booking form: buttons everywhere + locked identity lines
   (owner spec, Oct 17, 2026). */
.pill-btn { display:block; width:100%; padding:10px 6px; border:1.5px solid #d9a094; border-radius:999px; background:#fff; color:#8c4a3f; font-weight:700; font-size:.95rem; text-align:center; cursor:pointer; font-family:inherit; }
/* check87 (owner, Oct 20, 2026): a selected pill — service, time,
   length, status, kind — fills with the SAME bright yellow as a
   picked slot on the customer Book page (the shared --sel-yellow
   above); the old brown fill is gone so the two books read alike. */
.pill-btn.sel { background:var(--sel-yellow); border-color:var(--sel-border); color:var(--sel-ink); box-shadow:0 4px 14px rgba(230,207,30,.45); }
.pill-btn.time-btn.taken { background:#f1ecea; border-color:#ddd0cb; color:#97837b; }
.pill-btn.time-btn.taken.sel { background:var(--sel-yellow); border-color:var(--sel-border); color:var(--sel-ink); }
/* check87: a start time inside a both-workers block — disabled,
   greyed, and labeled; it cannot be tapped at all. */
.pill-btn.time-btn.blocked { background:#e9e4e1; border-color:#d8cfc9; color:#9a8f8a; cursor:not-allowed; box-shadow:none; }
.pill-btn .blocked-tag { display:block; font-size:.68rem; font-weight:800; letter-spacing:.07em; text-transform:uppercase; }
.svc-grid { display:flex; flex-wrap:wrap; gap:8px; }
.svc-grid .pill-btn { flex:1 1 45%; width:auto; }
.svc-grid .pill-btn.wide { flex-basis:100%; }
.time-cols { display:flex; gap:10px; }
.time-col { flex:1; display:flex; flex-direction:column; gap:8px; }
.len-row { display:flex; gap:8px; }
.len-row .pill-btn { flex:1; width:auto; font-size:.92rem; }
.status-row { display:flex; gap:8px; }
.status-row .pill-btn { flex:1; width:auto; }
.locked-line { font-size:1.05rem; margin:0 0 12px; }
.locked-line .lab { color:#6f5f58; }
.locked-line .val { font-weight:800; }

/* check92 (owner, Oct 20, 2026): the Edit screen's top runs tight —
   the name card, the phone line, the Personal note and the service
   pills sit close together with minimal card padding and gaps.
   Only the top of the screen changes; everything below the
   services keeps the standard field spacing. */
.form-card.card-tight { padding: 14px 16px; }
/* check178 item 10 (owner, Oct 26, 2026, 9:15 PM): the ASK block
   on /Book — a trusted customer with an upcoming appointment is
   asked whether she needs another one before the form opens. */
.another-ask { margin-top: 18px; text-align: center; }
.another-ask-line { margin: 0 0 6px; }
.another-ask-q { margin: 0 0 14px; font-weight: 600; }
.another-ask-btns { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }
.another-ask-btns .btn { min-height: 44px; padding: .55em 1.2em; display: inline-flex; align-items: center; justify-content: center; white-space: nowrap; }
.another-ask-btns .another-no { background: #fff; border: 1.5px solid var(--rose); color: var(--charcoal); font-weight: 600; box-shadow: 0 3px 10px rgba(150,85,95,.10); }
.another-ask-btns .another-no:hover { background: var(--rose-soft); }
.form-card.edit-card { padding-top: 16px; }
.edit-card .locked-line { margin-bottom: 4px; }
.edit-card .top-field { margin-bottom: 10px; }
.newflag { margin:10px 0 0; font-weight:700; color:#8c4a3f; }
.src-line { font-size:.78rem; color:#a08d84; }

/* Customer-booked cells stood out bright red (owner spec, Oct 17,
   2026) until check194 (owner, Oct 27, 2026): the red was
   "overwhelming," so online-customer cells now wear Sample H
   butter gold (mockups/book-online-color-samples2.html) with the
   sample's warm dark-brown ink; admin cells keep the soft tint.
   No text label. The white mark dot's ring goes back to its own
   dark ring — the white ring only read on red. */
.book-grid td.book-appt-customer { background:#f9eac0; }
.book-grid td.book-appt-customer a { color:#71500f; }
.book-grid td.book-appt-customer .cdot-white { border-color:#2b2320; }
/* Every open cell is a tap target into Add Booking for that slot. */
.book-grid td.cell-free { padding:0; }
.book-grid td.cell-free a { display:block; width:100%; height:100%; min-height:34px; padding:6px; box-sizing:border-box; text-decoration:none; position:relative; }
/* check125 (Oct 24, 2026): the empty-cell plus carries the SAME box
   as .cell-plus (7px 11px padding inside the same top/right inset), so
   its glyph lands on the exact x/y a Starts or Closed cell's plus
   glyph occupies — before, the bare glyph sat 11px right and 7px
   higher than the .cell-plus glyphs and the column's pluses did not
   read as one vertical line ("Plus sign not lined up vertically"). */
.book-grid td.cell-free .plus { position:absolute; top:2px; right:6px; padding:7px 11px; color:#d9a094; font-weight:800; font-size:27px; line-height:1; }
.book-grid td.cell-free a:hover { background:#fdf0ec; }
/* Delete-customer checkbox gate. */
.confirm-line { display:flex; gap:10px; align-items:flex-start; font-size:.98rem; margin:0 0 12px; cursor:pointer; }
.confirm-line input { width:22px; height:22px; flex:none; margin-top:1px; accent-color:#b3261e; }
.btn[disabled] { opacity:.45; cursor:not-allowed; }

/* Double-booking: booked cells carry a + too, into Add Booking for
   the same day and start time. */
.book-grid td.book-appt { position:relative; }
.book-grid .cell-plus { position:absolute; top:2px; right:6px; font-weight:800; font-size:27px; line-height:1; color:#c08552; text-decoration:none; z-index:2; padding:7px 11px; }
.book-grid td.book-appt-customer .cell-plus { color:#71500f; }
/* check121 (owner, Oct 24, 2026): the plus grows up (27px glyph,
   ~40px tap box — the same size lands on the empty-cell plus
   above, so every "+" in the grid reads and taps alike), and a
   cell spanning several half-hour rows carries one plus PER row:
   the .cell-plus-row modifier drops the shared component to the
   covered row's own top edge, the offset arriving as the --pt
   percentage of the cell's height (the grid's own proportional
   math). */
.book-grid .cell-plus-row { top:calc(var(--pt, 0%) + 2px); }

/* Stacked appointments inside one book cell (double bookings). */
.book-grid .appt-block { display:block; }
/* Bookings that share a slot sit side by side on one line, the cell split
   by a vertical divider, so the owner sees they come at the same time
   (owner, Oct 17, 2026). */
.book-grid .appt-stack { display:flex; }
.book-grid .appt-stack .appt-block { flex:1 1 0; min-width:0; }
.book-grid .appt-stack .appt-block + .appt-block { border-left:1.5px solid rgba(120,80,60,.35); margin-left:7px; padding-left:7px; }
/* Odd-minute starts (only the owner can enter them) sit in bright yellow
   cells: the minutes before the hour are dead waiting time (owner, Oct 17, 2026). */
.book-grid td.book-appt-odd { background:#ffe93c; }
/* Customer color marks used to sit in the cell's lower right corner
   (one per appointment, so one person could show two dots); check87
   moved the dot into the card, inline after the name — see the
   .appt-card rules below. */
/* Second line of a booking: start time on the left, the service circles on
   the right — one circle per service, in its own color (owner, Oct 17, 2026). */
.book-grid .appt-line2 { display:flex; justify-content:space-between; align-items:center; margin-top:2px; }
.book-grid .p-note { display:block; font-size:.8rem; }
.cust-head { margin:2px 0 10px; }
.cust-head .cust-name { font-size:1.45rem; font-weight:700; line-height:1.25; }
.cust-head .cust-phone { font-size:1rem; color:#8a7a72; margin-top:2px; }
/* check221 (owner, Oct 28, 2026): the customer's two settings move
   onto the NAME line, right side of the name.
   check222 (owner, Oct 28, 2026): both settings are CHECKBOXES
   whose labels say what they do — "Allow Multiple Bookings" and
   "Must pay deposit to book appointment" — each in its own
   auto-submitting form, side by side in the space beside the
   name. The green box is the multiple-bookings one, the red box
   the deposit one. */
.cust-head .name-row { display:flex; gap:10px; align-items:center; }
.cust-head .name-row .cust-name { flex:0 0 auto; }
/* check224 (owner, Oct 28, 2026, 10:54 PM — "Do a left alignment,
   but move them all the way to the right and make 2 lines"): the
   two checkboxes stack in TWO LINES as one block pushed ALL the
   way right; inside the block the labels are LEFT-aligned, so
   both checkbox squares share one column edge. */
.cust-head .head-checks { display:flex; flex-direction:column; gap:8px; margin-left:auto; flex:0 0 auto; }
.cust-head .head-checks form { flex:none; display:flex; margin:0; align-items:center; }
.cust-head .multi-book, .cust-head .deposit-box { display:flex; align-items:center; gap:8px; font-weight:600; font-size:.95rem; line-height:1.2; cursor:pointer; }
.cust-head .multi-book input, .cust-head .deposit-box input { width:24px; height:24px; flex:0 0 auto; margin:0; }
.cust-head .multi-book input { accent-color:#2e9e4f; }
.cust-head .deposit-box input { accent-color:#b3261e; }
.cust-tabs { display:flex; gap:8px; margin:0 0 18px; }
.cust-tabs a { flex:1; text-align:center; padding:12px 0; font-size:1.05rem; font-weight:700; border-radius:12px; border:2px solid var(--rose); color:var(--rose-deep); background:#fff; text-decoration:none; }
.cust-tabs a.on { background:var(--rose); color:#fff; }
.vlog-line { padding:9px 2px; border-bottom:1px solid #f0e4df; font-size:.97rem; line-height:1.45; }
.vlog-line a.vlog-link { display:block; color:inherit; text-decoration:none; }
.vlog-line:last-child { border-bottom:none; }
.vlog-line .coin { width:19px; height:19px; border-radius:50%; display:inline-flex; align-items:center; justify-content:center; color:#fff; font-family:Arial, sans-serif; font-weight:800; font-size:11px; vertical-align:-4px; margin:0 1px; }
.vlog-line .coin-N { background:#22c55e; }
.vlog-line .coin-P { background:#e75480; }
.vlog-line .coin-W { background:#7c3aed; }
.vlog-line .coin-F { background:#7c3aed; }
.vlog-line .coin-M { background:#e75480; }
.vlog-line .coin-G { background:#22c55e; }
.book-grid .svc-coins { display:flex; gap:3px; }
.book-grid .coin { width:21px; height:21px; border-radius:50%; display:inline-flex; align-items:center; justify-content:center; color:#fff; font-family:Arial, sans-serif; font-weight:800; font-size:12px; border:1.5px solid rgba(255,255,255,.9); box-shadow:0 0 0 1px rgba(0,0,0,.18); flex:none; }
.book-grid .coin-N { background:#22c55e; }
.book-grid .coin-note { background:#e9a13b; }
.book-grid .coin-note svg { width:11px; height:11px; display:block; }
.book-grid .coin-P { background:#e75480; }
.book-grid .coin-W { background:#7c3aed; }
.book-grid .coin-F { background:#7c3aed; }
.book-grid .coin-M { background:#e75480; }
.book-grid .coin-G { background:#22c55e; }
.book-grid td.has-plus { position:relative; }

/* Custom time: the last option under the start-time buttons. */
.custom-time { margin-top:10px; border:1.5px solid #d9a094; border-radius:14px; padding:10px 12px; display:flex; align-items:center; gap:12px; background:#fff; }
.custom-time.sel { background:var(--sel-yellow); border-color:var(--sel-border); color:var(--sel-ink); }
.custom-time label { font-weight:700; margin:0; white-space:nowrap; }
.custom-time input { flex:1; padding:8px; font-size:1.05rem; border:1.5px solid #d9a094; border-radius:10px; font-family:inherit; background:#fff; color:#3d2c29; }

/* Quick entry: type a line, Verify shows what it means, Add to Book
   writes it. */
.qe-card { background:#fff; border:1.5px solid #e8cfc8; border-radius:16px; padding:16px; margin:0 0 14px; }
.qe-card h3 { margin:0 0 12px; font-size:1.15rem; }
.qe-row { display:flex; gap:10px; }
.qe-row input { flex:1; min-width:0; padding:13px 14px; font-size:1.05rem; border:1.5px solid #d9a094; border-radius:999px; font-family:inherit; background:#fff; color:#3d2c29; }
.qe-row .btn { flex:none; padding:13px 22px; }
.qe-verified { margin-top:14px; border:1.5px solid #b7d3a8; background:#f3f9ef; border-radius:14px; padding:12px 14px; }
.qe-verified .ok { color:#3e7a2e; font-weight:700; }
.qe-verified .who { font-size:1.12rem; font-weight:700; margin:4px 0 2px; }
.qe-verified .what { margin:0; color:#5a4640; }
.qe-problem { margin-top:14px; border:1.5px solid #d9a094; background:#fdf0ec; border-radius:14px; padding:12px 14px; color:#8c3a2b; font-weight:600; }
.qe-add { width:100%; margin-top:14px; padding:15px; font-size:1.1rem; }

.qe-pick { margin-top:14px; }
.qe-pick-title { font-weight:700; margin:0 0 6px; }
.qe-what { margin:0 0 10px; color:#5a4640; }
.qe-pick form { margin:0 0 8px; }
.qe-more { margin:2px 0 0; color:#6f5f58; font-size:.95rem; }
.qe-pick-btn { width:100%; display:block; text-align:left; padding:13px 14px; font-size:1.05rem; font-family:inherit; background:#fff; border:1.5px solid #d9a094; border-radius:12px; color:#3d2c29; cursor:pointer; box-sizing:border-box; }
.qe-pick-phone { font-weight:700; white-space:nowrap; }
.qe-new { margin-top:14px; }
.qe-new input[type="text"], .qe-new input[type="tel"] { width:100%; box-sizing:border-box; padding:12px 14px; font-size:1.05rem; border:1.5px solid #d9a094; border-radius:12px; font-family:inherit; background:#fff; color:#3d2c29; margin:0 0 10px; }
/* Owner candidate/search rows (Oct 20, 2026): ONE format for Quick
   Entry candidates and admin customer search — mark dot + name +
   phone on the top line, personal note under the name, a booking
   line (Quick Entry only), then the last two visits under a divider.
   A section is simply absent when she has none. Rows sort with
   future visits first (soonest at the very top), then most visits,
   a personal note as tiebreak, then the most recent visit. */
.cr-main { display:block; flex:1; min-width:0; }
.cr-top { display:flex; align-items:center; }
.cr-name { font-weight:700; }
.cr-phone { margin-left:auto; font-weight:700; white-space:nowrap; padding-left:10px; }
.cr-line { display:block; font-weight:600; margin-top:2px; }
.cr-div { display:block; border-top:1px solid #ecd9d3; margin:8px 0 6px; }
.cr-hist { display:flex; align-items:center; gap:5px; color:#6f5f58; font-size:.92rem; margin-top:3px; }
.cr-hist .coin { width:19px; height:19px; border-radius:50%; display:inline-flex; align-items:center; justify-content:center; color:#fff; font-family:Arial, sans-serif; font-weight:800; font-size:11px; flex:none; }
.cr-hist .coin-N { background:#22c55e; }
.cr-hist .coin-G { background:#22c55e; }
.cr-hist .coin-M { background:#e75480; }
.cr-hist .coin-P { background:#e75480; }
.cr-hist .coin-W { background:#7c3aed; }
.cr-hist .coin-F { background:#7c3aed; }
.qe-pick-btn .p-note, .qe-pick-btn .cr-line, .qe-pick-btn .cr-hist { margin-left:21px; }
.qe-pick-btn .cr-div { margin-left:21px; }
.qe-pick-btn .p-note { display:block; }
.pick-row .cr-main .p-note, .pick-row .cr-main .cr-hist { margin-left:21px; }
.pick-row .cr-main .cr-div { margin-left:21px; }

/* Repeat row on the owner booking form (owner spec, Oct 18, 2026). */
.repeat-row { display:flex; align-items:center; gap:10px; font-size:1.05rem; flex-wrap:nowrap; }
.repeat-check { display:flex; align-items:center; gap:8px; font-weight:600; cursor:pointer; white-space:nowrap; }
.repeat-check input[type="checkbox"] { width:24px; height:24px; accent-color:#b5654d; }
.repeat-weeks { padding:9px 10px; font-size:1.05rem; font-family:inherit; border:1.5px solid #d9a094; border-radius:10px; background:#fff; color:#3d2c29; flex:1; min-width:0; }

/* Past days in the book (owner spec, Oct 18, 2026): yesterday and older
   get a very light grey wash so today and newer stand out. Online-booking
   cells in the past give up their white text so names stay readable. */
.book-grid td.day-past, .book-grid th.day-past { background:#f3f1f0; }
.book-grid td.book-appt-customer.day-past a { color:#3d2c29; }
.book-grid td.book-appt-customer.day-past .cdot-white { border-color:#b9a89f; }

/* Customer booking page, Step 1: each service button carries its coin
   (owner, Oct 19, 2026); Wax sits on its own line. */
.book-svc .slot { display:flex !important; flex-direction:row !important; align-items:center !important; flex-wrap:nowrap; white-space:nowrap; justify-content:flex-start; min-height:0; height:52px; padding:0 9px 0 7px; border-radius:999px; gap:6px; text-align:left; }
/* check87 (owner, Oct 20, 2026): the customer pickers speak the
   admin book's language — the same pill border, ink, and weight as
   .pill-btn, and the time slots sit in the admin's two-column pill
   grid. Selected on both pages is the shared bright yellow. */
.book-svc .slot { border-color:#d9a094; color:#8c4a3f; font-weight:700; }
.slot-grid.time-grid { grid-template-columns:1fr 1fr; }
.time-grid .slot { border-radius:999px; border-color:#d9a094; color:#8c4a3f; font-weight:700; min-height:0; padding:10px 6px; }
.time-grid .slot.full { background:#f4efec; color:var(--muted); font-weight:500; }
.book-svc .svc-name { white-space:nowrap; font-size:.875rem; letter-spacing:-.02em; }
.book-svc .coin { width:22px; height:22px; font-size:.8rem; }
.form-card:has(.book-svc) { padding-left:12px; padding-right:12px; }
.book-svc .coin { width:26px; height:26px; border-radius:50%; color:#fff; font-weight:700; font-size:.85rem; display:inline-flex; align-items:center; justify-content:center; flex:0 0 auto; }
.book-svc .coin-N { background:#22c55e; }
.book-svc .coin-G { background:#22c55e; }
.book-svc .coin-M { background:#e75480; }
.book-svc .coin-P { background:#e75480; }
.book-svc .coin-W { background:#7c3aed; }
.book-svc .coin-F { background:#7c3aed; }
.svc-grid.book-svc { display:grid; grid-template-columns:1fr 1fr; }
.svc-btn { display:flex; align-items:center; justify-content:flex-start; gap:6px; height:52px; padding:0 9px 0 7px; white-space:nowrap; text-align:left; font-size:.875rem; letter-spacing:-.02em; }
.svc-btn .coin { width:26px; height:26px; border-radius:50%; color:#fff; font-family:Arial, sans-serif; font-weight:700; font-size:.85rem; display:inline-flex; align-items:center; justify-content:center; flex:0 0 auto; }
.svc-btn .coin-N { background:#22c55e; }
.svc-btn .coin-G { background:#22c55e; }
.svc-btn .coin-M { background:#e75480; }
.svc-btn .coin-P { background:#e75480; }
.svc-btn .coin-W { background:#7c3aed; }
.svc-btn .coin-F { background:#7c3aed; }

/* check85 (owner, Oct 20, 2026) — Book grid: each appointment card is
   positioned and sized by its OWN times inside the cell's full span
   (a 1-hour booking sharing a cell with a later-starting one no
   longer stretches to the later end), and NoShow appointments stay in
   the book, gray and struck through, as the day's record. Everything
   below is additive and scoped to Starts cells (.has-area / .appt-card);
   no earlier rule is changed. The cell's own background goes neutral —
   the color now lives on each card, so the free part of a shared cell
   reads as free time; past days keep their wash over cards and cell. */
.book-grid td.has-area { background:#fff; }
.book-grid td.has-area.day-past { background:#f3f1f0; }
.book-grid .appt-area { position:absolute; inset:0; }
.book-grid .appt-card { position:absolute; box-sizing:border-box; overflow:hidden; padding:7px 9px; background:#fbeef1; }
.book-grid .appt-card.lane-sep { border-left:1.5px solid rgba(120,80,60,.35); }
.book-grid .appt-card.card-odd { background:#ffe93c; }
/* check194: the online-customer card itself takes the same Sample
   H butter gold + warm dark-brown ink as its cell above. */
.book-grid .appt-card.card-customer { background:#f9eac0; color:#71500f; }
/* check200 (owner, Oct 27, 2026): a card whose saved checkout
   holds a DISCOUNT renders BRIGHT RED — the acknowledgement
   banner's warning red #d92b20 — with white reading text, so a
   typo'd discount warns the admin at a glance. The sub-elements
   adapt like they did on the old red cards: the texted-grey
   check warms to a pale blush (the plain grey washes out on
   red), the personal-note line goes near-white, and the gold
   note pencil keeps its deep fill with a dark-warm ring. */
.book-grid .appt-card.card-discount { background:#d92b20; color:#fff; }
.book-grid .appt-card.card-discount .act-chk-grey { color:#ffc9c2; }
.book-grid .appt-card.card-discount .p-note { color:#ffe9e6; }
.book-grid .appt-card.card-discount .coin-note { background:#dd941f; box-shadow:inset 0 0 0 1.5px rgba(90,10,5,.45); }
.book-grid td.day-past .appt-card { background:#f3f1f0; }
.book-grid .appt-card .p-note { white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
/* No-show record: gray card, name struck through in red, red tag,
   dimmed service coins, and the visit note as a small pill. */
.book-grid .appt-card.card-noshow { background:#e8e4e2; color:#7c7270; }
.book-grid .appt-card .ns-name { text-decoration:line-through; text-decoration-thickness:2px; text-decoration-color:#c24545; }
/* The NO-SHOW pill is shared: book-grid cards, Quick Entry candidate
   rows, find-customer rows, and Visit Log lines all carry the same
   tag, so it is deliberately NOT scoped to .book-grid. */
.ns-tag { display:inline-block; background:#c24545; color:#fff; font-size:10.5px; font-weight:800; letter-spacing:.6px; padding:2.5px 7px; border-radius:20px; vertical-align:middle; margin-left:7px; }
/* Inside a visit line the pill sits inline right after the "N days ago"
   text (owner, Oct 20, 2026) — the flex row's own gap supplies most of
   the spacing, so the tag's left margin shrinks to match. */
.cr-hist .ns-tag { margin-left:2px; }
.book-grid .appt-card.card-noshow .coin { background:#a89a96; }
.book-grid .appt-card.card-noshow .p-note { color:#8a7a76; }
.book-grid .ns-note { display:inline-block; margin-top:5px; background:#fff; border:1px solid #d8cfcc; color:#6b565a; font-size:.78rem; font-style:italic; padding:2px 8px; border-radius:6px; max-width:100%; box-sizing:border-box; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }

/* ---------- check86: deposit gate (Oct 20, 2026) ---------- */
/* The deposit pills on book-grid cards share the NO-SHOW pill's
   metrics so the two tags sit alike on a card: amber while a deposit
   is owed, green once it is on file to credit at the visit. */
.dep-tag { display:inline-block; background:#8a6d1d; color:#fff; font-size:10.5px; font-weight:800; letter-spacing:.6px; padding:2.5px 7px; border-radius:20px; vertical-align:middle; margin-left:7px; }
.dep-tag-paid { background:#3e7d4e; }
/* check216 (owner, Oct 28, 2026 — sample mockups/restricted-bookcard-sample.html):
   the RESTRICTED tag — ONE pill before the name on a restricted-list
   customer's Book card, carrying the appointment's confirmation state
   ("Restricted, confirmed" / "Restricted, unconfirmed"). It is the
   FIRST item of the name line; a card wearing it also carries
   .card-restricted so the line may wrap (see the rule by the
   card-trusted wrap below). */
.rstr-tag { flex:none; display:inline-flex; align-items:center; background:#f6d9d2; border:1.5px solid var(--rose); color:var(--rose-deep); font-size:10.5px; font-weight:700; letter-spacing:.02em; padding:2px 7px; border-radius:999px; line-height:1.25; }

/* ---------- check97: new-online-booking beep alert (Oct 24, 2026) ---------- */
/* The unacknowledged online booking's card: a red outline drawn
   INSIDE the card's own box (outline-offset pulls it in, so the
   card's geometry — measured by the alignment proofs — never
   moves) plus the shared-metrics NEW pill. Both clear the moment
   the owner acknowledges the booking (BookingAlert / AdminAckAt). */
.book-grid .appt-card.card-new { outline:2.5px solid #d92b20; outline-offset:-2.5px; }
.new-tag { display:inline-block; background:#d92b20; color:#fff; font-size:10.5px; font-weight:800; letter-spacing:.6px; padding:2.5px 7px; border-radius:20px; vertical-align:middle; margin-left:7px; }
/* The banner itself, in the approved sample's language: alarm red,
   bell + NEW ONLINE BOOKING, who/when/what, and one big white
   Acknowledge button. One banner per alerting booking. */
.booking-alert { background:#d92b20; color:#fff; border-radius:14px; padding:14px 16px; margin:14px 0 6px; box-shadow:0 4px 14px rgba(217,43,32,.35); }
.booking-alert .ba-row { display:flex; align-items:center; gap:10px; }
.booking-alert .ba-bell { flex:0 0 auto; width:30px; height:30px; }
.booking-alert .ba-title { font-size:20px; font-weight:800; letter-spacing:.3px; }
.booking-alert .ba-detail { font-size:17px; margin-top:7px; line-height:1.35; }
.booking-alert .ba-beep { font-size:14.5px; margin-top:5px; font-style:italic; opacity:.95; }
.booking-alert .ba-ack { display:block; width:100%; margin-top:11px; background:#fff; color:#b11a10; border:none; border-radius:12px; font-size:19px; font-weight:800; padding:13px 0; cursor:pointer; }
.booking-alert .ba-ack:disabled { opacity:.6; }
/* The SOUND chip in the admin bar: quiet gray while off, the
   sample's green while armed. One tap arms the beep (browser audio
   rules); the choice persists in localStorage. */
.sound-chip { font:inherit; font-size:14px; font-weight:800; letter-spacing:.4px; background:#e8e2dc; color:#6b6259; border:none; border-radius:999px; padding:6px 14px; cursor:pointer; white-space:nowrap; }
.sound-chip.on { background:#2e7d46; color:#fff; }
/* A deposit-Pending card: warm stripes + a dashed rose outline —
   visibly "not a real booking yet" beside the normal cards. It is
   purely a display treatment; a Pending appointment consumes no
   chair in any availability math. */
.book-grid .appt-card.card-deposit { background:repeating-linear-gradient(45deg,#fdf3ec,#fdf3ec 10px,#f8e7de 10px,#f8e7de 20px); outline:2px dashed #b76e79; outline-offset:-2px; }

/* The public deposit step (/Deposit): summary + terms boxes in the
   salon's card language, the pay button full-width like the sample. */
.dep-summary { background:var(--blush); border:1px solid var(--rose-soft); border-radius:12px; padding:14px 16px; margin-bottom:16px; }
.dep-summary p { margin:0; }
.dep-terms { background:#fdf6ec; border:1px solid #ecd9ac; border-radius:12px; padding:14px 16px; margin-bottom:18px; }
.dep-samename { margin-bottom:10px; }
.dep-pay { width:100%; font-size:1.08rem; }

/* Notes-list edit pen (check86 addition): the same round icon-button
   metrics as the row's red delete X, in neutral ink; while editing
   the pen is the save button and turns green. */
.note-pen { width:24px; height:24px; line-height:20px; text-align:center; border-radius:50%; border:1.5px solid #7d7169; color:#7d7169; background:#fff; font-weight:bold; font-size:13px; padding:0; cursor:pointer; vertical-align:top; }
.note-pen.saving { border-color:#3e7d4e; color:#3e7d4e; }
.note-edit-input { width:100%; box-sizing:border-box; font:inherit; padding:6px 8px; border:1.5px solid var(--rose); border-radius:8px; }

/* ---------- check93 (Oct 20, 2026) ---------- */
/* The shared notes component (_NoteList): one list on every surface
   that shows a customer's notes — the appointment screen's "Notes
   for …" card and the profile's Visit Log render the same table,
   the same controls, the same spacing. The action column carries
   the pen and the ✕ side by side at phone width. */
.note-list .log-table .note-actions { width:58px; text-align:right; white-space:nowrap; }
.note-list .note-act-form { margin:0; display:inline-block; vertical-align:top; }
/* The component's delete/hide X: the exact metrics the note rows'
   inline-styled ✕ buttons used before check93, now one class. */
.note-list .note-x { width:24px; height:24px; line-height:20px; text-align:center; border-radius:50%; border:1.5px solid #b3261e; color:#b3261e; background:#fff; font-weight:bold; font-size:13px; padding:0; cursor:pointer; vertical-align:top; }
/* A derived line's pen is a LINK (it opens the appointment the line
   comes from) wearing the pen's round button look. */
.note-list a.note-open { display:inline-block; box-sizing:border-box; text-decoration:none; }
/* check193: the All Notes / Visits Only toggle in the NOTE header's
   place — two small pills wearing the visit-pill metrics (solid
   rose = the view in force, outlined = the other one). They sit
   inside a <th>, so they opt out of its uppercase header styling. */
.note-list .note-view-toggle { display:inline-flex; gap:6px; text-transform:none; letter-spacing:0; }
.note-list .nvt-btn { font-family:inherit; font-size:.78rem; font-weight:700; line-height:1.2; padding:3px 10px; border-radius:20px; border:1.5px solid var(--rose); background:#fff; color:var(--rose-dark); cursor:pointer; white-space:nowrap; }
.note-list .nvt-btn.is-on { background:var(--rose); color:#fff; }
/* The visit-history chips' hide ✕ (owner search, Edit pickers,
   Quick Entry): quiet until tapped, in the delete red. */
.cr-hist .hist-x { color:#b3261e; font-weight:bold; font-size:12px; margin-left:5px; cursor:pointer; }

/* ---------- check87 (Oct 20, 2026) ---------- */
/* Split-cell block display: when only ONE worker is blocked at an
   empty cell, that worker's half of the cell fills with his/her
   Block Hours color (Steven green #1ed760 left, Tracy pink #ff4fa0
   right — the settled check77 colors, also used on the Block Hours
   page). It is a visual layer inside the existing single table
   cell: it never intercepts taps, so the cell's + still books the
   free chair, and no table structure changed. */
.book-grid .cell-halves { position:absolute; inset:0; display:flex; pointer-events:none; }
.book-grid .cell-halves .half { flex:1; position:relative; }
.book-grid .cell-halves .half-s.on { background:#1ed760; }
.book-grid .cell-halves .half-t.on { background:#ff4fa0; }
.book-grid .cell-halves .half-lab { position:absolute; top:2px; font-size:.68rem; font-weight:800; color:rgba(0,0,0,.55); }
.book-grid .cell-halves .half-s .half-lab { left:5px; }
.book-grid .cell-halves .half-t .half-lab { right:5px; color:rgba(255,255,255,.85); }
/* ---------- check88 (Oct 20, 2026) ---------- */
/* Blocked-half tap targets: transparent overlays above the split
   cell's Add-booking anchor, one per blocked half. Tapping the
   blocked half opens that day's Block Hours page (edit/remove the
   block); tapping the free half still hits the anchor underneath
   and books the free chair. The colored .cell-halves layer above
   stays visual only. (In a Tracy-out cell the overlay also covers
   the little + glyph's corner — that corner is inside her blocked
   half, so it goes to Block Hours too; the glyph stays visible
   through the transparent overlay.) */
.book-grid .half-hit { position:absolute; top:0; bottom:0; width:50%; z-index:3; display:block; }
.book-grid .half-hit-s { left:0; }
.book-grid .half-hit-t { right:0; }
.book-grid .half-hit:hover { background:rgba(0,0,0,.07); }
/* ---------- check91 (Oct 20, 2026) ---------- */
/* Split-cell tap-target FIX. The check88 rules above never took
   effect: the overlays are <a> elements inside td.cell-free, so the
   generic cell anchor rule (.book-grid td.cell-free a — specificity
   0,2,2) beat .book-grid .half-hit (0,2,0) on every shared property.
   The overlays computed to position:relative / width:100% /
   min-height:34px / padding:6px and rendered IN FLOW, stacked below
   the cell's Add-booking anchor: the visible green/pink half of the
   cell hit-tested to Add booking, and the Block Hours targets sat
   displaced over the rows underneath (owner's live report, Oct 20:
   "the link of the splitted cells are wrong... the link of the below
   in the cell is correct"). The rules below restate every contested
   property at 0,3,2 so the overlay wins: absolutely positioned over
   exactly its half of the cell, full cell height, no padding. The
   :active rules keep the pressed half in the worker's own color —
   before this fix a press-and-hold landed on the anchor underneath
   and its :hover wash painted the half back to the default cell
   color. */
.book-grid td.cell-free a.half-hit { position:absolute; top:0; bottom:0; width:50%; height:auto; min-height:0; padding:0; z-index:3; -webkit-tap-highlight-color:transparent; }
.book-grid td.cell-free a.half-hit-s { left:0; right:auto; }
.book-grid td.cell-free a.half-hit-t { right:0; left:auto; }
.book-grid td.cell-free a.half-hit-s:active { background:rgba(30,215,96,.45); }
.book-grid td.cell-free a.half-hit-t:active { background:rgba(255,79,160,.45); }
/* check91 item 8 (owner, Oct 20, 2026): the customer color dot moves
   from directly after the name (an orange dot read as part of the
   name — "HigdonO") to the RIGHT side of the card, next to the
   cell's "+" sign. The name line becomes a flex row; the dot slot is
   pushed to the right edge, and the line keeps 14px of right
   padding so the dot stops just left of the "+" (which floats at
   the cell's top-right corner) instead of sliding under it. Still
   exactly ONE dot per card — only its position changed. */
.book-grid .appt-card .card-line1 { display:flex; align-items:center; gap:6px; padding-right:14px; }
.book-grid .appt-card .card-line1 strong { min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
/* check121 (owner, Oct 24, 2026) SUPERSEDES the check91 item 8 /
   check103 placements narrated around this block: "Put color code
   and yellow note icon at the end of the name." The dot span moves
   INSIDE the name's <strong>, immediately after the name text, so
   it is no longer pushed to the line's right edge (the
   margin-left:auto it carried is gone) — it follows the end of
   the name wherever that falls, and on a wrapped lane-card name
   it lands after the last word. The 14px right padding stays:
   with check121's bigger cell plus floating at the cell's
   top-right, the reserve keeps long name ink from sliding under
   the glyph. The two markers ride in one .name-marks cluster
   (white-space:nowrap) so that when the cluster wraps to the
   name's next line it wraps TOGETHER — the pencil never drops
   to a line of its own. */
.book-grid .appt-card .name-marks { white-space:nowrap; }
.book-grid .appt-card .card-dot { display:inline-flex; margin-left:5px; vertical-align:middle; }
.book-grid .appt-card .card-dot .cdot { margin-right:0; }
/* check157 (owner, Oct 25, 2026): the activation check rides in
   the same name-marks cluster, BETWEEN the color dot and the note
   pencil (name → dot → check → pencil — his mockup): GREY once
   her confirmation has been texted and she has not clicked the
   link, BLUE once she has. Admin-booked appointments only; the
   span is simply absent otherwise. */
.book-grid .appt-card .act-chk { display:inline-block; margin-left:5px; font-size:15px; font-weight:900; line-height:1; vertical-align:1px; }
.book-grid .appt-card .act-chk-grey { color:#b9b0aa; }
.book-grid .appt-card .act-chk-blue { color:#2f7fd0; }
/* check228 (owner, Oct 29, 2026): the check210 trusted-heart
   rules are removed with the Book heart icon itself. The
   shared .name-marks layout and the .card-trusted wrap rule
   below stay, so the name → dot → pencil line is unchanged. */
/* check217 (owner, Oct 28, 2026): the RESTRICTED "!" rides the
   name line's FRONT — a red disc with a white exclamation,
   immediately before the name text (the name-line icon size
   family, the same warning red #d92b20; the disc and mark are drawn
   inside the one inline SVG, so it renders identically on
   every device). Visual only — it sits inside the card's one
   anchor and is never a tap target of its own. */
.book-grid .appt-card .card-bang { display:inline-flex; margin-right:5px; vertical-align:middle; }
.book-grid .appt-card .card-bang svg { width:15px; height:15px; display:block; }
/* check194: on the butter-gold customer card the pale grey check
   washed out, so there it takes a muted warm taupe — the same
   "texted, not yet opened" reading, visible on gold. The gold
   Note-to-Salon pencil coin likewise gets a deeper fill and a
   dark-warm ring so it still reads as a coin on the gold ground.
   (The blue check keeps its blue — it reads fine on gold.) */
.book-grid .appt-card.card-customer .act-chk-grey { color:#9a8659; }
.book-grid .appt-card.card-customer .coin-note { background:#dd941f; box-shadow:inset 0 0 0 1.5px rgba(113,80,15,.55); }
/* A merged same-person card lists its services on one line under
   the name (both services together, never a second card). */
.book-grid .appt-card .appt-svcs { display:block; font-size:.82rem; font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }

/* check102 (owner, Oct 22, 2026): the compact fit for SPLIT cards
   only (.lane-card — every card in a multi-entry overlap group; a
   half card is ~58px wide at the real week-grid column width, where
   check101's nowrap name shrank to one letter). Tighter padding,
   the name wraps word by word instead of ellipsizing, and the
   service WORDS drop out — the service coins on line 2 stay and
   carry the services. The .p-note identity line and line 2 are
   untouched, and full-width cards match none of these selectors,
   so they render exactly as before. */
.book-grid .appt-card.lane-card { padding:6px 7px; }
.book-grid .appt-card.lane-card .card-line1 strong { white-space:normal; overflow:visible; text-overflow:clip; font-size:13.5px; line-height:1.25; }
/* check210: a TRUSTED card's name line wraps like a lane
   card's, so the dot / pencil cluster drops under the name
   intact instead of being ellipsis-clipped on a narrow
   column. Only trusted cards carry .card-trusted; every
   other card renders exactly as before. */
.book-grid .appt-card.card-trusted .card-line1 strong { white-space:normal; overflow:visible; text-overflow:clip; }
/* check216: a RESTRICTED card's name line wraps like a trusted
   card's — the .rstr-tag (above) is long, so at phone width it
   takes its own line and the name + dot + check cluster
   drops under it intact, exactly as the approved sample renders.
   Only restricted cards carry .card-restricted. */
.book-grid .appt-card.card-restricted .card-line1 { flex-wrap:wrap; }
.book-grid .appt-card.card-restricted .card-line1 strong { white-space:normal; overflow:visible; text-overflow:clip; }
.book-grid .appt-card.lane-card .appt-svcs { display:none; }

/* check103 (owner, Oct 22, 2026): the split-card dot moves to the
   card's bottom-right corner (owner-approved after check102's rig
   proof: in a standard-width column the in-flow dot squeezed the
   name box to ~24px against ~45px of first name). .card-dot is the
   same span inside .card-line1; the card anchor is its positioned
   ancestor, so absolute positioning pins it to the corner, out of
   the name line's flow, and the name gets the half's full width.
   Full-width cards match none of this — their dot stays on the
   name line, exactly as check91 item 8 put it. The lane cards'
   line-2 row gains right padding so the rightmost service coin
   stops clear of the corner dot instead of sliding under it.
   The name line also gives up its 14px right reserve on lane
   cards: that reserve existed to park the in-flow dot left of
   the cell's "+" — with the dot in the corner the reserve only
   shrank the measured name box while the name's ink (overflow
   visible, per check102) painted across it anyway.
   check121 (owner, Oct 24, 2026) SUPERSEDES the corner placement
   itself: the absolute rule is gone, so the lane-card dot is back
   in the name line's flow at the end of the name, like every
   other card. The line-2 right padding is retained untouched —
   the strip simply keeps the breathing room it has today. */
.book-grid .appt-card.lane-card .card-line1 { padding-right:0; }
.book-grid .appt-card.lane-card .appt-line2 { padding-right:19px; }

/* check94 (owner, Oct 21, 2026): a card that landed through the quiet
   live update glows softly until it is viewed or ~75 seconds pass. */
.book-grid .appt-card.just-landed { z-index: 6; animation: newCardPulse 1.6s ease-in-out infinite alternate; }
@keyframes newCardPulse {
    from { box-shadow: 0 0 0 3px #f9a825, 0 0 10px 2px rgba(249, 168, 37, .55); }
    to   { box-shadow: 0 0 0 3px #f9a825, 0 0 20px 6px rgba(249, 168, 37, .9); }
}
.book-grid .new-pill { background: #f9a825; color: #222; font-size: 11px; font-weight: 800; border-radius: 10px; padding: 1px 7px; margin-left: 6px; white-space: nowrap; letter-spacing: .02em; }

/* check94: an appointment's own note under its "Booked by ..." line. */
.note-list .appt-note-text { display: block; }

/* check104 (owner, Oct 23, 2026): visitor pills on the Book admin
   bar — today's public-page visits (solid rose) and the all-time
   total (outlined), riding at the right of the "Appointment Book"
   title and wrapping under it on narrow screens. New classes only;
   nothing above this block changed. */
.visit-pills { display:inline-flex; align-items:center; gap:8px; flex-wrap:wrap; margin-left:auto; }
.visit-pill { display:inline-block; font-size:15px; font-weight:700; line-height:1.2; padding:6px 14px; border-radius:20px; white-space:nowrap; }
.visit-pill-today { background:#b76e79; color:#fff; }
.visit-pill-total { background:#fff; color:#96555f; border:1.5px solid #b76e79; padding:5px 14px; }

/* check147 (owner, Oct 24, 2026): the site-theme switch at the
   very bottom of the Book page, below the visitor pills — five
   pill options in the sound row's spirit, each carrying the old
   picker dot (.theme-dot-*) and its name; the active theme is
   ringed in rose. Owner's tool only: no public page renders it,
   and admin pages themselves carry no theme. The option rules
   are scoped under .book-theme-row on purpose: the dormant
   footer-picker rules further down this file use the bare
   .theme-opt name (pale text for its dark ground) and must
   never leak into this light-ground control. */
.book-theme-row { display:flex; justify-content:center; align-items:center; gap:8px; flex-wrap:wrap; margin:16px 0 4px; }
.book-theme-row .theme-opt { font:inherit; font-size:13.5px; font-weight:700; display:inline-flex; align-items:center; gap:7px; background:#fff; color:#6b6259; border:1.5px solid #e3d2cc; border-radius:999px; padding:6px 13px; cursor:pointer; white-space:nowrap; }
.book-theme-row .theme-opt:hover { border-color:#b76e79; }
.book-theme-row .theme-opt.active { background:#fdf3f0; color:#96555f; border-color:#b76e79; box-shadow:inset 0 0 0 1px #b76e79; }

/* ---------- check108 (owner, Oct 23, 2026) ---------- */
/* The appointment card's bottom strip, split between the two
   workers: Steven's service coins in the left half, Tracy's in the
   right, told apart by position alone — NO names or labels are
   printed (owner: "Do not put names on it. We know."). A
   shared-only entry's coins straddle the divider, centered on it.
   The strip bleeds to the card's side and bottom edges (the card's
   9px / 7px padding is cancelled by the negative margins) so the
   divider runs the strip's full height at the card's true center.
   New classes only; nothing above this block changed. */
/* check111 (owner, Oct 23, 2026): no line between the customer's
   name and the service — the strip's border-top is gone. The
   vertical divider between the two halves (.svc-half-t) stays. */
.book-grid .appt-card .svc-strip { display:flex; position:relative; box-sizing:border-box; margin:6px -9px -7px; min-height:27px; }
.book-grid .appt-card .svc-half { flex:1 1 0; min-width:0; display:flex; align-items:center; gap:3px; padding:3px 6px; }
/* check112 (owner, Oct 23, 2026, later the same evening): the
   strip's vertical divider is REMOVED — "Don't use small tiny
   vertical." The .svc-half-t border-left that stood here is
   gone; the two halves are told apart by the coins' positions
   alone, and a straddling coin sits at the center with nothing
   drawn under it. Everything else about the strip is as
   check108/check111 left it. */
/* check113: the .svc-straddle rule that lived here is gone with the
   straddle itself — coins are dealt by fixed worker now, so no coin
   ever sits on the divider (see the check113 block at the file's
   foot). */
/* On split (lane) cards the strip keeps the compact cards' own
   padding rhythm and stops short of the card's bottom edge, so its
   right half stays clear of the corner dot check103 parked at the
   bottom-right; the coins keep the standard 21px size — there are
   no labels to drop on short cards. */
.book-grid .appt-card.lane-card .svc-strip { margin:5px -7px 10px; }
/* The Note-to-Salon pencil leaves the coin row and rides at the
   TOP of the card: it takes the name line's auto margin so it sits
   in the right-hand cluster with the color dot, and the dot keeps
   its settled spot at the line's right edge (check91 item 8) with
   a 6px gap after the pencil.
   check121 (owner, Oct 24, 2026) SUPERSEDES the cluster: the
   pencil now sits INSIDE the name's <strong>, immediately after
   the color dot at the end of the name (name, dot, pencil), in
   every card form — the auto margin and the old pencil-then-dot
   sibling rule are gone. */
.book-grid .appt-card .card-line1 .coin-note { margin-left:5px; vertical-align:middle; }

/* ---------- check109 (owner, Oct 23, 2026) ---------- */
/* Phone only — the same max-width:640px breakpoint as the
   small-screen table layout above. Every 30-minute row of the
   Book grid renders TWICE as tall as before: a row measured
   40.55px in check108, driven by the Time cell that sits in
   every row, so the Time cell's height is set to exactly
   double (81.09px) and each row follows it. Cards are placed
   by percentage inside their cells, so they grow with the
   rows. Desktop widths never see this block. (Today's column
   width on phones is set by the Book page's sizing script,
   not here.) New block only; nothing above changed. */
@media (max-width: 640px) {
    .book-grid tbody th.book-time { height:81.09px; }
}

/* ---------- check111 (owner, Oct 23, 2026) ---------- */
/* Half-hour lines across the day columns. A Starts cell
   ROWSPANS its whole span and the rows inside it render no
   cell at all (Covered), so the per-cell bottom borders that
   draw every grid line elsewhere never exist at the :30
   boundaries inside a spanning cell — the Time gutter showed
   its lines (its cells never span) but the day columns did
   not. The lines are painted on the spanning cell itself: a
   tile one row tall (100%/rowspan of the cell's height)
   whose bottom pixel is the same 1px #e3d2cc line the cell
   borders use, repeated down the cell. Cards paint above
   the cell background, so a card covers the line where it
   sits — like the paper book's printed lines under a written
   entry. Only Starts cells ever span, and only they carry a
   rowspan attribute above 1. Nothing else changes: row
   heights, column widths and the gutter are untouched. */
.book-grid td.book-appt[rowspan="2"], .book-grid td.book-appt[rowspan="3"], .book-grid td.book-appt[rowspan="4"], .book-grid td.book-appt[rowspan="5"], .book-grid td.book-appt[rowspan="6"], .book-grid td.book-appt[rowspan="7"], .book-grid td.book-appt[rowspan="8"], .book-grid td.book-appt[rowspan="9"], .book-grid td.book-appt[rowspan="10"], .book-grid td.book-appt[rowspan="11"], .book-grid td.book-appt[rowspan="12"], .book-grid td.book-appt[rowspan="13"], .book-grid td.book-appt[rowspan="14"], .book-grid td.book-appt[rowspan="15"], .book-grid td.book-appt[rowspan="16"], .book-grid td.book-appt[rowspan="17"], .book-grid td.book-appt[rowspan="18"], .book-grid td.book-appt[rowspan="19"], .book-grid td.book-appt[rowspan="20"], .book-grid td.book-appt[rowspan="21"], .book-grid td.book-appt[rowspan="22"], .book-grid td.book-appt[rowspan="23"], .book-grid td.book-appt[rowspan="24"] { background-image:linear-gradient(to bottom, transparent calc(100% - 1px), #e3d2cc calc(100% - 1px)); background-repeat:repeat-y; }
.book-grid td.book-appt[rowspan="2"] { background-size:100% 50%; }
.book-grid td.book-appt[rowspan="3"] { background-size:100% 33.3333%; }
.book-grid td.book-appt[rowspan="4"] { background-size:100% 25%; }
.book-grid td.book-appt[rowspan="5"] { background-size:100% 20%; }
.book-grid td.book-appt[rowspan="6"] { background-size:100% 16.6667%; }
.book-grid td.book-appt[rowspan="7"] { background-size:100% 14.2857%; }
.book-grid td.book-appt[rowspan="8"] { background-size:100% 12.5%; }
.book-grid td.book-appt[rowspan="9"] { background-size:100% 11.1111%; }
.book-grid td.book-appt[rowspan="10"] { background-size:100% 10%; }
.book-grid td.book-appt[rowspan="11"] { background-size:100% 9.0909%; }
.book-grid td.book-appt[rowspan="12"] { background-size:100% 8.3333%; }
.book-grid td.book-appt[rowspan="13"] { background-size:100% 7.6923%; }
.book-grid td.book-appt[rowspan="14"] { background-size:100% 7.1429%; }
.book-grid td.book-appt[rowspan="15"] { background-size:100% 6.6667%; }
.book-grid td.book-appt[rowspan="16"] { background-size:100% 6.25%; }
.book-grid td.book-appt[rowspan="17"] { background-size:100% 5.8824%; }
.book-grid td.book-appt[rowspan="18"] { background-size:100% 5.5556%; }
.book-grid td.book-appt[rowspan="19"] { background-size:100% 5.2632%; }
.book-grid td.book-appt[rowspan="20"] { background-size:100% 5%; }
.book-grid td.book-appt[rowspan="21"] { background-size:100% 4.7619%; }
.book-grid td.book-appt[rowspan="22"] { background-size:100% 4.5455%; }
.book-grid td.book-appt[rowspan="23"] { background-size:100% 4.3478%; }
.book-grid td.book-appt[rowspan="24"] { background-size:100% 4.1667%; }

/* ---------- check112 (owner, Oct 23, 2026) — in-card lines REMOVED by check125 ---------- */
/* The half-hour lines used to run across the appointment CARDS too
   (one .card-grid-line span per grid boundary inside each card).
   check125 (owner, Oct 24, 2026) SUPERSEDES that setting: "Melissa
   takes 1 hour so there shouldn't be a line in the middle at 9:30."
   _BookCell.cshtml no longer emits the spans and the rule is gone —
   a card's face is clean. The :30 lines across the columns' EMPTY
   space (check111's cell background tiles and the row lines) are
   untouched. isolation stays: the card is still its own stacking
   context so the check113 .svc-fill spans (z-index:-1) park above
   the card's background but below its text and coins. */
.book-grid .appt-card { isolation:isolate; }

/* ---------- check113: arranged cards + the arrange form (Oct 23, 2026) ----------
   An ARRANGED card (a combination whose parts run on their own
   spans) carries one extra layer inside the same card component:
   .svc-sides paints a light tinted fill on each side for that
   worker's part span — green-tinted on Steven's (left) side in the
   N coin's color family, pink-tinted on Tracy's (right) side in the
   P coin's — positioned by % of the card's own visit span, so a
   part that starts later begins lower and a shorter part's fill
   ends at its own end line. The layer prints BEFORE the card's
   grid lines in the markup and shares their z-index:-1 parking
   behind the card's content (the card is isolation:isolate since
   check112), so the :30 lines still cross the fills like they
   cross everything else — the paper book's printed lines. Ordinary
   cards emit no layer at all and keep the exact check112 look:
   name + note on top, coins in unlabeled halves, no line between
   name and service, no vertical divider. */
.book-grid .appt-card .svc-sides { position:absolute; inset:0; z-index:-1; pointer-events:none; }
.book-grid .appt-card .svc-side { position:absolute; top:0; bottom:0; width:50%; overflow:hidden; }
.book-grid .appt-card .svc-side-s { left:0; }
.book-grid .appt-card .svc-side-t { left:50%; }
.book-grid .appt-card .svc-fill { position:absolute; left:0; right:0; display:block; }
.book-grid .appt-card .svc-side-s .svc-fill { background:rgba(53,181,88,.14); }
.book-grid .appt-card .svc-side-t .svc-fill { background:rgba(231,84,128,.12); }

/* The arrange block on the Add/Edit form: one card per part with
   the part's coin + name, a computed end readout (start + length
   only — the end is never a picker), and the form's own pill
   components for the part's Start and Length. */
.arrange-note { margin:8px 0 0; color:#8a7a76; font-size:.9rem; }
.arrange-part { border:1.5px solid #f0e2dc; border-radius:12px; padding:10px 12px 12px; margin-top:10px; background:#fff; }
.arrange-head { display:flex; align-items:center; gap:8px; }
.arrange-name { font-weight:700; }
.arrange-end { margin-left:auto; color:#96555f; font-weight:700; font-size:.92rem; white-space:nowrap; }
.arrange-lab { margin:10px 0 5px; font-size:.8rem; font-weight:700; letter-spacing:.4px; color:#8a7a76; text-transform:uppercase; }
/* check115: the part Start group no longer has a layout of its
   own — it renders in the shared .time-cols / .time-col layout
   above, exactly like the main Start group (the one-across
   .arrange-times stack is gone). Only the part's custom-time box
   keeps a rule, unchanged from before. */
.arrange-part .part-custom { padding:5px 8px; border:1.5px solid #e3d2cc; border-radius:999px; font:inherit; font-size:.85rem; margin-top:8px; }

/* ---------- check118: five visitor-picked public themes (Oct 24, 2026) ----------
   The public site carries five themes picked by the VISITOR from the
   theme picker at the bottom of every public page (a shared partial in
   the footer, public pages only). The pick lives in the aplus-theme
   cookie for about a year; the server paints the saved theme from the
   first byte via the body's theme-* class. No cookie = Marble & Gold.
   There is deliberately NO day-of-week or time input anywhere here —
   the owner ruled rotation out ("Based on user selection. Not day
   of week").

   Architecture: the base stylesheet above IS the Rose Blossom look
   (the site's current rose/blush design), so theme-rose needs only
   narrow overrides. The four newer looks share the editorial
   treatment marked by body.pub.thed, and differ through per-theme
   variables (body.theme-marble / theme-evening / theme-botanical /
   theme-dusty). The CONTENT rules in this block are scoped under
   body.pub (or body.theme-*): admin pages carry no pub/theme
   class at all, so their content rendering cannot move.
   check167 item 13: the HEADER rules are the exception — the
   header is one component on every page now, so its selectors
   are gated on plain `body`, admin included. */

/* ----- Public header pills (all public themes) ----- */
body .header-pills { display:flex; align-items:center; gap:10px; }
body .header-pills .btn { min-height:44px; padding:.55em 1.2em; font-size:.92rem; white-space:nowrap; }
/* check161 (owner, Oct 25, 2026 — the new home design): the
   header pair is the design's, on every public page and under
   every theme — a WHITE call pill with a rose outline, a rose
   handset and dark letterspaced words ("CALL US"), and a
   FILLED rose book pill with white words ("BOOK NOW" /
   "CHANGE APPOINTMENT") and a white chevron. This supersedes
   the check118/119 arrangement (solid phone pill + light book
   pill, swapped again in the editorial themes): the design's
   pair holds everywhere, so the per-theme swap rules below now
   repeat the same treatment instead of inverting it. Every
   interaction state stays pinned (check119's lesson: a tapped
   tel: link must never repaint invisible). */
body .header-pills .header-call { background:#fff; border:1.5px solid var(--rose); color:var(--charcoal); letter-spacing:.14em; font-weight:600; box-shadow:0 3px 10px rgba(150,85,95,.10); }
body .header-pills .header-call svg { color:var(--rose); flex:0 0 auto; }
body .header-pills .header-call:hover { background:var(--rose-soft); }
body .header-pills .header-call:visited,
body .header-pills .header-call:active,
body .header-pills .header-call:focus { background:#fff; color:var(--charcoal); }
body .btn-book { border:1.5px solid transparent; background:linear-gradient(160deg,#cb939c,var(--rose)); color:#fff; letter-spacing:.14em; font-weight:600; white-space:nowrap; box-shadow:0 3px 10px rgba(150,85,95,.25); }
body .btn-book:hover { background:linear-gradient(160deg,var(--rose),var(--rose-dark)); color:#fff; }
body .btn-book:visited,
body .btn-book:active,
body .btn-book:focus { background:linear-gradient(160deg,#cb939c,var(--rose)); color:#fff; }
body .header-book .pill-chev { flex:0 0 auto; margin-left:2px; }
body.pub.thed .header-pills .header-call { background:#fff; border:1.5px solid var(--rose); color:var(--charcoal); box-shadow:0 3px 10px rgba(150,85,95,.10); }
body.pub.thed .header-pills .header-call:hover { background:var(--rose-soft); color:var(--charcoal); }
body.pub.thed .header-pills .header-call:visited,
body.pub.thed .header-pills .header-call:active,
body.pub.thed .header-pills .header-call:focus { background:#fff; color:var(--charcoal); }
body.pub.thed .btn-book { background:linear-gradient(160deg,#cb939c,var(--rose)); border:1.5px solid transparent; color:#fff; box-shadow:0 3px 10px rgba(150,85,95,.25); }
body.pub.thed .btn-book:hover { background:linear-gradient(160deg,var(--rose),var(--rose-dark)); color:#fff; }
body.theme-evening.thed .btn-book { background:linear-gradient(160deg,#cb939c,var(--rose)); color:#fff; }
body.theme-evening.thed .btn-book:hover { background:linear-gradient(160deg,var(--rose),var(--rose-dark)); color:#fff; }
body.pub.thed .header-pills .btn-book:visited,
body.pub.thed .header-pills .btn-book:active,
body.pub.thed .header-pills .btn-book:focus { background:linear-gradient(160deg,#cb939c,var(--rose)); color:#fff; }
body.theme-evening.thed .header-pills .btn-book:visited,
body.theme-evening.thed .header-pills .btn-book:active,
body.theme-evening.thed .header-pills .btn-book:focus { background:linear-gradient(160deg,#cb939c,var(--rose)); color:#fff; }
@media (max-width: 767px) {
    body .header-inner { flex-wrap:wrap; row-gap:10px; padding-bottom:14px; }
    body .nav-toggle { order:2; margin-left:auto; }
    body .header-pills { order:3; flex:1 1 100%; }
    /* check161: the design's pair splits the row — CALL US
       takes its half, BOOK NOW the other; the pair still
       fills the row (the check139/check155 sizing notes are
       superseded with the number label they protected). */
    body .header-pills .btn { justify-content:center; }
    body .header-pills .header-call { flex:1 1 0; min-width:0; }
    /* check178 item 10: the pair is now Book Appointment +
       Search Appointment — each takes half the row, one line
       apiece, equal heights. */
    body .header-pills .header-book,
    body .header-pills .header-search { flex:1 1 0; min-width:0; padding:.55em .5em; }
    body .header-pills .header-book { flex:1 1 0; min-width:0; }
    body .header-pills .btn { padding:.55em .5em; font-size:.84rem; }
    /* check161 fix: in the CHANGE APPOINTMENT state the long
       label cannot share the row evenly at phone width — the
       call pill takes its natural width and the book pill
       flexes into the rest (the check139 arrangement), with a
       touch less type, so the whole pill stays on screen. */
    body .header-pills.hp-change .header-call { flex:0 0 auto; }
    body .header-pills.hp-change .header-book { flex:1 1 0; font-size:.8rem; letter-spacing:.1em; }
}
@media (min-width: 768px) {
    body .header-pills { margin-left:8px; }
}

/* ----- Homepage featured cards + price menu (rose defaults) ----- */
.feat-cards { display:grid; gap:20px; margin-top:30px; }
.feat-card { background:#fff; border-radius:var(--radius); overflow:hidden; box-shadow:var(--shadow); text-decoration:none; color:inherit; display:flex; flex-direction:column; }
.feat-card img { width:100%; height:230px; object-fit:cover; }
.feat-body { padding:20px 22px 24px; }
.feat-body h3 { font-size:1.35rem; margin-bottom:.3em; }
.feat-body p { color:var(--muted); margin:0 0 10px; font-size:.98rem; }
.feat-body .from { color:var(--rose-dark); font-weight:700; }
.home-menu { margin-top:36px; display:grid; gap:0 40px; }
.home-mi { display:flex; align-items:baseline; gap:10px; padding:11px 0; border-bottom:1px solid #f0e2dd; text-decoration:none; color:inherit; }
.home-mi .t { font-weight:600; }
.home-mi .dots { flex:1; border-bottom:2px dotted #e3c9c2; transform:translateY(-3px); }
.home-mi .p { font-weight:700; color:var(--rose-dark); white-space:nowrap; }
.ornament { display:flex; align-items:center; gap:12px; margin-top:30px; }
.ornament::before, .ornament::after { content:""; height:1px; background:#ecd9d3; flex:1; }
.ornament i { width:8px; height:8px; background:var(--gold); transform:rotate(45deg); display:block; }
/* The interior view: the photo strip is Rose Blossom's (the site's
   current photos); every other theme shows the generated interior. */
.salon-img { width:100%; height:300px; object-fit:cover; border-radius:12px; margin-top:24px; box-shadow:var(--shadow); }
.salon-cap { display:flex; justify-content:space-between; align-items:center; gap:16px; flex-wrap:wrap; margin-top:18px; }
.salon-cap p { color:var(--muted); margin:0; }
.hero-kicker, .hero-rule { display:none; }
body.pub .salon-strip, body.pub .salon-strip-cta { display:none; }
/* check149 (owner, Oct 24, 2026): Rose Blossom's salon view
   joins the new design — the single interior photo shows and
   the old photo strip stays hidden, exactly like the four
   editorial themes. (The check118 rose overrides that showed
   the strip and hid the single are removed.) */

/* ----- check149: Rose Blossom takes the NEW design's hero -----
   (owner, Oct 24, 2026: the reverted Rose homepage "is really
   bad"; the Marble & Gold front-page graphics "was good").
   That step gave Rose the marble-gold hero photo with the
   editorial treatment (paper ground, left ink text, pale left
   shade) while the accent stayed rose.
   ----- check150 SUPERSEDES that hero treatment (owner,
   Oct 24, 2026, 10:47 PM — "go for it. Upload", on the sample
   built from his own Instagram posts): under Rose Blossom
   the hero is now the owner's Instagram photo (long floral
   French artificial nails on a deep red towel,
   hero-instagram.webp) FULL-BLEED at full strength, the words
   set over it at the bottom — white headline + tagline with a
   soft shadow, pale-pink kicker and rating, a white rule, and
   the Book Appointment Online button filled with the rose
   gradient. The pale left shade is REPLACED by a deep-wine
   shade (faint at the top, deepening toward the bottom) so
   the words stay readable over the photo. The four editorial
   themes keep their own hero photos and treatments (.thed
   rules below) — nothing here touches them, and every other
   Rose Blossom page keeps the base design. */
body.pub.theme-rose .hero { background:#563036; color:#fff; text-align:left; min-height:540px; display:flex; align-items:flex-end; }
body.pub.theme-rose .hero-bg { background-image:url("/images/hero-instagram.webp"); opacity:1; background-size:cover; background-position:center 25%; }
body.pub.theme-rose .hero::after { background:linear-gradient(180deg, rgba(86,48,54,.16) 0%, rgba(86,48,54,.10) 40%, rgba(86,48,54,.58) 88%); }
body.pub.theme-rose .hero-inner { padding-bottom:30px; }
body.pub.theme-rose .hero h1 { text-shadow:0 2px 14px rgba(86,48,54,.45); color:#fff; }
body.pub.theme-rose .hero .tagline { color:#fff; text-shadow:0 2px 14px rgba(86,48,54,.45); }
body.pub.theme-rose .hero .rating { background:none; border:0; border-bottom:1.5px solid rgba(255,255,255,.55); border-radius:0; padding:0 0 2px; color:#ffe9ec; text-shadow:0 1px 8px rgba(86,48,54,.5); }
body.pub.theme-rose .hero-cta { margin:26px 0 0; max-width:none; align-items:stretch; }
body.pub.theme-rose .hero-cta .btn-outline { border:none; color:#fff; background:linear-gradient(135deg,#c0808d,#b76e79); box-shadow:0 6px 18px rgba(86,48,54,.35); }
body.pub.theme-rose .hero-cta .btn-outline:hover { background:linear-gradient(135deg,#c0808d,#b76e79); }
body.pub.theme-rose .hero-kicker { display:block; color:#ffe3e8; text-shadow:0 1px 8px rgba(86,48,54,.5); }
body.pub.theme-rose .hero-rule { display:block; width:64px; height:2px; background:#fff; opacity:.85; margin:18px 0 2px; }
/* check151 (owner, Oct 24, 2026, 11:40 PM — "top part missing
   nails"; 11:45 PM — "make the color matching the existing"):
   the Instagram photo is portrait; under cover at desktop
   widths the short wide hero band framed plain fingers and
   cut the decorated nails off. The nail cluster sits at
   roughly 38–64% of the photo's height, so on desktop the
   hero background reframes on it (center 50%). The phone
   framing above (center 25%) is the approved check150 sample
   look and does not change. Same step: the hero's deep-wine
   shade from check150 read as a different color against the
   page, so it is re-tinted into the site's rose family —
   the new shade is rose-dark deepened, the same hue as
   --rose itself. Alphas, stops, and every other hero color
   (the pale-pink kicker and rating line, the rose-gradient
   Book button) are exactly as check150 left them. */
@media (min-width: 768px) {
    body.pub.theme-rose .hero-bg { background-position:center 50%; }
}
/* check150 (owner, Oct 24, 2026): the homepage's first
   featured card — Artificial Nails, his own Instagram photo —
   leads FULL-WIDTH with a taller photo, under EVERY theme
   (these rules are deliberately unscoped). It carries no
   price (check149's no-prices rule stands). */
.feat-lead img { height:250px; }
@media (min-width: 768px) {
    .feat-lead { grid-column:1 / -1; }
    .feat-lead img { height:340px; }
}
@media (min-width: 768px) {
    .feat-cards { grid-template-columns:1fr 1fr; gap:26px; }
    .feat-card img { height:300px; }
    .home-menu { grid-template-columns:1fr 1fr; }
    .salon-img { height:420px; }
}
@media (min-width: 1100px) {
    .home-menu { grid-template-columns:1fr 1fr 1fr; }
}

/* ----- The theme picker bar (all public themes; footer is dark everywhere) ----- */
.theme-bar { margin:28px 0 0; padding:20px 0 34px; border-top:1px solid rgba(255,255,255,.16); display:flex; flex-wrap:wrap; gap:10px 18px; align-items:center; }
.theme-bar-label { font-size:.8rem; font-weight:700; letter-spacing:.18em; text-transform:uppercase; color:#cfc2b6; }
.theme-opts { display:flex; flex-wrap:wrap; gap:8px; }
.theme-opt { display:inline-flex; align-items:center; gap:8px; padding:8px 14px; border-radius:999px; border:1.5px solid rgba(255,255,255,.32); background:transparent; color:#f3e9e4; font:inherit; font-size:.88rem; font-weight:600; cursor:pointer; }
.theme-opt:hover { border-color:rgba(255,255,255,.6); }
.theme-opt.on { border-color:var(--gold); box-shadow:0 0 0 1px var(--gold); background:rgba(255,255,255,.08); }
.theme-dot { width:15px; height:15px; border-radius:50%; flex:none; border:1px solid rgba(0,0,0,.3); }
.theme-dot-marble { background:linear-gradient(135deg,#ffffff 45%,#c9a227 100%); }
.theme-dot-rose { background:#b76e79; }
.theme-dot-evening { background:linear-gradient(135deg,#1c0a10 30%,#7e2438 100%); }
.theme-dot-botanical { background:#5f7d4a; }
.theme-dot-dusty { background:#a26769; }

/* ----- The editorial theme system: variables per look ----- */
body.pub.thed {
    --acc:#c9a227; --acc-hi:#d9ba45; --acc-text:#a8861c; --acc-soft:#e9d189;
    --acc-tint:#faf5e6; --dots:#d8cba6; --line:#e7ddc8; --hair:#efe8d8;
    --paper:#f6f4ef; --alt:#f1ece1; --surface:#ffffff;
    --ink-th:#33302d; --muted-th:#7a716a; --btn-ink:#2e2a26;
    --header-bg:rgba(255,255,255,.94); --footer-bg:#2e2b28; --panel:#2e2b28;
    --outline-bg:rgba(255,255,255,.85);
    --hero-ink:#33302d; --hero-sub:#5d564f;
    --shade-a:rgba(251,250,247,.96); --shade-b:rgba(251,250,247,.85); --shade-c:rgba(251,250,247,.30);
}
/* Warm-white marble veining behind Marble & Gold pages (the approved
   sample's texture, redrawn from its own SVG recipe). */
body.theme-marble.thed {
    background-image:
        linear-gradient(rgba(255,255,255,.72), rgba(255,255,255,.72)),
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='900' height='900'%3E%3Cfilter id='m'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.0032 0.0068' numOctaves='6' seed='11'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0.48 0 0 0 0 0.45 0 0 0 0 0.40 0.85 0 0 0 0 0'/%3E%3C/filter%3E%3Crect width='900' height='900' filter='url(%23m)' opacity='0.13'/%3E%3C/svg%3E");
}
body.theme-evening.thed {
    --acc:#c9a227; --acc-hi:#d9ba45; --acc-text:#e9d189; --acc-soft:#8f6f1d;
    --acc-tint:#33241a; --dots:#6b4a35; --line:#4a2c33; --hair:#3a2129;
    --paper:#211216; --alt:#2b181d; --surface:#2e1a20;
    --ink-th:#f3eae4; --muted-th:#c4a99e; --btn-ink:#241417;
    --header-bg:rgba(24,11,14,.96); --footer-bg:#150a0d; --panel:#3a1e26;
    --outline-bg:rgba(255,255,255,.06);
    --hero-ink:#f8f0e9; --hero-sub:#e0c9bd;
    --shade-a:rgba(22,9,13,.92); --shade-b:rgba(22,9,13,.72); --shade-c:rgba(22,9,13,.18);
}
body.theme-botanical.thed {
    --acc:#5f7d4a; --acc-hi:#84a563; --acc-text:#435f35; --acc-soft:#cfdcbc;
    --acc-tint:#eef2df; --dots:#c3cba6; --line:#dde0c8; --hair:#e8ead6;
    --paper:#f6f4ea; --alt:#edf0dc; --surface:#ffffff;
    --ink-th:#33302d; --muted-th:#6f7261; --btn-ink:#ffffff;
    --header-bg:rgba(255,255,255,.94); --footer-bg:#26331f; --panel:#26331f;
    --outline-bg:rgba(255,255,255,.85);
    --hero-ink:#2f3527; --hero-sub:#5c6152;
    --shade-a:rgba(248,247,238,.95); --shade-b:rgba(248,247,238,.84); --shade-c:rgba(248,247,238,.28);
}
body.theme-dusty.thed {
    --acc:#a26769; --acc-hi:#c08a8d; --acc-text:#8c4f52; --acc-soft:#e3c4c2;
    --acc-tint:#faeeea; --dots:#d9b8ac; --line:#ecd9d2; --hair:#f3e4de;
    --paper:#faf4ef; --alt:#f6e9e1; --surface:#ffffff;
    --ink-th:#3a2e2c; --muted-th:#857069; --btn-ink:#ffffff;
    --header-bg:rgba(255,255,255,.94); --footer-bg:#38262a; --panel:#38262a;
    --outline-bg:rgba(255,255,255,.85);
    --hero-ink:#3d2e2d; --hero-sub:#6d5c5a;
    --shade-a:rgba(250,244,239,.95); --shade-b:rgba(250,244,239,.84); --shade-c:rgba(250,244,239,.28);
}
body.theme-marble.thed { --hero-img:url("/images/hero-marble-gold.webp"); }
body.theme-evening.thed { --hero-img:url("/images/hero-evening.webp"); }
body.theme-botanical.thed { --hero-img:url("/images/hero-botanical.webp"); }
body.theme-dusty.thed { --hero-img:url("/images/hero-dustyrose.webp"); }

/* ----- The editorial treatment, driven by the variables ----- */
body.pub.thed { background-color:var(--paper); color:var(--ink-th); }
body.pub.thed a { color:var(--acc-text); }
body.pub.thed .kicker { color:var(--acc-text); letter-spacing:.26em; }
body.pub.thed .lead { color:var(--muted-th); }
body.pub.thed .section.alt { background:var(--alt); }
body.pub.thed button.link-btn { color:var(--acc-text); }
body.pub.thed .btn-call { background:linear-gradient(160deg,var(--acc-hi),var(--acc)); color:var(--btn-ink); border:1.5px solid var(--acc-text); box-shadow:0 4px 14px rgba(20,12,8,.22); }
body.pub.thed .btn-call:hover { background:linear-gradient(160deg,var(--acc),var(--acc-text)); color:var(--btn-ink); }
body.pub.thed .btn-outline { background:var(--outline-bg); color:var(--ink-th); border:1.5px solid var(--acc-soft); }
body.pub.thed .btn-outline:hover { background:var(--acc-tint); }
body.pub.thed .site-header { background:var(--header-bg); border-bottom:1px solid var(--line); }
body.pub.thed .site-header::after { content:""; position:absolute; left:0; right:0; bottom:-1px; height:2px; background:linear-gradient(90deg,transparent,var(--acc) 30%,var(--acc) 70%,transparent); opacity:.55; }
body.pub.thed .site-nav { background:var(--surface); border-bottom-color:var(--line); }
body.pub.thed .site-nav a { color:var(--muted-th); border-top-color:var(--hair); }
body.pub.thed .site-nav a.active { color:var(--ink-th); }
body.pub.thed .nav-toggle span { background:var(--ink-th); }
body.pub.thed .hero { background:var(--paper); color:var(--hero-ink); text-align:left; }
body.pub.thed .hero-bg { background-image:var(--hero-img); opacity:1; }
body.pub.thed .hero::after { background:linear-gradient(90deg,var(--shade-a) 0%,var(--shade-b) 34%,var(--shade-c) 62%,transparent 78%); }
body.pub.thed .hero h1 { text-shadow:none; color:var(--hero-ink); }
body.pub.thed .hero .tagline { color:var(--hero-sub); }
body.pub.thed .hero .rating { background:none; border:0; border-bottom:1.5px solid var(--acc-soft); border-radius:0; padding:0 0 2px; color:var(--hero-ink); }
body.pub.thed .hero .rating .star { color:var(--acc); }
body.theme-marble.thed .hero .rating .star { color:var(--rose); }
body.pub.thed .hero-cta { margin:30px 0 0; align-items:stretch; justify-content:flex-start; max-width:none; }
body.pub.thed .hero-cta .btn-outline { border-color:var(--acc-soft); color:var(--hero-ink); background:var(--outline-bg); }
body.pub.thed .hero-kicker { display:block; }
body.pub.thed .hero-rule { display:block; width:64px; height:2px; background:var(--acc); margin:18px 0 2px; }
body.pub.thed .feat-card { border:1px solid var(--line); border-top:3px solid var(--acc); border-radius:6px; box-shadow:0 10px 30px rgba(20,12,8,.10); }
body.pub.thed .feat-body p { color:var(--muted-th); }
body.pub.thed .feat-body .from { color:var(--acc-text); }
body.theme-marble.thed .feat-body .from { color:var(--rose-dark); }
body.pub.thed .home-mi { border-bottom-color:var(--hair); }
body.pub.thed .home-mi .dots { border-bottom-color:var(--dots); }
body.pub.thed .home-mi .p { color:var(--acc-text); }
body.pub.thed .ornament::before, body.pub.thed .ornament::after { background:var(--line); }
body.pub.thed .ornament i { background:var(--acc); }
body.pub.thed .salon-img { border:1px solid var(--line); }
body.pub.thed .salon-cap p { color:var(--muted-th); }
body.pub.thed .award { background:var(--panel); border-top:3px solid var(--acc); }
body.pub.thed .award h2 { color:#fff; }
body.pub.thed .award .kicker { color:var(--acc-soft); }
body.pub.thed .award .lead { color:#d8cfc4; }
body.pub.thed .hours-list li { border-bottom-color:var(--hair); }
body.pub.thed .hours-list li::after { content:""; flex:1; order:1; border-bottom:2px dotted var(--dots); transform:translateY(-3px); margin:0 6px; }
body.pub.thed .hours-list li span:last-child { order:2; }
body.pub.thed .form-card { background:var(--surface); border:1px solid var(--line); box-shadow:0 10px 30px rgba(20,12,8,.10); }
body.pub.thed .field input, body.pub.thed .field textarea, body.pub.thed .field select { background:var(--surface); border-color:var(--line); color:var(--ink-th); }
body.pub.thed .field input:focus, body.pub.thed .field textarea:focus, body.pub.thed .field select:focus { border-color:var(--acc); box-shadow:0 0 0 3px var(--acc-tint); }
/* check204: the date control is a primary button in every theme,
   so it takes the .btn-call treatment here too (it used to sit
   in the field rules above, when it was a white box). */
body.pub.thed .date-display { background:linear-gradient(160deg,var(--acc-hi),var(--acc)); color:var(--btn-ink); border:1.5px solid var(--acc-text); box-shadow:0 4px 14px rgba(20,12,8,.22); }
body.pub.thed .date-display:hover { background:linear-gradient(160deg,var(--acc),var(--acc-text)); color:var(--btn-ink); }
body.pub.thed .date-display:focus { box-shadow:0 0 0 3px var(--acc-tint); }
body.pub.thed .step-n { background:linear-gradient(160deg,var(--acc-hi),var(--acc)); color:var(--btn-ink); }
body.pub.thed .slot { background:var(--surface); border-color:var(--line); color:var(--ink-th); }
body.pub.thed .slot:has(input:focus-visible) { outline-color:var(--acc); }
/* The shared settled selection color survives every theme: this
   rule must beat the .thed .slot rule above, so it is restated
   here at higher specificity (owner spec, Oct 19-20, 2026). */
body.pub.thed .slot:has(input:checked) { background:var(--sel-yellow); border-color:var(--sel-border); color:var(--sel-ink); box-shadow:0 4px 14px rgba(230,207,30,.45); }
body.pub.thed .book-svc .slot, body.pub.thed .time-grid .slot { border-color:var(--acc-soft); color:var(--acc-text); }
body.pub.thed .time-grid .slot.full, body.pub.thed .slot.full { background:var(--alt); color:var(--muted-th); }
body.pub.thed .notice { background:var(--acc-tint); border-color:var(--acc); color:var(--ink-th); }
body.pub.thed .cal-pop { background:var(--surface); border-color:var(--line); color:var(--ink-th); }
body.pub.thed .cal-nav { border-color:var(--line); background:var(--surface); color:var(--acc-text); }
body.pub.thed .cal-day:hover:not(:disabled) { background:var(--acc-tint); }
body.pub.thed .cal-week span { color:var(--muted-th); }
body.pub.thed .contact-block { background:var(--alt); border:1px solid var(--line); }
body.pub.thed .dep-summary { background:var(--alt); border-color:var(--line); }
body.pub.thed .menu-list, body.pub.thed .menu-items { background:var(--surface); border:1px solid var(--line); box-shadow:0 10px 30px rgba(20,12,8,.08); }
body.pub.thed .menu-list li, body.pub.thed .menu-item { border-bottom-color:var(--hair); }
body.pub.thed .menu-row .name { color:var(--ink-th); }
body.pub.thed .menu-row .dots { border-bottom-color:var(--dots); }
body.pub.thed .menu-row .price { color:var(--acc-text); }
body.pub.thed .menu-item .desc, body.pub.thed .menu-blurb { color:var(--muted-th); }
body.pub.thed .starts-at span { background:var(--acc-tint); color:var(--acc-text); border-color:var(--line); }
body.pub.thed .menu-note { background:var(--acc-tint); color:var(--ink-th); }
body.pub.thed .menu-group > h2::after { background:var(--line); }
body.pub.thed .svc-card { background:var(--surface); border:1px solid var(--line); box-shadow:0 10px 30px rgba(20,12,8,.08); }
body.pub.thed .svc-body p { color:var(--muted-th); }
body.pub.thed .video-card p { color:var(--muted-th); }
body.pub.thed .map-frame { border:1px solid var(--line); }
body.pub.thed .site-footer { background:var(--footer-bg); border-top:3px solid var(--acc); }
body.pub.thed .site-footer a { color:var(--acc-soft); }
body.pub.thed .site-footer .tagline { color:#b6ad99; }
body.pub.thed .site-footer .rating { border-color:var(--line); color:#fff; }
body.pub.thed .site-footer .rating .star { color:var(--acc); }
body.pub.thed .footer-bottom { border-top-color:var(--hair); color:#a89e88; }
@media (max-width: 767px) {
    body.pub.thed .hero::after { background:linear-gradient(180deg,var(--shade-a) 0%,var(--shade-b) 55%,var(--shade-c) 100%); }
}
@media (min-width: 768px) {
    body.pub.thed .hero-cta { flex-direction:row; justify-content:flex-start; }
    body.pub.thed .site-nav a.active { box-shadow:inset 0 -2px 0 var(--acc); }
}

/* ═══════════════════════════════════════════════════════════════════
   check122 — booking confirmation card (MyAppointment, just-booked).
   Self-contained: every class is conf-* prefixed and the palette is
   scoped to .conf-col, so the five public themes cannot break the
   card and the card cannot break them. Lifted from the owner's
   approved sample (mockups/booking-confirmation.html, Oct 24, 2026).
   ═══════════════════════════════════════════════════════════════════ */
.conf-col { --cacc:#a26769; --cacch:#c08a8d; --cacct:#8c4f52; --caccs:#e9c8c4;
  --cink:#3a2e2c; --cmut:#8a6f66; --cline:#f0ddd2; --cgold:#c9a227; --cgoldd:#a8861c;
  max-width:462px; margin:24px auto 0; font-family:'Inter',system-ui,sans-serif; color:var(--cink); }
.conf-card { position:relative; border-radius:26px; overflow:hidden;
  box-shadow:0 18px 44px rgba(140,79,82,.22); border:1px solid #f3d9cd; background:#fff8f3; }
.conf-photo { position:relative; }
.conf-photo img { width:100%; height:218px; object-fit:cover; display:block; }
.conf-photo::after { content:""; position:absolute; inset:auto 0 0 0; height:110px;
  background:linear-gradient(to bottom, rgba(255,248,243,0), #fff8f3); }
/* check133 (owner, Oct 24, 2026): the confirmation card's
   decorative top is RESTORED (check97 had trimmed it and the
   owner missed it) — the photo band's gold vines, the medallion's
   sparkles, and the heart divider rules are back, exactly as the
   check124/check122 design had them. .conf-petal (the pink "egg"
   ovals) and .conf-thanks (the thank-you paragraph) stay deleted
   — they are NOT restored. */
.conf-vine { position:absolute; color:var(--cgold); opacity:.85; pointer-events:none; }
.conf-medallion { position:relative; z-index:2; width:104px; height:104px; margin:-56px auto 0; border-radius:50%;
  background:radial-gradient(circle at 34% 28%, #fffdf9, #fdf1e6);
  border:2.5px solid var(--cgold); outline:5px solid rgba(201,162,39,.16);
  display:flex; align-items:center; justify-content:center; box-shadow:0 12px 26px rgba(140,79,82,.25); }
.conf-medallion svg { width:50px; height:50px; }
.conf-sparkle { position:absolute; color:var(--cgold); }
.conf-body { padding:14px 24px 26px; text-align:center; position:relative; }
/* check133: the heart divider below the title gives the heading
   its gap again (the check97-era 20px bottom margin is retired);
   the slim 404/Error variant still forces its own 20px, so those
   cards are unchanged. The title also scales down with the rest
   of the card's type (see the check133 note at .conf-who). */
.conf-title { font-family:'Playfair Display',serif; font-size:29px; font-weight:700; margin:8px 0 0; }
.conf-heartdiv { display:flex; align-items:center; gap:10px; margin:12px auto; max-width:260px; color:var(--cgoldd); }
.conf-heartdiv::before, .conf-heartdiv::after { content:""; height:1px; flex:1;
  background:linear-gradient(90deg, transparent, var(--cgold), transparent); }
.conf-heartdiv span { font-size:15px; }
.conf-details { background:#fff; border:1.5px solid var(--cgold); border-radius:18px; text-align:left;
  padding:24px 16px 10px; box-shadow:0 8px 22px rgba(58,46,44,.07); position:relative; }
/* check133 (owner, Oct 24, 2026 — "Letters are too big. They got
   cut off really bad"): the check130 oversized type scales down
   to comfortable phone sizes — name 36 -> 28, service 26 -> 21,
   detail values 25 -> 20, address/phone 23 -> 19, and the
   "You're booked!" title 36 -> 29 to match. Nothing else about
   the check130 box changes. */
.conf-who { font-family:'Playfair Display',serif; font-size:28px; font-weight:600;
  text-align:center; line-height:1.15; }
.conf-svc { color:#b76e79; font-weight:600; font-size:21px; margin:6px 0 0; text-align:center; }
.conf-bottle { position:absolute; top:16px; right:14px; width:48px; opacity:.95; }
.conf-minidiv { display:flex; align-items:center; gap:10px; margin:18px 6px 4px; color:var(--cgoldd); }
.conf-minidiv::before, .conf-minidiv::after { content:""; height:1px; background:rgba(201,162,39,.55); flex:1; }
.conf-minidiv span { font-size:15px; line-height:1; }
/* check130 (owner, Oct 24, 2026 — approved sample
   mockups/confirm-details-sample.html): the details rows carry
   their label small and uppercase ABOVE a big semibold value,
   the icon chips grow to the sample's 52px, and the Location
   address links to directions with a subtle gold underline
   while the phone under it is a rose tel: link. (The value
   sizes were scaled down in check133 — see .conf-who.) */
.conf-drow { display:flex; align-items:center; gap:14px; padding:15px 2px; }
.conf-drow + .conf-drow { border-top:1px solid var(--cline); }
.conf-ic { width:52px; height:52px; flex:0 0 52px; border-radius:50%; background:#f9e9e6;
  display:flex; align-items:center; justify-content:center; }
.conf-ic svg { width:26px; height:26px; }
.conf-dmain { flex:1; min-width:0; }
.conf-lab { display:block; color:var(--cmut); font-size:16px; font-weight:600;
  letter-spacing:.4px; text-transform:uppercase; margin-bottom:3px; }
.conf-drow b { display:block; font-weight:600; font-size:20px; line-height:1.3; }
/* check133: the Date value rides 1px smaller — at phone width
   "Saturday, October 24" at 20px wrapped to two lines in the
   ~204px value column (measured on the rig); 19px keeps the
   owner's date on ONE line. Other values stay 20px. */
.conf-drow b.conf-date { font-size:19px; }
.conf-drow b.conf-addr { font-size:19px; }
.conf-drow b.conf-addr a { color:inherit; text-decoration:underline;
  text-decoration-color:var(--cgold); text-underline-offset:4px; }
.conf-phone { display:block; font-size:19px; font-weight:600; line-height:1.3; margin-top:6px; }
.conf-phone a { color:#b76e79; text-decoration:none; }
.conf-leaf { display:flex; align-items:center; gap:10px; margin:16px auto 0; max-width:240px; color:var(--cgoldd); }
.conf-leaf::before, .conf-leaf::after { content:""; height:1px; flex:1;
  background:linear-gradient(90deg, transparent, var(--cgold), transparent); }
.conf-actions { padding:22px 6px 4px; text-align:center; }
.conf-btn { display:flex; align-items:center; justify-content:center; gap:10px; width:100%; max-width:360px;
  margin:0 auto; text-decoration:none; font-weight:600; font-size:16px; padding:16px 20px; border-radius:999px;
  line-height:1.4; border:1.5px solid transparent; }
.conf-btn svg { width:20px; height:20px; flex:0 0 20px; }
.conf-btn-cal { background:linear-gradient(160deg, var(--cacch), var(--cacc));
  box-shadow:0 8px 20px rgba(140,79,82,.35); }
.conf-btn-note { max-width:360px; margin:8px auto 0; color:var(--cmut); font-size:13px; }
.conf-btn-txt { background:#fff; border:1.5px solid var(--caccs);
  box-shadow:0 4px 14px rgba(58,46,44,.08); margin-top:16px; }
/* check133: real <button> elements wear .conf-btn too (My
   Appointment's Change toggle and Cancel button, unified with the
   card's buttons per the owner) — they need the UA font reset
   anchors get for free, and their label colors spelled out (the
   three-class color rules below name only anchors). The owner's
   buttons-2-and-4 ruling: Cancel wears Text Me's format exactly —
   white pill, rose text — so there is no danger variant. */
button.conf-btn { font-family:inherit; cursor:pointer; }
.conf-col button.conf-btn.conf-btn-cal { color:#fff; }
.conf-col button.conf-btn.conf-btn-txt { color:var(--cacct); }
/* The button label colors ride three-class selectors on purpose:
   the public themes paint every link (body.pub.thed a) with their
   accent text color, which would otherwise wash out the white
   labels on the rose and dark buttons. */
.conf-col a.conf-btn.conf-btn-cal { color:#fff; }
.conf-col a.conf-btn.conf-btn-txt { color:var(--cacct); }
.conf-txt-preview { max-width:360px; margin:14px auto 0; text-align:left; }
.conf-cap { color:var(--cmut); font-size:12.5px; margin:0 2px 6px; }
.conf-bubble { background:#e9e9eb; color:#111; border-radius:18px; border-bottom-left-radius:4px;
  padding:12px 14px; font-size:14px; line-height:1.5; }
/* check133: the old black .conf-home "Back to Homepage" button is
   retired — the homepage return is now the _HomeButton component
   (variant B: a white .conf-btn pill, house icon, "Home"). */

/* ---------- check126: the error pages wear the same card ----------
   (owner, Oct 24, 2026 — mockups/404-sample.html + his amendments:
   "Call, text." and the 404 page's one-minute auto refresh). The
   404 / Error pages reuse the conf-* card above wholesale; only
   these small pieces are new: a text medallion (the "404" /
   "!" where the confirmation card carries its check mark), the
   gold border on the Text button (the sample's treatment), and
   a quiet text link. */
.conf-medallion .conf-med-num { font-family:'Playfair Display',serif; font-weight:700;
  font-size:36px; color:var(--cacct); }
.conf-btn.conf-btn-gold { border-color:var(--cgold); }
.conf-col .conf-body a.conf-textlink { color:var(--cacct); font-weight:500;
  text-decoration:none; border-bottom:1px solid var(--caccs); }

/* ---------- check127: the error pages, trimmed ----------
   (owner, Oct 24, 2026 — "Too much details for average
   customers.") The 404 / Error cards drop their lead
   paragraph, the gold heart divider, and the 404 page's
   visible refresh note (the silent 60-second meta refresh
   itself stays); the .conf-note rule from check126 is
   retired with the note. What remains: photo, medallion,
   headline, Call + Text, home link. This slim body modifier
   tightens the card's spacing for the shorter content —
   the shared .conf-body (the confirmation card's) is
   untouched. */
.conf-body.conf-body-slim { padding-top:10px; padding-bottom:24px; }
.conf-body-slim .conf-title { margin-bottom:20px; }

/* ---------- check125: Book alignment (owner, Oct 24, 2026) ----------
   "Service icons not lined up horizontally. Plus sign not lined up
   vertically." Three alignment fixes, all inside the Book grid:

   1) THE COIN ROW LIVES IN THE BOTTOM STRIP. The card becomes a
   flex column and the strip (or the fallback coin row) takes
   margin-top:auto, so the coins always sit on ONE line at the
   card's bottom, whatever the wrapped name / note above them used
   to push them to. Before, the strip sat in normal flow right
   under the name: on the owner's 9:00 split hour one card's coins
   straddled the :30 line while the neighbouring card's coin
   floated higher, and on a tall card the row floated mid-face.
   The strip's own margins (flush bleed on full cards, the lane
   card's 10px bottom margin) are unchanged — only its top margin
   gives. The no-show note keeps its shrink-to-fit width via
   align-self (a column flex item would otherwise stretch). */
.book-grid .appt-card { display:flex; flex-direction:column; }
.book-grid .appt-card .svc-strip,
.book-grid .appt-card.lane-card .svc-strip { margin-top:auto; }
.book-grid .appt-card .appt-line2:has(> .svc-coins) { margin-top:auto; }
.book-grid .appt-card .ns-note { align-self:flex-start; }

/* 2) PER-LANE PLUSES SHARE ONE X PER LANE. A lane plus is offset
   from the cell's right edge by the complementary share of the
   cell's width (--pl = the lane's right edge, emitted by
   _BookCell.cshtml), less the same 6px inset the full-width
   .cell-plus uses — so within a lane, the first-row plus and
   every .cell-plus-row sit at the identical horizontal position,
   and a full-width cell's pluses still sit exactly where they
   always did (right:6px, no --pl). */
.book-grid .cell-plus-lane { right:calc(100% - var(--pl, 100%) + 6px); }

/* ---------- check131 (owner, Oct 24, 2026): short cards fit
   their strip ----------
   A 15-minute appointment's card is half a phone row tall
   (~40px) — shorter than its own name line plus the
   bottom-pinned coin strip (check125), so its coins painted
   as clipped semicircles at the card's bottom edge (his
   screenshot: the 10:30 walk-in, Dip + Pedicure, both coins
   cut in half). The card now carries a floor under its
   height: it grows until its content fits, extending into
   the empty space below its slot (standard calendar
   behavior; a following card sits later in the DOM and
   paints above the extension, so the short card never
   covers it, and nothing is shrunk to make room). A card
   whose slot already fits its content is untouched — the
   percentage height wins and check125's measured geometry
   is unchanged. The px value inside the phone media query
   is the measured fit of the canonical card (name line +
   strip) for engines without intrinsic sizing keywords;
   max-content states the same floor exactly, for every
   card shape (wrapped lane names, note lines), wherever
   it is supported. */
@media (max-width: 640px) {
    .book-grid .appt-card { min-height: 68px; }
}
.book-grid .appt-card { min-height: max-content; }

/* ---------- check133 (owner, Oct 24, 2026): Phone Sync panel ----
   The admin Phone Sync card, following the approved design
   (mockups/phone-sync-design.html, panel C): one warm-white card
   with the gold border, the toggle, the account row, the two
   action buttons (password outlined, QR rose), the last-sync row,
   and the rules list with gold dots. Panel-only classes — nothing
   else on the site wears them. */
.sync-card {
    max-width: 560px;
    margin-top: 18px;
    padding: 28px;
    border: 1.5px solid rgba(201,162,39,.72);
    border-radius: 28px;
    background: #fff;
    box-shadow: 0 18px 42px rgba(150,85,95,.13);
}
.sync-head { display:flex; align-items:center; justify-content:space-between; gap:20px; }
.sync-head h2 { font-family:'Playfair Display',Georgia,serif; font-size:33px; font-weight:700; line-height:1; margin:0; }
.sync-toggle-form { margin:0; }
.sync-toggle {
    width:59px; height:33px; padding:3px;
    border:0; border-radius:999px;
    background:#cfc4bf; cursor:pointer;
    box-shadow: inset 0 0 0 1px rgba(150,85,95,.2);
}
.sync-toggle::after {
    content:""; display:block;
    width:27px; height:27px; border-radius:50%;
    background:#fff; box-shadow:0 2px 6px rgba(0,0,0,.22);
}
.sync-toggle.on { background:var(--rose); }
.sync-toggle.on::after { margin-left:26px; }
.sync-divider { height:1px; margin:22px 0 0; background:#e3d2cc; }
.sync-row {
    padding:16px 0 15px;
    display:flex; align-items:center; justify-content:space-between; gap:20px;
    border-bottom:1px solid #e3d2cc; font-size:15px;
}
.sync-row span { color:#8a7a74; font-weight:600; }
.sync-row strong { font-weight:700; }
.sync-btn-pw, .sync-btn-qr { width:100%; min-height:49px; margin-top:13px; }
.sync-btn-pw { background:#fff; color:var(--rose-dark); border:1.5px solid var(--gold); }
.sync-btn-qr { border:0; }
.sync-card form .field { margin-top:13px; }
.sync-qr { display:flex; flex-direction:column; align-items:center; padding:17px 0 3px; }
.sync-qr svg { width:120px; height:120px; }
.sync-setup-url { font-size:13px; color:#8a7a74; word-break:break-all; text-align:center; margin:8px 0 0; }
.sync-row-last { padding:13px 0 14px; }
.sync-rules { list-style:none; margin:0; padding:17px 0 0; }
.sync-rules li {
    position:relative; padding:0 0 11px 19px;
    color:#554b47; font-size:14.5px; font-weight:500; line-height:1.42;
}
.sync-rules li::before {
    content:""; position:absolute; left:1px; top:.48em;
    width:7px; height:7px; border-radius:50%; background:var(--gold);
}
.sync-rules li:last-child { padding-bottom:0; }
@media (max-width: 460px) {
    .sync-card { padding:24px 21px; }
}

/* check143: the shared device link row (_DeviceLinks) — quiet
   text links, no box. The anchor is pinned to the .link-btn
   values so both actions read identically in every theme. */
.dev-links { display: flex; flex-wrap: wrap; gap: 8px 26px; justify-content: center; align-items: center; margin-top: 18px; }
.dev-links form { margin: 0; }
.dev-links a { color: var(--acc-text); text-decoration: underline; font-size: .95rem; }

/* check152 (owner, Oct 25, 2026, 12:08 AM — picking from the
   five booking-page top samples): "Make sure you use font
   throughout all pages for the top part of each page. Use Top 1
   image, but with font in top 2." Top 1 = the photo band over
   the owner's Instagram photo; Top 2's font = the Great Vibes
   handwriting script. One shared band (_PageTop.cshtml) now
   tops every public page, and the homepage hero headline wears
   the same script, so the font runs throughout.

   The font is SELF-HOSTED (wwwroot/fonts/great-vibes.woff2,
   the latin subset) — no Google Fonts dependency. */
@font-face {
    font-family: "Great Vibes";
    src: url("/fonts/great-vibes.woff2") format("woff2");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

/* The shared page-top band: Top 1's framing exactly — the
   Instagram photo at center 40%/cover in a 170px rounded band,
   the rose-wine #563036 shade faint at the top and deepening
   toward the bottom, the letterspaced pale-pink kicker, the
   gold rule — with the title in Great Vibes, sized up for
   script metrics so it reads over the shade. */
.page-top { position:relative; border-radius:18px; overflow:hidden; height:170px; background:url("/images/hero-instagram.webp") center 40%/cover; display:flex; flex-direction:column; justify-content:flex-end; padding:16px 20px; margin-bottom:22px; }
.page-top::after { content:""; position:absolute; inset:0; background:linear-gradient(180deg, rgba(86,48,54,0) 25%, rgba(86,48,54,.6)); }
.page-top-kicker { position:relative; z-index:2; color:#ffe3e8; letter-spacing:.3em; font-size:.72rem; font-weight:700; text-transform:uppercase; text-shadow:0 1px 8px rgba(86,48,54,.5); }
.page-top-title { position:relative; z-index:2; color:#fff; font-family:"Great Vibes", cursive; font-weight:400; font-size:2.6rem; line-height:1.15; margin:2px 0 6px; text-shadow:0 2px 10px rgba(86,48,54,.45); }
.page-top-rule { position:relative; z-index:2; width:64px; height:3px; background:#e8c877; border-radius:3px; }
@media (min-width: 768px) {
    .page-top-title { font-size: 3rem; }
}

/* The homepage hero headline in the same script — same photo,
   layout, shade, and button as check151; only the headline's
   typeface (and its size, up for script metrics) changes. The
   kicker and rating line stay exactly as they are. */
.hero h1 { font-family:"Great Vibes", cursive; font-weight:400; font-size:3.4rem; line-height:1.15; }
@media (min-width: 768px) {
    .hero h1 { font-size: 4.6rem; }
}

/* check152 (owner, Oct 25, 2026, 12:10 AM): "Make sure you keep
   'Your last appointment was 32 days ago'. Number 32 is a little
   bigger font." — the returning-customer line on /Book keeps its
   wording and its place under the page top; only its day number
   (.lv-num, wrapped by Book.cshtml from LastVisitDays) grows to
   1.3em, same color, bold. One style covers the "1 day ago" and
   "N days ago" variants; "today" carries no number. */
.lv-num { font-size:1.3em; font-weight:700; }

/* check153 (owner, Oct 25, 2026, 12:33 AM + 12:37 AM expansion):
   "Bring these on top banner" + "Home services gallery book
   appointment search appointment" -- the shared page-top band
   carries the full menu as five text-link pills, in the
   owner's order: Home, Services, Gallery, Book Appointment,
   Search Appointment. They ride their own wrapping row under
   the script title (the gold rule keeps its row above them),
   so the title is never crowded or covered at phone widths;
   the band grows past 170px only when the row wraps. Colors
   come from the existing palette only: the idle pill is the
   white pill with rose-dark text (the confirmation component's
   outline-button look); the pill for the page being viewed is
   filled with the site's rose gradient (#c0808d -> #b76e79,
   the hero Book button's). */
.page-top { height:auto; min-height:170px; }
.page-top-bottom { position:relative; z-index:2; }
.page-top-nav { position:relative; z-index:2; display:flex; flex-wrap:wrap; gap:8px; margin-top:10px; }
.page-top-pill { display:inline-block; padding:7px 16px; border-radius:999px; background:rgba(255,255,255,.93); border:1.5px solid rgba(255,255,255,.85); color:#96555f; font-size:.85rem; font-weight:700; line-height:1.2; text-decoration:none; box-shadow:0 2px 10px rgba(86,48,54,.35); }
.page-top-pill:hover { background:#fff; }
.page-top-pill.is-active { background:linear-gradient(135deg,#c0808d,#b76e79); border-color:transparent; color:#fff; }
@media (max-width: 380px) {
    .page-top-pill { padding:6px 12px; font-size:.8rem; }
}

/* check157 (owner, Oct 25, 2026): "Steven letters cannot be
   read. Use black." A Starts cell shared by a customer booking
   and another booking carries .book-appt-customer, whose legacy
   cell rule (td.book-appt-customer a { color:#fff }) whitened
   EVERY card in the cell — the pale admin card beside the red
   one rendered its name and note white on pale pink. White text
   belongs only to the genuinely red card: inside a customer
   cell, a card that is not itself .card-customer (or the
   no-show card, which keeps its own grey) takes the standard
   dark card text, and a white mark dot on such a card keeps
   its dark ring. The red card is untouched. */
.book-grid td.book-appt-customer a.appt-card:not(.card-customer):not(.card-noshow) { color:#33302d; }
.book-grid td.book-appt-customer a.appt-card:not(.card-customer) .cdot-white { border-color:#2b2320; }

/* ═══════════════════════════════════════════════════════════════════
   check158 (owner, Oct 25, 2026 — "I want my website design like
   photo 1"): the photo-1 restyle of the three shared surfaces.
   Everything below is an override block; no earlier rule is
   edited, so stripping this block returns check157's CSS byte
   for byte.

   1. SITE HEADER (public pages; admin keeps its compact header
      untouched — every rule here is scoped body.pub): the plain
      brand row becomes the owner's emblem artwork centered on
      white (header-emblem.webp — medallion, cherry blossoms and
      gold swirls cropped from his high-resolution art; the pills
      baked into that art are NOT used). Under it, the live pills
      row: rose phone pill, the gold heart/divider ornament, and
      the white Book pill with its calendar icon (check157's
      BookCta label still drives its text). The hamburger rides
      at the emblem's level on the right; the menu and its panel
      are the same components, recolored to the light masthead in
      every theme — the artwork is fixed brand art, so the
      masthead keeps photo 1's white ground even under the dark
      Evening Glamour theme (whose --header-bg is near-black).
   ═══════════════════════════════════════════════════════════════════ */
body .site-header { background:#fff; }
body.pub.thed .site-header { background:#fff; border-bottom:1px solid #f0e2dd; }
body.pub.thed .site-header .site-nav { background:#fff; }
body.pub.thed .site-header .site-nav a { color:var(--charcoal); border-top-color:#f0e2dd; }
body.pub.thed .site-header .site-nav a.active { color:var(--rose-dark); }
body.pub.thed .site-header .nav-toggle span { background:var(--charcoal); }
body .header-inner { flex-wrap:wrap; min-height:0; padding-top:10px; }
body .brand-art { order:0; flex:1 1 100%; display:flex; justify-content:center; }
/* the aspect-ratio reserves the artwork's box before it loads,
   so the masthead never grows and shoves the page down
   mid-tap (the screen must not move — check155's rule). */
body .brand-art img { width:min(400px, 96%); height:auto; aspect-ratio:820 / 190; }
body .nav-toggle { position:absolute; top:30px; right:12px; margin-left:0; z-index:60; }
body .header-pills { order:2; }
body .hdr-orn { display:flex; align-items:center; justify-content:center; flex:0 0 auto; }
body .header-book svg { flex:0 0 auto; }
@media (min-width: 768px) {
    body .header-inner { flex-direction:column; align-items:center; flex-wrap:nowrap; padding-top:16px; padding-bottom:16px; }
    body .brand-art { flex:0 1 auto; }
    body .brand-art img { width:min(520px, 72vw); }
    body .header-pills { margin:8px 0 0; }
    body .site-nav { order:3; margin:10px 0 0; justify-content:center; }
}

/* check161 (owner, Oct 25, 2026 — the new home design): the
   Explore Our Services section that replaces the homepage
   hero + featured cards. Heading in rose serif with a short
   rule each side, the letterspaced tagline under it, and the
   2-wide grid of eight cards: photo on top, a cream ARCH panel
   domed over the photo's lower part carrying the line icon,
   the name, the subtitle and the rose arrow circle, with the
   blossom sprig (card-sprig.webp, one crop) mirrored into the
   panel's bottom corners. The sprig is a plain crop on the
   design's own panel cream (the panel color below is that
   cream, sampled), its rectangle edges faded by a radial
   mask so no crop line can show. */
.explore { padding-top:30px; }
.explore-head { display:flex; align-items:center; justify-content:center; gap:16px; }
.explore-rule { flex:0 1 54px; height:1.5px; background:#d8a7ad; }
.explore-title { font-family:"Playfair Display",Georgia,serif; font-weight:600; color:var(--rose-dark); font-size:clamp(1.65rem,6vw,2.35rem); text-align:center; margin:0; white-space:nowrap; }
.explore-tag { text-align:center; color:#8d837c; font-weight:500; font-size:clamp(.45rem,2.15vw,.72rem); letter-spacing:.12em; margin:10px 0 0; white-space:nowrap; }
/* check227 (owner, Oct 29, 2026): the four nav cards restyled
   to his contemporary reference — photo feathering into a
   cream panel laid out as a ROW (pink icon disc with a gold
   ring, serif title + uppercase subtitle, maroon arrow
   circle). One card per row on phones. */
.xgrid { display:grid; grid-template-columns:1fr; gap:18px; margin-top:26px; }
.xcard { position:relative; display:flex; flex-direction:column; background:#fffaf3; border:1px solid #e6c88f; border-radius:26px; overflow:hidden; box-shadow:0 12px 28px rgba(150,85,95,.15); text-decoration:none; color:inherit; }
.xcard-photo { display:block; aspect-ratio:354 / 185; position:relative; overflow:hidden; }
/* check169: the img must be ABS positioned — in-flow, its natural
   height beat the wrapper's aspect-ratio (content can grow an
   auto-height ratio box), so each card's photo took its own
   image's natural proportions and the four cards rendered at
   different sizes on desktop (owner, Oct 26, 2026). Absolute
   positioning takes the img out of the box's sizing entirely:
   the ratio rules, object-fit crops, all four photos identical. */
.xcard-photo img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block; }
/* check227: the photo feathers into the panel cream. */
.xcard-photo::after { content:""; position:absolute; left:0; right:0; bottom:0; height:46%; background:linear-gradient(to bottom, rgba(250,240,227,0), #faf0e3); pointer-events:none; }
.xcard-arch { position:relative; z-index:1; display:flex; align-items:center; gap:14px; background:#faf0e3; margin-top:-28px; padding:16px 18px 18px; flex:1; }
.xcard-ic { flex:none; width:58px; height:58px; border-radius:50%; display:flex; align-items:center; justify-content:center; background:linear-gradient(160deg,#f7dcdd,#eec6c9); border:2px solid #d9a75f; color:#5b2333; }
.xcard-text { flex:1; min-width:0; display:block; }
.xcard-name { display:block; font-family:"Playfair Display",Georgia,serif; font-weight:600; font-size:1.45rem; color:#3d2320; }
.xcard-sub { display:block; color:#8a6f5c; font-size:.68rem; font-weight:600; letter-spacing:.14em; text-transform:uppercase; margin-top:4px; }
.xcard-arrow { flex:none; display:flex; align-items:center; justify-content:center; width:44px; height:44px; border-radius:50%; background:linear-gradient(160deg,#b3555f,#96404c); color:#fff; margin:0; }
@media (min-width: 768px) {
    .explore { padding-top:38px; }
    .xgrid { grid-template-columns:1fr 1fr; gap:24px; margin-top:32px; }
    .xcard-name { font-size:1.55rem; }
}

/* check158, surface 2 — the page-top band's two pills take
   photo 1's treatment: equal halves of the band's width, a
   taller pill, centered labels. The band itself (photo, kicker,
   script title, gold rule) already matches photo 1 and is
   untouched, as are the active-pill fill and the two-pill rule. */
.page-top-nav { gap:10px; }
.page-top-pill { flex:1 1 0; text-align:center; padding:11px 14px; font-size:.95rem; }
@media (max-width: 420px) {
    .page-top-pill { padding:10px 8px; font-size:.86rem; }
}
@media (max-width: 360px) {
    .page-top-pill { padding:10px 5px; font-size:.8rem; }
}

/* check158, surface 3 — the confirmation card grows photo 1's
   blossom sprigs: one sprig image (conf-sprig.webp, cropped from
   the owner's header art) fans out at each lower side of the
   gold medallion, tucked behind its ring; the right sprig is
   the same image mirrored. The wrap carries the medallion's
   overlap margin so the bare medallion (error pages) is
   unchanged. The gold-bordered details box, centered name and
   service, bottle, and icon-chip rows already match photo 1
   and are untouched. */
.conf-medwrap { position:relative; z-index:2; width:104px; margin:-56px auto 0; }
.conf-medwrap .conf-medallion { margin:0 auto; }
.conf-sprig { position:absolute; bottom:-12px; width:86px; height:auto; z-index:-1; pointer-events:none; }
.conf-sprig-l { right:64px; }
.conf-sprig-r { left:64px; transform:scaleX(-1); }

/* check160 — the admin text set as ONE table (owner-approved
   mockup text-set-table-component-v2.html, style locked in
   activation-link-design.md): three rows always — Text
   Reminder, Google Review, Appointment Confirmation — in the
   Edit screen and on her profile alike. Icon circles 32px;
   action labels bold rose-dark; a row whose action is
   unavailable greys (tr.off); status checks grey #c4bab4 /
   blue #2f7fd0; the time beside a check is quiet #8a6f66 13px;
   her tap count is blue bold. Row 2's check is the set's one
   manual toggle — a bare button inside its own small form. */
/* check229 (owner, Oct 29, 2026): the text set is a 2x2 GRID
   OF COMPACT TILES now (approved sample
   mockups/four-links-combined-sample.html) — the tall table
   rows are gone. Tile: soft border, 16px radius, light cream,
   padding 12px 8px 10px; the icon disc centers on top, the
   label sits under it, the check badge rides the top-right
   corner, and the recorded time / count shows as a small
   quiet meta line under the label. */
.textset-grid { display:grid; grid-template-columns:1fr 1fr; gap:10px; margin:0 0 14px; }
.textset .tstile { position:relative; border:1.5px solid #eee0d4; border-radius:16px; background:#fffdf9; padding:12px 8px 10px; text-align:center; }
.textset .tstile .ts-ic { display:block; }
.textset .tstile .icx { width:56px; height:56px; font-size:25px; }
.textset .tstile .icx svg { width:28px; height:28px; }
.textset .tstile .ts-ck { position:absolute; top:8px; right:8px; }
.textset .tstile .ck { width:28px; height:28px; font-size:15px; }
.textset .icx { display:inline-flex; align-items:center; justify-content:center; width:32px; height:32px; border-radius:50%; font-size:16px; font-weight:900; }
.textset .ic-mail { background:#f7efe8; color:#96555f; border:1.5px solid #e7d8cf; }
.textset .ic-g { background:#fff; color:#4285F4; border:1.5px solid #d8d8d8; font-family:Arial,sans-serif; }
/* check229 (owner, Oct 29, 2026): the Recommend Online Booking
   row's chain-link icon — same cream circle family as the
   envelope icons (the approved sample's link glyph). */
.textset .ic-link { background:#f7efe8; color:#96555f; border:1.5px solid #e7d8cf; }
.textset .tstile .ts-lb { display:block; margin-top:8px; font-size:16.5px; font-weight:700; line-height:1.2; color:#96555f; }
.textset .tstile .ts-lb a { color:#96555f; text-decoration:none; }
.textset .tstile.off .ts-lb { color:#b9b0aa; }
.textset .tstile .ts-meta { display:block; margin-top:3px; font-size:14px; }
.textset .tstile .ts-meta .tm { margin-right:0; }
/* check174 (owner, Oct 26, 2026): the text set's check is a
   round BADGE now — the shared _CheckBadge control (design of
   record: mockups/textset-check-sample.html). ON = green disk
   with a bold white check; OFF = gray disk with a white check.
   It replaces the small bare grey / blue checks (.ck.grey /
   .ck.blue are gone — nothing renders them any more). */
.textset .ck { display:inline-flex; align-items:center; justify-content:center; width:34px; height:34px; border-radius:50%; color:#fff; font-size:19px; font-weight:900; line-height:1; vertical-align:middle; }
.textset .ck.off { background:#c6bcb4; }
.textset .ck.on { background:#2e9e4f; box-shadow:0 3px 8px rgba(46,158,79,.35); }
.textset .tm { color:#8a6f66; font-size:13px; margin-right:7px; }
.textset .cnt { color:#2f7fd0; font-weight:700; }
.textset .ckform { display:inline; margin:0; }
.textset .ckbtn { background:none; border:none; padding:0; margin:0; cursor:pointer; font:inherit; }

/* ════════════════════════════════════════════════════════════
   check163 (owner, Oct 25, 2026) — appended block. Stripping
   this block returns check162's CSS byte for byte.

   1. HEADER BAND FULL-BLEED (public pages only — every rule
      is scoped body.pub; the admin header carries no pub
      class and cannot move): "Stretch all the way to left
      right and top. No Margin." The masthead's wrap loses its
      width cap and side/top padding, the emblem artwork fills
      the band's full width flush to the viewport's top edge,
      and the pills row keeps its side inset of its own. The
      hamburger (absolute, top right) is untouched and stays
      reachable over the artwork.
   2. THE VIEW-SWITCH PILL: one floating pill fixed at the
      bottom LEFT corner, rendered only for the signed-in
      owner (see _Layout / OwnerViewMode). White in admin
      mode, rose-filled in customer mode. z-index sits above
      the sticky header (50), below the lightbox (100).
   3. /Services BIG RECTANGLES: the logo hub stays a circle,
      centered at the top of the section; the five categories
      are big rectangles — full-width stacked on the phone, a
      2-wide grid of large cards on desktop — wearing the same
      rose ribbon name band (the shared .svc-ribbon rule). The
      pop-down panels keep their rules above; the two display
      rules below re-scope the ring's .svc-orbit.js gating to
      the new container. The ring's own rules above are dead
      (no element carries those classes anymore).
   ════════════════════════════════════════════════════════════ */
body .header-inner { max-width:none; padding-top:0; padding-left:0; padding-right:0; }
body .brand-art { display:block; }
body .brand-art img { width:100%; }
/* check169 (owner, Oct 26, 2026 — "the logo on top is
   humongous" on computer): the full-bleed rule above scales the
   820x190 artwork to the whole window, so on a desktop monitor
   the band runs 400px+ tall. On wide screens the artwork is
   capped and centered instead; its right edge tone (#fef8f3)
   becomes the band's ground so the artwork's plain-cream right
   side melts into it and no seam shows. Phones keep the
   full-bleed band exactly as designed. */
@media (min-width: 1024px) {
    body .brand-art { background:#fef8f3; }
    body .brand-art img { width:min(880px, 100%); margin:0 auto; }
}
@media (max-width: 767px) {
    /* 12px, not 20: at 390px the CHANGE APPOINTMENT pair needs
       356px of content — 20px insets left only 350 and the row
       overflowed the viewport by 11px (proof161_on163 caught
       it). min-width:0 lets the flex row itself never force
       the page wider than the viewport. */
    body .header-pills { padding-left:12px; padding-right:12px; min-width:0; }
}
@media (min-width: 768px) {
    body .header-inner { padding-top:0; }
    body .brand-art { align-self:stretch; flex:0 1 auto; }
}

.view-pill-form { position:fixed; left:10px; bottom:10px; z-index:90; margin:0; }
.view-pill { appearance:none; -webkit-appearance:none; border-radius:999px; padding:11px 18px; font-family:var(--font-body); font-weight:600; font-size:.95rem; line-height:1.2; cursor:pointer; box-shadow:0 6px 18px rgba(86,48,54,.28); }
.view-pill-view { background:#fff; color:var(--rose-dark); border:1.5px solid var(--rose); }
.view-pill-back { background:var(--rose); color:#fff; border:1.5px solid var(--rose); }

/* check244 (owner, Oct 29, 2026): the view pill's DEV segment
   (Admin mode only; markup in _Layout) is an anchor wearing
   the segment styles — it needs flex centering and no
   underline. The four-segment pill (.four) uses the
   approved sample's smaller text (17px) and tighter segment
   padding (15px) so all four segments fit a phone screen;
   the three-segment pill keeps its original sizing. */
.view-pill3 .vp3-dev { display:flex; align-items:center; text-decoration:none; }
.view-pill3.four .vp3-seg { font-size:17px; padding:10px 15px; }

.svc-rects { margin-top:26px; }
.svc-logo-hub {
    width:150px;
    aspect-ratio:1;
    border-radius:50%;
    background:#fffdfb;
    border:2.5px solid var(--gold);
    display:flex;
    align-items:center;
    justify-content:center;
    overflow:hidden;
    margin:0 auto 22px;
}
.svc-logo-hub img { width:88%; }
.svc-cards { display:grid; grid-template-columns:1fr; gap:18px; }
.svc-rect { display:block; text-decoration:none; border-radius:22px; }
.svc-rect-photo {
    display:block;
    position:relative;
    width:100%;
    aspect-ratio:3 / 2;
    border-radius:22px;
    border:3px solid var(--gold);
    overflow:hidden;
    background:#fff;
}
.svc-rect-photo img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block; }
/* the ribbon rides lower on a rectangle than it did on the
   disc — across the photo's lower portion, off its bottom
   edge zone (the shared .svc-ribbon rule sets the rest). */
.svc-rect-photo .svc-ribbon { bottom:12%; font-size:1.15rem; padding:7px 6px; }
.svc-rect.open .svc-rect-photo { border-color:var(--rose-dark); box-shadow:0 0 0 5px #f3d9d7; }
.svc-rects.js .svc-panel { display:none; }
.svc-rects.js .svc-panel.open { display:block; animation:svc-pop .18s ease-out; }
@media (min-width: 768px) {
    .svc-cards { grid-template-columns:1fr 1fr; }
    .svc-logo-hub { width:180px; }
}

/* ════════════════════════════════════════════════════════════
   check164 (owner, Oct 25, 2026) — appended block. Stripping
   this block returns check163's CSS byte for byte.

   Item 2 — NO SHOW TIME GATE: the Edit screen's No Show status
   pill and "Mark No Show" button render disabled while the
   appointment's start time is still ahead. The pill takes the
   same greyed treatment as a blocked time pill; a disabled
   .btn (the Mark No Show button) dims and loses its pointer. */
.pill-btn.status-btn:disabled { background:#e9e4e1; border-color:#d8cfc9; color:#9a8f8a; cursor:not-allowed; box-shadow:none; }
.btn:disabled { opacity:.45; cursor:not-allowed; }

/* ════════════════════════════════════════════════════════════
   check165 (owner, Oct 26, 2026) — appended block. Stripping
   this block returns check164's CSS byte for byte.

   Item 2 — BAND PILLS ONE LINE (owner, from the /Visit band:
   "Search appointment is 1 inline. Book appointment in middle
   of button"): the shared page-top band's two pills rendered
   unevenly — "Search Appointment" wrapped to two lines at
   phone widths while "Book Appointment" sat on one, so the
   pills stood at different heights with the labels riding
   high. Both labels now stay on ONE line (nowrap, slightly
   smaller type at phone widths), the two pills share one
   height, and each label is vertically centered in its pill.
   Fills, border, and the active state are untouched, as are
   the site header's own CALL US / BOOK NOW pills. */
.page-top-nav { flex-wrap:nowrap; }
.page-top-pill { display:flex; align-items:center; justify-content:center; min-width:0; white-space:nowrap; }
@media (max-width: 420px) {
    .page-top-pill { padding:10px 6px; font-size:.82rem; }
}
@media (max-width: 360px) {
    .page-top-pill { padding:10px 4px; font-size:.78rem; }
}

/* Item 3 — INSTAGRAM LINK ICON (owner, Oct 26, 2026: "Big
   Instagram symbol first then the wording"): the /Visit page's
   "Find us on Instagram" link was plain underlined text. A
   large inline-SVG glyph (30px, the camera outline) now leads
   the wording, vertically centered with it, in the link's own
   rose tone (currentColor). The wording, target, and the
   footer's separate "Instagram" link are unchanged. */
.insta-link { display:inline-flex; align-items:center; gap:9px; }
.insta-icon { width:30px; height:30px; flex:0 0 auto; }

/* Item 5 — BIG GREEN CHECK (owner, Oct 26, 2026: "make the
   check icon big green every time"): the confirmation
   medallion's check grows from 50px to 70px inside the same
   104px gold-ring medallion and turns green — the glyph's own
   stroke is #1d9d4e (set in _ConfirmationCard.cshtml), a clear
   green that reads against the cream medallion. Only the
   shared confirmation card carries an svg.conf-check, so the
   error pages' text medallions and the admin Book's grey/blue
   verification checks are untouched. */
.conf-medallion svg.conf-check { width:70px; height:70px; }

/* ════════════════════════════════════════════════════════════
   check166 (owner, Oct 26, 2026) — appended block. Stripping
   this block returns check165's CSS byte for byte.

   DETAILS BOX LABELS (owner, from the confirmation card's
   details box: "Remove the words date time. Replace Word
   Location with A+ Nails (use fancy font) as the top"): the
   shared confirmation card's Date and Time rows lose their
   small label words entirely — the existing icon chip and
   the big value carry each row alone (the row is flex
   align-items:center, so the chip centers on the value).
   The Location block's top line is now the salon's name in
   the Great Vibes fancy script (self-hosted, see the
   @font-face above), prominent at 30px, in rose-dark so it
   reads on the white box, sitting where the LOCATION label
   sat — above the unchanged address and phone links. The
   old .conf-lab rule stays in the file above, now unused by
   the card; nothing else renders it. */
.conf-salonname { display:block; font-family:"Great Vibes", cursive; font-weight:400;
  font-size:30px; line-height:1.15; color:var(--rose-dark); margin-bottom:2px; }

/* ════════════════════════════════════════════════════════════
   check167 (owner, Oct 26, 2026) — appended block. Stripping
   this block returns check166's CSS (modulo the header
   selector un-gating in the header blocks above, item 13).

   THE APPOINTMENT PAYMENT + BILL build. The bill component
   (.bill — the shared _Bill partial; BillImage draws the same
   layout into the stored PNG), the Edit screen's PAYMENT
   block (.pay-block), her pay page's wallet / Zelle options
   (check178: Cash App removed), the Book card's PAID stamp (item 9), the
   payment banner tint (item 8 — the banner itself reuses the
   .booking-alert component), and the profile history lines. */
.bill { max-width:430px; margin:0 auto; }
.bill-frame { background:#fffdfb; border:1.5px solid var(--gold); border-radius:26px; overflow:hidden; box-shadow:0 18px 50px rgba(150,85,95,.22), inset 0 0 0 5px #fffdfb, inset 0 0 0 6.5px var(--gold); padding-bottom:18px; }
/* check216 (owner, Oct 28, 2026 — sample mockups/restricted-confirm-sample.html):
   the restricted-list customer's booking CONFIRM PANEL — the
   bill-frame card (the .bill-frame rule above carries the gold
   double frame) with the message and the Confirm / Not now pair,
   shown once per booking under her pick summary, plus that summary
   card itself (her service + when, exactly as the sample draws it). */
.confirm-panel { padding:24px 22px 22px; margin-top:16px; }
.confirm-msg { font-size:16.5px; line-height:1.55; color:var(--charcoal); margin:0 0 20px; }
.confirm-btns { display:flex; gap:10px; }
.confirm-btns .btn-call { flex:1.35; }
.confirm-btns .btn-outline { flex:1; background:#fff; }
.picked-summary { background:#fff; border:1px solid #ecdcd6; border-radius:16px; box-shadow:0 6px 22px rgba(150,85,95,.12); padding:12px 14px; display:flex; align-items:center; gap:10px; margin-top:16px; }
.picked-summary .svc { display:inline-flex; align-items:center; gap:8px; font-weight:700; font-size:15px; color:var(--charcoal); }
.picked-summary .coin { width:26px; height:26px; font-size:.85rem; }
.picked-summary .when { margin-left:auto; text-align:right; font-size:14px; font-weight:600; color:var(--rose-dark); line-height:1.3; white-space:nowrap; }
.bill-emblem { width:100%; height:auto; display:block; }
.bill-thanks { font-family:"Great Vibes", cursive; font-size:44px; line-height:1.15; color:var(--rose-dark); text-align:center; margin-top:14px; padding:0 16px; }
.bill-divider { display:flex; align-items:center; justify-content:center; gap:10px; margin:8px 0 4px; }
.bill-div-line { width:64px; height:2px; background:var(--gold); display:block; }
.bill-heart { color:var(--rose); font-size:17px; }
.bill-items { padding:8px 26px 0; }
.bill-item { display:flex; justify-content:space-between; gap:14px; padding:6px 0; font-size:16.5px; color:var(--charcoal); }
.bill-item-price { font-weight:600; white-space:nowrap; }
.bill-totals { margin:14px 18px 0; background:linear-gradient(180deg, var(--rose-soft), #f6e3de); border-radius:16px; padding:14px 18px; }
.bill-trow { display:flex; justify-content:space-between; gap:14px; font-size:16px; color:var(--charcoal); padding:3px 0; }
.bill-trow.bill-tip { color:var(--rose-dark); }
.bill-trule { height:2px; background:var(--gold); margin:8px 0; }
.bill-trow.bill-total { font-family:var(--font-display); font-size:22px; font-weight:700; }
.bill-stamp-row { display:flex; align-items:center; justify-content:space-between; gap:12px; padding:16px 26px 6px; min-height:86px; }
.bill-paidline { font-size:13.5px; color:#8a6f66; }
.bill-stamp { font-weight:800; font-size:19px; letter-spacing:.04em; padding:7px 14px; border:3px solid; border-radius:8px; transform:rotate(-8deg); background:rgba(255,255,255,.65); white-space:nowrap; }
.bill-stamp-due { color:#8a8378; border-color:#8a8378; }
.bill-stamp-paid { color:#2e7d43; border-color:#2e7d43; }
/* check179 (owner, Oct 26, 2026 — "Build the footer like this
   sample", mockups/bill-footer-sample.html #4): the footer's
   decorated block. The sample was drawn on a 470px frame; the
   bill's frame is 430px at most and narrower on phones, so the
   name row scales WITH the footer (container units, with
   fixed-size fallbacks first) — the sample's proportions hold
   at every width and nothing ever clips. No graphics sit over
   any letter. */
.bill-foot { text-align:center; padding:22px 16px 0; container-type:inline-size; }
.bill-foot-orn { display:flex; align-items:center; justify-content:center; gap:10px; margin-bottom:12px; }
.bill-foot-orn .bill-div-line { width:52px; }
.bill-foot-name { display:flex; align-items:center; justify-content:center; gap:12px; gap:3cqw; }
.bill-foot-sprig { height:32px; height:8.8cqw; width:auto; flex:0 0 auto; }
.bill-foot-sprig.flip { transform:scaleX(-1); }
.bill-sign { font-family:"Great Vibes", cursive; font-size:40px; font-size:11cqw; line-height:1.1; color:var(--rose-dark); white-space:nowrap; padding-top:4px; }
.bill-addr { font-size:13.5px; color:#8a6f66; line-height:1.45; }
.bill-foot .bill-addr { margin-top:10px; }
.bill-web { font-size:14.5px; font-weight:700; letter-spacing:.22em; color:#a8861b; margin-top:7px; margin-right:-.22em; }
/* check182 (owner, Oct 27, 2026 — approved sample
   mockups/pay-page-sample6): the totals box's ONE total — the
   stamp treatment scaled up, centered in the box, the biggest
   number on the bill — and the paid line's own row under the
   box (the corner stamp row is gone). */
.bill-total-stamp { display:flex; justify-content:center; padding-top:10px; }
.bill-stamp.bill-total-big { font-size:31px; font-weight:800; border-width:4px; border-radius:10px; padding:10px 22px; letter-spacing:.03em; }
.bill-paidline-row { text-align:center; padding:12px 26px 0; }
/* check182: THE TIP SECTION — one shared treatment (the
   COMPONENTS-FIRST rule): the /Pay bill picker (inside the
   bill's top via _Bill) and the standalone /Pay card both
   render this same section. (Its LOOK is check187's, below;
   the section's structure and behavior remain check182's.) */
/* check187 (owner, Oct 27, 2026 — approved Sample E,
   mockups/tip-sample-E.html): THE TIP SECTION restyled to
   GOLD LUXURY, the same one shared treatment as always: a
   cream panel with a DOUBLE gold frame (the gold border
   plus the pale-gold inset ring) and the blossom-branch SVG
   sweeping its top edge; "ADD A TIP" in rose-dark Playfair
   with a gold heart; the six pills white with gold borders
   and rose-dark bold text — percent on top, its dollar
   amount directly under it — in a grid of TWO ROWS OF
   THREE; the selected pill a deep rose fill with white
   text and a gold ring (the shared yellow .sel stays every
   other pill group's — it is overridden inside .tip-sec
   only); the Custom field wide under the rows, white with
   a gold border to match. Presentation only: the tip gate,
   the preset amounts, the totals and every behavior are
   check182's, unchanged. (check201 supersedes the wide
   Custom field: see the note at the .tip-custom rules.) */
.tip-sec { --gold-pale:#eed682; position:relative; margin:26px 0 4px; border-radius:22px; padding:40px 18px 18px; background:linear-gradient(180deg, #fffaf3, #fdf3ec); border:1.5px solid var(--gold); box-shadow:0 10px 24px rgba(160,120,40,.18), inset 0 0 0 5px #fffaf3, inset 0 0 0 6.5px var(--gold-pale); }
.tip-sec .tip-branch { position:absolute; top:-16px; left:50%; transform:translateX(-50%); width:330px; max-width:92%; height:42px; pointer-events:none; }
.tip-sec .tip-lab { font-family:var(--font-display); font-size:23px; letter-spacing:.14em; color:var(--rose-dark); text-align:center; margin:0 0 16px; font-weight:700; }
.tip-sec .tip-lab .heart { color:var(--gold); font-size:19px; vertical-align:2px; margin-left:7px; }
.tip-sec .tip-row { display:grid; grid-template-columns:1fr 1fr 1fr; gap:10px; position:relative; z-index:1; }
.tip-sec .tip-row .pill-btn { width:auto; height:70px; padding:0 4px; background:#fff; border:1.5px solid var(--gold); border-radius:999px; color:var(--rose-dark); font-size:21px; font-weight:700; line-height:1.1; white-space:nowrap; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:2px; box-shadow:0 3px 8px rgba(160,120,40,.16); }
.tip-sec .tip-row .pill-btn .tip-pct { font-size:23px; font-weight:700; line-height:1.05; }
.tip-sec .tip-row .pill-btn .tip-amt { font-size:16.5px; font-weight:600; line-height:1.1; letter-spacing:0; color:#a4575f; opacity:1; }
.tip-sec .tip-row .pill-btn.sel { background:linear-gradient(160deg, #a9606c, var(--rose-dark)); color:#fff; border-color:var(--gold); box-shadow:0 0 0 2px #fffaf3, 0 0 0 4.5px var(--gold), 0 8px 18px rgba(150,85,95,.42); }
.tip-sec .tip-row .pill-btn.sel .tip-amt { color:#ffeec9; }
/* check201 (owner, Oct 27, 2026 — approved sample
   mockups/pay-tip-sample.html): the WIDE Custom field under
   the rows is REMOVED — the custom amount entry is now ONE
   compact pill-shaped field under the grid (same gold border,
   pill radius, the section's own type size, capped at two
   pills wide and centered), still shown only when Custom is
   picked. The ids, the wiring and the tip gate are
   untouched. */
.tip-sec .tip-custom { border:1.5px solid var(--gold); border-radius:999px; padding:0 22px; background:#fff; margin:12px auto 0; max-width:230px; height:54px; display:flex; align-items:center; gap:8px; box-shadow:0 3px 8px rgba(160,120,40,.14); position:relative; z-index:1; }
.tip-sec .tip-custom span { color:var(--rose-dark); font-size:20px; font-weight:700; }
.tip-sec .tip-custom input { flex:1; border:0; outline:0; font-size:20px; font-weight:700; font-family:inherit; color:var(--charcoal); background:transparent; min-width:0; }
.tip-sec.bill-tip-sec { margin:26px 14px 4px; }
.bill-wrap { max-width:470px; }
.bill-photo { width:100%; height:auto; display:block; border-radius:18px; box-shadow:0 14px 40px rgba(150,85,95,.25); }
.bill-save { display:block; width:100%; margin-top:16px; text-align:center; }
.pay-options { margin-top:18px; }
.wallet-btn { min-height:48px; margin-top:12px; }
.wallet-btn:empty { display:none; margin:0; min-height:0; }
.zelle-panel { display:flex; align-items:center; justify-content:space-between; gap:12px; margin-top:12px; border:1.5px solid #6d1ed4; color:#3c0a75; border-radius:14px; padding:13px 16px; font-size:16px; background:#faf6ff; }
.zelle-amt { font-size:19px; }
.pay-block .pay-rows { display:flex; flex-direction:column; gap:8px; }
.pay-block input[type="text"] { box-sizing:border-box; padding:11px 12px; font-size:1rem; border:1.5px solid #d9a094; border-radius:12px; font-family:inherit; background:#fff; color:var(--charcoal); }
.pay-block input[type="text"]:disabled { background:#f3efed; color:#9a8f8a; }
.pay-row { display:flex; gap:8px; align-items:center; }
.pay-label { flex:1 1 auto; min-width:0; }
.pay-amt { flex:0 0 96px; width:96px; text-align:right; }
.pay-remove { flex:none; width:36px; height:36px; border-radius:50%; border:1.5px solid #d9a094; background:#fff; color:#8c4a3f; font-size:15px; cursor:pointer; }
.pay-add { width:100%; margin-top:10px; }
.pay-total-row { display:flex; justify-content:space-between; align-items:center; margin:14px 0; font-size:17px; }
/* check199: Text Her the Payment Link + Copy Payment Link share
   one row in the payment block — equal halves, both labels on
   ONE line at phone width (the band-pills lesson: the row's own
   type steps down, never wraps). */
.pay-textrow { display:flex; gap:10px; }
.pay-textrow .btn { flex:1 1 0; min-width:0; white-space:nowrap; padding-left:2px; padding-right:2px; font-size:13px; }
.pay-textrow .btn:first-child { flex-grow:1.3; }
@media (max-width:374px) { .pay-textrow .btn { font-size:12px; } }
.pay-total-row strong { font-size:20px; }
.pay-markpaid { margin-top:20px; border-top:1px solid #f0e2da; padding-top:16px; }
.pay-methods { display:grid; grid-template-columns:1fr 1fr; gap:8px; }
.pay-tip-row { margin-top:10px; }
.pay-tip-label { font-weight:700; color:var(--rose-dark); }
.pay-paid-record { display:flex; flex-direction:column; gap:6px; }
.pay-paid-line { display:flex; justify-content:space-between; font-size:16px; }
.pay-paid-line strong { font-size:18px; }
.pay-history-line { display:flex; justify-content:space-between; gap:12px; padding:8px 0; border-top:1px solid #f0e2da; font-size:15px; }
.pay-history-line:first-of-type { border-top:0; }
.pay-history-line a { flex:none; font-weight:700; }
/* check171: the PAY RECORDS lines (shared component _PayRecords —
   the Payment page's records and the profile payment history).
   One line per visit: paid shows its amounts, unpaid shows the
   green dash; the dash editor opens in place under its line. */
.pay-rec-line { display:block; padding:10px 0; border-top:1px solid #f0e2da; font-size:15.5px; color:inherit; text-decoration:none; }
.pay-rec-line:first-of-type { border-top:0; padding-top:2px; }
a.pay-rec-line:hover .pay-rec-main span:first-child { text-decoration:underline; }
.pay-rec-main { display:flex; justify-content:space-between; align-items:center; gap:12px; }
.pay-rec-main strong { font-size:16.5px; flex:none; }
.pay-rec-sub { display:block; margin-top:2px; color:#8a6f66; font-size:14.5px; }
.pay-rec-dash { flex:none; border:0; background:none; padding:2px 10px; margin:-2px -6px; font-size:21px; font-weight:900; line-height:1; color:#2e9e4f; cursor:pointer; font-family:inherit; }
.pay-rec-dash-static { flex:none; padding:2px 10px; margin:-2px -6px; font-size:21px; font-weight:900; line-height:1; color:#2e9e4f; }
.pay-rec-editor { margin-top:10px; border-top:1px dashed #e7d8cf; padding-top:12px; }
.pay-rec-total { display:flex; justify-content:space-between; align-items:center; margin-bottom:12px; font-size:16.5px; }
.pay-rec-total strong { font-size:18px; }
.pay-rec-editor .pay-amt { flex:0 0 110px; width:110px; text-align:right; box-sizing:border-box; padding:11px 12px; font-size:1rem; border:1.5px solid #d9a094; border-radius:12px; font-family:inherit; background:#fff; color:var(--charcoal); }
/* check171: the Receipt Image button — the gold outline of the
   paid state (the design of record's highlighted button). */
.btn-gold { background:#fff; color:var(--rose-dark); border:2px solid var(--gold); }
.btn-gold:hover { background:#fdf6e0; }
/* Item 8: a DECLINED payment banner keeps the alert red; a
   PAID one goes green — the banner shape is the shared
   .booking-alert either way. */
.booking-alert.pay-alert-paid { background:#2e7d43; box-shadow:0 4px 14px rgba(46,125,67,.35); }
/* Item 9: the Book card's big green PAID stamp. */
.paid-stamp { position:absolute; left:50%; top:52%; transform:translate(-50%,-50%) rotate(-8deg); z-index:5; pointer-events:none; font-weight:800; font-size:1.28rem; letter-spacing:.06em; color:#2e7d43; border:3px solid #2e7d43; border-radius:8px; padding:1px 10px; background:rgba(255,255,255,.55); }
.lane-card .paid-stamp { font-size:.95rem; padding:0 6px; border-width:2.5px; }

/* ============================================================
   check168 (owner, Oct 26, 2026) — appended block.
   Item 2: the payment banner becomes DESIGN A (cream/gold
   card like the bill, green medallion, detail rows, rose
   ACKNOWLEDGE pill) — these rules come after check167's
   .booking-alert.pay-alert-paid on purpose: equal specificity,
   later wins. The banner keeps .booking-alert for the Book
   script's beep count, so the red base is fully replaced here.
   Item 1: the trusted badge + the Customers trusted list.
   Item 4: bill extra lines and the Edit block's extras
   (icon controls — + / pen / ✕ — per the owner's refinement).
   ============================================================ */
.booking-alert.pay-alert { background:#fffdfb; color:var(--charcoal); border:1.5px solid var(--gold); border-radius:20px; box-shadow:0 8px 22px rgba(86,48,54,.14); padding:18px; text-align:left; font-family:inherit; }
.booking-alert.pay-alert-paid { background:#fffdfb; box-shadow:0 8px 22px rgba(86,48,54,.14); }
.pay-alert .pa-top { display:flex; gap:14px; align-items:center; }
.pay-alert .pa-med { flex:0 0 62px; width:62px; height:62px; border-radius:50%; display:flex; align-items:center; justify-content:center; }
.pay-alert .pa-med svg { width:34px; height:34px; }
.pay-alert-paid .pa-med { background:#e7f5ec; border:3px solid #2e9e4f; }
.pay-alert-declined .pa-med { background:#fdeceb; border:3px solid #b3382e; }
.pay-alert .pa-head { display:flex; flex-direction:column; }
.pay-alert .pa-word { font-size:30px; font-weight:800; letter-spacing:1px; line-height:1; }
.pay-alert-paid .pa-word { color:#2e9e4f; }
.pay-alert-declined .pa-word { color:#b3382e; }
.pay-alert .pa-total { font-size:21px; color:var(--charcoal); margin-top:3px; }
.pay-alert .pa-rows { margin-top:13px; border-top:1px solid #f0e2da; padding-top:11px; font-size:18px; }
.pay-alert .pa-r { display:flex; justify-content:space-between; gap:14px; padding:3.5px 0; }
.pay-alert .pa-lab { color:var(--rose-dark); font-weight:700; }
.pay-alert .pa-val { text-align:right; }
.pay-alert .pa-ack { margin-top:14px; display:block; width:100%; text-align:center; background:linear-gradient(135deg,#b76e79,#96555f); color:#fff; font-size:20px; font-weight:700; letter-spacing:1px; padding:13px 0; border-radius:999px; border:none; cursor:pointer; font-family:inherit; }
.pay-alert .pa-beep { margin-top:9px; text-align:center; font-size:15px; color:#8a6f66; }
/* Item 1: trusted surfaces. */
.trusted-badge { display:inline-block; background:#e7f5ec; color:#2e7d43; border:1.5px solid #2e9e4f; border-radius:999px; padding:3px 12px; font-weight:700; }
.trusted-badge.untrusted { background:#e9e4e1; color:#8a7a76; border-color:#b9b0aa; }
/* check216 (owner, Oct 28, 2026 — sample mockups/profile-trust-restrict-sample.html):
   the profile's RESTRICTED badge — the .trusted-badge shape in rose —
   and the hairline divider inside the ONE combined profile card that
   holds the Trusted section over the Restricted section (the owner's
   "Combine those 2 into 1 table instead"). */
.restricted-badge { display:inline-block; background:var(--rose-soft); color:var(--rose-deep); border:1.5px solid var(--rose); border-radius:999px; padding:3px 12px; font-weight:700; }
.profile-divider { border:0; border-top:1px solid #ecdcd6; margin:20px 0; }
.trusted-why { color:var(--rose-dark); font-weight:600; margin-left:6px; }
.trusted-row { display:flex; gap:12px; align-items:baseline; padding:9px 0; border-top:1px solid #f0e2da; flex-wrap:wrap; }
.trusted-row:first-of-type { border-top:none; }
.trusted-name { font-weight:700; color:var(--rose-dark); font-size:1.05rem; }
.trusted-phone { color:var(--charcoal); }
.trusted-row .trusted-why { margin-left:auto; }
/* Item 4: the bill's extra lines — indented, smaller, muted. */
.bill-extra { display:flex; justify-content:space-between; gap:14px; padding:2px 0 4px 26px; font-size:14.5px; color:#8a6f66; }
.bill-extra-price { white-space:nowrap; }
/* Item 4: the Edit block's items + extras. */
.pay-item { display:flex; flex-direction:column; gap:6px; }
.pay-extras { display:flex; flex-direction:column; gap:6px; margin-left:26px; }
.pay-extra-row .pay-xlabel { flex:1 1 auto; min-width:0; }
.pay-xamt { flex:0 0 76px; width:76px; text-align:right; }
.pay-extra-row input[readonly] { border-color:transparent; background:transparent; box-shadow:none; }
/* check202: a WAIVED nail extra in the payment block — the
   line stays on the bill, struck, charged $0.00. */
.pay-waived .pay-xlabel, .pay-waived .pay-xamt { text-decoration: line-through; }
/* check203 (owner, Oct 27, 2026): the fast sub-item picks
   under each main line (the approved sample's treatment):
   a row of one-tap pills carrying name + typical price in
   the tip-pill dress (white, gold border, rose-dark bold),
   then the SMALL + on its own line below, aligned under the
   first pill — the same add-extra control, restyled from its
   old circle into the pick pill shape so the two read as one
   family; the big "+ Add line" at the block's bottom stays
   the main-line adder. */
.pay-picks { display:flex; flex-direction:column; gap:8px; }
.pay-pickrow { display:flex; flex-wrap:wrap; gap:9px; }
.pay-pick { border:1.5px solid var(--gold); background:#fff; border-radius:999px; padding:10px 15px; font-size:15px; font-weight:700; color:var(--rose-dark); cursor:pointer; box-shadow:0 1px 2px rgba(150,85,95,.10); }
.pay-pick:disabled { opacity:.45; cursor:default; }
.pay-add-extra { border:1.5px solid var(--gold); background:#fff; border-radius:999px; padding:9px 16px; font-size:17px; font-weight:700; line-height:1; color:var(--rose-dark); cursor:pointer; box-shadow:0 1px 2px rgba(150,85,95,.10); }
.pay-xedit { flex:0 0 34px; width:34px; height:38px; border:none; background:none; color:var(--gold); font-size:17px; cursor:pointer; padding:0; }
.pay-xedit.on { color:var(--rose-dark); }
.pay-add-extra:disabled, .pay-xedit:disabled { opacity:.45; cursor:default; }

/* check169 (owner, Oct 26, 2026): the Activity Log — the
   approved sample's treatment: a sticky bar with the title and
   the filter pills (the house pill shape: rose outline, solid
   rose gradient when on), then day labels and entry cards with
   the who chips (CUSTOMER blue / ADMIN rose / SYSTEM gray). */
.al-top { position: sticky; top: 0; background: #fdf7f4; padding: 16px 0 10px; z-index: 5; }
.al-h1 { font-family: Georgia, 'Times New Roman', serif; font-size: 26px; color: #96555f; text-align: center; cursor: pointer; margin: 0 0 4px; }
.al-titlelink { display: block; font-family: Georgia, 'Times New Roman', serif; font-size: 24px; color: #96555f; text-align: center; text-decoration: none; }
.al-titlelink .al-backarr { color: #b76e79; font-weight: 700; }
.al-pills { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin: 10px 0 6px; }
.al-pill { border: 1.5px solid #b76e79; color: #96555f; background: #fff; border-radius: 999px; padding: 8px 16px; font-size: 15px; font-weight: 600; white-space: nowrap; text-decoration: none; }
.al-pill.on { background: linear-gradient(180deg, #c47e89, #b76e79); color: #fff; border-color: #b76e79; }
.al-custname { font-family: Georgia, 'Times New Roman', serif; font-size: 24px; color: #33302d; text-align: center; margin: 8px 0 2px; }
.al-custphone { font-size: 14.5px; color: #8a6f66; text-align: center; margin-bottom: 16px; }
.al-daylabel { font-size: 12.5px; font-weight: 700; letter-spacing: 1.2px; color: #8a6f66; margin: 16px 2px 8px; }
.al-entry { background: #fff; border: 1px solid #e7d8cf; border-radius: 16px; padding: 12px 14px; margin-bottom: 10px; box-shadow: 0 1px 3px rgba(150, 85, 95, .06); position: relative; }
.al-entry.al-tap { cursor: pointer; }
.al-chev { float: right; color: #b76e79; font-size: 22px; font-weight: 700; line-height: 1; margin-top: 2px; }
.al-when { font-size: 13px; color: #8a6f66; margin-bottom: 5px; }
.al-what { font-size: 16.5px; line-height: 1.35; color: #33302d; }
.al-detail { font-size: 15px; color: #5c554f; margin-top: 3px; line-height: 1.4; }
.al-meta { font-size: 13px; color: #8a6f66; margin-top: 5px; }
.al-who { display: inline-block; font-size: 11.5px; font-weight: 700; letter-spacing: .4px; border-radius: 999px; padding: 2px 9px; vertical-align: 2px; margin-right: 7px; }
.al-who.customer { background: #e8f1fc; color: #2f7fd0; }
.al-who.admin { background: #f9e9e6; color: #96555f; }
.al-who.system { background: #efefef; color: #777; }

/* check176 (owner, Oct 26, 2026): the front-desk walk-in
   sign-in (/CheckIn) — design of record: mockups/checkin-1..4.
   A kiosk: its own band on every step, elderly-size digits, a
   big number pad, the shared service pills scaled up, one big
   OK. Fluid by clamp() so the iPad (portrait AND landscape)
   gets the same screen, larger; every tap target is at least
   64px. The admin Sign-ins list + detail (.si-*) follow
   mockups/checkin-5-admin. */
.ci-band { background: linear-gradient(180deg, #f6ddd6, #eec9c0); padding: 18px 0 14px; text-align: center; border-bottom: 2px solid var(--gold); }
.ci-emblem { width: 70px; height: 70px; border-radius: 50%; border: 2.5px solid var(--gold); background: #fff; display: inline-flex; align-items: center; justify-content: center; font-family: Georgia, serif; font-size: 25px; color: var(--rose-dark); transition: filter .6s ease; }
/* check214 (owner, Oct 28, 2026): while the desk camera is
   LIVE, the emblem itself is the indicator — a slow light-red
   gradient sweeps inside the A+ circle (the check213 corner
   dot is retired; this is the only camera-live sign). The
   gold ring and the rose-dark A+ stay; the CheckIn script
   toggles .cam-live on exactly the old dot's state (camera
   started + recorder live), with a gentle .6s settle-in. */
.ci-emblem.cam-live { background: linear-gradient(135deg, #f9dcd6, #f2a49b, #f7c8c0, #ee8f84); background-size: 300% 300%; animation: ciCamIn .6s ease, ciCamSweep 6s ease-in-out infinite alternate; }
@keyframes ciCamSweep { 0% { background-position: 0% 0%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 100%; } }
@keyframes ciCamIn { from { filter: brightness(1.3) saturate(.35); } to { filter: brightness(1) saturate(1); } }
.ci-brand { font-family: Georgia, serif; font-size: 14px; letter-spacing: 3px; color: var(--rose-dark); margin-top: 5px; }
.ci-wrap { max-width: 560px; margin: 0 auto; padding: 24px 20px 34px; }
/* check214 (owner, Oct 28, 2026): the Sign In heading wears
   the SAME Great Vibes script as the welcome's "Welcome back"
   (his ask, with screenshots) — script faces read small, so it
   is sized like a script heading, never fake-bolded (Great
   Vibes ships only 400), line-height 1.1 so the script's
   ascenders/descenders never clip. */
.ci-h1 { font-family: "Great Vibes", cursive; font-size: 54px; font-weight: 400; color: var(--rose-dark); text-align: center; margin: 0; line-height: 1.1; }
.ci-phonebox { margin-top: 22px; background: #fff; border: 2.5px solid var(--rose); border-radius: 20px; height: clamp(92px, 13vh, 128px); display: flex; align-items: center; justify-content: center; box-shadow: 0 6px 18px rgba(150, 85, 95, .12); padding: 0 10px; }
.ci-digits { font-size: clamp(34px, 7.5vw, 52px); font-weight: 700; letter-spacing: 2px; color: #33302d; white-space: nowrap; }
.ci-digits .dim { color: #d8c6bc; }
.ci-error { margin-top: 16px; background: #f9e9e6; color: var(--rose-dark); font-weight: 700; font-size: 18px; text-align: center; border-radius: 14px; padding: 12px 14px; }
.ci-pad { margin-top: 22px; display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
.ci-key { background: #fff; border: 1.5px solid #e7d8cf; border-radius: 999px; height: clamp(72px, 10.5vh, 100px); display: flex; align-items: center; justify-content: center; font-size: 32px; font-weight: 700; color: var(--rose-dark); box-shadow: 0 2px 6px rgba(150, 85, 95, .08); cursor: pointer; font-family: inherit; padding: 0; }
.ci-key:active { background: #f9e9e6; }
.ci-keyfn { font-size: 26px; color: #8a6f66; }
.ci-keyblank { cursor: default; box-shadow: none; }
.ci-ok { margin-top: 24px; display: block; width: 100%; text-align: center; border: none; border-radius: 999px; padding: 21px; min-height: 72px; font-size: 24px; font-weight: 700; color: #fff; background: linear-gradient(180deg, #c9838f, var(--rose)); box-shadow: 0 10px 22px rgba(183, 110, 121, .35); cursor: pointer; font-family: inherit; }
.ci-script { font-family: "Great Vibes", cursive; font-size: 44px; color: var(--rose-dark); text-align: center; }
.ci-name { font-family: var(--font-display); font-size: 48px; font-weight: 700; color: #33302d; text-align: center; margin-top: 2px; overflow-wrap: break-word; }
.ci-fieldlabel { display: block; font-size: 19px; font-weight: 700; color: #8a6f66; margin: 24px 0 8px 4px; text-align: left; }
.ci-textbox { width: 100%; background: #fff; border: 2.5px solid var(--rose); border-radius: 18px; height: 78px; padding: 0 22px; font-size: 30px; font-weight: 700; color: #33302d; box-shadow: 0 6px 18px rgba(150, 85, 95, .10); font-family: inherit; }
.ci-pills { margin-top: 26px; }
.ci-pills .svc-grid { display: flex; flex-wrap: wrap; gap: 14px; justify-content: center; }
.ci-pills .book-svc .slot { height: auto; min-height: 68px; padding: 12px 20px; border-width: 2px; flex: 0 1 auto; }
.ci-pills .book-svc .svc-name { font-size: 1.18rem; white-space: normal; }
.ci-pills .book-svc .coin { width: 32px; height: 32px; font-size: 1rem; }
.ci-startover { display: block; text-align: center; margin-top: 20px; font-size: 17px; font-weight: 600; color: #8a6f66; }
.ci-check { width: 128px; height: 128px; margin: 34px auto 0; border-radius: 50%; background: linear-gradient(180deg, #3cb45e, #2e9e4f); display: flex; align-items: center; justify-content: center; color: #fff; font-size: 66px; font-weight: 900; box-shadow: 0 16px 34px rgba(46, 158, 79, .35), inset 0 0 0 5px rgba(255, 255, 255, .35); }
.ci-donename { font-family: var(--font-display); font-size: 42px; font-weight: 700; color: #33302d; text-align: center; margin-top: 30px; overflow-wrap: break-word; }
.ci-doneline { font-size: 23px; color: var(--rose-dark); font-weight: 700; text-align: center; margin-top: 8px; }
/* check192 (owner, Oct 27, 2026): the phone step's wording
   line — his exact words — on top of the phone box. */
.ci-prompt { margin-top: 20px; font-size: 20px; font-weight: 600; color: var(--rose-dark); text-align: center; }
/* check192: the pad answers on pointerdown; the browser must
   never hold a tap back to decide if it is a double-tap zoom. */
.ci-wrap { touch-action: manipulation; }
.ci-key, .ci-ok { touch-action: manipulation; }
/* check196 (owner, Oct 27, 2026): the welcome DISPLAY's
   background is the owner's own floral artwork — peonies and
   cherry blossoms framing a calm cream center — covering the
   whole screen for the welcome's 30 seconds (design of record:
   mockups/checkin-welcome-sample2.html, approved). Her info
   sits on top in that calm center under the lightest cream
   veil that keeps it readable. The services are display pills
   in the picker's look, never selectable. The layer sits under
   the owner's view-mode pill (z-index 90) so it stays
   reachable in admin/customer-view mode. */
.ci-welcome { position: fixed; inset: 0; z-index: 60; background: url("/images/checkin-welcome.jpg") center center / cover no-repeat; display: flex; align-items: center; justify-content: center; cursor: pointer; }
.ci-veil { position: relative; text-align: center; padding: 38px 30px 40px; margin: 0 18px; border-radius: 30px; background: radial-gradient(ellipse 115% 110% at 50% 50%, rgba(255, 251, 244, .82) 0%, rgba(255, 251, 244, .66) 55%, rgba(255, 251, 244, .34) 80%, rgba(255, 251, 244, 0) 100%); }
/* check214: the clamp ceiling rises 54px -> 72px so short-
   wide viewports (landscape phones) are not trapped at the
   phone size; the 700px media block below still wins on
   tablets with the full iPad sizes. */
.ci-welcome .ci-script { font-size: clamp(40px, 13.5vw, 72px); white-space: nowrap; margin-top: 2px; text-shadow: 0 1px 10px rgba(255, 251, 244, .9); }
.ci-welcome .ci-name { font-size: clamp(44px, 13vw, 58px); text-shadow: 0 1px 12px rgba(255, 251, 244, .95); }
.ci-welcome .ci-svc-label { max-width: 340px; text-shadow: 0 1px 8px rgba(255, 251, 244, .95); }
.ci-svc-label { font-size: 19px; color: var(--rose-dark); margin: 0 auto 20px; }
.ci-dpills { display: flex; flex-wrap: wrap; justify-content: center; gap: 14px; }
.ci-dpill { display: inline-flex; align-items: center; gap: 12px; background: #fffdfb; border: 1.5px solid #dfa89e; border-radius: 999px; padding: 9px 24px 9px 9px; box-shadow: 0 3px 10px rgba(150, 85, 95, .08); }
.ci-dpill .coin { width: 44px; height: 44px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; color: #fff; font-family: Arial, sans-serif; font-weight: 800; font-size: 21px; flex: none; }
.ci-dpill .coin-N { background: #22c55e; }
.ci-dpill .coin-G { background: #22c55e; }
.ci-dpill .coin-M { background: #e75480; }
.ci-dpill .coin-P { background: #e75480; }
.ci-dpill .coin-W { background: #7c3aed; }
.ci-dpill .coin-F { background: #7c3aed; }
.ci-dpill-name { font-size: 24px; font-weight: 700; color: var(--rose-dark); }
@media (min-width: 700px) {
    .ci-wrap { max-width: 880px; padding: 34px 40px 44px; }
    .ci-h1 { font-size: 78px; }
    .ci-script { font-size: 56px; }
    .ci-name { font-size: 60px; }
    .ci-emblem { width: 88px; height: 88px; font-size: 31px; }
    .ci-brand { font-size: 17px; }
    .ci-textbox { height: 92px; font-size: 34px; }
    .ci-pills .book-svc .svc-name { font-size: 1.3rem; }
    .ci-ok { font-size: 28px; min-height: 84px; }
    .ci-check { width: 160px; height: 160px; font-size: 82px; }
    .ci-donename { font-size: 52px; }
    .ci-doneline { font-size: 27px; }
    .ci-prompt { font-size: 24px; }
    /* check214: the welcome was phone-tuned (66/70) and read
       too small on the 11-inch iPad — full tablet sizes. */
    .ci-welcome .ci-script { font-size: 104px; }
    .ci-welcome .ci-name { font-size: 84px; }
    .ci-svc-label { font-size: 22px; }
    .ci-dpill-name { font-size: 27px; }
}

/* check176: the admin Sign-ins list + one-sign-in page
   (design of record: mockups/checkin-5-admin). */
.si-wrap { max-width: 860px; margin: 0 auto; padding: 20px 16px 34px; }
.si-back { display: inline-block; font-size: 16px; font-weight: 700; color: var(--rose-dark); text-decoration: none; margin-bottom: 6px; }
.si-h1 { font-family: var(--font-display); font-size: 28px; font-weight: 700; color: var(--rose-dark); margin: 0; }
.si-sub { font-size: 15.5px; color: #8a6f66; margin-top: 3px; }
.si-empty { margin-top: 16px; background: #fff; border: 1px solid #e7d8cf; border-radius: 16px; padding: 22px 16px; text-align: center; font-size: 17px; color: #8a6f66; }
.si-card { background: #fff; border: 1px solid #e7d8cf; border-radius: 16px; margin-top: 16px; padding: 6px 16px; box-shadow: 0 1px 3px rgba(150, 85, 95, .06); }
.si-row { display: flex; align-items: center; gap: 14px; padding: 15px 0; border-bottom: 1px solid #f0e2da; text-decoration: none; color: inherit; min-height: 64px; }
.si-row:last-child { border-bottom: none; }
.si-time { flex: 0 0 74px; text-align: center; background: #fdf3ec; border: 1px solid #e7d8cf; border-radius: 12px; padding: 7px 0; }
.si-time b { display: block; font-size: 16.5px; color: var(--rose-dark); }
.si-time span { font-size: 12px; color: #8a6f66; }
.si-who { flex: 1; min-width: 0; }
.si-who b { font-size: 18.5px; }
.si-svc { display: block; font-size: 15px; color: #5c554f; margin-top: 2px; }
.si-ph { display: block; font-size: 13.5px; color: #8a6f66; margin-top: 1px; }
.si-tag-new { display: inline-block; font-size: 11px; font-weight: 900; letter-spacing: 1px; padding: 3px 8px; border-radius: 999px; vertical-align: 2px; margin-left: 7px; background: #fdf0d5; color: #9a7414; border: 1px solid #ecd9a0; }
.si-st { flex: 0 0 auto; font-size: 14px; font-weight: 700; padding: 7px 13px; border-radius: 999px; }
.si-st-wait { background: #fdf0d5; color: #9a7414; }
.si-st-appt { background: #e2f3e6; color: #22703a; }
.si-st-dismissed { background: #efefef; color: #777; }
.si-chev { flex: 0 0 auto; color: #cbb8ae; font-size: 22px; }
.si-detail { padding: 18px 16px; }
.si-rowline { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 8px 0; font-size: 17px; }
.si-assignrow { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 22px; }
.si-date, .si-timeselect { flex: 1 1 200px; min-height: 64px; font-size: 18px; font-weight: 600; border: 2px solid var(--rose); border-radius: 14px; padding: 0 14px; background: #fff; color: #33302d; font-family: inherit; }
.si-btnrow { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 22px; }
.si-btnrow .btn { min-height: 56px; flex: 1 1 160px; }
.si-wide { display: block; width: 100%; margin-top: 16px; text-align: center; }
