/* ===========================================================================
   portal.css — the client portal's own layer. [client-portal-2026-08-23]

   Loaded AFTER css/style.css (the design system: :root tokens, Cinzel and
   Montserrat, .btn, .form-field, .svc-card) and AFTER css/site.css (the
   booking-wizard layer: the week strip, .pay-when, .consent-block).

   NOTHING HERE RESTATES SOMETHING THOSE TWO ALREADY DO. Roughly sixty classes
   are reused as they stand. What is below is the nine things that genuinely do
   not exist yet, about thirty lines of pattern lifted out of the staff app's
   admin.css (which is NOT served to clients and must not become a link on a
   customer's page), and three fixes to rules that fail WCAG 2.1 AA today.

   Every foreground/background pair used here was checked against the real hex
   values in style.css. The ratios are written beside the rules that use them.
   =========================================================================== */

:root {
  /* NEW. The smallest gold text — 0.62rem to 0.72rem labels, the price rail,
     the reveal control — where --gold-deep's 5.08:1 on --bg-soft is closer to
     the line than a 12px uppercase label should ever be.
       #6F5222 on --bg      #FCFAF6   6.94:1
       #6F5222 on --bg-soft #F4F1E8   6.40:1
       #6F5222 on --surface #FFFFFF   7.23:1
     Note --gold #B68A45 is 3.00:1 on --bg and is therefore DECORATION ONLY in
     this portal: rules, borders, badge edges. It is never a glyph on cream.
     The staff app's #8C6A34 is deliberately not imported — it is 4.40:1 on
     --bg-soft and fails. */
  --gold-ink: #6F5222;

  /* 8.29:1 against --bg. style.css styles focus on form inputs and on nothing
     else, so every button and link on the public site is currently invisible
     when focused. The portal does not repeat that. */
  --focus: var(--green);

  --err-ink: #8F3D33;   /* 6.99:1 on --bg  */
  --ok-ink:  #235C37;   /* 7.58:1 on --bg  */

  --tabbar-h: 58px;
}

/* --------------------------------------------------------------------------
   1. Skip link. There is not one anywhere in public/ today (2.4.1).
   -------------------------------------------------------------------------- */
.skip { position: absolute; left: -9999px; }
.skip:focus {
  left: 10px; top: 10px; z-index: 100; background: var(--surface);
  border: 1px solid var(--green); color: var(--green);
  padding: 11px 16px; border-radius: var(--radius);
  font-family: "Montserrat", sans-serif; font-size: .8rem; font-weight: 600;
  letter-spacing: .09em; text-transform: uppercase;
}

/* --------------------------------------------------------------------------
   2. A visible focus ring on everything, not just inputs (2.4.7).
   -------------------------------------------------------------------------- */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible,
input[type="radio"]:focus-visible,
input[type="checkbox"]:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: 2px;
}
main:focus { outline: none; }

.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* --------------------------------------------------------------------------
   3. Three existing AA failures the portal must not inherit.

   site.css .wk-slot borders at 1.46:1 and .wk-dn day names at 2.96:1 are the
   booking slot buttons and the letters above them — the two things a man is
   actually aiming at. The placeholder is 4.21:1. All three are corrected here
   rather than in the shared files, so nothing on the public site moves.
   -------------------------------------------------------------------------- */
.portal .wk-slot { border-color: var(--line-strong); }        /* 3.20:1 */
.portal .wk-dn   { color: var(--grey); }                      /* 5.53:1 */
.portal .form-field input::placeholder { color: var(--grey); }/* 5.53:1 */
.portal .wk-none { color: var(--grey); }
.portal .wk-loading { color: var(--grey); }

/* --------------------------------------------------------------------------
   4. The tab bar.

   Three destinations, permanently on screen, at the bottom of the display
   where a thumb already is. Above 861px the same <nav>, in the same place in
   the source, flows into the header row instead — CSS only, no duplicate
   markup, nothing to keep in step.
   -------------------------------------------------------------------------- */
header.site.portal { position: sticky; top: 0; }
header.site.portal .row { gap: 12px; padding: 10px clamp(14px, 4.4vw, 28px); }
header.site.portal .brandmark { min-height: 44px; }
header.site.portal .brandmark img { height: clamp(24px, 6.2vw, 34px); }
header.site.portal .brandmark .wordmark {
  font-size: clamp(.72rem, 3.4vw, 1.05rem);
  letter-spacing: clamp(.06em, .35vw, .2em);
}
header.site.portal .call {
  min-height: 44px; padding: 0 clamp(12px, 3.4vw, 18px);
  margin-left: auto; white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 50; display: flex;
  background: var(--surface); border-top: 1px solid var(--line-strong);
  padding-bottom: env(safe-area-inset-bottom);
  box-shadow: 0 -10px 26px -22px rgba(30, 85, 64, .55);
}
.tab {
  flex: 1 1 0; min-height: var(--tabbar-h);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 4px; padding: 9px 4px;
  font-family: "Montserrat", sans-serif; font-size: .66rem; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--grey);                       /* 5.53:1 on --surface */
  -webkit-tap-highlight-color: transparent;
}
.tab svg {
  width: 22px; height: 22px; stroke: currentColor; fill: none;
  stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
}
/* Colour is not carrying this on its own: the current tab also gets a rule
   along its top edge. Same reasoning site.css gives for the "Today" column. */
.tab[aria-current="page"] {
  color: var(--green);                      /* 8.65:1 on --surface */
  box-shadow: inset 0 2px 0 var(--gold-ink);
}
.tab:hover { color: var(--green); }
.tab:focus-visible { outline: 2px solid var(--focus); outline-offset: -3px; }
.tab:active { background: rgba(30, 85, 64, .05); }

main.portal-main {
  max-width: 760px; margin: 0 auto;
  padding: 26px clamp(14px, 4.4vw, 28px) calc(var(--tabbar-h) + 26px + env(safe-area-inset-bottom));
}
main.portal-main.booking {
  padding-bottom: calc(var(--tabbar-h) + 70px + env(safe-area-inset-bottom));
}
/* No tab bar on the two pages outside the session. */
main.portal-main.plain { padding-bottom: 40px; max-width: 460px; }

@media (min-width: 861px) {
  .tabbar {
    position: static; background: none; border-top: 0; box-shadow: none;
    margin-left: 0; padding: 0; gap: 6px;
  }
  .tab {
    flex: 0 0 auto; min-height: 44px; flex-direction: row; gap: 8px;
    padding: 0 14px; font-size: .78rem; letter-spacing: .09em;
  }
  .tab svg { width: 17px; height: 17px; }
  .tab[aria-current="page"] { box-shadow: inset 0 -2px 0 var(--gold-ink); }
  main.portal-main,
  main.portal-main.booking { padding-bottom: 40px; }
}

/* At 320px, or at 200% text, the words go and the icons stay rather than the
   labels truncating into nonsense (1.4.4, 1.4.10). */
@media (max-width: 340px) {
  .tab span { display: none; }
  .tab { gap: 0; }
}

/* --------------------------------------------------------------------------
   5. Page furniture
   -------------------------------------------------------------------------- */
.portal-head { margin: 0 0 22px; }
.portal-head h1 { font-size: clamp(1.4rem, 5vw, 1.8rem); margin-bottom: .2em; }
.portal-head p { margin: 0; font-size: .92rem; }

.back-link {
  display: inline-flex; align-items: center; min-height: 44px; gap: 6px;
  font-family: "Montserrat", sans-serif; font-size: .74rem; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase; color: var(--green);
}
.back-link:hover { color: var(--gold-deep); }

/* Upcoming / Past. Two words, not a third layer of navigation. */
.seg { display: flex; gap: 4px; margin: 0 0 18px; border-bottom: 1px solid var(--line); }
.seg button {
  min-height: 44px; padding: 0 14px; border: 0; background: none; cursor: pointer;
  font-family: "Montserrat", sans-serif; font-size: .74rem; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase; color: var(--grey);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.seg button[aria-selected="true"] { color: var(--green); border-bottom-color: var(--gold-deep); }
.seg button:hover { color: var(--gold-deep); }

/* --------------------------------------------------------------------------
   6. The visit card. .hist-row in the staff app is close and is the wrong
   colour, and it has no date block — which is the thing he opened the page to
   find, so it is the thing on the left where the eye lands.
   -------------------------------------------------------------------------- */
.visit-list { display: flex; flex-direction: column; gap: 12px; }
.visit-card {
  display: block; width: 100%; text-align: left;
  background: var(--surface); border: 1px solid var(--line-strong);
  border-radius: var(--radius); padding: 14px 16px;
  box-shadow: var(--shadow-card); cursor: pointer; font: inherit; color: inherit;
  transition: border-color .15s, box-shadow .15s;
}
.visit-card:hover { border-color: var(--green); box-shadow: var(--shadow-lift); }
.visit-card:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
/* The top of the card is one link — a 100px target, and the whole of it. The
   veil below it is a <details>, which cannot live inside a link or a button,
   so the two are siblings rather than nested. */
a.vc-top {
  display: flex; align-items: flex-start; gap: 14px;
  color: inherit; text-decoration: none;
}
a.vc-top:focus-visible { outline: 2px solid var(--focus); outline-offset: 4px; }
.vc-date {
  flex: 0 0 auto; text-align: center; min-width: 56px;
  border-right: 1px solid var(--line); padding-right: 14px;
}
.vc-dow {
  display: block; font-size: .66rem; font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; color: var(--grey);          /* 5.53:1 */
}
.vc-day {
  display: block; font-family: "Cinzel", Georgia, serif; font-size: 1.6rem;
  line-height: 1.1; color: var(--green);                  /* 8.65:1 */
}
.vc-mon {
  display: block; font-size: .66rem; font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; color: var(--grey);
}
.vc-body { flex: 1 1 auto; min-width: 0; }
.vc-when {
  font-weight: 600; font-size: 1rem; color: var(--ink);   /* 15.49:1 */
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px;
}
.vc-mins { font-weight: 400; font-size: .82rem; color: var(--grey); }
.vc-where { font-size: .84rem; color: var(--grey); margin-top: 2px; }
.vc-foot { margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--line); }

/* --------------------------------------------------------------------------
   7. Status badges — the pattern from admin.css, copied rather than linked.
   The client bundle must not carry the staff stylesheet.
   Every badge says its state in a word, so no meaning rests on colour alone.
   -------------------------------------------------------------------------- */
.badge {
  display: inline-block; padding: 3px 9px; border-radius: 999px;
  font-family: "Montserrat", sans-serif; font-size: .62rem; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; white-space: nowrap;
  background: var(--bg-soft); border: 1px solid var(--line-strong);
  color: var(--ink);                                       /* 13.71:1 */
}
.badge.confirmed  { color: var(--green);    border-color: var(--green); }    /* 7.66:1 */
.badge.requested  { color: var(--gold-ink); border-color: var(--gold); }     /* 6.40:1 */
.badge.en_route   { color: var(--green);    border-color: var(--green); }
.badge.completed  { color: var(--grey);     border-color: var(--line-strong); }
.badge.cancelled  { color: var(--err-ink);  border-color: #c9635a; }         /* 6.5:1  */
.badge.no_show    { color: var(--err-ink);  border-color: #c9635a; }

/* --------------------------------------------------------------------------
   8. Detail rows and totals — also from admin.css, also copied.
   -------------------------------------------------------------------------- */
.panel {
  background: var(--surface); border: 1px solid var(--line-strong);
  border-radius: var(--radius); padding: 18px; margin: 0 0 16px;
  box-shadow: var(--shadow-card);
}
.panel > h2 {
  font-family: "Montserrat", sans-serif; font-size: .78rem; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; color: var(--gold-deep);  /* 5.74:1 */
  margin: 0 0 12px;
}
.dl-row {
  display: flex; justify-content: space-between; align-items: baseline; gap: 14px;
  padding: 8px 0; border-bottom: 1px solid var(--line); font-size: .9rem;
}
.dl-row:last-child { border-bottom: 0; }
.dl-k { color: var(--grey); flex: 1 1 auto; min-width: 0; }                   /* 5.53:1 */
.dl-v { color: var(--ink); text-align: right; white-space: nowrap; }          /* 15.49:1 */
.dl-row.included .dl-k { padding-left: 14px; position: relative; }
.dl-row.included .dl-k::before { content: "·"; position: absolute; left: 4px; }
.dl-row.included .dl-v { color: var(--grey); }
.dl-row.grand { border-top: 1px solid var(--line-strong); border-bottom: 0; padding-top: 12px; }
.dl-row.grand .dl-k,
.dl-row.grand .dl-v {
  font-weight: 700; font-size: 1.05rem; color: var(--gold-deep);              /* 5.74:1 */
}

.empty-state {
  text-align: center; padding: 28px 18px;
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  background: var(--bg-soft);
}
.empty-state img { height: 40px; margin: 0 0 14px; background: var(--green-deep);
  border: 1px solid rgba(182, 138, 69, .45); border-radius: 2px; }
.empty-state p { color: var(--ink-soft); font-size: .94rem; }                 /* 6.44:1 */
.empty-state .btn { margin-top: 6px; }

/* --------------------------------------------------------------------------
   9. The veil.

   What he came for is WHEN and WHERE. What would embarrass him is WHAT. Those
   are separable, so they are separated: the itemised list is behind one tap.

   <details> because it is native, needs no JavaScript, is announced correctly,
   cannot trap focus, and is the element site.css already chose for
   .consent-more and .wk-jump with a comment saying why.
   -------------------------------------------------------------------------- */
.veil { border-top: 0; }
.veil > summary {
  list-style: none; display: flex; align-items: center; justify-content: space-between;
  gap: 12px; min-height: 44px; cursor: pointer; font-size: .88rem; color: var(--ink);
}
.veil > summary::-webkit-details-marker { display: none; }
.veil-count { color: var(--ink); }
.veil-do {
  flex: 0 0 auto; font-size: .7rem; font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: var(--gold-ink);                          /* 6.94:1 */
}
/* The word is REAL TEXT, not generated content: ::before is not reliably
   announced, and "Show" is the only instruction on the control. Only the
   triangle is generated, and it is decoration. */
.vd-hide { display: none; }
.veil[open] .vd-show { display: none; }
.veil[open] .vd-hide { display: inline; }
.veil-do::after { content: " \25B8"; }
.veil[open] .veil-do::after { content: " \25BE"; }
.veil > summary:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.veil-body { padding-top: 4px; }

/* --------------------------------------------------------------------------
   10. The sheet. A portal-side copy of the .upsell primitive from style.css,
   anchored to the bottom of the screen on a phone. Same height capping, same
   overscroll containment, same sticky actions.
   -------------------------------------------------------------------------- */
.sheet {
  position: fixed; inset: 0; z-index: 60; display: flex;
  align-items: flex-end; justify-content: center;
  background: rgba(7, 19, 15, .55);
  overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain;
}
.sheet[hidden] { display: none; }
.sheet-card {
  width: 100%; max-width: 460px; background: var(--surface);
  border: 1px solid var(--line); border-top: 2px solid var(--gold);
  border-radius: var(--radius) var(--radius) 0 0;
  padding: 24px 22px 20px;
  box-shadow: 0 -24px 60px -30px rgba(7, 19, 15, .7);
  max-height: calc(100vh - 40px); max-height: calc(100svh - 40px);
  overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain;
  animation: sheet-in .22s ease;
}
@keyframes sheet-in { from { transform: translateY(14px); opacity: 0; } to { transform: none; opacity: 1; } }
.sheet-card h2 {
  font-size: 1.15rem; text-transform: none; letter-spacing: .03em;
  margin-bottom: .5em; outline: none;
}
.sheet-card p { font-size: .92rem; }
.sheet-acts {
  display: flex; flex-direction: column; gap: 10px;
  position: sticky; bottom: 0; z-index: 1;
  margin: 16px -22px -20px; padding: 14px 22px 20px;
  padding-bottom: calc(20px + env(safe-area-inset-bottom));
  background: var(--surface); border-top: 1px solid var(--line);
}
.sheet-acts .btn { width: 100%; min-height: 50px; }
/* Destructive on the far side of a gap and never above the quiet way out. */
.btn.danger { border-color: #b2503d; color: #a1442f; }                        /* 5.4:1 */
.btn.danger:hover { background: rgba(178, 80, 61, .08); }
.btn.solid.danger { background: #9c3f2c; border-color: #9c3f2c; color: #fff; } /* 6.5:1 */
.btn.solid.danger:hover { background: #8a3624; }
.btn.block { width: 100%; }
.btn.tall { min-height: 50px; }

@media (min-width: 620px) {
  .sheet { align-items: center; padding: 24px; }
  .sheet-card { border-radius: var(--radius); border-top-width: 2px; }
}

/* --------------------------------------------------------------------------
   11. The toast. There is nothing like it anywhere in this repo, and "Card
   removed" / "Visit moved" have to be said out loud somewhere.
   -------------------------------------------------------------------------- */
.toast-rail {
  position: fixed; left: 0; right: 0; z-index: 70;
  bottom: calc(var(--tabbar-h) + 10px + env(safe-area-inset-bottom));
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 0 14px; pointer-events: none;
}
.toast {
  pointer-events: auto; max-width: 460px; width: 100%;
  background: var(--green); color: #fff;                                      /* 8.65:1 */
  border-radius: var(--radius); padding: 12px 14px;
  font-size: .88rem; line-height: 1.5;
  box-shadow: 0 14px 30px -18px rgba(7, 19, 15, .8);
  display: flex; align-items: flex-start; gap: 12px;
  animation: toast-in .2s ease;
}
.toast.err { background: #8a3624; }                                           /* 8.2:1 */
.toast button {
  flex: 0 0 auto; border: 0; background: none; color: inherit; cursor: pointer;
  font-size: 1rem; line-height: 1; padding: 2px 4px; opacity: .8;
}
.toast button:hover { opacity: 1; }
@keyframes toast-in { from { transform: translateY(8px); opacity: 0; } to { transform: none; opacity: 1; } }
@media (min-width: 861px) { .toast-rail { bottom: 18px; } }

/* --------------------------------------------------------------------------
   12. The running total during booking.
   -------------------------------------------------------------------------- */
.price-rail {
  position: fixed; left: 0; right: 0; z-index: 45;
  bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom));
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 11px clamp(14px, 4.4vw, 28px);
  background: var(--bg-soft); border-top: 1px solid var(--line-strong);
  font-size: .86rem; font-weight: 600; color: var(--ink);                      /* 13.71:1 */
}
.price-rail[hidden] { display: none; }
.pr-what {
  color: var(--grey); font-size: .78rem; min-width: 0; font-weight: 400;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pr-amt {
  font-size: 1.05rem; color: var(--gold-ink); white-space: nowrap;             /* 6.40:1 */
}
@media (min-width: 861px) {
  .price-rail {
    position: static; max-width: 760px; margin: 24px auto 0;
    border: 1px solid var(--line-strong); border-radius: var(--radius);
  }
}

/* --------------------------------------------------------------------------
   13. Booking: the bath cards stacked, the add-ons as plain rows.

   Three cards across 390px gives 120px each. site.css already makes exactly
   this argument about .pay-when, and it is the same argument here.
   -------------------------------------------------------------------------- */
.stacked-grid { display: grid; grid-template-columns: 1fr; gap: 12px; }

.shortcut {
  display: block; width: 100%; text-align: left; font: inherit; color: inherit;
  min-height: 64px; padding: 16px; cursor: pointer;
  background: var(--bg-soft); border: 1px solid var(--green);
  border-left: 3px solid var(--gold-deep); border-radius: var(--radius);
}
.shortcut:hover { background: rgba(30, 85, 64, .06); }
.shortcut .sc-label {
  display: block; font-size: .66rem; font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--gold-ink); margin-bottom: 4px;       /* 6.40:1 */
}
.shortcut .sc-what { display: block; font-weight: 600; color: var(--ink); }
.shortcut .sc-meta { display: block; font-size: .82rem; color: var(--grey); margin-top: 2px; }

.or-rule {
  display: flex; align-items: center; gap: 12px; margin: 20px 0;
  font-size: .72rem; font-weight: 600; letter-spacing: .16em;
  text-transform: uppercase; color: var(--grey);
}
.or-rule::before, .or-rule::after {
  content: ""; flex: 1 1 auto; height: 1px; background: var(--line-strong);
}

.addon-list-p { list-style: none; margin: 0; padding: 0; }
.addon-list-p li { border-bottom: 1px solid var(--line); }
.addon-list-p li:last-child { border-bottom: 0; }
.addon-row {
  display: flex; align-items: center; gap: 12px; min-height: 52px;
  padding: 6px 2px; cursor: pointer;
}
.addon-row input[type="checkbox"] {
  width: 24px; height: 24px; flex: 0 0 auto; margin: 0; accent-color: var(--green); cursor: pointer;
}
.addon-row .ar-name { flex: 1 1 auto; font-size: .94rem; color: var(--ink); }
.addon-row .ar-price {
  flex: 0 0 auto; font-weight: 700; color: var(--gold-deep); white-space: nowrap; /* 5.74:1 */
}
.addon-row .ar-was {
  color: var(--grey); font-weight: 400; text-decoration: line-through; margin-right: 5px;
}

.step-crumb {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: 10px; margin: 0 0 18px; padding: 12px 0;
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
.step-crumb strong { font-family: "Cinzel", Georgia, serif; color: var(--green); letter-spacing: .04em; }
.step-crumb button {
  border: 0; background: none; cursor: pointer; min-height: 44px; padding: 0 2px;
  font-family: "Montserrat", sans-serif; font-size: .7rem; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase; color: var(--gold-ink);      /* 6.94:1 */
}
.step-crumb button:hover { color: var(--green); }

/* --------------------------------------------------------------------------
   14. Sign in and reset
   -------------------------------------------------------------------------- */
.auth-crest { text-align: center; margin: 8px 0 22px; }
.auth-crest img {
  height: 46px; background: var(--green-deep);
  border: 1px solid rgba(182, 138, 69, .45); border-radius: 2px;
}
.auth-crest .wordmark {
  display: block; margin-top: 10px; font-family: "Cinzel", serif;
  font-size: .95rem; font-weight: 600; letter-spacing: .24em; color: var(--green);
}
.code-input {
  font-family: "Montserrat", sans-serif; font-size: 1.5rem !important;
  letter-spacing: .38em; text-align: center; font-variant-numeric: tabular-nums;
}
/* Sign in is an ordinary sign-in form: both fields on the screen, nothing
   folded away behind a disclosure. What used to be an .auth-alt <details> is
   now the plain second button under the .or-rule, which is .btn.block.tall and
   needs no rule of its own. These three are the small print around it. */
.auth-forgot { margin: -4px 0 0; font-size: .88rem; }
.auth-forgot a { font-weight: 600; text-decoration: underline; }

/* The signup line, at the weight a signup line has on any other website: a
   sentence a man reads, with the words he is looking for underlined in it. */
.auth-new {
  margin: 20px 0 0; text-align: center; font-size: .92rem;
  color: var(--ink-soft);                                                       /* 6.44:1 */
}
.auth-new .linkish { font-weight: 600; }

/* Standing guidance, printed for everybody and never the result of a lookup.
   See the note at the top of signin.js. */
.auth-note {
  margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line);
  line-height: 1.65;
}
.auth-note a { font-weight: 600; text-decoration: underline; }
.auth-foot {
  margin-top: 24px; text-align: center; font-size: .88rem; color: var(--grey);
  line-height: 2;
}
.auth-foot a { font-weight: 600; }
.linkish {
  border: 0; background: none; padding: 0; cursor: pointer; font: inherit;
  color: var(--green); text-decoration: underline; min-height: 44px;
}
.linkish:hover { color: var(--gold-deep); }
.linkish[disabled] { color: var(--grey); text-decoration: none; cursor: default; }

/* --------------------------------------------------------------------------
   15. Account
   -------------------------------------------------------------------------- */
.card-row {
  display: flex; align-items: center; gap: 12px; padding: 12px 0;
  border-bottom: 1px solid var(--line);
}
.card-row:last-of-type { border-bottom: 0; }
.card-row .cr-what { flex: 1 1 auto; min-width: 0; }
.card-row .cr-brand { font-weight: 600; color: var(--ink); text-transform: capitalize; }
.card-row .cr-exp { font-size: .8rem; color: var(--grey); }
/* .btn.small is 31px tall in style.css, which is right on a desktop toolbar and
   wrong next to a man's card details on a phone. 2.5.5 applies at every width in
   this portal, so Remove is brought up to the same 44px as everything else. */
.card-row .btn.small { min-height: 44px; padding: 0 16px; flex: 0 0 auto; }
.switch-row {
  display: flex; align-items: flex-start; gap: 12px; min-height: 44px;
  cursor: pointer; padding: 6px 0;
}
.switch-row input { width: 22px; height: 22px; flex: 0 0 auto; margin-top: 2px; accent-color: var(--green); }
.switch-row span { font-size: .9rem; line-height: 1.5; color: var(--ink); }
.switch-row .sr-note { display: block; font-size: .8rem; color: var(--grey); margin-top: 2px; }

.masked { font-variant-numeric: tabular-nums; letter-spacing: .02em; }

/* The Stripe card field, mounted only when he asks to add a card. */
#cardMount {
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  background: var(--surface); padding: 12px; min-height: 48px;
}

/* --------------------------------------------------------------------------
   16. Printing a receipt. [receipt-2026-09-04]

   A man printing a receipt for his own records should get the receipt and not
   the application around it. Everything that is navigation, action or chrome
   comes off; what is left is the visit, the money and the reference.

   THE VEIL IS NOT OVERRIDDEN HERE. A closed <details> prints closed, which is
   the correct behaviour and not an oversight: whether the service names reach
   a sheet of paper that may sit in a printer tray, or in a household recycling
   box, is his decision and it is the one he already made on the screen.
   -------------------------------------------------------------------------- */
@media print {
  header.site, .tabbar, .skip, .toast-rail, .sheet,
  .back-link, .no-print, .btn, .seg, .form-msg { display: none !important; }

  /* Colour costs ink and a receipt is a document. */
  body.portal { background: #fff; color: #000; }
  .portal-main { padding: 0; max-width: none; }
  .panel {
    border: 0; box-shadow: none; padding: 0; margin: 0 0 14px; background: transparent;
    break-inside: avoid;
  }
  .panel.receipt { border-top: 1px solid #000; padding-top: 10px; }
  a[href]::after { content: ""; }
}

/* --------------------------------------------------------------------------
   17. Motion. style.css sets scroll-behavior:smooth on <html> unconditionally.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .wizard-panel.active,
  .wizard-sub.active,
  .sheet-card,
  .toast { animation: none; }
  * { transition-duration: .01ms !important; }
}
