npm package: @startnext/chrome
Description: Startnext Chrome Web Components
Author: Startnext
Latest version: 0.5.6

# @startnext/chrome

> Startnext Header/Footer Web Components

Wiederverwendbare Header- und Footer-Components für alle Startnext Microservices.

## Installation

```bash
npm install @startnext/chrome
# or
pnpm add @startnext/chrome
```

## Quick Start

### Modern JavaScript (React, Vue, etc.)
```javascript
import '@startnext/chrome';
```

```html
<startnext-header></startnext-header>
<startnext-footer></startnext-footer>
```

**React 18 + Next.js (lazy import):**

```jsx
import { useEffect } from 'react';

export function ChromeHeader() {
  useEffect(() => { import('@startnext/chrome'); }, []);

  return (
    <startnext-header
      api-url="https://scs-api.vercel.app"
      light-header
      hide-lang hide-cta hide-color-mode show-back-link
    />
  );
}
```

### Via CDN (PHP, Vanilla HTML)
```html
<script type="module" src="https://unpkg.com/@startnext/chrome@latest/dist/index.js"></script>

<startnext-header></startnext-header>
<startnext-footer></startnext-footer>
```

## API

### `<startnext-header>`

**Attributes:**

| Attribute | Type | Default | Description |
|---|---|---|---|
| `api-url` | `string` | - | URL des SCS API (z. B. `https://scs-api.vercel.app` oder relativ `/scs-api`). Ohne Attribut: statische Default-Daten |
| `lang` | `string` | `'de'` | Aktive Sprache (beliebiger 2-Buchstaben-Code, z. B. `'de'`, `'en'`, `'fr'`) |
| `languages` | `string` | - | Kommagetrennte Liste von Sprachcodes, auf die der Language-Switcher eingeschränkt wird, z. B. `'de,en'`. Ohne Attribut: alle vom API gelieferten Sprachen. Der Switcher wird automatisch ausgeblendet, wenn nach dem Filtern nur noch 1 Sprache übrig bleibt |
| `light-header` | `boolean` | `false` | Weiße Schrift/Icons im Header (unabhängig von `color-mode`, z. B. über einem dunklen Hero-Bild) |
| `large-animation` | `boolean` | `false` | Große Lottie-Logo-Animation mit Claim und horizontaler Navigation (z. B. für die Startseite). Erfordert `api-url` |
| `authenticated` | `boolean` | `false` | Zeigt User-Avatar statt "Anmelden" Button |
| `user-name` | `string` | - | Name des eingeloggten Users |
| `user-avatar` | `string` | - | Avatar-URL des Users |
| `color-mode` | `'light' \| 'dark'` | auto | Seitenweiter Farbmodus. Ohne Attribut: Header liest `<html class="dark/light">` beim Mount (Default: `light`). Mit Attribut: Header setzt die `<html>`-Klasse entsprechend und steuert damit auch Seiten-CSS-Variablen (`html.dark { ... }`). Der Toggle-Button im Header wechselt `<html>`-Klasse und emittet `color-mode-change` |
| `hide-color-mode` | `boolean` | `false` | Versteckt den Color-Mode Toggle-Button |
| `hide-lang` | `boolean` | `false` | Versteckt den Language-Switcher komplett |
| `hide-login` | `boolean` | `false` | Versteckt den "Anmelden" Button (auch wenn nicht eingeloggt) |
| `hide-cta` | `boolean` | `false` | Versteckt den CTA-Button ("Projekt starten") |
| `show-back-link` | `boolean` | `false` | Zeigt den aus der API gelieferten "Zurück"-Link links neben dem Logo. Nur sichtbar wenn in Notion konfiguriert |

**Events:**

| Event | Detail | Description |
|---|---|---|
| `burger-menu-toggle` | `{ open: boolean }` | Burger-Menü geöffnet/geschlossen |
| `user-menu-toggle` | `{ open: boolean }` | User-Menü geöffnet/geschlossen |
| `navigation-click` | `{ item: NavigationItem }` | Navigation-Link geklickt |
| `cta-click` | `{ url: string }` | "Projekt starten" Button geklickt |
| `logout` | `{}` | Abmelden geklickt |
| `language-change` | `{ language: string }` | Sprache gewechselt |
| `scroll-state-change` | `{ scrolled: boolean, slideUp: boolean }` | Scroll-Zustand geändert |
| `color-mode-change` | `{ mode: 'light' \| 'dark' }` | Farbmodus gewechselt (per Toggle-Button) |

**Usage Examples:**

```html
<!-- Default: dunkler Header (dunkle Schrift für helle Seiten) -->
<startnext-header></startnext-header>

<!-- Mit Live-Daten vom SCS API -->
<startnext-header api-url="https://scs-api.vercel.app" lang="de"></startnext-header>

<!-- Sprachauswahl auf DE und EN einschränken -->
<startnext-header api-url="/scs-api" lang="de" languages="de,en"></startnext-header>

<!-- Heller Header (weiße Schrift über dunklem Hero) -->
<startnext-header light-header></startnext-header>

<!-- Heller Header + große Animation (z.B. Startseite) -->
<startnext-header api-url="/scs-api" light-header large-animation></startnext-header>

<!-- Heller Header + groß + eingeloggt -->
<startnext-header
  api-url="/scs-api"
  light-header
  large-animation
  authenticated
  user-name="Elias Groesel"
  user-avatar="https://..."
></startnext-header>

<!-- Zurück-Link anzeigen (aus Notion/API, z.B. auf Unterseiten) -->
<startnext-header api-url="/scs-api" show-back-link></startnext-header>

<!-- Nur DE, kein Login, kein CTA -->
<startnext-header languages="de" hide-login hide-cta></startnext-header>
```

```html
<!-- light-header und color-mode sind unabhängig voneinander -->

<!-- Heller Header über dunklem Hero, Seite selbst im Light Mode -->
<html class="light">
  <startnext-header light-header large-animation></startnext-header>
</html>

<!-- Seite im Dark Mode (html.dark), Header dennoch weiße Schrift -->
<html class="dark">
  <startnext-header color-mode="dark" light-header large-animation></startnext-header>
</html>

<!-- Seite dunkel, Header mit explizit gesetztem color-mode (schreibt html-Klasse nicht) -->
<html class="dark">
  <startnext-header color-mode="light"></startnext-header>
</html>
```

```javascript
const header = document.querySelector('startnext-header');

header.addEventListener('navigation-click', (e) => {
  console.log(e.detail.item);
  // e.preventDefault() to handle navigation yourself
});

header.addEventListener('language-change', (e) => {
  // Sprache auch im Footer synchronisieren
  document.querySelector('startnext-footer').setAttribute('lang', e.detail.language);
});

header.addEventListener('logout', () => {
  // Handle logout
});

header.addEventListener('color-mode-change', (e) => {
  console.log(`Color mode: ${e.detail.mode}`); // 'light' | 'dark'
  // <html>-Klasse wird automatisch vom Header gesetzt
});
```

### `<startnext-footer>`

**Attributes:**

| Attribute | Type | Default | Description |
|---|---|---|---|
| `lang` | `string` | `'de'` | Aktive Sprache (beliebiger 2-Buchstaben-Code) |
| `api-url` | `string` | - | URL des SCS API. Ohne Attribut: statische Default-Daten |
| `lang-sync` | `boolean` | `true` | Synchronisiert `lang` automatisch beim `language-change`-Event des Headers. Mit `lang-sync="false"` deaktivieren |

**Events:**

| Event | Detail | Description |
|---|---|---|
| `navigation-click` | `{ item: { url, label } }` | Footer-Link geklickt |

## Theming

Override CSS Custom Properties:

```css
startnext-header {
  --primary-color: #0066FF;
  --btn-primary-bg: #0066FF;

  /* Header-Hintergrund */
  --header-bg: transparent;          /* Standard-Hintergrund (Default: transparent) */
  --header-bg-scrolled: #FAFAFA;     /* Hintergrund wenn gescrollt */

  /* Textfarben — überschreiben --text-primary gezielt für den Headbar */
  --header-text: #FFFFFF;            /* Textfarbe Standard (z.B. weiß über Hero) */
  --header-text-scrolled: #304b50;   /* Textfarbe wenn gescrollt */
}

startnext-footer {
  --footer-bg: #111111;
  --footer-link-hover: #0066FF;
}
```

`--header-text` und `--header-text-scrolled` sind eine Alternative zu `light-header` wenn mehr Kontrolle über die Textfarbe gewünscht ist (z. B. transparenter Header über dunklem Bild mit weißem Text, aber weißem Header-Hintergrund nach dem Scrollen mit dunklem Text).

## Fonts

Standardmäßig nutzen die Components System-Fonts als Fallback. Für eigene Schriftarten `@font-face` im eigenen CSS deklarieren und `--font-family` setzen:

```css
@font-face {
  font-family: "PFDin";
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  src: url("/fonts/PFDin-subset.woff2") format("woff2");
}

startnext-header, startnext-footer {
  --font-family: "PFDin", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
```

## Browser Support

- Chrome/Edge 90+
- Firefox 88+
- Safari 14+

## Development

```bash
# Install deps (from monorepo root)
pnpm install

# Dev mode (watch)
pnpm --filter @startnext/chrome dev

# Build
pnpm --filter @startnext/chrome build

# Lint
pnpm --filter @startnext/chrome lint
```

Demo-Seite öffnen: `packages/scs-web-component/demo/index.html`

## Architecture

Jede Component ist modular in drei Dateien aufgeteilt:

```
src/
├── components/
│   ├── base/
│   │   ├── BaseComponent.ts    # Abstrakte Basis (Shadow DOM, Events, Theming)
│   │   ├── icons.ts            # SVG-Icon-Registry
│   │   └── styles.ts           # Shared Reset-CSS
│   ├── header/
│   │   ├── StartnextHeader.ts  # Logik (Scroll, Drawers, Lottie, Events)
│   │   ├── header.css.ts       # CSS als Template-Literal-Export
│   │   └── header.template.ts  # Render-Funktionen (HTML-Strings)
│   └── footer/
│       ├── StartnextFooter.ts  # Logik (Render, Events)
│       ├── footer.css.ts       # CSS als Template-Literal-Export
│       └── footer.template.ts  # Render-Funktion (HTML-String)
├── data/
│   ├── defaults.ts             # Statische Default-Daten (ohne API)
│   └── uiStrings.ts            # ARIA-Labels / UI-Strings (de/en)
├── types/
│   └── index.ts                # Alle TypeScript-Interfaces
└── index.ts                    # Barrel-Export
```

**Konventionen:**
- CSS in `*.css.ts` als exportierter Template-Literal-String (kein extra Build-Plugin nötig)
- Templates in `*.template.ts` als reine Funktionen die HTML-Strings zurückgeben
- Logik in der Hauptdatei: Event-Handling, State, Lifecycle
- BEM-Naming für CSS-Klassen (`headbar__left`, `drawer__item--highlighted`)
- Shadow DOM (open mode), kein Virtual DOM

## Monorepo Structure

```
packages/
  scs-web-component/   ← this package
  scs-api/             ← Express API service
```