/* =====================================================================
   Fulham Boxing Club — member account.

   This screen is the club's website as far as a member is concerned: they
   arrive from fulhamboxingclub.co.uk to log in and book, and the join
   should be invisible. So the tokens, the type and the shapes here are
   lifted from the site's own stylesheet (landing/public/styles.css) rather
   than from the staff app: white ground, the club's green, Anton set in
   uppercase for anything that behaves like a headline.

   Structural rules carried over from the rest of the platform:
     · the document never scrolls — one region does, and it hides its bar
     · nothing overhangs: every fixed thing accounts for the safe area
     · phones get a bottom tab bar, desktops get the pill nav in the header
   ===================================================================== */

@font-face{
  font-family:'Anton';
  src:url('../shared/fonts/anton-display.woff2') format('woff2');
  font-weight:400;font-style:normal;font-display:swap;
}

:root{
  /* Sampled from the club's logo, same values the website uses. */
  --ink:#16130f; --ink-soft:#52594f; --faint:#8a8f86;
  --paper:#ffffff; --paper-alt:#f3f6f2; --paper-deep:#eaf0e8;
  --green:#3f7a42; --green-dark:#2c5c2f; --green-bright:#4f9d55;
  --green-wash:rgba(63,122,66,.08);
  --gold:#c9a86a;
  --line:rgba(22,19,15,.1); --line-strong:rgba(22,19,15,.2);
  --red:#b3341f;

  --display:'Anton','Arial Narrow',Arial,sans-serif;
  --body:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;

  --radius:14px; --radius-sm:9px;
  --shadow-card:0 12px 28px -16px rgba(22,19,15,.16);
  --shadow-lift:0 24px 48px -20px rgba(22,19,15,.22);
  --ease:cubic-bezier(.4,0,.2,1);
  --ease-punch:cubic-bezier(.2,.9,.3,1.3);

  /* Height of the phone tab bar, so content and toasts can clear it. */
  --tabbar:60px;
}

*,*::before,*::after{box-sizing:border-box}
/* Toggled from JS on elements whose class also sets display, so it has to
   win the cascade outright. */
[hidden]{display:none !important}

/* The page owns the viewport. Only .wrap scrolls, and it hides its bar.
   ---------------------------------------------------------------------
   TWO DIFFERENT VIEWPORTS, AND THEY NEED DIFFERENT UNITS.

   INSTALLED (PWA): the layout viewport can stop ABOVE the home indicator,
   so `height:100%` left a white strip at the bottom and `dvh` measured the
   same short box. `100vh` is the large viewport and reaches the real screen
   edge. That is the fix in app/crm.css, and it is right — for an installed
   app, where there is no browser chrome and the viewport never changes size.

   IN A BROWSER TAB: Safari's toolbar collapses and expands as you scroll,
   and `vh`/`lvh` both mean "as if the toolbar were hidden" — permanently
   TALLER than what you can actually see. With the document set to that
   height and `overflow:hidden`, the bottom of the layout sits behind the
   toolbar with no way to scroll to it: the pay sheet's buttons could not be
   reached, and the top was clipped as the visual viewport slid around
   inside a layout box bigger than itself.

   `dvh` is the one that tracks the toolbar. So: dvh by default, vh only
   when actually installed. */
html{background:var(--paper)}
html,body{height:100dvh;overflow:hidden;overscroll-behavior:none}
@media (display-mode:standalone),(display-mode:fullscreen),(display-mode:minimal-ui){
  html,body{height:100vh}
}
body{
  margin:0;display:flex;flex-direction:column;
  font-family:var(--body);color:var(--ink);background:var(--paper);
  line-height:1.5;-webkit-font-smoothing:antialiased;
  -webkit-text-size-adjust:100%;text-size-adjust:100%;
}
html[data-kb] body{height:var(--app-h,100dvh)}
::-webkit-scrollbar{width:0;height:0}
img{display:block;max-width:100%}
button{font:inherit;color:inherit;cursor:pointer}
:focus-visible{outline:3px solid var(--green);outline-offset:2px}

/* ------------------------------------------------------------ header */
.topbar{
  display:flex;align-items:center;justify-content:space-between;gap:1rem;
  padding:.7rem clamp(.9rem,3vw,1.6rem);
  padding-top:calc(.7rem + env(safe-area-inset-top));
  background:var(--paper);border-bottom:1px solid var(--line);
  flex-shrink:0;z-index:10;
}
.brand{display:flex;align-items:center;gap:.6rem;min-width:0}
.brand img{width:38px;height:38px;flex-shrink:0}
.brand .wordmark{
  font-family:var(--display);text-transform:uppercase;line-height:.95;
  font-size:clamp(.95rem,3.4vw,1.15rem);letter-spacing:.01em;
}
.brand .wordmark span{display:block;color:var(--green);font-size:.62em;letter-spacing:.14em}

/* Desktop nav: pills in the header. On phones this whole strip moves to
   the bottom of the screen (see the media query at the end). */
#nav{display:flex;align-items:center;gap:.25rem}
#nav button{
  border:none;background:none;padding:.5rem .85rem;border-radius:999px;
  font-size:.86rem;font-weight:600;color:var(--ink-soft);
  transition:background .18s var(--ease),color .18s var(--ease);
}
#nav button:hover{background:var(--paper-alt);color:var(--ink)}
#nav button.active{background:var(--green);color:#fff}
#nav button .ico{display:none}
#nav #logoutBtn{color:var(--faint);font-weight:500}

/* ----------------------------------------------------------- content */
.wrap{
  flex:1;min-height:0;width:100%;
  overflow-y:auto;overscroll-behavior:contain;scrollbar-width:none;
  padding:clamp(1rem,3vw,1.6rem) clamp(.9rem,3vw,1.6rem) 2rem;
}
/* A flex column of full height, so the signed-out card can centre itself
   against the viewport while the signed-in screens still flow top-down. */
.inner{max-width:720px;margin-inline:auto;width:100%;min-height:100%;display:flex;flex-direction:column}

h1,h2,.display{
  font-family:var(--display);font-weight:400;text-transform:uppercase;
  letter-spacing:.01em;line-height:1;margin:0;
}
h1{font-size:clamp(1.7rem,1.4rem+2vw,2.5rem)}
h2{font-size:clamp(1.15rem,1rem+.9vw,1.5rem);margin:1.8rem 0 .7rem}
.eyebrow{
  font-family:var(--display);text-transform:uppercase;letter-spacing:.16em;
  font-size:.72rem;color:var(--green);margin-bottom:.35rem;
}
.muted{color:var(--ink-soft);font-size:.9rem}
.error{color:var(--red);font-size:.85rem;min-height:1.15em;margin:.4rem 0 0}
/* The same line, in the "that worked" colour. It carries real instructions
   now ("we emailed you a link, go and open it") rather than a one-word
   failure, so it gets a box to sit in and room to run to two or three lines
   — min-height stays on .error so the layout does not jump when it is empty. */
.error.ok{
  color:var(--green-dark);background:var(--green-wash);
  border-radius:var(--radius-sm);padding:.6rem .7rem;margin-top:.7rem;
  font-weight:600;line-height:1.4;
}
.error.ok:empty{display:none}

.viewhead{
  display:flex;align-items:center;justify-content:space-between;
  gap:.8rem;flex-wrap:wrap;margin-bottom:1rem;
}

.card{
  background:var(--paper);border:1px solid var(--line);
  border-radius:var(--radius);padding:clamp(1rem,3vw,1.3rem);
  box-shadow:var(--shadow-card);
}
.stack{display:flex;flex-direction:column;gap:.65rem}

/* ----------------------------------------------------------- buttons */
button.primary{
  background:var(--green);color:#fff;border:none;
  padding:.72rem 1.15rem;border-radius:var(--radius-sm);
  font-weight:700;min-height:46px;letter-spacing:.01em;
  transition:background .18s var(--ease),transform .12s var(--ease-punch);
}
button.primary:hover:not(:disabled){background:var(--green-dark)}
button.primary:active:not(:disabled){transform:translateY(1px)}
button.primary:disabled{opacity:.5;cursor:default}
button.ghost{
  background:none;border:1px solid var(--line-strong);color:var(--ink);
  padding:.5rem .9rem;border-radius:var(--radius-sm);font-weight:600;
  transition:border-color .18s var(--ease),background .18s var(--ease);
}
button.ghost:hover:not(:disabled){border-color:var(--green);background:var(--green-wash)}
button.ghost:disabled{opacity:.5;cursor:default}
button.linkish{
  background:none;border:none;padding:0;margin-top:.8rem;
  font-size:.85rem;color:var(--green-dark);text-decoration:underline;
}

/* -------------------------------------------------------------- auth */
/* The one screen a member sees before they are a member. It gets the
   badge at size and the club's headline type, because for most people
   this is the first page of the website they actually interact with. */
.authwrap{
  flex:1;display:flex;align-items:center;justify-content:center;
  padding:1rem 0 2rem;
}
.auth{width:100%;max-width:400px;padding:clamp(1.4rem,5vw,2rem);text-align:left}
.auth .badge{width:74px;height:74px;margin:0 auto .9rem}
.auth h1{text-align:center}
.auth > .muted{text-align:center;margin-top:.4rem}

.tabs{display:flex;gap:.4rem;margin:1.2rem 0 .4rem;background:var(--paper-alt);padding:.25rem;border-radius:999px}
.tabs button{
  flex:1;padding:.55rem;border:none;background:none;border-radius:999px;
  font-size:.88rem;font-weight:700;color:var(--ink-soft);
  transition:background .2s var(--ease),color .2s var(--ease);
}
.tabs button.active{background:var(--paper);color:var(--green-dark);box-shadow:0 1px 3px rgba(22,19,15,.12)}

form label{display:block;margin:.8rem 0 0;font-size:.78rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--ink-soft)}
form input:not([type=checkbox]){
  display:block;width:100%;margin-top:.35rem;padding:.7rem .8rem;
  border:1px solid var(--line-strong);border-radius:var(--radius-sm);
  font:inherit;background:var(--paper);color:var(--ink);
  transition:border-color .18s var(--ease),box-shadow .18s var(--ease);
}
form input:focus{outline:none;border-color:var(--green);box-shadow:0 0 0 3px var(--green-wash)}
/* Under 16px iOS Safari zooms the page in on focus and never zooms back out,
   so a member who types their email lands in the portal zoomed. `font:inherit`
   above makes these 1rem already on most phones — this pins it so a smaller
   root font-size can never quietly drop them under the threshold. */
@media (pointer:coarse){form input:not([type=checkbox]),form textarea,form select{font-size:16px}}
form .primary{width:100%;margin-top:1rem}
.checkrow{
  display:flex;align-items:center;gap:.6rem;margin:1rem 0 0;
  font-size:.85rem;font-weight:600;text-transform:none;letter-spacing:0;color:var(--ink);
}
.checkrow input{width:18px;height:18px;accent-color:var(--green);margin:0;flex:none}

/* ------------------------------------------------- offer banner ------ */
/* One strip, above everything, only when the club is actually advertising
   something. Club green rather than a warning colour — this is good news, and
   an alert-yellow bar teaches people to dismiss it on sight. It wraps to two
   lines on a narrow phone instead of shrinking the text, because the value
   ("20% off") is the part that has to stay legible. */
.offerbanner{
  display:flex;align-items:center;justify-content:space-between;
  flex-wrap:wrap;gap:.5rem 1rem;
  background:var(--green);color:#fff;
  border-radius:var(--radius);padding:.7rem 1rem;margin-bottom:1rem;
}
.offerbanner .ob-main{display:flex;align-items:baseline;gap:.6rem;flex-wrap:wrap;min-width:0}
.offerbanner .ob-value{
  font-family:var(--display);text-transform:uppercase;letter-spacing:.02em;
  font-size:1.15rem;line-height:1;flex:none;
}
.offerbanner .ob-text{font-size:.9rem;font-weight:600;line-height:1.35;min-width:0}
.offerbanner .ob-meta{display:flex;align-items:center;gap:.5rem;flex:none}
.offerbanner .ob-code{
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:.78rem;font-weight:700;letter-spacing:.06em;
  background:rgba(255,255,255,.18);border-radius:999px;padding:.25rem .6rem;
}
.offerbanner .ob-ends{font-size:.75rem;opacity:.85;white-space:nowrap}

/* ------------------------------------------------ credits strip ------ */
/* The headline: class credits, PT sessions, gym access, read from a single
   my_entitlements() call and shown at the top of Book and Membership so
   a member never has to hunt for what they can actually do right now. */
.creditstrip{display:flex;gap:.55rem;margin-bottom:1rem}
.creditstrip .pill,.creditstrip .skeleton{flex:1 1 0;min-width:0}
.pill{
  background:var(--paper-alt);border:1px solid var(--line);border-radius:var(--radius-sm);
  padding:.55rem .7rem;display:flex;flex-direction:column;gap:.15rem;
  transition:border-color .18s var(--ease),background .18s var(--ease);
}
.pill-label{font-size:.66rem;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--ink-soft);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pill-value{font-family:var(--display);font-size:1.1rem;letter-spacing:.01em;color:var(--ink-soft);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pill.good{background:var(--green-wash);border-color:rgba(63,122,66,.28)}
.pill.good .pill-value{color:var(--green-dark)}
/* "Update needed" — a fact we genuinely don't know yet (migration not
   applied), styled apart from "you have zero", which is a fact we do know. */
.pill.warn{border-style:dashed}
.pill.warn .pill-value{font-family:var(--body);font-weight:600;font-size:.82rem;font-style:italic;color:var(--faint)}

/* -------------------------------------------------- segmented control */
/* Classes/PT live as a segment inside the Book and My bookings tabs
   instead of PT becoming a fifth top-level destination — see the phone
   tab-bar note further down. */
.segmented{display:flex;gap:.25rem;background:var(--paper-alt);padding:.25rem;border-radius:999px;margin-bottom:1rem}
.segmented button{
  flex:1;padding:.55rem .6rem;border:none;background:none;border-radius:999px;
  font-size:.85rem;font-weight:700;color:var(--ink-soft);min-height:38px;
  transition:background .2s var(--ease),color .2s var(--ease);
}
.segmented button.active{background:var(--paper);color:var(--green-dark);box-shadow:0 1px 3px rgba(22,19,15,.12)}

/* --------------------------------------------------------- timetable */
.weeknav{display:flex;align-items:center;gap:.5rem;font-weight:700;font-size:.9rem}
.weeknav button{width:38px;height:38px;padding:0;font-size:1.1rem;line-height:1}

.dayhead{
  font-family:var(--display);text-transform:uppercase;letter-spacing:.08em;
  font-size:.85rem;color:var(--ink);margin:1.3rem 0 .1rem;
  display:flex;align-items:center;gap:.6rem;
}
.dayhead::after{content:'';flex:1;height:1px;background:var(--line)}
.dayhead:first-child{margin-top:0}

.classrow{
  display:flex;align-items:center;justify-content:space-between;gap:.9rem;
  background:var(--paper);border:1px solid var(--line);border-left:3px solid var(--green);
  border-radius:var(--radius);padding:.8rem .95rem;
  transition:border-color .18s var(--ease),box-shadow .18s var(--ease);
}
.classrow:hover{box-shadow:var(--shadow-card)}
.classrow.is-booked{border-left-color:var(--gold);background:var(--paper-alt)}
/* ARRIVED FROM THE WEBSITE. Someone who tapped BOOK HERE on a specific
   Thursday 19:30 class, or Select on a specific price card, gets scrolled to
   it — and this is what tells them which one of the thirty rows on screen is
   the one they came for. It fades itself out after a couple of seconds
   rather than sticking, because it is an answer to "where is it", not a
   state the row is in. Honouring prefers-reduced-motion: the ring still
   appears, it just does not pulse. */
@keyframes deeplinkPulse{
  0%{box-shadow:0 0 0 0 rgba(63,122,66,.42)}
  70%{box-shadow:0 0 0 10px rgba(63,122,66,0)}
  100%{box-shadow:0 0 0 0 rgba(63,122,66,0)}
}
.deeplinked{
  border-color:var(--green)!important;
  animation:deeplinkPulse 1.3s var(--ease) 3;
}
.classrow.deeplinked{background:var(--green-wash)}
@media (prefers-reduced-motion:reduce){
  .deeplinked{animation:none;box-shadow:0 0 0 3px rgba(63,122,66,.35)}
}

.cr-main{display:flex;flex-direction:column;min-width:0;gap:.1rem}
/* A long class name wraps rather than pushing the Book button off a narrow
   phone. overflow-wrap covers the single-long-word case that flex min-width
   alone does not. */
.cr-main .when{font-family:var(--display);font-size:1.02rem;letter-spacing:.02em;text-transform:uppercase;overflow-wrap:anywhere}
.cr-main .who{font-size:.82rem;color:var(--ink-soft);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cr-side{display:flex;align-items:center;gap:.7rem;flex:none}
.spots{font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--green-dark)}
.spots.full{color:#a8690c}

/* Started, finished, or inside the last 15 minutes. Faded rather than
   removed: the day still has to read as a day, and a member looking at
   this evening wants to see that the 18:00 has gone, not wonder whether
   the app has lost it. Nothing in here is pressable. */
.classrow.is-past{
  opacity:.55;background:var(--paper-alt);border-left-color:var(--line);
  box-shadow:none;
}
.classrow.is-past:hover{box-shadow:none}
.classrow.is-past .when{text-decoration:line-through;text-decoration-thickness:1px}
.cr-shut{
  font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:.05em;
  color:var(--ink-soft);white-space:nowrap;
}

/* --------------------------------------------- personal training book */
.coachpicker{display:flex;gap:.5rem;flex-wrap:wrap;margin-bottom:1rem}
.chip{
  border:1px solid var(--line-strong);background:var(--paper);color:var(--ink);
  padding:.5rem .95rem;border-radius:999px;font-weight:600;font-size:.85rem;
  min-height:44px;transition:border-color .18s var(--ease),background .18s var(--ease),color .18s var(--ease);
}
.chip.active{background:var(--green);border-color:var(--green);color:#fff}
.chip:hover:not(.active){border-color:var(--green)}

.ptempty{border-top:3px solid var(--gold);display:flex;flex-direction:column;gap:.5rem}
.ptempty .name{font-family:var(--display);text-transform:uppercase;font-size:1.05rem}
.ptplanrow{display:flex;align-items:center;justify-content:space-between;gap:.6rem;padding:.5rem 0;border-top:1px solid var(--line);font-size:.9rem}
.ptplanrow:first-child{border-top:none}
.ptplanrow .price{font-weight:700;color:var(--green-dark)}

/* ------------------------------------------------------- memberships */
.shophead{
  font-family:var(--display);text-transform:uppercase;letter-spacing:.04em;
  font-size:.95rem;color:var(--ink-soft);margin:1.6rem 0 .5rem;
}
.shophead:first-child{margin-top:0}
.plan{display:flex;flex-direction:column;gap:.3rem;border-top:3px solid var(--green)}
.plan .name{font-family:var(--display);text-transform:uppercase;font-size:1.15rem;letter-spacing:.02em}
.plan .price{font-family:var(--display);font-size:1.7rem;color:var(--green-dark);line-height:1.05;margin:.2rem 0 .5rem}
/* Phones: price and button share a line so the whole plan list fits the
   screen. Stacked, the third card sat behind the tab bar, which reads as
   the page being cut off rather than as something to scroll to. */
@media (max-width:760px){
  .plan{display:grid;grid-template-columns:1fr auto;grid-template-areas:'name name' 'sub sub' 'price cta';align-items:center;gap:.25rem .8rem;padding:.9rem 1rem}
  .plan .name{grid-area:name}
  .plan .muted{grid-area:sub}
  .plan .price{grid-area:price;margin:.35rem 0 0;font-size:1.5rem}
  .plan .primary{grid-area:cta;margin-top:.35rem;padding:.6rem 1rem;min-height:42px;font-size:.88rem}
}
/* One line under each group heading saying what the group actually is —
   "bought once, used whenever" is the difference between a pack and a
   membership, and it is not obvious from two prices side by side. */
.shopnote{font-size:.85rem;color:var(--ink-soft);margin:-.25rem 0 .7rem;line-height:1.45}

/* The membership they are already on. Gold rather than green, and no
   button: there is nothing to buy on this card. */
.plan-head{display:flex;align-items:baseline;justify-content:space-between;gap:.6rem;flex-wrap:wrap}
.plan-head .tag{
  font-size:.68rem;font-weight:800;letter-spacing:.06em;text-transform:uppercase;
  background:var(--gold);color:#2a2000;padding:.15rem .45rem;border-radius:999px;white-space:nowrap;
}
.plan.is-current{border-top-color:var(--gold)}
.plan-foot{font-size:.82rem;line-height:1.5;margin:.2rem 0 0}

@media (max-width:760px){
  .plan .plan-head{grid-area:name}
  .plan .plan-foot{grid-column:1/-1;margin-top:.35rem}
}

.card.mine{display:flex;flex-direction:column;gap:.2rem;border-top:3px solid var(--gold)}
.card.mine .name{font-family:var(--display);text-transform:uppercase;font-size:1.15rem}

.note{
  background:var(--green-wash);border:1px solid var(--paper-deep);
  border-radius:var(--radius-sm);padding:.75rem .9rem;font-size:.85rem;margin:0 0 1rem;
}

/* ------------------------------------------------------------- toast */
.toast{
  position:fixed;left:50%;transform:translateX(-50%);
  bottom:calc(1.1rem + env(safe-area-inset-bottom));
  background:var(--ink);color:#fff;padding:.7rem 1.1rem;border-radius:999px;
  font-size:.87rem;font-weight:600;z-index:60;max-width:calc(100vw - 2rem);
  box-shadow:var(--shadow-lift);animation:toastIn .24s var(--ease-punch);
}
.toast.bad{background:var(--red)}
@keyframes toastIn{from{opacity:0;transform:translate(-50%,12px)}to{opacity:1;transform:translate(-50%,0)}}

/* Placeholder rows while a list loads. Shown only when there is nothing on
   screen yet — a refresh swaps the finished list straight in, so the
   timetable never blinks empty between one week and the next. */
.skeleton{
  border-radius:var(--radius);height:66px;border:1px solid var(--line);
  background:linear-gradient(90deg,var(--paper-alt) 25%,var(--paper-deep) 37%,var(--paper-alt) 63%);
  background-size:400% 100%;animation:shimmer 1.3s ease-in-out infinite;
}
@keyframes shimmer{from{background-position:100% 0}to{background-position:0 0}}

/* ============================ PHONES ================================ */
/* The header nav becomes a bottom tab bar: thumbs are at the bottom of a
   phone, and it keeps the club's mark at the top where it belongs. */
@media (max-width:760px){
  .brand img{width:34px;height:34px}
  .wrap{padding-bottom:calc(var(--tabbar) + env(safe-area-inset-bottom) + 1rem)}

  #nav{
    position:fixed;left:0;right:0;bottom:0;z-index:50;
    display:flex;justify-content:space-around;align-items:stretch;gap:0;
    background:var(--paper);border-top:1px solid var(--line);
    padding:0 .2rem env(safe-area-inset-bottom);
    box-shadow:0 -6px 20px -12px rgba(22,19,15,.3);
  }
  #nav button{
    flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;
    gap:2px;padding:.45rem .1rem;height:var(--tabbar);border-radius:0;
    font-size:.66rem;font-weight:700;letter-spacing:.01em;
    background:none;color:var(--faint);
  }
  #nav button:hover{background:none}
  #nav button.active{background:none;color:var(--green-dark)}
  #nav button .ico{display:block;width:22px;height:22px}
  #nav button .ico svg{width:100%;height:100%;display:block}
  /* Log out is not a destination — it lives in Account on a phone. */
  #nav #logoutBtn{display:none}

  .toast{bottom:calc(var(--tabbar) + env(safe-area-inset-bottom) + .8rem)}

  .classrow{gap:.6rem;padding:.75rem .8rem}
  .cr-side{flex-direction:column;align-items:flex-end;gap:.4rem}
  .viewhead{margin-bottom:.8rem}

  .creditstrip{gap:.4rem}
  .pill{padding:.5rem .5rem}
  .pill-label{font-size:.62rem}
  .pill-value{font-size:.95rem}

  .segmented{margin-bottom:.85rem}
  .segmented button{font-size:.8rem;padding:.5rem .4rem}

  .coachpicker{gap:.4rem}
  .chip{padding:.5rem .8rem;font-size:.82rem}

  .ptplanrow{font-size:.85rem}
}

/* Very narrow phones: keep the two-line class row from wrapping badly, and
   keep the three-across credits strip from crushing its numbers. */
@media (max-width:380px){
  .cr-main .when{font-size:.95rem}
  #nav button{font-size:.6rem}

  .creditstrip{gap:.3rem}
  .pill{padding:.45rem .4rem}
  .pill-label{font-size:.58rem;letter-spacing:.02em}
  .pill-value{font-size:.85rem}
  .pill.warn .pill-value{font-size:.68rem}
}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms !important;transition-duration:.001ms !important}
}

/* =====================================================================
   Card checkout (Stripe Payment Element) — see portal.js payModal().
   The portal had no modal before this; everything else is a card in the
   flow. Kept deliberately plain so the Element, which is styled through
   Stripe's Appearance API to match these same variables, sits inside it
   without a visible seam.
   ===================================================================== */
.pay-scrim{
  position:fixed;inset:0;z-index:80;background:rgba(22,19,15,.5);
  display:flex;align-items:flex-end;justify-content:center;padding:0;
  animation:payIn .18s ease;
  /* Same story as html/body above. `min-height:100lvh` made the scrim
     TALLER than the visible area in a browser tab, and since the sheet is
     bottom-aligned that pushed Pay and Cancel underneath Safari's toolbar
     with nothing to scroll. dvh is what you can see; lvh is only correct
     once installed, where it stops the drawer from ending short of the
     home indicator. */
  min-height:100dvh;
}
@media (display-mode:standalone),(display-mode:fullscreen),(display-mode:minimal-ui){
  .pay-scrim{min-height:100lvh}
}
@media (min-width:641px){
  .pay-scrim{align-items:center;padding:24px}
}
.pay-modal{
  background:#fff;width:100%;max-width:460px;
  border-radius:var(--radius) var(--radius) 0 0;
  padding:22px 20px calc(20px + env(safe-area-inset-bottom));
  max-height:92dvh;overflow-y:auto;
  box-shadow:0 -8px 40px rgba(22,19,15,.28);
}
@media (min-width:641px){
  .pay-modal{border-radius:var(--radius);padding-bottom:20px;box-shadow:0 24px 60px rgba(22,19,15,.3)}
}
.pay-head h2{margin:0;font-size:1.15rem}
.pay-head .muted{margin:.25rem 0 0}
.pay-total{font-size:1.6rem;font-weight:800;color:var(--green);margin:.5rem 0 .2rem}
.pay-body{margin:1rem 0 .4rem;min-height:60px}
.pay-status{font-size:.85rem;color:var(--ink-soft);margin:.4rem 0 0;min-height:1.1em}
.pay-status.bad{color:#b3261e;font-weight:600}
.pay-foot{display:flex;gap:10px;margin-top:1rem}
.pay-foot button{flex:1;min-height:46px}
/* A question, not a form — no Element to make room for, so the sheet closes
   up around the two buttons instead of leaving payModal's body gap. */
.confirm-sheet .pay-head h2{font-size:1.1rem;line-height:1.3}
.confirm-sheet .pay-foot{margin-top:1.25rem}

/* Two ways to say yes ("pay now" / "pay in person"), so they stack full
   width and read top to bottom instead of competing for half a row each.
   Cancel goes last visually — it is the least likely answer, and putting it
   under the thumb on a phone is how people leave by accident. */
.pay-foot.stacked{flex-direction:column;gap:8px}
.pay-foot.stacked button{width:100%;flex:none;justify-content:center}
.pay-foot.stacked .ghost{min-height:40px;font-size:.88rem}
.choice-sub{display:block;font-size:.75rem;font-weight:500;opacity:.75;margin-top:.1rem}
@keyframes payIn{from{opacity:0}to{opacity:1}}
@media (prefers-reduced-motion:reduce){.pay-scrim{animation:none}}
