@custom-variant dark (&:is(.dark *));

@layer base {
    * {
        @apply border-border outline-ring/50;
    }
    html {
        @apply font-sans;
        * {
            @apply touch-manipulation selection:bg-primary selection:text-primary-foreground;
        }
    }
    body {
        @apply font-sans bg-background text-foreground;
    }
    /* Chrome need this to have dark scrollbars on dark mode */
    .dark {
        color-scheme: dark;
    }
}

:root {
    --background: oklch(1 0 0);
    --foreground: oklch(0.141 0.005 285.823);
    --card: oklch(1 0 0);
    --card-foreground: oklch(0.141 0.005 285.823);
    --popover: oklch(1 0 0);
    --popover-foreground: oklch(0.141 0.005 285.823);
    --primary: oklch(0.21 0.006 285.885);
    --primary-foreground: oklch(0.985 0 0);
    --secondary: oklch(0.967 0.001 286.375);
    --secondary-foreground: oklch(0.21 0.006 285.885);
    --muted: oklch(0.967 0.001 286.375);
    --muted-foreground: oklch(0.552 0.016 285.938);
    --accent: oklch(0.967 0.001 286.375);
    --accent-foreground: oklch(0.21 0.006 285.885);
    --destructive: oklch(0.577 0.245 27.325);
    --border: oklch(0.92 0.004 286.32);
    --input: oklch(0.92 0.004 286.32);
    --ring: oklch(0.705 0.015 286.067);
    --chart-1: oklch(0.646 0.222 41.116);
    --chart-2: oklch(0.6 0.118 184.704);
    --chart-3: oklch(0.398 0.07 227.392);
    --chart-4: oklch(0.828 0.189 84.429);
    --chart-5: oklch(0.769 0.188 70.08);
    --radius: 0.625rem;
    --sidebar: oklch(0.985 0 0);
    --sidebar-foreground: oklch(0.141 0.005 285.823);
    --sidebar-primary: oklch(0.21 0.006 285.885);
    --sidebar-primary-foreground: oklch(0.985 0 0);
    --sidebar-accent: oklch(0.967 0.001 286.375);
    --sidebar-accent-foreground: oklch(0.21 0.006 285.885);
    --sidebar-border: oklch(0.92 0.004 286.32);
    --sidebar-ring: oklch(0.705 0.015 286.067);

    --font-sans:
        -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", Helvetica,
        sans-serif;
    --font-serif:
        ui-serif, "New York", "Georgia Pro", Georgia, "Linux Libertine",
        "DejaVu Serif", serif;
    --font-mono:
        ui-monospace, "SF Mono", "Cascadia Code", "Cascadia Mono",
        "Segoe UI Mono", "Roboto Mono", "Ubuntu Mono", Menlo, Consolas, Monaco,
        monospace;

    --snippet-foreground: var(--foreground);
    --snippet-keyword: oklch(55% 0.25 300);
    --snippet-builtin: oklch(55% 0.2 20);
    --snippet-function: oklab(55% -0 -0.2);
    --snippet-string: oklch(40% 0.12 140);
    --snippet-symbol: oklch(50% 0.1 67);
    --snippet-regex: oklch(72% 0.17 340);
    --snippet-operator: oklch(70% 0.14 235);
    --snippet-constant: oklch(70% 0.2 42);
    --snippet-comment: oklch(40% 0 16);
    --snippet-cdata: oklch(60% 0.09 201);
    --snippet-builtin: oklch(55% 0.2 20);
    --snippet-inserted: oklch(40% 0.12 140);
}

.dark {
    --background: oklch(0.141 0.005 285.823);
    --foreground: oklch(0.985 0 0);
    --card: oklch(0.21 0.006 285.885);
    --card-foreground: oklch(0.985 0 0);
    --popover: oklch(0.21 0.006 285.885);
    --popover-foreground: oklch(0.985 0 0);
    --primary: oklch(0.92 0.004 286.32);
    --primary-foreground: oklch(0.21 0.006 285.885);
    --secondary: oklch(0.274 0.006 286.033);
    --secondary-foreground: oklch(0.985 0 0);
    --muted: oklch(0.274 0.006 286.033);
    --muted-foreground: oklch(0.705 0.015 286.067);
    --accent: oklch(0.274 0.006 286.033);
    --accent-foreground: oklch(0.985 0 0);
    --destructive: oklch(0.704 0.191 22.216);
    --border: oklch(1 0 0 / 10%);
    --input: oklch(1 0 0 / 15%);
    --ring: oklch(0.552 0.016 285.938);
    --chart-1: oklch(0.488 0.243 264.376);
    --chart-2: oklch(0.696 0.17 162.48);
    --chart-3: oklch(0.769 0.188 70.08);
    --chart-4: oklch(0.627 0.265 303.9);
    --chart-5: oklch(0.645 0.246 16.439);
    --sidebar: oklch(0.21 0.006 285.885);
    --sidebar-foreground: oklch(0.985 0 0);
    --sidebar-primary: oklch(0.488 0.243 264.376);
    --sidebar-primary-foreground: oklch(0.985 0 0);
    --sidebar-accent: oklch(0.274 0.006 286.033);
    --sidebar-accent-foreground: oklch(0.985 0 0);
    --sidebar-border: oklch(1 0 0 / 10%);
    --sidebar-ring: oklch(0.552 0.016 285.938);

    --snippet-foreground: var(--foreground);
    --snippet-keyword: oklch(78.715% 0.11877 304.749);
    --snippet-builtin: oklch(75.558% 0.12971 2.726);
    --snippet-function: oklch(76.643% 0.11144 259.903);
    --snippet-string: oklch(85.771% 0.10919 142.756);
    --snippet-symbol: oklch(91.93% 0.07032 86.528);
    --snippet-regex: oklch(87.003% 0.07521 336.235);
    --snippet-operator: oklch(84.672% 0.08339 210.315);
    --snippet-constant: oklch(82.367% 0.1014 52.601);
    --snippet-comment: oklch(68.652% 0.03744 274.725);
    --snippet-cdata: oklch(85.85% 0.07922 182.82);
    --snippet-deleted: oklch(75.558% 0.12971 2.726);
    --snippet-inserted: oklch(85.771% 0.10919 142.756);
}

@theme inline {
    --font-sans: var(--font-sans);
    --color-sidebar-ring: var(--sidebar-ring);
    --color-sidebar-border: var(--sidebar-border);
    --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
    --color-sidebar-accent: var(--sidebar-accent);
    --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
    --color-sidebar-primary: var(--sidebar-primary);
    --color-sidebar-foreground: var(--sidebar-foreground);
    --color-sidebar: var(--sidebar);
    --color-chart-5: var(--chart-5);
    --color-chart-4: var(--chart-4);
    --color-chart-3: var(--chart-3);
    --color-chart-2: var(--chart-2);
    --color-chart-1: var(--chart-1);
    --color-ring: var(--ring);
    --color-input: var(--input);
    --color-border: var(--border);
    --color-destructive: var(--destructive);
    --color-accent-foreground: var(--accent-foreground);
    --color-accent: var(--accent);
    --color-muted-foreground: var(--muted-foreground);
    --color-muted: var(--muted);
    --color-secondary-foreground: var(--secondary-foreground);
    --color-secondary: var(--secondary);
    --color-primary-foreground: var(--primary-foreground);
    --color-primary: var(--primary);
    --color-popover-foreground: var(--popover-foreground);
    --color-popover: var(--popover);
    --color-card-foreground: var(--card-foreground);
    --color-card: var(--card);
    --color-foreground: var(--foreground);
    --color-background: var(--background);
    --radius-sm: calc(var(--radius) - 4px);
    --radius-md: calc(var(--radius) - 2px);
    --radius-lg: var(--radius);
    --radius-xl: calc(var(--radius) + 4px);
    --radius-2xl: calc(var(--radius) + 8px);
    --radius-3xl: calc(var(--radius) + 12px);
    --radius-4xl: calc(var(--radius) + 16px);
}

@theme inline {
    --icon-indeterminate: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-minus-icon lucide-minus"><path d="M5 12h14"/></svg>');
    --icon-check: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-check-icon lucide-check"><path d="M20 6 9 17l-5-5"/></svg>');
    --icon-chevron-down: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-down-icon lucide-chevron-down"><path d="m6 9 6 6 6-6"/></svg>');
}

/* ========================================================================== */
/* accordion                                                                  */
/* ========================================================================== */

@utility accordion {
    &::details-content {
        block-size: 0;
        @apply block overflow-hidden opacity-0;
        transition-property: block-size, content-visibility, opacity;
        transition-duration: 0.2s;
        transition-behavior: allow-discrete;
    }
    [open]&::details-content {
        block-size: auto;
        block-size: calc-size(auto, size);
        @apply opacity-100;
    }
    &:not(.accordion--default):not(.accordion--menu) {
        @apply accordion--default;
    }
}

@utility accordion--default {
    & + details {
        @apply border-t border-border;
    }
}

@utility accordion--border {
    @apply px-4 first:rounded-t-md first:border-t last:border-b last:rounded-b-md border-x;
}

@utility accordion__summary {
    @apply flex items-center w-full justify-between gap-2;
    @apply focus-visible:border-ring focus-visible:ring-ring/50;
    @apply rounded-md py-4 text-sm font-medium transition-all;
    @apply outline-none hover:underline focus-visible:ring-[3px];
    @apply cursor-pointer select-none;

    &::marker {
        @apply content-none;
    }
    &::-webkit-details-marker {
        @apply hidden;
    }
    &::after {
        @apply bg-muted-foreground block size-4 content-[''] ms-auto;
        @apply mask-[image:var(--icon-chevron-down)] mask-size-[1rem] mask-center mask-no-repeat;
        @apply transition-transform;
    }
    [open] > &::after {
        @apply rotate-180;
    }
    & > svg {
        @apply h-5;
    }
}

@utility accordion__content {
    @apply pb-4;
}

/* ========================================================================== */
/* alert                                                                      */
/* ========================================================================== */

@utility alert {
    @apply relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current;

    &:not([class~="alert--destructive"]) {
        @apply alert--primary;
    }
}

@utility alert--primary {
    @apply bg-card text-card-foreground border-border;
}
@utility alert--destructive {
    @apply text-destructive bg-card [&>svg]:text-current border-border;
    > * {
        @apply text-destructive;
    }
}

@utility alert__title {
    @apply col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight;
}

@utility alert__content {
    @apply text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed;
}

/* ========================================================================== */
/* aspect-ratio                                                               */
/* ========================================================================== */

@utility aspect-ratio {
    @apply overflow-hidden bg-muted size-full object-cover rounded-md aspect-square;
}

/* ========================================================================== */
/* avatar                                                                     */
/* ========================================================================== */

@utility avatar {
    @apply relative flex shrink-0 rounded-full select-none;
    @apply bg-accent text-accent-foreground;

    &:not([class~="avatar--xs"]):not([class~="avatar--sm"]):not(
            [class~="avatar--lg"]
        ):not([class~="avatar--xl"]) {
        @apply avatar--md;
    }

    &:is(button, a) {
        @apply cursor-pointer hover:[&>img]:brightness-80;
    }
    &:focus-visible,
    &:has(:focus-visible) {
        @apply border-ring ring-ring/50 ring-[3px] outline-none;
    }
    &:disabled,
    &:has(input[disabled]) {
        @apply opacity-50 cursor-not-allowed;
    }
}

@utility avatar--xs {
    @apply size-6;
}
@utility avatar--sm {
    @apply size-8;
}
@utility avatar--md {
    @apply size-9;
}
@utility avatar--lg {
    @apply size-10;
}
@utility avatar--xl {
    @apply size-12;
}

@utility avatar--empty {
    & .avatar__img {
        @apply hidden;
    }
    & .avatar__fallback {
        @apply grid place-content-center;
    }
}

@utility avatar__img {
    @apply aspect-square overflow-hidden size-full rounded-[inherit] bg-accent;
}

@utility avatar__fallback {
    @apply hidden aspect-square rounded-[inherit] size-full;
}

/* ========================================================================== */
/* avatar-group                                                               */
/* ========================================================================== */

@utility avatar-group {
    @apply flex;
    & > .avatar {
        @apply ring-background ring-2;
    }

    &:not([class~="avatar-group--space-1"]):not(
            [class~="avatar-group--space-2"]
        ) {
        @apply avatar-group--stacked;
    }
}

@utility avatar-group--stacked {
    @apply -space-x-2;
}
@utility avatar-group--space-1 {
    @apply gap-1;
}
@utility avatar-group--space-2 {
    @apply gap-2;
}

/* ========================================================================== */
/* badge                                                                      */
/* ========================================================================== */

@utility badge {
    @apply h-5 gap-1 rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium transition-all [&>svg]:size-3! inline-flex items-center justify-center w-fit whitespace-nowrap shrink-0 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px];
    @apply empty:size-3 empty:p-0 empty:rounded-full;

    &:not([class~="badge--secondary"]):not([class~="badge--destructive"]):not(
            [class~="badge--outline"]
        ) {
        @apply badge--primary;
    }
}

@utility badge--primary {
    @apply bg-primary text-primary-foreground [a]:hover:bg-primary/80;
}
@utility badge--secondary {
    @apply bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80;
}
@utility badge--destructive {
    @apply bg-destructive/10 [a]:hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 text-destructive dark:bg-destructive/20;
}
@utility badge--outline {
    @apply border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground;
}

/* ========================================================================== */
/* breadcrumb                                                                 */
/* ========================================================================== */

@utility breadcrumb {
    @apply text-muted-foreground flex flex-wrap items-center gap-1.5 text-sm wrap-break-word sm:gap-2.5;
}

@utility breadcrumb__item {
    @apply inline-flex items-center gap-1.5 sm:gap-2.5 text-sm;

    &:not(:last-child)::after {
        @apply bg-muted-foreground block size-3.5 content-[''];
        @apply mask-(--icon-chevron-down) -rotate-90 mask-size-[0.875rem] mask-center mask-no-repeat;
    }
}

@utility breadcrumb__item__link {
    @apply text-muted-foreground cursor-pointer transition-colors;
    @apply inline-flex items-center gap-2;
    @apply hover:text-primary;
    @apply [&_svg]:size-4;

    &[aria-current="page"] {
        @apply text-primary cursor-default no-underline;
    }
}

/* ========================================================================== */
/* busy                                                                       */
/* ========================================================================== */

@utility busy {
    @apply relative size-full rounded-[inherit];
    @apply aria-busy:*:pointer-events-none;

    &[aria-busy="true"] {
        @apply cursor-wait;
    }

    &:not([class~="busy--opaque"]) {
        @apply busy--transparent;
    }
}

@utility busy--transparent {
    @apply aria-busy:[&>*:not(.Busy-indicator)]:opacity-30;
    @apply aria-busy:[&>*:not(.Busy-indicator)]:transition-opacity;
    @apply aria-busy:[&>*:not(.Busy-indicator)]:duration-1000;
}

@utility busy--opaque {
    @apply aria-busy:[&>*:not(.Busy-indicator)]:opacity-0;
}

@theme {
    --animate-fade-spin: spin 1s linear infinite, custom-fade 1s linear;
    @keyframes custom-fade {
        0% {
            opacity: 0;
        }
        30% {
            opacity: 0;
        }
        100% {
            opacity: 1;
        }
    }
}

@utility busy__indicator {
    @apply absolute top-1/2 start-1/2 z-30 hidden -translate-1/2;
    @apply animate-fade-spin transform rounded-full border-current border-t-transparent;

    [aria-busy="true"] & {
        display: inline-block;
    }
    [aria-busy="true"] .button & {
        @apply text-current;
        + * {
            opacity: 0;
        }
    }

    @apply busy__indicator--md busy__indicator--primary;
}

@utility busy__indicator--sm {
    @apply size-5 border-2;
}
@utility busy__indicator--md {
    @apply size-6 border-3;
}
@utility busy__indicator--lg {
    @apply size-8 border-4;
}

@utility busy__indicator--primary {
    @apply text-primary;
}
@utility busy__indicator--onprimary {
    @apply text-primary-foreground;
}

/* ========================================================================== */
/* button                                                                     */
/* ========================================================================== */

@utility button {
    @apply inline-flex shrink-0 items-center justify-center gap-2 font-medium whitespace-nowrap transition-all outline-none;
    @apply cursor-pointer select-none relative;
    svg {
        @apply pointer-events-none shrink-0 size-4;
    }
    &:focus-visible,
    &:has(:focus-visible) {
        @apply border-ring ring-ring/50 ring-[3px];
    }
    &[aria-invalid="true"] {
        @apply border-destructive ring-destructive/20 dark:ring-destructive/40;
    }
    &:disabled,
    &:has(input[disabled]) {
        @apply opacity-50 cursor-not-allowed;
    }
    &:not(.button-group--sm *):not(.button-group--lg *):not(
            [class~="button--sm"]
        ):not([class~="button--lg"]) {
        @apply button--md;
    }
    &:not([class~="button--outline"]):not([class~="button--destructive"]):not(
            [class~="button--secondary"]
        ):not([class~="button--ghost"]) {
        @apply button--primary;
    }

    input {
        @apply sr-only;
    }
}
@utility button--sm {
    @apply h-8 gap-1.5 rounded-md px-3 text-sm has-[>svg]:px-2.5;
}
@utility button--md {
    @apply h-9 rounded-md px-4 text-sm has-[>svg]:px-3;
}
@utility button--lg {
    @apply h-10 rounded-md px-6 text-sm has-[>svg]:px-4;
}
@utility button--icon {
    @apply px-0! aspect-square;
}
@utility button--primary {
    @apply bg-primary text-primary-foreground shadow-xs;
    &:not(:disabled):not(:has(input:disabled)) {
        @apply hover:bg-primary/90;
    }
}
@utility button--outline {
    @apply border border-border bg-background shadow-xs dark:bg-input/30 dark:border-input;
    &[aria-pressed="true"] {
        @apply bg-accent text-accent-foreground dark:bg-accent/50;
    }
    &:has(input[type="checkbox"].button__toggle),
    &:has(input[type="radio"].button__toggle) {
        @apply has-checked:bg-accent has-checked:text-accent-foreground;
        &:not(:disabled):not(:has(input:disabled)) {
            @apply has-checked:dark:hover:bg-accent;
        }
    }
    &:not(:disabled):not(:has(input:disabled)) {
        @apply hover:bg-accent dark:hover:bg-accent/50 hover:text-accent-foreground;
    }
}
@utility button--secondary {
    @apply bg-secondary text-secondary-foreground shadow-xs;
    &:not(:disabled):not(:has(input:disabled)) {
        @apply hover:bg-secondary/80;
    }
}
@utility button--ghost {
    &:has(input[type="checkbox"].button__toggle),
    &:has(input[type="radio"].button__toggle) {
        @apply has-checked:bg-accent has-checked:text-accent-foreground;
        &:not(:disabled):not(:has(input:disabled)) {
            @apply has-checked:dark:hover:bg-accent;
        }
    }
    &:not(:disabled):not(:has(input:disabled)) {
        @apply hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50;
    }
}
@utility button--destructive {
    @apply bg-destructive text-white shadow-xs;
    @apply focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60;
    &:not(:disabled):not(:has(input:disabled)) {
        @apply not-has-disabled:hover:bg-destructive/90;
    }
}
@utility button__toggle {
    @apply sr-only;
}
@utility button__swap {
    @apply sr-only;

    &:not(:checked) {
        & ~ .button__swap-off {
            @apply block;
        }
        & ~ .button__swap-on {
            @apply hidden;
        }
    }
    &:checked {
        & ~ .button__swap-off {
            @apply hidden;
        }
        & ~ .button__swap-on {
            @apply block;
        }
    }
}
@utility button__swap-on {
    @apply block;
}
@utility button__swap-off {
    @apply block;
}

/* ========================================================================== */
/* button-group                                                               */
/* ========================================================================== */

@utility button-group {
    @apply flex w-fit items-stretch *:focus-visible:z-10 *:focus-visible:relative;
    @apply [&>input]:flex-1;
    @apply has-[.button-group]:gap-2;

    &:not([class~="button-group--space-1"]):not(
            [class~="button-group--space-2"]
        ) {
        @apply button-group--space-0;
    }
}
@utility button-group--space-0 {
    .button {
        @apply not-first:border-s-0 not-first:rounded-s-none not-last:not-only-of-type:rounded-e-none;
    }
}
@utility button-group--space-1 {
    @apply gap-1;
}
@utility button-group--space-2 {
    @apply gap-2;
}

@utility button-group__separator {
    &:not([class~="button-group__separator--horizontal"]) {
        @apply button-group__separator--vertical;
    }
}
@utility button-group__separator--horizontal {
    @apply shrink-0 h-px bg-transparent relative self-stretch mx-px w-auto;
}
@utility button-group__separator--vertical {
    @apply shrink-0 w-px self-stretch bg-transparent relative my-px h-auto;
}

/* ========================================================================== */
/* card                                                                       */
/* ========================================================================== */

@utility card {
    @apply bg-card text-card-foreground flex flex-col gap-6 rounded-xl border border-border py-6 shadow-sm;
}

@utility card__header {
    @apply @container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6;
}

@utility card__title {
    @apply leading-none font-semibold;
}

@utility card__desc {
    @apply text-muted-foreground text-sm;
}

@utility card__content {
    @apply px-6;
}

@utility card__footer {
    @apply flex items-center px-6 [.border-t]:pt-6;
}

/* ========================================================================== */
/* checkbox                                                                   */
/* ========================================================================== */

@utility checkbox {
    @apply border-input dark:bg-input/30 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 appearance-none rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50;
    @apply cursor-pointer;

    &:checked,
    &:indeterminate {
        @apply bg-primary dark:bg-primary border-primary;
    }
    &:checked::after,
    &:indeterminate::after {
        @apply bg-primary-foreground block size-3.5 content-[''];
        @apply mask-size-[0.875rem] mask-center mask-no-repeat;
    }
    &:checked::after {
        @apply mask-[image:var(--icon-check)];
    }
    &:indeterminate::after {
        @apply mask-[image:var(--icon-indeterminate)];
    }
}

@utility checkbox--master {
    &:checked,
    &:indeterminate {
        @apply bg-accent dark:bg-accent border-accent;
    }
    &:checked::after,
    &:indeterminate::after {
        @apply bg-accent-foreground;
    }
}

/* ========================================================================== */
/* checkbox-group                                                             */
/* ========================================================================== */

@utility checkbox-group {
    @apply flex flex-col gap-3;
    @apply relative ps-6;
    &::before {
        @apply absolute top-0 bottom-0 start-1.75 z-10 block w-0.5 h-full content-[''] bg-border;
    }
}

/* ========================================================================== */
/* dialog                                                                     */
/* ========================================================================== */

@utility dialog {
    &:is([open], :popover-open) {
        @apply opacity-100;

        &::backdrop {
            @apply opacity-100;
        }
        > .dialog__content {
            @apply scale-100;
        }

        @starting-style {
            @apply opacity-0;

            &::backdrop {
                @apply opacity-0;
            }
            > .dialog__content {
                @apply scale-95;
            }
        }
    }
    &::backdrop {
        @apply bg-black/50 opacity-0 transition-all transition-discrete;
    }
}

@utility dialog__content {
    @apply bg-background text-foreground fixed top-1/2 start-1/2 z-50 max-h-[calc(100%-2rem)] w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 rounded-lg border border-border shadow-lg sm:max-w-[425px];
    @apply scale-95 transition-all;
}

@utility dialog__content__header {
    @apply flex flex-col gap-4 text-center sm:text-left p-4;
}

@utility dialog__content__title {
    @apply text-lg leading-none font-semibold;
}

@utility dialog__content__desc {
    @apply text-muted-foreground text-sm;
}

@utility dialog__content__main {
    @apply flex-1 p-4;
}
@utility dialog__content__main--wide {
    @apply p-0;
}
@utility dialog__content__main--scroll {
    @apply border-y border-border overflow-y-auto;
}

@utility dialog__content__footer {
    @apply rounded-b-[inherit] flex flex-col-reverse gap-2 sm:flex-row sm:justify-end p-4;
}

@utility dialog__content__cancel {
    @apply ring-offset-background focus:ring-ring absolute top-4 end-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus-visible:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4;
}

/* ========================================================================== */
/* diff                                                                       */
/* ========================================================================== */

@utility diff {
    @apply block relative size-full overflow-hidden;
    /* Must be updated with javascript */
    --slider-value: 50%;

    &:has(:focus-visible) .diff__line__thumb {
        @apply border-ring ring-ring/50 ring-[3px];
    }
}

@utility diff__line {
    @apply absolute top-0 start-[var(--slider-value)] w-0.5 h-full bg-background;
    @apply transform-gpu -translate-x-1/2 rtl:translate-x-1/2 pointer-events-none z-10 flex items-center justify-center;
}

@utility diff__line__thumb {
    @apply absolute top-1/2 start-1/2 size-7 -translate-1/2 rtl:translate-x-1/2 bg-background rounded-md flex items-center justify-center;
    @apply shadow-sm;
}

@utility diff__content {
    user-select: none;
    @apply absolute inset-0 size-full object-cover pointer-events-none block z-2;
    clip-path: inset(0 calc(100% - var(--slider-value)) 0 0);
    [dir="rtl"] &,
    html[dir="rtl"] & {
        clip-path: inset(0 0 0 calc(100% - var(--slider-value)));
    }

    & + & {
        z-index: 1;
        clip-path: none;
    }
}

@utility diff__range {
    @apply absolute inset-0 size-full m-0 p-0 opacity-0 z-20 appearance-none;
    @apply cursor-grab active:cursor-grabbing;
}

/* ========================================================================== */
/* field                                                                      */
/* ========================================================================== */

@utility field {
    &:not([class~="field--horizontal"]) {
        @apply flex w-full gap-3 flex-col *:w-full [&>.sr-only]:w-auto;
    }

    &:has(input[disabled]),
    &:has(select[disabled]),
    &:has(textarea[disabled]) {
        @apply cursor-not-allowed opacity-50;
    }
    &:has([aria-invalid="true"]) {
        @apply ring-destructive/20 dark:ring-destructive/40 border-destructive;
    }
    /* &:has(input[type="checkbox"]) {
        @apply cursor-pointer;
    } */
}

@utility field--horizontal {
    @apply flex flex-row gap-3 items-center;
}

@utility field__label {
    /* group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50 group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50 has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border [&>*]:data-[slot=field]:p-4 has-data-[state=checked]:bg-primary/5 has-data-[state=checked]:border-primary dark:has-data-[state=checked]:bg-primary/10; */
    @apply items-center text-sm font-medium select-none flex w-fit gap-2 leading-snug;
    @apply has-checked:border-primary has-checked:bg-primary/5 dark:has-checked:bg-primary/10;

    :has(input[disabled], select[disabled], textarea[disabled]) > & {
        @apply cursor-not-allowed opacity-50;
    }
    :has(input[required], select[required], textarea[required]) > & {
        @apply after:text-destructive;
        @apply after:content-['*'];
        @apply after:-m-1.5;
        @apply after:font-medium;
    }
}

@utility field__label--normal {
    @apply font-normal;
}

@utility field__desc {
    @apply text-muted-foreground text-sm leading-normal font-normal;
    @apply min-h-5 flex items-center gap-1;
    @apply [&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4;
    @apply [&>svg]:pointer-events-none [&>svg]:shrink-0 [&>svg:not([class*='size-'])]:size-4;
}

@utility field__error {
    @apply invisible;
    :has(
            input:invalid:user-invalid,
            select:invalid:user-invalid,
            textarea:invalid:user-invalid
        )
        > & {
        @apply visible;
    }
    :has(
            input[aria-invalid="true"],
            select[aria-invalid="true"],
            textarea[aria-invalid="true"]
        )
        > & {
        @apply visible;
    }
    @apply text-destructive text-sm leading-normal font-normal;
    @apply min-h-5 flex items-center gap-1;
    @apply [&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4;
    @apply [&>svg]:pointer-events-none [&>svg]:shrink-0 [&>svg:not([class*='size-'])]:size-4;
}

@utility field-group {
    @apply flex flex-col w-full gap-7;

    .field-group > & {
        @apply gap-4;
    }
    .checkbox-group > & {
        @apply gap-3;
    }
}

@utility field-group__horizontal {
    @apply flex-row flex-wrap;
    & > .field {
        @apply flex-1 basis-0 min-w-35;
    }
}

/* ========================================================================== */
/* fieldset                                                                   */
/* ========================================================================== */

@utility fieldset {
    @apply flex flex-col gap-4 has-[.checkbox-group]:gap-3 has-[.radio-group]:gap-3;

    /* Not correctly reset by tailwind preflight: */
    min-inline-size: 0;
    margin-inline: 0;
    padding-block: 0;
    padding-inline: 0;
}

@utility fieldset__legend {
    @apply mb-1.5 font-medium text-base;
}
@utility fieldset__legend--label {
    @apply text-sm;
}

@utility fieldset__desc {
    @apply text-muted-foreground text-sm leading-normal font-normal last:mt-0 nth-last-2:-mt-1 [&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4;
    @apply -mt-1.5;
}

/* ========================================================================== */
/* hgroup                                                                     */
/* ========================================================================== */

@utility hgroup {
    @apply scroll-mt-[calc(6*var(--spacing)+env(safe-area-inset-top))];

    &:has(h1) {
        @apply not-first:mt-12;
    }
    h1 {
        @apply scroll-m-20 text-4xl font-extrabold tracking-tight text-balance;
        @apply pb-4;
        @apply flex items-center gap-2;
    }
    &:has(h2) {
        @apply border-b border-border pb-2 not-first:mt-10;
    }
    h2 {
        @apply scroll-m-20 text-3xl font-semibold tracking-tight;
        @apply pb-2;
        @apply flex items-center gap-2;
    }
    &:has(h3) {
        @apply not-first:mt-8;
    }
    h3 {
        @apply scroll-m-20 text-2xl font-semibold tracking-tight;
        @apply pb-1.5;
        @apply flex items-center gap-2;
    }
    &:has(h4) {
        @apply not-first:mt-6;
    }
    h4 {
        @apply scroll-m-20 text-xl font-semibold tracking-tight;
        @apply pb-1;
        @apply flex items-center gap-2;
    }
    h1 + p {
        @apply text-muted-foreground leading-8;
    }
    h2 + p {
        @apply text-muted-foreground leading-7;
    }
    h3 + p {
        @apply text-muted-foreground leading-6;
    }
    h4 + p {
        @apply text-muted-foreground leading-4;
    }
}

/* ========================================================================== */
/* indicator                                                                  */
/* ========================================================================== */

@utility indicator {
    @apply absolute z-10 whitespace-nowrap;
    top: var(--indicator-t, 0);
    bottom: var(--indicator-b, auto);
    left: var(--indicator-s, auto);
    right: var(--indicator-e, 0);
    translate: var(--indicator-x, 35%) var(--indicator-y, -35%);

    @apply border border-transparent rounded-full grid place-items-center;
    /* color variants */
    @apply bg-destructive text-white;
    @apply before:bg-inherit;
    /* size variants */
    @apply text-xs h-5 min-w-5 px-0.5;
}
/* color variants */
@utility indicator--primary {
    @apply bg-primary text-primary-foreground;
    @apply before:bg-inherit;
}
@utility indicator--secondary {
    @apply bg-secondary text-secondary-foreground;
    @apply before:bg-inherit;
}
/* size variants */
@utility indicator--sm {
    @apply text-xs h-3 min-w-3 px-px;
}
@utility indicator--md {
    @apply text-sm h-5 min-w-5 px-0.5;
}
@utility indicator--lg {
    @apply h-7 min-w-7 px-1;
}
/* position variants */
@utility indicator--left {
    --indicator-s: 0;
    --indicator-e: auto;
    --indicator-x: -40%;
    --indicator-y: -50%;
    --indicator-t: 50%;
    --indicator-b: 50%;
}
@utility indicator--right {
    --indicator-s: auto;
    --indicator-e: 0;
    --indicator-x: 40%;
    --indicator-y: -50%;
    --indicator-t: 50%;
    --indicator-b: 50%;
}
@utility indicator--bottom {
    --indicator-t: auto;
    --indicator-b: 0;
    --indicator-y: 40%;
    --indicator-s: 50%;
    --indicator-e: 50%;
    --indicator-x: -50%;
}
@utility indicator--top {
    --indicator-t: 0;
    --indicator-b: auto;
    --indicator-y: -40%;
    --indicator-s: 50%;
    --indicator-e: 50%;
    --indicator-x: -50%;
}
@utility indicator--start {
    --indicator-s: 0;
    --indicator-e: auto;
    --indicator-x: -40%;
}
@utility indicator--end {
    --indicator-s: auto;
    --indicator-e: 0;
    --indicator-x: 40%;
}
@utility indicator--offset {
    &.indicator--left {
        --indicator-x: -140%;
    }
    &.indicator--right {
        --indicator-x: 140%;
    }
    &.indicator--top {
        --indicator-y: -140%;
    }
    &.indicator--bottom {
        --indicator-y: 140%;
    }
}
/* feature variants */
@utility indicator--ping {
    @apply relative rounded-full;
    @apply before:absolute before:-inset-1 before:rounded-full before:animate-ping;
}

/* ========================================================================== */
/* input                                                                      */
/* ========================================================================== */

@utility input {
    @apply file:text-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm;
    @apply placeholder:text-muted-foreground;
    @apply focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px];
    @apply aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive;
    @apply invalid:user-invalid:ring-destructive/20 dark:invalid:user-invalid:ring-destructive/40 invalid:user-invalid:border-destructive;

    &::-webkit-search-cancel-button {
        display: none;
    }

    &[type="file"],
    &[type="color"] {
        @apply cursor-pointer;
    }
}

@utility input-error {
    @apply text-destructive cursor-default;
    @apply min-h-5 text-sm leading-5;
    @apply peer-disabled:cursor-not-allowed peer-disabled:opacity-50;
    @apply peer-invalid/input:opacity-100 peer-invalid/input:cursor-auto;
}

/* ========================================================================== */
/* item                                                                       */
/* ========================================================================== */

@utility item {
    @apply flex items-center text-sm rounded-md transition-colors [a]:hover:bg-accent/50 [a]:transition-colors duration-100 flex-wrap outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] p-4 gap-2.5;
    & > svg {
        @apply h-5;
    }
}

/* ========================================================================== */
/* kbd                                                                        */
/* ========================================================================== */

@utility kbd {
    @apply bg-muted text-foreground pointer-events-none inline-flex h-5 w-fit min-w-5 items-center justify-center gap-1 rounded-sm px-1 font-sans text-xs font-medium select-none [&_svg:not([class*='size-'])]:size-3;

    /* TODO: tooltip integration */
    /* Tooltip > & {
        @apply bg-background/20 text-background dark:bg-background/10;
    } */
}
@utility kbd-group {
    @apply inline-flex items-center gap-1;
}

/* ========================================================================== */
/* label                                                                      */
/* ========================================================================== */

@utility label {
    @apply flex h-3.5 items-center gap-2 text-sm leading-none select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50;
    @apply has-[+input[aria-invalid=true],+select[aria-invalid=true],+textarea[aria-invalid=true]]:text-destructive;
    @apply has-disabled:cursor-not-allowed has-disabled:opacity-50;
    @apply has-[+input:disabled,+select:disabled,+textarea:disabled]:cursor-not-allowed;
    @apply has-[+input:disabled,+select:disabled,+textarea:disabled]:opacity-50;
    @apply has-[input[type=checkbox],input[type=radio]]:cursor-pointer;

    &:not([class~="label--normal"]) {
        @apply label--medium;
    }
}

@utility label--medium {
    @apply font-medium;
}
@utility label--normal {
    @apply font-normal;
}

@utility label--required {
    @apply after:text-destructive;
    @apply after:-ms-1;
    @apply after:content-['*'];
    @apply after:text-lg;
    @apply after:font-medium;
}

/* ========================================================================== */
/* layout                                                                     */
/* ========================================================================== */
@utility layout__main {
    @apply mx-auto max-w-3xl p-4 sm:px-6 lg:px-8;
}

/* ========================================================================== */
/* link                                                                       */
/* ========================================================================== */

@utility link {
    @apply text-primary font-medium;
    @apply underline underline-offset-4 inline-flex items-center gap-2;
    @apply [&_svg:not([class*='size-'])]:size-4;
    @apply cursor-pointer;
}

/* ========================================================================== */
/* hover-card                                                                 */
/* ========================================================================== */

@utility hover-card {
    @apply z-50 outline-none aria-hidden:hidden;
    @apply bg-popover text-popover-foreground z-50 rounded-md border border-border p-4 shadow-md;
    @apply transition-all opacity-100 scale-100;
    @starting-style {
        @apply opacity-0 scale-95;
    }
}

/* ========================================================================== */
/* progress                                                                   */
/* ========================================================================== */

@utility progress {
    @apply appearance-none bg-muted relative h-2 w-full overflow-hidden rounded-full;
    &::-webkit-progress-bar {
        @apply bg-muted;
    }
    &::-webkit-progress-value {
        @apply bg-primary transition-[width];
    }
    &::-moz-progress-bar {
        @apply bg-primary;
    }
    &::-ms-fill {
        @apply bg-primary;
    }
}

/* ========================================================================== */
/* radio-group                                                                */
/* ========================================================================== */

@utility radio-group {
    @apply flex flex-col gap-3;
}

@utility radio {
    @apply border-input text-primary dark:bg-input/30 relative aspect-square size-4 shrink-0 appearance-none rounded-full border shadow-xs transition-[color,box-shadow] outline-none;
    &:focus-visible {
        @apply border-ring ring-[3px] ring-ring/50;
    }
    &:disabled {
        @apply cursor-not-allowed opacity-50;
    }
    &[aria-invalid="true"] {
        @apply aria-invalid:ring-destructive/20 dark:ring-destructive/40 border-destructive;
    }
    &:checked:before {
        @apply bg-primary absolute top-1/2 start-1/2 size-2 -translate-x-1/2 -translate-y-1/2 rounded-full content-[''];
    }
}

/* ========================================================================== */
/* rating                                                                     */
/* ========================================================================== */

@utility rating-group {
    @apply flex flex-row items-center h-9;
}

@utility rating-group__output {
    @apply text-right text-muted-foreground align-middle;
}

@utility rating {
    @apply relative text-input cursor-pointer rounded-md px-1.5 transition-all;

    input {
        @apply sr-only;
    }

    & svg {
        @apply size-6 text-input pointer-events-none;
    }

    /* Keyboard Focus Indicator */
    /* We target the label when the internal input is focused via keyboard */
    &:has(input:focus-visible) {
        @apply outline-2 outline-offset-2 outline-primary rounded-sm;
    }

    /* Logic for coloring stars when checked */
    :not(:hover) & {
        &:has(input:checked),
        &:has(~ .rating input:checked) {
            & svg {
                @apply text-primary fill-primary;
            }
        }
    }

    /* Logic for coloring stars on hover */
    &:hover,
    &:has(~ .rating:hover) {
        & svg {
            @apply text-primary fill-primary;
        }
    }
}

/* ========================================================================== */
/* select                                                                     */
/* ========================================================================== */

@utility select {
    /* TODO: find better method to color arrow without modifying the svg directly */
    --icon-chevron-down-50: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="oklch(0.708 0 0 / 0.5)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-down-icon lucide-chevron-down"><path d="m6 9 6 6 6-6"/></svg>');

    @apply border-input selection:bg-primary selection:text-primary-foreground dark:bg-input/30 dark:hover:bg-input/50 h-9 w-full min-w-0 appearance-none rounded-md border bg-popover! text-popover-foreground scheme-light dark:scheme-dark px-3 py-2 pe-9 text-sm shadow-xs transition-[color,box-shadow] outline-none disabled:pointer-events-none disabled:cursor-not-allowed focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive;
    @apply bg-[image:var(--icon-chevron-down-50)] bg-size-[1rem] bg-position-[center_right_0.75rem] rtl:bg-position-[center_left_0.75rem] bg-no-repeat;
    @apply cursor-pointer;

    option {
        @apply bg-popover text-popover-foreground;
        @apply disabled:text-muted-foreground;
    }

    optgroup {
        @apply bg-popover text-popover-foreground;
        @apply disabled:text-muted-foreground;
    }

    &:has(option[value=""]:checked) {
        @apply text-muted-foreground;
    }
}

/* ========================================================================== */
/* separator                                                                  */
/* ========================================================================== */

@utility separator {
    @apply my-4 bg-border shrink-0;

    &:not([class~="separator--vertical"]) {
        @apply separator--horizontal;
    }
}

@utility separator--horizontal {
    @apply h-px w-full;
}
@utility separator--vertical {
    @apply h-full w-px;
}

/* ========================================================================== */
/* slider (4kb)                                                               */
/* ========================================================================== */

@utility slider {
    @apply block;
    --slider-value: 0%;
}

@utility slider__range {
    @apply appearance-none flex items-center p-0 outline-none w-full h-6;

    &:hover,
    &:focus-visible {
        &::-webkit-slider-thumb {
            @apply ring-4 cursor-pointer;
        }
        &::-moz-range-thumb {
            @apply ring-4 cursor-pointer;
        }
        &::-ms-thumb {
            @apply ring-4 cursor-pointer;
        }
    }

    &::-webkit-slider-thumb {
        @apply appearance-none border-primary bg-background ring-ring/50 block size-4 shrink-0 rounded-full border shadow-sm -mt-1.25;
    }
    &::-webkit-slider-runnable-track {
        @apply appearance-none rounded-full h-1.5 w-full;
        background: linear-gradient(
            to right,
            var(--primary) var(--slider-value),
            var(--muted) var(--slider-value)
        );
    }
    &::-moz-range-thumb {
        @apply appearance-none border-primary bg-background ring-ring/50 block size-4 shrink-0 rounded-full border shadow-sm -mt-1.25;
    }
    &::-moz-range-track {
        @apply appearance-none rounded-full h-1.5 w-full;
        background: linear-gradient(
            to right,
            var(--primary) var(--slider-value),
            var(--muted) var(--slider-value)
        );
    }
    &::-ms-thumb {
        @apply appearance-none border-primary bg-background ring-ring/50 block size-4 shrink-0 rounded-full border shadow-sm -mt-1.25;
    }
    &::-ms-track {
        @apply appearance-none rounded-full h-1.5 w-full;
    }
    &::-ms-fill-lower {
        @apply bg-primary rounded-full;
    }
    &::-ms-fill-upper {
        @apply bg-muted rounded-full;
    }
}

@utility slider__datalist {
    @apply flex gap-1 justify-between h-3;

    > * {
        @apply text-center empty:mx-2 text-muted-foreground empty:border-e text-xs;
    }
}

/* ========================================================================== */
/* snippet                                                                    */
/* ========================================================================== */

@utility snippet {
    @apply block relative;
    direction: ltr;

    pre {
        @apply bg-muted rounded-md overflow-x-auto p-4 text-sm;
        * {
            color: var(--snippet-foreground);
        }
    }
    &:has(x-copy-text) {
        x-copy-text {
            @apply absolute end-2 top-2;
        }
        pre {
            @apply pe-14;
        }
    }
    /* https://prismjs.com/tokens.html */
    .token.keyword,
    .token.doctype,
    .token.important,
    .token.prolog {
        color: var(--snippet-keyword);
    }
    .token.builtin,
    .token.entity {
        color: var(--snippet-builtin);
    }
    .token.function,
    .token.property,
    .token.tag {
        color: var(--snippet-function);
    }
    .token.boolean,
    .token.constant,
    .token.number {
        color: var(--snippet-constant);
    }
    .token.string,
    .token.attr-value,
    .token.char,
    .token.url {
        color: var(--snippet-string);
    }
    .token.symbol,
    .token.class-name,
    .token.attr-name,
    .token.namespace {
        color: var(--snippet-symbol);
    }
    .token.regex {
        color: var(--snippet-regex);
    }
    .token.operator {
        color: var(--snippet-operator);
    }
    .token.comment,
    .token.punctuation {
        color: var(--snippet-comment);
    }
    .token.cdata {
        color: var(--snippet-cdata);
    }
    .token.deleted {
        color: var(--snippet-deleted);
    }
    .token.inserted {
        color: var(--snippet-inserted);
    }
    .token.important,
    .token.bold {
        font-weight: bold;
    }
    .token.italic {
        font-style: italic;
    }
}

/* ========================================================================== */
/* spinner                                                                    */
/* ========================================================================== */

@utility spinner {
    @apply flex items-center justify-center;

    & > svg {
        @apply pointer-events-none shrink-0 animate-spin;
    }

    &:not([class~="spinner--sm"]):not([class~="spinner--md"]):not(
            [class~="spinner--lg"]
        ):not([class~="spinner--xl"]) {
        @apply spinner--md;
    }
}

@utility spinner--sm {
    @apply [&>svg]:size-3;
}
@utility spinner--md {
    @apply [&>svg]:size-4;
}
@utility spinner--lg {
    @apply [&>svg]:size-6;
}
@utility spinner--xl {
    @apply [&>svg]:size-8;
}

/* ========================================================================== */
/* switch                                                                     */
/* ========================================================================== */

@utility switch {
    @apply focus-visible:border-ring focus-visible:ring-ring/50 inline-flex h-[1.15rem] w-8 shrink-0 appearance-none items-center rounded-full border border-transparent shadow-xs transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50;
    @apply bg-input dark:bg-input/80 checked:bg-primary dark:checked:bg-primary;
    @apply before:pointer-events-none before:block before:size-4 before:rounded-full before:ring-0 before:transition-all before:content-[''];
    @apply before:bg-background dark:before:bg-foreground;
    @apply dark:checked:before:bg-primary-foreground checked:before:ms-3.5;
    @apply cursor-pointer;
}

/* ========================================================================== */
/* tabs                                                                       */
/* ========================================================================== */

@utility tabs {
    @apply block;
}

@utility tabs__list {
    @apply h-9 inline-flex w-fit items-center justify-center rounded-lg p-0.75;
    @apply bg-muted text-muted-foreground;

    [role="tab"] {
        @apply text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-[color,box-shadow];
        @apply focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring;
        @apply disabled:pointer-events-none disabled:opacity-50;
        @apply [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4;
    }
    [role="tab"][aria-selected="true"] {
        @apply bg-background dark:text-foreground shadow-sm select-none;
        @apply dark:border-input;
    }
    [role="tab"]:focus-visible {
        @apply border-ring ring-2 ring-ring/50 outline-none;
    }
}

@utility tabs__panel {
    @apply h-fit rounded-lg mt-2;
}

@utility tabs__panel--border {
    @apply border;
}

/* ========================================================================== */
/* textarea                                                                   */
/* ========================================================================== */

@utility textarea {
    @apply border-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm;
    @apply placeholder:text-muted-foreground;
}

/* ========================================================================== */
/* tooltip                                                                    */
/* ========================================================================== */

@utility tooltip {
    --tooltip-content: attr(aria-label);
    @apply aria-hidden:hidden relative;

    &:before {
        @apply content-(--tooltip-content);
        @apply bg-foreground text-background pointer-events-none invisible absolute z-50 w-fit max-w-xs scale-95 truncate rounded-md px-3 py-1.5 text-xs opacity-0 transition-all delay-300 ease-out;
    }
    &:after {
        @apply pointer-events-none invisible absolute z-50 scale-95 border-4 border-transparent opacity-0 transition-all delay-300 ease-out content-[''];
    }
    &:hover:before,
    &:hover:after,
    &:focus-visible:before,
    &:focus-visible:after {
        @apply visible scale-100 opacity-100;
    }

    &:not(.tooltip--top):not(.tooltip--bottom):not(.tooltip--left):not(
            .tooltip--right
        ) {
        @apply tooltip--top;
    }
    &:not(.tooltip--center):not(.tooltip--start):not(.tooltip--end) {
        @apply tooltip--center;
    }
}

@utility tooltip--top {
    @apply before:bottom-full before:mb-2 before:translate-y-2 hover:before:translate-y-0 focus-visible:before:translate-y-0;
    @apply after:border-t-foreground after:bottom-full after:mb-1 after:translate-y-2 after:border-b-0 after:border-x-transparent hover:after:translate-y-0 focus-visible:after:translate-y-0;
}
@utility tooltip--bottom {
    @apply before:top-full before:mt-2 before:-translate-y-2 hover:before:translate-y-0 focus-visible:before:translate-y-0;
    @apply after:border-b-foreground after:top-full after:mt-1 after:-translate-y-2 after:border-t-0 after:border-x-transparent hover:after:translate-y-0 focus-visible:after:translate-y-0;
}
@utility tooltip--left {
    @apply before:end-full before:me-2 before:translate-x-2 hover:before:translate-x-0 focus-visible:before:translate-x-0;
    @apply after:border-s-foreground after:end-full after:me-1 after:translate-x-2 after:border-e-0 after:border-y-transparent hover:after:translate-x-0 focus-visible:after:translate-x-0;
}
@utility tooltip--right {
    @apply before:start-full before:ms-2 before:-translate-x-2 hover:before:translate-x-0 focus-visible:before:translate-x-0;
    @apply after:border-e-foreground after:start-full after:ms-1 after:-translate-x-2 after:border-s-0 after:border-y-transparent hover:after:translate-x-0 focus-visible:after:translate-x-0;
}

@utility tooltip--center {
    &:not(.tooltip--top):not(.tooltip--bottom):not(.tooltip--left):not(
            .tooltip--right
        ),
    &.tooltip--top,
    &.tooltip--bottom {
        @apply before:start-1/2 before:-translate-x-1/2 after:start-1/2 after:-translate-x-1/2;
    }
    &.tooltip--left,
    &.tooltip--right {
        @apply before:top-1/2 before:-translate-y-1/2 after:top-1/2 after:-translate-y-1/2;
    }
}
@utility tooltip--start {
    &:not(.tooltip--top):not(.tooltip--bottom):not(.tooltip--left):not(
            .tooltip--right
        ),
    &.tooltip--top,
    &.tooltip--bottom {
        @apply before:start-0 after:start-3;
    }
    &.tooltip--left,
    &.tooltip--right {
        @apply before:bottom-0 after:bottom-3;
    }
}
@utility tooltip--end {
    &:not(.tooltip--top):not(.tooltip--bottom):not(.tooltip--left):not(
            .tooltip--right
        ),
    &.tooltip--top,
    &.tooltip--bottom {
        @apply before:end-0 after:end-3;
    }
    &.tooltip--left,
    &.tooltip--right {
        @apply before:top-0 after:top-3;
    }
}

/* ========================================================================== */
/* typography                                                                 */
/* ========================================================================== */

@utility h1 {
    @apply scroll-m-20 text-4xl font-extrabold tracking-tight text-balance;
    @apply not-first:mt-12;
}

@utility h2 {
    @apply scroll-m-20 border-b border-border pb-2 text-3xl font-semibold tracking-tight;
    @apply not-first:mt-10;
}

@utility h3 {
    @apply scroll-m-20 text-2xl font-semibold tracking-tight;
    @apply not-first:mt-8;
}

@utility h4 {
    @apply scroll-m-20 text-xl font-semibold tracking-tight;
    @apply not-first:mt-6;
}

@utility p {
    @apply leading-7;
    @apply not-first:mt-6;
}

@utility blockquote {
    @apply border-s-2 ps-6 italic;
    @apply not-first:mt-6;
    @apply border-border;
}

@utility table {
    @apply w-full;
    tr {
        @apply even:bg-muted m-0 border-t p-0;
    }
    th {
        @apply border border-border px-4 py-2 text-left font-bold [[align=center]]:text-center [[align=right]]:text-right;
    }
    td {
        @apply border border-border px-4 py-2 text-left [[align=center]]:text-center [[align=right]]:text-right;
    }
}

@utility linebreak {
    @apply leading-6.5;
}

@utility ul {
    @apply my-6 ms-6 list-disc [&>li]:mt-2;
}

@utility ol {
    @apply my-6 ms-6 list-decimal [&>li]:mt-2;
}

@utility code {
    @apply bg-muted relative rounded px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold;
}

@utility lead {
    @apply text-muted-foreground text-xl;
}

@utility small {
    @apply text-sm leading-none font-medium;
}

@utility muted {
    @apply text-muted-foreground text-sm;
}

@utility typography {
    a&,
    a {
        @apply link;
    }

    h1&,
    h1 {
        @apply h1;
    }

    h2&,
    h2 {
        @apply h2;
    }

    h3&,
    h3 {
        @apply h3;
    }

    h4&,
    h4 {
        @apply h4;
    }

    kbd&,
    kbd {
        @apply kbd;
    }

    p&,
    p {
        @apply p;
    }

    blockquote&,
    blockquote {
        @apply blockquote;
    }

    table&,
    table {
        @apply table;
    }

    br&,
    br {
        @apply linebreak;
    }

    ul&,
    ul {
        @apply ul;
    }

    ol&,
    ol {
        @apply ol;
    }

    code&,
    code {
        @apply code;
    }

    small&,
    small {
        @apply small;
    }
}
