/* KG's & INCH's - page-level blocks */

/* ---------- banner slider ---------- */

.slider {
  position: relative;
  overflow: hidden;
  background: var(--navy-deep);
}

.slides { position: relative; }

/* A slide is the picture. The wording is inside the artwork, so there is no
   copy layer and nothing to keep legible over it - which also means no scrim,
   no text shadow, and no crop that could cut a headline in half. */
.slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity .6s var(--ease);
}
.slide:first-child { position: relative; }
.slide.is-active { opacity: 1; visibility: visible; z-index: 2; }

.slide-img { display: block; }
.slide-img img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

/* The first slide is in the flow and sets the height of the band; the rest are
   stacked on top of it. The floor stops one tall upload from making the banner
   half the screen, the ceiling stops a wide one from becoming a sliver. */
.slide:first-child .slide-img img {
  min-height: clamp(240px, 26vw, 380px);
  max-height: 62vh;
}

/* The artwork already carries a navy-to-green panel down its left side - it
   was painted to hold wording, back when the wording was part of the picture.
   The words are HTML now, but the panel is still there, so this layer only has
   to make up the difference.

   It used to lay a second 68% navy wash over that panel. Two darkenings on top
   of each other read as a flat blue block with a hard edge where the artwork's
   own fade ends, which is not a gradient anyone designed - it is just two of
   them added up. What is left here is a light lift for contrast at the bottom,
   where the green of the panel is palest and white text needs the help. */
/* The darkening is its own full-bleed layer, not the container's background.
   .slide-inner is a .container - 1200px wide and centred - so painting the
   gradient on it stopped 83px short of each edge on a 1366px screen and drew a
   hard vertical line down both sides of the banner. The scrim has to span the
   picture; only the words belong inside the container. */
.slide::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(180deg, rgba(17, 44, 80, 0) 45%, rgba(17, 44, 80, .42) 100%),
    linear-gradient(90deg, rgba(17, 44, 80, .22) 0%, rgba(17, 44, 80, .04) 38%, rgba(17, 44, 80, 0) 55%);
  pointer-events: none;
}

.slide-inner {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  align-items: flex-end;
  padding-block: var(--sp-7);
  pointer-events: none;
}

/* Held to about 34rem: a headline that runs the full width of a 1600px banner
   is read in one sweep of the eyes and lands as a slogan, not a sentence. */
.slide-copy {
  max-width: 34rem;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-4);
}

.slide-title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(1.75rem, 3.6vw, 3rem);
  line-height: 1.12;
  letter-spacing: -0.01em;
  color: #fff;
  text-wrap: balance;
  text-shadow: 0 2px 18px rgba(10, 26, 48, .45);
}

.slide-sub {
  margin: 0;
  font-size: clamp(0.95rem, 1.35vw, 1.125rem);
  line-height: 1.6;
  color: rgba(255, 255, 255, .92);
  text-shadow: 0 1px 12px rgba(10, 26, 48, .45);
}

.slide-cta { pointer-events: auto; }

/* Up to 900px, not 700. The artwork's panel covers the left half of the
   picture, and by about 700px the headline has stopped fitting inside it and is
   running onto the bright food - which is exactly where white text disappears.
   Below this width the picture goes behind the words instead of beside them,
   the dark wash goes edge to edge, and the copy takes the full width. */
@media (max-width: 900px) {
  .slide::after {
    background: linear-gradient(180deg, rgba(17, 44, 80, .2) 0%, rgba(17, 44, 80, .82) 65%);
  }
  .slide-inner { padding-block: var(--sp-6); }
  .slide-copy { max-width: none; gap: var(--sp-3); }
  .slide-cta { width: 100%; justify-content: center; }
}
.slider-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 5;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1.5px solid rgba(255, 255, 255, .45);
  background: rgba(17, 44, 80, .38);
  backdrop-filter: blur(6px);
  color: #fff;
  cursor: pointer;
  transition: background-color .18s var(--ease), border-color .18s var(--ease);
}
.slider-arrow:hover { background: var(--green); border-color: var(--green); }
.slider-arrow.prev { left: var(--sp-4); }
.slider-arrow.next { right: var(--sp-4); }
/* Hidden at the same width the copy goes full-bleed. Left at 760px they sat
   on top of a headline that now runs the whole banner, and the left arrow ate
   the first word of it. The dots below still change slides. */
@media (max-width: 900px) { .slider-arrow { display: none; } }

.slider-dots {
  position: absolute;
  left: 50%;
  /* less the padding the buttons carry, so the rules sit where they did */
  bottom: calc(var(--sp-5) - 20px);
  transform: translateX(-50%);
  z-index: 5;
  display: flex;
  gap: 0;
}
/* The dot itself is a 4px rule, far too fine to hit with a thumb. The button
   is padded out and paints the rule through background-clip, so the mark stays
   thin while the tap area does not. 44px tall is the size a fingertip actually
   needs, so the button is a full 44x44 while the rule it paints stays 30px
   wide and 4px tall - exactly as it looked before. The gap is 0 because each
   button now carries its own 7px of side padding. */
.slider-dots button {
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 2px;
  background: rgba(255, 255, 255, .45);
  background-clip: content-box;
  padding: 20px 7px;
  cursor: pointer;
  transition: background-color .2s var(--ease), width .2s var(--ease);
}
.slider-dots button.is-active { background: var(--green); background-clip: content-box; width: 60px; }

/* Text links that sit on their own line - "Forgotten your password?", the
   footer credit - are only as tall as their text, which is around 17px and
   awkward to hit on a phone. Padding gives them a thumb-sized target without
   moving anything on the page. */
.form-note a,
.footer-bottom a,
.account-links a { display: inline-block; }

@media (hover: none) {
  .form-note a,
  .footer-bottom a { padding-block: var(--sp-2); }
}

/* ---------- about short ---------- */

.about-short {
  display: grid;
  grid-template-columns: .85fr 1.15fr;
  gap: clamp(var(--sp-6), 5vw, var(--sp-8));
  align-items: center;
}
@media (max-width: 860px) {
  .about-short { grid-template-columns: 1fr; }
}

.about-figure {
  position: relative;
  margin: 0;
  border-radius: var(--radius-lg);
  overflow: hidden;
  aspect-ratio: 4 / 5;
  box-shadow: var(--shadow-lg);
}
.about-figure img { width: 100%; height: 100%; object-fit: cover; object-position: center 22%; }

/* Caption sits over the foot of the photo, on a scrim so it stays readable
   whatever the picture is doing behind it. */
.about-figure figcaption {
  position: absolute;
  inset: auto 0 0 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--sp-6) var(--sp-5) var(--sp-4);
  background: linear-gradient(180deg, rgba(17,44,80,0) 0%, rgba(17,44,80,.82) 62%, rgba(17,44,80,.92) 100%);
  color: #fff;
}
.about-figure figcaption strong {
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 700;
  line-height: 1.1;
}
.about-figure figcaption span {
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #9FD46A;
}

.about-stats {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-7);
  margin: 0;
  padding-block: var(--sp-5);
  border-block: 1px solid var(--line);
}
.about-stats div { display: flex; flex-direction: column; gap: 2px; }
.about-stats dt {
  font-family: var(--font-display);
  font-size: var(--step-3);
  font-weight: 700;
  color: var(--green-deep);
  line-height: 1;
}
.about-stats dd {
  margin: 0;
  font-size: var(--step--1);
  color: var(--muted);
  letter-spacing: .08em;
  text-transform: uppercase;
  font-weight: 600;
}

/* ---------- cards on the home page ---------- */

.link-more {
  font-size: var(--step--1);
  font-weight: 700;
  color: var(--green-deep);
  letter-spacing: .01em;
}

.program-card .card-media { aspect-ratio: 4 / 3; }



.recipe-card .card-media { aspect-ratio: 1 / 1; position: relative; }

.recipe-card time, .blog-card time {
  font-size: var(--step--1);
  color: var(--muted);
  font-weight: 600;
  letter-spacing: .04em;
}

.media-tag {
  position: absolute;
  left: var(--sp-3);
  top: var(--sp-3);
  background: rgba(255, 255, 255, .94);
  color: var(--green-deep);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  padding: 0.3rem 0.55rem;
  border-radius: var(--radius-sm);
}

.blog-card .card-media { aspect-ratio: 16 / 10; }


/* ---------- testimonials ---------- */

.testimonial {
  display: flex;
  flex-direction: column;
  margin: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  transition: box-shadow .2s var(--ease), transform .2s var(--ease);
}
.testimonial:hover { box-shadow: var(--shadow); transform: translateY(-3px); }

.testimonial-photo { aspect-ratio: 4 / 3; background: var(--surface-2); }
.testimonial-photo img { width: 100%; height: 100%; object-fit: cover; }

.testimonial-body {
  padding: var(--sp-5);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}

.result-tag {
  align-self: flex-start;
  background: var(--green-soft);
  color: var(--green-deep);
  font-size: var(--step--1);
  font-weight: 700;
  padding: 0.3rem 0.7rem;
  border-radius: var(--radius-pill);
}

.testimonial blockquote {
  margin: 0;
  color: var(--ink-2);
  font-size: var(--step-0);
  line-height: 1.6;
}
.testimonial figcaption {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  font-weight: 700;
  color: var(--navy);
  font-size: var(--step--1);
}

/* Most of the stories were written before anyone thought to ask for a photo.
   Those cards close up rather than holding open an empty picture frame, and
   the initial rides beside the name instead. */
.testimonial-initial {
  flex: 0 0 34px;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-family: var(--font-display);
  font-size: var(--step-0);
  font-weight: 700;
  color: var(--green-deep);
  background: var(--green-soft);
}

/* Without a photograph the quote is the whole card, so it is given the weight
   the picture would have carried. */
.testimonial.no-photo blockquote { font-size: var(--step-0); color: var(--ink); }


/* ---------- testimonials page ---------- */

/* The home strip clips each story to a line and a half because it is six
   across. This page prints the whole thing, and the stories run from two lines
   to thirty - so it is columns, not a grid. A grid would hold every row to the
   height of its tallest card and leave a half page of white under the rest. */
.story-grid {
  columns: 3;
  column-gap: var(--sp-5);
}
.story-grid > * {
  break-inside: avoid;
  /* Safari still reads the old name, and a story split across two columns is
     unreadable rather than merely untidy. */
  -webkit-column-break-inside: avoid;
  page-break-inside: avoid;
  margin-bottom: var(--sp-5);
}

/* The photographs are before-and-after posts with the weights written across
   them, and they arrive both square and 4:5. Any fixed frame crops the numbers
   off one shape or the other, so here they keep their own - which columns can
   absorb and a grid could not. */
.story-grid .testimonial-photo { aspect-ratio: auto; }
.story-grid .testimonial-photo img { height: auto; }
.story-grid .testimonial blockquote { font-size: var(--step--1); }

@media (max-width: 1024px) { .story-grid { columns: 2; } }
@media (max-width: 680px)  { .story-grid { columns: 1; } }

/* ---------- page hero (inner pages) ---------- */

.page-hero {
  background: var(--surface-2);
  border-bottom: 1px solid var(--line);
  padding-block: var(--sp-7);
}
/* Smaller than the global h1: an inner page opens with a line of orientation,
   not a poster, and at the full display size a heading like "Nutrition that is
   measured, not guessed" ran most of the width of the screen. */
.page-hero h1 {
  color: var(--navy);
  font-size: clamp(1.6rem, 2.9vw, 2.375rem);
}
.page-hero .lede { color: var(--ink-2); font-size: var(--step-1); max-width: 62ch; }

/* ---------- value cards (about) ---------- */

/* ---------- what we hold to ---------- */

.value-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--sp-5);
  overflow: hidden;
  transition: transform .25s var(--ease), box-shadow .25s var(--ease),
              border-color .25s var(--ease);
}
/* The green rail is painted rather than bordered so it can run the width of
   the card on hover. */
.value-card::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  height: 3px;
  width: 3.5rem;
  background: var(--green);
  transition: width .35s var(--ease);
}
.value-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow);
  border-color: var(--line-strong);
}
.value-card:hover::before { width: 100%; }

.value-icon {
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  margin-top: var(--sp-2);
  border-radius: var(--radius);
  background: var(--green-soft);
  color: var(--green-deep);
  transition: background-color .25s var(--ease), color .25s var(--ease);
}
.value-card:hover .value-icon { background: var(--green); color: #fff; }

.value-card h3 { font-size: var(--step-1); color: var(--navy); }
.value-card p { color: var(--ink-2); font-size: var(--step--1); }

/* Each icon moves in the way its own idea moves: the needle sweeps, the bowl
   steams, the slash is drawn through the capsule, the week comes round. */
.icon [class^="ic-"] {
  transform-box: view-box;
  transform-origin: center;
}

.icon-gauge .ic-needle {
  transform-origin: 12px 18px;
  transition: transform .5s cubic-bezier(.34, 1.3, .5, 1);
}
.value-card:hover .icon-gauge .ic-needle { transform: rotate(-34deg); }

.icon-bowl .ic-steam {
  opacity: 0;
  transform: translateY(2px);
  transition: opacity .3s var(--ease), transform .45s var(--ease);
}
.value-card:hover .icon-bowl .ic-steam { opacity: 1; transform: translateY(0); }

.icon-no-pill .ic-slash {
  stroke-dasharray: 21;
  stroke-dashoffset: 21;
  transition: stroke-dashoffset .45s var(--ease);
}
.value-card:hover .icon-no-pill .ic-slash { stroke-dashoffset: 0; }

.icon-refresh-week .ic-spin {
  transform-origin: 12.3px 15.1px;
  transition: transform .6s var(--ease);
}
.value-card:hover .icon-refresh-week .ic-spin { transform: rotate(360deg); }

@media (prefers-reduced-motion: reduce) {
  .value-card,
  .value-card::before,
  .value-icon,
  .icon [class^="ic-"] { transition: none; }
  .value-card:hover { transform: none; }
  .icon-bowl .ic-steam { opacity: 1; transform: none; }
  .icon-no-pill .ic-slash { stroke-dashoffset: 0; }
}

/* ---------- clinic card ---------- */

.clinic-card {
  display: flex;
  flex-direction: column;
  gap: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 3px solid var(--green);
  border-radius: var(--radius);
  padding: var(--sp-5);
}
.clinic-code {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
}
.clinic-card h3 { font-size: var(--step-1); color: var(--navy); }
.clinic-card p { color: var(--ink-2); font-size: var(--step--1); }

/* ---------- timeline (how it works) ---------- */

.timeline {
  list-style: none;
  margin: 0 auto;
  padding: 0;
  max-width: 780px;
  display: flex;
  flex-direction: column;
}

.tl-item {
  position: relative;
  display: grid;
  grid-template-columns: 56px 1fr;
  gap: var(--sp-5);
  padding-bottom: var(--sp-6);
}
/* connector between the numbers */
.tl-item::before {
  content: "";
  position: absolute;
  left: 27px;
  top: 52px;
  bottom: -4px;
  width: 2px;
  background: var(--line-strong);
}
.tl-item:last-child { padding-bottom: 0; }
.tl-item:last-child::before { display: none; }

.tl-num {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--green-soft);
  border: 2px solid var(--green);
  color: var(--green-deep);
  font-family: var(--font-mono);
  font-size: var(--step-0);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.tl-body { padding-top: var(--sp-2); display: flex; flex-direction: column; gap: var(--sp-2); }
.tl-body h3 { font-size: var(--step-2); color: var(--navy); }
.tl-body p { color: var(--ink-2); }

/* ---------- program detail ---------- */

.program-detail {
  display: grid;
  grid-template-columns: 1fr 340px;
  gap: clamp(var(--sp-5), 4vw, var(--sp-7));
  align-items: start;
}
@media (max-width: 900px) { .program-detail { grid-template-columns: 1fr; } }

.program-hero-img {
  width: 100%;
  border-radius: var(--radius-lg);
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

.program-aside { display: flex; flex-direction: column; gap: var(--sp-4); position: sticky; top: 110px; }
@media (max-width: 900px) { .program-aside { position: static; } }

.aside-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--sp-5);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}
.aside-card h3 { font-size: var(--step-1); color: var(--navy); }
.aside-card p { color: var(--ink-2); font-size: var(--step--1); }
.aside-links { list-style: none; padding: 0; display: flex; flex-direction: column; gap: var(--sp-2); }
.aside-links a { color: var(--ink-2); font-size: var(--step--1); }
.aside-links a:hover { color: var(--green-deep); }

.tick-list { list-style: none; padding: 0; display: flex; flex-direction: column; gap: var(--sp-3); }
.tick-list li {
  position: relative;
  padding-left: var(--sp-6);
  color: var(--ink-2);
}
.tick-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.45em;
  width: 16px;
  height: 9px;
  border-left: 2.5px solid var(--green);
  border-bottom: 2.5px solid var(--green);
  transform: rotate(-45deg);
}

/* ---------- contact ---------- */

.contact-grid {
  display: grid;
  grid-template-columns: 1fr 1.05fr;
  gap: clamp(var(--sp-5), 4vw, var(--sp-7));
  align-items: start;
}
@media (max-width: 900px) { .contact-grid { grid-template-columns: 1fr; } }

.contact-rows { display: flex; flex-direction: column; gap: var(--sp-3); }

.contact-row {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--sp-4) var(--sp-5);
  color: var(--ink);
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.contact-row:hover { text-decoration: none; border-color: var(--green); box-shadow: var(--shadow-sm); }
/* The e-mail address is one unbreakable word about 180px wide, which on a
   320px screen was enough to hold the whole column open. min-width lets the
   text block shrink and break-word lets the address itself wrap. */
.contact-row > span:last-child {
  display: flex; flex-direction: column;
  min-width: 0;
  overflow-wrap: anywhere;
}

.contact-icon {
  display: grid;
  place-items: center;
  width: 42px; height: 42px;
  border-radius: 50%;
  background: var(--green-soft);
  color: var(--green-deep);
  flex: none;
}
.contact-label {
  font-size: var(--step--1);
  color: var(--muted);
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
}
.contact-value { font-weight: 700; color: var(--navy); }

.contact-form-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: clamp(var(--sp-5), 3vw, var(--sp-6));
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  box-shadow: var(--shadow);
}

/* ---------- prose (policy pages) ---------- */

.prose { display: flex; flex-direction: column; gap: var(--sp-4); }
.prose h2 {
  font-size: var(--step-2);
  color: var(--navy);
  margin-top: var(--sp-4);
}
.prose h2:first-of-type { margin-top: 0; }
.prose p { color: var(--ink-2); }

/* ---------- process steps ----------
   These rules went missing when this file was rewritten for the slider, which
   left the About and program-detail step lists rendering as a bare <ol>. */

.steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--sp-4);
  grid-template-columns: repeat(auto-fill, minmax(min(310px, 100%), 1fr));
  counter-reset: step;
}

.step {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--sp-4);
  align-items: start;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--sp-5);
  overflow: hidden;
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease),
              transform .2s var(--ease);
}
/* a thin brand rail that fills in on hover */
.step::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  background: var(--green);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform .25s var(--ease);
}
.step:hover {
  border-color: var(--line-strong);
  box-shadow: var(--shadow);
  transform: translateY(-2px);
}
.step:hover::before { transform: scaleY(1); }

.step-num {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--green-soft);
  color: var(--green-deep);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  flex: none;
}

.step h4 {
  font-family: var(--font-body);
  font-size: var(--step-1);
  font-weight: 700;
  color: var(--navy);
  line-height: 1.3;
}
.step p { color: var(--ink-2); font-size: var(--step--1); }

/* ---------- CTA band ----------
   Also lost in the rewrite, which left white text on a white background. */

.cta-band {
  background: linear-gradient(120deg, var(--green-deep) 0%, var(--green) 55%, #8CBF44 100%);
  padding-block: var(--sp-6);
  color: #fff;
}

.cta-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-6);
  flex-wrap: wrap;
}

.cta-copy { display: flex; flex-direction: column; gap: var(--sp-2); max-width: 46ch; }
.cta-copy h2 {
  color: #fff;
  font-size: clamp(1.4rem, 2.4vw, 2rem);
  line-height: 1.15;
}
.cta-copy p { color: #E4F1D4; font-size: var(--step-0); }

.cta-actions { display: flex; gap: var(--sp-3); flex-wrap: wrap; flex: none; }

@media (max-width: 760px) {
  .cta-inner { flex-direction: column; align-items: flex-start; gap: var(--sp-5); }
  .cta-actions { width: 100%; }
  .cta-actions .btn { flex: 1 1 auto; }
}

.cta-band .cta-outline {
  color: #fff;
  border-color: rgba(255, 255, 255, .6);
  background: transparent;
}
.cta-band .cta-outline:hover {
  color: var(--green-deep);
  background: #fff;
  border-color: #fff;
}

/* ---------- product tile fallback ----------
   56 of the 113 live products have no image; those tiles show the category
   name rather than an empty box. */

.placeholder-media {
  display: grid;
  place-items: center;
  background: linear-gradient(135deg, var(--green-soft), var(--navy-soft));
}
.placeholder-media span {
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 700;
  color: var(--navy);
  opacity: .45;
}

/* ---------- listing chrome ---------- */

.result-count {
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
}

.empty-note {
  color: var(--muted);
  padding: var(--sp-7) 0;
  text-align: center;
}

.card-summary {
  color: var(--ink-2);
  font-size: var(--step--1);
  line-height: 1.6;
}

/* ---------- blog / recipes switch ---------- */

.type-switch {
  display: inline-flex;
  gap: 0.25rem;
  padding: 0.3rem;
  background: var(--navy-soft);
  border-radius: var(--radius-pill);
}

.type-tab {
  font-family: var(--font-display);
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--navy);
  padding: 0.55rem 1.5rem;
  border-radius: var(--radius-pill);
  transition: background-color .16s var(--ease), color .16s var(--ease);
}
.type-tab:hover {
  text-decoration: none;
  background: rgba(255, 255, 255, .7);
}
.type-tab.is-active {
  background: var(--navy);
  color: #fff;
  cursor: default;
}

/* ---------- category filter ---------- */

.filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 0;
}

.filter-chip {
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--ink-2);
  background: var(--surface);
  border: 1.5px solid var(--line-strong);
  border-radius: var(--radius-pill);
  padding: 0.5rem 1rem;
  transition: background-color .16s var(--ease), border-color .16s var(--ease),
              color .16s var(--ease);
}
.filter-chip:hover {
  text-decoration: none;
  border-color: var(--green);
  color: var(--green-deep);
}
.filter-chip.is-active {
  background: var(--green);
  border-color: var(--green);
  color: #fff;
}

/* ---------- pager ---------- */

.pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0;
  flex-wrap: wrap;
}

.pager-num, .pager-btn {
  display: grid;
  place-items: center;
  min-width: 40px;
  height: 40px;
  padding: 0 var(--sp-2);
  border-radius: var(--radius-sm);
  border: 1.5px solid var(--line-strong);
  background: var(--surface);
  color: var(--navy);
  font-size: var(--step--1);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  transition: background-color .16s var(--ease), border-color .16s var(--ease),
              color .16s var(--ease);
}
.pager-num:hover, .pager-btn:hover {
  text-decoration: none;
  border-color: var(--green);
  color: var(--green-deep);
}
.pager-num.is-current {
  background: var(--green);
  border-color: var(--green);
  color: #fff;
}
.pager-btn.is-off { opacity: .35; }
.pager-gap { color: var(--muted); padding-inline: var(--sp-1); }

/* ---------- article ---------- */

.article-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: clamp(var(--sp-5), 4vw, var(--sp-7));
  align-items: start;
}
@media (max-width: 900px) { .article-layout { grid-template-columns: 1fr; } }

.article-title { font-size: clamp(1.6rem, 2.9vw, 2.375rem); }

.article-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  align-items: center;
  font-size: var(--step--1);
  color: var(--muted);
  font-weight: 600;
}

.article-hero {
  width: 100%;
  max-height: 460px;
  object-fit: cover;
  border-radius: var(--radius-lg);
}

/* The article body is admin-authored HTML from a rich-text editor, so these
   rules have to cover whatever tags it happens to contain - including inline
   font-size and colour attributes, which are overridden so the page keeps one
   readable type size, and a long unbroken URL or a table sized for a desktop,
   neither of which may be allowed to widen the page on a phone. */
.article-body { color: var(--ink-2); overflow-wrap: break-word; }
.article-body * { font-size: inherit !important; font-family: inherit !important; }
.article-body p,
.article-body div,
.article-body ul,
.article-body ol { margin: 0 0 var(--sp-4); }
.article-body h1, .article-body h2, .article-body h3, .article-body h4 {
  font-family: var(--font-display);
  color: var(--navy);
  margin: var(--sp-6) 0 var(--sp-3);
}
.article-body h2 { font-size: var(--step-2) !important; }
.article-body h3, .article-body h4 { font-size: var(--step-1) !important; }
.article-body ul, .article-body ol { padding-left: var(--sp-6); }
.article-body li { margin-bottom: var(--sp-2); }
.article-body img {
  max-width: 100%;
  height: auto;
  border-radius: var(--radius);
  margin-block: var(--sp-4);
}
.article-body a { color: var(--green-deep); text-decoration: underline; }
.article-body strong, .article-body b { color: var(--navy); }
/* display:block is what gives the table a scroller of its own, so a wide one
   is swiped rather than pushing the whole article sideways. */
.article-body table {
  display: block;
  width: 100%;
  max-width: 100%;
  overflow-x: auto;
  border-collapse: collapse;
  margin-bottom: var(--sp-4);
}
.article-body iframe { max-width: 100%; }
.article-body th, .article-body td {
  border: 1px solid var(--line);
  padding: var(--sp-2) var(--sp-3);
  text-align: left;
}

/* ---------- recipe sheet ----------
   The recipe body is rebuilt from the editor HTML by kgs_recipe_sections(),
   so unlike .article-body these rules style a known structure rather than
   whatever tags happened to be pasted in. */

.recipe-sheet {
  display: flex;
  flex-direction: column;
  gap: var(--sp-6);
}

.recipe-sheet strong { color: var(--navy); font-weight: 600; }
.recipe-sheet a { color: var(--green-deep); text-decoration: underline; }

.rs-head {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  font-family: var(--font-display);
  font-size: var(--step-2);
  line-height: 1.25;
  color: var(--navy);
  margin: 0 0 var(--sp-5);
}
.rs-head::before {
  content: "";
  flex: none;
  width: 26px;
  height: 3px;
  border-radius: 2px;
  background: var(--green);
}

/* A heading the dietitian typed inside a section - "Tempering", "For Dressing".
   Set below .rs-head so the two levels stay distinct. */
.rs-sub {
  font-family: var(--font-display);
  font-size: var(--step-0);
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--green-deep);
  margin: var(--sp-5) 0 var(--sp-3);
}
.rs-sub:first-child { margin-top: 0; }
.rs-ingredients .rs-sub { margin-top: var(--sp-5); }

.rs-para {
  color: var(--ink-2);
  font-size: var(--step-0);
  line-height: 1.75;
  margin: 0 0 var(--sp-3);
}
.rs-para:last-child { margin-bottom: 0; }

.rs-list {
  padding-left: var(--sp-6);
  color: var(--ink-2);
  line-height: 1.7;
}
.rs-list li { margin-bottom: var(--sp-2); }

.rs-image {
  max-width: 100%;
  height: auto;
  border-radius: var(--radius);
}

/* Ingredients - a shopping list, so it is ticked off rather than numbered. */
.rs-ingredients {
  background: var(--green-soft);
  border-radius: var(--radius-lg);
  padding: var(--sp-6);
}

.ing-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 var(--sp-7);
}
@media (max-width: 640px) { .ing-list { grid-template-columns: 1fr; } }

.ing-list li {
  position: relative;
  padding: var(--sp-3) 0 var(--sp-3) var(--sp-5);
  color: var(--ink);
  font-size: var(--step-0);
  line-height: 1.55;
  border-bottom: 1px solid rgba(90, 135, 38, .16);
}
.ing-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 1.35em;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--green);
  box-shadow: 0 0 0 3px rgba(113, 169, 48, .18);
}

/* The last row carries no rule - a border under the final item reads as a
   missing row. Only applies while the list is in two columns. */
.ing-list li:last-child { border-bottom: none; }
@media (min-width: 641px) {
  .ing-list li:nth-last-child(2):nth-child(odd) { border-bottom: none; }
}

/* Method - genuinely a sequence, so the numbers carry information. */
.step-list {
  list-style: none;
  padding: 0;
  margin: 0;
  counter-reset: step;
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
}

.step-list li {
  counter-increment: step;
  position: relative;
  min-height: 2.25rem;
  padding-left: 3.5rem;
  color: var(--ink-2);
  font-size: var(--step-0);
  line-height: 1.7;
}
.step-list li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: -0.15rem;
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 50%;
  background: var(--surface);
  border: 1.5px solid var(--green);
  color: var(--green-deep);
  font-family: var(--font-display);
  font-size: var(--step--1);
  font-weight: 700;
}
/* a rail so the steps read as one run rather than five separate notes */
.step-list li::after {
  content: "";
  position: absolute;
  left: calc(1.125rem - 0.75px);
  top: 2.35rem;
  bottom: calc(-1 * var(--sp-5));
  width: 1.5px;
  background: linear-gradient(var(--line-strong), rgba(203, 211, 196, 0));
}
.step-list li:last-child::after { display: none; }

/* Notes, tips, nutritional value - whatever else the recipe carries. */
.rs-notes {
  background: var(--navy-soft);
  border-radius: var(--radius-lg);
  padding: var(--sp-5) var(--sp-6);
}
.rs-notes .rs-head { font-size: var(--step-1); margin-bottom: var(--sp-3); }

/* Sitting under the article now, so it is separated from the last paragraph
   and set quieter than the body it follows. */
.article-meta {
  padding-top: var(--sp-5);
  border-top: 1px solid var(--line);
}

.article-foot {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
}

.article-aside {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  position: sticky;
  top: 110px;
}
@media (max-width: 900px) { .article-aside { position: static; } }

.aside-posts { list-style: none; padding: 0; display: flex; flex-direction: column; gap: var(--sp-4); }
.aside-posts a { display: flex; gap: var(--sp-3); align-items: flex-start; }
.aside-posts a:hover { text-decoration: none; }
.aside-posts img {
  width: 62px; height: 62px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  flex: none;
}
.aside-posts span { display: flex; flex-direction: column; gap: 2px; }
.aside-posts .ap-title {
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--navy);
  line-height: 1.35;
}
.aside-posts time { font-size: 0.75rem; color: var(--muted); font-weight: 600; }
.aside-posts a:hover .ap-title { color: var(--green-deep); }

/* ---------- product listing and detail ---------- */

.chip-count {
  font-variant-numeric: tabular-nums;
  opacity: .65;
  margin-left: .15em;
}

.product-card .card-body { gap: var(--sp-3); }
.product-card .p-foot {
  display: flex;
  align-items: baseline;
  margin-top: auto;
  padding-top: var(--sp-1);
}
/* Sold-out rows stay legible but read as unavailable. */
.product-card.is-out .card-media img { opacity: .55; filter: saturate(.65); }
.product-card.is-out .p-price {
  color: var(--muted);
  background: var(--surface-2);
}

.media-tag.tag-out {
  background: var(--ink);
  color: #fff;
}

.product-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--sp-8);
  align-items: start;
}
@media (max-width: 900px) {
  .product-layout { grid-template-columns: 1fr; gap: var(--sp-6); }
}

.product-figure {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.product-figure img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  display: block;
}

.product-title { font-size: clamp(1.5rem, 2.7vw, 2.125rem); color: var(--navy); }

.product-price-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-3);
}
.product-price {
  font-family: var(--font-display);
  font-size: var(--step-3);
  font-weight: 700;
  color: var(--navy);
}
.product-weight { color: var(--muted); font-size: var(--step-0); }

.stock-pill {
  font-size: var(--step--1);
  font-weight: 600;
  padding: 0.25rem 0.7rem;
  border-radius: var(--radius-pill);
  align-self: center;
}
.stock-pill.in  { background: var(--green-soft); color: var(--green-deep); }
.stock-pill.out { background: var(--danger-soft); color: var(--danger); }

.product-desc {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  color: var(--ink-2);
  line-height: 1.75;
}
.product-desc strong { color: var(--navy); font-weight: 600; }

/* The page ends in a question, not a checkout - there is no order table and
   the clinic takes product orders by phone. */
.enquiry-box {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: var(--sp-5);
}
.enquiry-box h2 { font-size: var(--step-1); color: var(--navy); }

.enquiry-form {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
}
.enquiry-form .input { flex: 1 1 14rem; background: var(--surface); }

.enquiry-alt {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  padding-top: var(--sp-2);
}
.enquiry-alt .btn { display: inline-flex; align-items: center; gap: var(--sp-2); }

/* Stand-in tile for the products with no photograph on file. The brand mark
   sits behind the category name so the grid keeps its rhythm. */
.product-ph {
  position: relative;
  width: 100%;
  height: 100%;
  gap: 0;
  padding: var(--sp-5);
  text-align: center;
}
.product-ph img {
  width: 44%;
  max-width: 96px;
  height: auto;
  opacity: .30;
}
.product-ph > span {
  font-family: var(--font-display);
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--navy);
  opacity: .55;
}

/* ---------- page hero polish ----------
   The inner-page header was a flat grey band. It now carries a soft wash of
   the brand green and the mark set very faintly behind the type, so a page
   opens with something of the clinic's own colour rather than a plain box. */

.page-hero {
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(120% 140% at 92% 0%, rgba(113, 169, 48, .13), rgba(113, 169, 48, 0) 58%),
    radial-gradient(90% 120% at 0% 100%, rgba(26, 66, 120, .07), rgba(26, 66, 120, 0) 60%),
    var(--surface-2);
}
.page-hero::after {
  content: "";
  position: absolute;
  top: 50%;
  right: -2.5rem;
  width: 260px;
  height: 300px;
  transform: translateY(-50%);
  background: url("../img/mark.png") no-repeat center / contain;
  opacity: .07;
  pointer-events: none;
}
@media (max-width: 900px) { .page-hero::after { display: none; } }

.page-hero .container { position: relative; z-index: 1; }

/* ---------- elevation, applied ----------
   Every panel on the site rests on the same first step of the elevation scale
   and lifts to the same second step. Written once here rather than repeated in
   each block, so the depth of the page stays consistent as blocks are added. */

.value-card,
.clinic-card,
.aside-card,
.step,
.testimonial,
.contact-row,
.product-figure,
.enquiry-box,
.filter-chip,
.type-switch {
  box-shadow: var(--shadow-xs);
}

.contact-form-card,
.about-figure { box-shadow: var(--shadow-lg); }

.value-card:hover,
.step:hover,
.testimonial:hover,
.contact-row:hover { box-shadow: var(--shadow); }

/* The corner radius follows the same idea: panels the size of a card share the
   card's radius, so nothing looks borrowed from another design. */
.value-card,
.clinic-card,
.aside-card,
.step,
.testimonial,
.contact-row { border-radius: var(--radius-lg); }

/* Media inside a card gets an inner line, so a photograph with a pale edge
   does not bleed into the card behind it. */
.card-media { position: relative; }
.card-media::after {
  content: "";
  position: absolute;
  inset: 0;
  box-shadow: inset 0 -1px 0 rgba(26, 66, 120, .06);
  pointer-events: none;
}

/* ---------- card detail ---------- */

/* Cards in a grid share a height, and the "view" line sits on the floor of the
   card so a row of them lines up however long the titles run. */
.grid > .card { height: 100%; display: flex; flex-direction: column; }
.grid > .card .card-body { flex: 1; }
.program-card .link-more,
.recipe-card .link-more,
.blog-card .link-more { margin-top: auto; padding-top: var(--sp-1); }

/* On hover the photograph darkens very slightly from the foot, which reads as
   the card coming forward rather than the image simply scaling. */
.card-hover .card-media::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(180deg, rgba(17, 44, 80, 0) 55%, rgba(17, 44, 80, .20) 100%);
  opacity: 0;
  transition: opacity .25s var(--ease);
  pointer-events: none;
}
.card-hover:hover .card-media::before { opacity: 1; }
.media-tag { z-index: 2; }

/* ---------- listing chrome, detailed ---------- */

.filter-chip {
  transition: background-color .16s var(--ease), border-color .16s var(--ease),
              color .16s var(--ease), box-shadow .16s var(--ease),
              transform .16s var(--ease);
}
.filter-chip:hover { box-shadow: var(--shadow-sm); transform: translateY(-1px); }
.filter-chip.is-active {
  box-shadow: 0 1px 2px rgba(26, 66, 120, .10), 0 8px 16px -10px rgba(90, 135, 38, .70);
}

.type-tab.is-active {
  box-shadow: 0 1px 2px rgba(26, 66, 120, .14), 0 8px 16px -10px rgba(26, 66, 120, .70);
}

.pager-num.is-current {
  background: var(--green);
  border-color: var(--green);
  color: #fff;
  box-shadow: 0 6px 14px -8px rgba(90, 135, 38, .8);
}
.pager-num,
.pager-btn { transition: background-color .16s var(--ease), border-color .16s var(--ease),
                         color .16s var(--ease), box-shadow .16s var(--ease); }
.pager-num:hover,
.pager-btn:not(.is-off):hover { box-shadow: var(--shadow-sm); }

/* An empty result is a state worth designing, not a stray sentence. */
.empty-note {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0;
  padding: var(--sp-8) var(--sp-5);
  background: var(--surface);
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-lg);
  text-align: center;
}
.empty-note::before {
  content: "";
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: var(--green-soft) url("../img/mark.png") no-repeat center / 60%;
  opacity: .8;
}

/* ---------- forms ---------- */

.input:focus, .select:focus, .textarea:focus {
  box-shadow: var(--ring-green);
}
.input:hover, .select:hover, .textarea:hover { border-color: var(--muted); }
.input:focus:hover, .select:focus:hover, .textarea:focus:hover { border-color: var(--green); }

/* Required fields say so quietly, rather than the visitor finding out on
   submit. */
.field label { display: flex; align-items: baseline; gap: .4em; }

/* ---------- slider motion ----------
   The slide itself cross-fades; only the button is animated, arriving a beat
   after the picture it sits on. Keyed off .is-active, which the existing
   slider script already toggles - no new JavaScript.

   The headline and body used to be animated here too. They are gone: a slide
   is now a picture with its wording baked in. */

.js .slide.is-active .slide-cta { animation: kgs-rise .6s .18s var(--ease) both; }

@media (prefers-reduced-motion: reduce) {
  .js .slide.is-active .slide-cta { animation: none; }
}

/* ---------- how it works ---------- */

.howto-layout {
  display: grid;
  grid-template-columns: minmax(0, 22rem) minmax(0, 1fr);
  gap: clamp(var(--sp-6), 5vw, var(--sp-8));
  align-items: start;
}
@media (max-width: 900px) {
  .howto-layout { grid-template-columns: 1fr; }
}

.howto-aside {
  position: sticky;
  top: calc(92px + var(--sp-5));
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
}
@media (max-width: 900px) { .howto-aside { position: static; } }

.howto-figure {
  position: relative;
  margin: 0;
  border-radius: var(--radius-lg);
  overflow: hidden;
  aspect-ratio: 4 / 5;
  box-shadow: var(--shadow-lg);
}
.howto-figure img { width: 100%; height: 100%; object-fit: cover; object-position: center 22%; }
.howto-figure figcaption {
  position: absolute;
  inset: auto 0 0 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--sp-6) var(--sp-5) var(--sp-4);
  background: linear-gradient(180deg, rgba(17,44,80,0) 0%, rgba(17,44,80,.82) 62%, rgba(17,44,80,.92) 100%);
  color: #fff;
}
.howto-figure figcaption strong {
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 700;
  line-height: 1.15;
}
.howto-figure figcaption span {
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #9FD46A;
}

.howto-quote {
  color: var(--ink-2);
  font-size: var(--step-0);
  line-height: 1.7;
}

/* The timeline is no longer a floating column, so it fills its own track. */
.howto-layout .timeline { max-width: none; margin: 0; }

/* ---------- policy pages ----------
   A legal page is still a document, so it is set on a page rather than left
   floating on the site's ground, and each clause is marked so the eye can find
   the one it came for. */

.prose {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  padding: clamp(var(--sp-5), 4vw, var(--sp-7));
  gap: var(--sp-5);
}
.prose h2 {
  position: relative;
  padding-left: var(--sp-5);
  margin-top: var(--sp-5);
  font-size: var(--step-1);
}
.prose h2::before {
  content: "";
  position: absolute;
  left: 0;
  top: .3em;
  bottom: .3em;
  width: 4px;
  border-radius: 2px;
  background: var(--green);
}
.prose h2 + p { padding-left: var(--sp-5); }
.prose p { line-height: 1.75; }
.prose .alert { margin-bottom: var(--sp-2); }


/* ---------- program packages ---------- */

/* A program carries anywhere from one package to fourteen, so the row count is
   left to the grid rather than fixed at three. */
.plan-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(270px, 1fr));
  gap: var(--sp-5);
  align-items: stretch;
}

.plan-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-6) var(--sp-5) var(--sp-5);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  transition: box-shadow .2s var(--ease), transform .2s var(--ease);
}
.plan-card:hover { box-shadow: var(--shadow); transform: translateY(-3px); }

/* The longest plan is the one the clinic recommends, so it is the one thing on
   the row carrying the brand colour. */
.plan-card.is-pick {
  border-color: var(--green);
  box-shadow: var(--shadow), var(--ring-green);
}
.plan-flag {
  position: absolute;
  top: 0;
  left: var(--sp-5);
  transform: translateY(-50%);
  background: var(--green);
  color: #fff;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  padding: 0.28rem 0.6rem;
  border-radius: var(--radius-pill);
}

.plan-name {
  font-size: var(--step-1);
  line-height: 1.25;
  color: var(--navy);
}
.plan-note {
  font-size: var(--step--1);
  color: var(--muted);
  margin: 0;
}

.plan-price {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0;
  margin: 0;
  padding-block: var(--sp-3);
  border-block: 1px solid var(--line);
}
.plan-amount {
  font-family: var(--font-display);
  font-size: var(--step-3);
  font-weight: 700;
  line-height: 1;
  color: var(--green-deep);
  font-variant-numeric: tabular-nums;
}
.plan-days {
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--muted);
  letter-spacing: .04em;
  text-transform: uppercase;
}

.plan-features {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0;
  font-size: var(--step--1);
  color: var(--ink-2);
}
.plan-features li {
  position: relative;
  padding-left: 1.35rem;
  line-height: 1.5;
}
.plan-features li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .45em;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--green-soft);
  box-shadow: inset 0 0 0 2px var(--green);
}

/* Pinned to the floor of the card so the buttons line up across a row whatever
   the feature lists do above them. */
.plan-cta { margin-top: auto; }

.plan-cta[disabled] { opacity: .6; cursor: progress; }

/* Whatever the checkout has to say - it is one line for the whole grid rather
   than one per card, because only one purchase can be in flight at a time. */
.buy-msg {
  margin: 0;
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--radius);
  background: var(--surface-2);
  border-left: 3px solid var(--green);
  font-size: var(--step--1);
  color: var(--ink);
}

.buy-msg.is-bad {
  background: var(--danger-soft);
  border-left-color: var(--danger);
  color: var(--danger);
}

/* ---------- purchase receipt ---------- */

.receipt {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: var(--sp-5);
  background: var(--surface);
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
}

.receipt-name {
  margin: 0;
  font-size: var(--step-2);
}

.receipt-rows {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0;
}

.receipt-rows > div {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--sp-4);
  padding-bottom: var(--sp-2);
  border-bottom: 1px dashed var(--line);
}

.receipt-rows > div:last-child { border-bottom: 0; padding-bottom: 0; }

.receipt-rows dt {
  margin: 0;
  color: var(--muted);
  font-size: var(--step--1);
}

.receipt-rows dd {
  margin: 0;
  font-weight: 600;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* A gateway reference is a long unbroken string; let it wrap rather than push
   the card sideways on a phone. */
.receipt-ref {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  font-weight: 500;
  word-break: break-all;
}

.plan-foot {
  text-align: center;
  font-size: var(--step--1);
  color: var(--muted);
  margin: 0;
}


/* ---------- customer account ---------- */

/* The account pages are read, not browsed: a fixed rail of destinations on the
   left, the record itself on the right. Same shape as the program detail page,
   so the site does not gain a second idea of what an aside is. */
.account-layout {
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr);
  gap: clamp(var(--sp-5), 4vw, var(--sp-7));
  align-items: start;
}
@media (max-width: 900px) {
  .account-layout { grid-template-columns: 1fr; }
}

.account-nav {
  position: sticky;
  top: 96px;
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  padding: var(--sp-5);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
}

.account-who {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding-bottom: var(--sp-4);
  border-bottom: 1px solid var(--line);
}
.account-initial {
  flex: 0 0 42px;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 700;
  color: var(--green-deep);
  background: var(--green-soft);
}
.account-who-text { display: flex; flex-direction: column; min-width: 0; }
.account-who-text strong {
  color: var(--navy);
  font-size: var(--step-0);
  line-height: 1.2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.account-who-text span { font-size: var(--step--1); color: var(--muted); }

.account-links { display: flex; flex-direction: column; gap: 2px; }
.account-links a {
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--radius-sm);
  font-weight: 600;
  font-size: var(--step--1);
  color: var(--ink-2);
  text-decoration: none;
  transition: background-color .15s var(--ease), color .15s var(--ease);
}
.account-links a:hover { background: var(--surface-2); color: var(--navy); }
.account-links a[aria-current="page"] {
  background: var(--green-soft);
  color: var(--green-deep);
}
/* Sign out is the one destructive thing on the rail, so it sits apart. */
.account-out {
  margin-top: var(--sp-3);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--line);
  border-radius: 0;
  color: var(--muted);
}
.account-links .account-out:hover { color: var(--danger); background: transparent; }

/* On a phone the rail took the whole first screen, so every account page
   opened on its own menu and the record itself started below the fold. Below
   900px it lies down into a strip of tabs that scrolls sideways instead.
   This block has to come after the rules above, not before them - it overrides
   them at equal specificity, so the cascade decides it on order. */
@media (max-width: 900px) {
  .account-nav {
    position: static;
    padding: var(--sp-4);
    gap: var(--sp-3);
  }
  .account-who { padding-bottom: var(--sp-3); }

  .account-links {
    flex-direction: row;
    gap: var(--sp-2);
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .account-links::-webkit-scrollbar { display: none; }

  .account-links a {
    flex: 0 0 auto;
    white-space: nowrap;
    border-radius: var(--radius-pill);
    background: var(--surface-2);
  }
  .account-links a[aria-current="page"] { background: var(--green-soft); }

  .account-links .account-out {
    margin-top: 0;
    padding-top: var(--sp-3);
    border-top: 0;
    border-radius: var(--radius-pill);
  }
}

.account-body { min-width: 0; }

/* The one thing a client opens this section to check. */
.plan-status {
  padding: var(--sp-6);
  border-radius: var(--radius-lg);
  border: 1px solid var(--line);
  background: var(--surface);
  box-shadow: var(--shadow-xs);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  align-items: flex-start;
}
.plan-status.is-on {
  border-color: var(--green);
  box-shadow: var(--shadow), var(--ring-green);
}
.plan-status h2 { margin: 0; }
.plan-status-line { margin: 0; color: var(--ink-2); font-size: var(--step--1); }

.account-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--sp-5);
  margin: 0;
  padding: var(--sp-5);
  border-radius: var(--radius-lg);
  border: 1px solid var(--line);
  background: var(--surface);
  box-shadow: var(--shadow-xs);
}
.account-stats div { display: flex; flex-direction: column; gap: 2px; }
.account-stats dt {
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 700;
  color: var(--green-deep);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.account-stats dd {
  margin: 0;
  font-size: var(--step--1);
  color: var(--muted);
  letter-spacing: .06em;
  text-transform: uppercase;
  font-weight: 600;
}


/* ---------- record tables ---------- */

/* A bill has five columns and a phone has none to spare, so the table scrolls
   inside its own box rather than pushing the page sideways. */
.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow-xs);
}

.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--step--1);
  min-width: 480px;
}
.data-table th,
.data-table td {
  padding: var(--sp-3) var(--sp-4);
  text-align: left;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
.data-table thead th {
  background: var(--surface-2);
  color: var(--muted);
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  font-size: 0.6875rem;
}
.data-table tbody tr:last-child td { border-bottom: 0; }
.data-table tbody tr:hover { background: var(--surface-2); }
.data-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.data-table .muted-cell { color: var(--muted); }

.data-table tfoot td {
  background: var(--surface-2);
  border-bottom: 0;
  font-weight: 600;
}
.data-table tfoot .is-total td {
  font-size: var(--step-0);
  font-weight: 700;
  color: var(--navy);
}


/* ---------- plan history ---------- */

.plan-history {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}

.plan-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-4);
  align-items: center;
  justify-content: space-between;
  padding: var(--sp-4) var(--sp-5);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow-xs);
}
.plan-row.is-on { border-color: var(--green); box-shadow: var(--shadow-xs), var(--ring-green); }
.plan-row-main { min-width: 0; }
.plan-row-main h3 { margin: 0; font-size: var(--step-0); color: var(--navy); }
.plan-row-dates { margin: 2px 0 0; font-size: var(--step--1); color: var(--muted); }
.plan-row-state { display: flex; align-items: center; gap: var(--sp-3); }
.pill-on { background: var(--green); color: #fff; }
.plan-left { font-size: var(--step--1); font-weight: 600; color: var(--green-deep); }


/* ---------- sign in and register ---------- */

.auth-wrap {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr);
  gap: clamp(var(--sp-5), 4vw, var(--sp-7));
  align-items: start;
  max-width: 62rem;
}
@media (max-width: 820px) {
  .auth-wrap { grid-template-columns: 1fr; }
}

.auth-card {
  padding: clamp(var(--sp-5), 4vw, var(--sp-7));
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
}

.auth-aside {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  align-items: flex-start;
  padding: var(--sp-6) var(--sp-5);
  border-radius: var(--radius-lg);
  background: var(--surface-2);
  border: 1px solid var(--line);
}
.auth-aside h2 { margin: 0; font-size: var(--step-1); }
.auth-aside p { margin: 0; color: var(--ink-2); font-size: var(--step--1); }
.auth-aside .btn { width: 100%; }

/* ---------- profile form ---------- */

.profile-form {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  overflow: hidden;
}

/* Each block is a titled section with a rule under it, so "your details" and
   "sign-in" read as two decisions rather than one long list of boxes. */
.pf-block {
  padding: clamp(var(--sp-5), 3.5vw, var(--sp-6));
  border-bottom: 1px solid var(--line);
}

.pf-head { margin-bottom: var(--sp-5); }
.pf-head h2 {
  margin: 0;
  font-size: var(--step-1);
  color: var(--navy);
}
.pf-head p {
  margin: var(--sp-2) 0 0;
  font-size: var(--step--1);
  color: var(--muted);
}

/* Two even columns. The fields used to be flex children on a start-aligned
   parent, so each one shrank to whatever its value happened to be - four
   different widths down one form. */
.pf-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-5);
}
.pf-grid .pf-wide { grid-column: 1 / -1; }
.pf-grid .field { min-width: 0; }
.pf-grid .input,
.pf-grid .textarea { width: 100%; }
.pf-grid .textarea { resize: vertical; min-height: 5.5rem; }

@media (max-width: 620px) {
  .pf-grid { grid-template-columns: 1fr; }
}

/* A field that is shown but not editable. The lock is the explanation - a
   greyed box on its own just looks broken. */
.input-locked { position: relative; display: block; }
.input-locked .input {
  background: var(--surface-2);
  color: var(--muted);
  padding-right: 2.4rem;
  cursor: not-allowed;
}
.input-locked svg {
  position: absolute;
  right: var(--sp-4);
  top: 50%;
  transform: translateY(-50%);
  color: var(--muted);
  pointer-events: none;
}

.pf-warn {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  margin: var(--sp-5) 0 0;
  padding: var(--sp-4);
  border-radius: var(--radius);
  background: var(--surface-2);
  color: var(--ink-2);
  font-size: var(--step--1);
  line-height: 1.5;
}
.pf-warn svg { flex: 0 0 auto; margin-top: .15em; color: var(--navy); }

/* The actions sit on their own bar at the foot of the card, so a long form
   still ends somewhere obvious. */
.pf-foot {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  padding: var(--sp-5) clamp(var(--sp-5), 3.5vw, var(--sp-6));
  background: var(--surface-2);
  border-bottom: 0;
}

.pf-aside {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-4);
  padding: var(--sp-5);
  border: 1px solid var(--line);
  border-left: 3px solid var(--green);
  border-radius: var(--radius);
  background: var(--surface);
}
.pf-aside-icon {
  flex: 0 0 40px;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--green-soft);
  color: var(--green-deep);
}
/* ---------- slider management ---------- */

.slide-card {
  padding: var(--sp-5);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow-xs);
}
/* A hidden slide is dimmed rather than moved, so the running order on this
   page is the running order on the home page. */
.slide-card.is-off { opacity: .62; }

.slide-card-head {
  display: grid;
  grid-template-columns: 200px minmax(0, 1fr) auto;
  gap: var(--sp-5);
  align-items: start;
}
@media (max-width: 780px) {
  .slide-card-head { grid-template-columns: 1fr; }
}

.slide-thumb {
  aspect-ratio: 16 / 7;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--surface-2);
  display: grid;
  place-items: center;
}
.slide-thumb img { width: 100%; height: 100%; object-fit: cover; }
.slide-missing {
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--danger);
}

.slide-meta { display: flex; flex-direction: column; gap: var(--sp-2); min-width: 0; }
.slide-meta p { margin: 0; }
.slide-pos {
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--muted);
}
.slide-alt-text { color: var(--ink-2); font-size: var(--step--1); }

.slide-actions { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.slide-actions form { margin: 0; }
.btn.is-danger { color: var(--danger); border-color: var(--danger); }
.btn.is-danger:hover { background: var(--danger); color: #fff; }

.slide-edit { margin-top: var(--sp-5); border-top: 1px solid var(--line); padding-top: var(--sp-4); }
.slide-edit summary {
  cursor: pointer;
  font-weight: 700;
  font-size: var(--step--1);
  color: var(--green-deep);
}
.slide-edit[open] summary { margin-bottom: var(--sp-5); }

.slide-form-foot { margin-top: var(--sp-5); }

/* A checkbox and its words on one line, aligned on the box rather than the
   text baseline. */
.check {
  display: flex !important;
  align-items: center;
  gap: var(--sp-3);
  font-weight: 500;
  cursor: pointer;
}
.check input { width: 17px; height: 17px; accent-color: var(--green); }

.field input[type="file"] {
  padding: var(--sp-3);
  font-size: var(--step--1);
}


/* ---------- register form ---------- */

/* Narrower than the account pages: this one is a form and nothing else, and a
   field 900px wide reads as a mistake. */
.register-wrap {
  max-width: 54rem;
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
}

.register-form {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}

/* Age and BMI are worked out, not typed. They are shown flat and unfocusable
   so nobody waits for a cursor that is not coming. */
.input.is-derived {
  background: var(--surface-2);
  border-style: dashed;
  color: var(--navy);
  font-weight: 700;
  cursor: default;
}
.input.is-derived::placeholder { font-weight: 400; color: var(--muted); }

.label-unit {
  font-weight: 500;
  color: var(--muted);
  text-transform: none;
  letter-spacing: 0;
}

/* +91 sits inside the field rather than beside it, so the country code cannot
   be mistaken for the first two digits of the number. */
.input-prefixed { display: flex; align-items: stretch; }
.input-prefix {
  display: flex;
  align-items: center;
  padding: 0 var(--sp-4);
  border: 1px solid var(--line);
  border-right: 0;
  border-radius: var(--radius-sm) 0 0 var(--radius-sm);
  background: var(--surface-2);
  color: var(--ink-2);
  font-weight: 600;
  font-size: var(--step--1);
  white-space: nowrap;
}
.input-prefixed .input {
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  min-width: 0;
  flex: 1;
}

.input-reveal { position: relative; display: block; }
.input-reveal .input { width: 100%; padding-right: 2.8rem; }
.reveal-btn {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--muted);
  cursor: pointer;
}
.reveal-btn:hover { color: var(--navy); background: var(--surface-2); }
.reveal-btn.is-on { color: var(--green-deep); }

.pf-foot-note {
  flex-basis: 100%;
  margin: 0;
  font-size: var(--step--1);
  color: var(--muted);
}

.form-note.center { text-align: center; }

.pf-aside strong { color: var(--navy); font-size: var(--step-0); }
.pf-aside p {
  margin: var(--sp-2) 0 0;
  font-size: var(--step--1);
  color: var(--ink-2);
  line-height: 1.55;
}


/* ---------- measurements ---------- */

.metric-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
  gap: var(--sp-4);
}

.metric {
  display: flex;
  flex-direction: column;
  padding: var(--sp-4) var(--sp-5);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow-xs);
}
/* "Subcutaneous fat" wraps to two lines and "BMI" does not, which left the
   numbers on one row sitting at different heights. The label holds two lines
   whether it needs them or not, so every value starts on the same line. */
.metric-label {
  margin: 0;
  min-height: 2.4em;
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  line-height: 1.2;
  color: var(--muted);
}
.metric-value {
  margin: var(--sp-2) 0 0;
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 700;
  line-height: 1;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
}
.metric-unit {
  margin-left: .28em;
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--muted);
}
/* Pushed to the floor of the tile, so the deltas line up across the row even
   where a label above them took an extra line. */
.metric-delta {
  margin: var(--sp-3) 0 0;
  padding-top: var(--sp-3);
  border-top: 1px solid var(--line);
  font-size: var(--step--1);
  font-weight: 600;
  margin-top: auto;
}

/* Good and bad, not up and down. Weight falling is progress and skeletal
   muscle falling is not, so the direction alone cannot pick the colour - the
   view passes which way each reading is meant to go. */
.is-good { color: var(--green-deep); }
.is-bad  { color: var(--danger); }
.is-flat { color: var(--muted); font-weight: 500; }

.metric-since {
  margin: 0;
  padding: var(--sp-4) var(--sp-5);
  border-radius: var(--radius);
  background: var(--surface-2);
  font-size: var(--step-0);
}
.metric-since strong {
  font-family: var(--font-display);
  font-size: var(--step-1);
}

/* "vs last visit" is the caption, not the number - it stays out of the way. */
.delta-cap {
  font-weight: 500;
  color: var(--muted);
  white-space: nowrap;
}

/* The change riding beside a number in a table cell. */
.cell-delta {
  margin-left: var(--sp-2);
  font-size: 0.6875rem;
  font-weight: 700;
}

/* A hint under a field, not a second label - quieter than the label above it,
   so the two are never confused. */
.field-hint {
  display: block;
  margin-top: var(--sp-2);
  font-size: var(--step--1);
  color: var(--muted);
  line-height: 1.5;
}

.input:disabled {
  background: var(--surface-2);
  color: var(--muted);
  cursor: not-allowed;
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-4);
  padding: clamp(var(--sp-6), 6vw, var(--sp-8)) var(--sp-5);
  text-align: center;
  border: 1px dashed var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface-2);
  color: var(--muted);
}
.empty-state p { margin: 0; }


/* ===========================================================================
   Basket, checkout and orders
   ===========================================================================
   The product card used to be one big anchor. It now has to hold an Add
   button as well, and a form inside an anchor is not valid HTML, so the card
   is a <div>, the anchor covers the picture and the name through an overlay,
   and the button sits above that overlay on its own.
   ------------------------------------------------------------------------ */

.product-card { position: relative; display: flex; flex-direction: column; }
.product-card .card-link { display: block; color: inherit; }
.product-card .card-link:hover { text-decoration: none; }
.product-card .card-link::after {
  content: ""; position: absolute; inset: 0; z-index: 0;
}

.card-add {
  position: relative; z-index: 1;
  margin-top: auto;
  padding: 0 var(--sp-5) var(--sp-5);
}
/* Sold out, or unpriced: the tile is a link through to the enquiry form and
   carries no button, so nothing here needs a disabled state. */
.product-card.is-out .card-add { display: none; }

/* ---------- add to basket, on the product page ---------- */

.buy-box { display: flex; flex-direction: column; gap: var(--sp-3); }
.buy-form { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; }
.buy-form .btn { flex: 1 1 12rem; }

/* Wide enough for two digits and the spinner, and no wider - a full-width
   number box next to a button reads as the more important of the two. */
.qty-input {
  width: 5.5rem;
  flex: none;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* ---------- the basket ---------- */

.cart-lines { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-3); }

.cart-line {
  display: grid;
  grid-template-columns: 72px 1fr auto auto auto;
  align-items: center;
  gap: var(--sp-4);
  padding: var(--sp-3);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
}
/* A line that cannot be sold is dimmed rather than hidden, so it is obvious
   why the total does not match what was picked out. */
.cart-line.is-out { opacity: .6; }

.cart-thumb {
  width: 72px; height: 72px;
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--surface-2);
  display: grid; place-items: center;
}
.cart-thumb img { width: 100%; height: 100%; object-fit: cover; }
.cart-thumb .placeholder-media img { width: 60%; height: auto; object-fit: contain; opacity: .5; }

.cart-line-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cart-name { font-weight: 700; color: var(--navy); }
.cart-name:hover { color: var(--green-deep); }
.cart-weight,
.cart-rate { font-size: var(--step--1); color: var(--muted); }

.cart-flag { font-size: var(--step--1); font-weight: 600; margin-top: 2px; }
.cart-flag.out  { color: var(--danger); }
.cart-flag.warn { color: var(--green-deep); }

.cart-line-total {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--step-0);
  color: var(--navy);
  font-variant-numeric: tabular-nums;
  min-width: 4.5rem;
  text-align: right;
}

.cart-actions {
  display: flex; align-items: center; gap: var(--sp-4);
  flex-wrap: wrap;
  margin-top: var(--sp-4);
}

/* Remove, on the row it belongs to.
   Sits quiet in grey until the row is hovered or the button is focused, then
   turns red - present when wanted, not shouting on every line. It is a real
   button with a title and an aria-label, so it is reachable by keyboard and
   announced properly; the icon alone would say nothing to a screen reader. */
.cart-remove {
  display: grid; place-items: center;
  width: 38px; height: 38px;
  margin-left: var(--sp-2);
  padding: 0;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: var(--muted);
  cursor: pointer;
  transition: color .15s var(--ease), background-color .15s var(--ease), border-color .15s var(--ease);
}
.cart-line:hover .cart-remove { color: var(--ink-2); }
.cart-remove:hover {
  color: var(--danger);
  background: var(--danger-soft);
  border-color: var(--danger-soft);
}
.cart-remove:focus-visible {
  outline: 2px solid var(--danger);
  outline-offset: 1px;
  color: var(--danger);
}

/* ---------- money summary, shared by the basket and the checkout ---------- */

.cart-summary { padding: var(--sp-5); display: flex; flex-direction: column; gap: var(--sp-3); }

.sum-row {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--sp-4);
  font-size: var(--step-0);
  font-variant-numeric: tabular-nums;
}
.sum-row span:first-child { color: var(--ink-2); }

.sum-total {
  padding-top: var(--sp-3);
  border-top: 1px solid var(--line);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--step-1);
  color: var(--navy);
}
.sum-total span:first-child { color: var(--navy); }

.sum-lines { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-3); }
.sum-lines li {
  display: flex; justify-content: space-between; gap: var(--sp-3);
  font-size: var(--step--1);
  padding-bottom: var(--sp-3);
  border-bottom: 1px solid var(--line);
}
.sum-lines li:last-child { border-bottom: 0; padding-bottom: 0; }
.sum-name { display: flex; flex-direction: column; gap: 1px; color: var(--navy); font-weight: 600; }
.sum-name small { font-weight: 400; color: var(--muted); }
.sum-amt { font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ---------- checkout ---------- */

.checkout-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  gap: var(--sp-6);
  align-items: start;
}
.checkout-form .card { padding: var(--sp-5); }
/* The summary follows down a long address form on a wide screen; on a narrow
   one it is simply the next thing after it. */
.checkout-summary { position: sticky; top: var(--sp-6); }
.checkout-summary .card { padding: var(--sp-5); }

.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-4); }
.field-row-3 { grid-template-columns: 1fr 1fr 1fr; }
.opt { font-weight: 400; color: var(--muted); }

/* ---------- an order ---------- */

.status-pill {
  display: inline-block;
  padding: 2px var(--sp-3);
  border-radius: var(--radius-pill);
  font-size: 0.6875rem; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase;
  background: var(--surface-2); color: var(--ink-2);
  white-space: nowrap;
}
.st-confirmed,
.st-pending   { background: var(--green-soft); color: var(--green-deep); }
.st-packed,
.st-shipped   { background: #fff3d6; color: #8a5b00; }
.st-delivered { background: var(--green-soft); color: var(--green-deep); }
.st-cancelled { background: var(--danger-soft); color: var(--danger); }

.order-meta {
  display: flex; flex-wrap: wrap; gap: var(--sp-5);
  padding: var(--sp-4) var(--sp-5);
}
.order-meta > div { display: flex; flex-direction: column; gap: 2px; }
.meta-k {
  font-size: 0.6875rem; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--muted);
}
.meta-v { font-weight: 600; color: var(--navy); }
.meta-v.mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: var(--step--1); }

.address { line-height: 1.7; }

/* The thank-you page. */
.done-head { text-align: center; }
.done-tick {
  display: grid; place-items: center;
  width: 76px; height: 76px; margin: 0 auto;
  border-radius: 50%;
  background: var(--green-soft); color: var(--green-deep);
}

@media (max-width: 900px) {
  .checkout-layout { grid-template-columns: 1fr; }
  .checkout-summary { position: static; }
}

@media (max-width: 600px) {
  /* The picture, the name and the price stay on one line; the quantity box
     drops underneath, where it has room to be tapped. */
  .cart-line {
    grid-template-columns: 56px 1fr auto auto;
    gap: var(--sp-3);
  }
  .cart-thumb { width: 56px; height: 56px; }
  .cart-line-qty { grid-column: 2 / -1; }
  .qty-input { width: 5rem; }

  .field-row,
  .field-row-3 { grid-template-columns: 1fr; }

  .order-meta { gap: var(--sp-4); }
}

/* ---------- staff orders screen ---------- */

/* Filters on the left, the search box on the right, and on a narrow screen the
   search drops underneath the filters rather than squeezing them. */
.orders-bar {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: var(--sp-4); flex-wrap: wrap;
}
.orders-bar .filter-bar { flex: 1 1 20rem; }

.orders-search { display: flex; gap: var(--sp-2); flex: 0 1 22rem; }
.orders-search .input { min-width: 0; }

.manage-cols {
  display: grid;
  grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
  gap: var(--sp-5);
  align-items: start;
}
.manage-cols .card { padding: var(--sp-5); }

/* The address is here to be copied onto a parcel, so it is set larger than
   body text and left selectable as one block. */
.address-block {
  font-size: var(--step-0);
  line-height: 1.8;
  padding: var(--sp-4);
  background: var(--surface-2);
  border-radius: var(--radius-sm);
  user-select: all;
}

@media (max-width: 900px) {
  .manage-cols { grid-template-columns: 1fr; }
  .orders-search { flex: 1 1 100%; }
}

/* ---------- recipe reel ----------
   A written recipe can carry a link to the reel of the same dish. The clinic
   pastes the link in the admin panel; these are the two places it shows.

   Instagram's own colours are deliberately not used. A magenta gradient button
   in the middle of a page built on green and navy reads as an advertisement
   someone else put there. The mark alone says whose it is. */

.reel-card {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  padding: var(--sp-4) var(--sp-5);
  background: var(--green-soft);
  border: 1px solid var(--green);
  border-radius: var(--radius-lg);
  color: inherit;
  text-decoration: none;
  transition: transform .15s var(--ease), box-shadow .15s var(--ease), background-color .15s var(--ease);
}
.reel-card:hover {
  background: #E7F2D9;
  transform: translateY(-2px);
  box-shadow: var(--shadow-sm);
}

.reel-play {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border-radius: var(--radius-pill);
  background: var(--green);
  color: #fff;
  /* The triangle is optically off-centre in its own box; nudge it back. */
  padding-left: 3px;
}

.reel-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.reel-title {
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--navy);
  line-height: 1.3;
}
.reel-sub { font-size: var(--step--1); color: var(--ink-2); }

.reel-mark { flex: 0 0 auto; color: var(--green-deep); margin-left: auto; }

/* Below the mark is the first thing to go - the play button already says this
   is a video, and the words already say where it goes. */
@media (max-width: 520px) {
  .reel-card { padding: var(--sp-4); gap: var(--sp-3); }
  .reel-mark { display: none; }
  .reel-sub { display: none; }
}

/* The mark on a recipe card in the list, opposite the category tag. */
.media-reel {
  position: absolute;
  right: var(--sp-3);
  top: var(--sp-3);
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  background: rgba(27, 33, 25, .78);
  color: #fff;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  padding: 0.3rem 0.5rem;
  border-radius: var(--radius-sm);
}
