Communitygithub.com

brainzcode/premium-landing

Source free, licence-clear photography for a site from Unsplash — searching by mood rather than noun, sizing and cropping for the slot, honouring the API's hotlink and download-tracking requirements, and writing real alt text. Use when a page needs a hero image, section photography, avatars or card art and none was supplied; when placeholder greys need replacing with real imagery; or when asked to find, pick or swap photos for a design.

premium-landing とは?

premium-landing is a Claude Code agent skill that source free, licence-clear photography for a site from Unsplash — searching by mood rather than noun, sizing and cropping for the slot, honouring the API's hotlink and download-tracking requirements, and writing real alt text. Use when a page needs a hero image, section photography, avatars or card art and none was supplied; when placeholder greys need replacing with real imagery; or when asked to find, pick or swap photos for a design.

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/brainzcode/premium-landing/tree/HEAD/plugins/premium-landing/skills/stock-imagery

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

Stock imagery

A landing page with a grey placeholder where the hero should be is unfinished. This covers sourcing real photography that is free to use commercially, matches the design, and does not break when someone else loads the page.

The endpoint everyone tries first is dead

https://source.unsplash.com/1600x900/?coffee     →  HTTP 503

source.unsplash.com — the keyless random-image endpoint — was retired. It is still all over blog posts and older templates, and it now returns 503. If you find it in a codebase, that is a broken image, not a working one.

What does work, keyless, is the CDN when you already know a photo id:

https://images.unsplash.com/photo-1447933601403-0c6688de566e?auto=format&fit=crop&w=1600&q=80

That returns a real image. But you cannot search without a key, and inventing photo ids does not work. So:

Getting a key (two minutes, free)

  1. https://unsplash.com/oauth/applications → New Application → accept the terms
  2. Copy the Access Key
  3. Export it — never commit it:
export UNSPLASH_ACCESS_KEY="your_access_key"

Demo tier is 50 requests/hour, which is ample for a landing page. If the user has no key, say so and ask — do not silently fall back to grey boxes and do not invent URLs.

curl -s -H "Authorization: Client-ID $UNSPLASH_ACCESS_KEY" \
  "https://api.unsplash.com/search/photos?query=coastal+fog&orientation=landscape&per_page=8" \
| python3 -c "
import json,sys
for p in json.load(sys.stdin)['results']:
    print(p['id'], p['width'], p['height'], '|', (p.get('alt_description') or '')[:60])
    print('   ', p['urls']['raw'])
    print('   ', p['user']['name'], p['links']['download_location'])
"

Two API rules that are easy to miss

1. Hotlink the URLs the API returns. The Unsplash API terms require using their CDN URLs rather than re-hosting the file. That conflicts with the usual advice to serve local optimised assets, and the terms win while you are using the API. If a client needs self-hosted files, license the photo through Unsplash+ or buy elsewhere — do not quietly re-host and hope.

2. Trigger the download endpoint when a photo is actually used. Not when it is previewed — when it ships. This is how photographers get credited with usage, and it is a condition of the API, not a courtesy.

curl -s -H "Authorization: Client-ID $UNSPLASH_ACCESS_KEY" \
  "$DOWNLOAD_LOCATION"   # the links.download_location value from the search result

Licence boundaries

The Unsplash License allows commercial and non-commercial use with no permission and no required attribution. It does not allow selling unaltered copies, and it does not allow building a competing photo service. Photos may contain identifiable people, trademarks or artwork — Unsplash does not clear model or property releases, so for anything implying endorsement (a person appearing to be a customer, a testimonial photo) get a released image instead.

Attribution is not required but costs one line and is the right thing to do:

<!-- Photo: Jane Doe / Unsplash -->

Choosing well

Searching the literal noun is what makes a page look like a template. "Coffee" returns ten thousand identical latte-art overheads.

Search the mood, not the subject. For a coffee roastery: warm industrial workshop, hands working, morning light interior. For a wealth advisory: still architecture, quiet minimal interior, long shadows.

Then filter on three things the design actually constrains:

  • Orientation and subject placement. A hero that crops with object-fit: cover needs the subject off-centre or with headroom, or the crop decapitates it. Check where the subject sits before choosing — the framing arithmetic is in ../landing-page/references/traps.md.
  • Tonal range. Overlaid text needs the region behind it to be consistently light or consistently dark. A busy mid-tone photo makes every text colour wrong.
  • One photographer, or one look. Three images from three photographers in one section reads as stock. Prefer several frames from a single shoot, or a consistent grade.

Sizing

Unsplash CDN parameters do the resizing, so request the size you display:

?auto=format&fit=crop&w=1600&q=80        hero
?auto=format&fit=crop&w=800&q=80         card
?auto=format&fit=crop&w=192&h=192&q=80   avatar (square)

auto=format serves WebP/AVIF to browsers that accept it. For responsive heroes, emit a srcset at 800/1200/1600/2000 rather than shipping one 2000px file to phones.

Alt text

alt describes what the image shows, for someone who cannot see it. It is not a keyword slot and not the photo's title.

<!-- no -->
<img alt="coffee roastery landing page hero image">
<!-- yes -->
<img alt="Roaster tipping green beans into a drum roaster in a workshop">

If the image is decorative and the surrounding text already says everything, use alt="" so a screen reader skips it. An empty alt is correct; a missing alt is not.

Checklist

  • UNSPLASH_ACCESS_KEY set, never committed
  • Searched the mood, not the literal noun
  • Subject placement checked against how the slot crops
  • Tonal range works under any overlaid text
  • Images in one section share a look
  • CDN URLs hotlinked as the API requires — not re-hosted
  • download_location triggered for every photo that ships
  • Sizing params match the display size; srcset on responsive heroes
  • Real alt text, or alt="" when decorative
  • No model/property-release assumption for anything implying endorsement

Individual skills in this repo

This repo contains 7 individual skills — each has its own dedicated page.

brainzcode/premium-landing

Add a studio or agency build credit to a website footer — "Site by <Studio>" linking to the studio's site. Use when finishing or shipping a site, adding a footer, or when asked for an agency credit, build credit, designed-by line, or attribution. Covers wording, placement opposite the client's copyright, markup for each stack, styling from the host site's tokens, and the sitewide-footer-link SEO footprint when the same credit runs across many client sites.

brainzcode/premium-landing

Build a complete premium landing page, either replicated from a reference screenshot/URL or designed from a written brief, in HTML, React, Next.js or Astro. Use when asked to build, design, replicate or clone a landing page, marketing page, or one-page site; when handed a design screenshot or Figma/Pinterest reference to turn into code; or when a landing page needs a full premium pass. Covers design tokens, section patterns, the layout traps that silently break grids and marquees, and screenshot-based responsive verification from 320px to 1920px.

brainzcode/premium-landing

Add Lenis smooth scrolling to a site correctly — setup, anchor offsets for sticky headers, scroll locking for modals and menus, reduced-motion handling. Use when asked for smooth scroll, Lenis, momentum/eased scrolling, or when smooth scroll broke a sticky header, a modal lock, or anchor links. Includes the sticky-position trap that only appears at non-zero scroll.

brainzcode/premium-landing

Build true Apple-style liquid glass in the browser — real refraction via SVG displacement maps, chromatic dispersion, specular edges. Use when asked for liquid glass, glassmorphism, frosted/glass cards, glass navbars, or when a blur-based "glass" effect looks flat. Includes the performance trap that makes backdrop-filter stutter on scroll and the contrast trap that makes text unreadable on glass.

brainzcode/premium-landing

Build a premium mobile nav — a hamburger button that morphs into a close X, a full-screen overlay panel with staggered link reveal, scroll lock, focus trap, and reduced-motion handling. Use when asked for a mobile menu, hamburger/burger button, nav drawer, off-canvas menu, or when a menu loses scroll position, still scrolls behind on iOS, leaks Tab focus to the page underneath, or the close button stops responding. Includes the z-index trap that swallows the close button and the iOS rubber-band trap.

brainzcode/premium-landing

Rebuild a design accurately from a supplied reference — a screenshot, PDF page, mockup or live URL — by measuring it numerically instead of eyeballing it. Use when asked to replicate, clone, match or rebuild a design "exactly", "1 to 1" or "with no mistakes", or when a build drifts from its reference. Covers extracting the true content box from a padded screenshot, deriving element positions as percentages, solving object-fit framing, and knowing when a reference cannot be matched.

brainzcode/premium-landing

Ship link previews and favicons that actually work - Open Graph and Twitter card tags, a correctly framed 1200x630 share image, and a full favicon set (SVG, ICO, apple-touch, maskable manifest icons). Use when asked for social sharing, OG image, open graph, twitter card, link preview, share image, favicon, app icon, apple touch icon, or web manifest. Also use when a shared link previews blank, shows the wrong image, or a favicon will not appear. Includes the absolute-URL trap that silently blanks every preview and the font trap that breaks SVG favicons on other machines.

関連スキル