/* ============================================================
   landing-connect.css, OPTION 2's SECOND FOLD: "Connect Spark to your live
   business data".

   Copy on the left, one large panel on the right. The panel is split: the old
   way, static and unlit, against Spark, running.

   THE SECTION IS THE SAME GROUND AS THE FOLD ABOVE IT. #141519 flat, edge to
   edge, with no seam and no second gradient, so scrolling out of the hero into
   this one does not read as arriving somewhere else. The only
   thing on the page with colour and light is the panel, and inside the panel
   the only thing with light is Spark's half of it. That is the whole visual
   argument of the fold.

   NOTHING IN HERE RESTYLES A PRODUCT CLASS. The rules marked LOCAL FIT adapt a
   component to a context it was never built for (an entity card outside the
   schema canvas, a composer outside its dock) and change geometry only, never
   colour, type or spacing inside the component.
   ============================================================ */

/* Same visibility gate as the rest of Option 2. */
.lp-connect{display:none}
/* OPAQUE, like .lp-showcase, and for the same reason: .lp-flow and .lp-bg are
   both position:fixed and keep painting behind every section as you scroll, so
   only a flat ground laid over them actually removes the animation here. */
html[data-lp-option="2"] .lp-connect{display:flex;position:relative;z-index:1;
  min-height:100dvh;align-items:center;
  padding-block:clamp(56px,8vh,104px);
  background:#141519}
html[data-lp-option="2"] .lp-connect > .lp-wrap{flex:1}

/* ---- the two halves of the fold ------------------------------------------
   The panel is the subject, so it takes the larger share and a fixed measure;
   the copy takes what is left. Same reasoning as fold 2, one size up, because
   here the right side is a diagram that has to be READ rather than a card that
   has to be glanced at. */
.lp-connect__in{display:grid;align-items:center;
  grid-template-columns:minmax(0,1fr) clamp(520px,54%,760px);
  column-gap:clamp(40px,5vw,88px)}

.lp-connect__copy{display:flex;flex-direction:column;align-items:flex-start;
  gap:clamp(16px,1.8vh,24px);max-width:450px}
/* ONE TYPE SYSTEM ACROSS THE WHOLE OPTION (Ameer: "use Option 6 as the
   typography reference"). The section heading is the same size, weight, leading
   and tracking as .lp-film3__h: 500, eased tracking, 1.06 leading, one step
   below the page's H1. The emphasis carries the only weight change in the
   whole ramp, at 600, which is what makes it read as emphasis without a second
   size or a second colour beyond the brand step. */
.lp-connect__h{font-size:clamp(33px,3.5vw,54px);line-height:1.06;font-weight:500;
  letter-spacing:-.028em;color:#fff;text-wrap:balance}
.lp-connect__h em{font-style:normal;font-weight:600;color:var(--accent)}
.lp-connect__sub{font-size:clamp(15px,1.15vw,17.5px);line-height:1.62;font-weight:400;
  color:rgba(255,255,255,.7);max-width:46ch}
.lp-connect__cta{margin-top:6px}

@keyframes lpcRise{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
.lp-connect__copy{animation:lpcRise .7s var(--ease) both}
.lp-connect__stage{animation:lpcRise .7s var(--ease) both;animation-delay:.12s}

/* ============================================================
   THE PANEL
   ============================================================
   One card, two columns and a hairline. Its height is a share of the VIEWPORT
   rather than a pixel figure, so it is contained on a laptop instead of running
   past the fold, and everything inside is built to that budget. */
/* MIN-height, NOT height. This was a fixed clamp, and on a window around 800px
   tall it resolved BELOW what the panel actually contains: the stage got
   squeezed under the answer card's own height, and the card, being anchored to
   the bottom of the stage, ran up over the source row. A box may be a share of
   the viewport, but it may never be smaller than the thing inside it, so the
   viewport share is now the FLOOR and the content sets the rest. */
.lpc-panel{position:relative;overflow:hidden;
  min-height:clamp(468px,64dvh,580px);
  display:grid;grid-template-columns:minmax(0,.78fr) 1px minmax(0,1fr);
  border-radius:26px;
  background:var(--card);border:1px solid var(--card-stroke);
  box-shadow:var(--shadow-2xl)}

/* THE KEY LIGHT, and it is a LIGHT WITH A POSITION rather than a wash behind a
   column. js/landing-connect.js moves it from beat to beat (see the KEY table
   there): up at the source while it connects, out over the schema, down at the
   composer on the moment of send, back over the answer as it builds. Blended as
   light rather than painted as a fill, and it is also the reason the contrast
   reads as lit against unlit rather than as two columns of equal weight.

   Fixed size and centred on the Spark column, so the transform js writes is
   read as "put the light here, this big". No transition: its position is a
   continuous function of the clock, not a state being animated between. */
.lpc-key{position:absolute;z-index:0;pointer-events:none;opacity:0;
  left:72%;top:0;width:520px;height:520px;margin-top:-260px;
  will-change:transform,opacity;
  background:radial-gradient(closest-side, var(--glow), transparent 70%)}

.lpc-div{background:var(--border-subtle)}
.lpc-col{position:relative;z-index:1;min-width:0;display:flex;flex-direction:column;
  padding:clamp(22px,2vw,30px) clamp(20px,1.9vw,28px)}

/* the column heads: the smallest voice on the page, and the only thing in the
   fold set in the mono face, because they are labels for two states rather than
   copy. Spark's takes the accent; the old way's takes the faintest ink there
   is, which is most of the argument made in one property. */
.lpc-lbl{font-family:var(--font-mono);font-size:10.5px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--text-faint);flex:none}
.lpc-lbl--spark{color:var(--accent)}

/* ---- THE OLD WAY: six handoffs, and no motion at all ---------------------
   Spaced by flex rather than by a fixed gap so the column always fills the
   panel's height, whatever the panel's height turns out to be. */
.lpc-col--old{justify-content:space-between}
.lpc-steps{flex:1;display:flex;flex-direction:column;justify-content:space-between;
  padding-block:clamp(14px,2.4vh,28px)}
.lpc-step{display:flex;align-items:center;gap:12px;flex:none}
/* neutral, never brand: nothing on this side of the panel is a Spark action. */
.lpc-step__ic{flex:none;display:grid;place-items:center;width:32px;height:32px;
  border-radius:10px;background:rgba(255,255,255,.035);
  border:1px solid var(--border-subtle);color:var(--text-faint)}
.lpc-step__ic svg{width:17px;height:17px}
.lpc-step__t{font-size:13.5px;line-height:1.35;color:var(--sub);min-width:0}
/* the handoff between two steps: a dashed hairline, drawn in the column's own
   quietest stroke. It is the WAITING between the steps, which is what the old
   way actually costs. */
/* it FLEXES: the six steps are pinned to the top and bottom of the column and
   the waiting between them takes up whatever height is left, which is the one
   honest way to draw a process whose real cost is the gaps in it. */
.lpc-link{flex:1;min-height:13px;width:1px;margin-inline-start:16px;
  background:repeating-linear-gradient(180deg,
    var(--border-strong) 0 3px, transparent 3px 6px)}
.lpc-foot{flex:none;font-size:12.5px;color:var(--text-faint)}
.lpc-foot--old{padding-top:2px}

/* ---- WITH SPARK: the product, running ------------------------------------
   Three bands that never change height: the source that is connected, the
   thread, and the composer. The middle one is the only thing that changes, and
   it changes by cross dissolve, which is why nothing in the panel ever jumps. */
.lpc-col--spark{gap:clamp(15px,1.9vh,22px)}
.lpc-src-w{flex:none}
.lpc-dock{flex:none;margin-top:auto}

/* LOCAL FIT: .ds-row is a full width row in the Data sources list. Here it is
   one object at the top of a panel, so it takes a smaller mono tile and the
   compact end of its own type. It also ARRIVES, which a row in a list does not. */
.lpc-src{padding:11px 13px;gap:11px;cursor:default;
  opacity:0;transform:translateY(-8px);
  transition:opacity .6s var(--ease),transform .6s var(--ease),
             border-color .5s var(--ease),background .5s var(--ease)}
.lpc-src.is-in{opacity:1;transform:none}
.lpc-src .ds-card__mono{width:28px;height:28px}
.lpc-src .ds-row__nm{font-size:13.5px}
.lpc-src .ds-row__meta{font-size:11.5px}
.lpc-src .ds-row__body{gap:4px}
.lpc-src__tag{height:22px;padding:0 8px;font-size:11px}
/* the dot before it comes online: the app's own status dot with no state class
   on it yet, so it takes the neutral it already has. */
.lpc-src .status-dot{transition:background .45s var(--ease)}
/* WHEN THE ANSWER CREDITS IT. The neutral glass pair, never a brand tint: the
   standing rule is that every emphasis state is #fff at 5% over #fff at 8%. */
.lpc-src.is-cited{background:var(--glass);border-color:var(--glass-2)}

/* THE STAGE IS A DEPTH STAGE. It carries the perspective every beat is placed
   in; js/landing-connect.js writes each beat's translate3d/rotateX/scale on
   every frame, and also drifts perspective-origin, so the beats are staged in a
   space that is being LOOKED AT rather than stacked flat with a scale on them.

   Fixed height, and every beat absolutely positioned in it, so they move
   through the same space instead of one replacing another and pushing
   everything below. Bottom anchored: a beat shorter than the stage sits ON the
   composer, the way a thread does, rather than floating in an empty box.

   NOTHING HERE HAS A TRANSITION. The beats' opacity, blur and transform are
   continuous functions of the clock, not states being eased between, which is
   what lets one beat's exit be authored against the next one's entrance. */
/* THE FLOOR IS THE TALLEST BEAT. The answer card is a fixed composition, so its
   height is knowable; the stage is never allowed below it, which is what stops
   a beat overflowing the space it is anchored in. Above that floor the stage
   takes whatever the panel has spare. */
.lpc-stage{position:relative;flex:1;min-height:292px;
  perspective:1150px;perspective-origin:50% 47%}
.lpc-beat{position:absolute;inset-inline:0;bottom:0;
  opacity:0;visibility:hidden;
  transform-origin:50% 78%;
  will-change:transform,opacity,filter;backface-visibility:hidden}
/* the depth the cards move in WITHIN the schema beat is scale and offset, not
   translateZ: the beat carries a blur, and a filter flattens whatever 3D its
   own descendants are in. The beat's own translateZ is unaffected, because
   that is resolved by the stage above it. */
.lpc-card{will-change:transform,opacity}

/* ---- the schema beat: two tables and the key between them ----------------
   LOCAL FIT: .er-card is absolutely placed inside the schema canvas and sized
   in px by ER_GEO. The same numbers, restated, because here the card is placed
   by this panel instead. CARD_W / HD_H / ROW_H in js/landing-connect.js must
   match the three figures below, or the join line will not meet its rows. */
.lpc-er{position:relative;display:flex;gap:34px;justify-content:center;
  transform-style:flat}
.lpc-card{position:relative;width:158px;flex:none}
.lpc-card .er-card__hd{height:46px}
.lpc-card .er-card__row{height:25px}
.lpc-card .er-card__nm{font-size:12.5px}
.lpc-card .er-card__sub{font-size:10px;line-height:13px}
.lpc-card .er-card__cn{font-size:11px}
/* the keys light only once Spark has MATCHED them. The tint and the badge are
   the product's own; this holds them back until the beat calls for them, so the
   moment of recognition is something you can actually see happen. */
.lpc-card .er-card__row.is-pk,
.lpc-card .er-card__row.is-fk{background:transparent;transition:background .6s var(--ease)}
.lpc-er.is-keyed .er-card__row.is-pk{background:var(--glass)}
.lpc-er.is-keyed .er-card__row.is-fk.is-reference{background:var(--success-soft);
  transition-delay:.26s}
.lpc-card .key{opacity:0;transform:scale(.72);
  transition:opacity .45s var(--ease),transform .45s cubic-bezier(.34,1.56,.64,1)}
.lpc-er.is-keyed .key{opacity:1;transform:none}
/* PK FIRST, THEN FK: Spark finds the identifier, then finds what points at it.
   The quarter second between them is the recognition, and it is the difference
   between two badges appearing and a relationship being worked out. */
.lpc-er.is-keyed .key--fk{transition-delay:.26s}
/* THE JOIN, drawn. .er-edges gives it the graph's own stroke and the class
   colour of the table it points at; the dash offset is what makes it travel
   from one card to the other instead of appearing between them. */
.lpc-join{position:absolute;z-index:2;inset-block-start:0;inset-inline-start:50%;
  transform:translateX(-50%);overflow:visible;pointer-events:none}
[dir="rtl"] .lpc-join{transform:translateX(50%) scaleX(-1)}
.lpc-join path{stroke-dasharray:1;stroke-dashoffset:1;
  transition:stroke-dashoffset .85s var(--ease)}
.lpc-join.is-drawn path{stroke-dashoffset:0}
.lpc-join circle{opacity:0;transition:opacity .4s var(--ease) .5s}
.lpc-join.is-drawn circle{opacity:1}

/* ---- the meaning beat ----------------------------------------------------
   LOCAL FIT: .sem-term sits in a three up grid on the Semantic Intelligence
   tab and has no width of its own. Alone in a column, it needs one, and it gets
   the column's. */
.lpc-term{width:100%;padding:15px 17px}
.lpc-term .sem-term__m{font-size:12px;line-height:18px}

/* ---- the investigating beat ---------------------------------------------
   LOCAL FIT: .ll opens with a 16px top margin under a question header it does
   not have here, and the app's step rhythm is built for a 960px thread. */
.lpc-ll{margin-top:0;gap:14px}
.lpc-ll .ll-hd-t{font-size:12.5px}
.lpc-ll .ll-time{font-size:11.5px}
.lpc-ll .ll-steps{gap:11px}
.lpc-ll .ll-t{font-size:12.5px}
.lpc-ll .ll-sub{font-size:11px}
/* both marks are in every row and the step's state picks which one shows, so a
   step turning from running to done never rewrites the DOM mid shot */
.lpc-ll .ll-step--running .ll-mark svg{display:none}
.lpc-ll .ll-step--done .ll-mark .ll-dot{display:none}
/* a step that has not started yet is present but unlit AND held back a few
   pixels: the loader is a list of what Spark WILL do, and each line settles
   into place as its turn comes rather than switching on where it stood. That
   is what makes the ticking read as work happening. */
.lpc-ll .ll-step{transition:opacity .45s var(--ease),transform .55s var(--ease)}
.lpc-ll .ll-step.is-waiting{opacity:.38;transform:translateY(5px)}

/* ---- the answer beat -----------------------------------------------------
   LOCAL FIT: .ans opens at 40px/42px padding and a 34px headline against a
   960px thread. Geometry only: the card's fill, hairline, rhythm and glow are
   untouched. */
.lpc-ans{padding:17px 19px 18px}
.lpc-ans::after{border-radius:18px}
.lpc-ans .aqh{font-size:12.5px}
.lpc-ans .aqh .q{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lpc-ans .aqh svg{width:14px;height:14px}
.lpc-ans .ans__h{font-size:19px;line-height:25px;min-height:25px}
.lpc-ans .ans__s{font-size:12.5px;line-height:1.5}
.lpc-ans .ans__meta{gap:8px}
.lpc-ans .mchip{font-size:11px}
/* the caret while the headline writes itself */
.lpc-ans.is-writing .ans__h::after{content:"";display:inline-block;width:2px;height:.84em;
  margin-inline-start:3px;vertical-align:-2px;background:var(--accent)}
/* the summary and the chips arrive after the headline has finished, in that
   order, which is the order the app builds a finished turn in, and each one
   RISES the last few pixels instead of fading in on the spot. */
.lpc-ans .ans__s,.lpc-ans .ans__meta{opacity:0;transform:translateY(7px);
  transition:opacity .55s var(--ease),transform .6s var(--ease)}
.lpc-ans.is-built .ans__s{opacity:1;transform:none}
.lpc-ans.is-built .ans__meta{opacity:1;transform:none;transition-delay:.16s}
/* WHERE THE ANSWER CAME FROM. The one chip that closes the loop back to the row
   at the top of the panel, so it is the one chip that lights. Neutral glass,
   per the state rule, never a brand tint. */
.lpc-mchip--src{transition:background .5s var(--ease),color .5s var(--ease)}
.lpc-mchip--src.is-lit{background:var(--glass-2);color:var(--ink)}

/* ---- the composer: the product's own, trimmed --------------------------- */
.lpc-composer{padding:11px 13px;border-radius:16px;gap:9px}
.lpc-composer textarea{font-size:12.5px;line-height:18px;min-height:18px;cursor:default}
.lpc-composer .cchip{height:28px;padding:0 9px;font-size:11.5px}
.lpc-composer .cchip .chev{width:12px;height:12px}
.lpc-composer .send{width:30px;height:30px}
.lpc-composer .send svg{width:16px;height:16px}
/* ACTIVE, NOT BRANDED: the standing rule that a hover or active state is the
   neutral glass pair. The Send button is the exception the product already
   makes, because there it is the one action. */
.lpc-composer.is-typing{border-color:var(--glass-2)}
.lpc-composer .send{transition:transform .2s var(--ease),background .2s var(--ease)}
.lpc-composer .send:not(:disabled){background:var(--accent);border-color:var(--accent);color:var(--on-accent)}
.lpc-composer.is-firing .send{transform:scale(.86)}
/* THE SEND, ONCE. A single ring leaving the button at the moment the question
   goes: the one flourish in the panel, and it is on the one control that is an
   action. It rides on the button's own accent, so it introduces no colour. */
.lpc-composer .send{position:relative}
.lpc-composer .send::after{content:"";position:absolute;inset:-1px;border-radius:50%;
  border:1.5px solid var(--accent);opacity:0;pointer-events:none}
.lpc-composer.is-firing .send::after{animation:lpcSend .58s var(--ease) forwards}
@keyframes lpcSend{
  0%{opacity:.85;transform:scale(1)}
  100%{opacity:0;transform:scale(2.5)}}

/* ---- narrower windows ----------------------------------------------------
   Below this the copy and the panel cannot both hold their width. The fold
   stacks, and the panel stops being a share of the viewport, because a one
   screen panel makes no sense once the content above it is vertical. */
@media (max-width:1180px){
  html[data-lp-option="2"] .lp-connect{min-height:0;display:block;
    padding-block:clamp(60px,9vh,110px)}
  .lp-connect__in{grid-template-columns:1fr;row-gap:clamp(32px,4vh,48px)}
  .lp-connect__copy{max-width:none}
  .lpc-panel{height:min(560px,84vh)}
}
/* AND BELOW A TABLET THE PANEL'S OWN TWO COLUMNS BECOME ONE. Side by side
   neither half has the width to be read: the old way's steps wrap onto two
   lines each and the entity cards lose the gap the join line needs. Stacked,
   the contrast is still made, it is just made in sequence. */
@media (max-width:760px){
  .lpc-panel{height:auto;grid-template-columns:1fr;grid-template-rows:auto 1px auto}
  .lpc-key{inset:auto 0 0 0;width:auto;height:62%}
  .lpc-col--spark{gap:14px}
  /* the floor is the TALLEST beat, so the composer under it holds still while
     the beats swap, the same job the fixed stage does at full width */
  .lpc-stage{min-height:196px}
  .lpc-beat{position:relative;bottom:auto}
  /* stacked, only the beat being played takes room, so the panel does not hold
     four beats' worth of empty height */
  .lpc-beat:not(.is-in){position:absolute;bottom:0}
  .lpc-steps{padding-block:16px;gap:0}
}
@media (max-width:520px){
  .lpc-er{gap:22px}
  .lpc-card{width:132px}
  .lp-connect__h{font-size:clamp(28px,8vw,36px)}
}
@media (prefers-reduced-motion:reduce){
  .lp-connect__copy,.lp-connect__stage{animation:none}
  .lpc-src,.lpc-join path,.lpc-join circle,
  .lpc-card .key,.lpc-card .er-card__row,.lpc-ll .ll-step,
  .lpc-ans .ans__s,.lpc-ans .ans__meta,.lpc-mchip--src{transition:none}
  .lpc-composer.is-firing .send::after{animation:none}
  .lpc-ans.is-writing .ans__h::after{display:none}
  /* the beats are positioned by js, which holds the final frame still under
     this query rather than easing to it: see sync() in landing-connect.js */
}
