/* ==========================================================================
   Life: motion, depth and feedback.

   Loaded after apple.css. What it adds is the layer a modern product page has and a static one lacks: things
   arrive rather than appear, surfaces answer the pointer, and nothing moves without a reason. Apple's own
   restraint sets the budget — one staged entrance, soft depth on hover, a single slow drift — so the page
   feels alive without reading as busy.

   Every animation sits behind prefers-reduced-motion: no-preference, so somebody who has asked their system
   for less motion gets the finished page, still and complete. Hover depth that moves nothing (shadows, rings,
   colour) stays for everyone.
   ========================================================================== */

:root {
  --ease-out: cubic-bezier(.16, 1, .3, 1);
  --ease-spring: cubic-bezier(.34, 1.56, .64, 1);
}

/* Motion -------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {

  /* The hero arrives in order — label, headline, subhead, action, note — each a beat after the last. */
  .hero-copy > * { animation: rise-in .9s var(--ease-out) both; }
  .hero-copy > :nth-child(1) { animation-delay: .05s; }
  .hero-copy > :nth-child(2) { animation-delay: .15s; }
  .hero-copy > :nth-child(3) { animation-delay: .27s; }
  .hero-copy > :nth-child(4) { animation-delay: .39s; }
  .hero-copy > :nth-child(5) { animation-delay: .5s; }
  @keyframes rise-in {
    from { opacity: 0; transform: translateY(18px); }
    to   { opacity: 1; transform: none; }
  }

  /* The photograph settles in behind it: a slow zoom from slightly close, once. */
  .hero-bg img { animation: settle 2.6s var(--ease-out) both; }
  @keyframes settle {
    from { opacity: 0; transform: scale(1.08); }
    to   { transform: scale(1); }
  }

  /* The headline's green-to-blue drifts across its words, slowly enough to notice only on a second look. */
  h1 em {
    background-size: 200% 100%;
    animation: drift 9s ease-in-out infinite alternate;
  }
  @keyframes drift {
    from { background-position: 0% 50%; }
    to   { background-position: 100% 50%; }
  }

  /* Grids cascade in as they scroll into view, rather than landing all at once. */
  .facility-grid > .reveal:nth-child(2),
  article.card.reveal:nth-of-type(2) { transition-delay: .06s; }
  .facility-grid > .reveal:nth-child(3),
  article.card.reveal:nth-of-type(3) { transition-delay: .12s; }
  .facility-grid > .reveal:nth-child(4),
  article.card.reveal:nth-of-type(4) { transition-delay: .18s; }
  .facility-grid > .reveal:nth-child(5),
  article.card.reveal:nth-of-type(5) { transition-delay: .24s; }
  .facility-grid > .reveal:nth-child(6),
  article.card.reveal:nth-of-type(6) { transition-delay: .3s; }

  /* An FAQ answer slides open instead of jumping into place; the chevron turns on the same curve. */
  .faq-item[open] .faq-body { animation: open-down .4s var(--ease-out); }
  .faq-item summary::after { transition: transform .35s var(--ease-out); }
  @keyframes open-down {
    from { opacity: 0; transform: translateY(-6px); }
    to   { opacity: 1; transform: none; }
  }

  /* Buttons lift a pixel on hover and press in on click — the smallest confirmation that something happened. */
  .btn:hover { transform: translateY(-1px); }
  .btn:active { transform: translateY(0) scale(.97); }

  /* A card's picture tips up on a slight spring when the card is hovered. */
  .card:hover .spot-icon,
  .facility-card:hover .spot-icon { transform: translateY(-2px) scale(1.06); }
  .spot-icon { transition: transform .45s var(--ease-spring); }
}

/* Depth and feedback (no movement, so for everybody) -------------------------- */

.btn {
  transition:
    background-color .2s var(--ease-out),
    border-color .2s var(--ease-out),
    color .2s var(--ease-out),
    box-shadow .3s var(--ease-out),
    transform .2s var(--ease-out);
}
/* The primary action glows in its own blue on hover. */
.btn-primary:hover { box-shadow: 0 12px 26px -12px rgba(0, 113, 227, .75); }
.btn-ghost:hover { box-shadow: 0 10px 22px -14px rgba(0, 113, 227, .6); }

/* The bar gains a soft shadow once the page has scrolled under it. */
.nav.scrolled { box-shadow: 0 10px 30px -22px rgba(0, 0, 0, .45); }

/* Nav links draw an underline from the left, instead of switching one on. */
.nav-links a {
  background: linear-gradient(currentColor, currentColor) 0 100% / 0 1px no-repeat;
  padding-bottom: 2px;
  transition: background-size .35s var(--ease-out), opacity .2s var(--ease-out);
}
.nav-links a:hover,
.nav-links a:focus-visible { background-size: 100% 1px; }

/* How far down the page you are: a hairline in the page's two colours along the bottom of the bar. */
.nav-progress { display: block; background: var(--grad-hero); box-shadow: none; }

/* Cards: a faint ring in the section's colour, a deeper coloured shadow, and a soft spotlight that follows
   the pointer across the surface (its position comes from script.js; without it the light rests at the top).
   isolation keeps the spotlight behind the card's own content while still above its background. */
.card,
.facility-card { isolation: isolate; overflow: hidden; }
.card::before,
.facility-card::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: radial-gradient(420px circle at var(--mx, 50%) var(--my, 0%),
    color-mix(in srgb, var(--tone, var(--action)) 13%, transparent), transparent 46%);
  opacity: 0;
  transition: opacity .35s var(--ease-out);
  pointer-events: none;
}
.card:hover::before,
.facility-card:hover::before { opacity: 1; }
.card:hover,
.facility-card:hover {
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--tone, var(--action)) 30%, transparent),
    0 26px 50px -30px color-mix(in srgb, var(--tone, var(--action)) 60%, transparent),
    0 2px 6px rgba(0, 0, 0, .05);
}

/* Hero mesh ----------------------------------------------------------------- */
/* A lattice of small dots over the photograph's wash and under the copy — neutral, in the page's own ink, so
   it reads as texture rather than decoration. It fades out towards the edges so it gathers behind the words
   instead of tiling the whole band. Stronger in light mode: on the 90% white wash, dots at dark mode's
   strength all but disappear. The first version drew lines and coloured pools; both went. */
.hero-mesh {
  position: absolute;
  inset: 0;
  pointer-events: none;
  --dot-a: 16%;
}
:root[data-theme="light"] .hero-mesh { --dot-a: 34%; }
@media (prefers-color-scheme: light) { :root:not([data-theme="dark"]) .hero-mesh { --dot-a: 34%; } }
.hero-mesh-grid {
  position: absolute;
  inset: 0;
  background-image: radial-gradient(circle, color-mix(in srgb, var(--fg) var(--dot-a), transparent) 1.5px, transparent 1.8px);
  background-size: 22px 22px;
  background-position: center;
  -webkit-mask-image: radial-gradient(ellipse 75% 65% at 50% 45%, #000 0%, transparent 78%);
  mask-image: radial-gradient(ellipse 75% 65% at 50% 45%, #000 0%, transparent 78%);
}
/* The dots breathe: the lattice brightens and dims on a slow cycle, and a soft band of stronger dots sweeps
   across it, so they seem to catch the light in turn rather than blink together. Slow and low-contrast by
   design — it should read as life on a second look, never as flicker — and still under reduced motion. */
.hero-mesh-grid::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(circle, color-mix(in srgb, var(--fg) calc(var(--dot-a) * 1.9), transparent) 1.6px, transparent 1.9px);
  background-size: 22px 22px;
  background-position: center;
  -webkit-mask-image: linear-gradient(105deg, transparent 30%, #000 50%, transparent 70%);
  mask-image: linear-gradient(105deg, transparent 30%, #000 50%, transparent 70%);
  -webkit-mask-size: 250% 100%;
  mask-size: 250% 100%;
  -webkit-mask-position: 120% 0;
  mask-position: 120% 0;
  opacity: 0;
}
@media (prefers-reduced-motion: no-preference) {
  .hero-mesh-grid { animation: dots-breathe 6s ease-in-out infinite alternate; }
  .hero-mesh-grid::after { animation: dots-sweep 6s ease-in-out infinite; }
  @keyframes dots-breathe {
    from { opacity: .6; }
    to   { opacity: 1; }
  }
  @keyframes dots-sweep {
    0%   { -webkit-mask-position: 120% 0; mask-position: 120% 0; opacity: 0; }
    15%  { opacity: 1; }
    85%  { opacity: 1; }
    100% { -webkit-mask-position: -20% 0; mask-position: -20% 0; opacity: 0; }
  }
}

/* The copy sits above the mesh. */
.hero > .hero-grid { position: relative; z-index: 2; }

/* Tooltips ------------------------------------------------------------------ */
/* For controls that are an icon and nothing else. Each already has an aria-label, so the tooltip is for
   sighted pointer and keyboard users and repeats it rather than replacing it. It meets WCAG 1.4.13: it shows
   on hover and on keyboard focus, stays while the pointer moves onto it (the pseudo-element is part of the
   control's hit area once visible), and Escape dismisses it (script.js). */
[data-tooltip] { position: relative; }
[data-tooltip]::after {
  content: attr(data-tooltip);
  position: absolute;
  z-index: 300;
  top: calc(100% + 10px);
  left: 50%;
  translate: -50% -4px;
  padding: 6px 10px;
  border-radius: 8px;
  background: var(--fg);
  color: var(--ink);
  font: 500 12px/1.3 var(--font-body);
  letter-spacing: -0.01em;
  white-space: nowrap;
  text-decoration: none;
  box-shadow: 0 10px 26px -10px rgba(0, 0, 0, .4);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .18s var(--ease-out), translate .18s var(--ease-out), visibility .18s;
}
[data-tooltip]:hover::after,
[data-tooltip]:focus-visible::after {
  opacity: 1;
  visibility: visible;
  translate: -50% 0;
  pointer-events: auto;
  transition-delay: .12s;
}
/* At the right edge of the screen the tooltip hangs from the control's right side so it cannot run off. */
[data-tooltip-align="end"]::after { left: auto; right: 0; translate: 0 -4px; }
[data-tooltip-align="end"]:hover::after,
[data-tooltip-align="end"]:focus-visible::after { translate: 0 0; }
.tooltips-dismissed [data-tooltip]::after { opacity: 0 !important; visibility: hidden !important; }
@media (prefers-reduced-motion: reduce) {
  [data-tooltip]::after { transition: opacity .01s; translate: -50% 0; }
  [data-tooltip-align="end"]::after { translate: 0 0; }
}

/* ---------------------------------------------------------------------------
   The contact form's success moment, played as one movement rather than a queue of them. The form lifts away and
   blurs out; as it goes, the box glides to the panel's height and the panel rises in; the hospital app's payment
   tick lands as the box settles (SuccessMark in Hms.UI: the disc pops and overshoots, the tick draws along its path,
   eight rays burst once). Five seconds later the same in reverse, the form's rows returning one after another. Every
   step starts while the previous is finishing, which is what makes the handover read as a single gesture.
   The disc is the page's own success green, so the tick needs a token of its own: white on the light theme's
   dark green, near-black on the dark theme's mint, where white would vanish.
   --------------------------------------------------------------------------- */
:root { --sent-ink: #FFFFFF; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --sent-ink: #04241A; } }
:root[data-theme="dark"] { --sent-ink: #04241A; }

.form-shell { position: relative; box-sizing: border-box; }

/* The box changes height smoothly while one state hands over to the other, so the page below glides instead of
   snapping to a new length — the jump is what made two animations read as two events. script.js sets the heights. */
.form-shell.is-morphing { overflow: hidden; transition: height 520ms cubic-bezier(.22, 1, .36, 1); }

/* `hidden` has to win. The browser's own `[hidden] { display: none }` is the weakest rule there is, and
   `#demo-form { display: grid }` in styles.css outranks it — so hiding the form did nothing on screen: it faded,
   snapped back, and the success panel appeared underneath it, out of view. An id plus the attribute beats the id. */
#demo-form[hidden],
.sent[hidden] { display: none; }

/* Leaving is quick and lifts slightly, as if handed upward; the arrival below it comes from underneath. */
#demo-form.is-leaving { animation: sent-lift 240ms cubic-bezier(.4, 0, .6, 1) both; }
#demo-form.is-returning > * {
  animation: sent-arrive 560ms cubic-bezier(.16, 1, .3, 1) both;
  animation-delay: calc(60ms + var(--i, 0) * 45ms);
}

.sent { display: grid; justify-items: center; gap: 12px; padding: 56px 12px; text-align: center; }
.sent.is-entering { animation: sent-arrive 460ms cubic-bezier(.16, 1, .3, 1) 40ms both; }
.sent.is-leaving { animation: sent-lift 280ms cubic-bezier(.4, 0, .6, 1) both; }

@keyframes sent-lift { to { opacity: 0; transform: translateY(-8px) scale(.985); filter: blur(3px); } }
@keyframes sent-arrive { from { opacity: 0; transform: translateY(12px); filter: blur(2px); } }

.sent h3 { margin: 8px 0 0; font-size: 22px; letter-spacing: -.01em; outline: none; }
.sent-line { margin: 0; max-width: 36ch; color: var(--mut); animation: sent-arrive 480ms cubic-bezier(.16, 1, .3, 1) .56s both; }

/* The mark's own timings are Hms.UI's, each pushed back by the same 120ms so the tick lands as the box settles. */
.sent-mark { position: relative; width: 96px; height: 96px; }
.sent-mark svg { width: 100%; height: 100%; animation: sent-pop .42s cubic-bezier(.34, 1.56, .64, 1) .12s both; }
/* Two classes deep, so it beats `.sent-mark svg` above — at one class the rays popped in and stayed, which is the
   bug Hms.UI's version records. Sized from the disc outward rather than by inset: an svg's auto size is 300x150. */
.sent-mark .sent-rays {
  position: absolute; left: -28%; top: -28%; width: 156%; height: 156%;
  pointer-events: none; stroke: var(--ok); transform-origin: center;
  animation: sent-rays 720ms cubic-bezier(.16, 1, .3, 1) .42s both;
}
.sent-disc { fill: var(--ok); }
.sent-tick {
  stroke: var(--sent-ink);
  stroke-dasharray: 64; stroke-dashoffset: 64;
  animation: sent-draw .4s cubic-bezier(.65, 0, .35, 1) .34s forwards;
}
@keyframes sent-pop { from { transform: scale(.4); opacity: 0; } to { transform: scale(1); opacity: 1; } }
@keyframes sent-draw { to { stroke-dashoffset: 0; } }
@keyframes sent-rays {
  0% { opacity: 0; transform: scale(.6) rotate(-8deg); }
  35% { opacity: 1; }
  100% { opacity: 0; transform: scale(1.12) rotate(0deg); }
}

/* The tick still has to be a tick — it is the picture of the words under it. Only the movement goes. */
@media (prefers-reduced-motion: reduce) {
  .form-shell.is-morphing { transition: none; }
  #demo-form.is-leaving, #demo-form.is-returning > *, .sent.is-entering, .sent.is-leaving, .sent-line, .sent-mark svg { animation: none; }
  .sent-tick { animation: none; stroke-dashoffset: 0; }
  .sent-mark .sent-rays { display: none; }
}
