/* 
 * Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
 * See LICENSE in the project root for license information.
 */

@config "../tailwind.config.js";
@import "tailwindcss";
@import "react18-json-view/src/style.css";

/* Smokeball Design Framework brand fonts (DES-631): Inter for body/UI/caption, Poppins for
 * headings, so rendering matches the design system on every platform instead of falling back to
 * Segoe UI. The @font-face rules are copied from @fontsource/inter and @fontsource/poppins
 * (latin + latin-ext subsets, only the weights declared below) rather than @import-ed, because the
 * Tailwind CLI would rewrite the package's relative url()s to paths that resolve nowhere. The
 * root-relative /files/ urls are satisfied by CopyWebpackPlugin (webpack.common.js) in the app
 * and by staticDirs (.storybook/main.ts) in Storybook; publicPath is always "/". Non-latin
 * scripts fall back to the Segoe UI stack. */
/* inter-latin-ext-400-normal */
@font-face {
  font-family: Inter;
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/files/inter-latin-ext-400-normal.woff2) format("woff2"), url(/files/inter-latin-ext-400-normal.woff) format("woff");
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* inter-latin-400-normal */
@font-face {
  font-family: Inter;
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/files/inter-latin-400-normal.woff2) format("woff2"), url(/files/inter-latin-400-normal.woff) format("woff");
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* inter-latin-ext-400-italic */
@font-face {
  font-family: Inter;
  font-style: italic;
  font-display: swap;
  font-weight: 400;
  src: url(/files/inter-latin-ext-400-italic.woff2) format("woff2"), url(/files/inter-latin-ext-400-italic.woff) format("woff");
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* inter-latin-400-italic */
@font-face {
  font-family: Inter;
  font-style: italic;
  font-display: swap;
  font-weight: 400;
  src: url(/files/inter-latin-400-italic.woff2) format("woff2"), url(/files/inter-latin-400-italic.woff) format("woff");
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* inter-latin-ext-600-normal */
@font-face {
  font-family: Inter;
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/files/inter-latin-ext-600-normal.woff2) format("woff2"), url(/files/inter-latin-ext-600-normal.woff) format("woff");
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* inter-latin-600-normal */
@font-face {
  font-family: Inter;
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/files/inter-latin-600-normal.woff2) format("woff2"), url(/files/inter-latin-600-normal.woff) format("woff");
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* poppins-latin-ext-600-normal */
@font-face {
  font-family: Poppins;
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/files/poppins-latin-ext-600-normal.woff2) format("woff2"), url(/files/poppins-latin-ext-600-normal.woff) format("woff");
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* poppins-latin-600-normal */
@font-face {
  font-family: Poppins;
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/files/poppins-latin-600-normal.woff2) format("woff2"), url(/files/poppins-latin-600-normal.woff) format("woff");
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

html,
body {
  width: 100%;
  height: 100vh;
  margin: 0;
  padding: 0;
  overflow: hidden;
  font-family: Inter, "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto,
    "Helvetica Neue", sans-serif;
  box-sizing: border-box;
}

*::before {
  box-sizing: border-box;
}

#container {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
}

@utility auto-min-h {
  height: var(--auto-min-height);
  min-height: 0;
}

/* Smokeball Design Framework type scale — role-based text styles.
 * Each bundles the framework's font-size + line-height + weight for a named role, so usage is a
 * single class (e.g. `text-heading-h1`, `text-body-ui`). Font-family follows the theme stacks
 * (`--font-heading` → Poppins / `--font-sans` → Inter). `*-semibold` variants
 * exist wherever the framework emits them; the unsuffixed body styles are the regular (400) weight.
 */
@utility text-heading-h1 {
  font-family: var(--font-heading);
  font-size: 2rem;
  line-height: 2.5rem;
  font-weight: 600;
}

@utility text-heading-h2 {
  font-family: var(--font-heading);
  font-size: 1.75rem;
  line-height: 2.25rem;
  font-weight: 600;
}

@utility text-heading-h3 {
  font-family: var(--font-heading);
  font-size: 1.5rem;
  line-height: 2rem;
  font-weight: 600;
}

/* The design system's `fontSize-md` / `lineHeight-snug` step - sub-headings and card titles. The
 * scale otherwise matched the system exactly; this was the only rung with nothing on it, which is
 * why a modest card title had to choose between 16px and a 24px display heading. */
@utility text-heading-h4 {
  font-family: var(--font-heading);
  font-size: 1.25rem;
  line-height: 1.75rem;
  font-weight: 600;
}

@utility text-body-paragraph {
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: 1.5rem;
  font-weight: 400;
}

@utility text-body-paragraph-semibold {
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: 1.5rem;
  font-weight: 600;
}

@utility text-body-ui {
  font-family: var(--font-sans);
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 400;
}

@utility text-body-ui-medium {
  font-family: var(--font-sans);
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 500;
}

@utility text-body-ui-semibold {
  font-family: var(--font-sans);
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 600;
}

@utility text-body-caption {
  font-family: var(--font-sans);
  font-size: 0.75rem;
  line-height: 1rem;
  font-weight: 400;
}

@utility text-body-caption-semibold {
  font-family: var(--font-sans);
  font-size: 0.75rem;
  line-height: 1rem;
  font-weight: 600;
}

/* The `@theme inline` block exposes CSS custom properties that Tailwind resolves
 * through `var(--color-*)` tokens. Runtime updates from `office-theme.ts` rewrite
 * the `--background`, `--foreground`, and neutral scale values as Outlook themes
 * change. To add a new semantic token (for example `--color-info`), define it here
 * and mirror its underlying `--foo` source in both the `:root` and `.dark` blocks.
 */
@theme inline {
  --color-background: hsl(var(--background));
  --color-foreground: hsl(var(--foreground));
  --color-muted: hsl(var(--muted));
  --color-muted-foreground: hsl(var(--muted-foreground));
  --color-primary: hsl(var(--primary));
  --color-primary-foreground: hsl(var(--primary-foreground));
  --color-secondary: hsl(var(--secondary));
  --color-secondary-foreground: hsl(var(--secondary-foreground));
  --color-destructive: hsl(var(--destructive));
  --color-destructive-foreground: hsl(var(--destructive-foreground));
  --color-accent: hsl(var(--accent));
  --color-accent-foreground: hsl(var(--accent-foreground));
  --color-popover: hsl(var(--popover));
  --color-popover-foreground: hsl(var(--popover-foreground));
  --color-card: hsl(var(--card));
  --color-card-foreground: hsl(var(--card-foreground));
  --color-border: hsl(var(--border));
  --color-input: hsl(var(--input));
  --color-ring: hsl(var(--ring));

  /* Smokeball Design Framework semantic colours, exposed as Tailwind utilities under the `ds-`
   * namespace so they never collide with the shadcn semantic tokens above (which are host-driven).
   * Each resolves to a `--ds-*` custom property whose light/dark values live in the `:root` / `.dark`
   * blocks below. Roles map to the framework thus:
   *   fills / surfaces  → `bg-ds-*`   (bg-ds-surface, bg-ds-accent, bg-ds-danger-subtle, …)
   *   foreground / icon → `text-ds-*` (text-ds-fg, text-ds-fg-danger, text-ds-fg-subtle, …)
   *   borders           → `border-ds-*` (border-ds-border, border-ds-border-danger, …)
   * Accent/danger/success/warning use the fixed framework palette; neutral-derived roles use the
   * host-adaptive neutrals so text/surfaces/borders keep tracking the Outlook theme. */
  /* Neutral-derived roles are inlined as `hsl(var(--neutral-*))` (not indirected through a `--ds-*`
   * property). `@theme inline` bakes this expression straight into each utility, so `var(--neutral-*)`
   * resolves at the *consuming* element and therefore flips with the adaptive scale under `.dark`.
   * (A `--ds-*` alias declared only on `:root` would freeze the light value and never flip.) */
  --color-ds-fg: hsl(var(--neutral-850));
  --color-ds-fg-subtle: hsl(var(--neutral-500));
  --color-ds-fg-disabled: hsl(var(--neutral-400));
  --color-ds-fg-placeholder: hsl(var(--neutral-400));
  --color-ds-fg-inverse: #fff;
  /* Ink for the bold semantic fills. Fixed rather than neutral-derived: the system only
   * overrides danger and success in dark, so the warning and accent-alt fills stay light in
   * both themes. An adaptive foreground on a fixed fill went near-white over yellow. */
  --color-ds-fg-on-bold: #1c2230;
  --color-ds-surface: hsl(var(--neutral-20));
  --color-ds-surface-overlay: hsl(var(--neutral-50));
  --color-ds-surface-canvas: hsl(var(--neutral-50));
  --color-ds-neutral: hsl(var(--neutral-100));
  --color-ds-border: hsl(var(--neutral-100));
  --color-ds-border-subtle: hsl(var(--neutral-50));
  --color-ds-border-input: hsl(var(--neutral-200));
  --color-ds-border-disabled: hsl(var(--neutral-400));
  --color-ds-border-inverse: hsl(var(--neutral-20));
  --color-ds-neutral-hover: hsl(var(--neutral-50));
  /* The brand fill, and the surface a disabled fill takes. Brand outranks primary, so a surface
   * gets at most one - the sign-in's "Connect to Smokeball" is the case it exists for. */
  --color-ds-brand: var(--ds-brand);
  --color-ds-brand-hover: var(--ds-brand-hover);
  --color-ds-brand-pressed: var(--ds-brand-pressed);
  --color-ds-disabled: var(--ds-disabled);

  /* The system's field roles - the surfaces a select, input or menu paints itself with.
   * `input-idle`, `-hover` and `-active` resolve to the same value in the system's palette; they
   * are kept apart so a later change to one does not silently move the others. */
  --color-ds-fields-input-idle: var(--ds-fields-input-idle);
  --color-ds-fields-input-hover: var(--ds-fields-input-hover);
  --color-ds-fields-input-active: var(--ds-fields-input-active);
  --color-ds-fields-input-disabled: var(--ds-fields-input-disabled);
  --color-ds-fields-menu-idle: var(--ds-fields-menu-idle);
  --color-ds-fields-menu-hover: var(--ds-fields-menu-hover);
  --color-ds-fields-menu-active: var(--ds-fields-menu-active);
  --color-ds-neutral-pressed: hsl(var(--neutral-100));
  --color-ds-neutral-transparent: rgba(0, 0, 0, 0.2);
  --color-ds-neutral-transparent-hover: rgba(0, 0, 0, 0.05);
  --color-ds-neutral-transparent-pressed: rgba(0, 0, 0, 0.1);
  --color-ds-tooltip: hsl(var(--neutral-20));
  --color-ds-tooltip-inverse: hsl(var(--neutral-950));

  /* The dark tooltip's own surface and text. Fixed rather than theme-flipping, because that is
   * how the system defines them: `background-tooltip-inverse-background` and `text-inverse` each
   * have a single value and stay put across themes. Reaching for the add-in's flipping
   * `--color-ds-tooltip-inverse` inverted the bubble in dark mode - the neutral scale runs the
   * other way there, so a near-black surface came out near-white with pale text on it. */
  --color-ds-tooltip-surface: #090b10;
  --color-ds-tooltip-on-surface: #ffffff;

  /* Table roles. The design system gives the grid its own small palette rather than reusing the
   * generic surface roles, because a header, a hovered row and a selected row have to be told apart
   * at a glance and the neutral scale alone does not do it. Indirected through `--ds-table-*` so the
   * dark overrides below can flip them. */
  --color-ds-table-header-default: var(--ds-table-header-default);
  --color-ds-table-header-hover: var(--ds-table-header-hover);
  --color-ds-table-header-active: var(--ds-table-header-active);
  --color-ds-table-row-hover: var(--ds-table-row-hover);
  --color-ds-table-row-selected: var(--ds-table-row-selected);
  --color-ds-table-cell-default: var(--ds-table-cell-default);

  /* The sort indicator's two states. `subtle` is the system's resting icon colour; the sorted
   * column's arrow takes `default`. */
  --color-ds-icon-default: var(--ds-icon-default);
  --color-ds-icon-subtle: var(--ds-icon-subtle);

  /* Fixed brand roles indirect through `--ds-*` so they flip via the `.dark` overrides below. */
  --color-ds-fg-accent: var(--ds-fg-accent);
  --color-ds-fg-accent-hover: var(--ds-fg-accent-hover);
  --color-ds-fg-danger: var(--ds-fg-danger);
  --color-ds-fg-success: var(--ds-fg-success);
  --color-ds-fg-warning: var(--ds-fg-warning);
  --color-ds-accent: var(--ds-bg-accent);
  --color-ds-accent-hover: var(--ds-bg-accent-hover);
  --color-ds-accent-pressed: var(--ds-bg-accent-pressed);
  --color-ds-accent-subtle: var(--ds-bg-accent-subtle);
  --color-ds-accent-subtle-hover: var(--ds-bg-accent-subtle-hover);
  --color-ds-accent-subtle-pressed: var(--ds-bg-accent-subtle-pressed);
  --color-ds-accent-alt: var(--ds-bg-accent-alt);
  --color-ds-accent-alt-hover: var(--ds-bg-accent-alt-hover);
  --color-ds-accent-alt-pressed: var(--ds-bg-accent-alt-pressed);
  --color-ds-danger-hover: var(--ds-bg-danger-hover);
  --color-ds-danger-pressed: var(--ds-bg-danger-pressed);
  --color-ds-danger-subtle-hover: var(--ds-bg-danger-subtle-hover);
  --color-ds-danger-subtle-pressed: var(--ds-bg-danger-subtle-pressed);
  --color-ds-success-hover: var(--ds-bg-success-hover);
  --color-ds-success-pressed: var(--ds-bg-success-pressed);
  --color-ds-warning-hover: var(--ds-bg-warning-hover);
  --color-ds-border-accent-hover: var(--ds-border-accent-hover);
  --color-ds-border-accent-pressed: var(--ds-border-accent-pressed);
  --color-ds-danger: var(--ds-bg-danger);
  --color-ds-danger-subtle: var(--ds-bg-danger-subtle);
  --color-ds-danger-bold: var(--ds-bg-danger-bold);
  --color-ds-success: var(--ds-bg-success);
  --color-ds-success-subtle: var(--ds-bg-success-subtle);
  --color-ds-success-bold: var(--ds-bg-success-bold);
  --color-ds-warning: var(--ds-bg-warning);
  --color-ds-warning-subtle: var(--ds-bg-warning-subtle);
  --color-ds-warning-bold: var(--ds-bg-warning-bold);

  --color-ds-border-focus: var(--ds-border-focus);
  /* Focus-ring colours: blue-200 / red-100 — translucent focus indicators. Inlined (light-only,
   * like the framework's border-focused-subtle) rather than flipped. */
  --color-ds-border-focus-subtle: #aed2fe;
  --color-ds-border-danger-subtle: var(--ds-border-danger-subtle);
  --color-ds-border-accent: var(--ds-border-accent);
  --color-ds-border-danger: var(--ds-border-danger);
  --color-ds-border-success: var(--ds-border-success);
  --color-ds-border-warning: var(--ds-border-warning);

  /* Animations */
  --animate-accordion-down: accordion-down 0.2s ease-out;
  --animate-accordion-up: accordion-up 0.2s ease-out;
  --animate-slide-from-left: slide-from-left 0.3s cubic-bezier(0.82, 0.085, 0.395, 0.895);
  --animate-slide-to-left: slide-to-left 0.25s cubic-bezier(0.82, 0.085, 0.395, 0.895);
  --animate-move: move 2s infinite cubic-bezier(0.25, 0.1, 0.25, 1);

  /* Container */
  --container-center: true;
  --container-padding: 2rem;
  --container-screen-2xl: 1400px;

  /* Custom breakpoints */
  --breakpoint-3xl: 1792px;
  --breakpoint-4xl: 2048px;


  /* Shadows */
  --shadow-menu: 0px 4px 8px 0px #0000003D;
  --shadow-modal: 0px 4px 8px 0px #0000003D, 0px 0px 1px 0px #00000052;

  /* Modal background shadow color */
  --color-modal-background-shadow: hsl(0 0% 22% / 0.6);
  --color-modal-overlay: var(--color-modal-background-shadow);

   /* Border radius */
  --radius-lg: var(--radius);
  --radius-md: calc(var(--radius) - 2px);
  --radius-sm: calc(var(--radius) - 4px);

  /* Typography — Smokeball Design Framework.
   * DES-631: the framework's brand fonts ship as @font-face rules copied from @fontsource at the
   * top of this file (see that comment for why they are not @import-ed): Inter for body/UI/caption,
   * Poppins Semi-Bold for headings, with the Segoe UI system stack as fallback while the webfonts
   * load. Role-based styles (text-heading-h1, text-body-ui, …) are defined as `@utility` blocks
   * below.
   */
  --font-sans: Inter, "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto,
    "Helvetica Neue", sans-serif;
  --font-heading: Poppins, var(--font-sans);

  /* Framework font-size primitives (px shown for reference): xs 12, sm 14, base 16, md 20,
   * lg 24, xl 28, 2xl 32. Namespaced as `text-ds-*` so they never clobber Tailwind's defaults
   * (whose lg/xl/2xl differ and are relied on by existing components). Each carries its paired
   * framework line-height. */
  --text-ds-xs: 0.75rem;
  --text-ds-xs--line-height: 1rem;
  --text-ds-sm: 0.875rem;
  --text-ds-sm--line-height: 1.25rem;
  --text-ds-base: 1rem;
  --text-ds-base--line-height: 1.5rem;
  --text-ds-md: 1.25rem;
  --text-ds-md--line-height: 1.75rem;
  --text-ds-lg: 1.5rem;
  --text-ds-lg--line-height: 2rem;
  --text-ds-xl: 1.75rem;
  --text-ds-xl--line-height: 2.25rem;
  --text-ds-2xl: 2rem;
  --text-ds-2xl--line-height: 2.5rem;

  /* UI Library colors */
  --color-black: #000;
  --color-white: #fff;
  --color-transparent-overlay: hsla(0, 0%, 0%, 0.4);
  --color-segmented-control-background: hsl(223, 14%, 90%);

  --color-gray-100: #f2f2f2;
  --color-gray-200: #e6e6e6;
  --color-gray-300: #dadada;
  --color-gray-400: #c4c4c4;
  --color-gray-500: #999999;
  --color-gray-600: #666666;
  --color-gray-700: #4d4d4d;
  --color-gray-800: #333333;

  /* Brand & descriptive palette — realigned to the Smokeball Design Framework's exact hex values.
   * The framework's canonical steps (blue-50/200/400/500/600/700/900, cyan-50/100/200/500, …) are
   * defined for new work; the add-in's legacy step names (blue-160, cyan-40, red-550, …) and the
   * default-Tailwind steps that components already use (blue-500, red-500, …) are each pinned to
   * the *closest* framework hex by lightness, so existing classes render framework colours without
   * touching component code. Neutrals are deliberately NOT here — they stay host-adaptive via
   * `office-theme.ts`. */

  /* Primary (orange) — NUC-7251: retuned from the legacy Smokeball orange (#f4610b) to the new
   * brand orange. #ff5000 is the terminal stop of the new logo's gradient
   * (#ffc431 → #ff9c11 → #ff5000); the 400/600 steps are derived from it so interactive states
   * (focus ring, hover, active) stay in the same hue family, and 50 is its light wash.
   * Consumers: the Assign-to-Matter accordion's open-state strip and the `branding` button
   * variants. The 100/200 tints are no longer used by any live component. */
  --color-orange-50: #fff2ec;
  --color-orange-100: #fddfce;
  --color-orange-200: #fac09e;
  --color-orange-400: #ff7c40;
  --color-orange-500: #ff5000;
  --color-orange-600: #cc4000;

  /* Cyan */
  --color-cyan-50: #edfafc;
  --color-cyan-40: #edfafc;
  --color-cyan-100: #c2edf5;
  --color-cyan-140: #c2edf5;
  --color-cyan-200: #96e1ee;
  --color-cyan-240: #96e1ee;
  --color-cyan-340: #96e1ee;
  --color-cyan-500: #21b0ca;
  --color-cyan-540: #21b0ca;

  /* Blue (accent) */
  --color-blue-50: #e1eeff;
  --color-blue-60: #e1eeff;
  --color-blue-100: #e1eeff;
  --color-blue-160: #aed2fe;
  --color-blue-200: #aed2fe;
  --color-blue-300: #aed2fe;
  --color-blue-360: #499afd;
  --color-blue-400: #499afd;
  --color-blue-460: #177efd;
  --color-blue-500: #177efd;
  --color-blue-560: #0265de;
  --color-blue-600: #0265de;
  --color-blue-660: #024eac;
  --color-blue-700: #024eac;
  --color-blue-900: #01234c;

  /* Neutral */
  --color-neutral-20: hsl(var(--neutral-20));
  --color-neutral-50: hsl(var(--neutral-50));
  --color-neutral-100: hsl(var(--neutral-100));
  --color-neutral-150: hsl(var(--neutral-150));
  --color-neutral-200: hsl(var(--neutral-200));
  --color-neutral-250: hsl(var(--neutral-250));
  --color-neutral-300: hsl(var(--neutral-300));
  --color-neutral-400: hsl(var(--neutral-400));
  --color-neutral-500: hsl(var(--neutral-500));
  --color-neutral-600: hsl(var(--neutral-600));
  --color-neutral-700: hsl(var(--neutral-700));
  --color-neutral-750: hsl(var(--neutral-750));
  --color-neutral-850: hsl(var(--neutral-850));
  --color-neutral-950: hsl(var(--neutral-950));

  /* Descriptive — green (success) */
  --color-green-50: #e9fcf4;
  --color-green-100: #d2f9e9;
  --color-green-200: #a4f4d3;
  --color-green-400: #49e9a6;
  --color-green-600: #16b673;
  --color-green-700: #118856;
  --color-green-800: #0b5b3a;
  --color-green-900: #073623;

  /* Yellow (warning) */
  --color-yellow-100: #fbf3b7;
  --color-yellow-150: #fbf3b7;
  --color-yellow-200: #f8eb87;
  --color-yellow-250: #f8eb87;
  --color-yellow-300: #f5e356;
  --color-yellow-350: #f5e356;
  --color-yellow-400: #f2db26;
  --color-yellow-450: #f2db26;
  --color-yellow-500: #d9c10d;
  --color-yellow-550: #d9c10d;
  --color-yellow-800: #484004;
  --color-yellow-850: #484004;
  --color-yellow-900: #302b03;

  /* Red (danger) */
  --color-red-50: #fde8e7;
  --color-red-100: #fabab8;
  --color-red-150: #fabab8;
  --color-red-200: #fabab8;
  --color-red-300: #f35e59;
  --color-red-400: #ef302a;
  --color-red-450: #ef302a;
  --color-red-500: #ef302a;
  --color-red-550: #d51710;
  --color-red-600: #d51710;
  --color-red-650: #d51710;
  --color-red-700: #d51710;
  --color-red-800: #470805;

  --color-black-5: rgba(0, 0, 0, 0.05);
  --color-black-10: rgba(0, 0, 0, 0.1);
  --color-black-15: rgba(0, 0, 0, 0.15);
  --color-black-20: rgba(0, 0, 0, 0.2);
  --color-black-30: rgba(0, 0, 0, 0.3);
  --color-black-40: rgba(0, 0, 0, 0.4);
  --color-black-50: rgba(0, 0, 0, 0.5);
  --color-black-60: rgba(0, 0, 0, 0.6);
  --color-black-70: rgba(0, 0, 0, 0.7);
  --color-black-80: rgba(0, 0, 0, 0.8);
  --color-black-90: rgba(0, 0, 0, 0.9);

  /* Additional — pink & purple */
  --color-pink-100: #f8b9ce;
  --color-pink-150: #f8b9ce;
  --color-pink-400: #ea2e6d;
  --color-pink-450: #ea2e6d;

  --color-purple-200: #ddb4e4;
  --color-purple-400: #bb69c9;
  --color-purple-450: #bb69c9;
}

@layer base {
  /* Base light-theme defaults. These values represent our fallback palette when
   * Outlook has not yet provided theme colors. If you want to tweak the static
   * light appearance, adjust the tokens here and leave the runtime logic in
   * `office-theme.ts` unchanged so Outlook can still override them.
   */
  :root {
    color-scheme: light;
    --background: 223 28% 95%;
    --foreground: 222 26% 15%;

    --muted: 240 4.8% 95.9%;
    /* DES-631: subtle text = design framework Neutral.600 #4B5881 (was the shadcn zinc default,
     * which read as washed-out grey next to the design). */
    --muted-foreground: 226 26% 40%;

    --popover: 0 0% 100%;
    --popover-foreground: 222 26% 15%;

    --card: 0 0% 100%;
    --card-foreground: 222 26% 15%;

    --border: 240 5.9% 90%;
    --input: 240 5.9% 90%;

    --primary: 213 98% 44%;
    --primary-foreground: 0 0% 98%;

    --secondary: 0 0% 100%;
    --secondary-foreground: 213 98% 44%;

    --accent: 240 4.8% 95.9%;
    --accent-foreground: 222 26% 15%;

    --destructive: 0 84.2% 60.2%;
    --destructive-foreground: 0 0% 98%;

    --ring: 213 98% 84%; /* blue-160 */

    --neutral-20: 240 20% 98%;
    --neutral-50: 223 28% 95%;
    --neutral-100: 222 26% 90%;
    --neutral-150: 222 26% 85%;
    --neutral-200: 222 26% 80%;
    --neutral-250: 222 26% 75%;
    --neutral-300: 222 26% 70%;
    --neutral-400: 222 26% 60%;
    --neutral-500: 222 26% 50%;
    --neutral-600: 222 26% 40%;
    --neutral-700: 222 26% 30%;
    --neutral-750: 222 26% 25%;
    --neutral-850: 222 26% 15%;
    --neutral-950: 222 26% 5%;

    --radius: 0.5rem;

    /* Design Framework semantic colours — fixed brand roles, LIGHT values.
     * (Neutral-derived roles — fg / surface / border / neutral fill — are NOT here: they are inlined
     * as `hsl(var(--neutral-*))` directly in the `@theme inline` block so they resolve per-element
     * and flip with the adaptive neutral scale. These fixed roles need explicit light/dark values
     * because brand hex don't flip on their own; `.dark` overrides only these.) */
    --ds-fg-accent: #0265de;
    --ds-fg-accent-hover: #177efd;
    --ds-fg-danger: #d51710;
    --ds-fg-success: #0b5b3a;
    --ds-fg-warning: #484004;

    --ds-bg-accent: #0265de;
    --ds-bg-accent-hover: #177efd;
    --ds-bg-accent-pressed: #024eac;
    --ds-bg-accent-subtle: #e1eeff;
    --ds-bg-danger: #d51710;
    --ds-bg-danger-subtle: #fde8e7;
    --ds-bg-danger-bold: #ef302a;
    --ds-bg-success: #0b5b3a;
    --ds-bg-success-subtle: #d2f9e9;
    --ds-bg-success-bold: #49e9a6;
    --ds-bg-warning: #484004;
    --ds-bg-warning-subtle: #fbf3b7;
    --ds-bg-warning-bold: #f2db26;

    --ds-border-focus: #0265de;
    --ds-border-danger-subtle: #fabab8;
    --ds-border-accent: #0265de;
    --ds-border-danger: #d51710;
    --ds-border-success: #0b5b3a;
    --ds-border-warning: #484004;

    /* The interaction states the roles above were missing. Values are the design system's own
     * (`sb-design-ai`, v1.0.0 foundations/tokens.css) resolved through its primitive palette, so a
     * component reaching for a hover or pressed state no longer has to invent one. */
    --ds-bg-accent-subtle-hover: #e1eeff;
    --ds-bg-accent-subtle-pressed: #e1eeff;
    --ds-bg-accent-alt: #c2edf5;
    --ds-bg-accent-alt-hover: #c2edf5;
    --ds-bg-accent-alt-pressed: #96e1ee;
    --ds-bg-danger-hover: #ef302a;
    --ds-bg-danger-pressed: #d51710;
    --ds-bg-danger-subtle-hover: #fabab8;
    --ds-bg-danger-subtle-pressed: #fabab8;
    --ds-bg-success-hover: #118856;
    --ds-bg-success-pressed: #0b5b3a;
    --ds-bg-warning-hover: #d9c10d;
    --ds-border-accent-hover: #177efd;
    --ds-border-accent-pressed: #024eac;

    --ds-table-header-default: #f9f9fb;
    --ds-table-header-hover: #dfe3ec;
    --ds-table-header-active: #f9f9fb;
    --ds-table-row-hover: #f9f9fb;
    --ds-table-row-selected: #edfafc;
    --ds-table-cell-default: #ffffff;
    --ds-brand: #ff5000;
    --ds-brand-hover: #e64800;
    --ds-brand-pressed: #cc4000;
    --ds-disabled: #0000000d;

    --ds-fields-input-idle: #ffffff;
    --ds-fields-input-hover: #ffffff;
    --ds-fields-input-active: #ffffff;
    --ds-fields-input-disabled: #f9f9fb;
    --ds-fields-menu-idle: #ffffff;
    --ds-fields-menu-hover: #f9f9fb;
    --ds-fields-menu-active: #edfafc;

    --ds-icon-default: #1c2230;
    --ds-icon-subtle: #4b5b81;
  }

  /* Dark theme overrides. When `office-theme.ts` detects a dark Outlook theme it
   * toggles the `dark` class on `document.documentElement`, which tells Tailwind
   * to apply this block. Only update these defaults if you need to change the
   * fallback experience; the dynamic neutral range and background still come from
   * the host theme at runtime.
   */
  .dark {
    color-scheme: dark;

    /* The system's dark table palette: the cell is the deepest surface and the header, hovered and
     * selected rows all sit one step above it. Hover and selected are the same value here - unlike
     * the light theme, dark carries selection on the checkbox alone. */
    --ds-table-header-default: #1c2230;
    --ds-table-header-hover: #394560;
    --ds-table-header-active: #1c2230;
    --ds-table-row-hover: #1c2230;
    --ds-table-row-selected: #1c2230;
    --ds-table-cell-default: #090b10;
    --ds-brand: #ff5000;
    --ds-brand-hover: #e64800;
    --ds-brand-pressed: #cc4000;
    --ds-disabled: #ffffff1a;

    /* Interaction states the dark block had been missing, so they fell through to their light
     * values: the secondary button's hover was a pale `#e1eeff` wash on a dark card. Values are the
     * system's own dark overrides. Where the system does not override a role (danger's bold fills,
     * the accent-alt cyans) the light value is deliberate and carries over. */
    --ds-bg-accent-subtle-hover: #01234c;
    --ds-bg-accent-subtle-pressed: #01234c;
    --ds-bg-danger-subtle-hover: #470805;
    --ds-bg-danger-subtle-pressed: #470805;
    --ds-border-accent-hover: #0265de;
    --ds-border-accent-pressed: #0265de;

    --ds-fields-input-idle: #1c2230;
    --ds-fields-input-hover: #1c2230;
    --ds-fields-input-active: #1c2230;
    /* The light theme's near-white, carried across by mistake: a disabled select keeps `text-ds-fg`,
     * which is a light neutral in dark, so it read at about 1.7:1. Takes the other input roles'
     * surface - the disabled affordance is carried by the border and the cursor. */
    --ds-fields-input-disabled: #1c2230;
    --ds-fields-menu-idle: #394560;
    --ds-fields-menu-hover: #394560;
    /* `#4b5b81` is the light theme's subtle-icon tone and far too light to sit under the accent
     * label the tree gives a selected row - that pairing was 2.35:1. This keeps the selection
     * readable as a band against the page while clearing AA for both foregrounds on it. */
    --ds-fields-menu-active: #243049;

    --ds-icon-default: #f9f9fb;
    --ds-icon-subtle: #bfc7d9;
    --background: 222 26% 10%;
    --foreground: 210 40% 96%;

    --muted: 220 18% 18%;
    --muted-foreground: 220 12% 73%;

    --popover: 222 26% 12%;
    --popover-foreground: 210 32% 95%;

    --card: 220 24% 14%;
    --card-foreground: 210 38% 96%;

    --border: 222 16% 24%;
    --input: 222 16% 24%;

    --primary: 213 98% 44%;
    --primary-foreground: 0 0% 98%;

    --secondary: 220 20% 18%;
    --secondary-foreground: 210 36% 95%;

    --accent: 220 28% 26%;
    --accent-foreground: 210 38% 95%;

    --destructive: 0 84% 60%;
    --destructive-foreground: 0 0% 98%;

    --ring: 213 98% 64%;

    --neutral-20: 222 22% 14%;
    --neutral-50: 222 22% 18%;
    --neutral-100: 222 22% 22%;
    --neutral-150: 222 22% 26%;
    --neutral-200: 222 22% 30%;
    --neutral-250: 222 22% 34%;
    --neutral-300: 222 22% 38%;
    --neutral-400: 222 22% 44%;
    --neutral-500: 222 22% 50%;
    --neutral-600: 222 22% 58%;
    --neutral-700: 222 22% 64%;
    --neutral-750: 222 22% 70%;
    --neutral-850: 222 22% 78%;
    --neutral-950: 222 22% 86%;

    --color-black-5: hsla(0 0% 100% / 0.06);
    --color-black-10: hsla(0 0% 100% / 0.1);
    --color-black-15: hsla(0 0% 100% / 0.15);
    --color-black-20: hsla(0 0% 100% / 0.2);
    --color-black-30: hsla(0 0% 100% / 0.3);
    --color-black-40: hsla(0 0% 100% / 0.4);
    --color-black-50: hsla(0 0% 100% / 0.5);
    --color-black-60: hsla(0 0% 100% / 0.6);
    --color-black-70: hsla(0 0% 100% / 0.7);
    --color-black-80: hsla(0 0% 100% / 0.8);
    --color-black-90: hsla(0 0% 100% / 0.9);

    /* Design Framework semantic colours — DARK. ONLY the fixed brand roles flip here; the
     * neutral-derived roles (fg / surface / border / neutral fill) intentionally inherit from
     * `:root` and track the adaptive neutral scale, which office-theme.ts rewrites for dark. */
    --ds-fg-accent: #499afd;
    --ds-fg-accent-hover: #499afd;
    --ds-fg-danger: #f35e59;
    --ds-fg-success: #49e9a6;
    --ds-fg-warning: #f2db26;

    --ds-bg-accent-hover: #0265de;
    --ds-bg-accent-pressed: #0265de;
    --ds-bg-accent-subtle: #01234c;
    --ds-bg-danger-subtle: #470805;
    --ds-bg-danger-bold: #ef302a;
    --ds-bg-success-subtle: #073623;
    --ds-bg-success-bold: #16b673;
    --ds-bg-warning-subtle: #302b03;
    --ds-border-danger-subtle: #470805;
    --ds-border-warning: #f2db26;

    --ds-border-danger: #f35e59;
    --ds-border-success: #49e9a6;
  }

  /* Keyframes for animations */
  @keyframes accordion-down {
    from { height: 0; }
    to { height: var(--radix-accordion-content-height); }
  }

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

  @keyframes slide-from-left {
    0% { transform: translateX(-100%); }
    100% { transform: translateX(0); }
  }

  @keyframes slide-to-left {
    0% { transform: translateX(0); }
    100% { transform: translateX(-100%); }
  }

  @keyframes move {
    0% { transform: translateX(-100%); }
    100% { transform: translateX(100%); }
  }
}

.ProseMirror {
  outline: none;
}

.suggestion-highlight, .unfocused-selection-highlight {
  @apply bg-blue-200 hover:bg-blue-300 dark:hover:bg-blue-400/50 dark:text-blue-50 dark:bg-blue-500/40;
}

/* Scrollbars, matched to the host's.
 *
 * Outlook styles every scrollbar in OWA - through `.customScrollBar` on each scroll container, plus
 * `body` - and the geometry below is its rules verbatim, read off `owa.shared.m.*.css`.
 *
 * The trick worth understanding before touching it: the gutter is 18px, but the thumb carries a 6px
 * transparent border and `background-clip: content-box`, so what the user sees is a 6px bar with a
 * 9px radius floating in an 18px hit area. Wide to grab, slim to look at. Setting `width` alone -
 * which is what this file used to do at 12px - gets you a 12px *bar*, which is why ours read as
 * furniture beside the host's.
 *
 * Colours are Outlook's `--neutralSecondary` / `--neutralPrimaryAlt` at their default values, and
 * the 50px minimum stops the thumb shrinking to a dot in a long file list.
 *
 * The standard `scrollbar-width`/`scrollbar-color` properties stay scoped to engines without
 * `::-webkit-scrollbar`, which is how Outlook scopes them too: from Chromium 121 the standard
 * properties take precedence over the pseudo-elements, and would throw away everything above. */
@supports not selector(::-webkit-scrollbar) {
  .scrollbar,
  body {
    scrollbar-color: #808080 transparent;
    scrollbar-width: thin;
  }
}

.scrollbar::-webkit-scrollbar,
body::-webkit-scrollbar {
  width: 18px;
  height: 18px;
}

.scrollbar::-webkit-scrollbar-track,
body::-webkit-scrollbar-track {
  background: transparent;
}

.scrollbar::-webkit-scrollbar-thumb,
body::-webkit-scrollbar-thumb {
  background-color: #808080;
  background-clip: content-box;
  border: 6px solid transparent;
  border-radius: 9px;
}

.scrollbar::-webkit-scrollbar-thumb:hover,
body::-webkit-scrollbar-thumb:hover {
  background-color: #616161;
}

.scrollbar::-webkit-scrollbar-thumb:vertical,
body::-webkit-scrollbar-thumb:vertical {
  min-height: 50px;
}

.scrollbar::-webkit-scrollbar-thumb:horizontal,
body::-webkit-scrollbar-thumb:horizontal {
  min-width: 50px;
}

/* App-wide tooltip appearance, to the design system's `ds-tooltip` in its default dark
 * appearance: the system's near-black surface rather than pure black, white text, and the
 * geometry it prescribes - 8px/16px padding, an 8px radius, a 360px ceiling and its own
 * 14px/20px body.
 *
 * Fluent v9 renders the body as `.fui-Tooltip__content` and the `withArrow` arrow as its
 * `::before` with `background-color: inherit`, so setting the body's background recolours the
 * arrow too. `!important` is required because Griffel injects the default atomic styles at
 * runtime, after this bundled stylesheet, so they would otherwise win on equal specificity. */
.fui-Tooltip__content {
  background-color: var(--color-ds-tooltip-surface) !important;
  color: var(--color-ds-tooltip-on-surface) !important;
  border: none !important;
  border-radius: 0.5rem !important;
  padding: 8px 16px !important;
  /* The system's ceiling. Without it a long tooltip runs the width of the panel, which is what
   * made the task assignee tooltip - which asked for a flat 400px - overrun its own trigger. */
  max-width: 360px !important;
  box-shadow:
    0px 10px 15px -3px #0000001a,
    0px 4px 6px -4px #0000001a !important;
  font-family: var(--font-sans) !important;
  font-size: 0.875rem !important;
  line-height: 1.25rem !important;
  font-weight: 400 !important;
}

/* The system stacks an optional semibold title over the body at a 4px gap. */
.fui-Tooltip__content > * + * {
  margin-top: 4px;
}


/* ==========================================================================
   Tree List - the design system's `ds-tree-list`.
   BEM prefix: .ds-tree-list

   Written as real CSS rather than utilities because two things here cannot be
   expressed as static classes: the indent is driven by a `--depth` custom
   property set per row, and the hover/selected highlight is a pseudo-element
   whose start edge is computed from that depth. Colours and radii still come
   from the add-in's tokens, so it stays in step with the rest of the theme.
   ========================================================================== */

.ds-tree-list {
  /* One nesting step. Matches the toggle column, so a child's content begins
     where its parent's chevron ended. */
  --ds-tree-list-indent: 20px;
  /* Half a toggle - shifts the guide-lines under the ancestor chevrons. */
  --ds-tree-list-guide-offset: 10px;
  /* Space between a row's indent step and the highlight pill. */
  --ds-tree-list-highlight-gap: 6px;
  /* The band's height, as a property so `--compact` can restate it on the container rather than
     each rule that depends on it re-deriving the size. */
  --ds-tree-list-row-height: 2.25rem;
  --ds-tree-list-icon-color: var(--color-ds-icon-subtle);
  --ds-tree-list-icon-color-selected: var(--color-ds-fg-accent);

  width: 100%;
  padding: 4px;
  background-color: transparent;
  border-radius: 0.25rem;
  color: var(--color-ds-fg);
}

.ds-tree-list__group {
  list-style: none;
  margin: 0;
  padding: 0;
}

.ds-tree-list__node {
  margin: 0;
}

/* There is no branch box here any more, and so no open/close animation (NUC-8152).

   Nested groups used to be wrapped in a `.ds-tree-list__branch` grid whose single row went
   0fr -> 1fr, which is what let a subtree animate to and from an auto height. That needed the
   whole subtree in the document to have a height to grow into, and on a real matter that meant
   thousands of rows mounted to reveal a handful. The tree is a flat list of the rows that are
   actually visible now, so a collapsed folder's children are not here to animate. See TreeList. */

/* The row and any controls beside it, on one line exactly one row tall.

   The band was introduced because an expanded node's `<li>` used to be the row plus its
   whole open subtree, so controls positioned against it centred themselves somewhere down
   the middle of the folder. Flattening (NUC-8152) retired that problem - a list item is one
   row now - but the band stays: it is the positioning context the selection highlight runs
   in (`::after` below), so the highlight can extend behind the actions instead of stopping
   at the row's edge. */
.ds-tree-list__rowband {
  position: relative;
  isolation: isolate;
  display: flex;
  align-items: center;
  height: var(--ds-tree-list-row-height);
}

/* The whole row is one click target, and takes the width the actions leave, so a
   long label ellipses rather than running under them. Content indents via padding
   driven by `--depth`; the highlight is painted behind the band so its start edge
   can be inset independently and still run to the band's end, behind the actions. */
.ds-tree-list__row {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1 1 auto;
  min-width: 0;
  height: 100%;
  padding-block: 0;
  padding-inline: 12px;
  padding-inline-start: calc(12px + var(--depth, 0) * var(--ds-tree-list-indent));
  border: none;
  background-color: transparent;
  font: inherit;
  color: inherit;
  text-align: start;
}

/* Only the button form activates - while the row is hosting a control it is a plain
   `<div>` with nothing to click, and a hand cursor over it would be a lie. */
button.ds-tree-list__row {
  cursor: pointer;
}

.ds-tree-list__rowband::after {
  content: "";
  position: absolute;
  z-index: -1;
  inset-block: 0;
  inset-inline-end: 0;
  inset-inline-start: calc(var(--depth, 0) * var(--ds-tree-list-indent) + var(--ds-tree-list-highlight-gap));
  border-radius: 0.5rem;
  background-color: transparent;
  transition: background-color 100ms cubic-bezier(0.4, 0, 0.2, 1);
}

/* Sits after the row on the band's line, in flow rather than absolute, so the row
   shrinks by exactly their width and no hidden copy is needed inside it to reserve
   the room - that copy duplicated every control into the row button. */
.ds-tree-list__actions {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  gap: 4px;
  padding-inline-end: 12px;
}

.ds-tree-list--compact {
  --ds-tree-list-row-height: 1.75rem;
}

.ds-tree-list__rowband:hover::after {
  background-color: var(--color-ds-neutral-hover);
}

.ds-tree-list__row:focus-visible {
  outline: 2px solid var(--color-ds-border-focus);
  outline-offset: -2px;
  border-radius: 0.5rem;
}

.ds-tree-list__rowband:has(.ds-tree-list__row--selected)::after,
.ds-tree-list__rowband:has(.ds-tree-list__row--selected):hover::after {
  background-color: var(--color-ds-fields-menu-active);
}

.ds-tree-list__row--selected .ds-tree-list__label {
  color: var(--color-ds-fg-accent);
  font-weight: 600;
}

/* Decorative - the whole row toggles, so this is only the cue. */
.ds-tree-list__toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  color: var(--color-ds-icon-subtle);
}

/* Leaves keep the box as an invisible spacer so labels stay aligned. */
.ds-tree-list__toggle--leaf {
  visibility: hidden;
}

.ds-tree-list__toggle-icon {
  width: 16px;
  height: 16px;
  transition: transform 200ms cubic-bezier(0.4, 0, 0.2, 1);
}

.ds-tree-list__node--expanded > .ds-tree-list__rowband .ds-tree-list__toggle-icon {
  transform: rotate(90deg);
}

.ds-tree-list__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  color: var(--ds-tree-list-icon-color);
}

.ds-tree-list__row--selected .ds-tree-list__icon {
  color: var(--ds-tree-list-icon-color-selected);
}

.ds-tree-list__icon > svg,
.ds-tree-list__icon > img {
  width: 100%;
  height: 100%;
  display: block;
}

.ds-tree-list__label {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 400;
  color: var(--color-ds-fg);
}

.ds-tree-list__trailing {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  color: var(--color-ds-fg-subtle);
}

/* A faint rule at each indent step so the eye can trace a nested node back to
   an ancestor. Depth 0 rows have a zero-width guide area, so nothing shows. */
.ds-tree-list--guides .ds-tree-list__rowband::before {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline-start: calc(12px + var(--ds-tree-list-guide-offset));
  width: calc(var(--depth, 0) * var(--ds-tree-list-indent));
  background-image: repeating-linear-gradient(
    to right,
    var(--color-ds-border) 0,
    var(--color-ds-border) 1px,
    transparent 1px,
    transparent var(--ds-tree-list-indent)
  );
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .ds-tree-list__toggle-icon {
    transition: none;
  }
}


/* The design system's `ds-spinner` rotation. Here rather than as a utility because a keyframed
 * animation is not something a class can express. Reduced motion slows it rather than stopping it -
 * an indicator that has stopped moving reads as a process that has hung. */
.ds-spinner > svg {
  animation: ds-spinner-rotate 1.1s linear infinite;
}

@keyframes ds-spinner-rotate {
  to {
    transform: rotate(360deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .ds-spinner > svg {
    animation-duration: 2.4s;
  }
}

/* A loading button: the system takes the spinner out of flow and centres it, and fades the label
 * rather than removing it. Adding the spinner to the button's flex row instead grows the button the
 * moment it starts loading, which is the layout shift the system calls out by name.
 *
 * opacity, not visibility - the label has to keep occupying its space, which is what holds the width
 * steady, and has to stay in the accessibility tree, or the button loses its accessible name at the
 * exact moment it is announcing itself as busy. */
button[aria-busy="true"] {
  position: relative;
}

button[aria-busy="true"] > :not(.ds-spinner) {
  opacity: 0;
}

button[aria-busy="true"] > .ds-spinner {
  position: absolute;
  top: 50%;
  left: 50%;
  translate: -50% -50%;
}

/* Attach Files runs edge to edge (NUC-7121): the folder tree drops the design system's 4px
   container inset so the selection band reaches the dialog's left edge. Scoped to this dialog —
   every other ds-tree-list in the add-in keeps the system defaults. */
[data-testid="attach-files-content"] .ds-tree-list {
  padding-inline-start: 0;
  /* Clears the scroll bar so the longest row does not run under it. */
  padding-inline-end: 2px;
}

/* The band is held 3px off both edges so it reads as a selected row rather than a full-width fill,
   and the chevron sits inside it rather than on it. The per-depth step is untouched, so nested
   folders still indent against their parent. */
[data-testid="attach-files-content"] .ds-tree-list__rowband::after {
  inset-inline-start: calc(3px + var(--depth, 0) * var(--ds-tree-list-indent));
  inset-inline-end: 3px;
}

[data-testid="attach-files-content"] .ds-tree-list__row {
  padding-inline-start: calc(8px + var(--depth, 0) * var(--ds-tree-list-indent));
}
