diff --git a/public/assets/css/pages/work.css b/public/assets/css/pages/work.css index 1f68ed3..229ead3 100644 --- a/public/assets/css/pages/work.css +++ b/public/assets/css/pages/work.css @@ -3,6 +3,9 @@ :root { --primer-color-accent: 3, 255, 219; --color-accent: rgb(var(--primer-color-accent)); + + --color-reflect: 220, 26, 0; + --color-vegvisir: 0, 128, 255; } vv-shell { @@ -38,95 +41,85 @@ section.git .buttons { gap: var(--padding); } -/* ## Timeline */ +/* ## Hero */ -section.timeline { - --timestamp-gap: calc(var(--padding) / 2); +section.hero { + --color-accent: rgba(255, 255, 255); - width: 100%; -} - -section.timeline :is(.year, .month, .day) { display: grid; - grid-template-columns: calc(40px + var(--timestamp-gap)) 1fr; - grid-template-rows: 1fr; + gap: var(--padding); + grid-template-columns: repeat(2, 1fr); } -section.timeline .track { - --opacity: .15; - --width: 2%; - - background: linear-gradient(90deg, - transparent 0%, transparent calc(50% - var(--width)), - rgba(255, 255, 255, var(--opacity)) calc(50% - var(--width)), rgba(255, 255, 255, var(--opacity)) calc(50% + var(--width)), - transparent calc(50% + var(--width)), transparent 100% - ); +section.hero .item { + width: 100%; + height: 300px; + position: relative; + border-radius: 6px; + box-shadow: 0 0 0 2px white; } -section.timeline .track p { - position: sticky; - top: calc(var(--running-size) + var(--padding)); - padding: calc(var(--padding) / 2) 0; - background-color: black; - color: var(--color-accent); -} - -section.timeline :not(.year) > .track p::before { - content: "/ "; - color: rgba(255, 255, 255, .3); -} - -/* ### Item */ - -section.timeline .items .item { +section.hero .wrapper { + z-index: 1; + height: 100%; display: flex; + position: relative; + align-items: baseline; flex-direction: column; - gap: calc(var(--padding) / 2); - padding: var(--padding); + padding: calc(var(--padding) * 1.5); } -section.timeline .items .item + .item { - border-top: solid 2px rgba(255, 255, 255, .2); +section.hero p { + width: 50%; } -section.timeline .items .item:first-of-type { - margin-top: var(--padding); - border-top: solid 2px var(--color-accent); +section.hero button { + margin-top: auto; } -/* No border style for the latest item (from the top) in the list */ -section.timeline .year:first-of-type .month:first-of-type .day:first-of-type .items .item:first-of-type { - margin-top: unset; - border-top: unset; +/* ### Vegivisr */ + +section.hero .item.vegvisir { + background-color: rgb(var(--color-vegvisir)); } -section.timeline .items .item .tags { +/* ### Reflect */ + +section.hero .item.reflect { + background: linear-gradient(0deg, rgba(215,31,5,1) 0%, rgba(233,102,102,1) 49%, rgba(251,251,251,1) 49%, rgba(215,31,5,1) 50%, rgba(215,31,5,1) 100%); +} + +/* ### Background */ + +section.hero .item .bg { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + overflow: hidden; + pointer-events: none; + border-radius: 6px; +} + +section.hero .item video { + position: absolute; + width: 100%; + bottom: 0; +} + +/* ## Heading */ + +section.heading { display: flex; - gap: calc(var(--padding) / 2); + justify-content: center; + align-items: center; + gap: 10px; } -section.timeline .items .item .tags .tag { - font-size: 11px; - letter-spacing: 1px; - color: rgba(255, 255, 255, .7); - background-color: rgba(255, 255, 255, .15); - border-radius: 4px; - padding: 5px 10px; -} - -section.timeline .items .item img { - max-width: 100%; - height: 250px; -} - -section.timeline .items .item .actions { - margin-top: 7px; -} - -/* ## Note */ - -section.note { - text-align: center; +section.heading svg { + fill: white; + height: 2em; } /* # Size queries */ @@ -152,43 +145,4 @@ section.note { section.git .buttons { justify-content: end; } -} - -@media (max-width: 500px) { - section.timeline { - padding: unset; - } - - section.timeline .track { - position: relative; - background: unset; - z-index: 10; - pointer-events: none; - } - - section.timeline .track p { - background-color: black; - } - - section.timeline :is(.years, .year, .months, .month, .days, .day) { - width: 0; - } - - section.timeline .items { - position: relative; - left: -140px; - } - - section.timeline .items .item { - padding: calc(var(--padding) * 1.5) 0; - width: calc(100vw - (var(--padding) * 3.5)); - } - - section.timeline .items .item:first-of-type { - border-top-color: rgba(var(--primer-color-accent), .2); - } - - section.timeline .year:first-of-type .month:first-of-type .day:first-of-type .items .item:first-of-type { - margin-top: var(--padding); - } } \ No newline at end of file diff --git a/public/assets/css/pages/work/timeline.css b/public/assets/css/pages/work/timeline.css new file mode 100644 index 0000000..df163ea --- /dev/null +++ b/public/assets/css/pages/work/timeline.css @@ -0,0 +1,147 @@ +/* # Overrides */ + +:root { + --primer-color-accent: 3, 255, 219; + --color-accent: rgb(var(--primer-color-accent)); +} + +vv-shell { + display: flex; + flex-direction: column; + gap: var(--padding); + width: 100%; + max-width: 1200px; + overflow-x: initial; +} + +/* # Sections */ + +/* ## Timeline */ + +section.timeline { + --timestamp-gap: calc(var(--padding) / 2); + + width: 100%; +} + +section.timeline :is(.year, .month, .day) { + display: grid; + grid-template-columns: calc(40px + var(--timestamp-gap)) 1fr; + grid-template-rows: 1fr; +} + +section.timeline .track { + --opacity: .15; + --width: 2%; + + background: linear-gradient(90deg, + transparent 0%, transparent calc(50% - var(--width)), + rgba(255, 255, 255, var(--opacity)) calc(50% - var(--width)), rgba(255, 255, 255, var(--opacity)) calc(50% + var(--width)), + transparent calc(50% + var(--width)), transparent 100% + ); +} + +section.timeline .track p { + position: sticky; + top: calc(var(--running-size) + var(--padding)); + padding: calc(var(--padding) / 2) 0; + background-color: black; + color: var(--color-accent); +} + +section.timeline :not(.year) > .track p::before { + content: "/ "; + color: rgba(255, 255, 255, .3); +} + +/* ### Item */ + +section.timeline .items .item { + display: flex; + flex-direction: column; + gap: calc(var(--padding) / 2); + padding: var(--padding); +} + +section.timeline .items .item + .item { + border-top: solid 2px rgba(255, 255, 255, .2); +} + +section.timeline .items .item:first-of-type { + margin-top: var(--padding); + border-top: solid 2px var(--color-accent); +} + +/* No border style for the latest item (from the top) in the list */ +section.timeline .year:first-of-type .month:first-of-type .day:first-of-type .items .item:first-of-type { + margin-top: unset; + border-top: unset; +} + +section.timeline .items .item .tags { + display: flex; + gap: calc(var(--padding) / 2); +} + +section.timeline .items .item .tags .tag { + font-size: 11px; + letter-spacing: 1px; + color: rgba(255, 255, 255, .7); + background-color: rgba(255, 255, 255, .15); + border-radius: 4px; + padding: 5px 10px; +} + +section.timeline .items .item img { + max-width: 100%; + height: 250px; +} + +section.timeline .items .item .actions { + margin-top: 7px; +} + +/* ## Note */ + +section.note { + text-align: center; +} + +@media (max-width: 500px) { + section.timeline { + padding: unset; + } + + section.timeline .track { + position: relative; + background: unset; + z-index: 10; + pointer-events: none; + } + + section.timeline .track p { + background-color: black; + } + + section.timeline :is(.years, .year, .months, .month, .days, .day) { + width: 0; + } + + section.timeline .items { + position: relative; + left: -140px; + } + + section.timeline .items .item { + padding: calc(var(--padding) * 1.5) 0; + width: calc(100vw - (var(--padding) * 3.5)); + } + + section.timeline .items .item:first-of-type { + border-top-color: rgba(var(--primer-color-accent), .2); + } + + section.timeline .year:first-of-type .month:first-of-type .day:first-of-type .items .item:first-of-type { + margin-top: var(--padding); + } +} \ No newline at end of file diff --git a/public/assets/css/shell.css b/public/assets/css/shell.css index f1e927b..56d0743 100644 --- a/public/assets/css/shell.css +++ b/public/assets/css/shell.css @@ -285,6 +285,7 @@ search-results { transform: scale(.99); transform-origin: 100% 0; overflow-y: scroll; + z-index: 50; } search-results:not([vv-page]) { diff --git a/public/assets/js/pages/work.js b/public/assets/js/pages/work/timeline.js similarity index 100% rename from public/assets/js/pages/work.js rename to public/assets/js/pages/work/timeline.js diff --git a/public/assets/media/icons/star.svg b/public/assets/media/icons/star.svg new file mode 100644 index 0000000..9fca4b6 --- /dev/null +++ b/public/assets/media/icons/star.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/media/vegvisir.webm b/public/assets/media/vegvisir.webm new file mode 100644 index 0000000..164810f Binary files /dev/null and b/public/assets/media/vegvisir.webm differ diff --git a/public/work.php b/public/work.php index 9bc9ec9..68e989c 100644 --- a/public/work.php +++ b/public/work.php @@ -1,38 +1,4 @@ -call(Endpoints::WORK->value)->get(); - - // Resolve tags and actions if we got work results - if ($resp_work->ok) { - $work_tags = $api->call(Endpoints::WORK_TAGS->value)->get()->json(); - $work_actions = $api->call(Endpoints::WORK_ACTIONS->value)->get()->json(); - } - -?> -

I have moved most of my free open-source software away from GitHub to Codeberg. I also have a mirror of everything and sources for some smaller projects on Forgejo.

@@ -41,141 +7,33 @@
- -ok): ?> - [[02 => [14 => []]]]] - */ - - $rows = []; - // Create array of arrays ordered by decending year, month, day, items - foreach ($resp_work->json() as $row) { - // Create array for current year if it doesn't exist - if (!array_key_exists($row[WorkModel::DATE_YEAR->value], $rows)) { - $rows[$row[WorkModel::DATE_YEAR->value]] = []; - } - - // Create array for current month if it doesn't exist - if (!array_key_exists($row[WorkModel::DATE_MONTH->value], $rows[$row[WorkModel::DATE_YEAR->value]])) { - $rows[$row[WorkModel::DATE_YEAR->value]][$row[WorkModel::DATE_MONTH->value]] = []; - } - - // Create array for current day if it doesn't exist - if (!array_key_exists($row[WorkModel::DATE_DAY->value], $rows[$row[WorkModel::DATE_YEAR->value]][$row[WorkModel::DATE_MONTH->value]])) { - $rows[$row[WorkModel::DATE_YEAR->value]][$row[WorkModel::DATE_MONTH->value]][$row[WorkModel::DATE_DAY->value]] = []; - } - - // Append item to ordered array - $rows[$row[WorkModel::DATE_YEAR->value]][$row[WorkModel::DATE_MONTH->value]][$row[WorkModel::DATE_DAY->value]][] = $row; - } - - ?> - -
- - $months): ?> -
-
-

-
- -
- - $days): ?> -
-
- -

-
- -
- - $items): ?> -
-
- -

-
- -
- -
- - - value), $item[WorkModel::ID->value]); ?> - - - -
- - - - -

value] ?>

- -
- - - - value])): ?> -

value] ?>

- - -

value] ?>

- - - value), $item[WorkModel::ID->value]); ?> - - - -
- - value] - // Bind VV Interactions for local links - ? "vv='work' vv-call='navigate'" - // Open external links in a new tab - : "target='_blank'"; - - $link_href = $action[WorkActionsModel::HREF->value] === null - // Navigate to work details page if no href is defined - ? "/work/{$item[WorkModel::ID->value]}" - // Href is defined so use it directly - : $action[WorkActionsModel::HREF->value]; - ?> - - > - -
- - -
- -
- -
- -
- -
- -
- -
- -
-
-

This is not really the end of the list. I will add some of my notable older work at some point.

-
- -

Something went wrong!

- - - +
+
+
+

Vegvisir

+

A PHP and JavaScript navigation framework for the seamless [open] web seas.

+ +
+
+ +
+
+
+
+

Reflect

+

A strange framework for building REST APIs in PHP.

+ +
+
+
+
+
+ +

Featured

+ +
+
+ +
\ No newline at end of file diff --git a/public/work/timeline.php b/public/work/timeline.php new file mode 100644 index 0000000..1bb6a5a --- /dev/null +++ b/public/work/timeline.php @@ -0,0 +1,171 @@ +call(Endpoints::WORK->value)->get(); + + // Resolve tags and actions if we got work results + if ($resp_work->ok) { + $work_tags = $api->call(Endpoints::WORK_TAGS->value)->get()->json(); + $work_actions = $api->call(Endpoints::WORK_ACTIONS->value)->get()->json(); + } + +?> + + +ok): ?> + [[02 => [14 => []]]]] + */ + + $rows = []; + // Create array of arrays ordered by decending year, month, day, items + foreach ($resp_work->json() as $row) { + // Create array for current year if it doesn't exist + if (!array_key_exists($row[WorkModel::DATE_YEAR->value], $rows)) { + $rows[$row[WorkModel::DATE_YEAR->value]] = []; + } + + // Create array for current month if it doesn't exist + if (!array_key_exists($row[WorkModel::DATE_MONTH->value], $rows[$row[WorkModel::DATE_YEAR->value]])) { + $rows[$row[WorkModel::DATE_YEAR->value]][$row[WorkModel::DATE_MONTH->value]] = []; + } + + // Create array for current day if it doesn't exist + if (!array_key_exists($row[WorkModel::DATE_DAY->value], $rows[$row[WorkModel::DATE_YEAR->value]][$row[WorkModel::DATE_MONTH->value]])) { + $rows[$row[WorkModel::DATE_YEAR->value]][$row[WorkModel::DATE_MONTH->value]][$row[WorkModel::DATE_DAY->value]] = []; + } + + // Append item to ordered array + $rows[$row[WorkModel::DATE_YEAR->value]][$row[WorkModel::DATE_MONTH->value]][$row[WorkModel::DATE_DAY->value]][] = $row; + } + + ?> + +
+ + $months): ?> +
+
+

+
+ +
+ + $days): ?> +
+
+ +

+
+ +
+ + $items): ?> +
+
+ +

+
+ +
+ +
+ + + value), $item[WorkModel::ID->value]); ?> + + + +
+ + + + +

value] ?>

+ +
+ + + + value])): ?> +

value] ?>

+ + +

value] ?>

+ + + value), $item[WorkModel::ID->value]); ?> + + + +
+ + value] + // Bind VV Interactions for local links + ? "vv='work' vv-call='navigate'" + // Open external links in a new tab + : "target='_blank'"; + + $link_href = $action[WorkActionsModel::HREF->value] === null + // Navigate to work details page if no href is defined + ? "/work/{$item[WorkModel::ID->value]}" + // Href is defined so use it directly + : $action[WorkActionsModel::HREF->value]; + ?> + + > + +
+ + +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+

This is not really the end of the list. I will add some of my notable older work at some point.

+
+ +

Something went wrong!

+ + \ No newline at end of file