/* joinedcontext pitch deck — brand theme over reveal.js.
   Every colour, size and space comes from tokens.css (--jc-*). Deck-local values
   use a --d- prefix so no --jc-* token is ever defined outside the token build.
   Stage is 1280x720; reveal scales it to whatever it is projected on. */

@font-face { font-family: "Space Grotesk"; src: url("fonts/space-grotesk-400.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Space Grotesk"; src: url("fonts/space-grotesk-500.woff2") format("woff2"); font-weight: 500; font-display: swap; }
@font-face { font-family: "Space Grotesk"; src: url("fonts/space-grotesk-700.woff2") format("woff2"); font-weight: 700; font-display: swap; }

:root {
  --d-pad: 64px;
  --d-chrome: 40px;
  --d-panel-border: 1px solid var(--jc-sem-border-default);

  /* reveal's own theme hooks */
  --r-background-color: var(--jc-sem-bg-page);
  --r-main-font: var(--jc-font-family-body);
  --r-main-color: var(--jc-sem-text-primary);
  --r-heading-font: var(--jc-font-family-brand);
  --r-heading-color: var(--jc-sem-text-primary);
  --r-link-color: var(--jc-sem-text-accent);
  --r-link-color-hover: var(--jc-sem-text-brand);
  --r-selection-background-color: var(--jc-sem-tint-aquaBg);
  --r-selection-color: var(--jc-sem-tint-aquaFg);
}

/* reveal 6 puts .reveal-viewport on <body> with its own white background, and a class
   beats a bare `body` selector, so the page paints white behind every slide unless this
   rule names the class too. */
html, body, .reveal-viewport { background: var(--jc-sem-bg-page); }
.reveal *, .reveal *::before, .reveal *::after { box-sizing: border-box; }

.reveal {
  font-family: var(--jc-font-family-body);
  font-size: 22px;
  line-height: var(--jc-font-leading-normal);
  color: var(--jc-sem-text-primary);
  font-weight: var(--jc-font-weight-regular);
}
.reveal ::selection { background: var(--jc-sem-tint-aquaBg); color: var(--jc-sem-tint-aquaFg); }

/* a slide is a full-bleed panel, never a centred column of text */
.reveal .slides { text-align: left; }
/* reveal writes `display: block` inline on the current slide, which would drop the
   whole flex layout (and every margin-top:auto with it), so this one has to win.
   overflow:hidden keeps scrollHeight equal to the 720px box: reveal measures it when
   building the PDF and hands a slide a second, near-empty page if it is even 1px over. */
.reveal .slides section {
  height: 720px; padding: 0; overflow: hidden;
  display: flex !important; flex-direction: column;
}
/* PDF export sets html.print-pdf, and reveal's rules under it outrank the one above,
   so the slide falls back to display:block and .s grows past its own height. */
html.print-pdf .reveal .slides section { display: flex !important; flex-direction: column; }
.reveal h1, .reveal h2, .reveal h3, .reveal h4 {
  font-family: var(--jc-font-family-brand);
  font-weight: var(--jc-font-weight-bold);
  line-height: var(--jc-font-leading-tight);
  letter-spacing: var(--jc-font-tracking-heading);
  color: var(--jc-sem-text-primary);
  text-transform: none; margin: 0; text-shadow: none;
}
.reveal p { margin: 0; }
.reveal strong { font-weight: var(--jc-font-weight-bold); color: var(--jc-sem-text-primary); }
.reveal code { font-family: var(--jc-font-family-mono); font-size: 0.82em; color: var(--jc-sem-text-accent); }

/* ---------- slide scaffold ---------------------------------------------- */

/* min-height:0 all the way down, otherwise a flex child refuses to shrink below its
   content and the slide quietly grows past its own 720px. */
.s { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: var(--jc-space-8);
     padding: var(--d-pad) var(--d-pad) calc(var(--d-pad) - 16px); }
.s.s-app { gap: var(--jc-space-6); padding-top: calc(var(--d-pad) - 12px); }
.s-head { flex: none; display: flex; flex-direction: column; gap: var(--jc-space-3); }
.s-body { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: var(--jc-space-6); }
.s-foot { flex: none; font-size: var(--jc-font-size-sm); color: var(--jc-sem-text-secondary); max-width: 88ch; }

.eyebrow {
  font-family: var(--jc-font-family-brand);
  font-size: 15px; font-weight: var(--jc-font-weight-medium);
  letter-spacing: var(--jc-font-tracking-wide); text-transform: uppercase;
  color: var(--jc-sem-text-accent);
}
.reveal .s h2 { font-size: 46px; max-width: 24ch; text-wrap: balance; }
.reveal .s h2.tight { font-size: 40px; }
.lead { font-size: 23px; color: var(--jc-sem-text-secondary); max-width: 62ch; }
.punch {
  font-family: var(--jc-font-family-brand); font-weight: var(--jc-font-weight-medium);
  font-size: 25px; line-height: var(--jc-font-leading-tight);
  color: var(--jc-sem-text-primary); max-width: 46ch;
  padding-left: var(--jc-space-6); border-left: 3px solid var(--jc-sem-mark-b);
}

/* ---------- reusable pieces --------------------------------------------- */

.panel {
  background: var(--jc-sem-bg-surface); border: var(--d-panel-border);
  border-radius: var(--jc-radius-lg); padding: var(--jc-space-6);
}
.grid { display: grid; gap: var(--jc-space-4); }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
.split { display: grid; grid-template-columns: 1fr 1.15fr; gap: var(--jc-space-12); align-items: center; flex: 1; min-height: 0; }
.stack { display: flex; flex-direction: column; gap: var(--jc-space-4); }
.row { display: flex; align-items: center; gap: var(--jc-space-4); }

.p-title { font-family: var(--jc-font-family-brand); font-weight: var(--jc-font-weight-bold); font-size: 21px; color: var(--jc-sem-text-primary); }
.p-body { font-size: 17px; color: var(--jc-sem-text-secondary); line-height: var(--jc-font-leading-normal); }
.p-small { font-size: var(--jc-font-size-sm); color: var(--jc-sem-text-secondary); }
.panel-cap {
  font-size: var(--jc-font-size-sm); color: var(--jc-sem-text-secondary);
  letter-spacing: var(--jc-font-tracking-wide); text-transform: uppercase;
}

.chip {
  display: inline-flex; align-items: center; gap: var(--jc-space-2);
  font-family: var(--jc-font-family-brand); font-weight: var(--jc-font-weight-medium);
  font-size: 15px; letter-spacing: var(--jc-font-tracking-wide);
  padding: 6px 14px; border-radius: var(--jc-radius-full); white-space: nowrap;
  background: var(--jc-sem-tint-aquaBg); color: var(--jc-sem-tint-aquaFg);
}
.chip-navy  { background: var(--jc-sem-tint-navyBg);  color: var(--jc-sem-tint-navyFg); }
.chip-blend { background: var(--jc-sem-tint-blendBg); color: var(--jc-sem-tint-blendFg); }
.chip-warn  { background: var(--jc-sem-bg-raised);    color: var(--jc-color-signal-warning); }

.stat { display: flex; flex-direction: column; gap: 2px; }
.stat-n {
  font-family: var(--jc-font-family-brand); font-weight: var(--jc-font-weight-bold);
  font-size: 42px; line-height: 1; letter-spacing: var(--jc-font-tracking-display);
  background: var(--jc-sem-gradient-text); -webkit-background-clip: text; background-clip: text;
  color: transparent;
}
.stat-l { font-size: 15px; color: var(--jc-sem-text-secondary); line-height: 1.35; }

.tint-a { background: var(--jc-sem-tint-navyBg);  color: var(--jc-sem-tint-navyFg); }
.tint-b { background: var(--jc-sem-tint-aquaBg);  color: var(--jc-sem-tint-aquaFg); }
.tint-c { background: var(--jc-sem-tint-blendBg); color: var(--jc-sem-tint-blendFg); }

/* ---------- persistent chrome ------------------------------------------- */

.deck-chrome {
  position: fixed; inset: 0; pointer-events: none; z-index: 6;
  font-family: var(--jc-font-family-brand);
}
.deck-chrome > * { position: absolute; pointer-events: auto; }
.dc-brand {
  bottom: 22px; left: 26px; display: flex; align-items: center; gap: 10px;
  font-size: 13px; letter-spacing: var(--jc-font-tracking-wide);
  color: var(--jc-sem-text-secondary); text-transform: uppercase;
}
.dc-brand img { height: 36px; width: auto; display: block; }
/* reveal's edge arrows, forward and back by mouse */
.reveal .controls { color: var(--jc-sem-text-brand); --r-controls-spacing: 10px; }
.reveal .controls .navigate-up, .reveal .controls .navigate-down { display: none; }
.dc-tools { top: 18px; right: 22px; display: flex; gap: 6px; opacity: 0.42; transition: opacity var(--jc-motion-duration-base) var(--jc-motion-easing-standard); }
.deck-chrome:hover .dc-tools, .dc-tools:focus-within { opacity: 1; }
.dc-tools button, .dc-lang button {
  font: inherit; font-size: 13px; letter-spacing: var(--jc-font-tracking-wide);
  background: var(--jc-sem-bg-raised); color: var(--jc-sem-text-secondary);
  border: var(--d-panel-border); border-radius: var(--jc-radius-md);
  padding: 6px 11px; cursor: pointer; line-height: 1;
  transition: color var(--jc-motion-duration-fast) var(--jc-motion-easing-standard),
              border-color var(--jc-motion-duration-fast) var(--jc-motion-easing-standard);
}
.dc-tools button:hover, .dc-lang button:hover { color: var(--jc-sem-text-accent); border-color: var(--jc-sem-border-focus); }
.dc-lang { top: 22px; left: 26px; display: flex; gap: 6px; }
.dc-lang button[aria-pressed="true"] { color: var(--jc-sem-text-onBrand); background: var(--jc-sem-action-primary); border-color: transparent; }
:root[data-theme="dark"] .dc-lang button[aria-pressed="true"] { color: var(--jc-color-neutral-1000); }
.dc-count {
  bottom: 22px; right: 26px; font-size: 13px; letter-spacing: var(--jc-font-tracking-wide);
  color: var(--jc-sem-text-secondary); font-variant-numeric: tabular-nums;
}
.dc-count b { color: var(--jc-sem-text-primary); font-weight: var(--jc-font-weight-medium); }
.dc-bar { bottom: 0; left: 0; right: 0; height: 3px; background: var(--jc-sem-border-subtle); }
.dc-bar span {
  display: block; height: 100%; width: 0;
  background: var(--jc-sem-gradient-brand);
  transition: width var(--jc-motion-duration-slow) var(--jc-motion-easing-emphasized);
}
.reveal .progress { display: none; }

/* ---------- fragments: one motion language everywhere -------------------- */

.reveal .slides section .fragment { transition: all var(--jc-motion-duration-slow) var(--jc-motion-easing-emphasized); }
.reveal .fragment.rise { opacity: 0; transform: translateY(18px); }
.reveal .fragment.rise.visible { opacity: 1; transform: none; }
.reveal .fragment.slide-in { opacity: 0; transform: translateX(-24px); }
.reveal .fragment.slide-in.visible { opacity: 1; transform: none; }
.reveal .fragment.grow-x { opacity: 0; transform: scaleX(0.4); transform-origin: left center; }
.reveal .fragment.grow-x.visible { opacity: 1; transform: none; }
.reveal .fragment.pop { opacity: 0; transform: scale(0.86); }
.reveal .fragment.pop.visible { opacity: 1; transform: none; }
/* a step that dims once the next one arrives */
.reveal .fragment.step { opacity: 0.24; transition: opacity var(--jc-motion-duration-base) var(--jc-motion-easing-standard); }
.reveal .fragment.step.visible { opacity: 1; }

/* ---------- 01 cover ----------------------------------------------------- */

.cover { justify-content: center; gap: var(--jc-space-6);
         background: var(--jc-sem-gradient-soft); }
.cover .mark-xl { display: none; }
.cover-foot .cover-logo { height: 56px; width: auto; display: block; }
body.on-cover .dc-brand { display: none; }
/* the PDF hides .deck-chrome, so slides 2+ carry a print-only copy of the corner logo */
.print-logo { display: none; }
@media print { .print-logo { display: block; position: absolute; left: 26px; bottom: 22px; height: 36px; width: auto; z-index: 5; } }
.reveal .cover h1 {
  font-size: 76px; letter-spacing: var(--jc-font-tracking-display);
  line-height: var(--jc-font-leading-display); max-width: 13ch;
  background: var(--jc-sem-gradient-text); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.cover .lead { font-size: 25px; color: var(--jc-sem-text-primary); max-width: 64ch; }
.cover-foot { margin-top: var(--jc-space-8); display: flex; justify-content: space-between; align-items: flex-end; gap: var(--jc-space-8); }
/* the name of the platform, big enough to read from the back row, in the title's gradient */
.cover-foot .p-small { font-family: var(--jc-font-family-brand); font-weight: var(--jc-font-weight-bold); font-size: 40px;
  letter-spacing: var(--jc-font-tracking-display); line-height: 1;
  background: var(--jc-sem-gradient-text); -webkit-background-clip: text; background-clip: text; color: transparent; }
.cover-hint { font-family: var(--jc-font-family-brand); font-size: 15px; color: var(--jc-sem-text-secondary); letter-spacing: var(--jc-font-tracking-wide); }
.cover-hint::after { content: ""; display: inline-block; width: 8px; height: 8px; margin-left: 10px; border-radius: 50%; background: var(--jc-sem-mark-b); animation: pulse 2.2s var(--jc-motion-easing-standard) infinite; }
@keyframes pulse { 0%, 100% { opacity: 0.25; transform: scale(0.8); } 50% { opacity: 1; transform: scale(1.15); } }

/* ---------- 02 question -------------------------------------------------- */

.s-centre { justify-content: center; gap: var(--jc-space-8); }
.q-main {
  font-family: var(--jc-font-family-brand); font-weight: var(--jc-font-weight-bold);
  font-size: 56px; line-height: var(--jc-font-leading-tight);
  letter-spacing: var(--jc-font-tracking-heading);
  color: var(--jc-sem-text-primary); max-width: 26ch;
}
.q-verdict { display: flex; align-items: center; gap: var(--jc-space-4); }
.q-verdict p {
  font-family: var(--jc-font-family-brand); font-weight: var(--jc-font-weight-medium);
  font-size: 27px; color: var(--jc-color-signal-error); letter-spacing: var(--jc-font-tracking-heading);
}


/* ---------- 03 + 04, isolation morphing into unification ------------------
   The two slides carry the same four nodes under matching data-auto-animate-id,
   so reveal glides each one from its scattered position onto the cross around the
   hub. Positions are percentages of the stage and name the element's CENTRE, which
   keeps the maths readable. The centring is done with negative margins, not with
   translate(-50%,-50%): reveal's auto-animate writes `transform: none` onto every
   matched element when the morph settles, and that silently drops half a card down
   and to the right. Anything positioned inside .stage therefore needs a fixed size
   and matching negative margins. */

.stage { position: relative; flex: none; height: 330px; }
/* isolation gets the taller stage: the four groups read as far apart, and the morph
   into the tighter unification stage pulls them visibly together */
.stage-iso { height: 420px; }
/* slide 4 carries one line more at the foot than slide 3, so it buys the room back
   from the gaps rather than from the stage: a shorter stage would move the cards
   mid-morph and reveal leaves its own height on an auto-animated stage anyway */
.s-uni { gap: var(--jc-space-4); }
/* the head is reserved, not measured: a title that wraps in one language and not in
   another would otherwise move every node and push the bottom row off the stage */
.s-stage .s-head { min-height: 140px; }
.stage .links {
  position: absolute; inset: 0; width: 100%; height: 100%;
}
.link-broken path {
  fill: none; stroke: var(--jc-sem-border-strong); stroke-width: 2;
  stroke-dasharray: 7 7; vector-effect: non-scaling-stroke; opacity: 0.6;
}
.link-live path {
  fill: none; stroke: var(--jc-sem-mark-b); stroke-width: 2.5;
  vector-effect: non-scaling-stroke;
  stroke-dasharray: 6 8; stroke-dashoffset: 0;
}
.present .link-live path { animation: flow 1.1s linear infinite; }
@keyframes flow { to { stroke-dashoffset: -28; } }

/* the red break in the middle of each dead link */
.cut {
  position: absolute; margin: -15px 0 0 -15px;
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--jc-sem-bg-page);
  display: grid; place-items: center;
}
.cut::before, .cut::after {
  content: ""; position: absolute; width: 17px; height: 2.5px; border-radius: 2px;
  background: var(--jc-color-signal-error);
}
.cut::before { transform: rotate(45deg); }
.cut::after  { transform: rotate(-45deg); }

.node {
  position: absolute; margin: -66px 0 0 -150px;
  width: 300px; height: 132px; padding: var(--jc-space-4) var(--jc-space-3);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--jc-space-2);
  border-radius: var(--jc-radius-lg); background: var(--jc-sem-bg-surface);
  text-align: center;
}
.node .icon { color: var(--jc-sem-mark-a); }
.node-label {
  font-family: var(--jc-font-family-brand); font-weight: var(--jc-font-weight-medium);
  font-size: 18px; color: var(--jc-sem-text-primary); line-height: var(--jc-font-leading-tight);
}
.fmt {
  font-family: var(--jc-font-family-mono); font-size: 16px;
  padding: 4px 11px; border-radius: var(--jc-radius-full); white-space: nowrap;
}

/* isolated: a dashed wall of its own, a format nobody else reads */
.node.walled { border: 2px dashed var(--jc-sem-border-strong); }
.node.walled .icon { color: var(--jc-sem-text-secondary); }
.node.walled .fmt { background: var(--jc-sem-bg-raised); color: var(--jc-color-signal-warning); }

/* joined: a solid brand edge and the one format everybody reads */
.node.joined { border: 2px solid var(--jc-sem-mark-b); box-shadow: var(--jc-shadow-md); }
.node.joined .fmt, .fmt-on { background: var(--jc-sem-tint-aquaBg); color: var(--jc-sem-tint-aquaFg); }

.hub {
  position: absolute; left: 50%; top: 50%; margin: -94px 0 0 -94px;
  width: 188px; height: 188px; border-radius: 50%;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--jc-space-2);
  background: var(--jc-sem-bg-surface); border: 2px solid var(--jc-sem-mark-a);
  box-shadow: var(--jc-shadow-lg);
}
.present .hub { animation: hubIn 700ms 250ms var(--jc-motion-easing-emphasized) backwards; }
@keyframes hubIn { from { opacity: 0; transform: scale(0.72); } }
.hub-label {
  font-family: var(--jc-font-family-brand); font-weight: var(--jc-font-weight-medium);
  font-size: 17px; color: var(--jc-sem-text-brand);
}
.eyebrow-warn { color: var(--jc-color-signal-warning); }
.uni-foot { display: flex; flex-direction: column; align-items: center; gap: var(--jc-space-3); }
.uni-foot .p-small { font-size: 17px; color: var(--jc-sem-text-primary); }
/* the exit argument: for a public buyer this is often the objection that blocks a signature */
.uni-exit { font-size: 15px; color: var(--jc-sem-text-secondary); }

/* ---------- 05 sixty seconds --------------------------------------------- */

.sixty-track { position: relative; height: 6px; border-radius: var(--jc-radius-full); background: var(--jc-sem-bg-raised); margin: var(--jc-space-8) 0 var(--jc-space-6); }
.sixty-fill {
  position: absolute; inset: 0 auto 0 0; width: var(--d-progress, 0%);
  border-radius: var(--jc-radius-full); background: var(--jc-sem-gradient-brand);
  transition: width 700ms var(--jc-motion-easing-emphasized);
}
.sixty-dot {
  position: absolute; top: 50%; width: 15px; height: 15px; border-radius: 50%;
  transform: translate(-50%, -50%); background: var(--jc-sem-bg-page);
  border: 2px solid var(--jc-sem-border-strong);
  transition: border-color var(--jc-motion-duration-base) var(--jc-motion-easing-standard),
              box-shadow var(--jc-motion-duration-base) var(--jc-motion-easing-standard);
}
.sixty-dot.on { border-color: var(--jc-sem-mark-b); box-shadow: 0 0 0 6px var(--jc-sem-tint-aquaBg); }
.sixty-steps { display: grid; grid-template-columns: repeat(5, 1fr); gap: var(--jc-space-4); align-items: stretch; }
.sixty-step {
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--jc-space-3);
  background: var(--jc-sem-bg-surface); border: var(--d-panel-border);
  border-radius: var(--jc-radius-lg); padding: var(--jc-space-6) var(--jc-space-4);
}
.sixty-step .icon { color: var(--jc-sem-mark-a); }
.sixty-step:last-child .icon { color: var(--jc-sem-mark-b); }
.sixty-t {
  font-family: var(--jc-font-family-mono); font-size: 16px; font-variant-numeric: tabular-nums;
  color: var(--jc-sem-text-accent); letter-spacing: var(--jc-font-tracking-wide);
}
.sixty-step .p-title { font-size: 20px; }
.sixty-step:last-child { border-color: var(--jc-sem-mark-b); }

/* ---------- mini-app screens --------------------------------------------- */

.app {
  flex: 1; min-height: 0; display: flex; flex-direction: column;
  background: var(--jc-sem-bg-surface); border: var(--d-panel-border);
  border-radius: var(--jc-radius-xl); overflow: hidden; box-shadow: var(--jc-shadow-lg);
}
.app-bar {
  flex: none; display: flex; align-items: center; gap: var(--jc-space-3);
  padding: 9px var(--jc-space-6); border-bottom: var(--d-panel-border);
  background: var(--jc-sem-bg-muted);
}
.app-dots { display: flex; gap: 6px; }
.app-dots i { width: 9px; height: 9px; border-radius: 50%; background: var(--jc-sem-border-strong); display: block; }
.app-q {
  font-family: var(--jc-font-family-brand); font-weight: var(--jc-font-weight-medium);
  font-size: 16px; color: var(--jc-sem-text-primary);
}
.app-live { margin-left: auto; display: flex; align-items: center; gap: 7px; font-size: 13px; color: var(--jc-sem-text-secondary); letter-spacing: var(--jc-font-tracking-wide); }
.app-live::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--jc-color-signal-success); animation: pulse 2s var(--jc-motion-easing-standard) infinite; }
.app-body { flex: 1; min-height: 0; display: grid; grid-template-rows: minmax(0, 1fr) auto;
            gap: var(--jc-space-4); padding: var(--jc-space-4) var(--jc-space-6); }
.app-body > * { min-height: 0; min-width: 0; }
.app-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--jc-space-6); padding-top: var(--jc-space-3); border-top: var(--d-panel-border); }
.app-stats .stat-n { font-size: 34px; }

/* map-ish panels */
.map-wrap { position: relative; border-radius: var(--jc-radius-lg); overflow: hidden; background: var(--jc-sem-bg-muted); }
.map-wrap svg { display: block; width: 100%; height: 100%; }
.map-district { fill: var(--jc-sem-bg-raised); stroke: var(--jc-sem-border-default); stroke-width: 1.5; transition: fill var(--jc-motion-duration-slow) var(--jc-motion-easing-standard); }
.present .map-district.hot { fill: var(--jc-sem-tint-aquaBg); }
.map-label { font-family: var(--jc-font-family-brand); font-size: 15px; fill: var(--jc-sem-text-secondary); }
.map-pin { fill: var(--jc-sem-mark-b); opacity: 0; }
.present .map-pin { animation: drop 520ms var(--jc-motion-easing-emphasized) forwards; }
@keyframes drop { from { opacity: 0; transform: translateY(-16px); } to { opacity: 0.9; transform: none; } }

/* horizontal bars that draw themselves in */
.bars { display: flex; flex-direction: column; gap: 20px; justify-content: center; min-height: 0; overflow: hidden; }
.bar-row { display: grid; grid-template-columns: 1fr 46px; gap: var(--jc-space-4); align-items: center; }
.bar-label { font-size: 15px; color: var(--jc-sem-text-secondary); margin-bottom: 3px; }
.bar-track { height: 12px; border-radius: var(--jc-radius-full); background: var(--jc-sem-bg-raised); overflow: hidden; }
.bar-fill {
  display: block; height: 100%; width: 0; border-radius: var(--jc-radius-full);
  background: var(--jc-sem-mark-c);
}
.present .bar-fill { animation: growx 900ms var(--jc-motion-easing-emphasized) forwards; }
@keyframes growx { from { width: 0; } to { width: var(--d-w, 50%); } }
.bar-fill.hot { background: var(--jc-sem-gradient-brand); }
.bar-val { font-family: var(--jc-font-family-mono); font-size: 14px; color: var(--jc-sem-text-primary); text-align: right; font-variant-numeric: tabular-nums; }

/* a line chart that draws itself */
.spark { width: 100%; height: 100%; display: block; }
.spark-line { fill: none; stroke: var(--jc-sem-mark-b); stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round;
              stroke-dasharray: 1400; stroke-dashoffset: 1400; }
.present .spark-line { animation: draw 1400ms var(--jc-motion-easing-emphasized) forwards; }
@keyframes draw { to { stroke-dashoffset: 0; } }
.spark-area { fill: var(--jc-sem-tint-aquaBg); opacity: 0; }
.present .spark-area { animation: fade 900ms 600ms var(--jc-motion-easing-standard) forwards; }
@keyframes fade { to { opacity: 0.7; } }
.spark-grid { stroke: var(--jc-sem-border-subtle); stroke-width: 1; }
.spark-axis { font-family: var(--jc-font-family-mono); font-size: 11px; fill: var(--jc-sem-text-secondary); }
.spark-peak { fill: var(--jc-sem-mark-a); opacity: 0; }
.present .spark-peak { animation: fade 400ms 1500ms var(--jc-motion-easing-standard) forwards; }

/* a ring gauge */
.ring { transform: rotate(-90deg); }
.ring-bg { fill: none; stroke: var(--jc-sem-bg-raised); stroke-width: 13; }
.ring-fg { fill: none; stroke: var(--jc-sem-mark-b); stroke-width: 13; stroke-linecap: round;
           stroke-dasharray: 327; stroke-dashoffset: 327; }
.present .ring-fg { animation: ring 1200ms var(--jc-motion-easing-emphasized) forwards; }
@keyframes ring { to { stroke-dashoffset: var(--d-off, 100); } }
.ring-mid { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; }

/* a data table that looks like an app grid */
.app-table { width: 100%; border-collapse: collapse; font-size: 16px; }
.app-table th {
  text-align: left; font-family: var(--jc-font-family-brand); font-weight: var(--jc-font-weight-medium);
  font-size: 13px; letter-spacing: var(--jc-font-tracking-wide); text-transform: uppercase;
  color: var(--jc-sem-text-secondary); padding: 0 var(--jc-space-3) 11px; border-bottom: var(--d-panel-border);
}
.app-table td { padding: 22px var(--jc-space-3); border-bottom: 1px solid var(--jc-sem-border-subtle); vertical-align: middle; }
.app-table tr:last-child td { border-bottom: 0; }
.pill {
  display: inline-block; font-size: 13px; font-weight: var(--jc-font-weight-medium);
  padding: 4px 11px; border-radius: var(--jc-radius-full); white-space: nowrap;
}
.mini-track { height: 7px; border-radius: var(--jc-radius-full); background: var(--jc-sem-bg-raised); overflow: hidden; }
.mini-track span { display: block; height: 100%; width: 0; background: var(--jc-sem-mark-b); border-radius: var(--jc-radius-full); }
.present .mini-track span { animation: growx 900ms var(--jc-motion-easing-emphasized) forwards; }

/* ---------- standards strip, on the unification slide --------------------- */

.std-strip { display: flex; flex-wrap: wrap; gap: var(--jc-space-2); justify-content: center; }
.std {
  font-family: var(--jc-font-family-mono); font-size: 13px;
  padding: 5px 11px; border-radius: var(--jc-radius-sm);
  background: var(--jc-sem-bg-raised); color: var(--jc-sem-text-secondary);
}

/* ---------- 10 ask -------------------------------------------------------- */

/* align-items:center lets a card hug its own content and sit centred in the band.
   Stretched, three cards of 180px content became three 480px boxes of mostly black. */
.ask-steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--jc-space-6); flex: 1; align-items: center; }
.ask-step { display: flex; flex-direction: column; justify-content: center;
  gap: var(--jc-space-4); padding: var(--jc-space-6);
            background: var(--jc-sem-bg-surface); border: var(--d-panel-border); border-radius: var(--jc-radius-lg); }
.ask-num {
  width: 52px; height: 52px; border-radius: var(--jc-radius-md); display: grid; place-items: center;
  background: var(--jc-sem-gradient-brand); color: var(--jc-sem-text-onBrand);
}
.ask-proof { margin-top: auto; font-size: var(--jc-font-size-sm); color: var(--jc-sem-text-secondary); }
.ask-contact { display: flex; gap: var(--jc-space-8); align-items: center; }
.ask-contact a { font-family: var(--jc-font-family-brand); font-size: 21px; color: var(--jc-sem-text-accent); text-decoration: none; }
.ask-contact a:hover { color: var(--jc-sem-text-brand); text-decoration: underline; }
/* the last slide: the address right under the title, three cards of equal height */
.s-contact .ask-contact { margin-top: var(--jc-space-4); }
.s-contact .ask-contact a { font-size: 28px; }
.s-contact .ask-steps { flex: none; margin-block: auto; align-items: stretch; }
.s-contact .ask-step { justify-content: flex-start; }

/* ---------- accessibility and print --------------------------------------- */


/* 04b the endpoint fan: one pill in the middle, a spoke per representation, staggered in */
.stage-epfan { height: 400px; }
.ep-centre { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 2; }
.ep-centre .dg-m { font-family: var(--jc-font-family-mono); font-size: 13px; color: var(--jc-sem-text-secondary); }
.spoke {
  position: absolute; transform: translate(-50%, -50%);
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 6px 12px; border-radius: var(--jc-radius-full);
  background: var(--jc-sem-tint-aquaBg); color: var(--jc-sem-tint-aquaFg);
  border: 1.5px solid var(--jc-sem-mark-b); box-shadow: var(--jc-shadow-md);
  white-space: nowrap;
}
.spoke-n { font-family: var(--jc-font-family-mono); font-size: 16px; font-weight: var(--jc-font-weight-medium); }
.link-spokes path { stroke-dasharray: 5 7; opacity: 0; }
.present .link-spokes path { animation: flow 1.1s linear infinite, fadeIn 300ms calc(400ms + var(--d-i) * 140ms) forwards; }
.present .spoke { opacity: 0; animation: spokeIn 500ms calc(400ms + var(--d-i) * 140ms) var(--jc-motion-easing-emphasized) forwards; }
@keyframes spokeIn { from { opacity: 0; transform: translate(-50%, -50%) scale(0.4); } to { opacity: 1; transform: translate(-50%, -50%) scale(1); } }
@keyframes fadeIn { to { opacity: 1; } }
.epfan-sub { text-align: center; margin-top: var(--jc-space-2); }

@media (prefers-reduced-motion: reduce) {
  .reveal .fragment, .present .bar-fill, .present .spark-line, .present .spark-area,
  .present .ring-fg, .present .map-pin, .present .mini-track span, .present .spark-peak,
  .cover-hint::after, .app-live::before, .present .spoke, .present .link-spokes path,
  .present .shard, .present .cracks, .present .glass-hub, .present .glass-hub::after, .present .glass-links path,
  .present .seams path, .present .glass-context .s-head,
  .present .verbs-in .verb { animation: none !important; transition: none !important; }
  .spoke, .link-spokes path { opacity: 1; }
  .reveal .fragment { opacity: 1 !important; transform: none !important; }
  .bar-fill { width: var(--d-w, 50%); }
  .spark-line { stroke-dashoffset: 0; }
  .spark-area, .spark-peak, .map-pin { opacity: 0.8; }
  .ring-fg { stroke-dashoffset: var(--d-off, 100); }
  .mini-track span { width: var(--d-w, 50%); }
}

/* printing goes through reveal's ?print-pdf mode; deck.js drops the dark theme first */
@media print {
  /* Chromium prints a box-shadow or a drop-shadow filter as a raster, and Preview on the Mac
     paints that raster as a grey rectangle behind the element: every pill, bubble and hub
     looked "selected" in the PDF. Print flat. */
  *, *::before, *::after { box-shadow: none !important; filter: none !important; text-shadow: none !important; }
  .deck-chrome, .dc-tools, .dc-lang, .reveal .controls { display: none !important; }
  video::-webkit-media-controls { display: none !important; }
  .reveal .slides section { height: 720px; overflow: hidden; }
  .app { box-shadow: none; }
  .bar-fill { width: var(--d-w, 50%); animation: none; }
  .spark-line { stroke-dashoffset: 0; animation: none; }
  .spark-area, .spark-peak, .map-pin { opacity: 0.8; animation: none; }
  .ring-fg { stroke-dashoffset: var(--d-off, 100); animation: none; }
  .mini-track span { width: var(--d-w, 50%); animation: none; }
  .shard, .cracks, .glass-hub, .glass-hub::after, .glass-links path, .seams path, .glass-context .s-head, .glass .spoke, .verbs-in .verb { animation: none !important; }
}

/* ==========================================================================
   The 60-second rule and the five units. Every unit is three slides with the
   same shape, so the styles below are shared by all five rather than written
   per unit: a problem slide, a solution slide, a proof slide.
   ========================================================================== */

.eyebrow-proof { color: var(--jc-sem-text-brand); }
.reveal .s h2.big { font-size: 52px; max-width: 20ch; }
.lead-wide { max-width: 72ch; }
/* share: the title on two lines and the endpoint explainer on one, so the four rings fit under them */
.s-share .s-head h2 { max-width: 32ch; }
.s-share .s-head .lead { max-width: 96ch; }

/* ---------- 02 the question: days, weeks, months ------------------------- */

.timebox { display: flex; gap: var(--jc-space-6); }
.tchip {
  font-family: var(--jc-font-family-brand); font-weight: var(--jc-font-weight-bold);
  font-size: 40px; letter-spacing: var(--jc-font-tracking-heading);
  color: var(--jc-sem-text-brand);
  padding: var(--jc-space-3) var(--jc-space-8);
  border: 2px solid var(--jc-sem-border-strong); border-radius: var(--jc-radius-lg);
}

/* ---------- the five verbs ---------------------------------------------- */

.verbs { display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--jc-space-3); }
.verb {
  display: flex; flex-direction: column; align-items: center; gap: var(--jc-space-3);
  padding: var(--jc-space-6) var(--jc-space-3);
  background: var(--jc-sem-bg-surface); border: var(--d-panel-border);
  border-radius: var(--jc-radius-lg); text-align: center;
}
.verb-ic {
  width: 52px; height: 52px; border-radius: var(--jc-radius-lg);
  display: grid; place-items: center;
  background: var(--jc-sem-tint-aquaBg); color: var(--jc-sem-tint-aquaFg);
}
.verb-n { font-family: var(--jc-font-family-brand); font-weight: var(--jc-font-weight-bold); font-size: 20px; color: var(--jc-sem-text-primary); }
.verb-s { font-family: var(--jc-font-family-mono); font-size: 15px; color: var(--jc-sem-text-accent); }
/* the rule slide: all seven verbs rise in together, staggered, no key presses */
.present .verbs-in .verb { animation: riseIn 500ms calc(200ms + var(--d-i) * 110ms) var(--jc-motion-easing-emphasized) both; }
@keyframes riseIn { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }

/* ---------- a problem slide: what it costs today ------------------------- */

.cost-strip { display: flex; flex-wrap: wrap; gap: var(--jc-space-3); }
.cost {
  display: inline-flex; align-items: center; gap: var(--jc-space-2);
  font-size: 18px; color: var(--jc-color-signal-warning);
  padding: var(--jc-space-2) var(--jc-space-4);
  background: var(--jc-sem-bg-surface); border: var(--d-panel-border);
  border-radius: var(--jc-radius-full);
}

/* ---------- asking for something ------------------------------------------ */

.askbar {
  display: flex; align-items: center; gap: var(--jc-space-3);
  font-family: var(--jc-font-family-brand); font-size: 22px;
  color: var(--jc-sem-text-primary);
  padding: var(--jc-space-4) var(--jc-space-6);
  background: var(--jc-sem-bg-surface); border: 2px solid var(--jc-sem-mark-b);
  border-radius: var(--jc-radius-full); box-shadow: var(--jc-shadow-md);
}
.askbar .icon { color: var(--jc-sem-mark-b); flex: none; }

/* ---------- the unit diagrams: one language, five drawings ----------------
   A card with an icon is a thing (a source, a person, a partner, an app); the ringed
   mark is the one context; a pill with the network icon is an endpoint; a dashed aqua
   ring is a boundary somebody drew; an arrow is data moving; a struck chip stays out.
   Every label is 16px or larger: 24 physical pixels on a 1080 frame, the same bar as
   the recordings, and check_deck.py fails anything smaller inside a .dg or a .stage. */

.dg { display: flex; align-items: center; justify-content: center; gap: var(--jc-space-3); }
.dg-col { display: flex; flex-direction: column; gap: var(--jc-space-3); }
.dg-node {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--jc-space-2); flex: none;
  width: 210px; min-height: 104px; padding: var(--jc-space-3) var(--jc-space-4); text-align: center;
  background: var(--jc-sem-bg-surface); border: 2px solid var(--jc-sem-border-strong);
  border-radius: var(--jc-radius-lg);
}
.dg-node .icon { color: var(--jc-sem-mark-a); flex: none; }
.dg-node.you .icon, .dg-node.partner .icon { color: var(--jc-sem-tint-blendFg); }
.dg-node.you, .dg-node.partner { width: 140px; }
.dg-node.sm { width: 140px; min-height: 96px; }
.dg-node.ind { width: 190px; }
.dg-node.live { border-color: var(--jc-sem-mark-b); box-shadow: var(--jc-shadow-md); }
.dg-node.dg-row {
  flex-direction: row; justify-content: flex-start; text-align: left;
  width: 600px; min-height: 0; padding: var(--jc-space-3) var(--jc-space-4); gap: var(--jc-space-4);
}
.dg-node.dg-ep {
  flex-direction: row; width: auto; min-height: 0; padding: 9px 18px; gap: var(--jc-space-2);
  border-radius: var(--jc-radius-full);
}
.dg-node.dg-ep .icon { color: var(--jc-sem-mark-b); }
.dg-l {
  font-family: var(--jc-font-family-brand); font-weight: var(--jc-font-weight-medium);
  font-size: 18px; line-height: var(--jc-font-leading-tight); color: var(--jc-sem-text-primary);
}
.dg-m { font-family: var(--jc-font-family-mono); font-size: 16px; color: var(--jc-sem-text-secondary); }
.dg-hub {
  flex: none; width: 132px; height: 132px; border-radius: 50%;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--jc-space-1);
  background: var(--jc-sem-bg-surface); border: 2px solid var(--jc-sem-mark-a); box-shadow: var(--jc-shadow-lg);
  text-align: center; padding: 0 var(--jc-space-2);
}
.dg-hub .dg-l { font-size: 16px; color: var(--jc-sem-text-brand); }
.dg-hub .icon { color: var(--jc-sem-mark-a); }
.dg-arrow { flex: none; }
.dg-arrow path { fill: none; stroke: var(--jc-sem-mark-b); stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }
.dg-arrow.back { transform: rotate(180deg); }
.dg-arrow.back path { stroke: var(--jc-sem-tint-blendFg); }
.dg-arrowbox { display: flex; flex-direction: column; align-items: center; gap: 2px; flex: none; }
.dg-al { font-family: var(--jc-font-family-mono); font-size: 16px; color: var(--jc-sem-text-secondary); min-height: 20px; white-space: nowrap; }
.dg-chip {
  font-family: var(--jc-font-family-mono); font-size: 16px;
  padding: 5px 12px; border-radius: var(--jc-radius-full); white-space: nowrap;
}
/* in and out have to be readable without the colour, so the excluded one is struck through as well as tinted */
.dg-chip.on { background: var(--jc-sem-tint-aquaBg); color: var(--jc-sem-tint-aquaFg); }
.dg-chip.off { background: var(--jc-sem-bg-raised); color: var(--jc-sem-text-secondary); text-decoration: line-through; }
.dg-ring {
  position: relative; display: flex; align-items: center; gap: var(--jc-space-3);
  padding: var(--jc-space-4); border: 2px dashed var(--jc-sem-mark-b); border-radius: var(--jc-radius-lg);
}
.dg-ring-t {
  position: absolute; top: -11px; left: var(--jc-space-4); padding: 0 var(--jc-space-2);
  background: var(--jc-sem-bg-page);
  font-family: var(--jc-font-family-mono); font-size: 16px; letter-spacing: var(--jc-font-tracking-wide);
  text-transform: uppercase; color: var(--jc-sem-text-accent);
}
/* share: one grid, so the three rows share their columns and the partners line up */
.dg-share { display: grid; grid-template-columns: repeat(5, max-content); gap: 10px 10px; align-items: center; justify-content: center; }
.dg-share > :nth-child(-n+2) { grid-row: 1 / span 4; }   /* the hub and its arrow sit beside all four rows */
.dg-share .dg-ring { width: 600px; padding: 6px var(--jc-space-3); gap: 6px; flex-wrap: wrap; }
.dg-break { flex-basis: 100%; height: 0; }
.dg-chip.fmt { background: var(--jc-sem-bg-raised); color: var(--jc-sem-text-secondary); padding: 3px 10px; }
.dg-chip.ai { display: inline-flex; align-items: center; gap: 5px; background: var(--jc-sem-tint-navyBg); color: var(--jc-sem-tint-navyFg); }
.dg-share .dg-step { display: flex; justify-content: center; }
.dg-share .dg-node.partner { width: 140px; }
.dg-share .dg-al { white-space: normal; max-width: 130px; text-align: center; line-height: 1.2; }
.dg-share .dg-arrowbox .dg-al:empty { display: none; }
.dg-compact .dg-node { min-height: 84px; }
.dg-compact .dg-hub { width: 112px; height: 112px; }
/* integrate and analyse: a flow of steps; the chips under a node say what it holds */
.dg-flow .dg-step { display: flex; align-items: center; }
.dg-flow .dg-col { align-items: center; gap: var(--jc-space-2); }
.dg-chips { display: flex; flex-wrap: wrap; justify-content: center; gap: 4px; max-width: 190px; }
.dg-ring.col { flex-direction: column; gap: var(--jc-space-2); }
.dg-ring.col .dg-chips { max-width: 280px; }

/* ---------- a proof slide that is waiting for a screen recording ---------- */

.vidframe {
  position: relative; width: 100%; max-width: 820px; height: 372px; margin: 0 auto;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--jc-space-4);
  border: 2px dashed var(--jc-sem-border-strong); border-radius: var(--jc-radius-lg);
  background: var(--jc-sem-bg-surface);
}
.vidframe-sm { height: 190px; max-width: 700px; }
.vidframe-story { width: 100%; max-width: 640px; height: 360px; aspect-ratio: 16 / 9; margin: 0 auto; }
.vidframe-story + .lead { text-align: center; margin: 0 auto; }
.vidframe-live { width: auto; aspect-ratio: 16 / 9; padding: 0; overflow: hidden; border-style: solid; }
.vidframe-live video { display: block; width: 100%; height: 100%; object-fit: contain; }
.vid-play {
  width: 72px; height: 72px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--jc-sem-tint-aquaBg); color: var(--jc-sem-tint-aquaFg);
}
.vid-note { font-family: var(--jc-font-family-mono); font-size: 15px; color: var(--jc-sem-text-secondary); }
.vid-cap { text-align: center; max-width: 68ch; margin: 0 auto; }

/* ---------- the measured proof ------------------------------------------- */

.pfgrid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--jc-space-6); }
.pf {
  padding: var(--jc-space-6);
  background: var(--jc-sem-bg-surface); border: var(--d-panel-border);
  border-radius: var(--jc-radius-lg);
}
.pf-n {
  font-family: var(--jc-font-family-brand); font-weight: var(--jc-font-weight-bold);
  font-size: 34px; letter-spacing: var(--jc-font-tracking-heading);
  color: var(--jc-sem-text-brand); margin-bottom: var(--jc-space-2);
}
.pf-b { font-size: 16px; color: var(--jc-sem-text-secondary); line-height: var(--jc-font-leading-normal); }
.pf-cond { font-size: var(--jc-font-size-sm); color: var(--jc-sem-text-secondary); text-align: center; }

/* ---------- the chapter card that opens each of the five units ----------- */

.s-chapter .s-centre { gap: var(--jc-space-12); }
.reveal .s h2.chapter-t {
  font-size: 68px; line-height: var(--jc-font-leading-tight);
  letter-spacing: var(--jc-font-tracking-heading); max-width: 18ch;
}
/* the same five verbs as slide 05, small, with this unit's one lit */
.verbs-sm { gap: var(--jc-space-3); }
.verbs-sm .verb { padding: var(--jc-space-4) var(--jc-space-2); gap: var(--jc-space-2); opacity: 0.4; }
.verbs-sm .verb-ic { width: 40px; height: 40px; border-radius: var(--jc-radius-md); }
.verbs-sm .verb-n { font-size: 16px; }
.verbs-sm .verb.on {
  opacity: 1;
  border-color: var(--jc-sem-border-focus);
  box-shadow: var(--jc-shadow-md);
}

/* ==========================================================================
   02-03 the glass. One 720x340 pane cut into five pieces by cracks from one
   impact point; each piece is a full-size box clipped to its polygon, so moving
   the box moves the piece, and the label sits at the polygon's centroid. Slide 02
   plays the break, slide 03 starts from the broken offsets and pulls every piece
   back onto the hub. Both slides reserve the same head height so the pane does
   not jump between them (the slide change itself is `none`).
   The base rule is the END state of each slide: print mode and reduced motion
   render it with no animation at all.
   ========================================================================== */

.s-glass .s-head { min-height: 100px; }
/* reveal's -in/-out transition names only steer the transform: the leaving slide still
   fades for 0.8s, which would show 02's title under 03's while the pieces move. Slide 03
   carries data-transition="none"; this makes 02 snap out the same way. */
.reveal .slides section.s-glass.past { transition: none; }
.s-glass .s-body { gap: 0; }
.glass { position: relative; flex: none; width: 720px; height: 340px; margin: 0 auto 64px; }
.shard {
  position: absolute; inset: 0;
  transform-origin: var(--cx) var(--cy);
  filter: drop-shadow(0 4px 6px rgb(20 23 42 / 0.10)) drop-shadow(0 12px 22px rgb(20 23 42 / 0.12));
}
.shard-face {
  position: absolute; inset: 0;
  background: linear-gradient(135deg, var(--jc-sem-bg-surface) 0%, var(--jc-sem-tint-aquaBg) 100%);
}
.shard-label {
  position: absolute; left: var(--cx); top: var(--cy); width: 200px; margin: -40px 0 0 -100px;
  display: flex; flex-direction: column; align-items: center; gap: 6px; text-align: center;
}
.shard-label .icon { color: var(--jc-sem-mark-a); }
.glass-lead { text-align: center; margin: 0 auto; }

/* 02: whole, then the cracks flash red and the pieces fly apart */
.glass-broken .shard { transform: translate(var(--sx), var(--sy)) rotate(var(--sr)); }
.cracks { position: absolute; inset: 0; opacity: 0; }
.cracks path { fill: none; stroke: var(--jc-color-signal-error); stroke-width: 2.5; stroke-linejoin: round; }
.present .glass-broken .shard { animation: shatter 900ms 800ms var(--jc-motion-easing-emphasized) both; }
.present .cracks { animation: crack 1100ms both; }
@keyframes shatter { from { transform: none; } }
@keyframes crack { 0% { opacity: 0.35; } 40% { opacity: 1; } 72% { opacity: 1; } 100% { opacity: 0; } }

/* 03: the same offsets, pulled back into place (with a touch of overshoot); the seams draw
   in aqua where the cracks were; the hub lands with a pulse; then the links, hub outward */
.glass-context .shard { transform: translate(var(--hx), var(--hy)); }
.present .glass-context .shard { animation: hold 1800ms 300ms cubic-bezier(0.55, 0, 0.15, 1.08) both; }
@keyframes hold { from { transform: translate(var(--sx), var(--sy)) rotate(var(--sr)); } }
.present .glass-context .s-head { animation: headIn 600ms 1800ms var(--jc-motion-easing-standard) both; }
@keyframes headIn { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: none; } }
.seams { position: absolute; inset: 0; z-index: 2; }
.seams path { fill: none; stroke: var(--jc-sem-mark-b); stroke-width: 2; stroke-linejoin: round; opacity: 0.85;
  stroke-dasharray: 1; stroke-dashoffset: 0; }
.present .seams path { animation: seamDraw 900ms 2000ms var(--jc-motion-easing-standard) both; }
@keyframes seamDraw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
.glass-hub { position: absolute; left: 322px; top: 126px; z-index: 3; }
.glass-hub .dg-hub { width: 100px; height: 100px; }
.present .glass-hub { animation: hubIn 700ms 2500ms var(--jc-motion-easing-emphasized) backwards; }
.glass-hub::after {
  content: ""; position: absolute; inset: -6px; border-radius: 50%;
  border: 2px solid var(--jc-sem-mark-b); opacity: 0; pointer-events: none;
}
.present .glass-hub::after { animation: pulseOut 1100ms 2900ms var(--jc-motion-easing-standard) both; }
@keyframes pulseOut { 0% { opacity: 0.9; transform: scale(0.85); } 100% { opacity: 0; transform: scale(1.7); } }
.glass-links { position: absolute; inset: 0; z-index: 2; }
.glass-links path { fill: none; stroke: var(--jc-sem-mark-b); stroke-width: 2.5; stroke-linecap: round; opacity: 1; }
.glass .spoke { z-index: 3; }
.present .glass-links path { animation: flow 1.1s linear infinite, linkIn 300ms calc(3100ms + var(--d-i) * 140ms) both; }
.present .glass .spoke { opacity: 1; animation: spokeIn 500ms calc(2300ms + var(--d-i) * 140ms) var(--jc-motion-easing-emphasized) both; }
@keyframes linkIn { from { opacity: 0; } to { opacity: 1; } }

/* two recordings side by side on one chapter card, a running clock on each */
.pair { display: flex; gap: var(--jc-space-6); justify-content: center; align-items: flex-start; }
.pair-item { display: flex; flex-direction: column; gap: var(--jc-space-2); flex: none; }
.pair-label { display: flex; align-items: center; gap: 8px; font-family: var(--jc-font-family-brand); font-weight: var(--jc-font-weight-bold); font-size: 18px; color: var(--jc-sem-text-primary); }
.pair-label .icon { color: var(--jc-sem-tint-blendFg); }
.vidframe-pair { width: 556px; height: 313px; }
.vid-clock {
  position: absolute; right: 12px; top: 10px; z-index: 2; padding: 3px 10px; border-radius: var(--jc-radius-md);
  font-family: var(--jc-font-family-mono); font-size: 18px; font-weight: var(--jc-font-weight-medium); font-variant-numeric: tabular-nums;
  color: #fff; background: rgba(15, 18, 40, 0.82);
}
.vid-clock::before { content: ""; display: inline-block; width: 8px; height: 8px; margin: 0 7px 1px 0; border-radius: 50%; background: #e5484d; }
.vid-clock.done::before { background: var(--jc-sem-mark-b); }

/* the chapter card that also carries the proof: a smaller promise, the recording under it */
.reveal .s h2.chapter-t.chapter-proof { font-size: 52px; max-width: none; }
.vidframe-chapter { max-width: 760px; height: 428px; }

/* why NGSI-LD: four sentences on top of each other, the user's emoji in front (Twemoji SVGs, so the PDF has them too) */
.lines { display: flex; flex-direction: column; gap: var(--jc-space-4); }
.line { display: flex; align-items: flex-start; gap: var(--jc-space-4); font-size: 24px; line-height: 1.4; color: var(--jc-sem-text-secondary); max-width: none; }
.line b { color: var(--jc-sem-text-primary); font-weight: var(--jc-font-weight-bold); }
.line .emo { flex: none; width: 34px; height: 34px; margin-top: 1px; }
.line .icon { flex: none; color: var(--jc-color-signal-warning); margin-top: 4px; }
.present .line { animation: riseIn 500ms calc(200ms + var(--d-i) * 130ms) var(--jc-motion-easing-emphasized) both; }
.s-body.spag-body { flex-direction: row; align-items: center; gap: var(--jc-space-8); }
.spag-body .lines { flex: 1; }
.spag-photo { flex: none; width: 480px; height: auto; }

/* the mesh: six applications, hand-made arrows between them or one broker in the middle */
.reveal .s .s-head-1 h2 { font-size: 40px; max-width: none; }
.stage.mesh { width: 1100px; height: 500px; margin: 0 auto; }
.mesh-links { position: absolute; inset: 0; width: 100%; height: 100%; }
.mesh-links path { fill: none; stroke: var(--k, var(--jc-color-signal-warning)); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.present .mesh-links g { animation: linkIn 300ms calc(200ms + var(--d-i, 0) * 90ms) both; }
.mesh-node { position: absolute; width: 180px; height: 64px; min-height: 0; padding: 6px 10px; gap: 4px; z-index: 2; }
.mesh-node .dg-l { font-size: 17px; white-space: nowrap; }
.mesh-pill {
  position: absolute; z-index: 3; transform: translate(-50%, -50%) rotate(var(--rot, 0deg));
  padding: 3px 12px; border-radius: var(--jc-radius-full); white-space: nowrap;
  font-family: var(--jc-font-family-brand); font-weight: var(--jc-font-weight-bold); font-size: 16px;
  color: var(--k); background: var(--jc-sem-bg-surface); border: 1.5px solid var(--k); box-shadow: var(--jc-shadow-sm);
}
.present .mesh-pill { animation: pillIn 300ms calc(300ms + var(--d-i, 0) * 90ms) both; }
@keyframes pillIn { from { opacity: 0; } }
.mesh-hub {
  position: absolute; left: 550px; top: 250px; transform: translate(-50%, -50%); z-index: 3;
  width: 176px; height: 176px; border-radius: 50%; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  background: var(--jc-sem-mark-a); border: 3px solid var(--jc-sem-mark-b); box-shadow: var(--jc-shadow-lg); color: #fff; text-align: center;
}
.mesh-hub .icon { color: var(--jc-sem-mark-b); }
.hub-t { font-family: var(--jc-font-family-brand); font-weight: var(--jc-font-weight-bold); font-size: 19px; line-height: 1.1; text-transform: uppercase; letter-spacing: 0.02em; }
.hub-s { font-family: var(--jc-font-family-brand); font-weight: var(--jc-font-weight-medium); font-size: 16px; color: #fff; opacity: 0.92; line-height: 1.15; margin-top: 2px; }
.present .mesh-hub { animation: hubIn 700ms 200ms var(--jc-motion-easing-emphasized) backwards; }
.broker-links path { stroke: var(--jc-sem-mark-b); stroke-width: 3; }
.present .broker-links g { animation: linkIn 300ms calc(700ms + var(--d-i) * 140ms) both; }
.spoke-pill { --k: var(--jc-sem-mark-b); color: var(--jc-sem-text-accent); }
.present .spoke-pill { animation: pillIn 300ms calc(800ms + var(--d-i) * 140ms) both; }

.stage.mesh.orgs { width: 760px; height: 340px; }
/* the click on the broker slide: joinedcontext is the layer around the broker and the standard */
.jc-layer {
  position: absolute; left: 550px; top: 250px; width: 240px; height: 240px; margin: -120px 0 0 -120px; z-index: 2;
  border-radius: 50%; border: 3px solid var(--jc-sem-mark-a); background: color-mix(in srgb, var(--jc-sem-mark-b) 10%, transparent);
  box-shadow: 0 0 0 10px color-mix(in srgb, var(--jc-sem-mark-b) 14%, transparent);
}
.jc-layer-tag {
  position: absolute; left: 100%; top: 50%; transform: translate(-22px, -50%);
  display: inline-flex; align-items: center; gap: 8px; padding: 6px 14px 6px 10px; border-radius: var(--jc-radius-full);
  background: var(--jc-sem-bg-surface); border: 2px solid var(--jc-sem-mark-a); box-shadow: var(--jc-shadow-md);
  font-family: var(--jc-font-family-brand); font-weight: var(--jc-font-weight-bold); font-size: 18px; color: var(--jc-sem-text-brand); white-space: nowrap;
}
.jc-layer-tag svg { width: 26px; height: 26px; }
.reveal .jc-layer.fragment { opacity: 0; transform: scale(0.5); transition: opacity 500ms var(--jc-motion-easing-emphasized), transform 500ms var(--jc-motion-easing-emphasized); }
.reveal .jc-layer.fragment.visible { opacity: 1; transform: scale(1); }

/* every employee and every department its own context space: departments fade in, people rise,
   their spaces pop and draw their links, then the KPI spaces and the links across departments */
.space-dept {
  position: absolute; top: 8px; width: 350px; height: 414px; border-radius: var(--jc-radius-lg);
  background: var(--jc-sem-bg-surface); border: var(--d-panel-border); box-shadow: var(--jc-shadow-sm);
  display: flex; align-items: flex-start; justify-content: center; gap: 8px; padding-top: 12px;
  font-family: var(--jc-font-family-brand); font-weight: var(--jc-font-weight-bold); font-size: 18px; color: var(--jc-sem-text-primary);
}
.space-dept .icon { color: var(--jc-sem-mark-a); }
.present .space-dept { animation: pillIn 350ms calc(var(--d-i) * 100ms) both; }
.space-emp {
  position: absolute; width: 100px; height: 56px; z-index: 2; display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 0 4px; padding: 0 4px;
  background: var(--jc-sem-bg-surface); border: 2px solid var(--jc-sem-border-strong); border-radius: var(--jc-radius-md);
  font-family: var(--jc-font-family-brand); font-weight: var(--jc-font-weight-medium); font-size: 16px; color: var(--jc-sem-text-primary);
}
.space-emp .icon { color: var(--jc-sem-tint-blendFg); }
.space-emp .icon + .icon { color: var(--jc-sem-mark-b); }
.space-emp p { flex-basis: 100%; text-align: center; line-height: 1.1; }
.present .space-emp { animation: riseIn 350ms calc(250ms + var(--d-i) * 50ms) var(--jc-motion-easing-emphasized) both; }
.space-bubble {
  position: absolute; width: 92px; height: 92px; border-radius: 50%; z-index: 2;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px; padding: 4px; text-align: center;
  background: var(--jc-sem-tint-aquaBg); border: 2px solid var(--jc-sem-mark-b); box-shadow: var(--jc-shadow-md);
  font-family: var(--jc-font-family-mono); font-size: 16px; line-height: 1.15; color: var(--jc-sem-tint-aquaFg);
}
.space-bubble .icon { color: var(--jc-sem-mark-b); }
.present .space-bubble { animation: hubIn 400ms calc(700ms + var(--d-i) * 50ms) var(--jc-motion-easing-emphasized) backwards; }
.space-kpi { width: 104px; height: 104px; background: var(--jc-sem-tint-navyBg); border-color: var(--jc-sem-mark-a); color: var(--jc-sem-tint-navyFg); }
.space-kpi .icon { color: var(--jc-sem-mark-a); }
.present .space-kpi { animation: hubIn 400ms calc(1600ms + var(--d-i) * 100ms) var(--jc-motion-easing-emphasized) backwards; }
.space-links path { stroke: var(--jc-sem-mark-b); stroke-width: 2; stroke-dasharray: 5 7; }
.space-links .space-own { stroke: var(--jc-sem-border-strong); stroke-dasharray: none; stroke-width: 2.5; }
.present .space-links .space-own { animation: linkIn 300ms calc(600ms + var(--d-i) * 50ms) both; }
.present .space-links path:not(.space-own) { animation: linkIn 300ms calc(1200ms + var(--d-i) * 60ms) both, flow 1.4s linear infinite; }
.space-links .space-feed { stroke: var(--jc-sem-mark-a); stroke-width: 1.8; }
.present .space-links .space-feed { animation: linkIn 300ms calc(1500ms + var(--d-i) * 100ms) both, flow 1.4s linear infinite; }
.space-links .space-cross { stroke: var(--jc-sem-mark-a); stroke-width: 2.5; }
.present .space-links .space-cross { animation: linkIn 300ms calc(1900ms + var(--d-i) * 120ms) both, flow 1.4s linear infinite; }
.stage.mesh.space { height: 430px; }
.space-lead { text-align: center; margin: 0 auto; }
.no-excel { position: absolute; right: -14px; top: -26px; width: 84px; height: 84px; z-index: 4; }
.no-excel .xl { position: absolute; left: 50%; top: 50%; width: 62px; height: 62px; transform: translate(-50%, -50%); filter: drop-shadow(var(--jc-shadow-sm)); }
.no-excel .cross { position: absolute; inset: 0; width: 100%; height: 100%; fill: none; stroke: #d0312d; stroke-width: 8; stroke-linecap: round; }
.present .no-excel { animation: crossIn 400ms 2300ms var(--jc-motion-easing-emphasized) both; }
@keyframes crossIn { from { opacity: 0; transform: scale(1.8) rotate(-12deg); } to { opacity: 1; transform: none; } }

/* the organisations: three rings on the same stage, an NGSI-LD link on every side */
.org-ring { position: absolute; transform: translate(-50%, -50%); flex-direction: row; gap: var(--jc-space-3); padding: var(--jc-space-3); background: var(--jc-sem-bg-page); z-index: 2; }
.org-ring .dg-node.org { width: 118px; min-height: 0; padding: var(--jc-space-2); }
.org-chips { gap: var(--jc-space-2); }
.org-chips .dg-chip { white-space: nowrap; }
