Added support for featured videos and optionally removing features from article header
This commit is contained in:
parent
d3ab5f343d
commit
cc38f170f5
9 changed files with 476 additions and 92 deletions
|
|
@ -5,11 +5,10 @@ date = 2025-02-27T07:07:07-05:00
|
||||||
draft = false
|
draft = false
|
||||||
categories = ['thoughts']
|
categories = ['thoughts']
|
||||||
tags = ['hugo', 'web']
|
tags = ['hugo', 'web']
|
||||||
|
disableToc = true
|
||||||
|
showFeature = false
|
||||||
+++
|
+++
|
||||||
|
|
||||||
First Post!!!
|
|
||||||
<!--more-->
|
|
||||||
|
|
||||||
## Social anxiety or introvert, chicken or egg?
|
## Social anxiety or introvert, chicken or egg?
|
||||||
|
|
||||||
I have been an introvert for as long as I can remember, and while I don't want this to turn into a self-help post, suffice it to say that I have never made a personal website primarily because it makes the hairs on the back of my neck stand up. Let today be the day that I face my fears and finally launch this site.
|
I have been an introvert for as long as I can remember, and while I don't want this to turn into a self-help post, suffice it to say that I have never made a personal website primarily because it makes the hairs on the back of my neck stand up. Let today be the day that I face my fears and finally launch this site.
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,6 @@ categories = ['references']
|
||||||
tags = ['hugo', 'markdown']
|
tags = ['hugo', 'markdown']
|
||||||
+++
|
+++
|
||||||
|
|
||||||
This cheatsheet is intended as a quick reference and showcase of the markdown syntax used in Hugo and Congo.
|
|
||||||
<!--more-->
|
|
||||||
|
|
||||||
{{< lead >}}
|
{{< lead >}}
|
||||||
This cheatsheet is intended as a quick reference and showcase of the markdown syntax used in Hugo and Congo.
|
This cheatsheet is intended as a quick reference and showcase of the markdown syntax used in Hugo and Congo.
|
||||||
{{< /lead >}}
|
{{< /lead >}}
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -1,57 +0,0 @@
|
||||||
---
|
|
||||||
title: "TOC Disable Example"
|
|
||||||
description: "Example showing how to disable the table of contents in markdown files"
|
|
||||||
date: 2025-01-27
|
|
||||||
draft: false
|
|
||||||
categories: ['examples']
|
|
||||||
tags: ['toc', 'markdown', 'hugo']
|
|
||||||
disableToc: true # This disables the table of contents for this page
|
|
||||||
---
|
|
||||||
|
|
||||||
{{< lead >}}
|
|
||||||
This page demonstrates how to disable the table of contents in markdown files.
|
|
||||||
{{< /lead >}}
|
|
||||||
|
|
||||||
## How to Disable TOC
|
|
||||||
|
|
||||||
To disable the table of contents in any markdown file (including `index.md` files), simply add the `disableToc: true` parameter to the front matter:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
title: "Your Page Title"
|
|
||||||
description: "Your page description"
|
|
||||||
disableToc: true # This disables the TOC
|
|
||||||
---
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage Examples
|
|
||||||
|
|
||||||
### For Individual Pages
|
|
||||||
Add `disableToc: true` to the front matter of any markdown file to disable the TOC for that specific page.
|
|
||||||
|
|
||||||
### For Index Pages
|
|
||||||
For `index.md` files that serve as list pages, you can also use the `cascade` parameter to apply the setting to all pages in that section:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
title: "Section Title"
|
|
||||||
cascade:
|
|
||||||
disableToc: true # Disables TOC for all pages in this section
|
|
||||||
---
|
|
||||||
```
|
|
||||||
|
|
||||||
## How It Works
|
|
||||||
|
|
||||||
When `disableToc: true` is set:
|
|
||||||
|
|
||||||
1. The table of contents will not be displayed on the page
|
|
||||||
2. The TOC JavaScript will not be loaded (improving performance)
|
|
||||||
3. The TOC highlighting functionality will be disabled
|
|
||||||
|
|
||||||
## Note
|
|
||||||
|
|
||||||
This feature works for both:
|
|
||||||
- Individual article pages (using the `single.html` template)
|
|
||||||
- List/index pages (using the `list.html` template)
|
|
||||||
|
|
||||||
The TOC will still be generated by Hugo, but it won't be displayed or have JavaScript functionality when disabled.
|
|
||||||
|
|
@ -7,9 +7,6 @@ categories = ['references']
|
||||||
tags = ['LSI', 'TrueNAS Scale', 'Broadcom', 'Update', 'SAS3Flash', 'HBA']
|
tags = ['LSI', 'TrueNAS Scale', 'Broadcom', 'Update', 'SAS3Flash', 'HBA']
|
||||||
+++
|
+++
|
||||||
|
|
||||||
Navigating Broadcom and LSI HBA updates on TrueNAS Scale.
|
|
||||||
<!--more-->
|
|
||||||
|
|
||||||
{{< lead >}}
|
{{< lead >}}
|
||||||
Navigating Broadcom and LSI HBA updates on TrueNAS Scale.
|
Navigating Broadcom and LSI HBA updates on TrueNAS Scale.
|
||||||
{{< /lead >}}
|
{{< /lead >}}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,11 @@
|
||||||
<article class="mt-6 flex max-w-prose flex-row">
|
<article class="mt-6 flex max-w-prose flex-row">
|
||||||
{{- $images := $.Resources.ByType "image" }}
|
{{- $images := $.Resources.ByType "image" }}
|
||||||
|
{{- $videos := $.Resources.ByType "video" }}
|
||||||
{{- $thumbnail := $images.GetMatch (.Params.thumbnail | default "*thumb*") }}
|
{{- $thumbnail := $images.GetMatch (.Params.thumbnail | default "*thumb*") }}
|
||||||
{{- $feature := $images.GetMatch (.Params.feature | default "*feature*") | default $thumbnail }}
|
{{- $feature := $images.GetMatch (.Params.feature | default "*feature*") | default $thumbnail }}
|
||||||
|
{{- if not $feature }}
|
||||||
|
{{- $feature = $videos.GetMatch (.Params.feature | default "*feature*") }}
|
||||||
|
{{- end }}
|
||||||
{{- with $feature }}
|
{{- with $feature }}
|
||||||
<div class="flex-none pe-4 sm:pe-6 ">
|
<div class="flex-none pe-4 sm:pe-6 ">
|
||||||
<a
|
<a
|
||||||
|
|
@ -12,6 +16,21 @@
|
||||||
{{ end }}"
|
{{ end }}"
|
||||||
aria-label="{{ $.Title | emojify }}"
|
aria-label="{{ $.Title | emojify }}"
|
||||||
>
|
>
|
||||||
|
{{ if eq .ResourceType "video" }}
|
||||||
|
<video
|
||||||
|
class="w-24 rounded-md sm:w-40 max-h-[7.5rem]"
|
||||||
|
autoplay
|
||||||
|
loop
|
||||||
|
muted
|
||||||
|
playsinline
|
||||||
|
{{ if $.Site.Params.enableImageLazyLoading | default true }}
|
||||||
|
loading="lazy"
|
||||||
|
{{ end }}
|
||||||
|
aria-label="{{ $.Params.featureAlt | default $.Params.thumbnailAlt | default "" }}"
|
||||||
|
>
|
||||||
|
<source src="{{ .RelPermalink }}" type="{{ .MediaType }}">
|
||||||
|
</video>
|
||||||
|
{{ else }}
|
||||||
<img
|
<img
|
||||||
alt="{{ $.Params.featureAlt | default $.Params.thumbnailAlt | default "" }}"
|
alt="{{ $.Params.featureAlt | default $.Params.thumbnailAlt | default "" }}"
|
||||||
{{ if eq .MediaType.SubType "svg" }}
|
{{ if eq .MediaType.SubType "svg" }}
|
||||||
|
|
@ -27,6 +46,7 @@
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
{{ end }}
|
{{ end }}
|
||||||
/>
|
/>
|
||||||
|
{{ end }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
@ -70,7 +90,15 @@
|
||||||
</div>
|
</div>
|
||||||
{{ if .Params.showSummary | default (.Site.Params.list.showSummary | default false) }}
|
{{ if .Params.showSummary | default (.Site.Params.list.showSummary | default false) }}
|
||||||
<div class="prose py-1 dark:prose-invert">
|
<div class="prose py-1 dark:prose-invert">
|
||||||
{{ $summary := .Summary | emojify }}
|
{{ $summary := "" }}
|
||||||
|
{{ $hasManualSummary := findRE "<!--\\s*more\\s*-->" .RawContent }}
|
||||||
|
{{ if $hasManualSummary }}
|
||||||
|
{{ $summary = .Summary | emojify }}
|
||||||
|
{{ else if .Description }}
|
||||||
|
{{ $summary = .Description | emojify }}
|
||||||
|
{{ else }}
|
||||||
|
{{ $summary = .Summary | emojify }}
|
||||||
|
{{ end }}
|
||||||
{{ $summary := replaceRE "<h[1-6][^>]*>(.*?)</h[1-6]>" "$1" $summary }}
|
{{ $summary := replaceRE "<h[1-6][^>]*>(.*?)</h[1-6]>" "$1" $summary }}
|
||||||
{{ $summary := replaceRE "\\s*<br\\s*/?>" " " $summary }}
|
{{ $summary := replaceRE "\\s*<br\\s*/?>" " " $summary }}
|
||||||
{{ $summary := replaceRE "\\s+" " " $summary }}
|
{{ $summary := replaceRE "\\s+" " " $summary }}
|
||||||
|
|
|
||||||
23
layouts/partials/video.html
Normal file
23
layouts/partials/video.html
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
{{ $video := .video }}
|
||||||
|
{{ $class := .class }}
|
||||||
|
{{ $lazy := .lazy }}
|
||||||
|
{{ $alt := .alt }}
|
||||||
|
{{ $autoplay := .autoplay | default true }}
|
||||||
|
{{ $loop := .loop | default true }}
|
||||||
|
{{ $muted := .muted | default true }}
|
||||||
|
|
||||||
|
{{ with $video }}
|
||||||
|
<video
|
||||||
|
{{ with $class }}class="{{ . }}"{{ end }}
|
||||||
|
{{ if $autoplay }}autoplay{{ end }}
|
||||||
|
{{ if $loop }}loop{{ end }}
|
||||||
|
{{ if $muted }}muted{{ end }}
|
||||||
|
playsinline
|
||||||
|
{{ with $lazy }}loading="lazy"{{ end }}
|
||||||
|
{{ with $alt }}aria-label="{{ . }}"{{ end }}
|
||||||
|
>
|
||||||
|
<source src="{{ .RelPermalink }}" type="{{ .MediaType }}">
|
||||||
|
{{ with $alt }}{{ . }}{{ end }}
|
||||||
|
</video>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
|
@ -1,8 +1,12 @@
|
||||||
{{ define "main" }}
|
{{ define "main" }}
|
||||||
{{ partial "background-images.html" . }}
|
{{ partial "background-images.html" . }}
|
||||||
{{- $images := .Resources.ByType "image" }}
|
{{- $images := .Resources.ByType "image" }}
|
||||||
|
{{- $videos := .Resources.ByType "video" }}
|
||||||
{{- $cover := $images.GetMatch (.Params.cover | default "*cover*") }}
|
{{- $cover := $images.GetMatch (.Params.cover | default "*cover*") }}
|
||||||
{{- $feature := $images.GetMatch (.Params.feature | default "*feature*") | default $cover }}
|
{{- $feature := $images.GetMatch (.Params.feature | default "*feature*") | default $cover }}
|
||||||
|
{{- if not $feature }}
|
||||||
|
{{- $feature = $videos.GetMatch (.Params.feature | default "*feature*") }}
|
||||||
|
{{- end }}
|
||||||
<article class="prose max-w-full dark:prose-invert glass">
|
<article class="prose max-w-full dark:prose-invert glass">
|
||||||
<header class="max-w-prose">
|
<header class="max-w-prose">
|
||||||
{{ if .Params.showBreadcrumbs | default (.Site.Params.article.showBreadcrumbs | default false) }}
|
{{ if .Params.showBreadcrumbs | default (.Site.Params.article.showBreadcrumbs | default false) }}
|
||||||
|
|
@ -22,17 +26,23 @@
|
||||||
{{ partial "article-meta.html" (dict "context" . "scope" "single") }}
|
{{ partial "article-meta.html" (dict "context" . "scope" "single") }}
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
{{ if .Params.showFeature | default true }}
|
||||||
{{ with $feature }}
|
{{ with $feature }}
|
||||||
<div class="prose">
|
<div class="prose">
|
||||||
{{ $altText := $.Params.featureAlt | default $.Params.coverAlt | default "" }}
|
{{ $altText := $.Params.featureAlt | default $.Params.coverAlt | default "" }}
|
||||||
{{ $class := "mb-6 rounded-md" }}
|
{{ $class := "mb-6 rounded-md" }}
|
||||||
|
{{ if eq .ResourceType "video" }}
|
||||||
|
{{ partial "video.html" (dict "video" . "alt" $altText "class" $class "lazy" false "autoplay" true "loop" true "muted" true) }}
|
||||||
|
{{ else }}
|
||||||
{{ $webp := $.Page.Site.Params.enableImageWebp | default true }}
|
{{ $webp := $.Page.Site.Params.enableImageWebp | default true }}
|
||||||
{{ partial "picture.html" (dict "img" . "alt" $altText "class" $class "lazy" false "webp" $webp) }}
|
{{ partial "picture.html" (dict "img" . "alt" $altText "class" $class "lazy" false "webp" $webp) }}
|
||||||
|
{{ end }}
|
||||||
{{ with $.Params.coverCaption }}
|
{{ with $.Params.coverCaption }}
|
||||||
<figcaption class="-mt-3 mb-6 text-center">{{ . | markdownify }}</figcaption>
|
<figcaption class="-mt-3 mb-6 text-center">{{ . | markdownify }}</figcaption>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
</header>
|
</header>
|
||||||
<section class="prose mt-0 flex max-w-full flex-col dark:prose-invert lg:flex-row">
|
<section class="prose mt-0 flex max-w-full flex-col dark:prose-invert lg:flex-row">
|
||||||
{{ if and (not (.Params.disableToc | default false)) (.Params.showTableOfContents | default (.Site.Params.article.showTableOfContents | default false)) (in .TableOfContents "<ul") }}
|
{{ if and (not (.Params.disableToc | default false)) (.Params.showTableOfContents | default (.Site.Params.article.showTableOfContents | default false)) (in .TableOfContents "<ul") }}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,387 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=1280, initial-scale=1.0">
|
||||||
|
<title>Matrix Synapse Docker Guide</title>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@700;800&family=Archivo+Black&display=swap" rel="stylesheet">
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: #0a0a0a;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#scaler {
|
||||||
|
width: 1280px;
|
||||||
|
height: 720px;
|
||||||
|
transform-origin: 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumbnail {
|
||||||
|
width: 1280px;
|
||||||
|
height: 720px;
|
||||||
|
background: linear-gradient(135deg, #0d1117 0%, #1a1f2e 50%, #0d1117 100%);
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 30px 90px rgba(0, 0, 0, 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Animated grid background */
|
||||||
|
.grid-bg {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background-image:
|
||||||
|
linear-gradient(rgba(0, 255, 159, 0.03) 1px, transparent 1px),
|
||||||
|
linear-gradient(90deg, rgba(0, 255, 159, 0.03) 1px, transparent 1px);
|
||||||
|
background-size: 40px 40px;
|
||||||
|
animation: gridPulse 3s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes gridPulse {
|
||||||
|
0%, 100% { opacity: 0.6; }
|
||||||
|
50% { opacity: 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Glowing orbs */
|
||||||
|
.orb {
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 50%;
|
||||||
|
filter: blur(80px);
|
||||||
|
opacity: 0.4;
|
||||||
|
animation: float 8s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.orb-1 {
|
||||||
|
width: 400px;
|
||||||
|
height: 400px;
|
||||||
|
background: radial-gradient(circle, #00ff9f 0%, transparent 70%);
|
||||||
|
top: -100px;
|
||||||
|
right: -100px;
|
||||||
|
animation-delay: 0s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.orb-2 {
|
||||||
|
width: 300px;
|
||||||
|
height: 300px;
|
||||||
|
background: radial-gradient(circle, #00bfff 0%, transparent 70%);
|
||||||
|
bottom: -80px;
|
||||||
|
left: -80px;
|
||||||
|
animation-delay: 2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.orb-3 {
|
||||||
|
width: 250px;
|
||||||
|
height: 250px;
|
||||||
|
background: radial-gradient(circle, #7c3aed 0%, transparent 70%);
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
animation-delay: 4s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes float {
|
||||||
|
0%, 100% { transform: translate(0, 0) scale(1); }
|
||||||
|
33% { transform: translate(30px, -30px) scale(1.1); }
|
||||||
|
66% { transform: translate(-30px, 30px) scale(0.9); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Content container */
|
||||||
|
.content {
|
||||||
|
position: relative;
|
||||||
|
z-index: 10;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 60px 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Matrix logo section */
|
||||||
|
.logo-section {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 24px;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.matrix-logo {
|
||||||
|
width: 90px;
|
||||||
|
height: 90px;
|
||||||
|
background: linear-gradient(135deg, #00ff9f 0%, #00bfff 100%);
|
||||||
|
border-radius: 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-family: 'JetBrains Mono', monospace;
|
||||||
|
font-size: 42px;
|
||||||
|
font-weight: 800;
|
||||||
|
color: #0a0a0a;
|
||||||
|
box-shadow: 0 8px 32px rgba(0, 255, 159, 0.3);
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.matrix-logo::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
inset: -2px;
|
||||||
|
background: linear-gradient(45deg, transparent 30%, rgba(255, 255, 255, 0.3) 50%, transparent 70%);
|
||||||
|
animation: shine 3s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shine {
|
||||||
|
0% { transform: translateX(-100%) rotate(45deg); }
|
||||||
|
100% { transform: translateX(200%) rotate(45deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.matrix-logo-text {
|
||||||
|
font-family: 'Archivo Black', sans-serif;
|
||||||
|
font-size: 36px;
|
||||||
|
color: #ffffff;
|
||||||
|
letter-spacing: -1px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Main title */
|
||||||
|
.main-title {
|
||||||
|
font-family: 'Archivo Black', sans-serif;
|
||||||
|
font-size: 82px;
|
||||||
|
line-height: 0.95;
|
||||||
|
color: #ffffff;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
letter-spacing: -3px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-line-1 {
|
||||||
|
display: block;
|
||||||
|
background: linear-gradient(90deg, #ffffff 0%, #00ff9f 100%);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
background-clip: text;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-line-2 {
|
||||||
|
display: block;
|
||||||
|
color: #ffffff;
|
||||||
|
margin-left: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tech badges */
|
||||||
|
.tech-badges {
|
||||||
|
display: flex;
|
||||||
|
gap: 16px;
|
||||||
|
margin-bottom: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
padding: 12px 24px;
|
||||||
|
background: rgba(0, 63, 39, 0.9);
|
||||||
|
border: 2px solid rgba(0, 255, 159, 0.3);
|
||||||
|
border-radius: 8px;
|
||||||
|
font-family: 'JetBrains Mono', monospace;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #00ff9f;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
box-shadow: 0 4px 16px rgba(0, 255, 159, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Docker compose visual */
|
||||||
|
.docker-visual {
|
||||||
|
position: absolute;
|
||||||
|
right: 80px;
|
||||||
|
bottom: 80px;
|
||||||
|
width: 420px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-window {
|
||||||
|
background: rgba(13, 17, 23, 0.95);
|
||||||
|
border: 1px solid rgba(0, 255, 159, 0.2);
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 20px;
|
||||||
|
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6);
|
||||||
|
backdrop-filter: blur(20px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-header {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-dot {
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot-1 { background: #ff5f56; }
|
||||||
|
.dot-2 { background: #ffbd2e; }
|
||||||
|
.dot-3 { background: #27c93f; }
|
||||||
|
|
||||||
|
.terminal-content {
|
||||||
|
font-family: 'JetBrains Mono', monospace;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-line {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-prompt {
|
||||||
|
color: #00ff9f;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-command {
|
||||||
|
color: #00bfff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-comment {
|
||||||
|
color: #6e7681;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-yaml {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yaml-key {
|
||||||
|
color: #ff7b72;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yaml-value {
|
||||||
|
color: #a5d6ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cursor {
|
||||||
|
display: inline-block;
|
||||||
|
width: 10px;
|
||||||
|
height: 20px;
|
||||||
|
background: #00ff9f;
|
||||||
|
animation: blink 1s step-end infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes blink {
|
||||||
|
50% { opacity: 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decorative elements */
|
||||||
|
.deco-line {
|
||||||
|
position: absolute;
|
||||||
|
height: 2px;
|
||||||
|
background: linear-gradient(90deg, transparent, #00ff9f, transparent);
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.deco-line-1 {
|
||||||
|
width: 300px;
|
||||||
|
top: 180px;
|
||||||
|
left: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.deco-line-2 {
|
||||||
|
width: 200px;
|
||||||
|
bottom: 200px;
|
||||||
|
right: 520px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="scaler">
|
||||||
|
<div class="thumbnail">
|
||||||
|
<div class="grid-bg"></div>
|
||||||
|
<div class="orb orb-1"></div>
|
||||||
|
<div class="orb orb-2"></div>
|
||||||
|
<div class="orb orb-3"></div>
|
||||||
|
<div class="deco-line deco-line-1"></div>
|
||||||
|
<div class="deco-line deco-line-2"></div>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
<div class="logo-section">
|
||||||
|
<div class="matrix-logo">[m]</div>
|
||||||
|
<div class="matrix-logo-text">Synapse</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h1 class="main-title">
|
||||||
|
<span class="title-line-1">Self-Host</span>
|
||||||
|
<span class="title-line-2">Your Server</span>
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<div class="tech-badges">
|
||||||
|
<div class="badge">Docker</div>
|
||||||
|
<div class="badge">Compose</div>
|
||||||
|
<div class="badge">Matrix</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="docker-visual">
|
||||||
|
<div class="terminal-window">
|
||||||
|
<div class="terminal-header">
|
||||||
|
<div class="terminal-dot dot-1"></div>
|
||||||
|
<div class="terminal-dot dot-2"></div>
|
||||||
|
<div class="terminal-dot dot-3"></div>
|
||||||
|
</div>
|
||||||
|
<div class="terminal-content">
|
||||||
|
<div class="terminal-line">
|
||||||
|
<span class="terminal-prompt">$</span>
|
||||||
|
<span class="terminal-command">docker compose up -d</span>
|
||||||
|
</div>
|
||||||
|
<div class="terminal-line">
|
||||||
|
<span class="terminal-comment"># Starting services...</span>
|
||||||
|
</div>
|
||||||
|
<div class="terminal-line">
|
||||||
|
<span class="terminal-yaml"><span class="yaml-key">synapse:</span></span>
|
||||||
|
</div>
|
||||||
|
<div class="terminal-line">
|
||||||
|
<span class="terminal-yaml"> <span class="yaml-key">image:</span> <span class="yaml-value">matrixdotorg/synapse</span></span>
|
||||||
|
</div>
|
||||||
|
<div class="terminal-line">
|
||||||
|
<span class="terminal-yaml"> <span class="yaml-key">ports:</span></span>
|
||||||
|
</div>
|
||||||
|
<div class="terminal-line">
|
||||||
|
<span class="terminal-yaml"> - <span class="yaml-value">8008:8008</span></span>
|
||||||
|
</div>
|
||||||
|
<div class="terminal-line">
|
||||||
|
<span class="terminal-yaml"> <span class="yaml-key">volumes:</span></span>
|
||||||
|
</div>
|
||||||
|
<div class="terminal-line">
|
||||||
|
<span class="terminal-yaml"> - <span class="yaml-value">./data:/data</span><span class="cursor"></span></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
function scaleContent() {
|
||||||
|
const scaler = document.getElementById('scaler');
|
||||||
|
const scaleX = window.innerWidth / 1280;
|
||||||
|
const scaleY = window.innerHeight / 720;
|
||||||
|
const scale = Math.min(scaleX, scaleY);
|
||||||
|
scaler.style.transform = `scale(${scale})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
scaleContent();
|
||||||
|
window.addEventListener('resize', scaleContent);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
Add table
Reference in a new issue