Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v2.8.2 #472

Closed
wants to merge 20 commits into from
Closed

v2.8.2 #472

wants to merge 20 commits into from

Conversation

EvanNotFound
Copy link
Owner

@EvanNotFound EvanNotFound commented Nov 30, 2024

fix #463

Summary by CodeRabbit

  • New Features

    • Introduced a delete_mask configuration option to enhance the visual presentation of deleted content in articles.
    • Added a new filter to modify the appearance of <del> tags based on the delete_mask setting.
    • Updated the postNoteLarge function to handle default values and improve icon handling.
    • Enhanced Open Graph metadata handling with a new configuration format.
    • Added a new audio player initialization script for improved audio playback options.
    • Comprehensive Tailwind CSS build with utility classes for responsive design.
  • Bug Fixes

    • Improved the reliability of the audio player by enforcing strict equality checks.
  • Refactor

    • Enhanced code clarity and organization by encapsulating audio player initialization logic within an IIFE.
    • Updated variable naming for better readability.
  • Style

    • Added a new .mask class for improved hover effects and transitions in markdown styles.
    • Adjusted styles for the mjx-container class to enhance scrollbar behavior.
    • Updated file paths for JavaScript libraries to streamline references.
    • Modified paths in build scripts for consistency and clarity.
    • Removed deprecated boolean checks for Open Graph settings to improve configuration management.

Copy link

coderabbitai bot commented Nov 30, 2024

📝 Walkthrough
📝 Walkthrough

Walkthrough

The changes introduce an immediately invoked function expression (IIFE) in the aplayer.js file to encapsulate the audio player initialization logic. Key modifications include the use of strict equality checks, renaming a loop variable for clarity, and altering the instantiation process of the APlayer instance. The encapsulation helps avoid global scope pollution, while the other changes enhance code clarity and maintain the existing control flow.

Changes

File Change Summary
source/js/plugins/aplayer.js Introduced an IIFE for audio player initialization, changed comparison operators to strict equality, renamed loop variable, modified player instantiation logic.
_config.yml Added delete_mask property to articles section, defaulting to false.
scripts/filters/delete-mask-handle.js Introduced a filter for <del> tags that applies a mask effect based on delete_mask configuration.
scripts/modules/note-large.js Modified postNoteLarge to check args length and adjust icon handling.
scripts/modules/note.js Removed and replaced a line registering the "subnote" tag, no functional change.
source/css/common/markdown.styl Added .mask class for styling <del> tags with hover effects.
layout/components/header/head.ejs Updated Open Graph metadata handling to support new configuration format and added deprecation warnings.
scripts/helpers/theme-helpers.js Added checkDeprecation function for logging deprecation warnings.
layout/components/plugins/aplayer.ejs Modified paths for JavaScript files referenced in the HTML output.
layout/components/scripts.ejs Updated paths for JavaScript files in the renderJS function.
layout/components/swup.ejs Changed paths for JavaScript libraries in the renderJS function.
package.json Updated output paths in build:css and watch:css scripts for Tailwind CSS.
source/js/build.js Modified BUILD_DIR constant to change the output path for JavaScript builds.
source/js/build/plugins/aplayer.js Introduced a new file for audio player initialization based on configuration.

Assessment against linked issues

Objective Addressed Explanation
Ensure APlayer is displayed on the page (#463)

Possibly related PRs

  • v2.8.1 #461: The changes in the main PR regarding the initialization of the audio player in aplayer.js may relate to the overall functionality and rendering of components in the Hexo theme, which is also a focus of PR v2.8.1 #461 that addresses rendering issues in the theme.

Suggested labels

deployed


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between cd84a2b and e0010cd.

📒 Files selected for processing (1)
  • .github/workflows/preview-deployment.yml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/preview-deployment.yml

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Outside diff range and nitpick comments (1)
source/js/plugins/aplayer.js (1)

1-4: LGTM! Consider adding error handling.

The IIFE and constant declarations look good. The use of strict equality operators is a good practice.

Consider adding error handling for missing theme configuration:

 (function() {
+  if (!theme?.plugins?.aplayer?.type || !theme?.plugins?.aplayer?.audios) {
+    console.warn('APlayer configuration is missing or invalid');
+    return;
+  }
   const audioList = [];
   const isFixed = theme.plugins.aplayer.type === "fixed";
   const isMini = theme.plugins.aplayer.type === "mini";
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between eaf1829 and 09aa3f5.

⛔ Files ignored due to path filters (2)
  • source/build/js/plugins/aplayer.js is excluded by !source/build/**
  • source/build/js/plugins/aplayer.js.map is excluded by !**/*.map, !source/build/**
📒 Files selected for processing (1)
  • source/js/plugins/aplayer.js (1 hunks)
🔇 Additional comments (1)
source/js/plugins/aplayer.js (1)

1-33: Verify APlayer dependencies and container setup.

Let's verify that the required setup is in place across the codebase.

✅ Verification successful

Dependencies and container setup are properly configured

The verification shows that the APlayer setup is correctly implemented:

  • Container element <div id="aplayer"></div> is properly defined in layout/components/plugins/aplayer.ejs
  • APlayer library is loaded via APlayer.min.js before the plugin code
  • The plugin script aplayer.js is loaded after the library
  • The loading order is correct as they are defined sequentially in the same EJS file
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if APlayer script is loaded before this code
rg -l '<script.*aplayer\.js' --type html

# Check if APlayer container element exists in templates
rg -l 'id="aplayer"' --type html

# Check if APlayer CSS is included
rg -l '<link.*aplayer\.css' --type html

# Check if APlayer library is included as a dependency
rg -l '"aplayer"|"@aplayer"' --type json

Length of output: 200


Script:

#!/bin/bash
# Let's check the content of the aplayer.ejs component
cat layout/components/plugins/aplayer.ejs

# Check if APlayer script is included in any other EJS files
rg -l "aplayer" --type-add 'ejs:*.ejs' --type ejs

# Look for APlayer script inclusion in layout files
rg "script.*aplayer" --type-add 'ejs:*.ejs' --type ejs -A 2 -B 2

# Check package.json for APlayer dependency
fd package.json --exec cat {}

Length of output: 1566

Comment on lines +6 to +16
for (const audio of theme.plugins.aplayer.audios) {
const audioObj = {
name: audio.name,
artist: audio.artist,
url: audio.url,
cover: audio.cover,
lrc: audio.lrc,
theme: audio.theme,
};
audioList.push(audioObj);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add validation for required audio properties.

While the audio object construction is clean, missing required properties could cause player initialization to fail silently.

Consider adding validation:

 for (const audio of theme.plugins.aplayer.audios) {
+  const requiredProps = ['name', 'url'];
+  const missingProps = requiredProps.filter(prop => !audio[prop]);
+  if (missingProps.length > 0) {
+    console.warn(`Skipping audio track: missing required properties: ${missingProps.join(', ')}`);
+    continue;
+  }
   const audioObj = {
     name: audio.name,
     artist: audio.artist,
     url: audio.url,
     cover: audio.cover,
     lrc: audio.lrc,
     theme: audio.theme,
   };
   audioList.push(audioObj);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
for (const audio of theme.plugins.aplayer.audios) {
const audioObj = {
name: audio.name,
artist: audio.artist,
url: audio.url,
cover: audio.cover,
lrc: audio.lrc,
theme: audio.theme,
};
audioList.push(audioObj);
}
for (const audio of theme.plugins.aplayer.audios) {
const requiredProps = ['name', 'url'];
const missingProps = requiredProps.filter(prop => !audio[prop]);
if (missingProps.length > 0) {
console.warn(`Skipping audio track: missing required properties: ${missingProps.join(', ')}`);
continue;
}
const audioObj = {
name: audio.name,
artist: audio.artist,
url: audio.url,
cover: audio.cover,
lrc: audio.lrc,
theme: audio.theme,
};
audioList.push(audioObj);
}

Comment on lines +18 to +32
if (isMini) {
new APlayer({
container: document.getElementById("aplayer"),
mini: true,
audio: audioList,
});
} else if (isFixed) {
const player = new APlayer({
container: document.getElementById("aplayer"),
fixed: true,
lrcType: 3,
audio: audioList,
});
document.querySelector(".aplayer-icon-lrc").click();
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add container verification and error handling.

The player initialization needs more robust error handling to prevent silent failures, which might be related to the reported display issues.

Apply these improvements:

+  const container = document.getElementById("aplayer");
+  if (!container) {
+    console.error("APlayer container element not found");
+    return;
+  }
+
+  try {
     if (isMini) {
       new APlayer({
-        container: document.getElementById("aplayer"),
+        container: container,
         mini: true,
         audio: audioList,
       });
     } else if (isFixed) {
       const player = new APlayer({
-        container: document.getElementById("aplayer"),
+        container: container,
         fixed: true,
         lrcType: 3,
         audio: audioList,
       });
-      document.querySelector(".aplayer-icon-lrc").click();
+      // Wait for player to be ready before clicking lyrics icon
+      setTimeout(() => {
+        const lrcIcon = document.querySelector(".aplayer-icon-lrc");
+        if (lrcIcon) lrcIcon.click();
+      }, 100);
     }
+  } catch (error) {
+    console.error("Failed to initialize APlayer:", error);
+  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (isMini) {
new APlayer({
container: document.getElementById("aplayer"),
mini: true,
audio: audioList,
});
} else if (isFixed) {
const player = new APlayer({
container: document.getElementById("aplayer"),
fixed: true,
lrcType: 3,
audio: audioList,
});
document.querySelector(".aplayer-icon-lrc").click();
}
const container = document.getElementById("aplayer");
if (!container) {
console.error("APlayer container element not found");
return;
}
try {
if (isMini) {
new APlayer({
container: container,
mini: true,
audio: audioList,
});
} else if (isFixed) {
const player = new APlayer({
container: container,
fixed: true,
lrcType: 3,
audio: audioList,
});
// Wait for player to be ready before clicking lyrics icon
setTimeout(() => {
const lrcIcon = document.querySelector(".aplayer-icon-lrc");
if (lrcIcon) lrcIcon.click();
}, 100);
}
} catch (error) {
console.error("Failed to initialize APlayer:", error);
}

新增功能:为 Markdown 内容中的 <del> 标签添加遮罩效果
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (3)
scripts/filters/delete-mask-handle.js (2)

3-3: Remove redundant 'use strict' directive

The 'use strict' directive is redundant as JavaScript modules are automatically in strict mode.

-"use strict";
🧰 Tools
🪛 Biome (1.9.4)

[error] 2-3: Redundant use strict directive.

The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
Safe fix: Remove the redundant use strict directive.

(lint/suspicious/noRedundantUseStrict)


13-22: Add error handling for content replacement

The content replacement lacks error handling which could cause issues if the content is undefined or null.

-    data.content = data.content.replace(
+    data.content = (data.content || '').replace(
       regPureDelTag,
       function (match, html) {
         if (theme.config.articles.style.delete_mask === true) {
           return `<del class="mask">${html}</del>`;
         }
         return match;
       }
     );
source/css/common/markdown.styl (1)

213-229: Consider accessibility implications of mask implementation

While the mask implementation is technically sound, consider adding aria attributes for screen readers.

   del.mask
     text-decoration none !important
     transition .2s cubic-bezier(.25, .46, .45, .94) color, .2s cubic-bezier(.25, .46, .45, .94) background
+    aria-label "Masked content, hover to reveal"
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 09aa3f5 and f0f412a.

📒 Files selected for processing (5)
  • _config.yml (1 hunks)
  • scripts/filters/delete-mask-handle.js (1 hunks)
  • scripts/modules/note-large.js (1 hunks)
  • scripts/modules/note.js (1 hunks)
  • source/css/common/markdown.styl (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • scripts/modules/note.js
🧰 Additional context used
🪛 Biome (1.9.4)
scripts/filters/delete-mask-handle.js

[error] 2-3: Redundant use strict directive.

The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
Safe fix: Remove the redundant use strict directive.

(lint/suspicious/noRedundantUseStrict)


[error] 11-11: The regular expression includes this negated empty character class.

Negated empty character classes match anything.
If you want to match against [, escape it [.
Otherwise, remove the character class or fill it.

(lint/correctness/noEmptyCharacterClassInRegex)

🔇 Additional comments (2)
_config.yml (2)

278-278: ⚠️ Potential issue

Unrelated change to PR objective

The addition of delete_mask configuration appears unrelated to fixing the aplayer display issue (#463). Consider submitting this change in a separate PR to maintain clear change tracking and purpose.


Line range hint 496-513: Verify aplayer configuration and implementation

The PR aims to fix the aplayer display issue, but there are no changes to the aplayer configuration. Please verify:

  1. The aplayer initialization in the JavaScript code
  2. The CSS visibility properties
  3. The DOM mounting point for the player

const theme = this.theme;

// 处理del标签的代码
const regPureDelTag = /<del(?:\s+[^>]*)?>((?:(?!<\/?del[\s>])[^])*)<\/del>/g;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Fix potential regex issue with empty character class

The regular expression includes a negated empty character class [^] which could be problematic. Consider using a more explicit pattern.

-const regPureDelTag = /<del(?:\s+[^>]*)?>((?:(?!<\/?del[\s>])[^])*)<\/del>/g;
+const regPureDelTag = /<del(?:\s+[^>]*)?>((?:(?!<\/?del[\s>])[\s\S])*)<\/del>/g;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const regPureDelTag = /<del(?:\s+[^>]*)?>((?:(?!<\/?del[\s>])[^])*)<\/del>/g;
const regPureDelTag = /<del(?:\s+[^>]*)?>((?:(?!<\/?del[\s>])[\s\S])*)<\/del>/g;
🧰 Tools
🪛 Biome (1.9.4)

[error] 11-11: The regular expression includes this negated empty character class.

Negated empty character classes match anything.
If you want to match against [, escape it [.
Otherwise, remove the character class or fill it.

(lint/correctness/noEmptyCharacterClassInRegex)

- Refactor Open Graph settings in _config.yml to use a new structure with 'enable', 'image', and 'description' fields.
- Implement a deprecation warning for the old Open Graph format in head.ejs to guide users towards the new configuration.
- Enhance Open Graph meta tags to include author and Twitter card information for better social media integration.
- Add a helper function to manage deprecation warnings, ensuring users are informed of outdated configurations.
Add og image and og description support
feat: update Open Graph configuration and deprecate old format
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (1)
layout/components/header/head.ejs (1)

35-39: Ensure deprecation message handles newline characters correctly

Verify that the newline characters \n in the deprecation message are rendered properly in the console output. Depending on the logging mechanism, \n may not produce actual line breaks.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between f0f412a and aa93c7b.

📒 Files selected for processing (3)
  • _config.yml (2 hunks)
  • layout/components/header/head.ejs (1 hunks)
  • scripts/helpers/theme-helpers.js (1 hunks)
🔇 Additional comments (4)
layout/components/header/head.ejs (2)

40-40: Open Graph configuration checks are comprehensive

The condition effectively checks both the new and old open_graph configurations, ensuring backward compatibility.


42-45: Variable assignments correctly handle fallbacks

The assignments for ogImage, ogDescription, and author appropriately prioritize page-level values and fallback to configuration defaults.

_config.yml (2)

94-97: Open Graph configuration updated successfully

The new open_graph object is properly defined, enhancing flexibility for Open Graph settings.


281-281: delete_mask property added correctly

The delete_mask option is correctly introduced, allowing control over the masking effect on <del> tags.

Repository owner deleted a comment from coderabbitai bot Dec 1, 2024
- Updated mermaid plugin version to 11.4.1 in _config.yml
- Added conditional loading of mermaid script based on version in scripts.ejs
- Removed outdated Tailwind CSS styles in tailwind.css
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (1)
source/css/build/tailwind.css (1)

1-1: Consider excluding build artifacts from version control

The tailwind.css file appears to be a generated build artifact from Tailwind CSS. Committing build files can lead to unnecessary repository bloat and potential merge conflicts. It's generally recommended to exclude such files from version control and generate them during the build or deployment process.

Suggestion: Add source/css/build/tailwind.css to your .gitignore file and ensure it's generated as part of your build pipeline.

🧰 Tools
🪛 Biome (1.9.4)

[error] 1-1: Duplicate font names are redundant and unnecessary: Emoji

Remove duplicate font names within the property

(lint/suspicious/noDuplicateFontNames)

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 931e83c and dc93991.

⛔ Files ignored due to path filters (2)
  • source/js/libs/mermaid.min.js is excluded by !**/*.min.js
  • source/js/libs/mermaid.min.js.map is excluded by !**/*.map, !**/*.min.js.map
📒 Files selected for processing (3)
  • _config.yml (3 hunks)
  • layout/components/scripts.ejs (1 hunks)
  • source/css/build/tailwind.css (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • layout/components/scripts.ejs
🧰 Additional context used
🪛 Biome (1.9.4)
source/css/build/tailwind.css

[error] 1-1: Duplicate font names are redundant and unnecessary: Emoji

Remove duplicate font names within the property

(lint/suspicious/noDuplicateFontNames)

🔇 Additional comments (3)
_config.yml (3)

94-97: ⚠️ Potential issue

Ensure consistent handling of 'open_graph' configuration changes

The open_graph property has been updated from a boolean to an object containing enable, image, and description. While this enhances configurability, it may introduce compatibility issues if other parts of the codebase expect open_graph to be a boolean. Please verify that all templates, scripts, and plugins referencing open_graph have been updated to accommodate the new structure to prevent runtime errors or unexpected behavior.

Run the following script to locate all usages of open_graph in the codebase:

✅ Verification successful

Let me analyze the code further by checking the historical changes to understand if this is a recent update and how it's being handled.


Based on the analysis of head.ejs, I can now generate the final response as I have sufficient information about how the open_graph configuration is handled.

The codebase properly handles both old and new open_graph configurations

The code in head.ejs already implements proper backward compatibility and graceful handling of both the old boolean format and the new object structure:

  • It includes a deprecation warning for the old format
  • Uses optional chaining (?.) to safely access the new structure
  • Maintains support for both theme.global.open_graph === true and theme.global.open_graph?.enable
  • Correctly handles the new properties (image and description) with proper fallbacks
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all occurrences of 'open_graph' outside of '_config.yml' to ensure they align with the new structure.

rg 'open_graph' --glob '!_config.yml'

Length of output: 909


Script:

#!/bin/bash
# Check git history for changes related to open_graph
git log -p --grep="open_graph" -- _config.yml layout/components/header/head.ejs

Length of output: 0


Script:

#!/bin/bash
# Check the complete head.ejs file to understand the full context of open_graph usage
cat layout/components/header/head.ejs

Length of output: 6457


450-450: Ensure compatibility with the updated Mermaid version

The mermaid plugin version has been updated to "11.4.1". This major version change may include breaking changes or new syntax. Verify that all existing Mermaid diagrams in your posts are compatible with the updated version. Additionally, confirm that the hexo-filter-mermaid-diagrams plugin supports this version to prevent rendering issues.

Run the following script to locate all posts containing Mermaid diagrams for review:

mermaid' {}


<details>
<summary>✅ Verification successful</summary>

mermaid' {} \;

# Also check for mermaid plugin configuration
fd "_config.yml" -x rg -A 5 "mermaid" {} \;

mermaid"

Check mermaid-related configuration

rg -A 5 "mermaid" _config.yml


---

mermaid'

# Check mermaid-related configuration and dependencies
cat _config.yml | grep -A 5 'mermaid'

# Check for package.json to see if hexo-filter-mermaid-diagrams is listed
cat package.json | grep 'hexo-filter-mermaid'

No Mermaid diagrams found in the codebase

Based on the configuration change in _config.yml updating the Mermaid version, but the absence of any Mermaid diagrams in the markdown files, this version update will not impact the codebase. The configuration appears to be a precautionary setup for potential future use rather than affecting any existing content.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all markdown files with Mermaid diagrams to check for compatibility.

fd -e md -x rg '

Length of output: 116


Script:

#!/bin/bash
# Description: Find all markdown files with Mermaid diagrams to check for compatibility.
fd -e md -x rg -l '

Length of output: 116


Script:

#!/bin/bash
# Search for markdown files containing mermaid diagrams
rg -l "

Length of output: 116


Script:

#!/bin/bash
# Search for markdown files containing mermaid diagrams
rg -l '

Length of output: 116


281-281: Verify the implementation of the 'delete_mask' feature

The delete_mask option has been added to the article style configuration to control the masking effect on <del> tags. Ensure that the corresponding filter delete-mask-handle.js is correctly implemented and that the class .mask is defined in your stylesheets to achieve the desired effect when delete_mask is set to true. Also, consider updating the documentation to inform users about this new feature.

Run the following script to confirm the usage of delete_mask in the codebase:

✅ Verification successful

Let me check the implementation of the delete-mask-handle.js filter and related CSS styles.


Let me check the CSS implementation for the mask effect.


The delete_mask feature is properly implemented

The feature is correctly implemented with both the filter and CSS styling:

  1. The delete-mask-handle.js filter adds the mask class to <del> tags when delete_mask is enabled
  2. The CSS implementation in markdown.styl provides the masking effect with proper transitions:
    • Hidden text with transparent color and black background when not hovered
    • Smooth transition for revealing content on hover
    • Proper handling of nested elements with opacity transitions
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for usage of 'delete_mask' to ensure it's properly implemented.

rg 'delete_mask' --glob '!_config.yml'

Length of output: 140


Script:

#!/bin/bash
# Check the implementation of delete-mask-handle.js
cat scripts/filters/delete-mask-handle.js

# Search for CSS related to del or mask classes
rg -g '*.css' -g '*.styl' -g '*.scss' -g '*.less' '\.mask|del'

Length of output: 130882


Script:

#!/bin/bash
# Check the content of markdown.styl for del.mask styling
cat source/css/common/markdown.styl

Length of output: 7138

@@ -0,0 +1 @@
*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.14 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}:root{--background:0 0% 100%;--foreground:240 10% 3.9%;--card:0 0% 100%;--card-foreground:240 10% 3.9%;--popover:0 0% 100%;--popover-foreground:240 10% 3.9%;--primary:240 5.9% 10%;--primary-foreground:0 0% 98%;--secondary:240 4.8% 95.9%;--secondary-foreground:240 5.9% 10%;--muted:240 4.8% 95.9%;--muted-foreground:240 3.8% 46.1%;--accent:240 4.8% 95.9%;--accent-foreground:240 5.9% 10%;--destructive:0 84.2% 60.2%;--destructive-foreground:0 0% 98%;--border:240 5.9% 90%;--input:240 5.9% 90%;--ring:240 10% 3.9%;--radius:0.5rem;--chart-1:12 76% 61%;--chart-2:173 58% 39%;--chart-3:197 37% 24%;--chart-4:43 74% 66%;--chart-5:27 87% 67%}.dark{--background:240 10% 3.9%;--foreground:0 0% 98%;--card:240 10% 3.9%;--card-foreground:0 0% 98%;--popover:240 10% 3.9%;--popover-foreground:0 0% 98%;--primary:0 0% 98%;--primary-foreground:240 5.9% 10%;--secondary:240 3.7% 15.9%;--secondary-foreground:0 0% 98%;--muted:240 3.7% 15.9%;--muted-foreground:240 5% 64.9%;--accent:240 3.7% 15.9%;--accent-foreground:0 0% 98%;--destructive:0 62.8% 30.6%;--destructive-foreground:0 0% 98%;--border:240 3.7% 15.9%;--input:240 3.7% 15.9%;--ring:240 4.9% 83.9%;--chart-1:220 70% 50%;--chart-2:160 60% 45%;--chart-3:30 80% 55%;--chart-4:280 65% 60%;--chart-5:340 75% 55%}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.visible{visibility:visible}.invisible{visibility:hidden}.collapse{visibility:collapse}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.bottom-0{bottom:0}.bottom-0\.5{bottom:.125rem}.left-0{left:0}.left-\[50\.5px\]{left:50.5px}.right-0{right:0}.right-\[12px\]{right:12px}.top-0{top:0}.top-3{top:.75rem}.top-\[12px\]{top:12px}.top-\[2px\]{top:2px}.z-1{z-index:1001}.z-2{z-index:1002}.z-3{z-index:1003}.z-\[1100\]{z-index:1100}.m-1{margin:.25rem}.m-14{margin:3.5rem}.m-16{margin:4rem}.m-3{margin:.75rem}.m-8{margin:2rem}.mx-0{margin-left:0;margin-right:0}.mx-0\.5{margin-left:.125rem;margin-right:.125rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.mx-6{margin-left:1.5rem;margin-right:1.5rem}.my-0\.5{margin-top:.125rem;margin-bottom:.125rem}.my-1{margin-top:.25rem;margin-bottom:.25rem}.my-1\.5{margin-top:.375rem;margin-bottom:.375rem}.my-2\.5{margin-top:.625rem;margin-bottom:.625rem}.my-6{margin-top:1.5rem;margin-bottom:1.5rem}.my-8{margin-top:2rem;margin-bottom:2rem}.mb-12{margin-bottom:3rem}.mb-14{margin-bottom:3.5rem}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.mb-6{margin-bottom:1.5rem}.mb-spacing-unit{margin-bottom:38px}.ml-1\.5{margin-left:.375rem}.ml-\[0\.2em\]{margin-left:.2em}.mr-0\.5{margin-right:.125rem}.mr-2{margin-right:.5rem}.mr-3{margin-right:.75rem}.mr-4{margin-right:1rem}.mr-\[3px\]{margin-right:3px}.mt-1{margin-top:.25rem}.mt-1\.5{margin-top:.375rem}.mt-10{margin-top:2.5rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.mt-8{margin-top:2rem}.box-border{box-sizing:border-box}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.table{display:table}.table-cell{display:table-cell}.grid{display:grid}.contents{display:contents}.hidden{display:none}.aspect-square{aspect-ratio:1/1}.size-1{width:.25rem}.h-1,.size-1{height:.25rem}.h-10{height:2.5rem}.h-12{height:3rem}.h-16{height:4rem}.h-2{height:.5rem}.h-2\.5{height:.625rem}.h-32{height:8rem}.h-4{height:1rem}.h-40{height:10rem}.h-6{height:1.5rem}.h-60{height:15rem}.h-8{height:2rem}.h-\[150px\]{height:150px}.h-\[46px\]{height:46px}.h-auto{height:auto}.h-dvh{height:100dvh}.h-fit{height:-moz-fit-content;height:fit-content}.h-full{height:100%}.h-screen{height:100vh}.min-h-dvh{min-height:100dvh}.w-1{width:.25rem}.w-10{width:2.5rem}.w-12{width:3rem}.w-16{width:4rem}.w-2{width:.5rem}.w-20{width:5rem}.w-6{width:1.5rem}.w-64{width:16rem}.w-8{width:2rem}.w-\[1px\]{width:1px}.w-\[46px\]{width:46px}.w-fit{width:-moz-fit-content;width:fit-content}.w-full{width:100%}.w-screen{width:100vw}.min-w-0{min-width:0}.\!max-w-none{max-width:none!important}.max-w-\[1340px\]{max-width:1340px}.max-w-full{max-width:100%}.max-w-none{max-width:none}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}.shrink{flex-shrink:1}.-translate-x-1{--tw-translate-x:-0.25rem}.-translate-x-1,.translate-y-0\.5{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-0\.5{--tw-translate-y:0.125rem}.-rotate-45{--tw-rotate:-45deg}.-rotate-45,.scale-100{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-100{--tw-scale-x:1;--tw-scale-y:1}.scale-125{--tw-scale-x:1.25;--tw-scale-y:1.25}.scale-125,.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.resize{resize:both}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-row{flex-direction:row}.flex-row-reverse{flex-direction:row-reverse}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-start{justify-content:flex-start}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.justify-around{justify-content:space-around}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-5{gap:1.25rem}.gap-6{gap:1.5rem}.space-x-0\.5>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.125rem*var(--tw-space-x-reverse));margin-left:calc(.125rem*(1 - var(--tw-space-x-reverse)))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.truncate{overflow:hidden;text-overflow:ellipsis}.truncate,.whitespace-nowrap{white-space:nowrap}.text-wrap{text-wrap:wrap}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-3xl{border-radius:1.5rem}.rounded-\[6\.2px\]{border-radius:6.2px}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-medium{border-radius:14px}.rounded-sm{border-radius:.125rem}.rounded-small{border-radius:9px}.rounded-xl{border-radius:.75rem}.rounded-l-lg{border-top-left-radius:.5rem;border-bottom-left-radius:.5rem}.rounded-t-large{border-top-left-radius:18px;border-top-right-radius:18px}.rounded-t-lg{border-top-left-radius:.5rem;border-top-right-radius:.5rem}.rounded-bl-lg{border-bottom-left-radius:.5rem}.rounded-tl-none{border-top-left-radius:0}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-l-2{border-left-width:2px}.border-t{border-top-width:1px}.border-t-2{border-top-width:2px}.border-solid{border-style:solid}.border-border-color{border-color:var(--border-color)}.border-shadow-color-1{border-color:var(--shadow-color-1)}.border-transparent{border-color:transparent}.border-white\/20{border-color:hsla(0,0%,100%,.2)}.border-t-border-color{border-top-color:var(--border-color)}.bg-background-color{background-color:var(--background-color)}.bg-background-color-transparent{background-color:var(--background-color-transparent)}.bg-background-color-transparent-15{background-color:var(--background-color-transparent-15)}.bg-background-color-transparent-40{background-color:var(--background-color-transparent-40)}.bg-gray-300\/50{background-color:rgba(209,213,219,.5)}.bg-second-background-color{background-color:var(--second-background-color)}.bg-third-background-color{background-color:var(--third-background-color)}.bg-third-text-color{background-color:var(--third-text-color)}.bg-zinc-50{--tw-bg-opacity:1;background-color:rgb(250 250 250/var(--tw-bg-opacity))}.bg-cover{background-size:cover}.object-cover{-o-object-fit:cover;object-fit:cover}.p-1{padding:.25rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-\[1px\]{padding:1px}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-7{padding-left:1.75rem;padding-right:1.75rem}.px-8{padding-left:2rem;padding-right:2rem}.px-\[10px\]{padding-left:10px;padding-right:10px}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.py-8{padding-top:2rem;padding-bottom:2rem}.py-\[2px\]{padding-top:2px;padding-bottom:2px}.pb-2{padding-bottom:.5rem}.pb-4{padding-bottom:1rem}.pb-7{padding-bottom:1.75rem}.pb-8{padding-bottom:2rem}.pl-0{padding-left:0}.pt-10{padding-top:2.5rem}.pt-5{padding-top:1.25rem}.pt-6{padding-top:1.5rem}.pt-7{padding-top:1.75rem}.text-center{text-align:center}.align-baseline{vertical-align:baseline}.align-text-top{vertical-align:text-top}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-\[0\.65rem\]{font-size:.65rem}.text-\[0\.7em\]{font-size:.7em}.text-\[0\.7rem\]{font-size:.7rem}.text-\[3\.2rem\]{font-size:3.2rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-light{font-weight:300}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.capitalize{text-transform:capitalize}.italic{font-style:italic}.ordinal{--tw-ordinal:ordinal;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.leading-\[1\.5\]{line-height:1.5}.leading-\[1\]{line-height:1}.tracking-tight{letter-spacing:-.025em}.text-background-color{color:var(--background-color)}.text-border-color{color:var(--border-color)}.text-default-text-color{color:var(--default-text-color)}.text-red-600{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity))}.text-second-text-color{color:var(--second-text-color)}.text-third-text-color{color:var(--third-text-color)}.underline{text-decoration-line:underline}.overline{text-decoration-line:overline}.line-through{text-decoration-line:line-through}.opacity-0{opacity:0}.shadow{--tw-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px -1px rgba(0,0,0,.1);--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color)}.shadow,.shadow-none{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-none{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000}.shadow-redefine-flat{--tw-shadow:0px 1px 4px 0px var(--shadow-color-2),0px 0px 0px 1px var(--shadow-color-1);--tw-shadow-colored:0px 1px 4px 0px var(--tw-shadow-color),0px 0px 0px 1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-shadow-color-2{--tw-shadow-color:var(--shadow-color-2);--tw-shadow:var(--tw-shadow-colored)}.blur{--tw-blur:blur(8px)}.blur,.drop-shadow{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.drop-shadow{--tw-drop-shadow:drop-shadow(0 1px 2px rgba(0,0,0,.1)) drop-shadow(0 1px 1px rgba(0,0,0,.06))}.invert{--tw-invert:invert(100%)}.filter,.invert{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-lg{--tw-backdrop-blur:blur(16px)}.backdrop-blur-lg,.backdrop-filter{-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-shadow{transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-100{transition-duration:.1s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.ease-linear{transition-timing-function:linear}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.will-change-transform{will-change:transform}.scrollbar-hide{-ms-overflow-style:none;scrollbar-width:none}.scrollbar-hide::-webkit-scrollbar{display:none}.last\:mb-0:last-child{margin-bottom:0}.hover\:-translate-y-1:hover{--tw-translate-y:-0.25rem}.hover\:-translate-y-1:hover,.hover\:transform:hover{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:border-primary:hover{border-color:var(--primary-color)}.hover\:border-second-background-color:hover{border-color:var(--second-background-color)}.hover\:bg-second-background-color:hover{background-color:var(--second-background-color)}.hover\:\!text-primary:hover{color:var(--primary-color)!important}.hover\:text-first-text-color:hover{color:var(--first-text-color)}.hover\:text-primary:hover{color:var(--primary-color)}.hover\:underline:hover{text-decoration-line:underline}.hover\:underline-offset-1:hover{text-underline-offset:1px}.hover\:shadow-none:hover{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000}.hover\:shadow-none:hover,.hover\:shadow-redefine-flat-hover:hover{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.hover\:shadow-redefine-flat-hover:hover{--tw-shadow:0px 1px 4px 0px var(--shadow-color-2),0px 0px 0px 1px var(--shadow-color-1),0px 0px 0px 1px inset var(--shadow-color-1);--tw-shadow-colored:0px 1px 4px 0px var(--tw-shadow-color),0px 0px 0px 1px var(--tw-shadow-color),inset 0px 0px 0px 1px var(--tw-shadow-color)}.hover\:shadow-shadow-color-2:hover{--tw-shadow-color:var(--shadow-color-2);--tw-shadow:var(--tw-shadow-colored)}.active\:scale-95:active{--tw-scale-x:.95;--tw-scale-y:.95;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.active\:\!text-primary:active{color:var(--primary-color)!important}.active\:underline:active{text-decoration-line:underline}.group:hover .group-hover\:visible{visibility:visible}.group:hover .group-hover\:translate-x-0{--tw-translate-x:0px}.group:hover .group-hover\:translate-x-0,.group:hover .group-hover\:translate-y-0{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:translate-y-0{--tw-translate-y:0px}.group:hover .group-hover\:translate-y-1{--tw-translate-y:0.25rem}.group:hover .group-hover\:scale-105,.group:hover .group-hover\:translate-y-1{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:scale-105{--tw-scale-x:1.05;--tw-scale-y:1.05}.group:hover .group-hover\:\!text-primary{color:var(--primary-color)!important}.group:hover .group-hover\:text-primary{color:var(--primary-color)}.group:hover .group-hover\:opacity-100{opacity:1}.dark\:block:is(.dark *){display:block}.dark\:hidden:is(.dark *){display:none}.dark\:border-gray-500\/30:is(.dark *){border-color:hsla(220,9%,46%,.3)}.dark\:bg-gray-500\/40:is(.dark *){background-color:hsla(220,9%,46%,.4)}.dark\:bg-zinc-800:is(.dark *){--tw-bg-opacity:1;background-color:rgb(39 39 42/var(--tw-bg-opacity))}.dark\:text-red-400:is(.dark *){--tw-text-opacity:1;color:rgb(248 113 113/var(--tw-text-opacity))}.dark\:brightness-75:is(.dark *){--tw-brightness:brightness(.75);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}@media (min-width:640px){.sm\:mx-6{margin-left:1.5rem;margin-right:1.5rem}.sm\:h-10{height:2.5rem}.sm\:h-72{height:18rem}.sm\:w-10{width:2.5rem}.sm\:scale-110{--tw-scale-x:1.1;--tw-scale-y:1.1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:gap-2{gap:.5rem}.sm\:rounded-t-large{border-top-left-radius:18px;border-top-right-radius:18px}.sm\:px-12{padding-left:3rem;padding-right:3rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:py-0{padding-top:0;padding-bottom:0}.sm\:py-6{padding-top:1.5rem;padding-bottom:1.5rem}.sm\:text-4xl{font-size:2.25rem;line-height:2.5rem}.sm\:text-xl{font-size:1.25rem;line-height:1.75rem}.sm\:shadow-redefine{--tw-shadow:0px 6px 24px 0px var(--shadow-color-2),0px 0px 0px 1px var(--shadow-color-1);--tw-shadow-colored:0px 6px 24px 0px var(--tw-shadow-color),0px 0px 0px 1px var(--tw-shadow-color)}.sm\:hover\:shadow-redefine-hover:hover,.sm\:shadow-redefine{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.sm\:hover\:shadow-redefine-hover:hover{--tw-shadow:0px 6px 24px 0px var(--shadow-color-2),0px 0px 0px 1px var(--shadow-color-1),0px 0px 0px 1px inset var(--shadow-color-1);--tw-shadow-colored:0px 6px 24px 0px var(--tw-shadow-color),0px 0px 0px 1px var(--tw-shadow-color),inset 0px 0px 0px 1px var(--tw-shadow-color)}}@media (min-width:768px){.md\:sticky{position:sticky}.md\:top-\[var\(--navbar-height\)\]{top:var(--navbar-height)}.md\:mx-8{margin-left:2rem;margin-right:2rem}.md\:my-2\.5{margin-top:.625rem;margin-bottom:.625rem}.md\:block{display:block}.md\:hidden{display:none}.md\:h-44{height:11rem}.md\:h-80{height:20rem}.md\:w-48{width:12rem}.md\:flex-row{flex-direction:row}.md\:gap-12{gap:3rem}.md\:whitespace-normal{white-space:normal}.md\:px-12{padding-left:3rem;padding-right:3rem}.md\:px-8{padding-left:2rem;padding-right:2rem}.md\:pb-0{padding-bottom:0}.md\:pl-8{padding-left:2rem}.md\:text-3xl{font-size:1.875rem;line-height:2.25rem}.md\:text-5xl{font-size:3rem;line-height:1}.md\:text-6xl{font-size:3.75rem;line-height:1}.md\:text-sm{font-size:.875rem;line-height:1.25rem}}@media (min-width:1024px){.lg\:absolute{position:absolute}.lg\:left-\[20px\]{left:20px}.lg\:right-\[20px\]{right:20px}.lg\:top-1\/2{top:50%}.lg\:\!block{display:block!important}.lg\:block{display:block}.lg\:-translate-y-1\/2{--tw-translate-y:-50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:text-left{text-align:left}.lg\:text-right{text-align:right}}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Remove duplicate font names to eliminate redundancy

The static analysis tool Biome has reported that there are duplicate font names 'Emoji' in the font-family property at line 1. This redundancy is unnecessary and could potentially cause confusion or unexpected behavior. Consider removing the duplicate font names to streamline the CSS.

Apply this diff to fix the issue:

- font-family: ui-sans-serif, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji, Noto Color Emoji;
+ font-family: ui-sans-serif, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;

Note: Ensure that this duplication is addressed in the Tailwind CSS configuration or source files before regenerating the build file to prevent the issue from recurring.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.14 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}:root{--background:0 0% 100%;--foreground:240 10% 3.9%;--card:0 0% 100%;--card-foreground:240 10% 3.9%;--popover:0 0% 100%;--popover-foreground:240 10% 3.9%;--primary:240 5.9% 10%;--primary-foreground:0 0% 98%;--secondary:240 4.8% 95.9%;--secondary-foreground:240 5.9% 10%;--muted:240 4.8% 95.9%;--muted-foreground:240 3.8% 46.1%;--accent:240 4.8% 95.9%;--accent-foreground:240 5.9% 10%;--destructive:0 84.2% 60.2%;--destructive-foreground:0 0% 98%;--border:240 5.9% 90%;--input:240 5.9% 90%;--ring:240 10% 3.9%;--radius:0.5rem;--chart-1:12 76% 61%;--chart-2:173 58% 39%;--chart-3:197 37% 24%;--chart-4:43 74% 66%;--chart-5:27 87% 67%}.dark{--background:240 10% 3.9%;--foreground:0 0% 98%;--card:240 10% 3.9%;--card-foreground:0 0% 98%;--popover:240 10% 3.9%;--popover-foreground:0 0% 98%;--primary:0 0% 98%;--primary-foreground:240 5.9% 10%;--secondary:240 3.7% 15.9%;--secondary-foreground:0 0% 98%;--muted:240 3.7% 15.9%;--muted-foreground:240 5% 64.9%;--accent:240 3.7% 15.9%;--accent-foreground:0 0% 98%;--destructive:0 62.8% 30.6%;--destructive-foreground:0 0% 98%;--border:240 3.7% 15.9%;--input:240 3.7% 15.9%;--ring:240 4.9% 83.9%;--chart-1:220 70% 50%;--chart-2:160 60% 45%;--chart-3:30 80% 55%;--chart-4:280 65% 60%;--chart-5:340 75% 55%}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.visible{visibility:visible}.invisible{visibility:hidden}.collapse{visibility:collapse}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.bottom-0{bottom:0}.bottom-0\.5{bottom:.125rem}.left-0{left:0}.left-\[50\.5px\]{left:50.5px}.right-0{right:0}.right-\[12px\]{right:12px}.top-0{top:0}.top-3{top:.75rem}.top-\[12px\]{top:12px}.top-\[2px\]{top:2px}.z-1{z-index:1001}.z-2{z-index:1002}.z-3{z-index:1003}.z-\[1100\]{z-index:1100}.m-1{margin:.25rem}.m-14{margin:3.5rem}.m-16{margin:4rem}.m-3{margin:.75rem}.m-8{margin:2rem}.mx-0{margin-left:0;margin-right:0}.mx-0\.5{margin-left:.125rem;margin-right:.125rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.mx-6{margin-left:1.5rem;margin-right:1.5rem}.my-0\.5{margin-top:.125rem;margin-bottom:.125rem}.my-1{margin-top:.25rem;margin-bottom:.25rem}.my-1\.5{margin-top:.375rem;margin-bottom:.375rem}.my-2\.5{margin-top:.625rem;margin-bottom:.625rem}.my-6{margin-top:1.5rem;margin-bottom:1.5rem}.my-8{margin-top:2rem;margin-bottom:2rem}.mb-12{margin-bottom:3rem}.mb-14{margin-bottom:3.5rem}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.mb-6{margin-bottom:1.5rem}.mb-spacing-unit{margin-bottom:38px}.ml-1\.5{margin-left:.375rem}.ml-\[0\.2em\]{margin-left:.2em}.mr-0\.5{margin-right:.125rem}.mr-2{margin-right:.5rem}.mr-3{margin-right:.75rem}.mr-4{margin-right:1rem}.mr-\[3px\]{margin-right:3px}.mt-1{margin-top:.25rem}.mt-1\.5{margin-top:.375rem}.mt-10{margin-top:2.5rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.mt-8{margin-top:2rem}.box-border{box-sizing:border-box}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.table{display:table}.table-cell{display:table-cell}.grid{display:grid}.contents{display:contents}.hidden{display:none}.aspect-square{aspect-ratio:1/1}.size-1{width:.25rem}.h-1,.size-1{height:.25rem}.h-10{height:2.5rem}.h-12{height:3rem}.h-16{height:4rem}.h-2{height:.5rem}.h-2\.5{height:.625rem}.h-32{height:8rem}.h-4{height:1rem}.h-40{height:10rem}.h-6{height:1.5rem}.h-60{height:15rem}.h-8{height:2rem}.h-\[150px\]{height:150px}.h-\[46px\]{height:46px}.h-auto{height:auto}.h-dvh{height:100dvh}.h-fit{height:-moz-fit-content;height:fit-content}.h-full{height:100%}.h-screen{height:100vh}.min-h-dvh{min-height:100dvh}.w-1{width:.25rem}.w-10{width:2.5rem}.w-12{width:3rem}.w-16{width:4rem}.w-2{width:.5rem}.w-20{width:5rem}.w-6{width:1.5rem}.w-64{width:16rem}.w-8{width:2rem}.w-\[1px\]{width:1px}.w-\[46px\]{width:46px}.w-fit{width:-moz-fit-content;width:fit-content}.w-full{width:100%}.w-screen{width:100vw}.min-w-0{min-width:0}.\!max-w-none{max-width:none!important}.max-w-\[1340px\]{max-width:1340px}.max-w-full{max-width:100%}.max-w-none{max-width:none}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}.shrink{flex-shrink:1}.-translate-x-1{--tw-translate-x:-0.25rem}.-translate-x-1,.translate-y-0\.5{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-0\.5{--tw-translate-y:0.125rem}.-rotate-45{--tw-rotate:-45deg}.-rotate-45,.scale-100{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-100{--tw-scale-x:1;--tw-scale-y:1}.scale-125{--tw-scale-x:1.25;--tw-scale-y:1.25}.scale-125,.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.resize{resize:both}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-row{flex-direction:row}.flex-row-reverse{flex-direction:row-reverse}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-start{justify-content:flex-start}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.justify-around{justify-content:space-around}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-5{gap:1.25rem}.gap-6{gap:1.5rem}.space-x-0\.5>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.125rem*var(--tw-space-x-reverse));margin-left:calc(.125rem*(1 - var(--tw-space-x-reverse)))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.truncate{overflow:hidden;text-overflow:ellipsis}.truncate,.whitespace-nowrap{white-space:nowrap}.text-wrap{text-wrap:wrap}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-3xl{border-radius:1.5rem}.rounded-\[6\.2px\]{border-radius:6.2px}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-medium{border-radius:14px}.rounded-sm{border-radius:.125rem}.rounded-small{border-radius:9px}.rounded-xl{border-radius:.75rem}.rounded-l-lg{border-top-left-radius:.5rem;border-bottom-left-radius:.5rem}.rounded-t-large{border-top-left-radius:18px;border-top-right-radius:18px}.rounded-t-lg{border-top-left-radius:.5rem;border-top-right-radius:.5rem}.rounded-bl-lg{border-bottom-left-radius:.5rem}.rounded-tl-none{border-top-left-radius:0}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-l-2{border-left-width:2px}.border-t{border-top-width:1px}.border-t-2{border-top-width:2px}.border-solid{border-style:solid}.border-border-color{border-color:var(--border-color)}.border-shadow-color-1{border-color:var(--shadow-color-1)}.border-transparent{border-color:transparent}.border-white\/20{border-color:hsla(0,0%,100%,.2)}.border-t-border-color{border-top-color:var(--border-color)}.bg-background-color{background-color:var(--background-color)}.bg-background-color-transparent{background-color:var(--background-color-transparent)}.bg-background-color-transparent-15{background-color:var(--background-color-transparent-15)}.bg-background-color-transparent-40{background-color:var(--background-color-transparent-40)}.bg-gray-300\/50{background-color:rgba(209,213,219,.5)}.bg-second-background-color{background-color:var(--second-background-color)}.bg-third-background-color{background-color:var(--third-background-color)}.bg-third-text-color{background-color:var(--third-text-color)}.bg-zinc-50{--tw-bg-opacity:1;background-color:rgb(250 250 250/var(--tw-bg-opacity))}.bg-cover{background-size:cover}.object-cover{-o-object-fit:cover;object-fit:cover}.p-1{padding:.25rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-\[1px\]{padding:1px}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-7{padding-left:1.75rem;padding-right:1.75rem}.px-8{padding-left:2rem;padding-right:2rem}.px-\[10px\]{padding-left:10px;padding-right:10px}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.py-8{padding-top:2rem;padding-bottom:2rem}.py-\[2px\]{padding-top:2px;padding-bottom:2px}.pb-2{padding-bottom:.5rem}.pb-4{padding-bottom:1rem}.pb-7{padding-bottom:1.75rem}.pb-8{padding-bottom:2rem}.pl-0{padding-left:0}.pt-10{padding-top:2.5rem}.pt-5{padding-top:1.25rem}.pt-6{padding-top:1.5rem}.pt-7{padding-top:1.75rem}.text-center{text-align:center}.align-baseline{vertical-align:baseline}.align-text-top{vertical-align:text-top}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-\[0\.65rem\]{font-size:.65rem}.text-\[0\.7em\]{font-size:.7em}.text-\[0\.7rem\]{font-size:.7rem}.text-\[3\.2rem\]{font-size:3.2rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-light{font-weight:300}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.capitalize{text-transform:capitalize}.italic{font-style:italic}.ordinal{--tw-ordinal:ordinal;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.leading-\[1\.5\]{line-height:1.5}.leading-\[1\]{line-height:1}.tracking-tight{letter-spacing:-.025em}.text-background-color{color:var(--background-color)}.text-border-color{color:var(--border-color)}.text-default-text-color{color:var(--default-text-color)}.text-red-600{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity))}.text-second-text-color{color:var(--second-text-color)}.text-third-text-color{color:var(--third-text-color)}.underline{text-decoration-line:underline}.overline{text-decoration-line:overline}.line-through{text-decoration-line:line-through}.opacity-0{opacity:0}.shadow{--tw-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px -1px rgba(0,0,0,.1);--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color)}.shadow,.shadow-none{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-none{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000}.shadow-redefine-flat{--tw-shadow:0px 1px 4px 0px var(--shadow-color-2),0px 0px 0px 1px var(--shadow-color-1);--tw-shadow-colored:0px 1px 4px 0px var(--tw-shadow-color),0px 0px 0px 1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-shadow-color-2{--tw-shadow-color:var(--shadow-color-2);--tw-shadow:var(--tw-shadow-colored)}.blur{--tw-blur:blur(8px)}.blur,.drop-shadow{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.drop-shadow{--tw-drop-shadow:drop-shadow(0 1px 2px rgba(0,0,0,.1)) drop-shadow(0 1px 1px rgba(0,0,0,.06))}.invert{--tw-invert:invert(100%)}.filter,.invert{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-lg{--tw-backdrop-blur:blur(16px)}.backdrop-blur-lg,.backdrop-filter{-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-shadow{transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-100{transition-duration:.1s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.ease-linear{transition-timing-function:linear}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.will-change-transform{will-change:transform}.scrollbar-hide{-ms-overflow-style:none;scrollbar-width:none}.scrollbar-hide::-webkit-scrollbar{display:none}.last\:mb-0:last-child{margin-bottom:0}.hover\:-translate-y-1:hover{--tw-translate-y:-0.25rem}.hover\:-translate-y-1:hover,.hover\:transform:hover{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:border-primary:hover{border-color:var(--primary-color)}.hover\:border-second-background-color:hover{border-color:var(--second-background-color)}.hover\:bg-second-background-color:hover{background-color:var(--second-background-color)}.hover\:\!text-primary:hover{color:var(--primary-color)!important}.hover\:text-first-text-color:hover{color:var(--first-text-color)}.hover\:text-primary:hover{color:var(--primary-color)}.hover\:underline:hover{text-decoration-line:underline}.hover\:underline-offset-1:hover{text-underline-offset:1px}.hover\:shadow-none:hover{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000}.hover\:shadow-none:hover,.hover\:shadow-redefine-flat-hover:hover{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.hover\:shadow-redefine-flat-hover:hover{--tw-shadow:0px 1px 4px 0px var(--shadow-color-2),0px 0px 0px 1px var(--shadow-color-1),0px 0px 0px 1px inset var(--shadow-color-1);--tw-shadow-colored:0px 1px 4px 0px var(--tw-shadow-color),0px 0px 0px 1px var(--tw-shadow-color),inset 0px 0px 0px 1px var(--tw-shadow-color)}.hover\:shadow-shadow-color-2:hover{--tw-shadow-color:var(--shadow-color-2);--tw-shadow:var(--tw-shadow-colored)}.active\:scale-95:active{--tw-scale-x:.95;--tw-scale-y:.95;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.active\:\!text-primary:active{color:var(--primary-color)!important}.active\:underline:active{text-decoration-line:underline}.group:hover .group-hover\:visible{visibility:visible}.group:hover .group-hover\:translate-x-0{--tw-translate-x:0px}.group:hover .group-hover\:translate-x-0,.group:hover .group-hover\:translate-y-0{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:translate-y-0{--tw-translate-y:0px}.group:hover .group-hover\:translate-y-1{--tw-translate-y:0.25rem}.group:hover .group-hover\:scale-105,.group:hover .group-hover\:translate-y-1{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:scale-105{--tw-scale-x:1.05;--tw-scale-y:1.05}.group:hover .group-hover\:\!text-primary{color:var(--primary-color)!important}.group:hover .group-hover\:text-primary{color:var(--primary-color)}.group:hover .group-hover\:opacity-100{opacity:1}.dark\:block:is(.dark *){display:block}.dark\:hidden:is(.dark *){display:none}.dark\:border-gray-500\/30:is(.dark *){border-color:hsla(220,9%,46%,.3)}.dark\:bg-gray-500\/40:is(.dark *){background-color:hsla(220,9%,46%,.4)}.dark\:bg-zinc-800:is(.dark *){--tw-bg-opacity:1;background-color:rgb(39 39 42/var(--tw-bg-opacity))}.dark\:text-red-400:is(.dark *){--tw-text-opacity:1;color:rgb(248 113 113/var(--tw-text-opacity))}.dark\:brightness-75:is(.dark *){--tw-brightness:brightness(.75);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}@media (min-width:640px){.sm\:mx-6{margin-left:1.5rem;margin-right:1.5rem}.sm\:h-10{height:2.5rem}.sm\:h-72{height:18rem}.sm\:w-10{width:2.5rem}.sm\:scale-110{--tw-scale-x:1.1;--tw-scale-y:1.1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:gap-2{gap:.5rem}.sm\:rounded-t-large{border-top-left-radius:18px;border-top-right-radius:18px}.sm\:px-12{padding-left:3rem;padding-right:3rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:py-0{padding-top:0;padding-bottom:0}.sm\:py-6{padding-top:1.5rem;padding-bottom:1.5rem}.sm\:text-4xl{font-size:2.25rem;line-height:2.5rem}.sm\:text-xl{font-size:1.25rem;line-height:1.75rem}.sm\:shadow-redefine{--tw-shadow:0px 6px 24px 0px var(--shadow-color-2),0px 0px 0px 1px var(--shadow-color-1);--tw-shadow-colored:0px 6px 24px 0px var(--tw-shadow-color),0px 0px 0px 1px var(--tw-shadow-color)}.sm\:hover\:shadow-redefine-hover:hover,.sm\:shadow-redefine{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.sm\:hover\:shadow-redefine-hover:hover{--tw-shadow:0px 6px 24px 0px var(--shadow-color-2),0px 0px 0px 1px var(--shadow-color-1),0px 0px 0px 1px inset var(--shadow-color-1);--tw-shadow-colored:0px 6px 24px 0px var(--tw-shadow-color),0px 0px 0px 1px var(--tw-shadow-color),inset 0px 0px 0px 1px var(--tw-shadow-color)}}@media (min-width:768px){.md\:sticky{position:sticky}.md\:top-\[var\(--navbar-height\)\]{top:var(--navbar-height)}.md\:mx-8{margin-left:2rem;margin-right:2rem}.md\:my-2\.5{margin-top:.625rem;margin-bottom:.625rem}.md\:block{display:block}.md\:hidden{display:none}.md\:h-44{height:11rem}.md\:h-80{height:20rem}.md\:w-48{width:12rem}.md\:flex-row{flex-direction:row}.md\:gap-12{gap:3rem}.md\:whitespace-normal{white-space:normal}.md\:px-12{padding-left:3rem;padding-right:3rem}.md\:px-8{padding-left:2rem;padding-right:2rem}.md\:pb-0{padding-bottom:0}.md\:pl-8{padding-left:2rem}.md\:text-3xl{font-size:1.875rem;line-height:2.25rem}.md\:text-5xl{font-size:3rem;line-height:1}.md\:text-6xl{font-size:3.75rem;line-height:1}.md\:text-sm{font-size:.875rem;line-height:1.25rem}}@media (min-width:1024px){.lg\:absolute{position:absolute}.lg\:left-\[20px\]{left:20px}.lg\:right-\[20px\]{right:20px}.lg\:top-1\/2{top:50%}.lg\:\!block{display:block!important}.lg\:block{display:block}.lg\:-translate-y-1\/2{--tw-translate-y:-50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:text-left{text-align:left}.lg\:text-right{text-align:right}}
*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.14 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}
🧰 Tools
🪛 Biome (1.9.4)

[error] 1-1: Duplicate font names are redundant and unnecessary: Emoji

Remove duplicate font names within the property

(lint/suspicious/noDuplicateFontNames)

Copy link

github-actions bot commented Dec 1, 2024

This pull request has been deployed to Vercel.

Latest commit: cd84a2b
✅ Preview: https://redefine-preview-pr-472.vercel.app
🔍 Inspect: https://vercel.com/evanovation/hexo-theme-redefine/6H9gfSeVUBFJuzFrHuYbJyq5v35U

View Workflow Logs

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (3)
.github/workflows/preview-deployment.yml (3)

21-21: Consider simplifying the environment name selection logic

The nested ternary operators make the condition hard to read. Consider refactoring to a more readable format using GitHub Actions' expression syntax.

-      name: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.user.login == 'EvanNotFound' && 'PR Preview Bypass' || github.event_name == 'pull_request_target' && 'PR Preview' || 'Preview' }}
+      name: ${{
+        (github.event_name == 'pull_request_target' && github.event.pull_request.user.login == 'EvanNotFound') && 'PR Preview Bypass' ||
+        (github.event_name == 'pull_request_target') && 'PR Preview' ||
+        'Preview'
+      }}

126-134: Fix formatting in debug step

While the debug logging is helpful for troubleshooting environment selection, there are some formatting issues to address:

  • Remove trailing spaces on line 130
  • Add a newline at the end of the file
      - name: Debug environment selection
        run: |
          echo "Event name: ${{ github.event_name }}"
          echo "PR author: ${{ github.event.pull_request.user.login }}"
-          echo "Selected environment: ${{ 
-            github.event_name == 'pull_request_target' && github.event.pull_request.user.login == 'EvanNotFound' && 'PR Preview Bypass' ||
-            github.event_name == 'pull_request_target' && 'PR Preview' ||
-            'Preview'
-          }}"
+          echo "Selected environment: ${{
+            github.event_name == 'pull_request_target' && github.event.pull_request.user.login == 'EvanNotFound' && 'PR Preview Bypass' ||
+            github.event_name == 'pull_request_target' && 'PR Preview' ||
+            'Preview'
+          }}"
+
🧰 Tools
🪛 yamllint (1.35.1)

[error] 130-130: trailing spaces

(trailing-spaces)


[error] 134-134: no new line character at the end of file

(new-line-at-end-of-file)


Security concerns identified with pull_request_target usage

The workflow has several security issues that need to be addressed:

  1. The workflow checks out and executes code from fork PRs without proper security controls:

    • Uses actions/checkout@v4 with dynamic repository and ref from PR
    • Runs npm install and npm run build on untrusted code
    • Executes Python script with untrusted YAML processing
  2. Special access bypass for 'EvanNotFound' through environment conditions creates potential security risks:

    • Different environment ('PR Preview Bypass') is used for specific user
    • No additional security validations before granting elevated access
  3. Sensitive tokens (VERCEL_TOKEN, GITHUB_TOKEN) are exposed to potentially untrusted code execution:

    • No explicit permissions limiting
    • Tokens available during untrusted code execution steps

Recommendations:

  • Move build and verification steps to a separate workflow triggered by pull_request
  • Use pull_request_target only for deployment after verification
  • Add explicit permissions field to limit token scope
  • Implement proper code validation before execution
🔗 Analysis chain

Line range hint 11-13: Verify security implications of pull_request_target

The workflow uses pull_request_target and provides special access to PRs from 'EvanNotFound'. While this is intentional, please ensure:

  1. The special access is strictly necessary
  2. The workflow doesn't execute untrusted code from forks before validation

Also applies to: 21-21

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for other workflows that might be triggered by pull_request_target
fd -e yml -e yaml . .github/workflows/ --exec grep -l "pull_request_target" {}

Length of output: 121


Script:

#!/bin/bash
# Check the content of the workflow file to analyze security measures
cat .github/workflows/preview-deployment.yml

Length of output: 4733


Script:

#!/bin/bash
# Check for any code execution steps in the workflow
rg -A 5 "run:|uses:" .github/workflows/preview-deployment.yml

Length of output: 2474


Script:

#!/bin/bash
# Check for environment access or token permissions
rg -i "permissions:|environment:|token" .github/workflows/preview-deployment.yml

Length of output: 246

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between e831035 and cd84a2b.

📒 Files selected for processing (1)
  • .github/workflows/preview-deployment.yml (2 hunks)
🧰 Additional context used
🪛 yamllint (1.35.1)
.github/workflows/preview-deployment.yml

[error] 130-130: trailing spaces

(trailing-spaces)


[error] 134-134: no new line character at the end of file

(new-line-at-end-of-file)

🔇 Additional comments (1)
.github/workflows/preview-deployment.yml (1)

124-125: LGTM: PR preview domain configuration

The PR preview domain configuration follows Vercel's naming conventions and correctly uses the {PR} placeholder for dynamic PR numbers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BUG] aplayer开启后没有在页面显示
3 participants