/* ==========================================================================
   EXXAT DESIGN SYSTEM — create-exxat-app starter globals.css
   ------------------------------------------------------------------
   Canonical theme tokens, custom variants, and base-layer styles live
   in `@exxatdesignux/ui/globals.css`. Synced from apps/web via
   `pnpm sync-ui-template` — sidebar utilities below; @source paths are
   template-specific.

   Standard: WCAG 2.1 Level AA
   ========================================================================== */

@import "@exxatdesignux/ui/globals.css";


/* App shell — scroll lives in `[data-page-scroll]` / hub insets, not the document. */
@layer base {
  html,
  body {
    height: 100%;
    overflow: hidden;
  }

  #root {
    display: flex;
    flex-direction: column;
    height: 100dvh;
    max-height: 100dvh;
    min-height: 0;
    overflow: hidden;
  }
}

/* This app's own files (templates auto-scan these regardless of CSS file location). */
@source "../../components";
@source "../../contexts";
@source "../../hooks";
@source "../../lib";
@source "../../stores";
@source "../";

/* Sidebar nav labels — beat stale package dist that still applies truncate. */
@layer utilities {
  /* Use data-sidebar (stable) — TooltipTrigger asChild on collapsible parents
     overwrites data-slot to tooltip-trigger, skipping slot-based rules. */
  [data-sidebar="menu-button"]:not([data-size="lg"]) {
    overflow: visible !important;
    height: auto !important;
    min-height: 1.75rem !important;
    align-items: center !important;
    padding-block: var(--exxat-spacing-1) !important;
    padding-inline: var(--exxat-spacing-2) !important;
  }

  [data-sidebar="menu-button"] > span[aria-hidden="true"] i,
  [data-sidebar="menu-button"] > i[aria-hidden="true"] {
    display: block;
    line-height: 1;
  }

  [data-sidebar-nav-label] {
    overflow: visible !important;
    white-space: normal !important;
    text-overflow: clip !important;
    word-break: break-word;
  }

  /* Child rows — flex centering; no translate nudge into the guide line. */
  [data-slot="sidebar-menu-sub-button"] {
    overflow: visible !important;
    height: auto !important;
    width: 100% !important;
    flex: 1 1 0% !important;
    min-width: 0 !important;
    align-items: center !important;
    box-sizing: border-box !important;
    translate: none !important;
    padding-block: var(--exxat-spacing-1) !important;
    padding-inline: var(--exxat-spacing-2) !important;
  }

  /* Primary sidebar collapsible — indent sub-menu rows; no vertical guide (overlaps icons). */
  [data-sidebar="menu-item"].group\/collapsible {
    position: relative;
  }

  [data-sidebar="menu-item"].group\/collapsible::before {
    content: none !important;
    display: none !important;
  }

  [data-slot="sidebar-menu-sub"] {
    margin-inline: 0 !important;
    margin-inline-start: var(--exxat-spacing-3) !important;
    padding-inline-end: 0 !important;
    padding-inline-start: 0 !important;
    translate: none !important;
    width: calc(100% - var(--exxat-spacing-3)) !important;
    max-width: 100% !important;
    box-sizing: border-box !important;
    border-inline-start: none !important;
  }

  /* Nested collapsible inside a sub-menu (e.g. Compliance under Program). */

  [data-slot="outline-tree-menu-item"]:has(
      > .group\/collapsible[data-state="open"] [data-slot="outline-tree-sub"]
    ),
  li:has(> .group\/collapsible[data-state="open"] [data-slot="outline-tree-sub"]) {
    position: relative !important;
  }

  [data-slot="outline-tree-menu-item"]:has(
      > .group\/collapsible[data-state="open"] [data-slot="outline-tree-sub"]
    )::before,
  li:has(> .group\/collapsible[data-state="open"] [data-slot="outline-tree-sub"])::before {
    content: "";
    position: absolute;
    left: calc(
      var(--outline-tree-row-padding-x) + var(--outline-tree-depth, 0) *
        var(--outline-tree-depth-step) + var(--outline-tree-chevron-half)
    );
    top: var(--outline-tree-guide-overhang);
    bottom: calc(-1 * var(--outline-tree-guide-overhang));
    border-left: 1px solid var(--sidebar-border);
    pointer-events: none;
    z-index: 0;
  }

  [data-slot="secondary-panel"] [data-slot="outline-tree-menu-item"]:has(
      > .group\/collapsible[data-state="open"] [data-slot="outline-tree-sub"]
    )::before,
  [data-slot="secondary-panel"]
    li:has(> .group\/collapsible[data-state="open"] [data-slot="outline-tree-sub"])::before {
    content: none !important;
    display: none !important;
  }

  [data-slot="outline-tree-sub"][data-guide-layout="chevronRail"] {
    margin-inline: 0 !important;
    padding-inline: 0 !important;
    width: 100% !important;
    min-width: 0 !important;
    box-sizing: border-box !important;
    border-inline-start: none !important;
  }

  [data-slot="sidebar-menu-sub-item"] {
    display: flex !important;
    align-items: center !important;
    width: 100% !important;
    max-width: 100% !important;
  }

  [data-slot="sidebar-menu-sub-item"].group\/collapsible-sub {
    flex-direction: column !important;
    align-items: stretch !important;
  }

  [data-sidebar="nav-sub-badge"] {
    position: static !important;
    transform: none !important;
    flex-shrink: 0 !important;
    align-self: center !important;
    margin-inline-end: var(--exxat-spacing-2) !important;
    pointer-events: none !important;
  }

  /*
   * App shell row — Ask Leo is a sibling rail on the right. SidebarInset
   * horizontal margins (mx-2 / collapsed ms-2) plus w-full overflow the outlet
   * wrapper and clip the main card's trailing rounded-xl — move gutters to
   * padding on [data-app-shell-main] instead.
   */
  [data-app-shell-row] [data-slot="sidebar-inset"] {
    margin-inline: 0 !important;
    width: 100%;
    max-width: 100%;
  }

  [data-app-shell-workspace-body] > [data-slot="secondary-panel"]:not([data-overlay]),
  [data-app-shell-workspace-body] [data-slot="sidebar-inset"] {
    margin-block-end: 0 !important;
    margin-block-start: 0 !important;
  }

  [data-app-shell-main] {
    margin-inline-start: 0;
    padding-inline-start: 0;
    padding-inline-end: 0.5rem;
  }

  /*
   * Scope rail closed (record detail, dashboards, etc.) — main column needs a
   * start gutter so the inset card is not flush to the workspace edge.
   */
  [data-app-shell-workspace-body]:not(:has(
      [data-slot="secondary-panel"][data-state="open"]:not([data-overlay])
    ))
    [data-app-shell-main] {
    padding-inline-start: 0.5rem;
  }

  /* Primary nav unmounted (focus shell) or flyout-only — no sidebar-gap spacer. */
  [data-app-shell-row]:not(:has([data-slot="sidebar"]:not([data-nav-flyout="true"])))
    [data-app-shell-main],
  [data-app-shell-row]:has([data-slot="sidebar"][data-nav-flyout="true"]) [data-app-shell-main] {
    padding-inline-start: 0.5rem;
  }

  @media (min-width: 768px) {
    [data-app-shell-main] {
      padding-inline-end: 0.5rem;
    }
  }

  [data-app-shell-workspace-body]:has(
    [data-slot="secondary-panel"][data-state="open"]:not([data-overlay])
  ) [data-app-shell-main] {
    padding-inline-start: 0;
  }

  /* Docked Ask Leo panel only — set when the right rail claims flex width.
     Floating window mode must leave this attribute unset so main does not shift. */
  [data-app-shell-row][data-ask-leo-open="true"] [data-app-shell-main] {
    padding-inline-end: 0;
  }

  [data-shell-utility-bar-full] [data-app-shell-workspace] {
    padding-top: 0;
  }

  [data-shell-utility-bar-full] [data-app-shell-row] [data-slot="sidebar"]:not([data-nav-flyout="true"]) [data-slot="sidebar-container"] {
    /* Clear utility bar (`--shell-utility-bar-height`) + optional full-bleed system banner above it. */
    top: calc(var(--shell-utility-bar-height) + var(--shell-system-banner-height, 0px));
  }

  /*
   * Compact shell density.
   *
   * Bar / rail / sticky headers share `--shell-utility-bar-height` (2.625rem).
   * Compact also drops the SiteHeader row (`components/compact-header-slot.tsx`).
   *
   * Icon buttons stay size-8 inside the bar (above the 24px target floor).
   */
  [data-shell-density="compact"] [data-slot="sidebar-group"] {
    padding-block: var(--exxat-spacing-1);
  }

  /*
   * No cards in this variant — docked rails / inset only.
   *
   * Flush is source-level on `SidebarInset` + docked secondary / Ask Leo; these
   * rules stay as belt-and-suspenders. Overlay flyouts keep sheet chrome.
   */
  [data-shell-density="compact"] [data-slot="sidebar-inset"],
  [data-shell-density="compact"] [data-slot="secondary-panel"]:not([data-overlay]),
  [data-shell-density="compact"] [data-slot="ask-leo-panel"]:not([data-overlay]) {
    margin-inline: 0;
    margin-block: 0;
    border-radius: 0;
    box-shadow: none;
  }

  [data-shell-density="compact"] [data-slot="secondary-panel"][data-overlay],
  [data-shell-density="compact"] [data-slot="ask-leo-panel"][data-overlay],
  [data-shell-density="compact"]
    [data-slot="sidebar"][data-nav-flyout="true"]
    [data-slot="sidebar-container"] {
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-sheet-flyout);
  }

  /*
   * Icon rail only — expanded secondary / Ask Leo use `ResizableHandle`
   * (1px `bg-border` + optional grip). Applying a border on expanded rails
   * doubles the separator next to the handle.
   */
  [data-shell-density="compact"]
    [data-slot="secondary-panel"][data-layout="icon"]:not([data-overlay]) {
    border-inline-end: 1px solid var(--sidebar-border);
  }

  [data-shell-density="compact"]
    [data-slot="ask-leo-panel"][data-own-size="true"]:not([data-overlay]) {
    border-inline-start: 1px solid var(--sidebar-border);
  }

  /*
   * The bar sits on the page, not on the rail.
   *
   * `bg-sidebar` (brand tint) is right for the other variants, where the bar is
   * chrome wrapped around a floating canvas. Compact has no gutter and no card,
   * so the bar is the top edge of the page itself and takes the page's own
   * surface. `--background`, not literal white, so dark mode and the contrast
   * modes follow.
   *
   * The bottom border matters more now: the bar and canvas share a colour, so
   * this rule is the only thing separating them. The other variants get that
   * separation free from the gutter and from `SiteHeader`'s own border.
   */
  [data-shell-density="compact"] [data-slot="utility-bar"] {
    background-color: var(--background);
    border-block-end: 1px solid var(--sidebar-border);
  }

  /*
   * The last gutters. Zeroing the inset card's own margin is not enough: the
   * shell keeps a 0.5rem gutter on `[data-app-shell-main]` (trailing always,
   * leading whenever the secondary rail is closed or the primary rail is a
   * flyout), and the fixed rail is inset from the bottom by
   * `--app-shell-inset-y`. Compact is edge-to-edge, so all three go.
   *
   * `!important` because the leading-gutter rules qualify on `:has()` state and
   * reach (0,5,0) specificity — the same reason the `sidebar-inset` margin
   * override above uses it. Setting the variable on the row rather than on this
   * ancestor is deliberate: `[data-app-shell-row]` declares it on itself, and a
   * local declaration beats an inherited one whatever the ancestor says.
   */
  [data-shell-density="compact"] [data-app-shell-main] {
    padding-inline: 0 !important;
  }

  [data-shell-density="compact"] [data-app-shell-row] {
    --app-shell-inset-y: 0rem;
  }

  /* Compact also halves the radius scale. That override lives in the package
     (`html[data-shell-density="compact"]`, beside the `data-text-size` blocks)
     and arrives through the import above. It has to be unlayered to outrank the
     unlayered `:root` that declares `--radius`. */

  /* ── Product glyph tiles ─────────────────────────────────────────────────
     One product mark, worn the same way by the switcher rows and the home
     page. `--product-brand` is set inline per product by `productTileStyle`;
     everything about how it is worn is decided here.

     The tile is the brand colour, undiluted, with a white glyph on it. The
     colour is what a row is recognised by before any label is read, so it has
     to be the brand and not a wash of it: the tile used to be the hue at
     lightness 0.95 with chroma cut to a third, which is a pale tint in either
     theme and reads as absence of colour rather than as this product's colour.

     Lightness is clamped rather than replaced, so a brand keeps its own weight
     — Surveys stays a vivid orange instead of flattening to brown — and only
     the ends of the scale are taken away. Those ends are the ones white cannot
     sit on: a brand palette promises nothing about lightness, Settings →
     Appearance will accept a pale yellow, and white on that measures 1.3:1.
     The window holds every brand, house or tenant, at 3.6:1 or better against
     the glyph, over the 3:1 that WCAG 1.4.11 asks of a graphic. Measured by
     `scripts/icon-contrast-probe.mjs`, which exists because axe cannot see a
     Font Awesome glyph: it is drawn from a pseudo-element, and
     `color-contrast` skips pseudo-element text.

     Dark mode raises the floor. A dark brand on a dark panel is a hole in the
     row rather than a mark on it. */
  .product-tile {
    background: oklch(from var(--product-brand) clamp(0.42, l, 0.6) c h);
  }

  .product-tile-glyph {
    color: oklch(1 0 0);
  }

  .dark .product-tile {
    background: oklch(from var(--product-brand) clamp(0.5, l, 0.6) c h);
  }
}

/* This app's own files (Tailwind skip binary assets). */
