/* RiptideOS.UI Components - Pre-built Tailwind CSS */

/* Cascade-layer order. `riptide` is declared last as a dedicated priority layer
   for Riptide's hand-authored component CSS (the high-specificity attribute-selector
   rules below) — those need to win against consumer Tailwind utilities and
   preflight resets. Tailwind's bulk output is imported into its native layers
   so Riptide's emitted utilities tie with the consumer's instead of beating them
   (which was the cause of #318). Consumer overrides work normally via
   specificity or by loading their stylesheet after ours. */
@layer properties, theme, base, components, utilities, riptide;

@import 'tailwindcss';
/* tw-animate.css uses @utility (a Tailwind v4 source directive) which cannot
   be nested inside a layer. Imported unlayered; its utilities land in the
   default `utilities` layer. Anything in tw-animate that absolutely must win
   should use the doubled-data-attribute trick or live inside @layer riptide below. */
@import './tw-animate.css';

/* Configure source paths for scanning Razor files */
@source "../../Components";

/* Safelist the bare chat utilities so consumers of the prebuilt CSS can
   apply them directly (component sources only use the variant forms). */
@source inline("shimmer scroll-fade-x");

/* Component structural variables & default theme tokens */
/* Alert defaults let users drop in a raw tweakcn/shadcn theme without defining
   the Riptide-specific --alert-* variables. Un-layered :root in the user's theme
   automatically overrides these @layer base values via CSS cascade. */
@layer base {
  :root {
    --sidebar-width: 16rem;
    --sidebar-width-mobile: 18rem;
    --sidebar-width-icon: 3rem;

    /* ── Sidebar Menu Button ── */
    --sidebar-menu-button-height: auto;
    --sidebar-menu-button-px: 0.5rem;
    --sidebar-menu-button-py: 0.375rem;
    --sidebar-menu-button-font-size: 0.875rem;
    --sidebar-menu-button-line-height: 1.25rem;
    --sidebar-menu-button-font-size-sm: 0.75rem;
    --sidebar-menu-button-line-height-sm: 1rem;
    --sidebar-menu-button-font-size-lg: 1rem;
    --sidebar-menu-button-line-height-lg: 1.5rem;
    --sidebar-menu-button-font-weight: 400;
    --sidebar-menu-button-active-font-weight: 500;
    --sidebar-menu-button-active-bg: var(--sidebar-accent);
    --sidebar-menu-button-active-color: var(--sidebar-accent-foreground);
    --sidebar-menu-button-active-shadow: none;
    --sidebar-menu-button-radius: 0.375rem;
    --sidebar-menu-button-gap: 0.5rem;
    --sidebar-menu-button-icon-size: 1rem;
    --sidebar-menu-button-collapsed-size: 2rem;
    --sidebar-menu-button-collapsed-padding: 0.5rem;
    --sidebar-menu-button-collapsed-padding-lg: 0.75rem;

    /* ── Sidebar Group ── */
    --sidebar-group-py: 0.5rem;
    --sidebar-group-px: 0.5rem;

    /* ── Sidebar Group Label ── */
    --sidebar-group-label-height: 2rem;
    --sidebar-group-label-px: 0.5rem;
    --sidebar-group-label-font-size: 0.75rem;
    --sidebar-group-label-line-height: 1rem;
    --sidebar-group-label-font-weight: 500;
    --sidebar-group-label-radius: 0.375rem;
    --sidebar-group-label-icon-size: 1rem;

    /* ── Sidebar Menu ── */
    --sidebar-menu-gap: 0.25rem;

    /* ── Sidebar Header ── */
    --sidebar-header-py: 0.5rem;
    --sidebar-header-px: 0.5rem;
    --sidebar-header-gap: 0.5rem;

    /* ── Sidebar Header Content ── */
    --sidebar-header-content-gap: 0.5rem;
    --sidebar-header-content-py: 0.5rem;
    --sidebar-header-content-px: 0.5rem;

    /* ── Sidebar Footer ── */
    --sidebar-footer-py: 0.5rem;
    --sidebar-footer-px: 0.5rem;
    --sidebar-footer-gap: 0.5rem;

    /* ── Sidebar Content ── */
    --sidebar-content-py: 0.5rem;
    --sidebar-content-px: 0.5rem;
    --sidebar-content-gap: 0.5rem;

    /* ── Sidebar Menu Badge ── */
    --sidebar-badge-height: 1.25rem;
    --sidebar-badge-min-width: 1.25rem;
    --sidebar-badge-px: 0.25rem;
    --sidebar-badge-font-size: 0.75rem;
    --sidebar-badge-line-height: 1rem;
    --sidebar-badge-font-weight: 500;
    --sidebar-badge-radius: 0.375rem;
    --sidebar-badge-right: 0.25rem;
    --sidebar-badge-bg: transparent;
    --sidebar-badge-color: var(--sidebar-foreground);

    /* ── Sidebar Sub Menu ── */
    --sidebar-sub-mx: 0.875rem;
    --sidebar-sub-px: 0.625rem;
    --sidebar-sub-py: 0.125rem;
    --sidebar-sub-gap: 0.25rem;

    /* ── Sidebar Sub Menu Button ── */
    --sidebar-sub-button-height: 1.75rem;
    --sidebar-sub-button-px: 0.5rem;
    --sidebar-sub-button-gap: 0.5rem;
    --sidebar-sub-button-radius: 0.375rem;
    --sidebar-sub-button-font-size: 0.875rem;
    --sidebar-sub-button-line-height: 1.25rem;
    --sidebar-sub-button-font-size-sm: 0.75rem;
    --sidebar-sub-button-line-height-sm: 1rem;
    --sidebar-sub-button-icon-size: 1rem;

    /* Default alert colors — override in your theme to customize */
    --alert-success: oklch(0.55 0.20 142);
    --alert-success-foreground: oklch(0.30 0.09 142);
    --alert-success-bg: oklch(0.993 0.003 142);
    --alert-info: oklch(0.50 0.20 255);
    --alert-info-foreground: oklch(0.30 0.10 255);
    --alert-info-bg: oklch(0.993 0.003 255);
    --alert-warning: oklch(0.68 0.18 55);
    --alert-warning-foreground: oklch(0.35 0.10 55);
    --alert-warning-bg: oklch(0.995 0.003 55);
    --alert-danger: var(--destructive, oklch(0.55 0.22 27));
    --alert-danger-foreground: var(--destructive-foreground, oklch(0.30 0.12 27));
    --alert-danger-bg: oklch(0.993 0.003 27);
  }

  .dark {
    --alert-success: oklch(0.60 0.18 142);
    --alert-success-foreground: oklch(0.90 0.06 142);
    --alert-success-bg: oklch(0.18 0.008 142);
    --alert-info: oklch(0.55 0.18 255);
    --alert-info-foreground: oklch(0.90 0.05 255);
    --alert-info-bg: oklch(0.18 0.008 255);
    --alert-warning: oklch(0.65 0.16 55);
    --alert-warning-foreground: oklch(0.92 0.06 55);
    --alert-warning-bg: oklch(0.19 0.008 55);
    --alert-danger: var(--destructive, oklch(0.55 0.20 27));
    --alert-danger-foreground: var(--destructive-foreground, oklch(0.90 0.06 27));
    --alert-danger-bg: oklch(0.18 0.008 27);
  }
}

/* Tailwind v4 CSS-first theme configuration.
   Uses @theme inline so var() references resolve at the utility call site. */
@theme inline {
  /* Colors */
  --color-border: var(--border);
  --color-input: var(--input);
  --color-ring: var(--ring);
  --color-background: var(--background);
  --color-foreground: var(--foreground);
  --color-primary: var(--primary);
  --color-primary-foreground: var(--primary-foreground);
  --color-secondary: var(--secondary);
  --color-secondary-foreground: var(--secondary-foreground);
  --color-destructive: var(--destructive);
  --color-destructive-foreground: var(--destructive-foreground);
  --color-muted: var(--muted);
  --color-muted-foreground: var(--muted-foreground);
  --color-accent: var(--accent);
  --color-accent-foreground: var(--accent-foreground);
  --color-popover: var(--popover);
  --color-popover-foreground: var(--popover-foreground);
  --color-card: var(--card);
  --color-card-foreground: var(--card-foreground);
  --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);
  --color-alert-success: var(--alert-success);
  --color-alert-success-foreground: var(--alert-success-foreground);
  --color-alert-success-bg: var(--alert-success-bg);
  --color-alert-info: var(--alert-info);
  --color-alert-info-foreground: var(--alert-info-foreground);
  --color-alert-info-bg: var(--alert-info-bg);
  --color-alert-warning: var(--alert-warning);
  --color-alert-warning-foreground: var(--alert-warning-foreground);
  --color-alert-warning-bg: var(--alert-warning-bg);
  --color-alert-danger: var(--alert-danger);
  --color-alert-danger-foreground: var(--alert-danger-foreground);
  --color-alert-danger-bg: var(--alert-danger-bg);

  /* Fonts */
  --font-sans: var(--font-sans, ui-sans-serif, system-ui, sans-serif);
  --font-serif: var(--font-serif, ui-serif, Georgia, serif);
  --font-mono: var(--font-mono, ui-monospace, monospace);

  /* Border Radius */
  --radius-lg: var(--radius);
  --radius-md: calc(var(--radius) * 0.8);
  --radius-sm: calc(var(--radius) * 0.6);

  /* Tracking (letter-spacing) — relative to --tracking-normal from the user's theme */
  --tracking-tighter: calc(var(--tracking-normal) - 0.05em);
  --tracking-tight: calc(var(--tracking-normal) - 0.025em);
  --tracking-normal: var(--tracking-normal);
  --tracking-wide: calc(var(--tracking-normal) + 0.025em);
  --tracking-wider: calc(var(--tracking-normal) + 0.05em);
  --tracking-widest: calc(var(--tracking-normal) + 0.1em);
}

/* Global theme defaults. These are resets rather than overrides, so they belong in
   `base` where border/background utilities beat them normally on specificity. They
   must stay OUT of `@layer riptide`: as `riptide.utilities` the universal `*` selector
   outranked every border-* utility (layer priority ignores specificity), flattening
   all border colours to --border — see #398. */
@layer base {
  * {
    border-color: var(--border);
  }

  body {
    background-color: var(--background);
    color: var(--foreground);
    font-family: var(--font-sans);
    letter-spacing: var(--tracking-normal, 0);
  }
}

/* All component utility/component layer blocks live inside `@layer riptide` so they win
   the cascade-layer parity against consumer Tailwind output. The inner @layer
   declarations (base/components/utilities) become sublayers of riptide. */
@layer riptide {

/* Required for keyboard navigation visual feedback in Select/Combobox/DropdownMenu */
@layer components {
  [role="option"][data-focused="true"] {
    background-color: var(--accent);
    color: var(--accent-foreground);
  }
}

/* Riptide Sidebar root visibility — needs to win against consumer Tailwind cascade.
   The Sidebar <aside> uses `hidden md:flex` Tailwind utilities to hide on mobile
   and show on desktop, but those utilities can tie or lose to consumer rules
   depending on stylesheet load order (the bug seen in #308). This higher-
   specificity attribute selector inside @layer riptide is authoritative regardless. */
@layer components {
  aside[data-variant][data-side] { display: none; }
  @media (min-width: 768px) {
    aside[data-variant][data-side] { display: flex; }
  }
}

/* ── Sidebar component layout/sizing via CSS variables ──
   Replaces hardcoded Tailwind utility classes with customizable variables.
   Consumers override these by setting variables on :root or a wrapper element. */
@layer components {
  /* ── Menu Button ── */
  [data-sidebar="menu-button"] {
    padding: var(--sidebar-menu-button-py) var(--sidebar-menu-button-px);
    font-size: var(--sidebar-menu-button-font-size);
    line-height: var(--sidebar-menu-button-line-height);
    border-radius: var(--sidebar-menu-button-radius);
    gap: var(--sidebar-menu-button-gap);
    height: var(--sidebar-menu-button-height);
    font-weight: var(--sidebar-menu-button-font-weight);
  }

  [data-sidebar="menu-button"][data-size="sm"] {
    font-size: var(--sidebar-menu-button-font-size-sm);
    line-height: var(--sidebar-menu-button-line-height-sm);
  }

  [data-sidebar="menu-button"][data-size="lg"] {
    font-size: var(--sidebar-menu-button-font-size-lg);
    line-height: var(--sidebar-menu-button-line-height-lg);
  }

  [data-sidebar="menu-button"] > svg {
    width: var(--sidebar-menu-button-icon-size);
    height: var(--sidebar-menu-button-icon-size);
  }

  [data-sidebar="menu-button"][data-active="true"] {
    font-weight: var(--sidebar-menu-button-active-font-weight);
    background-color: var(--sidebar-menu-button-active-bg);
    color: var(--sidebar-menu-button-active-color);
    box-shadow: var(--sidebar-menu-button-active-shadow);
  }

  /* Menu Button — collapsible icon mode */
  [data-collapsible="icon"] [data-sidebar="menu-button"] {
    width: var(--sidebar-menu-button-collapsed-size);
    height: var(--sidebar-menu-button-collapsed-size);
    padding: var(--sidebar-menu-button-collapsed-padding);
    gap: 0;
  }

  [data-collapsible="icon"] [data-sidebar="menu-button"][data-size="lg"] {
    padding: var(--sidebar-menu-button-collapsed-padding-lg);
  }

  /* ── Group ── */
  [data-sidebar="group"] {
    padding: var(--sidebar-group-py) var(--sidebar-group-px);
  }

  [data-collapsible="icon"] [data-sidebar="group"] {
    padding: 0;
  }

  /* ── Group Label ── */
  [data-sidebar="group-label"] {
    height: var(--sidebar-group-label-height);
    padding-left: var(--sidebar-group-label-px);
    padding-right: var(--sidebar-group-label-px);
    font-size: var(--sidebar-group-label-font-size);
    line-height: var(--sidebar-group-label-line-height);
    font-weight: var(--sidebar-group-label-font-weight);
    border-radius: var(--sidebar-group-label-radius);
  }

  [data-sidebar="group-label"] > svg {
    width: var(--sidebar-group-label-icon-size);
    height: var(--sidebar-group-label-icon-size);
  }

  [data-collapsible="icon"] [data-sidebar="group-label"] {
    margin-top: calc(-1 * var(--sidebar-group-label-height));
    padding-left: 0;
    padding-right: 0;
  }

  /* ── Menu ── */
  [data-sidebar="menu"] {
    gap: var(--sidebar-menu-gap);
  }

  /* ── Header ── */
  [data-sidebar="header"] {
    padding: var(--sidebar-header-py) var(--sidebar-header-px);
    gap: var(--sidebar-header-gap);
  }

  /* ── Header Content ── */
  [data-sidebar="header-content"] {
    gap: var(--sidebar-header-content-gap);
    padding: var(--sidebar-header-content-py) var(--sidebar-header-content-px);
  }

  [data-collapsible="icon"] [data-sidebar="header-content"] {
    padding: 0;
  }

  /* ── Footer ── */
  [data-sidebar="footer"] {
    padding: var(--sidebar-footer-py) var(--sidebar-footer-px);
    gap: var(--sidebar-footer-gap);
  }

  /* ── Content ── */
  [data-sidebar="content"] {
    padding: var(--sidebar-content-py) var(--sidebar-content-px);
    gap: var(--sidebar-content-gap);
  }

  /* ── Menu Badge ── */
  [data-sidebar="menu-badge"] {
    height: var(--sidebar-badge-height);
    min-width: var(--sidebar-badge-min-width);
    padding-left: var(--sidebar-badge-px);
    padding-right: var(--sidebar-badge-px);
    font-size: var(--sidebar-badge-font-size);
    line-height: var(--sidebar-badge-line-height);
    font-weight: var(--sidebar-badge-font-weight);
    border-radius: var(--sidebar-badge-radius);
    right: var(--sidebar-badge-right);
    background-color: var(--sidebar-badge-bg);
    color: var(--sidebar-badge-color);
  }

  /* ── Menu Sub ── */
  [data-sidebar="menu-sub"] {
    margin-left: var(--sidebar-sub-mx);
    margin-right: var(--sidebar-sub-mx);
    padding-left: var(--sidebar-sub-px);
    padding-right: var(--sidebar-sub-px);
    padding-top: var(--sidebar-sub-py);
    padding-bottom: var(--sidebar-sub-py);
    gap: var(--sidebar-sub-gap);
  }

  /* ── Menu Sub Button ── */
  [data-sidebar="menu-sub-button"] {
    height: var(--sidebar-sub-button-height);
    padding-left: var(--sidebar-sub-button-px);
    padding-right: var(--sidebar-sub-button-px);
    gap: var(--sidebar-sub-button-gap);
    border-radius: var(--sidebar-sub-button-radius);
    font-size: var(--sidebar-sub-button-font-size);
    line-height: var(--sidebar-sub-button-line-height);
  }

  [data-sidebar="menu-sub-button"][data-size="sm"] {
    font-size: var(--sidebar-sub-button-font-size-sm);
    line-height: var(--sidebar-sub-button-line-height-sm);
  }

  [data-sidebar="menu-sub-button"] > svg {
    width: var(--sidebar-sub-button-icon-size);
    height: var(--sidebar-sub-button-icon-size);
  }
}

/* DataGrid theming — all visual state (borders, hover, selected, pinned
   backgrounds) lives here in CSS. C# only handles structure (padding,
   alignment, z-index, separators). This separation prevents conflicts
   between Tailwind utilities and CSS overrides.

   Bottom borders are on cells (not rows) so they stay visible under
   sticky/pinned cells. This frees box-shadow exclusively for focus rings. */
@layer utilities {
  /* ── Cell Borders ──
     Bottom border on every cell so borders stay visible under sticky cells. */
  .group\/row > td,
  .group\/row > th {
    border-bottom: 1px solid var(--border);
  }

  /* ── Pinned Backgrounds ──
     Pinned cells inherit the row's background for opaque sticky coverage. */
  .group\/row > [data-pinned] {
    background-color: inherit;
  }

  /* ── Hover ──
     Opaque tint on ALL body cells — identical for pinned and non-pinned. */
  .group\/row:hover > td {
    background-color: color-mix(in oklab, var(--muted) 50%, var(--background));
  }

  /* ── Selected ──
     Solid muted on ALL body cells. Ordered after hover so source order wins.
     The row itself also gets the background so the <tr> (bg-background) can't
     bleed through under sticky cells as a visible white line. */
  .group\/row[aria-selected="true"] {
    background-color: var(--muted);
  }

  .group\/row[aria-selected="true"] > td {
    background-color: var(--muted);
  }
}

/* DataGrid keyboard navigation — focus ring drawn per-cell.
   Each cell renders its own top/bottom ring segment via inset box-shadow so
   the ring is consistent across pinned (sticky) and non-pinned cells alike.

   The focused row uses position: relative + z-index ONLY on :focus so the ring
   paints above adjacent rows. We must NOT set position: relative permanently
   because Chromium has a bug where position: relative on <tr> hides cell borders
   under border-collapse: collapse. */
@layer utilities {
  [role="row"][tabindex="0"]:focus {
    position: relative;
    z-index: 10;
  }

  [role="row"][tabindex="0"]:focus > [role="gridcell"] {
    box-shadow: inset 0 2px 0 0 var(--ring), inset 0 -2px 0 0 var(--ring);
  }

  [role="row"][tabindex="0"]:focus > [role="gridcell"]:first-child {
    box-shadow: inset 2px 0 0 0 var(--ring), inset 0 2px 0 0 var(--ring), inset 0 -2px 0 0 var(--ring);
  }

  [role="row"][tabindex="0"]:focus > [role="gridcell"]:last-child {
    box-shadow: inset -2px 0 0 0 var(--ring), inset 0 2px 0 0 var(--ring), inset 0 -2px 0 0 var(--ring);
  }

  [role="row"][tabindex="0"]:focus > [role="gridcell"]:only-child {
    box-shadow: inset 2px 0 0 0 var(--ring), inset -2px 0 0 0 var(--ring), inset 0 2px 0 0 var(--ring), inset 0 -2px 0 0 var(--ring);
  }
}



@layer utilities {
  /* Grid animation utilities for Accordion/Collapsible */
  .grid-rows-\[0fr\] {
    grid-template-rows: 0fr;
  }

  .grid-rows-\[1fr\] {
    grid-template-rows: 1fr;
  }

  .data-\[state\=open\]\:grid-rows-\[1fr\][data-state="open"] {
    grid-template-rows: 1fr;
  }

  .transition-\[grid-template-rows\] {
    transition-property: grid-template-rows;
    transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
    transition-duration: var(--tw-duration, var(--default-transition-duration));
  }
}

/* AspectRatio component - content wrapper fills parent and children fill wrapper */
/* Using utilities layer for higher specificity */
@layer utilities {
  .aspect-ratio-content {
    position: absolute !important;
    inset: 0 !important;
    width: 100% !important;
    height: 100% !important;
  }

  .aspect-ratio-content > * {
    width: 100% !important;
    height: 100% !important;
  }
}

/* Rich Text Editor - Headless Quill.js styles */
@layer components {
  /* Container styling - headless mode has no .ql-snow class */
  [data-slot="rich-text-editor"] .ql-container {
    font-family: inherit;
    font-size: inherit;
  }

  /* Editor content area */
  [data-slot="rich-text-editor"] .ql-editor {
    min-height: inherit;
    padding: 0.75rem;
    color: var(--foreground);
    outline: none;
  }

  /* Placeholder styling */
  [data-slot="rich-text-editor"] .ql-editor.ql-blank::before {
    color: var(--muted-foreground) !important;
    font-style: normal;
    left: 0.75rem;
    right: 0.75rem;
    pointer-events: none;
  }

  /* Disabled state */
  [data-slot="rich-text-editor"].opacity-50 .ql-editor {
    cursor: not-allowed;
  }

  /* Inline formatting - reinforce browser defaults */
  [data-slot="rich-text-editor"] .ql-editor strong,
  [data-slot="rich-text-editor"] .ql-editor b {
    font-weight: 700;
  }

  [data-slot="rich-text-editor"] .ql-editor em,
  [data-slot="rich-text-editor"] .ql-editor i {
    font-style: italic;
  }

  [data-slot="rich-text-editor"] .ql-editor u {
    text-decoration: underline;
  }

  [data-slot="rich-text-editor"] .ql-editor s {
    text-decoration: line-through;
  }

  /* Lists */
  [data-slot="rich-text-editor"] .ql-editor ul,
  [data-slot="rich-text-editor"] .ql-editor ol {
    padding-left: 1.5em;
    margin: 0.5em 0;
  }

  [data-slot="rich-text-editor"] .ql-editor ul {
    list-style-type: disc;
  }

  [data-slot="rich-text-editor"] .ql-editor ol {
    list-style-type: decimal;
  }

  [data-slot="rich-text-editor"] .ql-editor li {
    margin: 0.25em 0;
  }

  /* Code block - Quill uses .ql-code-block classes, not <pre> */
  [data-slot="rich-text-editor"] .ql-editor .ql-code-block-container {
    background-color: var(--muted);
    padding: 0.75em 1em;
    border-radius: 0.375rem;
    overflow-x: auto;
    font-family: var(--font-mono, ui-monospace, monospace);
    font-size: 0.875em;
    margin: 0.5em 0;
  }

  [data-slot="rich-text-editor"] .ql-editor .ql-code-block {
    font-family: inherit;
  }

  /* Links */
  [data-slot="rich-text-editor"] .ql-editor a {
    color: var(--primary);
    text-decoration: underline;
  }

  [data-slot="rich-text-editor"] .ql-editor a:hover {
    text-decoration: none;
  }

  /* Paragraphs */
  [data-slot="rich-text-editor"] .ql-editor p {
    margin: 0.5em 0;
  }

  [data-slot="rich-text-editor"] .ql-editor p:first-child {
    margin-top: 0;
  }

  [data-slot="rich-text-editor"] .ql-editor p:last-child {
    margin-bottom: 0;
  }
}

/* Timeline right-aligned content */
@layer components {
  [data-timeline-end] {
    text-align: right;
  }

  /* Flex-column containers (TimelineContent): align children to the right */
  [data-timeline-end] > :where(.flex-col) {
    align-items: flex-end;
    padding-left: 0;
    padding-right: 0.5rem;
  }

  /* Flex-row containers (TimelineHeader): justify items to the right */
  [data-timeline-end] :where(.flex:not(.flex-col)) {
    justify-content: flex-end;
  }
}

/* Rich Text Editor - Block formats that must override Tailwind preflight */
@layer utilities {
  /* Headings - !important required to override Tailwind preflight resets */
  [data-slot="rich-text-editor"] .ql-editor h1 {
    font-size: 2em !important;
    font-weight: 700 !important;
    line-height: 1.2 !important;
    margin-top: 0 !important;
    margin-bottom: 0.5em !important;
  }

  [data-slot="rich-text-editor"] .ql-editor h2 {
    font-size: 1.5em !important;
    font-weight: 600 !important;
    line-height: 1.3 !important;
    margin-top: 0 !important;
    margin-bottom: 0.5em !important;
  }

  [data-slot="rich-text-editor"] .ql-editor h3 {
    font-size: 1.25em !important;
    font-weight: 600 !important;
    line-height: 1.4 !important;
    margin-top: 0 !important;
    margin-bottom: 0.5em !important;
  }

  /* Blockquote - !important required to override Tailwind preflight resets */
  [data-slot="rich-text-editor"] .ql-editor blockquote {
    border-left: 4px solid var(--border) !important;
    padding-left: 1em !important;
    margin: 0.5em 0 !important;
    color: var(--muted-foreground) !important;
    font-style: italic !important;
  }
}

/* NativeSelect chevron — inline SVG that Tailwind v4 cannot extract from arbitrary-value classes */
[data-riptide-native-select] {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-size: 1rem;
  background-position: right 0.5rem center;
}

/* DateRangePicker responsive layout — desktop (≥640px)
   Doubled data-attribute selectors give specificity 0,2,0 which beats single-class Tailwind
   utilities (0,1,0) regardless of source order, keeping these rules inside the layer system. */
@layer utilities {
  @media (min-width: 40rem) {
    [data-drp][data-drp] {
      width: auto;
    }

    [data-drp-body][data-drp-body] {
      flex-direction: row;
    }

    [data-drp-presets][data-drp-presets] {
      /* Position context for the absolute inner scroller */
      position: relative;
      overflow-x: visible;
      border-bottom-width: 0;
      border-right-style: var(--tw-border-style);
      border-right-width: 1px;
      min-width: 140px;
      padding: 0;
    }

    /* Hide the mobile select on desktop */
    [data-drp-presets][data-drp-presets] > [data-drp-presets-select] {
      display: none;
    }

    /* Inner scroller fills the sidebar and scrolls independently of the calendar */
    [data-drp-presets][data-drp-presets] > [data-drp-presets-inner] {
      position: absolute;
      inset: 0;
      display: flex;
      flex-direction: column;
      overflow-y: auto;
      gap: calc(var(--spacing) * 1);
      padding: calc(var(--spacing) * 3);
    }

    [data-drp-presets-label][data-drp-presets-label] {
      display: block;
    }

    [data-drp-calendar][data-drp-calendar] {
      padding: calc(var(--spacing) * 3);
    }

    [data-drp-mobile-nav][data-drp-mobile-nav] {
      display: none;
    }

    [data-drp-desktop-spacer][data-drp-desktop-spacer] {
      display: block;
    }

    [data-drp-calendar-2][data-drp-calendar-2] {
      display: block;
      padding: calc(var(--spacing) * 3);
    }

    [data-drp-cell][data-drp-cell] {
      flex: none;
    }

    [data-drp-preset-btn][data-drp-preset-btn] {
      flex-shrink: 0;
      white-space: normal;
    }

    [data-drp-day-btn][data-drp-day-btn] {
      width: calc(var(--spacing) * 9);
    }
  }
}

/* Global animation disable — add class="riptide-no-animate" to <html> to turn off
   transitions and decorative animations.

   Looping status indicators are exempt: spinners (.animate-spin) and pulse
   (.animate-pulse) communicate ongoing work, not decoration, so freezing them
   would misrepresent state. Add .riptide-animate-keep to exempt anything else. */
@layer utilities {
  .riptide-no-animate *:not(.animate-spin, .animate-pulse, .riptide-animate-keep),
  .riptide-no-animate *:not(.animate-spin, .animate-pulse, .riptide-animate-keep)::before,
  .riptide-no-animate *:not(.animate-spin, .animate-pulse, .riptide-animate-keep)::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

} /* end @layer riptide */

/* Accessibility — respect user's reduced-motion preference.
   Left UNLAYERED on purpose so it cannot be defeated by any layered rule. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

@layer riptide {

/* DynamicForm - Horizontal layout label width via CSS variable */
@layer components {
  [data-orientation="horizontal"] > [data-slot="field-label"] {
    min-width: var(--riptide-label-width, auto);
  }
}

/* Sortable — global styles for ghost/fallback elements created outside the component tree */
@layer utilities {
  .sortable-ghost {
    visibility: hidden;
  }

  .sortable-fallback {
    opacity: 1 !important;
  }
}

/* DashboardGrid - Guide background rendered via ::before pseudo-element.
   JS reads the browser's actual computed column width to build a perfectly
   aligned SVG mask. Row height is fixed so no rounding issues. */
@layer components {
  .riptide-guide-background-grid::before {
    content: '';
    position: absolute;
    top: var(--riptide-grid-pad-top, 0px);
    right: var(--riptide-grid-pad-right, 0px);
    bottom: var(--riptide-grid-pad-bottom, 0px);
    left: var(--riptide-grid-pad-left, 0px);
    pointer-events: none;
    z-index: 0;
    background-color: color-mix(in oklch, var(--foreground) 8%, transparent);
    -webkit-mask-image: var(--riptide-dashboard-guide-svg);
    mask-image: var(--riptide-dashboard-guide-svg);
    -webkit-mask-size: var(--riptide-dashboard-cell-w) var(--riptide-dashboard-cell-h);
    mask-size: var(--riptide-dashboard-cell-w) var(--riptide-dashboard-cell-h);
    -webkit-mask-repeat: repeat;
    mask-repeat: repeat;
  }

  /* Hide widgets until JS has compacted the initial layout */
  [data-positioned="false"] > [data-widget-id] {
    visibility: hidden;
  }

  /* Focus ring on the active widget in editable grids.
     Sets Tailwind's ring variables so the ring composes with the
     existing shadow-sm utility instead of replacing it. */
  [data-editable="true"] [data-widget-id]:focus {
    --tw-ring-offset-shadow: 0 0 0 2px var(--background);
    --tw-ring-shadow: 0 0 0 4px var(--ring);
    z-index: 10;
  }

  /* Active ring on widgets during drag/resize */
  [data-dragging="true"],
  [data-resizing="true"] {
    outline: 2px dashed var(--ring);
    outline-offset: 2px;
  }
}

} /* end @layer riptide */

/* Alert countdown bar animation. Keyframes are not subject to cascade
   layers, so left at top level. */
@keyframes riptide-alert-countdown {
  from { width: 100%; }
  to { width: 0%; }
}

/* Chat utilities (Attachment/Marker/Message). @utility cannot be nested
   inside a layer; these land in the `utilities` layer like tw-animate's. */

/* Animated gradient text sweep for in-progress labels
   (e.g. uploading attachment titles, "is typing..." markers). */
@utility shimmer {
  color: transparent;
  background: linear-gradient(
      90deg,
      var(--muted-foreground) 0%,
      var(--foreground) 50%,
      var(--muted-foreground) 100%
    )
    0 0 / 200% 100%;
  background-clip: text;
  -webkit-background-clip: text;
  animation: riptide-shimmer 2s linear infinite;
}

/* Fades out the horizontal edges of a scroll container
   (e.g. attachment group rows). */
@utility scroll-fade-x {
  mask-image: linear-gradient(
    to right,
    transparent,
    black 1.5rem,
    black calc(100% - 1.5rem),
    transparent
  );
  -webkit-mask-image: linear-gradient(
    to right,
    transparent,
    black 1.5rem,
    black calc(100% - 1.5rem),
    transparent
  );
}

@keyframes riptide-shimmer {
  from { background-position: 200% 0; }
  to { background-position: -200% 0; }
}

/* Extended Tailwind utilities: Spacing scale for min-width, max-width, and min-height */
@layer utilities {
  .min-w-0 { min-width: calc(var(--spacing) * 0); }
  .min-w-1 { min-width: calc(var(--spacing) * 1); }
  .min-w-2 { min-width: calc(var(--spacing) * 2); }
  .min-w-3 { min-width: calc(var(--spacing) * 3); }
  .min-w-4 { min-width: calc(var(--spacing) * 4); }
  .min-w-5 { min-width: calc(var(--spacing) * 5); }
  .min-w-6 { min-width: calc(var(--spacing) * 6); }
  .min-w-8 { min-width: calc(var(--spacing) * 8); }
  .min-w-10 { min-width: calc(var(--spacing) * 10); }
  .min-w-12 { min-width: calc(var(--spacing) * 12); }
  .min-w-16 { min-width: calc(var(--spacing) * 16); }
  .min-w-20 { min-width: calc(var(--spacing) * 20); }
  .min-w-24 { min-width: calc(var(--spacing) * 24); }
  .min-w-28 { min-width: calc(var(--spacing) * 28); }
  .min-w-32 { min-width: calc(var(--spacing) * 32); }
  .min-w-36 { min-width: calc(var(--spacing) * 36); }
  .min-w-40 { min-width: calc(var(--spacing) * 40); }
  .min-w-44 { min-width: calc(var(--spacing) * 44); }
  .min-w-48 { min-width: calc(var(--spacing) * 48); }
  .min-w-52 { min-width: calc(var(--spacing) * 52); }
  .min-w-56 { min-width: calc(var(--spacing) * 56); }
  .min-w-60 { min-width: calc(var(--spacing) * 60); }
  .min-w-64 { min-width: calc(var(--spacing) * 64); }
  .min-w-72 { min-width: calc(var(--spacing) * 72); }
  .min-w-80 { min-width: calc(var(--spacing) * 80); }
  .min-w-96 { min-width: calc(var(--spacing) * 96); }
  .min-w-min { min-width: min-content; }
  .min-w-max { min-width: max-content; }
  .min-w-fit { min-width: fit-content; }
  .min-w-full { min-width: 100%; }

  .max-w-64 { max-width: calc(var(--spacing) * 64); }
  .max-w-72 { max-width: calc(var(--spacing) * 72); }
  .max-w-80 { max-width: calc(var(--spacing) * 80); }
  .max-w-96 { max-width: calc(var(--spacing) * 96); }

  .min-h-16 { min-height: calc(var(--spacing) * 16); }
  .min-h-24 { min-height: calc(var(--spacing) * 24); }
  .min-h-32 { min-height: calc(var(--spacing) * 32); }
  .min-h-48 { min-height: calc(var(--spacing) * 48); }
  .min-h-64 { min-height: calc(var(--spacing) * 64); }
}
