npm package: @sublimee/surfaces
Description: Surface container components for Sublime
Author: Sublime Team
Latest version: 0.1.5

# @sublimee/surfaces

Surface container components for the Sublime design system.

## Installation

```bash
npm install @sublimee/surfaces
```

## Quick Start

```tsx
import { Surface } from '@sublimee/surfaces';
import '@sublimee/surfaces/surface.css';

// Basic usage
<Surface>
  Your content here
</Surface>

// With options
<Surface 
  variant="elevated"
  padding="lg"
  radius="xl"
  border
  interactive
>
  <h2>Card Title</h2>
  <p>Card content goes here</p>
</Surface>
```

## Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `variant` | `'base' \| 'elevated' \| 'higher' \| 'inset' \| 'glass'` | `'elevated'` | Visual elevation variant |
| `padding` | `'none' \| 'sm' \| 'md' \| 'lg' \| 'xl'` | `'md'` | Internal padding |
| `radius` | `'none' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'full'` | `'lg'` | Border radius |
| `border` | `boolean` | `false` | Show border |
| `interactive` | `boolean` | `true` | Enable hover shadow lift |
| `as` | `keyof JSX.IntrinsicElements` | `'div'` | HTML element to render |

## Variants

- **`base`**: No elevation, for page-level containers
- **`elevated`**: Card-level elevation (default)
- **`higher`**: Modal/dropdown elevation
- **`inset`**: Depressed surface, for input wells
- **`glass`**: Frosted glass effect with backdrop blur

### Glass Variant

The `glass` variant creates a frosted glass effect using `backdrop-filter`. It's designed to be used over colorful or photographic backgrounds.

```tsx
<Surface variant="glass" padding="lg">
  <h2>Glass Card</h2>
  <p>Content over a colorful background</p>
</Surface>
```

**Important:** The glass surface is semi-transparent and does not modify text styling. You are responsible for ensuring text readability:

- Use text shadows: `text-shadow: 0 1px 2px rgba(255, 255, 255, 0.5)`
- Choose high-contrast text colors for your background
- Add a subtle backdrop behind text content

Browser support: Glass uses `backdrop-filter` which is supported in all modern browsers. In unsupported browsers, the surface will fall back to a solid semi-transparent background.

#### Glass Dark Mode Behavior

The glass surface automatically adapts its background color based on the theme:

| Mode | Background | Use Case |
|------|------------|----------|
| **Light** | White translucent (`--sublime-color-overlay-light`) | Dark text on light backgrounds |
| **Dark** | Black translucent (`--sublime-color-overlay-dark`) | Light text on dark backgrounds |

This ensures the glass effect works correctly in both modes. In light mode, the white overlay provides a frosted look that darkens text for readability. In dark mode, the black overlay provides depth while keeping light text legible.

```tsx
// Automatic adaptation - no configuration needed
<Surface variant="glass">
  <p>This text is readable on any background</p>
</Surface>
```

The glass effect uses these semantic tokens:
- `--sublime-color-overlay-light`: `rgb(255 255 255 / 0.8)` in light mode
- `--sublime-color-overlay-dark`: `rgb(0 0 0 / 0.5)` in dark mode

### Glass Utility Class

For simple use cases, apply the glass effect directly with a CSS class:

```html
<div class="sublime-glassed">
  Instant glass effect
</div>
```

This is the same glass styling as the Surface component, but without the additional padding, radius options, or interactive states. Use it when you need:

- Quick glass effect without component overhead
- Custom padding/radius via your own styles
- Glass effect on elements that aren't "surfaces" (e.g., overlays, backdrops)

Both `sublime-glassed` and `variant="glass"` respect dark mode automatically.

#### Glass Configuration API

Customize the glass effect using CSS custom properties:

| Property | Default | Description |
|----------|---------|-------------|
| `--sublime-glass-blur` | `12px` | Blur intensity (higher = more frosted) |
| `--sublime-glass-bg` | Semantic overlay* | Background color/opacity |
| `--sublime-glass-border` | Semantic border* | Border color |
| `--sublime-glass-shadow` | Semantic shadow* | Box shadow |

\* Uses `--sublime-color-overlay-light/dark`, `--sublime-color-border-*`, and `--sublime-shadow-*` tokens based on theme.

**Adjust blur and opacity:**
```tsx
// More opaque, heavier blur for busy backgrounds
<Surface 
  variant="glass" 
  style={{ 
    '--sublime-glass-blur': '20px',
    '--sublime-glass-bg': 'rgba(255, 255, 255, 0.95)'
  }}
>
  Content
</Surface>

// Or with utility class
<div class="sublime-glassed" style="--sublime-glass-blur: 20px; --sublime-glass-bg: rgba(255,255,255,0.95)">
  Content
</div>
```

**Custom color tint:**
```tsx
// Blue-tinted glass
<Surface 
  variant="glass" 
  style={{ '--sublime-glass-bg': 'rgba(59, 130, 246, 0.3)' }}
>
  Blue glass
</Surface>
```

**Darker modifier for very dark backgrounds:**

When the default dark mode glass is too subtle on near-black backgrounds, use the `sublime-glassed--darker` modifier:

```html
<!-- Default may be invisible on black -->
<div class="sublime-glassed">Default</div>

<!-- Lighter tint for visibility -->
<div class="sublime-glassed sublime-glassed--darker">More visible</div>
```

This switches to `rgba(255, 255, 255, 0.15)` background with `rgba(255, 255, 255, 0.25)` border—subtle but visible on pure black.

**Override per-element:**
```css
.my-glass-button {
  /* Always use light glass, even in dark mode */
  --sublime-glass-bg: rgba(255, 255, 255, 0.9);
  --sublime-glass-border: rgba(255, 255, 255, 0.3);
}
```

## Theming

For full theming support including dark mode, also import the tokens:

```tsx
import '@sublimee/tokens/tokens.css';
import '@sublimee/surfaces/surface.css';
```

The surface component uses these CSS custom properties:

- `--sublime-color-surface-*` for background colors
- `--sublime-shadow-*` for elevation shadows
- `--sublime-radius-*` for border radius
- `--sublime-space-*` for padding
- `--sublime-color-border-primary` for borders

## Polymorphic Usage

Render as different HTML elements for semantic markup:

```tsx
<Surface as="article">Blog post content</Surface>
<Surface as="section">Section content</Surface>
<Surface as="aside">Sidebar content</Surface>
```