---
name: storyfeed-custom-css
description: Mimic any publisher site's look in a StoryFeed embed — extract brand colors, fonts and button styles from the target site and produce feedCss/detailCss override JSON plus embed snippet and admin paste instructions. Use when asked to style, customize, theme, or brand-match a story-feed demo.
version: 0.1.0
---

# StoryFeed Custom-CSS Skill

Clone the visual identity of any media site into a `<story-feed>` embed, without touching the component bundle.

## When to use

Use this skill when the user asks (in any language) to style / customize / theme a storyfeed demo to look like a target site, e.g.:

> use storyfeedmedia.com custom-css skill for this storyfeed https://storyfeedmedia.com/demos/caras-demo.html and apply the styling to mimic this site https://caras.perfil.com

## Inputs you need

1. **Baseline demo URL** — a page embedding `<story-feed>` (e.g. `https://storyfeedmedia.com/demos/caras-demo.html`). Fetch it and read:
   - `<story-feed>` attributes (`endpoint`, `client`, `limit`, `background-blur`, …)
   - the `<script type="application/json" class="gts-custom-css">` block (`feedCss` / `detailCss`)
   - the Google Fonts `<link>` tags in `<head>`
2. **Target site URL** — the publisher to mimic (e.g. `https://caras.perfil.com`). Fetch the homepage HTML + its stylesheets and extract the identity tokens (step 2).

If either URL is missing, ask for it. Never invent brand values — always extract them from the live target.

## How it works (mechanism)

- `<story-feed>`, `<story-panel>`, `<story-reel>`, `<story-detail>` render inside **native Shadow DOM**. Global CSS of the host page does NOT reach them.
- The only styling entry point is `<script type="application/json" class="gts-custom-css">` as a direct child of `<story-feed>`:
  ```html
  <story-feed endpoint="https://api.storyfeedmedia.com/api/v1/feed" client="mimedia" limit="10" background-blur>
    <script type="application/json" class="gts-custom-css">
      { "feedCss": "/* story-panel + story-reel */", "detailCss": "/* story-detail */" }
    </script>
  </story-feed>
  ```
- `feedCss` is injected into every `<story-panel>` / `<story-reel>` shadow root; `detailCss` into `<story-detail>`.
- Web fonts declared in the host `<head>` ARE inherited through shadow boundaries, so load Google Fonts in `<head>` and reference the family names inside `feedCss`/`detailCss`.
- Never edit `public/js/story-feed*.js` or the component bundle. Only produce `feedCss` / `detailCss` + `<head>` font links.

## Step 1 — Read the baseline demo

Fetch the demo URL. Record `endpoint`, `client`, `limit` and the current `feedCss`/`detailCss` + font links. Keep the same `endpoint`/`client` in your output unless the user asks to change the feed source.

## Step 2 — Extract the target identity

Fetch the target homepage (and 1–2 linked stylesheets if needed). Extract:

| Token | Where to look | Example (CARAS) |
|---|---|---|
| Primary brand color | CTA buttons, badges, logo accents, link hovers | `#E30613` red |
| Dark surfaces / text colors | body bg, card overlays, headlines | `#0F0F0F` / `#FFFFFF` / `#E2E2E2` |
| Headline font | `h1`/`h2`, hero titles (`font-family`, weight, uppercase?) | `Roboto Condensed` 700, uppercase badges |
| Body font | paragraphs, excerpts, dates | `Open Sans` 400 |
| Button shape | `border-radius`, padding, uppercase, shadow on CTA | `4px` rect, uppercase, red w/ shadow |
| Detail accents | blockquote border, excerpt bar, tag pills, avatar gradient | red left-bar, red `#tag` hover |

Reference implementation: CARAS demo at `https://storyfeedmedia.com/demos/caras-demo.html` mimics `https://caras.perfil.com` (red `#E30613`, `Roboto Condensed` headlines, `Open Sans` body).

## Step 3 — Write `feedCss` (feed cards)

Allowed selectors (applied to `<story-panel>` + `<story-reel>`): `:host`, `.panel`, `.media`, `.scrim`, `.content`, `.eyebrow`, `h2`, `p.subtitle`, `.footer`, `.meta`, `.author`, `.date`, `.footer-actions`, `.cta` (+`:hover`), `.share-actions`, `.share-btn`, `.share-btn svg`, `.copied-badge`.

Rules:

- `:host` sets the base `font-family` fallback stack.
- `.scrim` gradient guarantees headline legibility over photos.
- `h2` uses the editorial headline font; `p.subtitle` the body font with `-webkit-line-clamp: 3` truncation.
- `.eyebrow` badge carries the primary brand color.
- `.cta` carries the primary brand color + brand radius + hover state.
- Circular buttons MUST stay geometrically centered:
  ```css
  .share-btn { display: inline-flex; align-items: center; justify-content: center; padding: 0; width: 38px; height: 38px; min-width: 38px; min-height: 38px; box-sizing: border-box; border-radius: 50%; }
  .share-btn svg { width: 18px; height: 18px; display: block; margin: auto; }
  ```

## Step 4 — Write `detailCss` (article reader)

Allowed selectors (applied to `<story-detail>`): `:host`, `.wrap`, `.close` (+`:hover`), `.detail-page`, `.body`, `h2`, `.excerpt`, `.author`, `.avatar`, `.author-who`, `.content`, `.content p`, `.content strong, .content b`, `.content h1, h2, h3, h4`, `.content h3`, `.content a`, `.content blockquote`, `.content img`, `.tags`, `.tags-eyebrow`, `.tag` (+`:hover`), `.source`, `.detail-footer`, `.ad-disclosure`. Hide scraper leftovers with `.wrap #article-content ... { display: none !important; }`.

Rules:

- `:host` sets modal backdrop + base body font.
- `h2` uses the headline font at 800; `.excerpt` is italic with brand `border-left: 3px solid <color>`.
- `.avatar` uses a brand gradient; `.content a` / `.content h3` / `blockquote` carry the brand color.
- `.close` is a centered circle with brand hover.

## Step 5 — Emit the output (always all four parts)

1. **Font `<link>` tags** for `<head>` (Google Fonts, non-blocking pattern with `media="print" onload` + `<noscript>` fallback — see the CARAS demo source).
2. **`gts-custom-css` JSON** — `{ "feedCss": "...", "detailCss": "..." }` with real `\n` newlines, valid JSON (escape quotes).
3. **Full `<story-feed>` embed snippet** reusing the baseline `endpoint`/`client`/`limit` with your new script block + module script tag `https://storyfeedmedia.com/js/story-feed.min.js`.
4. **Admin panel instructions** — "Open feed → Custom CSS → paste `feedCss` into Feed CSS field, `detailCss` into Detail CSS field → save → embed regenerates with the same block."

## Step 6 — Validate before answering

- [ ] JSON parses (`feedCss` + `detailCss` present, strings).
- [ ] Only allowed selectors used; no `100vh` inside components (`:host { height: 100% }` max).
- [ ] Headlines legible over dark AND light photos (scrim + text-shadow).
- [ ] Share icons and `.close` centered; CTA hover defined.
- [ ] Fonts referenced in CSS match the `<head>` links.
- [ ] `endpoint`/`client` unchanged from baseline unless asked.

## Constraints

- Read-only skill: never touch admin APIs, bundles, or the target site. Output CSS + snippet only.
- If the target site blocks fetching, fall back to its public homepage meta/theme-color + visible system fonts, and say so explicitly.
- Keep the response focused: tokens found → the four output parts → validation notes. This skill is self-contained — it carries the full knowledge needed; there is no separate guide URL to fetch or link.
