/* ===== BB Diet design tokens — Style Guide v1.1 (palette #30) ===== */
:root{
  --green:#bedb4d; --green-tint:rgba(190,219,77,.26); --amber:#f9b644; --amber-tint:rgba(249,182,68,.14);
  --black:#000; --ink:rgba(0,0,0,.72); --ink-strong:rgba(0,0,0,.86); --line:rgba(0,0,0,.12); --line-soft:rgba(0,0,0,.45);
  --white:#fff; --error:#c0392b; --ink-soft:rgba(0,0,0,.55);
  --serif:Georgia,"Times New Roman",serif; --sans:"Raleway","Segoe UI",system-ui,sans-serif; --hand:"Ink Free","Segoe Script","Bradley Hand",cursive;
  --r:18px;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;background:var(--white);color:var(--ink);font-family:var(--sans);font-size:16px;line-height:1.55;-webkit-font-smoothing:antialiased}
/* ⭐ HEADINGS ARE RALEWAY, 16 Sep 2026 — Angeline's call. They were Georgia; she
   asked for "Refer in under a minute", "What you'll actually pay", "Two
   dietitians and a diabetes educator" and the rest on Raleway, which is already
   the body face. Georgia stays for FIGURES only — prices, the big next-available
   time, the step numerals — where its old-style numerals earn their place.
   The .hand script accent inside a heading is untouched. */
h1,h2{font-family:var(--sans);font-weight:600;color:var(--ink);margin:0;line-height:1.14;letter-spacing:-.015em;text-wrap:balance}
h3,h4{font-family:var(--sans);font-weight:600;color:var(--ink);margin:0;line-height:1.25}
h1{font-size:clamp(34px,5vw,50px)} h2{font-size:clamp(28px,3.4vw,36px)} h3{font-size:20px} h4{font-size:16px}
p{margin:0} a{color:inherit}
.hand{font-family:var(--hand);color:var(--amber);font-size:1.06em;font-weight:400}
.k{display:block;font-weight:700;font-size:15px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink);margin-bottom:8px}
.lead{font-size:18px;max-width:60ch}
.in{max-width:1120px;margin:0 auto;padding:0 24px}
section{padding:64px 0}
.num{font-family:var(--serif);font-weight:400;color:var(--amber);font-size:28px;line-height:1}
/* buttons */
.btn{display:inline-flex;align-items:center;gap:8px;font-family:var(--sans);font-weight:700;font-size:15px;padding:13px 24px;border-radius:999px;text-decoration:none;border:1.5px solid transparent;cursor:pointer;background:none;color:var(--ink);transition:transform .2s,box-shadow .2s,background .2s;line-height:1.2;min-height:44px}
.btn.solid{background:var(--green);border-color:var(--green);color:var(--ink)}
.btn.solid:hover{transform:translateY(-1px);box-shadow:0 10px 24px -14px rgba(0,0,0,.35)}
.btn.line{border-color:var(--line-soft);color:var(--ink);font-weight:600}
.btn.line:hover{background:var(--green-tint)}
.btn.onband{border-color:rgba(255,255,255,.7);color:#fff}
.btn.sm{padding:10px 18px;font-size:14px;min-height:40px}
.btn:focus-visible,a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible{outline:3px solid var(--green);outline-offset:2px}
/* header */
header{position:sticky;top:0;z-index:40;background:rgba(255,255,255,.86);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);border-bottom:1px solid var(--line)}
/* ⚠ THE NAV RUNS OUT OF ROOM BEFORE IT RUNS OUT OF SCREEN, 20 Sep 2026 (item
   17). Nine fixed-gap items plus a cart pill plus a Book button overflowed
   between roughly 1100 and 1300px, and the cart was the one that got cut in
   half. The gaps now shrink with the viewport and the logo is not allowed to
   be squeezed, which keeps every item whole down to the burger breakpoint. */
.nav{display:flex;align-items:center;gap:clamp(10px,1.6vw,22px);max-width:1168px;margin:0 auto;padding:12px 24px}
.nav>.logo{flex:0 0 auto}
.logo img{height:44px;width:auto;display:block}
.links{display:flex;gap:clamp(10px,1.5vw,22px);margin-left:auto;flex-wrap:nowrap;list-style:none;padding:0;margin-top:0;margin-bottom:0;align-items:center}
.links a{text-decoration:none;font-weight:600;font-size:15px;color:var(--ink);padding:6px 0;border-bottom:2px solid transparent}
.links a[aria-current="page"]{border-bottom-color:var(--green)}
/* ⭐ HOVER HAS TO BE VISIBLE, 20 Sep 2026 (item 3). It only darkened the text a
   shade, which on a 15px semibold link is no signal at all. It now borrows the
   current-page underline at half strength, so hovering previews the state the
   link is about to take. */
.links a:hover{color:var(--ink-strong);border-bottom-color:var(--green-tint)}
.links a[aria-current="page"]:hover{border-bottom-color:var(--green)}
/* ⭐ THE RESOURCES SUBMENU HAD NO DROPDOWN CSS AT ALL, 21 Sep 2026 (item 2).
   Recipes/Blog were added as a nested <ul> straight in the markup with
   nothing to hide it, so it sat permanently open — wrapping the whole nav
   row onto two lines on every page. It now behaves like an actual dropdown:
   hidden until the parent is hovered or has focus inside it (so keyboard
   users tabbing to "Recipes"/"Blog" also reveal it), sitting in a floating
   card below the "Resources" link instead of pushing the nav around. */
.has-drop{position:relative}
.has-drop>a::after{content:"";display:inline-block;width:6px;height:6px;margin-left:6px;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:translateY(-2px) rotate(45deg)}
.has-drop .drop{position:absolute;top:100%;left:50%;transform:translateX(-50%) translateY(-6px);margin-top:14px;background:#fff;border:1px solid var(--line);border-radius:12px;box-shadow:0 16px 34px -14px rgba(0,0,0,.22);padding:8px;min-width:168px;list-style:none;opacity:0;visibility:hidden;pointer-events:none;transition:opacity .15s ease,transform .15s ease;z-index:50}
.has-drop:hover .drop,.has-drop:focus-within .drop{opacity:1;visibility:visible;pointer-events:auto;transform:translateX(-50%) translateY(0)}
/* ⚠ THE GAP ATE THE MOUSE, 22 Sep 2026 — Tristan: "I can't actually select the
   menu item under Resources menu" (screen recording). The card sits 14px below
   the link (margin-top above), and that strip belonged to neither the link nor
   the card — so the moment the pointer left "Resources" on its way down it was
   no longer over .has-drop, the card vanished, and there was nothing left to
   click. This invisible strip is part of the card, spans the gap, and keeps the
   hover alive all the way down. It only catches the pointer while the card is
   open (pointer-events follow the card's own open/closed state). */
.has-drop .drop::before{content:"";position:absolute;left:0;right:0;top:-18px;height:18px}
.drop a{display:block;padding:8px 12px;border-radius:8px;font-weight:600;font-size:14px;border-bottom:none!important;white-space:nowrap}
.drop a:hover{background:var(--green-tint);color:var(--ink-strong)}
.burger{display:none;margin-left:auto;background:none;border:1.5px solid var(--line-soft);border-radius:999px;width:44px;height:44px;cursor:pointer;color:var(--ink)}
.burger span{display:block;width:18px;height:2px;background:currentColor;margin:4px auto;border-radius:2px}
.menu{display:none}
/* hero */
/* FULL-BLEED HERO. The video is no longer a picture beside the headline — it is
   the whole first screen, with the words sitting on it. Everything that made the
   old split layout work (the frosted card, the outline shapes, the two-column
   grid) is deliberately undone below rather than deleted, because the markup is
   unchanged and only the presentation moved. */
.hero{position:relative;overflow:hidden;background:#101a06;padding:0;min-height:min(88vh,780px);display:flex;align-items:flex-end}
.hero .in{position:relative;z-index:2;width:100%;padding-top:140px;padding-bottom:104px}
.hero .photo{position:absolute;left:0;right:0;top:-18%;height:136%;border-radius:0;min-height:0;background:linear-gradient(160deg,#3a3a3a,var(--green));overflow:hidden;will-change:transform}
/* ⭐ THE PARALLAX BUFFER. The footage is deliberately 36% TALLER than the hero
   and sits 18% above it, so the script below can slide it down as the page
   scrolls without ever exposing a gap at the top. Change the 0.15 factor in
   site.js and this buffer has to change with it — max travel is
   factor × hero height, and that must stay under the 18% overhang. */
/* The video is bright and busy, so the text needs its own contrast rather than
   luck: darker top and bottom, lighter middle, so the footage still reads. */
.hero .photo::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,rgba(0,0,0,.55),rgba(0,0,0,.18) 38%,rgba(0,0,0,.70))}
/* ⭐ AND A SCRIM DOWN THE TEXT COLUMN, 16 Sep 2026. The vertical gradient above
   was tuned against dark footage; the salad clip is bright exactly where the
   headline sits, and white text was crossing specular highlights at barely
   1.1:1. This darkens the left third only, so the copy is readable and the food
   still reads at full brightness on the right where nothing sits over it.
   ⚠ z-index:1 IS LOAD-BEARING. ::before paints before .photo's real children,
   so without it this sits UNDER the video and does nothing at all. */
.hero .photo::before{content:"";position:absolute;inset:0;z-index:1;background:linear-gradient(90deg,rgba(0,0,0,.62),rgba(0,0,0,.34) 42%,rgba(0,0,0,0) 68%)}
/* the white page sweeping up into the footage, so the hero ends on a curve */
.hero::after{content:"";position:absolute;left:-6%;right:-6%;bottom:-70px;height:150px;background:var(--white);border-radius:50% 50% 0 0;z-index:3}
.hero .shape{display:none}
/* The hero video is decoration. It is muted, loops, carries a poster still for
   slow connections, and is hidden from assistive tech — the headline beside it
   is the content. prefers-reduced-motion stops it and leaves the poster. */
.hero .photo video,.hero .photo img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.shape{position:absolute;border:1.5px solid var(--black);border-radius:var(--r);opacity:.12;pointer-events:none}
.frost{position:relative;background:none;border-radius:0;padding:0;box-shadow:none;max-width:640px}
.frost h1{margin:8px 0 14px;color:#fff;text-shadow:0 2px 24px rgba(0,0,0,.35)}
.frost .k{color:var(--green)}
.frost .lead{color:rgba(255,255,255,.92)}
.frost .note{color:rgba(255,255,255,.88)}
/* on dark footage the outline button needs a white edge, not the ink one */
.frost .btn.line{border-color:rgba(255,255,255,.8);color:#fff}
.frost .btn.line:hover{background:rgba(255,255,255,.16)}
.cta{display:flex;gap:12px;flex-wrap:wrap;margin-top:24px}
.note{margin-top:18px;font-size:14px;display:flex;gap:8px;align-items:center}
.note i{width:8px;height:8px;border-radius:50%;background:var(--green);display:inline-block}
/* doors */
.doors{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-top:28px;position:relative;z-index:2}
.door{background:#fff;border-radius:var(--r);padding:24px;box-shadow:0 18px 40px -26px rgba(0,0,0,.35);display:flex;gap:16px;align-items:flex-start;border:1px solid var(--line)}
.door .num{min-width:40px}
.door h3{margin-bottom:4px}
.door .btn{margin-top:12px}
/* cards */
.cards{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-top:28px}
.card{background:#fff;border-radius:var(--r);padding:22px 20px;border:1px solid var(--line)}
.card .num{font-size:24px}
.card h3{margin:8px 0 6px}
.card p{font-size:15px}
.card .age{font-size:12px;letter-spacing:.12em;text-transform:uppercase;font-weight:700;margin-top:10px;display:block}
.card a{font-weight:700;text-decoration:none;display:inline-block;margin-top:10px;font-size:14px}
/* ⭐ THUMB-SIZED TAP TARGETS, 19 Sep 2026. The small inline links — "More →",
   "book →", the phone and email in the contact cards — were 20-something pixels
   tall, well under the 44px a thumb needs, so they were easy to miss and easy
   to hit the wrong one of. The text is unchanged; the hit area is not.
   ⚠ PHONE ONLY. A mouse is precise, and stretching every inline link on the
   desktop layout would leave odd gaps under the cards. */
@media (max-width:760px){
 .card a,.clinic a,.resource a,.member .body a:not(.btn),aside .card a,aside .panel a:not(.btn){
  display:inline-flex;align-items:center;min-height:44px}
 /* the big contact tiles: the whole number is the target, not just the glyphs */
 .card h3 a{display:flex;align-items:center;min-height:44px;width:100%}
}
.path{height:60px;border-left:2px dotted var(--black);opacity:.35;margin:0 auto;width:0;position:relative}
.path::after{content:"";position:absolute;left:-6px;bottom:-2px;width:10px;height:10px;border-right:2px solid var(--black);border-bottom:2px solid var(--black);transform:rotate(45deg)}
/* band */
.band{background:var(--black);color:#fff;border-radius:var(--r);padding:44px 40px;display:grid;grid-template-columns:1.2fr 1fr;gap:32px;align-items:center}
.band h2,.band .k,.band h3{color:#fff}
.band p{color:rgba(255,255,255,.9);font-size:17px}
.band ul{list-style:none;padding:0;margin:0;display:grid;gap:10px;font-size:15px}
.band li{display:flex;gap:10px;align-items:flex-start}
.band li b{font-family:var(--serif);font-weight:400;font-size:18px;min-width:30px;color:var(--amber)}
/* stats */
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-top:28px}
.stat{background:var(--amber-tint);border-radius:var(--r);padding:22px}
.stat .num{font-size:34px}
.stat span{display:block;font-size:14px;margin-top:6px}
.tag{display:inline-block;margin-top:10px;background:var(--green);color:var(--ink);font-size:12px;font-weight:700;letter-spacing:.06em;border-radius:999px;padding:3px 10px}
/* team */
.team{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;margin-top:28px}
.member{background:#fff;border-radius:var(--r);overflow:hidden;border:1px solid var(--line);display:flex;flex-direction:column}
/* Her headshots are transparent cut-outs, so the green tint behind them IS the
   backdrop — do not composite them onto white. object-position sits the crop on
   the face rather than the middle of the body. */
.member .pic{background:linear-gradient(160deg,var(--green-tint),var(--green));min-height:240px;position:relative;overflow:hidden}
/* CONTAIN, not cover. These are full-length transparent cut-outs: cover crops a
   tall figure to a band across the eyes. Contained and sat on the bottom edge,
   each one stands on the green panel and reads as a portrait. */
.member .pic img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;object-position:50% 100%;display:block;padding:10px 10px 0}
/* The founder card runs photo-beside-text on a wide screen. It used to carry
   this as an inline style, which no media query could reach, so on a phone the
   bio was squeezed into a ~150px column beside a 220px photo. */
.member.wide{display:grid;grid-template-columns:220px 1fr}
.member .body{padding:20px 22px 22px}
.member .role{font-weight:700;font-size:13px;letter-spacing:.04em;display:block;margin-top:2px}
.member p{font-size:15px;margin-top:8px}
.member .btn{margin-top:14px;align-self:flex-start}
/* A full-width photograph used as a band between sections.
   ⚠ NOT .band — that is already the black GP callout above, and reusing the
   name gave it aspect-ratio:21/8 with overflow:hidden, which crops it. */
.photoband{border-radius:var(--r);overflow:hidden;margin-top:28px;aspect-ratio:21/8;background:var(--green-tint)}
.photoband img{width:100%;height:100%;object-fit:cover;display:block}
@media (max-width:700px){.photoband{aspect-ratio:16/10}}
@media (max-width:760px){.member.wide{grid-template-columns:1fr}.member.wide .pic{min-height:300px}}

/* generic page */
.page-hero{background:linear-gradient(180deg,#fff,var(--green-tint));padding:48px 0 40px}
.page-hero .lead{margin-top:12px}
.two{display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,1fr);gap:28px;align-items:start}
.list{list-style:none;padding:0;margin:0;display:grid;gap:10px}
.list li{display:flex;gap:12px;align-items:flex-start;padding:12px 14px;border:1px solid var(--line);border-radius:12px;background:#fff}
.list li b{color:var(--ink-strong);font-weight:600}
.tick{color:var(--green);font-weight:700;flex:0 0 auto}
.panel{background:var(--amber-tint);border-radius:var(--r);padding:20px 22px}
.panel h3{margin-bottom:6px}
.scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
.scroll table{min-width:640px}
table{width:100%;border-collapse:collapse;font-size:15px;margin-top:14px}
th,td{text-align:left;padding:12px 10px;border-bottom:1px solid var(--line);vertical-align:top}
th{font-size:12px;letter-spacing:.1em;text-transform:uppercase;font-weight:700}
td b{font-family:var(--serif);font-weight:400;font-size:20px;color:var(--ink-strong)}
.faq details{border-bottom:1px solid var(--line);padding:14px 0}
.faq summary{cursor:pointer;font-weight:600;font-size:16px;list-style:none;display:flex;justify-content:space-between;gap:12px}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";font-family:var(--serif);font-size:22px;color:var(--amber);line-height:1}
.faq details[open] summary::after{content:"–"}
.faq p{margin-top:8px;font-size:15px;max-width:70ch}
.grid3{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-top:20px}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-top:20px}
.clinic{border:1px solid var(--line);border-radius:12px;padding:14px 16px;background:#fff}
.clinic b{display:block;font-weight:600;color:var(--ink-strong)}
.clinic span{font-size:14px}
.resource{display:flex;justify-content:space-between;gap:12px;align-items:center;border:1px solid var(--line);border-radius:12px;padding:12px 14px;background:#fff}
.resource b{font-weight:600;color:var(--ink-strong);display:block}
.resource span{font-size:14px}
/* forms */
form{display:grid;gap:14px}
label{display:grid;gap:6px;font-size:14px;font-weight:600}
input,select,textarea{font:inherit;font-size:16px;padding:12px 14px;border:1.5px solid var(--line-soft);border-radius:12px;background:#fff;color:var(--ink-strong);width:100%;min-height:48px}
textarea{min-height:110px;resize:vertical}
.row{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.row3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:10px}
.err{color:var(--error);font-size:13px;font-weight:600;display:none}
.invalid input,.invalid select{border-color:var(--error)}
.invalid .err{display:block}
.help{font-size:13px;font-weight:400}
/* booking funnel */
 /* ⚠ align-items MATTERS HERE. The pills are buttons inside flex <li>s; leave
    the default stretch on and a wrapped row lets one pill inflate to the row's
    height — which renders "2 · Appointment" as a large green circle. */
.steps{display:flex;align-items:flex-start;align-content:flex-start;gap:6px;flex-wrap:wrap;margin:0 0 22px;padding:0;list-style:none;counter-reset:s}
/* ⭐ THE PILLS ARE BUTTONS, 19 Sep 2026. A three-step bar that cannot be tapped
   is a label pretending to be navigation — people tap "1 · How" to go back and
   nothing happens. A step not yet reachable is disabled rather than hidden, so
   the bar still reads as a map of the whole thing.
   ⚠ ALL THE PILL STYLING LIVES ON THE BUTTON, NOT THE <li>. Leaving the border
   and the 999px radius on the li while the button sets the height turns each
   step into a large circle on a phone — which is exactly what shipped for about
   ten minutes. The li is now a bare wrapper. */
/* ⛔ NOT .done. There is a global .done{padding:40px 20px} for the finished
   panels elsewhere on the site, and a completed step carrying that class was
   silently inheriting 40px of padding — which is what blew the step bar up into
   giant circles. The step bar uses .step-done, which nothing else claims. */
.steps li{display:flex}
.steps li button{font-size:13px;font-weight:600;font-family:inherit;color:inherit;
 background:#fff;border:1px solid var(--line);border-radius:999px;
 padding:7px 13px;min-height:34px;display:inline-flex;align-items:center;cursor:pointer;
 white-space:nowrap;transition:background .15s,border-color .15s}
.steps li button:hover:not([disabled]){background:var(--green-tint);border-color:var(--green)}
.steps li button[disabled]{cursor:default}
.steps li[aria-current="step"] button{background:var(--green);border-color:var(--green);color:var(--ink-strong)}
.steps li.step-done button{background:var(--green-tint);border-color:transparent}
/* not yet reachable — present, but plainly not a door you can open */
.steps li:not(.step-done):not([aria-current="step"]) button[disabled]{opacity:.5}
/* A real tap target on a phone — 44px, the size a thumb needs. */
@media (max-width:760px){.steps li button{min-height:44px;padding:11px 15px}}
.choice{display:grid;gap:12px}
.choice button{text-align:left;background:#fff;border:1.5px solid var(--line);border-radius:14px;padding:16px 18px;font:inherit;color:var(--ink);cursor:pointer;display:grid;gap:4px;min-height:44px}
.choice button:hover{border-color:var(--green)}
.choice button[aria-pressed="true"]{border-color:var(--green);background:var(--green-tint)}
.choice b{font-weight:600;color:var(--ink-strong);font-size:16px}
.choice small{font-size:14px}
.choice .price{font-family:var(--serif);font-size:18px;color:var(--ink-strong)}
.slots{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin-top:8px}
.slots button{font:inherit;font-weight:600;font-size:14px;padding:10px 6px;border:1.5px solid var(--line);border-radius:10px;background:#fff;cursor:pointer;color:var(--ink);min-height:44px}
.slots button[aria-pressed="true"]{background:var(--green);border-color:var(--green);color:var(--ink-strong)}
.days{display:flex;gap:8px;overflow-x:auto;padding-bottom:6px;margin-top:10px}
.days button{flex:0 0 auto;font:inherit;font-size:13px;font-weight:600;border:1.5px solid var(--line);border-radius:12px;background:#fff;padding:8px 12px;cursor:pointer;color:var(--ink);min-width:70px;min-height:44px}
.days button[aria-pressed="true"]{background:var(--green);border-color:var(--green);color:var(--ink-strong)}
.days button span{display:block;font-weight:400;font-size:12px}
.summary{border:1px solid var(--line);border-radius:var(--r);padding:20px 22px;background:#fff;position:sticky;top:84px}
.summary dl{display:grid;grid-template-columns:auto 1fr;gap:6px 14px;margin:12px 0 0;font-size:15px}
.summary dt{font-weight:700;font-size:12px;letter-spacing:.08em;text-transform:uppercase;padding-top:3px}
.summary dd{margin:0;color:var(--ink-strong)}
.actions{display:flex;gap:10px;flex-wrap:wrap;margin-top:22px}

/* --- booking assistant (mock) --- */
.ai{border:1px solid var(--line);border-radius:16px;padding:18px;background:#fff;margin-top:6px}
.ai-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:14px;color:var(--ink-strong)}
.ai-dot{width:10px;height:10px;border-radius:50%;background:var(--green);flex:0 0 auto}
.ai-tag{font-size:12px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-soft);border:1px solid var(--line);border-radius:999px;padding:3px 9px}
.ai-label{display:block;font-weight:600;font-size:15px;margin:14px 0 6px;color:var(--ink-strong)}
.ai textarea{width:100%;font:inherit;font-size:16px;padding:12px 14px;border:1.5px solid var(--line);border-radius:12px;background:#fff;color:var(--ink);resize:vertical}
.ai textarea:focus{outline:2px solid var(--green);outline-offset:1px;border-color:var(--green)}
.ai-chips{display:flex;gap:8px;flex-wrap:wrap;margin-top:10px}
.ai-chips button{font:inherit;font-size:13px;padding:8px 12px;border-radius:999px;border:1.5px solid var(--line);background:#fff;cursor:pointer;color:var(--ink);min-height:44px}
.ai-chips button:hover{border-color:var(--green)}
.ai-out{margin-top:16px;border-top:1px solid var(--line);padding-top:16px}
.ai-heard{margin:0 0 8px}
.ai-tags{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:14px}
.ai-tags span{font-size:13px;font-weight:600;background:rgba(190,219,77,.26);border-radius:999px;padding:5px 11px;color:var(--ink-strong)}
.ai-card{border-left:3px solid var(--green);padding:2px 0 2px 14px;margin:0 0 14px}
.ai-card b{display:block;color:var(--ink-strong);margin-bottom:4px}
.ai-card p{margin:0 0 6px;font-size:15px}
.ai-why{margin:0;font-size:15px}
/* ⚠ 15px, NOT 13px, 20 Sep 2026 (items 12 and 15). This carries the phone
   number, which is the escape hatch for anyone the assistant is not helping —
   the last thing that should be set in the smallest type on the page. */
.ai-foot{margin:14px 0 0;font-size:15px;color:var(--ink-soft);line-height:1.5}
/* ⚠ AMBER, NOT GREEN, 20 Sep 2026 (item 14). Green is the colour of every
   button, pill and underline on this page, so the one word meant to single a
   card out was the least distinguishable thing on it. */
.sugg{font-size:11px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;background:var(--amber);color:#3a2a00;border-radius:999px;padding:2px 8px;vertical-align:2px}
.quiz{border:1px solid var(--line);border-radius:14px;padding:16px 18px;background:#fff;margin-top:14px}
.quiz .q{font-weight:600;color:var(--ink-strong);margin-top:12px;font-size:15px}
.quiz .q:first-of-type{margin-top:0}
.quiz .opts{display:flex;gap:8px;flex-wrap:wrap;margin-top:8px}
.quiz .opts button{font:inherit;font-size:13px;padding:8px 12px;border-radius:999px;border:1.5px solid var(--line);background:#fff;cursor:pointer;color:var(--ink);min-height:36px}
.quiz .opts button[aria-pressed="true"]{background:var(--green);border-color:var(--green);color:var(--ink-strong)}
.reco{margin-top:14px;padding:12px 14px;border-radius:12px;background:var(--amber-tint);font-size:15px}
.avail{color:var(--ink-strong)}
/* Spinner shown beside any “Checking availability…” line. Sized in em so the
   same element works next to a 34px serif h2 and a 14px caption; it borrows the
   surrounding colour, so it needs no variant per background. Reduced motion
   stops it spinning rather than hiding it — the ring still reads as "busy". */
.spin{display:inline-block;width:.85em;height:.85em;margin-left:.5em;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;vertical-align:-.08em;opacity:.55;animation:spin .7s linear infinite}
h2 .spin{width:.6em;height:.6em;border-width:3px;margin-left:.35em}
@keyframes spin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.spin{animation:none}}
.skel{display:grid;gap:10px;margin-top:18px}
.skel span{display:block;height:56px;border-radius:14px;background:linear-gradient(90deg,var(--green-tint),rgba(0,0,0,.04),var(--green-tint));background-size:200% 100%;animation:sh 1.2s linear infinite}
@keyframes sh{from{background-position:200% 0}to{background-position:-200% 0}}
@media (prefers-reduced-motion:reduce){.skel span{animation:none}}
.avail-first{margin-top:18px;background:var(--green-tint)}
.big-when{font-family:var(--serif);font-size:clamp(26px,3.4vw,34px);color:var(--ink-strong);line-height:1.15;margin-top:2px}
/* ⚠ THE OLD .slotlist/.slotlist li GRID BLOCK THAT USED TO LIVE HERE IS GONE,
   21 Sep 2026. It predated .slotrow and matched no element (.slotlist wrapped
   .slotrow <div>s, never a bare <li>) — dead until item 4 below turned
   .slotlist back into a real <ul>, at which point it would have started
   fighting the rules that actually style these rows. See item 4's block,
   further down this file, next to .slothead. */
.choice small b.avail{font-weight:700}
.done{text-align:center;padding:40px 20px}
.done .big{font-family:var(--serif);font-size:44px;color:var(--ink-strong)}
/* footer */
footer{background:var(--black);color:#fff;padding:44px 0 32px;margin-top:64px}
footer .in{display:grid;grid-template-columns:1.4fr 1fr 1fr 1fr 1fr;gap:28px;font-size:14px}
footer h4{color:#fff;margin:0 0 10px;font-size:15px}
footer a,footer p,footer span{color:rgba(255,255,255,.82);display:block;margin:4px 0;text-decoration:none}
footer a:hover{color:#fff}
footer .logo img{filter:brightness(0) invert(1)}
footer .fine{grid-column:1/-1;border-top:1px solid rgba(255,255,255,.18);padding-top:16px;font-size:13px;color:rgba(255,255,255,.65)}
/* motion */
.reveal{opacity:1;transform:none}
@media (prefers-reduced-motion:no-preference){.reveal{transition:opacity .5s,transform .5s}.reveal.pre{opacity:0;transform:translateY(14px)}}
/* responsive */
@media (max-width:980px){.cards,.stats{grid-template-columns:1fr 1fr}.team{grid-template-columns:1fr}.grid3{grid-template-columns:1fr 1fr}}
@media (max-width:1024px){
 .links{display:none}.burger{display:block}
 .menu.open{display:block;border-top:1px solid var(--line);background:#fff}.menu ul{list-style:none;margin:0;padding:8px 18px 14px;display:grid;gap:2px}.menu a{display:block;padding:12px 4px;text-decoration:none;font-weight:600;color:var(--ink);border-bottom:1px solid var(--line)}
}
@media (max-width:760px){
 .btn.sm{min-height:44px}
 .panel[style*="grid-template-columns"]{grid-template-columns:1fr!important}
 #pd-cols aside{order:-1}
 section{padding:44px 0}.in{padding:0 18px}
 .hero{padding:0;min-height:min(86vh,620px)}.hero .in{grid-template-columns:1fr;padding-top:96px;padding-bottom:72px}.hero::after{bottom:-50px;height:110px}.frost{padding:0}
 .doors,.cards,.stats,.two,.grid2,.grid3,.row,.band{grid-template-columns:1fr}.doors{margin-top:20px}.band{padding:28px 22px}
 .slots{grid-template-columns:repeat(3,1fr)}.summary{position:static}
 footer .in{grid-template-columns:1fr 1fr}
}
@media (max-width:420px){.row3{grid-template-columns:1fr 1fr 1fr}footer .in{grid-template-columns:1fr}}
/* shop */
/* Shown when the Storefront API could not be reached and the page is falling
   back to the frozen catalogue in worker/index.js. A wrong price is worse than
   a slow page, so say so rather than let the visitor assume. */
.stale{background:var(--amber-tint);border-radius:8px;padding:8px 12px;font-size:13px;font-weight:700;margin:0 0 14px}
.products{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;margin-top:28px}
.product{background:#fff;border-radius:var(--r);border:1px solid var(--line);overflow:hidden;display:flex;flex-direction:column;text-decoration:none;color:var(--ink)}
.product:hover{border-color:var(--green)}
.pimg{min-height:210px;position:relative;overflow:hidden;background:linear-gradient(160deg,var(--green-tint),var(--green))}
/* A pack shot is on white, so it beats the tint — name every variant or the
   two-class gradients below out-specify this rule and the white pouch sits on
   an amber wash. */
.pimg:has(img),.pimg.gut:has(img),.pimg.green:has(img){background:#fff}
.pimg.gut{background:linear-gradient(160deg,var(--amber-tint),var(--amber))}
.pimg.green{background:linear-gradient(160deg,var(--green-tint),#7fa83a)}
/* Pouches are shot on white, so contain-with-padding, never cover. The label
   only shows on a product we have no photograph of yet. */
.pimg img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;padding:16px;display:block}
.pimg.thumb img{padding:6px}
.pimg.nophoto::after{content:"Product photo (to be shot)";position:absolute;left:12px;bottom:10px;font-size:12px;color:var(--ink)}
.pimg .badge{position:absolute;top:12px;left:12px;background:var(--black);color:#fff;font-size:12px;font-weight:700;letter-spacing:.06em;border-radius:999px;padding:4px 10px}
.product .body{padding:18px 20px 20px;display:grid;gap:6px}
.product h3{margin:0}
.product .from{font-family:var(--serif);font-size:20px;color:var(--ink-strong)}
.product .sub{font-size:13px;font-weight:700;color:var(--ink)}
.product .ship{font-size:12px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-strong)}
/* The pack label photographed from Shopify's own product gallery — the printed
   panel is the authority on ingredients and nutrition, so the site shows it
   rather than retyping it. */
.labels{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:12px;margin-top:12px}
.label{display:block;border:1px solid var(--line);border-radius:12px;overflow:hidden;background:#fff}
.label:hover{border-color:var(--green)}
.label img{width:100%;height:auto;display:block}
.chips{display:flex;gap:8px;flex-wrap:wrap;margin-top:8px}
.chips button{font:inherit;font-weight:600;font-size:14px;padding:9px 14px;border-radius:999px;border:1.5px solid var(--line);background:#fff;cursor:pointer;color:var(--ink);min-height:44px}
.chips button[aria-pressed="true"]{background:var(--green);border-color:var(--green);color:var(--ink-strong)}
.buybox{border:1px solid var(--line);border-radius:var(--r);padding:22px;background:#fff;position:sticky;top:84px}
.buybox .lbl{font-size:12px;letter-spacing:.1em;text-transform:uppercase;font-weight:700;margin-top:16px;display:block}
.buybox .lbl:first-child{margin-top:0}
.modes{display:grid;gap:10px;margin-top:8px}
.mode{display:grid;grid-template-columns:auto 1fr auto;gap:12px;align-items:start;border:1.5px solid var(--line);border-radius:14px;padding:14px 16px;cursor:pointer;background:#fff}
.mode[aria-pressed="true"]{border-color:var(--green);background:var(--green-tint)}
.mode i{width:18px;height:18px;border-radius:50%;border:2px solid var(--line-soft);margin-top:2px;display:block;position:relative}
.mode[aria-pressed="true"] i{border-color:var(--ink-strong)}
.mode[aria-pressed="true"] i::after{content:"";position:absolute;inset:3px;border-radius:50%;background:var(--ink-strong)}
.mode b{font-weight:600;color:var(--ink-strong);display:block}
.mode small{font-size:13px;display:block;margin-top:2px}
.mode .price{font-family:var(--serif);font-size:20px;color:var(--ink-strong);text-align:right}
.mode .price s{font-size:14px;color:var(--ink);display:block;font-family:var(--sans)}
.mode select{margin-top:8px;min-height:40px;padding:8px 12px;font-size:14px;width:auto}
.qty{display:inline-flex;border:1.5px solid var(--line);border-radius:999px;overflow:hidden;margin-top:8px}
.qty button{font:inherit;font-size:18px;width:44px;min-height:44px;border:0;background:#fff;cursor:pointer;color:var(--ink)}
.qty span{min-width:36px;display:grid;place-items:center;font-weight:700;color:var(--ink-strong)}
.buybox .btn{width:100%;justify-content:center;margin-top:16px}
.added{margin-top:12px;padding:14px 16px;border-radius:14px;background:var(--green-tint);border:1.5px solid var(--green);display:grid;grid-template-columns:auto 1fr;gap:6px 10px;align-items:center;font-size:14px;font-weight:600;color:var(--ink-strong);animation:pop .25s ease-out}.added .btn{grid-column:2;justify-self:start;width:auto;margin-top:4px}.added .more{grid-column:2;font-size:13px;font-weight:600}@keyframes pop{from{transform:translateY(-6px);opacity:0}to{transform:none;opacity:1}}
.trust{list-style:none;padding:0;margin:14px 0 0;display:grid;gap:6px;font-size:13px}
.trust li{display:flex;gap:8px;align-items:center}
.toast{position:fixed;left:50%;bottom:24px;transform:translateX(-50%);background:var(--black);color:#fff;padding:12px 18px;border-radius:999px;font-size:14px;z-index:70;display:flex;gap:14px;align-items:center;box-shadow:0 12px 30px -10px rgba(0,0,0,.5)}
.toast a{color:var(--green);font-weight:700;text-decoration:none}
.cartpill{display:inline-flex;align-items:center;gap:6px;font-weight:700!important;padding:6px 12px!important;border:1.5px solid var(--line);border-radius:999px}
/* ⭐ THE MOBILE CART LINK HAD NO BADGE AT ALL, 21 Sep 2026 (item 7). The count
   only got its green pill via ".cartpill em", and the mobile burger menu's
   cart row never carries that class — it's a plain full-width list link, not
   the compact nav pill. The "0" was rendering as bare italic text, which read
   as a badge that had lost its background — easy to mistake for cropping.
   Both links share the [data-cartlink] attribute, so scoping the badge to
   that instead gives the mobile row the same green count badge without
   forcing the desktop pill's border/padding onto a full-width row. */
[data-cartlink] em{font-style:normal;background:var(--green);color:var(--ink-strong);border-radius:999px;padding:0 8px;font-size:12px;min-width:20px;text-align:center;display:inline-block}
.line-item{display:grid;grid-template-columns:72px 1fr auto;gap:14px;align-items:center;padding:14px 0;border-bottom:1px solid var(--line)}
.line-item .thumb{height:72px;border-radius:12px}
.line-item b{font-weight:600;color:var(--ink-strong);display:block}
.line-item small{display:block;font-size:13px}
.line-item .rm{font:inherit;font-size:13px;font-weight:600;background:none;border:0;color:var(--ink);cursor:pointer;text-decoration:underline;padding:6px 0;min-height:32px}
.line-item .amt{font-family:var(--serif);font-size:20px;color:var(--ink-strong);text-align:right}.line-item .amt small{display:block;font-size:12px}
.totals{display:grid;grid-template-columns:1fr auto;gap:8px 20px;font-size:15px;margin-top:14px}
.totals .big{font-family:var(--serif);font-size:24px;color:var(--ink-strong)}
.express{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-top:12px}
.express button{font:inherit;font-weight:700;font-size:14px;min-height:46px;border-radius:12px;border:0;color:#fff;cursor:pointer}
.express .shop{background:#5a31f4}.express .apple{background:#000}.express .google{background:#3c4043}
.or{display:flex;align-items:center;gap:12px;font-size:13px;margin:16px 0 4px}
.or::before,.or::after{content:"";flex:1;border-top:1px solid var(--line)}
.shopify-note{font-size:12px;display:flex;gap:6px;align-items:center;margin-top:12px}
.shopify-note i{width:14px;height:14px;border-radius:4px;background:#95bf47;display:inline-block}
.subcard{border:1px solid var(--line);border-radius:var(--r);padding:20px 22px;background:#fff;display:grid;gap:10px}
.subcard .status{display:inline-block;font-size:12px;font-weight:700;letter-spacing:.06em;border-radius:999px;padding:3px 10px;background:var(--green);color:var(--ink-strong)}
.subcard .status.paused{background:var(--amber)}
.subcard .status.cancelled{background:var(--line)}
.subcard dl{display:grid;grid-template-columns:auto 1fr;gap:6px 16px;margin:0;font-size:15px}
.subcard dt{font-weight:700;font-size:12px;letter-spacing:.08em;text-transform:uppercase;padding-top:3px}
.subcard dd{margin:0;color:var(--ink-strong)}
.subcard .actions{margin-top:8px}
.subcard .actions .btn{min-height:44px}
.msg{padding:10px 14px;border-radius:12px;background:var(--amber-tint);font-size:14px}
.steps3{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-top:20px}
@media (max-width:980px){.products{grid-template-columns:1fr 1fr}}
@media (max-width:760px){.products,.steps3,.express{grid-template-columns:1fr}.buybox{position:static}.line-item{grid-template-columns:56px 1fr auto}.line-item .thumb{height:56px}}
/* image lightbox — same window, closes on the cross, the backdrop or Escape */
.lb{position:fixed;inset:0;z-index:90;background:rgba(0,0,0,.84);display:grid;place-items:center;padding:24px;cursor:zoom-out}
.lb img{max-width:min(1100px,92vw);max-height:86vh;width:auto;height:auto;display:block;border-radius:12px;background:#fff;cursor:auto}
.lb-x{position:absolute;top:14px;right:14px;width:44px;height:44px;min-height:44px;border:0;border-radius:50%;background:#fff;color:var(--ink-strong);font-size:26px;line-height:1;cursor:pointer;display:grid;place-items:center}
.lb-x:hover{background:var(--green)}
.label{cursor:zoom-in}
[hidden]{display:none!important}
.sr{position:absolute;left:-9999px}

@media (prefers-reduced-motion:reduce){.hero .photo video{display:none}}

/* ---------- The in-chat booking run (16 Sep 2026) ----------
   Sits inside the assistant panel, after the thread. It is deliberately quieter
   than the tiles it replaces: same green as the rest of the funnel, but no card
   shadow, so it reads as the conversation continuing rather than a new widget. */
.ai-book{margin-top:16px;border-top:1px solid var(--line);padding-top:16px}
/* ⭐ A BUTTON SINCE 18 SEP 2026 — it always looked like a card, so it now
   behaves like one and reopens the length chooser. Reset the UA button styling
   (font, alignment, width) or it renders as a squat grey control. */
.ai-bookhead{display:flex;align-items:baseline;flex-wrap:wrap;gap:6px 12px;margin-bottom:10px;
 width:100%;text-align:left;font:inherit;color:inherit;background:none;cursor:pointer;
 border:1px solid transparent;border-radius:10px;padding:8px 10px;margin-left:-10px;margin-right:-10px;
 transition:background .15s,border-color .15s}
.ai-bookhead b{flex:1 1 auto;min-width:0}
/* ⭐ IT IS GREEN BECAUSE IT IS CHOSEN, NOT BECAUSE A MOUSE IS OVER IT — 20 Sep
   2026 (item 5). This row states the appointment the patient has settled on, so
   it reads as a chosen thing at all times; hover just deepens it. On a phone
   there is no hover at all, so the old rule meant the row never looked
   selected there. */
.ai-bookhead{background:var(--green-tint);border-color:var(--line)}
.ai-bookhead:hover,.ai-bookhead:focus-visible{background:var(--green);border-color:var(--green)}
.ai-bookhead b{font-weight:600;color:var(--ink-strong);font-size:16px}
.ai-bookhead .price{font-family:var(--serif);font-size:18px;color:var(--ink-strong);white-space:nowrap}
/* The affordance. Small and quiet — the whole row is the target, not this
   word. It stays visible on a phone: the phone is where the row was tapped
   with nothing happening, so hiding the one hint there defeats the fix. */
.ai-bookhead .chg{font-size:12px;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-soft);
 border:1px solid var(--line);border-radius:999px;padding:3px 9px;white-space:nowrap;margin-left:auto}
/* The route the run is working with, shown instead of re-asking a question the
   patient already answered in step 1. Quiet, one line, always changeable. */
.ai-route{margin:-4px 0 12px;font-size:13px;color:var(--ink-soft)}
.ai-q{margin:0 0 12px;font-size:15px;color:var(--ink-strong)}
.ai-q b{font-weight:700}
.choice.sm{gap:8px}
/* The gap column must never wrap onto two lines on a phone — a price broken
   across lines reads as two numbers. */
.choice .price{white-space:nowrap}
.choice.sm button{padding:12px 14px;border-radius:12px}
.choice.sm b{font-size:15px}
/* Times are a wrap, not a 3-up grid: on a phone two per row is the most that
   stays tappable, and the count varies with what Halaxy returns. */
.slotpick{display:flex;flex-wrap:wrap;gap:8px}
.slotpick button{flex:1 1 140px;min-height:44px;text-align:left;background:#fff;border:1.5px solid var(--line);border-radius:12px;padding:10px 12px;font:inherit;color:var(--ink);cursor:pointer;display:grid;gap:2px}
.slotpick button:hover{border-color:var(--green)}
.slotpick b{display:block;font-weight:600;color:var(--ink-strong);font-size:14px}
.slotpick span{font-size:14px;color:var(--ink-soft)}
.ai-alt{margin:12px 0 0;font-size:14px;color:var(--ink-soft)}
.ai-alt.big{font-size:15px;color:var(--ink)}
.linkish{background:none;border:0;padding:0;font:inherit;font-size:14px;color:var(--ink-strong);text-decoration:underline;cursor:pointer}
.linkish:hover{color:var(--green-deep,var(--ink-strong))}

/* ---------- Appointment cards (17 Sep 2026) ----------
   Angeline's own booking site put the badge above the card, the fees behind a
   toggle and the longest option first. The card is a DIV wrapping a button,
   because a <details> cannot live inside a <button> and the fees toggle has to
   be operable without selecting the appointment. */
.tiers{display:grid;gap:26px;margin-top:10px}
.tier{position:relative;border:1.5px solid var(--line);border-radius:14px;background:#fff}
.tier.on{border-color:var(--green);background:var(--green-tint)}
/* The badge straddles the top edge, so it needs room above every card — hence
   the generous grid gap rather than a margin that would collapse. */
.tier-badge{position:absolute;top:-13px;right:16px;max-width:calc(100% - 32px);
 font-size:11px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
 background:var(--green);color:#1d2b0a;border-radius:999px;padding:5px 12px;line-height:1.3}
.tier.sug .tier-badge{background:var(--amber);color:#3a2a00}
.tier-pick{display:grid;gap:9px;width:100%;text-align:left;background:none;border:0;
 font:inherit;color:var(--ink);cursor:pointer;padding:20px 18px 14px;min-height:44px}
.tier-h{font-family:var(--sans);font-weight:600;font-size:17px;color:var(--ink-strong);line-height:1.25}
.tier-lead,.tier-more{font-size:15px;line-height:1.5}
.tier-more{color:var(--ink-soft)}
.tier-elig{font-size:14px;font-weight:600;color:var(--ink-strong)}
.tier-note{font-size:14px;background:rgba(0,0,0,.035);border-radius:8px;padding:9px 11px;line-height:1.45}
/* ⭐ THE FOOTER ROW, 19 Sep 2026 — fees on the left, an explicit Select on the
   right. The card was one big button, which looks like nothing; this is the
   affordance that says it can be chosen. */
.tier-foot{display:flex;align-items:center;justify-content:space-between;gap:14px;
 border-top:1px solid var(--line);margin:0 18px;padding:4px 0 12px;flex-wrap:wrap}
.tier-foot .tier-fees{border-top:0;margin:0;padding:0;flex:1 1 auto;min-width:0}
.tier-select{flex:0 0 auto;white-space:nowrap}
.tier.on .tier-select{background:var(--ink-strong);border-color:var(--ink-strong);color:#fff}
/* A length this location cannot sell: shown, explained, never selectable. */
.tier.off{background:rgba(0,0,0,.02);border-style:dashed;color:var(--ink-soft);
 display:grid;gap:8px;padding:16px 18px}
.tier.off .tier-h{color:var(--ink-soft)}
.tier-why{margin:2px 0 0;font-size:14px;font-weight:600;color:var(--ink-strong);line-height:1.45}
/* The collapsed handle the other options fold into once one is chosen. */
.tier-mini{display:flex;align-items:center;gap:12px;width:100%;text-align:left;
 border:1.5px solid var(--line);border-radius:12px;background:#fff;cursor:pointer;
 padding:13px 16px;font:inherit;color:var(--ink-strong);transition:border-color .15s,background .15s}
.tier-mini:hover,.tier-mini:focus-visible{border-color:var(--green);background:var(--green-tint)}
.tier-mini b{font-weight:600;font-size:15px;flex:1 1 auto;min-width:0}
.tier-mini-price{font-family:var(--serif);font-size:15px;white-space:nowrap}
.tier-mini-go{font-size:12px;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-soft);
 border:1px solid var(--line);border-radius:999px;padding:3px 10px;white-space:nowrap}
.tier-mini.off{cursor:default;background:rgba(0,0,0,.02);border-style:dashed;color:var(--ink-soft)}
.tier-mini.off:hover{border-color:var(--line);background:rgba(0,0,0,.02)}
/* ⭐ "BOOK NOW" IS THE BOOKING BUTTON — item 14, redone 21 Sep 2026. It is
   the Halaxy link itself (a .btn.solid), sitting beside "Selected ✓" in the
   chosen card's own .tier-foot row. Only the collapsed (mini) card needs a
   wrapper row. Two dietitians means two links, so the group can wrap. */
.tier-mini-row{display:flex;align-items:center;gap:10px}
.tier-mini-row .tier-mini{width:auto;flex:1 1 auto;min-width:0}
.tier-book{display:flex;flex-wrap:wrap;gap:8px;flex:0 1 auto;min-width:0;max-width:100%}
.tier-booknow{white-space:nowrap}
.tiers:has(.tier-mini){gap:12px}
@media (max-width:420px){
 .tier-mini{flex-wrap:wrap;gap:6px 10px}
 .tier-mini b{flex:1 0 100%}
 .tier-foot .tier-select{width:100%}
 .tier-foot .tier-book,.tier-mini-row .tier-book{width:100%}
 .tier-book .tier-booknow{flex:1 1 auto;justify-content:center}
 .tier-mini-row{flex-wrap:wrap}
}
.tier-fees{border-top:1px solid var(--line);margin:0 18px;padding:0 0 4px}
.tier-fees summary{cursor:pointer;font-weight:600;font-size:14px;padding:11px 0;list-style:none;color:var(--ink-strong)}
.tier-fees summary::-webkit-details-marker{display:none}
.tier-fees summary::after{content:" ▾";color:var(--amber)}
.tier-fees[open] summary::after{content:" ▴"}
.tier-fees p{margin:0 0 12px;font-size:14px;line-height:1.5}
/* Step 3's time list is wider than the assistant's, and each button carries who
   the appointment is with. */
.slotpick.wide button{flex:1 1 170px}
.slotpick em{display:block;font-style:normal;font-size:13px;color:var(--ink-soft);margin-top:2px}
.slotpick button[aria-pressed="true"]{border-color:var(--green);background:var(--green-tint)}
@media (max-width:600px){
 .tiers{gap:24px}
 .tier-pick{padding:20px 15px 12px}
 .tier-fees{margin:0 15px}
 .tier-badge{right:12px;font-size:10px;padding:4px 10px}
}

/* ===== RECIPES (20 Sep 2026) =====
   /nutrition-recipes and the 28 /post/<slug> pages are static HTML written by
   build-recipes.js, not app-shell routes — so these rules have to stand on
   their own: nothing here may depend on a class site.js adds at runtime. */
.rgrid{display:grid;grid-template-columns:repeat(4,1fr);gap:18px;margin:32px 0 8px}
.rtile{display:flex;flex-direction:column;text-decoration:none;border:1px solid var(--line);border-radius:var(--r);overflow:hidden;background:#fff;transition:transform .18s ease,box-shadow .18s ease}
.rtile:hover{transform:translateY(-3px);box-shadow:0 10px 26px rgba(0,0,0,.10)}
.rtile .pic{display:block;aspect-ratio:3/2;background:var(--green-tint)}
.rtile .pic img{width:100%;height:100%;object-fit:cover;display:block}
.rtile .t{display:block;padding:14px 16px 16px;margin-top:auto;font-weight:600;color:var(--ink-strong);line-height:1.3}
.rwrap{padding-top:34px;padding-bottom:8px;max-width:920px}
.rcrumb{font-size:14px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;margin-bottom:14px}
.rcrumb a{color:var(--ink-soft);text-decoration:none;border-bottom:2px solid var(--green)}
.rdate{color:var(--ink-soft);font-size:14px;margin-top:10px}
.rchips{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}
.rchip{background:var(--green-tint);border-radius:999px;padding:5px 14px;font-size:14px}
.rchip b{font-family:var(--serif);font-weight:400;font-size:17px;color:var(--ink-strong)}
.rhero{margin:24px 0 22px;border-radius:var(--r);overflow:hidden;background:var(--green-tint)}
.rhero img{width:100%;height:auto;display:block;aspect-ratio:25/16;object-fit:cover}
.rcols{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.45fr);gap:36px;align-items:start;margin-top:30px}
.rcols h2{font-size:22px;padding-bottom:10px;border-bottom:2px solid var(--green);margin-bottom:14px}
.ring ul{list-style:none;padding:0;margin:0;display:grid;gap:9px}
.ring li{position:relative;padding-left:22px}
.ring li::before{content:"";position:absolute;left:0;top:.62em;width:9px;height:9px;border-radius:50%;background:var(--green)}
.rmeth ol{margin:0;padding-left:1.25em;display:grid;gap:12px}
.rmeth li::marker{font-family:var(--serif);color:var(--ink-strong)}
.rsub{font-size:15px;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-soft);margin:16px 0 8px}
.rnote{margin-top:18px;background:var(--amber-tint);border-radius:12px;padding:14px 16px;font-size:15px}
.rgal{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:14px;margin-top:30px}
.rgal img{width:100%;height:auto;display:block;border-radius:12px;aspect-ratio:4/3;object-fit:cover}
.rcta{display:block;margin:40px 0 56px;text-align:left}
.rcta h2{margin-bottom:10px}
.rcta p{margin-bottom:14px;max-width:62ch}
.rcta p:last-child{margin-bottom:0;display:flex;flex-wrap:wrap;gap:10px}
@media(max-width:980px){.rgrid{grid-template-columns:repeat(3,1fr)}.rcols{grid-template-columns:1fr;gap:26px}}
@media(max-width:700px){.rgrid{grid-template-columns:repeat(2,1fr);gap:14px}.rcta{padding:28px 22px}}
@media(max-width:420px){.rgrid{grid-template-columns:1fr}}
/* Article body. The recipe renderer lays itself out in two columns; an article
   is one measure of prose, so it gets its own block — shared page furniture,
   different insides. See build-posts.js. */
/* ⚠ A BARE URL WILL PUSH A PHONE SIDEWAYS. The dirty-dozen post ends in ten
   citations, each an unbroken URL — one of them made that page 142px wider than
   the screen. Every one of these posts is somebody else's writing that we are
   republishing verbatim, so the CSS has to cope with whatever is in it rather
   than the copy being tidied to fit. */
/* ⭐ FULL WIDTH, NOT 68ch — Tristan, 21 Sep 2026 (item 1). This used to cap the
   body at a reading-column width regardless of what sat above it, so a recipe's
   ingredients/method (in .rcols, up to 920px via .rwrap) or an article's own
   hero were full width and the text immediately below them stepped in sharply
   — visibly narrower on both blog and recipe pages. .rwrap already sets the
   page's real max-width (920px); .prose now simply fills it. */
.prose{max-width:100%;margin-top:22px;overflow-wrap:anywhere}
.prose a{overflow-wrap:anywhere}
.prose h2{font-size:26px;margin:32px 0 10px}
.prose h3{font-size:19px;margin:24px 0 8px}
.prose p{margin:0 0 14px}
.prose ul,.prose ol{margin:0 0 16px;padding-left:1.3em;display:grid;gap:8px}
.prose blockquote{margin:20px 0;padding:14px 18px;border-left:3px solid var(--green);background:var(--green-tint);border-radius:0 12px 12px 0}
.prose figure{margin:24px 0}
.prose figure img{width:100%;height:auto;display:block;border-radius:12px}
.prose figcaption{margin-top:8px;font-size:14px;color:var(--ink-soft)}

/* ===== AVAILABLE TIMES AND THE HANDOFF (20 Sep 2026) =====
   ⛔ THESE ARE NOT BUTTONS AND MUST NOT LOOK LIKE ONE. The times are shown to
   answer "how soon can I be seen"; the booking itself happens on Halaxy, which
   cannot be told which time was tapped. A tile that looks pressable and books
   nothing is exactly the complaint that started this (item 2).
   ⭐ A PLAIN BULLET LIST, NOT TILES — Tristan, 21 Sep 2026 (item 4): "The
   appointment times look clickable, but can't be. I think they should just
   be formatted into a paragraph bullet list." The green rounded tiles above
   read as pressable cards; a real <ul><li> with a bullet marker reads as what
   it is — information, not a control. The markup is a genuine <ul>/<li> now
   (see bookOut() callers in 3-booking.js), so this styles that directly
   rather than re-flattening it back into tiles. */
.slothead{margin:16px 0 8px;font-weight:600;color:var(--ink-strong)}
.slotlist{list-style:disc;margin:0;padding-left:1.3em;display:grid;gap:6px}
.slotlist li{font-size:15px;color:var(--ink)}
.slotlist b{font-weight:600;color:var(--ink-strong)}
.slotlist span{margin-left:4px}
.slotlist em{font-style:normal;font-size:13px;color:var(--ink-soft);margin-left:4px}
.handoff{margin-top:18px;border:1px solid var(--line);border-left:3px solid var(--green);border-radius:0 12px 12px 0;padding:16px 18px}
.handoff p{font-size:15px}
.handoff .actions{margin-top:14px}
/* A length this place does not sell. A statement of fact, not an error — the
   card explaining where it IS available sits directly below. */
.moved{margin:0 0 6px;font-size:14px;color:var(--ink-soft);background:var(--amber-tint);border-radius:10px;padding:8px 12px}
/* Everything a recipe carried after its method — Suggestions, Tips, Nutritional
   value. Same prose rules, just set apart from the two-column half above it.
   ⭐ FULL WIDTH, NOT 68ch — see .prose above; this is the other half of item 1. */
.rafter{margin-top:34px;padding-top:26px;border-top:1px solid var(--line);max-width:100%}
.rafter h2{font-size:22px}

/* ⭐ WHY THIS FILE EXISTS (23 Sep 2026). src/site.css is 57 KB — past what a
   chat can rewrite in one call, which is the same wall src/site.js hit on
   21 Sep and the reason it became src/js/*.js. So the stylesheet works the same
   way now: site.css first, then every file in src/css in filename order,
   appended into the one <style> block build.js writes. Nothing about the
   cascade changes; a rule here simply comes last, which is what lets this file
   adjust one that site.css already set.
   ⚠ Number a new part into place (2-…, 3-…) and keep each under ~40 KB. */

/* ⭐ THE FEES TABLE STACKS ON A PHONE. Six columns need 640px, so on a 390px
   screen the table scrolled sideways INSIDE the page — and the two columns off
   the right-hand edge were "without a referral" and "best for", the two a
   patient without a care plan most needs. The pre-launch check found it.
   Squeezing the columns instead just made every row half a screen tall, so
   each appointment becomes its own card, every figure labelled.
   ⚠ .scroll .feetable, not .feetable — `.scroll table{min-width:640px}` in
   site.css is a class AND a type, so it outranks a bare class and the table
   went on being 640px wide with the cards drawn inside it. */
@media (max-width:760px){
 .scroll.feewrap{overflow-x:visible}
 .scroll .feetable{min-width:0;display:block;margin-top:6px}
 .feetable thead{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
 .feetable tbody,.feetable tr,.feetable td{display:block;width:auto}
 .feetable tr{border:1px solid var(--line);border-radius:var(--r);padding:14px 16px;margin-top:12px;background:#fff}
 .feetable td{border:0;padding:6px 0;display:flex;gap:14px;align-items:baseline;justify-content:space-between;text-align:right}
 /* ⚠ THE LABELS COME FROM COLUMN POSITION, not from the cell, because these
    rows are written two ways: the static fallback in src/site.html and, once
    Halaxy answers, fillFees() in src/js/1-core.js. Only the first carries
    data-label, so a position rule is the one thing true of both.
    KEEP THESE IN THE SAME ORDER AS THE <th> ROW in src/site.html —
    test/mobile_ui.py reads the headings and fails if the two ever disagree. */
 .feetable td::before{flex:0 0 auto;font-size:12px;letter-spacing:.08em;text-transform:uppercase;font-weight:700;color:var(--ink)}
 .feetable td:nth-child(2)::before{content:"Length"}
 .feetable td:nth-child(3)::before{content:"With a GP referral"}
 .feetable td:nth-child(4)::before{content:"You pay with Medicare"}
 .feetable td:nth-child(5)::before{content:"Without a referral"}
 .feetable td:nth-child(6)::before{content:"Best for"}
 .feetable td:nth-child(1){display:block;padding:0 0 2px;text-align:left}
 .feetable td:nth-child(6){display:block;border-top:1px solid var(--line);margin-top:8px;padding-top:10px;text-align:left}
 .feetable td:nth-child(6)::before{display:block;margin-bottom:4px}
 .feetable td>b{font-size:18px}
 .feetable td:nth-child(1)>b{font-size:22px}
}

/* ⚠ 44px, NOT 32. The cart's Remove was a 13px underlined word with 6px of
   padding — a 32px-high target, under every phone guideline, sitting right
   beside the quantity stepper, so a near miss changes the order instead of
   removing the line. This overrides .line-item .rm in site.css. */
.line-item .rm{padding:11px 10px;min-height:44px;margin-left:-10px;border-radius:10px}
.line-item .rm:hover{background:rgba(0,0,0,.04)}

/* ⭐ DOWNLOAD LINKS ON A RESOURCE CARD, 24 Sep 2026.
   .resource is a space-between flex, so the buttons sit hard right of the
   title. Two of them (the diaries' PDF + Word) still fit on a desktop card.
   ⚠ ON A NARROW PHONE THEY WRAP TO THEIR OWN ROW AND SHARE IT. Left inline
   they squeezed the title to two or three words per line. .btn.sm is already
   lifted to a 44px tap target under 760px in site.css — do not shrink these. */
.resource .rdl{display:flex;gap:8px;flex:0 0 auto}
.resource .rdl .btn{white-space:nowrap}
/* ⚠ THE DIARIES SIT THREE TO A ROW AND CARRY TWO BUTTONS EACH. Inline, that
   left about 90px for the title and broke "Food Diary & Blood Sugar Record"
   over three lines. Give their buttons a row of their own at every width. */
.grid3 .resource{flex-wrap:wrap}
.grid3 .resource .rdl{width:100%}
.grid3 .resource .rdl .btn{flex:1 1 0;justify-content:center}
@media (max-width:560px){
 .resource{flex-wrap:wrap}
 .resource .rdl{width:100%}
 .resource .rdl .btn{flex:1 1 0;justify-content:center}
}
