AI 资讯
Every Sanity page builder has the same bug
Every Sanity marketing site ends up with a page builder. An array of sections, an insert menu, a render loop that maps block._type to a component. You've built it. I've built it. We've all built the same thing. And every one of them ships with the same bug. You add a new section. You wire it into the schema. You add a renderer. You add a component. You add the type. And then — because there are five places to touch and you're a human — you forget one. The section renders blank in production. Or it never shows up in the insert menu. Or it fetches no fields because you missed the GROQ projection, so it renders as nothing at all. No error. No red. Just a hole on the page where a section should be. The annoying part isn't the bug. It's that you'll hit it again on the next project, in exactly the same way, because you rewrote the whole thing from scratch — again. The section tax Here's what "add a section" actually costs in a typical Sanity + Next.js page builder: Schema — a new *Section object type, registered in your schema index. GROQ — a new conditional in the page-builder projection so the block's fields actually come down. Component — the React component that renders it. Renderer map — an entry mapping _type → component. Types — the block variant in whatever union your frontend renders. Miss #2 and the block arrives empty. Miss #4 and it silently skips. Miss #5 and TypeScript shrugs because your union is hand-maintained and now lies. Three different failure modes, all of them quiet, all of them "works on my machine until it doesn't." Now look at those five places and ask: which of them is actually unique to your site? The component is. It's welded to your design system — your spacing, your tokens, your brand. Nobody can reuse it and nobody should. The other four are plumbing . "Look up _type in a map, call the renderer, keep the map in sync with the schema and the query." That code is byte-for-byte the same idea on every project you've ever built. So why is it livi
AI 资讯
Install NixOS on Jetorbit
Overview Tulisan ini menceritakan pengalaman saya meng-install NixOS di VPS Jetorbit memakai nixos-anywhere , dideploy dari laptop macOS (nix-darwin). Komposisi Laptop (macOS + nix-darwin) : Semua konfigurasi NixOS dibuat di sini, lalu dikirim ke server. VPS Jetorbit (x86_64 Linux) : target deploy. Boot lewat legacy BIOS , dengan IP statis (bukan DHCP). nixos-anywhere : dipakai sekali saja untuk install awal. nixos-rebuild : dipakai untuk update konfigurasi setelah install awal. Catatan Penting : VPS tidak perlu menyimpan file konfigurasi sendiri. Kita edit config di laptop, lalu push ke VPS lewat SSH. Tidak ada apt update , tidak ada config drift, dan kondisi server selalu reproducible dari git. Pre-flight: Cek Sebelum Menyentuh Server Banyak kegagalan install sebenarnya bisa dicegah kalau kita cek tiga hal ini: 1. Mode boot: UEFI atau legacy BIOS? Ini menentukan konfigurasi bootloader. Salah konfigurasi di sini dapat menyebabkan GRUB gagal saan install nanti. Di VPS (SSH ke VPS): [ -d /sys/firmware/efi ] && echo "UEFI" || echo "BIOS" Di Jetorbit secara default adalah BIOS . Artinya konfigurasi GRUB mode legacy BIOS, bukan EFI. 2. Networking: IP, netmask, dan gateway Jetorbit memakai IP statis, bukan DHCP. Kalau konfigurasi NixOS kita set IP maka NixOS akan fallback ke DHCP, dan akan gagal dapat IP, sehingga server jadi tidak bisa diakses sama sekali setelah reboot. Di VPS: ip -4 a # lihat IP + CIDR dan nama interface (misal. ens3) ip route # lihat "default via X.X.X.X", itu gateway-nya Contoh: 2: ens3: ... inet 110.XXX.XXX.XXX/24 brd 110.XXX.XXX.255 scope global ens3 3. SSH Root nixos-anywhere memerlukan akses root ke server untuk bisa melakukan instalasi. Akses ini didapat lewat SSH key, bukan password. Jadi pastikan Di VPS: public key sudah terdaftar di root . Konfigurasi SSH root ini bisa dilakukan saat install OS awal di panel Jetorbit atau dikonfigurasi secara manual di ~/.ssh/authorized_keys . Cara Kerja nixos-anywhere Sebelum menjalankan perintahnya, ada ba
AI 资讯
Robot hand company settles Tesla trade secret suit and announces $11M raise
The startup, Proception, is taking a unique approach to collecting training data to tackle one of the hardest problems in robotics: hands.
产品设计
Rocket Lab is buying Iridium’s satellite network for $8 billion to take on SpaceX
Rocket Lab, the space company best known for its small satellite launcher Electron, has announced plans to acquire Iridium Communications for $8 billion. The deal will combine Rocket Lab's launch services and spacecraft manufacturing with Iridium's satellite-based communications network, putting it in a better position to challenge SpaceX. Iridium offers communications services to over 2.5 […]
AI 资讯
Omen AI’s plan to optimize data centers is all wet
Omen AI raised a $31 million Series A to monitor chip coolant and stop bacterial outbreaks in data centers.
AI 资讯
Robin Byrd, the Sex Godmother of Millennials, Says the Internet Ruined Porn
The 1970s porn actress turned New York City late night public access queen says censorship and a lack of star quality among modern adult entertainers turned her off of the industry.
AI 资讯
Introducing UIAble — A Free, Open-Source UI Library
Today, we’re excited to launch UIAble v1.0, an open-source component library built for developers, by developers. We explored a lot of UI libraries built on Shadcn. Most of them feel nearly identical — same structure, same aesthetic, same tradeoffs. That’s what pushed us to build something different. Not another library that looks like Shadcn with a coat of paint, but a design system with its own identity and a clearer sense of what it’s actually for. Why UIAble exists After enough frontend projects, one thing becomes obvious: the same UI patterns get rebuilt again and again. Inputs. Dialogs. Tables. Alerts. Dropdowns. OTP fields. Form validation states. Not because they’re hard to build, but because most existing libraries never quite fit real project requirements. Some are too opinionated. Some pile on unnecessary abstraction. Some become rigid after initial setup. And some make simple UI unnecessarily complicated. That friction is what led to UIAble. Not to launch another oversized library, just to build a cleaner, more practical foundation for modern frontend development. What UIAble actually is UIAble is a free, open-source UI component library built with Tailwind CSS , Shadcn-style architecture , and Base UI principles . The idea is straightforward: reusable components should stay flexible, readable, and easy to maintain. Instead of pulling projects into a rigid ecosystem, UIAble gives you components you can copy directly into your codebase, edit freely, and scale without fighting the library. No lock-in. No unnecessary abstraction. No dependency trap. What makes it different in practice A few things actually matter here. You get the code. UIAble doesn’t hide logic behind layers of packaging. You see the component. You edit it. You ship it. That alone changes how teams work with UI. It’s built for real product UI, not showcase pages. A lot of UI kits look great in demos and fall apart in production. UIAble focuses on the unglamorous stuff, forms that don’t bre
AI 资讯
Cx Dev Log — 2026-06-28
Labeled break/continue is now live across the entire Cx language stack. From the lexer to the JIT, two commits streamlined the implementation into a complete vertical slice. No parts left out, no corners cut—everything just works. The lexer seam If you're handling character literals and labels in the same codebase, you'll know what a pain this can be. We opted for a Rust-like syntax: 'ident for labels, with no closing quote. The label regex sits right after LiteralChar in the logos enum. Thanks to longest-match, 'x' becomes a char literal, while 'outer is parsed as a label. Escape sequences? They can't match labels because they have a backslash, making 'x' always look cleaner in code. A test fixture ( t_char_literal_guard ) ensures this order and regex integrity hold. Change the lexer rules, and it'll catch any mistakes immediately. Two-commit split We didn't cram this into a single mega-commit. No, we split it into two. Commit f94c6a5 laid down the frontend groundwork—adding the Label token, allowing loops and breaks to carry optional labels, and rejecting any misuse with semantic checks. The interpreter and JIT, however, initially took a back seat, guarding themselves against mislabeled jumps. Then came commit 0f56f1e , which wiped out these guards and enabled real execution on backends. Now all parses and semantic checks play nicely without rogue labeled breaks sneaking into the wrong loops. Interpreter changes The interpreter now handles BreakSignal and ContinueSignal carrying labels. Loops catch these signals when the label is either absent (defaulting to the innermost loop) or matches their own. The difference from before? Zero unlabelled break/continue behavior change while facilitating outward jumps. JIT changes The JIT saw more extensive adjustments, gaining a label field within LoopContext . Push and pop that context on a stack, trace it through lowering calls, and you've got labeled jumps pinpointed. The unlabeled jumps? They get the same treatment as bef
AI 资讯
Modernizando a Automação no Linux: Por que e como migrar do Cron para systemd Timers
Aprenda a substituir o velho Cron por systemd timers para ganhar logs nativos, controle de dependências e maior robustez.
AI 资讯
Why am I building a DevOps Infrastructure Lab?
I am committed to understand how systems actually work. I'm working on a multi-node lab to follow the complete path of a request from Python APIs to Linux processes, through Docker containers, networking and observability. The idea is simple: build a system that observes another system to understand the abstraction layers behind modern infrastructure. This project is about learning by building, experimenting and understanding what happens under the hood. Link: [ https://github.com/daniloprandi/devops-network-automation-lab ] DevOps #Linux #Python #Docker #Networking #Observability #Infrastructure
科技前沿
Why did this journal retract two 1940s papers by Max Planck?
Clicking on the links now reveals blank pages and empty PDFs. "Intellectually, it’s not acceptable.”
AI 资讯
How to fix the "Purple Potassium" Chrome Web Store rejection (and catch it before you submit)
You submitted your extension, waited days for review, and got back a rejection with a violation called "Purple Potassium." Your extension looks fine to you, so what does it even mean? Here is what it is, why it happens, and how to catch it before you ever hit submit. What "Purple Potassium" actually means "Purple Potassium" is Google's internal tag for excessive or unused permissions . Your manifest requests access to something your code does not actually use, and the reviewer flags it. It is one of the most common reasons a Chrome extension gets rejected, and it is frustrating precisely because the extension works fine in testing. Review is checking something testing never does: whether every permission you ask for is justified by your code. The usual causes 1. API permissions you declared but never call. You added tabs , bookmarks , or cookies to your manifest at some point, but there is no chrome.bookmarks.* call anywhere in your code. 2. Host access that is too broad. You requested <all_urls> when your extension only touches one site: // Flagged "host_permissions" : [ "<all_urls>" ] // Better "host_permissions" : [ "https://*.example.com/*" ] Leftover permissions after removing a feature. You shipped a feature that needed downloads, later removed the feature, and forgot to remove the permission. The tabs misunderstanding. The tabs permission does not grant access to the tabs API. Basic methods like chrome.tabs.create() work without it. It only grants four sensitive Tab properties: url, pendingUrl, title, and favIconUrl. If you declare tabs but never read those, it counts as unused. How to fix it by hand List everything in permissions, optional_permissions, and host_permissions. For each one, search your code for the matching chrome. call. Remove any permission with no usage. Narrow and other broad patterns to the specific hosts you need. In your reviewer notes, write one plain sentence per sensitive permission explaining why you need it. Reviewers often lack con
AI 资讯
TechCrunch Mobility: All eyes on Tesla FSD
Welcome back to TechCrunch Mobility, your hub for the future of transportation and now, more than ever, how AI is playing a part.
开发者
I built a free UAE calculator platform that runs on live government data
Living in the UAE means constantly Googling numbers: what is the visa fee now, how much zakat do I owe, what is today's fuel price, how is my gratuity calculated. The answers online are usually outdated. So I built Adad , a free set of 15 calculators that pull from official UAE government sources and refresh every 24 hours. No sign-up, works in 8 languages. A few that people use most: Visa fees: real GDRFA and ICA rates Zakat: gold, silver, savings DEWA bills: estimate before the bill lands Gratuity: UAE labour-law end-of-service It is at adad.ae if it is useful to you. Happy to answer how the data pipeline stays current.
AI 资讯
Quitter Vercel : héberger son app Next.js sur un VPS
Vercel m'a longtemps convenu. Tu pousses ton code, trente secondes plus tard c'est en ligne avec un certificat valide, un CDN et des previews par branche. Pour démarrer un projet, je ne connais rien de plus confortable. Le problème arrive après, quand le projet vit. La facture grimpe avec le trafic et les fonctions serverless, certaines fonctionnalités propriétaires deviennent compliquées à reproduire ailleurs, et tu finis par ne plus vraiment savoir où ni comment ton app tourne. C'est un excellent point de départ, et un piège dès qu'on veut maîtriser son coût et son infra. Pour ce portfolio comme pour plusieurs projets clients, j'ai pris le chemin inverse. Un VPS à quelques euros par mois, une image Docker, un reverse proxy, un pipeline maison. L'idée n'est pas de revenir à l'âge de pierre du déploiement par FTP : je garde le « git push et c'est en ligne », mais sur une machine que je contrôle de bout en bout. Voici comment c'est câblé, et les deux ou trois endroits où je me suis fait avoir. L'image Docker : tout repose sur le mode standalone La pièce qui change tout, c'est output: "standalone" dans next.config.ts . Au build, Next trace exactement les fichiers nécessaires au runtime et les recopie dans .next/standalone/ . On passe d'une image d'environ 1 Go à environ 200 Mo. Sans ça, tu traînes tout node_modules dans ton conteneur de prod pour rien. Le Dockerfile est multi-stage : une étape pour installer les dépendances, une pour builder, une dernière qui ne garde que le strict nécessaire. # deps : installe les dépendances (cache Docker optimal) FROM node:22-alpine AS deps WORKDIR /app COPY package.json yarn.lock .yarnrc.yml ./ RUN corepack enable && yarn install --immutable # builder : build l'app FROM node:22-alpine AS builder WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY . . RUN corepack enable && yarn build # runner : image finale, non-root FROM node:22-alpine AS runner WORKDIR /app ENV NODE_ENV=production RUN addgroup -g 1001 nodejs && a
AI 资讯
HackTheBox: Sloink Writeup
Summary NFS shares exposed the target's home directory and PostgreSQL backups. The user's psql history contained an MD5 hash that cracked to service . SSH with that account drops you immediately (shell is /bin/false ), but port forwarding still works - so we tunneled straight to the Postgres Unix socket and connected as the superuser. From there, COPY FROM PROGRAM gave us RCE as postgres. We injected our SSH key and got a shell. For root, a cron job running as root copies the entire Postgres data directory - which postgres owns. We dropped a SUID bash there, waited for the cron to fire, and root handed us a root shell. Chain: NFS leak → MD5 crack → SSH tunnel → Postgres RCE → SSH key injection → postgres shell → SUID bash via cron → root Recon nmap -A -Pn 10.129.234.160 -oA nmap PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.13 111/tcp open rpcbind 2-4 (RPC #100000) 2049/tcp open nfs_acl 3 (RPC #100227) NFS on 2049 is immediately interesting. We check what's exported: showmount -e 10.129.234.160 Export list for 10.129.234.160: /var/backups * /home * Both shares open to everyone ( * ). We mount them and enumerate: mkdir -p /mnt/home /mnt/backups mount -t nfs 10.129.234.160:/home /mnt/home mount -t nfs 10.129.234.160:/var/backups /mnt/backups find /mnt/backups -maxdepth 3 -ls # → several archive-*.zip files (~4.5MB each, created every minute) find /mnt/home -maxdepth 3 -ls # → /mnt/home/service (UID 1337, permission denied) We can't read the service home directory yet because our local UID doesn't match. We use NetExec to enumerate properly - it also detects a root escape vulnerability on the NFS server: nxc nfs 10.129.234.160 --enum-shares NFS 10.129.234.160 [*] Supported NFS versions: (3, 4) (root escape:True) NFS 10.129.234.160 [+] /var/backups NFS 10.129.234.160 0 r-- 4.5MB /var/backups/archive-2026-06-28T0446.zip NFS 10.129.234.160 [+] /home NFS 10.129.234.160 1337 r-- 90B /home/service/.bash_history NFS 10.129.234.160 1337 r-- 326B /hom
产品设计
I've been thinking about building a vehicle rental platform, but I'm hesitant because there are already so many established apps in the market. I'm curious to hear from people who have actually rented bikes or cars. What do you dislike about the current
AI 资讯
TeamLab 那片會跟著你走的花海,原理拆解 DIY
TeamLab 那片會跟著你走的花海,原理拆解+DIY 先看這張圖 這是 TeamLab 在東京台場的《呼應燈之森林》。當你走過去,附近的燈會慢慢亮起;你離開後,燈又慢慢暗下去,像是真的森林一樣。 還有另一個作品《花與人的共存》,花叢會跟著你移動——你站的地方,花就開在你腳邊;你離開,花就凋謝。 這兩件作品的核心邏輯是一樣的。這篇文章就來拆解它。 原理一:偵測位置 TeamLab 的互動裝置需要知道「你在哪裡」。 最常見的方法有兩種: 紅外線感應 :在地面下方埋紅外線接收器,你走過時阻擋光線,系統就知道有人在這個位置。缺點是只能測「有沒有人」,不能測「人在哪一個方向」。 深度相機(RealSense / Kinect) :像 Xbox 的體感相機,透過紅外線測量每一個點到你相機的距離,生成一張「深度地圖」。軟體在深度地圖裡找出人體的位置,然後算出座標。 DIY 版本 :一塊 Arduino + 超音波感測器(HC-SR04,大約 60 元)就能做到基本的「有人靠近」偵測。 原理二:控制回應 知道你在哪裡之後,系統要決定「要做什麼回應」。 TeamLab 的做法是 :不是「觸發」,而是「強度變化」 。 傳統的感應燈:感應到人 → 燈全亮 → 人離開 → 燈全滅。 TeamLab 的邏輯:感應到人 → 燈慢慢變亮(0.5 秒)→ 人持續在 → 維持亮度 → 人離開 → 慢慢變暗(2 秒)。 「慢慢」是關鍵。瞬間變化讓人注意到「科技」;緩慢變化讓人以為「這個空間有生命」。 這就是「驚奇設計」的核心: 時機對了,物理反應看起來像生物反應。 原理三:集體行為 最後一個秘密:TeamLab 的裝置很少只有一個「回應」。 通常會有 100-500 個元素(燈、花、光點)。每個元素各自計算自己與你的距離,決定自己的亮度或顏色。 當 500 個燈各自以稍微不同的速度亮起和暗下,你看到的不是「一個燈亮了」,而是「一片森林在你腳下呼吸」。 心理錯覺 :你把「一群各自輕微不同步的簡單反應」,詮釋成「一個整體有意志的生物」。 用 Arduino 自己做一個迷你版 材料: Arduino Uno(大約 200 元) 超音波感測器 HC-SR04(大約 60 元) LED 燈 x 3(大約 15 元) 麵包板和杜邦線 原理很簡單: 超音波感測器偵測距離 距離越近,LED 越亮(用 PWM 訊號控制) 距離越遠,LED 越暗 int trig = 7 ; int echo = 6 ; int led = 9 ; void setup () { Serial . begin ( 9600 ); pinMode ( trig , OUTPUT ); pinMode ( echo , INPUT ); pinMode ( led , OUTPUT ); } void loop () { digitalWrite ( trig , LOW ); delayMicroseconds ( 2 ); digitalWrite ( trig , HIGH ); delayMicroseconds ( 10 ); digitalWrite ( trig , LOW ); long duration = pulseIn ( echo , HIGH ); long distance = duration * 0.034 / 2 ; // 距離越近,LED 越亮 int brightness = map ( distance , 0 , 100 , 255 , 0 ); brightness = constrain ( brightness , 0 , 255 ); analogWrite ( led , brightness ); delay ( 50 ); } 這不是 TeamLab,但這是你自己做的「會呼吸的燈」。每個 maker 都是從這裡開始的。 庭庭:這個看起來很難 真的沒有你想的那麼難。 需要的東西全部可以在蝦皮買到,全部加起來大約 300 元。網路上有超多 Arduino 教學,關鍵字搜「Arduino 超音波 LED」就有幾十篇中文教學。 你不需要懂電子,只需要跟著步驟做,做完會有「哇,我自己做出了一個會亮的東西」的感動。 如果你想更進一步 TeamLab 的進入門檻其實不是技術,是「你要把技術藏在美學後面」。 推薦兩個方向可以繼續研究: p5.js + webcam :用 p5.js 讀取你的 webcam 影像,偵測顏色或移動。相當於用軟體做到 Kinect 的效果,零硬體成本。 Processing + 投影機 :把電腦畫面投射到牆上或地面上,加上感測器,就是一個簡單版互動投影。投影機在蝦皮一兩千元就有。 今日概念 :TeamLab 的魔法不是魔法,是三個原
科技前沿
為什麼那個會「注意你」的展品,反而讓你更想靠近
為什麼那個會「注意你」的展品,反而讓你更想靠近 博物館互動設計的隱形槓桿 東京。 teamLab 展覽入口。 地面是一整片黑色的水面,倒映著數位花朵。 你踏進去。 花朵在你腳步周圍散開,隨著你的移動一圈一圈地綻放和飄落。 你停下來,花也停下來。 你開始走,花就跟著你。 你以為是感應。但仔細看——延遲了大概 0.3 秒。 不是「立刻反應」,是「好像在觀察你,然後才決定」。 你站在那裡又多看了三秒。 你第一個「對」 讓我問你一個問題。 你去過那種「互動博物館」嗎?牆上寫著「請觸摸」,但你碰了之後什麼都沒發生——或者是那種「語音導覽機」,你對著它說話,它說「請靠近一點」。 然後你就失去興趣了。 現在讓我想另一個場景。 一個會動的恐龍骨骼。你站在它面前的時候,它頭轉過來看了你一眼。 你知道這是感應器。你知道工程師設計了「檢測到人」的時候讓它轉頭。 但你還是覺得—— 「它在看我。」 兩種互動,哪一個讓你停留更久? 你第一個「咦」 這裡有一個秘密。 讓人停留更久的,通常不是「立刻反應」的互動。 是那種「 好像在決定要不要理你 」的互動。 為什麼? 因為「立刻反應」讓你確認了——「這是機器」。 但「好像在決定要不要理你」讓你的大腦進入了一個不確定的狀態—— 「它真的知道我來了嗎?」 「它在決定什麼?」 「我想看看它決定什麼。」 這個「我想看看」就是互動設計裡最重要的瞬間—— 參與者的好奇心,被啟動了。 玉樹真一郎在《任天堂的體驗設計》裡,分析了一個現象: 《超級馬里奧》裡,當玩家靠近一個問號磚塊,頂了它,沒有任何東西掉下來。 玩家不會覺得「這個遊戲壞了」。 玩家會想:「 為什麼這次沒有? 」 然後再頂一次。 為什麼「沒有東西掉下來」沒有讓玩家放棄? 因為設計師在玩家心裡創造了一個「 還沒發生的確定事件 」。 玩家知道「遲早會有東西掉下來」。所以他們願意等待、願意再試一次。 博物館的互動設計也應該這樣。 不是立刻給答案。是讓你相信「答案快來了」,然後讓你一直站在那裡等。 你最後「我要改變做法」 讓我說一個失敗的設計。 一個科技博物館有一面「觸控牆」。牆上有很多按鈕,碰了就會播放影片、發出聲音、變色。 一開始很多小孩去碰。 但大概十五分鐘之後,那面牆就沒人碰了。 為什麼? 因為碰了 100 次,沒有任何一次比另一次更「值得等待」。 每一次都是立刻發生,每一次都是同樣的結果。 沒有任何一件事需要「決定」。 現在讓我說一個成功的設計。 同一個博物館的另一區,有一面「情緒牆」。 你站在牆前,系統會掃描你的臉——不是真的分析情緒,而是給你一個顏色。 每個人的顏色都不太一樣。 但顏色不是立刻出現的。 大概等了兩秒——然後它慢慢浮現出來。 在這兩秒裡,每個站在牆前的人都沒有動。 他們在等。 他們相信顏色一定會出現。但他們不確定會是什麼顏色。 三個馬上可以用的方向 第一:不要立刻給回饋。 加入一個 0.3 到 2 秒的「思考時間」。 讓互動看起來像「系統在決定」,而不只是「系統在檢測」。 壞掉的燈 vs 正在決定的燈——後者讓人更想站在那裡等。 自己試試看:30 行做出「延遲反應」的燈 // p5.js — 試試延遲回饋的感覺 let lights = []; const DELAY = 12 ; // 幀數延遲(約 0.2 秒) function setup () { createCanvas ( 400 , 400 ); for ( let i = 0 ; i < 5 ; i ++ ) { lights . push ({ history : [], lit : false }); for ( let j = 0 ; j < Math . max ( DELAY , 1 ); j ++ ) lights [ i ]. history . push ( false ); } } function draw () { background ( 30 ); let hovered = floor ( mouseX / 80 ); for ( let i = 0 ; i < lights . length ; i ++ ) { lights [ i ]. history . push ( hovered === i ); if ( DELAY > 0 ) lights [ i ]. history . shift (); lights [ i ]. lit = DELAY > 0 ? lights [ i ]. history [ 0 ] : ( hovered === i ); } // 畫燈泡 noStroke (); for ( let i = 0 ; i < lights . length ; i ++ ) { fill ( lights [ i ].
AI 资讯
I Started Building a Premium Template Marketplace — Week 1 Progress, Stack & What's Coming
I've been thinking about this problem for a while. Developers and businesses need quality websites fast — but the options are either overpriced custom builds, outdated templates, or starting from scratch every single time. So I decided to build the solution myself. Softchic is a premium template and ready-made website marketplace — production-ready, built on modern stacks, designed to actually look good. This is Week 1 of building it in public. Why Softchic The market exists. Developers need templates. Businesses need websites. But most template stores are either bloated, outdated, or built on stacks nobody wants to touch in 2026. Softchic is different — every template ships with: Modern stack (Next.js, TypeScript, Tailwind CSS v4) Clean, production-ready code Premium design out of the box The name went through 25+ candidates across multiple languages before landing here. Clean, available, memorable — Softchic. The Stack Framework: Next.js 14 (App Router) Language: TypeScript Styling: Tailwind CSS v4 Components: shadcn/ui Payments: Lemon Squeezy (international) + Paystack (Nigeria) Email: Resend Deployment: Vercel Design language: dark and premium — #0D0D0D background, #2563EB blue, #F97316 orange accents. Week 1 — What Got Built ✅ Waitlist page — designed and ready to deploy ✅ Navbar — responsive, dark-themed ✅ WaitlistForm — wired to Resend for email capture ✅ Brand system — colors, typography, full design identity locked ✅ Payment architecture — Lemon Squeezy + IP-based currency detection via ipapi.co with PPP pricing for global fairness The waitlist goes live very soon. Follow me here on Dev.to — I'll drop the link the moment it's live. Early subscribers get first access when the store launches. The launch goal: 200 waitlist subscribers before opening the store. That's the benchmark. No exceptions. What's Next Waitlist page goes live 🚀 Product listing page Template preview system First upload — a SaaS landing page template The Real Talk Building a marketplace fr