mirror of
https://github.com/Kugelschieber/schnittfest.git
synced 2026-11-12 09:02:01 +01:00
New design.
This commit is contained in:
@@ -1 +1,3 @@
|
|||||||
config.json
|
config.json
|
||||||
|
.secrets.env
|
||||||
|
shifu.db
|
||||||
|
|||||||
@@ -0,0 +1,764 @@
|
|||||||
|
# AGENTS.md — Building and editing websites with Shifu
|
||||||
|
|
||||||
|
This file tells an AI agent how to create and maintain a website built with
|
||||||
|
[Shifu](https://github.com/emvi/shifu), a Git/file-based CMS that renders Go
|
||||||
|
`html/template` files from JSON content. Read it fully before generating or
|
||||||
|
changing anything. When the rules here conflict with habits from other
|
||||||
|
frameworks (React, Hugo, Next.js, Tailwind build pipelines, …), the rules here win.
|
||||||
|
|
||||||
|
The goal of every change: **a site that renders correctly AND stays fully editable
|
||||||
|
in Shifu's admin UI** (on-page editor at `/admin`). Code that renders but cannot be
|
||||||
|
edited in the admin is considered broken.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Mental model
|
||||||
|
|
||||||
|
| Concept | Where it lives | What it is |
|
||||||
|
|---|---|---|
|
||||||
|
| **Template** | `tpl/**/<name>.html` | Go `html/template` for one element type (section, component, layout part). |
|
||||||
|
| **Admin config** | `admin/tpl/**/<name>.json` | Makes the template editable: label, editable fields, child content areas. |
|
||||||
|
| **Page** | `content/pages/**/<file>.json` | JSON with `path` (routes per language) and a tree of elements. |
|
||||||
|
| **Reference** ("ref") | `content/refs/<name>.json` | A standalone, reusable element (header, footer, head, …) shared by many pages. |
|
||||||
|
| **Sass** | `assets/scss/` | Compiled by Shifu (`sass` CLI) into `static/`. |
|
||||||
|
| **JS/TS** | `assets/js/` | Bundled + minified by Shifu (embedded esbuild) into `static/`. |
|
||||||
|
| **Static files** | `static/` | Served as-is under `/static/`. Admin uploads go to `static/media/`. |
|
||||||
|
| **Config** | `config.json` (+ `.secrets.env`) | Server, Sass/JS build, admin UI, etc. |
|
||||||
|
|
||||||
|
Rendering: a request matches a page `path` → Shifu walks `content.content` (the
|
||||||
|
root list of elements) in order → each element renders `tpl/.../<tpl>.html` with
|
||||||
|
`.CMS`, `.Args`, `.Page`, `.Content` → elements render their own children via
|
||||||
|
`.CMS.Render`.
|
||||||
|
|
||||||
|
### The "one element type = matching files" rule
|
||||||
|
|
||||||
|
Every editable element type `<name>` consists of files that share the same base name:
|
||||||
|
|
||||||
|
```
|
||||||
|
tpl/sections/hero.html # required — markup
|
||||||
|
admin/tpl/sections/hero.json # required — makes it editable/addable in the admin
|
||||||
|
assets/scss/_hero.scss # optional — styles, scoped to .hero
|
||||||
|
assets/js/hero.js # optional — behaviour, bound via data-component="hero"
|
||||||
|
```
|
||||||
|
|
||||||
|
Names: lowercase `snake_case`, **globally unique across all subdirectories** (Shifu
|
||||||
|
identifies templates by file base name only, folders are just for humans).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Project structure
|
||||||
|
|
||||||
|
Use this layout for new sites (it matches `shifu init` and the admin UI's own paths):
|
||||||
|
|
||||||
|
```
|
||||||
|
.
|
||||||
|
├── config.json
|
||||||
|
├── .secrets.env # secrets, never commit (add to .gitignore)
|
||||||
|
├── .gitignore
|
||||||
|
├── admin/
|
||||||
|
│ └── tpl/
|
||||||
|
│ ├── layout/ # head.json, end.json, header.json, footer.json
|
||||||
|
│ ├── sections/ # hero.json, text.json, cards.json, …
|
||||||
|
│ └── components/ # card.json, button.json, nav_item.json, …
|
||||||
|
├── assets/
|
||||||
|
│ ├── scss/
|
||||||
|
│ │ ├── main.scss # Sass entrypoint (only file referenced in config)
|
||||||
|
│ │ ├── _variables.scss
|
||||||
|
│ │ ├── _base.scss
|
||||||
|
│ │ └── _hero.scss … # one partial per element type, FLAT (no subfolders)
|
||||||
|
│ └── js/
|
||||||
|
│ ├── main.js # JS entrypoint
|
||||||
|
│ └── hero.js … # one module per interactive element type, FLAT
|
||||||
|
├── content/
|
||||||
|
│ ├── pages/ # pages (admin creates pages here)
|
||||||
|
│ │ ├── home.json
|
||||||
|
│ │ └── not-found.json
|
||||||
|
│ └── refs/ # references (admin creates refs here)
|
||||||
|
│ ├── head.json
|
||||||
|
│ └── end.json
|
||||||
|
├── static/ # served under /static/
|
||||||
|
│ ├── media/ # admin media library (uploads)
|
||||||
|
│ ├── main.css # GENERATED by Shifu — never write by hand
|
||||||
|
│ └── main.js # GENERATED by Shifu — never write by hand
|
||||||
|
└── tpl/
|
||||||
|
├── layout/ # head.html, end.html, header.html, footer.html
|
||||||
|
├── sections/
|
||||||
|
├── components/
|
||||||
|
└── partials/ # non-editable helpers used via {{ template }}
|
||||||
|
```
|
||||||
|
|
||||||
|
If you are editing an **existing** site, keep its structure, naming and file
|
||||||
|
locations (check `config.json` for the real `sass`/`js` dirs, entrypoints and output
|
||||||
|
paths) instead of migrating it to this layout.
|
||||||
|
|
||||||
|
`shifu.db` (SQLite, created at runtime when the admin UI is enabled) stores admin
|
||||||
|
users, sessions and the list of references. Don't commit it.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. config.json
|
||||||
|
|
||||||
|
Minimal configuration for local development:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"dev": true,
|
||||||
|
"log_level": "info",
|
||||||
|
"server": {
|
||||||
|
"host": "localhost",
|
||||||
|
"port": 8080,
|
||||||
|
"hostname": "http://localhost:8080"
|
||||||
|
},
|
||||||
|
"content": {
|
||||||
|
"provider": "fs",
|
||||||
|
"not_found": {
|
||||||
|
"en": "/not-found",
|
||||||
|
"de": "/de/nicht-gefunden"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sass": {
|
||||||
|
"dir": "assets/scss",
|
||||||
|
"entrypoint": "main.scss",
|
||||||
|
"out": "static/main.css",
|
||||||
|
"out_source_map": "static/main.css.map",
|
||||||
|
"watch": true
|
||||||
|
},
|
||||||
|
"js": {
|
||||||
|
"dir": "assets/js",
|
||||||
|
"entrypoint": "main.js",
|
||||||
|
"out": "static/main.js",
|
||||||
|
"source_map": true,
|
||||||
|
"watch": true
|
||||||
|
},
|
||||||
|
"ui": {
|
||||||
|
"path": "/admin",
|
||||||
|
"admin_password": "${ADMIN_PASSWORD}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`.secrets.env` (one `KEY=value` per line, referenced as `${KEY}` in `config.json`):
|
||||||
|
|
||||||
|
```env
|
||||||
|
ADMIN_PASSWORD=admin
|
||||||
|
```
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
* `dev: true` reloads templates and content on every request (local only). For
|
||||||
|
production set `dev: false`, set `server.host` to `""`, `server.hostname` to the
|
||||||
|
public origin (e.g. `https://example.com`, used for canonical links/sitemap), and
|
||||||
|
`secure_cookies: true`.
|
||||||
|
* Keys starting with `_` are treated as comments by convention (they are ignored).
|
||||||
|
* Optional sections (`api`, `remote`, `git`, `analytics`, `cors`) are documented in
|
||||||
|
the Shifu README — only add them when asked.
|
||||||
|
* Run with `shifu run .` (requires the `sass` CLI: `npm i -g sass`). JS needs no
|
||||||
|
Node.js, esbuild is built in.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Templates (`tpl/`)
|
||||||
|
|
||||||
|
Go `html/template` syntax plus Shifu functions and all
|
||||||
|
[Sprig](https://masterminds.github.io/sprig/) functions.
|
||||||
|
|
||||||
|
### 4.1 Variables available in every template
|
||||||
|
|
||||||
|
| Variable | Meaning |
|
||||||
|
|---|---|
|
||||||
|
| `.CMS` | CMS instance. `.CMS.Render`, `.CMS.LastUpdate` (cache-busting string). |
|
||||||
|
| `.Args` | `map[string]string` of route variables, e.g. `{{ index .Args "slug" }}`. |
|
||||||
|
| `.Page` | The page: `.Page.Language`, `.Page.Path` (map lang → path), `.Page.CanonicalLink`, `.Page.File`. |
|
||||||
|
| `.Content` | The element being rendered: `.Content.Position`, `.Content.Data`, `.Content.Copy`, `.Content.Content`. |
|
||||||
|
|
||||||
|
### 4.2 Shifu template functions
|
||||||
|
|
||||||
|
| Function | Use |
|
||||||
|
|---|---|
|
||||||
|
| `copy .Page .Content "key"` | Translated text for the page language; falls back to `en`. Returns `nil` if missing. |
|
||||||
|
| `get .Content "key"` | Language-independent value from `data`. Returns `nil` if missing. |
|
||||||
|
| `html <string>` | Output trusted HTML (needed for `html` type fields). |
|
||||||
|
| `htmlAttr <string>` | Output a trusted attribute. |
|
||||||
|
| `fmt "%s/%s" a b` | `fmt.Sprintf`. |
|
||||||
|
| `dict "k" v "k2" v2` | Build a map, e.g. to pass to partials. |
|
||||||
|
| `default a b c` | **Shifu's version**: returns the first non-nil argument (NOT Sprig's `default "fallback" .x`). |
|
||||||
|
| `int "12"`, `uint64`, `formatInt`, `formatFloat`, `formatDate`, `gtFloat`, `ltFloat`, `shuffle`, `year` | Helpers. |
|
||||||
|
| `markdown "static/x.md" .`, `markdownBlock "static/x.md" "block" .` | Render a Markdown file (path relative to project root). |
|
||||||
|
| `hostname`, `config` | `server.hostname`, full config. |
|
||||||
|
| `adminHead .Page`, `adminBody .Page`, `loggedIn .Page` | Admin UI hooks (see §4.4). |
|
||||||
|
|
||||||
|
### 4.3 Element template contract (REQUIRED for admin editing)
|
||||||
|
|
||||||
|
Every editable element template must:
|
||||||
|
|
||||||
|
1. Have **exactly one top-level HTML element** carrying
|
||||||
|
`data-shifu-element="{{ .Content.Position }}"`.
|
||||||
|
2. For each child content area `<area>` declared in its admin config, render the
|
||||||
|
children **and** place a slot directly after them:
|
||||||
|
```gotemplate
|
||||||
|
{{ .CMS.Render .Args .Page (fmt "%s.<area>" .Content.Position) (index .Content.Content "<area>") }}
|
||||||
|
<slot name="{{ .Content.Position }}/<area>"></slot>
|
||||||
|
```
|
||||||
|
The `<area>` string must be identical in all three places (position suffix,
|
||||||
|
`index` key, slot name) and in the admin config's `content` keys.
|
||||||
|
3. Read every editable value through `copy` (translatable text) or `get` (data), and
|
||||||
|
handle missing values — new elements added in the admin start **empty**.
|
||||||
|
|
||||||
|
Canonical section template — `tpl/sections/text.html`:
|
||||||
|
|
||||||
|
```gotemplate
|
||||||
|
{{- $headline := copy .Page .Content "headline" -}}
|
||||||
|
{{- $text := copy .Page .Content "text" -}}
|
||||||
|
{{- $background := get .Content "background" -}}
|
||||||
|
|
||||||
|
<section class="text{{ with $background }} text--{{ . }}{{ end }}" data-shifu-element="{{ .Content.Position }}">
|
||||||
|
<div class="text__inner">
|
||||||
|
{{ with $headline }}<h2 class="text__headline">{{ . }}</h2>{{ end }}
|
||||||
|
{{ with $text }}<div class="text__body">{{ html . }}</div>{{ end }}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
```
|
||||||
|
|
||||||
|
Container with child elements — `tpl/sections/cards.html`:
|
||||||
|
|
||||||
|
```gotemplate
|
||||||
|
{{- $headline := copy .Page .Content "headline" -}}
|
||||||
|
|
||||||
|
<section class="cards" data-shifu-element="{{ .Content.Position }}">
|
||||||
|
{{ with $headline }}<h2 class="cards__headline">{{ . }}</h2>{{ end }}
|
||||||
|
<div class="cards__grid">
|
||||||
|
{{ .CMS.Render .Args .Page (fmt "%s.items" .Content.Position) (index .Content.Content "items") }}
|
||||||
|
<slot name="{{ .Content.Position }}/items"></slot>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
```
|
||||||
|
|
||||||
|
Child element — `tpl/components/card.html`:
|
||||||
|
|
||||||
|
```gotemplate
|
||||||
|
{{- $title := copy .Page .Content "title" -}}
|
||||||
|
{{- $text := copy .Page .Content "text" -}}
|
||||||
|
{{- $href := copy .Page .Content "href" -}}
|
||||||
|
{{- $image := get .Content "image" -}}
|
||||||
|
|
||||||
|
<article class="card" data-shifu-element="{{ .Content.Position }}">
|
||||||
|
{{ with $image }}<img class="card__image" src="{{ . }}" alt="{{ copy $.Page $.Content "image_alt" }}" loading="lazy" />{{ end }}
|
||||||
|
{{ with $title }}<h3 class="card__title">{{ . }}</h3>{{ end }}
|
||||||
|
{{ with $text }}<div class="card__text">{{ html . }}</div>{{ end }}
|
||||||
|
{{ with $href }}<a class="card__link" href="{{ . }}">{{ default (copy $.Page $.Content "link_label") "Read more" }}</a>{{ end }}
|
||||||
|
</article>
|
||||||
|
```
|
||||||
|
|
||||||
|
Multiple content areas (e.g. two columns) — `tpl/sections/columns.html`:
|
||||||
|
|
||||||
|
```gotemplate
|
||||||
|
<section class="columns" data-shifu-element="{{ .Content.Position }}">
|
||||||
|
<div class="columns__col">
|
||||||
|
{{ .CMS.Render .Args .Page (fmt "%s.left" .Content.Position) (index .Content.Content "left") }}
|
||||||
|
<slot name="{{ .Content.Position }}/left"></slot>
|
||||||
|
</div>
|
||||||
|
<div class="columns__col">
|
||||||
|
{{ .CMS.Render .Args .Page (fmt "%s.right" .Content.Position) (index .Content.Content "right") }}
|
||||||
|
<slot name="{{ .Content.Position }}/right"></slot>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
```
|
||||||
|
|
||||||
|
Pitfalls:
|
||||||
|
|
||||||
|
* Inside `with`/`range`, `.` changes — use `$.Page` / `$.Content`.
|
||||||
|
* `{{ html $x }}` with a missing value prints the literal text `<nil>`. Always wrap
|
||||||
|
it: `{{ with $x }}{{ html . }}{{ end }}`.
|
||||||
|
* Never hard-code visible text in element templates — put it in `copy` so it is
|
||||||
|
editable and translatable. (Fallback labels via `default` are fine.)
|
||||||
|
* Don't use Go's `{{ block }}`/`{{ define }}` inheritance for page layouts. Layout
|
||||||
|
in Shifu is composition: pages are lists of elements (`head`, `header`, sections,
|
||||||
|
`footer`, `end`).
|
||||||
|
* Template file base names must be unique across all of `tpl/`; `tpl/a/card.html`
|
||||||
|
and `tpl/b/card.html` would clash.
|
||||||
|
|
||||||
|
### 4.4 Layout templates (head / end)
|
||||||
|
|
||||||
|
Every page starts with a `head` element and ends with an `end` element (normally
|
||||||
|
used as references, see §6). They split the HTML document. The admin UI needs
|
||||||
|
`adminHead` inside `<head>` and `adminBody` before `</body>`. They output nothing for
|
||||||
|
regular visitors.
|
||||||
|
|
||||||
|
`tpl/layout/head.html`:
|
||||||
|
|
||||||
|
```gotemplate
|
||||||
|
{{- $title := copy .Page .Content "title" -}}
|
||||||
|
{{- $description := copy .Page .Content "meta_description" -}}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="{{ .Page.Language }}">
|
||||||
|
<head>
|
||||||
|
<base href="/" />
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>{{ $title }}</title>
|
||||||
|
<meta name="description" content="{{ $description }}" />
|
||||||
|
<link rel="canonical" href="{{ .Page.CanonicalLink }}" />
|
||||||
|
{{- range $language, $path := .Page.Path }}
|
||||||
|
<link rel="alternate" hreflang="{{ $language }}" href="{{ hostname }}{{ $path }}" />
|
||||||
|
{{- end }}
|
||||||
|
<link rel="stylesheet" href="/static/main.css?v={{ .CMS.LastUpdate }}" />
|
||||||
|
<script defer src="/static/main.js?v={{ .CMS.LastUpdate }}"></script>
|
||||||
|
{{ adminHead .Page }}
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
```
|
||||||
|
|
||||||
|
`tpl/layout/end.html`:
|
||||||
|
|
||||||
|
```gotemplate
|
||||||
|
{{ adminBody .Page }}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
The `/static/...` file names must match `sass.out` and `js.out` in `config.json`.
|
||||||
|
|
||||||
|
The head is a *layout* element and is not wrapped in `data-shifu-element`
|
||||||
|
(`<head>` content cannot be edited on-page; its fields are editable from the
|
||||||
|
admin's page tree). For per-page titles, override the head reference's copy on
|
||||||
|
each page (§6).
|
||||||
|
|
||||||
|
### 4.5 Partials (non-editable helpers)
|
||||||
|
|
||||||
|
Put reusable markup that is *not* an admin element in `tpl/partials/` and call it
|
||||||
|
by file name. Do **not** create an admin config for partials.
|
||||||
|
|
||||||
|
```gotemplate
|
||||||
|
{{/* tpl/partials/button.html */}}
|
||||||
|
<a class="button button--{{ default .Variant "primary" }}" href="{{ .Href }}">{{ .Label }}</a>
|
||||||
|
```
|
||||||
|
|
||||||
|
```gotemplate
|
||||||
|
{{ with copy .Page .Content "cta_label" }}
|
||||||
|
{{ template "button.html" (dict "Label" . "Href" (copy $.Page $.Content "cta_href") "Variant" (get $.Content "cta_variant")) }}
|
||||||
|
{{ end }}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Admin configuration (`admin/tpl/`)
|
||||||
|
|
||||||
|
One JSON file per element type, **same base name as the template**. Without it the
|
||||||
|
element renders but cannot be edited, and it cannot be added from the admin.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"label": "Cards",
|
||||||
|
"layout": false,
|
||||||
|
"content": {
|
||||||
|
"items": {
|
||||||
|
"label": "Cards",
|
||||||
|
"tpl_filter": ["card"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"copy": {
|
||||||
|
"headline": { "label": "Headline" }
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"background": {
|
||||||
|
"label": "Background",
|
||||||
|
"type": "select",
|
||||||
|
"options": {
|
||||||
|
"": "Default",
|
||||||
|
"light": "Light",
|
||||||
|
"dark": "Dark"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| Key | Meaning |
|
||||||
|
|---|---|
|
||||||
|
| `label` | Display name in the admin's element picker. |
|
||||||
|
| `layout` | `true` for structural elements (head, end, header, footer). Disables some actions; new elements are inserted *before* a trailing layout element. |
|
||||||
|
| `content` | Child content areas: key = area name used in the template, `label`, optional `tpl_filter` (list of template names allowed in that area; omit to allow all). |
|
||||||
|
| `copy` | Translatable fields (stored per language under `copy.<lang>`). |
|
||||||
|
| `data` | Language-independent fields (stored under `data`). |
|
||||||
|
|
||||||
|
Field `type` (for `copy` and `data`):
|
||||||
|
|
||||||
|
| Type | Editor | Template usage |
|
||||||
|
|---|---|---|
|
||||||
|
| *(omitted)* / `text` | single-line input | `{{ $x }}` |
|
||||||
|
| `html` | rich-text editor (Trix) | `{{ with $x }}{{ html . }}{{ end }}` |
|
||||||
|
| `img` | media library picker, stores a path like `/static/media/photo.jpg` | `<img src="{{ $x }}">` |
|
||||||
|
| `file` | media library picker, stores a path | `<a href="{{ $x }}">` |
|
||||||
|
| `boolean` | checkbox, stores `"on"` when checked, key removed when unchecked | `{{ if $x }}` |
|
||||||
|
| `select` | dropdown from `options` (`value: label`) | compare as string: `{{ if eq $x "dark" }}` |
|
||||||
|
| `color` | color picker, stores `#rrggbb` | `style="--accent: {{ $x }}"` |
|
||||||
|
|
||||||
|
Rules derived from how the admin saves (important):
|
||||||
|
|
||||||
|
* **When an editor saves an element, its `copy` and `data` are replaced by exactly
|
||||||
|
the configured fields.** Any key the template reads but the admin config does not
|
||||||
|
declare is deleted on the first save. ⇒ Declare *every* `copy`/`data` key the
|
||||||
|
template uses. Don't store arrays/objects in `data` — they cannot be edited and
|
||||||
|
are lost. Model repeatable things (cards, slides, nav items, FAQ entries, team
|
||||||
|
members) as **child elements** in a content area instead.
|
||||||
|
* All saved values are **strings**. Write data values as strings in JSON too
|
||||||
|
(`"columns": "3"`, not `3`), otherwise `select` comparisons fail. Use
|
||||||
|
`{{ int (get .Content "columns") }}` when you need a number.
|
||||||
|
* Copy is edited for the languages present in the page's `path`.
|
||||||
|
* Use `copy` for anything a translator would change (text, alt text, link URLs that
|
||||||
|
differ by language, button labels); use `data` for design choices (variant, color,
|
||||||
|
image, alignment, size).
|
||||||
|
* Choose `select` over free text for design options and keep option keys stable —
|
||||||
|
they are referenced by CSS modifier classes.
|
||||||
|
* Prefixing a `label` with `_` (e.g. `"_HTML Head"`) sorts it first in the picker;
|
||||||
|
the demo uses this for layout elements.
|
||||||
|
|
||||||
|
Layout configs:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "label": "_HTML Head", "layout": true, "copy": { "title": { "label": "Title" }, "meta_description": { "label": "Meta Description" } } }
|
||||||
|
```
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "label": "_HTML End", "layout": true }
|
||||||
|
```
|
||||||
|
|
||||||
|
Admin config changes are picked up automatically for files directly inside
|
||||||
|
`admin/tpl/`; restart Shifu after adding files in its subdirectories.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Content (`content/`)
|
||||||
|
|
||||||
|
### 6.1 Pages — `content/pages/<name>.json`
|
||||||
|
|
||||||
|
A file with `path` and **no top-level `tpl`** is a page.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"display_name": "Home",
|
||||||
|
"path": {
|
||||||
|
"en": "/",
|
||||||
|
"de": "/de"
|
||||||
|
},
|
||||||
|
"sitemap": { "priority": "1.0" },
|
||||||
|
"content": {
|
||||||
|
"content": [
|
||||||
|
{
|
||||||
|
"ref": "head",
|
||||||
|
"copy": {
|
||||||
|
"en": { "title": "Acme — Home", "meta_description": "Acme builds things." },
|
||||||
|
"de": { "title": "Acme — Start", "meta_description": "Acme baut Dinge." }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ "ref": "header" },
|
||||||
|
{
|
||||||
|
"tpl": "hero",
|
||||||
|
"copy": {
|
||||||
|
"en": { "headline": "We build things", "text": "<div>Fast and reliable.</div>" },
|
||||||
|
"de": { "headline": "Wir bauen Dinge", "text": "<div>Schnell und zuverlässig.</div>" }
|
||||||
|
},
|
||||||
|
"data": { "image": "/static/media/hero.jpg", "align": "center" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tpl": "cards",
|
||||||
|
"copy": { "en": { "headline": "Services" }, "de": { "headline": "Leistungen" } },
|
||||||
|
"content": {
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"tpl": "card",
|
||||||
|
"copy": {
|
||||||
|
"en": { "title": "Design", "text": "<div>…</div>" },
|
||||||
|
"de": { "title": "Design", "text": "<div>…</div>" }
|
||||||
|
},
|
||||||
|
"content": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ "ref": "footer" },
|
||||||
|
{ "ref": "end" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Rules:
|
||||||
|
|
||||||
|
* The page root must use a **single** content area named `content`
|
||||||
|
(`"content": { "content": [ … ] }`). Elements are rendered in array order.
|
||||||
|
* Each element has either `tpl` (template name, lowercase, no extension) **or**
|
||||||
|
`ref` (reference name), plus optional `copy`, `data`, `content`, `display_name`.
|
||||||
|
* Every content area declared in an element's admin config should exist in the JSON
|
||||||
|
(use `[]` when empty), e.g. `"content": { "items": [] }`.
|
||||||
|
* `path` keys are language codes; the value is the exact route (no trailing slash,
|
||||||
|
must start with `/`). Every language in `path` should have `copy` for every
|
||||||
|
element; missing languages fall back to `en`.
|
||||||
|
* Dynamic routes: always give the variable a regular expression, e.g.
|
||||||
|
`"/blog/{slug:[a-z0-9-]+}"` or `"/p/{id:[0-9]+}"` (a bare `{slug}` does not match
|
||||||
|
in the current version). Each `{…}` matches exactly one path segment; read it with
|
||||||
|
`{{ index .Args "slug" }}`. Longer paths are matched first.
|
||||||
|
* 404: create a page whose path matches `content.not_found` in `config.json`
|
||||||
|
(default `/404`).
|
||||||
|
* Optional page keys: `disable_cache`, `header` (HTTP headers map), `handler` (Go
|
||||||
|
custom handler, only if the backend defines it), `analytics` (Pirsch tags / A/B
|
||||||
|
experiments — see the Shifu README).
|
||||||
|
* Rich-text (`html`) values are HTML strings. The Trix editor produces `<div>`,
|
||||||
|
`<br>`, `<strong>`, `<em>`, `<a>`, `<ul>/<ol>/<li>`, `<h1>`, `<blockquote>`,
|
||||||
|
`<pre>`. Stick to these tags so content stays editable.
|
||||||
|
* Image paths should point to `static/media/…` (the admin media library), e.g.
|
||||||
|
`/static/media/hero.jpg`, and the file must exist there.
|
||||||
|
* Media files go in `static/media/` only; don't put site assets (logos used by
|
||||||
|
templates, icons, fonts) there — use `static/img/`, `static/fonts/` instead.
|
||||||
|
|
||||||
|
### 6.2 References — `content/refs/<name>.json`
|
||||||
|
|
||||||
|
A content file with a **top-level `tpl`** is a reference (a standalone element).
|
||||||
|
Its name is the lowercase file name without `.json`.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"tpl": "head",
|
||||||
|
"copy": {
|
||||||
|
"en": { "title": "Acme", "meta_description": "Acme builds things." },
|
||||||
|
"de": { "title": "Acme", "meta_description": "Acme baut Dinge." }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"tpl": "header",
|
||||||
|
"data": { "logo": "/static/media/logo.svg" },
|
||||||
|
"copy": { "en": { "home_label": "Acme" }, "de": { "home_label": "Acme" } },
|
||||||
|
"content": {
|
||||||
|
"nav": [
|
||||||
|
{ "tpl": "nav_item", "copy": { "en": { "label": "About", "href": "/about" }, "de": { "label": "Über uns", "href": "/de/ueber-uns" } }, "content": {} }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
* Use refs for anything shared across pages: `head`, `header`, `footer`, `end`,
|
||||||
|
newsletter box, CTA banners.
|
||||||
|
* Pages use them with `{ "ref": "<name>" }`. Non-empty `copy`/`data` on the page
|
||||||
|
element override the ref's values for that page only (typical: page title).
|
||||||
|
* Ref names must be unique across **all** files in `content/` — never give a page
|
||||||
|
file the same name as a ref (e.g. no `content/pages/header.json`).
|
||||||
|
* The admin's "add reference" picker lists refs from `shifu.db`, not from disk. Refs
|
||||||
|
created by hand still render and are editable where used, but to make them
|
||||||
|
insertable from the admin register them (with Shifu stopped, after it has run
|
||||||
|
once so `shifu.db` exists; needs the `sqlite3` CLI):
|
||||||
|
```sh
|
||||||
|
sqlite3 shifu.db "INSERT OR IGNORE INTO reference (name) VALUES ('head'), ('header'), ('footer'), ('end');"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Styles (`assets/scss/`)
|
||||||
|
|
||||||
|
Shifu compiles the Sass entrypoint itself (`sass --style=compressed`) on start and
|
||||||
|
on every save. **Never** pre-compile, never write or edit `static/main.css` by hand,
|
||||||
|
never add PostCSS/Tailwind/Vite/webpack or npm build scripts, never inline large
|
||||||
|
`<style>` blocks in templates.
|
||||||
|
|
||||||
|
`assets/scss/main.scss`:
|
||||||
|
|
||||||
|
```scss
|
||||||
|
@use "variables";
|
||||||
|
@use "base";
|
||||||
|
@use "layout";
|
||||||
|
|
||||||
|
// one partial per element type, same name as the template
|
||||||
|
@use "head";
|
||||||
|
@use "header";
|
||||||
|
@use "footer";
|
||||||
|
@use "hero";
|
||||||
|
@use "text";
|
||||||
|
@use "cards";
|
||||||
|
@use "card";
|
||||||
|
```
|
||||||
|
|
||||||
|
`assets/scss/_variables.scss`:
|
||||||
|
|
||||||
|
```scss
|
||||||
|
$color-text: #1d1d1f;
|
||||||
|
$color-accent: #0a64d6;
|
||||||
|
$max-width: 1120px;
|
||||||
|
$radius: 12px;
|
||||||
|
$breakpoint-md: 768px;
|
||||||
|
|
||||||
|
@mixin md {
|
||||||
|
@media (min-width: $breakpoint-md) { @content; }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`assets/scss/_card.scss`:
|
||||||
|
|
||||||
|
```scss
|
||||||
|
@use "variables" as *;
|
||||||
|
|
||||||
|
.card {
|
||||||
|
border-radius: $radius;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&__image { display: block; width: 100%; height: auto; }
|
||||||
|
&__title { margin: 16px 0 8px; }
|
||||||
|
&__link { color: $color-accent; }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Conventions:
|
||||||
|
|
||||||
|
* Use the module system (`@use`/`@forward`), not deprecated `@import`.
|
||||||
|
* Scope styles to the element's root class (BEM: `.card`, `.card__title`,
|
||||||
|
`.card--dark`). Modifier names come from `select` option keys.
|
||||||
|
* Style rich-text output by element (`.text__body p, .text__body ul …`) since editors
|
||||||
|
can't add classes.
|
||||||
|
* Expose admin `color` fields as CSS custom properties
|
||||||
|
(`style="--accent: {{ $color }}"` + `color: var(--accent, #{$color-accent})`).
|
||||||
|
* Keep partials flat inside the Sass dir: Shifu only watches that directory itself
|
||||||
|
(not subfolders) for changes. Every subfolder is also a Sass load path, so names
|
||||||
|
must be unique.
|
||||||
|
* Fonts/images referenced from CSS go in `static/` and use absolute URLs
|
||||||
|
(`url("/static/fonts/inter.woff2")`).
|
||||||
|
* Requires the Dart Sass CLI (`sass`) on the machine running Shifu.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. JavaScript (`assets/js/`)
|
||||||
|
|
||||||
|
Shifu bundles and minifies the JS entrypoint with esbuild on start and on save (ES
|
||||||
|
modules, TypeScript `.ts` also works). **Never** pre-bundle, never edit
|
||||||
|
`static/main.js`, never add a separate bundler. `import` between files in
|
||||||
|
`assets/js/` is fine. Avoid npm dependencies unless the user asks; if one is needed,
|
||||||
|
prefer copying a small ES-module library into `assets/js/` (e.g. `vendor_glide.js`).
|
||||||
|
Keep JS files flat in that directory: like Sass, only the directory itself is
|
||||||
|
watched for changes, not its subfolders.
|
||||||
|
|
||||||
|
Pattern: progressive enhancement, components bound by `data-component`, idempotent
|
||||||
|
initialisation that also handles elements the admin inserts or re-renders on the fly.
|
||||||
|
|
||||||
|
`assets/js/main.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { initNav } from "./nav.js";
|
||||||
|
import { initSlider } from "./slider.js";
|
||||||
|
|
||||||
|
const components = {
|
||||||
|
nav: initNav,
|
||||||
|
slider: initSlider,
|
||||||
|
};
|
||||||
|
|
||||||
|
function init(root = document) {
|
||||||
|
root.querySelectorAll("[data-component]").forEach((el) => {
|
||||||
|
if (el.dataset.componentReady) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn = components[el.dataset.component];
|
||||||
|
|
||||||
|
if (fn) {
|
||||||
|
fn(el);
|
||||||
|
el.dataset.componentReady = "true";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
init();
|
||||||
|
// the admin UI swaps element HTML in place after edits
|
||||||
|
new MutationObserver(() => init()).observe(document.body, { childList: true, subtree: true });
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
`assets/js/nav.js`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export function initNav(el) {
|
||||||
|
const toggle = el.querySelector(".header__toggle");
|
||||||
|
|
||||||
|
if (!toggle) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
toggle.addEventListener("click", () => {
|
||||||
|
const open = el.classList.toggle("header--open");
|
||||||
|
toggle.setAttribute("aria-expanded", String(open));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Template side: `<header class="header" data-component="nav" data-shifu-element="{{ .Content.Position }}">`.
|
||||||
|
|
||||||
|
Rules:
|
||||||
|
|
||||||
|
* The site must be usable without JS; JS enhances.
|
||||||
|
* No inline `<script>` in element templates; no `onclick=` attributes.
|
||||||
|
* Pass configuration via `data-*` attributes rendered from `copy`/`data`.
|
||||||
|
* Don't rely on the DOM being static — the admin replaces element markup when
|
||||||
|
editors save. Never store state outside the element or bind listeners in a way
|
||||||
|
that breaks if an element is replaced.
|
||||||
|
* Load the bundle once, in `head.html`, with `defer`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. Workflows
|
||||||
|
|
||||||
|
### 9.1 Create a whole new site
|
||||||
|
|
||||||
|
1. Write `config.json`, `.secrets.env`, `.gitignore`
|
||||||
|
(`.secrets.env`, `shifu.db`, `static/main.css*`, `static/main.js*`).
|
||||||
|
2. Plan the element inventory from the design: layout parts (head, header, footer,
|
||||||
|
end), sections (hero, text, image, cards, columns, cta, faq, contact, …),
|
||||||
|
components (card, nav_item, faq_item, button…). Prefer a small set of flexible
|
||||||
|
sections with `select` options over many near-duplicates.
|
||||||
|
3. For each element type create: template, admin config, Sass partial (+ `@use` in
|
||||||
|
`main.scss`), and JS module (+ register in `main.js`) when interactive.
|
||||||
|
4. Create refs: `content/refs/head.json`, `header.json`, `footer.json`, `end.json`.
|
||||||
|
5. Create pages in `content/pages/`, each starting with `head` and ending with `end`,
|
||||||
|
with `copy` for every language in its `path`. Include a 404 page.
|
||||||
|
6. Put referenced images in `static/media/`.
|
||||||
|
7. Run `shifu run .`, open every page, check the log for errors.
|
||||||
|
|
||||||
|
### 9.2 Edit an existing site
|
||||||
|
|
||||||
|
1. Read `config.json`, list `tpl/`, `admin/tpl/`, `content/` and the Sass/JS
|
||||||
|
entrypoints first to learn the existing element inventory and conventions.
|
||||||
|
2. Reuse existing element types before creating new ones.
|
||||||
|
3. Edit content JSON surgically; keep keys you don't touch (`display_name`,
|
||||||
|
`analytics`, `header`, …). The admin writes compact single-line JSON — that's fine,
|
||||||
|
keep it valid; reformatting is allowed but not required.
|
||||||
|
4. Renaming a `copy`/`data` key or content area → update the template, the admin
|
||||||
|
config **and every page/ref JSON** that uses it (search all of `content/`).
|
||||||
|
5. Removing an element type → first remove all its uses from `content/`.
|
||||||
|
6. Adding a field → add it to template *and* admin config; existing content may lack
|
||||||
|
it, so templates must handle the missing value.
|
||||||
|
|
||||||
|
### 9.3 Add a new page
|
||||||
|
|
||||||
|
Create `content/pages/<slug>.json` (unique file name, not equal to any ref name),
|
||||||
|
copy the head/header/footer/end refs from an existing page, set `path` for all site
|
||||||
|
languages, override the head `title`/`meta_description`, and add nav entries in the
|
||||||
|
header ref if the page should be linked.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. Verification checklist
|
||||||
|
|
||||||
|
Before finishing, confirm:
|
||||||
|
|
||||||
|
- [ ] Every element type has `tpl/**/<name>.html` and `admin/tpl/**/<name>.json` with the same unique base name (partials excepted).
|
||||||
|
- [ ] Every element template has one root element with `data-shifu-element="{{ .Content.Position }}"`.
|
||||||
|
- [ ] Every content area appears identically in the template (`fmt "%s.<area>"`, `index … "<area>"`, `<slot name=".../<area>">`), the admin config `content`, and the JSON.
|
||||||
|
- [ ] Every `copy`/`data` key read in a template is declared in the admin config with the right `type`.
|
||||||
|
- [ ] No arrays/objects in `data`; all `copy`/`data` values are strings.
|
||||||
|
- [ ] `html` values are wrapped in `{{ with }}`; no `<nil>` can appear.
|
||||||
|
- [ ] `head.html` contains `{{ adminHead .Page }}`, `end.html` contains `{{ adminBody .Page }}`, and the CSS/JS URLs match `sass.out`/`js.out`.
|
||||||
|
- [ ] Pages: root area named `content`, start with `head`, end with `end`, `copy` for all languages in `path`, paths unique and starting with `/`.
|
||||||
|
- [ ] Refs live in `content/refs/`, names don't collide with any other file name in `content/`.
|
||||||
|
- [ ] No hand-written files in `static/` for CSS/JS output; no extra build tooling.
|
||||||
|
- [ ] Every Sass partial is `@use`d by the entrypoint; every JS module is imported by the entrypoint.
|
||||||
|
- [ ] JSON files are valid (e.g. `python3 -m json.tool file.json`).
|
||||||
|
- [ ] `shifu run .` starts without "Error compiling sass", "Error compiling js", "Error rendering template" or "Error parsing website content file" in the log; no page shows `Reference "…" not found!` or `<nil>`.
|
||||||
|
- [ ] Logged in at `/admin`, each element can be selected, edited, and new children can be added to every content area.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{ "label": "_HTML End", "layout": true }
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"label": "_Footer",
|
||||||
|
"layout": true,
|
||||||
|
"copy": {
|
||||||
|
"headline": { "label": "Überschrift" },
|
||||||
|
"text": { "label": "Text" },
|
||||||
|
"copyright": { "label": "Copyright" }
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"email": { "label": "E-Mail" },
|
||||||
|
"phone": { "label": "Telefon" },
|
||||||
|
"instagram": { "label": "Instagram URL" },
|
||||||
|
"vimeo": { "label": "Vimeo URL" }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"label": "_HTML Head",
|
||||||
|
"layout": true,
|
||||||
|
"copy": {
|
||||||
|
"title": { "label": "Title" },
|
||||||
|
"meta_description": { "label": "Meta Description" }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"label": "Instagram",
|
||||||
|
"copy": {
|
||||||
|
"headline": { "label": "Überschrift" }
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"widget": { "label": "LightWidget URL" },
|
||||||
|
"profile": { "label": "Profil URL" }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"label": "Intro (Hero-Video)",
|
||||||
|
"copy": {
|
||||||
|
"kicker": { "label": "Dachzeile" },
|
||||||
|
"headline": { "label": "Überschrift" },
|
||||||
|
"cta_label": { "label": "Button-Text" },
|
||||||
|
"cta_href": { "label": "Button-Link" },
|
||||||
|
"ticker": { "label": "Laufband-Text" }
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"video": { "label": "Video", "type": "file" },
|
||||||
|
"poster": { "label": "Vorschaubild", "type": "img" }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{ "label": "Impressum & Datenschutz" }
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"label": "_Navigation",
|
||||||
|
"layout": true,
|
||||||
|
"copy": {
|
||||||
|
"service_label": { "label": "Link: Gewerke" },
|
||||||
|
"work_label": { "label": "Link: Referenzen" },
|
||||||
|
"contact_label": { "label": "Link: Kontakt" }
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"full": { "label": "Volle Navigation anzeigen", "type": "boolean" }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"label": "Gewerke",
|
||||||
|
"content": {
|
||||||
|
"items": { "label": "Gewerke", "tpl_filter": ["service_item"] }
|
||||||
|
},
|
||||||
|
"copy": {
|
||||||
|
"headline": { "label": "Überschrift" },
|
||||||
|
"text": { "label": "Text", "type": "html" },
|
||||||
|
"image_caption": { "label": "Bildunterschrift" }
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"image": { "label": "Bild", "type": "img" }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"label": "Gewerk (Klappe)",
|
||||||
|
"copy": {
|
||||||
|
"title": { "label": "Titel" },
|
||||||
|
"text": { "label": "Text" }
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"color": {
|
||||||
|
"label": "Farbe",
|
||||||
|
"type": "select",
|
||||||
|
"options": {
|
||||||
|
"red": "Rot",
|
||||||
|
"orange": "Orange",
|
||||||
|
"yellow": "Gelb",
|
||||||
|
"pink": "Pink",
|
||||||
|
"purple": "Lila"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{ "label": "AGB" }
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"label": "Referenzen",
|
||||||
|
"content": {
|
||||||
|
"content": { "label": "Referenzen", "tpl_filter": ["work_entry"] }
|
||||||
|
},
|
||||||
|
"copy": {
|
||||||
|
"headline": { "label": "Überschrift" },
|
||||||
|
"text": { "label": "Text", "type": "html" }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"label": "Referenz (Video)",
|
||||||
|
"copy": {
|
||||||
|
"h2": { "label": "Titel" },
|
||||||
|
"text": { "label": "Text" }
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"video": { "label": "Embed-URL (YouTube/Vimeo)" }
|
||||||
|
}
|
||||||
|
}
|
||||||
+38
-1
@@ -1 +1,38 @@
|
|||||||
console.log("Hi!");
|
import { initNav } from "./nav.js";
|
||||||
|
import { initReveal } from "./reveal.js";
|
||||||
|
import { initTimecode } from "./timecode.js";
|
||||||
|
|
||||||
|
document.documentElement.classList.add("js");
|
||||||
|
|
||||||
|
const components = {
|
||||||
|
nav: initNav,
|
||||||
|
reveal: initReveal,
|
||||||
|
timecode: initTimecode,
|
||||||
|
};
|
||||||
|
|
||||||
|
function init(root = document) {
|
||||||
|
root.querySelectorAll("[data-component]").forEach((el) => {
|
||||||
|
if (el.dataset.componentReady) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn = components[el.dataset.component];
|
||||||
|
|
||||||
|
if (fn) {
|
||||||
|
fn(el);
|
||||||
|
el.dataset.componentReady = "true";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.readyState === "loading") {
|
||||||
|
document.addEventListener("DOMContentLoaded", start);
|
||||||
|
} else {
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
|
||||||
|
function start() {
|
||||||
|
init();
|
||||||
|
// the admin UI swaps element HTML in place after edits
|
||||||
|
new MutationObserver(() => init()).observe(document.body, { childList: true, subtree: true });
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
export function initNav(el) {
|
||||||
|
const toggle = el.querySelector(".nav__toggle");
|
||||||
|
|
||||||
|
if (!toggle) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const setOpen = (open) => {
|
||||||
|
el.classList.toggle("nav--open", open);
|
||||||
|
toggle.setAttribute("aria-expanded", String(open));
|
||||||
|
};
|
||||||
|
|
||||||
|
toggle.addEventListener("click", () => setOpen(!el.classList.contains("nav--open")));
|
||||||
|
el.querySelectorAll(".nav__link").forEach((link) => link.addEventListener("click", () => setOpen(false)));
|
||||||
|
el.addEventListener("keydown", (e) => {
|
||||||
|
if (e.key === "Escape") {
|
||||||
|
setOpen(false);
|
||||||
|
toggle.focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
let observer = null;
|
||||||
|
|
||||||
|
function getObserver() {
|
||||||
|
if (!observer) {
|
||||||
|
observer = new IntersectionObserver((entries) => {
|
||||||
|
entries.forEach((entry) => {
|
||||||
|
if (entry.isIntersecting) {
|
||||||
|
entry.target.classList.add("is-visible");
|
||||||
|
observer.unobserve(entry.target);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, { rootMargin: "0px 0px -8% 0px", threshold: 0.05 });
|
||||||
|
}
|
||||||
|
|
||||||
|
return observer;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function initReveal(el) {
|
||||||
|
if (!("IntersectionObserver" in window)) {
|
||||||
|
el.classList.add("is-visible");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
getObserver().observe(el);
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
const FPS = 25;
|
||||||
|
|
||||||
|
function pad(n) {
|
||||||
|
return String(n).padStart(2, "0");
|
||||||
|
}
|
||||||
|
|
||||||
|
export function initTimecode(el) {
|
||||||
|
const start = performance.now();
|
||||||
|
|
||||||
|
const tick = (now) => {
|
||||||
|
if (!el.isConnected) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const frames = Math.floor(((now - start) / 1000) * FPS);
|
||||||
|
const f = frames % FPS;
|
||||||
|
const s = Math.floor(frames / FPS) % 60;
|
||||||
|
const m = Math.floor(frames / (FPS * 60)) % 60;
|
||||||
|
const h = Math.floor(frames / (FPS * 3600));
|
||||||
|
el.textContent = `${pad(h)}:${pad(m)}:${pad(s)}:${pad(f)}`;
|
||||||
|
requestAnimationFrame(tick);
|
||||||
|
};
|
||||||
|
|
||||||
|
requestAnimationFrame(tick);
|
||||||
|
}
|
||||||
@@ -0,0 +1,204 @@
|
|||||||
|
@use "variables" as *;
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--beige: #{$beige};
|
||||||
|
--yellow: #{$yellow};
|
||||||
|
--orange: #{$orange};
|
||||||
|
--red: #{$red};
|
||||||
|
--pink: #{$pink};
|
||||||
|
--purple: #{$purple};
|
||||||
|
--ink: #{$ink};
|
||||||
|
}
|
||||||
|
|
||||||
|
*,
|
||||||
|
*::before,
|
||||||
|
*::after {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
scroll-padding-top: 88px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
min-height: 100vh;
|
||||||
|
color: $ink;
|
||||||
|
background: $beige;
|
||||||
|
font-family: "Manrope", -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 1.6;
|
||||||
|
font-weight: 500;
|
||||||
|
overflow-x: hidden;
|
||||||
|
|
||||||
|
// film grain
|
||||||
|
&::after {
|
||||||
|
content: "";
|
||||||
|
position: fixed;
|
||||||
|
inset: -50%;
|
||||||
|
z-index: 9999;
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0.07;
|
||||||
|
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
|
||||||
|
animation: grain 0.8s steps(4) infinite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes grain {
|
||||||
|
0% { transform: translate(0, 0); }
|
||||||
|
25% { transform: translate(-3%, 2%); }
|
||||||
|
50% { transform: translate(2%, -3%); }
|
||||||
|
75% { transform: translate(-2%, -1%); }
|
||||||
|
100% { transform: translate(1%, 3%); }
|
||||||
|
}
|
||||||
|
|
||||||
|
img,
|
||||||
|
video,
|
||||||
|
iframe {
|
||||||
|
display: block;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
strong, b { font-weight: 700; }
|
||||||
|
em, i { font-style: italic; }
|
||||||
|
|
||||||
|
::selection {
|
||||||
|
background: $yellow;
|
||||||
|
color: $ink;
|
||||||
|
}
|
||||||
|
|
||||||
|
:focus-visible {
|
||||||
|
outline: 3px solid $orange;
|
||||||
|
outline-offset: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.visually-hidden {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
overflow: hidden;
|
||||||
|
clip: rect(0 0 0 0);
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// shared section title: "01 Gewerke"
|
||||||
|
.section-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 16px;
|
||||||
|
font-size: clamp(40px, 7vw, 88px);
|
||||||
|
line-height: 1;
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing: -0.03em;
|
||||||
|
|
||||||
|
&__nr {
|
||||||
|
flex: none;
|
||||||
|
margin-top: 0.35em;
|
||||||
|
padding: 4px 10px;
|
||||||
|
border: 2px solid currentColor;
|
||||||
|
border-radius: 999px;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
font-variant-numeric: tabular-nums;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--light {
|
||||||
|
color: $beige;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// buttons
|
||||||
|
.button {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
padding: 16px 28px 16px 18px;
|
||||||
|
border: 3px solid $ink;
|
||||||
|
border-radius: 999px;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 700;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: 4px 4px 0 $ink;
|
||||||
|
transition: transform 0.25s $ease, box-shadow 0.25s $ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: translate(-2px, -2px) rotate(-1.5deg);
|
||||||
|
box-shadow: 7px 7px 0 $ink;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: translate(3px, 3px);
|
||||||
|
box-shadow: 0 0 0 $ink;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--yellow {
|
||||||
|
background: $yellow;
|
||||||
|
color: $ink;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--outline {
|
||||||
|
background: transparent;
|
||||||
|
padding: 12px 22px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__play {
|
||||||
|
position: relative;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
flex: none;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: $ink;
|
||||||
|
transition: transform 0.4s $ease;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 55%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 6px 0 6px 10px;
|
||||||
|
border-color: transparent transparent transparent $yellow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover &__play {
|
||||||
|
transform: rotate(360deg) scale(1.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// scroll reveal (only hidden once JS is running)
|
||||||
|
.js [data-component~="reveal"] {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(40px) rotate(1deg);
|
||||||
|
transition: opacity 0.8s $ease-out, transform 0.9s $ease-out;
|
||||||
|
|
||||||
|
&.is-visible {
|
||||||
|
opacity: 1;
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
*,
|
||||||
|
*::before,
|
||||||
|
*::after {
|
||||||
|
animation-duration: 0.01ms !important;
|
||||||
|
animation-iteration-count: 1 !important;
|
||||||
|
transition-duration: 0.01ms !important;
|
||||||
|
scroll-behavior: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.js [data-component~="reveal"] {
|
||||||
|
opacity: 1;
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
@use "variables" as *;
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 120px 0 32px;
|
||||||
|
background: $red;
|
||||||
|
color: $cream;
|
||||||
|
border-top: 3px solid $ink;
|
||||||
|
|
||||||
|
@include md {
|
||||||
|
padding-top: 160px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// big rotating "film reel" decoration
|
||||||
|
&::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
right: -160px;
|
||||||
|
top: -160px;
|
||||||
|
width: 480px;
|
||||||
|
height: 480px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background:
|
||||||
|
radial-gradient(circle at 50% 50%, $red 0 34px, transparent 35px),
|
||||||
|
radial-gradient(circle at 50% 22%, $red 0 46px, transparent 47px),
|
||||||
|
radial-gradient(circle at 50% 78%, $red 0 46px, transparent 47px),
|
||||||
|
radial-gradient(circle at 22% 50%, $red 0 46px, transparent 47px),
|
||||||
|
radial-gradient(circle at 78% 50%, $red 0 46px, transparent 47px),
|
||||||
|
$ink;
|
||||||
|
opacity: 0.25;
|
||||||
|
animation: reel 18s linear infinite;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__inner {
|
||||||
|
@include inner;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__headline {
|
||||||
|
font-size: clamp(56px, 12vw, 180px);
|
||||||
|
line-height: 0.9;
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
color: $cream;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
max-width: 32ch;
|
||||||
|
margin-top: 24px;
|
||||||
|
font-size: clamp(20px, 2.4vw, 28px);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__mail {
|
||||||
|
margin-top: 40px;
|
||||||
|
font-size: clamp(16px, 2vw, 22px);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__bottom {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 16px;
|
||||||
|
margin-top: 96px;
|
||||||
|
padding-top: 24px;
|
||||||
|
border-top: 2px solid rgba($cream, 0.35);
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__legal {
|
||||||
|
display: flex;
|
||||||
|
gap: 24px;
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: underline wavy;
|
||||||
|
text-underline-offset: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// end-credits style contact list
|
||||||
|
.credits {
|
||||||
|
display: grid;
|
||||||
|
gap: 4px;
|
||||||
|
max-width: 640px;
|
||||||
|
margin: 96px 0 0;
|
||||||
|
|
||||||
|
&__row {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
gap: 12px;
|
||||||
|
font-size: clamp(18px, 2vw, 22px);
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: "";
|
||||||
|
order: 1;
|
||||||
|
flex: 1;
|
||||||
|
border-bottom: 2px dotted rgba($cream, 0.5);
|
||||||
|
transform: translateY(-5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
dt {
|
||||||
|
order: 0;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.14em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
dd {
|
||||||
|
order: 2;
|
||||||
|
margin: 0;
|
||||||
|
font-weight: 700;
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
background: linear-gradient($yellow, $yellow) 0 100% / 0 3px no-repeat;
|
||||||
|
transition: background-size 0.3s $ease-out;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-size: 100% 3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes reel {
|
||||||
|
to { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
@@ -1,966 +0,0 @@
|
|||||||
.container {
|
|
||||||
max-width: 1600px;
|
|
||||||
width: 100%;
|
|
||||||
margin-right: auto;
|
|
||||||
margin-left: auto;
|
|
||||||
position: relative;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.row {
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: -webkit-box;
|
|
||||||
display: -ms-flexbox;
|
|
||||||
display: flex;
|
|
||||||
-webkit-box-flex: 0;
|
|
||||||
-ms-flex: 0 1 auto;
|
|
||||||
flex: 0 1 auto;
|
|
||||||
-webkit-box-orient: horizontal;
|
|
||||||
-webkit-box-direction: normal;
|
|
||||||
-ms-flex-direction: row;
|
|
||||||
flex-direction: row;
|
|
||||||
-ms-flex-wrap: wrap;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.row.reverse {
|
|
||||||
-webkit-box-orient: horizontal;
|
|
||||||
-webkit-box-direction: reverse;
|
|
||||||
-ms-flex-direction: row-reverse;
|
|
||||||
flex-direction: row-reverse;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col.reverse {
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
-webkit-box-direction: reverse;
|
|
||||||
-ms-flex-direction: column-reverse;
|
|
||||||
flex-direction: column-reverse;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-xs,
|
|
||||||
.col-xs-1,
|
|
||||||
.col-xs-2,
|
|
||||||
.col-xs-3,
|
|
||||||
.col-xs-4,
|
|
||||||
.col-xs-5,
|
|
||||||
.col-xs-6,
|
|
||||||
.col-xs-7,
|
|
||||||
.col-xs-8,
|
|
||||||
.col-xs-9,
|
|
||||||
.col-xs-10,
|
|
||||||
.col-xs-11,
|
|
||||||
.col-xs-12,
|
|
||||||
.col-xs-offset-0,
|
|
||||||
.col-xs-offset-1,
|
|
||||||
.col-xs-offset-2,
|
|
||||||
.col-xs-offset-3,
|
|
||||||
.col-xs-offset-4,
|
|
||||||
.col-xs-offset-5,
|
|
||||||
.col-xs-offset-6,
|
|
||||||
.col-xs-offset-7,
|
|
||||||
.col-xs-offset-8,
|
|
||||||
.col-xs-offset-9,
|
|
||||||
.col-xs-offset-10,
|
|
||||||
.col-xs-offset-11,
|
|
||||||
.col-xs-offset-12 {
|
|
||||||
box-sizing: border-box;
|
|
||||||
-webkit-box-flex: 0;
|
|
||||||
-ms-flex: 0 0 auto;
|
|
||||||
flex: 0 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-xs {
|
|
||||||
-webkit-box-flex: 1;
|
|
||||||
-ms-flex-positive: 1;
|
|
||||||
flex-grow: 1;
|
|
||||||
-ms-flex-preferred-size: 0;
|
|
||||||
flex-basis: 0;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-xs-1 {
|
|
||||||
-ms-flex-preferred-size: 8.33333333%;
|
|
||||||
flex-basis: 8.33333333%;
|
|
||||||
max-width: 8.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-xs-2 {
|
|
||||||
-ms-flex-preferred-size: 16.66666667%;
|
|
||||||
flex-basis: 16.66666667%;
|
|
||||||
max-width: 16.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-xs-3 {
|
|
||||||
-ms-flex-preferred-size: 25%;
|
|
||||||
flex-basis: 25%;
|
|
||||||
max-width: 25%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-xs-4 {
|
|
||||||
-ms-flex-preferred-size: 33.33333333%;
|
|
||||||
flex-basis: 33.33333333%;
|
|
||||||
max-width: 33.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-xs-5 {
|
|
||||||
-ms-flex-preferred-size: 41.66666667%;
|
|
||||||
flex-basis: 41.66666667%;
|
|
||||||
max-width: 41.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-xs-6 {
|
|
||||||
-ms-flex-preferred-size: 50%;
|
|
||||||
flex-basis: 50%;
|
|
||||||
max-width: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-xs-7 {
|
|
||||||
-ms-flex-preferred-size: 58.33333333%;
|
|
||||||
flex-basis: 58.33333333%;
|
|
||||||
max-width: 58.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-xs-8 {
|
|
||||||
-ms-flex-preferred-size: 66.66666667%;
|
|
||||||
flex-basis: 66.66666667%;
|
|
||||||
max-width: 66.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-xs-9 {
|
|
||||||
-ms-flex-preferred-size: 75%;
|
|
||||||
flex-basis: 75%;
|
|
||||||
max-width: 75%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-xs-10 {
|
|
||||||
-ms-flex-preferred-size: 83.33333333%;
|
|
||||||
flex-basis: 83.33333333%;
|
|
||||||
max-width: 83.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-xs-11 {
|
|
||||||
-ms-flex-preferred-size: 91.66666667%;
|
|
||||||
flex-basis: 91.66666667%;
|
|
||||||
max-width: 91.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-xs-12 {
|
|
||||||
-ms-flex-preferred-size: 100%;
|
|
||||||
flex-basis: 100%;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-xs-offset-0 {
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-xs-offset-1 {
|
|
||||||
margin-left: 8.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-xs-offset-2 {
|
|
||||||
margin-left: 16.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-xs-offset-3 {
|
|
||||||
margin-left: 25%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-xs-offset-4 {
|
|
||||||
margin-left: 33.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-xs-offset-5 {
|
|
||||||
margin-left: 41.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-xs-offset-6 {
|
|
||||||
margin-left: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-xs-offset-7 {
|
|
||||||
margin-left: 58.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-xs-offset-8 {
|
|
||||||
margin-left: 66.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-xs-offset-9 {
|
|
||||||
margin-left: 75%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-xs-offset-10 {
|
|
||||||
margin-left: 83.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-xs-offset-11 {
|
|
||||||
margin-left: 91.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.start-xs {
|
|
||||||
-webkit-box-pack: start;
|
|
||||||
-ms-flex-pack: start;
|
|
||||||
justify-content: flex-start;
|
|
||||||
text-align: start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.center-xs {
|
|
||||||
-webkit-box-pack: center;
|
|
||||||
-ms-flex-pack: center;
|
|
||||||
justify-content: center;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.end-xs {
|
|
||||||
-webkit-box-pack: end;
|
|
||||||
-ms-flex-pack: end;
|
|
||||||
justify-content: flex-end;
|
|
||||||
text-align: end;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-xs {
|
|
||||||
-webkit-box-align: start;
|
|
||||||
-ms-flex-align: start;
|
|
||||||
align-items: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.middle-xs {
|
|
||||||
-webkit-box-align: center;
|
|
||||||
-ms-flex-align: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottom-xs {
|
|
||||||
-webkit-box-align: end;
|
|
||||||
-ms-flex-align: end;
|
|
||||||
align-items: flex-end;
|
|
||||||
}
|
|
||||||
|
|
||||||
.around-xs {
|
|
||||||
-ms-flex-pack: distribute;
|
|
||||||
justify-content: space-around;
|
|
||||||
}
|
|
||||||
|
|
||||||
.between-xs {
|
|
||||||
-webkit-box-pack: justify;
|
|
||||||
-ms-flex-pack: justify;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.first-xs {
|
|
||||||
-webkit-box-ordinal-group: 0;
|
|
||||||
-ms-flex-order: -1;
|
|
||||||
order: -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.last-xs {
|
|
||||||
-webkit-box-ordinal-group: 2;
|
|
||||||
-ms-flex-order: 1;
|
|
||||||
order: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 511px) {
|
|
||||||
.hide-xs {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (min-width: 512px) {
|
|
||||||
.col-sm,
|
|
||||||
.col-sm-1,
|
|
||||||
.col-sm-2,
|
|
||||||
.col-sm-3,
|
|
||||||
.col-sm-4,
|
|
||||||
.col-sm-5,
|
|
||||||
.col-sm-6,
|
|
||||||
.col-sm-7,
|
|
||||||
.col-sm-8,
|
|
||||||
.col-sm-9,
|
|
||||||
.col-sm-10,
|
|
||||||
.col-sm-11,
|
|
||||||
.col-sm-12,
|
|
||||||
.col-sm-offset-0,
|
|
||||||
.col-sm-offset-1,
|
|
||||||
.col-sm-offset-2,
|
|
||||||
.col-sm-offset-3,
|
|
||||||
.col-sm-offset-4,
|
|
||||||
.col-sm-offset-5,
|
|
||||||
.col-sm-offset-6,
|
|
||||||
.col-sm-offset-7,
|
|
||||||
.col-sm-offset-8,
|
|
||||||
.col-sm-offset-9,
|
|
||||||
.col-sm-offset-10,
|
|
||||||
.col-sm-offset-11,
|
|
||||||
.col-sm-offset-12 {
|
|
||||||
box-sizing: border-box;
|
|
||||||
-webkit-box-flex: 0;
|
|
||||||
-ms-flex: 0 0 auto;
|
|
||||||
flex: 0 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-sm {
|
|
||||||
-webkit-box-flex: 1;
|
|
||||||
-ms-flex-positive: 1;
|
|
||||||
flex-grow: 1;
|
|
||||||
-ms-flex-preferred-size: 0;
|
|
||||||
flex-basis: 0;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-sm-1 {
|
|
||||||
-ms-flex-preferred-size: 8.33333333%;
|
|
||||||
flex-basis: 8.33333333%;
|
|
||||||
max-width: 8.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-sm-2 {
|
|
||||||
-ms-flex-preferred-size: 16.66666667%;
|
|
||||||
flex-basis: 16.66666667%;
|
|
||||||
max-width: 16.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-sm-3 {
|
|
||||||
-ms-flex-preferred-size: 25%;
|
|
||||||
flex-basis: 25%;
|
|
||||||
max-width: 25%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-sm-4 {
|
|
||||||
-ms-flex-preferred-size: 33.33333333%;
|
|
||||||
flex-basis: 33.33333333%;
|
|
||||||
max-width: 33.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-sm-5 {
|
|
||||||
-ms-flex-preferred-size: 41.66666667%;
|
|
||||||
flex-basis: 41.66666667%;
|
|
||||||
max-width: 41.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-sm-6 {
|
|
||||||
-ms-flex-preferred-size: 50%;
|
|
||||||
flex-basis: 50%;
|
|
||||||
max-width: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-sm-7 {
|
|
||||||
-ms-flex-preferred-size: 58.33333333%;
|
|
||||||
flex-basis: 58.33333333%;
|
|
||||||
max-width: 58.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-sm-8 {
|
|
||||||
-ms-flex-preferred-size: 66.66666667%;
|
|
||||||
flex-basis: 66.66666667%;
|
|
||||||
max-width: 66.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-sm-9 {
|
|
||||||
-ms-flex-preferred-size: 75%;
|
|
||||||
flex-basis: 75%;
|
|
||||||
max-width: 75%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-sm-10 {
|
|
||||||
-ms-flex-preferred-size: 83.33333333%;
|
|
||||||
flex-basis: 83.33333333%;
|
|
||||||
max-width: 83.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-sm-11 {
|
|
||||||
-ms-flex-preferred-size: 91.66666667%;
|
|
||||||
flex-basis: 91.66666667%;
|
|
||||||
max-width: 91.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-sm-12 {
|
|
||||||
-ms-flex-preferred-size: 100%;
|
|
||||||
flex-basis: 100%;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-sm-offset-0 {
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-sm-offset-1 {
|
|
||||||
margin-left: 8.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-sm-offset-2 {
|
|
||||||
margin-left: 16.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-sm-offset-3 {
|
|
||||||
margin-left: 25%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-sm-offset-4 {
|
|
||||||
margin-left: 33.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-sm-offset-5 {
|
|
||||||
margin-left: 41.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-sm-offset-6 {
|
|
||||||
margin-left: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-sm-offset-7 {
|
|
||||||
margin-left: 58.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-sm-offset-8 {
|
|
||||||
margin-left: 66.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-sm-offset-9 {
|
|
||||||
margin-left: 75%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-sm-offset-10 {
|
|
||||||
margin-left: 83.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-sm-offset-11 {
|
|
||||||
margin-left: 91.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.start-sm {
|
|
||||||
-webkit-box-pack: start;
|
|
||||||
-ms-flex-pack: start;
|
|
||||||
justify-content: flex-start;
|
|
||||||
text-align: start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.center-sm {
|
|
||||||
-webkit-box-pack: center;
|
|
||||||
-ms-flex-pack: center;
|
|
||||||
justify-content: center;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.end-sm {
|
|
||||||
-webkit-box-pack: end;
|
|
||||||
-ms-flex-pack: end;
|
|
||||||
justify-content: flex-end;
|
|
||||||
text-align: end;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-sm {
|
|
||||||
-webkit-box-align: start;
|
|
||||||
-ms-flex-align: start;
|
|
||||||
align-items: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.middle-sm {
|
|
||||||
-webkit-box-align: center;
|
|
||||||
-ms-flex-align: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottom-sm {
|
|
||||||
-webkit-box-align: end;
|
|
||||||
-ms-flex-align: end;
|
|
||||||
align-items: flex-end;
|
|
||||||
}
|
|
||||||
|
|
||||||
.around-sm {
|
|
||||||
-ms-flex-pack: distribute;
|
|
||||||
justify-content: space-around;
|
|
||||||
}
|
|
||||||
|
|
||||||
.between-sm {
|
|
||||||
-webkit-box-pack: justify;
|
|
||||||
-ms-flex-pack: justify;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.first-sm {
|
|
||||||
-webkit-box-ordinal-group: 0;
|
|
||||||
-ms-flex-order: -1;
|
|
||||||
order: -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.last-sm {
|
|
||||||
-webkit-box-ordinal-group: 2;
|
|
||||||
-ms-flex-order: 1;
|
|
||||||
order: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.show-xs {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 767px) {
|
|
||||||
.hide-sm {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (min-width: 768px) {
|
|
||||||
.col-md,
|
|
||||||
.col-md-1,
|
|
||||||
.col-md-2,
|
|
||||||
.col-md-3,
|
|
||||||
.col-md-4,
|
|
||||||
.col-md-5,
|
|
||||||
.col-md-6,
|
|
||||||
.col-md-7,
|
|
||||||
.col-md-8,
|
|
||||||
.col-md-9,
|
|
||||||
.col-md-10,
|
|
||||||
.col-md-11,
|
|
||||||
.col-md-12,
|
|
||||||
.col-md-offset-0,
|
|
||||||
.col-md-offset-1,
|
|
||||||
.col-md-offset-2,
|
|
||||||
.col-md-offset-3,
|
|
||||||
.col-md-offset-4,
|
|
||||||
.col-md-offset-5,
|
|
||||||
.col-md-offset-6,
|
|
||||||
.col-md-offset-7,
|
|
||||||
.col-md-offset-8,
|
|
||||||
.col-md-offset-9,
|
|
||||||
.col-md-offset-10,
|
|
||||||
.col-md-offset-11,
|
|
||||||
.col-md-offset-12 {
|
|
||||||
box-sizing: border-box;
|
|
||||||
-webkit-box-flex: 0;
|
|
||||||
-ms-flex: 0 0 auto;
|
|
||||||
flex: 0 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-md {
|
|
||||||
-webkit-box-flex: 1;
|
|
||||||
-ms-flex-positive: 1;
|
|
||||||
flex-grow: 1;
|
|
||||||
-ms-flex-preferred-size: 0;
|
|
||||||
flex-basis: 0;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-md-1 {
|
|
||||||
-ms-flex-preferred-size: 8.33333333%;
|
|
||||||
flex-basis: 8.33333333%;
|
|
||||||
max-width: 8.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-md-2 {
|
|
||||||
-ms-flex-preferred-size: 16.66666667%;
|
|
||||||
flex-basis: 16.66666667%;
|
|
||||||
max-width: 16.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-md-3 {
|
|
||||||
-ms-flex-preferred-size: 25%;
|
|
||||||
flex-basis: 25%;
|
|
||||||
max-width: 25%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-md-4 {
|
|
||||||
-ms-flex-preferred-size: 33.33333333%;
|
|
||||||
flex-basis: 33.33333333%;
|
|
||||||
max-width: 33.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-md-5 {
|
|
||||||
-ms-flex-preferred-size: 41.66666667%;
|
|
||||||
flex-basis: 41.66666667%;
|
|
||||||
max-width: 41.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-md-6 {
|
|
||||||
-ms-flex-preferred-size: 50%;
|
|
||||||
flex-basis: 50%;
|
|
||||||
max-width: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-md-7 {
|
|
||||||
-ms-flex-preferred-size: 58.33333333%;
|
|
||||||
flex-basis: 58.33333333%;
|
|
||||||
max-width: 58.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-md-8 {
|
|
||||||
-ms-flex-preferred-size: 66.66666667%;
|
|
||||||
flex-basis: 66.66666667%;
|
|
||||||
max-width: 66.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-md-9 {
|
|
||||||
-ms-flex-preferred-size: 75%;
|
|
||||||
flex-basis: 75%;
|
|
||||||
max-width: 75%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-md-10 {
|
|
||||||
-ms-flex-preferred-size: 83.33333333%;
|
|
||||||
flex-basis: 83.33333333%;
|
|
||||||
max-width: 83.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-md-11 {
|
|
||||||
-ms-flex-preferred-size: 91.66666667%;
|
|
||||||
flex-basis: 91.66666667%;
|
|
||||||
max-width: 91.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-md-12 {
|
|
||||||
-ms-flex-preferred-size: 100%;
|
|
||||||
flex-basis: 100%;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-md-offset-0 {
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-md-offset-1 {
|
|
||||||
margin-left: 8.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-md-offset-2 {
|
|
||||||
margin-left: 16.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-md-offset-3 {
|
|
||||||
margin-left: 25%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-md-offset-4 {
|
|
||||||
margin-left: 33.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-md-offset-5 {
|
|
||||||
margin-left: 41.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-md-offset-6 {
|
|
||||||
margin-left: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-md-offset-7 {
|
|
||||||
margin-left: 58.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-md-offset-8 {
|
|
||||||
margin-left: 66.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-md-offset-9 {
|
|
||||||
margin-left: 75%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-md-offset-10 {
|
|
||||||
margin-left: 83.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-md-offset-11 {
|
|
||||||
margin-left: 91.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.start-md {
|
|
||||||
-webkit-box-pack: start;
|
|
||||||
-ms-flex-pack: start;
|
|
||||||
justify-content: flex-start;
|
|
||||||
text-align: start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.center-md {
|
|
||||||
-webkit-box-pack: center;
|
|
||||||
-ms-flex-pack: center;
|
|
||||||
justify-content: center;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.end-md {
|
|
||||||
-webkit-box-pack: end;
|
|
||||||
-ms-flex-pack: end;
|
|
||||||
justify-content: flex-end;
|
|
||||||
text-align: end;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-md {
|
|
||||||
-webkit-box-align: start;
|
|
||||||
-ms-flex-align: start;
|
|
||||||
align-items: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.middle-md {
|
|
||||||
-webkit-box-align: center;
|
|
||||||
-ms-flex-align: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottom-md {
|
|
||||||
-webkit-box-align: end;
|
|
||||||
-ms-flex-align: end;
|
|
||||||
align-items: flex-end;
|
|
||||||
}
|
|
||||||
|
|
||||||
.around-md {
|
|
||||||
-ms-flex-pack: distribute;
|
|
||||||
justify-content: space-around;
|
|
||||||
}
|
|
||||||
|
|
||||||
.between-md {
|
|
||||||
-webkit-box-pack: justify;
|
|
||||||
-ms-flex-pack: justify;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.first-md {
|
|
||||||
-webkit-box-ordinal-group: 0;
|
|
||||||
-ms-flex-order: -1;
|
|
||||||
order: -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.last-md {
|
|
||||||
-webkit-box-ordinal-group: 2;
|
|
||||||
-ms-flex-order: 1;
|
|
||||||
order: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.show-sm {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 1023px) {
|
|
||||||
.hide-md {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (min-width: 1024px) {
|
|
||||||
.col-lg,
|
|
||||||
.col-lg-1,
|
|
||||||
.col-lg-2,
|
|
||||||
.col-lg-3,
|
|
||||||
.col-lg-4,
|
|
||||||
.col-lg-5,
|
|
||||||
.col-lg-6,
|
|
||||||
.col-lg-7,
|
|
||||||
.col-lg-8,
|
|
||||||
.col-lg-9,
|
|
||||||
.col-lg-10,
|
|
||||||
.col-lg-11,
|
|
||||||
.col-lg-12,
|
|
||||||
.col-lg-offset-0,
|
|
||||||
.col-lg-offset-1,
|
|
||||||
.col-lg-offset-2,
|
|
||||||
.col-lg-offset-3,
|
|
||||||
.col-lg-offset-4,
|
|
||||||
.col-lg-offset-5,
|
|
||||||
.col-lg-offset-6,
|
|
||||||
.col-lg-offset-7,
|
|
||||||
.col-lg-offset-8,
|
|
||||||
.col-lg-offset-9,
|
|
||||||
.col-lg-offset-10,
|
|
||||||
.col-lg-offset-11,
|
|
||||||
.col-lg-offset-12 {
|
|
||||||
box-sizing: border-box;
|
|
||||||
-webkit-box-flex: 0;
|
|
||||||
-ms-flex: 0 0 auto;
|
|
||||||
flex: 0 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-lg {
|
|
||||||
-webkit-box-flex: 1;
|
|
||||||
-ms-flex-positive: 1;
|
|
||||||
flex-grow: 1;
|
|
||||||
-ms-flex-preferred-size: 0;
|
|
||||||
flex-basis: 0;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-lg-1 {
|
|
||||||
-ms-flex-preferred-size: 8.33333333%;
|
|
||||||
flex-basis: 8.33333333%;
|
|
||||||
max-width: 8.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-lg-2 {
|
|
||||||
-ms-flex-preferred-size: 16.66666667%;
|
|
||||||
flex-basis: 16.66666667%;
|
|
||||||
max-width: 16.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-lg-3 {
|
|
||||||
-ms-flex-preferred-size: 25%;
|
|
||||||
flex-basis: 25%;
|
|
||||||
max-width: 25%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-lg-4 {
|
|
||||||
-ms-flex-preferred-size: 33.33333333%;
|
|
||||||
flex-basis: 33.33333333%;
|
|
||||||
max-width: 33.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-lg-5 {
|
|
||||||
-ms-flex-preferred-size: 41.66666667%;
|
|
||||||
flex-basis: 41.66666667%;
|
|
||||||
max-width: 41.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-lg-6 {
|
|
||||||
-ms-flex-preferred-size: 50%;
|
|
||||||
flex-basis: 50%;
|
|
||||||
max-width: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-lg-7 {
|
|
||||||
-ms-flex-preferred-size: 58.33333333%;
|
|
||||||
flex-basis: 58.33333333%;
|
|
||||||
max-width: 58.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-lg-8 {
|
|
||||||
-ms-flex-preferred-size: 66.66666667%;
|
|
||||||
flex-basis: 66.66666667%;
|
|
||||||
max-width: 66.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-lg-9 {
|
|
||||||
-ms-flex-preferred-size: 75%;
|
|
||||||
flex-basis: 75%;
|
|
||||||
max-width: 75%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-lg-10 {
|
|
||||||
-ms-flex-preferred-size: 83.33333333%;
|
|
||||||
flex-basis: 83.33333333%;
|
|
||||||
max-width: 83.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-lg-11 {
|
|
||||||
-ms-flex-preferred-size: 91.66666667%;
|
|
||||||
flex-basis: 91.66666667%;
|
|
||||||
max-width: 91.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-lg-12 {
|
|
||||||
-ms-flex-preferred-size: 100%;
|
|
||||||
flex-basis: 100%;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-lg-offset-0 {
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-lg-offset-1 {
|
|
||||||
margin-left: 8.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-lg-offset-2 {
|
|
||||||
margin-left: 16.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-lg-offset-3 {
|
|
||||||
margin-left: 25%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-lg-offset-4 {
|
|
||||||
margin-left: 33.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-lg-offset-5 {
|
|
||||||
margin-left: 41.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-lg-offset-6 {
|
|
||||||
margin-left: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-lg-offset-7 {
|
|
||||||
margin-left: 58.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-lg-offset-8 {
|
|
||||||
margin-left: 66.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-lg-offset-9 {
|
|
||||||
margin-left: 75%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-lg-offset-10 {
|
|
||||||
margin-left: 83.33333333%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-lg-offset-11 {
|
|
||||||
margin-left: 91.66666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.start-lg {
|
|
||||||
-webkit-box-pack: start;
|
|
||||||
-ms-flex-pack: start;
|
|
||||||
justify-content: flex-start;
|
|
||||||
text-align: start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.center-lg {
|
|
||||||
-webkit-box-pack: center;
|
|
||||||
-ms-flex-pack: center;
|
|
||||||
justify-content: center;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.end-lg {
|
|
||||||
-webkit-box-pack: end;
|
|
||||||
-ms-flex-pack: end;
|
|
||||||
justify-content: flex-end;
|
|
||||||
text-align: end;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-lg {
|
|
||||||
-webkit-box-align: start;
|
|
||||||
-ms-flex-align: start;
|
|
||||||
align-items: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.middle-lg {
|
|
||||||
-webkit-box-align: center;
|
|
||||||
-ms-flex-align: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottom-lg {
|
|
||||||
-webkit-box-align: end;
|
|
||||||
-ms-flex-align: end;
|
|
||||||
align-items: flex-end;
|
|
||||||
}
|
|
||||||
|
|
||||||
.around-lg {
|
|
||||||
-ms-flex-pack: distribute;
|
|
||||||
justify-content: space-around;
|
|
||||||
}
|
|
||||||
|
|
||||||
.between-lg {
|
|
||||||
-webkit-box-pack: justify;
|
|
||||||
-ms-flex-pack: justify;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.first-lg {
|
|
||||||
-webkit-box-ordinal-group: 0;
|
|
||||||
-ms-flex-order: -1;
|
|
||||||
order: -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.last-lg {
|
|
||||||
-webkit-box-ordinal-group: 2;
|
|
||||||
-ms-flex-order: 1;
|
|
||||||
order: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.show-md {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
@use "variables" as *;
|
||||||
|
|
||||||
|
.insta {
|
||||||
|
padding: 120px 0;
|
||||||
|
|
||||||
|
@include md {
|
||||||
|
padding: 160px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__inner {
|
||||||
|
@include inner;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__head {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: flex-end;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 24px;
|
||||||
|
margin-bottom: 56px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__frame {
|
||||||
|
padding: 16px;
|
||||||
|
border: 3px solid $ink;
|
||||||
|
border-radius: $radius-lg;
|
||||||
|
background: $cream;
|
||||||
|
box-shadow: 10px 10px 0 $pink;
|
||||||
|
transform: rotate(-0.75deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__widget {
|
||||||
|
width: 100%;
|
||||||
|
border: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: $radius - 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,267 @@
|
|||||||
|
@use "variables" as *;
|
||||||
|
|
||||||
|
.intro {
|
||||||
|
position: relative;
|
||||||
|
padding: 48px 0 0;
|
||||||
|
|
||||||
|
@include md {
|
||||||
|
padding-top: 72px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__inner {
|
||||||
|
@include inner;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__kicker {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding: 6px 14px;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: $ink;
|
||||||
|
color: $beige;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.08em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
rotate: -2deg;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__kicker-dot {
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: $red;
|
||||||
|
animation: blink 1s steps(1) infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__headline {
|
||||||
|
max-width: 12ch;
|
||||||
|
font-size: clamp(52px, 11vw, 168px);
|
||||||
|
line-height: 0.92;
|
||||||
|
// background-clip: text only paints inside the box; keep descenders (g, p, …) visible
|
||||||
|
padding-bottom: 0.3em;
|
||||||
|
margin-bottom: -0.3em;
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing: -0.045em;
|
||||||
|
background: linear-gradient(100deg, $ink 0 48%, $red 68%, $orange 88%);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
background-clip: text;
|
||||||
|
color: transparent;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__cta {
|
||||||
|
margin-top: 32px;
|
||||||
|
|
||||||
|
@include md {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 48px;
|
||||||
|
margin: 0;
|
||||||
|
rotate: 4deg;
|
||||||
|
transition: rotate 0.4s $ease, opacity 0.8s $ease-out, transform 0.9s $ease-out;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
rotate: -2deg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes blink {
|
||||||
|
50% { opacity: 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.viewfinder {
|
||||||
|
position: relative;
|
||||||
|
margin-top: 48px;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 3px solid $ink;
|
||||||
|
border-radius: $radius-lg;
|
||||||
|
background: $ink;
|
||||||
|
box-shadow: 10px 10px 0 $orange;
|
||||||
|
aspect-ratio: 16 / 9;
|
||||||
|
min-height: 320px;
|
||||||
|
|
||||||
|
@include md {
|
||||||
|
margin-top: 64px;
|
||||||
|
box-shadow: 16px 16px 0 $orange;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__video {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__overlay {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
color: #fff;
|
||||||
|
font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 0.08em;
|
||||||
|
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
|
||||||
|
|
||||||
|
@include md {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__corner {
|
||||||
|
position: absolute;
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
border: 0 solid rgba(#fff, 0.9);
|
||||||
|
|
||||||
|
&--tl { top: 20px; left: 20px; border-top-width: 3px; border-left-width: 3px; }
|
||||||
|
&--tr { top: 20px; right: 20px; border-top-width: 3px; border-right-width: 3px; }
|
||||||
|
&--bl { bottom: 20px; left: 20px; border-bottom-width: 3px; border-left-width: 3px; }
|
||||||
|
&--br { bottom: 20px; right: 20px; border-bottom-width: 3px; border-right-width: 3px; }
|
||||||
|
}
|
||||||
|
|
||||||
|
&__rec {
|
||||||
|
position: absolute;
|
||||||
|
top: 30px;
|
||||||
|
left: 70px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: "";
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: $red;
|
||||||
|
animation: blink 1s steps(1) infinite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__timecode {
|
||||||
|
position: absolute;
|
||||||
|
top: 30px;
|
||||||
|
right: 70px;
|
||||||
|
font-variant-numeric: tabular-nums;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__meta {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 30px;
|
||||||
|
left: 70px;
|
||||||
|
opacity: 0.85;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__battery {
|
||||||
|
position: absolute;
|
||||||
|
right: 74px;
|
||||||
|
bottom: 32px;
|
||||||
|
width: 30px;
|
||||||
|
height: 14px;
|
||||||
|
border: 2px solid #fff;
|
||||||
|
border-radius: 3px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
inset: 2px 30% 2px 2px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 3px;
|
||||||
|
right: -5px;
|
||||||
|
width: 3px;
|
||||||
|
height: 4px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__focus {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
border: 2px solid rgba($yellow, 0.9);
|
||||||
|
animation: focus-hunt 5s $ease infinite;
|
||||||
|
|
||||||
|
&::before,
|
||||||
|
&::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
background: rgba($yellow, 0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before { top: 50%; left: 50%; width: 12px; height: 2px; transform: translate(-50%, -50%); }
|
||||||
|
&::after { top: 50%; left: 50%; width: 2px; height: 12px; transform: translate(-50%, -50%); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 639px) {
|
||||||
|
&__meta,
|
||||||
|
&__battery {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__rec { left: 32px; top: 28px; }
|
||||||
|
&__timecode { right: 32px; top: 28px; }
|
||||||
|
&__corner { width: 22px; height: 22px; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes focus-hunt {
|
||||||
|
0%, 100% { transform: translate(-50%, -50%) scale(1); }
|
||||||
|
10% { transform: translate(-50%, -50%) scale(1.25); }
|
||||||
|
18% { transform: translate(-50%, -50%) scale(0.9); }
|
||||||
|
24% { transform: translate(-50%, -50%) scale(1); }
|
||||||
|
60% { transform: translate(-30%, -60%) scale(1); }
|
||||||
|
70% { transform: translate(-30%, -60%) scale(1.2); }
|
||||||
|
76% { transform: translate(-30%, -60%) scale(1); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.ticker {
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
margin: 72px -5vw 0;
|
||||||
|
padding: 18px 0;
|
||||||
|
overflow: hidden;
|
||||||
|
border-block: 3px solid $ink;
|
||||||
|
background: $yellow;
|
||||||
|
transform: rotate(-2deg);
|
||||||
|
|
||||||
|
@include md {
|
||||||
|
margin-top: 96px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__track {
|
||||||
|
display: flex;
|
||||||
|
width: max-content;
|
||||||
|
animation: ticker 40s linear infinite;
|
||||||
|
|
||||||
|
span {
|
||||||
|
padding-right: 0.5em;
|
||||||
|
white-space: nowrap;
|
||||||
|
font-size: clamp(24px, 4vw, 44px);
|
||||||
|
line-height: 1;
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing: -0.02em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover &__track {
|
||||||
|
animation-play-state: paused;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes ticker {
|
||||||
|
to { transform: translateX(-50%); }
|
||||||
|
}
|
||||||
@@ -0,0 +1,167 @@
|
|||||||
|
@use "variables" as *;
|
||||||
|
|
||||||
|
.nav {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 100;
|
||||||
|
padding: 12px 0;
|
||||||
|
transition: padding 0.3s $ease-out;
|
||||||
|
|
||||||
|
&__inner {
|
||||||
|
@include inner;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__brand {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
padding: 10px 18px;
|
||||||
|
border: 3px solid $ink;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: $cream;
|
||||||
|
box-shadow: 4px 4px 0 $ink;
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 22px;
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing: -0.02em;
|
||||||
|
transition: transform 0.3s $ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: rotate(-3deg) scale(1.04);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__rec {
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: $red;
|
||||||
|
box-shadow: 0 0 0 0 rgba($red, 0.6);
|
||||||
|
animation: rec-pulse 1.6s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__word {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__cut {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 1px;
|
||||||
|
color: $orange;
|
||||||
|
font-size: 0.75em;
|
||||||
|
transform: rotate(-90deg);
|
||||||
|
transition: transform 0.5s $ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__brand:hover &__cut {
|
||||||
|
transform: rotate(-90deg) translateY(-3px) scaleX(0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__toggle {
|
||||||
|
display: inline-flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 6px;
|
||||||
|
width: 52px;
|
||||||
|
height: 52px;
|
||||||
|
padding: 0 14px;
|
||||||
|
border: 3px solid $ink;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: $yellow;
|
||||||
|
box-shadow: 4px 4px 0 $ink;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
@include md {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__toggle-bar {
|
||||||
|
display: block;
|
||||||
|
height: 3px;
|
||||||
|
border-radius: 3px;
|
||||||
|
background: $ink;
|
||||||
|
transition: transform 0.3s $ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--open &__toggle-bar:first-child { transform: translateY(4.5px) rotate(45deg); }
|
||||||
|
&--open &__toggle-bar:nth-child(2) { transform: translateY(-4.5px) rotate(-45deg); }
|
||||||
|
|
||||||
|
&__links {
|
||||||
|
display: none;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 6px;
|
||||||
|
border: 3px solid $ink;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: $cream;
|
||||||
|
box-shadow: 4px 4px 0 $ink;
|
||||||
|
|
||||||
|
@include md {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__link {
|
||||||
|
position: relative;
|
||||||
|
padding: 8px 18px;
|
||||||
|
border-radius: 999px;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 700;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: background 0.2s, transform 0.3s $ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $ink;
|
||||||
|
color: $beige;
|
||||||
|
transform: rotate(-2deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--cta {
|
||||||
|
background: $red;
|
||||||
|
color: $cream;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// mobile overlay menu
|
||||||
|
&--open &__links {
|
||||||
|
position: fixed;
|
||||||
|
inset: 84px 16px auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
padding: 16px;
|
||||||
|
border-radius: $radius-lg;
|
||||||
|
animation: menu-pop 0.4s $ease;
|
||||||
|
|
||||||
|
.nav__link {
|
||||||
|
padding: 16px 20px;
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: 800;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: attr(data-nr);
|
||||||
|
margin-right: 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
vertical-align: middle;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rec-pulse {
|
||||||
|
0% { box-shadow: 0 0 0 0 rgba($red, 0.6); opacity: 1; }
|
||||||
|
50% { opacity: 0.35; }
|
||||||
|
70% { box-shadow: 0 0 0 10px rgba($red, 0); }
|
||||||
|
100% { box-shadow: 0 0 0 0 rgba($red, 0); opacity: 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes menu-pop {
|
||||||
|
from { opacity: 0; transform: scale(0.9) rotate(-2deg); }
|
||||||
|
to { opacity: 1; transform: none; }
|
||||||
|
}
|
||||||
@@ -14,7 +14,6 @@ time, mark, audio, video {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
border: 0;
|
border: 0;
|
||||||
outline: none;
|
|
||||||
font: inherit;
|
font: inherit;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
vertical-align: baseline;
|
vertical-align: baseline;
|
||||||
@@ -54,5 +53,4 @@ table {
|
|||||||
}
|
}
|
||||||
|
|
||||||
textarea:focus, input:focus, button:focus {
|
textarea:focus, input:focus, button:focus {
|
||||||
outline: none;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
@use "variables" as *;
|
||||||
|
|
||||||
|
.service {
|
||||||
|
padding: 120px 0;
|
||||||
|
|
||||||
|
@include md {
|
||||||
|
padding: 160px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__inner {
|
||||||
|
@include inner;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__head {
|
||||||
|
display: grid;
|
||||||
|
gap: 24px;
|
||||||
|
margin-bottom: 64px;
|
||||||
|
|
||||||
|
@include md {
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
align-items: end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
max-width: 46ch;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__grid {
|
||||||
|
display: grid;
|
||||||
|
gap: 56px;
|
||||||
|
|
||||||
|
@include md {
|
||||||
|
grid-template-columns: 5fr 7fr;
|
||||||
|
align-items: start;
|
||||||
|
gap: 64px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__items {
|
||||||
|
display: grid;
|
||||||
|
gap: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.polaroid {
|
||||||
|
position: relative;
|
||||||
|
margin: 0;
|
||||||
|
padding: 16px 16px 72px;
|
||||||
|
border: 3px solid $ink;
|
||||||
|
background: $cream;
|
||||||
|
box-shadow: 10px 10px 0 $ink;
|
||||||
|
rotate: 2.5deg;
|
||||||
|
transition: rotate 0.5s $ease, scale 0.5s $ease, opacity 0.8s $ease-out, transform 0.9s $ease-out;
|
||||||
|
|
||||||
|
@include md {
|
||||||
|
position: sticky;
|
||||||
|
top: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
rotate: -1deg;
|
||||||
|
scale: 1.02;
|
||||||
|
}
|
||||||
|
|
||||||
|
// tape
|
||||||
|
&::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: -18px;
|
||||||
|
left: 50%;
|
||||||
|
width: 140px;
|
||||||
|
height: 36px;
|
||||||
|
transform: translateX(-50%) rotate(-4deg);
|
||||||
|
background: rgba($yellow, 0.85);
|
||||||
|
border: 2px dashed rgba($ink, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__image {
|
||||||
|
width: 100%;
|
||||||
|
aspect-ratio: 4 / 3;
|
||||||
|
object-fit: cover;
|
||||||
|
object-position: center 33%;
|
||||||
|
border: 3px solid $ink;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__caption {
|
||||||
|
position: absolute;
|
||||||
|
right: 16px;
|
||||||
|
bottom: 18px;
|
||||||
|
left: 16px;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 700;
|
||||||
|
font-style: italic;
|
||||||
|
text-align: center;
|
||||||
|
transform: rotate(-1deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
@use "variables" as *;
|
||||||
|
|
||||||
|
.slate {
|
||||||
|
--slate-color: #{$red};
|
||||||
|
position: relative;
|
||||||
|
counter-increment: slate;
|
||||||
|
padding-top: 30px;
|
||||||
|
|
||||||
|
@each $name, $color in $colors {
|
||||||
|
&--#{$name} {
|
||||||
|
--slate-color: #{$color};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__clapper {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 34px;
|
||||||
|
border: 3px solid $ink;
|
||||||
|
border-radius: 10px 10px 0 0;
|
||||||
|
background: repeating-linear-gradient(
|
||||||
|
-55deg,
|
||||||
|
var(--slate-color) 0 20px,
|
||||||
|
$ink 20px 40px
|
||||||
|
);
|
||||||
|
transform-origin: 6px 100%;
|
||||||
|
transform: rotate(-9deg);
|
||||||
|
transition: transform 0.35s $ease;
|
||||||
|
|
||||||
|
// hinge
|
||||||
|
&::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
left: 2px;
|
||||||
|
bottom: -9px;
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
border: 3px solid $ink;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: $cream;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover &__clapper {
|
||||||
|
animation: clap 0.45s $ease;
|
||||||
|
transform: rotate(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__body {
|
||||||
|
position: relative;
|
||||||
|
padding: 28px 28px 28px;
|
||||||
|
border: 3px solid $ink;
|
||||||
|
border-radius: 0 0 $radius $radius;
|
||||||
|
background: $ink;
|
||||||
|
color: $beige;
|
||||||
|
box-shadow: 8px 8px 0 var(--slate-color);
|
||||||
|
transition: transform 0.35s $ease, box-shadow 0.35s $ease;
|
||||||
|
|
||||||
|
// top stripe bar of the slate body
|
||||||
|
&::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 14px;
|
||||||
|
background: repeating-linear-gradient(
|
||||||
|
-55deg,
|
||||||
|
var(--slate-color) 0 20px,
|
||||||
|
$ink 20px 40px
|
||||||
|
);
|
||||||
|
border-bottom: 3px solid $ink;
|
||||||
|
}
|
||||||
|
|
||||||
|
// "SCENE 01"
|
||||||
|
&::after {
|
||||||
|
content: "Szene 0" counter(slate);
|
||||||
|
position: absolute;
|
||||||
|
top: 30px;
|
||||||
|
right: 24px;
|
||||||
|
font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
|
||||||
|
font-size: 12px;
|
||||||
|
letter-spacing: 0.12em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover &__body {
|
||||||
|
transform: translate(-3px, -3px);
|
||||||
|
box-shadow: 12px 12px 0 var(--slate-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__title {
|
||||||
|
margin-top: 12px;
|
||||||
|
font-size: clamp(32px, 4vw, 48px);
|
||||||
|
line-height: 1.1;
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing: -0.03em;
|
||||||
|
color: var(--slate-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
margin-top: 8px;
|
||||||
|
font-size: 18px;
|
||||||
|
color: rgba($beige, 0.85);
|
||||||
|
}
|
||||||
|
|
||||||
|
// playful alternating tilt
|
||||||
|
&:nth-child(odd) { rotate: -1deg; }
|
||||||
|
&:nth-child(even) { rotate: 1deg; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.service__items {
|
||||||
|
counter-reset: slate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes clap {
|
||||||
|
0% { transform: rotate(-9deg); }
|
||||||
|
40% { transform: rotate(-22deg); }
|
||||||
|
70% { transform: rotate(1deg); }
|
||||||
|
100% { transform: rotate(0); }
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
@use "variables" as *;
|
||||||
|
|
||||||
|
.text {
|
||||||
|
padding: 72px 0 120px;
|
||||||
|
|
||||||
|
&__inner {
|
||||||
|
@include inner;
|
||||||
|
max-width: 880px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
margin-bottom: 40px;
|
||||||
|
font-size: clamp(40px, 6vw, 72px);
|
||||||
|
line-height: 1;
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing: -0.03em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 40px 0 12px;
|
||||||
|
padding: 4px 12px;
|
||||||
|
background: $yellow;
|
||||||
|
border: 2px solid $ink;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 800;
|
||||||
|
transform: rotate(-1deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
font-size: 17px;
|
||||||
|
line-height: 1.7;
|
||||||
|
hyphens: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
$beige: #f7eee0;
|
||||||
|
$cream: #fff8ec;
|
||||||
|
$yellow: #febb28;
|
||||||
|
$orange: #fe6732;
|
||||||
|
$red: #f5303c;
|
||||||
|
$pink: #ce2867;
|
||||||
|
$purple: #571b47;
|
||||||
|
$ink: #0e0c0b;
|
||||||
|
$grey: #3d3d3d;
|
||||||
|
|
||||||
|
$max-width: 1440px;
|
||||||
|
$radius: 20px;
|
||||||
|
$radius-lg: 32px;
|
||||||
|
$ease: cubic-bezier(0.34, 1.56, 0.64, 1); // springy
|
||||||
|
$ease-out: cubic-bezier(0.22, 1, 0.36, 1);
|
||||||
|
$shadow: 6px 6px 0 $ink;
|
||||||
|
|
||||||
|
$colors: (
|
||||||
|
"red": $red,
|
||||||
|
"orange": $orange,
|
||||||
|
"yellow": $yellow,
|
||||||
|
"pink": $pink,
|
||||||
|
"purple": $purple
|
||||||
|
);
|
||||||
|
|
||||||
|
@mixin sm {
|
||||||
|
@media (min-width: 640px) { @content; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin md {
|
||||||
|
@media (min-width: 900px) { @content; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin lg {
|
||||||
|
@media (min-width: 1200px) { @content; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin inner {
|
||||||
|
width: 100%;
|
||||||
|
max-width: $max-width;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 20px;
|
||||||
|
|
||||||
|
@include md {
|
||||||
|
padding: 0 48px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin stripes($color, $size: 22px) {
|
||||||
|
background: repeating-linear-gradient(
|
||||||
|
-45deg,
|
||||||
|
$color 0 $size,
|
||||||
|
$ink $size ($size * 2)
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
@use "variables" as *;
|
||||||
|
|
||||||
|
.work {
|
||||||
|
position: relative;
|
||||||
|
padding: 0;
|
||||||
|
background: $ink;
|
||||||
|
color: $beige;
|
||||||
|
counter-reset: take;
|
||||||
|
|
||||||
|
&__inner {
|
||||||
|
@include inner;
|
||||||
|
padding-top: 120px;
|
||||||
|
padding-bottom: 120px;
|
||||||
|
|
||||||
|
@include md {
|
||||||
|
padding-top: 160px;
|
||||||
|
padding-bottom: 160px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__head {
|
||||||
|
display: grid;
|
||||||
|
gap: 24px;
|
||||||
|
margin-bottom: 80px;
|
||||||
|
|
||||||
|
@include md {
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
align-items: end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
max-width: 46ch;
|
||||||
|
font-size: 20px;
|
||||||
|
color: rgba($beige, 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__list {
|
||||||
|
display: grid;
|
||||||
|
gap: 96px;
|
||||||
|
|
||||||
|
@include md {
|
||||||
|
gap: 140px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// sprocket holes
|
||||||
|
.filmstrip {
|
||||||
|
height: 44px;
|
||||||
|
background-color: $ink;
|
||||||
|
background-image: radial-gradient(ellipse 9px 8px at center, $beige 96%, transparent 100%);
|
||||||
|
background-size: 40px 20px;
|
||||||
|
background-position: 0 12px;
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
animation: filmstrip 2s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes filmstrip {
|
||||||
|
to { background-position: 40px 12px; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
@use "variables" as *;
|
||||||
|
|
||||||
|
.take {
|
||||||
|
counter-increment: take;
|
||||||
|
display: grid;
|
||||||
|
gap: 32px;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
@include md {
|
||||||
|
grid-template-columns: 4fr 8fr;
|
||||||
|
gap: 64px;
|
||||||
|
|
||||||
|
&:nth-child(even) {
|
||||||
|
grid-template-columns: 8fr 4fr;
|
||||||
|
|
||||||
|
.take__info { order: 2; }
|
||||||
|
.take__screen { order: 1; transform: rotate(1.5deg); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__info {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__label {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 6px 14px;
|
||||||
|
border: 2px solid $beige;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
|
||||||
|
font-size: 13px;
|
||||||
|
letter-spacing: 0.12em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: counter(take, decimal-leading-zero);
|
||||||
|
padding-left: 8px;
|
||||||
|
border-left: 2px solid $beige;
|
||||||
|
color: $yellow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__title {
|
||||||
|
margin-top: 20px;
|
||||||
|
font-size: clamp(32px, 4.5vw, 56px);
|
||||||
|
line-height: 1.05;
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing: -0.03em;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
margin-top: 16px;
|
||||||
|
color: rgba($beige, 0.75);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__screen {
|
||||||
|
position: relative;
|
||||||
|
aspect-ratio: 16 / 9;
|
||||||
|
border: 3px solid $beige;
|
||||||
|
border-radius: $radius;
|
||||||
|
overflow: hidden;
|
||||||
|
background: #000;
|
||||||
|
transform: rotate(-1.5deg);
|
||||||
|
transition: transform 0.5s $ease, box-shadow 0.5s $ease;
|
||||||
|
box-shadow: 10px 10px 0 var(--take-color, #{$red});
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover &__screen {
|
||||||
|
transform: rotate(0) scale(1.02);
|
||||||
|
box-shadow: 16px 16px 0 var(--take-color, #{$red});
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(4n+1) { --take-color: #{$pink}; }
|
||||||
|
&:nth-child(4n+2) { --take-color: #{$red}; }
|
||||||
|
&:nth-child(4n+3) { --take-color: #{$orange}; }
|
||||||
|
&:nth-child(4n+4) { --take-color: #{$yellow}; }
|
||||||
|
|
||||||
|
&:hover &__title {
|
||||||
|
color: var(--take-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__title {
|
||||||
|
transition: color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__video {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
-832
@@ -1,833 +1,12 @@
|
|||||||
@import "_reset.scss";
|
@use "reset";
|
||||||
@import "_grid.scss";
|
@use "base";
|
||||||
|
@use "nav";
|
||||||
|
@use "intro";
|
||||||
|
@use "service";
|
||||||
|
@use "service_item";
|
||||||
|
@use "work";
|
||||||
|
@use "work_entry";
|
||||||
|
@use "insta";
|
||||||
|
@use "footer";
|
||||||
|
@use "text";
|
||||||
|
|
||||||
* {
|
|
||||||
color: var(--black);
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
html {
|
|
||||||
color: var(--black);
|
|
||||||
font-family: "Manrope", -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
|
||||||
|
|
||||||
--white: #fff;
|
|
||||||
--beige: #f7eee0;
|
|
||||||
--yellow: #febb28;
|
|
||||||
--orange: #fe6732;
|
|
||||||
--red: #f5303c;
|
|
||||||
--pink: #ce2867;
|
|
||||||
--purple: #571b47;
|
|
||||||
--grey: #3d3d3d;
|
|
||||||
--black: #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
background-color: var(--beige);
|
|
||||||
padding: 0 16px;
|
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
section {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1, h2, h3, h4, p {
|
|
||||||
margin-block-start: 0;
|
|
||||||
margin-block-end: 0;
|
|
||||||
line-height: 1.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1, h2, h3 {
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 96px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-size: 48px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
font-size: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h4 {
|
|
||||||
font-size: 20px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: 500;
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: var(--red);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
button, a.button {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: 600;
|
|
||||||
padding: 16px 24px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-aos="fade-in"] {
|
|
||||||
opacity: 0;
|
|
||||||
transition-property: opacity;
|
|
||||||
|
|
||||||
&.aos-animate {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
position: sticky;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
height: 64px;
|
|
||||||
width: 100%;
|
|
||||||
background-color: var(--beige);
|
|
||||||
z-index: 100;
|
|
||||||
-webkit-backface-visibility: hidden; /* Correct fixed positioning on mobile */
|
|
||||||
|
|
||||||
.container {
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.wordmark {
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: 700;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
|
||||||
justify-content: flex-end;
|
|
||||||
text-align: right;
|
|
||||||
|
|
||||||
li {
|
|
||||||
position: relative;
|
|
||||||
display: inline-flex;
|
|
||||||
margin-left: 48px;
|
|
||||||
font-size: 18px;
|
|
||||||
line-height: 1.5;
|
|
||||||
font-weight: 500;
|
|
||||||
color: inherit;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&:nth-of-type(1):hover::before {
|
|
||||||
background-color: var(--pink);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-of-type(2):hover::before {
|
|
||||||
background-color: var(--red);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-of-type(3):hover::before {
|
|
||||||
background-color: var(--orange);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-of-type(4):hover::before {
|
|
||||||
background-color: var(--yellow);
|
|
||||||
}
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
height: 2px;
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mobile-menu {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
background-color: rgba(0, 0, 0, 0.8);
|
|
||||||
z-index: 1000;
|
|
||||||
animation: fade-in 0.2s ease-in-out;
|
|
||||||
-webkit-backface-visibility: hidden; /* Correct fixed positioning on mobile */
|
|
||||||
|
|
||||||
@keyframes fade-in {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
li {
|
|
||||||
color: white;
|
|
||||||
font-size: 24px;
|
|
||||||
line-height: 64px;
|
|
||||||
font-weight: 600;
|
|
||||||
text-align: center;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-start {
|
|
||||||
padding: 128px 0;
|
|
||||||
|
|
||||||
.headline {
|
|
||||||
display: flex;
|
|
||||||
margin-bottom: 96px;
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
flex: 1;
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: var(--red);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero {
|
|
||||||
width: 100%;
|
|
||||||
max-width: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
z-index: 1;
|
|
||||||
|
|
||||||
video {
|
|
||||||
height: 100%;
|
|
||||||
min-height: 512px;
|
|
||||||
width: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
transform: scale(1.004);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-service {
|
|
||||||
padding: 128px 0;
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
margin: 0 64px 24px 0;
|
|
||||||
padding-bottom: 12px;
|
|
||||||
border-bottom: 8px solid;
|
|
||||||
|
|
||||||
&:nth-of-type(1) {
|
|
||||||
border-color: var(--red);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-of-type(2) {
|
|
||||||
border-color: var(--orange);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-of-type(3) {
|
|
||||||
border-color: var(--yellow);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin: 0 64px 64px 0;
|
|
||||||
|
|
||||||
&:last-of-type {
|
|
||||||
margin-bottom: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.img {
|
|
||||||
min-height: 512px;
|
|
||||||
background-image: url("1.jpg");
|
|
||||||
background-position: center 33%;
|
|
||||||
background-size: cover;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-work {
|
|
||||||
padding: 128px 0;
|
|
||||||
|
|
||||||
.video {
|
|
||||||
margin-bottom: 128px;
|
|
||||||
|
|
||||||
&:nth-of-type(4n+1) h2 {
|
|
||||||
border-color: var(--pink);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-of-type(4n+2) h2 {
|
|
||||||
border-color: var(--red);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-of-type(4n+3) h2 {
|
|
||||||
border-color: var(--orange);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-of-type(4n+4) h2 {
|
|
||||||
border-color: var(--yellow);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:last-of-type {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
margin: 0 0 24px 64px;
|
|
||||||
padding-bottom: 12px;
|
|
||||||
border-bottom: 8px solid;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin-left: 64px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-rental {
|
|
||||||
padding: 128px 0;
|
|
||||||
|
|
||||||
.square {
|
|
||||||
position: sticky;
|
|
||||||
top: 128px;
|
|
||||||
padding: 32px 0;
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
margin-bottom: 24px;
|
|
||||||
padding-bottom: 12px;
|
|
||||||
border-bottom: 8px solid var(--red);
|
|
||||||
}
|
|
||||||
|
|
||||||
button, a.button {
|
|
||||||
display: inline-flex;
|
|
||||||
color: var(--black);
|
|
||||||
margin: 48px 12px 0 0;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: inset 0 0 0 2px var(--black);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.primary {
|
|
||||||
background-color: var(--yellow);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.secondary {
|
|
||||||
background-color: var(--orange);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.parts {
|
|
||||||
position: relative;
|
|
||||||
max-width: 720px;
|
|
||||||
min-height: 256px;
|
|
||||||
margin: 0 auto;
|
|
||||||
|
|
||||||
img:not(#part0) {
|
|
||||||
position: absolute;
|
|
||||||
filter: contrast(1.3) saturate(0.6);
|
|
||||||
}
|
|
||||||
|
|
||||||
#part0 {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part1 {
|
|
||||||
width: 29%;
|
|
||||||
left: 34%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part2 {
|
|
||||||
width: 8.5%;
|
|
||||||
left: 24%;
|
|
||||||
margin-top: 2%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part3 {
|
|
||||||
width: 19%;
|
|
||||||
left: 0;
|
|
||||||
margin-top: 2%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part4 {
|
|
||||||
width: 17%;
|
|
||||||
left: 2%;
|
|
||||||
margin-top: 15%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part5 {
|
|
||||||
width: 5.5%;
|
|
||||||
left: 70%;
|
|
||||||
margin-top: 9%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part6 {
|
|
||||||
width: 22%;
|
|
||||||
left: 64%;
|
|
||||||
margin-top: 1%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part7 {
|
|
||||||
width: 12.5%;
|
|
||||||
left: 87.5%;
|
|
||||||
margin-top: 1%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part8 {
|
|
||||||
width: 37%;
|
|
||||||
left: 30%;
|
|
||||||
margin-top: 28%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part9 {
|
|
||||||
width: 22.5%;
|
|
||||||
left: 0;
|
|
||||||
margin-top: 28%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part10 {
|
|
||||||
width: 49%;
|
|
||||||
left: 20%;
|
|
||||||
margin-top: 40%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part11 {
|
|
||||||
width: 14%;
|
|
||||||
left: 2%;
|
|
||||||
margin-top: 36%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part12 {
|
|
||||||
width: 27%;
|
|
||||||
left: 72%;
|
|
||||||
margin-top: 31%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part13 {
|
|
||||||
width: 24%;
|
|
||||||
left: 48%;
|
|
||||||
margin-top: 48%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part14 {
|
|
||||||
width: 19%;
|
|
||||||
left: 24%;
|
|
||||||
margin-top: 48%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part15 {
|
|
||||||
width: 4.5%;
|
|
||||||
left: 15%;
|
|
||||||
margin-top: 47%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part16 {
|
|
||||||
width: 24%;
|
|
||||||
left: 75%;
|
|
||||||
margin-top: 48%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part17 {
|
|
||||||
width: 7.5%;
|
|
||||||
left: 2%;
|
|
||||||
margin-top: 44%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part18-1 {
|
|
||||||
width: 14%;
|
|
||||||
left: 46%;
|
|
||||||
margin-top: 72%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part18-2 {
|
|
||||||
width: 14%;
|
|
||||||
left: 46%;
|
|
||||||
margin-top: 86%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part19-1 {
|
|
||||||
width: 17%;
|
|
||||||
left: 22%;
|
|
||||||
margin-top: 70%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part19-2 {
|
|
||||||
width: 17%;
|
|
||||||
left: 22%;
|
|
||||||
margin-top: 84%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part20 {
|
|
||||||
width: 13.5%;
|
|
||||||
left: 66%;
|
|
||||||
margin-top: 73%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part21 {
|
|
||||||
width: 11.5%;
|
|
||||||
left: 6%;
|
|
||||||
margin-top: 73%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part22 {
|
|
||||||
width: 13.5%;
|
|
||||||
left: 84%;
|
|
||||||
margin-top: 73%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part23 {
|
|
||||||
width: 28%;
|
|
||||||
left: 22%;
|
|
||||||
margin-top: 102%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part24 {
|
|
||||||
width: 37.5%;
|
|
||||||
left: 60%;
|
|
||||||
margin-top: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part25 {
|
|
||||||
width: 20%;
|
|
||||||
left: 14%;
|
|
||||||
margin-top: 105%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part26 {
|
|
||||||
width: 40%;
|
|
||||||
left: 43%;
|
|
||||||
margin-top: 106%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part27 {
|
|
||||||
width: 22.5%;
|
|
||||||
left: 20%;
|
|
||||||
margin-top: 115%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part28 {
|
|
||||||
width: 22%;
|
|
||||||
left: 47%;
|
|
||||||
margin-top: 130%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part29-1 {
|
|
||||||
width: 3%;
|
|
||||||
left: 4%;
|
|
||||||
margin-top: 106%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part29-2 {
|
|
||||||
width: 3%;
|
|
||||||
left: 8%;
|
|
||||||
margin-top: 106%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part30 {
|
|
||||||
width: 19%;
|
|
||||||
left: 70%;
|
|
||||||
margin-top: 116%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part31-1 {
|
|
||||||
width: 2.5%;
|
|
||||||
left: 13%;
|
|
||||||
margin-top: 125.5%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part31-2 {
|
|
||||||
width: 2.5%;
|
|
||||||
left: 16%;
|
|
||||||
margin-top: 125.5%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part32-1 {
|
|
||||||
width: 2.75%;
|
|
||||||
left: 20%;
|
|
||||||
margin-top: 126%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#part32-2 {
|
|
||||||
width: 2.75%;
|
|
||||||
left: 24%;
|
|
||||||
margin-top: 126%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-instagram {
|
|
||||||
padding: 128px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-text {
|
|
||||||
padding: 128px 0;
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
margin-bottom: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h4 {
|
|
||||||
margin: 16px 0 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
footer {
|
|
||||||
padding: 128px 0;
|
|
||||||
|
|
||||||
ul {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
|
|
||||||
li {
|
|
||||||
font-size: 18px;
|
|
||||||
line-height: 1.5;
|
|
||||||
font-weight: 500;
|
|
||||||
|
|
||||||
&:first-of-type {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:not(:first-of-type) {
|
|
||||||
margin-left: 48px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-of-type(4n+1):hover a::before {
|
|
||||||
background-color: var(--pink);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-of-type(4n+2):hover a::before {
|
|
||||||
background-color: var(--red);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-of-type(4n+3):hover a::before {
|
|
||||||
background-color: var(--orange);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-of-type(4n+4):hover a::before {
|
|
||||||
background-color: var(--yellow);
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
height: 2px;
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 1023px) {
|
|
||||||
h1 {
|
|
||||||
font-size: 64px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-size: 36px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
font-size: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h4 {
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-start {
|
|
||||||
padding: 64px 0;
|
|
||||||
|
|
||||||
.headline {
|
|
||||||
margin-bottom: 64px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-service {
|
|
||||||
padding: 64px 0;
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
margin: 0 32px 24px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin: 0 32px 32px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.img {
|
|
||||||
margin-top: 64px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-work {
|
|
||||||
padding: 64px 0;
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
margin: 0 0 24px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin: 0 0 32px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.video {
|
|
||||||
margin-bottom: 64px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-rental {
|
|
||||||
padding: 64px 0;
|
|
||||||
overflow-x: hidden;
|
|
||||||
|
|
||||||
.square {
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
margin: 0 0 24px 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.parts {
|
|
||||||
margin: 64px 0 0;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-instagram {
|
|
||||||
padding: 64px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-text {
|
|
||||||
padding: 64px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer {
|
|
||||||
padding: 64px 0;
|
|
||||||
|
|
||||||
ul {
|
|
||||||
display: block;
|
|
||||||
|
|
||||||
li {
|
|
||||||
margin: 12px 0 !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 767px) {
|
|
||||||
.section-service {
|
|
||||||
h2 {
|
|
||||||
margin: 0 0 16px 0;
|
|
||||||
padding-bottom: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin: 0 0 24px 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-work {
|
|
||||||
h2 {
|
|
||||||
margin: 0 0 16px 0;
|
|
||||||
padding-bottom: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin: 0 0 24px 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-rental {
|
|
||||||
.square h2 {
|
|
||||||
margin: 0 0 16px 0;
|
|
||||||
padding-bottom: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 511px) {
|
|
||||||
h1 {
|
|
||||||
font-size: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-size: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-start {
|
|
||||||
padding: 32px 0 0;
|
|
||||||
|
|
||||||
.headline {
|
|
||||||
margin-bottom: 32px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-service {
|
|
||||||
padding: 64px 0 0;
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
border-bottom: 4px solid;
|
|
||||||
}
|
|
||||||
|
|
||||||
.img {
|
|
||||||
margin-top: 32px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-work {
|
|
||||||
padding: 64px 0 0;
|
|
||||||
|
|
||||||
.video {
|
|
||||||
margin-bottom: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
border-bottom: 4px solid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-rental {
|
|
||||||
padding: 64px 0 0;
|
|
||||||
|
|
||||||
.square h2 {
|
|
||||||
border-bottom: 4px solid var(--red);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-instagram {
|
|
||||||
padding: 32px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-text {
|
|
||||||
padding: 32px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer {
|
|
||||||
padding: 32px 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+108
-15
@@ -7,18 +7,87 @@
|
|||||||
},
|
},
|
||||||
"content": {
|
"content": {
|
||||||
"content": [
|
"content": [
|
||||||
{"ref": "head"},
|
{
|
||||||
|
"ref": "head"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ref": "nav",
|
"ref": "nav",
|
||||||
"data": {
|
"data": {
|
||||||
"full": true
|
"full": "on"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tpl": "intro"
|
"tpl": "intro",
|
||||||
|
"copy": {
|
||||||
|
"de": {
|
||||||
|
"kicker": "Videoproduktion aus Ostwestfalen",
|
||||||
|
"headline": "Film, auf den Frame genau.",
|
||||||
|
"cta_label": "Projekt anfragen",
|
||||||
|
"cta_href": "mailto:hi@schnittfest.gmbh",
|
||||||
|
"ticker": "Film ✦ Animation ✦ Sound ✦ Schnitt ✦ Color Grading ✦ Imagefilm ✦ Commercial ✦"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"video": "/static/hero.mp4",
|
||||||
|
"poster": "/static/1.jpg"
|
||||||
|
},
|
||||||
|
"content": {}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tpl": "service"
|
"tpl": "service",
|
||||||
|
"copy": {
|
||||||
|
"de": {
|
||||||
|
"headline": "Gewerke",
|
||||||
|
"text": "<div>Von der ersten Idee bis zum finalen Frame: Wir planen, drehen, animieren und vertonen – alles aus einer Hand.</div>",
|
||||||
|
"image_caption": "Am Set, irgendwo zwischen Take 7 und 8."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"image": "/static/1.jpg"
|
||||||
|
},
|
||||||
|
"content": {
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"tpl": "service_item",
|
||||||
|
"copy": {
|
||||||
|
"de": {
|
||||||
|
"title": "Film",
|
||||||
|
"text": "sleep.shoot.eat.repeat."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"color": "red"
|
||||||
|
},
|
||||||
|
"content": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tpl": "service_item",
|
||||||
|
"copy": {
|
||||||
|
"de": {
|
||||||
|
"title": "Animation",
|
||||||
|
"text": "Herausstechen und Welten erschaffen."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"color": "orange"
|
||||||
|
},
|
||||||
|
"content": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tpl": "service_item",
|
||||||
|
"copy": {
|
||||||
|
"de": {
|
||||||
|
"title": "Sound",
|
||||||
|
"text": "Keine Musik wäre wie Butter ohne Brot."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"color": "yellow"
|
||||||
|
},
|
||||||
|
"content": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tpl": "work",
|
"tpl": "work",
|
||||||
@@ -34,7 +103,8 @@
|
|||||||
"h2": "Imagefilm",
|
"h2": "Imagefilm",
|
||||||
"text": "Schüco Stories auf den schwedischen Inseln in der Nähe von Stockholm. Bei diesem Bauprojekt wurde das komplette vorhaben von der Entstehung bis zum fertigen Objekt filmisch begleitet."
|
"text": "Schüco Stories auf den schwedischen Inseln in der Nähe von Stockholm. Bei diesem Bauprojekt wurde das komplette vorhaben von der Entstehung bis zum fertigen Objekt filmisch begleitet."
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"content": {}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tpl": "work_entry",
|
"tpl": "work_entry",
|
||||||
@@ -46,7 +116,8 @@
|
|||||||
"h2": "Artwork Film",
|
"h2": "Artwork Film",
|
||||||
"text": "Seit 25 Jahren bringt DansArt Tanz und Kultur nach Bielefeld. In vier Tanzstudios und einem eigenen Theater finden regelmäßig Tanzkurse, Ausbildungen für angehende Profitänzer *innen, Festivals, Workshops, Performances und Konzerte statt."
|
"text": "Seit 25 Jahren bringt DansArt Tanz und Kultur nach Bielefeld. In vier Tanzstudios und einem eigenen Theater finden regelmäßig Tanzkurse, Ausbildungen für angehende Profitänzer *innen, Festivals, Workshops, Performances und Konzerte statt."
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"content": {}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tpl": "work_entry",
|
"tpl": "work_entry",
|
||||||
@@ -58,7 +129,8 @@
|
|||||||
"h2": "Imagefilm",
|
"h2": "Imagefilm",
|
||||||
"text": "Neubau, Erweiterung und Renovation – das sind die Geschäftsfelder von H.O. Schlüter. Die H.O. Schlüter GmbH arbeitet als Partner zusammen mit Schüco International KG. Der Metallbau Lübz stellt sich in diesem Unternehmensfilm vor."
|
"text": "Neubau, Erweiterung und Renovation – das sind die Geschäftsfelder von H.O. Schlüter. Die H.O. Schlüter GmbH arbeitet als Partner zusammen mit Schüco International KG. Der Metallbau Lübz stellt sich in diesem Unternehmensfilm vor."
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"content": {}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tpl": "work_entry",
|
"tpl": "work_entry",
|
||||||
@@ -70,7 +142,8 @@
|
|||||||
"h2": "Commercial",
|
"h2": "Commercial",
|
||||||
"text": "Umbauten von Verbrennern zu Elektrofahrzeugen. ESDI EV Technologies ist eine Firma, die sich auf dem Schwerpunkt Elektroumbauten fokussiert hat. Mit Tesla-Technik, Nissan Leaf oder vielen weiteren baut ESDI EV VW Käfer, Porsche, Mini Cooper und mehr zu Elektrofahrzeugen."
|
"text": "Umbauten von Verbrennern zu Elektrofahrzeugen. ESDI EV Technologies ist eine Firma, die sich auf dem Schwerpunkt Elektroumbauten fokussiert hat. Mit Tesla-Technik, Nissan Leaf oder vielen weiteren baut ESDI EV VW Käfer, Porsche, Mini Cooper und mehr zu Elektrofahrzeugen."
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"content": {}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tpl": "work_entry",
|
"tpl": "work_entry",
|
||||||
@@ -82,7 +155,8 @@
|
|||||||
"h2": "Imagefilm",
|
"h2": "Imagefilm",
|
||||||
"text": "GOLDBECK und Schüco, das Fenstersystem AWE80 in der Entwicklung und Produktion in Bielefeld."
|
"text": "GOLDBECK und Schüco, das Fenstersystem AWE80 in der Entwicklung und Produktion in Bielefeld."
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"content": {}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tpl": "work_entry",
|
"tpl": "work_entry",
|
||||||
@@ -94,7 +168,8 @@
|
|||||||
"h2": "Porträtfilm",
|
"h2": "Porträtfilm",
|
||||||
"text": "Digitalisierung im Metallbau - Die berühmt-berüchtigte Industrie 4.0."
|
"text": "Digitalisierung im Metallbau - Die berühmt-berüchtigte Industrie 4.0."
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"content": {}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tpl": "work_entry",
|
"tpl": "work_entry",
|
||||||
@@ -106,7 +181,8 @@
|
|||||||
"h2": "Kampagne",
|
"h2": "Kampagne",
|
||||||
"text": "Azubi Recruiting Film für die Berufe Metallbauer, Metalltechnik, Technischer Systemplaner, Büromanagement."
|
"text": "Azubi Recruiting Film für die Berufe Metallbauer, Metalltechnik, Technischer Systemplaner, Büromanagement."
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"content": {}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tpl": "work_entry",
|
"tpl": "work_entry",
|
||||||
@@ -118,16 +194,33 @@
|
|||||||
"h2": "Eventfilm",
|
"h2": "Eventfilm",
|
||||||
"text": "50 führende Familienunternehmen aus ganz Deutschland zum Karrieretag Familienunternehmen in Bielefeld bei Schüco - Miele, Hilti, Haribo und viele mehr."
|
"text": "50 führende Familienunternehmen aus ganz Deutschland zum Karrieretag Familienunternehmen in Bielefeld bei Schüco - Miele, Hilti, Haribo und viele mehr."
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"content": {}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"copy": {
|
||||||
|
"de": {
|
||||||
|
"headline": "Referenzen",
|
||||||
|
"text": "<div>Popcorn bereit? Eine Auswahl unserer Lieblingsprojekte.</div>"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tpl": "insta"
|
"tpl": "insta",
|
||||||
|
"copy": {
|
||||||
|
"de": {
|
||||||
|
"headline": "Hinter den Kulissen"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{"ref": "footer"},
|
"content": {}
|
||||||
{"ref": "end"}
|
},
|
||||||
|
{
|
||||||
|
"ref": "footer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ref": "end"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -34,5 +34,9 @@
|
|||||||
"analytics": {
|
"analytics": {
|
||||||
"provider": "pirsch",
|
"provider": "pirsch",
|
||||||
"client_secret": ""
|
"client_secret": ""
|
||||||
|
},
|
||||||
|
"ui": {
|
||||||
|
"path": "/admin",
|
||||||
|
"admin_password": "${ADMIN_PASSWORD}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
var controller = new ScrollMagic.Controller();
|
|
||||||
|
|
||||||
var backgroundColor = new TweenMax.to(".bg-beige-to-black", 1, {
|
|
||||||
backgroundColor: "#000",
|
|
||||||
ease: Power1.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var backgroundColorScene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#work",
|
|
||||||
duration: 256
|
|
||||||
})
|
|
||||||
.setTween(backgroundColor)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var textColor = new TweenMax.to(".black-to-beige", 1, {
|
|
||||||
color: "#f7eee0",
|
|
||||||
ease: Power1.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var textColorScene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#work",
|
|
||||||
duration: 256
|
|
||||||
})
|
|
||||||
.setTween(textColor)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
|
|
||||||
var reverseBackgroundColor = new TweenMax.to(".bg-beige-to-black", 1, {
|
|
||||||
backgroundColor: "#f7eee0",
|
|
||||||
ease: Power1.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var reverseBackgroundColorScene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#rental",
|
|
||||||
duration: 256
|
|
||||||
})
|
|
||||||
.setTween(reverseBackgroundColor)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var reverseTextColor = new TweenMax.to(".black-to-beige", 1, {
|
|
||||||
color: "#000",
|
|
||||||
ease: Power1.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var reverseTextColorScene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#rental",
|
|
||||||
duration: 256
|
|
||||||
})
|
|
||||||
.setTween(reverseTextColor)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -1 +1 @@
|
|||||||
(()=>{console.log("Hi!");})();
|
(()=>{function a(t){let e=t.querySelector(".nav__toggle");if(!e)return;let n=o=>{t.classList.toggle("nav--open",o),e.setAttribute("aria-expanded",String(o))};e.addEventListener("click",()=>n(!t.classList.contains("nav--open"))),t.querySelectorAll(".nav__link").forEach(o=>o.addEventListener("click",()=>n(!1))),t.addEventListener("keydown",o=>{o.key==="Escape"&&(n(!1),e.focus())})}var i=null;function g(){return i||(i=new IntersectionObserver(t=>{t.forEach(e=>{e.isIntersecting&&(e.target.classList.add("is-visible"),i.unobserve(e.target))})},{rootMargin:"0px 0px -8% 0px",threshold:.05})),i}function c(t){if(!("IntersectionObserver"in window)){t.classList.add("is-visible");return}g().observe(t)}function s(t){return String(t).padStart(2,"0")}function d(t){let e=performance.now(),n=o=>{if(!t.isConnected)return;let r=Math.floor((o-e)/1e3*25),l=r%25,m=Math.floor(r/25)%60,v=Math.floor(r/1500)%60,p=Math.floor(r/(25*3600));t.textContent=`${s(p)}:${s(v)}:${s(m)}:${s(l)}`,requestAnimationFrame(n)};requestAnimationFrame(n)}document.documentElement.classList.add("js");var b={nav:a,reveal:c,timecode:d};function f(t=document){t.querySelectorAll("[data-component]").forEach(e=>{if(e.dataset.componentReady)return;let n=b[e.dataset.component];n&&(n(e),e.dataset.componentReady="true")})}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",u):u();function u(){f(),new MutationObserver(()=>f()).observe(document.body,{childList:!0,subtree:!0})}})();
|
||||||
|
|||||||
@@ -1,532 +0,0 @@
|
|||||||
var offset = window.screen.width > 512 ? 20 : 10;
|
|
||||||
|
|
||||||
var controller = new ScrollMagic.Controller();
|
|
||||||
|
|
||||||
var part2 = new TweenMax.from("#part2", 1, {
|
|
||||||
x: "-100vw",
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part2Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
})
|
|
||||||
.setTween(part2)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part3 = new TweenMax.from("#part3", 1, {
|
|
||||||
x: "-100vw",
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part3Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: this.offset
|
|
||||||
})
|
|
||||||
.setTween(part3)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part4 = new TweenMax.from("#part4", 1, {
|
|
||||||
x: "-100vw",
|
|
||||||
y: "100%",
|
|
||||||
rotation: 2,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part4Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 2*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part4)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part5 = new TweenMax.from("#part5", 1, {
|
|
||||||
x: "100vw",
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part5Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250
|
|
||||||
})
|
|
||||||
.setTween(part5)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part6 = new TweenMax.from("#part6", 1, {
|
|
||||||
x: "100vw",
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part6Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 3*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part6)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part7 = new TweenMax.from("#part7", 1, {
|
|
||||||
x: "100vw",
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part7Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 4*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part7)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part8 = new TweenMax.from("#part8", 1, {
|
|
||||||
x: "-100vw",
|
|
||||||
y: "200%",
|
|
||||||
rotation: 4,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part8Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 5*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part8)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part9 = new TweenMax.from("#part9", 1, {
|
|
||||||
x: "-100vw",
|
|
||||||
y: "300%",
|
|
||||||
rotation: 4,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part9Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 5*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part9)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part10 = new TweenMax.from("#part10", 1, {
|
|
||||||
x: "100vw",
|
|
||||||
y: "600%",
|
|
||||||
rotation: -12,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part10Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 6*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part10)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part11 = new TweenMax.from("#part11", 1, {
|
|
||||||
x: "-100vw",
|
|
||||||
y: "800%",
|
|
||||||
rotation: 12,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part11Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 7*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part11)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part12 = new TweenMax.from("#part12", 1, {
|
|
||||||
x: "100vw",
|
|
||||||
y: "500%",
|
|
||||||
rotation: -16,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part12Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 8*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part12)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part13 = new TweenMax.from("#part13", 1, {
|
|
||||||
x: "100vw",
|
|
||||||
y: "400%",
|
|
||||||
rotation: -24,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part13Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 9*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part13)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part14 = new TweenMax.from("#part14", 1, {
|
|
||||||
x: "-100vw",
|
|
||||||
y: "400%",
|
|
||||||
rotation: 24,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part14Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 10*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part14)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part15 = new TweenMax.from("#part15", 1, {
|
|
||||||
x: "-100vw",
|
|
||||||
y: "400%",
|
|
||||||
rotation: 24,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part15Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 11*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part15)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part16 = new TweenMax.from("#part16", 1, {
|
|
||||||
x: "100vw",
|
|
||||||
y: "400%",
|
|
||||||
rotation: 24,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part16Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 12*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part16)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part17 = new TweenMax.from("#part17", 1, {
|
|
||||||
x: "-100vw",
|
|
||||||
y: "400%",
|
|
||||||
rotation: 24,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part17Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 13*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part17)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part181 = new TweenMax.from("#part18-1", 1, {
|
|
||||||
x: "100vw",
|
|
||||||
y: "800%",
|
|
||||||
rotation: -32,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part181Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 14*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part181)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part182 = new TweenMax.from("#part18-2", 1, {
|
|
||||||
x: "100vw",
|
|
||||||
y: "800%",
|
|
||||||
rotation: -32,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part182Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 15*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part182)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part191 = new TweenMax.from("#part19-1", 1, {
|
|
||||||
x: "-100vw",
|
|
||||||
y: "800%",
|
|
||||||
rotation: 32,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part191Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 16*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part191)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part192 = new TweenMax.from("#part19-2", 1, {
|
|
||||||
x: "-100vw",
|
|
||||||
y: "800%",
|
|
||||||
rotation: 32,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part192Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 18*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part192)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part20 = new TweenMax.from("#part20", 1, {
|
|
||||||
x: "100vw",
|
|
||||||
y: "800%",
|
|
||||||
rotation: -32,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part20Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 19*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part20)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part21 = new TweenMax.from("#part21", 1, {
|
|
||||||
x: "-100vw",
|
|
||||||
y: "800%",
|
|
||||||
rotation: 32,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part21Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 20*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part21)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part22 = new TweenMax.from("#part22", 1, {
|
|
||||||
x: "100vw",
|
|
||||||
y: "800%",
|
|
||||||
rotation: -32,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part22Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 21*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part22)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part23 = new TweenMax.from("#part23", 1, {
|
|
||||||
x: "-100vw",
|
|
||||||
y: "2400%",
|
|
||||||
rotation: 32,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part23Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 22*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part23)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part24 = new TweenMax.from("#part24", 1, {
|
|
||||||
x: "100vw",
|
|
||||||
y: "1000%",
|
|
||||||
rotation: -32,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part24Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 23*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part24)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part25 = new TweenMax.from("#part25", 1, {
|
|
||||||
x: "-100vw",
|
|
||||||
y: "1000%",
|
|
||||||
rotation: 32,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part25Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 24*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part25)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part26 = new TweenMax.from("#part26", 1, {
|
|
||||||
x: "100vw",
|
|
||||||
y: "1000%",
|
|
||||||
rotation: -32,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part26Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 25*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part26)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part27 = new TweenMax.from("#part27", 1, {
|
|
||||||
x: "-100vw",
|
|
||||||
y: "1600%",
|
|
||||||
rotation: 32,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part27Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 26*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part27)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part28 = new TweenMax.from("#part28", 1, {
|
|
||||||
x: "100vw",
|
|
||||||
y: "1600%",
|
|
||||||
rotation: -32,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part28Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 33*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part28)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part291 = new TweenMax.from("#part29-1", 1, {
|
|
||||||
x: "-100vw",
|
|
||||||
y: "1600%",
|
|
||||||
rotation: 32,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part291Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 32*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part291)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part292 = new TweenMax.from("#part29-2", 1, {
|
|
||||||
x: "-100vw",
|
|
||||||
y: "1600%",
|
|
||||||
rotation: 32,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part292Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 31*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part292)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part30 = new TweenMax.from("#part30", 1, {
|
|
||||||
x: "100vw",
|
|
||||||
y: "1600%",
|
|
||||||
rotation: -32,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part30Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 34*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part30)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part311 = new TweenMax.from("#part31-1", 1, {
|
|
||||||
x: "-100vw",
|
|
||||||
y: "3200%",
|
|
||||||
rotation: 32,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part311Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 30*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part311)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part312 = new TweenMax.from("#part31-2", 1, {
|
|
||||||
x: "-100vw",
|
|
||||||
y: "3200%",
|
|
||||||
rotation: 32,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part312Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 29*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part312)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part321 = new TweenMax.from("#part32-1", 1, {
|
|
||||||
x: "-100vw",
|
|
||||||
y: "3200%",
|
|
||||||
rotation: 32,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part321Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 28*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part321)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
var part322 = new TweenMax.from("#part32-2", 1, {
|
|
||||||
x: "-100vw",
|
|
||||||
y: "3200%",
|
|
||||||
rotation: 32,
|
|
||||||
ease: Power2.easeOut
|
|
||||||
});
|
|
||||||
|
|
||||||
var part322Scene = new ScrollMagic.Scene({
|
|
||||||
triggerElement: "#parts",
|
|
||||||
duration: 250,
|
|
||||||
offset: 27*this.offset
|
|
||||||
})
|
|
||||||
.setTween(part322)
|
|
||||||
.addTo(controller);
|
|
||||||
|
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
|
{{ adminBody .Page }}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+32
-109
@@ -1,111 +1,34 @@
|
|||||||
<footer id="footer">
|
{{- $headline := default (copy .Page .Content "headline") "Und… Action?" -}}
|
||||||
<div class="container">
|
{{- $text := default (copy .Page .Content "text") "Erzähl uns von deiner Idee – wir machen einen Film daraus." -}}
|
||||||
<ul>
|
{{- $email := default (get .Content "email") "hi@schnittfest.gmbh" -}}
|
||||||
<li>© 2024 Schnittfest GmbH</li>
|
{{- $phone := default (get .Content "phone") "+49 176 93124984" -}}
|
||||||
<li>
|
{{- $instagram := default (get .Content "instagram") "https://instagram.com/schnittfest.gmbh" -}}
|
||||||
<a href="tel:+49017693124984">+49 176 93124984</a>
|
{{- $vimeo := default (get .Content "vimeo") "https://vimeo.com/schnittfest" -}}
|
||||||
</li>
|
{{- $copyright := default (copy .Page .Content "copyright") "Schnittfest GmbH" -}}
|
||||||
<li>
|
|
||||||
<a href="mailto:hi@schnitffest.gmbh">hi@schnittfest.gmbh</a>
|
<footer class="footer" id="footer" data-shifu-element="{{ .Content.Position }}">
|
||||||
</li>
|
<div class="footer__inner">
|
||||||
<li>
|
<div class="footer__cta" data-component="reveal">
|
||||||
<a href="https://instagram.com/schnittfest.gmbh">Instagram</a>
|
<h2 class="footer__headline">{{ $headline }}</h2>
|
||||||
</li>
|
<p class="footer__text">{{ $text }}</p>
|
||||||
<li>
|
<a class="button button--yellow footer__mail" href="mailto:{{ $email }}">
|
||||||
<a href="https://vimeo.com/schnittfest">Vimeo</a>
|
<span class="button__play" aria-hidden="true"></span>{{ $email }}
|
||||||
</li>
|
</a>
|
||||||
<li>
|
</div>
|
||||||
<a href="/agb" target="_blank">AGB</a>
|
|
||||||
</li>
|
<dl class="credits" data-component="reveal">
|
||||||
<li>
|
<div class="credits__row"><dt>Telefon</dt><dd><a href="tel:{{ $phone | replace " " "" }}">{{ $phone }}</a></dd></div>
|
||||||
<a href="/impressum" target="_blank">Impressum</a>
|
<div class="credits__row"><dt>E-Mail</dt><dd><a href="mailto:{{ $email }}">{{ $email }}</a></dd></div>
|
||||||
</li>
|
<div class="credits__row"><dt>Instagram</dt><dd><a href="{{ $instagram }}" target="_blank" rel="noopener">schnittfest.gmbh</a></dd></div>
|
||||||
</ul>
|
<div class="credits__row"><dt>Vimeo</dt><dd><a href="{{ $vimeo }}" target="_blank" rel="noopener">schnittfest</a></dd></div>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
<div class="footer__bottom">
|
||||||
|
<span>© {{ year }} {{ $copyright }}</span>
|
||||||
|
<span class="footer__legal">
|
||||||
|
<a href="/agb">AGB</a>
|
||||||
|
<a href="/impressum">Impressum</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<script type="text/javascript" src="https://player.vimeo.com/api/player.js"></script>
|
|
||||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.0.4/gsap.min.js"></script>
|
|
||||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.7/ScrollMagic.min.js"></script>
|
|
||||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.7/plugins/animation.gsap.min.js"></script>
|
|
||||||
<script type="text/javascript" src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
|
|
||||||
<script type="text/javascript" src="https://cdn.lightwidget.com/widgets/lightwidget.js"></script>
|
|
||||||
<script type="text/javascript" src="static/js/color.js"></script>
|
|
||||||
<script type="text/javascript" src="static/js/parts.js"></script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
AOS.init({
|
|
||||||
duration: 1000,
|
|
||||||
easing: "cubic-bezier(0.4, 0.0, 0.2, 1)",
|
|
||||||
once: true,
|
|
||||||
offset: 32
|
|
||||||
});
|
|
||||||
|
|
||||||
// navbar mobile menu
|
|
||||||
let mobileMenu = document.getElementById("mobileMenu");
|
|
||||||
let mobileMenuOpen = document.getElementById("mobileMenuOpen");
|
|
||||||
let mobileMenuClose = document.getElementById("mobileMenuClose");
|
|
||||||
|
|
||||||
function toggleMobileMenu() {
|
|
||||||
let hidden = mobileMenu.style.display;
|
|
||||||
|
|
||||||
if(hidden) {
|
|
||||||
mobileMenu.style.display = "";
|
|
||||||
} else {
|
|
||||||
mobileMenu.style.display = "none"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mobileMenuOpen.addEventListener("click", e => {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
toggleMobileMenu();
|
|
||||||
});
|
|
||||||
|
|
||||||
// scroll to from navigation
|
|
||||||
let scrollToService = document.getElementsByClassName("scrollToService");
|
|
||||||
let scrollToWork = document.getElementsByClassName("scrollToWork");
|
|
||||||
let scrollToRental = document.getElementsByClassName("scrollToRental");
|
|
||||||
let scrollToFooter = document.getElementsByClassName("scrollToFooter");
|
|
||||||
|
|
||||||
function addScrollTo(nodes, anchor) {
|
|
||||||
for (let node of nodes) {
|
|
||||||
node.addEventListener("click", () => {
|
|
||||||
toggleMobileMenu();
|
|
||||||
let section = document.getElementById(anchor);
|
|
||||||
|
|
||||||
if (window.location.pathname === "/") {
|
|
||||||
window.scrollTo({top: section.offsetTop, behavior: "smooth"});
|
|
||||||
} else {
|
|
||||||
window.location = `/#${anchor}`;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener("click", e => {
|
|
||||||
if(!mobileMenu.style.display) {
|
|
||||||
mobileMenu.style.display = "none"
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
addScrollTo(scrollToService, "service");
|
|
||||||
addScrollTo(scrollToWork, "work");
|
|
||||||
addScrollTo(scrollToRental, "rental");
|
|
||||||
addScrollTo(scrollToFooter, "footer");
|
|
||||||
|
|
||||||
// click on logo navigation
|
|
||||||
let homeLink = document.getElementById("homeLink");
|
|
||||||
|
|
||||||
homeLink.addEventListener("click", e => {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
|
|
||||||
if(window.location.pathname === "/") {
|
|
||||||
window.scrollTo({top: 0, behavior: "smooth"});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
window.location = "/";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|||||||
+25
-25
@@ -1,37 +1,37 @@
|
|||||||
|
{{- $title := default (copy .Page .Content "title") "Schnittfest – Film, auf den Frame genau." -}}
|
||||||
|
{{- $description := default (copy .Page .Content "meta_description") "Film, Animation und Sound aus Ostwestfalen. Schnittfest produziert Imagefilme, Commercials und Kampagnen – auf den Frame genau." -}}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="de">
|
<html lang="{{ .Page.Language }}">
|
||||||
<head>
|
<head>
|
||||||
<base href="/" />
|
<base href="/" />
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>{{ $title }}</title>
|
||||||
|
<meta name="description" content="{{ $description }}" />
|
||||||
<meta name="copyright" content="Schnittfest GmbH" />
|
<meta name="copyright" content="Schnittfest GmbH" />
|
||||||
<meta name="author" content="Emvi Software GmbH" />
|
<meta name="author" content="Emvi Software GmbH" />
|
||||||
<meta name="title" content="Schnittfest" />
|
<meta name="theme-color" content="#0e0c0b" />
|
||||||
<meta name="description" content="Film, auf den Frame genau." />
|
<meta name="msapplication-TileColor" content="#0e0c0b" />
|
||||||
<meta name="msapplication-TileColor" content="#000000" />
|
<meta name="apple-mobile-web-app-title" content="Schnittfest" />
|
||||||
<meta name="theme-color" content="#000000" />
|
<meta name="application-name" content="Schnittfest" />
|
||||||
<meta name="twitter:card" content="product" />
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
<meta name="twitter:title" content="Schnittfest" />
|
<meta name="twitter:title" content="{{ $title }}" />
|
||||||
<meta name="twitter:description" content="Film, auf den Frame genau." />
|
<meta name="twitter:description" content="{{ $description }}" />
|
||||||
<meta name="twitter:image" content="/static/1.jpg" />
|
<meta name="twitter:image" content="{{ hostname }}/static/1.jpg" />
|
||||||
<meta property="og:url" content="https://schnittfest.gmbh/" />
|
<meta property="og:url" content="{{ .Page.CanonicalLink }}" />
|
||||||
<meta property="og:title" content="Schnittfest" />
|
<meta property="og:title" content="{{ $title }}" />
|
||||||
<meta property="og:description" content="Film, auf den Frame genau." />
|
<meta property="og:description" content="{{ $description }}" />
|
||||||
<meta property="og:image" content="/static/1.jpg" />
|
<meta property="og:image" content="{{ hostname }}/static/1.jpg" />
|
||||||
|
<link rel="canonical" href="{{ .Page.CanonicalLink }}" />
|
||||||
<link rel="stylesheet" type="text/css" href="/static/web/main.css" />
|
|
||||||
<link rel="stylesheet" type="text/css" href="/static/web/manrope.css" />
|
|
||||||
<link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet" />
|
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/static/favicon/apple-touch-icon.png" />
|
<link rel="apple-touch-icon" sizes="180x180" href="/static/favicon/apple-touch-icon.png" />
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon/favicon-32x32.png" />
|
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon/favicon-32x32.png" />
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="/static/favicon/favicon-16x16.png" />
|
<link rel="icon" type="image/png" sizes="16x16" href="/static/favicon/favicon-16x16.png" />
|
||||||
<link rel="mask-icon" href="/static/favicon/safari-pinned-tab.svg" color="#000000" />
|
<link rel="mask-icon" href="/static/favicon/safari-pinned-tab.svg" color="#0e0c0b" />
|
||||||
<link rel="shortcut icon" href="/static/favicon/favicon.ico" />
|
<link rel="shortcut icon" href="/static/favicon/favicon.ico" />
|
||||||
<meta name="apple-mobile-web-app-title" content="Schnittfest" />
|
<link rel="preload" href="/static/fonts/Manrope-ExtraBold.woff2" as="font" type="font/woff2" crossorigin />
|
||||||
<meta name="application-name" content="Schnittfest" />
|
<link rel="stylesheet" href="/static/web/manrope.css" />
|
||||||
<meta name="msapplication-TileColor" content="#000000" />
|
<link rel="stylesheet" href="/static/web/main.css?v={{ .CMS.LastUpdate }}" />
|
||||||
<meta name="theme-color" content="#000000" />
|
<script defer src="/static/web/main.min.js?v={{ .CMS.LastUpdate }}"></script>
|
||||||
|
{{ adminHead .Page }}
|
||||||
<title>Schnittfest</title>
|
|
||||||
</head>
|
</head>
|
||||||
<body class="bg-beige-to-black">
|
<body>
|
||||||
|
|||||||
+13
-3
@@ -1,6 +1,16 @@
|
|||||||
<section id="instagram" class="section-instagram">
|
{{- $headline := default (copy .Page .Content "headline") "Hinter den Kulissen" -}}
|
||||||
<div class="container">
|
{{- $widget := default (get .Content "widget") "https://cdn.lightwidget.com/widgets/ea2fc8dd2d55541dbafdc312dbe28aee.html" -}}
|
||||||
|
{{- $profile := default (get .Content "profile") "https://instagram.com/schnittfest.gmbh" -}}
|
||||||
|
|
||||||
|
<section class="insta" id="instagram" data-shifu-element="{{ .Content.Position }}">
|
||||||
|
<div class="insta__inner">
|
||||||
|
<div class="insta__head" data-component="reveal">
|
||||||
|
<h2 class="section-title"><span class="section-title__nr">03</span>{{ $headline }}</h2>
|
||||||
|
<a class="button button--outline" href="{{ $profile }}" target="_blank" rel="noopener">@schnittfest.gmbh</a>
|
||||||
|
</div>
|
||||||
|
<div class="insta__frame" data-component="reveal">
|
||||||
<script src="https://cdn.lightwidget.com/widgets/lightwidget.js"></script>
|
<script src="https://cdn.lightwidget.com/widgets/lightwidget.js"></script>
|
||||||
<iframe src="https://cdn.lightwidget.com/widgets/ea2fc8dd2d55541dbafdc312dbe28aee.html" scrolling="no" allowtransparency="true" class="lightwidget-widget" style="width:100%;border:0;overflow:hidden;"></iframe>
|
<iframe src="{{ $widget }}" scrolling="no" allowtransparency="true" class="lightwidget-widget insta__widget" title="Instagram"></iframe>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
+34
-9
@@ -1,13 +1,38 @@
|
|||||||
<section id="start" class="section-start">
|
{{- $headline := default (copy .Page .Content "headline") "Film, auf den Frame genau." -}}
|
||||||
<div class="container" data-aos="fade-in">
|
{{- $kicker := default (copy .Page .Content "kicker") "Videoproduktion aus Ostwestfalen" -}}
|
||||||
<div class="headline">
|
{{- $ctaLabel := default (copy .Page .Content "cta_label") "Projekt anfragen" -}}
|
||||||
<h1 data-aos="fade-in">
|
{{- $ctaHref := default (copy .Page .Content "cta_href") "mailto:hi@schnittfest.gmbh" -}}
|
||||||
Film, auf den Frame genau.
|
{{- $ticker := default (copy .Page .Content "ticker") "Film ✦ Animation ✦ Sound ✦ Schnitt ✦ Color Grading ✦ Drohne ✦ Imagefilm ✦ Commercial ✦" -}}
|
||||||
<a href="mailto:hi@schnittfest.gmbh">⟶</a>
|
{{- $video := default (get .Content "video") "/static/hero.mp4" -}}
|
||||||
</h1>
|
{{- $poster := default (get .Content "poster") "/static/1.jpg" -}}
|
||||||
|
|
||||||
|
<section class="intro" id="start" data-shifu-element="{{ .Content.Position }}">
|
||||||
|
<div class="intro__inner">
|
||||||
|
<p class="intro__kicker" data-component="reveal"><span class="intro__kicker-dot"></span>{{ $kicker }}</p>
|
||||||
|
<h1 class="intro__headline" data-component="reveal">{{ $headline }}</h1>
|
||||||
|
<div class="intro__cta" data-component="reveal">
|
||||||
|
<a class="button button--yellow" href="{{ $ctaHref }}"><span class="button__play" aria-hidden="true"></span>{{ $ctaLabel }}</a>
|
||||||
</div>
|
</div>
|
||||||
<div id="hero" class="hero" data-aos="fade-in" data-aos-delay="200">
|
|
||||||
<video src="/static/hero.mp4" autoplay loop muted playsinline />
|
<div class="viewfinder" data-component="reveal">
|
||||||
|
<video class="viewfinder__video" src="{{ $video }}" poster="{{ $poster }}" autoplay loop muted playsinline></video>
|
||||||
|
<div class="viewfinder__overlay" aria-hidden="true">
|
||||||
|
<span class="viewfinder__corner viewfinder__corner--tl"></span>
|
||||||
|
<span class="viewfinder__corner viewfinder__corner--tr"></span>
|
||||||
|
<span class="viewfinder__corner viewfinder__corner--bl"></span>
|
||||||
|
<span class="viewfinder__corner viewfinder__corner--br"></span>
|
||||||
|
<span class="viewfinder__rec">REC</span>
|
||||||
|
<span class="viewfinder__timecode" data-component="timecode">00:00:00:00</span>
|
||||||
|
<span class="viewfinder__meta">4K · 25 FPS · ISO 800</span>
|
||||||
|
<span class="viewfinder__battery"></span>
|
||||||
|
<span class="viewfinder__focus"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ticker" aria-hidden="true">
|
||||||
|
<div class="ticker__track">
|
||||||
|
<span>{{ $ticker }}</span><span>{{ $ticker }}</span><span>{{ $ticker }}</span><span>{{ $ticker }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
<section id="text" class="section-text">
|
<section class="text" id="text" data-shifu-element="{{ .Content.Position }}">
|
||||||
<div class="container">
|
<div class="text__inner">
|
||||||
<h3>Impressum</h3>
|
<h3>Impressum</h3>
|
||||||
<p>
|
<p>
|
||||||
Schnittfest GmbH<br>
|
Schnittfest GmbH<br>
|
||||||
|
|||||||
+23
-26
@@ -1,28 +1,25 @@
|
|||||||
{{if get .Content "full"}}
|
{{- $full := get .Content "full" -}}
|
||||||
<nav class="header bg-beige-to-black">
|
{{- $service := default (copy .Page .Content "service_label") "Gewerke" -}}
|
||||||
<div class="container" data-aos="fade-in" data-aos-delay="50">
|
{{- $work := default (copy .Page .Content "work_label") "Referenzen" -}}
|
||||||
<div id="homeLink" class="wordmark black-to-beige">Schnittfest</div>
|
{{- $contact := default (copy .Page .Content "contact_label") "Kontakt" -}}
|
||||||
<ul class="links hide-sm black-to-beige">
|
|
||||||
<li class="scrollToService">Gewerke</li>
|
<header class="nav{{ if $full }} nav--full{{ end }}" data-component="nav" data-shifu-element="{{ .Content.Position }}">
|
||||||
<li class="scrollToWork">Referenzen</li>
|
<div class="nav__inner">
|
||||||
<li class="scrollToFooter">Kontakt</li>
|
<a class="nav__brand" href="/" aria-label="Schnittfest – Startseite">
|
||||||
</ul>
|
<span class="nav__rec" aria-hidden="true"></span>
|
||||||
<ul class="show-sm black-to-beige">
|
<span class="nav__word">Schnitt<span class="nav__cut" aria-hidden="true">✂</span>fest</span>
|
||||||
<li id="mobileMenuOpen">Menü</li>
|
</a>
|
||||||
</ul>
|
{{ if $full }}
|
||||||
</div>
|
<button class="nav__toggle" type="button" aria-expanded="false" aria-controls="nav-links">
|
||||||
</nav>
|
<span class="nav__toggle-bar"></span>
|
||||||
<nav id="mobileMenu" class="mobile-menu show-sm" style="display:none">
|
<span class="nav__toggle-bar"></span>
|
||||||
<ul>
|
<span class="visually-hidden">Menü</span>
|
||||||
<li class="scrollToService">Gewerke</li>
|
</button>
|
||||||
<li class="scrollToWork">Referenzen</li>
|
<nav class="nav__links" id="nav-links">
|
||||||
<li class="scrollToFooter">Kontakt</li>
|
<a class="nav__link" href="/#service" data-nr="01">{{ $service }}</a>
|
||||||
</ul>
|
<a class="nav__link" href="/#work" data-nr="02">{{ $work }}</a>
|
||||||
</nav>
|
<a class="nav__link nav__link--cta" href="/#footer" data-nr="03">{{ $contact }}</a>
|
||||||
{{else}}
|
|
||||||
<nav class="header bg-beige">
|
|
||||||
<div class="container">
|
|
||||||
<div id="homeLink" class="wordmark">Schnittfest</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
</nav>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|||||||
+19
-11
@@ -1,15 +1,23 @@
|
|||||||
<section id="service" class="section-service bg-beige">
|
{{- $headline := default (copy .Page .Content "headline") "Gewerke" -}}
|
||||||
<div class="container">
|
{{- $text := copy .Page .Content "text" -}}
|
||||||
<div class="services row">
|
{{- $image := default (get .Content "image") "/static/1.jpg" -}}
|
||||||
<div class="col-lg-4 col-md-4 col-sm-12 col-xs-12">
|
{{- $caption := copy .Page .Content "image_caption" -}}
|
||||||
<h2 class="black-to-beige" data-aos="fade-in" data-aos-delay="100">Film</h2>
|
|
||||||
<p class="black-to-beige" data-aos="fade-in" data-aos-delay="100">sleep.shoot.eat.repeat. </p>
|
<section class="service" id="service" data-shifu-element="{{ .Content.Position }}">
|
||||||
<h2 class="black-to-beige" data-aos="fade-in" data-aos-delay="200">Animation</h2>
|
<div class="service__inner">
|
||||||
<p class="black-to-beige" data-aos="fade-in" data-aos-delay="200">Herausstechen und Welten erschaffen.</p>
|
<div class="service__head" data-component="reveal">
|
||||||
<h2 class="black-to-beige" data-aos="fade-in" data-aos-delay="300">Sound</h2>
|
<h2 class="section-title"><span class="section-title__nr">01</span>{{ $headline }}</h2>
|
||||||
<p class="black-to-beige" data-aos="fade-in" data-aos-delay="300">Keine Musik wäre wie Butter ohne Brot.</p>
|
{{ with $text }}<div class="service__text">{{ html . }}</div>{{ end }}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-8 col-md-8 col-sm-12 col-xs-12 img" data-aos="fade-in"></div>
|
<div class="service__grid">
|
||||||
|
<div class="service__items">
|
||||||
|
{{ .CMS.Render .Args .Page (fmt "%s.items" .Content.Position) (index .Content.Content "items") }}
|
||||||
|
<slot name="{{ .Content.Position }}/items"></slot>
|
||||||
|
</div>
|
||||||
|
<figure class="polaroid" data-component="reveal">
|
||||||
|
<img class="polaroid__image" src="{{ $image }}" alt="{{ default $caption "Schnittfest am Set" }}" loading="lazy" />
|
||||||
|
{{ with $caption }}<figcaption class="polaroid__caption">{{ . }}</figcaption>{{ end }}
|
||||||
|
</figure>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{{- $title := copy .Page .Content "title" -}}
|
||||||
|
{{- $text := copy .Page .Content "text" -}}
|
||||||
|
{{- $color := default (get .Content "color") "red" -}}
|
||||||
|
|
||||||
|
<article class="slate slate--{{ $color }}" data-component="reveal" data-shifu-element="{{ .Content.Position }}">
|
||||||
|
<div class="slate__clapper" aria-hidden="true"></div>
|
||||||
|
<div class="slate__body">
|
||||||
|
{{ with $title }}<h3 class="slate__title">{{ . }}</h3>{{ end }}
|
||||||
|
{{ with $text }}<p class="slate__text">{{ . }}</p>{{ end }}
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
<section id="text" class="section-text">
|
<section class="text" id="text" data-shifu-element="{{ .Content.Position }}">
|
||||||
<div class="container">
|
<div class="text__inner">
|
||||||
<h3>Allgemeine Geschäftsbedingungen</h3>
|
<h3>Allgemeine Geschäftsbedingungen</h3>
|
||||||
<p>
|
<p>
|
||||||
Alle Preise verstehen sich zzgl. 3% Versicherungsgebühr und 19% MwSt.
|
Alle Preise verstehen sich zzgl. 3% Versicherungsgebühr und 19% MwSt.
|
||||||
|
|||||||
+15
-3
@@ -1,5 +1,17 @@
|
|||||||
<section id="work" class="section-work">
|
{{- $headline := default (copy .Page .Content "headline") "Referenzen" -}}
|
||||||
<div class="container">
|
{{- $text := copy .Page .Content "text" -}}
|
||||||
{{.CMS.Render .Args .Page (fmt "%s.content" .Content.Position) (index .Content.Content "content")}}
|
|
||||||
|
<section class="work" id="work" data-shifu-element="{{ .Content.Position }}">
|
||||||
|
<div class="filmstrip" aria-hidden="true"></div>
|
||||||
|
<div class="work__inner">
|
||||||
|
<div class="work__head" data-component="reveal">
|
||||||
|
<h2 class="section-title section-title--light"><span class="section-title__nr">02</span>{{ $headline }}</h2>
|
||||||
|
{{ with $text }}<div class="work__text">{{ html . }}</div>{{ end }}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="work__list">
|
||||||
|
{{ .CMS.Render .Args .Page (fmt "%s.content" .Content.Position) (index .Content.Content "content") }}
|
||||||
|
<slot name="{{ .Content.Position }}/content"></slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="filmstrip filmstrip--bottom" aria-hidden="true"></div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
+14
-9
@@ -1,11 +1,16 @@
|
|||||||
<div class="video row reverse">
|
{{- $title := copy .Page .Content "h2" -}}
|
||||||
<div class="col-lg-4 col-md-12 col-sm-12 col-xs-12">
|
{{- $text := copy .Page .Content "text" -}}
|
||||||
<h2 class="black-to-beige" data-aos="fade-in" data-aos-delay="100">{{copy .Page .Content "h2"}}</h2>
|
{{- $video := get .Content "video" -}}
|
||||||
<p class="black-to-beige" data-aos="fade-in" data-aos-delay="200">{{copy .Page .Content "text"}}</p>
|
|
||||||
</div>
|
<article class="take" data-component="reveal" data-shifu-element="{{ .Content.Position }}">
|
||||||
<div class="col-lg-8 col-md-12 col-sm-12 col-xs-12">
|
<div class="take__info">
|
||||||
<div style="padding:56.25% 0 0 0;position:relative;" data-aos="fade-in">
|
<span class="take__label" aria-hidden="true">Take</span>
|
||||||
<iframe src="{{get .Content "video"}}" style="position:absolute;top:0;left:0;width:100%;height:100%;" frameborder="0" allowfullscreen></iframe>
|
{{ with $title }}<h3 class="take__title">{{ . }}</h3>{{ end }}
|
||||||
</div>
|
{{ with $text }}<p class="take__text">{{ . }}</p>{{ end }}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="take__screen">
|
||||||
|
{{ with $video }}
|
||||||
|
<iframe class="take__video" src="{{ . }}" title="{{ default $title "Video" }}" loading="lazy" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen></iframe>
|
||||||
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
|
</article>
|
||||||
|
|||||||
Reference in New Issue
Block a user