social-voc-openclaw-workshop.html 83 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <meta name="format-detection" content="telephone=no">
  7. <title>VOC.market 南昌社媒 VOC 工作坊|5月28日安装环境,5月29日全天分析实战</title>
  8. <meta name="description" content="VOC.market 南昌本地社媒 VOC 工作坊:聚焦小红书和抖音,5月28日下午安装 OpenClaw(龙虾)并配置技能,5月29日全天做 VOC 分析实战。">
  9. <script>
  10. (() => {
  11. const isMobile = window.matchMedia("(max-width: 720px), (hover: none), (pointer: coarse)").matches;
  12. if (!isMobile) return;
  13. try {
  14. const key = "socialVocWorkshopLoadMarks";
  15. const now = Date.now();
  16. const marks = JSON.parse(sessionStorage.getItem(key) || "[]")
  17. .filter((time) => now - time < 12000);
  18. marks.push(now);
  19. sessionStorage.setItem(key, JSON.stringify(marks.slice(-5)));
  20. if (marks.length >= 3) {
  21. document.documentElement.classList.add("mobile-safe-mode");
  22. }
  23. } catch (error) {
  24. document.documentElement.classList.add("mobile-safe-mode");
  25. }
  26. })();
  27. </script>
  28. <style>
  29. :root {
  30. --black: #050505;
  31. --deep: #0b0d10;
  32. --panel: rgba(255, 255, 255, 0.075);
  33. --panel-strong: rgba(255, 255, 255, 0.12);
  34. --line: rgba(255, 255, 255, 0.16);
  35. --line-strong: rgba(255, 255, 255, 0.28);
  36. --white: #ffffff;
  37. --muted: #a8b0ba;
  38. --dim: #66707b;
  39. --cyan: #00f0ff;
  40. --rose: #ff5252;
  41. --amber: #f59e0b;
  42. --green: #3ee084;
  43. --blue: #6388ff;
  44. --platinum: #e7edf3;
  45. --smoke: #101419;
  46. --radius: 8px;
  47. --max: 1180px;
  48. --ease: cubic-bezier(0.22, 1, 0.36, 1);
  49. }
  50. * {
  51. box-sizing: border-box;
  52. }
  53. html {
  54. scroll-behavior: smooth;
  55. background: var(--black);
  56. }
  57. body {
  58. margin: 0;
  59. min-height: 100vh;
  60. overflow-x: hidden;
  61. color: var(--white);
  62. background:
  63. linear-gradient(180deg, rgba(0, 240, 255, 0.075), transparent 22rem),
  64. linear-gradient(90deg, rgba(255, 82, 82, 0.055), transparent 30rem),
  65. linear-gradient(130deg, rgba(255, 255, 255, 0.04), transparent 18%, rgba(255, 255, 255, 0.015) 28%, transparent 45%),
  66. var(--black);
  67. font-family: Inter, "PingFang SC", "Microsoft YaHei", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  68. line-height: 1.6;
  69. -webkit-font-smoothing: antialiased;
  70. }
  71. body::before {
  72. content: "";
  73. position: fixed;
  74. inset: 0;
  75. z-index: -3;
  76. pointer-events: none;
  77. background-image:
  78. linear-gradient(rgba(255, 255, 255, 0.04) 1px, transparent 1px),
  79. linear-gradient(90deg, rgba(255, 255, 255, 0.04) 1px, transparent 1px);
  80. background-size: 48px 48px;
  81. mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0.8), transparent 72%);
  82. }
  83. body::after {
  84. content: "";
  85. position: fixed;
  86. inset: 0;
  87. z-index: -2;
  88. pointer-events: none;
  89. background:
  90. repeating-linear-gradient(180deg, rgba(255, 255, 255, 0.028) 0, rgba(255, 255, 255, 0.028) 1px, transparent 1px, transparent 5px);
  91. opacity: 0.18;
  92. }
  93. .intro-overlay {
  94. position: fixed;
  95. inset: 0;
  96. z-index: 120;
  97. display: grid;
  98. place-items: center;
  99. pointer-events: none;
  100. opacity: 1;
  101. visibility: visible;
  102. background:
  103. linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.06), transparent),
  104. #050505;
  105. transform: translateZ(0);
  106. backface-visibility: hidden;
  107. contain: paint;
  108. will-change: opacity;
  109. transition: opacity 0.42s var(--ease), visibility 0.42s var(--ease);
  110. }
  111. .intro-overlay.is-hiding {
  112. opacity: 0;
  113. visibility: hidden;
  114. }
  115. .intro-overlay.is-gone {
  116. display: none;
  117. }
  118. .intro-lockup {
  119. position: relative;
  120. display: grid;
  121. gap: 10px;
  122. text-align: center;
  123. transform: translate3d(0, 10px, 0);
  124. backface-visibility: hidden;
  125. will-change: opacity, transform;
  126. animation: introLockup 0.86s var(--ease) forwards;
  127. }
  128. .intro-lockup strong {
  129. font-size: 1.7rem;
  130. line-height: 1;
  131. font-weight: 850;
  132. }
  133. .intro-lockup span {
  134. color: var(--muted);
  135. font-size: 0.8rem;
  136. font-weight: 650;
  137. }
  138. .intro-rule {
  139. width: 220px;
  140. height: 1px;
  141. margin: 6px auto 0;
  142. background: linear-gradient(90deg, transparent, var(--cyan), var(--rose), transparent);
  143. transform-origin: center;
  144. animation: introRule 1.1s var(--ease) forwards;
  145. }
  146. @keyframes introLockup {
  147. from { opacity: 0; transform: translate3d(0, 16px, 0) scale(0.985); }
  148. to { opacity: 1; transform: translate3d(0, 0, 0) scale(1); }
  149. }
  150. @keyframes introRule {
  151. from { transform: scaleX(0); opacity: 0; }
  152. to { transform: scaleX(1); opacity: 1; }
  153. }
  154. a {
  155. color: inherit;
  156. text-decoration: none;
  157. }
  158. button,
  159. textarea {
  160. font: inherit;
  161. }
  162. h1,
  163. h2,
  164. h3,
  165. p {
  166. margin: 0;
  167. }
  168. img {
  169. display: block;
  170. max-width: 100%;
  171. }
  172. #networkCanvas {
  173. position: fixed;
  174. inset: 0;
  175. z-index: -1;
  176. width: 100%;
  177. height: 100%;
  178. opacity: 0.52;
  179. pointer-events: none;
  180. transform: translateZ(0);
  181. }
  182. .progress {
  183. position: fixed;
  184. top: 0;
  185. left: 0;
  186. z-index: 80;
  187. width: 0;
  188. height: 3px;
  189. background: linear-gradient(90deg, var(--cyan), var(--rose), var(--amber));
  190. box-shadow: 0 0 24px rgba(0, 240, 255, 0.45);
  191. }
  192. .nav {
  193. position: sticky;
  194. top: 0;
  195. z-index: 70;
  196. border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  197. background: linear-gradient(180deg, rgba(5, 5, 5, 0.86), rgba(5, 5, 5, 0.62));
  198. backdrop-filter: blur(22px) saturate(1.35);
  199. transition: background 0.34s var(--ease), border-color 0.34s ease, box-shadow 0.34s ease;
  200. }
  201. .nav.is-scrolled {
  202. border-color: rgba(255, 255, 255, 0.15);
  203. background: linear-gradient(180deg, rgba(5, 5, 5, 0.92), rgba(5, 5, 5, 0.76));
  204. box-shadow: 0 18px 54px rgba(0, 0, 0, 0.36);
  205. }
  206. .nav-inner {
  207. display: flex;
  208. align-items: center;
  209. justify-content: space-between;
  210. max-width: var(--max);
  211. min-height: 64px;
  212. margin: 0 auto;
  213. padding: 0 20px;
  214. }
  215. .brand {
  216. display: inline-flex;
  217. align-items: center;
  218. gap: 10px;
  219. font-weight: 750;
  220. }
  221. .brand-mark {
  222. position: relative;
  223. overflow: hidden;
  224. display: grid;
  225. place-items: center;
  226. width: 34px;
  227. height: 34px;
  228. border: 1px solid rgba(255, 255, 255, 0.26);
  229. border-radius: var(--radius);
  230. background: linear-gradient(135deg, var(--cyan), var(--rose));
  231. color: #050505;
  232. font-weight: 900;
  233. }
  234. .brand-mark::after {
  235. content: "";
  236. position: absolute;
  237. inset: -40% -80%;
  238. background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.62), transparent);
  239. transform: translateX(-80%) rotate(18deg);
  240. animation: markSheen 5.4s ease-in-out infinite;
  241. }
  242. @keyframes markSheen {
  243. 0%, 65% { transform: translateX(-80%) rotate(18deg); }
  244. 82%, 100% { transform: translateX(90%) rotate(18deg); }
  245. }
  246. .brand-name {
  247. line-height: 1.1;
  248. }
  249. .brand-name small {
  250. display: block;
  251. margin-top: 2px;
  252. color: var(--muted);
  253. font-size: 0.72rem;
  254. font-weight: 500;
  255. }
  256. .nav-links {
  257. display: flex;
  258. align-items: center;
  259. gap: 20px;
  260. color: var(--muted);
  261. font-size: 0.9rem;
  262. }
  263. .nav-links a {
  264. transition: color 0.25s ease;
  265. }
  266. .nav-links a:hover {
  267. color: var(--cyan);
  268. }
  269. .nav-cta {
  270. display: inline-flex;
  271. align-items: center;
  272. justify-content: center;
  273. min-height: 38px;
  274. padding: 8px 14px;
  275. border-radius: var(--radius);
  276. background: linear-gradient(135deg, var(--cyan), var(--rose));
  277. color: #050505;
  278. font-weight: 800;
  279. box-shadow: 0 0 28px rgba(0, 240, 255, 0.14);
  280. }
  281. .hero {
  282. position: relative;
  283. display: grid;
  284. align-items: center;
  285. min-height: calc(92svh - 64px);
  286. padding: 58px 20px 48px;
  287. overflow: hidden;
  288. }
  289. .hero::before {
  290. content: "";
  291. position: absolute;
  292. inset: 0;
  293. z-index: -1;
  294. background:
  295. linear-gradient(180deg, rgba(5, 5, 5, 0.14), rgba(5, 5, 5, 0.98)),
  296. url("https://images.unsplash.com/photo-1551288049-bebda4e38f71?auto=format&fit=crop&w=1800&q=82") center/cover no-repeat;
  297. opacity: 0.34;
  298. }
  299. .hero::after {
  300. content: "";
  301. position: absolute;
  302. left: 20px;
  303. right: 20px;
  304. bottom: 20px;
  305. height: 1px;
  306. background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.28), transparent);
  307. opacity: 0.8;
  308. }
  309. .hero-inner {
  310. display: grid;
  311. grid-template-columns: minmax(0, 1.03fr) minmax(360px, 0.8fr);
  312. gap: 54px;
  313. align-items: center;
  314. width: min(100%, var(--max));
  315. margin: 0 auto;
  316. }
  317. .hero-copy {
  318. position: relative;
  319. }
  320. .hero-copy::before {
  321. content: "SOCIAL VOC";
  322. position: absolute;
  323. left: -4px;
  324. top: -58px;
  325. color: rgba(255, 255, 255, 0.055);
  326. font-size: 5.8rem;
  327. line-height: 1;
  328. font-weight: 900;
  329. white-space: nowrap;
  330. pointer-events: none;
  331. }
  332. .eyebrow {
  333. display: inline-flex;
  334. align-items: center;
  335. width: fit-content;
  336. min-height: 32px;
  337. margin-bottom: 18px;
  338. padding: 5px 10px;
  339. border: 1px solid rgba(0, 240, 255, 0.38);
  340. border-radius: var(--radius);
  341. background: linear-gradient(90deg, rgba(0, 240, 255, 0.13), rgba(255, 255, 255, 0.035));
  342. color: var(--cyan);
  343. font-size: 0.86rem;
  344. font-weight: 750;
  345. }
  346. h1 {
  347. max-width: 780px;
  348. font-size: 4.55rem;
  349. line-height: 1.03;
  350. letter-spacing: 0;
  351. text-wrap: balance;
  352. font-weight: 850;
  353. }
  354. .gradient-text {
  355. background: linear-gradient(120deg, var(--cyan), var(--platinum), var(--rose), var(--cyan));
  356. background-size: 220% 100%;
  357. background-clip: text;
  358. -webkit-background-clip: text;
  359. -webkit-text-fill-color: transparent;
  360. animation: gradientDrift 7s ease-in-out infinite;
  361. }
  362. @keyframes gradientDrift {
  363. 0%, 100% { background-position: 0% 50%; }
  364. 50% { background-position: 100% 50%; }
  365. }
  366. .hero-lead {
  367. max-width: 700px;
  368. margin-top: 20px;
  369. color: #d2d7de;
  370. font-size: 1.18rem;
  371. text-wrap: pretty;
  372. }
  373. .hero-actions {
  374. display: flex;
  375. flex-wrap: wrap;
  376. gap: 12px;
  377. margin-top: 30px;
  378. }
  379. .button {
  380. position: relative;
  381. overflow: hidden;
  382. display: inline-flex;
  383. align-items: center;
  384. justify-content: center;
  385. min-height: 46px;
  386. padding: 11px 16px;
  387. border: 1px solid rgba(255, 255, 255, 0.26);
  388. border-radius: var(--radius);
  389. color: var(--white);
  390. font-weight: 780;
  391. cursor: pointer;
  392. transition: transform 0.25s var(--ease), border-color 0.25s ease, background 0.25s ease, box-shadow 0.25s ease;
  393. }
  394. .button::before {
  395. content: "";
  396. position: absolute;
  397. inset: 0;
  398. background: linear-gradient(110deg, transparent 0%, rgba(255, 255, 255, 0.28) 45%, transparent 70%);
  399. transform: translateX(-110%);
  400. transition: transform 0.58s var(--ease);
  401. }
  402. .button:hover::before {
  403. transform: translateX(110%);
  404. }
  405. .button.primary {
  406. border: 0;
  407. background: linear-gradient(135deg, var(--cyan), var(--rose));
  408. color: #050505;
  409. box-shadow: 0 16px 40px rgba(0, 240, 255, 0.16);
  410. }
  411. .button:hover {
  412. transform: translateY(-2px);
  413. border-color: rgba(0, 240, 255, 0.56);
  414. background: rgba(255, 255, 255, 0.09);
  415. box-shadow: 0 12px 34px rgba(0, 0, 0, 0.28);
  416. }
  417. .button.primary:hover {
  418. background: linear-gradient(135deg, #72f8ff, #ff7474);
  419. }
  420. .hero-proof {
  421. display: grid;
  422. grid-template-columns: repeat(3, minmax(0, 1fr));
  423. gap: 10px;
  424. max-width: 650px;
  425. margin-top: 32px;
  426. }
  427. .proof-pill {
  428. position: relative;
  429. overflow: hidden;
  430. min-height: 76px;
  431. padding: 12px;
  432. border: 1px solid var(--line);
  433. border-radius: var(--radius);
  434. background: linear-gradient(180deg, rgba(255, 255, 255, 0.105), rgba(255, 255, 255, 0.045));
  435. backdrop-filter: blur(14px);
  436. }
  437. .proof-pill::before {
  438. content: "";
  439. position: absolute;
  440. inset: 0 0 auto;
  441. height: 1px;
  442. background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.58), transparent);
  443. }
  444. .proof-pill strong {
  445. display: block;
  446. color: var(--white);
  447. font-size: 1.12rem;
  448. line-height: 1.2;
  449. }
  450. .proof-pill span {
  451. display: block;
  452. margin-top: 5px;
  453. color: var(--muted);
  454. font-size: 0.84rem;
  455. }
  456. .requirement-strip {
  457. display: grid;
  458. grid-template-columns: auto minmax(0, 1fr);
  459. gap: 14px;
  460. align-items: center;
  461. max-width: 650px;
  462. margin-top: 16px;
  463. padding: 14px;
  464. border: 1px solid rgba(245, 158, 11, 0.36);
  465. border-radius: var(--radius);
  466. background: linear-gradient(135deg, rgba(245, 158, 11, 0.12), rgba(255, 255, 255, 0.06));
  467. backdrop-filter: blur(16px);
  468. }
  469. .requirement-strip b {
  470. display: block;
  471. color: var(--amber);
  472. font-size: 0.9rem;
  473. }
  474. .requirement-strip span {
  475. display: block;
  476. color: #dce2e8;
  477. font-size: 0.92rem;
  478. }
  479. .requirement-badge {
  480. display: grid;
  481. place-items: center;
  482. width: 42px;
  483. height: 42px;
  484. border: 1px solid rgba(245, 158, 11, 0.4);
  485. border-radius: var(--radius);
  486. color: #050505;
  487. background: var(--amber);
  488. font-weight: 950;
  489. }
  490. .hero-media {
  491. position: relative;
  492. isolation: isolate;
  493. min-height: 520px;
  494. border: 1px solid rgba(255, 255, 255, 0.2);
  495. border-radius: var(--radius);
  496. overflow: hidden;
  497. background: #080a0d;
  498. box-shadow: 0 28px 80px rgba(0, 0, 0, 0.48);
  499. transform-style: preserve-3d;
  500. }
  501. .hero-media::before {
  502. content: "";
  503. position: absolute;
  504. inset: 0;
  505. z-index: 4;
  506. pointer-events: none;
  507. border: 1px solid rgba(255, 255, 255, 0.16);
  508. background:
  509. linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent) 0 0 / 180% 1px no-repeat,
  510. linear-gradient(180deg, transparent, rgba(0, 240, 255, 0.16), transparent) 0 0 / 1px 180% no-repeat;
  511. animation: edgeTrace 7s ease-in-out infinite;
  512. }
  513. @keyframes edgeTrace {
  514. 0%, 100% { background-position: -120% 0, 0 -120%; opacity: 0.45; }
  515. 50% { background-position: 120% 0, 0 120%; opacity: 1; }
  516. }
  517. .hero-media img {
  518. position: absolute;
  519. inset: 0;
  520. width: 100%;
  521. height: 100%;
  522. object-fit: cover;
  523. opacity: 0.28;
  524. filter: saturate(0.9) contrast(1.1);
  525. }
  526. .hero-media::after {
  527. content: "";
  528. position: absolute;
  529. inset: 0;
  530. background:
  531. linear-gradient(180deg, rgba(5, 5, 5, 0.18), rgba(5, 5, 5, 0.92)),
  532. linear-gradient(90deg, rgba(0, 240, 255, 0.16), transparent 46%, rgba(255, 82, 82, 0.16));
  533. pointer-events: none;
  534. z-index: 1;
  535. }
  536. .signal-console {
  537. position: absolute;
  538. inset: 22px;
  539. z-index: 2;
  540. display: grid;
  541. grid-template-rows: auto 1fr auto;
  542. gap: 14px;
  543. }
  544. .console-top {
  545. display: flex;
  546. align-items: center;
  547. justify-content: space-between;
  548. gap: 12px;
  549. color: var(--muted);
  550. font-size: 0.82rem;
  551. }
  552. .console-dots {
  553. display: inline-flex;
  554. gap: 6px;
  555. }
  556. .console-dots span {
  557. width: 8px;
  558. height: 8px;
  559. border-radius: 50%;
  560. background: var(--cyan);
  561. box-shadow: 0 0 16px rgba(0, 240, 255, 0.7);
  562. }
  563. .console-dots span:nth-child(2) {
  564. background: var(--rose);
  565. box-shadow: 0 0 16px rgba(255, 82, 82, 0.7);
  566. }
  567. .console-dots span:nth-child(3) {
  568. background: var(--amber);
  569. box-shadow: 0 0 16px rgba(245, 158, 11, 0.7);
  570. }
  571. .radar {
  572. position: relative;
  573. min-height: 310px;
  574. border: 1px solid rgba(255, 255, 255, 0.13);
  575. border-radius: var(--radius);
  576. overflow: hidden;
  577. background:
  578. linear-gradient(rgba(255, 255, 255, 0.035) 1px, transparent 1px),
  579. linear-gradient(90deg, rgba(255, 255, 255, 0.035) 1px, transparent 1px),
  580. linear-gradient(135deg, rgba(0, 240, 255, 0.08), rgba(255, 255, 255, 0.03), rgba(255, 82, 82, 0.08)),
  581. rgba(255, 255, 255, 0.055);
  582. background-size: 28px 28px;
  583. }
  584. .radar-line {
  585. position: absolute;
  586. left: 8%;
  587. right: 8%;
  588. height: 2px;
  589. background: linear-gradient(90deg, transparent, var(--cyan), transparent);
  590. box-shadow: 0 0 18px rgba(0, 240, 255, 0.8);
  591. animation: scan 4.6s ease-in-out infinite;
  592. }
  593. @keyframes scan {
  594. 0% { top: 12%; opacity: 0; }
  595. 12% { opacity: 1; }
  596. 76% { opacity: 1; }
  597. 100% { top: 86%; opacity: 0; }
  598. }
  599. .signal-node {
  600. position: absolute;
  601. display: grid;
  602. place-items: center;
  603. min-width: 86px;
  604. min-height: 42px;
  605. padding: 6px 9px;
  606. border: 1px solid rgba(255, 255, 255, 0.18);
  607. border-radius: var(--radius);
  608. background: rgba(5, 5, 5, 0.6);
  609. color: var(--white);
  610. font-size: 0.82rem;
  611. font-weight: 750;
  612. backdrop-filter: blur(10px);
  613. animation: floatCard 5.8s ease-in-out infinite;
  614. }
  615. .signal-node small {
  616. color: var(--muted);
  617. font-size: 0.68rem;
  618. font-weight: 500;
  619. }
  620. .signal-node:nth-child(2) {
  621. top: 15%;
  622. left: 8%;
  623. border-color: rgba(0, 240, 255, 0.38);
  624. }
  625. .signal-node:nth-child(3) {
  626. top: 24%;
  627. right: 10%;
  628. border-color: rgba(255, 82, 82, 0.42);
  629. animation-delay: 0.5s;
  630. }
  631. .signal-node:nth-child(4) {
  632. top: 50%;
  633. left: 22%;
  634. border-color: rgba(245, 158, 11, 0.42);
  635. animation-delay: 1.1s;
  636. }
  637. .signal-node:nth-child(5) {
  638. right: 8%;
  639. bottom: 18%;
  640. border-color: rgba(62, 224, 132, 0.4);
  641. animation-delay: 1.8s;
  642. }
  643. @keyframes floatCard {
  644. 0%, 100% { transform: translateY(0); }
  645. 50% { transform: translateY(-9px); }
  646. }
  647. .console-bottom {
  648. display: grid;
  649. grid-template-columns: repeat(3, 1fr);
  650. gap: 10px;
  651. }
  652. .meter {
  653. padding: 12px;
  654. border: 1px solid rgba(255, 255, 255, 0.14);
  655. border-radius: var(--radius);
  656. background: rgba(255, 255, 255, 0.07);
  657. }
  658. .meter span {
  659. display: block;
  660. margin-bottom: 8px;
  661. color: var(--muted);
  662. font-size: 0.72rem;
  663. }
  664. .bar {
  665. height: 7px;
  666. border-radius: 999px;
  667. background: rgba(255, 255, 255, 0.11);
  668. overflow: hidden;
  669. }
  670. .bar i {
  671. display: block;
  672. width: 72%;
  673. height: 100%;
  674. border-radius: inherit;
  675. background: linear-gradient(90deg, var(--cyan), var(--rose));
  676. animation: barPulse 4s ease-in-out infinite;
  677. }
  678. .meter:nth-child(2) .bar i {
  679. width: 86%;
  680. background: linear-gradient(90deg, var(--amber), var(--cyan));
  681. animation-delay: 0.7s;
  682. }
  683. .meter:nth-child(3) .bar i {
  684. width: 64%;
  685. background: linear-gradient(90deg, var(--green), var(--cyan));
  686. animation-delay: 1.2s;
  687. }
  688. @keyframes barPulse {
  689. 0%, 100% { transform: translateX(-8%); opacity: 0.75; }
  690. 50% { transform: translateX(8%); opacity: 1; }
  691. }
  692. .ticker {
  693. border-top: 1px solid rgba(255, 255, 255, 0.1);
  694. border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  695. background: rgba(255, 255, 255, 0.045);
  696. overflow: hidden;
  697. }
  698. .ticker-track {
  699. display: flex;
  700. width: max-content;
  701. animation: marquee 34s linear infinite;
  702. }
  703. .ticker-group {
  704. display: flex;
  705. gap: 12px;
  706. padding: 16px 6px;
  707. }
  708. .ticker span {
  709. display: inline-flex;
  710. align-items: center;
  711. min-height: 34px;
  712. padding: 6px 12px;
  713. border: 1px solid rgba(255, 255, 255, 0.18);
  714. border-radius: var(--radius);
  715. color: #dce5ef;
  716. white-space: nowrap;
  717. background: rgba(5, 5, 5, 0.45);
  718. font-size: 0.9rem;
  719. }
  720. @keyframes marquee {
  721. from { transform: translateX(0); }
  722. to { transform: translateX(-50%); }
  723. }
  724. .signal-spine {
  725. position: relative;
  726. overflow: hidden;
  727. padding: 72px 20px 78px;
  728. border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  729. background:
  730. linear-gradient(90deg, rgba(255, 255, 255, 0.03), transparent 18%, rgba(255, 255, 255, 0.025) 56%, transparent),
  731. rgba(255, 255, 255, 0.018);
  732. }
  733. .signal-spine::before {
  734. content: "";
  735. position: absolute;
  736. top: 50%;
  737. left: 0;
  738. right: 0;
  739. height: 1px;
  740. background: linear-gradient(90deg, transparent, rgba(0, 240, 255, 0.35), rgba(255, 82, 82, 0.32), transparent);
  741. }
  742. .spine-inner {
  743. position: relative;
  744. width: min(100%, var(--max));
  745. margin: 0 auto;
  746. }
  747. .spine-word {
  748. position: absolute;
  749. top: -44px;
  750. right: 0;
  751. color: rgba(255, 255, 255, 0.045);
  752. font-size: 7rem;
  753. line-height: 1;
  754. font-weight: 900;
  755. white-space: nowrap;
  756. pointer-events: none;
  757. }
  758. .spine-grid {
  759. display: grid;
  760. grid-template-columns: repeat(4, minmax(0, 1fr));
  761. gap: 12px;
  762. }
  763. .spine-cell {
  764. position: relative;
  765. min-height: 210px;
  766. padding: 18px;
  767. border: 1px solid rgba(255, 255, 255, 0.14);
  768. border-radius: var(--radius);
  769. background:
  770. linear-gradient(180deg, rgba(255, 255, 255, 0.095), rgba(255, 255, 255, 0.035));
  771. backdrop-filter: blur(18px);
  772. overflow: hidden;
  773. transition: transform 0.34s var(--ease), border-color 0.34s ease, background 0.34s ease, box-shadow 0.34s ease;
  774. }
  775. .spine-cell::before {
  776. content: "";
  777. position: absolute;
  778. inset: 0 0 auto;
  779. height: 2px;
  780. background: linear-gradient(90deg, var(--cyan), var(--rose));
  781. opacity: 0.68;
  782. }
  783. .spine-cell:hover {
  784. transform: translateY(-6px);
  785. border-color: rgba(0, 240, 255, 0.38);
  786. }
  787. .spine-cell em {
  788. display: block;
  789. color: var(--dim);
  790. font-style: normal;
  791. font-size: 0.74rem;
  792. font-weight: 800;
  793. }
  794. .spine-cell strong {
  795. display: block;
  796. margin-top: 36px;
  797. color: var(--white);
  798. font-size: 1.2rem;
  799. line-height: 1.25;
  800. }
  801. .spine-cell span {
  802. display: block;
  803. margin-top: 12px;
  804. color: var(--muted);
  805. font-size: 0.9rem;
  806. }
  807. .spine-cell b {
  808. position: absolute;
  809. right: 16px;
  810. bottom: 10px;
  811. color: rgba(255, 255, 255, 0.065);
  812. font-size: 4rem;
  813. line-height: 1;
  814. font-weight: 900;
  815. }
  816. .section {
  817. position: relative;
  818. padding: 86px 20px;
  819. }
  820. .section::before {
  821. content: "";
  822. position: absolute;
  823. inset: 0 0 auto;
  824. height: 1px;
  825. background: linear-gradient(90deg, transparent, rgba(0, 240, 255, 0.35), rgba(255, 82, 82, 0.28), transparent);
  826. opacity: 0;
  827. transform: scaleX(0.46);
  828. transform-origin: center;
  829. transition: opacity 1s var(--ease), transform 1s var(--ease);
  830. }
  831. .section.section-active::before {
  832. opacity: 1;
  833. transform: scaleX(1);
  834. }
  835. .section.alt {
  836. background: rgba(255, 255, 255, 0.035);
  837. border-top: 1px solid rgba(255, 255, 255, 0.08);
  838. border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  839. }
  840. .wrap {
  841. width: min(100%, var(--max));
  842. margin: 0 auto;
  843. }
  844. .section-head {
  845. display: grid;
  846. gap: 12px;
  847. max-width: 760px;
  848. margin-bottom: 32px;
  849. }
  850. .section-head.center {
  851. margin-right: auto;
  852. margin-left: auto;
  853. text-align: center;
  854. }
  855. .section-kicker {
  856. color: var(--cyan);
  857. font-size: 0.92rem;
  858. font-weight: 800;
  859. }
  860. h2 {
  861. font-size: 2.8rem;
  862. line-height: 1.13;
  863. letter-spacing: 0;
  864. }
  865. .sub {
  866. color: var(--muted);
  867. font-size: 1.05rem;
  868. }
  869. .grid {
  870. display: grid;
  871. gap: 14px;
  872. }
  873. .grid.two {
  874. grid-template-columns: repeat(2, minmax(0, 1fr));
  875. }
  876. .grid.three {
  877. grid-template-columns: repeat(3, minmax(0, 1fr));
  878. }
  879. .grid.four {
  880. grid-template-columns: repeat(4, minmax(0, 1fr));
  881. }
  882. .card,
  883. .slice,
  884. .timeline-row,
  885. .deliverable,
  886. .share-panel {
  887. position: relative;
  888. overflow: hidden;
  889. border: 1px solid var(--line);
  890. border-radius: var(--radius);
  891. background:
  892. linear-gradient(180deg, rgba(255, 255, 255, 0.09), rgba(255, 255, 255, 0.045)),
  893. var(--panel);
  894. backdrop-filter: blur(18px);
  895. transform: translateZ(0);
  896. }
  897. .card::after,
  898. .timeline-row::after,
  899. .deliverable::after,
  900. .share-panel::after {
  901. content: "";
  902. position: absolute;
  903. inset: 0 0 auto;
  904. height: 1px;
  905. background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.42), transparent);
  906. pointer-events: none;
  907. }
  908. .card {
  909. min-height: 100%;
  910. padding: 20px;
  911. transition: transform 0.34s var(--ease), border-color 0.34s ease, background 0.34s ease, box-shadow 0.34s ease;
  912. }
  913. .card:hover {
  914. transform: translateY(-5px);
  915. border-color: rgba(0, 240, 255, 0.35);
  916. background: rgba(255, 255, 255, 0.095);
  917. box-shadow: 0 18px 48px rgba(0, 0, 0, 0.28);
  918. }
  919. .index {
  920. display: inline-flex;
  921. align-items: center;
  922. justify-content: center;
  923. width: 34px;
  924. height: 34px;
  925. margin-bottom: 14px;
  926. border: 1px solid rgba(255, 255, 255, 0.18);
  927. border-radius: var(--radius);
  928. color: #050505;
  929. background: var(--cyan);
  930. font-weight: 900;
  931. }
  932. .index.rose {
  933. background: var(--rose);
  934. }
  935. .index.amber {
  936. background: var(--amber);
  937. }
  938. .index.green {
  939. background: var(--green);
  940. }
  941. .card h3 {
  942. margin-bottom: 8px;
  943. font-size: 1.16rem;
  944. line-height: 1.36;
  945. letter-spacing: 0;
  946. }
  947. .card p,
  948. .card li {
  949. color: var(--muted);
  950. font-size: 0.94rem;
  951. }
  952. .list {
  953. display: grid;
  954. gap: 9px;
  955. margin: 0;
  956. padding: 0;
  957. list-style: none;
  958. }
  959. .list li {
  960. position: relative;
  961. padding-left: 18px;
  962. }
  963. .list li::before {
  964. content: "";
  965. position: absolute;
  966. top: 0.72em;
  967. left: 0;
  968. width: 7px;
  969. height: 7px;
  970. border-radius: 50%;
  971. background: var(--cyan);
  972. box-shadow: 0 0 12px rgba(0, 240, 255, 0.5);
  973. }
  974. .skill-wall {
  975. display: grid;
  976. grid-template-columns: 0.9fr 1.1fr;
  977. gap: 16px;
  978. align-items: stretch;
  979. }
  980. .slice {
  981. position: relative;
  982. overflow: hidden;
  983. min-height: 360px;
  984. padding: 24px;
  985. }
  986. .slice h3 {
  987. max-width: 360px;
  988. font-size: 1.9rem;
  989. line-height: 1.18;
  990. letter-spacing: 0;
  991. }
  992. .slice p {
  993. max-width: 380px;
  994. margin-top: 14px;
  995. color: var(--muted);
  996. }
  997. .skill-rings {
  998. position: absolute;
  999. right: 22px;
  1000. bottom: 22px;
  1001. width: 260px;
  1002. height: 260px;
  1003. border: 1px solid rgba(0, 240, 255, 0.32);
  1004. border-radius: 50%;
  1005. animation: rotateSlow 28s linear infinite;
  1006. }
  1007. .skill-rings::before,
  1008. .skill-rings::after {
  1009. content: "";
  1010. position: absolute;
  1011. border: 1px solid rgba(255, 255, 255, 0.16);
  1012. border-radius: 50%;
  1013. }
  1014. .skill-rings::before {
  1015. inset: 38px;
  1016. }
  1017. .skill-rings::after {
  1018. inset: 84px;
  1019. border-color: rgba(255, 82, 82, 0.34);
  1020. }
  1021. .ring-label {
  1022. position: absolute;
  1023. display: inline-flex;
  1024. align-items: center;
  1025. justify-content: center;
  1026. min-height: 34px;
  1027. padding: 5px 10px;
  1028. border: 1px solid rgba(255, 255, 255, 0.18);
  1029. border-radius: var(--radius);
  1030. background: rgba(5, 5, 5, 0.72);
  1031. color: var(--white);
  1032. font-size: 0.82rem;
  1033. animation: rotateBack 28s linear infinite;
  1034. }
  1035. .ring-label.a { top: -15px; left: 82px; }
  1036. .ring-label.b { top: 108px; right: -34px; }
  1037. .ring-label.c { left: -24px; bottom: 52px; }
  1038. .ring-label.d { right: 72px; bottom: -15px; }
  1039. @keyframes rotateSlow {
  1040. to { transform: rotate(360deg); }
  1041. }
  1042. @keyframes rotateBack {
  1043. to { transform: rotate(-360deg); }
  1044. }
  1045. .capability-grid {
  1046. display: grid;
  1047. grid-template-columns: repeat(2, minmax(0, 1fr));
  1048. gap: 14px;
  1049. }
  1050. .capability {
  1051. padding: 18px;
  1052. border: 1px solid var(--line);
  1053. border-radius: var(--radius);
  1054. background: rgba(255, 255, 255, 0.055);
  1055. transition: transform 0.34s var(--ease), border-color 0.34s ease, background 0.34s ease, box-shadow 0.34s ease;
  1056. }
  1057. .capability:hover {
  1058. transform: translateY(-5px);
  1059. border-color: rgba(0, 240, 255, 0.34);
  1060. background: rgba(255, 255, 255, 0.085);
  1061. box-shadow: 0 18px 48px rgba(0, 0, 0, 0.24);
  1062. }
  1063. .capability strong {
  1064. display: block;
  1065. margin-bottom: 8px;
  1066. font-size: 1.02rem;
  1067. }
  1068. .capability span {
  1069. color: var(--muted);
  1070. font-size: 0.9rem;
  1071. }
  1072. .daily-lab {
  1073. display: grid;
  1074. grid-template-columns: minmax(0, 0.95fr) minmax(420px, 1.05fr);
  1075. gap: 18px;
  1076. align-items: stretch;
  1077. }
  1078. .daily-copy {
  1079. display: grid;
  1080. align-content: center;
  1081. gap: 18px;
  1082. min-height: 100%;
  1083. }
  1084. .daily-copy .section-head {
  1085. margin-bottom: 0;
  1086. }
  1087. .daily-points {
  1088. display: grid;
  1089. gap: 10px;
  1090. }
  1091. .daily-point {
  1092. display: grid;
  1093. grid-template-columns: 38px minmax(0, 1fr);
  1094. gap: 12px;
  1095. align-items: start;
  1096. padding: 14px;
  1097. border: 1px solid var(--line);
  1098. border-radius: var(--radius);
  1099. background: rgba(255, 255, 255, 0.06);
  1100. }
  1101. .daily-point b {
  1102. display: grid;
  1103. place-items: center;
  1104. width: 34px;
  1105. height: 34px;
  1106. border-radius: var(--radius);
  1107. background: rgba(0, 240, 255, 0.16);
  1108. color: var(--cyan);
  1109. font-size: 0.84rem;
  1110. }
  1111. .daily-point strong {
  1112. display: block;
  1113. margin-bottom: 4px;
  1114. color: var(--white);
  1115. }
  1116. .daily-point span {
  1117. color: var(--muted);
  1118. font-size: 0.9rem;
  1119. }
  1120. .daily-board {
  1121. position: relative;
  1122. overflow: hidden;
  1123. min-height: 560px;
  1124. border: 1px solid var(--line-strong);
  1125. border-radius: var(--radius);
  1126. background:
  1127. linear-gradient(180deg, rgba(0, 240, 255, 0.08), transparent 32%),
  1128. linear-gradient(135deg, rgba(255, 82, 82, 0.09), transparent 42%),
  1129. rgba(255, 255, 255, 0.06);
  1130. backdrop-filter: blur(18px);
  1131. box-shadow: 0 26px 90px rgba(0, 0, 0, 0.42);
  1132. }
  1133. .daily-board::before {
  1134. content: "";
  1135. position: absolute;
  1136. inset: 0;
  1137. background-image:
  1138. linear-gradient(rgba(255, 255, 255, 0.045) 1px, transparent 1px),
  1139. linear-gradient(90deg, rgba(255, 255, 255, 0.045) 1px, transparent 1px);
  1140. background-size: 34px 34px;
  1141. mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0.92), transparent 92%);
  1142. pointer-events: none;
  1143. }
  1144. .board-inner {
  1145. position: relative;
  1146. z-index: 1;
  1147. display: grid;
  1148. gap: 14px;
  1149. padding: 18px;
  1150. }
  1151. .board-header {
  1152. display: flex;
  1153. align-items: center;
  1154. justify-content: space-between;
  1155. gap: 12px;
  1156. padding-bottom: 12px;
  1157. border-bottom: 1px solid rgba(255, 255, 255, 0.14);
  1158. }
  1159. .board-title {
  1160. display: grid;
  1161. gap: 4px;
  1162. }
  1163. .board-title strong {
  1164. font-size: 1.08rem;
  1165. }
  1166. .board-title span,
  1167. .board-status {
  1168. color: var(--muted);
  1169. font-size: 0.82rem;
  1170. }
  1171. .board-status {
  1172. display: inline-flex;
  1173. align-items: center;
  1174. min-height: 28px;
  1175. padding: 4px 9px;
  1176. border: 1px solid rgba(62, 224, 132, 0.34);
  1177. border-radius: var(--radius);
  1178. color: var(--green);
  1179. background: rgba(62, 224, 132, 0.08);
  1180. white-space: nowrap;
  1181. }
  1182. .pipeline {
  1183. display: grid;
  1184. gap: 10px;
  1185. }
  1186. .pipeline-step {
  1187. display: grid;
  1188. grid-template-columns: 72px minmax(0, 1fr) auto;
  1189. gap: 12px;
  1190. align-items: center;
  1191. padding: 13px;
  1192. border: 1px solid rgba(255, 255, 255, 0.13);
  1193. border-radius: var(--radius);
  1194. background: rgba(5, 5, 5, 0.42);
  1195. animation: stepGlow 6s ease-in-out infinite;
  1196. }
  1197. .pipeline-step:nth-child(2) { animation-delay: 0.45s; }
  1198. .pipeline-step:nth-child(3) { animation-delay: 0.9s; }
  1199. .pipeline-step:nth-child(4) { animation-delay: 1.35s; }
  1200. .pipeline-step:nth-child(5) { animation-delay: 1.8s; }
  1201. @keyframes stepGlow {
  1202. 0%, 100% { border-color: rgba(255, 255, 255, 0.13); }
  1203. 50% { border-color: rgba(0, 240, 255, 0.34); }
  1204. }
  1205. .pipeline-step code {
  1206. color: var(--cyan);
  1207. font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  1208. font-size: 0.78rem;
  1209. }
  1210. .pipeline-step strong {
  1211. display: block;
  1212. margin-bottom: 2px;
  1213. font-size: 0.95rem;
  1214. }
  1215. .pipeline-step span {
  1216. color: var(--muted);
  1217. font-size: 0.82rem;
  1218. }
  1219. .pipeline-step i {
  1220. display: inline-grid;
  1221. place-items: center;
  1222. width: 28px;
  1223. height: 28px;
  1224. border-radius: 50%;
  1225. color: #050505;
  1226. background: linear-gradient(135deg, var(--cyan), var(--rose));
  1227. font-style: normal;
  1228. font-weight: 900;
  1229. }
  1230. .topic-stack {
  1231. display: grid;
  1232. grid-template-columns: repeat(3, minmax(0, 1fr));
  1233. gap: 10px;
  1234. }
  1235. .topic-card {
  1236. min-height: 118px;
  1237. padding: 12px;
  1238. border: 1px solid rgba(255, 255, 255, 0.13);
  1239. border-radius: var(--radius);
  1240. background: rgba(255, 255, 255, 0.07);
  1241. }
  1242. .topic-card small {
  1243. color: var(--dim);
  1244. font-size: 0.72rem;
  1245. }
  1246. .topic-card strong {
  1247. display: block;
  1248. margin: 8px 0;
  1249. line-height: 1.28;
  1250. font-size: 0.92rem;
  1251. }
  1252. .topic-card span {
  1253. color: var(--muted);
  1254. font-size: 0.78rem;
  1255. }
  1256. .need-finder {
  1257. display: grid;
  1258. grid-template-columns: repeat(4, minmax(0, 1fr));
  1259. gap: 12px;
  1260. margin-top: 22px;
  1261. }
  1262. .need-chip {
  1263. min-height: 116px;
  1264. padding: 14px;
  1265. border: 1px solid var(--line);
  1266. border-radius: var(--radius);
  1267. background: rgba(255, 255, 255, 0.052);
  1268. transition: transform 0.34s var(--ease), border-color 0.34s ease, background 0.34s ease;
  1269. }
  1270. .need-chip:hover {
  1271. transform: translateY(-4px);
  1272. border-color: rgba(0, 240, 255, 0.32);
  1273. background: rgba(255, 255, 255, 0.08);
  1274. }
  1275. .need-chip strong {
  1276. display: block;
  1277. margin-bottom: 6px;
  1278. color: var(--white);
  1279. }
  1280. .need-chip span {
  1281. color: var(--muted);
  1282. font-size: 0.86rem;
  1283. }
  1284. .platform-map {
  1285. display: grid;
  1286. grid-template-columns: repeat(4, minmax(0, 1fr));
  1287. gap: 10px;
  1288. }
  1289. .platform {
  1290. min-height: 132px;
  1291. padding: 14px;
  1292. border: 1px solid var(--line);
  1293. border-radius: var(--radius);
  1294. background: rgba(255, 255, 255, 0.06);
  1295. transition: transform 0.34s var(--ease), border-color 0.34s ease, background 0.34s ease, box-shadow 0.34s ease;
  1296. }
  1297. .platform:hover {
  1298. transform: translateY(-4px);
  1299. border-color: rgba(255, 82, 82, 0.4);
  1300. background: rgba(255, 255, 255, 0.09);
  1301. box-shadow: 0 16px 42px rgba(0, 0, 0, 0.24);
  1302. }
  1303. .platform b {
  1304. display: block;
  1305. margin-bottom: 6px;
  1306. color: var(--white);
  1307. font-size: 1rem;
  1308. }
  1309. .platform span {
  1310. color: var(--muted);
  1311. font-size: 0.84rem;
  1312. }
  1313. .timeline {
  1314. display: grid;
  1315. gap: 12px;
  1316. }
  1317. .timeline-row {
  1318. display: grid;
  1319. grid-template-columns: 190px minmax(0, 1fr);
  1320. gap: 20px;
  1321. padding: 20px;
  1322. transition: border-color 0.5s ease, background 0.5s ease, box-shadow 0.5s ease;
  1323. }
  1324. .timeline-row.visible {
  1325. border-color: rgba(0, 240, 255, 0.26);
  1326. box-shadow: 0 18px 58px rgba(0, 0, 0, 0.24);
  1327. }
  1328. .time {
  1329. color: var(--cyan);
  1330. font-weight: 850;
  1331. }
  1332. .timeline-row h3 {
  1333. margin-bottom: 8px;
  1334. font-size: 1.25rem;
  1335. letter-spacing: 0;
  1336. }
  1337. .timeline-row p {
  1338. color: var(--muted);
  1339. }
  1340. .tags {
  1341. display: flex;
  1342. flex-wrap: wrap;
  1343. gap: 8px;
  1344. margin-top: 14px;
  1345. }
  1346. .tags span {
  1347. display: inline-flex;
  1348. align-items: center;
  1349. min-height: 30px;
  1350. padding: 5px 9px;
  1351. border: 1px solid rgba(255, 255, 255, 0.14);
  1352. border-radius: var(--radius);
  1353. background: rgba(255, 255, 255, 0.07);
  1354. color: #d8dee6;
  1355. font-size: 0.84rem;
  1356. font-weight: 700;
  1357. }
  1358. .deliverables {
  1359. display: grid;
  1360. grid-template-columns: repeat(3, minmax(0, 1fr));
  1361. gap: 12px;
  1362. }
  1363. .deliverable {
  1364. min-height: 190px;
  1365. padding: 18px;
  1366. transition: transform 0.34s var(--ease), border-color 0.34s ease, background 0.34s ease, box-shadow 0.34s ease;
  1367. }
  1368. .deliverable:hover {
  1369. transform: translateY(-5px);
  1370. border-color: rgba(0, 240, 255, 0.32);
  1371. background: rgba(255, 255, 255, 0.085);
  1372. box-shadow: 0 18px 46px rgba(0, 0, 0, 0.22);
  1373. }
  1374. .deliverable strong {
  1375. display: block;
  1376. margin: 18px 0 8px;
  1377. font-size: 1.02rem;
  1378. }
  1379. .deliverable span {
  1380. color: var(--muted);
  1381. font-size: 0.88rem;
  1382. }
  1383. .deliverable .mark {
  1384. display: inline-grid;
  1385. place-items: center;
  1386. width: 36px;
  1387. height: 36px;
  1388. border-radius: var(--radius);
  1389. color: #050505;
  1390. background: linear-gradient(135deg, var(--cyan), var(--rose));
  1391. font-weight: 900;
  1392. }
  1393. .split {
  1394. display: grid;
  1395. grid-template-columns: 0.88fr 1.12fr;
  1396. gap: 18px;
  1397. align-items: start;
  1398. }
  1399. .quote {
  1400. position: sticky;
  1401. top: 88px;
  1402. padding: 24px;
  1403. border: 1px solid var(--line);
  1404. border-radius: var(--radius);
  1405. background: linear-gradient(180deg, rgba(0, 240, 255, 0.08), rgba(255, 255, 255, 0.055));
  1406. }
  1407. .quote p {
  1408. font-size: 1.5rem;
  1409. line-height: 1.32;
  1410. font-weight: 760;
  1411. }
  1412. .quote span {
  1413. display: block;
  1414. margin-top: 14px;
  1415. color: var(--muted);
  1416. }
  1417. .share-panel {
  1418. display: grid;
  1419. gap: 12px;
  1420. padding: 18px;
  1421. }
  1422. textarea {
  1423. width: 100%;
  1424. min-height: 360px;
  1425. resize: vertical;
  1426. border: 1px solid var(--line);
  1427. border-radius: var(--radius);
  1428. outline: none;
  1429. padding: 16px;
  1430. background: rgba(0, 0, 0, 0.34);
  1431. color: #f4f8fb;
  1432. line-height: 1.72;
  1433. }
  1434. .copy-row {
  1435. display: flex;
  1436. justify-content: space-between;
  1437. gap: 10px;
  1438. align-items: center;
  1439. }
  1440. .copy-row small {
  1441. color: var(--dim);
  1442. }
  1443. .bottom-cta {
  1444. position: sticky;
  1445. bottom: 0;
  1446. z-index: 60;
  1447. display: none;
  1448. gap: 10px;
  1449. padding: 10px 14px calc(10px + env(safe-area-inset-bottom));
  1450. border-top: 1px solid rgba(255, 255, 255, 0.12);
  1451. background: rgba(5, 5, 5, 0.84);
  1452. backdrop-filter: blur(18px);
  1453. }
  1454. .bottom-cta a {
  1455. flex: 1;
  1456. min-height: 44px;
  1457. }
  1458. .toast {
  1459. position: fixed;
  1460. left: 50%;
  1461. bottom: 86px;
  1462. z-index: 90;
  1463. padding: 9px 12px;
  1464. border-radius: var(--radius);
  1465. background: var(--white);
  1466. color: var(--black);
  1467. font-size: 0.9rem;
  1468. font-weight: 800;
  1469. transform: translate(-50%, 12px);
  1470. opacity: 0;
  1471. pointer-events: none;
  1472. transition: opacity 0.2s ease, transform 0.2s ease;
  1473. }
  1474. .toast.show {
  1475. opacity: 1;
  1476. transform: translate(-50%, 0);
  1477. }
  1478. footer {
  1479. padding: 34px 20px 44px;
  1480. border-top: 1px solid rgba(255, 255, 255, 0.1);
  1481. color: var(--dim);
  1482. background: #050505;
  1483. }
  1484. .footer-inner {
  1485. display: flex;
  1486. align-items: center;
  1487. justify-content: space-between;
  1488. gap: 18px;
  1489. width: min(100%, var(--max));
  1490. margin: 0 auto;
  1491. }
  1492. [data-reveal] {
  1493. opacity: 0;
  1494. transform: translate3d(0, 34px, 0) scale(0.985);
  1495. will-change: opacity, transform;
  1496. transition:
  1497. opacity 0.82s var(--ease),
  1498. transform 0.82s var(--ease),
  1499. border-color 0.34s ease,
  1500. background 0.34s ease,
  1501. box-shadow 0.34s ease;
  1502. }
  1503. [data-reveal="fade-left"] {
  1504. transform: translate3d(-30px, 0, 0) scale(0.992);
  1505. }
  1506. [data-reveal="fade-right"] {
  1507. transform: translate3d(30px, 0, 0) scale(0.992);
  1508. }
  1509. [data-reveal="scale"] {
  1510. transform: translate3d(0, 24px, 0) scale(0.955);
  1511. }
  1512. [data-reveal].visible {
  1513. opacity: 1;
  1514. transform: translate3d(0, 0, 0) scale(1);
  1515. }
  1516. [data-reveal].visible.card:hover,
  1517. [data-reveal].visible.spine-cell:hover,
  1518. [data-reveal].visible.need-chip:hover,
  1519. [data-reveal].visible.capability:hover,
  1520. [data-reveal].visible.platform:hover,
  1521. [data-reveal].visible.deliverable:hover {
  1522. transform: translate3d(0, -6px, 0) scale(1.01);
  1523. }
  1524. [data-delay="1"] { transition-delay: 0.08s; }
  1525. [data-delay="2"] { transition-delay: 0.16s; }
  1526. [data-delay="3"] { transition-delay: 0.24s; }
  1527. [data-delay="4"] { transition-delay: 0.32s; }
  1528. .mobile-safe-mode *,
  1529. .mobile-safe-mode *::before,
  1530. .mobile-safe-mode *::after {
  1531. animation: none !important;
  1532. transition-duration: 0.01ms !important;
  1533. scroll-behavior: auto !important;
  1534. }
  1535. .mobile-safe-mode #networkCanvas,
  1536. .mobile-safe-mode .intro-overlay {
  1537. display: none !important;
  1538. }
  1539. .mobile-safe-mode [data-reveal] {
  1540. opacity: 1 !important;
  1541. transform: none !important;
  1542. }
  1543. @media (max-width: 980px) {
  1544. h1 {
  1545. font-size: 3.1rem;
  1546. }
  1547. h2 {
  1548. font-size: 2.15rem;
  1549. }
  1550. .hero-inner,
  1551. .skill-wall,
  1552. .daily-lab,
  1553. .split {
  1554. grid-template-columns: 1fr;
  1555. }
  1556. .hero-media {
  1557. min-height: 440px;
  1558. }
  1559. .grid.three,
  1560. .grid.four,
  1561. .platform-map,
  1562. .spine-grid,
  1563. .deliverables,
  1564. .need-finder {
  1565. grid-template-columns: repeat(2, minmax(0, 1fr));
  1566. }
  1567. .quote {
  1568. position: static;
  1569. }
  1570. }
  1571. @media (max-width: 720px) {
  1572. #networkCanvas {
  1573. display: none;
  1574. }
  1575. .intro-overlay {
  1576. background: #050505;
  1577. }
  1578. .intro-lockup {
  1579. animation-duration: 0.56s;
  1580. }
  1581. body::after {
  1582. display: none;
  1583. }
  1584. .ticker-track {
  1585. width: max-content;
  1586. animation: mobileMarquee 46s linear infinite;
  1587. will-change: transform;
  1588. }
  1589. .ticker-group {
  1590. flex-wrap: nowrap;
  1591. }
  1592. .brand-mark::after {
  1593. animation: markSheen 7.2s ease-in-out infinite;
  1594. }
  1595. .gradient-text {
  1596. animation: gradientDrift 9s ease-in-out infinite;
  1597. }
  1598. .hero-media::before {
  1599. opacity: 0.72;
  1600. animation: edgeTrace 9s ease-in-out infinite;
  1601. }
  1602. .radar-line {
  1603. top: 12%;
  1604. animation: mobileScan 6.2s var(--ease) infinite;
  1605. will-change: transform, opacity;
  1606. }
  1607. .signal-node {
  1608. animation: mobileFloat 7.2s ease-in-out infinite;
  1609. will-change: transform;
  1610. }
  1611. .signal-node:nth-child(3) { animation-delay: 0.7s; }
  1612. .signal-node:nth-child(4) { animation-delay: 1.4s; }
  1613. .signal-node:nth-child(5) { animation-delay: 2.1s; }
  1614. .bar i {
  1615. animation: mobileBarPulse 5.8s ease-in-out infinite;
  1616. will-change: transform, opacity;
  1617. }
  1618. .skill-rings {
  1619. animation: mobileRingBreathe 8.5s ease-in-out infinite;
  1620. }
  1621. .ring-label {
  1622. animation: mobileLabelFloat 7.6s ease-in-out infinite;
  1623. }
  1624. .ring-label.b { animation-delay: 0.8s; }
  1625. .ring-label.c { animation-delay: 1.6s; }
  1626. .ring-label.d { animation-delay: 2.4s; }
  1627. .pipeline-step {
  1628. animation: mobileStepGlow 7.8s ease-in-out infinite;
  1629. }
  1630. .pipeline-step:nth-child(2) { animation-delay: 0.5s; }
  1631. .pipeline-step:nth-child(3) { animation-delay: 1s; }
  1632. .pipeline-step:nth-child(4) { animation-delay: 1.5s; }
  1633. .pipeline-step:nth-child(5) { animation-delay: 2s; }
  1634. @keyframes mobileScan {
  1635. 0% { opacity: 0; transform: translate3d(0, 0, 0); }
  1636. 15% { opacity: 0.9; }
  1637. 78% { opacity: 0.9; }
  1638. 100% { opacity: 0; transform: translate3d(0, 230px, 0); }
  1639. }
  1640. @keyframes mobileFloat {
  1641. 0%, 100% { transform: translate3d(0, 0, 0); }
  1642. 50% { transform: translate3d(0, -6px, 0); }
  1643. }
  1644. @keyframes mobileBarPulse {
  1645. 0%, 100% { transform: translate3d(-6%, 0, 0); opacity: 0.78; }
  1646. 50% { transform: translate3d(6%, 0, 0); opacity: 1; }
  1647. }
  1648. @keyframes mobileMarquee {
  1649. from { transform: translate3d(0, 0, 0); }
  1650. to { transform: translate3d(-50%, 0, 0); }
  1651. }
  1652. @keyframes mobileRingBreathe {
  1653. 0%, 100% { box-shadow: 0 0 0 rgba(0, 240, 255, 0); border-color: rgba(0, 240, 255, 0.25); }
  1654. 50% { box-shadow: 0 0 34px rgba(0, 240, 255, 0.16); border-color: rgba(255, 82, 82, 0.34); }
  1655. }
  1656. @keyframes mobileLabelFloat {
  1657. 0%, 100% { transform: translate3d(0, 0, 0); }
  1658. 50% { transform: translate3d(0, -4px, 0); }
  1659. }
  1660. @keyframes mobileStepGlow {
  1661. 0%, 100% { border-color: rgba(255, 255, 255, 0.13); background: rgba(5, 5, 5, 0.42); }
  1662. 50% { border-color: rgba(0, 240, 255, 0.3); background: rgba(0, 240, 255, 0.055); }
  1663. }
  1664. .nav,
  1665. .proof-pill,
  1666. .requirement-strip,
  1667. .signal-node,
  1668. .spine-cell,
  1669. .card,
  1670. .slice,
  1671. .timeline-row,
  1672. .deliverable,
  1673. .share-panel,
  1674. .daily-board,
  1675. .bottom-cta {
  1676. -webkit-backdrop-filter: none;
  1677. backdrop-filter: none;
  1678. }
  1679. [data-reveal] {
  1680. transform: translate3d(0, 16px, 0);
  1681. will-change: auto;
  1682. transition-duration: 0.46s;
  1683. }
  1684. [data-reveal="fade-left"],
  1685. [data-reveal="fade-right"],
  1686. [data-reveal="scale"] {
  1687. transform: translate3d(0, 16px, 0);
  1688. }
  1689. .nav-links {
  1690. display: none;
  1691. }
  1692. .nav-inner {
  1693. min-height: 58px;
  1694. padding: 0 14px;
  1695. }
  1696. .brand-name small {
  1697. display: none;
  1698. }
  1699. .hero {
  1700. min-height: auto;
  1701. padding: 40px 16px 22px;
  1702. }
  1703. h1 {
  1704. font-size: 2.38rem;
  1705. }
  1706. h2 {
  1707. font-size: 1.82rem;
  1708. }
  1709. .hero-lead {
  1710. font-size: 1rem;
  1711. }
  1712. .hero-proof,
  1713. .grid.two,
  1714. .grid.three,
  1715. .grid.four,
  1716. .capability-grid,
  1717. .platform-map,
  1718. .spine-grid,
  1719. .deliverables,
  1720. .need-finder,
  1721. .topic-stack {
  1722. grid-template-columns: 1fr;
  1723. }
  1724. .signal-spine {
  1725. padding: 48px 16px 52px;
  1726. }
  1727. .spine-word {
  1728. top: -28px;
  1729. left: 0;
  1730. right: auto;
  1731. font-size: 3.4rem;
  1732. }
  1733. .spine-cell {
  1734. min-height: 170px;
  1735. }
  1736. .requirement-strip {
  1737. grid-template-columns: 1fr;
  1738. }
  1739. .daily-board {
  1740. min-height: auto;
  1741. }
  1742. .pipeline-step {
  1743. grid-template-columns: 1fr;
  1744. }
  1745. .hero-media {
  1746. min-height: 410px;
  1747. }
  1748. .console-bottom {
  1749. grid-template-columns: 1fr;
  1750. }
  1751. .meter {
  1752. padding: 10px;
  1753. }
  1754. .section {
  1755. padding: 58px 16px;
  1756. }
  1757. .timeline-row {
  1758. grid-template-columns: 1fr;
  1759. gap: 8px;
  1760. }
  1761. .skill-rings {
  1762. position: relative;
  1763. right: auto;
  1764. bottom: auto;
  1765. margin: 32px auto 0;
  1766. width: 230px;
  1767. height: 230px;
  1768. }
  1769. .copy-row {
  1770. align-items: stretch;
  1771. flex-direction: column;
  1772. }
  1773. .button {
  1774. width: 100%;
  1775. }
  1776. .bottom-cta {
  1777. display: flex;
  1778. }
  1779. .footer-inner {
  1780. align-items: flex-start;
  1781. flex-direction: column;
  1782. }
  1783. }
  1784. @media (max-width: 390px) {
  1785. h1 {
  1786. font-size: 2.08rem;
  1787. }
  1788. .hero-media {
  1789. min-height: 370px;
  1790. }
  1791. .signal-console {
  1792. inset: 14px;
  1793. }
  1794. .signal-node {
  1795. min-width: 74px;
  1796. font-size: 0.74rem;
  1797. }
  1798. .ticker span {
  1799. font-size: 0.82rem;
  1800. }
  1801. }
  1802. @media (prefers-reduced-motion: reduce) {
  1803. *,
  1804. *::before,
  1805. *::after {
  1806. animation-duration: 0.01ms !important;
  1807. animation-iteration-count: 1 !important;
  1808. scroll-behavior: auto !important;
  1809. transition-duration: 0.01ms !important;
  1810. }
  1811. }
  1812. </style>
  1813. </head>
  1814. <body>
  1815. <canvas id="networkCanvas" aria-hidden="true"></canvas>
  1816. <div class="progress" id="progress"></div>
  1817. <div class="intro-overlay" aria-hidden="true">
  1818. <div class="intro-lockup">
  1819. <strong>VOC.market</strong>
  1820. <span>Social Voice Intelligence Workshop</span>
  1821. <div class="intro-rule"></div>
  1822. </div>
  1823. </div>
  1824. <header class="nav">
  1825. <div class="nav-inner">
  1826. <a class="brand" href="#top" aria-label="VOC.market">
  1827. <span class="brand-mark">V</span>
  1828. <span class="brand-name">VOC.market<small>小红书 x 抖音需求洞察</small></span>
  1829. </a>
  1830. <nav class="nav-links" aria-label="页面导航">
  1831. <a href="#capability">课程能力</a>
  1832. <a href="#daily">口播日报</a>
  1833. <a href="#schedule">课程安排</a>
  1834. <a href="#deliverables">现场交付</a>
  1835. </nav>
  1836. </div>
  1837. </header>
  1838. <main id="top">
  1839. <section class="hero">
  1840. <div class="hero-inner">
  1841. <div class="hero-copy" data-reveal>
  1842. <div class="eyebrow">南昌本地 · 小红书 + 抖音 · 社媒 VOC 线下工作坊</div>
  1843. <h1>1天学会从评论里找用户需求,<span class="gradient-text">再做成选题和报告</span></h1>
  1844. <p class="hero-lead">VOC 就是“用户真实声音”。这堂课聚焦小红书和抖音:看大家怎么搜、怎么问、怎么吐槽、怎么夸,再把这些评论变成产品卖点、内容选题和一份可汇报的需求洞察。</p>
  1845. <div class="hero-actions">
  1846. <a class="button primary" href="#schedule">看这一天学什么</a>
  1847. <a class="button" href="#daily">看抖音选题日报</a>
  1848. </div>
  1849. <div class="hero-proof" aria-label="课程关键信息">
  1850. <div class="proof-pill">
  1851. <strong>2个平台</strong>
  1852. <span>小红书 + 抖音重点实操</span>
  1853. </div>
  1854. <div class="proof-pill">
  1855. <strong>5月28日下午</strong>
  1856. <span>安装环境,配好龙虾技能</span>
  1857. </div>
  1858. <div class="proof-pill">
  1859. <strong>5月29日全天</strong>
  1860. <span>做 VOC 分析、选题和报告</span>
  1861. </div>
  1862. </div>
  1863. <div class="requirement-strip" data-reveal data-delay="1">
  1864. <div class="requirement-badge">REQ</div>
  1865. <div>
  1866. <b>参会要求:请提前下载并安装好龙虾</b>
  1867. <span>5月28日下午会帮你把小红书/抖音采集技能配置好,确保 5月29日全天实战能跟着老师一起跑。</span>
  1868. </div>
  1869. </div>
  1870. </div>
  1871. <div class="hero-media" data-reveal data-delay="2" data-tilt>
  1872. <img src="https://images.unsplash.com/photo-1551288049-bebda4e38f71?auto=format&fit=crop&w=1400&q=82" alt="社媒数据分析工作台">
  1873. <div class="signal-console">
  1874. <div class="console-top">
  1875. <span class="console-dots" aria-hidden="true"><span></span><span></span><span></span></span>
  1876. <span>VOC.market / 小红书 x 抖音需求雷达</span>
  1877. </div>
  1878. <div class="radar" aria-label="社媒信号雷达">
  1879. <div class="radar-line"></div>
  1880. <div class="signal-node">抖音<small>视频 / 评论 / 回复</small></div>
  1881. <div class="signal-node">小红书<small>笔记 / 评论 / 搜索词</small></div>
  1882. <div class="signal-node">用户需求<small>痛点 / 阻碍 / 场景</small></div>
  1883. <div class="signal-node">选题报告<small>内容 / 卖点 / 动作</small></div>
  1884. </div>
  1885. <div class="console-bottom">
  1886. <div class="meter"><span>内容信号</span><div class="bar"><i></i></div></div>
  1887. <div class="meter"><span>用户情绪</span><div class="bar"><i></i></div></div>
  1888. <div class="meter"><span>行动优先级</span><div class="bar"><i></i></div></div>
  1889. </div>
  1890. </div>
  1891. </div>
  1892. </div>
  1893. </section>
  1894. <section class="ticker" aria-label="支持平台与能力">
  1895. <div class="ticker-track">
  1896. <div class="ticker-group">
  1897. <span>小红书笔记 / 评论 / 搜索词</span>
  1898. <span>抖音视频 / 评论 / 热评回复</span>
  1899. <span>从评论里找真实需求</span>
  1900. <span>把需求变成内容选题</span>
  1901. <span>生成可汇报的 VOC 报告</span>
  1902. <span>douyin-speaking-daily 每日选题雷达</span>
  1903. <span>口播逐字稿 / 爆款结构拆解</span>
  1904. <span>HTML VOC 报告 / 交付审计</span>
  1905. </div>
  1906. <div class="ticker-group" aria-hidden="true">
  1907. <span>小红书笔记 / 评论 / 搜索词</span>
  1908. <span>抖音视频 / 评论 / 热评回复</span>
  1909. <span>从评论里找真实需求</span>
  1910. <span>把需求变成内容选题</span>
  1911. <span>生成可汇报的 VOC 报告</span>
  1912. <span>douyin-speaking-daily 每日选题雷达</span>
  1913. <span>口播逐字稿 / 爆款结构拆解</span>
  1914. <span>HTML VOC 报告 / 交付审计</span>
  1915. </div>
  1916. </div>
  1917. </section>
  1918. <section class="signal-spine" aria-label="社媒 VOC 工作流">
  1919. <div class="spine-inner">
  1920. <div class="spine-word">COMMENT TO INSIGHT</div>
  1921. <div class="spine-grid">
  1922. <div class="spine-cell" data-reveal>
  1923. <em>01 / 搜内容</em>
  1924. <strong>先找到相关笔记和视频</strong>
  1925. <span>围绕你的产品、品类和竞品,在小红书、抖音里找到用户正在看的内容。</span>
  1926. <b>01</b>
  1927. </div>
  1928. <div class="spine-cell" data-reveal data-delay="1">
  1929. <em>02 / 看评论</em>
  1930. <strong>再看大家到底在问什么</strong>
  1931. <span>高赞评论、追问、吐槽和回复,往往比标题更接近真实需求。</span>
  1932. <b>02</b>
  1933. </div>
  1934. <div class="spine-cell" data-reveal data-delay="2">
  1935. <em>03 / 找需求</em>
  1936. <strong>把评论整理成需求清单</strong>
  1937. <span>用户为什么想买、为什么犹豫、在什么场景使用,现场一步步拆出来。</span>
  1938. <b>03</b>
  1939. </div>
  1940. <div class="spine-cell" data-reveal data-delay="3">
  1941. <em>04 / 做结果</em>
  1942. <strong>变成选题、卖点和报告</strong>
  1943. <span>最后输出内容选题、口播方向、产品卖点和一份可汇报的 VOC 报告。</span>
  1944. <b>04</b>
  1945. </div>
  1946. </div>
  1947. </div>
  1948. </section>
  1949. <section class="section">
  1950. <div class="wrap">
  1951. <div class="section-head center" data-reveal>
  1952. <div class="section-kicker">这堂课到底解决什么</div>
  1953. <h2>看懂小红书和抖音评论,你就能更快知道用户想要什么。</h2>
  1954. <p class="sub">很多团队每天刷内容,却没有把评论区里的问题整理成需求。这堂课会用龙虾帮你把“刷到的内容”变成“能指导产品和内容的证据”。</p>
  1955. </div>
  1956. <div class="grid four">
  1957. <article class="card" data-reveal>
  1958. <span class="index">01</span>
  1959. <h3>内容很多,看不过来</h3>
  1960. <p>同一个品类每天都有大量笔记和视频,靠人工刷很容易漏掉重要信号。</p>
  1961. </article>
  1962. <article class="card" data-reveal data-delay="1">
  1963. <span class="index rose">02</span>
  1964. <h3>评论里才有真实问题</h3>
  1965. <p>用户会在评论里问价格、效果、适不适合自己,也会说出不买的原因。</p>
  1966. </article>
  1967. <article class="card" data-reveal data-delay="2">
  1968. <span class="index amber">03</span>
  1969. <h3>爆款不能只靠照抄</h3>
  1970. <p>要知道它为什么能火:开头怎么抓人、哪里解决顾虑、评论为什么愿意互动。</p>
  1971. </article>
  1972. <article class="card" data-reveal data-delay="3">
  1973. <span class="index green">04</span>
  1974. <h3>结论要有证据</h3>
  1975. <p>每个需求、卖点和选题都要能回到原始评论,不做拍脑袋的判断。</p>
  1976. </article>
  1977. </div>
  1978. <div class="need-finder" aria-label="社媒 VOC 需求发现路径">
  1979. <div class="need-chip" data-reveal>
  1980. <strong>评论找需求</strong>
  1981. <span>把“想要、担心、不会用、太贵、有没有替代品”转成需求和购买阻碍。</span>
  1982. </div>
  1983. <div class="need-chip" data-reveal data-delay="1">
  1984. <strong>回复找证据</strong>
  1985. <span>热评下的追问和反驳,是判断需求强弱和人群分层的关键证据。</span>
  1986. </div>
  1987. <div class="need-chip" data-reveal data-delay="2">
  1988. <strong>账号找节奏</strong>
  1989. <span>监听竞品、达人和标杆账号,看到内容节奏、选题方向和转化动作。</span>
  1990. </div>
  1991. <div class="need-chip" data-reveal data-delay="3">
  1992. <strong>爆款找结构</strong>
  1993. <span>从逐字稿拆钩子、冲突、证明点和评论触发点,迁移成自己的口播框架。</span>
  1994. </div>
  1995. </div>
  1996. </div>
  1997. </section>
  1998. <section class="section alt" id="capability">
  1999. <div class="wrap">
  2000. <div class="skill-wall">
  2001. <div class="slice" data-reveal>
  2002. <div class="section-kicker">Capability Stack</div>
  2003. <h3>我们现场讲的不是一个工具,而是一条已经技能化的社媒 VOC 生产线。</h3>
  2004. <p>从技能配置、采集、归一化、洞察、口播日报到 HTML 报告,课程会把可交付的能力拆成学员能看懂、能复制、能回公司继续用的流程。</p>
  2005. <div class="skill-rings" aria-hidden="true">
  2006. <span class="ring-label a">采集</span>
  2007. <span class="ring-label b">理解</span>
  2008. <span class="ring-label c">报告</span>
  2009. <span class="ring-label d">行动</span>
  2010. </div>
  2011. </div>
  2012. <div class="capability-grid">
  2013. <div class="capability" data-reveal data-delay="1">
  2014. <strong>小红书/抖音采集</strong>
  2015. <span>正课优先跑通小红书和抖音:关键词搜索、笔记/视频详情、评论、热评回复、账号内容。</span>
  2016. </div>
  2017. <div class="capability" data-reveal data-delay="2">
  2018. <strong>账号与话题监听</strong>
  2019. <span>围绕关键词、竞品账号、达人内容和话题讨论持续观察,沉淀内容节奏、互动表现和需求变化。</span>
  2020. </div>
  2021. <div class="capability" data-reveal data-delay="3">
  2022. <strong>douyin-speaking-daily</strong>
  2023. <span>关键词监听、账号作品监听、评论采集、可选逐字稿补跑、每日选题日报、脚本共创和偏好沉淀。</span>
  2024. </div>
  2025. <div class="capability" data-reveal data-delay="4">
  2026. <strong>报告与审计</strong>
  2027. <span>VOC 数据归一化、mini report、HTML v2 报告生成、证据卡、行动建议和交付前审计。</span>
  2028. </div>
  2029. </div>
  2030. </div>
  2031. </div>
  2032. </section>
  2033. <section class="section" id="daily">
  2034. <div class="wrap daily-lab">
  2035. <div class="daily-copy" data-reveal>
  2036. <div class="section-head">
  2037. <div class="section-kicker">douyin-speaking-daily</div>
  2038. <h2>把抖音变成每天可刷新的口播选题雷达。</h2>
  2039. <p class="sub">这条能力适合讲给内容团队和老板听:不是“我今天想发什么”,而是“今天用户和竞品正在把什么问题推到台前”。</p>
  2040. </div>
  2041. <div class="daily-points">
  2042. <div class="daily-point">
  2043. <b>01</b>
  2044. <div>
  2045. <strong>先建立账号 profile</strong>
  2046. <span>行业、人群、账号定位、转化目标、禁忌表达和历史偏好先沉淀,后续选题不跑偏。</span>
  2047. </div>
  2048. </div>
  2049. <div class="daily-point">
  2050. <b>02</b>
  2051. <div>
  2052. <strong>再跑关键词与账号监听</strong>
  2053. <span>关键词视频、确认账号近期作品、评论和回复一起看,找到需求和内容机会。</span>
  2054. </div>
  2055. </div>
  2056. <div class="daily-point">
  2057. <b>03</b>
  2058. <div>
  2059. <strong>最后进入脚本共创</strong>
  2060. <span>选题 N、改稿、定稿都能续接同一次日报,把爆款结构迁移成自己的口播稿。</span>
  2061. </div>
  2062. </div>
  2063. </div>
  2064. </div>
  2065. <div class="daily-board" data-reveal data-delay="2" data-tilt>
  2066. <div class="board-inner">
  2067. <div class="board-header">
  2068. <div class="board-title">
  2069. <strong>Daily Speaking Radar</strong>
  2070. <span>runner -> report -> script co-creation</span>
  2071. </div>
  2072. <span class="board-status">P0 closed loop</span>
  2073. </div>
  2074. <div class="pipeline">
  2075. <div class="pipeline-step">
  2076. <code>profile</code>
  2077. <div>
  2078. <strong>账号定位与转化目标</strong>
  2079. <span>读取行业、人群、话术边界和脚本偏好。</span>
  2080. </div>
  2081. <i>1</i>
  2082. </div>
  2083. <div class="pipeline-step">
  2084. <code>monitor</code>
  2085. <div>
  2086. <strong>关键词 + 账号作品监听</strong>
  2087. <span>抓取爆款视频、竞品账号近期作品和互动证据。</span>
  2088. </div>
  2089. <i>2</i>
  2090. </div>
  2091. <div class="pipeline-step">
  2092. <code>comments</code>
  2093. <div>
  2094. <strong>评论 / 回复需求信号</strong>
  2095. <span>从高赞评论、追问和反驳里识别痛点、阻碍和场景。</span>
  2096. </div>
  2097. <i>3</i>
  2098. </div>
  2099. <div class="pipeline-step">
  2100. <code>transcript</code>
  2101. <div>
  2102. <strong>可选补跑逐字稿</strong>
  2103. <span>拆开头、冲突、证明点、结尾动作和评论触发点。</span>
  2104. </div>
  2105. <i>4</i>
  2106. </div>
  2107. <div class="pipeline-step">
  2108. <code>daily report</code>
  2109. <div>
  2110. <strong>今日选题池与共创稿</strong>
  2111. <span>输出选题置信度、可讲方向、60 秒稿和定稿沉淀。</span>
  2112. </div>
  2113. <i>5</i>
  2114. </div>
  2115. </div>
  2116. <div class="topic-stack">
  2117. <div class="topic-card">
  2118. <small>TOPIC 01 / 高置信</small>
  2119. <strong>用户不是不买,是不确定它适不适合自己</strong>
  2120. <span>评论证据:反复询问场景、预算和替代方案。</span>
  2121. </div>
  2122. <div class="topic-card">
  2123. <small>TOPIC 02 / 可转化</small>
  2124. <strong>把专家术语翻译成真实使用场景</strong>
  2125. <span>逐字稿证据:爆款用冲突开场,再用案例证明。</span>
  2126. </div>
  2127. <div class="topic-card">
  2128. <small>TOPIC 03 / 明日监听</small>
  2129. <strong>竞品新内容评论区出现同类追问</strong>
  2130. <span>账号证据:近期作品互动集中在购买阻碍。</span>
  2131. </div>
  2132. </div>
  2133. </div>
  2134. </div>
  2135. </div>
  2136. </section>
  2137. <section class="section">
  2138. <div class="wrap">
  2139. <div class="section-head" data-reveal>
  2140. <div class="section-kicker">Platform Map</div>
  2141. <h2>聚焦小红书和抖音,把“内容”和“评论”整理成需求证据。</h2>
  2142. <p class="sub">学员不用背 API 名称,只需要理解:搜什么内容、看哪些评论、怎么判断需求、最后怎么变成选题和报告。</p>
  2143. </div>
  2144. <div class="platform-map">
  2145. <div class="platform" data-reveal>
  2146. <b>抖音</b>
  2147. <span>关键词视频、话题、视频详情、评论、回复、账号主页、近期作品、逐字稿和口播结构。</span>
  2148. </div>
  2149. <div class="platform" data-reveal data-delay="1">
  2150. <b>小红书</b>
  2151. <span>关键词笔记、笔记详情、评论、作者信息,适合测评、种草、痛点和生活方式洞察。</span>
  2152. </div>
  2153. <div class="platform" data-reveal data-delay="2">
  2154. <b>热评回复</b>
  2155. <span>重点看高赞评论下面的追问、反驳和补充,判断需求是不是足够真实。</span>
  2156. </div>
  2157. <div class="platform" data-reveal data-delay="3">
  2158. <b>竞品账号</b>
  2159. <span>观察竞品和达人近期内容,找出他们正在解决的问题和评论区的新机会。</span>
  2160. </div>
  2161. <div class="platform" data-reveal>
  2162. <b>话题与关键词</b>
  2163. <span>把平台热词、搜索词、评论词和用户原话统一到采集矩阵,避免只看单一爆款。</span>
  2164. </div>
  2165. <div class="platform" data-reveal data-delay="1">
  2166. <b>评论与回复</b>
  2167. <span>把高赞评论、追问、反驳、复购表达转成需求、阻碍、证据和内容钩子。</span>
  2168. </div>
  2169. <div class="platform" data-reveal data-delay="2">
  2170. <b>账号监听</b>
  2171. <span>确认竞品/达人账号,持续观察近期作品和评论变化,形成每日选题雷达。</span>
  2172. </div>
  2173. <div class="platform" data-reveal data-delay="3">
  2174. <b>报告工厂</b>
  2175. <span>把小红书和抖音样本合并到同一 VOC 结构里,输出 HTML 报告、审计结果和行动清单。</span>
  2176. </div>
  2177. </div>
  2178. </div>
  2179. </section>
  2180. <section class="section alt" id="schedule">
  2181. <div class="wrap">
  2182. <div class="section-head" data-reveal>
  2183. <div class="section-kicker">Workshop Flow</div>
  2184. <h2>5月28日下午安装环境,5月29日全天做 VOC 分析实战。</h2>
  2185. <p class="sub">南昌本地线下工作坊。5月29日全程用真实业务问题操作,建议每位学员带一个自己的品牌、品类、竞品账号或口播账号方向。</p>
  2186. </div>
  2187. <div class="timeline">
  2188. <article class="timeline-row" data-reveal>
  2189. <div class="time">5月28日下午<br>安装环境</div>
  2190. <div>
  2191. <h3>下载并安装 OpenClaw(龙虾),现场配置社媒 VOC 技能</h3>
  2192. <p>这半天重点不是讲理论,而是把 VOC Token、社媒采集技能、douyin-speaking-daily、工作区和样例项目配置到能跑,为第二天全天实战做好准备。</p>
  2193. <div class="tags">
  2194. <span>参会前下载 OpenClaw</span>
  2195. <span>配置 VOC Token</span>
  2196. <span>配置社媒技能包</span>
  2197. <span>跑通 douyin-speaking-daily Demo</span>
  2198. </div>
  2199. </div>
  2200. </article>
  2201. <article class="timeline-row" data-reveal data-delay="1">
  2202. <div class="time">5月29日上午<br>VOC 需求发现</div>
  2203. <div>
  2204. <h3>从业务问题出发,用社媒找真实 VOC 需求</h3>
  2205. <p>现场跑抖音/小红书主线,并讲清社媒采集的同构方法:如何找关键词、如何选样本、如何从评论/回复里判断需求强度。</p>
  2206. <div class="tags">
  2207. <span>小红书/抖音采集思路</span>
  2208. <span>抖音视频与评论</span>
  2209. <span>小红书笔记与评论</span>
  2210. <span>需求 / 阻碍 / 场景证据</span>
  2211. </div>
  2212. </div>
  2213. </article>
  2214. <article class="timeline-row" data-reveal data-delay="2">
  2215. <div class="time">5月29日下午<br>口播日报与报告</div>
  2216. <div>
  2217. <h3>用 douyin-speaking-daily 生成选题雷达,再输出 VOC 报告</h3>
  2218. <p>用评论证据生成 VOC 洞察,用逐字稿和爆款结构拆出可复用口播框架,再把结论落到产品、内容、投放和销售动作。</p>
  2219. <div class="tags">
  2220. <span>每日选题日报</span>
  2221. <span>VOC 数据归一化</span>
  2222. <span>痛点/场景/阻碍聚类</span>
  2223. <span>HTML 报告与审计</span>
  2224. </div>
  2225. </div>
  2226. </article>
  2227. <article class="timeline-row" data-reveal data-delay="3">
  2228. <div class="time">5月29日收尾<br>现场交付</div>
  2229. <div>
  2230. <h3>每组交付一套自己的社媒 VOC 工作样板</h3>
  2231. <p>不是听完就散,而是现场验收技能配置、采集矩阵、证据包、洞察报告、口播选题和下一步行动清单。</p>
  2232. <div class="tags">
  2233. <span>技能配置完成</span>
  2234. <span>采集矩阵</span>
  2235. <span>证据卡</span>
  2236. <span>洞察报告</span>
  2237. </div>
  2238. </div>
  2239. </article>
  2240. </div>
  2241. </div>
  2242. </section>
  2243. <section class="section" id="deliverables">
  2244. <div class="wrap">
  2245. <div class="section-head center" data-reveal>
  2246. <div class="section-kicker">Deliverables</div>
  2247. <h2>现场带走 6 份能继续工作的资产。</h2>
  2248. <p class="sub">我们把交付物设计成企业内部可复盘、可协作、可继续迭代的格式。</p>
  2249. </div>
  2250. <div class="deliverables">
  2251. <div class="deliverable" data-reveal>
  2252. <span class="mark">1</span>
  2253. <strong>技能配置完成</strong>
  2254. <span>龙虾、VOC Token、社媒采集技能和 douyin-speaking-daily 跑通。</span>
  2255. </div>
  2256. <div class="deliverable" data-reveal data-delay="1">
  2257. <span class="mark">2</span>
  2258. <strong>社媒采集矩阵</strong>
  2259. <span>平台、关键词、账号、话题、样本量、采集目的和风险边界。</span>
  2260. </div>
  2261. <div class="deliverable" data-reveal data-delay="2">
  2262. <span class="mark">3</span>
  2263. <strong>用户原声证据包</strong>
  2264. <span>视频/笔记/评论/回复来源清晰,能回溯,不靠拍脑袋。</span>
  2265. </div>
  2266. <div class="deliverable" data-reveal data-delay="3">
  2267. <span class="mark">4</span>
  2268. <strong>社媒 VOC 报告</strong>
  2269. <span>痛点、场景、阻碍、卖点、内容机会和行动建议。</span>
  2270. </div>
  2271. <div class="deliverable" data-reveal data-delay="4">
  2272. <span class="mark">5</span>
  2273. <strong>口播日报与选题池</strong>
  2274. <span>每日趋势判断、选题置信度、60 秒稿和可复用结构框架。</span>
  2275. </div>
  2276. <div class="deliverable" data-reveal data-delay="4">
  2277. <span class="mark">6</span>
  2278. <strong>行动优先级清单</strong>
  2279. <span>产品优化、内容选题、投放测试、账号监听的下一步。</span>
  2280. </div>
  2281. </div>
  2282. </div>
  2283. </section>
  2284. <section class="section alt">
  2285. <div class="wrap split">
  2286. <div class="quote" data-reveal>
  2287. <p>适合真正想把社媒数据变成增长动作的人。</p>
  2288. <span>企业主、品牌负责人、产品负责人、内容/运营/增长团队,都能带着自己的业务问题来。</span>
  2289. </div>
  2290. <div class="grid two">
  2291. <article class="card" data-reveal data-delay="1">
  2292. <span class="index">A</span>
  2293. <h3>推荐参加</h3>
  2294. <ul class="list">
  2295. <li>正在做小红书、抖音的品牌和内容团队。</li>
  2296. <li>想从评论区、竞品账号和爆款视频中提炼产品/内容机会的人。</li>
  2297. <li>需要把 AI 工作流变成团队 SOP 和客户交付能力的顾问/服务商。</li>
  2298. <li>希望从“会用 AI”升级为“能用 AI 交付报告和策略”的业务负责人。</li>
  2299. </ul>
  2300. </article>
  2301. <article class="card" data-reveal data-delay="2">
  2302. <span class="index rose">B</span>
  2303. <h3>报名准备</h3>
  2304. <ul class="list">
  2305. <li>参会前请提前下载并安装好 OpenClaw(龙虾)。</li>
  2306. <li>请务必带电脑,全程实操。</li>
  2307. <li>建议提前准备一个品类、品牌、竞品、达人或口播账号方向。</li>
  2308. <li>5月28日下午统一安装环境、配置 VOC Token 和社媒 VOC 技能。</li>
  2309. <li>真实项目涉及敏感数据时,课堂可用脱敏关键词和公开样本。</li>
  2310. </ul>
  2311. </article>
  2312. <article class="card" data-reveal data-delay="3">
  2313. <span class="index amber">C</span>
  2314. <h3>活动信息</h3>
  2315. <ul class="list">
  2316. <li>形式:南昌本地线下工作坊。</li>
  2317. <li>时间:5月28日下午安装环境,5月29日全天 VOC 分析实战。</li>
  2318. <li>人数:建议 30 人以内,方便现场辅导。</li>
  2319. <li>地点:南昌本地场地,具体位置另行同步。</li>
  2320. <li>费用:以最终通知为准。</li>
  2321. </ul>
  2322. </article>
  2323. <article class="card" data-reveal data-delay="4">
  2324. <span class="index green">D</span>
  2325. <h3>品牌背书</h3>
  2326. <ul class="list">
  2327. <li>VOC.market 企业级 VOC 智能工厂方法论。</li>
  2328. <li>OpenClaw 龙虾技能包驱动,覆盖采集、分析、报告和审计。</li>
  2329. <li>小红书/抖音内容、用户评论和热评回复可组合成可追溯洞察。</li>
  2330. <li>目标不是一次性报告,而是训练团队拥有持续情报能力。</li>
  2331. </ul>
  2332. </article>
  2333. </div>
  2334. </div>
  2335. </section>
  2336. </main>
  2337. <nav class="bottom-cta" aria-label="底部导航">
  2338. <a class="button" href="#schedule">课程安排</a>
  2339. <a class="button primary" href="#deliverables">现场交付</a>
  2340. </nav>
  2341. <footer>
  2342. <div class="footer-inner">
  2343. <div class="brand">
  2344. <span class="brand-mark">V</span>
  2345. <span class="brand-name">VOC.market<small>VOC 为先 · 内容为王 · 增长为果</small></span>
  2346. </div>
  2347. <span>社媒 VOC 龙虾工作坊单页初稿</span>
  2348. </div>
  2349. </footer>
  2350. <div class="toast" id="toast">已复制</div>
  2351. <script>
  2352. const progress = document.getElementById("progress");
  2353. const revealItems = document.querySelectorAll("[data-reveal]");
  2354. const toast = document.getElementById("toast");
  2355. const introOverlay = document.querySelector(".intro-overlay");
  2356. const nav = document.querySelector(".nav");
  2357. const sectionBlocks = document.querySelectorAll(".section, .signal-spine, .hero");
  2358. const canvas = document.getElementById("networkCanvas");
  2359. const ctx = canvas ? canvas.getContext("2d") : null;
  2360. const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
  2361. const isTouchLike = window.matchMedia("(hover: none), (pointer: coarse)").matches;
  2362. const isMobileSafeMode = document.documentElement.classList.contains("mobile-safe-mode");
  2363. function updateProgress() {
  2364. const scrollTop = window.scrollY || document.documentElement.scrollTop;
  2365. const maxScroll = document.documentElement.scrollHeight - window.innerHeight;
  2366. const pct = maxScroll > 0 ? (scrollTop / maxScroll) * 100 : 0;
  2367. if (progress) progress.style.width = pct + "%";
  2368. if (nav) nav.classList.toggle("is-scrolled", scrollTop > 12);
  2369. }
  2370. revealItems.forEach((item, index) => {
  2371. if (!item.getAttribute("data-reveal")) {
  2372. if (item.matches(".hero-media, .daily-board, .share-panel, .quote")) {
  2373. item.setAttribute("data-reveal", "scale");
  2374. } else if (item.matches(".section-head, .daily-copy, .slice")) {
  2375. item.setAttribute("data-reveal", "fade-left");
  2376. } else if (index % 3 === 1) {
  2377. item.setAttribute("data-reveal", "fade-right");
  2378. } else if (index % 3 === 2) {
  2379. item.setAttribute("data-reveal", "scale");
  2380. }
  2381. }
  2382. });
  2383. if (isMobileSafeMode) {
  2384. revealItems.forEach((item) => item.classList.add("visible"));
  2385. sectionBlocks.forEach((item) => item.classList.add("section-active"));
  2386. } else if ("IntersectionObserver" in window) {
  2387. const revealObserver = new IntersectionObserver((entries) => {
  2388. entries.forEach((entry) => {
  2389. if (entry.isIntersecting) {
  2390. entry.target.classList.add("visible");
  2391. revealObserver.unobserve(entry.target);
  2392. }
  2393. });
  2394. }, { threshold: 0.12, rootMargin: "0px 0px -60px 0px" });
  2395. revealItems.forEach((item) => revealObserver.observe(item));
  2396. const sectionObserver = new IntersectionObserver((entries) => {
  2397. entries.forEach((entry) => {
  2398. entry.target.classList.toggle("section-active", entry.isIntersecting);
  2399. });
  2400. }, { threshold: 0.18, rootMargin: "-12% 0px -58% 0px" });
  2401. sectionBlocks.forEach((item) => sectionObserver.observe(item));
  2402. } else {
  2403. revealItems.forEach((item) => item.classList.add("visible"));
  2404. sectionBlocks.forEach((item) => item.classList.add("section-active"));
  2405. }
  2406. function showToast(message) {
  2407. toast.textContent = message;
  2408. toast.classList.add("show");
  2409. window.setTimeout(() => toast.classList.remove("show"), 1800);
  2410. }
  2411. function setupTilt() {
  2412. if (prefersReducedMotion || isTouchLike) return;
  2413. document.querySelectorAll("[data-tilt]").forEach((el) => {
  2414. el.addEventListener("mousemove", (event) => {
  2415. const rect = el.getBoundingClientRect();
  2416. const x = (event.clientX - rect.left) / rect.width - 0.5;
  2417. const y = (event.clientY - rect.top) / rect.height - 0.5;
  2418. el.style.transform = `perspective(900px) rotateY(${x * 5}deg) rotateX(${y * -5}deg)`;
  2419. });
  2420. el.addEventListener("mouseleave", () => {
  2421. el.style.transform = "perspective(900px) rotateY(0deg) rotateX(0deg)";
  2422. });
  2423. });
  2424. }
  2425. let nodes = [];
  2426. let animationId = null;
  2427. let networkStarted = false;
  2428. function shouldRunNetwork() {
  2429. return Boolean(ctx) && !prefersReducedMotion && !isMobileSafeMode && !isTouchLike && window.innerWidth >= 760;
  2430. }
  2431. function stopNetwork() {
  2432. if (animationId) {
  2433. cancelAnimationFrame(animationId);
  2434. animationId = null;
  2435. }
  2436. networkStarted = false;
  2437. if (ctx) ctx.clearRect(0, 0, window.innerWidth, window.innerHeight);
  2438. }
  2439. function resizeCanvas() {
  2440. if (!ctx || !canvas) return;
  2441. const ratio = window.devicePixelRatio || 1;
  2442. canvas.width = Math.floor(window.innerWidth * ratio);
  2443. canvas.height = Math.floor(window.innerHeight * ratio);
  2444. canvas.style.width = window.innerWidth + "px";
  2445. canvas.style.height = window.innerHeight + "px";
  2446. ctx.setTransform(ratio, 0, 0, ratio, 0, 0);
  2447. createNodes();
  2448. }
  2449. function createNodes() {
  2450. const mobile = window.innerWidth < 720;
  2451. const count = mobile
  2452. ? Math.min(24, Math.max(12, Math.floor(window.innerWidth / 38)))
  2453. : Math.min(58, Math.max(24, Math.floor(window.innerWidth / 26)));
  2454. nodes = Array.from({ length: count }, () => ({
  2455. x: Math.random() * window.innerWidth,
  2456. y: Math.random() * window.innerHeight,
  2457. vx: (Math.random() - 0.5) * (mobile ? 0.22 : 0.36),
  2458. vy: (Math.random() - 0.5) * (mobile ? 0.22 : 0.36),
  2459. r: Math.random() * 1.6 + 0.6
  2460. }));
  2461. }
  2462. function drawNetwork() {
  2463. if (!ctx || !shouldRunNetwork()) {
  2464. stopNetwork();
  2465. return;
  2466. }
  2467. ctx.clearRect(0, 0, window.innerWidth, window.innerHeight);
  2468. const mobile = window.innerWidth < 720;
  2469. const connectDistance = mobile ? 104 : 132;
  2470. nodes.forEach((node, index) => {
  2471. node.x += node.vx;
  2472. node.y += node.vy;
  2473. if (node.x < 0 || node.x > window.innerWidth) node.vx *= -1;
  2474. if (node.y < 0 || node.y > window.innerHeight) node.vy *= -1;
  2475. ctx.beginPath();
  2476. ctx.arc(node.x, node.y, node.r, 0, Math.PI * 2);
  2477. ctx.fillStyle = mobile ? "rgba(0, 240, 255, 0.38)" : "rgba(0, 240, 255, 0.5)";
  2478. ctx.fill();
  2479. for (let j = index + 1; j < nodes.length; j++) {
  2480. const other = nodes[j];
  2481. const dx = node.x - other.x;
  2482. const dy = node.y - other.y;
  2483. const dist = Math.sqrt(dx * dx + dy * dy);
  2484. if (dist < connectDistance) {
  2485. ctx.beginPath();
  2486. ctx.moveTo(node.x, node.y);
  2487. ctx.lineTo(other.x, other.y);
  2488. ctx.strokeStyle = `rgba(255, 255, 255, ${0.13 * (1 - dist / connectDistance)})`;
  2489. ctx.lineWidth = 1;
  2490. ctx.stroke();
  2491. }
  2492. }
  2493. });
  2494. animationId = requestAnimationFrame(drawNetwork);
  2495. }
  2496. function startNetwork() {
  2497. if (networkStarted || !shouldRunNetwork()) return;
  2498. networkStarted = true;
  2499. resizeCanvas();
  2500. drawNetwork();
  2501. }
  2502. function finishIntro() {
  2503. if (!introOverlay || introOverlay.classList.contains("is-gone")) {
  2504. startNetwork();
  2505. return;
  2506. }
  2507. introOverlay.classList.add("is-hiding");
  2508. window.setTimeout(() => {
  2509. introOverlay.classList.add("is-gone");
  2510. startNetwork();
  2511. }, prefersReducedMotion ? 20 : 440);
  2512. }
  2513. window.addEventListener("scroll", updateProgress, { passive: true });
  2514. window.addEventListener("resize", () => {
  2515. if (shouldRunNetwork()) {
  2516. if (networkStarted) resizeCanvas();
  2517. else startNetwork();
  2518. } else {
  2519. stopNetwork();
  2520. }
  2521. }, { passive: true });
  2522. document.addEventListener("visibilitychange", () => {
  2523. if (document.hidden) stopNetwork();
  2524. else startNetwork();
  2525. });
  2526. setupTilt();
  2527. updateProgress();
  2528. if (document.readyState === "complete") {
  2529. window.setTimeout(finishIntro, prefersReducedMotion ? 0 : (window.innerWidth < 720 ? 420 : 820));
  2530. } else {
  2531. window.addEventListener("load", () => {
  2532. window.setTimeout(finishIntro, prefersReducedMotion ? 0 : (window.innerWidth < 720 ? 420 : 820));
  2533. }, { once: true });
  2534. }
  2535. window.setTimeout(finishIntro, prefersReducedMotion ? 0 : 1800);
  2536. window.addEventListener("beforeunload", () => {
  2537. if (animationId) cancelAnimationFrame(animationId);
  2538. });
  2539. </script>
  2540. </body>
  2541. </html>