mirror of
https://codeberg.org/vlw/vlw.se.git
synced 2026-01-12 06:45:59 +01:00
wip: 2025-11-20T13:08:46+0100 (1763640526)
This commit is contained in:
parent
7e01690936
commit
9023aaefb9
34 changed files with 534 additions and 557 deletions
509
assets/css/shell.css
Normal file
509
assets/css/shell.css
Normal file
|
|
@ -0,0 +1,509 @@
|
|||
:root {
|
||||
--primer-color-accent: 255, 255, 0;
|
||||
--color-accent: yellow;
|
||||
|
||||
--hue-accent: 0deg;
|
||||
|
||||
--padding: 20px;
|
||||
--running-size: 80px;
|
||||
--header-search-size: var(--running-size);
|
||||
}
|
||||
|
||||
/* # Cornerstones */
|
||||
|
||||
* {
|
||||
fill: inherit;
|
||||
color: inherit;
|
||||
margin: 0;
|
||||
font-size: inherit;
|
||||
box-sizing: border-box;
|
||||
font-family: "Roboto Mono", sans-serif;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body {
|
||||
color: white;
|
||||
display: grid;
|
||||
font-size: 15px;
|
||||
overflow-x: hidden;
|
||||
min-height: 100svh;
|
||||
justify-items: center;
|
||||
background-color: black;
|
||||
grid-template-rows: var(--running-size) 1fr;
|
||||
overscroll-behavior: none;
|
||||
|
||||
&::before {
|
||||
top: -5%;
|
||||
right: 0;
|
||||
width: 20%;
|
||||
height: 5%;
|
||||
opacity: 0;
|
||||
z-index: 1000;
|
||||
content: "";
|
||||
position: absolute;
|
||||
box-shadow:
|
||||
0 0 30svh 10svh rgba(var(--primer-color-accent), .2),
|
||||
0 0 30svh 60svh rgba(var(--primer-color-accent), .1),
|
||||
0 0 30svh 150svh rgba(var(--primer-color-accent), .02)
|
||||
;
|
||||
transition: 1s opacity;
|
||||
border-radius: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
display: contents;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* # Components */
|
||||
|
||||
:is(h1, h2, h3, p, li) > a {
|
||||
--underline-tickness: 3px;
|
||||
|
||||
display: initial;
|
||||
text-decoration: underline;
|
||||
text-underline-offset: var(--underline-tickness);
|
||||
text-decoration-color: var(--color-accent);
|
||||
text-decoration-thickness: var(--underline-tickness);
|
||||
|
||||
@media (hover: hover) {
|
||||
&:hover {
|
||||
color: var(--color-accent);
|
||||
text-underline-offset: 1px;
|
||||
text-decoration-thickness: calc(var(--underline-tickness) * 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: var(--color-accent);
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
/* ## Buttons */
|
||||
|
||||
button {
|
||||
fill: inherit;
|
||||
color: inherit;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
|
||||
@media (hover: hover) {
|
||||
&:hover {
|
||||
border-color: rgba(255, 255, 255, .2);
|
||||
background-color: rgba(255, 255, 255, .1);
|
||||
}
|
||||
}
|
||||
|
||||
&.inline {
|
||||
gap: 10px;
|
||||
fill: var(--color-accent);
|
||||
display: flex;
|
||||
padding: calc(var(--padding) / 1.5);
|
||||
background: linear-gradient(139deg, rgba(0, 0, 0, 0) 0%, rgba(var(--primer-color-accent), .1) 100%);
|
||||
align-items: center;
|
||||
border-radius: 7px;
|
||||
|
||||
@media (hover: hover) {
|
||||
& {
|
||||
transition-duration: 300ms;
|
||||
transition-property: background-color, border-color, box-shadow, color, fill;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
fill: var(--color-accent);
|
||||
color: var(--color-accent);
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.solid) {
|
||||
box-shadow:
|
||||
0 0 0 2px rgba(var(--primer-color-accent), .1),
|
||||
10px 7px 40px 3px rgba(var(--primer-color-accent), .06)
|
||||
;
|
||||
|
||||
@media (hover: hover) {
|
||||
&:hover {
|
||||
box-shadow:
|
||||
0 0 0 2px rgba(var(--primer-color-accent), 1),
|
||||
10px 7px 30px 3px rgba(var(--primer-color-accent), .07)
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.solid {
|
||||
fill: black;
|
||||
color: black;
|
||||
border: solid 2px rgba(var(--primer-color-accent), 1);
|
||||
border-color: var(--color-accent);
|
||||
background-color: var(--color-accent);
|
||||
|
||||
@media (hover: hover) {
|
||||
box-shadow: 0 -10px 20px 10px rgba(var(--primer-color-accent), .05);
|
||||
border-color: rgba(var(--primer-color-accent), .2);
|
||||
background-color: rgba(var(--primer-color-accent), .2);
|
||||
}
|
||||
}
|
||||
|
||||
svg {
|
||||
flex: none;
|
||||
height: 1em;
|
||||
|
||||
&:last-child {
|
||||
width: 1.5em;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
&.chevron:last-child {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ## Header */
|
||||
|
||||
header {
|
||||
--border-style: solid 1px rgba(255, 255, 255, .2);
|
||||
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: var(--running-size);
|
||||
display: grid;
|
||||
z-index: 100;
|
||||
position: sticky;
|
||||
overflow: hidden;
|
||||
perspective: 3000px;
|
||||
align-items: stretch;
|
||||
border-bottom: var(--border-style);
|
||||
backdrop-filter: blur(20px);
|
||||
background-color: rgba(0, 0, 0, .8);
|
||||
grid-template-rows: var(--running-size);
|
||||
grid-template-columns: 1fr var(--header-search-size) var(--running-size);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
|
||||
/* TODO: this is ugly */
|
||||
&.searchboxActive > * {
|
||||
transform: rotateX(-180deg);
|
||||
}
|
||||
|
||||
&.searchboxActive searchbox {
|
||||
transform: rotateX(0);
|
||||
}
|
||||
|
||||
> * {
|
||||
--anim-3d-depth: 5px;
|
||||
--anim-3d-peek: 25deg;
|
||||
|
||||
transform: rotateX(0deg);
|
||||
transition: 300ms background-color;
|
||||
box-shadow: 0 var(--anim-3d-depth) 0 0 rgba(255, 255, 255, .2);
|
||||
backface-visibility: hidden;
|
||||
|
||||
/* enable 3d flip animation */
|
||||
@media not (prefers-reduced-motion: reduce) {
|
||||
& {
|
||||
--transform-duration: 600ms;
|
||||
|
||||
transition: var(--transform-duration) transform, 300ms background-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nav {
|
||||
gap: calc(var(--padding) * 2);
|
||||
display: flex;
|
||||
padding: var(--padding);
|
||||
align-items: center;
|
||||
|
||||
> p {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.buttons {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.logo {
|
||||
fill: none;
|
||||
|
||||
.path.solid {
|
||||
@media (hover: hover) {
|
||||
.logo:hover & {
|
||||
fill: var(--color-accent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
path.stroke {
|
||||
fill: var(--color-accent);
|
||||
}
|
||||
}
|
||||
|
||||
/* Don't show nested headers */
|
||||
header {
|
||||
.search {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
--icon-size: 25px;
|
||||
|
||||
gap: var(--padding);
|
||||
fill: var(--color-accent);
|
||||
color: rgba(255, 255, 255, .5);
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
display: grid;
|
||||
padding: var(--padding);
|
||||
font-size: 13px;
|
||||
border-left: var(--border-style);
|
||||
align-items: center;
|
||||
justify-items: center;
|
||||
grid-template-columns: 1fr;
|
||||
|
||||
&:not(.logo) {
|
||||
svg {
|
||||
width: var(--icon-size);
|
||||
}
|
||||
}
|
||||
|
||||
&.search {
|
||||
p {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
@media not (prefers-reduced-motion: reduce) {
|
||||
header:not(.searchboxActive) &:hover,
|
||||
header:not(.searchboxActive) &:hover + button.logo {
|
||||
transform: rotateX(calc(var(--anim-3d-peek) * -1));
|
||||
}
|
||||
|
||||
header:not(.searchboxActive) &:hover ~ searchbox {
|
||||
transform: rotateX(calc(180deg - var(--anim-3d-peek)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: custom element or div */
|
||||
searchbox {
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: var(--running-size);
|
||||
display: grid;
|
||||
position: absolute;
|
||||
transform: rotateX(180deg);
|
||||
box-shadow: none;
|
||||
align-items: stretch;
|
||||
background-color: var(--color-accent);
|
||||
grid-template-rows: var(--running-size);
|
||||
grid-template-columns: 1fr var(--running-size);
|
||||
|
||||
> * {
|
||||
box-shadow: 0 calc(var(--anim-3d-depth) * -1) 0 0 rgba(var(--primer-color-accent), .8);
|
||||
}
|
||||
|
||||
button {
|
||||
fill: black;
|
||||
transition: 300ms background-color, 300ms border-color;
|
||||
border-color: rgba(0, 0, 0, .1);
|
||||
|
||||
@media (hover: hover) {
|
||||
& {
|
||||
background-color: rgba(0, 0, 0, .08);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
input {
|
||||
color: black;
|
||||
border: none;
|
||||
padding: 0 var(--padding);
|
||||
outline: none;
|
||||
background-color: transparent;
|
||||
|
||||
&::placeholder {
|
||||
color: rgba(0, 0, 0, .5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ## vv-shell */
|
||||
|
||||
vv-shell {
|
||||
width: 100%;
|
||||
padding: calc(var(--padding) * 1.5);
|
||||
position: relative;
|
||||
max-width: 1000px;
|
||||
}
|
||||
|
||||
/* ## Search results */
|
||||
|
||||
search-results {
|
||||
gap: var(--padding);
|
||||
top: var(--running-size);
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: calc(100svh - var(--running-size));
|
||||
padding: var(--padding);
|
||||
display: flex;
|
||||
opacity: 0;
|
||||
z-index: 50;
|
||||
position: fixed;
|
||||
transform: scale(.99);
|
||||
overflow-y: scroll;
|
||||
transition: 500ms opacity, 300ms transform;
|
||||
pointer-events: none;
|
||||
flex-direction: column;
|
||||
background-color: black;
|
||||
transform-origin: 100% 0;
|
||||
|
||||
.searchboxActive ~ & {
|
||||
opacity: 1;
|
||||
pointer-events: all;
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
section {
|
||||
.search {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
gap: var(--padding);
|
||||
margin: auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
|
||||
:is(svg, img) {
|
||||
fill: var(--color-accent);
|
||||
width: 60px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* # Size queries */
|
||||
|
||||
@media (min-width: 700px) {
|
||||
:root {
|
||||
--header-search-size: 250px;
|
||||
}
|
||||
|
||||
/* # Cornerstones */
|
||||
|
||||
body::before {
|
||||
left: 0;
|
||||
right: unset;
|
||||
box-shadow:
|
||||
0 0 30svh 10svh rgba(var(--primer-color-accent), .1),
|
||||
0 0 30svh 60svh rgba(var(--primer-color-accent), .05),
|
||||
0 0 30svh 150svh rgba(var(--primer-color-accent), .02)
|
||||
;
|
||||
}
|
||||
|
||||
/* ## Header */
|
||||
|
||||
header nav {
|
||||
margin: 0 calc(var(--padding) / 2);
|
||||
}
|
||||
|
||||
header > button.search {
|
||||
grid-template-columns: var(--icon-size) 1fr;
|
||||
}
|
||||
|
||||
header > button.search p {
|
||||
display: initial;
|
||||
}
|
||||
|
||||
header.searchboxActive > nav {
|
||||
transform: rotateX(0deg);
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
/* ### Searchbox */
|
||||
|
||||
header searchbox {
|
||||
width: calc(var(--header-search-size) + var(--running-size));
|
||||
}
|
||||
|
||||
/* ### Menu */
|
||||
|
||||
/* Move the search box to the header */
|
||||
header > button.search {
|
||||
display: grid;
|
||||
justify-items: baseline;
|
||||
}
|
||||
|
||||
@media (min-height: 600px) {
|
||||
search-results {
|
||||
top: calc(var(--running-size) + var(--padding));
|
||||
width: 50%;
|
||||
height: calc(100svh - 100px);
|
||||
box-shadow:
|
||||
inset 0 0 100px 200px rgba(0, 0, 0, 1),
|
||||
0 0 100px 200px rgba(0, 0, 0, 1)
|
||||
;
|
||||
backdrop-filter: blur(15px);
|
||||
background-color: rgba(0, 0, 0, .8);
|
||||
--webkit-backdrop-filter: blur(15px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 900px) {
|
||||
header {
|
||||
.buttons {
|
||||
gap: 10px;
|
||||
width: 100%;
|
||||
display: grid;
|
||||
white-space: nowrap;
|
||||
align-items: center;
|
||||
grid-template-columns: repeat(3, 100px);
|
||||
|
||||
button {
|
||||
border: dashed 1px rgba(255, 255, 255, .3);
|
||||
padding: 13px var(--padding);
|
||||
transition: 100ms border;
|
||||
border-radius: 6px;
|
||||
|
||||
&:hover {
|
||||
border-color: var(--color-accent);
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
:is(
|
||||
[vv-page="/work"] a[href="/work"],
|
||||
[vv-page="/about"] a[href="/about"],
|
||||
[vv-page="/contact"] a[href="/contact"]
|
||||
) & {
|
||||
color: var(--color-accent);
|
||||
border-style: solid;
|
||||
border-color: var(--color-accent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -55,7 +55,7 @@
|
|||
};
|
||||
|
||||
?>
|
||||
<style><?= VV::css("public/assets/css/pages/about") ?></style>
|
||||
<style><?= VV::css("assets/css/pages/about") ?></style>
|
||||
<section class="intro">
|
||||
<h2 aria-hidden="true">Hi, I'm</h2>
|
||||
<h1>Victor Westerlund</h1>
|
||||
|
|
@ -137,4 +137,4 @@
|
|||
<p>RFC 3339</p>
|
||||
<p>digital archiving</p>
|
||||
</div>
|
||||
<script><?= VV::js("public/assets/js/pages/about") ?></script>
|
||||
<script><?= VV::js("assets/js/pages/about") ?></script>
|
||||
|
|
@ -1,532 +0,0 @@
|
|||
:root {
|
||||
--primer-color-accent: 255, 255, 0;
|
||||
--color-accent: yellow;
|
||||
--hue-accent: 0deg;
|
||||
|
||||
--padding: 20px;
|
||||
--running-size: 80px;
|
||||
--header-search-size: var(--running-size);
|
||||
}
|
||||
|
||||
/* # Cornerstones */
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
fill: inherit;
|
||||
box-sizing: border-box;
|
||||
font-family: "Roboto Mono", sans-serif;
|
||||
color: inherit;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body {
|
||||
display: grid;
|
||||
justify-items: center;
|
||||
grid-template-rows: var(--running-size) 1fr;
|
||||
overscroll-behavior: none;
|
||||
background-color: black;
|
||||
color: white;
|
||||
overflow-x: hidden;
|
||||
min-height: 100svh;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
body::before {
|
||||
transition: 1s opacity;
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: -5%;
|
||||
right: 0;
|
||||
width: 20%;
|
||||
height: 5%;
|
||||
border-radius: 100%;
|
||||
z-index: 1000;
|
||||
box-shadow:
|
||||
0 0 30svh 10svh rgba(var(--primer-color-accent), .2),
|
||||
0 0 30svh 60svh rgba(var(--primer-color-accent), .1),
|
||||
0 0 30svh 150svh rgba(var(--primer-color-accent), .02)
|
||||
;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* "enable" the corner glow effect on initial load when a page has been fully loaded */
|
||||
body[vv-top-page]::before {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
a {
|
||||
display: contents;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* # Components */
|
||||
|
||||
:is(h1, h2, h3, p, li) > a {
|
||||
--underline-tickness: 3px;
|
||||
|
||||
display: initial;
|
||||
text-decoration: underline;
|
||||
text-decoration-thickness: var(--underline-tickness);
|
||||
text-underline-offset: var(--underline-tickness);
|
||||
text-decoration-color: var(--color-accent);
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 30px;
|
||||
color: var(--color-accent);
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
/* ## Page transition */
|
||||
|
||||
[vv-loading] * {
|
||||
transition: 200ms opacity;
|
||||
}
|
||||
|
||||
[vv-loading="true"] * {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
[vv-loading="true"]::after {
|
||||
content: "";
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 45px;
|
||||
height: 49px;
|
||||
background-size: contain;
|
||||
image-rendering: pixelated;
|
||||
transform: translate(-50%, -50%);
|
||||
background-image: url("/assets/media/spinner.gif");
|
||||
-webkit-filter: hue-rotate(var(--hue-accent));
|
||||
filter: hue-rotate(var(--hue-accent));
|
||||
}
|
||||
|
||||
/* ## Buttons */
|
||||
|
||||
button {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
color: inherit;
|
||||
fill: inherit;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* ### Inline */
|
||||
|
||||
button.inline {
|
||||
gap: 10px;
|
||||
display: flex;
|
||||
border-radius: 7px;
|
||||
align-items: center;
|
||||
fill: var(--color-accent);
|
||||
padding: calc(var(--padding) / 1.5);
|
||||
background: linear-gradient(139deg, rgba(0, 0, 0, 0) 0%, rgba(var(--primer-color-accent), .1) 100%);
|
||||
}
|
||||
|
||||
button.inline:not(.solid) {
|
||||
box-shadow:
|
||||
0 0 0 2px rgba(var(--primer-color-accent), .1),
|
||||
10px 7px 40px 3px rgba(var(--primer-color-accent), .06)
|
||||
;
|
||||
}
|
||||
|
||||
button.inline svg {
|
||||
flex: none;
|
||||
height: 1em;
|
||||
}
|
||||
|
||||
button.inline svg:last-child {
|
||||
width: 1.5em;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
button.inline svg.chevron:last-child {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
|
||||
button.inline.solid {
|
||||
fill: black;
|
||||
color: black;
|
||||
border: solid 2px rgba(var(--primer-color-accent), 1);
|
||||
border-color: var(--color-accent);
|
||||
background-color: var(--color-accent);
|
||||
}
|
||||
|
||||
/* ## Header */
|
||||
|
||||
header {
|
||||
--border-style: solid 1px rgba(255, 255, 255, .2);
|
||||
|
||||
position: sticky;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: var(--running-size);
|
||||
border-bottom: var(--border-style);
|
||||
display: grid;
|
||||
align-items: stretch;
|
||||
grid-template-columns: 1fr var(--header-search-size) var(--running-size);
|
||||
grid-template-rows: var(--running-size);
|
||||
background-color: rgba(0, 0, 0, .8);
|
||||
z-index: 100;
|
||||
perspective: 3000px;
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
backdrop-filter: blur(20px);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
header > * {
|
||||
--anim-3d-depth: 5px;
|
||||
--anim-3d-peek: 25deg;
|
||||
|
||||
transition: 300ms background-color;
|
||||
transform: rotateX(0deg);
|
||||
backface-visibility: hidden;
|
||||
box-shadow: 0 var(--anim-3d-depth) 0 0 rgba(255, 255, 255, .2);
|
||||
}
|
||||
|
||||
/* enable 3d flip animation */
|
||||
@media not (prefers-reduced-motion: reduce) {
|
||||
header > * {
|
||||
--transform-duration: 600ms;
|
||||
|
||||
transition: var(--transform-duration) transform, 300ms background-color;
|
||||
}
|
||||
}
|
||||
|
||||
header nav {
|
||||
gap: calc(var(--padding) * 2);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: var(--padding);
|
||||
}
|
||||
|
||||
header nav > p {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
header .buttons {
|
||||
display: none;
|
||||
}
|
||||
|
||||
header .logo {
|
||||
fill: none;
|
||||
}
|
||||
|
||||
header .logo path.stroke {
|
||||
fill: var(--color-accent);
|
||||
}
|
||||
|
||||
header header .search {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ### Buttons */
|
||||
|
||||
header button {
|
||||
--icon-size: 25px;
|
||||
|
||||
display: grid;
|
||||
width: 100%;
|
||||
border-left: var(--border-style);
|
||||
grid-template-columns: 1fr;
|
||||
align-items: center;
|
||||
justify-items: center;
|
||||
padding: var(--padding);
|
||||
gap: var(--padding);
|
||||
fill: var(--color-accent);
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, .5);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
header button:not(.logo) svg {
|
||||
width: var(--icon-size);
|
||||
}
|
||||
|
||||
header button.search p {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ### Searchbox */
|
||||
|
||||
header searchbox {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: var(--running-size);
|
||||
background-color: var(--color-accent);
|
||||
display: grid;
|
||||
align-items: stretch;
|
||||
grid-template-columns: 1fr var(--running-size);
|
||||
grid-template-rows: var(--running-size);
|
||||
box-shadow: none;
|
||||
transform: rotateX(180deg);
|
||||
}
|
||||
|
||||
header searchbox > * {
|
||||
box-shadow: 0 calc(var(--anim-3d-depth) * -1) 0 0 rgba(var(--primer-color-accent), .8);
|
||||
}
|
||||
|
||||
header searchbox button {
|
||||
transition: 300ms background-color, 300ms border-color;
|
||||
border-color: rgba(0, 0, 0, .1);
|
||||
fill: black;
|
||||
}
|
||||
|
||||
header searchbox input {
|
||||
padding: 0 var(--padding);
|
||||
background-color: transparent;
|
||||
outline: none;
|
||||
color: black;
|
||||
border: none;
|
||||
}
|
||||
|
||||
header searchbox input::placeholder {
|
||||
color: rgba(0, 0, 0, .5);
|
||||
}
|
||||
|
||||
/* #### Active */
|
||||
|
||||
header.searchboxActive > * {
|
||||
transform: rotateX(-180deg);
|
||||
}
|
||||
|
||||
header.searchboxActive searchbox {
|
||||
transform: rotateX(0);
|
||||
}
|
||||
|
||||
/* ## vv-shell */
|
||||
|
||||
vv-shell {
|
||||
position: relative;
|
||||
padding: calc(var(--padding) * 1.5);
|
||||
width: 100%;
|
||||
max-width: 1000px;
|
||||
}
|
||||
|
||||
/* ## Search results */
|
||||
|
||||
search-results {
|
||||
transition: 500ms opacity, 300ms transform;
|
||||
position: fixed;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--padding);
|
||||
top: var(--running-size);
|
||||
right: 0;
|
||||
width: 100%;
|
||||
padding: var(--padding);
|
||||
height: calc(100svh - var(--running-size));
|
||||
background-color: black;
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
transform: scale(.99);
|
||||
transform-origin: 100% 0;
|
||||
overflow-y: scroll;
|
||||
z-index: 50;
|
||||
}
|
||||
|
||||
header.searchboxActive ~ search-results {
|
||||
opacity: 1;
|
||||
pointer-events: all;
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
search-results section.search {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ### "Start typing" prompt */
|
||||
|
||||
search-results .info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
margin: auto;
|
||||
gap: var(--padding);
|
||||
}
|
||||
|
||||
search-results .info :is(svg, img) {
|
||||
width: 60px;
|
||||
fill: var(--color-accent);
|
||||
}
|
||||
|
||||
/* # Feature queries */
|
||||
|
||||
@media (hover: hover) {
|
||||
:is(h1, h2, h3, p, li) > a:hover {
|
||||
text-underline-offset: 1px;
|
||||
text-decoration-thickness: calc(var(--underline-tickness) * 2);
|
||||
color: var(--color-accent);
|
||||
}
|
||||
|
||||
/* # Components */
|
||||
|
||||
button.inline {
|
||||
transition-duration: 300ms;
|
||||
transition-property: background-color, border-color, box-shadow, color, fill;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
border-color: rgba(255, 255, 255, .2);
|
||||
background-color: rgba(255, 255, 255, .1);
|
||||
}
|
||||
|
||||
button.inline:hover {
|
||||
fill: var(--color-accent);
|
||||
color: var(--color-accent);
|
||||
}
|
||||
|
||||
button.inline:not(.solid):hover {
|
||||
box-shadow:
|
||||
0 0 0 2px rgba(var(--primer-color-accent), 1),
|
||||
10px 7px 30px 3px rgba(var(--primer-color-accent), .07)
|
||||
;
|
||||
}
|
||||
|
||||
button.solid:hover {
|
||||
border-color: rgba(var(--primer-color-accent), .2);
|
||||
background-color: rgba(var(--primer-color-accent), .2);
|
||||
box-shadow: 0 -10px 20px 10px rgba(var(--primer-color-accent), .05);
|
||||
}
|
||||
|
||||
/* ## Header */
|
||||
|
||||
header .logo:hover path.solid {
|
||||
fill: var(--color-accent);
|
||||
}
|
||||
|
||||
header searchbox button:hover {
|
||||
background-color: rgba(0, 0, 0, .08);
|
||||
}
|
||||
|
||||
/* ### Search */
|
||||
|
||||
@media not (prefers-reduced-motion: reduce) {
|
||||
header:not(.searchboxActive) button.search:hover,
|
||||
header:not(.searchboxActive) button.search:hover + button.logo {
|
||||
transform: rotateX(calc(var(--anim-3d-peek) * -1));
|
||||
}
|
||||
|
||||
header:not(.searchboxActive) button.search:hover ~ searchbox {
|
||||
transform: rotateX(calc(180deg - var(--anim-3d-peek)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* # Size queries */
|
||||
|
||||
@media (min-width: 700px) {
|
||||
:root {
|
||||
--header-search-size: 250px;
|
||||
}
|
||||
|
||||
/* # Cornerstones */
|
||||
|
||||
body::before {
|
||||
right: unset;
|
||||
left: 0;
|
||||
box-shadow:
|
||||
0 0 30svh 10svh rgba(var(--primer-color-accent), .1),
|
||||
0 0 30svh 60svh rgba(var(--primer-color-accent), .05),
|
||||
0 0 30svh 150svh rgba(var(--primer-color-accent), .02)
|
||||
;
|
||||
}
|
||||
|
||||
/* ## Header */
|
||||
|
||||
header nav {
|
||||
margin: 0 calc(var(--padding) / 2);
|
||||
}
|
||||
|
||||
header > button.search {
|
||||
grid-template-columns: var(--icon-size) 1fr;
|
||||
}
|
||||
|
||||
header > button.search p {
|
||||
display: initial;
|
||||
}
|
||||
|
||||
header.searchboxActive > nav {
|
||||
transform: rotateX(0deg);
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
/* ### Searchbox */
|
||||
|
||||
header searchbox {
|
||||
width: calc(var(--header-search-size) + var(--running-size));
|
||||
}
|
||||
|
||||
/* ### Menu */
|
||||
|
||||
/* Move the search box to the header */
|
||||
header > button.search {
|
||||
display: grid;
|
||||
justify-items: baseline;
|
||||
}
|
||||
|
||||
@media (min-height: 600px) {
|
||||
search-results {
|
||||
top: calc(var(--running-size) + var(--padding));
|
||||
width: 50%;
|
||||
height: calc(100svh - 100px);
|
||||
background-color: rgba(0, 0, 0, .8);
|
||||
box-shadow:
|
||||
inset 0 0 100px 200px rgba(0, 0, 0, 1),
|
||||
0 0 100px 200px rgba(0, 0, 0, 1)
|
||||
;
|
||||
--webkit-backdrop-filter: blur(15px);
|
||||
backdrop-filter: blur(15px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 900px) {
|
||||
header {
|
||||
.buttons {
|
||||
gap: 10px;
|
||||
width: 100%;
|
||||
display: grid;
|
||||
white-space: nowrap;
|
||||
align-items: center;
|
||||
grid-template-columns: repeat(3, 100px);
|
||||
|
||||
button {
|
||||
transition: 100ms border;
|
||||
border: dashed 1px rgba(255, 255, 255, .3);
|
||||
padding: 13px var(--padding);
|
||||
border-radius: 6px;
|
||||
|
||||
&:hover {
|
||||
border-color: var(--color-accent);
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
:is(
|
||||
[vv-page="/work"] a[href="/work"],
|
||||
[vv-page="/about"] a[href="/about"],
|
||||
[vv-page="/contact"] a[href="/contact"]
|
||||
) & {
|
||||
color: var(--color-accent);
|
||||
border-style: solid;
|
||||
border-color: var(--color-accent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use VLW\Database\Models\Messages\Message;
|
||||
use VLW\Database\Tables\Messages\Messages;
|
||||
|
||||
|
||||
require_once VV::root("src/Database/Models/Messages/Message.php");
|
||||
require_once VV::root("src/Database/Tables/Messages/Messages.php");
|
||||
|
||||
|
|
@ -37,7 +37,7 @@
|
|||
}
|
||||
|
||||
?>
|
||||
<style><?= VV::css("public/assets/css/pages/contact") ?></style>
|
||||
<style><?= VV::css("assets/css/pages/contact") ?></style>
|
||||
<section>
|
||||
<h1>Let's chat!</h1>
|
||||
<p>The best way to get in touch is definitely by email, or through the form on this page. The time in Sweden is <i><?= $date->format("h:i a") ?></i> right now, I am currently <?= $date->is_available() ? "available" : "not available" ?> and will hopefully reply in about <?= $date->get_estimated_reply_hours() ?> hours.</p>
|
||||
|
|
@ -112,4 +112,4 @@
|
|||
</button>
|
||||
</form>
|
||||
</section>
|
||||
<script ><?= VV::js("public/assets/js/pages/contact") ?></script>
|
||||
<script ><?= VV::js("assets/js/pages/contact") ?></script>
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<style><?= VV::css("public/assets/css/pages/error") ?></style>
|
||||
<style><?= VV::css("assets/css/pages/error") ?></style>
|
||||
<canvas></canvas>
|
||||
<section class="error">
|
||||
<h1 glitch-text><span>4</span><span>0</span><span>4</span></h1>
|
||||
</section>
|
||||
<script type="module"><?= VV::js("public/assets/js/pages/error") ?></script>
|
||||
<script type="module"><?= VV::js("assets/js/pages/error") ?></script>
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
}
|
||||
|
||||
?>
|
||||
<style><?= VV::css("public/assets/css/pages/index") ?></style>
|
||||
<style><?= VV::css("assets/css/pages/index") ?></style>
|
||||
<div class="menu">
|
||||
<?= VV::embed("public/assets/media/line.svg") ?>
|
||||
<menu>
|
||||
|
|
@ -23,4 +23,4 @@
|
|||
</div>
|
||||
|
||||
<img src="/assets/media/gazing.jpg" alt="A portrait of Victor with a pair of cartoon glasses drawn in the shape of two V's over his eyes"/>
|
||||
<script type="module"><?= VV::js("public/assets/js/pages/index") ?></script>
|
||||
<script type="module"><?= VV::js("assets/js/pages/index") ?></script>
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
$search = new class extends Search {
|
||||
public readonly string $query;
|
||||
public readonly array $results;
|
||||
|
||||
|
||||
public function __construct() {
|
||||
$this->query = $_GET[GET_KEY_QUERY] ?? "";
|
||||
$this->results = strlen($this->query) >= MIN_QUERY_LENGTH ? parent::query($this->query, limit: LIMIT_RESULTS) : [];
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
}
|
||||
|
||||
?>
|
||||
<style><?= VV::css("public/assets/css/pages/search") ?></style>
|
||||
<style><?= VV::css("assets/css/pages/search") ?></style>
|
||||
<section class="search">
|
||||
<form>
|
||||
<input name="<?= GET_KEY_QUERY ?>" type="search" placeholder="search vlw.se..." value="<?= $search->query ?>">
|
||||
|
|
@ -42,7 +42,7 @@
|
|||
</section>
|
||||
|
||||
<?php if (isset($_GET[GET_KEY_QUERY])): ?>
|
||||
|
||||
|
||||
<?php if ($search->results): ?>
|
||||
<section class="stats">
|
||||
<p><?= count($search->results) ?> result(s)</p>
|
||||
|
|
@ -96,7 +96,7 @@
|
|||
<?php break; ?>
|
||||
|
||||
<?php endswitch; ?>
|
||||
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
<?php else: ?>
|
||||
|
|
@ -105,4 +105,4 @@
|
|||
<p>Start typing to search</p>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
<script><?= VV::js("public/assets/js/pages/search") ?></script>
|
||||
<script><?= VV::js("assets/js/pages/search") ?></script>
|
||||
|
|
@ -37,8 +37,8 @@
|
|||
//--><!]]>
|
||||
</script>
|
||||
|
||||
<style><?= VV::css("public/assets/css/fonts") ?></style>
|
||||
<style><?= VV::css("public/assets/css/shell") ?></style>
|
||||
<style><?= VV::css("assets/css/fonts") ?></style>
|
||||
<style><?= VV::css("assets/css/shell") ?></style>
|
||||
|
||||
<title>Victor Westerlund</title>
|
||||
<link rel="icon" href="/assets/media/vw.svg"/>
|
||||
|
|
@ -64,7 +64,7 @@
|
|||
</searchbox>
|
||||
</header>
|
||||
|
||||
<vv-shell></vv-shell>
|
||||
<?= VV::shell() ?>
|
||||
|
||||
<search-results>
|
||||
<div class="info empty">
|
||||
|
|
@ -74,6 +74,6 @@
|
|||
</search-results>
|
||||
|
||||
<?= VV::init() ?>
|
||||
<script><?= VV::js("public/assets/js/shell") ?></script>
|
||||
<script><?= VV::js("assets/js/shell") ?></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<style><?= VV::css("public/assets/css/pages/work/archive") ?></style>
|
||||
<style><?= VV::css("assets/css/pages/work/archive") ?></style>
|
||||
<section>
|
||||
<h1>This is an archived website!</h1>
|
||||
<p>You're about to view an archived version of this website on my domain. Everything you see, and all features that are available on the archived website have been recreated to simulate the real behavior as closely as possible. Some features can unfortunately not be simulated properly and have been disabled completely. No actions you take on this website have any real effects.</p>
|
||||
|
|
@ -9,4 +9,4 @@
|
|||
<?= VV::embed("public/assets/media/icons/chevron.svg") ?>
|
||||
</button></a>
|
||||
</section>
|
||||
<script><?= VV::js("public/assets/js/pages/work/archive") ?></script>
|
||||
<script><?= VV::js("assets/js/pages/work/archive") ?></script>
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
require_once VV::root("src/Database/Models/Work/Work.php");
|
||||
|
||||
?>
|
||||
<style><?= VV::css("public/assets/css/pages/work/index") ?></style>
|
||||
<style><?= VV::css("assets/css/pages/work/index") ?></style>
|
||||
<section class="hero">
|
||||
<div class="item vegvisir">
|
||||
<div class="wrapper">
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
}
|
||||
|
||||
?>
|
||||
<style><?= VV::css("public/assets/css/pages/work/timeline") ?></style>
|
||||
<style><?= VV::css("assets/css/pages/work/timeline") ?></style>
|
||||
<section class="git">
|
||||
<?= VV::embed("public/assets/media/icons/codeberg.svg") ?>
|
||||
<p>This timeline has most but not all of my FOSS software. If you want to see a list of all things I've created for the free software world, check out my repos on Codeberg or Forgejo.</p>
|
||||
|
|
@ -104,7 +104,7 @@
|
|||
<?php endif; ?>
|
||||
|
||||
<p><?= $work->summary ?></p>
|
||||
|
||||
|
||||
<?php if ($work->actions()): ?>
|
||||
<div class="actions">
|
||||
|
||||
|
|
@ -138,7 +138,7 @@
|
|||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<style><?= VV::css("public/assets/css/pages/work/wip") ?></style>
|
||||
<style><?= VV::css("assets/css/pages/work/wip") ?></style>
|
||||
<section class="disclaimer">
|
||||
<h1>Soon, very soon!</h1>
|
||||
<p>Bear with me as I cook up some texts about this project! Hopefully with some pictures too.</p>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue