# Theming 

## Theme-first customization

Concorde components ship with **default styles** (fallback values in each component and in `<sonic-theme>`).  
You do not need to define any CSS variables to get a usable UI.

To align the kit with your brand, override **only the essential theme tokens** on `<sonic-theme>`, on `:root`, or in a project stylesheet.  
Concorde derives radius steps, button/input rounding, shadows, and most per-component layout from these primitives—**do not copy long lists of derived variables** unless you have a specific need.

<sonic-code language="html">
  <template>
<sonic-theme color font >
  <!-- your app -->
</sonic-theme>
  </template>
</sonic-code>

<sonic-code language="javascript">
  <template>
import "@supersoniks/concorde/theme";
  </template>
</sonic-code>

| Attribute | Effect |
|-----------|--------|
| *(omit)* \| `theme="custom"` | Default: core tokens + your `--sc-*`; no built-in light/dark palette |
| `theme="light"` \| `"dark"` \| `"auto"` | Opt-in presets; `auto` follows `prefers-color-scheme` |
| `class="bg-base block"` (Tailwind) | Page/surface background (`--sc-base`) |
| `color` | Text color (`--sc-base-content`) |
| `font` | Base font family/weight (`--sc-font-family-base`, etc.) |

Popovers, modals, and toasts mount under the nearest `<sonic-theme>`.

## Customization example

Example (full brand override on `<sonic-theme>` or `:root`). Set every essential token below; derived radii and shadows still come from the theme engine—only `--sc-rounded` is listed here.

<sonic-code language="css">
  <template>
sonic-theme {
  /* Semantic fills */
  --sc-primary: #353429;
  --sc-secondary: #f43f5e;
  --sc-info: #7c3aed;
  --sc-danger: #d71839;
  --sc-warning: #f97316;
  --sc-success: #10b981;
  --sc-contrast: #111;

  /* Text/icons on semantic fills */
  --sc-primary-content: #fff;
  --sc-secondary-content: #fff;
  --sc-info-content: #fff;
  --sc-danger-content: #fff;
  --sc-warning-content: #fff;
  --sc-success-content: #fff;
  --sc-contrast-content: #fff;

  /* Neutral fills */
  --sc-base: #fff;
  --sc-base-50: #f6f6f5;
  --sc-base-100: #ededec;
  --sc-base-200: #d7d7d4;
  --sc-base-300: #c8c7c4;
  --sc-base-400: #a8a7a2;
  --sc-base-500: #94938c;
  --sc-base-600: #76756c;
  --sc-base-700: #59584e;
  --sc-base-800: #47463b;
  --sc-base-900: #353429;

  /* Text/icons on neutral surfaces */
  --sc-base-content: var(--sc-base-900);

  /* Typography */
  --sc-font-family-base: "Oswald", system-ui, -apple-system, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, sans-serif;
  --sc-headings-font-family: "alternate-gothic-compressed", system-ui, sans-serif;
  --sc-headings-line-height: 1.1;
  --sc-headings-font-weight: bold;
  --sc-headings-text-transform: none;

  /* Shape (primitive only) */
  --sc-rounded: 0;

  /* Forms */
  --sc-border-width: 0.2rem;
  --sc-form-height: 2em;
  --sc-input-bg: var(--sc-base);
  --sc-input-color: var(--sc-base-content);
  --sc-input-border-color: var(--sc-input-color);
  --sc-input-active-bg: var(--sc-primary);
  --sc-input-active-color: var(--sc-primary-content);
  --sc-input-active-border-color: var(--sc-primary);
}
  </template>
</sonic-code>

<sonic-button href="https://delanfranchi.github.io/concordecolors/"> Palette generator: concordecolors</sonic-button>


**Without these overrides**, components keep Concorde’s per-component fallbacks. Built-in light/dark palettes apply only when you set `theme="light"`, `theme="dark"`, or `theme="auto"`.

**What we intentionally avoid:** large public `--sc-alert-*` / `--sc-badge-*` APIs or `::part()` styling hooks on most components. Prefer attributes (`type`, `status`, `size`, …) and the theme tokens above.


## Only essential CSS variables (public theme API)

These are the **smallest set** we recommend customizing. Everything else should stay internal to the theme or to components (`--sc_*` private variables, attributes like `type`, `size`, `variant`).

### Surfaces and foreground

Tokens **without** a `-content` suffix are **fill / background** colors.  
Tokens **with** `-content` are **text and icons** on top of the matching fill (solid buttons, badges, alerts, etc.).

#### Neutral fills

| Variable | Role |
|----------|------|
| `--sc-base` | Main surface / page background |
| `--sc-base-50` … `--sc-base-900` | Neutral scale (borders, subtle backgrounds, muted UI) |

#### Neutral foreground

| Variable | Role |
|----------|------|
| `--sc-base-content` | Default body text and icons on neutral surfaces |

#### Semantic fills

| Variable | Role |
|----------|------|
| `--sc-primary` | Primary actions, links, emphasis |
| `--sc-secondary` | Secondary brand accent (when used) |
| `--sc-info`, `--sc-success`, `--sc-warning`, `--sc-danger` | Status and feedback |
| `--sc-contrast` | High-contrast fills (e.g. on media) |

#### Semantic foreground

| Variable | Role |
|----------|------|
| `--sc-primary-content`, `--sc-secondary-content`, … | Text/icons on the matching semantic **fill** (`--sc-primary`, etc.) |

### Shape

| Variable | Role |
|----------|------|
| `--sc-rounded` | **Single primitive** corner radius; the theme computes `--sc-rounded-sm`, `--sc-btn-rounded`, `--sc-input-rounded`, etc. |

### Typography

| Variable | Role |
|----------|------|
| `--sc-font-family-base` | Body UI text |
| `--sc-font-weight-base`, `--sc-font-style-base` | Optional |
| `--sc-headings-font-family`, `--sc-headings-line-height`, `--sc-headings-font-weight`, `--sc-headings-text-transform` | Headings (modal titles, etc.) |

### Forms (only if you customize inputs globally)

Interactive controls expose a few extra **theme-level** tokens; prefer these over styling individual inputs from outside.

| Variable | Role |
|----------|------|
| `--sc-border-width` | Default border thickness |
| `--sc-form-height` | Control height |
| `--sc-input-bg`, `--sc-input-color`, `--sc-input-border-color` | Default field chrome |
| `--sc-input-active-bg`, `--sc-input-active-color`, `--sc-input-active-border-color` | Focus/active state |

---

## Tailwind in new components ?

Set <code>tailwind.config.js</code> to match concorde style token in your custom component.

<sonic-code language="js">
  <template>
...
theme: {
  borderRadius: {
    DEFAULT: "var(--sc-rounded)",
    none: "0",
    sm: "var(--sc-rounded-sm)",
    md: "var(--sc-rounded-md)",
    lg: "var(--sc-rounded-lg)",
    xl: "var(--sc-rounded-xl)",
    full: "9999px",
  },
  boxShadow: {
    DEFAULT: "var(--sc-shadow)",
    none: "none",
    sm: "var(--sc-shadow-sm)",
    md: "var(--sc-shadow-md)",
    lg: "var(--sc-shadow-lg)",
    xl: "var(--sc-shadow-xl)",
  },
  colors: {
    transparent: "transparent",
    current: "currentColor",
    content: "var(--sc-base-content)",
    base: "var(--sc-base)",
    neutral: {
      0: "var(--sc-base)",
      50: "var(--sc-base-50)",
      100: "var(--sc-base-100)",
      200: "var(--sc-base-200)",
      300: "var(--sc-base-300)",
      400: "var(--sc-base-400)",
      500: "var(--sc-base-500)",
      600: "var(--sc-base-600)",
      700: "var(--sc-base-700)",
      800: "var(--sc-base-800)",
      900: "var(--sc-base-900)",
      content: "var(--sc-base)",
    },
    primary: {
      DEFAULT: "var(--sc-primary)",
      content: "var(--sc-primary-content)",
    },
    success: {
      DEFAULT: "var(--sc-success)",
      content: "var(--sc-success-content)",
    },
    danger: {
      DEFAULT: "var(--sc-danger)",
      content: "var(--sc-danger-content)",
    },
    warning: {
      DEFAULT: "var(--sc-warning)",
      content: "var(--sc-warning-content)",
    },
    info: {
      DEFAULT: "var(--sc-info)",
      content: "var(--sc-info-content)",
    },
    contrast: {
      DEFAULT: "var(--sc-contrast)",
      content: "var(--sc-contrast-content)",
    },
  },
  extend: {
    borderWidth: {
      DEFAULT: "var(--sc-border-width)",
    },
    fontFamily: {
      headings: ["var(--sc-headings-font-family, var(--sc-font-family-base, sans-serif))"],
      body: ["var(--sc-font-family-base)"],
      monospace: ["var(--sc-font-family-monospace, monospace)"],
    }
  }
  </template>
</sonic-code>

