/* 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); }
/* check266 (owner, Oct 31, 2026, 9:12 AM — "Remove the
   wiping funtions. It's buggy and slow."): the check263
   day bar + day pager states and the check264 week bar +
   week pager states that stood here are removed with the
   pagers themselves — no bar styles, no thead hiding, no
   touch-action override. The grid's own thead and
   check262's free sideways scroll rule every view again.
   The one survivor of the week work is check264's
   week-coin sizing, re-homed onto the table's
   server-rendered .week-view class at the coin block
   below. */
/* check268 (owner, Oct 31, 2026, 10:10 AM — "Pin the
   top row, no swipe."): the pinned day/date header,
   gated on body.f263 like the rest of the batch. The
   header the owner sees is a MIRROR (.book-pinhead)
   rendered outside #bookScroll — the scroller's
   overflow-x makes it a scroll box, so a sticky thead
   inside it could never pin against the page. The
   mirror instead wraps with the scroller in
   .book-pinwrap (its bottom edge is the pin's travel
   limit) and is position:sticky at top:0, so on page
   scroll it rides to the top of the screen while the
   grid scrolls under it. Sideways, its day strip
   (.book-pin-strip) is translated by the scroller's
   own scrollLeft (the pin script in Book.cshtml — a
   passive scroll listener, no gesture code), so every
   day label stays over its own column; the Time
   corner never translates, and the grid's own Time
   column keeps its sticky-left pin beneath it — the
   corner is fixed both ways. The table's own thead
   stays in the table (the sizing script reads the
   column widths from it) but collapses to zero
   height: font-size/line-height 0, so nothing of it
   paints and the mirror is the only header visible.
   Gate off, no mirror renders and none of these
   rules apply: the Book is check266's, exactly. */
body.f263 .book-pinwrap { margin-top:16px; }
body.f263 #bookScroll { margin-top:0 !important; }
body.f263 .book-grid { border-top:0; }
body.f263 .book-pinhead { position:sticky; top:0; z-index:8; display:flex; background:#fff; border-top:1px solid #e3d2cc; border-left:1px solid #e3d2cc; }
body.f263 .book-pin-corner { flex:0 0 64px; width:64px; text-align:right; font-weight:600; font-size:.92rem; background:#faf1ee; border-right:1px solid #e3d2cc; border-bottom:1px solid #e3d2cc; padding:8px 10px; position:relative; z-index:2; box-shadow:4px 0 6px -3px rgba(61,51,48,.35); }
body.f263 .book-pin-clip { flex:1 1 auto; overflow:hidden; }
body.f263 .book-pin-strip { display:flex; will-change:transform; }
body.f263 .book-pin-day { flex:0 0 auto; background:#faf1ee; text-align:left; font-size:.92rem; border-right:1px solid #e3d2cc; border-bottom:1px solid #e3d2cc; padding:8px 10px; }
body.f263 .book-pin-day.day-past { background:#f3f1f0; }
body.f263 .book-grid thead th { height:0; padding-top:0; padding-bottom:0; font-size:0; line-height:0; border-bottom:0; }
body.f263 .book-grid thead th .book-date { font-size:0; line-height:0; }
body.theme-halloween .book-pin-corner, body.theme-halloween .book-pin-day, body.theme-halloween .book-pin-day.day-past { background:var(--hw-panel2); color:var(--hw-gold-bright); }
.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); }

/* check254 (page-jump audit, Oct 29, 2026): an appointment card
   always wins the tap over a plus. The audit caught a lane plus
   painting over a narrow card and stealing its centre click on
   desktop (the tap opened a new-booking form instead of the
   appointment). check251 already keeps pluses out of occupied
   lanes; what remains is geometry — a plus in the empty
   remainder of a NEIGHBOURING lane can still overlap a card.
   Two moves: cards paint above pluses wherever the two overlap
   (the card's face is what the owner sees there, so the card is
   what the tap means), and the lane plus's own box shrinks to
   its glyph from the left — the glyph keeps the exact x
   check125 aligned (its right inset and right padding are
   untouched); only the empty padding on the card side goes. */
.book-grid .appt-card { z-index:3; }
.book-grid .cell-plus-lane { padding-left:2px; }
/* check263 (owner, Oct 30, 2026): a card's OWN plus rides above
   its card. check251 had stopped emitting pluses in occupied
   lanes at all, which left plain appointment cells (Carol
   Little's 11:00–12:00) with no quick-add; the plus grid is
   whole again (see _BookCell), and the pluses a card's lane
   earns on the rows the card itself covers carry
   .cell-plus-card and paint above the card (z-index 3) at its
   right edge — that corner's tap is the Add target, exactly as
   in check163. Every other plus keeps z-index 2, so check254's
   rule stands untouched: a NEIGHBOUR lane's plus still loses
   the tap to the card it overlaps. */
/* check263g: scoped to body.f263 with the rest of the
   gate — .cell-plus-card is only ever emitted gated-on. */
body.f263 .book-grid .cell-plus-card { z-index:4; }
/* check263 refinement (suite check254 B): on the DESKTOP
   grid a day column is shared by seven days, so a pileup
   lane card can be ~44px wide — there the on-card plus's
   padded tap box reached the card's centre and won its
   centre point (check254's rule: a card's centre tap opens
   the appointment). From 641px up the on-card plus's box
   hugs its glyph (horizontal padding 0), so even the
   narrowest lane card's centre stays the card's — with
   real clearance, not a sub-pixel margin: the glyph
   also steps down to 22px there (a mouse clicks it
   fine). On phones a day column is one screen wide,
   lanes run 100px+, the centre is never in reach, and
   the plus keeps its full finger-sized box and 27px
   glyph. */
@media (min-width: 641px) {
    body.f263 .book-grid .cell-plus-card { padding-left:0; padding-right:0; font-size:22px; }
}

/* 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, .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; }
/* check263 (owner, Oct 30, 2026): "Make those N and P or W or
   any of those small icons bigger, maybe double size." The
   service letter coins double — 21px -> 42px diameter, the
   letter 12px -> 24px with them (the white ring scales to
   2px). Colours, the two-worker split (check108/113) and the
   strip's bottom placement are unchanged; the strip's own
   height grows below to fit, and check131's grow-don't-clip
   floor (min-height: max-content on the card) takes the extra
   room out of the card's own growth, never out of the coins.
   Scoped to .book-grid exactly as before — the visit log's
   smaller .vlog-line coins are a different surface and stay.
   check263g: the doubling is GATED — the base rules keep
   check262's sizes (21px / 12px / 11px glyph, restored
   above and at the strip below) and the doubled values
   live in the body.f263 overrides: the layout emits that
   class only when the check263 gate is on for the request
   (a DEV session, or PROD with Features:Check263 "on"). */
body.f263 .book-grid .svc-coins { gap:6px; }
.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; }
body.f263 .book-grid .coin { width:42px; height:42px; font-size:24px; border-width:2px; }
/* check264 (owner, Oct 31, 2026, 12:46 AM — "Wrong size
   too", of the week view): the doubling above is the DAY
   view's, where a column is a screen wide (~326px) and a
   42px coin fits its card. A week-view column is ~150px:
   there the same 42px coin forces its strip to 48px and
   a one-row card (name + note + strip) outgrows its 81px
   slot by ~18px, so the card — coin riding its bottom —
   lands on the cell below (his screenshot: Sue King's N
   sitting on the word "Blocked"). The week view keeps
   its own size: 24px (letter 14px), the largest coin at
   which the canonical week card fits its own slot — the
   strip override beside check108's block gives it a
   30px strip to sit in. check266: the size survives the
   pagers' removal — scoped to the week state itself,
   the table's .week-view class, which the Book renders
   server-side for any window with no today in it,
   inside the phone media query that scoped the removed
   week pager, so the day view's 42px — and every other
   surface — is untouched. */
@media (max-width: 640px) {
    body.f263 table.book-grid.week-view .coin { width:24px; height:24px; font-size:14px; border-width:1.5px; }
    body.f263 table.book-grid.week-view .coin-note svg { width:13px; height:13px; }
}
.book-grid .coin-N { background:#22c55e; }
.book-grid .coin-note { background:#e9a13b; }
.book-grid .coin-note svg { width:11px; height:11px; display:block; }
body.f263 .book-grid .coin-note svg { width:22px; height:22px; }
.book-grid .coin-P { background:#e75480; }
.book-grid .coin-W, .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, .cr-hist .coin-G { background:#22c55e; }
.cr-hist .coin-M, .cr-hist .coin-P { background:#e75480; }
.cr-hist .coin-W, .cr-hist .coin-F { background:#7c3aed; }
.qe-pick-btn .p-note, .qe-pick-btn .cr-line, .qe-pick-btn .cr-hist, .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, .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, .book-svc .coin-G { background:#22c55e; }
.book-svc .coin-M, .book-svc .coin-P { background:#e75480; }
.book-svc .coin-W, .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, .svc-btn .coin-G { background:#22c55e; }
.svc-btn .coin-M, .svc-btn .coin-P { background:#e75480; }
.svc-btn .coin-W, .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; outline:1px solid #e3d2cc; }
.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); }
/* check294 (owner, Nov 2, 2026): the walk-in HOLD card — VIOLET
   (the owner's picked sample, mockups/walkin-color option B:
   #7c3aed family, white text) with the pale WALK-IN pill in
   the name line, in the tag family's shape. The grey check and
   the personal-note line lighten like the discount card's do;
   the service coins keep their colors. Placed BEFORE the
   day-past rule below on purpose: a past day's walk-in card
   greys with every other past card. */
.book-grid .appt-card.card-walkin294 { background:#7c3aed; color:#fff; }
.book-grid .appt-card.card-walkin294 .act-chk-grey { color:#ddd6fe; }
.book-grid .appt-card.card-walkin294 .p-note { color:#ede9fe; }
.wi294-tag { display:inline-block; background:#ede9fe; color:#5b21b6; font-size:10.5px; font-weight:800; letter-spacing:.6px; padding:2.5px 7px; border-radius:20px; vertical-align:middle; margin-left:7px; }
.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. */
/* check263: min-height 27px -> 48px and the half gap 3px ->
   6px, so the strip fits the doubled 42px coins (see the
   .book-grid .coin note above). check263g: gated with the
   coins — the base rules keep check262's 27px / 3px and the
   grown values apply only under body.f263. */
.book-grid .appt-card .svc-strip { display:flex; position:relative; box-sizing:border-box; margin:6px -9px -7px; min-height:27px; }
body.f263 .book-grid .appt-card .svc-strip { min-height:48px; }
/* check264: in the week view the strip carries the
   week view's own 24px coins (see the .book-grid .coin
   block) — 30px fits them with the halves' own padding,
   so a one-row week card's stack (name + note + strip)
   fits its slot instead of growing over the cell below.
   check266: keyed off the table's server-rendered
   .week-view class in the phone media query, as at the
   coin block — the week pager that used to set the
   state is removed. */
@media (max-width: 640px) {
    body.f263 table.book-grid.week-view .appt-card .svc-strip { min-height:30px; }
}
.book-grid .appt-card .svc-half { flex:1 1 0; min-width:0; display:flex; align-items:center; gap:3px; padding:3px 6px; }
body.f263 .book-grid .appt-card .svc-half { gap: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; }

/* ---------- check251 (owner, Oct 29, 2026) ---------- */
/* The start/end lines, as the CARD's own edge treatment.
   check248 painted them as cell-level overlay spans across the
   cell's FULL width, so in a multi-lane cell Lisa Cane's 2:15
   line sliced through Layla's card beside her — the owner:
   "Line for Lisa Cane must not cut Layla's cell. That line must
   stay with Lisa only", then his simplification: "If it's a
   component, you can just draw a line under and a line above
   the card, right?" So the line moved inside the card
   component: a card whose start falls between the grid's :30
   boundaries wears the line as its FIRST pixel row, a card
   whose end falls between them as its LAST pixel row (the
   .card-edge spans _BookCell emits inside the card anchor).
   Inside the card, left:0/right:0 IS the card's own width by
   construction — the line can never cross into a neighbor's
   lane, and a lone card's line spans the full cell exactly as
   before. The line is still the grid's OWN line: the same
   1px solid #e3d2cc the cell borders and the check111 tile
   use. No color, weight or effect of its own, and never a
   tap target. The old .cell-edge-line overlay rule is gone. */
/* check261 (owner, Oct 30, 2026 — "I asked you to fix this a
   few days ago"): the card now carries its OWN frame — the
   outline on the base .appt-card rule above (the grid's own
   1px #e3d2cc). The outline paints just outside the card's
   box, so a card that exactly fills its slot keeps the exact
   single line it always had (the outline lands on the cell
   border it replaces), while a card whose box leaves the
   slot — check131's content-grown short cards, lane cards
   inside a shared cell — is framed wherever it actually
   paints. That makes check251's in-card edge spans redundant:
   the outline draws every edge, on-grid or off, at exactly
   the card's width. The spans stay in the markup (the shared
   partial is untouched) and are simply not painted. */
.book-grid .appt-card .card-edge { display:none; }
.book-grid .appt-card .card-edge-t { top:0; }
.book-grid .appt-card .card-edge-b { bottom:0; }

/* ---------- 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, body.pub.theme-halloween .header-pills .header-call, body.pub.theme-thanksgiving1 .header-pills .header-call, body.pub.theme-thanksgiving2 .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, body.pub.theme-halloween .header-pills .header-call:hover, body.pub.theme-thanksgiving1 .header-pills .header-call:hover, body.pub.theme-thanksgiving2 .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, body.pub.theme-halloween .header-pills .header-call:visited, body.pub.theme-halloween .header-pills .header-call:active, body.pub.theme-halloween .header-pills .header-call:focus, body.pub.theme-thanksgiving1 .header-pills .header-call:visited, body.pub.theme-thanksgiving1 .header-pills .header-call:active, body.pub.theme-thanksgiving1 .header-pills .header-call:focus, body.pub.theme-thanksgiving2 .header-pills .header-call:visited, body.pub.theme-thanksgiving2 .header-pills .header-call:active, body.pub.theme-thanksgiving2 .header-pills .header-call:focus
{ background:#fff; color:var(--charcoal); }
body.pub.thed .btn-book, body.pub.theme-halloween .btn-book, body.pub.theme-thanksgiving1 .btn-book, body.pub.theme-thanksgiving2 .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, body.pub.theme-halloween .btn-book:hover, body.pub.theme-thanksgiving1 .btn-book:hover, body.pub.theme-thanksgiving2 .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, body.pub.theme-halloween .header-pills .btn-book:visited, body.pub.theme-halloween .header-pills .btn-book:active, body.pub.theme-halloween .header-pills .btn-book:focus, body.pub.theme-thanksgiving1 .header-pills .btn-book:visited, body.pub.theme-thanksgiving1 .header-pills .btn-book:active, body.pub.theme-thanksgiving1 .header-pills .btn-book:focus, body.pub.theme-thanksgiving2 .header-pills .btn-book:visited, body.pub.theme-thanksgiving2 .header-pills .btn-book:active, body.pub.theme-thanksgiving2 .header-pills .btn-book:focus, 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, 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, body.pub.theme-halloween, body.pub.theme-thanksgiving1, body.pub.theme-thanksgiving2
{
    --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, body.pub.theme-halloween, body.pub.theme-thanksgiving1, body.pub.theme-thanksgiving2
{
    --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, body.pub.theme-halloween, body.pub.theme-thanksgiving1, body.pub.theme-thanksgiving2
{ --hero-img:url("/images/hero-dustyrose.webp"); }

/* ----- The editorial treatment, driven by the variables ----- */
body.pub.thed, body.pub.theme-halloween, body.pub.theme-thanksgiving1, body.pub.theme-thanksgiving2
{ background-color:var(--paper); color:var(--ink-th); }
body.pub.thed a, body.pub.theme-halloween a, body.pub.theme-thanksgiving1 a, body.pub.theme-thanksgiving2 a
{ color:var(--acc-text); }
body.pub.thed .kicker, body.pub.theme-halloween .kicker, body.pub.theme-thanksgiving1 .kicker, body.pub.theme-thanksgiving2 .kicker
{ color:var(--acc-text); letter-spacing:.26em; }
body.pub.thed .lead, body.pub.theme-halloween .lead, body.pub.theme-thanksgiving1 .lead, body.pub.theme-thanksgiving2 .lead
{ color:var(--muted-th); }
body.pub.thed .section.alt, body.pub.theme-halloween .section.alt, body.pub.theme-thanksgiving1 .section.alt, body.pub.theme-thanksgiving2 .section.alt
{ background:var(--alt); }
body.pub.thed button.link-btn, body.pub.theme-halloween button.link-btn, body.pub.theme-thanksgiving1 button.link-btn, body.pub.theme-thanksgiving2 button.link-btn
{ color:var(--acc-text); }
body.pub.thed .btn-call, body.pub.theme-halloween .btn-call, body.pub.theme-thanksgiving1 .btn-call, body.pub.theme-thanksgiving2 .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, body.pub.theme-halloween .btn-call:hover, body.pub.theme-thanksgiving1 .btn-call:hover, body.pub.theme-thanksgiving2 .btn-call:hover
{ background:linear-gradient(160deg,var(--acc),var(--acc-text)); color:var(--btn-ink); }
body.pub.thed .btn-outline, body.pub.theme-halloween .btn-outline, body.pub.theme-thanksgiving1 .btn-outline, body.pub.theme-thanksgiving2 .btn-outline
{ background:var(--outline-bg); color:var(--ink-th); border:1.5px solid var(--acc-soft); }
body.pub.thed .btn-outline:hover, body.pub.theme-halloween .btn-outline:hover, body.pub.theme-thanksgiving1 .btn-outline:hover, body.pub.theme-thanksgiving2 .btn-outline:hover
{ background:var(--acc-tint); }
body.pub.thed .site-header, body.pub.theme-halloween .site-header, body.pub.theme-thanksgiving1 .site-header, body.pub.theme-thanksgiving2 .site-header
{ background:var(--header-bg); border-bottom:1px solid var(--line); }
body.pub.thed .site-header::after, body.pub.theme-halloween .site-header::after, body.pub.theme-thanksgiving1 .site-header::after, body.pub.theme-thanksgiving2 .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, body.pub.theme-halloween .site-nav, body.pub.theme-thanksgiving1 .site-nav, body.pub.theme-thanksgiving2 .site-nav
{ background:var(--surface); border-bottom-color:var(--line); }
body.pub.thed .site-nav a, body.pub.theme-halloween .site-nav a, body.pub.theme-thanksgiving1 .site-nav a, body.pub.theme-thanksgiving2 .site-nav a
{ color:var(--muted-th); border-top-color:var(--hair); }
body.pub.thed .site-nav a.active, body.pub.theme-halloween .site-nav a.active, body.pub.theme-thanksgiving1 .site-nav a.active, body.pub.theme-thanksgiving2 .site-nav a.active
{ color:var(--ink-th); }
body.pub.thed .nav-toggle span, body.pub.theme-halloween .nav-toggle span, body.pub.theme-thanksgiving1 .nav-toggle span, body.pub.theme-thanksgiving2 .nav-toggle span
{ background:var(--ink-th); }
body.pub.thed .hero, body.pub.theme-halloween .hero, body.pub.theme-thanksgiving1 .hero, body.pub.theme-thanksgiving2 .hero
{ background:var(--paper); color:var(--hero-ink); text-align:left; }
body.pub.thed .hero-bg, body.pub.theme-halloween .hero-bg, body.pub.theme-thanksgiving1 .hero-bg, body.pub.theme-thanksgiving2 .hero-bg
{ background-image:var(--hero-img); opacity:1; }
body.pub.thed .hero::after, body.pub.theme-halloween .hero::after, body.pub.theme-thanksgiving1 .hero::after, body.pub.theme-thanksgiving2 .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, body.pub.theme-halloween .hero h1, body.pub.theme-thanksgiving1 .hero h1, body.pub.theme-thanksgiving2 .hero h1
{ text-shadow:none; color:var(--hero-ink); }
body.pub.thed .hero .tagline, body.pub.theme-halloween .hero .tagline, body.pub.theme-thanksgiving1 .hero .tagline, body.pub.theme-thanksgiving2 .hero .tagline
{ color:var(--hero-sub); }
body.pub.thed .hero .rating, body.pub.theme-halloween .hero .rating, body.pub.theme-thanksgiving1 .hero .rating, body.pub.theme-thanksgiving2 .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, body.pub.theme-halloween .hero .rating .star, body.pub.theme-thanksgiving1 .hero .rating .star, body.pub.theme-thanksgiving2 .hero .rating .star
{ color:var(--acc); }
body.theme-marble.thed .hero .rating .star { color:var(--rose); }
body.pub.thed .hero-cta, body.pub.theme-halloween .hero-cta, body.pub.theme-thanksgiving1 .hero-cta, body.pub.theme-thanksgiving2 .hero-cta
{ margin:30px 0 0; align-items:stretch; justify-content:flex-start; max-width:none; }
body.pub.thed .hero-cta .btn-outline, body.pub.theme-halloween .hero-cta .btn-outline, body.pub.theme-thanksgiving1 .hero-cta .btn-outline, body.pub.theme-thanksgiving2 .hero-cta .btn-outline
{ border-color:var(--acc-soft); color:var(--hero-ink); background:var(--outline-bg); }
body.pub.thed .hero-kicker, body.pub.theme-halloween .hero-kicker, body.pub.theme-thanksgiving1 .hero-kicker, body.pub.theme-thanksgiving2 .hero-kicker
{ display:block; }
body.pub.thed .hero-rule, body.pub.theme-halloween .hero-rule, body.pub.theme-thanksgiving1 .hero-rule, body.pub.theme-thanksgiving2 .hero-rule
{ display:block; width:64px; height:2px; background:var(--acc); margin:18px 0 2px; }
body.pub.thed .feat-card, body.pub.theme-halloween .feat-card, body.pub.theme-thanksgiving1 .feat-card, body.pub.theme-thanksgiving2 .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, body.pub.theme-halloween .feat-body p, body.pub.theme-thanksgiving1 .feat-body p, body.pub.theme-thanksgiving2 .feat-body p
{ color:var(--muted-th); }
body.pub.thed .feat-body .from, body.pub.theme-halloween .feat-body .from, body.pub.theme-thanksgiving1 .feat-body .from, body.pub.theme-thanksgiving2 .feat-body .from
{ color:var(--acc-text); }
body.theme-marble.thed .feat-body .from { color:var(--rose-dark); }
body.pub.thed .home-mi, body.pub.theme-halloween .home-mi, body.pub.theme-thanksgiving1 .home-mi, body.pub.theme-thanksgiving2 .home-mi
{ border-bottom-color:var(--hair); }
body.pub.thed .home-mi .dots, body.pub.theme-halloween .home-mi .dots, body.pub.theme-thanksgiving1 .home-mi .dots, body.pub.theme-thanksgiving2 .home-mi .dots
{ border-bottom-color:var(--dots); }
body.pub.thed .home-mi .p, body.pub.theme-halloween .home-mi .p, body.pub.theme-thanksgiving1 .home-mi .p, body.pub.theme-thanksgiving2 .home-mi .p
{ color:var(--acc-text); }
body.pub.thed .ornament::before, body.pub.thed .ornament::after, body.pub.theme-halloween .ornament::before, body.pub.theme-halloween .ornament::after, body.pub.theme-thanksgiving1 .ornament::before, body.pub.theme-thanksgiving1 .ornament::after, body.pub.theme-thanksgiving2 .ornament::before, body.pub.theme-thanksgiving2 .ornament::after
{ background:var(--line); }
body.pub.thed .ornament i, body.pub.theme-halloween .ornament i, body.pub.theme-thanksgiving1 .ornament i, body.pub.theme-thanksgiving2 .ornament i
{ background:var(--acc); }
body.pub.thed .salon-img, body.pub.theme-halloween .salon-img, body.pub.theme-thanksgiving1 .salon-img, body.pub.theme-thanksgiving2 .salon-img
{ border:1px solid var(--line); }
body.pub.thed .salon-cap p, body.pub.theme-halloween .salon-cap p, body.pub.theme-thanksgiving1 .salon-cap p, body.pub.theme-thanksgiving2 .salon-cap p
{ color:var(--muted-th); }
body.pub.thed .award, body.pub.theme-halloween .award, body.pub.theme-thanksgiving1 .award, body.pub.theme-thanksgiving2 .award
{ background:var(--panel); border-top:3px solid var(--acc); }
body.pub.thed .award h2, body.pub.theme-halloween .award h2, body.pub.theme-thanksgiving1 .award h2, body.pub.theme-thanksgiving2 .award h2
{ color:#fff; }
body.pub.thed .award .kicker, body.pub.theme-halloween .award .kicker, body.pub.theme-thanksgiving1 .award .kicker, body.pub.theme-thanksgiving2 .award .kicker
{ color:var(--acc-soft); }
body.pub.thed .award .lead, body.pub.theme-halloween .award .lead, body.pub.theme-thanksgiving1 .award .lead, body.pub.theme-thanksgiving2 .award .lead
{ color:#d8cfc4; }
body.pub.thed .hours-list li, body.pub.theme-halloween .hours-list li, body.pub.theme-thanksgiving1 .hours-list li, body.pub.theme-thanksgiving2 .hours-list li
{ border-bottom-color:var(--hair); }
body.pub.thed .hours-list li::after, body.pub.theme-halloween .hours-list li::after, body.pub.theme-thanksgiving1 .hours-list li::after, body.pub.theme-thanksgiving2 .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, body.pub.theme-halloween .hours-list li span:last-child, body.pub.theme-thanksgiving1 .hours-list li span:last-child, body.pub.theme-thanksgiving2 .hours-list li span:last-child
{ order:2; }
body.pub.thed .form-card, body.pub.theme-halloween .form-card, body.pub.theme-thanksgiving1 .form-card, body.pub.theme-thanksgiving2 .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, body.pub.theme-halloween .field input, body.pub.theme-halloween .field textarea, body.pub.theme-halloween .field select, body.pub.theme-thanksgiving1 .field input, body.pub.theme-thanksgiving1 .field textarea, body.pub.theme-thanksgiving1 .field select, body.pub.theme-thanksgiving2 .field input, body.pub.theme-thanksgiving2 .field textarea, body.pub.theme-thanksgiving2 .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, body.pub.theme-halloween .field input:focus, body.pub.theme-halloween .field textarea:focus, body.pub.theme-halloween .field select:focus, body.pub.theme-thanksgiving1 .field input:focus, body.pub.theme-thanksgiving1 .field textarea:focus, body.pub.theme-thanksgiving1 .field select:focus, body.pub.theme-thanksgiving2 .field input:focus, body.pub.theme-thanksgiving2 .field textarea:focus, body.pub.theme-thanksgiving2 .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, body.pub.theme-halloween .date-display, body.pub.theme-thanksgiving1 .date-display, body.pub.theme-thanksgiving2 .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, body.pub.theme-halloween .date-display:hover, body.pub.theme-thanksgiving1 .date-display:hover, body.pub.theme-thanksgiving2 .date-display:hover
{ background:linear-gradient(160deg,var(--acc),var(--acc-text)); color:var(--btn-ink); }
body.pub.thed .date-display:focus, body.pub.theme-halloween .date-display:focus, body.pub.theme-thanksgiving1 .date-display:focus, body.pub.theme-thanksgiving2 .date-display:focus
{ box-shadow:0 0 0 3px var(--acc-tint); }
body.pub.thed .step-n, body.pub.theme-halloween .step-n, body.pub.theme-thanksgiving1 .step-n, body.pub.theme-thanksgiving2 .step-n
{ background:linear-gradient(160deg,var(--acc-hi),var(--acc)); color:var(--btn-ink); }
body.pub.thed .slot, body.pub.theme-halloween .slot, body.pub.theme-thanksgiving1 .slot, body.pub.theme-thanksgiving2 .slot
{ background:var(--surface); border-color:var(--line); color:var(--ink-th); }
body.pub.thed .slot:has(input:focus-visible), body.pub.theme-halloween .slot:has(input:focus-visible), body.pub.theme-thanksgiving1 .slot:has(input:focus-visible), body.pub.theme-thanksgiving2 .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), body.pub.theme-halloween .slot:has(input:checked), body.pub.theme-thanksgiving1 .slot:has(input:checked), body.pub.theme-thanksgiving2 .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, body.pub.theme-halloween .book-svc .slot, body.pub.theme-halloween .time-grid .slot, body.pub.theme-thanksgiving1 .book-svc .slot, body.pub.theme-thanksgiving1 .time-grid .slot, body.pub.theme-thanksgiving2 .book-svc .slot, body.pub.theme-thanksgiving2 .time-grid .slot
{ border-color:var(--acc-soft); color:var(--acc-text); }
body.pub.thed .time-grid .slot.full, body.pub.thed .slot.full, body.pub.theme-halloween .time-grid .slot.full, body.pub.theme-halloween .slot.full, body.pub.theme-thanksgiving1 .time-grid .slot.full, body.pub.theme-thanksgiving1 .slot.full, body.pub.theme-thanksgiving2 .time-grid .slot.full, body.pub.theme-thanksgiving2 .slot.full
{ background:var(--alt); color:var(--muted-th); }
body.pub.thed .notice, body.pub.theme-halloween .notice, body.pub.theme-thanksgiving1 .notice, body.pub.theme-thanksgiving2 .notice
{ background:var(--acc-tint); border-color:var(--acc); color:var(--ink-th); }
body.pub.thed .cal-pop, body.pub.theme-halloween .cal-pop, body.pub.theme-thanksgiving1 .cal-pop, body.pub.theme-thanksgiving2 .cal-pop
{ background:var(--surface); border-color:var(--line); color:var(--ink-th); }
body.pub.thed .cal-nav, body.pub.theme-halloween .cal-nav, body.pub.theme-thanksgiving1 .cal-nav, body.pub.theme-thanksgiving2 .cal-nav
{ border-color:var(--line); background:var(--surface); color:var(--acc-text); }
body.pub.thed .cal-day:hover:not(:disabled), body.pub.theme-halloween .cal-day:hover:not(:disabled), body.pub.theme-thanksgiving1 .cal-day:hover:not(:disabled), body.pub.theme-thanksgiving2 .cal-day:hover:not(:disabled)
{ background:var(--acc-tint); }
body.pub.thed .cal-week span, body.pub.theme-halloween .cal-week span, body.pub.theme-thanksgiving1 .cal-week span, body.pub.theme-thanksgiving2 .cal-week span
{ color:var(--muted-th); }
body.pub.thed .contact-block, body.pub.theme-halloween .contact-block, body.pub.theme-thanksgiving1 .contact-block, body.pub.theme-thanksgiving2 .contact-block
{ background:var(--alt); border:1px solid var(--line); }
body.pub.thed .dep-summary, body.pub.theme-halloween .dep-summary, body.pub.theme-thanksgiving1 .dep-summary, body.pub.theme-thanksgiving2 .dep-summary
{ background:var(--alt); border-color:var(--line); }
body.pub.thed .menu-list, body.pub.thed .menu-items, body.pub.theme-halloween .menu-list, body.pub.theme-halloween .menu-items, body.pub.theme-thanksgiving1 .menu-list, body.pub.theme-thanksgiving1 .menu-items, body.pub.theme-thanksgiving2 .menu-list, body.pub.theme-thanksgiving2 .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, body.pub.theme-halloween .menu-list li, body.pub.theme-halloween .menu-item, body.pub.theme-thanksgiving1 .menu-list li, body.pub.theme-thanksgiving1 .menu-item, body.pub.theme-thanksgiving2 .menu-list li, body.pub.theme-thanksgiving2 .menu-item
{ border-bottom-color:var(--hair); }
body.pub.thed .menu-row .name, body.pub.theme-halloween .menu-row .name, body.pub.theme-thanksgiving1 .menu-row .name, body.pub.theme-thanksgiving2 .menu-row .name
{ color:var(--ink-th); }
body.pub.thed .menu-row .dots, body.pub.theme-halloween .menu-row .dots, body.pub.theme-thanksgiving1 .menu-row .dots, body.pub.theme-thanksgiving2 .menu-row .dots
{ border-bottom-color:var(--dots); }
body.pub.thed .menu-row .price, body.pub.theme-halloween .menu-row .price, body.pub.theme-thanksgiving1 .menu-row .price, body.pub.theme-thanksgiving2 .menu-row .price
{ color:var(--acc-text); }
body.pub.thed .menu-item .desc, body.pub.thed .menu-blurb, body.pub.theme-halloween .menu-item .desc, body.pub.theme-halloween .menu-blurb, body.pub.theme-thanksgiving1 .menu-item .desc, body.pub.theme-thanksgiving1 .menu-blurb, body.pub.theme-thanksgiving2 .menu-item .desc, body.pub.theme-thanksgiving2 .menu-blurb
{ color:var(--muted-th); }
body.pub.thed .starts-at span, body.pub.theme-halloween .starts-at span, body.pub.theme-thanksgiving1 .starts-at span, body.pub.theme-thanksgiving2 .starts-at span
{ background:var(--acc-tint); color:var(--acc-text); border-color:var(--line); }
body.pub.thed .menu-note, body.pub.theme-halloween .menu-note, body.pub.theme-thanksgiving1 .menu-note, body.pub.theme-thanksgiving2 .menu-note
{ background:var(--acc-tint); color:var(--ink-th); }
body.pub.thed .menu-group > h2::after, body.pub.theme-halloween .menu-group > h2::after, body.pub.theme-thanksgiving1 .menu-group > h2::after, body.pub.theme-thanksgiving2 .menu-group > h2::after
{ background:var(--line); }
body.pub.thed .svc-card, body.pub.theme-halloween .svc-card, body.pub.theme-thanksgiving1 .svc-card, body.pub.theme-thanksgiving2 .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, body.pub.theme-halloween .svc-body p, body.pub.theme-thanksgiving1 .svc-body p, body.pub.theme-thanksgiving2 .svc-body p, body.pub.thed .video-card p, body.pub.theme-halloween .video-card p, body.pub.theme-thanksgiving1 .video-card p, body.pub.theme-thanksgiving2 .video-card p { color:var(--muted-th); }
body.pub.thed .map-frame, body.pub.theme-halloween .map-frame, body.pub.theme-thanksgiving1 .map-frame, body.pub.theme-thanksgiving2 .map-frame
{ border:1px solid var(--line); }
body.pub.thed .site-footer, body.pub.theme-halloween .site-footer, body.pub.theme-thanksgiving1 .site-footer, body.pub.theme-thanksgiving2 .site-footer
{ background:var(--footer-bg); border-top:3px solid var(--acc); }
body.pub.thed .site-footer a, body.pub.theme-halloween .site-footer a, body.pub.theme-thanksgiving1 .site-footer a, body.pub.theme-thanksgiving2 .site-footer a
{ color:var(--acc-soft); }
body.pub.thed .site-footer .tagline, body.pub.theme-halloween .site-footer .tagline, body.pub.theme-thanksgiving1 .site-footer .tagline, body.pub.theme-thanksgiving2 .site-footer .tagline
{ color:#b6ad99; }
body.pub.thed .site-footer .rating, body.pub.theme-halloween .site-footer .rating, body.pub.theme-thanksgiving1 .site-footer .rating, body.pub.theme-thanksgiving2 .site-footer .rating
{ border-color:var(--line); color:#fff; }
body.pub.thed .site-footer .rating .star, body.pub.theme-halloween .site-footer .rating .star, body.pub.theme-thanksgiving1 .site-footer .rating .star, body.pub.theme-thanksgiving2 .site-footer .rating .star
{ color:var(--acc); }
body.pub.thed .footer-bottom, body.pub.theme-halloween .footer-bottom, body.pub.theme-thanksgiving1 .footer-bottom, body.pub.theme-thanksgiving2 .footer-bottom
{ border-top-color:var(--hair); color:#a89e88; }
@media (max-width: 767px) {
    body.pub.thed .hero::after, body.pub.theme-halloween .hero::after, body.pub.theme-thanksgiving1 .hero::after, body.pub.theme-thanksgiving2 .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, body.pub.theme-halloween .hero-cta, body.pub.theme-thanksgiving1 .hero-cta, body.pub.theme-thanksgiving2 .hero-cta
{ flex-direction:row; justify-content:flex-start; }
    body.pub.thed .site-nav a.active, body.pub.theme-halloween .site-nav a.active, body.pub.theme-thanksgiving1 .site-nav a.active, body.pub.theme-thanksgiving2 .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, .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, .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; }
}

/* check263 item 6 (owner, Oct 30, 2026, 10:45 PM —
   "Welcome inside photo like service page"): the word
   Welcome INSIDE the home hero photo, wearing the
   _PageTop title's treatment exactly — Great Vibes,
   white, the rose-wine shade and soft shadow that let
   the script read over photo art (see .page-top /
   .page-top-title above). It sits bottom-left inside
   the hero, clear of the medallion in both themes: the
   Halloween hero band (hero.jpg on wide screens, the
   medallion cluster on phones) and the Classic emblem
   band (header-emblem.webp). The header renders the
   span on the home page only, inside the hero's own
   home anchor, so check262's tap-to-home is untouched
   and the word itself never takes a tap. The shade
   rides as the word's own soft backdrop patch, so it
   can never wash over the medallion. Sizing mirrors
   .page-top-title (2.6rem, 3rem from 768px), trimmed
   to 2rem on phones, where the Classic band runs only
   ~90px tall. On desktop the Classic emblem is
   height-capped (check259 item 9: 150px tall, 647px
   wide, centred), so the word's left offset follows
   the artwork's own left edge there (the media rule
   below). */
/* check263g: every rule in this item-6 block is scoped to
   body.f263 — the layout's gate class — so with the gate
   off the hero anchors keep check262's exact positioning
   (the span itself is only rendered gated-on anyway). */
body.f263 .hw-hero a, body.f263 .brand-art { position:relative; }
body.f263 .hero-welcome { position:absolute; left:20px; bottom:12px; z-index:2; font-family:"Great Vibes", cursive; font-weight:400; font-size:2.6rem; line-height:1.15; color:#fff; text-shadow:0 2px 10px rgba(86,48,54,.45); padding:.05em .3em; background:radial-gradient(ellipse at center, rgba(86,48,54,.42), rgba(86,48,54,0) 72%); pointer-events:none; }
@media (min-width: 768px) {
    body.f263 .hero-welcome { font-size:3rem; }
}
@media (min-width: 1024px) {
    /* The desktop emblem is height-capped at 150px
       (check259 item 9), so the artwork renders 647px
       wide, centred — the word's left follows its edge:
       half the viewport minus half the artwork (324px)
       plus the same 20px inset. */
    body.f263 .brand-art .hero-welcome { left:calc(50% - 304px); }
}
@media (max-width: 640px) {
    body.f263 .hero-welcome { font-size:2rem; left:12px; bottom:8px; }
}

/* 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, body.pub.theme-halloween .site-header, body.pub.theme-thanksgiving1 .site-header, body.pub.theme-thanksgiving2 .site-header
{ background:#fff; border-bottom:1px solid #f0e2dd; }
body.pub.thed .site-header .site-nav, body.pub.theme-halloween .site-header .site-nav, body.pub.theme-thanksgiving1 .site-header .site-nav, body.pub.theme-thanksgiving2 .site-header .site-nav
{ background:#fff; }
body.pub.thed .site-header .site-nav a, body.pub.theme-halloween .site-header .site-nav a, body.pub.theme-thanksgiving1 .site-header .site-nav a, body.pub.theme-thanksgiving2 .site-header .site-nav a
{ color:var(--charcoal); border-top-color:#f0e2dd; }
body.pub.thed .site-header .site-nav a.active, body.pub.theme-halloween .site-header .site-nav a.active, body.pub.theme-thanksgiving1 .site-header .site-nav a.active, body.pub.theme-thanksgiving2 .site-header .site-nav a.active
{ color:var(--rose-dark); }
body.pub.thed .site-header .nav-toggle span, body.pub.theme-halloween .site-header .nav-toggle span, body.pub.theme-thanksgiving1 .site-header .nav-toggle span, body.pub.theme-thanksgiving2 .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, .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?v=326") 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, .ci-dpill .coin-G { background: #22c55e; }
.ci-dpill .coin-M, .ci-dpill .coin-P { background: #e75480; }
.ci-dpill .coin-W, .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; }

/* ════════════════════════════════════════════════════════════
   check258 (owner, Oct 29, 2026, 10:14 PM — "Port theme into
   DEV mode"): the HALLOWEEN theme, ported from the dev line
   (checks 235-237 + check253's zero-white batch). Everything
   below is scoped to body.theme-halloween (stamped by the
   layout while the per-book SeasonalTheme gate is on) or to
   the hw-* markup the themed pages render only while the
   gate is on — a selector audit of the ported region found
   204 rules, ZERO non-gated selector parts, so the classic
   theme's cascade is untouched. The dev line's global
   step-card layout section is NOT ported: this line's steps
   are the shared _BookingSteps partial's .form-card.step-box
   frame, which the skin below colors through its .form-card
   and .step-n rules. Type set: the layout loads Playfair
   italics + Jost only on themed pages (see _Layout).
   ════════════════════════════════════════════════════════════ */
:root {
    --font-script: "Great Vibes", cursive;
    --font-geo: "Jost", "Inter", -apple-system, "Segoe UI", sans-serif;
    --hw-bg: #140b06;
    --hw-panel: #1d110a;
    --hw-panel2: #241209;
    --hw-gold: #c8a165;
    --hw-gold-bright: #e8c88a;
    --hw-cream: #fdf3e0;
    --hw-ink: #f3e9d2;
    --hw-muted: #c9ae7e;
    --hw-line: #6b4d24;
    --hw-maroon: #571e23;
}


/* ---------- Halloween: page + type ---------- */
html:has(body.theme-halloween) { background: var(--hw-bg); }
body.theme-halloween {
    background: var(--hw-bg);
    color: var(--hw-ink);
    font-family: var(--font-geo);
    color-scheme: dark;
    /* check236: the page-level overflow guard — nothing on
       a themed customer page may push past the viewport and
       hand the phone a horizontal scroll. `clip`, not
       `hidden`: it creates no scroll container, so the
       sticky header keeps sticking. */
    overflow-x: clip;
    --font-body: "Jost", "Inter", -apple-system, "Segoe UI", sans-serif;
    --charcoal: #f3e9d2;
    --muted: #c9ae7e;
    --rose: #c8a165;
    --rose-dark: #e8c88a;
    --rose-deep: #a87f3d;
    --rose-soft: #2a180c;
    --blush: #1d110a;
    --shadow: 0 10px 30px rgba(0, 0, 0, .5);
}
body.theme-halloween h1 { font-family: var(--font-script); font-weight: 400; }
body.theme-halloween h2 { font-family: var(--font-display); font-style: italic; }
body.theme-halloween .btn, body.theme-halloween button, body.theme-halloween input,
body.theme-halloween select, body.theme-halloween textarea, body.theme-halloween label {
    font-family: var(--font-geo);
}
body.theme-halloween a { color: var(--hw-gold-bright); }

/* ---------- Halloween: shared themed header ---------- */
.hw-top { background: var(--hw-bg); }
.hw-hero img { width: 100%; height: auto; display: block; }
/* check236: the asset sheet's medallion-cluster art is the
   COMPACT phone hero (the phone mock's centered cluster);
   the wide scene hero stays for larger screens. The swap
   itself lives in the <=640px header block below. */
.hw-hero .hw-hero-cluster { display: none; }
.hw-actions { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; padding: 16px 20px 18px; }
.hw-btn { display: inline-flex; align-items: center; gap: 9px; border-radius: 999px; padding: 12px 26px; font-family: var(--font-geo); font-weight: 600; letter-spacing: .06em; font-size: 1rem; text-decoration: none; white-space: nowrap; }
.hw-btn-book { background: linear-gradient(180deg, #f59a23, #e05f0c); color: #fff; box-shadow: 0 6px 18px rgba(224, 95, 12, .35); }
.hw-btn-search { background: var(--hw-panel2); border: 1.5px solid var(--hw-gold); color: #f0d9a8; }
.site-header.hw-header { background: var(--hw-bg); border-bottom: 1px solid var(--hw-gold); backdrop-filter: none; }
.hw-inner { justify-content: center; min-height: 52px; }
.hw-header .site-nav a { color: #e6c887; font-family: var(--font-geo); letter-spacing: .08em; font-weight: 500; }
.hw-header .site-nav a.active { color: #ffd98a; font-weight: 700; box-shadow: inset 0 -2px 0 #e8a33d; }
.hw-header .nav-toggle span { background: var(--hw-gold-bright); }
@media (min-width: 768px) {
    .hw-header .site-nav { margin: 0 auto; }
}
@media (max-width: 767px) {
    .hw-header .site-nav { background: var(--hw-panel); border: 1px solid var(--hw-gold); max-width: 100vw; overflow-x: auto; }
    .hw-header .site-nav a { border-top-color: #3a2410; }
    body .hw-header .nav-toggle { position: static; margin-left: auto; }
    .hw-actions { padding: 12px 12px 14px; gap: 10px; }
    .hw-btn { padding: 11px 16px; font-size: .9rem; }
}
/* check236: on phones the two header actions sit SIDE BY
   SIDE under the hero — one row, equal halves (the phone
   mock) — instead of wrapping onto two rows. */
@media (max-width: 640px) {
    .hw-actions { flex-wrap: nowrap; }
    .hw-btn { flex: 1 1 0; justify-content: center; padding: 11px 6px; font-size: .84rem; letter-spacing: .03em; }
    .hw-hero .hw-hero-main { display: none; }
    .hw-hero .hw-hero-cluster { display: block; }
}

/* ---------- Halloween: banners, divider, cards ---------- */
.hw-banner { border: 1px solid var(--hw-gold); border-radius: 18px; overflow: hidden; margin-bottom: 22px; background: var(--hw-panel); }
.hw-banner img { width: 100%; height: auto; display: block; }
/* check236: webs + bats corner accents (asset sheet) on the
   Book and Services banner cards — a mirrored pair in the
   top corners, subtle, clipped by the card's own rounding,
   never interactive. */
.hw-banner { position: relative; }
.hw-banner img.hw-webs { position: absolute; top: 0; width: 104px; height: auto; opacity: .8; pointer-events: none; }
.hw-banner img.hw-webs-l { left: 0; }
.hw-banner img.hw-webs-r { right: 0; transform: scaleX(-1); }
/* check236: the asset-sheet banner art on the Our Salon /
   Gallery / Visit pages (theme on only — the markup itself
   is gated, so this rule is inert otherwise). */
.hw-page-banner { display: block; width: 100%; height: auto; border: 1px solid var(--hw-gold); border-radius: 18px; margin: 4px 0 22px; }
/* check236: the asset sheet's pumpkin cluster — a decorative
   section break on Home between the hero buttons and the
   cards. */
.hw-break { text-align: center; margin: 2px 0 20px; }
.hw-break img { width: min(520px, 92%); height: auto; border: 1px solid var(--hw-gold); border-radius: 18px; display: inline-block; }
/* check236: the asset sheet's garland as a top border strip
   on the customer footer (the footer markup renders it only
   when the theme is on for a customer page). The footer's
   own top padding would gap the strip, so it pulls up. */
.hw-garland { display: block; width: 100%; height: 54px; object-fit: cover; margin: -48px 0 26px; }
.hw-divider { display: flex; flex-direction: column; align-items: center; gap: 10px; margin: 4px 0 20px; }
/* check236: the flourish under the Services medallion is
   the asset sheet's dividers-row.jpg — the plain CSS line
   flourishes it replaces are gone. */
.hw-divider-row { width: min(460px, 88%); height: auto; border-radius: 10px; display: block; }
.hw-medal { width: 64px; height: 64px; border-radius: 50%; flex: none; }
.hw-home { padding-top: 26px; }
.hw-grid { display: grid; grid-template-columns: 1fr; gap: 18px; }
@media (min-width: 768px) {
    .hw-grid { grid-template-columns: 1fr 1fr; gap: 24px; }
}
.hw-card { display: block; background: var(--hw-panel); border: 1px solid var(--hw-gold); border-radius: 18px; overflow: hidden; text-decoration: none; box-shadow: 0 12px 28px rgba(0, 0, 0, .45); }
.hw-photo { display: block; aspect-ratio: 3.4 / 1; overflow: hidden; }
.hw-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.hw-bar { display: flex; align-items: center; gap: 13px; padding: 13px 16px; background: linear-gradient(180deg, #241209, #180c05); }
.hw-ic { flex: none; width: 46px; height: 46px; border: 1.5px solid var(--hw-gold); border-radius: 50%; color: var(--hw-gold-bright); display: flex; align-items: center; justify-content: center; }
/* check236: the Services card's icon IS the owner's normal
   medallion, filling its gold-ring disc. */
.hw-ic .hw-ic-medal { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; display: block; }
.hw-text { display: flex; flex-direction: column; min-width: 0; }
.hw-name { font-family: var(--font-display); font-style: italic; font-weight: 600; color: var(--hw-cream); font-size: 1.32rem; line-height: 1.15; }
.hw-sub { color: var(--hw-gold); text-transform: uppercase; letter-spacing: .13em; font-size: .66rem; font-weight: 600; margin-top: 3px; font-family: var(--font-geo); }
.hw-arrow { margin-left: auto; flex: none; width: 38px; height: 38px; border: 1.5px solid var(--hw-gold); border-radius: 50%; color: var(--hw-gold-bright); display: flex; align-items: center; justify-content: center; }
body.theme-halloween .svc-panel { background: var(--hw-panel); border-color: var(--hw-gold); color: var(--hw-ink); }
body.theme-halloween .svc-panel h2, body.theme-halloween .svc-panel h3 { color: var(--hw-gold-bright); }
body.theme-halloween .svc-item-desc { color: var(--hw-muted); }

/* ---------- Halloween: footer ---------- */
body.theme-halloween .site-footer { background: #0f0703; color: #e9dcc3; border-top: 1px solid var(--hw-gold); }
body.theme-halloween .site-footer h3 { color: var(--hw-gold-bright); }
body.theme-halloween .site-footer .tagline { color: var(--hw-muted); }
body.theme-halloween .site-footer a { color: #f0d9a8; }
body.theme-halloween .site-footer .rating { border-color: var(--hw-gold); color: var(--hw-cream); }
body.theme-halloween .footer-bottom { border-top-color: #3a2410; color: #a98f5f; }

/* ---------- Halloween: the step cards + booking ---------- */
body.theme-halloween .step-card { background: var(--hw-panel); border: 1px solid var(--hw-gold); color: var(--hw-ink); }
body.theme-halloween .step-n { background: var(--hw-maroon); border: 1px solid var(--hw-gold); color: var(--hw-cream); }
body.theme-halloween .step-glyph { background: transparent; border-color: var(--hw-gold); }
body.theme-halloween .step-glyph::before { content: "🎃"; font-size: 1.1rem; }
body.theme-halloween .step-head .step-hint { color: var(--hw-muted); }
body.theme-halloween .book-svc .slot, body.theme-halloween .time-grid .slot {
    background: var(--hw-panel2); border-color: var(--hw-line); color: var(--hw-ink); border-radius: 18px;
}
body.theme-halloween .book-svc .slot:has(input:checked) {
    background: linear-gradient(180deg, #5a3410, #3d2208); border-color: #e8a33d; color: var(--hw-cream);
}
/* check236: on phones the picked service AND the picked
   time wear the mock's ORANGE GLOW (bright gradient fill +
   lit border + halo); the wide-screen dark-amber fill
   above is unchanged. The picked service also swaps to
   the glowing medallion (the shared .slot medal rules) —
   no extra check disc: his selected medallion file
   already carries the check badge. */
@media (max-width: 640px) {
    body.theme-halloween .book-svc .slot:has(input:checked),
    body.theme-halloween .time-grid .slot:has(input:checked) {
        background: linear-gradient(180deg, #f59a23, #e05f0c);
        border-color: #ffb35c;
        color: #fff;
        box-shadow: 0 0 0 3px rgba(245, 154, 35, .35), 0 6px 18px rgba(224, 95, 12, .45);
    }
}
body.theme-halloween .book-svc .slot::after { content: "›"; margin-left: auto; color: var(--hw-gold-bright); font-size: 1.35rem; line-height: 1; }
body.theme-halloween .date-display { background: linear-gradient(180deg, #6d2b30, var(--hw-maroon)); color: var(--hw-cream); border: 1px solid var(--hw-gold); box-shadow: 0 4px 14px rgba(0, 0, 0, .45); }
body.theme-halloween .date-display:hover { background: var(--hw-maroon); }
body.theme-halloween .cal-pop { background: var(--hw-panel); border-color: var(--hw-gold); color: var(--hw-ink); }
body.theme-halloween .cal-nav { background: var(--hw-panel2); color: var(--hw-gold-bright); border-color: var(--hw-line); }
body.theme-halloween .btn-call { background: linear-gradient(180deg, #f59a23, #e05f0c); color: #fff; border-color: transparent; }
body.theme-halloween .btn-call:hover { background: linear-gradient(180deg, #f59a23, #c94f08); color: #fff; }
body.theme-halloween .btn-book { background: linear-gradient(180deg, #f59a23, #e05f0c); color: #fff; border-color: transparent; }
body.theme-halloween .btn-outline { background: transparent; border-color: var(--hw-gold); color: var(--hw-gold-bright); }
body.theme-halloween .contact-block { background: var(--hw-panel); border: 1px solid var(--hw-gold); border-radius: 18px; padding: 24px 22px; color: var(--hw-ink); }
body.theme-halloween .contact-block h2, body.theme-halloween .contact-block h3 { color: var(--hw-gold-bright); }
body.theme-halloween .picked-summary, body.theme-halloween .bill-frame { background: var(--hw-panel); border-color: var(--hw-line); color: var(--hw-ink); }

/* ---------- Halloween: forms + generic surfaces (all pages) ---------- */
body.theme-halloween input, body.theme-halloween select, body.theme-halloween textarea {
    background: var(--hw-panel2); border-color: var(--hw-line); color: var(--hw-cream);
}
body.theme-halloween .form-card, body.theme-halloween .qe-card {
    background: var(--hw-panel); border-color: var(--hw-line); color: var(--hw-ink);
}
body.theme-halloween .notice { background: #2a1a0c; border-color: var(--hw-line); color: var(--hw-ink); }
body.theme-halloween .notice.error { background: #3d1416; border-color: #8a3a3a; color: #ffd9d0; }
body.theme-halloween .theme-sel { background: var(--hw-panel2); color: var(--hw-cream); border: 1.5px solid var(--hw-line); border-radius: 8px; padding: 6px 8px; }

/* ---------- Halloween: admin skin (check236: staff pages
   never carry the body class, so these can only match the
   shared pieces on public pages — never an admin page) --- */
/* check236: the staff banner keeps its WHITE, readable
   design under every theme — its old near-black recolor
   rule here is removed on purpose. */
body.theme-halloween .book-grid { background: var(--hw-panel); border-color: var(--hw-line); color: var(--hw-ink); }
body.theme-halloween .book-grid th, body.theme-halloween .book-grid td { border-color: #3a2410; }
body.theme-halloween .book-grid td.has-area { background: var(--hw-panel2); }
body.theme-halloween .appt-card { background: #2a180c; border-color: var(--hw-line); color: var(--hw-ink); }
body.theme-halloween .book-empty, body.theme-halloween .book-closed, body.theme-halloween .book-blocked { color: var(--hw-muted); }
body.theme-halloween .cust-tabs a { background: var(--hw-panel2); border-color: var(--hw-gold); color: var(--hw-gold-bright); }
body.theme-halloween .pick-row, body.theme-halloween .slot-check, body.theme-halloween .custom-time,
body.theme-halloween .qe-pick-btn, body.theme-halloween .cal-pop { background: var(--hw-panel); color: var(--hw-ink); }
body.theme-halloween .view-pill3 { background: var(--hw-panel); border-color: var(--hw-gold); }
body.theme-halloween .vp3-seg { color: var(--hw-gold-bright); }

/* ---------- Halloween: sign-in pages (check236: the
   medallion markup is gone and /CheckIn + the PIN page
   never carry the body class — these rules are inert) --- */
.hw-signin-medal { width: 84px; height: 84px; border-radius: 50%; display: block; margin: 0 auto 10px; }
.hw-ci-medal { text-align: center; padding: 14px 0 2px; background: var(--hw-bg); }
.hw-ci-medal .hw-signin-medal { margin: 0 auto; }
body.theme-halloween .ci-wrap { background: var(--hw-bg); color: var(--hw-ink); }
body.theme-halloween .ci-band { background: var(--hw-panel); border-bottom: 1px solid var(--hw-gold); }
body.theme-halloween .ci-brand { color: var(--hw-gold-bright); }
body.theme-halloween .ci-phonebox, body.theme-halloween .ci-textbox { background: var(--hw-panel2); border-color: var(--hw-gold); color: var(--hw-cream); }
body.theme-halloween .ci-key { background: var(--hw-panel2); color: var(--hw-cream); border-color: var(--hw-line); }
body.theme-halloween .pin-input { background: var(--hw-panel2); border-color: var(--hw-gold); color: var(--hw-cream); }

/* ==========================================================
   check237 (owner, Oct 29, 2026, 9:32–9:38 AM): the dark
   theme applies EVERYWHERE while it is on — customer pages,
   Admin, CheckIn, and the PIN page. Admin layout/behavior
   are untouched; this section only recolors. Standing rule
   for this layer: NO white or near-white background may
   survive under body.theme-halloween on any surface, and
   staff text rides a bright high-contrast set. The white-
   spot fixes below each name the spot they close.
   ========================================================== */

/* SPOT: the themed NAV ROW on desktop — its dark ground
   existed only in the <=767px block, so wider screens fell
   back to the standard header's white bar with gold letters
   (owner's screenshot catch). Dark at every width now. */
body.theme-halloween .site-header.hw-header nav.site-nav { background: var(--hw-panel); }

/* SPOT: the SALON MANAGEMENT BANNER — check236's white
   ground is superseded while the theme is on (the owner's
   readability complaint was never about dark, it was about
   dim letters): deep maroon-black ground, BRIGHT letters —
   cream name, lit-gold sub and weekday, warm-white date. */
body.theme-halloween .admin-banner { background: linear-gradient(135deg, #170b06 0%, #2a130b 55%, #3a1c0d 100%); border-bottom: 2px solid var(--hw-gold); }
body.theme-halloween .admin-banner .ab-name { color: #fdf3e0; }
body.theme-halloween .admin-banner .ab-sub { color: #ffd98a; }
body.theme-halloween .admin-banner .ab-date { color: #f3e9d2; }
body.theme-halloween .admin-banner .ab-dow { color: #ffd98a; }

/* SPOT: the /Admin/Book toolbar rows — the design pills
   (.theme-opt: white ground, grey text) and the visitor
   "All time" pill (white ground) rendered white on the dark
   admin (owner's screenshot). Dark grounds, bright text;
   the active design pill wears the maroon + gold ring. */
body.theme-halloween .book-theme-row .theme-opt { background: var(--hw-panel2); color: var(--hw-ink); border-color: var(--hw-line); }
body.theme-halloween .book-theme-row .theme-opt:hover { border-color: var(--hw-gold); }
body.theme-halloween .book-theme-row .theme-opt.active { background: var(--hw-maroon); color: var(--hw-cream); border-color: var(--hw-gold); box-shadow: inset 0 0 0 1px var(--hw-gold); }
body.theme-halloween .visit-pill-total { background: var(--hw-panel2); color: var(--hw-gold-bright); border-color: var(--hw-gold); }
body.theme-halloween .visit-pill-today { background: var(--hw-maroon); color: var(--hw-cream); }

/* Staff body text: the bright set, stated once for the
   surfaces the base skin leaves at its light-theme ink. */
body.theme-halloween .ab-date, body.theme-halloween .book-grid td,
body.theme-halloween .book-grid th { color: var(--hw-ink); }

/* SPOT: the page-top band's two pills (Gallery / Our Salon /
   Visit / Search / My Appointment) — translucent WHITE
   grounds with rose text, never recolored by the theme
   layer. Dark glass grounds + lit-gold text under the
   theme; the current page's pill wears the orange. */
body.theme-halloween .page-top-pill { background: rgba(23, 11, 6, .88); border-color: var(--hw-gold); color: #f0d9a8; }
body.theme-halloween .page-top-pill.is-active { background: linear-gradient(180deg, #f59a23, #e05f0c); border-color: #ffb35c; color: #fff; }

/* ---------- check237 white-spot batch 2 (rig scan) --------
   Every entry names the surface the computed-style scan
   caught at white/near-white under the theme. */
/* SPOT: /Admin/Book day-column headers (#faf1ee). */
body.theme-halloween .book-grid thead th { background: var(--hw-panel2); color: var(--hw-gold-bright); }
/* SPOT: /Admin/Book closed + past-day cells (#e9e4e1 greys). */
body.theme-halloween .book-grid .book-closed { background: #241610; color: var(--hw-muted); }
/* SPOT: /Admin/Book customer-booked cells (pale yellow
   #f9eac0 highlight) — a dark amber tint keeps the meaning. */
body.theme-halloween .book-grid td.book-appt-customer { background: #3d2c10; }
body.theme-halloween .book-grid td.book-appt-customer a { color: #ffd98a; }
/* SPOT: the booking alert's ACKNOWLEDGE button (white on
   the red alert bar) — dark button, white letters. */
body.theme-halloween .booking-alert .ba-ack { background: #2a0f0c; color: #fff; }
/* SPOT: the shared pill button (.pill-btn — Edit service /
   length / status pills and friends) is a white pill with
   rose text at base; its .sel highlight (bright yellow
   with dark ink) already reads on dark and is kept. */
body.theme-halloween .pill-btn { background: var(--hw-panel2); color: var(--hw-ink); border-color: var(--hw-line); }
body.theme-halloween .pill-btn.time-btn.taken, body.theme-halloween .pill-btn.time-btn.blocked, body.theme-halloween .pill-btn.status-btn:disabled { background: #241610; border-color: var(--hw-line); color: var(--hw-muted); }
/* SPOT: the checkout TIP pills (white, gold border) — dark
   pills; the picked tip keeps a lit maroon-gold gradient. */
body.theme-halloween .tip-sec .tip-row .pill-btn { background: var(--hw-panel2); color: var(--hw-gold-bright); border-color: var(--hw-gold); }
body.theme-halloween .tip-sec .tip-row .pill-btn .tip-amt { color: var(--hw-muted); }
body.theme-halloween .tip-sec .tip-row .pill-btn.sel { background: linear-gradient(160deg, #6d2b30, var(--hw-maroon)); color: #fff; border-color: var(--hw-gold); box-shadow: 0 0 0 2px rgba(0,0,0,.4), 0 0 0 4.5px var(--hw-gold), 0 8px 18px rgba(0,0,0,.5); }
body.theme-halloween .tip-sec .tip-row .pill-btn.sel .tip-amt { color: #ffeec9; }
/* SPOT: the Edit page's four TEXT TILES (#fffdf9 cards,
   rose labels) — dark cards, lit-gold labels. */
body.theme-halloween .textset .tstile { background: var(--hw-panel); border-color: var(--hw-line); }
body.theme-halloween .textset .tstile .ts-lb,
body.theme-halloween .textset .tstile .ts-lb a { color: var(--hw-gold-bright); }
/* SPOT: /CheckIn's A+ emblem disc (white) — dark disc,
   gold ring (kept), lit-gold letters. */
body.theme-halloween .ci-emblem { background: var(--hw-panel2); color: var(--hw-gold-bright); }
/* SPOT: the CONFIRMATION card (#fff8f3) — the booking
   confirmation view and the message pages share it. Dark
   panel, and its photo fade + white text button follow. */
body.theme-halloween .conf-card { background: var(--hw-panel); border-color: var(--hw-line); color: var(--hw-ink); box-shadow: 0 18px 44px rgba(0, 0, 0, .5); }
body.theme-halloween .conf-photo::after { background: linear-gradient(to bottom, rgba(23, 12, 7, 0), var(--hw-panel)); }
body.theme-halloween .conf-btn-txt { background: var(--hw-panel2); }

/* SPOT batch 3 (Edit page chips): the text tiles' icon
   discs (pale cream; the Google G's disc is white), the
   notes "Visits Only" toggle (white), and the note pencil
   chip (white) — all dark discs/buttons under the theme. */
body.theme-halloween .textset .icx { background: var(--hw-panel2); color: var(--hw-gold-bright); }
body.theme-halloween .note-list .nvt-btn { background: var(--hw-panel2); color: var(--hw-gold-bright); border-color: var(--hw-gold); }
body.theme-halloween .note-list .nvt-btn.is-on { background: var(--hw-maroon); color: var(--hw-cream); }
body.theme-halloween .note-pen { background: var(--hw-panel2); border-color: var(--hw-gold); color: var(--hw-gold-bright); }
/* ...except the Google G keeps its blue (lighter, so it
   reads on the dark disc) — it is the staff's cue for the
   Google Review tile. */
body.theme-halloween .textset .ic-g { color: #7aa7f0; }

/* SPOT batch 4: the Book grid's sticky TIME GUTTER
   (.book-time / .book-time-head, #faf7f5/#faf1ee) — a white
   strip down the grid's left edge (the generic scan missed
   it: off-screen row headers report zero height in the
   headless pass; the screenshot + computed-style query are
   the evidence). Plus the grid's settings rows (.tool-link)
   kept their light-theme dark-brown ink — unreadable on
   the dark ground; they take the lit gold. */
body.theme-halloween .book-grid .book-time,
body.theme-halloween .book-grid .book-time-head { background: var(--hw-panel2); color: var(--hw-gold-bright); }
body.theme-halloween .book-admin-actions .tool-link { color: var(--hw-gold-bright); border-color: var(--hw-line); }

/* SPOT batch 5 (booking-flow scan): the confirmation's
   DETAILS panel (.conf-details) is pure white inside the
   dark card, its icon discs pale pink; and the /Deposit
   page's terms box (.dep-terms) is pale cream. */
body.theme-halloween .conf-details { background: var(--hw-panel2); border-color: var(--hw-gold); color: var(--hw-ink); }
body.theme-halloween .conf-ic { background: #3a2410; }
body.theme-halloween .conf-svc { color: var(--hw-gold-bright); }
body.theme-halloween .dep-terms { background: #2a1a0c; border-color: var(--hw-line); color: var(--hw-ink); }
/* ...and the confirmation's outline buttons (Text Me /
   Cancel / Home) keep a dim rose ink at base — lit gold
   under the theme so they read on the dark card. */
body.theme-halloween .conf-btn.conf-btn-txt { color: #f0d9a8; }

/* SPOT batch 6 (grid tags): the card's deposit/restriction
   tag (.rstr-tag, pale rose #f6d9d2) and the PAID stamp's
   translucent-white backing — dark maroon tag with bright
   letters; the stamp keeps its green, brightened, on a
   translucent-dark backing. */
body.theme-halloween .rstr-tag { background: #4a1f1a; border-color: #c96a5a; color: #ffb4a0; }
body.theme-halloween .paid-stamp { background: rgba(20, 10, 6, .55); color: #7ed492; border-color: #7ed492; }

/* SPOT batch 7 (final sweep): a PAST day's free cells
   (.cell-free.day-past) keep their own light-grey paint —
   dark like the closed cells under the theme. */
body.theme-halloween .book-grid td.cell-free.day-past,
body.theme-halloween .book-grid td.book-empty.day-past { background: #241610; }
body.theme-halloween .book-grid td.cell-free.day-past a { background: transparent; }
/* ...the whole day-past family, not just the empty cell:
   past cells, past area cells and the CARDS in past days
   all carry #f3f1f0 at base. Under the theme they go dark
   (past customer-booked cells keep the dark amber tint
   and their bright link color). */
body.theme-halloween .book-grid td.day-past,
body.theme-halloween .book-grid th.day-past,
body.theme-halloween .book-grid td.has-area.day-past { background: #241610; }
body.theme-halloween .book-grid td.day-past .appt-card { background: var(--hw-panel2); }
body.theme-halloween .book-grid td.book-appt-customer.day-past { background: #3d2c10; }
body.theme-halloween .book-grid td.book-appt-customer.day-past a { color: #ffd98a; }

/* ---------- check253 white-spot batch 8 (owner, Oct 29,
   2026 — the zero-white re-audit of the dev line) ---------
   The class-by-class skin missed whole staff surfaces; each
   entry names the page the computed-style scan caught at
   white/near-white. Colors only — no layout changes, and
   the classic theme is untouched (every rule is scoped to
   body.theme-halloween). */
/* SPOT: /Admin/ActivityLog — the entry cards and filter
   pills kept #fff, the sticky title band kept its cream
   ground, and the who chips were pale tints. Dark grounds
   and bright ink; the chips keep their customer / admin /
   system hues, deepened; the active filter pill keeps its
   distinction in maroon. */
body.theme-halloween .al-top { background: var(--hw-bg); }
body.theme-halloween .al-h1, body.theme-halloween .al-titlelink, body.theme-halloween .al-titlelink .al-backarr { color: var(--hw-gold-bright); }
body.theme-halloween .al-pill { background: var(--hw-panel2); border-color: var(--hw-gold); color: var(--hw-gold-bright); }
body.theme-halloween .al-pill.on { background: var(--hw-maroon); border-color: var(--hw-gold); color: var(--hw-cream); }
body.theme-halloween .al-entry { background: var(--hw-panel); border-color: var(--hw-line); color: var(--hw-ink); box-shadow: 0 1px 3px rgba(0, 0, 0, .4); }
body.theme-halloween .al-custname { color: var(--hw-cream); }
body.theme-halloween .al-custphone, body.theme-halloween .al-daylabel,
body.theme-halloween .al-when, body.theme-halloween .al-meta { color: var(--hw-muted); }
body.theme-halloween .al-what { color: var(--hw-ink); }
body.theme-halloween .al-detail { color: #d9c9a8; }
body.theme-halloween .al-chev { color: var(--hw-gold-bright); }
body.theme-halloween .al-who.customer { background: #17364d; color: #8fc3f5; }
body.theme-halloween .al-who.admin { background: #4a2320; color: #f2b8ab; }
body.theme-halloween .al-who.system { background: #2e2a26; color: #cfc8bd; }
/* SPOT: /Admin/SignIns + /Admin/SignIn — the sign-in cards
   (.si-card, .si-empty) kept #fff, the time chip and the
   status chips were pale tints. */
body.theme-halloween .si-card { background: var(--hw-panel); border-color: var(--hw-line); color: var(--hw-ink); box-shadow: 0 1px 3px rgba(0, 0, 0, .4); }
body.theme-halloween .si-empty { background: var(--hw-panel); border-color: var(--hw-line); color: var(--hw-muted); }
body.theme-halloween .si-row { border-bottom-color: var(--hw-line); }
body.theme-halloween .si-time { background: var(--hw-panel2); border-color: var(--hw-line); }
body.theme-halloween .si-time b { color: var(--hw-gold-bright); }
body.theme-halloween .si-time span { color: var(--hw-muted); }
body.theme-halloween .si-svc { color: #d9c9a8; }
body.theme-halloween .si-ph, body.theme-halloween .si-sub, body.theme-halloween .si-chev { color: var(--hw-muted); }
body.theme-halloween .si-tag-new, body.theme-halloween .si-st-wait { background: #3d2c10; color: #ffd98a; border-color: var(--hw-line); }
body.theme-halloween .si-st-appt { background: #173d24; color: #8fd3a5; }
body.theme-halloween .si-st-dismissed { background: #2e2a26; color: #cfc8bd; }
/* SPOT: /Admin/PhoneSync — the panel card kept #fff (the
   theme's pale-gold headings sat ON the white and were
   nearly unreadable) and its row labels / rules list were
   dim browns written for the white card. Dark card; the
   bright fonts read as intended. */
body.theme-halloween .sync-card { background: var(--hw-panel); color: var(--hw-ink); box-shadow: 0 18px 42px rgba(0, 0, 0, .5); }
body.theme-halloween .sync-divider { background: var(--hw-line); }
body.theme-halloween .sync-row { border-bottom-color: var(--hw-line); }
body.theme-halloween .sync-row span { color: var(--hw-muted); }
body.theme-halloween .sync-btn-pw { background: var(--hw-panel2); }
body.theme-halloween .sync-setup-url { color: var(--hw-muted); }
body.theme-halloween .sync-rules li { color: var(--hw-ink); }
/* SPOT: /Admin/AppointmentPayment — the Receipt Image pill
   (.btn-gold), the bill editor's $ / ✕ round buttons and
   the ＋ Add item bar kept #fff / cream grounds. */
body.theme-halloween .btn-gold { background: var(--hw-panel2); color: var(--hw-gold-bright); }
body.theme-halloween .btn-gold:hover { background: var(--hw-panel); }
body.theme-halloween .pay-disc-btn { background: var(--hw-panel2); color: var(--hw-gold-bright); }
body.theme-halloween .pay-remove { background: var(--hw-panel2); border-color: var(--hw-line); color: #f2b8ab; }
body.theme-halloween .pay-additem { background: var(--hw-panel2); border-color: var(--hw-gold); color: var(--hw-gold-bright); }
/* SPOT: /Admin/Blacklist — the Remove buttons (.btn-mini)
   kept #fff. The class is shared, so every .btn-mini on a
   themed page takes the dark ground; its rose ink already
   remaps bright through --rose-dark. */
body.theme-halloween .btn-mini { background: var(--hw-panel2); }
body.theme-halloween .btn-mini.danger:hover { background: #3d1416; }
/* SPOT: /Pay + /Bill — the bill's TOTAL stamp sat on a
   translucent-WHITE plaque (rgba(255,255,255,.65)). It
   takes the dark translucent backing the grid's PAID stamp
   already wears, its inks brightened to match; and the
   bill frame's inset paper ring (#fffdfb) — the light line
   ringing the dark sheet — goes panel-dark, the gold
   hairline beside it kept. */
body.theme-halloween .bill-stamp { background: rgba(20, 10, 6, .6); }
body.theme-halloween .bill-stamp-due { color: #d8c3a5; border-color: #a68a64; }
body.theme-halloween .bill-stamp-paid { color: #7ed492; border-color: #7ed492; }
body.theme-halloween .bill-frame { box-shadow: 0 18px 50px rgba(0, 0, 0, .5), inset 0 0 0 5px var(--hw-panel), inset 0 0 0 6.5px var(--gold); }
/* SPOT: the staff banner's logo — its base rule carries
   background:#fff (clipped under the opaque medallion, so
   never visible), but the letter of the zero-white rule
   takes a theme-scoped override anyway; the base rule and
   the classic theme keep the white. */
body.theme-halloween .admin-banner .ab-logo { background: transparent; }

/* ---------- check258 adaptation: this line's own chrome ----
   The dev line never had the check257 env switcher; its two
   white pills would sit on a themed page for an owner
   session. Under Halloween they take the unit's own DEV
   dark/gold dress (the look the owner approved for DEV) in
   BOTH environments — the knob position, not the color,
   says which environment is live. */
body.theme-halloween .env-slider257 { background: #241a17; border-color: #4a3730; }
body.theme-halloween .env-lab257 { color: #c9ae7e; }
body.theme-halloween .env-knob257 { background: var(--hw-maroon); color: var(--hw-cream); box-shadow: 0 2px 6px rgba(0,0,0,.5); }
body.theme-halloween .switcher257.env-dev .env-knob257 { background: #241a17; color: #f2c14e; }
body.theme-halloween .view-pill3 { background: #241a17; border-color: #4a3730; }
body.theme-halloween .vp3-seg { color: #c9ae7e; }
body.theme-halloween .vp3-seg.on { background: var(--hw-maroon); color: var(--hw-cream); }
body.theme-halloween .switcher257.env-dev .vp3-seg.on { background: #241a17; color: #f2c14e; }


/* ═══════════════════════════════════════════════════════════════════
   check259 (owner, Oct 30, 2026) — Halloween READABILITY pass +
   confirmation hero. The zero-white skin left the Book-grid VARIANT
   cards on their CLASSIC light backgrounds (the classic
   .book-grid .appt-card.card-* rules (0,3,0) beat the skin's
   body.theme-halloween .appt-card (0,2,1)) while their text took the
   theme's light colors — light-on-light ("Cannot read at all").
   Everything below is gated under body.theme-halloween; Classic is
   untouched. (1) every card variant gets a dark themed background +
   bright text; (2) the muted secondary classes (.p-note, QE helpers,
   medallion labels, placeholders) rise to AA-bright values —
   hierarchy rides weight/size now, never dimness; (3) the standard
   confirmation card becomes the page hero: lifted warm card, strong
   gold frame + glow, date/time values biggest + brightest.
   ═══════════════════════════════════════════════════════════════════ */
body.theme-halloween .book-grid .appt-card.card-customer { background: #3d2c10; color: var(--hw-ink); }
body.theme-halloween .book-grid .appt-card.card-odd { background: #4a3208; color: #ffe9b8; }
body.theme-halloween .book-grid .appt-card.card-deposit { background: #38200f; color: var(--hw-ink); }
/* the classic customer-cell rule (line ~2868) pins #33302d on any
   non-customer card in a customer cell at (0,5,2) — the deposit
   card lives exactly there; mirror it gated, brighter: */
body.theme-halloween .book-grid td.book-appt-customer a.appt-card:not(.card-customer):not(.card-noshow) { color: var(--hw-ink); }
body.theme-halloween .book-grid .appt-card.card-noshow { background: #2e2a28; color: #d8ccc6; }
body.theme-halloween .p-note, body.theme-halloween .book-grid .appt-card .p-note { color: #e8cf9f; }
body.theme-halloween .book-grid .appt-card.card-discount .p-note { color: #ffe9e6; }
body.theme-halloween .book-grid .appt-card .act-chk-grey { color: #d8c391; }
body.theme-halloween .book-grid .appt-card .act-chk-blue { color: #7db8f0; }
body.theme-halloween .late-label { color: var(--hw-gold-bright); }
body.theme-halloween input::placeholder, body.theme-halloween textarea::placeholder { color: #d9bc85; opacity: 1; }
body.theme-halloween .qe-what, body.theme-halloween .qe-more { color: #e8cf9f; }
body.theme-halloween .qe-problem { background: #3a1410; border-color: #c96a5a; color: #ffd9cf; }
body.theme-halloween .conf-card { background: linear-gradient(180deg, #6b4423, #472a10); border: 4px solid #ffc44d; box-shadow: 0 0 0 6px rgba(255, 180, 60, .25), 0 0 55px rgba(255, 150, 40, .65), 0 0 110px rgba(255, 120, 20, .35), inset 0 0 34px rgba(255, 170, 60, .18); }
body.theme-halloween .conf-col:has(> .conf-card) { position: relative; z-index: 0; }
body.theme-halloween .conf-col:has(> .conf-card)::before { content: ""; position: absolute; inset: -46px -14px; background: radial-gradient(ellipse at 50% 42%, rgba(255, 150, 40, .35), rgba(255, 150, 40, 0) 65%); z-index: -1; pointer-events: none; }
body.theme-halloween .conf-details { background: #4a2c10; }
body.theme-halloween .conf-photo::after { background: linear-gradient(to bottom, rgba(71, 42, 16, 0), #472a10); }
body.theme-halloween .conf-who { color: #fff6e0; }
body.theme-halloween .conf-svc { color: #ffd98a; font-weight: 700; }
body.theme-halloween .conf-drow b { color: var(--hw-cream); }
body.theme-halloween .conf-drow b.conf-date, body.theme-halloween .conf-drow b:not(.conf-date):not(.conf-addr) { font-size: 26px; font-weight: 800; color: #ffffff; }
body.theme-halloween .conf-drow b.conf-addr { color: #ffe9bb; }
body.theme-halloween .conf-ic { background: #7a4d1d; border: 2px solid #ffc44d; }
body.theme-halloween .conf-ic svg { stroke: #ffd98a; }
body.theme-halloween .conf-badge { filter: drop-shadow(0 0 6px rgba(53, 199, 89, .8)); }
body.theme-halloween .conf-phone a { color: #ffd98a; font-weight: 800; }
body.theme-halloween .conf-salonname { color: var(--hw-gold-bright); }
body.theme-halloween .conf-btn-note { color: #d9bc85; }
/* check259 (owner, Oct 30, 2026, 9:15 AM): the Halloween home hero
   buttons go SOLID — the orange gradient and the translucent-look
   panel read washed out over the hero art ("cannot see clear").
   Flat fills only, labels/icons >= 4.5:1 on their own ground:
   white on #bc5406 = 4.72, #f0d9a8 on #1d110a = 11.9. Same buttons,
   same order, same links — emphasis only. */
body.theme-halloween .hw-btn-book { background: #bc5406; color: #ffffff; font-weight: 700; box-shadow: 0 6px 18px rgba(0, 0, 0, .45); }
body.theme-halloween .hw-btn-search { background: #1d110a; border: 2px solid var(--hw-gold); color: #f0d9a8; font-weight: 700; }

/* ═══════════════════════════════════════════════════════════════════
   check259 (owner, Oct 30, 2026) — the SERVICE BUTTON component
   (approved sample: mockups/svcbtn/sample2). _ServicePills is the
   one shared render; the letter coin is replaced by the A+ glow
   medallion (/images/medal-selected.png). Resting = PLAIN icon
   (check261, owner Oct 30, 2026: "not glowing when unselected,
   only glows when selected" — supersedes item 8's resting glow
   for the icon only) + soft whole-button glow (themed border +
   outer halo + inset
   sheen); selected (:has(input:checked)) = stronger halo +
   brighter border + slightly larger glow icon. One treatment per
   theme, derived from its palette after the sample's three worked
   examples (Halloween / Dusty Rose / Evening Glamour verbatim).
   Scoped to .book-svc so the time/worker .slot pills never move.
   ═══════════════════════════════════════════════════════════════════ */
.book-svc .slot { height: 56px; border-radius: 20px; border: 2.5px solid #e58bb1; background: #fff7fa; color: #5b2333; box-shadow: 0 0 18px rgba(240, 130, 180, .45), inset 0 0 10px rgba(240, 130, 180, .12); }
.book-svc .slot:has(input:checked) { background: #ffeef6; border: 3px solid #e06ba0; color: #4a1c29; box-shadow: 0 0 32px rgba(240, 110, 170, .65), 0 0 10px rgba(245, 140, 190, .7), inset 0 0 14px rgba(240, 110, 170, .2); }
.book-svc .svc-medal { width: 38px; height: 38px; flex: 0 0 auto; display: block; filter: none; }
.book-svc .slot:has(input:checked) .svc-medal { width: 42px; height: 42px; filter: drop-shadow(0 0 8px rgba(255, 120, 175, .95)); }
.book-svc .slot::after { content: "›"; margin-left: auto; font-size: 1.35rem; line-height: 1; font-weight: 700; }
.book-svc .slot.slot-blocked { background: #f4efec; border-color: #cbb8b0; color: var(--muted); box-shadow: none; }
.book-svc .slot.slot-blocked .svc-medal { filter: grayscale(1); opacity: .45; }
/* Dusty Rose — rose-pink glow (sample verbatim) */
body.theme-dusty .book-svc .slot, body.theme-halloween .book-svc .slot { background: #fff8f1; border-color: #d98a94; color: #43302a; box-shadow: 0 0 18px rgba(230, 120, 140, .45), inset 0 0 10px rgba(230, 120, 140, .12); }
body.theme-dusty .book-svc .slot:has(input:checked), body.theme-halloween .book-svc .slot:has(input:checked) { background: #ffedf0; border-color: #d95f74; color: #2e1d16; box-shadow: 0 0 32px rgba(230, 110, 140, .65), 0 0 10px rgba(240, 140, 160, .7), inset 0 0 14px rgba(230, 120, 140, .2); }
body.theme-dusty .book-svc .svc-medal, body.theme-halloween .book-svc .svc-medal { filter: none; }
body.theme-dusty .book-svc .slot:has(input:checked) .svc-medal, body.theme-halloween .book-svc .slot:has(input:checked) .svc-medal { filter: drop-shadow(0 0 8px rgba(255, 120, 150, .95)); }
/* Marble & Gold — gold glow */
body.theme-marble .book-svc .slot { background: #fffdf4; border-color: #c9a227; color: #54450f; box-shadow: 0 0 18px rgba(201, 162, 39, .45), inset 0 0 10px rgba(201, 162, 39, .12); }
body.theme-marble .book-svc .slot:has(input:checked) { background: #fdf3cd; border-color: #a8861c; color: #453a0c; box-shadow: 0 0 32px rgba(201, 162, 39, .65), 0 0 10px rgba(215, 180, 70, .7), inset 0 0 14px rgba(201, 162, 39, .2); }
body.theme-marble .book-svc .svc-medal { filter: none; }
body.theme-marble .book-svc .slot:has(input:checked) .svc-medal { filter: drop-shadow(0 0 8px rgba(220, 180, 60, 1)); }
/* Botanical Spa — green-gold glow */
body.theme-botanical .book-svc .slot { background: #f8fbf1; border-color: #8aa653; color: #37451d; box-shadow: 0 0 18px rgba(140, 170, 80, .45), inset 0 0 10px rgba(140, 170, 80, .12); }
body.theme-botanical .book-svc .slot:has(input:checked) { background: #eff6dc; border-color: #6d8a35; color: #2e3c16; box-shadow: 0 0 32px rgba(130, 165, 70, .65), 0 0 10px rgba(155, 190, 95, .7), inset 0 0 14px rgba(130, 165, 70, .2); }
body.theme-botanical .book-svc .svc-medal { filter: none; }
body.theme-botanical .book-svc .slot:has(input:checked) .svc-medal { filter: drop-shadow(0 0 8px rgba(160, 200, 90, 1)); }
/* Evening Glamour — violet glow (sample verbatim) */
body.theme-evening .book-svc .slot { background: linear-gradient(180deg, #2a2140, #1d1730); border-color: #8f7fb8; color: #efe7f7; box-shadow: 0 0 18px rgba(150, 120, 230, .5), inset 0 0 12px rgba(150, 120, 230, .16); }
body.theme-evening .book-svc .slot:has(input:checked) { background: linear-gradient(180deg, #3a2c58, #271e42); border-color: #c0aaff; color: #ffffff; box-shadow: 0 0 34px rgba(160, 130, 255, .7), 0 0 10px rgba(190, 160, 255, .75), inset 0 0 16px rgba(160, 130, 255, .28); }
body.theme-evening .book-svc .svc-medal { filter: none; }
body.theme-evening .book-svc .slot:has(input:checked) .svc-medal { filter: drop-shadow(0 0 8px rgba(190, 160, 255, 1)); }
/* Halloween — orange/gold glow (sample verbatim) */
body.theme-halloween .book-svc .slot { background: linear-gradient(180deg, #452a0e, #2a180c); border: 2.5px solid #e8a33d; color: #f7ead0; box-shadow: 0 0 18px rgba(255, 140, 30, .45), inset 0 0 12px rgba(255, 140, 30, .18); }
body.theme-halloween .book-svc .slot:has(input:checked) { background: linear-gradient(180deg, #6b3d10, #452a0e); border: 3px solid #ffc44d; color: #fff3d6; box-shadow: 0 0 34px rgba(255, 150, 40, .75), 0 0 10px rgba(255, 180, 60, .8), inset 0 0 16px rgba(255, 160, 50, .3); }
body.theme-halloween .book-svc .svc-medal { filter: none; }
body.theme-halloween .book-svc .slot:has(input:checked) .svc-medal { width: 42px; height: 42px; filter: drop-shadow(0 0 10px rgba(255, 170, 50, 1)); }
/* check259 (owner, Oct 30, 2026): the confirmation time value's
   check badge — part of the shared component in EVERY theme (the
   one Classic-visible change in this build, by the owner's own
   directive). Bright green disc (#1d9d4e — the medallion check's
   green) with a white check: reads on the classic cream panel and
   on the dark Halloween panel alike. Sized in em, so it tracks
   the time text it follows. */
.conf-badge { display: inline-flex; width: 1.05em; height: 1.05em; margin-left: 8px; vertical-align: -0.14em; color: #35c759; }
.conf-badge svg { width: 100%; height: 100%; display: block; }

/* check259 item 3 FINAL (owner-approved WAY MORE sample,
   mockups/svcbtn/confcard.html): the Classic side of the same
   emphasis — stronger gold frame + warm soft shadow on the card,
   date/time the biggest, brightest values in Classic's ink.
   These ungated rules are the ONLY Classic-visible changes in
   this build besides the badge above and item 4's switcher. */
.conf-card { border: 2.5px solid var(--cgold); box-shadow: 0 18px 44px rgba(140, 79, 82, .22), 0 0 30px rgba(201, 162, 39, .28); }
.conf-drow b.conf-date, .conf-drow b:not(.conf-date):not(.conf-addr) { font-size: 22px; font-weight: 800; }

/* check259 item 9 (owner, Oct 30, 2026 — "ON PC, it's
   impossible to navigate. The header is gigantic"): DESKTOP
   ONLY (>= 992px) — the header becomes a contained band.
   Classic: the emblem artwork is height-capped (width follows
   its aspect ratio; the check169 cream ground melts the sides)
   — banner + pills + nav total ~270px. Halloween: the wide
   hero is height-capped with object-fit cover, centered (the
   scene art tolerates the crop; the phone cluster swap below
   640px is untouched). Phone/tablet rendering is unchanged —
   everything here is inside the min-width media query. */
@media (min-width: 992px) {
    body .brand-art img { width: auto; height: 150px; }
    .hw-hero .hw-hero-main { height: 150px; object-fit: cover; object-position: center; }
    /* Amendment 1 (owner chose sample B, Oct 30, 2026,
       10:47 AM — "remove on PC"): the two header CTA pills go
       away on desktop in BOTH branches — the nav row already
       carries both links. Markup still renders; phones keep
       the pills exactly as before. */
    body .header-pills, .hw-actions { display: none; }
    /* Amendment 2 (owner, Oct 30, 2026, 10:48 AM): the PC
       header is NOT sticky — "Let it all scroll off." No part
       of the site header stays fixed on desktop. (The owner's
       bottom switcher is a separate floating element and is
       untouched.) */
    .site-header { position: static; }
}

/* check260 item 2 (owner, Oct 30, 2026, 12:07 PM): on phone
   and iPad the two header buttons (Book Appointment /
   Search Appointment) stay stuck while the page scrolls —
   mobile must match the PC decision (check259 item 9:
   the header scrolls off). The stick comes from the PARENT:
   .site-header is position:sticky at base, and the Classic
   .header-pills row lives inside it (the Halloween
   .hw-actions row sits outside the header in .hw-top and
   already scrolls; what sticks in that branch is the same
   header's nav row). Below the desktop breakpoint the
   header becomes position:relative — NOT static, because
   the mobile .site-nav dropdown is absolutely anchored to
   it (top:100%); relative keeps that anchor pixel-identical
   while the whole header, buttons included, scrolls away
   in BOTH branches. Desktop (>= 992px) is untouched: the
   item-9 block above still hides the pills and holds the
   header static there. The owner's bottom switcher is a
   separate floating element and is not touched. */
@media (max-width: 991.98px) {
    .site-header { position: relative; }
}

/* ════════════════════════════════════════════════════════════
   check261 (owner, Oct 30, 2026): Halloween over an editorial
   base (.thed). Parts 1/2/4 below shipped first as the
   hotfix-260b stopgap (owner: "Deploy now. Quicker") and are
   folded in verbatim; part 3 (the medallion resting glow) is
   folded into the check259 service-button section itself,
   where those rules live. The bill insets at the end are
   check261's own crawl finds (light gradients on EVERY base,
   Rose included — the variable system never reaches them).
   ════════════════════════════════════════════════════════════ */

/* Part 1 — the editorial themes drive the customer pages
   through variables (--paper #faf4ef, --surface #fff, --alt,
   --header-bg…) consumed by body.pub.thed rules at (0,2,1),
   which beat the Halloween layer's (0,1,1). While Halloween
   is on, the variables themselves go dark. Scoped to
   halloween+thed only — no other theme changes. */
body.theme-halloween.thed, body.pub.theme-halloween {
    --paper: #140b06;
    --alt: #1d110a;
    --surface: #1d110a;
    --acc: #c8a165;
    --acc-hi: #e8c88a;
    --acc-text: #e8c88a;
    --acc-soft: #6b4d24;
    --acc-tint: #241209;
    --dots: #6b4d24;
    --line: #6b4d24;
    --hair: #3a2410;
    --ink-th: #f3e9d2;
    --muted-th: #c9ae7e;
    --btn-ink: #140b06;
    --header-bg: rgba(20, 11, 6, .94);
    --footer-bg: #0f0703;
    --panel: #1d110a;
    --outline-bg: rgba(29, 17, 10, .88);
    --hero-ink: #fdf3e0;
    --hero-sub: #c9ae7e;
    --shade-a: rgba(20, 11, 6, .95);
    --shade-b: rgba(20, 11, 6, .84);
    --shade-c: rgba(20, 11, 6, .28);
    --hero-img: url("/images/halloween/hero.jpg");
}

/* Part 2 — the hero buttons' text was repainted by the
   editorial link color (body.pub.thed a, (0,2,2)) — mud-brown
   on the orange Book button, dusty rose on Search. Re-assert
   the check259 item-6 spec: Book = white on orange, Search =
   pale gold on dark. (Every other themed link reads the
   remapped --acc-text gold from part 1.) */
body.pub.theme-halloween a.hw-btn-book { color: #fff; }
body.pub.theme-halloween a.hw-btn-search { color: #f0d9a8; }

/* Part 4 — the white band under the hero buttons was the
   site header painted by a LITERAL #fff rule (the editorial
   light-masthead block) that outranks the Halloween header
   rule and is immune to the variable fix. Darken the
   HALLOWEEN header only — the white masthead under the
   normal themes is the owner's brand design (the emblem
   artwork's ground) and is untouched. The border-bottom
   line is check261's addition (the Halloween layer's gold
   frame under the header). */
body.pub.theme-halloween .site-header.hw-header { background: var(--hw-bg); border-bottom: 1px solid rgba(255, 196, 77, .35); }
body.pub.theme-halloween .site-header.hw-header .site-nav { background: var(--hw-panel); }
body.pub.theme-halloween .site-header.hw-header .site-nav a { color: #e6c887; }
body.pub.theme-halloween .site-header.hw-header .nav-toggle span { background: var(--hw-gold-bright); }

/* check261 crawl finds — literal light rules the variable
   system never reaches, on any base: the contact buttons'
   pale gradients (the thed tint rules at (0,3,1) outrank the
   Halloween layer's (0,2,1)) and the bill's inset panels
   (light gradients on every base, Rose included). */
body.pub.theme-halloween .btn-call { background: linear-gradient(180deg, #6b4423, #472a10); color: #ffe9bd; border-color: #ffc44d; }
body.pub.theme-halloween .btn-book { background: linear-gradient(180deg, #f59a23, #e05f0c); color: #fff; border-color: #ffc44d; }
.bill-totals { background: linear-gradient(180deg, #241209, #1d110a); }
.tip-sec { background: linear-gradient(180deg, #2a180c, #1d110a); }

/* ════════════════════════════════════════════════════════════
   check262 item 3 (owner, Oct 30, 2026, 7:52 PM — his shot of
   the selected 1:00 PM time button + his tap): under Halloween
   there are exactly TWO button formats. ACTION buttons wear
   the selected-time-button format — orange gradient
   (180deg, #f59a23 → #e05f0c, the check259-proven stops),
   white bold text, pill radius (each class's own radius is
   already 999px). SECONDARY buttons wear the Search format —
   dark panel, gold border, pale gold text (the .hw-btn-search
   treatment). Selectable pills are not action buttons: dark
   at rest, and they turn the SAME orange when selected, at
   every width. Scoped to body.theme-halloween only — Classic
   and the other themes are untouched.
   ════════════════════════════════════════════════════════════ */
/* — primary action buttons → orange — */
body.theme-halloween .btn-call, body.pub.theme-halloween .btn-call {
    background: linear-gradient(180deg, #f59a23, #e05f0c);
    color: #fff; font-weight: 700; border-color: transparent;
}
body.theme-halloween .btn-call:hover, body.pub.theme-halloween .btn-call:hover {
    background: linear-gradient(180deg, #f59a23, #c94f08); color: #fff;
}
body.theme-halloween .ci-ok {
    background: linear-gradient(180deg, #f59a23, #e05f0c);
    color: #fff; box-shadow: 0 10px 22px rgba(224, 95, 12, .35);
}
body.theme-halloween .pp-pay {
    background: linear-gradient(180deg, #f59a23, #e05f0c); color: #fff;
}
body.theme-halloween .pp-pay:hover {
    background: linear-gradient(180deg, #f59a23, #c94f08);
}
body.theme-halloween .conf-btn-cal {
    background: linear-gradient(180deg, #f59a23, #e05f0c);
    border-color: transparent;
    box-shadow: 0 8px 20px rgba(224, 95, 12, .35);
}
/* — the header Book button joins the primary format (it was
   flattened to solid #bc5406 by check259 for contrast over the
   hero art; the owner's item-3 ruling makes the gradient THE
   action format site-wide, header included — see PROOF.md) — */
body.theme-halloween .hw-btn-book {
    background: linear-gradient(180deg, #f59a23, #e05f0c);
}
/* — secondary buttons → the Search format (the Search button's
   own ground is var(--hw-panel) #1d110a since check259) — */
body.theme-halloween .btn-outline, body.pub.theme-halloween .btn-outline, body.theme-halloween .btn.another-no {
    background: var(--hw-panel); border: 1.5px solid var(--hw-gold);
    color: #f0d9a8; font-weight: 600;
}
body.theme-halloween .conf-btn.conf-btn-txt {
    background: var(--hw-panel); border-color: var(--hw-gold);
    color: #f0d9a8;
}
/* — selectable pills: selected = the same orange, all widths — */
body.theme-halloween .book-svc .slot:has(input:checked),
body.theme-halloween .time-grid .slot:has(input:checked) {
    background: linear-gradient(180deg, #f59a23, #e05f0c);
    border-color: #ffb35c; color: #fff;
    box-shadow: 0 0 0 3px rgba(245, 154, 35, .35), 0 6px 18px rgba(224, 95, 12, .45);
}
body.theme-halloween .tip-sec .tip-row .pill-btn.sel {
    background: linear-gradient(180deg, #f59a23, #e05f0c);
    color: #fff; border-color: #ffb35c;
    box-shadow: 0 0 0 2px rgba(0, 0, 0, .4), 0 0 0 4.5px var(--hw-gold), 0 8px 18px rgba(0, 0, 0, .5);
}
body.theme-halloween .pill-btn.sel {
    background: linear-gradient(180deg, #f59a23, #e05f0c);
    border-color: #ffb35c; color: #fff;
}
body.theme-halloween .cal-day.sel {
    background: linear-gradient(180deg, #f59a23, #e05f0c);
    color: #fff; font-weight: 700;
}

/* check262 item 4 (owner, Oct 30, 2026, 7:57 PM — "Click on
   top header will bring back home page"): the Halloween hero
   link fills its container (no dead rim around the art), and
   the header band shows the hand — the band's non-interactive
   area navigates home via the shared site.js handler; the
   nav links and hamburger keep their own jobs. */
.hw-hero a { display: block; }
.site-header.hw-header, .site-header.hw-header a, .site-header.hw-header button { cursor: pointer; }

/* check272 (owner, Oct 31, 2026, 1:48 PM + 1:29 PM): the
   day note inside a Book day header (written on the Time
   block screen — see DayNotes), and the outline on the
   appointment card a contact-link landing brings into
   view. Both render only while the combined gate is on:
   the note span exists only for noted days and the
   appt-focus class is added only by the ?appt= script. */
.book-daynote { display:block; font-size:.78rem; font-weight:700; color:#8a4b3a; line-height:1.3; margin-top:2px; }
.appt-card.appt-focus { outline:3px solid #cd841f; outline-offset:2px; }

/* ════════════════════════════════════════════════════════════
   check274 (owner, Oct 31, 2026 — "Here is my theme for
   November. Can you create a theme called Thanksgiving 1
   based on these images"): THANKSGIVING 1 — the owner's
   light autumn design (cream ground, rust/gold leaves,
   deep-brown script) as a one-theme value beside Halloween
   in UnifiedTheme. This section is the theme-halloween
   layer's structural twin: same slots, same layout rules,
   light palette. It paints ONLY under
   body.theme-thanksgiving1, which the layout stamps only
   while the Check274 gate shows for the request (DEV
   sessions, or Features:Check274 "on") and Thanksgiving 1
   is the book's one theme — no other body ever matches.
   The editorial variables come first (the twin of the
   body.pub.theme-halloween variable block); the --hw-*
   variables are then REDEFINED light on the same body, so
   the unscoped hw-* structural rules (header band, cards,
   banners) repaint from the same declarations Halloween
   uses; the scoped twins after them mirror every
   body.theme-halloween rule with dark literals mapped to
   their light roles. The orange action gradient is kept —
   it is the art's own pumpkin orange.
   ════════════════════════════════════════════════════════════ */
/* The editorial variable block is the mechanical twin of
   body.pub.theme-halloween's (in the twins below); this
   block redefines the --hw-* variables light on the same
   body — :root carries Halloween's dark values, and every
   unscoped hw-* structural rule reads them from here. */
body.theme-thanksgiving1 {
    --hw-bg: #fbf2df;
    --hw-panel: #fffaf0;
    --hw-panel2: #f7ead2;
    --hw-gold: #b07f2a;
    --hw-gold-bright: #96690f;
    --hw-cream: #fdf3e0;
    --hw-ink: #43301c;
    --hw-muted: #8a6a44;
    --hw-line: #d9b380;
    --hw-maroon: #7a3b1e;
}

body.theme-thanksgiving1 .book-pin-corner, body.theme-thanksgiving1 .book-pin-day, body.theme-thanksgiving1 .book-pin-day.day-past { background:var(--hw-panel2); color:var(--hw-gold-bright); }
html:has(body.theme-thanksgiving1) { background: var(--hw-bg); }
body.theme-thanksgiving1 { background: var(--hw-bg);
    color: var(--hw-ink);
    font-family: var(--font-geo);
    color-scheme: light;
    /* check236: the page-level overflow guard — nothing on
       a themed customer page may push past the viewport and
       hand the phone a horizontal scroll. `clip`, not
       `hidden`: it creates no scroll container, so the
       sticky header keeps sticking. */
    overflow-x: clip;
    --font-body: "Jost", "Inter", -apple-system, "Segoe UI", sans-serif;
    --charcoal: #43301c;
    --muted: #8a6a44;
    --rose: #b07f2a;
    --rose-dark: #a05c14;
    --rose-deep: #96690f;
    --rose-soft: #f3e3c2;
    --blush: #fffaf0;
    --shadow: 0 10px 30px rgba(101, 67, 33, .28); }
body.theme-thanksgiving1 h1 { font-family: var(--font-script); font-weight: 400; }
body.theme-thanksgiving1 h2 { font-family: var(--font-display); font-style: italic; }
body.theme-thanksgiving1 .btn, body.theme-thanksgiving1 button, body.theme-thanksgiving1 input, body.theme-thanksgiving1 select, body.theme-thanksgiving1 textarea, body.theme-thanksgiving1 label { font-family: var(--font-geo); }
body.theme-thanksgiving1 a { color: var(--hw-gold-bright); }
body.theme-thanksgiving1 .svc-panel { background: var(--hw-panel); border-color: var(--hw-gold); color: var(--hw-ink); }
body.theme-thanksgiving1 .svc-panel h2, body.theme-thanksgiving1 .svc-panel h3 { color: var(--hw-gold-bright); }
body.theme-thanksgiving1 .svc-item-desc { color: var(--hw-muted); }
body.theme-thanksgiving1 .site-footer { background: #f3e6cf; color: #e9d5ae; border-top: 1px solid var(--hw-gold); }
body.theme-thanksgiving1 .site-footer h3 { color: var(--hw-gold-bright); }
body.theme-thanksgiving1 .site-footer .tagline { color: var(--hw-muted); }
body.theme-thanksgiving1 .site-footer a { color: #7a4a16; }
body.theme-thanksgiving1 .site-footer .rating { border-color: var(--hw-gold); color: var(--hw-cream); }
body.theme-thanksgiving1 .footer-bottom { border-top-color: #e9d5ae; color: #96690f; }
body.theme-thanksgiving1 .step-card { background: var(--hw-panel); border: 1px solid var(--hw-gold); color: var(--hw-ink); }
body.theme-thanksgiving1 .step-n { background: var(--hw-maroon); border: 1px solid var(--hw-gold); color: var(--hw-cream); }
body.theme-thanksgiving1 .step-glyph { background: transparent; border-color: var(--hw-gold); }
body.theme-thanksgiving1 .step-glyph::before { content: "🎃"; font-size: 1.1rem; }
body.theme-thanksgiving1 .step-head .step-hint { color: var(--hw-muted); }
body.theme-thanksgiving1 .book-svc .slot, body.theme-thanksgiving1 .time-grid .slot { background: var(--hw-panel2); border-color: var(--hw-line); color: var(--hw-ink); border-radius: 18px; }
body.theme-thanksgiving1 .book-svc .slot:has(input:checked) { background: linear-gradient(180deg, #7a4a16, #7a4a16); border-color: #e8a33d; color: var(--hw-cream); }
@media (max-width: 640px) {
    body.theme-thanksgiving1 .book-svc .slot:has(input:checked), body.theme-thanksgiving1 .time-grid .slot:has(input:checked) { background: linear-gradient(180deg, #f59a23, #e05f0c);
        border-color: #e08a1e;
        color: #fff;
        box-shadow: 0 0 0 3px rgba(245, 154, 35, .35), 0 6px 18px rgba(224, 95, 12, .45); }
}
body.theme-thanksgiving1 .book-svc .slot::after { content: "›"; margin-left: auto; color: var(--hw-gold-bright); font-size: 1.35rem; line-height: 1; }
body.theme-thanksgiving1 .date-display { background: linear-gradient(180deg, #7a3b1e, var(--hw-maroon)); color: var(--hw-cream); border: 1px solid var(--hw-gold); box-shadow: 0 4px 14px rgba(101, 67, 33, .24); }
body.theme-thanksgiving1 .date-display:hover { background: var(--hw-maroon); }
body.theme-thanksgiving1 .cal-pop { background: var(--hw-panel); border-color: var(--hw-gold); color: var(--hw-ink); }
body.theme-thanksgiving1 .cal-nav { background: var(--hw-panel2); color: var(--hw-gold-bright); border-color: var(--hw-line); }
body.theme-thanksgiving1 .btn-call { background: linear-gradient(180deg, #f59a23, #e05f0c); color: #fff; border-color: transparent; }
body.theme-thanksgiving1 .btn-call:hover { background: linear-gradient(180deg, #f59a23, #c94f08); color: #fff; }
body.theme-thanksgiving1 .btn-book { background: linear-gradient(180deg, #f59a23, #e05f0c); color: #fff; border-color: transparent; }
body.theme-thanksgiving1 .btn-outline { background: transparent; border-color: var(--hw-gold); color: var(--hw-gold-bright); }
body.theme-thanksgiving1 .contact-block { background: var(--hw-panel); border: 1px solid var(--hw-gold); border-radius: 18px; padding: 24px 22px; color: var(--hw-ink); }
body.theme-thanksgiving1 .contact-block h2, body.theme-thanksgiving1 .contact-block h3 { color: var(--hw-gold-bright); }
body.theme-thanksgiving1 .picked-summary, body.theme-thanksgiving1 .bill-frame { background: var(--hw-panel); border-color: var(--hw-line); color: var(--hw-ink); }
body.theme-thanksgiving1 input, body.theme-thanksgiving1 select, body.theme-thanksgiving1 textarea { background: var(--hw-panel2); border-color: var(--hw-line); color: var(--hw-cream); }
body.theme-thanksgiving1 .form-card, body.theme-thanksgiving1 .qe-card { background: var(--hw-panel); border-color: var(--hw-line); color: var(--hw-ink); }
body.theme-thanksgiving1 .notice { background: #f7ead2; border-color: var(--hw-line); color: var(--hw-ink); }
body.theme-thanksgiving1 .notice.error { background: #7a3b1e; border-color: #a03d1e; color: #f7ead2; }
body.theme-thanksgiving1 .theme-sel { background: var(--hw-panel2); color: var(--hw-cream); border: 1.5px solid var(--hw-line); border-radius: 8px; padding: 6px 8px; }
body.theme-thanksgiving1 .book-grid { background: var(--hw-panel); border-color: var(--hw-line); color: var(--hw-ink); }
body.theme-thanksgiving1 .book-grid th, body.theme-thanksgiving1 .book-grid td { border-color: #e9d5ae; }
body.theme-thanksgiving1 .book-grid td.has-area { background: var(--hw-panel2); }
body.theme-thanksgiving1 .appt-card { background: #f3e3c2; border-color: var(--hw-line); color: var(--hw-ink); }
body.theme-thanksgiving1 .book-empty, body.theme-thanksgiving1 .book-closed, body.theme-thanksgiving1 .book-blocked { color: var(--hw-muted); }
body.theme-thanksgiving1 .cust-tabs a { background: var(--hw-panel2); border-color: var(--hw-gold); color: var(--hw-gold-bright); }
body.theme-thanksgiving1 .pick-row, body.theme-thanksgiving1 .slot-check, body.theme-thanksgiving1 .custom-time, body.theme-thanksgiving1 .qe-pick-btn, body.theme-thanksgiving1 .cal-pop { background: var(--hw-panel); color: var(--hw-ink); }
body.theme-thanksgiving1 .view-pill3 { background: var(--hw-panel); border-color: var(--hw-gold); }
body.theme-thanksgiving1 .vp3-seg { color: var(--hw-gold-bright); }
body.theme-thanksgiving1 .ci-wrap { background: var(--hw-bg); color: var(--hw-ink); }
body.theme-thanksgiving1 .ci-band { background: var(--hw-panel); border-bottom: 1px solid var(--hw-gold); }
body.theme-thanksgiving1 .ci-brand { color: var(--hw-gold-bright); }
body.theme-thanksgiving1 .ci-phonebox, body.theme-thanksgiving1 .ci-textbox { background: var(--hw-panel2); border-color: var(--hw-gold); color: var(--hw-cream); }
body.theme-thanksgiving1 .ci-key { background: var(--hw-panel2); color: var(--hw-cream); border-color: var(--hw-line); }
body.theme-thanksgiving1 .pin-input { background: var(--hw-panel2); border-color: var(--hw-gold); color: var(--hw-cream); }
body.theme-thanksgiving1 .site-header.hw-header nav.site-nav { background: var(--hw-panel); }
body.theme-thanksgiving1 .admin-banner { background: linear-gradient(135deg, #fbf2df 0%, #f7ead2 55%, #7a4a16 100%); border-bottom: 2px solid var(--hw-gold); }
body.theme-thanksgiving1 .admin-banner .ab-name { color: #43301c; }
body.theme-thanksgiving1 .admin-banner .ab-sub { color: #a05c14; }
body.theme-thanksgiving1 .admin-banner .ab-date { color: #43301c; }
body.theme-thanksgiving1 .admin-banner .ab-dow { color: #a05c14; }
body.theme-thanksgiving1 .book-theme-row .theme-opt { background: var(--hw-panel2); color: var(--hw-ink); border-color: var(--hw-line); }
body.theme-thanksgiving1 .book-theme-row .theme-opt:hover { border-color: var(--hw-gold); }
body.theme-thanksgiving1 .book-theme-row .theme-opt.active { background: var(--hw-maroon); color: var(--hw-cream); border-color: var(--hw-gold); box-shadow: inset 0 0 0 1px var(--hw-gold); }
body.theme-thanksgiving1 .visit-pill-total { background: var(--hw-panel2); color: var(--hw-gold-bright); border-color: var(--hw-gold); }
body.theme-thanksgiving1 .visit-pill-today { background: var(--hw-maroon); color: var(--hw-cream); }
body.theme-thanksgiving1 .ab-date, body.theme-thanksgiving1 .book-grid td, body.theme-thanksgiving1 .book-grid th { color: var(--hw-ink); }
body.theme-thanksgiving1 .page-top-pill { background: rgba(23, 11, 6, .88); border-color: var(--hw-gold); color: #7a4a16; }
body.theme-thanksgiving1 .page-top-pill.is-active { background: linear-gradient(180deg, #f59a23, #e05f0c); border-color: #e08a1e; color: #fff; }
body.theme-thanksgiving1 .book-grid thead th { background: var(--hw-panel2); color: var(--hw-gold-bright); }
body.theme-thanksgiving1 .book-grid .book-closed { background: #f7ead2; color: var(--hw-muted); }
body.theme-thanksgiving1 .book-grid td.book-appt-customer { background: #e9d5ae; }
body.theme-thanksgiving1 .book-grid td.book-appt-customer a { color: #a05c14; }
body.theme-thanksgiving1 .booking-alert .ba-ack { background: #2a0f0c; color: #fff; }
body.theme-thanksgiving1 .pill-btn { background: var(--hw-panel2); color: var(--hw-ink); border-color: var(--hw-line); }
body.theme-thanksgiving1 .pill-btn.time-btn.taken, body.theme-thanksgiving1 .pill-btn.time-btn.blocked, body.theme-thanksgiving1 .pill-btn.status-btn:disabled { background: #f7ead2; border-color: var(--hw-line); color: var(--hw-muted); }
body.theme-thanksgiving1 .tip-sec .tip-row .pill-btn { background: var(--hw-panel2); color: var(--hw-gold-bright); border-color: var(--hw-gold); }
body.theme-thanksgiving1 .tip-sec .tip-row .pill-btn .tip-amt { color: var(--hw-muted); }
body.theme-thanksgiving1 .tip-sec .tip-row .pill-btn.sel { background: linear-gradient(160deg, #7a3b1e, var(--hw-maroon)); color: #fff; border-color: var(--hw-gold); box-shadow: 0 0 0 2px rgba(0,0,0,.4), 0 0 0 4.5px var(--hw-gold), 0 8px 18px rgba(101, 67, 33, .28); }
body.theme-thanksgiving1 .tip-sec .tip-row .pill-btn.sel .tip-amt { color: #f7ead2; }
body.theme-thanksgiving1 .textset .tstile { background: var(--hw-panel); border-color: var(--hw-line); }
body.theme-thanksgiving1 .textset .tstile .ts-lb, body.theme-thanksgiving1 .textset .tstile .ts-lb a { color: var(--hw-gold-bright); }
body.theme-thanksgiving1 .ci-emblem { background: var(--hw-panel2); color: var(--hw-gold-bright); }
body.theme-thanksgiving1 .conf-card { background: var(--hw-panel); border-color: var(--hw-line); color: var(--hw-ink); box-shadow: 0 18px 44px rgba(101, 67, 33, .28); }
body.theme-thanksgiving1 .conf-photo::after { background: linear-gradient(to bottom, rgba(23, 12, 7, 0), var(--hw-panel)); }
body.theme-thanksgiving1 .conf-btn-txt { background: var(--hw-panel2); }
body.theme-thanksgiving1 .textset .icx { background: var(--hw-panel2); color: var(--hw-gold-bright); }
body.theme-thanksgiving1 .note-list .nvt-btn { background: var(--hw-panel2); color: var(--hw-gold-bright); border-color: var(--hw-gold); }
body.theme-thanksgiving1 .note-list .nvt-btn.is-on { background: var(--hw-maroon); color: var(--hw-cream); }
body.theme-thanksgiving1 .note-pen { background: var(--hw-panel2); border-color: var(--hw-gold); color: var(--hw-gold-bright); }
body.theme-thanksgiving1 .textset .ic-g { color: #3d74c2; }
body.theme-thanksgiving1 .book-grid .book-time, body.theme-thanksgiving1 .book-grid .book-time-head { background: var(--hw-panel2); color: var(--hw-gold-bright); }
body.theme-thanksgiving1 .book-admin-actions .tool-link { color: var(--hw-gold-bright); border-color: var(--hw-line); }
body.theme-thanksgiving1 .conf-details { background: var(--hw-panel2); border-color: var(--hw-gold); color: var(--hw-ink); }
body.theme-thanksgiving1 .conf-ic { background: #e9d5ae; }
body.theme-thanksgiving1 .conf-svc { color: var(--hw-gold-bright); }
body.theme-thanksgiving1 .dep-terms { background: #f7ead2; border-color: var(--hw-line); color: var(--hw-ink); }
body.theme-thanksgiving1 .conf-btn.conf-btn-txt { color: #7a4a16; }
body.theme-thanksgiving1 .rstr-tag { background: #7a3b1e; border-color: #b45a28; color: #d98a5f; }
body.theme-thanksgiving1 .paid-stamp { background: rgba(20, 10, 6, .55); color: #3d9950; border-color: #3d9950; }
body.theme-thanksgiving1 .book-grid td.cell-free.day-past, body.theme-thanksgiving1 .book-grid td.book-empty.day-past { background: #f7ead2; }
body.theme-thanksgiving1 .book-grid td.cell-free.day-past a { background: transparent; }
body.theme-thanksgiving1 .book-grid td.day-past, body.theme-thanksgiving1 .book-grid th.day-past, body.theme-thanksgiving1 .book-grid td.has-area.day-past { background: #f7ead2; }
body.theme-thanksgiving1 .book-grid td.day-past .appt-card { background: var(--hw-panel2); }
body.theme-thanksgiving1 .book-grid td.book-appt-customer.day-past { background: #e9d5ae; }
body.theme-thanksgiving1 .book-grid td.book-appt-customer.day-past a { color: #a05c14; }
body.theme-thanksgiving1 .al-top { background: var(--hw-bg); }
body.theme-thanksgiving1 .al-h1, body.theme-thanksgiving1 .al-titlelink, body.theme-thanksgiving1 .al-titlelink .al-backarr { color: var(--hw-gold-bright); }
body.theme-thanksgiving1 .al-pill { background: var(--hw-panel2); border-color: var(--hw-gold); color: var(--hw-gold-bright); }
body.theme-thanksgiving1 .al-pill.on { background: var(--hw-maroon); border-color: var(--hw-gold); color: var(--hw-cream); }
body.theme-thanksgiving1 .al-entry { background: var(--hw-panel); border-color: var(--hw-line); color: var(--hw-ink); box-shadow: 0 1px 3px rgba(101, 67, 33, .22); }
body.theme-thanksgiving1 .al-custname { color: var(--hw-cream); }
body.theme-thanksgiving1 .al-custphone, body.theme-thanksgiving1 .al-daylabel, body.theme-thanksgiving1 .al-when, body.theme-thanksgiving1 .al-meta { color: var(--hw-muted); }
body.theme-thanksgiving1 .al-what { color: var(--hw-ink); }
body.theme-thanksgiving1 .al-detail { color: #8a6a44; }
body.theme-thanksgiving1 .al-chev { color: var(--hw-gold-bright); }
body.theme-thanksgiving1 .al-who.customer { background: #e2ecf7; color: #3d74c2; }
body.theme-thanksgiving1 .al-who.admin { background: #7a3b1e; color: #d98a5f; }
body.theme-thanksgiving1 .al-who.system { background: #43301c; color: #8a6a44; }
body.theme-thanksgiving1 .si-card { background: var(--hw-panel); border-color: var(--hw-line); color: var(--hw-ink); box-shadow: 0 1px 3px rgba(101, 67, 33, .22); }
body.theme-thanksgiving1 .si-empty { background: var(--hw-panel); border-color: var(--hw-line); color: var(--hw-muted); }
body.theme-thanksgiving1 .si-row { border-bottom-color: var(--hw-line); }
body.theme-thanksgiving1 .si-time { background: var(--hw-panel2); border-color: var(--hw-line); }
body.theme-thanksgiving1 .si-time b { color: var(--hw-gold-bright); }
body.theme-thanksgiving1 .si-time span { color: var(--hw-muted); }
body.theme-thanksgiving1 .si-svc { color: #8a6a44; }
body.theme-thanksgiving1 .si-ph, body.theme-thanksgiving1 .si-sub, body.theme-thanksgiving1 .si-chev { color: var(--hw-muted); }
body.theme-thanksgiving1 .si-tag-new, body.theme-thanksgiving1 .si-st-wait { background: #e9d5ae; color: #a05c14; border-color: var(--hw-line); }
body.theme-thanksgiving1 .si-st-appt { background: #e2f2e4; color: #3d9950; }
body.theme-thanksgiving1 .si-st-dismissed { background: #43301c; color: #8a6a44; }
body.theme-thanksgiving1 .sync-card { background: var(--hw-panel); color: var(--hw-ink); box-shadow: 0 18px 42px rgba(101, 67, 33, .28); }
body.theme-thanksgiving1 .sync-divider { background: var(--hw-line); }
body.theme-thanksgiving1 .sync-row { border-bottom-color: var(--hw-line); }
body.theme-thanksgiving1 .sync-row span { color: var(--hw-muted); }
body.theme-thanksgiving1 .sync-btn-pw { background: var(--hw-panel2); }
body.theme-thanksgiving1 .sync-setup-url { color: var(--hw-muted); }
body.theme-thanksgiving1 .sync-rules li { color: var(--hw-ink); }
body.theme-thanksgiving1 .btn-gold { background: var(--hw-panel2); color: var(--hw-gold-bright); }
body.theme-thanksgiving1 .btn-gold:hover { background: var(--hw-panel); }
body.theme-thanksgiving1 .pay-disc-btn { background: var(--hw-panel2); color: var(--hw-gold-bright); }
body.theme-thanksgiving1 .pay-remove { background: var(--hw-panel2); border-color: var(--hw-line); color: #d98a5f; }
body.theme-thanksgiving1 .pay-additem { background: var(--hw-panel2); border-color: var(--hw-gold); color: var(--hw-gold-bright); }
body.theme-thanksgiving1 .btn-mini { background: var(--hw-panel2); }
body.theme-thanksgiving1 .btn-mini.danger:hover { background: #7a3b1e; }
body.theme-thanksgiving1 .bill-stamp { background: rgba(20, 10, 6, .6); }
body.theme-thanksgiving1 .bill-stamp-due { color: #a05c14; border-color: #96690f; }
body.theme-thanksgiving1 .bill-stamp-paid { color: #3d9950; border-color: #3d9950; }
body.theme-thanksgiving1 .bill-frame { box-shadow: 0 18px 50px rgba(101, 67, 33, .28), inset 0 0 0 5px var(--hw-panel), inset 0 0 0 6.5px var(--gold); }
body.theme-thanksgiving1 .admin-banner .ab-logo { background: transparent; }
body.theme-thanksgiving1 .env-slider257 { background: #f7ead2; border-color: #8a6a44; }
body.theme-thanksgiving1 .env-lab257 { color: #8a6a44; }
body.theme-thanksgiving1 .env-knob257 { background: var(--hw-maroon); color: var(--hw-cream); box-shadow: 0 2px 6px rgba(101, 67, 33, .28); }
body.theme-thanksgiving1 .switcher257.env-dev .env-knob257 { background: #f7ead2; color: #f2c14e; }
body.theme-thanksgiving1 .view-pill3 { background: #f7ead2; border-color: #8a6a44; }
body.theme-thanksgiving1 .vp3-seg { color: #8a6a44; }
body.theme-thanksgiving1 .vp3-seg.on { background: var(--hw-maroon); color: var(--hw-cream); }
body.theme-thanksgiving1 .switcher257.env-dev .vp3-seg.on { background: #f7ead2; color: #f2c14e; }
body.theme-thanksgiving1 .book-grid .appt-card.card-customer { background: #e9d5ae; color: var(--hw-ink); }
body.theme-thanksgiving1 .book-grid .appt-card.card-odd { background: #e9d5ae; color: #ffffff; }
body.theme-thanksgiving1 .book-grid .appt-card.card-deposit { background: #7a4a16; color: var(--hw-ink); }
body.theme-thanksgiving1 .book-grid td.book-appt-customer a.appt-card:not(.card-customer):not(.card-noshow) { color: var(--hw-ink); }
body.theme-thanksgiving1 .book-grid .appt-card.card-noshow { background: #43301c; color: #8a6a44; }
body.theme-thanksgiving1 .p-note, body.theme-thanksgiving1 .book-grid .appt-card .p-note { color: #a05c14; }
body.theme-thanksgiving1 .book-grid .appt-card.card-discount .p-note { color: #fdf6ea; }
body.theme-thanksgiving1 .book-grid .appt-card .act-chk-grey { color: #a05c14; }
body.theme-thanksgiving1 .book-grid .appt-card .act-chk-blue { color: #3d74c2; }
body.theme-thanksgiving1 .late-label { color: var(--hw-gold-bright); }
body.theme-thanksgiving1 input::placeholder, body.theme-thanksgiving1 textarea::placeholder { color: #a05c14; opacity: 1; }
body.theme-thanksgiving1 .qe-what, body.theme-thanksgiving1 .qe-more { color: #a05c14; }
body.theme-thanksgiving1 .qe-problem { background: #7a3b1e; border-color: #b45a28; color: #f7ead2; }
body.theme-thanksgiving1 .conf-card { background: linear-gradient(180deg, #8a5a20, #f3e3c2); border: 4px solid #ffc44d; box-shadow: 0 0 0 6px rgba(255, 180, 60, .25), 0 0 55px rgba(255, 150, 40, .65), 0 0 110px rgba(255, 120, 20, .35), inset 0 0 34px rgba(255, 170, 60, .18); }
body.theme-thanksgiving1 .conf-col:has(> .conf-card) { position: relative; z-index: 0; }
body.theme-thanksgiving1 .conf-col:has(> .conf-card)::before { content: ""; position: absolute; inset: -46px -14px; background: radial-gradient(ellipse at 50% 42%, rgba(255, 150, 40, .35), rgba(255, 150, 40, 0) 65%); z-index: -1; pointer-events: none; }
body.theme-thanksgiving1 .conf-details { background: #e9d5ae; }
body.theme-thanksgiving1 .conf-photo::after { background: linear-gradient(to bottom, rgba(71, 42, 16, 0), #f3e3c2); }
body.theme-thanksgiving1 .conf-who { color: #fffaf0; }
body.theme-thanksgiving1 .conf-svc { color: #a05c14; font-weight: 700; }
body.theme-thanksgiving1 .conf-drow b { color: var(--hw-cream); }
body.theme-thanksgiving1 .conf-drow b.conf-date, body.theme-thanksgiving1 .conf-drow b:not(.conf-date):not(.conf-addr) { font-size: 26px; font-weight: 800; color: #ffffff; }
body.theme-thanksgiving1 .conf-drow b.conf-addr { color: #ffffff; }
body.theme-thanksgiving1 .conf-ic { background: #7a4a16; border: 2px solid #ffc44d; }
body.theme-thanksgiving1 .conf-ic svg { stroke: #a05c14; }
body.theme-thanksgiving1 .conf-badge { filter: drop-shadow(0 0 6px rgba(53, 199, 89, .8)); }
body.theme-thanksgiving1 .conf-phone a { color: #a05c14; font-weight: 800; }
body.theme-thanksgiving1 .conf-salonname { color: var(--hw-gold-bright); }
body.theme-thanksgiving1 .conf-btn-note { color: #a05c14; }
body.theme-thanksgiving1 .hw-btn-book { background: #bc5406; color: #ffffff; font-weight: 700; box-shadow: 0 6px 18px rgba(101, 67, 33, .24); }
body.theme-thanksgiving1 .hw-btn-search { background: #fffaf0; border: 2px solid var(--hw-gold); color: #7a4a16; font-weight: 700; }
body.theme-thanksgiving1 .book-svc .slot { background: #fff8f1; border-color: #c07a4a; color: #43301c; box-shadow: 0 0 18px rgba(230, 120, 140, .45), inset 0 0 10px rgba(230, 120, 140, .12); }
body.theme-thanksgiving1 .book-svc .slot:has(input:checked) { background: #fdf6ea; border-color: #c2502e; color: #43301c; box-shadow: 0 0 32px rgba(230, 110, 140, .65), 0 0 10px rgba(240, 140, 160, .7), inset 0 0 14px rgba(230, 120, 140, .2); }
body.theme-thanksgiving1 .book-svc .slot:has(input:checked) .svc-medal { filter: drop-shadow(0 0 8px rgba(255, 120, 150, .95)); }
body.theme-thanksgiving1 .book-svc .slot { background: linear-gradient(180deg, #e9d5ae, #f3e3c2); border: 2.5px solid #e8a33d; color: #f7ead2; box-shadow: 0 0 18px rgba(255, 140, 30, .45), inset 0 0 12px rgba(255, 140, 30, .18); }
body.theme-thanksgiving1 .book-svc .slot:has(input:checked) { background: linear-gradient(180deg, #7a4a16, #e9d5ae); border: 3px solid #ffc44d; color: #fffaf0; box-shadow: 0 0 34px rgba(255, 150, 40, .75), 0 0 10px rgba(255, 180, 60, .8), inset 0 0 16px rgba(255, 160, 50, .3); }
body.theme-thanksgiving1 .book-svc .svc-medal { filter: none; }
body.theme-thanksgiving1 .book-svc .slot:has(input:checked) .svc-medal { width: 42px; height: 42px; filter: drop-shadow(0 0 10px rgba(255, 170, 50, 1)); }
body.pub.theme-thanksgiving1 { --paper: #fbf2df;
    --alt: #fffaf0;
    --surface: #fffaf0;
    --acc: #b07f2a;
    --acc-hi: #a05c14;
    --acc-text: #a05c14;
    --acc-soft: #c9a05e;
    --acc-tint: #f7ead2;
    --dots: #c9a05e;
    --line: #c9a05e;
    --hair: #e9d5ae;
    --ink-th: #43301c;
    --muted-th: #8a6a44;
    --btn-ink: #fbf2df;
    --header-bg: rgba(251, 242, 223, .94);
    --footer-bg: #f3e6cf;
    --panel: #fffaf0;
    --outline-bg: rgba(255, 250, 240, .92);
    --hero-ink: #43301c;
    --hero-sub: #8a6a44;
    --shade-a: rgba(251, 242, 223, .92);
    --shade-b: rgba(251, 242, 223, .8);
    --shade-c: rgba(251, 242, 223, .25);
    --hero-img: url("/images/thanksgiving1/hero.jpg"); }
body.pub.theme-thanksgiving1 a.hw-btn-book { color: #fff; }
body.pub.theme-thanksgiving1 a.hw-btn-search { color: #7a4a16; }
body.pub.theme-thanksgiving1 .site-header.hw-header { background: var(--hw-bg); border-bottom: 1px solid rgba(255, 196, 77, .35); }
body.pub.theme-thanksgiving1 .site-header.hw-header .site-nav { background: var(--hw-panel); }
body.pub.theme-thanksgiving1 .site-header.hw-header .site-nav a { color: #7a4a16; }
body.pub.theme-thanksgiving1 .site-header.hw-header .nav-toggle span { background: var(--hw-gold-bright); }
body.pub.theme-thanksgiving1 .btn-call { background: linear-gradient(180deg, #8a5a20, #f3e3c2); color: #ffffff; border-color: #ffc44d; }
body.pub.theme-thanksgiving1 .btn-book { background: linear-gradient(180deg, #f59a23, #e05f0c); color: #fff; border-color: #ffc44d; }
body.theme-thanksgiving1 .btn-call, body.pub.theme-thanksgiving1 .btn-call { background: linear-gradient(180deg, #f59a23, #e05f0c);
    color: #fff; font-weight: 700; border-color: transparent; }
body.theme-thanksgiving1 .btn-call:hover, body.pub.theme-thanksgiving1 .btn-call:hover { background: linear-gradient(180deg, #f59a23, #c94f08); color: #fff; }
body.theme-thanksgiving1 .ci-ok { background: linear-gradient(180deg, #f59a23, #e05f0c);
    color: #fff; box-shadow: 0 10px 22px rgba(224, 95, 12, .35); }
body.theme-thanksgiving1 .pp-pay { background: linear-gradient(180deg, #f59a23, #e05f0c); color: #fff; }
body.theme-thanksgiving1 .pp-pay:hover { background: linear-gradient(180deg, #f59a23, #c94f08); }
body.theme-thanksgiving1 .conf-btn-cal { background: linear-gradient(180deg, #f59a23, #e05f0c);
    border-color: transparent;
    box-shadow: 0 8px 20px rgba(224, 95, 12, .35); }
body.theme-thanksgiving1 .hw-btn-book { background: linear-gradient(180deg, #f59a23, #e05f0c); }
body.theme-thanksgiving1 .btn-outline, body.pub.theme-thanksgiving1 .btn-outline, body.theme-thanksgiving1 .btn.another-no { background: var(--hw-panel); border: 1.5px solid var(--hw-gold);
    color: #7a4a16; font-weight: 600; }
body.theme-thanksgiving1 .conf-btn.conf-btn-txt { background: var(--hw-panel); border-color: var(--hw-gold);
    color: #7a4a16; }
body.theme-thanksgiving1 .book-svc .slot:has(input:checked), body.theme-thanksgiving1 .time-grid .slot:has(input:checked) { background: linear-gradient(180deg, #f59a23, #e05f0c);
    border-color: #e08a1e; color: #fff;
    box-shadow: 0 0 0 3px rgba(245, 154, 35, .35), 0 6px 18px rgba(224, 95, 12, .45); }
body.theme-thanksgiving1 .tip-sec .tip-row .pill-btn.sel { background: linear-gradient(180deg, #f59a23, #e05f0c);
    color: #fff; border-color: #e08a1e;
    box-shadow: 0 0 0 2px rgba(101, 67, 33, .22), 0 0 0 4.5px var(--hw-gold), 0 8px 18px rgba(101, 67, 33, .28); }
body.theme-thanksgiving1 .pill-btn.sel { background: linear-gradient(180deg, #f59a23, #e05f0c);
    border-color: #e08a1e; color: #fff; }
body.theme-thanksgiving1 .cal-day.sel { background: linear-gradient(180deg, #f59a23, #e05f0c);
    color: #fff; font-weight: 700; }

/* Hand fixes over the mechanical twins (reviewed):
   three places where a literal played a dark role in
   Halloween and a light one in the map. */
body.theme-thanksgiving1 .book-grid .appt-card.card-odd, body.theme-thanksgiving1 .conf-who { color: #43301c; }
body.theme-thanksgiving1 .book-svc .slot:has(input:checked) { background: linear-gradient(180deg, #7a4a16, #5f3a10); }
/* --hw-cream text sat on dark panel2 under Halloween;
   panel2 is light here, so the text on it goes ink. */
body.theme-thanksgiving1 input, body.theme-thanksgiving1 select, body.theme-thanksgiving1 textarea, body.theme-thanksgiving1 .theme-sel, body.theme-thanksgiving1 .ci-phonebox, body.theme-thanksgiving1 .ci-textbox, body.theme-thanksgiving1 .ci-key, body.theme-thanksgiving1 .pin-input, body.theme-thanksgiving1 .conf-drow b, body.theme-thanksgiving1 .al-custname { color: var(--hw-ink); }
body.theme-thanksgiving1 .al-who.system { color: #e9d5ae; }
body.theme-thanksgiving1 .site-footer { color: #43301c; }
body.theme-thanksgiving1 .site-footer .rating, body.pub.theme-thanksgiving1 .site-footer .rating { color: #7a4a16; }
body.pub.theme-thanksgiving1 .site-footer .tagline { color: #8a6a44; }
body.pub.theme-thanksgiving1 .site-footer a { color: #7a4a16; }
body.pub.theme-thanksgiving1 .footer-bottom { color: #8a6a44; }
/* The page-top pills sit on the dark photo band in
   every theme (translucent near-black ground); their
   pale-gold text is the one place pale text stays —
   the generic map darkened it onto the dark pill. */
body.pub.theme-thanksgiving1 .page-top-pill { color: #f0d9a8; }

/* ════════════════════════════════════════════════════════════
   check276 (owner, Oct 31, 2026 — "Here is Thanksgiving 2,
   dark theme (Thanksgiving 1 was light theme)", sent as a
   filled-in copy of the theme spec sheet): THANKSGIVING 2
   — the owner's dark Thanksgiving design as a one-theme
   value beside Halloween and Thanksgiving 1 in
   UnifiedTheme. This section is the theme-halloween
   layer's structural twin: same slots, same layout rules.
   The palette is the sheet's own five codes, a HYBRID:
   #F6E9DC cream page frame, #3A1F14 dark-brown cards and
   surfaces with #E7D6BE light text on them, #C6672C
   burnt-orange accents, #5A1119 deep-red headings. It
   paints ONLY under body.theme-thanksgiving2, which the
   layout stamps only while the Check276 gate shows for
   the request (DEV sessions, or Features:Check276 "on")
   and Thanksgiving 2 is the book's one theme.
   ════════════════════════════════════════════════════════════ */
/* The --hw-* variables redefined on the body in the
   sheet's palette — :root carries Halloween's dark
   values, and every unscoped hw-* structural rule reads
   them from here. --hw-bg is the cream FRAME; --hw-panel
   is the dark card ground the light --hw-ink sits on. */
body.theme-thanksgiving2 {
    --hw-bg: #f6e9dc;
    --hw-panel: #3a1f14;
    --hw-panel2: #4a2a18;
    --hw-gold: #c6672c;
    --hw-gold-bright: #eda964;
    --hw-cream: #f6e9dc;
    --hw-ink: #e7d6be;
    --hw-muted: #bfa887;
    --hw-line: #8a5a34;
    --hw-maroon: #5a1119;
}
html:has(body.theme-thanksgiving2) { background: #f6e9dc; }

body.theme-thanksgiving2 .book-pin-corner, body.theme-thanksgiving2 .book-pin-day, body.theme-thanksgiving2 .book-pin-day.day-past { background:var(--hw-panel2); color:var(--hw-gold-bright); }
html:has(body.theme-thanksgiving2) { background: var(--hw-bg); }
body.theme-thanksgiving2 { background: var(--hw-bg);
    color: var(--hw-ink);
    font-family: var(--font-geo);
    color-scheme: dark;
    /* check236: the page-level overflow guard — nothing on
       a themed customer page may push past the viewport and
       hand the phone a horizontal scroll. `clip`, not
       `hidden`: it creates no scroll container, so the
       sticky header keeps sticking. */
    overflow-x: clip;
    --font-body: "Jost", "Inter", -apple-system, "Segoe UI", sans-serif;
    --charcoal: #e7d6be;
    --muted: #bfa887;
    --rose: #c6672c;
    --rose-dark: #eda964;
    --rose-deep: #c6672c;
    --rose-soft: #2e1a0e;
    --blush: #3a1f14;
    --shadow: 0 10px 30px rgba(46, 26, 12, .5); }
body.theme-thanksgiving2 h1 { font-family: var(--font-script); font-weight: 400; }
body.theme-thanksgiving2 h2 { font-family: var(--font-display); font-style: italic; }
body.theme-thanksgiving2 .btn, body.theme-thanksgiving2 button, body.theme-thanksgiving2 input, body.theme-thanksgiving2 select, body.theme-thanksgiving2 textarea, body.theme-thanksgiving2 label { font-family: var(--font-geo); }
body.theme-thanksgiving2 a { color: var(--hw-gold-bright); }
body.theme-thanksgiving2 .svc-panel { background: var(--hw-panel); border-color: var(--hw-gold); color: var(--hw-ink); }
body.theme-thanksgiving2 .svc-panel h2, body.theme-thanksgiving2 .svc-panel h3 { color: var(--hw-gold-bright); }
body.theme-thanksgiving2 .svc-item-desc { color: var(--hw-muted); }
body.theme-thanksgiving2 .site-footer { background: #2e1a0e; color: #e5cfa5; border-top: 1px solid var(--hw-gold); }
body.theme-thanksgiving2 .site-footer h3 { color: var(--hw-gold-bright); }
body.theme-thanksgiving2 .site-footer .tagline { color: var(--hw-muted); }
body.theme-thanksgiving2 .site-footer a { color: #f0d9a8; }
body.theme-thanksgiving2 .site-footer .rating { border-color: var(--hw-gold); color: var(--hw-cream); }
body.theme-thanksgiving2 .footer-bottom { border-top-color: #57351d; color: #d98a4a; }
body.theme-thanksgiving2 .step-card { background: var(--hw-panel); border: 1px solid var(--hw-gold); color: var(--hw-ink); }
body.theme-thanksgiving2 .step-n { background: var(--hw-maroon); border: 1px solid var(--hw-gold); color: var(--hw-cream); }
body.theme-thanksgiving2 .step-glyph { background: transparent; border-color: var(--hw-gold); }
body.theme-thanksgiving2 .step-glyph::before { content: "🎃"; font-size: 1.1rem; }
body.theme-thanksgiving2 .step-head .step-hint { color: var(--hw-muted); }
body.theme-thanksgiving2 .book-svc .slot, body.theme-thanksgiving2 .time-grid .slot { background: var(--hw-panel2); border-color: var(--hw-line); color: var(--hw-ink); border-radius: 18px; }
body.theme-thanksgiving2 .book-svc .slot:has(input:checked) { background: linear-gradient(180deg, #d98a4a, #d98a4a); border-color: #e8a33d; color: var(--hw-cream); }
@media (max-width: 640px) {
    body.theme-thanksgiving2 .book-svc .slot:has(input:checked), body.theme-thanksgiving2 .time-grid .slot:has(input:checked) { background: linear-gradient(180deg, #f59a23, #e05f0c);
        border-color: #ffb35c;
        color: #fff;
        box-shadow: 0 0 0 3px rgba(245, 154, 35, .35), 0 6px 18px rgba(224, 95, 12, .45); }
}
body.theme-thanksgiving2 .book-svc .slot::after { content: "›"; margin-left: auto; color: var(--hw-gold-bright); font-size: 1.35rem; line-height: 1; }
body.theme-thanksgiving2 .date-display { background: linear-gradient(180deg, #5a1119, var(--hw-maroon)); color: var(--hw-cream); border: 1px solid var(--hw-gold); box-shadow: 0 4px 14px rgba(46, 26, 12, .42); }
body.theme-thanksgiving2 .date-display:hover { background: var(--hw-maroon); }
body.theme-thanksgiving2 .cal-pop { background: var(--hw-panel); border-color: var(--hw-gold); color: var(--hw-ink); }
body.theme-thanksgiving2 .cal-nav { background: var(--hw-panel2); color: var(--hw-gold-bright); border-color: var(--hw-line); }
body.theme-thanksgiving2 .btn-call { background: linear-gradient(180deg, #f59a23, #e05f0c); color: #fff; border-color: transparent; }
body.theme-thanksgiving2 .btn-call:hover { background: linear-gradient(180deg, #f59a23, #c94f08); color: #fff; }
body.theme-thanksgiving2 .btn-book { background: linear-gradient(180deg, #f59a23, #e05f0c); color: #fff; border-color: transparent; }
body.theme-thanksgiving2 .btn-outline { background: transparent; border-color: var(--hw-gold); color: var(--hw-gold-bright); }
body.theme-thanksgiving2 .contact-block { background: var(--hw-panel); border: 1px solid var(--hw-gold); border-radius: 18px; padding: 24px 22px; color: var(--hw-ink); }
body.theme-thanksgiving2 .contact-block h2, body.theme-thanksgiving2 .contact-block h3 { color: var(--hw-gold-bright); }
body.theme-thanksgiving2 .picked-summary, body.theme-thanksgiving2 .bill-frame { background: var(--hw-panel); border-color: var(--hw-line); color: var(--hw-ink); }
body.theme-thanksgiving2 input, body.theme-thanksgiving2 select, body.theme-thanksgiving2 textarea { background: var(--hw-panel2); border-color: var(--hw-line); color: var(--hw-cream); }
body.theme-thanksgiving2 .form-card, body.theme-thanksgiving2 .qe-card { background: var(--hw-panel); border-color: var(--hw-line); color: var(--hw-ink); }
body.theme-thanksgiving2 .notice { background: #2e1a0e; border-color: var(--hw-line); color: var(--hw-ink); }
body.theme-thanksgiving2 .notice.error { background: #5a1119; border-color: #d4694e; color: #f3e3c2; }
body.theme-thanksgiving2 .theme-sel { background: var(--hw-panel2); color: var(--hw-cream); border: 1.5px solid var(--hw-line); border-radius: 8px; padding: 6px 8px; }
body.theme-thanksgiving2 .book-grid { background: var(--hw-panel); border-color: var(--hw-line); color: var(--hw-ink); }
body.theme-thanksgiving2 .book-grid th, body.theme-thanksgiving2 .book-grid td { border-color: #57351d; }
body.theme-thanksgiving2 .book-grid td.has-area { background: var(--hw-panel2); }
body.theme-thanksgiving2 .appt-card { background: #2e1a0e; border-color: var(--hw-line); color: var(--hw-ink); }
body.theme-thanksgiving2 .book-empty, body.theme-thanksgiving2 .book-closed, body.theme-thanksgiving2 .book-blocked { color: var(--hw-muted); }
body.theme-thanksgiving2 .cust-tabs a { background: var(--hw-panel2); border-color: var(--hw-gold); color: var(--hw-gold-bright); }
body.theme-thanksgiving2 .pick-row, body.theme-thanksgiving2 .slot-check, body.theme-thanksgiving2 .custom-time, body.theme-thanksgiving2 .qe-pick-btn, body.theme-thanksgiving2 .cal-pop { background: var(--hw-panel); color: var(--hw-ink); }
body.theme-thanksgiving2 .view-pill3 { background: var(--hw-panel); border-color: var(--hw-gold); }
body.theme-thanksgiving2 .vp3-seg { color: var(--hw-gold-bright); }
body.theme-thanksgiving2 .ci-wrap { background: var(--hw-bg); color: var(--hw-ink); }
body.theme-thanksgiving2 .ci-band { background: var(--hw-panel); border-bottom: 1px solid var(--hw-gold); }
body.theme-thanksgiving2 .ci-brand { color: var(--hw-gold-bright); }
body.theme-thanksgiving2 .ci-phonebox, body.theme-thanksgiving2 .ci-textbox { background: var(--hw-panel2); border-color: var(--hw-gold); color: var(--hw-cream); }
body.theme-thanksgiving2 .ci-key { background: var(--hw-panel2); color: var(--hw-cream); border-color: var(--hw-line); }
body.theme-thanksgiving2 .pin-input { background: var(--hw-panel2); border-color: var(--hw-gold); color: var(--hw-cream); }
body.theme-thanksgiving2 .site-header.hw-header nav.site-nav { background: var(--hw-panel); }
body.theme-thanksgiving2 .admin-banner { background: linear-gradient(135deg, #f6e9dc 0%, #2e1a0e 55%, #d98a4a 100%); border-bottom: 2px solid var(--hw-gold); }
body.theme-thanksgiving2 .admin-banner .ab-name { color: #f6e9dc; }
body.theme-thanksgiving2 .admin-banner .ab-sub { color: #ffc98a; }
body.theme-thanksgiving2 .admin-banner .ab-date { color: #e7d6be; }
body.theme-thanksgiving2 .admin-banner .ab-dow { color: #ffc98a; }
body.theme-thanksgiving2 .book-theme-row .theme-opt { background: var(--hw-panel2); color: var(--hw-ink); border-color: var(--hw-line); }
body.theme-thanksgiving2 .book-theme-row .theme-opt:hover { border-color: var(--hw-gold); }
body.theme-thanksgiving2 .book-theme-row .theme-opt.active { background: var(--hw-maroon); color: var(--hw-cream); border-color: var(--hw-gold); box-shadow: inset 0 0 0 1px var(--hw-gold); }
body.theme-thanksgiving2 .visit-pill-total { background: var(--hw-panel2); color: var(--hw-gold-bright); border-color: var(--hw-gold); }
body.theme-thanksgiving2 .visit-pill-today { background: var(--hw-maroon); color: var(--hw-cream); }
body.theme-thanksgiving2 .ab-date, body.theme-thanksgiving2 .book-grid td, body.theme-thanksgiving2 .book-grid th { color: var(--hw-ink); }
body.theme-thanksgiving2 .page-top-pill { background: rgba(46, 26, 12, .88); border-color: var(--hw-gold); color: #f0d9a8; }
body.theme-thanksgiving2 .page-top-pill.is-active { background: linear-gradient(180deg, #f59a23, #e05f0c); border-color: #ffb35c; color: #fff; }
body.theme-thanksgiving2 .book-grid thead th { background: var(--hw-panel2); color: var(--hw-gold-bright); }
body.theme-thanksgiving2 .book-grid .book-closed { background: #4a2a18; color: var(--hw-muted); }
body.theme-thanksgiving2 .book-grid td.book-appt-customer { background: #57351d; }
body.theme-thanksgiving2 .book-grid td.book-appt-customer a { color: #ffc98a; }
body.theme-thanksgiving2 .booking-alert .ba-ack { background: #2a0f0c; color: #fff; }
body.theme-thanksgiving2 .pill-btn { background: var(--hw-panel2); color: var(--hw-ink); border-color: var(--hw-line); }
body.theme-thanksgiving2 .pill-btn.time-btn.taken, body.theme-thanksgiving2 .pill-btn.time-btn.blocked, body.theme-thanksgiving2 .pill-btn.status-btn:disabled { background: #4a2a18; border-color: var(--hw-line); color: var(--hw-muted); }
body.theme-thanksgiving2 .tip-sec .tip-row .pill-btn { background: var(--hw-panel2); color: var(--hw-gold-bright); border-color: var(--hw-gold); }
body.theme-thanksgiving2 .tip-sec .tip-row .pill-btn .tip-amt { color: var(--hw-muted); }
body.theme-thanksgiving2 .tip-sec .tip-row .pill-btn.sel { background: linear-gradient(160deg, #5a1119, var(--hw-maroon)); color: #fff; border-color: var(--hw-gold); box-shadow: 0 0 0 2px rgba(0,0,0,.4), 0 0 0 4.5px var(--hw-gold), 0 8px 18px rgba(46, 26, 12, .5); }
body.theme-thanksgiving2 .tip-sec .tip-row .pill-btn.sel .tip-amt { color: #f3e3c2; }
body.theme-thanksgiving2 .textset .tstile { background: var(--hw-panel); border-color: var(--hw-line); }
body.theme-thanksgiving2 .textset .tstile .ts-lb, body.theme-thanksgiving2 .textset .tstile .ts-lb a { color: var(--hw-gold-bright); }
body.theme-thanksgiving2 .ci-emblem { background: var(--hw-panel2); color: var(--hw-gold-bright); }
body.theme-thanksgiving2 .conf-card { background: var(--hw-panel); border-color: var(--hw-line); color: var(--hw-ink); box-shadow: 0 18px 44px rgba(46, 26, 12, .5); }
body.theme-thanksgiving2 .conf-photo::after { background: linear-gradient(to bottom, rgba(23, 12, 7, 0), var(--hw-panel)); }
body.theme-thanksgiving2 .conf-btn-txt { background: var(--hw-panel2); }
body.theme-thanksgiving2 .textset .icx { background: var(--hw-panel2); color: var(--hw-gold-bright); }
body.theme-thanksgiving2 .note-list .nvt-btn { background: var(--hw-panel2); color: var(--hw-gold-bright); border-color: var(--hw-gold); }
body.theme-thanksgiving2 .note-list .nvt-btn.is-on { background: var(--hw-maroon); color: var(--hw-cream); }
body.theme-thanksgiving2 .note-pen { background: var(--hw-panel2); border-color: var(--hw-gold); color: var(--hw-gold-bright); }
body.theme-thanksgiving2 .textset .ic-g { color: #7aa7f0; }
body.theme-thanksgiving2 .book-grid .book-time, body.theme-thanksgiving2 .book-grid .book-time-head { background: var(--hw-panel2); color: var(--hw-gold-bright); }
body.theme-thanksgiving2 .book-admin-actions .tool-link { color: var(--hw-gold-bright); border-color: var(--hw-line); }
body.theme-thanksgiving2 .conf-details { background: var(--hw-panel2); border-color: var(--hw-gold); color: var(--hw-ink); }
body.theme-thanksgiving2 .conf-ic { background: #57351d; }
body.theme-thanksgiving2 .conf-svc { color: var(--hw-gold-bright); }
body.theme-thanksgiving2 .dep-terms { background: #2e1a0e; border-color: var(--hw-line); color: var(--hw-ink); }
body.theme-thanksgiving2 .conf-btn.conf-btn-txt { color: #f0d9a8; }
body.theme-thanksgiving2 .rstr-tag { background: #67161f; border-color: #c6672c; color: #eab49a; }
body.theme-thanksgiving2 .paid-stamp { background: rgba(20, 10, 6, .55); color: #7ed492; border-color: #7ed492; }
body.theme-thanksgiving2 .book-grid td.cell-free.day-past, body.theme-thanksgiving2 .book-grid td.book-empty.day-past { background: #4a2a18; }
body.theme-thanksgiving2 .book-grid td.cell-free.day-past a { background: transparent; }
body.theme-thanksgiving2 .book-grid td.day-past, body.theme-thanksgiving2 .book-grid th.day-past, body.theme-thanksgiving2 .book-grid td.has-area.day-past { background: #4a2a18; }
body.theme-thanksgiving2 .book-grid td.day-past .appt-card { background: var(--hw-panel2); }
body.theme-thanksgiving2 .book-grid td.book-appt-customer.day-past { background: #57351d; }
body.theme-thanksgiving2 .book-grid td.book-appt-customer.day-past a { color: #ffc98a; }
body.theme-thanksgiving2 .al-top { background: var(--hw-bg); }
body.theme-thanksgiving2 .al-h1, body.theme-thanksgiving2 .al-titlelink, body.theme-thanksgiving2 .al-titlelink .al-backarr { color: var(--hw-gold-bright); }
body.theme-thanksgiving2 .al-pill { background: var(--hw-panel2); border-color: var(--hw-gold); color: var(--hw-gold-bright); }
body.theme-thanksgiving2 .al-pill.on { background: var(--hw-maroon); border-color: var(--hw-gold); color: var(--hw-cream); }
body.theme-thanksgiving2 .al-entry { background: var(--hw-panel); border-color: var(--hw-line); color: var(--hw-ink); box-shadow: 0 1px 3px rgba(46, 26, 12, .38); }
body.theme-thanksgiving2 .al-custname { color: var(--hw-cream); }
body.theme-thanksgiving2 .al-custphone, body.theme-thanksgiving2 .al-daylabel, body.theme-thanksgiving2 .al-when, body.theme-thanksgiving2 .al-meta { color: var(--hw-muted); }
body.theme-thanksgiving2 .al-what { color: var(--hw-ink); }
body.theme-thanksgiving2 .al-detail { color: #d9c4a5; }
body.theme-thanksgiving2 .al-chev { color: var(--hw-gold-bright); }
body.theme-thanksgiving2 .al-who.customer { background: #17364d; color: #8fc3f5; }
body.theme-thanksgiving2 .al-who.admin { background: #67161f; color: #eab49a; }
body.theme-thanksgiving2 .al-who.system { background: #2e1a0e; color: #c4b096; }
body.theme-thanksgiving2 .si-card { background: var(--hw-panel); border-color: var(--hw-line); color: var(--hw-ink); box-shadow: 0 1px 3px rgba(46, 26, 12, .38); }
body.theme-thanksgiving2 .si-empty { background: var(--hw-panel); border-color: var(--hw-line); color: var(--hw-muted); }
body.theme-thanksgiving2 .si-row { border-bottom-color: var(--hw-line); }
body.theme-thanksgiving2 .si-time { background: var(--hw-panel2); border-color: var(--hw-line); }
body.theme-thanksgiving2 .si-time b { color: var(--hw-gold-bright); }
body.theme-thanksgiving2 .si-time span { color: var(--hw-muted); }
body.theme-thanksgiving2 .si-svc { color: #d9c4a5; }
body.theme-thanksgiving2 .si-ph, body.theme-thanksgiving2 .si-sub, body.theme-thanksgiving2 .si-chev { color: var(--hw-muted); }
body.theme-thanksgiving2 .si-tag-new, body.theme-thanksgiving2 .si-st-wait { background: #57351d; color: #ffc98a; border-color: var(--hw-line); }
body.theme-thanksgiving2 .si-st-appt { background: #173d24; color: #8fd3a5; }
body.theme-thanksgiving2 .si-st-dismissed { background: #2e1a0e; color: #c4b096; }
body.theme-thanksgiving2 .sync-card { background: var(--hw-panel); color: var(--hw-ink); box-shadow: 0 18px 42px rgba(46, 26, 12, .5); }
body.theme-thanksgiving2 .sync-divider { background: var(--hw-line); }
body.theme-thanksgiving2 .sync-row { border-bottom-color: var(--hw-line); }
body.theme-thanksgiving2 .sync-row span { color: var(--hw-muted); }
body.theme-thanksgiving2 .sync-btn-pw { background: var(--hw-panel2); }
body.theme-thanksgiving2 .sync-setup-url { color: var(--hw-muted); }
body.theme-thanksgiving2 .sync-rules li { color: var(--hw-ink); }
body.theme-thanksgiving2 .btn-gold { background: var(--hw-panel2); color: var(--hw-gold-bright); }
body.theme-thanksgiving2 .btn-gold:hover { background: var(--hw-panel); }
body.theme-thanksgiving2 .pay-disc-btn { background: var(--hw-panel2); color: var(--hw-gold-bright); }
body.theme-thanksgiving2 .pay-remove { background: var(--hw-panel2); border-color: var(--hw-line); color: #eab49a; }
body.theme-thanksgiving2 .pay-additem { background: var(--hw-panel2); border-color: var(--hw-gold); color: var(--hw-gold-bright); }
body.theme-thanksgiving2 .btn-mini { background: var(--hw-panel2); }
body.theme-thanksgiving2 .btn-mini.danger:hover { background: #5a1119; }
body.theme-thanksgiving2 .bill-stamp { background: rgba(20, 10, 6, .6); }
body.theme-thanksgiving2 .bill-stamp-due { color: #d9b98c; border-color: #d98a4a; }
body.theme-thanksgiving2 .bill-stamp-paid { color: #7ed492; border-color: #7ed492; }
body.theme-thanksgiving2 .bill-frame { box-shadow: 0 18px 50px rgba(46, 26, 12, .5), inset 0 0 0 5px var(--hw-panel), inset 0 0 0 6.5px var(--gold); }
body.theme-thanksgiving2 .admin-banner .ab-logo { background: transparent; }
body.theme-thanksgiving2 .env-slider257 { background: #4a2a18; border-color: #cbb096; }
body.theme-thanksgiving2 .env-lab257 { color: #bfa887; }
body.theme-thanksgiving2 .env-knob257 { background: var(--hw-maroon); color: var(--hw-cream); box-shadow: 0 2px 6px rgba(46, 26, 12, .5); }
body.theme-thanksgiving2 .switcher257.env-dev .env-knob257 { background: #4a2a18; color: #f2c14e; }
body.theme-thanksgiving2 .view-pill3 { background: #4a2a18; border-color: #cbb096; }
body.theme-thanksgiving2 .vp3-seg { color: #bfa887; }
body.theme-thanksgiving2 .vp3-seg.on { background: var(--hw-maroon); color: var(--hw-cream); }
body.theme-thanksgiving2 .switcher257.env-dev .vp3-seg.on { background: #4a2a18; color: #f2c14e; }
body.theme-thanksgiving2 .book-grid .appt-card.card-customer { background: #57351d; color: var(--hw-ink); }
body.theme-thanksgiving2 .book-grid .appt-card.card-odd { background: #57351d; color: #fff3e0; }
body.theme-thanksgiving2 .book-grid .appt-card.card-deposit { background: #d98a4a; color: var(--hw-ink); }
body.theme-thanksgiving2 .book-grid td.book-appt-customer a.appt-card:not(.card-customer):not(.card-noshow) { color: var(--hw-ink); }
body.theme-thanksgiving2 .book-grid .appt-card.card-noshow { background: #2e1a0e; color: #cbb49e; }
body.theme-thanksgiving2 .p-note, body.theme-thanksgiving2 .book-grid .appt-card .p-note { color: #eda964; }
body.theme-thanksgiving2 .book-grid .appt-card.card-discount .p-note { color: #fbf0dd; }
body.theme-thanksgiving2 .book-grid .appt-card .act-chk-grey { color: #e0aa60; }
body.theme-thanksgiving2 .book-grid .appt-card .act-chk-blue { color: #7db8f0; }
body.theme-thanksgiving2 .late-label { color: var(--hw-gold-bright); }
body.theme-thanksgiving2 input::placeholder, body.theme-thanksgiving2 textarea::placeholder { color: #e0aa60; opacity: 1; }
body.theme-thanksgiving2 .qe-what, body.theme-thanksgiving2 .qe-more { color: #eda964; }
body.theme-thanksgiving2 .qe-problem { background: #5a1119; border-color: #c6672c; color: #f3e3c2; }
body.theme-thanksgiving2 .conf-card { background: linear-gradient(180deg, #8a5a20, #57351d); border: 4px solid #ffc44d; box-shadow: 0 0 0 6px rgba(255, 180, 60, .25), 0 0 55px rgba(255, 150, 40, .65), 0 0 110px rgba(255, 120, 20, .35), inset 0 0 34px rgba(255, 170, 60, .18); }
body.theme-thanksgiving2 .conf-col:has(> .conf-card) { position: relative; z-index: 0; }
body.theme-thanksgiving2 .conf-col:has(> .conf-card)::before { content: ""; position: absolute; inset: -46px -14px; background: radial-gradient(ellipse at 50% 42%, rgba(255, 150, 40, .35), rgba(255, 150, 40, 0) 65%); z-index: -1; pointer-events: none; }
body.theme-thanksgiving2 .conf-details { background: #57351d; }
body.theme-thanksgiving2 .conf-photo::after { background: linear-gradient(to bottom, rgba(71, 42, 16, 0), #57351d); }
body.theme-thanksgiving2 .conf-who { color: #fff8ec; }
body.theme-thanksgiving2 .conf-svc { color: #ffc98a; font-weight: 700; }
body.theme-thanksgiving2 .conf-drow b { color: var(--hw-cream); }
body.theme-thanksgiving2 .conf-drow b.conf-date, body.theme-thanksgiving2 .conf-drow b:not(.conf-date):not(.conf-addr) { font-size: 26px; font-weight: 800; color: #ffffff; }
body.theme-thanksgiving2 .conf-drow b.conf-addr { color: #fff3e0; }
body.theme-thanksgiving2 .conf-ic { background: #e08a4c; border: 2px solid #ffc44d; }
body.theme-thanksgiving2 .conf-ic svg { stroke: #ffc98a; }
body.theme-thanksgiving2 .conf-badge { filter: drop-shadow(0 0 6px rgba(53, 199, 89, .8)); }
body.theme-thanksgiving2 .conf-phone a { color: #ffc98a; font-weight: 800; }
body.theme-thanksgiving2 .conf-salonname { color: var(--hw-gold-bright); }
body.theme-thanksgiving2 .conf-btn-note { color: #e0aa60; }
body.theme-thanksgiving2 .hw-btn-book { background: #bc5406; color: #ffffff; font-weight: 700; box-shadow: 0 6px 18px rgba(46, 26, 12, .42); }
body.theme-thanksgiving2 .hw-btn-search { background: #3a1f14; border: 2px solid var(--hw-gold); color: #f0d9a8; font-weight: 700; }
body.theme-thanksgiving2 .book-svc .slot { background: #fff8f1; border-color: #e0a184; color: #e7d6be; box-shadow: 0 0 18px rgba(230, 120, 140, .45), inset 0 0 10px rgba(230, 120, 140, .12); }
body.theme-thanksgiving2 .book-svc .slot:has(input:checked) { background: #fbf0dd; border-color: #d4694e; color: #2e1a0e; box-shadow: 0 0 32px rgba(230, 110, 140, .65), 0 0 10px rgba(240, 140, 160, .7), inset 0 0 14px rgba(230, 120, 140, .2); }
body.theme-thanksgiving2 .book-svc .slot:has(input:checked) .svc-medal { filter: drop-shadow(0 0 8px rgba(255, 120, 150, .95)); }
body.theme-thanksgiving2 .book-svc .slot { background: linear-gradient(180deg, #57351d, #2e1a0e); border: 2.5px solid #e8a33d; color: #f3e3c2; box-shadow: 0 0 18px rgba(255, 140, 30, .45), inset 0 0 12px rgba(255, 140, 30, .18); }
body.theme-thanksgiving2 .book-svc .slot:has(input:checked) { background: linear-gradient(180deg, #d98a4a, #57351d); border: 3px solid #ffc44d; color: #f6e9dc; box-shadow: 0 0 34px rgba(255, 150, 40, .75), 0 0 10px rgba(255, 180, 60, .8), inset 0 0 16px rgba(255, 160, 50, .3); }
body.theme-thanksgiving2 .book-svc .svc-medal { filter: none; }
body.theme-thanksgiving2 .book-svc .slot:has(input:checked) .svc-medal { width: 42px; height: 42px; filter: drop-shadow(0 0 10px rgba(255, 170, 50, 1)); }
body.pub.theme-thanksgiving2 { --paper: #f6e9dc;
    --alt: #3a1f14;
    --surface: #3a1f14;
    --acc: #c6672c;
    --acc-hi: #eda964;
    --acc-text: #eda964;
    --acc-soft: #8a5a34;
    --acc-tint: #4a2a18;
    --dots: #8a5a34;
    --line: #8a5a34;
    --hair: #57351d;
    --ink-th: #e7d6be;
    --muted-th: #bfa887;
    --btn-ink: #f6e9dc;
    --header-bg: rgba(46, 26, 12, .94);
    --footer-bg: #2e1a0e;
    --panel: #3a1f14;
    --outline-bg: rgba(46, 26, 12, .88);
    --hero-ink: #f6e9dc;
    --hero-sub: #bfa887;
    --shade-a: rgba(46, 26, 12, .95);
    --shade-b: rgba(46, 26, 12, .84);
    --shade-c: rgba(46, 26, 12, .28);
    --hero-img: url("/images/thanksgiving2/hero.jpg"); }
body.pub.theme-thanksgiving2 a.hw-btn-book { color: #fff; }
body.pub.theme-thanksgiving2 a.hw-btn-search { color: #f0d9a8; }
body.pub.theme-thanksgiving2 .site-header.hw-header { background: var(--hw-bg); border-bottom: 1px solid rgba(255, 196, 77, .35); }
body.pub.theme-thanksgiving2 .site-header.hw-header .site-nav { background: var(--hw-panel); }
body.pub.theme-thanksgiving2 .site-header.hw-header .site-nav a { color: #eda964; }
body.pub.theme-thanksgiving2 .site-header.hw-header .nav-toggle span { background: var(--hw-gold-bright); }
body.pub.theme-thanksgiving2 .btn-call { background: linear-gradient(180deg, #8a5a20, #57351d); color: #fff3e0; border-color: #ffc44d; }
body.pub.theme-thanksgiving2 .btn-book { background: linear-gradient(180deg, #f59a23, #e05f0c); color: #fff; border-color: #ffc44d; }
body.theme-thanksgiving2 .btn-call, body.pub.theme-thanksgiving2 .btn-call { background: linear-gradient(180deg, #f59a23, #e05f0c);
    color: #fff; font-weight: 700; border-color: transparent; }
body.theme-thanksgiving2 .btn-call:hover, body.pub.theme-thanksgiving2 .btn-call:hover { background: linear-gradient(180deg, #f59a23, #c94f08); color: #fff; }
body.theme-thanksgiving2 .ci-ok { background: linear-gradient(180deg, #f59a23, #e05f0c);
    color: #fff; box-shadow: 0 10px 22px rgba(224, 95, 12, .35); }
body.theme-thanksgiving2 .pp-pay { background: linear-gradient(180deg, #f59a23, #e05f0c); color: #fff; }
body.theme-thanksgiving2 .pp-pay:hover { background: linear-gradient(180deg, #f59a23, #c94f08); }
body.theme-thanksgiving2 .conf-btn-cal { background: linear-gradient(180deg, #f59a23, #e05f0c);
    border-color: transparent;
    box-shadow: 0 8px 20px rgba(224, 95, 12, .35); }
body.theme-thanksgiving2 .hw-btn-book { background: linear-gradient(180deg, #f59a23, #e05f0c); }
body.theme-thanksgiving2 .btn-outline, body.pub.theme-thanksgiving2 .btn-outline, body.theme-thanksgiving2 .btn.another-no { background: var(--hw-panel); border: 1.5px solid var(--hw-gold);
    color: #f0d9a8; font-weight: 600; }
body.theme-thanksgiving2 .conf-btn.conf-btn-txt { background: var(--hw-panel); border-color: var(--hw-gold);
    color: #f0d9a8; }
body.theme-thanksgiving2 .book-svc .slot:has(input:checked), body.theme-thanksgiving2 .time-grid .slot:has(input:checked) { background: linear-gradient(180deg, #f59a23, #e05f0c);
    border-color: #ffb35c; color: #fff;
    box-shadow: 0 0 0 3px rgba(245, 154, 35, .35), 0 6px 18px rgba(224, 95, 12, .45); }
body.theme-thanksgiving2 .tip-sec .tip-row .pill-btn.sel { background: linear-gradient(180deg, #f59a23, #e05f0c);
    color: #fff; border-color: #ffb35c;
    box-shadow: 0 0 0 2px rgba(46, 26, 12, .38), 0 0 0 4.5px var(--hw-gold), 0 8px 18px rgba(46, 26, 12, .5); }
body.theme-thanksgiving2 .pill-btn.sel { background: linear-gradient(180deg, #f59a23, #e05f0c);
    border-color: #ffb35c; color: #fff; }
body.theme-thanksgiving2 .cal-day.sel { background: linear-gradient(180deg, #f59a23, #e05f0c);
    color: #fff; font-weight: 700; }

/* Hand fixes for the hybrid palette are appended
   after this section by the screenshot-review pass
   (see diag/check276/PROOF.md). */

/* ---------- check276 hand fixes (screenshot review) --
   Text that sits on the CREAM FRAME takes frame colors:
   deep-red headings (#5A1119, the sheet's heading code),
   deep warm brown body text, and a darker rust for the
   small links the twins left pale. Text inside the dark
   cards keeps the light palette above. */
body.theme-thanksgiving2 .visit-grid address { color: #43301c; }
body.theme-thanksgiving2 .visit-grid h2 { color: #5a1119; }
body.theme-thanksgiving2 .visit-grid .hours-list li { color: #43301c; border-bottom-color: rgba(90, 17, 25, .25); }
body.theme-thanksgiving2 .visit-grid .rating { color: #a34d1d !important; border-color: #c6672c !important; }
body.pub.theme-thanksgiving2 .insta-link { color: #a34d1d; }
body.pub.theme-thanksgiving2 .lead, body.pub.theme-thanksgiving2 .video-card p { color: #7a5a38; }
body.theme-thanksgiving2 .pin-wrap h1 { color: #5a1119; }

/* ---------- check279: ONE selected format — the
   time pill's orange (owner, Nov 1, 2026, 12:43 AM —
   "Different selection format"; his pick: ORANGE
   everywhere) ----------
   Behind the gate (the layout's body.f279 marker,
   the check263 f-class mechanism), every pick-pill
   group the shared components render — the service
   pills (.book-svc) and the time pills (.time-grid)
   of _BookingSteps, in the booking form AND the
   confirmation component's change form, plus the
   shared date pick's selected day (.cal-day.sel) —
   takes ONE selected treatment per theme: that
   theme's own time-pill selected treatment.
   Halloween, Thanksgiving 1 and Thanksgiving 2
   already select their time pills with the orange
   gradient below, so their service pills are
   brought to it (Thanksgiving 1's dark-brown
   selected service pill was the owner's screenshot).
   The default Rose base and Dusty Rose select
   their time pills with the shared selection
   yellow instead, so they take the canonical
   orange — Thanksgiving 1's time-selected
   treatment (gradient + #e08a1e border + white
   text + the orange halo) — exactly as the owner
   picked it. Selected states only: unselected
   pills keep their look, and with the gate off
   (no body.f279) every rule here is inert. */
body.f279 .book-svc .slot:has(input:checked),
body.f279 .time-grid .slot:has(input:checked) {
    background: linear-gradient(180deg, #f59a23, #e05f0c);
    border-color: #e08a1e; color: #fff;
    box-shadow: 0 0 0 3px rgba(245, 154, 35, .35), 0 6px 18px rgba(224, 95, 12, .45);
}
body.f279.theme-halloween .book-svc .slot:has(input:checked),
body.f279.theme-halloween .time-grid .slot:has(input:checked),
body.f279.theme-thanksgiving2 .book-svc .slot:has(input:checked),
body.f279.theme-thanksgiving2 .time-grid .slot:has(input:checked) {
    border-color: #ffb35c;
}
body.f279 .cal-day.sel {
    background: linear-gradient(180deg, #f59a23, #e05f0c);
    color: #fff; font-weight: 700;
}

/* ---------- check280: bigger service-pill letters
   (owner, Nov 1, 2026 — "Letters are too small",
   with a Thanksgiving 1 /Book screenshot) ----------
   Behind the gate (the layout's body.f280 marker,
   the check263 f-class mechanism), the service
   name on the shared service pills (.book-svc
   .svc-name — the ONE _ServicePills component,
   rendered by the booking form's Step 1 and by
   the confirmation component's change form) takes
   1.125rem (18px) instead of .875rem (14px).
   Size only: colors, the check279 orange selected
   format, the medallion, the layout and the
   nowrap are untouched. CheckIn and the admin
   SignIn render the component inside .ci-pills,
   whose own larger sizes (1.18rem, 1.3rem at
   700px+) are re-asserted below so they do not
   move. With the gate off (no body.f280) every
   rule here is inert. */
body.f280 .book-svc .svc-name {
    font-size: 1.125rem;
}
body.f280 .ci-pills .book-svc .svc-name {
    font-size: 1.18rem;
}
@media (min-width: 700px) {
    body.f280 .ci-pills .book-svc .svc-name {
        font-size: 1.3rem;
    }
}

/* ============================================================
   check291 — the ONE page banner, unified layout.
   .page-top-u reuses the standing .page-top band (photo,
   bottom veil, pills) and changes ONLY the layout: the
   letters (.pt-letters: eyebrow, script title, gold rule)
   anchor to the TOP of the band and the two buttons stay
   along the BOTTOM (space-between). Appended only — no
   earlier rule is touched, so gate-off pages render from
   the exact check290 bytes above.
   ============================================================ */
.page-top-u { justify-content: space-between; }
.page-top-u .pt-letters { position: relative; z-index: 2; }

/* Home variant: the owner's autumn artwork as the band's
   background, with the bronze letter treatment (the cream
   art cannot carry the white letters) and the screenshot's
   button pair — dark Book, orange Search. The body prefix
   out-specifies the standing theme pill rules. */
.page-top-home {
    background: url("/images/welcome-autumn.png") center / cover no-repeat;
}
.page-top-home::after {
    background: linear-gradient(180deg, rgba(255, 248, 235, 0) 55%, rgba(122, 72, 20, .28));
}
body .page-top-home .page-top-kicker {
    color: #8a5a1e;
    text-shadow: 0 1px 0 rgba(255, 252, 240, .85), 0 0 10px rgba(255, 250, 235, .7);
}
body .page-top-home .page-top-title {
    color: #9a4a1f;
    text-shadow: 0 1px 0 rgba(255, 252, 240, .9), 0 0 14px rgba(255, 250, 235, .75);
}
body .page-top-home .page-top-pill {
    background: #2a1409;
    border-color: #2a1409;
    color: #f0d9a8;
}
body .page-top-home .page-top-pill + .page-top-pill {
    background: linear-gradient(180deg, #f59a23, #e05f0c);
    border-color: #d97a16;
    color: #fff;
}

/* ============================================================
   check300 — the bill's easy-read colors + the sample's
   order (owner, Nov 2, 2026 — "Build as shown. Keep our
   art work", approving mockups/check300-bill-colors.html).
   Appended only — no earlier rule is touched.
   ============================================================
   Behind the gate (the layout's body.f300 marker), the ONE
   shared bill component (.bill — Pages/Shared/_Bill.cshtml)
   wears the sample's palette, and its parts stand in the
   sample's ORDER: service lines → the "Add a tip" tiles →
   the totals panel → the Scan to Pay QR. The order is
   VISUAL only: the frame becomes a flex column and its
   children take flex orders — the markup (and with it
   every id the /Pay tip script wires) is untouched, and
   the artwork (the emblem, the blossom branch, the
   sprigs, every image) renders exactly as before. Only
   colors move. The tip rules key off .tip-sec generally,
   so the /Pay standalone card's picker (the same shared
   treatment) takes the same colors. With the gate off
   (no body.f300) every rule here is inert and every bill
   surface renders byte-identically to check299. */
body.f300 .bill .bill-frame {
    background: #FFF9EC;
    border-color: #C79A3B;
    box-shadow: 0 18px 50px rgba(150,85,95,.22),
        inset 0 0 0 5px #FFF9EC, inset 0 0 0 6.5px #C79A3B;
    display: flex;
    flex-direction: column;
}
/* the ESTIMATE title (check290): the one unclassed div
   directly after the emblem. Its bronze is inline-styled
   rose today, so the sample's deep bronze needs the
   !important. A paid bill renders no such div — the
   thanks line that sits there carries its class and is
   never matched. */
body.f300 .bill .bill-emblem + div:not([class]), body.f300 .bill-est377 {
    color: #7A5410 !important;
}
body.f300 .bill-thanks { color: #3A2410; }
body.f300 .bill-div-line { background: #D9B96A; }
body.f300 .bill-items { order: 10; }
body.f300 .bill-item { color: #241708; }
body.f300 .bill-extra { color: #5C4520; }
body.f300 .tip-sec.bill-tip-sec { order: 20; }
body.f300 .bill-totals {
    order: 30;
    background: #FDEBD3;
}
body.f300 .bill-trow { color: #241708; }
body.f300 .bill-trow > span:first-child { color: #4A2F0E; }
body.f300 .bill-trule { background: #C79A3B; }
/* the one TOTAL (check182's stamp): the sample's deep
   bronze. The PAID stamp keeps its green — a state
   color the sample does not cover. */
body.f300 .bill-stamp-due { color: #8A5A00; border-color: #8A5A00; }
body.f300 .bill-paidline-row { order: 40; }
body.f300 .bill-paidline { color: #5C4520; }
/* the estimate's pay QR (check290 rev 1): the one
   unclassed frame child that wraps divs. Its caption
   takes the sample's muted brown — inline-styled
   today, hence the !important. */
body.f300 .bill .bill-frame > div:not([class]):has(> div) { order: 50; }
body.f300 .bill .bill-frame > div:not([class]):has(> div) > div:last-child {
    color: #5C4520 !important;
}
body.f300 .bill-foot { order: 60; }
/* the tip tiles — the shared .tip-sec treatment, in the
   bill and in the /Pay standalone card alike. The panel
   ground is the section's own check187 cream: an
   unscoped check261 crawl-find rule darkens it on every
   base today, which the sample's light card cannot
   carry — the gate restores the design's own ground
   (gate off keeps check299's rendering exactly). */
body.f300 .tip-sec { background: linear-gradient(180deg, #fffaf3, #fdf3ec); }
body.f300 .tip-sec .tip-lab { color: #3A2410; }
body.f300 .tip-sec .tip-row .pill-btn {
    border-color: #B98A2F;
    color: #33200A;
}
body.f300 .tip-sec .tip-row .pill-btn .tip-amt { color: #6B4A12; }
body.f300 .tip-sec .tip-row .pill-btn.sel {
    background: #F2A81D;
    border-color: #8A5A00;
    color: #241708;
    box-shadow: 0 8px 18px rgba(138,90,0,.35);
}
body.f300 .tip-sec .tip-row .pill-btn.sel .tip-amt { color: #3A2703; }
body.f300 .tip-sec .tip-custom { border-color: #B98A2F; }
body.f300 .tip-sec .tip-custom span { color: #3A2410; }
body.f300 .tip-sec .tip-custom input { color: #241708; }

/* ============================================================
   check301 (owner, Nov 2, 2026 — "Remove the slant
   total here"): the bill's straight TOTAL row. Behind
   the gate (the layout's body.f301 marker), the shared
   bill component's totals panel (_Bill.cshtml renders
   the gate's markup) ends with check300's sample Total
   row — the label "Total" and the amount, straight, no
   rotation, no stamp box — and the sample's Tip row
   stands between the Service row and the rule where
   the surface has a tip. The row markup exists only
   when the gate shows (and body.f301 is present on
   exactly those requests), so every rule here is
   scoped body.f301; with the gate off the component
   renders check300's markup and these rules never
   match. The sizes and colors are the sample's own
   (mockups/check300-bill-colors.html), stated outright
   so the rows read the same with or without the f300
   colors beneath them. Appended only — no earlier
   rule is touched.
   ============================================================ */
body.f301 .bill-total-row {
    display: flex;
    justify-content: space-between;
    gap: 14px;
    align-items: baseline;
    padding-top: 6px;
}
body.f301 .bill-total-lab {
    font-size: 24px;
    font-weight: 800;
    color: #241708;
}
body.f301 .bill-total-amt {
    font-size: 36px;
    font-weight: 900;
    color: #8A5A00;
    white-space: nowrap;
}
body.f301 .bill-trow.bill-tip-row { font-size: 21px; }
body.f301 .bill-trow.bill-tip-row > span:first-child {
    color: #4A2F0E;
    font-weight: 600;
}
body.f301 .bill-trow.bill-tip-row > span:last-child {
    color: #241708;
    font-weight: 700;
    font-size: 22px;
}

/* ============================================================
   check302 (owner, Nov 2, 2026 — "Remove all. Add a
   separator at photo 1. Add the text to the estimate
   screen"): the gold separator rule under the payment
   block's PLAIN total row — the site's gold rule
   (.bill-trule, 2px var(--gold)) standing directly
   under "Service total", spanning the block's width.
   The element renders only when Features:Check302
   shows (the block's Show302 branch); the style hangs
   off the layout's f302 body class, so with the gate
   off nothing on any page can wear it. The total row
   above carries its own 14px margins; the rule sits
   2px under the row's text line (negative top margin
   pulls it up into the row's bottom margin so it
   reads as directly under the total, like the
   owner's photo 2).
   ============================================================ */
body.f302 .pay-sep302 {
    height: 2px;
    background: var(--gold);
    margin: -8px 0 6px;
}

/* ============================================================
   check304 (owner, Nov 2, 2026 — "Thanksgiving two
   themes were supposed to be a dark theme but I
   still see white"): Thanksgiving 2's page ground
   goes DARK. The theme's own variable block (line
   ~5251) left the two page-ground variables at
   Thanksgiving 1's cream — --hw-bg: #f6e9dc and
   --paper: #f6e9dc — while its panels (--hw-panel
   #3a1f14, --hw-panel2 #4a2a18), ink (--hw-ink
   #e7d6be) and golds are the dark design, so dark
   cards stood on a cream page. In every sibling
   theme the two ground variables AGREE and sit
   just below the panel (Halloween: --hw-bg and
   --paper both #140b06 under panel #1d110a;
   Thanksgiving 1: both #fbf2df, its light design).
   The dark value is the theme's own shadow brown
   #2e1a0c — the rgba(46, 26, 12) of its --shadow,
   a step below --hw-panel #3a1f14 the way
   Halloween's #140b06 sits below #1d110a, and the
   dark edge tone of the theme's hero artwork
   (thanksgiving2/hero.jpg edges measure #2e1308).
   Scoped to the layout's f304 marker: with the
   gate off these rules never match and every
   surface is byte-identical to check303. The
   theme's panels, ink and golds are untouched;
   its color-scheme is already dark in its own
   block. The html rule restates BOTH html
   backgrounds above (the hardcoded cream at the
   theme block and the var(--hw-bg) one) — this
   selector outranks them and stands last.
   ============================================================ */
html:has(body.f304.theme-thanksgiving2) { background: #2e1a0c; }
body.f304.theme-thanksgiving2 {
    --hw-bg: #2e1a0c;
    --paper: #2e1a0c;
    background: #2e1a0c;
}

/* ============================================================
   check307 (owner, Nov 2, 2026): the Book's opening
   release disc row at the BEGINNING of the day — a
   second row in the grid's thead (.book-open-row),
   rendered only while the Check307 gate shows (the
   layout's f307 marker). Two rules only:
   (1) its cells sit middle-aligned, the footer's
   own treatment for the same discs (.book-late-row
   td), where the grid's generic header rule would
   top-align them;
   (2) under check263 the grid's thead collapses to
   zero height (body.f263 .book-grid thead th) — the
   mirror header is the only header that paints —
   so this row alone is un-collapsed, restating the
   generic header cell metrics, or the discs would
   never paint in the pinned-header view the owner
   actually uses. The discs themselves keep the
   shared .late-* rules untouched. Scoped to
   body.f307 throughout: with the gate off these
   rules never match and every surface renders
   byte-identically to check306.
   ============================================================ */
body.f307 .book-grid thead tr.book-open-row th { vertical-align: middle; }
body.f263.f307 .book-grid thead tr.book-open-row th {
    height: auto;
    padding: 8px 10px;
    font-size: .92rem;
    line-height: normal;
    border-bottom: 1px solid #e3d2cc;
}

/* ============================================================
   check308 (owner, Nov 2, 2026 — screenshot of the
   /CheckIn rest face in DEV, the check293 QR card
   sitting on top of the photo's baked "Touch to
   start" pill: "QR Code covers the message"):
   check293's card is anchored to the face's
   bottom (position absolute, bottom: 5%, in the
   CheckIn page's own style block) — in portrait
   that lands below the pill exactly as the
   approved mockup drew it, but in landscape the
   cover crop parks the pill low on the face and
   the bottom-anchored card covers its middle.
   Behind this gate the rest face becomes a
   centered vertical STACK: .cir turns into a
   flex column, the card leaves its absolute
   anchor and flows as the column's last item —
   the photo with its pill first, the card
   directly below it with clear spacing, both
   fully visible, nothing covering either. The
   card keeps its design (white card, QR, the
   one "Scan to sign in" line) and its portrait
   size (a height cap joins the width so a short
   portrait window cannot push it up onto the
   pill, and on short portrait windows the label
   steps down a size to stay on its line); in
   landscape the card takes a smaller width with
   its label stepped down to stay on one line,
   and the photo's crop shifts a touch (45% ->
   46%, 48% at the desk's own aspects) so the
   pill always ends above the card; on very wide
   or short landscape screens the crop and the
   card shrink further to the same end. The QR
   still encodes the same check293 sign-in link;
   the scan flow and the touch flow are
   untouched. Scoped to body.f308 throughout:
   with the gate off these rules never match and
   the start screen renders byte-identically to
   check307.
   ============================================================ */
body.f308 .cir { display: flex; flex-direction: column;
    align-items: center; justify-content: flex-end; }
body.f308 .cq293-card { position: relative; left: auto;
    bottom: auto; transform: none; flex: none;
    width: min(300px, 64vw, 34vh);
    margin: 0 0 3vh; }
@media (orientation: portrait) and (max-height: 900px) {
    /* Short portrait windows: the height cap above
       narrows the card, so the label steps down a
       size and stays on its one line. */
    body.f308 .cq293-t { font-size: 21px;
        white-space: nowrap; }
}
@media (orientation: landscape) {
    body.f308 .cir { background-position: 50% 46%; }
    body.f308 .cq293-card { width: min(190px, 27vh);
        margin-bottom: 1.5vh; }
    body.f308 .cq293-t { font-size: 18px;
        white-space: nowrap; }
}
@media (orientation: landscape)
    and (max-aspect-ratio: 17/10) {
    /* The desk's own aspects: a touch more crop
       shift buys the pill-to-card gap. */
    body.f308 .cir { background-position: 50% 48%; }
}
@media (orientation: landscape)
    and (min-aspect-ratio: 17/10) {
    body.f308 .cq293-card { width: min(170px, 25vh); }
}
@media (orientation: landscape)
    and (min-aspect-ratio: 2/1) {
    body.f308 .cir { background-position: 50% 52%; }
    body.f308 .cq293-card { width: min(150px, 24vh); }
    body.f308 .cq293-t { white-space: normal; }
}
@media (orientation: landscape) and (max-width: 900px) {
    /* The phone squeeze zone (the page's own rule
       stretches the photo to a fixed 1745px
       height there): the crop moves to the pill
       itself and the card takes its smallest
       width, label at full size on two lines —
       the pill and the card never meet. */
    body.f308 .cir { background-position: 50% 56%; }
    body.f308 .cq293-card { width: 150px;
        margin-bottom: 2vh; }
    body.f308 .cq293-t { font-size: 25px;
        white-space: normal; }
}

/* ============================================================
   check312 (owner, Nov 2, 2026 — sample v2 approved
   with a photo of the desk iPad: "The image on ipad
   is cropped, being moved down too much"; sample of
   record: mockups/checkin-rest-move-sample2): the
   /CheckIn REST FACE redesigned, behind its OWN
   gate. The face stops centering everything: the
   owner's photo anchors TOWARD ITS TOP
   (background-position 50% 22% — the sample's
   anchor), and the words the photo used to carry
   baked-in are rendered by the page in the UPPER
   HALF instead: "A+ Nails" in Pinyon Script (the
   fancy script below, SELF-HOSTED like Great Vibes
   before it — the desk iPad never depends on
   Google Fonts), "OF ROWLETT" letterspaced under
   it in the site's display serif, and a "Touch to
   start" pill, all under the sample's soft scrim.
   The bottom of the face is divided into THREE
   EQUAL COLUMNS (the gated .cq312-bottom markup in
   CheckIn.cshtml) and check293's QR card lives in
   the MIDDLE column only, SMALLER than either
   earlier design (about 158px wide, the code about
   118px, the same "Scan to sign in" line), sliding
   gently between that column's left and right
   edges every 60 seconds — the gated script in
   CheckIn.cshtml flips its .cq312-r class — so the
   always-on desk screen never burns one spot in.
   A touch still wakes the desk (and stops the
   timer with the wake); the QR still encodes the
   same check293 sign-in link; the idle return is
   untouched. These rules are scoped body.f312 and
   appended AFTER check308's block, so when both
   gates show, this composition wins over the
   stacked layout cleanly; with the gate off none
   of them match, no f312 body class is emitted,
   no gated markup renders, and the start screen
   renders byte-identically to check309.
   ============================================================ */
/* Pinyon Script, SELF-HOSTED (wwwroot/fonts/
   pinyon-script.woff2, the latin subset) — no
   Google Fonts dependency at runtime. */
@font-face {
    font-family: "Pinyon Script";
    src: url("/fonts/pinyon-script.woff2") format("woff2");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}
body.f312 .cir { display: block;
    background-position: 50% 22%; }
body.f312 .cq312-scrim { position: absolute; inset: 0;
    z-index: 1; pointer-events: none;
    background: linear-gradient(180deg,
        rgba(30, 16, 10, .46) 0%,
        rgba(30, 16, 10, .10) 48%,
        rgba(30, 16, 10, .26) 100%); }
body.f312 .cq312-top { position: absolute; left: 0;
    right: 0; top: 5.5%; z-index: 2; text-align: center;
    pointer-events: none; }
body.f312 .cq312-brand {
    font-family: "Pinyon Script", "Great Vibes", cursive;
    font-size: min(118px, 15vh, 13vw); line-height: 1.05;
    color: #fff; text-shadow: 0 3px 16px rgba(0,0,0,.55); }
body.f312 .cq312-sub { font-family: var(--font-display);
    font-weight: 600; letter-spacing: .55em;
    text-indent: .55em;
    font-size: min(21px, 2.8vh, 2.6vw);
    color: #ffe9c9; margin-top: 2px;
    text-shadow: 0 2px 8px rgba(0,0,0,.6); }
body.f312 .cq312-pill { display: inline-block;
    margin-top: min(40px, 5vh); background: #fff8ee;
    color: #7a3b2e; font-family: var(--font-body);
    font-weight: 700;
    font-size: min(34px, 4.6vh, 4vw);
    padding: min(22px, 3vh) min(64px, 7vw);
    border-radius: 999px;
    box-shadow: 0 10px 26px rgba(0,0,0,.4); }
body.f312 .cq312-bottom { position: absolute; left: 0;
    right: 0; bottom: 4.3%; z-index: 3; display: flex;
    align-items: flex-end; }
body.f312 .cq312-col { flex: 1 1 0; position: relative; }
body.f312 .cq293-card { --cq312w: min(158px, 31vw);
    position: relative; left: 6px; bottom: auto;
    transform: none; flex: none; width: var(--cq312w);
    margin: 0; padding: 12px 12px 9px;
    border-radius: 14px;
    transition: left .9s ease-in-out; }
body.f312 .cq293-card.cq312-r {
    left: calc(100% - var(--cq312w) - 6px); }
body.f312 .cq293-qr { width: min(118px, 24vw);
    margin: 0 auto; }
body.f312 .cq293-t { font-size: 15px; margin-top: 7px;
    white-space: nowrap; }

/* check315 (owner, Nov 2, 2026): the CheckIn phone
   step's OK / Cancel row + the step's LANDSCAPE fit.
   Hangs off body.f315 (the layout emits it exactly
   when the Check315 gate shows); with the gate off
   no rule here ever matches and every surface
   renders exactly as check309.
   The row: the phone form becomes a flex row, OK
   (the standing rose submit, untouched) and Cancel
   sharing the width; Cancel wears the KEYPAD KEY's
   face (white, thin border, rose-dark words — the
   .ci-key look) so the pair stays in the step's one
   component family, themed exactly where the keys
   are themed. */
body.f315 #ciPhoneForm { display: flex; gap: 14px; }
body.f315 #ciPhoneForm .ci-ok { flex: 1 1 0; width: auto; }
body.f315 .ci-cancel315 { background: #fff;
    color: var(--rose-dark);
    border: 1.5px solid #e7d8cf;
    box-shadow: 0 2px 6px rgba(150, 85, 95, .08); }
body.theme-halloween.f315 .ci-cancel315,
body.theme-thanksgiving1.f315 .ci-cancel315,
body.theme-thanksgiving2.f315 .ci-cancel315 {
    background: var(--hw-panel2); color: var(--hw-cream);
    border-color: var(--hw-line); }
/* The landscape fit (owner: "the desk iPad sits
   HORIZONTAL"): at the base rhythm the phone step
   stands ~975px tall — on a 1024x768 / 1180x820
   iPad the pad and the buttons cropped below the
   fold. In landscape up to 900px tall, and only
   there, the f315 step compresses its vertical
   rhythm (band, heading, box, keys sized off the
   viewport height) so the whole step — band,
   prompt, phone box, the full pad and the
   OK/Cancel row — is on screen at once with no
   scrolling, an error line included. Portrait and
   tall screens keep the base sizes exactly. */
@media (orientation: landscape) and (max-height: 900px) {
    body.f315 .ci-band { padding: 8px 0 6px; }
    body.f315 .ci-band .ci-emblem { width: 56px;
        height: 56px; font-size: 20px; }
    body.f315 .ci-brand { margin-top: 2px;
        font-size: 13px; }
    body.f315 .ci-wrap { padding: 12px 20px 16px; }
    body.f315 .ci-h1 { font-size: 52px; }
    body.f315 .ci-prompt { margin-top: 10px;
        font-size: 20px; }
    body.f315 .ci-phonebox { margin-top: 12px;
        height: 72px; }
    body.f315 .ci-error { margin-top: 10px;
        padding: 8px 14px; }
    body.f315 .ci-pad { margin-top: 12px; gap: 10px; }
    body.f315 .ci-key { height: clamp(46px, 8.5vh, 84px);
        font-size: 28px; }
    body.f315 #ciPhoneForm .ci-ok { margin-top: 14px;
        min-height: 60px; padding: 12px;
        font-size: 22px; }
}
/* check315, the corner card: the rest face's QR
   card (check293's design — the same white card,
   the same caption) at the phone step's upper
   right corner, fixed, so it adds no height to
   the step and the landscape fit above is
   untouched. It renders only while the Check315
   gate shows (and check293's — the markup is
   gated on both), sits above the step (z 40) and
   below the rest face itself (z 9999), and
   shrinks a step on short landscape screens. */
body.f315 .ci-qr315 { position: fixed; top: 12px;
    right: 12px; width: 128px; background: #fffdf8;
    border-radius: 16px; padding: 10px 10px 7px;
    text-align: center; z-index: 40;
    box-shadow: 0 8px 24px rgba(0, 0, 0, .35); }
body.f315 .ci-qr315-box svg { display: block;
    width: 100%; height: auto; }
body.f315 .ci-qr315-t { font-size: 13px;
    font-weight: 600; color: #4a2f1c;
    margin-top: 5px; letter-spacing: .03em; }
@media (orientation: landscape) and (max-height: 900px) {
    body.f315 .ci-qr315 { width: 112px; top: 10px;
        right: 10px; }
}

/* check316 (owner, Nov 2, 2026): the desk iPad sits
   HORIZONTAL — "sign in is horizontal. Change all
   settings to meet." Behind the Check316 gate the
   sign-in flow's remaining steps fit the landscape
   screen whole: the found/confirm step, the
   new-customer step, the welcome display and the
   done step. (The rest face is check312's; the
   phone step is check315's — the rules below are
   step-scoped with :has() so neither of those steps
   changes by a pixel while this gate shows.)
   Measured on build-check309 (diag/check316): the
   found step stands ~770-850px tall and the new
   step ~850px against a 768px screen — the OK
   button sits below the fold and the page scrolls.
   The fit, inside a landscape-only media query (so
   portrait and phones render exactly as before):
   the band slims to a header bar (emblem and brand
   on one line), the wrap widens so the eight
   service pills take two rows instead of three,
   the type and the OK step down one size, and the
   wrap becomes a flex column that centres the step
   in the space under the band — a deliberate
   landscape composition, not the portrait column
   stretched. The welcome's sizes hang off vh
   instead of vw so its veil scales with the
   screen's height and can never outgrow it.
   Gate OFF: no f316 class, this block never
   matches, every step is byte-identical to
   check309. */
@media (orientation: landscape) and (max-height: 900px) {
    /* the band, slimmed to a bar — only over one of
       this build's steps (the band over the phone
       step keeps its full height for check315). */
    body.f316 .ci-band:has(+ .ci-wrap.ci316-step) {
        display: flex; align-items: center;
        justify-content: center; gap: 14px;
        padding: 10px 0 8px; }
    body.f316 .ci-band:has(+ .ci-wrap.ci316-step) .ci-emblem {
        width: 60px; height: 60px; font-size: 22px; }
    body.f316 .ci-band:has(+ .ci-wrap.ci316-step) .ci-brand {
        margin-top: 0; font-size: 16px; }
    /* the wrap: wider, tighter, and centred in the
       space under the 80px bar. */
    body.f316 .ci-wrap.ci316-step {
        max-width: 1060px; padding: 16px 28px 20px;
        display: flex; flex-direction: column;
        justify-content: center;
        min-height: calc(100vh - 80px); }
    body.f316 .ci-wrap.ci316-step .ci-script {
        font-size: 46px; }
    body.f316 .ci-wrap.ci316-step .ci-name {
        font-size: 50px; margin-top: 0; }
    body.f316 .ci-wrap.ci316-step .ci-fieldlabel {
        margin: 14px 0 6px 4px; font-size: 17px; }
    body.f316 .ci-wrap.ci316-step .ci-textbox {
        height: 72px; font-size: 28px; }
    body.f316 .ci-wrap.ci316-step .ci-error {
        margin-top: 12px; padding: 10px 14px;
        font-size: 17px; }
    body.f316 .ci-wrap.ci316-step .ci-pills {
        margin-top: 18px; }
    body.f316 .ci-wrap.ci316-step .ci-pills .svc-grid {
        gap: 12px; }
    body.f316 .ci-wrap.ci316-step .ci-pills .book-svc .slot {
        min-height: 62px; padding: 10px 18px; }
    body.f316 .ci-wrap.ci316-step .ci-pills .book-svc .svc-name {
        font-size: 1.22rem; }
    body.f316 .ci-wrap.ci316-step .ci-ok {
        margin-top: 18px; min-height: 68px;
        padding: 16px; font-size: 25px; }
    body.f316 .ci-wrap.ci316-step .ci-startover {
        margin-top: 14px; font-size: 16px; }
    /* the done step's column, sized to the bar. */
    body.f316 .ci-wrap.ci316-step .ci-check {
        width: 128px; height: 128px; font-size: 66px;
        margin-top: 6px; }
    body.f316 .ci-wrap.ci316-step .ci-donename {
        font-size: 46px; margin-top: 20px; }
    body.f316 .ci-wrap.ci316-step .ci-doneline {
        font-size: 24px; margin-top: 6px; }
    /* check263's centred camera dot follows the
       slim band down on this build's steps (its
       rest-face placement outranks this rule, and
       the phone step's full band keeps the old
       offset because the body test fails there). */
    body.f316.f263:has(.ci-wrap.ci316-step) .ci-armdot257 {
        top: 88px; }
    /* the welcome display: every size hangs off the
       viewport HEIGHT, so the veil always fits the
       landscape screen it covers. */
    body.f316 .ci-welcome .ci-veil {
        padding: min(38px, 5vh) 30px min(40px, 5.4vh); }
    body.f316 .ci-welcome .ci-script {
        font-size: clamp(44px, 13.5vh, 104px); }
    body.f316 .ci-welcome .ci-name {
        font-size: clamp(40px, 11vh, 84px); }
    body.f316 .ci-welcome .ci-svc-label {
        font-size: clamp(17px, 2.9vh, 22px);
        margin-bottom: min(20px, 2.6vh); }
    body.f316 .ci-welcome .ci-dpills {
        gap: min(14px, 1.8vh); }
    body.f316 .ci-welcome .ci-dpill {
        padding: min(9px, 1.2vh) 24px
            min(9px, 1.2vh) min(9px, 1.2vh); }
    body.f316 .ci-welcome .ci-dpill .coin {
        width: clamp(36px, 5.6vh, 44px);
        height: clamp(36px, 5.6vh, 44px);
        font-size: clamp(17px, 2.7vh, 21px); }
    body.f316 .ci-welcome .ci-dpill-name {
        font-size: clamp(20px, 3.4vh, 27px); }
}

/* BUILD 318, item 2 — REVISED (owner, Nov 2, 2026):
   "Remove Good evening. Please sign in:" — the
   greeting line comes OFF the phone step entirely
   (the item's first form, his dictated two lines,
   was superseded by the removal the same evening).
   While the Check319 gate shows (and check287's —
   the greeting it removes is check287's), the page
   renders the prompt div empty and this rule takes
   it out of the layout altogether, so the "Sign In"
   heading stands alone and the step closes up the
   freed space (the check315/316 landscape fit only
   gains room). Hangs off body.f319 (the layout
   emits it exactly when the Check319 gate shows);
   with the gate off no rule here matches and the
   prompt is check287's one line exactly. */
body.f319 .ci-prompt { display: none; }

/* ============================================================
   BUILD 318, item 1 (owner, Nov 2, 2026): the rest face
   becomes his poster artwork, 100% — "Use this 100%".
   His words for the want: the Touch to start face as a
   SCREEN SAVER with animation, so the desk iPad can
   stay on all day without being shut off. The poster
   he supplied (wwwroot/images/station-poster-dark.png
   — dark marble, gold flowers, his "A+ Nails /
   Welcome / Touch to Start" composition) is laid over
   the whole face on the gated .ci318-art layer:
   contain-fitted over a backdrop sampled from the
   art's own dark edge tone (#150c07), so the WHOLE
   poster is on screen at every size — desk landscape
   (1024x768, 1180x820) and portrait alike, nothing
   cut at any edge — and breathed with a slow Ken
   Burns pan/zoom (36 s, gentle) so the always-on
   screen never sits still. Everything the earlier
   faces rendered (check215's photo face, check312's
   brand block and pill, check293's QR card, the glow
   and shimmer) stays in the page underneath, hidden:
   the poster's baked words are the face's words now.
   The one live thing on the poster is the QR: the
   gated .ci318-qr overlay carries check293's minted
   code (mirrored from the rest card by the gated
   script in CheckIn.cshtml) exactly over the
   poster's baked QR square, so it scans for real;
   the poster's baked "Scan to Sign In" caption stays
   as its caption. The baked QR's place in the art
   (measured from the file): left 47.1%, top 75.7%,
   width 7.0% of the poster's width; the poster is
   1672x941, so the stage variables below are the
   contain rect of a 1.77683-aspect picture inside
   the viewport, and the overlay rides it at any
   screen size. A touch anywhere on the face still
   wakes the desk, and the camera dot and every
   other station behaviour are untouched. Hangs off
   body.f318 (the layout emits it exactly when the
   Check318 gate shows); with the gate off no rule
   here matches, no gated markup renders, and the
   rest face is byte-identical to the check317 stack.
   ============================================================ */
body.f318 .cir { background: #150c07; }
body.f318 .ci318-art { position: absolute; inset: 0;
    z-index: 1; pointer-events: none;
    background: url("/images/station-poster-dark.png")
        center center / contain no-repeat;
    animation: ci318burns 36s ease-in-out infinite
        alternate; }
@keyframes ci318burns {
    0% { transform: scale(1) translate(0, 0); }
    100% { transform: scale(1.045)
        translate(-0.6%, 0.45%); }
}
body.f318 .cir-glow, body.f318 .cir-shimmer,
body.f318 .cq312-scrim, body.f318 .cq312-top,
body.f318 .cq312-bottom,
body.f318 .cir .cq293-card { display: none; }
body.f318 .ci318-qr {
    --sw: min(100vw, 177.683vh);
    --sh: min(56.280vw, 100vh);
    --sx: calc((100vw - var(--sw)) / 2);
    --sy: calc((100vh - var(--sh)) / 2);
    position: absolute; z-index: 2;
    left: calc(var(--sx) + var(--sw) * 0.471);
    top: calc(var(--sy) + var(--sh) * 0.757);
    width: calc(var(--sw) * 0.070); }
body.f318 .ci318-qr svg { display: block; width: 100%;
    height: auto; }

/* ============================================================
   BUILD 318, item 3 (owner, Nov 2, 2026): the phone
   step becomes his sign-in artwork, 100% — "Use this
   100%, make sure you change color of buttons when
   pressed". The light marble-and-orchid page he
   supplied (wwwroot/images/station-signin-light.png)
   is the step's full-screen background: the wrap
   (wearing its gated ci320-stage marker) becomes a
   fixed full-viewport stage over a cream backdrop
   sampled from the art's edge (#f5e9d8), and the art
   itself is painted whole by the stage's ::before at
   the contain rect — no black bar, nothing cut at
   1024x768, 1180x820 or in portrait. The REAL
   controls sit over their baked counterparts, all
   placed off the stage variables (the contain rect
   of the 1448x1086, 4:3 art): the phone box (art:
   left 19.7%, top 38.5%, width 60.5%, height 9.8%),
   the keypad (left 20.2%, top 49.7%, width 59.5%,
   height 32.1% — its grid keeps the art's own
   pitches), OK and Cancel (the row at top 83.7%,
   height 9.1%; OK 20.1%–51.3%, Cancel 53.2%–79.4%
   of the art's width), and check315's live corner
   QR re-seated exactly over the art's baked QR
   square (left 87.5%, top 7.8%, width 7.3% — its
   baked "Scan to Sign In" caption serves). The
   band, the "Sign In" heading and the prompt line
   leave the stage: the art carries the branding and
   the heading baked in, and the prompt div itself
   becomes the soft cream VEIL PATCH over the art's
   baked greeting line (art: left 32.2%, top 34.8%,
   width 35.8%, height 3.4%) — a radial cream fade
   with its text rendered invisible, so no greeting
   shows anywhere on the step (item 2's removal
   applies here too). The dress is the art's own:
   cream pills with gold borders and burgundy words,
   OK filled deep burgundy with cream words — and a
   PRESSED button changes colour (his order): a key
   fills burgundy with cream numbers while pressed,
   OK deepens, Cancel fills burgundy too. Every
   check315 behaviour (the 30-second idle return
   holding the camera stream, OK, Cancel, the corner
   code's mirror) is untouched — this block only
   moves and dresses the same elements. Hangs off
   body.f320 with the stage marker; with the gate
   off no rule here matches, no marker is emitted,
   and the phone step is byte-identical.
   ============================================================ */
body.f320 .ci-band:has(+ .ci-wrap.ci320-stage) {
    display: none; }
body.f320 .ci-wrap.ci320-stage {
    --sw: min(100vw, 133.333vh);
    --sh: min(75vw, 100vh);
    --sx: calc((100vw - var(--sw)) / 2);
    --sy: calc((100vh - var(--sh)) / 2);
    position: fixed; inset: 0; z-index: 30;
    max-width: none; margin: 0; padding: 0;
    background: #f5e9d8; }
body.f320 .ci-wrap.ci320-stage::before {
    content: ""; position: absolute; z-index: 0;
    left: var(--sx); top: var(--sy);
    width: var(--sw); height: var(--sh);
    background: url("/images/station-signin-light.png")
        center / 100% 100% no-repeat;
    pointer-events: none; }
body.f320 .ci320-stage .ci-h1 { display: none; }
/* the prompt is the veil patch over the art's baked
   greeting line — present, soft-edged, and empty of
   any visible words. The patch is wider and taller
   than the baked line and its gradient keeps alpha
   at 1 across the whole strip (the strip's corners
   sit at ~0.62 of the gradient ray, inside the 60%
   full stop), feathering only outside it — the
   baked words cannot ghost through. */
body.f320 .ci320-stage .ci-prompt {
    display: block; position: absolute; z-index: 1;
    left: calc(var(--sx) + var(--sw) * 0.285);
    top: calc(var(--sy) + var(--sh) * 0.322);
    width: calc(var(--sw) * 0.430);
    height: calc(var(--sh) * 0.084);
    margin: 0; padding: 0;
    font-size: 0; line-height: 0; color: transparent;
    background: radial-gradient(ellipse 75% 75%
        at 50% 50%, rgba(252, 241, 224, 1) 60%,
        rgba(251, 238, 218, 0.98) 76%,
        rgba(250, 236, 214, 0) 98%);
    pointer-events: none; }
body.f320 .ci320-stage .ci-phonebox {
    position: absolute; z-index: 1;
    left: calc(var(--sx) + var(--sw) * 0.197);
    top: calc(var(--sy) + var(--sh) * 0.385);
    width: calc(var(--sw) * 0.605);
    height: calc(var(--sh) * 0.098);
    margin: 0; padding: 0 calc(var(--sw) * 0.02);
    background: linear-gradient(180deg, #fffaf0,
        #f8ecd4);
    border: 2px solid #d9a441;
    border-radius: calc(var(--sh) * 0.030);
    box-shadow: 0 6px 18px rgba(146, 96, 32, .18),
        inset 0 1px 0 #ffffff; }
body.f320 .ci320-stage .ci-digits {
    font-size: calc(var(--sh) * 0.050);
    color: #71182a;
    letter-spacing: calc(var(--sw) * 0.004); }
body.f320 .ci320-stage .ci-digits .dim {
    color: #cfa96f; }
body.f320 .ci320-stage .ci-error {
    position: absolute; z-index: 2;
    left: calc(var(--sx) + var(--sw) * 0.247);
    top: calc(var(--sy) + var(--sh) * 0.322);
    width: calc(var(--sw) * 0.505); margin: 0; }
body.f320 .ci320-stage .ci-pad {
    position: absolute; z-index: 1;
    left: calc(var(--sx) + var(--sw) * 0.202);
    top: calc(var(--sy) + var(--sh) * 0.497);
    width: calc(var(--sw) * 0.595);
    height: calc(var(--sh) * 0.321);
    margin: 0;
    grid-template-rows: repeat(4, 1fr);
    column-gap: calc(var(--sw) * 0.012);
    row-gap: calc(var(--sh) * 0.008); }
body.f320 .ci320-stage .ci-key {
    height: auto; min-height: 0;
    background: linear-gradient(180deg, #fffdf6,
        #f8ecd7);
    border: 2px solid #d9a441; border-radius: 999px;
    color: #71182a;
    font-size: calc(var(--sh) * 0.040);
    box-shadow: 0 3px 8px rgba(146, 96, 32, .16); }
body.f320 .ci320-stage .ci-key:active {
    background: linear-gradient(180deg, #93253d,
        #6d1223);
    color: #fff6e8; border-color: #b98a2e; }
body.f320 .ci320-stage .ci-keyblank {
    background: transparent; border-color: transparent;
    box-shadow: none; }
body.f320 .ci320-stage #ciPhoneForm {
    position: absolute; z-index: 1;
    left: calc(var(--sx) + var(--sw) * 0.201);
    top: calc(var(--sy) + var(--sh) * 0.837);
    width: calc(var(--sw) * 0.593);
    height: calc(var(--sh) * 0.091);
    margin: 0; display: flex;
    gap: calc(var(--sw) * 0.019); }
body.f320 .ci320-stage #ciPhoneForm .ci-ok {
    flex: 312 1 0; width: auto; margin: 0;
    min-height: 0; padding: 0 calc(var(--sw) * 0.02);
    background: linear-gradient(180deg, #a12444,
        #7c1530);
    border: 2px solid #d9a441; border-radius: 999px;
    color: #fff8ec;
    font-size: calc(var(--sh) * 0.038);
    box-shadow: 0 8px 20px rgba(124, 21, 48, .35); }
body.f320 .ci320-stage #ciPhoneForm .ci-ok:active {
    background: linear-gradient(180deg, #7c1530,
        #5c0d22);
    color: #ffe9c9; }
body.f320 .ci320-stage #ciPhoneForm
    .ci-ok.ci-cancel315 {
    flex: 262 1 0;
    background: linear-gradient(180deg, #fffdf6,
        #f8ecd7);
    color: #71182a; border: 2px solid #d9a441;
    box-shadow: 0 3px 8px rgba(146, 96, 32, .16); }
body.f320 .ci320-stage #ciPhoneForm
    .ci-ok.ci-cancel315:active {
    background: linear-gradient(180deg, #93253d,
        #6d1223);
    color: #fff6e8; }
/* check315's live corner card, re-seated over the
   art's baked QR square (its card chrome goes
   transparent — the art's own card, gold frame and
   baked "Scan to Sign In" caption show around the
   live code, and the live caption hides). */
body.f320 .ci320-stage .ci-qr315 {
    position: absolute; z-index: 2;
    left: calc(var(--sx) + var(--sw) * 0.875);
    top: calc(var(--sy) + var(--sh) * 0.078);
    width: calc(var(--sw) * 0.073);
    background: transparent; border-radius: 0;
    padding: 0; box-shadow: none; }
body.f320 .ci320-stage .ci-qr315-t, body.f321 .ci-wrap.ci320-stage .ci-prompt { display: none; }

/* ---- morning: the sunrise picture ---- */
body.f321 .ci-wrap.ci320-stage.ci321-morning {
    background: #eeb8ad; }
body.f321 .ci-wrap.ci320-stage.ci321-morning::before {
    background-image:
        url("/images/station-signin-morning.png"); }
body.f321 .ci320-stage.ci321-morning .ci-phonebox {
    left: calc(var(--sx) + var(--sw) * 0.280);
    top: calc(var(--sy) + var(--sh) * 0.338);
    width: calc(var(--sw) * 0.438);
    height: calc(var(--sh) * 0.098); }
body.f321 .ci320-stage.ci321-morning .ci-error {
    left: calc(var(--sx) + var(--sw) * 0.280);
    top: calc(var(--sy) + var(--sh) * 0.292);
    width: calc(var(--sw) * 0.438); }
body.f321 .ci320-stage.ci321-morning .ci-pad {
    left: calc(var(--sx) + var(--sw) * 0.269);
    top: calc(var(--sy) + var(--sh) * 0.456);
    width: calc(var(--sw) * 0.461);
    height: calc(var(--sh) * 0.371);
    column-gap: calc(var(--sw) * 0.010);
    row-gap: calc(var(--sh) * 0.009); }
body.f321 .ci320-stage.ci321-morning #ciPhoneForm {
    left: calc(var(--sx) + var(--sw) * 0.212);
    top: calc(var(--sy) + var(--sh) * 0.854);
    width: calc(var(--sw) * 0.572);
    height: calc(var(--sh) * 0.105);
    gap: calc(var(--sw) * 0.026); }
body.f321 .ci320-stage.ci321-morning #ciPhoneForm .ci-ok, body.f321 .ci320-stage.ci321-morning #ciPhoneForm .ci-ok.ci-cancel315 { flex: 273 1 0; }
body.f321 .ci320-stage.ci321-morning .ci-qr315 {
    left: calc(var(--sx) + var(--sw) * 0.788);
    top: calc(var(--sy) + var(--sh) * 0.440);
    width: calc(var(--sw) * 0.154); }

/* ---- afternoon: the green orchid picture ---- */
body.f321 .ci-wrap.ci320-stage.ci321-afternoon {
    background: #e3d6c2; }
body.f321 .ci-wrap.ci320-stage.ci321-afternoon::before {
    background-image:
        url("/images/station-signin-afternoon.png"); }
body.f321 .ci320-stage.ci321-afternoon .ci-phonebox {
    left: calc(var(--sx) + var(--sw) * 0.285);
    top: calc(var(--sy) + var(--sh) * 0.342);
    width: calc(var(--sw) * 0.423);
    height: calc(var(--sh) * 0.098); }
body.f321 .ci320-stage.ci321-afternoon .ci-error {
    left: calc(var(--sx) + var(--sw) * 0.285);
    top: calc(var(--sy) + var(--sh) * 0.296);
    width: calc(var(--sw) * 0.423); }
body.f321 .ci320-stage.ci321-afternoon .ci-pad {
    left: calc(var(--sx) + var(--sw) * 0.287);
    top: calc(var(--sy) + var(--sh) * 0.460);
    width: calc(var(--sw) * 0.425);
    height: calc(var(--sh) * 0.366);
    column-gap: calc(var(--sw) * 0.011);
    row-gap: calc(var(--sh) * 0.007); }
body.f321 .ci320-stage.ci321-afternoon #ciPhoneForm {
    left: calc(var(--sx) + var(--sw) * 0.191);
    top: calc(var(--sy) + var(--sh) * 0.857);
    width: calc(var(--sw) * 0.616);
    height: calc(var(--sh) * 0.110);
    gap: calc(var(--sw) * 0.018); }
body.f321 .ci320-stage.ci321-afternoon #ciPhoneForm
    .ci-ok { flex: 301 1 0; }
body.f321 .ci320-stage.ci321-afternoon #ciPhoneForm
    .ci-ok.ci-cancel315 { flex: 297 1 0; }
body.f321 .ci320-stage.ci321-afternoon .ci-qr315 {
    left: calc(var(--sx) + var(--sw) * 0.768);
    top: calc(var(--sy) + var(--sh) * 0.475);
    width: calc(var(--sw) * 0.154); }

/* ---- evening: the dark marble picture ---- */
body.f321 .ci-wrap.ci320-stage.ci321-evening {
    background: #1e1108; }
body.f321 .ci-wrap.ci320-stage.ci321-evening::before {
    background-image:
        url("/images/station-signin-evening.png"); }
body.f321 .ci320-stage.ci321-evening .ci-phonebox {
    left: calc(var(--sx) + var(--sw) * 0.272);
    top: calc(var(--sy) + var(--sh) * 0.313);
    width: calc(var(--sw) * 0.430);
    height: calc(var(--sh) * 0.100);
    background: linear-gradient(180deg, #4a2415,
        #2a130b);
    border-color: #c99635;
    box-shadow: 0 6px 18px rgba(0, 0, 0, .5),
        inset 0 1px 0 rgba(255, 220, 160, .25); }
body.f321 .ci320-stage.ci321-evening .ci-digits {
    color: #f7ead0; }
body.f321 .ci320-stage.ci321-evening .ci-digits .dim {
    color: #a87c3f; }
body.f321 .ci320-stage.ci321-evening .ci-error {
    left: calc(var(--sx) + var(--sw) * 0.272);
    top: calc(var(--sy) + var(--sh) * 0.267);
    width: calc(var(--sw) * 0.430); }
body.f321 .ci320-stage.ci321-evening .ci-pad {
    left: calc(var(--sx) + var(--sw) * 0.284);
    top: calc(var(--sy) + var(--sh) * 0.431);
    width: calc(var(--sw) * 0.412);
    height: calc(var(--sh) * 0.358);
    column-gap: calc(var(--sw) * 0.008);
    row-gap: calc(var(--sh) * 0.009); }
body.f321 .ci320-stage.ci321-evening .ci-key {
    background: linear-gradient(180deg, #542c17,
        #331708);
    border-color: #c99635;
    color: #f7ead0;
    box-shadow: 0 3px 8px rgba(0, 0, 0, .45); }
body.f321 .ci320-stage.ci321-evening .ci-key:active {
    background: linear-gradient(180deg, #e9bc5f,
        #c99635);
    color: #2a130b; border-color: #e9bc5f; }
body.f321 .ci320-stage.ci321-evening .ci-keyblank {
    background: transparent; border-color: transparent;
    box-shadow: none; }
body.f321 .ci320-stage.ci321-evening #ciPhoneForm {
    left: calc(var(--sx) + var(--sw) * 0.180);
    top: calc(var(--sy) + var(--sh) * 0.832);
    width: calc(var(--sw) * 0.632);
    height: calc(var(--sh) * 0.114);
    gap: calc(var(--sw) * 0.032); }
body.f321 .ci320-stage.ci321-evening #ciPhoneForm
    .ci-ok {
    flex: 295 1 0;
    background: linear-gradient(180deg, #eec25e,
        #cf9c36);
    border-color: #8a6420; color: #331a04;
    box-shadow: 0 8px 20px rgba(0, 0, 0, .5); }
body.f321 .ci320-stage.ci321-evening #ciPhoneForm
    .ci-ok:active {
    background: linear-gradient(180deg, #93253d,
        #6d1223);
    color: #fff6e8; border-color: #c99635; }
body.f321 .ci320-stage.ci321-evening #ciPhoneForm
    .ci-ok.ci-cancel315 {
    flex: 305 1 0;
    background: linear-gradient(180deg, #93253d,
        #67122a);
    color: #ffedd6; border-color: #c99635;
    box-shadow: 0 3px 8px rgba(0, 0, 0, .45); }
body.f321 .ci320-stage.ci321-evening #ciPhoneForm
    .ci-ok.ci-cancel315:active {
    background: linear-gradient(180deg, #e9bc5f,
        #c99635);
    color: #2a130b; border-color: #e9bc5f; }
body.f321 .ci320-stage.ci321-evening .ci-qr315 {
    left: calc(var(--sx) + var(--sw) * 0.761);
    top: calc(var(--sy) + var(--sh) * 0.449);
    width: calc(var(--sw) * 0.146); }

/* BUILD 319, the keypad's last row: in all three
   pictures the baked last row is TWO wide pills —
   the 0 pill and the backspace pill, splitting the
   pad between them — not the grid's blank / 0 /
   back. So under a daypart the blank cell leaves
   the row and the real 0 and backspace ride
   absolutely over their baked pills (positions in
   percent of the pad, measured from each picture:
   the 0 pill's own glyph sits under the real one,
   never beside it). Rows 1–3 keep the grid. */
body.f321 .ci-wrap.ci320-stage .ci-keyblank {
    display: none; }
body.f321 .ci320-stage.ci321-morning
    .ci-key[data-k="0"],
body.f321 .ci320-stage.ci321-morning
    .ci-key[data-k="back"] {
    position: absolute; top: 75.2%; height: 25.1%; }
body.f321 .ci320-stage.ci321-morning
    .ci-key[data-k="0"] { left: 0; width: 48.6%; }
body.f321 .ci320-stage.ci321-morning
    .ci-key[data-k="back"] { left: 51.4%;
    width: 48.6%; }
body.f321 .ci320-stage.ci321-afternoon
    .ci-key[data-k="0"] {
    position: absolute; left: 0; top: 75.4%;
    width: 48.7%; height: 24.6%; }
body.f321 .ci320-stage.ci321-afternoon
    .ci-key[data-k="back"] {
    position: absolute; left: 51.3%; top: 74.6%;
    width: 48.9%; height: 25.4%; }
body.f321 .ci320-stage.ci321-evening
    .ci-key[data-k="0"] {
    position: absolute; left: 0; top: 74.0%;
    width: 48.3%; height: 26.3%; }
body.f321 .ci320-stage.ci321-evening
    .ci-key[data-k="back"] {
    position: absolute; left: 51.7%; top: 74.9%;
    width: 48.3%; height: 25.1%; }

/* ============================================================
   BUILD 320, item 3 (owner, Nov 2, 2026 — his real-iPad
   photos; diagnosis cause 1 in diag/check319/REAL-DEVICE-
   DIAGNOSIS.md): the artwork stage's geometry is computed
   from 100vw/100vh, which on iPad Safari describe the
   layout/large viewport, not the visible screen with the
   browser chrome — the stage was laid out for a bigger
   box than the screen shows and overflowed it. Behind
   this gate (body.f324), the stage's four variables are
   restated in the DYNAMIC viewport units (dvw/dvh,
   Safari 15.4+) — the fractions every control is placed
   with are unchanged; only the box they are fractions
   OF now tracks the visible screen as chrome shows and
   hides. Gate OFF: this block never matches, no f324
   marker is emitted, and the stage renders exactly as
   the BUILD 319 publish.
   ============================================================ */
body.f324 .ci-wrap.ci320-stage {
    --sw: min(100dvw, 133.333dvh);
    --sh: min(75dvw, 100dvh);
    --sx: calc((100dvw - var(--sw)) / 2);
    --sy: calc((100dvh - var(--sh)) / 2); }

/* ============================================================
   BUILD 320, item 6 (owner, Nov 2, 2026 — "I need to
   use all real estate of the ipad screen"): Touch to
   Start and the sign-in page FILL THE WHOLE SCREEN,
   edge to edge — no backdrop bands. Behind this gate
   (body.f327), the stage's variables become the COVER
   rect (in item 3's dv units — the final fit combines
   both gates): the virtual art box grows past the
   viewport on the long axis, centred, the fixed stage
   clips the overflow, and every control and the live
   QR — all placed as fractions of those variables —
   rides the picture through the crop exactly. The
   sign-in pictures are 4:3, so at the iPad's 4:3
   screen cover == contain there; a wider or shorter
   screen crops the picture's top/bottom or sides
   symmetrically, and the QR card, the phone box and
   OK/Cancel (all measured off-centre-safe in the
   proof) stay whole. The stage's cover is scoped to
   landscape — the station's orientation — because in
   portrait a 4:3 picture covering a tall screen would
   crop into the side-seated QR card; portrait keeps
   the contain fit. The poster face (16:9 art) turns
   to background-size: cover and its live QR is
   re-mapped through the poster's own cover rect —
   the QR square and the baked Touch to Start pill
   are central in that art, so the symmetric side
   crop never reaches them. Gate OFF: no rule here
   matches, no f327 marker is emitted, and both faces
   render byte-identically to the BUILD 319 publish.
   ============================================================ */
@media (orientation: landscape) {
body.f327 .ci-wrap.ci320-stage {
    --sw: max(100dvw, 133.333dvh);
    --sh: max(75dvw, 100dvh);
    --sx: calc((100dvw - var(--sw)) / 2);
    --sy: calc((100dvh - var(--sh)) / 2);
    overflow: hidden; }
}
body.f327 .ci318-art { background-size: cover; }
body.f327 .ci318-qr {
    --sw: max(100dvw, 177.683dvh);
    --sh: max(56.280dvw, 100dvh);
    --sx: calc((100dvw - var(--sw)) / 2);
    --sy: calc((100dvh - var(--sh)) / 2); }

/* ============================================================
   BUILD 320, item 6 — OWNER REFINEMENTS (Nov 2, 2026,
   late evening), all riding this same Check327 gate;
   gate OFF every rule below is inert and the faces
   render byte-identically to the BUILD 319 publish.

   R4 — THE BUTTON ROW, REDONE (owner, Nov 2,
   2026; supersedes the R1 seat swap, which never
   shipped): on the artwork stage, every picture,
   the form's Cancel is GONE (display:none — the
   button the check315 script builds simply never
   shows on the stage), OK takes the ENTIRE row
   where the pair sat, spanning both baked pills,
   and carries a green check chip before its label
   so she knows to tap it when her number is in.
   OK's filled look and pressed change per picture
   ride its classes untouched. The return to Touch
   to Start is a BACK pill at the stage's top-left
   corner instead — built by the check315 script
   under this gate (its click is Cancel's own
   expireToRest315 landing, so the camera stream
   stays held and no permission is asked again)
   and dressed by the .ci-back327 rule below: a
   dark pill with a gold edge and cream letters,
   readable on all three pictures. The keypad's
   0/backspace row is not in the form and does
   not move.
   R2 — THE POSTER'S TWO QRs NEVER MIX: the baked
   card in station-poster-dark.png measures left
   .4450 / top .7407 / right .5658 / bottom .9129 of
   the art — far bigger than the live code's .070
   square, so the baked pattern showed around it.
   The live overlay becomes an opaque card (the
   baked card's own near-white) covering the baked
   card completely with a small margin on every
   side, and the live code — unchanged in size —
   sits centred in it: exactly one QR is visible,
   and it is the live one.
   R3 — THE TOUCH TO START BAND GLOWS, AND THE
   GLOW TRAVELS: an overlay ring rides the baked
   pill's gold edge (the pill measures left .2835 /
   top .5133 / right .7273 / bottom .7078 of the
   art; the ring sits on the rim between that edge
   and the cream fill). A conic highlight runs
   around the ring continuously (the screen-saver
   face's gentle motion), with a soft drop glow.
   The ring is a ::after on the rest face: no
   markup, no layout shift, pointer-events none —
   a touch anywhere still starts sign-in. Where
   @property is unavailable the highlight simply
   rests at its start point; the band still reads.
   ============================================================ */
/* R4 — Cancel gone from the stage, OK alone on
   the row with its green check chip, and the
   Back pill's dress. */
body.f327 .ci320-stage #ciPhoneForm
    .ci-ok.ci-cancel315 { display: none; }
body.f327 .ci320-stage #ciPhoneForm .ci-ok::before {
    content: "✓"; display: inline-block;
    width: 1.45em; height: 1.45em; line-height: 1.45em;
    margin-right: .45em; vertical-align: -.3em;
    border-radius: 50%; background: #fffdf6;
    color: #1d9e4b; font-weight: 900;
    text-align: center; }
body.f327 .ci320-stage .ci-back327 {
    position: absolute; z-index: 6;
    left: calc(var(--sx) + var(--sw) * 0.028);
    top: calc(var(--sy) + var(--sh) * 0.030);
    padding: calc(var(--sh) * 0.012)
        calc(var(--sw) * 0.020);
    border-radius: 999px;
    background: rgba(26, 13, 6, .66);
    border: 1.5px solid rgba(233, 188, 95, .95);
    color: #ffeecb;
    font-size: calc(var(--sh) * 0.026);
    font-weight: 700; cursor: pointer;
    font-family: inherit; }
body.f327 .ci320-stage .ci-back327:active {
    background: rgba(124, 21, 48, .85); }
/* R2 — the opaque backing card over the baked QR. */
body.f327 .ci318-qr {
    left: calc(var(--sx) + var(--sw) * 0.4330);
    top: calc(var(--sy) + var(--sh) * 0.7194);
    width: calc(var(--sw) * 0.1448);
    height: calc(var(--sh) * 0.2148);
    background: #fffdf8;
    border-radius: calc(var(--sw) * 0.012);
    display: flex; align-items: center;
    justify-content: center; }
body.f327 .ci318-qr svg { width: 48.3%;
    height: auto; }
/* R3 — the travelling glow on the pill's gold band. */
@property --ci327a { syntax: "<angle>";
    initial-value: 0deg; inherits: false; }
@keyframes ci327travel { to { --ci327a: 360deg; } }
body.f327 .cir::after {
    content: ""; position: absolute; z-index: 3;
    pointer-events: none;
    --sw: max(100dvw, 177.683dvh);
    --sh: max(56.280dvw, 100dvh);
    --sx: calc((100dvw - var(--sw)) / 2);
    --sy: calc((100dvh - var(--sh)) / 2);
    left: calc(var(--sx) + var(--sw) * 0.2846);
    top: calc(var(--sy) + var(--sh) * 0.5159);
    width: calc(var(--sw) * 0.4416);
    height: calc(var(--sh) * 0.1911);
    border-radius: 999px;
    padding: 3px;
    background: conic-gradient(from var(--ci327a),
        rgba(255, 214, 120, 0) 0deg,
        rgba(255, 214, 120, 0) 245deg,
        rgba(255, 226, 150, .95) 302deg,
        rgba(255, 250, 224, 1) 320deg,
        rgba(255, 226, 150, .95) 338deg,
        rgba(255, 214, 120, 0) 360deg);
    -webkit-mask: linear-gradient(#000 0 0)
            content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask: linear-gradient(#000 0 0) content-box,
        linear-gradient(#000 0 0);
    mask-composite: exclude;
    filter: drop-shadow(0 0 6px
        rgba(255, 200, 90, .55));
    animation: ci327travel 3.6s linear infinite; }

/* ============================================================
   BUILD 320, item 6 — OWNER REFINEMENT R5 (Nov 2,
   2026, late evening; sharpens R2, same Check327
   gate): NO BAKED QR VISIBLE ANYWHERE.
   Poster: the baked card is not merely covered by
   the live code's backing — it is GONE from the
   picture. A patch in the surrounding dark marble's
   own tones (sampled from the art around the card:
   deep warm browns, lit slightly warmer toward the
   floor) sits over the baked card's whole area and
   reaches well past the live backing on every side,
   its edge feathered by its own shadow so the patch
   reads as plain poster. The margin is sized for
   the poster's slow Ken Burns breathing too: the
   art drifts a few pixels under its overlays, and
   the patch — unlike the tight R2 backing alone —
   keeps the baked pattern covered at every point
   of the drift. The live code on its white backing
   (R2) is the only QR on the face.
   Stage: the same rule on the phone step — the
   corner code (check315's card, whose chrome went
   transparent in check320 so the art's own card
   showed around the live code) gets an opaque
   near-white backing that covers each picture's
   baked square with margin on all four sides; the
   live code sits inside it with a quiet zone of
   the same white, so nothing baked shows around
   or behind it. The expansion per picture: the
   baked square's seat widened by .024 of the
   stage width, shifted half of that left and the
   matching fraction up.
   ============================================================ */
body.f327 .cir::before {
    content: ""; position: absolute; z-index: 2;
    --sw: max(100dvw, 177.683dvh);
    --sh: max(56.280dvw, 100dvh);
    --sx: calc((100dvw - var(--sw)) / 2);
    --sy: calc((100dvh - var(--sh)) / 2);
    left: calc(var(--sx) + var(--sw) * 0.4180);
    top: calc(var(--sy) + var(--sh) * 0.6880);
    width: calc(var(--sw) * 0.1800);
    height: calc(var(--sh) * 0.2620);
    border-radius: calc(var(--sw) * 0.014);
    background: linear-gradient(180deg,
        #1e1108 0%, #211307 55%, #2a180a 100%);
    box-shadow: 0 0 42px 26px
        rgba(24, 13, 6, .92); }
body.f327 .ci320-stage .ci-qr315 {
    left: calc(var(--sx) + var(--sw) * 0.863);
    top: calc(var(--sy) + var(--sh) * 0.062);
    width: calc(var(--sw) * 0.097);
    box-sizing: border-box;
    padding: calc(var(--sw) * 0.010);
    background: #fffdf8;
    border-radius: calc(var(--sw) * 0.010); }
body.f327 .ci320-stage.ci321-morning .ci-qr315 {
    left: calc(var(--sx) + var(--sw) * 0.776);
    top: calc(var(--sy) + var(--sh) * 0.424);
    width: calc(var(--sw) * 0.178); }
body.f327 .ci320-stage.ci321-afternoon .ci-qr315 {
    left: calc(var(--sx) + var(--sw) * 0.756);
    top: calc(var(--sy) + var(--sh) * 0.459);
    width: calc(var(--sw) * 0.178); }
body.f327 .ci320-stage.ci321-evening .ci-qr315 {
    left: calc(var(--sx) + var(--sw) * 0.749);
    top: calc(var(--sy) + var(--sh) * 0.433);
    width: calc(var(--sw) * 0.170); }

/* ============================================================
   BUILD 320, item 6 — OWNER REFINEMENT R7 (Nov 3,
   2026; replaces the withdrawn R6): A NEW REST-FACE
   POSTER. The owner supplied fresh art
   (station-poster-gold.png, 1448x1086 — 4:3, dark
   marble and gold flowers, "Welcome", a big glowing
   Touch to Start pill, and NO baked QR anywhere:
   the marble under the pill is clean). Behind this
   gate the face paints the new poster instead of
   station-poster-dark.png; everything else about
   the face is unchanged — Ken Burns breathing,
   touch-anywhere wake, the camera dot, and the
   live QR at its usual seat under the pill
   (bottom-centre) on the R2 opaque backing, still
   the only code on the face. Because the art has
   no baked QR, R5's marble patch is RETIRED on
   this face (display:none — nothing to hide), and
   because the art is 4:3, the poster's cover rect
   is the stage's own formula, so the R2/R3 overlays
   below restate their variables to it. R3's
   travelling glow re-maps to the new pill, which
   measures (outer gold edge, from the file) left
   .205 / top .495 / right .790 / bottom .715 —
   higher and wider than the old poster's pill.
   The old poster asset stays in the publish: with
   this gate off the face still paints it, exactly
   as the BUILD 319 publish does.
   ============================================================ */
body.f327 .ci318-art {
    background-image:
        url("/images/station-poster-gold.png"); }
body.f327 .ci318-qr {
    --sw: max(100dvw, 133.333dvh);
    --sh: max(75dvw, 100dvh);
    --sx: calc((100dvw - var(--sw)) / 2);
    --sy: calc((100dvh - var(--sh)) / 2); }
/* R7: no baked QR in the new art — R5's patch is
   retired on this face. */
body.f327 .cir::before { display: none; }
/* R7: the travelling glow on the NEW pill's band. */
body.f327 .cir::after {
    --sw: max(100dvw, 133.333dvh);
    --sh: max(75dvw, 100dvh);
    --sx: calc((100dvw - var(--sw)) / 2);
    --sy: calc((100dvh - var(--sh)) / 2);
    left: calc(var(--sx) + var(--sw) * 0.2000);
    top: calc(var(--sy) + var(--sh) * 0.4900);
    width: calc(var(--sw) * 0.5940);
    height: calc(var(--sh) * 0.2280); }

/* ============================================================
   BUILD 322 — check330 STATION TAP FEEDBACK: the visual
   layer of the tap feedback (the WebAudio click + the
   guarded navigator.vibrate(10) live in site.js). Every
   rule hangs off body.f330 (the layout emits that marker
   only while Features:Check330 shows), so gate-off pages
   render exactly as the BUILD 321 publish. The dip is a
   quick press-down ADDED to each control's existing look:
   a small scale + a shadow shift + a touch of brightness.
   It never sets a background or colour, so the daypart
   pressed-colour rules (check320/327: morning / afternoon
   / evening-gold) keep full ownership of what a pressed
   control looks like — the dip only moves it. The dip
   class itself (.ci330-dip) is added by site.js on
   pointerdown, holds while the finger is down, and
   lifts just after the release.
   ============================================================ */
body.f330 .ci-key,
body.f330 .ci-ok,
body.f330 .ci-back327,
body.f330 .ci-pills .slot,
body.f330 .ci-startover {
    transition: transform .07s ease, filter .07s ease,
        box-shadow .07s ease;
}
body.f330 .ci330-dip {
    transform: scale(.965) translateY(1px);
    filter: brightness(.985);
    box-shadow: 0 2px 7px rgba(80, 35, 20, .28),
        inset 0 2px 5px rgba(80, 35, 20, .16) !important;
}
/* The full-screen faces never scale — an edge would
   show. Their start tap takes a brief brightness pulse
   on the same class instead. */
body.f330 #ciRest.ci330-dip,
body.f330 #ciWelcome.ci330-dip {
    transform: none;
    box-shadow: none !important;
    filter: brightness(1.07);
}

/* ============================================================
   BUILD 323 — check331 (owner bug report, Nov 3, 2026,
   9:22 AM, with a screenshot from his real phone on
   the LIVE site): THE PORTRAIT PHONE FIT. Root cause:
   the sign-in stage (check320/321) and its fits
   (check324's dv contain rect, check327's cover) were
   designed and proven only at LANDSCAPE iPad sizes.
   In portrait the stage stays a 4:3 letterbox centred
   in a tall screen — empty backdrop bands above and
   below, every control shrunk to a fraction of the
   small box (at 390x844: keys 57x25 px, the phone box
   171x29 px) — and the error box, whose words are
   FIXED-size (18 px text, 12 px padding) inside a
   stage-fraction seat 171 px wide, wraps five lines
   tall and lands on the phone box and the keypad's
   first rows (reproduced in diag/check323: the
   message covers the phone box and rows 1-2 whole;
   on the owner's phone the stage rendered wider than
   the screen on top of that, clipping the art's
   sides and pushing a panel past the right edge).
   The rest face overflows the same way: check327's
   background-size: cover on the poster art is NOT
   orientation-scoped (only the stage's cover is), so
   in portrait the 4:3 poster scales to the screen's
   height and its Touch to Start pill crops off both
   edges.
   THE FIX, behind this build's gate (body.f331) and
   inside a portrait/narrow media query only —
   landscape never matches it, so the approved iPad
   rendering is untouched by construction: the
   stage's variables become THE VIEWPORT ITSELF
   (--sw 100dvw, --sh 100dvh, origin 0,0), so no
   stage can ever be wider than the screen again;
   the daypart art paints WHOLE across the top at
   its natural 4:3 (the greeting and heading ride
   it, fully visible); and the real controls take
   stacked portrait seats as fractions of the screen
   through the same variables — phone box under the
   art, the error in a RESERVED seat under the phone
   box (its worst wrap ends well above the pad, so
   it can never cover a key), the keypad at phone
   size, the OK row under it, the live QR back over
   each picture's baked square inside the art band,
   the Back pill at phone size in the top-left. The
   poster face returns to its contain fit (BUILD
   318's own portrait behaviour) with its live QR
   and travelling glow re-mapped through the contain
   rect. Seats are shared across the three dayparts
   (nothing baked needs riding below the art band;
   the pictures' own dresses and pressed colours are
   untouched) — the daypart selectors below exist so
   the seats outrank each picture's landscape map.
   No step, text, timing or behaviour changes.
   Gate OFF: no f331 marker, this block never
   matches, and every surface renders byte-identically
   to the BUILD 322 publish.
   ============================================================ */
@media (orientation: portrait) and (max-width: 600px) {
    /* the stage IS the screen */
    body.f331 .ci-wrap.ci320-stage {
        --sw: 100dvw;
        --sh: 100dvh;
        --sx: 0px;
        --sy: 0px;
        overflow: hidden; }
    /* the picture whole across the top */
    body.f331 .ci-wrap.ci320-stage::before {
        left: 0; top: 0;
        width: var(--sw);
        height: calc(var(--sw) * 0.75); }
    /* the check320 veil patch re-seated on the
       band (the daypart steps hide the prompt
       outright; this is the single-picture stage) */
    body.f331 .ci320-stage .ci-prompt {
        left: calc(var(--sw) * 0.285);
        top: calc(var(--sw) * 0.2415);
        width: calc(var(--sw) * 0.430);
        height: calc(var(--sw) * 0.063); }
    /* the phone box under the art */
    body.f331 .ci320-stage .ci-phonebox,
    body.f331 .ci320-stage.ci321-morning .ci-phonebox,
    body.f331 .ci320-stage.ci321-afternoon .ci-phonebox,
    body.f331 .ci320-stage.ci321-evening .ci-phonebox {
        left: calc(var(--sw) * 0.05);
        top: calc(var(--sw) * 0.75
            + var(--sh) * 0.028);
        width: calc(var(--sw) * 0.90);
        height: calc(var(--sh) * 0.076);
        padding: 0 calc(var(--sw) * 0.04); }
    body.f331 .ci320-stage .ci-digits {
        font-size: calc(var(--sw) * 0.080);
        letter-spacing: calc(var(--sw) * 0.004); }
    /* the message in its reserved seat — it ends
       above the pad at any wrap */
    body.f331 .ci320-stage .ci-error,
    body.f331 .ci320-stage.ci321-morning .ci-error,
    body.f331 .ci320-stage.ci321-afternoon .ci-error,
    body.f331 .ci320-stage.ci321-evening .ci-error {
        left: calc(var(--sw) * 0.05);
        top: calc(var(--sw) * 0.75
            + var(--sh) * 0.114);
        width: calc(var(--sw) * 0.90);
        font-size: 16px;
        padding: 10px 14px; }
    /* the keypad at phone size */
    body.f331 .ci320-stage .ci-pad,
    body.f331 .ci320-stage.ci321-morning .ci-pad,
    body.f331 .ci320-stage.ci321-afternoon .ci-pad,
    body.f331 .ci320-stage.ci321-evening .ci-pad {
        left: calc(var(--sw) * 0.05);
        top: calc(var(--sw) * 0.75
            + var(--sh) * 0.238);
        width: calc(var(--sw) * 0.90);
        height: calc(var(--sh) * 0.292);
        column-gap: calc(var(--sw) * 0.018);
        row-gap: calc(var(--sh) * 0.010); }
    /* the OK row (Cancel stays gone — check327) */
    body.f331 .ci320-stage #ciPhoneForm,
    body.f331 .ci320-stage.ci321-morning #ciPhoneForm,
    body.f331 .ci320-stage.ci321-afternoon #ciPhoneForm,
    body.f331 .ci320-stage.ci321-evening #ciPhoneForm {
        left: calc(var(--sw) * 0.05);
        top: calc(var(--sw) * 0.75
            + var(--sh) * 0.544);
        width: calc(var(--sw) * 0.90);
        height: calc(var(--sh) * 0.076); }
    /* the Back pill at phone size (its seat rides
       the stage variables to the top-left itself) */
    body.f331 .ci320-stage .ci-back327 {
        font-size: calc(var(--sw) * 0.042);
        padding: calc(var(--sh) * 0.010)
            calc(var(--sw) * 0.038); }
    /* the live QR back over each picture's baked
       square, inside the art band (the check327 R5
       seats, converted from art-rect fractions:
       tops scale by the band's 0.75) */
    body.f331 .ci320-stage .ci-qr315 {
        left: calc(var(--sw) * 0.863);
        top: calc(var(--sw) * 0.0465);
        width: calc(var(--sw) * 0.097); }
    body.f331 .ci320-stage.ci321-morning .ci-qr315 {
        left: calc(var(--sw) * 0.776);
        top: calc(var(--sw) * 0.318);
        width: calc(var(--sw) * 0.178); }
    body.f331 .ci320-stage.ci321-afternoon .ci-qr315 {
        left: calc(var(--sw) * 0.756);
        top: calc(var(--sw) * 0.344);
        width: calc(var(--sw) * 0.178); }
    body.f331 .ci320-stage.ci321-evening .ci-qr315 {
        left: calc(var(--sw) * 0.749);
        top: calc(var(--sw) * 0.325);
        width: calc(var(--sw) * 0.170); }
    /* the poster face: the whole poster fits the
       width again (contain), its QR and glow ring
       re-mapped through the contain rect */
    body.f331 .ci318-art { background-size: contain; }
    body.f331 .ci318-qr, body.f331 .cir::after {
        --sw: min(100dvw, 133.333dvh);
        --sh: min(75dvw, 100dvh);
        --sx: calc((100dvw - var(--sw)) / 2);
        --sy: calc((100dvh - var(--sh)) / 2); }
}

/* check331 (item 2): CLEANED ART — under the same gate the station art
   swaps to cleaned copies whose DRAWN keypad, drawn OK/Cancel row and
   baked QR cards were removed (the scene's own marble/floral background
   restored; brand, florals, greeting and the phone display pill are the
   original pixels — edits were composited only inside the removed
   shapes' regions). NEW filenames: the live art files are never
   overwritten, so gate-off renders the old art exactly as today (the
   check318/321 gating pattern). The gold poster was inspected and has
   NO baked QR (clean marble under the pill) — nothing to swap there;
   the DARK poster (paints only when check327 is off) did carry a baked
   QR card + caption and swaps under :not(.f327). The LIVE QR overlays
   do not move. These rules sit AFTER the portrait block above on
   purpose: its ::before shorthand resets background-image, so the
   swaps must win by source order at equal specificity. */
body.f331 .ci-wrap.ci320-stage::before { background-image: url("/images/station-signin-light-clean.png?v=12"); }
body.f331 .ci-wrap.ci320-stage.ci321-morning::before { background-image: url("/images/station-signin-morning-clean.png?v=12"); }
body.f331 .ci-wrap.ci320-stage.ci321-afternoon::before { background-image: url("/images/station-signin-afternoon-clean.png?v=12"); }
body.f331 .ci-wrap.ci320-stage.ci321-evening::before { background-image: url("/images/station-signin-evening-clean.png?v=12"); }
body.f331:not(.f327) .ci318-art { background-image: url("/images/station-poster-dark-clean.png?v=12"); }

/* ================================================================
   BUILD 324 — Check332: TWO SIGN-IN SCREENS (owner redirect,
   Nov 3, 2026: "one background for a phone and one background
   for the iPad horizontal — two separate screens"). The phone
   step no longer stretches one universal stage across every
   screen shape:
     (1) the LANDSCAPE SCREEN keeps the approved BUILD 320-323
         layout and seats, on artwork cleaned of its drawn
         display pill (the -clean2 files), so the real phone
         box is the only display on the screen;
     (2) the PHONE SCREEN — every portrait viewport — gets its
         own portrait background artwork (the -portrait files:
         the same daypart scene on top, its own marble below)
         and a native stacked layout seated in viewport units:
         display, message seat, keypad, full-row OK;
     (3) SHORT LANDSCAPE PHONES (landscape, height up to
         500px) get the landscape screen fitted BY HEIGHT —
         the whole 4:3 stage always inside the screen, the
         side bands painted with a soft marble wash sampled
         and blurred from the same daypart artwork (the
         -band files: marble only, no scene, no words) —
         instead of the cover stage that pushed Back, the
         bottom key row and OK off the screen. (Refinement,
         Nov 3, 2026: the bands first repeated the whole
         artwork — tiling the scene, its greeting and its
         polish bottle a second time; the owner caught it.)
   The rest face follows its screen: contain fit in portrait
   (as BUILD 323 set it for narrow phones, now every portrait
   width) and on short landscape phones; untouched on the
   iPad landscape screen. (Refinement 2, later the same day,
   supersedes the portrait half of that sentence: the phone
   rest face now wears its own portrait poster — see the
   Refinement 2 note inside block (2) below. Refinement 3
   added a daypart test switch at the end of this file;
   the owner ordered it removed Nov 3, 2026 and the
   BUILD 325 refinement deleted it outright — markup,
   script, marker, rules and gate.) Steps, texts, timings and behaviour
   are unchanged — presentation only. Gate OFF: no f332
   marker is emitted and no rule here matches.
   ================================================================ */

/* (1) the landscape screen on pill-free artwork */
body.f332 .ci-wrap.ci320-stage::before { background-image: url("/images/station-signin-light-clean2.png?v=13"); }
body.f332 .ci-wrap.ci320-stage.ci321-morning::before { background-image: url("/images/station-signin-morning-clean2.png?v=13"); }
body.f332 .ci-wrap.ci320-stage.ci321-afternoon::before { background-image: url("/images/station-signin-afternoon-clean2.png?v=13"); }
body.f332 .ci-wrap.ci320-stage.ci321-evening::before { background-image: url("/images/station-signin-evening-clean2.png?v=13"); }

/* (2) THE PHONE SCREEN — portrait viewports */
@media (orientation: portrait) {
  body.f332 .ci-wrap.ci320-stage { --sw: 100dvw; --sh: 100dvh; --sx: 0px; --sy: 0px; }
  body.f332 .ci-wrap.ci320-stage::before { left: 0px; top: 0px; width: 100dvw; height: 100dvh; background-image: url("/images/station-signin-light-portrait.png?v=13"); background-size: cover; background-position: left top; }
  body.f332 .ci-wrap.ci320-stage.ci321-morning::before { background-image: url("/images/station-signin-morning-portrait.png?v=13"); }
  body.f332 .ci-wrap.ci320-stage.ci321-afternoon::before { background-image: url("/images/station-signin-afternoon-portrait.png?v=13"); }
  body.f332 .ci-wrap.ci320-stage.ci321-evening::before { background-image: url("/images/station-signin-evening-portrait.png?v=13"); }
  body.f332 .ci-wrap.ci320-stage .ci-phonebox { left: 5dvw; top: 30dvh; width: 90dvw; height: 7.6dvh; }
  body.f332 .ci-wrap.ci320-stage .ci-pad { left: 5dvw; top: 48dvh; width: 90dvw; height: 29dvh; }
  body.f332 .ci-wrap.ci320-stage #ciPhoneForm { left: 5dvw; top: 79dvh; width: 90dvw; height: 7.6dvh; }
  body.f332 .ci-wrap.ci320-stage .ci-qr315 { left: auto; right: 4dvw; top: 17dvh; width: 10.5dvh; }
  body.f332 .ci-wrap.ci320-stage.ci321-morning .ci-phonebox { left: 5dvw; top: 30dvh; width: 90dvw; height: 7.6dvh; }
  body.f332 .ci-wrap.ci320-stage.ci321-morning .ci-pad { left: 5dvw; top: 48dvh; width: 90dvw; height: 29dvh; }
  body.f332 .ci-wrap.ci320-stage.ci321-morning #ciPhoneForm { left: 5dvw; top: 79dvh; width: 90dvw; height: 7.6dvh; }
  body.f332 .ci-wrap.ci320-stage.ci321-morning .ci-qr315 { left: auto; right: 4dvw; top: 17dvh; width: 10.5dvh; }
  body.f332 .ci-wrap.ci320-stage.ci321-afternoon .ci-phonebox { left: 5dvw; top: 30dvh; width: 90dvw; height: 7.6dvh; }
  body.f332 .ci-wrap.ci320-stage.ci321-afternoon .ci-pad { left: 5dvw; top: 48dvh; width: 90dvw; height: 29dvh; }
  body.f332 .ci-wrap.ci320-stage.ci321-afternoon #ciPhoneForm { left: 5dvw; top: 79dvh; width: 90dvw; height: 7.6dvh; }
  body.f332 .ci-wrap.ci320-stage.ci321-afternoon .ci-qr315 { left: auto; right: 4dvw; top: 17dvh; width: 10.5dvh; }
  body.f332 .ci-wrap.ci320-stage.ci321-evening .ci-phonebox { left: 5dvw; top: 30dvh; width: 90dvw; height: 7.6dvh; }
  body.f332 .ci-wrap.ci320-stage.ci321-evening .ci-pad { left: 5dvw; top: 48dvh; width: 90dvw; height: 29dvh; }
  body.f332 .ci-wrap.ci320-stage.ci321-evening #ciPhoneForm { left: 5dvw; top: 79dvh; width: 90dvw; height: 7.6dvh; }
  body.f332 .ci-wrap.ci320-stage.ci321-evening .ci-qr315 { left: auto; right: 4dvw; top: 17dvh; width: 10.5dvh; }
  body.f332 .ci-wrap.ci320-stage .ci-digits { font-size: calc(100dvw * 0.080); }
  body.f332 .ci-wrap.ci320-stage .ci-error { left: 5dvw; top: 39.5dvh; width: 90dvw; font-size: 16px; padding: 10px 14px; }
  body.f332 .ci-wrap.ci320-stage .ci-prompt { left: 30dvw; top: 11.5dvh; width: 43dvw; height: 4dvh; }
  body.f332 .ci-wrap.ci320-stage .ci-back327 { font-size: calc(100dvw * 0.042); }
  /* the rest face on the phone screen — Refinement 2
     (owner, Nov 3, 2026: "iPhone background is wrong"):
     the wide poster letterboxed into a strip over black
     is replaced by its own PORTRAIT poster
     (station-poster-gold-portrait.png, 1170x2534: the
     gold poster recomposed into portrait from its own
     art — scene whole on top, its dark marble and floor
     reflection extended below, sub-line ROWLETT per his
     word). Wider portrait screens contain-fit it over
     the face's dark ground; phone widths cover-fit it
     (the next block) — its 0.4618 aspect IS the phone
     aspect, so the fit is exact and full-frame: no
     bands, nothing cropped. Seats are fractions of the
     painted rect: the pill's outer gold edge measures
     left .205 / top .172 / right .790 / bottom .248 of
     the portrait poster; the live QR card hangs BELOW
     the pill with a clear gap (his word: the code sits
     a little lower), fully inside the poster's floor
     area. The camera arm dot does not ride this face —
     seated over the portrait composition it floated
     mid-screen as a stray gold dot; it returns on every
     step after the wake and is untouched on the desk
     face. */
  body.f332 .cir .ci318-art { background-image: url("/images/station-poster-gold-portrait.png?v=14"); background-size: contain; }
  body.f332 .ci318-qr { --sw: min(100dvw, 46.18dvh); --sh: min(216.54dvw, 100dvh); --sx: calc((100dvw - var(--sw)) / 2); --sy: calc((100dvh - var(--sh)) / 2); left: calc(var(--sx) + var(--sw) * 0.3500); top: calc(var(--sy) + var(--sh) * 0.2850); width: calc(var(--sw) * 0.3000); height: calc(var(--sw) * 0.3340); }
  body.f332 .cir::after { --sw: min(100dvw, 46.18dvh); --sh: min(216.54dvw, 100dvh); --sx: calc((100dvw - var(--sw)) / 2); --sy: calc((100dvh - var(--sh)) / 2); left: calc(var(--sx) + var(--sw) * 0.2000); top: calc(var(--sy) + var(--sh) * 0.1690); width: calc(var(--sw) * 0.5940); height: calc(var(--sh) * 0.0820); }
  body.f332 .cir:not(.cir-off) ~ .ci-armdot257 { display: none; }
  body.f332 .ci318-qr svg { width: 72%; }
}

/* Refinement 2, phone widths: the portrait poster
   cover-fits — an exact full-frame fit at the phone
   aspect, so the poster fills the whole screen. */
@media (orientation: portrait) and (max-width: 600px) {
  body.f332 .cir .ci318-art { background-size: cover; }
  body.f332 .ci318-qr, body.f332 .cir::after { --sw: max(100dvw, 46.18dvh); --sh: max(216.54dvw, 100dvh); --sx: calc((100dvw - var(--sw)) / 2); --sy: calc((100dvh - var(--sh)) / 2); }
}

/* (3) SHORT LANDSCAPE PHONES — the landscape screen fitted by height */
@media (orientation: landscape) and (max-height: 500px) {
  body.f332 .ci-wrap.ci320-stage { --sw: 133.333dvh; --sh: 100dvh; --sx: calc((100dvw - 133.333dvh) / 2); --sy: 0px; background-image: url("/images/station-signin-light-band.png?v=13"); background-size: cover; background-position: center; box-shadow: inset 0 0 18dvh rgba(0, 0, 0, 0.45); }
  body.f332 .ci-wrap.ci320-stage.ci321-morning { background-image: url("/images/station-signin-morning-band.png?v=13"); background-size: cover; background-position: center; }
  body.f332 .ci-wrap.ci320-stage.ci321-afternoon { background-image: url("/images/station-signin-afternoon-band.png?v=13"); background-size: cover; background-position: center; }
  body.f332 .ci-wrap.ci320-stage.ci321-evening { background-image: url("/images/station-signin-evening-band.png?v=13"); background-size: cover; background-position: center; }
  body.f332 .ci-wrap.ci320-stage .ci-error { font-size: calc(var(--sh) * 0.034); padding: calc(var(--sh) * 0.012) calc(var(--sw) * 0.018); }
  body.f332 .cir .ci318-art { background-size: contain; }
  body.f332 .ci318-qr, body.f332 .cir::after { --sw: min(100dvw, 133.333dvh); --sh: min(75dvw, 100dvh); --sx: calc((100dvw - var(--sw)) / 2); --sy: calc((100dvh - var(--sh)) / 2); }
}


/* ================================================================
   BUILD 325 — Check334 (owner, Nov 3, 2026): ONE KEYPAD SCREEN
   for everyone, on the owner's own fall artwork — and the
   Touch to Start step is REMOVED. He supplied finished art and
   rejected every machine-derived poster ("horrible"), so the
   two EMPTY pictures he generated are used 100%, untouched:
     portrait screens:  station-signin-fall-portrait.png
                        (1284x2778 — medallion, ROWLETT,
                        Welcome over dark marble, fall still
                        life along the bottom)
     landscape screens: station-signin-fall-landscape.jpg
                        (2360x1640 — the same scene composed
                        wide: brand column on the left, the
                        control ground on the right)
   The with-keypad pictures he sent with them are the design
   of record for the LIVE controls (never shipped — their
   keypad and QR are baked): a wide glowing display pill,
   glowing dark-brown pill keys with gold rims and cream
   numerals (portrait: the last row is two wide keys, 0 and
   backspace; wide: 0 spans the first two columns), a bright
   gold OK bar with the white circle + green check, and the
   LIVE minted QR on a white card in the upper right beside
   "Please sign in:". Every seat below is a fraction of the
   painted picture, measured from those two references
   (tolerance notes in diag/check325/PROOF.md). The artwork
   is a single fall set — it does NOT swap by daypart while
   this gate displays.
   THE REST FACE IS NEVER PAINTED while the gate shows (the
   #ciRest rule below): the page opens straight on the
   keypad, and every return that used to land on the face —
   the check315 hesitation return (it clears the entry in
   place), the check326 welcome return (a fresh load) —
   lands on this keypad screen. The rest STATE MACHINE is
   untouched: the desk still rests underneath (the
   scan-completion poll runs at rest, the camera duty cycle
   and the session clips behave exactly as before), and the
   gated script in CheckIn.cshtml forwards the flow's first
   touch to the overlay's own wake handlers so the wake,
   the camera start and the session start happen exactly as
   the wake tap made them happen.
   Seats are written twice where the stacked gates demand
   it: a plain body.f334 selector (this gate alone) and a
   .ci320-stage-augmented twin that ties the f332/f321
   stacked specificities and wins on file order — the same
   stacking discipline BUILD 324 used. Gate OFF: no f334
   marker is emitted, no rule here matches, and every
   surface renders byte-identically to the BUILD 324 final
   publish.
   ================================================================ */

/* the Touch to Start face is never painted */
body.f334 #ciRest { display: none; }
/* the camera arm dot keeps its corner on this screen —
   the f263 centred seat (and its rest-face seat) would
   park it on the medallion or the keypad here */
body.f334 .ci-armdot257,
body.f334 .cir ~ .ci-armdot257,
body.f334 .cir:not(.cir-off) ~ .ci-armdot257 {
    top: auto; bottom: 2px; left: 2px; transform: none; }

/* ---- the stage: landscape picture, cover fit ---- */
body.f334 .ci-band:has(+ .ci-wrap.ci334-stage) { display: none; }
body.f334 .ci-wrap.ci334-stage {
    --sw: max(100dvw, 143.90dvh);
    --sh: max(69.49dvw, 100dvh);
    --sx: calc((100dvw - var(--sw)) / 2);
    --sy: calc((100dvh - var(--sh)) / 2);
    position: fixed; inset: 0; z-index: 30;
    max-width: none; margin: 0; padding: 0;
    overflow: hidden; background: #150a05; }
body.f334 .ci-wrap.ci334-stage::before,
body.f334 .ci-wrap.ci320-stage.ci334-stage::before,
body.f334 .ci-wrap.ci320-stage.ci321-morning.ci334-stage::before,
body.f334 .ci-wrap.ci320-stage.ci321-afternoon.ci334-stage::before,
body.f334 .ci-wrap.ci320-stage.ci321-evening.ci334-stage::before {
    content: ""; position: absolute; z-index: 0;
    left: var(--sx); top: var(--sy);
    width: var(--sw); height: var(--sh);
    background: url("/images/station-signin-gold-landscape.jpg?v=326")
        center / 100% 100% no-repeat;
    pointer-events: none; }
body.f334 .ci-wrap.ci334-stage .ci-h1,
body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-h1 { display: none; }

/* "Please sign in:" — the references carry the line as
   part of the composed screen; the empty pictures omit
   it, so the step's own prompt line wears its seat and
   dress (cream serif, over the art's dark ground). */
body.f334 .ci-wrap.ci334-stage .ci-prompt,
body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-prompt {
    display: block; position: absolute; z-index: 1;
    left: calc(var(--sx) + var(--sw) * 0.388);
    top: calc(var(--sy) + var(--sh) * 0.078);
    width: calc(var(--sw) * 0.374);
    height: auto;
    margin: 0; padding: 0; background: none;
    font-family: Georgia, "Times New Roman", serif;
    font-weight: 700; text-align: center;
    font-size: calc(var(--sw) * 0.0205);
    line-height: 1.15; color: #fff3d6;
    text-shadow: 0 2px 14px rgba(0, 0, 0, 0.55);
    pointer-events: none; }

/* the display pill */
body.f334 .ci-wrap.ci334-stage .ci-phonebox,
body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-phonebox {
    position: absolute; z-index: 1;
    left: calc(var(--sx) + var(--sw) * 0.388);
    top: calc(var(--sy) + var(--sh) * 0.172);
    width: calc(var(--sw) * 0.374);
    height: calc(var(--sh) * 0.076);
    margin: 0; padding: 0 calc(var(--sw) * 0.02);
    background: linear-gradient(180deg, #3a1d09, #241103);
    border: 2px solid #f0a832; border-radius: 999px;
    box-shadow: 0 0 22px rgba(255, 170, 50, 0.55),
        inset 0 2px 10px rgba(0, 0, 0, 0.65),
        inset 0 0 0 3px rgba(120, 60, 10, 0.35); }
body.f334 .ci-wrap.ci334-stage .ci-digits,
body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-digits {
    font-size: calc(var(--sw) * 0.021);
    color: #ffe9bd; letter-spacing: calc(var(--sw) * 0.004); }
body.f334 .ci-wrap.ci334-stage .ci-digits .dim,
body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-digits .dim {
    color: rgba(255, 205, 130, 0.38); }

/* the message seat: the art's empty left column —
   it never covers a key, the display or OK */
body.f334 .ci-wrap.ci334-stage .ci-error,
body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-error {
    position: absolute; z-index: 2;
    left: calc(var(--sx) + var(--sw) * 0.055);
    top: calc(var(--sy) + var(--sh) * 0.440);
    width: calc(var(--sw) * 0.240); margin: 0; }

/* the keypad */
body.f334 .ci-wrap.ci334-stage .ci-pad,
body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-pad {
    position: absolute; z-index: 1;
    left: calc(var(--sx) + var(--sw) * 0.398);
    top: calc(var(--sy) + var(--sh) * 0.258);
    width: calc(var(--sw) * 0.372);
    height: calc(var(--sh) * 0.272);
    margin: 0; display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: repeat(4, 1fr);
    column-gap: calc(var(--sw) * 0.024);
    row-gap: calc(var(--sh) * 0.016); }
body.f334 .ci-wrap.ci334-stage .ci-key,
body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-key {
    height: auto; min-height: 0;
    background: linear-gradient(180deg, #4a2410, #2e1507);
    border: 2px solid #e39a2d; border-radius: 999px;
    color: #fff3da; font-weight: 600;
    font-size: calc(var(--sh) * 0.052);
    box-shadow: 0 0 14px rgba(255, 166, 40, 0.45),
        0 4px 10px rgba(0, 0, 0, 0.5),
        inset 0 1px 0 rgba(255, 210, 130, 0.5);
    cursor: pointer; }
body.f334 .ci-wrap.ci334-stage .ci-key:active,
body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-key:active {
    background: linear-gradient(180deg, #f7b733, #dd8a1c);
    color: #3a1c05; border-color: #ffd873; }
body.f334 .ci-wrap.ci334-stage .ci-keyblank,
body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-keyblank {
    display: none; }
body.f334 .ci-wrap.ci334-stage .ci-key[data-k="0"],
body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-key[data-k="0"] {
    grid-column: 1 / 3; }

/* the OK bar */
body.f334 .ci-wrap.ci334-stage #ciPhoneForm,
body.f334 .ci-wrap.ci320-stage.ci334-stage #ciPhoneForm {
    position: absolute; z-index: 1;
    left: calc(var(--sx) + var(--sw) * 0.398);
    top: calc(var(--sy) + var(--sh) * 0.538);
    width: calc(var(--sw) * 0.372);
    height: calc(var(--sh) * 0.070);
    margin: 0; display: flex;
    gap: calc(var(--sw) * 0.016); }
body.f334 .ci-wrap.ci334-stage #ciPhoneForm .ci-ok,
body.f334 .ci-wrap.ci320-stage.ci334-stage #ciPhoneForm .ci-ok {
    flex: 1 1 auto; width: auto; margin: 0;
    min-height: 0; padding: 0 calc(var(--sw) * 0.02);
    display: flex; align-items: center;
    justify-content: center;
    gap: calc(var(--sw) * 0.018);
    background: linear-gradient(180deg, #ffd873,
        #f5a623 55%, #e8930c);
    border: 2px solid #ffcf6e; border-radius: 999px;
    color: #4a2403;
    font-family: Georgia, "Times New Roman", serif;
    font-weight: 700;
    font-size: calc(var(--sh) * 0.048);
    box-shadow: 0 0 26px rgba(255, 180, 60, 0.65),
        0 8px 22px rgba(0, 0, 0, 0.5);
    cursor: pointer; }
body.f334 .ci-wrap.ci334-stage #ciPhoneForm .ci-ok::before,
body.f334 .ci-wrap.ci320-stage.ci334-stage #ciPhoneForm .ci-ok::before {
    content: ""; flex: 0 0 auto;
    width: calc(var(--sh) * 0.042);
    height: calc(var(--sh) * 0.042);
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 40'%3E%3Ccircle cx='20' cy='20' r='19' fill='white'/%3E%3Cpath d='M11 21l6 6 12-13' stroke='%232fae4e' stroke-width='5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")
        center / contain no-repeat; }
body.f334 .ci-wrap.ci334-stage #ciPhoneForm .ci-ok:active,
body.f334 .ci-wrap.ci320-stage.ci334-stage #ciPhoneForm .ci-ok:active {
    background: linear-gradient(180deg, #f5a623, #d97c06);
    color: #331a02; }
/* check315's Cancel is REMOVED on this screen
   (BUILD 325 refinement 2 — the owner struck it):
   the gate's script block in CheckIn.cshtml takes
   the element out of the DOM while the gate shows,
   OK stands alone at the bar's full width as in the
   references, and no dress rule for Cancel remains
   in this section. The Back pill (check327) carries
   Cancel's behaviour — the same expireToRest315
   landing, clear + rest. */

/* the live QR card, upper right beside the prompt —
   the reference's seat; its baked caption in the
   references is the card's whole label, so the live
   caption hides and the card is the code alone */
body.f334 .ci-wrap.ci334-stage .ci-qr315,
body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-qr315 {
    position: absolute; z-index: 2;
    left: calc(var(--sx) + var(--sw) * 0.789);
    top: calc(var(--sy) + var(--sh) * 0.098);
    width: calc(var(--sw) * 0.120);
    background: #fffdf8;
    border-radius: calc(var(--sw) * 0.008);
    padding: calc(var(--sw) * 0.006);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45); }
body.f334 .ci-wrap.ci334-stage .ci-qr315-t,
body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-qr315-t { display: none; }

/* ---- SHORT LANDSCAPE PHONES: the landscape screen
   fitted by height. The side bands are a plain dark
   continuation of the picture's own edge tone with a
   soft vignette — no band picture is derived from the
   owner's art (his use-100% rule), so nothing can
   repeat on them: no words, no scene. ---- */
@media (orientation: landscape) and (max-height: 500px) {
  body.f334 .ci-wrap.ci334-stage {
      --sw: 143.90dvh; --sh: 100dvh;
      --sx: calc((100dvw - 143.90dvh) / 2); --sy: 0px;
      box-shadow: inset 0 0 18dvh rgba(0, 0, 0, 0.45); }
}

/* ---- PORTRAIT SCREENS: the iPhone picture ----
   Wider portrait screens contain-fit it over the
   stage's dark ground (the BUILD 324 Refinement 2
   rule for a portrait picture); phone widths
   cover-fit it — the picture's 0.4622 aspect IS the
   phone aspect, so the fit is exact and full-frame. */
@media (orientation: portrait) {
  body.f334 .ci-wrap.ci334-stage {
      --sw: min(100dvw, 46.22dvh);
      --sh: min(216.36dvw, 100dvh);
      --sx: calc((100dvw - var(--sw)) / 2);
      --sy: calc((100dvh - var(--sh)) / 2); }
  body.f334 .ci-wrap.ci334-stage::before,
  body.f334 .ci-wrap.ci320-stage.ci334-stage::before,
  body.f334 .ci-wrap.ci320-stage.ci321-morning.ci334-stage::before,
  body.f334 .ci-wrap.ci320-stage.ci321-afternoon.ci334-stage::before,
  body.f334 .ci-wrap.ci320-stage.ci321-evening.ci334-stage::before {
      background-image: url("/images/station-signin-fall-portrait.png?v=326"); }
  body.f334 .ci-wrap.ci334-stage .ci-prompt,
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-prompt {
      left: calc(var(--sx) + var(--sw) * 0.100);
      top: calc(var(--sy) + var(--sh) * 0.270);
      width: calc(var(--sw) * 0.560);
      text-align: left;
      font-size: calc(var(--sw) * 0.052); }
  body.f334 .ci-wrap.ci334-stage .ci-qr315,
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-qr315 {
      left: calc(var(--sx) + var(--sw) * 0.758);
      top: calc(var(--sy) + var(--sh) * 0.250);
      width: calc(var(--sw) * 0.217);
      border-radius: calc(var(--sw) * 0.018);
      padding: calc(var(--sw) * 0.014); }
  body.f334 .ci-wrap.ci334-stage .ci-phonebox,
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-phonebox {
      left: calc(var(--sx) + var(--sw) * 0.048);
      top: calc(var(--sy) + var(--sh) * 0.330);
      width: calc(var(--sw) * 0.904);
      height: calc(var(--sh) * 0.092); }
  body.f334 .ci-wrap.ci334-stage .ci-digits,
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-digits {
      font-size: calc(var(--sw) * 0.058); }
  body.f334 .ci-wrap.ci334-stage .ci-error,
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-error {
      left: calc(var(--sx) + var(--sw) * 0.115);
      top: calc(var(--sy) + var(--sh) * 0.795);
      width: calc(var(--sw) * 0.770); }
  body.f334 .ci-wrap.ci334-stage .ci-pad,
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-pad {
      left: calc(var(--sx) + var(--sw) * 0.115);
      top: calc(var(--sy) + var(--sh) * 0.437);
      width: calc(var(--sw) * 0.770);
      height: calc(var(--sh) * 0.257);
      grid-template-columns: repeat(6, 1fr);
      column-gap: calc(var(--sw) * 0.0325);
      row-gap: calc(var(--sh) * 0.0196); }
  body.f334 .ci-wrap.ci334-stage .ci-key,
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-key {
      grid-column: span 2;
      font-size: calc(var(--sw) * 0.075); }
  body.f334 .ci-wrap.ci334-stage .ci-key[data-k="0"],
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-key[data-k="0"] {
      grid-column: 1 / 4; }
  body.f334 .ci-wrap.ci334-stage .ci-key[data-k="back"],
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-key[data-k="back"] {
      grid-column: 4 / 7; }
  body.f334 .ci-wrap.ci334-stage #ciPhoneForm,
  body.f334 .ci-wrap.ci320-stage.ci334-stage #ciPhoneForm {
      left: calc(var(--sx) + var(--sw) * 0.115);
      top: calc(var(--sy) + var(--sh) * 0.715);
      width: calc(var(--sw) * 0.770);
      height: calc(var(--sh) * 0.068); }
  body.f334 .ci-wrap.ci334-stage #ciPhoneForm .ci-ok,
  body.f334 .ci-wrap.ci320-stage.ci334-stage #ciPhoneForm .ci-ok {
      font-size: calc(var(--sw) * 0.075); }
}
@media (orientation: portrait) and (max-width: 600px) {
  /* BUILD 325 refinement 2 (owner, Nov 3, 2026 —
     "Fix logo being cut off at top"): the cover fit
     this block used before centred a rect at least
     as tall as the layout viewport, and on the
     owner's iPhone the in-app browser's layout
     viewport runs taller than the visible content
     (it extends under the app's top band), so the
     rect's top — with the medallion's crown — sat
     in the hidden band (measured on his screenshot:
     the display pill lands ~26 CSS px above where
     a visible-viewport fit puts it, the signature
     of a ~50 px hidden band at the top). The phone
     fit is now a CONTAIN against the small
     viewport: the rect is never taller than
     100svh and never wider than the screen, and it
     is anchored to the top, pushed down by exactly
     the dvh-over-svh chrome difference when there
     is one. The whole picture — medallion first —
     is always on the visible screen; when the
     browser chrome hides and the viewport grows, a
     strip of the stage's dark ground can show below
     the picture, never a cropped top. */
  body.f334 .ci-wrap.ci334-stage {
      --sw: min(100dvw, 46.22svh);
      --sh: min(216.36dvw, 100svh);
      --sx: calc((100dvw - var(--sw)) / 2);
      --sy: max(0px, calc(100dvh - 100svh)); }
}

/* ---- WIDE LANDSCAPE SCREENS (PC monitors — BUILD 325
   refinement, owner Nov 3, 2026: "on PC, screen cut off").
   The base landscape fit is a COVER rect: on a screen
   wider than the picture's own 1.4390 shape (a 16:9 PC
   window is 1.778), the painted picture grows taller
   than the screen and its top and bottom are cropped
   away — the medallion's top and the "Welcome" script
   left the screen and the picture's reflective floor
   filled most of what remained. On these screens the
   picture now fits BY HEIGHT instead: the whole picture
   is always on screen, nothing cropped, and every seat
   (fractions of the same --sw/--sh rect) follows it.
   The side margins wear the same picture again, heavily
   blurred and darkened (an ambient wash, never a
   stretched copy), so the face still fills the screen
   edge to edge. At the picture's exact shape (the iPad)
   this fit and the cover fit are the same rect, so the
   desk face is unchanged; narrower landscape screens
   keep the cover fit, and short landscape phones keep
   their own fit-by-height rule above. ---- */
@media (orientation: landscape) and (min-height: 501px)
    and (min-aspect-ratio: 1439/1000) {
  body.f334 .ci-wrap.ci334-stage {
      --sw: 143.90dvh; --sh: 100dvh;
      --sx: calc((100dvw - var(--sw)) / 2); --sy: 0px; }
  body.f334 .ci-wrap.ci334-stage::after {
      content: ""; position: absolute; inset: 0; z-index: 0;
      background: url("/images/station-signin-gold-landscape.jpg?v=326")
          center / cover no-repeat;
      filter: blur(28px) brightness(0.5) saturate(1.1);
      transform: scale(1.15);
      pointer-events: none; }
  body.f334 .ci-wrap.ci334-stage::before,
  body.f334 .ci-wrap.ci320-stage.ci334-stage::before,
  body.f334 .ci-wrap.ci320-stage.ci321-morning.ci334-stage::before,
  body.f334 .ci-wrap.ci320-stage.ci321-afternoon.ci334-stage::before,
  body.f334 .ci-wrap.ci320-stage.ci321-evening.ci334-stage::before {
      z-index: 1; }
}

/* ================================================================
   BUILD 325 REFINEMENT 2 (owner, Nov 3, 2026, 4:31 PM —
   his iPhone screenshot of the DEV keypad screen):
   (1) PORTRAIT: the live QR card moves to the MIDDLE —
   centred horizontally in the free band between the
   Welcome flourish and the display pill. Its old seat
   hung off the display's top-right corner; the new one
   clears the "Please sign in:" line's glyphs (the line
   keeps the band's left side at a smaller size — the
   r2 proof measures the glyph rect against the card),
   the display and every key. The desk/landscape seat
   above is refinement 1's proven one and is NOT
   changed: on the wide picture the card never
   overlapped anything.
   (3) The Back pill (check327, built in script and
   wired to Cancel's own expireToRest315 landing) is
   seated just inside the picture's top-left corner on
   every screen — clear of the medallion's face (the
   portrait medallion starts at 30% of the width, the
   landscape one at 7.8%), the display and the QR —
   wearing its f327 dress (dark pill, gold rim),
   readable over the art's corner leaves. With the
   daypart switch deleted (refinement 1) the corner is
   free, and because the seat is written in the
   stage's own --sx/--sy fractions it follows the
   anchored picture on phones and the fit-by-height
   picture on PC screens alike.
   ================================================================ */
body.f334 .ci-wrap.ci334-stage .ci-back327,
body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-back327 {
    left: calc(var(--sx) + var(--sw) * 0.014);
    top: calc(var(--sy) + var(--sh) * 0.020);
    padding: calc(var(--sh) * 0.009)
        calc(var(--sw) * 0.014);
    font-size: calc(var(--sh) * 0.021); }
@media (orientation: portrait) {
  /* the sign-in line in the band's left zone. In the
     gate state where the line renders at all
     (check287 on, check319 off — the live PROD
     state) it is the long daypart greeting ("Good
     morning. Please sign in:"); at the old seat it
     wrapped across the band's full width and a
     centred card would have covered its glyphs.
     Here it stacks in the band's left zone (the
     art is empty there below the flourish tail),
     three short lines ending well before the card
     begins — the r2 proof measures the glyph union
     against the card in that very gate state. In
     the check319 state the line renders empty and
     the band holds the centred card alone. */
  body.f334 .ci-wrap.ci334-stage .ci-prompt,
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-prompt {
      left: calc(var(--sx) + var(--sw) * 0.060);
      top: calc(var(--sy) + var(--sh) * 0.256);
      width: calc(var(--sw) * 0.335);
      font-size: calc(var(--sw) * 0.036);
      line-height: 1.12; }
  body.f334 .ci-wrap.ci334-stage .ci-qr315,
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-qr315 {
      left: calc(var(--sx) + var(--sw) * 0.425);
      top: calc(var(--sy) + var(--sh) * 0.2535);
      width: calc(var(--sw) * 0.150); }
}
/* Cancel's belt-and-braces: the gate's script takes
   the element out of the DOM, and this rule keeps
   it from ever painting on this screen in the
   parse window before the script runs. */
body.f334 .ci-wrap.ci334-stage #ciPhoneForm .ci-ok.ci-cancel315,
body.f334 .ci-wrap.ci320-stage.ci334-stage #ciPhoneForm .ci-ok.ci-cancel315 {
    display: none; }
/* short landscape phones: the Back pill slims down
   with the small stage, so its right edge stays
   clear of the medallion's face there too */
@media (orientation: landscape) and (max-height: 500px) {
  body.f334 .ci-wrap.ci334-stage .ci-back327,
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-back327 {
      padding: calc(var(--sh) * 0.008)
          calc(var(--sw) * 0.010);
      font-size: calc(var(--sh) * 0.019); }
}

/* ================================================================
   BUILD 325 REFINEMENT 3 (owner, Nov 3, 2026 — three
   orders on the posted refinement-2 screen):
   (1) DESK QR: the live card leaves the upper right
   for the LOWER LEFT, centred on the medallion's
   column straight underneath the logo — the wide
   picture's medallion disc spans x .108–.296 of the
   art (centre .202, measured off the owner's file),
   its ROWLETT line ends at y .465 and the scene row
   under it (towel, orchid, polish) at y .60, so the
   first free seat in that column is the reflective
   floor from y .620: the card (its refinement-1
   width, .120) hangs there, clear of the Back pill,
   the display, the pad, the message box (its seat
   ends at y .57) and the scene itself. The portrait
   card keeps refinement 2's centred seat — the
   landscape media query below never matches it.
   (2) THE LAST ROW IS EVEN AGAIN: BUILD 319's
   daypart rules make the 0 and backspace keys
   position:absolute (they rode over the old
   pictures' baked wide pills), and the wrap still
   wears a ci321-* daypart class under this gate, so
   on this screen the two keys left the grid flow,
   shrank to fit-content and sat at their grid-area
   static spots — 0 narrow at the left, an empty
   middle, backspace narrow at the right, in BOTH
   orientations (the desk row showed it too). The
   f334 grid-column rules computed all along but are
   inert on absolutely-positioned items. The rescue
   below returns both keys to the flow under this
   gate only: the portrait row renders as the
   owner's reference shows it (0 and backspace, two
   wide pills splitting the row), the desk row as
   his desk reference shows it (0 spanning the first
   two columns, backspace in the third).
   (3) THE CAMERA ARM DOT IS NOT RENDERED in DEV
   view only (refinement 7, owner Nov 3, 2026,
   8:35 PM — "disable camera in dev. Only in
   prod"): the dot's only job was the camera's
   arm switch. Refinements 3-6 hid it under this
   gate wherever the gate showed — production
   included. Refinement 7 moves the hide out of
   this file into the DEV-only block in
   CheckIn.cshtml (rendered only while
   DevMode.IsActive), so a normal production
   session renders the dot — and runs the
   camera — exactly as before BUILD 325.
   (4) The Back pill sits a touch further inside the
   picture's corner, so it is fully on the picture
   on every screen (it stays in its refinement-2
   corner, over its dark pill dress).
   ================================================================ */

/* (2) the last-row rescue */
body.f334 .ci-wrap.ci334-stage .ci-key[data-k="0"],
body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-key[data-k="0"],
body.f334 .ci-wrap.ci334-stage .ci-key[data-k="back"],
body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-key[data-k="back"] {
    position: static; left: auto; right: auto;
    top: auto; bottom: auto; width: auto; height: auto; }

/* (3) refinement 7: the arm-dot hide moved to the
   DEV-only block in CheckIn.cshtml — no rule here,
   so in production the dot renders as before
   BUILD 325. */

/* (4) the Back pill, fully inside the corner */
body.f334 .ci-wrap.ci334-stage .ci-back327,
body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-back327 {
    left: calc(var(--sx) + var(--sw) * 0.018);
    top: calc(var(--sy) + var(--sh) * 0.024); }

/* (1) the desk QR card: lower left, under the logo */
@media (orientation: landscape) {
  body.f334 .ci-wrap.ci334-stage .ci-qr315,
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-qr315 {
      left: calc(var(--sx) + var(--sw) * 0.142);
      top: calc(var(--sy) + var(--sh) * 0.620); }
}

/* ================================================================
   REFINEMENT 3 (continued) — PORTRAIT PHONES: the
   owner's iPhone in its in-app browser "looks
   weird" (his Nov 3, 2026 screenshot of the posted
   refinement-2 screen): the face did not fill the
   visible width edge to edge and the stack ran too
   tall — the message box dangled below the OK bar
   over the bottom scene, crowded by the
   view-switcher pill. Two answers here:
   FIT: refinement 2 fitted the phone rect against
   100dvw horizontally; this block fits it against
   the SMALL viewport in both dimensions — the
   width the customer actually sees, with any
   dynamic chrome shown. --sw is the small width or
   the small-height-derived width, whichever is
   smaller (the picture's own shape preserved
   exactly, as a contain must); --sx centres the
   rect inside the small width and then applies the
   same dvh/dvw-over-small push refinement 2 proved
   vertically, horizontally: half the
   dynamic-over-small delta, the centred-crop
   share. On any browser where the small and
   dynamic viewports agree (every rig, desktop,
   ordinary Safari) every value here is exactly
   refinement 2's.
   STACK: the portrait stack is compressed so the
   WHOLE face — display, pad, OK and the message
   box — fits above the view-switcher pill's zone
   (the bottom ~11% of the screen): display at
   .326, pad at .428 (height .250), OK at .692, and
   the message box at .770, tucked under the OK bar
   with its foot clear of the pill zone instead of
   dangling at .795 over the scene's heart. Every
   seat stays within the proof tolerance of the
   owner's with-keypad reference photo.
   ================================================================ */
@media (orientation: portrait) and (max-width: 600px) {
  body.f334 .ci-wrap.ci334-stage {
      --sw: min(100svw, 46.22svh);
      --sh: min(216.36svw, 100svh);
      --sx: calc((100svw - var(--sw)) / 2
          + max(0px, (100dvw - 100svw) / 2));
      --sy: max(0px, calc(100dvh - 100svh)); }
  body.f334 .ci-wrap.ci334-stage .ci-phonebox,
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-phonebox {
      top: calc(var(--sy) + var(--sh) * 0.326); }
  body.f334 .ci-wrap.ci334-stage .ci-pad,
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-pad {
      top: calc(var(--sy) + var(--sh) * 0.428);
      height: calc(var(--sh) * 0.250); }
  body.f334 .ci-wrap.ci334-stage #ciPhoneForm,
  body.f334 .ci-wrap.ci320-stage.ci334-stage #ciPhoneForm {
      top: calc(var(--sy) + var(--sh) * 0.692);
      height: calc(var(--sh) * 0.066); }
  body.f334 .ci-wrap.ci334-stage .ci-error,
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-error {
      top: calc(var(--sy) + var(--sh) * 0.770); }
}

/* ================================================================
   BUILD 325 REFINEMENT 4 (owner, Nov 3, 2026, 7:02 PM —
   on the refinement-3 proof shots: "This keypad is
   not centered and same for welcome"): the DESK face's
   control block was seated right-of-centre, following
   the with-keypad reference photo's composition (the
   display spanned x .388–.762 of the picture, the pad
   and OK bar x .398–.770 — centres .575/.584). The
   owner wants the block CENTRED on the screen. The
   painted rect is itself centred on the screen in
   every landscape geometry this gate uses (cover fit,
   the wide fit-by-height branch, the short-landscape
   fit-by-height branch all centre the rect), so
   centring the seats on the rect centres them on the
   screen: display and the sign-in line keep their
   .374 width and move to left .313 (centre .500);
   the pad and the OK bar keep their .372 width and
   move to left .314 (centre .500). Vertical seats,
   widths and every other element are untouched: the
   QR card keeps its refinement-3 lower-left seat
   under the logo (its right edge, fraction .262 of
   the picture, clears the block's new left edge
   .313 by .051), the Back pill keeps the top-left
   corner, and the message box keeps its left-column
   seat (its right edge .295 clears the pad's new
   left edge .314). The picture's baked "Welcome"
   script is part of the owner's artwork and cannot
   move — it stays where the art has it (its glyphs
   span x ≈ .48–.75 of the wide picture, centre
   ≈ .616, measured off his file); the live sign-in
   line above the display is an HTML element and
   centres with the block. Portrait seats are NOT
   touched: refinement 4's proof measures them
   centred already (and the portrait picture's baked
   Welcome spans x ≈ .11–.89 of the art, centre
   ≈ .499 — centred in the art itself).
   ================================================================ */
@media (orientation: landscape) {
  body.f334 .ci-wrap.ci334-stage .ci-prompt, body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-prompt, body.f334 .ci-wrap.ci334-stage .ci-phonebox, body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-phonebox {
      left: calc(var(--sx) + var(--sw) * 0.313); }
  body.f334 .ci-wrap.ci334-stage .ci-pad, body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-pad, body.f334 .ci-wrap.ci334-stage #ciPhoneForm, body.f334 .ci-wrap.ci320-stage.ci334-stage #ciPhoneForm {
      left: calc(var(--sx) + var(--sw) * 0.314); }
}

/* ================================================================
   BUILD 325 REFINEMENT 5 (owner, Nov 3, 2026, 7:20 PM —
   "Use this image for ipad. Make the ok button with
   glow as you did in the past" + "Build it"): the DESK
   face gets the owner's NEW iPad design pair. The EMPTY
   picture ships byte-for-byte as
   station-signin-gold-landscape.jpg (1284x892 — the
   medallion + ROWLETT in a left column, a gold divider
   line at x ~.333, "Welcome" + "Please sign in:" +
   "Enter phone number or scan QR" baked at the top
   right, the towel/orchid/polish and candle scene along
   the bottom, dark marble ground); the two
   fall-landscape URL references above (the stage
   ::before and the wide branch's blurred ::after wash)
   now point at it. The with-keypad picture is the
   seat/style reference only (never shipped), measured
   off his file (fractions of the picture):
     display pill  left .407 top .268 w .446 h .089
                   (phone icon + divider at its left)
     keypad        left .420 top .378 w .417 h .372
                   (3 columns, key w .1305, gap .0125;
                   rows at .378/.474/.571/.668, key
                   h .081, row gap .016; bottom row:
                   0 spans two columns, backspace one)
     OK bar        left .454 top .768 w .290 h .080
     QR card       centre (.802, .192), width .105
                   (the baked card's own box is
                   .749/.128/.105/.128 — wider than
                   tall; the LIVE card is a square code
                   on a white card, so it is seated by
                   its centre and width and its height
                   follows the square code)
   Dressed per the reference: display and keys are
   CREAM-GOLD gradients with gold rims and DARK
   numerals; the OK bar is bright gold with the strong
   lit GLOW of the earlier builds (a pronounced layered
   gold halo) and plain dark "OK" letters — NO white
   check circle on this face (the reference has none;
   the portrait face keeps its refinement-4 OK,
   circle included). The live QR returns to the
   reference's seat at the upper right beside the
   baked "Please sign in:" (superseding refinement 3's
   lower-left seat on this face only; the portrait card
   keeps its centred seat). The HTML sign-in line
   renders NOTHING on this face — the art itself
   carries the line and its sub-line, so the prompt
   element is display:none here (its logic is intact
   for the portrait face and every other state). The
   message box moves out of the medallion column to
   the open marble floor right of the divider, below
   the OK bar (left .407, top .860, width .360 — its
   right edge .767 clears the candle scene at x .795).
   Every rule below is landscape-only and appended
   after refinements 1–4, so it wins on file order at
   equal specificity; the portrait face is untouched.
   ================================================================ */
@media (orientation: landscape) {
  /* the art carries the sign-in line — no HTML prompt
     on this face */
  body.f334 .ci-wrap.ci334-stage .ci-prompt,
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-prompt {
      display: none; }

  /* the display pill: cream-gold, gold rim, the phone
     icon + divider at its left, dark digits centred in
     the space right of the divider */
  body.f334 .ci-wrap.ci334-stage .ci-phonebox,
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-phonebox {
      left: calc(var(--sx) + var(--sw) * 0.407);
      top: calc(var(--sy) + var(--sh) * 0.268);
      width: calc(var(--sw) * 0.446);
      height: calc(var(--sh) * 0.089);
      padding: 0 calc(var(--sw) * 0.02) 0 calc(var(--sw) * 0.058);
      background: linear-gradient(180deg, #fffaf0,
          #fbeec4 40%, #f5da8e 85%, #eec978);
      border: 2px solid #e8a92c;
      box-shadow: 0 0 22px rgba(255, 180, 60, 0.45),
          inset 0 2px 6px rgba(255, 255, 255, 0.65),
          inset 0 -3px 8px rgba(170, 105, 25, 0.28); }
  body.f334 .ci-wrap.ci334-stage .ci-phonebox::before,
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-phonebox::before {
      content: ""; position: absolute;
      left: calc(var(--sw) * 0.017);
      top: 50%; transform: translateY(-50%);
      width: calc(var(--sw) * 0.024);
      height: calc(var(--sw) * 0.024);
      background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%235a3410' d='M1.885.511a1.745 1.745 0 0 1 2.61.163L6.29 2.98c.329.423.445.974.315 1.494l-.547 2.19a.68.68 0 0 0 .178.643l2.457 2.457a.68.68 0 0 0 .644.178l2.189-.547a1.75 1.75 0 0 1 1.494.315l2.306 1.794c.829.645.905 1.87.163 2.611l-1.034 1.034c-.74.74-1.846 1.065-2.877.702a18.6 18.6 0 0 1-7.01-4.42 18.6 18.6 0 0 1-4.42-7.009c-.362-1.03-.037-2.137.703-2.877z'/%3E%3C/svg%3E")
          center / contain no-repeat; }
  body.f334 .ci-wrap.ci334-stage .ci-phonebox::after,
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-phonebox::after {
      content: ""; position: absolute;
      left: calc(var(--sw) * 0.049);
      top: 50%; transform: translateY(-50%);
      width: 2px; height: 54%;
      background: rgba(122, 78, 20, 0.55);
      border-radius: 2px; }
  body.f334 .ci-wrap.ci334-stage .ci-digits,
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-digits {
      color: #4a2a10; }
  body.f334 .ci-wrap.ci334-stage .ci-digits .dim,
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-digits .dim {
      color: rgba(74, 42, 16, 0.38); }

  /* the keypad: cream-gold keys, gold rims, dark
     serif numerals; a press lights the key gold
     (the check330 dip rides on top, as before) */
  body.f334 .ci-wrap.ci334-stage .ci-pad,
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-pad {
      left: calc(var(--sx) + var(--sw) * 0.420);
      top: calc(var(--sy) + var(--sh) * 0.378);
      width: calc(var(--sw) * 0.417);
      height: calc(var(--sh) * 0.372);
      column-gap: calc(var(--sw) * 0.0125);
      row-gap: calc(var(--sh) * 0.016); }
  body.f334 .ci-wrap.ci334-stage .ci-key,
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-key {
      background: linear-gradient(180deg, #fff8dc,
          #f9e3a1 45%, #f0cd72 80%, #e9bc55);
      border: 2px solid #d99a26;
      color: #40220a;
      font-family: Georgia, "Times New Roman", serif;
      box-shadow: 0 0 14px rgba(255, 180, 60, 0.35),
          0 4px 10px rgba(0, 0, 0, 0.45),
          inset 0 1px 0 rgba(255, 255, 255, 0.75),
          inset 0 -2px 6px rgba(160, 95, 20, 0.35); }
  body.f334 .ci-wrap.ci334-stage .ci-key:active,
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-key:active {
      background: linear-gradient(180deg, #ffd873,
          #f5a623 55%, #e8930c);
      border-color: #ffd873; color: #3a1c05;
      box-shadow: 0 0 22px rgba(255, 180, 60, 0.65),
          0 4px 10px rgba(0, 0, 0, 0.45),
          inset 0 1px 0 rgba(255, 240, 200, 0.8); }

  /* the OK bar: bright gold, the strong layered GLOW
     of the earlier builds, plain dark OK letters and
     NO check circle on this face */
  body.f334 .ci-wrap.ci334-stage #ciPhoneForm,
  body.f334 .ci-wrap.ci320-stage.ci334-stage #ciPhoneForm {
      left: calc(var(--sx) + var(--sw) * 0.454);
      top: calc(var(--sy) + var(--sh) * 0.768);
      width: calc(var(--sw) * 0.290);
      height: calc(var(--sh) * 0.080); }
  body.f334 .ci-wrap.ci334-stage #ciPhoneForm .ci-ok,
  body.f334 .ci-wrap.ci320-stage.ci334-stage #ciPhoneForm .ci-ok {
      background: linear-gradient(180deg, #ffe082,
          #ffb92e 45%, #f59c0c 80%, #e8890c);
      border: 2px solid #ffd873;
      color: #4a2403;
      box-shadow: 0 0 16px rgba(255, 200, 80, 0.95),
          0 0 42px rgba(255, 170, 45, 0.80),
          0 0 84px rgba(255, 150, 30, 0.50),
          0 10px 26px rgba(0, 0, 0, 0.5),
          inset 0 2px 3px rgba(255, 255, 255, 0.8),
          inset 0 -3px 8px rgba(160, 80, 0, 0.35); }
  body.f334 .ci-wrap.ci334-stage #ciPhoneForm .ci-ok::before,
  body.f334 .ci-wrap.ci320-stage.ci334-stage #ciPhoneForm .ci-ok::before {
      display: none; }
  body.f334 .ci-wrap.ci334-stage #ciPhoneForm .ci-ok:active,
  body.f334 .ci-wrap.ci320-stage.ci334-stage #ciPhoneForm .ci-ok:active {
      background: linear-gradient(180deg, #ffb92e, #e8890c);
      color: #331a02; }

  /* the live QR card back at the reference's seat:
     upper right, beside the baked "Please sign in:",
     centred on (.802, .192) at the reference's width,
     wearing the reference's gold rim */
  body.f334 .ci-wrap.ci334-stage .ci-qr315,
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-qr315 {
      left: calc(var(--sx) + var(--sw) * 0.7495);
      top: calc(var(--sy) + var(--sh) * 0.116);
      width: calc(var(--sw) * 0.105);
      border: 2px solid #e8a92c;
      box-shadow: 0 0 18px rgba(255, 180, 60, 0.45),
          0 8px 24px rgba(0, 0, 0, 0.45); }

  /* the message box: the open marble floor right of
     the divider, below the OK bar */
  body.f334 .ci-wrap.ci334-stage .ci-error,
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-error {
      left: calc(var(--sx) + var(--sw) * 0.407);
      top: calc(var(--sy) + var(--sh) * 0.860);
      width: calc(var(--sw) * 0.360); }
}

/* ================================================
   BUILD 325 REFINEMENT 6 (owner, Nov 3, 2026,
   7:48-7:52 PM) — the desk face, three orders in
   one pass, all inside the Check334 gate (the
   f334 blocks above stay the gate-off bytes).

   1) THE FIT, DIAGNOSED AND FIXED. The owner
   photographed the PHYSICAL salon iPad ("Actual
   screen. Bad positioning"): the picture sat as
   a band across the top, a blurred streak wash
   filled the rest, and the controls shrank with
   the band. Cause: the r1 wide-screen rule
   switches the desk face to fit-by-height at any
   screen wider than the picture's own shape —
   and the salon iPad's full frame (1180x820) sits
   EXACTLY on that boundary, so the moment Safari
   shows its toolbar the visible frame (about
   1180x752) tips over it and the PC rule takes
   the desk: picture fitted by height into a
   centred band, blurred wash around it. The rigs
   only ever tested the full frame, where the two
   fits coincide. Fix: the fit is now chosen by
   how much crop covering would cost, and the
   maths runs on the VISIBLE viewport (svw/svh,
   pushed into the visible area when a browser
   reports a taller layout viewport — the r2/r3
   portrait lesson, applied to landscape):
     - screens up to 1.60x the picture's shape:
       the picture COVERS the visible screen (at
       the iPad's 1180x752 that crops about 4% of
       the picture's height top and bottom,
       symmetric — leaves and floor trim, the
       medallion and the sign-in line untouched);
     - wider than that (PC monitors): fit-by-
       height with the blurred wash, the r1
       outcome — covering there would cut the
       baked sign-in line itself;
     - narrower than the picture: cover, cropping
       the sides, as before.
   Every seat below is a fraction of the painted
   rect (--sx/--sy/--sw/--sh), so the controls
   ride the picture wherever it paints.

   2) THE PICTURE is the owner's new black-and-
   gold marble (1284x892, measured: medallion +
   ROWLETT + script Welcome in a left column,
   gold divider at x .321, "Please sign in:" at
   the top right, towels/orchid/polish bottom
   left, orchid/candle bottom right). It ships
   as station-signin-marble-landscape.png with
   ONE owner-ordered edit: the baked line "Enter
   phone number or scan QR" under "Please sign
   in:" is removed (clean marble cloned over it);
   every other pixel is his file exactly. The
   seats follow HIS with-keypad sample for this
   picture, measured off the file (fractions of
   the picture): display .356/.231/.388/.100,
   pad .357/.365/.394/.402 (cols .357/.494/.629,
   key w .124; rows .365/.465/.571/.675, key
   h .089), OK .356/.792/.389/.096, QR card
   centred (.818, .295) width .110. Dressing as
   the sample: cream display (a plain field — no
   phone icon on this face), cream-gold keys
   with dark numerals, the OK a full-width
   bright gold bar wearing the glow, plain "OK",
   the live QR beside the display. The HTML
   prompt renders nothing (the art carries
   "Please sign in:").

   3) THE RING GLOWS, MOVING (owner: "Make the
   circle around A+ glow moving"). The gate's
   script sets a .ci-ringglow334 layer on the
   stage; the rules below seat it exactly on the
   medallion's gold ring — measured off his
   file: the ring's centre is (.1745, .2752) of
   the picture and its bright band's centreline
   radius is 151px of 1284 (.1176 of the width).
   A masked conic sheen rotates around it, in
   the spirit of the BUILD 320 poster's
   travelling glow. Landscape desk face only;
   the portrait face is unchanged.
   ================================================ */

/* (0) the marble picture on the desk face. The
   ::before override carries the base rule's full
   selector list, daypart twins included — a
   plainer selector loses to them on specificity,
   however late it stands (found in proof). */
@media (orientation: landscape) {
  body.f334 .ci-wrap.ci334-stage::before, body.f334 .ci-wrap.ci320-stage.ci334-stage::before, body.f334 .ci-wrap.ci320-stage.ci321-morning.ci334-stage::before, body.f334 .ci-wrap.ci320-stage.ci321-afternoon.ci334-stage::before, body.f334 .ci-wrap.ci320-stage.ci321-evening.ci334-stage::before, body.f334 .ci-wrap.ci320-stage.ci334-stage::after {
      background-image:
        url("/images/station-signin-marble-landscape.png?v=326"); }
}

/* (1) tall landscape: cover the VISIBLE screen */
@media (orientation: landscape) and (min-height: 501px) {
  body.f334 .ci-wrap.ci320-stage.ci334-stage {
      --sw: max(100svw, 143.95svh);
      --sh: max(69.47svw, 100svh);
      --sx: calc((100svw - var(--sw)) / 2
          + max(0px, (100dvw - 100svw) / 2));
      --sy: calc(max(0px, 100dvh - 100svh)
          + (100svh - var(--sh)) / 2); }
}

/* (2) the cover band (the picture's shape up to
   1.60x): no blurred wash — the picture itself
   fills the screen */
@media (orientation: landscape) and (min-height: 501px)
    and (min-aspect-ratio: 14395/10000)
    and (max-aspect-ratio: 8/5) {
  body.f334 .ci-wrap.ci320-stage.ci334-stage::after {
      display: none; }
}

/* (3) wider than 1.60x (PC monitors): fit by
   height with the wash, the r1 outcome, in
   visible-viewport units */
@media (orientation: landscape) and (min-height: 501px)
    and (min-aspect-ratio: 8/5) {
  body.f334 .ci-wrap.ci320-stage.ci334-stage {
      --sw: 143.95svh;
      --sh: 100svh;
      --sx: calc((100svw - 143.95svh) / 2
          + max(0px, (100dvw - 100svw) / 2));
      --sy: max(0px, 100dvh - 100svh); }
  body.f334 .ci-wrap.ci320-stage.ci334-stage::after {
      display: block; }
}

/* (4) short landscape (phones): the fit-by-height
   rule restated on the new picture's shape and
   the visible viewport — same geometry the r5
   block proved */
@media (orientation: landscape) and (max-height: 500px) {
  body.f334 .ci-wrap.ci320-stage.ci334-stage {
      --sw: 143.95svh;
      --sh: 100svh;
      --sx: calc((100svw - 143.95svh) / 2
          + max(0px, (100dvw - 100svw) / 2));
      --sy: max(0px, 100dvh - 100svh); }
}

/* (5) the sample's seats on the marble face */
@media (orientation: landscape) {
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-phonebox {
      left: calc(var(--sx) + var(--sw) * 0.356);
      top: calc(var(--sy) + var(--sh) * 0.231);
      width: calc(var(--sw) * 0.388);
      height: calc(var(--sh) * 0.100);
      padding: 0 calc(var(--sw) * 0.020); }
  /* the sample's display is a plain entry field:
     no phone icon, no divider on this face */
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-phonebox::before, body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-phonebox::after { content: none; }
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-pad {
      left: calc(var(--sx) + var(--sw) * 0.357);
      top: calc(var(--sy) + var(--sh) * 0.365);
      width: calc(var(--sw) * 0.394);
      height: calc(var(--sh) * 0.402);
      column-gap: calc(var(--sw) * 0.013);
      row-gap: calc(var(--sh) * 0.0135); }
  /* the OK form: the incumbent seat rule names
     #ciPhoneForm — an element selector loses to
     the ID however late it stands (found in
     proof), so this override names it too */
  body.f334 .ci-wrap.ci334-stage #ciPhoneForm,
  body.f334 .ci-wrap.ci320-stage.ci334-stage #ciPhoneForm {
      left: calc(var(--sx) + var(--sw) * 0.356);
      top: calc(var(--sy) + var(--sh) * 0.792);
      width: calc(var(--sw) * 0.389);
      height: calc(var(--sh) * 0.096); }
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-qr315 {
      left: calc(var(--sx) + var(--sw) * 0.763);
      top: calc(var(--sy) + var(--sh) * 0.217);
      width: calc(var(--sw) * 0.110); }
  /* the message box on the open floor under the
     OK bar, clear of the candle at the right */
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-error {
      left: calc(var(--sx) + var(--sw) * 0.356);
      top: calc(var(--sy) + var(--sh) * 0.900);
      width: calc(var(--sw) * 0.380); }
  /* the Back pill steps in from the corner: at
     its old .014/.020 seat the cover crop (up to
     about 5% of the picture on the widest covered
     screens) would clip it off the visible area.
     At .058/.058 it stays on screen at every
     covered size, over the corner leaves, still
     clear of the medallion rim (top at .106) */
  body.f334 .ci-wrap.ci320-stage.ci334-stage .ci-back327 {
      left: calc(var(--sx) + var(--sw) * 0.058);
      top: calc(var(--sy) + var(--sh) * 0.058); }
}

/* (6) the medallion ring's travelling glow */
body.f334 .ci-wrap.ci320-stage.ci334-stage
    .ci-ringglow334 { display: none; }
@media (orientation: landscape) {
  body.f334 .ci-wrap.ci320-stage.ci334-stage
      .ci-ringglow334 {
      display: block;
      position: absolute;
      z-index: 1;
      pointer-events: none;
      width: calc(var(--sw) * 0.260);
      height: calc(var(--sw) * 0.260);
      left: calc(var(--sx) + var(--sw) * 0.0445);
      top: calc(var(--sy) + var(--sh) * 0.2752
          - var(--sw) * 0.130);
      border-radius: 50%;
      background:
        conic-gradient(from 0deg,
          rgba(255, 240, 200, 0) 0deg,
          rgba(255, 214, 110, 0.55) 25deg,
          rgba(255, 248, 218, 1) 45deg,
          rgba(255, 214, 110, 0.55) 65deg,
          rgba(255, 240, 200, 0) 90deg,
          rgba(255, 240, 200, 0) 360deg),
        radial-gradient(closest-side,
          rgba(255, 202, 96, 0.14),
          rgba(255, 202, 96, 0.14));
      -webkit-mask: radial-gradient(closest-side,
          transparent 80%, rgba(0, 0, 0, 0.55) 86%,
          #000 90.5%, rgba(0, 0, 0, 0.55) 95%,
          transparent 100%);
      mask: radial-gradient(closest-side,
          transparent 80%, rgba(0, 0, 0, 0.55) 86%,
          #000 90.5%, rgba(0, 0, 0, 0.55) 95%,
          transparent 100%);
      filter: blur(1.5px)
          drop-shadow(0 0 10px rgba(255, 190, 80, 0.55));
      mix-blend-mode: screen;
      animation: ciRing334spin 5.5s linear infinite; }
}
@keyframes ciRing334spin {
  to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  body.f334 .ci-wrap.ci320-stage.ci334-stage
      .ci-ringglow334 { animation: none; }
}

/* ================================================================
   BUILD 325 REFINEMENT 7 (owner, Nov 3, 2026,
   8:36 PM — his live screenshot of the portrait
   face in the in-app browser: "still a white
   strip, still shifted"). Two causes, both
   fixed:

   (1) THE FIT. Refinement 3 fitted the phone
   rect against the SMALL viewport (svw/svh).
   On the owner's phone the small-viewport
   report does not match the screen he actually
   sees: the picture painted about 362 of the
   428 CSS px wide, centred with dark stage
   ground on both sides (measured off his
   screenshot — the view-switcher pill, laid
   out in dynamic-viewport units, spans the
   full 428; the picture spans about 362,
   centred). The phone fit now sizes the rect
   from the DYNAMIC viewport — the units the
   rest of the page is laid out in and the ones
   that match the visible screen — and takes
   the FULL WIDTH: --sw is 100dvw and the rect
   keeps the picture's own shape, so on frames
   taller than the picture (the in-app browser)
   the stage's overflow crops the picture's
   bottom scene, never its top; on the plain
   Safari sizes (390x844, 430x932 — the frames
   the picture was drawn for) the fit is exact,
   as before. The refinement-2 vertical push
   stays: the top is anchored to the VISIBLE
   top, pushed down by the dynamic-over-small
   height difference when a browser reports
   one, so the medallion never slides under a
   hidden band. --sx is 0: the picture starts
   at the screen's left edge, no shift.

   (2) THE STRIP ITSELF was never only a fit
   problem: the shipped portrait artwork
   carries a baked-in white band down its own
   left edge (measured: 26 px of its 1284 px
   width, 2.02%, at every height — present in
   every publish since BUILD 325's base). No
   fit can paint it away. Refinement 7 removes
   it from the shipped file by mirroring the
   picture's own next 30 columns over the band
   (his ordered edit, the refinement-6 marble
   precedent): the pixel diff is confined to
   the band (x < 30 of 1284), the canvas, the
   aspect and every seat fraction are
   unchanged, and every other pixel is his
   file exactly.
   ================================================================ */
@media (orientation: portrait) and (max-width: 600px) {
  body.f334 .ci-wrap.ci334-stage {
      --sw: 100dvw;
      --sh: 216.36dvw;
      --sx: 0px;
      --sy: max(0px, calc(100dvh - 100svh)); }
}

/* ================================================================
   BUILD 326, item 2 (check336 — owner, Nov 3, 2026:
   "Here is my design. Use it" / "For ipad. Use
   similar for iPhone"): the first-timer ("Nice to
   meet you") step rebuilt to the owner's supplied
   design. Cream silk ground with orchid corners —
   two plates made from his design's own backdrop
   (station-first336-landscape.jpg for landscape,
   station-first336-portrait.jpg for portrait) —
   the A+ NAILS header (gold-ring A+ circle +
   letterspaced brand, hairlines either side) and
   one big cream card: the script heading, his line
   "Please enter your name and choose your
   service.", the Name field, three cream choices
   (A+ circle + Nails / Pedicure / Both + ›), the
   wide orange-to-red OK with NO check circle, and
   "Start over" underlined beneath it. The iPad
   wears the design as drawn (choices in a row);
   portrait fits the same design to the phone
   (choices stacked full width). The stage is a
   fixed full-screen ground like the welcome
   step's, below the owner's view pill (z 90).
   Every rule hangs off body.f336 + .ci336-stage,
   both emitted only while the gate shows; gate
   OFF: nothing here matches and the step renders
   exactly as the BUILD 325 publish.
   ================================================================ */
body.f336 .ci-wrap.ci336-stage {
    position: fixed; inset: 0; z-index: 60;
    max-width: none; margin: 0; padding: 0 0 40px;
    overflow-y: auto; overflow-x: hidden;
    background: #f6ecdc url("/images/station-first336-landscape.jpg?v=326") center / cover no-repeat;
    display: flex; flex-direction: column; align-items: center;
    touch-action: manipulation; }
@media (orientation: portrait) {
  body.f336 .ci-wrap.ci336-stage {
      background-image: url("/images/station-first336-portrait.jpg?v=326"); } }
body.f334.f336 .ci-band:has(+ .ci-wrap.ci336-stage), body.f336:has(.ci336-stage) .ci-armdot257 { display: none; }
body.f336 .ci336-stage .ci336-head {
    display: flex; align-items: center; gap: 18px; margin-top: 4.2vh; }
body.f336 .ci336-stage .ci336-line {
    display: block; width: min(180px, 16vw); height: 1px;
    background: linear-gradient(90deg, rgba(160,120,50,0), #b08d3e, rgba(160,120,50,0)); }
body.f336 .ci336-stage .ci336-logo {
    display: flex; align-items: center; justify-content: center;
    width: 84px; height: 84px; border-radius: 50%;
    border: 2px solid #b08d3e;
    outline: 1px solid rgba(176,141,62,.45); outline-offset: 3px;
    background: radial-gradient(circle at 35% 30%, #fffdf4, #f3e5c3);
    font-family: var(--font-display); font-size: 32px; font-weight: 600;
    color: #5d4020; }
body.f336 .ci336-stage .ci336-brand {
    font-family: var(--font-display); font-size: 29px; font-weight: 600;
    letter-spacing: .34em; margin-right: -.34em; color: #4a2f16; }
body.f336 .ci336-stage .ci336-card {
    width: min(1100px, 88%); margin-top: 3.2vh;
    background: #fffdf7; border: 1.5px solid #c2a054; border-radius: 26px;
    box-shadow: 0 24px 60px rgba(120, 84, 20, .18);
    padding: 38px 60px 34px; text-align: center; }
body.f336 .ci336-stage .ci336-script {
    font-family: "Great Vibes", cursive; font-size: 66px;
    line-height: 1.1; color: #452a12; }
body.f336 .ci336-stage .ci336-sub {
    font-family: var(--font-display); font-size: 25px;
    color: #452a12; margin-top: 10px; }
body.f336 .ci336-stage .ci336-error { margin-top: 18px; }
body.f336 .ci336-stage .ci336-label {
    display: block; text-align: left;
    font-family: var(--font-display); font-weight: 700; font-size: 27px;
    color: #3d2410; margin: 26px 0 10px; }
body.f336 .ci336-stage .ci336-textbox {
    display: block; width: 100%; height: 68px;
    border: 1.5px solid #b0823f; border-radius: 14px; background: #fff;
    padding: 0 20px; font-size: 25px; color: #3d2410; }
body.f336 .ci336-stage .ci336-textbox:focus {
    outline: 3px solid rgba(194,160,84,.45); outline-offset: 1px; }
body.f336 .ci336-stage .ci336-choices {
    display: flex; gap: 22px; margin-top: 26px; }
body.f336 .ci336-stage .ci336-choice {
    position: relative; flex: 1 1 0;
    display: flex; align-items: center; gap: 14px;
    min-height: 86px; padding: 10px 20px;
    border: 1.5px solid #c2a054; border-radius: 16px;
    background: linear-gradient(180deg, #fffaf0, #f5e6c4);
    cursor: pointer; }
body.f336 .ci336-stage .ci336-choice input {
    position: absolute; opacity: 0; pointer-events: none; }
body.f336 .ci336-stage .ci336-coin {
    flex: 0 0 auto; display: flex; align-items: center; justify-content: center;
    width: 54px; height: 54px; border-radius: 50%;
    border: 2px solid #b08d3e; background: #fdf6e0;
    font-family: var(--font-display); font-weight: 600; font-size: 21px;
    color: #6b4a1f; }
body.f336 .ci336-stage .ci336-choice-name {
    font-family: var(--font-display); font-weight: 700; font-size: 29px;
    color: #452a12; }
body.f336 .ci336-stage .ci336-chev {
    margin-left: auto; font-size: 34px; line-height: 1; color: #452a12; }
body.f336 .ci336-stage .ci336-choice:has(input:checked) {
    background: linear-gradient(180deg, #fceecb, #f2d69b);
    border-color: #a87c2a;
    box-shadow: 0 0 0 2px rgba(194,160,84,.4), 0 8px 20px rgba(150,100,20,.22); }
body.f336 .ci336-stage .ci336-choice:has(input:focus-visible) {
    outline: 3px solid rgba(194,160,84,.55); outline-offset: 2px; }
body.f336 .ci336-stage .ci336-ok {
    margin-top: 28px; display: block; width: 100%;
    border: none; border-radius: 999px; min-height: 86px; padding: 18px;
    font-size: 34px; font-weight: 700; letter-spacing: .04em; color: #fff;
    background: linear-gradient(90deg, #f59a23, #e8542f);
    box-shadow: 0 12px 26px rgba(224, 95, 12, .35);
    cursor: pointer; font-family: inherit; touch-action: manipulation; }
body.f336 .ci336-stage .ci336-ok:active { transform: translateY(1px); }
body.f336 .ci336-stage .ci336-startover {
    display: inline-block; margin-top: 24px;
    font-family: var(--font-display); font-size: 24px; font-weight: 600;
    color: #452a12; text-decoration: underline; text-underline-offset: 4px; }
/* check329-off fallback inside the design: the full
   service pill group dressed as cream rows. */
body.f336 .ci336-stage .ci336-pills { margin-top: 26px; }
body.f336 .ci336-stage .ci336-pills .slot-grid {
    display: flex; flex-direction: column; gap: 12px; }
body.f336 .ci336-stage .ci336-pills .slot {
    display: flex; align-items: center; gap: 14px;
    min-height: 64px; padding: 10px 20px; text-align: left;
    border: 1.5px solid #c2a054; border-radius: 16px;
    background: linear-gradient(180deg, #fffaf0, #f5e6c4); color: #452a12; }
body.f336 .ci336-stage .ci336-pills .svc-medal { display: none; }
body.f336 .ci336-stage .ci336-pills .slot:has(input:checked) {
    background: linear-gradient(180deg, #fceecb, #f2d69b);
    border-color: #a87c2a;
    box-shadow: 0 0 0 2px rgba(194,160,84,.4), 0 8px 20px rgba(150,100,20,.22); }
/* Portrait: the same design fitted to the phone —
   the card narrows, the three choices stack full
   width, every element keeps its place and order. */
@media (orientation: portrait) {
  body.f336 .ci336-stage .ci336-head { margin-top: 3.4vh; gap: 12px; }
  body.f336 .ci336-stage .ci336-logo { width: 62px; height: 62px; font-size: 24px; }
  body.f336 .ci336-stage .ci336-brand { font-size: 21px; }
  body.f336 .ci336-stage .ci336-line { width: 12vw; }
  body.f336 .ci336-stage .ci336-card {
      width: 92%; padding: 28px 22px 26px; border-radius: 22px; }
  body.f336 .ci336-stage .ci336-script { font-size: 47px; }
  body.f336 .ci336-stage .ci336-sub { font-size: 19px; }
  body.f336 .ci336-stage .ci336-label { font-size: 22px; margin-top: 20px; }
  body.f336 .ci336-stage .ci336-textbox { height: 58px; font-size: 22px; }
  body.f336 .ci336-stage .ci336-choices {
      flex-direction: column; gap: 14px; margin-top: 20px; }
  body.f336 .ci336-stage .ci336-choice { min-height: 66px; }
  body.f336 .ci336-stage .ci336-coin { width: 44px; height: 44px; font-size: 18px; }
  body.f336 .ci336-stage .ci336-choice-name { font-size: 24px; }
  body.f336 .ci336-stage .ci336-ok { min-height: 66px; font-size: 27px; margin-top: 22px; }
  body.f336 .ci336-stage .ci336-startover { font-size: 20px; margin-top: 18px; } }
/* Short landscape frames (the salon iPad's visible
   in-app window) compress a step so the whole card
   still fits without a scroll. */
@media (orientation: landscape) and (max-height: 780px) {
  body.f336 .ci336-stage .ci336-head { margin-top: 2.4vh; }
  body.f336 .ci336-stage .ci336-logo { width: 64px; height: 64px; font-size: 25px; }
  body.f336 .ci336-stage .ci336-card { margin-top: 2.2vh; padding: 26px 52px 24px; }
  body.f336 .ci336-stage .ci336-script { font-size: 54px; }
  body.f336 .ci336-stage .ci336-choice { min-height: 70px; }
  body.f336 .ci336-stage .ci336-ok { min-height: 68px; } }

/* ================================================================
   BUILD 327 (owner, Nov 3, 2026, 9:16–9:41 PM).

   Item 1 (gate Features:Check337): the staff NAME SEARCH
   step of the station sign-in — opened only by the
   keypad passcode 0000, never by a button. The step
   wears the ci337-stage wrap class; while Check334
   also shows, the wrap carries ci334-stage too and the
   f334 machinery paints the owner's marble / fall
   pictures and computes the painted rect
   (--sx/--sy/--sw/--sh) exactly as on the keypad
   screen — every seat below is a fraction of that
   rect, measured from the approved design
   (mockups/signin-name-search: label .356/.286, field
   .356/.342 w .50 h .096, bar .356/.485 w .50, rows
   from .475; portrait: field at the display seat
   .07/.335 w .86, rows from .445). With Check334 off
   the fallback rules at the end of this block paint
   the same pictures under the build's ?v=327 query
   (the house convention — BUILD 326 item 3: a changed
   artwork file ships under a fresh query, so a cached
   old copy can never be served again). Gate OFF: no
   f337 marker is emitted, the step never renders, and
   every surface is byte-identical to the BUILD 326
   publish.

   Item 2 (gate Features:Check338): the walk-in name +
   link card on the admin Edit screen (.wi338 — plain
   classes, no body marker; the card renders only for
   a saved anonymous walk-in while the gate shows).
   ================================================================ */

/* the top band never shows over the name step (the
   f334 rule covers the ci334-stage twin; this is the
   ci337-stage half) */
body.f337 .ci-band:has(+ .ci-wrap.ci337-stage) { display: none; }

/* the Back pill, top left of the picture — the
   keypad face's own seat (BUILD 325 refinement 6) */
body.f337 .ci-wrap.ci337-stage .ci337-back {
    position: absolute; z-index: 6;
    left: calc(var(--sx) + var(--sw) * 0.058);
    top: calc(var(--sy) + var(--sh) * 0.058);
    padding: calc(var(--sh) * 0.012) calc(var(--sw) * 0.016);
    border-radius: 999px;
    background: rgba(22, 13, 5, .55);
    border: 1.5px solid #d9a441;
    color: #f6e3ae; text-decoration: none;
    font-size: calc(var(--sw) * 0.017); font-weight: 700; }
body.f337 .ci-wrap.ci337-stage .ci337-back:active {
    background: rgba(124, 21, 48, .85); }

/* "Name" */
body.f337 .ci-wrap.ci337-stage .ci337-label {
    position: absolute; z-index: 1;
    left: calc(var(--sx) + var(--sw) * 0.356);
    top: calc(var(--sy) + var(--sh) * 0.286);
    color: #f3dfae;
    font-size: calc(var(--sw) * 0.0195);
    letter-spacing: .16em; text-transform: uppercase; }

/* the name field — the cream display dress */
body.f337 .ci-wrap.ci337-stage .ci337-field {
    position: absolute; z-index: 1;
    left: calc(var(--sx) + var(--sw) * 0.356);
    top: calc(var(--sy) + var(--sh) * 0.342);
    width: calc(var(--sw) * 0.50);
    height: calc(var(--sh) * 0.096);
    margin: 0; padding: 0 calc(var(--sw) * 0.022);
    background: linear-gradient(180deg, #fdf6e0, #f1dfae);
    border: 1.5px solid #caa14f;
    border-radius: calc(var(--sw) * 0.015);
    box-shadow: inset 0 2px 8px rgba(120, 84, 20, .25),
        0 0 18px rgba(255, 196, 64, .25);
    font-family: Georgia, "Times New Roman", serif;
    font-size: calc(var(--sw) * 0.034); color: #4a3418; }

/* the Search / Continue bar — the OK bar's dress */
body.f337 .ci-wrap.ci337-stage .ci337-bar {
    position: absolute; z-index: 1;
    left: calc(var(--sx) + var(--sw) * 0.356);
    top: calc(var(--sy) + var(--sh) * 0.485);
    width: calc(var(--sw) * 0.50);
    height: calc(var(--sh) * 0.092);
    margin: 0; padding: 0;
    display: flex; align-items: center; justify-content: center;
    background: linear-gradient(180deg, #ffd968, #e79a17);
    border: 1.5px solid #b97a0e;
    border-radius: calc(var(--sw) * 0.015);
    box-shadow: 0 0 16px rgba(255, 180, 40, .55),
        0 0 42px rgba(255, 170, 30, .35);
    font-family: Georgia, "Times New Roman", serif;
    font-size: calc(var(--sw) * 0.032); color: #3d2703;
    cursor: pointer; }
body.f337 .ci-wrap.ci337-stage .ci337-bar:active {
    background: linear-gradient(180deg, #f5a623, #d97c06); }

/* the results — cream rows under the field */
body.f337 .ci-wrap.ci337-stage .ci337-rows {
    position: absolute; z-index: 1;
    left: calc(var(--sx) + var(--sw) * 0.356);
    top: calc(var(--sy) + var(--sh) * 0.475);
    width: calc(var(--sw) * 0.50);
    max-height: calc(var(--sh) * 0.50);
    overflow-y: auto;
    display: flex; flex-direction: column;
    gap: calc(var(--sh) * 0.017); }
body.f337 .ci-wrap.ci337-stage .ci337-row {
    width: 100%; margin: 0; text-align: left; cursor: pointer;
    background: linear-gradient(180deg, #fdf6e0, #f3e2b2);
    border: 1.5px solid #caa14f;
    border-radius: calc(var(--sw) * 0.014);
    box-shadow: 0 4px 14px rgba(0, 0, 0, .4);
    padding: calc(var(--sh) * 0.018) calc(var(--sw) * 0.019); }
body.f337 .ci-wrap.ci337-stage .ci337-row:active {
    background: linear-gradient(180deg, #ffd968, #eda417); }
body.f337 .ci-wrap.ci337-stage .ci337-row-top {
    display: flex; justify-content: space-between;
    align-items: baseline; gap: calc(var(--sw) * 0.02); }
body.f337 .ci-wrap.ci337-stage .ci337-row-name {
    font-family: Georgia, "Times New Roman", serif;
    font-size: calc(var(--sw) * 0.0255); color: #4a3418; }
body.f337 .ci-wrap.ci337-stage .ci337-row-phone {
    font-size: calc(var(--sw) * 0.0186);
    color: #7a5a20; letter-spacing: .06em; }
body.f337 .ci-wrap.ci337-stage .ci337-row-last {
    display: block; margin-top: 3px;
    font-size: calc(var(--sw) * 0.017); color: #8a6a30; }

/* the medallion's travelling glow rides this step too
   (the gate's script seats the layer on any
   .ci334-stage; the f334 display rule names the
   keypad's ci320-stage twin, so this is the name
   step's own) — landscape desk face only, the r6 seat */
@media (orientation: landscape) {
  body.f337 .ci-wrap.ci337-stage .ci-ringglow334 {
      display: block;
      position: absolute; z-index: 1; pointer-events: none;
      width: calc(var(--sw) * 0.260);
      height: calc(var(--sw) * 0.260);
      left: calc(var(--sx) + var(--sw) * 0.0445);
      top: calc(var(--sy) + var(--sh) * 0.2752
          - var(--sw) * 0.130);
      border-radius: 50%;
      background:
        conic-gradient(from 0deg,
          rgba(255, 240, 200, 0) 0deg,
          rgba(255, 214, 110, 0.55) 25deg,
          rgba(255, 248, 218, 1) 45deg,
          rgba(255, 214, 110, 0.55) 65deg,
          rgba(255, 240, 200, 0) 90deg,
          rgba(255, 240, 200, 0) 360deg),
        radial-gradient(closest-side,
          rgba(255, 202, 96, 0.14),
          rgba(255, 202, 96, 0.14));
      -webkit-mask: radial-gradient(closest-side,
          transparent 80%, rgba(0, 0, 0, 0.55) 86%,
          #000 90.5%, rgba(0, 0, 0, 0.55) 95%,
          transparent 100%);
      mask: radial-gradient(closest-side,
          transparent 80%, rgba(0, 0, 0, 0.55) 86%,
          #000 90.5%, rgba(0, 0, 0, 0.55) 95%,
          transparent 100%);
      filter: blur(1.5px)
          drop-shadow(0 0 10px rgba(255, 190, 80, 0.55));
      mix-blend-mode: screen;
      animation: ciRing334spin 5.5s linear infinite; }
}
@media (prefers-reduced-motion: reduce) {
  body.f337 .ci-wrap.ci337-stage .ci-ringglow334 {
      animation: none; }
}

/* ---- PORTRAIT: the iPhone face (mockup frame 6) —
   the field wears the portrait display's dark pill at
   the display seat; the label is not drawn (the field
   itself carries the step, as on the keypad face) ---- */
@media (orientation: portrait) {
  body.f337 .ci-wrap.ci337-stage .ci337-back {
      left: calc(var(--sx) + var(--sw) * 0.05);
      top: calc(var(--sy) + var(--sh) * 0.036);
      font-size: calc(var(--sw) * 0.041); }
  body.f337 .ci-wrap.ci337-stage .ci337-label { display: none; }
  body.f337 .ci-wrap.ci337-stage .ci337-field {
      left: calc(var(--sx) + var(--sw) * 0.07);
      top: calc(var(--sy) + var(--sh) * 0.335);
      width: calc(var(--sw) * 0.86);
      height: calc(var(--sh) * 0.082);
      background: linear-gradient(180deg, #2e1c0d, #241505);
      border: 1.5px solid #d9a441; border-radius: 999px;
      box-shadow: 0 0 18px rgba(255, 196, 64, .35);
      color: #f6e3ae; font-size: calc(var(--sw) * 0.067); }
  body.f337 .ci-wrap.ci337-stage .ci337-bar {
      left: calc(var(--sx) + var(--sw) * 0.07);
      top: calc(var(--sy) + var(--sh) * 0.445);
      width: calc(var(--sw) * 0.86);
      height: calc(var(--sh) * 0.075);
      font-size: calc(var(--sw) * 0.06); }
  body.f337 .ci-wrap.ci337-stage .ci337-rows {
      left: calc(var(--sx) + var(--sw) * 0.07);
      top: calc(var(--sy) + var(--sh) * 0.445);
      width: calc(var(--sw) * 0.86);
      max-height: calc(var(--sh) * 0.52);
      gap: calc(var(--sh) * 0.014); }
  body.f337 .ci-wrap.ci337-stage .ci337-row-name {
      font-size: calc(var(--sw) * 0.059); }
  body.f337 .ci-wrap.ci337-stage .ci337-row-phone {
      font-size: calc(var(--sw) * 0.041); }
  body.f337 .ci-wrap.ci337-stage .ci337-row-last {
      font-size: calc(var(--sw) * 0.038); }
}

/* ---- FALLBACK STAGE (Check337 on, Check334 off):
   the same stage the keypad wears, painted by this
   gate alone — same pictures (under this build's
   ?v=327 query), same cover-fit rect math as the
   f334 base rules. When f334 shows, its own rules
   (earlier in this file, plus their refinement
   overrides) own the stage and these never win a
   seat they contest: every selector here carries
   :not(.f334) on the body. ---- */
body.f337:not(.f334) .ci-wrap.ci337-stage {
    --sw: max(100dvw, 143.95dvh);
    --sh: max(69.47dvw, 100dvh);
    --sx: calc((100dvw - var(--sw)) / 2);
    --sy: calc((100dvh - var(--sh)) / 2);
    position: fixed; inset: 0; z-index: 30;
    max-width: none; margin: 0; padding: 0;
    overflow: hidden; background: #150a05; }
body.f337:not(.f334) .ci-wrap.ci337-stage::before {
    content: ""; position: absolute; z-index: 0;
    left: var(--sx); top: var(--sy);
    width: var(--sw); height: var(--sh);
    background: url("/images/station-signin-marble-landscape.png?v=327")
        center / 100% 100% no-repeat;
    pointer-events: none; }
@media (orientation: portrait) {
  body.f337:not(.f334) .ci-wrap.ci337-stage {
      --sw: 100dvw; --sh: 216.36dvw;
      --sx: 0px;
      --sy: max(0px, 100dvh - 100svh); }
  body.f337:not(.f334) .ci-wrap.ci337-stage::before {
      background-image: url("/images/station-signin-fall-portrait.png?v=327"); }
}

/* ---- item 2: the walk-in name + link card ---- */
.wi338-row .cr-top { flex: 1 1 auto; display: flex;
    justify-content: space-between; align-items: baseline;
    gap: 10px; }
.wi338-confirm { margin-top: 14px; padding-top: 12px;
    border-top: 1px solid #ecd9d3; }
.wi338-confirm-line { font-size: 18px; margin: 0 0 4px; }
.wi338-confirm-sub { color: #8a7364; margin: 0 0 12px; }

/* ---- item 3 (gate Check339): the returning
   picker's verification-page dress. The stage and
   card are the welcome step's own .ci-welcome /
   .ci-veil (nothing here re-skins them — the
   picker's cascade IS the verification page's);
   these rules only make the display pills
   tappable: the checkbox rides hidden inside the
   .ci-dpill, a picked pill warms to the rose tint,
   and OK / Start over sit on the card. Gate OFF:
   no f339 class, the classic picker is untouched. */
body.f339 .ci339-pills {
    margin-top: min(26px, 3.4vh); }
body.f339 .ci339-pill {
    position: relative; cursor: pointer; }
body.f339 .ci339-pill input {
    position: absolute; opacity: 0;
    pointer-events: none; }
body.f339 .ci339-pill:has(input:checked) {
    background: #fdeee9;
    border-color: var(--rose-dark);
    box-shadow: 0 4px 14px rgba(150, 85, 95, .20); }
body.f339 .ci339-picker .ci-ok {
    margin-top: min(26px, 3.4vh); }
body.f339 .ci339-picker .ci-startover {
    display: inline-block;
    margin-top: min(16px, 2vh); }
body.f339 .ci339-picker .ci-error {
    margin-top: min(18px, 2.4vh); }

/* ---- BUILD 328, item 1 (gate Check341): the
   Admin Book grid loses the full-width horizontal
   line between time rows — the grid cells' bottom
   border, drawn across every worker column
   including the empty ones. Only that border goes:
   the columns' right borders, the table's top and
   left frame, the cards and the time buttons are
   untouched. Gate OFF: no f341 class, the Book is
   the BUILD 327 publish byte for byte. */
body.f341 .book-grid th, body.f341 .book-grid td {
    border-bottom: 0; }

/* ================================================================
   BUILD 330 (owner, Nov 3, 2026, 11:52 PM, with his
   screenshot of the app's own customer search — gate
   Features:Check346): the sign-in name search loses
   its hidden 0000 passcode (removed server-side in
   CheckIn.cshtml.cs) and gains the app's own face.
   (1) THE DOOR: a blank magnifier icon — glyph only,
   no text, no label, no chip — at the VERY TOP RIGHT
   CORNER of the keypad screen, seated in the stage's
   fractions on both faces: right edge at .982 of the
   picture (portrait: .95, the Back pill's own corner
   margin mirrored), top at .052 of the height —
   inside the corner even at the widest covered fit,
   whose crop eats about 5% at the top (the r6 Back
   pill lesson) — and clear of the display (x
   .356–.744, y .231–.331), the QR card (x .763–.873
   from y .217) and the medallion (rim ends x .296).
   The box is a real tap target (44px floor, about
   54px on the desk iPad); the glyph is a soft gold
   stroke with a dark soft shadow so it reads over
   the corner leaves, exactly the Back pill's
   situation at the opposite corner. Like the Back
   pill, the seat needs the Check334 stage; the
   name-step seats below ride the ci337-stage, so
   they also hold on 337's fallback stage.
   (2) THE SEARCH: the step's label, field and
   results wear the f337 seats; the results are the
   admin app's own rows — .pick-row / .cr-* / .coin
   (the global rules above, untouched) rendered by
   the step's script with the shared salonHistChips
   chips — so a row here is a row in the app: mark
   dot, full name, full phone, the personal note,
   the color-coded visit chips with "N days ago".
   Gate OFF: no f346 marker is emitted, no rule here
   matches, and every surface is byte-identical to
   the BUILD 329 publish.
   ================================================================ */

/* the corner search icon — landscape seat */
body.f346 .ci-wrap.ci334-stage .ci346-find {
    position: absolute; z-index: 3;
    width: max(44px, calc(var(--sw) * 0.046));
    height: max(44px, calc(var(--sw) * 0.046));
    left: calc(var(--sx) + var(--sw) * 0.982
        - max(44px, calc(var(--sw) * 0.046)));
    top: calc(var(--sy) + var(--sh) * 0.052);
    display: flex; align-items: center;
    justify-content: center;
    color: #f3d489;
    filter: drop-shadow(0 1px 3px rgba(0, 0, 0, .85))
        drop-shadow(0 0 7px rgba(0, 0, 0, .45));
    -webkit-tap-highlight-color: transparent; }
body.f346 .ci-wrap.ci334-stage .ci346-find svg {
    width: 58%; height: 58%; display: block; }
body.f346 .ci-wrap.ci334-stage .ci346-find:active {
    color: #ffd968; }

/* the corner search icon — portrait seat */
@media (orientation: portrait) {
  body.f346 .ci-wrap.ci334-stage .ci346-find {
      width: max(44px, calc(var(--sw) * 0.115));
      height: max(44px, calc(var(--sw) * 0.115));
      left: calc(var(--sx) + var(--sw) * 0.95
          - max(44px, calc(var(--sw) * 0.115)));
      top: calc(var(--sy) + var(--sh) * 0.036); }
}

/* the search label — the f337 label's seat and
   dress, carrying the app's own words */
body.f346 .ci-wrap.ci337-stage .ci346-label {
    position: absolute; z-index: 1;
    left: calc(var(--sx) + var(--sw) * 0.356);
    top: calc(var(--sy) + var(--sh) * 0.286);
    color: #f3dfae; white-space: nowrap;
    font-size: calc(var(--sw) * 0.0195);
    letter-spacing: .16em; text-transform: uppercase; }
@media (orientation: portrait) {
  body.f346 .ci-wrap.ci337-stage .ci346-label {
      left: calc(var(--sx) + var(--sw) * 0.07);
      top: calc(var(--sy) + var(--sh) * 0.296);
      font-size: calc(var(--sw) * 0.037);
      letter-spacing: .12em; }
}

/* the results — the f337 rows' seat; the rows
   themselves are the app's .pick-row cards */
body.f346 .ci-wrap.ci337-stage .ci346-rows {
    position: absolute; z-index: 1;
    left: calc(var(--sx) + var(--sw) * 0.356);
    top: calc(var(--sy) + var(--sh) * 0.475);
    width: calc(var(--sw) * 0.50);
    max-height: calc(var(--sh) * 0.50);
    overflow-y: auto;
    display: flex; flex-direction: column;
    gap: calc(var(--sh) * 0.017); }
body.f346 .ci-wrap.ci337-stage .ci346-rows .pick-row {
    width: 100%; margin-bottom: 0; flex: none; }
@media (orientation: portrait) {
  body.f346 .ci-wrap.ci337-stage .ci346-rows {
      left: calc(var(--sx) + var(--sw) * 0.07);
      top: calc(var(--sy) + var(--sh) * 0.445);
      width: calc(var(--sw) * 0.86);
      max-height: calc(var(--sh) * 0.52);
      gap: calc(var(--sh) * 0.014); }
}

/* ================================================================
   BUILD 342 (gate Features:Check369): the name
   search's results become their OWN scroll region.
   The f369 class rides the results box only while
   the gate shows (Pages/CheckIn, the Check346
   face). Three changes over the f346 seats above,
   scoped to that one box:
   (1) the height is ALSO capped by the visible
       viewport — the box's own top (its stage seat:
       --sy + the .475 / .445 stage fraction) plus
       its height can never pass the fold, so the
       whole scroll region is always on screen and
       reachable (a browser whose visible height is
       shorter than the stage's dvh math — an in-app
       browser's chrome over the page — otherwise
       leaves the box's lower half below the fold of
       a page that itself cannot scroll);
   (2) touch-action: pan-y — a vertical finger
       drag that starts on the list is the list's
       own pan, never the page's;
   (3) overscroll-behavior: contain — at the
       list's ends the gesture dies there; it never
       chains into a page scroll or pull behind it.
   The label, field and header seats are untouched
   and stay put. Gate OFF: no f369 class is
   emitted, no rule here matches, and the step is
   BUILD 341's byte for byte.
   ================================================================ */
body.f346 .ci-wrap.ci337-stage .ci346-rows.f369 {
    max-height: min(calc(var(--sh) * 0.50),
        calc(100dvh - var(--sy)
            - var(--sh) * 0.475 - 10px));
    overflow-y: auto;
    overscroll-behavior: contain;
    touch-action: pan-y;
    -webkit-overflow-scrolling: touch; }
@media (orientation: portrait) {
  body.f346 .ci-wrap.ci337-stage .ci346-rows.f369 {
      max-height: min(calc(var(--sh) * 0.52),
          calc(100dvh - var(--sy)
              - var(--sh) * 0.445 - 10px)); }
}

/* BUILD 333 (gate Features:Check349): the sign-in
   book display's frame — the shared Book card
   rendered standalone after a search pick. The
   card's own dress is the Book's (.book-grid
   .appt-card, in the grid blocks above); this
   block only seats it: a centered frame the
   .appt-area fills, on the station's own ground.
   These classes exist only on the gate-on book
   step, so no other surface can wear them. */
.ci349-panel { width:100%; box-sizing:border-box; padding:26px 18px 34px; }
.ci349-frame { position:relative; width:min(96%, 980px); height:min(46vh, 460px); margin:0 auto; }
/* The card's camera mark (check213) is sized by a
   rule that rides in the layout's admin-session
   switcher block — the Book always has an admin
   session, the station normally runs a desk
   session and never gets that block, so the mark's
   SVG would balloon to fill the card here. The
   same values, scoped to this frame, so the
   component renders on the station exactly as it
   renders in the Book. */
.ci349-frame .card-cam { display:block; margin-top:1px; line-height:0; color:var(--rose-dark); }
.ci349-frame .card-cam svg { width:14px; height:14px; fill:none; stroke:currentColor; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }

/* ================================================================
   BUILD 335 (gate Features:Check353): sign-in validation —
   (1) the quick review's door on the keypad: a blank list
   icon seated BESIDE the Check346 search icon in the top
   right corner, in the search icon's own dress (soft gold
   glyph, dark soft shadow), one icon-width to its left;
   like the search icon it needs the Check334 stage.
   (2) the quick-review list itself, built to the approved
   drawing (mockups/accept-revoke-sample): cream ground,
   white cards with a state left border (gold while a self
   sign-in awaits review, green once valid), TIME IN vs
   APPOINTMENT boxes, the difference line, the green
   Accept / red-outline Revoke buttons, and the valid tag.
   The kind ticket sits on a card's name line ONLY for
   a walk-in (owner refinement, Nov 4, 2026, 9:04 AM):
   .ci353-witag — the Book card's paid/unpaid ticket
   dress (the dep-tag pill's exact declarations) —
   reads "Walk in". No violet, no gold highlight; an
   appointment is the default and carries NO ticket
   anywhere. The same pill dresses the Book's walk-in
   seats while the gate shows (_BookCard's branch);
   gate off, every surface is byte-identical.
   ================================================================ */

/* the corner review button — landscape seat */
body.f353 .ci-wrap.ci334-stage .ci353-review {
    position: absolute; z-index: 3;
    width: max(44px, calc(var(--sw) * 0.046));
    height: max(44px, calc(var(--sw) * 0.046));
    left: calc(var(--sx) + var(--sw) * 0.982
        - max(44px, calc(var(--sw) * 0.046)) * 2
        - var(--sw) * 0.014);
    top: calc(var(--sy) + var(--sh) * 0.052);
    display: flex; align-items: center;
    justify-content: center;
    color: #f3d489;
    filter: drop-shadow(0 1px 3px rgba(0, 0, 0, .85))
        drop-shadow(0 0 7px rgba(0, 0, 0, .45));
    -webkit-tap-highlight-color: transparent; }
body.f353 .ci-wrap.ci334-stage .ci353-review svg {
    width: 58%; height: 58%; display: block; }
body.f353 .ci-wrap.ci334-stage .ci353-review:active {
    color: #ffd968; }

/* the corner review button — portrait seat */
@media (orientation: portrait) {
  body.f353 .ci-wrap.ci334-stage .ci353-review {
      width: max(44px, calc(var(--sw) * 0.115));
      height: max(44px, calc(var(--sw) * 0.115));
      left: calc(var(--sx) + var(--sw) * 0.95
          - max(44px, calc(var(--sw) * 0.115)) * 2
          - var(--sw) * 0.03);
      top: calc(var(--sy) + var(--sh) * 0.036); }
}

/* the review list */
.ci353-panel { width: min(94%, 560px); margin: 0 auto;
    padding: 18px 4px 30px; box-sizing: border-box;
    max-height: 94vh; overflow-y: auto; text-align: left; }
.ci353-top { display: flex; align-items: center;
    justify-content: space-between; margin: 8px 0 14px; }
.ci353-title { font-size: 24px; font-weight: bold; color: #12263c; }
.ci353-icons { display: flex; gap: 10px; }
.ci353-iconbtn { width: 48px; height: 48px; border-radius: 12px;
    background: #fff; border: 2px solid #c9b48a;
    display: flex; align-items: center; justify-content: center;
    color: #12263c; box-sizing: border-box; }
.ci353-iconbtn svg { width: 24px; height: 24px; display: block; }
.ci353-iconbtn.on { background: #cd841f; border-color: #cd841f; }
.ci353-card { background: #fff; border-radius: 14px;
    padding: 14px 16px; margin-bottom: 12px;
    border-left: 8px solid #d8d2c4; }
.ci353-card.pend { border-left-color: #cd841f; }
.ci353-card.valid { border-left-color: #3d9950; opacity: .75; }
.ci353-name { font-size: 21px; font-weight: bold; color: #12263c; }
.ci353-witag { 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; }
.ci353-svc { font-size: 16px; color: #444; margin-top: 2px; }
.ci353-times { display: flex; gap: 8px; margin-top: 10px; }
.ci353-tbox { flex: 1; background: #f7f2e7; border-radius: 10px;
    padding: 8px 10px; text-align: center; }
.ci353-tbox .lab { font-size: 12px; color: #777;
    text-transform: uppercase; letter-spacing: .5px; }
.ci353-tbox .val { font-size: 19px; font-weight: bold;
    color: #12263c; margin-top: 2px; }
.ci353-diff { margin-top: 8px; font-size: 16px; font-weight: bold;
    text-align: center; color: #12263c; }
.ci353-diff.early { color: #3d9950; }
.ci353-diff.late { color: #c0392b; }
.ci353-diff.walk { color: #8a6d1f; }
.ci353-btns { display: flex; gap: 10px; margin-top: 12px; }
.ci353-btns form { flex: 1; }
.ci353-btn { width: 100%; height: 52px; border-radius: 12px;
    font-size: 19px; font-weight: bold; border: none; cursor: pointer; }
.ci353-btn.accept { background: #3d9950; color: #fff; }
.ci353-btn.revoke { background: #fff; color: #c0392b;
    border: 2px solid #c0392b; }
.ci353-validtag { margin-top: 10px; text-align: center;
    font-size: 16px; font-weight: bold; color: #3d9950; }

/* BUILD 337 (gate Features:Check354): the estimate
   headline's two-line form — "Hi {Name}," over
   "Your service estimate:" — in the headline's own
   Great Vibes dress (.bill-thanks). The modifier
   class rides only the /Bill estimate headline
   while the gate shows (emitted by _Bill.cshtml);
   it shrinks the script and loosens the leading so
   both lines fit the phone width the way the
   one-line "Thank you, {Name}" did. No other
   surface can wear it. */
.bill-thanks-354 { font-size:35px; line-height:1.3; }

/* BUILD 346 item 2 (gate Features:Check377): the
   /Bill estimate headline's first line — "ESTIMATE"
   riding inside the three-line headline (emitted by
   _Bill.cshtml only while the gate shows, on the
   /Bill estimate state). The values are the page's
   standing ESTIMATE title div's own (its inline
   style, verbatim: 19px, weight 800, .4em letter
   spacing with the .4em indent that centers spaced
   caps, rose-dark) with the sans restored — the
   headline around it is the Great Vibes script, and
   the title was never script. Display block makes
   it the headline's first line. */
.bill-est377 { display:block; font-family:var(--font-body); font-size:19px; font-weight:800; letter-spacing:.4em; text-indent:.4em; color:var(--rose-dark); }

/* ================================================================
   BUILD 339 item 3 (gate Features:Check359): the station
   quick-review list in the owner's supplied design
   (mockups/signins-owner-design.png). These rules dress
   markup only the gate-on review render emits (the
   .ci359-* classes), so no gate-off surface can match
   them. The panel widens only in this dress (the
   .ci359-wide modifier rides the panel only while the
   gate shows).
   ================================================================ */
.ci353-panel.ci359-wide { width: min(96%, 900px); }
.ci359-card { display: flex; align-items: stretch;
    background: #fffdf8; border: 2px solid #e8c87e;
    border-left: 10px solid #cd841f; border-radius: 16px;
    padding: 16px 18px; margin-bottom: 14px;
    box-sizing: border-box; text-align: left; }
.ci359-main { flex: 1 1 auto; min-width: 0; display: flex;
    flex-direction: column; justify-content: center; }
.ci359-name { font-size: 30px; font-weight: 800;
    color: #12263c; line-height: 1.15; }
.ci359-svc { font-size: 19px; color: #777; margin-top: 4px; }
.ci359-mid { flex: 0 0 230px; box-sizing: border-box;
    border-left: 2px solid #e7dcc0;
    border-right: 2px solid #e7dcc0;
    margin: 0 18px; padding: 0 10px; display: flex;
    flex-direction: column; align-items: center;
    justify-content: center; text-align: center; }
.ci359-midlbl { font-size: 16px; font-weight: 600;
    color: #8a8578; }
.ci359-midtime { font-size: 30px; font-weight: 800;
    color: #12263c; margin-top: 2px; white-space: nowrap; }
/* the owner's refinement: on THIS list the
   "Walk in" ticket is BRIGHT GREEN (white text,
   same size and seat — the pill is the shared
   .ci353-witag; only its fill changes inside a
   359 card; the 335 dress elsewhere keeps the
   olive it shipped with). */
.ci359-card .ci353-witag { background: #00b140; }
.ci359-wait { margin-top: 9px; background: #cd841f;
    color: #fff; font-size: 16px; font-weight: 700;
    padding: 5px 16px; border-radius: 999px;
    white-space: nowrap; }
/* ================================================================
   BUILD 345 (gates Features:Check373 / Check374 /
   Check375): three review-list refinements.
   (1) Check373 — the "Walk in" pill BIGGER inside
   the review panel only (.f373 rides the panel
   while the gate shows): font and padding scaled
   half again over the shipped 10.5px / 2.5px 7px.
   The Book card's pill is outside the panel and
   keeps tonight's size.
   (2) Check374 — the Closed Tickets dress: a gray
   "Closed" pill in the waiting pill's own geometry,
   big letter badges for the services, and the
   section header (the ci359-sep dress in the 359
   list; .ci374-sep335 is its 335-dress twin).
   (3) Check375 — the review screen's Back link as
   a pill (.f375): the keypad face's .ci337-back
   dress (translucent dark fill, gold border,
   cream-gold text, 999px radius) in fixed sizes,
   since the stage's --sw/--sh measures do not
   exist on this screen.
   Gate off (any of the three): no rule applies and
   every surface is BUILD 344's exactly.
   ================================================================ */
.ci353-panel.f373 .ci353-witag { font-size: 15.75px;
    padding: 3.75px 10.5px; }
.ci374-closed { display: inline-block; background: #8a8578;
    color: #fff; font-size: 16px; font-weight: 700;
    padding: 5px 16px; border-radius: 999px;
    white-space: nowrap; }
.ci374-badges { margin-top: 4px; }
.ci374-badge { font-size: 26px; font-weight: 800;
    color: #12263c; margin-right: 8px; }
.ci359-card.closed374 .ci359-mid { justify-content: center; }
.ci374-sep335 { text-align: center; margin: 20px 2px 16px;
    color: #a08c5a; font-size: 14px; font-weight: 700;
    letter-spacing: 2.5px; }
.ci374-closedrow { margin-top: 10px; }
.ci337-back.f375 { display: inline-block;
    padding: 6px 16px; border-radius: 999px;
    background: rgba(22, 13, 5, .55);
    border: 1.5px solid #d9a441;
    color: #f6e3ae; font-size: 17px; font-weight: 700;
    text-decoration: none; }
.ci337-back.f375:active { background: rgba(124, 21, 48, .85); }
.ci359-side { flex: 0 0 205px; display: flex;
    flex-direction: column; gap: 10px;
    justify-content: center; }
.ci359-side form { margin: 0; }
.ci359-side .ci353-validtag { margin-top: 0; }
.ci359-btn { width: 100%; height: 52px; border-radius: 12px;
    font-size: 20px; font-weight: 800; border: none;
    cursor: pointer; box-sizing: border-box; }
.ci359-btn.accept { background: #3d9950; color: #fff; }
/* the owner's approved v3 sample (mockups/
   signins-owner-design-v3.png): Accept keeps its
   full size and seat (the whole column width, on
   top); Decline is a SMALL SQUARE red button under
   it, aligned LEFT in the column, its word readable
   inside — never a second full-width bar. */
.ci359-btn.decline { background: #d92b20; color: #fff;
    width: 84px; height: 84px; font-size: 16px; }
.ci359-sep { display: flex; align-items: center; gap: 14px;
    margin: 20px 2px 16px; color: #a08c5a; font-size: 14px;
    font-weight: 700; letter-spacing: 2.5px; }
.ci359-sep::before, .ci359-sep::after { content: "";
    flex: 1; height: 2px; background: #ddd3b8; }
@media (max-width: 640px) {
    .ci359-card { flex-direction: column; }
    .ci359-mid { flex: none; border: none;
        border-top: 2px solid #e7dcc0;
        margin: 12px 0 0; padding: 12px 0 0; }
    .ci359-side { flex: none; margin-top: 12px; }
}

/* ================================================================
   BUILD 339 item 4 (gate Features:Check360): the Accept
   button's chevron zone + its "Later" menu, on the review
   cards of BOTH dresses (BUILD 335's and Check359's). The
   wrap takes the Accept form's own flex seat; the chevron
   overlays the button's right edge (the button gains the
   matching right padding so its word stays centred in the
   free width); the menu hangs under the wrap's right
   edge. Markup and script emit only while the gate shows.
   ================================================================ */
.ci360-wrap { position: relative; flex: 1; display: flex; }
.ci360-wrap > form { flex: 1; margin: 0; }
.ci360-wrap .ci353-btn.accept,
.ci360-wrap .ci359-btn.accept { padding-right: 46px; }
.ci360-chev { position: absolute; right: 0; top: 0;
    width: 42px; height: 100%; border: none;
    border-radius: 0 12px 12px 0;
    background: rgba(0, 0, 0, 0.16); color: #fff;
    font-size: 15px; cursor: pointer; display: flex;
    align-items: center; justify-content: center;
    padding: 0; }
.ci360-menu { position: absolute; right: 0;
    top: calc(100% + 6px); z-index: 40; min-width: 150px;
    background: #fff; border: 1.5px solid #ddd3b8;
    border-radius: 12px; padding: 6px;
    box-shadow: 0 10px 24px rgba(60, 40, 10, 0.25); }
.ci360-menu form { margin: 0; }
.ci360-item { width: 100%; background: none; border: none;
    font-family: inherit; font-size: 17px; font-weight: 700;
    color: #12263c; padding: 10px 14px; text-align: left;
    cursor: pointer; border-radius: 8px; }
.ci360-item:hover, .ci360-item:active { background: #f7f2e7; }

/* ================================================================
   BUILD 339 item 5 (gate Features:Check361, body class
   f361): the sign-in OK form takes the keypad's own seat
   on the marble face. A later refinement re-seated the
   form apart from the pad (form .356/.389 against the
   pad's .420/.417 on the plain ci334 stage, and .357/
   .394 on the ci320 stage); while this gate shows the
   form's left and width ARE the pad's in each stage
   state, so the OK bar's edges are the keypad grid's
   edges. Only left/width are touched — the form's
   vertical seat, the OK glow and every other station
   element keep their current rules. The portrait face
   already seats form and pad together (.115/.770);
   its rule below pins the same values so the two can
   never drift apart there either.
   ================================================================ */
@media (orientation: landscape) {
  body.f361 .ci-wrap.ci334-stage #ciPhoneForm {
      left: calc(var(--sx) + var(--sw) * 0.420);
      width: calc(var(--sw) * 0.417); }
  body.f361 .ci-wrap.ci320-stage.ci334-stage #ciPhoneForm {
      left: calc(var(--sx) + var(--sw) * 0.357);
      width: calc(var(--sw) * 0.394); }
}
@media (orientation: portrait) {
  body.f361 .ci-wrap.ci334-stage #ciPhoneForm,
  body.f361 .ci-wrap.ci320-stage.ci334-stage #ciPhoneForm {
      left: calc(var(--sx) + var(--sw) * 0.115);
      width: calc(var(--sw) * 0.770); }
}

/* ================================================================
   BUILD 339 items 7+8 (gates Features:Check363 /
   Check364, body classes f363 / f364): a Book grid card
   is exactly as tall as its time span. check131's
   grow-don't-clip floor (min-height: max-content on
   .appt-card) let content push a card past its end
   line — spilling over the rows below (item 8) and
   over the neighbouring cards a same-time lane card
   stands beside (item 7). While f364 shows, EVERY
   grid card keeps its true span; while f363 shows,
   the lane cards (a multi-entry overlap group's
   cards — the same-time pairs) keep theirs. In both
   cases the interior compacts to fit the span: the
   coin strip takes check264's proven week sizes
   (24px coins, a 30px strip — the largest at which
   the canonical card fits its slot) at every scale,
   and the card padding tightens. The strip keeps
   riding the card's bottom (its margin-top:auto rule
   above is untouched; only its side/bottom margins
   follow the tighter padding). Content that still
   cannot fit a sub-hour span is clipped by the
   card's own overflow:hidden — the card never
   re-inflates. Gate off (either): no rule here
   matches and the grid renders byte-identically to
   the BUILD 338 publish.
   ================================================================ */
body.f363 .book-grid .appt-card.lane-card,
body.f364 .book-grid .appt-card { min-height: 0; }
body.f363 .book-grid .appt-card.lane-card,
body.f364 .book-grid .appt-card { padding: 5px 7px; }
body.f363 .book-grid .appt-card.lane-card .svc-strip,
body.f364 .book-grid .appt-card .svc-strip {
    min-height: 30px; margin-left: -7px;
    margin-right: -7px; margin-bottom: -5px; }
body.f363 .book-grid .appt-card.lane-card .coin,
body.f364 .book-grid .appt-card .coin {
    width: 24px; height: 24px; font-size: 14px;
    border-width: 1.5px; }
body.f363 .book-grid .appt-card.lane-card .coin-note svg,
body.f364 .book-grid .appt-card .coin-note svg {
    width: 13px; height: 13px; }
/* BUILD 339 item 7, tight lanes: in a split of 3 or
   more, the name steps down a size and the coin
   strip slims, so a long name wraps INSIDE its
   true span instead of pushing the strip off the
   card's bottom edge (measured on the rig book:
   a 3-way lane is ~74px wide; the stock name size
   wraps a long name to 3+ lines and the strip
   spilled ~7px past the card). The card partial
   stamps laneN<n> only while Check363 shows. */
body.f363 .book-grid .appt-card.laneN3,
body.f363 .book-grid .appt-card.laneN4,
body.f363 .book-grid .appt-card.laneN5 {
    padding: 4px 6px; }
body.f363 .book-grid .appt-card.laneN3 .card-line1 strong,
body.f363 .book-grid .appt-card.laneN4 .card-line1 strong,
body.f363 .book-grid .appt-card.laneN5 .card-line1 strong {
    font-size: 10.5px; line-height: 1.15;
    overflow-wrap: anywhere; }
/* in a 3+-way lane the strip leaves the flow and
   rides the card's bottom-right corner: a long
   name needs the card's whole height for its
   lines, and the coins stay fully inside the
   card, clear of the name's left-aligned lines. */
body.f363 .book-grid .appt-card.laneN3 .svc-strip,
body.f363 .book-grid .appt-card.laneN4 .svc-strip,
body.f363 .book-grid .appt-card.laneN5 .svc-strip {
    position: absolute; right: 5px; bottom: 3px;
    margin: 0; min-height: 0; }
body.f363 .book-grid .appt-card.laneN3 .coin,
body.f363 .book-grid .appt-card.laneN4 .coin,
body.f363 .book-grid .appt-card.laneN5 .coin {
    width: 18px; height: 18px; font-size: 11px; }
/* BUILD 339 item 8, sub-hour cards: a 30-minute
   span (~40px) cannot stack a name over a coin
   strip, so the strip rides BESIDE the name on
   one row — every mark stays inside the true
   span, nothing hangs below the end line. The
   card partial stamps short364 (span under an
   hour) only while Check364 shows. */
body.f364 .book-grid .appt-card.short364 {
    flex-direction: row; align-items: center;
    padding: 3px 7px; }
body.f364 .book-grid .appt-card.short364 .card-line1 {
    flex: 1 1 auto; }
body.f364 .book-grid .appt-card.short364 .svc-strip {
    margin: 0 0 0 6px; min-height: 0; }
body.f364 .book-grid .appt-card.short364 .coin {
    width: 20px; height: 20px; font-size: 12px; }

/* BUILD 346 (gate Features:Check378): the owner's
   drawn sign-in picker screen (design/signin-
   service-picker/) on the station's found step.
   The stage IS his scene (scene-clean.jpg — his
   background art with the baked greeting/question
   removed by the asset pass in diag/check346;
   the emblem's golden glow rides baked in the
   scene). The background is WIDTH-LOCKED (100%
   auto, never cover) so the live greeting and
   question sit exactly on the scene's cleaned
   bands at any stage width; lengths inside are
   container units (cqw) of the stage itself. The
   cards are his: photo crops from his art over
   the colored band (gradient matches his band,
   icon extracted from his art, name in the
   site's serif display face), the gold-ring
   arrow at the band's right. Selected is the
   art's dress: a strong gold glow around the
   whole card, the band brighter/more saturated,
   the arrow replaced by the big green check.
   The confirm is the owner's big green "Check
   me in" button (the only element not in his
   art — his own later words replaced it). The
   locked completion (ci378-done) dims the button
   and stills the cards. These rules render only
   inside the gate's branch, so the gate-off page
   keeps its rules untouched. */
.ci378-stage { position: relative; width: min(1050px, 97vw);
    margin: 6px auto 0; padding: 0 3.2% 3.2%; border-radius: 28px;
    background: #f8ead3 url('/images/signin378/scene-clean.jpg') top center / 100% auto no-repeat;
    box-shadow: 0 24px 60px rgba(120, 72, 20, .25);
    container-type: inline-size; }
.ci378-stage .ci-error { position: absolute; top: 10px; left: 50%;
    transform: translateX(-50%); z-index: 5; width: max-content;
    max-width: 92%; background: #b3261e; color: #fff;
    padding: 8px 18px; border-radius: 999px; font-size: 17px; }
.ci378-banner { padding-top: 21.5%; text-align: center; }
.ci378-greet { font-family: "Great Vibes", cursive;
    font-size: 5.4vw; font-size: 5.5cqw; line-height: 1.1;
    color: #6d3300; }
.ci378-flourish { width: 34%; height: 3px; margin: .6% auto 0;
    border-radius: 3px;
    background: linear-gradient(90deg, transparent, #c9973f 30%, #e8bc62 50%, #c9973f 70%, transparent); }
.ci378-ask { margin-top: 1.7%; display: flex; align-items: center;
    justify-content: center; gap: 2.2%;
    font-size: 2.6vw; font-size: 2.65cqw; font-weight: 700;
    color: #401b05; }
.ci378-rule { height: 2px; width: 9%; flex: 0 0 auto;
    background: linear-gradient(90deg, transparent, #c9973f); }
.ci378-rule-r { background: linear-gradient(90deg, #c9973f, transparent); }
.ci378-cards { margin-top: 3.8%; display: flex; gap: 2.4%; }
.ci378-card { flex: 1 1 0; position: relative; display: block;
    cursor: pointer; }
.ci378-card input { position: absolute; inset: 0; z-index: 3;
    opacity: 0; cursor: pointer; }
.ci378-sent .ci378-card, .ci378-done .ci378-card { pointer-events: none; }
.ci378-inner { position: relative; display: flex;
    flex-direction: column; aspect-ratio: 362 / 286;
    border-radius: 20px; overflow: hidden;
    border: 2px solid #d9a441; background: #fff;
    box-shadow: 0 6px 18px rgba(120, 72, 20, .18); }
.ci378-photo { flex: 0 0 59.5%; background-size: cover;
    background-position: center; }
.ci378-photo-nails { background-image: url('/images/signin378/card-nails.jpg'); }
.ci378-photo-pedi { background-image: url('/images/signin378/card-pedi.jpg'); }
.ci378-photo-wax { background-image: url('/images/signin378/card-wax.jpg'); }
.ci378-band { flex: 1; display: flex; align-items: center;
    gap: 5%; padding: 0 5.5%; }
.ci378-band-nails { background: linear-gradient(180deg, #e2607c 0%, #c22547 55%, #9c1433 100%); }
.ci378-band-pedi { background: linear-gradient(180deg, #b3bd68 0%, #7f9c2c 55%, #5e7c07 100%); }
.ci378-band-wax { background: linear-gradient(180deg, #b96fc0 0%, #8e3690 55%, #6d1f6e 100%); }
.ci378-card:has(input:checked) { filter: drop-shadow(0 0 10px rgba(255, 205, 40, .95)) drop-shadow(0 0 26px rgba(255, 180, 0, .8)); }
.ci378-card:has(input:checked) .ci378-inner { border-color: #ffcf3f; }
.ci378-card:has(input:checked) .ci378-band { filter: brightness(1.13) saturate(1.3); }
.ci378-icon { height: 62%; width: auto; max-width: 27%;
    object-fit: contain; }
.ci378-name { font-family: var(--font-display); font-weight: 700;
    color: #fff; font-size: 2.5vw; font-size: 2.55cqw;
    letter-spacing: .01em; text-shadow: 0 1px 3px rgba(0, 0, 0, .3); }
.ci378-go { margin-left: auto; flex: 0 0 auto;
    width: 4vw; width: 4.1cqw; height: 4vw; height: 4.1cqw;
    border: 2px solid rgba(255, 216, 130, .95); border-radius: 50%;
    color: #ffedb5; display: grid; place-items: center;
    font-size: 2.9vw; font-size: 3cqw; font-weight: 700; line-height: 1; }
.ci378-card:has(input:checked) .ci378-go { display: none; }
.ci378-check { position: absolute; right: 4.2%; top: 58.6%;
    width: 9.7vw; width: 9.9cqw; height: 9.7vw; height: 9.9cqw;
    border-radius: 50%; z-index: 2; display: none;
    place-items: center;
    background: radial-gradient(circle at 35% 30%, #6fe03c, #22b006 72%);
    border: 3px solid #e9c766; color: #fff;
    font-size: 6vw; font-size: 6.1cqw; font-weight: 800; line-height: 1;
    box-shadow: 0 6px 18px rgba(21, 110, 0, .45); }
.ci378-card:has(input:checked) .ci378-check { display: grid; }
.ci378-confirm { display: block; margin: 3.6% auto 0;
    min-width: 46%; padding: 1.5cqw 4cqw; border-radius: 999px;
    border: 2px solid #e9c766;
    background: linear-gradient(180deg, #41c711, #1f9d04);
    color: #fff; font-family: var(--font-body);
    font-size: 2.6vw; font-size: 2.65cqw; font-weight: 800;
    letter-spacing: .01em; cursor: pointer;
    box-shadow: 0 12px 26px rgba(24, 120, 0, .35); }
.ci378-confirm:disabled { filter: grayscale(.4) brightness(.94);
    opacity: .7; box-shadow: none; cursor: default; }
/* A narrow window on the station stacks the cards
   (the QR flow's phone dress lives in the scan
   page itself; this only keeps the station sane). */
@media (max-width: 640px) {
    .ci378-cards { flex-direction: column; }
    .ci378-card { flex: none; }
    .ci378-inner { aspect-ratio: 362 / 250; }
    .ci378-greet { font-size: 9.4vw; font-size: 9.4cqw; }
    .ci378-ask { font-size: 4.4vw; font-size: 4.4cqw; }
    .ci378-name { font-size: 5.6vw; font-size: 5.6cqw; }
    .ci378-go { width: 8.6vw; width: 8.6cqw; height: 8.6vw; height: 8.6cqw;
        font-size: 6.4vw; font-size: 6.4cqw; }
    .ci378-check { width: 25vw; width: 25cqw; height: 25vw; height: 25cqw;
        font-size: 15.5vw; font-size: 15.5cqw; }
    .ci378-confirm { font-size: 5.4vw; font-size: 5.4cqw;
        padding: 12px 30px; }
}

/* ================================================================
   BUILD 347 (gate Features:Check380): ROTATING SIGN-IN
   FACES. Three landscape keypad faces cropped from the
   owner's supplied composite (design/signin-faces-
   rotate) cycle in 10-minute wall-clock slots A -> B ->
   C so the desk iPad never sits on one picture all day
   (dead-pixel / burn-in avoidance). The wrap wears
   ci380-stage ci380-{a|b|c} (the server picks the slot;
   the gate's script in CheckIn.cshtml advances it at
   slot boundaries while the screen is idle). The face
   paints the stage's own art box (the --sx/--sy/--sw/
   --sh geometry every seat on this screen is written
   in) at 100% 100%, and every live control is re-seated
   per face in the same art fractions, measured off the
   owner's art — the slight per-face shift is part of
   the anti-burn-in design. The live dress (cream keys,
   gold OK) is today's, untouched; the emblem ring and
   the Welcome script carry the golden glow as drawn
   (two overlay layers the gate's script adds; seats
   tuned at the station's 1180x752). Landscape only:
   portrait keeps BUILD 346's face exactly. Gate OFF:
   no ci380 classes, no layers, BUILD 346's single
   marble face byte for byte.
   ================================================================ */
@media (orientation: landscape) {
body.f380 .ci-wrap.ci334-stage.ci380-stage.ci380-a::before,
body.f380 .ci-wrap.ci320-stage.ci334-stage.ci380-stage.ci380-a::before,
body.f380 .ci-wrap.ci320-stage.ci321-morning.ci334-stage.ci380-stage.ci380-a::before,
body.f380 .ci-wrap.ci320-stage.ci321-afternoon.ci334-stage.ci380-stage.ci380-a::before,
body.f380 .ci-wrap.ci320-stage.ci321-evening.ci334-stage.ci380-stage.ci380-a::before {
    background: url("/images/station-signin-face-a.jpg?v=347")
        center / 100% 100% no-repeat; }
body.f380 .ci-wrap.ci334-stage.ci380-stage.ci380-b::before,
body.f380 .ci-wrap.ci320-stage.ci334-stage.ci380-stage.ci380-b::before,
body.f380 .ci-wrap.ci320-stage.ci321-morning.ci334-stage.ci380-stage.ci380-b::before,
body.f380 .ci-wrap.ci320-stage.ci321-afternoon.ci334-stage.ci380-stage.ci380-b::before,
body.f380 .ci-wrap.ci320-stage.ci321-evening.ci334-stage.ci380-stage.ci380-b::before {
    background: url("/images/station-signin-face-b.jpg?v=347")
        center / 100% 100% no-repeat; }
body.f380 .ci-wrap.ci334-stage.ci380-stage.ci380-c::before,
body.f380 .ci-wrap.ci320-stage.ci334-stage.ci380-stage.ci380-c::before,
body.f380 .ci-wrap.ci320-stage.ci321-morning.ci334-stage.ci380-stage.ci380-c::before,
body.f380 .ci-wrap.ci320-stage.ci321-afternoon.ci334-stage.ci380-stage.ci380-c::before,
body.f380 .ci-wrap.ci320-stage.ci321-evening.ci334-stage.ci380-stage.ci380-c::before {
    background: url("/images/station-signin-face-c.jpg?v=347")
        center / 100% 100% no-repeat; }

body.f380 .ci-wrap.ci380-stage.ci380-a .ci-phonebox {
    left: calc(var(--sx) + var(--sw) * 0.384);
    top: calc(var(--sy) + var(--sh) * 0.195);
    width: calc(var(--sw) * 0.373);
    height: calc(var(--sh) * 0.108); }
body.f380 .ci-wrap.ci380-stage.ci380-a .ci-pad {
    left: calc(var(--sx) + var(--sw) * 0.394);
    top: calc(var(--sy) + var(--sh) * 0.335);
    width: calc(var(--sw) * 0.369);
    height: calc(var(--sh) * 0.385); }
body.f380 .ci-wrap.ci380-stage.ci380-a #ciPhoneForm {
    left: calc(var(--sx) + var(--sw) * 0.386);
    top: calc(var(--sy) + var(--sh) * 0.752);
    width: calc(var(--sw) * 0.389);
    height: calc(var(--sh) * 0.09); }
body.f380 .ci-wrap.ci380-stage.ci380-a .ci-qr315 {
    left: calc(var(--sx) + var(--sw) * 0.783);
    top: calc(var(--sy) + var(--sh) * 0.19);
    width: calc(var(--sw) * 0.103); }
body.f380 .ci-wrap.ci380-stage.ci380-a .ci-back327 {
    left: calc(var(--sx) + var(--sw) * 0.046);
    top: calc(var(--sy) + var(--sh) * 0.041); }
body.f380 .ci-wrap.ci380-stage.ci380-a .ci346-find {
    left: calc(var(--sx) + var(--sw) * 0.963
        - max(44px, calc(var(--sw) * 0.046)));
    top: calc(var(--sy) + var(--sh) * 0.033); }
body.f380 .ci-wrap.ci380-stage.ci380-a .ci353-review {
    left: calc(var(--sx) + var(--sw) * 0.971
        - max(44px, calc(var(--sw) * 0.046)) * 2
        - var(--sw) * 0.014);
    top: calc(var(--sy) + var(--sh) * 0.033); }
body.f380 .ci-wrap.ci380-stage.ci380-b .ci-phonebox {
    left: calc(var(--sx) + var(--sw) * 0.39);
    top: calc(var(--sy) + var(--sh) * 0.193);
    width: calc(var(--sw) * 0.38);
    height: calc(var(--sh) * 0.112); }
body.f380 .ci-wrap.ci380-stage.ci380-b .ci-pad {
    left: calc(var(--sx) + var(--sw) * 0.4);
    top: calc(var(--sy) + var(--sh) * 0.339);
    width: calc(var(--sw) * 0.372);
    height: calc(var(--sh) * 0.387); }
body.f380 .ci-wrap.ci380-stage.ci380-b #ciPhoneForm {
    left: calc(var(--sx) + var(--sw) * 0.398);
    top: calc(var(--sy) + var(--sh) * 0.75);
    width: calc(var(--sw) * 0.384);
    height: calc(var(--sh) * 0.092); }
body.f380 .ci-wrap.ci380-stage.ci380-b .ci-qr315 {
    left: calc(var(--sx) + var(--sw) * 0.795);
    top: calc(var(--sy) + var(--sh) * 0.192);
    width: calc(var(--sw) * 0.108); }
body.f380 .ci-wrap.ci380-stage.ci380-b .ci-back327 {
    left: calc(var(--sx) + var(--sw) * 0.032);
    top: calc(var(--sy) + var(--sh) * 0.05); }
body.f380 .ci-wrap.ci380-stage.ci380-b .ci346-find {
    left: calc(var(--sx) + var(--sw) * 0.973
        - max(44px, calc(var(--sw) * 0.046)));
    top: calc(var(--sy) + var(--sh) * 0.021); }
body.f380 .ci-wrap.ci380-stage.ci380-b .ci353-review {
    left: calc(var(--sx) + var(--sw) * 0.98
        - max(44px, calc(var(--sw) * 0.046)) * 2
        - var(--sw) * 0.014);
    top: calc(var(--sy) + var(--sh) * 0.021); }
body.f380 .ci-wrap.ci380-stage.ci380-c .ci-phonebox {
    left: calc(var(--sx) + var(--sw) * 0.419);
    top: calc(var(--sy) + var(--sh) * 0.193);
    width: calc(var(--sw) * 0.376);
    height: calc(var(--sh) * 0.113); }
body.f380 .ci-wrap.ci380-stage.ci380-c .ci-pad {
    left: calc(var(--sx) + var(--sw) * 0.431);
    top: calc(var(--sy) + var(--sh) * 0.334);
    width: calc(var(--sw) * 0.367);
    height: calc(var(--sh) * 0.391); }
body.f380 .ci-wrap.ci380-stage.ci380-c #ciPhoneForm {
    left: calc(var(--sx) + var(--sw) * 0.42);
    top: calc(var(--sy) + var(--sh) * 0.748);
    width: calc(var(--sw) * 0.39);
    height: calc(var(--sh) * 0.084); }
body.f380 .ci-wrap.ci380-stage.ci380-c .ci-qr315 {
    left: calc(var(--sx) + var(--sw) * 0.819);
    top: calc(var(--sy) + var(--sh) * 0.19);
    width: calc(var(--sw) * 0.104); }
body.f380 .ci-wrap.ci380-stage.ci380-c .ci-back327 {
    left: calc(var(--sx) + var(--sw) * 0.045);
    top: calc(var(--sy) + var(--sh) * 0.057); }
body.f380 .ci-wrap.ci380-stage.ci380-c .ci346-find {
    left: calc(var(--sx) + var(--sw) * 0.955
        - max(44px, calc(var(--sw) * 0.046)));
    top: calc(var(--sy) + var(--sh) * 0.032); }
body.f380 .ci-wrap.ci380-stage.ci380-c .ci353-review {
    left: calc(var(--sx) + var(--sw) * 0.961
        - max(44px, calc(var(--sw) * 0.046)) * 2
        - var(--sw) * 0.014);
    top: calc(var(--sy) + var(--sh) * 0.032); }
/* the golden glow, as drawn: a travelling sheen on the
   emblem ring and a soft radiance behind Welcome. The
   layers are added by the gate's script as the stage's
   first children (over the picture, under the controls)
   and carry no pointer events. */
.f380 .ci380-ringglow, .f380 .ci380-welglow {
    position: absolute; pointer-events: none; }
.f380 .ci380-ringglow { z-index: 2; border-radius: 50%;
    background: conic-gradient(
        from 0deg,
        transparent 0deg,
        rgba(255, 190, 70, 0) 40deg,
        rgba(255, 205, 95, .55) 75deg,
        rgba(255, 240, 190, .95) 95deg,
        rgba(255, 205, 95, .55) 115deg,
        rgba(255, 190, 70, 0) 150deg,
        transparent 360deg);
    -webkit-mask: radial-gradient(closest-side,
        transparent 71%, #000 82%, #000 97%,
        transparent 99%);
    mask: radial-gradient(closest-side,
        transparent 71%, #000 82%, #000 97%,
        transparent 99%);
    filter: blur(1.2px) brightness(1.25)
        drop-shadow(0 0 14px rgba(255, 180, 60, .75));
    animation: ci380spin 5.5s linear infinite; }
.f380 .ci380-welglow { z-index: 1;
    background: radial-gradient(closest-side,
        rgba(255, 196, 84, .50),
        rgba(255, 176, 64, .22) 55%,
        rgba(255, 176, 64, 0) 78%);
    filter: blur(7px);
    animation: ci380pulse 4.2s ease-in-out infinite; }
.f380 .ci380-a .ci380-ringglow {
    left: 5.2%; top: 4.0%;
    width: 24.9%; height: 39.0%; }
.f380 .ci380-a .ci380-welglow {
    left: 11.5%; top: 47.5%;
    width: 33.8%; height: 25.6%; }
.f380 .ci380-b .ci380-ringglow {
    left: 6.9%; top: 5.9%;
    width: 23.7%; height: 37.2%; }
.f380 .ci380-b .ci380-welglow {
    left: 9.0%; top: 46.5%;
    width: 35.3%; height: 25.1%; }
.f380 .ci380-c .ci380-ringglow {
    left: 14.3%; top: 10.3%;
    width: 20.9%; height: 32.7%; }
.f380 .ci380-c .ci380-welglow {
    left: 9.8%; top: 46.5%;
    width: 36.2%; height: 26.2%; }
@keyframes ci380spin {
    to { transform: rotate(360deg); } }
@keyframes ci380pulse {
    0%, 100% { opacity: .72; }
    50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .f380 .ci380-ringglow,
  .f380 .ci380-welglow { animation: none; } }
} /* landscape */

/* ================================================================
   BUILD 348 (gate Features:Check382; the layout's "f382"
   body class rides beside f380 exactly when the gate
   shows — with Check382 off no rule below can match and
   every surface stays BUILD 347's, byte for byte). The
   fix build for BUILD 347's rotating faces.
   Item 1 — the emblem-ring and "Welcome" glow layers are
   re-seated in the stage's art-box terms (var(--sx) /
   --sy / --sw / --sh — the terms every live control
   already uses). The f380 seats were raw percentages of
   the wrap; the wrap and the art box agree at only one
   size, so the ring rendered oversized and off its
   medallion. The fractions below are measured off each
   face's own art: the ring layer's box is the
   medallion's outer rim; the radiance's box is the
   "Welcome" script's own extent.
   Item 2 — the shipped face is the owner's panel
   with every drawn control cleaned off in the
   panel's own texture (station-signin-face-a-
   clean.png?v=348 — lossless, his native pixels):
   the drawn "Back" pill and the bottom name plate,
   and — his refinements of Nov 5, 2026, the standing
   rule "if you add a button, you must always clean
   up the background" — the drawn display, key
   pills, OK bar, QR tile and corner icons and
   every drawn drop shadow, so the live controls
   sit on clean ground, the live Back pill is the
   only "Back" on the screen and no panel name
   shows. The controls keep their f380 seats —
   the paint-out never moves the art.
   SCOPE (owner, Nov 5, 2026, 7:43 AM): "Only fix
   face A. Remove face B and C. We'll come back
   later to add B and C." — only face A's cleaned
   panel ships; the b/c stage classes paint face
   A's panel and wear face A's glow seats below,
   and the gate's runtime pins the wrap to
   ci380-a, so no B or C art, seat or glow is
   ever active while this gate shows.
   Item 3 (the CSS half) — in portrait the glow layers
   never show; the gate's runtime block in
   CheckIn.cshtml takes the ci380 stage itself off a
   portrait stage, and the ci382-flat rule below keeps
   the layers hidden in any environment while the
   stage stands flattened.
   ================================================================ */
@media (orientation: landscape) {
body.f380.f382 .ci-wrap.ci334-stage.ci380-stage.ci380-a::before, body.f380.f382 .ci-wrap.ci320-stage.ci334-stage.ci380-stage.ci380-a::before, body.f380.f382 .ci-wrap.ci320-stage.ci321-morning.ci334-stage.ci380-stage.ci380-a::before, body.f380.f382 .ci-wrap.ci320-stage.ci321-afternoon.ci334-stage.ci380-stage.ci380-a::before, body.f380.f382 .ci-wrap.ci320-stage.ci321-evening.ci334-stage.ci380-stage.ci380-a::before, body.f380.f382 .ci-wrap.ci334-stage.ci380-stage.ci380-b::before, body.f380.f382 .ci-wrap.ci320-stage.ci334-stage.ci380-stage.ci380-b::before, body.f380.f382 .ci-wrap.ci320-stage.ci321-morning.ci334-stage.ci380-stage.ci380-b::before, body.f380.f382 .ci-wrap.ci320-stage.ci321-afternoon.ci334-stage.ci380-stage.ci380-b::before, body.f380.f382 .ci-wrap.ci320-stage.ci321-evening.ci334-stage.ci380-stage.ci380-b::before, body.f380.f382 .ci-wrap.ci334-stage.ci380-stage.ci380-c::before, body.f380.f382 .ci-wrap.ci320-stage.ci334-stage.ci380-stage.ci380-c::before, body.f380.f382 .ci-wrap.ci320-stage.ci321-morning.ci334-stage.ci380-stage.ci380-c::before, body.f380.f382 .ci-wrap.ci320-stage.ci321-afternoon.ci334-stage.ci380-stage.ci380-c::before, body.f380.f382 .ci-wrap.ci320-stage.ci321-evening.ci334-stage.ci380-stage.ci380-c::before {
    background: url("/images/station-signin-face-a-clean.png?v=348")
        center / 100% 100% no-repeat; }
.f380.f382 .ci380-a .ci380-ringglow {
    left: calc(var(--sx) + var(--sw) * 0.098);
    top: calc(var(--sy) + var(--sh) * 0.086);
    width: calc(var(--sw) * 0.227);
    height: calc(var(--sh) * 0.327); }
.f380.f382 .ci380-a .ci380-welglow {
    left: calc(var(--sx) + var(--sw) * 0.052);
    top: calc(var(--sy) + var(--sh) * 0.475);
    width: calc(var(--sw) * 0.290);
    height: calc(var(--sh) * 0.175); }
/* faces B and C are REMOVED while this gate shows
   (owner, Nov 5, 2026: face A only; B and C return
   in a later build) — the b/c classes, if a slot
   ever puts one on the wrap before the gate's
   pin takes it back off, wear face A's panel and
   face A's seats, never their own. */
.f380.f382 .ci380-b .ci380-ringglow {
    left: calc(var(--sx) + var(--sw) * 0.098);
    top: calc(var(--sy) + var(--sh) * 0.086);
    width: calc(var(--sw) * 0.227);
    height: calc(var(--sh) * 0.327); }
.f380.f382 .ci380-b .ci380-welglow {
    left: calc(var(--sx) + var(--sw) * 0.052);
    top: calc(var(--sy) + var(--sh) * 0.475);
    width: calc(var(--sw) * 0.290);
    height: calc(var(--sh) * 0.175); }
.f380.f382 .ci380-c .ci380-ringglow {
    left: calc(var(--sx) + var(--sw) * 0.098);
    top: calc(var(--sy) + var(--sh) * 0.086);
    width: calc(var(--sw) * 0.227);
    height: calc(var(--sh) * 0.327); }
.f380.f382 .ci380-c .ci380-welglow {
    left: calc(var(--sx) + var(--sw) * 0.052);
    top: calc(var(--sy) + var(--sh) * 0.475);
    width: calc(var(--sw) * 0.290);
    height: calc(var(--sh) * 0.175); }
} /* landscape */
@media (orientation: portrait) {
body.f382 .ci380-ringglow,
body.f382 .ci380-welglow { display: none; }
}
body.f382 .ci382-flat .ci380-ringglow,
body.f382 .ci382-flat .ci380-welglow { display: none; }

/* ================================================================
   BUILD 348 — the owner's refinements (Nov 5, 2026,
   7:15–7:27 AM, from his laptop look at the DEV
   faces; same Check382 gate).
   Item 4 — NO BLACK LINES: on screens wider than
   the picture's cover band (PC monitors, aspect
   over 8/5) the stage's older refinement fits the
   picture by height and fills the sides with a
   blurred dark wash — the black bars he flagged.
   While the faces show, the stage COVERS at those
   shapes too (the cover-band geometry restated):
   the picture itself is the whole background,
   edge to edge, and the wash never paints. The
   short-landscape fit (landscape phones) gets the
   same cover. Every seat is an art-box fraction,
   so the controls ride the picture as before.
   Item 5 — THE QR TILE IS CRISP: the art's drawn
   QR tile is painted out (item 2's pass), and the
   live tile wears a clean defined dress on the
   faces — solid cream-white, a hairline gold
   border, no blur, no smudge, no shadow.
   Item 6 — THE 0 KEY: the wide double-width 0
   becomes a normal single key in the LEFT column
   of its row, the delete key beside it in the
   middle column (his words: "Make number 0 at
   the right size, and align left"). The keypad
   is a shared component: the placement below
   holds on the faces, on the portrait stage and
   on the plain grid alike. Gate off, the wide 0
   stands exactly as BUILD 347 shipped it.
   Item 7 — NEVER A BARE BACKGROUND: the welcome
   card (the first-timer completion) paints its
   silk backdrop from an image; while this gate
   shows, the welcome also carries the theme's
   cream as its base colour — the same base the
   ci336 ground already wears — so the screen
   can never fall back to bare black behind the
   card, on any screen.
   ================================================================ */
@media (orientation: landscape) and (min-height: 501px)
    and (min-aspect-ratio: 8/5) {
body.f380.f382 .ci-wrap.ci334-stage,
body.f380.f382 .ci-wrap.ci320-stage.ci334-stage {
    --sw: max(100svw, 143.95svh);
    --sh: max(69.47svw, 100svh);
    --sx: calc((100svw - var(--sw)) / 2
        + max(0px, (100dvw - 100svw) / 2));
    --sy: calc(max(0px, 100dvh - 100svh)
        + (100svh - var(--sh)) / 2); }
body.f380.f382 .ci-wrap.ci334-stage::after,
body.f380.f382 .ci-wrap.ci320-stage.ci334-stage::after {
    display: none; }
}
@media (orientation: landscape) and (max-height: 500px) {
body.f380.f382 .ci-wrap.ci334-stage,
body.f380.f382 .ci-wrap.ci320-stage.ci334-stage {
    --sw: max(100svw, 143.95svh);
    --sh: max(69.47svw, 100svh);
    --sx: calc((100svw - var(--sw)) / 2
        + max(0px, (100dvw - 100svw) / 2));
    --sy: calc(max(0px, 100dvh - 100svh)
        + (100svh - var(--sh)) / 2); }
body.f380.f382 .ci-wrap.ci334-stage::after,
body.f380.f382 .ci-wrap.ci320-stage.ci334-stage::after {
    display: none; }
}
@media (orientation: landscape) {
body.f380.f382 .ci-wrap.ci380-stage .ci-qr315 {
    background: #fffdf8;
    border: 2px solid #b98a2e;
    border-radius: calc(var(--sw) * 0.010);
    padding: calc(var(--sw) * 0.007);
    box-shadow: none; }
}
body.f380.f382 .ci-wrap.ci334-stage .ci-key[data-k="0"],
body.f380.f382 .ci-wrap.ci320-stage.ci334-stage
    .ci-key[data-k="0"] { grid-column: 1 / 2; grid-row: 4; }
body.f380.f382 .ci-wrap.ci334-stage .ci-key[data-k="back"],
body.f380.f382 .ci-wrap.ci320-stage.ci334-stage
    .ci-key[data-k="back"] { grid-column: 2 / 3; grid-row: 4; }
@media (orientation: portrait) {
body.f380.f382 .ci-wrap.ci334-stage .ci-key[data-k="0"],
body.f380.f382 .ci-wrap.ci320-stage.ci334-stage
    .ci-key[data-k="0"] { grid-column: 1 / 3; grid-row: 4; }
body.f380.f382 .ci-wrap.ci334-stage .ci-key[data-k="back"],
body.f380.f382 .ci-wrap.ci320-stage.ci334-stage
    .ci-key[data-k="back"] { grid-column: 3 / 5; grid-row: 4; }
}
body.f382 .ci-pad .ci-keyblank {
    grid-column: 3; grid-row: 4; }
body.f382 .ci-pad .ci-key[data-k="0"] {
    grid-column: 1; grid-row: 4; }
body.f382 .ci-pad .ci-key[data-k="back"] {
    grid-column: 2; grid-row: 4; }
body.f382 .ci-welcome { background-color: #f6ecdc; }

/* ================================================================
   BUILD 350 (gate Features:Check384; the layout's "f384"
   body class rides beside f380/f382 exactly when the gate
   shows — with Check384 off no rule below can match and
   every surface stays BUILD 349's, byte for byte).
   The owner's verdict on BUILD 347/348's cropped panel
   faces (Nov 5, 2026, 8:15 AM): "Really Bad. Use this
   photo as background and put your controls on top of
   it." The station sign-in's landscape background is now
   HIS OWN PHOTO (station-signin-photo350.png?v=350 —
   the file he supplied, design/signin-background/,
   shipped at its native 1505x1045 pixels, lossless,
   never recomposed or regenerated): a dark-marble
   autumn scene whose LEFT side carries the emblem,
   "ROWLETT" and the "Welcome" script, and whose RIGHT
   side is empty marble made for the controls. The
   emblem ring already glows in his art — this gate
   adds NO glow layers of its own, and BUILD 347's two
   glow layers (seated for face A's panel) are hidden
   while it shows (the rule after this block).
   The stage geometry below restates the cover in the
   PHOTO's own aspect (1505:1045 = 144.019 : 69.435) at
   every landscape shape, so the picture fills the
   screen edge to edge — no black lines, no blurred
   side wash (the ::after wash never paints). Every
   seat is an art-box fraction measured off the photo:
   the emblem + Welcome zone ends at x = 0.375 of the
   picture and the bottom props (orchid, candle) stay
   below y = 0.65 on the right, so the whole control
   cluster lives on clean marble at x 0.43-0.86,
   y 0.06-0.70 — display, keypad (BUILD 348's single-
   size left-column 0 rides along untouched), OK, the
   crisp QR tile, the Back pill, the search and
   sign-ins icons. The seats are uniform across
   BUILD 347's face classes: the 10-minute rotation
   now has a single picture to show, so a slot swap
   changes nothing on screen. The stage-wide (no-
   ci380) forms carry :not(.ci382-flat) so a wrap
   BUILD 348's runtime flattened keeps BUILD 348's
   rendering exactly. LANDSCAPE ONLY — portrait is
   outside this block entirely and keeps BUILD 349's
   face. Check380 / Check381 / Check382 / Check383
   are not modified.
   ================================================================ */
@media (orientation: landscape) {
/* the cover, in the photo's own aspect, at every
   landscape shape */
body.f384 .ci-wrap.ci334-stage:not(.ci382-flat),
body.f384 .ci-wrap.ci320-stage.ci334-stage:not(.ci382-flat),
body.f380.f382.f384 .ci-wrap.ci334-stage:not(.ci382-flat),
body.f380.f382.f384 .ci-wrap.ci320-stage.ci334-stage:not(.ci382-flat) {
    --sw: max(100svw, 144.019svh);
    --sh: max(69.435svw, 100svh);
    --sx: calc((100svw - var(--sw)) / 2
        + max(0px, (100dvw - 100svw) / 2));
    --sy: calc(max(0px, 100dvh - 100svh)
        + (100svh - var(--sh)) / 2); }
body.f384 .ci-wrap.ci334-stage:not(.ci382-flat)::after,
body.f384 .ci-wrap.ci320-stage.ci334-stage:not(.ci382-flat)::after {
    display: none; }
/* the photo paints the stage — every face class,
   one picture */
body.f380.f384 .ci-wrap.ci334-stage.ci380-stage.ci380-a::before, body.f380.f384 .ci-wrap.ci320-stage.ci334-stage.ci380-stage.ci380-a::before, body.f380.f384 .ci-wrap.ci320-stage.ci321-morning.ci334-stage.ci380-stage.ci380-a::before, body.f380.f384 .ci-wrap.ci320-stage.ci321-afternoon.ci334-stage.ci380-stage.ci380-a::before, body.f380.f384 .ci-wrap.ci320-stage.ci321-evening.ci334-stage.ci380-stage.ci380-a::before, body.f380.f384 .ci-wrap.ci334-stage.ci380-stage.ci380-b::before, body.f380.f384 .ci-wrap.ci320-stage.ci334-stage.ci380-stage.ci380-b::before, body.f380.f384 .ci-wrap.ci320-stage.ci321-morning.ci334-stage.ci380-stage.ci380-b::before, body.f380.f384 .ci-wrap.ci320-stage.ci321-afternoon.ci334-stage.ci380-stage.ci380-b::before, body.f380.f384 .ci-wrap.ci320-stage.ci321-evening.ci334-stage.ci380-stage.ci380-b::before, body.f380.f384 .ci-wrap.ci334-stage.ci380-stage.ci380-c::before, body.f380.f384 .ci-wrap.ci320-stage.ci334-stage.ci380-stage.ci380-c::before, body.f380.f384 .ci-wrap.ci320-stage.ci321-morning.ci334-stage.ci380-stage.ci380-c::before, body.f380.f384 .ci-wrap.ci320-stage.ci321-afternoon.ci334-stage.ci380-stage.ci380-c::before, body.f380.f384 .ci-wrap.ci320-stage.ci321-evening.ci334-stage.ci380-stage.ci380-c::before, body.f384 .ci-wrap.ci334-stage:not(.ci382-flat)::before, body.f384 .ci-wrap.ci320-stage.ci334-stage:not(.ci382-flat)::before, body.f384 .ci-wrap.ci320-stage.ci321-morning.ci334-stage:not(.ci382-flat)::before, body.f384 .ci-wrap.ci320-stage.ci321-afternoon.ci334-stage:not(.ci382-flat)::before, body.f384 .ci-wrap.ci320-stage.ci321-evening.ci334-stage:not(.ci382-flat)::before {
    background: url("/images/station-signin-photo350.png?v=350")
        center / 100% 100% no-repeat; }
/* the controls, seated on the photo's empty right
   side — the same seats under every face class */
body.f380.f384 .ci-wrap.ci380-stage.ci380-a .ci-phonebox,
body.f380.f384 .ci-wrap.ci380-stage.ci380-b .ci-phonebox,
body.f380.f384 .ci-wrap.ci380-stage.ci380-c .ci-phonebox,
body.f384 .ci-wrap.ci334-stage:not(.ci382-flat) .ci-phonebox,
body.f384 .ci-wrap.ci320-stage.ci334-stage:not(.ci382-flat) .ci-phonebox {
    left: calc(var(--sx) + var(--sw) * 0.430);
    top: calc(var(--sy) + var(--sh) * 0.148);
    width: calc(var(--sw) * 0.330);
    height: calc(var(--sh) * 0.096); }
body.f380.f384 .ci-wrap.ci380-stage.ci380-a .ci-pad,
body.f380.f384 .ci-wrap.ci380-stage.ci380-b .ci-pad,
body.f380.f384 .ci-wrap.ci380-stage.ci380-c .ci-pad,
body.f384 .ci-wrap.ci334-stage:not(.ci382-flat) .ci-pad,
body.f384 .ci-wrap.ci320-stage.ci334-stage:not(.ci382-flat) .ci-pad {
    left: calc(var(--sx) + var(--sw) * 0.440);
    top: calc(var(--sy) + var(--sh) * 0.266);
    width: calc(var(--sw) * 0.320);
    height: calc(var(--sh) * 0.338); }
body.f380.f384 .ci-wrap.ci380-stage.ci380-a #ciPhoneForm,
body.f380.f384 .ci-wrap.ci380-stage.ci380-b #ciPhoneForm,
body.f380.f384 .ci-wrap.ci380-stage.ci380-c #ciPhoneForm,
body.f384 .ci-wrap.ci334-stage:not(.ci382-flat) #ciPhoneForm,
body.f384 .ci-wrap.ci320-stage.ci334-stage:not(.ci382-flat) #ciPhoneForm {
    left: calc(var(--sx) + var(--sw) * 0.430);
    top: calc(var(--sy) + var(--sh) * 0.622);
    width: calc(var(--sw) * 0.330);
    height: calc(var(--sh) * 0.078); }
body.f380.f384 .ci-wrap.ci380-stage.ci380-a .ci-qr315,
body.f380.f384 .ci-wrap.ci380-stage.ci380-b .ci-qr315,
body.f380.f384 .ci-wrap.ci380-stage.ci380-c .ci-qr315,
body.f384 .ci-wrap.ci334-stage:not(.ci382-flat) .ci-qr315,
body.f384 .ci-wrap.ci320-stage.ci334-stage:not(.ci382-flat) .ci-qr315 {
    left: calc(var(--sx) + var(--sw) * 0.776);
    top: calc(var(--sy) + var(--sh) * 0.142);
    width: calc(var(--sw) * 0.082); }
body.f380.f384 .ci-wrap.ci380-stage.ci380-a .ci-back327,
body.f380.f384 .ci-wrap.ci380-stage.ci380-b .ci-back327,
body.f380.f384 .ci-wrap.ci380-stage.ci380-c .ci-back327,
body.f384 .ci-wrap.ci334-stage:not(.ci382-flat) .ci-back327,
body.f384 .ci-wrap.ci320-stage.ci334-stage:not(.ci382-flat) .ci-back327 {
    left: calc(var(--sx) + var(--sw) * 0.430);
    top: calc(var(--sy) + var(--sh) * 0.062); }
body.f380.f384 .ci-wrap.ci380-stage.ci380-a .ci346-find,
body.f380.f384 .ci-wrap.ci380-stage.ci380-b .ci346-find,
body.f380.f384 .ci-wrap.ci380-stage.ci380-c .ci346-find,
body.f384 .ci-wrap.ci334-stage:not(.ci382-flat) .ci346-find,
body.f384 .ci-wrap.ci320-stage.ci334-stage:not(.ci382-flat) .ci346-find {
    left: calc(var(--sx) + var(--sw) * 0.790
        - max(44px, calc(var(--sw) * 0.046)));
    top: calc(var(--sy) + var(--sh) * 0.060); }
body.f380.f384 .ci-wrap.ci380-stage.ci380-a .ci353-review,
body.f380.f384 .ci-wrap.ci380-stage.ci380-b .ci353-review,
body.f380.f384 .ci-wrap.ci380-stage.ci380-c .ci353-review,
body.f384 .ci-wrap.ci334-stage:not(.ci382-flat) .ci353-review,
body.f384 .ci-wrap.ci320-stage.ci334-stage:not(.ci382-flat) .ci353-review {
    left: calc(var(--sx) + var(--sw) * 0.798
        - max(44px, calc(var(--sw) * 0.046)) * 2
        - var(--sw) * 0.014);
    top: calc(var(--sy) + var(--sh) * 0.060); }
/* the QR tile's crisp dress, restated so it does
   not depend on BUILD 348's gate riding along:
   solid cream-white, a defined gold border, no
   blur, no shadow (BUILD 348's refinement). */
body.f380.f384 .ci-wrap.ci380-stage .ci-qr315,
body.f384 .ci-wrap.ci334-stage:not(.ci382-flat) .ci-qr315,
body.f384 .ci-wrap.ci320-stage.ci334-stage:not(.ci382-flat) .ci-qr315 {
    background: #fffdf8;
    border: 2px solid #b98a2e;
    border-radius: calc(var(--sw) * 0.010);
    padding: calc(var(--sw) * 0.007);
    box-shadow: none; }
} /* landscape */
/* BUILD 347's glow layers belong to face A's panel;
   while the owner's photo is the background its glow
   is the art's own — the layers never show. */
body.f384 .ci380-ringglow,
body.f384 .ci380-welglow { display: none; }

/* ================================================================
   BUILD 351 (gate Features:Check385; the layout's "f385"
   body class rides beside f384 exactly when the gate
   shows — with Check385 off no rule below can match and
   every surface stays BUILD 350's, byte for byte).
   The owner's ruling (Nov 5, 2026, 8:58 AM, after his
   No to BUILD 350's Features OK): "you have to put all
   controls at the position where you put them in
   earlier version" — spelled out at 8:59 AM: "back
   button on top left, the sign-ins and search on top
   right, backspace at the lower right of keypad,
   etc...." BUILD 350 re-seated every control by
   measuring off his photo; this gate puts them back
   at the LONG-STANDING layout — the BUILD 346/334-era
   marble-stage seats (the ci334-stage seats) — while
   BUILD 350's photo stays the background: the same
   file, the same full-screen cover fill.
   (a) The stage geometry vars are restored to the
   BUILD 334 formulas (its rules (1)/(3)/(4), copied
   verbatim), so every seat written in stage terms —
   the display, the prompt, the message seat, the
   name/search step's field, bar and rows — lands
   where it landed in that era.
   (b) The photo's ::before keeps its own cover box,
   in BUILD 350's formulas, independent of the stage
   vars — the picture still fills the screen edge to
   edge, no black lines, no blurred wash. One
   framing change: the box is anchored so the
   visible window starts at 2% of the picture's
   height (never more than the vertical overflow),
   because the centred crop grazed the top of the
   emblem glow's halo at the station and laptop
   aspects — the ring and its halo now sit whole
   inside the frame at both (measured in the
   proof: the ring line spans y .102-.440 of
   the picture, its halo reaches about y .068).
   (c) The seven controls BUILD 350 re-seated are
   restated at their ci334-stage fractions: block (5)
   of the BUILD 334 rules (the sample's seats on the
   marble face), with BUILD 339's f361 amendment to
   the OK form (its left/width are the keypad's), and
   the corner icons at their BUILD 330/335 seats
   (f346/f353 — the top right, beside each other).
   (d) The keypad's bottom row — the marked sub-block
   at the end.
   (e) BUILD 347's glow layers stay down (the
   suppression rules stand after the landscape
   block): two ring systems over one emblem
   would double-glow.
   (f) THE EMBLEM GLOW, ACCURATE (owner, Nov 5,
   2026, 9:04 AM "glow still not accurate", then
   9:09 AM: the glow stays, seated exactly on the
   photo's emblem): BUILD 334's travelling ring
   (.ci-ringglow334) is re-seated in cover-box
   terms on the PHOTO's emblem — centre at
   (.191, .271) of the picture, ridge-fitted off
   the owner's file in the proof; the layer's
   annulus peak (90.5% of its radius) lands on
   the ring line itself (177px, .1179 of the
   picture's width).
   Its sheen, mask, blend and 5.5s spin are BUILD
   334's own, untouched — only the seat moves,
   from the marble medallion to the photo's.
   (g) THE PHONE-BOX TRACE (owner, Nov 5, 2026,
   9:09 AM): a matching gold light travels around
   the phone number box's border — the same conic
   wedge, the same 5.5s loop, the same always-on
   behaviour as the emblem ring (BUILD 334's ring
   never pauses for entry, so the trace doesn't
   either). It rides .ci-digits::before (the
   box's own pseudos carry its phone icon and
   divider), outset 3px from the box with a
   border-only mask, so it hugs the box's actual
   rendered border at every size. The travelling
   angle is BUILD 327's @property technique.
   Check380 / Check381 / Check382 / Check383 /
   Check384 code is not modified. LANDSCAPE ONLY,
   like the gate it repairs — item (e) excepted,
   for the reason given there.
   ================================================================ */
@property --ci385a { syntax: "<angle>";
    initial-value: 0deg; inherits: false; }
@keyframes ci385travel { to { --ci385a: 360deg; } }

/* (a) the marble era's stage geometry, restored —
   BUILD 334's rule (1): tall landscape. Every
   (a) selector is fenced :not(.ci337-stage): the
   name/search step's stage box is its own era
   box, restored separately in (a2) below — the
   proof's first run caught these rules (and
   BUILD 350's) sitting on the wrong box there. */
@media (orientation: landscape) and (min-height: 501px) {
body.f384.f385 .ci-wrap:not(.ci337-stage).ci334-stage:not(.ci382-flat),
body.f384.f385 .ci-wrap:not(.ci337-stage).ci320-stage.ci334-stage:not(.ci382-flat),
body.f380.f382.f384.f385 .ci-wrap:not(.ci337-stage).ci334-stage:not(.ci382-flat),
body.f380.f382.f384.f385 .ci-wrap:not(.ci337-stage).ci320-stage.ci334-stage:not(.ci382-flat) {
    --sw: max(100svw, 143.95svh);
    --sh: max(69.47svw, 100svh);
    --sx: calc((100svw - var(--sw)) / 2
        + max(0px, (100dvw - 100svw) / 2));
    --sy: calc(max(0px, 100dvh - 100svh)
        + (100svh - var(--sh)) / 2); }
}
/* BUILD 334's rule (3): wider than 1.60x, the
   fit-by-height box the era's seats were drawn on */
@media (orientation: landscape) and (min-height: 501px)
    and (min-aspect-ratio: 8/5) {
body.f384.f385 .ci-wrap:not(.ci337-stage).ci334-stage:not(.ci382-flat),
body.f384.f385 .ci-wrap:not(.ci337-stage).ci320-stage.ci334-stage:not(.ci382-flat),
body.f380.f382.f384.f385 .ci-wrap:not(.ci337-stage).ci334-stage:not(.ci382-flat),
body.f380.f382.f384.f385 .ci-wrap:not(.ci337-stage).ci320-stage.ci334-stage:not(.ci382-flat) {
    --sw: 143.95svh;
    --sh: 100svh;
    --sx: calc((100svw - 143.95svh) / 2
        + max(0px, (100dvw - 100svw) / 2));
    --sy: max(0px, 100dvh - 100svh); }
}
/* BUILD 334's rule (4): short landscape (phones) —
   the same fit by height */
@media (orientation: landscape) and (max-height: 500px) {
body.f384.f385 .ci-wrap:not(.ci337-stage).ci334-stage:not(.ci382-flat),
body.f384.f385 .ci-wrap:not(.ci337-stage).ci320-stage.ci334-stage:not(.ci382-flat),
body.f380.f382.f384.f385 .ci-wrap:not(.ci337-stage).ci334-stage:not(.ci382-flat),
body.f380.f382.f384.f385 .ci-wrap:not(.ci337-stage).ci320-stage.ci334-stage:not(.ci382-flat) {
    --sw: 143.95svh;
    --sh: 100svh;
    --sx: calc((100svw - 143.95svh) / 2
        + max(0px, (100dvw - 100svw) / 2));
    --sy: max(0px, 100dvh - 100svh); }
}

/* (a2) the name/search step's own era box: on the
   ci337-stage wrap the era ran the fit-by-height
   box at EVERY landscape size (measured off the
   era build in the proof: 1082.5x752 at the
   station, 1582.9x1100 wide), while BUILD 347's
   and BUILD 350's var blocks put the tall box
   there. Restated here, after (a), at higher
   specificity, so the name step's seats land
   exactly where the era put them; the photo
   behind it still paints from (b)'s cover box. */
@media (orientation: landscape) {
body.f380.f382.f384.f385 .ci-wrap.ci334-stage.ci337-stage,
body.f380.f382.f384.f385 .ci-wrap.ci320-stage.ci334-stage.ci337-stage,
body.f384.f385 .ci-wrap.ci334-stage.ci337-stage,
body.f384.f385 .ci-wrap.ci320-stage.ci334-stage.ci337-stage {
    --sw: 143.95svh;
    --sh: 100svh;
    --sx: calc((100svw - 143.95svh) / 2
        + max(0px, (100dvw - 100svw) / 2));
    --sy: max(0px, 100dvh - 100svh); }
}

@media (orientation: landscape) {
/* (b) the photo's own cover box — BUILD 350's
   formulas, kept off the stage vars so the picture
   covers the screen whatever the seats' box does */
body.f384.f385 .ci-wrap.ci334-stage:not(.ci382-flat),
body.f384.f385 .ci-wrap.ci320-stage.ci334-stage:not(.ci382-flat),
body.f380.f382.f384.f385 .ci-wrap.ci334-stage:not(.ci382-flat),
body.f380.f382.f384.f385 .ci-wrap.ci320-stage.ci334-stage:not(.ci382-flat) {
    --cw: max(100svw, 144.019svh);
    --ch: max(69.435svw, 100svh);
    --cx: calc((100svw - var(--cw)) / 2
        + max(0px, (100dvw - 100svw) / 2));
    --cy: calc(max(0px, 100dvh - 100svh)
        - min(var(--ch) * 0.02,
              max(0px, var(--ch) - 100svh))); }
body.f380.f384.f385 .ci-wrap.ci334-stage.ci380-stage.ci380-a::before,
body.f380.f384.f385 .ci-wrap.ci320-stage.ci334-stage.ci380-stage.ci380-a::before,
body.f380.f384.f385 .ci-wrap.ci320-stage.ci321-morning.ci334-stage.ci380-stage.ci380-a::before,
body.f380.f384.f385 .ci-wrap.ci320-stage.ci321-afternoon.ci334-stage.ci380-stage.ci380-a::before,
body.f380.f384.f385 .ci-wrap.ci320-stage.ci321-evening.ci334-stage.ci380-stage.ci380-a::before,
body.f380.f384.f385 .ci-wrap.ci334-stage.ci380-stage.ci380-b::before,
body.f380.f384.f385 .ci-wrap.ci320-stage.ci334-stage.ci380-stage.ci380-b::before,
body.f380.f384.f385 .ci-wrap.ci320-stage.ci321-morning.ci334-stage.ci380-stage.ci380-b::before,
body.f380.f384.f385 .ci-wrap.ci320-stage.ci321-afternoon.ci334-stage.ci380-stage.ci380-b::before,
body.f380.f384.f385 .ci-wrap.ci320-stage.ci321-evening.ci334-stage.ci380-stage.ci380-b::before,
body.f380.f384.f385 .ci-wrap.ci334-stage.ci380-stage.ci380-c::before,
body.f380.f384.f385 .ci-wrap.ci320-stage.ci334-stage.ci380-stage.ci380-c::before,
body.f380.f384.f385 .ci-wrap.ci320-stage.ci321-morning.ci334-stage.ci380-stage.ci380-c::before,
body.f380.f384.f385 .ci-wrap.ci320-stage.ci321-afternoon.ci334-stage.ci380-stage.ci380-c::before,
body.f380.f384.f385 .ci-wrap.ci320-stage.ci321-evening.ci334-stage.ci380-stage.ci380-c::before,
body.f384.f385 .ci-wrap.ci334-stage:not(.ci382-flat)::before,
body.f384.f385 .ci-wrap.ci320-stage.ci334-stage:not(.ci382-flat)::before,
body.f384.f385 .ci-wrap.ci320-stage.ci321-morning.ci334-stage:not(.ci382-flat)::before,
body.f384.f385 .ci-wrap.ci320-stage.ci321-afternoon.ci334-stage:not(.ci382-flat)::before,
body.f384.f385 .ci-wrap.ci320-stage.ci321-evening.ci334-stage:not(.ci382-flat)::before {
    left: var(--cx); top: var(--cy);
    width: var(--cw); height: var(--ch); }

/* (c) the controls at their marble-era seats — the
   same seats under every face class (the rotation
   has one picture to show) and on the stage-wide
   forms, exactly as BUILD 350's block seated its
   own fractions there */
/* the display — block (5): .356 / .231 / .388 x .100 */
body.f380.f384.f385 .ci-wrap.ci380-stage.ci380-a .ci-phonebox,
body.f380.f384.f385 .ci-wrap.ci380-stage.ci380-b .ci-phonebox,
body.f380.f384.f385 .ci-wrap.ci380-stage.ci380-c .ci-phonebox,
body.f384.f385 .ci-wrap.ci334-stage:not(.ci382-flat) .ci-phonebox,
body.f384.f385 .ci-wrap.ci320-stage.ci334-stage:not(.ci382-flat) .ci-phonebox {
    left: calc(var(--sx) + var(--sw) * 0.356);
    top: calc(var(--sy) + var(--sh) * 0.231);
    width: calc(var(--sw) * 0.388);
    height: calc(var(--sh) * 0.100);
    padding: 0 calc(var(--sw) * 0.020); }
/* the keypad — block (5): .357 / .365 / .394 x .402 */
body.f380.f384.f385 .ci-wrap.ci380-stage.ci380-a .ci-pad,
body.f380.f384.f385 .ci-wrap.ci380-stage.ci380-b .ci-pad,
body.f380.f384.f385 .ci-wrap.ci380-stage.ci380-c .ci-pad,
body.f384.f385 .ci-wrap.ci334-stage:not(.ci382-flat) .ci-pad,
body.f384.f385 .ci-wrap.ci320-stage.ci334-stage:not(.ci382-flat) .ci-pad {
    left: calc(var(--sx) + var(--sw) * 0.357);
    top: calc(var(--sy) + var(--sh) * 0.365);
    width: calc(var(--sw) * 0.394);
    height: calc(var(--sh) * 0.402);
    column-gap: calc(var(--sw) * 0.013);
    row-gap: calc(var(--sh) * 0.0135); }
/* the OK form — block (5)'s vertical seat (.792 /
   .096) with BUILD 339's f361 amendment: its left
   and width are the keypad's (.357 / .394) */
body.f380.f384.f385 .ci-wrap.ci380-stage.ci380-a #ciPhoneForm,
body.f380.f384.f385 .ci-wrap.ci380-stage.ci380-b #ciPhoneForm,
body.f380.f384.f385 .ci-wrap.ci380-stage.ci380-c #ciPhoneForm,
body.f384.f385 .ci-wrap.ci334-stage:not(.ci382-flat) #ciPhoneForm,
body.f384.f385 .ci-wrap.ci320-stage.ci334-stage:not(.ci382-flat) #ciPhoneForm {
    left: calc(var(--sx) + var(--sw) * 0.357);
    top: calc(var(--sy) + var(--sh) * 0.792);
    width: calc(var(--sw) * 0.394);
    height: calc(var(--sh) * 0.096); }
/* the QR tile — block (5): .763 / .217, at the
   display's right (the crisp dress is BUILD 350's,
   untouched) */
body.f380.f384.f385 .ci-wrap.ci380-stage.ci380-a .ci-qr315,
body.f380.f384.f385 .ci-wrap.ci380-stage.ci380-b .ci-qr315,
body.f380.f384.f385 .ci-wrap.ci380-stage.ci380-c .ci-qr315,
body.f384.f385 .ci-wrap.ci334-stage:not(.ci382-flat) .ci-qr315,
body.f384.f385 .ci-wrap.ci320-stage.ci334-stage:not(.ci382-flat) .ci-qr315 {
    left: calc(var(--sx) + var(--sw) * 0.763);
    top: calc(var(--sy) + var(--sh) * 0.217);
    width: calc(var(--sw) * 0.110); }
/* the Back pill — block (5): the top left, .058 /
   .058, in from the corner over the leaves */
body.f380.f384.f385 .ci-wrap.ci380-stage.ci380-a .ci-back327,
body.f380.f384.f385 .ci-wrap.ci380-stage.ci380-b .ci-back327,
body.f380.f384.f385 .ci-wrap.ci380-stage.ci380-c .ci-back327,
body.f384.f385 .ci-wrap.ci334-stage:not(.ci382-flat) .ci-back327,
body.f384.f385 .ci-wrap.ci320-stage.ci334-stage:not(.ci382-flat) .ci-back327 {
    left: calc(var(--sx) + var(--sw) * 0.058);
    top: calc(var(--sy) + var(--sh) * 0.058); }
/* the search icon — BUILD 330's seat (f346): the
   top right corner */
body.f380.f384.f385 .ci-wrap.ci380-stage.ci380-a .ci346-find,
body.f380.f384.f385 .ci-wrap.ci380-stage.ci380-b .ci346-find,
body.f380.f384.f385 .ci-wrap.ci380-stage.ci380-c .ci346-find,
body.f384.f385 .ci-wrap.ci334-stage:not(.ci382-flat) .ci346-find,
body.f384.f385 .ci-wrap.ci320-stage.ci334-stage:not(.ci382-flat) .ci346-find {
    left: calc(var(--sx) + var(--sw) * 0.982
        - max(44px, calc(var(--sw) * 0.046)));
    top: calc(var(--sy) + var(--sh) * 0.052); }
/* the sign-ins icon — BUILD 335's seat (f353):
   beside the search, one icon-width to its left */
body.f380.f384.f385 .ci-wrap.ci380-stage.ci380-a .ci353-review,
body.f380.f384.f385 .ci-wrap.ci380-stage.ci380-b .ci353-review,
body.f380.f384.f385 .ci-wrap.ci380-stage.ci380-c .ci353-review,
body.f384.f385 .ci-wrap.ci334-stage:not(.ci382-flat) .ci353-review,
body.f384.f385 .ci-wrap.ci320-stage.ci334-stage:not(.ci382-flat) .ci353-review {
    left: calc(var(--sx) + var(--sw) * 0.982
        - max(44px, calc(var(--sw) * 0.046)) * 2
        - var(--sw) * 0.014);
    top: calc(var(--sy) + var(--sh) * 0.052); }

/* (f) the emblem ring re-seated on the photo's
   emblem (see the header). Only the seat is
   restated; BUILD 334's sheen, annulus mask,
   blend, blur and spin ride along untouched. */
body.f380.f382.f384.f385 .ci-wrap.ci380-stage .ci-ringglow334,
body.f380.f382.f384.f385 .ci-wrap.ci380-stage.ci380-a .ci-ringglow334,
body.f380.f382.f384.f385 .ci-wrap.ci380-stage.ci380-b .ci-ringglow334,
body.f380.f382.f384.f385 .ci-wrap.ci380-stage.ci380-c .ci-ringglow334,
body.f384.f385 .ci-wrap.ci380-stage .ci-ringglow334,
body.f380.f382.f384.f385 .ci-wrap.ci-stage-wide:not(.ci382-flat) .ci-ringglow334,
body.f384.f385 .ci-wrap.ci-stage-wide:not(.ci382-flat) .ci-ringglow334 {
    width: calc(var(--cw) * 0.2605);
    height: calc(var(--cw) * 0.2605);
    left: calc(var(--cx) + var(--cw) * 0.0607);
    top: calc(var(--cy) + var(--ch) * 0.271
        - var(--cw) * 0.1303); }

/* (g) the phone-box trace (see the header). The
   band is the pseudo's padding ring, 3px wide,
   outset 3px from the box's border box, corner
   radius the box's own 20px + the outset. */
body.f380.f382.f384.f385 .ci-wrap.ci380-stage .ci-digits::before,
body.f384.f385 .ci-wrap.ci380-stage .ci-digits::before,
body.f380.f382.f384.f385 .ci-wrap.ci-stage-wide:not(.ci382-flat) .ci-digits::before,
body.f384.f385 .ci-wrap.ci-stage-wide:not(.ci382-flat) .ci-digits::before {
    content: ""; position: absolute;
    inset: -3px; border-radius: 23px;
    padding: 3px; pointer-events: none;
    background: conic-gradient(from var(--ci385a),
        rgba(255, 240, 200, 0) 0deg,
        rgba(255, 214, 110, 0.55) 25deg,
        rgba(255, 248, 218, 1) 45deg,
        rgba(255, 214, 110, 0.55) 65deg,
        rgba(255, 240, 200, 0) 90deg,
        rgba(255, 240, 200, 0) 360deg);
    -webkit-mask: linear-gradient(#000 0 0) content-box,
        linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask: linear-gradient(#000 0 0) content-box,
        linear-gradient(#000 0 0);
    mask-composite: exclude;
    filter: drop-shadow(0 0 6px rgba(255, 190, 80, 0.55));
    mix-blend-mode: screen;
    animation: ci385travel 5.5s linear infinite; }

/* (d) THE BOTTOM ROW — SETTLED by the owner's
   earlier-version direction (Nov 5, 2026,
   9:09 AM: the original layout — wide 0,
   backspace at the lower right).
   ACTIVE — variant A, the marble-era row the
   owner's layout note describes ("backspace at
   the lower right of keypad"): the 0 is WIDE,
   spanning columns 1-2 (the f334 stage placement),
   and the delete key sits at the lower right,
   column 3.
   Variant B — BUILD 348's row (the 0 a normal
   single key in column 1, the delete beside it in
   column 2): delete the two rules below and
   BUILD 348's f382 placements govern again. */
body.f380.f382.f384.f385 .ci-wrap.ci334-stage .ci-key[data-k="0"],
body.f380.f382.f384.f385 .ci-wrap.ci320-stage.ci334-stage .ci-key[data-k="0"] {
    grid-column: 1 / 3; grid-row: 4; }
body.f380.f382.f384.f385 .ci-wrap.ci334-stage .ci-key[data-k="back"],
body.f380.f382.f384.f385 .ci-wrap.ci320-stage.ci334-stage .ci-key[data-k="back"] {
    grid-column: 3 / 4; grid-row: 4; }
} /* landscape */

/* BUILD 351 (e) — BUILD 347's glow layers stay
   down on every sign-in step and wrap state while
   Check385 shows (see the f385 header). Unscoped
   on purpose: the phone step, the name/search
   step, the review step and the flat (ci382-flat)
   wrap all sit under this. BUILD 334's ring is
   NOT here — item (f) re-seats it on the photo's
   emblem instead. BUILD 347's layers also stay
   down under Check384's own rule; these restate
   them under the pair so it does not ride on one
   gate. */
body.f384.f385 .ci380-ringglow,
body.f384.f385 .ci380-welglow {
    display: none; }
@media (prefers-reduced-motion: reduce) {
  body.f384.f385 .ci-wrap .ci-digits::before {
      animation: none; } }

/* ================================================================
   BUILD 352, item 1 (gate Features:Check386; the layout's
   "f386" body class rides beside f385 exactly when the gate
   shows — with Check386 off no rule below can match and the
   trace stays BUILD 351's, byte for byte). The owner's words
   (Nov 5, 2026, 9:35 AM): "The glow on phone number must
   contour the box which is not rectangular." BUILD 351's
   trace (item (g) of the f385 block above) rides
   .ci-digits::before with a corner radius of 23px — a
   generic rounded rect. The display box is NOT a rounded
   rect: its governing seat rule (the BUILD 334 stage rule
   for .ci-phonebox) declares border-radius: 999px, a true
   pill whose ends are semicircles of half the box's height.
   Outset 1px from that border (the pseudo's inset -3px
   against the box's 2px border), the true contour is the
   same stadium with its radius grown by the outset — which
   is exactly what the box's own declaration produces on
   the pseudo: 999px clamps to half the pseudo's height,
   i.e. the box's clamped radius plus the outset, at every
   size, with nothing hard-coded. So this block restates
   ONLY the radius, with the box's own value; the wedge,
   the mask band, the drop shadow and the 5.5s loop are
   BUILD 351's rule, untouched, and BUILD 351's emblem
   ring is not in this block at all.
   ================================================================ */
body.f380.f382.f384.f385.f386 .ci-wrap.ci380-stage .ci-digits::before,
body.f384.f385.f386 .ci-wrap.ci380-stage .ci-digits::before,
body.f380.f382.f384.f385.f386 .ci-wrap.ci-stage-wide:not(.ci382-flat) .ci-digits::before,
body.f384.f385.f386 .ci-wrap.ci-stage-wide:not(.ci382-flat) .ci-digits::before {
    border-radius: 999px; }

/* ================================================================
   BUILD 352, item 2 (gate Features:Check387; the layout's
   "f387" body class — with Check387 off no rule below can
   match and the picker stays BUILD 351's, byte for byte).
   The dress of the Check378 confirm button's thank-you
   state (the content itself is swapped in by the picker's
   own submit script and by the locked re-render, both
   gated in CheckIn.cshtml): a white circle with a green
   check that pops in, then three soft white dots that
   gently light one after another — opacity .35 to 1 on a
   slow 2.4s cycle, staggered .8s — the exact behaviour of
   the sample the owner approved (Nov 5, 2026, 9:40 AM,
   after "that's too much flashing" ruled out the coloured
   chase: no colour changes, no bright flashing, no pulse
   rings). Nothing else on the picker is touched — no
   background, icon or photo changes (the owner's scope
   guard, Nov 5, 2026, 9:41 AM).
   ================================================================ */
@keyframes ci387pop { 0% { transform: scale(0); }
    70% { transform: scale(1.25); }
    100% { transform: scale(1); } }
@keyframes ci387breathe { 0%, 100% { opacity: .35; }
    50% { opacity: 1; } }
body.f387 .ci378-confirm .ci387-check {
    display: inline-block; width: 1.4em; height: 1.4em;
    border-radius: 50%; background: #fff; color: #1f9d04;
    font-size: .8em; line-height: 1.4em; text-align: center;
    vertical-align: -.28em; margin-right: .45em;
    animation: ci387pop .45s ease forwards; }
body.f387 .ci378-confirm .ci387-dot {
    display: inline-block; width: .45em; height: .45em;
    border-radius: 50%; background: #fff; opacity: .35;
    margin-left: .3em; vertical-align: .05em;
    animation: ci387breathe 2.4s ease-in-out infinite; }
body.f387 .ci378-confirm .ci387-dot.d2 {
    animation-delay: .8s; }
body.f387 .ci378-confirm .ci387-dot.d3 {
    animation-delay: 1.6s; }
@media (prefers-reduced-motion: reduce) {
  body.f387 .ci378-confirm .ci387-check {
      animation: none; }
  body.f387 .ci378-confirm .ci387-dot {
      animation: none; opacity: .85; } }

/* ================================================================
   BUILD 354, item 1 (gate Features:Check391; the layout's
   "f391" body class rides beside f385 exactly when the gate
   shows — with Check391 off no rule below can match and the
   emblem layer is never built, so every surface stays
   BUILD 353's, byte for byte). The owner's words (Nov 5,
   2026): adjust the sign-in A+ to carry the laurels "on
   left and right side like my logo from the website". The
   station photo's burned-in emblem (A+ over a lotus, no
   laurels) stays untouched IN THE FILE; the real emblem
   (logo-emblem.png — A+ with a laurel branch on EACH side
   + NAILS) rides as a LIVE layer (.ci391-emblem, built by
   the gate's own script block in CheckIn.cshtml) seated
   inside the photo's glowing ring at the seat measured
   off the owner's file (design/signin-background/
   background.png, 1505x1045): ring centre (288, 294),
   medallion disc radius 170 (the bright rim peaks ~177).
   The owner's approved sample (design/signin-logo/
   sample-v2.png, "Position OK now") is the seat of
   record. The layer is seated in the stage's own
   cover-box terms — the --cx / --cy / --cw / --ch of
   BUILD 351 (b)'s photo box, the same terms BUILD 385
   (f) seats the ring in — so it tracks the photo at
   every landscape size:
     width  = 340/1505 of the box  = 0.22591
     left   = (288-170)/1505       = 0.07841
     top    = 294/1045 of the box height (0.28134)
              minus the radius in box-width terms
              (170/1505 = 0.11296)
   It sits INSIDE the ring: the photo's ::before rides
   at z-index 1 (the face-era seat), so the layer ties
   it at z-index 1 and wins on tree order (the pseudo
   is the wrap's first child, the layer follows); the
   ring layer shares z-index 1 and paints above it,
   later in tree order, exactly as it paints above
   the photo — and every control rides above both.
   The Check385/386 glow is not modified. The layer is
   clipped to the disc (border-radius 50%) so the
   emblem's square corners never cover the ring.
   LANDSCAPE ONLY, like the photo itself — portrait
   never paints the photo and never shows the layer
   (the base rule below keeps it display:none wherever
   the seat rules do not reach).
   ================================================================ */
body.f391 .ci391-emblem { display: none; }
@media (orientation: landscape) {
body.f380.f382.f384.f385.f391 .ci-wrap.ci380-stage .ci391-emblem,
body.f384.f385.f391 .ci-wrap.ci380-stage .ci391-emblem,
body.f380.f382.f384.f385.f391 .ci-wrap.ci-stage-wide:not(.ci382-flat) .ci391-emblem,
body.f384.f385.f391 .ci-wrap.ci-stage-wide:not(.ci382-flat) .ci391-emblem {
    display: block;
    position: absolute;
    z-index: 1;
    pointer-events: none;
    width: calc(var(--cw) * 0.22591);
    height: calc(var(--cw) * 0.22591);
    left: calc(var(--cx) + var(--cw) * 0.07841);
    top: calc(var(--cy) + var(--ch) * 0.28134
        - var(--cw) * 0.11296);
    border-radius: 50%;
    overflow: hidden; }
body.f391 .ci391-emblem img {
    width: 100%; height: 100%; display: block; }
}

/* ================================================================
   BUILD 354, item 2 (gate Features:Check392; the layout's
   "f392" body class — with Check392 off no rule below can
   match and every surface stays BUILD 353's, byte for
   byte). The serving half of the owner's artwork audit
   (Nov 5, 2026, 12:36 PM: separate iPad and iPhone photo
   versions):
   (a) THE HEADER HERO. While the gate shows, _SiteHeader
   renders the hero as a <picture>: the wide hero.jpg is
   the <img>, the medallion cluster is the phone <source>
   (max-width 640px), so a phone downloads ONLY the
   cluster and a larger screen ONLY the wide hero. The
   standing <=640px rule hides .hw-hero-main (it was the
   wide file's slot); while this gate shows the slot
   stays visible at phone widths and carries the cluster
   art in the very slot the cluster's own rule rendered
   it in — same width, same height, same pixels.
   (b) THE SIGN-IN PHOTO. In phone landscape (landscape,
   max-width 1000px — the iPad/station at 1180px keeps
   the full file) the stage's ::before serves the
   phone-sized copy of the owner's scene
   (station-signin-photo350-phone.jpg, 1242x862 — the
   widest phone cover box measures 932 CSS px, so the
   copy keeps a 1.33x headroom — derived from the
   owner's original design/signin-background/
   background.png). Only the background IMAGE changes:
   the cover box, the seats, the Check391 emblem seat
   and the Check385/386 glow all read the same
   fractions of the same scene and track identically.
   The selector lists below mirror BUILD 350's image
   rules selector for selector, with f392 added.
   ================================================================ */
@media (max-width: 640px) {
    body.f392 .hw-hero .hw-hero-main { display: block; }
}
/* (c) THE HERO, COMPLETE (owner, Nov 5, 2026, 12:52 PM,
   with a screenshot of the live homepage on his laptop:
   "Logo got cut off, Thank you... missing bottom"). The
   cause is the standing desktop rule at the top of this
   file's check259 block: at min-width 992px the hero img
   is forced into a 150px-tall full-width box with
   object-fit: cover, which shows only a middle slice of
   the artwork — and the standing hero.jpg is itself a
   ratio slice of the sheet piece, so the medallion's
   bottom and the artwork's lowest text line ("CLIENTS")
   are cut twice over. While this gate shows, the band
   takes the artwork's TRUE aspect (the gated <picture>
   serves hero-full.jpg — the complete sheet piece,
   derived in this build) at every width: the height
   cap below simply does not apply. Gate off: the 150px
   cover crop stands exactly as today. */
@media (min-width: 992px) {
    body.f392 .hw-hero .hw-hero-main { height: auto; }
}
@media (orientation: landscape) and (max-width: 1000px) {
body.f380.f384.f392 .ci-wrap.ci334-stage.ci380-stage.ci380-a::before,
body.f380.f384.f392 .ci-wrap.ci320-stage.ci334-stage.ci380-stage.ci380-a::before,
body.f380.f384.f392 .ci-wrap.ci320-stage.ci321-morning.ci334-stage.ci380-stage.ci380-a::before,
body.f380.f384.f392 .ci-wrap.ci320-stage.ci321-afternoon.ci334-stage.ci380-stage.ci380-a::before,
body.f380.f384.f392 .ci-wrap.ci320-stage.ci321-evening.ci334-stage.ci380-stage.ci380-a::before,
body.f380.f384.f392 .ci-wrap.ci334-stage.ci380-stage.ci380-b::before,
body.f380.f384.f392 .ci-wrap.ci320-stage.ci334-stage.ci380-stage.ci380-b::before,
body.f380.f384.f392 .ci-wrap.ci320-stage.ci321-morning.ci334-stage.ci380-stage.ci380-b::before,
body.f380.f384.f392 .ci-wrap.ci320-stage.ci321-afternoon.ci334-stage.ci380-stage.ci380-b::before,
body.f380.f384.f392 .ci-wrap.ci320-stage.ci321-evening.ci334-stage.ci380-stage.ci380-b::before,
body.f380.f384.f392 .ci-wrap.ci334-stage.ci380-stage.ci380-c::before,
body.f380.f384.f392 .ci-wrap.ci320-stage.ci334-stage.ci380-stage.ci380-c::before,
body.f380.f384.f392 .ci-wrap.ci320-stage.ci321-morning.ci334-stage.ci380-stage.ci380-c::before,
body.f380.f384.f392 .ci-wrap.ci320-stage.ci321-afternoon.ci334-stage.ci380-stage.ci380-c::before,
body.f380.f384.f392 .ci-wrap.ci320-stage.ci321-evening.ci334-stage.ci380-stage.ci380-c::before,
body.f384.f392 .ci-wrap.ci334-stage:not(.ci382-flat)::before,
body.f384.f392 .ci-wrap.ci320-stage.ci334-stage:not(.ci382-flat)::before,
body.f384.f392 .ci-wrap.ci320-stage.ci321-morning.ci334-stage:not(.ci382-flat)::before,
body.f384.f392 .ci-wrap.ci320-stage.ci321-afternoon.ci334-stage:not(.ci382-flat)::before,
body.f384.f392 .ci-wrap.ci320-stage.ci321-evening.ci334-stage:not(.ci382-flat)::before {
    background-image: url("/images/station-signin-photo350-phone.jpg?v=354"); }
}

/* ================================================================
   BUILD 355, item 1 (gate Features:Check393): THE PEDICURE
   BAND GOES BLUE. Owner correction, Nov 5, 2026, 1:14 PM
   (replacing this item's first brief, which would have
   resized the selected check badge): "do not change color
   of the check, change color of the design to be mainly
   blue instead" + "keep same size of the check". The
   problem he saw: the selected card's GREEN check badge
   sits on the Pedicure card's GREEN band and drowns in
   it. So the badge is not touched at all — its size,
   green radial background, gold border and seat stay
   exactly as BUILD 354 ships them — and the PEDICURE
   band (.ci378-band-pedi, the green gradient) becomes a
   MAINLY BLUE gradient of the same 3-stop structure and
   comparable depth, below, while the layout wears the
   "f393" body class. The white name text and the band
   icon read on the blue as they did on the green, the
   :has(input:checked) brightening keeps working on top
   of it, and the green check now stands clearly apart
   from the band. Nails (pink) and Wax (purple) are
   untouched. The scan page carries the identical blue
   in its own gated block (one design, no divergence).
   With Check393 off no rule below can fire and the
   picker is BUILD 354's exactly, green band included.
   ================================================================ */
body.f393 .ci378-band-pedi { background: linear-gradient(180deg, #7fb2e0 0%, #2f6fb3 55%, #1d4e80 100%); }

/* ================================================================
   BUILD 355, item 4 (gate Features:Check396): THE CONFIRM'S
   ARROW. Owner, Nov 5, 2026, 1:18 PM: "Add an arrow to point
   to the right at this button, meaning customer is checking
   in. After clicked, change to the message we set with
   blinking white as designed (remove the arrow)". While the
   layout wears the "f396" body class, the picker's confirm
   button carries a .ci396-arrow span (the "›" glyph, the
   button's own white, its own weight, sized with the text)
   at the text's right. The span is emitted only in the
   button's "Check me in" state: the Check387 client swap
   replaces the button's content wholesale (arrow gone), the
   server's locked re-render never emits it, and the second
   rule below hides any arrow inside a disabled confirm for
   good measure. With Check396 off no rule below can fire
   and no span is emitted — the button is BUILD 354's
   exactly.
   ================================================================ */
body.f396 .ci378-confirm .ci396-arrow { display: inline-block;
    margin-left: .4em; font-weight: 800; }
body.f396 .ci378-confirm:disabled .ci396-arrow { display: none; }

/* ================================================================
   BUILD 355, item 5 (gate Features:Check397): THE CARD FRAME
   GOES GOLD. Owner, Nov 5, 2026, 1:19 PM, with his close-up
   of the Nails card: "Why there is a white band around the
   image? It's supposed to be a gold band". The white is the
   card body's own background — .ci378-inner carries #fff —
   peeking past the photo and band edges, the seam between
   them above all. While the layout wears the "f397" body
   class the inner background is the design's own border
   gold (#d9a441): colour only — no size, layout or radius
   changes — on all three cards, selected and unselected
   (the selected gold glow and #ffcf3f border are separate
   rules and keep working). The scan page carries the
   identical restatement in its own gated block. With
   Check397 off the frame is BUILD 354's white exactly.
   ================================================================ */
body.f397 .ci378-inner { background: #d9a441; }

/* ================================================================
   BUILD 356, item 1 (gate Features:Check398): THE PICKER GOES
   FULL-BLEED AND THE REPEATED TOP STRIP GOES. Owner, Nov 5,
   2026: the scene already carries the big logo — the public
   header strip above it (the plain A+ circle + "A+ NAILS") is
   repeated, and in iPad landscape the scene does not fill the
   screen: the sign-in wrap centres at 880px leaving a wide
   cream margin at the left, while the stage's own 1050px width
   overflows it to the right (the Wax card cut) and the page
   stack pushes the "Check me in" button below the fold. While
   the layout wears the "f398" body class AND a picker stage is
   on the page (the :has test — every picker surface, both
   dresses, and no other step), the header strip (themed
   .hw-top or the plain site header) never renders, and the
   stage is fixed edge to edge: no margins, no rounded floating
   card, no shadow. Inside, the stage becomes a column flex so
   the cards area takes exactly the height the banner and the
   confirm leave: at 1180x752 and 1780x1100 all three cards and
   the full confirm sit inside the screen with nothing cut and
   no scrolling; in portrait the stacked cards keep their
   natural height and the stage scrolls inside itself, still
   edge to edge. The scene art, the bands, the glyphs and the
   gate's own geometry rules are untouched — only the frame
   around the scene changes. With Check398 off, none of the
   rules below can fire and the picker is BUILD 355's exactly.
   ================================================================ */
body.f398:has(.ci378-stage) .hw-top,
body.f398:has(.ci378-stage) header.site-header { display: none; }
body.f398 .ci378-stage { position: fixed; inset: 0; z-index: 60;
    width: auto; height: 100dvh; margin: 0; border-radius: 0;
    box-shadow: none; overflow-y: auto; display: flex;
    flex-direction: column; }
body.f398 .ci378-banner { flex: 0 0 auto; }
@media (min-width: 700px) {
    /* The desk banner is a TEXT block whose every
       measure scales with the stage's WIDTH
       (padding-top: 21.5%, the greeting at 5.5cqw,
       the question at 2.65cqw): at iPad widths it
       alone eats half the screen height and pushes
       the cards and the confirm off the bottom.
       While the gate shows, at desk widths its
       measures hang on the viewport HEIGHT instead
       — the same proportions at 1180x752 the design
       has today, and a scene that fits at
       1780x1100 too. Portrait keeps the shipped
       phone dress untouched. */
    body.f398 .ci378-banner { padding-top: 4vh; }
    body.f398 .ci378-greet { font-size: 8vh; }
    body.f398 .ci378-ask { font-size: 3vh; }
}
body.f398 .ci378-cards { flex: 1 1 auto; min-height: 0; }
body.f398 .ci378-card { display: flex; }
body.f398 .ci378-inner { flex: 1 1 auto; height: 100%; }
body.f398 .ci378-confirm { flex: 0 0 auto; }
/* BUILD 356, item 1 (Check398, owner's addition
   Nov 5, 2026, 2:49 PM): the Start over the picker
   renders inside the scene (CheckIn.cshtml moves it
   into the stage while the gate shows) — centred in
   the stage's flex column under the confirm, on the
   scene's own background (no box of its own: a
   control over artwork keeps a cleaned background),
   in the link's shipped dress. It counts in the
   stage's fit like every other child, so the whole
   box stays inside the screen. */
body.f398 .ci398-startover { flex: 0 0 auto;
    align-self: center; margin: 10px 0 14px; }
/* BUILD 356, item 1 (Check398, owner's addition
   Nov 5, 2026, 2:51 PM): the iPhone fit — in
   portrait the shipped narrow-window dress stacks
   the cards at their natural aspect (flex: none,
   aspect-ratio 362/250), which pushes the
   "Check me in" button below the fold: the box
   did not fit the phone's screen. While the gate
   shows, at portrait widths the three cards share
   the stage's height by flex like they do in
   landscape, the inner's fixed aspect lets go,
   and the WHOLE box — scene, cards, the confirm
   (arrow and thank-you state included) and Start
   over — sits inside the iPhone viewport with no
   scrolling and nothing cut. The photos cover-
   crop inside their shorter frames; the bands
   keep their share. Portrait only; landscape
   above is untouched. */
@media (max-width: 699px) {
    body.f398 .ci378-card { flex: 1 1 0;
        min-height: 0; }
    body.f398 .ci378-inner { aspect-ratio: auto; }
}

/* ================================================================
   BUILD 356, item 4 (gate Features:Check401): THE NAME STEP'S
   MESSAGE BAR, HIGHLIGHTED HARD. Owner, Nov 5, 2026: "Too hard
   to see. Highlight really hard so customer can see clearly" —
   the approved sample (design/name-highlight/
   sample-name-highlight-v3.png) measured off the file: a
   solid red bar #d01818 with a dark-red #6e0606 border and
   the words in big white bold capitals. The class is carried
   only by the first-timer name step's two message bars (the
   check336 dress's .ci336-error and the classic step's
   .ci-error) and only while the gate shows — the wording is
   unchanged; text-transform does the shouting. Other steps'
   bars keep the pale dress. With Check401 off no element
   carries the class and the bar is BUILD 355's exactly.
   ================================================================ */
.ci401-msg { background: #d01818; border: 3px solid #6e0606;
    color: #fff; font-weight: 800; font-size: 25px;
    text-transform: uppercase; letter-spacing: .02em;
    padding: 16px 14px; }

/* ================================================================
   BUILD 356, item 5 (gate Features:Check402): THE PICKER CARDS'
   GOLD FRAME, REDESIGNED SO IT CANNOT BREAK. Owner, Nov 5, 2026,
   2:41 PM (his close-up of the live Nails card): "The border
   around these 3 buttons are not right. They have a white spot?
   You need to redesign the buttons to avoid the white hold, and
   make the buttons to have gold border properly."
   Root cause, measured in diag/check356: the frame was a lone
   2px border on a 20px radius. Along the straight runs its
   middle row is solid #d9a441, but at the corner arcs EVERY
   pixel of the stroke is an anti-aliased edge pixel blending
   the gold into whatever sits behind the card — the pale scene
   art — so the arcs wash out whitish and the border looks
   broken, worst at the top corners against the scene's
   brightest wash; the photo's own near-white top strip inside
   the card heightens the break. Nothing behind the border was
   wrong (the scene is the cleaned backing the design wants);
   the stroke itself had no solid core.
   The redesign changes no measurement the owner has approved —
   the 2px border, the 20px radius, the card geometry and the
   badge seats are all untouched — and gives the frame its core
   on the true outer edge: while the gate shows, the inner
   carries a 2px gold ring (a box-shadow spread, concentric
   with the border — its outer radius is the border's + 2, its
   inner edge meets the border's outer edge exactly), so the
   frame is a continuous 4px band of gold whose middle two
   pixels cannot wash out at any point of the path, corners
   included; only the outermost pixel still blends to the
   scene, as any edge must. The shipped soft drop shadow rides
   after the ring. Selected, the ring turns the bright #ffcf3f
   together with the border (Check378's selected border colour)
   so the lit frame is continuous too. With Check402 off, no
   ring: the lone 2px border and its white-spotted arcs, exactly
   as BUILD 355 shipped.
   ================================================================ */
body.f402 .ci378-inner { box-shadow: 0 0 0 2px #d9a441,
    0 6px 18px rgba(120, 72, 20, .18); }
body.f402 .ci378-card:has(input:checked) .ci378-inner {
    box-shadow: 0 0 0 2px #ffcf3f,
    0 6px 18px rgba(120, 72, 20, .18); }

/* ================================================================
   BUILD 358 (gates Features:Check406-409, owner Nov 5, 2026,
   4:05-4:06 PM, from his DEV screenshots of the phone
   first-timer flow and the wide picker). Four fixes to the
   sign-in surfaces BUILD 356 dressed. With a gate off, its
   rules below cannot fire and the surface is BUILD 357's
   byte for byte.
   ================================================================ */

/* BUILD 358, item 1 (Check406): the first-timer name step
   loses its top A+ strip and its box fills the screen.
   Desk, Check336 dress: the in-stage head (the A+ circle
   + A+ NAILS row) is gone and the card becomes the whole
   screen — full width, full height, square corners, no
   border or shadow, its own scroll if a short frame
   ever needs it; the stage's bottom padding goes too. */
body.f406 .ci336-stage .ci336-head { display: none; }
body.f406 .ci-wrap.ci336-stage { padding: 0; }
body.f406 .ci336-stage .ci336-card { width: 100%; max-width: none;
    flex: 1 1 auto; min-height: 0; margin-top: 0;
    border: none; border-radius: 0; box-shadow: none;
    overflow-y: auto; }
/* Desk, classic dress (Check336 off): the step's page
   band hides (the same :has(+ ...) pattern Check316
   uses) and the wrap itself becomes the full-screen
   box, fixed edge to edge with room under the pill. */
body.f406 .ci-band:has(+ .ci-wrap > form[action*="handler=SignUp"] .ci378-cards) { display: none; }
body.f406 .ci-wrap:has(> form[action*="handler=SignUp"] .ci378-cards) {
    position: fixed; inset: 0; z-index: 60;
    max-width: none; margin: 0; overflow-y: auto;
    padding-bottom: 88px; }

/* BUILD 358, item 2 (Check407): the selected card's
   green check badge sized in container units resolves
   against the stage on the picker — but the name
   step's cards have no container ancestor, so there
   the same units fell back to the viewport and the
   badge blew up into a clipped semicircle. While the
   gate shows, every card is its own container and the
   badge, the service name and the arrow carry
   card-relative sizes at the picker's exact
   proportions (the badge is 31.2% of the card's width
   — the same fraction 9.9cqw of the stage was of the
   stage-sized card — seated at the standing right/top,
   its font scaled by the same ratio; the portrait
   values are the standing phone proportions restated
   per card). The badge's design — green radial, gold
   border, white check — does not change. */
body.f407 .ci378-inner { container-type: inline-size; }
body.f407 .ci378-check { width: 31.2cqw; height: 31.2cqw;
    font-size: 18.4cqw; }
body.f407 .ci378-name { font-size: 8.04cqw; }
body.f407 .ci378-go { width: 12.9cqw; height: 12.9cqw;
    font-size: 9.45cqw; }
@media (max-width: 640px) {
    body.f407 .ci378-check { width: 25cqw; height: 25cqw;
        font-size: 15.5cqw; }
    body.f407 .ci378-name { font-size: 5.6cqw; }
    body.f407 .ci378-go { width: 8.6cqw; height: 8.6cqw;
        font-size: 6.4cqw; }
}
/* Portrait seat for the badge: the portrait cards
   share the stage's height by flex (Check398), so
   their height is no longer the design's aspect and
   the standing top seat (58.6% of height) would push
   the width-sized badge past the card's bottom.
   While the gate shows, in portrait the badge seats
   from the bottom at the design's own gap (its
   bottom sat 1.5% of the card's width above the
   frame's bottom edge) — same size, fully inside at
   any card height. */
@media (max-width: 640px) {
    body.f407 .ci378-check { top: auto; bottom: 1.5cqw; }
}

/* BUILD 358, item 3 (Check408): the card photos carried
   the original artwork's drawn frame inside them — a
   cream wedge and a drawn gold arc in every top corner
   — so the photo never filled the frame's corner.
   While the gate shows, the cards use re-cropped
   photos cut inside the drawn frame (new files; the
   shipped photos are untouched and the scan page,
   which shares them, never sees these). The phone
   crops ride the same swap in the portrait dress. */
body.f408 .ci378-photo-nails { background-image: url('/images/signin378/card-nails-358.jpg'); }
body.f408 .ci378-photo-pedi { background-image: url('/images/signin378/card-pedi-358.jpg'); }
body.f408 .ci378-photo-wax { background-image: url('/images/signin378/card-wax-358.jpg'); }
@media (max-width: 640px) {
    body.f408 .ci378-photo-nails { background-image: url('/images/signin378/card-nails-phone-358.jpg'); }
    body.f408 .ci378-photo-pedi { background-image: url('/images/signin378/card-pedi-phone-358.jpg'); }
    body.f408 .ci378-photo-wax { background-image: url('/images/signin378/card-wax-phone-358.jpg'); }
}

/* BUILD 358, item 4 (Check409): the wide-frame picker
   fit. The picker's content ran taller than a short
   wide frame (1250x665 proved 688px of content in a
   665px stage): the stage scrolled, its scrollbar ate
   width and shifted the scene, and the confirm crowded
   the bottom pill bar. While the gate shows, at desk
   widths the stage cannot scroll, the form becomes a
   true flex column ending 60px above the bottom (the
   pill's clearance), and the cards row absorbs the
   height: the cards keep their design size when there
   is room and shrink proportionally (aspect kept) when
   there is not, instead of pushing the confirm off.
   At wide frames — 1800px and up, the stage no more
   than twice as wide as tall — the banner also takes
   the design's own seat: its top padding tracks the
   scene art's width so the greeting and the question
   sit BELOW the art's A+ lockup (whose lowest element,
   the ROWLETT line, ends at 26.2% of the art's height
   = 19.7% of the stage's width), clear of the emblem,
   exactly as the owner's approved design sample has
   them. 1180x752 and 1780x1100 keep their seats. */
@media (min-width: 700px) {
    body.f409 .ci378-stage { overflow: hidden; padding-bottom: 60px; }
    body.f409 .ci378-form { display: flex; flex-direction: column;
        flex: 1 1 auto; min-height: 0; }
    body.f409 .ci378-form > :not(.ci378-cards) { flex: 0 0 auto; }
    body.f409 .ci378-stage .ci378-cards { flex: 1 1 auto;
        min-height: 0; align-items: center;
        justify-content: center; }
    body.f409 .ci378-stage .ci378-card { flex: 0 0 auto;
        height: min(25.07cqw, 100%); aspect-ratio: 362 / 286; }
}
@media (min-width: 1800px) and (max-aspect-ratio: 2/1) {
    body.f409 .ci378-banner { padding-top: 21.6%; }
    body.f409 .ci378-greet { font-size: 7vh; }
    body.f409 .ci378-ask { font-size: 2.6vh; }
    body.f409 .ci378-stage .ci378-cards { margin-top: 0.8vh; }
    body.f409 .ci378-confirm { margin-top: 1.6vh; }
}
/* BUILD 358, item 4 (Check409), portrait half: the
   phone-width desk picker never rendered its cards
   at all — Check398's portrait design has the three
   cards share the stage's height by flex, but the
   form between the stage and the cards is a plain
   block, so the share never engaged and the row
   collapsed to a gold bar (visible in BUILD 356's
   own portrait proof shot). While the gate shows,
   the form is the same flex column as at desk
   widths, ending above the pill bar, and the cards
   take their designed shares of the screen. */
@media (max-width: 699px) {
    body.f409 .ci378-stage { overflow: hidden;
        padding-bottom: 60px; }
    body.f409 .ci378-form { display: flex;
        flex-direction: column; height: 100%;
        min-height: 0; }
    body.f409 .ci378-form > :not(.ci378-cards) {
        flex: 0 0 auto; }
    body.f409 .ci378-cards { flex: 1 1 auto;
        min-height: 0; }
}

/* BUILD 359, item 2 (gate Features:Check411): the
   picture-card picker's "Please pick a service."
   notice beside the "Check me in" button — the
   same red pill the scene's error wears (#b3261e,
   white bold text), in a centered row with the
   button; the row wraps, so on frames with no
   room beside the button the notice drops under
   it. Hidden is the resting state; the gate's
   script in CheckIn.cshtml shows it on an empty
   confirm tap and hides it the moment any
   service is picked. Gate off, none of these
   rules exist and the picker is BUILD 358's. */
body.f411 .ci411-row { display: flex;
    align-items: center; justify-content: center;
    gap: 14px; flex-wrap: wrap; margin-top: 3.6%; }
body.f411 .ci411-row .ci378-confirm { margin: 0; }
body.f411 .ci411-note { background: #b3261e;
    color: #fff; padding: 8px 18px;
    border-radius: 999px; font-size: 17px;
    font-weight: 700; white-space: nowrap; }
body.f411 .ci411-note[hidden] { display: none; }

/* ================================================================
   BUILD 361, item 2 (gate Features:Check414): THE PICKER'S
   SCENE, CLEANED, WITH THE REAL LOGO AT THE UPPER RIGHT.
   Owner, Nov 5, 2026, 5:44 PM: the giant A+ lockup baked
   into the scene sat behind the greeting and the question
   ("The background is behind the text") — the scene the
   stage paints is now the cleaned art (scene-clean-361.jpg:
   the lockup painted out of the owner's scene itself, in
   diag/check361; his shipped scene-clean.jpg is untouched
   and still serves with the gate off), and the salon's
   real emblem rides as a live layer (.ci414-logo, emitted
   by CheckIn.cshtml only while the gate shows) small in
   the stage's upper right corner at the approved sample's
   seat (design/picker-logo-corner/sample-ipad.png: 104px
   tall at 1180x752, 16px from the top, 20px from the
   right — restated here in the stage's own terms: 13.8vh
   tall, 2.1vh down, 1.7% in), clear of the greeting,
   which is centred and never reaches it. With no lockup
   behind the text, Check409's wide-frame banner seat
   (the greeting pushed below where the lockup ended)
   no longer applies: at 1800px and up the banner keeps
   its normal seat and sizes while this gate shows. In
   portrait the emblem takes the phone sample's size.
   Gate off: no .ci414-logo is emitted, the stage paints
   the shipped scene, and the picker is BUILD 360's byte
   for byte.
   ================================================================ */
body.f414 .ci378-stage { background-image: url('/images/signin378/scene-clean-361.jpg?v=361'); }
body.f414 .ci414-logo { position: absolute; top: 2.1vh;
    right: 1.7%; height: 13.8vh; width: auto; z-index: 6;
    pointer-events: none; }
@media (min-width: 1800px) and (max-aspect-ratio: 2/1) {
    body.f414 .ci378-banner { padding-top: 4vh; }
    body.f414 .ci378-greet { font-size: 8vh; }
    body.f414 .ci378-ask { font-size: 3vh; }
    body.f414 .ci378-stage .ci378-cards { margin-top: 3.8%; }
    body.f414 .ci378-confirm { margin-top: 3.6%; }
}
@media (max-width: 699px) {
    body.f414 .ci414-logo { top: 10px; right: 12px;
        height: 19cqw; }
}

/* BUILD 365, item 1 (gate Features:Check418; the
   body class is set in _Layout): the service
   picker's redesigned cards, from the owner's
   own mockup (design/picker-redesign-365/
   design-final.jpg), measured not eyeballed.
   Every picture-card picker surface (the
   station desk picker's found step and name
   step — the .ci378-stage scenes and the name
   step's own box — in both dresses) renders
   the cards as wide horizontal rows of aspect
   738/248: the RIGHT 62% is the service photo
   (card-{key}-365.jpg, cropped from his
   artwork at native resolution, baked name
   tails + chevron disc healed out), the LEFT
   side a soft pink gradient panel rendered
   live carrying the big dark-red (#74080e)
   italic serif name (cap height 25% of the
   card height, font-size 36% of it) and the
   dark-red icon matte-extracted from the same
   artwork (icon-{key}-365.png), name + icon
   vertically centred as one group, icon left
   edge at ~5% of the card width. The old
   per-service colour bands are gone — one
   soft style for Dip, Pedicure and Wax. A
   bright gold frame runs all the way around
   (3px border + 2px outer ring, radius
   4.6% / 13%) and the photo fills to the
   frame with no white at the corners (BUILD
   358's corner discipline rides the new
   inner). The chevron rides in a cream disc
   (30% of the card height) at the bottom-right
   corner — centre 94.3% of the width, 70% of
   the height. A selected card's frame turns
   the check402 bright gold (the ring pattern
   re-stated here so this gate alone frames
   selected cards too); the big legacy check
   is capped to the row height while
   Check420 is off (it reads as "picked"
   without spilling out of the short rows) —
   Check420's own seat is the block below.
   On the desk stages the cards flex-share the
   scene's height (their width is the full
   column, so cqw is the card width there);
   the name runs 12.1cqw where the card holds
   the mockup's aspect, and in vh on the desk
   stages where the flex, not the aspect,
   sets the height. Gate off: no rule here
   applies and BUILD 364's cards render byte
   for byte. */
body.f418 .ci378-cards,
body.f418 .ci378-stage .ci378-cards { flex-direction: column; }
body.f418 .ci378-cards, body.f418 .ci378-stage .ci378-cards { align-items: stretch; }
body.f418 .ci378-stage .ci378-form, body.f418 .ci378-stage .ci378-cards { width: 100%; }
body.f418 .ci378-card { display: block; flex: none; }
/* FIX ROUND (owner, Nov 5, 2026, late): the flex:
   none above is the stacking root-cause guard.
   Measured on the broken build (diag/check365,
   proof365-fix-repro.log): outside the stage,
   a card label keeps the standing flex: 1 1 0
   (and, at portrait widths, Check398's stage-fit
   share, which is not stage-scoped) inside a
   flex column with no definite height — the
   labels collapse to zero height (the container
   ends up as tall as its gaps alone) while the
   aspect-ratio inners keep their full height
   and paint over each other and over the
   "Check me in" pill. Under this gate a card
   outside the stage sizes to its inner instead.
   The stage rule below still owns the stage's
   cards (the flex share is the stage's own
   design, and the stage gives the column its
   definite height). */
body.f418 .ci378-stage .ci378-card { flex: 1 1 0;
    height: auto; aspect-ratio: auto; min-height: 0; }
body.f418 .ci378-inner { flex-direction: row;
    aspect-ratio: 738/248; height: auto;
    background: linear-gradient(100deg, #fadbd2 0%, #fcebe3 45%, #fdf3e8 100%);
    border: 3px solid #d9a441;
    box-shadow: 0 0 0 2px #d9a441, 0 4px 10px rgba(90,50,20,.18);
    border-radius: 4.6% / 13%; }
body.f418 .ci378-stage .ci378-inner {
    aspect-ratio: auto; height: 100%; min-height: 0; }
body.f418 .ci378-card:has(input:checked) .ci378-inner {
    border-color: #ffcf3f;
    box-shadow: 0 0 0 2px #ffcf3f, 0 0 22px 5px rgba(255,190,40,.55); }
body.f418 .ci378-photo { position: absolute;
    top: 0; right: 0; bottom: 0; width: 62%;
    height: auto; flex: none; border-radius: 0;
    background-size: cover;
    background-position: 50% 50%; }
body.f418 .ci378-photo-nails { background-image: url(/images/signin378/card-nails-365.jpg?v=365); }
body.f418 .ci378-photo-pedi { background-image: url(/images/signin378/card-pedi-365.jpg?v=365); background-position: 50% 42%; }
body.f418 .ci378-photo-wax { background-image: url(/images/signin378/card-wax-365.jpg?v=365); }
body.f418 .ci378-band,
body.f418 .ci378-band-nails,
body.f418 .ci378-band-pedi,
body.f418 .ci378-band-wax { background: none; }
body.f418 .ci378-band { position: relative;
    z-index: 1; flex: 1 1 auto; height: 100%;
    flex-direction: row; align-items: center;
    justify-content: flex-start; gap: 4%;
    padding: 0 0 0 5%; }
body.f418 .ci378-icon { height: 52%; width: auto; }
body.f418 .ci378-band-nails .ci378-icon { height: 54%; }
body.f418 .ci378-band-pedi .ci378-icon { height: 40%; }
body.f418 .ci378-band-wax .ci378-icon { height: 53%; }
body.f418 .ci378-name { color: #74080e;
    font-style: italic; text-shadow: none;
    font-size: 12.1cqw; }
body.f418 .ci378-go { position: absolute;
    right: 1%; bottom: 14.5%; height: 30%;
    width: auto; aspect-ratio: 1; margin: 0;
    z-index: 2; display: flex; align-items: center;
    justify-content: center; border-radius: 50%;
    background: radial-gradient(circle at 38% 32%, #fffaf0, #f6e7c3 78%);
    border: 2px solid #b08a34; color: #6e1f16;
    font-size: 5.6cqw; line-height: 1; }
body.f418 .ci378-check { height: 62%;
    width: auto; aspect-ratio: 1; }
@media (min-width: 700px) {
    body.f418 .ci378-stage .ci378-name {
        font-size: 4.9vh; }
    body.f418 .ci378-stage .ci378-go {
        font-size: 2.1vh; }
}
@media (max-width: 699px) {
    body.f418 .ci378-stage .ci378-inner {
        aspect-ratio: auto; }
    body.f418 .ci378-stage .ci378-name {
        font-size: 5.9vh; }
    body.f418 .ci378-stage .ci378-go {
        font-size: 2.7vh; }
}

/* FIX ROUND (owner, Nov 5, 2026, late): ONE picker
   interface for both station flows — while
   Check418 shows, the first-timer name step
   renders the pick state's stage itself
   (CheckIn.cshtml); the only situational pieces
   are the greeting text and this name box,
   seated in the stage's form between the banner
   and the cards, in the scene's own palette so
   it reads as part of the one interface. */
body.f418 .ci418-namebox { width: min(560px, 92%);
    margin: 1.4vh auto 0; }
body.f418 .ci418-namelabel { display: block;
    font-family: var(--font-display); font-weight: 700;
    font-size: 2.9vh; color: #6d3300;
    margin: 0 0 .8vh; }
body.f418 .ci418-nameinput { display: block;
    width: 100%; box-sizing: border-box;
    height: 6.6vh; min-height: 50px;
    border: 2px solid #b0823f; border-radius: 14px;
    background: #fffdf8; padding: 0 18px;
    font-size: 2.9vh; color: #3d2410; }
body.f418 .ci418-nameinput:focus {
    outline: 3px solid rgba(194, 160, 84, .45);
    outline-offset: 1px; }
/* FIX ROUND 2 (owner, Nov 6, 2026): the name
   box's placeholder. "Please enter your name"
   (the input's placeholder attribute, emitted
   with the gated box in CheckIn.cshtml) stands
   in the empty box; tapping into the box
   clears it so she can type (the :focus
   rules); and after a "Check me in" tap with
   the name still empty, the re-rendered step
   marks the input ci418-namewarn (the standing
   name error) and the same words turn bold
   red as the warning — the Check411 notice's
   show-on-empty-submit family. The dresses
   live on the gated input only; gate off, the
   step renders byte for byte. */
body.f418 .ci418-nameinput::placeholder {
    opacity: 1; }
body.f418 .ci418-nameinput:focus::placeholder {
    color: transparent; }
body.f418 .ci418-nameinput.ci418-namewarn::placeholder {
    color: #d01818; font-weight: 700; }
body.f418 .ci418-nameinput.ci418-namewarn:focus::placeholder {
    color: transparent; }
/* FIX ROUND: at desk widths the box compacts —
   the stage's room is spoken for (banner,
   cards, confirm), and a full phone-sized box
   would squeeze the name step's cards well
   below the pick state's. The phone keeps the
   generous touch sizes above. */
@media (min-width: 700px) {
    body.f418 .ci418-namebox { margin-top: .8vh; }
    body.f418 .ci418-namelabel { font-size: 2.2vh;
        margin-bottom: .5vh; }
    body.f418 .ci418-nameinput { height: 5.2vh;
        min-height: 42px; font-size: 2.2vh; }
}

/* BUILD 365, item 3 (gate Features:Check420):
   the green selected check on the NEW cards
   (rides with Check418's dress — alone this
   gate emits nothing).
   FIX ROUND (owner, Nov 5, 2026, late — "The
   checks are super tiny"): the disc is BIG
   again, at BUILD 364's own proportions
   measured off its renders (diag/check365,
   proof365-fix-repro.log): on the desk cards
   the old disc stood 39% of the card height
   (108px on a 277px card, found and name step
   alike); on the phone it stood 90px — 25% of
   the card's width, 57% of its flexed height.
   The new desk disc takes the 39%-of-height
   proportion, centred on the photo's right
   half (centre 80% of the width, 50% of the
   height), the old seat's own neighbourhood,
   clear of the name ink (which ends by 25% of
   the width there) and of the bottom-right
   chevron. On the phone the wide card leaves
   exactly one zone for a big disc: Pedicure's
   name ink reaches 75% of the width and the
   chevron owns the bottom-right, so the disc
   takes 44% of the card height in the
   top-right of the photo (centre 87% of the
   width, 24% of the height) — the largest
   disc that keeps >= 8px from the name ink
   and from the chevron, which stays visible
   on a selected card so the two marks never
   merge. (Percentages resolve against the
   inner's padding box; the proof measures the
   rendered centres and clearances.)
   FIX ROUND 2 (owner, Nov 6, 2026 — "Make
   green check a little bigger and put at the
   right at the middle"): the disc grows
   ~15-20% (desk 39% -> 46% of the card
   height; phone 44% -> 47.5%) and seats at
   the right-middle. The desk seat already stood
   at the middle (centre 80% of the width,
   50% of the height) and keeps it. On the
   phone the true middle is walled off,
   measured on the found step's Pedicure
   card (365.1x143.0): the chevron is a
   41.1px disc centred at 92.6% of the width,
   69.7% of the height, and the name ink ends
   at 75.1% of the width — at centre 50% of
   the height the largest disc holding >= 8px
   from both measures ~37px, SMALLER than
   the fix round's 60.3px. So the phone disc
   takes 47.5% at centre 87% of the width,
   26.5% of the height (~65px on the found
   step, ~46px on the name step) — the
   largest disc, at the lowest seat, that
   keeps >= 8px from the ink and from the
   chevron, which stays visible: the proof's
   first pass at 51% / 28% rendered 69.9px
   but measured a 6.2px ink gap and a 7.0px
   chevron clearance, just under the floor,
   so the disc settles at 47.5% / 26.5%
   (solved clearances ~9px and ~13px,
   re-measured in the proof). The glyph
   grows with the disc (same fill ratio). */
body.f418.f420 label.ci378-card:has(input:checked) .ci378-go {
    display: flex; }
body.f418.f420 .ci378-check { left: 80%;
    right: auto; top: 50%; bottom: auto;
    transform: translate(-50%, -50%); height: 46%;
    width: auto; aspect-ratio: 1;
    font-size: 8.9cqw; background: #1e9e4a; }
@media (min-width: 700px) {
    body.f418.f420 .ci378-stage .ci378-check {
        font-size: 2cqw; }
}
@media (max-width: 699px) {
    body.f418.f420 .ci378-check { left: 87%;
        top: 26.5%; height: 47.5%; }
    body.f418.f420 .ci378-stage .ci378-check {
        font-size: 9.4cqw; }
}

/* BUILD 365, FIX ROUND 2 (gate
   Features:Check429; owner, Nov 6, 2026 —
   "move back space to the right"): the
   sign-in keypad's bottom row. The pad's
   grid order stands [blank] [0] [backspace];
   while the gate shows, the three cells
   re-seat to [0] [blank] [backspace] — the
   backspace key takes the right cell.
   The seats layer over the standing ones:
   the plain pad is a 3-track grid whose
   f382 seats stand 0 at 1, blank at 3, back
   at 2; the station stage is BUILD 334's
   six-track grid, whose f382 portrait
   seats stand 0 at tracks 1-2, back at
   tracks 3-4 (the middle) — each f429 rule
   below mirrors its standing selector and
   moves only the backspace (and the blank
   on the plain pad) to the right cell.
   The landscape stage already seats the
   backspace at the lower right (BUILD
   351's settled row) and is untouched.
   Placement only: the markup, the digits,
   the OK button and every other key are
   untouched, and with the gate off (no f429
   body class) the pad renders exactly as
   before, byte for byte. */
body.f429 .ci-pad [data-k="0"] {
    grid-column: 1; grid-row: 4; }
body.f429 .ci-pad .ci-keyblank {
    grid-column: 2; grid-row: 4; }
body.f429 .ci-pad [data-k="back"] {
    grid-column: 3; grid-row: 4; }
body.f429.f382 .ci-pad .ci-keyblank {
    grid-column: 2; grid-row: 4; }
body.f429.f382 .ci-pad .ci-key[data-k="back"] {
    grid-column: 3; grid-row: 4; }
@media (orientation: portrait) {
body.f429.f380.f382 .ci-wrap.ci334-stage
    .ci-key[data-k="back"],
body.f429.f380.f382
    .ci-wrap.ci320-stage.ci334-stage
    .ci-key[data-k="back"] {
    grid-column: 5 / 7; grid-row: 4; }
}

/* BUILD 365, item 2 (gate Features:Check419):
   the layout — the mockup's card gap (48px on
   a 248px card = 19.4% of the card height)
   between the three cards, the confirm row
   (the green "Check me in" pill with
   Check411's notice riding it) seated ~27% of
   a card height below the stack, and Start
   Over below it. Check411's notice behaviour
   and Check398/415's Start Over behaviour are
   untouched — only seats move. On the desk
   stages the cards flex-share the scene, so
   the gap is a fixed share of the scene
   height; on aspect-true surfaces (the name
   step, the portrait column) the gap keys off
   the same share. Gate off: today's spacing
   byte for byte; composes independently of
   Check418 (old cards, new spacing). */
body.f419 .ci378-cards { gap: 9vh; }
body.f419 .ci378-stage .ci378-cards { gap: 5.7%; }
body.f419 .ci378-confirm, body.f419 .ci411-row { margin-top: 12.8vh; }
body.f419 .ci378-stage .ci378-confirm, body.f419 .ci378-stage .ci411-row {
    margin-top: 3.6vh; }
body.f419 .ci378-stage .ci411-row .ci378-confirm {
    margin-top: 0; }
body.f419 .ci378-startover { margin: 1.4vh 0 1.8vh; }
/* BUILD 366 (gate Features:Check421; the layout's
   body.f421 marker, customer-facing pages only —
   Admin never carries the class, so every size
   below is unreachable on an Admin page): the
   owner's bigger-fonts pass (Nov 5, 2026, 9:47 PM
   — "make the fonts bigger across the website; I
   think most fonts used in our website are
   small"). Font sizes ONLY — no words added or
   removed, no seats moved. Deliberately NOT
   touched: the BUILD 365 picker cards' internals
   (cqw-sized, design-locked), the BUILD 361/365
   greeting + corner-logo geometry, the CheckIn
   keypad (already 32px), display script faces
   (.bill-thanks, .bill-sign) and the confirmation
   card's themed detail values (already 22-26px).
   Baseline sizes are BUILD 365's; targets are
   roughly a fifth bigger, erring bigger on the
   Book flow the owner pointed at (step labels,
   service names, the date bar, the time pills). */
body.f421, body.f421.pub p { font-size: 18px; }
body.f421.pub a { font-size: 17px; }
body.f421.pub label, body.f421.pub input, body.f421.pub select, body.f421.pub textarea { font-size: 18px; }
body.f421.pub .page-top-pill { font-size: 1.1rem; }
/* check421: the themed header band is a fixed
   composition — its buttons stay at their design
   size (.84rem); any larger and the Search button
   runs off the right edge at phone width
   (measured). This rule exists to hold them
   against the generic link size above. */
body.f421.pub .hw-btn { font-size: .84rem; }
body.f421.pub .lead { font-size: 1.3rem; }
body.f421.pub .tagline { font-size: 18.5px; }
body.f421.pub .fineprint { font-size: 1.02rem; }
body.f421.pub .kicker { font-size: .95rem; }
body.f421 h1 { font-size: 2.3rem; }
body.f421 h2 { font-size: 1.85rem; }
body.f421 h3 { font-size: 1.4rem; }
body.f421 .hero h1 { font-size: 2.8rem; }
body.f421 .page-top-title { font-size: 2.95rem; }
body.f421 .page-top-kicker { font-size: .9rem; }
body.f421 .footer-bottom { font-size: 1.04rem; }
body.f421 .site-nav a { font-size: 17.5px; }
body.f421 .header-call, body.f421 .view-tab { font-size: 1.08rem; }
body.f421 .btn { font-size: 1.02rem; }
body.f421 .btn-mini { font-size: 1.04rem; }
body.f421 .notice { font-size: 18px; }
body.f421 .xcard-name { font-size: 1.68rem; }
body.f421 .xcard-sub { font-size: .88rem; }
body.f421 .svc-item-name { font-size: 1.18rem; }
body.f421 .svc-item-desc { font-size: 1.08rem; }
body.f421 .svc-ribbon { font-size: 1.32rem; }
body.f421 .step-head { font-size: 1.4rem; }
body.f421 .step-n { font-size: 1.22rem; }
body.f421 .book-svc .svc-name {
    font-size: 21px; letter-spacing: -.02em; }
body.f421 .step-box .svc-grid.book-svc { gap: 14px; }
body.f421 .step-box .book-svc .slot { padding: 0 5px; }
body.f421 .step-box .book-svc .svc-medal {
    width: 32px; height: 32px; }
body.f421 .step-box .book-svc
    .slot:has(input:checked) .svc-medal {
    width: 34px; height: 34px; }
/* check421: the slots' invisible inputs are
   inset:0 but keep the UA checkbox margin, which
   pushed the Book grid 2px past the phone edge at
   the bigger sizes; zero it inside the gate. */
body.f421 .slot input { margin: 0; }
body.f421 .time-grid .slot { font-size: 18.5px; }
body.f421 .date-text { font-size: 1.55rem; }
body.f421 .cal-title { font-size: 1.15rem; }
body.f421 .cal-week span { font-size: .88rem; }
body.f421 .cal-day { font-size: 1.12rem; }
body.f421 .pill-btn { font-size: 1.1rem; }
body.f421 .pill-btn .blocked-tag { font-size: .8rem; }
body.f421 .field .error, body.f421 .field .optional, body.f421 .pick-row .p-sub { font-size: 1.02rem; }
body.f421 .picked-summary .svc { font-size: 18px; }
body.f421 .picked-summary .when { font-size: 16.5px; }
body.f421 .picked-summary .coin { font-size: .98rem; }
body.f421.pub .confirm-msg { font-size: 19px; }
body.f421 .conf-title { font-size: 32px; }
body.f421 .conf-who { font-size: 31px; }
body.f421 .conf-svc { font-size: 23.5px; }
body.f421 .conf-lab { font-size: 18.5px; }
body.f421 .conf-phone { font-size: 21.5px; }
body.f421 .conf-btn-note { font-size: 15px; }
body.f421 .conf-cap { font-size: 14.5px; }
body.f421 .conf-heartdiv span, body.f421 .conf-minidiv span { font-size: 17px; }
body.f421 .bill-item { font-size: 19px; }
body.f421 .bill-trow { font-size: 18.5px; }
body.f421 .bill-trow.bill-total { font-size: 25px; }
body.f421 .bill-paidline, body.f421 .bill-addr { font-size: 15.5px; }
body.f421 .bill-web, body.f421 .bill-extra { font-size: 16.5px; }
body.f421 .bill-est377 { font-size: 21.5px; }
body.f421 .tip-sec .tip-row .pill-btn .tip-amt {
    font-size: 18.5px; }

/* ================================================================
   BUILD 370 (gate Features:Check428): THE iPAD PICKER'S OWN
   DESIGN. Owner, Nov 5, 2026, 11:51 PM: "I want interface on
   ipad are customize for ipad and not using iphone interface."
   Design approved Nov 6, 2026: Option B, "Three across"
   (design/ipad-picker-370/sample-B.png; its sources option-b.html
   + shared.css are the measurements below, taken off the files,
   never eyeballed).

   WHERE IT APPLIES: only inside the tablet band — the same band
   Check423 defined for this codebase: (pointer: coarse) and
   (min-width: 641px) and (max-width: 1400px). That is every iPad
   (portrait 768-1024, landscape 1024-1366) and nothing else:
   phone widths never reach 641px, and the desk/station renders
   are either fine-pointer or wider than 1400px, so outside the
   band BUILD 365's wide-row design renders exactly, gate on or
   off. And it composes with Check418 like Check420 does: every
   rule needs body.f418 as well as body.f428, so with Check418
   off this gate emits nothing at all.

   THE DESIGN (the sample's frame is 1180x820; its card is
   337x448): the stage's three cards stand side by side in one
   row (gap 26px), each a TALL card of aspect 337/448. The
   service photo (the owner's card-{key}-365.jpg art, cover-fit
   exactly as the sample's own <img> fits it) fills the top
   53.1% (the sample's 238 of 448); below it the soft pink
   panel (the sample's own gradient) fills the remaining
   46.9%, carrying the dark-red icon (36% of the panel's
   height; the nail bottle 40% — the sample's 76/84px on its
   210px panel) over the big dark-red italic serif name
   (12.8cqw of the card — the sample's 43px on its 337px
   card), icon + name centred in the panel as one group. The
   gold frame and the selected card's bright-gold turn are
   BUILD 365's own (the f418/f402 rules), with the corner
   radius restated to the sample's 26px (7.7cqw). The
   chevron's cream disc rides the panel's bottom-right
   corner (21% of the panel's height — the sample's 44px —
   at its 14px insets). The selected card's big green check
   seats at the RIGHT-MIDDLE of the tall card (the owner's
   standing placement, BUILD 365 fix round 2 — not the
   sample's top-centre seat, which his later word
   supersedes), its disc the sample's 68px restated as
   20cqw of the card. The banner takes the sample's seats
   (top padding 3.2vh; the greeting at the sample's 54px =
   4.6cqw of the stage; the question at its 27px = 2.4cqw),
   and the "Check me in" pill and Start over keep their
   standing seats below the centred row. In the stage the
   row is centred in the height the banner and the confirm
   leave (Check409's flex column), so the whole composition
   sits inside the screen in portrait and landscape alike;
   in a SHORT wide frame (a split view or a landscape
   phone's height, under 561px) the cards instead share
   the stage's height by flex like the wide-row design
   does, so nothing is ever clipped — the photo/panel
   split is by percentage and holds at any card height.

   NOTHING ELSE MOVES: no markup changes anywhere (the
   layout's f428 body-class marker is the only emission,
   and only while the gate shows), and every behaviour —
   multi-pick, Wax's zero minutes beside the others,
   arrival pre-checks, Check411's pick-a-service notice,
   the unified name step with its name box and warn
   state, Check415's Start Over, Check414's corner
   emblem over the cleaned scene — rides the standing
   handlers and rules untouched. The phone scan page is
   not dressed by this gate (its wide scene is
   Check398's own two-column iPad treatment). Card-
   relative sizes are in cqw of the card itself, the
   f407 container the whole f418 family already reads.
   Gate off: BUILD 369's renders byte for byte.
   ================================================================ */
@media (pointer: coarse) and (min-width: 641px)
    and (max-width: 1400px) {
    body.f418.f428 .ci378-banner { padding-top: 3.2vh; }
    body.f418.f428 .ci378-greet { font-size: 4.6cqw; }
    body.f418.f428 .ci378-ask { font-size: 2.4cqw; }
    body.f418.f428 .ci378-cards,
    body.f418.f428 .ci378-stage .ci378-cards {
        flex-direction: row; }
    body.f418.f428 .ci378-cards { gap: 26px;
        align-items: center; }
    body.f418.f428 .ci378-card { flex: 1 1 0;
        min-width: 0; }
    body.f418.f428 .ci378-stage .ci378-card {
        flex: 1 1 0; height: auto; aspect-ratio: auto;
        min-height: 0; }
    body.f418.f428 .ci378-inner { flex-direction: column;
        aspect-ratio: 337 / 448; height: auto;
        border-radius: 7.7cqw; }
    body.f418.f428 .ci378-stage .ci378-inner {
        aspect-ratio: 337 / 448; height: auto; }
    body.f418.f428 .ci378-photo { top: 0; left: 0;
        right: 0; bottom: auto; width: auto;
        height: 53.1%; }
    body.f418.f428 .ci378-band { position: absolute;
        left: 0; right: 0; top: auto; bottom: 0;
        height: 46.9%; flex-direction: column;
        align-items: center; justify-content: center;
        gap: 4.8%; padding: 0;
        background: linear-gradient(135deg, #fdeef1 0%,
            #f9dbe0 55%, #f4ccd4 100%); }
    body.f418.f428 .ci378-icon { height: 36%; }
    body.f418.f428 .ci378-band-nails .ci378-icon {
        height: 40%; }
    /* The standing selected-band brightening was
       written for the old colour bands; on the
       pink panel it washes the selected card's
       panel toward white. The sample's selected
       panel stays the same pink — the gold frame
       and the label's glow carry the selection. */
    body.f418.f428 .ci378-card:has(input:checked)
        .ci378-band { filter: none; }
    body.f418.f428 .ci378-name { font-size: 12.8cqw; }
    body.f418.f428 .ci378-go { right: 4.2%;
        bottom: 6.7%; height: 21%; font-size: 5cqw; }
    body.f418.f428 .ci378-check { left: 86%;
        right: auto; top: 50%; bottom: auto;
        transform: translate(-50%, -50%);
        width: 20cqw; height: 20cqw;
        font-size: 12cqw; }
    body.f418.f428 .ci378-stage .ci378-check {
        font-size: 12cqw; }
}
/* Portrait: the tall frame leaves more air than the
   sample's landscape frame. The cards row does not
   stretch to fill it — the pill hugs the cards as in
   the sample and the slack falls below Start over,
   inside the scene. (Landscape's content already
   fills its frame; the standing flex stands there.) */
@media (pointer: coarse) and (min-width: 641px)
    and (max-width: 1400px) and (orientation: portrait) {
    body.f418.f428 .ci378-stage .ci378-cards {
        flex: 0 1 auto; }
}
/* The short-frame guard (see the note above): under
   561px of frame height the tall aspect lets go and
   the cards share the stage's height by flex, the
   wide-row design's own fit — the row direction and
   the photo/panel split above still hold. */
@media (pointer: coarse) and (min-width: 641px)
    and (max-width: 1400px) and (max-height: 560px) {
    body.f418.f428 .ci378-stage .ci378-card {
        display: flex; }
    body.f418.f428 .ci378-stage .ci378-inner {
        aspect-ratio: auto; height: 100%; flex: 1 1 auto; }
}

/* ================================================================
   BUILD 365, FIX ROUND 3 (gate Features:Check418 — the
   redesign's own gate; no new key): THE PHONE SCENE
   FILLS THE FRAME. Owner, Nov 6, 2026, 7:02 AM, on his
   DEV check of the name step: "Background image is not
   right." The stage is full-screen on the phone band
   (Check398: position fixed, inset 0, height 100dvh)
   but the scene stayed width-locked (top center /
   100% auto, the base rule as re-imaged by Check414):
   scene-clean-361.jpg is 4:3, so at 390px wide it
   paints 292.5px tall and ends in a hard edge just
   under the name box — the three cards and the pill
   sat on the flat #f8ead3 fallback. His approved
   design (design/picker-redesign-365/design-final.jpg,
   853x1844) fills the whole frame top to bottom.
   On the phone band only, while the redesign shows,
   the stage paints the owner's own portrait scene
   from the same design set — background-orchid-only.jpg
   (884x1779), shipped byte-identical as
   scene-portrait-365r3.jpg: orchid top-left, gold
   ribbon across the top, warm glow through the
   middle, gold wave along the bottom, no baked text
   and no baked logo, so the greeting, the name box
   and the live emblem layer (Check414) keep their
   clean seats. The fit is cover, anchored top
   centre: at 390x844 it is height-exact (844.0px)
   with 14.7px trimmed per side, and the art is
   never shown larger than native (884 native px
   over a 419px render — a 2.11x downscale).
   Desk widths and the tablet band keep the
   width-locked wide scene exactly; the phone scan
   page carries no site.css and is untouched.
   Gate off: no rule here applies and the stage
   paints BUILD 371's scene byte for byte.
   ================================================================ */
@media (max-width: 699px) {
    body.f418 .ci378-stage {
        background-image: url('/images/signin378/scene-portrait-365r3.jpg?v=365r3');
        background-size: cover;
        background-position: top center; }
}

/* BUILD 373, items 1+2 (gates Features:Check433 /
   Check434): the Book view's tab row — the owner's
   approved sample dress (design/book-tabs-373/
   shared.css): a flex row of three pills, the
   active tab filled dusty-rose with a soft shadow,
   the others outlined on white. The row only ever
   renders while a tab gate shows (Book.cshtml), so
   no rule here can touch a gate-off page. Admin
   renders Classic — these colors are the sample's
   fixed dress, never themed. The tabs' contents
   reuse the standing component CSS (.ci353-panel /
   .ci359-* for the sign-ins cards, .cust-* /
   .pick-* for the directory rows); the only new
   content rule seats the sign-ins panel under the
   day line. */
.book-tabs433 { display: flex; gap: 10px; margin: 0 0 14px; }
.btab433 { flex: 1 1 0; display: flex; align-items: center;
    justify-content: center; min-height: 52px; padding: 10px 8px;
    border: 2px solid #b76e79; border-radius: 999px;
    background: #fff; color: #96555f; font-size: 19px;
    font-weight: 700; text-decoration: none; text-align: center; }
.btab433.on { background: #b76e79; color: #fff;
    box-shadow: 0 4px 14px rgba(183, 110, 121, .4); }
.tab433-panel { margin-top: 10px; }
@media (max-width: 640px) {
    .btab433 { font-size: 17px; min-height: 48px; }
}

/* BUILD 373, item 3 (gate Features:Check435): the
   Home strip's per-device dress. While the gate
   shows, the strip (Index.cshtml's .hw-break435)
   carries a <picture> of native-width crops and a
   live script "Welcome" overlay; these rules give
   the strip its relative seat, keep the picture's
   image in the standing strip dress (gold border,
   cream ground, soft shadow — the .hw-break img
   rules above do not reach an image inside a
   <picture> on every engine, so the dress is
   restated for it), and seat the word bottom-left
   inside the strip, in the hero Welcome's own
   treatment (Great Vibes script) in the bronze the
   Home banner title wears. Keyed under the
   strip's own gated class (.hw-break435), which
   Index renders only while the gate shows on the
   Thanksgiving 1 home — gate off (and on every
   other theme), nothing here can match. */
.hw-break435 { position: relative; }
.hw-break435 picture img { width: min(520px, 92%);
    height: auto; border: 3px solid #d9a441;
    border-radius: 18px; background: #fff8ec;
    box-shadow: 0 6px 18px rgba(122, 72, 20, .18);
    padding: 6px 10px; box-sizing: border-box; }
.hw-break435 .hw-welcome435 { position: absolute;
    left: calc(50% - min(260px, 46%) + 18px); bottom: 14px;
    font-family: "Great Vibes", cursive; font-size: 34px;
    line-height: 1; color: #9a4a1f; pointer-events: none;
    padding: .05em .3em;
    background: radial-gradient(ellipse at center,
        rgba(255, 248, 236, .78), rgba(255, 248, 236, 0) 72%);
    text-shadow: 0 1px 6px rgba(255, 248, 236, .9); }

/* ================================================================
   BUILD 374 (gates Features:Check436 / Check437 /
   Check438 / Check440): the sign-ins list round.
   Every class here is emitted only while its gate
   shows (the views carry the gated class terms and
   branches), so no rule in this block can touch a
   gate-off page.
   (1) Check436 — the one-tap Close button: on the
   review cards an outline sibling of the cards' own
   Accept / Decline / Revoke buttons; on the
   /Admin/SignIns rows a compact outline pill at the
   row's right edge.
   (2) Check437 — the list background: the customer
   sign-in stage's own scene, painted the way the
   stage paints it (Check414's cleaned scene,
   width-locked over the cream ground; on the phone
   band Check418's portrait scene, cover — the same
   files at native resolution on every band). The
   panels gain the stage's own frame (radius,
   shadow, side padding) so the cards sit inside
   the scene; the cards keep their solid grounds
   and stay fully readable.
   (3) Check438 — the Back buttons big and clearly
   visible in every theme: a large solid pill in
   fixed colors (deep red, gold ring, white word)
   that no theme dress can mute, at the links'
   standing seats, unmoved.
   (4) Check440 — the services as the Book grid's
   own coins at the big size (the f263 Book coins'
   measures and colors), one per kind in the Book's
   canonical order, standing where the card's
   services text line stood.
   ================================================================ */
.ci359-btn.close436 { background: #fff; color: #12263c;
    border: 2.5px solid #12263c; }
.ci353-btn.close436 { background: #fff; color: #12263c;
    border: 2px solid #12263c; }
.close436f { margin-top: 10px; }
.si-close436-form { flex: none; margin: 0; }
.si-close436 { min-height: 48px; padding: 8px 20px;
    border-radius: 999px; background: #fff;
    border: 2px solid #12263c; color: #12263c;
    font-size: 17px; font-weight: 800; cursor: pointer; }
.bg437 { background: #f8ead3
    url('/images/signin378/scene-clean-361.jpg?v=361')
    top center / 100% auto no-repeat;
    border-radius: 24px;
    box-shadow: 0 24px 60px rgba(120, 72, 20, .25); }
.ci353-panel.bg437 { padding-left: 16px;
    padding-right: 16px; }
@media (max-width: 699px) {
    .bg437 { background-image:
        url('/images/signin378/scene-portrait-365r3.jpg?v=365r3');
        background-size: cover;
        background-position: top center; }
}
.ci353-panel a.ci337-back.big438,
.si-wrap a.si-back.big438 {
    display: inline-flex; align-items: center;
    min-height: 58px; padding: 10px 30px;
    border-radius: 999px; background: #7c1530;
    border: 3px solid #d9a441; color: #fff;
    font-size: 23px; font-weight: 800;
    text-decoration: none;
    box-shadow: 0 6px 18px rgba(60, 20, 10, .35); }
.si-wrap a.si-back.big438 { margin-bottom: 14px; }
.svc440 { display: inline-flex; gap: 10px;
    align-items: center; margin-top: 6px; }
.svc440 .coin { width: 42px; height: 42px;
    border-radius: 50%; display: inline-flex;
    align-items: center; justify-content: center;
    color: #fff; font-family: Arial, sans-serif;
    font-weight: 800; font-size: 22px;
    border: 2px solid rgba(255, 255, 255, .9);
    box-shadow: 0 0 0 1px rgba(0, 0, 0, .18);
    flex: none; }
.svc440 .coin-N { background: #22c55e; }
.svc440 .coin-P { background: #e75480; }
.svc440 .coin-W, .svc440 .coin-F { background: #7c3aed; }
.svc440 .coin-M { background: #e75480; }
.svc440 .coin-G { background: #22c55e; }

/* ================================================================
   BUILD 375, item 1 (gate Features:Check441; the layout's
   body.f441 marker, emitted on the /Book page only): THE BOOK
   FLOW'S WARNINGS GO BIG AND BOLD. Owner, Nov 6, 2026, 8:15 AM,
   with a screenshot of the small red "Please pick a time." line
   on the dark theme: "This warning is way to small."

   THE SET — every warning line the booking steps render in
   their standing warning dress, treated the same way:
   - the field validation spans (.field .error): "Please
     choose a service." (Step 1), "Please pick a time."
     (Step 2), "Please tell us your name." and "Please give
     your phone number so we can reach you." (Step 3), plus
     the Facial refusal that rides the same span;
   - the slot area's empty-state lines (.slot-area p):
     "Pick at least one service above to see open times.",
     "No more times today. Please pick another date." and
     "We're closed that day. Please pick another date.".
   The .notice.error box at the top of the form is a
   different, already-prominent treatment (a bordered box at
   .98rem) and is NOT a small warning line; it is untouched.

   Size and weight ONLY — same words, same seats, same
   show/hide behaviour, no colour change (the standing red
   #b3261e stands in the classic dress and every theme,
   exactly as today), no new text. 1.3rem (20.8px) bold reads
   at a glance beside the step heads (18.9px; 22.4px under
   f421, whose 1.02rem on .field .error this block follows
   and outranks at equal specificity by source order, so the
   two bigger-text passes compose instead of fighting).
   The marker exists only on /Book, so no other page's
   warnings can take these sizes. Gate off: no rule here
   applies and BUILD 374's warnings render byte for byte.
   ================================================================ */
body.f441 .field .error { font-size: 1.3rem; font-weight: 700; }
body.f441 .slot-area p { font-size: 1.3rem; font-weight: 700; }

/* ================================================================
   BUILD 375, item 3 (gate Features:Check445; the layout's
   body.f445 marker, emitted on the CheckIn page only):
   THE iPAD PICKER FIT FIX. Owner, Nov 6, 2026, 10:30 AM:
   "Sign in with ipad I see 3 really big buttons for
   service picker. They're too big to cover the check in
   button entirely. Quickly fix."

   THE DEFECT, measured on the BUILD 374 publish
   (diag/check375/measure445*.log): in the tablet band
   the stage's cards row is a flex child that SHRINKS
   when the stage's other content (banner, the name
   step's name box, the pill row, Start over) leaves it
   less than the cards' aspect height — but the cards
   themselves kept their full aspect height and, centred
   in the shrunken row, painted out of it symmetrically,
   over the banner above and the "Check me in" pill
   below. At 1180x820 (found step, three-across) the
   cards measured 466px tall in a 414px row, their
   bottoms 4px above the pill — one longer greeting or
   one shorter frame from covering it entirely, exactly
   as the owner saw.

   THE FIX (three-across half; composes with Check428 —
   every rule needs body.f418.f428.f445, so this gate
   alone emits nothing, and with Check445 off BUILD
   374's renders stand byte for byte): the row stretches
   its cards to the row's own height, each card becomes
   a flex seat that centres its inner, and the inner —
   which keeps BUILD 370's aspect ratio and its
   width-driven height whenever the stage has room —
   is CAPPED at the card's height (max-height: 100%).
   A capped card is shorter than the design aspect and
   nothing else changes: the photo/panel split is by
   percentage of the card and holds at any height, the
   gold frame, the pink panel, the icon, the name, the
   chevron and the right-middle green check all ride
   their standing relative seats. The pill and Start
   over are flex children after the row in the stage's
   column and the row can no longer paint outside
   itself, so the pill is reachable at every tablet
   size by construction. (BUILD 370's short-frame
   guard below 561px already took the inner to the
   row's height outright; this cap is that same idea
   at every tablet height, and outranks it where the
   two overlap.) Gate off: no rule here applies.
   ================================================================ */
@media (pointer: coarse) and (min-width: 641px)
    and (max-width: 1400px) {
    body.f418.f428.f445 .ci378-stage .ci378-cards {
        align-items: stretch; }
    body.f418.f428.f445 .ci378-stage .ci378-card {
        display: flex; align-items: center;
        min-height: 0; }
    body.f418.f428.f445 .ci378-stage .ci378-inner {
        flex: 1 1 auto; max-height: 100%; }
}

/* ============================================================
   BUILD 375 (gate Features:Check446 — the switcher
   container carries sw446 only while the gate shows):
   the view switcher's iPad treatment. The stroke
   icons ride inside the three view buttons (emitted
   only while the gate shows) and stay hidden
   everywhere else; in the tablet band the bar seats
   at the bottom RIGHT, stacks vertically, drops the
   whole environment axis (the PROD and DEV segments
   and the drag knob — an iPad never enters DEV) and
   shows exactly three icon-only buttons in the
   owner's order — Customer, Admin, Sign in — each
   keeping the standing .on fill while its view is
   active. Outside the band, and with the gate off,
   the bar is BUILD 374's.
   ============================================================ */
.vp3-ic { display: none; width: 23px; height: 23px; }
@media (pointer: coarse) and (min-width: 641px) and (max-width: 1400px) {
  .switcher257.sw446 { left: auto; right: 10px; }
  .switcher257.sw446 .sw5-row { flex-direction: column; width: auto; padding: 4px; gap: 4px; cursor: default; touch-action: auto; }
  .switcher257.sw446 .sw5-row .vp3-seg { flex: none; width: 50px; height: 50px; padding: 0; font-size: 0; line-height: 0; display: flex; align-items: center; justify-content: center; }
  .switcher257.sw446 .sw5-row .vp3-seg .vp3-ic { display: block; }
  .switcher257.sw446 .sw5-row .vp3-seg[name="mode"][value="customer"] { order: 1; }
  .switcher257.sw446 .sw5-row .vp3-seg[name="mode"][value="admin"] { order: 2; }
  .switcher257.sw446 .sw5-row .vp3-seg[name="mode"][value="signin"] { order: 3; }
  .switcher257.sw446 .sw5-row .sw5-env-seg,
  .switcher257.sw446 .env-knob257 { display: none; }
}

/* ============================================================
   BUILD 376 (gate Features:Check443): the Thanksgiving 1
   header's name as a LIVE layer. The baked "A+ NAILS OF
   ROWLETT" line is painted out of the wide hero
   (hero-full-443.jpg) and this span carries the name
   instead, reading exactly "A+ Nails Rowlett" in the
   artwork's own lettering as closely as web text can —
   Playfair Display (the site's serif), the baked
   glyphs' dark bronze (#6d3c24, sampled from the
   artwork), wide tracking. Measured seat on the wide
   artwork (859x182): the baked glyphs spanned
   x 475..811 (55.30%..94.53% of the width), cap top
   y 27 (14.84% of the height), cap height 19px
   (2.21% of the width) — the rules below seat the
   live glyphs on those same fractions (font-size in
   cqw of the hero anchor, which becomes a container
   only while it carries the layer, so the layer
   tracks the artwork at every band width; the
   anchor's link underline is dropped while it
   carries the layer, so the nameplate never wears
   it). The
   phone band's artwork is the medallion cluster,
   which carries no name; there the same live line
   stands as a nameplate directly under the picture
   (the cluster's own surfaces leave it no clean
   overlay seat, and the Home welcome word holds the
   bottom-left). The rules key off the span itself —
   emitted only by the gate's thanksgiving1 render —
   so no other theme and no gate-off render is
   touched: BUILD 375's bytes stand everywhere else.
   ============================================================ */
.hw-hero a:has(> .hero-name443) { position: relative; container-type: inline-size; text-decoration: none; }
.hero-name443 { position: absolute; left: 55.1%; top: 12.3%; font-family: "Playfair Display", Georgia, serif; font-weight: 700; font-size: 3.16cqw; letter-spacing: .34em; line-height: 1; color: #6d3c24; white-space: nowrap; pointer-events: none; text-decoration: none; }
@media (max-width: 640px) {
  .hero-name443 { position: static; display: block; text-align: center; font-size: 4cqw; letter-spacing: .08em; padding: .32em 0 .42em; }
}

/* ============================================================
   BUILD 377 (gate Features:Check444): the quick check-in
   icon on the appointment details screen (Admin/Edit).
   The anchor is emitted only while the gate shows and
   only on today's Booked, not-yet-checked-in
   appointment; the one rule below seats the icon-only
   anchor in the header row's link line (the .admin-links
   anchors are text links — the icon needs the flex seat
   to sit on their baseline). The class renders nowhere
   else, so no other surface — and no gate-off render —
   is touched: BUILD 376's bytes stand everywhere else.
   ============================================================ */
.admin-links a.ci444-link { display: inline-flex; align-items: center; vertical-align: middle; }

/* ============================================================
   BUILD 379, item 2 (gate Features:Check450): the ONE
   vertical icon bar at the TOP RIGHT on iPad (owner,
   Nov 6, 2026 — "reorganize 2 buttons on top right and
   3 buttons on bottom right into a vertical bar at the
   top right: Sign in page, Admin Book View, Sign-ins
   List, Search", and "remove the icon to main website
   too as we don't need it"). The bar's markup is
   emitted by the layout only while the gate shows
   (for the same owner-PIN sessions the switcher
   renders for); it is display:none everywhere except
   the tablet band — Check446's band, (pointer:
   coarse) and 641–1400px — where it seats fixed at
   the top right, ABOVE the switcher's own layer.
   Each item is the approved sample's dress: a round
   white button (50px) with a gold ring and the
   site's stroke icon in deep red, and a small
   caption under it; the button for the view being
   stood on takes the switcher's filled treatment
   (rose fill, white icon). There is no Customer /
   main-website button and no DEV button.
   In the same band, while the gate shows: the
   switcher is hidden whole (its sw450 class — the
   bar replaces the bottom-right stack AND the
   bottom-left pill on iPad), and on the station
   (body.f450) the two corner icons the bar replaces
   — the search glyph (.ci346-find) and the sign-ins
   glyph (.ci353-review) on the keypad step, and
   their row on the review step (.ci353-icons) —
   do not render. Outside the band, and with the
   gate off, every rule here is inert and the site
   is BUILD 378's byte for byte.
   ============================================================ */
.bar450 { display: none; }
@media (pointer: coarse) and (min-width: 641px) and (max-width: 1400px) {
  .switcher257.sw450 { display: none; }
  body.f450.f346 .ci-wrap.ci334-stage .ci346-find,
  body.f450.f353 .ci-wrap.ci334-stage .ci353-review,
  body.f450 .ci353-icons { display: none; }
  .bar450 { display: flex; flex-direction: column; align-items: center; gap: 6px; position: fixed; top: 10px; right: 10px; z-index: 10002; }
  .bar450-form { margin: 0; display: contents; }
  .bar450-btn { display: flex; flex-direction: column; align-items: center; gap: 2px; margin: 0; padding: 0; border: 0; background: transparent; cursor: pointer; text-decoration: none; font-family: var(--font-body); -webkit-tap-highlight-color: transparent; }
  .bar450-round { width: 50px; height: 50px; border-radius: 50%; background: #fffdf8; border: 2.5px solid #c9973f; box-shadow: 0 4px 12px rgba(86, 48, 54, .28); display: flex; align-items: center; justify-content: center; color: #7c1530; }
  .bar450-round svg { width: 23px; height: 23px; display: block; }
  .bar450-cap { font-size: 11px; font-weight: 700; line-height: 1.15; color: #5a3a22; text-shadow: 0 1px 4px rgba(255, 248, 236, .95), 0 0 6px rgba(255, 248, 236, .8); }
  .bar450-btn.on .bar450-round { background: var(--rose); border-color: var(--rose); color: #fff; }
  .bar450-btn:active .bar450-round { transform: scale(.94); }
}

/* ================================================================
   BUILD 381 (gates Features:Check455 / Check457 / Check458)

   Item 1 (Check455): Check450's ONE bar on the iPhone keypad
   step. The layout emits the same shared .bar450 markup for the
   station's keypad-step render while the gate shows (body
   .f455); the rules below seat it in the PHONE band with
   Check450's own seat and dress, copied rule for rule from the
   tablet block above (the classes are one component — the band
   is all that changes), and retire the two corner glyphs the
   bar replaces on that step (the search glyph, the sign-ins
   glyph — the same pair body.f450 retires in the tablet band).
   A bar emitted ONLY for this gate (Check450 off) carries
   .bar455only and never shows in Check450's tablet band.
   Item 3 (Check457): the "Rewards Members!" heading — hidden
   everywhere except the tablet band, where it sits above the
   display pill, centred on the keypad column: its seat
   mirrors the pill's FINAL composition seat (Check385's
   unified block: left .356, width .388, the same seat under
   every stage face), and the portrait seat mirrors the
   portrait pill. It moves nothing and takes no taps.
   Item 4 (Check458): the appointment details pill — one
   button on the right of the shared header's name row:
   "Sign In" filled rose, "Close this ticket" outlined.
   With every gate off, no element below exists in any render
   and the file's effect is BUILD 380's byte for byte.
   ================================================================ */
@media (pointer: coarse) and (min-width: 641px) and (max-width: 1400px) {
  .bar450.bar455only { display: none; }
}
@media (pointer: coarse) and (max-width: 640px) {
  body.f455 .bar450 { display: flex; flex-direction: column; align-items: center; gap: 6px; position: fixed; top: 10px; right: 10px; z-index: 10002; }
  body.f455 .bar450-form { margin: 0; display: contents; }
  body.f455 .bar450-btn { display: flex; flex-direction: column; align-items: center; gap: 2px; margin: 0; padding: 0; border: 0; background: transparent; cursor: pointer; text-decoration: none; font-family: var(--font-body); -webkit-tap-highlight-color: transparent; }
  body.f455 .bar450-round { width: 50px; height: 50px; border-radius: 50%; background: #fffdf8; border: 2.5px solid #c9973f; box-shadow: 0 4px 12px rgba(86, 48, 54, .28); display: flex; align-items: center; justify-content: center; color: #7c1530; }
  body.f455 .bar450-round svg { width: 23px; height: 23px; display: block; }
  body.f455 .bar450-cap { font-size: 11px; font-weight: 700; line-height: 1.15; color: #5a3a22; text-shadow: 0 1px 4px rgba(255, 248, 236, .95), 0 0 6px rgba(255, 248, 236, .8); }
  body.f455 .bar450-btn.on .bar450-round { background: var(--rose); border-color: var(--rose); color: #fff; }
  body.f455 .bar450-btn:active .bar450-round { transform: scale(.94); }
  body.f455.f346 .ci-wrap.ci334-stage .ci346-find,
  body.f455.f353 .ci-wrap.ci334-stage .ci353-review { display: none; }
}
.ci457-head { display: none; }
@media (pointer: coarse) and (min-width: 641px) and (max-width: 1400px) {
  body.f457 .ci-wrap.ci334-stage .ci457-head { display: block; position: absolute; z-index: 4; pointer-events: none; text-align: center; left: calc(var(--sx) + var(--sw) * 0.356); width: calc(var(--sw) * 0.388); top: calc(var(--sy) + var(--sh) * 0.058); }
  .ci457-line1 { display: flex; align-items: center; justify-content: center; gap: calc(var(--sw) * 0.018); color: #f2c14e; }
  .ci457-script { font-family: "Great Vibes", cursive; font-weight: 400; font-size: calc(var(--sw) * 0.056); line-height: 1.15; color: #f6c95c; text-shadow: 0 2px 10px rgba(0, 0, 0, .55); white-space: nowrap; }
  .ci457-gift { width: calc(var(--sw) * 0.040); height: calc(var(--sw) * 0.040); flex: none; filter: drop-shadow(0 2px 5px rgba(0, 0, 0, .5)); }
  .ci457-line2 { font-family: var(--font-display); font-weight: 600; font-size: calc(var(--sw) * 0.0245); color: #f0c75e; letter-spacing: .01em; margin-top: calc(var(--sh) * 0.006); text-shadow: 0 1px 6px rgba(0, 0, 0, .6); white-space: nowrap; }
  @media (orientation: portrait) {
    body.f457 .ci-wrap.ci334-stage .ci457-head { left: calc(var(--sx) + var(--sw) * 0.048); width: calc(var(--sw) * 0.904); top: calc(var(--sy) + var(--sh) * 0.200); }
  }
}
.ci458-form { margin: 0 0 0 auto; flex: none; }
.ci458-btn { appearance: none; -webkit-appearance: none; border-radius: 999px; padding: 10px 22px; font-family: var(--font-body); font-size: 1rem; font-weight: 700; line-height: 1.2; cursor: pointer; white-space: nowrap; -webkit-tap-highlight-color: transparent; }
.ci458-signin { background: var(--rose); border: 2px solid var(--rose); color: #fff; box-shadow: 0 4px 12px rgba(86, 48, 54, .25); }
.ci458-close { background: #fff; border: 2px solid var(--rose); color: var(--rose-dark); }
.ci458-btn:active { transform: scale(.97); }

/* BUILD 383 (gate Features:Check466): the smart rest —
   while the gate shows (body.f466, the sign-in surface
   only), check212's rest face is NEAR-BLACK: the face
   paints plain black and every lit layer on it (poster
   art, brand block, glow, shimmer, QR card) is hidden,
   and the camera arm dot hides while the face rests —
   so a resting station burns as little light as the
   page can manage. The face still wakes on a touch or
   on camera motion exactly as check212 built it; the
   rules below only dress the resting face. Gate off:
   no rule here applies and the face is BUILD 382's. */
body.f466 .cir { background: #000; animation: none; }
body.f466 .cir::before,
body.f466 .cir::after { display: none; }
body.f466 .cir .cq312-scrim,
body.f466 .cir .cq312-top,
body.f466 .cir .cir-glow,
body.f466 .cir .cir-shimmer,
body.f466 .cir .ci318-art,
body.f466 .cir .ci318-qr,
body.f466 .cir .cq312-bottom,
body.f466 .cir .cq293-card { display: none; }
body.f466 .cir:not(.cir-off) ~ .ci-armdot257 { display: none; }
/* The veil itself (see the gated div in CheckIn):
   a plain black fixed layer just under the rest
   face's own z-index, keyed on the rest overlay's
   class — visible exactly while the desk is at
   rest, gone the moment it wakes, on either rest
   stack (check334's keypad-first screen or the
   painted face under it). It never takes a touch. */
body.f466 .dim466 { position: fixed; inset: 0;
  background: #000; z-index: 9998; opacity: 0;
  visibility: hidden; pointer-events: none;
  transition: opacity .15s ease,
    visibility 0s linear .15s; }
body.f466 #ciRest:not(.cir-off) ~ .dim466 {
  opacity: 1; visibility: visible;
  transition: opacity .15s ease; }

/* ============================================================
   BUILD 384, item 1 (owner, Nov 7, 2026 — the approved
   component sheet: design/button-component/button.png,
   his words "Use this button everywhere"): THE SALON
   BUTTON — one shared component. Cream face, gold
   border, deep-red serif label with an icon; picked
   wears rose (tabs, big actions) or gold (choices);
   small and quiet variants; disabled dims. Pages use
   these classes directly as they migrate (BUILD 385);
   the Payment page below wears the same dress through
   its paypage469 marker, which renders only while
   Features:Check469 shows.
   ============================================================ */
.sbtn { display: inline-flex; align-items: center; justify-content: center; gap: 12px;
    min-height: 64px; padding: 8px 22px; border-radius: 15px; cursor: pointer;
    background: linear-gradient(180deg, #fffaf1, #fbeed9);
    border: 1.5px solid #d9a441; color: #7c2128;
    font-family: Georgia, 'Times New Roman', serif; font-size: 24px; font-weight: 700;
    box-shadow: 0 3px 10px rgba(176, 127, 42, .18), inset 0 1px 0 #ffffff;
    text-decoration: none; }
.sbtn svg { flex: none; }
.sbtn-rose { background: linear-gradient(180deg, #d1828a, #b04a56); color: #fff; border-color: #b98a2f;
    box-shadow: 0 6px 16px rgba(176, 74, 86, .35), inset 0 1px 0 rgba(255, 255, 255, .35); }
.sbtn-gold { background: linear-gradient(180deg, #ffd873, #f0b23e); color: #43300a; border-color: #b98a2f;
    box-shadow: 0 6px 16px rgba(217, 164, 41, .4), inset 0 1px 0 rgba(255, 255, 255, .6); }
.sbtn-big { min-height: 84px; width: 100%; border-radius: 999px; font-size: 32px;
    background: linear-gradient(180deg, #d78a8c, #bd5a63); color: #fff; border-color: #b98a2f;
    box-shadow: 0 8px 20px rgba(189, 90, 99, .4), inset 0 1px 0 rgba(255, 255, 255, .35); }
.sbtn-small { min-height: 52px; padding: 6px 18px; border-radius: 12px; font-size: 21px; }
.sbtn-quiet { background: linear-gradient(180deg, #fffdf8, #faf3e6); color: #a4575f; border-color: #e2c491; }
.sbtn[disabled], .sbtn.dis { opacity: .45; pointer-events: none; }

/* The Payment page in the component dress (gate
   Features:Check469; the marker renders only while
   the gate shows, so gate-off keeps check468's page
   byte for byte). His background art at each screen
   size; the arrangement and every control unchanged. */
.paypage469 { background: #fdf2f0 url('/images/paybg-469/bg-desktop.jpg?v=469') top center / cover no-repeat; }
@media (max-width: 1100px) {
    .paypage469 { background-image: url('/images/paybg-469/bg-tablet.jpg?v=469'); } }
@media (max-width: 700px) {
    .paypage469 { background-image: url('/images/paybg-469/bg-phone.jpg?v=469'); } }
.paypage469 .cust-tabs a { min-height: 64px; border-radius: 15px;
    background: linear-gradient(180deg, #fffaf1, #fbeed9);
    border: 1.5px solid #d9a441; color: #7c2128;
    font-family: Georgia, 'Times New Roman', serif; font-size: 24px; font-weight: 700;
    box-shadow: 0 3px 10px rgba(176, 127, 42, .18), inset 0 1px 0 #ffffff; }
.paypage469 .cust-tabs a.on { background: linear-gradient(180deg, #d1828a, #b04a56); color: #fff; border-color: #b98a2f;
    box-shadow: 0 6px 16px rgba(176, 74, 86, .35), inset 0 1px 0 rgba(255, 255, 255, .35); }
.paypage469 #payBlock .btn { min-height: 64px; border-radius: 15px;
    background: linear-gradient(180deg, #fffaf1, #fbeed9);
    border: 1.5px solid #d9a441; color: #7c2128;
    font-family: Georgia, 'Times New Roman', serif; font-size: 24px; font-weight: 700;
    box-shadow: 0 3px 10px rgba(176, 127, 42, .18), inset 0 1px 0 #ffffff; }
.paypage469 #payBlock .pill-btn { border-radius: 12px;
    background: linear-gradient(180deg, #fffaf1, #fbeed9);
    border: 1.5px solid #d9a441; color: #7c2128;
    font-family: Georgia, 'Times New Roman', serif; font-weight: 700;
    box-shadow: 0 3px 10px rgba(176, 127, 42, .18), inset 0 1px 0 #ffffff; }
.paypage469 #payBlock .pay-methods .pill-btn { min-height: 64px; border-radius: 15px; font-size: 23px; }
.paypage469 #payBlock .pay-methods .pill-btn.sel { background: linear-gradient(180deg, #ffd873, #f0b23e); color: #43300a; border-color: #b98a2f;
    box-shadow: 0 6px 16px rgba(217, 164, 41, .4), inset 0 1px 0 rgba(255, 255, 255, .6); }
.paypage469 #payBlock .pay-methods ~ button[type="submit"].btn { min-height: 84px; border-radius: 999px; font-size: 32px;
    background: linear-gradient(180deg, #d78a8c, #bd5a63); color: #fff; border-color: #b98a2f;
    box-shadow: 0 8px 20px rgba(189, 90, 99, .4), inset 0 1px 0 rgba(255, 255, 255, .35); }
.paypage469 #payBlock .btn[disabled], .paypage469 #payBlock .pill-btn[disabled] { opacity: .5; }
.paypage469 #payEstimateBtn, .paypage469 #payFinalBillBtn425,
.paypage469 #payCopyTextBtn427, .paypage469 #payTextBillBtn453 {
    white-space: nowrap; font-size: 22px; height: 100%; }
.paypage469 .wrap { max-width: 1180px; }
.paypage469 .pay469-layout { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 18px; align-items: start; }
@media (max-width: 899px) {
    .paypage469 .pay469-layout { grid-template-columns: minmax(0, 1fr); } }
.paypage469 .pay469-side > .btn { width: 100%; margin: 0 0 12px; }
.paypage469 .pay469-side > .btn:last-child { margin-bottom: 0; }
.paypage469 #payBlock { max-width: 1120px; }

/* BUILD 385 (Check470): the Salon Button rollout.
   The component from BUILD 384 (design/button-
   component) becomes the dress of the standard
   button family site-wide: cream is the standard
   button, rose is a form's main submit, gold is
   Call. Serif, gold border, 15px corners. The
   Book grid's state pills (time / status) and
   the station buttons keep their own dress —
   they are state furniture, not actions. */
body.b470 .btn {
    background: linear-gradient(180deg, #fffaf1, #fbeed9);
    border: 1.5px solid #d9a441;
    color: #7c2128;
    font-family: Georgia, 'Times New Roman', serif;
    font-weight: 700;
    border-radius: 15px;
    box-shadow: 0 3px 8px rgba(122, 72, 20, .18);
}
body.b470 .btn-primary,
body.b470 button[type="submit"].btn,
body.b470 input[type="submit"].btn {
    background: linear-gradient(180deg, #d1828a, #b04a56);
    border-color: #b04a56;
    color: #fff;
}
body.b470 .btn-call {
    background: linear-gradient(180deg, #ffd873, #f0b23e);
    border-color: #d9a441;
    color: #43300a;
}
body.b470 .btn-outline {
    background: linear-gradient(180deg, #fffdf8, #fdf3e3);
    border: 1.5px solid #d9a441;
    color: #7c2128;
}
body.b470 .hero-cta .btn-outline {
    background: transparent;
    border-color: #fff;
    color: #fff;
}
body.b470 .pill-btn:not(.time-btn):not(.status-btn) {
    background: linear-gradient(180deg, #fffaf1, #fbeed9);
    border: 1.5px solid #d9a441;
    color: #7c2128;
    font-family: Georgia, 'Times New Roman', serif;
    font-weight: 700;
    border-radius: 15px;
}

/* ============================================================
   BUILD 386, item 1 (gate Features:Check471): the tip
   section keeps its readable cream dress in EVERY theme.
   Mirrors the f300 values (which only cover the bill
   surfaces while that gate shows) and also pins the pill
   background itself, which no earlier restore set — under
   a dark theme the pills took the theme's dark panel fill
   with dark words on top (the owner's DEV screenshot,
   Nov 7, 2026). Scoped to body.b471; gate off: nothing
   here applies and every theme paints as before.
   ============================================================ */
body.b471 .tip-sec { background: linear-gradient(180deg, #fffaf3, #fdf3ec); }
body.b471 .tip-sec .tip-lab { color: #3A2410; }
body.b471 .tip-sec .tip-row .pill-btn {
    background: #fff;
    border-color: #B98A2F;
    color: #33200A;
}
body.b471 .tip-sec .tip-row .pill-btn .tip-amt { color: #6B4A12; }
body.b471 .tip-sec .tip-row .pill-btn.sel {
    background: #F2A81D;
    border-color: #8A5A00;
    color: #241708;
    box-shadow: 0 8px 18px rgba(138,90,0,.35);
}
body.b471 .tip-sec .tip-row .pill-btn.sel .tip-amt { color: #3A2703; }
body.b471 .tip-sec .tip-custom { background: #fff; border-color: #B98A2F; }
body.b471 .tip-sec .tip-custom span { color: #3A2410; }
body.b471 .tip-sec .tip-custom input { color: #241708; }

/* ============================================================
   BUILD 386, item 4 (gate Features:Check474, owner,
   Nov 7, 2026 — "increase the size of text"): the header
   Book / Search buttons wear bigger text. On phones the
   two buttons share one row, so the size is the largest
   that fits a 390px row with both labels on one line —
   letter spacing drops to zero and the icons, chevrons
   and gaps tighten to pay for it. Scoped to body.b474;
   gate off: the buttons render exactly as before.
   ============================================================ */
@media (max-width: 640px) {
    body.pub.b474 .hw-actions { gap: 10px; }
    body.pub.b474 .hw-btn {
        font-size: .93rem;
        letter-spacing: 0;
        gap: 6px;
        padding: 12px 4px;
    }
    body.pub.b474 .hw-btn svg { width: 16px; height: 16px; }
    body.pub.b474 .hw-btn .pill-chev { width: 13px; height: 13px; }
}
@media (min-width: 641px) and (max-width: 767px) {
    body.pub.b474 .hw-btn { font-size: .98rem; letter-spacing: .02em; }
}

/* ============================================================
   BUILD 387, item 1 (gate Features:Check475, owner,
   Nov 7, 2026 — "Check all buttons and text everywhere.
   A lot of them too small"): a readability floor for the
   small text on the customer surfaces, the station
   sign-in screens, the booking alert cards and the
   payment tab's text rows — the text a person has to
   READ. Deliberately NOT touched: the admin Book grid
   and its tags/coins (dense working furniture), badges,
   calendar and time-picker number cells (sized to their
   grids). Scoped to body.b475; gate off: every size is
   exactly as before.
   ============================================================ */
body.b475 .field .optional { font-size: 15.5px; }
body.b475 .field .error { font-size: 15px; }
body.b475 .fineprint { font-size: 15px; }
body.b475 .conf-cap { font-size: 15px; }
body.b475 .conf-bubble { font-size: 15px; }
body.b475 .conf-btn-note { font-size: 15px; }
body.b475 .book-date { font-size: 15px; }
body.b475 .book-svc .svc-name { font-size: 15px; }
body.b475 .svc-btn { font-size: 15px; }
body.b475 .picked-summary .when { font-size: 15px; }
body.b475 .pick-row .p-sub { font-size: 15px; }
body.b475 .pick-row .p-profile { font-size: 15.5px; }
body.b475 .menu-item .desc { font-size: 15.5px; }
body.b475 .menu-list .menu-desc { font-size: 15.5px; }
body.b475 .svc-item-desc { font-size: 15.5px; }
body.b475 .bill-addr { font-size: 15px; }
body.b475 .bill-paidline { font-size: 15px; }
body.b475 .bill-extra { font-size: 15.5px; }
body.b475 .bill-web { font-size: 15.5px; }
body.b475 .pay-textrow .btn { font-size: 15px; }
body.b475 .pay-rec-sub { font-size: 15.5px; }
body.b475 .kicker { font-size: 13.5px; }
body.b475 .page-top-kicker { font-size: 13.5px; }
body.b475 .hw-sub { font-size: 12.5px; }
body.b475 .footer-bottom { font-size: 15px; }
body.b475 .xcard-sub { font-size: 14.5px; }
body.b475 .svc-ribbon { font-size: 14px; }
body.b475 .video-card p { font-size: 15.5px; }
body.b475 .pin-hint { font-size: 15.5px; }
body.b475 .si-time span { font-size: 14.5px; }
body.b475 .si-ph { font-size: 15px; }
body.b475 .si-st { font-size: 15px; }
body.b475 .btn-mini { font-size: 15px; }
body.b475 .header-call { font-size: 15.5px; }
body.b475 .al-who { font-size: 13.5px; }
body.b475 .al-meta { font-size: 14.5px; }
body.b475 .al-when { font-size: 14.5px; }
body.b475 .al-daylabel { font-size: 13.5px; }
body.b475 .al-custphone { font-size: 15.5px; }
body.b475 .ci-brand { font-size: 15px; }
body.b475 .ci353-witag { font-size: 12px; }
body.b475 .ci353-tbox .lab { font-size: 13.5px; }
body.b475 .ci359-sep { font-size: 15px; }
body.b475 .ci374-sep335 { font-size: 15px; }
body.b475 .bar450-cap { font-size: 12.5px; }

/* ============================================================
   BUILD 387, item 2 (gate Features:Check476, owner,
   Nov 7, 2026 — "Make bigger. Place at top left
   corner" "On the header"): the header menu button
   grows (bars 24px → 34px wide, 2.5px → 4px thick,
   wider gaps, a bigger pad) and moves from the top
   right corner of the header to the top left corner.
   Scoped to body.b476; gate off: the button renders
   and sits exactly as before.
   ============================================================ */
body.b476 .nav-toggle {
    left: 12px;
    right: auto;
    top: 12px;
    padding: 12px;
    gap: 7px;
}
body.b476 .nav-toggle span {
    width: 34px;
    height: 4px;
}
/* Fix round (owner, Nov 8, 2026 — "the menu icon must
   be at the very top on the left, inside the header"):
   in the themed header the button leaves the bar below
   the hero and sits at the hero's own top-left corner
   (the hero seat the partial renders gate-on); on the
   banner-home variant (no hero seat) it pins to the
   bar's top-left corner instead. The soft dark pad
   keeps the gold bars readable over the artwork. */
body.b476 .hw-top {
    position: relative;
}
body.b476 .nav-toggle-hero {
    position: absolute;
    top: 10px;
    left: 10px;
    margin: 0;
    z-index: 70;
    background: rgba(43, 24, 6, .42);
    border-radius: 12px;
}
body.b476 .nav-toggle-hero span {
    background: var(--hw-gold-bright);
}
body.b476 .hw-header .nav-toggle {
    position: absolute;
    top: 6px;
    left: 10px;
    right: auto;
    margin: 0;
    z-index: 70;
}

/* check477 (BUILD 388 item 1, owner, Nov 7, 2026):
   the hero artwork wrap — renders gate-on only, so
   the gate-off page is untouched. The wrap is the
   "Welcome" word's seat: the word's bottom anchor
   now measures from the artwork alone, so it can
   never sit across the picture's bottom edge again
   (the in-flow name band under the phone picture
   used to stretch the anchor past the artwork). */
.hw-art477 { position: relative; display: block; }

/* ============================================================
   BUILD 389, item 1 (gate Features:Check478 — body.b478):
   the DEV screen picker. The DEV segment's box (in DEV
   only) opens a small list; a device pick frames the page
   in an overlay at exactly the salon devices' sizes —
   iPhone 15 Plus 430x932 / 932x430, iPad A16 820x1180 /
   1180x820 — scaled down only when the computer screen
   itself is smaller than the frame. While the picker
   shows, the slider knob hides: the box carries the
   state ("DEV · <view>"). Gate off: no .b478, and the
   picker markup never renders, so every page is
   byte-identical to BUILD 388. */
body.b478 .switcher257.env-dev .env-knob257 {
    display: none;
}
body.b478 .devpick478 {
    position: relative;
}
body.b478 .devpick478-arrow {
    font-size: .72em;
}
body.b478 .devpick478-menu {
    position: absolute;
    bottom: calc(100% + 10px);
    right: 0;
    min-width: 248px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 6px;
    background: #fffdf8;
    border: 1.5px solid #d9a441;
    border-radius: 14px;
    box-shadow: 0 14px 34px rgba(61, 35, 5, .28);
    z-index: 9990;
}
body.b478 .devpick478-menu[hidden] {
    display: none;
}
body.b478 .devpick478-opt {
    text-align: left;
    background: none;
    border: 0;
    border-radius: 9px;
    padding: 11px 12px;
    font-size: 15px;
    font-weight: 600;
    color: #43302a;
    cursor: pointer;
    white-space: nowrap;
}
body.b478 .devpick478-opt:hover {
    background: #fbeed9;
}
body.b478 .devpick478-opt.is-on {
    background: #f7e3c2;
}
body.b478 .devpick478-ck {
    color: #7c2128;
    font-weight: 800;
}
body.b478 .devframe478 {
    position: fixed;
    inset: 0;
    z-index: 99980;
    background: rgba(24, 14, 4, .93);
    display: flex;
    flex-direction: column;
    align-items: center;
    overflow: auto;
}
body.b478 .devframe478-bar {
    display: flex;
    gap: 14px;
    align-items: center;
    padding: 12px 16px 4px;
    color: #f7e3c2;
    font-size: 16px;
    font-weight: 700;
}
body.b478 .devframe478-dims {
    opacity: .75;
    font-weight: 600;
}
body.b478 .devframe478-close {
    margin-left: 8px;
    background: #fbeed9;
    border: 1.5px solid #d9a441;
    color: #7c2128;
    border-radius: 999px;
    padding: 8px 16px;
    font-size: 15px;
    font-weight: 700;
    cursor: pointer;
}
body.b478 .devframe478-stage {
    position: relative;
    margin: 8px auto 22px;
    flex: 0 0 auto;
}
body.b478 .devframe478-if {
    border: 0;
    background: #fff;
    border-radius: 14px;
    box-shadow: 0 24px 60px rgba(0, 0, 0, .5);
    transform-origin: top left;
}

/* ============================================================
   BUILD 390, item 1 (gate Features:Check480 — body.b480):
   when the station rests (the sign-in page's rest face is
   up), the owner's chrome goes dark with the screen —
   the view switcher (z-index 10001), the vertical icon
   bar (10002) and the camera arm dot (10000) all ride
   ABOVE the smart-rest black layer (9998) today, so they
   stay lit on the dark screen. Gate on: while #ciRest is
   up (not .cir-off), those three are hidden; the moment
   the desk wakes they are back. Only the CheckIn page
   carries #ciRest, so no other page can trip the rule.
   Gate off: no .b480, every page byte-identical to
   BUILD 389. */
body.b480:has(#ciRest:not(.cir-off)) .switcher257,
body.b480:has(#ciRest:not(.cir-off)) .bar450,
body.b480:has(#ciRest:not(.cir-off)) .ci-armdot257 {
    visibility: hidden;
}

/* ============================================================
   BUILD 391, item 3 (gate Features:Check483 — body.b483):
   the Book view's Customers tab on the phone. The search
   input and the add-customer line shipped with NO styles
   at all — the input rendered at the browser's tiny
   default size and the line as small plain text (the
   owner's "super tiny" screenshot). Gate on: the search
   is a full-width, finger-sized field and the add line
   is a real tappable row, at every width; on phones the
   tabs keep their full size instead of shrinking.
   Gate off: no .b483, byte-identical to BUILD 390. */
body.b483 .cust-search {
    width: 100%;
    box-sizing: border-box;
    font-size: 17px;
    min-height: 52px;
    padding: 12px 16px;
    border: 2px solid #d9c4a5;
    border-radius: 999px;
    background: #fffdf8;
    color: #43302a;
}
body.b483 .cust-add-link {
    font-size: 17px;
    font-weight: 600;
    margin: 14px 2px 6px;
}
body.b483 .cust-add-link a {
    display: inline-block;
    padding: 10px 6px;
}
@media (max-width: 640px) {
    body.b483 .btab433 {
        font-size: 19px;
        min-height: 56px;
    }
}

/* ============================================================
   BUILD 391, item 5 (gate Features:Check485 — body.b485):
   a past cell greys EVERY card's background to the pale
   #f3f1f0 (the day-past rule) but sets no text color —
   the two white-text cards (the violet walk-in hold and
   the red discount card) kept their white names on the
   pale ground: invisible (the owner's "can not see"
   screenshot, Sue King's 1:00 PM walk-in at 2 PM).
   Gate on: on light themes, a past walk-in / discount
   card takes dark text with matching note + check
   tones. Dark themes (Thanksgiving 2, Halloween)
   grey their past cards to dark grounds and keep
   white text — excluded by name. Gate off: no .b485,
   byte-identical to BUILD 390. */
body.b485:not(.theme-thanksgiving2):not(.theme-halloween)
    .book-grid td.day-past .appt-card.card-walkin294,
body.b485:not(.theme-thanksgiving2):not(.theme-halloween)
    .book-grid td.day-past .appt-card.card-discount {
    color: #4a3f3a;
}
body.b485:not(.theme-thanksgiving2):not(.theme-halloween)
    .book-grid td.day-past .appt-card.card-walkin294 .act-chk-grey,
body.b485:not(.theme-thanksgiving2):not(.theme-halloween)
    .book-grid td.day-past .appt-card.card-discount .act-chk-grey {
    color: #8a7a72;
}
body.b485:not(.theme-thanksgiving2):not(.theme-halloween)
    .book-grid td.day-past .appt-card.card-walkin294 .p-note,
body.b485:not(.theme-thanksgiving2):not(.theme-halloween)
    .book-grid td.day-past .appt-card.card-discount .p-note {
    color: #6b5a52;
}

/* ============================================================
   BUILD 391 fix round, item 4 (gate Features:Check484 —
   body.b484): the Book page's per-device layouts, from
   the owner's approved samples (design/build-391/
   sample-book-iphone.html, sample-book-ipad.html).

   PHONE (max-width 640px): the week grid becomes a
   one-column card list for ONE day. The pick script on
   the page adds .list484 to the table and .day484 to
   the picked day's cells (today when the window holds
   it, else the first day); every rule here hangs on
   those classes, so without script — and at every
   other width — the grid is exactly as today. Only
   rows holding the picked day's appointment cells
   show, each led by its time label; the cards
   themselves are the grid's own .appt-card component
   laid out in flow at natural height, full width,
   with the sample's big name. The footer's late-disc
   cell for the picked day stays under the list. The
   pinned mirror head collapses to the picked day's
   strip — the list's day bar. The Sign-ins tab's
   wait-list cards get the sample's big Accept /
   Decline buttons.

   IPAD (641–1199px): the .bk484-ipad section the page
   renders gate-on (time rows x the two workers'
   columns, cards the shared _BookCard component)
   replaces the week grid, which is hidden in this
   band only. Outside the band the section never
   shows; on desktop the grid stands exactly as
   today. (Known trade, the approved sample's own
   shape: the late/opening discs live in the grid,
   so in this band they are not on screen; they
   remain on the phone list's footer and on desktop.)

   Gate off: no .b484, byte-identical to BUILD 391. */
.bk484-ipad { display: none; }
@media (max-width: 640px) {
    body.b484 .book-pinhead {
        position: static;
        display: block;
        border: 0;
        background: transparent;
    }
    body.b484 .book-pin-corner { display: none; }
    body.b484 .book-pin-clip { overflow: visible; }
    body.b484 .book-pin-strip {
        display: block;
        transform: none !important;
    }
    body.b484 .book-pin-day {
        display: none;
        border: 0;
        background: transparent;
        padding: 6px 2px 2px;
        font-size: 21px;
        font-weight: 800;
        color: #43302a;
    }
    body.b484 .book-pin-day.day484 { display: block; }
    body.b484 .book-pin-day .book-date { font-size: 21px; }
    body.b484 #bookScroll { overflow: visible !important; }
    body.b484 table.book-grid.list484 {
        display: block;
        width: auto !important;
        min-width: 0 !important;
        border: 0;
        background: transparent;
    }
    body.b484 table.book-grid.list484 thead { display: none; }
    body.b484 table.book-grid.list484 tbody { display: block; }
    body.b484 table.book-grid.list484 tbody tr { display: none; }
    body.b484 table.book-grid.list484 tbody tr:has(> td.day484.book-appt) {
        display: block;
    }
    body.b484 table.book-grid.list484 th.book-time {
        display: block;
        position: static;
        box-shadow: none;
        background: transparent;
        border: 0;
        padding: 10px 2px 4px;
        font-size: 14px;
        font-weight: 800;
        letter-spacing: .8px;
        color: #a4835f;
        text-align: left;
    }
    body.b484 table.book-grid.list484 tr.book-half th.book-time {
        color: #a4835f;
    }
    body.b484 table.book-grid.list484 td { display: none; }
    body.b484 table.book-grid.list484 td.day484 {
        display: block;
        width: auto;
        padding: 0;
        border: 0;
        background: transparent;
    }
    body.b484 table.book-grid.list484 td.day484 .appt-area {
        position: static;
    }
    body.b484 table.book-grid.list484 .appt-card {
        position: static;
        display: flex;
        width: auto !important;
        height: auto !important;
        min-height: 0;
        margin: 0 0 10px;
        padding: 12px 14px;
        border-radius: 16px;
        box-shadow: 0 2px 8px rgba(122, 72, 20, .08);
        font-size: 16px;
    }
    body.b484 table.book-grid.list484 .appt-card .card-line1 strong {
        font-size: 20px;
    }
    body.b484 table.book-grid.list484 td.day484 > a.cell-plus {
        display: none;
    }
    body.b484 table.book-grid.list484 td.day484 > a.cell-plus:first-of-type {
        display: block;
        position: static;
        text-align: center;
        font-size: 26px;
        line-height: 1;
        padding: 2px 0 8px;
    }
    body.b484 table.book-grid.list484 tfoot { display: block; }
    body.b484 table.book-grid.list484 tfoot tr { display: block; }
    body.b484 table.book-grid.list484 tfoot th.book-time {
        display: none;
    }
    body.b484 table.book-grid.list484 tfoot td { display: none; }
    body.b484 table.book-grid.list484 tfoot td.day484 {
        display: block;
        width: auto;
        padding: 10px 0 4px;
        border: 0;
        background: transparent;
    }
    body.b484 .ci359-card { border-radius: 16px; }
    body.b484 .ci359-btn.accept,
    body.b484 .ci359-btn.decline,
    body.b484 .ci353-btn {
        font-size: 18px;
        padding: 13px 10px;
    }
}
@media (min-width: 641px) and (max-width: 1199px) {
    body.b484 .book-pinwrap { display: none; }
    body.b484 .bk484-ipad {
        display: block;
        margin-top: 16px;
    }
    body.b484 .bk484-day {
        font-size: 24px;
        font-weight: 800;
        color: #43302a;
        padding: 2px 2px 12px;
    }
    body.b484 .bk484-grid {
        display: grid;
        grid-template-columns: 90px 1fr 1fr;
        gap: 10px;
    }
    body.b484 .bk484-th {
        font-size: 17px;
        font-weight: 800;
        color: #7c5a21;
        text-align: center;
        padding: 8px 0;
    }
    body.b484 .bk484-tm {
        font-size: 16px;
        font-weight: 700;
        color: #a4835f;
        text-align: right;
        padding: 12px 8px 0 0;
    }
    body.b484 .bk484-cell {
        display: flex;
        flex-direction: column;
        gap: 8px;
        min-width: 0;
    }
    body.b484 .bk484-cell .appt-card {
        position: static;
        display: flex;
        width: auto !important;
        height: auto !important;
        min-height: 0;
        padding: 10px 12px;
        border-radius: 14px;
        box-shadow: 0 2px 8px rgba(122, 72, 20, .08);
    }
    body.b484 .bk484-cell .appt-card .card-line1 strong {
        font-size: 19px;
    }
    body.b484 .bk484-plus {
        color: #d08a94;
        font-size: 26px;
        line-height: 1;
        text-align: center;
        text-decoration: none;
        padding: 4px 0;
    }
}

/* ============================================================
   BUILD 391 fix round (gate Features:Check486 —
   body.b486): the station camera is OFF on the
   sign-in screen (the owner's order) — the camera
   arm dot, the camera's own on/off switch, is
   hidden outright: a hidden switch cannot invite
   a tap, and Apple's green camera dot never
   appears because the camera itself never starts
   (the CheckIn page's Check486 severing). Gate
   off: no .b486, byte-identical to BUILD 391. */
body.b486 .ci-armdot257 {
    display: none !important;
}

/* ============================================================
   BUILD 391 fix round, item 7 (gate Features:Check487 —
   body.b487): the dimmed picture at rest. Today the
   smart rest's veil (check466's .dim466) is plain
   black, so a resting station is a dead black screen.
   While this gate shows, the veil — up exactly while
   #ciRest lacks .cir-off, gone the moment it wakes,
   its timing and touch-transparency untouched —
   carries the sign-in scene instead: the rest face's
   own photo (check215's salon picture, the .cir
   background) under a strong black overlay (~84%),
   so the resting screen is clearly dark and clearly
   resting, but visibly the salon picture. No element
   is added and no word is added; check480's chrome
   hiding at rest rides above the veil exactly as
   today. Gate off: no .b487, the veil is plain black
   and every page is byte-identical to BUILD 391. */
body.b487:has(#ciRest:not(.cir-off)) .dim466 {
    background: linear-gradient(rgba(0, 0, 0, .84),
        rgba(0, 0, 0, .84)),
        url("/images/checkin-rest-photo.jpg")
        center / cover no-repeat;
}

/* ============================================================
   BUILD 391 fix round, item 11 REVISED (gate
   Features:Check490 — body.b490): the DEV screen picker
   is hidden on iDevices (owner, Nov 8, 2026, 4:39 PM:
   "Hide in idevice" — the picker is a COMPUTER-only
   tool; this supersedes the same afternoon's "make it
   work on phone and iPad" scope). The twin segment
   (.devtwin490, rendered only while the gate shows,
   beside the picker in the layout) never shows by
   default; on a coarse pointer the picker button
   hides and the plain DEV segment stands in its place
   — no dropdown menu, no device framing, entering and
   leaving DEV unchanged. In the iPad band, check446's
   env-axis hide (.switcher257.sw446 .sw5-row
   .sw5-env-seg, specificity 0-4-0) beats the twin's
   show rule below (0-2-1), so the twin stays hidden
   there and the band keeps today's shape exactly. On
   a fine pointer neither rule fires and the picker
   works exactly as Check478 built it. Gate off: no
   .b490 and no twin markup — every page is
   byte-identical to BUILD 391. */
body.b490 .devtwin490 {
    display: none;
}
@media (pointer: coarse) {
    body.b490 #devPick478Btn {
        display: none;
    }
    body.b490 .devtwin490 {
        display: block;
    }
}

/* ============================================================
   BUILD 392, item 1 (gate Features:Check491 — body.b491):
   the phone Book list's day header and spacing. Two
   measured defects from the owner's live screenshot
   (Nov 8, 2026), both confirmed in the rig: (1) the
   pinned mirror's picked day (.book-pin-day.day484)
   carries the pin script's inline column width — 0px
   in list mode, where the grid's thead is display:none
   and measures zero — so "Today: Sunday Nov 8" stacked
   a word per line in a sliver (measured: 4px wide,
   142px tall, 4+ lines); (2) the phone grid's frozen
   Time-cell height (the check110 block: th.book-time
   height 81.09px, the sideways grid's row-height
   driver) survived into list mode as dead air above
   each hour's cards (measured: an 81px label block
   over a one-line label). Gate on, phone band only:
   the picked day spans the list's full width with its
   words on ONE line (the markup's <br> retired, the
   date spaced as a word), and the list's Time cells
   size to their text. The sideways grid in every
   other state, the iPad band and desktop are
   untouched. Gate off: no .b491, byte-identical to
   BUILD 391. */
@media (max-width: 640px) {
    body.b491 .book-pin-day.day484 {
        width: auto !important;
        white-space: nowrap;
    }
    body.b491 .book-pin-day.day484 br { display: none; }
    body.b491 .book-pin-day.day484 .book-date {
        margin-left: .35em;
    }
    body.b491 table.book-grid.list484 tbody th.book-time {
        height: auto;
    }
}

/* ============================================================
   BUILD 392, item 2 (gate Features:Check492 — body.b492):
   the Payment tab's method pills never wrap. "Clover"
   is the longest word: icon + word measure a hair
   wider than the tile, so the word wrapped under its
   icon while Cash and Zelle sat on one line (owner's
   screenshot, Nov 8, 2026; measured in the rig: the
   Clover word's center sat 25px below its icon's,
   Cash/Zelle within 1px). Gate on: the three pills
   are flex rows — icon and word on one line, centered;
   the grid stretch keeps the three heights equal. The
   Final Bill sheet carries its own f492 rule (it
   renders without this layout). Icons, words, colors
   and the selected state are untouched. Gate off: no
   .b492, byte-identical to BUILD 391. */
body.b492 .pay-methods .pay-method {
    display: flex;
    align-items: center;
    justify-content: center;
    white-space: nowrap;
}

/* ============================================================
   BUILD 392, item 4 (gate Features:Check494 — body.b494):
   one tab dress on both customer screens. The shared
   _CustTabs anchors wear the plain rose-outline pill
   of the base rule, but the Payment page's section
   (.paypage469 — BUILD 384/385's Salon Button
   direction) dresses them as big cream tiles with
   gold borders, so the same three tabs changed
   clothes between the Profile page and the Payment
   page (owner: "Different styles of buttons", Nov 8,
   2026). Gate on: the Customer (Profile) page's
   section carries .custpage494 (rendered only while
   the gate shows) and its tabs wear the Payment
   page's exact dress, declaration for declaration.
   The Payment page itself is unchanged. Gate off:
   no .b494 and no section class — byte-identical to
   BUILD 391. */
body.b494 .custpage494 .cust-tabs a {
    min-height: 64px; border-radius: 15px;
    background: linear-gradient(180deg, #fffaf1, #fbeed9);
    border: 1.5px solid #d9a441; color: #7c2128;
    font-family: Georgia, 'Times New Roman', serif;
    font-size: 24px; font-weight: 700;
    box-shadow: 0 3px 10px rgba(176, 127, 42, .18), inset 0 1px 0 #ffffff;
}
body.b494 .custpage494 .cust-tabs a.on {
    background: linear-gradient(180deg, #d1828a, #b04a56);
    color: #fff; border-color: #b98a2f;
    box-shadow: 0 6px 16px rgba(176, 74, 86, .35), inset 0 1px 0 rgba(255, 255, 255, .35);
}

/* ============================================================
   BUILD 392, item 8 (gate Features:Check498 — body.b498):
   the four station buttons stay for the owner. BUILD
   390's rest-hide (the f480 block) darkens the
   switcher, the camera arm dot AND the vertical icon
   bar (.bar450) while the sign-in screen rests; the
   owner ruled the bar must ALWAYS be there when he
   is logged in as admin (Nov 8, 2026: "Four buttons
   on the top right must always be there"). The bar
   renders only for owner-PIN sessions (the layout's
   show450 / show455 read), so exempting it touches
   admin sessions only — a customer session never
   renders the bar, and its rest (switcher and dot
   included) is exactly as today. Gate on: while the
   rest face is up, the bar stays visible — this rule
   mirrors f480's selector shape and stands later in
   the file, so it wins the tie. Gate off: no .b498,
   byte-identical to BUILD 391. */
body.b498:has(#ciRest:not(.cir-off)) .bar450 {
    visibility: visible;
}

/* ============================================================
   BUILD 394, item 1 (gate Features:Check500 — body.b500):
   the owner's four buttons on the phone too. The bar's
   markup is emitted for owner-PIN sessions on every page
   (the layout's show450 / show455 read), but its dress
   seats it ONLY in the tablet band (the Check450 block
   above) and, through Check455, on the station keypad
   step — so on the phone the Book's Sign-ins tab (the
   owner's screenshot, Nov 8, 2026: "Cannot return to
   phone sign in. Where are 4 buttons on top right")
   had no bar at all and no way back to the phone
   sign-in screen. While this gate shows, the phone
   band seats the same bar with Check450's own dress,
   copied rule for rule from the tablet block (the
   classes are one component — the band is all that
   changes). Only display is touched: BUILD 390's
   rest-hide and BUILD 392's admin rest exemption
   speak in visibility and compose exactly as in the
   tablet band. With the gate off there is no .b500
   and every rule here is inert.
   ============================================================ */
@media (pointer: coarse) and (max-width: 640px) {
  body.b500 .bar450 { display: flex; flex-direction: column; align-items: center; gap: 6px; position: fixed; top: 10px; right: 10px; z-index: 10002; }
  body.b500 .bar450-form { margin: 0; display: contents; }
  body.b500 .bar450-btn { display: flex; flex-direction: column; align-items: center; gap: 2px; margin: 0; padding: 0; border: 0; background: transparent; cursor: pointer; text-decoration: none; font-family: var(--font-body); -webkit-tap-highlight-color: transparent; }
  body.b500 .bar450-round { width: 50px; height: 50px; border-radius: 50%; background: #fffdf8; border: 2.5px solid #c9973f; box-shadow: 0 4px 12px rgba(86, 48, 54, .28); display: flex; align-items: center; justify-content: center; color: #7c1530; }
  body.b500 .bar450-round svg { width: 23px; height: 23px; display: block; }
  body.b500 .bar450-cap { font-size: 11px; font-weight: 700; line-height: 1.15; color: #5a3a22; text-shadow: 0 1px 4px rgba(255, 248, 236, .95), 0 0 6px rgba(255, 248, 236, .8); }
  body.b500 .bar450-btn.on .bar450-round { background: var(--rose); border-color: var(--rose); color: #fff; }
  body.b500 .bar450-btn:active .bar450-round { transform: scale(.94); }
}

/* ============================================================
   BUILD 396, item 3 (gate Features:Check505 — body.b505):
   the four-button bar the CheckIn page renders itself
   (the layout stands its shared bar down on the station
   while this gate shows). The dress is Check450's own,
   copied rule for rule: the tablet block from Check450's
   band rules and the phone block from Check500's f500
   rules — the classes are one component, the band is all
   that changes; only the seat is scoped to .b505 (the
   marker the layout emits on the sign-in surface alone,
   so no other page's bar is touched). The rest rule
   after the bands re-states Check480's rest-hide for
   this bar: Check498's exemption (the b498 rule above,
   same specificity) was written for the layout's bar
   and stands earlier in the file, so without this line
   it would hold the station's own bar up at rest —
   the owner's word for the station is that the bar
   hides with the other controls while the screen
   rests and returns when it wakes. Gate off: no .b505
   marker, the page renders no bar of its own, and
   every rule here is inert.
   ============================================================ */
@media (pointer: coarse) and (min-width: 641px) and (max-width: 1400px) {
  body.b505 .bar450 { display: flex; flex-direction: column; align-items: center; gap: 6px; position: fixed; top: 10px; right: 10px; z-index: 10002; }
  body.b505 .bar450-form { margin: 0; display: contents; }
  body.b505 .bar450-btn { display: flex; flex-direction: column; align-items: center; gap: 2px; margin: 0; padding: 0; border: 0; background: transparent; cursor: pointer; text-decoration: none; font-family: var(--font-body); -webkit-tap-highlight-color: transparent; }
  body.b505 .bar450-round { width: 50px; height: 50px; border-radius: 50%; background: #fffdf8; border: 2.5px solid #c9973f; box-shadow: 0 4px 12px rgba(86, 48, 54, .28); display: flex; align-items: center; justify-content: center; color: #7c1530; }
  body.b505 .bar450-round svg { width: 23px; height: 23px; display: block; }
  body.b505 .bar450-cap { font-size: 11px; font-weight: 700; line-height: 1.15; color: #5a3a22; text-shadow: 0 1px 4px rgba(255, 248, 236, .95), 0 0 6px rgba(255, 248, 236, .8); }
  body.b505 .bar450-btn.on .bar450-round { background: var(--rose); border-color: var(--rose); color: #fff; }
  body.b505 .bar450-btn:active .bar450-round { transform: scale(.94); }
}
@media (pointer: coarse) and (max-width: 640px) {
  body.b505 .bar450 { display: flex; flex-direction: column; align-items: center; gap: 6px; position: fixed; top: 10px; right: 10px; z-index: 10002; }
  body.b505 .bar450-form { margin: 0; display: contents; }
  body.b505 .bar450-btn { display: flex; flex-direction: column; align-items: center; gap: 2px; margin: 0; padding: 0; border: 0; background: transparent; cursor: pointer; text-decoration: none; font-family: var(--font-body); -webkit-tap-highlight-color: transparent; }
  body.b505 .bar450-round { width: 50px; height: 50px; border-radius: 50%; background: #fffdf8; border: 2.5px solid #c9973f; box-shadow: 0 4px 12px rgba(86, 48, 54, .28); display: flex; align-items: center; justify-content: center; color: #7c1530; }
  body.b505 .bar450-round svg { width: 23px; height: 23px; display: block; }
  body.b505 .bar450-cap { font-size: 11px; font-weight: 700; line-height: 1.15; color: #5a3a22; text-shadow: 0 1px 4px rgba(255, 248, 236, .95), 0 0 6px rgba(255, 248, 236, .8); }
  body.b505 .bar450-btn.on .bar450-round { background: var(--rose); border-color: var(--rose); color: #fff; }
  body.b505 .bar450-btn:active .bar450-round { transform: scale(.94); }
}
body.b505:has(#ciRest:not(.cir-off)) .bar450 {
    visibility: hidden;
}

/* ============================================================
   BUILD 398, item 2 (gate Features:Check508 — the framed
   page's own band classes, body.b508fp / body.b508fi):
   the page inside the DEV screen picker's frame renders
   as the picked device. The frame runs on the owner's
   computer, whose fine (mouse) pointer keeps every
   (pointer: coarse) band rule in this file from firing
   inside it — so the framed sign-in page showed no
   four-button bar at either size (owner, Nov 9, 2026:
   "Missing on iphone too"). While the gate shows, the
   layout's marker script stamps the picked device's
   class on the framed page's body (b508fp in the
   iPhone frame, b508fi in the iPad frame), and the
   rules below are the standing band rules copied
   selector for selector with that class OR-ed in place
   of the pointer test: the bar's tablet band
   (Check450) and phone bands (Check455's station seat,
   Check500, Check505 — the classes are one component,
   the band is all that changes), check446's iPad
   switcher band (inside the iPad frame the switcher
   is the three-icon vertical bar with no environment
   axis, exactly as a real iPad), Check457's
   Rewards heading seat, and the sign-in picker's own
   iPad scene treatment (Checks 418/428/445 — the
   portrait-orientation and short-frame variants are
   not copied: the only iPad frame is landscape,
   1180x820, where they are inert on the real device
   too). Two deliberate exceptions, both recorded in
   diag/check398/PROOF.md: Check490's coarse-pointer
   picker hiding is NOT copied — inside a frame the
   picker is the owner's frame-switching control
   (BUILD 398 item 1), so the framed phone keeps its
   picker button and the plain DEV twin stays hidden;
   and Check506's rest band test is a script read,
   left as built. The classes exist only inside the
   picker's frame and only while the gate shows:
   every real device and the plain desktop render
   exactly as BUILD 397.
   ============================================================ */
/* --- ci378 ipad scene (check418/428), framed-device copy --- */
body.b508fi.f418.f428 .ci378-banner {
    padding-top: 3.2vh;
}
body.b508fi.f418.f428 .ci378-greet {
    font-size: 4.6cqw;
}
body.b508fi.f418.f428 .ci378-ask {
    font-size: 2.4cqw;
}
body.b508fi.f418.f428 .ci378-cards,
body.b508fi.f418.f428 .ci378-stage .ci378-cards {
    flex-direction: row;
}
body.b508fi.f418.f428 .ci378-cards {
    gap: 26px;
        align-items: center;
}
body.b508fi.f418.f428 .ci378-card {
    flex: 1 1 0;
        min-width: 0;
}
body.b508fi.f418.f428 .ci378-stage .ci378-card {
    flex: 1 1 0; height: auto; aspect-ratio: auto;
        min-height: 0;
}
body.b508fi.f418.f428 .ci378-inner {
    flex-direction: column;
        aspect-ratio: 337 / 448; height: auto;
        border-radius: 7.7cqw;
}
body.b508fi.f418.f428 .ci378-stage .ci378-inner {
    aspect-ratio: 337 / 448; height: auto;
}
body.b508fi.f418.f428 .ci378-photo {
    top: 0; left: 0;
        right: 0; bottom: auto; width: auto;
        height: 53.1%;
}
body.b508fi.f418.f428 .ci378-band {
    position: absolute;
        left: 0; right: 0; top: auto; bottom: 0;
        height: 46.9%; flex-direction: column;
        align-items: center; justify-content: center;
        gap: 4.8%; padding: 0;
        background: linear-gradient(135deg, #fdeef1 0%,
            #f9dbe0 55%, #f4ccd4 100%);
}
body.b508fi.f418.f428 .ci378-icon {
    height: 36%;
}
body.b508fi.f418.f428 .ci378-band-nails .ci378-icon {
    height: 40%;
}
body.b508fi.f418.f428 .ci378-card:has(input:checked)
        .ci378-band {
    filter: none;
}
body.b508fi.f418.f428 .ci378-name {
    font-size: 12.8cqw;
}
body.b508fi.f418.f428 .ci378-go {
    right: 4.2%;
        bottom: 6.7%; height: 21%; font-size: 5cqw;
}
body.b508fi.f418.f428 .ci378-check {
    left: 86%;
        right: auto; top: 50%; bottom: auto;
        transform: translate(-50%, -50%);
        width: 20cqw; height: 20cqw;
        font-size: 12cqw;
}
body.b508fi.f418.f428 .ci378-stage .ci378-check {
    font-size: 12cqw;
}

/* --- ci378 stage stretch (check445), framed-device copy --- */
body.b508fi.f418.f428.f445 .ci378-stage .ci378-cards {
    align-items: stretch;
}
body.b508fi.f418.f428.f445 .ci378-stage .ci378-card {
    display: flex; align-items: center;
        min-height: 0;
}
body.b508fi.f418.f428.f445 .ci378-stage .ci378-inner {
    flex: 1 1 auto; max-height: 100%;
}

/* --- switcher ipad band (check446), framed-device copy --- */
body.b508fi .switcher257.sw446 {
    left: auto; right: 10px;
}
body.b508fi .switcher257.sw446 .sw5-row {
    flex-direction: column; width: auto; padding: 4px; gap: 4px; cursor: default; touch-action: auto;
}
body.b508fi .switcher257.sw446 .sw5-row .vp3-seg {
    flex: none; width: 50px; height: 50px; padding: 0; font-size: 0; line-height: 0; display: flex; align-items: center; justify-content: center;
}
body.b508fi .switcher257.sw446 .sw5-row .vp3-seg .vp3-ic {
    display: block;
}
body.b508fi .switcher257.sw446 .sw5-row .vp3-seg[name="mode"][value="customer"] {
    order: 1;
}
body.b508fi .switcher257.sw446 .sw5-row .vp3-seg[name="mode"][value="admin"] {
    order: 2;
}
body.b508fi .switcher257.sw446 .sw5-row .vp3-seg[name="mode"][value="signin"] {
    order: 3;
}
body.b508fi .switcher257.sw446 .sw5-row .sw5-env-seg,
body.b508fi .switcher257.sw446 .env-knob257 {
    display: none;
}

/* --- bar tablet band (check450), framed-device copy --- */
body.b508fi .switcher257.sw450 {
    display: none;
}
body.b508fi.f450.f346 .ci-wrap.ci334-stage .ci346-find,
body.b508fi.f450.f353 .ci-wrap.ci334-stage .ci353-review,
body.b508fi.f450 .ci353-icons {
    display: none;
}
body.b508fi .bar450 {
    display: flex; flex-direction: column; align-items: center; gap: 6px; position: fixed; top: 10px; right: 10px; z-index: 10002;
}
body.b508fi .bar450-form {
    margin: 0; display: contents;
}
body.b508fi .bar450-btn {
    display: flex; flex-direction: column; align-items: center; gap: 2px; margin: 0; padding: 0; border: 0; background: transparent; cursor: pointer; text-decoration: none; font-family: var(--font-body); -webkit-tap-highlight-color: transparent;
}
body.b508fi .bar450-round {
    width: 50px; height: 50px; border-radius: 50%; background: #fffdf8; border: 2.5px solid #c9973f; box-shadow: 0 4px 12px rgba(86, 48, 54, .28); display: flex; align-items: center; justify-content: center; color: #7c1530;
}
body.b508fi .bar450-round svg {
    width: 23px; height: 23px; display: block;
}
body.b508fi .bar450-cap {
    font-size: 11px; font-weight: 700; line-height: 1.15; color: #5a3a22; text-shadow: 0 1px 4px rgba(255, 248, 236, .95), 0 0 6px rgba(255, 248, 236, .8);
}
body.b508fi .bar450-btn.on .bar450-round {
    background: var(--rose); border-color: var(--rose); color: #fff;
}
body.b508fi .bar450-btn:active .bar450-round {
    transform: scale(.94);
}

/* --- bar455only guard (check455), framed-device copy --- */
body.b508fi .bar450.bar455only {
    display: none;
}

/* --- rewards heading (check457), framed-device copy --- */
body.b508fi.f457 .ci-wrap.ci334-stage .ci457-head {
    display: block; position: absolute; z-index: 4; pointer-events: none; text-align: center; left: calc(var(--sx) + var(--sw) * 0.356); width: calc(var(--sw) * 0.388); top: calc(var(--sy) + var(--sh) * 0.058);
}
body.b508fi .ci457-line1 {
    display: flex; align-items: center; justify-content: center; gap: calc(var(--sw) * 0.018); color: #f2c14e;
}
body.b508fi .ci457-script {
    font-family: "Great Vibes", cursive; font-weight: 400; font-size: calc(var(--sw) * 0.056); line-height: 1.15; color: #f6c95c; text-shadow: 0 2px 10px rgba(0, 0, 0, .55); white-space: nowrap;
}
body.b508fi .ci457-gift {
    width: calc(var(--sw) * 0.040); height: calc(var(--sw) * 0.040); flex: none; filter: drop-shadow(0 2px 5px rgba(0, 0, 0, .5));
}
body.b508fi .ci457-line2 {
    font-family: var(--font-display); font-weight: 600; font-size: calc(var(--sw) * 0.0245); color: #f0c75e; letter-spacing: .01em; margin-top: calc(var(--sh) * 0.006); text-shadow: 0 1px 6px rgba(0, 0, 0, .6); white-space: nowrap;
}

/* --- station bar tablet (check505), framed-device copy --- */
body.b508fi.b505 .bar450 {
    display: flex; flex-direction: column; align-items: center; gap: 6px; position: fixed; top: 10px; right: 10px; z-index: 10002;
}
body.b508fi.b505 .bar450-form {
    margin: 0; display: contents;
}
body.b508fi.b505 .bar450-btn {
    display: flex; flex-direction: column; align-items: center; gap: 2px; margin: 0; padding: 0; border: 0; background: transparent; cursor: pointer; text-decoration: none; font-family: var(--font-body); -webkit-tap-highlight-color: transparent;
}
body.b508fi.b505 .bar450-round {
    width: 50px; height: 50px; border-radius: 50%; background: #fffdf8; border: 2.5px solid #c9973f; box-shadow: 0 4px 12px rgba(86, 48, 54, .28); display: flex; align-items: center; justify-content: center; color: #7c1530;
}
body.b508fi.b505 .bar450-round svg {
    width: 23px; height: 23px; display: block;
}
body.b508fi.b505 .bar450-cap {
    font-size: 11px; font-weight: 700; line-height: 1.15; color: #5a3a22; text-shadow: 0 1px 4px rgba(255, 248, 236, .95), 0 0 6px rgba(255, 248, 236, .8);
}
body.b508fi.b505 .bar450-btn.on .bar450-round {
    background: var(--rose); border-color: var(--rose); color: #fff;
}
body.b508fi.b505 .bar450-btn:active .bar450-round {
    transform: scale(.94);
}

/* --- station keypad bar phone (check455), framed-device copy --- */
body.b508fp.f455 .bar450 {
    display: flex; flex-direction: column; align-items: center; gap: 6px; position: fixed; top: 10px; right: 10px; z-index: 10002;
}
body.b508fp.f455 .bar450-form {
    margin: 0; display: contents;
}
body.b508fp.f455 .bar450-btn {
    display: flex; flex-direction: column; align-items: center; gap: 2px; margin: 0; padding: 0; border: 0; background: transparent; cursor: pointer; text-decoration: none; font-family: var(--font-body); -webkit-tap-highlight-color: transparent;
}
body.b508fp.f455 .bar450-round {
    width: 50px; height: 50px; border-radius: 50%; background: #fffdf8; border: 2.5px solid #c9973f; box-shadow: 0 4px 12px rgba(86, 48, 54, .28); display: flex; align-items: center; justify-content: center; color: #7c1530;
}
body.b508fp.f455 .bar450-round svg {
    width: 23px; height: 23px; display: block;
}
body.b508fp.f455 .bar450-cap {
    font-size: 11px; font-weight: 700; line-height: 1.15; color: #5a3a22; text-shadow: 0 1px 4px rgba(255, 248, 236, .95), 0 0 6px rgba(255, 248, 236, .8);
}
body.b508fp.f455 .bar450-btn.on .bar450-round {
    background: var(--rose); border-color: var(--rose); color: #fff;
}
body.b508fp.f455 .bar450-btn:active .bar450-round {
    transform: scale(.94);
}
body.b508fp.f455.f346 .ci-wrap.ci334-stage .ci346-find,
body.b508fp.f455.f353 .ci-wrap.ci334-stage .ci353-review {
    display: none;
}

/* --- bar phone band (check500), framed-device copy --- */
body.b508fp.b500 .bar450 {
    display: flex; flex-direction: column; align-items: center; gap: 6px; position: fixed; top: 10px; right: 10px; z-index: 10002;
}
body.b508fp.b500 .bar450-form {
    margin: 0; display: contents;
}
body.b508fp.b500 .bar450-btn {
    display: flex; flex-direction: column; align-items: center; gap: 2px; margin: 0; padding: 0; border: 0; background: transparent; cursor: pointer; text-decoration: none; font-family: var(--font-body); -webkit-tap-highlight-color: transparent;
}
body.b508fp.b500 .bar450-round {
    width: 50px; height: 50px; border-radius: 50%; background: #fffdf8; border: 2.5px solid #c9973f; box-shadow: 0 4px 12px rgba(86, 48, 54, .28); display: flex; align-items: center; justify-content: center; color: #7c1530;
}
body.b508fp.b500 .bar450-round svg {
    width: 23px; height: 23px; display: block;
}
body.b508fp.b500 .bar450-cap {
    font-size: 11px; font-weight: 700; line-height: 1.15; color: #5a3a22; text-shadow: 0 1px 4px rgba(255, 248, 236, .95), 0 0 6px rgba(255, 248, 236, .8);
}
body.b508fp.b500 .bar450-btn.on .bar450-round {
    background: var(--rose); border-color: var(--rose); color: #fff;
}
body.b508fp.b500 .bar450-btn:active .bar450-round {
    transform: scale(.94);
}

/* --- station bar phone (check505), framed-device copy --- */
body.b508fp.b505 .bar450 {
    display: flex; flex-direction: column; align-items: center; gap: 6px; position: fixed; top: 10px; right: 10px; z-index: 10002;
}
body.b508fp.b505 .bar450-form {
    margin: 0; display: contents;
}
body.b508fp.b505 .bar450-btn {
    display: flex; flex-direction: column; align-items: center; gap: 2px; margin: 0; padding: 0; border: 0; background: transparent; cursor: pointer; text-decoration: none; font-family: var(--font-body); -webkit-tap-highlight-color: transparent;
}
body.b508fp.b505 .bar450-round {
    width: 50px; height: 50px; border-radius: 50%; background: #fffdf8; border: 2.5px solid #c9973f; box-shadow: 0 4px 12px rgba(86, 48, 54, .28); display: flex; align-items: center; justify-content: center; color: #7c1530;
}
body.b508fp.b505 .bar450-round svg {
    width: 23px; height: 23px; display: block;
}
body.b508fp.b505 .bar450-cap {
    font-size: 11px; font-weight: 700; line-height: 1.15; color: #5a3a22; text-shadow: 0 1px 4px rgba(255, 248, 236, .95), 0 0 6px rgba(255, 248, 236, .8);
}
body.b508fp.b505 .bar450-btn.on .bar450-round {
    background: var(--rose); border-color: var(--rose); color: #fff;
}
body.b508fp.b505 .bar450-btn:active .bar450-round {
    transform: scale(.94);
}


/* ================================================================
   BUILD 399, item 2 (gate Features:Check510)

   The owner's four-button bar (.bar450) at EVERY width and
   pointer type. Until now its dress lived only inside the
   touch bands — Check450's tablet band (the plain .bar450
   rules), Check500's f500 phone band, Check505's f505 rules
   on the station — so on the computer (fine pointer, any
   width) the bar's markup rendered for an owner session but
   the base rule (.bar450 { display: none }) left it
   invisible: on the Book the owner asked where the buttons
   on the right side had gone (Nov 9, 2026 — "Must always on
   on every pages" in admin mode).

   While the gate shows, the layout marks the body b510 (and
   emits the bar for an owner session even if both band
   gates were off); the rules below seat the bar with
   Check450's own tablet dress, copied rule for rule, under
   NO media query — so it stands on the computer exactly as
   it stands on the iPad. Inside the touch bands the same
   values already apply through the band rules; this block
   changes nothing there. One deliberate omission: the cap
   carries no font-size here — outside the bands the
   small-text floor (body.b475) owns the cap size, and
   inside them the band rules keep theirs.

   The rest behaviour is untouched: every rest-hide in this
   file works through visibility (Check480's f480,
   Check498's exemption, Check505's restated hide on the
   station), and no rule below sets visibility — so on the
   sign-in page the bar still hides while the screen rests
   and returns when it wakes. The switcher is untouched
   too: nothing here seats or hides it at any width (the
   tablet band keeps its standing sw450 hide, the computer
   keeps its pill).

   Gate off: the body never carries b510 and no rule below
   can match — the file's effect is BUILD 398's exactly.
   ================================================================ */
body.b510 .bar450 { display: flex; flex-direction: column; align-items: center; gap: 6px; position: fixed; top: 10px; right: 10px; z-index: 10002; }
body.b510 .bar450-form { margin: 0; display: contents; }
body.b510 .bar450-btn { display: flex; flex-direction: column; align-items: center; gap: 2px; margin: 0; padding: 0; border: 0; background: transparent; cursor: pointer; text-decoration: none; font-family: var(--font-body); -webkit-tap-highlight-color: transparent; }
body.b510 .bar450-round { width: 50px; height: 50px; border-radius: 50%; background: #fffdf8; border: 2.5px solid #c9973f; box-shadow: 0 4px 12px rgba(86, 48, 54, .28); display: flex; align-items: center; justify-content: center; color: #7c1530; }
body.b510 .bar450-round svg { width: 23px; height: 23px; display: block; }
body.b510 .bar450-cap { font-weight: 700; line-height: 1.15; color: #5a3a22; text-shadow: 0 1px 4px rgba(255, 248, 236, .95), 0 0 6px rgba(255, 248, 236, .8); }
body.b510 .bar450-btn.on .bar450-round { background: var(--rose); border-color: var(--rose); color: #fff; }
body.b510 .bar450-btn:active .bar450-round { transform: scale(.94); }

/* ================================================================
   BUILD 400 — Check511 (owner, Nov 9, 2026: "Selected services
   is not highlighted as the time selected. Buggy"): a SELECTED
   SERVICE wears the SAME strong selected treatment as the
   SELECTED TIME, in every theme.

   Why they differed: the two selected states are defined in
   different layers. The time pills take the shared
   .slot:has(input:checked) treatment (the base rule's solid
   selected yellow, restated for the themed bodies) plus each
   seasonal theme's own unified pill rule (Halloween's and the
   two Thanksgiving twins' "selectable pills: selected = the
   same orange" blocks cover .book-svc and .time-grid
   together). The service pills, though, carry check259's own
   per-theme .book-svc selected stack — pale tints and halo
   glows in the classic and site themes, and in Thanksgiving 1
   a screenshot-review hand fix darkened ONLY the service
   fill — so on their own rules the picked services read faint
   next to the picked time (measured on BUILD 399 with
   Check279 off: Rose — service #ffeef6 pink against time
   #ffe93c yellow; Thanksgiving 1 — service dark-brown
   gradient against time bright-orange gradient). Today the
   two coincide on the live site only because Check279's
   blanket block overrides both groups with one treatment.

   The fix makes the match this gate's own doing, scoped to
   the shared service component (.book-svc — Step 1 of the
   booking form and of the confirmation change form, and the
   sign-in service pickers; one component, one dress). While
   Check279 shows, the service pills restate Check279's
   unified treatment — the exact treatment the time pills
   carry in that shape, per theme. While Check279 does not
   show, the service pills take each theme's own time-pill
   treatment: the solid selected yellow in the classic and
   site themes, the themes' orange gradient in Halloween and
   the Thanksgiving twins (with each twin's own border tone,
   exactly as its unified rule dresses the time pills).
   Only the fill, the border color, the text color and the
   shadow are set — the service pill keeps its own border
   width and medal, which are the component's, not the
   selected state's. Unselected services and the time pills
   themselves are never touched.

   Gate off: the body never carries b511 and no rule below
   can match — the file's effect is BUILD 399's exactly.
   ================================================================ */
body.b511.f279 .book-svc .slot:has(input:checked) {
    background: linear-gradient(180deg, #f59a23, #e05f0c);
    border-color: #e08a1e;
    color: #fff;
    box-shadow: 0 0 0 3px rgba(245, 154, 35, .35), 0 6px 18px rgba(224, 95, 12, .45);
}
body.b511.f279.theme-halloween .book-svc .slot:has(input:checked),
body.b511.f279.theme-thanksgiving2 .book-svc .slot:has(input:checked) {
    border-color: #ffb35c;
}
body.b511:not(.f279) .book-svc .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.b511:not(.f279).theme-halloween .book-svc .slot:has(input:checked) {
    background: linear-gradient(180deg, #f59a23, #e05f0c);
    border-color: #ffb35c;
    color: #fff;
    box-shadow: 0 0 0 3px rgba(245, 154, 35, .35), 0 6px 18px rgba(224, 95, 12, .45);
}
body.b511:not(.f279).theme-thanksgiving1 .book-svc .slot:has(input:checked) {
    background: linear-gradient(180deg, #f59a23, #e05f0c);
    border-color: #e08a1e;
    color: #fff;
    box-shadow: 0 0 0 3px rgba(245, 154, 35, .35), 0 6px 18px rgba(224, 95, 12, .45);
}
body.b511:not(.f279).theme-thanksgiving2 .book-svc .slot:has(input:checked) {
    background: linear-gradient(180deg, #f59a23, #e05f0c);
    border-color: #ffb35c;
    color: #fff;
    box-shadow: 0 0 0 3px rgba(245, 154, 35, .35), 0 6px 18px rgba(224, 95, 12, .45);
}

/* ============================================================
   BUILD 402, item 2 (gate Features:Check514): the
   four-button bar's phone seat, hardened. The
   owner reported on his iPhone that only the last
   2 of the 4 buttons showed (Nov 10, 2026) — the
   first two were lost off the top of the screen.
   The phone band's standing seat (Check500's
   block, Check505's on the station) is a fixed
   column pinned 10px from the layout viewport's
   top with no say about the phone's own top safe
   area (the status-bar / notch strip a home-screen
   or full-bleed render slides under) and no bound
   on the column's height against a short visible
   viewport. While this gate shows, in the phone
   band only: the seat's top inset is the greater
   of the standing 10px and the device's safe-area
   top inset, and the column may not grow taller
   than the visible viewport (its buttons may
   shrink to fit instead of running off either
   end). The iPad and desktop seats are untouched.
   The second pair of rules is the Check508 mirror:
   the same seat inside an iPhone device frame,
   whose band the framed page wears as a body
   class instead of the pointer test. With the
   gate off there is no .b514 and every rule here
   is inert.
   ============================================================ */
@media (pointer: coarse) and (max-width: 640px) {
  body.b514 .bar450 { top: max(10px, env(safe-area-inset-top)); max-height: calc(100dvh - 20px); }
  body.b514 .bar450-btn { flex: 0 1 auto; min-height: 0; }
}
body.b508fi.b514 .bar450 { top: max(10px, env(safe-area-inset-top)); max-height: calc(100dvh - 20px); }
body.b508fi.b514 .bar450-btn { flex: 0 1 auto; min-height: 0; }

/* ============================================================
   BUILD 402, item 6 (gate Features:Check518): on the
   appointment Edit form a SELECTED SERVICE wears a pale
   format while the selected time is bright (owner,
   Nov 10, 2026, on his screenshot of the form).

   Why they differed (measured on BUILD 401): the base
   component rule (.pill-btn.sel) paints the bright
   selected yellow for every pill, but BUILD 385's Salon
   Button migration dress (the b470 block: body.b470
   .pill-btn:not(.time-btn):not(.status-btn)) repaints
   every non-time pill in the component's cream BASE
   face at higher specificity — selected state
   included. The time pills are carved out of that
   dress, so a picked time keeps the bright yellow
   while a picked service (cream gradient #fffaf1 ->
   #fbeed9, gold border, deep-red ink) reads unpicked
   next to it.

   The fix puts the page's two choice groups on the
   shared Salon Button component's own picked face,
   by construction: while this gate shows, the Edit
   form carries .edit518 (rendered only then) and ONE
   rule dresses BOTH the service pills (.svc-grid) and
   the time pills (.time-cols) in the component's
   picked-choice treatment — the .sbtn-gold face of
   BUILD 384, declaration for declaration, the same
   restatement the Payment page's selected pills wear
   under .paypage469. A picked service and the picked
   time are the same treatment because they are the
   same rule. (The picked time's own dress therefore
   moves from the flat selected yellow to the
   component gold under this gate — both groups move
   together; that is the owner's Nov 10, 2026 standing
   directive: button components, one format for all.)
   Only the fill, border color, text color and shadow
   are set — each pill keeps its own size, radius and
   coin. The form's other pill rows (kind, length,
   status, arrange) are untouched, as are unpicked
   pills everywhere. Gate off: no .edit518 renders
   and no rule below can match — the file's effect is
   BUILD 401's exactly.
   ============================================================ */
body .edit518 .svc-grid .pill-btn.sel,
body .edit518 .time-cols .pill-btn.sel {
    background: linear-gradient(180deg, #ffd873, #f0b23e);
    color: #43300a; border-color: #b98a2f;
    box-shadow: 0 6px 16px rgba(217, 164, 41, .4), inset 0 1px 0 rgba(255, 255, 255, .6);
}

/* ============================================================
   BUILD 404, item 1 (gate Features:Check520): on the
   same Edit form the SELECTED TYPE pill (Regular
   appointment / Walk-in) and the SELECTED DURATION
   pills (15 min – 2 hours) read wrong (owner,
   Nov 10, 2026, on his screenshot of the form:
   "These buttons must have be the same component.
   selected buttons are wrong").

   Why they differ (measured on BUILD 403): both
   groups are the form's own .pill-btn with the same
   .sel picked marker as the services and the times,
   but they are neither .svc-grid nor .time-cols, so
   BUILD 402's f518 dress never reaches them. BUILD
   385's Salon Button migration dress (the b470
   block: body.b470 .pill-btn:not(.time-btn)
   :not(.status-btn)) repaints them in the
   component's cream BASE face at higher specificity
   than the base .pill-btn.sel rule — picked state
   included — so a picked Type or Duration pill
   wears the unpicked cream face, with only the
   base rule's yellow glow shadow (0 4px 14px
   rgba(230,207,30,.45)) left to say it is picked.

   The fix completes the form's one-component
   treatment: while this gate shows, the Edit form
   carries .edit520 alongside .edit518 (each
   rendered only while its gate shows) and ONE rule
   dresses BOTH remaining choice groups — the kind
   pills (#kindBtns) and the length pills (#lenBtns)
   — in the component's picked-choice treatment,
   the .sbtn-gold face of BUILD 384, declaration for
   declaration, exactly as f518 dresses the service
   and time pills. A picked Type and a picked
   Duration are the same treatment as a picked
   service and the picked time because they are the
   same declarations. Only the fill, border color,
   text color and shadow are set — each pill keeps
   its own size and radius. The form's other pill
   rows (status, arrange) are untouched, as are
   unpicked pills everywhere. Gate off: no .edit520
   renders and no rule below can match — the file's
   effect is BUILD 403's exactly.
   ============================================================ */
body .edit520 #kindBtns .pill-btn.sel,
body .edit520 #lenBtns .pill-btn.sel {
    background: linear-gradient(180deg, #ffd873, #f0b23e);
    color: #43300a; border-color: #b98a2f;
    box-shadow: 0 6px 16px rgba(217, 164, 41, .4), inset 0 1px 0 rgba(255, 255, 255, .6);
}

/* ============================================================
   BUILD 405, item 1 (gate Features:Check521): on the
   same Edit form the SELECTED ARRANGE pill (Both
   together / Each its own time) reads wrong (owner,
   Nov 10, 2026, on his screenshot of the form:
   "Selected buttons not formatted correctly").

   Why it differs (measured on BUILD 404): the
   arrange-mode pills are the form's own .pill-btn
   with the same .sel picked marker as every other
   choice group, but they sit in #arrangeModeBtns —
   neither .svc-grid nor .time-cols (f518) nor
   #kindBtns / #lenBtns (f520) — so no component
   picked-face rule ever reaches them. BUILD 385's
   Salon Button migration dress (the b470 block:
   body.b470 .pill-btn:not(.time-btn)
   :not(.status-btn)) repaints them in the
   component's cream BASE face at higher specificity
   than the base .pill-btn.sel rule — picked state
   included — so a picked Arrange pill wears the
   unpicked cream face, with only the base rule's
   yellow glow shadow (0 4px 14px
   rgba(230,207,30,.45)) left to say it is picked.

   The fix completes the form's one-component
   treatment: while this gate shows, the Edit form
   carries .edit521 alongside .edit518 and .edit520
   (each rendered only while its gate shows) and
   ONE rule dresses the arrange-mode pills
   (#arrangeModeBtns) in the component's
   picked-choice treatment, the .sbtn-gold face of
   BUILD 384, declaration for declaration, exactly
   as f518 dresses the service and time pills and
   f520 dresses the kind and length pills. A picked
   Arrange is the same treatment as a picked
   service, the picked time, a picked Type and a
   picked Duration because they are the same
   declarations. Only the fill, border color, text
   color and shadow are set — each pill keeps its
   own size and radius. The per-part pills inside
   #arrangeParts render the same markup family;
   they are untouched here, as are the form's
   status pills and unpicked pills everywhere.
   Gate off: no .edit521 renders and no rule below
   can match — the file's effect is BUILD 404's
   exactly.
   ============================================================ */
body .edit521 #arrangeModeBtns .pill-btn.sel {
    background: linear-gradient(180deg, #ffd873, #f0b23e);
    color: #43300a; border-color: #b98a2f;
    box-shadow: 0 6px 16px rgba(217, 164, 41, .4), inset 0 1px 0 rgba(255, 255, 255, .6);
}
