Add Projects section with inverted pendulum and real-time interface pages
This commit is contained in:
1 parent
0097be4114
commit
0699938cd5
17 files changed
+357
No files matched your search
@@ -0,0 +1,60 @@
|
||||
<style>
|
||||
.project-filter { display: flex; flex-wrap: wrap; gap: .5em; justify-content: center; margin: 1.5em 0 1em; }
|
||||
.project-filter button {
|
||||
font: inherit; font-size: .9em; cursor: pointer; padding: .25em .9em;
|
||||
border: 1px solid #d5d8e0; border-radius: 999px; background: #fff; color: #34495e;
|
||||
}
|
||||
.project-filter button:hover { border-color: hsl(232, 61%, 64%); }
|
||||
.project-filter button.active { background: hsl(232, 61%, 64%); border-color: hsl(232, 61%, 64%); color: #fff; }
|
||||
|
||||
.project-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 1.5em; margin: 1.5em 0 2em; }
|
||||
.project-card {
|
||||
display: flex; flex-direction: column; background: #fff; border: 1px solid #e3e5ea; border-radius: 8px;
|
||||
overflow: hidden; transition: box-shadow .2s, transform .2s;
|
||||
}
|
||||
.project-card:hover { box-shadow: 0 6px 18px rgba(40, 50, 90, .12); transform: translateY(-2px); }
|
||||
.project-card[hidden] { display: none; }
|
||||
.project-card-cover { display: block; aspect-ratio: 16 / 10; background: #eef0f5; overflow: hidden; border: 0; }
|
||||
.project-card-cover:hover { border: 0; }
|
||||
.project-card-cover img { width: 100%; height: 100%; object-fit: cover; display: block; margin: 0; }
|
||||
.project-card-cover.placeholder { display: flex; align-items: center; justify-content: center; padding: 0 .5em; text-align: center; color: #fff; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 1.8em; font-weight: 600; background: linear-gradient(135deg, hsl(232, 61%, 64%), hsl(232, 45%, 38%)); }
|
||||
.project-card-cover.placeholder:hover { color: #fff; }
|
||||
.project-card-body { display: flex; flex-direction: column; gap: .5em; padding: 1em 1.1em 1.1em; flex: 1; }
|
||||
.project-card-title { margin: 0; font-size: 1.2em; line-height: 1.25; }
|
||||
.project-card-title a { color: inherit; border: 0; }
|
||||
.project-card-title a:hover { color: hsl(232, 61%, 64%); border: 0; }
|
||||
.project-card-summary { margin: 0; color: #4a5568; font-size: .95em; line-height: 1.5; flex: 1; }
|
||||
.project-card-footer { display: flex; align-items: center; justify-content: space-between; gap: .5em; font-size: .85em; margin-top: .3em; }
|
||||
.project-card-footer a { color: #c05b4d; white-space: nowrap; }
|
||||
|
||||
.project-tags { display: flex; flex-wrap: wrap; gap: .35em; }
|
||||
.project-tag {
|
||||
display: inline-block; padding: .05em .65em; font-size: .78em; font-weight: 600; letter-spacing: .02em;
|
||||
border-radius: 999px; background: hsl(232, 61%, 94%); color: hsl(232, 45%, 40%);
|
||||
}
|
||||
.project-status { font-size: .85em; color: #8a8a8a; }
|
||||
.project-status::before { content: ""; display: inline-block; width: .55em; height: .55em; border-radius: 50%; margin-right: .4em; background: #b0b4c0; }
|
||||
.project-status[data-status="active"]::before { background: #4caf7d; }
|
||||
.project-status[data-status="completed"]::before { background: hsl(232, 61%, 64%); }
|
||||
.project-status[data-status="in progress"]::before { background: #e0a030; }
|
||||
|
||||
.project-summary { text-align: center; font-size: 1.1em; color: #4a5568; max-width: 40em; margin: .4em auto 1em; }
|
||||
.project-header .project-tags { justify-content: center; }
|
||||
.project-meta { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: .6em 1.4em; margin: 1em 0 1.5em; font-size: .95em; color: #6b7280; }
|
||||
.project-btn {
|
||||
display: inline-block; padding: .35em 1em; border-radius: 4px; border: 1px solid hsl(232, 61%, 64%);
|
||||
color: hsl(232, 61%, 64%); font-size: .95em;
|
||||
}
|
||||
.project-btn:hover { background: hsl(232, 61%, 64%); color: #fff; border-color: hsl(232, 61%, 64%); }
|
||||
.project-btn.primary { background: hsl(232, 61%, 64%); color: #fff; }
|
||||
.project-btn.primary:hover { background: hsl(232, 61%, 54%); }
|
||||
.project-back { text-align: center; margin-top: 2em; }
|
||||
|
||||
.project-content figure, figure.project-video { margin: 1.5em auto; text-align: center; }
|
||||
.project-content figure img { max-width: 100%; height: auto; }
|
||||
figure.project-video video { display: block; margin: 0 auto; width: 100%; max-width: 420px; max-height: 75vh; background: #000; border-radius: 6px; }
|
||||
figure.project-video.wide video { max-width: 100%; }
|
||||
figure.project-video figcaption, .project-content figcaption { margin-top: .5em; font-size: .9em; color: #6b7280; }
|
||||
.project-content table { margin: 1em auto; }
|
||||
@media (max-width: 600px) { .project-grid { grid-template-columns: 1fr; } }
|
||||
</style>
|
||||
@@ -0,0 +1,31 @@
|
||||
{{ define "title" }}{{ .Title }} - {{ .Site.Title }}{{ end }}
|
||||
|
||||
{{ define "content" }}
|
||||
{{ partial "projects/styles.html" . }}
|
||||
<article class="post">
|
||||
{{- with .Content }}<div class="post-content">{{ . }}</div>{{ end }}
|
||||
|
||||
<div class="project-grid">
|
||||
{{- range .Pages.ByDate.Reverse }}
|
||||
{{- $cover := .Resources.GetMatch (.Params.cover | default "cover.*") -}}
|
||||
<div class="project-card">
|
||||
{{- if $cover }}
|
||||
<a class="project-card-cover" href="{{ .RelPermalink }}" tabindex="-1" aria-hidden="true">
|
||||
<img src="{{ $cover.RelPermalink }}" alt="" loading="lazy">
|
||||
</a>
|
||||
{{- else }}
|
||||
<a class="project-card-cover placeholder" href="{{ .RelPermalink }}" tabindex="-1" aria-hidden="true">{{ index (split .Title ":") 0 }}</a>
|
||||
{{- end }}
|
||||
<div class="project-card-body">
|
||||
<h2 class="project-card-title"><a href="{{ .RelPermalink }}">{{ .Title }}</a></h2>
|
||||
{{- with .Params.summary }}<p class="project-card-summary">{{ . }}</p>{{ end }}
|
||||
<div class="project-card-footer">
|
||||
{{- with .Params.status }}<span class="project-status" data-status="{{ . | lower }}">{{ . }}</span>{{ else }}<span></span>{{ end }}
|
||||
{{- with .Params.repo }}<a href="{{ . }}" target="_blank" rel="noopener">Source code ↗</a>{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{- end }}
|
||||
</div>
|
||||
</article>
|
||||
{{ end }}
|
||||
@@ -0,0 +1,22 @@
|
||||
{{ define "title" }}{{ .Title }} - {{ .Site.Title }}{{ end }}
|
||||
|
||||
{{ define "content" }}
|
||||
{{ partial "projects/styles.html" . }}
|
||||
<article class="post project-page">
|
||||
<header class="post-header project-header">
|
||||
<h1 class="post-title">{{ .Title }}</h1>
|
||||
{{- with .Params.summary }}<p class="project-summary">{{ . }}</p>{{ end }}
|
||||
<div class="project-meta">
|
||||
{{- with .Params.status }}<span class="project-status" data-status="{{ . | lower }}">{{ . }}</span>{{ end }}
|
||||
{{- if not .Date.IsZero }}<span>{{ .Date.Format "January 2006" }}</span>{{ end }}
|
||||
{{- with .Params.repo }}<a class="project-btn primary" href="{{ . }}" target="_blank" rel="noopener">Source code ↗</a>{{ end }}
|
||||
{{- with .Params.docs }}<a class="project-btn" href="{{ . }}" target="_blank" rel="noopener">Documentation</a>{{ end }}
|
||||
{{- with .Params.pypi }}<a class="project-btn" href="{{ . }}" target="_blank" rel="noopener">PyPI</a>{{ end }}
|
||||
</div>
|
||||
</header>
|
||||
<div class="post-content project-content">
|
||||
{{ .Content }}
|
||||
</div>
|
||||
<p class="project-back"><a href="{{ .Parent.RelPermalink }}">← All projects</a></p>
|
||||
</article>
|
||||
{{ end }}
|
||||
@@ -0,0 +1,12 @@
|
||||
{{- $src := .Get "src" | default (.Get 0) -}}
|
||||
{{- $caption := .Get "caption" -}}
|
||||
{{- $poster := .Get "poster" -}}
|
||||
{{- with .Page.Resources.GetMatch $src }}{{ $src = .RelPermalink }}{{ end -}}
|
||||
{{- with $poster }}{{ with $.Page.Resources.GetMatch . }}{{ $poster = .RelPermalink }}{{ end }}{{ end -}}
|
||||
<figure class="project-video">
|
||||
<video controls preload="metadata" playsinline{{ with $poster }} poster="{{ . }}"{{ end }}>
|
||||
<source src="{{ $src }}" type="video/mp4">
|
||||
Your browser does not support the video tag. <a href="{{ $src }}">Download the video</a>.
|
||||
</video>
|
||||
{{- with $caption }}<figcaption>{{ . | markdownify }}</figcaption>{{ end }}
|
||||
</figure>
|
||||
Reference in new issue
Block a user