Skip to content

Website: Update style mixins and variables - #43801

Merged
eashaw merged 16 commits into
mainfrom
website-add-spacing.less
Apr 20, 2026
Merged

Website: Update style mixins and variables#43801
eashaw merged 16 commits into
mainfrom
website-add-spacing.less

Conversation

@eashaw

@eashaw eashaw commented Apr 20, 2026

Copy link
Copy Markdown
Contributor

Changes:

  • Created spacing.less, a file that contains the common padding/margin/gap values used on the website
  • Updated containers.less to contain mixins for page containers
  • Added feature-blocks.less, a file that contains three mixins: .feature-with-image(), .three-column-features(), and .responsive-feature-row()
  • Added mixins for common text styles to typography.less
  • Updated pages to use the new mixins

Summary by CodeRabbit

  • New Features

    • Centralized spacing and typography system for consistent, responsive layouts
    • Reusable feature-block patterns for image/text rows and multi-column feature grids
  • Style

    • Standardized page containers and content areas with responsive padding and max-widths
    • Unified heading/body styles via new typography utilities
    • Simplified markup and improved feature image/text alignment and responsiveness

Copilot AI review requested due to automatic review settings April 20, 2026 18:59
@fleet-release fleet-release added the ~ga4-annotation This label is automatically applied to certain website changes label Apr 20, 2026

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

fleet-release
fleet-release previously approved these changes Apr 20, 2026
@coderabbitai

coderabbitai Bot commented Apr 20, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c5cac608-7b4c-493c-9634-6f0454e6db4f

📥 Commits

Reviewing files that changed from the base of the PR and between 9e27f2a and 617cf11.

📒 Files selected for processing (1)
  • website/assets/styles/pages/software-management.less

Walkthrough

Added new LESS modules and variables for spacing and typography, plus three mixin files defining container/content and feature-block layouts. Updated the mixins index to import these files. Replaced many hard-coded typography and spacing rules in page styles with the new mixins/variables. Introduced feature layout mixins and refactored multiple page styles to use them. Updated EJS templates to simplify markup by removing Bootstrap utility classes and switching to semantic purpose-based containers that rely on the new LESS mixins. No existing mixins were modified; only new declarations and refactors were appended.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description clearly outlines the changes made (spacing.less, containers.less updates, feature-blocks.less, typography.less mixins, and page updates) but does not follow the repository's required template structure. Follow the template by including sections like 'Related issue', 'Checklist for submitter', 'Testing', and other applicable sections. Fill in relevant checkboxes or provide explanations for why sections don't apply.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding and updating style mixins and variables for the website.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch website-add-spacing.less

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
website/assets/styles/pages/device-management.less (1)

765-821: ⚠️ Potential issue | 🟡 Minor

Duplicate [purpose='feature-with-image'] block inside the same @media (max-width: 767px) — dead declaration.

Both lines 765-770 and lines 812-821 open [purpose='feature-with-image'] inside the same media query. The [purpose='feature-image'] { margin-bottom: 64px; } at line 768 is overridden by margin-bottom: 60px; at line 819 because of source order, so the 64px value never takes effect. Merge the two blocks and pick a single intended value.

♻️ Proposed consolidation
     [purpose='feature-with-image'] {
       margin-bottom: 80px;
+      [purpose='feature-text'] {
+        width: 100%;
+        margin-left: auto;
+        margin-right: auto;
+      }
       [purpose='feature-image'] {
-        margin-bottom: 64px;
+        margin-bottom: 60px; // or 64px — confirm intended value
       }
     }

and remove the second block at lines 812-821.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/assets/styles/pages/device-management.less` around lines 765 - 821,
There are duplicate [purpose='feature-with-image'] blocks in the same media
scope causing the [purpose='feature-image'] margin-bottom:64px to be overridden
by a later margin-bottom:60px; merge the two [purpose='feature-with-image']
blocks into one, consolidate the nested rules ([purpose='feature-image'] and
[purpose='feature-text']) and choose the single intended margin-bottom value for
[purpose='feature-image'] (remove the other), ensuring only one combined
definition of [purpose='feature-with-image'] remains.
🧹 Nitpick comments (5)
website/assets/styles/mixins-and-variables/typography.less (1)

30-38: Use the new @kicker-font variable instead of the hardcoded font-family.

You added @kicker-font: 'Roboto Mono'; on line 5 specifically for kicker-style titles, but .kicker-title() still hardcodes the family string. Referencing the variable keeps the single source of truth you introduced in this PR.

♻️ Proposed diff
 .kicker-title() {
-  font-family: 'Roboto Mono';
+  font-family: `@kicker-font`;
   font-weight: 400;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/assets/styles/mixins-and-variables/typography.less` around lines 30 -
38, The .kicker-title() mixin is still hardcoding the font-family string; update
it to use the new `@kicker-font` variable instead of 'Roboto Mono'. Locate the
.kicker-title() mixin in typography.less and replace the font-family value with
`@kicker-font` so the mixin reads font-family: `@kicker-font`; ensuring the new
single source of truth is used.
website/assets/styles/pages/docs/mdm-commands.less (1)

362-374: Redundant media query block.

The @media(max-width: 767px) and @media(max-width: 576px) rules now apply the identical value @page-padding-tablet-mobile to [purpose='page-container']. The 576px block is dead weight since the 767px rule already covers that viewport. Consider removing the 576px block (or differentiating it if a distinct mobile padding is actually desired).

♻️ Proposed diff
   `@media`(max-width: 767px) {
     [purpose='page-container'] {
       padding: `@page-padding-tablet-mobile`;
     }
-
-  }
-
-  `@media`(max-width: 576px) {
-    [purpose='page-container'] {
-      padding: `@page-padding-tablet-mobile`;
-    }
-
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/assets/styles/pages/docs/mdm-commands.less` around lines 362 - 374,
The two media queries set the same padding for [purpose='page-container'] so
remove the redundant `@media`(max-width: 576px) block (or, if you intended a
different mobile padding, change the value in the 576px block to a distinct
variable such as `@page-padding-mobile`) and keep only `@media`(max-width: 767px) {
[purpose='page-container'] { padding: `@page-padding-tablet-mobile`; } } to
eliminate dead weight while preserving the `@page-padding-tablet-mobile` variable
usage.
website/assets/styles/pages/docs/script-library.less (1)

344-354: Remove or differentiate the duplicate mobile padding rule.

Line 346 and Line 353 set the same @page-padding-tablet-mobile value, and the max-width: 576px block has no other rules. If no narrower phone-specific token is intended, the second block can be removed.

♻️ Proposed cleanup
   `@media`(max-width: 767px) {
     [purpose='page-container'] {
       padding: `@page-padding-tablet-mobile`;
     }
 
   }
-
-  `@media`(max-width: 576px) {
-    [purpose='page-container'] {
-      padding: `@page-padding-tablet-mobile`;
-    }
-
-  }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/assets/styles/pages/docs/script-library.less` around lines 344 - 354,
There are two identical mobile media-query rules setting
[purpose='page-container'] padding to `@page-padding-tablet-mobile` for max-width:
767px and max-width: 576px; remove the redundant `@media`(max-width: 576px) block
(or if a distinct narrower-phone token is intended, change its padding to
`@page-padding-mobile` or the appropriate token) so only one mobile-specific rule
remains; target the duplicate block containing the selector
[purpose='page-container'] and the `@page-padding-tablet-mobile` assignment and
either delete it or replace the padding token accordingly.
website/assets/styles/mixins-and-variables/containers.less (1)

81-86: Optional: add .page-content-admin() for completeness.

spacing.less defines @content-max-width-admin: 800px specifically for admin pages (e.g., admin/query-generator), but no matching mixin is declared here. If admin pages are meant to consume this token via mixin (mirroring .page-content-docs(), .page-content(), .page-content-narrow()), consider adding one to keep the set symmetric.

♻️ Proposed addition
 // Narrow form/error pages
 .page-content-narrow() {
   max-width: `@content-max-width-narrow`;
   margin-left: auto;
   margin-right: auto;
 }
+
+// Admin pages: admin/query-generator
+.page-content-admin() {
+  max-width: `@content-max-width-admin`;
+  margin-left: auto;
+  margin-right: auto;
+}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/assets/styles/mixins-and-variables/containers.less` around lines 81 -
86, Add a new Less mixin named .page-content-admin() that mirrors the existing
.page-content(), .page-content-docs(), and .page-content-narrow() mixins by
setting max-width to `@content-max-width-admin` and centering the block with
margin-left: auto and margin-right: auto; place it alongside the other
page-content mixins in containers.less so admin pages can consume the
`@content-max-width-admin` token consistently.
website/assets/styles/pages/software-management.less (1)

127-179: Duplicate [purpose='feature-slide'] rulesets — consolidate.

Lines 127-145 and 167-179 both open [purpose='feature-slide'] in the same scope. They merge at compile time, but this split hides the full rule from readers and redeclares [purpose='feature-text'] { width: 50%; } in both blocks. Merge them into a single declaration for clarity and to avoid future drift.

♻️ Proposed consolidation
   [purpose='feature-slide'] {
+    padding-top: 64px;
+    padding-bottom: 32px;
+    &.invisible {
+      height: 0;
+      padding: 0;
+    }
     [purpose='feature-image'] {
       width: 50%;
       img {
         max-width: 100%;
         max-height: 100%;
       }
     }
     [purpose='feature-text'] {
       width: 50%;
+      padding-left: 48px;
+      margin-left: 16px;
       h3 {
         color: `@core-fleet-black`;
         font-size: 24px;
         font-weight: 800;
         line-height: `@heading-lineheight`; /* 120% */
         margin-bottom: 32px;
       }
     }
   }
-  [purpose='feature-slide'] {
-    padding-top: 64px;
-    padding-bottom: 32px;
-    &.invisible {
-      height: 0;
-      padding: 0;
-    }
-    [purpose='feature-text'] {
-      padding-left: 48px;
-      margin-left: 16px;
-      width: 50%;
-    }
-  }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/assets/styles/pages/software-management.less` around lines 127 - 179,
There are two duplicated [purpose='feature-slide'] blocks; merge them into one
so all rules for [purpose='feature-slide'] (including padding-top: 64px,
padding-bottom: 32px, .invisible { height: 0; padding: 0 }, and the nested
[purpose='feature-image'] and [purpose='feature-text'] rules) live in a single
declaration, remove the redundant [purpose='feature-text'] { width: 50% }
duplicate, and preserve the existing nested rules like
[purpose='feature-image'], [purpose='feature-text'] h3, and the .invisible
modifier so behavior and styling remain identical.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@website/assets/styles/mixins-and-variables/feature-blocks.less`:
- Around line 6-8: The inline comment in feature-blocks.less incorrectly
documents the collapse breakpoint as "below 992px" while the mixin actually
switches to a column layout at max-width: 768px; update the comment text in the
block starting with "// Side-by-side: an image paired with a text block..." to
state the correct collapse point (e.g., "Collapses to a single column at
max-width: 768px" or "below 768px") so the documentation matches the implemented
breakpoint.

In `@website/views/pages/device-management.ejs`:
- Around line 74-104: The feature card headings were changed from h4 to h5 and
no longer match the stylesheet selector [purpose='three-column-features']
[purpose='feature'] h4; revert the headings in device-management.ejs from h5
back to h4 (the headings inside each <div purpose="feature">) so the existing
styles apply, or alternatively update the stylesheet selector to target h5
instead of h4 (selector: [purpose='three-column-features'] [purpose='feature']
h4) — pick one approach and make the corresponding change for all feature cards.

In `@website/views/pages/homepage.ejs`:
- Around line 1450-1454: Add rel="noopener noreferrer" to the external anchor
that opens in a new tab: locate the <a> element with target="_blank" pointing to
"https://github.com/fleetdm/fleet/graphs/contributors" in the homepage view and
update that anchor to include rel="noopener noreferrer" to prevent window.opener
leakage in older browsers.

In `@website/views/pages/observability.ejs`:
- Around line 78-114: The alt text for two <img> elements is mismatched: the
image before the <h5>Live connection</h5> currently has alt="Software and asset
inventory" and the image before the <h5>EDR health checks</h5> currently has
alt="Verify updates and settings"; update those alt attributes to match their
adjacent headings (e.g., alt="Live connection" and alt="EDR health checks") or
set them to an empty string (alt="") if the icons are purely decorative, keeping
the other <img> alt texts unchanged.

---

Outside diff comments:
In `@website/assets/styles/pages/device-management.less`:
- Around line 765-821: There are duplicate [purpose='feature-with-image'] blocks
in the same media scope causing the [purpose='feature-image'] margin-bottom:64px
to be overridden by a later margin-bottom:60px; merge the two
[purpose='feature-with-image'] blocks into one, consolidate the nested rules
([purpose='feature-image'] and [purpose='feature-text']) and choose the single
intended margin-bottom value for [purpose='feature-image'] (remove the other),
ensuring only one combined definition of [purpose='feature-with-image'] remains.

---

Nitpick comments:
In `@website/assets/styles/mixins-and-variables/containers.less`:
- Around line 81-86: Add a new Less mixin named .page-content-admin() that
mirrors the existing .page-content(), .page-content-docs(), and
.page-content-narrow() mixins by setting max-width to `@content-max-width-admin`
and centering the block with margin-left: auto and margin-right: auto; place it
alongside the other page-content mixins in containers.less so admin pages can
consume the `@content-max-width-admin` token consistently.

In `@website/assets/styles/mixins-and-variables/typography.less`:
- Around line 30-38: The .kicker-title() mixin is still hardcoding the
font-family string; update it to use the new `@kicker-font` variable instead of
'Roboto Mono'. Locate the .kicker-title() mixin in typography.less and replace
the font-family value with `@kicker-font` so the mixin reads font-family:
`@kicker-font`; ensuring the new single source of truth is used.

In `@website/assets/styles/pages/docs/mdm-commands.less`:
- Around line 362-374: The two media queries set the same padding for
[purpose='page-container'] so remove the redundant `@media`(max-width: 576px)
block (or, if you intended a different mobile padding, change the value in the
576px block to a distinct variable such as `@page-padding-mobile`) and keep only
`@media`(max-width: 767px) { [purpose='page-container'] { padding:
`@page-padding-tablet-mobile`; } } to eliminate dead weight while preserving the
`@page-padding-tablet-mobile` variable usage.

In `@website/assets/styles/pages/docs/script-library.less`:
- Around line 344-354: There are two identical mobile media-query rules setting
[purpose='page-container'] padding to `@page-padding-tablet-mobile` for max-width:
767px and max-width: 576px; remove the redundant `@media`(max-width: 576px) block
(or if a distinct narrower-phone token is intended, change its padding to
`@page-padding-mobile` or the appropriate token) so only one mobile-specific rule
remains; target the duplicate block containing the selector
[purpose='page-container'] and the `@page-padding-tablet-mobile` assignment and
either delete it or replace the padding token accordingly.

In `@website/assets/styles/pages/software-management.less`:
- Around line 127-179: There are two duplicated [purpose='feature-slide']
blocks; merge them into one so all rules for [purpose='feature-slide']
(including padding-top: 64px, padding-bottom: 32px, .invisible { height: 0;
padding: 0 }, and the nested [purpose='feature-image'] and
[purpose='feature-text'] rules) live in a single declaration, remove the
redundant [purpose='feature-text'] { width: 50% } duplicate, and preserve the
existing nested rules like [purpose='feature-image'], [purpose='feature-text']
h3, and the .invisible modifier so behavior and styling remain identical.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d7a0cb11-5dc6-4e83-b986-4f2388529ce9

📥 Commits

Reviewing files that changed from the base of the PR and between db3b2d3 and 9e27f2a.

📒 Files selected for processing (37)
  • website/assets/styles/mixins-and-variables/containers.less
  • website/assets/styles/mixins-and-variables/feature-blocks.less
  • website/assets/styles/mixins-and-variables/index.less
  • website/assets/styles/mixins-and-variables/spacing.less
  • website/assets/styles/mixins-and-variables/typography.less
  • website/assets/styles/pages/articles/basic-whitepaper.less
  • website/assets/styles/pages/configuration-builder.less
  • website/assets/styles/pages/customers.less
  • website/assets/styles/pages/device-management.less
  • website/assets/styles/pages/docs/app-details.less
  • website/assets/styles/pages/docs/app-library.less
  • website/assets/styles/pages/docs/basic-documentation.less
  • website/assets/styles/pages/docs/command-details.less
  • website/assets/styles/pages/docs/mdm-commands.less
  • website/assets/styles/pages/docs/os-settings.less
  • website/assets/styles/pages/docs/osquery-table-details.less
  • website/assets/styles/pages/docs/policy-details.less
  • website/assets/styles/pages/docs/policy-library.less
  • website/assets/styles/pages/docs/query-detail.less
  • website/assets/styles/pages/docs/query-library.less
  • website/assets/styles/pages/docs/script-details.less
  • website/assets/styles/pages/docs/script-library.less
  • website/assets/styles/pages/docs/vital-details.less
  • website/assets/styles/pages/fleet-premium-trial.less
  • website/assets/styles/pages/homepage.less
  • website/assets/styles/pages/infrastructure-as-code.less
  • website/assets/styles/pages/landing-pages/linux-management.less
  • website/assets/styles/pages/landing-pages/replace-jamf.less
  • website/assets/styles/pages/observability.less
  • website/assets/styles/pages/partners.less
  • website/assets/styles/pages/software-management.less
  • website/assets/styles/pages/transparency.less
  • website/views/pages/device-management.ejs
  • website/views/pages/homepage.ejs
  • website/views/pages/landing-pages/linux-management.ejs
  • website/views/pages/observability.ejs
  • website/views/pages/software-management.ejs

Comment on lines +6 to +8
// Side-by-side: an image paired with a text block (headline + paragraph +
// checklist or similar). Collapses to a single column below 992px.
//

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Correct the documented collapse breakpoint.

The mixin switches to a column layout at max-width: 768px, not below 992px.

📝 Proposed fix
-// checklist or similar). Collapses to a single column below 992px.
+// checklist or similar). Collapses to a single column at 768px and below.
📝 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
// Side-by-side: an image paired with a text block (headline + paragraph +
// checklist or similar). Collapses to a single column below 992px.
//
// Side-by-side: an image paired with a text block (headline + paragraph +
// checklist or similar). Collapses to a single column at 768px and below.
//
🧰 Tools
🪛 Stylelint (17.7.0)

[error] 8-8: Unexpected empty comment (scss/comment-no-empty)

(scss/comment-no-empty)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/assets/styles/mixins-and-variables/feature-blocks.less` around lines
6 - 8, The inline comment in feature-blocks.less incorrectly documents the
collapse breakpoint as "below 992px" while the mixin actually switches to a
column layout at max-width: 768px; update the comment text in the block starting
with "// Side-by-side: an image paired with a text block..." to state the
correct collapse point (e.g., "Collapses to a single column at max-width: 768px"
or "below 768px") so the documentation matches the implemented breakpoint.

Comment on lines +74 to 104
<div purpose="three-column-features">
<div purpose="feature">
<h5>Operating systems</h5>
<p>Manage Apple, Windows, Linux, and Android devices in one place. Fleet supports diverse, mixed environments with no vendor lock-in.</p>
</div>

<div purpose="feature-item" class="pl-0 pl-lg-4 pr-lg-0 col-12 col-sm-6 col-lg-4">
<h5>Config management</h5>
<p>Bring devices into a secure, predictable state, no matter where they start. Define, target, and deploy the right settings to the right devices.</p>
</div>
<div purpose="feature-item" class="pr-0 pr-lg-4 pl-lg-0 col-12 col-sm-6 col-lg-4">
<h5>Software management</h5>
<p>Keep applications and plugins secure and up-to-date automatically. Install the software end users need or let them install it themselves via self service.</p>
<p><a href="/software-management">More about software management</a></p>
</div>
<div purpose="feature">
<h5>Automated enrollment</h5>
<p>Drop ship devices with Apple Business Manager or Autopilot. End users can set up their own devices. No IT help needed.</p>
</div>

<div purpose="feature-item" class="pl-0 pl-lg-4 col-12 col-sm-6 col-lg-4">
<h5>Custom scripts</h5>
<p>Run the right script at the right time, across any platform. Remediate drift, gather diagnostics, and automate fleet-wide tasks.</p>
<p><a href="/orchestration">More about orchestration</a></p>
</div>
<div purpose="feature">
<h5>Config management</h5>
<p>Bring devices into a secure, predictable state, no matter where they start. Define, target, and deploy the right settings to the right devices.</p>
</div>
<div purpose="feature">
<h5>Software management</h5>
<p>Keep applications and plugins secure and up-to-date automatically. Install the software end users need or let them install it themselves via self service.</p>
<p><a href="/software-management">More about software management</a></p>
</div>

<div purpose="feature-item" class="pr-0 pr-lg-4 col-12 col-sm-6 col-lg-4">
<h5>Flexible by design</h5>
<p>Manage devices via Fleet’s UI, API, or infrastructure as code. The open-source community helps extend what’s possible, from platform support to deployment workflows.</p>
</div>
<div purpose="feature">
<h5>Custom scripts</h5>
<p>Run the right script at the right time, across any platform. Remediate drift, gather diagnostics, and automate fleet-wide tasks.</p>
<p><a href="/orchestration">More about orchestration</a></p>
</div>

<div purpose="feature-row" class="row d-flex flex-sm-row flex-column justify-content-lg-between justify-content-center mb-0 align-items-center align-items-sm-start">
<div purpose="feature">
<h5>Flexible by design</h5>
<p>Manage devices via Fleet’s UI, API, or infrastructure as code. The open-source community helps extend what’s possible, from platform support to deployment workflows.</p>
</div>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Keep the heading tag aligned with the page stylesheet.

The updated feature cards use h5, but website/assets/styles/pages/device-management.less styles these feature headings with [purpose='three-column-features'] [purpose='feature'] h4. These headings will miss the intended typography unless the tag or selector is updated.

🎨 Proposed fix
-            <h5>Operating systems</h5>
+            <h4>Operating systems</h4>
...
-            <h5>Automated enrollment</h5>
+            <h4>Automated enrollment</h4>
...
-            <h5>Config management</h5>
+            <h4>Config management</h4>
...
-            <h5>Software management</h5>
+            <h4>Software management</h4>
...
-            <h5>Custom scripts</h5>
+            <h4>Custom scripts</h4>
...
-            <h5>Flexible by design</h5>
+            <h4>Flexible by design</h4>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/views/pages/device-management.ejs` around lines 74 - 104, The feature
card headings were changed from h4 to h5 and no longer match the stylesheet
selector [purpose='three-column-features'] [purpose='feature'] h4; revert the
headings in device-management.ejs from h5 back to h4 (the headings inside each
<div purpose="feature">) so the existing styles apply, or alternatively update
the stylesheet selector to target h5 instead of h4 (selector:
[purpose='three-column-features'] [purpose='feature'] h4) — pick one approach
and make the corresponding change for all feature cards.

Comment on lines +1450 to +1454
<div purpose="feature">
<img alt="Free as in free" src="/images/homepage-icon-free-48x64@2x.png">
<h5>Free as in free</h5>
<p>The <a href="https://fleetdm.com/docs/get-started/faq#what-is-your-commitment-to-open-source-stewardship">free version of Fleet</a> will always be free. Fleet is independently backed and actively maintained with the help of many amazing <a target="_blank" href="https://github.com/fleetdm/fleet/graphs/contributors">contributors</a>.</p>
</div>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add rel to the external new-tab link.

Line 1453 opens GitHub in a new tab; add rel="noopener noreferrer" to avoid exposing window.opener in browsers that do not implicitly protect it.

🛡️ Proposed fix
-          <p>The <a href="https://fleetdm.com/docs/get-started/faq#what-is-your-commitment-to-open-source-stewardship">free version of Fleet</a> will always be free. Fleet is independently backed and actively maintained with the help of many amazing <a target="_blank" href="https://github.com/fleetdm/fleet/graphs/contributors">contributors</a>.</p>
+          <p>The <a href="https://fleetdm.com/docs/get-started/faq#what-is-your-commitment-to-open-source-stewardship">free version of Fleet</a> will always be free. Fleet is independently backed and actively maintained with the help of many amazing <a target="_blank" rel="noopener noreferrer" href="https://github.com/fleetdm/fleet/graphs/contributors">contributors</a>.</p>
📝 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
<div purpose="feature">
<img alt="Free as in free" src="/images/homepage-icon-free-48x64@2x.png">
<h5>Free as in free</h5>
<p>The <a href="https://fleetdm.com/docs/get-started/faq#what-is-your-commitment-to-open-source-stewardship">free version of Fleet</a> will always be free. Fleet is independently backed and actively maintained with the help of many amazing <a target="_blank" href="https://github.com/fleetdm/fleet/graphs/contributors">contributors</a>.</p>
</div>
<div purpose="feature">
<img alt="Free as in free" src="/images/homepage-icon-free-48x64@2x.png">
<h5>Free as in free</h5>
<p>The <a href="https://fleetdm.com/docs/get-started/faq#what-is-your-commitment-to-open-source-stewardship">free version of Fleet</a> will always be free. Fleet is independently backed and actively maintained with the help of many amazing <a target="_blank" rel="noopener noreferrer" href="https://github.com/fleetdm/fleet/graphs/contributors">contributors</a>.</p>
</div>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/views/pages/homepage.ejs` around lines 1450 - 1454, Add rel="noopener
noreferrer" to the external anchor that opens in a new tab: locate the <a>
element with target="_blank" pointing to
"https://github.com/fleetdm/fleet/graphs/contributors" in the homepage view and
update that anchor to include rel="noopener noreferrer" to prevent window.opener
leakage in older browsers.

Comment on lines +78 to +114
<div purpose="three-column-features">
<div purpose="feature">
<img alt="Software and asset inventory" src="/images/icon-live-connection-48x48@2x.png">
<h5>Live connection</h5>
<p>Talk to online devices in real time with Fleet’s live query API. Implement custom workflows like conditional access based on device posture, Identity, and more.</p>
</div>

<div purpose="feature-item" class="pr-0 pr-lg-4 col-12 col-sm-6 col-lg-4" >
<img alt="Software and asset inventory" src="/images/icon-software-and-asset-inventory-48x48@2x.png" class="mx-auto mx-sm-0">
<h5>Software and asset inventory</h5>
<p>Get visibility into all endpoints across any operating system*, including support for servers and containers in every cloud infrastructure.</p>
<p><a href="/software-management">More about software management</a></p>
</div>
<div purpose="feature">
<img alt="Software and asset inventory" src="/images/icon-software-and-asset-inventory-48x48@2x.png">
<h5>Software and asset inventory</h5>
<p>Get visibility into all endpoints across any operating system*, including support for servers and containers in every cloud infrastructure.</p>
<p><a href="/software-management">More about software management</a></p>
</div>

<div purpose="feature-item" class="pl-0 pl-lg-4 pr-lg-0 col-12 col-sm-6 col-lg-4">
<img alt="See logins for every endpoint" src="/images/icon-see-logins-for-every-endpoint-48x48@2x.png" class="mx-auto mx-sm-0">
<h5>See logins for every endpoint</h5>
<p>Identify who logs in to any system, including login history and current sessions. Look up any computer by the email address of the person using it.</p>
</div>
<div purpose="feature">
<img alt="See logins for every endpoint" src="/images/icon-see-logins-for-every-endpoint-48x48@2x.png">
<h5>See logins for every endpoint</h5>
<p>Identify who logs in to any system, including login history and current sessions. Look up any computer by the email address of the person using it.</p>
</div>

<div purpose="feature-item" class="pr-0 pr-lg-4 pl-lg-0 col-12 col-sm-6 col-lg-4 mb-lg-0">
<img alt="CIS benchmarks" src="/images/icon-cis-benchmarks-48x48@2x.png" class="mx-auto mx-sm-0">
<h5>CIS benchmarks</h5>
<p>Keep all your endpoints* compliant with customizable baselines, or use common benchmarks like CIS.</p>
</div>
<div purpose="feature">
<img alt="CIS benchmarks" src="/images/icon-cis-benchmarks-48x48@2x.png">
<h5>CIS benchmarks</h5>
<p>Keep all your endpoints* compliant with customizable baselines, or use common benchmarks like CIS.</p>
</div>

<div purpose="feature-item" class="pl-0 pl-lg-4 col-12 col-sm-6 col-lg-4 mb-sm-0">
<img alt="Verify updates and settings" src="/images/icon-edr-health-check-48x48@2x.png" class="mx-auto mx-sm-0">
<h5>EDR health checks</h5>
<p>Verify that your EDR tools are installed and working so you can identify and address configuration issues quickly.</p>
</div>
<div purpose="feature">
<img alt="Verify updates and settings" src="/images/icon-edr-health-check-48x48@2x.png">
<h5>EDR health checks</h5>
<p>Verify that your EDR tools are installed and working so you can identify and address configuration issues quickly.</p>
</div>

<div purpose="feature-item" class="pr-0 pr-lg-4 col-12 col-sm-6 col-lg-4 mb-0">
<img alt="Verify updates and settings" src="/images/icon-verify-updates-and-settings-48x48@2x.png" class="mx-auto mx-sm-0">
<h5>Verify updates and settings</h5>
<p>Track progress towards deadlines for security posture remediation projects, and enforce due dates through automations.</p>
</div>
<div purpose="feature">
<img alt="Verify updates and settings" src="/images/icon-verify-updates-and-settings-48x48@2x.png">
<h5>Verify updates and settings</h5>
<p>Track progress towards deadlines for security posture remediation projects, and enforce due dates through automations.</p>
</div>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix mismatched icon alt text.

Line 80 describes the “Live connection” icon as “Software and asset inventory”, and Line 105 describes “EDR health checks” as “Verify updates and settings”. Match the adjacent feature heading, or use empty alt text if these icons are decorative.

♿ Proposed fix
-        <img alt="Software and asset inventory" src="/images/icon-live-connection-48x48@2x.png">
+        <img alt="Live connection" src="/images/icon-live-connection-48x48@2x.png">
...
-        <img alt="Verify updates and settings" src="/images/icon-edr-health-check-48x48@2x.png">
+        <img alt="EDR health checks" src="/images/icon-edr-health-check-48x48@2x.png">
📝 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
<div purpose="three-column-features">
<div purpose="feature">
<img alt="Software and asset inventory" src="/images/icon-live-connection-48x48@2x.png">
<h5>Live connection</h5>
<p>Talk to online devices in real time with Fleet’s live query API. Implement custom workflows like conditional access based on device posture, Identity, and more.</p>
</div>
<div purpose="feature-item" class="pr-0 pr-lg-4 col-12 col-sm-6 col-lg-4" >
<img alt="Software and asset inventory" src="/images/icon-software-and-asset-inventory-48x48@2x.png" class="mx-auto mx-sm-0">
<h5>Software and asset inventory</h5>
<p>Get visibility into all endpoints across any operating system*, including support for servers and containers in every cloud infrastructure.</p>
<p><a href="/software-management">More about software management</a></p>
</div>
<div purpose="feature">
<img alt="Software and asset inventory" src="/images/icon-software-and-asset-inventory-48x48@2x.png">
<h5>Software and asset inventory</h5>
<p>Get visibility into all endpoints across any operating system*, including support for servers and containers in every cloud infrastructure.</p>
<p><a href="/software-management">More about software management</a></p>
</div>
<div purpose="feature-item" class="pl-0 pl-lg-4 pr-lg-0 col-12 col-sm-6 col-lg-4">
<img alt="See logins for every endpoint" src="/images/icon-see-logins-for-every-endpoint-48x48@2x.png" class="mx-auto mx-sm-0">
<h5>See logins for every endpoint</h5>
<p>Identify who logs in to any system, including login history and current sessions. Look up any computer by the email address of the person using it.</p>
</div>
<div purpose="feature">
<img alt="See logins for every endpoint" src="/images/icon-see-logins-for-every-endpoint-48x48@2x.png">
<h5>See logins for every endpoint</h5>
<p>Identify who logs in to any system, including login history and current sessions. Look up any computer by the email address of the person using it.</p>
</div>
<div purpose="feature-item" class="pr-0 pr-lg-4 pl-lg-0 col-12 col-sm-6 col-lg-4 mb-lg-0">
<img alt="CIS benchmarks" src="/images/icon-cis-benchmarks-48x48@2x.png" class="mx-auto mx-sm-0">
<h5>CIS benchmarks</h5>
<p>Keep all your endpoints* compliant with customizable baselines, or use common benchmarks like CIS.</p>
</div>
<div purpose="feature">
<img alt="CIS benchmarks" src="/images/icon-cis-benchmarks-48x48@2x.png">
<h5>CIS benchmarks</h5>
<p>Keep all your endpoints* compliant with customizable baselines, or use common benchmarks like CIS.</p>
</div>
<div purpose="feature-item" class="pl-0 pl-lg-4 col-12 col-sm-6 col-lg-4 mb-sm-0">
<img alt="Verify updates and settings" src="/images/icon-edr-health-check-48x48@2x.png" class="mx-auto mx-sm-0">
<h5>EDR health checks</h5>
<p>Verify that your EDR tools are installed and working so you can identify and address configuration issues quickly.</p>
</div>
<div purpose="feature">
<img alt="Verify updates and settings" src="/images/icon-edr-health-check-48x48@2x.png">
<h5>EDR health checks</h5>
<p>Verify that your EDR tools are installed and working so you can identify and address configuration issues quickly.</p>
</div>
<div purpose="feature-item" class="pr-0 pr-lg-4 col-12 col-sm-6 col-lg-4 mb-0">
<img alt="Verify updates and settings" src="/images/icon-verify-updates-and-settings-48x48@2x.png" class="mx-auto mx-sm-0">
<h5>Verify updates and settings</h5>
<p>Track progress towards deadlines for security posture remediation projects, and enforce due dates through automations.</p>
</div>
<div purpose="feature">
<img alt="Verify updates and settings" src="/images/icon-verify-updates-and-settings-48x48@2x.png">
<h5>Verify updates and settings</h5>
<p>Track progress towards deadlines for security posture remediation projects, and enforce due dates through automations.</p>
</div>
<div purpose="three-column-features">
<div purpose="feature">
<img alt="Live connection" src="/images/icon-live-connection-48x48@2x.png">
<h5>Live connection</h5>
<p>Talk to online devices in real time with Fleet's live query API. Implement custom workflows like conditional access based on device posture, Identity, and more.</p>
</div>
<div purpose="feature">
<img alt="Software and asset inventory" src="/images/icon-software-and-asset-inventory-48x48@2x.png">
<h5>Software and asset inventory</h5>
<p>Get visibility into all endpoints across any operating system*, including support for servers and containers in every cloud infrastructure.</p>
<p><a href="/software-management">More about software management</a></p>
</div>
<div purpose="feature">
<img alt="See logins for every endpoint" src="/images/icon-see-logins-for-every-endpoint-48x48@2x.png">
<h5>See logins for every endpoint</h5>
<p>Identify who logs in to any system, including login history and current sessions. Look up any computer by the email address of the person using it.</p>
</div>
<div purpose="feature">
<img alt="CIS benchmarks" src="/images/icon-cis-benchmarks-48x48@2x.png">
<h5>CIS benchmarks</h5>
<p>Keep all your endpoints* compliant with customizable baselines, or use common benchmarks like CIS.</p>
</div>
<div purpose="feature">
<img alt="EDR health checks" src="/images/icon-edr-health-check-48x48@2x.png">
<h5>EDR health checks</h5>
<p>Verify that your EDR tools are installed and working so you can identify and address configuration issues quickly.</p>
</div>
<div purpose="feature">
<img alt="Verify updates and settings" src="/images/icon-verify-updates-and-settings-48x48@2x.png">
<h5>Verify updates and settings</h5>
<p>Track progress towards deadlines for security posture remediation projects, and enforce due dates through automations.</p>
</div>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/views/pages/observability.ejs` around lines 78 - 114, The alt text
for two <img> elements is mismatched: the image before the <h5>Live
connection</h5> currently has alt="Software and asset inventory" and the image
before the <h5>EDR health checks</h5> currently has alt="Verify updates and
settings"; update those alt attributes to match their adjacent headings (e.g.,
alt="Live connection" and alt="EDR health checks") or set them to an empty
string (alt="") if the icons are purely decorative, keeping the other <img> alt
texts unchanged.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors the website’s LESS styling into reusable spacing/typography/layout mixins and updates multiple marketing/docs pages to use the new shared patterns, reducing repeated inline Bootstrap utility classes and duplicated CSS.

Changes:

  • Added shared spacing variables and new mixins for containers, typography, and “feature” block layouts.
  • Updated page templates (EJS) to use standardized purpose-based markup (e.g., feature-with-image, three-column-features).
  • Updated many page-specific LESS files to call the new mixins and use centralized spacing variables.

Reviewed changes

Copilot reviewed 5 out of 37 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
website/views/pages/software-management.ejs Switches feature sections to purpose="feature-with-image" markup.
website/views/pages/observability.ejs Converts feature grids and feature-with-image sections to the new markup; updates footnote structure.
website/views/pages/landing-pages/linux-management.ejs Removes Bootstrap layout classes in favor of mixin-driven layout.
website/views/pages/homepage.ejs Reorders feature-with-image DOM structure to match standardized markup.
website/views/pages/device-management.ejs Replaces Bootstrap layout classes with feature-with-image / three-column-features markup.
website/assets/styles/pages/transparency.less Replaces heading styles with typography mixins; removes unused feature grid CSS.
website/assets/styles/pages/software-management.less Applies .feature-with-image() and refactors feature section styling.
website/assets/styles/pages/partners.less Replaces heading/kicker styles with typography mixins.
website/assets/styles/pages/observability.less Uses new feature layout mixins (.responsive-feature-row(), .feature-with-image()) and adjusts footnote styling.
website/assets/styles/pages/landing-pages/replace-jamf.less Replaces repeated 3-column feature layout with .three-column-features().
website/assets/styles/pages/landing-pages/linux-management.less Refactors feature-with-image layout to use .feature-with-image().
website/assets/styles/pages/infrastructure-as-code.less Replaces heading/kicker styles with typography mixins.
website/assets/styles/pages/homepage.less Applies new typography and feature layout mixins for consistency.
website/assets/styles/pages/fleet-premium-trial.less Replaces h3 styling with .title-m().
website/assets/styles/pages/docs/vital-details.less Uses centralized padding variable and .page-content-docs().
website/assets/styles/pages/docs/script-library.less Uses centralized padding variables and .page-content-docs().
website/assets/styles/pages/docs/script-details.less Uses centralized padding variables and .page-content-docs().
website/assets/styles/pages/docs/query-library.less Uses centralized padding variables and .page-content-docs().
website/assets/styles/pages/docs/query-detail.less Uses centralized padding variables and .page-content-docs().
website/assets/styles/pages/docs/policy-library.less Uses centralized padding variables and .page-content-docs().
website/assets/styles/pages/docs/policy-details.less Uses centralized padding variables and .page-content-docs().
website/assets/styles/pages/docs/osquery-table-details.less Uses centralized padding variables and .page-content-docs().
website/assets/styles/pages/docs/os-settings.less Uses centralized padding variables and .page-content-docs().
website/assets/styles/pages/docs/mdm-commands.less Uses centralized padding variables and .page-content-docs().
website/assets/styles/pages/docs/command-details.less Uses centralized padding variables and .page-content-docs().
website/assets/styles/pages/docs/basic-documentation.less Uses centralized padding variables and .page-content-docs().
website/assets/styles/pages/docs/app-library.less Uses centralized padding variables and .page-content-docs().
website/assets/styles/pages/docs/app-details.less Uses centralized padding variables and .page-content().
website/assets/styles/pages/device-management.less Applies .feature-with-image() / .responsive-feature-row() mixins and updates feature section styling.
website/assets/styles/pages/customers.less Replaces heading/kicker styles with typography mixins.
website/assets/styles/pages/configuration-builder.less Replaces h3 styling with .title-m().
website/assets/styles/pages/articles/basic-whitepaper.less Replaces h1 styling with .title-xl().
website/assets/styles/mixins-and-variables/typography.less Adds shared text style mixins and a new kicker font variable.
website/assets/styles/mixins-and-variables/spacing.less Introduces shared spacing variables and max-width tokens.
website/assets/styles/mixins-and-variables/index.less Imports new spacing + feature-block mixins into the shared bundle.
website/assets/styles/mixins-and-variables/feature-blocks.less Adds mixins for feature-with-image and feature grid layouts.
website/assets/styles/mixins-and-variables/containers.less Adds shared mixins for page container/content sizing.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

[purpose='feature-with-image'] {
margin-bottom: 120px;
[purpose='feature-text'] {
// width: unset;

// Title styles:
.kicker-title() {
font-family: 'Roboto Mono';
Comment on lines +40 to +44
[purpose='feature-text'] {
display: flex;
flex-direction: column;
gap: 32px;
}
Comment thread website/assets/styles/pages/device-management.less
Comment thread website/assets/styles/pages/software-management.less
@eashaw
eashaw merged commit 308e5f3 into main Apr 20, 2026
4 checks passed
@eashaw
eashaw deleted the website-add-spacing.less branch April 20, 2026 19:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

~ga4-annotation This label is automatically applied to certain website changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants