| -rw-r--r-- | .github/workflows/build-and-deploy.yml | 77 | ||||
| -rw-r--r-- | .gitignore | 3 | ||||
| -rw-r--r-- | deploy/inventory.yml | 15 | ||||
| -rw-r--r-- | deploy/playbook.yml | 21 | ||||
| -rw-r--r-- | internal/b2/client.go | 4 | ||||
| -rw-r--r-- | internal/lightgallery/html_renderer.go | 10 | ||||
| -rw-r--r-- | internal/tailwind/transformer.go | 26 | ||||
| -rw-r--r-- | main.go | 42 | ||||
| -rw-r--r-- | static/input.css | 129 | ||||
| -rw-r--r-- | static/output.css | 235 | ||||
| -rw-r--r-- | views/index.html | 62 | ||||
| -rw-r--r-- | views/layouts/blog-main.html | 147 | ||||
| -rw-r--r-- | views/layouts/blog-page.html | 64 |
13 files changed, 317 insertions, 518 deletions
diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml deleted file mode 100644 index ac5fa1f..0000000 --- a/.github/workflows/build-and-deploy.yml +++ /dev/null @@ -1,77 +0,0 @@ -name: Publish Docker image -on: - push: - tags: - - "*" -jobs: - build-and-push: - if: github.repository == 'SayaAndy/saya-today-web' - runs-on: ubuntu-latest - environment: Production - permissions: - packages: write - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Generate output.css with tailwindcss - uses: ZoeyVid/tailwindcss-update@main - with: - input: static/input.css - output: static/output.css - params: "--minify" - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.repository_owner }} - password: ${{ secrets.GHCR_TOKEN }} - - name: Build and push - uses: docker/build-push-action@v6 - with: - context: . - file: ./Dockerfile - push: true - tags: | - ghcr.io/sayaandy/saya-today-web:latest - ghcr.io/sayaandy/saya-today-web:${{ github.ref_name }} - - deploy: - if: github.repository == 'SayaAndy/saya-today-web' - runs-on: ubuntu-latest - environment: Production - needs: [build-and-push] - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Set up SSH connection for pl.saya.today - run: | - mkdir -p ~/.ssh - (cat <<EOF - ${{ secrets.SVC_GITHUB_PK }} - EOF - ) > ~/.ssh/id_ed25519 - chmod 600 ~/.ssh/id_ed25519 - sed -i 's/\r$//' ~/.ssh/id_ed25519 - ssh-keyscan -H pl.saya.today >> ~/.ssh/known_hosts - - - name: Test SSH connection - run: | - ssh -o ConnectTimeout=10 -i ~/.ssh/id_ed25519 svc_github@pl.saya.today "echo 'SSH connection successful'" - - - name: Install Ansible - shell: bash - run: | - sudo apt update - sudo apt install -y ansible - - - name: Run Ansible playbook - env: - ANSIBLE_HOST_KEY_CHECKING: False - working-directory: ./deploy - run: | - ansible-playbook -i inventory.yml -l stage playbook.yml --private-key ~/.ssh/id_ed25519 -u svc_github -e saya_today_web_b2_key_id=${{ secrets.B2_KEY_ID }} -e saya_today_web_b2_application_key=${{ secrets.B2_APPLICATION_KEY }} -e saya_today_web_tag=${{ github.ref_name }} @@ -36,9 +36,6 @@ config*.json /main /sayana-demo -/static/input.css /.vscode .envrc - -/.ansible diff --git a/deploy/inventory.yml b/deploy/inventory.yml deleted file mode 100644 index 3c1220d..0000000 --- a/deploy/inventory.yml +++ /dev/null @@ -1,15 +0,0 @@ -all: - children: - prod: - hosts: - pl.saya.today: - saya_today_web_name: sayana-web - saya_today_web_hostname: sayana-web - saya_today_web_ipv4_address: 172.16.0.18 - - stage: - hosts: - pl.saya.today: - saya_today_web_name: sayana-demo - saya_today_web_hostname: sayana-demo - saya_today_web_ipv4_address: 172.16.0.17 diff --git a/deploy/playbook.yml b/deploy/playbook.yml deleted file mode 100644 index 773bb61..0000000 --- a/deploy/playbook.yml +++ /dev/null @@ -1,21 +0,0 @@ ---- -- name: Deploy saya-today-web Docker Container - hosts: all - remote_user: svc_github - - tasks: - - name: Deploy saya-today-web Docker Container - community.docker.docker_container: - name: "{{ saya_today_web_name }}" - hostname: "{{ saya_today_web_hostname }}" - image: "ghcr.io/sayaandy/saya-today-web:{{ saya_today_web_tag }}" - env: - B2_KEY_ID: "{{ saya_today_web_b2_key_id }}" - B2_APPLICATION_KEY: "{{ saya_today_web_b2_application_key }}" - network_mode: caddy - networks: - - name: caddy - ipv4_address: "{{ saya_today_web_ipv4_address }}" - restart_policy: unless-stopped - no_log: true -... diff --git a/internal/b2/client.go b/internal/b2/client.go index 1a97e5f..f2b6cad 100644 --- a/internal/b2/client.go +++ b/internal/b2/client.go @@ -36,10 +36,10 @@ type BlogPage struct { Metadata *frontmatter.Metadata } -func (c *B2Client) Scan(prefix string) ([]*BlogPage, error) { +func (c *B2Client) Scan() ([]*BlogPage, error) { filePaths := []*BlogPage{} - iter := c.bucket.List(context.Background(), b2.ListPrefix(c.prefix+prefix)) + iter := c.bucket.List(context.Background(), b2.ListPrefix(c.prefix)) for iter.Next() { obj := iter.Object() diff --git a/internal/lightgallery/html_renderer.go b/internal/lightgallery/html_renderer.go index e611f0b..bd73eac 100644 --- a/internal/lightgallery/html_renderer.go +++ b/internal/lightgallery/html_renderer.go @@ -38,13 +38,13 @@ func (r *LightGalleryHTMLRenderer) renderLightGallery(w util.BufWriter, source [ return ast.WalkContinue, nil } - galleryID := generateDivId(8) + galleryID := generateDivId(4) w.WriteString(fmt.Sprintf(` <div class="justify-content-center display-block m-2"> - <hr class="border-t-4 border-dotted border-main-dark mt-[0.8vmin] mb-[0.8vmin] w-[80%%] ml-auto mr-auto"> + <hr class="border-t-4 border-dotted border-main-dark mt-vmin0-8 mb-vmin0-8 w-p80 ml-auto mr-auto"> <div id="lg-%s" class="inline-gallery-container relative ml-auto mr-auto"></div> - <hr class="border-t-4 border-dotted border-main-dark mt-[0.8vmin] mb-[0.8vmin] w-[80%%] ml-auto mr-auto"> + <hr class="border-t-4 border-dotted border-main-dark mt-vmin0-8 mb-vmin0-8 w-p80 ml-auto mr-auto"> </div>`, galleryID)) var dynamicElements []string @@ -67,8 +67,8 @@ func (r *LightGalleryHTMLRenderer) renderLightGallery(w util.BufWriter, source [ thumb: "https://f003.backblazeb2.com/file/sayana-photos/thumbnails/%s.webp", subHtml: `+"`"+`<div class="flex flex-row light-gallery-captions"> - <p class="grow !text-[1vmax]/[0.9] text-left font-spectral text-main-dark">%s</p> - <p class="!text-[1vmax]/[0.9] text-right font-spectral text-secondary">%s</p> + <p class="grow text-vmax1 text-left lh-0-9 font-spectral text-main-dark">%s</p> + <p class="text-vmax1 text-right lh-0-9 font-spectral text-secondary">%s</p> </div>`+"`"+` }`, img.URL, img.URL, img.Caption, imageUrlWithoutExt, imageUrlWithoutExt, img.Caption, dayDate.Format("2006-01-02 15:04:05 -07:00"))) } diff --git a/internal/tailwind/transformer.go b/internal/tailwind/transformer.go index 2f052b9..51a33bc 100644 --- a/internal/tailwind/transformer.go +++ b/internal/tailwind/transformer.go @@ -17,44 +17,44 @@ func (t *TailwindTransformer) Transform(node *ast.Document, reader text.Reader, switch node := n.(type) { case *ast.Heading: classes := map[int]string{ - 1: "font-patua text-[2.5vmax] font-bold text-main-dark mb-[1.2vmin] tracking-[0.04vmin]", - 2: "font-spectral text-[2vmax] font-bold text-main-dark mb-[0.8vmin] tracking-[0.04vmin]", - 3: "font-spectral text-[1.5vmax] font-medium text-main-dark mb-[0.6vmin] tracking-[0.04vmin]", - 4: "font-spectral text-[1.2vmax] font-medium text-main-medium mb-[0.4vmin] tracking-[0.04vmin]", - 5: "font-spectral text-[1vmax] font-medium text-main-medium mb-[0.4vmin] italic tracking-[0.04vmin]", - 6: "font-spectral text-[1vmax] font-medium text-secondary mb-[0.4vmin]", + 1: "font-patua text-vmax2-5 font-bold text-main-dark mb-vmin1-2 ls-vmin0-04", + 2: "font-spectral text-vmax2 font-bold text-main-dark mb-vmin0-8 ls-vmin0-04", + 3: "font-spectral text-vmax1-5 font-medium text-main-dark mb-vmin0-6 ls-vmin0-04", + 4: "font-spectral text-vmax1-2 font-medium text-main-medium mb-vmin0-4 ls-vmin0-04", + 5: "font-spectral text-vmax1 font-medium text-main-medium mb-vmin0-4 italic ls-vmin0-04", + 6: "font-spectral text-vmax1 font-medium text-secondary mb-vmin0-4", } if class, ok := classes[node.Level]; ok { node.SetAttribute([]byte("class"), []byte(class)) } case *ast.Paragraph: - node.SetAttribute([]byte("class"), []byte("text-[1vmax]/[2] font-spectral tracking-[0.04vmin] -indent-[2vmax] ml-[2vmax] mb-[1.6vmin]")) + node.SetAttribute([]byte("class"), []byte("text-vmax1 font-spectral lh-2 ls-vmin0-04 timl-vmax2 mb-vmin1-6")) case *ast.List: if node.IsOrdered() { - node.SetAttribute([]byte("class"), []byte("list-decimal list-inside space-y-[0.8vmin] mb-[1.6vmin] pl-[2vmax]")) + node.SetAttribute([]byte("class"), []byte("list-decimal list-inside space-y-vmin0-8 mb-vmin1-6 pl-vmax2")) } else { - node.SetAttribute([]byte("class"), []byte("list-disc list-inside space-y-[0.8vmin] mb-[1.6vmin] pl-[2vmax]")) + node.SetAttribute([]byte("class"), []byte("list-disc list-inside space-y-vmin0-8 mb-vmin1-6 pl-vmax2")) } case *ast.ListItem: - node.SetAttribute([]byte("class"), []byte("text-[1vmax]/[2] font-spectral tracking-[0.04vmin]")) + node.SetAttribute([]byte("class"), []byte("text-vmax1 font-spectral lh-2 ls-vmin0-04")) case *ast.Blockquote: - node.SetAttribute([]byte("class"), []byte("border-l-[0.4vmin] border-main-medium bg-background-dark p-[0.8vmin] mb-[0.8vmin] italic")) + node.SetAttribute([]byte("class"), []byte("border-l-vmin0-4 border-main-medium bg-background-dark p-vmin0-8 mb-vmin0-8 italic")) case *ast.CodeSpan: node.SetAttribute([]byte("class"), []byte("bg-background-dark")) case *ast.CodeBlock, *ast.FencedCodeBlock: - node.SetAttribute([]byte("class"), []byte("bg-background-dark p-[0.8vmin] rounded-lg overflow-x-auto mb-[1.6vmin]")) + node.SetAttribute([]byte("class"), []byte("bg-background-dark p-vmin0-8 rounded-lg overflow-x-auto mb-vmin1-6")) case *ast.Link: node.SetAttribute([]byte("class"), []byte("text-secondary hover:text-main-dark underline")) case *ast.Image: - node.SetAttribute([]byte("class"), []byte("max-w-full h-auto rounded-lg shadow-lg mb-[1.6vmin]")) + node.SetAttribute([]byte("class"), []byte("max-w-full h-auto rounded-lg shadow-lg mb-vmin1-6")) case *ast.Emphasis: switch node.Level { @@ -8,7 +8,6 @@ import ( "log" "log/slog" "os" - "slices" "strconv" "strings" @@ -18,7 +17,6 @@ import ( "github.com/SayaAndy/saya-today-web/internal/lightgallery" "github.com/SayaAndy/saya-today-web/internal/tailwind" "github.com/gofiber/fiber/v2" - "github.com/gofiber/fiber/v2/middleware/redirect" "github.com/gofiber/template/html/v2" "github.com/yuin/goldmark" "github.com/yuin/goldmark/parser" @@ -38,9 +36,8 @@ var ( gmhtml.WithXHTML(), ), ) - b2Client *b2.B2Client - configPath = flag.String("c", "config.yaml", "Path to the configuration file (in YAML format)") - availableLanguages = make([]string, 0) + b2Client *b2.B2Client + configPath = flag.String("c", "config.yaml", "Path to the configuration file (in YAML format)") ) func main() { @@ -63,37 +60,14 @@ func main() { os.Exit(1) } - for _, lang := range cfg.BlogPages.AvailableLanguages { - availableLanguages = append(availableLanguages, lang.Name) - } - engine := html.New("./views", ".html") app := fiber.New(fiber.Config{ Views: engine, }) - app.Use(redirect.New(redirect.Config{ - Rules: map[string]string{ - "/blog": "/", - }, - StatusCode: 301, - })) - app.Get("/", func(c *fiber.Ctx) error { - return c.Status(fiber.StatusOK).Render("index", fiber.Map{ - "AvailableLanguages": cfg.BlogPages.AvailableLanguages, - }) - }) - - app.Get("/blog/:lang", func(c *fiber.Ctx) error { - lang := c.Params("lang") - if !slices.Contains(availableLanguages, lang) { - c.Set(fiber.HeaderContentType, fiber.MIMETextPlainCharsetUTF8) - return c.Status(fiber.ErrNotFound.Code).SendString(fmt.Sprintf("server does not support '%s' language... yet??", lang)) - } - - pages, err := b2Client.Scan(lang + "/") + pages, err := b2Client.Scan() status := fiber.StatusOK if err != nil { status = fiber.StatusPartialContent @@ -114,20 +88,14 @@ func main() { }) } - return c.Status(status).Render("layouts/blog-main", fiber.Map{ + return c.Status(status).Render("index", fiber.Map{ "PublishedYear": "2025", "BlogPages": pageMeta, }) }) app.Get("/blog/:lang/:title", func(c *fiber.Ctx) error { - lang := c.Params("lang") - if !slices.Contains(availableLanguages, lang) { - c.Set(fiber.HeaderContentType, fiber.MIMETextPlainCharsetUTF8) - return c.Status(fiber.ErrNotFound.Code).SendString(fmt.Sprintf("server does not support '%s' language... yet??", lang)) - } - - metadata, parsedMarkdownDesktop, parsedMarkdownMobile, err := readBlogPost(lang + "/" + c.Params("title")) + metadata, parsedMarkdownDesktop, parsedMarkdownMobile, err := readBlogPost(c.Params("lang") + "/" + c.Params("title")) if err != nil { c.Set(fiber.HeaderContentType, fiber.MIMETextPlainCharsetUTF8) return c.Status(fiber.ErrNotFound.Code).SendString(fmt.Sprintf("failed to find '%s' post", c.Params("title"))) diff --git a/static/input.css b/static/input.css index edecc19..2603afb 100644 --- a/static/input.css +++ b/static/input.css @@ -194,6 +194,135 @@ body:has(.lg-container:not([class~="lg-inline"])) .mobile-topbar-custom { display: none; } +.lh-0-9 { + line-height: 0.9; +} + +.lh-2 { + line-height: 2; +} + +.ls-vmin0-04 { + letter-spacing: 0.04vmin; +} + +.timl-vmax2 { + text-indent: 2vmax hanging; +} + +.text-vmax0-8 { + font-size: 0.8vmax; +} + +.text-vmax1 { + font-size: 1vmax !important; +} + +.text-vmax1-2 { + font-size: 1.2vmax; +} + +.text-vmax1-5 { + font-size: 1.5vmax !important; +} + +.text-vmax2 { + font-size: 2vmax; +} + +.text-vmax2-5 { + font-size: 2.5vmax; +} + +.w-vw90 { + width: 90vw; +} + +.w-p60 { + width: 60%; +} + +.w-p80 { + width: 80%; +} + +.w-p100 { + width: 100%; +} + +.w-vmax4 { + width: 4vmax; +} + +.h-vh40 { + height: 40vh; +} + +.h-vh90 { + height: 90vh; +} + +.h-vmax4 { + height: 4vmax; +} + +.mt-vmin0-8 { + margin-top: 0.8vmin; +} + +.mt-vmin1-6 { + margin-top: 1.6vmin; +} + +.mx-vmin1-6 { + margin-left: 1.6vmin; + margin-right: 1.6vmin; +} + +.mb-vmin0-4 { + margin-bottom: 0.4vmin; +} + +.mb-vmin0-6 { + margin-bottom: 0.8vmin; +} + +.mb-vmin0-8 { + margin-bottom: 0.8vmin; +} + +.mb-vmin1-2 { + margin-bottom: 1.2vmin; +} + +.mb-vmin1-6 { + margin-bottom: 1.6vmin; +} + +.pl-vmin0-8 { + padding-left: 0.8vmin; +} + +.pl-vmax2 { + padding-left: 2vmax; +} + +.pr-vmin1-2 { + padding-right: 1.2vmin; +} + +.p-vmin0-8 { + padding: 0.8vmin; +} + +.p-vmin2-4 { + padding: 2.4vmin; +} + +.space-y-vmin0-8 { + column-gap: 0.8vmin; +} + .lg-backdrop { background-color: var(--background-light-color); opacity: 0.8 !important; diff --git a/static/output.css b/static/output.css index e732576..312a97f 100644 --- a/static/output.css +++ b/static/output.css @@ -217,24 +217,12 @@ .m-2 { margin: calc(var(--spacing) * 2); } - .mx-\[1\.6vmin\] { - margin-inline: 1.6vmin; - } .mx-auto { margin-inline: auto; } .my-auto { margin-block: auto; } - .mt-\[0\.8vmin\] { - margin-top: 0.8vmin; - } - .mt-\[1\.6vmin\] { - margin-top: 1.6vmin; - } - .mt-\[8vh\] { - margin-top: 8vh; - } .mt-auto { margin-top: auto; } @@ -244,30 +232,9 @@ .mr-auto { margin-right: auto; } - .mb-\[0\.4vmin\] { - margin-bottom: 0.4vmin; - } - .mb-\[0\.6vmin\] { - margin-bottom: 0.6vmin; - } - .mb-\[0\.8vmin\] { - margin-bottom: 0.8vmin; - } - .mb-\[1\.2vmin\] { - margin-bottom: 1.2vmin; - } - .mb-\[1\.6vmin\] { - margin-bottom: 1.6vmin; - } .mb-auto { margin-bottom: auto; } - .ml-\[2vmax\] { - margin-left: 2vmax; - } - .ml-\[5vw\] { - margin-left: 5vw; - } .ml-auto { margin-left: auto; } @@ -277,12 +244,6 @@ .flex { display: flex; } - .h-\[4vmax\] { - height: 4vmax; - } - .h-\[40vh\] { - height: 40vh; - } .h-\[92vh\] { height: 92vh; } @@ -295,24 +256,6 @@ .max-h-\[80\%\] { max-height: 80%; } - .w-\[4vmax\] { - width: 4vmax; - } - .w-\[60\%\] { - width: 60%; - } - .w-\[80\%\%\] { - width: 80%%; - } - .w-\[80\%\] { - width: 80%; - } - .w-\[90vw\] { - width: 90vw; - } - .w-\[100\%\] { - width: 100%; - } .max-w-full { max-width: 100%; } @@ -373,13 +316,6 @@ .gap-4 { gap: calc(var(--spacing) * 4); } - .space-y-\[0\.8vmin\] { - :where(& > :not(:last-child)) { - --tw-space-y-reverse: 0; - margin-block-start: calc(0.8vmin * var(--tw-space-y-reverse)); - margin-block-end: calc(0.8vmin * calc(1 - var(--tw-space-y-reverse))); - } - } .justify-self-center { justify-self: center; } @@ -395,9 +331,6 @@ .rounded-4xl { border-radius: var(--radius-4xl); } - .rounded-\[20\%\] { - border-radius: 20%; - } .rounded-lg { border-radius: var(--radius-lg); } @@ -412,10 +345,6 @@ border-right-style: var(--tw-border-style); border-right-width: 1px; } - .border-l-\[0\.4vmin\] { - border-left-style: var(--tw-border-style); - border-left-width: 0.4vmin; - } .border-dashed { --tw-border-style: dashed; border-style: dashed; @@ -430,29 +359,11 @@ .object-cover { object-fit: cover; } - .object-scale-down { - object-fit: scale-down; - } .p-4 { padding: calc(var(--spacing) * 4); } - .p-\[0\.8vmin\] { - padding: 0.8vmin; - } - .p-\[2\.4vmin\] { - padding: 2.4vmin; - } - .px-\[0\.8vmin\] { - padding-inline: 0.8vmin; - } - .pr-\[1\.2vmin\] { - padding-right: 1.2vmin; - } - .pl-\[0\.8vmin\] { - padding-left: 0.8vmin; - } - .pl-\[2vmax\] { - padding-left: 2vmax; + .pr-2 { + padding-right: calc(var(--spacing) * 2); } .text-center { text-align: center; @@ -463,42 +374,12 @@ .text-right { text-align: right; } - .-indent-\[2vmax\] { - text-indent: calc(2vmax * -1); - } .font-patua { font-family: var(--font-patua); } .font-spectral { font-family: var(--font-spectral); } - .\!text-\[1vmax\]\/\[0\.9\] { - font-size: 1vmax !important; - line-height: 0.9 !important; - } - .text-\[0\.8vmax\]\/\[0\.9\] { - font-size: 0.8vmax; - line-height: 0.9; - } - .text-\[1vmax\]\/\[2\] { - font-size: 1vmax; - line-height: 2; - } - .text-\[1\.2vmax\] { - font-size: 1.2vmax; - } - .text-\[1\.5vmax\] { - font-size: 1.5vmax; - } - .text-\[1vmax\] { - font-size: 1vmax; - } - .text-\[2\.5vmax\] { - font-size: 2.5vmax; - } - .text-\[2vmax\] { - font-size: 2vmax; - } .font-bold { --tw-font-weight: var(--font-weight-bold); font-weight: var(--font-weight-bold); @@ -511,10 +392,6 @@ --tw-font-weight: var(--font-weight-medium); font-weight: var(--font-weight-medium); } - .tracking-\[0\.04vmin\] { - --tw-tracking: 0.04vmin; - letter-spacing: 0.04vmin; - } .italic { font-style: italic; } @@ -695,6 +572,103 @@ body:has(.lg-container:not([class~="lg-inline"])) .mobile-topbar-custom { .mobile { display: none; } +.lh-0-9 { + line-height: 0.9; +} +.lh-2 { + line-height: 2; +} +.ls-vmin0-04 { + letter-spacing: 0.04vmin; +} +.timl-vmax2 { + text-indent: 2vmax hanging; +} +.text-vmax0-8 { + font-size: 0.8vmax; +} +.text-vmax1 { + font-size: 1vmax !important; +} +.text-vmax1-2 { + font-size: 1.2vmax; +} +.text-vmax1-5 { + font-size: 1.5vmax !important; +} +.text-vmax2 { + font-size: 2vmax; +} +.text-vmax2-5 { + font-size: 2.5vmax; +} +.w-vw90 { + width: 90vw; +} +.w-p60 { + width: 60%; +} +.w-p80 { + width: 80%; +} +.w-p100 { + width: 100%; +} +.w-vmax4 { + width: 4vmax; +} +.h-vh40 { + height: 40vh; +} +.h-vh90 { + height: 90vh; +} +.h-vmax4 { + height: 4vmax; +} +.mt-vmin0-8 { + margin-top: 0.8vmin; +} +.mt-vmin1-6 { + margin-top: 1.6vmin; +} +.mx-vmin1-6 { + margin-left: 1.6vmin; + margin-right: 1.6vmin; +} +.mb-vmin0-4 { + margin-bottom: 0.4vmin; +} +.mb-vmin0-6 { + margin-bottom: 0.8vmin; +} +.mb-vmin0-8 { + margin-bottom: 0.8vmin; +} +.mb-vmin1-2 { + margin-bottom: 1.2vmin; +} +.mb-vmin1-6 { + margin-bottom: 1.6vmin; +} +.pl-vmin0-8 { + padding-left: 0.8vmin; +} +.pl-vmax2 { + padding-left: 2vmax; +} +.pr-vmin1-2 { + padding-right: 1.2vmin; +} +.p-vmin0-8 { + padding: 0.8vmin; +} +.p-vmin2-4 { + padding: 2.4vmin; +} +.space-y-vmin0-8 { + column-gap: 0.8vmin; +} .lg-backdrop { background-color: var(--background-light-color); opacity: 0.8 !important; @@ -880,11 +854,6 @@ body:has(.lg-container:not([class~="lg-inline"])) .mobile-topbar-custom { syntax: "*"; inherits: false; } -@property --tw-space-y-reverse { - syntax: "*"; - inherits: false; - initial-value: 0; -} @property --tw-border-style { syntax: "*"; inherits: false; @@ -894,10 +863,6 @@ body:has(.lg-container:not([class~="lg-inline"])) .mobile-topbar-custom { syntax: "*"; inherits: false; } -@property --tw-tracking { - syntax: "*"; - inherits: false; -} @property --tw-shadow { syntax: "*"; inherits: false; @@ -975,10 +940,8 @@ body:has(.lg-container:not([class~="lg-inline"])) .mobile-topbar-custom { --tw-rotate-z: initial; --tw-skew-x: initial; --tw-skew-y: initial; - --tw-space-y-reverse: 0; --tw-border-style: solid; --tw-font-weight: initial; - --tw-tracking: initial; --tw-shadow: 0 0 #0000; --tw-shadow-color: initial; --tw-shadow-alpha: 100%; diff --git a/views/index.html b/views/index.html index 1c57bd1..ce80db6 100644 --- a/views/index.html +++ b/views/index.html @@ -12,51 +12,39 @@ <style> .menu-outer-body { border-radius: 10%; - width: 40vh; - height: 30vh; + width: 60vw; + height: 40vh; } .menu-inner-body { width: 85%; } - .flex-adaptive { - flex-direction: row; - } - - .language-icon { - max-width: calc(80% / {{ .AvailableLanguages | len }}); - max-height: 80%; - } - - @media (max-aspect-ratio: 0.8/1) { + @media (max-aspect-ratio: 1.2/1) { .menu-outer-body { border-radius: 5%; } - .menu-outer-body { - width: min(40vh, 100vw); - height: 40vh; - border-radius: 0; + .menu-inner-body { + width: 92.5%; } + } - .language-icon { - max-width: 40%; - max-height: calc(80% / {{ .AvailableLanguages | len }}); + @media (max-aspect-ratio: 0.8/1) { + .menu-outer-body { + width: 100vw; + height: 80vh; + border-radius: 0; } .menu-inner-body { - width: 92.5%; - } - - .flex-adaptive { - flex-direction: column; + width: 100%; } } </style> </head> -<body data-theme="night" class="font-spectral text-main-dark text-[1.5vmax] overflow-hidden bg-interlocked-hexagons h-screen flex flex-col"> +<body data-theme="night" class="font-spectral text-main-dark text-vmax1-5 overflow-hidden bg-interlocked-hexagons h-screen flex flex-col"> <div class="absolute star z-0">*</div> <div class="absolute star z-0">*</div> @@ -103,13 +91,27 @@ </script> <div class="menu-outer-body p-4 z-1 bg-background-dark flex flex-col mx-auto my-auto opacity-70"> - <p class="font-patua mx-auto text-[2.5vmax] mt-[0.8vmin] mb-[0.8vmin]">saya.today</p> - <div class="menu-inner-body grow bg-background-light flex flex-adaptive mx-auto opacity-100"> - {{- range .AvailableLanguages }} - <img onclick="location.href='/blog/{{ .Name }}';" class="object-scale-down cursor-pointer flex-1 rounded-[20%] language-icon mx-auto my-auto relative" src="{{ .Flag }}" alt="{{ .Alt }}"> + <p class="font-patua mx-auto text-vmax2-5 mt-vmin0-8 mb-vmin1-6">saya.today</p> + <div class="menu-inner-body grow bg-background-light flex flex-col mx-auto mb-vmin1-6 overflow-y-auto opacity-100"> + {{- range .BlogPages }} + <div class="m-2 flex flex-row justify-center justify-items-center gap-4"> + <img onclick="location.href='/blog/{{ .Link }}';" style="flex-grow: 0;" class="flex-1 cursor-pointer object-cover rounded-4xl select-none w-vmax4 h-vmax4" src="https://f003.backblazeb2.com/file/sayana-photos/thumbnails/{{ .Thumbnail }}.webp"> + <div class="flex-5 justify-self-center flex-col border-r-1 border-dashed border-opacity-50 border-main-medium"> + <a href="/blog/{{ .Link }}" class="block font-extrabold">{{ .Title }}</a> + <a href="/blog/{{ .Link }}" class="block italic text-vmax1 text-secondary">{{ .ActionDate }}</a> + <p>{{ .ShortDescription }}</p> + </div> + <div class="flex-3 justify-self-center flex flex-col text-right"> + <p class="grow text-vmax1"> + Тэги: {{ .Tags }} + </p> + <p class="italic text-secondary text-vmax1"> + {{ .PublishedTime }} + </p> + </div> + </div> {{- end }} </div> - <p class="font-spectral mx-auto text-[1.5vmax] text-secondary mt-[0.8vmin] mb-[0.8vmin]">Choose your language</p> </div> <script> diff --git a/views/layouts/blog-main.html b/views/layouts/blog-main.html deleted file mode 100644 index 1b8e149..0000000 --- a/views/layouts/blog-main.html +++ /dev/null @@ -1,147 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -<head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>SAYA TODAY // Заглавная</title> - <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css"> - <link rel="preconnect" href="https://fonts.googleapis.com"> - <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> - <link href="https://fonts.googleapis.com/css2?family=Spectral:ital,wght@0,200;0,300;0,400;0,500;0,600;0,700;0,800;1,200;1,300;1,400;1,500;1,600;1,700;1,800&family=Patua+One&display=swap" rel="stylesheet"> - <link href="/output.css" rel="stylesheet"> - <style> - .menu-outer-body { - border-radius: 10%; - width: 60vw; - height: 40vh; - } - - .menu-inner-body { - width: 85%; - } - - @media (max-aspect-ratio: 1.2/1) { - .menu-outer-body { - border-radius: 5%; - } - - .menu-inner-body { - width: 92.5%; - } - } - - @media (max-aspect-ratio: 0.8/1) { - .menu-outer-body { - width: 100vw; - height: 80vh; - border-radius: 0; - } - - .menu-inner-body { - width: 100%; - } - } - </style> -</head> - -<body data-theme="night" class="font-spectral text-main-dark text-[1.5vmax] overflow-hidden bg-interlocked-hexagons h-screen flex flex-col"> - - <div class="absolute star z-0">*</div> - <div class="absolute star z-0">*</div> - <div class="absolute star z-0">*</div> - <div class="absolute star z-0">*</div> - <div class="absolute star z-0">*</div> - <div class="absolute star z-0">*</div> - <div class="absolute star z-0">*</div> - <div class="absolute star z-0">*</div> - <div class="absolute star z-0">*</div> - <div class="absolute star z-0">*</div> - <div class="absolute star z-0">*</div> - <div class="absolute star z-0">*</div> - <div class="absolute star z-0">*</div> - <div class="absolute star z-0">*</div> - <div class="absolute star z-0">*</div> - <div class="absolute star z-0">*</div> - <div class="absolute star z-0">*</div> - <div class="absolute star z-0">*</div> - <div class="absolute star z-0">*</div> - <div class="absolute star z-0">*</div> - <div class="absolute star z-0">*</div> - <div class="absolute star z-0">*</div> - <div class="absolute star z-0">*</div> - <div class="absolute star z-0">*</div> - <div class="absolute star z-0">*</div> - - <script> - function switchTheme(theme) { - if (theme == "" || typeof theme == "undefined") { - const currentTheme = document.body.getAttribute('data-theme'); - switch (currentTheme) { - case "olive": theme = "lettuce"; break; - case "lettuce": theme = "night"; break; - case "night": theme = "olive"; break; - } - } - // localStorage.setItem('theme', theme); - document.body.setAttribute('data-theme', theme); - } - - const savedTheme = 'night'; - switchTheme(savedTheme); - </script> - - <div class="menu-outer-body p-4 z-1 bg-background-dark flex flex-col mx-auto my-auto opacity-70"> - <p class="font-patua mx-auto text-[2.5vmax] mt-[0.8vmin] mb-[1.6vmin]">saya.today</p> - <div class="menu-inner-body grow bg-background-light flex flex-col mx-auto mb-[1.6vmin] overflow-y-auto opacity-100"> - {{- range .BlogPages }} - <div class="m-2 flex flex-row justify-center justify-items-center gap-4"> - <img onclick="location.href='/blog/{{ .Link }}';" style="flex-grow: 0;" class="flex-1 cursor-pointer object-cover rounded-4xl select-none w-[4vmax] h-[4vmax]" src="https://f003.backblazeb2.com/file/sayana-photos/thumbnails/{{ .Thumbnail }}.webp"> - <div class="flex-5 justify-self-center flex-col border-r-1 border-dashed border-opacity-50 border-main-medium"> - <a href="/blog/{{ .Link }}" class="block font-extrabold">{{ .Title }}</a> - <a href="/blog/{{ .Link }}" class="block italic text-[1vmax] text-secondary">{{ .ActionDate }}</a> - <p>{{ .ShortDescription }}</p> - </div> - <div class="flex-3 justify-self-center flex flex-col text-right"> - <p class="grow text-[1vmax]"> - {{ .Tags }} - </p> - <p class="italic text-secondary text-[1vmax]"> - {{ .PublishedTime }} - </p> - </div> - </div> - {{- end }} - </div> - </div> - - <script> - function generateStars() { - var clWidth = document.documentElement.clientWidth; - var clHeight = document.documentElement.clientHeight; - - stars = document.getElementsByClassName("star"); - for (let starIndex = 0; starIndex < stars.length; starIndex++) { - const star = stars[starIndex]; - const x = Math.floor(Math.random() * clWidth); - const y = Math.floor(Math.random() * clHeight * 0.8); - const rot = Math.random() * 90; - const animDuration = (Math.random() * 10) + 3; - const sz = Math.floor(Math.random() * 8) + 12; - star.style.transform = `translateX(${x}px) translateY(${y}px) rotate(${rot}deg)`; - star.style.animationDuration = `${animDuration}s`; - star.style.fontSize = `${sz}px`; - } - } - - document.addEventListener('DOMContentLoaded', generateStars); - - let generateStarsTimer; - window.addEventListener("resize", () => { - clearTimeout(generateStarsTimer); - generateStarsTimer = setTimeout(() => { - generateStars(); - }, 1000); - }); - </script> -</body> -</html> diff --git a/views/layouts/blog-page.html b/views/layouts/blog-page.html index 3552d00..427f33e 100644 --- a/views/layouts/blog-page.html +++ b/views/layouts/blog-page.html @@ -49,7 +49,7 @@ saya.today </div> <div class="flex flex-col gap-0 relative z-20"> - <i onclick="location.href='../';" class="fas fa-home nav-icon-custom text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 flex justify-center items-center rounded-lg"></i> + <i onclick="location.href='/';" class="fas fa-home nav-icon-custom text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 flex justify-center items-center rounded-lg"></i> <i class="fas fa-search nav-icon-custom text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 flex justify-center items-center rounded-lg"></i> <i class="fas fa-images nav-icon-custom text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 flex justify-center items-center rounded-lg"></i> <i onclick="switchTheme('')" class="fas fa-swatchbook nav-icon-custom text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 flex justify-center items-center rounded-lg"></i> @@ -59,26 +59,26 @@ <div class="bg-background-dark z-10 h-screen desktop"> <div class="border-left-custom bg-background-dark"></div> - <div class="content-square flex flex-col bg-background-dark relative mt-[1.6vmin] mx-[1.6vmin]"> - <div class="flex flex-row mb-[0.4vmin]"> - <i onclick="location.href='../';" class="fas fa-circle-left hover:bg-main-dark hover:bg-opacity-10 cursor-pointer transition-colors duration-300 rounded-md text-[2vmax] mt-auto mb-auto px-[0.8vmin]"></i> - <p class="text-[2vmax] font-spectral italic font-extrabold select-none mt-auto pl-[0.8vmin] pr-[1.2vmin]">//</p> - <p class="text-[2vmax] font-spectral italic text-left mt-auto">{{ .Title }}</p> - <p class="grow text-[1.5vmax] font-spectral text-secondary text-right mt-auto">{{ .PublishedDate }}</p> + <div class="content-square flex flex-col bg-background-dark relative mt-vmin1-6 mx-vmin1-6"> + <div class="flex flex-row mb-vmin0-4"> + <i onclick="location.href='/';" class="fas fa-circle-left hover:bg-main-dark hover:bg-opacity-10 cursor-pointer transition-colors duration-300 rounded-md text-vmax2 mt-auto mb-auto pl-vmin0-8 pr-2"></i> + <p class="text-vmax2 font-spectral italic font-extrabold select-none mt-auto pl-vmin0-8 pr-vmin1-2">//</p> + <p class="text-vmax2 font-spectral italic text-left mt-auto">{{ .Title }}</p> + <p class="grow text-vmax1-5 font-spectral text-secondary text-right mt-auto">{{ .PublishedDate }}</p> </div> - <hr class="border-t-4 border-dotted border-main-dark mb-[0.8vmin]"> + <hr class="border-t-4 border-dotted border-main-dark mb-vmin0-8"> - <div class="bg-background-light flex flex-col flex-1 overflow-y-auto inset-shadow p-[2.4vmin]"> + <div class="bg-background-light flex flex-col flex-1 overflow-y-auto inset-shadow p-vmin2-4"> {{ .ParsedMarkdownDesktop }} {{- if .MapLocationX }} - <hr class="border-t-4 border-dotted border-main-dark mt-[0.8vmin] mb-[0.8vmin] w-[80%] ml-auto mr-auto"> - <div id="location-map-desktop" class="relative p-[0.8vmin] flex-none ml-auto mr-auto w-[60%] h-[40vh]"></div> - <hr class="border-t-4 border-dotted border-main-dark mt-[0.8vmin] mb-[0.8vmin] w-[80%] ml-auto mr-auto"> + <hr class="border-t-4 border-dotted border-main-dark mt-vmin0-8 mb-vmin0-8 w-p80 ml-auto mr-auto"> + <div id="location-map-desktop" class="relative p-vmin0-8 flex-none ml-auto mr-auto w-p60 h-vh40"></div> + <hr class="border-t-4 border-dotted border-main-dark mt-vmin0-8 mb-vmin0-8 w-p80 ml-auto mr-auto"> {{- end }} </div> - <div class="flex flex-row mt-[0.8vmin] mb-[0.4vmin]"> - <p class="grow text-[0.8vmax]/[0.9] font-spectral italic text-right text-secondary mr-2"> + <div class="flex flex-row mt-vmin0-8 mb-vmin0-4"> + <p class="grow text-vmax0-8 lh-0-9 font-spectral italic text-right text-secondary mr-2"> <a href="">{{ .Title }}</a> © {{ .PublishedYear }} by <a href="https://t.me/EarlInisMona">Saya Andy</a> is licensed under <a href="https://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0</a> </p> <img src="https://mirrors.creativecommons.org/presskit/icons/cc.svg" alt="" style="max-width:1.2vh; max-height:1.2vh;"> @@ -86,15 +86,15 @@ <img src="https://mirrors.creativecommons.org/presskit/icons/sa.svg" alt="" style="max-width:1.2vh; max-height:1.2vh;"> </div> - <hr class="border-t-4 border-dotted border-main-dark mb-[0.8vmin]"> + <hr class="border-t-4 border-dotted border-main-dark mb-vmin0-8"> </div> <div class="border-right-custom bg-background-dark shadow-2xl"></div> </div> - <div class="mobile-topbar-custom fixed bg-squares-and-triangles bg-repeat flex-row items-center shadow-2xl w-[90vw] z-20 mobile"> + <div class="mobile-topbar-custom fixed bg-squares-and-triangles bg-repeat flex-row items-center shadow-2xl w-vw90 z-20 mobile"> <div class="flex flex-row gap-0 relative z-20"> - <i onclick="location.href='../';" class="fas fa-home nav-icon-custom text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 flex justify-center items-center rounded-lg"></i> + <i onclick="location.href='/';" class="fas fa-home nav-icon-custom text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 flex justify-center items-center rounded-lg"></i> <i class="fas fa-search nav-icon-custom text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 flex justify-center items-center rounded-lg"></i> <i class="fas fa-images nav-icon-custom text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 flex justify-center items-center rounded-lg"></i> <i onclick="switchTheme('')" class="fas fa-swatchbook nav-icon-custom text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 flex justify-center items-center rounded-lg"></i> @@ -104,29 +104,29 @@ </div> </div> - <div class="bg-background-dark flex-row z-10 w-[90vw] h-[92vh] mobile ml-[5vw] mt-[8vh]"> + <div class="bg-background-dark flex-row z-10 w-vw90 h-[92vh] mobile" style="margin-left: 5vw; margin-top: 8vh;"> <div class="border-left-custom bg-background-dark"></div> - <div class="content-square flex flex-col bg-background-dark relative mt-[1.6vmin] mx-[1.6vmin]"> - <div class="flex flex-row mb-[0.4vmin]"> - <i onclick="location.href='../';" class="fas fa-circle-left hover:bg-main-dark hover:bg-opacity-10 cursor-pointer transition-colors duration-300 rounded-md text-[2vmax] mt-auto mb-auto px-[0.8vmin]"></i> - <p class="text-[2vmax] font-spectral italic font-extrabold select-none mt-auto pl-[0.8vmin] pr-[1.2vmin]">//</p> - <p class="text-[2vmax] font-spectral italic text-left mt-auto">{{ .Title }}</p> - <p class="grow text-[1.5vmax] font-spectral text-secondary text-right mt-auto">{{ .PublishedDate }}</p> + <div class="content-square flex flex-col bg-background-dark relative mt-vmin1-6 mx-vmin1-6"> + <div class="flex flex-row mb-vmin0-4"> + <i onclick="location.href='/';" class="fas fa-circle-left hover:bg-main-dark hover:bg-opacity-10 cursor-pointer transition-colors duration-300 rounded-md text-vmax2 mt-auto mb-auto pl-vmin0-8 pr-2"></i> + <p class="text-vmax2 font-spectral italic font-extrabold select-none mt-auto pl-vmin0-8 pr-vmin1-2">//</p> + <p class="text-vmax2 font-spectral italic text-left mt-auto">{{ .Title }}</p> + <p class="grow text-vmax1-5 font-spectral text-secondary text-right mt-auto">{{ .PublishedDate }}</p> </div> - <hr class="border-t-4 border-dotted border-main-dark mb-[0.8vmin]"> + <hr class="border-t-4 border-dotted border-main-dark mb-vmin0-8"> - <div class="bg-background-light flex flex-col overflow-y-auto inset-shadow p-[2.4vmin] max-h-[80%]"> + <div class="bg-background-light flex flex-col overflow-y-auto inset-shadow p-vmin2-4 max-h-[80%]"> {{ .ParsedMarkdownMobile }} {{- if .MapLocationX }} - <hr class="border-t-4 border-dotted border-main-dark mt-[0.8vmin] mb-[0.8vmin] w-[80%] ml-auto mr-auto"> - <div id="location-map-mobile" class="relative p-[0.8vmin] flex-none ml-auto mr-auto w-[100%] h-[40vh]"></div> - <hr class="border-t-4 border-dotted border-main-dark mt-[0.8vmin] mb-[0.8vmin] w-[80%] ml-auto mr-auto"> + <hr class="border-t-4 border-dotted border-main-dark mt-vmin0-8 mb-vmin0-8 w-p80 ml-auto mr-auto"> + <div id="location-map-mobile" class="relative p-vmin0-8 flex-none ml-auto mr-auto w-p100 h-vh40"></div> + <hr class="border-t-4 border-dotted border-main-dark mt-vmin0-8 mb-vmin0-8 w-p80 ml-auto mr-auto"> {{- end }} </div> - <div class="flex flex-row mt-[0.8vmin] mb-[0.4vmin]"> - <p class="grow text-[0.8vmax]/[0.9] font-spectral italic text-right text-secondary mr-2"> + <div class="flex flex-row mt-vmin0-8 mb-vmin0-4"> + <p class="grow text-vmax0-8 lh-0-9 font-spectral italic text-right text-secondary mr-2"> <a href="">{{ .Title }}</a> © {{ .PublishedYear }} by <a href="https://t.me/EarlInisMona">Saya Andy</a> is licensed under <a href="https://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0</a> </p> <img src="https://mirrors.creativecommons.org/presskit/icons/cc.svg" alt="" style="max-width:1.2vh; max-height:1.2vh;"> @@ -134,7 +134,7 @@ <img src="https://mirrors.creativecommons.org/presskit/icons/sa.svg" alt="" style="max-width:1.2vh; max-height:1.2vh;"> </div> - <hr class="border-t-4 border-dotted border-main-dark mb-[0.8vmin]"> + <hr class="border-t-4 border-dotted border-main-dark mb-vmin0-8"> </div> <div class="border-right-custom bg-background-dark shadow-2xl"></div> |