@import "tailwindcss";
@import "tw-animate-css";

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

/*
 * Polymorphic state variants — vendored from shadcn/ui (MIT):
 * packages/shadcn/src/tailwind.css
 *
 * Our components emit upstream shadcn's `data-open:` / `data-closed:` /
 * `data-checked:` / `data-selected:` / `data-horizontal:` … class prefixes
 * verbatim, for class-string parity with the React originals. Those prefixes
 * are NOT Tailwind builtins — without these `@custom-variant` declarations
 * every such class silently compiles to nothing. This block must therefore
 * ship with the theme, not just live in the docs app.
 *
 * "Polymorphic" = each variant matches both spellings a headless library
 * might use: Radix-style `[data-state="open"]` AND boolean-ish `[data-open]`.
 * zag-js (which drives our components) uses both conventions depending on
 * the machine, so both arms are load-bearing here.
 *
 * ZAG EMISSION AUDIT (@zag-js/* 1.43.0) — why the `data-selected` arm below
 * diverges from upstream:
 *   @zag-js/dom-query `dataAttr` is `(guard) => guard ? "" : void 0`, i.e. it
 *   emits a PRESENCE attribute (`data-selected=""`), never `="true"`.
 *   Confirmed in real connects:
 *     - @zag-js/tabs      trigger: data-selected + data-disabled via dataAttr
 *     - @zag-js/checkbox  root:    data-active + data-disabled via dataAttr;
 *                                  data-state is a literal
 *                                  "checked"/"unchecked"/"indeterminate"
 *     - @zag-js/splitter  resizer: data-disabled via dataAttr;
 *                                  data-orientation is a literal string
 *   Upstream's `data-selected` matches ONLY `[data-selected="true"]`, so it
 *   would never fire against zag's `data-selected=""`. Widened below with the
 *   `:not(...="false")` arm the other variants already carry.
 *   `data-disabled` and `data-active` already had that arm upstream — it
 *   matches `=""` — so they are left byte-identical to upstream.
 *   `data-horizontal`/`data-vertical` key on `data-orientation`, which zag
 *   emits as a literal string, so they need no widening either.
 */
@custom-variant data-open {
  &:where([data-state="open"]),
  &:where([data-open]:not([data-open="false"])) {
    @slot;
  }
}

@custom-variant data-closed {
  &:where([data-state="closed"]),
  &:where([data-closed]:not([data-closed="false"])) {
    @slot;
  }
}

@custom-variant data-checked {
  &:where([data-state="checked"]),
  &:where([data-checked]:not([data-checked="false"])) {
    @slot;
  }
}

@custom-variant data-unchecked {
  &:where([data-state="unchecked"]),
  &:where([data-unchecked]:not([data-unchecked="false"])) {
    @slot;
  }
}

/* WIDENED vs upstream: upstream matches only [data-selected="true"]; zag's
 * dataAttr emits data-selected="" (see audit note above). */
@custom-variant data-selected {
  &:where([data-selected="true"]),
  &:where([data-selected]:not([data-selected="false"])) {
    @slot;
  }
}

/* Upstream as-is: the second arm already matches zag's data-disabled="". */
@custom-variant data-disabled {
  &:where([data-disabled="true"]),
  &:where([data-disabled]:not([data-disabled="false"])) {
    @slot;
  }
}

/* Upstream as-is: the second arm already matches zag's data-active="". */
@custom-variant data-active {
  &:where([data-state="active"]),
  &:where([data-active]:not([data-active="false"])) {
    @slot;
  }
}

@custom-variant data-horizontal {
  &:where([data-orientation="horizontal"]) {
    @slot;
  }
}

@custom-variant data-vertical {
  &:where([data-orientation="vertical"]) {
    @slot;
  }
}

@utility no-scrollbar {
  -ms-overflow-style: none;
  scrollbar-width: none;

  &::-webkit-scrollbar {
    display: none;
  }
}

:root {
  --background: oklch(1 0 0);
  --foreground: oklch(0.145 0 0);
  --card: oklch(1 0 0);
  --card-foreground: oklch(0.145 0 0);
  --popover: oklch(1 0 0);
  --popover-foreground: oklch(0.145 0 0);
  --primary: oklch(0.205 0 0);
  --primary-foreground: oklch(0.985 0 0);
  --secondary: oklch(0.97 0 0);
  --secondary-foreground: oklch(0.205 0 0);
  --muted: oklch(0.97 0 0);
  --muted-foreground: oklch(0.535 0 0); /* DIVERGENCE: darkened from shadcn 0.556 (previously 0.54) to also clear 4.5:1 on the switch-choice-card's tinted bg (bg-input/5-ish), which measured 4.48:1 at 0.54 */
  --accent: oklch(0.97 0 0);
  --accent-foreground: oklch(0.205 0 0);
  --destructive: oklch(0.47 0.238 27.325); /* DIVERGENCE: darkened from shadcn 0.577 (previously 0.558) — the soft/tint destructive variants (button, badge, bubble, attachment: text-destructive[/80] on a light destructive-tinted bg) render this color as TEXT directly, not just as a solid-fill button background; 0.558 cleared 4.5:1 for the solid pairing but only reached ~4.3:1 for the tint pairing, so it's darkened further to clear both (verified against apps/docs's /verify pages, which carry the identical component CSS) */
  --border: oklch(0.922 0 0);
  --input: oklch(0.922 0 0);
  --ring: oklch(0.708 0 0);
  --chart-1: oklch(0.87 0 0);
  --chart-2: oklch(0.556 0 0);
  --chart-3: oklch(0.439 0 0);
  --chart-4: oklch(0.371 0 0);
  --chart-5: oklch(0.269 0 0);
  --radius: 0.625rem;
  --sidebar: oklch(0.985 0 0);
  --sidebar-foreground: oklch(0.145 0 0);
  --sidebar-primary: oklch(0.205 0 0);
  --sidebar-primary-foreground: oklch(0.985 0 0);
  --sidebar-accent: oklch(0.97 0 0);
  --sidebar-accent-foreground: oklch(0.205 0 0);
  --sidebar-border: oklch(0.922 0 0);
  --sidebar-ring: oklch(0.708 0 0);
}

.dark {
  --background: oklch(0.145 0 0);
  --foreground: oklch(0.985 0 0);
  --card: oklch(0.205 0 0);
  --card-foreground: oklch(0.985 0 0);
  --popover: oklch(0.205 0 0);
  --popover-foreground: oklch(0.985 0 0);
  --primary: oklch(0.922 0 0);
  --primary-foreground: oklch(0.205 0 0);
  --secondary: oklch(0.269 0 0);
  --secondary-foreground: oklch(0.985 0 0);
  --muted: oklch(0.269 0 0);
  --muted-foreground: oklch(0.708 0 0);
  --accent: oklch(0.269 0 0);
  --accent-foreground: oklch(0.985 0 0);
  --destructive: oklch(0.704 0.191 22.216); /* shadcn value — reads as TEXT on dark backgrounds (errors, alerts), where light red passes */
  --border: oklch(1 0 0 / 10%);
  --input: oklch(1 0 0 / 15%);
  --ring: oklch(0.556 0 0);
  --chart-1: oklch(0.87 0 0);
  --chart-2: oklch(0.556 0 0);
  --chart-3: oklch(0.439 0 0);
  --chart-4: oklch(0.371 0 0);
  --chart-5: oklch(0.269 0 0);
  --sidebar: oklch(0.205 0 0);
  --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.269 0 0);
  --sidebar-accent-foreground: oklch(0.985 0 0);
  --sidebar-border: oklch(1 0 0 / 10%);
  --sidebar-ring: oklch(0.556 0 0);
}


@theme inline {
  --color-background: var(--background);
  --color-foreground: var(--foreground);
  --color-card: var(--card);
  --color-card-foreground: var(--card-foreground);
  --color-popover: var(--popover);
  --color-popover-foreground: var(--popover-foreground);
  --color-primary: var(--primary);
  --color-primary-foreground: var(--primary-foreground);
  --color-secondary: var(--secondary);
  --color-secondary-foreground: var(--secondary-foreground);
  --color-muted: var(--muted);
  --color-muted-foreground: var(--muted-foreground);
  --color-accent: var(--accent);
  --color-accent-foreground: var(--accent-foreground);
  --color-destructive: var(--destructive);
  --color-border: var(--border);
  --color-input: var(--input);
  --color-ring: var(--ring);
  --color-chart-1: var(--chart-1);
  --color-chart-2: var(--chart-2);
  --color-chart-3: var(--chart-3);
  --color-chart-4: var(--chart-4);
  --color-chart-5: var(--chart-5);
  --color-sidebar: var(--sidebar);
  --color-sidebar-foreground: var(--sidebar-foreground);
  --color-sidebar-primary: var(--sidebar-primary);
  --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
  --color-sidebar-accent: var(--sidebar-accent);
  --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
  --color-sidebar-border: var(--sidebar-border);
  --color-sidebar-ring: var(--sidebar-ring);
  --radius-sm: calc(var(--radius) * 0.6);
  --radius-md: calc(var(--radius) * 0.8);
  --radius-lg: var(--radius);
  --radius-xl: calc(var(--radius) * 1.4);
  --radius-2xl: calc(var(--radius) * 1.8);
  --radius-3xl: calc(var(--radius) * 2.2);
  --radius-4xl: calc(var(--radius) * 2.6);
}

@layer base {
  * {
    @apply border-border outline-ring/50;
  }
  body {
    @apply bg-background text-foreground;
  }

}

/*
 * `mu-font-heading` is a styling hook emitted by the card, dialog, drawer,
 * sheet, alert-dialog and empty titles. It had NO rule in either distribution
 * — the only definition in the repo lived in `apps/docs/src/app.css`, which no
 * consumer receives — so component titles silently fell back to the body face
 * with no error.
 *
 * Defined HERE, in globals.css, because this file is the one both
 * distributions consume: the copy path ships it as the project's stylesheet,
 * and the import path pulls the same file in via
 * `@import "@marko-ui/shadcn/styles/globals*.css"`. A rule in `style-*.css`
 * would reach import consumers only, since those files scope everything under
 * `.style-<name>`.
 *
 * `@layer components`, not `base`: a base-layer rule loses to any Tailwind
 * `font-*` utility, which would make the hook silently non-functional the
 * moment a consumer set a font utility on the same element.
 *
 * `--font-heading` falls back to `--font-sans` and then to a real stack:
 * `--font-sans` is NOT defined by this theme, so a two-step var() fallback
 * alone would resolve to nothing on a project that set neither.
 */
@layer components {
  .mu-font-heading {
    font-family: var(
      --font-heading,
      var(--font-sans, ui-sans-serif, system-ui, sans-serif)
    );
  }
}

/*
 * Measured-height accordion animation (parity with Radix's
 * `--radix-accordion-content-height`, which Radix computes via
 * ResizeObserver in `@radix-ui/react-collapsible` and re-exports through
 * `@radix-ui/react-accordion`). `accordion.marko` publishes
 * `--marko-accordion-content-height` on each content panel from its own
 * ResizeObserver; these keyframes replace tw-animate-css's upstream
 * `accordion-down`/`accordion-up` (which only knows Radix/Bits/Reka/Kobalte/
 * ng-primitives var names) so `height: 0 -> auto` becomes
 * `height: 0 -> <measured px>` in every browser, not just ones supporting
 * `calc-size()`/`interpolate-size`.
 *
 * NAMED `marko-accordion-down`/`marko-accordion-up`, NOT `accordion-down`/
 * `accordion-up` — Tailwind v4's build (Lightning CSS) dedupes same-named
 * top-level `@keyframes` across the whole sheet and keeps the FIRST
 * occurrence, which is tw-animate-css's own `@theme inline` block (it loads
 * before this file). A same-named override here compiles clean but
 * is silently discarded from the production CSS — verified: the built
 * stylesheet contained exactly one `@keyframes accordion-down` (tw-animate-
 * css's), zero references to `--marko-accordion-content-height`, i.e. this
 * entire mechanism was dead code until renamed. Using a unique name sidesteps
 * the dedup entirely; the `@theme inline` block below repoints Tailwind's
 * `--animate-accordion-down`/`-up` (the vars `animate-accordion-down`/`-up`
 * utility classes actually resolve to, referenced verbatim from shadcn's
 * accordion.tsx class string, which this repo's accordion.marko also keeps
 * unchanged for class-string parity) at these renamed keyframes instead of
 * tw-animate-css's originals, which stay defined (harmless, unreferenced)
 * for anything else that might target the bare `accordion-down` name.
 *
 * Shared by the consumer theme (globals.css) and the docs site's app.css —
 * both must import it AFTER tw-animate-css.
 */
@theme inline {
  --animate-accordion-down: marko-accordion-down var(--tw-animation-duration, var(--tw-duration, 0.2s))
    var(--tw-ease, ease-out) var(--tw-animation-delay, 0s) var(--tw-animation-iteration-count, 1)
    var(--tw-animation-direction, normal) var(--tw-animation-fill-mode, none);
  --animate-accordion-up: marko-accordion-up var(--tw-animation-duration, var(--tw-duration, 0.2s))
    var(--tw-ease, ease-out) var(--tw-animation-delay, 0s) var(--tw-animation-iteration-count, 1)
    var(--tw-animation-direction, normal) var(--tw-animation-fill-mode, none);
}

@keyframes marko-accordion-down {
  from {
    height: 0;
  }
  to {
    height: var(--marko-accordion-content-height, auto);
  }
}

@keyframes marko-accordion-up {
  from {
    height: var(--marko-accordion-content-height, auto);
  }
  to {
    height: 0;
  }
}
