diff --git a/.gitea/workflows/ci.yaml b/.gitea/workflows/ci.yaml new file mode 100644 index 0000000..9612b38 --- /dev/null +++ b/.gitea/workflows/ci.yaml @@ -0,0 +1,52 @@ +name: CI + +on: + push: + branches: + - main + pull_request: {} + workflow_dispatch: {} + +jobs: + release: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup QEMU + uses: docker/setup-qemu-action@v3 + + - name: Setup docker buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Container Registery + uses: docker/login-action@v3 + with: + registery: git.housh.dev + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Extract metadata for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: git.housh.dev/homelab/docs + tags: | + type=schedule + type=ref,event=branch + type=ref,event=pr + type=semvar,pattern={{version}} + type=semvar,pattern={{major}}.{{minor}} + type=semvar,pattern={{major}} + type=sha + type=raw,value=latest + + - name: Build and push Docker image + uses: docker/build-push-action@v6 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/Sources/Docs/Extensions.swift b/Sources/Docs/Extensions.swift index c989f29..4c784e0 100644 --- a/Sources/Docs/Extensions.swift +++ b/Sources/Docs/Extensions.swift @@ -43,6 +43,15 @@ extension Item where M == ArticleMetadata { } return primaryTag } + + func getDate() -> Date { + guard let date = metadata.date else { return date } + return date + } + + func getUpdatedDate() -> Date? { + return metadata.updated + } } // NOTE: Most of these are taken from https://github.com/loopwerk/loopwerk.io diff --git a/Sources/Docs/Metadata.swift b/Sources/Docs/Metadata.swift index b147f1d..33dca12 100644 --- a/Sources/Docs/Metadata.swift +++ b/Sources/Docs/Metadata.swift @@ -22,6 +22,13 @@ enum SiteMetadata { /// Represents the valid file metadata for an article. struct ArticleMetadata: Metadata { + + /// The creation date of the article. + let date: Date? + + /// The updated date of the article. + let updated: Date? + /// The articles associated tags. let tags: [String] diff --git a/Sources/Docs/Templates/BaseLayout.swift b/Sources/Docs/Templates/BaseLayout.swift index 6490d77..ed16ee8 100644 --- a/Sources/Docs/Templates/BaseLayout.swift +++ b/Sources/Docs/Templates/BaseLayout.swift @@ -40,7 +40,8 @@ private func siteHeader(_ section: Section) -> Node { div(class: "header__logo") { a(href: "/") { div(class: "logo") { - "docs.housh.dev" + img(src: "/static/favicon-32x32.png") + span(class: "pl-2") { "docs.housh.dev" } } } } @@ -50,6 +51,9 @@ private func siteHeader(_ section: Section) -> Node { li { a(class: section == .articles ? "active" : "", href: "/articles/") { "Articles" } } + li { + a(href: "https://uptime.housh.dev/status/housh-dev", rel: "nofollow", target: "_blank") { "Server-Monitor" } + } li { a(class: section == .about ? "active" : "", href: "/about.html") { "About" } } diff --git a/Sources/Docs/Templates/RenderArticle.swift b/Sources/Docs/Templates/RenderArticle.swift index 9160cc9..2103bab 100644 --- a/Sources/Docs/Templates/RenderArticle.swift +++ b/Sources/Docs/Templates/RenderArticle.swift @@ -16,7 +16,13 @@ func tagPrefix(index: Int, totalTags: Int) -> Node { func renderArticleInfo(_ article: Item) -> Node { div(class: "text-slate-400 gray-links text-sm mb-8") { span(class: "border-r border-gray pr-2 mr-2") { - article.date.formatted("MMMM dd, yyyy") + article.getDate().formatted("MMMM dd, yyyy") + } + + if let updated = article.getUpdatedDate() { + span(class: "border-r border-gray pr-2 mr-2") { + "Updated: \(updated.formatted("MMMM dd, yyyy"))" + } } %.text("\(article.body.withoutHtmlTags.numberOfWords) words, posted in ") @@ -94,7 +100,7 @@ func renderArticle(context: ItemRenderingContext) -> Node { title: context.item.title, extraHeader: generateHeader(.article(context.item)) ) { - article(class: "pt-8 font-avenir text-lg") { + article(class: "pt-8") { h1 { context.item.title } div { renderArticleInfo(context.item) @@ -104,7 +110,7 @@ func renderArticle(context: ItemRenderingContext) -> Node { div(class: "border-t border-light pt-8 mt-16") { div(class: "grid lg:grid-cols-2") { - h2(class: "text-4xl font-extrabold mb-8") { otherArticles.title } + h4(class: "text-3xl text-amber-500 font-extrabold mb-8") { otherArticles.title } if let tag = otherArticles.tag { a(href: "/articles/tag/\(tag)") { div(class: " [&:hover]:border-b border-orange px-5 flex flex-row gap-5") { @@ -133,7 +139,7 @@ func renderArticle(context: ItemRenderingContext) -> Node { func renderArticleForGrid(article: Item) -> Node { section { - h2(class: "post-title text-2xl font-bold mb-2") { + h3(class: "post-title text-2xl font-bold mb-2") { a(class: "[&:hover]:border-b border-orange-400", href: article.url) { article.title } } renderArticleInfo(article) diff --git a/content/articles/2025-04-02-Network.md b/content/articles/2025-04-02-Network.md index 9a12b28..9ace2cc 100644 --- a/content/articles/2025-04-02-Network.md +++ b/content/articles/2025-04-02-Network.md @@ -1,5 +1,6 @@ --- date: 2025-4-02 +updated: 2025-4-03 author: "Michael Housh" tags: network, infrastructure --- @@ -53,12 +54,15 @@ This is the network where all the VoIP phones are on. It is considered This is the network where all IoT (internet of things) devices are. This is considered an "untrusted" network and communications with other networks are -minimized to what is actually needed to work. +minimized to what is actually needed to work. This network is not able to +communicate with the internet, because these devices are made by so many +different companies with unknown intentions, this adds an extra layer of +security by ensuring all communications are internal to our networks. -The exception to items placed on the IoT network is "apple" specific devices, +The exception to items placed on the IoT network are "apple" specific devices, such as home-pods and apple-tv because there are network challenges with these -devices operating properly when placed on the IoT network (which may be resolved -in the future). +devices operating properly when placed on the IoT network, such as airdrop and +screen casting (which may be resolved in the future). ## Firewall @@ -72,9 +76,9 @@ from communicating with other networks or the internet. ## DNS -DNS is what translates IP addresses to domain names (i.e. `po.housh.dev` -> -`192.168.50.6`). This is managed by the unifi management console and is accessed -via `Settings -> Routing -> DNS`. +DNS is what translates IP addresses to domain names (i.e. +`po.housh.dev -> 192.168.50.6`). This is managed by the unifi management console +and is accessed via `Settings -> Routing -> DNS`. We primarily use wildcard records, which allow the actual routing to be handled by the servers to the correct service. diff --git a/content/static/input.css b/content/static/input.css index f2c72f2..ac2126c 100644 --- a/content/static/input.css +++ b/content/static/input.css @@ -33,6 +33,14 @@ --green: #a6e3a1; } +/* Reset */ +* { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; +} + /* HEADER */ .header { display: flex; @@ -92,6 +100,8 @@ padding: 10px; } +/* Nav */ + nav a:hover { @apply border-b-2 border-orange-400; } @@ -99,16 +109,18 @@ nav a.active { @apply border-b-2 border-orange-400; } +/* Body */ + body { - @apply bg-slate-900 font-avenir; + @apply bg-slate-900 font-avenir text-xl; } h1 { - @apply text-4xl; + @apply text-6xl pb-2; } h2 { - @apply text-3xl mb-4 pt-4; + @apply text-5xl mb-8 pt-4; color: var(--green); } h3 { @@ -119,26 +131,27 @@ p { @apply mb-8; } -img { - padding-top: 10px; - padding-bottom: 10px; -} - article h2 { @apply border-b-2 border-slate-200; } -article { - @apply font-avenir text-lg; +article a { + @apply text-orange-400; +} + +article a:hover { + @apply border-b border-green-400; +} + +article code { + @apply bg-amber-700; } .container { @apply px-10; } -* { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - -ms-box-sizing: border-box; - box-sizing: border-box; +.container img { + padding-top: 10px; + padding-bottom: 10px; } diff --git a/content/static/output.css b/content/static/output.css index 548bfe5..1760786 100644 --- a/content/static/output.css +++ b/content/static/output.css @@ -1,2 +1,2 @@ /*! tailwindcss v4.1.1 | MIT License | https://tailwindcss.com */ -@import "https://fonts.cdnfonts.com/css/avenir";@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-orange-400:oklch(75% .183 55.934);--color-amber-500:oklch(76.9% .188 70.08);--color-green-400:oklch(79.2% .209 151.711);--color-slate-200:oklch(92.9% .013 255.508);--color-slate-400:oklch(70.4% .04 256.788);--color-slate-900:oklch(20.8% .042 265.755);--color-gray-200:oklch(92.8% .006 264.531);--color-white:#fff;--spacing:.25rem;--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25/1.875);--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5/2.25);--font-weight-thin:100;--font-weight-bold:700;--font-weight-extrabold:800;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--font-avenir:"Avenir",sans-serif}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:color-mix(in oklab,currentColor 50%,transparent)}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*,:after,:before,::backdrop{border-color:var(--color-gray-200,currentColor)}::file-selector-button{border-color:var(--color-gray-200,currentColor)}}@layer components;@layer utilities{.static{position:static}.isolate{isolation:isolate}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.m-580{margin:calc(var(--spacing)*580)}.my-24{margin-block:calc(var(--spacing)*24)}.mt-4{margin-top:calc(var(--spacing)*4)}.mt-10{margin-top:calc(var(--spacing)*10)}.mt-16{margin-top:calc(var(--spacing)*16)}.mr-2{margin-right:calc(var(--spacing)*2)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-8{margin-bottom:calc(var(--spacing)*8)}.mb-10{margin-bottom:calc(var(--spacing)*10)}.mb-12{margin-bottom:calc(var(--spacing)*12)}.mb-16{margin-bottom:calc(var(--spacing)*16)}.flex{display:flex}.grid{display:grid}.inline{display:inline}.transform{transform:var(--tw-rotate-x)var(--tw-rotate-y)var(--tw-rotate-z)var(--tw-skew-x)var(--tw-skew-y)}.flex-row{flex-direction:row}.flex-wrap{flex-wrap:wrap}.gap-2{gap:calc(var(--spacing)*2)}.gap-4{gap:calc(var(--spacing)*4)}.gap-5{gap:calc(var(--spacing)*5)}.gap-10{gap:calc(var(--spacing)*10)}.gap-x-2{column-gap:calc(var(--spacing)*2)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-green-400{border-color:var(--color-green-400)}.border-orange-400{border-color:var(--color-orange-400)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-5{padding-inline:calc(var(--spacing)*5)}.pt-2{padding-top:calc(var(--spacing)*2)}.pt-3{padding-top:calc(var(--spacing)*3)}.pt-8{padding-top:calc(var(--spacing)*8)}.pr-2{padding-right:calc(var(--spacing)*2)}.pb-5{padding-bottom:calc(var(--spacing)*5)}.text-center{text-align:center}.font-avenir{font-family:var(--font-avenir)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-\[40px\]{font-size:40px}.leading-\[1\.25\]{--tw-leading:1.25;line-height:1.25}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-extrabold{--tw-font-weight:var(--font-weight-extrabold);font-weight:var(--font-weight-extrabold)}.font-thin{--tw-font-weight:var(--font-weight-thin);font-weight:var(--font-weight-thin)}.text-orange-400{color:var(--color-orange-400)}.text-slate-400{color:var(--color-slate-400)}.text-white{color:var(--color-white)}.uppercase{text-transform:uppercase}.filter{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,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}@media (min-width:64rem){.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:gap-x-5{column-gap:calc(var(--spacing)*5)}}.\[\&\:hover\]\:border-b:hover{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.\[\&\>h1\>strong\]\:font-bold>h1>strong{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}}@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){@layer base{*,:before,:after,::backdrop{--tw-rotate-x:rotateX(0);--tw-rotate-y:rotateY(0);--tw-rotate-z:rotateZ(0);--tw-skew-x:skewX(0);--tw-skew-y:skewY(0);--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}:root{--accent:#a6e3a1;--background:#222129;--color:#fff;--border-color:#ffffff1a;--phoneWidth:(max-width: 684px);--tabletWidth:(max-width: 900px)--orange: #f5a87f;--green:#a6e3a1}.header{flex-direction:column;display:flex;position:relative}.header__inner{justify-center:space-between;align-items:center;display:flex}.header__logo{flex:1;display:flex}.header__logo:after{content:"";background:repeating-linear-gradient(90deg,#ffa86a,#ffa86a 2px,#0000 0 10px);background:repeating-linear-gradient(90deg,var(--accent),var(--accent)2px,transparent 0,transparent 10px);width:100%;display:block;right:10px}.header__logo a{flex:none;max-width:100%;text-decoration:none}.logo{background:#ffa86a;background:var(--accent);color:#000;align-items:center;padding:5px 10px;text-decoration:none;display:flex}.header .menu{flex-wrap:wrap;margin:0;padding:10px;list-style:none;display:flex}nav a:hover,nav a.active{border-bottom-style:var(--tw-border-style);border-bottom-width:2px;border-color:var(--color-orange-400)}body{background-color:var(--color-slate-900);font-family:var(--font-avenir)}h1{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}h2{margin-bottom:calc(var(--spacing)*4);padding-top:calc(var(--spacing)*4);font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height));color:var(--green)}h3{padding-block:calc(var(--spacing)*4);font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height));color:var(--color-amber-500)}p{margin-bottom:calc(var(--spacing)*8)}img{padding-top:10px;padding-bottom:10px}article h2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px;border-color:var(--color-slate-200)}article{font-family:var(--font-avenir);font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.container{padding-inline:calc(var(--spacing)*10)}*{box-sizing:border-box;-ms-box-sizing:border-box}@property --tw-rotate-x{syntax:"*";inherits:false;initial-value:rotateX(0)}@property --tw-rotate-y{syntax:"*";inherits:false;initial-value:rotateY(0)}@property --tw-rotate-z{syntax:"*";inherits:false;initial-value:rotateZ(0)}@property --tw-skew-x{syntax:"*";inherits:false;initial-value:skewX(0)}@property --tw-skew-y{syntax:"*";inherits:false;initial-value:skewY(0)}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false} \ No newline at end of file +@import "https://fonts.cdnfonts.com/css/avenir";@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-orange-400:oklch(75% .183 55.934);--color-amber-500:oklch(76.9% .188 70.08);--color-amber-600:oklch(66.6% .179 58.318);--color-amber-700:oklch(55.5% .163 48.998);--color-green-400:oklch(79.2% .209 151.711);--color-slate-200:oklch(92.9% .013 255.508);--color-slate-400:oklch(70.4% .04 256.788);--color-slate-900:oklch(20.8% .042 265.755);--color-gray-200:oklch(92.8% .006 264.531);--color-white:#fff;--spacing:.25rem;--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25/1.875);--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5/2.25);--text-5xl:3rem;--text-5xl--line-height:1;--text-6xl:3.75rem;--text-6xl--line-height:1;--font-weight-thin:100;--font-weight-bold:700;--font-weight-extrabold:800;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--font-avenir:"Avenir",sans-serif}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:color-mix(in oklab,currentColor 50%,transparent)}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*,:after,:before,::backdrop{border-color:var(--color-gray-200,currentColor)}::file-selector-button{border-color:var(--color-gray-200,currentColor)}}@layer components;@layer utilities{.static{position:static}.isolate{isolation:isolate}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.m-580{margin:calc(var(--spacing)*580)}.my-24{margin-block:calc(var(--spacing)*24)}.mt-4{margin-top:calc(var(--spacing)*4)}.mt-10{margin-top:calc(var(--spacing)*10)}.mt-16{margin-top:calc(var(--spacing)*16)}.mr-2{margin-right:calc(var(--spacing)*2)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-8{margin-bottom:calc(var(--spacing)*8)}.mb-10{margin-bottom:calc(var(--spacing)*10)}.mb-12{margin-bottom:calc(var(--spacing)*12)}.mb-16{margin-bottom:calc(var(--spacing)*16)}.flex{display:flex}.grid{display:grid}.inline{display:inline}.transform{transform:var(--tw-rotate-x)var(--tw-rotate-y)var(--tw-rotate-z)var(--tw-skew-x)var(--tw-skew-y)}.flex-row{flex-direction:row}.flex-wrap{flex-wrap:wrap}.gap-2{gap:calc(var(--spacing)*2)}.gap-4{gap:calc(var(--spacing)*4)}.gap-5{gap:calc(var(--spacing)*5)}.gap-10{gap:calc(var(--spacing)*10)}.gap-x-2{column-gap:calc(var(--spacing)*2)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-green-400{border-color:var(--color-green-400)}.border-orange-400{border-color:var(--color-orange-400)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-5{padding-inline:calc(var(--spacing)*5)}.pt-2{padding-top:calc(var(--spacing)*2)}.pt-3{padding-top:calc(var(--spacing)*3)}.pt-8{padding-top:calc(var(--spacing)*8)}.pr-2{padding-right:calc(var(--spacing)*2)}.pb-5{padding-bottom:calc(var(--spacing)*5)}.pl-2{padding-left:calc(var(--spacing)*2)}.text-center{text-align:center}.font-avenir{font-family:var(--font-avenir)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-\[40px\]{font-size:40px}.leading-\[1\.25\]{--tw-leading:1.25;line-height:1.25}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-extrabold{--tw-font-weight:var(--font-weight-extrabold);font-weight:var(--font-weight-extrabold)}.font-thin{--tw-font-weight:var(--font-weight-thin);font-weight:var(--font-weight-thin)}.text-amber-500{color:var(--color-amber-500)}.text-orange-400{color:var(--color-orange-400)}.text-slate-400{color:var(--color-slate-400)}.text-white{color:var(--color-white)}.uppercase{text-transform:uppercase}.filter{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,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}@media (min-width:64rem){.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:gap-x-5{column-gap:calc(var(--spacing)*5)}}.\[\&\:hover\]\:border-b:hover{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.\[\&\>h1\>strong\]\:font-bold>h1>strong{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}}@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){@layer base{*,:before,:after,::backdrop{--tw-rotate-x:rotateX(0);--tw-rotate-y:rotateY(0);--tw-rotate-z:rotateZ(0);--tw-skew-x:skewX(0);--tw-skew-y:skewY(0);--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}:root{--accent:#a6e3a1;--background:#222129;--color:#fff;--border-color:#ffffff1a;--phoneWidth:(max-width: 684px);--tabletWidth:(max-width: 900px)--orange: #f5a87f;--green:#a6e3a1}*{box-sizing:border-box;-ms-box-sizing:border-box}.header{flex-direction:column;display:flex;position:relative}.header__inner{justify-center:space-between;align-items:center;display:flex}.header__logo{flex:1;display:flex}.header__logo:after{content:"";background:repeating-linear-gradient(90deg,#ffa86a,#ffa86a 2px,#0000 0 10px);background:repeating-linear-gradient(90deg,var(--accent),var(--accent)2px,transparent 0,transparent 10px);width:100%;display:block;right:10px}.header__logo a{flex:none;max-width:100%;text-decoration:none}.logo{background:#ffa86a;background:var(--accent);color:#000;align-items:center;padding:5px 10px;text-decoration:none;display:flex}.header .menu{flex-wrap:wrap;margin:0;padding:10px;list-style:none;display:flex}nav a:hover,nav a.active{border-bottom-style:var(--tw-border-style);border-bottom-width:2px;border-color:var(--color-orange-400)}body{background-color:var(--color-slate-900);font-family:var(--font-avenir);font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}h1{padding-bottom:calc(var(--spacing)*2);font-size:var(--text-6xl);line-height:var(--tw-leading,var(--text-6xl--line-height))}h2{margin-bottom:calc(var(--spacing)*8);padding-top:calc(var(--spacing)*4);font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--line-height));color:var(--green)}h3{padding-block:calc(var(--spacing)*4);font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height));color:var(--color-amber-500)}p{margin-bottom:calc(var(--spacing)*8)}article h2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px;border-color:var(--color-slate-200)}article a{color:var(--color-orange-400)}article a:hover{border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--color-green-400)}article code{background-color:var(--color-amber-700)}.container{padding-inline:calc(var(--spacing)*10)}.container img{padding-top:10px;padding-bottom:10px}@property --tw-rotate-x{syntax:"*";inherits:false;initial-value:rotateX(0)}@property --tw-rotate-y{syntax:"*";inherits:false;initial-value:rotateY(0)}@property --tw-rotate-z{syntax:"*";inherits:false;initial-value:rotateZ(0)}@property --tw-skew-x{syntax:"*";inherits:false;initial-value:skewX(0)}@property --tw-skew-y{syntax:"*";inherits:false;initial-value:skewY(0)}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false} \ No newline at end of file diff --git a/content/static/prism.css b/content/static/prism.css index 46660e7..ca944c1 100644 --- a/content/static/prism.css +++ b/content/static/prism.css @@ -9,7 +9,7 @@ https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+css+cli code[class*="language-"], pre[class*="language-"] { color: #ccc; - background: none; + background: #121416; font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace; font-size: 1em; text-align: left;