
/* ---- How you'd like to pay ----
   Three choices, stacked. Two fitted side by side; three across a 390px phone
   would give each option about 120px, which is not enough for a title and a
   line of explanation without one of them being unreadable. A stacked list
   reads the same at every width and leaves room for the description that
   actually tells the customer what each one means. */
.pay-when{display:grid;grid-template-columns:1fr;gap:.5rem;margin:0 0 .9rem}
.pw-opt{display:flex;flex-direction:column;gap:.2rem;text-align:left;width:100%;
  padding:.7rem .8rem;font:inherit;
  border:1px solid #d8ded7;border-radius:4px;background:#fff;cursor:pointer;transition:.15s}
.pw-opt:hover{border-color:#123526}
.pw-opt:focus-visible{outline:2px solid #123526;outline-offset:2px}
.pw-opt.is-on{border-color:#123526;background:#f3f7f3;box-shadow:inset 0 0 0 1px #123526}
.pw-t{font-weight:600;font-size:.9rem;color:#16241c}
.pw-d{font-size:.78rem;color:#6b7a70;line-height:1.35}
.tip-box{margin:0 0 1rem;padding:.8rem;border:1px solid #e6eae4;border-radius:4px;background:#fafbf9}
.tip-label{font-size:.82rem;font-weight:600;color:#16241c;margin-bottom:.5rem}
.tip-label span{font-weight:400;color:#8a978d}
.tip-opts{display:flex;flex-wrap:wrap;gap:.4rem}
.tip-opt{padding:.42rem .8rem;border:1px solid #d8ded7;border-radius:999px;background:#fff;
  font-size:.82rem;cursor:pointer;transition:.15s;color:#16241c}
.tip-opt:hover{border-color:#123526}
.tip-opt.is-on{background:#123526;border-color:#123526;color:#fff}
.tip-custom{display:flex;align-items:center;gap:.3rem;margin-top:.55rem}
.tip-custom span{color:#6b7a70}
.tip-custom input{width:100px;padding:.4rem .5rem;border:1px solid #d8ded7;border-radius:3px;font:inherit}
.pay-note{font-size:.8rem;color:#4d6156;background:#f3f7f3;border-left:2px solid #123526;
  padding:.6rem .75rem;margin:0 0 .9rem;line-height:1.45}

/* ---- Area-of-focus photos: was hidden and unexplained, so nobody used it ---- */
.photo-block{border:1px solid #d8ded7;border-radius:5px;padding:.9rem;background:#fafbf9}
.photo-why{font-size:.82rem;color:#4d6156;margin:.25rem 0 .7rem;line-height:1.45}
.photo-private{font-size:.75rem;color:#6b7a70;margin:.6rem 0 0;line-height:1.4}

/* The photo is a required field now, and it is validated the same way every
   other required field on this form is -- setCustomValidity + reportValidity
   on the input itself. style.css hides that input with display:none, and a
   browser will not show a validation bubble against something it cannot
   render, so the message never appeared. Kept invisible but still laid out,
   pinned to the top of the drop zone so the bubble points at the right thing. */
#bkPhotoField .photo-drop{position:relative}
#bkPhotoField .photo-drop input{display:block;position:absolute;top:0;left:50%;
  width:1px;height:1px;padding:0;border:0;opacity:0;pointer-events:none}

/* Said once on the payment step and again here: if storage refused the photos,
   the booking still stands and the customer is told how to send them. */
.bd-photo{font-size:.85rem;color:#4d6156;background:#f3f7f3;border-left:2px solid #123526;
  padding:.6rem .75rem;margin:0 0 .9rem;line-height:1.45;text-align:left}
.form-row-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:.6rem}
@media(max-width:520px){.form-row-3{grid-template-columns:1fr 1fr}
  .form-row-3 .form-field:last-child{grid-column:1 / -1}}

/* ---- Consent: deliberately plain, deliberately unmissable ---- */
.consent-block{border:1px solid #d8ded7;border-left:3px solid #123526;border-radius:4px;
  background:#fafbf9;padding:.85rem .9rem;margin:0 0 1rem}
.consent-row{display:flex;gap:.65rem;align-items:flex-start;cursor:pointer}
.consent-row input{width:22px;height:22px;flex:0 0 auto;margin-top:2px;accent-color:#123526}
.consent-row span{font-size:.82rem;line-height:1.5;color:#4d6156}
.consent-row strong{display:block;color:#16241c;margin-bottom:.2rem;font-size:.86rem}
.consent-block.missing{border-color:#c9635a;border-left-color:#c9635a;background:#fdf4f3}
/* The block rule above turns the lead-in into its own line, which is right for
   the heading and wrong for a sentence emphasised mid-paragraph. [eligibility-attestation-2026-08-15] */
.consent-row strong.inline{display:inline;margin:0;font-size:inherit;color:#16241c}

/* ---- The full terms, folded away [consent-fold-2026-08-20] ----
   Quiet on purpose. This is the opposite of the checkbox above it: the box is
   the thing to notice, and this is here for the man who wants all of it before
   he agrees. Styled as a plain underlined line rather than a button, because a
   button competes with Pay and this must not. */
.consent-more{margin:.7rem 0 0;border-top:1px solid #e7ebe6;padding-top:.6rem}
.consent-more summary{font-size:.78rem;color:#4d6156;cursor:pointer;
  text-decoration:underline;text-underline-offset:3px;list-style:none}
.consent-more summary::-webkit-details-marker{display:none}
.consent-more summary::after{content:" ↓";text-decoration:none;display:inline-block}
.consent-more[open] summary::after{content:" ↑"}
.consent-more summary:hover{color:#16241c}
.consent-more summary:focus-visible{outline:2px solid #8a6f3f;outline-offset:2px}
.consent-full{margin-top:.55rem}
.consent-full p{margin:0 0 .5rem;font-size:.78rem;line-height:1.55;color:#4d6156}
.consent-full p:last-child{margin-bottom:0}
.consent-full strong{color:#16241c}

/* ---- The three baths, stated in the page [static-menu-2026-08-20] ----
   Deliberately plain. This section exists so a crawler, an AI assistant and a
   man skimming on a phone all get the same answer to "what do you offer and
   what does it cost" without running a line of JavaScript. Styled as readable
   prose rather than a pricing table: prose is what gets quoted back. */
#menu{padding:3.2rem 0}
#menu .section-head{margin-bottom:1.8rem}
.menu-list{display:grid;gap:1rem;grid-template-columns:1fr}
.menu-item{border:1px solid #d8ded7;border-left:3px solid #8a6f3f;border-radius:4px;
  background:#fcfbf7;padding:1.1rem 1.2rem}
.menu-item h3{margin:0 0 .3rem;font-size:1.12rem;color:#123526;letter-spacing:.01em}
.menu-meta{margin:0 0 .55rem;font-size:.95rem;color:#16241c;line-height:1.7}
.menu-meta strong{font-size:1.2rem;color:#123526}
/* The list price, struck through and quiet — present so the discount is
   provable rather than asserted, but never competing with what he pays. */
.menu-was{font-size:.82rem;color:#8a9a90;text-decoration:line-through;margin-left:.3rem}
.menu-off{display:inline-block;font-size:.62rem;letter-spacing:.1em;text-transform:uppercase;
  background:#8a6f3f;color:#fff;border-radius:2px;padding:.18rem .4rem;margin-left:.35rem;
  vertical-align:.1em;font-weight:600}
.menu-dur{display:block;font-size:.82rem;color:#7d8f84;margin-top:.15rem}
.menu-blurb{margin:0 0 .55rem;font-size:.92rem;line-height:1.6;color:#4d6156}
.menu-inc{margin:0;font-size:.85rem;line-height:1.6;color:#4d6156}
.menu-inc-label{display:inline-block;font-size:.7rem;letter-spacing:.12em;
  text-transform:uppercase;color:#8a6f3f;margin-right:.35rem}
.menu-pending{font-size:.95rem;line-height:1.6;color:#4d6156;margin:0}

/* What can be added to a bath. A plain list, because a man wondering whether
   you even offer a shave should find that out in one glance. */
.menu-addons{margin:1.6rem 0 0;border-top:1px solid #e7ebe6;padding-top:1.4rem}
.menu-addons h3{margin:0 0 .4rem;font-size:1.05rem;color:#123526}
.menu-addons > p{margin:0 0 .9rem;font-size:.88rem;line-height:1.6;color:#4d6156}
.addon-list{list-style:none;margin:0;padding:0;display:grid;gap:.1rem;grid-template-columns:1fr}
.addon-list li{display:flex;align-items:baseline;gap:.5rem;padding:.42rem 0;
  border-bottom:1px solid #eef1ec;font-size:.9rem}
.addon-list li:last-child{border-bottom:0}
.addon-name{color:#16241c}
.addon-price{margin-left:auto;color:#123526;font-weight:600;white-space:nowrap}
.addon-exempt{flex:0 0 auto;font-size:.62rem;letter-spacing:.08em;text-transform:uppercase;
  color:#8a6f3f;white-space:nowrap}

@media (min-width:820px){
  .addon-list{grid-template-columns:1fr 1fr;column-gap:2.2rem}
}
.menu-foot{margin:1.5rem 0 0;font-size:.9rem;line-height:1.7;color:#4d6156}

@media (min-width:820px){
  .menu-list{grid-template-columns:repeat(3,1fr);gap:1.1rem}
  .menu-item{padding:1.3rem 1.3rem}
}

/* ---- The week of open times [week-view-2026-08-20] ----
   A row of days that scrolls sideways on a phone and fits whole on a desktop.
   Scroll-snap so a swipe lands on a day rather than halfway between two, and
   the day columns keep a minimum width so a Saturday with six times open does
   not squeeze the rest into slivers. */
.wk{margin:0 0 1rem}
.wk-head{display:flex;align-items:center;justify-content:space-between;gap:.5rem;margin:0 0 .6rem}
.wk-range{font-size:.9rem;color:#16241c;font-weight:600;text-align:center;flex:1}
.wk-nav{width:38px;height:38px;flex:0 0 auto;border:1px solid #d8ded7;background:#fff;border-radius:4px;
  font-size:1.1rem;line-height:1;color:#123526;cursor:pointer}
.wk-nav:hover:not(:disabled){border-color:#123526}
.wk-nav:disabled{opacity:.32;cursor:default}
.wk-strip{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(92px,1fr);gap:.4rem;
  overflow-x:auto;scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;
  padding:0 0 .4rem;scrollbar-width:thin}
.wk-day{scroll-snap-align:start;border:1px solid #e2e7e0;border-radius:6px;background:#fff;
  padding:.5rem .35rem;min-height:120px}
.wk-day.empty{background:#f7f8f6}
.wk-dh{text-align:center;padding:0 0 .45rem;border-bottom:1px solid #eef1ec;margin:0 0 .45rem}
.wk-dn{display:block;font-size:.68rem;letter-spacing:.1em;text-transform:uppercase;color:#8a9a90}
.wk-dd{display:block;font-size:1.05rem;color:#16241c;font-weight:600;margin-top:1px}

/* [week-sunday-2026-08-20] Today has to be found, not assumed.
   While the strip began on today, the first column WAS today and a border was
   enough. Now that it runs Sunday to Saturday, today sits anywhere in the row
   and has to be picked out at a glance — so it gets a tinted header, a filled
   date, and the word Today under it. Colour is not carrying this on its own:
   the label is there for anyone who cannot separate the two greens. */
.wk-day.today{border-color:#123526;box-shadow:inset 0 0 0 1px #123526}
.wk-day.today .wk-dh{border-bottom-color:#123526}
.wk-day.today .wk-dn{color:#123526;font-weight:600}
.wk-day.today .wk-dd{background:#123526;color:#fff;border-radius:999px;
  width:1.7em;height:1.7em;line-height:1.7em;margin:1px auto 0}
.wk-today-tag{display:block;font-size:.56rem;letter-spacing:.1em;text-transform:uppercase;
  color:#123526;font-weight:600;margin-top:3px}
.wk-slots{display:flex;flex-direction:column;gap:.3rem}
/* [tap-target-2026-09-02] min-height:44px, and it is not decoration.
   Every booking and every reschedule in this business passes through one of
   these buttons, and at .5rem of padding round a .78rem label the box came out
   around 32px tall — under the 44px WCAG 2.1 asks for and well under what an
   older or unsteady hand can hit first time. The strip scroll-snaps on
   .wk-strip and .wk-day, never on the slot, so a taller slot only makes the
   day column taller and nothing about the swipe changes. Centred with flex
   because the height no longer comes from the padding. */
.wk-slot{width:100%;min-height:44px;display:flex;flex-direction:column;align-items:center;
  justify-content:center;border:1px solid #cfd8d1;background:#fff;border-radius:4px;padding:.5rem .25rem;
  font-size:.78rem;color:#16241c;cursor:pointer;font-family:inherit;line-height:1.2;text-align:center}
.wk-slot:hover{border-color:#123526;background:#f6f9f6}
.wk-slot.selected{background:#123526;border-color:#123526;color:#fff}
.wk-slot.soon{border-style:dashed}
.wk-soon{display:block;font-size:.58rem;letter-spacing:.08em;text-transform:uppercase;color:#8a6f3f;margin-top:2px}
.wk-slot.selected .wk-soon{color:#d8c9a4}
.wk-none{display:block;text-align:center;color:#b3bdb6;font-size:.9rem;padding:.5rem 0}
.wk-loading{padding:1.4rem .5rem;text-align:center;color:#7d8f84;font-size:.85rem;grid-column:1/-1}
.wk-hint{margin:.5rem 0 0;font-size:.8rem;line-height:1.5;color:#4d6156}

/* The date input, demoted to a way of reaching a date a long way off. */
.wk-jump{margin:0 0 1rem;border-top:1px solid #e7ebe6;padding-top:.6rem}
.wk-jump summary{font-size:.78rem;color:#4d6156;cursor:pointer;text-decoration:underline;
  text-underline-offset:3px;list-style:none}
.wk-jump summary::-webkit-details-marker{display:none}
.wk-jump summary:hover{color:#16241c}
.wk-jump .form-field{margin-top:.55rem}

@media (min-width:640px){
  .wk-strip{grid-auto-columns:1fr;overflow-x:visible}
  .wk-slot{font-size:.82rem}
}

/* ---- Eligibility: the standard, stated before the box that refers to it ---- */
.eligibility-block{border:1px solid #d8ded7;border-left:3px solid #8a6f3f;border-radius:4px;
  background:#fcfbf7;padding:.85rem .9rem;margin:0 0 .6rem}
.eligibility-block .elig-title{margin:0 0 .35rem;font-size:.86rem;color:#16241c}
.eligibility-block .elig-body{margin:0 0 .45rem;font-size:.82rem;line-height:1.5;color:#4d6156}
.eligibility-block .elig-body:last-child{margin-bottom:0}

/* ---- The waiting list, offered when a time can't be had ----
   Deliberately quiet. Nobody wants a cheerful box after being told no, and
   the men this is for already found it hard to ask once. Plain green rule,
   plain type, one thing to press. */
.waitlist-offer{margin-top:1rem;padding:1rem 1.05rem;background:#fafbf9;
  border:1px solid #d8ded7;border-left:3px solid #123526;border-radius:4px}
.waitlist-offer h3{margin:0 0 .45rem;font-size:.98rem;color:#16241c}
.waitlist-offer p{margin:0 0 .7rem;font-size:.85rem;line-height:1.55;color:#4d6156}
.waitlist-offer .wl-when strong{color:#16241c}
.wl-flex{display:flex;gap:.6rem;align-items:flex-start;margin:0 0 .85rem;cursor:pointer}
.wl-flex input{width:20px;height:20px;flex:0 0 auto;margin-top:1px;accent-color:#123526}
.wl-flex span{font-size:.82rem;line-height:1.5;color:#4d6156}
.waitlist-offer .btn{width:100%}
.wl-note{margin:.7rem 0 0!important;font-size:.78rem;color:#6b7a70}
.wl-done{margin-top:.9rem;padding:.75rem .85rem;border-radius:3px;font-size:.85rem;
  line-height:1.55;background:rgba(76,144,96,.08);border-left:2px solid #4c9060;color:#235c37}
.wl-done.err{background:rgba(201,99,90,.08);border-left-color:#c9635a;color:#8f3d33}
.wl-done strong{display:block;margin-bottom:.25rem}

/* ---- Short-notice times: offered, and honest about needing confirming ---- */
.slot-btn.soon{border-style:dashed}
.slot-soon{display:block;font-size:.6rem;letter-spacing:.06em;text-transform:uppercase;
  color:#82602c;margin-top:1px}
.slot-btn.soon.selected .slot-soon{color:#e8d5ae}
.short-notice-note{margin:.7rem 0 0;padding:.65rem .75rem;border-left:2px solid #c8a55b;
  background:#fdf9f0;font-size:.82rem;line-height:1.5;color:#6b5a2e}
