Просмотр исходного кода

Merge pull request #7093 from weseek/imprv/use-css-var

imprv: Use CSS variables
Yuki Takei 3 лет назад
Родитель
Сommit
ecfd51ae18
72 измененных файлов с 3382 добавлено и 4463 удалено
  1. 3 4
      packages/app/src/components/Admin/Customize/CustomizeThemeSetting.tsx
  2. 1 1
      packages/app/src/components/Admin/UserGroupDetail/UpdateParentConfirmModal.tsx
  3. 2 1
      packages/app/src/components/Layout/RawLayout.tsx
  4. 3 3
      packages/app/src/components/Navbar/AppearanceModeDropdown.tsx
  5. 1 1
      packages/app/src/components/PageRenameModal.tsx
  6. 2 2
      packages/app/src/components/SearchPage/SearchControl.tsx
  7. 1 1
      packages/app/src/interfaces/customize.ts
  8. 5 2
      packages/app/src/pages/_app.page.tsx
  9. 6 51
      packages/app/src/pages/_document.page.tsx
  10. 6 2
      packages/app/src/pages/utils/commons.ts
  11. 2 1
      packages/app/src/server/crowi/index.js
  12. 1 0
      packages/app/src/server/models/config.ts
  13. 1 0
      packages/app/src/server/routes/apiv3/customize-setting.js
  14. 41 1
      packages/app/src/server/service/customize.ts
  15. 18 7
      packages/app/src/server/service/plugin.ts
  16. 7 3
      packages/app/src/stores/admin/customize.tsx
  17. 5 1
      packages/app/src/stores/context.tsx
  18. 14 19
      packages/app/src/stores/use-next-themes.tsx
  19. 0 1
      packages/app/src/styles/bootstrap/_variables.scss
  20. 469 429
      packages/app/src/styles/theme/_apply-colors-dark.scss
  21. 376 342
      packages/app/src/styles/theme/_apply-colors-light.scss
  22. 119 124
      packages/app/src/styles/theme/_apply-colors.scss
  23. 32 0
      packages/app/src/styles/theme/_hsl-functions.scss
  24. 112 0
      packages/app/src/styles/theme/_hsl-reboot-bootstrap-theme-colors.scss
  25. 1 1
      packages/app/src/styles/theme/_reboot-bootstrap-border-colors.scss
  26. 7 6
      packages/app/src/styles/theme/_reboot-bootstrap-buttons.scss
  27. 8 8
      packages/app/src/styles/theme/_reboot-bootstrap-colors.scss
  28. 11 11
      packages/app/src/styles/theme/_reboot-bootstrap-dropdown.scss
  29. 9 9
      packages/app/src/styles/theme/_reboot-bootstrap-tables.scss
  30. 14 5
      packages/app/src/styles/theme/_reboot-bootstrap-theme-colors.scss
  31. 11 4
      packages/app/src/styles/theme/_reboot-toastr-colors.scss
  32. 21 0
      packages/app/src/styles/theme/mixins/_hsl-badge.scss
  33. 142 0
      packages/app/src/styles/theme/mixins/_hsl-button.scss
  34. 1 1
      packages/app/src/styles/theme/mixins/_list-group.scss
  35. 0 34
      packages/app/src/styles/theme/mixins/_tables.scss
  36. 2 0
      packages/core/src/index.ts
  37. 5 0
      packages/core/src/interfaces/color-scheme.ts
  38. 3 2
      packages/core/src/interfaces/growi-theme-metadata.ts
  39. 8 0
      packages/core/src/utils/growi-theme-metadata.ts
  40. 89 66
      packages/preset-themes/src/styles/antarctic.scss
  41. 92 64
      packages/preset-themes/src/styles/blackboard.scss
  42. 0 1
      packages/preset-themes/src/styles/bootstrap/_variables.scss
  43. 94 77
      packages/preset-themes/src/styles/christmas.scss
  44. 172 127
      packages/preset-themes/src/styles/default.scss
  45. 180 112
      packages/preset-themes/src/styles/fire-red.scss
  46. 92 58
      packages/preset-themes/src/styles/future.scss
  47. 76 63
      packages/preset-themes/src/styles/halloween.scss
  48. 188 137
      packages/preset-themes/src/styles/hufflepuff.scss
  49. 91 60
      packages/preset-themes/src/styles/island.scss
  50. 163 112
      packages/preset-themes/src/styles/jade-green.scss
  51. 88 65
      packages/preset-themes/src/styles/kibela.scss
  52. 165 108
      packages/preset-themes/src/styles/mono-blue.scss
  53. 70 54
      packages/preset-themes/src/styles/nature.scss
  54. 89 77
      packages/preset-themes/src/styles/spring.scss
  55. 0 538
      packages/preset-themes/src/styles/theme/_apply-colors-dark.scss
  56. 0 430
      packages/preset-themes/src/styles/theme/_apply-colors-light.scss
  57. 0 691
      packages/preset-themes/src/styles/theme/_apply-colors.scss
  58. 32 0
      packages/preset-themes/src/styles/theme/_hsl-functions.scss
  59. 0 25
      packages/preset-themes/src/styles/theme/_reboot-bootstrap-border-colors.scss
  60. 0 21
      packages/preset-themes/src/styles/theme/_reboot-bootstrap-buttons.scss
  61. 0 60
      packages/preset-themes/src/styles/theme/_reboot-bootstrap-colors.scss
  62. 0 37
      packages/preset-themes/src/styles/theme/_reboot-bootstrap-dropdown.scss
  63. 0 51
      packages/preset-themes/src/styles/theme/_reboot-bootstrap-nav.scss
  64. 0 74
      packages/preset-themes/src/styles/theme/_reboot-bootstrap-tables.scss
  65. 0 3
      packages/preset-themes/src/styles/theme/_reboot-bootstrap-text.scss
  66. 0 92
      packages/preset-themes/src/styles/theme/_reboot-bootstrap-theme-colors.scss
  67. 0 0
      packages/preset-themes/src/styles/theme/_reboot-toastr-colors.scss
  68. 0 9
      packages/preset-themes/src/styles/theme/mixins/_count-badge.scss
  69. 142 0
      packages/preset-themes/src/styles/theme/mixins/_hsl-button.scss
  70. 0 70
      packages/preset-themes/src/styles/theme/mixins/_list-group.scss
  71. 0 34
      packages/preset-themes/src/styles/theme/mixins/_tables.scss
  72. 89 70
      packages/preset-themes/src/styles/wood.scss

+ 3 - 4
packages/app/src/components/Admin/Customize/CustomizeThemeSetting.tsx

@@ -3,7 +3,6 @@ import React, { useCallback, useEffect, useState } from 'react';
 import { PresetThemes, PresetThemesMetadatas } from '@growi/preset-themes';
 import { useTranslation } from 'next-i18next';
 
-import { apiv3Put } from '~/client/util/apiv3-client';
 import { toastSuccess, toastError, toastWarning } from '~/client/util/toastr';
 import { useSWRxGrowiThemeSetting } from '~/stores/admin/customize';
 
@@ -20,7 +19,7 @@ type Props = {
 const CustomizeThemeSetting = (props: Props): JSX.Element => {
   const { t } = useTranslation();
 
-  const { data, error } = useSWRxGrowiThemeSetting();
+  const { data, error, update } = useSWRxGrowiThemeSetting();
   const [currentTheme, setCurrentTheme] = useState(data?.currentTheme);
 
   useEffect(() => {
@@ -38,7 +37,7 @@ const CustomizeThemeSetting = (props: Props): JSX.Element => {
     }
 
     try {
-      await apiv3Put('/customize-setting/theme', {
+      await update({
         theme: currentTheme,
       });
 
@@ -47,7 +46,7 @@ const CustomizeThemeSetting = (props: Props): JSX.Element => {
     catch (err) {
       toastError(err);
     }
-  }, [currentTheme, t]);
+  }, [currentTheme, t, update]);
 
   const availableThemes = data?.pluginThemesMetadatas == null
     ? PresetThemesMetadatas

+ 1 - 1
packages/app/src/components/Admin/UserGroupDetail/UpdateParentConfirmModal.tsx

@@ -43,7 +43,7 @@ export const UpdateParentConfirmModal: FC = () => {
                 {t('admin:user_group_management.update_parent_confirm_modal.danger_message')}
               </div>
 
-              <div className="custom-control custom-checkbox custom-checkbox-primary pl-5">
+              <div className="custom-control custom-checkbox custom-checkbox-succsess pl-5">
                 <input
                   className="custom-control-input"
                   name="forceUpdateParents"

+ 2 - 1
packages/app/src/components/Layout/RawLayout.tsx

@@ -1,10 +1,11 @@
 import React, { ReactNode, useState } from 'react';
 
+import { ColorScheme } from '@growi/core';
 import Head from 'next/head';
 import { ToastContainer } from 'react-toastify';
 import { useIsomorphicLayoutEffect } from 'usehooks-ts';
 
-import { ColorScheme, useNextThemes, NextThemesProvider } from '~/stores/use-next-themes';
+import { useNextThemes, NextThemesProvider } from '~/stores/use-next-themes';
 import loggerFactory from '~/utils/logger';
 
 

+ 3 - 3
packages/app/src/components/Navbar/AppearanceModeDropdown.tsx

@@ -47,15 +47,15 @@ export const AppearanceModeDropdown:FC<AppearanceModeDropdownProps> = (props: Ap
 
   const followOsCheckboxModifiedHandler = useCallback((isChecked: boolean) => {
     if (isChecked) {
-      setTheme(Themes.system);
+      setTheme(Themes.SYSTEM);
     }
     else {
-      setTheme(resolvedTheme ?? Themes.light);
+      setTheme(resolvedTheme ?? Themes.LIGHT);
     }
   }, [resolvedTheme, setTheme]);
 
   const userPreferenceSwitchModifiedHandler = useCallback((isDarkMode: boolean) => {
-    setTheme(isDarkMode ? Themes.dark : Themes.light);
+    setTheme(isDarkMode ? Themes.DARK : Themes.LIGHT);
   }, [setTheme]);
 
   /* eslint-disable react/prop-types */

+ 1 - 1
packages/app/src/components/PageRenameModal.tsx

@@ -304,7 +304,7 @@ const PageRenameModal = (): JSX.Element => {
             </label>
           </div>
 
-          <div className="custom-control custom-checkbox custom-checkbox-primary">
+          <div className="custom-control custom-checkbox custom-checkbox-success">
             <input
               className="custom-control-input"
               name="remain_metadata"

+ 2 - 2
packages/app/src/components/SearchPage/SearchControl.tsx

@@ -118,7 +118,7 @@ const SearchControl: FC <Props> = React.memo((props: Props) => {
             </div>
             <div className="d-none d-lg-flex align-items-center ml-auto search-control-include-options">
               <div className="border rounded px-2 py-1 mr-3">
-                <div className="custom-control custom-checkbox custom-checkbox-primary">
+                <div className="custom-control custom-checkbox custom-checkbox-succsess">
                   <input
                     className="custom-control-input mr-2"
                     type="checkbox"
@@ -132,7 +132,7 @@ const SearchControl: FC <Props> = React.memo((props: Props) => {
                 </div>
               </div>
               <div className="border rounded px-2 py-1">
-                <div className="custom-control custom-checkbox custom-checkbox-primary">
+                <div className="custom-control custom-checkbox custom-checkbox-succsess">
                   <input
                     className="custom-control-input mr-2"
                     type="checkbox"

+ 1 - 1
packages/app/src/interfaces/customize.ts

@@ -1,4 +1,4 @@
-import { GrowiThemeMetadata } from '@growi/core';
+import type { GrowiThemeMetadata } from '@growi/core';
 
 export type IResLayoutSetting = {
   isContainerFluid: boolean,

+ 5 - 2
packages/app/src/pages/_app.page.tsx

@@ -11,7 +11,7 @@ import * as nextI18nConfig from '^/config/next-i18next.config';
 import { ActivatePluginService } from '~/client/services/activate-plugin';
 import { useI18nextHMR } from '~/services/i18next-hmr';
 import {
-  useAppTitle, useConfidential, useGrowiVersion, useSiteUrl, useIsDefaultLogo,
+  useAppTitle, useConfidential, useGrowiVersion, useSiteUrl, useIsDefaultLogo, useForcedColorScheme,
 } from '~/stores/context';
 import { SWRConfigValue, swrGlobalConfiguration } from '~/utils/swr-utils';
 
@@ -20,7 +20,9 @@ import { CommonProps } from './utils/commons';
 import { registerTransformerForObjectId } from './utils/objectid-transformer';
 
 import '~/styles/style-app.scss';
-
+import '~/styles/theme/_apply-colors-light.scss';
+import '~/styles/theme/_apply-colors-dark.scss';
+import '~/styles/theme/_apply-colors.scss';
 
 const isDev = process.env.NODE_ENV === 'development';
 
@@ -64,6 +66,7 @@ function GrowiApp({ Component, pageProps }: GrowiAppProps): JSX.Element {
   useConfidential(commonPageProps.confidential);
   useGrowiVersion(commonPageProps.growiVersion);
   useIsDefaultLogo(commonPageProps.isDefaultLogo);
+  useForcedColorScheme(commonPageProps.forcedColorScheme);
 
   // Use the layout defined at the page level, if available
   const getLayout = Component.getLayout ?? (page => page);

+ 6 - 51
packages/app/src/pages/_document.page.tsx

@@ -1,8 +1,6 @@
 /* eslint-disable @next/next/google-font-display */
 import React from 'react';
 
-import type { ViteManifest } from '@growi/core';
-import { DefaultThemeMetadata, PresetThemesMetadatas } from '@growi/preset-themes';
 import Document, {
   DocumentContext, DocumentInitialProps,
   Html, Head, Main, NextScript,
@@ -14,40 +12,6 @@ import loggerFactory from '~/utils/logger';
 
 const logger = loggerFactory('growi:page:_document');
 
-type HeadersForThemesProps = {
-  theme: string,
-  presetThemesManifest: ViteManifest,
-  pluginThemeHref: string | undefined,
-}
-const HeadersForThemes = (props: HeadersForThemesProps): JSX.Element => {
-  const {
-    theme, presetThemesManifest, pluginThemeHref,
-  } = props;
-
-  const elements: JSX.Element[] = [];
-
-  // when plugin theme is specified
-  if (pluginThemeHref != null) {
-    elements.push(
-      <link rel="stylesheet" key={`link_custom-themes-${theme}`} href={pluginThemeHref} />,
-    );
-  }
-  // preset theme
-  else {
-    const themeMetadata = PresetThemesMetadatas.find(p => p.name === theme);
-    const manifestKey = themeMetadata?.manifestKey ?? DefaultThemeMetadata.manifestKey;
-    if (themeMetadata == null || !(themeMetadata.manifestKey in presetThemesManifest)) {
-      logger.warn(`Use default theme because the key for '${theme} does not exist in preset-themes manifest`);
-    }
-    const href = `/static/preset-themes/${presetThemesManifest[manifestKey].file}`; // configured by express.static
-    elements.push(
-      <link rel="stylesheet" key={`link_preset-themes-${theme}`} href={href} />,
-    );
-  }
-
-  return <>{elements}</>;
-};
-
 type HeadersForGrowiPluginProps = {
   pluginResourceEntries: GrowiPluginResourceEntries;
 }
@@ -72,12 +36,10 @@ const HeadersForGrowiPlugin = (props: HeadersForGrowiPluginProps): JSX.Element =
 };
 
 interface GrowiDocumentProps {
-  theme: string,
+  themeHref: string,
   customScript: string | null,
   customCss: string | null,
   customNoscript: string | null,
-  presetThemesManifest: ViteManifest,
-  pluginThemeHref: string | undefined,
   pluginResourceEntries: GrowiPluginResourceEntries;
 }
 declare type GrowiDocumentInitialProps = DocumentInitialProps & GrowiDocumentProps;
@@ -87,28 +49,22 @@ class GrowiDocument extends Document<GrowiDocumentInitialProps> {
   static override async getInitialProps(ctx: DocumentContext): Promise<GrowiDocumentInitialProps> {
     const initialProps: DocumentInitialProps = await Document.getInitialProps(ctx);
     const { crowi } = ctx.req as CrowiRequest<any>;
-    const { configManager, customizeService, pluginService } = crowi;
+    const { customizeService, pluginService } = crowi;
 
-    const theme = configManager.getConfig('crowi', 'customize:theme');
+    const { themeHref } = customizeService;
     const customScript: string | null = customizeService.getCustomScript();
     const customCss: string | null = customizeService.getCustomCss();
     const customNoscript: string | null = customizeService.getCustomNoscript();
 
-    // import preset-themes manifest
-    const presetThemesManifest = await import('@growi/preset-themes/dist/themes/manifest.json').then(imported => imported.default);
-
     // retrieve plugin manifests
     const pluginResourceEntries = await (pluginService as IPluginService).retrieveAllPluginResourceEntries();
-    const pluginThemeHref = await (pluginService as IPluginService).retrieveThemeHref(theme);
 
     return {
       ...initialProps,
-      theme,
+      themeHref,
       customScript,
       customCss,
       customNoscript,
-      presetThemesManifest,
-      pluginThemeHref,
       pluginResourceEntries,
     };
   }
@@ -137,7 +93,7 @@ class GrowiDocument extends Document<GrowiDocumentInitialProps> {
   override render(): JSX.Element {
     const {
       customCss, customScript, customNoscript,
-      theme, presetThemesManifest, pluginThemeHref, pluginResourceEntries,
+      themeHref, pluginResourceEntries,
     } = this.props;
 
     return (
@@ -150,8 +106,7 @@ class GrowiDocument extends Document<GrowiDocumentInitialProps> {
           <link rel='preload' href="/static/fonts/Lato-Regular-latin-ext.woff2" as="font" type="font/woff2" />
           <link rel='preload' href="/static/fonts/Lato-Bold-latin.woff2" as="font" type="font/woff2" />
           <link rel='preload' href="/static/fonts/Lato-Bold-latin-ext.woff2" as="font" type="font/woff2" />
-          <HeadersForThemes theme={theme}
-            presetThemesManifest={presetThemesManifest} pluginThemeHref={pluginThemeHref} />
+          <link rel="stylesheet" key="link-theme" href={themeHref} />
           <HeadersForGrowiPlugin pluginResourceEntries={pluginResourceEntries} />
           {this.renderCustomCss(customCss)}
         </Head>

+ 6 - 2
packages/app/src/pages/utils/commons.ts

@@ -1,12 +1,13 @@
+import type { ColorScheme, IUser, IUserHasId } from '@growi/core';
 import {
-  DevidedPagePath, Lang, AllLang, IUser, IUserHasId,
+  DevidedPagePath, Lang, AllLang,
 } from '@growi/core';
 import { GetServerSideProps, GetServerSidePropsContext } from 'next';
 import { SSRConfig, UserConfig } from 'next-i18next';
 
 import * as nextI18NextConfig from '^/config/next-i18next.config';
 
-import { CrowiRequest } from '~/interfaces/crowi-request';
+import type { CrowiRequest } from '~/interfaces/crowi-request';
 
 export type CommonProps = {
   namespacesRequired: string[], // i18next
@@ -22,6 +23,7 @@ export type CommonProps = {
   redirectDestination: string | null,
   isDefaultLogo: boolean,
   currentUser?: IUser,
+  forcedColorScheme?: ColorScheme,
 } & Partial<SSRConfig>;
 
 // eslint-disable-next-line max-len
@@ -47,6 +49,7 @@ export const getServerSideCommonProps: GetServerSideProps<CommonProps> = async(c
   const redirectDestination = !isMaintenanceMode && currentPathname === '/maintenance' ? '/' : isMaintenanceMode && !currentPathname.match('/admin/*') && !(currentPathname === '/maintenance') ? '/maintenance' : null;
   const isCustomizedLogoUploaded = await attachmentService.isBrandLogoExist();
   const isDefaultLogo = crowi.configManager.getConfig('crowi', 'customize:isDefaultLogo') || !isCustomizedLogoUploaded;
+  const forcedColorScheme = crowi.customizeService.forcedColorScheme;
 
   const props: CommonProps = {
     namespacesRequired: ['translation'],
@@ -62,6 +65,7 @@ export const getServerSideCommonProps: GetServerSideProps<CommonProps> = async(c
     redirectDestination,
     currentUser,
     isDefaultLogo,
+    forcedColorScheme,
   };
 
   return { props };

+ 2 - 1
packages/app/src/server/crowi/index.js

@@ -130,7 +130,6 @@ Crowi.prototype.init = async function() {
     this.setUpFileUploaderSwitchService(),
     this.setupAttachmentService(),
     this.setUpAcl(),
-    this.setUpCustomize(),
     this.setUpRestQiitaAPI(),
     this.setupUserGroupService(),
     this.setupExport(),
@@ -141,6 +140,7 @@ Crowi.prototype.init = async function() {
     this.setupActivityService(),
     this.setupCommentService(),
     this.setupSyncPageStatusService(),
+    this.setUpCustomize(), // depends on pluginService
   ]);
 
   // globalNotification depends on slack and mailer
@@ -604,6 +604,7 @@ Crowi.prototype.setUpCustomize = async function() {
     this.customizeService = new CustomizeService(this);
     this.customizeService.initCustomCss();
     this.customizeService.initCustomTitle();
+    this.customizeService.initGrowiTheme();
 
     // add as a message handler
     if (this.s2sMessagingService != null) {

+ 1 - 0
packages/app/src/server/models/config.ts

@@ -116,6 +116,7 @@ export const defaultCrowiConfigs: { [key: string]: any } = {
   'customize:highlightJsStyle' : 'github',
   'customize:highlightJsStyleBorder' : false,
   'customize:theme' : PresetThemes.DEFAULT,
+  'customize:theme:forcedColorScheme' : null,
   'customize:isContainerFluid' : false,
   'customize:isEnabledTimeline' : true,
   'customize:isEnabledAttachTitleHeader' : false,

+ 1 - 0
packages/app/src/server/routes/apiv3/customize-setting.js

@@ -325,6 +325,7 @@ module.exports = (crowi) => {
       const customizedParams = {
         theme: await crowi.configManager.getConfig('crowi', 'customize:theme'),
       };
+      customizeService.initGrowiTheme();
       const parameters = { action: SupportedAction.ACTION_ADMIN_THEME_UPDATE };
       activityEvent.emit('update', res.locals.activity._id, parameters);
       return res.apiv3({ customizedParams });

+ 41 - 1
packages/app/src/server/service/customize.ts

@@ -1,5 +1,6 @@
 // eslint-disable-next-line no-unused-vars
-import { DevidedPagePath } from '@growi/core';
+import { ColorScheme, DevidedPagePath, getForcedColorScheme } from '@growi/core';
+import { DefaultThemeMetadata, PresetThemesMetadatas } from '@growi/preset-themes';
 import uglifycss from 'uglifycss';
 
 import loggerFactory from '~/utils/logger';
@@ -7,8 +8,10 @@ import loggerFactory from '~/utils/logger';
 import S2sMessage from '../models/vo/s2s-message';
 
 import ConfigManager from './config-manager';
+import type { IPluginService } from './plugin';
 import { S2sMessageHandlable } from './s2s-messaging/handlable';
 
+
 const logger = loggerFactory('growi:service:CustomizeService');
 
 
@@ -25,17 +28,26 @@ class CustomizeService implements S2sMessageHandlable {
 
   xssService: any;
 
+  pluginService: IPluginService;
+
   lastLoadedAt?: Date;
 
   customCss?: string;
 
   customTitleTemplate!: string;
 
+  theme: string;
+
+  themeHref: string;
+
+  forcedColorScheme?: ColorScheme;
+
   constructor(crowi) {
     this.configManager = crowi.configManager;
     this.s2sMessagingService = crowi.s2sMessagingService;
     this.appService = crowi.appService;
     this.xssService = crowi.xssService;
+    this.pluginService = crowi.pluginService;
   }
 
   /**
@@ -60,6 +72,7 @@ class CustomizeService implements S2sMessageHandlable {
     await configManager.loadConfigs();
     this.initCustomCss();
     this.initCustomTitle();
+    this.initGrowiTheme();
   }
 
   async publishUpdatedMessage() {
@@ -137,6 +150,33 @@ class CustomizeService implements S2sMessageHandlable {
     return this.xssService.process(customTitle);
   }
 
+  async initGrowiTheme(): Promise<void> {
+    const theme = this.configManager.getConfig('crowi', 'customize:theme');
+
+    this.theme = theme;
+
+    const resultForThemePlugin = await this.pluginService.findThemePlugin(theme);
+
+    if (resultForThemePlugin != null) {
+      this.forcedColorScheme = getForcedColorScheme(resultForThemePlugin.themeMetadata.schemeType);
+      this.themeHref = resultForThemePlugin.themeHref;
+    }
+    // retrieve preset theme
+    else {
+      // import preset-themes manifest
+      const presetThemesManifest = await import('@growi/preset-themes/dist/themes/manifest.json').then(imported => imported.default);
+
+      const themeMetadata = PresetThemesMetadatas.find(p => p.name === theme);
+      this.forcedColorScheme = getForcedColorScheme(themeMetadata?.schemeType);
+
+      const manifestKey = themeMetadata?.manifestKey ?? DefaultThemeMetadata.manifestKey;
+      if (themeMetadata == null || !(themeMetadata.manifestKey in presetThemesManifest)) {
+        logger.warn(`Use default theme because the key for '${theme} does not exist in preset-themes manifest`);
+      }
+      this.themeHref = `/static/preset-themes/${presetThemesManifest[manifestKey].file}`; // configured by express.static
+    }
+
+  }
 
 }
 

+ 18 - 7
packages/app/src/server/service/plugin.ts

@@ -33,9 +33,16 @@ function retrievePluginManifest(growiPlugin: GrowiPlugin): ViteManifest {
   return JSON.parse(manifestStr);
 }
 
+
+type FindThemePluginResult = {
+  growiPlugin: GrowiPlugin,
+  themeMetadata: GrowiThemeMetadata,
+  themeHref: string,
+}
+
 export interface IPluginService {
   install(origin: GrowiPluginOrigin): Promise<string>
-  retrieveThemeHref(theme: string): Promise<string | undefined>
+  findThemePlugin(theme: string): Promise<FindThemePluginResult | null>
   retrieveAllPluginResourceEntries(): Promise<GrowiPluginResourceEntries>
   downloadNotExistPluginRepositories(): Promise<void>
 }
@@ -322,8 +329,7 @@ export class PluginService implements IPluginService {
     return growiPlugins.meta.name;
   }
 
-  async retrieveThemeHref(theme: string): Promise<string | undefined> {
-
+  async findThemePlugin(theme: string): Promise<FindThemePluginResult | null> {
     const GrowiPlugin = mongoose.model('GrowiPlugin') as GrowiPluginModel;
 
     let matchedPlugin: GrowiPlugin | undefined;
@@ -349,15 +355,20 @@ export class PluginService implements IPluginService {
       logger.error(`Could not find the theme '${theme}' from GrowiPlugin documents.`, e);
     }
 
+    if (matchedPlugin == null || matchedThemeMetadata == null) {
+      return null;
+    }
+
+    let themeHref;
     try {
-      if (matchedPlugin != null && matchedThemeMetadata != null) {
-        const manifest = await retrievePluginManifest(matchedPlugin);
-        return `${PLUGINS_STATIC_DIR}/${matchedPlugin.installedPath}/dist/${manifest[matchedThemeMetadata.manifestKey].file}`;
-      }
+      const manifest = retrievePluginManifest(matchedPlugin);
+      themeHref = `${PLUGINS_STATIC_DIR}/${matchedPlugin.installedPath}/dist/${manifest[matchedThemeMetadata.manifestKey].file}`;
     }
     catch (e) {
       logger.error(`Could not read manifest file for the theme '${theme}'`, e);
     }
+
+    return { growiPlugin: matchedPlugin, themeMetadata: matchedThemeMetadata, themeHref };
   }
 
   async retrieveAllPluginResourceEntries(): Promise<GrowiPluginResourceEntries> {

+ 7 - 3
packages/app/src/stores/admin/customize.tsx

@@ -27,7 +27,10 @@ export const useSWRxLayoutSetting = (): SWRResponse<IResLayoutSetting, Error> &
   };
 };
 
-export const useSWRxGrowiThemeSetting = (): SWRResponse<IResGrowiTheme, Error> => {
+type UpdateThemeArgs = {
+  theme: string,
+}
+export const useSWRxGrowiThemeSetting = (): SWRResponse<IResGrowiTheme, Error> & updateConfigMethodForAdmin<UpdateThemeArgs> => {
 
   const fetcher = useCallback(async() => {
     const res = await apiv3Get<IResGrowiTheme>('/customize-setting/theme');
@@ -36,8 +39,9 @@ export const useSWRxGrowiThemeSetting = (): SWRResponse<IResGrowiTheme, Error> =
 
   const swrResponse = useSWR('/customize-setting/theme', fetcher);
 
-  const update = async(theme: string) => {
-    await apiv3Put('/customize-setting/layout', { theme });
+  const update = async({ theme }: UpdateThemeArgs) => {
+
+    await apiv3Put('/customize-setting/theme', { theme });
 
     if (swrResponse.data == null) {
       swrResponse.mutate();

+ 5 - 1
packages/app/src/stores/context.tsx

@@ -1,4 +1,4 @@
-import { IUser } from '@growi/core';
+import type { ColorScheme, IUser } from '@growi/core';
 import { Key, SWRResponse } from 'swr';
 import useSWRImmutable from 'swr/immutable';
 
@@ -209,6 +209,10 @@ export const useIsCustomizedLogoUploaded = (initialData?: boolean): SWRResponse<
   return useStaticSWR('isCustomizedLogoUploaded', initialData);
 };
 
+export const useForcedColorScheme = (initialData?: ColorScheme): SWRResponse<ColorScheme, Error> => {
+  return useContextSWR('forcedColorScheme', initialData);
+};
+
 export const useGrowiCloudUri = (initialData?: string): SWRResponse<string, Error> => {
   return useStaticSWR('growiCloudUri', initialData);
 };

+ 14 - 19
packages/app/src/stores/use-next-themes.tsx

@@ -1,35 +1,30 @@
-import { isClient } from '@growi/core';
+import { isClient, ColorScheme } from '@growi/core';
 import { ThemeProvider, useTheme } from 'next-themes';
 import { ThemeProviderProps, UseThemeProps } from 'next-themes/dist/types';
 
+import { useForcedColorScheme } from './context';
+
 export const Themes = {
-  light: 'light',
-  dark: 'dark',
-  system: 'system',
+  ...ColorScheme,
+  SYSTEM: 'system',
 } as const;
 export type Themes = typeof Themes[keyof typeof Themes];
 
-export const ResolvedThemes = {
-  light: Themes.light,
-  dark: Themes.dark,
-} as const;
-export type ResolvedThemes = typeof ResolvedThemes[keyof typeof ResolvedThemes];
-export const ColorScheme = ResolvedThemes;
-export type ColorScheme = ResolvedThemes;
-
 
 const ATTRIBUTE = 'data-theme';
 
 export const NextThemesProvider: React.FC<ThemeProviderProps> = (props) => {
-  return <ThemeProvider {...props} attribute={ATTRIBUTE} />;
+  const { data: forcedColorScheme } = useForcedColorScheme();
+
+  return <ThemeProvider {...props} forcedTheme={forcedColorScheme} attribute={ATTRIBUTE} />;
 };
 
 type UseThemeExtendedProps = Omit<UseThemeProps, 'theme'|'resolvedTheme'> & {
   theme: Themes,
-  resolvedTheme: ResolvedThemes,
+  resolvedTheme: ColorScheme,
   useOsSettings: boolean,
   isDarkMode: boolean,
-  resolvedThemeByAttributes?: ResolvedThemes,
+  resolvedThemeByAttributes?: ColorScheme,
 }
 
 export const useNextThemes = (): UseThemeProps & UseThemeExtendedProps => {
@@ -37,9 +32,9 @@ export const useNextThemes = (): UseThemeProps & UseThemeExtendedProps => {
 
   return Object.assign(props, {
     theme: props.theme as Themes,
-    resolvedTheme: props.resolvedTheme as ResolvedThemes,
-    useOsSettings: props.theme === Themes.system,
-    isDarkMode: props.resolvedTheme === ResolvedThemes.dark,
-    resolvedThemeByAttributes: isClient() ? document.documentElement.getAttribute(ATTRIBUTE) as ResolvedThemes : undefined,
+    resolvedTheme: props.resolvedTheme as ColorScheme,
+    useOsSettings: props.theme === Themes.SYSTEM,
+    isDarkMode: props.resolvedTheme === ColorScheme.DARK,
+    resolvedThemeByAttributes: isClient() ? document.documentElement.getAttribute(ATTRIBUTE) as ColorScheme : undefined,
   });
 };

+ 0 - 1
packages/app/src/styles/bootstrap/_variables.scss

@@ -90,7 +90,6 @@ $border-radius-lg: 8px;
 // Buttons
 //
 // For each of Bootstrap's buttons, define text, background, and border color.
-$btn-link-disabled-color: $gray-500;
 $btn-focus-box-shadow: none;
 $btn-active-box-shadow: none;
 

+ 469 - 429
packages/app/src/styles/theme/_apply-colors-dark.scss

@@ -2,537 +2,577 @@
 @use '../bootstrap/init' as *;
 @use '../atoms/mixins/buttons' as mixins-buttons;
 @use './mixins/count-badge';
+@use './mixins/hsl-button';
+@use './hsl-functions' as hsl;
 
 // determine optional variables
-$color-list: $color-global !default;
-$bgcolor-list: $bgcolor-global !default;
-$color-list-hover: $color-global !default;
-$bgcolor-list-hover: lighten($bgcolor-global, 8%) !default;
-$color-list-active: $color-reversal !default;
-$bgcolor-list-active: $primary !default;
-$bgcolor-subnav: lighten($bgcolor-global, 3%) !default;
-$color-table: white !default;
-$bgcolor-table: #343a40 !default;
-$border-color-table: lighten($bgcolor-table, 7.5%) !default;
-$color-table-hover: rgba(white, 0.075) !default;
-$bgcolor-table-hover: lighten($bgcolor-table, 7.5%) !default;
-$bgcolor-sidebar-list-group: $bgcolor-list !default;
-$color-tags: #949494 !default;
-$bgcolor-tags: $dark !default;
-$border-color-global: $gray-500 !default;
-$border-color-toc: $border-color-global !default;
-$color-dropdown: $color-global !default;
-$bgcolor-dropdown: $bgcolor-global !default;
-$color-dropdown-link: $color-global !default;
-$color-dropdown-link-hover: $light !default;
-$bgcolor-dropdown-link-hover: lighten($bgcolor-global, 15%) !default;
-$color-dropdown-link-active: $light !default;
-$bgcolor-dropdown-link-active: $primary !default;
-
-// override bootstrap variables
-$text-muted: $gray-550;
-$table-dark-color: $color-table;
-$table-dark-bg: $bgcolor-table;
-$table-dark-border-color: $border-color-table;
-$table-dark-hover-color: $color-table-hover;
-$table-dark-hover-bg: $bgcolor-table-hover;
-$border-color: $border-color-global;
-$dropdown-color: $color-dropdown;
-$dropdown-bg: $bgcolor-dropdown;
-$dropdown-link-color: $color-dropdown-link;
-$dropdown-link-hover-color: $color-dropdown-link-hover;
-$dropdown-link-hover-bg: $bgcolor-dropdown-link-hover;
-$dropdown-link-active-color: $color-dropdown-link-active;
-$dropdown-link-active-bg: $bgcolor-dropdown-link-active;
-
-@import './mixins/list-group';
-@import './reboot-bootstrap-text';
-@import './reboot-bootstrap-border-colors';
-@import './reboot-bootstrap-tables';
-@import './reboot-bootstrap-dropdown';
-
-// List Group
-@include override-list-group-item($color-list, $bgcolor-list, $color-list-hover, $bgcolor-list-hover, $color-list-active, $bgcolor-list-active);
-
-/*
-  * Form
-  */
-input.form-control,
-select.form-control,
-select.custom-select,
-textarea.form-control {
-  color: $color-global;
-  background-color: darken($bgcolor-global, 5%);
-  border-color: $border-color-global;
-  &:focus {
-    background-color: $bgcolor-global;
-  }
-  // FIXME: accent color
-  // border: 1px solid darken($border, 30%);
-}
-
-.form-control[disabled],
-.form-control[readonly] {
-  color: lighten($color-global, 10%);
-  background-color: lighten($bgcolor-global, 5%);
-}
-
-.input-group > .input-group-prepend > .input-group-text {
-  color: theme-color('light');
-  background-color: theme-color('secondary');
-  border: 1px solid theme-color('secondary');
-  border-right: none;
-  &.text-muted {
-    color: theme-color('light') !important;
+:root[data-theme='dark'] {
+  $color-list: var(--color-list,var(--color-global));
+  $bgcolor-list: var(--bgcolor-list,var(--bgcolor-global));
+  $color-list-hover: var(--color-list-hover,var(--color-global));
+  $color-list-active: var(--color-list-active,var(--color-reversal));
+  $bgcolor-list-hover: var(--bgcolor-list-hover,var(--bgcolor-global));
+  $bgcolor-list-active: var(--bgcolor-list-active,var(--primary));
+  $bgcolor-subnav: var(--bgcolor-subnav);
+  $color-table: var(--color-table,white);
+  $bgcolor-table: var(--bgcolor-table,#343a40);
+  $border-color-table: var(--border-color-table,hsl.lighten(var(--bgcolor-table),7.5%),lighten(#343a40, 7.5%));
+  $color-table-hover: var(--color-table-hover,rgba(white, 0.075));
+  $bgcolor-table-hover: var(--bgcolor-table-hover,hsl.lighten(var(--bgcolor-table),7.5%),lighten(#343a40, 7.5%));
+  $bgcolor-sidebar-list-group: var(--bgcolor-sidebar-list-group,var(--bgcolor-list));
+  $color-tags: var(--color-tags,#949494);
+  $bgcolor-tags: var(--bgcolor-tags,var(--dark));
+  $border-color-global: var(--border-color-global,#{$gray-500});
+  $border-color-toc: var(--border-color-toc,#{$border-color-global});
+  $color-dropdown: var(--color-dropdown,var(--color-global));
+  $bgcolor-dropdown: var(--bgcolor-dropdown,var(--bgcolor-global));
+  $color-dropdown-link: var(--color-dropdown-link,var(--color-global));
+  $color-dropdown-link-hover: var(--color-dropdown-link-hover,var(--light));
+  $bgcolor-dropdown-link-hover: var(--bgcolor-dropdown-link-hover,var(--primary));
+  $color-dropdown-link-active: var(--color-dropdown-link-active,var(--light));
+  $bgcolor-dropdown-link-active: var(--bgcolor-dropdown-link-active,var(--primary));
+
+  // override bootstrap variables
+  $text-muted: $gray-550;
+  $table-dark-color: $color-table;
+  $table-dark-bg: $bgcolor-table;
+  $table-dark-border-color: $border-color-table;
+  $table-dark-hover-color: $color-table-hover;
+  $table-dark-hover-bg: $bgcolor-table-hover;
+  $border-color: $border-color-global;
+  $dropdown-color: $color-dropdown;
+  $dropdown-bg: $bgcolor-dropdown;
+  $dropdown-link-color: $color-dropdown-link;
+  $dropdown-link-hover-color: $color-dropdown-link-hover;
+  $dropdown-link-hover-bg: $bgcolor-dropdown-link-hover;
+  $dropdown-link-active-color: $color-dropdown-link-active;
+  $dropdown-link-active-bg: $bgcolor-dropdown-link-active;
+
+  @import './mixins/list-group';
+  @import './reboot-bootstrap-text';
+  @import './reboot-bootstrap-border-colors';
+  @import './reboot-bootstrap-tables';
+  @import './reboot-bootstrap-theme-colors';
+  @import 'hsl-reboot-bootstrap-theme-colors';
+  @import './reboot-bootstrap-dropdown';
+
+  // List Group
+  @include override-list-group-item(
+    $color-list,
+    $bgcolor-sidebar-list-group,
+    $color-list-hover,
+    $bgcolor-list-hover,
+    $color-list-active,
+    $bgcolor-list-active
+  );
+  /*
+    * Form
+    */
+  input.form-control,
+  select.form-control,
+  select.custom-select,
+  textarea.form-control {
+    color: var(--color-global);
+    background-color: hsl.darken(var(--bgcolor-global), 5%);
+    border-color: $border-color-global;
+    &:focus {
+      background-color: var(--bgcolor-global);
+    }
+    // FIXME: accent color
+    // border: 1px solid darken($border, 30%);
   }
-}
-
-.input-group input {
-  border-color: $border-color-global;
-}
 
-label.custom-control-label::before {
-  background-color: darken($bgcolor-global, 5%);
-}
+  .form-control[disabled],
+  .form-control[readonly] {
+    color: hsl.lighten(var(--color-global),10%);
+    background-color: hsl.lighten(var(--bgcolor-global),5%);
+  }
 
-/*
- * Table
- */
-.table {
-  @extend .table-dark;
-}
+  .input-group > .input-group-prepend > .input-group-text {
+    color: theme-color('light');
+    background-color: theme-color('secondary');
+    border: 1px solid theme-color('secondary');
+    border-right: none;
+    &.text-muted {
+      color: theme-color('light') !important;
+    }
+  }
 
-/*
- * Card
- */
-.card:not([class*='bg-']):not(.well):not(.card-disabled) {
-  @extend .bg-dark;
-}
+  .input-group input {
+    border-color: $border-color-global;
+  }
 
-// [TODO] GW-3219 modify common color of well in dark theme, then remove below css.
-.card.well {
-  border-color: $secondary;
-}
+  label.custom-control-label::before {
+    background-color: hsl.darken(var(--bgcolor-global),5%);
+  }
 
-.card.card-disabled {
-  background-color: lighten($dark, 10%);
-  border-color: $secondary;
-}
+  /*
+  * Table
+  */
+  .table {
+    @extend .table-dark;
+  }
 
-/*
- * Pagination
- */
-ul.pagination {
-  li.page-item {
-    button.page-link {
-      @extend .btn-dark;
-    }
+  /*
+  * Card
+  */
+  .card:not([class*=‘bg-’]):not(.well):not(.card-disabled) {
+    @extend .bg-dark;
   }
-}
 
-/*
- * GROWI Login form
- */
-.nologin {
-  // background color
-  $color-gradient: #3c465c;
-  background: linear-gradient(45deg, darken($color-gradient, 30%) 0%, hsla(340, 100%, 55%, 0) 70%),
-    linear-gradient(135deg, darken(var.$growi-green, 30%) 10%, hsla(225, 95%, 50%, 0) 70%),
-    linear-gradient(225deg, darken(var.$growi-blue, 20%) 10%, hsla(140, 90%, 50%, 0) 80%),
-    linear-gradient(315deg, darken($color-gradient, 25%) 100%, hsla(35, 95%, 55%, 0) 70%);
+  // [TODO] GW-3219 modify common color of well in dark theme, then remove below css.
+  .card.well {
+    border-color: var(--secondary);
+  }
 
-  .nologin-header {
-    background-color: rgba(black, 0.5);
+  .card.card-disabled {
+    background-color: lighten($dark, 10%);
+    border-color: var(--secondary);
+  }
 
-    .logo {
-      background-color: rgba(white, 0);
-      fill: rgba(white, 0.5);
+  /*
+  * Pagination
+  */
+  ul.pagination {
+    li.page-item.disabled {
+      button.page-link {
+        color: $gray-400;
+      }
     }
-
-    h1 {
-      color: rgba(white, 0.5);
+    li.page-item.active {
+      button.page-link {
+        color: hsl.contrast(var(--primary));
+        background-color: var(--primary);
+        &:hover,
+        &:focus {
+          color: hsl.contrast(var(--primary));
+          background-color: var(--primary);
+        }
+      }
+    }
+    li.page-item {
+      button.page-link {
+        @extend .btn-dark;
+        color: var(--primary);
+      }
     }
   }
 
-  .nologin-dialog {
-    background-color: rgba(black, 0.5);
-  }
+  /*
+  * GROWI Login form
+  */
+  .nologin {
+    // background color
+    $color-gradient: #3c465c;
+    background: linear-gradient(45deg, darken($color-gradient, 30%) 0%, hsla(340, 100%, 55%, 0) 70%),
+      linear-gradient(135deg, darken(var.$growi-green, 30%) 10%, hsla(225, 95%, 50%, 0) 70%),
+      linear-gradient(225deg, darken(var.$growi-blue, 20%) 10%, hsla(140, 90%, 50%, 0) 80%),
+      linear-gradient(315deg, darken($color-gradient, 25%) 100%, hsla(35, 95%, 55%, 0) 70%);
+
+    .nologin-header {
+      background-color: rgba(black, 0.5);
+
+      .logo {
+        background-color: rgba(white, 0);
+        fill: rgba(white, 0.5);
+      }
 
-  .input-group {
-    .input-group-text {
-      color: darken(white, 30%);
-      background-color: rgba($gray-700, 0.7);
+      h1 {
+        color: rgba(white, 0.5);
+      }
     }
 
-    .form-control {
-      color: white;
-      background-color: rgba(#505050, 0.7);
-      box-shadow: unset;
+    .nologin-dialog {
+      background-color: rgba(black, 0.5);
+    }
 
-      &::placeholder {
+    .input-group {
+      .input-group-text {
         color: darken(white, 30%);
+        background-color: rgba($gray-700, 0.7);
       }
-    }
-  }
 
-  .btn-fill {
-    .btn-label {
-      color: $gray-300;
+      .form-control {
+        color: white;
+        background-color: rgba(#505050, 0.7);
+        box-shadow: unset;
+
+        &::placeholder {
+          color: darken(white, 30%);
+        }
+      }
     }
-    .btn-label-text {
-      color: $gray-400;
+
+    .btn-fill {
+      .btn-label {
+        color: $gray-300;
+      }
+      .btn-label-text {
+        color: $gray-400;
+      }
     }
-  }
 
-  .grw-external-auth-form {
-    border-color: gray !important;
-  }
+    .grw-external-auth-form {
+      border-color: gray !important;
+    }
 
-  .btn-external-auth-tab {
-    @extend .btn-dark;
-  }
+    .btn-external-auth-tab {
+      @extend .btn-dark;
+    }
 
-  // footer link text
-  .link-growi-org {
-    color: rgba(white, 0.4);
+    // footer link text
+    .link-growi-org {
+      color: rgba(white, 0.4);
 
-    &:hover,
-    &.focus {
-      color: rgba(white, 0.7);
+      &:hover,
+      &.focus {
+        color: rgba(white, 0.7);
 
-      .growi {
-        color: darken(var.$growi-green, 5%);
-      }
+        .growi {
+          color: darken(var.$growi-green, 5%);
+        }
 
-      .org {
-        color: darken(var.$growi-blue, 5%);
+        .org {
+          color: darken(var.$growi-blue, 5%);
+        }
       }
     }
   }
-}
 
-/*
- * GROWI subnavigation
- */
-.grw-drawer-toggler {
-  @extend .btn-dark;
-  color: $gray-400;
-}
+  /*
+  * GROWI subnavigation
+  */
+  .grw-drawer-toggler {
+    @include button-variant($dark, $dark);
+    @include mixins-buttons.button-svg-icon-variant($dark, $dark);
+    color: $gray-400;
+    box-shadow: none !important;
 
-/*
- * GROWI page list
- */
-.page-list {
-  .page-list-ul {
-    > li {
-      > span.page-list-meta {
-        color: darken($color-global, 10%);
-      }
-    }
   }
 
-  // List group
-  .list-group-item {
-    &.active {
-      background-color: lighten($bgcolor-global, 9%) !important;
-    }
-    .list-group-item-action:hover {
-      background-color: $bgcolor-list-hover;
+  /*
+  * GROWI page list
+  */
+  .page-list {
+    .page-list-ul {
+      > li {
+        > span.page-list-meta {
+          color: hsl.darken(var(--color-global),10%);
+        }
+      }
     }
-    .page-list-snippet {
-      color: darken($body-color, 10%);
+
+    // List group
+    .list-group-item {
+      &.active {
+        background-color: hsl.lighten(var(--bgcolor-global),10%) !important;
+      }
+      &.list-group-item-action:hover {
+        background-color: hsl.lighten(var(--bgcolor-global),10%) !important;
+      }
+      .page-list-snippet {
+        color: hsl.darken(var(--color-global),10%);
+      }
     }
   }
-}
 
-/*
- * GROWI ToC
- */
-.revision-toc-content {
-  ::marker {
-    color: lighten($bgcolor-global, 30%);
+  /*
+  * GROWI ToC
+  */
+  .revision-toc-content {
+    ::marker {
+      color: hsl.lighten(var(--color-global),30%);
+    }
   }
-}
 
-/*
- * GROWI subnavigation
- */
-.grw-subnav {
-  background-color: $bgcolor-subnav;
-}
+  /*
+  * GROWI subnavigation
+  */
+  .grw-subnav {
+    background-color: var(--bgcolor-subnav);
+  }
 
-.grw-subnav-fixed-container .grw-subnav {
-  background-color: rgba($bgcolor-subnav, 0.85);
-}
+  .grw-subnav-fixed-container .grw-subnav {
+    background-color: hsl.alpha(var(--bgcolor-subnav),85%);
+  }
 
-.grw-page-editor-mode-manager {
-  .btn-outline-primary {
-    &:hover {
-      color: $primary;
-      background-color: $gray-700;
+  .grw-page-editor-mode-manager {
+    .btn-outline-primary {
+      &:hover {
+        color: var(--primary);
+        background-color: $gray-700;
+      }
     }
   }
-}
 
-// Search drop down
-#search-typeahead-asynctypeahead {
-  background-color: $bgcolor-global;
-  .table {
-    background-color: transparent;
+  // Search drop down
+  #search-typeahead-asynctypeahead {
+    background-color: var(--bgcolor-global);
+    .table {
+      background-color: transparent;
+    }
   }
-}
 
-/*
- * GROWI Sidebar
- */
-.grw-sidebar {
-  // List
-  @include override-list-group-item($color-list, $bgcolor-sidebar-list-group, $color-list-hover, $bgcolor-list-hover, $color-list-active, $bgcolor-list-active);
-
-  // Pagetree
-  .grw-pagetree {
-    @include override-list-group-item-for-pagetree(
-      $color-sidebar-context,
-      lighten($bgcolor-sidebar-context, 8%),
-      lighten($bgcolor-sidebar-context, 15%),
-      darken($color-sidebar-context, 15%),
-      darken($color-sidebar-context, 10%),
-      lighten($bgcolor-sidebar-context, 18%),
-      lighten($bgcolor-sidebar-context, 24%)
+  /*
+  * GROWI Sidebar
+  */
+  .grw-sidebar {
+    --gray-500: hsl(var(--gray-500-hs),var(--gray-500-l));
+    --gray-500-hs: 210,13%;
+    --gray-500-l: 61%;
+    // List
+    @include override-list-group-item(
+      $color-list,
+      $bgcolor-sidebar-list-group,
+      $color-list-hover,
+      $bgcolor-list-hover,
+      $color-list-active,
+      $bgcolor-list-active
     );
-    .grw-pagetree-triangle-btn {
-      @include mixins-buttons.button-outline-svg-icon-variant($secondary, $gray-200);
-    }
-    .btn-page-item-control {
-      @include button-outline-variant($gray-500, $gray-500, $secondary, transparent);
-      @include hover() {
-        background-color: lighten($bgcolor-sidebar-context, 20%);
+    // Pagetree
+    .grw-pagetree {
+      @include override-list-group-item-for-pagetree(
+        var(--color-sidebar-context),
+        hsl.lighten(var(--bgcolor-sidebar-context),8%),
+        hsl.lighten(var(--bgcolor-sidebar-context),15%),
+        hsl.darken(var(--color-sidebar-context),15%),
+        hsl.darken(var(--color-sidebar-context),10%),
+        hsl.lighten(var(--bgcolor-sidebar-context),18%),
+        hsl.lighten(var(--bgcolor-sidebar-context),24%)
+      );
+      .grw-pagetree-triangle-btn {
+        @include mixins-buttons.button-outline-svg-icon-variant(var(--secondary), $gray-200);
       }
-      &:not(:disabled):not(.disabled):active,
-      &:not(:disabled):not(.disabled).active {
-        background-color: lighten($bgcolor-sidebar-context, 34%);
+      .btn-page-item-control {
+        @include hsl-button.button-outline-variant(var(--gray-500), var(--gray-500), var(--secondary), transparent);
+        @include hover() {
+          background-color: hsl.lighten(var(--bgcolor-sidebar-context),20%);
+        }
+        &:not(:disabled):not(.disabled):active,
+        &:not(:disabled):not(.disabled).active {
+          background-color: hsl.lighten(var(--bgcolor-sidebar-context),34%);
+        }
+        box-shadow: none !important;
       }
-      box-shadow: none !important;
     }
-  }
-  .private-legacy-pages-link {
-    &:hover {
-      background: $bgcolor-list-hover;
+    .private-legacy-pages-link {
+      &:hover {
+        background: var(--bgcolor-list-hover);
+      }
     }
   }
-}
 
-.btn.btn-page-item-control {
-  @include button-outline-variant($gray-500, $gray-500, $secondary, transparent);
-  @include hover() {
-    background-color: $gray-700;
-  }
-  &:not(:disabled):not(.disabled):active,
-  &:not(:disabled):not(.disabled).active {
-    color: $gray-200;
-    background-color: $gray-600;
-  }
-  box-shadow: none !important;
-}
-
-/*
- * Popover
- */
-.popover {
-  background-color: $bgcolor-global;
-  border-color: $secondary;
-  .popover-header {
-    color: $white;
-    background-color: $secondary;
-    border-color: $secondary;
-  }
-  .popover-body {
-    color: inherit;
+  .btn.btn-page-item-control {
+    @include hsl-button.button-outline-variant(var(--gray-500), var(--gray-500), var(--secondary), transparent);
+    @include hover() {
+      background-color: $gray-700;
+    }
+    &:not(:disabled):not(.disabled):active,
+    &:not(:disabled):not(.disabled).active {
+      color: $gray-200;
+      background-color: $gray-600;
+    }
+    box-shadow: none !important;
   }
 
-  &.bs-popover-top .arrow {
-    &::before {
-      border-top-color: $secondary;
+  /*
+  * Popover
+  */
+  .popover {
+    background-color: var(--bgcolor-global);
+    border-color: var(--secondary);
+    .popover-header {
+      color: white;
+      background-color: var(--secondary);
+      border-color: var(--secondary);
     }
-
-    &::after {
-      border-top-color: $bgcolor-global;
+    .popover-body {
+      color: inherit;
     }
-  }
-  &.bs-popover-bottom .arrow {
-    &::before {
-      border-bottom-color: $secondary;
+
+    &.bs-popover-top .arrow {
+      &::before {
+        border-top-color: var(--secondary);
+      }
+
+      &::after {
+        border-top-color: var(--bgcolor-global);
+      }
     }
+    &.bs-popover-bottom .arrow {
+      &::before {
+        border-bottom-color: var(--secondary);
+      }
 
-    &::after {
-      border-bottom-color: $bgcolor-global;
+      &::after {
+        border-bottom-color: var(--bgcolor-global);
+      }
     }
-  }
-  &.bs-popover-right .arrow {
-    &::before {
-      border-right-color: $secondary;
+    &.bs-popover-right .arrow {
+      &::before {
+        border-right-color: var(--secondary);
+      }
+
+      &::after {
+        border-right-color: var(--bgcolor-global);
+      }
     }
+    &.bs-popover-left .arrow {
+      &::before {
+        border-left-color: var(--secondary);
+      }
 
-    &::after {
-      border-right-color: $bgcolor-global;
+      &::after {
+        border-left-color: var(--bgcolor-global);
+      }
     }
   }
-  &.bs-popover-left .arrow {
-    &::before {
-      border-left-color: $secondary;
-    }
 
-    &::after {
-      border-left-color: $bgcolor-global;
-    }
+  /*
+  * GROWI Grid Edit Modal
+  */
+  .grw-grid-edit-preview {
+    background: $gray-900;
   }
-}
 
-/*
- * GROWI Grid Edit Modal
- */
-.grw-grid-edit-preview {
-  background: $gray-900;
-}
+  /*
+  * Slack
+  */
+  .grw-slack-notification {
+    background-color: transparent;
+    $color-slack: #4b144c;
 
-/*
- * Slack
- */
-.grw-slack-notification {
-  background-color: transparent;
-  $color-slack: #4b144c;
+    .form-control {
+      background: var(--bgcolor-global);
+    }
 
-  .form-control {
-    background: $bgcolor-global;
-  }
+    .custom-control-label {
+      &::before {
+        background-color: var(--secondary);
+        border-color: transparent;
+      }
+      &::after {
+        background-color: darken($color-slack, 5%);
+        background-image: url(/images/icons/slack/slack-logo-dark-off.svg);
+      }
+    }
 
-  .custom-control-label {
-    &::before {
-      background-color: $secondary;
-      border-color: transparent;
+    .custom-control-input:checked ~ .custom-control-label {
+      &::before {
+        background-color: lighten($color-slack, 10%);
+      }
+      &::after {
+        background-color: darken($color-slack, 5%);
+        background-image: url(/images/icons/slack/slack-logo-dark-on.svg);
+      }
     }
-    &::after {
-      background-color: darken($color-slack, 5%);
-      background-image: url(/images/icons/slack/slack-logo-dark-off.svg);
+    .grw-slack-logo svg {
+      fill: #dd80de;
     }
-  }
 
-  .custom-control-input:checked ~ .custom-control-label {
-    &::before {
-      background-color: lighten($color-slack, 10%);
+    .grw-btn-slack {
+      background-color: black;
+      &:focus,
+      &:hover {
+        background-color: black;
+      }
     }
-    &::after {
-      background-color: darken($color-slack, 5%);
-      background-image: url(/images/icons/slack/slack-logo-dark-on.svg);
+
+    .grw-btn-slack-triangle {
+      color: var(--secondary);
     }
   }
-  .grw-slack-logo svg {
-    fill: #dd80de;
+
+  /*
+  * GROWI HandsontableModal
+  */
+  .grw-hot-modal-navbar {
+    background-color: var(--dark);
   }
 
-  .grw-btn-slack {
-    background-color: black;
-    &:focus,
-    &:hover {
-      background-color: black;
+  .wiki {
+    h1 {
+      border-color: hsl.lighten(var(--border-color-theme),10%);
+    }
+    h2 {
+      border-color: var(--border-color-theme);
     }
   }
 
-  .grw-btn-slack-triangle {
-    color: $secondary;
+  /*
+  * GROWI comment form
+  */
+  .comment-form {
+    #slack-mark-black {
+      display: none;
+    }
   }
-}
 
-/*
- * GROWI HandsontableModal
- */
-.grw-hot-modal-navbar {
-  background-color: $dark;
-}
-
-.wiki {
-  h1 {
-    border-color: lighten($border-color-theme, 10%);
-  }
-  h2 {
-    border-color: $border-color-theme;
+  .page-comments-row {
+    background: var(--bgcolor-subnav);
   }
-}
 
-/*
- * GROWI comment form
- */
-.comment-form {
-  #slack-mark-black {
-    display: none;
+  /*
+  * GROWI tags
+  */
+  .grw-tag-labels {
+    .grw-tag-label {
+      color: $color-tags;
+      background-color: $bgcolor-tags;
+    }
   }
-}
-
-.page-comments-row {
-  background: $bgcolor-subnav;
-}
 
-/*
- * GROWI tags
- */
-.grw-tag-labels {
-  .grw-tag-label {
-    color: $color-tags;
-    background-color: $bgcolor-tags;
+  /*
+  * GROWI popular tags
+  */
+  .grw-popular-tag-labels {
+    .grw-tag-label {
+      color: $color-tags;
+      background-color: $bgcolor-tags;
+    }
   }
-}
 
-/*
- * GROWI popular tags
- */
-.grw-popular-tag-labels {
-  .grw-tag-label {
-    color: $color-tags;
-    background-color: $bgcolor-tags;
+  /*
+  * admin settings
+  */
+  .admin-setting-header {
+    border-color: $border-color-global;
   }
-}
 
-/*
- * admin settings
- */
-.admin-setting-header {
-  border-color: $border-color-global;
-}
+  /*
+  * grw-side-contents
+  */
+  .grw-side-contents-sticky-container {
+    .grw-count-badge {
+      @include count-badge.count-badge($gray-400, $gray-700);
+    }
 
-/*
-* grw-side-contents
-*/
-.grw-side-contents-sticky-container {
-  .grw-count-badge {
-    @include count-badge.count-badge($gray-400, $gray-700);
-  }
+    .grw-border-vr {
+      border-color: $border-color-toc;
+    }
 
-  .grw-border-vr {
-    border-color: $border-color-toc;
+    .revision-toc {
+      border-color: $border-color-toc;
+    }
   }
 
-  .revision-toc {
-    border-color: $border-color-toc;
+  /*
+  * drawio
+  */
+  .drawio-viewer {
+    border-color: $border-color-global;
   }
-}
-
-/*
- * drawio
- */
-.drawio-viewer {
-  border-color: $border-color-global;
-}
 
-/*
- * modal
- */
-.grw-modal-head {
-  border-color: $border-color-global;
-}
+  /*
+  * modal
+  */
+  .grw-modal-head {
+    border-color: $border-color-global;
+  }
 
-/*
- * skeleton
- */
-.grw-skeleton {
-  background-color: lighten($bgcolor-subnav, 15%);
+  /*
+  * skeleton
+  */
+  .grw-skeleton {
+  }
 }

+ 376 - 342
packages/app/src/styles/theme/_apply-colors-light.scss

@@ -2,429 +2,463 @@
 @use '../bootstrap/init' as *;
 @use '../atoms/mixins/buttons' as mixins-buttons;
 @use './mixins/count-badge';
+@use './mixins/hsl-button';
+@use './hsl-functions' as hsl;
 
 // determine optional variables
-$color-list: $color-global !default;
-$bgcolor-list: $bgcolor-global !default;
-$color-list-hover: $color-global !default;
-$bgcolor-list-hover: lighten($primary, 72%) !default;
-$bgcolor-list-active: lighten($primary, 65%) !default;
-$color-list-active: color-yiq($bgcolor-list-active) !default;
-$color-table: $color-global !default;
-$bgcolor-table: null !default;
-$border-color-table: $gray-200 !default;
-$color-table-hover: $color-table !default;
-$bgcolor-table-hover: rgba(black, 0.075) !default;
-$bgcolor-sidebar-list-group: $bgcolor-list !default;
-$color-tags: $secondary !default;
-$bgcolor-tags: $gray-200 !default;
-$border-color-global: $gray-300 !default;
-$border-color-toc: $border-color-global !default;
-$color-dropdown: $color-global !default;
-$color-dropdown-link: $color-global !default;
-$color-dropdown-link-hover: $color-global !default;
-$color-dropdown-link-active: $color-reversal !default;
-$bgcolor-dropdown-link-active: $primary !default;
-
-// override bootstrap variables
-$text-muted: $gray-500;
-$table-color: $color-table;
-$table-bg: $bgcolor-table;
-$table-border-color: $border-color-table;
-$table-hover-color: $color-table-hover;
-$table-hover-bg: $bgcolor-table-hover;
-$border-color: $border-color-global;
-$dropdown-color: $color-dropdown;
-$dropdown-link-color: $color-dropdown-link;
-$dropdown-link-hover-color: $color-dropdown-link-hover;
-$dropdown-link-active-color: $color-dropdown-link-active;
-$dropdown-link-active-bg: $bgcolor-dropdown-link-active;
-
-@import './mixins/list-group';
-@import './reboot-bootstrap-text';
-@import './reboot-bootstrap-border-colors';
-@import './reboot-bootstrap-tables';
-@import './reboot-bootstrap-dropdown';
-
-// List Group
-@include override-list-group-item($color-list, $bgcolor-list, $color-list-hover, $bgcolor-list-hover, $color-list-active, $bgcolor-list-active);
-
-/*
- * Form
- */
-.form-control {
-  background-color: $bgcolor-global;
-}
+:root[data-theme='light'] {
+  $color-list: var(--color-list,var(--color-global));
+  $bgcolor-list: var(--bgcolor-list,var(--bgcolor-global));
+  $color-list-hover: var(--color-list-hover,var(--color-global));
+  $bgcolor-list-hover: var(--bgcolor-list-hover, var(--bgcolor-global));
+  $bgcolor-list-active: var(--bgcolor-list-active, hsl.lighten(var(--primary),65%));
+  $color-list-active: var(--color-list-active,hsl(var(--primary-hs), clamp(10%, (100% - var(--primary-l)  - 65% - 51%) * 1000, 95%)));
+  $color-table: var(--color-table,var(--color-global));
+  $bgcolor-table: var(--bgcolor-table,null);
+  $border-color-table: var(--border-color-table,#{$gray-200});
+  $color-table-hover: var(--color-table-hover,var(--color-table));
+  $bgcolor-table-hover: var(--bgcolor-table-hover,rgba(black, 0.075));
+  $bgcolor-sidebar-list-group: var(--bgcolor-sidebar-list-group,var(--bgcolor-list));
+  $color-tags: var(--color-tags,var(--secondary));
+  $bgcolor-tags: var(--bgcolor-tags,#{$gray-200});
+  $border-color-global: var(--border-color-global,#{$gray-300});
+  $border-color-toc: var(--border-color-toc,#{$gray-300});
+  $color-dropdown: var(--color-dropdown,var(--color-global));
+  $bgcolor-dropdown: var(--color-dropdown,var(--bgcolor-global));
+  $color-dropdown-link: var(--color-dropdown-link,var(--color-global));
+  $color-dropdown-link-hover: var(--color-dropdown-link-hover,var(--color-global));
+  $color-dropdown-link-active: var(--color-dropdown-link-active,var(--color-reversal));
+  $bgcolor-dropdown-link-hover: hsl.darken(var(--bgcolor-global),15%);
+  $bgcolor-dropdown-link-active: var(--bgcolor-dropdown-link-active,var(--primary));
+
+  // override bootstrap variables
+  $text-muted: $gray-500;
+  $table-color: $color-table;
+  $table-bg: $bgcolor-table;
+  $table-border-color: $border-color-table;
+  $table-hover-color: $color-table-hover;
+  $table-hover-bg: $bgcolor-table-hover;
+  $border-color: $border-color-global;
+  $dropdown-color: $color-dropdown;
+  $dropdown-link-color: $color-dropdown-link;
+  $dropdown-link-hover-color: $color-dropdown-link-hover;
+  $dropdown-link-hover-bg: $bgcolor-dropdown-link-hover;
+  $dropdown-link-active-color: $color-dropdown-link-active;
+  $dropdown-link-active-bg: $bgcolor-dropdown-link-active;
+
+  @import './mixins/list-group';
+  @import './reboot-bootstrap-text';
+  @import './reboot-bootstrap-border-colors';
+  @import './reboot-bootstrap-tables';
+  @import './reboot-bootstrap-theme-colors';
+  @import 'hsl-reboot-bootstrap-theme-colors';
+  @import './reboot-bootstrap-dropdown';
+
+  // List Group
+  @include override-list-group-item(
+    $color-list,
+    $bgcolor-sidebar-list-group,
+    $color-list-hover,
+    $bgcolor-list-hover,
+    $color-list-active,
+    $bgcolor-list-active
+  );
+  /*
+  * Form
+  */
+  .form-control {
+    background-color: var(--bgcolor-global);
+  }
 
-.form-control::placeholder {
-  color: darken($bgcolor-global, 20%);
-}
+  .form-control::placeholder {
+    color: hsl.darken(var(--bgcolor-global), 20%);
+  }
 
-.form-control[disabled],
-.form-control[readonly] {
-  color: lighten($color-global, 10%);
-  background-color: darken($bgcolor-global, 5%);
-}
+  .form-control[disabled],
+  .form-control[readonly] {
+    color: hsl.lighten(var(--color-global),10%);
+    background-color: hsl.darken(var(--bgcolor-global),5%);
+  }
 
-/*
- * card
- */
-.card.card-disabled {
-  background-color: darken($bgcolor-card, 5%);
-  border-color: $gray-200;
-}
+  /*
+  * card
+  */
+  .card.card-disabled {
+    background-color: var(--background-color);
+    border-color: $gray-200;
+  }
 
-/*
- * GROWI Login form
- */
-.nologin {
-  // background color
-  $color-gradient: #3e4d6c;
-  background: linear-gradient(45deg, darken($color-gradient, 30%) 0%, hsla(340, 100%, 55%, 0) 70%),
-    linear-gradient(135deg, var.$growi-green 10%, hsla(225, 95%, 50%, 0) 70%), linear-gradient(225deg, var.$growi-blue 10%, hsla(140, 90%, 50%, 0) 80%),
-    linear-gradient(315deg, darken($color-gradient, 25%) 100%, hsla(35, 95%, 55%, 0) 70%);
+  /*
+  * GROWI Login form
+  */
+  .nologin {
+    // background color
+    $color-gradient: #3c465c;
+    background: linear-gradient(45deg, darken($color-gradient, 30%) 0%, hsla(340, 100%, 55%, 0) 70%),
+      linear-gradient(135deg, var.$growi-green 10%, hsla(225, 95%, 50%, 0) 70%), linear-gradient(225deg, var.$growi-blue 10%, hsla(140, 90%, 50%, 0) 80%),
+      linear-gradient(315deg, darken($color-gradient, 25%) 100%, hsla(35, 95%, 55%, 0) 70%);
 
-  .nologin-header {
-    background-color: rgba(white, 0.5);
+    .nologin-header {
+      background-color: rgba(white, 0.5);
 
-    .logo {
-      background-color: rgba(black, 0);
-      fill: rgba(black, 0.5);
-    }
+      .logo {
+        background-color: rgba(black, 0);
+        fill: rgba(black, 0.5);
+      }
 
-    h1 {
-      color: rgba(black, 0.5);
+      h1 {
+        color: rgba(black, 0.5);
+      }
     }
-  }
 
-  .nologin-dialog {
-    background-color: rgba(white, 0.5);
-  }
+    .nologin-dialog {
+      background-color: rgba(white, 0.5);
+    }
 
-  .dropdown-with-icon {
-    .dropdown-toggle {
-      color: white;
-      background-color: rgba($gray-600, 0.7);
-      box-shadow: unset;
-      &:focus {
+    .dropdown-with-icon {
+      .dropdown-toggle {
         color: white;
         background-color: rgba($gray-600, 0.7);
+        box-shadow: unset;
+        &:focus {
+          color: white;
+          background-color: rgba($gray-600, 0.7);
+        }
+      }
+      i {
+        color: darken(white, 30%);
+        background-color: rgba($gray-700, 0.7);
       }
     }
-    i {
-      color: darken(white, 30%);
-      background-color: rgba($gray-700, 0.7);
-    }
-  }
 
-  .input-group {
-    .input-group-text {
-      color: darken(white, 30%);
-      background-color: rgba($gray-700, 0.7);
-    }
+    .input-group {
+      .input-group-text {
+        color: darken(white, 30%);
+        background-color: rgba($gray-700, 0.7);
+      }
 
-    .form-control {
-      color: white;
-      background-color: rgba($gray-600, 0.7);
-      box-shadow: unset;
+      .form-control {
+        color: white;
+        background-color: rgba($gray-600, 0.7);
+        box-shadow: unset;
 
-      &::placeholder {
-        color: darken(white, 30%);
+        &::placeholder {
+          color: darken(white, 30%);
+        }
       }
     }
-  }
 
-  // footer link text
-  .link-growi-org {
-    color: rgba(black, 0.4);
+    // footer link text
+    .link-growi-org {
+      color: rgba(black, 0.4);
 
-    &:hover,
-    &.focus {
-      color: black;
+      &:hover,
+      &.focus {
+        color: black;
 
-      .growi {
-        color: darken(var.$growi-green, 20%);
-      }
+        .growi {
+          color: darken(var.$growi-green, 20%);
+        }
 
-      .org {
-        color: darken(var.$growi-blue, 15%);
+        .org {
+          color: darken(var.$growi-blue, 15%);
+        }
       }
     }
   }
-}
 
-/*
- * GROWI subnavigation
- */
-.grw-subnav {
-  background-color: $bgcolor-subnav;
-}
+  /*
+  * GROWI subnavigation
+  */
+  .grw-subnav {
+    background-color: var(--bgcolor-subnav);
+  }
 
-.grw-subnav-fixed-container .grw-subnav {
-  background-color: rgba($bgcolor-subnav, 0.85);
-}
+  .grw-subnav-fixed-container .grw-subnav {
+    background-color: hsl.alpha(var(--bgcolor-subnav),85%);
+  }
 
-.grw-page-editor-mode-manager {
-  .btn-outline-primary {
-    &:hover {
-      color: $primary;
-      background-color: $gray-200;
+  .grw-page-editor-mode-manager {
+    .btn-outline-primary {
+      &:hover {
+        color: var(--primary);
+        background-color: $gray-200;
+      }
     }
   }
-}
 
-.grw-drawer-toggler {
-  @extend .btn-light;
-  color: $gray-500;
-}
-
-/*
- * GROWI Sidebar
- */
-.grw-sidebar {
-  // List
-  @include override-list-group-item($color-list, $bgcolor-sidebar-list-group, $color-list-hover, $bgcolor-list-hover, $color-list-active, $bgcolor-list-active);
-  // sidebar-centent-bg
-  .grw-navigation-wrap {
-    // Drop a shadow on the light theme. The dark theme makes '$ bgcolor-sidebar-context' brighter than the body.
-    box-shadow: 0px 0px 3px rgba(black, 0.24);
-  }
-  // Pagetree
-  .grw-pagetree {
-    @include override-list-group-item-for-pagetree(
-      $color-sidebar-context,
-      darken($bgcolor-sidebar-context, 5%),
-      darken($bgcolor-sidebar-context, 12%),
-      lighten($color-sidebar-context, 10%),
-      lighten($color-sidebar-context, 8%),
-      darken($bgcolor-sidebar-context, 15%),
-      darken($bgcolor-sidebar-context, 24%)
+  .grw-drawer-toggler {
+    @include button-variant($light, $light);
+    @include mixins-buttons.button-svg-icon-variant($light, $light);
+    color: $gray-500;
+    box-shadow: none !important;
+  }
+
+  /*
+  * GROWI Sidebar
+  */
+  .grw-sidebar {
+    // List
+    @include override-list-group-item(
+      $color-list,
+      $bgcolor-sidebar-list-group,
+      $color-list-hover,
+      $bgcolor-list-hover,
+      $color-list-active,
+      $bgcolor-list-active
     );
-    .grw-pagetree-triangle-btn {
-      @include mixins-buttons.button-outline-svg-icon-variant($gray-400, $primary);
+    // sidebar-centent-bg
+    .grw-navigation-wrap {
+      // Drop a shadow on the light theme. The dark theme makes '$ bgcolor-sidebar-context' brighter than the body.
+      box-shadow: 0px 0px 3px rgba(black, 0.24);
     }
-  }
-  .private-legacy-pages-link {
-    &:hover {
-      background: $bgcolor-list-hover;
+    // Pagetree
+    .grw-pagetree {
+      @include override-list-group-item-for-pagetree(
+        var(--color-sidebar-context),
+        hsl.darken(var(--bgcolor-sidebar-context),5%),
+        hsl.darken(var(--bgcolor-sidebar-context),12%),
+        hsl.lighten(var(--color-sidebar-context),10%),
+        hsl.lighten(var(--color-sidebar-context),8%),
+        hsl.darken(var(--bgcolor-sidebar-context),15%),
+        hsl.darken(var(--bgcolor-sidebar-context),24%)
+      );
+
+      .grw-pagetree-triangle-btn {
+        @include mixins-buttons.button-outline-svg-icon-variant($gray-400, var(--primary));
+      }
+    }
+    .private-legacy-pages-link {
+      &:hover {
+        background: $bgcolor-list-hover;
+      }
     }
   }
-}
-
-.btn.btn-page-item-control {
-  @include button-outline-variant($gray-500, $primary, lighten($primary, 52%), transparent);
-  @include hover() {
-    background-color: lighten($primary, 58%);
-  }
-  &:not(:disabled):not(.disabled):active,
-  &:not(:disabled):not(.disabled).active {
-    color: $primary;
-  }
-  box-shadow: none !important;
-}
 
-/*
- * GROWI page list
- */
-.page-list {
-  .page-list-ul {
-    > li {
-      > span.page-list-meta {
-        color: lighten($color-global, 10%);
+  .btn.btn-page-item-control {
+    --gray-500: hsl(var(--gray-500-hs),var(--gray-500-l));
+    --gray-500-hs: 210,13%;
+    --gray-500-l: 61%;
+    @include hsl-button.button-outline-variant(var(--gray-500), var(--primary), #{hsl.lighten(var(--primary), 52%)}, transparent);
+    @include hover() {
+      background-color: hsl.lighten(var(--primary), 58%);
+    }
+    &:not(:disabled):not(.disabled):active,
+    &:not(:disabled):not(.disabled).active {
+      color: var(--primary);
+    }
+    box-shadow: none !important;
+  }
+
+  /*
+  * GROWI page list
+  */
+  .page-list {
+    .page-list-ul {
+      > li {
+        > span.page-list-meta {
+          color: hsl.lighten(var(--color-global),10%);
+        }
       }
     }
-  }
-  // List group
-  .list-group-item {
-    .page-list-snippet {
-      color: lighten($body-color, 10%);
+    // List group
+    .list-group-item {
+      &.active {
+        background-color: hsl.lighten(var(--primary),77%) !important;
+      }
+      &.list-group-item-action:hover {
+        background-color: hsl.lighten(var(--primary),72%) !important;
+      }
+      .page-list-snippet {
+        color: hsl.lighten(var(--color-global),10%);
+      }
     }
   }
-}
 
-/*
- * GROWI ToC
- */
-.revision-toc-content {
-  ::marker {
-    color: darken($bgcolor-global, 20%);
+  /*
+  * GROWI ToC
+  */
+  .revision-toc-content {
+    ::marker {
+      color: hsl.darken(var(--bgcolor-global),20%);
+    }
   }
-}
 
-/*
- * GROWI Editor
- */
-.grw-editor-navbar-bottom {
-  background-color: $gray-50;
+  /*
+  * GROWI Editor
+  */
+  .grw-editor-navbar-bottom {
+    background-color: $gray-50;
 
-  #slack-mark-white {
-    display: none;
-  }
+    #slack-mark-white {
+      display: none;
+    }
 
-  .input-group-text {
-    margin-right: 1px;
-    color: $secondary;
-    border-color: $light;
-  }
+    .input-group-text {
+      margin-right: 1px;
+      color: var(--secondary);
+      border-color: var(--light);
+    }
 
-  .btn.btn-outline-secondary {
-    border-color: $border-color;
+    .btn.btn-outline-secondary {
+      border-color: $border-color;
+    }
   }
-}
 
-/*
- * GROWI Link Edit Modal
- */
-.link-edit-modal {
-  span i {
-    color: $gray-400;
+  /*
+  * GROWI Link Edit Modal
+  */
+  .link-edit-modal {
+    span i {
+      color: $gray-400;
+    }
   }
-}
 
-/*
- * GROWI Grid Edit Modal
- */
+  /*
+  * GROWI Grid Edit Modal
+  */
 
-.grw-grid-edit-preview {
-  background: $gray-100;
-}
+  .grw-grid-edit-preview {
+    background: $gray-100;
+  }
 
-/*
- * Slack
- */
-.grw-slack-notification {
-  background-color: white;
-  $color-slack: #4b144c;
+  /*
+  * Slack
+  */
+  .grw-slack-notification {
+    background-color: white;
+    $color-slack: #4b144c;
 
-  .form-control {
-    background: white;
-  }
+    .form-control {
+      background: white;
+    }
 
-  .custom-control-label {
-    &::before {
-      background-color: $gray-200;
-      border-color: transparent;
+    .custom-control-label {
+      &::before {
+        background-color: $gray-200;
+        border-color: transparent;
+      }
+      &::after {
+        background-color: white;
+        background-image: url(/images/icons/slack/slack-logo-off.svg);
+      }
     }
-    &::after {
-      background-color: white;
-      background-image: url(/images/icons/slack/slack-logo-off.svg);
+    .custom-control-input:checked ~ .custom-control-label {
+      &::before {
+        background-color: lighten($color-slack, 60%);
+      }
+      &::after {
+        background-image: url(/images/icons/slack/slack-logo-on.svg);
+      }
     }
-  }
-  .custom-control-input:checked ~ .custom-control-label {
-    &::before {
-      background-color: lighten($color-slack, 60%);
+    .grw-slack-logo svg {
+      fill: #af30b0;
     }
-    &::after {
-      background-image: url(/images/icons/slack/slack-logo-on.svg);
+
+    .grw-btn-slack {
+      background-color: white;
+
+      &:hover,
+      &:focus {
+        background-color: white;
+      }
+    }
+
+    .grw-btn-slack-triangle {
+      color: var(--secondary);
     }
-  }
-  .grw-slack-logo svg {
-    fill: #af30b0;
   }
 
-  .grw-btn-slack {
-    background-color: white;
+  /*
+  * GROWI HandsontableModal
+  */
+  .grw-hot-modal-navbar {
+    background-color: var(--light);
+  }
 
-    &:hover,
-    &:focus {
-      background-color: white;
+  .wiki {
+    h1 {
+      border-color: var(--border-color-theme);
+    }
+    h2 {
+      border-color: var(--border-color-theme);
     }
   }
 
-  .grw-btn-slack-triangle {
-    color: $secondary;
+  /*
+  * GROWI comment form
+  */
+  .comment-form {
+    #slack-mark-white {
+      display: none;
+    }
   }
-}
 
-/*
- * GROWI HandsontableModal
- */
-.grw-hot-modal-navbar {
-  background-color: $light;
-}
-
-.wiki {
-  h1 {
-    border-color: $border-color-theme;
+  .page-comments-row {
+    background: var(--bgcolor-subnav);
   }
-  h2 {
-    border-color: $border-color-theme;
+
+  /*
+  * GROWI tags
+  */
+  .grw-tag-labels {
+    .grw-tag-label {
+      color: $color-tags;
+      background-color: $bgcolor-tags;
+    }
   }
-}
 
-/*
- * GROWI comment form
- */
-.comment-form {
-  #slack-mark-white {
-    display: none;
+  /*
+  * GROWI popular tags
+  */
+  .grw-popular-tag-labels {
+    .grw-tag-label {
+      color: $color-tags;
+      background-color: $bgcolor-tags;
+    }
   }
-}
 
-.page-comments-row {
-  background: $bgcolor-subnav;
-}
+  /*
+  * grw-side-contents
+  */
+  .grw-side-contents-sticky-container {
+    .grw-count-badge {
+      @include count-badge.count-badge($gray-600, $gray-200);
+    }
 
-/*
- * GROWI tags
- */
-.grw-tag-labels {
-  .grw-tag-label {
-    color: $color-tags;
-    background-color: $bgcolor-tags;
+    .grw-border-vr {
+      border-color: $border-color-toc;
+    }
+    .revision-toc {
+      border-color: $border-color-toc;
+    }
   }
-}
 
-/*
- * GROWI popular tags
- */
-.grw-popular-tag-labels {
-  .grw-tag-label {
-    color: $color-tags;
-    background-color: $bgcolor-tags;
+  /*
+  * drawio
+  */
+  .drawio-viewer {
+    border-color: $border-color-global;
   }
-}
 
-/*
-* grw-side-contents
-*/
-.grw-side-contents-sticky-container {
-  .grw-count-badge {
-    @include count-badge.count-badge($gray-600, $gray-200);
+  /*
+  * admin settings
+  */
+  .admin-setting-header {
+    border-color: $border-color;
   }
 
-  .grw-border-vr {
-    border-color: $border-color-toc;
+  /*
+  * modal
+  */
+  .grw-modal-head {
+    border-color: $border-color-global;
   }
-  .revision-toc {
-    border-color: $border-color-toc;
-  }
-}
 
-/*
- * drawio
- */
-.drawio-viewer {
-  border-color: $border-color-global;
-}
-
-/*
- * admin settings
- */
-.admin-setting-header {
-  border-color: $border-color;
-}
-
-/*
- * modal
- */
-.grw-modal-head {
-  border-color: $border-color-global;
-}
-
-/*
- * skeleton
- */
-.grw-skeleton {
-  background-color: darken($bgcolor-subnav, 10%);
+  /*
+  * skeleton
+  */
+  .grw-skeleton {
+    background-color: hsl.lighten(var(--bgcolor-navbar),10%);
+  }
 }

+ 119 - 124
packages/app/src/styles/theme/_apply-colors.scss

@@ -1,54 +1,52 @@
 @use '../variables' as var;
 @use '../bootstrap/init' as *;
 @use '../mixins';
-@use './mixins/tables'; // comment out and use _reboot-bootstrap-tables instead -- 2020.05.28 Yuki Takei
 @use '../atoms/mixins/code';
+@use './mixins/hsl-button';
+@use './hsl-functions' as hsl;
 
 //
 //== Apply to Bootstrap
 //
 
 // determine optional variables
-$border-image-navbar: linear-gradient(to right, $gray-300 0%, $gray-300 100%) !default;
-$bgcolor-search-top-dropdown: $secondary !default;
-$bgcolor-sidebar-nav-item-active: darken($bgcolor-sidebar, 10%) !default;
-$text-shadow-sidebar-nav-item-active: 1px 1px 2px $primary !default;
-$bgcolor-inline-code: $gray-100 !default;
-$color-inline-code: darken($red, 15%) !default;
-$bordercolor-inline-code: $gray-400 !default;
-$bordercolor-nav-tabs: $gray-300 !default;
-$bordercolor-nav-tabs-hover: $gray-200 $gray-200 $bordercolor-nav-tabs !default;
-$color-nav-tabs-link-active: $gray-600 !default;
-$bordercolor-nav-tabs-active: $bordercolor-nav-tabs $bordercolor-nav-tabs $bgcolor-global !default;
-$color-btn-reload-in-sidebar: $gray-500;
-$bgcolor-keyword-highlighted: var.$grw-marker-yellow !default;
-$bgcolor-page-list-group-item-active: lighten($primary, 76%) !default;
-$color-page-list-group-item-meta: $gray-500 !default;
-$color-search-page-list-title: $color-global !default;
-$bgcolor-subnav: darken($bgcolor-global, 3%) !default;
+$bgcolor-search-top-dropdown: var(--bgcolor-search-top-dropdown,var(--secondary));
+$bgcolor-sidebar-nav-item-active: var(--bgcolor-sidebar-nav-item-active,#{hsl.darken(var(--primary),10%)});
+$text-shadow-sidebar-nav-item-active: var(--text-shadow-sidebar-nav-item-active,1px 1px 2px var(--primary));
+$bgcolor-inline-code: var(--bgcolor-inline-code, #{$gray-100});
+$color-inline-code: var(--color-inline-code, #{darken($red, 15%)});
+$bordercolor-inline-code: var(--bordercolor-inline-code, #{$gray-400});
+$bordercolor-nav-tabs: var(--bordercolor-nav-tabs, #{$gray-300});
+$bordercolor-nav-tabs-hover: var(--bordercolor-nav-tabs-hover,#{$gray-200} #{$gray-200} #{$bordercolor-nav-tabs});
+$border-nav-tabs-link-active: var(--border-nav-tabs-link-active, #{$gray-600});
+$bordercolor-nav-tabs-active: var(--bordercolor-nav-tabs-active,$bordercolor-nav-tabs $bordercolor-nav-tabs var(--bgcolor-global));
+$color-btn-reload-in-sidebar: var(--color-btn-reload-in-sidebar,#{$gray-500});
+$bgcolor-keyword-highlighted: var(--bgcolor-keyword-highlighted,#{var.$grw-marker-yellow});
+$color-page-list-group-item-meta: var(--color-page-list-group-item-meta,#{$gray-500});
+$color-search-page-list-title: var(--color-search-page-list-title,var(--color-global));
 
 // override bootstrap variables
-$body-bg: $bgcolor-global;
-$body-color: $color-global;
-$link-color: $color-link;
-$link-hover-color: $color-link-hover;
-$input-focus-color: $color-global;
+$body-bg: var(--bgcolor-global);
+$body-color: var(--color-global);
+$link-color: var(--color-link);
+$link-hover-color: var(--color-link-hover);
+$input-focus-color: var(--color-global);
 $nav-tabs-border-color: $bordercolor-nav-tabs;
 $nav-tabs-link-hover-border-color: $bordercolor-nav-tabs-hover;
-$nav-tabs-link-active-color: $color-nav-tabs-link-active;
-$nav-tabs-link-active-bg: $bgcolor-global;
+$nav-tabs-link-active-color: var(--color-nav-tabs-link-active);
+$nav-tabs-link-active-bg: var(--bgcolor-global);
 $nav-tabs-link-active-border-color: $bordercolor-nav-tabs-active;
 $theme-colors: map-merge($theme-colors, ( primary: $primary ));
 
 @import 'reboot-bootstrap-buttons';
 @import 'reboot-bootstrap-colors';
 @import 'reboot-bootstrap-theme-colors';
+@import 'hsl-reboot-bootstrap-theme-colors';
 @import 'reboot-bootstrap-nav';
 @import 'reboot-toastr-colors';
-@import '~emoji-mart/css/emoji-mart'; // Emoji-mart style
 
 // determine variables with bootstrap function (These variables can be used after importing bootstrap above)
-$color-modal-header: color-yiq($primary) !default;
+$color-modal-header: var(--color-modal-header,#{hsl.contrast(var(--primary))});
 
 code:not([class^='language-']) {
   @include code.code-inline-color($color-inline-code, $bgcolor-inline-code, $bordercolor-inline-code);
@@ -75,13 +73,13 @@ code:not([class^='language-']) {
 // Dropdown
 .grw-apperance-mode-dropdown {
   .grw-sidebar-mode-icon svg {
-    fill: $secondary;
+    fill: var(--secondary);
   }
   .grw-color-mode-icon svg {
-    fill: $color-global;
+    fill: var(--color-global);
   }
   .grw-color-mode-icon-muted svg {
-    fill: $secondary;
+    fill: var(--secondary);
   }
 }
 
@@ -92,12 +90,12 @@ code:not([class^='language-']) {
 
 // Tabs
 .nav.nav-tabs .nav-link.active {
-  color: $color-link !important;
+  color: var(--color-link);
   background: transparent;
 
   &:hover,
   &:focus {
-    color: $color-link-hover !important;
+    color: var(--color-link-hover);
   }
 }
 
@@ -110,23 +108,23 @@ ul.pagination {
   }
   li.page-item.active {
     button.page-link {
-      color: color-yiq($primary);
-      background-color: $primary;
+      color: hsl.contrast(var(--primary));
+      background-color: var(--primary);
       &:hover,
       &:focus {
-        color: color-yiq($primary);
-        background-color: $primary;
+        color: hsl.contrast(var(--primary));
+        background-color: var(--primary);
       }
     }
   }
   li.page-item {
     button.page-link {
-      color: $primary;
-      border-color: $secondary;
+      color: var(--primary);
+      border-color: var(--secondary) !important;
       &:hover,
       &:active,
       &:focus {
-        color: $primary;
+        color: var(--primary);
       }
     }
   }
@@ -144,13 +142,13 @@ ul.pagination {
 //
 
 .grw-logo {
-  // set transition for fill
+  set transition for fill
   svg * {
     transition: fill 0.8s ease-out;
   }
 
   svg {
-    fill: $fillcolor-logo-mark;
+    fill: var(--fillcolor-logo-mark);
   }
 
   &:hover {
@@ -167,75 +165,70 @@ ul.pagination {
 }
 
 .grw-navbar {
-  background: $bgcolor-navbar;
+  background: var(--bgcolor-navbar);
   .nav-item .nav-link {
-    color: $color-link-nabvar;
+    color: var(--color-link-nabvar);
   }
 
-  border-image: $border-image-navbar;
-  border-image-slice: 1;
+  border-image: var(--border-image-navbar) !important;
+  border-image-slice: 1 !important;
 
   .grw-app-title {
-    color: $fillcolor-logo-mark;
+    color: var(--fillcolor-logo-mark);
   }
 }
 
 .grw-global-search {
   .btn-secondary.dropdown-toggle {
-    @include button-variant($bgcolor-search-top-dropdown, $bgcolor-search-top-dropdown);
+    @include hsl-button.button-variant(var(--bgcolor-search-top-dropdown), var(--bgcolor-search-top-dropdown));
   }
 
   // for https://youtrack.weseek.co.jp/issue/GW-2603
   .search-typeahead {
-    background-color: rgba($bgcolor-global, 0.9);
+    background-color: hsl.alpha(var(--bgcolor-global),10%);
   }
 }
 
 .grw-sidebar {
+  $color-resize-button: var(--color-resize-button,var(--color-global));
+  $bgcolor-resize-button: var(--bgcolor-resize-button,white);
+  $color-resize-button-hover: var(--color-resize-button-hover,var(--color-reversal));
+  $bgcolor-resize-button-hover: var(--bgcolor-resize-button-hover,#{hsl.lighten(var(--bgcolor-resize-button), 5%)});
   .grw-navigation-resize-button {
-    $color-resize-button: $color-global !default;
-    $bgcolor-resize-button: white !default;
-    $color-resize-button-hover: $color-reversal !default;
-    $bgcolor-resize-button-hover: lighten($bgcolor-resize-button, 5%) !default;
-
     .hexagon-container svg {
       .background {
-        fill: $bgcolor-resize-button;
+        fill: var(--bgcolor-resize-button);
       }
       .icon {
-        fill: $color-resize-button;
+        fill: var(--color-resize-button);
       }
     }
     &:hover .hexagon-container svg {
       .background {
-        fill: $bgcolor-resize-button-hover;
+        fill: var(--bgcolor-resize-button-hover);
       }
       .icon {
-        fill: $color-resize-button-hover;
+        fill: var(--color-resize-button-hover);
       }
     }
   }
   div.grw-global-navigation {
     > div {
-      background-color: $bgcolor-sidebar;
+      background-color: var(--bgcolor-sidebar);
     }
   }
   div.grw-contextual-navigation {
     > div {
-      color: $color-sidebar-context;
-      background-color: $bgcolor-sidebar-context;
+      color: var(--color-sidebar-context);
+      background-color: var(--bgcolor-sidebar-context);
     }
   }
 
   .grw-sidebar-nav {
     .btn {
-      @include button-variant(
-        $bgcolor-sidebar,
-        $bgcolor-sidebar,
-        darken($bgcolor-sidebar, 7.5%),
-        darken($bgcolor-sidebar, 10%),
-        $bgcolor-sidebar-nav-item-active,
-        $bgcolor-sidebar-nav-item-active
+      @include hsl-button.button-variant(
+        var(--bgcolor-sidebar),
+        var(--bgcolor-sidebar),
       );
     }
   }
@@ -246,7 +239,7 @@ ul.pagination {
       }
       // fukidashi
       &:after {
-        border-right-color: $bgcolor-sidebar-context;
+        border-right-color: var(--bgcolor-sidebar-context) !important;
       }
     }
   }
@@ -258,24 +251,24 @@ ul.pagination {
 
     .grw-recent-changes-resize-button {
       .custom-control-label::before {
-        background-color: $primary;
+        background-color: var(--primary);
       }
 
       .custom-control-label::after {
-        background-color: $bgcolor-global;
+        background-color: var(--bgcolor-global);
       }
 
       .custom-control-input:not(:checked) + .custom-control-label::before {
-        color: $bgcolor-global;
+        color: var(--bgcolor-global);
       }
 
       .custom-control-input:checked + .custom-control-label::before {
-        color: $bgcolor-global;
-        background-color: $primary;
-        // border-color: $primary !important;
+        color: var(--bgcolor-global);
+        background-color: var(--primary);
+        border-color: var(--primary);
       }
       .custom-control-input:checked + .custom-control-label::after {
-        color: $bgcolor-global;
+        color: var(--bgcolor-global);
       }
     }
   }
@@ -296,10 +289,10 @@ ul.pagination {
   .grw-recent-changes {
     .list-group {
       .list-group-item {
-        background-color: transparent;
+        background-color: transparent !important;
 
         .icon-lock {
-          color: $color-link;
+          color: var(--color-link);
         }
 
         .grw-recent-changes-item-lower {
@@ -318,7 +311,7 @@ ul.pagination {
  * Icon
  */
 .editor-container .navbar-editor svg {
-  fill: $color-editor-icons;
+  fill: var(--color-editor-icons);
 }
 
 // page preview button in link form
@@ -331,13 +324,14 @@ ul.pagination {
  */
 .modal {
   .modal-header {
-    border-bottom-color: $border-color-theme;
+    border-bottom-color: var(--border-color-theme);
     .modal-title {
       color: $color-modal-header;
     }
     .close {
       color: $color-modal-header;
       opacity: 0.5;
+
       &:hover {
         opacity: 0.9;
       }
@@ -345,11 +339,11 @@ ul.pagination {
   }
 
   .modal-content {
-    background-color: $bgcolor-global;
+    background-color: var(--bgcolor-global);
   }
 
   .modal-footer {
-    border-top-color: $border-color-theme;
+    border-top-color: var(--border-color-theme);
   }
 }
 
@@ -357,13 +351,13 @@ ul.pagination {
   .nav-item {
     &:hover,
     &:focus {
-      background-color: rgba($color-link, 0.08);
+      background-color: hsl.alpha(var(--color-link),10%);
     }
     .nav-link {
       -webkit-appearance: none;
-      color: $color-link;
+      color: var(--color-link);
       svg {
-        fill: $color-link;
+        fill: var(--color-link);
       }
 
       // Disabled state lightens text
@@ -377,14 +371,14 @@ ul.pagination {
   }
 
   .grw-nav-slide-hr {
-    border-color: $color-link;
+    border-color: var(--color-link) !important;
   }
 }
 
 .grw-page-accessories-modal {
   .modal-header {
     .close {
-      color: $secondary;
+      color: var(--secondary);
     }
   }
 }
@@ -393,9 +387,9 @@ ul.pagination {
  * cards
  */
 .card.well {
-  color: $color-global;
-  background-color: $bgcolor-card;
-  border-color: $light;
+  color: var(--color-global);
+  background-color: var(--bgcolor-card);
+  border-color: var(--light);
   box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
 }
 
@@ -438,7 +432,7 @@ ul.pagination {
   h6,
   h7 {
     &.blink {
-      @include mixins.blink-bgcolor($bgcolor-blinked-section);
+      @include mixins.blink-bgcolor(var(--bgcolor-blinked-section));
     }
   }
 
@@ -447,21 +441,21 @@ ul.pagination {
   }
 
   a {
-    color: $color-link-wiki;
+    color: var(--color-link-wiki);
 
     &:hover {
-      color: $color-link-wiki-hover;
+      color: var(--color-link-wiki-hover);
     }
   }
 
   // table with handsontable modal button
   .editable-with-handsontable {
     button {
-      color: $color-link-wiki;
+      color: var(--color-link-wiki);
     }
 
     button:hover {
-      color: $color-link-wiki-hover;
+      color: var(--color-link-wiki-hover);
     }
   }
 }
@@ -473,14 +467,15 @@ ul.pagination {
   // List group
   .list-group {
     .list-group-item {
+      background-color: var(--bgcolor-global) !important;
       a {
         svg {
-          fill: $color-global;
+          fill: var(--color-global);
         }
 
         @include hover() {
           svg {
-            fill: $color-global;
+            fill: var(--color-global);
           }
         }
       }
@@ -493,9 +488,9 @@ ul.pagination {
       }
 
       &.list-group-item-action {
+        background-color: var(--bgcolor-list);
         &.active {
-          background-color: $bgcolor-page-list-group-item-active;
-          border-left-color: $primary;
+          border-left-color: var(--primary);
         }
       }
     }
@@ -507,19 +502,19 @@ ul.pagination {
  */
 .layout-root.editing {
   .main {
-    background-color: darken($bgcolor-global, 2%);
+    background-color: hsl.darken(var(--bgcolor-global),2%);
 
     .page-editor-editor-container {
-      border-right-color: $border-color-theme;
+      border-right-color: var(--border-color-theme);
 
       .navbar-editor {
-        background-color: $bgcolor-global; // same color with active tab
-        border-bottom-color: $border-color-theme;
+        background-color: var(--bgcolor-global); // same color with active tab
+        border-bottom-color: var(--border-color-theme);
       }
     }
 
     .page-editor-preview-container {
-      background-color: $bgcolor-global;
+      background-color: var(--bgcolor-global);
     }
   }
 }
@@ -529,8 +524,8 @@ ul.pagination {
  */
 body.editing-sidebar {
   .page-editor-preview-body {
-    color: $color-sidebar-context;
-    background-color: $bgcolor-sidebar-context;
+    color: var(--color-sidebar-context);
+    background-color: var(--bgcolor-sidebar-context);
   }
 }
 
@@ -541,10 +536,10 @@ body.editing-sidebar {
   .desktop-preview,
   .tablet-preview,
   .mobile-preview {
-    background: $bgcolor-global;
+    background: var(--bgcolor-global);
   }
   .grid-edit-border-for-each-cols {
-    border: 2px solid $bgcolor-global;
+    border: 2px solid var(--bgcolor-global);
   }
 }
 
@@ -568,10 +563,10 @@ body.editing-sidebar {
  * GROWI comment
  */
 .page-comment-meta .page-comment-revision svg {
-  fill: $color-link;
+  fill: var(--color-link);
 
   &:hover {
-    fill: $color-link-hover;
+    fill: var(--color-link-hover);
   }
 }
 
@@ -581,17 +576,17 @@ body.editing-sidebar {
 .page-comments {
   .page-comment .page-comment-main,
   .page-comment-form .comment-form-main {
-    background-color: $bgcolor-global;
+    background-color: var(--bgcolor-global);
 
     &:before {
-      border-right-color: $bgcolor-global;
+      border-right-color: var(--bgcolor-global);
     }
 
     .nav.nav-tabs {
       > li > a.active {
         background: transparent;
-        border-bottom: solid 1px darken($bgcolor-global, 4%);
-        border-bottom-color: darken($bgcolor-global, 4%);
+        border-bottom: solid 1px hsl.darken(var(--bgcolor-global),4%);
+        border-bottom-color: hsl.darken(var(--bgcolor-global),4%);
       }
     }
   }
@@ -602,10 +597,10 @@ body.editing-sidebar {
  */
 .search-result-base {
   .grw-search-page-nav {
-    background-color: $bgcolor-subnav;
+    background-color: var(--bgcolor-subnav);
   }
   .search-control {
-    background-color: $bgcolor-global;
+    background-color: var(--bgcolor-global);
   }
   .page-list {
     .highlighted-keyword {
@@ -626,8 +621,8 @@ mark.rbt-highlight-text {
  * GROWI page content footer
  */
 .page-content-footer {
-  background-color: darken($bgcolor-global, 2%);
-  border-top-color: $border-color-theme;
+  background-color: hsl.darken(var(--bgcolor-global),2%);
+  border-top-color: var(--border-color-theme);
 }
 
 /*
@@ -637,7 +632,7 @@ mark.rbt-highlight-text {
   #layoutOptions {
     .customize-layout-card {
       &.border-active {
-        border-color: $color-theme-color-box;
+        border-color: var(--color-theme-color-box);
       }
     }
   }
@@ -645,11 +640,11 @@ mark.rbt-highlight-text {
   #themeOptions {
     .theme-option-container.active {
       .theme-option-name {
-        color: $color-global;
+        color: var(--color-global);
       }
       a {
-        background-color: $color-theme-color-box;
-        border-color: $color-theme-color-box;
+        background-color: var(--color-theme-color-box);
+        border-color: var(--color-theme-color-box);
       }
     }
   }
@@ -659,13 +654,13 @@ mark.rbt-highlight-text {
  * HackMd
  */
 .bg-box {
-  background-color: $bgcolor-global;
+  background-color: var(--bgcolor-global);
 }
 
 .grw-fab {
   .btn-create-page {
     svg {
-      fill: color-yiq($primary);
+      fill: hsl.contrast(var(--primary));
     }
   }
 
@@ -689,7 +684,7 @@ mark.rbt-highlight-text {
 .grw-unopend-notification {
   width: 7px;
   height: 7px;
-  background-color: $primary;
+  background-color: var(--primary);
 }
 
 /*

+ 32 - 0
packages/app/src/styles/theme/_hsl-functions.scss

@@ -0,0 +1,32 @@
+@use '~bootstrap/scss/functions' as bs;
+
+@function contrast($color, $darken-degrees: 0%, $alpha-degrees: 100%) {
+  $color: bs.str-replace($color, 'var(');
+  $color: bs.str-replace($color, ')');
+  $color-hs: var(#{$color+'-hs'});
+  $color-l: var(#{$color+'-l'});
+  // @return hsl($color-hs, clamp(10%, calc((100% - $color-l - 51% ) * 1000), 95%));
+  @return hsla($color-hs, clamp(10%, calc((100% - $color-l - $darken-degrees - 51% ) * 1000), 95%), $alpha-degrees);
+}
+
+@function lighten($color, $degrees) {
+  $color: bs.str-replace($color, 'var(');
+  $color: bs.str-replace($color, ')');
+  $color-hs: var(#{$color+'-hs'});
+  $color-l: var(#{$color+'-l'});
+  @return hsl($color-hs, calc($color-l + $degrees));
+}
+@function darken($color, $degrees) {
+  $color: bs.str-replace($color, 'var(');
+  $color: bs.str-replace($color, ')');
+  $color-hs: var(#{$color+'-hs'});
+  $color-l: var(#{$color+'-l'});
+  @return hsl($color-hs, calc($color-l - $degrees));
+}
+@function alpha($color, $degrees) {
+  $color: bs.str-replace($color, 'var(');
+  $color: bs.str-replace($color, ')');
+  $color-hs: var(#{$color+'-hs'});
+  $color-l: var(#{$color+'-l'});
+  @return hsla($color-hs,$color-l,$degrees);
+}

+ 112 - 0
packages/app/src/styles/theme/_hsl-reboot-bootstrap-theme-colors.scss

@@ -0,0 +1,112 @@
+@use '../bootstrap/init' as *;
+@use '../atoms/mixins/buttons' as mixins-buttons;
+@use './mixins/hsl-button';
+@use './mixins/hsl-badge';
+@use './hsl-functions' as hsl;
+
+$hsl-colors: (
+  'primary': var(--primary),
+  'secondary': var(--secondary)
+);
+
+@each $color, $value in $hsl-colors {
+  .bg-#{$color} {
+    background-color: $value !important;
+    a,
+    button {
+      @include hover-focus() {
+        background-color: hsl.darken($value, 10%) !important;
+      }
+    }
+  }
+}
+
+@each $color, $value in $hsl-colors {
+  .border-#{$color} {
+    border-color: $value !important;
+  }
+}
+
+@each $color, $value in $hsl-colors {
+  .text-#{$color} {
+    color: $value !important;
+    @if $emphasized-link-hover-darken-percentage != 0 {
+      a {
+        @include hover-focus() {
+          color: hsl.darken($value, $emphasized-link-hover-darken-percentage) !important;
+        }
+      }
+    }
+  }
+}
+
+@each $color, $value in $hsl-colors {
+  .btn-#{$color} {
+    @include hsl-button.button-variant($value, $value);
+    @include hsl-button.button-svg-icon-variant($value, $value);
+    box-shadow: none !important;
+  }
+}
+
+@each $color, $value in $hsl-colors {
+  .btn-outline-#{$color} {
+    @include hsl-button.button-outline-variant($value, $value, hsl.alpha($value, 10%), $value);
+    @include mixins-buttons.button-outline-svg-icon-variant($value, $value);
+
+    &:not(:disabled):not(.disabled):active,
+    &:not(:disabled):not(.disabled).active {
+      color: $value;
+      background-color: hsl.alpha($value, 10%);
+      border-color: $value;
+    }
+
+    box-shadow: none !important;
+  }
+
+  // separate style: https://github.com/weseek/growi/pull/6804
+  .show > .btn-outline-#{$color}.dropdown-toggle {
+    color: $value;
+    background-color: hsl.alpha($value, 10%);
+    border-color: $value;
+  }
+}
+
+@each $color, $value in $hsl-colors {
+  .alert-#{$color} {
+    $alert-color: rgba(white,90%);
+    $alert-bg-color: hsl.darken($value, calc($alert-bg-level + 0.95) * $theme-color-interval);
+    $alert-border-color: hsl.darken($value, $alert-border-level * $theme-color-interval);
+
+    color: $alert-color;
+    @include gradient-bg($alert-bg-color);
+    border-color: $alert-border-color;
+
+    hr {
+      border-top-color: hsl.darken($value, calc($alert-border-level + 5) * $theme-color-interval);
+    }
+
+    .alert-link {
+      color: hsl.contrast($value);
+    }
+  }
+
+  // Alert link
+  :root, .wiki {
+    .alert.alert-primary {
+      a,
+      a:hover {
+        color: hsl.darken($value, calc($alert-bg-level - 7.7) * $theme-color-interval);
+      }
+    }
+  }
+}
+
+@each $color, $value in $hsl-colors {
+  .badge-#{$color} {
+    @include hsl-badge.badge-variant($value);
+  }
+
+  a.badge-#{$color}  {
+    @include hsl-badge.badge-variant($value);
+  }
+}

+ 1 - 1
packages/app/src/styles/theme/_reboot-bootstrap-border-colors.scss

@@ -25,5 +25,5 @@
 }
 
 .border-info {
-  border-color: ver(--info) !important;
+  border-color: $info !important;
 }

+ 7 - 6
packages/app/src/styles/theme/_reboot-bootstrap-buttons.scss

@@ -1,21 +1,22 @@
 .btn-link {
-  color: $link-color;
+  color: var(--color-link);
   svg {
-    fill: $link-color;
+    fill: var(--color-link);
   }
 
   @include hover() {
-    color: $link-hover-color;
+    color: var(--color-link-hover);
     svg {
-      fill: $link-hover-color;
+      fill: var(--color-link-hover);
     }
   }
 
   &:disabled,
   &.disabled {
-    color: $btn-link-disabled-color;
+    color: var(--color-link-disabled, #{$gray-500});
     svg {
-      fill: $btn-link-disabled-color;
+      fill: var(--color-link-disabled, #{$gray-500});
     }
   }
 }
+

+ 8 - 8
packages/app/src/styles/theme/_reboot-bootstrap-colors.scss

@@ -14,32 +14,32 @@
 // 3. Set an explicit initial text-align value so that we can later use
 //    the `inherit` value on things like `<th>` elements.
 
-&, body {
-  color: $body-color;
-  background-color: $body-bg; // 2
+html, body {
+  color: var(--color-global);
+  background-color: var(--bgcolor-global); // 2
 
   svg {
-    fill: $body-color;
+    fill: var(--color-global);
   }
 }
 
 // Links
 
 a {
-  color: $link-color;
+  color: var(--color-link);
   text-decoration: $link-decoration;
   background-color: transparent; // Remove the gray background on active links in IE 10.
 
   svg {
-    fill: $link-color;
+    fill: var(--color-link);
   }
 
   @include hover() {
-    color: $link-hover-color;
+    color: var(--color-link-hover);
     text-decoration: $link-hover-decoration;
 
     svg {
-      fill: $link-hover-color;
+      fill: var(--color-link-hover);
     }
   }
 }

+ 11 - 11
packages/app/src/styles/theme/_reboot-bootstrap-dropdown.scss

@@ -1,37 +1,37 @@
 @use '../bootstrap/init' as *;
 
 .dropdown-menu {
-  color: $dropdown-color;
+  color: $color-dropdown;
   svg {
-    fill: $dropdown-color;
+    fill: $color-dropdown;
   }
 
-  background-color: $dropdown-bg;
+  background-color: $bgcolor-dropdown;
 }
 
 .dropdown-item {
-  color: $dropdown-link-color;
+  color: $color-dropdown-link;
   svg {
-    fill: $dropdown-link-color;
+    fill: $color-dropdown-link;
   }
 
   @include hover-focus() {
-    color: $dropdown-link-hover-color;
+    color: $color-dropdown-link;
     svg {
-      fill: $dropdown-link-hover-color;
+      fill: $color-dropdown-link-hover;
     }
 
-    @include gradient-bg($dropdown-link-hover-bg);
+    @include gradient-bg($bgcolor-dropdown-link-hover);
   }
 
   &:active,
   &.active,
   &:active:hover,
   &.active:hover {
-    color: $dropdown-link-active-color;
-    background-color: $dropdown-link-active-bg;
+    color: $color-dropdown-link-active;
+    background-color:  $bgcolor-dropdown-link-active;
     svg {
-      fill: $dropdown-link-active-color;
+      fill: $color-dropdown-link-active;
     }
   }
 }

+ 9 - 9
packages/app/src/styles/theme/_reboot-bootstrap-tables.scss

@@ -8,37 +8,37 @@
 //
 
 .table {
-  color: $table-color;
-  background-color: $table-bg; // Reset for nesting within parents with `background-color`.
+  color: $color-table;
+  background-color: $bgcolor-table; // Reset for nesting within parents with `background-color`.
 
   th,
   td {
-    border-top-color: $table-border-color;
+    border-top-color: $border-color-table;
   }
 
   thead th {
-    border-bottom-color: $table-border-color;
+    border-bottom-color: $border-color-table;
   }
 
   tbody + tbody {
-    border-top-color: $table-border-color;
+    border-top-color: $border-color-table;
   }
 }
 
 .table-bordered {
-  border-color: $table-border-color;
+  border-color: $border-color-table;
 
   th,
   td {
-    border-color: $table-border-color;
+    border-color: $border-color-table;
   }
 }
 
 .table-hover {
   tbody tr {
     @include hover() {
-      color: $table-hover-color;
-      background-color: $table-hover-bg;
+      color: $color-table-hover;
+      background-color: $bgcolor-table-hover;
     }
   }
 }

+ 14 - 5
packages/app/src/styles/theme/_reboot-bootstrap-theme-colors.scss

@@ -7,7 +7,7 @@
 
 @each $color, $value in $theme-colors {
   .border-#{$color} {
-    border-color: $value !important;
+    border-color: $value;
   }
 }
 
@@ -57,16 +57,16 @@
       border-color: $color;
     }
     .custom-control-input:checked + .custom-control-label::after {
-      color: $bgcolor-global;
+      color: var(--bgcolor-global);
     }
     .custom-control-input:not(:disabled):active ~ .custom-control-label::before {
-      color: $bgcolor-global;
+      color: var(--bgcolor-global);
       background-color: $color;
       border-color: $color;
     }
     .custom-control-input:focus:not(:checked) ~ .custom-control-label::before {
-      color: $bgcolor-global;
-      background-color: $bgcolor-global;
+      color: var(--bgcolor-global);
+      background-color: var(--bgcolor-global);
       border-color: $input-focus-border-color;
     }
   }
@@ -80,6 +80,15 @@
       theme-color-level($color, $alert-color-level)
     );
   }
+  // Alert link
+  :root, .wiki {
+    .alert.alert-#{$color} {
+      a,
+      a:hover {
+        color: theme-color-level($color, $alert-color-level - 2);
+      }
+    }
+  }
 }
 
 @each $color, $value in $theme-colors {

+ 11 - 4
packages/app/src/styles/theme/_reboot-toastr-colors.scss

@@ -1,15 +1,22 @@
 .toast-success {
-  background-color: var(--success);
+  background-color: var(--success) !important;
 }
 
 .toast-error {
-  background-color: var(--danger);
+  background-color: var(--danger) !important;
 }
 
 .toast-info {
-  background-color: var(--info);
+  background-color: var(--info) !important;
 }
 
 .toast-warning {
-  background-color: var(--warning);
+  background-color: var(--warning) !important;
+}
+
+:root {
+  --toastify-color-info: var(--info);
+  --toastify-color-success: var(--success);
+  --toastify-color-warning: var(--warning);
+  --toastify-color-error: var(--danger);
 }

+ 21 - 0
packages/app/src/styles/theme/mixins/_hsl-badge.scss

@@ -0,0 +1,21 @@
+@use '../../bootstrap/init' as bs;
+@use '../hsl-functions' as hsl;
+
+// @mixin badge-variant($bg) {
+@mixin badge-variant($bg) {
+  color: hsl.contrast($bg);
+  background-color: $bg;
+
+  @at-root a#{&} {
+    @include bs.hover-focus() {
+      color: hsl.contrast($bg);
+      background-color: hsl.darken($bg, 10%);
+    }
+
+    &:focus,
+    &.focus {
+      outline: 0;
+      // box-shadow: 0 0 0 $badge-focus-width hsl.alpha($bg, 50%);
+    }
+  }
+}

+ 142 - 0
packages/app/src/styles/theme/mixins/_hsl-button.scss

@@ -0,0 +1,142 @@
+@use '../../bootstrap/init' as bs;
+@use '../hsl-functions' as hsl;
+
+// @mixin button-variant($background, $border, $hover-background: darken($background, 7.5%), $hover-border: darken($border, 10%), $active-background: darken($background, 10%), $active-border: darken($border, 12.5%)) {
+@mixin button-variant($background, $border, $hover-background-darken-degrees: 7.5%, $hover-border-darken-degrees: 10%, $active-background-darken-degrees: 10%, $active-border-darken-degrees: 12.5%) {
+  $hover-background: hsl.darken($background, $hover-background-darken-degrees);  // DO NOT ... twice
+  $hover-border: hsl.darken($border, $hover-border-darken-degrees);  // DO NOT ... twice
+
+  color: hsl.contrast($background);
+  @include bs.gradient-bg($background);
+  border-color: $border;
+  // @include box-shadow($btn-box-shadow);
+
+  @include bs.hover() {
+    color: hsl.contrast($background);
+    @include bs.gradient-bg($hover-background);
+    border-color: $hover-border;
+  }
+
+  &:focus,
+  &.focus {
+    color: hsl.contrast($background);
+    @include bs.gradient-bg($hover-background);
+    border-color: $hover-border;
+    // @if $enable-shadows {
+    //   @include box-shadow($btn-box-shadow, 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5));
+    // } @else {
+    //   // Avoid using mixin so we can pass custom focus shadow properly
+    //   box-shadow: 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);
+    // }
+  }
+
+  // // Disabled comes first so active can properly restyle
+  &.disabled,
+  &:disabled {
+    color: hsl.contrast($background);
+    @include bs.gradient-bg($background);
+    border-color: $border;
+    // Remove CSS gradients if they're enabled
+    @if bs.$enable-gradients {
+      background-image: none;
+    }
+  }
+
+  &:not(:disabled):not(.disabled):active,
+  &:not(:disabled):not(.disabled).active,
+  .show > &.dropdown-toggle {
+    color: hsl.contrast($background);
+    background-color: $hover-background;
+    border-color: $hover-border;
+  }
+  //   @if $enable-gradients {
+  //     background-image: none; // Remove the gradient for the pressed/active state
+  //   }
+  //   border-color: $active-border;
+
+  //   &:focus {
+  //     // @if $enable-shadows and $btn-active-box-shadow != none {
+  //     //   @include box-shadow($btn-active-box-shadow, 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5));
+  //     // } @else {
+  //     //   // Avoid using mixin so we can pass custom focus shadow properly
+  //     //   box-shadow: 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);
+  //     // }
+  //   }
+  // }
+}
+
+// @mixin button-outline-variant($color, $color-hover: color-yiq($color), $active-background: $color, $active-border: $color) {
+@mixin button-outline-variant($color, $color-hover: hsl.contrast($color), $active-background: $color, $active-border: $color) {
+  color: $color;
+  border-color: $color;
+
+  @include bs.hover() {
+    color: $color-hover;
+    background-color: $active-background;
+    border-color: $active-border;
+  }
+
+  // &:focus,
+  // &.focus {
+  //   box-shadow: 0 0 0 bs.$btn-focus-width hsl.alpha($color,50%);
+  // }
+
+  &.disabled,
+  &:disabled {
+    color: $color;
+    background-color: transparent;
+  }
+
+  // &:not(:disabled):not(.disabled):active,
+  // &:not(:disabled):not(.disabled).active,
+  // .show > &.dropdown-toggle {
+  //   color: hsl.contrast($active-background);
+  //   background-color: $active-background;
+  //   border-color: $active-border;
+
+  // &:focus {
+  //   @if $enable-shadows and $btn-active-box-shadow != none {
+  //     @include bs.box-shadow($btn-active-box-shadow, 0 0 0 $btn-focus-width hsl.alpha($color,50%));
+  //   } @else {
+  //     // Avoid using mixin so we can pass custom focus shadow properly
+  //     box-shadow: 0 0 0 $btn-focus-width hsl.alpha($color,50%);
+  //   }
+  // }
+  // }
+}
+
+// @mixin button-svg-icon-variant($background, $hover-background: darken($background, 7.5%), $active-background: darken($background, 10%)) {
+@mixin button-svg-icon-variant($background, $hover-background-darken-degrees: 7.5%, $active-background-darken-degrees: 10%) {
+  svg {
+    fill: hsl.contrast($background);
+  }
+
+  @include bs.hover() {
+    svg {
+      fill: hsl.contrast($background);
+    }
+  }
+
+  &:focus,
+  &.focus {
+    svg {
+      fill: hsl.contrast($background);
+    }
+  }
+
+  // Disabled comes first so active can properly restyle
+  &.disabled,
+  &:disabled {
+    svg {
+      fill: hsl.contrast($background);
+    }
+  }
+
+  &:not(:disabled):not(.disabled):active,
+  &:not(:disabled):not(.disabled).active,
+  .show > &.dropdown-toggle {
+    svg {
+      fill: hsl.contrast($background);
+    }
+  }
+}

+ 1 - 1
packages/app/src/styles/theme/mixins/_list-group.scss

@@ -63,7 +63,7 @@
     }
     .grw-pagetree-title-anchor {
       .grw-sidebar-text-muted {
-        color: rgba(desaturate($color, 50%), 0.6);
+        // color: rgba(desaturate($color, 50%), 0.6);
       }
     }
   }

+ 0 - 34
packages/app/src/styles/theme/mixins/_tables.scss

@@ -1,34 +0,0 @@
-//== Table
-// $table-variants: (
-//   'light': $light,
-//   'dark': $dark,
-// );
-
-// remove when master version is released
-// show https://github.com/twbs/bootstrap/blob/28cb1ff2b23253293601c51aff434c39b461025e/scss/mixins/_table-variants.scss
-// @mixin table-variant($state, $background) {
-//   .table-#{$state} {
-//     $table-hover-bg-factor: 0.075 !default;
-//     $table-striped-bg-factor: 0.05 !default;
-//     $body-bg: $white !default;
-//     $table-active-bg-factor: 0.1 !default;
-//     $table-border-factor: 0.1 !default;
-
-//     $color: color-contrast(mix(rgba($background, 1), $body-bg, opacity($background) * 100));
-//     $color: gray;
-//     $hover-bg: mix($color, $background, percentage($table-hover-bg-factor));
-//     $striped-bg: mix($color, $background, percentage($table-striped-bg-factor));
-//     $active-bg: mix($color, $background, percentage($table-active-bg-factor));
-
-//     --bs-table-bg: #{$background};
-//     --bs-table-striped-bg: #{$striped-bg};
-//     --bs-table-striped-color: #{color-contrast($striped-bg)};
-//     --bs-table-active-bg: #{$active-bg};
-//     --bs-table-active-color: #{color-contrast($active-bg)};
-//     --bs-table-hover-bg: #{$hover-bg};
-//     --bs-table-hover-color: #{color-contrast($hover-bg)};
-
-//     color: $color;
-//     border-color: mix($color, $background, percentage($table-border-factor));
-//   }
-// }

+ 2 - 0
packages/core/src/index.ts

@@ -14,6 +14,7 @@ export * as pageUtils from './utils/page-utils';
 // export all
 export * from './plugin/interfaces/option-parser';
 export * from './interfaces/attachment';
+export * from './interfaces/color-scheme';
 export * from './interfaces/common';
 export * from './interfaces/growi-facade';
 export * from './interfaces/growi-theme-metadata';
@@ -31,4 +32,5 @@ export * from './models/vo/error-apiv3';
 export * from './service/localstorage-manager';
 export * from './utils/basic-interceptor';
 export * from './utils/browser-utils';
+export * from './utils/growi-theme-metadata';
 export * from './utils/with-utils';

+ 5 - 0
packages/core/src/interfaces/color-scheme.ts

@@ -0,0 +1,5 @@
+export const ColorScheme = {
+  LIGHT: 'light',
+  DARK: 'dark',
+} as const;
+export type ColorScheme = typeof ColorScheme[keyof typeof ColorScheme];

+ 3 - 2
packages/core/src/interfaces/growi-theme-metadata.ts

@@ -1,7 +1,8 @@
+import { ColorScheme } from './color-scheme';
+
 export const GrowiThemeSchemeType = {
+  ...ColorScheme,
   BOTH: 'both',
-  LIGHT: 'light',
-  DARK: 'dark',
 } as const;
 export type GrowiThemeSchemeType = typeof GrowiThemeSchemeType[keyof typeof GrowiThemeSchemeType];
 

+ 8 - 0
packages/core/src/utils/growi-theme-metadata.ts

@@ -0,0 +1,8 @@
+import type { ColorScheme } from '../interfaces/color-scheme';
+import { GrowiThemeSchemeType } from '../interfaces/growi-theme-metadata';
+
+export const getForcedColorScheme = (growiThemeSchemeType?: GrowiThemeSchemeType): ColorScheme | undefined => {
+  return growiThemeSchemeType == null || growiThemeSchemeType === GrowiThemeSchemeType.BOTH
+    ? undefined
+    : growiThemeSchemeType as ColorScheme;
+};

+ 89 - 66
packages/preset-themes/src/styles/antarctic.scss

@@ -1,18 +1,7 @@
 @use './variables' as *;
 @use './bootstrap/variables' as *;
 @use './theme/mixins/page-editor-mode-manager';
-
-// == Define Bootstrap theme colors
-//
-
-// colors for overriding bootstrap $theme-colors
-// $secondary: #;
-// $info: #;
-// $success: #;
-// $warning: #;
-// $danger: #;
-// $light: #;
-// $dark: #;
+@use './theme/hsl-functions' as hsl;
 
 .growi:not(.login-page) {
   // add background-image
@@ -32,84 +21,118 @@
   background-size: cover;
 }
 
-$themecolor: #000080;
-$themelight: #f0f8ff;
-$accentcolor: #ffd700;
-
 .grw-navbar {
-  border-bottom: $accentcolor 4px solid;
+  border-bottom: #ffd700 4px solid;
 }
 
 //== Light Mode
 //
-:root {
-  $primary: $themecolor;
+:root[data-theme='light'] {
+  --primary: hsl(var(--primary-hs),var(--primary-l)) !important;
+  --primary-hs: 240,100%;
+  --primary-l: 25%;
+  --secondary: hsl(var(--secondary-hs),var(--secondary-l)) !important;
+  --secondary-hs: 208,7%;
+  --secondary-l: 46%;
 
   // Background colors
-  $bgcolor-global: $themelight;
-  $bgcolor-inline-code: $gray-100; //optional
-  $bgcolor-card: $gray-50;
-  $bgcolor-blinked-section: rgba($primary, 0.15);
-  //$bgcolor-keyword-highlighted: $grw-marker-yellow;
+  --bgcolor-global: hsl(var(--bgcolor-global-hs),var(--bgcolor-global-l));
+  --bgcolor-global-hs: 208,100%;
+  --bgcolor-global-l: 97%;
+  --bgcolor-inline-code: #{$gray-100}; //optional
+  --bgcolor-card: #{$gray-50};
+  --bgcolor-blinked-section: #{hsl.alpha(var(--primary), 85%)};
+  //--bgcolor-keyword-highlighted: #{$grw-marker-yellow};
 
   // Font colors
-  $color-global: black;
-  $color-reversal: #eeeeee;
-  // $color-header: #2b2b2b;
-  $color-link: lighten($themecolor, 20%);
-  $color-link-hover: lighten($color-link, 20%);
-  $color-link-wiki: lighten($primary, 20%);
-  $color-link-wiki-hover: lighten($color-link-wiki, 20%);
-  $color-link-nabvar: $color-reversal;
-  $color-inline-code: #c7254e; // optional
+  --color-global: hsl(var(--color-global-hs),var(--color-global-l));
+  --color-global-hs: 0,0%;
+  --color-global-l: 0%;
+  --color-reversal: #eeeeee;
+  // --color-header: #2b2b2b;
+  --color-link: #{hsl.lighten(var(--primary), 20%)};
+  --color-link-hs: var(--primary-hs);
+  --color-link-l: calc(var(--primary-l) + 20%);
+  --color-link-hover: #{hsl.lighten(var(--primary), 40%)};
+  --color-link-wiki: #{hsl.lighten(var(--primary), 20%)};
+  --color-link-wiki-hs: var(--primary-hs);
+  --color-link-wiki-l: calc(var(--primary-l) + 20%);
+  --color-link-wiki-hover: l#{hsl.lighten(var(--primary), 40%)};
+  --color-link-nabvar: var(--color-reversal);
+  --color-inline-code: #c7254e; // optional
 
   // List Group colors
-  // $color-list: $color-global;
-  // $bgcolor-list: $bgcolor-global;
-  // $color-list-hover: $color-reversal;
-  // $bgcolor-list-hover: ;
-  // $color-list-active: $color-reversal;
-  // $bgcolor-list-active: $primary;
+  // --color-list: var(--color-global);
+  // --bgcolor-list: var(--bgcolor-global);
+  // --color-list-hover: var(--color-reversal);
+  // --bgcolor-list-hover: ;
+  // --color-list-active: var(--color-reversal);
+  // --bgcolor-list-active: var(--primary);
+
+  // Table colors
+  // --color-table: #; // optional
+  --bgcolor-table: var(--bgcolor-global); // optional
+  // --border-color-table: #; // optional
+  // --color-table-hover: #; // optional
+  // --bgcolor-table-hover: #; // optional
 
   // Navbar
-  $bgcolor-navbar: #35393f;
-  $bgcolor-search-top-dropdown: #fa9913;
-  $border-image-navbar: linear-gradient(to right, #f6d02e 0%, #f87c00 47%, #f6d02e 100%);
+  --bgcolor-navbar: hsl(var(--bgcolor-navbar-hs),var(--bgcolor-navbar-l));
+  --bgcolor-navbar-hs: 216,9%;
+  --bgcolor-navbar-l: 23%;
+  --bgcolor-search-top-dropdown: hsl(var(--bgcolor-search-top-dropdown-hs),var(--bgcolor-search-top-dropdown-l));
+  --bgcolor-search-top-dropdown-hs: 35,96%;
+  --bgcolor-search-top-dropdown-l: 53%;
+  --border-image-navbar: linear-gradient(to right, #f6d02e 0%, #f87c00 47%, #f6d02e 100%);
+
   // Logo colors
-  $bgcolor-logo: $bgcolor-navbar;
-  $fillcolor-logo-mark: lighten(desaturate($bgcolor-inline-code, 10%), 15%);
+  --bgcolor-logo: var(--bgcolor-navbar);
+  --fillcolor-logo-mark: #{lighten(desaturate($gray-100, 10%), 15%)};
 
   // Sidebar
-  $bgcolor-sidebar: $themecolor;
-  $bgcolor-sidebar-nav-item-active: rgba(black, 0.37); // optional
-  $text-shadow-sidebar-nav-item-active: 0px 0px 10px #0099ff; // optional
+  --bgcolor-sidebar: var(--primary);
+  --bgcolor-sidebar-hs: var(--primary-hs);
+  --bgcolor-sidebar-l: var(--primary-l);
+  --bgcolor-sidebar-nav-item-active: rgba(black, 0.37); // optional
+  --text-shadow-sidebar-nav-item-active: 0px 0px 10px #0099ff; // optional
+
   // Sidebar resize button
-  $color-resize-button: $color-reversal;
-  $bgcolor-resize-button: #fa9913;
-  $color-resize-button-hover: $color-reversal;
-  $bgcolor-resize-button-hover: lighten($bgcolor-resize-button, 5%);
+  --color-resize-button: var(--color-reversal);
+  --bgcolor-resize-button: hsl(var(--bgcolor-resize-button-hs),var(--bgcolor-resize-button-l));
+  --bgcolor-resize-button-hs: 35,96%;
+  --bgcolor-resize-button-l: 53%;
+  --color-resize-button-hover: var(--color-reversal);
+  --bgcolor-resize-button-hover: #{hsl.lighten(var(--bgcolor-resize-button), 5%)};
+
   // Sidebar contents
-  $color-sidebar-context: $themecolor;
-  $bgcolor-sidebar-context: #f4f6fc;
+  --color-sidebar-context: var(--primary);
+  --color-sidebar-context-hs: var(--primary-hs);
+  --color-sidebar-context-l: var(--primary-l);
+  --bgcolor-sidebar-context: hsl(var(--bgcolor-sidebar-context-hs),var(--bgcolor-sidebar-context-l));
+  --bgcolor-sidebar-context-hs: 225,57%;
+  --bgcolor-sidebar-context-l: 97%;
+
   // Sidebar list group
-  $bgcolor-sidebar-list-group: #fafbff; // optional
+  --bgcolor-sidebar-list-group: #fafbff; // optional
+
+  // Subnavigation
+  --bgcolor-subnav: hsl(var(--bgcolor-subnav-hs),var(--bgcolor-subnav-l));
+  --bgcolor-subnav-hs: var(--bgcolor-global-hs);
+  --bgcolor-subnav-l: calc(var(--bgcolor-global-l) - 3%);
 
   // Icon colors
-  $color-editor-icons: $color-global;
+  --color-editor-icons: var(--color-global);
 
   // Border colors
-  $border-color-theme: $gray-400;
-  $border-color-global: $gray-400;
-  $bordercolor-inline-code: #ccc8c8; // optional
+  --border-color-theme: #{$gray-400};
+  --border-color-global: #{gray-400};
+  --bordercolor-inline-code: #ccc8c8; // optional
 
   // Dropdown colors
-  $bgcolor-dropdown-link-active: $growi-blue;
+  --bgcolor-dropdown-link-active: #{$growi-blue};
 
   // admin theme box
-  $color-theme-color-box: lighten($themecolor, 20%);
-
-  @import './theme/apply-colors';
-  @import './theme/apply-colors-light';
+  --color-theme-color-box: #{hsl.lighten(var(--primary), 20%)};
 
   &, body {
     background-image: url('../images/antarctic/bg.svg');
@@ -121,16 +144,16 @@ $accentcolor: #ffd700;
   //Button
   .btn-group.grw-page-editor-mode-manager {
     .btn.btn-outline-primary {
-      @include page-editor-mode-manager.btn-page-editor-mode-manager(darken($primary, 10%), lighten($primary, 55%), lighten($primary, 60%));
+      @include page-editor-mode-manager.btn-page-editor-mode-manager(#{hsl.darken(var(--primary), 10%)}, #{hsl.lighten(var(--primary), 55%)}, #{hsl.lighten(var(--primary), 60%)});
     }
   }
 
   .table {
-    background-color: $themelight;
+    background-color:  var(--bgcolor-global);
   }
 
   #search-typeahead-asynctypeahead {
-    background-color: $bgcolor-global;
+    background-color: var(--bgcolor-global);
     .table {
       background-color: transparent;
     }

+ 92 - 64
packages/preset-themes/src/styles/blackboard.scss

@@ -1,99 +1,127 @@
 @use './variables' as *;
 @use './bootstrap/variables' as *;
 @use './theme/mixins/page-editor-mode-manager';
+@use './theme/hsl-functions' as hsl;
 
-:root {
+:root[data-theme='dark']{
   // Theme colors
-  $themecolor: #da8506;
-  $themelight: #223729;
-  $accentcolor: #739aff;
-  $subthemecolor: #192a1f;
-
-  $primary: $themecolor;
-  $dark: #223729;
+  --primary: hsl(var(--primary-hs),var(--primary-l)) !important;
+  --primary-hs: 36,95%;
+  --primary-l: 44%;
+  --secondary: hsl(var(--secondary-hs),var(--secondary-l)) !important;
+  --secondary-hs: 208,7%;
+  --secondary-l: 46%;
+  --subthemecolor: hsl(var(--subthemecolor-hs),var(--subthemecolor-l));
+  --subthemecolor-hs: 141,25%;
+  --subthemecolor-l: 13%;
 
   // Background colors
-  $bgcolor-global: $themelight;
-  $bgcolor-navbar: #563e23;
-  $bgcolor-inline-code: $gray-100; //optional
-  $bgcolor-card: darken($themelight, 5%);
-  $bgcolor-blinked-section: rgba($primary, 0.5);
-  $bgcolor-keyword-highlighted: darken($grw-marker-red, 30%);
+  --bgcolor-global: hsl(var(--bgcolor-global-hs),var(--bgcolor-global-l));
+  --bgcolor-global-hs: 140,24%;
+  --bgcolor-global-l: 17%;
+  --bgcolor-inline-code: #{$gray-100}; //optional
+  --bgcolor-card: #{hsl.darken(var(--bgcolor-global), 5%)};
+  --bgcolor-blinked-section: #{hsl.alpha(var(--primary), 50%)};
+  --bgcolor-keyword-highlighted: #{darken($grw-marker-red, 30%)};
 
   // Font colors
-  $color-global: #ffffff;
-  $color-reversal: $gray-100;
-  $color-link: $accentcolor;
-  $color-link-hover: lighten($color-link, 12%);
-  $color-link-wiki: $accentcolor;
-  $color-link-wiki-hover: lighten($color-link-wiki, 12%);
-  $color-link-nabvar: $color-reversal;
-  $color-inline-code: $subthemecolor;
-  $color-inline-code: #c7254e; // optional
-  $color-search: $dark;
+  --color-global: hsl(var(--color-global-hs),var(--color-global-l));
+  --color-global-hs: 0,0%;
+  --color-global-l: 100%;
+  --color-reversal: var(--gray-100);
+  --color-link: hsl(var(--color-link-hs),var(--color-link-l));
+  --color-link-hs: 223,100%;
+  --color-link-l: 73%;
+  --color-link-hover: #{hsl.lighten(var(--color-link), 12%)};
+  --color-link-wiki: var(--color-link);
+  --color-link-wiki-hs: var(--color-link-hs);
+  --color-link-wiki-l: var(--color-link-l);
+  --color-link-wiki-hover: #{hsl.lighten(var(--color-link), 12%)};
+  --color-link-nabvar: var(--color-reversal);
+  --color-inline-code: var(--subthemecolor);
+  --color-search: $dark;
 
   // List Group colors
-  // $color-list: $color-global;
-  $bgcolor-list: transparent;
-  $color-list-hover: $accentcolor;
-  // $bgcolor-list-hover: lighten($bgcolor-global, 3%);
-  // $color-list-active: $color-reversal;
-  // $bgcolor-list-active: $primary;
+  // --color-list: var(--color-global);
+  --bgcolor-list: transparent;
+  --color-list-hover: var(--color-link);
+  // --bgcolor-list-hover: #{hsl.lighten(var(--bgcolor-global), 3%);
+  // --color-list-active: var(--color-reversal);
+  // --bgcolor-list-active: var(--primary);
+
+  // Table colors
+  // --color-table: #; // optional
+  --bgcolor-table: var(--bgcolor-global); // optional
+  // --border-color-table: #; // optional
+  // --color-table-hover: #; // optional
+  // --bgcolor-table-hover: #; // optional
 
   // Navbar
-  $bgcolor-navbar: #563e23;
-  $bgcolor-search-top-dropdown: $themecolor;
-  $border-image-navbar: linear-gradient(to right, #bebebe 0%, #d8d8d8 100%);
+  --bgcolor-navbar: hsl(var(--bgcolor-navbar-hs),var(--bgcolor-navbar-l));
+  --bgcolor-navbar-hs: 32,42%;
+  --bgcolor-navbar-l: 24%;
+  --bgcolor-search-top-dropdown: var(--primary);
+  --bgcolor-search-top-dropdown-hs: var(--primary-hs);
+  --bgcolor-search-top-dropdown-l: var(--primary-l);
+  --border-image-navbar: linear-gradient(to right, #bebebe 0%, #d8d8d8 100%);
 
   // Logo colors
-  $bgcolor-logo: $color-global;
-  $fillcolor-logo-mark: $color-global;
-  // $fillcolor-logo-mark: #4e5a60;
+  --bgcolor-logo: var(--color-global);
+  --fillcolor-logo-mark: var(--color-global);
 
   // Sidebar
-  $bgcolor-sidebar: #7b5932;
-  // $bgcolor-sidebar-nav-item-active: rgba(#, 0.3); // optional
-  $text-shadow-sidebar-nav-item-active: 0px 0px 10px $primary; // optional
+  --bgcolor-sidebar: hsl(var(--bgcolor-sidebar-hs),var(--bgcolor-sidebar-l));
+  --bgcolor-sidebar-hs: 32,42%;
+  --bgcolor-sidebar-l: 34%;
+  // 00bgcolor-sidebar-nav-item-active: rgba(#, 0.3); // optional
+  --text-shadow-sidebar-nav-item-active: 0px 0px 10px var(--primary); // optional
+
   // Sidebar resize button
-  $color-resize-button: $color-global;
-  $bgcolor-resize-button: $primary;
-  $color-resize-button-hover: $color-global;
-  $bgcolor-resize-button-hover: darken($bgcolor-resize-button, 5%);
+  --color-resize-button: var(--color-global);
+  --bgcolor-resize-button: var(--primary);
+  --bgcolor-resize-button-hs: var(--primary-hs);
+  --bgcolor-resize-button-l: var(--primary-l);
+  --color-resize-button-hover: var(--color-global);
+  --bgcolor-resize-button-hover: #{hsl.darken(var(--color-global), 5%)};
+
   // Sidebar contents
-  $bgcolor-sidebar-context: lighten($subthemecolor, 8%);
-  $color-sidebar-context: $color-global;
+  --color-sidebar-context: var(--color-global);
+  --color-sidebar-context-hs: var(--color-global-hs);
+  --color-sidebar-context-l: var(--color-global-l);
+  --bgcolor-sidebar-context: #{hsl.lighten(var(--subthemecolor),8%)};
+  --bgcolor-sidebar-context-hs: var(--subthemecolor-hs);
+  --bgcolor-sidebar-context-l: calc(var(--subthemecolor-l) + 8%);
+
   // Sidebar list group
-  // $bgcolor-sidebar-list-group: #; // optional
+  // --bgcolor-sidebar-list-group: #; // optional
+
+  // Subnavigation
+  --bgcolor-subnav: hsl(var(--bgcolor-subnav-hs),var(--bgcolor-subnav-l));
+  --bgcolor-subnav-hs: var(--bgcolor-global-hs);
+  --bgcolor-subnav-l: calc(var(--bgcolor-global-l) - 3%);
 
   // Icon colors
-  $color-editor-icons: $color-global;
+  --color-editor-icons: var(--color-global);
 
   // Border colors
-  $border-color-theme: $color-global;
-  $bordercolor-inline-code: #4d4d4d; // optional
-
-  // Dropdown colors
-  $color-dropdown-link-active: $color-global;
-  $color-dropdown-link-hover: $color-reversal;
+  --border-color-theme: var(--color-global);
+  --bordercolor-inline-code: #4d4d4d; // optional
 
   // admin theme box
-  $color-theme-color-box: $primary;
-
-  @import './theme/apply-colors';
-  @import './theme/apply-colors-dark';
+  --color-theme-color-box: var(--primary);
 
   // Navs
   .nav-tabs {
-    border-bottom: $border-color-theme 1px solid;
+    border-bottom: var(--border-color-theme) 1px solid;
     .nav-link {
       &:hover {
-        border-color: lighten($border-color-theme, 10%);
+        border-color: #{hsl.lighten(var(--color-global), 10%)};
         border-bottom: none;
       }
       &.active {
-        color: $color-link;
+        color: var(--color-link);
         background-color: transparent;
-        border-color: $border-color-theme;
+        border-color: var(--border-color-theme);
       }
     }
   }
@@ -101,14 +129,14 @@
   // Table
   .table {
     color: white;
-    background-color: $themelight;
-    border-color: $border-color-theme;
+    background-color: var(--bgcolor-global);
+    border-color: var(--border-color-theme);
   }
 
   // Button
   .btn-group.grw-page-editor-mode-manager {
     .btn.btn-outline-primary {
-      @include page-editor-mode-manager.btn-page-editor-mode-manager(#ffffff, $primary, $primary, darken($primary, 20%));
+      @include page-editor-mode-manager.btn-page-editor-mode-manager(#ffffff, var(--primary), var(--primary), #{hsl.darken(var(--primary), 20%)});
     }
   }
 }

+ 0 - 1
packages/preset-themes/src/styles/bootstrap/_variables.scss

@@ -90,7 +90,6 @@ $border-radius-lg: 8px;
 // Buttons
 //
 // For each of Bootstrap's buttons, define text, background, and border color.
-$btn-link-disabled-color: $gray-500;
 $btn-focus-box-shadow: none;
 $btn-active-box-shadow: none;
 

+ 94 - 77
packages/preset-themes/src/styles/christmas.scss

@@ -1,34 +1,12 @@
 @use './variables' as *;
 @use './bootstrap/variables' as *;
 @use './theme/mixins/page-editor-mode-manager';
-
-// == Define Bootstrap theme colors
-//
-
-// colors for overriding bootstrap $theme-colors
-// $secondary: #;
-// $info: #;
-// $success: #;
-// $warning: #;
-// $danger: #;
-// $light: #;
-// $dark: #;
-
-$themecolor: #b3000c;
-$themelight: white;
-$subthemecolor: #30882c;
-$bgcolor-global: $themelight;
-$linktext: $subthemecolor;
-$linktext-hover: lighten($subthemecolor, 15%);
-$sidebar-text: white;
-$fillcolor-logo-mark: lighten(desaturate($themecolor, 50%), 50%);
-$color-link-wiki: lighten($subthemecolor, 5%);
-$color-link-wiki-hover: lighten($color-link-wiki, 15%);
+@use './theme/hsl-functions' as hsl;
 
 .growi:not(.login-page) {
   // add background-image
   .page-editor-preview-container {
-    background-image: url('/images/themes/christmas/christmas.jpg');
+    background-image: url('../images/christmas/christmas.jpg');
     background-attachment: fixed;
     background-position: center center;
     background-size: cover;
@@ -37,72 +15,110 @@ $color-link-wiki-hover: lighten($color-link-wiki, 15%);
 
 //== Light Mode
 //
-:root {
-  $primary: #d3c665;
+:root[data-theme='light'] {
+  --primary: hsl(var(--primary-hs),var(--primary-l)) !important;
+  --primary-hs: 53,56%;
+  --primary-l: 61%;
+  --secondary: hsl(var(--secondary-hs),var(--secondary-l)) !important;
+  --secondary-hs: 208,7%;
+  --secondary-l: 46%;
+
   // Background colors
-  $bgcolor-card: $gray-50;
-  $bgcolor-inline-code: $gray-100; //optional
-  $bgcolor-blinked-section: rgba($primary, 0.5);
-  //$bgcolor-keyword-highlighted: $grw-marker-yellow;
+  --bgcolor-global: hsl(var(--bgcolor-global-hs),var(--bgcolor-global-l));
+  --bgcolor-global-hs: 0,0%;
+  --bgcolor-global-l: 100%;
+  --bgcolor-card: #{$gray-50};
+  --bgcolor-inline-code: #{$gray-100}; //optional
+  --bgcolor-blinked-section: #{hsl.alpha(var(--primary),50%)};
+  //--bgcolor-keyword-highlighted: #{$grw-marker-yellow};
 
   // Font colors
-  $color-global: #112744;
-  $color-reversal: $gray-100;
-  $color-link: $subthemecolor;
-  $color-link-hover: lighten($color-link, 10%);
-  $color-link-nabvar: $color-reversal;
-  $color-inline-code: #c7254e; // optional
-  $color-modal-header: $themelight;
+  --color-global: hsl(var(--color-global-hs),var(--color-global-l));
+  --color-global-hs: 214,60%;
+  --color-global-l: 17%;
+  --color-reversal: #{$gray-100};
+  --color-link: hsl(var(--color-link-hs),var(--color-link-l));
+  --color-link-hs: 117,51%;
+  --color-link-l: 35%;
+  --color-link-hover: #{hsl.lighten(var(--color-link), 15%)};
+  --color-link-nabvar: var(--color-reversal);
+  --color-link-wiki: #{hsl.lighten(var(--color-link), 5%)};
+  --color-link-wiki-hs: var(--color-link-hs);
+  --color-link-wiki-l: calc(var(--color-link-l) + 5%);
+  --color-link-wiki-hover: #{hsl.lighten(var(--color-link), 20%)};
+  --color-inline-code: #c7254e; // optional
+  --color-modal-header: var(--bgcolor-global);
 
   // Table colors
-  $border-color-table: $gray-400; // optional
+  --border-color-table: #{$gray-400}; // optional
 
   // List Group colors
-  // $color-list: $color-global;
-  $bgcolor-list: transparent;
-  // $color-list-hover: $color-reversal;
-  $color-list-active: $themelight;
-  $bgcolor-list-active: $themecolor;
+  // --color-list: var(--color-global);
+  --bgcolor-list: transparent;
+  // --color-list-hover: var(--color-reversal);
+  --color-list-active: var(--bgcolor-global);
+  --bgcolor-list-active: var(--bgcolor-navbar);
 
   // Navbar
-  $bgcolor-navbar: $themecolor;
-  $bgcolor-search-top-dropdown: $primary;
-  $border-color-navbar-gradient-left: #545fff;
-  $border-color-navbar-gradient-right: #00a6e5;
-  $border-image-navbar: linear-gradient(to right, $primary 0%, $subthemecolor 100%);
+  --bgcolor-navbar: hsl(var(--bgcolor-navbar-hs),var(--bgcolor-navbar-l));
+  --bgcolor-navbar-h: 356;
+  --bgcolor-navbar-s: 100%;
+  --bgcolor-navbar-l: 35%;
+  --bgcolor-navbar-hs: var(--bgcolor-navbar-h),var(--bgcolor-navbar-s);
+  --bgcolor-search-top-dropdown: var(--primary);
+  --bgcolor-search-top-dropdown-hs: var(--primary-hs);
+  --bgcolor-search-top-dropdown-l: var(--primary-l);
+  --border-color-navbar-gradient-left: #545fff;
+  --border-color-navbar-gradient-right: #00a6e5;
+  --border-image-navbar: linear-gradient(to right, var(--primary) 0%, var(--color-link) 100%);
 
   // Logo colors
-  $bgcolor-logo: $themecolor;
+  --bgcolor-logo: var(--bgcolor-navbar);
+  --fillcolor-logo-mark: hsl(var(--bgcolor-navbar-h),calc(var(--bgcolor-navbar-s) - 50%),calc(var(--bgcolor-navbar-l) + 50%));
 
   // Sidebar
-  $bgcolor-sidebar: $subthemecolor;
-  $bgcolor-sidebar-nav-item-active: rgba(black, 0.37); // optional
-  $text-shadow-sidebar-nav-item-active: 0px 0px 10px $primary; // optional
+  --bgcolor-sidebar: var(--color-link);
+  --bgcolor-sidebar-hs: var(--color-link-hs);
+  --bgcolor-sidebar-l: var(--color-link-l);
+  --bgcolor-sidebar-nav-item-active: rgba(black, 0.37); // optional
+  --text-shadow-sidebar-nav-item-active: 0px 0px 10px var(--primary); // optional
+
   // Sidebar resize button
-  $color-resize-button: $color-reversal;
-  $bgcolor-resize-button: $primary;
-  $color-resize-button-hover: $color-reversal;
-  $bgcolor-resize-button-hover: lighten($bgcolor-resize-button, 5%);
-  $color-sidebar-context: $linktext;
-  $bgcolor-sidebar-context: #f4fcf6;
+  --color-resize-button: var(--color-reversal);
+  --bgcolor-resize-button: var(--primary);
+  --bgcolor-resize-button-hs: var(--primary-hs);
+  --bgcolor-resize-button-l: var(--primary-l);
+  --color-resize-button-hover: var(--color-reversal);
+  --bgcolor-resize-button-hover: #{hsl.lighten(var(--primary), 5%)};
+
+  // Sidebar contents
+  --color-sidebar-context: var(--color-link);
+  --color-sidebar-context-hs: var(--color-link-hs);
+  --color-sidebar-context-l: var(--color-link-l);
+  --bgcolor-sidebar-context: hsl(var(--bgcolor-sidebar-context-hs),var(--bgcolor-sidebar-context-l));
+  --bgcolor-sidebar-context-hs: 135,57%;
+  --bgcolor-sidebar-context-l: 97%;
+
   // Sidebar list group
-  $bgcolor-sidebar-list-group: #fafbff; // optional
+  --bgcolor-sidebar-list-group: #fafbff; // optional
+
+  // Subnavigation
+  --bgcolor-subnav: hsl(var(--bgcolor-subnav-hs),var(--bgcolor-subnav-l));
+  --bgcolor-subnav-hs: var(--bgcolor-global-hs);
+  --bgcolor-subnav-l: calc(var(--bgcolor-global-l) - 3%);
 
   // Icon colors
-  $color-editor-icons: $color-global;
+  --color-editor-icons: var(--color-global);  --color-editor-icons: var(--color-global);
 
   // Border colors
-  $border-color-theme: $gray-300; // former: `$navbar-border: $gray-300;`
-  $bordercolor-inline-code: #ccc8c8; // optional
+  --border-color-theme: #{$gray-300}; // former: `$navbar-border: $gray-300;`
+  --bordercolor-inline-code: #ccc8c8; // optional
 
   // Dropdown colors
-  $bgcolor-dropdown-link-active: $themecolor;
+  --bgcolor-dropdown-link-active: var(--bgcolor-navbar);
 
   // admin theme box
-  $color-theme-color-box: lighten($themecolor, 20%);
-
-  @import './theme/apply-colors';
-  @import './theme/apply-colors-light';
+  --color-theme-color-box: #{hsl.lighten(var(--bgcolor-navbar), 20%)};
 
   &, body {
     background-image: url('../images/christmas/christmas.jpg');
@@ -113,15 +129,15 @@ $color-link-wiki-hover: lighten($color-link-wiki, 15%);
   // change color of highlighted header in wiki (default: orange)
 
   .sidebar {
-    background: $themecolor;
+    background: var(--bgcolor-navbar);
   }
 
   .rbt-menu {
-    background: $themelight;
+    background: var(--bgcolor-global);
   }
 
   .page-editor-preview-container {
-    background-image: url('/images/themes/christmas/christmas.jpg');
+    background-image: url('../images/christmas/christmas.jpg');
     background-attachment: fixed;
     background-size: cover;
   }
@@ -158,8 +174,8 @@ $color-link-wiki-hover: lighten($color-link-wiki, 15%);
   * Modal
   */
   .modal-dialog .modal-header.bg-primary {
-    background-image: url('/images/themes/christmas/christmas-navbar.jpg');
-    border-bottom: 2px solid $subthemecolor;
+    background-image: url('../images/christmas/christmas-navbar.jpg');
+    border-bottom: 2px solid var(--color-link);
   }
 
   /*
@@ -167,22 +183,23 @@ $color-link-wiki-hover: lighten($color-link-wiki, 15%);
   */
   .card {
     &.border-primary {
-      border-color: $themecolor !important;
+      border-color: var(--bgcolor-navbar) !important;
     }
     .card-header.bg-primary {
       color: white;
-      background-image: url('/images/themes/christmas/christmas-navbar.jpg') !important;
+      background-image: url('../images/christmas/christmas-navbar.jpg') !important;
     }
   }
 
   .grw-navbar {
-    background-image: url('/images/themes/christmas/christmas-navbar.jpg');
+    background-image: url('../images/christmas/christmas-navbar.jpg');
   }
 
   // Button
-  .grw-page-editor-mode-manager {
+  .btn-group.grw-page-editor-mode-manager {
     .btn.btn-outline-primary {
-      @include page-editor-mode-manager.btn-page-editor-mode-manager(darken($subthemecolor, 15%), lighten($subthemecolor, 35%), lighten($subthemecolor, 45%));
+      @include page-editor-mode-manager.btn-page-editor-mode-manager(#{hsl.darken(var(--color-link), 15%)}, #{hsl.lighten(var(--color-link), 35%)}, #{hsl.lighten(var(--color-link), 45%)});
     }
   }
+
 }

+ 172 - 127
packages/preset-themes/src/styles/default.scss

@@ -1,115 +1,136 @@
 @use './variables' as *;
 @use './bootstrap/variables' as *;
 @use './theme/mixins/page-editor-mode-manager';
-
-// == Define Bootstrap theme colors
-//
-
-// colors for overriding bootstrap $theme-colors
-// $secondary: #;
-// --info: #;
-// --success: #;
-// --warning: #;
-// --danger: #;
-// $light: #;
-// $dark: #;
+@use './theme/hsl-functions' as hsl;
 
 //== Light Mode
 //
 :root[data-theme='light'] {
-  $primary: #122c55;
-  $accent: #209fd8;
+  --primary: hsl(var(--primary-hs),var(--primary-l));
+  --primary-hs: 216.7,65%;
+  --primary-l: 20.2%;
+  --secondary: hsl(var(--secondary-hs),var(--secondary-l));
+  --secondary-hs: 208,7%;
+  --secondary-l: 46%;
+  --accent: hsl(var(--accent-hs),var(--accent-l));
+  --accent-hs: 198.6,74.2%;
+  --accent-l: 48.6%;
 
   // Background colors
-  $bgcolor-global: white;
-  $bgcolor-inline-code: $gray-100; //optional
-  $bgcolor-card: $gray-50;
-  $bgcolor-blinked-section: rgba($primary, 0.1);
-  //$bgcolor-keyword-highlighted: $grw-marker-yellow;
+  --bgcolor-global: hsl(var(--bgcolor-global-hs),var(--bgcolor-global-l));
+  --bgcolor-global-hs: 0,0%;
+  --bgcolor-global-l: 100%;
+  --bgcolor-inline-code: #{$gray-100}; //optional
+  --bgcolor-card: #{$gray-50};
+  --bgcolor-blinked-section: #{hsl.alpha(var(--primary),90%)};
+  // --bgcolor-keyword-highlighted: #{$grw-marker-yellow};
 
   // Font colors
-  $color-global: #112744;
-  $color-reversal: $light;
-  // $color-header: #2b2b2b;
-  $color-link: #1938ba;
-  $color-link-hover: lighten($color-link, 20%);
-  $color-link-wiki: $color-link;
-  $color-link-wiki-hover: lighten($color-link-wiki, 20%);
-  $color-link-nabvar: $gray-500;
-  $color-inline-code: darken($red, 15%); // optional
+  --color-global: hsl(var(--color-global-hs),var(--color-global-l));
+  --color-global-hs: 214.1,60%;
+  --color-global-l: 16.7%;
+  --color-reversal: var(--light);
+  // --color-header: #2b2b2b;
+  --color-link: hsl(var(--color-link-hs),var(--color-link-l));
+  --color-link-hs: 228.4,76.3%;
+  --color-link-l: 41.4%;
+  --color-link-hover: #{hsl.lighten(var(--color-link),20%)};
+  --color-link-wiki: var(--color-link);
+  --color-link-wiki-hs: var(--color-link-hs);
+  --color-link-wiki-l: var(--color-link-l);
+  --color-link-wiki-hover: #{hsl.lighten(var(--color-link-wiki),20%)};
+  --color-link-nabvar: #{$gray-500};
+  --color-inline-code: #{darken($red, 15%)}; // optional
 
   // List Group colors
-  // $color-list: $color-global; // optional
-  // $bgcolor-list: $bgcolor-global; // optional
-  // $color-list-hover: $color-global; // optional
-  // $bgcolor-list-hover: darken($bgcolor-global, 3%); // optional
-  // $color-list-active: $color-reversal; // optional
-  // $bgcolor-list-active: $primary; // optional
+  --color-list: var(--color-global); // optional
+  --bgcolor-list: var(--bgcolor-global); // optional
+  // --color-list-hover: var(--color-global); // optional
+  --bgcolor-list-hover: #{hsl.darken(var(--bgcolor-global),3%)};// optional
+  // --color-list-active: white ; // optional
+  // --bgcolor-list-active: #{hsl.lighten(var(--bgcolor-global),3%)}; // optional
+  // --color-page-list-group-item-meta: #{$gray-500}; // optional
 
   // Table colors
-  // $bgcolor-subnav: #; // optional
-  // $color-table: #; // optional
-  // $bgcolor-table: #; // optional
-  // $border-color-table: #; // optional
-  // $color-table-hover: #; // optional
-  // $bgcolor-table-hover: #; // optional
+  // --color-table: #; // optional
+  // --bgcolor-table: #; // optional
+  // --border-color-table: #; // optional
+  // --color-table-hover: #; // optional
+  // --bgcolor-table-hover: #; // optional
 
   // Navbar
-  $bgcolor-navbar: $gray-900;
-  $bgcolor-search-top-dropdown: $accent;
-  $border-image-navbar: linear-gradient(to right, #36c9ff 0%, #36c9ff 33%, #7926ff 66%, #ff2eff 100%);
+  --bgcolor-navbar: #{$gray-900};
+  --bgcolor-navbar-h:0;
+  --bgcolor-navbar-s:0%;
+  --bgcolor-navbar-l:12.94%;
+  --bgcolor-navbar-hs: 0,0%;
+  --bgcolor-search-top-dropdown: var(--accent);
+  --bgcolor-search-top-dropdown-hs: var(--accent-hs);
+  --bgcolor-search-top-dropdown-l: var(--accent-l);
+  --border-image-navbar: linear-gradient(to right, #36c9ff 0%, #36c9ff 33%, #7926ff 66%, #ff2eff 100%);
 
   // Logo colors
-  $bgcolor-logo: $bgcolor-navbar;
-  $fillcolor-logo-mark: lighten(desaturate($bgcolor-navbar, 10%), 15%);
+  --bgcolor-logo: var(--bgcolor-navbar);
+  --fillcolor-logo-mark: hsl(var(--bgcolor-navbar-h),calc(var(--bgcolor-navbar-s) - 20%),calc(var(--bgcolor-navbar-l) + 15%));
 
   // Sidebar
-  $bgcolor-sidebar: $primary;
-  $bgcolor-sidebar-nav-item-active: rgba(black, 0.37); // optional
-  $text-shadow-sidebar-nav-item-active: 0px 0px 10px #0099ff; // optional
+  --bgcolor-sidebar: var(--primary);
+  --bgcolor-sidebar-hs: var(--primary-hs);
+  --bgcolor-sidebar-l: var(--primary-l);
+  --bgcolor-sidebar-nav-item-active: rgba(black, 0.37); // optional
+  --text-shadow-sidebar-nav-item-active: 0px 0px 10px #0099ff; // optional
+
   // Sidebar resize button
-  $color-resize-button: $color-reversal;
-  $bgcolor-resize-button: $accent;
-  $color-resize-button-hover: $color-reversal;
-  $bgcolor-resize-button-hover: lighten($bgcolor-resize-button, 5%);
+  --color-resize-button: var(--color-reversal);
+  --bgcolor-resize-button: var(--accent);
+  --bgcolor-resize-button-hs: var(--accent-hs);
+  --bgcolor-resize-button-l: var(--accent-l);
+  --color-resize-button-hover: var(--color-reversal);
+  --bgcolor-resize-button-hover: #{hsl.lighten(var(--accent), 5%)};
+
   // Sidebar contents
-  $color-sidebar-context: $color-global;
-  $bgcolor-sidebar-context: lighten($primary, 77%);
+  --color-sidebar-context: var(--color-global);
+  --color-sidebar-context-hs: var(--color-global-hs);
+  --color-sidebar-context-l: var(--color-global-l);
+  --bgcolor-sidebar-context: #{hsl.lighten(var(--primary),77%)};
+  --bgcolor-sidebar-context-hs: var(--primary-hs);
+  --bgcolor-sidebar-context-l: calc(var(--primary-l) + 77%);
+
   // Sidebar list group
-  $bgcolor-sidebar-list-group: $gray-50; // optional
+  // --bgcolor-sidebar-list-group: #{$gray-50}; // optional
 
   // Subnavigation
-  // $bgcolor-subnav: #fafafa; // optional
+  --bgcolor-subnav: hsl(var(--bgcolor-subnav-hs),var(--bgcolor-subnav-l));
+  --bgcolor-subnav-hs: var(--bgcolor-global-hs);
+  --bgcolor-subnav-l: calc(var(--bgcolor-global-l) - 3%);
 
   // Tabs
-  // $color-nav-tabs-link-active: #; //optional
-  // $bordercolor-nav-tabs-hover: # # $bordercolor-nav-tabs; // optional
-  // $bordercolor-nav-tabs-active: # # $bgcolor-global; // optional
+  // --bordercolor-nav-tabs: #{$gray-300}; // optional
+  // --color-nav-tabs-link-active: #; //optional
+  // --bordercolor-nav-tabs-hover: # # $bordercolor-nav-tabs; // optional
+  // --bordercolor-nav-tabs-active: # # // optional
 
   // Tags
-  // $color-tags: #; //optional
-  // $bgcolor-tags: #; //optional
+  // --color-tags: #; //optional
+  // --bgcolor-tags: #; //optional
 
   // Icon colors
-  $color-editor-icons: $color-global;
+  --color-editor-icons: var(--color-global);
 
   // Border colors
-  $border-color-theme: $gray-400;
-  $bordercolor-inline-code: $gray-400; // optional
+  --border-color-theme: #{$gray-400};
+  --bordercolor-inline-code: #{$gray-400}; // optional
 
   // Dropdown colors
-  $bgcolor-dropdown-link-active: $growi-blue;
+  --bgcolor-dropdown-link-active: #{$growi-blue};
 
   // admin theme box
-  $color-theme-color-box: lighten($primary, 20%);
-
-  @import './theme/apply-colors';
-  @import './theme/apply-colors-light';
+  --color-theme-color-box: #{hsl.lighten(var(--primary), 20%)};
 
   // Button
   .btn-group.grw-page-editor-mode-manager {
     .btn.btn-outline-primary {
-      @include page-editor-mode-manager.btn-page-editor-mode-manager($primary, lighten($primary, 65%), lighten($primary, 70%));
+      @include page-editor-mode-manager.btn-page-editor-mode-manager (var(--primary),#{hsl.lighten(var(--primary),65%)}, #{hsl.lighten(var(--primary),70%)});
     }
   }
 }
@@ -117,96 +138,120 @@
 //== Dark Mode
 //
 :root[data-theme='dark'] {
-  $primary: #115cd3;
-  $accent: #db00c2;
+  --primary: hsl(var(--primary-hs),var(--primary-l));
+  --primary-hs: 216.8,85.1%;
+  --primary-l: 44.7%;
+  --secondary: hsl(var(--secondary-hs),var(--secondary-l));
+  --secondary-hs: 208,7%;
+  --secondary-l: 46%;
+  --accent: hsl(var(--accent-hs),var(--accent-l));
+  --accent-hs: 307,100%;
+  --accent-l: 43%;
 
   // Background colors
-  $bgcolor-global: #131418;
-  $bgcolor-inline-code: #1f1f22; //optional
-  $bgcolor-card: darken($bgcolor-global, 5%);
-  $bgcolor-blinked-section: rgba($primary, 0.4);
-  $bgcolor-keyword-highlighted: darken($grw-marker-red, 30%);
+  --bgcolor-global: hsl(var(--bgcolor-global-hs),var(--bgcolor-global-l));
+  --bgcolor-global-hs: 228,12%;
+  --bgcolor-global-l: 8%;
+  --bgcolor-inline-code: #1f1f22; //optional
+  --bgcolor-card: #{hsl.darken(var(--bgcolor-global),5%)};
+  --bgcolor-blinked-section: #{hsl.alpha(var(--primary), 60%)};
+  --bgcolor-keyword-highlighted: #{darken($grw-marker-red, 30%)};
 
   // Font colors
-  $color-global: $gray-400;
-  $color-reversal: $gray-900;
-  // $color-header: desaturate($primary, 20%);
-  $color-link: #7b9ad5;
-  $color-link-hover: lighten($color-link, 10%);
-  $color-link-wiki: $color-link;
-  $color-link-wiki-hover: lighten($color-link-wiki, 10%);
-  $color-link-nabvar: #a7a7a7;
-  $color-inline-code: #c7254e; // optional
+  --color-global: hsl(var(--color-global-hs),var(--color-global-l));
+  --color-global-hs: 0,0%;
+  --color-global-l: 74%;
+  --color-reversal: #{$gray-900};
+  // --color-header: desaturate($primary, 20%);
+  --color-link: hsl(var(--color-link-hs),var(--color-link-l));
+  --color-link-hs: 219.3,51.7%;
+  --color-link-l: 65.9%;
+  --color-link-hover: #{hsl.lighten(var(--color-link),10%)};
+  --color-link-wiki: var(--color-link);
+  --color-link-wiki-hs: var(--color-link-hs);
+  --color-link-wiki-l: var(--color-link-l);
+  --color-link-wiki-hover: #{hsl.lighten(var(--color-link-wiki),10%)};
+  --color-link-nabvar: #a7a7a7;
+  --color-inline-code: #c7254e; // optional
 
   // List Group colors
-  // $color-list: $color-global; // optional
-  // $bgcolor-list: $bgcolor-global; // optional
-  // $color-list-hover: $color-global; // optional
-  // $bgcolor-list-hover: lighten($bgcolor-global, 3%); // optional
-  // $color-list-active:white ; // optional
-  // $bgcolor-list-active: $primary; // optional
+  --color-list: var(--color-global); // optional
+  --bgcolor-list: var(--bgcolor-global); // optional
+  // --color-list-hover: var(--color-global); // optional
+  --bgcolor-list-hover: #{hsl.lighten(var(--bgcolor-global),3%)}; // optional
+  // --color-list-active: white ; // optional
+  // --bgcolor-list-active: var(--primary); // optional
 
   // Table colors
-  // $color-table: #; // optional
-  // $bgcolor-table: #; // optional
-  // $border-color-table: #; // optional
-  // $color-table-hover: #; // optional
-  // $bgcolor-table-hover: #; // optional
+  // --color-table: #; // optional
+  // --bgcolor-table: #; // optional
+  // --border-color-table: #; // optional
+  // --color-table-hover: #; // optional
+  // --bgcolor-table-hover: #; // optional
 
   // Navbar
-  $bgcolor-navbar: #2a2929;
-  $bgcolor-search-top-dropdown: $accent;
-  $border-image-navbar: linear-gradient(to right, #44bfe3 0%, #b04aff 50%, #ff1794 100%);
+  --bgcolor-navbar: #2a2929;
+  --bgcolor-search-top-dropdown: var(--accent);
+  --bgcolor-search-top-dropdown-hs: var(--accent-hs);
+  --bgcolor-search-top-dropdown-l: var(--accent-l);
+  --border-image-navbar: linear-gradient(to right, #44bfe3 0%, #b04aff 50%, #ff1794 100%);
 
   // Logo colors
-  $bgcolor-logo: $bgcolor-navbar;
-  $fillcolor-logo-mark: $gray-700;
+  --bgcolor-logo: var(--bgcolor-navbar);
+  --fillcolor-logo-mark: #{$gray-700};
 
   // Sidebar
-  $bgcolor-sidebar: #122c55;
-  $bgcolor-sidebar-nav-item-active: rgba(#969494, 0.3); // optional
-  $text-shadow-sidebar-nav-item-active: 0px 0px 10px #0099ff; // optional
+  --bgcolor-sidebar: hsl(var(--bgcolor-sidebar-hs),var(--bgcolor-sidebar-l));
+  --bgcolor-sidebar-hs: 216.7,65%;
+  --bgcolor-sidebar-l: 20.2%;
+  --bgcolor-sidebar-nav-item-active: rgba(#969494, 0.3); // optional
+  --text-shadow-sidebar-nav-item-active: 0px 0px 10px #0099ff; // optional
+  --bgcolor-sidebar-context: hsl(var(--bgcolor-sidebar-context-hs),var(--bgcolor-sidebar-context-l));
+  --bgcolor-sidebar-context-hs: 228,12%;
+  --bgcolor-sidebar-context-l: 16%;
   // Sidebar resize button
-  $color-resize-button: white;
-  $bgcolor-resize-button: $accent;
-  $color-resize-button-hover: white;
-  $bgcolor-resize-button-hover: darken($bgcolor-resize-button, 5%);
+  --color-resize-button: white;
+  --bgcolor-resize-button: var(--accent);
+  --color-resize-button-hover: white;
+  --bgcolor-resize-button-hover: #{hsl.darken(var(--accent), 5%)};
   // Sidebar contents
-  $bgcolor-sidebar-context: lighten($bgcolor-global, 8%);
-  $color-sidebar-context: $color-global;
+  --color-sidebar-context: var(--color-global);
+  --color-sidebar-context-hs: var(--color-global-hs);
+  --color-sidebar-context-l: var(--color-global-l);
   // Sidebar list group
-  $bgcolor-sidebar-list-group: #1c2a3e; // optional
+  // --bgcolor-sidebar-list-group: #1c2a3e; // optional
 
   // Subnavigation
-  $bgcolor-subnav: lighten($bgcolor-global, 4%); // optional
+  --bgcolor-subnav: hsl(var(--bgcolor-subnav-hs),var(--bgcolor-subnav-l));
+  --bgcolor-subnav-hs: var(--bgcolor-global-hs);
+  --bgcolor-subnav-l: calc(var(--bgcolor-global-l) + 4%);
 
   // Tabs
-  $bordercolor-nav-tabs: $gray-700; // optional
-  // $color-nav-tabs-link-active: #; //optional
-  $bordercolor-nav-tabs-hover: #666 #666 $bordercolor-nav-tabs; // optional
-  // $bordercolor-nav-tabs-active: # # $bgcolor-global; // optional
+  --bordercolor-nav-tabs: #{$gray-700}; // optional
+  // --color-nav-tabs-link-active: #; //optional
+  --bordercolor-nav-tabs-hover: #666 #666 var(--bordercolor-nav-tabs); // optional
+  --bordercolor-nav-tabs-active: var(--bordercolor-nav-tabs) var(--bordercolor-nav-tabs) var(--bgcolor-global); // optional
 
   // Tags
-  // $color-tags: #; //optional
-  // $bgcolor-tags: #; //optional
+  // --color-tags: #; //optional
+  // --bgcolor-tags: #; //optional
 
   // Icon colors
-  $color-editor-icons: $color-global;
+  --color-editor-icons: var(--color-global);
 
   // Border colors
-  $border-color-theme: $gray-400;
-  $bordercolor-inline-code: $secondary; // optional
+  --border-color-theme: hsl(var(--border-color-theme-hs),var(--border-color-theme-l));
+  --border-color-theme-hs: 210,13%;
+  --border-color-theme-l: 71%;
+  --bordercolor-inline-code: var(--secondary); // optional
 
   // admin theme box
-  $color-theme-color-box: $primary;
-
-  @import './theme/apply-colors';
-  @import './theme/apply-colors-dark';
+  --color-theme-color-box: var(--primary);
 
   //Button
   .btn-group.grw-page-editor-mode-manager {
     .btn.btn-outline-primary {
-      @include page-editor-mode-manager.btn-page-editor-mode-manager(lighten($primary, 30%), lighten($primary, 20%), $primary, darken($primary, 20%));
+      @include page-editor-mode-manager.btn-page-editor-mode-manager(#{hsl.lighten(var(--primary), 30%)}, #{hsl.lighten(var(--primary), 20%)}, var(--primary), #{hsl.darken(var(--primary), 20%)});
     }
   }
 }

+ 180 - 112
packages/preset-themes/src/styles/fire-red.scss

@@ -1,85 +1,114 @@
 @use './variables' as *;
 @use './bootstrap/variables' as *;
 @use './theme/mixins/page-editor-mode-manager';
+@use './theme/hsl-functions' as hsl;
 
 :root[data-theme='light'] {
   // Theme colors
-  $themecolor: #ea5532;
-  $themelight: #ffffff;
-  $accentcolor: #bfbfbf;
-  $subthemecolor: #e6e6e6;
-
-  $primary: $themecolor;
+  --primary: hsl(var(--primary-hs),var(--primary-l)) !important;
+  --primary-hs: 11,81%;
+  --primary-l: 56%;
+  --secondary: hsl(var(--secondary-hs),var(--secondary-l)) !important;
+  --secondary-hs: 208,7%;
+  --secondary-l: 46%;
+  --accentcolor: hsl(var(--accentcolor-hs),var(--accentcolor-l));
+  --accentcolor-hs: 0,0%;
+  --accentcolor-l: 75%;
 
   // Background colors
-  $bgcolor-global: $themelight;
-  $bgcolor-inline-code: $gray-100; //optional
-  $bgcolor-card: $accentcolor;
-  $bgcolor-blinked-section: rgba($primary, 0.1);
-  //$bgcolor-keyword-highlighted: $grw-marker-yellow;
+  --bgcolor-global: hsl(var(--bgcolor-global-hs),var(--bgcolor-global-l));
+  --bgcolor-global-hs: 0,0%;
+  --bgcolor-global-l: 100%;
+  --bgcolor-inline-code: #{$gray-100}; //optional
+  --bgcolor-card: var(--accentcolor);
+  --bgcolor-blinked-section: #{hsl.alpha(var(--primary),90%)};
+  //--bgcolor-keyword-highlighted: #{$grw-marker-yellow};
 
   // Font colors
-  $color-global: #2c2c2c;
-  $color-reversal: $gray-100;
-  $color-link: $primary;
-  $color-link-hover: lighten($color-link, 12%);
-  $color-link-wiki: $primary;
-  $color-link-wiki-hover: lighten($color-link-wiki, 12%);
-  $color-link-nabvar: $color-reversal;
-  $color-inline-code: #c7254e; // optional
-  $color-search: $color-global;
+  --color-global: hsl(var(--color-global-hs),var(--color-global-l));
+  --color-global-hs: 0,0%;
+  --color-global-l: 17%;
+  --color-reversal: #{$gray-100};
+  --color-link: var(--primary);
+  --color-link-hs: var(--primary-hs);
+  --color-link-l: var(--primary-l);
+  --color-link-hover: #{hsl.lighten(var(--primary), 12%)};
+  --color-link-wiki: var(--primary);
+  --color-link-wiki-hs: var(--primary-hs);
+  --color-link-wiki-l: var(--primary-l);
+  --color-link-wiki-hover: #{hsl.lighten(var(--primary), 12%)};
+  --color-link-nabvar: var(--color-reversal);
+  --color-inline-code: #c7254e; // optional
+  --color-search: var(--color-global);
 
   // List Group colors
-  // $color-list: $color-global;
-  $bgcolor-list: transparent;
-  $color-list-hover: $color-search;
-  $bgcolor-list-hover: darken($bgcolor-global, 3%);
-  // $color-list-active: $color-reversal;
-  // $bgcolor-list-active: $primary;
+  // --color-list: var(--color-global);
+  --bgcolor-list: transparent;
+  --color-list-hover: var(--color-global);
+  --bgcolor-list-hover: #{hsl.darken(var(--bgcolor-global),3%)};
+  // --color-list-active: var(--color-reversal);
+  // --bgcolor-list-active: var(--primary);
 
   // Navbar
-  $bgcolor-navbar: $color-global;
-  $bgcolor-search-top-dropdown: $themecolor;
-  $border-image-navbar: linear-gradient(to right, $primary 0%, darken($primary, 5%) 100%);
+  --bgcolor-navbar: var(--color-global);
+  --bgcolor-navbar-hs: var(--color-global-hs);
+  --bgcolor-navbar-l: var(--color-global-l);
+  --bgcolor-search-top-dropdown: var(--primary);
+  --bgcolor-search-top-dropdown-hs: var(--primary-hs);
+  --bgcolor-search-top-dropdown-l: var(--primary-l);
+  --border-image-navbar: linear-gradient(to right, var(--primary) 0%, #{hsl.darken(var(--primary), 5%)} 100%);
 
   // Logo colors
-  $bgcolor-logo: $themelight;
-  $fillcolor-logo-mark: $themelight;
+  --bgcolor-logo: var(--bgcolor-global);
+  --fillcolor-logo-mark: var(--bgcolor-global);
 
   // Sidebar
-  $bgcolor-sidebar: $accentcolor;
-  // $bgcolor-sidebar-nav-item-active: rgba(#, 0.37); // optional
-  $text-shadow-sidebar-nav-item-active: 0px 0px 10px #ffffff; // optional
+  --bgcolor-sidebar: var(--accentcolor);
+  --bgcolor-sidebar-hs: var(--accentcolor-hs);
+  --bgcolor-sidebar-l: var(--accentcolor-l);
+  // --bgcolor-sidebar-nav-item-active: rgba(#, 0.37); // optional
+  --text-shadow-sidebar-nav-item-active: 0px 0px 10px #ffffff; // optional
+
   // Sidebar resize button
-  $color-resize-button: #ffffff;
-  $bgcolor-resize-button: $primary;
-  $color-resize-button-hover: $color-reversal;
-  $bgcolor-resize-button-hover: lighten($bgcolor-resize-button, 5%);
+  --color-resize-button: #ffffff;
+  --bgcolor-resize-button: var(--primary);
+  --bgcolor-sidebar-context-hs: var(--primary-hs);
+  --bgcolor-sidebar-context-l: var(--primary-l);
+  --color-resize-button-hover: var(--color-reversal);
+  --bgcolor-resize-button-hover: #{hsl.lighten(var(--primary), 5%)};
+
   // Sidebar contents
-  $color-sidebar-context: $color-global;
-  $bgcolor-sidebar-context: #ececec;
+  --color-sidebar-context: var(--color-global);
+  --color-sidebar-context-hs: var(--color-global-hs);
+  --color-sidebar-context-l: var(--color-global-l);
+  --bgcolor-sidebar-context: hsl(var(--bgcolor-sidebar-context-hs),var(--bgcolor-sidebar-context-l));
+  --bgcolor-sidebar-context-hs: 0,0%;
+  --bgcolor-sidebar-context-l: 93%;
+
   // Sidebar list group
-  // $bgcolor-sidebar-list-group: #; // optional
+  // --bgcolor-sidebar-list-group: #; // optional
+
+  // Subnavigation
+  --bgcolor-subnav: hsl(var(--bgcolor-subnav-hs),var(--bgcolor-subnav-l));
+  --bgcolor-subnav-hs: var(--bgcolor-global-hs);
+  --bgcolor-subnav-l: calc(var(--bgcolor-global-l) - 3%);
 
   // Icon colors
-  $color-editor-icons: $color-global;
+  --color-editor-icons: var(--color-global);
 
   // Border colors
-  $border-color-theme: $primary;
-  $bordercolor-inline-code: #ccc8c8; // optional
+  --border-color-theme: var(--primary);
+  --bordercolor-inline-code: #ccc8c8; // optional
 
   // admin theme box
-  $color-theme-color-box: $primary;
-
-  @import './theme/apply-colors';
-  @import './theme/apply-colors-light';
+  --color-theme-color-box: var(--primary);
 
   // Navs {
   .nav-tabs {
-    border-bottom: $border-color-theme 1px solid;
+    border-bottom: var(--primary) 1px solid;
     .nav-link {
       &:hover {
-        border-color: lighten($border-color-theme, 10%);
+        border-color: #{hsl.lighten(var(--primary), 10%)};
         border-bottom: none;
       }
       &.active {
@@ -87,106 +116,136 @@
       }
     }
   }
+
   // Button
   .btn-group.grw-page-editor-mode-manager {
     .btn.btn-outline-primary {
-      @include page-editor-mode-manager.btn-page-editor-mode-manager(#ffffff, $primary, $primary, lighten($primary, 20%));
+      @include page-editor-mode-manager.btn-page-editor-mode-manager(#ffffff, var(--primary), var(--primary), #{hsl.lighten(var(--primary), 20%)});
     }
   }
+
+  .grw-global-search .btn-secondary.dropdown-toggle {
+    color: white;
+  }
+
+  .btn-primary {
+    color:white !important;
+  }
 }
 
 :root[data-theme='dark'] {
   // Theme colors
-  $themecolor: #ea5532;
-  $themedark: #333333;
-  $accentcolor: #212121;
-  $subthemecolor: #2e2e2e;
-
-  $primary: #ea5532;
-  $dark: #a7a7a7;
+  --primary: hsl(var(--primary-hs),var(--primary-l)) !important;
+  --primary-hs: 11,81%;
+  --primary-l: 56%;
+  --secondary: hsl(var(--secondary-hs),var(--secondary-l)) !important;
+  --secondary-hs: 208,7%;
+  --secondary-l: 46%;
+  --accentcolor: hsl(var(--accentcolor-hs),var(--accentcolor-l));
+  --accentcolor-hs: 0,0%;
+  --accentcolor-l: 13%;
 
   // Background colors
-  $bgcolor-global: $themedark;
-  $bgcolor-navbar: #2b2b2b;
-  $bgcolor-inline-code: $gray-100; //optional
-  $bgcolor-card: darken($themedark, 5%);
-  $bgcolor-blinked-section: rgba($primary, 0.5);
-  $bgcolor-keyword-highlighted: darken($grw-marker-red, 30%);
+  --bgcolor-global: hsl(var(--bgcolor-global-hs),var(--bgcolor-global-l));
+  --bgcolor-global-hs: 0,0%;
+  --bgcolor-global-l: 20%;
+  --bgcolor-inline-code: #{$gray-100}; //optional
+  --bgcolor-card: #{hsl.darken(var(--bgcolor-global), 5%)};
+  --bgcolor-blinked-section: #{hsl.alpha(var(--primary),50%)};
+  --bgcolor-keyword-highlighted: #{darken($grw-marker-red, 30%)};
 
   // Font colors
-  $color-global: #ffffff;
-  $color-reversal: $gray-100;
-  $color-link: $primary;
-  $color-link-hover: lighten($color-link, 12%);
-  $color-link-wiki: $primary;
-  $color-link-wiki-hover: lighten($color-link-wiki, 12%);
-  $color-link-nabvar: $color-reversal;
-  $color-inline-code: $subthemecolor;
-  $color-inline-code: #c7254e; // optional
-  $color-search: $dark;
+  --color-global: hsl(var(--color-global-hs),var(--color-global-l));
+  --color-global-hs: 0,0%;
+  --color-global-l: 100%;
+  --color-reversal: #{$gray-100};
+  --color-link: var(--primary);
+  --color-link-hs: var(--primary-hs);
+  --color-link-l: var(--primary-l);
+  --color-link-hover: #{hsl.lighten(var(--color-link),12%)};
+  --color-link-wiki: var(--primary);
+  --color-link-wiki-hs: var(--primary-hs);
+  --color-link-wiki-l: var(--primary-l);
+  --color-link-wiki-hover: #{hsl.lighten(var(--color-link),12%)};
+  --color-link-nabvar: var(--color-reversal);
+  --color-inline-code: #c7254e; // optional
+  --color-search: #a7a7a7;
 
   // List Group colors
-  // $color-list: $color-global;
-  $bgcolor-list: transparent;
-  $color-list-hover: $accentcolor;
-  // $bgcolor-list-hover: lighten($bgcolor-global, 3%);
-  // $color-list-active: $color-reversal;
-  // $bgcolor-list-active: $primary;
+  // --color-list: var(--color-global);
+  --bgcolor-list: transparent;
+  --color-list-hover: var(--accentcolor);
+  // --bgcolor-list-hover: #{hsl.darken(var(--bgcolor-global),3%)};// optional
+  // --color-list-active: white ; // optional
+  // --bgcolor-list-active: #{hsl.lighten(var(--bgcolor-global),3%)}; // optional
 
   // Navbar
-  $bgcolor-navbar: #2c2c2c;
-  $bgcolor-search-top-dropdown: $themecolor;
-  $border-image-navbar: linear-gradient(to right, #ea5532 0%, #c9171e 100%);
+  --bgcolor-navbar: hsl(var(--bgcolor-navbar-hs),var(--bgcolor-navbar-l));
+  --bgcolor-navbar-hs: 0,0%;
+  --bgcolor-navbar-l: 17%;
+  --bgcolor-search-top-dropdown: var(--primary);
+  --bgcolor-search-top-dropdown-hs: var(--primary-hs);
+  --bgcolor-search-top-dropdown-l: var(--primary-l);
+  --border-image-navbar: linear-gradient(to right, #ea5532 0%, #c9171e 100%);
 
   // Logo colors
-  $bgcolor-logo: #ffffff;
-  $fillcolor-logo-mark: #ffffff;
-  // $fillcolor-logo-mark: #4e5a60;
+  --bgcolor-logo: var(--color-global);
+  --fillcolor-logo-mark: var(--color-global);
+  // --fillcolor-logo-mark: #4e5a60;
 
   // Sidebar
-  $bgcolor-sidebar: $accentcolor;
-  // $bgcolor-sidebar-nav-item-active: rgba(#, 0.3); // optional
-  $text-shadow-sidebar-nav-item-active: 0px 0px 10px $primary; // optional
+  --bgcolor-sidebar: var(--accentcolor);
+  --bgcolor-sidebar-hs: var(--accentcolor-hs);
+  --bgcolor-sidebar-l: var(--accentcolor-l);
+  // --bgcolor-sidebar-nav-item-active: rgba(#, 0.3); // optional
+  --text-shadow-sidebar-nav-item-active: 0px 0px 10px var(--primary); // optional
+
   // Sidebar resize button
-  $color-resize-button: $color-global;
-  $bgcolor-resize-button: $primary;
-  $color-resize-button-hover: $color-global;
-  $bgcolor-resize-button-hover: darken($bgcolor-resize-button, 5%);
+  --color-resize-button: var(--color-global);
+  --bgcolor-resize-button: var(--primary);
+  --bgcolor-resize-button-hs: var(--primary-hs);
+  --bgcolor-resize-button-l: var(--primary-l);
+  --color-resize-button-hover: var(--color-global);
+  --bgcolor-resize-button-hover: #{hsl.darken(var(--primary), 5%)};
+
   // Sidebar contents
-  $bgcolor-sidebar-context: #413f3f;
-  $color-sidebar-context: $color-global;
+  --color-sidebar-context: var(--color-global);
+  --color-sidebar-context-hs: var(--color-global-hs);
+  --color-sidebar-context-l: var(--color-global-l);
+  --bgcolor-sidebar-context: hsl(var(--bgcolor-sidebar-context-hs),var(--bgcolor-sidebar-context-l));
+  --bgcolor-sidebar-context-hs: 0,2%;
+  --bgcolor-sidebar-context-l: 25%;
+
   // Sidebar list group
-  // $bgcolor-sidebar-list-group: #; // optional
+  // --bgcolor-sidebar-list-group: #; // optional
+
+  // Subnavigation
+  --bgcolor-subnav: hsl(var(--bgcolor-subnav-hs),var(--bgcolor-subnav-l));
+  --bgcolor-subnav-hs: var(--bgcolor-global-hs);
+  --bgcolor-subnav-l: calc(var(--bgcolor-global-l) - 3%);
 
   // Icon colors
-  $color-editor-icons: $color-global;
+  --color-editor-icons: var(--color-global);
 
   // Border colors
-  $border-color-theme: $primary;
-  $bordercolor-inline-code: #4d4d4d; // optional
-
-  // Dropdown colors
-  $color-dropdown-link-active: $color-global;
-  $color-dropdown-link-hover: $color-reversal;
+  --border-color-theme: var(--primary);
+  --bordercolor-inline-code: #4d4d4d; // optional
 
   // admin theme box
-  $color-theme-color-box: $primary;
-
-  @import './theme/apply-colors';
-  @import './theme/apply-colors-dark';
+  --color-theme-color-box: var(--primary);
 
   // Navs
   .nav-tabs {
-    border-bottom: $border-color-theme 1px solid;
+    border-bottom: var(--primary) 1px solid;
     .nav-link {
       &:hover {
-        border-color: lighten($border-color-theme, 10%);
+        border-color: #{hsl.lighten(var(--primary), 10%)};
         border-bottom: none;
       }
       &.active {
-        color: $color-link;
+        color: var(--primary);
         background-color: transparent;
-        border-color: $border-color-theme;
+        border-color: var(--primary);
       }
     }
   }
@@ -199,7 +258,16 @@
   // Button
   .btn-group.grw-page-editor-mode-manager {
     .btn.btn-outline-primary {
-      @include page-editor-mode-manager.btn-page-editor-mode-manager(#ffffff, $primary, $primary, darken($primary, 20%));
+      @include page-editor-mode-manager.btn-page-editor-mode-manager(#ffffff, var(--primary), var(--primary), #{hsl.darken(var(--primary), 20%)});
     }
   }
+
+  .grw-global-search .btn-secondary.dropdown-toggle {
+    color: white;
+  }
+
+  .btn-primary {
+    color:white !important;
+  }
+
 }

+ 92 - 58
packages/preset-themes/src/styles/future.scss

@@ -1,95 +1,129 @@
 @use './variables' as *;
 @use './bootstrap/variables' as *;
 @use './theme/mixins/page-editor-mode-manager';
+@use './theme/hsl-functions' as hsl;
+
+:root[data-theme='dark']{
+  --primary: hsl(var(--primary-hs),var(--primary-l)) !important;
+  --primary-hs: 181,100%;
+  --primary-l: 36%;
+  --secondary: hsl(var(--secondary-hs),var(--secondary-l)) !important;
+  --secondary-hs: 208,7%;
+  --secondary-l: 46%;
+  --themecolor: hsl(var(--themecolor-hs),var(--themecolor-l));
+  --themecolor-hs: 193,34%;
+  --themecolor-l: 13%;
+  --accentcolor: hsl(var(--accentcolor-hs),var(--accentcolor-l));
+  --accentcolor-hs: 178,100%;
+  --accentcolor-l: 50%;
 
-$primary: #00b5b7;
-$themecolor: #16282d;
-$accentcolor: #00fff5;
-
-:root {
   // Background colors
-  $bgcolor-global: $themecolor;
-  $bgcolor-inline-code: #1f1f22; //optional
-  $bgcolor-card: darken($themecolor, 5%);
-  $bgcolor-blinked-section: rgba($primary, 0.4);
-  $bgcolor-keyword-highlighted: darken($grw-marker-red, 30%);
+  --bgcolor-global: var(--themecolor);
+  --bgcolor-inline-code: #1f1f22; //optional
+  --bgcolor-card: #{hsl.darken(var(--themecolor), 5%)};
+  --bgcolor-blinked-section: #{hsl.alpha(var(--primary), 60%)};
+  --bgcolor-keyword-highlighted: #{darken($grw-marker-red, 30%)};
 
   // Font colors
-  $color-global: #95abba;
-  $color-reversal: $gray-900;
-  $color-header: #95abba;
-  $color-link: $accentcolor;
-  $color-link-hover: lighten($color-link, 20%);
-  $color-link-wiki: $accentcolor;
-  $color-link-wiki-hover: darken($color-link-wiki, 5%);
-  $color-link-nabvar: #a7a7a7;
-  $color-inline-code: #c7254e; // optional
-  $color-search: $primary;
+  --color-global: #{hsl(var(--color-global-hs),var(--color-global-l))};
+  --color-global-hs: 204,21%;
+  --color-global-l: 66%;
+  --color-reversal: #{$gray-900};
+  --color-header: var(--color-global);
+  --color-link: var(--accentcolor);
+  --color-link-hover: #{hsl.lighten(var(--accentcolor), 20%)};
+  --color-link-wiki: var(--accentcolor);
+  --color-link-wiki-hover: #{hsl.darken(var(--accentcolor), 5%)};
+  --color-link-nabvar: #a7a7a7;
+  --color-inline-code: #c7254e; // optional
+  --color-search: var(--primary);
 
   // List Group colors
-  // $color-list: $color-global;
-  $bgcolor-list: transparent;
-  // $color-list-hover: $color-reversal;
-  $color-list-active: white;
-  // $bgcolor-list-active: $primary;
+  // --color-list: var(--color-global);
+  --bgcolor-list: transparent;
+  // --color-list-hover: var(--color-reversal);
+  --color-list-active: white;
+  --bgcolor-list-active: var(--primary);
+  // --color-page-list-group-item-meta: #{$gray-500}; // optional
 
   // Table colors
-  // $color-table: #; // optional
-  $bgcolor-table: darken($themecolor, 3%); // optional
-  // $border-color-table: #; // optional
-  // $color-table-hover: #; // optional
-  // $bgcolor-table-hover: #; // optional
+  // --color-table: #; // optional
+  --bgcolor-table: #{hsl.darken(var(--themecolor), 3%)}; // optional
+  // --border-color-table: #; // optional
+  // --color-table-hover: #; // optional
+  // --bgcolor-table-hover: #; // optional
 
   // Navbar
-  $bgcolor-navbar: #01181a;
-  $bgcolor-search-top-dropdown: #00c2c4;
-  $border-image-navbar: linear-gradient(90deg, #6cfff9 0%, #0034c1 45%, #6cfff9 100%);
+  --bgcolor-navbar: hsl(var(--bgcolor-navbar-hs),var(--bgcolor-navbar-l));
+  --bgcolor-navbar-hs: 185,93%;
+  --bgcolor-navbar-l: 5%;
+  --bgcolor-search-top-dropdown: hsl(var(--bgcolor-search-top-dropdown-hs),var(--bgcolor-search-top-dropdown-l));
+  --bgcolor-search-top-dropdown-hs: 181,100%;
+  --bgcolor-search-top-dropdown-l: 38%;
+  --border-image-navbar: linear-gradient(90deg, #6cfff9 0%, #0034c1 45%, #6cfff9 100%);
 
   // Logo colors
-  $bgcolor-logo: darken($themecolor, 10%);
-  $fillcolor-logo-mark: #dedede;
+  --bgcolor-logo: #{hsl.darken(var(--themecolor), 10%)};
+  --fillcolor-logo-mark: #dedede;
 
   // Sidebar
-  $bgcolor-sidebar: #052e2f;
-  $bgcolor-sidebar-nav-item-active: rgba(#969494, 0.3); // optional
-  $text-shadow-sidebar-nav-item-active: 0px 0px 10px #969494; // optional
+  --bgcolor-sidebar: hsl(var(--bgcolor-sidebar-hs),var(--bgcolor-sidebar-l));
+  --bgcolor-sidebar-hs: 181,81%;
+  --bgcolor-sidebar-l: 10%;
+  --bgcolor-sidebar-nav-item-active: rgba(#969494, 0.3); // optional
+  --text-shadow-sidebar-nav-item-active: 0px 0px 10px #969494; // optional
+
+  // Sidebar resize button
+  --color-resize-button: #0e2329;
+  --bgcolor-resize-button: var(--bgcolor-search-top-dropdown);
+  --bgcolor-resize-button-hs: var(--bgcolor-search-top-dropdown-hs);
+  --bgcolor-resize-button-l: var(--bgcolor-search-top-dropdown-l);
+  --color-resize-button-hover: #0e2329;
+  --bgcolor-resize-button-hover: #{hsl.lighten(var(--bgcolor-search-top-dropdown), 5%)};
 
   // Sidebar contents
-  $color-sidebar-context: #2cfbff;
-  $bgcolor-sidebar-context: #184040;
+  --color-sidebar-context: hsl(var(--color-sidebar-context-hs),var(--color-sidebar-context-l));
+  --color-sidebar-context-hs: 181,100%;
+  --color-sidebar-context-l: 59%;
+  --bgcolor-sidebar-context: hsl(var(--bgcolor-sidebar-context-hs),var(--bgcolor-sidebar-context-l));
+  --bgcolor-sidebar-context-hs: 180,45%;
+  --bgcolor-sidebar-context-l: 17%;
 
   // Sidebar list group
-  $bgcolor-sidebar-list-group: #162126; // optional
+  --bgcolor-sidebar-list-group: #162126; // optional
 
-  // Sidebar resize button
-  $color-resize-button: #0e2329;
-  $bgcolor-resize-button: #00c2c4;
-  $color-resize-button-hover: #0e2329;
-  $bgcolor-resize-button-hover: lighten($bgcolor-resize-button, 5%);
+  // Subnavigation
+  --bgcolor-subnav: hsl(var(--bgcolor-subnav-hs),var(--bgcolor-subnav-l));
+  --bgcolor-subnav-hs: var(--bgcolor-global-hs);
+  --bgcolor-subnav-l: calc(var(--bgcolor-global-l) - 3%);
 
   // Tabs
-  $bordercolor-nav-tabs: #4c9eb4; // optional
-  // $color-nav-tabs-link-active: #; //optional
-  $bordercolor-nav-tabs-hover: #295561 #295561 $bordercolor-nav-tabs; // optional
-  // $bordercolor-nav-tabs-active: # # $bgcolor-global; // optional
+  --bordercolor-nav-tabs: #4c9eb4; // optional
+  // --color-nav-tabs-link-active: #; //optional
+  --bordercolor-nav-tabs-hover: #295561 #295561 var(--bordercolor-nav-tabs); // optional
+  // --bordercolor-nav-tabs-active: # # var(--bgcolor-global); // optional
+
+  // Tags
+  // --color-tags: #; //optional
+  // --bgcolor-tags: #; //optional
 
   // Icon colors
-  $color-editor-icons: $color-global;
+  --color-editor-icons: var(--color-global);
 
   // Border colors
-  $border-color-theme: #407483;
-  $bordercolor-inline-code: #4d4d4d; // optional
+  --border-color-theme: #407483;
+  --bordercolor-inline-code: #4d4d4d; // optional
 
-  // admin theme box
-  $color-theme-color-box: lighten($primary, 20%);
+  // Dropdown colors
+  --bgcolor-dropdown-link-active: #{$growi-blue};
 
-  @import './theme/apply-colors';
-  @import './theme/apply-colors-dark';
+  // admin theme box
+  --color-theme-color-box: #{hsl.lighten(var(--primary), 20%)};
 
   //Button
   .btn-group.grw-page-editor-mode-manager {
     .btn.btn-outline-primary {
-      @include page-editor-mode-manager.btn-page-editor-mode-manager(lighten($primary, 10%), $primary, darken($primary, 10%), darken($primary, 20%));
+      @include page-editor-mode-manager.btn-page-editor-mode-manager(#{hsl.lighten(var(--primary), 10%)}, var(--primary), #{hsl.darken(var(--primary), 10%)}, #{hsl.darken(var(--primary), 20%)});
     }
   }
 

+ 76 - 63
packages/preset-themes/src/styles/halloween.scss

@@ -1,24 +1,12 @@
 @use './variables' as *;
 @use './bootstrap/variables' as *;
 @use './theme/mixins/page-editor-mode-manager';
+@use './theme/hsl-functions' as hsl;
 
-$themecolor: #aa4a04;
-$themelight: #f0f8ff;
-$accentcolor: #ffd700;
 $bordercolor: #7e0d7e;
 
-// == Define Bootstrap theme colors
-//
-
 // colors for overriding bootstrap $theme-colors
-$primary: $themecolor;
-$light: lighten($secondary, 10%);
 
-// $info: #;
-// $success: #;
-// $warning: #;
-// $danger: #;
-// $dark: #;
 
 .growi:not(.login-page) {
   // add background-image
@@ -28,79 +16,104 @@ $light: lighten($secondary, 10%);
 }
 
 
-:root {
+:root[data-theme='dark'] {
+  --primary: hsl(var(--primary-hs),var(--primary-l)) !important;
+  --primary-hs: 25,95%;
+  --primary-l: 34%;
+  --secondary: hsl(var(--secondary-hs),var(--secondary-l)) !important;
+  --secondary-hs: 208,7%;
+  --secondary-l: 46%;
+
   // Background colors
-  $bgcolor-global: #050000;
-  $bgcolor-inline-code: #1f1f22; //optional
-  $bgcolor-card: $bgcolor-global;
-  $bgcolor-blinked-section: rgba($primary, 0.4);
-  $bgcolor-keyword-highlighted: darkviolet;
+  --bgcolor-global: hsl(var(--bgcolor-global-hs),var(--bgcolor-global-l));
+  --bgcolor-global-hs: 0,100%;
+  --bgcolor-global-l: 1%;
+  --bgcolor-inline-code: #1f1f22; //optional
+  --bgcolor-card: var(--bgcolor-global);
+  --bgcolor-blinked-section: #{hsl.alpha(var(--primary), 60%)};
+  --bgcolor-keyword-highlighted: darkviolet;
 
   // Font colors
-  $color-global: #e9af2b;
-  $color-reversal: #eeeeee;
-  // $color-header: #2b2b2b;
-  $color-link: #aa97cb;
-  $color-link-hover: lighten($color-link, 20%);
-  $color-link-wiki: #aa97cb;
-  $color-link-wiki-hover: lighten($color-link-wiki, 20%);
-  $color-link-nabvar: #a7a7a7;
-  $color-inline-code: #c7254e; // optional
+  --color-global: hsl(var(--color-global-hs),var(--color-global-l));
+  --color-global-hs: 42,81%;
+  --color-global-l: 54%;
+  --color-reversal: #eeeeee;
+  // --color-header: #2b2b2b;
+  --color-link: hsl(var(--color-link-hs),var(--color-link-l));
+  --color-link-hs: 262,33%;
+  --color-link-l: 69%;
+  --color-link-hover: #{hsl.lighten(var(--color-link), 20%)};
+  --color-link-wiki: var(--color-link);
+  --color-link-wiki-hs: var(--color-link-hs);
+  --color-link-wiki-l: var(--color-link-l);
+  --color-link-wiki-hover: #{hsl.lighten(var(--color-link), 20%)};
+  --color-link-nabvar: #a7a7a7;
+  --color-inline-code: #c7254e; // optional
 
   // List Group colors
-  $color-list: #979797;
-  $bgcolor-list: transparent;
-  $color-list-hover: $themecolor;
-  // $bgcolor-list-hover: ;
-  // $color-list-active: $color-reversal;
-  // $bgcolor-list-active: $primary;
+  --color-list: #979797;
+  --bgcolor-list: transparent;
+  --color-list-hover: var(--primary);
+  // --bgcolor-list-hover: ;
+  // --color-list-active: var(--color-reversal);
+  // --bgcolor-list-active: var(--primary);
 
   // Search Top
-  $color-search: $primary;
+  --color-search: var(--primary);
 
   // Navbar
-  $bgcolor-navbar: #eceded;
-  $bgcolor-search-top-dropdown: $primary;
-  $border-image-navbar: linear-gradient(90deg, #e3b7ff 0%, #134774 100%);
+  --bgcolor-navbar: hsl(var(--bgcolor-navbar-hs),var(--bgcolor-navbar-l));
+  --bgcolor-navbar-hs: 180,3%;
+  --bgcolor-navbar-l: 93%;
+  --bgcolor-search-top-dropdown: var(--primary);
+  --bgcolor-search-top-dropdown-hs: var(--primary-hs);
+  --bgcolor-search-top-dropdown-l: var(--primary-l);
+  --border-image-navbar: linear-gradient(90deg, #e3b7ff 0%, #134774 100%);
 
   // Logo colors
-  $bgcolor-logo: darken($themecolor, 10%);
-  $fillcolor-logo-mark: #dedede;
+  --bgcolor-logo: #{hsl.darken(var(--primary),10%)};
+  --fillcolor-logo-mark: #dedede;
 
   // Sidebar
-  $bgcolor-sidebar: #162b33;
-  $bgcolor-sidebar-nav-item-active: rgba(#969494, 0.3); // optional
-  $text-shadow-sidebar-nav-item-active: 0px 0px 10px #969494; // optional
+  --bgcolor-sidebar: hsl(var(--bgcolor-sidebar-hs),var(--bgcolor-sidebar-l));
+  --bgcolor-sidebar-hs: 197,40%;
+  --bgcolor-sidebar-l: 14%;
+  --bgcolor-sidebar-nav-item-active: rgba(#969494, 0.3); // optional
+  --text-shadow-sidebar-nav-item-active: 0px 0px 10px #969494; // optional
 
   // Sidebar contents
-  $color-sidebar-context: #aa97cb;
-  $bgcolor-sidebar-context: #302b3c;
+  --color-sidebar-context: hsl(var(--color-sidebar-context-hs),var(--color-sidebar-context-l));
+  --color-sidebar-context-hs: 262,33%;
+  --color-sidebar-context-l: 69%;
+  --bgcolor-sidebar-context: hsl(var(--bgcolor-sidebar-context-hs),var(--bgcolor-sidebar-context-l));
+  --bgcolor-sidebar-context-hs: 258,17%;
+  --bgcolor-sidebar-context-l: 20%;
 
   // Sidebar list group
-  $bgcolor-sidebar-list-group: #2c2926; // optional
+  --bgcolor-sidebar-list-group: #2c2926; // optional
 
   // Sidebar resize button
-  $color-resize-button: #effcfa;
-  $bgcolor-resize-button: $primary;
-  $color-resize-button-hover: #effcfa;
-  $bgcolor-resize-button-hover: lighten($bgcolor-resize-button, 5%);
+  --color-resize-button: #effcfa;
+  --bgcolor-resize-button: var(--primary);
+  --bgcolor-resize-button-hs: var(--primary-hs);
+  --bgcolor-resize-button-l: var(--primary-l);
+  --color-resize-button-hover: #effcfa;
+  --bgcolor-resize-button-hover: #{hsl.lighten(var(--primary), 5%)};
+
+  // Subnavigation
+  --bgcolor-subnav: hsl(var(--bgcolor-subnav-hs),var(--bgcolor-subnav-l));
+  --bgcolor-subnav-hs: var(--bgcolor-global-hs);
+  --bgcolor-subnav-l: calc(var(--bgcolor-global-l) + 4%);
 
   // Icon colors
-  $color-editor-icons: $color-global;
+  --color-editor-icons: var(--color-global);
 
   // Border colors
-  $border-color-theme: $gray-300; // former: `$navbar-border: $gray-300;`
-  $bordercolor-inline-code: #4d4d4d; // optional
-
-  // Dropdown colors
-  $color-dropdown-link-active: $color-reversal;
-  $color-dropdown-link-hover: $color-global;
+  --border-color-theme: #{$gray-300}; // former: `$navbar-border: $gray-300;`
+  --bordercolor-inline-code: #4d4d4d; // optional
 
   // admin theme box
-  $color-theme-color-box: lighten($primary, 20%);
-
-  @import './theme/apply-colors';
-  @import './theme/apply-colors-dark';
+  --color-theme-color-box: #{hsl.lighten(var(--primary), 20%)};
 
   &, body {
     background-image: url('../images/halloween/halloween.jpg');
@@ -113,13 +126,13 @@ $light: lighten($secondary, 10%);
   // Button
   .btn-group.grw-page-editor-mode-manager {
     .btn.btn-outline-primary {
-      @include page-editor-mode-manager.btn-page-editor-mode-manager(lighten($primary, 35%), $primary, lighten($primary, 5%), darken($primary, 20%));
+      @include page-editor-mode-manager.btn-page-editor-mode-manager(#{hsl.lighten(var(--primary), 35%)}, var(--primary), #{hsl.lighten(var(--primary), 5%)}, #{hsl.darken(var(--primary), 20%)});
     }
   }
 
   // Table
   .table {
-    color: $color-global;
+    color: var(--color-global);
   }
 
   pre {

+ 188 - 137
packages/preset-themes/src/styles/hufflepuff.scss

@@ -1,118 +1,142 @@
 @use './variables' as *;
 @use './bootstrap/variables' as *;
 @use './theme/mixins/page-editor-mode-manager';
+@use './theme/hsl-functions' as hsl;
 
 // == Define Bootstrap theme colors
 //
 
 // colors for overriding bootstrap $theme-colors
-// $secondary: #;
-// $info: #;
-// $success: #;
-// $warning: #;
-// $danger: #;
-// $light: #;
-// $dark: #;
-
-// .grw-navbar {
-//   border-bottom: $accentcolor 4px solid;
-// }
+// --info: #;
+// --success: #;
+// --warning: #;
+// --danger: #;
+// --light: #;
+// --dark: #;
 
 //== Light Mode
 //
 :root[data-theme='light'] {
   // Theme colors
-  $themecolor: #eaab20;
-  $themelight: #efe2cf;
-  $subthemecolor: #231e1d;
-  $third-main-color: #f0c05a;
-  $accentcolor: #993439;
-
-  $primary: $themecolor;
-  // $secondary: $subthemecolor;
-  $secondary: $third-main-color;
+  --primary: hsl(var(--primary-hs),var(--primary-l)) !important;
+  --primary-hs: 41,83%;
+  --primary-l: 52%;
+  --secondary: hsl(var(--secondary-hs),var(--secondary-l)) !important;
+  --secondary-hs: 41,83%;
+  --secondary-l: 65%;
+  --subthemecolor: hsl(var(--subthemecolor-hs),var(--subthemecolor-l));
+  --subthemecolor-hs: 10,9%;
+  --subthemecolor-l: 13%;
 
   // Background colors
-  $bgcolor-global: lighten($themelight, 10%);
-  $bgcolor-inline-code: $gray-100; //optional
-  $bgcolor-card: $gray-100;
-  $bgcolor-blinked-section: rgba($primary, 0.5);
-  $bgcolor-keyword-highlighted: $grw-marker-green;
+  --bgcolor-global: hsl(var(--bgcolor-global-hs),var(--bgcolor-global-l));
+  --bgcolor-global-hs: 36,50%;
+  --bgcolor-global-l: 97%;
+  --bgcolor-inline-code: #{$gray-100}; //optional
+  --bgcolor-card: #{$gray-100};
+  --bgcolor-blinked-section: #{hsl.alpha(var(--primary),50%)};
+  --bgcolor-keyword-highlighted: $grw-marker-green;
 
   // Font colors
-  $color-global: $subthemecolor;
-  $color-reversal: white;
-  $color-link: $accentcolor;
-  $color-link-hover: lighten($accentcolor, 10%);
-  $color-link-wiki: $accentcolor;
-  $color-link-wiki-hover: lighten($color-link-wiki, 10%);
-  $color-link-nabvar: $color-reversal;
-  $color-inline-code: #c7254e; // optional
+  --color-global: var(--subthemecolor);
+  --color-global-hs: var(--subthemecolor-hs);
+  --color-global-l: var(--subthemecolor-l);
+  --color-reversal: white;
+  --color-link: hsl(var(--color-link-hs),var(--color-link-l));
+  --color-link-hs: 357,49%;
+  --color-link-l: 40%;
+  --color-link-hover: #{hsl.lighten(var(--color-link), 10%)};
+  --color-link-wiki: var(--color-link);
+  --color-link-wiki-hs: var(--color-link-hs);
+  --color-link-wiki-l: var(--color-link-l);
+  --color-link-wiki-hover: #{hsl.lighten(var(--color-link), 10%)};
+  --color-link-nabvar: var(--color-reversal);
+  --color-inline-code: #c7254e; // optional
 
   // List Group colors
-  // $color-list: $color-global;
-  $bgcolor-list: transparent;
-  $color-list-hover: lighten($themecolor, 10%);
-  // $bgcolor-list-hover: darken($bgcolor-list, 2%);
-  // $color-list-active: $bgcolor-global;
-  // $bgcolor-list-active: $accentcolor;
+  // --color-list: var(--color-global);
+  --bgcolor-list: transparent;
+  --color-list-hover: #{hsl.lighten(var(--primary), 10%)};
+  // --bgcolor-list-hover: #{hsl.darken(var(--bgcolor-list), 2%)};
+  // --color-list-active: var(--bgcolor-global);
+  // --bgcolor-list-active: var(--color-link);
 
   // Navbar
-  $bgcolor-navbar: $third-main-color;
-  $bgcolor-search-top-dropdown: $themecolor;
-  $border-image-navbar: linear-gradient(to right, #90a555 0%, #a84be6 50%, #eaab20 100%);
+  --bgcolor-navbar: var(--secondary);
+  --bgcolor-navbar-hs: var(--secondary-hs);
+  --bgcolor-navbar-l: var(--secondary-l);
+  --bgcolor-search-top-dropdown: var(--primary);
+  --bgcolor-search-top-dropdown-hs: var(--primary-hs);
+  --bgcolor-search-top-dropdown-l: var(--primary-l);
+  --border-image-navbar: linear-gradient(to right, #90a555 0%, #a84be6 50%, #eaab20 100%);
 
   // Logo colors
-  $bgcolor-logo: $bgcolor-navbar;
-  $fillcolor-logo-mark: lighten(desaturate($bgcolor-inline-code, 10%), 15%);
+  --bgcolor-logo: var(--bgcolor-navbar);
+  --fillcolor-logo-mark: #{lighten(desaturate($gray-100, 10%), 15%)};
 
   // Sidebar
-  $bgcolor-sidebar: $themecolor;
+  --bgcolor-sidebar: var(--primary);
+  --bgcolor-sidebar-hs: var(--primary-hs);
+  --bgcolor-sidebar-l: var(--primary-l);
+
   // Sidebar resize button
-  $color-resize-button: $color-reversal;
-  $bgcolor-resize-button: $subthemecolor;
-  $color-resize-button-hover: $color-reversal;
-  $bgcolor-resize-button-hover: lighten($bgcolor-resize-button, 10%);
+  --color-resize-button: var(--color-reversal);
+  --bgcolor-resize-button: var(--subthemecolor);
+  --bgcolor-resize-button-hs: var(--subthemecolor-hs);
+  --bgcolor-resize-button-l: var(--subthemecolor-l);
+  --color-resize-button-hover: var(--color-reversal);
+  --bgcolor-resize-button-hover: #{hsl.lighten(var(--bgcolor-resize-button), 10%)};
+
   // Sidebar contents
-  $color-sidebar-context: $accentcolor;
-  $bgcolor-sidebar-context: lighten($themelight, 8%);
+  --color-sidebar-context: var(--color-link);
+  --color-sidebar-context-hs: var(--color-link-hs);
+  --color-sidebar-context-l: var(--color-link-l);
+  --bgcolor-sidebar-context: #{hsl.darken(var(--bgcolor-global), 2%)};
+  --bgcolor-sidebar-context-hs: var(--bgcolor-global-hs);
+  --bgcolor-sidebar-context-l: calc(var(--bgcolor-global-l) - 2%);
+
   // Sidebar list group
-  $bgcolor-sidebar-list-group: lighten($themelight, 10%);
+  --bgcolor-sidebar-list-group: #{hsl.lighten(var(--bgcolor-global), 10%)};
+
+  // Subnavigation
+  --bgcolor-subnav: hsl(var(--bgcolor-subnav-hs),var(--bgcolor-subnav-l));
+  --bgcolor-subnav-hs: var(--bgcolor-global-hs);
+  --bgcolor-subnav-l: calc(var(--bgcolor-global-l) - 3%);
 
   // Icon colors
-  $color-editor-icons: $accentcolor;
+  --color-editor-icons: var(--color-link);
 
   // Border colors
-  $border-color-theme: lighten($subthemecolor, 40%);
-  $bordercolor-inline-code: #ccc8c8; // optional
+  --border-color-theme: #{hsl.lighten(var(--subthemecolor), 40%)};
+  --bordercolor-inline-code: #ccc8c8; // optional
 
   // Dropdown colors
-  $bgcolor-dropdown-link-active: $growi-blue;
+  --bgcolor-dropdown-link-active: #{$growi-blue};
 
   // admin theme box
-  $color-theme-color-box: darken($primary, 5%);
-
-  @import './theme/apply-colors';
-  @import './theme/apply-colors-light';
+  --color-theme-color-box: #{hsl.darken(var(--primary), 5%)};
 
   &, body {
     background-image: url('../images/hufflepuff/badger-light3.png');
+    background-attachment: fixed;
+    background-position: bottom;
+    background-size: cover;
   }
 
   // Button
   .btn.btn-outline-primary {
-    @include page-editor-mode-manager.btn-page-editor-mode-manager(darken($primary, 50%), darken($primary, 50%), lighten($primary, 20%));
+    @include page-editor-mode-manager.btn-page-editor-mode-manager(#{hsl.darken(var(--primary), 50%)}, #{hsl.darken(var(--primary), 50%)}, #{hsl.lighten(var(--primary), 20%)});
   }
   .btn-group.grw-page-editor-mode-manager {
     .btn.btn-outline-primary {
-      @include page-editor-mode-manager.btn-page-editor-mode-manager(darken($primary, 70%), lighten($primary, 5%), lighten($primary, 20%));
+      @include page-editor-mode-manager.btn-page-editor-mode-manager(#{hsl.darken(var(--primary), 70%)}, #{hsl.lighten(var(--primary), 5%)}, #{hsl.lighten(var(--primary), 20%)});
     }
   }
 
   .growi:not(.login-page) {
     // add background-image
     .page-editor-preview-container {
-      background-image: url('../images/themes/hufflepuff/badger-light3.png');
+      background-image: url('../images/hufflepuff/badger-light3.png');
       background-attachment: fixed;
       background-position: bottom;
       background-size: cover;
@@ -122,7 +146,7 @@
   // login and register
   .nologin {
     background: unset !important;
-    background-image: url('../images/themes/hufflepuff/badger-light.png');
+    background-image: url('../images/hufflepuff/badger-light.png');
     background-attachment: fixed;
     background-position: bottom;
     background-size: cover;
@@ -133,26 +157,26 @@
     }
 
     .link-switch {
-      color: $color-global;
+      color: #{hsl.darken(var(--color-global),10%)};
     }
 
     .grw-external-auth-form {
-      border-color: $accentcolor !important;
+      border-color: #993439 !important;
     }
   }
 
   .table {
-    background-color: $bgcolor-global;
+    background-color: var(--bgcolor-global);
   }
 
   .card-timeline > .card-header {
-    background-color: $third-main-color;
+    background-color: var(--secondary);
   }
 
   .nav.nav-tabs {
     > .nav-item {
       > .nav-link.active {
-        color: $subthemecolor;
+        color: #231e1d;
       }
     }
   }
@@ -160,101 +184,128 @@
 
 :root[data-theme='dark'] {
   // Theme colors
-  $themecolor: #eaab20;
-  $themedark: #3d3f38;
-  $subthemecolor: #231e1d;
-  $third-main-color: #967224;
-  $accentcolor: #993439;
-
-  $primary: darken($themecolor, 10%);
-  $secondary: $third-main-color;
-  $dark: #031018;
+  --primary: hsl(var(--primary-hs),var(--primary-l)) !important;
+  --primary-hs: 41,83%;
+  --primary-l: 62%;
+  --secondary: hsl(var(--secondary-hs),var(--secondary-l)) !important;
+  --secondary-hs: 41,61%;
+  --secondary-l: 36%;
+  --subthemecolor: hsl(var(--subthemecolor-hs),var(--subthemecolor-l));
+  --subthemecolor-hs: 10,9%;
+  --subthemecolor-l: 13%;
+  --accentcolor: hsl(var(--accentcolor-hs),var(--accentcolor-l));
+  --accentcolor-hs: 357,49%;
+  --accentcolor-l: 40%;
 
   // Background colors
-  $bgcolor-global: $themedark;
-  // $bgcolor-navbar: #27343b;
-  $bgcolor-inline-code: $subthemecolor;
-  $bgcolor-card: darken($themedark, 5%);
-  $bgcolor-blinked-section: rgba($primary, 0.5);
-  $bgcolor-keyword-highlighted: darken($grw-marker-cyan, 40%);
+  --bgcolor-global: hsl(var(--bgcolor-global-hs),var(--bgcolor-global-l));
+  --bgcolor-global-hs: 77,6%;
+  --bgcolor-global-l: 23%;
+  // --bgcolor-navbar: #27343b;
+  --bgcolor-inline-code: var(--subthemecolor);
+  --bgcolor-card: #{hsl.darken(var(--bgcolor-global), 5%)};
+  --bgcolor-blinked-section: #{hsl.alpha(var(--primary), 50%)};
+  --bgcolor-keyword-highlighted: #{darken($grw-marker-cyan, 40%)};
 
   // Font colors
-  $color-global: #efe2cf;
-  $color-reversal: $gray-100;
-  $color-link: lighten($themecolor, 20%);
-  $color-link-hover: lighten($color-link, 10%);
-  $color-link-wiki: lighten($primary, 20%);
-  $color-link-wiki-hover: lighten($color-link-wiki, 20%);
-  $color-link-nabvar: $color-reversal;
-  $color-inline-code: $themecolor;
-  // $color-inline-code: #c7254e; // optional
-  // $color-search: #000102;
+  --color-global: hsl(var(--color-global-hs),var(--color-global-l));
+  --color-global-hs: 36,50%;
+  --color-global-l: 87%;
+  --color-reversal: #{$gray-100};
+  --color-link: #{hsl.lighten(var(--primary), 30%)};
+  --color-link-hs: var(--primary-hs);
+  --color-link-l: calc(var(--primary-l) + 30%);
+  --color-link-hover: #{hsl.lighten(var(--primary), 40%)};
+  --color-link-wiki: #{hsl.lighten(var(--primary), 20%)};
+  --color-link-wiki-hs: var(--primary-hs);
+  --color-link-wiki-l: calc(var(--primary-l) + 20%);
+  --color-link-wiki-hover: #{hsl.lighten(var(--primary), 50%)};
+  --color-link-nabvar: var(--color-reversal);
+  --color-inline-code: #{hsl.lighten(var(--primary), 10%)};
+  // --color-inline-code: #c7254e; // optional
+  // --color-search: #000102;
 
   // List Group colors
-  // $color-list: $color-global;
-  $bgcolor-list: transparent;
-  $color-list-hover: $accentcolor;
-  // $bgcolor-list-hover: lighten($bgcolor-global, 3%);
-  // $color-list-active: $color-reversal;
-  // $bgcolor-list-active: $primary;
+  // --color-list: var(--color-global);
+  --bgcolor-list: transparent;
+  --color-list-hover: var(--accentcolor);
+  // --bgcolor-list-hover: #{hsl.lighten(var(--bgcolor-global), 3%)};
+  // --color-list-active: var(--color-reversal);
+  // --bgcolor-list-active: var(--primary);
 
   // Navbar
-  $bgcolor-navbar: $third-main-color;
-  $bgcolor-search-top-dropdown: $themecolor;
-  $border-image-navbar: linear-gradient(to right, #90a555 0%, #3d98a3 50%, #eaab20 100%);
+  --bgcolor-navbar: var(--secondary);
+  --bgcolor-navbar-hs: var(--secondary-hs);
+  --bgcolor-navbar-l: var(--secondary-l);
+  --bgcolor-search-top-dropdown: #{hsl.lighten(var(--primary), 10%)};
+  --bgcolor-search-top-dropdown-hs: var(--primary-hs);
+  --bgcolor-search-top-dropdown-l: calc(var(--primary-l) + 10%);
+  --border-image-navbar: linear-gradient(to right, #90a555 0%, #3d98a3 50%, #eaab20 100%);
 
   // Logo colors
-  $bgcolor-logo: #13191c;
-  $fillcolor-logo-mark: white;
+  --bgcolor-logo: #13191c;
+  --fillcolor-logo-mark: white;
 
   // Sidebar
-  $bgcolor-sidebar: $themecolor;
-  // $bgcolor-sidebar-nav-item-active: rgba(#, 0.3); // optional
-  $text-shadow-sidebar-nav-item-active: 0px 0px 10px #cc951e; // optional
+  --bgcolor-sidebar: #{hsl.lighten(var(--primary), 10%)};
+  --bgcolor-sidebar-hs: var(--primary-hs);
+  --bgcolor-sidebar-l: calc(var(--primary-l) + 10%);
+  // --bgcolor-sidebar-nav-item-active: rgba(#, 0.3); // optional
+  --text-shadow-sidebar-nav-item-active: 0px 0px 10px #cc951e; // optional
+
   // Sidebar resize button
-  $color-resize-button: $color-global;
-  $bgcolor-resize-button: $accentcolor;
-  $color-resize-button-hover: $color-global;
-  $bgcolor-resize-button-hover: darken($bgcolor-resize-button, 7%);
+  --color-resize-button: var(--color-global);
+  --bgcolor-resize-button: var(--accentcolor);
+  --bgcolor-resize-button-hs: var(--accentcolor-hs);
+  --bgcolor-resize-button-l: var(--accentcolor-l);
+  --color-resize-button-hover: var(--color-global);
+  --bgcolor-resize-button-hover: #{hsl.darken(var(--accentcolor), 7%)};
+
   // Sidebar contents
-  $color-sidebar-context: $color-global;
-  $bgcolor-sidebar-context: lighten($themedark, 5%);
+  --color-sidebar-context: var(--color-link);
+  --color-sidebar-context-hs: var(--color-link-hs);
+  --color-sidebar-context-l: var(--color-link-l);
+  --bgcolor-sidebar-context: #{hsl.lighten(var(--bgcolor-global), 5%)};
+  --bgcolor-sidebar-context-hs: var(--bgcolor-global-hs);
+  --bgcolor-sidebar-context-l: calc(var(--bgcolor-global-l) + 5%);
+
   // Sidebar list group
-  $bgcolor-sidebar-list-group: lighten($subthemecolor, 5%);
+  --bgcolor-sidebar-list-group: #{hsl.lighten(var(--subthemecolor), 5%)};
+
+  // Subnavigation
+  --bgcolor-subnav: hsl(var(--bgcolor-subnav-hs),var(--bgcolor-subnav-l));
+  --bgcolor-subnav-hs: var(--bgcolor-global-hs);
+  --bgcolor-subnav-l: calc(var(--bgcolor-global-l) - 3%);
 
   // Icon colors
-  $color-editor-icons: $themecolor;
+  --color-editor-icons: #{hsl.lighten(var(--primary), 10%)};
 
   // Border colors
-  $border-color-theme: darken($themecolor, 25%);
-  $bordercolor-inline-code: #4d4d4d; // optional
-
-  // Dropdown colors
-  $color-dropdown-link-active: $color-reversal;
-  $color-dropdown-link-hover: $color-global;
+  --border-color-theme: #{hsl.darken(var(--primary), 15%)};
+  --bordercolor-inline-code: #4d4d4d; // optional
 
   // admin theme box
-  $color-theme-color-box: $primary;
-
-  @import './theme/apply-colors';
-  @import './theme/apply-colors-dark';
+  --color-theme-color-box: var(--primary);
 
   &, body {
     background-image: url('../images/hufflepuff/badger-dark.jpg');
+    background-attachment: fixed;
+    background-position: bottom;
+    background-size: cover;
   }
 
   // Navs
   .nav-tabs {
-    border-bottom: $border-color-theme 1px solid;
+    border-bottom: var(--border-color-theme) 1px solid;
     .nav-link {
       &:hover {
-        border-color: lighten($border-color-theme, 10%);
+        border-color: #{hsl.darken(var(--primary), 5%)};
         border-bottom: none;
       }
       &.active {
-        color: $color-link;
+        color: var(--color-link);
         background-color: transparent;
-        border-color: $border-color-theme;
+        border-color: var(--border-color-theme);
       }
     }
   }
@@ -266,22 +317,22 @@
 
   // Button
   .btn.btn-outline-primary {
-    @include page-editor-mode-manager.btn-page-editor-mode-manager(lighten($primary, 40%), lighten($primary, 15%), darken($primary, 10%), darken($primary, 30%));
+    @include page-editor-mode-manager.btn-page-editor-mode-manager(#{hsl.lighten(var(--primary), 40%)}, #{hsl.lighten(var(--primary), 15%)}, #{hsl.darken(var(--primary), 10%)}, #{hsl.darken(var(--primary), 30%)});
   }
   .btn-group.grw-page-editor-mode-manager {
     .btn.btn-outline-primary {
-      @include page-editor-mode-manager.btn-page-editor-mode-manager(lighten($primary, 40%), lighten($primary, 15%), darken($primary, 0%), darken($primary, 30%));
+      @include page-editor-mode-manager.btn-page-editor-mode-manager(#{hsl.lighten(var(--primary), 40%)}, #{hsl.lighten(var(--primary), 15%)}, #{hsl.darken(var(--primary), 10%)}, #{hsl.darken(var(--primary), 30%)});
     }
   }
 
   .card-timeline > .card-header {
-    background-color: $accentcolor;
+    background-color: var(--accentcolor);
   }
 
   .growi:not(.login-page) {
     // add background-image
     .page-editor-preview-container {
-      background-image: url('../images/themes/hufflepuff/badger-dark.jpg');
+      background-image: url('../images/hufflepuff/badger-dark.jpg');
       background-attachment: fixed;
       background-position: bottom;
       background-size: cover;
@@ -291,7 +342,7 @@
   // login and register
   .nologin {
     background: unset !important;
-    background-image: url('../images/themes/hufflepuff/badger-light.png');
+    background-image: url('../images/hufflepuff/badger-light.png');
     background-attachment: fixed;
     background-position: bottom;
     background-size: cover;
@@ -302,11 +353,11 @@
     }
 
     .link-switch {
-      color: $color-global;
+      color: var(--color-global);
     }
 
     .grw-external-auth-form {
-      border-color: $accentcolor !important;
+      border-color: var(--accentcolor) !important;
     }
   }
 }

+ 91 - 60
packages/preset-themes/src/styles/island.scss

@@ -2,88 +2,119 @@
 @use './bootstrap/variables' as *;
 @use './theme/mixins/page-editor-mode-manager';
 @use './atoms/mixins/buttons' as mixins-buttons;
+@use './theme/hsl-functions' as hsl;
+
+//== Light Mode
+//
+:root[data-theme='light'] {
+  --primary: hsl(var(--primary-hs),var(--primary-l)) !important;
+  --primary-hs: 171,33%;
+  --primary-l: 69%;
+  --secondary: hsl(var(--secondary-hs),var(--secondary-l)) !important;
+  --secondary-hs: 208,7%;
+  --secondary-l: 46%;
 
-$color-primary: #97cbc3;
-$color-themelight: rgba(183, 226, 219, 1);
-
-:root {
-  $primary: $color-primary;
   // Background colors
-  $bgcolor-card: $gray-50;
-  $bgcolor-global: lighten($color-themelight, 10%);
-  $bgcolor-inline-code: $gray-100; //optional
-  $bgcolor-blinked-section: rgba($primary, 0.3);
-  //$bgcolor-keyword-highlighted: $grw-marker-yellow;
+  --bgcolor-global: hsl(var(--bgcolor-global-hs),var(--bgcolor-global-l));
+  --bgcolor-global-hs: 170,43%;
+  --bgcolor-global-l: 90%;
+  --bgcolor-card: #{$gray-50};
+  --bgcolor-inline-code: #{$gray-100}; //optional
+  --bgcolor-blinked-section: #{hsl.alpha(var(--primary), 70%)};
+  //--bgcolor-keyword-highlighted: #{$grw-marker-yellow};
 
   // Font colors
-  $color-global: #112744;
-  $color-reversal: #eeeeee;
-  // $color-header: #2b2b2b;
-  $color-link: #3c6d72;
-  $color-link-hover: lighten($color-link, 20%);
-  $color-link-wiki: $color-link;
-  $color-link-wiki-hover: lighten($color-link-wiki, 20%);
-  $color-link-nabvar: $color-reversal;
-  $color-inline-code: #c7254e; // optional
+  --color-global: hsl(var(--color-global-hs),var(--color-global-l));
+  --color-global-hs: 214,60%;
+  --color-global-l: 17%;
+  --color-reversal: #eeeeee;
+  // --color-header: #2b2b2b;
+  --color-link: hsl(var(--color-link-hs),var(--color-link-l));
+  --color-link-hs: 186,31%;
+  --color-link-l: 34%;
+  --color-link-hover: #{hsl.lighten(var(--color-link), 20%)};
+  --color-link-wiki: var(--color-link);
+  --color-link-wiki-hs: var(--color-link-hs);
+  --color-link-wiki-l: var(--color-link-l);
+  --color-link-wiki-hover: #{hsl.lighten(var(--color-link), 20%)};
+  --color-link-nabvar: var(--color-reversal);
+  --color-inline-code: #c7254e; // optional
 
   // List Group colors
-  // $color-list: $color-global;
-  // $bgcolor-list: lighten($color-themelight, 10%);
-  // $color-list-hover: ;
-  $bgcolor-list-hover: $color-themelight;
-  $color-list-active: $color-global;
-  $bgcolor-list-active: $primary;
+  // --color-list: var(--color-global);
+  // --bgcolor-list: var(--bgcolor-global);
+  // --color-list-hover: ;
+  --bgcolor-list-hover: #{hsl.darken(var(--bgcolor-global),10%)};
+  --color-list-active: var(--color-global);
+  --bgcolor-list-active: var(--primary);
 
   // Table colors
-  // $color-table: #; // optional
-  // $bgcolor-table: #; // optional
-  $border-color-table: $primary; // optional
-  // $color-table-hover: #; // optional
-  // $bgcolor-table-hover: #; // optional
+  // --color-table: #; // optional
+  // --bgcolor-table: #; // optional
+  --border-color-table: var(--primary); // optional
+  // --color-table-hover: #; // optional
+  // --bgcolor-table-hover: #; // optional
 
   // Navbar
-  $bgcolor-navbar: #302e2e;
-  $bgcolor-search-top-dropdown: $color-primary;
-  $border-image-navbar: linear-gradient(to right, #5ce4ef 0%, #5953eb 100%);
+  --bgcolor-navbar: hsl(var(--bgcolor-navbar-hs),var(--bgcolor-navbar-l));
+  --bgcolor-navbar-hs: 0,2%;
+  --bgcolor-navbar-l: 18%;
+  --bgcolor-search-top-dropdown: var(--primary);
+  --bgcolor-search-top-dropdown-hs: var(--primary-hs);
+  --bgcolor-search-top-dropdown-l: var(--primary-l);
+  --border-image-navbar: linear-gradient(to right, #5ce4ef 0%, #5953eb 100%);
 
   // Logo colors
-  $bgcolor-logo: #0d3955;
-  $fillcolor-logo-mark: lighten(desaturate($bgcolor-inline-code, 10%), 15%);
+  --bgcolor-logo: #0d3955;
+  --fillcolor-logo-mark: #{lighten(desaturate($gray-100, 10%), 15%)};
 
   // Sidebar
-  $bgcolor-sidebar: #0d3955;
-  $bgcolor-sidebar-nav-item-active: rgba(black, 0.37);
-  // $bgcolor-sidebar-nav-item-active: rgba(#969494, 0.3); // optional
-  $text-shadow-sidebar-nav-item-active: 0px 0px 10px #0099ff; // optional
+  --bgcolor-sidebar: hsl(var(--bgcolor-sidebar-hs),var(--bgcolor-sidebar-l));
+  --bgcolor-sidebar-hs: 203,73%;
+  --bgcolor-sidebar-l: 19%;
+  --bgcolor-sidebar-nav-item-active: rgba(black, 0.37);
+  // --bgcolor-sidebar-nav-item-active: rgba(#969494, 0.3); // optional
+  --text-shadow-sidebar-nav-item-active: 0px 0px 10px #0099ff; // optional
+
   // Sidebar resize button
-  $color-resize-button: white;
-  $bgcolor-resize-button: $primary;
-  $color-resize-button-hover: white;
-  $bgcolor-resize-button-hover: darken($bgcolor-resize-button, 5%);
+  --color-resize-button: white;
+  --bgcolor-resize-button: var(--primary);
+  --bgcolor-resize-button-hs: var(--primary-hs);
+  --bgcolor-resize-button-l: var(--primary-l);
+  --color-resize-button-hover: white;
+  --bgcolor-resize-button-hover: #{hsl.darken(var(--primary),5%)};
+
   // Sidebar contents
-  $bgcolor-sidebar-context: #e2f3f1;
-  $color-sidebar-context: $color-link;
+  --bgcolor-sidebar-context: hsl(var(--bgcolor-sidebar-context-hs),var(--bgcolor-sidebar-context-l));
+  --bgcolor-sidebar-context-hs: 173,41%;
+  --bgcolor-sidebar-context-l: 92%;
+  --color-sidebar-context: var(--color-link);
+  --color-sidebar-context-hs: var(--color-link-hs);
+  --color-sidebar-context-l: var(--color-link-l);
+
   // Sidebar list group
-  $bgcolor-sidebar-list-group: #eff8f7; // optional
+  --bgcolor-sidebar-list-group: #eff8f7; // optional
+
+  // Subnavigation
+  --bgcolor-subnav: hsl(var(--bgcolor-subnav-hs),var(--bgcolor-subnav-l));
+  --bgcolor-subnav-hs: var(--bgcolor-global-hs);
+  --bgcolor-subnav-l: calc(var(--bgcolor-global-l) + 4%);
 
   // Tabs
-  $bordercolor-nav-tabs: $gray-300; // optional
+  --bordercolor-nav-tabs: #{$gray-300}; // optional
 
   // Icon colors
-  $color-editor-icons: $color-global;
+  --color-editor-icons: var(--color-global);
 
   // Border colors
-  $border-color-theme: $gray-300;
-  $bordercolor-inline-code: #ccc8c8; // optional
+  --border-color-theme: #{$gray-300};
+  --bordercolor-inline-code: #ccc8c8; // optional
 
   // Dropdown colors
-  $bgcolor-dropdown-link-active: $growi-blue;
+  --bgcolor-dropdown-link-active: #{$growi-blue};
 
   // admin theme box
-  $color-theme-color-box: darken($primary, 15%);
-
-  @import './theme/apply-colors';
-  @import './theme/apply-colors-light';
+  --color-theme-color-box: #{hsl.darken(var(--primary), 15%)};
 
   &, body {
     background-image: url('../images/island/island.png');
@@ -91,11 +122,11 @@ $color-themelight: rgba(183, 226, 219, 1);
   }
 
   .rbt-menu {
-    background: lighten($color-themelight, 5%);
+    background: #{hsl.darken(var(--bgcolor-global), 5%)};
   }
 
   .page-editor-preview-container {
-    background-image: url('/images/themes/island/island.png');
+    background-image: url('../images/island/island.png');
     background-attachment: fixed;
   }
 
@@ -107,14 +138,14 @@ $color-themelight: rgba(183, 226, 219, 1);
   // Button
   .btn-group.grw-page-editor-mode-manager {
     .btn.btn-outline-primary {
-      @include page-editor-mode-manager.btn-page-editor-mode-manager(darken($primary, 50%), lighten($primary, 5%), darken($primary, 5%));
+      @include page-editor-mode-manager.btn-page-editor-mode-manager(#{hsl.darken(var(--primary), 50%)}, #{hsl.lighten(var(--primary), 5%)}, #{hsl.darken(var(--primary), 5%)});
     }
   }
 
   // Cards
   .admin-bot-card {
     .grw-botcard-title-active {
-      color: $color-reversal;
+      color: var(--color-reversal);
     }
   }
 
@@ -125,7 +156,7 @@ $color-themelight: rgba(183, 226, 219, 1);
     // Pagetree
     .grw-pagetree {
       .grw-pagetree-triangle-btn {
-        @include mixins-buttons.button-outline-svg-icon-variant($gray-400, $bgcolor-sidebar);
+        @include mixins-buttons.button-outline-svg-icon-variant($gray-400, #0d3955);
       }
     }
   }

+ 163 - 112
packages/preset-themes/src/styles/jade-green.scss

@@ -1,85 +1,114 @@
 @use './variables' as *;
 @use './bootstrap/variables' as *;
 @use './theme/mixins/page-editor-mode-manager';
+@use './theme/hsl-functions' as hsl;
 
 :root[data-theme='light'] {
   // Theme colors
-  $themecolor: #38b48b;
-  $themelight: #ffffff;
-  $accentcolor: #bfbfbf;
-  $subthemecolor: #e6e6e6;
-
-  $primary: $themecolor;
+  --primary: hsl(var(--primary-hs),var(--primary-l)) !important;
+  --primary-hs: 160,53%;
+  --primary-l: 46%;
+  --secondary-hs: 208,7%;
+  --secondary-l: 46%;
+  --accentcolor: hsl(var(--accentcolor-hs),var(--accentcolor-l));
+  --accentcolor-hs: 0,0%;
+  --accentcolor-l: 75%;
 
   // Background colors
-  $bgcolor-global: $themelight;
-  $bgcolor-inline-code: $gray-100; //optional
-  $bgcolor-card: $accentcolor;
-  $bgcolor-blinked-section: rgba($primary, 0.1);
-  //$bgcolor-keyword-highlighted: $grw-marker-yellow;
+  --bgcolor-global: hsl(var(--bgcolor-global-hs),var(--bgcolor-global-l));
+  --bgcolor-global-hs: 0,0%;
+  --bgcolor-global-l: 100%;
+  --bgcolor-inline-code: #{$gray-100}; //optional
+  --bgcolor-card: var(--accentcolor);
+  --bgcolor-blinked-section: #{hsl.alpha(var(--primary),90%)};
+  //--bgcolor-keyword-highlighted: #{$grw-marker-yellow};
 
   // Font colors
-  $color-global: #2c2c2c;
-  $color-reversal: $gray-100;
-  $color-link: $primary;
-  $color-link-hover: lighten($color-link, 12%);
-  $color-link-wiki: $primary;
-  $color-link-wiki-hover: lighten($color-link-wiki, 12%);
-  $color-link-nabvar: $color-reversal;
-  $color-inline-code: #c7254e; // optional
-  $color-search: $color-global;
+  --color-global: hsl(var(--color-global-hs),var(--color-global-l));
+  --color-global-hs: 0,0%;
+  --color-global-l: 17%;
+  --color-reversal: #{$gray-100};
+  --color-link: var(--primary);
+  --color-link-hs: var(--primary-hs);
+  --color-link-l: var(--primary-l);
+  --color-link-hover: #{hsl.lighten(var(--primary), 12%)};
+  --color-link-wiki: var(--primary);
+  --color-link-wiki-hs: var(--primary-hs);
+  --color-link-wiki-l: var(--primary-l);
+  --color-link-wiki-hover: #{hsl.lighten(var(--primary), 12%)};
+  --color-link-nabvar: var(--color-reversal);
+  --color-inline-code: #c7254e; // optional
+  --color-search: var(--color-global);
 
   // List Group colors
-  // $color-list: $color-global;
-  $bgcolor-list: transparent;
-  $color-list-hover: $color-search;
-  $bgcolor-list-hover: darken($bgcolor-global, 3%);
-  // $color-list-active: $color-reversal;
-  // $bgcolor-list-active: $primary;
+  // --color-list: var(--color-global);
+  --bgcolor-list: transparent;
+  --color-list-hover: var(--color-global);
+  --bgcolor-list-hover: #{hsl.darken(var(--bgcolor-global),3%)};
+  // --color-list-active: var(--color-reversal);
+  // --bgcolor-list-active: var(--primary);
 
   // Navbar
-  $bgcolor-navbar: $color-global;
-  $bgcolor-search-top-dropdown: $themecolor;
-  $border-image-navbar: linear-gradient(to right, $primary 0%, darken($primary, 5%) 100%);
+  --bgcolor-navbar: var(--color-global);
+  --bgcolor-navbar-hs: var(--color-global-hs);
+  --bgcolor-navbar-l: var(--color-global-l);
+  --bgcolor-search-top-dropdown: var(--primary);
+  --bgcolor-search-top-dropdown-hs: var(--primary-hs);
+  --bgcolor-search-top-dropdown-l: var(--primary-l);
+  --border-image-navbar: linear-gradient(to right, var(--primary) 0%, #{hsl.darken(var(--primary), 5%)} 100%);
+
 
   // Logo colors
-  $bgcolor-logo: $themelight;
-  $fillcolor-logo-mark: $themelight;
+  --bgcolor-logo: var(--bgcolor-global);
+  --fillcolor-logo-mark: var(--bgcolor-global);
 
   // Sidebar
-  $bgcolor-sidebar: $accentcolor;
-  // $bgcolor-sidebar-nav-item-active: rgba(#, 0.37); // optional
-  $text-shadow-sidebar-nav-item-active: 0px 0px 10px #ffffff; // optional
+  --bgcolor-sidebar: var(--accentcolor);
+  --bgcolor-sidebar-hs: var(--accentcolor-hs);
+  --bgcolor-sidebar-l: var(--accentcolor-l);
+  // --bgcolor-sidebar-nav-item-active: rgba(#, 0.37); // optional
+  --text-shadow-sidebar-nav-item-active: 0px 0px 10px #ffffff; // optional
+
   // Sidebar resize button
-  $color-resize-button: #ffffff;
-  $bgcolor-resize-button: $primary;
-  $color-resize-button-hover: $color-reversal;
-  $bgcolor-resize-button-hover: lighten($bgcolor-resize-button, 5%);
+  --color-resize-button: #ffffff;
+  --bgcolor-resize-button: var(--primary);
+  --bgcolor-sidebar-context-hs: var(--primary-hs);
+  --bgcolor-sidebar-context-l: var(--primary-l);
+  --color-resize-button-hover: var(--color-reversal);
+  --bgcolor-resize-button-hover: #{hsl.lighten(var(--primary), 5%)};
+
   // Sidebar contents
-  $color-sidebar-context: $color-global;
-  $bgcolor-sidebar-context: #ebebeb;
+  --color-sidebar-context: var(--color-global);
+  --color-sidebar-context-hs: var(--color-global-hs);
+  --color-sidebar-context-l: var(--color-global-l);
+  --bgcolor-sidebar-context: hsl(var(--bgcolor-sidebar-context-hs),var(--bgcolor-sidebar-context-l));
+  --bgcolor-sidebar-context-hs: 0,0%;
+  --bgcolor-sidebar-context-l: 93%;
+
   // Sidebar list group
-  // $bgcolor-sidebar-list-group: #; // optional
+  // --bgcolor-sidebar-list-group: #; // optional
+
+  // Subnavigation
+  --bgcolor-subnav: hsl(var(--bgcolor-subnav-hs),var(--bgcolor-subnav-l));
+  --bgcolor-subnav-hs: var(--bgcolor-global-hs);
+  --bgcolor-subnav-l: calc(var(--bgcolor-global-l) - 3%);
 
   // Icon colors
-  $color-editor-icons: $color-global;
+  --color-editor-icons: var(--color-global);
 
   // Border colors
-  $border-color-theme: $primary;
-  $bordercolor-inline-code: #ccc8c8; // optional
+  --border-color-theme: var(--primary);
+  --bordercolor-inline-code: #ccc8c8; // optional
 
   // admin theme box
-  $color-theme-color-box: $primary;
-
-  @import './theme/apply-colors';
-  @import './theme/apply-colors-light';
+  --color-theme-color-box: var(--primary);
 
   // Navs {
   .nav-tabs {
-    border-bottom: $border-color-theme 1px solid;
+    border-bottom: var(--primary) 1px solid;
     .nav-link {
       &:hover {
-        border-color: lighten($border-color-theme, 10%);
+        border-color: #{hsl.lighten(var(--primary), 10%)};
         border-bottom: none;
       }
       &.active {
@@ -87,106 +116,128 @@
       }
     }
   }
+
   // Button
   .btn-group.grw-page-editor-mode-manager {
     .btn.btn-outline-primary {
-      @include page-editor-mode-manager.btn-page-editor-mode-manager(#ffffff, $primary, $primary, lighten($primary, 20%));
+      @include page-editor-mode-manager.btn-page-editor-mode-manager(#ffffff, var(--primary), var(--primary), #{hsl.lighten(var(--primary), 20%)});
     }
   }
 }
 
 :root[data-theme='dark'] {
   // Theme colors
-  $themecolor: #38b48b;
-  $themedark: #333333;
-  $accentcolor: #212121;
-  $subthemecolor: #2e2e2e;
-
-  $primary: #38b48b;
-  $dark: #a7a7a7;
+  --primary: hsl(var(--primary-hs),var(--primary-l)) !important;
+  --primary-hs: 160,53%;
+  --primary-l: 46%;
+  --secondary: hsl(var(--secondary-hs),var(--secondary-l)) !important;
+  --secondary-hs: 208,7%;
+  --secondary-l: 46%;
+  --accentcolor: hsl(var(--accentcolor-hs),var(--accentcolor-l));
+  --accentcolor-hs: 0,0%;
+  --accentcolor-l: 13%;
 
   // Background colors
-  $bgcolor-global: $themedark;
-  $bgcolor-navbar: #2b2b2b;
-  $bgcolor-inline-code: $gray-100; //optional
-  $bgcolor-card: darken($themedark, 5%);
-  $bgcolor-blinked-section: rgba($primary, 0.5);
-  $bgcolor-keyword-highlighted: darken($grw-marker-red, 30%);
+  --bgcolor-global: hsl(var(--bgcolor-global-hs),var(--bgcolor-global-l));
+  --bgcolor-global-hs: 0,0%;
+  --bgcolor-global-l: 20%;
+  --bgcolor-inline-code: #{$gray-100}; //optional
+  --bgcolor-card: #{hsl.darken(var(--bgcolor-global), 5%)};
+  --bgcolor-blinked-section: #{hsl.alpha(var(--primary),50%)};
+  --bgcolor-keyword-highlighted: #{darken($grw-marker-red, 30%)};
 
   // Font colors
-  $color-global: #ffffff;
-  $color-reversal: $gray-100;
-  $color-link: $primary;
-  $color-link-hover: lighten($color-link, 12%);
-  $color-link-wiki: $primary;
-  $color-link-wiki-hover: lighten($color-link-wiki, 12%);
-  $color-link-nabvar: $color-reversal;
-  $color-inline-code: $subthemecolor;
-  $color-inline-code: #c7254e; // optional
-  $color-search: $dark;
+  --color-global: hsl(var(--color-global-hs),var(--color-global-l));
+  --color-global-hs: 0,0%;
+  --color-global-l: 100%;
+  --color-reversal: #{$gray-100};
+  --color-link: var(--primary);
+  --color-link-hs: var(--primary-hs);
+  --color-link-l: var(--primary-l);
+  --color-link-hover: #{hsl.lighten(var(--color-link),12%)};
+  --color-link-wiki: var(--primary);
+  --color-link-wiki-hs: var(--primary-hs);
+  --color-link-wiki-l: var(--primary-l);
+  --color-link-wiki-hover: #{hsl.lighten(var(--color-link),12%)};
+  --color-link-nabvar: var(--color-reversal);
+  --color-inline-code: #c7254e; // optional
+  --color-search: #a7a7a7;
 
   // List Group colors
-  // $color-list: $color-global;
-  $bgcolor-list: transparent;
-  $color-list-hover: $accentcolor;
-  // $bgcolor-list-hover: lighten($bgcolor-global, 3%);
-  // $color-list-active: $color-reversal;
-  // $bgcolor-list-active: $primary;
+  // --color-list: var(--color-global);
+  --bgcolor-list: transparent;
+  --color-list-hover: var(--accentcolor);
+  // --bgcolor-list-hover: #{hsl.darken(var(--bgcolor-global),3%)};// optional
+  // --color-list-active: white ; // optional
+  // --bgcolor-list-active: #{hsl.lighten(var(--bgcolor-global),3%)}; // optional
 
   // Navbar
-  $bgcolor-navbar: #2c2c2c;
-  $bgcolor-search-top-dropdown: $themecolor;
-  $border-image-navbar: linear-gradient(to right, $primary 0%, darken($primary, 5%) 100%);
+  --bgcolor-navbar: hsl(var(--bgcolor-navbar-hs),var(--bgcolor-navbar-l));
+  --bgcolor-navbar-hs: 0,0%;
+  --bgcolor-navbar-l: 17%;
+  --bgcolor-search-top-dropdown: var(--primary);
+  --bgcolor-search-top-dropdown-hs: var(--primary-hs);
+  --bgcolor-search-top-dropdown-l: var(--primary-l);
+  --border-image-navbar: linear-gradient(to right, var(--primary) 0%, #{hsl.darken(var(--primary), 5%)} 100%);
 
   // Logo colors
-  $bgcolor-logo: #ffffff;
-  $fillcolor-logo-mark: #ffffff;
-  // $fillcolor-logo-mark: #4e5a60;
+  --bgcolor-logo: var(--color-global);
+  --fillcolor-logo-mark: var(--color-global);
+  // --fillcolor-logo-mark: #4e5a60;
 
   // Sidebar
-  $bgcolor-sidebar: $accentcolor;
-  // $bgcolor-sidebar-nav-item-active: rgba(#, 0.3); // optional
-  $text-shadow-sidebar-nav-item-active: 0px 0px 10px $primary; // optional
+  --bgcolor-sidebar: var(--accentcolor);
+  --bgcolor-sidebar-hs: var(--accentcolor-hs);
+  --bgcolor-sidebar-l: var(--accentcolor-l);
+  // --bgcolor-sidebar-nav-item-active: rgba(#, 0.3); // optional
+  --text-shadow-sidebar-nav-item-active: 0px 0px 10px var(--primary); // optional
+
   // Sidebar resize button
-  $color-resize-button: $color-global;
-  $bgcolor-resize-button: $primary;
-  $color-resize-button-hover: $color-global;
-  $bgcolor-resize-button-hover: darken($bgcolor-resize-button, 5%);
+  --color-resize-button: var(--color-global);
+  --bgcolor-resize-button: var(--primary);
+  --bgcolor-resize-button-hs: var(--primary-hs);
+  --bgcolor-resize-button-l: var(--primary-l);
+  --color-resize-button-hover: var(--color-global);
+  --bgcolor-resize-button-hover: #{hsl.darken(var(--primary), 5%)};
+
   // Sidebar contents
-  $bgcolor-sidebar-context: #3c403c;
-  $color-sidebar-context: $color-global;
+  --color-sidebar-context: var(--color-global);
+  --color-sidebar-context-hs: var(--color-global-hs);
+  --color-sidebar-context-l: var(--color-global-l);
+  --bgcolor-sidebar-context: hsl(var(--bgcolor-sidebar-context-hs),var(--bgcolor-sidebar-context-l));
+  --bgcolor-sidebar-context-hs: 0,2%;
+  --bgcolor-sidebar-context-l: 25%;
+
   // Sidebar list group
-  // $bgcolor-sidebar-list-group: #; // optional
+  // --bgcolor-sidebar-list-group: #; // optional
+
+  // Subnavigation
+  --bgcolor-subnav: hsl(var(--bgcolor-subnav-hs),var(--bgcolor-subnav-l));
+  --bgcolor-subnav-hs: var(--bgcolor-global-hs);
+  --bgcolor-subnav-l: calc(var(--bgcolor-global-l) - 3%);
 
   // Icon colors
-  $color-editor-icons: $color-global;
+  --color-editor-icons: var(--color-global);
 
   // Border colors
-  $border-color-theme: $primary;
-  $bordercolor-inline-code: #4d4d4d; // optional
-
-  // Dropdown colors
-  $color-dropdown-link-active: $color-global;
-  $color-dropdown-link-hover: $color-reversal;
+  --border-color-theme: var(--primary);
+  --bordercolor-inline-code: #4d4d4d; // optional
 
   // admin theme box
-  $color-theme-color-box: $primary;
-
-  @import './theme/apply-colors';
-  @import './theme/apply-colors-dark';
+  --color-theme-color-box: var(--primary);
 
   // Navs
   .nav-tabs {
-    border-bottom: $border-color-theme 1px solid;
+    border-bottom: var(--primary) 1px solid;
     .nav-link {
       &:hover {
-        border-color: lighten($border-color-theme, 10%);
+        border-color: #{hsl.lighten(var(--primary), 10%)};
         border-bottom: none;
       }
       &.active {
-        color: $color-link;
+        color: var(--primary);
         background-color: transparent;
-        border-color: $border-color-theme;
+        border-color: var(--primary);
       }
     }
   }
@@ -199,7 +250,7 @@
   // Button
   .btn-group.grw-page-editor-mode-manager {
     .btn.btn-outline-primary {
-      @include page-editor-mode-manager.btn-page-editor-mode-manager(#ffffff, $primary, $primary, darken($primary, 20%));
+      @include page-editor-mode-manager.btn-page-editor-mode-manager(#ffffff, var(--primary), var(--primary), #{hsl.darken(var(--primary), 20%)});
     }
   }
 }

+ 88 - 65
packages/preset-themes/src/styles/kibela.scss

@@ -1,85 +1,108 @@
 @use './variables' as *;
 @use './bootstrap/variables' as *;
 @use './theme/mixins/page-editor-mode-manager';
+@use './theme/hsl-functions' as hsl;
+
+:root[data-theme='light']{
+  --primary: hsl(var(--primary-hs),var(--primary-l)) !important;
+  --primary-hs: 212,80%;
+  --primary-l: 35%;
+  --secondary: hsl(var(--secondary-hs),var(--secondary-l)) !important;
+  --secondary-hs: 208,7%;
+  --secondary-l: 46%;
+  --subthemecolor: hsl(var(--subthemecolor-hs),var(--subthemecolor-l));
+  --subthemecolor-hs: 224,94%;
+  --subthemecolor-l: 66%;
+  --lightthemecolor: hsl(var(--lightthemecolor-hs),var(--lightthemecolor-l));
+  --lightthemecolor-hs: 220,80%;
+  --lightthemecolor-l: 84%;
 
-$bgcolor-theme: rgb(18, 86, 163);
-$themelight: #f4f5f6;
-$subthemecolor: rgb(88, 130, 250);
-$lightthemecolor: rgba(181, 203, 247, 0.61);
-
-// Light Mode
-:root {
   // Background colors
-  $bgcolor-navbar: white;
-  $bgcolor-navbar-active: $bgcolor-theme;
-  $bgcolor-global: $themelight;
-  $bgcolor-inline-code: lighten($subthemecolor, 70%);
-  $bgcolor-card: $lightthemecolor;
-  //$bgcolor-keyword-highlighted: $grw-marker-yellow;
+  --bgcolor-global: hsl(var(--bgcolor-global-hs),var(--bgcolor-global-l));
+  --bgcolor-global-hs: 210,10%;
+  --bgcolor-global-l: 96%;
+  --bgcolor-inline-code: #{hsl.lighten(var(--subthemecolor), 70%)};
+  --bgcolor-card: var(--lightthemecolor);
+  --bgcolor-blinked-section: #{hsl.alpha(var(--primary),80%)};
+  //--bgcolor-keyword-highlighted: #{$grw-marker-yellow};
+
+  // Font colors
+  --color-global: hsl(var(--color-global-hs),var(--color-global-l));
+  --color-global-hs: 217,23%;
+  --color-global-l: 31%;
+  --color-reversal: #{$gray-100};
+  --color-header: var(--primary);
+  --color-link: hsl(var(--color-link-hs),var(--color-link-l));
+  --color-link-hs: 224,56%;
+  --color-link-l: 55%;
+  --color-link-hover: #{hsl.lighten(var(--color-link),12%)};
+  --color-link-wiki: #{hsl.lighten(var(--primary), 20%)};
+  --color-link-wiki-hover: #{hsl.lighten(var(--primary), 40%)};
+  --color-link-nabvar: var(--color-global);
+  --color-inline-code: var(--subthemecolor);
 
-  $color-header: $bgcolor-theme;
-  $color-global: #3c4a60;
-  $color-link: rgb(74, 109, 204);
-  $color-link-hover: lighten($color-link, 12%);
-  $sidebar-text: $bgcolor-theme;
-  $color-reversal: $gray-100;
+  // List Group colors
+  --color-list: var(--color-global); // optional
+  --bgcolor-list: var(--bgcolor-global); // optional
+  --color-list-hover: var(--color-reversal);
+  --color-list-active: var(--color-reversal);
+  --bgcolor-list-active: var(--primary);
+
+  // Navbar
+  --bgcolor-navbar: hsl(var(--bgcolor-navbar-hs),var(--bgcolor-navbar-l));
+  --bgcolor-navbar-hs: 0,0%;
+  --bgcolor-navbar-l: 100%;
+  --bgcolor-search-top-dropdown: var(--primary);
+  --bgcolor-search-top-dropdown-hs: var(--primary-hs);
+  --bgcolor-search-top-dropdown-l: var(--primary-l);
 
-  $primary: $bgcolor-theme;
-  $info: lighten($bgcolor-theme, 20%);
+  // Logo colors
+  --bgcolor-logo: transparent;
+  --fillcolor-logo-mark: #{hsl.lighten(var(--primary), 20%)};
 
-  $bgcolor-blinked-section: rgba($primary, 0.2);
+  // Sidebar
+  --bgcolor-sidebar: var(--primary);
+  --bgcolor-sidebar-hs: var(--primary-hs);
+  --bgcolor-sidebar-l: var(--primary-l);
+  --bgcolor-sidebar-context: #{hsl.lighten(var(--primary), 10%)};
 
-  // List Group colors
-  $color-list: $color-global;
-  $bgcolor-list: $bgcolor-global;
-  $color-list-active: $color-reversal;
-  $bgcolor-list-active: $primary;
-  $color-list-hover: $color-reversal;
+  // Sidebar resize button
+  --color-resize-button: var(--color-reversal);
+  --bgcolor-resize-button: hsl(var(--bgcolor-resize-button-hs),var(--bgcolor-resize-button-l));
+  --bgcolor-resize-button-hs: 199,74%;
+  --bgcolor-resize-button-l: 49%;
+  --color-resize-button-hover: var(--color-reversal);
+  --bgcolor-resize-button-hover: #{hsl.lighten(var(--bgcolor-resize-button), 5%)};
 
-  // navbar
-  $bgcolor-search-top-dropdown: $primary;
+  // Sidebar contents
+  --color-sidebar-context: var(--color-global);
+  --color-sidebar-context-hs: var(--color-global-hs);
+  --color-sidebar-context-l: var(--color-global-l);
+  --bgcolor-sidebar-context: hsl(var(--bgcolor-sidebar-context-hs),var(--bgcolor-sidebar-context-l));
+  --bgcolor-sidebar-context-hs: 225,57%;
+  --bgcolor-sidebar-context-l: 97%;
 
-  // Logo colors
-  $bgcolor-logo: transparent;
-  $fillcolor-logo-mark: lighten($bgcolor-theme, 20%);
+  // Sidebar list group
+  --bgcolor-sidebar-list-group: #fafbff; // optional
 
-  // Icon colors
-  $color-editor-icons: $color-global;
+  // Subnavigation
+  --bgcolor-subnav: hsl(var(--bgcolor-subnav-hs),var(--bgcolor-subnav-l));
+  --bgcolor-subnav-hs: var(--bgcolor-global-hs);
+  --bgcolor-subnav-l: calc(var(--bgcolor-global-l) - 3%);
 
-  $color-link-wiki: lighten($bgcolor-theme, 20%);
-  $color-link-wiki-hover: lighten($color-link-wiki, 20%);
-  $color-link-nabvar: $color-global;
-  $color-link-nabvar-hover: $color-global;
-  $color-inline-code: $subthemecolor;
+  // Icon colors
+  --color-editor-icons: var(--color-global);
 
   // border colors
-  $border-color-theme: $lightthemecolor;
-  $thickborder: #5584e1;
-  $bordercolor-inline-code: $lightthemecolor;
+  --border-color-theme: var(--lightthemecolor);
+  --thickborder: #5584e1;
+  --bordercolor-inline-code: var(--lightthemecolor);
 
   // dropdown colors
-  $bgcolor-dropdown-link-active: $growi-blue;
+  --bgcolor-dropdown-link-active: #{$growi-blue};
 
   // admin theme box
-  $color-theme-color-box: lighten($bgcolor-theme, 20%);
-
-  // Sidebar
-  $bgcolor-sidebar: $bgcolor-theme;
-  $color-sidebar-context: $color-reversal;
-  $bgcolor-sidebar-context: lighten($bgcolor-theme, 10%);
-  // Sidebar resize button
-  $color-resize-button: $color-reversal;
-  $bgcolor-resize-button: #209fd8;
-  $color-resize-button-hover: $color-reversal;
-  $bgcolor-resize-button-hover: lighten($bgcolor-resize-button, 5%);
-  // Sidebar contents
-  $color-sidebar-context: $color-global;
-  $bgcolor-sidebar-context: #f4f6fc;
-  // Sidebar list group
-  $bgcolor-sidebar-list-group: #fafbff; // optional
-
-  @import './theme/apply-colors';
-  @import './theme/apply-colors-light';
+  --color-theme-color-box: #{hsl.lighten(var(--primary), 20%)};
 
   .main {
     .container,
@@ -102,9 +125,9 @@ $lightthemecolor: rgba(181, 203, 247, 0.61);
   }
 
   //Button
-  .grw-page-editor-mode-manager {
+  .btn-group.grw-page-editor-mode-manager {
     .btn.btn-outline-primary {
-      @include page-editor-mode-manager.btn-page-editor-mode-manager(darken($primary, 15%), lighten($primary, 45%), lighten($primary, 50%));
+      @include page-editor-mode-manager.btn-page-editor-mode-manager (#{hsl.darken(var(--primary), 15%)}, #{hsl.lighten(var(--primary), 45%)}, #{hsl.lighten(var(--primary), 50%)});
     }
   }
 }

+ 165 - 108
packages/preset-themes/src/styles/mono-blue.scss

@@ -1,85 +1,112 @@
 @use './variables' as *;
 @use './bootstrap/variables' as *;
 @use './theme/mixins/page-editor-mode-manager';
+@use './theme/hsl-functions' as hsl;
 
 :root[data-theme='light'] {
   // Theme colors
-  $themecolor: #00587a;
-  $themelight: #f7fbfd;
-  $accentcolor: #16617d;
-  $subthemecolor: #186718;
-
-  $primary: $themecolor;
+  --primary: hsl(var(--primary-hs),var(--primary-l)) !important;
+  --primary-hs: 197,100%;
+  --primary-l: 24%;
+  --secondary: hsl(var(--secondary-hs),var(--secondary-l)) !important;
+  --secondary-hs: 208,7%;
+  --secondary-l: 46%;
+  --accentcolor: hsl(var(--accentcolor-hs),var(--accentcolor-l));
+  --accentcolor-hs: 210,14%;
+  --accentcolor-l: 89%;
 
   // Background colors
-  $bgcolor-global: $themelight;
-  $bgcolor-inline-code: $gray-100; //optional
-  $bgcolor-card: darken($themelight, 5%);
-  $bgcolor-blinked-section: rgba($primary, 0.1);
-  //$bgcolor-keyword-highlighted: $grw-marker-yellow;
+  --bgcolor-global: hsl(var(--bgcolor-global-hs),var(--bgcolor-global-l));
+  --bgcolor-global-hs: 200,60%;
+  --bgcolor-global-l: 98%;
+  --bgcolor-inline-code: #{$gray-100}; //optional
+  --bgcolor-card: #{hsl.darken(var(--bgcolor-global), 5%)};
+  --bgcolor-blinked-section: #{hsl.alpha(var(--primary),90%)};
+  //--bgcolor-keyword-highlighted: #{$grw-marker-yellow};
 
   // Font colors
-  $color-global: $themecolor;
-  $color-reversal: $gray-100;
-  $color-link: lighten($primary, 5%);
-  $color-link-hover: lighten($color-link, 12%);
-  $color-link-wiki: lighten($primary, 20%);
-  $color-link-wiki-hover: lighten($color-link-wiki, 20%);
-  $color-link-nabvar: $color-reversal;
-  $color-inline-code: #c7254e; // optional
-  $color-search: #c0d6df;
+  --color-global: var(--primary);
+  --color-global-hs: var(--primary-hs);
+  --color-global-l: var(--primary-l);
+  --color-reversal: #{$gray-100};
+  --color-link: #{hsl.lighten(var(--primary),5%)};
+  --color-link-hs: var(--primary-hs);
+  --color-link-l: calc(var(--primary-l) + 5%);
+  --color-link-hover: #{hsl.lighten(var(--color-link), 12%)};
+  --color-link-wiki: #{hsl.lighten(var(--primary),20%)};
+  --color-link-wiki-hs: var(--primary-hs);
+  --color-link-wiki-l: calc(var(--primary-l) + 20%);
+  --color-link-wiki-hover: #{hsl.lighten(var(--primary),40%)};
+  --color-link-nabvar: var(--color-reversal);
+  --color-inline-code: #c7254e; // optional
+  --color-search: #c0d6df;
 
   // List Group colors
-  // $color-list: $color-global;
-  $bgcolor-list: transparent;
-  $color-list-hover: $color-search;
-  $bgcolor-list-hover: lighten($primary, 70%);
-  // $color-list-active: $color-reversal;
-  // $bgcolor-list-active: $primary;
+  // --color-list: var(--color-global);
+  --bgcolor-list: transparent;
+  --color-list-hover: var(--color-search);
+  --bgcolor-list-hover: #{hsl.lighten(var(--primary), 70%)};
+  // --color-list-active: var(--color-reversal);
+  // --bgcolor-list-active: var(--primary);
 
   // Navbar
-  $bgcolor-navbar: #2a2929;
-  $bgcolor-search-top-dropdown: $themecolor;
-  $border-image-navbar: linear-gradient(to right, #54bafd 0%, #3d98a3 50%, #708b0b 100%);
+  --bgcolor-navbar: hsl(var(--bgcolor-navbar-hs),var(--bgcolor-navbar-l));
+  --bgcolor-navbar-h: 0;
+  --bgcolor-navbar-s: 1%;
+  --bgcolor-navbar-l: 16%;
+  --bgcolor-navbar-hs: 0,1%;
+  --bgcolor-search-top-dropdown: var(--primary);
+  --bgcolor-search-top-dropdown-hs: var(--primary-hs);
+  --bgcolor-search-top-dropdown-l: var(--primary-l);
+  --border-image-navbar: linear-gradient(to right, #54bafd 0%, #3d98a3 50%, #708b0b 100%);
 
   // Logo colors
-  $bgcolor-logo: $themecolor;
-  $fillcolor-logo-mark: lighten(desaturate($bgcolor-navbar, 10%), 15%);
+  --bgcolor-logo: var(--primary);
+  --fillcolor-logo-mark: hsl(var(--bgcolor-navbar-h),calc(var(--bgcolor-navbar-s) - 10%),calc(var(--bgcolor-navbar-l) + 15%));
 
   // Sidebar
-  $bgcolor-sidebar: $themecolor;
-  // $bgcolor-sidebar-nav-item-active: rgba(#, 0.37); // optional
-  $text-shadow-sidebar-nav-item-active: 0px 0px 10px #0099ff; // optional
+  --bgcolor-sidebar: var(--primary);
+  --bgcolor-sidebar-hs: var(--primary-hs);
+  --bgcolor-sidebar-l: var(--primary-l);
+
+  // --bgcolor-sidebar-nav-item-active: rgba(#, 0.37); // optional
+  --text-shadow-sidebar-nav-item-active: 0px 0px 10px #0099ff; // optional
+
   // Sidebar resize button
-  $color-resize-button: $color-reversal;
-  $bgcolor-resize-button: #209fd8;
-  $color-resize-button-hover: $color-reversal;
-  $bgcolor-resize-button-hover: lighten($bgcolor-resize-button, 5%);
+  --color-resize-button: var(--color-reversal);
+  --bgcolor-resize-button: hsl(var(--bgcolor-resize-button-hs),var(--bgcolor-resize-button-l));
+  --bgcolor-resize-button-hs: 199,74%;
+  --bgcolor-resize-button-l: 49%;
+  --color-resize-button-hover: var(--color-reversal);
+  --bgcolor-resize-button-hover: #{hsl.lighten(var(--bgcolor-resize-button), 5%)};
+
   // Sidebar contents
-  $color-sidebar-context: $color-global;
-  $bgcolor-sidebar-context: #f1fcff;
+  --color-sidebar-context: var(--color-global);
+  --color-sidebar-context-hs: var(--color-global-hs);
+  --color-sidebar-context-l: var(--color-global-l);
+  --bgcolor-sidebar-context: hsl(var(--bgcolor-sidebar-context-hs),var(--bgcolor-sidebar-context-l));
+  --bgcolor-sidebar-context-hs: 193,100%;
+  --bgcolor-sidebar-context-l: 97%;
+
   // Sidebar list group
-  // $bgcolor-sidebar-list-group: #; // optional
+  // --bgcolor-sidebar-list-group: #; // optional
 
   // Icon colors
-  $color-editor-icons: $color-global;
+  --color-editor-icons: var(--color-global);
 
   // Border colors
-  $border-color-theme: $gray-300;
-  $bordercolor-inline-code: #ccc8c8; // optional
+  --border-color-theme: var(--accentcolor);
+  --bordercolor-inline-code: #ccc8c8; // optional
 
   // admin theme box
-  $color-theme-color-box: lighten($primary, 20%);
-
-  @import './theme/apply-colors';
-  @import './theme/apply-colors-light';
+  --color-theme-color-box: #{hsl.lighten(var(--primary), 20%)};
 
   // Navs {
   .nav-tabs {
-    border-bottom: $border-color-theme 1px solid;
+    border-bottom: var(--accentcolor) 1px solid;
     .nav-link {
       &:hover {
-        border-color: lighten($border-color-theme, 10%);
+        border-color: #{hsl.lighten(var(--accentcolor),10%)};
         border-bottom: none;
       }
       &.active {
@@ -90,99 +117,129 @@
   // Button
   .btn-group.grw-page-editor-mode-manager {
     .btn.btn-outline-primary {
-      @include page-editor-mode-manager.btn-page-editor-mode-manager($primary, lighten($primary, 65%), lighten($primary, 70%));
+      @include page-editor-mode-manager.btn-page-editor-mode-manager(var(--primary), #{hsl.lighten(var(--primary), 65%)}, #{hsl.lighten(var(--primary), 70%)});
     }
   }
 }
 
 :root[data-theme='dark'] {
   // Theme colors
-  $themecolor: #00587a;
-  $themedark: #061f2f;
-  $accentcolor: #16617d;
-  $subthemecolor: #c1f1f0;
-
-  $primary: #0090c8;
-  $dark: #031018;
+  --primary: hsl(var(--primary-hs),var(--primary-l)) !important;
+  --primary-hs: 197,100%;
+  --primary-l: 39%;
+  --secondary: hsl(var(--secondary-hs),var(--secondary-l)) !important;
+  --secondary-hs: 208,7%;
+  --secondary-l: 46%;
+  --accentcolor: hsl(var(--accentcolor-hs),var(--accentcolor-l));
+  --accentcolor-hs: 203,78%;
+  --accentcolor-l: 35%;
 
   // Background colors
-  $bgcolor-global: $themedark;
-  $bgcolor-navbar: #27343b;
-  $bgcolor-inline-code: #1f1f22; //optional
-  $bgcolor-card: darken($themedark, 5%);
-  $bgcolor-blinked-section: rgba($primary, 0.5);
-  $bgcolor-keyword-highlighted: darken($grw-marker-red, 30%);
+  --bgcolor-global: hsl(var(--bgcolor-global-hs),var(--bgcolor-global-l));
+  --bgcolor-global-hs: 203,77%;
+  --bgcolor-global-l: 10%;
+  --bgcolor-navbar: hsl(var(--bgcolor-navbar-hs),var(--bgcolor-navbar-l));
+  --bgcolor-navbar-hs: 201,20%;
+  --bgcolor-navbar-l: 19%;
+  --bgcolor-inline-code: #1f1f22; //optional
+  --bgcolor-card: #{hsl.darken(var(--bgcolor-global), 5%)};
+  --bgcolor-blinked-section: #{hsl.alpha(var(--primary),50%)};
+  --bgcolor-keyword-highlighted: #{darken($grw-marker-red, 30%)};
 
   // Font colors
-  $color-global: #d3d4d4;
-  $color-reversal: $gray-100;
-  $color-link: #97d1f0;
-  $color-link-hover: darken($color-link, 12%);
-  $color-link-wiki: lighten($primary, 20%);
-  $color-link-wiki-hover: lighten($color-link-wiki, 20%);
-  $color-link-nabvar: $color-reversal;
-  $color-inline-code: $subthemecolor;
-  $color-inline-code: #c7254e; // optional
-  $color-search: #000102;
+  --color-global: hsl(var(--color-global-hs),var(--color-global-l));
+  --color-global-hs: 180,1%;
+  --color-global-l: 83%;
+  --color-reversal: #{$gray-100};
+  --color-link: hsl(var(--color-link-hs),var(--color-link-l));
+  --color-link-hs: 201,75%;
+  --color-link-l: 77%;
+  --color-link-hover: #{hsl.darken(var(--color-link), 12%)};
+  --color-link-wiki: #{hsl.lighten(var(--primary),20%)};
+  --color-link-wiki-hs: var(--primary-hs);
+  --color-link-wiki-l: calc(var(--primary-l) + 20%);
+  --color-link-wiki-hover: #{hsl.lighten(var(--primary),40%)};
+  --color-link-nabvar: var(--color-reversal);
+  --color-inline-code: #c7254e; // optional
+  --color-search: #000102;
 
   // List Group colors
-  // $color-list: $color-global;
-  $bgcolor-list: transparent;
-  $color-list-hover: $accentcolor;
-  // $bgcolor-list-hover: lighten($bgcolor-global, 3%);
-  // $color-list-active: $color-reversal;
-  // $bgcolor-list-active: $primary;
+  // --color-list: var(--color-global);
+  --bgcolor-list: transparent;
+  --color-list-hover: #16617d;
+  // --bgcolor-list-hover: #{hsl.lighten(var(--bgcolor-global),3%)}; // optional
+  // --color-list-active: var(--color-reversal);
+  // --bgcolor-list-active: var(--primary);
 
   // Navbar
-  $bgcolor-navbar: #2a2929;
-  $bgcolor-search-top-dropdown: $themecolor;
-  $border-image-navbar: linear-gradient(to right, #54bafd 0%, #3d98a3 50%, #708b0b 100%);
+  --bgcolor-navbar: hsl(var(--bgcolor-navbar-hs),var(--bgcolor-navbar-l));
+  --bgcolor-navbar-h: 0;
+  --bgcolor-navbar-s: 1%;
+  --bgcolor-navbar-l: 16%;
+  --bgcolor-navbar-hs:var(--bgcolor-navbar-h),var(--bgcolor-navbar-s);
+  --bgcolor-search-top-dropdown: var(--primary);
+  --bgcolor-search-top-dropdown-hs: var(--primary-hs);
+  --bgcolor-search-top-dropdown-l: var(--primary-l);
+  --border-image-navbar: linear-gradient(to right, #54bafd 0%, #3d98a3 50%, #708b0b 100%);
 
   // Logo colors
-  $bgcolor-logo: #13191c;
-  $fillcolor-logo-mark: lighten(desaturate($bgcolor-navbar, 10%), 15%);
-  // $fillcolor-logo-mark: #4e5a60;
+  --bgcolor-logo: #13191c;
+  --fillcolor-logo-mark: hsl(var(--bgcolor-navbar-h),calc(var(--bgcolor-navbar-s) - 10%),calc(var(--bgcolor-navbar-l) + 15%));
+  // --fillcolor-logo-mark: #4e5a60;
 
   // Sidebar
-  $bgcolor-sidebar: $accentcolor;
-  // $bgcolor-sidebar-nav-item-active: rgba(#, 0.3); // optional
-  $text-shadow-sidebar-nav-item-active: 0px 0px 10px #0099ff; // optional
+  --bgcolor-sidebar: hsl(var(--bgcolor-sidebar-hs),var(--bgcolor-sidebar-l));
+  --bgcolor-sidebar-hs: 196,70%;
+  --bgcolor-sidebar-l: 29%;
+  // --bgcolor-sidebar-nav-item-active: rgba(#, 0.3); // optional
+  --text-shadow-sidebar-nav-item-active: 0px 0px 10px #0099ff; // optional
+
   // Sidebar resize button
-  $color-resize-button: $color-global;
-  $bgcolor-resize-button: $themecolor;
-  $color-resize-button-hover: $color-global;
-  $bgcolor-resize-button-hover: darken($bgcolor-resize-button, 5%);
+  --color-resize-button: var(--color-global);
+  --bgcolor-resize-button: var(--primary);
+  --bgcolor-resize-button-hs: var(--primary-hs);
+  --bgcolor-resize-button-l: var(--primary-l);
+  --color-resize-button-hover: var(--color-global);
+  --bgcolor-resize-button-hover: #{hsl.darken(var(--primary), 5%)};
+
   // Sidebar contents
-  $bgcolor-sidebar-context: darken($bgcolor-sidebar, 13%);
-  $color-sidebar-context: $color-global;
+  --bgcolor-sidebar-context: #{hsl.darken(var(--bgcolor-sidebar), 13%)};
+  --bgcolor-sidebar-context-hs: var(--bgcolor-sidebar-hs);
+  --bgcolor-sidebar-context-l: calc(var(--bgcolor-sidebar-l) - 13%);
+  --color-sidebar-context: var(--color-global);
+  --color-sidebar-context-hs: var(--color-global-hs);
+  --color-sidebar-context-l: var(--color-global-l);
+
   // Sidebar list group
-  // $bgcolor-sidebar-list-group: #; // optional
+  // --bgcolor-sidebar-list-group: #; // optional
+
+  // Subnavigation
+  --bgcolor-subnav: hsl(var(--bgcolor-subnav-hs),var(--bgcolor-subnav-l));
+  --bgcolor-subnav-hs: var(--bgcolor-global-hs);
+  --bgcolor-subnav-l: calc(var(--bgcolor-global-l) - 3%);
 
   // Icon colors
-  $color-editor-icons: $color-global;
+  --color-editor-icons: var(--color-global);
 
   // Border colors
-  $border-color-theme: #146aa0;
-  $bordercolor-inline-code: #4d4d4d; // optional
+  --border-color-theme: var(--accentcolor);
+  --bordercolor-inline-code: #4d4d4d; // optional
 
   // admin theme box
-  $color-theme-color-box: $primary;
-
-  @import './theme/apply-colors';
-  @import './theme/apply-colors-dark';
+  --color-theme-color-box: var(--primary);
 
   // Navs
   .nav-tabs {
-    border-bottom: $border-color-theme 1px solid;
+    border-bottom: var(--accentcolor) 1px solid;
     .nav-link {
       &:hover {
-        border-color: lighten($border-color-theme, 10%);
+        border-color: #{hsl.lighten(var(--accentcolor), 10%)};
         border-bottom: none;
       }
       &.active {
-        color: $color-link;
+        color: var(--color-link);
         background-color: transparent;
-        border-color: $border-color-theme;
+        border-color: var(--accentcolor);
       }
     }
   }
@@ -195,7 +252,7 @@
   // Button
   .btn-group.grw-page-editor-mode-manager {
     .btn.btn-outline-primary {
-      @include page-editor-mode-manager.btn-page-editor-mode-manager(lighten($primary, 30%), $primary, darken($primary, 10%), darken($primary, 20%));
+      @include page-editor-mode-manager.btn-page-editor-mode-manager(#{hsl.lighten(var(--primary), 30%)}, var(--primary), #{hsl.darken(var(--primary), 10%)}, #{hsl.darken(var(--primary), 20%)});
     }
   }
 }

+ 70 - 54
packages/preset-themes/src/styles/nature.scss

@@ -1,18 +1,7 @@
 @use './variables' as *;
 @use './bootstrap/variables' as *;
 @use './theme/mixins/page-editor-mode-manager';
-
-// == Define Bootstrap theme colors
-//
-
-// colors for overriding bootstrap $theme-colors
-// $secondary: #;
-// $info: #;
-// $success: #;
-// $warning: #;
-// $danger: #;
-// $light: #;
-// $dark: #;
+@use './theme/hsl-functions' as hsl;
 
 .growi:not(.login-page) {
   // add background-image
@@ -23,86 +12,113 @@
   }
 }
 
-$themecolor: #12b105;
-
 //== Light Mode
 //
-:root {
-  $primary: #460039;
-  $light: $gray-100;
+:root[data-theme='light'] {
+  --primary: hsl(var(--primary-hs),var(--primary-l)) !important;
+  --primary-hs: 311,100%;
+  --primary-l: 14%;
+  --secondary: hsl(var(--secondary-hs),var(--secondary-l)) !important;
+  --secondary-hs: 208,7%;
+  --secondary-l: 46%;
 
   // Background colors
-  $bgcolor-global: #fdfdfd;
-  $bgcolor-inline-code: $gray-100; //optional
-  $bgcolor-card: #f1ffe4;
-  $bgcolor-subnav: #fafafa;
-  $bgcolor-blinked-section: rgba($primary, 0.1);
-  //$bgcolor-keyword-highlighted: $grw-marker-yellow;
+  --bgcolor-global: hsl(var(--bgcolor-global-hs),var(--bgcolor-global-l));
+  --bgcolor-global-hs: 0,0%;
+  --bgcolor-global-l: 99%;
+  --bgcolor-inline-code: #{$gray-100}; //optional
+  --bgcolor-card: #f1ffe4;
+  --bgcolor-blinked-section: #{hsl.alpha(var(--primary), 90%)};
+  //--bgcolor-keyword-highlighted: #{$grw-marker-yellow};
 
   // Font colors
-  $color-global: #460039;
-  $color-reversal: #eeeeee;
-  $color-link: #7e0044;
-  $color-link-hover: lighten($color-link, 20%);
-  $color-link-wiki: lighten($primary, 20%);
-  $color-link-wiki-hover: lighten($color-link-wiki, 20%);
-  $color-link-nabvar: #a7a7a7;
-  $color-inline-code: #c7254e; // optional
-  $color-search: white;
+  --color-global: hsl(var(--color-global-hs),var(--color-global-l));
+  --color-global-hs: 311,100%;
+  --color-global-l: 14%;
+  --color-reversal: #eeeeee;
+  --color-link: hsl(var(--color-link-hs),var(--color-link-l));
+  --color-link-hs: 328,100%;
+  --color-link-l: 25%;
+  --color-link-hover: #{hsl.lighten(var(--color-link), 20%)};
+  --color-link-wiki: #{hsl.lighten(var(--primary), 20%)};
+  --color-link-wiki-hs: var(--primary-hs);
+  --color-link-wiki-l: calc(var(--primary-l) + 20%);
+  --color-link-wiki-hover: #{hsl.lighten(var(--primary), 40%)};
+  --color-link-nabvar: #a7a7a7;
+  --color-inline-code: #c7254e; // optional
+  --color-search: white;
 
   // Navbar
-  $bgcolor-navbar: #234136;
-  $bgcolor-search-top-dropdown: $themecolor;
-  $border-image-navbar: linear-gradient(to right, #5c78ef 0%, #16bc42 50%, #5c78ef 100%);
+  --bgcolor-navbar: hsl(var(--bgcolor-navbar-hs),var(--bgcolor-navbar-l));
+  --bgcolor-navbar-hs: 158,30%;
+  --bgcolor-navbar-l: 20%;
+  --bgcolor-search-top-dropdown: hsl(var(--bgcolor-search-top-dropdown-hs),var(--bgcolor-search-top-dropdown-l));
+  --bgcolor-search-top-dropdown-hs: 115,95%;
+  --bgcolor-search-top-dropdown-l: 36%;
+  --border-image-navbar: linear-gradient(to right, #5c78ef 0%, #16bc42 50%, #5c78ef 100%);
 
   // Logo colors
-  $bgcolor-logo: $bgcolor-navbar;
-  $fillcolor-logo-mark: lighten(desaturate($bgcolor-inline-code, 10%), 15%);
+  --bgcolor-logo: var(--bgcolor-navbar);
+  --fillcolor-logo-mark: #{lighten(desaturate($gray-100, 10%), 15%)};
 
   // Sidebar
-  $bgcolor-sidebar: #188f64;
+  --bgcolor-sidebar: hsl(var(--bgcolor-sidebar-hs),var(--bgcolor-sidebar-l));
+  --bgcolor-sidebar-hs: 158,71%;
+  --bgcolor-sidebar-l: 33%;
+
   // Sidebar contents
-  $color-sidebar-context: #7e0044;
-  $bgcolor-sidebar-context: #f4f5ec;
+  --color-sidebar-context: hsl(var(--color-sidebar-context-hs),var(--color-sidebar-context-l));
+  --color-sidebar-context-hs: 328,100%;
+  --color-sidebar-context-l: 25%;
+  --bgcolor-sidebar-context: hsl(var(--bgcolor-sidebar-context-hs),var(--bgcolor-sidebar-context-l));
+  --bgcolor-sidebar-context-hs: 67,31%;
+  --bgcolor-sidebar-context-l: 94%;
+
   // Sidebar resize button
-  $color-resize-button: white;
-  $bgcolor-resize-button: $themecolor;
+  --color-resize-button: white;
+  --bgcolor-resize-button: hsl(var(--bgcolor-resize-button-hs),var(--bgcolor-resize-button-l));
+  --bgcolor-resize-button-hs: 115,95%;
+  --bgcolor-resize-button-l: 36%;
+  --color-resize-button-hover: var(--color-reversal);
+  --bgcolor-resize-button-hover: #{hsl.lighten(var(--bgcolor-resize-button), 5%)};
+
+  // Subnavigation
+  --bgcolor-subnav: hsl(var(--bgcolor-subnav-hs),var(--bgcolor-subnav-l));
+  --bgcolor-subnav-hs: 0,0%;
+  --bgcolor-subnav-l: 98%;
 
   // Icon colors
-  $color-editor-icons: $color-global;
+  --color-editor-icons: var(--color-global);
 
   // Border colors
-  $border-color-theme: $gray-300;
-  $bordercolor-inline-code: #ccc8c8; // optional
+  --border-color-theme: #{$gray-300};
+  --bordercolor-inline-code: #ccc8c8; // optional
 
   // Table colors
-  $border-color-table: $gray-400; // optional
+  --border-color-table: #{$gray-400}; // optional
 
   // admin theme box
-  $color-theme-color-box: lighten($primary, 20%);
-
-  @import './theme/apply-colors';
-  @import './theme/apply-colors-light';
+  --color-theme-color-box: #{hsl.lighten(var(--primary), 20%)};
 
   // Search Top
   .grw-global-search {
     .btn-secondary.dropdown-toggle {
-      color: $color-search;
+      color: var(--color-search);
     }
   }
 
   // Navs
   .nav-tabs .nav-link.active {
-    color: $color-link !important;
+    color: var(--color-link) !important;
     &:hover {
-      color: $color-link-hover !important;
+      color: var(--color-link-hover) !important;
     }
   }
 
   // Button
   .btn-group.grw-page-editor-mode-manager {
     .btn.btn-outline-primary {
-      @include page-editor-mode-manager.btn-page-editor-mode-manager($bgcolor-navbar, lighten($bgcolor-navbar, 65%), lighten($bgcolor-navbar, 70%));
+      @include page-editor-mode-manager.btn-page-editor-mode-manager(var(--bgcolor-navbar), #{hsl.lighten(var(--bgcolor-navbar), 65%)}, #{hsl.lighten(var(--bgcolor-navbar), 70%)});
     }
   }
 }

+ 89 - 77
packages/preset-themes/src/styles/spring.scss

@@ -1,98 +1,106 @@
 @use './variables' as *;
 @use './bootstrap/variables' as *;
 @use './theme/mixins/page-editor-mode-manager';
-@use './bootstrap/init' as bs;
-
-// == Define Bootstrap theme colors
-//
-
-// colors for overriding bootstrap $theme-colors
-// $secondary: #;
-// $info: #;
-// $success: #;
-// $warning: #;
-// $danger: #;
-// $light: #;
-// $dark: #;
-
-$themecolor: #ffb8c6;
-$themelight: #fff0f5;
-$subthemecolor: #67a856;
-$third-main-color: antiquewhite;
-$accentcolor: #e08dbc;
-
-.grw-navbar {
-  border-bottom: $accentcolor 4px solid;
-}
+@use './theme/mixins/hsl-button';
+@use './theme/hsl-functions' as hsl;
 
 //== Light Mode
 //
-:root {
-  $primary: $themecolor;
-  $secondary: $accentcolor;
+:root[data-theme='light'] {
+  --primary: hsl(var(--primary-hs),var(--primary-l)) !important;
+  --primary-hs: 348,100%;
+  --primary-l: 86%;
+  --secondary: hsl(var(--secondary-hs),var(--secondary-l)) !important;
+  --secondary-hs: 326,57%;
+  --secondary-l: 72%;
 
   // Background colors
-  $bgcolor-global: white;
-  $bgcolor-inline-code: $gray-100; //optional
-  $bgcolor-card: $gray-50;
-  $bgcolor-blinked-section: rgba($primary, 0.5);
-  $bgcolor-keyword-highlighted: $grw-marker-cyan;
+  --bgcolor-global: hsl(var(--bgcolor-global-hs),var(--bgcolor-global-l));
+  --bgcolor-global-hs: 0,0%;
+  --bgcolor-global-l: 100%;
+  --bgcolor-inline-code: #{$gray-100}; //optional
+  --bgcolor-card: #{$gray-50};
+  --bgcolor-blinked-section: #{hsl.alpha(var(--primary), 50%)};
+  --bgcolor-keyword-highlighted: #{$grw-marker-cyan};
 
   // Font colors
-  $color-global: black;
-  $color-reversal: white;
-  $color-link: $subthemecolor;
-  $color-link-hover: lighten($subthemecolor, 10%);
-  $color-link-wiki: $subthemecolor;
-  $color-link-wiki-hover: lighten($color-link-wiki, 10%);
-  $color-link-nabvar: $bgcolor-global;
-  $color-inline-code: #c7254e; // optional
+  --color-global: hsl(var(--color-global-hs),var(--color-global-l));
+  --color-global-hs: 0,0%;
+  --color-global-l: 0%;
+  --color-reversal: white;
+  --color-link: hsl(var(--color-link-hs),var(--color-link-l));
+  --color-link-hs: 108,32%;
+  --color-link-l: 50%;
+  --color-link-hover: #{hsl.lighten(var(--color-link), 10%)};
+  --color-link-wiki: var(--color-link);
+  --color-link-wiki-hs: var(--color-link-hs);
+  --color-link-wiki-l: var(--color-link-l);
+  --color-link-wiki-hover: #{hsl.lighten(var(--color-link), 10%)};
+  --color-link-nabvar: var(--bgcolor-global);
+  --color-inline-code: #c7254e; // optional
 
   // List Group colors
   // $color-list: $color-global;
-  $bgcolor-list: $themelight;
-  $color-list-hover: lighten($accentcolor, 20%);
-  $bgcolor-list-hover: darken($bgcolor-list, 2%);
-  $color-list-active: $bgcolor-global;
-  $bgcolor-list-active: $accentcolor;
+  --bgcolor-list: #fff0f5;
+  --color-list-hover: #{hsl.lighten(var(--secondary), 20%)};
+  --bgcolor-list-hover: #{darken(#fff0f5, 2%)};
+  --color-list-active: var(--bgcolor-global);
+  --bgcolor-list-active: var(--secondary);
 
   // Navbar
-  $bgcolor-navbar: #d3687c;
-  $bgcolor-search-top-dropdown: $themecolor;
-  $border-image-navbar: linear-gradient(to right, #cbe682 0%, #4ad6e8 50%, #ea42f0 100%);
+  --bgcolor-navbar: hsl(var(--bgcolor-navbar-hs),var(--bgcolor-navbar-l));
+  --bgcolor-navbar-hs: 349,55%;
+  --bgcolor-navbar-l: 62%;
+  --bgcolor-search-top-dropdown: var(--primary);
+  --bgcolor-search-top-dropdown-hs: var(--primary-hs);
+  --bgcolor-search-top-dropdown-l: var(--primary-l);
+  --border-image-navbar: linear-gradient(to right, #cbe682 0%, #4ad6e8 50%, #ea42f0 100%);
 
   // Logo colors
-  $bgcolor-logo: $bgcolor-navbar;
-  $fillcolor-logo-mark: lighten(desaturate($bgcolor-inline-code, 10%), 15%);
+  --bgcolor-logo: var(--bgcolor-navbar);
+  --fillcolor-logo-mark: #{lighten(desaturate($gray-100, 10%), 15%)};
 
   // Sidebar
-  $bgcolor-sidebar: $themecolor;
+  --bgcolor-sidebar: var(--primary);
+  --bgcolor-sidebar-hs: var(--primary-hs);
+  --bgcolor-sidebar-l: var(--primary-l);
+
   // Sidebar resize button
-  $color-resize-button: $color-reversal;
-  $bgcolor-resize-button: $subthemecolor;
-  $color-resize-button-hover: $color-reversal;
-  $bgcolor-resize-button-hover: lighten($bgcolor-resize-button, 5%);
+  --color-resize-button: var(--color-reversal);
+  --bgcolor-resize-button: var(--color-link);
+  --bgcolor-resize-button-hs: var(--color-link-hs);
+  --bgcolor-resize-button-l: var(--color-link-l);
+  --color-resize-button-hover: var(--color-reversal);
+  --bgcolor-resize-button-hover: #{hsl.lighten(var(--color-link), 5%)};
+
   // Sidebar contents
-  $color-sidebar-context: $subthemecolor;
-  $bgcolor-sidebar-context: #fdfffe;
+  --color-sidebar-context: var(--color-link);
+  --color-sidebar-context-hs: var(--color-link-hs);
+  --color-sidebar-context-l: var(--color-link-l);
+  --bgcolor-sidebar-context: hsl(var(--bgcolor-sidebar-context-hs),var(--bgcolor-sidebar-context-l));
+  --bgcolor-sidebar-context-hs: 150,100%;
+  --bgcolor-sidebar-context-l: 100%;
+
   // Sidebar list group
-  $bgcolor-sidebar-list-group: #fafbff; // optional
+  --bgcolor-sidebar-list-group: #fafbff; // optional
+
+  // Subnavigation
+  --bgcolor-subnav: hsl(var(--bgcolor-subnav-hs),var(--bgcolor-subnav-l));
+  --bgcolor-subnav-hs: var(--bgcolor-global-hs);
+  --bgcolor-subnav-l: calc(var(--bgcolor-global-l) + 4%);
 
   // Icon colors
-  $color-editor-icons: $color-global;
+  --color-editor-icons: var(--color-global);
 
   // Border colors
-  $border-color-theme: $gray-300; // former: `$navbar-border: $gray-300;`
-  $bordercolor-inline-code: #ccc8c8; // optional
+  --border-color-theme: #{$gray-300}; // former: `$navbar-border: $gray-300;`
+  --bordercolor-inline-code: #ccc8c8; // optional
 
   // Dropdown colors
-  $bgcolor-dropdown-link-active: $growi-blue;
+  --bgcolor-dropdown-link-active: #{$growi-blue};
 
   // admin theme box
-  $color-theme-color-box: darken($primary, 20%);
-
-  @import './theme/apply-colors';
-  @import './theme/apply-colors-light';
+  --color-theme-color-box: #{hsl.darken(var(--primary), 20%)};
 
   &, body {
     background-image: url('../images/spring/spring02.svg');
@@ -101,21 +109,25 @@ $accentcolor: #e08dbc;
     background-size: cover;
   }
 
+  .grw-navbar {
+    border-bottom: var(--secondary) 4px solid;
+  }
+
   //Button
   // Outline buttons are applyed the accent color to this spring theme cuz the primary is too light and it looks like unable to click them.
   .btn.btn-outline-primary {
-    @include bs.button-outline-variant($accentcolor, $accentcolor, lighten($accentcolor, 20%), $accentcolor);
+    @include hsl-button.button-outline-variant(var(--secondary), var(--secondary), #{hsl.lighten(var(--secondary), 20%)}, var(--secondary));
   }
   .btn-group.grw-page-editor-mode-manager {
     .btn.btn-outline-primary {
-      @include page-editor-mode-manager.btn-page-editor-mode-manager(darken($primary, 50%), lighten($primary, 5%), lighten($primary, 10%));
+      @include page-editor-mode-manager.btn-page-editor-mode-manager(#{hsl.darken(var(--primary), 50%)}, #{hsl.lighten(var(--primary), 5%)}, #{hsl.lighten(var(--primary), 10%)});
     }
   }
 
   .growi:not(.login-page) {
     // add background-image
     .page-editor-preview-container {
-      background-image: url('/images/themes/spring/spring02.svg');
+      background-image: url('../images/spring/spring02.svg');
       background-attachment: fixed;
       background-position: bottom;
       background-size: cover;
@@ -125,7 +137,7 @@ $accentcolor: #e08dbc;
   // login and register
   .nologin {
     background: unset !important;
-    background-image: url('/images/themes/spring/spring.svg');
+    background-image: url('../images/spring/spring.svg');
     background-attachment: fixed;
     background-position: bottom;
     background-size: cover;
@@ -136,44 +148,44 @@ $accentcolor: #e08dbc;
     }
 
     .link-switch {
-      color: $color-global;
+      color: var(--color-global);
     }
 
     .grw-external-auth-form {
-      border-color: $accentcolor !important;
+      border-color: var(--secondary) !important;
     }
   }
 
   .table {
-    background-color: $bgcolor-global;
+    background-color: var(--bgcolor-global);
   }
 
   /*
     Cards
   */
   .card-timeline > .card-header {
-    background-color: $third-main-color;
+    background-color: antiquewhite;
   }
 
   .admin-bot-card {
     .grw-botcard-title-active {
-      color: $color-reversal;
+      color: var(--color-reversal);
     }
   }
 
   h1,
   h2 {
-    color: $subthemecolor;
+    color: var(--color-link);
 
     svg {
-      fill: $subthemecolor;
+      fill: var(--color-link);
     }
   }
 
   .nav.nav-tabs {
     > .nav-item {
       > .nav-link.active {
-        color: $subthemecolor;
+        color: var(--color-link);
       }
     }
   }

+ 0 - 538
packages/preset-themes/src/styles/theme/_apply-colors-dark.scss

@@ -1,538 +0,0 @@
-@use '../variables' as var;
-@use '../bootstrap/init' as *;
-@use '../atoms/mixins/buttons' as mixins-buttons;
-@use './mixins/count-badge';
-
-// determine optional variables
-$color-list: $color-global !default;
-$bgcolor-list: $bgcolor-global !default;
-$color-list-hover: $color-global !default;
-$bgcolor-list-hover: lighten($bgcolor-global, 8%) !default;
-$color-list-active: $color-reversal !default;
-$bgcolor-list-active: $primary !default;
-$bgcolor-subnav: lighten($bgcolor-global, 3%) !default;
-$color-table: white !default;
-$bgcolor-table: #343a40 !default;
-$border-color-table: lighten($bgcolor-table, 7.5%) !default;
-$color-table-hover: rgba(white, 0.075) !default;
-$bgcolor-table-hover: lighten($bgcolor-table, 7.5%) !default;
-$bgcolor-sidebar-list-group: $bgcolor-list !default;
-$color-tags: #949494 !default;
-$bgcolor-tags: $dark !default;
-$border-color-global: $gray-500 !default;
-$border-color-toc: $border-color-global !default;
-$color-dropdown: $color-global !default;
-$bgcolor-dropdown: $bgcolor-global !default;
-$color-dropdown-link: $color-global !default;
-$color-dropdown-link-hover: $light !default;
-$bgcolor-dropdown-link-hover: lighten($bgcolor-global, 15%) !default;
-$color-dropdown-link-active: $light !default;
-$bgcolor-dropdown-link-active: $primary !default;
-
-// override bootstrap variables
-$text-muted: $gray-550;
-$table-dark-color: $color-table;
-$table-dark-bg: $bgcolor-table;
-$table-dark-border-color: $border-color-table;
-$table-dark-hover-color: $color-table-hover;
-$table-dark-hover-bg: $bgcolor-table-hover;
-$border-color: $border-color-global;
-$dropdown-color: $color-dropdown;
-$dropdown-bg: $bgcolor-dropdown;
-$dropdown-link-color: $color-dropdown-link;
-$dropdown-link-hover-color: $color-dropdown-link-hover;
-$dropdown-link-hover-bg: $bgcolor-dropdown-link-hover;
-$dropdown-link-active-color: $color-dropdown-link-active;
-$dropdown-link-active-bg: $bgcolor-dropdown-link-active;
-
-@import './mixins/list-group';
-@import './reboot-bootstrap-text';
-@import './reboot-bootstrap-border-colors';
-@import './reboot-bootstrap-tables';
-@import './reboot-bootstrap-dropdown';
-
-// List Group
-@include override-list-group-item($color-list, $bgcolor-list, $color-list-hover, $bgcolor-list-hover, $color-list-active, $bgcolor-list-active);
-
-/*
-  * Form
-  */
-input.form-control,
-select.form-control,
-select.custom-select,
-textarea.form-control {
-  color: $color-global;
-  background-color: darken($bgcolor-global, 5%);
-  border-color: $border-color-global;
-  &:focus {
-    background-color: $bgcolor-global;
-  }
-  // FIXME: accent color
-  // border: 1px solid darken($border, 30%);
-}
-
-.form-control[disabled],
-.form-control[readonly] {
-  color: lighten($color-global, 10%);
-  background-color: lighten($bgcolor-global, 5%);
-}
-
-.input-group > .input-group-prepend > .input-group-text {
-  color: theme-color('light');
-  background-color: theme-color('secondary');
-  border: 1px solid theme-color('secondary');
-  border-right: none;
-  &.text-muted {
-    color: theme-color('light') !important;
-  }
-}
-
-.input-group input {
-  border-color: $border-color-global;
-}
-
-label.custom-control-label::before {
-  background-color: darken($bgcolor-global, 5%);
-}
-
-/*
- * Table
- */
-.table {
-  @extend .table-dark;
-}
-
-/*
- * Card
- */
-.card:not([class*='bg-']):not(.well):not(.card-disabled) {
-  @extend .bg-dark;
-}
-
-// [TODO] GW-3219 modify common color of well in dark theme, then remove below css.
-.card.well {
-  border-color: $secondary;
-}
-
-.card.card-disabled {
-  background-color: lighten($dark, 10%);
-  border-color: $secondary;
-}
-
-/*
- * Pagination
- */
-ul.pagination {
-  li.page-item {
-    button.page-link {
-      @extend .btn-dark;
-    }
-  }
-}
-
-/*
- * GROWI Login form
- */
-.nologin {
-  // background color
-  $color-gradient: #3c465c;
-  background: linear-gradient(45deg, darken($color-gradient, 30%) 0%, hsla(340, 100%, 55%, 0) 70%),
-    linear-gradient(135deg, darken(var.$growi-green, 30%) 10%, hsla(225, 95%, 50%, 0) 70%),
-    linear-gradient(225deg, darken(var.$growi-blue, 20%) 10%, hsla(140, 90%, 50%, 0) 80%),
-    linear-gradient(315deg, darken($color-gradient, 25%) 100%, hsla(35, 95%, 55%, 0) 70%);
-
-  .nologin-header {
-    background-color: rgba(black, 0.5);
-
-    .logo {
-      background-color: rgba(white, 0);
-      fill: rgba(white, 0.5);
-    }
-
-    h1 {
-      color: rgba(white, 0.5);
-    }
-  }
-
-  .nologin-dialog {
-    background-color: rgba(black, 0.5);
-  }
-
-  .input-group {
-    .input-group-text {
-      color: darken(white, 30%);
-      background-color: rgba($gray-700, 0.7);
-    }
-
-    .form-control {
-      color: white;
-      background-color: rgba(#505050, 0.7);
-      box-shadow: unset;
-
-      &::placeholder {
-        color: darken(white, 30%);
-      }
-    }
-  }
-
-  .btn-fill {
-    .btn-label {
-      color: $gray-300;
-    }
-    .btn-label-text {
-      color: $gray-400;
-    }
-  }
-
-  .grw-external-auth-form {
-    border-color: gray !important;
-  }
-
-  .btn-external-auth-tab {
-    @extend .btn-dark;
-  }
-
-  // footer link text
-  .link-growi-org {
-    color: rgba(white, 0.4);
-
-    &:hover,
-    &.focus {
-      color: rgba(white, 0.7);
-
-      .growi {
-        color: darken(var.$growi-green, 5%);
-      }
-
-      .org {
-        color: darken(var.$growi-blue, 5%);
-      }
-    }
-  }
-}
-
-/*
- * GROWI subnavigation
- */
-.grw-drawer-toggler {
-  @extend .btn-dark;
-  color: $gray-400;
-}
-
-/*
- * GROWI page list
- */
-.page-list {
-  .page-list-ul {
-    > li {
-      > span.page-list-meta {
-        color: darken($color-global, 10%);
-      }
-    }
-  }
-
-  // List group
-  .list-group-item {
-    &.active {
-      background-color: lighten($bgcolor-global, 9%) !important;
-    }
-    .list-group-item-action:hover {
-      background-color: $bgcolor-list-hover;
-    }
-    .page-list-snippet {
-      color: darken($body-color, 10%);
-    }
-  }
-}
-
-/*
- * GROWI ToC
- */
-.revision-toc-content {
-  ::marker {
-    color: lighten($bgcolor-global, 30%);
-  }
-}
-
-/*
- * GROWI subnavigation
- */
-.grw-subnav {
-  background-color: $bgcolor-subnav;
-}
-
-.grw-subnav-fixed-container .grw-subnav {
-  background-color: rgba($bgcolor-subnav, 0.85);
-}
-
-.grw-page-editor-mode-manager {
-  .btn-outline-primary {
-    &:hover {
-      color: $primary;
-      background-color: $gray-700;
-    }
-  }
-}
-
-// Search drop down
-#search-typeahead-asynctypeahead {
-  background-color: $bgcolor-global;
-  .table {
-    background-color: transparent;
-  }
-}
-
-/*
- * GROWI Sidebar
- */
-.grw-sidebar {
-  // List
-  @include override-list-group-item($color-list, $bgcolor-sidebar-list-group, $color-list-hover, $bgcolor-list-hover, $color-list-active, $bgcolor-list-active);
-
-  // Pagetree
-  .grw-pagetree {
-    @include override-list-group-item-for-pagetree(
-      $color-sidebar-context,
-      lighten($bgcolor-sidebar-context, 8%),
-      lighten($bgcolor-sidebar-context, 15%),
-      darken($color-sidebar-context, 15%),
-      darken($color-sidebar-context, 10%),
-      lighten($bgcolor-sidebar-context, 18%),
-      lighten($bgcolor-sidebar-context, 24%)
-    );
-    .grw-pagetree-triangle-btn {
-      @include mixins-buttons.button-outline-svg-icon-variant($secondary, $gray-200);
-    }
-    .btn-page-item-control {
-      @include button-outline-variant($gray-500, $gray-500, $secondary, transparent);
-      @include hover() {
-        background-color: lighten($bgcolor-sidebar-context, 20%);
-      }
-      &:not(:disabled):not(.disabled):active,
-      &:not(:disabled):not(.disabled).active {
-        background-color: lighten($bgcolor-sidebar-context, 34%);
-      }
-      box-shadow: none !important;
-    }
-  }
-  .private-legacy-pages-link {
-    &:hover {
-      background: $bgcolor-list-hover;
-    }
-  }
-}
-
-.btn.btn-page-item-control {
-  @include button-outline-variant($gray-500, $gray-500, $secondary, transparent);
-  @include hover() {
-    background-color: $gray-700;
-  }
-  &:not(:disabled):not(.disabled):active,
-  &:not(:disabled):not(.disabled).active {
-    color: $gray-200;
-    background-color: $gray-600;
-  }
-  box-shadow: none !important;
-}
-
-/*
- * Popover
- */
-.popover {
-  background-color: $bgcolor-global;
-  border-color: $secondary;
-  .popover-header {
-    color: $white;
-    background-color: $secondary;
-    border-color: $secondary;
-  }
-  .popover-body {
-    color: inherit;
-  }
-
-  &.bs-popover-top .arrow {
-    &::before {
-      border-top-color: $secondary;
-    }
-
-    &::after {
-      border-top-color: $bgcolor-global;
-    }
-  }
-  &.bs-popover-bottom .arrow {
-    &::before {
-      border-bottom-color: $secondary;
-    }
-
-    &::after {
-      border-bottom-color: $bgcolor-global;
-    }
-  }
-  &.bs-popover-right .arrow {
-    &::before {
-      border-right-color: $secondary;
-    }
-
-    &::after {
-      border-right-color: $bgcolor-global;
-    }
-  }
-  &.bs-popover-left .arrow {
-    &::before {
-      border-left-color: $secondary;
-    }
-
-    &::after {
-      border-left-color: $bgcolor-global;
-    }
-  }
-}
-
-/*
- * GROWI Grid Edit Modal
- */
-.grw-grid-edit-preview {
-  background: $gray-900;
-}
-
-/*
- * Slack
- */
-.grw-slack-notification {
-  background-color: transparent;
-  $color-slack: #4b144c;
-
-  .form-control {
-    background: $bgcolor-global;
-  }
-
-  .custom-control-label {
-    &::before {
-      background-color: $secondary;
-      border-color: transparent;
-    }
-    &::after {
-      background-color: darken($color-slack, 5%);
-      // background-image: url(/images/icons/slack/slack-logo-dark-off.svg); -- should be specified in app -- 2022.12.09 Yuki Takei
-    }
-  }
-
-  .custom-control-input:checked ~ .custom-control-label {
-    &::before {
-      background-color: lighten($color-slack, 10%);
-    }
-    &::after {
-      background-color: darken($color-slack, 5%);
-      // background-image: url(/images/icons/slack/slack-logo-dark-on.svg); -- should be specified in app -- 2022.12.09 Yuki Takei
-    }
-  }
-  .grw-slack-logo svg {
-    fill: #dd80de;
-  }
-
-  .grw-btn-slack {
-    background-color: black;
-    &:focus,
-    &:hover {
-      background-color: black;
-    }
-  }
-
-  .grw-btn-slack-triangle {
-    color: $secondary;
-  }
-}
-
-/*
- * GROWI HandsontableModal
- */
-.grw-hot-modal-navbar {
-  background-color: $dark;
-}
-
-.wiki {
-  h1 {
-    border-color: lighten($border-color-theme, 10%);
-  }
-  h2 {
-    border-color: $border-color-theme;
-  }
-}
-
-/*
- * GROWI comment form
- */
-.comment-form {
-  #slack-mark-black {
-    display: none;
-  }
-}
-
-.page-comments-row {
-  background: $bgcolor-subnav;
-}
-
-/*
- * GROWI tags
- */
-.grw-tag-labels {
-  .grw-tag-label {
-    color: $color-tags;
-    background-color: $bgcolor-tags;
-  }
-}
-
-/*
- * GROWI popular tags
- */
-.grw-popular-tag-labels {
-  .grw-tag-label {
-    color: $color-tags;
-    background-color: $bgcolor-tags;
-  }
-}
-
-/*
- * admin settings
- */
-.admin-setting-header {
-  border-color: $border-color-global;
-}
-
-/*
-* grw-side-contents
-*/
-.grw-side-contents-sticky-container {
-  .grw-count-badge {
-    @include count-badge.count-badge($gray-400, $gray-700);
-  }
-
-  .grw-border-vr {
-    border-color: $border-color-toc;
-  }
-
-  .revision-toc {
-    border-color: $border-color-toc;
-  }
-}
-
-/*
- * drawio
- */
-.drawio-viewer {
-  border-color: $border-color-global;
-}
-
-/*
- * modal
- */
-.grw-modal-head {
-  border-color: $border-color-global;
-}
-
-/*
- * skeleton
- */
-.grw-skeleton {
-  background-color: lighten($bgcolor-subnav, 15%);
-}

+ 0 - 430
packages/preset-themes/src/styles/theme/_apply-colors-light.scss

@@ -1,430 +0,0 @@
-@use '../variables' as var;
-@use '../bootstrap/init' as *;
-@use '../atoms/mixins/buttons' as mixins-buttons;
-@use './mixins/count-badge';
-
-// determine optional variables
-$color-list: $color-global !default;
-$bgcolor-list: $bgcolor-global !default;
-$color-list-hover: $color-global !default;
-$bgcolor-list-hover: lighten($primary, 72%) !default;
-$bgcolor-list-active: lighten($primary, 65%) !default;
-$color-list-active: color-yiq($bgcolor-list-active) !default;
-$color-table: $color-global !default;
-$bgcolor-table: null !default;
-$border-color-table: $gray-200 !default;
-$color-table-hover: $color-table !default;
-$bgcolor-table-hover: rgba(black, 0.075) !default;
-$bgcolor-sidebar-list-group: $bgcolor-list !default;
-$color-tags: $secondary !default;
-$bgcolor-tags: $gray-200 !default;
-$border-color-global: $gray-300 !default;
-$border-color-toc: $border-color-global !default;
-$color-dropdown: $color-global !default;
-$color-dropdown-link: $color-global !default;
-$color-dropdown-link-hover: $color-global !default;
-$color-dropdown-link-active: $color-reversal !default;
-$bgcolor-dropdown-link-active: $primary !default;
-
-// override bootstrap variables
-$text-muted: $gray-500;
-$table-color: $color-table;
-$table-bg: $bgcolor-table;
-$table-border-color: $border-color-table;
-$table-hover-color: $color-table-hover;
-$table-hover-bg: $bgcolor-table-hover;
-$border-color: $border-color-global;
-$dropdown-color: $color-dropdown;
-$dropdown-link-color: $color-dropdown-link;
-$dropdown-link-hover-color: $color-dropdown-link-hover;
-$dropdown-link-active-color: $color-dropdown-link-active;
-$dropdown-link-active-bg: $bgcolor-dropdown-link-active;
-
-@import './mixins/list-group';
-@import './reboot-bootstrap-text';
-@import './reboot-bootstrap-border-colors';
-@import './reboot-bootstrap-tables';
-@import './reboot-bootstrap-dropdown';
-
-// List Group
-@include override-list-group-item($color-list, $bgcolor-list, $color-list-hover, $bgcolor-list-hover, $color-list-active, $bgcolor-list-active);
-
-/*
- * Form
- */
-.form-control {
-  background-color: $bgcolor-global;
-}
-
-.form-control::placeholder {
-  color: darken($bgcolor-global, 20%);
-}
-
-.form-control[disabled],
-.form-control[readonly] {
-  color: lighten($color-global, 10%);
-  background-color: darken($bgcolor-global, 5%);
-}
-
-/*
- * card
- */
-.card.card-disabled {
-  background-color: darken($bgcolor-card, 5%);
-  border-color: $gray-200;
-}
-
-/*
- * GROWI Login form
- */
-.nologin {
-  // background color
-  $color-gradient: #3e4d6c;
-  background: linear-gradient(45deg, darken($color-gradient, 30%) 0%, hsla(340, 100%, 55%, 0) 70%),
-    linear-gradient(135deg, var.$growi-green 10%, hsla(225, 95%, 50%, 0) 70%), linear-gradient(225deg, var.$growi-blue 10%, hsla(140, 90%, 50%, 0) 80%),
-    linear-gradient(315deg, darken($color-gradient, 25%) 100%, hsla(35, 95%, 55%, 0) 70%);
-
-  .nologin-header {
-    background-color: rgba(white, 0.5);
-
-    .logo {
-      background-color: rgba(black, 0);
-      fill: rgba(black, 0.5);
-    }
-
-    h1 {
-      color: rgba(black, 0.5);
-    }
-  }
-
-  .nologin-dialog {
-    background-color: rgba(white, 0.5);
-  }
-
-  .dropdown-with-icon {
-    .dropdown-toggle {
-      color: white;
-      background-color: rgba($gray-600, 0.7);
-      box-shadow: unset;
-      &:focus {
-        color: white;
-        background-color: rgba($gray-600, 0.7);
-      }
-    }
-    i {
-      color: darken(white, 30%);
-      background-color: rgba($gray-700, 0.7);
-    }
-  }
-
-  .input-group {
-    .input-group-text {
-      color: darken(white, 30%);
-      background-color: rgba($gray-700, 0.7);
-    }
-
-    .form-control {
-      color: white;
-      background-color: rgba($gray-600, 0.7);
-      box-shadow: unset;
-
-      &::placeholder {
-        color: darken(white, 30%);
-      }
-    }
-  }
-
-  // footer link text
-  .link-growi-org {
-    color: rgba(black, 0.4);
-
-    &:hover,
-    &.focus {
-      color: black;
-
-      .growi {
-        color: darken(var.$growi-green, 20%);
-      }
-
-      .org {
-        color: darken(var.$growi-blue, 15%);
-      }
-    }
-  }
-}
-
-/*
- * GROWI subnavigation
- */
-.grw-subnav {
-  background-color: $bgcolor-subnav;
-}
-
-.grw-subnav-fixed-container .grw-subnav {
-  background-color: rgba($bgcolor-subnav, 0.85);
-}
-
-.grw-page-editor-mode-manager {
-  .btn-outline-primary {
-    &:hover {
-      color: $primary;
-      background-color: $gray-200;
-    }
-  }
-}
-
-.grw-drawer-toggler {
-  @extend .btn-light;
-  color: $gray-500;
-}
-
-/*
- * GROWI Sidebar
- */
-.grw-sidebar {
-  // List
-  @include override-list-group-item($color-list, $bgcolor-sidebar-list-group, $color-list-hover, $bgcolor-list-hover, $color-list-active, $bgcolor-list-active);
-  // sidebar-centent-bg
-  .grw-navigation-wrap {
-    // Drop a shadow on the light theme. The dark theme makes '$ bgcolor-sidebar-context' brighter than the body.
-    box-shadow: 0px 0px 3px rgba(black, 0.24);
-  }
-  // Pagetree
-  .grw-pagetree {
-    @include override-list-group-item-for-pagetree(
-      $color-sidebar-context,
-      darken($bgcolor-sidebar-context, 5%),
-      darken($bgcolor-sidebar-context, 12%),
-      lighten($color-sidebar-context, 10%),
-      lighten($color-sidebar-context, 8%),
-      darken($bgcolor-sidebar-context, 15%),
-      darken($bgcolor-sidebar-context, 24%)
-    );
-    .grw-pagetree-triangle-btn {
-      @include mixins-buttons.button-outline-svg-icon-variant($gray-400, $primary);
-    }
-  }
-  .private-legacy-pages-link {
-    &:hover {
-      background: $bgcolor-list-hover;
-    }
-  }
-}
-
-.btn.btn-page-item-control {
-  @include button-outline-variant($gray-500, $primary, lighten($primary, 52%), transparent);
-  @include hover() {
-    background-color: lighten($primary, 58%);
-  }
-  &:not(:disabled):not(.disabled):active,
-  &:not(:disabled):not(.disabled).active {
-    color: $primary;
-  }
-  box-shadow: none !important;
-}
-
-/*
- * GROWI page list
- */
-.page-list {
-  .page-list-ul {
-    > li {
-      > span.page-list-meta {
-        color: lighten($color-global, 10%);
-      }
-    }
-  }
-  // List group
-  .list-group-item {
-    .page-list-snippet {
-      color: lighten($body-color, 10%);
-    }
-  }
-}
-
-/*
- * GROWI ToC
- */
-.revision-toc-content {
-  ::marker {
-    color: darken($bgcolor-global, 20%);
-  }
-}
-
-/*
- * GROWI Editor
- */
-.grw-editor-navbar-bottom {
-  background-color: $gray-50;
-
-  #slack-mark-white {
-    display: none;
-  }
-
-  .input-group-text {
-    margin-right: 1px;
-    color: $secondary;
-    border-color: $light;
-  }
-
-  .btn.btn-outline-secondary {
-    border-color: $border-color;
-  }
-}
-
-/*
- * GROWI Link Edit Modal
- */
-.link-edit-modal {
-  span i {
-    color: $gray-400;
-  }
-}
-
-/*
- * GROWI Grid Edit Modal
- */
-
-.grw-grid-edit-preview {
-  background: $gray-100;
-}
-
-/*
- * Slack
- */
-.grw-slack-notification {
-  background-color: white;
-  $color-slack: #4b144c;
-
-  .form-control {
-    background: white;
-  }
-
-  .custom-control-label {
-    &::before {
-      background-color: $gray-200;
-      border-color: transparent;
-    }
-    &::after {
-      background-color: white;
-      // background-image: url(/images/icons/slack/slack-logo-off.svg); -- should be specified in app -- 2022.12.09 Yuki Takei
-    }
-  }
-  .custom-control-input:checked ~ .custom-control-label {
-    &::before {
-      background-color: lighten($color-slack, 60%);
-    }
-    &::after {
-      // background-image: url(/images/icons/slack/slack-logo-on.svg); -- should be specified in app -- 2022.12.09 Yuki Takei
-    }
-  }
-  .grw-slack-logo svg {
-    fill: #af30b0;
-  }
-
-  .grw-btn-slack {
-    background-color: white;
-
-    &:hover,
-    &:focus {
-      background-color: white;
-    }
-  }
-
-  .grw-btn-slack-triangle {
-    color: $secondary;
-  }
-}
-
-/*
- * GROWI HandsontableModal
- */
-.grw-hot-modal-navbar {
-  background-color: $light;
-}
-
-.wiki {
-  h1 {
-    border-color: $border-color-theme;
-  }
-  h2 {
-    border-color: $border-color-theme;
-  }
-}
-
-/*
- * GROWI comment form
- */
-.comment-form {
-  #slack-mark-white {
-    display: none;
-  }
-}
-
-.page-comments-row {
-  background: $bgcolor-subnav;
-}
-
-/*
- * GROWI tags
- */
-.grw-tag-labels {
-  .grw-tag-label {
-    color: $color-tags;
-    background-color: $bgcolor-tags;
-  }
-}
-
-/*
- * GROWI popular tags
- */
-.grw-popular-tag-labels {
-  .grw-tag-label {
-    color: $color-tags;
-    background-color: $bgcolor-tags;
-  }
-}
-
-/*
-* grw-side-contents
-*/
-.grw-side-contents-sticky-container {
-  .grw-count-badge {
-    @include count-badge.count-badge($gray-600, $gray-200);
-  }
-
-  .grw-border-vr {
-    border-color: $border-color-toc;
-  }
-  .revision-toc {
-    border-color: $border-color-toc;
-  }
-}
-
-/*
- * drawio
- */
-.drawio-viewer {
-  border-color: $border-color-global;
-}
-
-/*
- * admin settings
- */
-.admin-setting-header {
-  border-color: $border-color;
-}
-
-/*
- * modal
- */
-.grw-modal-head {
-  border-color: $border-color-global;
-}
-
-/*
- * skeleton
- */
-.grw-skeleton {
-  background-color: darken($bgcolor-subnav, 10%);
-}

+ 0 - 691
packages/preset-themes/src/styles/theme/_apply-colors.scss

@@ -1,691 +0,0 @@
-@use '../variables' as var;
-@use '../bootstrap/init' as *;
-@use '../mixins';
-@use './mixins/tables'; // comment out and use _reboot-bootstrap-tables instead -- 2020.05.28 Yuki Takei
-@use '../atoms/mixins/code';
-
-//
-//== Apply to Bootstrap
-//
-
-// determine optional variables
-$border-image-navbar: linear-gradient(to right, $gray-300 0%, $gray-300 100%) !default;
-$bgcolor-search-top-dropdown: $secondary !default;
-$bgcolor-sidebar-nav-item-active: darken($bgcolor-sidebar, 10%) !default;
-$text-shadow-sidebar-nav-item-active: 1px 1px 2px $primary !default;
-$bgcolor-inline-code: $gray-100 !default;
-$color-inline-code: darken($red, 15%) !default;
-$bordercolor-inline-code: $gray-400 !default;
-$bordercolor-nav-tabs: $gray-300 !default;
-$bordercolor-nav-tabs-hover: $gray-200 $gray-200 $bordercolor-nav-tabs !default;
-$color-nav-tabs-link-active: $gray-600 !default;
-$bordercolor-nav-tabs-active: $bordercolor-nav-tabs $bordercolor-nav-tabs $bgcolor-global !default;
-$color-btn-reload-in-sidebar: $gray-500;
-$bgcolor-keyword-highlighted: var.$grw-marker-yellow !default;
-$bgcolor-page-list-group-item-active: lighten($primary, 76%) !default;
-$color-page-list-group-item-meta: $gray-500 !default;
-$color-search-page-list-title: $color-global !default;
-$bgcolor-subnav: darken($bgcolor-global, 3%) !default;
-
-// override bootstrap variables
-$body-bg: $bgcolor-global;
-$body-color: $color-global;
-$link-color: $color-link;
-$link-hover-color: $color-link-hover;
-$input-focus-color: $color-global;
-$nav-tabs-border-color: $bordercolor-nav-tabs;
-$nav-tabs-link-hover-border-color: $bordercolor-nav-tabs-hover;
-$nav-tabs-link-active-color: $color-nav-tabs-link-active;
-$nav-tabs-link-active-bg: $bgcolor-global;
-$nav-tabs-link-active-border-color: $bordercolor-nav-tabs-active;
-$theme-colors: map-merge($theme-colors, ( primary: $primary ));
-
-@import 'reboot-bootstrap-buttons';
-@import 'reboot-bootstrap-colors';
-@import 'reboot-bootstrap-theme-colors';
-@import 'reboot-bootstrap-nav';
-@import 'reboot-toastr-colors';
-
-// determine variables with bootstrap function (These variables can be used after importing bootstrap above)
-$color-modal-header: color-yiq($primary) !default;
-
-code:not([class^='language-']) {
-  @include code.code-inline-color($color-inline-code, $bgcolor-inline-code, $bordercolor-inline-code);
-}
-
-.code-highlighted {
-  border-color: $bordercolor-inline-code;
-}
-
-//
-//== Apply to Bootstrap Elements
-//
-
-// Alert link
-@each $color, $value in $theme-colors {
-  .alert.alert-#{$color} {
-    a,
-    a:hover {
-      color: theme-color-level($color, $alert-color-level - 2);
-    }
-  }
-}
-
-// Dropdown
-.grw-apperance-mode-dropdown {
-  .grw-sidebar-mode-icon svg {
-    fill: $secondary;
-  }
-  .grw-color-mode-icon svg {
-    fill: $color-global;
-  }
-  .grw-color-mode-icon-muted svg {
-    fill: $secondary;
-  }
-}
-
-// Form
-.form-control {
-  @include form-control-focus();
-}
-
-// Tabs
-.nav.nav-tabs .nav-link.active {
-  color: $color-link !important;
-  background: transparent;
-
-  &:hover,
-  &:focus {
-    color: $color-link-hover !important;
-  }
-}
-
-// Pagination
-ul.pagination {
-  li.page-item.disabled {
-    button.page-link {
-      color: $gray-400;
-    }
-  }
-  li.page-item.active {
-    button.page-link {
-      color: color-yiq($primary);
-      background-color: $primary;
-      &:hover,
-      &:focus {
-        color: color-yiq($primary);
-        background-color: $primary;
-      }
-    }
-  }
-  li.page-item {
-    button.page-link {
-      color: $primary;
-      border-color: $secondary;
-      &:hover,
-      &:active,
-      &:focus {
-        color: $primary;
-      }
-    }
-  }
-}
-
-//
-//== Apply to Handsontable
-//
-.handsontable {
-  color: initial;
-}
-
-//
-//== Apply to GROWI Elements
-//
-
-.grw-logo {
-  // set transition for fill
-  svg * {
-    transition: fill 0.8s ease-out;
-  }
-
-  svg {
-    fill: $fillcolor-logo-mark;
-  }
-
-  &:hover {
-    svg {
-      .group1 {
-        fill: var.$growi-green;
-      }
-
-      .group2 {
-        fill: var.$growi-blue;
-      }
-    }
-  }
-}
-
-.grw-navbar {
-  background: $bgcolor-navbar;
-  .nav-item .nav-link {
-    color: $color-link-nabvar;
-  }
-
-  border-image: $border-image-navbar;
-  border-image-slice: 1;
-
-  .grw-app-title {
-    color: $fillcolor-logo-mark;
-  }
-}
-
-.grw-global-search {
-  .btn-secondary.dropdown-toggle {
-    @include button-variant($bgcolor-search-top-dropdown, $bgcolor-search-top-dropdown);
-  }
-
-  // for https://youtrack.weseek.co.jp/issue/GW-2603
-  .search-typeahead {
-    background-color: rgba($bgcolor-global, 0.9);
-  }
-}
-
-.grw-sidebar {
-  .grw-navigation-resize-button {
-    $color-resize-button: $color-global !default;
-    $bgcolor-resize-button: white !default;
-    $color-resize-button-hover: $color-reversal !default;
-    $bgcolor-resize-button-hover: lighten($bgcolor-resize-button, 5%) !default;
-
-    .hexagon-container svg {
-      .background {
-        fill: $bgcolor-resize-button;
-      }
-      .icon {
-        fill: $color-resize-button;
-      }
-    }
-    &:hover .hexagon-container svg {
-      .background {
-        fill: $bgcolor-resize-button-hover;
-      }
-      .icon {
-        fill: $color-resize-button-hover;
-      }
-    }
-  }
-  div.grw-global-navigation {
-    > div {
-      background-color: $bgcolor-sidebar;
-    }
-  }
-  div.grw-contextual-navigation {
-    > div {
-      color: $color-sidebar-context;
-      background-color: $bgcolor-sidebar-context;
-    }
-  }
-
-  .grw-sidebar-nav {
-    .btn {
-      @include button-variant(
-        $bgcolor-sidebar,
-        $bgcolor-sidebar,
-        darken($bgcolor-sidebar, 7.5%),
-        darken($bgcolor-sidebar, 10%),
-        $bgcolor-sidebar-nav-item-active,
-        $bgcolor-sidebar-nav-item-active
-      );
-    }
-  }
-  .grw-sidebar-nav-primary-container {
-    .btn.active {
-      i {
-        text-shadow: $text-shadow-sidebar-nav-item-active;
-      }
-      // fukidashi
-      &:after {
-        border-right-color: $bgcolor-sidebar-context;
-      }
-    }
-  }
-
-  .grw-sidebar-content-header {
-    .grw-btn-reload {
-      color: $color-btn-reload-in-sidebar;
-    }
-
-    .grw-recent-changes-resize-button {
-      .custom-control-label::before {
-        background-color: $primary;
-      }
-
-      .custom-control-label::after {
-        background-color: $bgcolor-global;
-      }
-
-      .custom-control-input:not(:checked) + .custom-control-label::before {
-        color: $bgcolor-global;
-      }
-
-      .custom-control-input:checked + .custom-control-label::before {
-        color: $bgcolor-global;
-        background-color: $primary;
-        // border-color: $primary !important;
-      }
-      .custom-control-input:checked + .custom-control-label::after {
-        color: $bgcolor-global;
-      }
-    }
-  }
-
-  .grw-pagetree {
-    .list-group-item {
-      .grw-pagetree-title-anchor {
-        color: inherit;
-      }
-    }
-  }
-  .grw-pagetree-footer {
-    .h5.grw-private-legacy-pages-anchor {
-      color: inherit;
-    }
-  }
-
-  .grw-recent-changes {
-    .list-group {
-      .list-group-item {
-        background-color: transparent;
-
-        .icon-lock {
-          color: $color-link;
-        }
-
-        .grw-recent-changes-item-lower {
-          color: $gray-500;
-
-          svg {
-            fill: $gray-500;
-          }
-        }
-      }
-    }
-  }
-}
-
-/*
- * Icon
- */
-.editor-container .navbar-editor svg {
-  fill: $color-editor-icons;
-}
-
-// page preview button in link form
-.btn-page-preview svg {
-  fill: white;
-}
-
-/*
- * Modal
- */
-.modal {
-  .modal-header {
-    border-bottom-color: $border-color-theme;
-    .modal-title {
-      color: $color-modal-header;
-    }
-    .close {
-      color: $color-modal-header;
-      opacity: 0.5;
-      &:hover {
-        opacity: 0.9;
-      }
-    }
-  }
-
-  .modal-content {
-    background-color: $bgcolor-global;
-  }
-
-  .modal-footer {
-    border-top-color: $border-color-theme;
-  }
-}
-
-.grw-custom-nav-tab {
-  .nav-item {
-    &:hover,
-    &:focus {
-      background-color: rgba($color-link, 0.08);
-    }
-    .nav-link {
-      -webkit-appearance: none;
-      color: $color-link;
-      svg {
-        fill: $color-link;
-      }
-
-      // Disabled state lightens text
-      &.disabled {
-        color: $nav-link-disabled-color;
-        svg {
-          fill: $nav-link-disabled-color;
-        }
-      }
-    }
-  }
-
-  .grw-nav-slide-hr {
-    border-color: $color-link;
-  }
-}
-
-.grw-page-accessories-modal {
-  .modal-header {
-    .close {
-      color: $secondary;
-    }
-  }
-}
-
-/*
- * cards
- */
-.card.well {
-  color: $color-global;
-  background-color: $bgcolor-card;
-  border-color: $light;
-  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
-}
-
-.admin-bot-card {
-  .grw-botcard-title-active {
-    color: $gray-200;
-  }
-}
-
-/*
- * Form Slider
- */
-.admin-page {
-  span.slider {
-    background-color: $gray-300;
-
-    &:before {
-      background-color: white;
-    }
-  }
-
-  input:checked + .slider {
-    background-color: #007bff;
-  }
-
-  input:focus + .slider {
-    box-shadow: 0 0 1px #007bff;
-  }
-}
-
-/*
- * GROWI wiki
- */
-.wiki {
-  h1,
-  h2,
-  h3,
-  h4,
-  h5,
-  h6,
-  h7 {
-    &.blink {
-      @include mixins.blink-bgcolor($bgcolor-blinked-section);
-    }
-  }
-
-  .highlighted-keyword {
-    background: linear-gradient(transparent 60%, $bgcolor-keyword-highlighted 60%);
-  }
-
-  a {
-    color: $color-link-wiki;
-
-    &:hover {
-      color: $color-link-wiki-hover;
-    }
-  }
-
-  // table with handsontable modal button
-  .editable-with-handsontable {
-    button {
-      color: $color-link-wiki;
-    }
-
-    button:hover {
-      color: $color-link-wiki-hover;
-    }
-  }
-}
-
-/*
- * GROWI page-list
- */
-.page-list {
-  // List group
-  .list-group {
-    .list-group-item {
-      a {
-        svg {
-          fill: $color-global;
-        }
-
-        @include hover() {
-          svg {
-            fill: $color-global;
-          }
-        }
-      }
-
-      .page-list-meta {
-        color: $color-page-list-group-item-meta;
-        svg {
-          fill: $color-page-list-group-item-meta;
-        }
-      }
-
-      &.list-group-item-action {
-        &.active {
-          background-color: $bgcolor-page-list-group-item-active;
-          border-left-color: $primary;
-        }
-      }
-    }
-  }
-}
-
-/*
- * GROWI Editor
- */
-.layout-root.editing {
-  .main {
-    background-color: darken($bgcolor-global, 2%);
-
-    .page-editor-editor-container {
-      border-right-color: $border-color-theme;
-
-      .navbar-editor {
-        background-color: $bgcolor-global; // same color with active tab
-        border-bottom-color: $border-color-theme;
-      }
-    }
-
-    .page-editor-preview-container {
-      background-color: $bgcolor-global;
-    }
-  }
-}
-
-/*
- * Preview for editing /Sidebar
- */
-body.editing-sidebar {
-  .page-editor-preview-body {
-    color: $color-sidebar-context;
-    background-color: $bgcolor-sidebar-context;
-  }
-}
-
-/*
- * GROWI Grid Edit Modal
- */
-.grw-grid-edit-preview {
-  .desktop-preview,
-  .tablet-preview,
-  .mobile-preview {
-    background: $bgcolor-global;
-  }
-  .grid-edit-border-for-each-cols {
-    border: 2px solid $bgcolor-global;
-  }
-}
-
-.grid-preview-col-0 {
-  background: var.$growi-blue;
-}
-
-.grid-preview-col-3 {
-  background: var.$growi-green;
-}
-
-/*
- * GROWI comment
- */
-.page-comment-meta .page-comment-revision svg {
-  fill: $color-link;
-
-  &:hover {
-    fill: $color-link-hover;
-  }
-}
-
-/*
- * GROWI comment form
- */
-.page-comments {
-  .page-comment .page-comment-main,
-  .page-comment-form .comment-form-main {
-    background-color: $bgcolor-global;
-
-    &:before {
-      border-right-color: $bgcolor-global;
-    }
-
-    .nav.nav-tabs {
-      > li > a.active {
-        background: transparent;
-        border-bottom: solid 1px darken($bgcolor-global, 4%);
-        border-bottom-color: darken($bgcolor-global, 4%);
-      }
-    }
-  }
-}
-
-/*
- * GROWI search result
- */
-.search-result-base {
-  .grw-search-page-nav {
-    background-color: $bgcolor-subnav;
-  }
-  .search-control {
-    background-color: $bgcolor-global;
-  }
-  .page-list {
-    .highlighted-keyword {
-      background: linear-gradient(transparent 60%, $bgcolor-keyword-highlighted 60%);
-    }
-  }
-}
-
-/*
- * react bootstrap typeahead
- */
-mark.rbt-highlight-text {
-  // Temporarily the highlight color is black
-  color: black;
-}
-
-/*
- * GROWI page content footer
- */
-.page-content-footer {
-  background-color: darken($bgcolor-global, 2%);
-  border-top-color: $border-color-theme;
-}
-
-/*
- * GROWI admin page #layoutOptions #themeOptions
- */
-.admin-page {
-  #layoutOptions {
-    .customize-layout-card {
-      &.border-active {
-        border-color: $color-theme-color-box;
-      }
-    }
-  }
-
-  #themeOptions {
-    .theme-option-container.active {
-      .theme-option-name {
-        color: $color-global;
-      }
-      a {
-        background-color: $color-theme-color-box;
-        border-color: $color-theme-color-box;
-      }
-    }
-  }
-}
-
-/*
- * HackMd
- */
-.bg-box {
-  background-color: $bgcolor-global;
-}
-
-.grw-fab {
-  .btn-create-page {
-    svg {
-      fill: color-yiq($primary);
-    }
-  }
-
-  .btn-scroll-to-top {
-    fill: $gray-900;
-  }
-}
-
-/*
-  Slack Integration
-*/
-.selecting-bot-type {
-  .bot-type-disc {
-    width: 20px;
-  }
-}
-
-/*
-  In App Notification
-*/
-.grw-unopend-notification {
-  width: 7px;
-  height: 7px;
-  background-color: $primary;
-}
-
-/*
-Emoji picker modal
-*/
-.emoji-picker-modal {
-  background-color: transparent !important;
-}

+ 32 - 0
packages/preset-themes/src/styles/theme/_hsl-functions.scss

@@ -0,0 +1,32 @@
+@use 'bootstrap/scss/functions' as bs;
+
+@function contrast($color, $darken-degrees: 0%) {
+  $color: bs.str-replace($color, 'var(');
+  $color: bs.str-replace($color, ')');
+  $color-hs: var(#{$color+'-hs'});
+  $color-l: var(#{$color+'-l'});
+  // @return hsl($color-hs, clamp(10%, calc((100% - $color-l - 51% ) * 1000), 95%));
+  @return hsl($color-hs, clamp(10%, calc((100% - $color-l - $darken-degrees - 51% ) * 1000), 95%));
+}
+
+@function lighten($color, $degrees) {
+  $color: bs.str-replace($color, 'var(');
+  $color: bs.str-replace($color, ')');
+  $color-hs: var(#{$color+'-hs'});
+  $color-l: var(#{$color+'-l'});
+  @return hsl($color-hs, calc($color-l + $degrees));
+}
+@function darken($color, $degrees) {
+  $color: bs.str-replace($color, 'var(');
+  $color: bs.str-replace($color, ')');
+  $color-hs: var(#{$color+'-hs'});
+  $color-l: var(#{$color+'-l'});
+  @return hsl($color-hs, calc($color-l - $degrees));
+}
+@function alpha($color, $degrees) {
+  $color: bs.str-replace($color, 'var(');
+  $color: bs.str-replace($color, ')');
+  $color-hs: var(#{$color+'-hs'});
+  $color-l: var(#{$color+'-l'});
+  @return hsla($color-hs,$color-l,$degrees);
+}

+ 0 - 25
packages/preset-themes/src/styles/theme/_reboot-bootstrap-border-colors.scss

@@ -1,25 +0,0 @@
-@use '../bootstrap/init' as *;
-
-//
-// Border
-//
-
-.border {
-  border: $border-width solid $border-color !important;
-}
-
-.border-top {
-  border-top: $border-width solid $border-color !important;
-}
-
-.border-right {
-  border-right: $border-width solid $border-color !important;
-}
-
-.border-bottom {
-  border-bottom: $border-width solid $border-color !important;
-}
-
-.border-left {
-  border-left: $border-width solid $border-color !important;
-}

+ 0 - 21
packages/preset-themes/src/styles/theme/_reboot-bootstrap-buttons.scss

@@ -1,21 +0,0 @@
-.btn-link {
-  color: $link-color;
-  svg {
-    fill: $link-color;
-  }
-
-  @include hover() {
-    color: $link-hover-color;
-    svg {
-      fill: $link-hover-color;
-    }
-  }
-
-  &:disabled,
-  &.disabled {
-    color: $btn-link-disabled-color;
-    svg {
-      fill: $btn-link-disabled-color;
-    }
-  }
-}

+ 0 - 60
packages/preset-themes/src/styles/theme/_reboot-bootstrap-colors.scss

@@ -1,60 +0,0 @@
-//
-//
-// Apply partially
-//   https://github.com/twbs/bootstrap/blob/v4.5.0/scss/_reboot.scss
-//
-//
-
-// stylelint-disable at-rule-no-vendor-prefix, declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix
-
-// Body
-//
-// 1. Remove the margin in all browsers.
-// 2. As a best practice, apply a default `background-color`.
-// 3. Set an explicit initial text-align value so that we can later use
-//    the `inherit` value on things like `<th>` elements.
-
-&, body {
-  color: $body-color;
-  background-color: $body-bg; // 2
-
-  svg {
-    fill: $body-color;
-  }
-}
-
-// Links
-
-a {
-  color: $link-color;
-  text-decoration: $link-decoration;
-  background-color: transparent; // Remove the gray background on active links in IE 10.
-
-  svg {
-    fill: $link-color;
-  }
-
-  @include hover() {
-    color: $link-hover-color;
-    text-decoration: $link-hover-decoration;
-
-    svg {
-      fill: $link-hover-color;
-    }
-  }
-}
-
-// And undo these styles for placeholder links/named anchors (without href).
-// It would be more straightforward to just use a[href] in previous block, but that
-// causes specificity issues in many other styles that are too complex to fix.
-// See https://github.com/twbs/bootstrap/issues/19402
-
-// a:not([href]) {
-//   color: inherit;
-//   text-decoration: none;
-
-//   @include hover() {
-//     color: inherit;
-//     text-decoration: none;
-//   }
-// }

+ 0 - 37
packages/preset-themes/src/styles/theme/_reboot-bootstrap-dropdown.scss

@@ -1,37 +0,0 @@
-@use '../bootstrap/init' as *;
-
-.dropdown-menu {
-  color: $dropdown-color;
-  svg {
-    fill: $dropdown-color;
-  }
-
-  background-color: $dropdown-bg;
-}
-
-.dropdown-item {
-  color: $dropdown-link-color;
-  svg {
-    fill: $dropdown-link-color;
-  }
-
-  @include hover-focus() {
-    color: $dropdown-link-hover-color;
-    svg {
-      fill: $dropdown-link-hover-color;
-    }
-
-    @include gradient-bg($dropdown-link-hover-bg);
-  }
-
-  &:active,
-  &.active,
-  &:active:hover,
-  &.active:hover {
-    color: $dropdown-link-active-color;
-    background-color: $dropdown-link-active-bg;
-    svg {
-      fill: $dropdown-link-active-color;
-    }
-  }
-}

+ 0 - 51
packages/preset-themes/src/styles/theme/_reboot-bootstrap-nav.scss

@@ -1,51 +0,0 @@
-//
-//
-// Apply partially
-//   https://github.com/twbs/bootstrap/blob/v4.5.0/scss/_nav.scss
-//
-//
-
-.nav-link {
-  // Disabled state lightens text
-  &.disabled {
-    color: $nav-link-disabled-color;
-    svg {
-      fill: $nav-link-disabled-color;
-    }
-  }
-}
-
-//
-// Tabs
-//
-
-.nav-tabs {
-  border-bottom: $nav-tabs-border-width solid $nav-tabs-border-color;
-
-  .nav-link {
-    border: $nav-tabs-border-width solid transparent;
-    @include border-top-radius($nav-tabs-border-radius);
-
-    @include hover-focus() {
-      border-color: $nav-tabs-link-hover-border-color;
-    }
-
-    &.disabled {
-      color: $nav-link-disabled-color;
-      background-color: transparent;
-      border-color: transparent;
-    }
-  }
-
-  .nav-link.active,
-  .nav-item.show .nav-link {
-    color: $nav-tabs-link-active-color;
-    background-color: $nav-tabs-link-active-bg;
-    border-color: $nav-tabs-link-active-border-color;
-  }
-
-  .dropdown-menu {
-    // Remove the top rounded corners here since there is a hard edge above the menu
-    @include border-top-radius(0);
-  }
-}

+ 0 - 74
packages/preset-themes/src/styles/theme/_reboot-bootstrap-tables.scss

@@ -1,74 +0,0 @@
-@use '../bootstrap/init' as *;
-
-//
-//
-// Apply partially
-//   https://github.com/twbs/bootstrap/blob/v4.5.0/scss/_tables.scss
-//
-//
-
-.table {
-  color: $table-color;
-  background-color: $table-bg; // Reset for nesting within parents with `background-color`.
-
-  th,
-  td {
-    border-top-color: $table-border-color;
-  }
-
-  thead th {
-    border-bottom-color: $table-border-color;
-  }
-
-  tbody + tbody {
-    border-top-color: $table-border-color;
-  }
-}
-
-.table-bordered {
-  border-color: $table-border-color;
-
-  th,
-  td {
-    border-color: $table-border-color;
-  }
-}
-
-.table-hover {
-  tbody tr {
-    @include hover() {
-      color: $table-hover-color;
-      background-color: $table-hover-bg;
-    }
-  }
-}
-
-.table-dark {
-  color: $table-dark-color;
-  background-color: $table-dark-bg;
-
-  th,
-  td,
-  thead th {
-    border-color: $table-dark-border-color;
-  }
-
-  &.table-bordered {
-    border: 0;
-  }
-
-  &.table-striped {
-    tbody tr:nth-of-type(#{$table-striped-order}) {
-      background-color: $table-dark-accent-bg;
-    }
-  }
-
-  &.table-hover {
-    tbody tr {
-      @include hover() {
-        color: $table-dark-hover-color;
-        background-color: $table-dark-hover-bg;
-      }
-    }
-  }
-}

+ 0 - 3
packages/preset-themes/src/styles/theme/_reboot-bootstrap-text.scss

@@ -1,3 +0,0 @@
-.text-muted {
-  color: $text-muted !important;
-}

+ 0 - 92
packages/preset-themes/src/styles/theme/_reboot-bootstrap-theme-colors.scss

@@ -1,92 +0,0 @@
-@use '../bootstrap/init' as *;
-@use '../atoms/mixins/buttons' as mixins-buttons;
-
-@each $color, $value in $theme-colors {
-  @include bg-variant('.bg-#{$color}', $value);
-}
-
-@each $color, $value in $theme-colors {
-  .border-#{$color} {
-    border-color: $value !important;
-  }
-}
-
-@each $color, $value in $theme-colors {
-  @include text-emphasis-variant('.text-#{$color}', $value, true);
-}
-
-@each $color, $value in $theme-colors {
-  .btn-#{$color} {
-    @include button-variant($value, $value);
-    @include mixins-buttons.button-svg-icon-variant($value, $value);
-    box-shadow: none !important;
-  }
-}
-
-@each $color, $value in $theme-colors {
-  .btn-outline-#{$color} {
-    @include button-outline-variant($value, $color-hover: $value, $active-background: rgba($value, 0.1), $active-border: $value);
-    @include mixins-buttons.button-outline-svg-icon-variant($value, $color-hover: $value);
-
-    &:not(:disabled):not(.disabled):active,
-    &:not(:disabled):not(.disabled).active {
-      color: $value;
-      background-color: rgba($value, 0.1);
-      border-color: $value;
-    }
-
-    box-shadow: none !important;
-  }
-
-  // separate style: https://github.com/weseek/growi/pull/6804
-  .show > .btn-outline-#{$color}.dropdown-toggle {
-    color: $value;
-    background-color: rgba($value, 0.1);
-    border-color: $value;
-  }
-}
-
-@each $theme-color, $color in $theme-colors {
-  .custom-checkbox-#{$theme-color} {
-    .custom-control-label::before {
-      border-color: $input-border-color;
-      transition: 0.3s ease-in-out;
-    }
-    .custom-control-input:checked + .custom-control-label::before {
-      background-color: $color;
-      border-color: $color;
-    }
-    .custom-control-input:checked + .custom-control-label::after {
-      color: $bgcolor-global;
-    }
-    .custom-control-input:not(:disabled):active ~ .custom-control-label::before {
-      color: $bgcolor-global;
-      background-color: $color;
-      border-color: $color;
-    }
-    .custom-control-input:focus:not(:checked) ~ .custom-control-label::before {
-      color: $bgcolor-global;
-      background-color: $bgcolor-global;
-      border-color: $input-focus-border-color;
-    }
-  }
-}
-
-@each $color, $value in $theme-colors {
-  .alert-#{$color} {
-    @include alert-variant(
-      theme-color-level($color, $alert-bg-level),
-      theme-color-level($color, $alert-border-level),
-      theme-color-level($color, $alert-color-level)
-    );
-  }
-}
-
-@each $color, $value in $theme-colors {
-  .badge-#{$color} {
-    @include badge-variant($value);
-  }
-  a.badge-#{$color} {
-    @include badge-variant($value);
-  }
-}

+ 0 - 0
packages/preset-themes/src/styles/theme/_reboot-toastr-colors.scss


+ 0 - 9
packages/preset-themes/src/styles/theme/mixins/_count-badge.scss

@@ -1,9 +0,0 @@
-@mixin count-badge($color, $bg-color, $min-width: initial) {
-  min-width: $min-width;
-  padding: 0.1rem 0.5rem;
-  font-family: var(--font-family-monospace);
-  font-size: 12px;
-  font-weight: 500;
-  color: $color;
-  background-color: $bg-color;
-}

+ 142 - 0
packages/preset-themes/src/styles/theme/mixins/_hsl-button.scss

@@ -0,0 +1,142 @@
+@use '../../bootstrap/init' as bs;
+@use '../hsl-functions' as hsl;
+
+// @mixin button-variant($background, $border, $hover-background: darken($background, 7.5%), $hover-border: darken($border, 10%), $active-background: darken($background, 10%), $active-border: darken($border, 12.5%)) {
+@mixin button-variant($background, $border, $hover-background-darken-degrees: 7.5%, $hover-border-darken-degrees: 10%, $active-background-darken-degrees: 10%, $active-border-darken-degrees: 12.5%) {
+  $hover-background: hsl.darken($background, $hover-background-darken-degrees);  // DO NOT ... twice
+  $hover-border: hsl.darken($border, $hover-border-darken-degrees);  // DO NOT ... twice
+
+  color: hsl.contrast($background);
+  @include bs.gradient-bg($background);
+  border-color: $border;
+  // @include box-shadow($btn-box-shadow);
+
+  @include bs.hover() {
+    color: hsl.contrast($background);
+    @include bs.gradient-bg($hover-background);
+    border-color: $hover-border;
+  }
+
+  &:focus,
+  &.focus {
+    color: hsl.contrast($background);
+    @include bs.gradient-bg($hover-background);
+    border-color: $hover-border;
+    // @if $enable-shadows {
+    //   @include box-shadow($btn-box-shadow, 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5));
+    // } @else {
+    //   // Avoid using mixin so we can pass custom focus shadow properly
+    //   box-shadow: 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);
+    // }
+  }
+
+  // // Disabled comes first so active can properly restyle
+  &.disabled,
+  &:disabled {
+    color: hsl.contrast($background);
+    @include bs.gradient-bg($background);
+    border-color: $border;
+    // Remove CSS gradients if they're enabled
+    @if bs.$enable-gradients {
+      background-image: none;
+    }
+  }
+
+  &:not(:disabled):not(.disabled):active,
+  &:not(:disabled):not(.disabled).active,
+  .show > &.dropdown-toggle {
+    color: hsl.contrast($background);
+    background-color: $hover-background;
+    border-color: $hover-border;
+  }
+  //   @if $enable-gradients {
+  //     background-image: none; // Remove the gradient for the pressed/active state
+  //   }
+  //   border-color: $active-border;
+
+  //   &:focus {
+  //     // @if $enable-shadows and $btn-active-box-shadow != none {
+  //     //   @include box-shadow($btn-active-box-shadow, 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5));
+  //     // } @else {
+  //     //   // Avoid using mixin so we can pass custom focus shadow properly
+  //     //   box-shadow: 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);
+  //     // }
+  //   }
+  // }
+}
+
+// @mixin button-outline-variant($color, $color-hover: color-yiq($color), $active-background: $color, $active-border: $color) {
+@mixin button-outline-variant($color, $color-hover: hsl.contrast($color), $active-background: $color, $active-border: $color) {
+  color: $color;
+  border-color: $color;
+
+  @include bs.hover() {
+    color: $color-hover;
+    background-color: $active-background;
+    border-color: $active-border;
+  }
+
+  // &:focus,
+  // &.focus {
+  //   box-shadow: 0 0 0 bs.$btn-focus-width hsl.alpha($color,50%);
+  // }
+
+  &.disabled,
+  &:disabled {
+    color: $color;
+    background-color: transparent;
+  }
+
+  // &:not(:disabled):not(.disabled):active,
+  // &:not(:disabled):not(.disabled).active,
+  // .show > &.dropdown-toggle {
+  //   color: hsl.contrast($active-background);
+  //   background-color: $active-background;
+  //   border-color: $active-border;
+
+  // &:focus {
+  //   @if $enable-shadows and $btn-active-box-shadow != none {
+  //     @include bs.box-shadow($btn-active-box-shadow, 0 0 0 $btn-focus-width hsl.alpha($color,50%));
+  //   } @else {
+  //     // Avoid using mixin so we can pass custom focus shadow properly
+  //     box-shadow: 0 0 0 $btn-focus-width hsl.alpha($color,50%);
+  //   }
+  // }
+  // }
+}
+
+// @mixin button-svg-icon-variant($background, $hover-background: darken($background, 7.5%), $active-background: darken($background, 10%)) {
+@mixin button-svg-icon-variant($background, $hover-background-darken-degrees: 7.5%, $active-background-darken-degrees: 10%) {
+  svg {
+    fill: hsl.contrast($background);
+  }
+
+  @include bs.hover() {
+    svg {
+      fill: hsl.contrast($background);
+    }
+  }
+
+  &:focus,
+  &.focus {
+    svg {
+      fill: hsl.contrast($background);
+    }
+  }
+
+  // Disabled comes first so active can properly restyle
+  &.disabled,
+  &:disabled {
+    svg {
+      fill: hsl.contrast($background);
+    }
+  }
+
+  &:not(:disabled):not(.disabled):active,
+  &:not(:disabled):not(.disabled).active,
+  .show > &.dropdown-toggle {
+    svg {
+      fill: hsl.contrast($background);
+    }
+  }
+}

+ 0 - 70
packages/preset-themes/src/styles/theme/mixins/_list-group.scss

@@ -1,70 +0,0 @@
-@use '../../bootstrap/init' as bs;
-@use '../../mixins';
-@use './count-badge';
-
-@mixin override-list-group-item($color, $bgcolor, $color-hover: $color, $bgcolor-hover: $bgcolor, $color-active: $color, $bgcolor-active: $bgcolor) {
-  .list-group {
-    .list-group-item {
-      color: $color;
-      background-color: $bgcolor;
-      border-color: $border-color-global;
-
-      &.list-group-item-action {
-        &:hover {
-          background-color: $bgcolor-hover;
-        }
-        &.active {
-          color: $color-active;
-          background-color: $bgcolor-active;
-        }
-      }
-    }
-  }
-}
-
-@mixin override-list-group-item-for-pagetree($color, $bgcolor-hover, $bgcolor-active, $btn-color, $btn-color-hover, $btn-bgcolor-hover, $btn-bgcolor-active) {
-  .grw-pagetree-is-over {
-    background: $bgcolor-hover;
-  }
-  .list-group-item {
-    color: $color;
-    background-color: transparent;
-    border-color: $border-color-global;
-
-    .grw-count-badge {
-      @include count-badge.count-badge($btn-color, $bgcolor-hover, 28px);
-    }
-
-    .btn.btn-page-item-control {
-      color: $btn-color;
-      background-color: transparent;
-      @include bs.hover() {
-        color: $btn-color-hover;
-        background-color: $btn-bgcolor-hover;
-      }
-      &:not(:disabled):not(.disabled):active,
-      &:not(:disabled):not(.disabled).active {
-        color: $btn-color-hover;
-        background-color: $btn-bgcolor-active;
-      }
-    }
-
-    &.grw-pagetree-current-page-item {
-      background: $bgcolor-hover;
-    }
-
-    &.list-group-item-action {
-      &:hover {
-        background-color: $bgcolor-hover;
-      }
-      &:active {
-        background-color: $bgcolor-active;
-      }
-    }
-    .grw-pagetree-title-anchor {
-      .grw-sidebar-text-muted {
-        color: rgba(desaturate($color, 50%), 0.6);
-      }
-    }
-  }
-}

+ 0 - 34
packages/preset-themes/src/styles/theme/mixins/_tables.scss

@@ -1,34 +0,0 @@
-//== Table
-// $table-variants: (
-//   'light': $light,
-//   'dark': $dark,
-// );
-
-// remove when master version is released
-// show https://github.com/twbs/bootstrap/blob/28cb1ff2b23253293601c51aff434c39b461025e/scss/mixins/_table-variants.scss
-// @mixin table-variant($state, $background) {
-//   .table-#{$state} {
-//     $table-hover-bg-factor: 0.075 !default;
-//     $table-striped-bg-factor: 0.05 !default;
-//     $body-bg: $white !default;
-//     $table-active-bg-factor: 0.1 !default;
-//     $table-border-factor: 0.1 !default;
-
-//     $color: color-contrast(mix(rgba($background, 1), $body-bg, opacity($background) * 100));
-//     $color: gray;
-//     $hover-bg: mix($color, $background, percentage($table-hover-bg-factor));
-//     $striped-bg: mix($color, $background, percentage($table-striped-bg-factor));
-//     $active-bg: mix($color, $background, percentage($table-active-bg-factor));
-
-//     --bs-table-bg: #{$background};
-//     --bs-table-striped-bg: #{$striped-bg};
-//     --bs-table-striped-color: #{color-contrast($striped-bg)};
-//     --bs-table-active-bg: #{$active-bg};
-//     --bs-table-active-color: #{color-contrast($active-bg)};
-//     --bs-table-hover-bg: #{$hover-bg};
-//     --bs-table-hover-color: #{color-contrast($hover-bg)};
-
-//     color: $color;
-//     border-color: mix($color, $background, percentage($table-border-factor));
-//   }
-// }

+ 89 - 70
packages/preset-themes/src/styles/wood.scss

@@ -1,21 +1,12 @@
 @use './variables' as *;
 @use './bootstrap/variables' as *;
 @use './theme/mixins/page-editor-mode-manager';
-
-// == Define Bootstrap theme colors
-//
-// colors for overriding bootstrap $theme-colors
-// $secondary: #;
-// $success: #;
-// $warning: #;
-// $danger: #;
-// $light: #;
-// $dark: #;
+@use './theme/hsl-functions' as hsl;
 
 .growi:not(.login-page) {
   // add background-image
   .page-editor-preview-container {
-    background-image: url('/images/themes/wood/wood.jpg');
+    background-image: url('../images/wood/wood.jpg');
     background-attachment: fixed;
     background-position: center center;
     background-size: cover;
@@ -24,97 +15,125 @@
 
 .growi.login-page {
   .page-wrapper {
-    background-image: url('/images/themes/wood/wood.jpg');
+    background-image: url('../images/wood/wood.jpg');
     background-attachment: fixed;
     background-position: center center;
     background-size: cover;
   }
 }
 
-$themecolor: #b9b177;
-$themelight: #f5f3ee;
-
 //== Light Mode
 //
-:root {
-  $primary: #aaa45f;
+:root[data-theme='light'] {
+  --primary: hsl(var(--primary-hs),var(--primary-l)) !important;
+  --primary-hs: 55,31%;
+  --primary-l: 52%;
+  --secondary: hsl(var(--secondary-hs),var(--secondary-l)) !important;
+  --secondary-hs: 208,7%;
+  --secondary-l: 46%;
+  --themecolor: hsl(var(--themecolor-hs),var(--themecolor-l));
+  --themecolor-hs: 53,32%;
+  --themecolor-l: 60%;
 
   // Background colors
-  $bgcolor-global: white;
-  $bgcolor-card: #ece8de;
-  $bgcolor-blinked-section: rgba($primary, 0.3);
-  $bgcolor-keyword-highlighted: $grw-marker-blue;
+  --bgcolor-global: hsl(var(--bgcolor-global-hs),var(--bgcolor-global-l));
+  --bgcolor-global-hs: 0,0%;
+  --bgcolor-global-l: 100%;
+  --bgcolor-card: #ece8de;
+  --bgcolor-blinked-section: #{hsl.alpha(var(--primary),70%)};
+  --bgcolor-keyword-highlighted: #{$grw-marker-blue};
 
   // Font colors
-  // $color-global: black;
-  $color-global: #433005;
-  $color-reversal: #fffffc;
-  $color-link: #9d7406;
-  $color-link-hover: lighten($color-link, 10%);
-  $color-link-wiki: $color-link;
-  $color-link-wiki-hover: lighten($color-link-wiki, 10%);
-  $color-link-nabvar: #a7a7a7;
-  $color-search: white;
+  --color-global: hsl(var(--color-global-hs),var(--color-global-l));
+  --color-global-hs: 42,86%;
+  --color-global-l: 14%;
+  --color-reversal: #fffffc;
+  --color-link: hsl(var(--color-link-hs),var(--color-link-l));
+  --color-link-hs: 44,93%;
+  --color-link-l: 32%;
+  --color-link-hover: #{hsl.lighten(var(--color-link), 10%)};
+  --color-link-wiki: var(--color-link);
+  --color-link-wiki-hs: var(--color-link-hs);
+  --color-link-wiki-l: var(--color-link-l);
+  --color-link-wiki-hover: #{hsl.lighten(var(--color-link), 10%)};
+  --color-link-nabvar: #a7a7a7;
+  --color-search: white;
 
   // Inline code
-  $bgcolor-inline-code: $themelight; //optional
-  // $color-inline-code: # !default;
-  $bordercolor-inline-code: $themecolor; //optional
+  --bgcolor-inline-code: #f5f3ee;; //optional
+  // --color-inline-code: # !default;
+  --bordercolor-inline-code: var(--themecolor); //optional
 
   // List Group colors
-  // $color-list: $color-global;
-  $bgcolor-list: transparent;
-  $color-list-hover: $gray-100;
-  $bgcolor-list-hover: lighten($primary, 40%);
-  // $color-list-active: $color-reversal;
-  $bgcolor-list-active: lighten($primary, 30%);
+  // --color-list: var(--color-global);
+  --bgcolor-list: transparent;
+  --color-list-hover: #{$gray-100};
+  --bgcolor-list-hover: #{hsl.lighten(var(--primary), 40%)};
+  // --color-list-active: var(--color-reversal);
+  --bgcolor-list-active: #{hsl.lighten(var(--primary), 30%)};
 
   // Table colors
-  // $color-table: #; // optional
-  // $bgcolor-table: #; // optional
-  $border-color-table: $gray-400; // optional
-  // $color-table-hover: #; // optional
-  // $bgcolor-table-hover: #; // optional
+  // --color-table: #; // optional
+  // --bgcolor-table: #; // optional
+  --border-color-table: #{$gray-400}; // optional
+  // --color-table-hover: #; // optional
+  // --bgcolor-table-hover: #; // optional
 
   // Navbar
-  $bgcolor-navbar: #2a2929;
-  $bgcolor-search-top-dropdown: $themecolor;
-  $border-image-navbar: linear-gradient(to right, $themecolor 0%, darken($themecolor, 20%) 100%);
+  --bgcolor-navbar: hsl(var(--bgcolor-navbar-hs),var(--bgcolor-navbar-l));
+  --bgcolor-navbar-hs: 0,1%;
+  --bgcolor-navbar-l: 16%;
+  --bgcolor-search-top-dropdown: var(--themecolor);
+  --bgcolor-search-top-dropdown-hs: var(--themecolor-hs);
+  --bgcolor-search-top-dropdown-l: var(--themecolor-l);
+  --border-image-navbar: linear-gradient(to right, var(--themecolor) 0%, #{hsl.darken(var(--themecolor), 20%)} 100%);
 
   // Logo colors
-  $bgcolor-logo: darken($themecolor, 10%);
-  $fillcolor-logo-mark: lighten(desaturate($themecolor, 50%), 50%); // Icon colors
-  $color-editor-icons: $color-global;
+  --bgcolor-logo: #{hsl.darken(var(--themecolor), 10%)};
+  --fillcolor-logo-mark: #{lighten(desaturate(#b9b177, 50%), 50%)}; // Icon colors
+  --color-editor-icons: var(--color-global);
 
   // Sidebar
-  $bgcolor-sidebar: $themecolor;
+  --bgcolor-sidebar: var(--themecolor);
+  --bgcolor-sidebar-hs: var(--themecolor-hs);
+  --bgcolor-sidebar-l: var(--themecolor-l);
+
   // Sidebar contents
-  $color-sidebar-context: #9d7406;
-  $bgcolor-sidebar-context: lighten($themecolor, 38%);
+  --color-sidebar-context: hsl(var(--color-sidebar-context-hs),var(--color-sidebar-context-l));
+  --color-sidebar-context-hs: 44,93%;
+  --color-sidebar-context-l: 32%;
+  --bgcolor-sidebar-context: #{hsl.lighten(var(--themecolor), 38%)};
+  --bgcolor-sidebar-context-hs: var(--themecolor-hs);
+  --bgcolor-sidebar-context-l: calc(var(--themecolor-l) + 38%);
+
   // Sidebar list group
-  $bgcolor-sidebar-list-group: rgba(#f7f5f1, 0.5);
+  --bgcolor-sidebar-list-group: rgba(#f7f5f1, 0.5);
+
   // Sidebar resize button
-  $color-resize-button: white;
-  $bgcolor-resize-button: $themecolor;
+  --color-resize-button: white;
+  --bgcolor-resize-button: var(--themecolor);
+  --bgcolor-resize-button-hs: var(--themecolor-hs);
+  --bgcolor-resize-button-l: var(--themecolor-l);
+  --color-resize-button-hover: var(--color-reversal);
+  --bgcolor-resize-button-hover: #{hsl.lighten(var(--bgcolor-resize-button), 5%)};
 
   // Border colors
-  $border-color-theme: $gray-300; // former: `$navbar-border: $gray-300;`
-  $bordercolor-inline-code: #ccc8c8; // optional
+  --border-color-theme: #{$gray-300}; // former: `$navbar-border: $gray-300;`
+  --bordercolor-inline-code: #ccc8c8; // optional
 
   // Dropdown colors
-  $bgcolor-dropdown-link-active: $growi-blue;
+  --bgcolor-dropdown-link-active: #{$growi-blue};
 
   // admin theme box
-  $color-theme-color-box: lighten($primary, 20%);
+  --color-theme-color-box: #{hsl.lighten(var(--primary), 20%)};
 
   // alert
-  $color-alert: $color-reversal;
-
-  // portal
-  $info: lighten($themecolor, 10%);
+  --color-alert: var(--color-reversal);
 
-  @import './theme/apply-colors';
-  @import './theme/apply-colors-light';
+  // Subnavigation
+  --bgcolor-subnav: hsl(var(--bgcolor-subnav-hs),var(--bgcolor-subnav-l));
+  --bgcolor-subnav-hs: var(--bgcolor-global-hs);
+  --bgcolor-subnav-l: calc(var(--bgcolor-global-l) - 3%);
 
   &, body {
     background-image: url('../images/wood/wood.jpg');
@@ -127,13 +146,13 @@ $themelight: #f5f3ee;
    * Modal
    */
   .modal-dialog .modal-header.bg-primary {
-    background-image: url('/images/themes/wood/wood-navbar.jpg');
+    background-image: url('../images/wood/wood-navbar.jpg');
   }
 
   // Sidebar
   .grw-sidebar {
     div[data-testid='GlobalNavigation'] {
-      background-image: url('/images/themes/wood/wood-navbar.jpg');
+      background-image: url('../images/wood/wood-navbar.jpg');
 
       button,
       .btn {
@@ -143,7 +162,7 @@ $themelight: #f5f3ee;
     div[data-testid='ContextualNavigation'] {
       > div {
         background-color: rgba(white, 0.6);
-        background-image: url('/images/themes/wood/wood-navbar.jpg');
+        background-image: url('../images/wood/wood-navbar.jpg');
         background-blend-mode: lighten;
       }
     }
@@ -170,7 +189,7 @@ $themelight: #f5f3ee;
   // Button
   .btn-group.grw-page-editor-mode-manager {
     .btn.btn-outline-primary {
-      @include page-editor-mode-manager.btn-page-editor-mode-manager(darken($primary, 30%), lighten($primary, 15%), lighten($primary, 25%));
+      @include page-editor-mode-manager.btn-page-editor-mode-manager(#{hsl.darken(var(--primary), 30%)}, #{hsl.lighten(var(--primary), 15%)}, #{hsl.lighten(var(--primary), 25%)});
     }
   }
 }