/* fx-imp.css: Impressions surface motion (Create, Campaigns, Creator Videos, Analytics, SDK). Owner: B. Loads after fx.css; override base rules on specificity (#impressions ...), never !important. */

/* ========================================================================
   What lives where. fx.css owns the primitives (tokens, keyframes, the
   skeleton blocks, .fx-chip, tabs, tilt, sheen). This file only
   places them on the Impressions surfaces and draws the few shapes that are
   Impressions' own: the campaign-card and video-row skeletons, the
   Analytics skeleton, the medal ranks, the budget-burn tint. The JS half
   is in wiring.js (fxCampaigns, fxTopVids, fxLaunched), in
   impressions-analytics.js (skeletonHtml, fxShown) and in
   impressions-sdk.js (fxSeen, and the chip colours in renderStatus).

   Same rules as fx.css: transform / opacity only (plus one-shot pulse
   rings), nothing infinite but a bounded loading bar, no dot inside a pill,
   colours from tokens so both themes follow, and a closing reduced-motion
   block that stops everything added here.
   ======================================================================== */

/* ---------- 1. section header ---------- */
/* A soft, static gold wash behind the title (Impressions' accent) that fades in with the section, and the
   glyph pops once each time the section opens (the section toggles display, so both replay like riseIn).
   isolation keeps the wash's z-index:-1 inside the header instead of behind the page ground. */
#impressions > .phead{position:relative;isolation:isolate}
#impressions > .phead::before{content:"";position:absolute;z-index:-1;left:0;top:0;width:min(820px,100%);height:190px;pointer-events:none;
  background:radial-gradient(460px 170px at 90px 50px,rgba(201,146,31,.20),transparent 70%);
  animation:fxFade var(--fx-d4) var(--fx-soft) backwards}
:root[data-theme="dark"] #impressions > .phead::before{background:radial-gradient(460px 170px at 90px 50px,rgba(239,192,78,.11),transparent 70%)}
#impressions > .phead .glyph{animation:fxPop 420ms var(--fx-spring) 100ms backwards}

/* ---------- 2. Create Campaign ---------- */
/* the PreRec upload field rises in when the campaign type switches to PreRec */
#impressions #prerecUpload{animation:fxRise var(--fx-d3) var(--fx-ease) backwards}
/* the CPM chip bumps once when the rate crosses a colour band ($4 / $6 / $10; inline script in index.html) */
@keyframes fxImpBump{40%{transform:scale(1.1)}}
#impressions .cpmval.fx-imp-bump{animation:fxImpBump 340ms var(--fx-spring)}
/* dropzones: the icon lifts on hover and while a file is held over the zone, which also rings once */
#impressions .dropzone .big{transition:transform var(--fx-d2) var(--fx-spring)}
@media (hover:hover){#impressions .dropzone:hover .big{transform:translateY(-3px) scale(1.08)}}
#impressions .dropzone.dragging{--fx-pc:var(--fx-pc-green);animation:fxPulse 600ms var(--fx-soft) 1}
#impressions .dropzone.dragging .big{transform:translateY(-4px) scale(1.12)}

/* ---------- 3. Campaigns ---------- */
/* milestone chips ride in the card title, which wraps instead of squeezing when they need the room */
#campDash .ctitle{flex-wrap:wrap;row-gap:6px}
#campDash .ctitle + .mono{white-space:nowrap}
.fx-imp-chips{display:inline-flex;gap:6px;flex-wrap:wrap;letter-spacing:0}
.fx-imp-chips:empty{display:none}
/* first-read skeleton (index.html #fxTplCamp): the real card's rhythm, title row, hint, 7 stats, pool bar */
.fx-camp-sk{margin-bottom:14px}
.fx-camp-skhead{display:flex;align-items:center;gap:10px}
.fx-camp-skhead > .fx-sk-line{--w:34%;height:13px;margin:0}
.fx-camp-skhead > .fx-sk-pill{--w:72px;--h:20px}
.fx-camp-skhead > .fx-sk-line:last-child{--w:84px;margin-left:auto}
.fx-camp-skhint{--w:46%;margin-top:14px}
.fx-camp-skstats{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:12px;margin-top:16px}
.fx-camp-skstats .fx-sk-line{margin:0}
.fx-camp-skstats .fx-sk-line:first-child{--w:58%;height:9px}
.fx-camp-skstats .fx-sk-line:last-child{--w:74%;height:16px;margin-top:8px}
.fx-camp-skbar{display:block;height:6px;border-radius:4px;margin-top:18px}

/* ---------- 4. Creator Videos ---------- */
/* the real top three (the list is ranked by verified views) wear a medal ring on their rank. The ring is a
   pseudo-element centred on the number and reaching into the row's gap, so the row keeps its exact widths
   (a wider rank box pushed "Watch" onto two lines in the narrow two-column grid). */
#cvList .vid[data-medal] .vrk{position:relative;isolation:isolate}
#cvList .vid[data-medal] .vrk::before{content:"";position:absolute;z-index:-1;left:50%;top:50%;width:28px;height:28px;margin:-14px 0 0 -14px;border-radius:50%}
#cvList .vid[data-medal="1"] .vrk{color:var(--fx-gold-ink)}
#cvList .vid[data-medal="1"] .vrk::before{background:rgba(201,146,31,.12);box-shadow:inset 0 0 0 1.5px rgba(201,146,31,.55)}
#cvList .vid[data-medal="2"] .vrk{color:var(--ink-2)}
#cvList .vid[data-medal="2"] .vrk::before{background:var(--paper-3);box-shadow:inset 0 0 0 1.5px var(--line-2)}
#cvList .vid[data-medal="3"] .vrk{color:#8A5A34}
#cvList .vid[data-medal="3"] .vrk::before{background:rgba(176,112,64,.12);box-shadow:inset 0 0 0 1.5px rgba(176,112,64,.5)}
:root[data-theme="dark"] #cvList .vid[data-medal="3"] .vrk{color:#D39A6A}
/* the play glyph on the thumbnail nudges forward on hover */
#cvList .vid .th::after{transition:transform var(--fx-d2) var(--fx-spring),color var(--fx-d2) ease}
@media (hover:hover){#cvList .vid:hover .th::after{transform:scale(1.25);color:rgba(23,21,15,.7)}}
/* skeleton row (index.html #fxTplVid) */
.fx-vid-sk .fx-sk-num{--w:2.2ch}
.fx-vid-skth{width:64px;height:40px;border-radius:7px;flex:none}
.fx-vid-sktx{flex:1;min-width:0}
.fx-vid-sktx .fx-sk-line:first-child{--w:52%}
.fx-vid-sktx .fx-sk-line:last-child{--w:78%;height:.7em}
.fx-vid-sk .vpay .fx-sk-line{--w:54px;height:15px;margin:0}

/* ---------- 5. Analytics ---------- */
/* first-load skeleton (impressions-analytics.js skeletonHtml): the real grid, so nothing moves on arrival */
.fx-ian-sk .ian-hero{padding-bottom:20px}
.fx-ian-sk .ian-hero .fx-sk-line{margin:.5em 0}
.fx-ian-sk .ian-tile{min-height:118px}
.fx-ian-skchart{display:block;height:220px;margin-top:16px;border-radius:10px}
/* a skeleton is already a loading state: the refresh dim is not stacked on top of it */
#impressions .ian-busy .ian-body[aria-busy="true"]{opacity:1}
/* refresh: a thin indeterminate bar under the "Updated" line while a filter change loads. Transform only,
   bounded to 12 passes; padding + margin still add up to the line's old 12px, so nothing below moves. */
@keyframes fxImpIndet{from{transform:translateX(-100%)}to{transform:translateX(250%)}}
#impressions .ian-busy .ian-updated{position:relative;overflow:hidden;padding-bottom:6px;margin-bottom:6px}
#impressions .ian-busy .ian-updated::after{content:"";position:absolute;left:0;bottom:0;width:40%;height:2px;border-radius:2px;
  background:linear-gradient(90deg,transparent,var(--ian-accent),transparent);animation:fxImpIndet 1.1s var(--fx-soft) 12}
/* the hero sparkline wipes in left to right on a new payload (fxShown adds the class, animationend drops it) */
@keyframes fxImpWipe{from{clip-path:inset(0 100% 0 0)}to{clip-path:inset(0 0 0 0)}}
#impressions .ian-hero .spark svg.fx-imp-wipe{animation:fxImpWipe 1s var(--fx-ease) .18s backwards}
/* budget burn on the "Budget left" tile: green while more than a quarter is left, gold to 10%, coral below */
#impressions .ian-meter[data-tone="gold"] i{background:var(--gold)}
#impressions .ian-meter[data-tone="coral"] i{background:var(--coral)}

/* ---------- 6. SDK ---------- */
/* first-load busy sheen over the settings card: the sticky Save bar stays opaque (at 55% the settings
   scrolling under it would show through), and it carries the "Loading your settings" line anyway */
#isdkSettings.fx-sk-busy > .isdk-actions{opacity:1}
/* the preview stage rises in just behind the settings column each time the tab opens. Kept off
   data-fx-stagger on .isdk-grid: #isdkSettings carries the first-load busy skeleton (its clear-fade is a
   Web Animation now, so it could not restart a stagger any more, but the stage's own rule is simpler). */
#impressions .isdk-stage{animation:fxRise var(--fx-d3) var(--fx-ease) 70ms backwards}
/* the storefront callout rises in whenever it appears */
#impressions .isdk-callout{animation:fxRise var(--fx-d3) var(--fx-ease) backwards}
/* install chip: accent-tinted while the install is being checked (no dot; live and stale colours are in
   index.html next to .isdk-chip) */
#impressions .isdk-chip.isdk-chk{background:var(--ian-accent-soft);color:var(--ian-accent-ink);border-color:var(--ian-accent-soft)}
/* code-sample language tabs: the sliding underline wears the code panel's gold, not ink */
#impressions .isdk-langs .fx-tabink{background:#EFC04E}

/* ---------- 7. reduced motion ---------- */
/* index.html's kill switch already makes these .001ms; this block removes what would still be seen. */
@media (prefers-reduced-motion: reduce){
  #impressions > .phead::before,#impressions > .phead .glyph,#impressions #prerecUpload,#impressions .cpmval.fx-imp-bump,
  #impressions .dropzone.dragging,#impressions .isdk-callout,#impressions .isdk-stage,#impressions .ian-busy .ian-updated::after,
  #impressions .ian-hero .spark svg.fx-imp-wipe{animation:none}
  #impressions .dropzone .big,#cvList .vid .th::after{transition:none}
  #impressions .dropzone:hover .big,#impressions .dropzone.dragging .big,#cvList .vid:hover .th::after{transform:none}
}
