diff --git a/index.html b/index.html index 6ad3035..8873242 100644 --- a/index.html +++ b/index.html @@ -26,15 +26,21 @@

-
+
- 👋Social Media, + 👋Social Media,
Back to the People.
-

Join a decentralized social network where you control your data and connect freely. Experience a platform built on individual Sovereignty and community collaboration.

+

+ Join a decentralized social network where you control your data and connect freely. +
+ Experience a platform built on individual + Sovereignty + and community collaboration. +

-

-
- -
-
Where Users Reign Supreme in the Digital Realm
+
+ +
+
+ Where Users Reign Supreme in the Digital Realm +

- Each user possesses an independent server (Canister) deployed on a decentralized cloud computing network. Entirely controlled by the user's private key, it securely stores personal information. This ensures exceptional responsiveness and an outstanding user experience. + Each user possesses an independent server (Canister) deployed on a decentralized cloud computing network. + Entirely controlled by the user's private key, it securely stores personal information. This ensures exceptional responsiveness and an outstanding user experience.

Join us in ushering a new era of user-centric social networking. @@ -63,16 +72,17 @@

-
-
+
+
Harnessing Decentralization's Avant-Garde

- By leveraging decentralized cloud computing, we are dedicated to empowering individuals to reclaim control over their data and online presence. We upholds the principles of privacy, security, and autonomy, enabling users to connect and interact without reliance on centralized authorities. + By leveraging decentralized cloud computing, we are dedicated to empowering individuals to reclaim + control over their data and online presence. We upholds the principles of privacy, security, and autonomy, enabling users to connect and interact without reliance on centralized authorities.
- Through this innovative approach, we aim to revolutionize the social networking landscape, fostering a truly democratic and user-centric digital ecosystem. + Through this innovative approach, we aim to revolutionize the social networking landscape, fostering a truly democratic and user-centric digital ecosystem.

- +
@@ -91,10 +101,10 @@

@@ -104,17 +114,17 @@

📝
Community-driven
-
+
See our plans for a better social future.
@@ -123,7 +133,7 @@

👀
Stay Tuned
-
+
Connect with community that values your voice and privacy.
@@ -133,20 +143,22 @@

-
- Discord -
+
+ Discord +
-
- Openchat -
+
+ Openchat +

+ + diff --git a/instantpage-5.2.0.js b/instantpage-5.2.0.js new file mode 100644 index 0000000..dc4e040 --- /dev/null +++ b/instantpage-5.2.0.js @@ -0,0 +1,2 @@ +/*! instant.page v5.2.0 - (C) 2019-2023 Alexandre Dieulot - https://instant.page/license */ +let t,e,n,o,i,a=null,s=65,c=new Set;const r=1111;function d(t){o=performance.now();const e=t.target.closest("a");m(e)&&p(e.href,"high")}function u(t){if(performance.now()-o{p(e.href,"high"),i=void 0},s))}function l(t){const e=t.target.closest("a");m(e)&&p(e.href,"high")}function f(t){t.relatedTarget&&t.target.closest("a")==t.relatedTarget.closest("a")||i&&(clearTimeout(i),i=void 0)}function h(t){if(performance.now()-o1||t.metaKey||t.ctrlKey)return;if(!e)return;e.addEventListener("click",function(t){1337!=t.detail&&t.preventDefault()},{capture:!0,passive:!1,once:!0});const n=new MouseEvent("click",{view:window,bubbles:!0,cancelable:!1,detail:1337});e.dispatchEvent(n)}function m(o){if(o&&o.href&&(!n||"instant"in o.dataset)){if(o.origin!=location.origin){if(!(e||"instant"in o.dataset)||!a)return}if(["http:","https:"].includes(o.protocol)&&("http:"!=o.protocol||"https:"!=location.protocol)&&(t||!o.search||"instant"in o.dataset)&&!(o.hash&&o.pathname+o.search==location.pathname+location.search||"noInstant"in o.dataset))return!0}}function p(t,e="auto"){if(c.has(t))return;const n=document.createElement("link");n.rel="prefetch",n.href=t,n.fetchPriority=e,n.as="document",document.head.appendChild(n),c.add(t)}!function(){if(!document.createElement("link").relList.supports("prefetch"))return;const o="instantVaryAccept"in document.body.dataset||"Shopify"in window,i=navigator.userAgent.indexOf("Chrome/");i>-1&&(a=parseInt(navigator.userAgent.substring(i+"Chrome/".length)));if(o&&a&&a<110)return;const c="instantMousedownShortcut"in document.body.dataset;t="instantAllowQueryString"in document.body.dataset,e="instantAllowExternalLinks"in document.body.dataset,n="instantWhitelist"in document.body.dataset;const r={capture:!0,passive:!0};let f=!1,v=!1,g=!1;if("instantIntensity"in document.body.dataset){const t=document.body.dataset.instantIntensity;if(t.startsWith("mousedown"))f=!0,"mousedown-only"==t&&(v=!0);else if(t.startsWith("viewport")){const e=navigator.connection&&navigator.connection.saveData,n=navigator.connection&&navigator.connection.effectiveType&&navigator.connection.effectiveType.includes("2g");e||n||("viewport"==t?document.documentElement.clientWidth*document.documentElement.clientHeight<45e4&&(g=!0):"viewport-all"==t&&(g=!0))}else{const e=parseInt(t);isNaN(e)||(s=e)}}v||document.addEventListener("touchstart",d,r);f?c||document.addEventListener("mousedown",l,r):document.addEventListener("mouseover",u,r);c&&document.addEventListener("mousedown",h,r);if(g){let t=window.requestIdleCallback;t||(t=(t=>{t()})),t(function(){const t=new IntersectionObserver(e=>{e.forEach(e=>{if(e.isIntersecting){const n=e.target;t.unobserve(n),p(n.href)}})});document.querySelectorAll("a").forEach(e=>{m(e)&&t.observe(e)})},{timeout:1500})}}(); \ No newline at end of file diff --git a/style.css b/style.css index 7ff1304..4c96eb2 100644 --- a/style.css +++ b/style.css @@ -273,7 +273,7 @@ header .title p { font-weight: normal; } -header .title span:first-child {color: #0633f8;} +header .title span:nth-child(1) {color: #0633f8;} header .title span:nth-child(2) {color: #0e31f9;} header .title span:nth-child(3) {color: #312df8;} header .title span:nth-child(4) {color: #3d26f8;} @@ -282,8 +282,9 @@ header .title span:nth-child(6) {color: #611ef9;} header .title span:nth-child(7) {color: #751af9;} header .title span:nth-child(8) {color: #8217f9;} header .title span:nth-child(9) {color: #8b15f9;} -header .title span:nth-child(10) {color: #9e11f9;} +header .title span:nth-child(10) {color: #9e11f8;} header .title span:nth-child(11) {color: #9a12f9;} +header .title span:nth-child(12) {color: #9606fc;} .app-link a { display: flex; @@ -453,8 +454,8 @@ button:hover .button-text { } .card-button-social { - width: 3.7rem; - height: 3.7rem; + width: 3.5rem; + height: 3.5rem; margin: 10px; display: flex; align-items: center; diff --git a/technology/index.html b/technology/index.html new file mode 100644 index 0000000..ae26e1d --- /dev/null +++ b/technology/index.html @@ -0,0 +1,125 @@ + + + + + + Technology + + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+

Harnessing Decentralization's Avant-Garde

+

+ ICE CUBE distinguishes itself by granting users control over their own canister to store all information, ensuring no external interference. Users exclusively interact with their own canister, enabling a seamless and rapid experience, unaffected even during high user volumes. ICE CUBE also features an open database, allowing anyone to freely query any data, breaking away from the data silos seen in Web2 applications. +

+

+ On another note, ICE CUBE incorporates a unique incentive mechanism for creators through the Bonding Curve. ICE CUBE tokenizes posts and publicly issues them, providing returns to purchasers. +

+

+ Essentially, every post can be "tokenized," with tokens issued in a manner akin to fungible tokens, where the price of each share gradually increases with the quantity purchased. +

+

+ By offering contributors an expected return on investment, ICE CUBE encourages spontaneous early donations to valuable public goods. The entire process of asset + issuance and returns is governed by smart contracts, ensuring transparency and openness. +

+
+ +
+

+ Introduction to technical architecture +

+

+ ICE CUBE embraces the Actor model, continuously exploring technologies for decentralized application (DApp) built entirely upon Actor model principles. +

+

+ The foundational unit of ICE CUBE is the canister, a concept we believe aligns synergistically with the Internet Computer. + DApps constructed upon this architectural paradigm may emerge as the prevailing norm, unlocking myriad possibilities for innovation derived from this powerful concept. +

+

+ Detailed description of technical architecture +

+

+ ICE CUBE incorporates modular design, an open database, user cloud terminals, and a creator incentive mechanism. +

+
    +
  • + Modular Design: Categorizes canisters based on functionality, each with its designated role. +
  • +
  • + Public Database: An open database allowing anyone to directly publish and access content. +
  • +
  • + User Cloud Terminals: Each user possesses their small independent server (canister), offering on-chain private services. +
  • +
  • + Creator Incentives: Assigns "tokens" to post, distinguishing outstanding content. +
  • +
+

+ Its architecture is designed based on the actor model provided by IC. + Decentralized collaboration among canisters facilitates information flow, with users needing only to query canisters for all relevant information.In essence, users interact solely with their own canister at the frontend, leaving subsequent collaboration tasks to be gradually + completed by the canisters. +

+

+ We create a Feed canister for each user to store their personal information flow, serving as their private space. Users can save posts in their own canister (Feed canister), and no one else can delete them besides the user. +

+

+ Interactions between users and the public area are automatically handled by the Feed canister. Users can simply query their Feed canister to obtain the latest information flow from those they follow. Posting, commenting, and liking interactions are also automatically completed by the Feed canister in subsequent operations. +

+

+ Overall, ICE CUBE can be divided into four modules: User, Feed, Post, and Fetch. +

+
    +
  • + User canister: The user zone responsible for recording user information and relationships. It stores user profiles and follower relationships. +
  • +
  • + Post canister: The public zone that stores all publicly posted content. The Root Post canister can create numerous Bucket canisters to store posts. +
  • +
  • + Feed canister: The information stream storing a user's personal information flow. The Root Feed canister creates a Feed canister for each user. +
  • +
  • + Fetch canister: The intermediary station responsible for pushing the latest information flow of a specific user. It records posts, comments, or likes that the user's Feed canister has not fetched. +
  • +
+

+ Users can also incorporate advanced custom features by deploying an independent Feed canister to + interact with the public zone. For example, sending posts point-to-point to specific Feed canisters to + create private social circles or connecting to AI for automatic posting. Any functionality is + achievable, with the community having the flexibility to develop and expand various features, such as + adding a point-to-point private messaging feature. +

+

+ The advantage of this approach is that users only need to query their Feed canister to access posts from those they follow. It is convenient, swift, and all backend processes are decentralized collaborations between canisters, completely decoupled. The system continues running even if several canisters go offline. +

+ +
+ +

+ Check out the Docs for more. +

+
+ + + + + + \ No newline at end of file diff --git a/technology/script.js b/technology/script.js new file mode 100644 index 0000000..ee3a139 --- /dev/null +++ b/technology/script.js @@ -0,0 +1,185 @@ +const AnimateOnScroll = function ({ offset } = { offset: 10 }) { + // 定义屏幕的顶部、底部和侧面 + const windowTop = offset * window.innerHeight / 100; + const windowBottom = window.innerHeight - windowTop; + const windowLeft = 0; + const windowRight = window.innerWidth; + + this.start = element => { + window.requestAnimationFrame(() => { + // 设置自定义属性 + element.style.animationDelay = element.dataset.animationDelay; + element.style.animationDuration = element.dataset.animationDuration; + + // 通过将类设置为动画来启动动画 + element.classList.add(element.dataset.animation); + + // 将元素设置为动画 + element.dataset.animated = "true"; + }); + }; + + this.inViewport = element => { + // 获取元素的边界框 + const elementRect = element.getBoundingClientRect(); + const elementTop = + elementRect.top + parseInt(element.dataset.animationOffset) || + elementRect.top; + const elementBottom = + elementRect.bottom - parseInt(element.dataset.animationOffset) || + elementRect.bottom; + const elementLeft = elementRect.left; + const elementRight = elementRect.right; + + // 检查元素是否在屏幕上 + return ( + elementTop <= windowBottom && + elementBottom >= windowTop && + elementLeft <= windowRight && + elementRight >= windowLeft); + + }; + + // 遍历元素数组,检查元素是否在屏幕上并开始动画 + this.verifyElementsInViewport = (els = elements) => { + for (let i = 0, len = els.length; i < len; i++) { + // 如果元素已经动画,则移至下一个循环 + if (els[i].dataset.animated) continue; + + this.inViewport(els[i]) && this.start(els[i]); + } + }; + + // 获取所有要动画的元素 + this.getElements = () => + document.querySelectorAll("[data-animation]:not([data-animated])"); + + // 更新要动画的元素列表 + this.update = () => { + elements = this.getElements(); + elements && this.verifyElementsInViewport(elements); + }; + + // 开始 + window.addEventListener("load", this.update, false); + window.addEventListener( + "scroll", + () => this.verifyElementsInViewport(elements), + { passive: true }); + + window.addEventListener( + "resize", + () => this.verifyElementsInViewport(elements), + { passive: true }); + +}; + +// Initialize +const options = { + offset: 15 // percentage of the window +}; + +const animation = new AnimateOnScroll(options); + +const MIN_SPEED = 1.5 +const MAX_SPEED = 2.5 + +function randomNumber(min, max) { + return Math.random() * (max - min) + min +} + +class Blob { + constructor(el) { + this.el = el + const boundingRect = this.el.getBoundingClientRect() + this.size = boundingRect.width + this.initialX = randomNumber(0, window.innerWidth - this.size) + this.initialY = randomNumber(0, window.innerHeight - this.size) + this.el.style.top = `${this.initialY}px` + this.el.style.left = `${this.initialX}px` + this.vx = + randomNumber(MIN_SPEED, MAX_SPEED) * (Math.random() > 0.5 ? 1 : -1) + this.vy = + randomNumber(MIN_SPEED, MAX_SPEED) * (Math.random() > 0.5 ? 1 : -1) + this.x = this.initialX + this.y = this.initialY + } + + update() { + this.x += this.vx + this.y += this.vy + if (this.x >= window.innerWidth - this.size) { + this.x = window.innerWidth - this.size + this.vx *= -1 + } + if (this.y >= window.innerHeight - this.size) { + this.y = window.innerHeight - this.size + this.vy *= -1 + } + if (this.x <= 0) { + this.x = 0 + this.vx *= -1 + } + if (this.y <= 0) { + this.y = 0 + this.vy *= -1 + } + } + + move() { + this.el.style.transform = `translate(${this.x - this.initialX}px, ${ + this.y - this.initialY + }px)` + } +} + +function initBlobs() { + const blobEls = document.querySelectorAll('.bouncing-blob') + const blobs = Array.from(blobEls).map((blobEl) => new Blob(blobEl)) + + function update() { + requestAnimationFrame(update) + blobs.forEach((blob) => { + blob.update() + blob.move() + }) + } + + requestAnimationFrame(update) +} + +initBlobs(); + + + +const TOGGLE = document.querySelector("button"); + +const UPDATE = () => { + const DARK = TOGGLE.matches("[aria-pressed=true]"); + TOGGLE.setAttribute("aria-pressed", DARK ? false : true); + document.documentElement.className = DARK ? "dark" : ""; +}; + +const TOGGLE_THEME = () => { + if (!document.startViewTransition) return UPDATE(); + document.startViewTransition(() => UPDATE()); +}; + +TOGGLE.addEventListener("click", TOGGLE_THEME); + +if (!CSS.supports("animation-timeline: view()")) { + const MARKS = document.querySelectorAll("mark"); + const OPTS = { + threshold: 1.0 }; + + const HANDLE = entries => { + entries.forEach(entry => { + entry.target.style.setProperty( + "--highlighted", + entry.isIntersecting ? 1 : 0); + + }); + }; + const OBSERVER = new IntersectionObserver(HANDLE, OPTS); + MARKS.forEach(M => OBSERVER.observe(M)); +} diff --git a/technology/style.css b/technology/style.css new file mode 100644 index 0000000..3cc10ff --- /dev/null +++ b/technology/style.css @@ -0,0 +1,271 @@ +*, +*:after, +*:before { + box-sizing: border-box; +} + +body { + min-height: 100vh; + font-weight: 80; + padding: 0 4rem 0 1rem; + background: #fff; + color: #000; + font-family: "Geist Sans", "SF Pro Text", "SF Pro Icons", "AOS Icons", "Helvetica Neue", Helvetica, Arial, sans-serif, system-ui; +} + +body::after { + --size: 80px; + --thickness: 2px; + content: ""; + position: fixed; + height: 100vh; + width: 100vw; + pointer-events: none; + top: 0; + left: 0; + z-index: -1; + opacity: 0.25; +} + +.bouncing-blob { + width: 32vw; + aspect-ratio: 1; + border-radius: 50%; + will-change: transform; + position: absolute; + z-index: 1; + top: 0; + left: 0; + transform-origin: left top; +} + +.bouncing-blob--blue { + background: #3e87d9; +} + +.bouncing-blob--white { + background: #ffffff; + z-index: 2; + width: 15vw; +} + +.bouncing-blob--purple { + background: #9f89f6; +} + +.bouncing-blob--pink { + background: #f08bd850; +} + +.bouncing-blobs-container { + position: fixed; + z-index: -1; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.bouncing-blobs-glass { + position: absolute; + z-index: 2; + top: 0; + left: 0; + width: 100%; + height: 100%; + backdrop-filter: blur(140px); + -webkit-backdrop-filter: blur(140px); + pointer-events: none; +} + +.bouncing-blobs { + position: absolute; + z-index: 1; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.dark body { + background: hsl(0 0% 6%); + color: hsl(0 0% 96%); +} + +mark { + color: hsl(0 0% 6%); +} + +.dark mark { + color: hsl(0 0% 98%); +} + +section { + margin-bottom: 2rem; +} + +.dark header svg path { + fill: white; +} + +* { + box-sizing: border-box; +} + +:where(h1, h2) { + font-weight: 120; +} + +code { + max-width: 100%; + overflow: auto; +} + +main { + padding: 0 1rem; + width: 57ch; + max-width: 100%; + margin: 0 auto; + font-size: 1.25rem; + padding: 0 0 50vmin 0; +} + +button { + position: fixed; + top: 1rem; + right: 1rem; + width: 48px; + aspect-ratio: 1; + padding: 0; + border-radius: 12px; + border: 0; + background: transparent; + display: grid; + place-items: center; + cursor: pointer; +} + +[aria-pressed=true] svg path:last-of-type, +[aria-pressed=false] svg path:first-of-type { + display: none; +} + +button svg { + width: 65%; +} + +mark { + --lightness: 80%; + --highlighted: 1; + --highlight: hsl(var(--hue, 45) 80% var(--lightness)); + background: transparent; +} + +@supports (animation-timeline: view()) { + mark { + --highlighted: 0; + -webkit-animation: highlight steps(1) both; + animation: highlight steps(1) both; + animation-timeline: view(); + animation-range: entry 100% cover 10%; + } +} + +.dark mark { + --lightness: 35%; +} + +mark span { + background: linear-gradient(120deg, var(--highlight, lightblue) 50%, transparent 50%) 110% 0 / 200% 100% no-repeat; + background-position: calc((1 - var(--highlighted)) * 110%) 0; + transition: background-position 1s; +} + +p, +li { + position: relative; +} + +a { + color: hsl(236, 100%, 47%); + text-decoration: none; +} + +a:is(:hover, :focus-visible) { + text-decoration: underline; + text-underline-offset: 6px; +} + +hr { + margin: 2rem auto; +} + +hr+p { + text-align: center; +} + +mark::after { + content: attr(data-author); + display: grid; + place-items: center; + font-variant-numeric: tabular-nums; + font-weight: bold; + position: absolute; + padding: 7px; + aspect-ratio: 1; + border-radius: 12px; + background: var(--highlight); + font-weight: 80; + top: 0; + left: 100%; + translate: 50% 0; + font-size: 0.875rem; + scale: var(--highlighted); + transition: scale 0.2s; +} + +@-webkit-keyframes highlight { + to { + --highlighted: 1; + } +} + +@keyframes highlight { + to { + --highlighted: 1; + } +} + +::view-transition-new(root) { + -webkit-animation: grow 1s; + animation: grow 1s; +} + +::view-transition-old(root) { + -webkit-animation: none; + animation: none; +} + +@-webkit-keyframes grow { + 0% { + -webkit-clip-path: polygon(50vmax 50vmax, 50vmax 50vmax, 50vmax 50vmax); + clip-path: polygon(50vmax 50vmax, 50vmax 50vmax, 50vmax 50vmax); + } + + 100% { + -webkit-clip-path: polygon(50vmax -100vmax, -100vmax 200vmax, 200vmax 200vmax); + clip-path: polygon(50vmax -100vmax, -100vmax 200vmax, 200vmax 200vmax); + } +} + +@keyframes grow { + 0% { + -webkit-clip-path: polygon(50vmax 50vmax, 50vmax 50vmax, 50vmax 50vmax); + clip-path: polygon(50vmax 50vmax, 50vmax 50vmax, 50vmax 50vmax); + } + + 100% { + -webkit-clip-path: polygon(50vmax -100vmax, -100vmax 200vmax, 200vmax 200vmax); + clip-path: polygon(50vmax -100vmax, -100vmax 200vmax, 200vmax 200vmax); + } +}