/* Styling for images that replaced <image-slot> at build time.
 *
 * image-slot is an authoring element that cannot ship: it renders inside shadow
 * DOM, so a crawler or a social preview sees nothing. The build swaps each one
 * for a real <img>.
 *
 * But image-slot also did the sizing. Its :host was width:100%/height:100% with
 * aspect-ratio 3/2, its .frame was position:absolute/inset:0/overflow:hidden,
 * and it positioned the img by script to produce a cover crop. A bare <img>
 * inherits none of that, so the first build rendered every hero letterboxed and
 * stacked instead of filling its panel.
 *
 * This is the whole of the difference. mbclinic.css stays byte-identical to
 * Design's; this file is loaded after it. See IMPLEMENTATION.md section 11.2. */

img.ds-img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    /* image-slot's :host declared aspect-ratio 3/2. Where a container has no
     * definite height, height:100% resolves to auto and the image would fall
     * back to its own natural shape — which is why the shop product grid did
     * not match. With a definite height this is ignored, exactly as it was. */
    aspect-ratio: 3 / 2;
}

/* Where nothing else constrains the box, match image-slot's own default. */
.hero-media img.ds-img { min-height: 420px; }

/* --- Resource guides -------------------------------------------------------
 * These are A4 print documents. Design wraps them in <doc-page>, which sizes
 * each sheet from its shadow DOM; stripping that element (it cannot ship) left
 * the sections with no width at all.
 *
 * DELIBERATE DEPARTURE: Design renders them at a fixed 850px. Reproducing that
 * would make a guide unreadable on a phone, and these are written for parents,
 * who will mostly be on one. So: A4 proportions up to 850px, fluid below.
 * The comparison harness will always report a height difference on guides; that
 * is this decision, not a defect. */

.doc-pages .page {
    width: 100%;
    max-width: 850px;
    margin: 0 auto clamp(16px, 3vw, 32px);
    padding: clamp(24px, 5vw, 64px);
    box-sizing: border-box;
    background: #fff;
}
.doc-pages { background: var(--paper-2, #f4f2ee); padding: clamp(16px, 4vw, 48px) 0; }
.doc-pages .page img { max-width: 100%; height: auto; }

/* Guide covers have no src: Design left them as empty slots with the author's
 * own note as the placeholder text. Hide the broken image rather than ship it;
 * the missing covers are tracked separately. */
.doc-pages img[src=""] { display: none; }

/* Cookie consent bar.
 *
 * Not in Design's export, because Design's export has no analytics in it. The
 * site was built with no measurement at all: no GA4, no Metricool, nothing.
 * Adding them means asking first, so there has to be somewhere to ask.
 *
 * Uses Design's own tokens and .btn classes so it reads as part of the site
 * rather than a bolted-on third-party widget. Sits at the bottom, does not
 * cover content on a phone, and never blocks the page: a visitor who ignores
 * it entirely is simply never tracked, which is the correct default. */
/* NAMED .cookie-bar, NOT .consent (14 Sep 2026).
 *
 * Design already uses .consent for the consent CHECKBOX ROW on the contact form
 * and styles it display:grid in mbclinic.css. This bar was called .consent too,
 * so Design's form-row rule was laying out the cookie banner: one element, two
 * unrelated components' styles.
 *
 * mbclinic.css is refreshed from the snapshot on every port, so that made the
 * banner's appearance hostage to an unrelated change in Design. A distinct name
 * is the durable fix; tools/check-banner.mjs fails the build if the collision
 * comes back. */
.cookie-bar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 60;
  background: var(--paper, #fff);
  border-top: 1px solid var(--line, #e5e5e5);
  box-shadow: 0 -6px 24px rgba(0, 0, 0, .07);
}
.cookie-bar-inner {
  max-width: 1100px;
  margin: 0 auto;
  padding: var(--s-4, 16px) var(--gut, 24px);
  display: flex;
  align-items: center;
  gap: var(--s-5, 20px);
  flex-wrap: wrap;
}
.cookie-bar-inner p {
  margin: 0;
  flex: 1 1 22rem;
  font-size: .875rem;
  line-height: 1.5;
  color: var(--ink-soft, #555);
}
.cookie-bar-inner a { border-bottom: 1px solid var(--line, #ccc); }
.cookie-bar-actions {
  display: flex;
  gap: var(--s-3, 12px);
  flex: 0 0 auto;
}
.cookie-bar-actions button {
  font: inherit;
  font-size: .875rem;
  padding: .55rem 1.25rem;
  border-radius: 999px;
  border: 1px solid var(--line, #ccc);
  background: transparent;
  color: var(--ink, #111);
  cursor: pointer;
}
.cookie-bar-actions .cookie-accept {
  background: var(--ink, #111);
  border-color: var(--ink, #111);
  color: var(--paper, #fff);
}
.cookie-bar-actions button:focus-visible {
  outline: 2px solid var(--ink, #111);
  outline-offset: 2px;
}
@media (max-width: 40rem) {
  .cookie-bar-inner { padding: var(--s-3, 12px) var(--s-4, 16px); }
  .cookie-bar-actions { width: 100%; }
  .cookie-bar-actions button { flex: 1; }
}

/* Resource download gate.
 *
 * Not in Design's export: Design drew the guides as A4 documents and the site
 * pages around them, but nothing about how a reader asks for the PDF. Built on
 * Design's own tokens and .btn so it reads as part of the site. */
.gate {
  position: fixed; inset: 0; z-index: 80;
  display: none;
  align-items: center; justify-content: center;
  background: rgba(0, 0, 0, .38);
  padding: var(--s-4, 16px);
}
.gate.is-open { display: flex; }
.gate-card {
  background: var(--paper, #fff);
  border: 1px solid var(--line, #e5e5e5);
  max-width: 30rem; width: 100%;
  padding: var(--s-7, 32px);
  position: relative;
  max-height: 90vh; overflow-y: auto;
}
.gate-x {
  position: absolute; top: 10px; right: 14px;
  background: none; border: 0; cursor: pointer;
  font-size: 26px; line-height: 1; color: var(--ink-soft, #666);
}
.gate-card h3 { margin: 4px 0 10px; }
.gate-note { font-size: .875rem; color: var(--ink-soft, #555); line-height: 1.55; margin: 0 0 var(--s-4, 16px); }
.gate-small { font-size: .8125rem; }
.gate-note a, .gate-consent a { border-bottom: 1px solid var(--line, #ccc); }
.gate-form label { display: block; font-size: .8125rem; letter-spacing: .04em; text-transform: uppercase; color: var(--label, #777); margin-bottom: 6px; }
.gate-form input[type="email"] {
  width: 100%; font: inherit; padding: .7rem .8rem;
  border: 1px solid var(--line, #ccc); background: var(--paper, #fff);
  margin-bottom: var(--s-4, 16px);
}
.gate-consent { display: flex; gap: 10px; align-items: flex-start; margin-bottom: var(--s-3, 12px); }
.gate-consent input { margin-top: 3px; flex: 0 0 auto; }
.gate-consent label { text-transform: none; letter-spacing: 0; font-size: .875rem; color: var(--ink-soft, #555); margin: 0; line-height: 1.5; }
.gate-form .btn { width: 100%; justify-content: center; }
.gate-msg { font-size: .875rem; margin: var(--s-3, 12px) 0 0; color: var(--ink-soft, #555); }

/* The two actions on a guide card: download is primary, reading is not hidden.
 *
 * Design built .gcard-cta as the SINGLE action at the foot of a flex COLUMN, so
 * it carries `margin-top: auto` to push itself down and a large `padding-top`
 * for the gap above it. Putting it in a flex ROW next to a link inherited both:
 * the auto margin stopped pinning the actions to the card bottom, and the
 * padding-top pushed the button's text below the link's. They also stopped
 * looking related, because a <button> keeps its native chrome while an <a>
 * does not.
 *
 * So the row takes over the pinning, and the two children are levelled. */
.guide-actions {
  margin-top: auto;
  padding-top: var(--s-5);
  display: flex;
  align-items: baseline;
  gap: var(--s-5);
  flex-wrap: wrap;
}
.guide-actions .gcard-cta,
.guide-actions .link-ul { margin-top: 0; padding-top: 0; }

/* Strip the native button so it reads as Design's own text CTA.
 *
 * Two wrappers, because the 16 Sep 2026 export introduced Design's own
 * .gcard-actions row (which levels its children exactly as .guide-actions does
 * above). The button reset is still ours: a <button> keeps its native chrome
 * whatever the row does, and Design only ever styles anchors here. */
.guide-actions button.gcard-cta,
.gcard-actions button.gcard-cta {
  -webkit-appearance: none;
  appearance: none;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--ink);
  border-radius: 0;
  padding: 0 0 4px;
  cursor: pointer;
  color: var(--ink);
  font-family: var(--sans);
  font-weight: 500;
  font-size: var(--t-xs);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  line-height: inherit;
  white-space: nowrap;
  transition: color .3s, border-color .3s;
}
.guide-actions button.gcard-cta:hover,
.gcard-actions button.gcard-cta:hover { color: var(--stone); border-color: var(--stone); }
.guide-actions button.gcard-cta:focus-visible,
.gcard-actions button.gcard-cta:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.guide-actions .link-ul { font-size: var(--t-xs); }

/* ---------------------------------------------------------------------------
 * Mobile header overflow, and the floating call to action.
 *
 * THE BUG, which is Design's and predates the port. At a 390px viewport the
 * nav needs 424px of content (brand 204 + gap 24 + CTA 128 + gap 24 + burger
 * 44) inside 343px of available width. The burger is pushed off the right edge
 * and the whole page scrolls sideways. Measured in Design's own untouched
 * export too: nav 507px there, because "Book a Consultation" is longer than
 * "Get in touch". So on a phone there was no navigation at all.
 *
 * THE FIX solves Andrew's request at the same time. Below 600px the header CTA
 * comes out of the nav, which leaves brand + burger at 272px and fits
 * comfortably with the tagline intact, and the call to action becomes a
 * floating bar that appears once you scroll past the hero. It is more visible
 * there than a small bordered button ever was in a dark header.
 * ------------------------------------------------------------------------- */
@media (max-width: 600px) {
  .nav-cta { display: none; }
}

.mcta {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 55;                 /* under the consent bar (60) and the gate (80) */
  display: none;
  padding: 10px var(--gut, 20px) calc(10px + env(safe-area-inset-bottom, 0px));
  background: rgba(20, 20, 20, .94);
  backdrop-filter: blur(12px);
  border-top: 1px solid rgba(255, 255, 255, .14);
  transform: translateY(110%);
  transition: transform .28s ease;
}
.mcta.is-in { transform: translateY(0); }
.mcta a {
  display: block;
  text-align: center;
  padding: 13px 18px;
  border: 1px solid rgba(255, 255, 255, .5);
  color: #fff;
  font-family: var(--sans);
  font-weight: 500;
  font-size: var(--t-nav, 12px);
  letter-spacing: .16em;
  text-transform: uppercase;
}
@media (max-width: 600px) { .mcta { display: block; } }

/* The consent bar is also fixed to the bottom. While it is up, sit above it
 * rather than under it, or the two overlap and neither is readable. */
body.has-cookie-bar .mcta { bottom: auto; top: auto; }
@media (max-width: 600px) {
  body.has-cookie-bar .mcta { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .mcta { transition: none; }
}

/* Guides related to a blog post.
 *
 * Not in Design's export, because Design never linked posts to guides at all.
 * The post layout picked "related reading" by file order, so the ARFID post,
 * which every ARFID query lands on, offered postnatal nutrition and linked to
 * none of the ten ARFID guides. Roughly 28,000 words sat one category-list
 * link deep from the page carrying the traffic. */
.related--guides { margin-top: var(--s-8, 40px); }
.related--guides .hint {
  font-size: .875rem; color: var(--ink-soft, #555); margin: -4px 0 var(--s-4, 16px);
}
.guide-list { list-style: none; margin: 0; padding: 0; }
.guide-list li {
  padding: var(--s-3, 12px) 0;
  border-bottom: 1px solid var(--line-soft, #eee);
  display: flex; align-items: baseline; gap: var(--s-4, 16px); flex-wrap: wrap;
}
.guide-list li:first-child { border-top: 1px solid var(--line-soft, #eee); }
.guide-list a { font-family: var(--serif); font-size: 1.0625rem; color: var(--ink); }
.guide-list a:hover { color: var(--stone); }
.guide-kind {
  margin-left: auto;
  font-family: var(--sans); font-size: var(--t-xs, 11px);
  letter-spacing: .16em; text-transform: uppercase; color: var(--label, #888);
  white-space: nowrap;
}

/* ---- clickable dropdown headings -------------------------------------
 *
 * "Clinic" and "Resources" used to be inert <span> labels: the panel opened
 * but the heading itself went nowhere, which reads as a broken menu
 * (Andrew, 14 Sep 2026). They are now real links to the overview pages.
 *
 * Design's mbclinic.css styles the trigger as `.nav-item > span`, and that
 * stylesheet is refreshed from the snapshot on every port, so the matching
 * rules for `.nav-item > a` belong here, in ours, where they survive.
 * Selectors mirror lines 93-96 of mbclinic.css; keep them in step if Design
 * restyles the header.
 *
 * :focus-within is why this needs no JavaScript. Design's script binds to a
 * span trigger, finds none, and returns early, so nothing intercepts the
 * click. Hover already opens the panel for a mouse; :focus-within opens it
 * for a keyboard, so tabbing to "Clinic" reveals the pages under it rather
 * than skipping past them. Below 900px `.nav-links` is display:none and the
 * burger menu takes over, so a phone never hits the tap-versus-open problem.
 */
.nav-links > .nav-item > a {
  font-size: var(--t-nav); letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--stone-light, #b9b5ac); line-height: 1;
  display: inline-flex; align-items: center; gap: 4px;
  text-decoration: none; border-bottom: 0;
}
.nav-item:hover > a, .nav-item.is-open > a, .nav-item > a:focus-visible {
  color: var(--stone-light);
}
.nav-item > a.active { color: var(--paper); }
/* Keyboard parity with :hover. Mirrors .nav-item:hover .dropdown. */
.nav-item:focus-within .dropdown {
  opacity: 1; visibility: visible; pointer-events: auto;
  transform: translateX(-50%) translateY(0);
}

/* ---- mobile overflow: covering two Design CSS bugs ---------------------
 *
 * At 390px the homepage was 619px wide and the contact page 408px, so both
 * scrolled sideways under your thumb. Verified as DESIGN's, not the porter's:
 * Design's own homepage measures the same 619px, and its contact page is
 * worse than ours (507px).
 *
 * ONE root cause, two places. A `1fr` grid track is `minmax(auto, 1fr)`, and
 * `auto` floors at min-content, so a track will not shrink below its widest
 * unbreakable content no matter how narrow the screen gets. `minmax(0, 1fr)`
 * removes that floor. This is the standard fix and it changes nothing at any
 * width where the content already fits.
 *
 *   .collab-row  the Professional Registration tiles on the homepage
 *   .consent     the checkbox label on the contact form
 *
 * THESE LIVE HERE, NOT IN mbclinic.css, because that file is Design's and is
 * refreshed from the snapshot on every port: a fix made there is erased by the
 * next export. ported.css is ours and survives.
 *
 * tools/check-mobile.mjs fails the build if any page overflows at 390px, so a
 * future export that reintroduces this, or introduces it somewhere new, is
 * caught rather than shipped.
 *
 * REMOVE THESE once Mel has corrected the tracks in Design. They are harmless
 * duplicates at that point, but a stale override is a thing that hides the
 * next real bug.
 */
.collab-row { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 620px) {
  .collab-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.consent { grid-template-columns: auto minmax(0, 1fr); }

/* The same floor reached through the other door. A grid or flex CHILD defaults
 * to min-width:auto, which is also min-content, so the child refuses to shrink
 * and pushes its track wider than the screen. On the contact page the form's
 * single column computed to 385px inside a 343px parent for exactly this
 * reason. Letting these children shrink is what makes the tracks above work.
 *
 * Scoped to the containers Design uses for layout, not applied globally:
 * min-width:0 everywhere would let genuinely unshrinkable things collapse. */
.split > *, .form-grid > *, .sec-head--row > *, .info-list > * { min-width: 0; }

/* A form control has its own intrinsic width and ignores the grid entirely
 * unless told otherwise. A <select> carrying "A patient (I am a clinician)"
 * is wider than a phone. */
.form-grid input, .form-grid select, .form-grid textarea { max-width: 100%; }

/* Design pins phrases to one line with an inline white-space:nowrap, which no
 * stylesheet can override and which never gets released on a phone. The porter
 * converts those inline styles to this class (transformation 3v) so the intent
 * survives on a wide screen and the text can wrap on a narrow one. */
.nowrap-wide { white-space: nowrap; }
@media (max-width: 620px) {
  .nowrap-wide { white-space: normal; }
}

/* The "Read the paper" link on /publications/. Quiet on purpose: it is an
 * offer to verify the citation, not part of the citation, so it should not
 * compete with the paper's title.
 *
 * The DOI used to be printed beside it in grey. That read as broken, because
 * grey text next to a link looks like a link that does not work (Andrew,
 * 14 Sep 2026). The DOI is now in the ScholarlyArticle markup, which is where
 * a machine looks for it and where it costs the reader nothing. */
.doi-link {
  font-family: var(--sans); font-size: var(--t-xs, 11px);
  letter-spacing: .06em; text-transform: uppercase;
  color: var(--label, #8a8a84); white-space: nowrap;
  border-bottom: 1px solid var(--line, #e6e5e1); padding-bottom: 1px;
}
.doi-link:hover { color: var(--ink); border-bottom-color: var(--ink); }

/* ---- dropdown affordance ------------------------------------------------
 *
 * Design's caret is a 7px "▾" glyph at 70% opacity, which is close to
 * invisible on a dark bar (Andrew, 14 Sep 2026). Two problems: it is too
 * faint to read as an affordance at all, and even when seen it only says a
 * menu EXISTS, never whether it is open.
 *
 * Drawn rather than typed. A text triangle at 7px renders differently in
 * every font and at every device pixel ratio; two borders on a rotated box
 * are the same shape everywhere.
 *
 * The rotation is the point. It gives the control state, so the nav says
 * "this opens" when closed and "this is open" when open, which no static
 * glyph can do. Paired with aria-haspopup on the trigger, since the visual
 * affordance and the announced one should not disagree.
 *
 * Here rather than in mbclinic.css because that file is Design's and is
 * refreshed from the snapshot on every port.
 */
.nav-item > a .caret {
  font-size: 0; opacity: 1;
  display: inline-block; width: 9px; height: 9px;
  position: relative; top: -1px;
  transition: transform .2s ease;
}
.nav-item > a .caret::after {
  content: ''; position: absolute; inset: 0; margin: auto;
  width: 6px; height: 6px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translate(-1px, -1px);
}
.nav-item:hover > a .caret,
.nav-item:focus-within > a .caret { transform: rotate(180deg); }

/* Respect a reduced-motion preference: the state still changes, it just
 * does not animate getting there. */
@media (prefers-reduced-motion: reduce) {
  .nav-item > a .caret { transition: none; }
}

/* ---- table of contents: one number, not two -----------------------------
 *
 * Design's legal TOC numbers its own entries with a CSS counter
 * (.legal .toc li { counter-increment: t }). That is right for the privacy
 * notice, whose TOC labels carry no numbers of their own.
 *
 * It is wrong for the T&Cs, whose headings ARE numbered clauses: the counter
 * put a second, different number beside each one, so the reader saw
 * "2  1. Sessions" (Andrew, 14 Sep 2026).
 *
 * The clause number is the one that must survive, because that is what a
 * contract is cited by. So the counter is suppressed only where the labels
 * already number themselves; build-terms.mjs marks that TOC.
 */
.legal .toc--self-numbered li::before { content: none; }
.legal .toc--self-numbered li { padding-left: 0; }

/* --- Classes the pages use that nothing styled --------------------------------
 *
 * Found by tools/check-css-coverage.mjs on 16 Sep 2026, after three separate
 * "the markup arrived but its styling did not" faults in one Design export.
 * These four predate that export and had simply never been noticed, which is
 * the point: an unstyled class does not break a page, it quietly degrades it.
 */

/* Two calls to action in the school-food-standards post. The post is generated
 * into src/blog by extract-blog.mjs, so the class cannot be corrected at source
 * without the next run undoing it. Mirrors .btn in mbclinic.css as at 16 Sep
 * 2026; if Design restyles .btn, this needs the same change. */
.btn-submit {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--sans); font-weight: 500; font-size: var(--t-s);
  letter-spacing: 0.18em; text-transform: uppercase;
  padding: var(--s-4) 26px;
  border: 1px solid var(--ink); background: var(--ink); color: var(--paper);
  transition: background .35s, color .35s; cursor: pointer;
}
.btn-submit:hover { background: transparent; color: var(--ink); }

/* The sub-processor names in the privacy notice table, meant to sit back from
 * the organisation they qualify. */
.muted { color: var(--ink-soft, #6F6A5E); }

/* The 10-row table in the terms page, which was rendering as a bare HTML table
 * with browser default borders and no spacing. */
.legal-table-wrap { overflow-x: auto; margin: var(--s-5) 0 var(--s-6); }
.legal-table {
  width: 100%; border-collapse: collapse;
  font-size: var(--t-s); line-height: 1.6;
}
.legal-table th, .legal-table td {
  text-align: left; vertical-align: top;
  padding: var(--s-3) var(--s-4);
  border-bottom: 1px solid var(--line, #e5e5e5);
}
.legal-table th {
  font-family: var(--sans); font-weight: 500; font-size: var(--t-xs);
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--label, #6F6A5E);
}


/* Cookie settings, in the footer's bottom row: a button (it acts on this page,
   it goes nowhere) dressed as the Privacy and Terms links beside it. Live-only:
   Design has no consent banner. BIZ_OPS audit, 16 Sep 2026, finding 7. */
.foot-bottom .foot-cookie { background: none; border: 0; padding: 0; margin: 0; cursor: pointer;
  font: inherit; letter-spacing: inherit; text-transform: inherit; color: inherit; }
.foot-bottom .foot-cookie:hover, .foot-bottom .foot-cookie:focus-visible { color: var(--paper); }

