[Website] Public Launch Assembly (#438)

* Reduce hero size for placeholder

* Clean up Sticky Footer

- Increase the specificity of the selector to prevent any accidental
collisions
- Account for the meganav that exists

* [Website] Add Boundary Features section to homepage (#436)

* Install and implement ProductFeaturesList

* Add images and content

* Inline the product features

* [Website] Add use cases section (#445)

* Commit to illustrate UseCases error

* update react image

* Add in content from design

* Tweaks

* Apply handy edits

Co-authored-by: Brandon Romano <BrandonRRomano@gmail.com>

Co-authored-by: Jeff Escalante <jescalan@users.noreply.github.com>
Co-authored-by: Brandon Romano <BrandonRRomano@gmail.com>

* [Website] Add SectionBreakCta component (#452)

* Create implement barebones component

* Build structure/add content

* Get CSS up to spec

- Typography
- spacing
- Layout
- box-shadow
- Accent line

* Mobile treatment

* Update URL

* Add a break-section to give bg on page

* Change link to outbound

Design is incorrect for this link

Co-authored-by: Brandon Romano <BrandonRRomano@gmail.com>

* Reduce CSS selectors

Co-authored-by: Brandon Romano <BrandonRRomano@gmail.com>

* [Website] Add branded CTA section (#450)

* Create skeleton for component

* Bring in line with CallToAction styles

* Set up background

* Typography and layout (and mobile)

* Button polish

* Changes to prep for updates

These will keep the homepage ready for component updates 
and the upcoming docs and download pages.

Co-authored-by: Brandon Romano <BrandonRRomano@gmail.com>

* Address feedback

- Reduce button hackiness
- Adjust pattern position on mobile to not overlap button

Co-authored-by: Brandon Romano <BrandonRRomano@gmail.com>

* Upgrade button, minor tweaks to BrandedCTA (#481)

* Updates dependencies

* [Website] Homepage hero updates (#503)

* Adjustments to align and lay out left side

* Implement hero background

* Adjust hero URLs

* Implement mobile hero pattern/tweaks

* Add video!

* Mobile tweaks

* Remove mobile bg

* Center the text/buttons on mobile

* Remove mobile hero pattern

* Address visual nits

* Adjust interface for video

* [Website] Add "How it works" section (#483)

* Create skeleton and implement component

* Add sections

* Add CSS and adjust structure

* Remove sections ternary

* Change nomenclature for clarity

* Mobile tweaks

* Tweaks inspired by HCP

* Create LogoList component skeleton

* Implement LogoList on main component

- Shift footertext responsibility to it
- Assume logos will be passed in, because it doesn't render otherwise
  anyway with the right checks

* Implement some logos/restructure LogoList

* CSS adjustments to logolist/section layout

* Show example for too many integrations

* Remove cutoff logic

* Add SVGs for diagram stack

* Combine SVGs into a component

This is necessary to act on various parts of the image independently.

* Fully combine SVG and remove unneeded CSS

* Further CSS cleanup

* Implement stickyness

* Set up active example checks for graphic

* Implement reactivity

- Apply styles based on inactivity or activity, whichever fits best
  per-element
- Add expected state to the general HowItWorks component, where it will
  be managed and passed into the diagram
- Make icon and arrow spacers use the same spacer class

* CSS tweaks for design/organization

* Implement scroll-to-animate functionality!

* Fill out icons for integrations

* Feature updates

- Move LogoList into folder
- Give descriptions some margin

* Mobile treatment tweaks

* Import logic from the cloud-platform page on .com

This fixes a bug in which the in-view example would not update in an
expected manner.

* Remove max-width adjustment on UL

* Fix need for height on the graphic

* Padding/margin tweaks

* Minor CSS tweaks

* Final padding adjustments

* Plugging in proper content into the landing page (#545)

* Misc content updates to align with copy doc

* Plug in feature SVGs

* Move use cases up

* Remove the MegaNav - to be replaced soon

* Updates the nav

* Add footer content, security page

* Remove react-mega-nav from styles

* Downloads Page (#541)

* [Website] Add use cases section (#445)

* Commit to illustrate UseCases error

* update react image

* Add in content from design

* Tweaks

* Apply handy edits

Co-authored-by: Brandon Romano <BrandonRRomano@gmail.com>

Co-authored-by: Jeff Escalante <jescalan@users.noreply.github.com>
Co-authored-by: Brandon Romano <BrandonRRomano@gmail.com>

* Port new downloader page to Boundary

* update placeholder data

* missing css property

* Fix the weird rebase

* Fix padding

Co-authored-by: Noel Quiles <3746694+EnMod@users.noreply.github.com>
Co-authored-by: Jeff Escalante <jescalan@users.noreply.github.com>
Co-authored-by: Brandon Romano <BrandonRRomano@gmail.com>

* [Website] Add alert banner (#557)

* Bring over waypoint's implementation

* Prove that it works/theme to boundary

* revert to hidden for now

* [Website] README polish (#558)

* Adjust readme for boundary

* Correct URL in first paragraph

* [Website] Add community page (#555)

* Just import files from Consul

* Revert CSS paradigm for VerticalBlockList

* Adds community to the nav

Co-authored-by: Brandon Romano <BrandonRRomano@gmail.com>

* A few small content / bug tweaks (#563)

* adds HashiStackMenu

* Fix platform agnostic copy

* Reduce padding between sections

* Fix Subnav indicator for docs page

* Fix features padding

* Adds Favicon

* Update how it works content

* Adds share image

* Updates use cases

* Styling to community page

* Remove some color overrides

* Add SVGO option to nextconfig (#565)

* Add press kit to footer (#567)

* Plug in proper link for onboard users

* Plug in proper video URL (#584)

* Bump HSM version (#582)

* Downloads Page Content (#585)

* Wire up Boundary Downloads content

* Plug in remaining downloads content

* Download via Product slug

* Tweak with transition timing (#587)

* Plug in proper logo into the downloads page (#589)

* Content tweaks (#590)

* Remove border top from footer (#591)

* More content tweaks (#608)

* Updates the hero to support UI/CLI previews (#609)

* Updates the hero to support UI/CLI previews

* Updates video

* More content tweaks (#634)

* Plugs in light theme UI video

* Update infra as code feature

* Remove Auth (#636)

* Remove auth-related files

* Remove auth-related config

* Remove auth provider and next-auth pkgs

* Remove *env.local from gitignore

* Swtich og:image to have a www subdomain

Co-authored-by: Noel Quiles <3746694+EnMod@users.noreply.github.com>

* Elevate prop destructuring to function call

Co-authored-by: Jeff Escalante <jescalan@users.noreply.github.com>

* Update website/pages/community/index.jsx

Co-authored-by: Jeff Escalante <jescalan@users.noreply.github.com>

Co-authored-by: Noel Quiles <3746694+EnMod@users.noreply.github.com>
Co-authored-by: Jeff Escalante <jescalan@users.noreply.github.com>
Co-authored-by: Zack Tanner <zacktanner@gmail.com>
Co-authored-by: Jimmy Merritello <7191639+jmfury@users.noreply.github.com>
pull/643/head
Brandon Romano 6 years ago committed by GitHub
parent b7139920a1
commit dcb609b831
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -3,4 +3,3 @@ node_modules
.next
out
.mdx-data
.env*.local

@ -28,6 +28,7 @@ This subdirectory contains the entire source for the [Boundary Website](https://
- [Editing Navigation Sidebars](#editing-navigation-sidebars)
- [Index-less Categories](#index-less-categories)
- [Custom or External Links](#custom-or-external-links)
- [Editing/Enabling the Alert Banner](#editingenabling-the-alert-banner)
- [Changing the Release Version](#changing-the-release-version)
- [Displaying a Prerelease](#displaying-a-prerelease)
- [Redirects](#redirects)
@ -316,6 +317,15 @@ If the link provided in the `href` property is external, it will display a small
<!-- END: editing-docs-sidebars -->
## Editing/Enabling the Alert Banner
The data and visibility of the alert banner are controlled by the `alert-banner.js` file in the [`/data` directory](data). The following data can be edited in this file:
- `ALERT_BANNER_ACTIVE`: Determines if the banner is visible (when set to `true`) or not (when set to `false`).
- `tag`: Copy for the bordered text on the left side of the alert.
- `text`: Copy for the center text of the alert.
- `url`: Where the alert links to when clicked.
<!-- BEGIN: releases -->
<!-- Generated text, do not edit directly -->

@ -1,28 +0,0 @@
.signInWrapper {
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.loadingIconSpin {
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
animation: spin 0.5s linear infinite;
}
@keyframes spin {
100% {
transform: rotate(360deg);
}
}
.loginLockup {
display: flex;
width: 50vw;
justify-content: space-around;
}

@ -1,83 +0,0 @@
import { useSession, getCsrfToken, getProviders } from 'next-auth/client'
import LoadingIcon from './loading.svg?include'
import InlineSvg from '@hashicorp/react-inline-svg'
import styles from './auth-gate.module.css'
import Button from '@hashicorp/react-button'
import { useEffect, useState } from 'react'
import { useRouter } from 'next/router'
import SigninErrorPage from 'components/signin-error-page'
export default function AuthGate({ children }) {
const [session, loading] = useSession()
const { query } = useRouter()
if (query?.error === 'oAuthCallback') return <SigninErrorPage />
if (loading)
return <InlineSvg className={styles.loadingIconSpin} src={LoadingIcon} />
return session ? (
<>{children}</>
) : (
<div className={styles.signInWrapper}>
<SignInForm />
</div>
)
}
function SignInForm() {
const [token, setToken] = useState(null)
useEffect(() => {
async function getToken() {
const t = await getCsrfToken()
if (t) {
setToken(t)
}
}
getToken()
}, [token])
return token ? (
<section className={styles.signInWrapper}>
<Form token={token} callbackUrl={window.location.origin} />
</section>
) : null
}
function Form({ callbackUrl, token }) {
const authProviders = useAuthProviders()
return (
<div className={styles.loginLockup}>
{authProviders &&
Object.keys(authProviders).map((ap) => (
<form
key={ap}
action={`${callbackUrl}/api/auth/signin/${ap}`}
method="POST"
>
<input type="hidden" name="csrfToken" value={token} />
<input type="hidden" name="callbackUrl" value={callbackUrl} />
<Button
type="submit"
title={`Sign in with ${authProviders[ap].name}`}
theme={{ variant: 'primary', background: 'dark' }}
/>
</form>
))}
</div>
)
}
export function useAuthProviders() {
const [authProviders, setAuthProviders] = useState([])
async function getProviderList() {
const providers = await getProviders()
if (providers) {
setAuthProviders(providers)
}
}
useEffect(() => {
if (typeof window !== 'undefined') {
getProviderList()
}
}, [])
return authProviders
}

@ -1 +0,0 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><circle opacity=".3" cx="24" cy="24" r="24" fill="#fff"/><path d="M48 24A24 24 0 1131.416 1.175l-1.112 3.423A20.4 20.4 0 1044.4 24H48z" fill="#1D1E23"/></svg>

Before

Width:  |  Height:  |  Size: 253 B

@ -1,24 +0,0 @@
.authIndicator {
position: fixed;
bottom: 0;
width: 100vw;
z-index: 3;
padding: 1rem 2rem;
text-align: center;
background: var(--black);
color: var(--white);
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
@media (--medium-up) {
justify-content: flex-end;
}
}
.loggedInText {
margin: 1rem 1rem;
@media (--medium-up) {
margin: 0 1rem;
}
}

@ -1,27 +0,0 @@
import { signOut, useSession } from 'next-auth/client'
import styles from './auth-indicator.module.css'
import Button from '@hashicorp/react-button'
export default function AuthIndicator() {
const [session, loading] = useSession()
if (loading) return `Loading...`
return (
<div className={styles.authIndicator}>
{session && (
<>
<span className={`g-type-label ${styles.loggedInText}`}>
Signed in as {session.user.email}
</span>
<span>
<Button
onClick={signOut}
title={`Sign out`}
size="small"
theme={{ variant: 'secondary-neutral', background: 'dark' }}
/>
</span>
</>
)}
</div>
)
}

@ -1 +0,0 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><circle opacity=".3" cx="24" cy="24" r="24" fill="#fff"/><path d="M48 24A24 24 0 1131.416 1.175l-1.112 3.423A20.4 20.4 0 1044.4 24H48z" fill="#1D1E23"/></svg>

Before

Width:  |  Height:  |  Size: 253 B

@ -0,0 +1,66 @@
.brandedCta {
padding: 88px 0;
background-color: var(--red-l3);
background-image: url('./img/bg-pattern.svg');
background-position: bottom right;
background-repeat: no-repeat;
@media (--small) {
background-position: bottom 0 right -130px;
}
@media (462px <= width < 600px) {
background-position: bottom 0 right -260px;
}
@media (width < 462px) {
background-position: bottom 0 right -170px;
}
}
.contentContainer {
@media (width >= 992px) {
display: flex;
}
@media (width < 992px) {
flex-direction: column;
}
}
.heading {
color: var(--black);
margin-top: 0;
@media (width >= 992px) {
flex-basis: 33.3%;
margin: 0;
}
}
.content {
max-width: 647px;
margin: 0;
color: var(--gray-3);
}
.content-and-links {
@media (width >= 992px) {
flex-basis: 66.6%;
margin-left: 32px;
}
& .g-type-body-large {
max-width: 35em;
}
}
.links {
margin-top: 40px;
margin-bottom: -16px;
& a {
margin-right: 16px;
margin-bottom: 16px;
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 26 KiB

@ -0,0 +1,46 @@
import styles from './branded-cta.module.css'
import Button from '@hashicorp/react-button'
export default function BrandedCta({ heading, content, links }) {
return (
<div className={styles.brandedCta}>
<div className={`g-grid-container ${styles.contentContainer}`}>
<h2
data-testid="heading"
className={`g-type-display-2 ${styles.heading}`}
>
{heading}
</h2>
<div className="content-and-links">
<p
data-testid="content"
className={`g-type-body-large ${styles.content}`}
>
{content}
</p>
<div data-testid="links" className={styles.links}>
{links.map((link, stableIdx) => {
const buttonVariant = stableIdx === 0 ? 'primary' : 'secondary'
const linkType = link.type || ''
return (
<Button
// eslint-disable-next-line react/no-array-index-key
key={stableIdx}
linkType={linkType}
theme={{
variant: buttonVariant,
brand: 'red',
background: 'light',
}}
title={link.text}
url={link.url}
/>
)
})}
</div>
</div>
</div>
</div>
)
}

@ -1,19 +0,0 @@
import AuthIndicator from 'components/auth-indicator'
import AuthGate from 'components/auth-gate'
import { Provider as NextAuthProvider } from 'next-auth/client'
const shouldApplyAuth =
process.env.HASHI_ENV === 'production' || process.env.HASHI_ENV === 'preview'
export default function ConditionalAuthProvider({ children, session }) {
return shouldApplyAuth ? (
<NextAuthProvider session={session}>
<AuthGate>
{children}
<AuthIndicator />
</AuthGate>
</NextAuthProvider>
) : (
<>{children}</>
)
}

@ -0,0 +1,124 @@
import Tabs from '@hashicorp/react-tabs'
import { prettyOs, prettyArch } from 'components/downloader/utils/downloader'
import styles from './style.module.css'
export default function DownloadTabs({
defaultTabIdx,
tabData,
downloads,
version,
merchandisingSlot,
brand,
logo,
tutorialLink,
}) {
return (
<Tabs
key={defaultTabIdx}
centered
fullWidthBorder
theme={brand}
className={styles.tabs}
defaultTabIdx={defaultTabIdx}
items={tabData.map(({ os, packageManagers }) => ({
heading: prettyOs(os),
tabChildren: function TabChildren() {
return (
<div className={styles.cards}>
<Cards
key={os}
os={os}
downloads={downloads}
packageManagers={packageManagers}
version={version}
theme={brand}
logo={logo}
tutorialLink={tutorialLink}
/>
{merchandisingSlot}
</div>
)
},
}))}
/>
)
}
function Cards({
os,
downloads,
packageManagers,
version,
theme,
logo,
tutorialLink,
}) {
const arches = downloads[os]
const hasPackageManager = Boolean(packageManagers)
const hasMultiplePackageManagers = Array.isArray(packageManagers)
return (
<>
<div
className={
hasMultiplePackageManagers
? styles.downloadCardsSingle
: styles.downloadCards
}
>
{hasPackageManager && (
<div className={styles.packageManagers}>
<span className={styles.cardTitle}>Package Manager</span>
{Array.isArray(packageManagers) ? (
<Tabs
theme={theme}
items={packageManagers.map(({ label, commands }) => ({
heading: label,
tabChildren: function TabChildren() {
return (
<div className={styles.install}>
{commands.map((command) => (
<pre key={command}>{command}</pre>
))}
</div>
)
},
}))}
/>
) : (
<div className={styles.install}>
{packageManagers.commands.map((command) => (
<pre key={command}>{command}</pre>
))}
</div>
)}
{tutorialLink && (
<div>
<a href={tutorialLink.href}>{tutorialLink.label}</a>
</div>
)}
</div>
)}
<div className={hasPackageManager ? styles.card : styles.soloCard}>
<span className={styles.cardTitle}>Binary Download</span>
<div className={styles.logoDownloadWrapper}>
<div className={styles.logoWrapper}>
{logo}
<span className={styles.version}>{version}</span>
</div>
{Object.entries(arches).map(([arch, url]) => (
<a href={url} key={arch} className={styles.downloadLink}>
{prettyArch(arch)}
</a>
))}
</div>
<div className={styles.fastly}>
Bandwidth courtesy of
<img src={require('../logos/fastly.svg')} alt="Fastly" />
</div>
</div>
</div>
</>
)
}

@ -0,0 +1,156 @@
.cards {
max-width: 880px;
margin: 0 auto;
}
.logoWrapper {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 10px;
}
.logoDownloadWrapper {
width: 100%;
}
.version {
margin-left: 8px;
}
.downloadCards {
justify-content: center;
margin: 54px 0 24px;
& a {
color: var(--gray-2);
}
@media (--medium-up) {
margin: 64px 0;
display: grid;
grid-template-columns: 1fr 1fr;
grid-column-gap: 48px;
justify-items: center;
}
& .downloadLink {
color: var(--brand);
margin-right: 16px;
}
}
.downloadCardsSingle {
composes: downloadCards;
& .card {
max-width: unset;
}
@media (--medium-up) {
grid-template-columns: 1fr;
& .card:first-child {
margin-bottom: 48px;
}
}
}
.card {
width: 100%;
min-height: 278px;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
justify-content: space-between;
padding: 40px 32px;
color: var(--gray-2);
border: 1px solid var(--gray-6);
&:first-child {
border-bottom: none;
@media (--medium-up) {
border-bottom: 1px solid var(--gray-6);
}
}
}
.packageManagers {
composes: card;
& a {
color: var(--brand);
}
& :global {
& .g-tabs {
width: 100%;
@media (--medium-up) {
width: initial;
}
}
}
}
.soloCard {
composes: card;
grid-column: span 2;
&:first-child {
border-bottom: 1px solid var(--gray-6);
}
}
.install {
color: var(--white);
background-color: var(--black);
padding: 16px 24px;
border-radius: 3px;
text-align: left;
margin: 32px 0;
& pre {
margin: 0;
padding: 0;
background-color: inherit;
white-space: normal;
&::before {
color: #e93471;
content: '$';
margin-right: 8px;
}
@media (--medium-up) {
white-space: pre;
}
}
}
.cardTitle {
font-family: var(--font-display);
font-size: 12px;
line-height: 18px;
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--gray-4);
font-weight: bold;
}
.fastly {
display: flex;
align-items: center;
flex-direction: column;
& svg path {
fill: var(--black);
}
& img {
margin-top: 12px;
width: 48px;
}
}

@ -0,0 +1,58 @@
import { useState, useRef, useEffect } from 'react'
import Button from '@hashicorp/react-button'
import styles from './style.module.css'
export default function Dropdown({ options, onChange, title, brand }) {
const [open, setOpen] = useState(false)
const buttonRef = useRef()
useEffect(() => {
function handleClickOutside(event) {
if (buttonRef.current.contains(event.target)) return
setOpen(false)
}
document.addEventListener('mousedown', handleClickOutside)
return () => {
document.removeEventListener('mousedown', handleClickOutside)
}
}, [])
return (
<div className={styles.root} ref={buttonRef}>
<Button
className="trigger"
theme={{ brand }}
onClick={() => setOpen((open) => !open)}
aria-expanded={open}
aria-controls="menu-list"
aria-haspopup="true"
title={title}
icon={{
position: 'right',
svg:
'<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M5 7.5L10 12.5L15 7.5" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',
}}
/>
{open && (
<ul className={styles.menu} id="menu-list" role="menu">
{options.map((option) => (
<li
className={styles.option}
tabIndex={0}
role="menuitem"
key={option.value}
onClick={() => {
onChange(option.value)
setOpen(false)
}}
>
{option.label}
</li>
))}
</ul>
)}
</div>
)
}

@ -0,0 +1,28 @@
.root {
display: inline-block;
position: relative;
}
.menu {
position: absolute;
list-style: none;
max-height: 250px;
overflow-y: auto;
top: 35px;
width: 100%;
padding: 0;
background-color: var(--white);
box-shadow: 0 2px 1px -1px rgba(0, 0, 0, 0.2), 0 1px 1px 0 rgba(0, 0, 0, 0.14),
0 1px 3px 0 rgba(0, 0, 0, 0.12);
}
.option {
padding: 8px 16px;
cursor: pointer;
background-color: var(--brand);
color: var(--white);
&:hover {
background-color: var(--brand-d1);
}
}

@ -0,0 +1,7 @@
<svg width="156" height="61" viewBox="0 0 156 61" xmlns="http://www.w3.org/2000/svg">
<path
d="M106.167 6.237v40.95h12.226V40.93h-4.04V0h-8.187v6.237zM0 40.93h4.156V21.174H0V15.74l4.156-.687v-5.5C4.156 2.891 5.597 0 14.042 0c1.824 0 3.986.271 5.879.614l-1.122 6.697c-1.283-.204-1.918-.24-2.728-.24-2.976 0-3.728.298-3.728 3.222v4.76h6.177v6.12h-6.177V40.93h4.113v6.255L0 47.187V40.93zm102.002-1.977c-1.28.272-2.4.239-3.211.259-3.368.083-3.077-1.03-3.077-4.226V21.174h6.41v-6.121h-6.41V0h-8.187v36.694c0 7.204 1.767 10.492 9.469 10.492 1.824 0 4.33-.472 6.223-.88l-1.217-7.353zm-24.695-17.79v-1.096c-2.477-.455-4.937-.461-6.27-.461-3.811 0-4.276 2.032-4.276 3.134 0 1.56.53 2.402 4.657 3.31 6.033 1.363 12.093 2.784 12.093 10.31 0 7.139-3.652 10.826-11.338 10.826-5.143 0-10.134-1.11-13.941-2.082v-6.151h6.2l-.004 1.092c2.668.519 5.465.467 6.926.467 4.064 0 4.721-2.198 4.721-3.367 0-1.622-1.165-2.4-4.975-3.178-7.177-1.234-12.873-3.699-12.873-11.033 0-6.943 4.616-9.666 12.302-9.666 5.207 0 9.166.812 12.976 1.785v6.11h-6.198zm-41.475 17.77v-.967h-.98v.965c-4.395-.257-7.91-3.81-8.139-8.237h.975v-.987h-.97c.26-4.397 3.761-7.915 8.133-8.171v.97h.981v-.973c4.31.232 7.782 3.633 8.157 7.928v.283h-.983v.987h.983v.27c-.373 4.298-3.846 7.701-8.157 7.933zm16.347.02l-.006-25.632h-8.186v2.404a16.673 16.673 0 00-5.567-2.119h.046v-2.844h1V8.671H31.22v2.091h1v2.845h.056c-7.83 1.45-13.764 8.348-13.764 16.646 0 9.35 7.534 16.93 16.828 16.93a16.674 16.674 0 008.672-2.419l1.474 2.423h8.648v-8.234h-1.957.001zm86.935-23.9H156v6.115h-4.037L141.607 46.8c-2.967 7.2-7.843 13.977-15.266 13.977-1.826 0-4.257-.203-5.942-.61l.74-7.476c1.082.203 2.499.337 3.242.337 3.443 0 7.326-2.146 8.541-5.883L122.43 21.168h-4.036v-6.115h16.895v6.115h-4.036l5.945 14.713 5.944-14.713h-4.027v-6.115zM39.639 26.569l-.623-.627-3.164 2.774a1.494 1.494 0 00-.51-.09c-.853 0-1.544.716-1.544 1.598 0 .883.69 1.598 1.545 1.598.853 0 1.546-.715 1.546-1.598 0-.168-.025-.33-.071-.481l2.82-3.174z"
fill="#000"
fill-rule="nonzero"
/>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

@ -0,0 +1,158 @@
import { useState, Fragment, useEffect } from 'react'
import Dropdown from 'components/downloader/dropdown'
import {
prettyArch,
prettyOs,
sortPlatforms,
getVersionLabel,
sortAndFilterReleases,
} from 'components/downloader/utils/downloader'
import styles from './style.module.css'
export default function ReleaseInformation({
productId,
productName,
latestVersion,
packageManagers,
containers,
tutorials,
changelog,
brand,
}) {
const [selectedVersionId, setSelectedVersionId] = useState(latestVersion)
const [releases, setReleases] = useState([])
const { version, ...selectedVersion } =
releases.find((release) => release.version === selectedVersionId) || {}
useEffect(() => {
// lazy load all release versions to populate dropdown & releases section
fetch(`https://releases.hashicorp.com/${productId}/index.json`)
.then((res) => res.json())
.then((data) => {
const latestReleases = sortAndFilterReleases(Object.keys(data.versions))
const releases = latestReleases.map((releaseVersion) => ({
...sortPlatforms(data.versions[releaseVersion]),
version: releaseVersion,
}))
setReleases(releases)
})
}, [])
return (
<div className={styles.root}>
<div className="g-container">
<h2>Release Information</h2>
<div className={styles.grid}>
{releases.length > 0 && (
<>
<div className={styles.releases}>Releases:</div>
<div>
<Dropdown
title={`${productName} ${getVersionLabel(
version,
latestVersion
)}`}
brand={brand}
options={releases.map((releaseData) => ({
label: `${productName} ${getVersionLabel(
releaseData.version,
latestVersion
)}`,
value: releaseData.version,
}))}
onChange={(release) => setSelectedVersionId(release)}
/>
<a
href={
changelog ||
`https://github.com/hashicorp/${productId}/blob/v${version}/CHANGELOG.md`
}
className={styles.changelog}
>
Changelog
</a>
</div>
</>
)}
<div className={styles.latestDownloads}>Latest Downloads:</div>
<div>
Package downloads for {productName} {version}
<div className={styles.downloads}>
{Object.entries(selectedVersion).map(([os, release]) => (
<Fragment key={os}>
<div className={styles.os}>{prettyOs(os)}</div>
<div>
{Object.entries(release).map(([arch, file]) => (
<a href={file} key={arch}>
{prettyArch(arch)}
</a>
))}
</div>
</Fragment>
))}
</div>
<p>
You can find the{' '}
<a
href={`https://releases.hashicorp.com/${productId}/${version}/${productId}_${version}_SHA256SUMS`}
>
SHA256 checksums for {productName} {version}
</a>{' '}
online and you can{' '}
<a
href={`https://releases.hashicorp.com/${productId}/${version}/${productId}_${version}_SHA256SUMS.sig`}
>
verify the checksums signature file
</a>{' '}
which has been signed using{' '}
<a href="https://hashicorp.com/security">
HashiCorp&apos;s GPG key.
</a>
</p>
</div>
{packageManagers?.length > 0 && (
<>
<div className={styles.heading}>Package Managers</div>
<div className={styles.links}>
{packageManagers.map((packageManager) => (
<div key={packageManager.label}>
Install with{' '}
<a href={packageManager.url}>{packageManager.label}</a>
</div>
))}
</div>
</>
)}
{containers?.length > 0 && (
<>
<div className={styles.heading}>Containers</div>
<div className={styles.links}>
{containers.map((container) => (
<div key={container.label}>
Run with <a href={container.url}>{container.label}</a>
</div>
))}
</div>
</>
)}
{containers?.length > 0 && (
<>
<div className={styles.heading}>Tutorials</div>
<div className={styles.links}>
{tutorials.map((tutorial) => (
<div key={tutorial.label}>
<a href={tutorial.url}>{tutorial.label}</a>
</div>
))}
</div>
</>
)}
</div>
</div>
</div>
)
}

@ -0,0 +1,101 @@
.root {
background-color: var(--gray-7);
padding: 42px 0;
margin-top: 42px;
color: var(--gray-2);
& p {
color: var(--gray-2);
}
& a {
color: var(--gray-2);
}
& :global(.g-container) {
max-width: 825px;
}
& h2 {
text-align: center;
color: var(--black);
margin-bottom: 54px;
@media (--medium-up) {
margin-bottom: 64px;
}
}
}
.heading {
margin: 24px 0;
font-weight: bold;
color: var(--black);
@media (--medium-up) {
text-align: right;
margin: 0;
}
}
.changelog {
display: block;
margin: 24px 0 0;
color: var(--black);
@media (--medium-up) {
display: inline-block;
margin: 0 0 0 24px;
}
}
.grid {
margin: 48px auto;
@media (--medium-up) {
display: grid;
grid-column-gap: 32px;
grid-row-gap: 48px;
grid-template-columns: auto 1fr;
}
}
.latestDownloads {
composes: heading;
margin-top: 40px;
@media (--medium-up) {
margin-top: 0;
}
}
.downloads {
display: grid;
width: 100%;
grid-template-columns: auto 1fr;
margin: 17px 0 40px;
grid-column-gap: 28px;
grid-row-gap: 16px;
& a {
margin: 0 6px;
}
& .os {
font-weight: bold;
color: var(--black);
}
@media (--medium-up) {
margin: 20px 0 64px;
}
}
.releases {
align-self: center;
composes: heading;
}
.links > div:not(:first-child) {
margin: 15px 0;
}

@ -0,0 +1,123 @@
import semverRSort from 'semver/functions/rsort'
import semverPrerelease from 'semver/functions/prerelease'
import semverValid from 'semver/functions/valid'
export function getVersionLabel(version, latestVersion) {
if (version === latestVersion) {
return `${version} (latest)`
}
return version
}
export function sortAndFilterReleases(releases) {
const validReleases = releases.filter(semverValid)
// descending sort on releases, while filtering out pre-releases
return semverRSort(validReleases).filter(
(version) => !semverPrerelease(version)
)
}
/** TODO: Below utils directly from Product-Downloader component.
* Should either be exported, or migrated back to web-components */
export function prettyArch(arch) {
switch (arch) {
case 'all':
return 'Universal (32 and 64-bit)'
case 'i686':
case 'i386':
case '686':
case '386':
return '32-bit'
case 'x86_64':
case '86_64':
case 'amd64':
return '64-bit'
default:
if (/-/.test(arch)) {
const parts = arch.split(/-(.+)/)
return `${prettyArch(parts[0])} (${parts[1]})`
} else {
const parts = arch.split('_')
if (parts.length > 0) {
return (
parts[parts.length - 1].charAt(0).toUpperCase() +
parts[parts.length - 1].slice(1)
)
}
}
}
}
export function detectOs(platform) {
for (let key in platformMap) {
if (platform.indexOf(key) !== -1) {
return platformMap[key]
}
}
return null
}
export function prettyOs(os) {
switch (os) {
case 'darwin':
return 'Mac OS X'
case 'freebsd':
return 'FreeBSD'
case 'openbsd':
return 'OpenBSD'
case 'netbsd':
return 'NetBSD'
case 'archlinux':
return 'Arch Linux'
case 'linux':
return 'Linux'
case 'windows':
return 'Windows'
default:
return os.charAt(0).toUpperCase() + os.slice(1)
}
}
const platformMap = {
Mac: 'darwin',
Win: 'windows',
Linux: 'linux',
}
export function sortPlatforms(releaseData) {
// first we pull the platforms out of the release data object and format it the way we want
const platforms = releaseData.builds.reduce((acc, build) => {
if (!acc[build.os]) acc[build.os] = {}
acc[build.os][build.arch] = build.url
return acc
}, {})
const platformKeys = Object.keys(platforms)
// create array of sorted values to base the order on
const sortedValues = Object.keys(platformMap)
.map((e) => platformMap[e])
// join the lists together to make sure
// all items are accounted for when sorting
.concat(platformKeys)
// filter our any duplicates and unneeded items
.filter((elem, pos, arr) => {
return arr.indexOf(elem) == pos && platformKeys.indexOf(elem) > -1
})
return (
platformKeys
// sort items based on platformMap order
.sort((a, b) => {
return sortedValues.indexOf(a) - sortedValues.indexOf(b)
})
// create new sorted object to return
.reduce((result, key) => {
result[key] = platforms[key]
return result
}, {})
)
}

@ -8,6 +8,12 @@ export default function Footer({ openConsentManager }) {
<Link href="/docs">
<a>Docs</a>
</Link>
<a href="https://learn.hashicorp.com/boundary">Learn</a>
<a href="https://hashicorp.com/privacy">Privacy</a>
<Link href="/security">
<a>Security</a>
</Link>
<a href="/files/press-kit.zip">Press Kit</a>
<a onClick={openConsentManager}>Consent Manager</a>
</div>
</div>

@ -2,7 +2,6 @@
padding: 25px 0 17px 0;
flex-shrink: 0;
display: flex;
border-top: 1px solid var(--gray-6);
& .g-container {
display: flex;

@ -0,0 +1,40 @@
.homepageHero {
padding: 128px 0;
background-repeat: no-repeat;
background-color: var(--red-l3);
background-image: url(/img/hero-pattern.svg);
background-position: bottom right;
@media (max-width: 767px) {
padding: 88px 0;
background-position: bottom 0 right -130px;
}
& :global(.g-hero) {
background: none;
padding: 0;
& :global(.g-btn) {
border-color: var(--red);
background-color: var(--red);
}
& :global(.carousel) {
display: flex;
flex-direction: column-reverse;
& :global(.controls) {
padding-top: 0;
margin-bottom: 32px;
& :global(.progress-bar) {
background-color: var(--gray-6);
& > span {
background: var(--red);
}
}
}
}
}
}

@ -1,35 +1,51 @@
import s from './style.module.css'
import Button from '@hashicorp/react-button'
import Hero from '@hashicorp/react-hero'
import styles from './HomepageHero.module.css'
export default function HomepageHero({ title, description, links }) {
/**
* A simple Facade around our react-hero to make the interface a little more straightforward
* for the end-user updating this on our Homepage, while also allowing us to shim in some
* additional styles and encapsulate that logic.
*/
export default function HomepageHero({
title,
description,
links,
uiVideo,
cliVideo,
}) {
return (
<div className={s.root}>
<div className="g-grid-container">
<span className={s.eyebrow}>
Welcome to the <span className={s.red}>INTERNAL BETA</span> for
HashiCorp Boundary! This is a confidential internal only beta. No
details should be shared externally.
</span>
<h1 className="g-type-display-1">{title}</h1>
<div className={s.contentAndLinks}>
<p className="g-type-body-large">{description}</p>
<div className={s.links}>
{links.map((link, index) => {
const brand = index === 0 ? 'hashicorp' : 'neutral'
const variant = index === 0 ? 'primary' : 'secondary'
return (
<Button
key={link.text}
title={link.text}
linkType={link.type}
url={link.url}
theme={{ variant, brand }}
/>
)
})}
</div>
</div>
</div>
<div className={styles.homepageHero}>
<Hero
data={{
title: title,
description: description,
buttons: links,
backgroundTheme: 'light',
centered: false,
videos: [
{
name: 'UI',
playbackRate: uiVideo.playbackRate,
src: [
{
srcType: uiVideo.srcType,
url: uiVideo.url,
},
],
},
{
name: 'CLI',
playbackRate: cliVideo.playbackRate,
src: [
{
srcType: cliVideo.srcType,
url: cliVideo.url,
},
],
},
],
}}
/>
</div>
)
}

@ -1,62 +0,0 @@
.root {
/* 100% height - nav - footer */
min-height: calc(100vh - (64px + 77px));
width: 100%;
padding: 150px 0;
background-repeat: no-repeat;
background-color: var(--gray-7);
background-image: url(/img/hero-pattern.svg);
background-size: contain;
@media (max-width: 758px) {
padding: 64px 0;
}
& .eyebrow {
font-family: var(--font-body);
text-align: center;
display: block;
font-weight: var(--font-weight-bold);
font-size: 1.1rem;
& .red {
color: #ba2226;
}
}
@media (max-width: 758px) {
background-image: url(/img/mobile-hero-pattern.svg);
}
& h1 {
text-align: center;
white-space: pre-wrap;
}
& p {
margin: 0 auto 0 auto;
text-align: center;
max-width: 40em;
}
& :global(.g-grid-container) {
max-width: 700px;
}
& .links {
display: flex;
flex-wrap: wrap;
justify-content: center;
margin-top: calc(32px - 8px);
margin-bottom: -8px;
& a {
margin: 8px;
&:global(.variant-primary) {
border-color: var(--boundary);
background-color: var(--boundary);
}
}
}
}

@ -0,0 +1,9 @@
.root {
& > h4 {
margin-top: 0;
}
& > p {
margin-bottom: 32px;
}
}

@ -0,0 +1,26 @@
import LogoList from './logo-list'
import s from './feature.module.css'
import { useInView } from 'react-intersection-observer'
import { useState } from 'react'
export default function Feature({
title,
description,
logos,
onInViewStatusChanged,
}) {
const [ref, inView] = useInView({ threshold: 0.8 })
const [inViewStatus, setInViewStatus] = useState(false)
if (inView != inViewStatus) {
setInViewStatus(inView)
onInViewStatusChanged(inView)
}
return (
<div className={s.root} ref={ref}>
<h4 className="g-type-display-4">{title}</h4>
<p className="g-type-body">{description}</p>
{logos ? <LogoList logos={logos} /> : null}
</div>
)
}

@ -0,0 +1,22 @@
import s from './logo-list.module.css'
export default function LogoList({ logos }) {
return (
<div className={s.root}>
<div className={s.logos}>
{logos.map((logo, stableIdx) => (
<div
// eslint-disable-next-line react/no-array-index-key
key={stableIdx}
>
<img src={logo.url} alt={logo.alt} />
</div>
))}
</div>
<p className={`g-type-tag-label ${s.footerText}`}>
Integrations coming soon
</p>
</div>
)
}

@ -0,0 +1,16 @@
.logos {
display: flex;
flex-direction: row;
align-items: center;
max-width: 440px;
flex-wrap: wrap;
& > div {
margin-right: 30px;
margin-bottom: 20px;
}
}
.footerText {
color: var(--gray-5);
}

@ -0,0 +1,190 @@
.root {
--transition-time: 0.7s;
@media (--medium-up) {
position: sticky;
top: calc(50vh - (249px));
}
& > svg {
width: 100%;
}
& .boundaryLetter,
& .spacer,
& .iconBg {
fill: var(--white);
}
& .iconLines,
& .iconBg {
stroke-linecap: round;
stroke-width: 1.5px;
stroke-linejoin: round;
}
& .boundaryFill,
& .arrowHead {
fill: #f04e54;
}
& .arrowHead,
& .arrowSegment,
& .spacer {
transition: var(--transition-time) ease;
transition-property: opacity;
}
& .arrowSegment {
stroke-width: 2px;
stroke: #f04e54;
stroke-miterlimit: 10;
stroke-linecap: round;
fill: none;
}
& .dropShadow {
opacity: 0.08;
mix-blend-mode: multiply;
}
& .iconLines {
stroke: var(--white);
fill: none;
transition: var(--transition-time) ease;
transition-property: stroke;
}
& .subtitle {
fill: #b6b8c3;
}
& .iconBg {
stroke: #e5e6ec;
stroke-width: 1px;
transition: var(--transition-time) ease;
transition-property: fill, stroke;
}
& .authenticate {
& .iconBg {
fill: var(--white);
}
& .iconLines {
stroke: #e5e6ec;
stroke-width: 1px;
}
}
& .authorize {
& .spacer {
opacity: 0;
}
& .iconBg {
fill: var(--black);
stroke: var(--black);
}
& .iconLines {
stroke: #e5e6ec;
}
}
& .access {
& .spacer {
opacity: 0;
}
& .iconBg {
fill: var(--black);
stroke: var(--black);
}
& .vaultIcon {
fill: var(--white);
}
}
& .hostsAndServices {
opacity: 1;
transform: translate(0, 0);
transition: var(--transition-time) ease;
transition-property: opacity, transform;
& .leadingLine {
fill: none;
stroke-linecap: round;
stroke-miterlimit: 10;
stroke-width: 1.5px;
stroke: var(--black);
}
}
& .arrowOne .arrowHead,
& .arrowTwo .arrowHead {
@media (--small) {
opacity: 0;
}
}
& .inactive {
& .arrowHead,
& .arrowSegment,
& .spacer {
@media (--medium-up) {
opacity: 0;
}
}
&.authorize {
& .spacer {
@media (--medium-up) {
opacity: 1;
}
}
& .iconBg {
@media (--medium-up) {
fill: var(--white);
stroke: #e5e6ec;
}
}
& .iconLines {
@media (--medium-up) {
stroke: #b6b8c3;
}
}
}
&.access {
& .spacer {
@media (--medium-up) {
opacity: 1;
}
}
& .iconBg {
@media (--medium-up) {
fill: var(--white);
stroke: var(--white);
}
}
& .vaultIcon {
@media (--medium-up) {
fill: var(--black);
}
}
}
&.hostsAndServices {
@media (--medium-up) {
opacity: 0;
transform: translate(0, 10px);
}
}
}
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,87 @@
.root {
padding: 88px 0;
& .headerWrapper {
& h2 {
text-align: center;
margin-top: 0;
margin-bottom: 32px;
@media (--small) {
margin-bottom: 0;
}
}
& p {
max-width: 818px;
text-align: center;
margin-left: auto;
margin-right: auto;
}
}
}
.contentContainer {
display: flex;
justify-content: space-between;
position: relative;
@media (--small) {
flex-direction: column;
}
& > ul {
max-width: 470px;
margin-left: 128px;
padding: 0;
@media (width < 1120px) {
margin-left: 64px;
}
@media (width < 1024px) {
margin-left: 40px;
}
@media (--small) {
margin-left: 0;
}
}
}
.diagram {
width: 591px;
max-width: 100%;
}
.features {
& > li {
list-style: none;
& > div {
list-style: none;
padding-bottom: 285px;
@media (--small) {
padding-top: 0;
margin-bottom: 0;
padding-bottom: 100px;
}
}
&:last-child {
& > div {
padding-bottom: 355px;
margin-bottom: -200px;
}
}
&:first-child {
& > div {
padding-top: 108px;
@media (width < 1120px) {
padding-top: 64px;
}
}
}
}
}

@ -0,0 +1,50 @@
import s from './how-it-works.module.css'
import classNames from 'classnames'
import HowBoundaryWorksDiagram from './how-boundary-works-diagram'
import Feature from './feature'
import { useState } from 'react'
export default function HowItWorks({ title, description, features }) {
const [activeExampleIndex, setActiveExampleIndex] = useState(0)
const [viewportStatus, setViewportStatus] = useState(
new Array(features.length).fill(false)
)
return (
<div className={s.root}>
<div className={classNames('g-grid-container', s.headerWrapper)}>
<h2 className="g-type-display-2">{title}</h2>
<p className="g-type-body-large">{description}</p>
</div>
<div className={`g-grid-container ${s.contentContainer}`}>
<div className={s.diagram}>
<HowBoundaryWorksDiagram activeExampleIndex={activeExampleIndex} />
</div>
<ul className={s.features}>
{features.map((feature, index) => (
<li key={feature.title}>
<Feature
{...feature}
onInViewStatusChanged={(state) => {
const newStatusArray = [...viewportStatus]
newStatusArray[index] = state
setViewportStatus(newStatusArray)
// Calculate the first element in focus, set that as
// our new activeExampleIndex. If it's been updated
// notify the subscriber.
const newExampleIndex = newStatusArray.lastIndexOf(true)
if (
activeExampleIndex != newExampleIndex &&
newExampleIndex != -1
) {
setActiveExampleIndex(newExampleIndex)
}
}}
/>
</li>
))}
</ul>
</div>
</div>
)
}

@ -0,0 +1,22 @@
import styles from './section-break-cta.module.css'
import Button from '@hashicorp/react-button'
export default function SectionBreakCta({ heading, content, link }) {
return (
<div className={styles.sectionBreakCta}>
<hr />
<h4 className="g-type-display-4">{heading}</h4>
<p className="g-type-body">{content}</p>
<Button
title={link.text}
url={link.url}
theme={{
brand: 'neutral',
variant: 'tertiary-neutral',
background: 'light',
}}
linkType="outbound"
/>
</div>
)
}

@ -0,0 +1,31 @@
.sectionBreakCta {
padding: 60px 30px;
max-width: 800px;
display: flex;
flex-direction: column;
text-align: center;
box-shadow: 0 8px 12px rgba(37, 38, 45, 0.08);
margin: 0 auto;
background-color: var(--white);
@media (width <= 880px) {
margin: 0 40px;
}
& > h4 {
margin-top: 0;
margin-bottom: 8px;
}
& > p {
margin-top: 0;
margin-bottom: 40px;
}
& hr {
width: 64px;
background-color: var(--red);
margin-top: 0;
margin-bottom: 24px;
}
}

@ -1,33 +0,0 @@
import styles from './signin-error.module.css'
import Button from '@hashicorp/react-button'
import { useAuthProviders } from 'components/auth-gate'
export default function SigninErrorPage() {
const authProviders = useAuthProviders()
return (
<div className={styles.signinErrorWrapper}>
<h1 className="g-type-display-3">
Sorry! <br />
It seems you do not have appropriate permissions to view this content.
</h1>
{authProviders && (
<div className={styles.logoutCard}>
<div className={styles.authProviderGoBack}>
<h4>{`If you'd like to try again with another Okta account, please log out of Okta`}</h4>
{process.env.NEXT_PUBLIC_OKTA_DOMAIN && (
<Button
url={`https://${process.env.NEXT_PUBLIC_OKTA_DOMAIN}`}
title={`Go to Okta`}
/>
)}
</div>
<div className={styles.authProviderGoBack}>
<h4>{`If you'd like to try again with another Auth0 account, please go back`}</h4>
<Button url="/" title="Go back" />
</div>
)
</div>
)}
</div>
)
}

@ -1,29 +0,0 @@
.signinErrorWrapper {
display: flex;
justify-content: center;
align-items: center;
text-align: center;
flex-direction: column;
width: 100vw;
height: 100vh;
}
.logoutCard {
margin-top: 3rem;
display: flex;
justify-content: center;
flex-wrap: wrap;
align-items: center;
text-align: center;
padding: 2rem;
border: 1px solid var(--gray-6);
}
.authProviderGoBack {
display: flex;
flex: 0 1 600px;
justify-content: center;
align-items: center;
text-align: center;
flex-direction: column;
}

@ -19,7 +19,7 @@ export default function ProductSubnav() {
},
{
text: 'Download',
url: 'https://github.com/hashicorp/boundary/releases',
url: '/downloads',
},
]}
currentPath={router.asPath}

@ -0,0 +1,7 @@
export const ALERT_BANNER_ACTIVE = false
export default {
tag: 'ANNOUNCING',
text: 'Some details about an announcement here',
url: 'https://hashicorp.com',
}

@ -0,0 +1,66 @@
export const packageManagers = {
homebrew: {
label: 'Homebrew',
url: '',
commands: ['brew tap hashicorp/tap', 'brew install hashicorp/tap/boundary'],
},
ubuntu: {
label: 'Ubuntu/Debian',
commands: [
'curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -',
'sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"',
'sudo apt-get update && sudo apt-get install boundary',
],
},
centos: {
label: 'CentOS/RHEL',
commands: [
'sudo yum install -y yum-utils',
'sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo',
'sudo yum -y install boundary',
],
},
fedora: {
label: 'Fedora',
commands: [
'sudo dnf install -y dnf-plugins-core',
'sudo dnf config-manager --add-repo https://rpm.releases.hashicorp.com/fedora/hashicorp.repo',
'sudo dnf -y install boundary',
],
},
amazonLinux: {
label: 'Amazon Linux',
commands: [
'sudo yum install -y yum-utils',
'sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/AmazonLinux/hashicorp.repo',
'sudo yum -y install boundary',
],
},
}
export const packageManagersByOs = {
darwin: packageManagers.homebrew,
linux: [
packageManagers.ubuntu,
packageManagers.centos,
packageManagers.fedora,
packageManagers.amazonLinux,
],
}
export const getStartedLinks = [
{
label: 'Install Boundary',
href:
'https://learn.hashicorp.com/tutorials/boundary/getting-started-install',
},
{
label: 'Introduction to Boundary',
href:
'https://learn.hashicorp.com/tutorials/boundary/getting-started-intro',
},
{
label: 'Start a Development Environment',
href: 'https://learn.hashicorp.com/tutorials/boundary/getting-started-dev',
},
]

@ -1,10 +1,28 @@
export default [
{
text: 'Overview',
url: '/',
type: 'inbound',
},
'divider',
{
text: 'Tutorials',
url: 'https://learn.hashicorp.com/boundary',
type: 'inbound',
},
{
text: 'Docs',
url: '/docs/getting-started',
url: '/docs',
type: 'inbound',
},
{
text: 'API',
url: '/api-docs',
type: 'inbound',
},
{
text: 'Community',
url: '/community',
type: 'inbound',
},
]

@ -1,19 +0,0 @@
import NextAuth from 'next-auth'
import NextAuthProviders from 'next-auth/providers'
function formatProviderConfig(ap) {
const apName = ap.toUpperCase()
const config = {
clientId: process.env[`${apName}_CLIENT_ID`],
clientSecret: process.env[`${apName}_CLIENT_SECRET`],
domain: process.env[`${apName}_DOMAIN`],
}
return NextAuthProviders[ap](config)
}
export default (req, res) => ({ environments, pages }) =>
NextAuth(req, res, {
providers:
environments[process.env.HASHI_ENV]?.map(formatProviderConfig) || [],
pages,
})

@ -5,25 +5,21 @@ const redirects = require('./redirects.js')
// log out our primary environment variables for clarity in build logs
console.log(`HASHI_ENV: ${process.env.HASHI_ENV}`)
console.log(`NODE_ENV: ${process.env.NODE_ENV}`)
console.log(`NEXTAUTH_URL: ${process.env.NEXTAUTH_URL}`)
console.log(`OKTA_DOMAIN: ${process.env.OKTA_DOMAIN}`)
console.log(`AUTH0_DOMAIN: ${process.env.AUTH0_DOMAIN}`)
module.exports = withHashicorp({
defaultLayout: true,
transpileModules: ['is-absolute-url', '@hashicorp/react-mega-nav'],
transpileModules: ['is-absolute-url', '@hashicorp/react-.*'],
mdx: { resolveIncludes: path.join(__dirname, 'pages/partials') },
})({
async redirects() {
return await redirects
},
svgo: { plugins: [{ removeViewBox: false }] },
experimental: { modern: true },
env: {
HASHI_ENV: process.env.HASHI_ENV || 'development',
SEGMENT_WRITE_KEY: 'JkNZiSgwVRAAFrkqqdHLxf0xfcZuhYYc',
BUGSNAG_CLIENT_KEY: '635db43e199cb02419379291d573205b',
BUGSNAG_SERVER_KEY: 'f85278a46e1b5565a9e91974cdc2843b',
NEXT_PUBLIC_OKTA_DOMAIN: process.env.OKTA_DOMAIN,
NEXT_PUBLIC_AUTH0_DOMAIN: process.env.AUTH0_DOMAIN,
},
})

File diff suppressed because it is too large Load Diff

@ -5,29 +5,39 @@
"author": "HashiCorp",
"dependencies": {
"@apidevtools/json-schema-ref-parser": "^9.0.6",
"@hashicorp/mktg-assets": "^1.0.0-alpha.20",
"@hashicorp/nextjs-scripts": "13.0.0-canary.1",
"@hashicorp/react-content": "4.0.2",
"@hashicorp/react-docs-page": "5.0.3",
"@hashicorp/react-alert-banner": "^4.1.0",
"@hashicorp/react-button": "^3.0.1",
"@hashicorp/react-content": "5.1.0",
"@hashicorp/react-docs-page": "6.2.0",
"@hashicorp/react-global-styles": "4.5.0",
"@hashicorp/react-hashi-stack-menu": "^1.0.3",
"@hashicorp/react-head": "1.1.3",
"@hashicorp/react-image": "2.0.4",
"@hashicorp/react-mega-nav": "4.0.1-2",
"@hashicorp/react-hero": "^3.1.9",
"@hashicorp/react-image": "3.0.1",
"@hashicorp/react-product-downloader": "4.1.3",
"@hashicorp/react-product-features-list": "^2.1.0",
"@hashicorp/react-section-header": "2.0.2",
"@hashicorp/react-subnav": "3.3.1",
"@hashicorp/react-tabs": "^0.6.1",
"@hashicorp/react-use-cases": "2.0.1",
"@hashicorp/react-vertical-text-block-list": "2.0.3",
"babel-plugin-import-glob-array": "0.2.0",
"change-case": "^4.1.1",
"classnames": "^2.2.6",
"fs-exists-sync": "0.1.0",
"gray-matter": "4.0.2",
"js-yaml": "3.14.0",
"line-reader": "0.4.0",
"next": "9.5.3",
"next-auth": "^3.1.0",
"next-mdx-remote": "1.0.0",
"react": "16.13.1",
"react-dom": "16.13.1",
"readdirp": "3.4.0"
"react-intersection-observer": "^8.29.0",
"react-player": "^2.6.2",
"readdirp": "3.4.0",
"semver": "^7.3.2"
},
"devDependencies": {
"dart-linkcheck": "2.0.15",
@ -52,7 +62,6 @@
"generate:readme": "next-hashicorp markdown-blocks README.md",
"lint": "next-hashicorp lint",
"start": "next dev",
"dev:auth": "HASHI_ENV=preview npm start",
"static": "npm run build && npm run export && cp _redirects out/.",
"linkcheck": "linkcheck <website url>"
}

@ -3,16 +3,17 @@ import '@hashicorp/nextjs-scripts/lib/nprogress/style.css'
import NProgress from '@hashicorp/nextjs-scripts/lib/nprogress'
import createConsentManager from '@hashicorp/nextjs-scripts/lib/consent-manager'
import useAnchorLinkAnalytics from '@hashicorp/nextjs-scripts/lib/anchor-link-analytics'
import HashiStackMenu from '@hashicorp/react-hashi-stack-menu'
import Router from 'next/router'
import HashiHead from '@hashicorp/react-head'
import Head from 'next/head'
import { ErrorBoundary } from '@hashicorp/nextjs-scripts/lib/bugsnag'
import ConditionalAuthProvider from 'components/conditional-auth-provider'
import MegaNav from '@hashicorp/react-mega-nav'
import ProductSubnav from '../components/subnav'
import Footer from 'components/footer'
import Error from './_error'
import { productName } from '../data/metadata'
import AlertBanner from '@hashicorp/react-alert-banner'
import alertBannerData, { ALERT_BANNER_ACTIVE } from 'data/alert-banner'
NProgress({ Router })
const { ConsentManager, openConsentManager } = createConsentManager({
@ -24,23 +25,22 @@ function App({ Component, pageProps }) {
return (
<ErrorBoundary FallbackComponent={Error}>
<ConditionalAuthProvider session={pageProps.session}>
<HashiHead
is={Head}
title={`${productName} by HashiCorp`}
siteName={`${productName} by HashiCorp`}
description="Write your description here"
image="https://www.boundaryproject.io/img/og-image.png"
icon={[{ href: '/favicon.ico' }]}
/>
<MegaNav product={productName} />
<ProductSubnav />
<div className="content">
<Component {...pageProps} />
</div>
<Footer openConsentManager={openConsentManager} />
<ConsentManager />
</ConditionalAuthProvider>
<HashiHead
is={Head}
title={`${productName} by HashiCorp`}
siteName={`${productName} by HashiCorp`}
description="Boundary is an open source solution that automates a secure identity-based user access to hosts and services across environments."
image="https://www.boundaryproject.io/img/og-image.png"
icon={[{ href: '/favicon.ico' }]}
/>
{ALERT_BANNER_ACTIVE && <AlertBanner {...alertBannerData} theme="red" />}
<HashiStackMenu />
<ProductSubnav />
<div className="content">
<Component {...pageProps} />
</div>
<Footer openConsentManager={openConsentManager} />
<ConsentManager />
</ErrorBoundary>
)
}

@ -1,12 +0,0 @@
import nextAuthApiRoute from 'lib/next-auth-utils/config'
export default (req, res) =>
nextAuthApiRoute(
req,
res
)({
environments: { production: ['Okta', 'Auth0'], preview: ['Okta', 'Auth0'] },
pages: {
error: '/signin-error', // Error code passed in query string as ?error=
},
})

@ -0,0 +1,32 @@
import VerticalTextBlockList from '@hashicorp/react-vertical-text-block-list'
import SectionHeader from '@hashicorp/react-section-header'
import Head from 'next/head'
export default function CommunityPage() {
return (
<div id="p-community">
<Head>
<title key="title">Community | Boundary by HashiCorp</title>
</Head>
<SectionHeader
headline="Community"
description="Boundary is a newly-launched open source project. The project team depends on the communitys engagement and feedback. Get involved today."
use_h1={true}
/>
<VerticalTextBlockList
data={[
{
header: 'Community Forum',
body:
'[Boundary Community Forum](https://discuss.hashicorp.com/c/boundary)',
},
{
header: 'Bug Tracker',
body:
'[Issue tracker on GitHub](https://github.com/hashicorp/boundary/issues). Please only use this for reporting bugs. Do not ask for general help here; use the Community Form for that.',
},
]}
/>
</div>
)
}

@ -0,0 +1,21 @@
#p-community {
max-width: var(--site-max-width);
margin: 72px auto;
& .g-section-header {
margin-bottom: 100px;
}
& .g-vertical-text-block-list {
& .list {
& .body-text {
& a {
color: var(--red);
&::after {
background-color: var(--red);
}
}
}
}
}
}

@ -12,7 +12,7 @@ function DocsLayout(props) {
return (
<DocsPage
productName={productName}
productSlug={productSlug}
productSlug="red"
subpath={subpath}
order={order}
staticProps={props}

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 310 67"><defs><style>.cls-1{fill:#f04e54;}</style></defs><g id="LOGOS"><path d="M104.58,32.17c3.08-1.33,4.48-3.21,4.48-6.54V21.45c0-5.44-3.09-8.59-10.72-8.59H82.5v40.3H99.44c7.32,0,11-3.57,11-9.26V39.61C110.45,35.67,108.27,33,104.58,32.17Zm-14.46-13h7.32c2.78,0,4,1,4,3.27V26c0,2.36-1.08,3.76-4.05,3.76H90.12Zm12.71,23.78c0,3-1.46,3.94-4.91,3.94h-7.8v-11h8.47c3,0,4.24,1.33,4.24,4Z"/><path d="M126.48,23.09c-10.1,0-12.82,5.56-12.82,11.62v7.44c0,6.05,2.72,11.61,12.82,11.61s12.83-5.56,12.83-11.61V34.71C139.31,28.65,136.58,23.09,126.48,23.09Zm5.45,19.3c0,3.33-1.51,5.08-5.45,5.08S121,45.72,121,42.39V34.47c0-3.34,1.51-5.09,5.44-5.09s5.45,1.75,5.45,5.09Z"/><path d="M161.46,23.69V44.15c-2.67,1.39-5.88,2.48-7.69,2.48s-2.36-.79-2.36-2.37V23.69H144V45.05c0,5.27,1.75,8.71,6.65,8.71a29.59,29.59,0,0,0,11.8-3.08l.73,2.48h5.63V23.69Z"/><path d="M193.34,23.09a29.59,29.59,0,0,0-11.8,3.08l-.72-2.48h-5.63V53.16h7.38V32.71c2.66-1.39,5.87-2.48,7.68-2.48s2.36.79,2.36,2.36V53.16H200V31.8C200,26.54,198.24,23.09,193.34,23.09Z"/><path d="M222.44,11.66V23.94a41,41,0,0,0-7.87-.85c-6.83,0-9.73,3.87-9.73,10.41v10c0,6.72,3.14,10.22,9.07,10.22a15.48,15.48,0,0,0,9.32-3.08l.72,2.48h5.87V10.63Zm0,33.15a10.43,10.43,0,0,1-6.59,2.66c-2.73,0-3.63-1.33-3.63-3.75V33.32c0-2.67,1-3.94,3.69-3.94a33,33,0,0,1,6.53.79Z"/><path d="M245.74,23.09a38.76,38.76,0,0,0-10.11,1.39l.91,5.63a40.74,40.74,0,0,1,8.17-.91c4.71,0,5.62,1.15,5.62,4.42V36.7h-7.07c-6,0-8.6,2.3-8.6,8.29,0,5.09,2.3,8.77,7.69,8.77a16.06,16.06,0,0,0,8.77-2.6l.54,2h6.06V33.74C257.72,26.35,255,23.09,245.74,23.09Zm4.59,23.29a11.57,11.57,0,0,1-5.56,1.51c-2.3,0-3-.9-3-3,0-2.24.67-2.9,3.09-2.9h5.44Z"/><path d="M277.92,23.09A33,33,0,0,0,270.18,27l-.48-3.27h-6.24V53.16h7.39v-19a56,56,0,0,1,7.8-4.29Z"/><path d="M300.61,23.69l-6.77,22.39-6.72-22.39h-7.56l9.32,29.47h2.59l-3.68,11.92h7l3.93-11.92,9.44-29.47Z"/><polygon class="cls-1" points="9.89 64.1 9.89 59.28 19.9 59.28 19.9 56.3 15.05 56.3 15.05 51.45 37.97 51.45 27.32 33.01 37.97 14.57 14.47 14.57 14.47 40.15 1.82 40.15 1.82 1.92 45.34 1.92 52.61 14.5 41.92 33.01 52.83 51.9 45.78 64.1 9.89 64.1"/><rect class="cls-1" x="6.98" y="51.45" width="4.85" height="4.85"/><rect class="cls-1" x="1.82" y="59.25" width="4.85" height="4.85"/></g></svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

@ -1,17 +1,75 @@
import { useMemo, useState, useEffect } from 'react'
import VERSION from 'data/version.js'
import ProductDownloader from '@hashicorp/react-product-downloader'
import Head from 'next/head'
import HashiHead from '@hashicorp/react-head'
import { productName, productSlug } from 'data/metadata'
import { packageManagersByOs, getStartedLinks } from 'data/downloads'
import ReleaseInformation from 'components/downloader/release-information'
import { sortPlatforms, detectOs } from 'components/downloader/utils/downloader'
import DownloadCards from 'components/downloader/cards'
import styles from './style.module.css'
export default function DownloadsPage({ releaseData, previousVersions }) {
const sortedDownloads = useMemo(() => sortPlatforms(releaseData), [
releaseData,
])
const osKeys = Object.keys(sortedDownloads)
const [osIndex, setSelectedOsIndex] = useState()
const tabData = Object.keys(sortedDownloads).map((osKey) => ({
os: osKey,
packageManagers: packageManagersByOs[osKey] || null,
}))
useEffect(() => {
// if we're on the client side, detect the default platform only on initial render
const index = osKeys.indexOf(detectOs(window.navigator.platform))
setSelectedOsIndex(index)
}, [])
export default function DownloadsPage({ releaseData }) {
return (
<div id="p-downloads" className="g-container">
<div className={styles.root}>
<h1>Download {productName}</h1>
<HashiHead is={Head} title={`Downloads | ${productName} by HashiCorp`} />
<ProductDownloader
product={productName}
<DownloadCards
brand="red"
defaultTabIdx={osIndex}
tabData={tabData}
downloads={sortedDownloads}
version={VERSION}
releaseData={releaseData}
logo={
<img
className={styles.logo}
src={require('./img/boundary-logo.svg')}
/>
}
tutorialLink={{
label: 'View Tutorial on HashiCorp Learn',
href:
'https://learn.hashicorp.com/tutorials/boundary/getting-started-install',
}}
/>
<div className="g-container">
<div className={styles.gettingStarted}>
<h2>Getting Started</h2>
<div className={styles.links}>
{getStartedLinks.map((link) => (
<a href={link.href} key={link.href}>
{link.label}
</a>
))}
</div>
</div>
</div>
<ReleaseInformation
brand="red"
productId="vault"
productName={productName}
releases={previousVersions}
latestVersion={releaseData.version}
/>
</div>
)

@ -1,4 +0,0 @@
#p-downloads {
margin-top: 72px;
margin-bottom: 72px;
}

@ -0,0 +1,61 @@
.root {
margin-top: 72px;
& a {
text-decoration: underline;
}
& h1 {
text-align: center;
}
--brand: var(--red);
--brand-d1: #c03e43;
}
.logo {
max-width: 140px;
}
.hosting {
border: 1px solid var(--gray-6);
padding: 16px;
text-align: center;
color: var(--gray-2);
}
.gettingStarted {
max-width: 680px;
margin: 40px auto 64px;
text-align: center;
& p {
color: var(--gray-3);
}
& a {
color: var(--black);
}
& h2 {
text-align: center;
margin: 16px 0;
}
@media (--medium-up) {
margin: 88px auto 128px;
}
}
.links {
margin-top: 32px;
& a {
text-align: center;
display: block;
margin: 8px 0;
}
}
.signUpButton {
margin-left: 26px;
}

@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 118 118"><defs><style>.cls-1{fill:#fff0f0;}.cls-2{fill:#f04e54;}</style></defs><path class="cls-1" d="M3,0H118a0,0,0,0,1,0,0V115a3,3,0,0,1-3,3H3a3,3,0,0,1-3-3V3A3,3,0,0,1,3,0Z"/><path class="cls-2" d="M41.56,71.15a1.21,1.21,0,0,1-.88-.37,1.25,1.25,0,0,1,0-1.77L52.87,56.82,40.68,44.62a1.25,1.25,0,1,1,1.77-1.76L55.52,55.94a1.23,1.23,0,0,1,0,1.76L42.45,70.78A1.25,1.25,0,0,1,41.56,71.15Z"/><path class="cls-2" d="M76.44,75.51H59A1.25,1.25,0,1,1,59,73H76.44a1.25,1.25,0,0,1,0,2.5Z"/></svg>

After

Width:  |  Height:  |  Size: 573 B

@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 118 118"><defs><style>.cls-1{fill:#fff0f0;}.cls-2,.cls-3,.cls-4{fill:none;stroke:#f04e54;stroke-width:2.5px;}.cls-3,.cls-4{stroke-linejoin:round;}.cls-4{stroke-linecap:round;}</style></defs><rect class="cls-1" width="118" height="118" rx="3"/><path class="cls-2" d="M39.1,71.73a7.61,7.61,0,0,1,7.61-7.61h0a7.62,7.62,0,0,1,7.62,7.61v3H39.1Z"/><path class="cls-3" d="M36.46,43.22A3.76,3.76,0,0,0,32.7,47V71a3.76,3.76,0,0,0,3.76,3.76H81.54A3.76,3.76,0,0,0,85.3,71V47a3.76,3.76,0,0,0-3.76-3.76Z"/><line class="cls-4" x1="60.93" y1="53.61" x2="78.13" y2="53.61"/><line class="cls-4" x1="60.93" y1="60.78" x2="67.65" y2="60.78"/><circle class="cls-2" cx="46.71" cy="57.25" r="6.87"/></svg>

After

Width:  |  Height:  |  Size: 769 B

@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 118 118"><defs><style>.cls-1{fill:#fff0f0;}.cls-2{fill:#f04e54;}</style></defs><path class="cls-1" d="M3,0H118a0,0,0,0,1,0,0V115a3,3,0,0,1-3,3H3a3,3,0,0,1-3-3V3A3,3,0,0,1,3,0Z"/><circle class="cls-2" cx="84.5" cy="75.5" r="1.25"/><path class="cls-2" d="M85.75,43.5a1.34,1.34,0,0,0-.09-.45V36h0a1.13,1.13,0,0,0,.09-.45,1.12,1.12,0,0,0-.1-.48,1.22,1.22,0,0,0-.31-.43l-.15-.13a1.43,1.43,0,0,0-.21-.12l-.24-.07a.65.65,0,0,0-.14,0l-.1,0h-48a1.25,1.25,0,0,0-1.25,1.25v48a1.12,1.12,0,0,0,.1.48,1.22,1.22,0,0,0,.67.67,1.12,1.12,0,0,0,.48.1h8a1.25,1.25,0,0,0,0-2.5H37.75V36.75H59.11V59.5a1.25,1.25,0,0,0,1.25,1.25H84.23l.12,0,.06,0h0l.08,0a1.25,1.25,0,0,0,1.25-1.25,1.34,1.34,0,0,0-.09-.45V52a1.17,1.17,0,0,0,0-.9V44A1.34,1.34,0,0,0,85.75,43.5ZM61.61,36.75H83.16v21.5H61.61Z"/><circle class="cls-2" cx="84.5" cy="67.5" r="1.25"/><path class="cls-2" d="M85.65,83a1.39,1.39,0,0,0-.11-.21,1.45,1.45,0,0,0-.35-.35L85,82.35a1.13,1.13,0,0,0-.24-.08,1.29,1.29,0,0,0-.48,0,1.13,1.13,0,0,0-.24.08l-.21.11a1,1,0,0,0-.19.16,1.25,1.25,0,0,0,.88,2.13,1.12,1.12,0,0,0,.48-.1,1.09,1.09,0,0,0,.4-.27,1.22,1.22,0,0,0,.37-.88,1.94,1.94,0,0,0,0-.24A1.13,1.13,0,0,0,85.65,83Z"/><circle class="cls-2" cx="60.5" cy="83.5" r="1.25"/><circle class="cls-2" cx="52.5" cy="83.5" r="1.25"/><circle class="cls-2" cx="68.5" cy="83.5" r="1.25"/><circle class="cls-2" cx="76.5" cy="83.5" r="1.25"/></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 118 118"><defs><style>.cls-1{fill:#fff0f0;}.cls-2{fill:#f04e54;}</style></defs><rect class="cls-1" width="118" height="118" rx="3"/><path class="cls-2" d="M59,58.25a1.24,1.24,0,0,1-.56-.13L38.61,48.2a1.24,1.24,0,0,1-.7-1.12,1.26,1.26,0,0,1,.7-1.12l19.83-9.91a1.23,1.23,0,0,1,1.12,0L79.39,46a1.26,1.26,0,0,1,.7,1.12,1.24,1.24,0,0,1-.7,1.12L59.56,58.12A1.24,1.24,0,0,1,59,58.25ZM42,47.08,59,55.6l17-8.52L59,38.56Z"/><path class="cls-2" d="M39.17,72.17a1.2,1.2,0,0,1-.88-.38A1.05,1.05,0,0,1,38,71.4a1.15,1.15,0,0,1-.1-.48,1,1,0,0,1,0-.25,1.19,1.19,0,0,1,.07-.23,1.39,1.39,0,0,1,.11-.21.77.77,0,0,1,.16-.19,1.24,1.24,0,0,1,1.13-.34.88.88,0,0,1,.23.07.65.65,0,0,1,.22.11,1.35,1.35,0,0,1,.19.16.74.74,0,0,1,.15.19,1.43,1.43,0,0,1,.12.21c0,.08.05.16.07.23a2,2,0,0,1,0,.25,1.32,1.32,0,0,1-.09.48,1.36,1.36,0,0,1-.27.39A1.23,1.23,0,0,1,39.17,72.17Z"/><path class="cls-2" d="M53.49,79.48a1.26,1.26,0,0,1-.56-1.69h0a1.24,1.24,0,0,1,1.68-.55h0a1.25,1.25,0,0,1,.56,1.68h0a1.26,1.26,0,0,1-1.12.69h0A1.24,1.24,0,0,1,53.49,79.48Zm-5-2.48A1.25,1.25,0,0,1,48,75.32h0a1.26,1.26,0,0,1,1.68-.57h0a1.26,1.26,0,0,1,.56,1.69h0a1.24,1.24,0,0,1-1.12.68h0A1.38,1.38,0,0,1,48.53,77Zm-5-2.48A1.26,1.26,0,0,1,43,72.83h0a1.24,1.24,0,0,1,1.68-.55h0A1.24,1.24,0,0,1,45.25,74h0a1.25,1.25,0,0,1-1.12.69h0A1.24,1.24,0,0,1,43.57,74.52Z"/><path class="cls-2" d="M59,82.08a1.2,1.2,0,0,1-.89-.37,1.21,1.21,0,0,1-.36-.88,1.64,1.64,0,0,1,0-.23,2.17,2.17,0,0,1,.07-.24.88.88,0,0,1,.12-.21.74.74,0,0,1,.15-.19l.19-.17a.88.88,0,0,1,.22-.1.63.63,0,0,1,.23-.08,1.35,1.35,0,0,1,.49,0,.63.63,0,0,1,.23.08.88.88,0,0,1,.22.1l.19.17a.77.77,0,0,1,.16.19,1.39,1.39,0,0,1,.11.21,1.09,1.09,0,0,1,.07.24.85.85,0,0,1,0,.23A1.26,1.26,0,0,1,59,82.08Z"/><path class="cls-2" d="M62.85,78.92a1.24,1.24,0,0,1,.56-1.68h0a1.23,1.23,0,0,1,1.67.55h0a1.26,1.26,0,0,1-.55,1.69h0a1.24,1.24,0,0,1-.56.13h0A1.25,1.25,0,0,1,62.85,78.92Zm5-2.48a1.27,1.27,0,0,1,.55-1.69h0a1.26,1.26,0,0,1,1.68.57h0A1.25,1.25,0,0,1,69.48,77h0a1.38,1.38,0,0,1-.56.12h0A1.21,1.21,0,0,1,67.81,76.44Zm5-2.48a1.26,1.26,0,0,1,.56-1.68h0a1.25,1.25,0,0,1,1.68.55h0a1.26,1.26,0,0,1-.56,1.69h0a1.23,1.23,0,0,1-.55.13h0A1.26,1.26,0,0,1,72.76,74Z"/><path class="cls-2" d="M78.84,72.17a1.2,1.2,0,0,1-.88-.38,1.18,1.18,0,0,1-.37-.87A1.24,1.24,0,0,1,78,70a1.27,1.27,0,0,1,1.13-.34.88.88,0,0,1,.23.07.65.65,0,0,1,.22.11,1,1,0,0,1,.19.16,1.23,1.23,0,0,1,.36.88,1.26,1.26,0,0,1-1.25,1.25Z"/><path class="cls-2" d="M39.17,60.25a1.22,1.22,0,0,1-.88-.37.93.93,0,0,1-.16-.18,2.26,2.26,0,0,1-.11-.22.88.88,0,0,1-.07-.23,1,1,0,0,1,0-.24,1,1,0,0,1,0-.25.88.88,0,0,1,.07-.23,1.51,1.51,0,0,1,.11-.22,1.46,1.46,0,0,1,.16-.19,1.3,1.3,0,0,1,1.77,0,1.39,1.39,0,0,1,.15.19,1.21,1.21,0,0,1,.19.45,1.51,1.51,0,0,1,0,.49,1.55,1.55,0,0,1-.07.23,2.39,2.39,0,0,1-.12.22,1.37,1.37,0,0,1-.34.34l-.22.12-.23.07A1.06,1.06,0,0,1,39.17,60.25Z"/><path class="cls-2" d="M53.49,67.56a1.25,1.25,0,0,1-.56-1.68h0a1.27,1.27,0,0,1,1.68-.56h0A1.26,1.26,0,0,1,55.17,67h0a1.26,1.26,0,0,1-1.12.69h0A1.24,1.24,0,0,1,53.49,67.56Zm-5-2.48A1.25,1.25,0,0,1,48,63.4h0a1.28,1.28,0,0,1,1.68-.57h0a1.27,1.27,0,0,1,.56,1.69h0a1.25,1.25,0,0,1-1.12.69h0A1.24,1.24,0,0,1,48.53,65.08Zm-5-2.48A1.25,1.25,0,0,1,43,60.92h0a1.25,1.25,0,0,1,1.68-.55h0A1.24,1.24,0,0,1,45.25,62h0a1.25,1.25,0,0,1-1.12.69h0A1.24,1.24,0,0,1,43.57,62.6Z"/><path class="cls-2" d="M59,70.17a1.21,1.21,0,0,1-.89-.38,1.19,1.19,0,0,1-.27-.39,1.32,1.32,0,0,1-.09-.48,2,2,0,0,1,0-.25c0-.07,0-.15.07-.23a.88.88,0,0,1,.12-.21.9.9,0,0,1,.15-.19,1.26,1.26,0,0,1,1.13-.34.88.88,0,0,1,.23.07.65.65,0,0,1,.22.11,1,1,0,0,1,.19.16,1.46,1.46,0,0,1,.16.19,1.39,1.39,0,0,1,.11.21,1.19,1.19,0,0,1,.07.23,1,1,0,0,1,0,.25,1.15,1.15,0,0,1-.1.48,1.05,1.05,0,0,1-.27.39A1.19,1.19,0,0,1,59,70.17Z"/><path class="cls-2" d="M62.85,67a1.25,1.25,0,0,1,.56-1.68h0a1.24,1.24,0,0,1,1.67.56h0a1.25,1.25,0,0,1-.55,1.68h0a1.24,1.24,0,0,1-.56.13h0A1.25,1.25,0,0,1,62.85,67Zm5-2.48a1.24,1.24,0,0,1,.55-1.67h0A1.25,1.25,0,0,1,70,63.4h0a1.25,1.25,0,0,1-.56,1.68h0a1.24,1.24,0,0,1-.56.13h0A1.22,1.22,0,0,1,67.81,64.52Zm5-2.48a1.25,1.25,0,0,1,.56-1.67h0a1.25,1.25,0,0,1,1.68.55h0a1.25,1.25,0,0,1-.56,1.68h0a1.24,1.24,0,0,1-.56.13h0A1.26,1.26,0,0,1,72.76,62Z"/><path class="cls-2" d="M78.84,60.25a1,1,0,0,1-.24,0l-.24-.07L78.15,60a.7.7,0,0,1-.19-.16,1.26,1.26,0,0,1-.37-.88,1.3,1.3,0,0,1,.37-.88.9.9,0,0,1,.19-.15l.21-.12.24-.07a1.35,1.35,0,0,1,.49,0l.23.07a.94.94,0,0,1,.22.12.9.9,0,0,1,.19.15,1.28,1.28,0,0,1,.36.88,1.25,1.25,0,0,1-1.25,1.25Z"/></svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 118 118"><defs><style>.cls-1{fill:#fff0f0;}.cls-2{fill:none;stroke:#f04e54;stroke-linecap:round;stroke-linejoin:round;stroke-width:2.5px;}</style></defs><rect class="cls-1" width="118" height="118" rx="3"/><polyline class="cls-2" points="65.53 42.2 74.86 42.2 74.86 51.53"/><line class="cls-2" x1="43.14" y1="73.93" x2="74.86" y2="42.2"/><polyline class="cls-2" points="74.86 66.47 74.86 75.8 65.53 75.8"/><line class="cls-2" x1="63.67" y1="64.6" x2="74.86" y2="75.8"/><line class="cls-2" x1="43.14" y1="44.07" x2="52.47" y2="53.4"/></svg>

After

Width:  |  Height:  |  Size: 625 B

@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 118 118"><defs><style>.cls-1{fill:#fff0f0;}.cls-2{fill:#f04e54;}</style></defs><rect class="cls-1" width="118" height="118" rx="3"/><path class="cls-2" d="M92.25,76.24,82.15,66.15A15.86,15.86,0,1,0,54.22,55.86a15.59,15.59,0,0,0,.64,4.39l-4,11.92-9.83-29.5a1.25,1.25,0,0,0-2.38,0L33.45,58.34H27a1.25,1.25,0,0,0,0,2.5h7.35A1.25,1.25,0,0,0,35.54,60l4.32-13L49.7,76.52a1.24,1.24,0,0,0,1.18.85,1.25,1.25,0,0,0,1.19-.85l4.26-12.8a15.82,15.82,0,0,0,24,4.19L90.48,78ZM70.09,42.49A13.33,13.33,0,0,1,83.22,58.34H57a12.64,12.64,0,0,1-.25-2.48A13.38,13.38,0,0,1,70.09,42.49ZM57.7,60.84H82.49a13.36,13.36,0,0,1-24.79,0Z"/></svg>

After

Width:  |  Height:  |  Size: 701 B

@ -0,0 +1 @@
<svg width="48" height="30" viewBox="0 0 48 30" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M13.432 11.09c0 .581.063 1.053.173 1.4.125.346.283.724.503 1.133.078.126.11.252.11.362 0 .157-.095.315-.299.472l-.99.66a.753.753 0 01-.41.142c-.156 0-.314-.078-.47-.22a4.881 4.881 0 01-.567-.74 12.238 12.238 0 01-.487-.928c-1.227 1.448-2.768 2.172-4.623 2.172-1.32 0-2.374-.378-3.145-1.133-.77-.756-1.163-1.763-1.163-3.022 0-1.337.472-2.423 1.43-3.242.96-.818 2.233-1.227 3.853-1.227.534 0 1.085.047 1.667.126.581.079 1.179.204 1.808.346V6.242c0-1.196-.252-2.03-.74-2.518-.502-.487-1.351-.723-2.562-.723-.55 0-1.116.063-1.698.204a12.52 12.52 0 00-1.698.535c-.252.11-.44.173-.55.205a.963.963 0 01-.252.047c-.22 0-.33-.157-.33-.488v-.77c0-.253.031-.442.11-.552.078-.11.22-.22.44-.33.55-.283 1.21-.52 1.981-.708a9.525 9.525 0 012.453-.3c1.87 0 3.239.426 4.12 1.275.864.85 1.304 2.14 1.304 3.872v5.098h.032zM7.048 13.48c.519 0 1.054-.094 1.62-.283a3.503 3.503 0 001.493-1.007c.252-.3.44-.63.535-1.007.094-.378.157-.834.157-1.37v-.66c-.456-.11-.943-.205-1.446-.268-.504-.063-.99-.094-1.478-.094-1.054 0-1.824.204-2.343.63-.519.424-.77 1.022-.77 1.809 0 .74.188 1.29.581 1.668.378.393.928.582 1.651.582zm12.626 1.7c-.283 0-.472-.047-.598-.158-.125-.094-.236-.314-.33-.613L15.051 2.245c-.094-.314-.141-.519-.141-.63 0-.251.125-.393.377-.393h1.54c.3 0 .504.048.614.158.126.094.22.314.315.613l2.641 10.418L22.85 1.993c.078-.314.173-.519.298-.613.126-.095.346-.158.63-.158h1.257c.299 0 .503.048.63.158.125.094.235.314.298.613l2.484 10.544 2.72-10.544c.095-.314.205-.519.315-.613.126-.095.33-.158.613-.158h1.462c.252 0 .393.126.393.394 0 .078-.016.157-.031.252-.016.094-.047.22-.11.393l-3.79 12.164c-.094.315-.204.52-.33.614-.125.095-.33.157-.597.157H27.74c-.3 0-.503-.047-.63-.157-.125-.11-.235-.315-.298-.63L24.375 4.26l-2.421 10.135c-.079.315-.173.52-.3.63-.125.11-.345.157-.628.157h-1.352zm20.204.425c-.818 0-1.635-.095-2.422-.284-.786-.188-1.399-.393-1.808-.63-.251-.14-.424-.298-.487-.44a1.111 1.111 0 01-.094-.44v-.803c0-.33.125-.488.361-.488.095 0 .189.016.283.047.095.032.236.095.393.158a8.55 8.55 0 001.73.55 9.434 9.434 0 001.87.19c.991 0 1.762-.174 2.296-.52.535-.346.818-.85.818-1.495 0-.44-.142-.802-.424-1.101-.283-.3-.818-.567-1.588-.819l-2.28-.708c-1.148-.362-1.997-.897-2.516-1.605-.519-.692-.786-1.463-.786-2.282 0-.66.141-1.243.424-1.747.283-.503.66-.944 1.132-1.29a4.988 4.988 0 011.636-.818 6.847 6.847 0 011.98-.268c.347 0 .708.016 1.054.063.362.047.692.11 1.022.173.315.079.613.158.896.252.283.094.503.189.66.283.22.126.378.252.472.394.095.126.142.299.142.519v.74c0 .33-.126.503-.362.503-.126 0-.33-.063-.597-.189-.896-.409-1.903-.613-3.019-.613-.896 0-1.604.141-2.091.44-.488.3-.74.756-.74 1.4 0 .441.158.82.473 1.118.314.3.896.598 1.729.866l2.233.708c1.132.362 1.95.865 2.437 1.51.487.646.723 1.385.723 2.204 0 .676-.142 1.29-.409 1.825a4.23 4.23 0 01-1.148 1.385c-.487.393-1.069.676-1.745.881a7.47 7.47 0 01-2.248.33z" fill="#BDBEC2"/><path fill-rule="evenodd" clip-rule="evenodd" d="M42.85 23.254c-5.173 3.824-12.688 5.854-19.15 5.854-9.057 0-17.217-3.352-23.38-8.923-.488-.44-.048-1.039.534-.692 6.666 3.87 14.89 6.216 23.396 6.216 5.739 0 12.044-1.197 17.845-3.651.865-.394 1.604.566.755 1.196z" fill="#BDBEC2"/><path fill-rule="evenodd" clip-rule="evenodd" d="M45.004 20.799c-.66-.85-4.371-.41-6.053-.205-.504.063-.582-.378-.126-.708 2.956-2.077 7.814-1.48 8.38-.787.566.708-.157 5.57-2.924 7.9-.425.362-.834.173-.645-.3.629-1.557 2.028-5.066 1.368-5.9z" fill="#BDBEC2"/></svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

@ -0,0 +1 @@
<svg width="103" height="30" viewBox="0 0 103 30" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M42.352 17.448l4.395 11.667h-2.232l-1.032-2.91h-4.598l-.993 2.898H35.68l4.394-11.667 2.278.012zm-1.204 2.166l-1.724 4.91h3.498l-1.717-4.91h-.057zM47.731 20.753h6.68v.79l-4.386 6.01h4.41v1.562h-7.012v-.935l4.318-5.868h-4.01v-1.559zM62.813 20.753v8.362H60.83v-1.1h-.035a2.664 2.664 0 01-1.047.884c-.456.221-.958.332-1.466.324a2.855 2.855 0 01-2.216-.828c-.513-.549-.77-1.404-.77-2.566v-5.076h2.013v4.849a2.529 2.529 0 00.42 1.589 1.508 1.508 0 001.265.531 1.67 1.67 0 001.34-.589c.351-.433.532-.981.507-1.539v-4.84h1.97zM68.742 20.615a2.078 2.078 0 01.739.112v1.992a1.7 1.7 0 00-.45-.215 2.194 2.194 0 00-.72-.1 1.54 1.54 0 00-1.223.608 2.932 2.932 0 00-.5 1.881v4.233H64.62v-8.373h1.97v1.316h.031c.16-.43.444-.802.816-1.07a2.19 2.19 0 011.304-.384zM76.569 27.006v1.62a4.234 4.234 0 01-1.278.5 7.18 7.18 0 01-1.685.193 3.875 3.875 0 01-2.97-1.132c-.709-.754-1.063-1.803-1.063-3.147a4.59 4.59 0 011.135-3.202 3.695 3.695 0 012.875-1.258 3.461 3.461 0 012.693 1.062c.642.708.962 1.685.962 2.932v.954h-5.722c.089.84.358 1.428.808 1.759a2.882 2.882 0 001.755.5 4.14 4.14 0 001.35-.215 4.32 4.32 0 001.14-.566zm-1.262-2.92a2.194 2.194 0 00-.45-1.49 1.62 1.62 0 00-1.274-.512 1.84 1.84 0 00-1.27.508 2.602 2.602 0 00-.747 1.494h3.74zM49.002 1.41v11.666h-2.028V3.93h-.03l-3.622 9.146H41.98L38.27 3.93h-.023v9.146h-1.874V1.41h2.905l3.352 8.635h.058l3.536-8.646 2.778.011zm1.693.884a1.062 1.062 0 01.354-.815 1.25 1.25 0 011.705 0 1.1 1.1 0 01.342.808 1.07 1.07 0 01-.35.808c-.232.214-.538.33-.854.323a1.181 1.181 0 01-1.108-.689 1.069 1.069 0 01-.089-.435zm2.17 2.417v8.365H50.9V4.711h1.966zm5.972 6.926c.333-.009.662-.078.97-.204.348-.133.676-.315.974-.538v1.843a3.964 3.964 0 01-1.07.408c-.43.096-.87.142-1.312.138a3.981 3.981 0 01-4.168-4.156 4.772 4.772 0 011.19-3.317c.787-.872 1.902-1.308 3.343-1.308.378.002.754.05 1.12.142.312.072.613.184.897.331v1.886a4.137 4.137 0 00-.931-.516 2.724 2.724 0 00-.97-.18 2.47 2.47 0 00-1.882.769 2.851 2.851 0 00-.715 2.043 2.724 2.724 0 00.688 1.978 2.49 2.49 0 001.878.689l-.011-.008zm7.55-7.072c.142-.002.284.01.424.034.109.015.216.042.319.081v1.993a1.727 1.727 0 00-.454-.215 2.193 2.193 0 00-.72-.1 1.54 1.54 0 00-1.223.608 2.928 2.928 0 00-.497 1.885v4.233h-1.97V4.711h1.97v1.32h.031c.16-.43.444-.802.816-1.07a2.2 2.2 0 011.304-.389v-.007zm.847 4.444a4.526 4.526 0 011.173-3.286c.77-.808 1.854-1.212 3.252-1.212a4.01 4.01 0 013.078 1.154 4.402 4.402 0 011.105 3.152 4.449 4.449 0 01-1.174 3.24 4.234 4.234 0 01-3.186 1.204 4.18 4.18 0 01-3.078-1.154 4.233 4.233 0 01-1.17-3.09v-.008zm2.05-.065c-.049.716.162 1.426.593 2a2.126 2.126 0 001.701.693 1.981 1.981 0 001.635-.692c.417-.601.615-1.326.562-2.055a3.078 3.078 0 00-.58-2.036 2.012 2.012 0 00-1.648-.658 2.067 2.067 0 00-1.681.72 3.15 3.15 0 00-.581 2.035v-.007zm9.47-2.044a.834.834 0 00.27.662c.362.261.762.466 1.185.608a4.052 4.052 0 011.659 1.062c.32.406.487.911.473 1.428a2.308 2.308 0 01-.904 1.897 3.849 3.849 0 01-2.455.716 5.87 5.87 0 01-1.155-.127 5.138 5.138 0 01-1.07-.324v-1.924a4.82 4.82 0 001.155.593c.359.139.739.215 1.123.223.34.021.678-.044.986-.188a.667.667 0 00.315-.628.875.875 0 00-.327-.688 5.076 5.076 0 00-1.25-.647 3.848 3.848 0 01-1.54-1.023 2.243 2.243 0 01-.454-1.447 2.285 2.285 0 01.9-1.859c.666-.51 1.49-.77 2.329-.731.33.004.66.038.985.1.312.051.617.135.912.25v1.874a4.196 4.196 0 00-.912-.45c-.33-.12-.68-.183-1.031-.185a1.516 1.516 0 00-.878.22.696.696 0 00-.315.596V6.9zm4.433 2.109a4.525 4.525 0 011.174-3.286c.77-.808 1.862-1.212 3.252-1.212a4.01 4.01 0 013.078 1.154 4.402 4.402 0 011.104 3.152 4.449 4.449 0 01-1.173 3.24 4.234 4.234 0 01-3.186 1.204 4.18 4.18 0 01-3.079-1.154 4.233 4.233 0 01-1.17-3.09v-.008zm2.052-.065c-.05.716.16 1.426.592 2a2.12 2.12 0 001.7.693 1.982 1.982 0 001.636-.692c.417-.601.615-1.326.562-2.055a3.078 3.078 0 00-.581-2.036 2.012 2.012 0 00-1.632-.658 2.063 2.063 0 00-1.681.72 3.151 3.151 0 00-.596 2.035v-.007zm13.083-2.629h-2.933v6.761h-1.993V6.323H92V4.711h1.397V3.556a2.904 2.904 0 01.854-2.166 3.018 3.018 0 012.201-.843c.213-.001.425.01.635.035.166.021.33.059.49.112v1.7a2.013 2.013 0 00-.343-.138 1.782 1.782 0 00-.562-.081 1.185 1.185 0 00-.95.385 1.7 1.7 0 00-.335 1.154v1.008h2.932V2.833l1.978-.604V4.71h1.993v1.612h-1.993v3.913c-.038.385.061.771.28 1.09a1.13 1.13 0 00.882.319c.141-.004.28-.033.411-.085.148-.046.289-.11.42-.192v1.627a2.274 2.274 0 01-.624.193 4.12 4.12 0 01-.858.092 2.444 2.444 0 01-1.866-.665 2.824 2.824 0 01-.623-1.998l.004-4.302zM13.524 1.41H.356v13.167h13.168V1.41zM28.062 1.41H14.894v13.167h13.168V1.41zM13.524 15.947H.356v13.168h13.168V15.947zM28.062 15.947H14.894v13.168h13.168V15.947z" fill="#BDBEC2"/></svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

@ -0,0 +1 @@
<svg width="54" height="54" viewBox="0 0 54 54" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="26.466" cy="27.251" fill="#BDBEC2" r="4.458"/><circle cx="35.141" cy="27.242" fill="#BDBEC2" r="2.057"/><circle cx="40.725" cy="23.944" r="2.057" fill="#BDBEC2"/><circle cx="43.658" cy="17.453" fill="#BDBEC2" r="2.057"/><circle cx="46.542" cy="23.859" r="2.021" fill="#BDBEC2"/><circle cx="40.746" cy="30.7" r="1.996" fill="#BDBEC2"/><circle cx="46.668" cy="30.535" r="1.91" fill="#BDBEC2"/><circle cx="43.582" cy="37.117" fill="#BDBEC2" r="2.082"/><path d="M26.549 47.952a20.65 20.65 0 1112.572-37.06L36.6 14.15a16.507 16.507 0 100 26.233l2.521 3.329a20.461 20.461 0 01-12.573 4.24z" fill="#BDBEC2"/></svg>

After

Width:  |  Height:  |  Size: 714 B

@ -0,0 +1 @@
<svg width="43" height="43" viewBox="0 0 43 43" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M26.175 14.16h1.086l3.095-3.094.152-1.314a13.91 13.91 0 00-22.63 6.787 1.684 1.684 0 011.086-.065l6.19-1.021s.315-.521.477-.489a7.72 7.72 0 0110.566-.803h-.022z" fill="#BDBEC2"/><path d="M34.764 16.539a13.942 13.942 0 00-4.202-6.776l-4.344 4.344a7.72 7.72 0 012.835 6.124V21a3.866 3.866 0 010 7.732H21.32l-.77.782v4.637l.77.77h7.732a10.055 10.055 0 005.711-18.383z" fill="#BDBEC2"/><path d="M13.58 34.879h7.73v-6.19h-7.73c-.552 0-1.096-.118-1.597-.347l-1.086.337-3.116 3.095-.272 1.085a10 10 0 006.07 2.02z" fill="#BDBEC2"/><path d="M13.58 14.802a10.055 10.055 0 00-6.07 18.025l4.484-4.485a3.866 3.866 0 115.114-5.114l4.485-4.485a10.044 10.044 0 00-8.014-3.941z" fill="#BDBEC2"/></svg>

After

Width:  |  Height:  |  Size: 789 B

@ -0,0 +1 @@
<svg width="38" height="39" viewBox="0 0 38 39" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M18.942.529C8.483.529 0 9.235 0 19.969c0 8.587 5.462 15.863 12.9 18.486.929.12 1.277-.477 1.277-.954v-3.339c-5.229 1.193-6.391-2.624-6.391-2.624-.814-2.266-2.092-2.862-2.092-2.862-1.743-1.193.116-1.193.116-1.193 1.86.12 2.906 2.028 2.906 2.028 1.743 2.981 4.416 2.146 5.461 1.67.117-1.313.698-2.148 1.162-2.625-4.183-.477-8.599-2.146-8.599-9.66 0-2.147.697-3.817 1.976-5.248-.117-.358-.814-2.385.232-5.009 0 0 1.627-.477 5.23 2.027 1.51-.476 3.137-.596 4.764-.596 1.627 0 3.254.239 4.764.596 3.603-2.504 5.23-2.027 5.23-2.027 1.046 2.624.348 4.651.232 5.129a7.826 7.826 0 011.976 5.247c0 7.514-4.416 9.064-8.6 9.541.698.597 1.279 1.79 1.279 3.578v5.367c0 .477.348 1.074 1.278.955C32.654 35.831 38 28.556 38 19.969 37.884 9.235 29.4.53 18.942.53z" fill="#BDBEC2"/></svg>

After

Width:  |  Height:  |  Size: 913 B

@ -0,0 +1 @@
<svg width="44" height="43" viewBox="0 0 44 43" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M20.842 17.267l.267-4.74a9.257 9.257 0 00-5.424 2.609l3.87 2.755.008-.004a.795.795 0 001.26-.61l.019-.01zM28.755 15.138a9.33 9.33 0 00-5.39-2.61l.267 4.732.003.002a.793.793 0 001.261.608l.014.006 3.845-2.738zM17.816 20.08l-3.534-3.174a9.339 9.339 0 00-1.315 5.891l4.53-1.313.003-.015a.798.798 0 00.311-1.369l.005-.02zM31.324 19.752a9.446 9.446 0 00-1.16-2.844l-3.514 3.16.002.009a.797.797 0 00.311 1.369l.004.02 4.553 1.316a9.444 9.444 0 00-.196-3.03zM22.959 20.326H21.51l-.902 1.127.323 1.41 1.304.63 1.3-.628.322-1.41-.9-1.13zM26.335 24.205a.788.788 0 00-.486.066.8.8 0 00-.385 1.033l-.006.007 1.819 4.412a9.311 9.311 0 003.75-4.732l-4.685-.796-.007.01zM19.044 24.83a.794.794 0 00-.917-.606l-.008-.01-4.644.792a9.35 9.35 0 003.739 4.7l1.8-4.368-.014-.017a.792.792 0 00.044-.49zM22.578 26.203a.794.794 0 00-1.042.342h-.004l-2.284 4.148c1.58.54 3.326.662 5.078.262.312-.071.617-.156.915-.256l-2.29-4.156h-.017a.79.79 0 00-.356-.34z" fill="#BDBEC2"/><path fill-rule="evenodd" clip-rule="evenodd" d="M20.985.284a2.884 2.884 0 012.496 0l15.034 7.21a2.873 2.873 0 011.556 1.942l3.714 16.204a2.852 2.852 0 01-.556 2.423l-10.4 12.995a2.873 2.873 0 01-2.248 1.075l-16.686.004a2.884 2.884 0 01-2.247-1.078L1.243 28.067a2.883 2.883 0 01-.554-2.423L4.398 9.44a2.859 2.859 0 011.555-1.943L20.985.284zm.35 6.238c0-.554.404-1.004.9-1.004.498 0 .9.45.9 1.004l.002.091c0 .059.002.12 0 .166-.007.211-.04.39-.074.57-.017.094-.034.189-.049.29l-.005.047c-.074.61-.135 1.118-.097 1.592.031.21.14.31.245.406l.05.045c.002.066.013.284.02.404 2.862.255 5.518 1.57 7.47 3.624l.342-.245.047.003c.129.01.345.027.5-.063.392-.266.75-.632 1.18-1.07l.032-.032c.068-.073.13-.144.191-.214.122-.14.242-.279.403-.418.04-.034.095-.077.145-.117l.055-.043c.432-.346 1.032-.31 1.342.081.31.39.21.987-.22 1.332l-.066.054c-.046.038-.094.078-.133.107-.168.124-.327.209-.488.295a6.637 6.637 0 00-.26.143c-.538.334-.984.61-1.338.944-.145.155-.155.304-.164.446a3.414 3.414 0 01-.005.066l-.137.123-.182.164a11.724 11.724 0 011.686 3.914c.326 1.426.377 2.85.188 4.22l.364.105.025.038c.072.106.196.29.363.354.458.145.974.2 1.594.265l.019.002c.102.008.198.012.294.016.184.007.364.014.57.053l.164.038c.034.01.068.017.097.024.53.129.87.618.761 1.1-.11.483-.628.776-1.161.661h-.007l-.007-.002c-.006-.001-.011-.004-.017-.006l-.086-.017a2.518 2.518 0 01-.147-.033 3.694 3.694 0 01-.536-.2c-.088-.038-.176-.076-.271-.113l-.027-.01c-.584-.21-1.069-.384-1.542-.453-.21-.017-.332.068-.448.15l-.056.037c-.065-.013-.268-.049-.384-.067a11.75 11.75 0 01-5.187 6.553c.014.033.03.079.048.127.038.1.079.211.102.238l-.025.063c-.053.131-.107.268-.044.47.174.455.457.9.797 1.434.057.085.114.163.17.24.108.148.215.294.313.48a4.625 4.625 0 01.117.244c.232.497.062 1.07-.382 1.284-.448.217-1.005-.012-1.244-.512a9.654 9.654 0 00-.034-.068c-.028-.056-.057-.117-.078-.163-.084-.195-.132-.37-.18-.55-.026-.091-.05-.183-.081-.279l-.009-.025c-.2-.59-.366-1.08-.608-1.494-.12-.177-.261-.22-.398-.261l-.062-.02-.09-.16c-.035-.067-.074-.138-.102-.187a11.578 11.578 0 01-8.304-.021l-.203.37c-.152.041-.298.083-.388.19-.23.276-.363.67-.505 1.087-.06.177-.12.358-.192.537-.03.097-.056.19-.08.283a3.727 3.727 0 01-.18.545 3.41 3.41 0 01-.11.23v.002c-.001 0-.002 0-.003.002-.24.498-.795.726-1.242.51-.444-.215-.614-.788-.382-1.285a5.49 5.49 0 00.04-.087c.026-.055.052-.113.075-.156.099-.187.206-.334.315-.484.056-.077.112-.154.168-.238.34-.535.64-1.015.814-1.47.044-.151-.021-.358-.08-.511l.163-.394a11.75 11.75 0 01-5.188-6.507l-.393.068a2.685 2.685 0 01-.04-.023c-.113-.066-.299-.175-.477-.16-.473.068-.959.243-1.543.453l-.026.01a6.89 6.89 0 00-.266.11c-.17.074-.337.145-.541.2a3.405 3.405 0 01-.233.053.06.06 0 00-.008.002l-.009.003-.013.002c-.534.116-1.052-.178-1.162-.66-.11-.482.231-.972.762-1.1l.013-.005h.004l.004-.002c.022-.005.047-.01.072-.017.058-.014.12-.03.168-.038.205-.04.386-.047.569-.054.096-.004.193-.008.294-.016l.02-.002c.62-.065 1.135-.12 1.593-.264.13-.054.255-.219.35-.345l.037-.047.377-.11a11.734 11.734 0 011.836-8.152l-.289-.26a2.99 2.99 0 01-.006-.041c-.019-.127-.051-.348-.175-.48-.353-.333-.8-.61-1.338-.944a6.592 6.592 0 00-.257-.142 3.694 3.694 0 01-.489-.296 3.502 3.502 0 01-.192-.155l-.007-.005c-.432-.346-.531-.942-.222-1.333a.865.865 0 01.718-.318c.215.007.438.086.626.237l.054.043c.05.04.106.083.146.117.16.139.279.276.4.415.061.072.124.144.192.217l.016.016c.437.446.8.816 1.197 1.085.184.107.33.084.47.061l.065-.01c.052.039.226.164.325.232a11.563 11.563 0 017.506-3.624l.02-.382c.12-.117.255-.284.293-.467.039-.483-.023-1.002-.098-1.627l-.002-.013a6.848 6.848 0 00-.049-.288 3.786 3.786 0 01-.074-.571c-.002-.045 0-.101 0-.157l.002-.075-.001-.012-.001-.013z" fill="#BDBEC2"/></svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

@ -0,0 +1 @@
<svg width="36" height="10" viewBox="0 0 36 10" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="4.922" cy="4.922" r="4.831" fill="#BDBEC2"/><circle cx="17.89" cy="4.922" r="4.831" fill="#BDBEC2"/><circle cx="30.858" cy="4.922" r="4.831" fill="#BDBEC2"/></svg>

After

Width:  |  Height:  |  Size: 270 B

@ -0,0 +1 @@
<svg width="64" height="23" viewBox="0 0 64 23" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M8.01 5.734C3.614 5.734 0 9.347 0 13.745s3.613 8.01 8.01 8.01c4.399 0 8.011-3.612 8.011-8.01s-3.612-8.01-8.01-8.01zm0 12.252c-2.198 0-4.083-1.885-4.083-4.084S5.655 9.818 8.01 9.818c2.199 0 4.084 1.885 4.084 4.084 0 2.2-1.885 4.084-4.084 4.084zM22.147 16.572c0-.628.786-.942 1.257-.47 2.042 2.041 5.34 5.654 5.34 5.654s.158.157.315.157h3.769c.629 0 .786-.785.472-1.1l-5.97-6.125-.313-.315c-.629-.785-.629-1.1.157-2.042l4.712-5.34c.314-.314.157-1.1-.628-1.1h-3.613c-.157 0-.314.157-.314.157s-2.67 2.828-4.241 4.556c-.471.47-1.257.157-1.257-.472v-9.11c0-.471-.314-.628-.628-.628h-2.513c-.471 0-.628.314-.628.628v20.263c0 .47.314.628.628.628h2.67c.471 0 .628-.314.628-.628v-.157l.157-4.556zM43.98 21.128l-.314-2.67c0-.315-.314-.629-.786-.629h-.628c-2.199 0-3.927-1.728-3.927-3.77v-3.455c0-.472.314-.786.786-.786h3.612c.315 0 .629-.157.629-.628V6.677c0-.471-.314-.786-.629-.786h-3.612c-.472 0-.786-.314-.786-.785V1.022c0-.314-.157-.628-.628-.628h-2.67c-.314 0-.629.157-.629.628v13.194c.157 4.398 3.613 7.854 8.011 7.854.314 0 .786 0 1.1-.157.314 0 .47-.314.47-.785zM63.3 17.829c-2.199 0-2.67-.785-2.67-3.927V6.52c0-.315-.157-.629-.628-.629h-2.67c-.315 0-.629.314-.629.629v.314c-1.1-.629-2.513-1.1-3.927-1.1-4.398 0-8.01 3.613-8.01 8.011s3.612 8.01 8.01 8.01c2.042 0 3.77-.785 5.184-1.884.785 1.1 1.885 1.885 3.927 1.885.314 0 2.042 0 2.042-.786v-2.827c-.157 0-.315-.314-.629-.314zm-10.524.157c-2.199 0-4.084-1.885-4.084-4.084s1.728-4.084 4.084-4.084 4.084 1.885 4.084 4.084c-.157 2.2-1.885 4.084-4.084 4.084z" fill="#BDBEC2"/></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

@ -0,0 +1 @@
<svg width="41" height="41" viewBox="0 0 41 41" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M40.522.279H.154v40.367h40.368V.28z" fill="#BDBEC2"/><path d="M11.462 16.771c-.785-.471-1.414-.628-3.613-.628H4.551V29.65h2.513v-5.026h1.414c1.413 0 1.885-.157 2.513-.471 1.414-.629 2.199-2.2 2.199-3.927.157-1.414-.471-2.67-1.728-3.456zm-1.257 5.027c-.314.628-.628.628-1.727.628H7.22v-4.084h1.57c1.1 0 1.729.785 1.729 2.042 0 .628-.157.942-.315 1.414zm-5.654 9.11h.628v5.497h-.628v-5.497zm6.754 1.413c-.471 0-.785.158-1.1.629-.314.471-.47.785-.47 1.57 0 1.257.628 2.042 1.57 2.042.471 0 .942-.157 1.257-.47l-.157-.472c-.315.314-.472.314-.943.314-.314 0-.628-.157-.942-.471-.157-.157-.157-.471-.157-.943v-.157h2.356v-.157c0-.942-.157-1.256-.472-1.727-.157 0-.628-.157-.942-.157zm-.942 1.728c0-.785.314-1.256.785-1.256.314 0 .471.157.628.314.157.157.157.471.157.942h-1.57zm5.811-1.1c0 .158.157.315.157.472v2.984h-.628v-2.67c0-.471 0-.471-.157-.628 0-.157-.157-.157-.471-.157-.314 0-.786.314-.943.628v2.827h-.628v-3.141c0-.628-.157-.785-.157-.785l.628-.157s.157.314.157.628c.314-.471.786-.629 1.1-.629.314 0 .785.158.942.629zm-2.042-16.02c0-.943.629-1.571 1.571-1.571.785 0 1.414.785 1.414 1.57 0 .943-.629 1.571-1.571 1.571-.785 0-1.414-.628-1.414-1.57zm.157 2.984l2.513-.471v10.21H14.29v-9.74zm3.456 12.566h.942l-.157.47h-.785v2.514c0 .471.157.628.471.628h.157v.471c-.157.158-.314.158-.471.158-.157 0-.314 0-.471-.157-.314-.158-.314-.315-.314-.786v-2.67h-.472v-.471h.472v-1.571h.628v1.414zm-8.796-1.571H8.32v1.885c-.158-.314-.629-.471-.943-.471-.314 0-.471 0-.628.314-.471.314-.786.942-.786 1.884 0 1.257.472 2.042 1.571 2.042.471 0 .628-.157.943-.47v.47h.628c-.157-.157-.157-.628-.157-1.256v-4.398zm-.471 4.398s0 .157-.157.314c-.158.157-.472.314-.629.314a.864.864 0 01-.785-.471c-.157-.157-.157-.628-.157-1.1 0-.628 0-.785.157-1.099.157-.314.471-.471.628-.471.471 0 .628.157.943.471v2.042zm17.749-2.984l-1.257 4.083c-.314.786-.47 1.257-1.256 1.414l-.157-.471c.314-.157.47-.314.628-.785 0-.315-.157-.472-.157-.472 0-.314-.314-1.1-.314-1.413l-.786-2.514.629-.157.785 2.514c.157.314.157.942.157.942s.157-.471.157-.785l.786-2.67h.785v.313zm.471 3.298c0-.157 0-.157-.157-.157h-.157v.628h.157v-.314l.157.314h.157l-.157-.314c-.157 0 0 0 0-.157zm-.314.157v-.157h.157s.157 0 .157.157h-.314zm0-.628c-.314 0-.628.314-.628.628s.314.628.628.628.628-.314.628-.628-.314-.628-.628-.628zm0 1.1c-.157 0-.471-.158-.471-.472 0-.314.157-.471.471-.471.157 0 .471.157.471.471 0 .314-.157.471-.471.471zm5.969-9.11h-1.257c-.314 0-.471-.158-.471-.158 0-.314.314-.471.942-.785h.315c2.042 0 3.455-1.257 3.455-2.985 0-.628-.157-1.1-.628-1.57h.628c.628 0 1.257-.158 1.728-.786l-1.1-1.728c-.628.472-1.256.786-1.884.786-.315 0-.629 0-1.1-.157-.628-.157-1.1-.314-1.728-.314-2.356 0-3.927 1.256-3.927 3.298 0 1.414.629 2.356 2.042 2.827-1.57.472-1.727 1.1-1.727 1.728 0 .628.314 1.1.785 1.257.471.157 1.1.314 2.199.314h1.1c.942 0 1.727.314 1.727 1.256 0 .472-.314.786-.628.943-.314.314-.942.314-1.57.314-1.1 0-1.729-.471-1.729-1.257 0-.314 0-.47.158-.628h-2.2c-.157.157-.157.471-.157.943 0 .628.315 1.256.786 1.727.785.786 2.199 1.1 3.613 1.1 1.413 0 2.827-.314 3.77-1.257.47-.628.785-1.256.785-2.042 0-.942-.315-1.57-.786-2.042-.942-.628-1.727-.785-3.141-.785zm-2.356-4.242c0-.942.47-1.414 1.413-1.414.943 0 1.414.472 1.414 1.414 0 .943-.471 1.414-1.57 1.414-.786 0-1.257-.471-1.257-1.414zm-7.069-1.256c-.47 0-1.1.314-1.727.942v7.068h-2.514v-7.225c0-.785-.157-1.728-.314-2.356l2.2-.628c.156.47.313.785.313 1.256.315-.314.629-.471 1.1-.785.471-.314 1.1-.471 1.728-.471 1.1 0 1.885.628 2.199 1.413.157.314.157.785.157 1.414v7.225h-2.356v-6.44c0-.942-.157-1.413-.786-1.413zm-1.256 11.152v2.513c0 .471.157.628.471.628h.157v.471c-.157.157-.314.157-.471.157-.157 0-.314 0-.471-.157-.314-.157-.314-.314-.314-.785v-2.67h-.472v-.471h.472v-1.571h.628v1.57h.942l-.157.472h-.785v-.157zm-2.356-.314l.628-.157v4.083h-.628V32.48z" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

@ -0,0 +1 @@
<svg width="45" height="44" viewBox="0 0 45 44" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M17.369 7.535l10.318 5.957v11.912L17.37 19.448V7.535zM28.816 13.492v11.912l10.319-5.956V7.53l-10.319 5.962zM5.917.882v11.912l10.319 5.962V6.838L5.917.882zM17.369 32.666l10.313 5.961V26.71l-10.313-5.956v11.913z" fill="#BDBEC2"/></svg>

After

Width:  |  Height:  |  Size: 377 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

@ -1,22 +1,231 @@
import BrandedCta from 'components/branded-cta'
import HomepageHero from 'components/homepage-hero'
import HowItWorks from 'components/how-it-works'
import SectionBreakCta from 'components/section-break-cta'
import ProductFeaturesList from '@hashicorp/react-product-features-list'
import UseCases from '@hashicorp/react-use-cases'
export default function HomePage() {
return (
<div className="p-home">
<HomepageHero
title="Identity-based secure access management"
title="Simple and secure remote access"
description="Access any system from anywhere based on user identity."
links={[
{
text: 'Download',
url: 'https://github.com/hashicorp/boundary/releases',
type: 'download',
title: 'Get Started',
url:
'https://learn.hashicorp.com/collections/boundary/getting-started',
external: true,
},
]}
uiVideo={{
url: '/videos/hero-ui.mp4',
srcType: 'mp4',
playbackRate: 2,
}}
cliVideo={{
url: '/videos/hero-cli.mp4',
srcType: 'mp4',
playbackRate: 1,
}}
/>
<HowItWorks
title="Secure access to hosts and services"
description="Traditional approaches like SSH bastion hosts or VPNs require distributing and managing credentials, configuring network controls like firewalls, and exposing the private network. Boundary provides a secure way to access hosts and critical systems without having to manage credentials or expose your network, and is entirely open source."
features={[
{
title: 'Authenticate',
description:
'Authenticate with any trusted identity provider you are already using. No need to distribute new credentials and manage them.',
logos: [
{
alt: 'GitHub',
url: require('./img/logos/github.svg?url'),
},
{
alt: 'AWS',
url: require('./img/logos/aws.svg?url'),
},
{
alt: 'Microsoft Azure',
url: require('./img/logos/azure.svg?url'),
},
{
alt: 'Google Cloud Platform',
url: require('./img/logos/gcp.svg?url'),
},
{
alt: 'Okta',
url: require('./img/logos/okta.svg?url'),
},
{
alt: 'Ping',
url: require('./img/logos/ping.svg?url'),
},
{
alt: 'More integrations',
url: require('./img/logos/more.svg?url'),
},
],
},
{
title: 'Authorize',
description:
'Authorize access based on logical roles and services, instead of physical IP addresses. Manage dynamic infrastructure and integrate service registries so hosts and service catalogs are kept up-to-date.',
logos: [
{
alt: 'Consul',
url: require('./img/logos/consul.svg?url'),
},
{
alt: 'AWS',
url: require('./img/logos/aws.svg?url'),
},
{
alt: 'Microsoft Azure',
url: require('./img/logos/azure.svg?url'),
},
{
alt: 'Terraform',
url: require('./img/logos/terraform.svg?url'),
},
{
alt: 'Google Cloud Platform',
url: require('./img/logos/gcp.svg?url'),
},
{
alt: 'Kubernetes',
url: require('./img/logos/kubernetes.svg?url'),
},
{
url: require('./img/logos/more.svg?url'),
alt: 'More integrations',
},
],
},
{
title: 'Access',
description:
'Automate credential injection to securely access services and hosts with HashiCorp Vault. Reduce risk of leaking credentials with dynamic secrets and just-in-time credentials.',
},
]}
/>
<div className="use-cases-section">
<div className="g-grid-container">
<h2 className="g-type-display-2">Use cases</h2>
<UseCases
items={[
{
title: 'Easily onboard and manage users',
description:
'Use SSO to manage onboarding and off-boarding users.',
image: {
url: require('./img/red-usecase-accessmgmt.png?url'),
},
link: {
title: 'Learn more',
url:
'https://learn.hashicorp.com/tutorials/boundary/getting-started-config',
},
},
{
title: 'Open and extensible remote access',
description:
'Integrate with existing tooling and APIs to simplify access.',
image: {
url: require('./img/red-usecase-accessprivileges.png?url'),
},
link: {
title: 'Learn more',
url: '/docs/common-workflows/manage-identities',
},
},
{
title: 'Compliance without overhead',
description:
'Provide session visibility that enables teams to stay compliant.',
image: {
url: require('./img/red-usecase-sessionvisibility.png?url'),
},
link: {
title: 'Learn more',
url: '/docs/common-workflows/manage-sessions',
},
},
]}
/>
</div>
</div>
<div className="break-section">
<SectionBreakCta
heading="Have you tried Boundary?"
content="Share your feedback for a chance to receive special swag."
link={{
text: 'Share your Boundary story',
url: 'http://hashi.co/boundary-survey',
}}
/>
</div>
<section className="features-section">
<ProductFeaturesList
heading="Boundary Features"
features={[
{
title: 'Identity-based access',
content:
'Enables privileged sessions for users and applications based on user identity and role.',
icon: require('./img/features/identity-based-access.svg?url'),
},
{
title: 'Session management',
content:
'Ensures access control regardless of user or operators infrastructure.',
icon: require('./img/features/session-management.svg?url'),
},
{
title: 'Platform agnostic',
content:
'One workflow for identity-based access across clouds, kubernetes clusters, and on-prem infrastructure.',
icon: require('./img/features/platform-agnosticity.svg?url'),
},
{
title: 'Session visibility',
content:
'Visibility into session metrics, events, logs, and traces with the ability to export data to business intelligence and event monitoring tools.',
icon: require('./img/features/session-visibility.svg?url'),
},
{
title: 'Infrastructure as code',
content:
'Define policies and manage Boundary with an Infrastructure as Code approach. Terraform provider supports the full breadth of Boundary configurations.',
icon: require('./img/features/config-as-code.svg?url'),
},
{
title: 'Manage dynamic environments',
content:
'Secure access to dynamic systems and applications with automated controls.',
icon: require('./img/features/managing-dynamic-environments.svg?url'),
},
]}
/>
</section>
<BrandedCta
heading="Ready to get started?"
content="Boundary is an open source solution that automates a secure identity-based user access to hosts and services across environments."
links={[
{
text: 'Get Started',
url: '/docs/getting-started',
type: 'inbound',
url:
'https://learn.hashicorp.com/collections/boundary/getting-started',
type: 'outbound',
},
{ text: 'Explore documentation', url: '/docs' },
]}
/>
</div>

@ -1,3 +1,49 @@
p {
color: black;
.p-home {
& .break-section {
background: linear-gradient(
var(--gray-7) 0%,
var(--gray-7) 50%,
var(--white) 50%,
var(--white) 100%
);
}
& .features-section {
padding: 128px 0;
@media (max-width: 800px) {
padding: 88px 0;
}
& > * {
padding-top: 0;
padding-bottom: 0;
}
}
& .use-cases-section {
padding-top: 128px;
padding-bottom: 128px;
background-color: var(--gray-7);
@media (max-width: 800px) {
padding-top: 88px;
}
& .g-use-cases {
& .icon {
min-height: 140px;
margin-bottom: 25px;
}
}
& h2 {
margin: 0;
text-align: center;
margin-bottom: 64px;
@media (max-width: 800px) {
margin-bottom: 48px;
}
}
}
}

@ -0,0 +1,37 @@
import styles from './styles.module.css'
export default function SecurityPage() {
return (
<div className={styles.securityPage}>
<div className="g-container">
<div className={styles.longformWrapper}>
<h2>Security</h2>
<p>
We understand that many users place a high level of trust in
HashiCorp and the tools we build. We apply best practices and focus
on security to make sure we can maintain the trust of the community.
</p>
<p>
We deeply appreciate any effort to disclose vulnerabilities
responsibly.
</p>
<p>
If you would like to report a vulnerability, please see the{' '}
<a href="https://www.hashicorp.com/security">
HashiCorp security page
</a>{' '}
which has the proper email to communicate with as well as our PGP
key.
</p>
<p>
{' '}
If you aren&apos;t reporting a security sensitive vulnerability,
please open an issue on the standard{' '}
<a href="https://github.com/hashicorp/boundary">GitHub</a>{' '}
repository.
</p>
</div>
</div>
</div>
)
}

@ -0,0 +1,15 @@
.securityPage {
& .longformWrapper {
@media (min-width: 800px) {
margin-top: 80px;
margin-bottom: 80px;
max-width: 70%;
margin-left: auto;
margin-right: auto;
}
& a {
color: var(--red);
}
}
}

@ -1,5 +0,0 @@
import PageComponent from 'components/signin-error-page'
export default function SigninErrorPage() {
return <PageComponent />
}

@ -6,35 +6,33 @@
@import '~@hashicorp/react-global-styles/_temporary-to-remove/layout.css';
@import '~@hashicorp/react-global-styles/_temporary-to-remove/tables.css';
@import '~@hashicorp/react-button/dist/style.css';
@import '~@hashicorp/react-hero/dist/style.css';
@import '~@hashicorp/react-button/styles/index.css';
@import '~@hashicorp/react-consent-manager/dist/style.css';
@import '~@hashicorp/react-toggle/dist/style.css';
@import '~@hashicorp/react-section-header/dist/style.css';
@import '~@hashicorp/react-product-downloader/dist/style.css';
@import '~@hashicorp/react-vertical-text-block-list/dist/style.css';
@import '~@hashicorp/react-docs-sidenav/dist/style.css';
@import '~@hashicorp/react-content/dist/style.css';
@import '~@hashicorp/react-docs-sidenav/style.css';
@import '~@hashicorp/react-content/style.css';
@import '~@hashicorp/react-subnav/dist/style.css';
@import '~@hashicorp/react-tabs/dist/style.css';
@import '~@hashicorp/react-enterprise-alert/dist/style.css';
@import '~@hashicorp/react-mega-nav/style.css';
@import '~@hashicorp/react-docs-page/style.css';
@import '~@hashicorp/react-product-features-list/style.css';
@import '~@hashicorp/react-use-cases/dist/style.css';
@import '~@hashicorp/react-alert-banner/style.css';
/* Local Components */
@import '../components/footer/style.css';
/* Local Pages */
@import './downloads/style.css';
@import './community/style.css';
@import './home/style.css';
/* Print Styles */
@import './print.css';
/* Expand content so footer is always at the bottom */
.__next > .content {
min-height: calc(100vh - 260px);
}
/*
* About this selector:
* `.g-subnav ~ *` finds all elements after the navigation.
@ -52,14 +50,6 @@
scroll-margin-top: calc(64px + 0.5em);
}
/* Sticky Footer */
.content {
overflow-y: auto;
/* 100% height - nav - footer */
min-height: calc(100vh - (64px + 77px));
}
/* Web Fonts */
@font-face {
font-family: 'klavika-web';
@ -148,36 +138,19 @@
* TODO, eventually remove:
* Temporary Boundary Branding
*/
:root {
--boundary: #f04e54;
}
.g-docs-sidenav {
--highlight-color: var(--boundary);
--highlight-color: var(--red);
}
.g-subnav {
& a.variant-primary {
border-color: var(--boundary);
background-color: var(--boundary);
border-color: var(--red);
background-color: var(--red);
}
& .g-subnav-inner {
& .style-menu-item {
& .text::after {
background: var(--boundary);
}
}
}
}
.g-content {
--highlight-color: var(--boundary);
}
.g-vertical-text-block-list {
& .list {
& .body-text {
& a {
color: var(--boundary) !important;
background: var(--red);
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 165 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.
Loading…
Cancel
Save