Split randomizer views and align NDS toolbox vocabulary
All checks were successful
Deploy Sokko G / deploy (push) Successful in 17s

This commit is contained in:
Shinuwa 2026-09-01 19:47:22 +02:00
parent 6b85e58765
commit fef7735a1d
57 changed files with 4932 additions and 4815 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,31 @@
// Rôle : fournit les primitives de surfaces réutilisables du design system.
@mixin card-surface($fill: rgba(16, 20, 38, 0.88)) {
border-color: transparent;
border-radius: var(--radius-md);
background:
linear-gradient($fill, $fill) padding-box,
radial-gradient(circle at 100% 0%, rgba(34, 211, 238, 0.42), transparent 28%) border-box,
linear-gradient(135deg, rgba(246, 196, 83, 0.62) 0%, rgba(246, 196, 83, 0.42) 72%, rgba(34, 211, 238, 0.24) 100%) border-box;
}
@mixin card-surface-hover(
$fill: rgba(21, 26, 48, 0.96),
$start: rgba(139, 92, 246, 0.9),
$end: rgba(196, 181, 253, 0.72),
$glow-primary: 0 0 18px rgba(139, 92, 246, 0.22),
$glow-secondary: 0 0 34px rgba(196, 181, 253, 0.12)
) {
border-color: transparent;
background:
linear-gradient($fill, $fill) padding-box,
linear-gradient(135deg, $start, $end) border-box;
box-shadow:
var(--shadow-sm),
$glow-primary,
$glow-secondary;
}
@mixin card-cover-divider {
border-bottom: 1px solid rgba(246, 196, 83, 0.42);
}

View file

@ -0,0 +1,369 @@
// Rôle : expose les classes NDS de boutons texte, icône et lignes.
@use "../controls";
.nds-button {
@include controls.text-button;
font-weight: 800;
}
.nds-button:hover:not(:disabled, [data-variant="primary"], [data-variant="danger"], [data-variant="ghost"], .active, .is-active, [aria-pressed="true"]) {
@include controls.text-button-hover;
}
.nds-button[data-size="sm"] {
@include controls.text-button(sm);
}
.nds-button[data-size="xs"] {
@include controls.text-button(xs);
}
.nds-button[data-variant="primary"] {
@include controls.text-button-primary;
}
.nds-button[data-variant="primary"]:hover {
@include controls.text-button-primary-hover;
}
.nds-button[data-variant="secondary"] {
@include controls.text-button-secondary;
}
.nds-button[data-variant="ghost"] {
@include controls.text-button-ghost;
}
.nds-button[data-variant="ghost"]:hover {
@include controls.text-button-ghost-hover;
}
.nds-button[data-variant="dashed"] {
@include controls.text-button-dashed;
}
.nds-button[data-variant="dashed"]:hover {
@include controls.text-button-dashed-hover;
}
.nds-button[data-variant="danger"] {
@include controls.text-button-danger;
}
.nds-button[data-variant="danger"]:hover {
@include controls.text-button-danger-hover;
}
.nds-button[data-edge="left"] {
@include controls.button-edge(left);
}
.nds-button[data-edge="middle"] {
@include controls.button-edge(middle);
}
.nds-button[data-edge="top"] {
@include controls.button-edge(top);
}
.nds-button[data-edge="center"] {
@include controls.button-edge(center);
}
.nds-button[data-edge="right"] {
@include controls.button-edge(right);
}
.nds-button[data-edge="bottom"] {
@include controls.button-edge(bottom);
}
.nds-button[data-edge="top-left"] {
@include controls.button-edge(top-left);
}
.nds-button[data-edge="top-right"] {
@include controls.button-edge(top-right);
}
.nds-button[data-edge="bottom-right"] {
@include controls.button-edge(bottom-right);
}
.nds-button[data-edge="bottom-left"] {
@include controls.button-edge(bottom-left);
}
.nds-button[data-border="joined"][data-edge="left"] {
@include controls.button-joined-border(left);
}
.nds-button[data-border="joined"][data-edge="middle"] {
@include controls.button-joined-border(middle);
}
.nds-button[data-border="joined"][data-edge="top"] {
@include controls.button-joined-border(top);
}
.nds-button[data-border="joined"][data-edge="center"] {
@include controls.button-joined-border(center);
}
.nds-button[data-border="joined"][data-edge="right"] {
@include controls.button-joined-border(right);
}
.nds-button[data-border="joined"][data-edge="bottom"] {
@include controls.button-joined-border(bottom);
}
.nds-button[data-border="joined"][data-edge="top-left"] {
@include controls.button-joined-border(top-left);
}
.nds-button[data-border="joined"][data-edge="top-right"] {
@include controls.button-joined-border(top-right);
}
.nds-button[data-border="joined"][data-edge="bottom-right"] {
@include controls.button-joined-border(bottom-right);
}
.nds-button[data-border="joined"][data-edge="bottom-left"] {
@include controls.button-joined-border(bottom-left);
}
.nds-button[data-border="none"] {
@include controls.button-borderless;
}
.nds-button.is-active,
.nds-button.active,
.nds-button.active,
.nds-button.is-active,
.nds-button[aria-pressed="true"] {
@include controls.text-button-active;
}
.nds-icon-button {
@include controls.icon-button;
display: inline-grid;
place-items: center;
box-shadow: none;
}
.nds-icon-button .ui-icon {
@include controls.icon-button-icon;
}
.nds-icon-button[class*="drag-handle"] {
cursor: grab;
touch-action: none;
user-select: none;
}
.nds-icon-button[class*="drag-handle"]:active {
cursor: grabbing;
}
.nds-icon-button[class*="drag-handle"]:disabled {
cursor: not-allowed;
}
.nds-icon-button:hover:not([data-variant="primary"], [data-variant="danger"], [data-variant="ghost"], .active, .is-active, [aria-pressed="true"]) {
@include controls.icon-button-hover;
}
.nds-icon-button:hover:not([data-variant="primary"], [data-variant="danger"], [data-variant="ghost"], .active, .is-active, [aria-pressed="true"]) .ui-icon {
@include controls.icon-button-hover-icon;
}
.nds-icon-button[data-size="sm"] {
@include controls.icon-button(sm);
}
.nds-icon-button[data-size="sm"] .ui-icon {
@include controls.icon-button-icon(sm);
}
.nds-icon-button[data-size="xs"] {
@include controls.icon-button(xs);
}
.nds-icon-button[data-size="xs"] .ui-icon {
@include controls.icon-button-icon(xs);
}
.nds-icon-button[data-size="xxs"] {
@include controls.icon-button(xxs);
}
.nds-icon-button[data-size="xxs"] .ui-icon {
@include controls.icon-button-icon(xxs);
}
.nds-icon-button[data-size="micro"] {
@include controls.icon-button(micro);
}
.nds-icon-button[data-size="micro"] .ui-icon {
@include controls.icon-button-icon(micro);
}
.nds-icon-button[data-variant="primary"] {
@include controls.icon-button-primary;
}
.nds-icon-button[data-variant="primary"]:hover {
@include controls.icon-button-primary-hover;
}
.nds-icon-button[data-variant="primary"]:hover .ui-icon {
@include controls.icon-button-primary-hover-icon;
}
.nds-icon-button[data-variant="ghost"] {
@include controls.icon-button-ghost;
}
.nds-icon-button[data-variant="panel-toggle"] {
@include controls.icon-button-panel-toggle;
}
.nds-icon-button[data-variant="panel-toggle"]:hover,
.nds-icon-button[data-variant="panel-toggle"].active,
.nds-icon-button[data-variant="panel-toggle"].is-active,
.nds-icon-button[data-variant="panel-toggle"][aria-pressed="true"] {
@include controls.icon-button-panel-toggle-hover;
}
.nds-icon-button[data-variant="danger"] {
@include controls.icon-button-danger;
}
.nds-icon-button[data-variant="danger"]:hover {
@include controls.icon-button-danger-hover;
}
.nds-icon-button[data-variant="danger"]:hover .ui-icon {
@include controls.icon-button-danger-hover-icon;
}
.nds-icon-button[class*="drag-handle"]:hover {
cursor: grab;
}
.nds-icon-button[class*="drag-handle"]:active,
.nds-icon-button[class*="drag-handle"]:hover:active {
cursor: grabbing;
}
.nds-icon-button[data-edge="left"] {
@include controls.button-edge(left);
}
.nds-icon-button[data-edge="middle"] {
@include controls.button-edge(middle);
}
.nds-icon-button[data-edge="top"] {
@include controls.button-edge(top);
}
.nds-icon-button[data-edge="center"] {
@include controls.button-edge(center);
}
.nds-icon-button[data-edge="right"] {
@include controls.button-edge(right);
}
.nds-icon-button[data-edge="bottom"] {
@include controls.button-edge(bottom);
}
.nds-icon-button[data-edge="top-left"] {
@include controls.button-edge(top-left);
}
.nds-icon-button[data-edge="top-right"] {
@include controls.button-edge(top-right);
}
.nds-icon-button[data-edge="bottom-right"] {
@include controls.button-edge(bottom-right);
}
.nds-icon-button[data-edge="bottom-left"] {
@include controls.button-edge(bottom-left);
}
.nds-icon-button[data-border="joined"][data-edge="left"] {
@include controls.button-joined-border(left);
}
.nds-icon-button[data-border="joined"][data-edge="middle"] {
@include controls.button-joined-border(middle);
}
.nds-icon-button[data-border="joined"][data-edge="top"] {
@include controls.button-joined-border(top);
}
.nds-icon-button[data-border="joined"][data-edge="center"] {
@include controls.button-joined-border(center);
}
.nds-icon-button[data-border="joined"][data-edge="right"] {
@include controls.button-joined-border(right);
}
.nds-icon-button[data-border="joined"][data-edge="bottom"] {
@include controls.button-joined-border(bottom);
}
.nds-icon-button[data-border="joined"][data-edge="top-left"] {
@include controls.button-joined-border(top-left);
}
.nds-icon-button[data-border="joined"][data-edge="top-right"] {
@include controls.button-joined-border(top-right);
}
.nds-icon-button[data-border="joined"][data-edge="bottom-right"] {
@include controls.button-joined-border(bottom-right);
}
.nds-icon-button[data-border="joined"][data-edge="bottom-left"] {
@include controls.button-joined-border(bottom-left);
}
.nds-icon-button[data-border="none"] {
@include controls.button-borderless;
}
.nds-icon-button.active,
.nds-icon-button.is-active,
.nds-icon-button[aria-pressed="true"] {
@include controls.icon-button-active;
}
.nds-list-row {
@include controls.list-row-button;
}
.nds-list-row:hover,
.nds-list-row.is-active,
.nds-list-row.active {
@include controls.list-row-button-hover;
}
.nds-list-row.is-active,
.nds-list-row.active {
@include controls.list-row-button-active;
}
.nds-list-row button {
@include controls.list-row-button-content;
}

View file

@ -0,0 +1,46 @@
// Rôle : expose les classes NDS de cases à cocher.
@use "../controls";
.nds-checkbox {
@include controls.checkbox-control;
}
.nds-checkbox[data-size="xs"] {
@include controls.checkbox-control(xs);
}
.nds-checkbox[data-size="sm"] {
@include controls.checkbox-control(sm);
}
.nds-checkbox::before {
@include controls.checkbox-check;
}
.nds-checkbox[data-size="xs"]::before {
@include controls.checkbox-check(xs);
}
.nds-checkbox[data-size="sm"]::before {
@include controls.checkbox-check(sm);
}
.nds-checkbox:hover:not(:disabled) {
@include controls.checkbox-hover;
}
.nds-checkbox:checked {
@include controls.checkbox-checked;
}
.nds-checkbox:checked::before {
@include controls.checkbox-checked-check;
}
.nds-checkbox:disabled {
@include controls.checkbox-disabled;
}
.nds-checkbox:disabled::before {
opacity: 0.54;
}

View file

@ -0,0 +1,110 @@
// Rôle : expose les classes NDS de surfaces événement.
@use "../controls";
.nds-event-surface {
--nds-event-color: #8b5cf6;
box-sizing: border-box;
width: min(210px, 100%);
min-height: 44px;
overflow: hidden;
border: 1px solid color-mix(in srgb, var(--nds-event-color) 24%, rgba(255, 255, 255, 0.22));
border-radius: var(--radius-sm);
background: color-mix(in srgb, var(--nds-event-color) 82%, transparent);
box-shadow: 0 10px 22px rgba(0, 0, 0, 0.22);
}
.nds-event-surface[data-size="md"] {
min-height: 44px;
}
.nds-event-surface[data-size="sm"] {
min-height: 22px;
}
.nds-event-surface[data-size="xs"] {
min-height: 10px;
border-width: 0;
border-radius: 4px;
}
.nds-event-surface[data-variant="dark"] {
border-color: color-mix(in srgb, var(--nds-event-color) 42%, rgba(11, 14, 27, 0.28));
background: color-mix(in srgb, var(--nds-event-color) 88%, transparent);
}
.nds-event-surface button {
@include controls.event-surface-button;
@include controls.event-surface-contrast-default;
}
.nds-event-surface button:hover,
.nds-event-surface button:focus-visible {
@include controls.event-surface-button-hover;
}
.nds-event-surface[data-size="sm"] button {
display: block;
padding: 4px 7px;
text-align: center;
}
.nds-event-surface[data-size="xs"] button {
position: relative;
display: block;
padding: 0 4px;
text-align: center;
}
.nds-event-surface[data-size="xs"] button:hover,
.nds-event-surface[data-size="xs"] button:focus-visible {
background: rgba(0, 0, 0, 0.18);
}
.nds-event-surface[data-size="sm"] button > span {
display: none;
}
.nds-event-surface[data-size="xs"] button > span {
display: none;
}
.nds-event-surface strong,
.nds-event-surface span {
display: block;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.nds-event-surface[data-variant="dark"] button {
@include controls.event-surface-contrast-dark;
}
.nds-event-surface strong {
font-size: 11px;
line-height: 14px;
}
.nds-event-surface[data-size="sm"] strong {
max-width: 100%;
line-height: 14px;
}
.nds-event-surface[data-size="xs"] strong {
position: absolute;
top: 0;
right: 4px;
left: 4px;
max-width: 100%;
height: 10px;
font-size: 8px;
line-height: 10px;
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.45);
}
.nds-event-surface span {
font-size: 10px;
line-height: 12px;
opacity: 0.86;
}

View file

@ -0,0 +1,107 @@
// Rôle : expose les classes NDS de champs, select et textarea.
@use "../controls";
.nds-input,
.nds-time,
.nds-select,
.nds-textarea {
@include controls.field-control;
}
.nds-input::placeholder,
.nds-textarea::placeholder {
@include controls.field-placeholder;
}
.nds-input[data-size="sm"],
.nds-textarea[data-size="sm"] {
@include controls.field-control(sm);
}
.nds-input[data-size="xs"],
.nds-textarea[data-size="xs"] {
@include controls.field-control(xs);
}
.nds-time {
@include controls.time-control;
}
.nds-time[data-size="sm"] {
@include controls.time-control(sm);
}
.nds-time[data-size="xs"] {
@include controls.time-control(xs);
}
.nds-select {
@include controls.select-control;
}
.nds-select[data-size="sm"] {
@include controls.select-control(sm);
}
.nds-select[data-size="xs"] {
@include controls.select-control(xs);
}
.nds-select:hover,
.nds-select:focus {
@include controls.select-control-hover;
box-shadow: none;
}
.nds-select:focus {
border-color: var(--color-primary);
box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.16);
}
.nds-select option {
@include controls.select-option;
}
.nds-textarea {
@include controls.field-textarea;
@include controls.scrollbar-resizer;
}
.nds-textarea[data-size="sm"] {
@include controls.field-textarea(sm);
}
.nds-textarea[data-size="xs"] {
@include controls.field-textarea(xs);
}
.nds-textarea[data-variant="ghost"] {
@include controls.field-textarea-ghost;
}
.nds-input:hover,
.nds-time:hover,
.nds-textarea:hover {
@include controls.field-hover;
}
.nds-textarea[data-variant="ghost"]:hover {
@include controls.inline-field-hover;
}
.nds-input:focus,
.nds-time:focus,
.nds-select:focus,
.nds-select-trigger:focus,
.nds-textarea:focus {
@include controls.field-focus;
}
.nds-inline-input {
@include controls.inline-field;
}
.nds-inline-input:hover,
.nds-inline-input:focus {
@include controls.inline-field-hover;
}

View file

@ -0,0 +1,189 @@
// Rôle : expose les classes NDS de swatches, triggers select et icon pickers.
@use "../controls";
.nds-swatch {
@include controls.color-swatch;
}
.nds-swatch[data-variant="rainbow"] {
@include controls.color-swatch-rainbow;
}
.nds-swatch.active,
.nds-swatch.is-active,
.nds-swatch[aria-pressed="true"] {
@include controls.color-swatch-active;
}
.nds-select-trigger,
.nds-date-trigger {
@include controls.select-trigger;
}
.nds-select-trigger[data-size="sm"],
.nds-date-trigger[data-size="sm"] {
@include controls.select-trigger(sm);
}
.nds-select-trigger[data-size="xs"],
.nds-date-trigger[data-size="xs"] {
@include controls.select-trigger(xs);
}
.nds-select-trigger[data-variant="icon-picker"] {
grid-template-columns: minmax(18px, 1fr);
justify-items: center;
min-width: 52px;
padding-inline: 10px 30px;
}
.nds-select-trigger[data-variant="icon-picker"]:has(> span:not([aria-hidden="true"])) {
grid-template-columns: 18px minmax(0, 1fr);
justify-items: start;
padding-inline: 10px 34px;
}
.nds-select-trigger[data-size="sm"][data-variant="icon-picker"] {
grid-template-columns: minmax(18px, 1fr);
min-width: 50px;
padding-inline: 10px 30px;
}
.nds-select-trigger[data-size="sm"][data-variant="icon-picker"]:has(> span:not([aria-hidden="true"])) {
grid-template-columns: 18px minmax(0, 1fr);
padding-inline: 10px 34px;
}
.nds-select-trigger[data-size="xs"][data-variant="icon-picker"] {
grid-template-columns: minmax(16px, 1fr);
min-width: 46px;
padding-inline: 9px 28px;
}
.nds-select-trigger[data-size="xs"][data-variant="icon-picker"]:has(> span:not([aria-hidden="true"])) {
grid-template-columns: 16px minmax(0, 1fr);
padding-inline: 8px 30px;
}
.nds-select-trigger:hover:not(:disabled),
.nds-select-trigger.is-active,
.nds-select-trigger.active,
.nds-select-trigger[aria-pressed="true"],
.nds-date-trigger:hover:not(:disabled),
.nds-date-trigger.is-active,
.nds-date-trigger.active,
.nds-date-trigger[aria-pressed="true"] {
@include controls.select-trigger-hover;
}
.nds-select-trigger:focus,
.nds-date-trigger:focus {
@include controls.select-trigger-hover;
@include controls.field-focus;
outline: 2px solid var(--color-accent-gold);
outline-offset: 3px;
}
.nds-select-trigger[data-size="sm"]:hover:not(:disabled),
.nds-select-trigger[data-size="sm"].is-active,
.nds-select-trigger[data-size="sm"].active,
.nds-select-trigger[data-size="sm"][aria-pressed="true"],
.nds-date-trigger[data-size="sm"]:hover:not(:disabled),
.nds-date-trigger[data-size="sm"].is-active,
.nds-date-trigger[data-size="sm"].active,
.nds-date-trigger[data-size="sm"][aria-pressed="true"] {
@include controls.select-trigger-hover(sm);
}
.nds-select-trigger[data-size="sm"]:focus,
.nds-date-trigger[data-size="sm"]:focus {
@include controls.select-trigger-hover(sm);
@include controls.field-focus;
outline: 2px solid var(--color-accent-gold);
outline-offset: 3px;
}
.nds-select-trigger[data-size="xs"]:hover:not(:disabled),
.nds-select-trigger[data-size="xs"].is-active,
.nds-select-trigger[data-size="xs"].active,
.nds-select-trigger[data-size="xs"][aria-pressed="true"],
.nds-date-trigger[data-size="xs"]:hover:not(:disabled),
.nds-date-trigger[data-size="xs"].is-active,
.nds-date-trigger[data-size="xs"].active,
.nds-date-trigger[data-size="xs"][aria-pressed="true"] {
@include controls.select-trigger-hover(xs);
}
.nds-select-trigger[data-size="xs"]:focus,
.nds-date-trigger[data-size="xs"]:focus {
@include controls.select-trigger-hover(xs);
@include controls.field-focus;
outline: 2px solid var(--color-accent-gold);
outline-offset: 3px;
}
.nds-select-trigger .ui-icon,
.nds-date-trigger .ui-icon {
@include controls.select-trigger-icon;
}
.nds-select-trigger[data-size="sm"] .ui-icon,
.nds-date-trigger[data-size="sm"] .ui-icon {
@include controls.select-trigger-icon(sm);
}
.nds-select-trigger[data-size="xs"] .ui-icon,
.nds-date-trigger[data-size="xs"] .ui-icon {
@include controls.select-trigger-icon(xs);
}
.nds-select-trigger .ui-icon-chevron-down,
.nds-date-trigger .ui-icon-chevron-down {
@include controls.date-picker-trigger-chevron;
}
.nds-select-trigger[data-variant="icon-picker"] > .ui-icon:not(.ui-icon-chevron-down) {
width: 18px;
height: 18px;
}
.nds-select-trigger[data-variant="icon-picker"]:has(> span:not([aria-hidden="true"])) > .ui-icon:not(.ui-icon-chevron-down) {
justify-self: center;
}
.nds-select-trigger[data-size="xs"][data-variant="icon-picker"] > .ui-icon:not(.ui-icon-chevron-down) {
width: 16px;
height: 16px;
}
.nds-select-trigger span,
.nds-date-trigger span {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.nds-large-icon-picker-trigger {
@include controls.large-icon-picker-trigger;
}
.nds-large-icon-picker-trigger:hover {
@include controls.large-icon-picker-trigger-hover;
}
.nds-large-icon-picker-trigger.active,
.nds-large-icon-picker-trigger.is-active,
.nds-large-icon-picker-trigger[aria-pressed="true"] {
@include controls.large-icon-picker-trigger-hover;
border-color: rgba(246, 196, 83, 0.62);
box-shadow:
0 0 0 1px rgba(246, 196, 83, 0.22),
0 0 22px rgba(139, 92, 246, 0.24);
}
.nds-large-icon-picker-trigger img,
.nds-large-icon-picker-trigger .ui-icon {
width: 72px;
height: 72px;
object-fit: contain;
}

View file

@ -0,0 +1,63 @@
// Rôle : expose les scrollboxes, focus et états désactivés NDS.
@use "../controls";
.nds-scrollbox,
.nds-textarea {
width: 100%;
@include controls.scrollbar-control;
}
.nds-scrollbox {
max-height: 400px;
overflow: auto;
padding: 12px;
border: 1px solid rgba(165, 180, 252, 0.12);
border-radius: var(--radius-md);
background: rgba(5, 7, 17, 0.34);
color: var(--color-text-secondary);
}
.nds-scrollbox[data-variant="ghost"] {
padding: 0;
border: 0;
border-radius: 0;
background: transparent;
}
.nds-scrollbox[data-axis="horizontal"] {
max-height: none;
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
}
.nds-input:focus-visible,
.nds-time:focus-visible,
.nds-select:focus-visible,
.nds-textarea:focus-visible,
.nds-inline-input:focus-visible,
.nds-button:focus-visible,
.nds-icon-button:focus-visible,
.nds-switch:focus-visible,
.nds-radio-button-group button:focus-visible,
.nds-checkbox:focus-visible,
.nds-select-trigger:focus-visible,
.nds-date-trigger:focus-visible,
.nds-large-icon-picker-trigger:focus-visible {
@include controls.field-focus;
outline: 2px solid var(--color-accent-gold);
outline-offset: 3px;
}
.nds-button:disabled,
.nds-icon-button:disabled,
.nds-quantity-stepper button:disabled,
.nds-select:disabled,
.nds-select-trigger:disabled,
.nds-input:disabled,
.nds-time:disabled,
.nds-textarea:disabled,
.nds-date-trigger:disabled,
.nds-large-icon-picker-trigger:disabled {
@include controls.control-disabled;
}

View file

@ -0,0 +1,56 @@
// Rôle : expose les classes NDS de steppers numériques.
@use "../controls";
.nds-quantity-stepper {
@include controls.quantity-stepper;
}
.nds-quantity-stepper[data-size="sm"] {
@include controls.quantity-stepper(sm);
}
.nds-quantity-stepper[data-size="xs"] {
@include controls.quantity-stepper(xs);
}
.nds-quantity-stepper button {
@include controls.quantity-stepper-button;
}
.nds-quantity-stepper[data-size="sm"] button {
@include controls.quantity-stepper-button(sm);
}
.nds-quantity-stepper[data-size="xs"] button {
@include controls.quantity-stepper-button(xs);
}
.nds-quantity-stepper button:hover {
@include controls.quantity-stepper-button-hover;
}
.nds-quantity-stepper .ui-icon {
@include controls.quantity-stepper-button-icon;
}
.nds-quantity-stepper[data-size="sm"] .ui-icon {
@include controls.quantity-stepper-button-icon(sm);
}
.nds-quantity-stepper[data-size="xs"] .ui-icon {
@include controls.quantity-stepper-button-icon(xs);
}
.nds-quantity-stepper-value {
@include controls.quantity-stepper-value;
}
.nds-quantity-stepper-input {
@include controls.quantity-stepper-input;
@include controls.number-spinner-reset;
}
.nds-quantity-stepper-input:hover,
.nds-quantity-stepper-input:focus {
@include controls.quantity-stepper-input-hover;
}

View file

@ -0,0 +1,186 @@
// Rôle : expose les classes NDS de switchs, radio groups et toggles composés.
@use "../controls";
.nds-switch {
@include controls.switch-control;
}
.nds-switch[data-size="lg"] {
@include controls.switch-control(lg);
}
.nds-switch[data-size="sm"] {
@include controls.switch-control(sm);
}
.nds-switch[data-size="xs"] {
@include controls.switch-control(xs);
}
.nds-switch:has(> span:not(.ui-icon)) {
grid-template-columns: var(--nds-switch-icon-size) minmax(0, 1fr) var(--nds-switch-track-width);
min-width: max-content;
}
.nds-switch:has(> span:not(.ui-icon)) > span:not(.ui-icon) {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.nds-switch .ui-icon {
@include controls.switch-icon;
}
.nds-switch i {
@include controls.switch-track;
}
.nds-switch i::before {
@include controls.switch-thumb;
}
.nds-switch:hover {
@include controls.switch-hover;
}
.nds-switch.active,
.nds-switch.is-active,
.nds-switch[aria-pressed="true"] {
@include controls.switch-active;
}
.nds-switch.active i,
.nds-switch.is-active i,
.nds-switch[aria-pressed="true"] i {
@include controls.switch-active-track;
}
.nds-switch.active i::before,
.nds-switch.is-active i::before,
.nds-switch[aria-pressed="true"] i::before {
@include controls.switch-active-thumb;
}
.nds-native-switch {
@include controls.native-switch-label;
}
.nds-native-switch input {
@include controls.native-switch-input;
}
.nds-native-switch > span:first-of-type {
--nds-switch-track-width: 36px;
--nds-switch-track-height: 20px;
--nds-switch-thumb-size: 12px;
--nds-switch-thumb-left: 3px;
--nds-switch-active-left: 19px;
@include controls.switch-track;
min-width: 36px;
}
.nds-native-switch > span:first-of-type::before {
@include controls.switch-thumb;
}
.nds-native-switch input:checked + span {
@include controls.switch-active-track;
}
.nds-native-switch input:checked + span::before {
@include controls.switch-active-thumb;
}
.nds-native-switch:has(input:disabled) {
@include controls.control-disabled;
cursor: not-allowed;
}
.nds-native-switch:has(input:disabled) > span:first-of-type,
.nds-native-switch:has(input:disabled) b {
cursor: not-allowed;
}
.nds-radio-button-group {
@include controls.radio-button-group;
}
.nds-radio-button-group[data-size="sm"] {
@include controls.radio-button-group(sm);
}
.nds-radio-button-group[data-size="xs"] {
@include controls.radio-button-group(xs);
}
.nds-radio-button-group > button,
.nds-radio-button-group > span {
@include controls.radio-button-group-option;
}
.nds-radio-button-group[data-size="sm"] > button,
.nds-radio-button-group[data-size="sm"] > span {
@include controls.radio-button-group-option(sm);
}
.nds-radio-button-group[data-size="xs"] > button,
.nds-radio-button-group[data-size="xs"] > span {
@include controls.radio-button-group-option(xs);
}
.nds-radio-button-group > button:hover,
.nds-radio-button-group > span:hover {
@include controls.radio-button-group-option-hover;
}
.nds-radio-button-group > button.active,
.nds-radio-button-group > button.is-active,
.nds-radio-button-group > span.active,
.nds-radio-button-group > span.is-active {
@include controls.radio-button-group-option-active;
}
.nds-radio-button-group .ui-icon {
@include controls.radio-button-group-option-icon;
}
.nds-radio-button-group[data-size="sm"] .ui-icon {
@include controls.radio-button-group-option-icon(sm);
}
.nds-radio-button-group[data-size="xs"] .ui-icon {
@include controls.radio-button-group-option-icon(xs);
}
.nds-radio-button-group[aria-disabled="true"] {
@include controls.control-disabled;
}
.nds-compound-toggle-field {
@include controls.compound-toggle-field;
}
.nds-compound-toggle-field button {
@include controls.compound-toggle-field-option;
}
.nds-compound-toggle-field button:hover:not(:disabled) {
@include controls.radio-button-group-option-hover;
}
.nds-compound-toggle-field button.is-active,
.nds-compound-toggle-field button.active,
.nds-compound-toggle-field button[aria-pressed="true"] {
@include controls.radio-button-group-option-active;
}
.nds-compound-toggle-field-input {
@include controls.compound-toggle-field-input;
}
.nds-compound-toggle-field-input:hover,
.nds-compound-toggle-field-input:focus {
@include controls.inline-field-hover;
}

View file

@ -0,0 +1,429 @@
// Rôle : regroupe les mixins de boutons texte, icône, bords joints et toolbar.
@use "../../mixins";
@mixin text-button($size: md) {
$height: 42px;
$padding: 0 18px;
$font-size: inherit;
@if $size == sm {
$height: 34px;
$padding: 0 12px;
$font-size: var(--font-size-sm);
} @else if $size == xs {
$height: 30px;
$padding: 0 10px;
$font-size: var(--font-size-xs);
}
display: inline-flex;
min-height: $height;
align-items: center;
justify-content: center;
gap: 8px;
padding: $padding;
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
background: rgba(21, 26, 48, 0.92);
color: var(--color-text-primary);
font: inherit;
font-size: $font-size;
cursor: pointer;
transition:
transform var(--duration-fast) var(--ease-standard),
border-color var(--duration-fast) var(--ease-standard),
background-color var(--duration-fast) var(--ease-standard),
color var(--duration-fast) var(--ease-standard),
box-shadow var(--duration-fast) var(--ease-standard);
}
@mixin text-button-hover {
border-color: rgba(196, 181, 253, 0.34);
background:
linear-gradient(135deg, rgba(31, 37, 68, 0.96), rgba(22, 26, 51, 0.96)) padding-box,
linear-gradient(135deg, rgba(139, 92, 246, 0.32), rgba(196, 181, 253, 0.2)) border-box;
box-shadow:
0 0 14px rgba(139, 92, 246, 0.12),
inset 0 1px 0 rgba(255, 255, 255, 0.05);
}
@mixin text-button-primary {
border-color: rgba(246, 196, 83, 0.34);
background:
linear-gradient(135deg, rgba(72, 43, 160, 0.96), rgba(45, 52, 146, 0.94)) padding-box,
linear-gradient(135deg, rgba(246, 196, 83, 0.66), rgba(139, 92, 246, 0.36)) border-box;
box-shadow:
0 8px 22px rgba(5, 7, 17, 0.22),
inset 0 1px 0 rgba(255, 255, 255, 0.08);
color: #fff;
font-weight: 700;
}
@mixin text-button-primary-hover {
border-color: rgba(246, 196, 83, 0.72);
background:
radial-gradient(circle at 100% 0, rgba(246, 196, 83, 0.24), transparent 42%) padding-box,
linear-gradient(135deg, rgba(125, 62, 232, 0.98), rgba(62, 72, 184, 0.98)) padding-box,
linear-gradient(135deg, rgba(255, 219, 128, 0.98), rgba(139, 92, 246, 0.82), rgba(34, 211, 238, 0.42)) border-box;
box-shadow:
0 0 0 1px rgba(246, 196, 83, 0.18),
0 0 18px rgba(139, 92, 246, 0.26),
0 0 24px rgba(246, 196, 83, 0.14),
inset 0 1px 0 rgba(255, 255, 255, 0.2),
inset 0 -2px 0 rgba(246, 196, 83, 0.24);
}
@mixin text-button-secondary {
border-color: rgba(196, 181, 253, 0.18);
background:
linear-gradient(135deg, rgba(31, 37, 68, 0.72), rgba(15, 23, 42, 0.72)) padding-box,
linear-gradient(135deg, rgba(139, 92, 246, 0.3), rgba(34, 211, 238, 0.14)) border-box;
color: var(--color-text-primary);
}
@mixin text-button-ghost {
border-color: transparent;
background: transparent;
color: var(--color-text-secondary);
box-shadow: none;
}
@mixin text-button-ghost-hover {
border-color: rgba(196, 181, 253, 0.18);
background: rgba(139, 92, 246, 0.08);
color: var(--color-text-primary);
box-shadow: none;
}
@mixin text-button-dashed {
border-style: dashed;
border-color: rgba(246, 196, 83, 0.28);
background:
linear-gradient(135deg, rgba(246, 196, 83, 0.04), rgba(139, 92, 246, 0.06)),
rgba(7, 10, 24, 0.72);
color: var(--color-text-secondary);
font-weight: 900;
box-shadow: 0 10px 18px rgba(0, 0, 0, 0.16);
}
@mixin text-button-dashed-hover {
border-color: rgba(246, 196, 83, 0.54);
background:
linear-gradient(135deg, rgba(246, 196, 83, 0.1), rgba(139, 92, 246, 0.1)),
rgba(13, 17, 34, 0.82);
color: var(--color-text-primary);
box-shadow:
0 0 16px rgba(246, 196, 83, 0.12),
0 10px 18px rgba(0, 0, 0, 0.16);
}
@mixin text-button-danger {
color: var(--color-danger);
}
@mixin text-button-danger-hover {
border-color: rgba(251, 113, 133, 0.48);
background:
radial-gradient(circle at 100% 0, rgba(251, 113, 133, 0.22), transparent 42%) padding-box,
linear-gradient(135deg, rgba(96, 22, 45, 0.94), rgba(58, 16, 34, 0.96)) padding-box,
linear-gradient(135deg, rgba(251, 113, 133, 0.82), rgba(244, 114, 182, 0.42), rgba(196, 181, 253, 0.18)) border-box;
color: #fff;
box-shadow:
0 0 0 1px rgba(251, 113, 133, 0.12),
0 0 16px rgba(251, 113, 133, 0.16),
inset 0 1px 0 rgba(255, 255, 255, 0.08),
inset 0 -2px 0 rgba(251, 113, 133, 0.24);
}
@mixin text-button-active {
@include mixins.temporary-toggle-active;
}
@mixin list-row-button {
overflow: hidden;
border: 1px solid rgba(150, 165, 205, 0.12);
border-radius: var(--radius-sm);
background: rgba(5, 7, 17, 0.36);
}
@mixin list-row-button-hover {
border-color: rgba(150, 165, 205, 0.24);
background: rgba(5, 7, 17, 0.5);
}
@mixin list-row-button-active {
border-color: rgba(246, 196, 83, 0.42);
background: rgba(246, 196, 83, 0.08);
}
@mixin list-row-button-content {
display: inline-flex;
width: 100%;
min-height: 32px;
align-items: center;
justify-content: flex-start;
overflow: hidden;
padding: 0 8px;
border-color: transparent;
background: transparent;
color: var(--color-text-primary);
font-size: var(--font-size-sm);
font-weight: 900;
text-overflow: ellipsis;
white-space: nowrap;
}
@mixin control-disabled {
box-shadow: none;
cursor: not-allowed;
opacity: 0.48;
}
@mixin icon-button($size: md) {
$control-size: 40px;
@if $size == sm {
$control-size: 34px;
} @else if $size == xs {
$control-size: 30px;
} @else if $size == xxs {
$control-size: 26px;
} @else if $size == micro {
$control-size: 22px;
}
display: inline-flex;
width: $control-size;
height: $control-size;
min-width: $control-size;
min-height: $control-size;
align-items: center;
justify-content: center;
padding: 0;
border: 1px solid rgba(165, 180, 252, 0.12);
border-radius: var(--radius-md);
background: rgba(21, 26, 48, 0.88);
color: var(--color-text-secondary);
font: inherit;
cursor: pointer;
transition:
transform var(--duration-fast) var(--ease-standard),
border-color var(--duration-fast) var(--ease-standard),
background-color var(--duration-fast) var(--ease-standard),
color var(--duration-fast) var(--ease-standard),
box-shadow var(--duration-fast) var(--ease-standard);
}
@mixin icon-button-icon($size: md) {
$icon-size: 21px;
@if $size == sm {
$icon-size: 19px;
} @else if $size == xs {
$icon-size: 17px;
} @else if $size == xxs {
$icon-size: 15px;
} @else if $size == micro {
$icon-size: 12px;
}
width: $icon-size;
height: $icon-size;
transition:
background-color var(--duration-fast) var(--ease-standard),
filter var(--duration-fast) var(--ease-standard);
}
@mixin icon-button-hover {
border-color: rgba(196, 181, 253, 0.32);
background:
linear-gradient(135deg, rgba(31, 37, 68, 0.94), rgba(18, 22, 44, 0.96)) padding-box,
linear-gradient(135deg, rgba(139, 92, 246, 0.3), rgba(196, 181, 253, 0.2)) border-box;
color: var(--color-text-primary);
box-shadow:
0 0 12px rgba(139, 92, 246, 0.1),
inset 0 1px 0 rgba(255, 255, 255, 0.05);
}
@mixin icon-button-hover-icon {
background-color: #c4b5fd;
filter: drop-shadow(0 0 6px rgba(196, 181, 253, 0.28));
}
@mixin icon-button-primary {
border-color: rgba(246, 196, 83, 0.34);
background:
linear-gradient(135deg, rgba(72, 43, 160, 0.96), rgba(45, 52, 146, 0.94)) padding-box,
linear-gradient(135deg, rgba(246, 196, 83, 0.66), rgba(139, 92, 246, 0.36)) border-box;
color: #fff;
box-shadow:
0 8px 22px rgba(5, 7, 17, 0.22),
inset 0 1px 0 rgba(255, 255, 255, 0.08);
}
@mixin icon-button-primary-hover {
border-color: rgba(246, 196, 83, 0.72);
background:
radial-gradient(circle at 100% 0, rgba(246, 196, 83, 0.24), transparent 42%) padding-box,
linear-gradient(135deg, rgba(125, 62, 232, 0.98), rgba(62, 72, 184, 0.98)) padding-box,
linear-gradient(135deg, rgba(255, 219, 128, 0.98), rgba(139, 92, 246, 0.82), rgba(34, 211, 238, 0.42)) border-box;
color: #fff;
box-shadow:
0 0 0 1px rgba(246, 196, 83, 0.18),
0 0 18px rgba(139, 92, 246, 0.26),
0 0 24px rgba(246, 196, 83, 0.14),
inset 0 1px 0 rgba(255, 255, 255, 0.2),
inset 0 -2px 0 rgba(246, 196, 83, 0.24);
}
@mixin icon-button-primary-hover-icon {
background-color: #fff;
filter: drop-shadow(0 0 6px rgba(246, 196, 83, 0.3));
}
@mixin icon-button-ghost {
border-color: transparent;
background: transparent;
color: var(--color-text-muted);
box-shadow: none;
}
@mixin icon-button-danger {
border-color: rgba(251, 113, 133, 0.2);
color: var(--color-danger);
}
@mixin icon-button-danger-hover {
border-color: rgba(251, 113, 133, 0.56);
background:
radial-gradient(circle at 100% 0, rgba(251, 113, 133, 0.22), transparent 42%) padding-box,
linear-gradient(135deg, rgba(96, 22, 45, 0.94), rgba(58, 16, 34, 0.96)) padding-box,
linear-gradient(135deg, rgba(251, 113, 133, 0.82), rgba(244, 114, 182, 0.42), rgba(196, 181, 253, 0.18)) border-box;
color: #fff;
box-shadow:
0 0 0 1px rgba(251, 113, 133, 0.12),
0 0 16px rgba(251, 113, 133, 0.16),
inset 0 1px 0 rgba(255, 255, 255, 0.08),
inset 0 -2px 0 rgba(251, 113, 133, 0.24);
}
@mixin icon-button-danger-hover-icon {
background-color: #fff;
filter: drop-shadow(0 0 6px rgba(251, 113, 133, 0.26));
}
@mixin icon-button-active {
@include mixins.temporary-toggle-active;
}
@mixin button-edge($edge: right) {
@if $edge == left {
border-radius: var(--radius-sm) 0 0 var(--radius-sm);
} @else if $edge == middle {
border-radius: 0;
} @else if $edge == top {
border-radius: var(--radius-sm) var(--radius-sm) 0 0;
} @else if $edge == center {
border-radius: 0;
} @else if $edge == bottom {
border-radius: 0 0 var(--radius-sm) var(--radius-sm);
} @else if $edge == top-left {
border-radius: var(--radius-sm) 0 0 0;
} @else if $edge == top-right {
border-radius: 0 var(--radius-sm) 0 0;
} @else if $edge == bottom-right {
border-radius: 0 0 var(--radius-sm) 0;
} @else if $edge == bottom-left {
border-radius: 0 0 0 var(--radius-sm);
} @else {
border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}
}
@mixin button-joined-border($edge: right) {
@if $edge == left {
border-right-color: transparent;
} @else if $edge == middle {
border-right-color: transparent;
border-left-color: transparent;
} @else if $edge == right {
border-left-color: transparent;
} @else if $edge == top {
border-bottom-color: transparent;
} @else if $edge == center {
border-top-color: transparent;
border-bottom-color: transparent;
} @else if $edge == bottom {
border-top-color: transparent;
} @else if $edge == top-left {
border-right-color: transparent;
border-bottom-color: transparent;
} @else if $edge == top-right {
border-left-color: transparent;
border-bottom-color: transparent;
} @else if $edge == bottom-right {
border-left-color: transparent;
border-top-color: transparent;
} @else if $edge == bottom-left {
border-right-color: transparent;
border-top-color: transparent;
}
}
@mixin button-borderless {
border-color: transparent;
}
@mixin icon-button-edge($edge: right) {
@include button-edge($edge);
}
@mixin icon-button-panel-toggle {
background: rgba(39, 18, 69, 0.86);
color: var(--color-text-primary);
}
@mixin icon-button-panel-toggle-hover {
border-color: rgba(246, 196, 83, 0.44);
background: rgba(56, 28, 92, 0.94);
color: var(--color-accent-gold);
}
@mixin button-split($position: start, $axis: horizontal) {
@if $axis == vertical {
@if $position == start {
@include button-edge(top);
} @else {
@include button-edge(bottom);
border-top-color: transparent;
}
} @else {
@if $position == start {
@include button-edge(left);
} @else {
@include button-edge(right);
border-left-color: transparent;
}
}
}
@mixin toolbar-button($size: sm) {
@include icon-button($size);
display: inline-grid;
place-items: center;
font-size: var(--font-size-sm);
font-weight: 900;
box-shadow: none;
}
@mixin toolbar-button-icon($size: sm) {
@include icon-button-icon($size);
}
@mixin toolbar-button-hover {
@include icon-button-hover;
}
@mixin toolbar-button-active {
@include icon-button-active;
}

View file

@ -0,0 +1,90 @@
// Rôle : regroupe les mixins de cases à cocher.
@mixin checkbox-control($size: md) {
$control-size: 20px;
$radius: 3px;
@if $size == xs {
$control-size: 14px;
} @else if $size == sm {
$control-size: 18px;
}
appearance: none;
-webkit-appearance: none;
display: inline-grid;
width: $control-size;
min-width: $control-size;
max-width: $control-size;
inline-size: $control-size;
min-inline-size: $control-size;
max-inline-size: $control-size;
aspect-ratio: 1;
height: $control-size;
min-height: $control-size;
max-height: $control-size;
block-size: $control-size;
min-block-size: $control-size;
max-block-size: $control-size;
place-content: center;
margin: 0;
padding: 0;
border: 1px solid transparent;
border-radius: $radius;
line-height: 0;
background:
linear-gradient(135deg, rgba(27, 34, 66, 0.92), rgba(16, 20, 44, 0.94)) padding-box,
linear-gradient(135deg, rgba(246, 196, 83, 0.5), rgba(139, 92, 246, 0.44)) border-box;
box-shadow:
inset 0 0 0 1px rgba(255, 255, 255, 0.06),
0 0 0 1px rgba(5, 7, 17, 0.42);
cursor: pointer;
}
@mixin checkbox-check($size: md) {
$check-size: 11px;
@if $size == xs {
$check-size: 8px;
} @else if $size == sm {
$check-size: 10px;
}
content: "";
width: $check-size;
height: $check-size;
background: #fff;
transform: scale(0);
transition: transform var(--duration-fast) var(--ease-standard);
clip-path: polygon(14% 52%, 0 66%, 38% 100%, 100% 18%, 84% 5%, 34% 68%);
}
@mixin checkbox-hover {
border-color: rgba(246, 196, 83, 0.6);
box-shadow:
inset 0 0 0 1px rgba(255, 255, 255, 0.04),
0 0 14px rgba(246, 196, 83, 0.14);
}
@mixin checkbox-checked {
border-color: rgba(246, 196, 83, 0.88);
background:
linear-gradient(135deg, rgba(246, 196, 83, 0.96), rgba(139, 92, 246, 0.86)) padding-box,
linear-gradient(135deg, var(--color-accent-gold), rgba(196, 181, 253, 0.88)) border-box;
box-shadow:
inset 0 0 0 1px rgba(255, 255, 255, 0.12),
0 0 16px rgba(246, 196, 83, 0.2);
}
@mixin checkbox-checked-check {
transform: scale(1);
}
@mixin checkbox-disabled {
border-color: rgba(165, 180, 252, 0.08);
background:
linear-gradient(135deg, rgba(148, 163, 184, 0.08), rgba(51, 65, 85, 0.12)) padding-box,
linear-gradient(135deg, rgba(148, 163, 184, 0.16), rgba(99, 102, 241, 0.08)) border-box;
box-shadow: none;
cursor: not-allowed;
opacity: 0.48;
}

View file

@ -0,0 +1,40 @@
// Rôle : regroupe les mixins de surfaces événement calendrier.
@mixin event-surface-button {
display: grid;
width: 100%;
height: 100%;
min-width: 0;
min-height: 0;
box-sizing: border-box;
align-content: start;
padding: 5px 7px;
border: 0;
border-radius: 0;
background: transparent;
color: white;
cursor: pointer;
text-align: left;
}
@mixin event-surface-contrast-default {
color: white;
span {
color: rgba(255, 255, 255, 0.86);
opacity: 1;
}
}
@mixin event-surface-contrast-dark {
color: rgba(11, 14, 27, 0.92);
span {
color: rgba(11, 14, 27, 0.76);
opacity: 1;
}
}
@mixin event-surface-button-hover {
background: rgba(0, 0, 0, 0.14);
box-shadow: none;
}

View file

@ -0,0 +1,453 @@
// Rôle : regroupe les mixins de champs texte, select, textarea et champs inline.
@mixin select-control($size: md) {
$height: 44px;
$padding-right: 40px;
$padding-left: 14px;
$border-alpha: 0.12;
$chevron-offset: 14px;
@if $size == sm {
$height: 36px;
$padding-right: 34px;
$padding-left: 12px;
$border-alpha: 0.14;
$chevron-offset: 10px;
} @else if $size == xs {
$height: 32px;
$padding-right: 30px;
$padding-left: 10px;
$border-alpha: 0.14;
$chevron-offset: 9px;
}
min-height: $height;
overflow: hidden;
padding: 0 $padding-right 0 $padding-left;
border: 1px solid rgba(165, 180, 252, $border-alpha);
border-radius: var(--radius-md);
appearance: none;
-webkit-appearance: none;
color: var(--color-text-primary);
font: inherit;
text-overflow: ellipsis;
background-color: rgba(21, 26, 48, 0.86);
background-image:
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23c4b5fd' viewBox='-6.5 0 32 32'%3E%3Cpath d='M18.813 11.406l-7.906 9.906c-.75.906-1.906.906-2.625 0L.376 11.406c-.75-.938-.375-1.656.781-1.656h16.875c1.188 0 1.531.719.781 1.656z'/%3E%3C/svg%3E"),
linear-gradient(135deg, rgba(139, 92, 246, 0.04), rgba(31, 41, 78, 0.08)),
linear-gradient(rgba(21, 26, 48, 0.42), rgba(21, 26, 48, 0.42));
background-position:
calc(100% - #{$chevron-offset}) 50%,
0 0,
0 0;
background-size:
11px 11px,
auto,
auto;
background-repeat: no-repeat;
}
@mixin select-control-hover {
border-color: rgba(196, 181, 253, 0.22);
background-color: rgba(21, 26, 48, 0.92);
background-image:
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23f6c453' viewBox='-6.5 0 32 32'%3E%3Cpath d='M18.813 11.406l-7.906 9.906c-.75.906-1.906.906-2.625 0L.376 11.406c-.75-.938-.375-1.656.781-1.656h16.875c1.188 0 1.531.719.781 1.656z'/%3E%3C/svg%3E"),
linear-gradient(135deg, rgba(246, 196, 83, 0.06), rgba(139, 92, 246, 0.08)),
linear-gradient(rgba(21, 26, 48, 0.58), rgba(21, 26, 48, 0.58));
color: var(--color-text-primary);
}
@mixin select-trigger($size: md) {
$height: 44px;
$padding-right: 40px;
$padding-left: 12px;
$icon-size: 16px;
$font-size: inherit;
$border-alpha: 0.12;
$chevron-offset: 14px;
$chevron-size: 11px;
@if $size == sm {
$height: 36px;
$padding-right: 34px;
$padding-left: 10px;
$icon-size: 14px;
$font-size: var(--font-size-sm);
$border-alpha: 0.14;
$chevron-offset: 10px;
} @else if $size == xs {
$height: 32px;
$padding-right: 30px;
$padding-left: 8px;
$icon-size: 13px;
$font-size: var(--font-size-xs);
$border-alpha: 0.14;
$chevron-offset: 9px;
}
position: relative;
display: grid;
grid-template-columns: $icon-size minmax(0, 1fr);
align-items: center;
gap: 6px;
width: 100%;
min-height: $height;
padding: 0 $padding-right 0 $padding-left;
border: 1px solid rgba(165, 180, 252, $border-alpha);
border-radius: var(--radius-md);
background-color: rgba(21, 26, 48, 0.86);
background-image:
linear-gradient(135deg, rgba(139, 92, 246, 0.04), rgba(31, 41, 78, 0.08)),
linear-gradient(rgba(21, 26, 48, 0.42), rgba(21, 26, 48, 0.42));
background-position:
0 0,
0 0;
background-size:
auto,
auto;
background-repeat: no-repeat;
color: var(--color-text-primary);
font: inherit;
font-size: $font-size;
font-weight: 900;
font-variant-numeric: tabular-nums;
text-align: left;
transition:
border-color var(--duration-fast) var(--ease-standard),
background-color var(--duration-fast) var(--ease-standard),
color var(--duration-fast) var(--ease-standard),
box-shadow var(--duration-fast) var(--ease-standard);
&::after {
content: "";
position: absolute;
top: 50%;
right: $chevron-offset;
width: $chevron-size;
height: $chevron-size;
background-color: #c4b5fd;
mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-6.5 0 32 32'%3E%3Cpath d='M18.813 11.406l-7.906 9.906c-.75.906-1.906.906-2.625 0L.376 11.406c-.75-.938-.375-1.656.781-1.656h16.875c1.188 0 1.531.719.781 1.656z'/%3E%3C/svg%3E") center / contain no-repeat;
pointer-events: none;
transform: translateY(-50%);
transition: background-color var(--duration-fast) var(--ease-standard);
}
}
@mixin select-trigger-hover($size: md) {
border-color: rgba(196, 181, 253, 0.22);
background-color: rgba(21, 26, 48, 0.92);
background-image:
linear-gradient(135deg, rgba(246, 196, 83, 0.06), rgba(139, 92, 246, 0.08)),
linear-gradient(rgba(21, 26, 48, 0.58), rgba(21, 26, 48, 0.58));
background-position: 0 0, 0 0;
background-size: auto, auto;
background-repeat: no-repeat;
color: var(--color-text-primary);
&::after {
background-color: var(--color-accent-gold);
}
}
@mixin select-trigger-icon($size: md) {
$icon-size: 16px;
@if $size == sm {
$icon-size: 14px;
} @else if $size == xs {
$icon-size: 13px;
}
width: $icon-size;
height: $icon-size;
color: var(--color-text-secondary);
}
@mixin select-option {
background: #11182f;
color: var(--color-text-primary);
}
@mixin field-control($size: md) {
$height: 44px;
$padding: 0 14px;
$font-size: inherit;
@if $size == sm {
$height: 36px;
$padding: 0 10px;
$font-size: var(--font-size-sm);
} @else if $size == xs {
$height: 32px;
$padding: 0 8px;
$font-size: var(--font-size-xs);
}
box-sizing: border-box;
width: 100%;
min-width: 0;
min-height: $height;
padding: $padding;
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
background:
linear-gradient(135deg, rgba(139, 92, 246, 0.04), rgba(31, 41, 78, 0.08)),
rgba(21, 26, 48, 0.38);
color: var(--color-text-primary);
font: inherit;
font-size: $font-size;
transition:
border-color var(--duration-fast) var(--ease-standard),
background-color var(--duration-fast) var(--ease-standard),
color var(--duration-fast) var(--ease-standard),
box-shadow var(--duration-fast) var(--ease-standard);
}
@mixin field-textarea($size: md) {
$min-height: 108px;
$padding: 14px 20px 20px 14px;
@if $size == sm {
$min-height: 88px;
$padding: 12px 16px 16px 10px;
} @else if $size == xs {
$min-height: 72px;
$padding: 10px 14px 14px 8px;
}
min-height: $min-height;
padding: $padding;
overflow: auto;
resize: vertical;
scrollbar-gutter: stable;
}
@mixin field-textarea-ghost {
border-color: transparent;
background: transparent;
box-shadow: none;
color: inherit;
}
@mixin field-placeholder {
color: var(--color-text-muted);
opacity: 0.58;
}
@mixin field-hover {
border-color: rgba(196, 181, 253, 0.22);
background:
linear-gradient(135deg, rgba(246, 196, 83, 0.04), rgba(139, 92, 246, 0.08)),
rgba(21, 26, 48, 0.5);
}
@mixin field-focus {
border-color: var(--color-primary);
box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.16);
}
@mixin time-control($size: md) {
@include field-control($size);
padding-right: 8px;
color-scheme: dark;
font-variant-numeric: tabular-nums;
&::-webkit-calendar-picker-indicator {
width: 16px;
height: 16px;
margin-left: 4px;
border-radius: var(--radius-sm);
cursor: pointer;
filter: invert(77%) sepia(14%) saturate(810%) hue-rotate(209deg) brightness(99%) contrast(92%);
opacity: 0.82;
transition:
background-color var(--duration-fast) var(--ease-standard),
filter var(--duration-fast) var(--ease-standard),
opacity var(--duration-fast) var(--ease-standard);
}
&::-webkit-datetime-edit {
min-width: 0;
color: var(--color-text-primary);
}
&::-webkit-datetime-edit-fields-wrapper {
padding: 0;
}
&::-webkit-datetime-edit-hour-field,
&::-webkit-datetime-edit-minute-field,
&::-webkit-datetime-edit-ampm-field {
border-radius: 4px;
}
&::-webkit-datetime-edit-hour-field:focus,
&::-webkit-datetime-edit-minute-field:focus,
&::-webkit-datetime-edit-ampm-field:focus {
background: rgba(139, 92, 246, 0.28);
color: var(--color-text-primary);
}
&:hover::-webkit-calendar-picker-indicator,
&:focus::-webkit-calendar-picker-indicator {
background-color: rgba(246, 196, 83, 0.12);
filter: invert(80%) sepia(77%) saturate(455%) hue-rotate(346deg) brightness(101%) contrast(93%);
opacity: 1;
}
&:disabled::-webkit-calendar-picker-indicator {
cursor: not-allowed;
opacity: 0.42;
}
}
@mixin field-disabled {
border-color: rgba(165, 180, 252, 0.08);
background:
linear-gradient(135deg, rgba(148, 163, 184, 0.05), transparent 62%),
rgba(15, 23, 42, 0.42);
box-shadow: none;
color: rgba(203, 213, 225, 0.66);
cursor: not-allowed;
}
@mixin inline-field($size: md) {
$height: 30px;
$padding: 5px 8px;
$radius: var(--radius-md);
@if $size == sm {
$height: 28px;
$padding: 4px 7px;
$radius: var(--radius-sm);
} @else if $size == xs {
$height: 26px;
$padding: 3px 6px;
$radius: var(--radius-sm);
}
box-sizing: border-box;
width: 100%;
min-width: 0;
min-height: $height;
padding: $padding;
overflow: hidden;
border: 1px solid transparent;
border-radius: $radius;
background: transparent;
color: var(--color-text-primary);
font: inherit;
text-overflow: ellipsis;
white-space: nowrap;
transition:
border-color var(--duration-fast) var(--ease-standard),
background-color var(--duration-fast) var(--ease-standard),
color var(--duration-fast) var(--ease-standard),
box-shadow var(--duration-fast) var(--ease-standard);
}
@mixin inline-field-hover {
border-color: rgba(246, 196, 83, 0.34);
background: rgba(21, 26, 48, 0.42);
}
@mixin inline-textarea {
box-sizing: border-box;
width: 100%;
min-width: 0;
border: 0;
background: transparent;
color: var(--color-text-primary);
font: inherit;
resize: vertical;
}
@mixin table-header-field {
width: 100%;
padding: 0 8px;
border-top: 0;
border-left: 0;
border-radius: 0;
text-align: center;
}
@mixin table-header-field-focus {
z-index: 5;
border-color: rgba(246, 196, 83, 0.38);
background: rgba(21, 26, 48, 0.8);
color: var(--color-text-primary);
box-shadow: inset 0 0 0 1px rgba(246, 196, 83, 0.55), 0 0 0 2px rgba(139, 92, 246, 0.18);
outline: 0;
}
@mixin table-cell-field {
width: 100%;
min-width: 0;
min-height: 34px;
padding: 6px 8px;
border: 0;
border-right: 1px solid rgba(165, 180, 252, 0.08);
border-bottom: 1px solid rgba(165, 180, 252, 0.08);
border-radius: 0;
background: rgba(16, 20, 38, 0.34);
color: var(--color-text-primary);
caret-color: transparent;
font-size: var(--font-size-sm);
font-variant-numeric: tabular-nums;
}
@mixin table-cell-field-focus {
position: relative;
z-index: 4;
border-color: rgba(34, 211, 238, 0.42);
background:
linear-gradient(135deg, rgba(34, 211, 238, 0.08), rgba(139, 92, 246, 0.06)),
rgba(21, 26, 48, 0.58);
box-shadow: inset 0 0 0 1px rgba(34, 211, 238, 0.58);
outline: 0;
}
@mixin table-cell-field-editing-focus {
border-color: rgba(246, 196, 83, 0.38);
background: rgba(21, 26, 48, 0.72);
caret-color: auto;
box-shadow: inset 0 0 0 1px rgba(246, 196, 83, 0.55), 0 0 0 2px rgba(139, 92, 246, 0.18);
}
@mixin time-parts-control($size: md) {
$height: 44px;
$part-height: 42px;
$column-min: 34px;
@if $size == sm {
$height: 38px;
$part-height: 36px;
$column-min: 22px;
}
display: grid;
grid-template-columns: minmax($column-min, 1fr) 4px minmax($column-min, 1fr) 4px minmax($column-min, 1fr);
align-items: center;
min-height: $height;
overflow: hidden;
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
background: rgba(15, 23, 42, 0.64);
input {
width: auto;
min-width: 0;
min-height: $part-height;
padding: 0;
border: 0;
border-radius: 0;
background: transparent;
text-align: center;
box-shadow: none;
}
}
@mixin time-parts-focus {
border-color: var(--color-primary);
box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.16);
}

View file

@ -0,0 +1,254 @@
// Rôle : regroupe les mixins de menus compacts, swatches et pickers.
@use "buttons";
@use "fields";
@mixin date-picker-button($size: md) {
$height: 22px;
$padding: 0;
$font-size: 11px;
@if $size == header {
$height: 24px;
$padding: 0 6px;
$font-size: 10px;
} @else if $size == weekday {
$height: 26px;
$padding: 0 3px;
$font-size: 10px;
}
display: grid;
min-width: 0;
min-height: $height;
place-items: center;
padding: $padding;
overflow: hidden;
border: 1px solid transparent;
border-radius: var(--radius-sm);
background: rgba(16, 20, 38, 0.58);
color: var(--color-text-secondary);
font-size: $font-size;
font-weight: 800;
font-variant-numeric: tabular-nums;
text-overflow: ellipsis;
white-space: nowrap;
}
@mixin date-picker-button-hover {
border-color: rgba(246, 196, 83, 0.58);
background: rgba(139, 92, 246, 0.3);
color: var(--color-text-primary);
box-shadow: none;
}
@mixin date-picker-trigger {
@include fields.select-trigger(sm);
}
@mixin date-picker-trigger-hover {
@include fields.select-trigger-hover;
}
@mixin date-picker-trigger-icon {
@include fields.select-trigger-icon(sm);
}
@mixin date-picker-trigger-chevron {
display: none;
}
@mixin compact-menu-button($size: md) {
$button-size: 42px;
$icon-size: 26px;
@if $size == sm {
$button-size: 34px;
$icon-size: 21px;
}
@include buttons.icon-button;
width: $button-size;
min-width: $button-size;
height: $button-size;
min-height: $button-size;
img,
.ui-icon {
width: $icon-size;
height: $icon-size;
}
}
@mixin compact-menu-button-hover {
@include buttons.icon-button-hover;
}
@mixin floating-control-menu($columns: null, $item-size: 34px) {
display: grid;
gap: 6px;
padding: 8px;
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
background: rgba(10, 13, 28, 0.99);
box-shadow: var(--shadow-lg);
@if $columns {
grid-template-columns: repeat($columns, $item-size);
}
}
@mixin color-swatch($size: 34px) {
@include buttons.icon-button(sm);
width: $size;
min-width: $size;
min-height: $size;
padding: 0;
box-shadow: none;
&::before {
content: "";
width: max(12px, $size - 16px);
height: max(12px, $size - 16px);
border: 1px solid rgba(245, 247, 255, 0.22);
border-radius: 50%;
background: var(--swatch-color, var(--goal-tree-swatch-color, var(--color-accent-gold)));
box-shadow: inset 0 0 0 2px rgba(5, 7, 17, 0.36);
}
}
@mixin color-swatch-rainbow($size: 34px) {
@include color-swatch($size);
&::before {
width: max(14px, $size - 14px);
height: max(14px, $size - 14px);
border-color: rgba(245, 247, 255, 0.28);
background: conic-gradient(
from 20deg,
#f6c453,
#22d3ee,
#8b5cf6,
#d946ef,
#f5f7ff,
#f6c453
);
box-shadow:
inset 0 0 0 3px rgba(5, 7, 17, 0.34),
0 0 10px rgba(139, 92, 246, 0.16);
}
}
@mixin color-swatch-active {
@include buttons.icon-button-active;
}
@mixin large-icon-picker-trigger {
display: grid;
width: 100px;
min-width: 100px;
min-height: 100px;
place-items: center;
padding: 0;
border: 1px solid var(--color-primary-border);
border-radius: var(--radius-md);
background:
radial-gradient(circle at 50% 35%, rgba(246, 196, 83, 0.18), transparent 44%),
rgba(21, 26, 48, 0.86);
color: var(--color-text-primary);
}
@mixin large-icon-picker-trigger-hover {
border-color: rgba(246, 196, 83, 0.42);
background:
radial-gradient(circle at 50% 35%, rgba(246, 196, 83, 0.24), transparent 44%),
rgba(31, 37, 68, 0.94);
box-shadow: 0 0 18px rgba(139, 92, 246, 0.18);
}
@mixin position-toggle {
position: relative;
display: inline-grid;
grid-template-columns: repeat(2, 32px);
width: 74px;
min-height: 38px;
align-items: center;
justify-items: center;
gap: 0;
padding: 3px 4px;
border: 1px solid rgba(165, 180, 252, 0.12);
border-radius: var(--radius-pill);
background: rgba(7, 10, 24, 0.32);
color: var(--color-text-secondary);
&::before {
content: "";
position: absolute;
top: 3px;
bottom: 3px;
left: 4px;
width: 30px;
border: 1px solid rgba(246, 196, 83, 0.3);
border-radius: 50%;
background:
linear-gradient(135deg, rgba(246, 196, 83, 0.1), rgba(139, 92, 246, 0.08)),
rgba(21, 26, 48, 0.58);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05);
transition: transform var(--duration-fast) var(--ease-standard);
}
&[data-position="right"]::before {
transform: translateX(32px);
}
span {
position: relative;
z-index: 1;
display: inline-grid;
width: 30px;
height: 30px;
place-items: center;
justify-self: center;
align-self: center;
border-radius: 50%;
}
.ui-icon {
width: 16px;
height: 16px;
}
}
@mixin position-toggle-hover {
border-color: rgba(196, 181, 253, 0.24);
color: var(--color-text-primary);
}
@mixin edge-toggle {
@include buttons.icon-button;
@include buttons.icon-button-panel-toggle;
@include buttons.button-edge(right);
}
@mixin edge-toggle-hover {
@include buttons.icon-button-panel-toggle-hover;
}
@mixin split-button-start {
@include buttons.button-split(start);
}
@mixin split-button-end {
justify-content: center;
padding: 0;
@include buttons.button-split(end);
}
@mixin dashed-action-button {
@include buttons.text-button;
@include buttons.text-button-dashed;
font-size: var(--font-size-sm);
}
@mixin dashed-action-button-hover {
@include buttons.text-button-dashed-hover;
}

View file

@ -0,0 +1,41 @@
// Rôle : regroupe les mixins de scrollbar et resize handle.
@mixin scrollbar-control {
scrollbar-color: rgb(88, 55, 174) transparent;
scrollbar-width: thin;
&::-webkit-scrollbar {
width: 6px;
height: 6px;
border-radius: 0;
background-color: transparent;
}
&::-webkit-scrollbar-track {
border-radius: 0;
background-color: transparent;
box-shadow: none;
}
&::-webkit-scrollbar-thumb {
border-radius: var(--radius-pill);
background: linear-gradient(180deg, rgb(88, 55, 174), rgb(48, 30, 118));
}
&::-webkit-scrollbar-thumb:hover {
background: linear-gradient(180deg, rgba(246, 196, 83, 0.9), rgb(88, 55, 174));
}
&::-webkit-scrollbar-corner {
background: transparent;
}
}
@mixin scrollbar-resizer {
&::-webkit-resizer {
background-color: transparent;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M4 10L10 4M7 10L10 7' fill='none' stroke='%23f6c453' stroke-width='1.5' stroke-linecap='round' opacity='.82'/%3E%3Cpath d='M2 10L10 2' fill='none' stroke='%23c4b5fd' stroke-width='1' stroke-linecap='round' opacity='.34'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: calc(50% - 2px) calc(50% - 2px);
background-size: 12px 12px;
}
}

View file

@ -0,0 +1,116 @@
// Rôle : regroupe les mixins de steppers numériques et reset de spinner.
@mixin quantity-stepper($size: md) {
$button-size: 28px;
$value-min: 52px;
$gap: 6px;
$font-size: var(--font-size-sm);
@if $size == sm {
$button-size: 18px;
$value-min: 34px;
$gap: 2px;
$font-size: 0.68rem;
} @else if $size == xs {
$button-size: 16px;
$value-min: 30px;
$gap: 2px;
$font-size: 0.64rem;
}
display: inline-grid;
grid-template-columns: $button-size minmax($value-min, auto) $button-size;
flex: 0 0 auto;
align-items: center;
gap: $gap;
color: var(--color-text-secondary);
font-size: $font-size;
font-weight: 800;
white-space: nowrap;
}
@mixin quantity-stepper-button($size: md) {
$button-size: 28px;
@if $size == sm {
$button-size: 18px;
} @else if $size == xs {
$button-size: 16px;
}
display: inline-grid;
width: $button-size;
min-width: $button-size;
height: $button-size;
min-height: $button-size;
place-items: center;
padding: 0;
border: 1px solid rgba(165, 180, 252, 0.12);
border-radius: var(--radius-md);
background: rgba(21, 26, 48, 0.88);
color: var(--color-text-secondary);
line-height: 1;
}
@mixin quantity-stepper-button-hover {
border-color: rgba(196, 181, 253, 0.32);
background:
linear-gradient(135deg, rgba(31, 37, 68, 0.94), rgba(18, 22, 44, 0.96)) padding-box,
linear-gradient(135deg, rgba(139, 92, 246, 0.3), rgba(196, 181, 253, 0.2)) border-box;
color: var(--color-text-primary);
box-shadow:
0 0 10px rgba(139, 92, 246, 0.1),
inset 0 1px 0 rgba(255, 255, 255, 0.05);
}
@mixin quantity-stepper-button-icon($size: md) {
$icon-size: 16px;
@if $size == sm {
$icon-size: 10px;
} @else if $size == xs {
$icon-size: 9px;
}
width: $icon-size;
height: $icon-size;
flex: 0 0 $icon-size;
}
@mixin quantity-stepper-value {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 3px;
color: var(--color-text-secondary);
text-align: center;
}
@mixin quantity-stepper-input {
box-sizing: border-box;
width: max(18px, calc((var(--qty-current-digits, 1) * 0.72rem) + 8px));
min-height: 28px;
padding: 0 4px;
border: 1px solid transparent;
border-radius: var(--radius-sm);
background: transparent;
color: var(--color-text-primary);
font: inherit;
text-align: right;
-moz-appearance: textfield;
}
@mixin quantity-stepper-input-hover {
border-color: rgba(246, 196, 83, 0.34);
background: rgba(21, 26, 48, 0.42);
}
@mixin number-spinner-reset {
-moz-appearance: textfield;
&::-webkit-outer-spin-button,
&::-webkit-inner-spin-button {
margin: 0;
appearance: none;
-webkit-appearance: none;
}
}

View file

@ -0,0 +1,275 @@
// Rôle : regroupe les mixins de switchs, radio groups et toggles composés.
@use "../../mixins";
@use "buttons";
@use "fields";
@use "steppers";
@mixin switch-control($size: md) {
$icon-size: 16px;
$track-width: 34px;
$track-height: 18px;
$thumb-size: 12px;
$thumb-left: 3px;
$active-left: 17px;
$height: 34px;
$gap: 8px;
$padding: 0 6px 0 10px;
$radius: var(--radius-pill);
$font-size: var(--font-size-sm);
@if $size == lg {
$track-width: 30px;
$track-height: 16px;
$thumb-size: 10px;
$active-left: 15px;
$height: 40px;
$gap: 7px;
$padding: 0 7px 0 10px;
} @else if $size == sm {
$icon-size: 13px;
$track-width: 24px;
$track-height: 14px;
$thumb-size: 8px;
$thumb-left: 2px;
$active-left: 12px;
$height: 28px;
$gap: 5px;
$padding: 0 5px 0 8px;
$font-size: var(--font-size-xs);
} @else if $size == xs {
$icon-size: 13px;
$track-width: 18px;
$track-height: 12px;
$thumb-size: 8px;
$thumb-left: 2px;
$active-left: 7px;
$height: 26px;
$gap: 3px;
$padding: 0 4px;
$radius: var(--radius-sm);
$font-size: var(--font-size-xs);
}
--nds-switch-icon-size: #{$icon-size};
--nds-switch-track-width: #{$track-width};
--nds-switch-track-height: #{$track-height};
--nds-switch-thumb-size: #{$thumb-size};
--nds-switch-thumb-left: #{$thumb-left};
--nds-switch-active-left: #{$active-left};
display: inline-grid;
grid-template-columns: $icon-size $track-width;
width: fit-content;
min-height: $height;
align-items: center;
gap: $gap;
padding: $padding;
border: 1px solid rgba(165, 180, 252, 0.12);
border-radius: $radius;
background: rgba(5, 7, 17, 0.24);
color: var(--color-text-secondary);
font-size: $font-size;
font-weight: 800;
}
@mixin switch-icon {
width: var(--nds-switch-icon-size);
height: var(--nds-switch-icon-size);
}
@mixin switch-track {
position: relative;
display: block;
width: var(--nds-switch-track-width);
height: var(--nds-switch-track-height);
border: 1px solid rgba(165, 180, 252, 0.18);
border-radius: var(--radius-pill);
background: rgba(7, 10, 24, 0.72);
}
@mixin switch-thumb {
content: "";
position: absolute;
top: 50%;
left: var(--nds-switch-thumb-left);
width: var(--nds-switch-thumb-size);
height: var(--nds-switch-thumb-size);
border-radius: 50%;
background: var(--color-text-muted);
transform: translateY(-50%);
transition:
left var(--duration-fast) var(--ease-standard),
background-color var(--duration-fast) var(--ease-standard),
box-shadow var(--duration-fast) var(--ease-standard);
}
@mixin switch-hover {
@include buttons.icon-button-hover;
}
@mixin switch-active {
@include mixins.temporary-toggle-active;
}
@mixin switch-active-track {
border-color: rgba(246, 196, 83, 0.36);
background: rgba(246, 196, 83, 0.12);
}
@mixin switch-active-thumb {
left: var(--nds-switch-active-left);
background: var(--color-accent-gold);
box-shadow: 0 0 10px rgba(246, 196, 83, 0.28);
}
@mixin native-switch-label {
display: inline-flex;
align-items: center;
gap: 8px;
min-width: 0;
color: var(--color-text-secondary);
font-size: var(--font-size-xs);
font-weight: 900;
cursor: pointer;
}
@mixin native-switch-input {
position: absolute;
opacity: 0;
pointer-events: none;
}
@mixin radio-button-group-surface($size: md) {
$column-min: 36px;
$gap: 4px;
$padding: 4px;
$radius: var(--radius-md);
$background: rgba(5, 7, 17, 0.38);
@if $size == sm {
$column-min: 30px;
$gap: 3px;
$padding: 3px;
} @else if $size == xs {
$column-min: 24px;
$gap: 0;
$padding: 2px;
$radius: var(--radius-sm);
$background: rgba(5, 7, 17, 0.26);
}
--nds-radio-button-group-column-min: #{$column-min};
gap: $gap;
max-width: 100%;
padding: $padding;
border: 1px solid rgba(165, 180, 252, 0.12);
border-radius: $radius;
background: $background;
}
@mixin radio-button-group($size: md) {
@include radio-button-group-surface($size);
display: inline-grid;
grid-auto-flow: column;
grid-auto-columns: minmax(var(--nds-radio-button-group-column-min), 1fr);
}
@mixin radio-button-group-option($size: md) {
$height: 34px;
$padding: 0 10px;
$radius: calc(var(--radius-md) - 2px);
$font-size: var(--font-size-sm);
$icon-size: 16px;
@if $size == sm {
$height: 28px;
$padding: 0;
$font-size: var(--font-size-xs);
$icon-size: 19px;
} @else if $size == xs {
$height: 26px;
$padding: 0;
$radius: var(--radius-sm);
$font-size: var(--font-size-xs);
$icon-size: 13px;
}
--nds-radio-button-group-option-icon-size: #{$icon-size};
display: inline-flex;
min-width: 0;
min-height: $height;
align-items: center;
justify-content: center;
gap: 8px;
padding: $padding;
border: 1px solid transparent;
border-radius: $radius;
background: transparent;
color: var(--color-text-secondary);
font-size: $font-size;
font-weight: 900;
> .ui-icon {
width: var(--nds-radio-button-group-option-icon-size);
height: var(--nds-radio-button-group-option-icon-size);
min-width: var(--nds-radio-button-group-option-icon-size);
min-height: var(--nds-radio-button-group-option-icon-size);
flex: 0 0 var(--nds-radio-button-group-option-icon-size);
}
}
@mixin radio-button-group-option-compact-overflow {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
@mixin radio-button-group-option-hover {
border-color: rgba(196, 181, 253, 0.22);
background: rgba(21, 26, 48, 0.5);
color: var(--color-text-primary);
box-shadow: none;
}
@mixin radio-button-group-option-active {
@include mixins.temporary-toggle-active;
}
@mixin radio-button-group-option-icon($size: md) {
$icon-size: 16px;
@if $size == sm {
$icon-size: 19px;
} @else if $size == xs {
$icon-size: 13px;
}
--nds-radio-button-group-option-icon-size: #{$icon-size};
width: var(--nds-radio-button-group-option-icon-size);
height: var(--nds-radio-button-group-option-icon-size);
min-width: var(--nds-radio-button-group-option-icon-size);
min-height: var(--nds-radio-button-group-option-icon-size);
flex: 0 0 var(--nds-radio-button-group-option-icon-size);
}
@mixin compound-toggle-field {
@include radio-button-group(xs);
align-items: center;
grid-auto-columns: max-content;
}
@mixin compound-toggle-field-option {
@include radio-button-group-option(xs);
min-width: 50px;
}
@mixin compound-toggle-field-input {
@include fields.field-control(xs);
@include steppers.number-spinner-reset;
width: 34px;
min-height: 26px;
padding: 0 4px;
border-color: transparent;
border-radius: var(--radius-sm);
background: transparent;
text-align: center;
}