/* ===== BUILT IN THE OPEN: kinetic names =====
   Three rows read like an index: the name and its gesture on the left, the facts on the right, one hairline
   between rows, the same columns in every row. Each gesture is scrubbed by the row's own scroll position
   (--rv from reveal.js; Pulse from open-names.js). Calm, static and no-JS show the final state. */
.kn{padding:var(--s7) 0 var(--s6);border-top:1px solid var(--line);overflow-x:clip}
.kn-head{display:flex;justify-content:space-between;align-items:baseline;gap:20px;flex-wrap:wrap;margin-bottom:var(--s4)}
.kn-head .eyebrow{margin-bottom:0}
.kn-note{color:var(--mute)}

.kn-row{border-top:1px solid var(--line);padding:clamp(40px,4vw,56px) 0}
.kn-row:last-child{border-bottom:1px solid var(--line)}
.kn-grid{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));column-gap:clamp(16px,2vw,32px);align-items:start}
.kn-l{grid-column:1/4;min-width:0;position:relative}
.kn-r{grid-column:4/7;min-width:0;display:flex;flex-direction:column;align-items:flex-start;gap:var(--s2);padding-top:calc(var(--fs-label) * 1.5 + clamp(14px,1.6vw,24px))}

.kn-idx{color:var(--mute);margin:0 0 clamp(14px,1.6vw,24px)}
/* every name is set at one size (fitted by open-names.js to the longest, so the column reads as an index) */
.kn-name{font-size:var(--fd-l);line-height:.8;position:relative;display:inline-block;letter-spacing:var(--ls-d);white-space:nowrap;padding-top:.04em;margin:0}
.kn-blue{color:var(--blue)}
.kn-base{position:relative;height:2px;margin-top:clamp(8px,1vw,14px);clip-path:inset(-40px 0)} /* the heartbeat stays inside the rule's width */
.kn-rule{position:absolute;inset:0;background:var(--paper);transform-origin:left}

.kn-idea{font-size:var(--fs-2xl);line-height:1.15;letter-spacing:var(--ls-lead);font-weight:var(--tw-m);max-width:22ch;margin:0}
.kn-desc{font-size:var(--fs-body);color:var(--text-2);max-width:48ch;margin:0}
.kn-lens{color:var(--text-2);margin:0;max-width:56ch;line-height:1.7;text-transform:none;letter-spacing:var(--ls-data)}
.kn-stack{color:var(--mute);margin:0;letter-spacing:var(--ls-data);text-transform:none}
.kn-link{margin-top:var(--s1);display:inline-flex;align-items:center;gap:10px;padding:12px 18px;border:1px solid var(--paper);color:var(--paper);text-decoration:none}

/* scrubbed entry, shared by all three rows: the rule draws, the name rises out of its own line */
.kn-row.rv-a .kn-rule{transform:scaleX(clamp(0,calc(var(--rv) * 1.4 - .1),1))}
.kn-row.rv-a .kn-name{--q:clamp(0,calc(var(--rv) * 1.35),1);opacity:var(--q);transform:translateY(calc((1 - var(--q)) * 24px));clip-path:inset(-10% -2% calc((1 - var(--q)) * 100%) -2%)}
.kn-row.rv-a .kn-r{opacity:clamp(0,calc(var(--rv) * 1.6 - .3),1);transform:translateY(calc((1 - clamp(0,calc(var(--rv) * 1.6 - .3),1)) * 10px))}

/* AI Playbook: old ideas hang from the baseline on threads of different lengths */
.kn-hang{list-style:none;margin:0;padding:0;display:flex;flex-wrap:nowrap;column-gap:clamp(6px,2vw,28px);color:var(--text-2);text-transform:none;letter-spacing:var(--ls-data)}
.kn-hang li{position:relative;padding-top:var(--d);transform-origin:50% 0;min-width:0;flex:0 1 auto}
.kn-hang li::before{content:"";position:absolute;left:0;top:0;width:1px;height:calc(var(--d) - 4px);background:var(--dim);transform-origin:top}
.kn-row.rv-a .kn-hang li{--k:clamp(0,calc((var(--rv) - .25 - var(--i) * .07) / .4),1);opacity:var(--k);transform:translateY(calc((var(--k) - 1) * var(--d))) rotate(calc((1 - var(--k)) * 4deg))}
.kn-row.rv-a .kn-hang li::before{transform:scaleY(var(--k))}

/* TSight: lids part from one line, late in the same scroll */
.kn-eye{overflow:hidden;padding:0 .02em}
.kn-lid{position:absolute;left:0;right:0;height:51%;background:var(--ink);z-index:1;will-change:transform}
.kn-lid-t{top:0;border-bottom:2px solid var(--paper);transform:translateY(calc(var(--open,1) * -101%))}
.kn-lid-b{bottom:0;border-top:2px solid var(--paper);transform:translateY(calc(var(--open,1) * 101%))}
.kn-row[data-kn="ts"].rv-a .kn-lid{--open:clamp(0,calc((var(--rv) - .4) / .5),1)}

/* Pulse: one blip runs along the rule; each letter's colour is written from the blip's position */
.pu-l{display:inline-block}
.kn-blip{position:absolute;left:0;top:-22px;width:128px;height:46px;transform:translateX(calc(var(--bx,-80) * 1px));opacity:0}
.kn-blip rect{fill:var(--ink)}
.kn-blip path{fill:none;stroke:var(--blue);stroke-width:3;vector-effect:non-scaling-stroke;stroke-linejoin:round;stroke-linecap:round}
.kn-row.beating .kn-blip{opacity:1}

/* phones and narrow tablets: name and gesture first, then the facts */
@media (width < 900px){
  .kn-row{padding:var(--s4) 0 var(--s5)}
  .kn-l,.kn-r{grid-column:1/-1}
  .kn-r{padding-top:var(--s4)}
  .kn-blip{width:80px;height:30px;top:-14px}
  .kn-hang{font-size:var(--fs-micro);justify-content:space-between}
}
