/* heart3d.css
   P4: the research hero. A BodyParts3D heart with a glass LENS that looks INSIDE it.
   Outside the glass the visitor sees the heart's surface (heart-base.webp). Inside the glass they see the same
   place with the front of the heart cut away (heart-inside.webp: chambers, walls, septum, valves), magnified about
   twice, with the structure that a research area studies lit in crimson light (heart-inside-<area>.webp).
   Six soft breathing markers sit on the surface where those structures lie. The lens moves freely over the whole
   heart (nothing pulls it to a marker) and lights whichever structure its centre is over; a marker or a name in the
   list glides it there. See heart3d.js for the behaviour.

   Rules this file keeps: no icon in a circle (the glass is a window, not a symbol), nothing joins anything with a
   line, motion is transform and opacity only, hover only on (hover:hover) and (pointer:fine) with :focus-visible
   twins, a finished state under prefers-reduced-motion, and the base heart plus the names list with scripts off.
   Zero em or en dashes anywhere, comments included. Tokens come from fable.css (loaded first). */

/* ---------------------------------------------------------------- layout: the page CSS (pg-speak-research.css) places the three blocks; this file styles the heart and its parts */
.heart3d{ position:relative; }
body.pg-research .rheart .heart3d__plate{
  position:relative;
  width:100%;
  min-height:0;
  padding:0;
  display:flex;
  flex-direction:column;
  align-items:center;
  background:none;
  border:0;
  border-radius:0;
  box-shadow:none;
  overflow:visible;
}

/* ---------------------------------------------------------------- the names list (a clean list: colour and weight only) */
.heart3d__areas{ display:grid; justify-items:start; margin:.2rem 0 .9rem; padding:0; }
.heart3d__area,
body.pg-research .rheart .heart3d__area{
  display:block;
  width:auto;
  max-width:none;
  min-height:36px;
  margin:0 0 0 -.6rem;                /* the text keeps the column's left edge; the focus ring gets room around it */
  padding:.28rem .6rem;
  text-align:left;
  background:none;
  border:0;
  border-radius:var(--r-sm);
  cursor:pointer;
  font-family:var(--body);
  font-size:clamp(1rem,1.25vw,1.2rem);
  font-weight:500;
  line-height:1.25;
  letter-spacing:-.003em;
  white-space:nowrap;
  color:rgb(244 247 251 / .82);
  transition:color .28s ease,border-color .2s ease;
  -webkit-tap-highlight-color:transparent;
}
@media (pointer:coarse){
  .heart3d__area,body.pg-research .rheart .heart3d__area{ min-height:44px; }
}
.heart3d__area-name{ display:block; font-weight:inherit; }
.heart3d__area-note{ display:none; margin-top:.2rem; font-size:.9rem; font-weight:400; line-height:1.5; color:rgb(244 247 251 / .78); white-space:normal; }
.heart3d__area.is-look,
body.pg-research .rheart .heart3d__area.is-look{ color:#FF6B75; font-weight:700; }
@media (hover:hover) and (pointer:fine){
  .heart3d__area:hover,
  body.pg-research .rheart .heart3d__area:hover{ color:#fff; }
  .heart3d__area.is-look:hover,
  body.pg-research .rheart .heart3d__area.is-look:hover{ color:#FF6B75; }
}
.heart3d__area:focus-visible,
body.pg-research .rheart .heart3d__area:focus-visible{ color:#fff; outline:2px solid #FF6B75; outline-offset:2px; }
.heart3d__area.is-look:focus-visible,
body.pg-research .rheart .heart3d__area.is-look:focus-visible{ color:#FF6B75; }

/* the active area: its name, then its own line (words already on the pages). The space is reserved so nothing jumps. */
body.pg-research .rheart .heart3d__caption{
  position:relative;
  min-height:6.6rem;
  padding:0;
  border:0;
  border-radius:0;
  background:none;
  box-shadow:none;
  -webkit-backdrop-filter:none; backdrop-filter:none;
}
body.pg-research .rheart .heart3d__caption-k{
  display:block;
  margin:0 0 .35rem;
  font-family:var(--display);
  font-size:1.5rem;
  font-weight:700;
  line-height:1.15;
  letter-spacing:-.01em;
  color:#fff;
}
body.pg-research .rheart .heart3d__caption-p{
  margin:0;
  max-width:44ch;
  text-wrap:pretty;
  font-family:var(--body);
  font-size:1rem;
  line-height:1.6;
  color:var(--on-dark);
}
/* the lens is over no structure: the name and its line step back (the space stays, so nothing jumps) */
body.pg-research .rheart .heart3d__caption-k,
body.pg-research .rheart .heart3d__caption-p{ transition:opacity .3s ease; }
body.pg-research .rheart .heart3d__caption.is-quiet .heart3d__caption-k,
body.pg-research .rheart .heart3d__caption.is-quiet .heart3d__caption-p{ opacity:0; }
@keyframes rhCapIn{ from{ opacity:0; transform:translateY(6px); } to{ opacity:1; transform:none; } }
body.pg-research .rheart .heart3d__caption.is-swap .heart3d__caption-k,
body.pg-research .rheart .heart3d__caption.is-swap .heart3d__caption-p{ animation:rhCapIn .5s var(--ease-snap) both; }

/* ---------------------------------------------------------------- the stage: heart, markers, lens */
.heart3d__stage{
  --sw:420px; --sh:612px; --D:218px; --M:2; --rim:6px; --lit:0;
  position:relative;
  width:min(clamp(250px,calc((100svh - 224px) * .6867),600px),100%);
  aspect-ratio:980 / 1427;
  flex:0 0 auto;
  touch-action:pan-y;
  -webkit-tap-highlight-color:transparent;
  -webkit-user-select:none; user-select:none;
}
.heart3d.h3d-js.is-follow .heart3d__stage{ cursor:none; }
/* keyboard focus on the heart rings the LENS (the thing the arrow keys move), not the picture's box; before the lens exists it rings the box */
.heart3d__stage:focus-visible{ outline:none; }
.heart3d:not(.is-ready) .heart3d__stage:focus-visible{ outline:2px solid #FF6B75; outline-offset:8px; border-radius:var(--r-md); }
.heart3d__lens::after{
  content:'';
  position:absolute;
  inset:calc(var(--rim) * -1 - 5px);
  border-radius:50%;
  border:2px solid #FF6B75;
  opacity:0;
  pointer-events:none;
}
.heart3d__stage:focus-visible .heart3d__lens::after{ opacity:1; }
.heart3d__img{
  display:block;
  width:100%;
  height:100%;
  -webkit-user-drag:none; user-select:none;
  filter:drop-shadow(0 16px 22px rgb(0 0 0 / .35));
}
/* the research hero sizes the heart by the height of its stage (no cap): the whole heart and its lens fit in the viewport */
body.pg-research .rheart .heart3d__stage{
  width:auto;
  height:calc(var(--rh-cell) - var(--rh-under));
  max-width:100%;
}

/* ---------------------------------------------------------------- markers: small, soft, breathing, on the structure */
.h3d-spots{ position:absolute; inset:0; z-index:3; pointer-events:none; opacity:0; transition:opacity .7s ease; }
.heart3d.is-ready .h3d-spots{ opacity:1; }
.h3d-spot{
  position:absolute;
  left:calc(var(--hx) * 100%);
  top:calc(var(--hy) * 100%);
  width:44px; height:44px;
  margin:-22px 0 0 -22px;
  padding:0;
  border:0;
  border-radius:50%;
  background:none;
  cursor:pointer;
  pointer-events:auto;
  -webkit-tap-highlight-color:transparent;
  transition:opacity .4s ease;
}
.h3d-spot::before,
.h3d-spot::after{ content:''; position:absolute; left:50%; top:50%; border-radius:50%; pointer-events:none; }
.h3d-spot::before{
  width:18px; height:18px; margin:-9px 0 0 -9px;
  background:radial-gradient(circle,#fff 0,#FFE6E8 16%,rgb(255 107 117 / .92) 38%,rgb(226 58 70 / .5) 60%,rgb(226 58 70 / 0) 78%);
}
.h3d-spot::after{
  width:44px; height:44px; margin:-22px 0 0 -22px;
  background:radial-gradient(circle,rgb(255 107 117 / .30) 0,rgb(255 107 117 / .1) 44%,transparent 68%);
}
.heart3d:not(.h3d-js) .h3d-spots{ display:none; }
.h3d-spot.is-covered{ opacity:0; pointer-events:none; }
@media (prefers-reduced-motion:no-preference){
  .h3d-spot::before{ animation:h3dBreathe 3.6s ease-in-out infinite; animation-delay:calc(var(--i,0) * -.7s); animation-play-state:paused; }
  .h3d-spot::after{ animation:h3dHalo 3.6s ease-in-out infinite; animation-delay:calc(var(--i,0) * -.7s); animation-play-state:paused; }
  .heart3d.is-live .h3d-spot::before,
  .heart3d.is-live .h3d-spot::after{ animation-play-state:running; }
}
@keyframes h3dBreathe{ 0%,100%{ transform:scale(.8); opacity:.8; } 50%{ transform:scale(1.2); opacity:1; } }
@keyframes h3dHalo{ 0%,100%{ transform:scale(.8); opacity:.55; } 50%{ transform:scale(1.25); opacity:1; } }
@media (hover:hover) and (pointer:fine){
  .h3d-spot:hover::before{ animation:none; transform:scale(1.4); opacity:1; }
}
.h3d-spot:focus-visible::before{ animation:none; transform:scale(1.4); opacity:1; }
.h3d-spot:focus-visible{ outline:2px solid #FF6B75; outline-offset:-2px; }

/* ---------------------------------------------------------------- the lens: a glass window onto the inside */
.heart3d__lens{
  position:absolute;
  left:0; top:0;
  z-index:5;
  width:var(--D); height:var(--D);
  pointer-events:none;
  will-change:transform;
  opacity:0;
}
.heart3d.is-ready .heart3d__lens{ opacity:1; }
.heart3d:not(.h3d-js) .heart3d__lens{ display:none; }
/* on touch the glass itself can be dragged (the rest of the heart still scrolls the page) */
@media (pointer:coarse){
  .heart3d__lens{ pointer-events:auto; touch-action:none; border-radius:50%; }
}
.heart3d__lensin{
  position:absolute; inset:0;
  transition:transform .8s var(--ease-snap),opacity .5s ease;
}
.heart3d.h3d-js:not(.is-in) .heart3d__lensin{ opacity:0; transform:scale(.84); }
/* if the inside picture cannot load, the heart and the list stand alone */
.heart3d.h3d-fail .heart3d__lens,
.heart3d.h3d-fail .h3d-spots,
.heart3d.h3d-fail .h3d-cap,
.heart3d.h3d-fail .heart3d__hint{ display:none; }

/* a soft crimson halo behind the glass that grows as a structure lights up */
.heart3d__halo{
  position:absolute;
  inset:-22%;
  border-radius:50%;
  pointer-events:none;
  background:radial-gradient(circle,rgb(var(--crimson-bright-rgb) / .5) 0,rgb(var(--crimson-bright-rgb) / .16) 46%,transparent 68%);
  opacity:calc(var(--lit) * .9);
  transition:opacity .4s ease;
}
.heart3d__glass{
  position:absolute; inset:0;
  border-radius:50%;
  overflow:hidden;
  isolation:isolate;
  background:radial-gradient(circle at 50% 38%,#1B2B58 0,#0E1A3A 56%,#08112A 100%);
  box-shadow:0 30px 56px -20px rgb(0 0 0 / .72),0 10px 22px -10px rgb(0 0 0 / .5);
}
.heart3d__glass::after{
  content:'';
  position:absolute; inset:0;
  border-radius:50%;
  z-index:4;
  pointer-events:none;
  box-shadow:inset 0 0 0 1px rgb(255 255 255 / .14),inset 0 -26px 44px rgb(5 10 26 / .5),inset 0 14px 26px rgb(255 255 255 / .05);
}
.heart3d__mag{
  position:absolute; left:0; top:0;
  width:calc(var(--sw) * var(--M));
  height:calc(var(--sh) * var(--M));
  will-change:transform;
}
.heart3d__mag > img{
  position:absolute; left:0; top:0;
  display:block;
  width:100%; height:100%;
  max-width:none;
  -webkit-user-drag:none;
}
.h3d-in{ opacity:0; transition:opacity .5s ease; }
.h3d-in.is-loaded{ opacity:1; }

/* the lit structures: one overlay per area; the one whose structure the centre of the glass is over crossfades in, the others out */
.h3d-hi{ position:absolute; left:0; top:0; width:100%; height:100%; pointer-events:none; }
.h3d-hi img{
  position:absolute; left:0; top:0;
  display:block;
  width:100%; height:100%;
  max-width:none;
  opacity:0;
  transition:opacity .26s ease;
  will-change:opacity;
  -webkit-user-drag:none;
}
@media (prefers-reduced-motion:no-preference){
  .heart3d.is-live .h3d-hi{ animation:h3dLit 3.4s ease-in-out infinite alternate; }
}
@keyframes h3dLit{ 0%{ opacity:.8; } 100%{ opacity:1; } }

.heart3d__glare{
  position:absolute; inset:0;
  border-radius:50%;
  z-index:3;
  pointer-events:none;
  background:radial-gradient(118% 88% at 26% 11%,rgb(255 255 255 / .3) 0,rgb(255 255 255 / .08) 28%,transparent 44%);
}
.heart3d__sheen{
  position:absolute; inset:0;
  border-radius:50%;
  overflow:hidden;
  z-index:3;
  pointer-events:none;
}
.heart3d__sheen::after{
  content:'';
  position:absolute; top:-20%; bottom:-20%; left:0; width:34%;
  background:linear-gradient(100deg,transparent 0%,rgb(255 255 255 / .08) 30%,rgb(255 255 255 / .42) 50%,rgb(255 255 255 / .08) 70%,transparent 100%);
  opacity:0;
  transform:translate3d(-150%,0,0) skewX(-18deg);
}
@media (prefers-reduced-motion:no-preference){
  .heart3d.is-sweep .heart3d__sheen::after{ animation:h3dSheen 1.1s cubic-bezier(.45,.05,.25,1) both; }
}
@keyframes h3dSheen{
  0%{ transform:translate3d(-150%,0,0) skewX(-18deg); opacity:0; }
  16%{ opacity:1; }
  100%{ transform:translate3d(420%,0,0) skewX(-18deg); opacity:0; }
}
/* the rim: polished glass edge, light at the upper left, dark low right, a crimson cast where the light is on */
.heart3d__rim{
  position:absolute;
  inset:calc(var(--rim) * -1);
  border-radius:50%;
  z-index:6;
  pointer-events:none;
  background:conic-gradient(from 205deg,#F4F7FB 0deg,#9BA8C4 38deg,#26355F 92deg,#0C1833 150deg,#3A2A44 200deg,#8E3A52 236deg,#C9D2E4 288deg,#F4F7FB 360deg);
  -webkit-mask:radial-gradient(farthest-side,transparent calc(100% - var(--rim)),#000 calc(100% - var(--rim) + .7px));
          mask:radial-gradient(farthest-side,transparent calc(100% - var(--rim)),#000 calc(100% - var(--rim) + .7px));
}

/* the small caption that rides beside the lens */
.h3d-cap{
  position:absolute; left:0; top:0;
  z-index:7;
  padding:.46rem .82rem .5rem;
  border-radius:999px;
  background:rgb(12 24 51 / .9);
  border:1px solid rgb(255 255 255 / .18);
  box-shadow:0 14px 28px -12px rgb(0 0 0 / .7);
  font-family:var(--display);
  font-size:.82rem;
  font-weight:700;
  line-height:1;
  letter-spacing:.005em;
  color:#fff;
  white-space:nowrap;
  pointer-events:none;
  opacity:0;
  transition:opacity .28s ease;
  will-change:transform;
}
.heart3d.is-ready .h3d-cap.is-on{ opacity:1; }
.heart3d:not(.h3d-js) .h3d-cap{ display:none; }

/* the one hint, under the heart */
.heart3d__hint{
  margin:.55rem 0 0;
  text-align:center;
  font-family:var(--body);
  font-size:1rem;
  font-weight:500;
  line-height:1.4;
  color:rgb(244 247 251 / .8);
  transition:opacity .4s ease;
}
.heart3d__hint--touch{ display:none; }
@media (hover:none){
  .heart3d__hint--fine{ display:none; }
  .heart3d__hint--touch{ display:inline; }
}
/* the hint steps aside while a structure is lit and comes back whenever the lens is over none */
.heart3d.is-used.is-lit .heart3d__hint{ opacity:0; }
.heart3d:not(.h3d-js) .heart3d__hint{ display:none; }

.heart3d__live{ position:absolute; width:1px; height:1px; margin:-1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; }

.heart3d__meta{
  display:flex; flex-wrap:wrap; justify-content:center; gap:.3rem 1rem;
  margin-top:.45rem;
  font-family:var(--body); font-size:.78rem; font-weight:500; line-height:1.5;
  color:rgb(244 247 251 / .62);
}
.heart3d__credit a{ color:inherit; text-decoration:underline; text-decoration-color:rgb(244 247 251 / .3); text-underline-offset:2px; transition:color .2s ease; }
@media (hover:hover) and (pointer:fine){
  .heart3d__credit a:hover{ color:#fff; text-decoration-color:currentColor; }
}
.heart3d__credit a:focus-visible{ color:#fff; text-decoration-color:currentColor; outline:2px solid #FF6B75; outline-offset:2px; }

/* ---------------------------------------------------------------- scripts off: the surface of the heart and the list, whole */
html.no-js .heart3d__area,
.heart3d[data-no-js-demo] .heart3d__area{ cursor:default; pointer-events:none; color:#fff; }
html.no-js .heart3d__area-note,
.heart3d[data-no-js-demo] .heart3d__area-note{ display:block; }
html.no-js .heart3d__caption,
.heart3d[data-no-js-demo] .heart3d__caption{ display:none; }

/* ---------------------------------------------------------------- narrower screens */
@media (max-width:900px){
  body.pg-research .rheart__lens{ display:flex; flex-direction:column; }
  body.pg-research .rheart .heart3d__caption{ order:-1; min-height:6.2rem; margin-bottom:1rem; }
  /* the six names become a two column grid of real buttons: sentence case, 44 px, the active one has a 1 px coral border */
  .heart3d__areas,body.pg-research .rheart .heart3d__areas{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:.5rem; margin:0; justify-items:stretch; }
  .heart3d__area,
  body.pg-research .rheart .heart3d__area{
    min-height:44px; margin:0; padding:.4rem .8rem; font-size:1rem; white-space:normal;
    border:1px solid transparent; border-radius:10px; display:flex; align-items:center;
  }
  .heart3d__area.is-look,
  body.pg-research .rheart .heart3d__area.is-look{ color:#fff; font-weight:500; border-color:#FF6B75; }
  .heart3d__area:focus-visible,
  body.pg-research .rheart .heart3d__area:focus-visible{ outline:none; border-color:#FF6B75; }
  body.pg-research .rheart .heart3d__stage{ height:auto; width:min(86vw,330px); }
}
@media (max-width:900px) and (min-width:560px){
  body.pg-research .rheart .heart3d__stage{ width:min(64svh,calc(64svh * .6867),420px); }
}
@media (hover:hover) and (pointer:fine) and (max-width:900px){
  .heart3d__area:hover,
  body.pg-research .rheart .heart3d__area:hover{ border-color:#FF6B75; }
}

/* short laptops (about 720 px tall): the left column gets a little tighter so the line under the list stays above the fold */
@media (min-width:901px) and (max-height:780px){
  .heart3d__area,
  body.pg-research .rheart .heart3d__area{ min-height:32px; padding-top:.2rem; padding-bottom:.2rem; font-size:1rem; }
  body.pg-research .rheart .heart3d__caption{ min-height:5.4rem; }
  body.pg-research .rheart .heart3d__caption-k{ font-size:1.3rem; }
  body.pg-research .rheart .heart3d__caption-p{ font-size:.95rem; line-height:1.5; }
  body.pg-research .rhero .phero__title{ font-size:clamp(2.1rem,3.9vw,3.4rem); margin-bottom:.8rem; }
  body.pg-research .rhero .phero__deck{ font-size:1rem; }
}

/* ---------------------------------------------------------------- reduced motion: finished, still, nothing travelling */
@media (prefers-reduced-motion:reduce){
  .heart3d__lensin,.h3d-in,.h3d-hi img,.heart3d__halo,.h3d-spot,.h3d-spots,.h3d-cap,.heart3d__hint,.heart3d__area,body.pg-research .rheart .heart3d__caption-k,body.pg-research .rheart .heart3d__caption-p{ transition:none; }
  .h3d-hi,.h3d-spot::before,.h3d-spot::after{ animation:none; }
}
