/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/

var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// src/main.ts
var main_exports = {};
__export(main_exports, {
  default: () => MinimalTheme
});
module.exports = __toCommonJS(main_exports);
var import_obsidian12 = require("obsidian");

// src/settings/settings-interface.ts
var DEFAULT_SETTINGS = {
  lightStyle: "oxygen-light",
  darkStyle: "oxygen-dark",
  lightScheme: "oxygen-oxygen-light",
  darkScheme: "oxygen-oxygen-dark",
  editorFont: "",
  lineHeight: 1.5,
  lineWidth: 40,
  lineWidthWide: 50,
  maxWidth: 88,
  textNormal: 16,
  textSmall: 13,
  imgGrid: false,
  imgWidth: "img-default-width",
  tableWidth: "table-default-width",
  iframeWidth: "iframe-default-width",
  mapWidth: "map-default-width",
  chartWidth: "chart-default-width",
  colorfulHeadings: false,
  colorfulFrame: false,
  colorfulActiveStates: false,
  trimNames: true,
  labeledNav: false,
  fullWidthMedia: true,
  workspaceBorders: "enhanced",
  minimalStatus: true,
  underlineInternal: true,
  underlineExternal: true,
  folding: true,
  lineNumbers: false,
  readableLineLength: false,
  devBlockWidth: false,
  customPresets: [],
  enableCustomPresets: true,
  // Sidebar indentation guides
  navIndentationGuideWidth: "0px",
  navIndentationGuideColor: "rgba(var(--mono-rgb-100), 0.12)",
  // Animation settings
  animationPersonality: "default",
  animationSpeed: 1,
  // Blur background
  enableBlur: false,
  // Folder icon
  useDefaultFolderIcon: false
};

// src/settings.ts
var import_obsidian10 = require("obsidian");

// src/settings/sections/ColorSchemeSettings.ts
var import_obsidian = require("obsidian");
function buildColorSchemeSettings(containerEl, plugin) {
  const colorGroup = new import_obsidian.SettingGroup(containerEl).setHeading("Color scheme");
  colorGroup.addSetting((setting) => {
    setting.setName("Light mode color scheme").setDesc("Preset color options for light mode. To create a custom color scheme use the Style Settings plugin. See Documentation for details.").addDropdown((dropdown) => {
      dropdown.addOption("oxygen-oxygen-light", "Oxygen").addOption("oxygen-minimal-light", "Minimal").addOption("oxygen-atom-light", "Atom").addOption("oxygen-ayu-light", "Ayu").addOption("oxygen-catppuccin-light", "Catppuccin").addOption("oxygen-eink-light", "E-ink (beta)").addOption("oxygen-everforest-light", "Everforest").addOption("oxygen-flexoki-light", "Flexoki").addOption("oxygen-gruvbox-light", "Gruvbox").addOption("oxygen-macos-light", "macOS").addOption("oxygen-nord-light", "Nord").addOption("oxygen-rose-pine-light", "Ros\xE9 Pine").addOption("oxygen-notion-light", "Sky").addOption("oxygen-solarized-light", "Solarized").addOption("oxygen-things-light", "Things");
      if (plugin.settings.enableCustomPresets && plugin.settings.customPresets.length > 0) {
        plugin.settings.customPresets.sort((a, b) => a.name.localeCompare(b.name)).forEach((preset) => {
          dropdown.addOption(`oxygen-custom-${preset.id}`, preset.name);
        });
      }
      dropdown.setValue(plugin.settings.lightScheme).onChange((value) => {
        plugin.settings.lightScheme = value;
        void plugin.saveData(plugin.settings);
        plugin.updateStyle();
        plugin.updateCustomPresetCSS();
      });
    });
  });
  colorGroup.addSetting((setting) => {
    setting.setName("Light mode background contrast").setDesc("Level of contrast between sidebar and main content.").addDropdown((dropdown) => {
      dropdown.addOption("oxygen-light", "Default").addOption("oxygen-light-white", "All white").addOption("oxygen-light-tonal", "Low contrast").addOption("oxygen-light-contrast", "High contrast").setValue(plugin.settings.lightStyle).onChange((value) => {
        plugin.settings.lightStyle = value;
        void plugin.saveData(plugin.settings);
        plugin.updateStyle();
      });
    });
  });
  colorGroup.addSetting((setting) => {
    setting.setName("Dark mode color scheme").setDesc("Preset colors options for dark mode.").addDropdown((dropdown) => {
      dropdown.addOption("oxygen-oxygen-dark", "Oxygen").addOption("oxygen-minimal-dark", "Minimal").addOption("oxygen-atom-dark", "Atom").addOption("oxygen-ayu-dark", "Ayu").addOption("oxygen-catppuccin-dark", "Catppuccin").addOption("oxygen-dracula-dark", "Dracula").addOption("oxygen-eink-dark", "E-ink (beta)").addOption("oxygen-everforest-dark", "Everforest").addOption("oxygen-flexoki-dark", "Flexoki").addOption("oxygen-gruvbox-dark", "Gruvbox").addOption("oxygen-macos-dark", "macOS").addOption("oxygen-nord-dark", "Nord").addOption("oxygen-rose-pine-dark", "Ros\xE9 Pine").addOption("oxygen-notion-dark", "Sky").addOption("oxygen-solarized-dark", "Solarized").addOption("oxygen-things-dark", "Things");
      if (plugin.settings.enableCustomPresets && plugin.settings.customPresets.length > 0) {
        plugin.settings.customPresets.sort((a, b) => a.name.localeCompare(b.name)).forEach((preset) => {
          dropdown.addOption(`oxygen-custom-${preset.id}`, preset.name);
        });
      }
      dropdown.setValue(plugin.settings.darkScheme).onChange((value) => {
        plugin.settings.darkScheme = value;
        void plugin.saveData(plugin.settings);
        plugin.updateStyle();
        plugin.updateCustomPresetCSS();
      });
    });
  });
  colorGroup.addSetting((setting) => {
    setting.setName("Dark mode background contrast").setDesc("Level of contrast between sidebar and main content.").addDropdown((dropdown) => {
      dropdown.addOption("oxygen-dark", "Default").addOption("oxygen-dark-tonal", "Low contrast").addOption("oxygen-dark-black", "True black").setValue(plugin.settings.darkStyle).onChange((value) => {
        plugin.settings.darkStyle = value;
        void plugin.saveData(plugin.settings);
        plugin.updateStyle();
      });
    });
  });
}

// src/settings/sections/FeatureSettings.ts
var import_obsidian2 = require("obsidian");
function buildFeatureSettings(containerEl, plugin) {
  const featuresGroup = new import_obsidian2.SettingGroup(containerEl).setHeading("Features");
  featuresGroup.addSetting((setting) => {
    setting.setName("Text labels for primary navigation").setDesc("Navigation items in the left sidebar uses text labels. See Documentation for details.").addToggle((toggle) => {
      toggle.setValue(plugin.settings.labeledNav).onChange((value) => {
        plugin.settings.labeledNav = value;
        void plugin.saveData(plugin.settings);
        plugin.refresh();
      });
    });
  });
  featuresGroup.addSetting((setting) => {
    setting.setName("Colorful window frame").setDesc("The top area of the app uses your accent color.").addToggle((toggle) => {
      toggle.setValue(plugin.settings.colorfulFrame).onChange((value) => {
        plugin.settings.colorfulFrame = value;
        void plugin.saveData(plugin.settings);
        plugin.refresh();
      });
    });
  });
  featuresGroup.addSetting((setting) => {
    setting.setName("Colorful active states").setDesc("Active file and menu items use your accent color.").addToggle((toggle) => {
      toggle.setValue(plugin.settings.colorfulActiveStates).onChange((value) => {
        plugin.settings.colorfulActiveStates = value;
        void plugin.saveData(plugin.settings);
        plugin.refresh();
      });
    });
  });
  featuresGroup.addSetting((setting) => {
    setting.setName("Colorful headings").setDesc("Headings use a different color for each size.").addToggle((toggle) => {
      toggle.setValue(plugin.settings.colorfulHeadings).onChange((value) => {
        plugin.settings.colorfulHeadings = value;
        void plugin.saveData(plugin.settings);
        plugin.refresh();
      });
    });
  });
  featuresGroup.addSetting((setting) => {
    setting.setName("Minimal status bar").setDesc("Turn off to use full-width status bar.").addToggle((toggle) => {
      toggle.setValue(plugin.settings.minimalStatus).onChange((value) => {
        plugin.settings.minimalStatus = value;
        void plugin.saveData(plugin.settings);
        plugin.refresh();
      });
    });
  });
  featuresGroup.addSetting((setting) => {
    setting.setName("Trim file names in sidebars").setDesc("Use ellipses to fit file names on a single line.").addToggle((toggle) => {
      toggle.setValue(plugin.settings.trimNames).onChange((value) => {
        plugin.settings.trimNames = value;
        void plugin.saveData(plugin.settings);
        plugin.refresh();
      });
    });
  });
  featuresGroup.addSetting((setting) => {
    setting.setName("Borders").setDesc("Border style for workspace elements.").addDropdown((dropdown) => {
      dropdown.addOption("enhanced", "Enhanced").addOption("default", "Default").addOption("none", "None").setValue(plugin.settings.workspaceBorders).onChange((value) => {
        plugin.settings.workspaceBorders = value;
        void plugin.saveData(plugin.settings);
        plugin.refresh();
      });
    });
  });
  featuresGroup.addSetting((setting) => {
    setting.setName("Indentation guides thickness").setDesc("Thickness of indentation guides in the sidebar file explorer.").addDropdown((dropdown) => {
      dropdown.addOption("0px", "None").addOption("1px", "Thin").addOption("2px", "Medium").addOption("3px", "Thick").setValue(plugin.settings.navIndentationGuideWidth).onChange((value) => {
        plugin.settings.navIndentationGuideWidth = value;
        void plugin.saveData(plugin.settings);
        plugin.refresh();
      });
    });
  });
  featuresGroup.addSetting((setting) => {
    setting.setName("Indentation guides color").setDesc("Color of indentation guides in the sidebar.").addDropdown((dropdown) => {
      dropdown.addOption("rgba(var(--mono-rgb-100), 0.12)", "Subtle").addOption("var(--text-faint)", "Strong").addOption("var(--color-accent)", "Accent color").setValue(plugin.settings.navIndentationGuideColor).onChange((value) => {
        plugin.settings.navIndentationGuideColor = value;
        void plugin.saveData(plugin.settings);
        plugin.refresh();
      });
    });
  });
  featuresGroup.addSetting((setting) => {
    setting.setName("Underline internal links").setDesc("Show underlines on internal links.").addToggle((toggle) => {
      toggle.setValue(plugin.settings.underlineInternal).onChange((value) => {
        plugin.settings.underlineInternal = value;
        void plugin.saveData(plugin.settings);
        plugin.refresh();
      });
    });
  });
  featuresGroup.addSetting((setting) => {
    setting.setName("Underline external links").setDesc("Show underlines on external links.").addToggle((toggle) => {
      toggle.setValue(plugin.settings.underlineExternal).onChange((value) => {
        plugin.settings.underlineExternal = value;
        void plugin.saveData(plugin.settings);
        plugin.refresh();
      });
    });
  });
  featuresGroup.addSetting((setting) => {
    setting.setName("Maximize media").setDesc("Images and videos fill the width of the line.").addToggle((toggle) => {
      toggle.setValue(plugin.settings.fullWidthMedia).onChange((value) => {
        plugin.settings.fullWidthMedia = value;
        void plugin.saveData(plugin.settings);
        plugin.refresh();
      });
    });
  });
  featuresGroup.addSetting((setting) => {
    if (!("enableBlur" in plugin.settings)) {
      plugin.settings.enableBlur = false;
    }
    setting.setName("Enable background blur").setDesc("Adds background blur to modal dialogs. Disable if scrolling becomes laggy. Not available on mobile devices.").addToggle((toggle) => {
      toggle.setValue(plugin.settings.enableBlur).onChange((value) => {
        plugin.settings.enableBlur = value;
        void plugin.saveData(plugin.settings);
        plugin.refresh();
      });
    });
  });
  featuresGroup.addSetting((setting) => {
    if (!("useDefaultFolderIcon" in plugin.settings)) {
      plugin.settings.useDefaultFolderIcon = false;
    }
    setting.setName("Use default Obsidian folder icon").setDesc("Toggle to use Obsidian's default file explorer icon instead of the folder-closed icon.").addToggle((toggle) => {
      toggle.setValue(plugin.settings.useDefaultFolderIcon).onChange((value) => {
        plugin.settings.useDefaultFolderIcon = value;
        void plugin.saveData(plugin.settings);
        plugin.refresh();
      });
    });
  });
}

// src/settings/sections/LayoutSettings.ts
var import_obsidian3 = require("obsidian");
function buildLayoutSettings(containerEl, plugin) {
  const layoutGroup = new import_obsidian3.SettingGroup(containerEl).setHeading("Layout");
  layoutGroup.addSetting((setting) => {
    setting.setName("Image grids").setDesc("Turn consecutive images into columns. To make a new row, add an extra line break between images. These options can also be defined on a per-file basis, see Documentation for details.").addToggle((toggle) => {
      toggle.setValue(plugin.settings.imgGrid).onChange((value) => {
        plugin.settings.imgGrid = value;
        void plugin.saveData(plugin.settings);
        plugin.refresh();
      });
    });
  });
  layoutGroup.addSetting((setting) => {
    setting.setName("Chart width").setDesc("Default width for chart blocks.").addDropdown((dropdown) => {
      dropdown.addOption("chart-default-width", "Default").addOption("chart-wide", "Wide line width").addOption("chart-max", "Maximum line width").addOption("chart-100", "100% pane width").setValue(plugin.settings.chartWidth).onChange((value) => {
        plugin.settings.chartWidth = value;
        void plugin.saveData(plugin.settings);
        plugin.refresh();
      });
    });
  });
  layoutGroup.addSetting((setting) => {
    setting.setName("Iframe width").setDesc("Default width for iframe blocks.").addDropdown((dropdown) => {
      dropdown.addOption("iframe-default-width", "Default").addOption("iframe-wide", "Wide line width").addOption("iframe-max", "Maximum line width").addOption("iframe-100", "100% pane width").setValue(plugin.settings.iframeWidth).onChange((value) => {
        plugin.settings.iframeWidth = value;
        void plugin.saveData(plugin.settings);
        plugin.refresh();
      });
    });
  });
  layoutGroup.addSetting((setting) => {
    setting.setName("Image width").setDesc("Default width for image blocks.").addDropdown((dropdown) => {
      dropdown.addOption("img-default-width", "Default").addOption("img-wide", "Wide line width").addOption("img-max", "Maximum line width").addOption("img-100", "100% pane width").setValue(plugin.settings.imgWidth).onChange((value) => {
        plugin.settings.imgWidth = value;
        void plugin.saveData(plugin.settings);
        plugin.refresh();
      });
    });
  });
  layoutGroup.addSetting((setting) => {
    setting.setName("Map width").setDesc("Default width for map blocks.").addDropdown((dropdown) => {
      dropdown.addOption("map-default-width", "Default").addOption("map-wide", "Wide line width").addOption("map-max", "Maximum line width").addOption("map-100", "100% pane width").setValue(plugin.settings.mapWidth).onChange((value) => {
        plugin.settings.mapWidth = value;
        void plugin.saveData(plugin.settings);
        plugin.refresh();
      });
    });
  });
  layoutGroup.addSetting((setting) => {
    setting.setName("Table width").setDesc("Default width for table and Dataview blocks.").addDropdown((dropdown) => {
      dropdown.addOption("table-default-width", "Default").addOption("table-wide", "Wide line width").addOption("table-max", "Maximum line width").addOption("table-100", "100% pane width").setValue(plugin.settings.tableWidth).onChange((value) => {
        plugin.settings.tableWidth = value;
        void plugin.saveData(plugin.settings);
        plugin.refresh();
      });
    });
  });
}

// src/settings/sections/TypographySettings.ts
var import_obsidian4 = require("obsidian");
function buildTypographySettings(containerEl, plugin) {
  const typographyGroup = new import_obsidian4.SettingGroup(containerEl).setHeading("Typography");
  typographyGroup.addSetting((setting) => {
    setting.setName("Text font size").setDesc("Used for the main text (default 16).").addText((text) => {
      text.setPlaceholder("16").setValue((plugin.settings.textNormal || "") + "").onChange((value) => {
        plugin.settings.textNormal = parseFloat(value);
        void plugin.saveData(plugin.settings);
        plugin.setFontSize();
      });
    });
  });
  typographyGroup.addSetting((setting) => {
    setting.setName("Small font size").setDesc("Used for text in the sidebars and tabs (default 13).").addText((text) => {
      text.setPlaceholder("13").setValue((plugin.settings.textSmall || "") + "").onChange((value) => {
        plugin.settings.textSmall = parseFloat(value);
        void plugin.saveData(plugin.settings);
        plugin.refresh();
      });
    });
  });
  typographyGroup.addSetting((setting) => {
    setting.setName("Line height").setDesc("Line height of text (default 1.5).").addText((text) => {
      text.setPlaceholder("1.5").setValue((plugin.settings.lineHeight || "") + "").onChange((value) => {
        plugin.settings.lineHeight = parseFloat(value);
        void plugin.saveData(plugin.settings);
        plugin.refresh();
      });
    });
  });
  typographyGroup.addSetting((setting) => {
    setting.setName("Normal line width").setDesc("Number of characters per line (default 40).").addText((text) => {
      text.setPlaceholder("40").setValue((plugin.settings.lineWidth || "") + "").onChange((value) => {
        plugin.settings.lineWidth = parseInt(value.trim());
        void plugin.saveData(plugin.settings);
        plugin.refresh();
      });
    });
  });
  typographyGroup.addSetting((setting) => {
    setting.setName("Wide line width").setDesc("Number of characters per line for wide elements (default 50).").addText((text) => {
      text.setPlaceholder("50").setValue((plugin.settings.lineWidthWide || "") + "").onChange((value) => {
        plugin.settings.lineWidthWide = parseInt(value.trim());
        void plugin.saveData(plugin.settings);
        plugin.refresh();
      });
    });
  });
  typographyGroup.addSetting((setting) => {
    setting.setName("Maximum line width %").setDesc("Percentage of space inside a pane that a line can fill (default 88).").addText((text) => {
      text.setPlaceholder("88").setValue((plugin.settings.maxWidth || "") + "").onChange((value) => {
        plugin.settings.maxWidth = parseInt(value.trim());
        void plugin.saveData(plugin.settings);
        plugin.refresh();
      });
    });
  });
  typographyGroup.addSetting((setting) => {
    setting.setName("Editor font").setDesc("Overrides the text font defined in Obsidian appearance settings when in edit mode.").addText((text) => {
      text.setPlaceholder("").setValue((plugin.settings.editorFont || "") + "").onChange((value) => {
        plugin.settings.editorFont = value;
        void plugin.saveData(plugin.settings);
        plugin.refresh();
      });
    });
  });
}

// src/settings/sections/CustomPresetSettings.ts
var import_obsidian8 = require("obsidian");

// src/utils/css-props.ts
function setCssProps(element, props) {
  for (const [key, value] of Object.entries(props)) {
    element.style.setProperty(key, value);
  }
}
function setCssProp(element, prop, value) {
  element.style.setProperty(prop, value);
}

// src/utils/color-utils.ts
function hexToHSL(hex) {
  hex = hex.replace("#", "");
  const r = parseInt(hex.substring(0, 2), 16) / 255;
  const g = parseInt(hex.substring(2, 4), 16) / 255;
  const b = parseInt(hex.substring(4, 6), 16) / 255;
  const max = Math.max(r, g, b);
  const min = Math.min(r, g, b);
  let h = 0, s = 0, l = (max + min) / 2;
  if (max !== min) {
    const d = max - min;
    s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
    switch (max) {
      case r:
        h = (g - b) / d + (g < b ? 6 : 0);
        break;
      case g:
        h = (b - r) / d + 2;
        break;
      case b:
        h = (r - g) / d + 4;
        break;
    }
    h /= 6;
  }
  return {
    h: Math.round(h * 360),
    s: Math.round(s * 100),
    l: Math.round(l * 100)
  };
}
function hslToHex(hsl) {
  const h = hsl.h / 360;
  const s = hsl.s / 100;
  const l = hsl.l / 100;
  const hue2rgb = (p, q, t) => {
    if (t < 0) t += 1;
    if (t > 1) t -= 1;
    if (t < 1 / 6) return p + (q - p) * 6 * t;
    if (t < 1 / 2) return q;
    if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
    return p;
  };
  let r, g, b;
  if (s === 0) {
    r = g = b = l;
  } else {
    const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
    const p = 2 * l - q;
    r = hue2rgb(p, q, h + 1 / 3);
    g = hue2rgb(p, q, h);
    b = hue2rgb(p, q, h - 1 / 3);
  }
  const toHex = (c) => {
    const hex = Math.round(c * 255).toString(16);
    return hex.length === 1 ? "0" + hex : hex;
  };
  return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
}
function validateHex(hex) {
  const hexRegex = /^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}|[A-Fa-f0-9]{8}|[A-Fa-f0-9]{4})$/;
  return hexRegex.test(hex);
}
function generateColorSwatch(preset) {
  const swatch = document.createElement("div");
  swatch.className = "custom-preset-swatch";
  const lightBaseHex = hslToHex(preset.light.base);
  const lightAccentHex = hslToHex(preset.light.accent);
  const darkBaseHex = hslToHex(preset.dark.base);
  setCssProps(swatch, {
    "--swatch-gradient-start": lightBaseHex,
    "--swatch-gradient-mid": lightAccentHex,
    "--swatch-gradient-end": darkBaseHex
  });
  return swatch;
}
function sanitizePresetName(name) {
  return name.trim().replace(/[<>:"/\\|?*]/g, "");
}
function generatePresetId(name) {
  return sanitizePresetName(name).toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "").substring(0, 50);
}
function validatePresetId(id) {
  const idRegex = /^[a-z0-9-]+$/;
  return idRegex.test(id) && id.length > 0 && id.length <= 50;
}
function isPresetIdUnique(id, existingPresets, excludeId) {
  return !existingPresets.some((preset) => preset.id === id && preset.id !== excludeId);
}

// src/presets/PresetManager.ts
var PresetManager = class {
  /**
   * Validate preset ID format and uniqueness
   */
  static validatePresetId(id, existingPresets, excludeId) {
    return validatePresetId(id) && isPresetIdUnique(id, existingPresets, excludeId);
  }
  /**
   * Sanitize preset name
   */
  static sanitizePresetName(name) {
    return sanitizePresetName(name);
  }
  /**
   * Create a new preset with validation
   */
  static createPreset(name, author = "", existingPresets = []) {
    const sanitizedName = this.sanitizePresetName(name);
    if (!sanitizedName) {
      throw new Error("Preset name cannot be empty");
    }
    let id = generatePresetId(sanitizedName);
    let counter = 1;
    while (!this.validatePresetId(id, existingPresets)) {
      id = `${generatePresetId(sanitizedName)}-${counter}`;
      counter++;
    }
    return {
      id,
      name: sanitizedName,
      author: author.trim(),
      version: "1.0.0",
      light: {
        base: { h: 210, s: 2, l: 96 },
        // Light background
        accent: { h: 200, s: 80, l: 50 },
        colors: {}
      },
      dark: {
        base: { h: 210, s: 2, l: 13 },
        // Dark background
        accent: { h: 200, s: 80, l: 50 },
        colors: {}
      }
    };
  }
  /**
   * Update an existing preset
   */
  static updatePreset(id, updates, existingPresets) {
    const existingPreset = existingPresets.find((p) => p.id === id);
    if (!existingPreset) {
      throw new Error(`Preset with ID "${id}" not found`);
    }
    const updatedPreset = { ...existingPreset, ...updates };
    if (updates.id && updates.id !== id) {
      if (!this.validatePresetId(updates.id, existingPresets, id)) {
        throw new Error(`Preset ID "${updates.id}" is invalid or already exists`);
      }
    }
    if (updates.name) {
      updatedPreset.name = this.sanitizePresetName(updates.name);
      if (!updatedPreset.name) {
        throw new Error("Preset name cannot be empty");
      }
    }
    return updatedPreset;
  }
  /**
   * Delete a preset
   */
  static deletePreset(id, existingPresets) {
    return existingPresets.filter((preset) => preset.id !== id);
  }
  /**
   * Export preset as JSON
   */
  static exportPresetAsJSON(preset) {
    return JSON.stringify(preset, null, 2);
  }
  /**
   * Import preset from JSON
   */
  static importPresetFromJSON(json) {
    try {
      const parsed = JSON.parse(json);
      if (typeof parsed !== "object" || parsed === null) {
        throw new Error("Invalid preset format: not an object");
      }
      const data = parsed;
      if (!data.id || !data.name || !data.light || !data.dark) {
        throw new Error("Invalid preset format: missing required fields");
      }
      if (!data.light.base || !data.light.accent || !data.dark.base || !data.dark.accent) {
        throw new Error("Invalid preset format: missing base or accent colors");
      }
      const validateHSL = (hsl) => {
        if (typeof hsl !== "object" || hsl === null) return false;
        const h = hsl.h;
        const s = hsl.s;
        const l = hsl.l;
        return typeof h === "number" && h >= 0 && h <= 360 && typeof s === "number" && s >= 0 && s <= 100 && typeof l === "number" && l >= 0 && l <= 100;
      };
      if (!validateHSL(data.light.base) || !validateHSL(data.light.accent) || !validateHSL(data.dark.base) || !validateHSL(data.dark.accent)) {
        throw new Error("Invalid preset format: HSL values out of range");
      }
      const extractColors = (colors) => {
        if (typeof colors === "object" && colors !== null) {
          const result = {};
          for (const [key, value] of Object.entries(colors)) {
            if (typeof value === "string") {
              result[key] = value;
            }
          }
          return result;
        }
        return {};
      };
      const extractFrameOffset = (offset) => {
        if (typeof offset === "number") {
          return offset;
        }
        return void 0;
      };
      if (typeof data.id !== "string") {
        throw new Error("Invalid preset format: id must be a string");
      }
      if (typeof data.name !== "string") {
        throw new Error("Invalid preset format: name must be a string");
      }
      const idStr = data.id;
      const nameStr = data.name;
      const authorStr = typeof data.author === "string" ? data.author : "";
      const versionStr = typeof data.version === "string" ? data.version : "1.0.0";
      const preset = {
        id: this.sanitizePresetName(idStr),
        name: this.sanitizePresetName(nameStr),
        author: authorStr,
        version: versionStr,
        light: {
          base: data.light.base,
          accent: data.light.accent,
          colors: extractColors(data.light.colors),
          frameLightnessOffset: extractFrameOffset(data.light.frameLightnessOffset)
        },
        dark: {
          base: data.dark.base,
          accent: data.dark.accent,
          colors: extractColors(data.dark.colors),
          frameLightnessOffset: extractFrameOffset(data.dark.frameLightnessOffset)
        }
      };
      if (!preset.id || !preset.name) {
        throw new Error("Invalid preset format: ID or name is empty after sanitization");
      }
      return preset;
    } catch (error) {
      if (error instanceof SyntaxError) {
        throw new Error("Invalid JSON format");
      }
      throw error;
    }
  }
  /**
   * Get preset by ID
   */
  static getPresetById(id, presets) {
    return presets.find((preset) => preset.id === id);
  }
  /**
   * Check if preset is currently active
   */
  static isPresetActive(presetId, lightScheme, darkScheme) {
    return lightScheme === `oxygen-custom-${presetId}` || darkScheme === `oxygen-custom-${presetId}`;
  }
  /**
   * Generate a preview of the preset colors
   */
  static generatePresetPreview(preset) {
    var _a, _b, _c, _d;
    return {
      light: [
        hslToHex(preset.light.base),
        hslToHex(preset.light.accent),
        ((_a = preset.light.colors) == null ? void 0 : _a.bg1) || hslToHex(preset.light.base),
        ((_b = preset.light.colors) == null ? void 0 : _b.tx1) || hslToHex({ ...preset.light.base, l: Math.max(0, preset.light.base.l - 30) })
      ],
      dark: [
        hslToHex(preset.dark.base),
        hslToHex(preset.dark.accent),
        ((_c = preset.dark.colors) == null ? void 0 : _c.bg1) || hslToHex(preset.dark.base),
        ((_d = preset.dark.colors) == null ? void 0 : _d.tx1) || hslToHex({ ...preset.dark.base, l: Math.min(100, preset.dark.base.l + 30) })
      ]
    };
  }
};

// src/modals/PresetEditorModal.ts
var import_obsidian5 = require("obsidian");

// src/utils/preset-color-defaults.ts
function getDefaultColorForKey(key, palette) {
  const baseH = palette.base.h;
  const baseS = palette.base.s;
  const baseL = palette.base.l;
  const accentH = palette.accent.h;
  const isLightBase = baseL > 50;
  const syntaxDefaults = {
    "red": "#e74c3c",
    "orange": "#e67e22",
    "yellow": "#f39c12",
    "green": "#27ae60",
    "cyan": "#16a085",
    "blue": "#3498db",
    "purple": "#9b59b6",
    "pink": "#e91e63"
  };
  if (syntaxDefaults[key]) {
    return syntaxDefaults[key];
  }
  let s, l;
  switch (key) {
    case "bg1":
      return hslToHex({ h: baseH, s: baseS, l: baseL });
    case "bg2":
      l = isLightBase ? Math.max(0, baseL - 5) : Math.min(100, baseL + 5);
      return hslToHex({ h: baseH, s: baseS, l });
    case "bg3":
      l = isLightBase ? Math.max(0, baseL - 10) : Math.min(100, baseL + 10);
      return hslToHex({ h: baseH, s: baseS, l });
    case "ui1":
      l = isLightBase ? Math.max(0, baseL - 15) : Math.min(100, baseL + 15);
      return hslToHex({ h: baseH, s: baseS, l });
    case "ui2":
      l = isLightBase ? Math.max(0, baseL - 10) : Math.min(100, baseL + 10);
      return hslToHex({ h: baseH, s: baseS, l });
    case "ui3":
      l = isLightBase ? Math.max(0, baseL - 5) : Math.min(100, baseL + 5);
      return hslToHex({ h: baseH, s: baseS, l });
    case "tx1":
      s = Math.max(0, baseS - 10);
      l = isLightBase ? Math.max(0, baseL - 87) : Math.min(100, baseL + 77);
      return hslToHex({ h: baseH, s, l });
    case "tx2":
      s = Math.max(0, baseS - 20);
      l = isLightBase ? Math.max(0, baseL - 53) : Math.min(100, baseL + 45);
      return hslToHex({ h: baseH, s, l });
    case "tx3":
      s = Math.max(0, baseS - 10);
      l = isLightBase ? Math.max(0, baseL - 78) : Math.min(100, baseL + 30);
      return hslToHex({ h: baseH, s, l });
    case "tx4":
      s = Math.max(0, baseS - 10);
      l = isLightBase ? Math.max(0, baseL - 48) : Math.min(100, baseL + 40);
      return hslToHex({ h: baseH, s, l });
    case "hl1":
      return hslToHex({ h: accentH, s: 50, l: 40 });
    case "hl2":
      return "#ffb150";
    default:
      return "#000000";
  }
}

// src/modals/components/PresetColorControls.ts
function createHSLControls(container, hsl, onChange) {
  const controls = container.createEl("div", { cls: "hsl-controls" });
  const hslCopy = { ...hsl };
  const previewWrapper = controls.createEl("div", { cls: "color-preview-wrapper" });
  const preview = previewWrapper.createEl("div", { cls: "color-preview" });
  setCssProp(preview, "--preview-color", hslToHex(hslCopy));
  preview.title = "Click to pick a color with hex input";
  const colorInput = previewWrapper.createEl("input", { type: "color", cls: "hsl-color-input-overlay" });
  colorInput.value = hslToHex(hslCopy);
  const updatePreview = () => {
    const hexColor = hslToHex(hslCopy);
    setCssProp(preview, "--preview-color", hexColor);
    colorInput.value = hexColor;
  };
  colorInput.onchange = () => {
    const newHSL = hexToHSL(colorInput.value);
    hslCopy.h = newHSL.h;
    hslCopy.s = newHSL.s;
    hslCopy.l = newHSL.l;
    hueSlider.value = newHSL.h.toString();
    hueValue.textContent = newHSL.h.toString();
    satSlider.value = newHSL.s.toString();
    satValue.textContent = newHSL.s.toString();
    lightSlider.value = newHSL.l.toString();
    lightValue.textContent = newHSL.l.toString();
    updatePreview();
    onChange(hslCopy);
  };
  const hueControl = controls.createEl("div", { cls: "hsl-control" });
  hueControl.createEl("label", { text: "Hue" });
  const hueSlider = hueControl.createEl("input", { type: "range" });
  hueSlider.min = "0";
  hueSlider.max = "360";
  const hueValue = hueControl.createEl("span", { text: hsl.h.toString() });
  hueSlider.value = hsl.h.toString();
  hueSlider.oninput = () => {
    hslCopy.h = parseInt(hueSlider.value);
    hueValue.textContent = hslCopy.h.toString();
    updatePreview();
    onChange(hslCopy);
  };
  const satControl = controls.createEl("div", { cls: "hsl-control" });
  satControl.createEl("label", { text: "Saturation" });
  const satSlider = satControl.createEl("input", { type: "range" });
  satSlider.min = "0";
  satSlider.max = "100";
  const satValue = satControl.createEl("span", { text: hsl.s.toString() });
  satSlider.value = hsl.s.toString();
  satSlider.oninput = () => {
    hslCopy.s = parseInt(satSlider.value);
    satValue.textContent = hslCopy.s.toString();
    updatePreview();
    onChange(hslCopy);
  };
  const lightControl = controls.createEl("div", { cls: "hsl-control" });
  lightControl.createEl("label", { text: "Lightness" });
  const lightSlider = lightControl.createEl("input", { type: "range" });
  lightSlider.min = "0";
  lightSlider.max = "100";
  const lightValue = lightControl.createEl("span", { text: hsl.l.toString() });
  lightSlider.value = hsl.l.toString();
  lightSlider.oninput = () => {
    hslCopy.l = parseInt(lightSlider.value);
    lightValue.textContent = hslCopy.l.toString();
    updatePreview();
    onChange(hslCopy);
  };
}
function createColorOverride(container, label, key, colors, palette, onUpdate) {
  const override = container.createEl("div", { cls: "color-override collapsible-item" });
  const header = override.createEl("div", { cls: "override-header" });
  const toggle = header.createEl("input", { type: "checkbox" });
  header.createEl("label", { text: label });
  const colorInputWrapper = header.createEl("div", { cls: "color-input-wrapper" });
  const colorPreview = colorInputWrapper.createEl("div", { cls: "color-preview-swatch" });
  const colorInput = colorInputWrapper.createEl("input", { type: "color", cls: "hsl-color-input-overlay" });
  colorInput.disabled = true;
  let originalColor = null;
  const updateColorPreview = (color) => {
    setCssProp(colorPreview, "--preview-color", color);
    colorInput.value = color;
  };
  if (colors[key]) {
    toggle.checked = true;
    colorInput.disabled = false;
    updateColorPreview(colors[key]);
    originalColor = colors[key];
  } else {
    const defaultColor = getDefaultColorForKey(key, palette);
    updateColorPreview(defaultColor);
    originalColor = defaultColor;
  }
  colorInput.onclick = () => {
    if (!toggle.checked) {
      toggle.checked = true;
      colorInput.disabled = false;
      const restoredColor = originalColor || colors[key] || getDefaultColorForKey(key, palette);
      colors[key] = restoredColor;
      updateColorPreview(restoredColor);
      originalColor = restoredColor;
      onUpdate();
    }
  };
  toggle.onchange = () => {
    if (toggle.checked) {
      colorInput.disabled = false;
      const restoredColor = originalColor || colors[key] || getDefaultColorForKey(key, palette);
      colors[key] = restoredColor;
      updateColorPreview(restoredColor);
      originalColor = restoredColor;
    } else {
      colorInput.disabled = true;
      originalColor = colors[key] || originalColor;
      delete colors[key];
    }
    onUpdate();
  };
  colorInput.onchange = () => {
    if (validateHex(colorInput.value)) {
      colors[key] = colorInput.value;
      originalColor = colorInput.value;
      updateColorPreview(colorInput.value);
      onUpdate();
    }
  };
  colorInput.oninput = () => {
    if (validateHex(colorInput.value)) {
      colors[key] = colorInput.value;
      originalColor = colorInput.value;
      updateColorPreview(colorInput.value);
      onUpdate();
    }
  };
  return override;
}

// src/types/obsidian-extensions.ts
function getVaultConfig(app, key) {
  const extApp = app;
  return extApp.vault.getConfig(key);
}
function setVaultConfig(app, key, value) {
  const extApp = app;
  extApp.vault.setConfig(key, value);
}
function setTheme(app, theme) {
  const extApp = app;
  extApp.setTheme(theme);
}
function onVaultConfigChanged(app, callback) {
  const extApp = app;
  return extApp.vault.on("config-changed", callback);
}
function updateFontSize(app) {
  const extApp = app;
  if (typeof extApp.updateFontSize === "function") {
    extApp.updateFontSize();
  }
}

// src/constants.ts
var CSS_CLASSES = {
  PLUGIN_THEME: "oxygen-theme",
  THEME_LIGHT: "theme-light",
  THEME_DARK: "theme-dark",
  CUSTOM_PRESETS_STYLE: "oxygen-custom-presets",
  THEME_OVERRIDE: "data-theme-override"
};
var LIGHT_STYLES = [
  "oxygen-light",
  "oxygen-light-tonal",
  "oxygen-light-contrast",
  "oxygen-light-white"
];
var DARK_STYLES = [
  "oxygen-dark",
  "oxygen-dark-tonal",
  "oxygen-dark-black"
];
var LIGHT_SCHEMES = [
  "oxygen-oxygen-light",
  "oxygen-minimal-light",
  "oxygen-atom-light",
  "oxygen-ayu-light",
  "oxygen-catppuccin-light",
  "oxygen-eink-light",
  "oxygen-everforest-light",
  "oxygen-flexoki-light",
  "oxygen-gruvbox-light",
  "oxygen-macos-light",
  "oxygen-nord-light",
  "oxygen-rose-pine-light",
  "oxygen-notion-light",
  "oxygen-solarized-light",
  "oxygen-things-light"
];
var DARK_SCHEMES = [
  "oxygen-oxygen-dark",
  "oxygen-minimal-dark",
  "oxygen-atom-dark",
  "oxygen-ayu-dark",
  "oxygen-catppuccin-dark",
  "oxygen-dracula-dark",
  "oxygen-eink-dark",
  "oxygen-everforest-dark",
  "oxygen-flexoki-dark",
  "oxygen-gruvbox-dark",
  "oxygen-macos-dark",
  "oxygen-nord-dark",
  "oxygen-rose-pine-dark",
  "oxygen-notion-dark",
  "oxygen-solarized-dark",
  "oxygen-things-dark"
];
var TABLE_WIDTH_STYLES = [
  "table-100",
  "table-default-width",
  "table-wide",
  "table-max"
];
var IFRAME_WIDTH_STYLES = [
  "iframe-100",
  "iframe-default-width",
  "iframe-wide",
  "iframe-max"
];
var IMAGE_WIDTH_STYLES = [
  "img-100",
  "img-default-width",
  "img-wide",
  "img-max"
];
var MAP_WIDTH_STYLES = [
  "map-100",
  "map-default-width",
  "map-wide",
  "map-max"
];
var CHART_WIDTH_STYLES = [
  "chart-100",
  "chart-default-width",
  "chart-wide",
  "chart-max"
];
var COMMAND_IDS = {
  // Font commands
  INCREASE_FONT: "increase-body-font-size",
  DECREASE_FONT: "decrease-body-font-size",
  // Style cycling commands
  CYCLE_DARK_STYLE: "toggle-minimal-dark-cycle",
  CYCLE_LIGHT_STYLE: "toggle-minimal-light-cycle",
  // Feature toggle commands
  TOGGLE_BORDERS: "toggle-hidden-borders",
  TOGGLE_COLORFUL_HEADINGS: "toggle-colorful-headings",
  TOGGLE_COLORFUL_FRAME: "toggle-minimal-colorful-frame",
  TOGGLE_IMAGE_GRID: "toggle-minimal-img-grid",
  TOGGLE_THEME: "toggle-minimal-switch",
  // Width cycling commands
  CYCLE_TABLE_WIDTH: "cycle-minimal-table-width",
  CYCLE_IMAGE_WIDTH: "cycle-minimal-image-width",
  CYCLE_IFRAME_WIDTH: "cycle-minimal-iframe-width",
  CYCLE_CHART_WIDTH: "cycle-minimal-chart-width",
  CYCLE_MAP_WIDTH: "cycle-minimal-map-width",
  // Light style commands
  LIGHT_DEFAULT: "toggle-minimal-light-default",
  LIGHT_WHITE: "toggle-minimal-light-white",
  LIGHT_TONAL: "toggle-minimal-light-tonal",
  LIGHT_CONTRAST: "toggle-minimal-light-contrast",
  // Dark style commands
  DARK_DEFAULT: "toggle-minimal-dark-default",
  DARK_TONAL: "toggle-minimal-dark-tonal",
  DARK_BLACK: "toggle-minimal-dark-black",
  // Custom preset commands
  CREATE_PRESET: "create-custom-preset",
  IMPORT_PRESET: "import-custom-preset",
  CYCLE_PRESETS_LIGHT: "cycle-custom-presets-light",
  CYCLE_PRESETS_DARK: "cycle-custom-presets-dark",
  // Dev commands
  DEV_BLOCK_WIDTH: "toggle-minimal-dev-block-width",
  // Settings command
  OPEN_SETTINGS: "oxygen-settings:open-settings"
};
var DEFAULTS = {
  FONT_SIZE_NORMAL: 16,
  FONT_SIZE_SMALL: 13,
  LINE_HEIGHT: 1.5,
  LINE_WIDTH: 40,
  LINE_WIDTH_WIDE: 50,
  MAX_WIDTH: 88,
  FONT_STEP: 0.5
};
var VAULT_CONFIG = {
  BASE_FONT_SIZE: "baseFontSize",
  FOLD_HEADING: "foldHeading",
  SHOW_LINE_NUMBER: "showLineNumber",
  READABLE_LINE_LENGTH: "readableLineLength",
  THEME: "theme"
};
var OBSIDIAN_THEMES = {
  LIGHT: "moonstone",
  DARK: "obsidian",
  SYSTEM: "system"
};
var OXYGEN_THEME_NAME = "Oxygen";
var SCHEME_DISPLAY_NAMES = {
  // Light schemes
  "oxygen-oxygen-light": "Oxygen",
  "oxygen-minimal-light": "Minimal",
  "oxygen-atom-light": "Atom",
  "oxygen-ayu-light": "Ayu",
  "oxygen-catppuccin-light": "Catppuccin",
  "oxygen-eink-light": "E-ink (beta)",
  "oxygen-everforest-light": "Everforest",
  "oxygen-flexoki-light": "Flexoki",
  "oxygen-gruvbox-light": "Gruvbox",
  "oxygen-macos-light": "macOS",
  "oxygen-nord-light": "Nord",
  "oxygen-rose-pine-light": "Ros\xE9 Pine",
  "oxygen-notion-light": "Sky",
  "oxygen-solarized-light": "Solarized",
  "oxygen-things-light": "Things",
  // Dark schemes
  "oxygen-oxygen-dark": "Oxygen",
  "oxygen-minimal-dark": "Minimal",
  "oxygen-atom-dark": "Atom",
  "oxygen-ayu-dark": "Ayu",
  "oxygen-catppuccin-dark": "Catppuccin",
  "oxygen-dracula-dark": "Dracula",
  "oxygen-eink-dark": "E-ink (beta)",
  "oxygen-everforest-dark": "Everforest",
  "oxygen-flexoki-dark": "Flexoki",
  "oxygen-gruvbox-dark": "Gruvbox",
  "oxygen-macos-dark": "macOS",
  "oxygen-nord-dark": "Nord",
  "oxygen-rose-pine-dark": "Ros\xE9 Pine",
  "oxygen-notion-dark": "Sky",
  "oxygen-solarized-dark": "Solarized",
  "oxygen-things-dark": "Things"
};

// src/utils/theme-utils.ts
function isOxygenThemeActive(app) {
  const cssTheme = getVaultConfig(app, "cssTheme");
  return cssTheme === OXYGEN_THEME_NAME;
}
function updateObsidianAccentColor(app, hsl) {
  const hex = hslToHex(hsl);
  setVaultConfig(app, "accentColor", hex);
  app.workspace.trigger("css-change");
}

// src/modals/PresetEditorModal.ts
var PresetEditorModal = class extends import_obsidian5.Modal {
  constructor(app, plugin, preset, onSave) {
    super(app);
    this.plugin = plugin;
    this.isEditing = preset !== null;
    this.preset = preset || this.createDefaultPreset();
    this.onSave = onSave;
  }
  createDefaultPreset() {
    return PresetManager.createPreset("New Preset", "", this.plugin.settings.customPresets);
  }
  onOpen() {
    const { contentEl } = this;
    contentEl.empty();
    contentEl.addClass("preset-editor-modal");
    const header = contentEl.createEl("div", { cls: "modal-header" });
    header.createEl("h2", { text: this.isEditing ? "Edit preset" : "Create new preset" });
    const basicInfo = contentEl.createEl("div", { cls: "modal-section" });
    new import_obsidian5.Setting(basicInfo).setName("Preset name").setDesc("A unique name for your color preset").addText((text) => {
      this.nameInput = text.inputEl;
      text.setValue(this.preset.name).setPlaceholder("Enter preset name").onChange((value) => {
        this.preset.name = value;
        this.updatePreview();
      });
    });
    new import_obsidian5.Setting(basicInfo).setName("Author (optional)").setDesc("Your name or the creator of this preset").addText((text) => {
      this.authorInput = text.inputEl;
      text.setValue(this.preset.author || "").setPlaceholder("Enter author name").onChange((value) => {
        this.preset.author = value;
      });
    });
    const contentArea = contentEl.createEl("div", { cls: "modes-container" });
    const lightSection = contentArea.createEl("div", { cls: "mode-section" });
    lightSection.createEl("h3", { text: "Light mode" });
    this.buildModeContent(lightSection, "light");
    const darkSection = contentArea.createEl("div", { cls: "mode-section" });
    darkSection.createEl("h3", { text: "Dark mode" });
    this.buildModeContent(darkSection, "dark");
    const previewSection = contentEl.createEl("div", { cls: "modal-section" });
    previewSection.createEl("h3", { text: "Preview" });
    this.previewSwatch = previewSection.createEl("div", { cls: "preview-swatch" });
    this.updatePreview();
    const footer = contentEl.createEl("div", { cls: "modal-footer" });
    const cancelBtn = footer.createEl("button", { text: "Cancel", cls: "mod-cta" });
    cancelBtn.onclick = () => this.close();
    const saveBtn = footer.createEl("button", {
      text: this.isEditing ? "Update" : "Create",
      cls: "mod-cta"
    });
    saveBtn.onclick = () => this.savePreset();
  }
  buildModeContent(container, mode) {
    container.empty();
    const palette = mode === "light" ? this.preset.light : this.preset.dark;
    const requiredSection = container.createEl("div", { cls: "color-section" });
    const headerText = mode === "light" ? "Light theme colors" : "Dark theme colors";
    requiredSection.createEl("h3", { text: headerText });
    const baseSection = requiredSection.createEl("div", { cls: "color-group" });
    baseSection.createEl("label", { text: "Base color" });
    createHSLControls(baseSection, palette.base, (hsl) => {
      if (mode === "light") {
        this.preset.light.base = hsl;
      } else {
        this.preset.dark.base = hsl;
      }
      this.updatePreview();
    });
    const accentSection = requiredSection.createEl("div", { cls: "color-group" });
    accentSection.createEl("label", { text: "Accent color" });
    createHSLControls(accentSection, palette.accent, (hsl) => {
      if (mode === "light") {
        this.preset.light.accent = hsl;
      } else {
        this.preset.dark.accent = hsl;
      }
      this.updatePreview();
    });
    const frameSection = requiredSection.createEl("div", { cls: "color-group" });
    frameSection.createEl("label", { text: "Colorful frame lightness override (optional)", cls: "frame-label" });
    const frameDesc = frameSection.createEl("div", { cls: "setting-item-description frame-description" });
    frameDesc.textContent = mode === "dark" ? "Offset from accent lightness for colorful frame. Default: -25 (darkens by 25%). Leave empty for default." : "Offset from accent lightness for colorful frame. Default: +30 (brightens by 30%). Leave empty for default.";
    const frameInput = frameSection.createEl("input", { type: "number", cls: "frame-input" });
    frameInput.placeholder = mode === "dark" ? "-25" : "+30";
    frameInput.min = "-100";
    frameInput.max = "100";
    frameInput.step = "5";
    if (palette.frameLightnessOffset !== void 0) {
      frameInput.value = palette.frameLightnessOffset.toString();
    }
    frameInput.oninput = () => {
      const value = frameInput.value.trim();
      if (value === "") {
        if (mode === "light") {
          delete this.preset.light.frameLightnessOffset;
        } else {
          delete this.preset.dark.frameLightnessOffset;
        }
      } else {
        const offset = parseInt(value);
        if (!isNaN(offset)) {
          if (mode === "light") {
            this.preset.light.frameLightnessOffset = offset;
          } else {
            this.preset.dark.frameLightnessOffset = offset;
          }
        }
      }
      this.updatePreview();
    };
    const advancedSection = container.createEl("div", { cls: "color-section" });
    const advancedHeader = advancedSection.createEl("div", { cls: "collapsible-header" });
    advancedHeader.createEl("h4", { text: "Advanced overrides (optional)" });
    const advancedToggle = advancedHeader.createEl("button", {
      cls: "collapse-toggle"
    });
    (0, import_obsidian5.setIcon)(advancedToggle, "chevron-down");
    if (!palette.colors) {
      palette.colors = {};
    }
    const advancedItems = [];
    const overrideKeys = ["bg1", "bg2", "bg3", "ui1", "ui2", "ui3", "tx1", "tx2", "tx3", "tx4", "hl1", "hl2"];
    const overrideLabels = ["Background 1", "Background 2", "Background 3", "UI 1", "UI 2", "UI 3", "Text 1", "Text 2", "Text 3", "Text 4", "Highlight 1", "Highlight 2"];
    const colors = palette.colors;
    overrideKeys.forEach((key, index) => {
      const item = createColorOverride(
        advancedSection,
        overrideLabels[index],
        key,
        colors,
        palette,
        () => this.updatePreview()
      );
      advancedItems.push(item);
      item.addClass("collapsible-content-item");
    });
    advancedToggle.onclick = () => {
      const isCollapsed = !advancedItems[0].classList.contains("expanded");
      advancedItems.forEach((item) => {
        if (isCollapsed) {
          item.addClass("expanded");
        } else {
          item.removeClass("expanded");
        }
      });
      (0, import_obsidian5.setIcon)(advancedToggle, isCollapsed ? "chevron-up" : "chevron-down");
    };
    const syntaxSection = container.createEl("div", { cls: "color-section" });
    const syntaxHeader = syntaxSection.createEl("div", { cls: "collapsible-header" });
    syntaxHeader.createEl("h4", { text: "Syntax colors (optional)" });
    const syntaxToggle = syntaxHeader.createEl("button", {
      cls: "collapse-toggle"
    });
    (0, import_obsidian5.setIcon)(syntaxToggle, "chevron-down");
    const syntaxColors = ["red", "orange", "yellow", "green", "cyan", "blue", "purple", "pink"];
    const syntaxItems = [];
    syntaxColors.forEach((color) => {
      const item = createColorOverride(
        syntaxSection,
        color.charAt(0).toUpperCase() + color.slice(1),
        color,
        colors,
        palette,
        () => this.updatePreview()
      );
      syntaxItems.push(item);
      item.addClass("collapsible-content-item");
    });
    syntaxToggle.onclick = () => {
      const isCollapsed = !syntaxItems[0].classList.contains("expanded");
      syntaxItems.forEach((item) => {
        if (isCollapsed) {
          item.addClass("expanded");
        } else {
          item.removeClass("expanded");
        }
      });
      (0, import_obsidian5.setIcon)(syntaxToggle, isCollapsed ? "chevron-up" : "chevron-down");
    };
  }
  updatePreview() {
    this.previewSwatch.empty();
    const presetIndex = this.plugin.settings.customPresets.findIndex((p) => p.id === this.preset.id);
    if (presetIndex !== -1) {
      this.plugin.settings.customPresets[presetIndex] = this.preset;
      const presetSchemeId = `oxygen-custom-${this.preset.id}`;
      const isActiveLight = this.plugin.settings.lightScheme === presetSchemeId;
      const isActiveDark = this.plugin.settings.darkScheme === presetSchemeId;
      if (isActiveLight || isActiveDark) {
        const isLightMode = document.body.classList.contains("theme-light");
        if (isLightMode && isActiveLight) {
          updateObsidianAccentColor(this.plugin.app, this.preset.light.accent);
        } else if (!isLightMode && isActiveDark) {
          updateObsidianAccentColor(this.plugin.app, this.preset.dark.accent);
        }
        this.plugin.updateStyle();
        this.plugin.updateCustomPresetCSS();
      }
    }
    const lightPalette = this.preset.light;
    const darkPalette = this.preset.dark;
    const lightBaseHex = hslToHex(lightPalette.base);
    const lightAccentHex = hslToHex(lightPalette.accent);
    const darkBaseHex = hslToHex(darkPalette.base);
    const darkAccentHex = hslToHex(darkPalette.accent);
    const lightRow = this.previewSwatch.createEl("div", { cls: "preview-row" });
    lightRow.createEl("div", { text: "Light mode", cls: "preview-label" });
    const lightColors = lightRow.createEl("div", { cls: "preview-colors" });
    const lightBaseColor = lightColors.createEl("div", { cls: "preview-color" });
    lightBaseColor.setAttribute("data-color", lightBaseHex);
    setCssProp(lightBaseColor, "--preview-color", lightBaseHex);
    const lightAccentColor = lightColors.createEl("div", { cls: "preview-color" });
    lightAccentColor.setAttribute("data-color", lightAccentHex);
    setCssProp(lightAccentColor, "--preview-color", lightAccentHex);
    const darkRow = this.previewSwatch.createEl("div", { cls: "preview-row" });
    darkRow.createEl("div", { text: "Dark mode", cls: "preview-label" });
    const darkColors = darkRow.createEl("div", { cls: "preview-colors" });
    const darkBaseColor = darkColors.createEl("div", { cls: "preview-color" });
    darkBaseColor.setAttribute("data-color", darkBaseHex);
    setCssProp(darkBaseColor, "--preview-color", darkBaseHex);
    const darkAccentColor = darkColors.createEl("div", { cls: "preview-color" });
    darkAccentColor.setAttribute("data-color", darkAccentHex);
    setCssProp(darkAccentColor, "--preview-color", darkAccentHex);
  }
  savePreset() {
    try {
      if (!this.preset.name.trim()) {
        throw new Error("Preset name is required");
      }
      if (!this.isEditing) {
        this.preset.id = PresetManager.createPreset(
          this.preset.name,
          this.preset.author || "",
          this.plugin.settings.customPresets
        ).id;
      }
      this.onSave(this.preset);
      this.close();
    } catch (error) {
      console.error("Error saving preset:", error);
    }
  }
  onClose() {
    const { contentEl } = this;
    contentEl.empty();
  }
};

// src/modals/PresetImportModal.ts
var import_obsidian6 = require("obsidian");
var PresetImportModal = class extends import_obsidian6.Modal {
  constructor(app, plugin, onImport) {
    super(app);
    this.parsedPreset = null;
    this.plugin = plugin;
    this.onImport = onImport;
  }
  onOpen() {
    const { contentEl } = this;
    contentEl.empty();
    contentEl.addClass("preset-import-modal");
    const header = contentEl.createEl("div", { cls: "modal-header" });
    header.createEl("h2", { text: "Import custom preset" });
    const instructions = contentEl.createEl("div", { cls: "modal-section" });
    instructions.createEl("p", {
      text: "Paste a JSON preset below. You can export presets from this plugin or create them manually following the correct format."
    });
    const inputSection = contentEl.createEl("div", { cls: "modal-section" });
    inputSection.createEl("h3", { text: "JSON preset data" });
    new import_obsidian6.Setting(inputSection).setName("Preset JSON").setDesc("Paste the complete JSON preset data here").addTextArea((text) => {
      this.textArea = text.inputEl;
      this.textArea.addClass("preset-json-input");
      text.setPlaceholder("Paste JSON preset data here...").onChange((value) => this.parseJSON(value));
    });
    const previewSection = contentEl.createEl("div", { cls: "modal-section" });
    previewSection.createEl("h3", { text: "Preview" });
    this.previewContainer = previewSection.createEl("div", { cls: "preview-container" });
    this.previewContainer.createEl("p", {
      text: "Enter valid JSON to see a preview of the preset",
      cls: "preview-placeholder"
    });
    const errorSection = contentEl.createEl("div", { cls: "modal-section error-section hidden" });
    errorSection.createEl("div", { cls: "error-message" });
    const footer = contentEl.createEl("div", { cls: "modal-footer" });
    const cancelBtn = footer.createEl("button", { text: "Cancel", cls: "mod-cta" });
    cancelBtn.onclick = () => this.close();
    this.importButton = footer.createEl("button", {
      text: "Import preset",
      cls: "mod-cta"
    });
    this.importButton.disabled = true;
    this.importButton.onclick = () => this.importPreset();
  }
  parseJSON(jsonString) {
    const errorSection = this.contentEl.querySelector(".error-section");
    const errorMessage = this.contentEl.querySelector(".error-message");
    this.parsedPreset = null;
    this.importButton.disabled = true;
    errorSection.addClass("hidden");
    this.previewContainer.empty();
    if (!jsonString.trim()) {
      this.previewContainer.createEl("p", {
        text: "Enter valid JSON to see a preview of the preset",
        cls: "preview-placeholder"
      });
      return;
    }
    try {
      this.parsedPreset = PresetManager.importPresetFromJSON(jsonString);
      const existingPreset = this.plugin.settings.customPresets.find((p) => p.id === this.parsedPreset.id);
      if (existingPreset) {
        throw new Error(`A preset with ID "${this.parsedPreset.id}" already exists. Please rename the preset.`);
      }
      this.showPreview(this.parsedPreset);
      this.importButton.disabled = false;
    } catch (error) {
      errorMessage.textContent = error instanceof Error ? error.message : "Invalid JSON format";
      errorSection.removeClass("hidden");
      this.previewContainer.createEl("p", {
        text: "Fix the JSON errors above to see a preview",
        cls: "preview-error"
      });
    }
  }
  showPreview(preset) {
    this.previewContainer.empty();
    const info = this.previewContainer.createEl("div", { cls: "preset-info" });
    const nameRow = info.createEl("div", { cls: "info-row" });
    nameRow.createEl("strong", { text: "Name: " });
    nameRow.createEl("span", { text: preset.name });
    if (preset.author) {
      const authorRow = info.createEl("div", { cls: "info-row" });
      authorRow.createEl("strong", { text: "Author: " });
      authorRow.createEl("span", { text: preset.author });
    }
    const versionRow = info.createEl("div", { cls: "info-row" });
    versionRow.createEl("strong", { text: "Version: " });
    versionRow.createEl("span", { text: preset.version || "1.0.0" });
    const idRow = info.createEl("div", { cls: "info-row" });
    idRow.createEl("strong", { text: "ID: " });
    idRow.createEl("span", { text: preset.id, cls: "preset-id" });
    const preview = this.previewContainer.createEl("div", { cls: "color-preview-section" });
    preview.createEl("h4", { text: "Color preview" });
    const modeToggle = preview.createEl("div", { cls: "mode-toggle" });
    const lightModeBtn = modeToggle.createEl("button", {
      text: "Light mode",
      cls: "mode-btn active"
    });
    const darkModeBtn = modeToggle.createEl("button", {
      text: "Dark mode",
      cls: "mode-btn"
    });
    const swatchContainer = preview.createEl("div", { cls: "swatch-container" });
    const lightSwatches = swatchContainer.createEl("div", { cls: "mode-swatches active" });
    const lightBaseSwatchPreview = lightSwatches.createEl("div", { cls: "color-swatch" });
    const lightBaseHSL = `${preset.light.base.h}, ${preset.light.base.s}%, ${preset.light.base.l}%`;
    lightBaseSwatchPreview.setAttribute("data-hsl", lightBaseHSL);
    setCssProp(lightBaseSwatchPreview, "--swatch-hsl", lightBaseHSL);
    lightBaseSwatchPreview.title = `Base: hsl(${preset.light.base.h}, ${preset.light.base.s}%, ${preset.light.base.l}%)`;
    const lightAccentSwatchPreview = lightSwatches.createEl("div", { cls: "color-swatch" });
    const lightAccentHSL = `${preset.light.accent.h}, ${preset.light.accent.s}%, ${preset.light.accent.l}%`;
    lightAccentSwatchPreview.setAttribute("data-hsl", lightAccentHSL);
    setCssProp(lightAccentSwatchPreview, "--swatch-hsl", lightAccentHSL);
    lightAccentSwatchPreview.title = `Accent: hsl(${preset.light.accent.h}, ${preset.light.accent.s}%, ${preset.light.accent.l}%)`;
    const darkSwatches = swatchContainer.createEl("div", { cls: "mode-swatches" });
    const darkBaseSwatchPreview = darkSwatches.createEl("div", { cls: "color-swatch" });
    const darkBaseHSL = `${preset.dark.base.h}, ${preset.dark.base.s}%, ${preset.dark.base.l}%`;
    darkBaseSwatchPreview.setAttribute("data-hsl", darkBaseHSL);
    setCssProp(darkBaseSwatchPreview, "--swatch-hsl", darkBaseHSL);
    darkBaseSwatchPreview.title = `Base: hsl(${preset.dark.base.h}, ${preset.dark.base.s}%, ${preset.dark.base.l}%)`;
    const darkAccentSwatchPreview = darkSwatches.createEl("div", { cls: "color-swatch" });
    const darkAccentHSL = `${preset.dark.accent.h}, ${preset.dark.accent.s}%, ${preset.dark.accent.l}%`;
    darkAccentSwatchPreview.setAttribute("data-hsl", darkAccentHSL);
    setCssProp(darkAccentSwatchPreview, "--swatch-hsl", darkAccentHSL);
    darkAccentSwatchPreview.title = `Accent: hsl(${preset.dark.accent.h}, ${preset.dark.accent.s}%, ${preset.dark.accent.l}%)`;
    lightModeBtn.onclick = () => {
      lightModeBtn.classList.add("active");
      darkModeBtn.classList.remove("active");
      lightSwatches.classList.add("active");
      darkSwatches.classList.remove("active");
    };
    darkModeBtn.onclick = () => {
      darkModeBtn.classList.add("active");
      lightModeBtn.classList.remove("active");
      darkSwatches.classList.add("active");
      lightSwatches.classList.remove("active");
    };
    const details = this.previewContainer.createEl("div", { cls: "color-details-section" });
    details.createEl("h4", { text: "Color values" });
    const lightDetails = details.createEl("div", { cls: "mode-details" });
    lightDetails.createEl("h5", { text: "Light mode" });
    const lightBase = lightDetails.createEl("div", { cls: "color-detail" });
    const lightBaseSwatchDetail = lightBase.createEl("div", { cls: "detail-swatch" });
    const lightBaseHSLDetail = `${preset.light.base.h}, ${preset.light.base.s}%, ${preset.light.base.l}%`;
    lightBaseSwatchDetail.setAttribute("data-hsl", lightBaseHSLDetail);
    setCssProp(lightBaseSwatchDetail, "--detail-hsl", lightBaseHSLDetail);
    lightBase.createEl("span", { text: "Base: " });
    lightBase.createEl("span", { text: `hsl(${preset.light.base.h}, ${preset.light.base.s}%, ${preset.light.base.l}%)` });
    const lightAccent = lightDetails.createEl("div", { cls: "color-detail" });
    const lightAccentSwatchDetail = lightAccent.createEl("div", { cls: "detail-swatch" });
    const lightAccentHSLDetail = `${preset.light.accent.h}, ${preset.light.accent.s}%, ${preset.light.accent.l}%`;
    lightAccentSwatchDetail.setAttribute("data-hsl", lightAccentHSLDetail);
    setCssProp(lightAccentSwatchDetail, "--detail-hsl", lightAccentHSLDetail);
    lightAccent.createEl("span", { text: "Accent: " });
    lightAccent.createEl("span", { text: `hsl(${preset.light.accent.h}, ${preset.light.accent.s}%, ${preset.light.accent.l}%)` });
    const darkDetails = details.createEl("div", { cls: "mode-details" });
    darkDetails.createEl("h5", { text: "Dark mode" });
    const darkBase = darkDetails.createEl("div", { cls: "color-detail" });
    const darkBaseSwatchDetail = darkBase.createEl("div", { cls: "detail-swatch" });
    const darkBaseHSLDetail = `${preset.dark.base.h}, ${preset.dark.base.s}%, ${preset.dark.base.l}%`;
    darkBaseSwatchDetail.setAttribute("data-hsl", darkBaseHSLDetail);
    setCssProp(darkBaseSwatchDetail, "--detail-hsl", darkBaseHSLDetail);
    darkBase.createEl("span", { text: "Base: " });
    darkBase.createEl("span", { text: `hsl(${preset.dark.base.h}, ${preset.dark.base.s}%, ${preset.dark.base.l}%)` });
    const darkAccent = darkDetails.createEl("div", { cls: "color-detail" });
    const darkAccentSwatchDetail = darkAccent.createEl("div", { cls: "detail-swatch" });
    const darkAccentHSLDetail = `${preset.dark.accent.h}, ${preset.dark.accent.s}%, ${preset.dark.accent.l}%`;
    darkAccentSwatchDetail.setAttribute("data-hsl", darkAccentHSLDetail);
    setCssProp(darkAccentSwatchDetail, "--detail-hsl", darkAccentHSLDetail);
    darkAccent.createEl("span", { text: "Accent: " });
    darkAccent.createEl("span", { text: `hsl(${preset.dark.accent.h}, ${preset.dark.accent.s}%, ${preset.dark.accent.l}%)` });
    const lightOverrides = Object.keys(preset.light.colors || {}).length;
    const darkOverrides = Object.keys(preset.dark.colors || {}).length;
    if (lightOverrides > 0 || darkOverrides > 0) {
      const overridesInfo = this.previewContainer.createEl("div", { cls: "overrides-info" });
      overridesInfo.createEl("p", {
        text: `Custom overrides: ${lightOverrides} light mode, ${darkOverrides} dark mode`
      });
    }
  }
  importPreset() {
    if (this.parsedPreset) {
      this.onImport(this.parsedPreset);
      this.close();
    }
  }
  onClose() {
    const { contentEl } = this;
    contentEl.empty();
  }
};

// src/modals/ConfirmationModal.ts
var import_obsidian7 = require("obsidian");
var ConfirmationModal = class _ConfirmationModal extends import_obsidian7.Modal {
  constructor(app, title, message, confirmText = "Yes", cancelText = "Cancel") {
    super(app);
    this.title = title;
    this.message = message;
    this.confirmText = confirmText;
    this.cancelText = cancelText;
  }
  onOpen() {
    const { contentEl } = this;
    contentEl.empty();
    contentEl.createEl("h2", { text: this.title });
    contentEl.createEl("p", { text: this.message });
    const buttonContainer = contentEl.createDiv("modal-button-container");
    const cancelButton = buttonContainer.createEl("button", {
      text: this.cancelText,
      cls: "mod-cta"
    });
    cancelButton.addEventListener("click", () => {
      this.close();
      this.resolve(false);
    });
    const confirmButton = buttonContainer.createEl("button", {
      text: this.confirmText,
      cls: "mod-cta confirm-button"
    });
    confirmButton.addEventListener("click", () => {
      this.close();
      this.resolve(true);
    });
    confirmButton.focus();
  }
  onClose() {
    const { contentEl } = this;
    contentEl.empty();
  }
  // Static method to show the modal and return a promise
  static async show(app, title, message, confirmText = "Yes", cancelText = "Cancel") {
    return new Promise((resolve) => {
      const modal = new _ConfirmationModal(app, title, message, confirmText, cancelText);
      modal.resolve = resolve;
      modal.open();
    });
  }
};

// src/settings/sections/CustomPresetSettings.ts
function buildCustomPresetSettings(containerEl, plugin, app, refreshCallback) {
  const customPresetsGroup = new import_obsidian8.SettingGroup(containerEl).setHeading("Custom color schemes");
  customPresetsGroup.addSetting((setting) => {
    setting.setName("Enable custom presets").setDesc("Allow creation and use of custom color presets").addToggle((toggle) => {
      toggle.setValue(plugin.settings.enableCustomPresets).onChange((value) => {
        plugin.settings.enableCustomPresets = value;
        if (!value) {
          let needsUpdate = false;
          if (plugin.settings.lightScheme.startsWith("oxygen-custom-")) {
            plugin.settings.lightScheme = "oxygen-oxygen-light";
            needsUpdate = true;
          }
          if (plugin.settings.darkScheme.startsWith("oxygen-custom-")) {
            plugin.settings.darkScheme = "oxygen-oxygen-dark";
            needsUpdate = true;
          }
          if (needsUpdate) {
            plugin.updateStyle();
            plugin.updateCustomPresetCSS();
          }
        }
        void plugin.saveData(plugin.settings);
        refreshCallback();
      });
    });
  });
  if (!plugin.settings.enableCustomPresets) {
    return;
  }
  customPresetsGroup.addSetting((setting) => {
    setting.setName("Create new preset").setDesc("Design a custom color scheme from scratch").addExtraButton((button) => {
      button.setIcon("plus").setTooltip("Create new preset").onClick(() => openPresetEditor(app, plugin, null, refreshCallback));
    });
  });
  customPresetsGroup.addSetting((setting) => {
    setting.setName("Import preset").setDesc("Import a preset from JSON data").addExtraButton((button) => {
      button.setIcon("download").setTooltip("Import preset").onClick(() => openPresetImporter(app, plugin, refreshCallback));
    });
  });
  containerEl.createEl("br");
  if (plugin.settings.customPresets.length > 0) {
    const presetsList = containerEl.createEl("div", { cls: "custom-presets-list" });
    plugin.settings.customPresets.sort((a, b) => a.name.localeCompare(b.name)).forEach((preset) => {
      addPresetListItem(presetsList, preset, app, plugin, refreshCallback);
    });
  } else {
    const emptyState = containerEl.createEl("div", { cls: "custom-presets-empty" });
    emptyState.createEl("p", {
      text: "No custom presets yet. Create your first preset to get started!",
      cls: "empty-message"
    });
  }
  containerEl.createEl("br");
}
function addPresetListItem(container, preset, app, plugin, refreshCallback) {
  const presetItem = container.createEl("div", { cls: "custom-preset-item" });
  const presetInfo = presetItem.createEl("div", { cls: "preset-info" });
  const swatch = generateColorSwatch(preset);
  presetInfo.appendChild(swatch);
  const details = presetInfo.createEl("div", { cls: "preset-details" });
  details.createEl("div", { text: preset.name, cls: "preset-name" });
  if (preset.author) {
    details.createEl("div", { text: `by ${preset.author}`, cls: "preset-author" });
  }
  details.createEl("div", { text: preset.id, cls: "preset-id preset-id-display" });
  new import_obsidian8.Setting(presetItem).setName("").setDesc("").addExtraButton((button) => button.setIcon("edit").setTooltip("Edit preset").onClick(() => openPresetEditor(app, plugin, preset, refreshCallback))).addExtraButton((button) => button.setIcon("download").setTooltip("Export preset").onClick(() => exportPreset(preset))).addExtraButton((button) => button.setIcon("trash").setTooltip("Delete preset").onClick(async () => await deletePreset(app, plugin, preset, refreshCallback)));
}
function openPresetEditor(app, plugin, preset, refreshCallback) {
  const modal = new PresetEditorModal(app, plugin, preset, (updatedPreset) => {
    if (preset) {
      const index = plugin.settings.customPresets.findIndex((p) => p.id === preset.id);
      if (index !== -1) {
        plugin.settings.customPresets[index] = updatedPreset;
      }
    } else {
      plugin.settings.customPresets.push(updatedPreset);
    }
    void plugin.saveData(plugin.settings);
    const presetSchemeId = `oxygen-custom-${updatedPreset.id}`;
    const isActiveLight = plugin.settings.lightScheme === presetSchemeId;
    const isActiveDark = plugin.settings.darkScheme === presetSchemeId;
    if (isActiveLight || isActiveDark) {
      const isLightMode = document.body.classList.contains("theme-light");
      if (isLightMode && isActiveLight) {
        updateObsidianAccentColor(plugin.app, updatedPreset.light.accent);
      } else if (!isLightMode && isActiveDark) {
        updateObsidianAccentColor(plugin.app, updatedPreset.dark.accent);
      }
      plugin.updateStyle();
      plugin.updateCustomPresetCSS();
    }
    refreshCallback();
  });
  modal.open();
}
function openPresetImporter(app, plugin, refreshCallback) {
  const modal = new PresetImportModal(app, plugin, (importedPreset) => {
    plugin.settings.customPresets.push(importedPreset);
    void plugin.saveData(plugin.settings);
    refreshCallback();
  });
  modal.open();
}
function exportPreset(preset) {
  const json = PresetManager.exportPresetAsJSON(preset);
  const blob = new Blob([json], { type: "application/json" });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = `${preset.id}.json`;
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  URL.revokeObjectURL(url);
}
async function deletePreset(app, plugin, preset, refreshCallback) {
  const isActive = PresetManager.isPresetActive(
    preset.id,
    plugin.settings.lightScheme,
    plugin.settings.darkScheme
  );
  if (isActive) {
    const confirmed = await ConfirmationModal.show(
      app,
      "Delete active preset",
      "This preset is currently active. Deleting it will switch to the default scheme. Continue?",
      "Delete"
    );
    if (!confirmed) {
      return;
    }
    if (plugin.settings.lightScheme === `oxygen-custom-${preset.id}`) {
      plugin.settings.lightScheme = "oxygen-oxygen-light";
    }
    if (plugin.settings.darkScheme === `oxygen-custom-${preset.id}`) {
      plugin.settings.darkScheme = "oxygen-oxygen-dark";
    }
  }
  plugin.settings.customPresets = plugin.settings.customPresets.filter((p) => p.id !== preset.id);
  await plugin.saveData(plugin.settings);
  plugin.updateStyle();
  plugin.updateCustomPresetCSS();
  refreshCallback();
}

// src/settings/sections/AnimationSettings.ts
var import_obsidian9 = require("obsidian");
function buildAnimationSettings(containerEl, plugin) {
  const animationGroup = new import_obsidian9.SettingGroup(containerEl).setHeading("Animations");
  let speedSetting;
  animationGroup.addSetting((setting) => {
    setting.setName("Animation personality").setDesc("Choose the animation style: Default (smooth), Playful (bouncy), or Off (disabled).").addDropdown((dropdown) => {
      dropdown.addOption("default", "Default").addOption("playful", "Playful").addOption("off", "Off").setValue(plugin.settings.animationPersonality || "default").onChange((value) => {
        plugin.settings.animationPersonality = value;
        void plugin.saveData(plugin.settings);
        plugin.refresh();
        if (speedSetting !== void 0) {
          if (value === "off") {
            speedSetting.settingEl.addClass("hidden");
          } else {
            speedSetting.settingEl.removeClass("hidden");
          }
        }
      });
    });
  });
  animationGroup.addSetting((setting) => {
    speedSetting = setting;
    setting.setName("Animation speed").setDesc("Control the speed of animations. Range: 0 (disabled) to 2 (half speed / slower). Default: 1 (normal speed). Lower values = faster animations, higher values = slower animations.").addSlider((slider) => {
      slider.setLimits(0, 2, 0.1).setValue(plugin.settings.animationSpeed).setDynamicTooltip().onChange((value) => {
        plugin.settings.animationSpeed = value;
        void plugin.saveData(plugin.settings);
        plugin.refresh();
      });
    });
    if (plugin.settings.animationPersonality === "off") {
      speedSetting.settingEl.addClass("hidden");
    }
  });
}

// src/settings.ts
var MinimalSettingsTab = class extends import_obsidian10.PluginSettingTab {
  constructor(app, plugin) {
    super(app, plugin);
    this.icon = "lucide-swatch-book";
    this.plugin = plugin;
  }
  display() {
    const { containerEl } = this;
    containerEl.empty();
    buildColorSchemeSettings(containerEl, this.plugin);
    buildCustomPresetSettings(containerEl, this.plugin, this.app, () => this.display());
    buildFeatureSettings(containerEl, this.plugin);
    buildAnimationSettings(containerEl, this.plugin);
    buildLayoutSettings(containerEl, this.plugin);
    buildTypographySettings(containerEl, this.plugin);
  }
};

// src/presets/preset-css-generator.ts
var PresetCSSGenerator = class {
  /**
   * Generate CSS custom properties as an object for direct application to body element
   * This avoids creating style elements and complies with Obsidian guidelines
   */
  static generateProperties(preset, mode) {
    const palette = mode === "light" ? preset.light : preset.dark;
    const baseH = palette.base.h;
    const baseS = palette.base.s;
    const baseL = palette.base.l;
    const accentH = palette.accent.h;
    const accentS = palette.accent.s;
    const accentL = palette.accent.l;
    const isLightMode = mode === "light";
    const isLightBase = baseL > 50;
    const bg1 = `hsl(${baseH}, ${baseS}%, ${baseL}%)`;
    const bg2 = `hsl(${baseH}, ${baseS}%, ${isLightBase ? Math.max(0, baseL - 5) : Math.min(100, baseL + 5)}%)`;
    const bg3 = `hsl(${baseH}, ${baseS}%, ${isLightBase ? Math.max(0, baseL - 10) : Math.min(100, baseL + 10)}%)`;
    const ui1L = isLightBase ? Math.max(0, baseL - 15) : Math.min(100, baseL + 15);
    const ui2L = isLightBase ? Math.max(0, baseL - 10) : Math.min(100, baseL + 10);
    const ui3L = isLightBase ? Math.max(0, baseL - 5) : Math.min(100, baseL + 5);
    const ui1 = `hsl(${baseH}, ${baseS}%, ${ui1L}%)`;
    const ui2 = `hsl(${baseH}, ${baseS}%, ${ui2L}%)`;
    const ui3 = `hsl(${baseH}, ${baseS}%, ${ui3L}%)`;
    const tx1L = isLightBase ? 15 : 85;
    const tx2L = isLightBase ? 25 : 75;
    const tx3L = isLightBase ? 35 : 65;
    const tx4L = isLightBase ? 30 : 70;
    const tx1 = `hsl(${baseH}, ${Math.max(0, baseS - 10)}%, ${tx1L}%)`;
    const tx2 = `hsl(${baseH}, ${Math.max(0, baseS - 20)}%, ${tx2L}%)`;
    const tx3 = `hsl(${baseH}, ${Math.max(0, baseS - 10)}%, ${tx3L}%)`;
    const tx4 = `hsl(${baseH}, ${Math.max(0, baseS - 10)}%, ${tx4L}%)`;
    const hl1 = `hsla(${accentH}, 50%, 40%, 30%)`;
    const hl2 = `rgba(255, 177, 80, 0.3)`;
    const sp1 = isLightMode ? "white" : "black";
    const hslToRgb = (h, s, l) => {
      h = h / 360;
      s = s / 100;
      l = l / 100;
      const hue2rgb = (p2, q2, t) => {
        if (t < 0) t += 1;
        if (t > 1) t -= 1;
        if (t < 1 / 6) return p2 + (q2 - p2) * 6 * t;
        if (t < 1 / 2) return q2;
        if (t < 2 / 3) return p2 + (q2 - p2) * (2 / 3 - t) * 6;
        return p2;
      };
      if (s === 0) {
        return [l, l, l];
      }
      const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
      const p = 2 * l - q;
      const r2 = hue2rgb(p, q, h + 1 / 3);
      const g2 = hue2rgb(p, q, h);
      const b2 = hue2rgb(p, q, h - 1 / 3);
      return [r2, g2, b2];
    };
    const [r, g, b] = hslToRgb(accentH, accentS, accentL);
    const luminance = 0.2126 * (r <= 0.03928 ? r / 12.92 : Math.pow((r + 0.055) / 1.055, 2.4)) + 0.7152 * (g <= 0.03928 ? g / 12.92 : Math.pow((g + 0.055) / 1.055, 2.4)) + 0.0722 * (b <= 0.03928 ? b / 12.92 : Math.pow((b + 0.055) / 1.055, 2.4));
    const textOnAccent = luminance > 0.5 ? "black" : "white";
    const props = {
      "--base-h": `${baseH}`,
      "--base-s": `${baseS}%`,
      "--base-l": `${baseL}%`,
      "--accent-h": `${accentH}`,
      "--accent-s": `${accentS}%`,
      "--accent-l": `${accentL}%`,
      "--bg1": bg1,
      "--bg2": bg2,
      "--bg-tab": bg2,
      "--bg3": bg3,
      "--ui1": ui1,
      "--ui2": ui2,
      "--ui3": ui3,
      "--tx1": tx1,
      "--tx2": tx2,
      "--tx3": tx3,
      "--tx4": tx4,
      "--hl1": hl1,
      "--hl2": hl2,
      "--sp1": sp1,
      "--text-on-accent": textOnAccent
    };
    const extendedS = accentS;
    const extendedL = isLightBase ? 55 : 65;
    props["--color-red"] = `hsl(0, var(--accent-s), ${extendedL}%)`;
    props["--color-orange"] = `hsl(25, var(--accent-s), ${extendedL}%)`;
    props["--color-yellow"] = `hsl(50, var(--accent-s), ${extendedL}%)`;
    props["--color-green"] = `hsl(130, var(--accent-s), ${extendedL}%)`;
    props["--color-cyan"] = `hsl(180, var(--accent-s), ${extendedL}%)`;
    props["--color-blue"] = `hsl(220, var(--accent-s), ${extendedL}%)`;
    props["--color-purple"] = `hsl(280, var(--accent-s), ${extendedL}%)`;
    props["--color-pink"] = `hsl(330, var(--accent-s), ${extendedL}%)`;
    if (palette.frameLightnessOffset !== void 0) {
      const offset = palette.frameLightnessOffset >= 0 ? `+ ${palette.frameLightnessOffset}` : `- ${Math.abs(palette.frameLightnessOffset)}`;
      props["--frame-background-l"] = `calc(var(--accent-l) ${offset}%)`;
    }
    if (palette.colors) {
      const overrides = [
        "bg1",
        "bg2",
        "bg3",
        "ui1",
        "ui2",
        "ui3",
        "tx1",
        "tx2",
        "tx3",
        "tx4",
        "hl1",
        "hl2",
        "red",
        "orange",
        "yellow",
        "green",
        "cyan",
        "blue",
        "purple",
        "pink"
      ];
      overrides.forEach((colorKey) => {
        var _a;
        const color = (_a = palette.colors) == null ? void 0 : _a[colorKey];
        if (color) {
          switch (colorKey) {
            case "bg1":
            case "bg2":
            case "bg3":
            case "ui1":
            case "ui2":
            case "ui3":
            case "tx1":
            case "tx2":
            case "tx3":
            case "tx4":
            case "hl1":
            case "hl2":
              props[`--${colorKey}`] = color;
              break;
            default:
              props[`--color-${colorKey}`] = color;
              break;
          }
        }
      });
    }
    return props;
  }
  /**
   * Generate CSS for a custom preset using Oxygen custom variables
   * This allows Style Settings to override Obsidian native variables
   * @deprecated Use generateProperties instead to avoid creating style elements
   */
  static generateCSS(preset, mode) {
    const palette = mode === "light" ? preset.light : preset.dark;
    const themeClass = mode === "light" ? "theme-light" : "theme-dark";
    const className = `oxygen-custom-${preset.id}`;
    let css = `.${themeClass}.${className} {
`;
    const baseH = palette.base.h;
    const baseS = palette.base.s;
    const baseL = palette.base.l;
    const accentH = palette.accent.h;
    const accentS = palette.accent.s;
    const accentL = palette.accent.l;
    const isLightMode = mode === "light";
    const isLightBase = baseL > 50;
    const bg1 = `hsl(${baseH}, ${baseS}%, ${baseL}%)`;
    const bg2 = `hsl(${baseH}, ${baseS}%, ${isLightBase ? Math.max(0, baseL - 5) : Math.min(100, baseL + 5)}%)`;
    const bg3 = `hsl(${baseH}, ${baseS}%, ${isLightBase ? Math.max(0, baseL - 10) : Math.min(100, baseL + 10)}%)`;
    const ui1L = isLightBase ? Math.max(0, baseL - 15) : Math.min(100, baseL + 15);
    const ui2L = isLightBase ? Math.max(0, baseL - 10) : Math.min(100, baseL + 10);
    const ui3L = isLightBase ? Math.max(0, baseL - 5) : Math.min(100, baseL + 5);
    const ui1 = `hsl(${baseH}, ${baseS}%, ${ui1L}%)`;
    const ui2 = `hsl(${baseH}, ${baseS}%, ${ui2L}%)`;
    const ui3 = `hsl(${baseH}, ${baseS}%, ${ui3L}%)`;
    const tx1L = isLightBase ? 15 : 85;
    const tx2L = isLightBase ? 25 : 75;
    const tx3L = isLightBase ? 35 : 65;
    const tx4L = isLightBase ? 30 : 70;
    const tx1 = `hsl(${baseH}, ${Math.max(0, baseS - 10)}%, ${tx1L}%)`;
    const tx2 = `hsl(${baseH}, ${Math.max(0, baseS - 20)}%, ${tx2L}%)`;
    const tx3 = `hsl(${baseH}, ${Math.max(0, baseS - 10)}%, ${tx3L}%)`;
    const tx4 = `hsl(${baseH}, ${Math.max(0, baseS - 10)}%, ${tx4L}%)`;
    const hl1 = `hsla(${accentH}, 50%, 40%, 30%)`;
    const hl2 = `rgba(255, 177, 80, 0.3)`;
    const sp1 = isLightMode ? "white" : "black";
    const hslToRgb = (h, s, l) => {
      h = h / 360;
      s = s / 100;
      l = l / 100;
      const hue2rgb = (p2, q2, t) => {
        if (t < 0) t += 1;
        if (t > 1) t -= 1;
        if (t < 1 / 6) return p2 + (q2 - p2) * 6 * t;
        if (t < 1 / 2) return q2;
        if (t < 2 / 3) return p2 + (q2 - p2) * (2 / 3 - t) * 6;
        return p2;
      };
      if (s === 0) {
        return [l, l, l];
      }
      const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
      const p = 2 * l - q;
      const r2 = hue2rgb(p, q, h + 1 / 3);
      const g2 = hue2rgb(p, q, h);
      const b2 = hue2rgb(p, q, h - 1 / 3);
      return [r2, g2, b2];
    };
    const [r, g, b] = hslToRgb(accentH, accentS, accentL);
    const luminance = 0.2126 * (r <= 0.03928 ? r / 12.92 : Math.pow((r + 0.055) / 1.055, 2.4)) + 0.7152 * (g <= 0.03928 ? g / 12.92 : Math.pow((g + 0.055) / 1.055, 2.4)) + 0.0722 * (b <= 0.03928 ? b / 12.92 : Math.pow((b + 0.055) / 1.055, 2.4));
    const textOnAccent = luminance > 0.5 ? "black" : "white";
    css += `  --base-h: ${baseH};
`;
    css += `  --base-s: ${baseS}%;
`;
    css += `  --base-l: ${baseL}%;
`;
    css += `
`;
    css += `  --accent-h: ${accentH};
`;
    css += `  --accent-s: ${accentS}%;
`;
    css += `  --accent-l: ${accentL}%;
`;
    css += `  --text-on-accent: ${textOnAccent};
`;
    css += `
`;
    css += `  --bg1: ${bg1};
`;
    css += `  --bg2: ${bg2};
`;
    css += `  --bg-tab: ${bg2};
`;
    css += `  --bg3: ${bg3};
`;
    css += `
`;
    css += `  --ui1: ${ui1};
`;
    css += `  --ui2: ${ui2};
`;
    css += `  --ui3: ${ui3};
`;
    css += `
`;
    css += `  --tx1: ${tx1};
`;
    css += `  --tx2: ${tx2};
`;
    css += `  --tx3: ${tx3};
`;
    css += `  --tx4: ${tx4};
`;
    css += `
`;
    css += `  --hl1: ${hl1};
`;
    css += `  --hl2: ${hl2};
`;
    css += `
`;
    css += `  --sp1: ${sp1};
`;
    css += `
`;
    const extendedS = accentS;
    const extendedL = isLightBase ? 55 : 65;
    css += `  --color-red: hsl(0, var(--accent-s), ${extendedL}%);
`;
    css += `  --color-orange: hsl(25, var(--accent-s), ${extendedL}%);
`;
    css += `  --color-yellow: hsl(50, var(--accent-s), ${extendedL}%);
`;
    css += `  --color-green: hsl(130, var(--accent-s), ${extendedL}%);
`;
    css += `  --color-cyan: hsl(180, var(--accent-s), ${extendedL}%);
`;
    css += `  --color-blue: hsl(220, var(--accent-s), ${extendedL}%);
`;
    css += `  --color-purple: hsl(280, var(--accent-s), ${extendedL}%);
`;
    css += `  --color-pink: hsl(330, var(--accent-s), ${extendedL}%);
`;
    css += `
`;
    if (palette.frameLightnessOffset !== void 0) {
      const offset = palette.frameLightnessOffset >= 0 ? `+ ${palette.frameLightnessOffset}` : `- ${Math.abs(palette.frameLightnessOffset)}`;
      css += `  --frame-background-l: calc(var(--accent-l) ${offset}%);
`;
      css += `
`;
    }
    if (palette.colors) {
      const overrides = [
        "bg1",
        "bg2",
        "bg3",
        "ui1",
        "ui2",
        "ui3",
        "tx1",
        "tx2",
        "tx3",
        "tx4",
        "hl1",
        "hl2",
        "red",
        "orange",
        "yellow",
        "green",
        "cyan",
        "blue",
        "purple",
        "pink"
      ];
      overrides.forEach((colorKey) => {
        var _a;
        const color = (_a = palette.colors) == null ? void 0 : _a[colorKey];
        if (color) {
          switch (colorKey) {
            case "bg1":
            case "bg2":
            case "bg3":
            case "ui1":
            case "ui2":
            case "ui3":
            case "tx1":
            case "tx2":
            case "tx3":
            case "tx4":
            case "hl1":
            case "hl2":
              css += `  --${colorKey}: ${color};
`;
              break;
            // For accent colors, we need to determine which ax variable this should map to
            // This is a simplified mapping - in practice, you might want more sophisticated logic
            default:
              css += `  --color-${colorKey}: ${color};
`;
              break;
          }
        }
      });
    }
    css += "}\n";
    return css;
  }
};

// src/managers/custom-preset-css.ts
var ACCENT_PROPERTIES = ["--accent-h", "--accent-s", "--accent-l", "--text-on-accent"];
var STYLE_ELEMENT_ID = "oxygen-custom-preset-accent";
var CustomPresetCSS = class {
  constructor(plugin) {
    this.isUpdating = false;
    this.styleEl = null;
    this.plugin = plugin;
  }
  /**
   * Initialize custom preset CSS
   */
  initialize() {
    if (!this.plugin.isOxygenThemeActive()) {
      return;
    }
    this.updateCSS();
  }
  /**
   * Check if the user has set a custom accent color in Obsidian.
   * Returns the HSL values if set, or null if not.
   */
  getUserAccentHSL() {
    const userAccentColor = getVaultConfig(this.plugin.app, "accentColor");
    if (typeof userAccentColor === "string" && userAccentColor.length > 0) {
      return hexToHSL(userAccentColor);
    }
    return null;
  }
  /**
   * Apply the user's custom accent color as inline styles on body.
   * Inline styles have the highest CSS specificity, so they override
   * both theme class selectors (built-in schemes) and our <style> element
   * (custom presets). This ensures the user's accent choice always wins.
   */
  applyUserAccentInline() {
    const userHSL = this.getUserAccentHSL();
    if (userHSL) {
      const textOnAccent = this.calculateTextOnAccent(userHSL.h, userHSL.s, userHSL.l);
      setCssProps(document.body, {
        "--accent-h": `${userHSL.h}`,
        "--accent-s": `${userHSL.s}%`,
        "--accent-l": `${userHSL.l}%`,
        "--text-on-accent": textOnAccent
      });
    }
  }
  /**
   * Calculate whether text on accent should be black or white
   */
  calculateTextOnAccent(h, s, l) {
    const hNorm = h / 360;
    const sNorm = s / 100;
    const lNorm = l / 100;
    const hue2rgb = (p, q, t) => {
      if (t < 0) t += 1;
      if (t > 1) t -= 1;
      if (t < 1 / 6) return p + (q - p) * 6 * t;
      if (t < 1 / 2) return q;
      if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
      return p;
    };
    let r, g, b;
    if (sNorm === 0) {
      r = g = b = lNorm;
    } else {
      const q = lNorm < 0.5 ? lNorm * (1 + sNorm) : lNorm + sNorm - lNorm * sNorm;
      const p = 2 * lNorm - q;
      r = hue2rgb(p, q, hNorm + 1 / 3);
      g = hue2rgb(p, q, hNorm);
      b = hue2rgb(p, q, hNorm - 1 / 3);
    }
    const luminance = 0.2126 * (r <= 0.03928 ? r / 12.92 : Math.pow((r + 0.055) / 1.055, 2.4)) + 0.7152 * (g <= 0.03928 ? g / 12.92 : Math.pow((g + 0.055) / 1.055, 2.4)) + 0.0722 * (b <= 0.03928 ? b / 12.92 : Math.pow((b + 0.055) / 1.055, 2.4));
    return luminance > 0.5 ? "black" : "white";
  }
  /**
   * Update custom preset CSS based on current settings.
   * Most properties are applied as inline body styles.
   * Accent properties (--accent-h/s/l) are applied via a <style> element
   * scoped to the preset's body class, so they persist through Obsidian's
   * accent color reset (which only clears inline styles, not stylesheet rules).
   *
   * IMPORTANT: If the user has set a custom accent in Obsidian, it is
   * re-applied as inline styles AFTER all cleanup and preset application.
   * Inline styles beat class selectors (theme CSS) and <style> element rules,
   * ensuring the user's accent choice always wins.
   */
  updateCSS() {
    if (this.isUpdating) {
      return;
    }
    if (!this.plugin.isOxygenThemeActive()) {
      return;
    }
    this.isUpdating = true;
    const hasUserAccent = this.getUserAccentHSL() !== null;
    const allPresetClasses = Array.from(document.body.classList).filter(
      (cls) => cls.startsWith("oxygen-custom-")
    );
    allPresetClasses.forEach((cls) => document.body.classList.remove(cls));
    const presetProperties = [
      "--base-h",
      "--base-s",
      "--base-l",
      "--accent-h",
      "--accent-s",
      "--accent-l",
      "--bg1",
      "--bg2",
      "--bg-tab",
      "--bg3",
      "--ui1",
      "--ui2",
      "--ui3",
      "--tx1",
      "--tx2",
      "--tx3",
      "--tx4",
      "--hl1",
      "--hl2",
      "--sp1",
      "--text-on-accent",
      "--color-red",
      "--color-orange",
      "--color-yellow",
      "--color-green",
      "--color-cyan",
      "--color-blue",
      "--color-purple",
      "--color-pink",
      "--frame-background-l"
    ];
    presetProperties.forEach((prop) => {
      document.body.style.removeProperty(prop);
    });
    this.removeAccentStyleElement();
    const activeLightPreset = this.plugin.settings.customPresets.find(
      (p) => this.plugin.settings.lightScheme === `oxygen-custom-${p.id}`
    );
    const activeDarkPreset = this.plugin.settings.customPresets.find(
      (p) => this.plugin.settings.darkScheme === `oxygen-custom-${p.id}`
    );
    const isLightMode = document.body.classList.contains("theme-light");
    const activePreset = isLightMode ? activeLightPreset : activeDarkPreset;
    if (activePreset) {
      const presetClass = `oxygen-custom-${activePreset.id}`;
      document.body.classList.add(presetClass);
      const mode = isLightMode ? "light" : "dark";
      const properties = PresetCSSGenerator.generateProperties(activePreset, mode);
      const inlineProps = {};
      const accentProps = {};
      for (const [key, value] of Object.entries(properties)) {
        if (ACCENT_PROPERTIES.includes(key)) {
          accentProps[key] = value;
        } else {
          inlineProps[key] = value;
        }
      }
      setCssProps(document.body, inlineProps);
      if (Object.keys(accentProps).length > 0) {
        const themeClass = isLightMode ? "theme-light" : "theme-dark";
        let cssText = `body.${themeClass}.${presetClass} {
`;
        for (const [prop, value] of Object.entries(accentProps)) {
          cssText += `  ${prop}: ${value};
`;
        }
        cssText += "}\n";
        this.createAccentStyleElement(cssText);
      }
    }
    if (hasUserAccent) {
      this.applyUserAccentInline();
    }
    setTimeout(() => {
      this.isUpdating = false;
    }, 50);
  }
  /**
   * Create or update the accent style element
   */
  createAccentStyleElement(cssText) {
    this.removeAccentStyleElement();
    this.styleEl = document.createElement("style");
    this.styleEl.id = STYLE_ELEMENT_ID;
    this.styleEl.textContent = cssText;
    document.head.appendChild(this.styleEl);
  }
  /**
   * Remove the accent style element
   */
  removeAccentStyleElement() {
    if (this.styleEl) {
      this.styleEl.remove();
      this.styleEl = null;
    }
    const existing = document.getElementById(STYLE_ELEMENT_ID);
    if (existing) {
      existing.remove();
    }
  }
  /**
   * Cleanup - remove all custom preset classes, CSS properties, and style element
   */
  cleanup() {
    const allPresetClasses = Array.from(document.body.classList).filter(
      (cls) => cls.startsWith("oxygen-custom-")
    );
    allPresetClasses.forEach((cls) => document.body.classList.remove(cls));
    const presetProperties = [
      "--base-h",
      "--base-s",
      "--base-l",
      "--accent-h",
      "--accent-s",
      "--accent-l",
      "--bg1",
      "--bg2",
      "--bg-tab",
      "--bg3",
      "--ui1",
      "--ui2",
      "--ui3",
      "--tx1",
      "--tx2",
      "--tx3",
      "--tx4",
      "--hl1",
      "--hl2",
      "--sp1",
      "--text-on-accent",
      "--color-red",
      "--color-orange",
      "--color-yellow",
      "--color-green",
      "--color-cyan",
      "--color-blue",
      "--color-purple",
      "--color-pink",
      "--frame-background-l"
    ];
    presetProperties.forEach((prop) => {
      document.body.style.removeProperty(prop);
    });
    this.removeAccentStyleElement();
  }
};

// src/managers/style-manager.ts
var import_obsidian11 = require("obsidian");
var StyleManagerImpl = class {
  constructor(plugin) {
    this.cssObserver = null;
    this.plugin = plugin;
    this.customPresetCSS = new CustomPresetCSS(plugin);
  }
  /**
   * Detect OS for OS-specific styling
   */
  detectOS() {
    if (import_obsidian11.Platform.isMacOS) {
      return "macos";
    }
    if (import_obsidian11.Platform.isWin) {
      return "windows";
    }
    return "neutral";
  }
  /**
   * Initialize style management
   */
  initialize() {
    this.loadRules();
  }
  /**
   * Initialize custom preset CSS (called after main load completes)
   */
  initializeCustomPresets() {
    this.customPresetCSS.initialize();
  }
  /**
   * Cleanup on plugin unload
   */
  cleanup() {
    this.unloadRules();
    this.removeStyle();
    this.removeSettings();
    this.removeLightScheme();
    this.removeDarkScheme();
    this.customPresetCSS.cleanup();
    if (this.cssObserver) {
      this.cssObserver.disconnect();
      this.cssObserver = null;
    }
  }
  /**
   * Refresh all styles
   */
  refresh() {
    if (!this.plugin.isOxygenThemeActive()) {
      return;
    }
    this.updateStyle();
  }
  /**
   * Update custom preset CSS (public interface)
   */
  updateCustomPresetCSS() {
    this.customPresetCSS.updateCSS();
  }
  /**
   * Update all styles based on current settings
   */
  updateStyle() {
    if (!this.plugin.isOxygenThemeActive()) {
      return;
    }
    this.removeStyle();
    this.removeSettings();
    if (this.plugin.settings.lightStyle && this.plugin.settings.lightStyle.trim()) {
      document.body.addClass(this.plugin.settings.lightStyle);
    }
    if (this.plugin.settings.darkStyle && this.plugin.settings.darkStyle.trim()) {
      document.body.addClass(this.plugin.settings.darkStyle);
    }
    try {
      if (document.body.classList.contains("theme-light")) {
        this.updateLightScheme();
      } else if (document.body.classList.contains("theme-dark")) {
        this.updateDarkScheme();
      } else {
        document.body.addClass("theme-light");
        this.updateLightScheme();
      }
    } catch (error) {
      console.error("Error updating schemes:", error);
    }
    const bordersValue = this.plugin.settings.workspaceBorders;
    if (bordersValue === "enhanced") {
      document.body.classList.remove("borders-none", "borders-on");
    } else if (bordersValue === "default") {
      document.body.classList.remove("borders-none");
      document.body.classList.add("borders-on");
    } else if (bordersValue === "none") {
      document.body.classList.remove("borders-on");
      document.body.classList.add("borders-none");
    }
    document.body.classList.toggle("colorful-headings", this.plugin.settings.colorfulHeadings);
    document.body.classList.toggle("colorful-frame", this.plugin.settings.colorfulFrame);
    document.body.classList.toggle("colorful-active", this.plugin.settings.colorfulActiveStates);
    document.body.classList.toggle("enable-blur", this.plugin.settings.enableBlur);
    document.body.classList.toggle("links-int-on", this.plugin.settings.underlineInternal);
    document.body.classList.toggle("links-ext-on", this.plugin.settings.underlineExternal);
    document.body.classList.toggle("full-width-media", this.plugin.settings.fullWidthMedia);
    document.body.classList.toggle("img-grid", this.plugin.settings.imgGrid);
    document.body.classList.toggle("oxygen-dev-block-width", this.plugin.settings.devBlockWidth);
    document.body.classList.toggle("oxygen-status-off", !this.plugin.settings.minimalStatus);
    document.body.classList.toggle("full-file-names", !this.plugin.settings.trimNames);
    document.body.classList.toggle("labeled-nav", this.plugin.settings.labeledNav);
    document.body.classList.toggle("oxygen-folding", this.plugin.settings.folding);
    document.body.classList.toggle("use-default-folder-icon", this.plugin.settings.useDefaultFolderIcon);
    document.body.addClass(
      this.plugin.settings.chartWidth,
      this.plugin.settings.tableWidth,
      this.plugin.settings.imgWidth,
      this.plugin.settings.iframeWidth,
      this.plugin.settings.mapWidth
    );
    const cssProps = {
      "--font-ui-small": `${this.plugin.settings.textSmall}px`,
      "--line-height": String(this.plugin.settings.lineHeight),
      "--line-width": `${this.plugin.settings.lineWidth}rem`,
      "--line-width-wide": `${this.plugin.settings.lineWidthWide}rem`,
      "--max-width": `${this.plugin.settings.maxWidth}%`,
      "--font-editor-override": this.plugin.settings.editorFont
    };
    const isDefaultWidth = this.plugin.settings.navIndentationGuideWidth === "0px";
    const isDefaultColor = this.plugin.settings.navIndentationGuideColor === "rgba(var(--mono-rgb-100), 0.12)";
    if (!isDefaultWidth) {
      cssProps["--nav-indentation-guide-width"] = this.plugin.settings.navIndentationGuideWidth;
    } else {
      document.body.style.removeProperty("--nav-indentation-guide-width");
    }
    if (!isDefaultColor) {
      cssProps["--nav-indentation-guide-color"] = this.plugin.settings.navIndentationGuideColor;
    } else {
      document.body.style.removeProperty("--nav-indentation-guide-color");
    }
    setCssProps(document.body, cssProps);
    document.body.classList.remove("animations-refined", "animations-default", "animations-playful", "animations-off");
    const animationPersonality = this.plugin.settings.animationPersonality || "default";
    if (animationPersonality === "off") {
      document.body.classList.add("animations-off");
      document.body.style.removeProperty("--anim-speed-modifier");
    } else if (animationPersonality === "playful") {
      document.body.classList.add("animations-playful");
      document.body.style.setProperty("--anim-speed-modifier", this.plugin.settings.animationSpeed.toString());
    } else {
      document.body.classList.add("animations-default");
      document.body.style.setProperty("--anim-speed-modifier", this.plugin.settings.animationSpeed.toString());
    }
    this.customPresetCSS.updateCSS();
    this.customPresetCSS.applyUserAccentInline();
  }
  /**
   * Update light mode style
   */
  updateLightStyle() {
    if (!this.plugin.isOxygenThemeActive()) {
      return;
    }
    this.removeStyle();
    document.body.removeClass("theme-dark");
    document.body.addClass("theme-light", this.plugin.settings.lightStyle);
    const theme = getVaultConfig(this.plugin.app, "theme");
    if (theme !== "system") {
      setTheme(this.plugin.app, "moonstone");
      setVaultConfig(this.plugin.app, "theme", "moonstone");
    }
    this.plugin.app.workspace.trigger("css-change");
  }
  /**
   * Update dark mode style
   */
  updateDarkStyle() {
    if (!this.plugin.isOxygenThemeActive()) {
      return;
    }
    this.removeStyle();
    document.body.removeClass("theme-light");
    document.body.addClass("theme-dark", this.plugin.settings.darkStyle);
    const theme = getVaultConfig(this.plugin.app, "theme");
    if (theme !== "system") {
      setTheme(this.plugin.app, "obsidian");
      setVaultConfig(this.plugin.app, "theme", "obsidian");
    }
    this.plugin.app.workspace.trigger("css-change");
  }
  /**
   * Update light color scheme
   */
  updateLightScheme() {
    if (!this.plugin.isOxygenThemeActive()) {
      return;
    }
    this.removeLightScheme();
    this.removeDarkScheme();
    if (!document.body.classList.contains("theme-light")) {
      document.body.removeClass("theme-dark");
      document.body.addClass("theme-light");
    }
    if (this.plugin.settings.lightScheme && this.plugin.settings.lightScheme.trim()) {
      document.body.addClass(this.plugin.settings.lightScheme);
    }
  }
  /**
   * Update dark color scheme
   */
  updateDarkScheme() {
    if (!this.plugin.isOxygenThemeActive()) {
      return;
    }
    this.removeDarkScheme();
    this.removeLightScheme();
    if (!document.body.classList.contains("theme-dark")) {
      document.body.removeClass("theme-light");
      document.body.addClass("theme-dark");
    }
    if (this.plugin.settings.darkScheme && this.plugin.settings.darkScheme.trim()) {
      document.body.addClass(this.plugin.settings.darkScheme);
    }
  }
  /**
   * Remove style classes
   */
  removeStyle() {
    document.body.removeClass(
      "oxygen-light",
      "oxygen-light-tonal",
      "oxygen-light-contrast",
      "oxygen-light-white",
      "oxygen-dark",
      "oxygen-dark-tonal",
      "oxygen-dark-black",
      // Legacy or mis-prefixed classes that might be sticking
      "minimal-light",
      "minimal-light-tonal",
      "minimal-light-contrast",
      "minimal-light-white",
      "minimal-dark",
      "minimal-dark-tonal",
      "minimal-dark-black"
    );
  }
  /**
   * Remove light scheme classes
   */
  removeLightScheme() {
    document.body.removeClass(...LIGHT_SCHEMES);
    this.plugin.settings.customPresets.forEach((preset) => {
      document.body.removeClass(`oxygen-custom-${preset.id}`);
    });
  }
  /**
   * Remove dark scheme classes
   */
  removeDarkScheme() {
    document.body.removeClass(...DARK_SCHEMES);
    this.plugin.settings.customPresets.forEach((preset) => {
      document.body.removeClass(`oxygen-custom-${preset.id}`);
    });
  }
  /**
   * Remove settings classes
   */
  removeSettings() {
    document.body.removeClass(
      "borders-none",
      "borders-on",
      "colorful-headings",
      "colorful-frame",
      "colorful-active",
      "links-int-on",
      "links-ext-on",
      "full-width-media",
      "img-grid",
      "oxygen-dev-block-width",
      "oxygen-status-off",
      "full-file-names",
      "labeled-nav",
      "oxygen-folding",
      "enable-blur",
      "use-default-folder-icon",
      "animations-refined",
      "animations-default",
      "animations-playful",
      "animations-off",
      "table-wide",
      "table-max",
      "table-100",
      "table-default-width",
      "iframe-wide",
      "iframe-max",
      "iframe-100",
      "iframe-default-width",
      "img-wide",
      "img-max",
      "img-100",
      "img-default-width",
      "chart-wide",
      "chart-max",
      "chart-100",
      "chart-default-width",
      "map-wide",
      "map-max",
      "map-100",
      "map-default-width"
    );
  }
  /**
   * Load CSS rules
   * Uses CSS custom properties on body instead of creating style elements
   */
  loadRules() {
    if (!this.plugin.isOxygenThemeActive()) {
      return;
    }
    document.body.classList.add(CSS_CLASSES.PLUGIN_THEME);
    this.updateStyle();
  }
  /**
   * Unload CSS rules
   */
  unloadRules() {
    document.body.style.removeProperty("--font-ui-small");
    document.body.style.removeProperty("--line-height");
    document.body.style.removeProperty("--line-width");
    document.body.style.removeProperty("--line-width-wide");
    document.body.style.removeProperty("--max-width");
    document.body.style.removeProperty("--font-editor-override");
    document.body.style.removeProperty("--nav-indentation-guide-width");
    document.body.style.removeProperty("--nav-indentation-guide-color");
    document.body.style.removeProperty("--anim-speed-modifier");
    document.body.classList.remove(CSS_CLASSES.PLUGIN_THEME);
  }
  /**
   * Setup CSS watcher for re-applying custom presets
   */
  setupCSSWatcher() {
  }
};

// src/managers/theme-manager.ts
var ThemeManagerImpl = class {
  constructor(plugin) {
    this.plugin = plugin;
  }
  /**
   * Toggle between light and dark themes
   */
  updateTheme() {
    const currentTheme = getVaultConfig(this.plugin.app, "theme");
    if (currentTheme === OBSIDIAN_THEMES.SYSTEM) {
      if (document.body.classList.contains("theme-light")) {
        document.body.removeClass("theme-light");
        document.body.addClass("theme-dark");
      } else {
        document.body.removeClass("theme-dark");
        document.body.addClass("theme-light");
      }
    } else {
      if (document.body.classList.contains("theme-light")) {
        document.body.removeClass("theme-light");
        document.body.addClass("theme-dark");
      } else {
        document.body.removeClass("theme-dark");
        document.body.addClass("theme-light");
      }
      const theme = getVaultConfig(this.plugin.app, "theme");
      const newTheme = theme === OBSIDIAN_THEMES.LIGHT ? OBSIDIAN_THEMES.DARK : OBSIDIAN_THEMES.LIGHT;
      setTheme(this.plugin.app, newTheme);
      setVaultConfig(this.plugin.app, "theme", newTheme);
    }
    this.plugin.app.workspace.trigger("css-change");
  }
  /**
   * Switch to light theme
   */
  switchToLight() {
    document.body.removeClass("theme-dark");
    document.body.addClass("theme-light");
    const theme = getVaultConfig(this.plugin.app, "theme");
    if (theme !== OBSIDIAN_THEMES.SYSTEM) {
      setTheme(this.plugin.app, OBSIDIAN_THEMES.LIGHT);
      setVaultConfig(this.plugin.app, "theme", OBSIDIAN_THEMES.LIGHT);
    }
    this.plugin.app.workspace.trigger("css-change");
  }
  /**
   * Switch to dark theme
   */
  switchToDark() {
    document.body.removeClass("theme-light");
    document.body.addClass("theme-dark");
    const theme = getVaultConfig(this.plugin.app, "theme");
    if (theme !== OBSIDIAN_THEMES.SYSTEM) {
      setTheme(this.plugin.app, OBSIDIAN_THEMES.DARK);
      setVaultConfig(this.plugin.app, "theme", OBSIDIAN_THEMES.DARK);
    }
    this.plugin.app.workspace.trigger("css-change");
  }
  /**
   * Get current theme mode
   */
  getCurrentMode() {
    return document.body.classList.contains("theme-light") ? "light" : "dark";
  }
  /**
   * Update sidebar theme for high contrast light mode
   */
  updateSidebarTheme() {
    if (!this.plugin.isOxygenThemeActive()) {
      return;
    }
    const sidebarEl = document.getElementsByClassName("mod-left-split")[0];
    const ribbonEl = document.getElementsByClassName("side-dock-ribbon")[0];
    if (sidebarEl && ribbonEl && document.body.classList.contains("theme-light") && this.plugin.settings.lightStyle === "oxygen-light-contrast") {
      sidebarEl.addClass("theme-dark");
      ribbonEl.addClass("theme-dark");
    } else if (sidebarEl && ribbonEl) {
      sidebarEl.removeClass("theme-dark");
      ribbonEl.removeClass("theme-dark");
    }
  }
  /**
   * Cleanup sidebar theme on unload
   */
  cleanupSidebarTheme() {
    const sidebarEl = document.getElementsByClassName("mod-left-split")[0];
    if (sidebarEl) {
      sidebarEl.removeClass("theme-dark");
    }
    const ribbonEl = document.getElementsByClassName("side-dock-ribbon")[0];
    if (ribbonEl) {
      ribbonEl.removeClass("theme-dark");
    }
  }
};

// src/managers/settings-sync.ts
var SettingsSyncManager = class {
  constructor(plugin) {
    this.plugin = plugin;
  }
  /**
   * Setup event watchers for vault config changes
   */
  setupWatchers() {
    this.plugin.registerEvent(
      onVaultConfigChanged(this.plugin.app, () => {
        this.syncFromVault();
      })
    );
    this.plugin.registerEvent(
      this.plugin.app.workspace.on("css-change", () => {
        this.updateSidebarTheme();
      })
    );
  }
  /**
   * Sync settings from Obsidian vault config
   * @param skipSave - If true, don't save settings (used during initial load)
   */
  syncFromVault(skipSave = false) {
    const fontSize = getVaultConfig(this.plugin.app, VAULT_CONFIG.BASE_FONT_SIZE);
    if (typeof fontSize === "number") {
      this.plugin.settings.textNormal = fontSize;
    }
    this.plugin.settings.folding = !!getVaultConfig(this.plugin.app, VAULT_CONFIG.FOLD_HEADING);
    this.plugin.settings.lineNumbers = !!getVaultConfig(this.plugin.app, VAULT_CONFIG.SHOW_LINE_NUMBER);
    this.plugin.settings.readableLineLength = !!getVaultConfig(this.plugin.app, VAULT_CONFIG.READABLE_LINE_LENGTH);
    const bodyClassList = document.body.classList;
    bodyClassList.toggle("oxygen-folding", this.plugin.settings.folding);
    bodyClassList.toggle("oxygen-line-nums", this.plugin.settings.lineNumbers);
    bodyClassList.toggle("oxygen-readable", this.plugin.settings.readableLineLength);
    bodyClassList.toggle("oxygen-readable-off", !this.plugin.settings.readableLineLength);
    if (!skipSave) {
      void this.plugin.saveData(this.plugin.settings);
    }
  }
  /**
   * Sync font size to Obsidian vault config
   */
  setFontSize() {
    setVaultConfig(this.plugin.app, VAULT_CONFIG.BASE_FONT_SIZE, this.plugin.settings.textNormal);
    updateFontSize(this.plugin.app);
  }
  /**
   * Update sidebar theme for high contrast mode
   */
  updateSidebarTheme() {
    const sidebarEl = document.getElementsByClassName("mod-left-split")[0];
    const ribbonEl = document.getElementsByClassName("side-dock-ribbon")[0];
    if (sidebarEl && ribbonEl && document.body.classList.contains("theme-light") && this.plugin.settings.lightStyle === "oxygen-light-contrast") {
      sidebarEl.addClass("theme-dark");
      ribbonEl.addClass("theme-dark");
    } else if (sidebarEl && ribbonEl) {
      sidebarEl.removeClass("theme-dark");
      ribbonEl.removeClass("theme-dark");
    }
  }
  /**
   * Cleanup - no specific cleanup needed for this manager
   */
  cleanup() {
  }
};

// src/commands/font-commands.ts
function registerFontCommands(plugin) {
  plugin.addCommand({
    id: COMMAND_IDS.INCREASE_FONT,
    name: "Increase body font size",
    callback: () => {
      plugin.settings.textNormal += DEFAULTS.FONT_STEP;
      void plugin.saveData(plugin.settings);
      setFontSize(plugin);
    }
  });
  plugin.addCommand({
    id: COMMAND_IDS.DECREASE_FONT,
    name: "Decrease body font size",
    callback: () => {
      plugin.settings.textNormal -= DEFAULTS.FONT_STEP;
      void plugin.saveData(plugin.settings);
      setFontSize(plugin);
    }
  });
}
function setFontSize(plugin) {
  setVaultConfig(plugin.app, "baseFontSize", plugin.settings.textNormal);
  updateFontSize(plugin.app);
}

// src/commands/scheme-commands.ts
function registerSchemeCommands(plugin) {
  LIGHT_SCHEMES.forEach((scheme) => {
    const schemeName = SCHEME_DISPLAY_NAMES[scheme] || scheme;
    plugin.addCommand({
      id: `toggle-${scheme}`,
      name: `Switch light color scheme to ${schemeName} (light)`,
      callback: () => {
        plugin.settings.lightScheme = scheme;
        void plugin.saveData(plugin.settings);
        updateLightScheme(plugin);
        updateLightStyle(plugin);
      }
    });
  });
  DARK_SCHEMES.forEach((scheme) => {
    const schemeName = SCHEME_DISPLAY_NAMES[scheme] || scheme;
    plugin.addCommand({
      id: `toggle-${scheme}`,
      name: `Switch dark color scheme to ${schemeName} (dark)`,
      callback: () => {
        plugin.settings.darkScheme = scheme;
        void plugin.saveData(plugin.settings);
        updateDarkScheme(plugin);
        updateDarkStyle(plugin);
      }
    });
  });
}
function updateLightScheme(plugin) {
  removeLightScheme(plugin);
  removeDarkScheme(plugin);
  if (!document.body.classList.contains("theme-light")) {
    document.body.removeClass("theme-dark");
    document.body.addClass("theme-light");
  }
  document.body.addClass(plugin.settings.lightScheme);
}
function updateDarkScheme(plugin) {
  removeDarkScheme(plugin);
  removeLightScheme(plugin);
  if (!document.body.classList.contains("theme-dark")) {
    document.body.removeClass("theme-light");
    document.body.addClass("theme-dark");
  }
  document.body.addClass(plugin.settings.darkScheme);
}
function updateLightStyle(plugin) {
  if (!plugin.isOxygenThemeActive()) {
    return;
  }
  document.body.removeClass(
    "theme-dark",
    "oxygen-light",
    "oxygen-light-tonal",
    "oxygen-light-contrast",
    "oxygen-light-white"
  );
  document.body.addClass("theme-light", plugin.settings.lightStyle);
  const theme = getVaultConfig(plugin.app, "theme");
  if (theme !== "system") {
    setTheme(plugin.app, "moonstone");
    setVaultConfig(plugin.app, "theme", "moonstone");
  }
  plugin.app.workspace.trigger("css-change");
}
function updateDarkStyle(plugin) {
  if (!plugin.isOxygenThemeActive()) {
    return;
  }
  document.body.removeClass(
    "theme-light",
    "oxygen-dark",
    "oxygen-dark-tonal",
    "oxygen-dark-black"
  );
  document.body.addClass("theme-dark", plugin.settings.darkStyle);
  const theme = getVaultConfig(plugin.app, "theme");
  if (theme !== "system") {
    setTheme(plugin.app, "obsidian");
    setVaultConfig(plugin.app, "theme", "obsidian");
  }
  plugin.app.workspace.trigger("css-change");
}
function removeLightScheme(plugin) {
  document.body.removeClass(...LIGHT_SCHEMES);
  plugin.settings.customPresets.forEach((preset) => {
    document.body.removeClass(`minimal-custom-${preset.id}`);
  });
}
function removeDarkScheme(plugin) {
  document.body.removeClass(...DARK_SCHEMES);
  plugin.settings.customPresets.forEach((preset) => {
    document.body.removeClass(`minimal-custom-${preset.id}`);
  });
}

// src/commands/style-commands.ts
function registerStyleCommands(plugin) {
  plugin.addCommand({
    id: COMMAND_IDS.CYCLE_DARK_STYLE,
    name: "Cycle between dark mode styles",
    callback: () => {
      const currentIndex = DARK_STYLES.indexOf(plugin.settings.darkStyle);
      const nextIndex = (currentIndex + 1) % DARK_STYLES.length;
      plugin.settings.darkStyle = DARK_STYLES[nextIndex];
      void plugin.saveData(plugin.settings);
      updateDarkStyle2(plugin);
    }
  });
  plugin.addCommand({
    id: COMMAND_IDS.CYCLE_LIGHT_STYLE,
    name: "Cycle between light mode styles",
    callback: () => {
      const currentIndex = LIGHT_STYLES.indexOf(plugin.settings.lightStyle);
      const nextIndex = (currentIndex + 1) % LIGHT_STYLES.length;
      plugin.settings.lightStyle = LIGHT_STYLES[nextIndex];
      void plugin.saveData(plugin.settings);
      updateLightStyle2(plugin);
    }
  });
  plugin.addCommand({
    id: COMMAND_IDS.LIGHT_DEFAULT,
    name: "Use light mode (default)",
    callback: () => {
      plugin.settings.lightStyle = "oxygen-light";
      plugin.settings.lightScheme = "oxygen-oxygen-light";
      void plugin.saveData(plugin.settings);
      updateLightScheme(plugin);
      updateLightStyle2(plugin);
    }
  });
  plugin.addCommand({
    id: COMMAND_IDS.LIGHT_WHITE,
    name: "Use light mode (all white)",
    callback: () => {
      plugin.settings.lightStyle = "oxygen-light-white";
      void plugin.saveData(plugin.settings);
      updateLightStyle2(plugin);
    }
  });
  plugin.addCommand({
    id: COMMAND_IDS.LIGHT_TONAL,
    name: "Use light mode (low contrast)",
    callback: () => {
      plugin.settings.lightStyle = "oxygen-light-tonal";
      void plugin.saveData(plugin.settings);
      updateLightStyle2(plugin);
    }
  });
  plugin.addCommand({
    id: COMMAND_IDS.LIGHT_CONTRAST,
    name: "Use light mode (high contrast)",
    callback: () => {
      plugin.settings.lightStyle = "oxygen-light-contrast";
      void plugin.saveData(plugin.settings);
      updateLightStyle2(plugin);
    }
  });
  plugin.addCommand({
    id: COMMAND_IDS.DARK_DEFAULT,
    name: "Use dark mode (default)",
    callback: () => {
      plugin.settings.darkStyle = "oxygen-dark";
      plugin.settings.darkScheme = "oxygen-oxygen-dark";
      void plugin.saveData(plugin.settings);
      updateDarkScheme(plugin);
      updateDarkStyle2(plugin);
    }
  });
  plugin.addCommand({
    id: COMMAND_IDS.DARK_TONAL,
    name: "Use dark mode (low contrast)",
    callback: () => {
      plugin.settings.darkStyle = "oxygen-dark-tonal";
      void plugin.saveData(plugin.settings);
      updateDarkStyle2(plugin);
    }
  });
  plugin.addCommand({
    id: COMMAND_IDS.DARK_BLACK,
    name: "Use dark mode (true black)",
    callback: () => {
      plugin.settings.darkStyle = "oxygen-dark-black";
      void plugin.saveData(plugin.settings);
      updateDarkStyle2(plugin);
    }
  });
}
function updateLightStyle2(plugin) {
  if (!plugin.isOxygenThemeActive()) {
    return;
  }
  document.body.removeClass(
    "theme-dark",
    "oxygen-light",
    "oxygen-light-tonal",
    "oxygen-light-contrast",
    "oxygen-light-white"
  );
  document.body.addClass("theme-light", plugin.settings.lightStyle);
  const theme = getVaultConfig(plugin.app, "theme");
  if (theme !== "system") {
    setTheme(plugin.app, "moonstone");
    setVaultConfig(plugin.app, "theme", "moonstone");
  }
  plugin.app.workspace.trigger("css-change");
}
function updateDarkStyle2(plugin) {
  if (!plugin.isOxygenThemeActive()) {
    return;
  }
  document.body.removeClass(
    "theme-light",
    "oxygen-dark",
    "oxygen-dark-tonal",
    "oxygen-dark-black"
  );
  document.body.addClass("theme-dark", plugin.settings.darkStyle);
  const theme = getVaultConfig(plugin.app, "theme");
  if (theme !== "system") {
    setTheme(plugin.app, "obsidian");
    setVaultConfig(plugin.app, "theme", "obsidian");
  }
  plugin.app.workspace.trigger("css-change");
}

// src/commands/preset-commands.ts
function registerPresetCommands(plugin) {
  plugin.addCommand({
    id: COMMAND_IDS.CREATE_PRESET,
    name: "Create custom color preset",
    callback: () => {
      const modal = new PresetEditorModal(plugin.app, plugin, null, (preset) => {
        plugin.settings.customPresets.push(preset);
        void plugin.saveData(plugin.settings);
      });
      modal.open();
    }
  });
  plugin.addCommand({
    id: COMMAND_IDS.IMPORT_PRESET,
    name: "Import custom color preset",
    callback: () => {
      const modal = new PresetImportModal(plugin.app, plugin, (preset) => {
        plugin.settings.customPresets.push(preset);
        void plugin.saveData(plugin.settings);
      });
      modal.open();
    }
  });
  plugin.addCommand({
    id: COMMAND_IDS.CYCLE_PRESETS_LIGHT,
    name: "Cycle through custom presets (light mode)",
    callback: () => {
      if (plugin.settings.customPresets.length === 0) return;
      const currentIndex = plugin.settings.customPresets.findIndex(
        (p) => plugin.settings.lightScheme === `oxygen-custom-${p.id}`
      );
      const nextIndex = (currentIndex + 1) % plugin.settings.customPresets.length;
      const nextPreset = plugin.settings.customPresets[nextIndex];
      plugin.settings.lightScheme = `oxygen-custom-${nextPreset.id}`;
      void plugin.saveData(plugin.settings);
      updateLightScheme2(plugin);
    }
  });
  plugin.addCommand({
    id: COMMAND_IDS.CYCLE_PRESETS_DARK,
    name: "Cycle through custom presets (dark mode)",
    callback: () => {
      if (plugin.settings.customPresets.length === 0) return;
      const currentIndex = plugin.settings.customPresets.findIndex(
        (p) => plugin.settings.darkScheme === `oxygen-custom-${p.id}`
      );
      const nextIndex = (currentIndex + 1) % plugin.settings.customPresets.length;
      const nextPreset = plugin.settings.customPresets[nextIndex];
      plugin.settings.darkScheme = `oxygen-custom-${nextPreset.id}`;
      void plugin.saveData(plugin.settings);
      updateDarkScheme2(plugin);
    }
  });
}
function updateLightScheme2(plugin) {
  plugin.updateLightScheme();
}
function updateDarkScheme2(plugin) {
  plugin.updateDarkScheme();
}

// src/commands/feature-commands.ts
function registerFeatureCommands(plugin) {
  plugin.addCommand({
    id: COMMAND_IDS.TOGGLE_BORDERS,
    name: "Toggle sidebar borders",
    callback: () => {
      const current = plugin.settings.workspaceBorders;
      if (current === "enhanced") {
        plugin.settings.workspaceBorders = "default";
      } else if (current === "default") {
        plugin.settings.workspaceBorders = "none";
      } else {
        plugin.settings.workspaceBorders = "enhanced";
      }
      void plugin.saveData(plugin.settings);
      refresh(plugin);
    }
  });
  plugin.addCommand({
    id: COMMAND_IDS.TOGGLE_COLORFUL_HEADINGS,
    name: "Toggle colorful headings",
    callback: () => {
      plugin.settings.colorfulHeadings = !plugin.settings.colorfulHeadings;
      void plugin.saveData(plugin.settings);
      refresh(plugin);
    }
  });
  plugin.addCommand({
    id: COMMAND_IDS.TOGGLE_COLORFUL_FRAME,
    name: "Toggle colorful window frame",
    callback: () => {
      plugin.settings.colorfulFrame = !plugin.settings.colorfulFrame;
      void plugin.saveData(plugin.settings);
      refresh(plugin);
    }
  });
  plugin.addCommand({
    id: COMMAND_IDS.TOGGLE_IMAGE_GRID,
    name: "Toggle image grids",
    callback: () => {
      plugin.settings.imgGrid = !plugin.settings.imgGrid;
      void plugin.saveData(plugin.settings);
      refresh(plugin);
    }
  });
  plugin.addCommand({
    id: COMMAND_IDS.TOGGLE_THEME,
    name: "Switch between light and dark mode",
    callback: () => {
      updateTheme(plugin);
    }
  });
  plugin.addCommand({
    id: COMMAND_IDS.DEV_BLOCK_WIDTH,
    name: "Dev: show block widths",
    callback: () => {
      plugin.settings.devBlockWidth = !plugin.settings.devBlockWidth;
      void plugin.saveData(plugin.settings);
      refresh(plugin);
    }
  });
  plugin.addCommand({
    id: COMMAND_IDS.OPEN_SETTINGS,
    name: "Open settings",
    icon: "settings-2",
    callback: () => {
      const appWithSettings = plugin.app;
      appWithSettings.setting.open();
      appWithSettings.setting.openTabById(plugin.manifest.id);
    }
  });
}
function refresh(plugin) {
  plugin.updateStyle();
}
function updateTheme(plugin) {
  if (!plugin.isOxygenThemeActive()) {
    return;
  }
  const theme = getVaultConfig(plugin.app, "theme");
  if (theme === "system") {
    if (document.body.classList.contains("theme-light")) {
      document.body.removeClass("theme-light");
      document.body.addClass("theme-dark");
    } else {
      document.body.removeClass("theme-dark");
      document.body.addClass("theme-light");
    }
  } else {
    if (document.body.classList.contains("theme-light")) {
      document.body.removeClass("theme-light");
      document.body.addClass("theme-dark");
    } else {
      document.body.removeClass("theme-dark");
      document.body.addClass("theme-light");
    }
    const currentTheme = getVaultConfig(plugin.app, "theme");
    const newTheme = currentTheme === "moonstone" ? "obsidian" : "moonstone";
    setTheme(plugin.app, newTheme);
    setVaultConfig(plugin.app, "theme", newTheme);
  }
  plugin.app.workspace.trigger("css-change");
}

// src/commands/width-commands.ts
function registerWidthCommands(plugin) {
  plugin.addCommand({
    id: COMMAND_IDS.CYCLE_TABLE_WIDTH,
    name: "Cycle between table width options",
    callback: () => {
      const currentIndex = TABLE_WIDTH_STYLES.indexOf(plugin.settings.tableWidth);
      const nextIndex = (currentIndex + 1) % TABLE_WIDTH_STYLES.length;
      plugin.settings.tableWidth = TABLE_WIDTH_STYLES[nextIndex];
      void plugin.saveData(plugin.settings);
      refresh2(plugin);
    }
  });
  plugin.addCommand({
    id: COMMAND_IDS.CYCLE_IMAGE_WIDTH,
    name: "Cycle between image width options",
    callback: () => {
      const currentIndex = IMAGE_WIDTH_STYLES.indexOf(plugin.settings.imgWidth);
      const nextIndex = (currentIndex + 1) % IMAGE_WIDTH_STYLES.length;
      plugin.settings.imgWidth = IMAGE_WIDTH_STYLES[nextIndex];
      void plugin.saveData(plugin.settings);
      refresh2(plugin);
    }
  });
  plugin.addCommand({
    id: COMMAND_IDS.CYCLE_IFRAME_WIDTH,
    name: "Cycle between iframe width options",
    callback: () => {
      const currentIndex = IFRAME_WIDTH_STYLES.indexOf(plugin.settings.iframeWidth);
      const nextIndex = (currentIndex + 1) % IFRAME_WIDTH_STYLES.length;
      plugin.settings.iframeWidth = IFRAME_WIDTH_STYLES[nextIndex];
      void plugin.saveData(plugin.settings);
      refresh2(plugin);
    }
  });
  plugin.addCommand({
    id: COMMAND_IDS.CYCLE_CHART_WIDTH,
    name: "Cycle between chart width options",
    callback: () => {
      const currentIndex = CHART_WIDTH_STYLES.indexOf(plugin.settings.chartWidth);
      const nextIndex = (currentIndex + 1) % CHART_WIDTH_STYLES.length;
      plugin.settings.chartWidth = CHART_WIDTH_STYLES[nextIndex];
      void plugin.saveData(plugin.settings);
      refresh2(plugin);
    }
  });
  plugin.addCommand({
    id: COMMAND_IDS.CYCLE_MAP_WIDTH,
    name: "Cycle between map width options",
    callback: () => {
      const currentIndex = MAP_WIDTH_STYLES.indexOf(plugin.settings.mapWidth);
      const nextIndex = (currentIndex + 1) % MAP_WIDTH_STYLES.length;
      plugin.settings.mapWidth = MAP_WIDTH_STYLES[nextIndex];
      void plugin.saveData(plugin.settings);
      refresh2(plugin);
    }
  });
}
function refresh2(plugin) {
  plugin.updateStyle();
}

// src/commands/index.ts
function registerAllCommands(plugin) {
  registerFontCommands(plugin);
  registerStyleCommands(plugin);
  registerSchemeCommands(plugin);
  registerPresetCommands(plugin);
  registerFeatureCommands(plugin);
  registerWidthCommands(plugin);
}

// src/utils/migrations.ts
var MigrationRunner = class {
  constructor(app, settings) {
    this.app = app;
    this.settings = settings;
  }
  async run() {
    let migrated = false;
    const migrationVersion = "minimal-to-oxygen-prefix-v1";
    if (!this.settings._migrationVersions || !this.settings._migrationVersions.includes(migrationVersion)) {
      let prefixMigrated = false;
      if (this.settings.lightStyle && this.settings.lightStyle.startsWith("minimal-")) {
        this.settings.lightStyle = this.settings.lightStyle.replace(/^minimal-/, "oxygen-");
        prefixMigrated = true;
      }
      if (this.settings.darkStyle && this.settings.darkStyle.startsWith("minimal-")) {
        this.settings.darkStyle = this.settings.darkStyle.replace(/^minimal-/, "oxygen-");
        prefixMigrated = true;
      }
      if (this.settings.lightScheme && this.settings.lightScheme.startsWith("minimal-")) {
        this.settings.lightScheme = this.settings.lightScheme.replace(/^minimal-/, "oxygen-");
        prefixMigrated = true;
      }
      if (this.settings.darkScheme && this.settings.darkScheme.startsWith("minimal-")) {
        this.settings.darkScheme = this.settings.darkScheme.replace(/^minimal-/, "oxygen-");
        prefixMigrated = true;
      }
      if (prefixMigrated) {
        if (!this.settings._migrationVersions) {
          this.settings._migrationVersions = [];
        }
        this.settings._migrationVersions.push(migrationVersion);
        migrated = true;
        console.debug("[Oxygen Settings] Migrated settings from minimal- to oxygen- prefix");
      }
    }
    if (this.settings.lightScheme === "minimal-default-light") {
      this.settings.lightScheme = "oxygen-minimal-light";
      migrated = true;
    }
    if (this.settings.darkScheme === "minimal-default-dark") {
      this.settings.darkScheme = "oxygen-minimal-dark";
      migrated = true;
    }
    if (this.settings.animationPersonality === "refined") {
      this.settings.animationPersonality = "default";
      migrated = true;
    }
    return migrated;
  }
  /**
   * Specifically handles the workspace borders migration which requires checking if a value was previously set.
   */
  migrateWorkspaceBorders(loadedData) {
    if (loadedData && typeof loadedData === "object") {
      const legacyData = loadedData;
      if (legacyData.bordersToggle !== void 0 || legacyData.workspaceBordersEnhanced !== void 0) {
        if (legacyData.workspaceBorders === void 0) {
          if (legacyData.bordersToggle === false) {
            this.settings.workspaceBorders = "none";
          } else if (legacyData.workspaceBordersEnhanced === true) {
            this.settings.workspaceBorders = "enhanced";
          } else {
            this.settings.workspaceBorders = "default";
          }
          return true;
        }
      }
    }
    return false;
  }
};

// src/main.ts
var MinimalTheme = class extends import_obsidian12.Plugin {
  constructor() {
    super(...arguments);
    // Cache theme state to avoid repeated vault config calls (performance optimization)
    this._isOxygenActive = false;
    this._isInitialized = false;
  }
  async onload() {
    await this.loadSettings();
    this.styleManager = new StyleManagerImpl(this);
    this.themeManager = new ThemeManagerImpl(this);
    this.settingsSyncManager = new SettingsSyncManager(this);
    this.settingsTab = new MinimalSettingsTab(this.app, this);
    this.addSettingTab(this.settingsTab);
    this._isOxygenActive = isOxygenThemeActive(this.app);
    const initialThemeMode = document.body.classList.contains("theme-light") ? "light" : "dark";
    if (this._isOxygenActive) {
      this.styleManager.initialize();
      this._isInitialized = true;
    }
    this.settingsSyncManager.setupWatchers();
    this.settingsSyncManager.syncFromVault(true);
    this.app.workspace.onLayoutReady(() => {
      if (this._isOxygenActive) {
        this.themeManager.updateSidebarTheme();
      }
    });
    registerAllCommands(this);
    let debounceTimer;
    let lastThemeMode = initialThemeMode;
    this.registerEvent(
      this.app.workspace.on("css-change", () => {
        window.clearTimeout(debounceTimer);
        debounceTimer = window.setTimeout(() => {
          const newThemeState = isOxygenThemeActive(this.app);
          const currentThemeMode = document.body.classList.contains("theme-light") ? "light" : "dark";
          const themeModeChanged = lastThemeMode !== null && lastThemeMode !== currentThemeMode;
          lastThemeMode = currentThemeMode;
          if (this._isOxygenActive && !newThemeState) {
            this._isOxygenActive = false;
            this._isInitialized = false;
            this.styleManager.cleanup();
          } else if (!this._isOxygenActive && newThemeState && !this._isInitialized) {
            this._isOxygenActive = true;
            this._isInitialized = true;
            this.styleManager.initialize();
          } else if (this._isOxygenActive && newThemeState && this._isInitialized && themeModeChanged) {
            this.styleManager.updateStyle();
            this.styleManager.updateCustomPresetCSS();
          } else if (this._isOxygenActive && newThemeState && this._isInitialized) {
            this.styleManager.updateCustomPresetCSS();
          }
        }, 100);
      })
    );
  }
  onunload() {
    this.themeManager.cleanupSidebarTheme();
    this.styleManager.cleanup();
    this.settingsSyncManager.cleanup();
  }
  async loadSettings() {
    const loadedData = await this.loadData();
    this.settings = Object.assign({}, DEFAULT_SETTINGS, loadedData);
    const migrationRunner = new MigrationRunner(this.app, this.settings);
    let migrated = await migrationRunner.run();
    if (migrationRunner.migrateWorkspaceBorders(loadedData)) {
      migrated = true;
    }
    if (!this.settings.customPresets) {
      this.settings.customPresets = [];
    }
    if (this.settings.enableCustomPresets === void 0) {
      this.settings.enableCustomPresets = true;
    }
    if (!this.settings.animationPersonality) {
      this.settings.animationPersonality = "default";
    }
    if (migrated) {
      await this.saveSettings();
    }
  }
  async saveSettings() {
    await this.saveData(this.settings);
  }
  // Convenience methods that delegate to managers
  refresh() {
    this.styleManager.refresh();
  }
  updateStyle() {
    this.styleManager.updateStyle();
  }
  updateLightStyle() {
    this.styleManager.updateLightStyle();
  }
  updateDarkStyle() {
    this.styleManager.updateDarkStyle();
  }
  updateLightScheme() {
    this.styleManager.updateLightScheme();
  }
  updateDarkScheme() {
    this.styleManager.updateDarkScheme();
  }
  updateCustomPresetCSS() {
    this.styleManager.updateCustomPresetCSS();
  }
  setFontSize() {
    this.settingsSyncManager.setFontSize();
  }
  /**
   * Check if the Oxygen theme is currently active (uses cached value for performance)
   * @returns true if Oxygen theme is active, false otherwise
   */
  isOxygenThemeActive() {
    return this._isOxygenActive;
  }
};
//# sourceMappingURL=data:application/json;base64,[encoded data, 364460 characters]
