/* ─────────────────────────────────────────────────────────────────────────────
   MOHR, /assessment
   The single-purpose booking page. Loaded after assets/mohr.css and
   assets/faq.css; every token, button, field and FAQ style comes from those.
   Nothing here redefines the brand; this file only adds the pieces the
   booking page needs and the home page does not:

     - the hero offer block ($299, credit, address)
     - the visit itinerary (what happens during the assessment)
     - the HairMetrix diagram and measurement list
     - the provider block
     - the treatment-pricing rows
     - the booking card's four states: form → working → booking → trouble
     - the sticky mobile action bar
   ───────────────────────────────────────────────────────────────────────────── */

/* ── inherited label markers, switched off ────────────────
   assets/mohr.css and assets/faq.css set a small brass disc in front of every
   micro-cap label and every closing reassurance line. Site-wide that disc is
   the house marker, but this page stacks eight of them down one scroll, where
   they stop reading as hierarchy and start reading as decoration. Here the
   labels stand on their letterspacing alone and sit flush with the headline
   they introduce, which also gives the column a single clean left edge.

   Scoped to this file, which only /assessment loads, so the marker is
   untouched on the home, pricing and confirmation pages.
   ─────────────────────────────────────────────────────── */
.eyebrow::before,
.faq__group::before,
.final__reassure div::before{display:none;}
/* the flex gaps existed only to hold the disc off the text */
.eyebrow,
.faq__group,
.final__reassure div{gap:0;}

/* Without their bullets the three closing reassurances need something to bind
   them into one group. The brass rule this page already uses for .role,
   .beat__note and .money__row--lead does it, and it occupies roughly the width
   the discs did, so the text stays where it was. */
.final__reassure{padding-left:1.4rem;border-left:2px solid var(--brass);}

/* ── header ───────────────────────────────────────────────
   Stripped to the wordmark and the one action. No navigation away.
   ─────────────────────────────────────────────────────── */
.nav--single{justify-content:space-between;}
.nav--single .btn{padding:.72rem 1.15rem;font-size:.9rem;}
@media(max-width:520px){
  .nav--single .btn{padding:.62rem .9rem;font-size:.82rem;}
}

/* ── hero ─────────────────────────────────────────────────
   Inherits .hero from mohr.css. The additions here exist for one reason: on a
   phone the headline, the one-line explanation, the $299 with its credit
   terms, the Park Avenue address and the button all have to land inside
   the first screen. The h1 is therefore set smaller than the home page's, because
   the offer headline is a sentence, not three words.
   ─────────────────────────────────────────────────────── */
/* .hero h1 in mohr.css is sized for a three-word home-page headline; this is a
   sentence, so it needs its own scale (and the extra class for specificity). */
.hero .hero__h1{font-size:clamp(1.95rem,5.4vw,3.5rem);letter-spacing:-.022em;max-width:22ch;}
.hero__lede{margin:1.15rem 0 0;font-size:clamp(1.02rem,1.1vw,1.2rem);max-width:33rem;}

/* What MOHR stands for, above the fold at every width. The header's .nav__tag
   spells it out from 860px up, but most of this page's traffic arrives on a
   phone, where that tag is hidden — so the hero label carries the full name as
   a quieter second line, and stands down again once the header says it. */
.hero .hero__eyebrow{flex-direction:column;align-items:flex-start;gap:.42rem;}
.hero__expansion{
  font-family:var(--accent);font-size:.66rem;font-weight:500;letter-spacing:.2em;
  text-transform:uppercase;color:color-mix(in srgb,var(--slate) 74%,transparent);
}
@media(min-width:860px){
  .hero__expansion{display:none;}
}

/* the offer, in numerals: price, what it converts into, and the two terms a
   patient wants settled before paying */
.offer{
  margin-top:clamp(1.5rem,3.4vw,2.1rem);padding-top:1.3rem;
  border-top:1px solid color-mix(in srgb,var(--ink) 13%,transparent);
}
.offer__price{display:flex;flex-wrap:wrap;align-items:baseline;gap:.35rem .9rem;margin:0;}
.offer__amount{
  font-family:var(--display);font-size:clamp(2.5rem,6.6vw,3.4rem);line-height:1;
  color:var(--evergreen);letter-spacing:-.03em;
}
.offer__credit{
  font-family:var(--accent);font-size:clamp(.95rem,1vw,1.05rem);font-weight:500;
  color:var(--ink);letter-spacing:.005em;line-height:1.35;
}
.offer__facts{list-style:none;margin:.9rem 0 0;padding:0;display:flex;flex-direction:column;gap:.5rem;}
.offer__facts li{
  font-size:.95rem;line-height:1.45;color:var(--slate);
}

.hero__cta{flex-direction:column;align-items:flex-start;gap:.85rem;margin-top:clamp(1.6rem,3.4vw,2.1rem);}
.hero__cta .btn{padding:1.08rem 1.75rem;}
.hero__creditline{
  font-family:var(--accent);font-size:.9rem;font-weight:500;color:var(--slate);
  letter-spacing:.01em;margin:0;max-width:32rem;line-height:1.5;
}
/* On a phone the decorative aperture sits below the fold; keep it small enough
   that it never becomes the reason the page scrolls. */
@media(max-width:939px){
  .hero__aperture .aperture{width:min(58vw,240px);}
  .hero{padding-bottom:clamp(2.5rem,6vh,4rem);}
}
/* Small phones: the fold budget. Cold Meta traffic arrives here, so the
   headline, the explanation, the $299 with both of its terms, the address and
   the button are all trimmed to land inside one screen on a 375×667 device.
   Nothing is hidden and nothing drops below 15px. */
@media(max-width:520px){
  .hero{padding-top:clamp(1.4rem,4vh,2.4rem);}
  .hero .eyebrow{font-size:.68rem;letter-spacing:.18em;margin-bottom:1rem;}
  .hero .hero__h1{font-size:1.72rem;line-height:1.08;max-width:none;}
  .hero__lede{margin-top:.9rem;font-size:1rem;line-height:1.5;}
  .offer{margin-top:1.2rem;padding-top:1rem;}
  .offer__amount{font-size:2.2rem;}
  .offer__credit{font-size:.95rem;}
  .offer__facts{margin-top:.7rem;gap:.45rem;}
  .offer__facts li{font-size:.9rem;}
  .hero__cta{margin-top:1.2rem;gap:.7rem;}
  /* full-width button: the largest tap target the column allows */
  .hero__cta .btn{width:100%;justify-content:center;text-align:center;}
  .hero__creditline{font-size:.85rem;}
}

/* ── the visit ────────────────────────────────────────────
   Three beats as an itinerary, not three cards in a row. A sticky label column
   on the left, full-width rows on the right, each opening with a serif numeral.
   ─────────────────────────────────────────────────────── */
.visit__head{max-width:46rem;margin-bottom:clamp(2.4rem,5vw,3.4rem);}
/* the supporting line under the section title, kept in the display serif so it
   reads as a second headline rather than as body copy */
.visit__support{
  font-family:var(--display);font-weight:300;
  font-size:clamp(1.35rem,2.8vw,2rem);line-height:1.2;letter-spacing:-.018em;
  color:var(--evergreen);margin:1.1rem 0 0;max-width:26ch;
}
.visit__grid{display:grid;grid-template-columns:1fr;gap:0 clamp(2rem,4vw,3.5rem);}
@media(min-width:900px){.visit__grid{grid-template-columns:13rem minmax(0,1fr);}}
.visit__label{
  font-family:var(--accent);font-size:.72rem;font-weight:600;letter-spacing:.2em;
  text-transform:uppercase;color:var(--slate);margin:0 0 1.6rem;
  line-height:1.5;
}
@media(min-width:900px){.visit__label{position:sticky;top:5.5rem;align-self:start;}}
.visit__list{max-width:48rem;}

.beat{
  display:grid;grid-template-columns:auto minmax(0,1fr);gap:0 clamp(1.2rem,2.5vw,2rem);
  padding:clamp(1.8rem,3.5vw,2.6rem) 0;
  border-top:1px solid color-mix(in srgb,var(--ink) 12%,transparent);
}
.beat:first-child{border-top:0;padding-top:0;}
.beat__n{
  font-family:var(--display);font-size:clamp(2rem,4vw,2.6rem);line-height:.9;
  color:color-mix(in srgb,var(--evergreen) 34%,transparent);letter-spacing:-.03em;
  grid-row:1 / span 2;
}
.beat h3{font-size:clamp(1.25rem,2.2vw,1.6rem);color:var(--evergreen);letter-spacing:-.012em;margin:0 0 .6rem;}
.beat p{margin:0;color:var(--slate);font-size:1.02rem;line-height:1.65;max-width:38rem;}
.beat p + p{margin-top:.8rem;}
.beat__note{
  margin-top:1rem;padding-left:1.1rem;border-left:2px solid var(--brass);
  font-size:.94rem;color:var(--slate);line-height:1.6;
}
.beat__note b{color:var(--ink);font-weight:600;}

/* ── HairMetrix ───────────────────────────────────────────
   Runs on the evergreen panel. The diagram leads and the list follows: what the
   imaging can help quantify, stated as readings rather than as promises.

   The diagram is drawn, not photographed, and says so in its caption. There is
   no real HairMetrix capture in /assets yet, and a stock scalp photograph would
   be worse than an honest schematic. Swap it for a real capture when one is
   approved: replace the <svg> inside .metrix__figure and keep the caption
   truthful.
   ─────────────────────────────────────────────────────── */
.metrix__head{max-width:44rem;margin-bottom:clamp(2.2rem,4.5vw,3.2rem);}
.metrix__grid{display:grid;grid-template-columns:1fr;gap:clamp(2.2rem,4.5vw,4rem);align-items:start;}
@media(min-width:880px){.metrix__grid{grid-template-columns:1.05fr .95fr;}}
.metrix__lede{margin-top:1.4rem;color:color-mix(in srgb,var(--porcelain) 86%,transparent);}

.metrix__figure{margin:0;}
.metrix__caption{
  margin:1rem 0 0;font-size:.82rem;line-height:1.55;
  color:color-mix(in srgb,var(--porcelain) 60%,transparent);max-width:32rem;
}
/* the measured field: a rounded frame, a light graticule, follicular units at
   differing calibre, and one site brought up close under calipers */
.field{display:block;width:100%;height:auto;}
.field__bg{fill:color-mix(in srgb,var(--porcelain) 6%,transparent);}
.field__frame{fill:none;stroke:color-mix(in srgb,var(--porcelain) 26%,transparent);stroke-width:1;}
.field__grid line{stroke:color-mix(in srgb,var(--porcelain) 12%,transparent);stroke-width:1;}
.field__hairs path{
  fill:none;stroke:color-mix(in srgb,var(--porcelain) 62%,transparent);stroke-linecap:round;
}
.field__loupeRing{fill:none;stroke:var(--brass);stroke-width:1.4;}
.field__loupeFill{fill:color-mix(in srgb,var(--porcelain) 7%,transparent);}
.field__caliper line{stroke:color-mix(in srgb,var(--brass-light) 78%,transparent);stroke-width:1;stroke-dasharray:3 4;}
.field__focus{fill:var(--brass);}
.field__marks line{stroke:color-mix(in srgb,var(--brass) 70%,transparent);stroke-width:1.4;}
.metrix__body{margin-top:1.3rem;color:color-mix(in srgb,var(--porcelain) 78%,transparent);
  font-size:1.02rem;line-height:1.7;max-width:34rem;}

.metrix__panel{
  border:1px solid color-mix(in srgb,var(--porcelain) 22%,transparent);
  border-radius:var(--radius);padding:clamp(1.5rem,3vw,2.1rem);
  background:color-mix(in srgb,var(--porcelain) 5%,transparent);
}
.metrix__panelHead{
  font-family:var(--accent);font-size:.7rem;font-weight:600;letter-spacing:.2em;text-transform:uppercase;
  color:var(--brass-light);margin:0 0 1.3rem;
}
.metrix__list{list-style:none;margin:0;padding:0;}
.metrix__list li{
  padding:.85rem 0;border-top:1px solid color-mix(in srgb,var(--porcelain) 15%,transparent);
  color:color-mix(in srgb,var(--porcelain) 88%,transparent);font-size:.98rem;line-height:1.55;
}
.metrix__list li:first-child{border-top:0;padding-top:0;}
.metrix__list b{color:var(--porcelain);font-weight:600;}
.metrix__foot{
  margin:1.4rem 0 0;font-size:.86rem;line-height:1.6;
  color:color-mix(in srgb,var(--porcelain) 66%,transparent);
}

/* ── who you'll see ───────────────────────────────────────
   Deliberately not a headshot grid: there are no photographs to use yet, so
   credibility is carried by a ruled statement and two named roles.
   ─────────────────────────────────────────────────────── */
.who__grid{display:grid;grid-template-columns:1fr;gap:clamp(2rem,4vw,3.5rem);align-items:start;}
@media(min-width:860px){.who__grid{grid-template-columns:1fr 1fr;}}
.who__roles{display:flex;flex-direction:column;gap:1.4rem;}
.role{
  border-left:2px solid var(--brass);padding:.2rem 0 .2rem 1.4rem;
}
.role__who{font-family:var(--display);font-size:1.3rem;color:var(--evergreen);line-height:1.25;margin:0 0 .45rem;}
.role__what{
  font-family:var(--accent);font-size:.7rem;font-weight:600;letter-spacing:.2em;
  text-transform:uppercase;color:var(--slate);margin:0 0 .7rem;
}
.role p{margin:0;font-size:.99rem;color:var(--slate);line-height:1.65;}

/* ── why MOHR ─────────────────────────────────────────────
   Three differentiators, stated positively. .contrast__label carries the same
   micro-cap rule the old "not …" label used, so the grid is unchanged visually
   while the copy stops defining the practice by what it isn't. The label sits
   flush with the heading below it, unornamented.
   ─────────────────────────────────────────────────────── */
.contrast{display:grid;grid-template-columns:1fr;gap:1px;
  background:color-mix(in srgb,var(--ink) 12%,transparent);
  border:1px solid color-mix(in srgb,var(--ink) 12%,transparent);
  border-radius:var(--radius);overflow:hidden;margin-top:clamp(2rem,4vw,3rem);}
@media(min-width:760px){.contrast{grid-template-columns:repeat(3,1fr);}}
.contrast__cell{background:var(--porcelain);padding:clamp(1.5rem,3vw,2.1rem);}
.contrast__label,
.contrast__not{
  font-family:var(--accent);font-size:.7rem;font-weight:600;letter-spacing:.18em;text-transform:uppercase;
  color:var(--slate);margin:0 0 .8rem;
}
.contrast__cell h3{font-size:1.18rem;color:var(--evergreen);margin:0 0 .5rem;letter-spacing:-.01em;}
.contrast__cell p{margin:0;font-size:.97rem;color:var(--slate);line-height:1.6;}

/* ── after the assessment ─────────────────────────────────
   Treatment pricing, stated on the page rather than saved for the room. Three
   rows on a ruled panel: what treatment costs, what the $299 becomes, and what
   happens if the provider says no. The aim is qualified patients, so the range
   is legible rather than buried.
   ─────────────────────────────────────────────────────── */
.after__grid{display:grid;grid-template-columns:1fr;gap:clamp(2.2rem,4.5vw,4rem);align-items:start;}
@media(min-width:900px){.after__grid{grid-template-columns:1fr 1fr;}}
.money{
  border:1px solid color-mix(in srgb,var(--ink) 13%,transparent);
  border-radius:var(--radius);padding:clamp(1.4rem,3vw,2.1rem);
  background:color-mix(in srgb,var(--sage) 45%,transparent);
}
.money__row{padding:1.2rem 0;border-top:1px solid color-mix(in srgb,var(--ink) 12%,transparent);}
.money__row:first-child{border-top:0;padding-top:0;}
.money__label{
  font-family:var(--accent);font-size:.7rem;font-weight:600;letter-spacing:.2em;
  text-transform:uppercase;color:var(--slate);margin:0 0 .55rem;
}
.money__figure{
  font-family:var(--display);font-size:clamp(1.6rem,3.4vw,2.1rem);line-height:1.05;
  letter-spacing:-.025em;color:var(--evergreen);margin:0;
}
.money__note{margin:.55rem 0 0;font-size:.95rem;line-height:1.55;color:var(--slate);max-width:32rem;}
/* the row the patient is really being asked to trust */
.money__row--lead .money__figure{color:var(--ink);}
.money__row--lead{border-left:2px solid var(--brass);padding-left:1.1rem;}
.money__foot{
  margin:1.3rem 0 0;padding-top:1.2rem;
  border-top:1px solid color-mix(in srgb,var(--ink) 12%,transparent);
  font-size:.9rem;line-height:1.6;color:var(--slate);
}

/* ── booking card ─────────────────────────────────────────
   Four states in one .card, switched by a data attribute on the card:
     form      → name / email / phone
     working   → creating the checkout session
     booking   → payment confirmed, Calendly released
     trouble   → payment could not be confirmed
   Only the "booking" state ever renders a calendar. There is no path from the
   form state to a booking time that does not pass through Stripe.
   ─────────────────────────────────────────────────────── */
.book__state{display:none;}
.card[data-state="form"]    .book__state--form,
.card[data-state="working"] .book__state--working,
.card[data-state="booking"] .book__state--booking,
.card[data-state="trouble"] .book__state--trouble{display:block;animation:focusIn .6s var(--ease) both;}

.card__price{
  display:flex;align-items:baseline;gap:.6rem;margin:-.4rem 0 1.4rem;
  padding-bottom:1.2rem;border-bottom:1px solid color-mix(in srgb,var(--ink) 10%,transparent);
}
.card__priceAmount{font-family:var(--display);font-size:2rem;line-height:1;color:var(--evergreen);letter-spacing:-.03em;}
.card__priceWhat{font-size:.92rem;color:var(--slate);line-height:1.45;}

/* the honeypot: off-screen, never focusable, never announced */
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden;}

/* submit button while a checkout session is being created */
.btn[aria-busy="true"]{opacity:.72;cursor:progress;}
.btn[aria-busy="true"] .btn__dot{animation:pulseDot 1.1s ease-in-out infinite;}
@keyframes pulseDot{0%,100%{transform:scale(1);opacity:1;}50%{transform:scale(1.9);opacity:.45;}}

/* form-level error, distinct from the per-field .field__err */
.form__error{
  display:none;margin:1rem 0 0;padding:.85rem 1rem;border-radius:var(--radius-sm);
  background:color-mix(in srgb,#a8442f 8%,transparent);
  border:1px solid color-mix(in srgb,#a8442f 30%,transparent);
  font-size:.92rem;color:#8a3320;line-height:1.55;
}
.form__error.on{display:block;}

/* the cancelled-checkout nudge */
.form__notice{
  display:none;margin:0 0 1.3rem;padding:.85rem 1rem;border-radius:var(--radius-sm);
  background:var(--sage);font-size:.92rem;color:var(--slate);line-height:1.55;
}
.form__notice.on{display:block;}
.form__notice b{color:var(--ink);font-weight:600;}

/* working state: a skeleton shaped like the checkout hand-off, not a spinner */
.working{text-align:center;padding:1.4rem 0 .6rem;}
.working__mark{width:64px;height:64px;margin:0 auto 1.4rem;display:block;}
.working__mark .ring{fill:none;stroke:color-mix(in srgb,var(--evergreen) 30%,transparent);}
.working__mark .arc{fill:none;stroke:var(--brass);stroke-linecap:round;transform-origin:center;
  animation:spin 1.1s linear infinite;}
.working h3{font-family:var(--display);font-size:1.5rem;color:var(--evergreen);margin:0 0 .6rem;}
.working p{color:var(--slate);font-size:.98rem;margin:0;}
.working__bars{margin-top:1.8rem;display:flex;flex-direction:column;gap:.65rem;}
.working__bars span{
  height:10px;border-radius:100px;background:color-mix(in srgb,var(--ink) 8%,transparent);
  animation:shimmer 1.6s var(--ease) infinite;
}
.working__bars span:nth-child(2){width:82%;animation-delay:.12s;}
.working__bars span:nth-child(3){width:56%;animation-delay:.24s;}
@keyframes shimmer{0%,100%{opacity:.5;}50%{opacity:1;}}

/* booking state */
.booked__head{display:flex;gap:1rem;align-items:flex-start;margin-bottom:1.4rem;}
.booked__head svg{flex:0 0 auto;width:44px;height:44px;}
.booked__head h3{font-family:var(--display);font-size:1.5rem;color:var(--evergreen);margin:0 0 .35rem;line-height:1.15;}
.booked__head p{margin:0;font-size:.95rem;color:var(--slate);line-height:1.55;}
.booked__embed{
  min-height:640px;border-radius:var(--radius-sm);overflow:hidden;
  border:1px solid color-mix(in srgb,var(--ink) 10%,transparent);
  background:color-mix(in srgb,var(--sage) 55%,transparent);
}
.booked__fallback{margin:1.1rem 0 0;font-size:.9rem;color:var(--slate);line-height:1.6;}
.booked__fallback a{color:var(--evergreen);font-weight:600;text-underline-offset:3px;}

/* trouble state */
.trouble h3{font-family:var(--display);font-size:1.5rem;color:var(--evergreen);margin:0 0 .7rem;}
.trouble p{color:var(--slate);font-size:.98rem;line-height:1.6;margin:0 0 .9rem;}
.trouble .btn{margin-top:.5rem;}

/* ── sticky action bar (small screens) ────────────────────
   The page is long and the form lives at the bottom; on a phone the offer has
   to stay reachable. Hidden once the booking card is on screen so it never
   covers the thing it points at.
   ─────────────────────────────────────────────────────── */
.actionbar{
  position:fixed;left:0;right:0;bottom:0;z-index:90;
  display:flex;align-items:center;justify-content:space-between;gap:1rem;
  padding:.8rem clamp(1rem,4vw,1.5rem);
  padding-bottom:calc(.8rem + env(safe-area-inset-bottom,0px));
  background:color-mix(in srgb,var(--porcelain) 94%,transparent);
  backdrop-filter:saturate(1.1) blur(10px);
  border-top:1px solid color-mix(in srgb,var(--ink) 10%,transparent);
  transform:translateY(110%);transition:transform .4s var(--ease);
}
.actionbar.on{transform:none;}
.actionbar__what{font-size:.82rem;line-height:1.35;color:var(--slate);}
.actionbar__what b{display:block;font-family:var(--display);font-size:1.15rem;color:var(--evergreen);letter-spacing:-.02em;}
.actionbar .btn{padding:.8rem 1.15rem;font-size:.9rem;white-space:nowrap;}
/* narrowest phones: the bar carries a price, a label and a button on one row, so
   tighten all three rather than let anything overflow the viewport */
@media(max-width:400px){
  .actionbar{gap:.6rem;padding-inline:.9rem;}
  .actionbar__what{font-size:.75rem;}
  .actionbar__what b{font-size:1.05rem;}
  .actionbar .btn{padding:.75rem .95rem;font-size:.85rem;}
}
@media(min-width:860px){.actionbar{display:none;}}

/* ── footer ───────────────────────────────────────────────
   The fuller, legal footer (.foot--legal and friends) is shared with
   /assessment-confirmed and lives in assets/mohr.css. The only page-specific
   piece is leaving room for the sticky action bar so the disclaimer is never
   trapped under it.
   ─────────────────────────────────────────────────────── */
@media(max-width:859px){body{padding-bottom:5.5rem;}}

/* ── motion ───────────────────────────────────────────── */
@media (prefers-reduced-motion:reduce){
  .actionbar{transition:none;}
  .working__bars span,.working__mark .arc,.btn[aria-busy="true"] .btn__dot{animation:none !important;}
}
