/* ─── Design tokens ─────────────────────────────────────────────────────── */ :root { color-scheme: light dark; --radius: 8px; --radius-sm: 4px; --font-sans: system-ui, -apple-system, sans-serif; --font-mono: ui-monospace, "Cascadia Code", "Fira Code", monospace; --shadow: 0 0 3px color-mix(in srgb, CanvasText 10%, Canvas 90%); --border-color: color-mix(in srgb, CanvasText 10%, Canvas 90%); /* Foreground color rendered over token highlight backgrounds */ --tok-text: CanvasText; /* Hover outline color for highlighted token ranges */ --tok-hover: AccentColor; /* Token color palette — 12 distinct hues in oklch, light-mode values. Dark-mode overrides follow in the @media block below. */ --tok-0: oklch(80% 0.13 30); --tok-1: oklch(82% 0.13 80); --tok-2: oklch(80% 0.13 140); --tok-3: oklch(80% 0.13 195); --tok-4: oklch(80% 0.13 250); --tok-5: oklch(80% 0.13 300); --tok-6: oklch(80% 0.13 340); --tok-7: oklch(82% 0.13 55); --tok-8: oklch(80% 0.13 165); --tok-9: oklch(80% 0.13 220); --tok-10: oklch(80% 0.13 270); --tok-11: oklch(80% 0.13 320); } @media (prefers-color-scheme: dark) { :root { /* Slightly higher lightness so highlights read on dark Canvas */ --tok-0: oklch(68% 0.16 30); --tok-1: oklch(70% 0.16 80); --tok-2: oklch(68% 0.16 140); --tok-3: oklch(68% 0.16 195); --tok-4: oklch(68% 0.16 250); --tok-5: oklch(68% 0.16 300); --tok-6: oklch(68% 0.16 340); --tok-7: oklch(70% 0.16 55); --tok-8: oklch(68% 0.16 165); --tok-9: oklch(68% 0.16 220); --tok-10: oklch(68% 0.16 270); --tok-11: oklch(68% 0.16 320); } } /* ─── Reset ─────────────────────────────────────────────────────────────── */ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } /* ─── Base ──────────────────────────────────────────────────────────────── */ body { font-family: var(--font-sans); background: Canvas; color: CanvasText; line-height: 1.6; min-height: 100dvh; padding-block-end: 4rem; } /* ─── Header ────────────────────────────────────────────────────────────── */ header { background: Canvas; padding: 1.25rem 2rem; max-width: 1400px; margin-inline: auto; h1 { font-size: 1.35rem; font-weight: 700; letter-spacing: -0.01em; } p { font-size: 0.875rem; opacity: 0.7; margin-block-start: 0.2rem; } } /* ─── Main layout ───────────────────────────────────────────────────────── */ main { max-width: 1400px; margin-inline: auto; padding: 1.5rem 2rem; display: grid; gap: 1.25rem; } /* ─── Input section ─────────────────────────────────────────────────────── */ .input-section { display: grid; gap: 0.5rem; label { font-size: 0.8rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: GrayText; } textarea { font-family: var(--font-mono); font-size: 1.1rem; line-height: 1.7; background: Field; color: FieldText; border: 1px solid var(--border-color); border-radius: var(--radius); padding: 0.75rem 1rem; resize: vertical; width: 100%; transition: border-color 0.15s; &:focus { outline: none; border-color: AccentColor; box-shadow: 0 0 0 3px color-mix(in srgb, AccentColor 20%, transparent); } } } /* ─── Add tokenizer row ─────────────────────────────────────────────────── */ .add-tokenizer-section { display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; select { font-family: var(--font-sans); font-size: 0.9rem; background: Field; color: FieldText; border: 1px solid var(--border-color); border-radius: var(--radius-sm); padding: 0.45rem 0.75rem; flex: 1 1 280px; max-width: 480px; cursor: pointer; transition: border-color 0.15s; &:focus { outline: none; border-color: AccentColor; } } button { font-family: var(--font-sans); font-size: 0.9rem; font-weight: 600; background: AccentColor; color: AccentColorText; border: none; border-radius: var(--radius-sm); padding: 0.45rem 1.1rem; cursor: pointer; transition: opacity 0.15s; white-space: nowrap; &:hover:not(:disabled) { opacity: 0.85; } &:disabled { opacity: 0.4; cursor: not-allowed; } } } /* ─── Empty state ───────────────────────────────────────────────────────── */ .empty-state { text-align: center; color: GrayText; font-size: 0.9rem; padding: 2.5rem 1rem; border: 1.5px dashed var(--border-color); border-radius: var(--radius); background: Canvas; &.hidden { display: none; } } /* ─── Panels grid ───────────────────────────────────────────────────────── */ #panels { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: 1rem; align-items: start; } /* ─── Individual tokenizer panel ────────────────────────────────────────── */ .panel { background: Canvas; border: 1px solid var(--border-color); border-radius: var(--radius); box-shadow: var(--shadow); display: grid; grid-template-rows: auto auto auto 1fr; overflow: hidden; /* Panel header bar */ .panel-header { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; padding: 0.65rem 1rem; background: ButtonFace; border-block-end: 1px solid var(--border-color); .panel-title { font-size: 0.85rem; font-weight: 600; color: ButtonText; text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .remove-btn { font-size: 0.75rem; font-weight: 600; color: GrayText; background: none; border: 1px solid var(--border-color); border-radius: var(--radius-sm); padding: 0.2rem 0.5rem; cursor: pointer; flex-shrink: 0; transition: color 0.12s, border-color 0.12s; &:hover { color: LinkText; border-color: LinkText; } } } /* Text mirror with highlights */ .panel-text { font-family: var(--font-mono); font-size: 1.05rem; line-height: 1.8; padding: 0.85rem 1rem; border-block-end: 1px solid var(--border-color); white-space: pre-wrap; word-break: break-all; min-height: 3.5rem; } /* Stats bar */ .panel-stats { display: flex; gap: 1.5rem; padding: 0.45rem 1rem; background: ButtonFace; border-block-end: 1px solid var(--border-color); font-size: 0.78rem; color: GrayText; flex-wrap: wrap; strong { color: CanvasText; font-weight: 600; } } /* Token table */ .panel-table-wrap { overflow-y: auto; max-height: 360px; } table { width: 100%; border-collapse: collapse; font-size: 0.82rem; thead { position: sticky; top: 0; background: ButtonFace; z-index: 1; th { text-align: left; padding: 0.4rem 0.75rem; font-weight: 600; font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.05em; color: GrayText; border-block-end: 1px solid var(--border-color); } } tbody tr { cursor: default; transition: background 0.08s; &:hover { background: color-mix(in srgb, ButtonFace 60%, Canvas); } &.active { background: color-mix( in srgb, var(--row-color, AccentColor) 18%, Canvas ); } td { padding: 0.3rem 0.75rem; border-block-end: 1px solid color-mix(in srgb, ButtonBorder 60%, transparent); vertical-align: middle; &.tok-cell { font-family: var(--font-mono); font-size: 0.88rem; } &.id-cell { font-family: var(--font-mono); color: GrayText; font-size: 0.8rem; text-align: right; } &.color-swatch { width: 18px; padding-inline: 0.5rem; span { display: block; width: 10px; height: 10px; border-radius: 50%; background: var(--row-color, var(--border-color)); } } } } } /* Loading state */ &.loading { .panel-text, .panel-stats, .panel-table-wrap { opacity: 0.4; pointer-events: none; } } .panel-loading { display: none; align-items: center; gap: 0.5rem; padding: 0.6rem 1rem; font-size: 0.8rem; color: GrayText; .spinner { width: 14px; height: 14px; border: 2px solid var(--border-color); border-top-color: AccentColor; border-radius: 50%; animation: spin 0.7s linear infinite; flex-shrink: 0; } } &.loading .panel-loading { display: flex; } } @keyframes spin { to { transform: rotate(360deg); } }