{"version":3,"file":"africanies-africanies-theme.mjs","sources":["../../../../libs/africanies-theme/src/lib/mode-color.safelist.ts","../../../../libs/africanies-theme/src/lib/mode-color.service.ts","../../../../libs/africanies-theme/src/lib/theme.service.ts","../../../../libs/africanies-theme/src/africanies-africanies-theme.ts"],"sourcesContent":["/**\n * Tailwind safelist side-effect for shipping-mode color utilities.\n *\n * WHY this file exists: JIT/content scanning only keeps class names that appear\n * as *literal strings* in scanned sources. {@link ModeColorService} already\n * returns these literals, but keeping a dedicated comment list makes the\n * contract obvious for consumers who configure `safelist` or purge plugins.\n *\n * Do not rename these strings without updating ModeColorService and THEME.md.\n *\n * SFN (export / green):\n * text-export-strong bg-export-strong hover:bg-export-hover border-export-strong\n * text-export bg-export bg-export-subtle bg-export-light border-export\n * hover:bg-export-light hover:bg-export-subtle dark:bg-export/15 dark:hover:bg-export/15\n * dark:bg-[color-mix(in_srgb,#26bd5d_15%,#212529)] dark:bg-export dark:text-export dark:border-export\n *\n * STN (import / orange):\n * text-import-strong bg-import-strong hover:bg-import-hover border-import-strong\n * text-import bg-import bg-import-subtle bg-import-light border-import\n * hover:bg-import-light hover:bg-import-subtle dark:bg-import/15 dark:hover:bg-import/15\n * dark:bg-[color-mix(in_srgb,#f08829_15%,#212529)] dark:bg-import dark:text-import dark:border-import\n */\nexport const MODE_COLOR_SAFELIST = [\n  'text-export',\n  'text-export-strong',\n  'bg-export',\n  'bg-export-strong',\n  'bg-export-subtle',\n  'bg-export-light',\n  'border-export',\n  'border-export-strong',\n  'hover:bg-export-hover',\n  'hover:bg-export-light',\n  'hover:bg-export-subtle',\n  'dark:bg-export/15',\n  'dark:hover:bg-export/15',\n  'dark:hover:bg-export-light',\n  'dark:bg-[color-mix(in_srgb,#26bd5d_15%,#212529)]',\n  'dark:bg-export',\n  'dark:text-export',\n  'dark:border-export',\n  'text-import',\n  'text-import-strong',\n  'bg-import',\n  'bg-import-strong',\n  'bg-import-subtle',\n  'bg-import-light',\n  'border-import',\n  'border-import-strong',\n  'hover:bg-import-hover',\n  'hover:bg-import-light',\n  'hover:bg-import-subtle',\n  'dark:bg-import/15',\n  'dark:hover:bg-import/15',\n  'dark:hover:bg-import-light',\n  'dark:bg-[color-mix(in_srgb,#f08829_15%,#212529)]',\n  'dark:bg-import',\n  'dark:text-import',\n  'dark:border-import',\n] as const;\n","import { computed, inject, Injectable } from '@angular/core';\n\nimport { ShippingModeService } from '@africanies/africanies-core';\n\n/**\n * Tailwind class bundle for the active shipping mode (SFN export / STN import).\n *\n * Use these for **primary** product chrome: CTAs, selected controls, progress,\n * and accent text. Semantic colors (danger / warning) stay mode-independent.\n */\nexport interface ModeColorClasses {\n  /**\n   * Accessible accent text — mode brand color in light and dark.\n   */\n  text: string;\n  /** Solid background utility, e.g. `bg-export`. */\n  bg: string;\n  /** Soft background utility, e.g. `bg-export-subtle`. */\n  bgSubtle: string;\n  /** Border matching the mode accent, e.g. `border-export`. */\n  border: string;\n  /**\n   * Filled primary CTA — `variant=\"primary\"` on buttons.\n   * Includes hover utility as a literal so Tailwind keeps it.\n   */\n  primary: string;\n  /**\n   * Transparent / text-only CTA — `variant=\"ghost-primary\"` on buttons.\n   * Mode accent text + soft hover fill.\n   */\n  ghostPrimary: string;\n  /**\n   * Soft highlight for selected / active rows (works in dark mode).\n   * Dark uses a translucent tint — fine over solid surfaces, not for\n   * sticky overlays (see {@link softSolid}).\n   */\n  soft: string;\n  /**\n   * Opaque soft fill — same tint as {@link soft}, but dark mode mixes into\n   * ink so scrolled content cannot show through (sticky table headers/cells).\n   */\n  softSolid: string;\n  /**\n   * Soft hover highlight for menus and lists.\n   */\n  softHover: string;\n  /**\n   * Active nav leaf / collapsed rail — solid mode fill + white text.\n   */\n  activeFill: string;\n  /**\n   * Stroked secondary CTA — white fill, mode border + text (portal `.btn-stroked`).\n   */\n  stroked: string;\n}\n\n/**\n * Maps {@link ShippingModeService} to mode-accent Tailwind classes.\n *\n * - **SFN** → export green is primary\n * - **STN** → import orange is primary\n *\n * WHY literal class strings: Tailwind's scanner cannot see dynamically built\n * names like `` `text-${token}` ``. Returning full literals (`text-export`, …)\n * keeps utilities in the compiled CSS. See {@link MODE_COLOR_SAFELIST}.\n *\n * @example\n * ```html\n * @let colors = modeColor.classes();\n * <button type=\"button\" [class]=\"colors.primary\">Save</button>\n * <span [class]=\"colors.text\">Mode accent</span>\n * ```\n */\n@Injectable({ providedIn: 'root' })\n/**\n * Maps {@link ShippingModeService} to mode-accent Tailwind classes.\n */\nexport class ModeColorService {\n  private readonly shippingMode = inject(ShippingModeService);\n\n  /**\n   * Mode-dependent utility classes. Recomputes when shipping mode changes.\n   */\n  readonly classes = computed<ModeColorClasses>(() => {\n    // Literal strings required for Tailwind content detection — do not interpolate.\n    if (this.shippingMode.mode() === 'sfn') {\n      return {\n        text: 'text-export dark:text-export',\n        bg: 'bg-export',\n        bgSubtle: 'bg-export-subtle',\n        border: 'border-export',\n        primary:\n          'bg-export text-white border-transparent hover:bg-export-strong dark:bg-export dark:hover:bg-export-light',\n        ghostPrimary:\n          'bg-transparent text-export border-transparent hover:bg-export-subtle dark:text-export dark:hover:bg-export/15',\n        soft: 'bg-export-subtle dark:bg-export/15',\n        softSolid:\n          'bg-export-subtle dark:bg-[color-mix(in_srgb,#26bd5d_15%,#212529)]',\n        softHover: 'hover:bg-export-subtle dark:hover:bg-export/15',\n        activeFill:\n          'bg-export text-white border-transparent hover:bg-export-strong dark:bg-export dark:text-white dark:hover:bg-export-light',\n        stroked:\n          'bg-surface text-export border-export hover:bg-export-subtle dark:bg-ink-950 dark:text-export dark:border-export dark:hover:bg-export/15',\n      };\n    }\n    return {\n      text: 'text-import-strong dark:text-import',\n      bg: 'bg-import',\n      bgSubtle: 'bg-import-subtle',\n      border: 'border-import',\n      primary:\n        'bg-import-strong text-white border-transparent hover:bg-import-hover dark:bg-import dark:hover:bg-import-light',\n      ghostPrimary:\n        'bg-transparent text-import-strong border-transparent hover:bg-import-subtle dark:text-import dark:hover:bg-import/15',\n      soft: 'bg-import-subtle dark:bg-import/15',\n      softSolid:\n        'bg-import-subtle dark:bg-[color-mix(in_srgb,#f08829_15%,#212529)]',\n      softHover: 'hover:bg-import-subtle dark:hover:bg-import/15',\n      activeFill:\n        'bg-import-strong text-white border-transparent hover:bg-import-hover dark:bg-import dark:text-white dark:hover:bg-import-light',\n      stroked:\n        'bg-surface text-import-strong border-import-strong hover:bg-import-subtle dark:bg-ink-950 dark:text-import dark:border-import dark:hover:bg-import/15',\n    };\n  });\n}\n","import { DOCUMENT } from '@angular/common';\nimport { inject, Injectable, signal } from '@angular/core';\n\nimport { AFRICANIES_THEME_KEY, STORAGE_TOKEN } from '@africanies/africanies-storage';\n\nimport type { Theme } from './theme.types';\n\n/**\n * Application light/dark theme preference.\n *\n * WHY signals (not BehaviorSubject): theme is synchronous UI state read from\n * templates and other services; a signal avoids RxJS subscription boilerplate\n * and matches Angular 22 change detection. Persistence goes through\n * {@link STORAGE_TOKEN} so tests can swap storage without touching `localStorage`.\n *\n * Applies the Tailwind `darkMode: 'class'` contract by toggling `dark` on\n * `document.documentElement`, and sets `color-scheme` so native UI (date\n * pickers, scrollbars, form controls) matches the app theme — class-based\n * dark mode alone does not restyle browser chrome.\n *\n * @example\n * ```ts\n * // app.config.ts\n * import { inject, provideAppInitializer } from '@angular/core';\n * import { ThemeService } from '@africanies/africanies-theme';\n *\n * export const appConfig = {\n *   providers: [\n *     provideAppInitializer(() => {\n *       inject(ThemeService); // applies stored / system theme once\n *     }),\n *   ],\n * };\n *\n * // In a component\n * const theme = inject(ThemeService);\n * theme.toggle();\n * theme.setTheme('dark');\n * const current = theme.theme(); // 'light' | 'dark'\n * ```\n */\n@Injectable({ providedIn: 'root' })\n/**\n * Application light/dark theme preference.\n */\nexport class ThemeService {\n  private readonly storage = inject(STORAGE_TOKEN);\n  private readonly document = inject(DOCUMENT);\n\n  /**\n   * Current theme. Prefer reading via `theme()` in templates / computed values\n   * rather than caching the string, so dark-class consumers stay in sync.\n   */\n  readonly theme = signal<Theme>(this.resolveInitialTheme());\n\n  constructor() {\n    this.applyToDocument(this.theme());\n  }\n\n  /**\n   * Sets and persists the theme, updating the `dark` class and `color-scheme`\n   * on `<html>`.\n   *\n   * @param theme - Absolute preference to store.\n   */\n  setTheme(theme: Theme): void {\n    this.theme.set(theme);\n    this.applyToDocument(theme);\n    try {\n      this.storage.set(AFRICANIES_THEME_KEY, theme);\n    } catch {\n      // Persistence failure must not block the in-session visual toggle —\n      // private browsing / quota issues are transient for theme preference.\n    }\n  }\n\n  /**\n   * Flips between light and dark.\n   *\n   * @returns The theme after the toggle.\n   */\n  toggle(): Theme {\n    const next: Theme = this.theme() === 'light' ? 'dark' : 'light';\n    this.setTheme(next);\n    return next;\n  }\n\n  private resolveInitialTheme(): Theme {\n    try {\n      const stored = this.storage.get<Theme>(AFRICANIES_THEME_KEY);\n      if (stored === 'light' || stored === 'dark') {\n        return stored;\n      }\n    } catch {\n      // Fall through to system preference when storage is unavailable.\n    }\n    return this.prefersDark() ? 'dark' : 'light';\n  }\n\n  private prefersDark(): boolean {\n    const win = this.document.defaultView;\n    return !!win?.matchMedia?.('(prefers-color-scheme: dark)').matches;\n  }\n\n  private applyToDocument(theme: Theme): void {\n    const root = this.document.documentElement;\n    if (theme === 'dark') {\n      root.classList.add('dark');\n    } else {\n      root.classList.remove('dark');\n    }\n    // Native date/time pickers follow `color-scheme`, not Tailwind's `dark` class.\n    root.style.colorScheme = theme;\n  }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}