/* ============================================================
   SV Deck — shared styles
   Fonts embedded from the exact families used in the Figma file.
   ============================================================ */

@font-face {
  font-family: "Hamburg Hand";
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url("fonts/HamburgHand-Regular.woff2") format("woff2");
}
@font-face {
  font-family: "Hamburg Hand";
  font-style: normal;
  font-weight: 700;
  font-display: block;
  src: url("fonts/HamburgHand-Bold.woff2") format("woff2");
}
@font-face {
  font-family: "Hamburg Hand Light";
  font-style: normal;
  font-weight: 300;
  font-display: block;
  src: url("fonts/HamburgHand-Light.woff2") format("woff2");
}
/* Inter (Google Fonts, OFL) — variable weight, used on some numeric labels. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: block;
  src: url("fonts/Inter-latin.woff2") format("woff2");
}
/* Caveat (Google Fonts, OFL) — handwriting; used on a stamp label. */
@font-face {
  font-family: "Caveat";
  font-style: normal;
  font-weight: 400 700;
  font-display: block;
  src: url("fonts/Caveat-latin.woff2") format("woff2");
}
/* DM Sans (Google Fonts, OFL) — used on some chart labels. */
@font-face {
  font-family: "DM Sans";
  font-style: normal;
  font-weight: 100 1000;
  font-display: block;
  src: url("fonts/DMSans-latin.woff2") format("woff2");
}
/* General Sans (Fontshare, free) — used on some chart/axis labels. */
@font-face {
  font-family: "General Sans";
  font-style: normal;
  font-weight: 500;
  font-display: block;
  src: url("fonts/GeneralSans-Medium.woff2") format("woff2");
}
@font-face {
  font-family: "General Sans";
  font-style: normal;
  font-weight: 600;
  font-display: block;
  src: url("fonts/GeneralSans-Semibold.woff2") format("woff2");
}

/* ----- The palette: two inks on white -----
   Crisp black, full white, flat #F15824 — the logomark's own value, one
   strength, no darkened sibling and no gradient.

   There is no grey in this palette. Every soft tone is black at a reduced
   strength, derived rather than picked: a grey of value v on white is
   identical to black at alpha 1 - v/255. That is what keeps the deck from
   drifting — a third colour cannot appear, because there is nowhere for one
   to hide.

   The accent is used once per slide, on the one thing being argued. Below
   24px it should give way to black: #F15824 carries 3.0:1 on white, which is
   enough for display type and not for a caption.
   ----- */
:root {
  --sans: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica,
          "Segoe UI", Roboto, Arial, sans-serif;
  --sheet: #FFFFFF;
  --ink: #000000;
  --acc: #F15824;
}

/* ----- Stage: fixed 1920x1080 design space ----- */
.stage {
  position: relative;
  width: 1920px;
  height: 1080px;
  overflow: hidden;
  background: var(--sheet);
  transform-origin: top left;
}

/* Slide content fills the stage; children are absolutely positioned in
   1920x1080 design coordinates. */
.slide {
  position: absolute;
  inset: 0;
  width: 1920px;
  height: 1080px;
  overflow: hidden;
}

/* Absolutely-positioned primitives use design-pixel coordinates. */
.abs { position: absolute; }
.txt {
  position: absolute;
  margin: 0;
  padding: 0;
  white-space: nowrap;
  line-height: normal;
  color: var(--ink);
  font-family: var(--sans);
}

/* Body copy in the Figma file is "SF Pro Display" (Apple-proprietary). After
   the reskin the whole deck speaks in one sans, so .sf resolves to the same
   stack as everything else and is kept only so existing slides keep working. */
.sf { font-family: var(--sans); }
img.abs, svg.abs { display: block; }


/* ----- The hundred, narrowing to make room for what it is measured against -----
   The slide after the hundred is a build on it: the field narrows to the
   left, dims, and rises into the room the headline gives up, and the pane
   arrives on the right. The pair is joined by a cut, so the build slide's
   opening frame is the previous slide's closing frame and the move starts
   from exactly there — a cross-fade would ghost a full-size grid over a
   shrinking one.

   Every part of the move is written as an animation away from the state
   before it, with the finished state on the element itself. That is what
   makes it reversible: stepping back plays the widening, and arriving any
   other way — by jump, by deep link, or with animation turned off — simply
   shows the composition already resolved. A build never replays.
   ----- */
@media (prefers-reduced-motion: no-preference) {
  /* forward: the field narrows and the headline gives up its room */
  .layer.active.from-prev .gridshift {
    animation: gridshift 0.72s cubic-bezier(0.32, 0, 0.16, 1) both;
  }
  .layer.active.from-prev .titleout {
    animation: titleout 0.34s ease both;
  }
  .layer.active.from-prev .tests > * {
    animation: testin 0.42s cubic-bezier(0.4, 0, 0.2, 1) both;
  }
  .layer.active.from-prev .tests > *:nth-child(1) { animation-delay: 0.30s; }
  .layer.active.from-prev .tests > *:nth-child(2) { animation-delay: 0.38s; }
  .layer.active.from-prev .tests > *:nth-child(3) { animation-delay: 0.46s; }
  .layer.active.from-prev .tests > *:nth-child(4) { animation-delay: 0.54s; }
  .layer.active.from-prev .tests > *:nth-child(5) { animation-delay: 0.60s; }
  .layer.active.from-prev .tests > *:nth-child(6) { animation-delay: 0.66s; }

  /* company 01 leaves the field, colours, and lands as Photon's mark */
  .layer.active.from-prev .fieldout { animation: fieldout 0.44s ease both; animation-delay: 0.26s; }
  .layer.active.from-prev .markfly  { animation: markfly 0.66s cubic-bezier(0.32, 0, 0.16, 1) both; animation-delay: 0.28s; }
  .layer.active.from-prev .marknum  { animation: marknum 0.66s cubic-bezier(0.32, 0, 0.16, 1) both; animation-delay: 0.28s; }
  .layer.active.from-prev .openin   { animation: openin 0.52s cubic-bezier(0.4, 0, 0.2, 1) both; animation-delay: 0.62s; }

  /* backward: the same gesture, run the other way */
  .layer.active.from-next .gridwide {
    animation: gridwide 0.62s cubic-bezier(0.32, 0, 0.16, 1) both;
  }
  .layer.active.from-next .titlein {
    animation: titlein 0.42s ease both;
    animation-delay: 0.16s;
  }
}

/* The grid's finished state is on the element; each keyframe only says where
   it came from. */
@keyframes gridshift {
  from { transform: none; opacity: 1; }
}
@keyframes gridwide {
  from { transform: translate(-360px, -59px) scale(0.72); opacity: 0.63; }
}
/* the headline leaves on the build and comes back on the way out of it */
@keyframes titleout {
  from { opacity: 1; }
}
@keyframes titlein {
  from { opacity: 0; }
}
@keyframes testin {
  from { opacity: 0; transform: translateX(18px); }
  to   { opacity: 1; transform: none; }
}

/* The field the mark came out of, and the flight itself. The start values are
   the EFFECTIVE ones on the slide before: company 01 sits inside a field drawn
   at 0.63 opacity, so 0.035 ink reads as 0.022 and its numeral as 0.16. */
@keyframes fieldout {
  from { opacity: 0.63; }
}
@keyframes markfly {
  from { left: 99.6px; top: 324.7px; width: 50.4px; height: 50.4px;
         background: rgba(0, 0, 0, 0.022); box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.047); }
}
@keyframes marknum {
  from { left: 124.8px; top: 337.7px; font-size: 11.5px; color: rgba(0, 0, 0, 0.771); opacity: 0.16; }
}
@keyframes openin {
  from { opacity: 0; transform: translateY(12px); }
}

/* ----- A slide that carries its own switch -----
   [data-tabs] holds a set of buttons (data-tab) and the panels they reveal
   (data-panel). Only the marked panel is drawn, so the slide is one page
   with several states rather than several slides. The button is a real
   <button>, which is also what keeps a press from advancing the deck.
   ----- */
/* The group spans the sheet so its panels can use the slide's own
   coordinates. It is scaffolding, not a surface: clicks fall through it to
   whatever the slide has underneath, and only the parts meant to be used
   take them back. */
[data-tabs] { pointer-events: none; }
[data-tabs] [data-panel] { display: none; }
/* A panel is drawn across the whole sheet so its parts can use the slide's
   own coordinates, which would otherwise put it on top of the buttons that
   switch it. It is a picture, not a surface, so clicks pass through it. */
[data-tabs] [data-panel].on { display: block; pointer-events: none; }
/* ...but anything inside one that is meant to be used takes them back: the
   tabs of a nested group, the documents in frames, links and footage. */
[data-tabs] [data-tab],
[data-tabs] [data-panel] iframe,
[data-tabs] [data-panel] video,
[data-tabs] [data-panel] [data-zoom],
[data-tabs] [data-panel] a { pointer-events: auto; }

.gtab {
  display: block;
  width: 100%;
  text-align: left;
  font-family: var(--sans);
  background: none;
  border: none;
  border-left: 3px solid rgba(0, 0, 0, 0.12);
  padding: 14px 18px;
  cursor: pointer;
  box-sizing: border-box;
}
.gtab .k {
  display: block;
  font-size: 13px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: rgba(0, 0, 0, 0.3);
}
.gtab .t {
  display: block;
  margin-top: 4px;
  font-size: 25px;
  font-weight: 500;
  letter-spacing: -0.4px;
  line-height: 1.15;
  color: rgba(0, 0, 0, 0.5);
}
.gtab.on { border-left-color: var(--acc); background: rgba(241, 88, 36, 0.07); }
.gtab.on .k { color: var(--acc); }
.gtab.on .t { color: rgba(0, 0, 0, 0.9); }

/* A pane's own tabs, the level below .gtab */
.stab {
  display: block;
  text-align: left;
  font-family: var(--sans);
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  padding: 0 18px 14px 0;
  cursor: pointer;
  box-sizing: border-box;
}
.stab.on { border-bottom-color: var(--acc); }

.exlink {
  font-size: 16px;
  font-weight: 500;
  color: var(--acc);
  text-decoration: none;
}
.exlink:hover { text-decoration: underline; }

/* ----- The programme rail, as the one-pager carries it -----
   A spine, a square marker per row that fills when the row is live, and the
   rows that are not live sitting back at a third strength. No numbers, no
   fill behind the row: the marker and the weight do the work.
   ----- */
.grow {
  display: flex;
  align-items: center;
  gap: 20px;
  background: none;
  border: none;
  padding: 0;
  font-family: var(--sans);
  text-align: left;
  cursor: pointer;
  opacity: 0.34;
  transition: opacity 0.18s;
}
.grow.on { opacity: 1; }
.grow .mk { flex: 0 0 auto; width: 11px; height: 11px; margin-left: -5px;
             background: #FFFFFF; box-shadow: inset 0 0 0 1px #343A41; }
.grow.on .mk { background: var(--acc); box-shadow: inset 0 0 0 1px var(--acc); }
.grow .yr { display: block; font-size: 13px; font-weight: 600; letter-spacing: 0.16em;
             text-transform: uppercase; font-variant-numeric: tabular-nums; color: #979DA4; }
.grow.on .yr { color: var(--acc); }
.grow .tt { color: #0B0D10; font-size: 22px; font-weight: 500; line-height: 1.3; letter-spacing: -0.014em; }

/* A frame's own tab strip: the live one takes a wash, ink, and its caption
   in the accent. Enough that you can see which one you pressed. */
.ptab {
  appearance: none;
  background: none;
  border: 0;
  cursor: pointer;
  font-family: var(--sans);
  text-align: left;
  padding: 13px 18px;
  box-sizing: border-box;
  transition: background 0.18s, color 0.18s;
}
.ptab .n { display: block; font-size: 17px; line-height: 1.25; font-weight: 500; color: #343A41; }
.ptab .t { display: block; font-size: 14px; line-height: 1.3; color: #787E85; margin-top: 3px; }
.ptab .c { display: block; font-size: 12.5px; letter-spacing: 0.11em; text-transform: uppercase;
           color: #979DA4; margin-top: 4px; }
.ptab:hover { background: #FAFAF8; }
.ptab.on { background: #F5F5F2; }
.ptab.on .n { color: #0B0D10; }
.ptab.cap.on .c { color: var(--acc); }

/* The way out of an exhibit, floating over it rather than sitting under it. */
.exfloat {
  position: absolute;
  font-size: 15px;
  font-weight: 500;
  color: var(--acc);
  text-decoration: none;
  background: #FFFFFF;
  padding: 10px 16px;
  box-shadow: inset 0 0 0 1px #E9E9E4, 0 6px 18px rgba(11, 13, 16, 0.08);
}
.exfloat:hover { box-shadow: inset 0 0 0 1px var(--acc), 0 6px 18px rgba(11, 13, 16, 0.12); }

[data-zoom] { cursor: zoom-in; }

/* ----- The research photographs, drifting -----
   Three stills behind a wash. A slow, staggered scale so the frame is alive
   without asking to be watched; it stops entirely for anyone who has asked
   their system not to animate.
   ----- */
@media (prefers-reduced-motion: no-preference) {
  .kb { animation: kenburns 22s ease-in-out infinite alternate both; transform-origin: center; }
  .kb1 { animation-delay: -7s; }
  .kb2 { animation-delay: -14s; }
}
@keyframes kenburns {
  from { transform: scale(1.00); }
  to   { transform: scale(1.09); }
}

/* ----- What changed, stacking -----
   Each press adds a line and leaves the ones before it exactly where they
   are, so the page builds rather than arriving whole. Only the new line
   moves; the pair is joined by a cut, so the lines already on the sheet do
   not cross-fade with themselves. The finished state is on the element.
   ----- */
@media (prefers-reduced-motion: no-preference) {
  .layer.active.from-prev .rowin { animation: rowin 0.52s cubic-bezier(0.32, 0, 0.16, 1) both; }
  /* the four pairs arrive one after another rather than all at once */
  .layer.active .tests-row { animation: rowin 0.46s cubic-bezier(0.32, 0, 0.16, 1) both; }
  .layer.active .tests-row:nth-of-type(1) { animation-delay: 0.10s; }
  .layer.active .tests-row:nth-of-type(2) { animation-delay: 0.22s; }
  .layer.active .tests-row:nth-of-type(3) { animation-delay: 0.34s; }
  .layer.active .tests-row:nth-of-type(4) { animation-delay: 0.46s; }
}
@keyframes rowin {
  from { opacity: 0; transform: translateY(26px); }
}

/* ----- Our Numbers, in two presses -----
   The record is read on a scale of its own -- the plot stretched 4.762x about
   the baseline, which is what the one-pager does -- so $3.5M climbs instead
   of hugging the axis. The next press returns the plot to a scale that fits
   $20M, every label travelling with its own point, and the projection draws
   in behind them.
   ----- */
@media (prefers-reduced-motion: no-preference) {
  .layer.active.from-prev .jrescale { animation: jrescale 0.72s cubic-bezier(0.32, 0, 0.16, 1) both; }
  .layer.active.from-prev .seg600 { animation: seg600 0.72s cubic-bezier(0.32, 0, 0.16, 1) both; }
  .layer.active.from-prev .lab35  { animation: lab35  0.72s cubic-bezier(0.32, 0, 0.16, 1) both; }
  .layer.active.from-prev .dot35  { animation: dot35  0.72s cubic-bezier(0.32, 0, 0.16, 1) both; }
  .layer.active.from-prev .planpath { animation: planpath 0.8s ease both; animation-delay: 0.52s; }
  .layer.active.from-prev .lab20  { animation: fadeup 0.5s ease both; animation-delay: 0.86s; }
}
@keyframes jrescale { from { transform: scaleY(4.762); } }
@keyframes seg600   { from { top: 673px; } }
@keyframes lab35    { from { top: 357px; } }
@keyframes dot35    { from { top: 427px; } }
@keyframes planpath { from { opacity: 0; } }
@keyframes fadeup   { from { opacity: 0; transform: translateY(14px); } }


/* Arriving at the record, the line walks its own journey: six flat years
   drawn first, then the climb, then the ground under it, then the readings.
   pathLength normalises the dash units so the stretch does not distort it. */
@media (prefers-reduced-motion: no-preference) {
  .layer.active.from-prev .jdraw .jflat {
    animation: drawflat 0.9s cubic-bezier(0.4, 0, 0.6, 1) both;
  }
  .layer.active.from-prev .jdraw .jclimb {
    animation: drawclimb 0.5s cubic-bezier(0.3, 0, 0.2, 1) both;
    animation-delay: 0.86s;
  }
  .layer.active.from-prev .jdraw .jarea { animation: fadein 0.5s ease both; animation-delay: 1.18s; }
  .layer.active.from-prev .jfade { animation: fadeup 0.5s ease both; }
  .layer.active.from-prev .jf1 { animation-delay: 0.52s; }
  .layer.active.from-prev .jf2 { animation-delay: 1.24s; }
}
@keyframes drawflat  { from { stroke-dasharray: 1149; stroke-dashoffset: 1149; }
                       to   { stroke-dasharray: 1149; stroke-dashoffset: 0; } }
@keyframes drawclimb { from { stroke-dasharray: 380; stroke-dashoffset: 380; }
                       to   { stroke-dasharray: 380; stroke-dashoffset: 0; } }
@keyframes fadein { from { opacity: 0; } }

/* ----- Arriving at the hundred -----
   The previous page ends on a tile of small squares at the far right; this
   page opens on the field itself, far left. So the field travels in from
   where that tile was and grows into place, the three roles land a beat
   later, and the terms follow. Only on the way forward: coming back, the
   page is simply there.
   ----- */
@media (prefers-reduced-motion: no-preference) {
  .layer.active.from-prev .gridin {
    transform-origin: 363px 539px;
    animation: gridin 0.78s cubic-bezier(0.32, 0, 0.16, 1) both;
  }
  .layer.active.from-prev .fracin {
    transform-origin: center;
    animation: fracin 0.5s cubic-bezier(0.32, 0, 0.16, 1) both;
    animation-delay: 0.42s;
  }
  .layer.active.from-prev .termsin {
    animation: termsin 0.5s ease both;
    animation-delay: 0.6s;
  }
}
@keyframes gridin {
  from { transform: translate(1166px, -194px) scale(0.6); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
@keyframes fracin {
  from { transform: scale(0.88); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
@keyframes termsin {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* A rail with less room to give: the titles drop a size so each one keeps to
   a single line, and the rows close up to match. */
.railslim .grow { gap: 14px; }
.railslim .grow .tt { font-size: 14px; letter-spacing: -0.005em; }
.railslim .grow .mk { width: 9px; height: 9px; margin-left: -4px; }

/* A strip with five tabs in it has less room per tab, so its second line
   holds to one line at a smaller size rather than wrapping under itself. */
.ptab.slim .n { white-space: nowrap; }
.ptab.slim .t { font-size: 12px; white-space: nowrap; }

/* ----- Who signed -----
   A wall of faces fills the frame. Three of them come out of it in turn: the
   signer's own tile grows into a card, the face gives way to the company's
   mark, and the deal is set beneath it in ink. The finished state sits on
   the elements.
   ----- */
.scard { position: absolute; background: #FFFFFF; overflow: hidden; transform-origin: 0 0;
         box-shadow: 0 1px 0 #E9E9E4, 0 18px 40px rgba(11, 13, 16, 0.10); }
.scard .sface { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; }
.scard .slogo { position: absolute; left: 50%; top: 78px; width: 240px; height: 64px; margin-left: -120px;
                object-fit: contain; object-position: center; mix-blend-mode: multiply; }
.scard .srule { position: absolute; left: 50%; top: 172px; width: 28px; height: 2px; margin-left: -14px;
                background: var(--acc); }
.scard .samt  { position: absolute; left: 0; right: 0; top: 196px; text-align: center; font-size: 62px;
                line-height: 1; font-weight: 500; letter-spacing: -0.035em; color: #0B0D10;
                font-variant-numeric: tabular-nums; }

@media (prefers-reduced-motion: no-preference) {
  [data-panel].on .scard        { animation: scardgrow 0.7s cubic-bezier(0.2, 0, 0.15, 1) both; }
  [data-panel].on .scard .sface { animation: sfaceout 0.45s ease both; }
  [data-panel].on .scard .slogo { animation: slogoin 0.5s cubic-bezier(0.2, 0, 0.2, 1) both; }
  [data-panel].on .scard .srule,
  [data-panel].on .scard .samt  { animation: samtin 0.5s cubic-bezier(0.2, 0, 0.2, 1) both; }
  /* all three together: out of the wall, then the marks, then the deals */
  [data-panel].on .scard        { animation-delay: 0.20s; }
  [data-panel].on .scard .sface { animation-delay: 0.95s; }
  [data-panel].on .scard .slogo { animation-delay: 1.05s; }
  [data-panel].on .scard .srule,
  [data-panel].on .scard .samt  { animation-delay: 1.55s; }
}
/* from the signer's 90px tile in the wall to the 320px card */
@keyframes scardgrow { from { opacity: 0.6; transform: translate(var(--dx), var(--dy)) scale(0.28125); }
                       to   { opacity: 1;   transform: none; } }
@keyframes sfaceout  { from { opacity: 1; } to { opacity: 0; } }
@keyframes slogoin   { from { opacity: 0; transform: translateY(14px) scale(0.9); } to { opacity: 1; transform: none; } }
@keyframes samtin    { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

/* ----- Active pipeline -----
   The same wall of faces; twenty marks come out of it, in reading order. */
.pcard { position: absolute; background: #FFFFFF; display: flex; align-items: center; justify-content: center;
         box-shadow: 0 1px 0 #E9E9E4, 0 12px 28px rgba(11, 13, 16, 0.08); }
.pcard img { width: 66%; max-height: 50%; object-fit: contain; mix-blend-mode: multiply; }
@media (prefers-reduced-motion: no-preference) {
  [data-panel].on .pcard { animation: pcardpop 0.5s cubic-bezier(0.2, 0, 0.2, 1) both; }
  [data-panel].on .pcard.p0 { animation-delay: 0.15s; }
  [data-panel].on .pcard.p1 { animation-delay: 0.26s; }
  [data-panel].on .pcard.p2 { animation-delay: 0.37s; }
  [data-panel].on .pcard.p3 { animation-delay: 0.48s; }
  [data-panel].on .pcard.p4 { animation-delay: 0.59s; }
  [data-panel].on .pcard.p5 { animation-delay: 0.70s; }
  [data-panel].on .pcard.p6 { animation-delay: 0.81s; }
  [data-panel].on .pcard.p7 { animation-delay: 0.92s; }
  [data-panel].on .pcard.p8 { animation-delay: 1.03s; }
  [data-panel].on .pcard.p9 { animation-delay: 1.14s; }
  [data-panel].on .pcard.p10 { animation-delay: 1.25s; }
  [data-panel].on .pcard.p11 { animation-delay: 1.36s; }
  [data-panel].on .pcard.p12 { animation-delay: 1.47s; }
  [data-panel].on .pcard.p13 { animation-delay: 1.58s; }
  [data-panel].on .pcard.p14 { animation-delay: 1.69s; }
  [data-panel].on .pcard.p15 { animation-delay: 1.80s; }
  [data-panel].on .pcard.p16 { animation-delay: 1.91s; }
  [data-panel].on .pcard.p17 { animation-delay: 2.02s; }
  [data-panel].on .pcard.p18 { animation-delay: 2.13s; }
  [data-panel].on .pcard.p19 { animation-delay: 2.24s; }
}
@keyframes pcardpop { from { opacity: 0; transform: translateY(16px) scale(0.6); } to { opacity: 1; transform: none; } }

/* ----- In Amit's words -----
   The film's own field, carried out to the deck's frame: the same near-black,
   the same ruled grid at the same pitch, its lines running straight into
   the film's, so the film is not a rectangle on a panel but a window in
   one field. No build; the page is simply there. */
.testpanel {
  background-color: #020202;
  background-image:
    repeating-linear-gradient(0deg,  rgba(255,255,255,0.085) 0 1px, transparent 1px 47px),
    repeating-linear-gradient(90deg, rgba(255,255,255,0.085) 0 1px, transparent 1px 47px);
}

/* ----- The two deals -----
   A build in five presses. First the 2024 deal alone, centred; then it
   slides to the left and the 2026 deal comes in beside it; then its terms
   arrive one at a time. Transitions, not animations, so a step back is the
   same move in reverse; with animation off the steps still show. */
.dl .dlA { transform: translateX(601px); transition: transform 0.6s cubic-bezier(0.3, 0, 0.15, 1); }
.dl.s1 .dlA, .dl.s2 .dlA, .dl.s3 .dlA, .dl.s4 .dlA { transform: none; }
.dl .dlB { opacity: 0; transform: translateX(28px); transition: opacity 0.5s ease 0.25s, transform 0.6s cubic-bezier(0.3, 0, 0.15, 1) 0.25s; }
.dl.s1 .dlB, .dl.s2 .dlB, .dl.s3 .dlB, .dl.s4 .dlB { opacity: 1; transform: none; }
.dl .dlt { opacity: 0; transform: translateY(14px); transition: opacity 0.4s ease, transform 0.45s cubic-bezier(0.2, 0, 0.2, 1); }
.dl.s2 .dlt2, .dl.s3 .dlt2, .dl.s4 .dlt2,
.dl.s3 .dlt3, .dl.s4 .dlt3,
.dl.s4 .dlt4 { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .dl * { transition: none !important; } }

/* ----- Popovers -----
   A sheet of the page's own, over a shade. Its builds key on .popover.on,
   so they play on every opening. */
.popover { position: absolute; inset: 0; display: none; background: rgba(11, 13, 16, 0.42); z-index: 5; }
.popover.on { display: block; }
.popover .popsheet { position: absolute; left: 120px; top: 68px; width: 1680px; height: 945px; background: #FFFFFF;
                     box-shadow: 0 30px 80px rgba(11, 13, 16, 0.35); overflow: hidden; transform-origin: center; }
.popover .popsheet > * { }
.popover .popinner { position: absolute; left: 0; top: 0; width: 1920px; height: 1080px; transform: scale(0.875); transform-origin: 0 0; }
[data-pop] { cursor: pointer; }
@media (prefers-reduced-motion: no-preference) {
  .popover.on .popsheet { animation: popsheet 0.36s cubic-bezier(0.2, 0, 0.2, 1) both; }
  /* the record rises bar by bar, left to right; each value settles above its bar; the booked target arrives last */
  .popover.on .b0 { animation: aarise 0.5s cubic-bezier(0.2, 0, 0.2, 1) both; animation-delay: 0.35s; }
  .popover.on .aalab0 { animation: aasettle 0.4s ease both; animation-delay: 0.57s; }
  .popover.on .b1 { animation: aarise 0.5s cubic-bezier(0.2, 0, 0.2, 1) both; animation-delay: 0.44s; }
  .popover.on .aalab1 { animation: aasettle 0.4s ease both; animation-delay: 0.66s; }
  .popover.on .b2 { animation: aarise 0.5s cubic-bezier(0.2, 0, 0.2, 1) both; animation-delay: 0.53s; }
  .popover.on .aalab2 { animation: aasettle 0.4s ease both; animation-delay: 0.75s; }
  .popover.on .b3 { animation: aarise 0.5s cubic-bezier(0.2, 0, 0.2, 1) both; animation-delay: 0.62s; }
  .popover.on .aalab3 { animation: aasettle 0.4s ease both; animation-delay: 0.84s; }
  .popover.on .b4 { animation: aarise 0.5s cubic-bezier(0.2, 0, 0.2, 1) both; animation-delay: 0.71s; }
  .popover.on .aalab4 { animation: aasettle 0.4s ease both; animation-delay: 0.93s; }
  .popover.on .b5 { animation: aarise 0.5s cubic-bezier(0.2, 0, 0.2, 1) both; animation-delay: 0.80s; }
  .popover.on .aalab5 { animation: aasettle 0.4s ease both; animation-delay: 1.02s; }
  .popover.on .b6 { animation: aarise 0.5s cubic-bezier(0.2, 0, 0.2, 1) both; animation-delay: 0.89s; }
  .popover.on .aalab6 { animation: aasettle 0.4s ease both; animation-delay: 1.11s; }
  .popover.on .b7 { animation: aarise 0.5s cubic-bezier(0.2, 0, 0.2, 1) both; animation-delay: 0.98s; }
  .popover.on .aalab7 { animation: aasettle 0.4s ease both; animation-delay: 1.20s; }
  .popover.on .b8 { animation: aarise 0.5s cubic-bezier(0.2, 0, 0.2, 1) both; animation-delay: 1.07s; }
  .popover.on .aalab8 { animation: aasettle 0.4s ease both; animation-delay: 1.29s; }
  .popover.on .aatbar { animation: aarise 0.6s cubic-bezier(0.2, 0, 0.2, 1) both; animation-delay: 1.4s; }
  .popover.on .aatlab { animation: aasettle 0.4s ease both; animation-delay: 1.8s; }
}
@keyframes popsheet { from { opacity: 0; transform: scale(0.96); } to { opacity: 1; transform: none; } }
@keyframes aarise { from { transform: scaleY(0); } }
@keyframes aasettle { from { opacity: 0; transform: translateY(8px); } }

/* ----- The hundred, in one press -----
   The slide opens with cell one already Photon, its card above it, and
   everything else stepped back. One press and the Photon card closes as
   the roles' own cards open over their boxes. Transitions, so a step
   back is the same move in reverse. */
.hund .copen { opacity: 0; transition: opacity 0.45s ease; }
.hund .c1 { opacity: 1; }
.hund .pcard { opacity: 0; transform: translateY(10px); transition: opacity 0.45s ease, transform 0.5s cubic-bezier(0.2, 0, 0.2, 1); }
.hund .pline { transform: none; transition: opacity 0.45s ease; }
.hund.s0 .p1 { opacity: 1; transform: none; }
.hund .rcard { opacity: 0; transform: translateY(10px); transition: opacity 0.45s ease, transform 0.5s cubic-bezier(0.2, 0, 0.2, 1); }
.hund.s1 .rcard { opacity: 1; transform: none; }
.hund .gcell, .hund .hband, .hund .lit1 { transition: opacity 0.45s ease; }
.hund .gcell:not(.lit1), .hund .hband { opacity: 0.16; }
/* what opened on the earlier press steps back too */
.hund.s1 .lit1 { opacity: 0.16; }
@media (prefers-reduced-motion: reduce) { .hund * { transition: none !important; } }
