/*
  Tailwind v4 theme for CloudGrid.

  This maps Tailwind's utility namespaces onto the --cg-* custom properties in
  tokens.css. It does not define any values of its own: every entry is a var()
  reference, so a theme change stays a one-file edit in tokens.css and never has
  to be mirrored here.

  Load order matters. tokens.css must be imported before this file, or the
  var() references resolve to nothing:

      @import "tailwindcss";
      @import "@cloudgrid-io/ui/tokens.css";
      @import "@cloudgrid-io/ui/theme.css";

  The setup guide's Step 2 example mapped --color-background, --color-accent and
  friends. Those names do not exist in this brand system, so this file is
  authored against the real tokens rather than copied from the guide.

  Utilities are a convenience layer, not the contract. The canon in tokens.css
  stands: components consume custom properties exclusively and must never
  hardcode a hex. Where a component needs a token with no utility (durations,
  transitions, the press scale), use var(--cg-*) directly.
*/

/*
  `inline` is load-bearing, not stylistic. Do not remove it.

  With a plain `@theme`, Tailwind evaluates each var() once, at :root, and emits
  the resolved literal. Utilities then point at the theme variable, which is
  frozen to whatever the default scope resolved to. The surface flips stop
  working: inside data-cg-surface="panel", --cg-border-hairline correctly becomes
  rgba(255,255,255,0.24), but border-hairline still paints #f1f1f1, because the
  utility never sees the flipped variable.

  With `inline`, Tailwind inlines the theme value into the utility, so
  border-hairline compiles to `border-color: var(--cg-border-hairline)` and the
  variable resolves at the element. The flip works.

  Measured, not assumed: with plain @theme, --color-hairline computed to #f1f1f1
  in all three scopes while --cg-border-hairline flipped correctly in each.

  One consequence to know: text does not flip by inheritance. A container that
  sets data-cg-surface must also apply a text color from a token (text-ink), or
  its children inherit the already-resolved color from an ancestor and stay dark.
*/
@theme inline {
  /* ---- names this file must not claim ----
     shadcn's own theme layer owns background, foreground, card, popover,
     primary, secondary, muted, accent, destructive, border, input, ring,
     chart-* and sidebar-*, and its component source depends on them. Whichever
     block loads last wins, so claiming one of those names here does not produce
     an error: it silently changes what a shadcn component renders.

     Found the hard way. An earlier version of this file mapped --color-muted to
     the muted *text* color and --color-accent to the accent *text* color. In
     shadcn both are background colors, so text-muted and text-accent rendered
     near-white on white. The badge was invisible.

     So: muted text is --color-faint, the brand purple is --color-brand, and the
     brand trio is brand / lime / cyan. Nothing below overlaps shadcn. */

  /* ---- surfaces ----
     One name serves every color utility, so --color-page gives bg-page,
     text-page and border-page alike. */
  --color-page: var(--cg-surface-page);
  --color-page-alt: var(--cg-surface-page-alt);
  --color-subtle: var(--cg-surface-subtle);
  --color-control: var(--cg-surface-control);
  --color-panel: var(--cg-surface-panel);
  --color-code: var(--cg-surface-code);

  /* ---- text ----
     Deliberately not called --color-primary: in this system "primary" is the
     purple brand color, while the primary *text* color is ink. Collapsing both
     onto text-primary would make the utility lie. */
  --color-ink: var(--cg-text-primary);
  --color-body: var(--cg-text-secondary);
  --color-faint: var(--cg-text-muted);
  --color-placeholder: var(--cg-text-placeholder);
  --color-inverse: var(--cg-text-inverse);
  --color-on-primary: var(--cg-text-on-primary);
  --color-on-accent: var(--cg-text-on-accent);
  --color-on-code: var(--cg-text-on-code);

  /* ---- brand ---- */
  --color-brand: var(--cg-primary);
  --color-brand-press: var(--cg-primary-press);
  --color-brand-tint: var(--cg-primary-tint);
  --color-lime: var(--cg-secondary);
  --color-lime-press: var(--cg-secondary-press);
  --color-cyan: var(--cg-tertiary);
  --color-cyan-press: var(--cg-tertiary-press);
  /* `danger`, not `destructive`: rule 4 says never claim a name shadcn's theme
     layer owns, and `destructive` is one of its own. This is the CloudGrid name
     for the same value, alongside faint / brand / lime / cyan. shadcn.css bridges
     --destructive to the same token, so both spellings resolve to one source. */
  --color-danger: var(--cg-danger);

  /* ---- state ----
     What an entity IS: online, offline, pending, unhealthy, expired, and danger
     above.

     #111 added the tokens and stopped there, so for one release the state
     palette was reachable only as raw var(--cg-online). That is the shape #30
     and #91 both found people get wrong: `danger` had utilities and its five
     siblings did not, so the first consumer of the state palette would either
     hardcode an escape hatch or reach for `text-accent` and get a surface.

     Each name serves every colour utility, so --color-online gives text-online,
     bg-online and border-online alike.

     Checked against rule 4 before claiming these: shadcn owns background,
     foreground, card, popover, primary, secondary, muted, accent, destructive,
     border, input, ring, chart-* and sidebar-*. None of these collide.

     There is no --color-offline-fill, because there is no --cg-offline-fill.
     #111's note explains why, and it is a design decision rather than an
     omission: the muted neutral on a neutral tint measures 2.90:1, under the
     3:1 bar, so an unplugged chip uses the card ground and border-control
     instead. A utility here would have to invent the value it maps.

     unhealthy (#122) arrives with its token rather than a release later, which
     is the whole point of the guard that walks this block. #113 shipped the
     `indicator` group with no bridge at all and nothing went red, because that
     guard walks the `state` group and only that one. A token whose utility
     lands in a later version is a token the first consumer reaches for and
     does not find. */
  --color-online: var(--cg-online);
  --color-online-fill: var(--cg-online-fill);
  --color-offline: var(--cg-offline);
  --color-pending: var(--cg-pending);
  --color-pending-fill: var(--cg-pending-fill);
  --color-unhealthy: var(--cg-unhealthy);
  --color-unhealthy-fill: var(--cg-unhealthy-fill);
  --color-expired: var(--cg-expired);
  --color-expired-fill: var(--cg-expired-fill);
  --color-danger-fill: var(--cg-danger-fill);

  /* ---- lines ---- */
  --color-hairline: var(--cg-border-hairline);
  --color-line: var(--cg-border-control);
  --color-line-strong: var(--cg-border-strong);
  --color-line-accent: var(--cg-border-accent);

  /* ---- type families ----
     --font-sans points at the body face so the stock font-sans utility is
     correct rather than something to remember not to use. */
  --font-sans: var(--cg-font-body);
  --font-body: var(--cg-font-body);
  --font-display: var(--cg-font-display);
  --font-mono: var(--cg-font-mono);

  /* ---- type scale ----
     Every --text-* carries a --text-*--line-height companion, because Tailwind
     emits the pair together:

       .text-body-sm { font-size: var(--cg-body-sm);
                       line-height: var(--tw-leading, var(--text-body-sm--line-height)) }

     Without the companion the utility sets a size and no leading, and the
     leading falls back to whatever an ancestor happens to declare. That reads
     fine here, where globals.css sets line-height on body, and wrong in a
     consumer app that copied the component and not the stylesheet -- which is
     the whole population this registry serves. A `leading-*` utility still wins
     when a component wants to override, via --tw-leading.

     Two other companions Tailwind supports, added only where the brand actually
     pairs a value with a size rather than everywhere it is possible:
     --letter-spacing on the display ramp, because the brand specifies
     --cg-display-tracking for it, and --font-weight on the label, because
     --cg-label-weight exists for exactly that. Body and heading have no specified
     tracking or weight, so they get none: a companion that invents a value is
     worse than an absent one, since it forces a weight where a component expected
     to inherit. Closes the gap noted in notes.md after #30. */
  --text-display-xl: var(--cg-display-xl);
  --text-display-xl--line-height: var(--cg-display-line);
  --text-display-xl--letter-spacing: var(--cg-display-tracking);
  --text-display-lg: var(--cg-display-lg);
  --text-display-lg--line-height: var(--cg-display-line);
  --text-display-lg--letter-spacing: var(--cg-display-tracking);
  --text-display-md: var(--cg-display-md);
  --text-display-md--line-height: var(--cg-display-line);
  --text-display-md--letter-spacing: var(--cg-display-tracking);
  --text-display-sm: var(--cg-display-sm);
  --text-display-sm--line-height: var(--cg-display-line);
  --text-display-sm--letter-spacing: var(--cg-display-tracking);
  --text-heading-lg: var(--cg-heading-lg);
  --text-heading-lg--line-height: var(--cg-heading-line);
  --text-heading-md: var(--cg-heading-md);
  --text-heading-md--line-height: var(--cg-heading-line);
  --text-heading-sm: var(--cg-heading-sm);
  --text-heading-sm--line-height: var(--cg-heading-line);
  --text-body-lg: var(--cg-body-lg);
  --text-body-lg--line-height: var(--cg-body-line);
  --text-body-md: var(--cg-body-md);
  --text-body-md--line-height: var(--cg-body-line);
  --text-body-sm: var(--cg-body-sm);
  --text-body-sm--line-height: var(--cg-body-line);
  --text-caption: var(--cg-caption);
  --text-caption--line-height: var(--cg-body-line);
  --text-mono: var(--cg-mono-size);
  --text-mono--line-height: var(--cg-mono-line);
  --text-label: var(--cg-label-size);
  --text-label--line-height: var(--cg-body-line);
  --text-label--font-weight: var(--cg-label-weight);

  /* ---- weights ----
     `--font-weight-display` is unreachable and kept only for completeness. Both
     namespaces build the same utility name: the family `--font-display` and the
     weight `--font-weight-display` each want `font-display`, and the family wins.
     Measured, not assumed: the build emits
     `.font-display,.font-heading{font-family:var(--cg-font-display)}` and no
     rule anywhere sets font-weight 800.

     That is rule 4 one layer in. Rule 4 is about not claiming a name shadcn
     owns; this is two of our own entries claiming one name, with the same
     silent outcome.

     So the brand's display weight is exposed as `font-heavy`. Different word,
     same token, and reachable. Needed by any display-face heading that is not an
     h1, since globals.css only styles h1. */
  --font-weight-regular: var(--cg-weight-regular);
  --font-weight-medium: var(--cg-weight-medium);
  --font-weight-bold: var(--cg-weight-bold);
  --font-weight-display: var(--cg-weight-display);
  --font-weight-heavy: var(--cg-weight-display);

  /* ---- leading and tracking ---- */
  --leading-display: var(--cg-display-line);
  --leading-heading: var(--cg-heading-line);
  --leading-body: var(--cg-body-line);
  --leading-mono: var(--cg-mono-line);
  --tracking-display: var(--cg-display-tracking);
  --tracking-body: var(--cg-body-tracking);

  /* ---- corners ---- */
  --radius-xs: var(--cg-radius-xs);
  --radius-sm: var(--cg-radius-sm);
  --radius-md: var(--cg-radius-md);
  --radius-lg: var(--cg-radius-lg);
  --radius-xl: var(--cg-radius-xl);
  --radius-2xl: var(--cg-radius-2xl);
  --radius-pill: var(--cg-radius-pill);

  /* ---- elevation ----
     Hairlines first. Shadows appear on the wash or on hover, never as the
     default way to contain something. */
  --shadow-card: var(--cg-shadow-card);
  --shadow-raised: var(--cg-shadow-raised);
  --shadow-hover: var(--cg-shadow-hover);
  --shadow-panel: var(--cg-shadow-panel);
  --shadow-focus: var(--cg-ring-focus);

  /* ---- spacing ----
     --spacing sets the 4px base, so the numeric utilities (p-4, gap-6) line up
     with the --cg-space-* ramp by construction. The named entries below are the
     layout measurements, which have no numeric equivalent. */
  --spacing: 4px;
  --spacing-page-pad: var(--cg-page-pad);
  --spacing-stack-tight: var(--cg-stack-tight);
  --spacing-stack: var(--cg-stack);
  --spacing-stack-loose: var(--cg-stack-loose);
  --spacing-section-gap: var(--cg-section-gap);
  --spacing-header: var(--cg-header-height);
  --spacing-footer: var(--cg-footer-height);

  /* ---- widths ---- */
  --container-form: var(--cg-column-form);
  --container-wide: var(--cg-column-wide);
  --container-page: var(--cg-container);
  --container-measure: var(--cg-measure);

  /* ---- motion ----
     Tailwind has an --ease-* namespace, so these become ease-out / ease-in-out.
     Durations have no theme namespace in v4: use var(--cg-duration) directly, or
     the duration-[…] arbitrary value. */
  --ease-out: var(--cg-ease-out);
  --ease-in-out: var(--cg-ease-in-out);
}
