077

Word Game App Landing

£20 or the whole Vault, £99

A one-page site for a mobile game or consumer app with a real 3D phone that turns to a new screen as you scroll through four features, and a row of letter tiles that solves itself as the phone glides away. Store buttons, pricing with a monthly and yearly toggle, an FAQ and a scannable QR download block. Built to be adapted in an afternoon: suits word and puzzle games, trivia and quiz apps, education and language apps, habit and streak trackers, and any launch that needs a phone in the hero.

ScrollTriggerSplitText Lenis advanced
11 more details
webgl-shaderpinningscrubsplit-textcount-upaccordionpointer-tiltprocedural-3d3d-transformskeyboard-navigationform-animation

This template reads better at your own screen size than in the frame below:

Released

About this template

Inkling is a complete one-page site for an invented daily word puzzle, written in the voice of a newspaper games page and built so that a buyer can make it their own in an afternoon. Two colours carry it: a cobalt blue and a sunflower yellow, the same pair the game uses for its tiles. A blue-black ink, a warm paper and a high-contrast display serif give it the grown-up, editorial feel of a printed puzzle page, with hard-edged shadows in place of soft ones.

Read the full template overview

The centrepiece is a real 3D phone, built in code with three.js rather than a mockup image. It has a titanium frame, a frosted glass back in deep ink blue with a polished camera plateau, side buttons, a glass front that reflects a small studio, and a status bar drawn around a dynamic island rather than baked into the screens. It stands on a cobalt slab in the hero while a row of letter tiles beside the headline turns over, one by one, as you scroll and spells the day's word. The phone then glides down onto the feature story and stays fixed while it turns a full circle to a new screen for each of four features, with the copy, the stage colour and a step rail changing alongside.

Every screen is an ordinary image referenced by one src in the markup, so replacing the screens needs no code. The five bundled screens were generated with an AI image model and ship with the style sheet and the master files, plus an HTML screen kit for redrawing them exactly. Without WebGL, with reduced motion, with a blocked CDN or with no script, the same screens appear as flat pictures in a device frame, stacked with their copy, and every tile shows its letter. The palette, faces, radii and spacing sit in one token block at the top of style.css, every section is a commented block in index.html, and the README walks through making it yours in thirty minutes.

Word Game App Landing - website template preview

What's included

12 items
  • A real 3D phone built in three.js: rounded titanium frame with a bevelled edge, frosted glass back with a polished camera plateau, a vector status bar round the dynamic island, side buttons, a bottom port and speaker grille, and black glass over the screen
  • A hero row of letter tiles that turns over in order as you scroll, so the day's word solves itself while the phone leaves; scroll back and it un-solves
  • One scrubbed timeline keeps the phone pinned while it turns a full circle and swaps its screen mid-turn for each of four features, with copy, specimen cards, stage colour and a step rail changing alongside
  • The phone glides from the hero onto the story stage on scroll, and leaves with it when the story ends
  • A reusable CSS letter tile (letter, colour state, flip) that also draws the how-to-play rules, the specimen cards and a tile-lettered footer wordmark
  • Five bundled AI-generated app screens with their masters, a screen style sheet for generating matching ones, and an HTML screen kit to redraw them
  • Cobalt and sunflower palette with measured contrast, a display serif and a highly legible UI sans, all in one token block
  • Pricing with a monthly and yearly toggle: prices swap with a roll, plans are repeatable cards and the yearly figures live in the markup
  • Keyboard-operable FAQ accordion, pricing toggle and feature rail with visible focus
  • A QR block that ships a real, scannable code, and store buttons in plain HTML
  • Designed fallback for no WebGL, reduced motion, blocked CDN and no script: the same screens as flat pictures in a device frame, stacked with their copy, every tile face up
  • First-class 390px layout: the phone takes the upper half of the pinned stage and the copy steps in a compact panel below it

Perfect for

6 use cases
  • Word, puzzle, trivia and quiz games launching on iPhone and Android
  • Language-learning and education apps built around a daily habit
  • Habit, streak and wellbeing trackers
  • Consumer apps and SaaS products with a mobile companion
  • Subscription apps that need a free tier and a paid tier side by side
  • Startup waitlists and product pages that want a store-button hero

How it works

6 sections

Structure

One static page in plain sections, each a commented block with a data-section hook and an anchor id. A synchronous head script adds a gate class before first paint, and a second one adds a 3D gate only when the browser has WebGL and motion is allowed. The script takes the classes away again if the phone cannot be built, so the page is always readable.

The phone

The phone is assembled in code from rounded extrusions and simple primitives: frame, glass, camera module, buttons and a port. A small studio of emissive panels is baked into an environment map, so the materials reflect real light. The screen is a shader that shows one image, or two with a soft wipe between them. One fixed canvas draws it over the page and the script places it on whichever slot in the markup is current.

Scroll

GSAP writes the phone's played values into one plain pose object: a scrubbed glide from the hero onto the story stage, then one pinned, scrubbed timeline that turns the phone, swells it briefly, swaps the screen in the middle of the turn and steps the copy and stage colour. The render loop reads that pose every frame and adds the pointer tilt and idle float itself, so continuous motion and played motion never fight.

Letter tiles

A tile is one inline element: its letter is an attribute and its colour is a state. A tile marked to flip has a blank front and a coloured back, and turns over with a single rotation. The hero row is tied to the first screen of scrolling, so it solves as the phone leaves and un-solves in reverse. Any other row turns over once, in order, as it scrolls into view. Without motion every tile simply shows its face.

Features are read from the markup

Each feature is a step block holding its copy, its screen and its specimen cards. The script counts the steps, builds the rail from their labels and sets the scroll distance from their number, so adding or removing a step is a copy or a delete. The pricing toggle and the FAQ work the same way: plans and questions are repeatable blocks the script reads.

Fallbacks

With reduced motion, no WebGL, a blocked CDN or no script, the flat screens show in a simple device frame and every feature is its own coloured band with its copy. Pricing and the FAQ still work whenever GSAP loads, and the FAQ shows every answer open when it does not.

Plugins ScrollTrigger, SplitText
Difficulty Advanced
Smooth scroll Lenis integration
Includes HTML + JS + CSS source, documentation, AI setup prompt, lifetime updates

Lighthouse, as measured

Google Lighthouse on this template's demo, from the latest scan. A measurement of the demo as shipped, not a promise for your page.

Accessibility
100
Best practices
100

No performance score, on purpose. That figure depends on how you deploy: your server's compression and caching, your CDN, the connection and the device doing the test, none of which the code controls. The same page can score very differently on two consecutive runs, so measure it where it will live.

Questions about this template

The bundled app screens are AI-generated. Can I use them, and how do I replace them?

They are original artwork made with an image model for this demo, so ship them if they suit you. Each screen is one image tag with one src; point it at your own screenshot of any portrait size. The download includes the masters, the exact style sheet and prompts, and an HTML screen kit to redraw any screen precisely.

My app is not a word game. What do I do with the letter tiles?

Keep them, retitle them, or delete them. A tile row is a few inline elements whose letters you type into the markup, so spell your own name or a slogan, or remove the hero row and the rules cards. The scroll-driven solve only attaches to a row that asks for it, so nothing else breaks.

How do I change the game colours and the tile states?

Two brand colours, blue and yellow, sit at the top of style.css beside ink, paper and a neutral for the third state. Change them and the tiles, the buttons, the stage tones and the phone's studio light follow. The comment above them lists the measured contrast pairs, so you can see which limits to respect.

How do I set my own free and paid plans?

Plans are repeatable cards, each with a monthly and a yearly figure written as two spans; type both. The bundled example is a free tier with ads, a paid tier that removes them and unlocks an archive, and a family tier. The toggle only swaps which span shows, so there is no billing logic and no payment is taken.

Do the store buttons and QR code work?

The buttons are plain links with placeholder addresses, and the QR code is a real, scannable image of an example address. Replace each href with your App Store and Google Play URLs and swap assets/qr.svg for a code pointing at your store page or smart link. Nothing is tracked or wired until you do.

How much work is it to make this my own?

About thirty minutes for a first pass: rename the app, repaint the token block, swap the screens, then edit the four features, the plans and the questions. Changing the shape of the phone or adding a new kind of section takes longer. Every place to edit carries an EDIT comment, so searching the folder lists the work.

Paid template

Purchase to unlock the code.

Buying Word Game App Landing opens the HTML, CSS and JavaScript source, the full documentation, an AI setup prompt for your editor, and every update we ship to it. Standard license: unlimited personal and commercial projects. Every paid product is tested for desktop and mobile layouts, reduced-motion handling, animation cleanup and keyboard controls wherever there is something to operate.

£20 Standard license, unlimited projects

Browse free effects

Or the whole library: the Vault, £99, one payment.

Documentation

Quick Start

1. Upload the folder. index.html, assets/style.css, assets/script.js (or assets/script.min.js), assets/qr.svg and assets/img/*.webp are the whole site. assets/screens/, assets/img-src/ and assets/img-manifest.json are optional and only used on your machine. Any static host will do.

2. Check the <head>. Four things must stay, in this order:

Code snippet omitted: it ships with the download.

The two small scripts must stay synchronous and in <head>. The first adds the gate class that stops gated elements painting visible for a frame and then flashing to zero. The second adds html.gl, which the stylesheet uses to swap the flat screens for the pinned 3D story before first paint. Copy the probe from index.html exactly. data-cfasync="false" stops Cloudflare Rocket Loader deferring them.

3. Keep the scripts before </body>, in this order:

Code snippet omitted: it ships with the download.

three.js loads as an ES module through an import map, in a dynamic import, so a blocked or failed download simply leaves the flat screens in place. assets/script.js is added by that small module script once three has loaded or failed, so do not add a second <script src="assets/script.js">. Lenis is optional; delete its tag and the page scrolls natively. The minimum supported GSAP is 3.12 (SplitText needs 3.13 for masked lines); the demo is built against 3.15.0.

If your site already uses three.js, keep your own import map and make sure three resolves to r160 or later; the script only needs window.THREE to exist before it runs.


Using It With Your Own Design

Make it yours in 30 minutes

Every place you must change is marked. Search the folder for EDIT: and you have your to-do list.

The comment convention (the same in index.html, style.css and script.js):

Marker Meaning
EDIT: A string, link, number or image you are expected to change
SECTION: The start of one self-contained block, with its data-section hook and anchor id. Delete the whole block to remove the section
REPEAT: A block to copy to add another, or delete to remove one (a feature step, a plan, a question, a review, a stat, a tile)
KEEP: A class or data- attribute the script or layout relies on. Leave it

1. Rename the app (2 minutes). Search for Inkling. It appears in the title and description, the nav and footer lockups, the alt texts and screen labels, the footer wordmark tiles, and the copy. The app icon is the #mark symbol at the top of index.html: replace its two shapes with your logo.

2. Swap the colours and fonts (5 minutes). Everything lives in the :root block at the top of assets/style.css. Change --blue and --sun first, then --ink and --paper. Each colour has an RGB triple beside it; change both. The comment above the tokens lists the measured contrast pairs, so you can see which alpha values must stay. Fonts are --font-display and --font-body; change the Google Fonts link in <head> to match.

3. Swap the screens (5 minutes). Every phone screen is one <img data-screen>: one in the hero and one inside each feature step. Change the src to your own portrait screenshot. Any size works (about 853 by 1844, as bundled, is plenty); the 3D display cover-fits it, so it is never stretched. The same image is the flat fallback for visitors without WebGL, so write a real alt. No code changes. See The screens below.

4. Edit the features (5 minutes). Each feature is a REPEAT block, a .step. Change its data-tone (sun, blue, butter or ink, or add your own in style.css), its label, headline, paragraph, three points, screen and specimen cards. Copy a whole step to add a feature; delete one to remove it. The step number, the rail, the scroll distance and the phone's turns follow. Two to six features suit the pacing.

5. Edit pricing and questions (5 minutes). Each plan is an article.plan. A price holds two spans, data-billing="monthly" and data-billing="yearly"; type both, at the same width if you want the "per month" label to sit tight. A plan with one price (Free) needs neither. Add or delete plan cards freely, and add plan--featured to the one you want in ink. FAQ items are .faq-item blocks; add data-faq-open to the one you want open on load.

6. Wire the store links and the QR code (3 minutes). Replace the href on every .store-btn with your App Store and Google Play URLs (the hero and nav buttons scroll to the download block in the demo; point them at the stores if you prefer). Replace assets/qr.svg with a QR code for your store page or a smart link, or change its src. The bundled code is a real code for an example address, so do not ship it. The pricing plans are a front end only: no payment is taken and nothing is stored.

7. Proof and press (5 minutes). The stat band counts up to whatever number is written in each [data-count] element, keeping any prefix or suffix (2.4M, £38M). Press names and reviews are plain text. Replace them with real ones, and remove the section if you have none.

Sections and their hooks

Section Hook Anchor Notes
Nav data-section="nav" none A masthead bar. data-nav-optional links hide on phones
Hero data-section="hero" #top Dateline, headline, copy, store buttons, the solving tile row, floating cards and the hero phone slot
Story data-section="story" #features The pinned feature story. data-spin is the turn between features in degrees (360 by default, 0 for a calm swap)
Press data-section="press" none A quote and a column of names
How data-section="how" #how Three rule cards, each with a row of tiles that turn over on entry
Proof data-section="proof" #reviews Count-up stats, the store rating and reviews. On the cobalt ground
Pricing data-section="pricing" #pricing data-period on the section is the starting period (monthly or yearly)
FAQ data-section="faq" #faq An accordion, one open at a time
Download data-section="download" #download Closing headline, store buttons and the QR card
Footer data-section="footer" none Links, legal line and the tile wordmark

Delete any section (the whole block from its SECTION comment to its closing tag) and the rest keeps working: every initialiser in script.js returns early when its markup is missing, and the nav links to a removed anchor simply do nothing. Remove the matching nav and footer links too.

The letter tiles

A tile is one element: <i class="tile" data-l="S" data-state="hit"></i>. The letter is data-l, so it is drawn by CSS and is not text a screen reader reads. data-state picks the colour.

data-state Look Meaning in the example
hit Cobalt, white letter Right letter, right place
near Sunflower, ink letter In the word, wrong place
miss Slate, paper letter Not in the word
plain White with an ink outline A typed letter, not yet submitted

Size a row with --tile on its .tile-row (or use .tile-row--m, --s, --xs). Add tile--flip to a tile and it gets a blank front and a coloured back; the script turns it over.

Attribute Effect
data-tiles="scroll" on a .tile-row The row is tied to the first screen of scrolling: it solves as the page scrolls and un-solves on the way back. This is the hero row
data-tiles on a .tile-row The row turns over once, in order, when it scrolls into view

Tiles are decorative, so wrap a meaningful row in an element with role="img" and an aria-label (the hero does), or hide it with aria-hidden="true" (the how-to-play art and the footer wordmark do). If your app is not a word game, spell your name or a slogan in them, or delete the rows; nothing else depends on them.

The screens

Each screen is an image. There is nothing to configure: the script collects the hero's img[data-screen] and each step's img[data-screen], in page order, and puts them on the phone.

File Where it shows
assets/img/screen-home.webp The hero
assets/img/screen-board.webp, screen-streaks.webp, screen-hints.webp, screen-leagues.webp The four feature steps, in order

The bundled screens are AI-generated. They were made with an image model (OpenAI image generation through the Codex CLI) from one written style sheet, first the puzzle board, then the other four with the board attached as a reference so they read as one app. Every word and tile was checked at full size and the two weakest were regenerated. They are original artwork for this demo, so you can ship them, but they show a fictional app: replace them with your own. The masters are in assets/img-src/ (JPEG, 853 by 1844), each with its top 6.5 percent painted as a plain strip of paper because the phone draws the status bar itself. assets/img-manifest.json lists how they are baked to WebP: bun scripts/build-template-assets.ts word-game-app-landing-template --force in the Vault repo, or any WebP encoder at the same size.

To replace a screen: export a portrait screenshot without its status bar (about 853 by 1844 is plenty; a 9 by 19.5 ratio fills the phone exactly), save it in assets/img/, and change the src of the matching <img data-screen>. Keep width and height in step with the file so the flat fallback does not shift.

To generate a matching set for your own app: assets/screens/screen-style-sheet.md is the exact style sheet the bundled screens were made from, with the palette, type, shapes and the brief pattern. Paste it into any image tool, attach assets/img-src/screen-board.jpg as the reference, describe each screen with its exact words and tile colours, and ask for a very tall 9:19.5 portrait. Image models misspell and miscount, so inspect every word at full size and regenerate weak ones.

To redraw a screen exactly: assets/screens/screen-kit.html is plain HTML for all five screens, built on the same tokens and the same .tile component as the site. Edit it, then in DevTools right-click a .screen element and choose Capture node screenshot (at a device pixel ratio of 3), or capture it with Playwright:

Code snippet omitted: it ships with the download.

Practical notes for your own screens:

  • Leave the top 6.5 percent as a plain strip of the screen's own colour, and start your header below it and inset from the rounded corners. The phone draws its own status bar there (the clock, signal, wifi and battery, as vectors, either side of the dynamic island and a corner radius in from the edge), and the flat fallback draws the same one in CSS, so a screenshot that already has one shows two. Export screenshots without the status bar, or paint the strip over.
  • Dark screens. The status glyphs are dark ink. The 3D phone measures the top of each screenshot and switches to white glyphs on a dark one; data-tone="dark" or "light" on the <img data-screen> sets it outright (an image from another origin cannot be measured, so give those the attribute). The flat fallback, which draws its status bar in CSS, reads only the attribute. The step's own data-tone is its stage colour, a separate thing.
  • The clock reads 9:41. Set data-status-time on the hero slot to change it in the 3D phone; the flat fallback's clock is the content of .shot-frame::after in style.css.
  • Any aspect works. The display is 9 to 19.5; an image of another ratio is cropped to fill, never stretched. A squarer image loses its sides.
  • Weight. Each bundled screen is about 70 KB as WebP.

The phone

The phone is built in code (see buildPhoneModel in script.js): a bevelled titanium frame, a frosted glass back (a fine seeded grain in its bump and roughness, so the studio light spreads across it the way etched glass takes it), a polished glass camera plateau carrying three machined-metal lenses with dark multi-coated glass, a frosted flash, a lidar sensor and a microphone pinhole, four side buttons, a bottom port and speaker grille, and black glass over the screen with a dynamic island. The status bar is drawn as vectors in the screen shader, so it stays crisp at any size and its glyphs follow each screen's tone through the wipe. The display's corners are concentric with the body's, and the screen is clipped to that curve by a rounded-rectangle mask in the screen shader, so the bezel is one even width all the way round. Lit by a small studio baked to an environment map, so the metal and glass catch real reflections.

Token or attribute Effect
--phone-frame The metal frame colour (a blue-grey titanium). The lens rings are this colour lifted a little toward white
--phone-back The back glass colour (frosted, in a deep ink blue); the camera plateau is the same glass a shade darker and polished. Deep, real-phone colours read best; a bright flat back reads as a toy
--phone-light The colour of the floor bounce in the studio light
--screen-bg The colour shown on the display while a screen loads
data-status-time on the hero slot The status bar clock (default 9:41)
data-tilt on the hero slot How far the phone is turned in the hero, in radians (default -0.24)
data-idle="0" on the hero slot Turns off the idle float
data-intro="0" on the hero slot Skips the load entrance
?still=1 in the URL Both of the above, for screenshots
data-spin on the story section Degrees the phone turns between features

The phone's size and position come from the two empty slots in the markup, data-phone-slot="hero" and data-phone-slot="story", which reserve room in the layout; the fixed canvas only draws on top of them. Change a slot's size in CSS (--phone-h) and the phone follows.


Palette

Colour is a handful of tokens at the top of style.css, each with its RGB triple, so every translucent value is mixed from one source:

Token Role
--blue Cobalt: the hero slab, the proof band, buttons, correct tiles. Text on paper at 7.4:1
--sun Sunflower: the download block, near tiles, the featured plan's button. A fill, never text on paper (1.5:1)
--butter A soft yellow for the pricing ground and the hints step
--ink Blue-black: all type on light grounds, and the dark bands
--paper, --sand The page and its second step
--white, --slate Cards, and the tile that missed
--phone-frame, --phone-back, --phone-light The 3D phone's metal, glass and studio light

Measured contrast is written beside the tokens. On cobalt use --paper or --paper-dim, never --paper-faint; --ink-faint is for paper, sand and white surfaces.

Typeface

Noto Serif Display (700, plus one italic) carries headlines, numerals, tile letters and the wordmark; Atkinson Hyperlegible Next at 400, 500, 600 and 700 carries everything else. They are set in --font-display and --font-body. Any high-contrast display serif and any legible UI sans will do; check headline wrapping after you change them, because the hero title is sized so each line sits on one line.

Imagery and credits

No photographs are bundled: the phone is 3D, the screens are AI-generated artwork or redrawn from the kit, and the page has no stock images. The QR code encodes an example address. three.js (MIT licence) is loaded from a CDN, and the Noto Serif Display and Atkinson Hyperlegible fonts (SIL Open Font Licence) from Google Fonts.


Accessibility and fallbacks

  • Keyboard. The FAQ, the pricing toggle and the feature rail are native buttons with a visible focus ring. The rail jumps to a feature by moving the scroll position. FAQ panels are exposed as regions and hidden from screen readers while closed.
  • Screen readers. The 3D canvas is decorative and hidden. Every feature's copy is real text in the document, and each flat screen has a real alt. The pricing toggle announces the period it switches to. Tile letters come from data-l, so decorative rows are not read out; the hero row carries a single label.
  • Colour. The tiles use blue and yellow, not red and green, and every tile carries its letter, so colour is never the only clue.
  • Reduced motion. No 3D phone, no pin, no scrub, no tile turning. Every feature becomes its own coloured band with its copy, its flat screen in a device frame and its specimen cards; every reveal is visible; every tile is face up; counters show their final figures. Pricing and the FAQ still work, without motion.
  • No WebGL. The same flat, stacked layout, and the console stays clean because WebGL is probed before a renderer is built.
  • No JavaScript, or the CDN blocked. Everything is readable: the gate class is removed, the screens show, the tiles are face up, the FAQ answers are all open and both pricing periods read as text.
  • Touch and small screens. The pinned story is redesigned for a phone: the 3D phone takes the upper half of the stage and the copy steps in a compact panel beneath it. The pixel ratio is capped at 1.5 on touch, and the phone geometry uses fewer segments.
  • Smooth scroll. Lenis is on by default; add data-smooth="off" to <html> or ?smooth=off to the address to turn it off. Reduced motion turns it off automatically.

Browser support

Current Chrome, Safari, Firefox and Edge. The 3D phone needs WebGL 2; every browser without it shows the flat layout. The stage uses :has() to paint its first tone before the script runs, and the tile ticks use CSS masks.

Performance

One fixed canvas draws the phone, and only while it can be on screen (from the top of the page until the story has scrolled away). It renders at a pixel ratio capped at 2 (1.5 on touch) and the model is about 30 draw calls. The first lever to lower it: cap the ratio at 1.5 in buildPhone (Math.min(window.devicePixelRatio || 1, ...)). The screens are the only heavy assets, so export them smaller if you need to shave weight.

Dependencies

GSAP 3.12 or later with ScrollTrigger, plus SplitText 3.13 or later for the masked headline (demo built against 3.15.0); three.js r160 or later as an ES module (demo built against 0.180.0). Lenis 1.3 is optional.

GSAP writes the phone's played motion (the hero-to-story glide, the pinned turn-and-swap timeline and the load entrance) into one pose object, turns the letter tiles over (scrubbed with the scroll in the hero, played on entry elsewhere), and runs the reveals, count-up, pricing and FAQ. The render loop, not GSAP, owns everything continuous: the pointer tilt, the idle float and the drawing.

Teardown

Everything runs inside one gsap.context() exposed as window.gsapContext. Call window.gsapContext.revert() to remove the pinned story, the tiles' turning, the reveals, the listeners, the 3D canvas (its geometry, materials, textures and WebGL context are released) and Lenis if this script started it. A host's own Lenis is left running.

Worked examples, the events and programmatic API, and the class reference ship with the download, alongside the full source.