@scania/tegel-lite 0.0.3-rules-beta.9 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +0 -29
  2. package/dist/assets/icons/scania/microphone.svg +4 -0
  3. package/dist/assets/icons/scania/microphone_inactive.svg +7 -0
  4. package/dist/assets/icons/scania/notification_snooze.svg +6 -0
  5. package/dist/assets/icons/scania/paperclip.svg +3 -0
  6. package/dist/components.css +2036 -1807
  7. package/dist/global.css +3 -2
  8. package/dist/scania-variables.css +8 -0
  9. package/dist/tl-button.css +19 -0
  10. package/dist/tl-dropdown.css +36 -1
  11. package/dist/tl-folder-tabs.css +64 -0
  12. package/dist/tl-header.css +207 -51
  13. package/dist/tl-icon.css +16 -0
  14. package/dist/tl-inline-tabs.css +81 -0
  15. package/dist/tl-navigation-tabs.css +81 -0
  16. package/dist/tl-slider.css +1024 -1485
  17. package/dist/tl-text-field.css +32 -13
  18. package/package.json +3 -14
  19. package/.ai/rules/01-design-tokens.mdc +0 -318
  20. package/.ai/rules/02-components-forms.mdc +0 -396
  21. package/.ai/rules/03-components-display.mdc +0 -474
  22. package/.ai/rules/04-components-navigation.mdc +0 -358
  23. package/.ai/rules/05-guidelines.mdc +0 -144
  24. package/.ai/rules/06-patterns.mdc +0 -352
  25. package/.cursor/rules/tegel-lite/01-design-tokens.mdc +0 -317
  26. package/.cursor/rules/tegel-lite/02-components-forms.mdc +0 -395
  27. package/.cursor/rules/tegel-lite/03-components-display.mdc +0 -473
  28. package/.cursor/rules/tegel-lite/04-components-navigation.mdc +0 -357
  29. package/.cursor/rules/tegel-lite/05-guidelines.mdc +0 -143
  30. package/.cursor/rules/tegel-lite/06-patterns.mdc +0 -351
  31. package/.github/copilot-instructions.md +0 -2045
  32. package/AGENTS.md +0 -2045
  33. package/CLAUDE.md +0 -2045
  34. package/bin/setup-ai-rules.js +0 -368
  35. package/dist/tl-folder-tab.css +0 -87
  36. package/dist/tl-inline-tab.css +0 -80
  37. package/dist/tl-navigation-tab.css +0 -114
  38. package/dist/tl-textarea-mixins.css +0 -0
@@ -1,368 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * setup-ai-rules.js
5
- *
6
- * Interactive CLI to copy @scania/tegel-lite AI coding rules into a user's project.
7
- *
8
- * Usage:
9
- * npx tegel-lite-setup-rules # Interactive mode
10
- * npx tegel-lite-setup-rules --all # Copy all rule formats (skip prompts)
11
- *
12
- * Plain Node.js — no external dependencies. Uses built-in readline.
13
- */
14
-
15
- import fs from 'fs';
16
- import path from 'path';
17
- import readline from 'readline';
18
- import { fileURLToPath } from 'url';
19
-
20
- const __filename = fileURLToPath(import.meta.url);
21
- const __dirname = path.dirname(__filename);
22
- const packageRoot = path.resolve(__dirname, '..');
23
-
24
- // Where files will be copied to
25
- const projectRoot = process.cwd();
26
-
27
- // Markers for idempotent updates in aggregated files
28
- const MARKER_START = '<!-- START @scania/tegel-lite rules -->';
29
- const MARKER_END = '<!-- END @scania/tegel-lite rules -->';
30
-
31
- // ── Tool definitions ──────────────────────────────────────────────────────────
32
-
33
- const TOOLS = [
34
- {
35
- id: 'cursor',
36
- label: 'Cursor',
37
- description: '.cursor/rules/tegel-lite/*.mdc',
38
- sourceDir: path.join(packageRoot, '.cursor', 'rules', 'tegel-lite'),
39
- targetDir: path.join(projectRoot, '.cursor', 'rules', 'tegel-lite'),
40
- mode: 'directory',
41
- },
42
- {
43
- id: 'vscode',
44
- label: 'VS Code (GitHub Copilot)',
45
- description: '.github/copilot-instructions.md',
46
- sourceFile: path.join(packageRoot, '.github', 'copilot-instructions.md'),
47
- targetFile: path.join(projectRoot, '.github', 'copilot-instructions.md'),
48
- mode: 'aggregated',
49
- },
50
- {
51
- id: 'claude',
52
- label: 'Claude',
53
- description: 'CLAUDE.md',
54
- sourceFile: path.join(packageRoot, 'CLAUDE.md'),
55
- targetFile: path.join(projectRoot, 'CLAUDE.md'),
56
- mode: 'aggregated',
57
- },
58
- ];
59
-
60
- // ── Helpers ───────────────────────────────────────────────────────────────────
61
-
62
- /**
63
- * Wrap content in section markers for idempotent updates.
64
- */
65
- function wrapWithMarkers(content) {
66
- return `${MARKER_START}\n${content.trim()}\n${MARKER_END}`;
67
- }
68
-
69
- /**
70
- * Replace the marked section in existing file content, or append if not found.
71
- */
72
- function upsertMarkedSection(existingContent, newSection) {
73
- const pattern = `${escapeRegex(MARKER_START)}[\\s\\S]*?${escapeRegex(MARKER_END)}`;
74
- const markerRegex = new RegExp(pattern);
75
-
76
- if (markerRegex.test(existingContent)) {
77
- // Replace existing section
78
- return existingContent.replace(new RegExp(pattern), newSection);
79
- }
80
-
81
- // Append with spacing
82
- const separator = existingContent.trim().length > 0 ? '\n\n' : '';
83
- return existingContent.trimEnd() + separator + newSection + '\n';
84
- }
85
-
86
- function escapeRegex(str) {
87
- return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
88
- }
89
-
90
- /**
91
- * Ask a yes/no question via readline.
92
- */
93
- function askYesNo(rl, question) {
94
- return new Promise((resolve) => {
95
- rl.question(`${question} (y/N): `, (answer) => {
96
- resolve(answer.trim().toLowerCase() === 'y');
97
- });
98
- });
99
- }
100
-
101
- // ── Checkbox UI ───────────────────────────────────────────────────────────────
102
-
103
- /**
104
- * Display an interactive checkbox list in the terminal.
105
- * Arrow keys navigate, space toggles, enter confirms.
106
- *
107
- * Uses readline.emitKeypressEvents to correctly parse multi-byte
108
- * escape sequences (arrow keys) across all platforms.
109
- */
110
- function showCheckboxList(items) {
111
- return new Promise((resolve) => {
112
- const selected = items.map(() => false); // Nothing selected by default
113
- let cursor = 0;
114
-
115
- const { stdin, stdout } = process;
116
-
117
- // Non-interactive fallback (e.g. CI, piped input)
118
- if (!stdin.isTTY) {
119
- console.log('Non-interactive terminal detected. Selecting all tools.');
120
- resolve(items.map((_, i) => i));
121
- return;
122
- }
123
-
124
- // ── Rendering ───────────────────────────────────────────────
125
-
126
- let rendered = false;
127
-
128
- function render() {
129
- const lines = items.map((item, i) => {
130
- const checkbox = selected[i] ? '\x1B[32m◉\x1B[0m' : '○';
131
- const pointer = i === cursor ? '\x1B[36m❯\x1B[0m ' : ' ';
132
- const desc = `\x1B[2m${item.description}\x1B[0m`;
133
- return `${pointer}${checkbox} ${item.label} ${desc}`;
134
- });
135
-
136
- lines.push('');
137
- lines.push('\x1B[2m↑↓ navigate · space toggle · enter confirm\x1B[0m');
138
-
139
- return lines.join('\n');
140
- }
141
-
142
- function rerender() {
143
- if (rendered) {
144
- // Move up to overwrite previous output
145
- // render() produces items.length (items) + 1 (empty line) + 1 (help text) = items.length + 2 lines
146
- const lineCount = items.length + 2;
147
- // Use ANSI escape codes in single write for atomic update
148
- stdout.write(`\x1B[${lineCount}A\x1B[J${render()}\n`);
149
- } else {
150
- stdout.write(render());
151
- stdout.write('\n');
152
- }
153
- rendered = true;
154
- }
155
-
156
- // ── Cleanup ─────────────────────────────────────────────────
157
-
158
- function cleanup() {
159
- stdin.setRawMode(false);
160
- stdin.removeAllListeners('keypress');
161
- stdin.pause();
162
- stdout.write('\x1B[?25h'); // Show cursor
163
- }
164
-
165
- // ── Keypress handler ────────────────────────────────────────
166
-
167
- function onKeypress(_, key) {
168
- if (!key) return;
169
-
170
- // Ctrl+C → exit
171
- if (key.ctrl && key.name === 'c') {
172
- cleanup();
173
- stdout.write('\n');
174
- process.exit(0);
175
- }
176
-
177
- // Enter → confirm selection
178
- if (key.name === 'return') {
179
- cleanup();
180
- stdout.write('\n');
181
- resolve(selected.reduce((acc, sel, i) => (sel ? [...acc, i] : acc), []));
182
- return;
183
- }
184
-
185
- // Space → toggle current item (check both key.name and key.sequence for compatibility)
186
- if (key.name === 'space' || key.sequence === ' ') {
187
- selected[cursor] = !selected[cursor];
188
- }
189
-
190
- // Up arrow or k → move cursor up
191
- if (key.name === 'up' || key.name === 'k') {
192
- cursor = (cursor - 1 + items.length) % items.length;
193
- }
194
-
195
- // Down arrow or j → move cursor down
196
- if (key.name === 'down' || key.name === 'j') {
197
- cursor = (cursor + 1) % items.length;
198
- }
199
-
200
- rerender();
201
- }
202
-
203
- // ── Start listening ─────────────────────────────────────────
204
-
205
- readline.emitKeypressEvents(stdin);
206
-
207
- stdin.setRawMode(true);
208
- stdin.resume();
209
-
210
- stdin.on('keypress', onKeypress);
211
-
212
- // Initial render
213
- stdout.write('\x1B[?25l'); // Hide cursor
214
- rerender();
215
- });
216
- }
217
-
218
- // ── Copy logic ────────────────────────────────────────────────────────────────
219
-
220
- /**
221
- * Copy a directory of files (e.g. .cursor/rules/tegel-lite/*.mdc).
222
- */
223
- function copyDirectoryTool(tool, rl, skipPrompt) {
224
- return copyDirectoryToolAsync(tool, rl, skipPrompt);
225
- }
226
-
227
- async function copyDirectoryToolAsync(tool, rl, skipPrompt) {
228
- if (!fs.existsSync(tool.sourceDir)) {
229
- console.log(` ⚠ Source not found: ${path.relative(packageRoot, tool.sourceDir)}`);
230
- console.log(' Run "npm run generate:ai-rules" in the package first.');
231
- return;
232
- }
233
-
234
- const files = fs.readdirSync(tool.sourceDir).filter((f) => f.endsWith('.mdc'));
235
-
236
- if (files.length === 0) {
237
- console.log(' ⚠ No .mdc files found in source directory.');
238
- return;
239
- }
240
-
241
- // Check if target directory already exists
242
- if (fs.existsSync(tool.targetDir) && !skipPrompt) {
243
- const overwrite = await askYesNo(
244
- rl,
245
- ` Target exists: ${path.relative(projectRoot, tool.targetDir)}. Overwrite?`,
246
- );
247
- if (!overwrite) {
248
- console.log(' Skipped.');
249
- return;
250
- }
251
- }
252
-
253
- fs.mkdirSync(tool.targetDir, { recursive: true });
254
-
255
- for (const file of files) {
256
- const src = path.join(tool.sourceDir, file);
257
- const dest = path.join(tool.targetDir, file);
258
- fs.copyFileSync(src, dest);
259
- console.log(` Copied: ${path.relative(projectRoot, dest)}`);
260
- }
261
- }
262
-
263
- /**
264
- * Copy an aggregated file (CLAUDE.md, AGENTS.md, copilot-instructions.md).
265
- * Uses markers for idempotent upsert.
266
- */
267
- async function copyAggregatedTool(tool, rl, skipPrompt) {
268
- if (!fs.existsSync(tool.sourceFile)) {
269
- console.log(` ⚠ Source not found: ${path.relative(packageRoot, tool.sourceFile)}`);
270
- console.log(' Run "npm run generate:ai-rules" in the package first.');
271
- return;
272
- }
273
-
274
- const sourceContent = fs.readFileSync(tool.sourceFile, 'utf-8');
275
- const wrappedContent = wrapWithMarkers(sourceContent);
276
- const targetRelative = path.relative(projectRoot, tool.targetFile);
277
-
278
- if (fs.existsSync(tool.targetFile)) {
279
- const existingContent = fs.readFileSync(tool.targetFile, 'utf-8');
280
-
281
- // Check if markers already exist
282
- if (existingContent.includes(MARKER_START)) {
283
- // Update in place
284
- const updatedContent = upsertMarkedSection(existingContent, wrappedContent);
285
- fs.writeFileSync(tool.targetFile, updatedContent, 'utf-8');
286
- console.log(` Updated: ${targetRelative} (replaced existing tegel-lite section)`);
287
- return;
288
- }
289
-
290
- // File exists but no markers — ask to append
291
- if (!skipPrompt) {
292
- const append = await askYesNo(
293
- rl,
294
- ` File exists: ${targetRelative}. Append tegel-lite rules?`,
295
- );
296
- if (!append) {
297
- console.log(' Skipped.');
298
- return;
299
- }
300
- }
301
-
302
- const updatedContent = upsertMarkedSection(existingContent, wrappedContent);
303
- fs.writeFileSync(tool.targetFile, updatedContent, 'utf-8');
304
- console.log(` Updated: ${targetRelative} (appended tegel-lite section)`);
305
- } else {
306
- // Create new file
307
- const dir = path.dirname(tool.targetFile);
308
- fs.mkdirSync(dir, { recursive: true });
309
- fs.writeFileSync(tool.targetFile, wrappedContent + '\n', 'utf-8');
310
- console.log(` Created: ${targetRelative}`);
311
- }
312
- }
313
-
314
- // ── Main ──────────────────────────────────────────────────────────────────────
315
-
316
- async function main() {
317
- const args = process.argv.slice(2);
318
- const skipPrompt = args.includes('--all');
319
-
320
- console.log('');
321
- console.log('\x1B[1m@scania/tegel-lite — AI Coding Rules Setup\x1B[0m');
322
- console.log('');
323
-
324
- let selectedIndices;
325
-
326
- if (skipPrompt) {
327
- console.log('Installing all rule formats (--all flag).\n');
328
- selectedIndices = TOOLS.map((_, i) => i);
329
- } else {
330
- console.log('Select which AI tools to configure:\n');
331
- selectedIndices = await showCheckboxList(TOOLS);
332
- }
333
-
334
- if (selectedIndices.length === 0) {
335
- console.log('No tools selected. Exiting.');
336
- process.exit(0);
337
- }
338
-
339
- const selectedTools = selectedIndices.map((i) => TOOLS[i]);
340
-
341
- console.log(`\nInstalling rules for: ${selectedTools.map((t) => t.label).join(', ')}\n`);
342
-
343
- // Create a readline interface for yes/no prompts
344
- const rl = readline.createInterface({
345
- input: process.stdin,
346
- output: process.stdout,
347
- });
348
-
349
- for (const tool of selectedTools) {
350
- console.log(`\n${tool.label}:`);
351
-
352
- if (tool.mode === 'directory') {
353
- await copyDirectoryTool(tool, rl, skipPrompt);
354
- } else {
355
- await copyAggregatedTool(tool, rl, skipPrompt);
356
- }
357
- }
358
-
359
- rl.close();
360
-
361
- console.log('\n\x1B[32m✓ Done!\x1B[0m AI coding rules installed successfully.');
362
- console.log('\nRe-run this command anytime to update rules to the latest version.\n');
363
- }
364
-
365
- main().catch((err) => {
366
- console.error('Error:', err.message);
367
- process.exit(1);
368
- });
@@ -1,87 +0,0 @@
1
- .tl-folder-tabs {
2
- --folder-tabs-scroll-button-surface: var(--color-background-surface-200);
3
- --folder-tabs-scroll-button-surface-hover: var(--color-background-surface-300);
4
- --folder-tabs-scroll-button-surface-active: var(--color-background-surface-400);
5
- --folder-tabs-scroll-button-text: var(--color-foreground-text-soft);
6
- }
7
-
8
- .tl-folder-tabs__tab {
9
- --folder-tab-surface: var(--color-background-surface-200);
10
- --folder-tab-surface-selected: var(--color-background-layer-01);
11
- --folder-tab-surface-hover: var(--color-background-surface-300);
12
- --folder-tab-border-selected: var(--color-foreground-border-accent-focus);
13
- --folder-tab-divider: var(--color-foreground-icon-discrete);
14
- --folder-tab-text: var(--color-foreground-text-soft);
15
- --folder-tab-text-disabled: var(--color-foreground-text-disabled);
16
- }
17
-
18
- .tl-folder-tabs--primary .tl-folder-tabs__tab {
19
- --folder-tab-surface-selected: var(--color-background-layer-01);
20
- }
21
-
22
- .tl-folder-tabs--secondary .tl-folder-tabs__tab {
23
- --folder-tab-surface-selected: var(--color-background-layer-02);
24
- }
25
-
26
- /* Typography Usage mixins */
27
- .tl-folder-tabs__tab {
28
- all: unset;
29
- font-family: var(--headline-07-font-family);
30
- font-size: var(--headline-07-font-size);
31
- line-height: var(--headline-07-line-height);
32
- font-weight: var(--headline-07-font-weight);
33
- letter-spacing: var(--headline-07-letter-spacing);
34
- text-transform: var(--headline-07-text-transform);
35
- box-sizing: border-box;
36
- position: relative;
37
- display: inline-flex;
38
- align-items: center;
39
- min-inline-size: 142px;
40
- inline-size: auto;
41
- flex: 0 0 auto;
42
- white-space: nowrap;
43
- padding: 16px;
44
- text-align: left;
45
- cursor: pointer;
46
- border-left: 1px solid transparent;
47
- border-top: 2px solid var(--folder-tab-surface);
48
- background-color: var(--folder-tab-surface);
49
- color: var(--folder-tab-text);
50
- }
51
- .tl-folder-tabs__tab + .tl-folder-tabs__tab {
52
- border-left-color: var(--folder-tab-divider);
53
- }
54
- .tl-folder-tabs__tab:focus-visible {
55
- outline: 2px solid currentcolor;
56
- outline-offset: -4px;
57
- box-shadow: none;
58
- }
59
- .tl-folder-tabs__tab:hover:not(.tl-folder-tabs__tab--disabled):not(.tl-folder-tabs__tab--selected) {
60
- background-color: var(--folder-tab-surface-hover);
61
- border-top-color: var(--folder-tab-surface-hover);
62
- color: var(--folder-tab-text);
63
- }
64
- .tl-folder-tabs__tab--selected {
65
- background-color: var(--folder-tab-surface-selected);
66
- border-top-color: var(--folder-tab-border-selected);
67
- color: var(--folder-tab-text);
68
- }
69
- .tl-folder-tabs__tab--selected::after {
70
- content: "";
71
- position: absolute;
72
- top: 0;
73
- right: -1px;
74
- bottom: 0;
75
- width: 1px;
76
- background-color: var(--folder-tab-surface-selected);
77
- z-index: 1;
78
- }
79
- .tl-folder-tabs__tab--disabled {
80
- color: var(--folder-tab-text-disabled);
81
- cursor: not-allowed;
82
- user-select: none;
83
- }
84
- .tl-folder-tabs__tab--disabled:focus-visible {
85
- outline: none;
86
- box-shadow: none;
87
- }
@@ -1,80 +0,0 @@
1
- /* Typography Usage mixins */
2
- .tl-inline-tabs__tab {
3
- all: unset;
4
- margin-right: 32px;
5
- box-sizing: border-box;
6
- }
7
- .tl-inline-tabs__tab * {
8
- box-sizing: border-box;
9
- }
10
- .tl-inline-tabs__tab {
11
- font-family: var(--headline-07-font-family);
12
- font-size: var(--headline-07-font-size);
13
- line-height: var(--headline-07-line-height);
14
- font-weight: var(--headline-07-font-weight);
15
- letter-spacing: var(--headline-07-letter-spacing);
16
- text-transform: var(--headline-07-text-transform);
17
- color: var(--inline-tabs-tab);
18
- text-decoration: none;
19
- display: block;
20
- position: relative;
21
- transition: color 0.15s ease-in-out 0s;
22
- white-space: nowrap;
23
- background-color: transparent;
24
- border: 0;
25
- padding: 20px 4px;
26
- }
27
- .tl-inline-tabs__tab:focus-visible {
28
- outline: none;
29
- }
30
- .tl-inline-tabs__tab:focus-visible::before {
31
- content: "";
32
- position: absolute;
33
- inset: 18px 0;
34
- border-radius: 2px;
35
- box-shadow: 0 0 0 2px var(--inline-tabs-tab-focus) inset;
36
- z-index: 2;
37
- pointer-events: none;
38
- }
39
- .tl-inline-tabs__tab::after {
40
- background-color: var(--inline-tabs-tab-indicator-hover);
41
- content: " ";
42
- position: absolute;
43
- bottom: 0;
44
- right: 0;
45
- left: 0;
46
- margin-left: auto;
47
- width: 0%;
48
- margin-right: auto;
49
- height: 2px;
50
- z-index: 1;
51
- transition: width 0.15s ease-in-out 0s;
52
- }
53
- .tl-inline-tabs__tab:not(.tl-inline-tabs__tab--selected)::after {
54
- width: 0%;
55
- }
56
- .tl-inline-tabs__tab:hover {
57
- cursor: pointer;
58
- color: var(--inline-tabs-tab-hover);
59
- }
60
- .tl-inline-tabs__tab:hover::after {
61
- width: 100%;
62
- }
63
- .tl-inline-tabs__tab--selected {
64
- color: var(--inline-tabs-tab-selected);
65
- }
66
- .tl-inline-tabs__tab--selected::after {
67
- background-color: var(--inline-tabs-tab-indicator-active);
68
- width: 100%;
69
- }
70
- .tl-inline-tabs__tab--disabled {
71
- color: var(--inline-tabs-tab-disabled);
72
- pointer-events: none;
73
- cursor: not-allowed;
74
- }
75
- .tl-inline-tabs__tab--disabled::after {
76
- content: none;
77
- }
78
- .tl-inline-tabs__tab--disabled:focus-visible::before {
79
- box-shadow: none;
80
- }
@@ -1,114 +0,0 @@
1
- /* Typography Usage mixins */
2
- .tl-navigation-tabs__tab {
3
- /* tds-navigation-tab variables */
4
- --navigation-tabs-tab: var(--color-foreground-text-soft);
5
- --navigation-tabs-tab-selected: var(--color-foreground-text-strong);
6
- --navigation-tabs-tab-hover: var(--color-foreground-text-strong);
7
- --navigation-tabs-tab-focus: var(--color-foreground-text-strong);
8
- --navigation-tabs-tab-disabled: var(--color-foreground-text-disabled);
9
- --navigation-tabs-tab-indicator-hover: var(--color-foreground-border-discrete);
10
- --navigation-tabs-tab-indicator-active: var(--color-foreground-border-accent-focus);
11
- }
12
-
13
- .tl-navigation-tabs {
14
- /* tds-navigation-tabs variables */
15
- --navigation-tabs-horizontal-divider: var(--color-foreground-icon-discrete);
16
- --navigation-tabs-tab-background-primary: var(--scania-color-transparent-invisible-light);
17
- --navigation-tabs-tab-background-secondary: var(--scania-color-transparent-invisible-dark);
18
- --navigation-tabs-tab-background: var(--navigation-tabs-tab-background-primary);
19
- --navigation-tabs-scroll-button-icon: var(--color-foreground-icon-strong);
20
- --navigation-tabs-scroll-button-background: var(--navigation-tabs-tab-background);
21
- --navigation-tabs-scroll-button-background-hover: var(--navigation-tabs-tab-background);
22
- --navigation-tabs-scroll-button-background-active: var(--navigation-tabs-tab-background);
23
- }
24
- .tl-navigation-tabs--primary {
25
- --navigation-tabs-tab-background: var(--navigation-tabs-tab-background-primary);
26
- }
27
- .tl-navigation-tabs--secondary {
28
- --navigation-tabs-tab-background: var(--navigation-tabs-tab-background-secondary);
29
- }
30
-
31
- .traton .tl-navigation-tabs {
32
- --navigation-tabs-tab-background-primary: var(--traton-color-transparent-invisible-light);
33
- --navigation-tabs-tab-background-secondary: var(--traton-color-transparent-invisible-dark);
34
- }
35
-
36
- .tl-navigation-tabs__tab {
37
- all: unset;
38
- margin-right: 32px;
39
- box-sizing: border-box;
40
- }
41
- .tl-navigation-tabs__tab * {
42
- box-sizing: border-box;
43
- }
44
- .tl-navigation-tabs__tab {
45
- font-family: var(--headline-07-font-family);
46
- font-size: var(--headline-07-font-size);
47
- line-height: var(--headline-07-line-height);
48
- font-weight: var(--headline-07-font-weight);
49
- letter-spacing: var(--headline-07-letter-spacing);
50
- text-transform: var(--headline-07-text-transform);
51
- color: var(--navigation-tabs-tab);
52
- text-decoration: none;
53
- display: block;
54
- position: relative;
55
- transition: color 0.15s ease-in-out 0s;
56
- white-space: nowrap;
57
- background-color: transparent;
58
- border: 0;
59
- padding: 26px 4px;
60
- }
61
- .tl-navigation-tabs__tab:focus-visible {
62
- outline: none;
63
- }
64
- .tl-navigation-tabs__tab:focus-visible::before {
65
- content: "";
66
- position: absolute;
67
- inset: 18px 0;
68
- border-radius: 2px;
69
- box-shadow: 0 0 0 2px var(--navigation-tabs-tab-focus) inset;
70
- z-index: 2;
71
- pointer-events: none;
72
- }
73
- .tl-navigation-tabs__tab::after {
74
- background-color: var(--navigation-tabs-tab-indicator-hover);
75
- content: " ";
76
- position: absolute;
77
- bottom: 0;
78
- right: 0;
79
- left: 0;
80
- margin-left: auto;
81
- width: 0%;
82
- margin-right: auto;
83
- height: 2px;
84
- z-index: 1;
85
- transition: width 0.15s ease-in-out 0s;
86
- }
87
- .tl-navigation-tabs__tab:not(.tl-navigation-tabs__tab--selected)::after {
88
- width: 0%;
89
- }
90
- .tl-navigation-tabs__tab:hover {
91
- cursor: pointer;
92
- color: var(--navigation-tabs-tab-hover);
93
- }
94
- .tl-navigation-tabs__tab:hover::after {
95
- width: 100%;
96
- }
97
- .tl-navigation-tabs__tab--selected {
98
- color: var(--navigation-tabs-tab-selected);
99
- }
100
- .tl-navigation-tabs__tab--selected::after {
101
- background-color: var(--navigation-tabs-tab-indicator-active);
102
- width: 100%;
103
- }
104
- .tl-navigation-tabs__tab--disabled {
105
- color: var(--navigation-tabs-tab-disabled);
106
- pointer-events: none;
107
- cursor: not-allowed;
108
- }
109
- .tl-navigation-tabs__tab--disabled::after {
110
- content: none;
111
- }
112
- .tl-navigation-tabs__tab--disabled:focus-visible::before {
113
- box-shadow: none;
114
- }
File without changes