diff --git a/_assets/css/tailwind.css b/_assets/css/tailwind.css index fa560f1..3dc518c 100644 --- a/_assets/css/tailwind.css +++ b/_assets/css/tailwind.css @@ -221,14 +221,15 @@ } } -/* Blog Post & Page Styles */ -.blog-post, .page { +/* Blog Post, Page & FAQ Styles */ +.blog-post, .page, .faq-content { font-family: "Inter Variable", "Inter", ui-sans-serif, system-ui, sans-serif; } /* Headings */ .blog-post h1, .blog-post h2, .blog-post h3, .blog-post h4, .blog-post h5, .blog-post h6, -.page h1, .page h2, .page h3, .page h4, .page h5, .page h6 { +.page h1, .page h2, .page h3, .page h4, .page h5, .page h6, +.faq-content h1, .faq-content h2, .faq-content h3, .faq-content h4, .faq-content h5, .faq-content h6 { color: #141035; font-weight: 600; line-height: 1.3; @@ -236,7 +237,7 @@ margin-bottom: 1rem; /* 16px */ } -.blog-post h1, .page h1 { +.blog-post h1, .page h1, .faq-content h1 { font-size: 2.25rem; /* 36px */ font-weight: 700; line-height: 1.2; @@ -245,74 +246,74 @@ } @media (min-width: 768px) { - .blog-post h1, .page h1 { + .blog-post h1, .page h1, .faq-content h1 { font-size: 3rem; /* 48px */ } } @media (min-width: 1024px) { - .blog-post h1, .page h1 { + .blog-post h1, .page h1, .faq-content h1 { font-size: 3.5rem; /* 56px */ } } -.blog-post h2, .page h2 { +.blog-post h2, .page h2, .faq-content h2 { font-size: 1.75rem; /* 28px */ margin-top: 3rem; /* 48px */ } @media (min-width: 768px) { - .blog-post h2, .page h2 { + .blog-post h2, .page h2, .faq-content h2 { font-size: 2.25rem; /* 36px */ } } -.blog-post h3, .page h3 { +.blog-post h3, .page h3, .faq-content h3 { font-size: 1.5rem; /* 24px */ margin-top: 2.5rem; /* 40px */ } @media (min-width: 768px) { - .blog-post h3, .page h3 { + .blog-post h3, .page h3, .faq-content h3 { font-size: 1.75rem; /* 28px */ } } -.blog-post h4, .page h4 { +.blog-post h4, .page h4, .faq-content h4 { font-size: 1.25rem; /* 20px */ margin-top: 2rem; /* 32px */ } @media (min-width: 768px) { - .blog-post h4, .page h4 { + .blog-post h4, .page h4, .faq-content h4 { font-size: 1.375rem; /* 22px */ } } -.blog-post h5, .page h5 { +.blog-post h5, .page h5, .faq-content h5 { font-size: 1.125rem; /* 18px */ margin-top: 1.5rem; /* 24px */ } @media (min-width: 768px) { - .blog-post h5, .page h5 { + .blog-post h5, .page h5, .faq-content h5 { font-size: 1.25rem; /* 20px */ } } -.blog-post h6, .page h6 { +.blog-post h6, .page h6, .faq-content h6 { font-size: 1rem; /* 16px */ margin-top: 1.25rem; /* 20px */ } @media (min-width: 768px) { - .blog-post h6, .page h6 { + .blog-post h6, .page h6, .faq-content h6 { font-size: 1.125rem; /* 18px */ } } /* Paragraphs */ -.blog-post p, .page p { +.blog-post p, .page p, .faq-content p { color: #5E5E5E; font-size: 1.125rem; /* 18px */ line-height: 1.7; @@ -320,52 +321,55 @@ } @media (min-width: 768px) { - .blog-post p, .page p { + .blog-post p, .page p, .faq-content p { font-size: 1.25rem; /* 20px */ line-height: 1.8; } } /* First paragraph styling */ -.blog-post > p:first-of-type, .page > p:first-of-type { +.blog-post > p:first-of-type, .page > p:first-of-type, .faq-content > p:first-of-type { font-size: 1.25rem; /* 20px */ color: #141035; } @media (min-width: 768px) { - .blog-post > p:first-of-type, .page > p:first-of-type { + .blog-post > p:first-of-type, .page > p:first-of-type, .faq-content > p:first-of-type { font-size: 1.375rem; /* 22px */ line-height: 1.8; } } /* Links */ -.blog-post a, .page a { +.blog-post a, .page a, .faq-content a { color: #8A7DFF; text-decoration: underline; text-underline-offset: 3px; transition: all 0.2s ease; } -.blog-post a:hover, .page a:hover { +.blog-post a:hover, .page a:hover, .faq-content a:hover { color: #7A6DE5; text-decoration-thickness: 2px; } .blog-post strong, .blog-post b, -.page strong, .page b { +.page strong, .page b, +.faq-content strong, .faq-content b { color: #141035; font-weight: 600; } .blog-post em, .blog-post i, -.page em, .page i { +.page em, .page i, +.faq-content em, .faq-content i { font-style: italic; } /* Lists */ .blog-post ul, .blog-post ol, -.page ul, .page ol { +.page ul, .page ol, +.faq-content ul, .faq-content ol { font-size: 1.125rem; /* 18px */ line-height: 1.7; margin-bottom: 1.5rem; /* 24px */ @@ -375,34 +379,35 @@ @media (min-width: 768px) { .blog-post ul, .blog-post ol, - .page ul, .page ol { + .page ul, .page ol, + .faq-content ul, .faq-content ol { font-size: 1.25rem; /* 20px */ line-height: 1.8; } } -.blog-post li, .page li { +.blog-post li, .page li, .faq-content li { margin-bottom: 0.75rem; /* 12px */ padding-left: 0.5rem; /* 8px */ } -.blog-post li:last-child, .page li:last-child { +.blog-post li:last-child, .page li:last-child, .faq-content li:last-child { margin-bottom: 0; } -.blog-post ul, .page ul { +.blog-post ul, .page ul, .faq-content ul { list-style: disc; } -.blog-post ul li::marker, .page ul li::marker { +.blog-post ul li::marker, .page ul li::marker, .faq-content ul li::marker { color: #8A7DFF; } -.blog-post ol, .page ol { +.blog-post ol, .page ol, .faq-content ol { list-style: decimal; } -.blog-post ol li::marker, .page ol li::marker { +.blog-post ol li::marker, .page ol li::marker, .faq-content ol li::marker { color: #8A7DFF; font-weight: 600; } @@ -455,7 +460,7 @@ } /* Blockquotes */ -.blog-post blockquote, .page blockquote { +.blog-post blockquote, .page blockquote, .faq-content blockquote { position: relative; margin: 2rem 0; /* 32px */ padding: 1.5rem 1.5rem 1.5rem 3rem; /* 24px 24px 24px 48px */ @@ -468,24 +473,24 @@ } @media (min-width: 768px) { - .blog-post blockquote, .page blockquote { + .blog-post blockquote, .page blockquote, .faq-content blockquote { margin: 2.5rem 0; /* 40px */ padding: 2rem 2rem 2rem 3.5rem; /* 32px 32px 32px 56px */ font-size: 1.25rem; /* 20px */ } } -.blog-post blockquote p, .page blockquote p { +.blog-post blockquote p, .page blockquote p, .faq-content blockquote p { margin: 0; color: #141035; } -.blog-post blockquote p:not(:last-child), .page blockquote p:not(:last-child) { +.blog-post blockquote p:not(:last-child), .page blockquote p:not(:last-child), .faq-content blockquote p:not(:last-child) { margin-bottom: 1rem; /* 16px */ } /* TL;DR blocks */ -.blog-post .tldr, .page .tldr { +.blog-post .tldr, .page .tldr, .faq-content .tldr { margin: 0 0 2rem 0; /* 32px */ padding: 1.25rem 1.5rem; /* 20px 24px */ background: linear-gradient(135deg, rgba(138, 125, 255, 0.08) 0%, rgba(138, 125, 255, 0.03) 100%); @@ -494,12 +499,12 @@ } @media (min-width: 768px) { - .blog-post .tldr, .page .tldr { + .blog-post .tldr, .page .tldr, .faq-content .tldr { padding: 1.5rem 2rem; /* 24px 32px */ } } -.blog-post .tldr .tldr-label, .page .tldr .tldr-label { +.blog-post .tldr .tldr-label, .page .tldr .tldr-label, .faq-content .tldr .tldr-label { display: block; font-size: 0.75rem; /* 12px */ font-weight: 700; @@ -509,7 +514,7 @@ margin-bottom: 0.5rem; /* 8px */ } -.blog-post .tldr p, .page .tldr p { +.blog-post .tldr p, .page .tldr p, .faq-content .tldr p { margin: 0; font-size: 1rem; /* 16px */ line-height: 1.7; @@ -517,13 +522,13 @@ } @media (min-width: 768px) { - .blog-post .tldr p, .page .tldr p { + .blog-post .tldr p, .page .tldr p, .faq-content .tldr p { font-size: 1.125rem; /* 18px */ } } /* Code */ -.blog-post code, .page code { +.blog-post code, .page code, .faq-content code { background: #f1f5f9; color: #334155; padding: 0.1875rem 0.5rem; /* 3px 8px */ @@ -533,7 +538,7 @@ border: 1px solid #e2e8f0; } -.blog-post pre, .page pre { +.blog-post pre, .page pre, .faq-content pre { background: #1e293b; color: #e2e8f0; padding: 1.5rem; /* 24px */ @@ -544,7 +549,7 @@ box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); } -.blog-post pre code, .page pre code { +.blog-post pre code, .page pre code, .faq-content pre code { background: transparent; padding: 0; border: none; @@ -553,13 +558,13 @@ } @media (min-width: 768px) { - .blog-post pre code, .page pre code { + .blog-post pre code, .page pre code, .faq-content pre code { font-size: 1rem; /* 16px */ } } /* Tables */ -.blog-post table, .page table { +.blog-post table, .page table, .faq-content table { display: block; width: 100%; overflow-x: auto; @@ -570,19 +575,20 @@ } @media (min-width: 768px) { - .blog-post table, .page table { + .blog-post table, .page table, .faq-content table { font-size: 1.125rem; /* 18px */ } } .blog-post th, .blog-post td, -.page th, .page td { +.page th, .page td, +.faq-content th, .faq-content td { border: 1px solid #e5e7eb; padding: 0.75rem 1rem; /* 12px 16px */ text-align: left; } -.blog-post th, .page th { +.blog-post th, .page th, .faq-content th { background-color: #f9fafb; color: #141035; font-weight: 600; @@ -591,21 +597,21 @@ letter-spacing: 0.05em; } -.blog-post tbody tr, .page tbody tr { +.blog-post tbody tr, .page tbody tr, .faq-content tbody tr { background: #FFF; transition: background-color 0.2s ease; } -.blog-post tbody tr:hover, .page tbody tr:hover { +.blog-post tbody tr:hover, .page tbody tr:hover, .faq-content tbody tr:hover { background: #f9fafb; } -.blog-post td, .page td { +.blog-post td, .page td, .faq-content td { color: #5E5E5E; } /* Horizontal rules */ -.blog-post hr, .page hr { +.blog-post hr, .page hr, .faq-content hr { margin: 3rem 0; /* 48px */ border: none; height: 2px; @@ -613,7 +619,7 @@ } @media (min-width: 768px) { - .blog-post hr, .page hr { + .blog-post hr, .page hr, .faq-content hr { margin: 4rem 0; /* 64px */ } } diff --git a/assets/css/styles.css b/assets/css/styles.css index bed4009..b1ea31c 100644 --- a/assets/css/styles.css +++ b/assets/css/styles.css @@ -816,6 +816,10 @@ a.button:hover { margin-bottom: 0px !important; } +.\!mb-2 { + margin-bottom: 0.5rem !important; +} + .\!mb-4 { margin-bottom: 1rem !important; } @@ -920,6 +924,10 @@ a.button:hover { margin-top: 6rem; } +.mt-3 { + margin-top: 0.75rem; +} + .mt-4 { margin-top: 1rem; } @@ -928,6 +936,10 @@ a.button:hover { margin-top: 1.5rem; } +.mt-8 { + margin-top: 2rem; +} + .mt-auto { margin-top: auto; } @@ -1238,6 +1250,10 @@ a.button:hover { justify-content: flex-start; } +.justify-end { + justify-content: flex-end; +} + .justify-center { justify-content: center; } @@ -1307,6 +1323,12 @@ a.button:hover { margin-bottom: calc(6rem * var(--tw-space-y-reverse)); } +.space-y-3 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.75rem * var(--tw-space-y-reverse)); +} + .space-y-4 > :not([hidden]) ~ :not([hidden]) { --tw-space-y-reverse: 0; margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse))); @@ -1546,6 +1568,10 @@ a.button:hover { background-color: rgb(34 197 94 / var(--tw-bg-opacity, 1)); } +.bg-green-500\/10 { + background-color: rgb(34 197 94 / 0.1); +} + .bg-pink-50 { --tw-bg-opacity: 1; background-color: rgb(253 242 248 / var(--tw-bg-opacity, 1)); @@ -1681,6 +1707,10 @@ a.button:hover { padding: 1rem; } +.p-5 { + padding: 1.25rem; +} + .p-6 { padding: 1.5rem; } @@ -2037,6 +2067,11 @@ a.button:hover { color: rgb(31 41 55 / var(--tw-text-opacity, 1)); } +.text-green-400 { + --tw-text-opacity: 1; + color: rgb(74 222 128 / var(--tw-text-opacity, 1)); +} + .text-green-600 { --tw-text-opacity: 1; color: rgb(22 163 74 / var(--tw-text-opacity, 1)); @@ -2092,6 +2127,16 @@ a.button:hover { text-underline-offset: 2px; } +.placeholder-gray-400::-moz-placeholder { + --tw-placeholder-opacity: 1; + color: rgb(156 163 175 / var(--tw-placeholder-opacity, 1)); +} + +.placeholder-gray-400::placeholder { + --tw-placeholder-opacity: 1; + color: rgb(156 163 175 / var(--tw-placeholder-opacity, 1)); +} + .opacity-0 { opacity: 0; } @@ -2214,14 +2259,15 @@ a.button:hover { } } -/* Blog Post & Page Styles */ -.blog-post, .page { +/* Blog Post, Page & FAQ Styles */ +.blog-post, .page, .faq-content { font-family: "Inter Variable", "Inter", ui-sans-serif, system-ui, sans-serif; } /* Headings */ .blog-post h1, .blog-post h2, .blog-post h3, .blog-post h4, .blog-post h5, .blog-post h6, -.page h1, .page h2, .page h3, .page h4, .page h5, .page h6 { +.page h1, .page h2, .page h3, .page h4, .page h5, .page h6, +.faq-content h1, .faq-content h2, .faq-content h3, .faq-content h4, .faq-content h5, .faq-content h6 { color: #141035; font-weight: 600; line-height: 1.3; @@ -2229,7 +2275,7 @@ a.button:hover { margin-bottom: 1rem; /* 16px */ } -.blog-post h1, .page h1 { +.blog-post h1, .page h1, .faq-content h1 { font-size: 2.25rem; /* 36px */ font-weight: 700; line-height: 1.2; @@ -2238,74 +2284,74 @@ a.button:hover { } @media (min-width: 768px) { - .blog-post h1, .page h1 { + .blog-post h1, .page h1, .faq-content h1 { font-size: 3rem; /* 48px */ } } @media (min-width: 1024px) { - .blog-post h1, .page h1 { + .blog-post h1, .page h1, .faq-content h1 { font-size: 3.5rem; /* 56px */ } } -.blog-post h2, .page h2 { +.blog-post h2, .page h2, .faq-content h2 { font-size: 1.75rem; /* 28px */ margin-top: 3rem; /* 48px */ } @media (min-width: 768px) { - .blog-post h2, .page h2 { + .blog-post h2, .page h2, .faq-content h2 { font-size: 2.25rem; /* 36px */ } } -.blog-post h3, .page h3 { +.blog-post h3, .page h3, .faq-content h3 { font-size: 1.5rem; /* 24px */ margin-top: 2.5rem; /* 40px */ } @media (min-width: 768px) { - .blog-post h3, .page h3 { + .blog-post h3, .page h3, .faq-content h3 { font-size: 1.75rem; /* 28px */ } } -.blog-post h4, .page h4 { +.blog-post h4, .page h4, .faq-content h4 { font-size: 1.25rem; /* 20px */ margin-top: 2rem; /* 32px */ } @media (min-width: 768px) { - .blog-post h4, .page h4 { + .blog-post h4, .page h4, .faq-content h4 { font-size: 1.375rem; /* 22px */ } } -.blog-post h5, .page h5 { +.blog-post h5, .page h5, .faq-content h5 { font-size: 1.125rem; /* 18px */ margin-top: 1.5rem; /* 24px */ } @media (min-width: 768px) { - .blog-post h5, .page h5 { + .blog-post h5, .page h5, .faq-content h5 { font-size: 1.25rem; /* 20px */ } } -.blog-post h6, .page h6 { +.blog-post h6, .page h6, .faq-content h6 { font-size: 1rem; /* 16px */ margin-top: 1.25rem; /* 20px */ } @media (min-width: 768px) { - .blog-post h6, .page h6 { + .blog-post h6, .page h6, .faq-content h6 { font-size: 1.125rem; /* 18px */ } } /* Paragraphs */ -.blog-post p, .page p { +.blog-post p, .page p, .faq-content p { color: #5E5E5E; font-size: 1.125rem; /* 18px */ line-height: 1.7; @@ -2313,52 +2359,55 @@ a.button:hover { } @media (min-width: 768px) { - .blog-post p, .page p { + .blog-post p, .page p, .faq-content p { font-size: 1.25rem; /* 20px */ line-height: 1.8; } } /* First paragraph styling */ -.blog-post > p:first-of-type, .page > p:first-of-type { +.blog-post > p:first-of-type, .page > p:first-of-type, .faq-content > p:first-of-type { font-size: 1.25rem; /* 20px */ color: #141035; } @media (min-width: 768px) { - .blog-post > p:first-of-type, .page > p:first-of-type { + .blog-post > p:first-of-type, .page > p:first-of-type, .faq-content > p:first-of-type { font-size: 1.375rem; /* 22px */ line-height: 1.8; } } /* Links */ -.blog-post a, .page a { +.blog-post a, .page a, .faq-content a { color: #8A7DFF; text-decoration: underline; text-underline-offset: 3px; transition: all 0.2s ease; } -.blog-post a:hover, .page a:hover { +.blog-post a:hover, .page a:hover, .faq-content a:hover { color: #7A6DE5; text-decoration-thickness: 2px; } .blog-post strong, .blog-post b, -.page strong, .page b { +.page strong, .page b, +.faq-content strong, .faq-content b { color: #141035; font-weight: 600; } .blog-post em, .blog-post i, -.page em, .page i { +.page em, .page i, +.faq-content em, .faq-content i { font-style: italic; } /* Lists */ .blog-post ul, .blog-post ol, -.page ul, .page ol { +.page ul, .page ol, +.faq-content ul, .faq-content ol { font-size: 1.125rem; /* 18px */ line-height: 1.7; margin-bottom: 1.5rem; /* 24px */ @@ -2368,34 +2417,35 @@ a.button:hover { @media (min-width: 768px) { .blog-post ul, .blog-post ol, - .page ul, .page ol { + .page ul, .page ol, + .faq-content ul, .faq-content ol { font-size: 1.25rem; /* 20px */ line-height: 1.8; } } -.blog-post li, .page li { +.blog-post li, .page li, .faq-content li { margin-bottom: 0.75rem; /* 12px */ padding-left: 0.5rem; /* 8px */ } -.blog-post li:last-child, .page li:last-child { +.blog-post li:last-child, .page li:last-child, .faq-content li:last-child { margin-bottom: 0; } -.blog-post ul, .page ul { +.blog-post ul, .page ul, .faq-content ul { list-style: disc; } -.blog-post ul li::marker, .page ul li::marker { +.blog-post ul li::marker, .page ul li::marker, .faq-content ul li::marker { color: #8A7DFF; } -.blog-post ol, .page ol { +.blog-post ol, .page ol, .faq-content ol { list-style: decimal; } -.blog-post ol li::marker, .page ol li::marker { +.blog-post ol li::marker, .page ol li::marker, .faq-content ol li::marker { color: #8A7DFF; font-weight: 600; } @@ -2448,7 +2498,7 @@ a.button:hover { } /* Blockquotes */ -.blog-post blockquote, .page blockquote { +.blog-post blockquote, .page blockquote, .faq-content blockquote { position: relative; margin: 2rem 0; /* 32px */ padding: 1.5rem 1.5rem 1.5rem 3rem; /* 24px 24px 24px 48px */ @@ -2461,24 +2511,24 @@ a.button:hover { } @media (min-width: 768px) { - .blog-post blockquote, .page blockquote { + .blog-post blockquote, .page blockquote, .faq-content blockquote { margin: 2.5rem 0; /* 40px */ padding: 2rem 2rem 2rem 3.5rem; /* 32px 32px 32px 56px */ font-size: 1.25rem; /* 20px */ } } -.blog-post blockquote p, .page blockquote p { +.blog-post blockquote p, .page blockquote p, .faq-content blockquote p { margin: 0; color: #141035; } -.blog-post blockquote p:not(:last-child), .page blockquote p:not(:last-child) { +.blog-post blockquote p:not(:last-child), .page blockquote p:not(:last-child), .faq-content blockquote p:not(:last-child) { margin-bottom: 1rem; /* 16px */ } /* TL;DR blocks */ -.blog-post .tldr, .page .tldr { +.blog-post .tldr, .page .tldr, .faq-content .tldr { margin: 0 0 2rem 0; /* 32px */ padding: 1.25rem 1.5rem; /* 20px 24px */ background: linear-gradient(135deg, rgba(138, 125, 255, 0.08) 0%, rgba(138, 125, 255, 0.03) 100%); @@ -2487,12 +2537,12 @@ a.button:hover { } @media (min-width: 768px) { - .blog-post .tldr, .page .tldr { + .blog-post .tldr, .page .tldr, .faq-content .tldr { padding: 1.5rem 2rem; /* 24px 32px */ } } -.blog-post .tldr .tldr-label, .page .tldr .tldr-label { +.blog-post .tldr .tldr-label, .page .tldr .tldr-label, .faq-content .tldr .tldr-label { display: block; font-size: 0.75rem; /* 12px */ font-weight: 700; @@ -2502,7 +2552,7 @@ a.button:hover { margin-bottom: 0.5rem; /* 8px */ } -.blog-post .tldr p, .page .tldr p { +.blog-post .tldr p, .page .tldr p, .faq-content .tldr p { margin: 0; font-size: 1rem; /* 16px */ line-height: 1.7; @@ -2510,13 +2560,13 @@ a.button:hover { } @media (min-width: 768px) { - .blog-post .tldr p, .page .tldr p { + .blog-post .tldr p, .page .tldr p, .faq-content .tldr p { font-size: 1.125rem; /* 18px */ } } /* Code */ -.blog-post code, .page code { +.blog-post code, .page code, .faq-content code { background: #f1f5f9; color: #334155; padding: 0.1875rem 0.5rem; /* 3px 8px */ @@ -2526,7 +2576,7 @@ a.button:hover { border: 1px solid #e2e8f0; } -.blog-post pre, .page pre { +.blog-post pre, .page pre, .faq-content pre { background: #1e293b; color: #e2e8f0; padding: 1.5rem; /* 24px */ @@ -2537,7 +2587,7 @@ a.button:hover { box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); } -.blog-post pre code, .page pre code { +.blog-post pre code, .page pre code, .faq-content pre code { background: transparent; padding: 0; border: none; @@ -2546,13 +2596,13 @@ a.button:hover { } @media (min-width: 768px) { - .blog-post pre code, .page pre code { + .blog-post pre code, .page pre code, .faq-content pre code { font-size: 1rem; /* 16px */ } } /* Tables */ -.blog-post table, .page table { +.blog-post table, .page table, .faq-content table { display: block; width: 100%; overflow-x: auto; @@ -2563,19 +2613,20 @@ a.button:hover { } @media (min-width: 768px) { - .blog-post table, .page table { + .blog-post table, .page table, .faq-content table { font-size: 1.125rem; /* 18px */ } } .blog-post th, .blog-post td, -.page th, .page td { +.page th, .page td, +.faq-content th, .faq-content td { border: 1px solid #e5e7eb; padding: 0.75rem 1rem; /* 12px 16px */ text-align: left; } -.blog-post th, .page th { +.blog-post th, .page th, .faq-content th { background-color: #f9fafb; color: #141035; font-weight: 600; @@ -2584,21 +2635,21 @@ a.button:hover { letter-spacing: 0.05em; } -.blog-post tbody tr, .page tbody tr { +.blog-post tbody tr, .page tbody tr, .faq-content tbody tr { background: #FFF; transition: background-color 0.2s ease; } -.blog-post tbody tr:hover, .page tbody tr:hover { +.blog-post tbody tr:hover, .page tbody tr:hover, .faq-content tbody tr:hover { background: #f9fafb; } -.blog-post td, .page td { +.blog-post td, .page td, .faq-content td { color: #5E5E5E; } /* Horizontal rules */ -.blog-post hr, .page hr { +.blog-post hr, .page hr, .faq-content hr { margin: 3rem 0; /* 48px */ border: none; height: 2px; @@ -2606,7 +2657,7 @@ a.button:hover { } @media (min-width: 768px) { - .blog-post hr, .page hr { + .blog-post hr, .page hr, .faq-content hr { margin: 4rem 0; /* 64px */ } } @@ -2856,6 +2907,10 @@ a.button:hover { background-color: rgb(138 125 255 / 0.2); } +.hover\:bg-\[\#8A7DFF\]\/30:hover { + background-color: rgb(138 125 255 / 0.3); +} + .hover\:bg-gray-800:hover { --tw-bg-opacity: 1; background-color: rgb(31 41 55 / var(--tw-bg-opacity, 1)); @@ -2948,6 +3003,26 @@ a.button:hover { filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); } +.focus\:border-\[\#8A7DFF\]:focus { + --tw-border-opacity: 1; + border-color: rgb(138 125 255 / var(--tw-border-opacity, 1)); +} + +.focus\:outline-none:focus { + outline: 2px solid transparent; + outline-offset: 2px; +} + +.focus\:ring-2:focus { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); +} + +.focus\:ring-\[\#8A7DFF\]\/20:focus { + --tw-ring-color: rgb(138 125 255 / 0.2); +} + .group:hover .group-hover\:translate-x-1 { --tw-translate-x: 0.25rem; transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); @@ -3081,9 +3156,6 @@ a.button:hover { .lg\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } - .lg\:grid-cols-4 { - grid-template-columns: repeat(4, minmax(0, 1fr)); - } .lg\:flex-row { flex-direction: row; } @@ -3168,3 +3240,9 @@ a.button:hover { line-height: 78px; } } + +@media (min-width: 1280px) { + .xl\:grid-cols-5 { + grid-template-columns: repeat(5, minmax(0, 1fr)); + } +} diff --git a/content/_index.html b/content/_index.html index 5becb79..27f4454 100644 --- a/content/_index.html +++ b/content/_index.html @@ -29,17 +29,17 @@
- For GitLab users, we provide a dedicated pipeline template. + Use our Docker image directly in GitLab CI with built-in caching support.
generate-sbom:
image: sbomifyhub/sbomify-action
+ cache:
+ key: sbomify-cache
+ paths:
+ - .sbomify-cache/
variables:
- TOKEN: $SBOMIFY_TOKEN
- COMPONENT_ID: 'Your Component ID'
- UPLOAD: "true"
- AUGMENT: "true"
+ SBOMIFY_CACHE_DIR: "${CI_PROJECT_DIR}/.sbomify-cache/sbomify"
+ TRIVY_CACHE_DIR: "${CI_PROJECT_DIR}/.sbomify-cache/trivy"
+ SYFT_CACHE_DIR: "${CI_PROJECT_DIR}/.sbomify-cache/syft"
+ LOCK_FILE: poetry.lock
+ OUTPUT_FILE: sbom.cdx.json
+ UPLOAD: "false"
ENRICH: "true"
- COMPONENT_NAME: 'my-python-app'
- COMPONENT_VERSION: $CI_COMMIT_SHA
- LOCK_FILE: 'poetry.lock'
- OUTPUT_FILE: 'sbom.cdx.json'
script:
- - /sbomify.sh
+ - sbomify-action
- Seamlessly integrate with Bitbucket Pipelines using our official pipe. + Seamlessly integrate with Bitbucket Pipelines using our Docker image with built-in caching.
- step:
- name: Build SBOM
- script:
- - pipe: docker://sbomifyhub/sbomify-action:latest
- variables:
- TOKEN: $SBOMIFY_TOKEN
- COMPONENT_ID: "Your Component ID"
- UPLOAD: "true"
- AUGMENT: "true"
- ENRICH: "true"
- COMPONENT_NAME: "my-python-app"
- COMPONENT_VERSION: $BITBUCKET_COMMIT
- LOCK_FILE: "poetry.lock"
- OUTPUT_FILE: "bitbucket-sbom.cdx.json"
+pipelines:
+ default:
+ - step:
+ caches:
+ - sbomify
+ script:
+ - pipe: docker://sbomifyhub/sbomify-action:latest
+ variables:
+ SBOMIFY_CACHE_DIR: "${BITBUCKET_CLONE_DIR}/.sbomify-cache/sbomify"
+ TRIVY_CACHE_DIR: "${BITBUCKET_CLONE_DIR}/.sbomify-cache/trivy"
+ SYFT_CACHE_DIR: "${BITBUCKET_CLONE_DIR}/.sbomify-cache/syft"
+ LOCK_FILE: poetry.lock
+ OUTPUT_FILE: sbom.cdx.json
+ UPLOAD: "false"
+ ENRICH: "true"
+
+definitions:
+ caches:
+ sbomify: .sbomify-cache
- For any other CI/CD system, you can use our Docker image directly. + For any other CI/CD system, use our Docker image directly. All generators are pre-installed.
docker run --rm \
- -v $(pwd):/code \
- -e TOKEN=<my token> \
- -e COMPONENT_ID=<my component id> \
- -e LOCK_FILE=/code/requirements.txt \
- -e OUTPUT_FILE=/code/sbom.cdx.json \
- -e COMPONENT_NAME=my-app \
+# Create persistent cache volume
+docker volume create sbomify-cache
+
+docker run --rm \
+ -v $(pwd):/github/workspace \
+ -v sbomify-cache:/cache \
+ -w /github/workspace \
+ -e SBOMIFY_CACHE_DIR=/cache/sbomify \
+ -e TRIVY_CACHE_DIR=/cache/trivy \
+ -e SYFT_CACHE_DIR=/cache/syft \
+ -e LOCK_FILE=/github/workspace/requirements.txt \
+ -e OUTPUT_FILE=/github/workspace/sbom.cdx.json \
+ -e UPLOAD=false \
-e ENRICH=true \
sbomifyhub/sbomify-action
+ Install via pip for local development or non-Docker environments. Requires external generators (Trivy, Syft, or cdxgen) to be installed separately. +
+pip install sbomify-action
+
+# CLI usage
+sbomify-action --lock-file requirements.txt \
+ --enrich --no-upload -o sbom.cdx.json
+
+# Or use environment variables
+export LOCK_FILE=requirements.txt
+export ENRICH=true
+export UPLOAD=false
+sbomify-action
+
+ Generate SBOMs from lockfiles across 14 languages, plus Docker images and Yocto/OpenEmbedded builds.
+Generate SBOMs directly from container images using DOCKER_IMAGE instead of a lockfile. Scans all layers and installed packages.
Batch process SPDX SBOMs from Yocto builds. Extracts .spdx.tar.zst archives, uploads package SBOMs, and tags them with a product release.
Five generators with automatic fallback. The best tool for each ecosystem is selected automatically.
+Native Python generator. Most accurate for Python ecosystems.
+Native Rust generator. Most accurate for Rust ecosystems.
+Broadest ecosystem support. Best choice for Java/Gradle and multi-language projects.
+Security-focused scanner by Aqua Security. Supports CycloneDX and SPDX output.
+Comprehensive scanner by Anchore. Supports CycloneDX and SPDX output including Terraform.
+Default format. Versions 1.3 through 1.7 supported depending on generator.
+SBOM_FORMAT=cyclonedx
+ Versions 2.2 and 2.3 via Trivy or Syft, plus 3.0 via Yocto/OpenEmbedded. Validated against JSON schemas.
+SBOM_FORMAT=spdx
+
- Leverage the power of OWASP Dependency-Track for continuous component analysis.
+ Leverage the power of OWASP Dependency-Track for continuous component analysis. Upload SBOMs directly from CI/CD with UPLOAD_DESTINATIONS=dependency-track.
+ Direct Upload: sbomify-action can upload SBOMs directly to your Dependency Track instance from any CI pipeline. +
+@@ -168,7 +426,7 @@
We integrate with 11 data sources to add metadata to your SBOM components: descriptions, licenses, supplier information, and more.
+We integrate with 12 data sources to add metadata to your SBOM components: descriptions, licenses, supplier information, and more.
Authoritative data direct from the ecosystem's official source.
-Python Package Index
@@ -226,6 +484,11 @@Debian Package Archive
pkg:deb/debian/*C/C++ (Conan)
+ pkg:conan/* ++ {{ . }} +
+ {{ end }} +No questions match your search.
+ +{{ . }}
+ {{ end }} + + Read full answer → + +Our team is here to help you get started with SBOMs and supply chain security.
+ +