/* /science/exosomes/ — the embedded 3D figure, and nothing else.
 *
 * WHY THIS IS NOT IN styles.css. The site ships one stylesheet for 466 pages, on purpose.
 * These rules are used by one page. Folded into the shared file they took it from 16.5 KB
 * to 18.4 KB gzipped and failed the PART 6 gate, and the fix would have been to raise a
 * ceiling so that 465 pages could carry bytes they never render. Loaded here instead:
 * styles.css is untouched, every other page is byte-identical to before, and this file is
 * measured by its own ceiling in build.js so it cannot drift either.
 *
 * Declared by src/pages/science-exosomes.js via the `styles` export.
 */

/* An inline figure, not a section. 700px inside a 900px column, sitting in the
   reading flow directly under the prose it illustrates. */
.exo3d{border:1px solid var(--line);border-radius:var(--r-card);
  overflow:hidden;background:var(--paper);margin:0}
/* The figure sits in a grid column whose width has nothing to do with the viewport:
   ~590px on a wide desktop (the .numbered label rail eats 390px), but ~970px on an
   iPad, where .numbered has already collapsed to one column. A viewport media query
   gets that backwards and squeezed the stage to 380px on desktop while leaving it
   luxurious on a tablet. So the split is done with flex-wrap and no query at all:
   the stage carries almost all the grow, so the rail holds its 196px beside it and
   takes the full line once the two no longer fit. Wraps at ~556px of container,
   whatever the device happens to be. */
.exo3d__top{display:flex;flex-wrap:wrap;align-items:stretch}
.exo3d__stage{flex:100 0 360px;max-width:100%}
.exo3d__key{flex:1 0 196px;max-width:100%}

/* the viewer */
.exo3d__stage{position:relative;height:320px;min-width:0;
  background:radial-gradient(120% 110% at 32% 18%,#16374F 0%,#0B2239 58%,#061725 100%)}
@media (max-width:720px){.exo3d__stage{height:280px}}
/* A stage this narrow is nearly square; cover would crop the model's edges off.
   The live canvas fits the model to the height, so contain is what matches it. */
@media (max-width:720px){.exo3d__facade img{object-fit:contain}}
.exo3d__stage three-d-stage{position:absolute;inset:0;display:block;width:100%;height:100%}
.exo3d__stage three-d-stage:not(:defined){visibility:hidden}

/* nothing heavy loads until this is pressed */
.exo3d__facade{position:absolute;inset:0;z-index:2;display:grid;align-content:end;
  justify-items:center;gap:11px;padding:0 20px 24px;text-align:center}
/* The poster IS the model, rendered at this exact size and angle, so pressing the
   button swaps a picture for the same picture and nothing jumps. Same trick, and
   the same reason, as the homepage hero poster. */
.exo3d__facade img{position:absolute;inset:0;z-index:0;width:100%;height:100%;object-fit:cover}
/* Weighted to the bottom, not the middle: the cutaway is the whole point of the
   picture and a centred scrim puts a grey disc over it. */
.exo3d__facade::after{content:"";position:absolute;inset:0;z-index:1;
  background:linear-gradient(to bottom,rgba(6,23,37,.06) 26%,rgba(6,23,37,.5) 62%,
    rgba(6,23,37,.92) 100%)}
.exo3d__facade > .btn,.exo3d__facade > p{position:relative;z-index:2}
.exo3d__facade p{max-width:32ch;font:400 12px/1.55 var(--font-mono);color:var(--on-dark-2)}
.exo3d[data-loaded] .exo3d__facade{display:none}

.exo3d__hint{position:absolute;left:16px;bottom:12px;z-index:3;opacity:0;pointer-events:none;
  font:400 10.5px/1 var(--font-mono);letter-spacing:.08em;text-transform:uppercase;
  color:var(--on-dark-faint)}
.exo3d[data-loaded] .exo3d__hint{opacity:1;transition:opacity .5s ease .5s}
.exo3d__hint--touch{display:none}
@media (pointer:coarse){
  .exo3d__hint--fine{display:none}
  .exo3d__hint--touch{display:inline}
}

/* the key */
.exo3d__key{background:var(--surface);border-left:1px solid var(--line);
  padding:16px 14px;display:flex;flex-direction:column;gap:1px}
/* Once the rail wraps under the stage the left rule is in the wrong place. There is
   no query that knows when flex wrapped, so both rules are drawn and the one that is
   wrong is invisible: the rail's own background covers the stage's bottom edge. */
.exo3d__key{border-top:1px solid var(--line);margin-top:-1px}
.exo3d__key > p{font:600 10.5px/1 var(--font-ui);letter-spacing:.12em;text-transform:uppercase;
  color:var(--label);margin:2px 0 9px 8px}

.exo3d__part{display:flex;align-items:center;gap:9px;width:100%;text-align:left;
  padding:8px;border-radius:9px;font:600 13px/1.25 var(--font-ui);color:var(--text-2);
  transition:background-color .15s,color .15s}
.exo3d__part:hover{background:#E4EDF4;color:var(--text)}
.exo3d__part[aria-pressed="true"]{background:var(--surface-brand);color:var(--cyan-deep)}
.exo3d__dot{width:11px;height:11px;flex:none;border-radius:3px;background:var(--c);
  box-shadow:inset 0 0 0 1px rgba(11,34,57,.22)}

.exo3d__reset{margin:9px 0 0 8px;align-self:flex-start;padding:2px 0;
  font:400 10.5px/1 var(--font-mono);letter-spacing:.06em;text-transform:uppercase;
  color:var(--label);text-decoration:underline;text-underline-offset:3px}
.exo3d__reset:hover{color:var(--cyan-deep)}
.exo3d__reset[hidden]{display:none}

/* On a phone the rail becomes a row of pills. Six stacked list rows under a stage
   turns a figure into a screenful. */
@media (max-width:720px){
  .exo3d__key{flex-direction:row;flex-wrap:wrap;gap:6px;padding:13px 14px 15px}
  .exo3d__key > p{width:100%;margin:0 0 3px 2px}
  .exo3d__part{width:auto;background:var(--paper);border:1px solid var(--line);
    border-radius:var(--r-pill);padding:10px 14px;font-size:12.5px}
  .exo3d__part[aria-pressed="true"]{border-color:var(--cyan-mid)}
  .exo3d__reset{margin:5px 0 0 2px}
  .exo3d__foot .source{font-size:11.5px}
}

/* The caption strip. All six entries are in the markup, always — the figure has to
   carry its meaning with no JavaScript, no WebGL, and to a screen reader that never
   sees a canvas. The script adds data-ui to the figure and from then on the strip
   shows one entry at a time, which is what keeps the whole thing the size of a
   photograph instead of the size of a section. */
.exo3d__gloss{border-top:1px solid var(--line);padding:13px 18px;min-height:56px;
  display:flex;flex-direction:column;justify-content:center;gap:5px}
.exo3d__gloss > div{display:flex;gap:9px;align-items:baseline;flex-wrap:wrap}
.exo3d__gloss dt{font:600 12.5px/1.5 var(--font-ui);color:var(--text);flex:none}
.exo3d__gloss dd{font-size:12.5px;line-height:1.5;color:var(--text-3);margin:0}
.exo3d__gloss em{font-style:normal;color:var(--text-2);font-weight:600}

.exo3d__prompt{display:none;font:400 12.5px/1.5 var(--font-ui);color:var(--label)}
.exo3d[data-ui] .exo3d__prompt{display:block}
.exo3d[data-ui][data-active] .exo3d__prompt{display:none}
.exo3d[data-ui] .exo3d__gloss > div[data-gloss]{display:none}
.exo3d[data-ui] .exo3d__gloss > div[data-gloss][data-on]{display:flex}

.exo3d__foot{padding:4px 18px 15px}
.exo3d__foot .source{line-height:1.55}
