/*
  The shadcn bridge: every shadcn semantic variable, resolved to a CloudGrid
  token.

  This ships from the package rather than living in the registry app, because a
  consumer needs it just as much as we do. `npx shadcn add @cloudgrid/button`
  copies our component source and installs @cloudgrid-io/ui, but the source
  refers to --background, --primary and --border. Without this file those names
  still point at whatever the consumer's own `shadcn init` wrote, which is the
  stock oklch grey palette, and our components render grey in their app while
  looking correct in ours. One file, imported by both, so the two cannot drift.

  Import order:

      @import "tailwindcss";
      @import "@cloudgrid-io/ui/fonts.css";
      @import "@cloudgrid-io/ui/tokens.css";
      @import "@cloudgrid-io/ui/theme.css";
      @import "@cloudgrid-io/ui/shadcn.css";   <- after the consumer's own :root

  Two mappings are worth reading twice, because the obvious one is wrong.

  --secondary is NOT --cg-secondary. In shadcn, "secondary" is the quiet button
  variant. In this brand --cg-secondary is lime, an accent used sparingly. A lime
  secondary button would put the loudest color in the system on the quietest
  control, so secondary maps to the neutral control fill instead.

  --accent is NOT an accent either. shadcn uses it for hover and highlight
  backgrounds, so it maps to the subtle surface.

  THE SELECTOR LIST IS LOAD-BEARING. Declaring these at :root alone is not
  enough, and the failure is invisible until a real component sits on a flipped
  surface.

  A custom property that references another is substituted where it is DECLARED,
  and descendants inherit the already-resolved value. With
  `--border: var(--cg-border-hairline)` at :root only, --border computes to
  #f1f1f1 at the root and every descendant inherits that literal. Redefining
  --cg-border-hairline inside [data-cg-surface="panel"] then changes nothing:
  measured, --cg-border-hairline was rgba(255,255,255,0.24) inside the panel
  while --border was still #f1f1f1, so every shadcn component kept its
  light-surface borders on purple and on ink.

  Repeating the block on the flip selectors makes each scope re-resolve the whole
  mapping against its own --cg-* values. Tokens the flips do not touch, like
  --cg-primary, resolve identically in all three, so listing everything costs
  nothing and guarantees nothing is missed.
*/

:root,
[data-cg-surface="panel"],
[data-cg-surface="ink"] {
  /* surfaces */
  --background: var(--cg-surface-page);
  --card: var(--cg-surface-card);
  --popover: var(--cg-surface-card);
  --muted: var(--cg-surface-subtle);
  --secondary: var(--cg-surface-control);
  --accent: var(--cg-surface-subtle);

  /* text on those surfaces */
  --foreground: var(--cg-text-primary);
  --card-foreground: var(--cg-text-primary);
  --popover-foreground: var(--cg-text-primary);
  --muted-foreground: var(--cg-text-muted);
  --secondary-foreground: var(--cg-text-primary);
  --accent-foreground: var(--cg-text-primary);

  /* the brand action color */
  --primary: var(--cg-primary);
  --primary-foreground: var(--cg-text-on-primary);

  --border: var(--cg-border-hairline);
  --input: var(--cg-border-control);

  /* The ring is --cg-text-accent, not --cg-focus-ring, and the difference is a
     WCAG failure rather than a preference.

     --cg-focus-ring is translucent (0.28 on the default surface). Components
     then apply an opacity modifier on top of it, `ring-ring/50`, so the ring
     composites at 0.14 and reaches 1.23:1 against the white page. SC 1.4.11
     requires 3:1 for a non-text indicator. The purple panel was no better:
     white at 0.5 alpha over purple measures 2.60:1. Two of the three surfaces
     failed; only ink passed, and only just, at 3.22:1.

     No translucent value fixes it while the /50 remains: even a fully opaque
     colour halves to 2.25:1. So the modifier had to go from the components, and
     the ring had to become solid.

     --cg-text-accent is the token that already flips to the right solid colour
     in every scope, so this needs no change to tokens.css and creates no drift
     against the site and v0 copies of it:

       default  var(--cg-primary)    purple    5.84:1 on white
       panel    #ffffff              white     5.84:1 on purple
       ink      var(--cg-secondary)  lime     10.33:1 on ink

     --cg-focus-ring is untouched and still backs the brand's own
     --cg-ring-focus shadow. Pinned by an assertion in
     registry/e2e/token-wiring.spec.ts. */
  --ring: var(--cg-text-accent);

  /* charts: the brand trio first, then neutrals, so a three-series chart is
     purple, lime, cyan and a five-series one degrades to grey rather than
     inventing colors. */
  --chart-1: var(--cg-primary);
  --chart-2: var(--cg-secondary);
  --chart-3: var(--cg-tertiary);
  --chart-4: var(--cg-neutral-500);
  --chart-5: var(--cg-neutral-700);

  /* sidebar: a subtle wash, not its own palette */
  --sidebar: var(--cg-surface-page-alt);
  --sidebar-foreground: var(--cg-text-primary);
  --sidebar-primary: var(--cg-primary);
  --sidebar-primary-foreground: var(--cg-text-on-primary);
  --sidebar-accent: var(--cg-surface-subtle);
  --sidebar-accent-foreground: var(--cg-text-primary);
  --sidebar-border: var(--cg-border-hairline);
  --sidebar-ring: var(--cg-focus-ring);

  /* shadcn derives its own radius scale from this one value. Pointing it at
     --cg-radius-lg keeps anything not explicitly mapped in the right family. */
  --radius: var(--cg-radius-lg);

  /* Closed 2026-08-16 (#62). This was the package's one literal colour, a
     #c0392b placeholder, because the brand had no red of any kind. It now points
     at --cg-danger like every other mapping here.

     This declaration sits inside the combined :root / panel / ink selector, which
     is what makes it flip: per rule 2 a custom property referencing another is
     substituted where it is DECLARED, so being declared once per scope is what
     gives an invalid field the on-purple red inside a panel rather than the
     white-surface one. Declared at :root alone it would freeze to #E53935
     everywhere, which measures 1.38:1 on the panel. */
  --destructive: var(--cg-danger);
}
/* The primary action on purple. Operator decision, 2026-08-12, issue #41.

   --cg-primary IS the panel surface: --cg-surface-panel is var(--cg-primary).
   So mapping --primary to it inside the panel scope gave a button the exact
   colour of the ground behind it. Measured before the fix: button background
   rgb(90,71,240), panel background rgb(90,71,240). Contrast against the surface
   1:1. The label stayed white so the text was readable, but the control had no
   shape at all.

   Lime is the brand's other action colour and the natural "go" on purple, so
   that is what a primary becomes here, with ink on top rather than white.

   Both flipped surfaces, not just the panel. I first wrote this for the panel
   only, on the assumption that purple keeps its shape against ink. The assertion
   said otherwise: purple on #222 measures 2.72:1, also under the 3:1 floor. So
   the reported bug was two of three surfaces and only one had been noticed.

   The rule that falls out is simple enough to hold in your head: purple on white,
   lime on either dark brand surface. Lime on ink measures about 10:1.

   Guarded by an assertion that measures the button against the surface BEHIND it
   in all three scopes. The suite already had two tests here and neither could see
   this: one asserts the button renders the brand colour in every scope, which is
   satisfied by exactly the behaviour that caused the bug, and the other compares
   the label against the button rather than the button against its ground. */
[data-cg-surface="panel"],
[data-cg-surface="ink"] {
  --primary: var(--cg-secondary);
  --primary-foreground: var(--cg-text-on-accent);
}


/*
  Backgrounds that do not flip on their own.

  Every shadcn *foreground* maps to a token the surface blocks redefine, so text
  turns white inside a panel automatically. Four backgrounds do not, because the
  brand tokens behind them describe the page rather than a container:

    --background -> --cg-surface-page      static
    --muted      -> --cg-surface-subtle    static
    --accent     -> --cg-surface-subtle    static
    --secondary  -> --cg-surface-control   static

  Half of each pair follows the surface and half does not, so they collide
  exactly where the surface changes. An outline button on a panel rendered white
  text on a white pill: 1:1 contrast, the label completely invisible, and
  nothing errored. Same shape for bg-muted, bg-secondary and bg-accent.

  So each scope gets the four named explicitly, using tokens that exist in that
  scope. "Background" inside a container means that container, not the page.

  The exact choices below are a design call as much as a fix, and worth a
  reviewer's eye: on the panel these resolve to transparent, so the purple shows
  through, which is what an outline control should do anyway.
*/
[data-cg-surface="panel"] {
  --background: var(--cg-surface-panel);
  --muted: var(--cg-surface-card);
  --accent: var(--cg-surface-card);
  --secondary: var(--cg-surface-card);
}

[data-cg-surface="ink"] {
  --background: var(--cg-surface-code);
  --muted: var(--cg-surface-page-alt);
  --accent: var(--cg-surface-page-alt);
  --secondary: var(--cg-surface-page-alt);
}
