Website: Add case study article template page and three articles (#37153)
Changes: - Updated the website's build-static-content script to add support for a new article category: `case study`. - Added a new article template page for case study articles - Added case study articles from Stripe, Faire, and Foursquare. --------- Co-authored-by: Mike Thomas <78363703+mike-j-thomas@users.noreply.github.com>
@@ -0,0 +1,87 @@
|
||||
# Faire secures Macs with CIS benchmarks and Fleet
|
||||
|
||||
|
||||
## Why Faire needed a change
|
||||
|
||||
Faire’s IT team is highly technical and prefers vendors that provide features through APIs. They’re builders who extend applications when out-of-the-box features fall short, and their workflows are highly automated and managed as code.
|
||||
|
||||
They had used their previous MDM for several years, but frustration grew as it lagged in adopting new MDM APIs, including Apple’s Declarative Device Management. Faire’s workflow, based on ‘config-as-code’, also proved challenging.
|
||||
|
||||
With all their other IT systems, like their IDP, productivity software, and cloud infrastructure, all configured through code with automated CI/CD pipelines, maintaining an MDM that had to be managed via the UI became increasingly painful.
|
||||
|
||||
|
||||
One team member spent months trying to build a Terraform provider for the previous MDM, but gave up because of bugs and inconsistent APIs.
|
||||
|
||||
Support also became a problem. Feature requests often felt ignored, and responses were slow, which didn’t work for a company of Faire's size.
|
||||
|
||||
## The search for a solution
|
||||
|
||||
Faire focused on three priorities when selecting a new MDM:
|
||||
|
||||
<div purpose="checklist">
|
||||
|
||||
API-first architecture: A first-class API built for deep integration, not an API layered on top of a UI
|
||||
|
||||
Comprehensive Apple support: End-to-end lifecycle management for macOS and iPadOS, including automated enrollment, policy controls, and software distribution
|
||||
|
||||
A reputable vendor: A well-established partner they could rely on for the long term
|
||||
</div>
|
||||
|
||||
## Choosing Fleet
|
||||
|
||||
Faire selected Fleet after a bake-off with three other MDM vendors, including an open-source option. They were already using Fleet to manage osquery telemetry, and the availability of a SaaS deployment matched their move away from self-hosting.
|
||||
|
||||
All Fleet features are accessible through an API, with examples that show how to automate tasks through GitOps. Fleet integrated directly into Faire’s onboarding workflows, and their engineers appreciate managing device configurations through GitOps and pull requests.
|
||||
|
||||
Fleet also gives Faire more flexibility for managing Macs and iPads. They use custom profiles and can tap into native MDM APIs that Fleet exposes, even when those APIs are not yet implemented as built-in features.
|
||||
|
||||
In addition, Fleet helps Faire monitor Macs against CIS benchmarks. This improves their device security posture and gives IT the ability to take remediation actions when they find issues.
|
||||
|
||||
Fleet’s reputation in the Mac Admins community also matters to Faire. Industry experts highly regard the team and product, and Fleet’s open-source foundation gives Faire confidence that the underlying IP will always remain available.
|
||||
|
||||
<div purpose="attribution-quote">
|
||||
|
||||
*My team is loving managing devices via GitOps with Fleet.*
|
||||
|
||||
**Jeremy Baker**
|
||||
|
||||
Engineering Manager
|
||||
|
||||
</div>
|
||||
|
||||
## The future
|
||||
|
||||
Faire continues to be impressed by Fleet’s proactive support. For example, Fleet reached out when they detected a downed webhook on Faire’s end. In another instance, an engineer got on a video call 10 minutes after Faire filed a critical migration ticket.
|
||||
|
||||
Telemetry from Fleet remains important for device posture. It gives Faire the visibility they need to assess device signals alongside their IDP. Fleet’s integrated MDM then provides a path to remediation and risk mitigation when they find issues.
|
||||
|
||||
Fleet is working with Faire to explore managing other platforms, including Windows, Linux, and potentially BYOD mobile devices.
|
||||
|
||||
Interested to learn more? [Read Faire’s article](https://craft.faire.com/using-observability-to-reduce-chaos-in-an-mdm-migration-20a0056a48e7) about their MDM migration.
|
||||
|
||||
|
||||
|
||||
|
||||
<meta name="category" value="case study">
|
||||
<meta name="articleTitle" value="Faire secures Macs with CIS benchmarks and Fleet">
|
||||
|
||||
|
||||
<meta name="publishedOn" value="2025-12-11">
|
||||
<meta name="authorGitHubUsername" value="n/a">
|
||||
<meta name="authorFullName" value="Fleetdm">
|
||||
|
||||
|
||||
<meta name="companyLogoFilename" value="faire-logo-192x40@2x.png">
|
||||
<meta name="quoteAuthorImageFilename" value="jeremy-baker-120x120@2x.png">
|
||||
<meta name="quoteAuthorName" value="Jeremy Baker">
|
||||
<meta name="quoteAuthorJobTitle" value="Engineering Manager">
|
||||
<meta name="quoteContent" value="“Fleet has opened a lot of opportunities for us. My team is loving managing devices via GitOps, and the built-in support for CIS benchmarks has made it easy to enforce these on our devices.”">
|
||||
|
||||
<meta name="companyName" value="Faire">
|
||||
<meta name="companyInfo" value="Faire is a global online wholesale marketplace that connects independent retailers with emerging and established brands. Retailers use the platform to discover products and manage inventory, and brands use it to reach a wider audience and streamline wholesale operations.">
|
||||
<meta name="companyInfoLineTwo" value="Faire operates in the US, Canada, and the UK, with about 1,000 employees. Most of their endpoints run macOS, with some Windows laptops, and they also manage 300 iPads used for Zoom Rooms.">
|
||||
|
||||
<meta name="summaryChallenge" value="Faire’s previous MDM slowed them down. It lacked timely support for new OS controls, its APIs made config-as-code workflows hard to automate, and support responses were too slow to keep up with their needs.">
|
||||
<meta name="summarySolution" value="Fleet replaced their previous MDM for managing Macs and iPads, and supports the GitOps workflows they use to manage their infrastructure.">
|
||||
<meta name="summaryKeyResults" value="Enforced CIS Level 1 benchmarks to keep laptops secure; Migrated 1,000 Macs and iPads to Fleet without disruption; Moved device management workflows into GitOps; Received proactive support from Fleet">
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
# Foursquare cut costs and gained 114% ROI with Fleet
|
||||
|
||||
## Why Foursquare needed a change
|
||||
|
||||
Foursquare supports more than 200 Macs and around 15 Windows devices in a hybrid environment, where developers are able to work on the platforms of their choice. That flexibility means the IT team must support macOS and Windows with the same level of consistency and security.
|
||||
|
||||
The team faced two main challenges: the complexity of managing endpoints across different MDMs, and the time required to maintain them. As a small team, they were running two separate MDM platforms — an Apple-focused MDM for Macs and another for Windows. The overhead of maintaining both systems was overwhelming and added unnecessary complexity.
|
||||
|
||||
To minimize this complexity, the team began automating their processes. Automation required API-driven configurability across systems, but their previous MDM’s fragmented API made it difficult to build reliable DevOps workflows. That limitation pushed the team to evaluate alternatives.
|
||||
|
||||
They also found that maintaining multiple MDM tools pulled time away from supporting users. They wanted to refocus their resources on serving their users’ needs instead of “looking after the tools that managed their devices.”
|
||||
|
||||
## The search for a solution
|
||||
|
||||
The team at Foursquare began evaluating alternatives. Their main goal was to consolidate their device management into a single platform that supported both macOS and Windows. Any replacement also had to match the controls they already relied on in their existing MDMs.
|
||||
|
||||
They needed a platform with a developer-friendly API — something simple, reliable, and easy to work with. A clear API would let the team invest more in automation, which hadn’t been practical while managing two different MDMs.
|
||||
|
||||
They also wanted the migration to be quick and seamless. With their past experience, the team knew that MDM changes could be disruptive, and they wanted to minimize any impact on end users.
|
||||
|
||||
## Choosing Fleet
|
||||
|
||||
The Foursquare team had met Fleet at a DevOps conference. After hearing positive feedback and conducting their own research, they decided to evaluate the platform. Fleet checked all the boxes they were looking for: macOS and Windows support, a developer-friendly API, and a GitOps-first approach.
|
||||
|
||||
During the evaluation, the team was particularly impressed with Fleet’s Open Source roots. The transparency gave them confidence early on. Everything from bugs to roadmaps and source code was available for review.
|
||||
|
||||
<div purpose="attribution-quote">
|
||||
|
||||
There are no surprises - you can see what they are working on at any time.
|
||||
|
||||
**Mike Meyer**
|
||||
|
||||
Senior Manager, Corporate Engineer
|
||||
|
||||
</div>
|
||||
|
||||
A key question was whether Fleet could do everything their current MDMs. The Fleet team helped them translate their current configurations into Fleet equivalents. In some cases, they discovered new ways to manage these settings that were easier to automate. Throughout the process, the Fleet team stayed closely engaged and provided strong support.
|
||||
|
||||
The evaluation also showed that Fleet fit well with their telemetry pipeline. They could send device data directly into their SIEM and data lake without staging it separately. Having device data alongside identity and authentication information in the same repository gave the team more flexibility in how they worked with that data.
|
||||
|
||||
When Foursquare decided to migrate, moving their macOS and Windows devices to Fleet was seamless. The Fleet team provided ready-to-use tools and guidance that made the transition straightforward.
|
||||
|
||||
<div purpose="attribution-quote">
|
||||
|
||||
One of the easiest, quickest, smoothest migrations I’ve ever done.
|
||||
|
||||
**Mike Meyer**
|
||||
|
||||
Senior Manager, Corporate Engineer
|
||||
|
||||
</div>
|
||||
|
||||
## Clearer visibility and stronger automation
|
||||
|
||||
After six months, Foursquare began to see clear benefits.
|
||||
|
||||
<div purpose="checklist">
|
||||
|
||||
They reduced time spent on endpoint maintenance by 50%. Instead of “caring for the tools,” the team could focus more on solving their customers’ needs.
|
||||
|
||||
They reduced MDM spend by 24% by consolidating two separate platforms into Fleet and eliminating redundant licensing.
|
||||
|
||||
</div>
|
||||
|
||||
Foursquare also gained real-time visibility into their endpoints. They could dispatch queries and send results directly into their SIEM, giving them a clearer understanding of device state. This level of visibility helped them make data-driven decisions and deploy updates or configuration changes with confidence.
|
||||
|
||||
Fleet has also become a key part of their automation workflow. Managing configurations through automation — instead of through a UI — gave the team a level of confidence they didn’t have before.
|
||||
|
||||
<div purpose="attribution-quote">
|
||||
|
||||
Fleet is the best tool for Foursquare - it helps my team be more creative and effective.
|
||||
|
||||
**Mike Meyer**
|
||||
|
||||
Senior Manager, Corporate Engineer
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<meta name="category" value="case study">
|
||||
<meta name="companyLogoFilename" value="foursquare-logo-212x40@2x.png">
|
||||
<meta name="articleTitle" value="Foursquare cut costs and gained 114% ROI with Fleet">
|
||||
|
||||
|
||||
<meta name="publishedOn" value="2025-12-11">
|
||||
<meta name="authorGitHubUsername" value="n/a">
|
||||
<meta name="authorFullName" value="Fleetdm">
|
||||
|
||||
<meta name="quoteContent" value="“One of the easiest, quickest, smoothest migrations I’ve ever done.”">
|
||||
<meta name="quoteAuthorImageFilename" value="mike-meyer-120x120@2x.png">
|
||||
<meta name="quoteAuthorName" value="Mike Meyer">
|
||||
<meta name="quoteAuthorJobTitle" value="Senior Manager, Corporate Engineer">
|
||||
|
||||
<meta name="companyName" value="Foursquare">
|
||||
<meta name="companyInfo" value="Foursquare is the industry's leading geospatial technology platform, designed to help businesses make smarter decisions and create more engaging customer experiences.">
|
||||
<meta name="companyInfoLineTwo" value="Powered by deep machine learning and a privacy-forward approach, their technology and solutions are redefining how organizations derive value from location intelligence.">
|
||||
|
||||
<meta name="summaryChallenge" value="Foursquare wanted to simplify how they managed Macs and Windows devices. Their devices were split across two different MDMs, which created extra work and made automation harder for a small IT team.">
|
||||
<meta name="summarySolution" value="Fleet provided Foursquare with a single MDM platform that supports both Mac and Windows. Migrating from their previous MDMs was seamless and easy, thanks to Fleet-provided out-of-the-box tools that added speed and simplicity.">
|
||||
<meta name="summaryKeyResults" value="Cut endpoint maintenance effort by 50%; Reduced licensing costs by 24%; Achieved 114% ROI by removing duplicate tools; Real-time visibility with direct integration to their SIEM, with no latency; Increased reliability of security controls with GitOps">
|
||||
@@ -0,0 +1,97 @@
|
||||
# Stripe moved 10,000 Macs to Fleet, saving hundreds of thousands annually
|
||||
|
||||
## Why Stripe needed a change
|
||||
|
||||
Stripe manages about 10,000 Macs and 5,000 Chromebooks for employees and support partners. All employee Macs are provisioned automatically with Apple Automated Device Enrollment, and users authenticate into the device during onboarding. Chromebooks have a lower risk profile and are used by support partners.
|
||||
|
||||
Stripe has a strong focus on security and automation. Their previous MDM relied on manual, UI-driven workflows, which didn’t fit their “infrastructure as code” approach. Fragmented APIs made it hard to automate even simple tasks, and the team had to build workarounds to fill gaps.
|
||||
|
||||
New Apple OS releases introduce features, commands, and profiles. Stripe wanted more visibility and control than their MDM provided. Support for the latest OS only arrived after public release, and they couldn’t inject raw payloads or inspect device responses.
|
||||
|
||||
Slow vendor support made these issues worse. Stripe often waited a long time for ticket responses, delaying resolutions. Lower-impact bugs sometimes went unfixed.
|
||||
|
||||
<div purpose="attribution-quote">
|
||||
|
||||
*The ability to get heard [with our previous MDM] was just impossible.*
|
||||
|
||||
**Wes Whetstone**
|
||||
|
||||
Staff Client Platform Engineer
|
||||
</div>
|
||||
|
||||
## The search for a solution
|
||||
|
||||
When their previous MDM came up for renewal, Stripe decided to look for alternatives. They evaluated several MDMs against a clear set of requirements.
|
||||
|
||||
First, any replacement had to support all critical use cases for Stripe’s Macs. Employee Macs are “business only,” and third-party software must be approved as “business critical” before installation. Stripe’s security teams also use MDM profiles as part of their device-trust decisions. Getting core MDM functionality right was essential.
|
||||
|
||||
Next, the MDM had to fit Stripe’s automation workflows. The team focuses on infrastructure-as-code and wanted the MDM to integrate into existing workflows, not introduce another isolated tool. Stripe also prefers open-source tools because they offer more visibility into how the product works.
|
||||
|
||||
Finally, the MDM had to support on-premise deployment. Stripe didn’t consider cloud-only MDMs because they view MDM as critical infrastructure. With control over 10,000 Macs, they wanted full control over who could access the system.
|
||||
|
||||
## Choosing Fleet
|
||||
|
||||
During evaluation, Stripe needed to confirm that Fleet could handle their core MDM use cases, including Automated Device Enrollment and deploying security profiles.
|
||||
|
||||
Fleet met those requirements, but the open-source model gave Stripe additional confidence. Being able to see how profiles were built and deployed made them comfortable managing Macs with Fleet.
|
||||
|
||||
<div purpose="attribution-quote">
|
||||
|
||||
*The openness of the whole management stack … is more valuable to us.*
|
||||
|
||||
**Wes Whetstone**
|
||||
|
||||
Staff Client Platform Engineer
|
||||
</div>
|
||||
|
||||
When issues arise, Stripe can also inspect what went wrong themselves. Instead of uploading logs and waiting for a vendor response, they can typically identify where issues originate, which leads to faster resolutions.
|
||||
|
||||
Fleet’s API-first design let Stripe automate their entire MDM workflow. They migrated 10,000 Macs in 10 days, and custom profiles allowed them to set up Macs in video conferencing rooms with true zero-touch deployment — something their previous MDM could not support.
|
||||
|
||||
<div purpose="attribution-quote">
|
||||
|
||||
*We saved a couple of hundred thousand dollars a year.*
|
||||
|
||||
**Wes Whetstone**
|
||||
|
||||
Staff Client Platform Engineer
|
||||
</div>
|
||||
|
||||
## The results
|
||||
|
||||
Using Fleet as the MDM for Macs gives Stripe’s security and IT teams more control over a critical piece of infrastructure. It has removed manual work and allowed the team to build custom solutions, such as enabling remote screen sharing in meeting rooms without requiring someone on site. Core MDM capabilities are now a pillar of Stripe’s zero-trust device attestation.
|
||||
|
||||
Stripe is enthusiastic about Fleet’s support, stating that “[Fleet’s] customer success manager played a key role in the successful migration and rollout.”
|
||||
|
||||
Stripe also plans to evaluate the capabilities offered by Fleet’s open-source MDM for other platforms they manage, including Windows VMs and BYOD programs.
|
||||
|
||||
<div purpose="attribution-quote">
|
||||
|
||||
*Fleet’s Customer Success Manager for Stripe is the best!*
|
||||
|
||||
**Wes Whetstone**
|
||||
|
||||
Staff Client Platform Engineer
|
||||
</div>
|
||||
|
||||
<meta name="category" value="case study">
|
||||
<meta name="articleTitle" value="Stripe moved 10,000 Macs to Fleet, saving hundreds of thousands annually">
|
||||
|
||||
|
||||
<meta name="publishedOn" value="2025-12-11">
|
||||
<meta name="authorGitHubUsername" value="n/a">
|
||||
<meta name="authorFullName" value="Fleetdm">
|
||||
|
||||
<meta name="companyLogoFilename" value="stripe-logo-96x40@2x.png">
|
||||
<meta name="quoteAuthorImageFilename" value="wes-whetstone-120x120@2x.png">
|
||||
<meta name="quoteAuthorName" value="Wes Whetstone">
|
||||
<meta name="quoteAuthorJobTitle" value="Staff Client Platform Engineer">
|
||||
<meta name="quoteContent" value="“The ability to get heard [with our previous MDM] was just impossible.”">
|
||||
|
||||
<meta name="companyName" value="Stripe">
|
||||
<meta name="companyInfo" value="Stripe is a financial technology company that provides a developer-friendly platform for businesses to accept and manage online payments. It offers a broad set of financial infrastructure products, including tools for subscription management, fraud prevention, business incorporation, and issuing physical and virtual cards.">
|
||||
|
||||
<meta name="summaryChallenge" value="As a leading financial services provider, Stripe wanted more automation, transparency, and flexibility from its MDM. Their previous tool relied on manual processes, and slow support left the team dissatisfied.">
|
||||
<meta name="summarySolution" value="Stripe already used Fleet for device visibility with osquery. Fleet’s open-source, automation-first approach gave Stripe the transparency they wanted and let them replace manual tasks with automated scripts. The option to deploy Fleet on-prem also set it apart from other MDMs, many of which are cloud-first or cloud-only.">
|
||||
<meta name="summaryKeyResults" value="Seamless migration of 10,000 Macs in 10 days.; Saved “hundreds of thousands” each year in licensing costs.; Gained the ability to deploy custom profiles for full control, including setting up Macs in Zoom Rooms without user interaction.">
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
module.exports = {
|
||||
|
||||
|
||||
friendlyName: 'View case study',
|
||||
|
||||
|
||||
description: 'Display "Case study" page.',
|
||||
|
||||
inputs: {
|
||||
pageUrlSuffix : {
|
||||
description: 'The relative path to the case study article page from within this route.',
|
||||
example: 'case-study/foo',
|
||||
type: 'string',
|
||||
defaultsTo: ''
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
exits: {
|
||||
success: { viewTemplatePath: 'pages/articles/case-study' },
|
||||
badConfig: { responseType: 'badConfig' },
|
||||
notFound: { responseType: 'notFound' },
|
||||
redirect: { responseType: 'redirect' },
|
||||
},
|
||||
|
||||
|
||||
fn: async function ({pageUrlSuffix}) {
|
||||
|
||||
if (!_.isObject(sails.config.builtStaticContent) || !_.isArray(sails.config.builtStaticContent.markdownPages) || !sails.config.builtStaticContent.compiledPagePartialsAppPath) {
|
||||
throw {badConfig: 'builtStaticContent.markdownPages'};
|
||||
}
|
||||
|
||||
// Serve appropriate page content.
|
||||
let thisPage = _.find(sails.config.builtStaticContent.markdownPages, { url: this.req.path });
|
||||
if (!thisPage) {// If there's no EXACTLY matching content page, try a revised version of the URL suffix that's lowercase, with all slashes deduped, and any leading or trailing slash removed (leading slashes are only possible if this is a regex, rather than "/*" route)
|
||||
let revisedPageUrlSuffix = pageUrlSuffix.toLowerCase().replace(/\/+/g, '/').replace(/^\/+/,'').replace(/\/+$/,'');
|
||||
thisPage = _.find(sails.config.builtStaticContent.markdownPages, { url: '/' + revisedPageUrlSuffix });
|
||||
if (thisPage) {// If we matched a page with the revised suffix, then redirect to that rather than rendering it, so the URL gets cleaned up.
|
||||
throw {redirect: thisPage.url};
|
||||
} else {// If no page could be found even with the revised suffix, then throw a 404 error.
|
||||
throw 'notFound';
|
||||
}
|
||||
}
|
||||
// Setting the pages meta title and description from the articles meta tags.
|
||||
let pageTitleForMeta;
|
||||
if(thisPage.meta.articleTitle) {
|
||||
pageTitleForMeta = thisPage.meta.articleTitle;
|
||||
}//fi
|
||||
let pageDescriptionForMeta;
|
||||
if(thisPage.meta.description){
|
||||
pageDescriptionForMeta = thisPage.meta.description;
|
||||
}
|
||||
|
||||
// Set the currentSection variable for the website header to "customers"
|
||||
let currentSection = 'customers';
|
||||
|
||||
|
||||
// Respond with view.
|
||||
return {
|
||||
path: require('path'),
|
||||
thisPage: thisPage,
|
||||
markdownPages: sails.config.builtStaticContent.markdownPages,
|
||||
compiledPagePartialsAppPath: sails.config.builtStaticContent.compiledPagePartialsAppPath,
|
||||
pageTitleForMeta,
|
||||
pageDescriptionForMeta,
|
||||
currentSection,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 105 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 69 KiB |
@@ -0,0 +1,25 @@
|
||||
parasails.registerPage('case-study', {
|
||||
// ╦╔╗╔╦╔╦╗╦╔═╗╦ ╔═╗╔╦╗╔═╗╔╦╗╔═╗
|
||||
// ║║║║║ ║ ║╠═╣║ ╚═╗ ║ ╠═╣ ║ ║╣
|
||||
// ╩╝╚╝╩ ╩ ╩╩ ╩╩═╝ ╚═╝ ╩ ╩ ╩ ╩ ╚═╝
|
||||
data: {
|
||||
//…
|
||||
},
|
||||
|
||||
// ╦ ╦╔═╗╔═╗╔═╗╦ ╦╔═╗╦ ╔═╗
|
||||
// ║ ║╠╣ ║╣ ║ ╚╦╝║ ║ ║╣
|
||||
// ╩═╝╩╚ ╚═╝╚═╝ ╩ ╚═╝╩═╝╚═╝
|
||||
beforeMount: function() {
|
||||
//…
|
||||
},
|
||||
mounted: async function() {
|
||||
//…
|
||||
},
|
||||
|
||||
// ╦╔╗╔╔╦╗╔═╗╦═╗╔═╗╔═╗╔╦╗╦╔═╗╔╗╔╔═╗
|
||||
// ║║║║ ║ ║╣ ╠╦╝╠═╣║ ║ ║║ ║║║║╚═╗
|
||||
// ╩╝╚╝ ╩ ╚═╝╩╚═╩ ╩╚═╝ ╩ ╩╚═╝╝╚╝╚═╝
|
||||
methods: {
|
||||
//…
|
||||
}
|
||||
});
|
||||
@@ -60,6 +60,7 @@
|
||||
@import 'pages/docs/basic-documentation.less';
|
||||
@import 'pages/handbook/basic-handbook.less';
|
||||
@import 'pages/articles/basic-article.less';
|
||||
@import 'pages/articles/case-study.less';
|
||||
@import 'pages/articles/articles.less';
|
||||
@import 'pages/reports/state-of-device-management.less';
|
||||
@import 'pages/admin/email-templates.less';
|
||||
|
||||
@@ -0,0 +1,816 @@
|
||||
#case-study {
|
||||
h1 {
|
||||
font-size: 36px;
|
||||
}
|
||||
hr {
|
||||
margin-top: 64px;
|
||||
margin-bottom: 64px;
|
||||
border-top: 2px solid @core-vibrant-blue-15;
|
||||
width: 100%;
|
||||
}
|
||||
h2 {
|
||||
color: #192147;
|
||||
|
||||
/* Title M (FKA h3) */
|
||||
font-family: Inter;
|
||||
font-size: 24px;
|
||||
font-style: normal;
|
||||
font-weight: 800;
|
||||
line-height: 120%;
|
||||
}
|
||||
h3 {
|
||||
padding-top: 32px;
|
||||
color: #192147;
|
||||
|
||||
/* Title S (FKA h4) */
|
||||
font-family: Inter;
|
||||
font-size: 20px;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
line-height: 24px; /* 120% */
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
h4 {
|
||||
color: #192147;
|
||||
|
||||
/* Title XS */
|
||||
font-family: Inter;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
line-height: 19.2px; /* 120% */
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
[purpose='page-content'] {
|
||||
max-width: 1072px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
[purpose='page-container'] {
|
||||
padding: 64px;
|
||||
}
|
||||
|
||||
[purpose='article-title-and-quote'] {
|
||||
max-width: 663px;
|
||||
margin-bottom: 64px;
|
||||
}
|
||||
[purpose='article-title'] {
|
||||
h1 {
|
||||
color: #192147;
|
||||
|
||||
/* Title XL (FKA h1) */
|
||||
font-family: Inter;
|
||||
font-size: 48px;
|
||||
font-style: normal;
|
||||
font-weight: 800;
|
||||
line-height: 57.6px; /* 120% */
|
||||
}
|
||||
}
|
||||
[purpose='case-study-logo'] {
|
||||
margin-bottom: 24px;
|
||||
img {
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
[purpose='case-study-quote'] {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding-top: 48px;
|
||||
padding-bottom: 48px;
|
||||
[purpose='quote-author-image'] {
|
||||
margin-right: 24px;
|
||||
img {
|
||||
height: 120px;
|
||||
}
|
||||
}
|
||||
[purpose='quote-text'] {
|
||||
color: #515774;
|
||||
font-size: 20px;
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
line-height: 30px; /* 150% */
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
[purpose='quote-author-name'] {
|
||||
color: #515774;
|
||||
|
||||
/* Body SM (bold) */
|
||||
font-family: Inter;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
line-height: 21px; /* 150% */
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
[purpose='quote-author-job-title'] {
|
||||
color: #515774;
|
||||
|
||||
/* Body SM (FKA Card text) */
|
||||
font-family: Inter;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 20px; /* 142.857% */
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[purpose='summary'] {
|
||||
margin-bottom: 32px;
|
||||
border-radius: 16px;
|
||||
border: 1px solid #E2E4EA;
|
||||
background: #FFF;
|
||||
padding: 0 32px 32px 32px;
|
||||
ul {
|
||||
margin-bottom: 0px;
|
||||
list-style-type: none;
|
||||
padding-left: 0px;
|
||||
li {
|
||||
font-size: 16px;
|
||||
line-height: 150%;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
padding-left: 40px;
|
||||
text-indent: -40px;
|
||||
margin-bottom: 0px;
|
||||
padding-top: 16px;
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
li::before {
|
||||
content: ' ';
|
||||
background-image: url('/images/icon-checkbox-checked-24x24@2x.png');
|
||||
background-size: 24px 24px;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
top: 7px;
|
||||
margin-right: 16px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[purpose='right-sidebar'] {
|
||||
margin-top: 16px;
|
||||
margin-left: 64px;
|
||||
width: 343px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
[purpose='sidebar-link'] {
|
||||
margin-bottom: 12px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
color: #515774;
|
||||
text-decoration: none;
|
||||
img {
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
display: inline;
|
||||
margin-right: 12px;
|
||||
}
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
color: @core-fleet-black;
|
||||
img {
|
||||
filter: brightness(0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
[purpose='edit-link'] {
|
||||
padding-top: 24px;
|
||||
padding-bottom: 16px;
|
||||
margin-top: 24px;
|
||||
border-top: 1px solid #E2E4EA;
|
||||
a {
|
||||
text-decoration: none;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
}
|
||||
[purpose='article-container'] {
|
||||
max-width: 663px;
|
||||
padding-right: 0px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0px;
|
||||
}
|
||||
|
||||
[purpose='company-information'] {
|
||||
p {
|
||||
margin-bottom: 40px;
|
||||
color: #515774;
|
||||
|
||||
/* Body MD (FKA p) */
|
||||
font-family: Inter;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 24px; /* 150% */
|
||||
}
|
||||
}
|
||||
[purpose='case-study-links'] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
[purpose='case-study-link'] {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding: 8px;
|
||||
align-items: center;
|
||||
text-decoration: none;
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
border-radius: 4px;
|
||||
background: #f6f7f8;
|
||||
}
|
||||
[purpose='link-image'] {
|
||||
margin-right: 16px;
|
||||
img {
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
[purpose='link-text'] {
|
||||
p {
|
||||
margin-bottom: 0px;
|
||||
color: #515774;
|
||||
font-family: Inter;
|
||||
font-size: 12px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 18px; /* 150% */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
[purpose='article-content'] {
|
||||
word-wrap: break-word;
|
||||
h1:first-of-type {
|
||||
display: none;
|
||||
}
|
||||
img {
|
||||
max-width: 100%;
|
||||
width: auto;
|
||||
height: auto;
|
||||
max-height: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding: 24px 0px 16px 0px;
|
||||
}
|
||||
h2 {
|
||||
font-size: 24px;
|
||||
margin-top: 64px;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
h3 {
|
||||
font-size: 20px;
|
||||
margin-top: 48px;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
h4 {
|
||||
font-size: 16px;
|
||||
margin-top: 24px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
h2 > code:not(.bash):not(.nohighlight):not(.mermaid) {
|
||||
padding: 0px 4px;
|
||||
font-weight: 400;
|
||||
font-size: 22px;
|
||||
line-height: inherit;
|
||||
}
|
||||
h3 > code:not(.bash):not(.nohighlight):not(.mermaid) {
|
||||
padding: 0px 4px;
|
||||
font-weight: 400;
|
||||
font-size: 18px;
|
||||
line-height: inherit;
|
||||
}
|
||||
p {
|
||||
font-size: 16px;
|
||||
line-height: 150%;
|
||||
color: #515774;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
img + em { // Image captions
|
||||
position: relative;
|
||||
top: -12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
ul, ol {
|
||||
padding-left: 16px;
|
||||
}
|
||||
li {
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
li::marker {
|
||||
color: @core-vibrant-blue;
|
||||
}
|
||||
.markdown-heading {
|
||||
scroll-margin-top: 140px;
|
||||
}
|
||||
[purpose='checklist-item'] {
|
||||
display: flex;
|
||||
input[type='checkbox'] {
|
||||
margin-left: -18px;
|
||||
min-width: 16px;
|
||||
min-height: 16px;
|
||||
align-self: center;
|
||||
}
|
||||
input:checked, input:active {
|
||||
accent-color: @core-vibrant-blue;
|
||||
}
|
||||
[purpose='task'] {
|
||||
margin-left: 16px;
|
||||
input {
|
||||
display: none;
|
||||
}
|
||||
p {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
[purpose='checklist-item']::marker {
|
||||
display: none;
|
||||
}
|
||||
ul {
|
||||
list-style-type: disc;
|
||||
padding-left: 16px;
|
||||
}
|
||||
li {
|
||||
line-height: 24px;
|
||||
padding-bottom: 16px;
|
||||
p { // Making sure our list items stay a consistent size if the contents get wrapped in a <p> tag coverted from Markdown.
|
||||
margin-bottom: 0;
|
||||
}
|
||||
ol, ul { // adding padding to nested lists
|
||||
padding-top: 16px;
|
||||
li:last-child { // removing the padding from the last item of nested lists
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
ol {
|
||||
counter-reset: custom-counter;
|
||||
list-style-type: none;
|
||||
padding-inline-start: 0px;
|
||||
padding: 0;
|
||||
margin-top: 16px;
|
||||
margin-bottom: 20px;
|
||||
ul > li {
|
||||
text-indent: 0px;
|
||||
margin-left: 0px;
|
||||
}
|
||||
> li {
|
||||
counter-increment: custom-counter;
|
||||
margin-left: 36px;
|
||||
text-indent: -36px;
|
||||
padding-left: 0px;
|
||||
margin-bottom: 16px;
|
||||
code:not(.nohighlight):not(.mermaid) {
|
||||
display: inline;
|
||||
}
|
||||
p {
|
||||
display: inline;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
blockquote {
|
||||
text-indent: 0px;
|
||||
}
|
||||
}
|
||||
> li::before {
|
||||
content: counter(custom-counter);
|
||||
background-color: #E2E4EA;
|
||||
width: 24px;
|
||||
font-size: 13px;
|
||||
display: inline-block;
|
||||
border-radius: 50%;
|
||||
margin-right: 10px;
|
||||
padding: 2px 4px;
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
text-indent: 0px;
|
||||
}
|
||||
}
|
||||
a > code:not(.hljs):not(.nohighlight):not(.mermaid) {
|
||||
color: inherit;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
code:not(.bash):not(.hljs):not(.nohighlight):not(.mermaid) {
|
||||
background: #F1F0FF;
|
||||
padding: 4px 8px;
|
||||
font-family: @code-font;
|
||||
font-size: 13px;
|
||||
line-height: 16px;
|
||||
color: @core-fleet-black;
|
||||
}
|
||||
pre {
|
||||
code {
|
||||
background: none;
|
||||
padding: 0px;
|
||||
font-family: @code-font;
|
||||
font-size: 13px;
|
||||
line-height: 16px;
|
||||
color: @core-fleet-black;
|
||||
}
|
||||
padding: 24px;
|
||||
border: 1px solid #E2E4EA;
|
||||
border-radius: 6px;
|
||||
margin: 0px 0px 40px;
|
||||
font-family: @code-font;
|
||||
background: #F9FAFC;
|
||||
white-space: break-spaces;
|
||||
}
|
||||
code.mermaid:not([data-processed='true']) {
|
||||
opacity: 0;
|
||||
}
|
||||
code.mermaid {
|
||||
color: @core-fleet-black-75;
|
||||
margin-bottom: 16px 0px 32px;
|
||||
font-family: @code-font;
|
||||
display: inline-block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
background: #fff;
|
||||
svg {
|
||||
max-height: 600px;
|
||||
}
|
||||
}
|
||||
blockquote {
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
[purpose='quote'] {
|
||||
margin: 72px 0 32px 0px;
|
||||
font-style: italic;
|
||||
line-height: 150%;
|
||||
font-size: 20px;
|
||||
max-width: 640px;
|
||||
p {
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
[purpose='large-quote'] {
|
||||
margin: 72px 0 32px 0px;
|
||||
font-style: italic;
|
||||
line-height: 150%;
|
||||
margin-bottom: 24px;
|
||||
font-size: 16px;
|
||||
p:last-of-type {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
strong {
|
||||
color: #515774;
|
||||
font-family: Inter;
|
||||
font-size: 12px;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
line-height: 18px;
|
||||
}
|
||||
}
|
||||
[purpose='large-quote']::before, [purpose='quote']::before {
|
||||
content: ' ';
|
||||
background-image: url('/images/icon-quote-21x17@2x.png');
|
||||
background-repeat: no-repeat;
|
||||
background-size: 21px 17px;
|
||||
display: block;
|
||||
position: relative;
|
||||
top: -16px;
|
||||
left: 0px;
|
||||
width: 21px;
|
||||
height: 17px;
|
||||
}
|
||||
[purpose='attribution-quote'], [purpose='large-quote'] {
|
||||
margin: 64px 0 32px 0px;
|
||||
p:first-of-type {
|
||||
font-style: italic;
|
||||
line-height: 150%;
|
||||
margin-bottom: 24px;
|
||||
font-size: 20px;
|
||||
}
|
||||
p {
|
||||
font-size: 14px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
strong {
|
||||
color: #515774;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
line-height: 18px;
|
||||
}
|
||||
}
|
||||
[purpose='attribution-quote'] {
|
||||
margin: 80px 0px;
|
||||
padding-top: 15px;
|
||||
}
|
||||
[purpose='attribution-quote']:last-of-type {
|
||||
margin: 80px 0px;
|
||||
}
|
||||
[purpose='attribution-quote']::before {
|
||||
content: ' ';
|
||||
background-image: url('/images/icon-quote-21x17@2x.png');
|
||||
background-repeat: no-repeat;
|
||||
background-size: 21px 17px;
|
||||
display: block;
|
||||
position: relative;
|
||||
top: -16px;
|
||||
left: 0px;
|
||||
width: 21px;
|
||||
height: 17px;
|
||||
}
|
||||
[purpose='checklist'] {
|
||||
margin-bottom: 32px;
|
||||
p {
|
||||
font-size: 16px;
|
||||
line-height: 150%;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
padding-left: 40px;
|
||||
text-indent: -40px;
|
||||
margin-bottom: 0px;
|
||||
padding-top: 12px;
|
||||
padding-bottom: 12px;
|
||||
&:last-of-type {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
}
|
||||
p::before {
|
||||
content: ' ';
|
||||
background-image: url('/images/icon-checkbox-checked-24x24@2x.png');
|
||||
background-size: 24px 24px;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
top: 7px;
|
||||
margin-right: 16px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
}
|
||||
[purpose='tip'] {
|
||||
margin: 16px 0 32px;
|
||||
background: #F7F7FC;
|
||||
border: 1px solid @core-vibrant-blue-50;
|
||||
padding: 16px;
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
img {
|
||||
display: flex;
|
||||
margin: 4px 12px 0 0;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
padding: 0px;
|
||||
}
|
||||
p {
|
||||
display: block;
|
||||
margin-bottom: 16px;
|
||||
line-height: 24px;
|
||||
font-size: 16px;
|
||||
}
|
||||
p:only-child, p:last-child {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
ul:last-child {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
li:last-child {
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
}
|
||||
table {
|
||||
table-layout: auto;
|
||||
border: 1px solid @border-lt-gray;
|
||||
border-collapse: collapse;
|
||||
font-size: 16px;
|
||||
line-height: 28px;
|
||||
margin-bottom: 16px;
|
||||
max-width: 100%;
|
||||
th {
|
||||
font-weight: @bold;
|
||||
border: 1px solid @border-lt-gray;
|
||||
padding: 8px 7px 7px 8px;
|
||||
}
|
||||
td {
|
||||
border: 1px solid @border-lt-gray;
|
||||
padding: 8px 7px 7px 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[purpose='about-fleet-section'] {
|
||||
h2 {
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
p {
|
||||
margin-bottom: 32px;
|
||||
line-height: 150%;
|
||||
}
|
||||
}
|
||||
[purpose='button-row'] {
|
||||
margin-top: 48px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: start;
|
||||
align-items: center;
|
||||
a {
|
||||
font-weight: 700;
|
||||
font-size: 14px;
|
||||
text-decoration: none;
|
||||
}
|
||||
[purpose='cta-button'] {
|
||||
cursor: pointer;
|
||||
margin-right: 32px;
|
||||
background: @core-vibrant-green;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
height: 36px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: #FFF;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
[purpose='cta-button']::before {
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
opacity: 1;
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -5px;
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
transform: skew(-10deg);
|
||||
transition: left 0.5s ease-in, opacity 0.50s ease-in, width 0.5s ease-in;
|
||||
}
|
||||
[purpose='cta-button']:hover:before {
|
||||
left: 160px;
|
||||
width: 110%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 991px) {
|
||||
[purpose='page-container'] {
|
||||
padding: 64px 32px;
|
||||
}
|
||||
[purpose='right-sidebar'] {
|
||||
margin-left: 40px;
|
||||
}
|
||||
[purpose='article-title-and-quote'] {
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
[purpose='article-container'] {
|
||||
max-width: 100%;
|
||||
padding-right: 0px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
[purpose='summary'] {
|
||||
padding: 0 24px 16px 24px;
|
||||
}
|
||||
[purpose='article-content'] {
|
||||
[purpose='attribution-quote'] {
|
||||
text-align: center;
|
||||
margin: 64px 0px;
|
||||
&::before {
|
||||
height: 0px;
|
||||
background: none;
|
||||
display: none;
|
||||
}
|
||||
&:last-of-type {
|
||||
margin-bottom: 96px;
|
||||
}
|
||||
p:first-of-type {
|
||||
font-style: italic;
|
||||
line-height: 150%;
|
||||
margin-bottom: 16px;
|
||||
font-size: 16px;
|
||||
}
|
||||
p {
|
||||
font-size: 12px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
strong {
|
||||
color: #515774;
|
||||
font-size: 12px;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
line-height: 18px;
|
||||
}
|
||||
}
|
||||
[purpose='attribution-quote'] + h2 {
|
||||
margin-top: 128px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
[purpose='article-title'] {
|
||||
h1 {
|
||||
font-size: 32px;
|
||||
line-height: 120%;
|
||||
}
|
||||
}
|
||||
[purpose='page-container'] {
|
||||
padding: 48px 24px;
|
||||
|
||||
}
|
||||
[purpose='page-content'] {
|
||||
max-width: 560px;
|
||||
}
|
||||
[purpose='case-study-quote'] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-top: 48px;
|
||||
padding-bottom: 64px;
|
||||
[purpose='quote-author-image'] {
|
||||
margin-right: 32px;
|
||||
}
|
||||
[purpose='quote-text'] {
|
||||
font-size: 16px;
|
||||
line-height: 150%; /* 150% */
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
}
|
||||
[purpose='company-information'] {
|
||||
h2 {
|
||||
margin-top: 32px;
|
||||
margin-bottom: 16px;
|
||||
color: #192147;
|
||||
font-family: Inter;
|
||||
font-size: 24px;
|
||||
font-style: normal;
|
||||
font-weight: 800;
|
||||
line-height: 120%; /* 120% */
|
||||
}
|
||||
p {
|
||||
margin-bottom: 0px;
|
||||
color: #515774;
|
||||
|
||||
/* Body MD (FKA p) */
|
||||
font-family: Inter;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 24px; /* 150% */
|
||||
}
|
||||
}
|
||||
[purpose='right-sidebar'] {
|
||||
margin-top: 40px;
|
||||
}
|
||||
[purpose='about-fleet-section'] {
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
[purpose='bottom-case-study-links'] {
|
||||
margin-top: 32px;
|
||||
padding-top: 32px;
|
||||
border-top: 1px solid #E2E4EA;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
[purpose='article-content'] {
|
||||
img {
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
img + em { // Image captions
|
||||
top: 4px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@media (max-width: 575px) {
|
||||
[purpose='page-container'] {
|
||||
padding: 32px 24px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 375px) {
|
||||
[purpose='page-container'] {
|
||||
padding: 32px 16px;
|
||||
}
|
||||
[purpose='case-study-quote'] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
[purpose='quote-author-image'] {
|
||||
margin-right: 0px;
|
||||
margin-bottom: 16px;
|
||||
img {
|
||||
height: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -162,6 +162,14 @@ module.exports.routes = {
|
||||
}
|
||||
},// handles /success-stores/foo
|
||||
|
||||
'GET /case-study/*': {
|
||||
skipAssets: false,
|
||||
action: 'articles/view-case-study',// Meta title and description set in view action
|
||||
locals: {
|
||||
currentSection: 'customers',
|
||||
}
|
||||
},// handles /case-study/foo
|
||||
|
||||
'GET /securing': {
|
||||
skipAssets: false,
|
||||
action: 'articles/view-articles',// Meta title and description set in view action
|
||||
|
||||
@@ -651,7 +651,7 @@ module.exports = {
|
||||
throw new Error(`Failed compiling markdown content: An article page is missing a category meta tag (<meta name="category" value="guides">) at "${path.join(topLvlRepoPath, pageSourcePath)}". To resolve, add a meta tag with the category of the article`);
|
||||
} else {
|
||||
// Throwing an error if the article has an invalid category.
|
||||
let validArticleCategories = ['deploy', 'articles', 'security', 'engineering', 'success stories', 'announcements', 'guides', 'releases', 'podcasts', 'report' ];
|
||||
let validArticleCategories = ['deploy', 'articles', 'security', 'engineering', 'success stories', 'announcements', 'guides', 'releases', 'podcasts', 'report', 'case study' ];
|
||||
if(!validArticleCategories.includes(embeddedMetadata.category)) {
|
||||
throw new Error(`Failed compiling markdown content: An article page has an invalid category meta tag (<meta name="category" value="${embeddedMetadata.category}">) at "${path.join(topLvlRepoPath, pageSourcePath)}". To resolve, change the meta tag to a valid category, one of: ${validArticleCategories}`);
|
||||
}
|
||||
@@ -691,11 +691,57 @@ module.exports = {
|
||||
throw new Error(`Failed compiling markdown content: An article page has an invalid showOnTestimonialsPageWithEmoji meta tag (<meta name="showOnTestimonialsPageWithEmoji" value="${embeddedMetadata.articleImageUrl}">) at "${path.join(topLvlRepoPath, pageSourcePath)}". To resolve, change the value of the meta tag to be one of 🥀, 🔌, 🚪, or 🪟 and try running this script again.`);
|
||||
}
|
||||
}
|
||||
if(embeddedMetadata.category === 'case study') {
|
||||
// Note: Case study articles use a page template that requires additional meta tags.
|
||||
if(!embeddedMetadata.summaryChallenge){
|
||||
throw new Error(`Failed compiling markdown content: A case study article is missing a "summaryChallenge" meta tag at ${path.join(topLvlRepoPath, pageSourcePath)}. To resolve, add a summaryChallenge meta tag and try running this script again.`);
|
||||
}
|
||||
|
||||
if(!embeddedMetadata.summarySolution){
|
||||
throw new Error(`Failed compiling markdown content: A case study article is missing a "summarySolution" meta tag at ${path.join(topLvlRepoPath, pageSourcePath)}. To resolve, add a summarySolution meta tag and try running this script again.`);
|
||||
}
|
||||
|
||||
if(!embeddedMetadata.summaryKeyResults){
|
||||
throw new Error(`Failed compiling markdown content: A case study article is missing a "summaryKeyResults" meta tag at ${path.join(topLvlRepoPath, pageSourcePath)}. To resolve, add a summaryKeyResults meta tag and try running this script again.`);
|
||||
} else if(embeddedMetadata.summaryKeyResults.split(';').length === 1) {
|
||||
// Make sure that summaryKeyResults meta tag values are semicolon-separated lists.
|
||||
throw new Error(`Failed compiling markdown content: A case study article has an invalid "summaryKeyResults" meta tag value at ${path.join(topLvlRepoPath, pageSourcePath)}. To resolve, change the summaryKeyResults meta tag value to be a list of results separated by semi-colons (e.g., "Cut endpoint maintenance effort by 50%; Reduced licensing costs by 21%;") and try running this script again.`);
|
||||
}
|
||||
|
||||
// If a companyLogoFilename meta tag is provided, make sure the image exists in the website/assets/images folder.
|
||||
if(embeddedMetadata.companyLogoFilename) {
|
||||
let companyLogoImageExists = await sails.helpers.fs.exists(path.join(topLvlRepoPath, 'website/assets/images/'+embeddedMetadata.companyLogoFilename));
|
||||
if(!companyLogoImageExists){
|
||||
throw new Error(`Failed compiling markdown content: A case study article (${path.join(topLvlRepoPath, pageSourcePath)}) has a "companyLogoFilename" meta tag value that references an image that is not in the website/assets/images folder (${path.join(topLvlRepoPath, 'website/assets/images/'+embeddedMetadata.companyLogoFilename)}). Was it moved?`);
|
||||
}
|
||||
}
|
||||
|
||||
if(embeddedMetadata.quoteContent) {
|
||||
// If a quoteContent meta tag is provided, make sure that the article has quoteAuthorName, quoteAuthorJobTitle, and quoteAuthorImageFilename meta tags.
|
||||
if(!embeddedMetadata.quoteAuthorName) {
|
||||
throw new Error(`Failed compiling markdown content: A case study article is missing a "quoteAuthorName" meta tag at ${path.join(topLvlRepoPath, pageSourcePath)}. To resolve, add a quoteAuthorName meta tag and try running this script again.`);
|
||||
}
|
||||
|
||||
if(!embeddedMetadata.quoteAuthorJobTitle) {
|
||||
throw new Error(`Failed compiling markdown content: A case study article is missing a "quoteAuthorJobTitle" meta tag at ${path.join(topLvlRepoPath, pageSourcePath)}. To resolve, add a quoteAuthorJobTitle meta tag and try running this script again.`);
|
||||
}
|
||||
|
||||
if(!embeddedMetadata.quoteAuthorImageFilename) {
|
||||
throw new Error(`Failed compiling markdown content: A case study article is missing a "quoteAuthorImageFilename" meta tag at ${path.join(topLvlRepoPath, pageSourcePath)}. To resolve, add a quoteAuthorImageFilename meta tag and try running this script again.`);
|
||||
} else {
|
||||
// If a quoteAuthorImageFilename meta tag is provided, make sure the file exists.
|
||||
let quoteAuthorImageExists = await sails.helpers.fs.exists(path.join(topLvlRepoPath, 'website/assets/images/'+embeddedMetadata.quoteAuthorImageFilename));
|
||||
if(!quoteAuthorImageExists){
|
||||
throw new Error(`Failed compiling markdown content: A case study article (${path.join(topLvlRepoPath, pageSourcePath)}) has a "quoteAuthorImageFilename" meta tag value that references an image that is not in the website/assets/images folder (${path.join(topLvlRepoPath, 'website/assets/images/'+embeddedMetadata.quoteAuthorImageFilename)}). Was it moved?`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// For article pages, we'll attach the category to the `rootRelativeUrlPath`.
|
||||
// If the article is categorized as 'product' we'll replace the category with 'use-cases', or if it is categorized as 'success story' we'll replace it with 'device-management'
|
||||
rootRelativeUrlPath = (
|
||||
'/' +
|
||||
(encodeURIComponent(embeddedMetadata.category === 'success stories' ? 'success-stories' : embeddedMetadata.category === 'security' ? 'securing' : embeddedMetadata.category)) + '/' +
|
||||
(encodeURIComponent(embeddedMetadata.category === 'success stories' ? 'success-stories' : embeddedMetadata.category === 'security' ? 'securing' : embeddedMetadata.category === 'case study' ? 'case-study' : embeddedMetadata.category)) + '/' +
|
||||
(pageUnextensionedUnwhitespacedLowercasedRelPath.split(/\//).map((fileOrFolderName) => encodeURIComponent(fileOrFolderName.replace(/^[0-9]+[\-]+/,'').replace(/\./g, '-'))).join('/'))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -232,22 +232,22 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="mobileNavbarToggleCustomers" purpose="mobile-dropdown" class="collapse align-items-start">
|
||||
<a purpose="dropdown-item" class="dropdown-item" data-dropdown-option="Stripe + Fleet" href="/announcements/consolidate-multiple-tools-with-fleet">
|
||||
<a purpose="dropdown-item" class="dropdown-item" data-dropdown-option="Stripe + Fleet" href="/case-study/stripe">
|
||||
<div purpose="dropdown-item-link">
|
||||
<div purpose="dropdown-item-icon">
|
||||
<img src="/images/nav-icon-testimonials-40x40@2x.png" alt="Fintech + Fleet">
|
||||
<img src="/images/nav-icon-stripe-40x40@2x.png" alt="Fintech + Fleet">
|
||||
</div>
|
||||
<div purpose="dropdown-item-text">
|
||||
<p purpose="nav-item-heading">
|
||||
Fintech + Fleet
|
||||
Stripe + Fleet
|
||||
</p>
|
||||
<p purpose="nav-item-body">
|
||||
Fintech giant consolidates multiple tools with Fleet.
|
||||
Stripe moved 10,000 Macs to Fleet, saving hundreds of thousands annually
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<a purpose="dropdown-item" class="dropdown-item" data-dropdown-option="Foursquare + Fleet" href="/announcements/foursquare-quickly-migrates-to-fleet">
|
||||
<a purpose="dropdown-item" class="dropdown-item" data-dropdown-option="Foursquare + Fleet" href="/case-study/foursquare">
|
||||
<div purpose="dropdown-item-link">
|
||||
<div purpose="dropdown-item-icon">
|
||||
<img src="/images/nav-icon-foursquare-40x40@2x.png" alt="Foursquare + Fleet">
|
||||
@@ -264,6 +264,23 @@
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<a purpose="dropdown-item" class="dropdown-item" data-dropdown-option="Faire + Fleet" href="/case-study/faire">
|
||||
<div purpose="dropdown-item-link">
|
||||
<div purpose="dropdown-item-icon">
|
||||
<img src="/images/nav-icon-faire-40x40@2x.png" alt="Faire + Fleet">
|
||||
</div>
|
||||
<div purpose="dropdown-item-text">
|
||||
<div purpose="dropdown-item-text">
|
||||
<p purpose="nav-item-heading">
|
||||
Faire + Fleet
|
||||
</p>
|
||||
<p purpose="nav-item-body">
|
||||
Faire secures Macs with CIS benchmarks and Fleet
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<a purpose="dropdown-item" class="dropdown-item" data-dropdown-option="What people are saying" href="/testimonials">
|
||||
<div purpose="dropdown-item-link">
|
||||
<div purpose="dropdown-item-icon">
|
||||
@@ -504,22 +521,22 @@
|
||||
|
||||
<div purpose="header-dropdown" class="dropdown-menu customers-dropdown">
|
||||
|
||||
<a purpose="dropdown-item" class="dropdown-item" data-dropdown-option="Stripe + Fleet" href="/announcements/consolidate-multiple-tools-with-fleet">
|
||||
<a purpose="dropdown-item" class="dropdown-item" data-dropdown-option="Stripe + Fleet" href="/case-study/stripe">
|
||||
<div purpose="dropdown-item-link">
|
||||
<div purpose="dropdown-item-icon">
|
||||
<img src="/images/nav-icon-testimonials-40x40@2x.png" alt="Stripe + Fleet">
|
||||
<img src="/images/nav-icon-stripe-40x40@2x.png" alt="Stripe + Fleet">
|
||||
</div>
|
||||
<div purpose="dropdown-item-text">
|
||||
<p purpose="nav-item-heading">
|
||||
Fintech + Fleet
|
||||
Stripe + Fleet
|
||||
</p>
|
||||
<p purpose="nav-item-body">
|
||||
Fintech giant consolidates multiple tools with Fleet.
|
||||
Stripe moved 10,000 Macs to Fleet, saving hundreds of thousands annually
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<a purpose="dropdown-item" class="dropdown-item" data-dropdown-option="Foursquare + Fleet" href="/announcements/foursquare-quickly-migrates-to-fleet">
|
||||
<a purpose="dropdown-item" class="dropdown-item" data-dropdown-option="Foursquare + Fleet" href="/case-study/foursquare">
|
||||
<div purpose="dropdown-item-link">
|
||||
<div purpose="dropdown-item-icon">
|
||||
<img src="/images/nav-icon-foursquare-40x40@2x.png" alt="Foursquare + Fleet">
|
||||
@@ -530,7 +547,24 @@
|
||||
Foursquare + Fleet
|
||||
</p>
|
||||
<p purpose="nav-item-body">
|
||||
Foursquare quickly migrates to Fleet for device management.
|
||||
Foursquare cut costs and gained 114% ROI with Fleet
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<a purpose="dropdown-item" class="dropdown-item" data-dropdown-option="Foursquare + Fleet" href="/case-study/faire">
|
||||
<div purpose="dropdown-item-link">
|
||||
<div purpose="dropdown-item-icon">
|
||||
<img src="/images/nav-icon-faire-40x40@2x.png" alt="Faire + Fleet">
|
||||
</div>
|
||||
<div purpose="dropdown-item-text">
|
||||
<div purpose="dropdown-item-text">
|
||||
<p purpose="nav-item-heading">
|
||||
Faire + Fleet
|
||||
</p>
|
||||
<p purpose="nav-item-body">
|
||||
Faire secures Macs with CIS benchmarks and Fleet
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -901,6 +935,7 @@
|
||||
<script src="/js/pages/app-library.page.js"></script>
|
||||
<script src="/js/pages/articles/articles.page.js"></script>
|
||||
<script src="/js/pages/articles/basic-article.page.js"></script>
|
||||
<script src="/js/pages/articles/case-study.page.js"></script>
|
||||
<script src="/js/pages/command-details.page.js"></script>
|
||||
<script src="/js/pages/configuration-builder.page.js"></script>
|
||||
<script src="/js/pages/connect-vanta.page.js"></script>
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
<div id="case-study" v-cloak>
|
||||
<div purpose="page-container">
|
||||
<div purpose="page-content">
|
||||
<div purpose="article-title-and-quote">
|
||||
<div purpose="article-title">
|
||||
<div purpose="case-study-logo" v-if="thisPage.meta.companyLogoFilename"><img alt="Logo" src="/images/<%=thisPage.meta.companyLogoFilename %>"></div>
|
||||
<h1><%=thisPage.meta.articleTitle %></h1>
|
||||
</div>
|
||||
<div purpose="case-study-quote" v-if="thisPage.meta.quoteContent">
|
||||
<div purpose="quote-author-image">
|
||||
<img alt="<%= thisPage.meta.quoteAuthorName %>" src="/images/<%= thisPage.meta.quoteAuthorImageFilename %>">
|
||||
</div>
|
||||
<div purpose="quote" >
|
||||
<p purpose="quote-text"><%= thisPage.meta.quoteContent %></p>
|
||||
<p purpose="quote-author-name"><%= thisPage.meta.quoteAuthorName %></p>
|
||||
<p purpose="quote-author-job-title"><%= thisPage.meta.quoteAuthorJobTitle %></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div purpose="summary-and-sidebar" class="d-flex flex-row justify-content-between">
|
||||
<div purpose="summary">
|
||||
<h3>Challenge</h3>
|
||||
<p><%= thisPage.meta.summaryChallenge %></p>
|
||||
<h3>Solution</h3>
|
||||
<p><%= thisPage.meta.summarySolution %></p>
|
||||
<h3>Key results</h3>
|
||||
<ul>
|
||||
<% for(let result of thisPage.meta.summaryKeyResults.split('; ')){%>
|
||||
<li><%=result %></li>
|
||||
<% }%>
|
||||
</ul>
|
||||
</div>
|
||||
<div purpose="sidebar-container" class="d-md-flex d-none">
|
||||
<div purpose="right-sidebar" class="d-flex flex-column">
|
||||
<div class="d-md-flex d-none flex-column order-lg-2 order-1">
|
||||
<div purpose="company-information" v-if="thisPage.meta.companyName && thisPage.meta.companyInfo">
|
||||
<h4>About <%= thisPage.meta.companyName %></h4>
|
||||
<p>
|
||||
<%= thisPage.meta.companyInfo %>
|
||||
</p>
|
||||
<p v-if="thisPage.meta.companyInfoLineTwo">
|
||||
<%= thisPage.meta.companyInfoLineTwo %>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4>More customer stories</h4>
|
||||
<div purpose="case-study-links" >
|
||||
<a href="/case-study/foursquare" purpose="case-study-link" v-if="thisPage.url !== '/case-study/foursquare'">
|
||||
<div purpose="link-image">
|
||||
<img alt="Foursquare" src="/images/nav-icon-foursquare-40x40@2x.png">
|
||||
</div>
|
||||
<div purpose="link-text">
|
||||
<p><strong>Foursquare</strong></p>
|
||||
<p>Foursquare cut costs and gained 114% ROI with Fleet</p>
|
||||
</div>
|
||||
</a>
|
||||
<a href="/case-study/stripe" purpose="case-study-link" v-if="thisPage.url !== '/case-study/stripe'">
|
||||
<div purpose="link-image">
|
||||
<img alt="Stripe" src="/images/nav-icon-stripe-40x40@2x.png">
|
||||
</div>
|
||||
<div purpose="link-text">
|
||||
<p><strong>Stripe</strong></p>
|
||||
<p>Stripe moved 10,000 Macs to Fleet, saving hundreds of thousands annually</p>
|
||||
</div>
|
||||
</a>
|
||||
<a href="/case-study/faire" purpose="case-study-link" v-if="thisPage.url !== '/case-study/faire'">
|
||||
<div purpose="link-image">
|
||||
<img alt="Faire" src="/images/nav-icon-faire-40x40@2x.png">
|
||||
</div>
|
||||
<div purpose="link-text">
|
||||
<p><strong>Faire</strong></p>
|
||||
<p>Faire keeps Macs secure with CIS benchmarks using Fleet</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div purpose="edit-link">
|
||||
<a purpose="sidebar-link" :href="'https://github.com/fleetdm/fleet/edit/main/articles/'+thisPage.sectionRelativeRepoPath"> <img src="/images/icon-edit-16x16@2x.png" alt="Suggest an edit">Suggest an edit</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div purpose="article-container">
|
||||
<div class="d-block d-md-none" purpose="company-information" v-if="thisPage.meta.companyName && thisPage.meta.companyInfo">
|
||||
<h2>About <%= thisPage.meta.companyName %></h2>
|
||||
<p>
|
||||
<%= thisPage.meta.companyInfo %>
|
||||
</p>
|
||||
<p v-if="thisPage.meta.companyInfoLineTwo">
|
||||
<%= thisPage.meta.companyInfoLineTwo %>
|
||||
</p>
|
||||
</div>
|
||||
<div purpose="article-content" parasails-has-no-page-script>
|
||||
<%- partial(path.relative(path.dirname(__filename), path.resolve( sails.config.appPath, path.join(sails.config.builtStaticContent.compiledPagePartialsAppPath, thisPage.htmlId)))) %>
|
||||
<hr>
|
||||
</div>
|
||||
<div purpose="about-fleet-section">
|
||||
<h2>About Fleet</h2>
|
||||
|
||||
<p>Fleet is an Open Device Management platform. Manage configuration, application deployment, and patching from a single console. Fleet supports multiple operating systems, including macOS, iOS, Android, Windows, Linux, ChromeOS, and AWS, as well as Google Cloud, Azure Data Centers, and containers.</p>
|
||||
|
||||
<p>For security and IT teams, Fleet delivers interoperability and easy automation through open standards, flexible deployment, transparent controls, and real-time visibility of your inventory.</p>
|
||||
|
||||
<p>For end users, Fleet builds trust through data transparency and clarity. Devices remain reliable and well-managed, minimizing disruptions and ensuring maximum productivity.</p>
|
||||
<div purpose="button-row">
|
||||
<a purpose="cta-button" href="/contact">Get a demo</a>
|
||||
<signup-button :signed-in="this.me"></signup-button>
|
||||
</div>
|
||||
</div>
|
||||
<div purpose="bottom-case-study-links" class="d-flex d-md-none flex-column">
|
||||
<div>
|
||||
<h4>More customer stories</h4>
|
||||
<div purpose="case-study-links" >
|
||||
<a href="/case-study/foursquare" purpose="case-study-link" v-if="thisPage.url !== '/case-study/foursquare'">
|
||||
<div purpose="link-image">
|
||||
<img alt="Foursquare" src="/images/nav-icon-foursquare-40x40@2x.png">
|
||||
</div>
|
||||
<div purpose="link-text">
|
||||
<p><strong>Foursquare</strong></p>
|
||||
<p>Foursquare cut costs and gained 114% ROI with Fleet</p>
|
||||
</div>
|
||||
</a>
|
||||
<a href="/case-study/stripe" purpose="case-study-link" v-if="thisPage.url !== '/case-study/stripe'">
|
||||
<div purpose="link-image">
|
||||
<img alt="Stripe" src="/images/nav-icon-stripe-40x40@2x.png">
|
||||
</div>
|
||||
<div purpose="link-text">
|
||||
<p><strong>Stripe</strong></p>
|
||||
<p>Stripe moved 10,000 Macs to Fleet, saving hundreds of thousands annually</p>
|
||||
</div>
|
||||
</a>
|
||||
<a href="/case-study/faire" purpose="case-study-link" v-if="thisPage.url !== '/case-study/faire'">
|
||||
<div purpose="link-image">
|
||||
<img alt="Faire" src="/images/nav-icon-faire-40x40@2x.png">
|
||||
</div>
|
||||
<div purpose="link-text">
|
||||
<p><strong>Faire</strong></p>
|
||||
<p>Faire keeps Macs secure with CIS benchmarks using Fleet</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div purpose="edit-link">
|
||||
<a purpose="sidebar-link" :href="'https://github.com/fleetdm/fleet/edit/main/articles/'+thisPage.sectionRelativeRepoPath"> <img src="/images/icon-edit-16x16@2x.png" alt="Suggest an edit">Suggest an edit</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<signup-modal></signup-modal>
|
||||
</div>
|
||||
<%- /* Expose server-rendered data as window.SAILS_LOCALS :: */ exposeLocalsToBrowser() %>
|
||||