/* ══════════════════════════════════════════════════════════════════════════
   MEDBUS — ABOUT PAGE
   ──────────────────────────────────────────────────────────────────────────
   Loaded only by frontend/about.blade.php, on top of medbus-home.css. Nothing
   here redefines a token or a shared component: every rule is either a new
   about-only block (.mb-ahero, .mb-purpose, .mb-pledge) or a modifier on an
   existing one (.mb-benefits--start, .mb-features--about).

   Motion policy is inherited, not restated. medbus-home.css already carries
   the global `prefers-reduced-motion` block that collapses every animation
   and transition on `.mb *` to 0.001ms, so each keyframe below is written to
   END where it STARTS — a single 0.001ms run then leaves the element exactly
   where the static layout puts it, with nothing stranded mid-flight.

   Two IDs are load-bearing: #mb-hero and #mb-features. medbus-home.js watches
   for those and toggles `.is-visible`, which is what starts and stops every
   drift on the page. They are why none of this needs new JS.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── 01 · HERO ART ──────────────────────────────────────────────────────
   The hero reuses .mb-hero wholesale (gradient, waves, padding, button
   choreography). Only the right-hand column is new. */
.mb-ahero__art {
  position: relative;
  /* Bottom-anchored for the same reason the home hero is: with the grid
     centring items, an art column shorter than the copy column leaves the
     cut-out hovering above the section edge instead of standing on it. */
  align-self: end;
  min-height: clamp(430px, 48vw, 680px);
  margin-bottom: calc(-1 * var(--mb-hero-pb));
}

/* — Backdrop —
   The shape the figure stands on: one large blue squircle with a paler disc
   overlapping its left, exactly the arrangement in the reference. Both are
   confined to the art column on purpose. Spread across the whole hero they
   would pass under the headline and the lede, and a solid tint crossing a
   glyph stem drops muted body text under AA — the same constraint the
   closing section's ring mask exists for.

   Everything here animates transform only, so the whole backdrop is one
   compositor pass and never repaints. Paused until the hero is on screen. */
.mb-ahero__stage {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

/* The blue disc. A true circle — aspect-ratio 1 plus a 50% radius — rather
   than the squircle this was: at this size an organic blob reads as a
   smudge behind the figure, where a circle reads as a deliberate stage.

   Positioned with `left` maths rather than translateX(-50%), because the
   breathe animation owns `transform` and a centring translate there would be
   overwritten the moment it started.

   Four layers on one element, so it is still a single paint: a broad wash, a
   lit top-left shoulder, a white floor bounce along the bottom edge, and an
   inner rim. */
.mb-ahero__blob {
  position: absolute;
  /* 73.6% is 80% of the 92% this was. `left` carries the centring because the
     breathe animation owns `transform` — a translateX(-50%) there would be
     overwritten the moment it started. */
  left: 13.2%;
  bottom: 6%;
  width: 73.6%;
  aspect-ratio: 1;
  border-radius: 50%;
  background:
    radial-gradient(48% 42% at 30% 20%, rgba(255, 255, 255, .5), transparent 62%),
    radial-gradient(70% 44% at 52% 104%, rgba(255, 255, 255, .3), transparent 68%),
    linear-gradient(158deg, #eaf5ff 0%, #cbe5fd 46%, #a8d2f8 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .7),
    0 36px 70px -40px rgba(9, 106, 201, .26);
  animation: mb-blob 18s var(--mb-ease) infinite;
  animation-play-state: paused;
}
/* Paler disc overlapping the blob's left shoulder. */
.mb-ahero__disc {
  position: absolute;
  left: -2%;
  bottom: 18%;
  width: 46%;
  aspect-ratio: 1;
  border-radius: 50%;
  background:
    radial-gradient(46% 46% at 34% 28%, rgba(255, 255, 255, .82), transparent 66%),
    linear-gradient(160deg, #e9f2fe 0%, #cbe2fb 100%);
  animation: mb-blob 22s var(--mb-ease) infinite reverse;
  animation-play-state: paused;
}
.mb-hero.is-visible .mb-ahero__blob,
.mb-hero.is-visible .mb-ahero__disc { animation-play-state: running; }

/* Breathes rather than travels: a backdrop this large sliding around would
   read as a bug. Returns to its start, so reduced motion leaves it put. */
@keyframes mb-blob {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  33%      { transform: translate3d(0, -10px, 0) scale(1.025); }
  66%      { transform: translate3d(0, 6px, 0) scale(.988); }
}

/* Small bubbles riding over the backdrop for depth. */
.mb-ahero__bubbles { position: absolute; inset: -8% -6% 0; z-index: 1; pointer-events: none; }
.mb-ahero__bubbles span {
  position: absolute;
  border-radius: 50%;
  will-change: transform;
  animation: mb-bub 15s var(--mb-ease) infinite;
  animation-play-state: paused;
}
.mb-hero.is-visible .mb-ahero__bubbles span { animation-play-state: running; }
.mb-ahero__bubbles span:nth-child(1),
.mb-ahero__bubbles span:nth-child(2) {
  background:
    radial-gradient(38% 38% at 32% 28%, rgba(255, 255, 255, .95), rgba(255, 255, 255, 0) 60%),
    linear-gradient(150deg, rgba(255, 255, 255, .55) 0%, rgba(255, 255, 255, .18) 100%);
}
.mb-ahero__bubbles span:nth-child(1) { width: 11%; aspect-ratio: 1; left: 4%;   top: 22%; animation-duration: 16s; animation-delay: -1s; }
.mb-ahero__bubbles span:nth-child(2) { width: 7%;  aspect-ratio: 1; right: 6%;  top: 66%; animation-duration: 12s; animation-delay: -5s; }
.mb-ahero__bubbles span:nth-child(3),
.mb-ahero__bubbles span:nth-child(4) { background: #fff; opacity: .6; }
.mb-ahero__bubbles span:nth-child(3) { width: 2.4%; aspect-ratio: 1; right: 24%; top: 18%; animation-duration: 11s; animation-delay: -2s; }
.mb-ahero__bubbles span:nth-child(4) { width: 1.8%; aspect-ratio: 1; left: 24%;  top: 86%; animation-duration: 13s; animation-delay: -6s; }

@keyframes mb-bub {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  25%      { transform: translate3d(10px, -16px, 0) scale(1.04); }
  50%      { transform: translate3d(-6px, -26px, 0) scale(1); }
  75%      { transform: translate3d(-12px, -12px, 0) scale(.97); }
}

/* — The figure —
   Wrapper rather than a bare <img> because the tablet screen is positioned
   as a percentage of the PHOTO's box, not the column's. Absolute + width:auto
   shrink-to-fits the wrapper to the image at every height, so those
   percentages stay locked to the glass no matter how the hero scales. */
.mb-ahero__figure {
  position: absolute;
  left: 50%;
  bottom: 0;
  z-index: 3;
  height: 100%;
  transform: translateX(-50%);
  filter: drop-shadow(0 22px 34px rgba(11, 34, 56, .16));
}
img.mb-ahero__doctor {
  display: block;
  height: 100%;
  width: auto;
  max-width: none;
}

/* — In-tablet screen —
   Measured off the source PNG: the glass sits at 6.626%/26.007% of the
   photo, 26.300% wide and 26.926% tall. Drawn in CSS/SVG rather than compped
   into the image so it stays crisp at every width and can animate.

   Three screens on one 13s clock, cross-faded so the glass never changes
   height mid-cycle:

     0 - 26%   the wordmark, with a ring tracking around it
     32 - 58%  a growth chart: cylinder bars rising under a trend arrow
     64 - 94%  a layered cylinder infographic building from the base up
     94 - 100% back to the wordmark

   Each build FINISHES well before its screen fades — the bars are full by
   46% and hold to 58%, the tower is complete by 82% and holds to 94% — so
   the viewer always sees a finished chart, not a chart caught mid-grow.

   aria-hidden — the logo is already in the header and this is decoration. */
.mb-ahero__screen {
  position: absolute;
  left: 6.626%;
  top: 26.007%;
  width: 26.300%;
  height: 26.926%;
  border-radius: 3%;
  background: radial-gradient(78% 60% at 50% 26%, #ffffff 0%, #eef6ff 100%);
  overflow: hidden;
  /* Everything inside is sized off this font-size, which is what keeps the
     whole screen — layout AND animation — proportional instead of needing a
     tuned value per breakpoint.

     Derived rather than guessed: the glass is 18.23% of .mb-ahero__art's
     height (26.300% of the photo width x the photo aspect of 0.6933), so a
     font that tracks that height tracks the glass. The clamp is the art's own
     clamp(430px, 48vw, 680px) multiplied by 0.02206. */
  font-size: clamp(9.49px, 1.059vw, 15px);
}

/* Back effect: one soft glow drifting behind the screens. No grid — a ruled
   backdrop at this size reads as moire rather than as graph paper. */
.mb-ahero__screen::after {
  content: "";
  position: absolute;
  inset: -30%;
  background: radial-gradient(38% 38% at 50% 50%, rgba(46, 139, 240, .2), transparent 70%);
  animation: mb-scr-glow 13s var(--mb-ease) infinite;
  animation-play-state: paused;
  pointer-events: none;
}
.mb-hero.is-visible .mb-ahero__screen::after { animation-play-state: running; }
/* Returns to its start, so reduced motion leaves the glow centred. */
@keyframes mb-scr-glow {
  0%, 100% { transform: translate3d(0, 0, 0); }
  50%      { transform: translate3d(0, 16%, 0); }
}

/* — The three stacked screens —
   Written so a reduced-motion collapse lands on "logo visible, both charts
   hidden" — a complete, sensible still rather than a half-drawn chart. */
.mb-scr__page {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  /* em, NOT %. Percentage padding resolves against the CONTAINING BLOCK's
     width, and this is absolutely positioned inside a box whose containing
     block is the whole photo — a "5%" here was 5% of 249px, not of the 66px
     glass, and ate two thirds of the screen. */
  padding: .5em;
  gap: .35em;
  animation-play-state: paused;
}
.mb-scr__page--logo   { animation: mb-scr-page-a 13s var(--mb-ease) infinite; }
.mb-scr__page--growth { animation: mb-scr-page-b 13s var(--mb-ease) infinite; }
.mb-scr__page--stack  { animation: mb-scr-page-c 13s var(--mb-ease) infinite; }
.mb-hero.is-visible .mb-scr__page { animation-play-state: running; }

@keyframes mb-scr-page-a {
  0%, 26%   { opacity: 1; transform: scale(1); }
  32%, 94%  { opacity: 0; transform: scale(.93); }
  100%      { opacity: 1; transform: scale(1); }
}
@keyframes mb-scr-page-b {
  0%, 26%   { opacity: 0; transform: scale(.93); }
  32%, 58%  { opacity: 1; transform: scale(1); }
  64%, 100% { opacity: 0; transform: scale(.93); }
}
@keyframes mb-scr-page-c {
  0%, 58%   { opacity: 0; transform: scale(.93); }
  64%, 94%  { opacity: 1; transform: scale(1); }
  100%      { opacity: 0; transform: scale(.93); }
}

/* ── Screen 1 · wordmark + tracking ring ─────────────────────────────── */
.mb-scr__logo {
  position: relative;
  z-index: 1;
  flex: none;
  width: 86%;
  height: auto;
  /* NOT gated on .is-visible. animation-play-state pauses an animation at its
     FIRST keyframe, and this starts at opacity 0 — gating it left the tablet
     blank until the IntersectionObserver happened to fire, which is a blank
     screen on any load where the observer is slow, throttled in a background
     tab, or never runs at all. Looping decoration can be paused at frame
     zero safely; an entrance cannot. */
  animation: mb-scr-logo-in .9s var(--mb-ease) both;
}
@keyframes mb-scr-logo-in {
  from { opacity: 0; transform: scale(.8) translateY(14%); }
  60%  { opacity: 1; }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}

/* Conic gradient masked down to a hairline annulus, then rotated — one
   composited transform, no repaint. -webkit-mask is carried for Safari. */
.mb-scr__ring {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 78%;
  aspect-ratio: 1;
  margin: -39% 0 0 -39%;
  border-radius: 50%;
  background: conic-gradient(from 0deg,
    rgba(46, 139, 240, 0) 0 52%,
    rgba(46, 139, 240, .55) 76%,
    var(--mb-blue) 96%,
    rgba(46, 139, 240, 0) 100%);
  -webkit-mask: radial-gradient(closest-side, transparent 0 84%, #000 85%);
          mask: radial-gradient(closest-side, transparent 0 84%, #000 85%);
  animation: mb-scr-spin 1.6s linear infinite;
  animation-play-state: paused;
}
.mb-hero.is-visible .mb-scr__ring { animation-play-state: running; }
/* A full turn ends where it starts, so reduced motion leaves a static ring. */
@keyframes mb-scr-spin { to { transform: rotate(360deg); } }

/* ── Shared chrome for both chart screens ────────────────────────────── */
.mb-scr__head { display: flex; align-items: center; gap: .35em; width: 100%; flex: none; }
.mb-scr__head i { display: block; height: .3em; min-height: 2px; border-radius: 999px; background: #bcd8f4; }
.mb-scr__head i:first-child { width: 40%; background: var(--mb-blue); }
.mb-scr__head i:last-child  { width: 20%; margin-left: auto; background: #34c98a; }

.mb-scr__load {
  position: relative;
  width: 100%;
  height: .26em;
  min-height: 2px;
  flex: none;
  border-radius: 999px;
  background: #dbe9fa;
  overflow: hidden;
}
.mb-scr__load::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(90deg, #7cc0fb, var(--mb-blue));
  transform-origin: 0 50%;
  animation: mb-scr-load 13s var(--mb-ease) infinite;
  animation-play-state: paused;
}
.mb-hero.is-visible .mb-scr__load::before { animation-play-state: running; }
/* Fills across screen 2's window and holds full — scaleX(1) is the right
   thing to leave behind when motion is off. */
@keyframes mb-scr-load {
  0%, 30%   { transform: scaleX(0); }
  50%, 100% { transform: scaleX(1); }
}

/* ── Screen 2 · growth chart ─────────────────────────────────────────── */
.mb-scr__plot {
  position: relative;
  width: 100%;
  flex: 1 1 auto;
  min-height: 0;
  border-bottom: 1px solid rgba(9, 106, 201, .2);
}

/* Cylinder bars. The 3D read comes from two things and no images: a
   left-to-right gradient over the flat colour that darkens both edges and
   leaves a highlight off-centre, and an elliptical border-radius that rounds
   the cap far more across than down. The lighter top face is a ::before
   ellipse rather than a filter, so nothing here spawns a new layer. */
.mb-scr__cyls {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-end;
  gap: .2em;
}
.mb-scr__cyls i {
  position: relative;
  flex: 1 1 0;
  height: var(--h);
  border-radius: 50% 50% 46% 46% / 16% 16% 10% 10%;
  background:
    linear-gradient(90deg,
      rgba(0, 0, 0, .22) 0%,
      rgba(255, 255, 255, .5) 32%,
      rgba(255, 255, 255, .08) 62%,
      rgba(0, 0, 0, .24) 100%),
    var(--c);
  transform-origin: 50% 100%;
  animation: mb-scr-grow 13s var(--mb-ease) infinite;
  animation-play-state: paused;
  animation-delay: calc(var(--i) * .09s);
}
.mb-hero.is-visible .mb-scr__cyls i { animation-play-state: running; }
/* Top face. */
.mb-scr__cyls i::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: .34em;
  border-radius: 50%;
  background: var(--cl);
}
/* Grows to full by 46% and holds to 58% — the whole point of the timing is
   that the bar is COMPLETE while its screen is on. Ends at scaleY(1), so the
   reduced-motion still is a finished chart. */
@keyframes mb-scr-grow {
  0%, 28%  { transform: scaleY(.02); }
  46%      { transform: scaleY(1); }
  100%     { transform: scaleY(1); }
}

/* Trend curve over the bar tops. Four pieces, all on the one 13s clock:
   a white halo, the navy line, round vertex dots and an arrowhead.

   stroke-dashoffset is the only property on this screen that repaints rather
   than composites — acceptable on a ~125-unit path, and it is the only way to
   draw a line ON rather than fade it in. The dots and the head fade instead,
   timed to land just after the line reaches them. */
.mb-scr__spark {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}
.mb-scr__spark path {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  /* The viewBox matches the plot box aspect, so geometry is undistorted — but
     non-scaling-stroke still matters: it keeps the weight identical whether
     the glass is 124px wide or 66px. */
  vector-effect: non-scaling-stroke;
}
.mb-scr__sparkhalo { stroke: #ffffff; stroke-width: 4.2; opacity: .9; }
.mb-scr__sparkline { stroke: #0b2238; stroke-width: 1.9; }

/* Halo and line draw together, so the white never runs ahead of the navy. */
.mb-scr__sparkhalo,
.mb-scr__sparkline {
  stroke-dasharray: 140;
  animation: mb-scr-draw 13s var(--mb-ease) infinite;
  animation-play-state: paused;
}
.mb-scr__sparkdots circle {
  transform-box: fill-box;
  transform-origin: center;
  fill: #ffffff;
  stroke: #0b2238;
  stroke-width: 1.6;
  vector-effect: non-scaling-stroke;
  opacity: 1;
  animation: mb-scr-dot 13s var(--mb-ease) infinite;
  animation-play-state: paused;
}
/* Each dot lights as the line passes it. The line runs 30% -> 50%, so the
   five dots are spread across that window. */
.mb-scr__sparkdots circle:nth-child(1) { animation-delay: .0s; }
.mb-scr__sparkdots circle:nth-child(2) { animation-delay: .5s; }
.mb-scr__sparkdots circle:nth-child(3) { animation-delay: 1.0s; }
.mb-scr__sparkdots circle:nth-child(4) { animation-delay: 1.5s; }
.mb-scr__sparkdots circle:nth-child(5) { animation-delay: 2.0s; }

.mb-scr__sparkhead {
  stroke: #0b2238;
  stroke-width: 2.1;
  opacity: 1;
  animation: mb-scr-head 13s var(--mb-ease) infinite;
  animation-play-state: paused;
}
.mb-hero.is-visible .mb-scr__sparkhalo,
.mb-hero.is-visible .mb-scr__sparkline,
.mb-hero.is-visible .mb-scr__sparkdots circle,
.mb-hero.is-visible .mb-scr__sparkhead { animation-play-state: running; }

/* All three end at their finished state — line drawn, dots lit, head shown —
   so the reduced-motion still is a complete chart. */
@keyframes mb-scr-draw {
  0%, 30%   { stroke-dashoffset: 140; }
  50%, 100% { stroke-dashoffset: 0; }
}
@keyframes mb-scr-dot {
  0%, 32%   { opacity: 0; transform: scale(.2); }
  38%, 100% { opacity: 1; transform: scale(1); }
}
@keyframes mb-scr-head {
  0%, 48%   { opacity: 0; }
  55%, 100% { opacity: 1; }
}

/* ── Screen 3 · layered cylinder infographic ─────────────────────────── */
.mb-scr__tower { width: 100%; height: auto; flex: 1 1 auto; min-height: 0; overflow: visible; }

/* Each ring rises into place from below, widest and shortest first, so the
   tower assembles outward-in. transform-box keeps the translate in viewBox
   user units rather than CSS pixels. */
.mb-scr__tower g {
  transform-box: view-box;
  animation: mb-scr-rise 13s var(--mb-ease) infinite;
  animation-play-state: paused;
  animation-delay: calc(var(--i) * .16s);
}
.mb-hero.is-visible .mb-scr__tower g { animation-play-state: running; }
/* Complete by 82% and holding to 94%. Ends assembled, so reduced motion
   leaves a built tower rather than a pile below the frame. */
@keyframes mb-scr-rise {
  0%, 60%   { transform: translateY(16px); opacity: 0; }
  82%, 100% { transform: translateY(0); opacity: 1; }
}

/* Legend dots under the tower, one per ring. */
.mb-scr__legend { display: flex; gap: .3em; flex: none; }
.mb-scr__legend i {
  width: .34em;
  height: .34em;
  min-width: 3px;
  min-height: 3px;
  border-radius: 50%;
  background: var(--c);
}

/* — The two glass cards —
   Back on the page's shared .mb-card component: the same backdrop-blur recipe
   as the home hero and the feature snippets, so they read as one family
   rather than a second card style invented for this page.

   Anchored to the column's outer edges on purpose. .mb-card's fill is .28
   alpha, which measures 9.11:1 over a light flat backdrop and collapses over
   a strong one — the corners keep them off the squircle's saturated centre,
   where that recipe stops holding. */
.mb-ahero__card {
  position: absolute;
  z-index: 5;
  animation: mb-drift 8s var(--mb-ease) infinite;
  animation-play-state: paused;
}
.mb-hero.is-visible .mb-ahero__card { animation-play-state: running; }
.mb-ahero__card--a { right: -3%; top: 2%;     width: min(214px, 45%); animation-delay: -1.4s; }
.mb-ahero__card--b { left:  -4%; bottom: 10%; width: min(208px, 44%); animation-delay: -4.8s; animation-duration: 9.2s; }

/* — Floating icon cards —
   White rounded squares carrying a single coloured glyph, as in the
   reference. Solid white rather than the tinted glass above: these sit ON the
   squircle, where a translucent card loses its edge entirely. Each floats on
   its own clock so the set never pulses in unison. */
.mb-ahero__chip {
  position: absolute;
  z-index: 4;
  display: grid;
  place-items: center;
  width: clamp(42px, 4.2vw, 58px);
  aspect-ratio: 1;
  border-radius: 30%;
  background: #fff;
  color: var(--mb-chip-fg);
  box-shadow: 0 12px 30px rgba(11, 34, 56, .14), 0 2px 6px rgba(11, 34, 56, .06);
  animation: mb-ahero-chip 7s var(--mb-ease) infinite;
  animation-play-state: paused;
}
.mb-hero.is-visible .mb-ahero__chip { animation-play-state: running; }
.mb-ahero__chip svg { width: 46%; height: 46%; }
/* Tucked along the squircle's flanks rather than into the corners — those
   are taken by the two glass cards now. */
.mb-ahero__chip--1 { left:  7%;  top: 30%; --mb-chip-fg: #e2445c;      animation-delay: -.6s;  animation-duration: 7.6s; }
.mb-ahero__chip--2 { right: 2%;  top: 38%; --mb-chip-fg: var(--mb-blue); animation-delay: -2.3s; animation-duration: 8.4s; }
.mb-ahero__chip--3 { left:  2%;  top: 60%; --mb-chip-fg: var(--mb-blue); animation-delay: -4.1s; animation-duration: 9s; }
.mb-ahero__chip--4 { right: 6%;  top: 70%; --mb-chip-fg: #f0803c;      animation-delay: -5.6s; animation-duration: 8s; }
@keyframes mb-ahero-chip {
  from, to { transform: translate3d(0, 0, 0); }
  50%      { transform: translate3d(0, -11px, 0); }
}

/* ── 02 · BUILT WITH PURPOSE ────────────────────────────────────────────
   Cards on the left, the positioning statement on the right. The cards are
   real internal links — this block is the page's main hand-off to /features,
   /integrations and /pricing, so it is an SEO asset as much as a layout one. */
.mb-purpose {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(1.75rem, 4vw, 3.5rem);
  align-items: center;
}
.mb-pillars { display: grid; gap: clamp(.75rem, 1.3vw, 1rem); }

.mb-pillar {
  position: relative;
  display: grid;
  grid-template-columns: 50px minmax(0, 1fr) 20px;
  gap: 1rem;
  align-items: center;
  padding: 1.125rem 1.25rem;
  background: #fff;
  border: 1px solid var(--mb-line);
  border-radius: var(--mb-r-lg);
  box-shadow: var(--mb-shadow-xs);
  text-decoration: none;
  overflow: hidden;
  transition: transform .28s var(--mb-ease), box-shadow .28s var(--mb-ease),
              border-color .28s var(--mb-ease);
}
/* Accent rail that wipes down the leading edge on hover. Scale rather than
   height, so it stays on the compositor. */
.mb-pillar::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  background: linear-gradient(180deg, var(--mb-blue-400), var(--mb-blue));
  transform: scaleY(0);
  transform-origin: 50% 0;
  transition: transform .3s var(--mb-ease);
}
.mb-pillar:hover, .mb-pillar:focus-visible {
  transform: translateY(-4px);
  box-shadow: var(--mb-shadow-md);
  border-color: #cfe3fa;
}
.mb-pillar:hover::before, .mb-pillar:focus-visible::before { transform: scaleY(1); }
.mb-pillar .mb-tile { width: 50px; height: 50px; border-radius: 15px; transition: transform .3s var(--mb-ease); }
.mb-pillar .mb-tile svg { width: 25px; height: 25px; }
.mb-pillar:hover .mb-tile { transform: scale(1.08) rotate(-4deg); }
.mb-pillar__text { display: grid; gap: .2rem; min-width: 0; }
.mb-pillar__text strong { font-size: .9375rem; font-weight: 600; color: var(--mb-ink); }
.mb-pillar__text span { font-size: .8125rem; color: var(--mb-muted); line-height: 1.5; }

/* Category label above each card's headline. Same treatment as .mb-eyebrow
   but a step smaller, so the four cards read as a labelled set rather than
   four unrelated links. Written as a descendant selector to match the
   (0,2,0) of the `.mb-pillar__text span` rule above and win on source
   order — the alternative was !important on two declarations. */
.mb-pillar__text .mb-pillar__kicker {
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--mb-blue);
  margin-bottom: .1rem;
}
.mb-pillar__go {
  display: grid;
  place-items: center;
  color: var(--mb-blue);
  transition: transform .28s var(--mb-ease);
}
.mb-pillar:hover .mb-pillar__go,
.mb-pillar:focus-visible .mb-pillar__go { transform: translateX(5px); }

.mb-purpose__copy .mb-h2 { margin-bottom: 1rem; text-wrap: balance; }
.mb-purpose__copy .mb-lede + .mb-lede { margin-top: .875rem; }
.mb-purpose__list { display: grid; gap: .875rem; margin-top: 1.625rem; }
.mb-purpose__list li {
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr);
  gap: .75rem;
  align-items: start;
  font-size: .875rem;
  color: var(--mb-muted);
  line-height: 1.6;
}
.mb-purpose__list strong { display: block; font-size: .9375rem; font-weight: 600; color: var(--mb-ink); margin-bottom: .05rem; }
.mb-purpose__list svg { margin-top: .2rem; color: var(--mb-blue); }
.mb-purpose__cta { margin-top: 1.75rem; }

/* ── 03 · WHY MEDBUS ────────────────────────────────────────────────────
   .mb-benefit is centred everywhere else. Six cards carrying a sentence each
   read better ranged left, so the alignment is flipped here rather than a
   second card component being introduced.

   Three fixed columns, not auto-fit: six cards on an auto-fit track land as
   4 + 2 on a wide monitor, which leaves the filled card marooned beside one
   sibling and a hole. */
.mb-benefits--start { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.mb-benefits--start .mb-benefit {
  position: relative;
  overflow: hidden;
  text-align: left;
  justify-items: start;
  align-content: start;
  padding: 1.625rem 1.5rem;
  gap: .6875rem;
}
.mb-benefits--start .mb-benefit h3 { font-size: 1.0625rem; letter-spacing: -.01em; }
.mb-benefits--start .mb-benefit p { font-size: .8438rem; line-height: 1.6; }
.mb-benefits--start .mb-tile { width: 50px; height: 50px; border-radius: 15px; transition: transform .32s var(--mb-ease); }
.mb-benefits--start .mb-tile svg { width: 26px; height: 26px; }
.mb-benefits--start .mb-benefit:hover .mb-tile { transform: scale(1.09) rotate(-5deg); }

/* Tinted wash that rises out of the bottom-right corner on hover. Opacity on
   a pseudo-element, so nothing in the card is repainted. */
.mb-benefits--start .mb-benefit::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background: radial-gradient(70% 70% at 100% 100%, rgba(9, 106, 201, .07), transparent 70%);
  opacity: 0;
  transition: opacity .32s var(--mb-ease);
  pointer-events: none;
}
.mb-benefits--start .mb-benefit:hover::after { opacity: 1; }
.mb-benefits--start .mb-benefit > * { position: relative; z-index: 1; }

/* Keyword line closing each card — the specific terms a clinic actually
   searches for, kept visually subordinate to the sentence above it. */
.mb-benefit__tags {
  display: flex;
  flex-wrap: wrap;
  gap: .375rem;
  margin-top: .125rem;
}
.mb-benefit__tags span {
  padding: .1875rem .5rem;
  border-radius: var(--mb-r-pill);
  background: var(--mb-blue-50);
  border: 1px solid var(--mb-line);
  font-size: .75rem;
  font-weight: 600;
  color: var(--mb-ink-soft);
}

/* The filled card that closes the grid. */
.mb-benefit--accent {
  background: linear-gradient(140deg, var(--mb-blue) 0%, var(--mb-blue-700) 100%);
  border-color: transparent;
  color: #fff;
}
.mb-benefit--accent h3 { color: #fff; }
.mb-benefit--accent p  { color: rgba(255, 255, 255, .84); }
.mb-benefit--accent .mb-tile { background: rgba(255, 255, 255, .18); color: #fff; }
.mb-benefit--accent:hover { border-color: transparent; box-shadow: var(--mb-shadow-lg); }
.mb-benefit--accent .mb-benefit__tags span {
  background: rgba(255, 255, 255, .14);
  border-color: rgba(255, 255, 255, .22);
  color: rgba(255, 255, 255, .92);
}
/* The corner wash is invisible on a blue ground; swap it for a light one. */
.mb-benefits--start .mb-benefit--accent::after {
  background: radial-gradient(70% 70% at 100% 100%, rgba(255, 255, 255, .16), transparent 70%);
}

/* Conversion strip under the grid. */
.mb-whycta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 2rem;
  margin-top: clamp(1.25rem, 2.4vw, 1.75rem);
  padding: 1.25rem clamp(1.25rem, 2.4vw, 1.875rem);
  background: #fff;
  border: 1px solid var(--mb-line);
  border-radius: var(--mb-r-lg);
  box-shadow: var(--mb-shadow-xs);
}
.mb-whycta p { font-size: .9375rem; color: var(--mb-ink); font-weight: 600; }
.mb-whycta p span { display: block; font-size: .8125rem; font-weight: 400; color: var(--mb-muted); margin-top: .125rem; }
.mb-whycta div { display: flex; flex-wrap: wrap; gap: .625rem; }

/* ── 04 · FEATURES ──────────────────────────────────────────────────────
   The home page's 3-up .mb-features grid, reused whole. Everything below is
   additive: the card's own lift and the floating snippet's drift already
   come from medbus-home.css. */

/* Photo pans in slowly while the card is hovered. object-fit already crops
   it, so the scale eats into the crop rather than moving the frame. */
.mb-features--about .mb-feature__media img {
  transition: transform .6s var(--mb-ease);
}
.mb-features--about .mb-feature:hover .mb-feature__media img { transform: scale(1.05); }

/* The floating snippet gets a second layer of life on top of the inherited
   drift: a slow sheen crossing the glass, and a lift when the card is
   hovered. The sheen is a transform on a pseudo-element behind the content,
   so it composites and never repaints the blurred backdrop. */
.mb-features--about .mb-feature__overlay {
  transition: transform .35s var(--mb-ease), box-shadow .35s var(--mb-ease);
}
.mb-features--about .mb-feature__overlay > .mb-scr__sheen {
  position: absolute;
  inset: -40% -60%;
  z-index: 0;
  background: linear-gradient(74deg, transparent 38%, rgba(255, 255, 255, .55) 50%, transparent 62%);
  transform: translate3d(-70%, 0, 0);
  animation: mb-sheen 6.5s var(--mb-ease) infinite;
  animation-play-state: paused;
  pointer-events: none;
}
.mb-features.is-visible .mb-scr__sheen { animation-play-state: running; }
.mb-feature:nth-child(2n) .mb-scr__sheen { animation-delay: -2.2s; }
.mb-feature:nth-child(3n) .mb-scr__sheen { animation-delay: -4.4s; }
/* Ends off-screen where it starts, so reduced motion leaves no band parked
   across the card. */
@keyframes mb-sheen {
  0%, 62%, 100% { transform: translate3d(-70%, 0, 0); }
  32%           { transform: translate3d(70%, 0, 0); }
}

/* Hovering the card lifts the snippet a little further than the card itself,
   which is what sells it as floating ABOVE the photo rather than stuck to it.
   The drift keeps running underneath; this rides on top of it. */
.mb-features--about .mb-feature:hover .mb-feature__overlay {
  box-shadow:
    0 18px 44px rgba(0, 0, 0, .16),
    inset 0 1px 0 rgba(255, 255, 255, .5),
    inset 0 -1px 0 rgba(255, 255, 255, .1),
    inset 0 0 22px 11px rgba(255, 255, 255, 1);
}

/* ── 05 · OUR COMMITMENT ────────────────────────────────────────────────
   Was four bare titles in the .mb-benefit grid. Now a card each with a
   sentence and a numbered rail, which is what lets the section carry real
   copy instead of four labels. */
.mb-pledges {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(.875rem, 1.6vw, 1.25rem);
  margin-top: clamp(2rem, 3.5vw, 3rem);
  counter-reset: pledge;
}
.mb-pledge {
  position: relative;
  display: grid;
  gap: .6875rem;
  align-content: start;
  padding: 1.75rem 1.5rem 1.625rem;
  background: #fff;
  border: 1px solid var(--mb-line);
  border-radius: var(--mb-r-lg);
  box-shadow: var(--mb-shadow-xs);
  overflow: hidden;
  transition: transform .3s var(--mb-ease), box-shadow .3s var(--mb-ease),
              border-color .3s var(--mb-ease);
}
.mb-pledge:hover {
  transform: translateY(-5px);
  box-shadow: var(--mb-shadow-md);
  border-color: #cfe3fa;
}
/* Rail across the top that draws in from the left on hover. */
.mb-pledge::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 3px;
  background: linear-gradient(90deg, var(--mb-blue-400), var(--mb-blue));
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform .32s var(--mb-ease);
}
.mb-pledge:hover::before { transform: scaleX(1); }

/* Oversized ghost numeral in the corner. Pure decoration, so it is drawn by
   a counter rather than sitting in the DOM for a screen reader to announce. */
.mb-pledge::after {
  counter-increment: pledge;
  content: "0" counter(pledge);
  position: absolute;
  right: .5rem;
  top: .125rem;
  font-family: var(--mb-font-head);
  font-size: 2.75rem;
  font-weight: 800;
  line-height: 1;
  color: var(--mb-blue);
  opacity: .07;
  pointer-events: none;
  transition: opacity .32s var(--mb-ease), transform .32s var(--mb-ease);
}
.mb-pledge:hover::after { opacity: .13; transform: translateY(-2px); }

.mb-pledge .mb-tile { width: 52px; height: 52px; border-radius: 16px; transition: transform .32s var(--mb-ease); }
.mb-pledge .mb-tile svg { width: 26px; height: 26px; }
.mb-pledge:hover .mb-tile { transform: scale(1.08) rotate(-5deg); }
.mb-pledge h3 { font-size: 1rem; font-weight: 600; letter-spacing: -.01em; text-wrap: balance; }
.mb-pledge p { font-size: .8438rem; color: var(--mb-muted); line-height: 1.6; }

/* ── 06 · DIRECTIONAL REVEAL ────────────────────────────────────────────
   The base .mb-reveal rises from below. The two purpose columns read better
   sliding in from the side they occupy. Both selectors sit at (0,2,0),
   matching `.js .mb-reveal`, so they win on source order — this file loads
   after medbus-home.css. `.js .mb-reveal.is-in` is (0,3,0) and still clears
   them. Guarded by `.js` for the same reason the base rule is: with no
   script to add `.is-in`, the content must never start hidden. */
.js .mb-reveal--left  { transform: translate3d(-26px, 0, 0); }
.js .mb-reveal--right { transform: translate3d(26px, 0, 0); }

/* ══════════════════════════════════════════════════════════════════════════
   RESPONSIVE
   ══════════════════════════════════════════════════════════════════════════ */

@media (max-width: 1080px) {
  /* 3 -> 2 and 4 -> 2. Six and four cards both still divide evenly, so the
     filled card stays in a corner rather than stranded on its own row. */
  .mb-benefits--start { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .mb-pledges         { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 900px) {
  .mb-purpose { grid-template-columns: 1fr; }
  /* Statement first, then the cards it introduces. */
  .mb-purpose__copy { order: -1; }

  .mb-ahero__art { min-height: clamp(360px, 64vw, 500px); margin-top: 2.25rem; }
  /* The cards hang a few percent outside the art column on desktop, where the
     shell gutter absorbs the overhang. Once the art is a full-width row that
     gutter is gone and the overhang lands past the viewport edge, where the
     hero's overflow:hidden slices the card in half. Pull them inside. */
  .mb-ahero__card--a { right: 0; top: 0; }
  .mb-ahero__card--b { left: 0; bottom: 6%; }
  /* The art switches to a different clamp here, so the screen's type has to
     follow it: the same x0.02206 ratio applied to clamp(360px, 64vw, 500px). */
  .mb-ahero__screen { font-size: clamp(7.94px, 1.412vw, 11.03px); }
  /* The bubble field is sized off the column; once that column is full width
     the orbs balloon and wash out the tint the section relies on. */
  .mb-ahero__bubbles { inset: -4% 6% 0; }

  /* Sideways travel costs horizontal room the single column does not have,
     and would introduce a scrollbar on the way in. Fall back to the base
     rise, which is what every other reveal on the page does here anyway. */
  .js .mb-reveal--left,
  .js .mb-reveal--right { transform: translate3d(0, 18px, 0); }

  .mb-whycta { justify-content: flex-start; }
}

@media (max-width: 620px) {
  /* Two columns of a tile plus a two-line title, a three-line sentence and a
     tag row stop fitting well before the cards themselves do. */
  .mb-benefits--start { grid-template-columns: minmax(0, 1fr); }
  .mb-pledges         { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 560px) {
  /* A ~150px glass card over a ~200px-wide figure is unreadable. The motion
     moves to the bubbles and the chips down here — still alive, nothing
     illegible. */
  .mb-ahero__card { display: none; }
  .mb-ahero__chip { width: clamp(40px, 11vw, 50px); }
  .mb-ahero__chip--1 { right: 0; }
  .mb-ahero__chip--2 { left: 0; }
  .mb-whycta div .mb-btn { flex: 1 1 100%; }
}
